diff --git a/_maps/map_files/MetaStation/MetaStation.v40D.dmm b/_maps/map_files/MetaStation/MetaStation.v40D.dmm index 4a87c6eefcd..3e93cfc1116 100644 --- a/_maps/map_files/MetaStation/MetaStation.v40D.dmm +++ b/_maps/map_files/MetaStation/MetaStation.v40D.dmm @@ -362,7 +362,7 @@ "agX" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/hos) "agY" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/fancy/carpet,/area/security/hos) "agZ" = (/obj/machinery/hologram/holopad,/obj/structure/stool/bed/chair{dir = 1},/obj/effect/landmark/start{name = "Head of Security"},/turf/simulated/floor/fancy/carpet,/area/security/hos) -"aha" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/mob/living/simple_animal/hostile/retaliate/bat{desc = "A fierce companion for any person of power, this spider has been carefully trained by NanoTrasen specialists. Its beady, staring eyes send shivers down your spine"; emote_hear = list("chitters"); faction = "spiders"; harm_intent_damage = 3; health = 200; icon_dead = "guard_dead"; icon_gib = "guard_dead"; icon_living = "guard"; icon_state = "guard"; l_move_time = 1; max_co2 = 5; max_tox = 2; maxHealth = 250; melee_damage_lower = 15; melee_damage_upper = 20; min_oxy = 5; name = "Sergeant Araneus"; real_name = "Sergeant Araneus"; response_help = "pets"; turns_per_move = 10; voice_name = "unidentifiable voice"},/turf/simulated/floor/fancy/carpet,/area/security/hos) +"aha" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/mob/living/simple_animal/hostile/retaliate/bat{desc = "A fierce companion for any person of power, this spider has been carefully trained by NanoTrasen specialists. Its beady, staring eyes send shivers down your spine"; emote_hear = list("chitters"); faction = "spiders"; harm_intent_damage = 3; health = 200; icon_dead = "guard_dead"; icon_gib = "guard_dead"; icon_living = "guard"; icon_state = "guard"; max_co2 = 5; max_tox = 2; maxHealth = 250; melee_damage_lower = 15; melee_damage_upper = 20; min_oxy = 5; name = "Sergeant Araneus"; real_name = "Sergeant Araneus"; response_help = "pets"; turns_per_move = 10; voice_name = "unidentifiable voice"},/turf/simulated/floor/fancy/carpet,/area/security/hos) "ahb" = (/obj/structure/table/wood,/obj/item/device/taperecorder{pixel_x = -4; pixel_y = 0},/obj/item/device/radio/off{pixel_x = 0; pixel_y = 3},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/hos) "ahc" = (/obj/machinery/door/firedoor,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/command{name = "Head of Security's Office"; req_access = null; req_access_txt = "58"},/turf/simulated/floor/fancy/carpet,/area/security/hos) "ahd" = (/turf/simulated/floor/plasteel,/area/security/range) @@ -1230,12 +1230,12 @@ "axH" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 8; initialize_directions = 11},/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "redcorner"},/area/security/brig) "axI" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plasteel,/area/security/brig) "axJ" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden{req_access_txt = "0"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/security/brig) -"axK" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/light,/obj/machinery/door_timer/cell_1,/obj/machinery/camera{c_tag = "Brig - Hallway - Port"; dir = 1; network = list("SS13")},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) +"axK" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/light,/obj/machinery/camera{c_tag = "Brig - Hallway - Port"; dir = 1; network = list("SS13")},/obj/machinery/door_timer{id = "Cell 1"; name = "Cell 1"; pixel_y = -32},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) "axL" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 1; initialize_directions = 11},/turf/simulated/floor/plasteel{dir = 8; icon_state = "redcorner"},/area/security/brig) "axM" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 2; initialize_directions = 11},/turf/simulated/floor/plasteel,/area/security/brig) -"axN" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/door_timer/cell_2,/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) +"axN" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 2; initialize_directions = 11},/obj/machinery/door_timer{id = "Cell 3"; name = "Cell 3"; pixel_y = -32},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/security/brig) "axO" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden{req_access_txt = "0"},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) -"axP" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 2; initialize_directions = 11},/obj/machinery/door_timer/cell_3,/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/security/brig) +"axP" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/door_timer{id = "Cell 2"; name = "Cell 2"; pixel_y = -32},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) "axQ" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden{req_access_txt = 1},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 9},/area/security/brig) "axR" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 1},/area/security/brig) "axS" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 1; initialize_directions = 11},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 5},/area/security/brig) @@ -3896,7 +3896,7 @@ "bwV" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/fancy/carpet,/area/crew_quarters/heads) "bwW" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/item/device/radio/intercom{dir = 2; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = -28},/obj/machinery/hologram/holopad,/obj/machinery/camera{c_tag = "Head of Personnel's Office"; dir = 1; network = list("SS13")},/turf/simulated/floor/fancy/carpet,/area/crew_quarters/heads) "bwX" = (/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 5},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/fancy/carpet,/area/crew_quarters/heads) -"bwY" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/mob/living/simple_animal/corgi/Ian,/turf/simulated/floor/fancy/carpet,/area/crew_quarters/heads) +"bwY" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/mob/living/simple_animal/pet/corgi/Ian,/turf/simulated/floor/fancy/carpet,/area/crew_quarters/heads) "bwZ" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/fancy/carpet,/area/crew_quarters/heads) "bxa" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 5},/obj/structure/stool/bed/chair/comfy/beige,/turf/simulated/floor/fancy/carpet,/area/bridge) "bxb" = (/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/showcase{desc = "A slightly battered looking TV. Vaious Nanotrasen infomercials play on a loop, accompanied by a jaunty tune."; dir = 1; icon = 'icons/obj/computer.dmi'; icon_state = "security_det"; name = "NanoTrasen corporate newsfeed"; pixel_x = 2; pixel_y = 3},/obj/structure/table/wood,/turf/simulated/floor/fancy/carpet,/area/assembly/showroom{name = "\improper Corporate Showroom"}) @@ -4229,7 +4229,7 @@ "bDq" = (/obj/machinery/atmospherics/unary/portables_connector/visible{dir = 4},/obj/machinery/portable_atmospherics/pump,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/structure/window/reinforced{dir = 1},/obj/machinery/camera{c_tag = "Starboard Primary Hallway - Atmospherics"; dir = 4; network = list("SS13")},/turf/simulated/floor/plasteel{icon_state = "arrival"; dir = 8},/area/hallway/primary/starboard) "bDr" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/hallway/primary/starboard) "bDs" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 10},/turf/simulated/floor/plasteel{icon_state = "caution"; dir = 4},/area/hallway/primary/starboard) -"bDt" = (/obj/machinery/light,/obj/machinery/computer/security/telescreen{dir = 1; name = "MiniSat Monitor"; network = list("MiniSat","tcomm"); pixel_x = 0; pixel_y = -29},/mob/living/simple_animal/fox/Renault,/turf/simulated/floor/fancy/carpet{tag = "icon-carpetside"; icon_state = "carpetside"},/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) +"bDt" = (/obj/machinery/light,/obj/machinery/computer/security/telescreen{dir = 1; name = "MiniSat Monitor"; network = list("MiniSat","tcomm"); pixel_x = 0; pixel_y = -29},/mob/living/simple_animal/pet/fox/Renault,/turf/simulated/floor/fancy/carpet{tag = "icon-carpetside"; icon_state = "carpetside"},/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "bDu" = (/obj/structure/grille,/obj/structure/window/reinforced/fulltile,/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plating,/area/security/checkpoint/science{name = "Security Post - Research Division"}) "bDv" = (/obj/machinery/space_heater,/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/atmos) "bDw" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plasteel,/area/atmos) @@ -4606,7 +4606,7 @@ "bKD" = (/obj/structure/grille,/obj/structure/window/reinforced/fulltile,/obj/machinery/atmospherics/pipe/simple/green/visible,/obj/machinery/atmospherics/pipe/simple/cyan/visible{dir = 4},/turf/simulated/floor/plating,/area/atmos) "bKE" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/maintcentral{name = "Central Maintenance"}) "bKF" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 10},/turf/simulated/floor/engine,/area/toxins/explab) -"bKG" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1; scrub_Toxins = 0},/mob/living/simple_animal/pug{desc = "It's Pugley III, the loveable four-legged test subject."; dir = 8; name = "Pugley III"; real_name = "Pugley III"},/turf/simulated/floor/engine,/area/toxins/explab) +"bKG" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1; scrub_Toxins = 0},/mob/living/simple_animal/pet/pug{desc = "It's Pugley III, the loveable four-legged test subject."; dir = 8; name = "Pugley III"; real_name = "Pugley III"},/turf/simulated/floor/engine,/area/toxins/explab) "bKH" = (/obj/structure/grille,/obj/structure/window/reinforced/fulltile,/obj/machinery/atmospherics/pipe/simple/insulated,/turf/simulated/floor/plating,/area/maintenance/incinerator) "bKI" = (/obj/item/stack/cable_coil,/obj/structure/lattice/catwalk,/turf/space,/area/solar/port) "bKJ" = (/obj/item/stack/sheet/mineral/plasma{layer = 2.9},/obj/item/stack/sheet/mineral/plasma{layer = 2.9},/obj/structure/table/glass,/obj/item/weapon/reagent_containers/glass/bottle/epinephrine,/obj/item/weapon/reagent_containers/glass/bottle/charcoal{pixel_x = 7; pixel_y = 4},/obj/item/weapon/storage/pill_bottle/epinephrine{pixel_x = 3},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whiteyellow"},/area/medical/chemistry) @@ -6423,7 +6423,7 @@ "ctA" = (/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/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay{name = "Medbay Central"}) "ctB" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "whitebluefull"},/area/medical/medbay{name = "Medbay Central"}) "ctC" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 10},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/medical/cmo) -"ctD" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/manifold/supply/hidden{dir = 8},/mob/living/simple_animal/cat/Runtime,/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/medical/cmo) +"ctD" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/manifold/supply/hidden{dir = 8},/mob/living/simple_animal/pet/cat/Runtime,/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/medical/cmo) "ctE" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/medical/cmo) "ctF" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/medical/cmo) "ctG" = (/obj/structure/closet/secure_closet/scientist,/obj/item/weapon/storage/backpack/satchel_tox,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/toxins/explab) @@ -7790,7 +7790,7 @@ "cVB" = (/obj/machinery/door/window/northleft{dir = 4; name = "Containment Pen #1"; req_access_txt = "55"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/toxins/xenobiology) "cVC" = (/obj/machinery/door/window/northleft{base_state = "right"; dir = 8; icon_state = "right"; name = "Containment Pen #2"; req_access_txt = "55"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/toxins/xenobiology) "cVD" = (/obj/machinery/door/window/northleft{dir = 4; name = "Containment Pen #2"; req_access_txt = "55"},/obj/machinery/door/poddoor/preopen{id = "xenobio8"; name = "containment blast door"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/engine,/area/toxins/xenobiology) -"cVE" = (/mob/living/carbon/slime,/turf/simulated/floor/engine,/area/toxins/xenobiology) +"cVE" = (/mob/living/simple_animal/slime,/turf/simulated/floor/engine,/area/toxins/xenobiology) "cVG" = (/obj/structure/table/reinforced,/obj/machinery/door_control{id = "xenobio3"; name = "Containment Blast Doors"; pixel_x = 0; pixel_y = 4; req_access_txt = "55"},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 5; icon_state = "warning"},/area/toxins/xenobiology) "cVI" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 5},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/xenobiology) "cVK" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 9; icon_state = "warning"},/area/toxins/xenobiology) @@ -7953,7 +7953,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatJatJatJatJatJaahatJatJaahcrMatJatJaahaahaahaahalWalWatKalWalWatLatMatMatMatMatMatNalWalWalWalWatOavbatPatPatPatPatQatRaheatSavcatUatVatWatXatYatZauaaubaucaudaheangaavaavaavanmahAaukaulansaumavdavgajSauoadRadRanBanyanoakjadRautanBahJahJajQanCauwauxanCajQaodanZajQaoiaqtaqtauBauBauBajQajQauCaheaiYauDauEarWauFauGauHauIauJauKauLauMauNauOauParWauQaocaxqauSauTauUaocauVaocaocaocauWaocaocauXauYauZajoajoajoajoauVapwapxavaazvatHaBwaBjaveatHaobatHaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQxaahatJatJatJatJatJatJatJatJatJatJatJavfatJaahcrMalWalWalWaBFavhalWaahaahaahaahaahaahaahaahaahaahaahalWankaviaotalOavjalOavkavlavmavnavoavpaheaheaheaokaojaojaojaolaheaheaoAaoOaoMaoPaoAahAahAagKavzavAameavBavBavCavDavBavEavBavDavBavFavBavEavGavHavIavDavJavKavBavBavBavDavBavLahCavMavNavNavNavNagKaquaheauEaiYaiYarWarWarWarWarWavOavPavQavRavSarWarWarWavTaocapwavUatyapxaocapxaocavVaocavWavXavYavZawaawbawcawdaweawfawgawhaweawiapxapxavUapxawjatIawkatIabjabjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrMaahatJaraatJatJatJatJawlaahatJatJatJatJatJatJawmawnawmawoawpalWalWaahaaaaaaaaaaaaaaaaaaaaaaaaaahalWalWalWapRalOawqalOawrawsawtawuawvawwaheaaaaahaaaaaaaaaaaaaaaaahaaaaoUapyapvapCapzawCavNapDawEawFawGawHawHawIawGawHawJawKawGawLawMawHawNawOawPawHawQawRawSawTawTawUawVawWawXawYawZaxaaxbaxcaxdagKaquaheaxeahfaxfarWaxgaxhaxiatratsattaxjarWaxkatpaxlarWaxmaocaocaocauWaocaocapxaocaqKaocaxnatHatHatAaxoajoatHatHatHatHatHatHatHatHatHaoaatHatHatHatHatHaxpatHaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatJatJatJatJatJatJatJatJatJatJatJaahatJatJatJaahalWalWalWaBHawwaotalWaaaangadoaavadoanmaahaahaahaahalWapFalWaxwasvasvasvaxxaxyalWaxzaxAaxBaheaaaaxCaxCaxCaxCaxCaxCaxCaaaaoAapLapGaqbaoAahAahAagKaxHaxIaxJaxKaxLaxMaxJaxNaxLaxIaxOaxPaxQaxRaxSaxTaxUaxVaxWaxXaxYaxZayaaxYaybaycaydayeayfaygayhayiayjagKaquaykaykaykaykaykauPaylaymaynayoaypauLayqayraysauFarWaqhaytayuayvaywayvayxayvayyayvayvayzayAayBayCayDayEayFayGayFayHayIayJayIayKatHatHatHayHayIayKayLayLayFaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatJatJatJatJatJatJatJatJatJatJatJaahatJatJatJaahalWalWalWaBHawwaotalWaaaangadoaavadoanmaahaahaahaahalWapFalWaxwasvasvasvaxxaxyalWaxzaxAaxBaheaaaaxCaxCaxCaxCaxCaxCaxCaaaaoAapLapGaqbaoAahAahAagKaxHaxIaxJaxKaxLaxMaxJaxPaxLaxIaxOaxNaxQaxRaxSaxTaxUaxVaxWaxXaxYaxZayaaxYaybaycaydayeayfaygayhayiayjagKaquaykaykaykaykaykauPaylaymaynayoaypauLayqayraysauFarWaqhaytayuayvaywayvayxayvayyayvayvayzayAayBayCayDayEayFayGayFayHayIayJayIayKatHatHatHayHayIayKayLayLayFaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahatJatJatJatJatJatJatJayMatJaahaahaahaahalWalOawwaouagAaaaaoAarlaqQarlaoAarCarCarCayUayUayUayUaxFayUayUayWayWayWayWayTayWayYaheaahaxCayXayVazaayZazbaxCaaaaoAasJasJaueaoAaaaaaaazgaufaziaugagKaufazlaugagKaufazoaugagKavyahAawxagKahAauhazuahAahAazxazxauiazzaujazxazxazBagKagKagKagKagKaquaykazCazDazEaykarWarWarWarWazFazGazHavRavSarWarWarWaocazIapwaoaapxapwazJapxatHatHatHatHatHazKazLazMazNazOazPazOazQazRazSazRazTayIazUayIazVazRazSazRayLazWazXaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQxaahaahaahatJatJatJatJaraatJatJatJazYatJatJatJatJaahaaaaahagAaviawwanfalWaaaaavasJaupasJaavarCaAcaAdayUaAeaAfaAgaAhaAiayUaAjaAkaAlaAmaAnayWayYaheaaaaxCazdazcaAoazeaApaxCaaaaoUauqasJauraoAausausaboaAxaAyaAzagKaAAaAyaAzagKaABaAyaAzagKaACaADaAEagKaAFaAGaAHaAIawyazxaAKaALaAMaANaAOaAPazBaAQaARaARaASaARaATaykaAUaAVaAWaykaAXaAYaAXarWaAZaBaaBbaBcaBdaBeaBfaBgayvaBhatHatHatHatHatHatHatHaBiaBIauuaBkaBlaBmaBnaBoayFayFayFaahaahaJzaBqazRazRazRazRazRaBraJzazRaBsayFayFazXaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahatJatJatJatJatJatJatJaahatJaahaahatJatJaahaahalWalWardawwalWalWaaaaoAasJasJasJaBLaBuaBvaBvaCTaBxaByaBzaBAaBBaBCaBDaBEaCVaBGaDHayWayYaheaaaaxCaAraAqaBJaAsaBKaxCaaaaoAauyasJasJauzaBOauAaboaBQaAyaBRagKaBQaAyaBSagKaBQaAyaBTagKaBUaBVaBWagKaBXaBYaBZaCaaCbazxaCcaCdaCeaCfaCgaChazBaCiapjapjapjaCjaCkaykaClaCmaCnaykaCoaCpaCpaCqaCraCsaCtarWarWarWarWarWaocaCuatHavqaCwaCxaCyavraCAaCBaCCaCCaCCaCCaCDaCEaCFavsaCHayFaCIaahaahaaaaaaaaaaahaahaaaaaaaahaaaatJazRayFazXaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/map_files/MiniStation/MiniStation.dmm b/_maps/map_files/MiniStation/MiniStation.dmm index d63590ecb3c..392ef5442c9 100644 --- a/_maps/map_files/MiniStation/MiniStation.dmm +++ b/_maps/map_files/MiniStation/MiniStation.dmm @@ -134,7 +134,7 @@ "cD" = (/obj/machinery/newscaster{pixel_y = 32},/turf/simulated/floor/plasteel,/area/security/brig) "cE" = (/obj/machinery/photocopier,/turf/simulated/floor/plasteel,/area/security/brig) "cF" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/engine,/area/medical/research{name = "Research Division"}) -"cG" = (/mob/living/carbon/slime,/turf/simulated/floor/engine,/area/medical/research{name = "Research Division"}) +"cG" = (/mob/living/simple_animal/slime,/turf/simulated/floor/engine,/area/medical/research{name = "Research Division"}) "cH" = (/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/medical/research{name = "Research Division"}) "cI" = (/obj/machinery/door/window/northleft{dir = 4; name = "Containment Pen"; req_access_txt = "55"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/medical/research{name = "Research Division"}) "cJ" = (/obj/machinery/door/window/northleft{base_state = "right"; dir = 8; icon_state = "right"; name = "Containment Pen"; req_access_txt = "55"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/medical/research{name = "Research Division"}) @@ -252,7 +252,7 @@ "eR" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/turf/simulated/floor/plating,/area/security/brig) "eS" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel,/area/security/brig) "eT" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel,/area/security/brig) -"eU" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/door_timer/cell_2{dir = 4; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/brig) +"eU" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door_timer{id = "Cell 2"; name = "Cell 2"; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/brig) "eV" = (/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 = "xenobio1"; name = "containment blast door"},/turf/simulated/floor/engine,/area/medical/research{name = "Research Division"}) "eW" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/medical/research{name = "Research Division"}) "eX" = (/turf/simulated/wall,/area/space) @@ -345,7 +345,7 @@ "gG" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 10},/obj/structure/stool/bed/chair{dir = 4},/obj/effect/landmark/start{name = "Security Officer"},/turf/simulated/floor/plasteel,/area/security/brig) "gH" = (/obj/structure/table,/obj/item/weapon/storage/box/chemimp{pixel_x = 4; pixel_y = 3},/obj/item/weapon/storage/box/trackimp,/turf/simulated/floor/plasteel,/area/security/brig) "gI" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/storage/box/handcuffs,/obj/item/weapon/pen,/turf/simulated/floor/plasteel,/area/security/brig) -"gJ" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door_timer/cell_3{dir = 4; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/brig) +"gJ" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/door_timer{id = "Cell 1"; name = "Cell 1"; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/brig) "gK" = (/obj/machinery/computer/security/wooden_tv,/obj/item/device/radio/intercom{broadcasting = 0; freerange = 0; listening = 1; name = "Common Channel"; pixel_y = 25},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/security/brig) "gL" = (/obj/item/weapon/storage/secure/safe{pixel_x = 4; pixel_y = 26},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/fancy/carpet,/area/security/brig) "gM" = (/obj/structure/table/wood,/obj/item/device/camera{desc = "A one use - polaroid camera. 30 photos left."; name = "detectives camera"; pictures_left = 30},/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/item/device/taperecorder{pixel_y = 0},/obj/machinery/camera/autoname,/obj/item/weapon/folder/yellow,/obj/machinery/newscaster{pixel_y = 32},/turf/simulated/floor/fancy/carpet,/area/security/brig) @@ -396,7 +396,7 @@ "hF" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plasteel,/area/security/brig) "hG" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 8},/turf/simulated/floor/plasteel,/area/security/brig) "hH" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 10},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel,/area/security/brig) -"hI" = (/obj/machinery/door/window/brigdoor{dir = 4; id = "Cell 3"; name = "Cell 3"; req_access_txt = "2"},/obj/machinery/door/firedoor/border_only{dir = 8},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/brig) +"hI" = (/obj/machinery/door/window/brigdoor{dir = 4; id = "Cell 1"; name = "Cell 1"; req_access_txt = "2"},/obj/machinery/door/firedoor/border_only{dir = 8},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/brig) "hJ" = (/obj/machinery/flasher{id = "Cell 3"; pixel_x = 28},/turf/simulated/floor/plasteel,/area/security/brig) "hK" = (/obj/structure/closet/secure_closet/detective,/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/security/brig) "hL" = (/turf/simulated/floor/fancy/carpet,/area/security/brig) @@ -1021,7 +1021,7 @@ "tG" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/obj/effect/landmark/start{name = "Head of Personnel"},/turf/simulated/floor/plasteel,/area/crew_quarters/heads{name = "\improper Job Assignment"}) "tH" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/machinery/computer/secure_data,/obj/item/device/radio/intercom{broadcasting = 0; freerange = 0; listening = 1; name = "Common Channel"; pixel_y = 25},/turf/simulated/floor/plasteel,/area/crew_quarters/heads{name = "\improper Job Assignment"}) "tI" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 8},/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/turf/simulated/floor/plasteel,/area/crew_quarters/heads{name = "\improper Job Assignment"}) -"tJ" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/structure/stool/bed/chair{dir = 8},/mob/living/simple_animal/corgi/Ian,/turf/simulated/floor/plasteel,/area/crew_quarters/heads{name = "\improper Job Assignment"}) +"tJ" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/structure/stool/bed/chair{dir = 8},/mob/living/simple_animal/pet/corgi/Ian,/turf/simulated/floor/plasteel,/area/crew_quarters/heads{name = "\improper Job Assignment"}) "tK" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{dir = 1},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plasteel,/area/crew_quarters/heads{name = "\improper Job Assignment"}) "tL" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/wall/r_wall,/area/crew_quarters/heads{name = "\improper Job Assignment"}) "tM" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plating,/area/hallway/primary/central) @@ -1825,13 +1825,13 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadadadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaambqcMcNcOcOcPcOcQcRcSbqbNbNbNcTcUcVcUcWcXcYcZcWdadbcUdccjdddedfdgdhdidjckamamamamamambUcscscsdkdlcpcpdmdncmcmdobUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadadadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamamambqdpcScScScScSdqcSdrdsbNdtdudvdwdxdydwdzdAdBdCdDdEcjcjcjdFdedGdHdedIdJckaaaaaaaaaaambUbUbUbUdKbUdLdMbUbUbUbUbUbUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamamamamamambqdNcSdOcScSdPcSdOdQbqbqbqdRdSdTdUdVdWdXdYdZeaebecedeeefdeegeheiejekelckaaaaaaaaaaaabUclcmcmemencpcpeoepeqeresetaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeuamamamamamamambqevewexeyezezezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeSeSeTeUckckckckckaaaaaaaaaaambUcFcGcseVcIcpcpcpcpcpcpcpeWamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeuamamamamamamambqevewexeyezezezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeSeSeTgJckckckckckaaaaaaaaaaambUcFcGcseVcIcpcpcpcpcpcpcpeWamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXamaaaaaaaaaaambJeZfafbfccScScSfdfebqffcSfbfgfheIfieKeLfjfkflebfmedfndedefofpfqfrfsckamamamamamamambUcscscsftfucpcpcpcpfvcpcpfwamamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXaaaaaaaaaaaaaabqfxcSfyfzfAfAfAfAfBfCfDfAfEfFfGfHfIfJeLfKfLcjfMfNckdededefofOfPdefQckamaaaaaaaaaaambUbUbUbUbUbUcpcpfRfSfTfUbUbUbUbUbUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXaaaaaaaaaaaaaabqfxcSfyfzfAfAfAfAfBfCfDfAfEfFfGfHfIfJeLfKfLcjfMfNckdededefofOhIdefQckamaaaaaaaaaaambUbUbUbUbUbUcpcpfRfSfTfUbUbUbUbUbUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXaaaaaaaaaaaaaabqcScSfbfccScScScSdrfVcScSfafWbIfXfXfXfYfZgacjgbgcgdgegfggghgigjgegkcjckckckckglgmgngogpgqgrgsbUgtgugvbUbUgwbUgxgygzbUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXaaaaaaaaaaaaaagAgBcSfbfccScSgCcSdrfVcScScSdrgDfXfXfXeLfjgacjgEgFgFgGgHgIdegJckckckcjgKgLgMckgNgOgPgogQcpcpcpcpcpgRgSgTgUgVbUgWgXgYbUamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXaaaaaaaaaaaaaagAgBcSfbfccScSgCcSdrfVcScScSdrgDfXfXfXeLfjgacjgEgFgFgGgHgIdeeUckckckcjgKgLgMckgNgOgPgogQcpcpcpcpcpgRgSgTgUgVbUgWgXgYbUamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXaaaaaaaaaaaaaagZhacShbhchdbqbqbqbqbqbqbqbqbqbqbxbxbxeLfjhecjcjhfdehghhhigFhjfqfrhkcjhlhmhnckhofXhphqhrcpcpcphshthuhvhththwbUhxhyhxbUbUamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXaaaaaaaaaaaaaaeHhAcSfbfccSbqbNbNbNbNbNbNbNbNbNbNbxhBeLfjgahCcjhDhEhFdehGgehHhIdehJcjhKhLhMckhNfXhOgohPhQhRhShThUhVhWcpcphXbUgRhYhZiabUamamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXaaaaaaaaaaaaaaeHhAcSfbfccSbqbNbNbNbNbNbNbNbNbNbNbxhBeLfjgahCcjhDhEhFdehGgehHfPdehJcjhKhLhMckhNfXhOgohPhQhRhShThUhVhWcpcphXbUgRhYhZiabUamamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXaaaaaaaaaaaaaaibcScShbhcicbqbNbxbxbxbxbxbxbxbxidbxieeLfjgaifcjigihiiijikilimgjgegkcjinioipckiqfXfXgoirhQisitiuiviwixiyiziAbUcpiBiCbUbUbUbUbUamamamamamamamamamamamamamamamamamiDiDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXaaaaaaaaaaaaaafhgBcSfbfccSbqiEdwiFiGbxiHiIiJiKiLbxbxiMiNiOiPcjcjcjcjcjcjcjcjcjcjcjcjiQiRiSckiTfXiUgobUbUbUbUbUgviVbUbUbUbUbUcpiWcpiXbUiYiZjabLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajbjcjdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXaaaaaaaaaaaaxJgZhaewjehcjfbqbOjgjhjijjjkjljljljmjnjofYdAjpjpjqjqjqjqjqjqjqjqjrjqjqjqjsjtjujqdzjqjvjwjxjyjzjAjBjCjDjEjFjEjGjHcpjIjJjKjLjMjLbUamamamamamamamamamamamamamamamamamiDiDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/map_files/TgStation/tgstation.2.1.3.dmm b/_maps/map_files/TgStation/tgstation.2.1.3.dmm index d54c10c66f8..454dbfb2ca3 100644 --- a/_maps/map_files/TgStation/tgstation.2.1.3.dmm +++ b/_maps/map_files/TgStation/tgstation.2.1.3.dmm @@ -502,13 +502,13 @@ "ajH" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plasteel{dir = 8; icon_state = "redcorner"},/area/security/brig) "ajI" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel,/area/security/brig) "ajJ" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (NORTH)"; dir = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/security/brig) -"ajK" = (/obj/machinery/door_timer/cell_1,/obj/machinery/light,/obj/machinery/atmospherics/pipe/manifold/supply/hidden,/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) +"ajK" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/machinery/door_timer{id = "Cell 2"; name = "Cell 2"; pixel_y = -32},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) "ajL" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plasteel{dir = 8; icon_state = "redcorner"},/area/security/brig) -"ajM" = (/obj/machinery/door_timer/cell_2,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) -"ajN" = (/obj/machinery/door_timer/cell_3,/obj/machinery/camera{c_tag = "Brig Central"; dir = 1},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) +"ajM" = (/obj/machinery/light,/obj/machinery/atmospherics/pipe/manifold/supply/hidden,/obj/machinery/door_timer{id = "Cell 1"; name = "Cell 1"; pixel_y = -32},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) +"ajN" = (/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/machinery/door_timer{id = "Cell 4"; name = "Cell 4"; pixel_y = -32},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) "ajO" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) "ajP" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden,/turf/simulated/floor/plasteel{icon_state = "red"; dir = 9},/area/security/brig) -"ajQ" = (/obj/machinery/door_timer/cell_4,/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) +"ajQ" = (/obj/machinery/camera{c_tag = "Brig Central"; dir = 1},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/machinery/door_timer{id = "Cell 3"; name = "Cell 3"; pixel_y = -32},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig) "ajR" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/supply/hidden,/turf/simulated/floor/plasteel{dir = 8; icon_state = "redcorner"},/area/security/brig) "ajS" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plasteel,/area/security/brig) "ajT" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (NORTH)"; dir = 1},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/brig) @@ -657,7 +657,7 @@ "amG" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) "amH" = (/turf/simulated/wall,/area/maintenance/fpmaint2) "amI" = (/obj/structure/closet/crate,/turf/simulated/shuttle/floor,/area/space) -"amJ" = (/obj/machinery/door/airlock/shuttle{name = "Labor Shuttle Airlock"},/obj/docking_port/mobile{dir = 8; dwidth = 2; height = 5; id = "laborcamp"; name = "labor camp shuttle"; travelDir = 90; width = 9},/obj/docking_port/stationary{dir = 8; dwidth = 2; height = 5; id = "laborcamp_home"; name = "fore bay 1"; width = 9},/turf/simulated/shuttle/floor,/area/space) +"amJ" = (/obj/machinery/door/airlock/shuttle{id_tag = "prisonshuttle"; name = "Labor Shuttle Airlock"},/obj/docking_port/mobile{dir = 8; dwidth = 2; height = 5; id = "laborcamp"; name = "labor camp shuttle"; travelDir = 90; width = 9},/obj/docking_port/stationary{dir = 8; dwidth = 2; height = 5; id = "laborcamp_home"; name = "fore bay 1"; width = 9},/turf/simulated/shuttle/floor,/area/space) "amK" = (/obj/machinery/door/airlock/external{name = "Labor Camp Shuttle Airlock"},/turf/simulated/floor/plating,/area/security/processing) "amL" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/security{id_tag = "laborexit"; name = "Labor Shuttle"; req_access = null; req_access_txt = "63"},/turf/simulated/floor/plasteel,/area/security/processing) "amM" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 32},/obj/machinery/light{dir = 1},/turf/simulated/floor/plasteel,/area/hallway/primary/fore) @@ -2625,12 +2625,12 @@ "aYy" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/wall,/area/bridge/meeting_room) "aYz" = (/obj/machinery/door/airlock/command{name = "Conference Room"; req_access = null; req_access_txt = "19"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/wood,/area/bridge/meeting_room) "aYA" = (/turf/simulated/wall,/area/bridge/meeting_room) -"aYB" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 6},/turf/simulated/wall/r_wall,/area/bridge/meeting_room) +"aYB" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 6},/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) "aYC" = (/obj/machinery/porta_turret{ai = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai_upload) "aYD" = (/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) "aYE" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai_upload) "aYF" = (/obj/machinery/camera/motion{c_tag = "AI Upload Chamber"; dir = 2; network = list("SS13","RD","AIUpload")},/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) -"aYG" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 10},/turf/simulated/wall/r_wall,/area/crew_quarters/captain) +"aYG" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 10},/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) "aYH" = (/turf/simulated/wall/r_wall,/area/crew_quarters/captain) "aYI" = (/obj/machinery/door/airlock/command{name = "Captain's Office"; req_access = null; req_access_txt = "20"},/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/wood,/area/crew_quarters/captain) "aYJ" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/wall/r_wall,/area/crew_quarters/captain) @@ -2702,7 +2702,7 @@ "aZX" = (/obj/structure/table,/obj/item/weapon/aiModule/reset,/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai_upload) "aZY" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai_upload) "aZZ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/table,/obj/item/weapon/phone,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai_upload) -"baa" = (/obj/structure/table,/obj/item/weapon/aiModule/supplied/protectStation,/obj/machinery/light{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai_upload) +"baa" = (/obj/structure/table,/obj/machinery/light{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai_upload) "bab" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) "bac" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/captain) "bad" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/wood,/area/crew_quarters/captain) @@ -2728,6 +2728,7 @@ "bax" = (/obj/machinery/power/apc{dir = 8; name = "Vacant Office APC"; pixel_x = -24; pixel_y = 0},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/security/vacantoffice) "bay" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plating,/area/maintenance/port) "baz" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating,/area/maintenance/port) +"baA" = (/obj/structure/table,/obj/item/weapon/aiModule/supplied/oxygen,/obj/item/weapon/aiModule/zeroth/oneHuman,/obj/machinery/door/window{base_state = "left"; dir = 8; icon_state = "left"; name = "High-Risk Modules"; req_access_txt = "20"},/obj/item/weapon/aiModule/reset/purge,/obj/structure/window/reinforced,/obj/item/weapon/aiModule/core/full/antimov,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/item/weapon/aiModule/supplied/protectStation,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai_upload) "baB" = (/obj/machinery/door/airlock{name = "Unit 2"},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet) "baC" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/structure/mirror{pixel_x = 28},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet) "baD" = (/obj/machinery/washing_machine,/turf/simulated/floor/plasteel{icon_state = "barber"},/area/crew_quarters/locker) @@ -2853,7 +2854,7 @@ "bcT" = (/obj/machinery/power/apc{cell_type = 5000; dir = 2; name = "Upload APC"; pixel_y = -24},/obj/structure/cable,/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) "bcU" = (/obj/machinery/computer/upload/borg,/obj/item/device/radio/intercom{broadcasting = 1; frequency = 1447; listening = 0; name = "Station Intercom (AI Private)"; pixel_y = -29},/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) "bcV" = (/obj/machinery/light,/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai_upload) -"bcW" = (/obj/structure/table,/obj/item/weapon/aiModule/supplied/oxygen,/obj/item/weapon/aiModule/zeroth/oneHuman,/obj/machinery/door/window{base_state = "left"; dir = 8; icon_state = "left"; name = "High-Risk Modules"; req_access_txt = "20"},/obj/item/weapon/aiModule/reset/purge,/obj/structure/window/reinforced,/obj/item/weapon/aiModule/core/full/antimov,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai_upload) +"bcW" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 5},/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) "bcX" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor/wood,/area/crew_quarters/captain) "bcY" = (/obj/structure/stool/bed/chair,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/wood,/area/crew_quarters/captain) "bcZ" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/wood,/area/crew_quarters/captain) @@ -2882,6 +2883,7 @@ "bdw" = (/obj/machinery/newscaster{pixel_y = -32},/obj/machinery/light,/turf/simulated/floor/plasteel{dir = 2; icon_state = "escape"},/area/hallway/secondary/exit) "bdx" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitecorner"},/area/hallway/secondary/exit) "bdy" = (/obj/machinery/door/airlock/external{name = "Port Docking Bay 4"; req_access_txt = "0"},/turf/simulated/floor/plating,/area/hallway/secondary/entry) +"bdz" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 9},/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) "bdA" = (/obj/machinery/door/airlock/external{name = "Port Docking Bay 3"; req_access_txt = "0"},/turf/simulated/floor/plating,/area/hallway/secondary/entry) "bdB" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/entry) "bdC" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/entry) @@ -2915,13 +2917,13 @@ "bee" = (/obj/machinery/requests_console{announcementConsole = 1; department = "Bridge"; departmentType = 5; name = "Bridge RC"; pixel_y = -30},/obj/machinery/light,/turf/simulated/floor/wood,/area/bridge/meeting_room) "bef" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/fancy/carpet,/area/bridge/meeting_room) "beg" = (/obj/structure/noticeboard{dir = 8; pixel_x = 27; pixel_y = 0},/turf/simulated/floor/wood,/area/bridge/meeting_room) -"beh" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 5},/turf/simulated/wall/r_wall,/area/bridge/meeting_room) +"beh" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/regular{pixel_x = 0; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay) "bei" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{tag = "icon-manifold-r-f (EAST)"; dir = 4},/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) "bej" = (/obj/machinery/ai_status_display,/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) "bek" = (/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) "bel" = (/obj/machinery/status_display{density = 0; layer = 4},/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) "bem" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (WEST)"; dir = 8},/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) -"ben" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 9},/turf/simulated/wall/r_wall,/area/crew_quarters/captain) +"ben" = (/obj/structure/table,/obj/item/weapon/pen,/obj/machinery/camera{c_tag = "Experimentor Lab"; dir = 2; network = list("SS13","RD")},/obj/item/weapon/hand_labeler,/obj/item/stack/packageWrap,/turf/simulated/floor/plasteel{icon_state = "whitehall"; dir = 2},/area/toxins/explab) "beo" = (/obj/structure/table/wood,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/turf/simulated/floor/wood,/area/crew_quarters/captain) "bep" = (/obj/structure/table/wood,/obj/item/weapon/folder/blue,/obj/item/weapon/stamp/captain,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/wood,/area/crew_quarters/captain) "beq" = (/obj/structure/table/wood,/obj/item/weapon/hand_tele,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/wood,/area/crew_quarters/captain) @@ -3006,6 +3008,7 @@ "bfR" = (/obj/machinery/chem_dispenser,/turf/simulated/floor/plasteel{dir = 1; icon_state = "whiteyellow"},/area/medical/chemistry) "bfS" = (/obj/machinery/chem_master,/turf/simulated/floor/plasteel{dir = 5; icon_state = "whiteyellow"},/area/medical/chemistry) "bfT" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 101.325; on = 1; pressure_checks = 1},/obj/machinery/atmospherics/pipe/simple/general/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/prison) +"bfU" = (/obj/structure/closet/l3closet/scientist,/turf/simulated/floor/plasteel{icon_state = "whitehall"; dir = 2},/area/toxins/explab) "bfV" = (/obj/structure/stool/bed/chair,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay) "bfW" = (/obj/structure/stool/bed/chair,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay) "bfX" = (/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay) @@ -3082,6 +3085,7 @@ "bhq" = (/obj/structure/bodycontainer/morgue,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/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) "bhu" = (/obj/machinery/light/small{dir = 1},/obj/item/weapon/extinguisher,/turf/simulated/floor/plating,/area/storage/emergency) "bhv" = (/obj/item/weapon/storage/box/lights/mixed,/turf/simulated/floor/plating,/area/storage/emergency) "bhw" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/power/apc{dir = 4; name = "Mech Bay APC"; pixel_x = 26; pixel_y = 0},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plating,/area/assembly/chargebay) @@ -3492,7 +3496,7 @@ "bpl" = (/obj/machinery/computer/card,/turf/simulated/floor/plasteel{icon_state = "blue"; dir = 10},/area/crew_quarters/heads) "bpm" = (/turf/simulated/floor/plasteel,/area/crew_quarters/heads) "bpn" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/fancy/carpet,/area/crew_quarters/heads) -"bpo" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/mob/living/simple_animal/corgi/Ian,/turf/simulated/floor/fancy/carpet,/area/crew_quarters/heads) +"bpo" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/mob/living/simple_animal/pet/corgi/Ian,/turf/simulated/floor/fancy/carpet,/area/crew_quarters/heads) "bpp" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/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,/area/crew_quarters/heads) "bpq" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/apc{dir = 8; name = "Gravity Generator APC"; pixel_x = -25; pixel_y = 1},/obj/structure/table,/obj/item/weapon/paper/gravity_gen{layer = 3},/obj/item/weapon/pen/blue,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -35},/turf/simulated/floor/plasteel,/area/engine/gravity_generator) "bpr" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel,/area/engine/gravity_generator) @@ -3543,7 +3547,7 @@ "bqk" = (/obj/machinery/door/firedoor/heavy,/obj/machinery/door/poddoor/shutters/preopen{id = "rnd2"; name = "research lab shutters"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/lab) "bql" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/heavy,/obj/machinery/door/poddoor/shutters/preopen{id = "rnd2"; name = "research lab shutters"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/lab) "bqm" = (/obj/structure/grille,/obj/machinery/door/poddoor/shutters/preopen{id = "rnd2"; name = "research lab shutters"},/obj/structure/window/fulltile,/turf/simulated/floor/plating,/area/toxins/lab) -"bqn" = (/obj/structure/table,/obj/item/weapon/storage/firstaid,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay) +"bqn" = (/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,/obj/structure/disposalpipe/junction{tag = "icon-pipe-j2 (NORTH)"; icon_state = "pipe-j2"; dir = 1},/turf/simulated/floor/plating,/area/maintenance/asmaint2) "bqo" = (/obj/machinery/computer/libraryconsole,/obj/structure/table/wood,/turf/simulated/floor/wood,/area/library) "bqp" = (/obj/structure/table/wood,/obj/machinery/computer/libraryconsole/bookmanagement{pixel_y = 0},/obj/machinery/light_switch{pixel_y = 28},/turf/simulated/floor/wood,/area/library) "bqq" = (/obj/structure/table/glass,/obj/item/weapon/reagent_containers/glass/bottle/epinephrine,/obj/item/stack/sheet/mineral/plasma{layer = 2.9},/obj/item/stack/sheet/mineral/plasma{layer = 2.9},/obj/machinery/requests_console{department = "Chemistry"; departmentType = 2; pixel_x = -30; pixel_y = 0},/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry) @@ -3632,11 +3636,11 @@ "brV" = (/turf/simulated/wall/r_wall,/area/toxins/explab) "brW" = (/obj/structure/table/glass,/obj/item/weapon/storage/box/beakers{pixel_x = 2; pixel_y = 2},/obj/item/weapon/storage/box/beakers{pixel_x = 2; pixel_y = 2},/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/dropper,/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteyellow"},/area/medical/chemistry) "brX" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = 0; pixel_y = 6},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitecorner"},/area/toxins/explab) -"brY" = (/obj/structure/closet/l3closet/scientist{pixel_x = -2},/turf/simulated/floor/plasteel{icon_state = "whitehall"; dir = 2},/area/toxins/explab) +"brY" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/door/firedoor/heavy,/obj/machinery/door/airlock/research{name = "Experimentation Lab"; req_access_txt = "7"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/explab) "brZ" = (/obj/structure/table,/obj/item/weapon/folder/white,/obj/item/weapon/folder/white,/obj/machinery/alarm{frequency = 1439; pixel_y = 23},/obj/item/device/radio/off,/turf/simulated/floor/plasteel{icon_state = "whitehall"; dir = 2},/area/toxins/explab) "bsa" = (/obj/structure/closet/emcloset{pixel_x = -2},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitecorner"},/area/toxins/explab) -"bsb" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/structure/window/fulltile,/obj/machinery/door/firedoor/heavy,/turf/simulated/floor/plating,/area/toxins/explab) -"bsc" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/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/plating,/area/maintenance/asmaint2) +"bsb" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/asmaint2) +"bsc" = (/obj/machinery/camera{c_tag = "Experimentor Lab Chamber"; dir = 1; network = list("SS13","RD")},/obj/machinery/light,/obj/structure/sign/nosmoking_2{pixel_y = -32},/turf/simulated/floor/engine,/area/toxins/explab) "bsd" = (/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 2},/turf/simulated/floor/plating,/area/maintenance/asmaint2) "bse" = (/turf/simulated/floor/plating,/area/maintenance/asmaint2) "bsf" = (/obj/machinery/camera{c_tag = "Cargo Recieving Dock"; dir = 4},/obj/machinery/door_control{id = "QMLoaddoor"; layer = 4; name = "Loading Doors"; pixel_x = -24; pixel_y = -8},/obj/machinery/door_control{dir = 2; id = "QMLoaddoor2"; layer = 4; name = "Loading Doors"; pixel_x = -24; pixel_y = 8},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/quartermaster/storage) @@ -3646,6 +3650,7 @@ "bsj" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (EAST)"; dir = 4},/turf/simulated/floor/plasteel,/area/quartermaster/office) "bsk" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plasteel,/area/quartermaster/office) "bsl" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_mining{name = "Cargo Office"; req_access_txt = "50"},/turf/simulated/floor/plasteel,/area/quartermaster/office) +"bsm" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 6},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/asmaint2) "bsn" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{dir = 8; icon_state = "browncorner"},/area/hallway/primary/central) "bso" = (/obj/structure/table,/obj/machinery/recharger,/turf/simulated/floor/plasteel{dir = 9; icon_state = "blue"},/area/crew_quarters/heads) "bsp" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plasteel,/area/crew_quarters/heads) @@ -3698,7 +3703,7 @@ "btk" = (/obj/machinery/door/airlock/maintenance{name = "Experimentation Lab Maintenance"; req_access_txt = "7"},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/toxins/explab) "btl" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/explab) "btm" = (/obj/structure/table/reinforced,/obj/item/weapon/folder/white,/obj/item/weapon/pen,/obj/item/weapon/reagent_containers/glass/bottle/epinephrine,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay) -"btn" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plating,/area/maintenance/asmaint2) +"btn" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint2) "bto" = (/obj/docking_port/stationary{dir = 8; dwidth = 5; height = 7; id = "supply_home"; name = "supply bay"; width = 12},/turf/space,/area/space) "btp" = (/obj/machinery/conveyor_switch/oneway{convdir = -1; id = "QMLoad"},/turf/simulated/floor/plasteel,/area/quartermaster/storage) "btq" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 101.325; on = 1; pressure_checks = 1},/turf/simulated/floor/plasteel,/area/quartermaster/storage) @@ -3811,7 +3816,7 @@ "bvt" = (/obj/structure/table/glass,/obj/item/weapon/folder/white,/obj/item/device/radio/headset/headset_medsci,/obj/machinery/requests_console{department = "Genetics"; departmentType = 0; name = "Genetics Requests Console"; pixel_x = 0; pixel_y = 30},/obj/item/weapon/storage/pill_bottle/mutadone,/obj/item/weapon/storage/pill_bottle/mannitol,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/genetics) "bvu" = (/obj/machinery/atmospherics/unary/cryo_cell,/turf/simulated/floor/plasteel,/area/medical/sleeper) "bvv" = (/obj/structure/table,/obj/machinery/cell_charger,/turf/simulated/floor/plasteel,/area/medical/sleeper) -"bvw" = (/obj/structure/table,/obj/item/weapon/pen,/obj/machinery/camera{c_tag = "Telescience Lab"; dir = 2; network = list("SS13","RD")},/obj/item/weapon/hand_labeler,/obj/item/stack/packageWrap,/turf/simulated/floor/plasteel{icon_state = "whitehall"; dir = 2},/area/toxins/explab) +"bvw" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 9},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/asmaint2) "bvx" = (/obj/machinery/camera{c_tag = "Genetics Cloning"; dir = 4; network = list("SS13")},/obj/structure/table,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/item/weapon/storage/box/rxglasses{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/box/bodybags,/obj/item/weapon/pen,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/genetics) "bvy" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (WEST)"; dir = 8},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/genetics) "bvz" = (/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/genetics) @@ -3840,7 +3845,7 @@ "bvW" = (/obj/machinery/computer/aifixer,/obj/machinery/requests_console{announcementConsole = 1; department = "Research Director's Desk"; departmentType = 5; name = "Research Director RC"; pixel_x = -2; pixel_y = 30},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plasteel{icon_state = "cafeteria"},/area/crew_quarters/hor) "bvX" = (/obj/structure/rack,/obj/item/weapon/circuitboard/aicore{pixel_x = -2; pixel_y = 4},/turf/simulated/floor/plasteel{dir = 9; icon_state = "warnwhite"},/area/crew_quarters/hor) "bvY" = (/obj/machinery/ai_status_display{pixel_y = 32},/turf/simulated/floor/plasteel{icon_state = "warnwhite"; dir = 1},/area/crew_quarters/hor) -"bvZ" = (/obj/machinery/door/airlock/research{name = "Experimentation Lab"; req_access_txt = "7"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/door/firedoor/heavy,/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/explab) +"bvZ" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/asmaint2) "bwa" = (/obj/machinery/power/apc{dir = 4; name = "Experimentation Lab APC"; pixel_x = 26; pixel_y = 0},/obj/structure/cable,/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/explab) "bwb" = (/obj/machinery/requests_console{department = "Science"; departmentType = 2; name = "Science Requests Console"; pixel_x = 0; pixel_y = -30},/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/explab) "bwc" = (/obj/machinery/light_switch{pixel_x = -20; pixel_y = 0},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/explab) @@ -4199,7 +4204,7 @@ "bCR" = (/obj/structure/grille,/obj/structure/window/reinforced/fulltile,/turf/simulated/floor/plating,/area/medical/cmo) "bCS" = (/obj/structure/table/glass,/obj/item/weapon/paper_bin{pixel_x = -2; pixel_y = 5},/turf/simulated/floor/plasteel{icon_state = "barber"},/area/medical/cmo) "bCT" = (/obj/structure/table/glass,/obj/item/weapon/folder/white,/obj/item/weapon/stamp/cmo,/obj/item/clothing/glasses/hud/health,/turf/simulated/floor/plasteel{icon_state = "barber"},/area/medical/cmo) -"bCU" = (/obj/structure/table/glass,/obj/item/weapon/pen,/obj/item/clothing/tie/stethoscope,/mob/living/simple_animal/cat/Runtime,/turf/simulated/floor/plasteel{icon_state = "barber"},/area/medical/cmo) +"bCU" = (/obj/structure/table/glass,/obj/item/weapon/pen,/obj/item/clothing/tie/stethoscope,/mob/living/simple_animal/pet/cat/Runtime,/turf/simulated/floor/plasteel{icon_state = "barber"},/area/medical/cmo) "bCV" = (/obj/structure/disposalpipe/segment,/obj/item/device/radio/intercom{pixel_x = 25},/obj/machinery/camera{c_tag = "Chief Medical Office"; dir = 8; network = list("SS13"); pixel_x = 0; pixel_y = -22},/turf/simulated/floor/plasteel{icon_state = "barber"},/area/medical/cmo) "bCW" = (/turf/simulated/floor/engine,/area/toxins/xenobiology) "bCX" = (/obj/machinery/camera{c_tag = "Xenobiology Test Chamber"; dir = 2; network = list("Xeno","RD"); pixel_x = 0},/obj/machinery/light{dir = 1},/turf/simulated/floor/engine,/area/toxins/xenobiology) @@ -4220,9 +4225,9 @@ "bDm" = (/obj/machinery/atmospherics/unary/portables_connector/visible,/turf/simulated/floor/plasteel{icon_state = "warnwhite"; dir = 5},/area/toxins/mixing) "bDn" = (/turf/simulated/wall/r_wall,/area/toxins/mixing) "bDo" = (/obj/structure/closet/crate,/obj/effect/spawner/lootdrop/maintenance{lootcount = 4; name = "4maintenance loot spawner"},/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"bDp" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 6},/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"bDq" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"bDr" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 9},/turf/simulated/floor/plating,/area/maintenance/asmaint2) +"bDp" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (WEST)"; dir = 8},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/toxins/mixing) +"bDq" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/o2{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/firstaid/o2,/obj/item/weapon/storage/firstaid/regular{pixel_x = -3; pixel_y = -3},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) +"bDr" = (/obj/structure/table,/obj/machinery/requests_console{announcementConsole = 0; department = "Medbay"; departmentType = 1; name = "Medbay RC"; pixel_x = 0; pixel_y = -30; pixel_z = 0},/obj/item/weapon/storage/firstaid/fire{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/firstaid/fire,/obj/item/weapon/storage/firstaid/regular{pixel_x = -3; pixel_y = -3},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) "bDs" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/wall,/area/toxins/mixing) "bDt" = (/obj/machinery/computer/security/mining,/obj/machinery/camera{c_tag = "Mining Dock"; dir = 4; network = list("SS13")},/turf/simulated/floor/plasteel,/area/quartermaster/miningdock) "bDu" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 5},/turf/simulated/floor/plasteel,/area/quartermaster/miningdock) @@ -4290,7 +4295,7 @@ "bEE" = (/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 5},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/mixing) "bEF" = (/obj/machinery/atmospherics/pipe/manifold/general/visible,/obj/machinery/meter,/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/mixing) "bEG" = (/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 9},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/mixing) -"bEH" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plating,/area/maintenance/asmaint2) +"bEH" = (/obj/structure/table,/obj/item/device/radio/intercom{broadcasting = 0; freerange = 0; frequency = 1485; listening = 1; name = "Station Intercom (Medbay)"; pixel_x = 0; pixel_y = -30},/obj/item/weapon/storage/firstaid/toxin{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/firstaid/toxin,/obj/item/weapon/storage/firstaid/regular{pixel_x = -3; pixel_y = -3},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) "bEI" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 6},/turf/simulated/wall,/area/maintenance/asmaint2) "bEJ" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/wall,/area/toxins/mixing) "bEK" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 9},/turf/simulated/wall,/area/toxins/mixing) @@ -4338,6 +4343,7 @@ "bFA" = (/obj/machinery/vending/wallmed{pixel_x = 28; pixel_y = 0},/obj/machinery/camera{c_tag = "Medbay Recovery Room"; dir = 8; network = list("SS13")},/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{tag = "icon-manifold-r-f (EAST)"; dir = 4},/obj/structure/closet/wardrobe/pjs,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) "bFB" = (/obj/structure/grille,/obj/machinery/door/poddoor/preopen{id = "telelab"; name = "test chamber blast door"},/obj/structure/window/reinforced/fulltile,/obj/machinery/door/firedoor/heavy,/turf/simulated/floor/engine,/area/toxins/explab) "bFC" = (/obj/structure/table,/obj/item/weapon/hand_labeler,/obj/item/weapon/gun/syringe,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) +"bFD" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/brute{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/firstaid/brute,/obj/item/weapon/storage/firstaid/regular{pixel_x = -3; pixel_y = -3},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) "bFE" = (/obj/structure/stool/bed/chair/office/light{dir = 8},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay) "bFF" = (/obj/structure/closet/secure_closet/personal/patient,/obj/machinery/door_control{id = "medpriv4"; name = "Privacy Shutters"; pixel_y = 25},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay) "bFG" = (/obj/structure/grille,/obj/machinery/door/poddoor/preopen{id = "medpriv4"; name = "privacy door"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/structure/window/fulltile,/turf/simulated/floor/plating,/area/medical/medbay) @@ -4360,7 +4366,7 @@ "bFX" = (/obj/machinery/door/firedoor/heavy,/obj/machinery/door/airlock/research{name = "Toxins Lab"; req_access_txt = "8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/mixing) "bFY" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 101.325; on = 1; pressure_checks = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/mixing) "bFZ" = (/obj/structure/sign/securearea{pixel_x = -32},/turf/simulated/floor/plasteel{icon_state = "warningcorner"; dir = 1},/area/toxins/mixing) -"bGa" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (WEST)"; dir = 8},/turf/simulated/floor/plasteel,/area/toxins/mixing) +"bGa" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/toxins/mixing) "bGb" = (/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plasteel{icon_state = "warningcorner"; dir = 2},/area/toxins/mixing) "bGc" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/wall,/area/toxins/mixing) "bGd" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/item/device/radio/intercom{pixel_y = 25},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plasteel,/area/toxins/mixing) @@ -4397,7 +4403,7 @@ "bGI" = (/obj/structure/disposalpipe/segment,/obj/structure/grille,/obj/structure/window/fulltile,/turf/simulated/floor/plating,/area/maintenance/asmaint) "bGJ" = (/obj/structure/closet/secure_closet/medical2,/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel,/area/medical/sleeper) "bGK" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor/plasteel{icon_state = "whitehall"; dir = 1},/area/medical/sleeper) -"bGL" = (/obj/machinery/camera{c_tag = "Telescience Test Chamber"; dir = 1; network = list("SS13","RD")},/obj/machinery/light,/obj/structure/sign/nosmoking_2{pixel_y = -32},/turf/simulated/floor/engine,/area/toxins/explab) +"bGL" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/toxins/mixing) "bGM" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel{icon_state = "whitehall"; dir = 1},/area/medical/sleeper) "bGN" = (/obj/structure/table,/obj/item/weapon/reagent_containers/glass/bottle/epinephrine{pixel_x = 7; pixel_y = -3},/obj/item/weapon/reagent_containers/glass/bottle/morphine,/obj/item/weapon/reagent_containers/syringe,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) "bGO" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/medical,/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) @@ -4405,9 +4411,9 @@ "bGQ" = (/obj/structure/closet/crate/freezer,/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 101.325; on = 1; pressure_checks = 1},/obj/item/weapon/reagent_containers/blood/empty,/obj/item/weapon/reagent_containers/blood/empty{pixel_x = -3; pixel_y = -3},/obj/item/weapon/reagent_containers/blood/AMinus,/obj/item/weapon/reagent_containers/blood/BMinus{pixel_x = -4; pixel_y = 4},/obj/item/weapon/reagent_containers/blood/BPlus{pixel_x = 1; pixel_y = 2},/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OPlus{pixel_x = -2; pixel_y = -1},/obj/item/weapon/reagent_containers/blood/random,/obj/item/weapon/reagent_containers/blood/random,/obj/item/weapon/reagent_containers/blood/random,/turf/simulated/floor/plasteel,/area/medical/sleeper) "bGR" = (/obj/structure/table,/obj/machinery/light,/obj/item/weapon/reagent_containers/spray/cleaner,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) "bGS" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/structure/closet/secure_closet/medical1,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) -"bGT" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/regular{pixel_x = 3; pixel_y = -3},/obj/item/weapon/storage/firstaid/o2{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/firstaid/o2,/obj/item/weapon/storage/firstaid/o2{pixel_x = -3; pixel_y = -3},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) -"bGU" = (/obj/structure/table,/obj/machinery/requests_console{announcementConsole = 0; department = "Medbay"; departmentType = 1; name = "Medbay RC"; pixel_x = 0; pixel_y = -30; pixel_z = 0},/obj/item/weapon/storage/firstaid/regular{pixel_x = 3; pixel_y = -3},/obj/item/weapon/storage/firstaid/fire{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/firstaid/fire,/obj/item/weapon/storage/firstaid/fire{pixel_x = -3; pixel_y = -3},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) -"bGV" = (/obj/structure/table,/obj/item/device/radio/intercom{broadcasting = 0; freerange = 0; frequency = 1485; listening = 1; name = "Station Intercom (Medbay)"; pixel_x = 0; pixel_y = -30},/obj/item/weapon/storage/firstaid/regular{pixel_x = 3; pixel_y = -3},/obj/item/weapon/storage/firstaid/toxin{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/firstaid/toxin,/obj/item/weapon/storage/firstaid/toxin{pixel_x = -3; pixel_y = -3},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) +"bGT" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/asmaint2) +"bGU" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plating{tag = "icon-platingdmg3"; icon_state = "platingdmg3"},/area/maintenance/asmaint2) +"bGV" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/asmaint2) "bGW" = (/obj/machinery/light,/obj/structure/table,/obj/item/weapon/storage/box/beakers{pixel_x = 2; pixel_y = 2},/obj/item/weapon/storage/box/syringes,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) "bGX" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/medical,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay) "bGY" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay) @@ -4437,7 +4443,7 @@ "bHw" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/mixing) "bHx" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/firedoor/heavy,/obj/machinery/door/airlock/research{name = "Toxins Launch Room Access"; req_access_txt = "8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/mixing) "bHy" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/toxins/mixing) -"bHz" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plasteel,/area/toxins/mixing) +"bHz" = (/obj/structure/grille,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/structure/window/reinforced/tinted/fulltile,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/asmaint2) "bHA" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{tag = "icon-manifold-r-f (WEST)"; dir = 8},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/toxins/mixing) "bHB" = (/obj/machinery/door/airlock/research{name = "Toxins Launch Room"; req_access_txt = "8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plasteel,/area/toxins/mixing) "bHC" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plasteel,/area/toxins/mixing) @@ -4474,7 +4480,7 @@ "bIh" = (/obj/effect/landmark{name = "blobstart"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint) "bIi" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint) "bIj" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{tag = "icon-manifold-r-f (NORTH)"; dir = 1},/turf/simulated/floor/plating,/area/maintenance/asmaint) -"bIk" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/regular{pixel_x = 3; pixel_y = -3},/obj/item/weapon/storage/firstaid/brute{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/firstaid/brute,/obj/item/weapon/storage/firstaid/brute{pixel_x = -3; pixel_y = -3},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper) +"bIk" = (/obj/machinery/atmospherics/binary/valve/open{tag = "icon-mvalve_map (EAST)"; icon_state = "mvalve_map"; dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/asmaint) "bIl" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay) "bIm" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay) "bIn" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/shieldwallgen{req_access = list(55)},/turf/simulated/floor/plating,/area/toxins/xenobiology) @@ -4497,7 +4503,7 @@ "bIE" = (/obj/structure/dispenser,/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/mixing) "bIF" = (/obj/machinery/power/apc{dir = 4; name = "Toxins Lab APC"; pixel_x = 26; pixel_y = 0},/obj/structure/cable,/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/mixing) "bIG" = (/turf/simulated/floor/plasteel{icon_state = "warningcorner"; dir = 4},/area/toxins/mixing) -"bIH" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plasteel,/area/toxins/mixing) +"bIH" = (/obj/machinery/alarm{frequency = 1439; pixel_y = 23},/obj/item/weapon/wrench,/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (WEST)"; dir = 8},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/maintenance/asmaint) "bII" = (/obj/machinery/camera{c_tag = "Toxins Launch Room Access"; dir = 1},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plasteel{icon_state = "warningcorner"; dir = 8},/area/toxins/mixing) "bIJ" = (/obj/machinery/door/window/southleft{name = "Mass Driver Door"; req_access_txt = "7"},/turf/simulated/floor/plasteel{icon_state = "loadingarea"},/area/toxins/mixing) "bIK" = (/obj/structure/grille,/obj/structure/window/fulltile,/turf/simulated/floor/plating,/area/toxins/mixing) @@ -4907,8 +4913,8 @@ "bQy" = (/obj/machinery/atmospherics/pipe/manifold/general/visible,/turf/simulated/floor/engine,/area/toxins/misc_lab) "bQz" = (/obj/machinery/atmospherics/unary/cold_sink/freezer{dir = 8},/turf/simulated/floor/engine,/area/toxins/misc_lab) "bQA" = (/obj/machinery/magnetic_module,/obj/effect/landmark{name = "blobstart"},/obj/structure/target_stake,/turf/simulated/floor/plasteel{dir = 2; icon_state = "bot"},/area/toxins/misc_lab) -"bQB" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"bQC" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating{tag = "icon-platingdmg3"; icon_state = "platingdmg3"},/area/maintenance/asmaint2) +"bQB" = (/obj/machinery/atmospherics/unary/tank/air{dir = 8},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 5},/area/maintenance/asmaint) +"bQC" = (/obj/machinery/atmospherics/binary/valve{dir = 4},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/asmaint) "bQD" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/aft) "bQE" = (/obj/structure/rack,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/aft) "bQF" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/aft) @@ -4956,7 +4962,7 @@ "bRv" = (/turf/simulated/floor/plasteel{dir = 10; icon_state = "warning"},/area/toxins/misc_lab) "bRw" = (/turf/simulated/floor/plasteel{dir = 6; icon_state = "warning"},/area/toxins/misc_lab) "bRx" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/wall,/area/maintenance/asmaint2) -"bRy" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating,/area/maintenance/asmaint2) +"bRy" = (/obj/structure/stool{pixel_y = 8},/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 5},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/maintenance/asmaint) "bRz" = (/obj/machinery/atmospherics/unary/outlet_injector,/turf/simulated/floor/plating/airless,/area/space) "bRA" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/aft) "bRB" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 6},/turf/simulated/wall,/area/maintenance/aft) @@ -5068,7 +5074,7 @@ "bTD" = (/obj/structure/table,/obj/item/stack/sheet/glass{amount = 50; pixel_x = 3; pixel_y = 3},/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/mineral/plasma{layer = 2.9},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 10},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/toxins/misc_lab) "bTE" = (/obj/machinery/camera{c_tag = "Testing Firing Range"; dir = 8; network = list("SS13","RD"); pixel_y = -22},/turf/simulated/floor/plating,/area/toxins/misc_lab) "bTF" = (/obj/structure/target_stake,/turf/simulated/floor/plating,/area/toxins/misc_lab) -"bTG" = (/obj/structure/grille,/obj/structure/window/reinforced/fulltile,/turf/simulated/floor/plating,/area/space) +"bTG" = (/obj/machinery/atmospherics/unary/portables_connector/visible{dir = 8},/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 6},/area/maintenance/asmaint) "bTH" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/visible,/turf/simulated/floor/plating,/area/maintenance/aft) "bTI" = (/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/aft) "bTJ" = (/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 5},/turf/simulated/floor/plating,/area/maintenance/aft) @@ -5115,8 +5121,8 @@ "bUy" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (NORTH)"; dir = 1},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/toxins/misc_lab) "bUz" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 10},/turf/simulated/floor/plasteel,/area/toxins/misc_lab) "bUA" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plasteel{icon_state = "warningcorner"; dir = 2},/area/toxins/misc_lab) -"bUB" = (/obj/machinery/door/airlock/external{name = "External Access"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/space) -"bUC" = (/turf/simulated/floor/plating,/area/space) +"bUB" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating{tag = "icon-platingdmg3"; icon_state = "platingdmg3"},/area/maintenance/asmaint2) +"bUC" = (/obj/machinery/light/small,/turf/simulated/floor/plating,/area/maintenance/asmaint2) "bUD" = (/obj/machinery/door/airlock/external{name = "External Access"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/maintenance/aft) "bUE" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/visible,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/aft) "bUF" = (/obj/machinery/atmospherics/pipe/simple/general/visible,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/aft) @@ -5148,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/carbon/slime,/turf/simulated/floor/engine,/area/toxins/xenobiology) +"bVi" = (/mob/living/simple_animal/slime,/turf/simulated/floor/engine,/area/toxins/xenobiology) "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) @@ -5164,7 +5170,7 @@ "bVv" = (/obj/structure/table/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/recharger{pixel_y = 4},/obj/item/weapon/paper/range,/turf/simulated/floor/plating{tag = "icon-warnplate (SOUTHEAST)"; icon_state = "warnplate"; dir = 6},/area/toxins/misc_lab) "bVw" = (/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/toxins/misc_lab) "bVx" = (/obj/structure/table/reinforced,/obj/machinery/magnetic_controller{autolink = 1},/obj/structure/window/reinforced{dir = 1},/obj/item/device/radio/intercom{freerange = 0; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29},/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor/plating{tag = "icon-warnplate (SOUTHWEST)"; icon_state = "warnplate"; dir = 10},/area/toxins/misc_lab) -"bVy" = (/obj/structure/grille,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/structure/window/reinforced/tinted/fulltile,/turf/simulated/floor/plating,/area/maintenance/asmaint2) +"bVy" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = -32},/turf/simulated/floor/plating,/area/maintenance/asmaint2) "bVz" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plating,/area/maintenance/aft) "bVA" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{dir = 5},/turf/simulated/floor/plating,/area/maintenance/aft) "bVB" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{dir = 4},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/aft) @@ -5284,9 +5290,9 @@ "bXL" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/asmaint) "bXM" = (/obj/effect/decal/cleanable/cobweb2,/obj/effect/spawner/lootdrop/maintenance,/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{tag = "icon-manifold-r-f (WEST)"; dir = 8},/turf/simulated/floor/plating,/area/maintenance/asmaint) "bXN" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 10},/turf/simulated/wall/r_wall,/area/medical/virology) -"bXO" = (/obj/machinery/alarm{frequency = 1439; pixel_y = 23},/obj/item/weapon/wrench,/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (WEST)"; dir = 8},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/medical/virology) -"bXP" = (/obj/machinery/atmospherics/binary/valve/open{tag = "icon-mvalve_map (EAST)"; icon_state = "mvalve_map"; dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/medical/virology) -"bXQ" = (/obj/machinery/atmospherics/unary/tank/air{dir = 8},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 5},/area/medical/virology) +"bXO" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 9},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/asmaint2) +"bXP" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/asmaint2) +"bXQ" = (/obj/structure/grille,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/window/reinforced/tinted/fulltile,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint2) "bXR" = (/obj/structure/closet/emcloset,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/plating,/area/maintenance/asmaint) "bXS" = (/obj/structure/rack{dir = 1},/obj/machinery/light/small{dir = 1},/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/asmaint) "bXT" = (/obj/structure/grille,/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/door/poddoor/preopen{id = "xenobio1"; name = "containment blast door"},/obj/structure/window/reinforced/fulltile,/turf/simulated/floor/engine,/area/toxins/xenobiology) @@ -5332,9 +5338,9 @@ "bYH" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating,/area/maintenance/asmaint) "bYI" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 10},/turf/simulated/floor/plating,/area/maintenance/asmaint) "bYJ" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating,/area/maintenance/asmaint) -"bYK" = (/obj/structure/stool{pixel_y = 8},/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 5},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/medical/virology) -"bYL" = (/obj/machinery/atmospherics/binary/valve{dir = 4},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/medical/virology) -"bYM" = (/obj/machinery/atmospherics/unary/portables_connector/visible{dir = 8},/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 6},/area/medical/virology) +"bYK" = (/obj/structure/reagent_dispensers/watertank,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 9},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint2) +"bYL" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint2) +"bYM" = (/obj/structure/rack{dir = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/effect/spawner/lootdrop/maintenance,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint2) "bYN" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 6},/turf/simulated/floor/plating,/area/maintenance/asmaint) "bYO" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{tag = "icon-manifold-r-f (EAST)"; dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint) "bYP" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plating,/area/maintenance/asmaint) @@ -5349,7 +5355,7 @@ "bYY" = (/obj/machinery/power/apc{dir = 4; name = "Testing Lab APC"; pixel_x = 26; pixel_y = 0},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/toxins/misc_lab) "bYZ" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plasteel,/area/toxins/misc_lab) "bZa" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"bZb" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating{tag = "icon-platingdmg3"; icon_state = "platingdmg3"},/area/maintenance/asmaint2) +"bZb" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint2) "bZc" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = -2; pixel_y = 5},/turf/simulated/floor/plating,/area/maintenance/asmaint2) "bZd" = (/obj/structure/table,/obj/item/weapon/folder/white,/obj/item/weapon/folder/white,/obj/item/weapon/pen,/turf/simulated/floor/plating,/area/maintenance/asmaint2) "bZe" = (/obj/structure/closet,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/aft) @@ -5457,6 +5463,7 @@ "cbc" = (/obj/machinery/computer/telecomms/monitor{network = "tcommsat"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "yellow"},/area/tcommsat/computer) "cbd" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{tag = "icon-manifold-r-f (WEST)"; dir = 8},/turf/simulated/floor/plating,/area/construction) "cbe" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 9},/turf/simulated/floor/plasteel{dir = 8; icon_state = "cautioncorner"},/area/hallway/primary/aft) +"cbf" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 6},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint2) "cbg" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/hallway/primary/aft) "cbh" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "yellow"},/area/hallway/primary/aft) "cbi" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_engineering{name = "Engineering"; req_access_txt = "32"},/turf/simulated/floor/plasteel,/area/engine/break_room) @@ -5540,12 +5547,12 @@ "ccI" = (/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,/area/toxins/misc_lab) "ccJ" = (/obj/item/stack/sheet/cardboard,/turf/simulated/floor/plating,/area/maintenance/asmaint2) "ccK" = (/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"ccL" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"ccM" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"ccN" = (/obj/machinery/light/small,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"ccO" = (/obj/machinery/door/airlock/external{name = "Starboard Docking Bay 2"; req_access_txt = "13"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"ccP" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = -32},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"ccQ" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/lattice/catwalk,/turf/space,/area/space) +"ccL" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint2) +"ccM" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 9},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/asmaint2) +"ccN" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/engine_smes) +"ccO" = (/obj/structure/grille,/obj/structure/window/reinforced/fulltile,/turf/simulated/floor/plating/airless,/area/engine/engineering) +"ccP" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/wall,/area/aisat) +"ccQ" = (/obj/structure/window/reinforced{dir = 4},/turf/simulated/wall,/area/aisat) "ccR" = (/obj/item/clothing/under/rank/vice,/obj/structure/closet,/obj/item/clothing/shoes/jackboots,/turf/simulated/floor/plating,/area/maintenance/aft) "ccS" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/aft) "ccT" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/engine/engineering) @@ -5624,7 +5631,7 @@ "ceo" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/wall,/area/maintenance/asmaint2) "cep" = (/obj/machinery/space_heater,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint2) "ceq" = (/obj/structure/sign/securearea{pixel_y = 32},/obj/effect/spawner/lootdrop/maintenance,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"cer" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 9},/turf/simulated/floor/plating,/area/maintenance/asmaint2) +"cer" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/lattice,/obj/structure/grille,/turf/space,/area/space) "ces" = (/obj/structure/rack{dir = 1},/obj/effect/decal/cleanable/cobweb2,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating,/area/maintenance/asmaint2) "cet" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 6},/turf/simulated/wall,/area/maintenance/asmaint2) "ceu" = (/obj/machinery/door/airlock/maintenance{name = "Research Delivery access"; req_access_txt = "12"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint2) @@ -5679,14 +5686,14 @@ "cfr" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{tag = "icon-manifold-r-f (NORTH)"; dir = 1},/turf/simulated/floor/plating,/area/maintenance/asmaint2) "cfs" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = "90Curve"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plating,/area/maintenance/asmaint2) "cft" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"cfu" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"cfv" = (/obj/structure/reagent_dispensers/watertank,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 9},/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"cfw" = (/obj/structure/grille,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/window/reinforced/tinted/fulltile,/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"cfx" = (/obj/structure/rack{dir = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"cfy" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"cfz" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 6},/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"cfA" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"cfB" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 9},/turf/simulated/floor/plating,/area/maintenance/asmaint2) +"cfu" = (/obj/structure/lattice,/obj/structure/window/reinforced,/obj/structure/grille,/turf/space,/area/space) +"cfv" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/lattice,/obj/structure/grille,/turf/space,/area/space) +"cfw" = (/obj/structure/lattice,/obj/structure/grille,/obj/structure/window/reinforced,/turf/space,/area/space) +"cfx" = (/obj/structure/window/reinforced,/obj/machinery/door/window{base_state = "right"; dir = 1; icon_state = "right"; name = "MiniSat Walkway Access"; req_access_txt = "13;65"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plating,/area/aisat) +"cfy" = (/obj/structure/window/reinforced,/obj/machinery/door/window{dir = 1; name = "MiniSat Walkway Access"; req_access_txt = "13;65"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plating,/area/aisat) +"cfz" = (/obj/machinery/door/window{name = "AI Core Door"; req_access_txt = "16"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai) +"cfA" = (/obj/machinery/power/apc{cell_type = 5000; dir = 1; name = "AI Chamber APC"; pixel_y = 24},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai) +"cfB" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "cfC" = (/obj/structure/closet/firecloset,/turf/simulated/floor/plating,/area/maintenance/asmaint2) "cfD" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 1; on = 1},/turf/simulated/floor/plating/airless,/area/space) "cfE" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/lattice/catwalk,/turf/space,/area/solar/port) @@ -5954,7 +5961,7 @@ "ckG" = (/obj/structure/grille,/obj/structure/window/reinforced/fulltile,/turf/simulated/floor/plating,/area/maintenance/starboardsolar) "ckH" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/airlock/external{name = "Solar Maintenance"; req_access = null; req_access_txt = "10; 13"},/turf/simulated/floor/plating,/area/maintenance/starboardsolar) "ckI" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/lattice/catwalk,/turf/space,/area/solar/port) -"ckJ" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 7; on = 1},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/engine_smes) +"ckJ" = (/obj/machinery/hologram/holopad,/obj/machinery/power/terminal,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai) "ckK" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 4},/area/engine/engine_smes) "ckL" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 8},/area/engine/engine_smes) "ckM" = (/obj/machinery/power/smes,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 1},/area/engine/engine_smes) @@ -6148,7 +6155,7 @@ "cos" = (/obj/structure/lattice/catwalk,/turf/space,/area/solar/starboard) "cot" = (/obj/structure/table,/obj/item/device/taperecorder{pixel_y = 0},/turf/simulated/floor/plating,/area/maintenance/aft) "cou" = (/obj/structure/table,/obj/item/weapon/storage/box/matches,/obj/item/weapon/storage/fancy/cigarettes,/turf/simulated/floor/plating,/area/maintenance/aft) -"cov" = (/obj/structure/grille,/obj/structure/window/reinforced/fulltile,/turf/simulated/floor/plating/airless,/area/space) +"cov" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai) "cow" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"},/turf/simulated/wall/r_wall,/area/engine/engineering) "cox" = (/obj/structure/grille,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/window/reinforced/fulltile,/turf/simulated/floor/plating,/area/engine/engineering) "coy" = (/obj/structure/grille,/obj/structure/cable,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/window/reinforced/fulltile,/turf/simulated/floor/plating,/area/engine/engineering) @@ -6362,20 +6369,17 @@ "csy" = (/obj/machinery/ai_slipper{icon_state = "motion0"; uses = 10},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "csz" = (/obj/item/device/radio/intercom{broadcasting = 0; freerange = 1; listening = 1; name = "Common Channel"; pixel_x = -27; pixel_y = 5},/obj/item/device/radio/intercom{anyai = 1; freerange = 1; listening = 0; name = "Custom Channel"; pixel_x = 0; pixel_y = 27},/obj/item/device/radio/intercom{anyai = 1; broadcasting = 0; freerange = 1; frequency = 1447; name = "Private Channel"; pixel_x = 27; pixel_y = 5},/obj/effect/landmark/start{name = "AI"},/obj/machinery/requests_console{department = "AI"; departmentType = 5; pixel_x = 32; pixel_y = 32},/obj/machinery/newscaster/security_unit{pixel_x = -32; pixel_y = 32},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "csA" = (/obj/effect/landmark{name = "tripai"},/obj/item/device/radio/intercom{anyai = 1; freerange = 1; listening = 0; name = "Custom Channel"; pixel_x = 0; pixel_y = 28},/obj/item/device/radio/intercom{broadcasting = 0; freerange = 1; listening = 1; name = "Common Channel"; pixel_x = 27; pixel_y = 5},/obj/item/device/radio/intercom{anyai = 1; broadcasting = 0; freerange = 1; frequency = 1447; name = "Private Channel"; pixel_x = 0; pixel_y = -25},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) -"csB" = (/obj/machinery/power/apc{cell_type = 5000; dir = 1; name = "AI Chamber APC"; pixel_y = 24},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai) -"csC" = (/obj/machinery/door/window{name = "AI Core Door"; req_access_txt = "16"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai) +"csB" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai) +"csC" = (/obj/machinery/power/smes{charge = 5e+006},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai) "csD" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/turretid{name = "AI Chamber turret control"; pixel_x = 5; pixel_y = 24},/obj/machinery/flasher{id = "AI"; pixel_x = -6; pixel_y = 24},/obj/machinery/camera/motion{c_tag = "AI Chamber South"; dir = 2; network = list("RD","MiniSat")},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai) -"csE" = (/obj/machinery/ai_slipper{icon_state = "motion0"; uses = 10},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) +"csE" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/wall/r_wall,/area/turret_protected/ai) "csF" = (/obj/machinery/light,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai) -"csG" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai) -"csH" = (/obj/machinery/hologram/holopad,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai) -"csI" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai) +"csG" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/wall/r_wall,/area/turret_protected/ai) +"csH" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/wall/r_wall,/area/turret_protected/ai) +"csI" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/wall/r_wall,/area/turret_protected/ai) "csJ" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/light/small{dir = 4},/obj/machinery/camera{c_tag = "MiniSat Exterior South West"; dir = 8; network = list("MiniSat"); pixel_x = 0; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plating,/area/aisat) -"csK" = (/obj/machinery/power/smes{charge = 5e+006},/obj/structure/cable,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai) "csL" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/light/small{dir = 8},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/camera{c_tag = "MiniSat Exterior South East"; dir = 4; network = list("MiniSat"); pixel_x = 0; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating,/area/aisat) "csM" = (/obj/docking_port/stationary{dheight = 9; dir = 2; dwidth = 5; height = 22; id = "syndicate_se"; name = "southeast of station"; turf_type = /turf/space; width = 18},/turf/space,/area/space) -"csN" = (/turf/simulated/wall/r_wall,/area/ai_monitored/storage/secure) -"csO" = (/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/wall/r_wall,/area/turret_protected/ai) "csP" = (/turf/simulated/wall,/area/ai_monitored/storage/secure) "csQ" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/machinery/camera{c_tag = "MiniSat Entrance"; dir = 4; network = list("MiniSat"); pixel_x = 0; pixel_y = 0},/obj/machinery/power/apc{dir = 8; name = "MiniSat External Power APC"; pixel_x = -27; pixel_y = 0},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plasteel{tag = "icon-darkbluecorners (WEST)"; icon_state = "darkbluecorners"; dir = 8},/area/aisat) "csR" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plasteel{tag = "icon-darkbluecorners"; icon_state = "darkbluecorners"; temperature = 273.15},/area/aisat) @@ -6385,9 +6389,7 @@ "csV" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/space,/area/space) "csW" = (/obj/structure/window/reinforced,/obj/structure/lattice,/turf/space,/area/space) "csX" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{tag = "icon-manifold-r-f (EAST)"; dir = 4},/turf/simulated/floor/plasteel{tag = "icon-darkbluecorners"; icon_state = "darkbluecorners"; temperature = 273.15},/area/aisat) -"csY" = (/obj/structure/lattice/catwalk,/turf/space,/area/aisat) "csZ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/aisat) -"cta" = (/obj/structure/grille,/obj/structure/lattice,/turf/space,/area/aisat) "ctb" = (/obj/structure/lattice,/turf/space,/area/aisat) "ctc" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/space,/area/space) "ctd" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 5},/turf/simulated/floor/plating,/area/aisat) @@ -6395,10 +6397,6 @@ "ctf" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{tag = "icon-darkblue"; icon_state = "darkblue"; temperature = 273.15},/area/aisat) "ctg" = (/obj/machinery/computer/security/telescreen{dir = 1; name = "MiniSat Monitor"; network = list("MiniSat"); pixel_x = 0; pixel_y = -30},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plasteel{tag = "icon-darkblue"; icon_state = "darkblue"; temperature = 273.15},/area/aisat) "cth" = (/obj/machinery/turretid{control_area = "\improper AI Satellite Antechamber"; enabled = 1; icon_state = "control_standby"; name = "Antechamber Turret Control"; pixel_x = 0; pixel_y = -24; req_access = list(65)},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plasteel{tag = "icon-darkblue"; icon_state = "darkblue"; temperature = 273.15},/area/aisat) -"cti" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/wall,/area/space) -"ctj" = (/obj/structure/window/reinforced{dir = 4},/turf/simulated/wall,/area/space) -"ctk" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/lattice,/obj/structure/grille,/turf/space,/area/aisat) -"ctl" = (/obj/structure/lattice,/obj/structure/window/reinforced,/obj/structure/grille,/turf/space,/area/aisat) "ctm" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 9},/turf/simulated/floor/plating,/area/aisat) "ctn" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/machinery/light/small{dir = 1},/obj/item/device/radio/intercom{broadcasting = 0; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/aisat_interior) "cto" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 6},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 8},/area/turret_protected/aisat_interior) @@ -6410,10 +6408,6 @@ "ctu" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/lattice,/turf/space,/area/space) "ctv" = (/obj/docking_port/stationary{dheight = 9; dir = 2; dwidth = 5; height = 22; id = "syndicate_s"; name = "south of station"; turf_type = /turf/space; width = 18},/turf/space,/area/space) "ctw" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 10},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 8},/area/turret_protected/aisat_interior) -"ctx" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/lattice,/obj/structure/grille,/turf/space,/area/aisat) -"cty" = (/obj/structure/lattice,/obj/structure/grille,/obj/structure/window/reinforced,/turf/space,/area/aisat) -"ctz" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plating,/area/space) -"ctA" = (/obj/structure/window/reinforced,/obj/machinery/door/window{base_state = "right"; dir = 1; icon_state = "right"; name = "MiniSat Walkway Access"; req_access_txt = "13;65"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plating,/area/space) "ctB" = (/obj/structure/grille,/obj/structure/window/reinforced/fulltile,/turf/simulated/floor/plating,/area/ai_monitored/storage/secure) "ctC" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/machinery/chem_heater,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry) "ctD" = (/obj/effect/landmark{name = "blobstart"},/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/turf/simulated/floor/engine,/area/toxins/explab) @@ -6424,8 +6418,6 @@ "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) "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/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plating,/area/space) -"ctM" = (/obj/structure/window/reinforced,/obj/machinery/door/window{dir = 1; name = "MiniSat Walkway Access"; req_access_txt = "13;65"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plating,/area/space) "ctN" = (/obj/machinery/alarm{dir = 4; pixel_x = -23; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 8},/area/turret_protected/aisat_interior) "ctO" = (/turf/simulated/floor/plasteel{tag = "icon-darkbluecorners (WEST)"; icon_state = "darkbluecorners"; dir = 8},/area/turret_protected/aisat_interior) "ctP" = (/turf/simulated/floor/plasteel{tag = "icon-darkbluecorners"; icon_state = "darkbluecorners"; temperature = 273.15},/area/turret_protected/aisat_interior) @@ -6468,7 +6460,7 @@ "cuA" = (/obj/structure/sign/directions/medical{dir = 4; icon_state = "direction_med"; pixel_x = 32; pixel_y = -24; tag = "icon-direction_med (EAST)"},/obj/structure/sign/directions/science{dir = 4; icon_state = "direction_sci"; pixel_x = 32; pixel_y = -32; tag = "icon-direction_sci (EAST)"},/obj/structure/sign/directions/engineering{pixel_x = 32; pixel_y = -40},/turf/simulated/floor/plasteel,/area/hallway/primary/central) "cuB" = (/obj/structure/disposalpipe/junction{icon_state = "pipe-j2"; dir = 2},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/structure/sign/directions/engineering{pixel_x = -32; pixel_y = -40},/obj/structure/sign/directions/medical{dir = 4; icon_state = "direction_med"; pixel_x = -32; pixel_y = -24; tag = "icon-direction_med (EAST)"},/obj/structure/sign/directions/evac{dir = 4; icon_state = "direction_evac"; pixel_x = -32; pixel_y = -32; tag = "icon-direction_evac (EAST)"},/turf/simulated/floor/plasteel,/area/hallway/primary/central) "cuD" = (/obj/machinery/light_switch{pixel_y = 28},/obj/machinery/camera{c_tag = "Custodial Closet"},/obj/structure/stool/bed/chair/janicart,/turf/simulated/floor/plasteel,/area/janitor) - + (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -6556,7 +6548,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfacfafPafPafPafPafPaaaafdaaaafPafPafPafPafPaafabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaafaaaaaaaaiaieagWaigafRaihaiiaiiaijahcafRaikailafUaimainaioaipaipaiqairafUafUaisaitaduaduaduabmabmabmabmabmabmabmabmaiuaivaiwaidaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaadwadxadxadxadxadyadzadAadBadBadBadBadCaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaaaaaaaafaaaaaaaaaafdaaaaaaaaaaafaaaaaaaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaixaixaiyaixaizaiAafRafRafRafRafRafRaiBaiCafRaiDaiEaiFaiFaiFaiFaiFaiFaiFaiFaiGaiHaiIaiJaiFailaiAaiKaiLaiMaiNaiOaiPaiQaiRaiuaivaiwaidaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaafaemaemaemaemaemaaaadzaaaaemaemaemaemaemaiSabqaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaafaenaenaenaenaenaaaafdaaaaenaenaenaenaenaafabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaixaiTaiUaiVaiWaiXaiYaiZajaajbajcajdajeajfajgajhajiajjajkajjajjajjajjajjajjajlajjajiajmajkajnajoajpajqajrajsajtajuajvajwaiuaivaiwacAaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaaaaafaaaaafaaaaaaadzaaaaaaaafaaaaafaaaaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaafaafbafbafbafbafcafdafeaffaffaffaffafgaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajxaeZaeZaeZaelaaaaafaizajyajzajAajBajCajDajEajFajGajHajIajJajKajLajIajJajMajLajIajJajNajOajOajOajPahCajQajRajSajTajUajVajWajVajVajVajXajYaiPaiuaivaiwaidaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfabfaafaafaafaafaafadzaafaafaafaafaafabfabfabfaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaafaafbafbafbafbafcafdafeaffaffaffaffafgaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajxaeZaeZaeZaelaaaaafaizajyajzajAajBajCajDajEajFajGajHajIajJajMajLajIajJajKajLajIajJajQajOajOajOajPahCajNajRajSajTajUajVajWajVajVajVajXajYaiPaiuaivaiwaidaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfabfaafaafaafaafaafadzaafaafaafaafaafabfabfabfaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaiSafPafPafPafPafPaaaafdaaaafPafPafPafPafPaafabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajZakaakbakcajZaiyaiyakdakeakfakgakhaiAafRakiafRafRakjakkaklakmaknakoaklakmaknakpakqakmakraksakmaktakuakmakvakwakxaiAakyakzaiPakAaiPakBakCaiPaiuaivaiwaidaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaaaaaaafaaaaaaakDaaaaaaaafaaaaaaaafaaaaafaafaafaaaaaaaaaaaaaaaaaaaafaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaaaaafaaaaafaaaaaaakEaaaaaaaafaaaaafaaaaaaabfaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaakFakGakHakIakJakKakLakKakeakMakNakOaiAakPakQakPafRakRakSakTafRakUakSakTafRakUakSakTafRakVakWakXakYailafRakZalaalbaiAalcaldalealfalealgalhaliaiuaivaiwaidaafaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaafaafaaaaaaaaaaafaaaaaaaljaaaaaaaafaaaaaaaafaaaaaaaaaaafaafaaaaaaaaaaaaaaaallalmallaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfabfaafaafaafaafalnaloalnaafaafaafaafabfabfabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajZalpalqalrajZaiyaiyaiyalsaltalualvaiAakPakQakPafRalwakSalxafRalyakSalzafRalAakSalBafRalCalDalEakYalFafRalGakSalHaiAalIalJalIalKalIalIalLalIaiuaivaiwacAacAaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaaaafaaaalMalNalMaaaaafaaaaaaaafaaaaaaaaaaaaaafaafaaaaaaaaaaaaallalOallaafaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -6574,19 +6566,19 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaafaqparpasuauEaqparpauFauEaqpamHauGamHamHamHamHamHasyatJanSauHauIanSanSamHasyatJauJaafauJamHapwatRamHauKauLamHasIapAaszauMasAauNauOauOauOauOauOauPauOauOauOauNauQauNauNauRauNauSauRauTauUauVauWauWauWauWauWauWauWauXauYauWauWauWauWauZavaavbavbavcavdapTarQarSarSavfarUavgavhatfavjaxZavlavmavnavoavpavqavraunauoauoaupasfaveatoaqcaqcaqcaqcaqcatoavtausatoaaaaaaallavuamlamlavvallavwanLavxavyanKallatqanKallavzamlallavAamlallavBavCavDavEatsatsavFavGavHavIavJavKavLaroabtabtaaIaaIabtabtabtabtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavMavNavNavNavOavNavNavNavPavQavRavPavPavPavSamHavTatJaDravUavVanSavWamHasyavXasAasAasAasAasAasAasCanSavVavYanSanSavZawaawbawcawdawdawdaweawdawfawdawdawgawhawiawjawjawjawjawjawjawkawlawmawnawnawnawnawnawnawnawoawnawpawpawpawpawpawqawrawsawtawuapTapTapTapTapTawvawwawxawyawzawAawBaviawDawEawFawGawHawIawJawJavsawLawMawNaqcaqcaqcaqcaqcawOawPawQatoaaaaaaallamlamlamlamlamlamlavDatsatsatsatsatsatsatsawRamlamlamlamlasnamlamlarjawSawTawUawVawWawXatwatwatwawYaroaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavMawZaxaawZaxbaxaaxaaxcawZaxaaxdaxeaxfaxfaxgamHavTatJaxhanSanSaxiaxjamHaxkarvarvarvarvarvarvaxlatJaxmanSamHasvasvaxnapNaqCaxoaxpaxqaxqaxraxqaxsaxqaxqaxtaxoaxuaxvaxvaxvaxvaxvaxvaxvavZaxwaxxaxyaxzaxAaxBaxCaxDaxEaxFaxGaxHaxIaxJaxKaxLamwaxMacAaeUapTaqOaqPaxNaqRaxOaxPaxQaxQaxQaxRaxSaxTaxUaxVaulaxWaxXaxYaHFayaaybatiaycaydaqcaqcaqcaqcaqcaydapWapWapWallallallanKallallaoyallallarjallallayeallallaoyallarjavuallallaoyallamlavuarjawSayfaroaygavGayhayiayjavGaykaroaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarpavMaylavMaBGaxaaxaaMBavMaylavMayqayraxbaysamHavTavXaytasAasAasCayuayuallasnallayuayuayuayuayvaywauQauNauNauNauNayxapNarBaxoaaaaafaaaayyaaaayzaaaaafaaaaxoaxuaxvayAayBayCayDayEaxvavZayFayGayHayIayJayKayLayMayMayNayOayOayOayPaxKayQamwayRacAaeUapTarQarSarSaySarUayTayUayVayWayXayYayZayZazaayZapWazbazcazdazeazfazgapWaydaqcaqcaqcaqcaqcaydapWaqoamlawTazhallallallaqoamlallaqoarjallaziamlallazjamlallazkazlallazmamlallaoyaoyarjaznazoaroazpavGazqazrazqavGazsaroaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaafaafaafaafaztaqpazuatBavMaymaynawCaypavMatBazuavMaqpazvazwamHazxazyazzazAatGazBayuazCazDazEazFazGazHazCayuazIazJazKawdawdawdawdawdazLazMaxoaafazNazNazOazNazPazNazNaafaxoaxuaxvazQazRazSazTazQaxvazUazVazWazXazYazZaAaaAbaAcaAdaAeaAfayOayOayOaAgayQamwaAhacAaeUapTapTapTapTapTaAiaAjaAkayZayZayZayZayZaAlaAmaAnayZapWapWapWapWaAoaApapWaydaqcaqcaqcaqcaqcaydapWallamlaAqazhallaArallamlamlallamlarjallamlamlallamlamlallarjasjallamlamlallaAsamlarjawSaAtaroaroaroaroaroaroaroaroaroabtabtabtabtabtaafaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarpavMaylavMaBGaxaaxaaMBavMaylavMayqayraxbaysamHavTavXaytasAasAasCayuayuallasnallayuayuayuayuayvaywauQauNauNauNauNayxapNarBaxoaaaaafaaaayyaaaayzaaaaafaaaaxoaxuaxvayAayBayCayDayEaxvavZayFayGayHayIayJayKayLayMayMayNayOayOayOayPaxKayQamwayRacAaeUapTarQarSarSaySarUayTayUayVayWayXayYayZayZazaayZapWazbazcazdazeazfazgapWaydaqcaqcaqcaqcaqcaydallaqoamlawTazhallallallaqoamlallaqoarjallaziamlallazjamlallazkazlallazmamlallaoyaoyarjaznazoaroazpavGazqazrazqavGazsaroaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaafaafaafaafaztaqpazuatBavMaymaynawCaypavMatBazuavMaqpazvazwamHazxazyazzazAatGazBayuazCazDazEazFazGazHazCayuazIazJazKawdawdawdawdawdazLazMaxoaafazNazNazOazNazPazNazNaafaxoaxuaxvazQazRazSazTazQaxvazUazVazWazXazYazZaAaaAbaAcaAdaAeaAfayOayOayOaAgayQamwaAhacAaeUapTapTapTapTapTaAiaAjaAkayZayZayZayZayZaAlaAmaAnayZapWapWapWapWaAoaApapWaydaqcaqcaqcaqcaqcaydallallamlaAqazhallaArallamlamlallamlarjallamlamlallamlamlallarjasjallamlamlallaAsamlarjawSaAtaroaroaroaroaroaroaroaroaroabtabtabtabtabtaafaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavMaylavMavMavMavMavMavMaylavMaaaaqpaAuaysaAvaAvaAwaAxaAvaAvaAyayuazCazEaAzaAAazEazEazCayuaqCaABaACaADaADaADaADaADaADaADaAEaaaazNaAFaAGaAIaAHaAJazNaaaaxoaxuaxvazQaAKaALaAMazQaxvawaazLaxxaANaAOaAPaAQaARaAbaASaATayOayOaAUayOaAgayQamwayRacAaeUapTaqOaqPaAVaqRaxOaAWayZaAXaAmaAYaAYayZaAlaAZaAnayZaBaaBbaBcaBdaBeaApaafaBfaBgaBgaBgaBgaBgaBhaaaallamlaBiaBjallallallallallallaBkaBlallallallallallallaBmaBnaBoaBpaBpaBpaBqaBraBsaBtaBuaBvaBwaBxaByaBzaBAaBBaBCaBDaBDaBDaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaajxaekaBEaekaeZaeZaeZaeZaekaBEaBFaelaqpaBGaBHaBIaBJaBKaBLaBMaBNaBOayuazCazEazEaBPazEazEazCayuaBQaBRaBSaBTaBUaBVaBWaBXaBYaBZaAEaafazNaCaaCbaCdaCcaCeazNaafaxoaxuaxvaCfaCgaChaCiaCjaxvapNaCkaxxaClaCmaCnayOaCnaCoaCpaCqaCraAgaxKaCsaxKayQamwayRacAaeUapTarQarRarSaCtarUaCuayZaCvaAmaAmaAmazaaCwaCxaCyayZaCzaCAaCBaCCaCDaApaaaaafaaaaafaaaaafaaaaafaaaallavuaCEaBsaCFaCGallasiamlavuarjamlallaaaallawTaBsaBsaCHaCIaCJaCJaCJaCJaCJaCKaCLaCMaCNaCOaCOaCOaCPaCQaCRaCSaCTaCUaCVaCWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajxaekaekaCXaOualQaCZaDaaDbaDcaDdaDealQaDgaDfavMaBGaDhaAvaDiaDjaDkaDlaDmaDnayuaDoazEazEazEazEaDpaDqbRJaDsaDtaDuaBYaBYaBYaBYaBYaBYaBYaAEaaaazNaDvaDwaDwaDxaDzazNaaaaxoaxuaxvaDAaDBaDCaDDaDEaxvapNaDFaxxaxxaDGaATaDHaATaDIaxxaxxaDJaDKaxKaDLaxKayQamwayRacAaeUapTapTapTapTapTaDMaDNaDOaDPaDQaDRaDRaDRaDSayZaDTayZaDUaDVaDWaBdaBeaApallallallallallallallallallallallallallaDXallallallallawTaBtaDYaDZaEaaDZaEbaEcaEdaEdaEeaEfaEfaEfaEfaEfaEgaEhaEiaEiaEiaEiaEiaEiaBDaEjaEkaElaBDaBDaBDaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeZaEmaEmaEnalQaEoalQaEoalQaEoalQaEoalQaDgaEpavMaBGaEqaAvaEraEsaEtaEuaEvaEwayuaExazEaEyaEzaEzaEAaEBaECaEDaEEaEFawKaEGaEGaEGawKaEHaEIaAEaafazNaEJaDyaEKaELaEMazNaafaxoaENaEOaEPaEQaDCaERaESaETaEUaEVaxKaEWaEXaDJaDJaDJaEYaEZaxKaFaaFaaxKaDJaxKaFbaoeaFcacAaeUaeUaeUaeUaeUamXawvaFdaFeaFfaFgaFeayoaFeaFiaFeaFjayZaFkaFlaFmaBdaFnaFoaFpaFqaFraFsaFtaFuaFuaFuaFuaFvaFwaFuaFuaFxaFyaFzaFAaBpaFBaFCaFDaFEaFFaFEaFGaFHaEfaEfaFIaEfaFJaFKaFLaEfaEiaFMaEiaFNaFOaFPaFQaFRaFSaFTaFUaFVaFWaFXaFYaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFZaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeZalQalQaGaalQaEoalQaEoaGbaEoalQaEoalQaDgaEpavMaBGaGcaAvaAvaGdaGeaGfaGgaAvayuayuayuayuaGhazEaAzaGiayuaGjaGkaBYaBYaBYaFhaBYaBYaBYaGmaAEaaaazNazNaGnaGoaGnazNazNaaaaxoaxuaxvaGpaGqaGraGsaGtaxvapNaGuaxKaGvaEXaDJaDJaDJaEYaGwaxKaAgaAgaxKaCsaxKaGxaGyaGzacAamXacAacAacAacAacAaGAaGBayZaGlaAmayZaGDayZaGEayZaGFayZaGGaGHaFmaBdaGIaGJaGKaGLaGMaGMaGNaGMaGMaGOaGMaGPaGQauwauwauwauwaGRaGSaGTaGUaGVamlaGWaGWaGWaGWaGXaEfaGYaGZaHaaGCaHcaHdaEfaHeaHfaEiaHgaHhaHiaHjaFRaHkaEjaEkaCTaHlaHmaFYaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeZaHnaHnaHoalQaEoalQaEoalQaEoalQaEoalQaDgaEpavMaHpaHqaHraHsaHsaHtaHuaxaaHvaHwaHxaHyayuaHzazEazEaHAayuaHBaHCaBYaHDaHEaOwaHGaHHaHIaHJaAEaaaaafaaaaHKaHLaHKaaaaafaaaaxoaxuaxvaDCaHMaHNaHOaHPaxvapNasJaxKaHQaHRaDJaDJaDJaHSaHTaxKaaaaaaaHUaHVaHWaHXaHYbzZaIaaIbaHUaaaaaaaIcaIdaIeaIfayZaIgaAmaAmaAmaCxaAmaAmaAmayZaBdaIhaIiaBdaBdaApaIjaIkaIkaIlaImaInaIkaIoaIkaIpaIqaIpaIraIpaIsaGWaGWaItaGWaGWaGWaGWaIuaIvaGWaGXaEfaGZaIwaIxaIyaIzaIAaEfaIBaICaIDaIEaIFaIGaIHaIIaIJaBAaIKaFVaFWaILaFYaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeZalQalQaGaalQaEoalQaEoaGbaEoalQaEoalQaDgaEpavMaBGaGcaAvaAvaGdaGeaGfaGgaAvayuayuayuayuaGhazEaAzaGiayuaGjaGkaBYaBYaBYaFhaBYaBYaBYaGmaAEaaaazNazNaGnaGoaGnazNazNaaaaxoaxuaxvaGpaGqaGraGsaGtaxvapNaGuaxKaGvaEXaDJaDJaDJaEYaGwaxKaAgaAgaxKaCsaxKaGxaGyaGzacAamXacAacAacAacAacAaGAaGBayZaGlaAmayZaGDayZaGEayZaGFayZaGGaGHaFmaBdaGIaGJaGKaGLaGMaGMaGNaGMaGMaGOaSOaGPaGQauwauwauwauwaGRaGSaGTaGUaGVamlaGWaGWaGWaGWaGXaEfaGYaGZaHaaGCaHcaHdaEfaHeaHfaEiaHgaHhaHiaHjaFRaHkaEjaEkaCTaHlaHmaFYaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeZaHnaHnaHoalQaEoalQaEoalQaEoalQaEoalQaDgaEpavMaHpaHqaHraHsaHsaHtaHuaxaaHvaHwaHxaHyayuaHzazEazEaHAayuaHBaHCaBYaHDaHEaOwaHGaHHaHIaHJaAEaaaaafaaaaHKaHLaHKaaaaafaaaaxoaxuaxvaDCaHMaHNaHOaHPaxvapNasJaxKaHQaHRaDJaDJaDJaHSaHTaxKaaaaaaaHUaHVaHWaHXaHYbzZaIaaIbaHUaaaaaaaIcaIdaIeaIfayZaIgaAmaAmaAmaCxaAmaAmaAmayZaBdaIhaIiaBdaBdaApaIjaIkaIkaIlaImaInaIkaIoaIpaIpaIqaIpaIraIpaIsaGWaGWaItaGWaGWaGWaGWaIuaIvaGWaGXaEfaGZaIwaIxaIyaIzaIAaEfaIBaICaIDaIEaIFaIGaIHaIIaIJaBAaIKaFVaFWaILaFYaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanTaekaekaCXaCYalQalQalQalQalQalQaIMalQaDgaINavMaBGaxaaIOaIPaIPaIPaIPaIPaIPaIPaIQaxaayuaIRaISaIRayuayuaITaIUaIVaADaADaADaADaIVaIWaIXaAEaIYaIZaIZaJaaJbaJaaIZaIZaJcaxoaJdaxvaJeaxvaJfaJfaJgaxvaJhaJiaxKaxKaxKaAgaDHaAgaxKaxKaxKaHUaHUaHUaJjaHYaHYaHYaHYaHYaJkaHUaHUaHUaIcaJlaIeaJmayZayZayZayZayZayZayZayZayZayZaJnaJoaJpaJqaJraJsaJtaJuaIkaJvaImaJwaJxaJwaIpaJyaJzaIpaJAaIpaJBaJCaJDaJEaJFaJFaJFaJGaJHaJIaGWaGXaEfaJJaIwaJKaIyaIzaJLaEfaJMaJNaJOaJPaJQaJRaJSaJTaJUaJVaJWaCTaHlaHmaFYaaaaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanTaekaJXaekaeZaeZaeZaeZaekaBEaJYafOaqpaJZaxaaKaaHbaKbaKcaKbaKdarpaKeaKfaxaaKgaKhaKiaKiaKjaKiaKkaKlaKiaKiaKiaKiaKiaKiaKiaKmaKnaKoaKpaKqaKqaKraKsaKqaKqaKqaKtaKuaKvaKraKqaKqaKqaKwaGyaKxaHYaKyaKzaHZaIaaIaaIaaHXaHYaHYaKAaHYaKBaKCaKDaKEaKFaKGaKHaKIaHYaHYaKAaKJaKKaKLaKMaKNaKOaKPaKQaHYaKRaHYaBdaKSaKTaKUaJoaKVaKWaKXaKYaKZaLaaIkaLbaLcaLdaLeaLfaIpaLgaJzaLhaLiaIpaGWaLjaLkaLlaLmaLnaLoaLpaLqaLraGWaGXaEfaLsaLtaLuaLvaLwaLxaEfaLyaLzaEiaLAaLAaLAaLAaEiaLBaCRaJWaCTaBDaBDaBDaLCaLCaLCaLDaLDaLDaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanTaekaJXaekaeZaeZaeZaeZaekaBEaJYafOaqpaJZaxaaKaaHbaKbaKcaKbaKdarpaKeaKfaxaaKgaKhaKiaKiaKjaKiaKkaKlaKiaKiaKiaKiaKiaKiaKiaKmaKnaKoaKpaKqaKqaKraKsaKqaKqaKqaKtaKuaKvaKraKqaKqaKqaKwaGyaKxaHYaKyaKzaHZaIaaIaaIaaHXaHYaHYaKAaHYaKBaKCaKDaKEaKFaKGaKHaKIaHYaHYaKAaKJaKKaKLaKMaKNaKOaKPaKQaHYaKRaHYaBdaKSaKTaKUaJoaKVaKWaKXaKYaKZaLaaIkaLbaLcaLdaLeaLfaIpaLgaJzaLhaLiaIpaIpaLjaLkaLlaLmaLnaLoaLpaLqaLraGWaGXaEfaLsaLtaLuaLvaLwaLxaEfaLyaLzaEiaLAaLAaLAaLAaEiaLBaCRaJWaCTaBDaBDaBDaLCaLCaLCaLDaLDaLDaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavMaylavMavMavMavMavMavMaylavMaaaaqpaAuaLEaKaaLFaLGaLHaLHaLIarpaLJaKfaLKaLLaKhaLMaLNaLOaLPaLQaLRaKiaKiaKiaKiaKiaKiaKiaKmaKiaKhaKiaKiaKiaLSaLTaLUaLUaLUaLUaLVaLUaLWaLUaLUaLXaKhaGyaHYaHYaHYaHYaHYaHYaHYaHYaHYaHYaHYaKAaHYaLYaLZaMaaMbaMcaMdaMeaMfaHYaHYaKAaHYaHYaHYaHYaHYaHYaHYaHYaHYaMgaHYaBdaKUaKUaKUaMhaMiaMjaMkaMlaMmaMnaIkaMoaImaMpaIkaIkaIpaMqaJzaMraLiaMsaIpaGWaGWaGWaGWaGWaGWaMtaMuaMvaGWaGXaEfaMwaGZaMxaMyaGZaMzaEfaEiaEiaEiaEiaEiaEiaMAaEiaEjaEjaEkaCTaMCaMDaBDaMEaMFaMGaMHaMIaLDaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaafaafaafaafaztaqpavMatBavMaNTaNUaNVaNWavMatBavMavMaqpaBGaxaaKaaMJaMKaLHaLHaLIarpaMLaKfaxaaLLaKhaKiaMMaMNaMNaMNaMOaMPaMQaMNaMRaMNaMNaMNaMSaMNaMTaMNaMNaMNaMUaMVaMWaMXaMXaMYaMZaNaaNbaNcaKicrraKhaGyaHYaNeaHYaNfaNfaNfaNfaNfaNfaNfaNfaNgaNfaNfaNfaNfaNfaNfaNfaNfaNfaNfaNfaNhaNfaNfaNfaNfaNfaNfaNfaNfaHYaHYaHYaBdaNiaNiaNiaNiaNiaNjaNkaJsaKZaNlaIkaNmaNnaNoaIkaNpaIpaNqaNraNsaLiaNtaIpaGWaNuaNvaNwaNxaNwaNyaNzaNAaGWaGXaEfaNBaNBaNCaNDaNEaNEbqoaEfaNGaNHaNIaBDaNJaNKaNLaEjaEjaNMaNNaBDaNOaBDaNPaNQaNRaNRaNSaLDaLDaLDaLDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafarpavMaylavMaBGaxaaxaaMBavMaylavMaNXaNYaNZaxaaKaaOaaRhaKcaOaaKdarpaObaKfaxaaOcaOcaOcaOdaOcaOeaOeaOeaOeaOeaOfaOgaOeaOhaOeaOeaOeaOiaOjaOkaOjaOlaOmaOnaKiaKiaOoaOpaOqaOraKlaKiaNdaOsaOsaHYaHYaHZaHUaHUaHUaHUaHUaHUaHUaHUaOtbUPbUObUQbUObUObUObVMbUObWHbUObXtaOtaHUaHUaHUaHUaHUaHUaHUaHUaHXaHYaHYaIkaOAaOBaOCaOCaOCaOCaOCaJsaODaOCaIkaOEaOFaOGaIpaIpaIpaOHaOIaIpaIpaIpaIpaGWaNwaOJaOKaOKaOKaOLaOMaNwaGWaGXaEfaONaGZaNCaNDaGZaGZaOOaEfaOPaOQaORaBDaEjaOSaOTaOUaOUaOVaOWaOXaOYaBDaOZaPaaNRaPbaNRaPcaPdaPdaPcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafarpavMaylavMaBGaxaaxaaMBavMaylavMaNXaNYaNZaxaaKaaOaaRhaKcaOaaKdarpaObaKfaxaaOcaOcaOcaOdaOcaOeaOeaOeaOeaOeaOfaOgaOeaOhaOeaOeaOeaOiaOjaOkaOjaOlaOmaOnaKiaKiaOoaOpaOqaOraKlaKiaNdaOsaOsaHYaHYaHZaHUaHUaHUaHUaHUaHUaHUaHUaOtbUPbUObUQbUObUObUObVMbUObWHbUObXtaOtaHUaHUaHUaHUaHUaHUaHUaHUaHXaHYaHYaIkaOAaOBaOCaOCaOCaOCaOCaJsaODaOCaIkaOEaOFaOGaIpaIpaIpaOHaOIaIpaIpaIpaIpaIpaNwaOJaOKaOKaOKaOLaOMaNwaGWaGXaEfaONaGZaNCaNDaGZaGZaOOaEfaOPaOQaORaBDaEjaOSaOTaOUaOUaOVaOWaOXaOYaBDaOZaPaaNRaPbaNRaPcaPdaPdaPcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavMaPeaxaavNaNZaxaaxaaPfavNaxaaPeaNZaxaaxaaxaaPgaPhaPhaPhaPhaPhaPhaPhaPiaxaaOcaPjaOcaPkaOeaPlaPmaPnaPoaPpaPmaPqaPraPsaPtaPuaPvaOiaPwaPxaPyaOlaPzaOnaOnaPAaOnaOnaOsaPBaPCaPDaPEaOsaOsaPFaHYaHZaHUaaaaaaaaaaaaaaaaaaaaaaOtaPGaPHaPIaPJaPKaPLaPMaPNaPOaPPaPQaOtaaaaaaaaaaaaaaaaaaaaaaHUaHXaHYaPRaIkaPSaOCaOCaOCaOCaOCaUaaJsaODaPUaPVaJsaPWaPXaIpaPYaPZaQaaQbaQcaQdaQeaQfaIpaNwaQgaQhaQhaQhaQiaQjaNwaGWaQkaEfaQlaQlaNCaNDaQmaQmaQnaEfaEfaQoaEfaBDaQpaNKaNLaQqaQqaNMaNNaBDaBDaBDaLDaQraQsaQtaLDaLDaLDaLDaQuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaavMaQvaQwaQwaQwaQwaQwaQwaQwaQwaQvaQwaQxaxaaxaaLLaxaaQyaQzaxaaQAaQBaxaaQCaQDaOcaQEaOcaPkaOeaQFaPmaQGaPmaPmaPmaPqaQHaPmaPmaPmaPvaOiaQIaPxaPxaOlaPzaOnaQJaQKaQKaQLaOsaQMaQNaQOaQPaQQaQRaHYaHYaHZaHUaaaaaaaaaaaaaOtaOtaOtaOtaQSaQTaQUaQVaQWaQXaQYaQZaRaaRbaRcaOtaOtaOtaOtaaaaaaaaaaaaaHUaHXaHYaHYaRdaOCaReaRgaRgaRgaRjaRiaRHaRkaRlaRmaRnaRoaRpaRqaRraRraRsaRtaRuaRuaRvaRraRwaRxaRyaRzaRAaRBaRCaQjaNwaGWaGXaEfaGZaGZaNCaNDaGZaGZaGZaRDaREaGZbqpaBDaRGaUyaRIaQqaQqaSHaRKaRLaBDaRMaRNaPaaNRaROaNRaRPaPdaPdaRQaRRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaqpaqpavMavMavMavMavMavMavMavMaqpaqparpaLLaRSaRTaRTaRUaRTaRTaRTaRVaRTaRTaRTaOcaQEaRWaRXaOeaRYaPmaRZaTfaSbaScaSdaSaaPmaPmaPmaSeaOiaSfaSgaShaOlaPzaOnaSiaSjaSkaSlaOsaSmaSnaSoaSpaSqaQRaHYaHYaHZaHUaHUaIcaSraOtaOtaSsaStaSuaSvaSwaSxaSyaSzaSxaSAaSxaSxaSBaSCaSDaSEaSFaOtaOtaSraIcaHUaHUaHXaHYaHYaIkaSGaJsaOCaOCaOCaOCaXsaOCaSIaSJaSKaSLaSMaSNaSOaSPaSQaSRaSSaSTaSUaSVaSPaSWaSXaSYaSZaTaaTbaSZaTcaTdaGWaGXaEfaTeaTeaNCaNDaTlaGZaGZaTgaGZaThaTiaBDaTjaTkaTpaQqaQqaTmaTnaEjaBDaToaNRaPaaNRaROaNSaLDaLDaLDaLDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -6594,70 +6586,70 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaUFavMavMaBGaUGaUHaUIaUJaUKaULaUMaUNaTraTtaRTaUOaUPaUQaOcaOeaURaUSaUTaUUaUTaUVaUWaUVaUVaUVaUXaUYaOeaUZaVaaVbaVcaVdaVeaVfaVgaOcaVhaOsaViaVjaVkaVlaVlaQRaHYaHYaHYaHYaHYaVmaVnaVoaVpaVqaVraVsaVtaVuaVvaVwaVxaVyaVzaVAaVBaVCaVDaVsaVEaVFaVGaVHaVIaVJaVKaVLaVMaHYaHYaIkaVNaVOaVPaVQaOCaVRaVSaVQaODaPUaVTaVTaVUaVVaIpaUeaUeaUeaVWaUeaUeaUkaVXaIpaNwaUnaQhaQhaUpaQhaVYaNwaGWaVZaWaaWbaWcaWdaWeaWfaWfaWfaWfaWfaWfaWgaWhaWiaWiaWiaWiaWiaWjaWkaWlaWhaWmaWnaWoaWpaNRaWqaLDaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaWraWsatBaWsaxaaxaaRTaWtaWuaWvaWvaWvaWwaWxaWyaRTaWzaQEaUQaWAaWAaWAaWBaWCaWAaWDaWEaWFaWGaWHaWHaWIaWJaOeaWKaWLaWMaWNaWOaWPaWPaWQaWRaWRaWSaWSaWSaWSaWSaWTaOsaHYaHYaWUaWVaWWaWXaWYaWZaOtaXaaXbaXcaXdaXeaXfaXfaXgaXhaXiaXjaXkaXlaXmaXcaXnaXaaOtaWZaWYaXoaXpaWVaXqaHYaHYaRdaOCaXraXsaOCaOCaOCaXsaOCaODaOCaPUaPUaOCaOCaXtaXuaXvaUeaUeaUeaUeaXwaXxaIpaXyaXzaQhaXAaXBaXCaXzaXDaGWaXEaXFaXFaXGaXHaXIaXJaXKaXLaXJaXJaXJaXMaXNaXOaXPaXPaXPaXPaXPaXQaXRaXNaXSaXTaXUaXVaNRaXWaLDaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavMavMavMaBGaxaaXXaTraXYaWvaWvaWvaXZaYaaTraRTaYbaYcaUQaWAaYdaYeaYfaYgaWAaYhaYiaYjaOeaYkaYlaYmaRZaOeaYnaYoaYpaYpaYpaYpaYqaYpaYpaYraYsaYsaYsaYtaYsaYuaYvaKAaKAaYwaYxaYxaYxaYxaYxaYxaYyaYzaYAaYBaXgaYCaYDaYDaYEaYFaYDaYCaXiaYGaYHaYIaYJaYHaYHaYHaYHaYHaYHaYKaKAaKAaIkaYLaYMaYNaYOaOCaOCaOCaYPaYQaYRaOCaYSaYTaYUaIpaIpaIpaYVaYWaYWaYWaIpaIpaIpaYXaQhaQhaYYaYZaZaaZbaYYaGWaZcaXFaZdaEfaZeaUzaZgaZfaZiaZjaTgaUuaZkaBDaZlaEjaZmaQqaQqaZmaEjaZnaBDaZoaZpaZqaROaNRaNSaLDaLDaLDaLDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavMaZraNZaZsaRTaTtaZtaTtaTraZuaZvaZwaTtaRTaZxaZyaZzaWAaWAaWAaZAaZBaWAaZCaYiaZEaOeaYkaYlaYmaRZaOeaYnaYoaYpaZFaZGaZGaZGaZHaYpaZIaZJaZKaZLaYvaYvaYvaYvaHYaHYaZMaZNaZOaZPaZQaZRaZSaZTaZUaZVaZWaZXaYDaYDaZYaZZaZYaYDaYDbaababbacbadbaebafbagbahbaibajaYHaXqaHYaHYaIkaIkaIkaIkaIkbakaRdbakbalaIkaIkaIkaIkaIkaIkbanbaobaobaobaobaobaobapbaobanaYYbaqbaqaYYbaraXFaXFaXFbanaZcaXFaZdaEfaEfaEfbasbatbasaEfbasaEfaEfaBDaBDbaubaubaubaubaubauaBDaBDbavaNRbawaROaNRaNRaRQaPdaPdaRQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavMaZraNZaZsaRTaTtaZtaTtaTraZuaZvaZwaTtaRTaZxaZyaZzaWAaWAaWAaZAaZBaWAaZCaYiaZEaOeaYkaYlaYmaRZaOeaYnaYoaYpaZFaZGaZGaZGaZHaYpaZIaZJaZKaZLaYvaYvaYvaYvaHYaHYaZMaZNaZOaZPaZQaZRaZSaZTaZUaZVaZWaZXaYDaYDaZYaZZaZYaYDaYDbaababbacbadbaebafbagbahbaibajaYHaXqaHYaHYaIkaIkaIkaIkaIkbakaRdbakbalaIkaIkaIkaIkaIkaIkaIkbaobaobaobaobaobaobapbaoaGWaYYbaqbaqaYYbaraXFaXFaXFbanaZcaXFaZdaEfaEfaEfbasbatbasaEfbasaEfaEfaBDaBDbaubaubaubaubaubauaBDaBDbavaNRbawaROaNRaNRaRQaPdaPdaRQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaqpaqpavMavMavMavMavMavMavMavMaqpaqparpaQyaxaaRTaRTaRUaRTaRTaRTaRVaRTaRTaRTbaxbaybazaWAaYdbaBaZAbaCaWAbaDbaEbaDaOeaYkaYlaYmaRZaOeaYnaYoaYpaZGbaFbaFaZGbaFaYpaZIbaGbaHbaHbaIbaJbaKaYvbaLaHYaWUbXubaNbaObaPbaQbaQbaRbaSbaTaZWbaUaYDaYDaZYbaVaZYaYDaYDbaWbabbaXbaYbaZbbabbbbbcbajbbdaYHaXqbbecrtaGybbfaXFaXFaXFaXFaXFaXFaXFaXFbbgaXFaXFaXFaXFbbhaXFaXFaXFaXFaXFaXFaXFaXFbbfaXFaXFaXFaXFbaraXFaXFaXFbbibbjaXFaXFbbkaXFaXFaXFbblaXFaXFaXFaXFaXFbbhbbmaXFaXFaXFaXFaXFaXFbbfbbnaRNaNRbbobbpbbqbbraLDaLDaLDaQuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavMavQavPavPavPavPavPavPavPavPavQavPbbsbbtaxabbuaRWbbvaWPaWPaWPbbwbbxbbyaOcbbzbbAbbBaWAaWAaWAbbCbbDaWAaOeaOeaOeaOeaYkaYlbbEbbFaOeaYnaYoaYpaZGbbGaZGbaFbbHaYpaZIbbIbaHbaHbaHbbJbbKaYvbbLaHYaWUbXvbbMbaObbNbbObbPbbQbbRbbSaZWbbTaZYaYDbbUbbVbbUaYDaZYbbWbabbbXbbYbbZbcabcbbbcbajbajaYHbccaHYaHYaGybbfaXFaXFaXFaXFaXFaXFaXFaXFbcdaXFaXFaXFaXFaXFaXFbcebcfbcfbcfbcgaXFaXFbbfaXFaXFaXFaXFbaraXFaXFbchaWbbciaWbaWbaWbaWbaWbaWbbcjaWbaWbaWbaWbaWbaWbaWbaWbaWbaWbaWbaWbbckbclbcmbcnbcnbcoaROaNRaNRbcpaPdaPdbcpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafavMawZaxaawZaxbaxaaxaaxcawZaxaawZaxbaxabcqaHqbcrbcsbctbcrbcrbcrbcubcvaOcaOcaOcbcwaUQaWAaYdbcxbcybczaWAbcAbcBbcAaOeaOeaOebcCbcDaOcaYnaYoaYpbcEaZGbaFbcFbcGaYpaZIaYvbcHbaHbaHbcIbcJbcKbcLaHYaWUbXvbcMbaObbNbcNbcObcPbaSbaOaZWbcQbcRaYDbcSbcTbcUaYDbcVbcWbabbcXbcYbcZbdabdabdbbajbdcaYHbddbdecuAaGybbfaXFaXFbdfaXFbdgbdhbdhbdhbdibdhbdhbdhbdjaXFaXFaXFaXFaXFaXFbdkbdlbdmbbfaXFaXFaXFaXFbarbdnbdobdpbdqbdraXFaXFaXFaXFaXFbdsbdtaXFaXFaXFaXFaXFaXFaXFaXFaXFaXFaXFaXFaXFbbfbdubdvbdwbdxaROaNRaNSaLDaLDaLDaLDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarpavMbdyavMaBGaxaaxaaMBavMbdAavMayqbdBbdCbdCbdDbdEbdFbdGbdHbdIbdJbdKbdLbdMbdMbdNbdOaWAaWAaWAbdPbdQaWAaOcaOcaOcaOcbdRaVbbdSbdTaVbbdUaYoaYpbdVaZGaZGbdWbdXaYpbdYaYvbdZbaHbaHbeabebbecbedaHYaWUaYxbaObeebaPbaPbefbaRbaSbegbehaXfbeibejbekbekbekbelbemaXkbenbeobepbeqberbajbesbajbetaYHaXqaHYaHYbeubeubeubeubeubeubeubevbewbewbexbeybeybevbezbezbezbezbezbeAbeAbeBbeCbeAbeAbeAbeAbeDaXFbeEbeFbeGbeHbeIaXFaXFaXFbeJbeJbeKbeKbeKbeKbeKbeLbeMbeMbeMbeNbeMbeObePbeMbeMbeQbeRbeRbeRbeRbeSbeTbeUbeVaLDaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaztaqpazuatBavMaymaynbeWbeXavMatBazuavMaqpaztarpbdDbeYbeZbeZbeZbfabdJbfbbfcbfdbfdbfebffaWAaYdbfgbdPbfhaWAbfibfiaQEaQEbfjbfkbflbfmbflbflbfnaYpbfobfpaZGaZGbdXbfqbfraYvbfsbaHbaHbeabftbfubedaHYbfvaYxbfwaYAbfxbfybfzbfAbaSbfBaYxaafbfCbfDbfDbfDbfEbfFbfGaafaYHbfHbfIbfJbfKbajbfLbajbfMaYHaXqaHYbfNbeubfObotbfQbfRbfSbeubqnbfVbfVbfWbfXbfXbfXbfYbfZbgabgbbezbgcbgdbgebgdbgdbgfbggbeAbeGbghbeGbeGbeGbgibeIbeIbgjbeIbgkbgkbeKbglbgmbgnbeKbgobgpbgobeKbgqbgrbgqbeRbgsbgtbgsbeRbgubgvbeRbgwbgxaLDaLDaLDaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafavMawZaxaawZaxbaxaaxaaxcawZaxaawZaxbaxabcqaHqbcrbcsbctbcrbcrbcrbcubcvaOcaOcaOcbcwaUQaWAaYdbcxbcybczaWAbcAbcBbcAaOeaOeaOebcCbcDaOcaYnaYoaYpbcEaZGbaFbcFbcGaYpaZIaYvbcHbaHbaHbcIbcJbcKbcLaHYaWUbXvbcMbaObbNbcNbcObcPbaSbaOaZWbcQbcRaYDbcSbcTbcUaYDbcVbaAbabbcXbcYbcZbdabdabdbbajbdcaYHbddbdecuAaGybbfaXFaXFbdfaXFbdgbdhbdhbdhbdibdhbdhbdhbdjaXFaXFaXFaXFaXFaXFbdkbdlbdmbbfaXFaXFaXFaXFbarbdnbdobdpbdqbdraXFaXFaXFaXFaXFbdsbdtaXFaXFaXFaXFaXFaXFaXFaXFaXFaXFaXFaXFaXFbbfbdubdvbdwbdxaROaNRaNSaLDaLDaLDaLDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarpavMbdyavMaBGaxaaxaaMBavMbdAavMayqbdBbdCbdCbdDbdEbdFbdGbdHbdIbdJbdKbdLbdMbdMbdNbdOaWAaWAaWAbdPbdQaWAaOcaOcaOcaOcbdRaVbbdSbdTaVbbdUaYoaYpbdVaZGaZGbdWbdXaYpbdYaYvbdZbaHbaHbeabebbecbedaHYaWUaYxbaObeebaPbaPbefbaRbaSbegbcWaXfbeibejbekbekbekbelbemaXkbdzbeobepbeqberbajbesbajbetaYHaXqaHYaHYbeubeubeubeubeubeubeubevbewbewbexbeybeybevbezbezbezbezbezbeAbeAbeBbeCbeAbeAbeAbeAbeDaXFbeEbeFbeGbeHbeIaXFaXFaXFbeJbeJbeKbeKbeKbeKbeKbeLbeMbeMbeMbeNbeMbeObePbeMbeMbeQbeRbeRbeRbeRbeSbeTbeUbeVaLDaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaztaqpazuatBavMaymaynbeWbeXavMatBazuavMaqpaztarpbdDbeYbeZbeZbeZbfabdJbfbbfcbfdbfdbfebffaWAaYdbfgbdPbfhaWAbfibfiaQEaQEbfjbfkbflbfmbflbflbfnaYpbfobfpaZGaZGbdXbfqbfraYvbfsbaHbaHbeabftbfubedaHYbfvaYxbfwaYAbfxbfybfzbfAbaSbfBaYxaafbfCbfDbfDbfDbfEbfFbfGaafaYHbfHbfIbfJbfKbajbfLbajbfMaYHaXqaHYbfNbeubfObotbfQbfRbfSbeubehbfVbfVbfWbfXbfXbfXbfYbfZbgabgbbezbgcbgdbgebgdbgdbgfbggbeAbeGbghbeGbeGbeGbgibeIbeIbgjbeIbgkbgkbeKbglbgmbgnbeKbgobgpbgobeKbgqbgrbgqbeRbgsbgtbgsbeRbgubgvbeRbgwbgxaLDaLDaLDaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafavMbdyavMavMavMavMavMavMbdAavMaafaafaafaaabdDbgybdDbgzbeZbgAbgBbcraVbbgCbgDbgEbgFbgGbgGbgGbgGbgGbgGbgHbgIbgJbfdbgKbgLaYpaYpaYpaYpaYpaYpbgMaYpaYpaYpbgNbgObgPbgQbgRbaHbaHbeabgSbecbedaHYbgTaYxbgUaYAaYAaYAaYAbfAbaSbgVaYxaafbfCbfDbgWbgXbgYbfDbgZaafaYHbhabbYbhbbhcbajbesbajbajaYHaXqaHYaHYbeubqqbhebhfbhgbhhbhibfXbhjbfXbhkbfXbfXbhlbfYbhmbhnbhobezbhpbgdbhqbgdbhpbhrbgdbeAbhsbhsbhubhvbeGbhwbeIbhxbhybhzbhAbhAbeKbhBbhCbhDbhEbhFbhGbhHbeKbhIbhJbhKbeRbhLbhMbhLbhNbhObhObeRbhPbgxaaaaafaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaacuzaaaaaaaafaafaaaaaaaaaaaaaaaaafaafaaabdDbhQbhRbhSbhTbhTbhUbhVaWPbhWaOcbhXbhYbhZbhZbhZbiabiabiabiabiabiabiabibbgNbicbidbiebifbigbihbiibijaYpbikbilbimbinbinbiobaHbaHbeabaHaYvbedaHYaWUbipbiqbirbisbitaYAbiubaSaYxaYxaafbfCbfDbgXbfDbgXbfDbgZaafaYHaYHbivbcZbiwbajbixbiybizaYHaXqaHYbiAbiBbiCbiDbqrbiFbrWbiHbfXbiIbiJbiKbiLbiLbiMbfYbiNbhnbiObezbhpbgdbhqbiPbhpbiQbiRbeAbiSbiTbiUbiVbeGbgibeIbiWbiXbiXbiYbiZbjabjbbjcbjcbjcbjdbjebjfbeKbjgbhJbjhbeRbjibjjbjkbjlbjmbjnbeRbhPbgxbjobjobjobjoaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaafaafaaabdDbjpbdDbjqbjrbjrbjsbdDbjtbjtaOcbjubjvbjubjubjubjvbjuaOcaOcaYpaYpaYpbjwbgNbjxbjxbjybjxbjxbjxbiibjxbjzbjAbjBbjCbjDbjEbjEbjEbjEbjFbjGbjHbjIbjJbjKbjLbjMbjNbjObjPaYAbfAbaSaYxaafaafbfCbfDbgYbjQbgWbjRbgZaafaafaYHbjSbjTaYHaYHaYHaYHbjUaYHbjVaHYaHYbeubjWbhebjXbhgbhhbjYbfXbjZbkabkbbkcbtmbkebezbkfbkgbkhbezbhpbgdbkibkjbhpbkkbgdbeAbeGbeGbeGbeGbeGbgibeIbklbkmbknbkobkpbkqbkrbksbktbktbkubkvbkwbeKbkxbhJbkybeRbkzbkAbkBbkCbkDbkEbeRbhPbkFbkGbkHbkIbkHaaaaaaaafaaaaafaaaaafaaaaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaafaafaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaabdDbkJbhRbkKbjrbkLbkMbdDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkNbkObkPbkQbkRbkSbkSbkTbkSbkSbkSbkUbkSbkVbkWbkXbkYbkZbecbecbecblaaYvblbaYvblcbldaKAbipbleblfblfblfblfblgblhbliaafaaabljblkbllbfDbfDblmbgZaaaaafblnbloblpblqblrblsblnbltblnbluaHYaHYbeublvbhectCblwblxbeublybjZbkablzblAbfXblBbezblCblDblEbezblFblGblHblIblJblKblLblMblNblOblNblNblNblPbeIblQbhyblRblSblTbkqblUblVblWblWblXblYblZbeKbmabgrbmbbeRbmcbmdbmebkCbhObmfbeRbhPbmgbmhbmibmibmibmibmibmibmjaafaaaaafaaaaaaaafaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaabdDbmkbhRbhRbhRbdDbdDbdDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkNbmlbjxbmmbmnbmobmnbmnbmnbmnbmnbmpbmnbmqbmrbmsbmtbmubmvbecbmwbaHbmxbmybmzbedbmAbmBbipbipblibmCbmDbmEbmFbmGbliaaaaaabfCbmHbmIbmJbmIbmKbgZaaaaaablnbmLbmMbmNblnbmOblnbltblnbluaHYaHYbeubmPbhebjXbmQbmRbeubmSbmTbmUbmVbmWbfXbmXbezbfYbmYbmZbezbeAbnabeAbeBbnbbncbncbncbncbncbncbncbncbgibeIbndbkmbknbnebnfbngbnhbnibnibniblXbkvbnjbnkbnlbnmbnnbnobnpbnqbnpbnrbhObnsbeRbntbnubnubnubnubnubnubnubnvbgxbjobjobjoaaaaaaaafaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabnwbkNbkNbnxbjxbjxbjxbnybnzbnzbnzbjxbjxbjxbjxbjzbnAbeabnBbnCbnDbnEbnFbnGbnHbaHbmzbnIbnJbnKbnLbnMbnNbnObnPbnQbnRbnSbliaafaaabfCbnTbnUbnUbnUbnVbgZaaaaafblnbnWbnXbnYblnbnZblnbltblnboaaHYaKJbobbocbodboebofbogbeubohbjZbhkbmVboibojbmSbmSbokbolbombonboobopbfXboqborbosbvtboubovbowboxboybncbgibeIbozboAboBboCboDbeKboEbnibniboFboGbkvboHboIboJboKboLbnoboMboNbhOboOboPboQbeRboRbrVbrVbrVbrVbrVbrVbrVbhPbgxboTboUbjobjoaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaboVboWboVboXboYbjxbjxbiibjxbjxbjxbjxbjxboZaYpaYpbpabpbbjEbpcbpdbecbpebaHbpfbaHbpgblubmAbphbpibpjbpkbplbpmbpnbpobppbliaaaaaabfCbpqbprbpsbprbptbgZaaaaaabpubpvbpwbpubpubpubpubpxbpubpyaKAaKAbeubeubpzbpAbpBbpCbeubpDbjZbpEbpFbpFbpFbpFbpFbpGbpHbpIbpJbpFbpKbpFbpLbpMbosbpNbpObpPbpQbpRbpSbncbpTbpUbpVbpWbpWbpXbpYbpZbqabqbbqbbqcbqdbkvbqebqfbqgbqhbqibnobnobqjbqkbqlbqmbnobeRbrVbrVbrXbvwbrZbrYbsabrVbqsbqtbqubqvbqwbjoaaaaafaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqxbqybqxbqzbjxbjxbjxbnybnzbnzbnzbjxbjxbqAbqBaYpbqCbaHbaHbqDbqEbqFbqGbaHbaHbaHbpgblubqHaHYbpibpjbqIbqJbqKbqLbqMbqNbliaafaafbqObqPbqQbqRbqSbqTbqUaafaafbqVbqWbqXbqYbqZbrabrbbrcbpubrdaHYaHYbmVbrebrfbrgbrhbribrjbrkbrlbrmbrnbrnbrnbrnbrnbrobrpbrqbrrbrsbrtbrubrvbrwbosbrxbrybrzbrAbrBboybncbgibeIbrCbrDbrEbrFbrFbeKbrGbrHbrIbnkbrJbkvbrKbnkbrLbrMbrNbrObrPbrQbrRbrSbrTbrUbsbbthbtgbtjbtibtibtibtlbtkbscbgxbsdbsebjobjoaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabnwbkNbkNbsfbjxbjxbjxbiibjxbjxbjxbjxbjxbqAbsgaYpbshbsibjEbsjbskbslbeabaHbaHaZhbmzbsnbqHaHYbpibpjblibsobspbsqbsrbssbliaaaaaaaafbfCbstbsubstbgZaafaaaaaabqVbsvbswbsxbsybszbszbsAbsBbsCaHYaHYbmVbsDbfXbsEbsFbsGbsHbsGbsIbsJbsKbsLbsKbsKbsKbsMbsNbfXbhkbsObsPbsPbsQbsRbosbosbsSbsTbsUbpRboybncbeHbeIbsVbsVbsVbsVbsVbeKbnkbnkbnkbnkbsWbsXbsYbnkbsZbtabtbbtcbtcbtcbtcbtdbtebtfbvZbuAbuzbuCbuBbuBbuDbwabrVbtnbgxbsdbsebjoaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtobqxbqybqxbmlbtpbjxbjxbtqbjxbtpbjxbjxbjxbqAbtraYpbtsbttbnGbtubtvbecbpbbjEbtwbtxbmzbsnbqHaWUbpibtyblibtzbtAbtBbtCbmGbliaaaaaaaafbtDbtEbnUbtFbtGaafaaaaaabqVbtHbtIbtJbtKbtLbtMbtNbpubtOaHYaHYbmSbmSbtPbtQbpGbtRbtSbtTbtUbtVbtWbtXbtWbtXbtWbtXbtWbtXbtYbtZbsPbuabubbucbudbuebufbugbuhbuibujbncbukbulbumbnmbunbhJbhJbuobhJbhJbupbuqburbusbutbtcbuubuvbuwbuxbuxbuxbuybuybuybuybuybwcbwbbwebwdbwebwfbwebrVbtnbgxbsdbuEbjobjoaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabuFbuGbuFbuHbuIbuHbuHbuHbuHbuHbuJbuKbjxbqAbuLaYpbuMbaHbuNbuObuPbuQbuRbuRbuRbuQbuQbuSbqHaJkbuTbpjblibuUbuVbuWbuXbuYbliaaaaaaaafbuZbvabqRbvbbvcaafaaaaaabqVbvdbvebvfbvgbtLbtMbtNbpubvhaHYaHYbvibvjbvkbvlbvmbvnbtXbvobvpbvqbvrbvsbDibvubvvbvubFzbtXbhkbjZbsPbvxbvybvzbvAbvBbvCbvDbvEbvEbvFbvGbvHbvIbvJbvKbvLbvMbvNbvMbvMbvObvMbvMbvPbvQbvRbvRbvSbvTbqibuxbvUbvVbvWbvXbvYbambuybxjbxibzCbyAbzDbxibAVbrVbtnbgxbwgbqvbwhbjoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabnwbkNbkNbkNaYpbkNbkNbkNbwibwibwibwibwjbwkbwkbwibwibwlbwlbwmbwnbuQbwobwpbwqbwrbuQbsnbqHaHZaIcaIcbliblibwsbliblibwtbliaHUaHUaHUbwubwvbsubwwbwxaHUaHUaHUbpubpubpubpubpubpubpubpubpubvhaHYbwybtXbtXbtXbwzbtXbtXbtXbwAbvpbwBbwCbwDbwEbwFbwGbwHbwIbwDbhkbjZbsPbwJbwKbwLbwMbwNbwObrAbrAbrAbwPbwQbwRbwSbwTbwTbwTbwTbwUbwTbwTbwTbwVbwVbwWbwXbwYbwYbwZbxabqibuxbxbbxcbxdbxebxfbxgbxhbrVbrVbFBbFBbFBbrVcfYbrVbtnbgxbsdbsebjobjoaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwibxkbxlbxmbxnbxobxpbwkbxqbxrbxsbxtbxubxvbxwbxxbxybuQbsnbqHaHYaHYaHYbxzaKQbxAaKAbxBbxCbxDaVLaVLaVLbxEbxFbxGbxHbxIaHYaHYaHYaHYaKQaHYaKAaHYaHYaHYbxzaHYbvhaHYbxJbtXbxKbxLbxMbxNbxObtXbxPbxQbxRbxSbwDbwEbwEbxTbxUbxVbwDbhkbxWbsPbrAbxXbxYbxZbwQbyabybbycbydbncbncbeHbyebwTbyfbygbyhbyibyjbykbwTbylbymbynbyobypbwYbyqbyrbysbytbyubyvbywbyxbyybyzbxhchfchfchfchfchfchfchfbrVbtnbgxbsdbsebjoaaaaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFZaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwkbyBbyCbyDbyEbyFbyGbyHbyIbyJbyKbyLbyMbyNbyObxxbyPbuQbsnbyQaHYaHYaHYaHYaHYaHYaKAaHYbqHaHYaHYaHYaHYaHYbyRbySbyTaHYaHYaHYaHYaHYaHYaHYaKAbyUaHYaHYaHYaHYbvhbyVbyWbtSbyXbyYbyZbyYbzabtXbzbbvpbvqbzcbtXbzdbzebzfbzgbzhbtXbhkbjZbsPbsPbsPbsPbsPbncbncbncbncbncbncbzibgibzjbwTbzkbzlbzmbznbzobzpbwTbzqbzrbzsbztbzubwYbyqbzvbzwbzxbzybzzbzzbzzbzAbzBbxhchfchfctEctDchfchfchfbrVbtnbgxbsdbsebjobjoaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwibzEbzFbzGbzHbzIbzJbwkbxrbxrbzKbzLbuRbzMbzNbzObzPbuQbzQbzRbzSbzSbzSbzTbzSbzSbzUbzSbzVaHYbzWbzXbzYbzYcuBbAabAbbAcbAdbAeaVLaVLbAfaVLbAgbAhaVLbAibAjbAkbAlaHYaHYbtXbAmbAnbAobtWbApbtXbtWbAqbArbtXbtXbtXbtXbtXbtXbtXbtXbhkbjZbfXbAsbAtbAubAvbAwbAxbAybAzbAAbAwbzibgibABbwTbACbADbAEbAFbAGbAHbwTbAIbAJbAKbALbAMbwYbyqbANbAObuybAPbAQbARbASbATbAUbxhchfchfchfbGLchfchfchfbrVbtnbqtbAWbqvbqwbjoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwibwibwkbwkbwkbwkbwibwibAXbAYbAZbBabuQbuQbuQbuQbuQbuQbBbbBcaIcaIcaIcaIcbBdbBdbBdbBdbBdbBdbBdbBdbBdbBdbBebBfbBgbBhbBhbBhbBhbBhbBibBhbBhbBjbBhbyebBkbyeaIdaJlbBlbtXbBmbBnbBobBpbBqbtXbBrbxQbBsbBtbBubBvbBwbBxbBybBzbBAbBBbBCbBDbBDbBEbBFbBGbBHbBIbBJbBKbBLbAwbzibgibBMbBMbBMbBMbBMbBMbBMbBMbBMbBNbBNbBNbBNbBNbBNbBObBPbBQbuybuybuybuybuybuybuybxhbrVbrVbrVbrVbrVbrVbrVbrVbtnbgxbBRbBSbjobjoaafaafaafaagaagaagaagaagaagaagaagaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBTaaaaaaaaaaafaaaaaabwlbBUbBVbBWbBXbBYbBZbCabCbbCcbCdbCebCfaaaaaaaafaaabBdbCgbChbCibCjbCkbClbCmbCnbCobCpbCqbCrbBhbCsbCtcuDbCubCwbCvbCvbCxbCybCzbCAbyebyebyebyebtXbCBbCCbCDbCCbCEbtXbCFbvpbCGbCHbCIbCJbCIbCIbCKbCLbCMbCNbCObCObCObCPbCQbvlbCRbCSbCTbCUbCVbAwbzibgibBMbCWbCWbCWbCXbCWbCWbCWbBMbCYbCYbCZbCYbCYbBNbDabDbbqibDcbDdbDebDfbDgbDhbJqbDjbDkbDlbDmbDnbDobDpbDqbDqbDrbDsbDdbDdbjoaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajxaekaeZaekaelaaaaafaaabwlbwlbDtbxrbDubDvbDwbDxbDybDybDzbDAbDBbDCaafbDDbDEbDFbDGbDHbDIbDJbDIbDKbDIbDIbDIbBdbDLbDMbDNbBhbDObDPbDQbDRbDSbCvbDTbBjbBhbDUbDVbDWbDXbDYbDZbEabEbbCCbEcbCCbxQbEdbEebEfbEgbtXbEhbEibCCbCCbEjbEkbmSbmSbmSbmSbmSbElbEmbpGbEnbEobEpbBKbEqbAwbzibgibBMbCWbCWbCWbCWbCWbCWbCWbBMbErbEsbEtbEubEvbBNbEwbExbEybEzbEAbEBbECbEDbEDbEDbEDbEEbEFbEGbDnbjobEHbEIbEJbEJbEKbELbEMaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbENbEObENaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajZbEPbEQbEPajZbERbERbERbwlbESbxrbETbEUbEVbEWbwlbBcbEXbBcbBcbEYbEZaaabFabFbbFcbFdbDIbDIbFebDIbFfbFgbFhbDIbBdbDLbFibFjbBhbFkbFlbFmbFnbFobCvbFpbBjbzibFqbFrbFsbFrbFtbFubtXbFvbCIbFwbCIbFxbtSbFybCJbFAbtXbFCbCCbCCbCCbCCbGNbmSbPIbFEbFFbFGbBEbFHbvlbFIbBKbBKbFJbFKbFLbFMbFNbBMbCWbCWbCWbCWbCWbCWbCWbBMbFObFPbFQbFRbFSbFTbFUbFVbtbbFWbFXbEDbFYbEDbEDbEDbEDbEDbEDbEDbDnbFZbGabGbbGcbGdbGebGfbEMaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbEObENbGgbENbEOaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeZalQaHnalQaeZbERbGhbGibwlbGjbxrbGkbxrbxrbEWbwlbGlbGmbGnbBcbEYbEZaafbFabGobGpbGqbGrbGsbGrbGrbGtbGubGrbGrbGvbGwbGxbGybBhbGzbBhbBhbBhbBhbGAbGBbGCbGDbGEbGFbGGbGHbGIbGIbtXbGJbGKcltbGMbGQbtXbGObGPbGSbtXbGRbGTbGVbGUbIkbGWbmSbGXbGYbpFbGZbHabHbbHcbCRbHdbBKbBKbHebAwbzibgibBMbBMbHfbCWbCWbHgbHfbBMbBMbHhbHibHjbHkbHlbBNbHmbHnbtbbHobHpbHqbHqbHrbHsbHtbHqbHubHvbHwbHxbHybHzbHAbHBbHCbHDbHEbEMaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbHFbEObHGbHHbHIbEObHFaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajZalQalQalQbHJbHKbxrbxrbHLbGjbxrbxrbxrbxrbEWbwlbHMbGnbHNbBcbEYbEZaaabFabHObHPbHQbDIbDIbHRbDIbHSbHTbHUbHVbBdbHWbHXbHYbHZbIabIbbIbbIbbIbbIbbIcbIbbIdbIebIfbIgbIhbIibIjbtSbtSbtSbtSbtSbtSbtSbtSbtSbtSbMNbMNbMNbMNbMNbMNbOnbOCbmSbmSbmSbmSbIlbImbhjbAwbAwbAwbAwbAwbAwbzibgibBMbInbIobIpbIqbIrbIsbInbItbHhbHibHjbIubIvbIwbIxbIybuwbIzbDdbIAbIAbIBbICbIDbIEbEDbEDbIFbDnbIGbIHbIIbDdbIJbIKbIKbDdaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbEObEObILbIMbIMbIMbINbEObEOaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeZaHnaHnaHnaeZbERbIObIPbIQbIRbxrbxrbISbITbIUbwlbBcbBcbBcbBcbEYbDCaafbIVbDEbIWbDGbIXbDIbIYbDIbDIbDIbDIbDIbBdbDLbIZbJabJbbJcbJcbJcbJcbJcbJcbJdbJebJfbJgbJhbJibJjbJkbJlbJmbJnbJmbJmbJmbJmbJmbJmbJmbJmbJmbJmbJmbJmbJmbJobJpbmSbGXcqlbBDbJrbBEbJsbJtbJubJvbJvbJwbJxbJgbJybJzbBMbJAbJBbJCbJDbJEbJFbJGbItbItbItbItbItbItbJHbJIbJJbJKbJLbDdbDnbDnbDnbDnbDnbDnbJMbEDbEDbDnbjobEHbgxbDdbJNbJObJPbJQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabJRbJSbJRbIMbJTbIMbJUbJVbENaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajZamIbJWbJXajZbERbERbERbwlbwlbERbERbERbwlbwlbwlaaaaaaaaabJYbJZbEZaaaaaaaafaaabBdbKabKbbKcbDIbKdbKebKfbKgbKhbKibKjbKkbKlbKmbKnbKobKpbKqbKmbKmbKmbKmbKmbKrbKsbKmbKmbKtbKmbKubKmbKmbKmbKmbKmbyebyebyebyebyebyebyebyebKvbKwbmSbKxbKybKzbKAbKBbKCbKDbKEbKFbKFbKGbKFbKFbKHbKIbBMbKJbKKbKLbKKbKMbKKbKNbKObKPbKQbKRbKSbKTbKUbyqbHnbqibKVaafbKWbKXbKYbKZbLabKZbLbbLcbLdbDnbLebtnbLfbDdbDdbDdbDdbDdaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbEObEObLgbIMbIMbIMbLhbEObEOaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanTaekbLiaekafOaaaaaaaaaaafaaIaafaaaaafaaIaafaaaaaaaaaaafbJYbEYbEZaafaafaafaafbBdbBdbBdbBdbBdbBdbBdbBdbBdbBdbLjbLkbLlbLmbKmbKnbKobKpbKqbLnbLnbLobLpbLqbLrbLsbLtbLubLvbLwbLxbLybLzbLAbLBbLCbLDbLDbLDbLDbLDbLDbLEbyebKvbLFbLGbLGbLGbLGbLGbLHbLIbLJbLGbLGbLGbLGbLGbLGbLFbLKbLLbLMbLNbLObLNbLPbLQbLRbLSbLSbLSbLSbLSbLSbLTbLUbLVbqibKVaafbKWbLWbLWbLXbLYbLZbMabMbbMcbDnbMdbtnbkFbjobMebMfbjoaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaafaafbHFbEObMgbMhbMibMjbHFaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaIaafaaaaafaaIaafaaaaaaaaaaaabJYbEYbEZaaaaaaaaaaafbMkbMlbMlbMmbMnbMobMobMpbMpbMkbDLbMqbKkbMrbKmbMsbMtbMtbMubMvbLnbMwbMxbMybMzbMAbMBbMCbMDbMEbMFbMGbMFbMHbMIbMJaafbMKbMKbMKbMKbMKbMLbyebKvbMMcqzbMObMPbMQbLGbMRbMSbMTbLGbMUbMVbMWbMVbMUbLFbMXbBMbKKbKKbKKbMYbKKbKKbMZbNabNbbNbbNcbNbbNbbNdbNebNfbNgbKVaafbKWbLWbNhbKZbNibKZbNjbNkbNlbDnbsebtnbkFbjobsebsebjoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbEObENbNmbENbMjaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafbBcbBcbJYbJYbJYbBcbBcaaaaaaaaaaaabJYbEYbEZaaaaaaaaaaafbMkbNnbMmbMmbMmbMmbMobYnbNpbNqbNrbKjbNsbNtbNubNvbNwbNxbNybNzbNAbNwbNwbNwbNybNBbNCbNDbNEbNFbLBbNGbNHbNIbNJbNKbLDbNLbNMbNNbNObMKbMLbNPbKvbLFbNQbMUbMUcrqbLGbNRbNSbNTbLGbMVbNUbMVbNVbNWbNXbNYbBMbNZbOabObbOcbOdbOebOfbOgbOhbOibOjbOkbOlbItbOmbZlbOobOpbOpbDnbDnbDnbDnbDnbDnbDdbDdbDdbDnbsebtnbOqbsebsebOrbjoaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbENbEObENaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBcbOsbGnbOtbGnbOubBcaaaaaaaaaaaabJYbJZbEZaaaaafbJYbJYbMkbMmbMmbOwbOvbMmbOxbMobMobOzbDLbMqbOAbOBbZmbODbOEbOFbOGbOHbOIbOFbOJbOFbOKbOLbOMbLubONbOObOPbOQbORbOSbOTbOUaafbOVbOWbNObOXbMKbMLbNPbKvbLFbOYbOZbMUbPabLGbPbbPcbPdbLGbMUbPebPfbMUbMUbLFbKvbBMbItbItbItbItbJHbPgbPhbPibJHbItbItbItbItbItbPjbPkbPlbPmbPnbPobPpbPqbPpbPrbOpbPsbPtbPubPvbPwbtnbkFbjobjobjobjoabtaafaafaafaagaagaagaagaagaagaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbBcbPxbGnbGnbGnbPybBcaaaaaaaaaaaabJYbEYbEZaaaaafbJYbPzbPAbPBbMmbMmcbdbPDbPDbPDbPEbPFcbebMqbOAbPHccdbPJbPKbMFbPLbPMbPNbPObPPbPQbPRbPSbPSbPTbPUbLBbPVbPWbPXbPYbPZbQabQbbNLbQcbNObNObMKbMLbNPbKvbLFbQdbMUbQebLHbLGbLGbQfbLGbLGbQgbQhbQibQgbQgbLFbKvbBMbQjbQkbQkbQlbQmbKKbQnbQobQpbQqbCWbCWbCWbItbQrbQsbQtbQubQvbPobQwbQxbQybQzbOmbPtbQAbPtbPvbBRbQBbQCbjoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaagaagaagaagaagaagaagaagaagaagaagaagaagaagaaaaaaaaaaaaaaaaaaaaabBcbPxbGnbGnbQDbQEbBcaaaaafaaaaaabJYbEYbDCbBcbBcbBcbQFbMkbQGbMmbMmcqmbQHbQIbQJbQKbMkcqnbMqbOAbPHcqobQLbQMbMFbMFbQNbLnbQObQPbQQbQRbMFbMFbLubQSbQTbQUbQVbQWbQXbQWbQYaafbMKbMKbMKbMKbMKbMLbyebKvbLFbQZbRabRabRbbRcbRdbRebRfbRgbMUbPebMUbMUcqpbLFbKvbBMbCWbCWbCWbRhbRibKKbRjbKKbRkbRlbCWbCWbCWbItbRmbRnbRobRpbRqbRrbRsbRtbRrbRubOpbRvbPtbRwbPvbjobRxbRybjoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaafaafbRzaafaafaafbBcbBcbBcbBcbBcbBcbBcbBcbBcbBcbRAbBcbBcbBcbJYbJYbJYbRBbRCbRDbREbRFbRGbRCbRHbPFbPFbPFbPFcqrbMkbMkbMkbMkbMkcqtbRKbOAbRLbKmbRMbRNbPNbRObPNbLnbMFbMFbMFbQRbRPbRQbRQbRRbRSbRTbNGbRUbRVbRWbNKbLDbNLbRXbRYbRYbMKbMLbyebKvbRZbSabSabSabSbbScbMUbSdbMUbMUbMUbPebMUbMUbMUbLFbKvbBMbCWbCWbCWbSebSfbQobSgbKKbShbSibQkbQkbSjbItbSkbSlbPlbSmbSnbPobQybSobRrbSpbOpbSqbSqbSqbPvbSrbSsbRybjoaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabStbSubSubSubSubSvbSwbSwbSxbSybSzbSAbSBbSCbSDbSEbBcbGnbGnbGnbGnbGnbGnbGnbSFbSGbSHbSIbSJbSKbSKbSKbSKbSLbSMbSMbSMbSNcqubSObDybDybSPbBccqnbMqbOAbSQbSRbSSbSTbRQbRQbSUbSVbRQbRQbSWbSXbSYbMFbSZbTabTbbTcbMFbTdbTebTfbOUaafbOVbTgbThbTibMKbMLbNPbTjbTkbTkbTkbTlbLFbTmbQZbTnbTobTpbTqbTrbTsbTsbTtbLFbKvbBMbItbItbItbItbTubTvbRjbTwbTubItbItbItbItbItbTxbTybTzbTAbTBbTCbTCbTCbTCbTDbOmbSqbSqbTEbPvbTFbSsbRybjobjobjoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaagaaaaafaaaaaabTGbTGbJYbGnbTHbTIbTJbTKbTLbBcbTMbJYbJYbJYbJYbJYbJYbJYbJYbDCbTNbTObTObTObTObTObTObTObTObTPbTPcqxbTPbTPbTQbTRbBccqnbMqbOAbSQbTSbTTbTUbTVbPSbTWbTXbPSbPSbTYbTZbUabUbbUcbUdbUebUfbMFbTdbUgbUhbQabQbbNLbUibRYbRYbMKbMLbNPbUjbyebyebyebNYbLFbUkbMUbMUbUlbUmbUnbUobUpbUobUnbLFbKvbBMbQjbQkbQkbUqbQmbKKbQnbQobUrbUsbCWbCWbCWbItbUtbUubUvbUwbRnbRpbUxbUybUzbUAbOpbSqbSqbSqbPvbTFbSsbRybsebsebjoaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaagaagaagaagaagbUBbUCbUDbGnbUEbTIbTIbUFbGnbBcbGnbJYaaaaaaaafaaaaaaaafaaabDCbTNbTObUGbUHbUIbUJbUKbULbUGbUMbUNcqCcqybTPbTPbTRbBccqDbMqbOAbURbUSbUTbUTbUUbKmbKmbKmbKmbKmbUVbUWbLnbLnbLnbUXbMFbTbbMFbTdbTebUYbOUaafbMKbMKbMKbMKbMKbMLbNPbUjbyebUZbzibNYbMMbVabVbbVcbVdbVebVfbVgbUpbVgbVhbLFbKvbBMbCWbVibCWbVjbRibKKbRjbKKbRkbVkbCWbVibCWbItbVlbVmbVnbVobVpbVqbVrbVsbVtbVubOmbVvbVwbVxbPvbSqbSsbVybjobsebjobjobjoaagaagaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbTGbTGbJYbVzbVAbVBbVCbVDbGnbVEbGnbJYaaaaaaaafaaaaaaaafaaabDCbTNbTObUGbVFbVGbVHbVIbVJbUGbVKbVLcqEbVNbVObTPbTRbBccqnbMqbOAbVPbVQbKmbVRbVSbKmbVTbVUbVVbKmbVWbQRbVXbLnbVYbUfbMFbUdbVZbWabRVbWbbNKbLDbNLbWcbWdbWebMKbMLbyebUjbyebABbzibNYbLFbWfbWgbWhbWibUmbWgbWjbUpbWjbNVbNXbKvbBMbCWbCWbCWbWkbWlbQobSgbKKbShbWmbQkbQkbSjbBMbPvbWnbWobWobPvbPvbWpbWqbWrbWsbWtbWubTCbWvbSqbSqbSsbRybjobWwbjobWxbjoaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafbJYbWybWzbWzbWAbTLbWBbBcbJYbJYaaaaaaaaaaaaaaaaaaaaabDCbTNbTObWCbWDbWEbVHbWFbWCbWCbVKbWGcqGcqFbWIbTPbTRbBccqnbMqbWJbWKbWKbWLbWMbWNbWObWPbWQbWRbKmbMFbQRbWSbWTbVYbWUbMFbUdbVZbTdbTebWVbOUaafbOVbWWbWXbWYbMKbMLbyebUjbyebGHbGHbNYbLFbLGbWZbXabLGbXbbLGbLGbLGbLGbLGbLFbKvbBMbItbItbItbItbTubXcbRjbXdbTubItbItbItbItbBMbRrbXebRrbRrbRrbPvbWpbWqbXfbXgbXhbXibUwbXjbPvbSqbSsbRybjobsebsebsebXkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafabtabtabtbBcbBcbBcbVEbBcbBcbBcbBcaafaaaaaabXlaaaaaaaaaaaaaaabEZbTNbTObWCbWCbXmbXnbXobWCbXpbXqbXrcqIcqHbXsbTPbTRbBccqJbXwbCrbWKbXxbXybXybXzbXAbXBbXCbXDbKmbXEbXFbVXbLnbVYbXGbMFbXHbVZbTdbXIbXJbQabQbbNLbXKbWdbWdbMKbMLbNPbUjbyebXLbzibNYbXMbSabSabXNbLGbXObXPbXQbLHbXRbXSbKwbKvbBMbQjbQkbQkbXTbQmbKKbQnbQobXUbXVbCWbCWbCWbBMbXWbRrbRrbRrbRrbPvbXXbXXbXYbXZbOpbOpbUwbOpbPvbOpbSsbRybjobYabYbbYcbXkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfabfabfabfabfabfabfabfabqabfabfabfabfabfaaaaaabBcbGnbGnbGnbGnbGnbGnbGnbGnbWBbJYaafaaaaaaaafaaIbYdaaaaaaaaabEZbTNbTObYebYfbYgbYhbYibYjbYkbYlbYmcqMcqKbYobTPbYpbYqbYrbYsbGybWKbYtbXybYubYvbYwbYxbYybYzbYAbNFbYBbLnbLnbLnbYCbMFbYDbYEbTdbTebMFbOUaafbMKbMKbMKbMKbMKbMLbNPbUjbyebYFbzibYGbYHbTkbYIbYJbLHbYKbYLbYMbLHbYNbKFbYObYPbBMbCWbCWbCWbYQbRibKKbRjbKKbRkbYRbCWbCWbCWbBMbYSbRrbYTbRrbRrbYUbYVbYWbYXbYYbOpbUwbUwbYZbPvbBRbZabZbbjobZcbZdbsebXkaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaafaaaaafaaaaafaaaacfaaaaafaaaaafaaaabfaafaafbBcbZebGnbBcbBcbBcbRAbBcbBcbBcbBcaaaaaaaaaaaIbZfbZgaaIaaIaafbEZbTNbTObZhbWCbUGbUGbUGbWCbZibZjbZkcqGcqNcqPbTPbBcbBcbZnbZobZpbWKbWKbZqbXybZrbZsbZtbZsbZubKmbMFbZvbZwbZxbZybONbZzbZAbZBbWabRVbZCbNKbLDbNLbZDbZEbZEbMKbMLbNPbUjbyebyebyebZFbZGbyebZHbZIbyebyebZJbyebyebZIbZKbZLbZMbBMbCWbCWbCWbZNbZObQobZPbKKbShbZQbQkbQkbSjbBMbRrbRrbZRbRrbRrbPvbXXbXXbZSbZTbOpbZUbZVbZWbPvboUbZabRybjobjobjobsebjoaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaabZXbZYbZZaaabZXbZYbZZaaabZXbZYbZZaaaabfaaaaaabBccaacabbBccacbGnbGncadbOucaebBcaaaaaaaaacafaaIaaIaafaaaaaabEZbTNbTObWCcagcahbUGcaibWCbWCbVKcajcqGcqKcakbTPcalcamcancaocapcaqcarcascatcascatcaucatcavbKmcawcaxcaybPSbPSbPUbRPcazbRUbPVbTecaAbOUaafbOVcaBcaCcaDbMKbMLbyebUjbzicaEcaFbZFcaGbyebZHcaHcaIcaJcaKcaLcaIcaMbZHbgxcaNbBMbBMbBMbBMbBMbBMcaOcaPcaObBMbBMbBMbBMbBMbBMbPvbPvbPvbPvbPvbPvcaQcaQcaRcaSbPvbPvbPvbPvbPvbjobRxbRybjocaTcaUbsebjoaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaafbZXcaVbZZaaabZXcaVbZZaaabZXcaVbZZaafaafaaaaaabBcbJYbJYbBcbBccaWcaXbOubGnbQDbBcaaaaaaaaaaaaaafaaaaaaaaaaaabDCbTNbTObUGcaYcaZbUGcbacbbbUGbVKcbccqEcqQcqVcqUcqXcqWbOAaZDcbgcbhcbicbjcbkcblcbmcbnbXycbobKmcbpbMFbZvbRPbRQcbqcbrcbscbtbLAcbucbvbQabQbbNLcbwbZEbZEbMKbMLbyecbxcbycbzcbAcbBcbCbyecbDcbEcbFcbGcbHcbGcbIcbEcbJbgxcbKbjoaaaaaaaaaaafaaaaaacbLaaaaafaaaaaaaaaaaabjocbMbMfbkGcbNcbNbPvcbOcbOcaRbQtcbPcbQbsebsebsebBRbRxbVybjocbRbsebsebjobjobjoaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaabZXcaVbZZaafbZXcaVbZZaafbZXcaVbZZaaaaafaafaafaafaafaafaafbBcbBcbBcbBcbRAbBcbBcaaaaaaaaaaaaaafaaaaaaaafaaabDCbTNbTObUGcbScbTcbUcbVcbWbUGcbXcbYcbZccaccbbTPccccqYcceccfccgcchcciccjcckcclccmccnccoccpccqccrbOQccscctbMFbMFbMFbMHbSYcctbTebUYbOUaafbMKbMKbMKbMKbMKbMLbyebYFccuccvccwccxccybyebyecczccAccBbKwccCccDbyebyebgxcbKbjoaaaaaaaaaaafaaaaaacbLaaaaafaaaaaaaaaaaabjobseccEbqvccFccGbPvccHccHccIbQtbPvbOpbjoccJccKbBRbRxccLccMccMccMccNccOccPccOccQaagaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbZXcaVbZZaaabZXcaVbZZaaabZXcaVbZZaafaafaaaaaaaaaaaaaaaaaabBcccRbBcbGnbGnbBcaafaaaaafaaaaaaaafaaaaaaaafaaabDCbTNbTObTObTObTObTObTObTObTObTPbTPbTPbTPbTPbTPbBcccSbBcccTccUccUccUccVccWccXccUccYccZcdabKmcdbcdcbPXcddcdecdfcdecddcdgcddcdhbRPcdiaafaafaafaafaafaafbMLcdjcdjcdjcdkcdlcdjcdjcdjcdmbyecdncdncdocdncdnbyebABbZGcbKbjobXkbXkbXkbjobXkbXkcdpbXkbjobXkbXkbXkbXkbjobjobRxcdqbjobjobPvbPvbPvcdrcdsbPvbBRbjobYcbseboTbRxbZbbjobjocdtbjobjobjobjoaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfabfaafaaabZXcaVbZZaaabZXcaVbZZaaabZXcaVbZZaaaaafaaaaaacducdvcdvcdvcdvbBcbBccdwbGnbBcbJYbJYbJYbJYbJYbJYbJYbJYbJYbBcbDCbTNbBccdxcdycdzcdzcdzcdzcdzcdzcdzcdzcdzcdAcdAcdzcdBcaWccTcdCcdDcdEcdFcdGcdHccUcdIcdJcdKbKmcdbcdLcdMcdNcdOcdPcdQcdRbMFcdScdTcdUbLuaafaafaaaaaaaaaaaacdVcdWcdXcdYcdZceacebceccdjcedceecefcegcehccBccBbzibzibZGbntceiceiceiceiceiceiceicejcekcekcekcekcekcekcelcekcemcekcekcenceocepceqcercesbjobjocetceoceuceocevbRybjocewbsebsebjoaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaafaaaaaaaaacexaaaaaaaaacexaaaaaaaaacexaaaaaaaafcducducduceycezceAceBceCbGnceDceEceFceEceEceEceEceEceEceEceEceEceEceGceHbRGceIceJceKceKceKceKceKceKceKceKceKceKceKceKceKceKccTccUceLceMceNceOcePceQceRceSceTceKbLuceUbLuceVbLuceUbLuceVbLuceWbLuceWbLuaafaafaaaaaaaaaaaacdjceXceYceZcfacfbcfccfdcdjcedcfeccBcffcfgcfhcfibDZcfjcfkcflcflcflcflcflcflcflcfmcfncflcflcflcflcflcflcfocfpcfqbmicfrcfscftcftcftcfucfvcfwcfxcfycfzcftcftcfAcfBbjocaUbsecfCbjoaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaboVboWboVboXboYbjxbjxbiibjxbjxbjxbjxbjxboZaYpaYpbpabpbbjEbpcbpdbecbpebaHbpfbaHbpgblubmAbphbpibpjbpkbplbpmbpnbpobppbliaaaaaabfCbpqbprbpsbprbptbgZaaaaaabpubpvbpwbpubpubpubpubpxbpubpyaKAaKAbeubeubpzbpAbpBbpCbeubpDbjZbpEbpFbpFbpFbpFbpFbpGbpHbpIbpJbpFbpKbpFbpLbpMbosbpNbpObpPbpQbpRbpSbncbpTbpUbpVbpWbpWbpXbpYbpZbqabqbbqbbqcbqdbkvbqebqfbqgbqhbqibnobnobqjbqkbqlbqmbnobeRbrVbrVbrXbenbrZbfUbsabrVbqsbqtbqubqvbqwbjoaaaaafaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqxbqybqxbqzbjxbjxbjxbnybnzbnzbnzbjxbjxbqAbqBaYpbqCbaHbaHbqDbqEbqFbqGbaHbaHbaHbpgblubqHaHYbpibpjbqIbqJbqKbqLbqMbqNbliaafaafbqObqPbqQbqRbqSbqTbqUaafaafbqVbqWbqXbqYbqZbrabrbbrcbpubrdaHYaHYbmVbrebrfbrgbrhbribrjbrkbrlbrmbrnbrnbrnbrnbrnbrobrpbrqbrrbrsbrtbrubrvbrwbosbrxbrybrzbrAbrBboybncbgibeIbrCbrDbrEbrFbrFbeKbrGbrHbrIbnkbrJbkvbrKbnkbrLbrMbrNbrObrPbrQbrRbrSbrTbrUbhtbthbtgbtjbtibtibtibtlbtkbqnbgxbsdbsebjobjoaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabnwbkNbkNbsfbjxbjxbjxbiibjxbjxbjxbjxbjxbqAbsgaYpbshbsibjEbsjbskbslbeabaHbaHaZhbmzbsnbqHaHYbpibpjblibsobspbsqbsrbssbliaaaaaaaafbfCbstbsubstbgZaafaaaaaabqVbsvbswbsxbsybszbszbsAbsBbsCaHYaHYbmVbsDbfXbsEbsFbsGbsHbsGbsIbsJbsKbsLbsKbsKbsKbsMbsNbfXbhkbsObsPbsPbsQbsRbosbosbsSbsTbsUbpRboybncbeHbeIbsVbsVbsVbsVbsVbeKbnkbnkbnkbnkbsWbsXbsYbnkbsZbtabtbbtcbtcbtcbtcbtdbtebtfbrYbuAbuzbuCbuBbuBbuDbwabrVbsbbgxbsdbsebjoaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtobqxbqybqxbmlbtpbjxbjxbtqbjxbtpbjxbjxbjxbqAbtraYpbtsbttbnGbtubtvbecbpbbjEbtwbtxbmzbsnbqHaWUbpibtyblibtzbtAbtBbtCbmGbliaaaaaaaafbtDbtEbnUbtFbtGaafaaaaaabqVbtHbtIbtJbtKbtLbtMbtNbpubtOaHYaHYbmSbmSbtPbtQbpGbtRbtSbtTbtUbtVbtWbtXbtWbtXbtWbtXbtWbtXbtYbtZbsPbuabubbucbudbuebufbugbuhbuibujbncbukbulbumbnmbunbhJbhJbuobhJbhJbupbuqburbusbutbtcbuubuvbuwbuxbuxbuxbuybuybuybuybuybwcbwbbwebwdbwebwfbwebrVbsbbgxbsdbuEbjobjoaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabuFbuGbuFbuHbuIbuHbuHbuHbuHbuHbuJbuKbjxbqAbuLaYpbuMbaHbuNbuObuPbuQbuRbuRbuRbuQbuQbuSbqHaJkbuTbpjblibuUbuVbuWbuXbuYbliaaaaaaaafbuZbvabqRbvbbvcaafaaaaaabqVbvdbvebvfbvgbtLbtMbtNbpubvhaHYaHYbvibvjbvkbvlbvmbvnbtXbvobvpbvqbvrbvsbDibvubvvbvubFzbtXbhkbjZbsPbvxbvybvzbvAbvBbvCbvDbvEbvEbvFbvGbvHbvIbvJbvKbvLbvMbvNbvMbvMbvObvMbvMbvPbvQbvRbvRbvSbvTbqibuxbvUbvVbvWbvXbvYbambuybxjbxibzCbyAbzDbxibAVbrVbsbbgxbwgbqvbwhbjoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabnwbkNbkNbkNaYpbkNbkNbkNbwibwibwibwibwjbwkbwkbwibwibwlbwlbwmbwnbuQbwobwpbwqbwrbuQbsnbqHaHZaIcaIcbliblibwsbliblibwtbliaHUaHUaHUbwubwvbsubwwbwxaHUaHUaHUbpubpubpubpubpubpubpubpubpubvhaHYbwybtXbtXbtXbwzbtXbtXbtXbwAbvpbwBbwCbwDbwEbwFbwGbwHbwIbwDbhkbjZbsPbwJbwKbwLbwMbwNbwObrAbrAbrAbwPbwQbwRbwSbwTbwTbwTbwTbwUbwTbwTbwTbwVbwVbwWbwXbwYbwYbwZbxabqibuxbxbbxcbxdbxebxfbxgbxhbrVbrVbFBbFBbFBbrVcfYbrVbsbbgxbsdbsebjobjoaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwibxkbxlbxmbxnbxobxpbwkbxqbxrbxsbxtbxubxvbxwbxxbxybuQbsnbqHaHYaHYaHYbxzaKQbxAaKAbxBbxCbxDaVLaVLaVLbxEbxFbxGbxHbxIaHYaHYaHYaHYaKQaHYaKAaHYaHYaHYbxzaHYbvhaHYbxJbtXbxKbxLbxMbxNbxObtXbxPbxQbxRbxSbwDbwEbwEbxTbxUbxVbwDbhkbxWbsPbrAbxXbxYbxZbwQbyabybbycbydbncbncbeHbyebwTbyfbygbyhbyibyjbykbwTbylbymbynbyobypbwYbyqbyrbysbytbyubyvbywbyxbyybyzbxhchfchfchfchfchfchfchfbrVbsbbgxbsdbsebjoaaaaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFZaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwkbyBbyCbyDbyEbyFbyGbyHbyIbyJbyKbyLbyMbyNbyObxxbyPbuQbsnbyQaHYaHYaHYaHYaHYaHYaKAaHYbqHaHYaHYaHYaHYaHYbyRbySbyTaHYaHYaHYaHYaHYaHYaHYaKAbyUaHYaHYaHYaHYbvhbyVbyWbtSbyXbyYbyZbyYbzabtXbzbbvpbvqbzcbtXbzdbzebzfbzgbzhbtXbhkbjZbsPbsPbsPbsPbsPbncbncbncbncbncbncbzibgibzjbwTbzkbzlbzmbznbzobzpbwTbzqbzrbzsbztbzubwYbyqbzvbzwbzxbzybzzbzzbzzbzAbzBbxhchfchfctEctDchfchfchfbrVbsbbgxbsdbsebjobjoaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwibzEbzFbzGbzHbzIbzJbwkbxrbxrbzKbzLbuRbzMbzNbzObzPbuQbzQbzRbzSbzSbzSbzTbzSbzSbzUbzSbzVaHYbzWbzXbzYbzYcuBbAabAbbAcbAdbAeaVLaVLbAfaVLbAgbAhaVLbAibAjbAkbAlaHYaHYbtXbAmbAnbAobtWbApbtXbtWbAqbArbtXbtXbtXbtXbtXbtXbtXbtXbhkbjZbfXbAsbAtbAubAvbAwbAxbAybAzbAAbAwbzibgibABbwTbACbADbAEbAFbAGbAHbwTbAIbAJbAKbALbAMbwYbyqbANbAObuybAPbAQbARbASbATbAUbxhchfchfchfbscchfchfchfbrVbsbbqtbAWbqvbqwbjoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwibwibwkbwkbwkbwkbwibwibAXbAYbAZbBabuQbuQbuQbuQbuQbuQbBbbBcaIcaIcaIcaIcbBdbBdbBdbBdbBdbBdbBdbBdbBdbBdbBebBfbBgbBhbBhbBhbBhbBhbBibBhbBhbBjbBhbyebBkbyeaIdaJlbBlbtXbBmbBnbBobBpbBqbtXbBrbxQbBsbBtbBubBvbBwbBxbBybBzbBAbBBbBCbBDbBDbBEbBFbBGbBHbBIbBJbBKbBLbAwbzibgibBMbBMbBMbBMbBMbBMbBMbBMbBMbBNbBNbBNbBNbBNbBNbBObBPbBQbuybuybuybuybuybuybuybxhbrVbrVbrVbrVbrVbrVbrVbrVbsbbgxbBRbBSbjobjoaafaafaafaagaagaagaagaagaagaagaagaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBTaaaaaaaaaaafaaaaaabwlbBUbBVbBWbBXbBYbBZbCabCbbCcbCdbCebCfaaaaaaaafaaabBdbCgbChbCibCjbCkbClbCmbCnbCobCpbCqbCrbBhbCsbCtcuDbCubCwbCvbCvbCxbCybCzbCAbyebyebyebyebtXbCBbCCbCDbCCbCEbtXbCFbvpbCGbCHbCIbCJbCIbCIbCKbCLbCMbCNbCObCObCObCPbCQbvlbCRbCSbCTbCUbCVbAwbzibgibBMbCWbCWbCWbCXbCWbCWbCWbBMbCYbCYbCZbCYbCYbBNbDabDbbqibDcbDdbDebDfbDgbDhbJqbDjbDkbDlbDmbDnbDobsmbtnbtnbvwbDsbDdbDdbjoaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajxaekaeZaekaelaaaaafaaabwlbwlbDtbxrbDubDvbDwbDxbDybDybDzbDAbDBbDCaafbDDbDEbDFbDGbDHbDIbDJbDIbDKbDIbDIbDIbBdbDLbDMbDNbBhbDObDPbDQbDRbDSbCvbDTbBjbBhbDUbDVbDWbDXbDYbDZbEabEbbCCbEcbCCbxQbEdbEebEfbEgbtXbEhbEibCCbCCbEjbEkbmSbmSbmSbmSbmSbElbEmbpGbEnbEobEpbBKbEqbAwbzibgibBMbCWbCWbCWbCWbCWbCWbCWbBMbErbEsbEtbEubEvbBNbEwbExbEybEzbEAbEBbECbEDbEDbEDbEDbEEbEFbEGbDnbjobvZbEIbEJbEJbEKbELbEMaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbENbEObENaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajZbEPbEQbEPajZbERbERbERbwlbESbxrbETbEUbEVbEWbwlbBcbEXbBcbBcbEYbEZaaabFabFbbFcbFdbDIbDIbFebDIbFfbFgbFhbDIbBdbDLbFibFjbBhbFkbFlbFmbFnbFobCvbFpbBjbzibFqbFrbFsbFrbFtbFubtXbFvbCIbFwbCIbFxbtSbFybCJbFAbtXbFCbCCbCCbCCbCCbGNbmSbPIbFEbFFbFGbBEbFHbvlbFIbBKbBKbFJbFKbFLbFMbFNbBMbCWbCWbCWbCWbCWbCWbCWbBMbFObFPbFQbFRbFSbFTbFUbFVbtbbFWbFXbEDbFYbEDbEDbEDbEDbEDbEDbEDbDnbFZbDpbGbbGcbGdbGebGfbEMaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbEObENbGgbENbEOaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeZalQaHnalQaeZbERbGhbGibwlbGjbxrbGkbxrbxrbEWbwlbGlbGmbGnbBcbEYbEZaafbFabGobGpbGqbGrbGsbGrbGrbGtbGubGrbGrbGvbGwbGxbGybBhbGzbBhbBhbBhbBhbGAbGBbGCbGDbGEbGFbGGbGHbGIbGIbtXbGJbGKcltbGMbGQbtXbGObGPbGSbtXbGRbDqbEHbDrbFDbGWbmSbGXbGYbpFbGZbHabHbbHcbCRbHdbBKbBKbHebAwbzibgibBMbBMbHfbCWbCWbHgbHfbBMbBMbHhbHibHjbHkbHlbBNbHmbHnbtbbHobHpbHqbHqbHrbHsbHtbHqbHubHvbHwbHxbHybGabHAbHBbHCbHDbHEbEMaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbHFbEObHGbHHbHIbEObHFaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajZalQalQalQbHJbHKbxrbxrbHLbGjbxrbxrbxrbxrbEWbwlbHMbGnbHNbBcbEYbEZaaabFabHObHPbHQbDIbDIbHRbDIbHSbHTbHUbHVbBdbHWbHXbHYbHZbIabIbbIbbIbbIbbIbbIcbIbbIdbIebIfbIgbIhbIibIjbtSbtSbtSbtSbtSbtSbtSbtSbtSbtSbMNbMNbMNbMNbMNbMNbOnbOCbmSbmSbmSbmSbIlbImbhjbAwbAwbAwbAwbAwbAwbzibgibBMbInbIobIpbIqbIrbIsbInbItbHhbHibHjbIubIvbIwbIxbIybuwbIzbDdbIAbIAbIBbICbIDbIEbEDbEDbIFbDnbIGbGLbIIbDdbIJbIKbIKbDdaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbEObEObILbIMbIMbIMbINbEObEOaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeZaHnaHnaHnaeZbERbIObIPbIQbIRbxrbxrbISbITbIUbwlbBcbBcbBcbBcbEYbDCaafbIVbDEbIWbDGbIXbDIbIYbDIbDIbDIbDIbDIbBdbDLbIZbJabJbbJcbJcbJcbJcbJcbJcbJdbJebJfbJgbJhbJibJjbJkbJlbJmbJnbJmbJmbJmbJmbJmbJmbJmbJmbJmbJmbJmbJmbJmbJobJpbmSbGXcqlbBDbJrbBEbJsbJtbJubJvbJvbJwbJxbJgbJybJzbBMbJAbJBbJCbJDbJEbJFbJGbItbItbItbItbItbItbJHbJIbJJbJKbJLbDdbDnbDnbDnbDnbDnbDnbJMbEDbEDbDnbjobvZbgxbDdbJNbJObJPbJQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabJRbJSbJRbIMbJTbIMbJUbJVbENaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajZamIbJWbJXajZbERbERbERbwlbwlbERbERbERbwlbwlbwlaaaaaaaaabJYbJZbEZaaaaaaaafaaabBdbKabKbbKcbDIbKdbKebKfbKgbKhbKibKjbKkbKlbKmbKnbKobKpbKqbKmbKmbKmbKmbKmbKrbKsbKmbKmbKtbKmbKubKmbKmbKmbKmbKmbyebyebyebyebyebyebyebyebKvbKwbmSbKxbKybKzbKAbKBbKCbKDbKEbKFbKFbKGbKFbKFbKHbKIbBMbKJbKKbKLbKKbKMbKKbKNbKObKPbKQbKRbKSbKTbKUbyqbHnbqibKVaafbKWbKXbKYbKZbLabKZbLbbLcbLdbDnbLebsbbLfbDdbDdbDdbDdbDdaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbEObEObLgbIMbIMbIMbLhbEObEOaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanTaekbLiaekafOaaaaaaaaaaafaaIaafaaaaafaaIaafaaaaaaaaaaafbJYbEYbEZaafaafaafaafbBdbBdbBdbBdbBdbBdbBdbBdbBdbBdbLjbLkbLlbLmbKmbKnbKobKpbKqbLnbLnbLobLpbLqbLrbLsbLtbLubLvbLwbLxbLybLzbLAbLBbLCbLDbLDbLDbLDbLDbLDbLEbyebKvbLFbLGbLGbLGbLGbLGbLHbLIbLJbLGbLGbLGbLGbLGbLGbLFbLKbLLbLMbLNbLObLNbLPbLQbLRbLSbLSbLSbLSbLSbLSbLTbLUbLVbqibKVaafbKWbLWbLWbLXbLYbLZbMabMbbMcbDnbMdbsbbkFbjobMebMfbjoaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaafaafbHFbEObMgbMhbMibMjbHFaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaIaafaaaaafaaIaafaaaaaaaaaaaabJYbEYbEZaaaaaaaaaaafbMkbMlbMlbMmbMnbMobMobMpbMpbMkbDLbMqbKkbMrbKmbMsbMtbMtbMubMvbLnbMwbMxbMybMzbMAbMBbMCbMDbMEbMFbMGbMFbMHbMIbMJaafbMKbMKbMKbMKbMKbMLbyebKvbMMcqzbMObMPbMQbLGbMRbMSbMTbLGbMUbMVbMWbMVbMUbLFbMXbBMbKKbKKbKKbMYbKKbKKbMZbNabNbbNbbNcbNbbNbbNdbNebNfbNgbKVaafbKWbLWbNhbKZbNibKZbNjbNkbNlbDnbsebsbbkFbjobsebsebjoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbEObENbNmbENbMjaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafbBcbBcbJYbJYbJYbBcbBcaaaaaaaaaaaabJYbEYbEZaaaaaaaaaaafbMkbNnbMmbMmbMmbMmbMobYnbNpbNqbNrbKjbNsbNtbNubNvbNwbNxbNybNzbNAbNwbNwbNwbNybNBbNCbNDbNEbNFbLBbNGbNHbNIbNJbNKbLDbNLbNMbNNbNObMKbMLbNPbKvbLFbNQbMUbMUcrqbLGbNRbNSbNTbLGbMVbNUbMVbNVbNWbNXbNYbBMbNZbOabObbOcbOdbOebOfbOgbOhbOibOjbOkbOlbItbOmbZlbOobOpbOpbDnbDnbDnbDnbDnbDnbDdbDdbDdbDnbsebsbbOqbsebsebOrbjoaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbENbEObENaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBcbOsbGnbOtbGnbOubBcaaaaaaaaaaaabJYbJZbEZaaaaafbJYbJYbMkbMmbMmbOwbOvbMmbOxbMobMobOzbDLbMqbOAbOBbZmbODbOEbOFbOGbOHbOIbOFbOJbOFbOKbOLbOMbLubONbOObOPbOQbORbOSbOTbOUaafbOVbOWbNObOXbMKbMLbNPbKvbLFbOYbOZbMUbPabLGbPbbPcbPdbLGbMUbPebPfbMUbMUbLFbKvbBMbItbItbItbItbJHbPgbPhbPibJHbItbItbItbItbItbPjbPkbPlbPmbPnbPobPpbPqbPpbPrbOpbPsbPtbPubPvbPwbsbbkFbjobjobjobjoabtaafaafaafaagaagaagaagaagaagaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbBcbPxbGnbGnbGnbPybBcaaaaaaaaaaaabJYbEYbEZaaaaafbJYbPzbPAbPBbMmbMmcbdbPDbPDbPDbPEbPFcbebMqbOAbPHccdbPJbPKbMFbPLbPMbPNbPObPPbPQbPRbPSbPSbPTbPUbLBbPVbPWbPXbPYbPZbQabQbbNLbQcbNObNObMKbMLbNPbKvbLFbQdbMUbQebLHbLGbLGbQfbLGbLGbQgbQhbQibQgbQgbLFbKvbBMbQjbQkbQkbQlbQmbKKbQnbQobQpbQqbCWbCWbCWbItbQrbQsbQtbQubQvbPobQwbQxbQybQzbOmbPtbQAbPtbPvbBRbGTbGUbjoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaagaagaagaagaagaagaagaagaagaagaagaagaagaagaaaaaaaaaaaaaaaaaaaaabBcbPxbGnbGnbQDbQEbBcaaaaafaaaaaabJYbEYbDCbBcbBcbBcbQFbMkbQGbMmbMmcqmbQHbQIbQJbQKbMkcqnbMqbOAbPHcqobQLbQMbMFbMFbQNbLnbQObQPbQQbQRbMFbMFbLubQSbQTbQUbQVbQWbQXbQWbQYaafbMKbMKbMKbMKbMKbMLbyebKvbLFbQZbRabRabRbbRcbRdbRebRfbRgbMUbPebMUbMUcqpbLFbKvbBMbCWbCWbCWbRhbRibKKbRjbKKbRkbRlbCWbCWbCWbItbRmbRnbRobRpbRqbRrbRsbRtbRrbRubOpbRvbPtbRwbPvbOpbSsbGVbjoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaafaafbRzaafaafaafbBcbBcbBcbBcbBcbBcbBcbBcbBcbBcbRAbBcbBcbBcbJYbJYbJYbRBbRCbRDbREbRFbRGbRCbRHbPFbPFbPFbPFcqrbMkbMkbMkbMkbMkcqtbRKbOAbRLbKmbRMbRNbPNbRObPNbLnbMFbMFbMFbQRbRPbRQbRQbRRbRSbRTbNGbRUbRVbRWbNKbLDbNLbRXbRYbRYbMKbMLbyebKvbRZbSabSabSabSbbScbMUbSdbMUbMUbMUbPebMUbMUbMUbLFbKvbBMbCWbCWbCWbSebSfbQobSgbKKbShbSibQkbQkbSjbItbSkbSlbPlbSmbSnbPobQybSobRrbSpbOpbSqbSqbSqbPvbSrbSsbGVbjoaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabStbSubSubSubSubSvbSwbSwbSxbSybSzbSAbSBbSCbSDbSEbBcbGnbGnbGnbGnbGnbGnbGnbSFbSGbSHbSIbSJbSKbSKbSKbSKbSLbSMbSMbSMbSNcqubSObDybDybSPbBccqnbMqbOAbSQbSRbSSbSTbRQbRQbSUbSVbRQbRQbSWbSXbSYbMFbSZbTabTbbTcbMFbTdbTebTfbOUaafbOVbTgbThbTibMKbMLbNPbTjbTkbTkbTkbTlbLFbTmbQZbTnbTobTpbTqbTrbTsbTsbTtbLFbKvbBMbItbItbItbItbTubTvbRjbTwbTubItbItbItbItbItbTxbTybTzbTAbTBbTCbTCbTCbTCbTDbOmbSqbSqbTEbPvbTFbSsbGVbjobjobjoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaagaaaaafaaaaaabJYbJYbJYbGnbTHbTIbTJbTKbTLbBcbTMbJYbJYbJYbJYbJYbJYbJYbJYbDCbTNbTObTObTObTObTObTObTObTObTPbTPcqxbTPbTPbTQbTRbBccqnbMqbOAbSQbTSbTTbTUbTVbPSbTWbTXbPSbPSbTYbTZbUabUbbUcbUdbUebUfbMFbTdbUgbUhbQabQbbNLbUibRYbRYbMKbMLbNPbUjbyebyebyebNYbLFbUkbMUbMUbUlbUmbUnbUobUpbUobUnbLFbKvbBMbQjbQkbQkbUqbQmbKKbQnbQobUrbUsbCWbCWbCWbItbUtbUubUvbUwbRnbRpbUxbUybUzbUAbOpbSqbSqbSqbPvbTFbSsbGVbsebsebjoaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaagaagaagaagaagbUDbGnbUDbGnbUEbTIbTIbUFbGnbBcbGnbJYaaaaaaaafaaaaaaaafaaabDCbTNbTObUGbUHbUIbUJbUKbULbUGbUMbUNcqCcqybTPbTPbTRbBccqDbMqbOAbURbUSbUTbUTbUUbKmbKmbKmbKmbKmbUVbUWbLnbLnbLnbUXbMFbTbbMFbTdbTebUYbOUaafbMKbMKbMKbMKbMKbMLbNPbUjbyebUZbzibNYbMMbVabVbbVcbVdbVebVfbVgbUpbVgbVhbLFbKvbBMbCWbVibCWbVjbRibKKbRjbKKbRkbVkbCWbVibCWbItbVlbVmbVnbVobVpbVqbVrbVsbVtbVubOmbVvbVwbVxbPvbSqbSsbHzbjobsebjobjobjoaagaagaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbJYbJYbJYbVzbVAbVBbVCbVDbGnbVEbGnbJYaaaaaaaafaaaaaaaafaaabDCbTNbTObUGbVFbVGbVHbVIbVJbUGbVKbVLcqEbVNbVObTPbTRbBccqnbMqbOAbVPbVQbKmbVRbVSbKmbVTbVUbVVbKmbVWbQRbVXbLnbVYbUfbMFbUdbVZbWabRVbWbbNKbLDbNLbWcbWdbWebMKbMLbyebUjbyebABbzibNYbLFbWfbWgbWhbWibUmbWgbWjbUpbWjbNVbNXbKvbBMbCWbCWbCWbWkbWlbQobSgbKKbShbWmbQkbQkbSjbBMbPvbWnbWobWobPvbPvbWpbWqbWrbWsbWtbWubTCbWvbSqbSqbSsbGVbjobWwbjobWxbjoaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafbJYbWybWzbWzbWAbTLbWBbBcbJYbJYaaaaaaaaaaaaaaaaaaaaabDCbTNbTObWCbWDbWEbVHbWFbWCbWCbVKbWGcqGcqFbWIbTPbTRbBccqnbMqbWJbWKbWKbWLbWMbWNbWObWPbWQbWRbKmbMFbQRbWSbWTbVYbWUbMFbUdbVZbTdbTebWVbOUaafbOVbWWbWXbWYbMKbMLbyebUjbyebGHbGHbNYbLFbLGbWZbXabLGbXbbLGbLGbLGbLGbLGbLFbKvbBMbItbItbItbItbTubXcbRjbXdbTubItbItbItbItbBMbRrbXebRrbRrbRrbPvbWpbWqbXfbXgbXhbXibUwbXjbPvbSqbSsbGVbjobsebsebsebXkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafbBcbBcbBcbBcbBcbBcbVEbBcbBcbBcbBcaafaaaaaabXlaaaaaaaaaaaaaaabEZbTNbTObWCbWCbXmbXnbXobWCbXpbXqbXrcqIcqHbXsbTPbTRbBccqJbXwbCrbWKbXxbXybXybXzbXAbXBbXCbXDbKmbXEbXFbVXbLnbVYbXGbMFbXHbVZbTdbXIbXJbQabQbbNLbXKbWdbWdbMKbMLbNPbUjbyebXLbzibNYbXMbSabSabXNbLGbIHbIkbQBbyebXRbXSbKwbKvbBMbQjbQkbQkbXTbQmbKKbQnbQobXUbXVbCWbCWbCWbBMbXWbRrbRrbRrbRrbPvbXXbXXbXYbXZbOpbOpbUwbOpbPvbOpbSsbGVbjobYabYbbYcbXkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfabfabfabfabfabfabfabfabqabfabfabfabfabfaaaaaabBcbGnbGnbGnbGnbGnbGnbGnbGnbWBbJYaafaaaaaaaafaaIbYdaaaaaaaaabEZbTNbTObYebYfbYgbYhbYibYjbYkbYlbYmcqMcqKbYobTPbYpbYqbYrbYsbGybWKbYtbXybYubYvbYwbYxbYybYzbYAbNFbYBbLnbLnbLnbYCbMFbYDbYEbTdbTebMFbOUaafbMKbMKbMKbMKbMKbMLbNPbUjbyebYFbzibYGbYHbTkbYIbYJbyebRybQCbTGbyebYNbKFbYObYPbBMbCWbCWbCWbYQbRibKKbRjbKKbRkbYRbCWbCWbCWbBMbYSbRrbYTbRrbRrbYUbYVbYWbYXbYYbOpbUwbUwbYZbPvbBRbZabUBbjobZcbZdbsebXkaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaafaaaaafaaaaafaaaacfaaaaafaaaaafaaaabfaafaafbBcbZebGnbBcbBcbBcbRAbBcbBcbBcbBcaaaaaaaaaaaIbZfbZgaaIaaIaafbEZbTNbTObZhbWCbUGbUGbUGbWCbZibZjbZkcqGcqNcqPbTPbBcbBcbZnbZobZpbWKbWKbZqbXybZrbZsbZtbZsbZubKmbMFbZvbZwbZxbZybONbZzbZAbZBbWabRVbZCbNKbLDbNLbZDbZEbZEbMKbMLbNPbUjbyebyebyebZFbZGbyebZHbZIbyebyebZJbyebyebZIbZKbZLbZMbBMbCWbCWbCWbZNbZObQobZPbKKbShbZQbQkbQkbSjbBMbRrbRrbZRbRrbRrbPvbXXbXXbZSbZTbOpbZUbZVbZWbPvboUbZabGVbjobjobjobsebjoaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaabZXbZYbZZaaabZXbZYbZZaaabZXbZYbZZaaaabfaaaaaabBccaacabbBccacbGnbGncadbOucaebBcaaaaaaaaacafaaIaaIaafaaaaaabEZbTNbTObWCcagcahbUGcaibWCbWCbVKcajcqGcqKcakbTPcalcamcancaocapcaqcarcascatcascatcaucatcavbKmcawcaxcaybPSbPSbPUbRPcazbRUbPVbTecaAbOUaafbOVcaBcaCcaDbMKbMLbyebUjbzicaEcaFbZFcaGbyebZHcaHcaIcaJcaKcaLcaIcaMbZHbgxcaNbBMbBMbBMbBMbBMbBMcaOcaPcaObBMbBMbBMbBMbBMbBMbPvbPvbPvbPvbPvbPvcaQcaQcaRcaSbPvbPvbPvbPvbPvbjobRxbGVbjocaTcaUbsebjoaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaafbZXcaVbZZaaabZXcaVbZZaaabZXcaVbZZaafaafaaaaaabBcbJYbJYbBcbBccaWcaXbOubGnbQDbBcaaaaaaaaaaaaaafaaaaaaaaaaaabDCbTNbTObUGcaYcaZbUGcbacbbbUGbVKcbccqEcqQcqVcqUcqXcqWbOAaZDcbgcbhcbicbjcbkcblcbmcbnbXycbobKmcbpbMFbZvbRPbRQcbqcbrcbscbtbLAcbucbvbQabQbbNLcbwbZEbZEbMKbMLbyecbxcbycbzcbAcbBcbCbyecbDcbEcbFcbGcbHcbGcbIcbEcbJbgxcbKbjoaaaaaaaaaaafaaaaaacbLaaaaafaaaaaaaaaaaabjocbMbMfbkGcbNcbNbPvcbOcbOcaRbQtcbPcbQbsebsebsebBRbRxbHzbjocbRbsebsebjobjobjoaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaabZXcaVbZZaafbZXcaVbZZaafbZXcaVbZZaaaaafaafaafaafaafaafaafbBcbBcbBcbBcbRAbBcbBcaaaaaaaaaaaaaafaaaaaaaafaaabDCbTNbTObUGcbScbTcbUcbVcbWbUGcbXcbYcbZccaccbbTPccccqYcceccfccgcchcciccjcckcclccmccnccoccpccqccrbOQccscctbMFbMFbMFbMHbSYcctbTebUYbOUaafbMKbMKbMKbMKbMKbMLbyebYFccuccvccwccxccybyebyecczccAccBbKwccCccDbyebyebgxcbKbjoaaaaaaaaaaafaaaaaacbLaaaaafaaaaaaaaaaaabjobseccEbqvccFccGbPvccHccHccIbQtbPvbOpbjoccJccKbBRbRxbGVbsebsebsebUCbkHbVybkHaagaagaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbZXcaVbZZaaabZXcaVbZZaaabZXcaVbZZaafaafaaaaaaaaaaaaaaaaaabBcccRbBcbGnbGnbBcaafaaaaafaaaaaaaafaaaaaaaafaaabDCbTNbTObTObTObTObTObTObTObTObTPbTPbTPbTPbTPbTPbBcccSbBcccTccUccUccUccVccWccXccUccYccZcdabKmcdbcdcbPXcddcdecdfcdecddcdgcddcdhbRPcdiaafaafaafaafaafaafbMLcdjcdjcdjcdkcdlcdjcdjcdjcdmbyecdncdncdocdncdnbyebABbZGcbKbjobXkbXkbXkbjobXkbXkcdpbXkbjobXkbXkbXkbXkbjobjobRxcdqbjobjobPvbPvbPvcdrcdsbPvbBRbjobYcbseboTbRxbUBbjobjocdtbjobjobjobjoaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfabfaafaaabZXcaVbZZaaabZXcaVbZZaaabZXcaVbZZaaaaafaaaaaacducdvcdvcdvcdvbBcbBccdwbGnbBcbJYbJYbJYbJYbJYbJYbJYbJYbJYbBcbDCbTNbBccdxcdycdzcdzcdzcdzcdzcdzcdzcdzcdzcdAcdAcdzcdBcaWccTcdCcdDcdEcdFcdGcdHccUcdIcdJcdKbKmcdbcdLcdMcdNcdOcdPcdQcdRbMFcdScdTcdUbLuaafaafaaaaaaaaaaaacdVcdWcdXcdYcdZceacebceccdjcedceecefcegcehccBccBbzibzibZGbntceiceiceiceiceiceiceicejcekcekcekcekcekcekcelcekcemcekcekcenceocepceqbXOcesbjobjocetceoceuceocevbGVbjocewbsebsebjoaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaafaaaaaaaaacexaaaaaaaaacexaaaaaaaaacexaaaaaaaafcducducduceycezceAceBceCbGnceDceEceFceEceEceEceEceEceEceEceEceEceEceGceHbRGceIceJceKceKceKceKceKceKceKceKceKceKceKceKceKceKccTccUceLceMceNceOcePceQceRceSceTceKbLuceUbLuceVbLuceUbLuceVbLuceWbLuceWbLuaafaafaaaaaaaaaaaacdjceXceYceZcfacfbcfccfdcdjcedcfeccBcffcfgcfhcfibDZcfjcfkcflcflcflcflcflcflcflcfmcfncflcflcflcflcflcflcfocfpcfqbmicfrcfscftcftcftbXPbYKbXQbYMbYLcbfbZbbZbccLccMbjocaUbsecfCbjoaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaafalkcfEcfEcfFcfGcfGcfGcfGcfGcfGcfGcfGcfGcfGcfGcfHcfIcfJcfIcfKcfLcfMcfNceEcfOcfPbOubBcbJYbJYbJYbJYbJYbJYbJYbJYbJYbBcbBccfQbSKcfRcfSceKcfTcfTcfUceKcfVcfWcfXctHcfZcgacgbcgccgdcgeccUcgfcggcghcgicgjcgkcglcgmcgnceKaafcgoaafbMLaafcgoaafbMLaafcgpaafcgpaaaaaaaaaaaaaaaaaaaaacdjcgqcgrcgscgtcgucgvcgwcdjbzicgxcgycgzcgAcgBbDZcgCcgDbyebjobXkbXkbXkbXkbjobXkbXkbXkbXkbjobXkbXkbXkbXkbjocgEbsebjocgFcgGbjobjobXkbXkbjobjocgHbZacgIbjocgJcgKboRbjobjobjobjobjoaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaafaaaaaaaaacgLaaaaaaaaacgLaaaaaaaaacgLaaaaaaaafcducducducgMcgNcgOcdvbGnbGnbGnbGnbBcaaaaaaaafaaaaaaaafaaaaaaaafaaabBccgPbBccgQcgRceKcgScgTcgUcgVcgWcgXceRceRceRcgYcgZchachbcgXccUchcchdchecgictIccUchgchhchiceKbMKchjbOVchjbMKchjbOVchjbMKchkbOVchlbMKaaaaaaaaaaaaaaaaaacdjchmchnchochpchqchrchschtchuchubFMchvchwbFMchxbyebyebyeaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaabjochybLebjochzbZabjoaaaaaaaaaaaabjobsebZachAchBchBchCchDchBaaaaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfabfaafaaabZXchEbZZaaabZXchEbZZaaabZXchEbZZaaaaafaaaaaacducdvcdvcdvcdvchFbWBbGnbGnbBcaafaafchGchGchGchGchGchGchGaafbBcbBcbBcchHchIceKchJcgUcgUcgVchKchLchLchMchNchOchPchPchQceRccUchRchSchTchUchVccUchWcdJchXceKbMKchYchZciabMKcibciccidbMKciecifcigbMKaaaaaaaaaaaaaaaaaacihciichncijcikcilcimcincdjaafbyecczciobNPbNPbyebyeaaaabtaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaabjocipbjobjociqbZabjobjobXkbXkbjobjobsecircischBcitciucivchBaaaaaaaafaafaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbZXchEbZZaaabZXchEbZZaaabZXchEbZZaafaafaafaaaaaaaaaaaaaagbBcbBcbBcciwbGnbBcaaaaaachGcixciycizciyciAchGaaabBcbQDbGnciBchIceKciCciCciDceKciEciFciGciHceSciIciJciKciLciLccUciMciNciOciPciQciRciSciTciUceKbMKciVciWciVbMKciXciYciXbMKciZcjacjbbMKaaaaaaaaaaaaaaaaaacdjcjccjdcjecjfcjgcjhcjicdjaafaafaafcjjaaaaaaaafaaaaaaabtaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaabXkbXkbXkbjocjkbBRbjocjlcjmcjnceocjncjncjncjncjocjpcjqchBcjrcjscjtchBaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFZaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaabZXchEbZZaafbZXchEbZZaafbZXchEbZZaaaaafaafaafaaaaaaaaaaagcjucjvcjubGnbGnbBcaaaaaachGcjwcjxcjycjzcjAchGaaabBccaXbGnciBchIceKciCciCciDceKcjBcgccjCcjDcjEcjFcjCcgccjCcjCcgccjGcjHcjIciIcjJcjKcjLceScjMceKbMKciVcjNciVbMKciXcjOciXbMKcjbcjPcjbbMKaaaaaaaaaaaaaaaaaacdjcdjcdjcjQcjRcjScjTcjUcjRaafaaaaafcfDaaaaaaaaaaaaaaaabtaafaafaafaafaafaafaaaaaaaaaaaaaaaaaabXkbsecjWbjocjXbsebjocjYbmhbmhcjZbmhbmibmibmickackackbchBckcckdckechBaafaaaaafaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaafbZXchEbZZaaabZXchEbZZaaabZXchEbZZaafaafaaaaafaafaaaaaaaagbBcbBcbBcbBcbGnbBcaafaafchGckfckgckhckickfchGaafbBcceKckjckkcklceKciCciDciDceKckmcknckockpceSckqckrcksckrckrcktckuckvckwckxckyckyckyckzckAceKbMKbMKbMKbMKbMKbMKbMKbMKbMKbMKbMKbMKbMKaaaaaaaaaaaaaaaaaaaaaaaaaaackBcjRckCckDckEcjRaafaafaaaaaaaaaaaaaaaaaaaaaabtaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaabXkckFbsebWwcgEbsebjobjobjobjobjobsebjoaafaaaaaaaaaaafckGckGckHckGckGaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaabZXckIbZZaaabZXckIbZZaaabZXckIbZZaaaabfaaaaaaaafaafaaaaaaaaaaaaaaabJYbGnbJYaaaaaachGckJckKckLckMckNchGchGchGceKckOckkckPceKceKceKceKceKckQceRckRciHceSceRceRceRckSckTckUceSceSciHceRckVceRceRckWckXceKaafaaaaaaaaaaafaafaaaaaaaafaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaackYcjRcjSckZcjUcjRaaaaafaaaaaaaaaaaaaaaaaaaaaabtaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaabXkbsebuEbjoclabsebsebsebsebsebsebsebjoaafaaaaaaaaaaafaaackGclbckGaaaaafaaaaafaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaabZXckIbZZaaabZXckIbZZaaabZXckIbZZaaaabfaaaaaaaafaafaaaaaaaaaaaaaaabJYbGnbJYaaaaaachGccNckKckLckMckNchGchGchGceKckOckkckPceKceKceKceKceKckQceRckRciHceSceRceRceRckSckTckUceSceSciHceRckVceRceRckWckXceKaafaaaaaaaaaaafaafaaaaaaaafaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaackYcjRcjSckZcjUcjRaaaaafaaaaaaaaaaaaaaaaaaaaaabtaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaabXkbsebuEbjoclabsebsebsebsebsebsebsebjoaafaaaaaaaaaaafaaackGclbckGaaaaafaaaaafaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaafaaaaafaaaaafaaaaafaaaaafaaaaafaaaabfaaaaaaaaaaafaafaaaaaaaaaaaabJYbGnbJYaaaaaachGclccldcleclfclgclhclicljclhclkcllclmclncloclpclqclrclschLcqqcluclvclwclxclyclzclyclzclAclBclCchLchLclDchLclEclFceKceKceKceKceKcgccgccgccgcceKaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaackYcjRclGclHclIclJaaaaafaafaafaafaaeaafaaaaaaaafaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaabXkbXkbXkbjocipbjobjoclKclLbLebMdbjobjoaafaaaaaaaaaaafaaackGckHckGaaaaafaaaaafaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfabfabfabfabqabfabfabfabfabfabfabfabfabfaaaaaaaaaaaaaafaafaaaaaaaafbJYbGnbJYaafaafchGclMclNclOclPclQclRclSclTclRclUclVclWclXclYclZcmaclZcmbcmccmdcmecmfcmgcmhcmicmjcmkcmjcmlcmmcmnchPcmecmochPcmpcmqchPcmrceRcmsceKcmtcgccmuaekaekaelaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaackYcjRcjRcmvcjRcjRaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaafcmwaafbjobjobXkbXkbjobjoaaaaafaaaaaaaaaaafaaaaaacmxaaaaaaaafaaaaafaaaaaaaafaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaaaaabJYbGnbJYaaaaaachGcmycmzcmAcmBcmCchGcmDcmEchGcmFceRcmGciHceScmHcjCcmIciIcmJcmKcmLcmLcmLcmMcmNcmOcmPcmQcmRcmMcmScmSckUceRckVciIcmTcmUcmVchLcmWcmXcgUcmXcmYaeXaeYaeZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaackYaagcjRcmZcjRcnaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaeaaaaaaaaaaaaaaaaafcnbaafaaaaafaaaaaaaafaaaaaaaafaaaaaaaaaaafaaaaaacmxaaaaaaaafaaaaafaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbBcbBcbRAbBcbBcaaachGcnccndcnechGchGchGchGchGceKcnfceRcmGcngcnhcnicjCcnjciIcnkcnlcnmcnncnoceKcnpcnqcnrcnscntceKcnucnvcnvcnlcnkciIcnwcnxceSceRcnyceKcnzcgccnAaekaekafOaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaacfDaagcnBcnCcnBaagaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaafcnDaafaaaaafaaaaaaaafaaaabfabfabfabqaafaafaafaafcmxaafaafaafaafaafabqabfabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafbBccgPbGncnEbBcaafchGchGchGchGchGaafaaaaaaaafceKcnFceRcnGcnHcnHcnIcgccgccnJceKcnKcnLcnLcnLceKcnMcnNcnOcnPcnQceKcnLcnLcnLcnKceKcnJcgccnRceSceRceKceKcgccgccgccgcceKaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaafaagaaaaaaaaaaagaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaaaaaaaafaaaaaaaafaaaabfaaaaaaaafaaaaafaaaaaacnSaaaaaaaafaaaaafaaaaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabJYcnTcnUcnVbBcaafaaaaaaaafaaaaaaaafaaaaaaaafceKcnWcnXciIcnYcnZcoacgccobcocceKcodcoecofcoecogcohcoicojcokcnQcogcoecoecoecolceKcomconckkceScoochWcopceRcoqcogaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaagaagaagaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaafaaaabfaafcorcorcorcorcoraaacosaaacorcorcorcorcoraafabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabJYcotcoubHMbBcbBccovcovcovcovcovcovcovcovcgcceKcowcoxcoycozcowceKceKceKcnJceKceKcogcogcogcogcoAcoBcoCcoBcoDcogcogcogcogceKceKcnJceKckkcoEcoFcoGcoHceRcoIcogaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaabfaaacoJcoKcoKcoKcoKcoLcoscoMcoNcoNcoNcoNcoOaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabJYcotcoubHMbBccgcccOccOccOccOccOccOccOccOcgcceKcowcoxcoycozcowceKceKceKcnJceKceKcogcogcogcogcoAcoBcoCcoBcoDcogcogcogcogceKceKcnJceKckkcoEcoFcoGcoHceRcoIcogaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaabfaaacoJcoKcoKcoKcoKcoLcoscoMcoNcoNcoNcoNcoOaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabJYbJYbJYbJYbBcaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceKcoPcoQcoRaaaaaaaaacogcogcogcogcogcogcogcogcogaaaaaaaaacoScoTcoUcoVcoWclyclycoXcoYcoZcogaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaabfacfcpacpacpacpacpaaaacosaaacpacpacpacpacpaaafabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceKcpbcpccpcaaaaaaaafaafaafaafaafaafaafaafaafaafaafaaaaaacpccpdcpbceKcpecpfceKcgccgccpgcgcaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaabfaaaaaaaaaaafaaaaaaaaacosaaaaaaaaaaafaaaaaaaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceKcphcpicpjaafaafaafcpkaaaaaaaaaaaacpkaaaaaacpkaafaafaafcplcpmcpnceKcpocdIcgcaafaaacppcpqaafaaaaaaaaaaafaaaaaaaaaaafaaaaaaaaaaafaaaaaaaaaaafaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaafcorcorcorcorcoraaacosaaacorcorcorcorcoraafabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -6673,11 +6665,11 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceKcqscpccqAaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaacqBcpccqsceKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaafaaaaaaaaaaafcqecsgcrWcshcqOcsmcslcsncqeaagaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaafaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaachWceKceKceKcpcaafaafaafaafaaaaaaaaaaaaaaaaafaafaafaafcpcceKceKceKchWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaafaaaaaaaaaaafcqecqecqecsQcsqcsRcqecqecqeaagaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfabfabfabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaacqsceKceKceKceKceKceKceKceKceKceKceKceKceKceKceKceKceKcqsaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaafaafaafaafaafaaacsTcqgcrPcsUcsXcqgcsTaaaaagaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaacqscqscqscqscpMcqscqscqscqscqscqscqscpMcqscqscqscqsaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaagcsYcsYaagaafaaacsTcqgcrPcsZcrQcqgcsTaaaaagaagcsYcsYaagaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaaaaaaaaaaaaaafaafaafaafaaaaaaaaaaaaaaaaafaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfcqLcqLctaaafaafctbcqectgctfcthcqectbaafaafctacqLcqLabfabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcqRcqScqTctiaaacrgcrgcrgcrhcricrkcrgcrgcrgaaactjcrbcrccrdabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcqRcqScrcctkctlcrgctoctnctpcrsctrctqctwcrgctyctxcqScrccrdabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcqRcrmctActzctzcrpctFcrFctGcrGctJcrFctKcrwctLctLctMcrzcrdabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaacqscqscqscqscpMcqscqscqscqscqscqscqscpMcqscqscqscqsaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaagaagaagaagaafaaacsTcqgcrPcsZcrQcqgcsTaaaaagaagaagaagaagaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaaaaaaaaaaaaaafaafaafaafaaaaaaaaaaaaaaaaafaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfcqLcqLabfaafaafctbcqectgctfcthcqectbaafaafabfcqLcqLabfabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcqRcqScqTccPaaacrgcrgcrgcrhcricrkcrgcrgcrgaaaccQcrbcrccrdabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcqRcqScrccercfucrgctoctnctpcrsctrctqctwcrgcfwcfvcqScrccrdabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcqRcrmcfxcrocrocrpctFcrFctGcrGctJcrFctKcrwcrxcrxcfycrzcrdabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcqRcrBcrdaaaaaacrgctNcrFctOcrNctPcrFctQcrgcrDcrDcrIcrJcrdabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfctRcrRcqecqecqecrgcrSctScrUcrUcrVctScrXcrgcqecqecqecrYctTabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcqRcrBcrdaaaaaacrZcsacsbcsccsdcrZcsecsfcrZaaaaaacqRcrJcrdabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -6686,11 +6678,11 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcqRcrBcrdaaacrZcrZcsrcspcspcsscspcspcstcrZcrZaaacqRcrJcrdabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfctRcsucqecqecrZcrZcsocspcsvcsvcsvcspcsocrZcrZcqecqecswctTabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcqRcrBcrdcqhcrZcsxcsocsycsvcszcsvcsycsocsAcrZcqhcqRcrJcrdabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcqRcrBcrdaaacrZcrZcsocspcsBcsCcsDcspcsocrZcrZaaacqRcrJcrdabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcqRcrBcrdaaacrZcrZcsrcspcspcsEcspcspcstcrZcrZaaacqRcrJcrdabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcqRcrBcrdaaacrZcrZcsFcspcsGcsHcsIcspcsFcrZcrZaaacqRcrJcrdabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfctRcsJcqecqecsvcrZcrZcsecrZcsKcrZcsbcrZcrZcsvcqecqecsLctTabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacsMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcqRcrBcrdaaaaafaaacsNcsNcsNcsOcsNcsNcsNaaaaafaaacqRcrJcrdabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcqRcrBcrdaaacrZcrZcsocspcfAcfzcsDcspcsocrZcrZaaacqRcrJcrdabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcqRcrBcrdaaacrZcrZcsrcspcfBcsycspcspcstcrZcrZaaacqRcrJcrdabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcqRcrBcrdaaacrZcrZcsFcspcovckJcsBcspcsFcrZcrZaaacqRcrJcrdabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfctRcsJcqecqecsvcrZcrZcsecsEcsCcsGcsbcrZcrZcsvcqecqecsLctTabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacsMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcqRcrBcrdaaaaafaaacrZcrZcrZcsHcsIcrZcrZaaaaafaaacqRcrJcrdabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcqRcrBcrdaaaaafaaacsPctZcuacsScuccubcsPaaaaafaaacqRcrJcrdabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcqRcrBcsVcrfcsWcsWcsPcudcufcuecuhcugcsPcrfcsWcrfctccrJcrdabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcqRctdctecrocrocrocujcuiculcukcuncumcuocrxcrxcrxcrxctmcrdabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/map_files/generic/z2.dmm b/_maps/map_files/generic/z2.dmm index a209cde1838..e160a9e1d29 100644 --- a/_maps/map_files/generic/z2.dmm +++ b/_maps/map_files/generic/z2.dmm @@ -215,22 +215,22 @@ "eg" = (/obj/structure/shuttle/engine/propulsion,/turf/simulated/shuttle/plating,/area/space) "eh" = (/obj/structure/shuttle/engine/propulsion{icon_state = "burst_r"},/turf/simulated/shuttle/plating,/area/space) "ei" = (/turf/unsimulated/wall,/area/centcom/control) -"ej" = (/turf/unsimulated/wall/fakedoor,/area/centcom/control) +"ej" = (/obj/machinery/door/airlock/centcom{name = "Centcom Customs"; opacity = 1; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) "ek" = (/turf/unsimulated/wall,/area/centcom/evac) -"el" = (/turf/unsimulated/floor{icon_state = "green"; dir = 9},/area/centcom/control) +"el" = (/obj/machinery/vending/clothing,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/ferry) "em" = (/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) -"en" = (/turf/unsimulated/floor{icon_state = "green"; dir = 5},/area/centcom/control) -"eo" = (/turf/space,/area/centcom/evac) +"en" = (/obj/machinery/door/poddoor/preopen{id = "CentComPort"; name = "security door"},/turf/unsimulated/floor{dir = 8; heat_capacity = 1; icon_state = "warning"},/area/centcom/control) +"eo" = (/obj/machinery/door/airlock/centcom{name = "Centcom Docks"; opacity = 1; req_access_txt = "109"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) "ep" = (/turf/unsimulated/wall,/area/centcom/prison) -"eq" = (/obj/structure/stool/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "green"; dir = 9},/area/centcom/control) +"eq" = (/obj/structure/table/reinforced,/obj/machinery/door/window/brigdoor{base_state = "rightsecure"; dir = 1; icon_state = "rightsecure"; name = "Centcom Customs"; req_access_txt = "109"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) "er" = (/turf/unsimulated/floor{icon_state = "greencorner"; dir = 1},/area/centcom/control) "es" = (/turf/unsimulated/floor{icon_state = "greencorner"; dir = 4},/area/centcom/control) -"et" = (/obj/structure/stool/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "green"; dir = 5},/area/centcom/control) +"et" = (/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/suppy) "eu" = (/obj/effect/landmark{name = "prisonwarp"},/turf/unsimulated/floor{name = "plating"},/area/centcom/prison) "ev" = (/obj/structure/stool/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "green"; dir = 8},/area/centcom/control) "ew" = (/obj/structure/stool/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "green"; dir = 4},/area/centcom/control) -"ex" = (/turf/unsimulated/floor{icon_state = "green"; dir = 8},/area/centcom/control) -"ey" = (/turf/unsimulated/floor{icon_state = "green"; dir = 4},/area/centcom/control) +"ex" = (/obj/structure/table,/obj/item/weapon/pen/blue{pixel_x = 4; pixel_y = 4},/obj/item/weapon/pen/red,/obj/item/weapon/pen{pixel_x = 8; pixel_y = 8},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/suppy) +"ey" = (/obj/structure/table,/obj/item/weapon/clipboard,/obj/item/weapon/coin/silver,/turf/unsimulated/floor,/area/centcom/suppy) "ez" = (/obj/structure/grille,/obj/structure/window/shuttle,/turf/simulated/shuttle/plating,/area/space) "eA" = (/turf/unsimulated/wall/fakedoor{name = "Centcom Security"},/area/centcom/evac) "eB" = (/turf/simulated/shuttle/floor,/turf/simulated/shuttle/wall/interior{icon_state = "swall_f10"},/area/space) @@ -239,8 +239,8 @@ "eE" = (/obj/machinery/computer/emergency_shuttle,/turf/simulated/shuttle/floor,/area/space) "eF" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/regular{pixel_x = 2; pixel_y = 3},/obj/item/weapon/crowbar,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/space) "eG" = (/turf/simulated/shuttle/floor,/turf/simulated/shuttle/wall/interior{icon_state = "swall_f6"},/area/space) -"eH" = (/obj/machinery/door/poddoor{id = "CentComPort"; name = "security door"},/turf/unsimulated/floor{dir = 1; icon_state = "loadingarea"},/area/centcom/control) -"eI" = (/obj/machinery/door/airlock/centcom{name = "Centcom Security"; opacity = 1; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) +"eH" = (/obj/structure/table,/obj/item/weapon/paper_bin,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/suppy) +"eI" = (/obj/structure/closet/crate,/turf/unsimulated/floor{tag = "icon-plating"; icon_state = "plating"},/area/centcom/suppy) "eJ" = (/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/evac) "eK" = (/obj/structure/table,/obj/item/weapon/storage/box/handcuffs,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/evac) "eL" = (/obj/machinery/computer/atmos_alert,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/space) @@ -256,7 +256,7 @@ "eV" = (/obj/machinery/flasher_button{id = "cockpit_flasher"; pixel_x = 6; pixel_y = -24},/turf/simulated/shuttle/floor,/area/space) "eW" = (/obj/machinery/computer/communications,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/space) "eX" = (/turf/unsimulated/floor{dir = 8; icon_state = "vault"},/area/centcom/control) -"eY" = (/obj/structure/table/reinforced,/obj/machinery/door/window/brigdoor{base_state = "rightsecure"; dir = 4; icon_state = "rightsecure"; name = "Centcom Customs"; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) +"eY" = (/turf/unsimulated/floor,/area/centcom/suppy) "eZ" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) "fa" = (/obj/structure/table/reinforced,/obj/item/weapon/clipboard,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/evac) "fb" = (/obj/structure/stool/bed/chair/office/dark,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/evac) @@ -278,9 +278,9 @@ "fr" = (/obj/structure/closet/emcloset,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/space) "fs" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/fire,/obj/item/weapon/storage/firstaid/regular{pixel_x = 2; pixel_y = 3},/obj/item/weapon/crowbar,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/space) "ft" = (/obj/structure/table/wood,/obj/item/weapon/paper_bin{pixel_y = 4},/obj/item/weapon/pen,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/ferry) -"fu" = (/obj/structure/mirror{pixel_y = 32},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/ferry) -"fv" = (/obj/structure/dresser,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/ferry) -"fw" = (/obj/machinery/door/poddoor/preopen{id = "CentComPort"; name = "security door"},/turf/unsimulated/floor{dir = 1; icon_state = "loadingarea"},/area/centcom/control) +"fu" = (/obj/machinery/door/airlock/centcom{name = "Centcom Supply"; req_access_txt = "106"},/turf/unsimulated/floor{tag = "icon-brown"; icon_state = "brown"},/area/centcom/suppy) +"fv" = (/turf/unsimulated/floor{dir = 8; heat_capacity = 1; icon_state = "warning"},/area/centcom/suppy) +"fw" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows2"; dir = 1},/area/centcom/suppy) "fx" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 8},/area/centcom/evac) "fy" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows2"; dir = 8},/area/centcom/evac) "fz" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 4},/area/centcom/evac) @@ -288,11 +288,11 @@ "fB" = (/turf/simulated/shuttle/floor4,/area/space) "fC" = (/obj/machinery/door/airlock/glass{name = "Emergency Shuttle Brig"; req_access_txt = "2"},/turf/simulated/shuttle/floor,/area/space) "fD" = (/obj/structure/stool/bed/chair/office/dark,/obj/effect/landmark{name = "Emergencyresponseteam"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry) -"fE" = (/obj/structure/stool,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/ferry) +"fE" = (/turf/unsimulated/wall/fakeglass,/area/centcom/suppy) "fF" = (/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/ferry) -"fG" = (/turf/unsimulated/floor{icon_state = "grass1"; name = "grass"},/area/space) +"fG" = (/obj/machinery/door/airlock/centcom{name = "Crate Storage"; req_access_txt = "106"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/suppy) "fH" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 1},/area/centcom/control) -"fI" = (/turf/unsimulated/floor{icon_state = "bot"},/area/centcom/control) +"fI" = (/obj/machinery/vending/autodrobe,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/ferry) "fJ" = (/turf/unsimulated/floor{icon_state = "grass1"; name = "grass"},/area/centcom/control) "fK" = (/obj/machinery/door/airlock/external{name = "Port Docking Bay 1"},/turf/unsimulated/floor{icon_state = "engine"},/area/centcom/evac) "fL" = (/turf/unsimulated/floor{icon_state = "engine"},/area/centcom/evac) @@ -306,9 +306,9 @@ "fT" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/obj/effect/landmark{name = "Emergencyresponseteam"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry) "fU" = (/obj/machinery/door/airlock/centcom{name = "Dressing Room"; opacity = 1; req_access_txt = "0"},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/ferry) "fV" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows2"; dir = 1},/area/centcom/control) -"fW" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 8},/area/centcom/control) -"fX" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows2"; dir = 8},/area/centcom/control) -"fY" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 4},/area/centcom/control) +"fW" = (/obj/structure/mirror{pixel_y = 32},/obj/structure/dresser,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/ferry) +"fX" = (/obj/structure/flora/ausbushes/brflowers,/turf/unsimulated/floor{icon_state = "grass1"; name = "grass"},/area/centcom/control) +"fY" = (/obj/structure/table/wood,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/ferry) "fZ" = (/obj/machinery/door/airlock/centcom{name = "Centcom Security"; opacity = 1; req_access_txt = "0"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/evac) "ga" = (/turf/simulated/shuttle/wall{icon_state = "swallc4"; dir = 2},/area/space) "gb" = (/turf/unsimulated/floor{name = "plating"},/area/centcom/ferry) @@ -354,20 +354,34 @@ "gP" = (/obj/structure/optable,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/space) "gQ" = (/obj/structure/table,/obj/item/weapon/circular_saw,/obj/item/weapon/cautery,/obj/item/weapon/surgicaldrill,/obj/item/robot_parts/l_arm,/obj/item/robot_parts/r_arm,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/space) "gR" = (/obj/structure/table,/obj/item/weapon/scalpel,/obj/item/weapon/retractor,/obj/item/weapon/hemostat,/obj/item/weapon/surgical_drapes,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/space) +"gS" = (/obj/item/weapon/shard{color = "#008000"; icon_state = "small"},/obj/structure/grille{color = "#008000"; density = 0; icon_state = "brokengrille"},/turf/unsimulated/floor/plating,/area/wizard_station) "gT" = (/obj/machinery/door/airlock/shuttle,/obj/docking_port/mobile{dir = 8; dwidth = 2; height = 12; id = "ferry"; name = "ferry shuttle"; travelDir = 180; width = 5},/obj/docking_port/stationary{dir = 8; dwidth = 2; height = 12; id = "ferry_away"; name = "unknown"; turf_type = /turf/unsimulated/floor; width = 5},/turf/simulated/shuttle/floor,/area/space) "gU" = (/obj/machinery/door/airlock/external{name = "Ferry Airlock"; req_access_txt = "0"},/turf/unsimulated/floor{icon_state = "engine"},/area/centcom/ferry) "gV" = (/turf/unsimulated/floor{icon_state = "engine"},/area/centcom/ferry) "gW" = (/turf/unsimulated/floor{icon_state = "greencorner"; dir = 4},/area/centcom/ferry) "gX" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0},/turf/unsimulated/wall,/area/centcom/evac) +"gY" = (/obj/structure/shuttle/engine/heater{tag = "icon-heater (WEST)"; icon_state = "heater"; dir = 8},/turf/unsimulated/floor/plating,/area/wizard_station) +"gZ" = (/obj/machinery/door/poddoor/preopen,/obj/effect/decal/cleanable/blood/splatter,/turf/unsimulated/floor/plating,/area/wizard_station) "ha" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 5},/area/centcom/ferry) +"hb" = (/obj/structure/table/wood,/obj/item/clothing/suit/wizrobe/magusblue,/obj/item/clothing/head/wizard/magus,/obj/item/weapon/staff,/obj/structure/mirror/magic{pixel_y = 28},/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "hc" = (/obj/structure/flora/bush,/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/area/syndicate_mothership) +"hd" = (/obj/machinery/door/poddoor/preopen,/obj/effect/decal/cleanable/blood/splatter,/obj/effect/decal/cleanable/blood/gibs/body,/turf/unsimulated/floor/plating,/area/wizard_station) +"he" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 4},/turf/unsimulated/floor/plating,/area/wizard_station) +"hf" = (/obj/item/weapon/shard{color = "#008000"; icon_state = "medium"},/obj/structure/grille{color = "#008000"; density = 0; icon_state = "brokengrille"},/turf/unsimulated/floor/plating,/area/wizard_station) +"hg" = (/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor/plating,/area/wizard_station) +"hh" = (/obj/structure/stool/bed/chair/comfy/black{dir = 8},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/ferry) "hi" = (/turf/unsimulated/floor{name = "plating"},/turf/simulated/shuttle/wall{icon_state = "swall_f9"; dir = 2},/area/space) "hj" = (/turf/unsimulated/floor{icon_state = "greencorner"},/area/centcom/ferry) "hk" = (/obj/structure/stool/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "greencorner"; dir = 8},/area/centcom/evac) +"hl" = (/turf/unsimulated/floor{dir = 1; icon_state = "green"},/area/centcom/control) "hm" = (/turf/unsimulated/wall/fakeglass,/area/centcom/ferry) "hn" = (/obj/machinery/door/airlock/shuttle{name = "Emergency Shuttle Airlock"},/turf/simulated/shuttle/plating,/area/space) "ho" = (/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = -30},/turf/simulated/shuttle/floor,/area/space) +"hp" = (/obj/structure/flora/ausbushes/palebush,/turf/unsimulated/floor{icon_state = "grass1"; name = "grass"},/area/centcom/control) +"hq" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows2"; dir = 6},/area/centcom/suppy) +"hr" = (/obj/structure/closet,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/suppy) "hs" = (/turf/unsimulated/wall,/area/centcom/holding) +"ht" = (/obj/structure/closet/secure_closet/quartermaster,/turf/unsimulated/floor{dir = 1; icon_state = "loadingarea"},/area/centcom/suppy) "hu" = (/obj/machinery/door/airlock/centcom{name = "Centcom"; opacity = 1; req_access_txt = "0"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/evac) "hv" = (/obj/machinery/door/airlock/shuttle{name = "Emergency Shuttle Cargo"},/turf/simulated/shuttle/floor,/area/space) "hw" = (/obj/machinery/status_display,/turf/simulated/shuttle/wall{icon_state = "swall14"; dir = 2},/area/space) @@ -376,6 +390,11 @@ "hz" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 8},/area/centcom/ferry) "hA" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows2"; dir = 8},/area/centcom/ferry) "hB" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 4},/area/centcom/ferry) +"hC" = (/obj/structure/closet/secure_closet/cargotech,/turf/unsimulated/floor{dir = 1; icon_state = "loadingarea"},/area/centcom/suppy) +"hD" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 1},/area/centcom/suppy) +"hE" = (/obj/machinery/door/airlock/centcom{name = "Supply Shuttle"; req_access_txt = "106"},/turf/unsimulated/floor{icon_state = "delivery"},/area/centcom/suppy) +"hF" = (/obj/machinery/computer/supplycomp,/turf/unsimulated/floor{dir = 8; heat_capacity = 1; icon_state = "warning"},/area/centcom/suppy) +"hG" = (/obj/structure/grille{color = "#008000"; density = 0; icon_state = "brokengrille"},/turf/unsimulated/floor/plating,/area/wizard_station) "hH" = (/turf/unsimulated/floor{name = "plating"},/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion (EAST)"; icon_state = "propulsion"; dir = 4},/turf/simulated/shuttle/wall{icon_state = "swall_f6"; dir = 2},/area/space) "hI" = (/turf/simulated/shuttle/floor,/turf/simulated/shuttle/wall/interior{icon_state = "swall_f9"},/area/space) "hJ" = (/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/space) @@ -445,7 +464,6 @@ "iX" = (/obj/structure/table/reinforced,/obj/item/weapon/clipboard,/turf/unsimulated/floor{icon_state = "green"; dir = 8},/area/centcom/evac) "iY" = (/obj/structure/stool/bed/chair/office/dark{dir = 1},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/evac) "iZ" = (/obj/structure/filingcabinet/filingcabinet,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/evac) -"ja" = (/obj/item/weapon/shard{color = "#008000"; icon_state = "small"},/obj/structure/grille{color = "#008000"; density = 0; icon_state = "brokengrille"},/turf/simulated/floor/plating/airless,/area/wizard_station) "jb" = (/turf/unsimulated/wall/fakeglass{color = "#008000"; dir = 8; icon_state = "fakewindows2"},/area/wizard_station) "jc" = (/turf/unsimulated/wall/fakeglass{color = "#008000"; dir = 4; icon_state = "fakewindows"},/area/wizard_station) "jd" = (/turf/unsimulated/wall/normal{tag = "icon-uranium2"; icon_state = "uranium2"},/area/wizard_station) @@ -524,10 +542,8 @@ "kM" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows2"; dir = 1},/area/syndicate_mothership) "kN" = (/turf/unsimulated/floor,/area/syndicate_mothership) "kO" = (/obj/machinery/door/poddoor/shutters{id = "nukeop_ready"; name = "shuttle dock"},/turf/unsimulated/floor,/area/syndicate_mothership) -"kQ" = (/turf/space,/area/tdome/tdomeobserve) "kR" = (/obj/effect/decal/remains/human,/obj/effect/decal/cleanable/blood,/turf/unsimulated/floor{tag = "icon-cultdamage6"; icon_state = "cultdamage6"},/area/wizard_station) "kS" = (/obj/effect/decal/cleanable/blood/splatter,/turf/unsimulated/floor{tag = "icon-cultdamage"; icon_state = "cultdamage"},/area/wizard_station) -"kT" = (/obj/structure/mirror{pixel_x = 28},/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "kU" = (/obj/machinery/suit_storage_unit/syndicate,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/space) "kV" = (/obj/effect/landmark{name = "Syndicate-Uplink"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/space) "kW" = (/turf/unsimulated/wall/fakeglass,/area/syndicate_mothership) @@ -557,10 +573,8 @@ "lz" = (/turf/unsimulated/floor{icon_state = "redbluefull"; dir = 2},/area/tdome/tdomeobserve) "lA" = (/obj/structure/stool/bed/chair,/obj/effect/landmark{name = "tdomeobserve"},/turf/unsimulated/floor{icon_state = "redbluefull"; dir = 2},/area/tdome/tdomeobserve) "lB" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion (EAST)"; icon_state = "propulsion"; dir = 4},/turf/space/transit,/area/wizard_station) -"lC" = (/obj/structure/shuttle/engine/heater{tag = "icon-heater (WEST)"; icon_state = "heater"; dir = 8},/turf/simulated/floor/plating/airless,/area/wizard_station) "lD" = (/obj/effect/decal/cleanable/blood/gibs/body,/turf/unsimulated/floor{icon_state = "floor"},/area/wizard_station) "lE" = (/turf/unsimulated/floor{icon_state = "floor"},/area/wizard_station) -"lF" = (/obj/machinery/door/poddoor/preopen,/obj/effect/decal/cleanable/blood/splatter,/turf/simulated/floor/plating/airless,/area/wizard_station) "lG" = (/turf/unsimulated/floor{tag = "icon-cultdamage"; icon_state = "cultdamage"},/area/wizard_station) "lH" = (/obj/effect/forcefield,/turf/unsimulated/floor{tag = "icon-cultdamage7"; icon_state = "cultdamage7"},/area/wizard_station) "lI" = (/obj/effect/forcefield,/turf/unsimulated/floor{tag = "icon-cultdamage5"; icon_state = "cultdamage5"},/area/wizard_station) @@ -613,7 +627,6 @@ "mF" = (/obj/structure/stool/bed/chair/wood/wings,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "mG" = (/obj/structure/table/wood,/obj/item/stack/medical/bruise_pack,/obj/item/stack/medical/ointment,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "mH" = (/obj/structure/table/wood,/obj/item/weapon/retractor,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) -"mI" = (/obj/structure/table/wood,/obj/item/clothing/suit/wizrobe/magusblue,/obj/item/clothing/head/wizard/magus,/obj/item/weapon/staff,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "mJ" = (/obj/structure/table/wood,/obj/item/clothing/suit/wizrobe/magusred,/obj/item/clothing/head/wizard/magus,/obj/item/weapon/staff,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "mK" = (/obj/structure/rack,/obj/item/clothing/head/helmet/space/hardsuit/wizard,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "mL" = (/obj/effect/decal/cleanable/blood/splatter,/obj/effect/decal/cleanable/blood/gibs/body,/turf/unsimulated/floor{tag = "icon-cultdamage"; icon_state = "cultdamage"},/area/wizard_station) @@ -651,14 +664,11 @@ "nt" = (/obj/machinery/recharger{pixel_y = 4},/obj/effect/landmark{name = "tdome1"},/turf/unsimulated/floor{name = "plating"},/area/tdome/tdome1) "nu" = (/turf/unsimulated/wall/fakeglass{color = "#008000"; dir = 1; icon_state = "fakewindows2"},/area/wizard_station) "nv" = (/obj/structure/bookcase,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) -"nw" = (/obj/structure/grille{color = "#008000"; density = 0; icon_state = "brokengrille"},/turf/simulated/floor/plating,/area/wizard_station) "nx" = (/obj/structure/cult/talisman{desc = "A altar dedicated to the Wizard's Federation"},/obj/item/weapon/kitchenknife/ritual,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "ny" = (/obj/item/clothing/shoes/sandal/marisa,/obj/item/clothing/suit/wizrobe/marisa,/obj/item/clothing/head/wizard/marisa,/obj/item/weapon/staff/broom,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "nz" = (/obj/effect/decal/cleanable/blood/splatter,/mob/living/simple_animal/hostile/creature{name = "Experiment 35b"},/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) -"nA" = (/obj/machinery/door/poddoor/preopen,/obj/effect/decal/cleanable/blood/splatter,/obj/effect/decal/cleanable/blood/gibs/body,/turf/simulated/floor/plating/airless,/area/wizard_station) "nB" = (/obj/effect/decal/cleanable/blood/splatter,/obj/effect/decal/remains/human,/turf/unsimulated/floor{icon_state = "floor"},/area/wizard_station) "nC" = (/obj/effect/decal/cleanable/blood/splatter,/obj/effect/decal/cleanable/blood/gibs/body,/turf/unsimulated/floor{icon_state = "floor"},/area/wizard_station) -"nD" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 4},/turf/simulated/floor/plating/airless,/area/wizard_station) "nE" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion"; dir = 8},/turf/space/transit,/area/wizard_station) "nF" = (/obj/machinery/sleeper{icon_state = "sleeper-open"; dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/space) "nG" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"; name = "Infirmary"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/space) @@ -668,7 +678,6 @@ "nK" = (/obj/machinery/flasher{id = "tdomeflash"; name = "Thunderdome Flash"},/turf/simulated/floor/bluegrid,/area/tdome/arena) "nL" = (/obj/machinery/camera{pixel_x = 12; pixel_y = -10; network = list("thunder"); c_tag = "Green Team"},/obj/effect/landmark{name = "tdome1"},/turf/unsimulated/floor{name = "plating"},/area/tdome/tdome1) "nM" = (/turf/unsimulated/wall/fakeglass{color = "#008000"},/area/wizard_station) -"nN" = (/obj/item/weapon/shard{color = "#008000"; icon_state = "medium"},/obj/structure/grille{color = "#008000"; density = 0; icon_state = "brokengrille"},/turf/simulated/floor/plating,/area/wizard_station) "nO" = (/obj/effect/landmark/start{name = "wizard"},/turf/unsimulated/floor{tag = "icon-cultdamage5"; icon_state = "cultdamage5"},/area/wizard_station) "nP" = (/obj/effect/decal/remains/human,/obj/effect/decal/cleanable/blood/splatter,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "nQ" = (/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/turf/simulated/shuttle/wall{icon_state = "swall_f5"; dir = 2},/area/wizard_station) @@ -738,7 +747,6 @@ "ph" = (/turf/unsimulated/wall/fakedoor{name = "Squad 2 Pod"},/area/wizard_station) "pi" = (/turf/unsimulated/wall/normal{tag = "icon-uranium13"; icon_state = "uranium13"},/area/wizard_station) "pj" = (/turf/simulated/shuttle/wall,/area/wizard_station) -"pk" = (/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/plating,/area/wizard_station) "pl" = (/obj/structure/table/wood,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "pm" = (/obj/structure/table/wood,/obj/item/weapon/gun/magic/wand{desc = "Used in emergency's to reignite magma engines. This one appears spent."; name = "wand of emergency engine ignition"},/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "pn" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_l"},/turf/space,/area/wizard_station) @@ -820,7 +828,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababbWcicicicicibWaDaDaDaDaDaDaDaDaDaDaDaDaDaDaDbWcjcjcjcjcjbWabab aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababbWbWbWbWbWbWbWabababababababababababababababbWbWbWbWbWbWbWabab aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaclaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab @@ -831,7 +839,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacacacacacacacacacckacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaclaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab @@ -910,72 +918,72 @@ abababababababababababababababababababababababababababababababababababababababab ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcBdrcOdrcBcOdfdncOdfdsabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcBdrcOdrcUcOdfdncOdfcGabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcBdrcOcOdtcOcOcOcOcOcFduababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcBdrcOdrdvcOcVcVcVcVdvababababababababababababababababababababababababababababababababababababdwdwdwdwdwdwdwdwdwababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcBdrcOdrcBcOdxdydzcNcBababababababababababababababababababababababababababababababababababababdwdAdBdBdBdBdBdCdwababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcWdDdDcYdEdFcIcYdDdDcXababababababababababababababababababababababababababababababababababababdwdGdHdHdHdHdHdGdwababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcWcJdIdfcOdJdKcDcXabababababababababababababababababababababababababababababababababababababdwdGdHdHdHdHdHdGdwababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcBdzcVdLcVdIcBababababababababababababababababababababababababababababababababababababababdwdGdHdHdHdHdHdMdNababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcBdOdPdQdRdScBababababababababababababababababababababababababababababababababababababababdwdGdHdHdHdHdHdTdwababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcWdsdsdsdsdscXababababababababababababababababababababababababababababababababababababababdwdGdHdHdHdHdUdGdwababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdwdGdHdHdHdHdHdVdwababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdwdGdHdHdHdHdHdWdNababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdwdGdHdHdHdHdHdGdwababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdwdXeBdHdHdHeGeadwababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdwebecedededeceedwababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdwdwefegegegehdwdwababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdwdwdwdwdwdwdwabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcBdrcOdrdvcOcVcVcVcVdvabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcBdrcOdrcBcOdxdydzcNcBabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcWdDdDcYdEdFcIcYdDdDcXabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcWcJdIdfcOdJdKcDcXababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcBdzcVdLcVdIcBabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcBdOdPdQdRdScBabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcWdsdsdsdsdscXabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababeieiejeieiekekekekekekekekababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababeieielemeneiekeoeoeoeoeoeoekababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababepepepepepepepepepepepepepepepepepabababeieqeremeseteieoeoeoeoeoeoekababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababepeuepeuepeuepeuepeuepeuepeuepeuepabababeievemememeweieoeoeoeoeoeoekababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababepepepepepepepepepepepepepepepepepabababeiexemememeyeieoeoeoeoeoeoekababababdAezezezezezdCabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababepeuepeuepeuepeuepeuepeuepeuepeuepabababeiexemememeyeieoekekeAekekekabababdAdZeCeDeEeDeFdYdCababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababepepepepepepepepepepepepepepepepepabababeieieHeieieIeieoekeJeJeJeKekabababdGeLeMdHdHdHeNeOdGababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababeiePeQeRePeieoekeJeJeJeJekabababdGeSeTeUeVdHeNeWdGababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababeieXeYeZePeieoekeJfafbfcekababdAfddBdBfedBfffgdBfddCabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhfhfhfhfhababeiePeQfifjeieoekfkflfmfnekababdGfofofoezfpdHfqfrfsezabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhftfufvfhaDeieifweieieieieiekeJeJeJeJfxfyfzdGfAfBfBfCdHdHdHdHfqdGabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhfEfFfFfhfGfHemfIfIfIfIfHfJekeJeJeJeJfKfLfKfMfBfNfNezfOfPfQdHfqezabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhfhfhfhfhfhfhfhfhfhfhfhfhfhfhfhfUfhfhfJfVemfWfXfYfIfVfJekfxfzfZfxfyfyfzdXdBdBdBgafQfQfQdHfqdGabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhgbgbgbgbgbgbgbgbgbgbgbgbgbgcgdfSgefhfJfVgfemememggfVfJekghgigigjfKfLfKgkdHgldHdHdHdHdHdHgmdGabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhgbhHdBdBgqdBdBdBezdBdBgrgsgtgdgugefhfJfVexemememeygvfJekghgigigjfxfyfzdGfPdHgwgxdHgwgxdHgydGabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzababababababababababababababababababababababababababababfhhHhIeNgDgEgEgEgEgEgEgEgqgFgGgdgugefhfJgvexemememeseieQekgHgigigjekababezfPdHgwgxdHgwgxdHgyezabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIgIgIgIgIgJgIgIgIgKgLgIgIgIgKgIgIgIgIgIgIgKgIgIgzababababababababababababababababababababababababababababfhgodHdHdHdHdHdHdHdHdHdHgTgUgVgdgugWfhgAfherememememememgigigigigjgXababezfPdHgwgxdHgwgxdHgyezabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgJgIgIgIgIgIgIgIgIgIgIgIgKgIgIgIgIgIgKgIgIgIgIgIgzababababababababababababababababababababababababababababfhhQeBgMgMeDeDeDeDeDeDeDgqgFhagdgufShRfSfSemememememememgigigigigjekababezfPdHgwgxdHgwgxdHgyezabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIgIgIhcgIgIgIgIgIgJgIgIgLgKgIgIgKgIgIgKgLgIgKgIgzababababababababababababababababababababababababababababfhgbhQdBdBgqdBdBdBezdBdBhigsgtgdguhjfhgAfhgfemememggeieQekhkgigigjfxfyfzdGfPdHgwgxdHgwgxdHgydGabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgJgIgIgKgLgIgIgKgIgLgzababababababababababababababababababababababababababababfhgbgbgbgbgbgbgbgbgbgbgbgbgbhmgdfSgefhfJfHevemememewfHfJekghgigigjfKfLfKhndHhodHdHdHdHdHdHgmdGabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgJgIgIgIgIgIgLgIgKgLgIgKgIgzababababababababababababababababababababababababababababfhfhfhfhfhfhfhhzhAhAhBfhfhfhfhfhhSfhfhfJfVevemememewfVfJekfxfzhufxfyfyfzdXdBdBhvdBhwezhxezezeaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIgIhyhyhyhyhyhyhygIgIgIgIgIgIgIgKgIgIhcgLgIgIgIgzabababababababababababababababababababababababababababababababfhhUhVhUhUhUhUhUhUhWhYhXhUhUhUfhfJgvevemememewgvfJekgigigigjfKfLfKhnhJhJhJhKdGfrfqfqhLezabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIhMhNhOhOhOhOhOhNhPgIgIgIgIhcgIhygJhygJgIgKgIgKgzabababababababababababababababababababababababababababababababfhhUhUhUhUfDhUfDhUhUhUhUhUhUisfhhZhZiaibicidiehZhZekgigigigjfxfyfzdGhJhJhJhJdGfqfqfqifdGabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIhNigihiiijikililhNimgIgIhygzgziniogzgzhyipiqhygzabababababababababababababababababababababababababababababababfhiJhUhUiKiKiKiKfRhUhUhUhUhUiLfhitiuiviwixiyiviuiuekgiiziAiBekababdGiCiCiDiDdGfrfqfqhLezabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIhNiEihihiFihihihhNimgIiGgzgziHiIiIiHgzgzgzgzgzgzgzgzabababababababababababababababababababababababababababababfhiMhUfTiKiNiOiKhUhUhUhUhUhUiPfhiuiUiViwixiyiViWiuekgiiXiYiZekababebfeedededededededfeeeabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajajbjcjdaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIhNjeihihihjfihjghNimhciGgzjhjijijijijjjkjljmjnjojpgzabababababababababababababababababababababababababababababfhiQhUhUiKiKiKiKfRhUhUhUhUhUiRfhjriujriwixiyjriujrekgigigigiekabababebegegegegegegegeeababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaajsaajtjujvjwjxaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIjyhNhNhNjzhNhNhNjAgIgIjBgzjCjijDjDjEjijijijFjGjGjGgzabababababababababababababababababababababababababababababfhiShUhUgnhUgnhUhUhUhUhUhUhUiTfhjPiuiuiwixiyiuiujQekjRjSjSjTekababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaajsjUjVjWjvjXjYaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIgIgIhNjZihkahNkbhyhyhykcgzjijDkdkejDjikfkgjmkhkigzgzabababababababababababababababababababababababababababababfhjqhUhUhUhUhUhUhUjHjJjIgpiTjLfhklkmkmiwixiyknknkoekekkpekekekababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaajYkqlGjXksktjYaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIgIgIhNkuihkvhNkwkxkxkxiogzjijDkykzjDjikfkAgzgzgzgzababababababababababababababababababababababababababababababfhfhfhfhfhgBfhfhfhfhfhfhfhfhfhfhhZhZhZhZixhZhZhZhZekeoeoeoeoekababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaajwjxkIkJkIkKkLaaaaaaaaaaaaaaaaaaaaababababababgzgIgIhMhNhNhNhNhNkuihkvhNkMkNkNkNkNkOjijijijijijikfkAgzgzgzgzabababababababababababababababababababababababababababababababababababababababababababababababababhZixhZkQkQkQeoeoeoeoeoekababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaajsjskLkRkSkTjwaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIhNkUihihkVhNkuihkvhNkWkXinkxiogzkYjDjDjDjijikfkZgzlalbgzgzabababababababababababababababababababababababababababababababababababababababababkQhZhZhZhZhZhZhZichZhZhZhZhZhZhZhZekekababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdwdwdwdwdwdwdwdwdwababababababababababababepepepepepepepepepababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdwdAdBdBdBdBdBdCdwababababababababababababepeuepeuepeuepeuepababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdwdGdHdHdHdHdHdGdwdwdwdwdwdwdwababababababepepepepepepepepepababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdwdGdHdHdHdHdHdGdwhrhChthChrdwababababababepeuepeuepeuepeuepababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdwdGdHdHdHdHdHdMhqfvetetetetdwababababababepepepepepepepepepababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdwdGdHdHdHdHdHdThEfvetetetetdNabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdwdGdHdHdHdHdUdGhqhFetetetetdwababababababepepepepepepepepepababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdwdGdHdHdHdHdHdVhEfvetetetetdwababababababepeuepeuepeuepeuepababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdwdGdHdHdHdHdHdWhDfvetetetetdwdwdwdwdwababepepepepepepepepepababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdwdGdHdHdHdHdHdGfwfvetetetetdweIeIeIdwababepeuepeuepeuepeuepababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdwdXeBdHdHdHeGeafEfvetetetetfGeIeIeIdwababepepepepepepepepepababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdwebecedededeceedweHeyexeteYdweIeIeIdwababababababababababababababdAezezezezezdCababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdwdwefegegegehdwdwdwdwdwdwfudwdwdwdwdwababababekekeAekekekabababdAdZeCeDeEeDeFdYdCabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdwdwdwdwdwdwdweifXfXfXfHhlfHfXfXfXeiababababekeJeJeJeKekabababdGeLeMdHdHdHeNeOdGabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhfhfhfhfheifXhpfXfVemfVfXhpfXeiababababekeJeJeJeJekabababdGeSeTeUeVdHeNeWdGabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhftfFfWfIfhfXfXfXgvemgvfXfXfXeiababababekeJfafbfcekababdAfddBdBfedBfffgdBfddCababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhfYhhfFfFfheQeieQeiemeieQeieQeiababababekfkflfmfnekababdGfofofoezfpdHfqfrfsezababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhfFfFfFelfhfJfHgfemememggeQfJeiababababekeJeJeJeJfxfyfzdGfAfBfBfCdHdHdHdHfqdGababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhfhfhfhfhfhfhfhfhfhfhfhfhfhfhfhfUfhfhfJfVevemememeseieQeieieieieiekeJeJeJeJfKfLfKfMfBfNfNezfOfPfQdHfqezababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhgbgbgbgbgbgbgbgbgbgbgbgbgbgcgdfSgefhfJfVevememememememejePePePeiekfxfzfZfxfyfyfzdXdBdBdBgafQfQfQdHfqdGababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhgbhHdBdBgqdBdBdBezdBdBgrgsgtgdgugefhfJfVevemememggeieQeieiePfieiekghgigigjfKfLfKgkdHgldHdHdHdHdHdHgmdGababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzababababababababababababababababababababababababababababfhhHhIeNgDgEgEgEgEgEgEgEgqgFgGgdgugefhfJgvevemememeseQfJeieReZfjeiekghgigigjfxfyfzdGfPdHgwgxdHgwgxdHgydGababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIgIgIgIgIgJgIgIgIgKgLgIgIgIgKgIgIgIgIgIgIgKgIgIgzababababababababababababababababababababababababababababfhgodHdHdHdHdHdHdHdHdHdHgTgUgVgdgugWfhgAfherememememeieQeieQeqeQeiekgHgigigjekababezfPdHgwgxdHgwgxdHgyezababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgJgIgIgIgIgIgIgIgIgIgIgIgKgIgIgIgIgIgKgIgIgIgIgIgzababababababababababababababababababababababababababababfhhQeBgMgMeDeDeDeDeDeDeDgqgFhagdgufShRfSfSemememememememeoePeXePengigigigigjgXababezfPdHgwgxdHgwgxdHgyezababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIgIgIhcgIgIgIgIgIgJgIgIgLgKgIgIgKgIgIgKgLgIgKgIgzababababababababababababababababababababababababababababfhgbhQdBdBgqdBdBdBezdBdBhigsgtgdguhjfhgAfhgfemememggeieQeieieieieiekhkgigigjekababezfPdHgwgxdHgwgxdHgyezababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgJgIgIgKgLgIgIgKgIgLgzababababababababababababababababababababababababababababfhgbgbgbgbgbgbgbgbgbgbgbgbgbhmgdfSgefhfJfHevemememewfHfJeiababababekghgigigjfxfyfzdGfPdHgwgxdHgwgxdHgydGababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgJgIgIgIgIgIgLgIgKgLgIgKgIgzababababababababababababababababababababababababababababfhfhfhfhfhfhfhhzhAhAhBfhfhfhfhfhhSfhfhfJfVevemememewfVfJeiababababekghgigigjfKfLfKhndHhodHdHdHdHdHdHgmdGababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIgIhyhyhyhyhyhyhygIgIgIgIgIgIgIgKgIgIhcgLgIgIgIgzabababababababababababababababababababababababababababababababfhhUhVhUhUhUhUhUhUhWhYhXhUhUhUfhfJgvevemememewgvfJeiababababekfxfzhufxfyfyfzdXdBdBhvdBhwezhxezezeaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIhMhNhOhOhOhOhOhNhPgIgIgIgIhcgIhygJhygJgIgKgIgKgzabababababababababababababababababababababababababababababababfhhUhUhUhUfDhUfDhUhUhUhUhUhUisfhhZhZiaibicidiehZhZhZababababekgigigigjfKfLfKhnhJhJhJhKdGfrfqfqhLezababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIhNigihiiijikililhNimgIgIhygzgziniogzgzhyipiqhygzabababababababababababababababababababababababababababababababfhiJhUhUiKiKiKiKfRhUhUhUhUhUiLfhitiuiviwixiyiviuiuhZababababekgigigigjfxfyfzdGhJhJhJhJdGfqfqfqifdGababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIhNiEihihiFihihihhNimgIiGgzgziHiIiIiHgzgzgzgzgzgzgzgzabababababababababababababababababababababababababababababfhiMhUfTiKiNiOiKhUhUhUhUhUhUiPfhiuiUiViwixiyiViWiuhZababababekgiiziAiBekababdGiCiCiDiDdGfrfqfqhLezababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagSjbjcjdaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIhNjeihihihjfihjghNimhciGgzjhjijijijijjjkjljmjnjojpgzabababababababababababababababababababababababababababababfhiQhUhUiKiKiKiKfRhUhUhUhUhUiRfhjriujriwixiyjriujrhZababababekgiiXiYiZekababebfeedededededededfeeeababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaajsaajtjujvjwjxaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIjyhNhNhNjzhNhNhNjAgIgIjBgzjCjijDjDjEjijijijFjGjGjGgzabababababababababababababababababababababababababababababfhiShUhUgnhUgnhUhUhUhUhUhUhUiTfhjPiuiuiwixiyiuiujQhZababababekgigigigiekabababebegegegegegegegeeabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaajsjUjVjWjvjXjYaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIgIgIhNjZihkahNkbhyhyhykcgzjijDkdkejDjikfkgjmkhkigzgzabababababababababababababababababababababababababababababfhjqhUhUhUhUhUhUhUjHjJjIgpiTjLfhklkmkmiwixiyknknkohZababababekjRjSjSjTekabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaajYkqlGjXksktjYaaaaaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIgIgIhNkuihkvhNkwkxkxkxiogzjijDkykzjDjikfkAgzgzgzgzababababababababababababababababababababababababababababababfhfhfhfhfhgBfhfhfhfhfhfhfhfhfhfhhZhZhZhZixhZhZhZhZhZababababekekkpekekekabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaajwjxkIkJkIkKkLaaaaaaaaaaaaaaaaaaaaababababababgzgIgIhMhNhNhNhNhNkuihkvhNkMkNkNkNkNkOjijijijijijikfkAgzgzgzgzabababababababababababababababababababababababababababababababababababababababababababababababababhZixhZabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaajsjskLkRkSjvjwaaaaaaaaaaaaaaaaaaaaaaababababababgzgIgIhNkUihihkVhNkuihkvhNkWkXinkxiogzkYjDjDjDjijikfkZgzlalbgzgzabababababababababababababababababababababababababababababababababababababababababhZhZhZhZhZhZhZhZichZhZhZhZhZhZhZhZababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaaaaaalhliljlklllmjvlnjsaaaaaaaaaaaaaaaaaaaaababababababgzgIgIhNkUihlolphNkuihkvhNhNnrlrhPlsgzltlulvlulujijijilwlxlxlygzabababababababababababababababababababababababababababababababababababababababababhZlzlAlAlAlAlAlzlzlzlAlAlAlAlAlzhZababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaalBlClDlElFlljvlGlHlIjsjsaaaaaaaaaaaaaaaaababababababgzlJgIhNkUihihlKhNihihihhNihihihhNjBgzlLlMlLlLlNjijijigzlOlPlygzababababababababababababababababababababababababababababababababababababababababablQlzlzlzlRlzlzlzlzlzlzlzlRlzlzlzlQababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaalBgYlDlEgZlljvlGlHlIjsjsaaaaaaaaaaaaaaaaababababababgzlJgIhNkUihihlKhNihihihhNihihihhNjBgzlLlMlLlLlNjijijigzlOlPlygzababababababababababababababababababababababababababababababababababababababababablQlzlzlzlRlzlzlzlzlzlzlzlRlzlzlzlQababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaajsaaljlSlSlTlljvlUlGlIaalVlWaaaaaaaaaaaaaaababababababgzgIgIhNkUihihihlXihihihlYihihihhNiGgzgzkglZmambgzmcjigzgzgzgzgzabababababababababababababababababababababababababababababababababababababababababhZlzlAlAlAlAlAlzlzlzlAlAlAlAlAlzhZababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaalnjsaaaajsmdmejWmfjWlnjsjsaaaaaaaaaaaaaaaaababababababgzgIgIhNkUihihihmgihihihmhihihmihNmjmjlsgzgzgzgzgzgNgCmlmmmnmogzabababababababababababababababababababababababababababababababababababababababababhZidmpmpmpmpmpmpmpmpmpmpmpmpmpibhZababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaakKmqmrmsmtmumtmtmqmvmsmtmtmumtmtaajsaaaaaaaaaaababababababgzgIhMhNhNhNhNhNhNmwihihhNhNhNhNhNhNhPmxmxmxmylsgzmzmzmzmzmzmzgzabababababababababababababababababababababababababababababababababmBmBmBmBmBmBmBmBmBmCmDmDmDmDmDmDmDmDmDmDmDmDmDmCmBmBmBmBmBmBmBmBmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaamEmFjvjvmFmEmGmHjvjvjvmImJmEmKmLlnmMjsjsaaaaaaababababababgzgIhNmNmNmOmPmQhNihihihhNmRmSmTmUmVhNgIgJgIgIgLjmmzmzmzmzmzmWgzabababababababababababababababababababababababababababababababababmBmZnanbnbnbnbnbncndmDmDmDmDmDmDmDmDmDmDmDmDmDnencnfnfnfnfnfnangmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaamEmFjvjvmFmEmGmHjvjvjvhbmJmEmKmLlnmMjsjsaaaaaaababababababgzgIhNmNmNmOmPmQhNihihihhNmRmSmTmUmVhNgIgJgIgIgLjmmzmzmzmzmzmWgzabababababababababababababababababababababababababababababababababmBmZnanbnbnbnbnbncndmDmDmDmDmDmDmDmDmDmDmDmDmDnencnfnfnfnfnfnangmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaanhnijvjvninhmMmMjvjvjvjvnjnhnknllSlSnmaaaaaaaaababababababgzgIhNihihihloihnnihihihnoihloihlonphNgIhcgKgJhcgznqnqnqnqnqlqgzabababababababababababababababababababababababababababababababababmBmZnanbnsnbnsnbncndmDmDmDmDmDmDmDmDmDmDmDmDmDnencnfntnfntnfnangmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaanunvjvlGjvnwlUlGjvnxjvjvnynunznAnBnCnDnEaaaaaaababababababgzgIhNnFihihihihnGihihihnHihihihihihhNgIgIgIgKiGgzgzgzgzgzgzgzgzabababababababababababababababababababababababababababababababababmBmZnanbnbnInbnbncndmDmDmDmDmDnJnKnJmDmDmDmDmDnencnfnfnLnfnfnangmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaanMnijvjWlUnNjWjvjvnOjvjvjvnMnPnQnmnRlhaaaaaaaaababababababgzgIhNnFihihnSnThNnUnVnUhNnWnXihihihhNgIgKgIhciGgzababababababababababababababababababababababababababababababababababababababababmBmZnanbnbnbnbnbncndmDmDmDmDmDnJnYnJmDmDmDmDmDnencnfnfnfnfnfnangmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaanunvjvlGjvhGlUlGjvnxjvjvnynunzhdnBnChenEaaaaaaababababababgzgIhNnFihihihihnGihihihnHihihihihihhNgIgIgIgKiGgzgzgzgzgzgzgzgzabababababababababababababababababababababababababababababababababmBmZnanbnbnInbnbncndmDmDmDmDmDnJnKnJmDmDmDmDmDnencnfnfnLnfnfnangmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaanMnijvjWlUhfjWjvjvnOjvjvjvnMnPnQnmnRlhaaaaaaaaababababababgzgIhNnFihihnSnThNnUnVnUhNnWnXihihihhNgIgKgIhciGgzababababababababababababababababababababababababababababababababababababababababmBmZnanbnbnbnbnbncndmDmDmDmDmDnJnYnJmDmDmDmDmDnencnfnfnfnfnfnangmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaajdnZjvjvnZjdoajvlGjWjvjvoajdobocodoeaaaaaaaaaaababababababgzgIhNihihgOhNhNhNofogihhNhNhNihihihhNgIgIgJgIiGgzababababababababababababababababababababababababababababababababababababababababmBmZnanbnsnbnsnbncndmDmDmDmDmDmDmDmDmDmDmDmDmDnencnfntnfntnfnangmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaajwmqojmsmtokmtmqkIolkImsmtokmtmqjsjsjsaaaaaaaaababababababgzgIhNgQgPgRhNgIhNopopophNgIhNiloqorhNgIgIgIgIiGgzababababababababababababababababababababababababababababababababababababababababmBmZnanbnbnbnbnbncndmDmDmDmDmDmDmDmDmDmDmDmDmDnencnfnfnfnfnfnangmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaamdlGaajsaajsoslmmdaaaajsaaaaaaaajsaaaaaaaaababababababgzgIhNopopophNgIjyotegoujAgIhNopopophNgIgIgIgIiGgzababababababababababababababababababababababababababababababababababababababababmBmBmBovovovovovmBmCmDmDmDmDmDmDmDmDmDmDmDmDmDmCmBovovovovovmBmBmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaajsjsaaowlGaaoxoymdjsaalUaaaaaaaaaaaaaaaaaaababababababgzgIjyotegoujAgIgIgIgIgIgIgIjyotegoujAgIgIgIgIiGgzababababababababababababababababababababababababababababababababababababababababababmBozozozozozmBoAoBoBoBoBoBoBoBoBoBoBoBoBoBoCmBoDoDoDoDoDmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaaaaaaaajsjsaaoElGoFaaaaaajsaaaaaaaaaaaaaaaaababababababgzgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIgIiGgzababababababababababababababababababababababababababababababababababababababababababmBmBmBmBmBmBmBoGoHoHoHoHoHoIoJoKoHoHoHoHoHoGmBmBmBmBmBmBmBababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaajsmumqoLmsmujsaajsjsaaaaaaaaaaaaaaababababababgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzgzababababababababababababababababababababababababababababababababababababababababababababababababoMoGoGoGoNoGoOoOoOoOoOoGoNoGoGoGoMababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaamEoPoQoRmEownllFoSoTjsaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababoMoMoUoMoMoMoMoVoWoXoMoMoMoMoUoMoMababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaamEoPoQoRmEownlgZoSoTjsaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababoMoMoUoMoMoMoMoVoWoXoMoMoMoMoUoMoMababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaakIoYoZpakIpbpclEpdjvjYaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababoMoMoMoMoMababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaaaaaaaalmjsjdpepfpgjdjWphlEpdaajsaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaajsmupimqkImspimupjpkpdaajsaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababhshshshshshshshshshshshshshshshshshshsababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaajsmupimqkImspimupjhgpdaajsaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababhshshshshshshshshshshshshshshshshshshsababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaaaaaaaajsmEjvplpmpljvmEaapnaaaajsaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababhspopppqprprpppsptpupvpwpxpypxpxpxpzhsababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaaaaaajslGpAjvjvjvjvjvpAaaaaaaaalGaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababhspopppppppppppBpwpwpwpCpxpxpxpDpxpxhsababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababaaaaaaaaaaaaaaaaaajsjslmjvjdpEjvjvjvpEjdaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababhspopppFpopGpHpIpwpwpwpwpxpxpJpxpKpyhsababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab diff --git a/code/LINDA/LINDA_fire.dm b/code/LINDA/LINDA_fire.dm index 082608ae120..a8e338695bf 100644 --- a/code/LINDA/LINDA_fire.dm +++ b/code/LINDA/LINDA_fire.dm @@ -61,7 +61,7 @@ /obj/effect/hotspot/proc/perform_exposure() var/turf/simulated/location = loc - if(!istype(location)) return 0 + if(!istype(location) || !(location.air)) return 0 if(volume > CELL_VOLUME*0.95) bypassing = 1 else bypassing = 0 @@ -101,7 +101,7 @@ Kill() return - if(location.air.toxins < 0.5 || location.air.oxygen < 0.5) + if(!(location.air) || location.air.toxins < 0.5 || location.air.oxygen < 0.5) Kill() return diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 901e45b3a68..9f46ab5c791 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -44,12 +44,19 @@ #define GRAB_UPGRADING 4 #define GRAB_KILL 5 + +//Hostile Mob Stances #define HOSTILE_STANCE_IDLE 1 //#define HOSTILE_STANCE_ALERT 2 //Was only used by bears #define HOSTILE_STANCE_ATTACK 3 #define HOSTILE_STANCE_ATTACKING 4 //#define HOSTILE_STANCE_TIRED 5 //Was also only used by bears +//Hostile Mob AI Status +#define AI_ON 1 +#define AI_SLEEP 2 +#define AI_OFF 3 + //Embedded objects #define EMBEDDED_PAIN_CHANCE 15 //Chance for embedded objects to cause pain (damage user) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 45de5f82b5d..60a0f565f24 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -1,5 +1,26 @@ #define MIDNIGHT_ROLLOVER 864000 //number of deciseconds in a day +#define JANUARY 1 +#define FEBRUARY 2 +#define MARCH 3 +#define APRIL 4 +#define MAY 5 +#define JUNE 6 +#define JULY 7 +#define AUGUST 8 +#define SEPTEMBER 9 +#define OCTOBER 10 +#define NOVEMBER 11 +#define DECEMBER 12 + +//Select holiday names -- If you test for a holiday in the code, make the holiday's name a define and test for that instead +#define NEW_YEAR "New Year" +#define VALENTINES "Valentine's Day" +#define APRIL_FOOLS "April Fool's Day" +#define EASTER "Easter" +#define HALLOWEEN "Halloween" +#define CHRISTMAS "Christmas" +#define FRIDAY_13TH "Friday the 13th" //Human Overlays Indexes///////// #define SPECIES_LAYER 26 // mutantrace colors... these are on a seperate layer in order to prvent @@ -75,6 +96,11 @@ #define NO_DEXTERY 1 //if other mobs (monkeys, aliens, etc) can use this //used by canUseTopic() +//Sizes of mobs, used by mob/living/var/mob_size +#define MOB_SIZE_SMALL 1 +#define MOB_SIZE_HUMAN 2 +#define MOB_SIZE_LARGE 3 + //singularity defines #define STAGE_ONE 1 #define STAGE_TWO 3 diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index d6c41b34888..976f1e016e7 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -7,8 +7,9 @@ #define MEMBER_PUBLIC 16 #define INTENT_STYLE 32 #define MIDROUND_ANTAG 64 +#define SOUND_INSTRUMENTS 128 -#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG) +#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS) //Chat toggles #define CHAT_OOC 1 diff --git a/code/__DEFINES/say.dm b/code/__DEFINES/say.dm new file mode 100644 index 00000000000..ff5062598ff --- /dev/null +++ b/code/__DEFINES/say.dm @@ -0,0 +1,29 @@ +/* + Defines for use in saycode and text formatting. + Currently contains speech spans and message modes +*/ + +//Message modes. Each one defines a radio channel, more or less. +#define MODE_HEADSET "headset" +#define MODE_ROBOT "robot" +#define MODE_R_HAND "right hand" +#define MODE_L_HAND "left hand" +#define MODE_INTERCOM "intercom" +#define MODE_BINARY "binary" +#define MODE_WHISPER "whisper" +#define MODE_SECURE_HEADSET "secure headset" +#define MODE_DEPARTMENT "department" +#define MODE_ALIEN "alientalk" +#define MODE_HOLOPAD "holopad" +#define MODE_CHANGELING "changeling" + +//Spans. Robot speech, italics, etc. Applied in compose_message(). +#define SPAN_ROBOT "robot" +#define SPAN_YELL "yell" +#define SPAN_ITALICS "italics" +#define SPAN_SANS "sans" + +//bitflag #defines for return value of the radio() proc. +#define ITALICS 1 +#define REDUCE_RANGE 2 +#define NOPASS 4 diff --git a/code/__HELPERS/names.dm b/code/__HELPERS/names.dm index d0b8e36896b..50f981a3b04 100644 --- a/code/__HELPERS/names.dm +++ b/code/__HELPERS/names.dm @@ -70,23 +70,16 @@ var/religion_name = null new_station_name = name + " " // Prefix - switch(SSevent.holiday) - //get normal name - if(null,"",0) - name = pick("", "Stanford", "Dorf", "Alium", "Prefix", "Clowning", "Aegis", "Ishimura", "Scaredy", "Death-World", "Mime", "Honk", "Rogue", "MacRagge", "Ultrameens", "Safety", "Paranoia", "Explosive", "Neckbear", "Donk", "Muppet", "North", "West", "East", "South", "Slant-ways", "Widdershins", "Rimward", "Expensive", "Procreatory", "Imperial", "Unidentified", "Immoral", "Carp", "Ork", "Pete", "Control", "Nettle", "Aspie", "Class", "Crab", "Fist","Corrogated","Skeleton","Race", "Fatguy", "Gentleman", "Capitalist", "Communist", "Bear", "Beard", "Derp", "Space", "Spess", "Star", "Moon", "System", "Mining", "Neckbeard", "Research", "Supply", "Military", "Orbital", "Battle", "Science", "Asteroid", "Home", "Production", "Transport", "Delivery", "Extraplanetary", "Orbital", "Correctional", "Robot", "Hats", "Pizza") - if(name) - new_station_name += name + " " - - //For special days like christmas, easter, new-years etc ~Carn - if("Friday the 13th") - name = pick("Mike","Friday","Evil","Myers","Murder","Deathly","Stabby") - new_station_name += name + " " + for(var/holiday_name in SSevent.holidays) + if(holiday_name == "Friday the 13th") random = 13 - else - //get the first word of the Holiday and use that - var/i = findtext(SSevent.holiday," ",1,0) - name = copytext(SSevent.holiday,1,i) - new_station_name += name + " " + var/datum/holiday/holiday = SSevent.holidays[holiday_name] + name = holiday.getStationPrefix() + //get normal name + if(!name) + name = pick("", "Stanford", "Dorf", "Alium", "Prefix", "Clowning", "Aegis", "Ishimura", "Scaredy", "Death-World", "Mime", "Honk", "Rogue", "MacRagge", "Ultrameens", "Safety", "Paranoia", "Explosive", "Neckbear", "Donk", "Muppet", "North", "West", "East", "South", "Slant-ways", "Widdershins", "Rimward", "Expensive", "Procreatory", "Imperial", "Unidentified", "Immoral", "Carp", "Ork", "Pete", "Control", "Nettle", "Aspie", "Class", "Crab", "Fist","Corrogated","Skeleton","Race", "Fatguy", "Gentleman", "Capitalist", "Communist", "Bear", "Beard", "Derp", "Space", "Spess", "Star", "Moon", "System", "Mining", "Neckbeard", "Research", "Supply", "Military", "Orbital", "Battle", "Science", "Asteroid", "Home", "Production", "Transport", "Delivery", "Extraplanetary", "Orbital", "Correctional", "Robot", "Hats", "Pizza") + if(name) + new_station_name += name + " " // Suffix name = pick("Station", "Fortress", "Frontier", "Suffix", "Death-trap", "Space-hulk", "Lab", "Hazard","Spess Junk", "Fishery", "No-Moon", "Tomb", "Crypt", "Hut", "Monkey", "Bomb", "Trade Post", "Fortress", "Village", "Town", "City", "Edition", "Hive", "Complex", "Base", "Facility", "Depot", "Outpost", "Installation", "Drydock", "Observatory", "Array", "Relay", "Monitor", "Platform", "Construct", "Hangar", "Prison", "Center", "Port", "Waystation", "Factory", "Waypoint", "Stopover", "Hub", "HQ", "Office", "Object", "Fortification", "Colony", "Planet-Cracker", "Roost", "Fat Camp") diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index f3b61f94ba4..4e997ed0a10 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -506,7 +506,7 @@ Turf and target are seperate in case you want to teleport some distance from a t moblist.Add(M) for(var/mob/living/carbon/monkey/M in sortmob) moblist.Add(M) - for(var/mob/living/carbon/slime/M in sortmob) + for(var/mob/living/simple_animal/slime/M in sortmob) moblist.Add(M) for(var/mob/living/simple_animal/M in sortmob) moblist.Add(M) @@ -798,7 +798,7 @@ Turf and target are seperate in case you want to teleport some distance from a t sleep(delayfraction) - if(!user || user.incapacitated() || !(user.loc == T)) + if(!user || user.stat || user.weakened || user.stunned || !(user.loc == T)) return 0 if(needhand) //Sometimes you don't want the user to have to keep their active hand @@ -1267,7 +1267,38 @@ Turf and target are seperate in case you want to teleport some distance from a t var/turf/T = locate(final_x, final_y, AM.z) if(T) return T + +//Finds the distance between two atoms, in pixels +/proc/getPixelDistance(var/atom/A, var/atom/B) + if(!istype(A)||!istype(B)) + return 0 + + var/_x1 = A.x + var/_x2 = B.x + var/_y1 = A.y + var/_y2 = B.y + + //Ensure _x1 is bigger, simplicity + if(_x2 > _x1) + var/tx = _x1 + _x1 = _x2 + _x2 = tx + + //Ensure _y1 is bigger, simplicity + if(_y2 > _y1) + var/ty = _y1 + _y1 = _y2 + _y2 = ty + + //DY/DX + var/dx = _x1 - _x2 + A.pixel_x + B.pixel_x + var/dy = _y1 - _y2 + A.pixel_y + B.pixel_y + + //Distance check + if(dx == 0 && dy == 0) //No distance, don't bother calculating + return 0 + . = sqrt(((dx**2) + (dy**2))) /proc/get(atom/loc, type) while(loc) @@ -1351,6 +1382,10 @@ var/global/list/common_tools = list( /obj/item/weapon/twohanded/fireaxe,\ /obj/item/weapon/hatchet,\ /obj/item/weapon/throwing_star,\ + /obj/item/clothing/glasses/sunglasses/garb,\ + /obj/item/clothing/glasses/sunglasses/gar,\ + /obj/item/clothing/glasses/hud/security/sunglasses/gars,\ + /obj/item/clothing/glasses/meson/gar,\ /obj/item/weapon/twohanded/spear) //Because is_sharp is used for food or something. @@ -1500,4 +1535,4 @@ var/list/WALLITEMS = list( return pick("red","green","blue","brown","yellow","orange","darkred","crimson", "lime","darkgreen","cyan","navy","teal","purple","indigo") else - return "white" \ No newline at end of file + return "white" diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index f21f383e69b..66d22ff71b1 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -126,8 +126,6 @@ W.afterattack(A,src,0,params) // 0: not Adjacent else RangedAttack(A, params) - last_movement=world.time - return /mob/proc/changeNext_move(num) next_move = world.time + num diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm index cbbd9bc7052..88dd74669d2 100644 --- a/code/_onclick/hud/_defines.dm +++ b/code/_onclick/hud/_defines.dm @@ -54,6 +54,7 @@ #define ui_borg_camera "CENTER+3:21,SOUTH:5" //borgs #define ui_borg_album "CENTER+4:21,SOUTH:5" //borgs +#define ui_monkey_head "CENTER-4:13,SOUTH:5" //monkey #define ui_monkey_mask "CENTER-3:14,SOUTH:5" //monkey #define ui_monkey_back "CENTER-2:15,SOUTH:5" //monkey diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 5dffc0127b2..fbde37f1d94 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -76,7 +76,7 @@ alerts -= category if(client && hud_used) hud_used.reorganize_alerts() - client.screen -= alert + client.screen -= alert qdel(alert) // Make sure any alerts you throw have a path that matches /obj/screen/alert/[id] or /obj/screen/alert/[category] diff --git a/code/_onclick/hud/alien.dm b/code/_onclick/hud/alien.dm index 4f13c983594..a0422e05b91 100644 --- a/code/_onclick/hud/alien.dm +++ b/code/_onclick/hud/alien.dm @@ -106,7 +106,7 @@ mymob.pullin = new /obj/screen/pull() mymob.pullin.icon = 'icons/mob/screen_alien.dmi' - mymob.pullin.icon_state = "pull0" + mymob.pullin.update_icon(mymob) mymob.pullin.screen_loc = ui_pull_resist //begin indicators diff --git a/code/_onclick/hud/alien_larva.dm b/code/_onclick/hud/alien_larva.dm index 3f9ea8e37d6..ab395f371e1 100644 --- a/code/_onclick/hud/alien_larva.dm +++ b/code/_onclick/hud/alien_larva.dm @@ -29,7 +29,7 @@ mymob.pullin = new /obj/screen/pull() mymob.pullin.icon = 'icons/mob/screen_alien.dmi' - mymob.pullin.icon_state = "pull0" + mymob.pullin.update_icon(mymob) mymob.pullin.screen_loc = ui_pull_resist mymob.blind = new /obj/screen() diff --git a/code/_onclick/hud/drones.dm b/code/_onclick/hud/drones.dm index 086dc39c95a..63600d94053 100644 --- a/code/_onclick/hud/drones.dm +++ b/code/_onclick/hud/drones.dm @@ -11,7 +11,7 @@ mymob.pullin = new /obj/screen/pull() mymob.pullin.icon = ui_style - mymob.pullin.icon_state = "pull0" + mymob.pullin.update_icon(mymob) mymob.pullin.screen_loc = ui_drone_pull adding += mymob.pullin diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 4d2ea2b32f0..18b4f72a13b 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -267,7 +267,7 @@ mymob.pullin = new /obj/screen/pull() mymob.pullin.icon = ui_style - mymob.pullin.icon_state = "pull0" + mymob.pullin.update_icon(mymob) mymob.pullin.screen_loc = ui_pull_resist hotkeybuttons += mymob.pullin diff --git a/code/_onclick/hud/monkey.dm b/code/_onclick/hud/monkey.dm index 3cd2871960c..ad2d394d7b3 100644 --- a/code/_onclick/hud/monkey.dm +++ b/code/_onclick/hud/monkey.dm @@ -73,6 +73,15 @@ inv_box.layer = 19 adding += inv_box + inv_box = new /obj/screen/inventory() + inv_box.name = "head" + inv_box.icon = ui_style + inv_box.icon_state = "head" + inv_box.screen_loc = ui_monkey_head + inv_box.slot_id = slot_head + inv_box.layer = 19 + adding += inv_box + inv_box = new /obj/screen/inventory() inv_box.name = "back" inv_box.icon = ui_style @@ -96,7 +105,7 @@ mymob.pullin = new /obj/screen/pull() mymob.pullin.icon = ui_style - mymob.pullin.icon_state = "pull0" + mymob.pullin.update_icon(mymob) mymob.pullin.screen_loc = ui_pull_resist lingchemdisplay = new /obj/screen/ling/chems() diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index fe5b38db0ab..878efe59e65 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -127,7 +127,7 @@ mymob.pullin = new /obj/screen/pull() mymob.pullin.icon = 'icons/mob/screen_cyborg.dmi' - mymob.pullin.icon_state = "pull0" + mymob.pullin.update_icon(mymob) mymob.pullin.screen_loc = ui_borg_pull mymob.blind = new /obj/screen() diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 0a289671a7a..856dce11be8 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -187,6 +187,13 @@ /obj/screen/pull/Click() usr.stop_pulling() +/obj/screen/pull/update_icon(mob/mymob) + if(!mymob) return + if(mymob.pulling) + icon_state = "pull" + else + icon_state = "pull0" + /obj/screen/resist name = "resist" icon = 'icons/mob/screen_midnight.dmi' diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 75917f2de7d..b2f0fd6fcdf 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -39,6 +39,17 @@ visible_message("[attack_message]", "[attack_message]") +/mob/living/simple_animal/attacked_by(var/obj/item/I, var/mob/living/user) + if(!I.force) + user.visible_message("[user] gently taps [src] with [I].",\ + "This weapon is ineffective, it does no damage.") + else if(I.force >= force_threshold && I.damtype != STAMINA) + ..() + else + visible_message("[I] bounces harmlessly off of [src].",\ + "[I] bounces harmlessly off of [src].") + + // Proximity_flag is 1 if this afterattack was called on something adjacent, in your square, or on your person. // Click parameters is the params string from byond Click() code, see that documentation. diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index b6060e3d3f7..515f0368ec6 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -117,11 +117,11 @@ Slimes Nothing happening here */ -/mob/living/carbon/slime/UnarmedAttack(var/atom/A) +/mob/living/simple_animal/slime/UnarmedAttack(var/atom/A) A.attack_slime(src) /atom/proc/attack_slime(mob/user as mob) return -/mob/living/carbon/slime/RestrainedClickOn(var/atom/A) +/mob/living/simple_animal/slime/RestrainedClickOn(var/atom/A) return /* diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm index b95575cec58..ba766fbee8c 100644 --- a/code/_onclick/telekinesis.dm +++ b/code/_onclick/telekinesis.dm @@ -168,8 +168,7 @@ var/const/tk_maxrange = 15 O.icon_state = "nothing" flick("empdisable",O) spawn(5) - O.delete() - return + qdel(O) /obj/item/tk_grab/update_icon() diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 6cc5abb7a18..515dfef3825 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -110,6 +110,10 @@ var/mutant_races = 0 //players can choose their mutant race before joining the game var/mutant_colors = 0 + var/no_summon_guns //No + var/no_summon_magic //Fun + var/no_summon_events //Allowed + var/alert_desc_green = "All threats to the station have passed. Security may not have weapons visible, privacy laws are once again fully enforced." 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." @@ -476,6 +480,12 @@ config.starlight = 1 if("grey_assistants") config.grey_assistants = 1 + if("no_summon_guns") + config.no_summon_guns = 1 + if("no_summon_magic") + config.no_summon_magic = 1 + if("no_summon_events") + config.no_summon_events = 1 else diary << "Unknown setting in configuration: '[name]'" diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index 7bee21bbb03..46379e1ed8b 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -37,7 +37,7 @@ Note: you can set the datum's defined processing_interval to some integer to set processing_interval = GCD /datum/controller/game_controller/proc/setup() - world << "Initializing Subsystems..." + world << "Initializing Subsystems..." //sort subsystems by priority, so they initialize in the correct order sortTim(subsystems, /proc/cmp_subsystem_priority) @@ -52,7 +52,7 @@ Note: you can set the datum's defined processing_interval to some integer to set S.Initialize(world.timeofday) sleep(-1) - world << "Initializations complete" + world << "Initializations complete" world.log << "Initializations complete" world.sleep_offline = 1 diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index 93e38c36be7..929d2078bb2 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -11,7 +11,7 @@ var/datum/subsystem/events/SSevent var/frequency_lower = 3000 //5 minutes lower bound. var/frequency_upper = 9000 //15 minutes upper bound. Basically an event will happen every 5 to 15 minutes. - var/holiday //This will be a string of the name of any realworld holiday which occurs today (GMT time) + var/list/holidays //List of all holidays occuring today or null if no holidays var/wizardmode = 0 @@ -65,7 +65,7 @@ var/datum/subsystem/events/SSevent if(E.occurrences >= E.max_occurrences) continue if(E.earliest_start >= world.time) continue if(E.holidayID) - if(E.holidayID != holiday) continue + if(!holidays || !holidays[E.holidayID]) continue if(E.weight < 0) //for round-start events etc. if(E.runEvent() == PROCESS_KILL) E.max_occurrences = 0 @@ -82,7 +82,7 @@ var/datum/subsystem/events/SSevent if(E.occurrences >= E.max_occurrences) continue if(E.earliest_start >= world.time) continue if(E.holidayID) - if(E.holidayID != holiday) continue + if(!holidays || !holidays[E.holidayID]) continue sum_of_weights -= E.weight if(sum_of_weights <= 0) //we've hit our goal @@ -152,12 +152,12 @@ var/datum/subsystem/events/SSevent ////////////// //Uncommenting ALLOW_HOLIDAYS in config.txt will enable holidays -//It's easy to add stuff. Just modify getHoliday to set holiday to something using the switch for DD(#day) MM(#month) YY(#year). -//You can then check if it's a special day in any code in the game by doing if(events.holiday == "MyHolidayID") +//It's easy to add stuff. Just add a holiday datum in code/modules/holiday/holidays.dm +//You can then check if it's a special day in any code in the game by doing if(SSevent.holidays["Groundhog Day"]) //You can also make holiday random events easily thanks to Pete/Gia's system. -//simply make a random event normally, then assign it a holidayID string which matches the one you gave it in getHolday. -//Anything with a holidayID, which does not match the holiday string, will never occur. +//simply make a random event normally, then assign it a holidayID string which matches the holiday's name. +//Anything with a holidayID, which isn't in the holidays list, will never occur. //Please, Don't spam stuff up with stupid stuff (key example being april-fools Pooh/ERP/etc), //And don't forget: CHECK YOUR CODE!!!! We don't want any zero-day bugs which happen only on holidays and never get found/fixed! @@ -165,111 +165,27 @@ var/datum/subsystem/events/SSevent ////////////////////////////////////////////////////////////////////////////////////////////////////////// //ALSO, MOST IMPORTANTLY: Don't add stupid stuff! Discuss bonus content with Project-Heads first please!// ////////////////////////////////////////////////////////////////////////////////////////////////////////// -~Carn */ +*/ -//sets up the holiday string in the events manager. +//sets up the holidays and holidays list /datum/subsystem/events/proc/getHoliday() if(!config.allow_holidays) return // Holiday stuff was not enabled in the config! - holiday = null - var/YY = text2num(time2text(world.timeofday, "YY")) // get the current year - var/MM = text2num(time2text(world.timeofday, "MM")) // get the current month - var/DD = text2num(time2text(world.timeofday, "DD")) // get the current day + var/YY = text2num(time2text(world.timeofday, "YY")) // get the current year + var/MM = text2num(time2text(world.timeofday, "MM")) // get the current month + var/DD = text2num(time2text(world.timeofday, "DD")) // get the current day - //Main switch. If any of these are too dumb/inappropriate, or you have better ones, feel free to change whatever - switch(MM) - if(1) //Jan - switch(DD) - if(1) holiday = "New Year" - - if(2) //Feb - switch(DD) - if(2) holiday = "Groundhog Day" - if(14) holiday = "Valentine's Day" - if(17) holiday = "Random Acts of Kindness Day" - - if(3) //Mar - switch(DD) - if(14) holiday = "Pi Day" - if(17) holiday = "St. Patrick's Day" - if(27) - if(YY == 16) - holiday = "Easter" - if(31) - if(YY == 13) - holiday = "Easter" - - if(4) //Apr - switch(DD) - if(1) - holiday = "April Fool's Day" - if(YY == 18 && prob(50)) holiday = "Easter" - if(5) - if(YY == 15) holiday = "Easter" - if(16) - if(YY == 17) holiday = "Easter" - if(20) - holiday = "Four-Twenty" - if(YY == 14 && prob(50)) holiday = "Easter" - if(22) holiday = "Earth Day" - - if(5) //May - switch(DD) - if(1) holiday = "Labour Day" - if(4) holiday = "FireFighter's Day" - if(12) holiday = "Owl and Pussycat Day" //what a dumb day of observence...but we -do- have costumes already :3 - - if(6) //Jun - - if(7) //Jul - switch(DD) - if(1) holiday = "Doctor's Day" - if(2) holiday = "UFO Day" - if(8) holiday = "Writer's Day" - if(30) holiday = "Friendship Day" - - if(8) //Aug - switch(DD) - if(5) holiday = "Beer Day" - - if(9) //Sep - switch(DD) - if(19) holiday = "Talk-Like-a-Pirate Day" - if(28) holiday = "Stupid-Questions Day" - - if(10) //Oct - switch(DD) - if(4) holiday = "Animal's Day" - if(7) holiday = "Smiling Day" - if(16) holiday = "Boss' Day" - if(31) holiday = "Halloween" - - if(11) //Nov - switch(DD) - if(1) holiday = "Vegan Day" - if(13) holiday = "Kindness Day" - if(19) holiday = "Flowers Day" - if(21) holiday = "Saying-'Hello' Day" - - if(12) //Dec - switch(DD) - if(10) holiday = "Human-Rights Day" - if(14) holiday = "Monkey Day" - if(21) holiday = "Mayan Doomsday Anniversary" - if(22) holiday = "Orgasming Day" //lol. These all actually exist - if(24) holiday = "Xmas" - if(25) holiday = "Xmas" - if(26) holiday = "Boxing Day" - if(31) holiday = "New Year" - - if(!holiday) - //Friday the 13th - if(DD == 13) - if(time2text(world.timeofday, "DDD") == "Fri") - holiday = "Friday the 13th" - - world.update_status() + for(var/H in typesof(/datum/holiday) - /datum/holiday) + var/datum/holiday/holiday = new H() + if(holiday.shouldCelebrate(DD, MM, YY)) + holiday.celebrate() + if(!holidays) + holidays = list() + holidays[holiday.name] = holiday + if(holidays) + holidays = shuffle(holidays) + world.update_status() /datum/subsystem/events/proc/toggleWizardmode() wizardmode = !wizardmode diff --git a/code/controllers/subsystem/jobs.dm b/code/controllers/subsystem/jobs.dm index 1d663b946ca..a6ecefc1f02 100644 --- a/code/controllers/subsystem/jobs.dm +++ b/code/controllers/subsystem/jobs.dm @@ -23,7 +23,7 @@ var/datum/subsystem/job/SSjob occupations = list() var/list/all_jobs = typesof(/datum/job) if(!all_jobs.len) - world << "Error setting up jobs, no job datums found" + world << "Error setting up jobs, no job datums found" return 0 for(var/J in all_jobs) diff --git a/code/controllers/subsystem/shuttles.dm b/code/controllers/subsystem/shuttles.dm index 91025890fc0..53c501c11ff 100644 --- a/code/controllers/subsystem/shuttles.dm +++ b/code/controllers/subsystem/shuttles.dm @@ -162,7 +162,7 @@ var/datum/subsystem/shuttle/SSshuttle break if(callShuttle) - if(emergency.mode < SHUTTLE_DOCKED) + if(emergency.mode < SHUTTLE_CALL) emergency.request(null, 2.5) log_game("There is no means of calling the shuttle anymore. Shuttle automatically called.") message_admins("All the communications consoles were destroyed and all AIs are inactive. Shuttle called.") diff --git a/code/controllers/subsystem/shuttles/supply.dm b/code/controllers/subsystem/shuttles/supply.dm index 3aa57e82b16..3fcc981725c 100644 --- a/code/controllers/subsystem/shuttles/supply.dm +++ b/code/controllers/subsystem/shuttles/supply.dm @@ -303,10 +303,6 @@ updateUsrDialog() return -/obj/machinery/computer/ordercomp/say_quote(text) - return "flashes, \"[text]\"" - - /obj/machinery/computer/supplycomp/attack_hand(var/mob/user as mob) if(!allowed(user)) user << "Access Denied." @@ -530,7 +526,3 @@ status_signal.data["command"] = command frequency.post_signal(src, status_signal) - - -/obj/machinery/computer/supplycomp/say_quote(text) - return "flashes, \"[text]\"" diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 9f9ecf422a8..040232d7baa 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -47,7 +47,7 @@ var/datum/subsystem/ticker/ticker NEW_SS_GLOBAL(ticker) login_music = pickweight(list('sound/ambience/title2.ogg' = 49, 'sound/ambience/title1.ogg' = 49, 'sound/ambience/clown.ogg' = 2)) // choose title music! - if(SSevent.holiday == "April Fool's Day") + if(SSevent.holidays && SSevent.holidays[APRIL_FOOLS]) login_music = 'sound/ambience/clown.ogg' /datum/subsystem/ticker/Initialize() @@ -188,11 +188,13 @@ var/datum/subsystem/ticker/ticker world << "Welcome to [station_name()], enjoy your stay!" - world << sound('sound/AI/welcome.ogg') // Skie - //Holiday Round-start stuff ~Carn - if(SSevent.holiday) + world << sound('sound/AI/welcome.ogg') + + if(SSevent.holidays) world << "and..." - world << "

Happy [SSevent.holiday] Everybody!

" + for(var/holidayname in SSevent.holidays) + var/datum/holiday/holiday = SSevent.holidays[holidayname] + world << "

[holiday.greet()]

" spawn(0)//Forking here so we dont have to wait for this to finish @@ -383,6 +385,8 @@ var/datum/subsystem/ticker/ticker world << "[aiPlayer.name] (Played by: [aiPlayer.mind.key])'s laws when it was deactivated were:" aiPlayer.show_laws(1) + world << "Total law changes: [aiPlayer.law_change_counter]" + if (aiPlayer.connected_robots.len) var/robolist = "[aiPlayer.real_name]'s minions were: " for(var/mob/living/silicon/robot/robo in aiPlayer.connected_robots) diff --git a/code/controllers/subsystems.dm b/code/controllers/subsystems.dm index 3c9a3c4e0bb..47eaadb43e5 100644 --- a/code/controllers/subsystems.dm +++ b/code/controllers/subsystems.dm @@ -28,7 +28,7 @@ /datum/subsystem/proc/Initialize(start_timeofday) var/time = (world.timeofday - start_timeofday) / 10 var/msg = "Initialized [name] SubSystem within [time] seconds" - world << "[msg]" + world << "[msg]" world.log << msg //hook for printing stats to the "MC" statuspanel for admins to see performance and related stats etc. diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm index 2aaea111eb1..de27718296c 100644 --- a/code/datums/diseases/transformation.dm +++ b/code/datums/diseases/transformation.dm @@ -189,7 +189,7 @@ stage3 = list("Your limbs are getting oozy.", "Your skin begins to peel away.") stage4 = list("You are turning into a slime.") stage5 = list("You have become a slime.") - new_form = /mob/living/carbon/slime + new_form = /mob/living/simple_animal/slime /datum/disease/transformation/slime/stage_act() ..() @@ -215,7 +215,7 @@ stage3 = list("Must... eat... chocolate....", "YAP") stage4 = list("Visions of washing machines assail your mind!") stage5 = list("AUUUUUU!!!") - new_form = /mob/living/simple_animal/corgi + new_form = /mob/living/simple_animal/pet/corgi /datum/disease/transformation/corgi/stage_act() ..() diff --git a/code/datums/gas_mixture.dm b/code/datums/gas_mixture.dm index 0b2d5377904..54302f051a3 100644 --- a/code/datums/gas_mixture.dm +++ b/code/datums/gas_mixture.dm @@ -37,7 +37,7 @@ What are the archived variables for? var/volume = CELL_VOLUME - var/temperature = 0 //in Kelvin, use calculate_temperature() to modify + var/temperature = 0 //in Kelvin var/last_share @@ -746,7 +746,7 @@ What are the archived variables for? if(border_multiplier) temperature = (old_self_heat_capacity*temperature - heat_capacity_transferred*border_multiplier*temperature_archived)/new_self_heat_capacity else - temperature = (old_self_heat_capacity*temperature - heat_capacity_transferred*border_multiplier*temperature_archived)/new_self_heat_capacity + temperature = (old_self_heat_capacity*temperature - heat_capacity_transferred*temperature_archived)/new_self_heat_capacity temperature_mimic(model, model.thermal_conductivity, border_multiplier) diff --git a/code/datums/goon_mutations_disabilities.dm b/code/datums/goon_mutations_disabilities.dm index 44555ce8c4b..9da8e51307e 100644 --- a/code/datums/goon_mutations_disabilities.dm +++ b/code/datums/goon_mutations_disabilities.dm @@ -4,16 +4,14 @@ text_gain_indication = "You feel an off sensation in your voicebox." text_lose_indication = "The off sensation passes." -/datum/mutation/human/wacky/say_mod(var/message) - if(message) - message = "[message]" - return message +/datum/mutation/human/wacky/get_spans() + return list(SPAN_SANS) /datum/mutation/human/mute name = "Mute" quality = NEGATIVE - text_gain_indication = "You feel unable to express yourself at all." - text_lose_indication = "You feel able to speak freely again." + text_gain_indication = "You feel unable to express yourself at all." + text_lose_indication = "You feel able to speak freely again." /datum/mutation/human/mute/on_acquiring(mob/living/carbon/human/owner) if(..()) return @@ -81,8 +79,8 @@ /datum/mutation/human/unintelligable name = "Unintelligable" quality = NEGATIVE - text_gain_indication = "You can't seem to form any coherent thoughts!" - text_lose_indication = "Your mind feels more clear." + text_gain_indication = "You can't seem to form any coherent thoughts!" + text_lose_indication = "Your mind feels more clear." /datum/mutation/human/unintelligable/say_mod(var/message) if(message) diff --git a/code/datums/goon_mutations_powers.dm b/code/datums/goon_mutations_powers.dm index e164eced752..a2e64ff37ee 100644 --- a/code/datums/goon_mutations_powers.dm +++ b/code/datums/goon_mutations_powers.dm @@ -28,11 +28,12 @@ text_gain_indication = "You feel one with your surroundings." text_lose_indication = "You feel oddly exposed." var/last_location + /datum/mutation/human/chameleon/on_life(mob/living/carbon/human/owner) if(owner.loc != last_location) owner.alpha = round(255 * 0.80) last_location = owner.loc - if((world.time - owner.last_movement) >= 30 && !owner.stat && owner.canmove && !owner.restrained()) + if((world.time - owner.next_move) >= 30 && !owner.stat && owner.canmove && !owner.restrained()) owner.alpha -= 25 else owner.alpha = round(255 * 0.80) diff --git a/code/datums/hud.dm b/code/datums/hud.dm index 39d63400ddb..f3315d1cfd6 100644 --- a/code/datums/hud.dm +++ b/code/datums/hud.dm @@ -20,6 +20,8 @@ var/datum/atom_hud/huds = list( \ var/list/hud_icons = list() //these will be the indexes for the atom's hud_list /datum/atom_hud/proc/remove_hud_from(var/mob/M) + if(src in M.permanent_huds) + return for(var/atom/A in hudatoms) remove_from_single_hud(M, A) hudusers -= M diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 9f8acdd9c52..dbdcb3afadb 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -592,7 +592,7 @@ if(!def_value)//If it's a custom objective, it will be an empty string. def_value = "custom" - var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "maroon", "debrain", "protect", "destroy", "prevent", "hijack", "escape", "survive", "steal", "download", "nuclear", "capture", "absorb", "custom") + var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "maroon", "debrain", "protect", "destroy", "prevent", "hijack", "escape", "survive", "martyr", "steal", "download", "nuclear", "capture", "absorb", "custom") if (!new_obj_type) return var/datum/objective/new_objective = null @@ -652,6 +652,10 @@ new_objective = new /datum/objective/survive new_objective.owner = src + if("martyr") + new_objective = new /datum/objective/martyr + new_objective.owner = src + if ("nuclear") new_objective = new /datum/objective/nuclear new_objective.owner = src @@ -724,14 +728,14 @@ switch(href_list["revolution"]) if("clear") remove_rev() - current << "You have been brainwashed! You are no longer a revolutionary!" + current << "You have been brainwashed! You are no longer a revolutionary!" message_admins("[key_name_admin(usr)] has de-rev'ed [current].") log_admin("[key_name(usr)] has de-rev'ed [current].") if("rev") if(src in ticker.mode.head_revolutionaries) ticker.mode.head_revolutionaries -= src ticker.mode.update_rev_icons_removed(src) - current << "Revolution has been disappointed of your leader traits! You are a regular revolutionary now!" + current << "Revolution has been disappointed of your leader traits! You are a regular revolutionary now!" else if(!(src in ticker.mode.revolutionaries)) current << " You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill the heads to win the revolution!" else @@ -746,9 +750,9 @@ if(src in ticker.mode.revolutionaries) ticker.mode.revolutionaries -= src ticker.mode.update_rev_icons_removed(src) - current << "You have proved your devotion to revoltion! Yea are a head revolutionary now!" + current << "You have proved your devotion to revoltion! Yea are a head revolutionary now!" else if(!(src in ticker.mode.head_revolutionaries)) - current << "You are a member of the revolutionaries' leadership now!" + current << "You are a member of the revolutionaries' leadership now!" else return if (ticker.mode.head_revolutionaries.len>0) @@ -874,7 +878,7 @@ switch(href_list["cult"]) if("clear") remove_cultist() - current << "You have been brainwashed! You are no longer a cultist!" + current << "You have been brainwashed! You are no longer a cultist!" message_admins("[key_name_admin(usr)] has de-cult'ed [current].") log_admin("[key_name(usr)] has de-cult'ed [current].") if("cultist") @@ -908,14 +912,14 @@ switch(href_list["wizard"]) if("clear") remove_wizard() - current << "You have been brainwashed! You are no longer a wizard!" + current << "You have been brainwashed! You are no longer a wizard!" log_admin("[key_name(usr)] has de-wizard'ed [current].") if("wizard") if(!(src in ticker.mode.wizards)) ticker.mode.wizards += src special_role = "Wizard" //ticker.mode.learn_basic_spells(current) - current << "You are the Space Wizard!" + current << "You are the Space Wizard!" message_admins("[key_name_admin(usr)] has wizard'ed [current].") log_admin("[key_name(usr)] has wizard'ed [current].") if("lair") @@ -932,7 +936,7 @@ switch(href_list["changeling"]) if("clear") remove_changeling() - current << "You grow weak and lose your powers! You are no longer a changeling and are stuck in your current form!" + current << "You grow weak and lose your powers! You are no longer a changeling and are stuck in your current form!" message_admins("[key_name_admin(usr)] has de-changeling'ed [current].") log_admin("[key_name(usr)] has de-changeling'ed [current].") if("changeling") @@ -940,7 +944,7 @@ ticker.mode.changelings += src current.make_changeling() special_role = "Changeling" - current << "Your powers are awoken. A flash of memory returns to us...we are [changeling.changelingID], a changeling!" + current << "Your powers are awoken. A flash of memory returns to us...we are [changeling.changelingID], a changeling!" message_admins("[key_name_admin(usr)] has changeling'ed [current].") log_admin("[key_name(usr)] has changeling'ed [current].") if("autoobjectives") @@ -961,7 +965,7 @@ switch(href_list["nuclear"]) if("clear") remove_nukeop() - current << "You have been brainwashed! You are no longer a syndicate operative!" + current << "You have been brainwashed! You are no longer a syndicate operative!" message_admins("[key_name_admin(usr)] has de-nuke op'ed [current].") log_admin("[key_name(usr)] has de-nuke op'ed [current].") if("nuclear") @@ -1011,7 +1015,7 @@ switch(href_list["traitor"]) if("clear") remove_traitor() - current << "You have been brainwashed! You are no longer a traitor!" + current << "You have been brainwashed! You are no longer a traitor!" message_admins("[key_name_admin(usr)] has de-traitor'ed [current].") log_admin("[key_name(usr)] has de-traitor'ed [current].") @@ -1019,7 +1023,7 @@ if(!(src in ticker.mode.traitors)) ticker.mode.traitors += src special_role = "traitor" - current << "You are a traitor!" + current << "You are a traitor!" message_admins("[key_name_admin(usr)] has traitor'ed [current].") log_admin("[key_name(usr)] has traitor'ed [current].") if(isAI(current)) @@ -1083,7 +1087,7 @@ switch(href_list["silicon"]) if("unmalf") remove_malf() - current << "You have been patched! You are no longer malfunctioning!" + current << "You have been patched! You are no longer malfunctioning!" message_admins("[key_name_admin(usr)] has de-malf'ed [current].") log_admin("[key_name(usr)] has de-malf'ed [current].") @@ -1334,7 +1338,7 @@ ..() //slime -/mob/living/carbon/slime/mind_initialize() +/mob/living/simple_animal/slime/mind_initialize() ..() mind.special_role = "slime" mind.assigned_role = "slime" @@ -1392,7 +1396,7 @@ mind.assigned_role = "Animal" mind.special_role = "Animal" -/mob/living/simple_animal/corgi/mind_initialize() +/mob/living/simple_animal/pet/corgi/mind_initialize() ..() mind.assigned_role = "Corgi" mind.special_role = "Corgi" diff --git a/code/datums/mutations.dm b/code/datums/mutations.dm index 566adcedc03..1548615ddd0 100644 --- a/code/datums/mutations.dm +++ b/code/datums/mutations.dm @@ -88,6 +88,9 @@ if(message) return message +/datum/mutation/human/proc/get_spans() + return list() + /datum/mutation/human/hulk name = "Hulk" @@ -179,6 +182,8 @@ /datum/mutation/human/x_ray/on_losing(mob/living/carbon/human/owner) if(..()) return + if((SEE_MOBS & owner.permanent_sight_flags) && (SEE_OBJS & owner.permanent_sight_flags) && (SEE_TURFS & owner.permanent_sight_flags)) //Xray flag combo + return owner.see_in_dark = initial(owner.see_in_dark) owner.sight = initial(owner.sight) @@ -204,7 +209,7 @@ /datum/mutation/human/epilepsy/on_life(mob/living/carbon/human/owner) if ((prob(1) && owner.paralysis < 1)) - owner.visible_message("[owner] starts having a seizure!", "You have a seizure!") + owner.visible_message("[owner] starts having a seizure!", "You have a seizure!") owner.Paralyse(10) owner.Jitter(1000) @@ -215,6 +220,7 @@ text_gain_indication = "You feel strange." /datum/mutation/human/bad_dna/on_acquiring(var/mob/living/carbon/human/owner) + owner << text_gain_indication var/mob/new_mob if(prob(95)) if(prob(50)) diff --git a/code/datums/spell.dm b/code/datums/spell.dm index 7137bbf9ad1..587d5f1c646 100644 --- a/code/datums/spell.dm +++ b/code/datums/spell.dm @@ -1,3 +1,6 @@ +#define TARGET_CLOSEST 1 +#define TARGET_RANDOM 2 + /obj/effect/proc_holder var/panel = "Debug"//What panel the proc holder needs to go on. @@ -245,6 +248,8 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin var/max_targets = 1 //leave 0 for unlimited targets in range, 1 for one selectable target in range, more for limited number of casts (can all target one guy, depends on target_ignore_prev) in range var/target_ignore_prev = 1 //only important if max_targets > 1, affects if the spell can be cast multiple times at one person from one cast var/include_user = 0 //if it includes usr in the target list + var/random_target = 0 // chooses random viable target instead of asking the caster + var/random_target_priority = TARGET_CLOSEST // if random_target is enabled how it will pick the target /obj/effect/proc_holder/spell/aoe_turf //affects all turfs in view or range (depends) var/inner_radius = -1 //for all your ring spell needs @@ -269,7 +274,22 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin //targets += input("Choose the target for the spell.", "Targeting") as mob in possible_targets //Adds a safety check post-input to make sure those targets are actually in range. - var/mob/M = input("Choose the target for the spell.", "Targeting") as mob in possible_targets + var/mob/M + if(!random_target) + M = input("Choose the target for the spell.", "Targeting") as mob in possible_targets + else + switch(random_target_priority) + if(TARGET_RANDOM) + M = pick(possible_targets) + if(TARGET_CLOSEST) + for(var/mob/living/L in possible_targets) + if(M) + if(get_dist(user,L) < get_dist(user,M)) + if(los_check(user,L)) + M = L + else + if(los_check(user,L)) + M = L if(M in view_or_range(range, user, selection_type)) targets += M else @@ -315,4 +335,16 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin /obj/effect/proc_holder/spell/proc/can_be_cast_by(mob/caster) if((human_req || clothes_req) && !ishuman(caster)) return 0 + return 1 + +/obj/effect/proc_holder/spell/targeted/proc/los_check(mob/A,mob/B) + //Checks for obstacles from A to B + var/obj/dummy = new(A.loc) + dummy.pass_flags |= PASSTABLE + for(var/turf/turf in getline(A,B)) + for(var/atom/movable/AM in turf) + if(!AM.CanPass(dummy,turf,1)) + qdel(dummy) + return 0 + qdel(dummy) return 1 \ No newline at end of file diff --git a/code/datums/spells/lightning.dm b/code/datums/spells/lightning.dm new file mode 100644 index 00000000000..b3e813c7e0e --- /dev/null +++ b/code/datums/spells/lightning.dm @@ -0,0 +1,98 @@ +/obj/effect/proc_holder/spell/targeted/lightning + name = "Lightning Bolt" + desc = "Throws a lightning bolt at the nearby enemy. Classic." + charge_type = "recharge" + charge_max = 300 + clothes_req = 1 + invocation = "UN'LTD P'WAH!" + invocation_type = "shout" + range = 7 + cooldown_min = 30 + selection_type = "view" + random_target = 1 + var/energy = 0 + var/ready = 0 + var/image/halo = null + +/obj/effect/proc_holder/spell/targeted/lightning/Click() + if(!ready) + if(cast_check()) + StartChargeup() + else + if(cast_check(skipcharge=1)) + choose_targets() + return 1 + +/obj/effect/proc_holder/spell/targeted/lightning/proc/StartChargeup(mob/user = usr) + ready = 1 + user << "You start gathering the power." + halo = image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = EFFECTS_LAYER) + user.overlays.Add(halo) + spawn(0) + while(ready) + sleep(1) + energy++ + if(energy >= 100 && ready) + Discharge() + +obj/effect/proc_holder/spell/targeted/lightning/proc/Reset(mob/user = usr) + ready = 0 + energy = 0 + if(halo) + user.overlays.Remove(halo) + +/obj/effect/proc_holder/spell/targeted/lightning/revert_cast(mob/user = usr) + user << "No target found in range." + Reset(user) + ..() + +/obj/effect/proc_holder/spell/targeted/lightning/proc/Discharge(mob/user = usr) + var/mob/living/M = user + //M.electrocute_act(25,"Lightning Bolt") + M << "You lose control over the spell." + Reset(user) + start_recharge() + + +/obj/effect/proc_holder/spell/targeted/lightning/cast(list/targets, mob/user = usr) + + var/mob/living/carbon/target = targets[1] + + if(get_dist(user,target)>range) + user << "They are too far away!" + Reset(user) + return + + user.Beam(target,icon_state="lightning",icon='icons/effects/effects.dmi',time=5) + + switch(energy) + if(0 to 25) + target.electrocute_act(10,"Lightning Bolt") + playsound(get_turf(target), 'sound/machines/defib_zap.ogg', 50, 1, -1) + if(25 to 75) + target.electrocute_act(25,"Lightning Bolt") + playsound(get_turf(target), 'sound/machines/defib_zap.ogg', 50, 1, -1) + if(75 to 100) + //CHAIN LIGHTNING + Bolt(user,target,energy,user) + Reset(user) + +/obj/effect/proc_holder/spell/targeted/lightning/proc/Bolt(mob/origin,mob/target,bolt_energy,mob/user = usr) + origin.Beam(target,icon_state="lightning",icon='icons/effects/effects.dmi',time=5) + var/mob/living/carbon/current = target + if(bolt_energy < 75) + current.electrocute_act(25,"Lightning Bolt") + playsound(get_turf(current), 'sound/machines/defib_zap.ogg', 50, 1, -1) + else + current.electrocute_act(25,"Lightning Bolt") + playsound(get_turf(current), 'sound/machines/defib_zap.ogg', 50, 1, -1) + var/list/possible_targets = new + for(var/mob/living/M in view_or_range(range,target,"view")) + if(user == M || target == M && los_check(current,M)) // || origin == M ? Not sure double shockings is good or not + continue + possible_targets += M + if(!possible_targets.len) + return + var/mob/living/next = pick(possible_targets) + if(next) + Bolt(current,next,bolt_energy-6,user) // 5 max bounces \ No newline at end of file diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index 3b5ca3a4ae9..119f1682296 100644 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -185,9 +185,9 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /datum/supply_packs/security/helmets name = "Helmets Crate" - contains = list(/obj/item/clothing/head/helmet, - /obj/item/clothing/head/helmet, - /obj/item/clothing/head/helmet) + contains = list(/obj/item/clothing/head/helmet/sec, + /obj/item/clothing/head/helmet/sec, + /obj/item/clothing/head/helmet/sec) cost = 10 containername = "helmet crate" @@ -801,24 +801,28 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine name = "Corgi Crate" cost = 50 containertype = /obj/structure/closet/critter/corgi + contains = list(/obj/item/clothing/tie/petcollar) containername = "corgi crate" /datum/supply_packs/organic/cat name = "Cat Crate" cost = 50 //Cats are worth as much as corgis. containertype = /obj/structure/closet/critter/cat + contains = list(/obj/item/clothing/tie/petcollar) containername = "cat crate" /datum/supply_packs/organic/pug name = "Pug Crate" cost = 50 containertype = /obj/structure/closet/critter/pug + contains = list(/obj/item/clothing/tie/petcollar) containername = "pug crate" /datum/supply_packs/organic/fox name = "Fox Crate" cost = 55 //Foxes are cool. containertype = /obj/structure/closet/critter/fox + contains = list(/obj/item/clothing/tie/petcollar) containername = "fox crate" /datum/supply_packs/organic/butterfly @@ -1243,3 +1247,26 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/weapon/lipstick/random) cost = 30 //Lots of very expensive items. You gotta pay up to look good! containername = "formal-wear crate" + +/datum/supply_packs/misc/foamforce + name = "Foam Force Crate" + contains = list(/obj/item/weapon/gun/projectile/shotgun/toy, + /obj/item/weapon/gun/projectile/shotgun/toy, + /obj/item/weapon/gun/projectile/shotgun/toy, + /obj/item/weapon/gun/projectile/shotgun/toy, + /obj/item/weapon/gun/projectile/shotgun/toy, + /obj/item/weapon/gun/projectile/shotgun/toy, + /obj/item/weapon/gun/projectile/shotgun/toy, + /obj/item/weapon/gun/projectile/shotgun/toy) + cost = 10 + containername = "foam force crate" + +/datum/supply_packs/misc/foamforce/bonus + name = "Foam Force Pistols Crate" + contains = list(/obj/item/weapon/gun/projectile/automatic/toy/pistol, + /obj/item/weapon/gun/projectile/automatic/toy/pistol, + /obj/item/ammo_box/magazine/toy/pistol, + /obj/item/ammo_box/magazine/toy/pistol) + cost = 40 + containername = "foam force pistols crate" + contraband = 1 \ No newline at end of file diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index 9c01029e1bb..be8c7879494 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -171,6 +171,22 @@ var/list/uplink_items = list() item = /obj/item/weapon/grenade/syndieminibomb cost = 6 +/datum/uplink_item/dangerous/foamsmg + name = "Toy Submachine Gun" + desc = "A fully-loaded Donksoft bullpup submachine gun that fires riot grade rounds with a 20-round magazine." + item = /obj/item/weapon/gun/projectile/automatic/c20r/toy + cost = 12 + gamemodes = list(/datum/game_mode/nuclear) + surplus = 0 + +/datum/uplink_item/dangerous/foammachinegun + name = "Toy Machine Gun" + desc = "A fully-loaded Donksoft belt-fed machine gun. This weapon has a massive 50-round magazine of devastating riot grade darts, that can briefly incapacitate someone in just one volley." + item = /obj/item/weapon/gun/projectile/automatic/l6_saw/toy + cost = 30 + gamemodes = list(/datum/game_mode/nuclear) + surplus = 0 + /datum/uplink_item/dangerous/viscerators name = "Viscerator Delivery Grenade" desc = "A unique grenade that deploys a swarm of viscerators upon activation, which will chase down and shred any non-operatives in the area." @@ -287,6 +303,14 @@ var/list/uplink_items = list() gamemodes = list(/datum/game_mode/nuclear) surplus = 0 +/datum/uplink_item/ammo/toydarts + name = "Box of Riot Darts" + desc = "A box of 40 Donksoft foam riot darts, for reloading any compatible foam dart gun. Don't forget to share!" + item = /obj/item/ammo_box/foambox/riot + cost = 10 + gamemodes = list(/datum/game_mode/nuclear) + surplus = 0 + // STEALTHY WEAPONS /datum/uplink_item/stealthy_weapons @@ -300,6 +324,13 @@ var/list/uplink_items = list() cost = 6 excludefrom = list(/datum/game_mode/nuclear) +/datum/uplink_item/stealthy_weapons/foampistol + name = "Toy Gun (with Stun Darts)" + desc = "An innocent looking toy pistol designed to fire foam darts. Comes loaded with riot grade darts, to incapacitate a target." + item = /obj/item/weapon/gun/projectile/automatic/toy/pistol/riot + cost = 10 + surplus = 10 + /datum/uplink_item/stealthy_weapons/sleepy_pen name = "Sleepy Pen" desc = "A syringe disguised as a functional pen, filled with a potent mix of drugs, including a strong anaesthetic and a chemical that is capable of blocking the movement of the vocal chords. \ @@ -427,7 +458,7 @@ var/list/uplink_items = list() /datum/uplink_item/badass/syndiecigs name = "Syndicate Smokes" - desc = "Strong flavor, dense smoke, infused with Doctor's Delight." + desc = "Strong flavor, dense smoke, infused with Omnizine." item = /obj/item/weapon/storage/fancy/cigarettes/cigpack_syndicate cost = 4 diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 45baa224943..a0eaf523e16 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -2,13 +2,15 @@ layer = 3 var/last_move = null var/anchored = 0 - var/move_speed = 10 - var/l_move_time = 1 var/throwing = 0 var/throw_speed = 2 var/throw_range = 7 var/mob/pulledby = null var/languages = 0 //For say() and Hear() + var/verb_say = "says" + var/verb_ask = "asks" + var/verb_exclaim = "exclaims" + var/verb_yell = "yells" var/inertia_dir = 0 var/pass_flags = 0 glide_size = 8 @@ -50,8 +52,6 @@ return last_move = direct - src.move_speed = world.timeofday - src.l_move_time - src.l_move_time = world.timeofday spawn(5) // Causes space drifting. /tg/station has no concept of speed, we just use 5 if(loc && direct && last_move == direct) @@ -117,7 +117,7 @@ if(pulledby) return 1 - if(locate(/obj/structure/lattice) in orange(1, get_turf(src))) //Not realistic but makes pushing things in space easier + if(locate(/obj/structure/lattice) in range(1, get_turf(src))) //Not realistic but makes pushing things in space easier return 1 return 0 @@ -159,7 +159,7 @@ //use a modified version of Bresenham's algorithm to get from the atom's current position to that of the target src.throwing = 1 - + SpinAnimation(5, 1) var/dist_x = abs(target.x - src.x) var/dist_y = abs(target.y - src.y) var/dx = (target.x > src.x) ? EAST : WEST diff --git a/code/game/dna.dm b/code/game/dna.dm index de97e0e1b04..c86fa683896 100644 --- a/code/game/dna.dm +++ b/code/game/dna.dm @@ -114,6 +114,12 @@ message = M.say_mod(message) return message +/datum/dna/proc/mutations_get_spans() + var/list/spans = list() + for(var/datum/mutation/human/M in mutations) + spans |= M.get_spans() + return spans + /proc/hardset_dna(mob/living/carbon/owner, ui, se, real_name, blood_type, datum/species/mrace, mcolor) if(!istype(owner, /mob/living/carbon/monkey) && !istype(owner, /mob/living/carbon/human)) return @@ -295,7 +301,7 @@ //////////////////////////////////////////////////////////// Monkey Block if(M) - M.update_icon = 1 //queue a full icon update at next life() call + M.regenerate_icons() return 1 /////////////////////////// DNA MISC-PROCS diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm index f2a2ca65f29..7be421ee470 100644 --- a/code/game/gamemodes/antag_spawner.dm +++ b/code/game/gamemodes/antag_spawner.dm @@ -64,7 +64,7 @@ H << "Unable to reach your apprentice! You can either attack the spellbook with the contract to refund your points, or wait and try again later." /obj/item/weapon/antag_spawner/contract/spawn_antag(var/client/C, var/turf/T, var/type = "") - new /obj/effect/effect/harmless_smoke(T) + PoolOrNew(/obj/effect/effect/harmless_smoke, T) var/mob/living/carbon/human/M = new/mob/living/carbon/human(T) C.prefs.copy_to(M) M.key = C.key diff --git a/code/game/gamemodes/blob/blob_finish.dm b/code/game/gamemodes/blob/blob_finish.dm index d3e0d49933e..32073430a46 100644 --- a/code/game/gamemodes/blob/blob_finish.dm +++ b/code/game/gamemodes/blob/blob_finish.dm @@ -22,6 +22,8 @@ /datum/game_mode/blob/declare_completion() + if(round_converted) //So badmin blobs later don't step on the dead natural blobs metaphorical toes + ..() if(blobwincount <= blobs.len) feedback_set_details("round_end_result","win - blob took over") world << "The blob has taken over the station!" diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm index d3a367e5e64..d8b317d1eb6 100644 --- a/code/game/gamemodes/blob/blobs/blob_mobs.dm +++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm @@ -8,14 +8,7 @@ icon = 'icons/mob/blob.dmi' pass_flags = PASSBLOB faction = list("blob") - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 maxbodytemp = 360 var/mob/camera/blob/overmind = null @@ -84,15 +77,17 @@ melee_damage_lower = 10 melee_damage_upper = 15 icon = H.icon - icon_state = "husk_s" + icon_state = "zombie_s" H.hair_style = null H.update_hair() human_overlays = H.overlays - adjustcolors(overmind.blob_reagent_datum.color) + if(overmind && overmind.blob_reagent_datum) + adjustcolors(overmind.blob_reagent_datum.color) H.loc = src loc.visible_message(" The corpse of [H.name] suddenly rises!") -/mob/living/simple_animal/hostile/blob/blobspore/Die() +/mob/living/simple_animal/hostile/blob/blobspore/death(gibbed) + ..(1) // On death, create a small smoke of harmful gas (s-Acid) var/datum/effect/effect/system/chem_smoke_spread/S = new var/turf/location = get_turf(src) @@ -110,6 +105,7 @@ S.set_up(reagents, 1, 1, location, 15, 1) // only 1-2 smoke cloud S.start() + ghostize() qdel(src) /mob/living/simple_animal/hostile/blob/blobspore/Destroy() @@ -152,7 +148,7 @@ maxbodytemp = 360 force_threshold = 10 environment_smash = 3 - mob_size = 2 + mob_size = MOB_SIZE_LARGE /mob/living/simple_animal/hostile/blob/blobbernaut/AttackingTarget() @@ -165,6 +161,6 @@ /mob/living/simple_animal/hostile/blob/blobbernaut/blob_act() return -/mob/living/simple_animal/hostile/blob/blobbernaut/Die() - ..() +/mob/living/simple_animal/hostile/blob/blobbernaut/death(gibbed) + ..(gibbed) flick("blobbernaut_death", src) \ No newline at end of file diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index 9e53d64cfc3..17e34ff67e9 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -154,8 +154,8 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" /datum/game_mode/proc/greet_changeling(var/datum/mind/changeling, var/you_are=1) if (you_are) - changeling.current << "You are [changeling.changeling.changelingID], a changeling! You have absorbed and taken the form of a human." - changeling.current << "Use say \":g message\" to communicate with your fellow changelings." + changeling.current << "You are [changeling.changeling.changelingID], a changeling! You have absorbed and taken the form of a human." + changeling.current << "Use say \":g message\" to communicate with your fellow changelings." changeling.current << "You must complete the following tasks:" if (changeling.current.mind) @@ -222,7 +222,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" text += "
The changeling was successful!" feedback_add_details("changeling_success","SUCCESS") else - text += "
The changeling has failed." + text += "
The changeling has failed." feedback_add_details("changeling_success","FAIL") text += "
" diff --git a/code/game/gamemodes/changeling/powers/augmented_eyesight.dm b/code/game/gamemodes/changeling/powers/augmented_eyesight.dm index e2f88ac9d9f..e76ed33827c 100644 --- a/code/game/gamemodes/changeling/powers/augmented_eyesight.dm +++ b/code/game/gamemodes/changeling/powers/augmented_eyesight.dm @@ -4,7 +4,7 @@ /obj/effect/proc_holder/changeling/augmented_eyesight name = "Augmented Eyesight" desc = "Creates heat receptors in our eyes and dramatically increases light sensing ability." - helptext = "Grants us night vision and thermal vision. It may be toggled on or off." + helptext = "Grants us night vision and thermal vision. It may be toggled on or off. We will become more vulnerable to flash-based devices while active." chemical_cost = 0 dna_cost = 2 //Would be 1 without thermal vision var/active = 0 //Whether or not vision is enhanced @@ -13,9 +13,11 @@ active = !active if(active) user << "We feel a minute twitch in our eyes, and darkness creeps away." + user.weakeyes = 1 else user << "Our vision dulls. Shadows gather." user.sight -= SEE_MOBS + user.weakeyes = 0 while(active) user.see_in_dark = 8 user.see_invisible = 2 diff --git a/code/game/gamemodes/changeling/powers/headcrab.dm b/code/game/gamemodes/changeling/powers/headcrab.dm new file mode 100644 index 00000000000..5970b10de9c --- /dev/null +++ b/code/game/gamemodes/changeling/powers/headcrab.dm @@ -0,0 +1,16 @@ +/obj/effect/proc_holder/changeling/headcrab + name = "Last Resort" + desc = "We sacrifce our current body in a moment of need, stunning and damaging everyone nearby. If a dead body is nearby we infect it to raise again." + chemical_cost = 20 + dna_cost = 1 + req_human = 1 + +/obj/effect/proc_holder/changeling/headcrab/sting_action(var/mob/user) + explosion(get_turf(user),0,0,2,0,silent=1) + var/turf = get_turf(user) + spawn(5) // So it's not killed in explosion + var/mob/living/simple_animal/hostile/headcrab/crab = new(turf) + crab.origin = user.mind + user.gib() + feedback_add_details("changeling_powers","LR") + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm index 98d0a0f18c6..eb77d14ef3d 100644 --- a/code/game/gamemodes/changeling/powers/mutations.dm +++ b/code/game/gamemodes/changeling/powers/mutations.dm @@ -224,9 +224,6 @@ remaining_uses-- return 1 -/obj/item/weapon/shield/changeling/IsReflect() - return 0 - /***************************************\ |*********SPACE SUIT + HELMET***********| diff --git a/code/game/gamemodes/changeling/traitor_chan.dm b/code/game/gamemodes/changeling/traitor_chan.dm index 37535659afb..292cbe9d52a 100644 --- a/code/game/gamemodes/changeling/traitor_chan.dm +++ b/code/game/gamemodes/changeling/traitor_chan.dm @@ -6,6 +6,7 @@ required_players = 0 required_enemies = 1 // how many of each type are required recommended_enemies = 3 + reroll_friendly = 1 var/list/possible_changelings = list() var/const/changeling_amount = 1 //hard limit on changelings if scaling is turned off diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index b4abfb1c20d..0f71d2ee0aa 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -233,7 +233,7 @@ if(cult_mind in cult) cult -= cult_mind cult_mind.current.verbs -= /mob/living/proc/cult_innate_comm - cult_mind.current << "An unfamiliar white light flashes through your mind, cleansing the taint of the dark-one and the memories of your time as his servant with it." + cult_mind.current << "An unfamiliar white light flashes through your mind, cleansing the taint of the dark-one and the memories of your time as his servant with it." cult_mind.memory = "" cult_mind.cult_words = initial(cult_mind.cult_words) update_cult_icons_removed(cult_mind) diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index c7753e7642a..32ae9b5a7e0 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -63,7 +63,7 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", usr.say("[input]") for(var/mob/M in mob_list) if((M.mind && (M.mind in ticker.mode.cult)) || (M in dead_mob_list)) - M << "[input]" + M << "[input]" return @@ -517,9 +517,8 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", M.reagents.add_reagent("unholywater",holy2unholy) return M.take_organ_damage(0,rand(5,20)) //really lucky - 5 hits for a crit - for(var/mob/O in viewers(M, null)) - O.show_message(text("[] beats [] with the arcane tome!", user, M), 1) - M << "You feel searing heat inside!" + M.visible_message("[user] beats [M] with the arcane tome!", \ + "You feel searing heat inside!") /obj/item/weapon/tome/attack_self(mob/living/user as mob) @@ -549,7 +548,7 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", usr.whisper("[input]") for(var/datum/mind/H in ticker.mode.cult) if (H.current) - H.current << "[input]" + H.current << "[input]" return if("Notes") if(usr.get_active_hand() != src) diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 39df1504e1e..babeb58ab51 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -135,11 +135,11 @@ var/list/sacrificed = list() return 1 */ else M << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." - M << "And not a single fuck was given, exterminate the cult at all costs." + M << "And not a single fuck was given, exterminate the cult at all costs." if(ticker.mode.name == "cult") if(M.mind == ticker.mode.sacrifice_target) for(var/mob/living/carbon/human/cultist in cultsinrange) - cultist << "The Chosen One!!
KILL THE CHOSEN ONE!!!
" + cultist << "The Chosen One!!
KILL THE CHOSEN ONE!!!
" return 0 else for(var/mob/living/carbon/human/cultist in cultsinrange) @@ -703,7 +703,7 @@ var/list/sacrificed = list() if(prob(30)) ticker.mode.grant_runeword(usr) stone_or_gib(M) - for(var/mob/victim in src.loc) //TO-DO: Move the shite above into the mob's own sac_act - see /mob/living/simple_animal/corgi/sac_act for an example + for(var/mob/victim in src.loc) //TO-DO: Move the shite above into the mob's own sac_act - see /mob/living/simple_animal/pet/corgi/sac_act for an example victim.sac_act(src, victim) //Sacrifice procs are now seperate per mob, this allows us to allow sacrifice on as many mob types as we want without making an already clunky system worse /* for(var/mob/living/carbon/alien/A) for(var/mob/K in cultsinrange) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 795beb6fdf2..64f1d779b34 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -98,14 +98,20 @@ ///Allows rounds to basically be "rerolled" should the initial premise fall through /datum/game_mode/proc/convert_roundtype() var/list/datum/game_mode/runnable_modes = config.get_runnable_modes() + var/list/datum/game_mode/usable_modes = list() for(var/datum/game_mode/G in runnable_modes) - if(!G.reroll_friendly) del(G) + if(G.reroll_friendly) + usable_modes += G + else + del(G) SSshuttle.emergencyNoEscape = 0 //Time to get the fuck out of here - if(!runnable_modes) return 0 + if(!usable_modes) + message_admins("Convert_roundtype failed due to no valid modes to convert to. Please report this error to the Coders.") + return 0 - replacementmode = pickweight(runnable_modes) + replacementmode = pickweight(usable_modes) switch(SSshuttle.emergency.mode) //Rounds on the verge of ending don't get new antags, they just run out if(SHUTTLE_STRANDED, SHUTTLE_ESCAPE) @@ -115,6 +121,7 @@ return 1 if(world.time >= (config.midround_antag_time_check * 600)) + message_admins("Convert_roundtype failed due to round length. Limit is [config.midround_antag_time_check] minutes.") return 0 var/living_crew = 0 @@ -123,6 +130,7 @@ if(Player.mind && Player.stat != DEAD && !isnewplayer(Player) &&!isbrain(Player)) living_crew++ if(living_crew / joined_player_list.len <= config.midround_antag_life_check) //If a lot of the player base died, we start fresh + message_admins("Convert_roundtype failed due to too many dead people. Limit is [config.midround_antag_life_check * 100]% living crew") return 0 var/list/antag_canadates = list() @@ -132,6 +140,7 @@ antag_canadates += H if(!antag_canadates) + message_admins("Convert_roundtype failed due to no antag canadates.") return 0 antag_canadates = shuffle(antag_canadates) @@ -148,7 +157,6 @@ replacementmode.make_antag_chance(H) round_converted = 2 message_admins("The roundtype has been converted, antagonists may have been created") - return 1 ///process() @@ -352,7 +360,7 @@ proc/display_roundstart_logout_report() continue //AFK client if(L.stat) if(L.suiciding) //Suicider - msg += "[L.name] ([L.ckey]), the [L.job] (Suicide)\n" + msg += "[L.name] ([L.ckey]), the [L.job] (Suicide)\n" continue //Disconnected client if(L.stat == UNCONSCIOUS) msg += "[L.name] ([L.ckey]), the [L.job] (Dying)\n" @@ -366,17 +374,17 @@ proc/display_roundstart_logout_report() if(D.mind && D.mind.current == L) if(L.stat == DEAD) if(L.suiciding) //Suicider - msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (Suicide)\n" + msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (Suicide)\n" continue //Disconnected client else msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (Dead)\n" continue //Dead mob, ghost abandoned else if(D.can_reenter_corpse) - msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (This shouldn't appear.)\n" + msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (This shouldn't appear.)\n" continue //Lolwhat else - msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (Ghosted)\n" + msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (Ghosted)\n" continue //Ghosted while alive @@ -418,4 +426,4 @@ proc/display_roundstart_logout_report() if(!isnum(enemy_minimum_age)) return 0 - return max(0, enemy_minimum_age - C.player_age) \ No newline at end of file + return max(0, enemy_minimum_age - C.player_age) diff --git a/code/game/gamemodes/malfunction/malfunction.dm b/code/game/gamemodes/malfunction/malfunction.dm index 8c6a2ef27eb..bc4e20ba0fc 100644 --- a/code/game/gamemodes/malfunction/malfunction.dm +++ b/code/game/gamemodes/malfunction/malfunction.dm @@ -90,7 +90,7 @@ /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 << "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 << "The process takes one minute per APC, during which you cannot interface with any other station objects." @@ -156,6 +156,8 @@ priority_announce("Hostile enviroment resolved. You have 3 minutes to board the Emergency Shuttle.", null, 'sound/AI/shuttledock.ogg', "Priority") SSshuttle.emergencyNoEscape = 0 malf_mode_declared = 0 + if(get_security_level() == "delta") + set_security_level("red") round_converted = convert_roundtype() else return 1 diff --git a/code/game/gamemodes/monkey/monkey.dm b/code/game/gamemodes/monkey/monkey.dm index c2b2c835721..66cc61bd322 100644 --- a/code/game/gamemodes/monkey/monkey.dm +++ b/code/game/gamemodes/monkey/monkey.dm @@ -92,8 +92,8 @@ if(!check_monkey_victory()) feedback_set_details("round_end_result","win - monkey win") feedback_set("round_end_result",escaped_monkeys) - world << "The monkeys have overthrown their captors! Eeek eeeek!!" + world << "The monkeys have overthrown their captors! Eeek eeeek!!" else feedback_set_details("round_end_result","loss - staff stopped the monkeys") feedback_set("round_end_result",escaped_monkeys) - world << "The staff managed to contain the monkey infestation!" + world << "The staff managed to contain the monkey infestation!" diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 730462ddfff..9f0eee8e881 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -5,6 +5,7 @@ datum/objective var/target_amount = 0 //If they are focused on a particular number. Steal objectives have their own counter. var/completed = 0 //currently only used for custom objectives. var/dangerrating = 0 //How hard the objective is, essentially. Used for dishing out objectives and checking overall victory. + var/martyr_compatible = 0 //If the objective is compatible with martyr objective, i.e. if you can still do it while dead. datum/objective/New(var/text) if(text) @@ -47,6 +48,7 @@ datum/objective/proc/update_explanation_text() datum/objective/assassinate var/target_role_type=0 dangerrating = 10 + martyr_compatible = 1 datum/objective/assassinate/find_target_by_role(role, role_type=0) target_role_type = role_type @@ -71,6 +73,7 @@ datum/objective/assassinate/update_explanation_text() datum/objective/mutiny var/target_role_type=0 + martyr_compatible = 1 datum/objective/mutiny/find_target_by_role(role, role_type=0) target_role_type = role_type @@ -99,6 +102,7 @@ datum/objective/mutiny/update_explanation_text() datum/objective/maroon var/target_role_type=0 dangerrating = 5 + martyr_compatible = 1 datum/objective/maroon/find_target_by_role(role, role_type=0) target_role_type = role_type @@ -156,6 +160,7 @@ datum/objective/debrain/update_explanation_text() datum/objective/protect//The opposite of killing a dude. var/target_role_type=0 dangerrating = 10 + martyr_compatible = 1 datum/objective/protect/find_target_by_role(role, role_type=0) target_role_type = role_type @@ -183,6 +188,7 @@ datum/objective/protect/update_explanation_text() datum/objective/hijack explanation_text = "Hijack the emergency shuttle by escaping alone." dangerrating = 25 + martyr_compatible = 0 //Technically you won't get both anyway. datum/objective/hijack/check_completion() if(!owner.current || owner.current.stat) @@ -210,6 +216,7 @@ datum/objective/hijack/check_completion() datum/objective/block explanation_text = "Do not allow any organic lifeforms to escape on the shuttle alive." dangerrating = 25 + martyr_compatible = 1 datum/objective/block/check_completion() if(!istype(owner.current, /mob/living/silicon)) @@ -258,6 +265,7 @@ datum/objective/escape/check_completion() datum/objective/escape/escape_with_identity dangerrating = 10 var/target_real_name // Has to be stored because the target's real_name can change over the course of the round + var/target_missing_id datum/objective/escape/escape_with_identity/find_target() target = ..() @@ -266,7 +274,16 @@ datum/objective/escape/escape_with_identity/find_target() datum/objective/escape/escape_with_identity/update_explanation_text() if(target && target.current) target_real_name = target.current.real_name - explanation_text = "Escape on the shuttle or an escape pod with the identity of [target_real_name], the [target.assigned_role] while wearing their identification card." + explanation_text = "Escape on the shuttle or an escape pod with the identity of [target_real_name], the [target.assigned_role]" + var/mob/living/carbon/human/H + if(ishuman(target.current)) + H = target.current + if(H && H.get_id_name() != target_real_name) + target_missing_id = 1 + else + explanation_text += " while wearing their identification card" + explanation_text += "." //Proper punctuation is important! + else explanation_text = "Free Objective." @@ -278,7 +295,7 @@ datum/objective/escape/escape_with_identity/check_completion() var/mob/living/carbon/human/H = owner.current if(..()) if(H.dna.real_name == target_real_name) - if(H.get_id_name()== target_real_name) + if(H.get_id_name()== target_real_name || target_missing_id) return 1 return 0 @@ -295,10 +312,21 @@ datum/objective/survive/check_completion() return 1 +datum/objective/martyr + explanation_text = "Die a glorious death." + dangerrating = 1 + +datum/objective/martyr/check_completion() + if(!owner.current) //Gibbed, etc. + return 1 + if(owner.current && owner.current.stat == DEAD) //You're dead! Yay! + return 1 + return 0 + datum/objective/nuclear explanation_text = "Destroy the station with a nuclear device." - + martyr_compatible = 1 var/global/list/possible_items = list() @@ -306,6 +334,7 @@ datum/objective/steal var/datum/objective_item/targetinfo = null //Save the chosen item datum so we can access it later. var/obj/item/steal_target = null //Needed for custom objectives (they're just items, not datums). dangerrating = 5 //Overridden by the individual item's difficulty, but defaults to 5 for custom objectives. + martyr_compatible = 0 datum/objective/steal/get_target() return steal_target @@ -426,21 +455,30 @@ datum/objective/download/proc/gen_amount_goal() explanation_text = "Download [target_amount] research level\s." return target_amount -datum/objective/download/check_completion() +datum/objective/download/check_completion()//NINJACODE if(!ishuman(owner.current)) return 0 - if(!owner.current || owner.current.stat == 2) + + var/mob/living/carbon/human/H = owner.current + if(!H || H.stat == DEAD) return 0 - if(!(istype(owner.current:wear_suit, /obj/item/clothing/suit/space/space_ninja)&&owner.current:wear_suit:s_initialized)) + + if(!istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja)) return 0 + + var/obj/item/clothing/suit/space/space_ninja/SN = H.wear_suit + if(!SN.s_initialized) + return 0 + var/current_amount - var/obj/item/clothing/suit/space/space_ninja/S = owner.current:wear_suit - if(!S.stored_research.len) + if(!SN.stored_research.len) return 0 else - for(var/datum/tech/current_data in S.stored_research) - if(current_data.level>1) current_amount+=(current_data.level-1) - if(current_amountYou are a member of the revolutionaries' leadership!" + rev_mind.current << "You are a member of the revolutionaries' leadership!" for(var/datum/objective/objective in rev_mind.objectives) rev_mind.current << "Objective #[obj_count]: [objective.explanation_text]" rev_mind.special_role = "Head Revolutionary" diff --git a/code/game/gamemodes/sandbox/h_sandbox.dm b/code/game/gamemodes/sandbox/h_sandbox.dm index 69c8e75be00..976b992f2be 100644 --- a/code/game/gamemodes/sandbox/h_sandbox.dm +++ b/code/game/gamemodes/sandbox/h_sandbox.dm @@ -115,7 +115,7 @@ datum/hSB/Topic(href, href_list) if("hsbtobj") if(!admin) return if(hsboxspawn) - world << "Sandbox: \black[usr.key] has disabled object spawning!" + world << "Sandbox: \black[usr.key] has disabled object spawning!" hsboxspawn = 0 return else diff --git a/code/game/gamemodes/traitor/double_agents.dm b/code/game/gamemodes/traitor/double_agents.dm index 7e4fb0e05fd..6ce9c6a44cf 100644 --- a/code/game/gamemodes/traitor/double_agents.dm +++ b/code/game/gamemodes/traitor/double_agents.dm @@ -5,6 +5,7 @@ required_players = 25 required_enemies = 5 recommended_enemies = 8 + reroll_friendly = 1 traitor_name = "double agent" diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm index 07fc56c7264..af52f87a109 100644 --- a/code/game/gamemodes/traitor/traitor.dm +++ b/code/game/gamemodes/traitor/traitor.dm @@ -111,6 +111,7 @@ else var/is_hijacker = prob(10) + var/martyr_chance = prob(20) var/objective_count = is_hijacker //Hijacking counts towards number of objectives if(!exchange_blue && traitors.len >= 5) //Set up an exchange if there are enough traitors if(!exchange_red) @@ -149,13 +150,28 @@ var/datum/objective/hijack/hijack_objective = new hijack_objective.owner = traitor traitor.objectives += hijack_objective + return + + + var/martyr_compatibility = 1 //You can't succeed in stealing if you're dead. + for(var/datum/objective/O in traitor.objectives) + if(!O.martyr_compatible) + martyr_compatibility = 0 + break + + if(martyr_compatibility && martyr_chance) + var/datum/objective/martyr/martyr_objective = new + martyr_objective.owner = traitor + traitor.objectives += martyr_objective + return + else - if (!(locate(/datum/objective/escape) in traitor.objectives)) + if(!(locate(/datum/objective/escape) in traitor.objectives)) var/datum/objective/escape/escape_objective = new escape_objective.owner = traitor traitor.objectives += escape_objective + return - return /datum/game_mode/proc/greet_traitor(var/datum/mind/traitor) diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index 9ddb0fa2aba..cfe5bdcc276 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -23,7 +23,7 @@ if(charged) new /obj/effect/rend(get_turf(usr), spawn_type, spawn_amt, rend_desc) charged = 0 - user.visible_message("[src] hums with power as [usr] deals a blow to [activate_descriptor] itself!") + user.visible_message("[src] hums with power as [usr] deals a blow to [activate_descriptor] itself!") else user << "The unearthly energies that powered the blade are now dormant." diff --git a/code/game/gamemodes/wizard/rightandwrong.dm b/code/game/gamemodes/wizard/rightandwrong.dm index b66c86966aa..b086e9a1d5d 100644 --- a/code/game/gamemodes/wizard/rightandwrong.dm +++ b/code/game/gamemodes/wizard/rightandwrong.dm @@ -155,10 +155,9 @@ SSevent.reschedule() else //Speed it up - SSevent.frequency_lower = round(SSevent.frequency_lower * 0.8) //1 minute | 48 seconds | 34.8 seconds | 30.7 seconds | 24.6 seconds - SSevent.frequency_upper = round(SSevent.frequency_upper * 0.6) //5 minutes | 3 minutes | 1 minute 48 seconds | 1 minute 4.8 seconds | 38.9 seconds - if(SSevent.frequency_upper < SSevent.frequency_lower) - SSevent.frequency_upper = SSevent.frequency_lower //this can't happen unless somehow multiple spellbooks are used, but just in case + SSevent.frequency_upper -= 600 //The upper bound falls a minute each time, making the AVERAGE time between events lessen + if(SSevent.frequency_upper < SSevent.frequency_lower) //Sanity + SSevent.frequency_upper = SSevent.frequency_lower SSevent.reschedule() message_admins("Summon Events intensifies, events will now occur every [SSevent.frequency_lower / 600] to [SSevent.frequency_upper / 600] minutes.") diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index b7ff72de867..7df187b1aa6 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -106,9 +106,12 @@ dat += "Flesh to Stone (60)
" dat += "This spell will curse a person to immediately turn into an unmoving statue. The effect will eventually wear off if the statue is not destroyed.
" + dat += "Lightning Bolt (30)
" + dat += "Charge up and throw lightning bolt at the nearby enemy. Classic. The longer you charge the more powerful the spell, beware of overcharge however!
" + dat += "Instant Summons (10)
" dat += "This spell can be used to bind a valuable item to you, bringing it to your hand at will. Using this spell while holding the bound item will allow you to unbind it. It does not require wizard garb.
" - if(ticker.mode.name != "ragin' mages") // we totally need summon greentext x100 + if(ticker.mode.name != "ragin' mages" && !config.no_summon_events) // we totally need summon greentext x100 dat += "Summon Events (One time use, persistent global spell)
" dat += "Give Murphy's law a little push and replace all events with special wizard ones that will confound and confuse everyone. Multiple castings increase the rate of these events.
" @@ -124,11 +127,11 @@ dat += "
" - if(!("summon guns" in active_challenges)) + if(!("summon guns" in active_challenges) && !config.no_summon_guns) dat += "Summon Guns (Single use only, global spell)
" dat += "Nothing could possibly go wrong with arming a crew of lunatics just itching for an excuse to kill you. Just be careful not to stand still too long!
" - if(!("summon magic" in active_challenges)) + if(!("summon magic" in active_challenges) && !config.no_summon_magic) dat += "Summon Magic (Single use only, global spell)
" dat += "Share the wonders of magic with the crew and show them why they aren't to be trusted with it at the same time.
" @@ -220,7 +223,7 @@ uses-- /* */ - var/list/available_spells = list(magicmissile = "Magic Missile", fireball = "Fireball", disintegrate = "Disintegrate", disabletech = "Disable Tech", repulse = "Repulse", smoke = "Smoke", blind = "Blind", mindswap = "Mind Transfer", forcewall = "Forcewall", blink = "Blink", teleport = "Teleport", mutate = "Mutate", etherealjaunt = "Ethereal Jaunt", knock = "Knock", barnyardcurse = "The Curse of the Barnyard", fleshtostone = "Flesh to Stone", summonitem = "Instant Summons", summonguns = "Summon Guns", summonmagic = "Summon Magic", summonevents = "Summon Events", staffchange = "Staff of Change", soulstone = "Six Soul Stone Shards and the spell Artificer", necrostone = "A Necromantic Stone", armor = "Mastercrafted Armor Set", staffanimate = "Staff of Animation", staffchaos = "Staff of Chaos", staffdoor = "Staff of Door Creation", wands = "Wand Assortment") + var/list/available_spells = list(magicmissile = "Magic Missile", fireball = "Fireball", disintegrate = "Disintegrate", disabletech = "Disable Tech", repulse = "Repulse", smoke = "Smoke", blind = "Blind", mindswap = "Mind Transfer", forcewall = "Forcewall", blink = "Blink", teleport = "Teleport", mutate = "Mutate", etherealjaunt = "Ethereal Jaunt", knock = "Knock", barnyardcurse = "The Curse of the Barnyard", fleshtostone = "Flesh to Stone", summonitem = "Instant Summons", summonguns = "Summon Guns", summonmagic = "Summon Magic", summonevents = "Summon Events", staffchange = "Staff of Change", soulstone = "Six Soul Stone Shards and the spell Artificer", necrostone = "A Necromantic Stone", armor = "Mastercrafted Armor Set", staffanimate = "Staff of Animation", staffchaos = "Staff of Chaos", staffdoor = "Staff of Door Creation", wands = "Wand Assortment", lightningbolt = "Lightning Bolt") var/already_knows = 0 for(var/obj/effect/proc_holder/spell/aspell in H.mind.spell_list) if(available_spells[href_list["spell_choice"]] == initial(aspell.name)) @@ -318,6 +321,10 @@ feedback_add_details("wizard_spell_learned","IS") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells H.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/summonitem(null) temp = "You have learned instant summons." + if("lightningbolt") + feedback_add_details("wizard_spell_learned","LB") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + H.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/lightning(null) + temp = "You have learned lightning bolt." if("summonguns") feedback_add_details("wizard_spell_learned","SG") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells rightandwrong(0, H, 0) diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index c091c9c3f02..b6a7df9996f 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -25,7 +25,7 @@ wizard.assigned_role = "MODE" wizard.special_role = "Wizard" if(wizardstart.len == 0) - wizard.current << "A starting location for you could not be found, please report this bug!" + wizard.current << "A starting location for you could not be found, please report this bug!" return 0 for(var/datum/mind/wiz in wizards) wiz.current.loc = pick(wizardstart) @@ -115,7 +115,7 @@ /datum/game_mode/proc/greet_wizard(var/datum/mind/wizard, var/you_are=1) if (you_are) - wizard.current << "You are the Space Wizard!" + wizard.current << "You are the Space Wizard!" wizard.current << "The Space Wizards Federation has given you the following tasks:" var/obj_count = 1 @@ -200,6 +200,9 @@ finished = 1 return 1 else + if(SSevent.wizardmode) //If summon events was active, turn it off + SSevent.toggleWizardmode() + SSevent.resetFrequency() return ..() finished = 1 @@ -208,7 +211,7 @@ /datum/game_mode/wizard/declare_completion() if(finished) feedback_set_details("round_end_result","loss - wizard killed") - world << "The wizard[(wizards.len>1)?"s":""] has been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!" + world << "The wizard[(wizards.len>1)?"s":""] has been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!" ..() return 1 diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index 87f12d201e6..81b6adc491c 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -181,8 +181,7 @@ Security Officer H.equip_to_slot_or_del(new /obj/item/clothing/shoes/jackboots(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/vest(H), slot_wear_suit) -// H.equip_to_slot_or_del(new /obj/item/clothing/head/beret/sec(H), slot_head) - H.equip_to_slot_or_del(new /obj/item/clothing/head/helmet(H), slot_head) + H.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/sec(H), slot_head) H.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/black(H), slot_gloves) H.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun/advtaser(H), slot_s_store) H.equip_to_slot_or_del(new /obj/item/device/flash/handheld(H), slot_l_store) diff --git a/code/game/machinery/ai_slipper.dm b/code/game/machinery/ai_slipper.dm index 734f483cf55..386c11d09c9 100644 --- a/code/game/machinery/ai_slipper.dm +++ b/code/game/machinery/ai_slipper.dm @@ -96,7 +96,7 @@ if(cooldown_on || disabled) return else - new /obj/effect/effect/foam(src.loc) + PoolOrNew(/obj/effect/effect/foam, loc) src.uses-- cooldown_on = 1 cooldown_time = world.timeofday + 100 diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 99fba02a701..5450c05c626 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -301,12 +301,12 @@ Release Pressure: - air
" + logmsg = "Valve was closed by [key_name(usr)], stopping the transfer into the air
" else if (holding) logmsg = "Valve was opened by [key_name(usr)], starting the transfer into the [holding]
" else - logmsg = "Valve was opened by [key_name(usr)], starting the transfer into the air
" + 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)") log_admin("[key_name(usr)] opened a canister that contains plasma at [x], [y], [z]") diff --git a/code/game/machinery/bots/bots.dm b/code/game/machinery/bots/bots.dm index 2dddc0aeb9f..f2bb4d9c38e 100644 --- a/code/game/machinery/bots/bots.dm +++ b/code/game/machinery/bots/bots.dm @@ -203,7 +203,7 @@ usr << "[text_hack]" bot_reset() else if(!hacked) - usr << "[text_dehack_fail]" + usr << "[text_dehack_fail]" else emagged = 0 hacked = 0 @@ -323,7 +323,7 @@ pulse2.dir = pick(cardinal) spawn(10) - pulse2.delete() + qdel(pulse2) if (on) turn_off() spawn(severity*300) diff --git a/code/game/machinery/bots/cleanbot.dm b/code/game/machinery/bots/cleanbot.dm index 69ed1cd26df..b9b28435749 100644 --- a/code/game/machinery/bots/cleanbot.dm +++ b/code/game/machinery/bots/cleanbot.dm @@ -157,7 +157,7 @@ text("[on ? "On" : "Off"]")) if(prob(5)) //Spawns foam! visible_message("[src] whirs and bubbles violently, before releasing a plume of froth!") - new /obj/effect/effect/foam(loc) + PoolOrNew(/obj/effect/effect/foam, loc) else if (prob(5)) visible_message("[src] makes an excited beeping booping sound!") @@ -240,7 +240,7 @@ text("[on ? "On" : "Off"]")) /obj/machinery/bot/cleanbot/explode() on = 0 - visible_message("[src] blows apart!") + visible_message("[src] blows apart!") var/turf/Tsec = get_turf(src) new /obj/item/weapon/reagent_containers/glass/bucket(Tsec) diff --git a/code/game/machinery/bots/ed209bot.dm b/code/game/machinery/bots/ed209bot.dm index df69dc9c78b..87f53d40a0c 100644 --- a/code/game/machinery/bots/ed209bot.dm +++ b/code/game/machinery/bots/ed209bot.dm @@ -37,14 +37,6 @@ bot_type = SEC_BOT bot_filter = RADIO_SECBOT - //List of weapons that secbots will not arrest for - var/safe_weapons = list(\ - /obj/item/weapon/gun/energy/laser/bluetag,\ - /obj/item/weapon/gun/energy/laser/redtag,\ - /obj/item/weapon/gun/energy/laser/practice,\ - /obj/item/weapon/melee/classic_baton/telescopic,\ - /obj/item/weapon/gun/energy/kinetic_accelerator) - /obj/item/weapon/ed209_assembly name = "\improper ED-209 assembly" @@ -206,6 +198,17 @@ Auto Patrol[]"}, icon_state = "[lasercolor]ed209[on]" set_weapon() +/obj/machinery/bot/ed209/bullet_act(var/obj/item/projectile/Proj) + if(istype(Proj ,/obj/item/projectile/beam)||istype(Proj,/obj/item/projectile/bullet)) + if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE)) + if (!Proj.nodamage && Proj.damage < src.health) + threatlevel = Proj.firer.assess_threat(src) + threatlevel += 6 + if(threatlevel >= 4) + target = Proj.firer + mode = BOT_HUNT + ..() + /obj/machinery/bot/ed209/bot_process() if (!..()) return @@ -392,9 +395,8 @@ Auto Patrol[]"}, continue /obj/machinery/bot/ed209/proc/check_for_weapons(var/obj/item/slot_item) - if(istype(slot_item, /obj/item/weapon/gun) || istype(slot_item, /obj/item/weapon/melee)) - if(!(slot_item.type in safe_weapons)) - return 1 + if(slot_item && slot_item.needs_permit) + return 1 return 0 /* terrible @@ -407,7 +409,7 @@ Auto Patrol[]"}, /obj/machinery/bot/ed209/explode() walk_to(src,0) - visible_message("[src] blows apart!") + visible_message("[src] blows apart!") var/turf/Tsec = get_turf(src) var/obj/item/weapon/ed209_assembly/Sa = new /obj/item/weapon/ed209_assembly(Tsec) @@ -513,7 +515,7 @@ Auto Patrol[]"}, pulse2.anchored = 1 pulse2.dir = pick(cardinal) spawn(10) - pulse2.delete() + qdel(pulse2) var/list/mob/living/carbon/targets = new for (var/mob/living/carbon/C in view(12,src)) if (C.stat==2) diff --git a/code/game/machinery/bots/floorbot.dm b/code/game/machinery/bots/floorbot.dm index a2112f53b2e..17ccdcc5830 100644 --- a/code/game/machinery/bots/floorbot.dm +++ b/code/game/machinery/bots/floorbot.dm @@ -446,7 +446,7 @@ obj/machinery/bot/floorbot/process_scan(var/scan_target) /obj/machinery/bot/floorbot/explode() on = 0 - visible_message("[src] blows apart!") + visible_message("[src] blows apart!") var/turf/Tsec = get_turf(src) var/obj/item/weapon/storage/toolbox/mechanical/N = new /obj/item/weapon/storage/toolbox/mechanical(Tsec) diff --git a/code/game/machinery/bots/medbot.dm b/code/game/machinery/bots/medbot.dm index 2dafe5746f3..4445626eb5e 100644 --- a/code/game/machinery/bots/medbot.dm +++ b/code/game/machinery/bots/medbot.dm @@ -51,6 +51,17 @@ treatment_fire = "omnizine" treatment_tox = "omnizine" +/obj/machinery/bot/medbot/derelict + name = "\improper Old Medibot" + desc = "Looks like it hasn't been modified since the late 2080s." + skin = "bezerk" + heal_threshold = 0 + declare_crit = 0 + treatment_oxy = "pancuronium" + treatment_brute = "pancuronium" + treatment_fire = "sodium_thiopental" + treatment_tox = "sodium_thiopental" + /obj/item/weapon/firstaid_arm_assembly name = "incomplete medibot assembly." desc = "A first aid kit with a robot arm permanently grafted to it." @@ -479,7 +490,7 @@ if(reagent_id == "internal_beaker") if(use_beaker && reagent_glass && reagent_glass.reagents.total_volume) reagent_glass.reagents.trans_to(patient,injection_amount) //Inject from beaker instead. - reagent_glass.reagents.reaction(patient, 2) + reagent_glass.reagents.reaction(patient, INGEST) else patient.reagents.add_reagent(reagent_id,injection_amount) C.visible_message("[src] injects [patient] with the syringe!", \ @@ -500,7 +511,7 @@ /obj/machinery/bot/medbot/explode() on = 0 - visible_message("[src] blows apart!") + visible_message("[src] blows apart!") var/turf/Tsec = get_turf(src) new /obj/item/weapon/storage/firstaid(Tsec) diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm index a574b24ccbc..c810c626fbe 100644 --- a/code/game/machinery/bots/mulebot.dm +++ b/code/game/machinery/bots/mulebot.dm @@ -913,7 +913,7 @@ obj/machinery/bot/mulebot/bot_reset() /obj/machinery/bot/mulebot/explode() - visible_message("[src] blows apart!") + visible_message("[src] blows apart!") var/turf/Tsec = get_turf(src) new /obj/item/device/assembly/prox_sensor(Tsec) diff --git a/code/game/machinery/bots/secbot.dm b/code/game/machinery/bots/secbot.dm index f5bd7dada47..0596bbe5b5e 100644 --- a/code/game/machinery/bots/secbot.dm +++ b/code/game/machinery/bots/secbot.dm @@ -27,15 +27,6 @@ bot_type = SEC_BOT bot_filter = RADIO_SECBOT - //List of weapons that secbots will not arrest for - var/safe_weapons = list(\ - /obj/item/weapon/gun/energy/laser/bluetag,\ - /obj/item/weapon/gun/energy/laser/redtag,\ - /obj/item/weapon/gun/energy/laser/practice,\ - /obj/item/weapon/melee/classic_baton/telescopic,\ - /obj/item/weapon/gun/energy/kinetic_accelerator) - - /obj/machinery/bot/secbot/beepsky name = "Officer Beep O'sky" desc = "It's Officer Beep O'sky! Powered by a potato and a shot of whiskey." @@ -189,6 +180,17 @@ Auto Patrol: []"}, declare_arrests = 0 icon_state = "secbot[on]" +/obj/machinery/bot/secbot/bullet_act(var/obj/item/projectile/Proj) + if(istype(Proj ,/obj/item/projectile/beam)||istype(Proj,/obj/item/projectile/bullet)) + if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE)) + if (!Proj.nodamage && Proj.damage < src.health) + threatlevel = Proj.firer.assess_threat(src) + threatlevel += 6 + if(threatlevel >= 4) + target = Proj.firer + mode = BOT_HUNT + ..() + /obj/machinery/bot/secbot/bot_process() if (!..()) return @@ -350,15 +352,14 @@ Auto Patrol: []"}, else continue /obj/machinery/bot/secbot/proc/check_for_weapons(var/obj/item/slot_item) - if(istype(slot_item, /obj/item/weapon/gun) || istype(slot_item, /obj/item/weapon/melee)) - if(!(slot_item.type in safe_weapons)) - return 1 + if(slot_item && slot_item.needs_permit) + return 1 return 0 /obj/machinery/bot/secbot/explode() walk_to(src,0) - visible_message("[src] blows apart!") + visible_message("[src] blows apart!") var/turf/Tsec = get_turf(src) var/obj/item/weapon/secbot_assembly/Sa = new /obj/item/weapon/secbot_assembly(Tsec) @@ -392,7 +393,14 @@ Auto Patrol: []"}, ..() return - if(type != /obj/item/clothing/head/helmet) //Eh, but we don't want people making secbots out of space helmets. + if(type != /obj/item/clothing/head/helmet/sec) //Eh, but we don't want people making secbots out of space helmets. + return + + if(!helmetCam) //I am so sorry for this. I could not think of a less terrible (and lazy) way. + user << "[src] needs to have a camera attached first." + return + if(F) //Has a flashlight. Player must remove it, else it will be lost forever. + user << "The mounted flashlight is in the way, remove it first." return if(S.secured) @@ -458,7 +466,7 @@ Auto Patrol: []"}, else if(istype(I, /obj/item/weapon/screwdriver)) if(!build_step) new /obj/item/device/assembly/signaler(get_turf(src)) - new /obj/item/clothing/head/helmet(get_turf(src)) + new /obj/item/clothing/head/helmet/sec(get_turf(src)) user << "You disconnect the signaler from the helmet." qdel(src) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 8a8b1836eae..f93b7f48696 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -214,15 +214,6 @@ user << "Camera bugged." src.bug = W src.bug.bugged_cameras[src.c_tag] = src - else if(istype(W, /obj/item/weapon/melee/energy/blade))//Putting it here last since it's a special case. I wonder if there is a better way to do these than type casting. - deactivate(user,2)//Here so that you can disconnect anyone viewing the camera, regardless if it's on or off. - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, loc) - spark_system.start() - playsound(loc, 'sound/weapons/blade1.ogg', 50, 1) - playsound(loc, "sparks", 50, 1) - visible_message("[user] has sliced the camera apart with an energy blade!") - qdel(src) else if(istype(W, /obj/item/device/laser_pointer)) var/obj/item/device/laser_pointer/L = W L.laser_act(src, user) @@ -323,17 +314,15 @@ return null -/obj/machinery/camera/proc/weld(var/obj/item/weapon/weldingtool/WT, var/mob/user) +/obj/machinery/camera/proc/weld(var/obj/item/weapon/weldingtool/WT, var/mob/living/user) if(busy) return 0 - if(!WT.isOn()) + if(!WT.remove_fuel(0, user)) return 0 - // Do after stuff here user << "You start to weld [src]." playsound(src.loc, 'sound/items/Welder.ogg', 50, 1) - WT.eyecheck(user) busy = 1 if(do_after(user, 100)) busy = 0 @@ -342,3 +331,18 @@ return 1 busy = 0 return 0 + + +/obj/machinery/camera/portable //Cameras which are placed inside of things, such as helmets. + var/turf/prev_turf + +/obj/machinery/camera/portable/New() + ..() + assembly.state = 0 //These cameras are portable, and so shall be in the portable state if removed. + assembly.anchored = 0 + assembly.update_icon() + +/obj/machinery/camera/portable/process() //Updates whenever the camera is moved. + if(cameranet && get_turf(src) != prev_turf) + cameranet.updatePortableCamera(src) + prev_turf = get_turf(src) \ No newline at end of file diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm index 5e36e6ff1af..10d4c1716b6 100644 --- a/code/game/machinery/camera/camera_assembly.dm +++ b/code/game/machinery/camera/camera_assembly.dm @@ -149,16 +149,15 @@ if(!anchored) ..() -/obj/item/weapon/camera_assembly/proc/weld(var/obj/item/weapon/weldingtool/WT, var/mob/user) +/obj/item/weapon/camera_assembly/proc/weld(var/obj/item/weapon/weldingtool/WT, var/mob/living/user) if(busy) return 0 - if(!WT.isOn()) + if(!WT.remove_fuel(0, user)) return 0 user << "You start to weld \the [src].." playsound(src.loc, 'sound/items/Welder.ogg', 50, 1) - WT.eyecheck(user) busy = 1 if(do_after(user, 20)) busy = 0 diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm index d672301e750..3e0dac86a35 100644 --- a/code/game/machinery/camera/tracking.dm +++ b/code/game/machinery/camera/tracking.dm @@ -73,8 +73,11 @@ //Cameras can't track people wearing an agent card or a ninja hood. if(H.wear_id && istype(H.wear_id.GetID(), /obj/item/weapon/card/id/syndicate)) continue - if(istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja) && (H.head.flags & NODROP)) - continue + //Generic variable who's existance is to blame on shitty old ninja code + if(istype(H.head, /obj/item/clothing/head)) + var/obj/item/clothing/head/hat = H.head + if(hat.blockTracking) + continue // Now, are they viewable by a camera? (This is last because it's the most intensive check) if(!near_camera(M)) @@ -127,10 +130,12 @@ U << "Follow camera mode terminated." U.cameraFollow = null return - if(istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja) && (H.head.flags & NODROP)) - U << "Follow camera mode terminated." - U.cameraFollow = null - return + if(istype(H.head, /obj/item/clothing/head)) + var/obj/item/clothing/head/hat = H.head + if(hat.blockTracking) + U << "Follow camera mode terminated." + U.cameraFollow = null + return if(H.digitalcamo) U << "Follow camera mode terminated." U.cameraFollow = null diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm index d3b042a86b4..696952e9b89 100644 --- a/code/game/machinery/computer/ai_core.dm +++ b/code/game/machinery/computer/ai_core.dm @@ -214,7 +214,7 @@ That prevents a few funky behaviors. 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." + U << "ERROR: AI flush is in progress, cannot execute transfer protocol." return switch(choice) @@ -227,13 +227,13 @@ That prevents a few funky behaviors. 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." + 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~ + 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. @@ -307,8 +307,8 @@ That prevents a few funky behaviors. T.occupier.cancel_camera() T.occupier = null else if (C.contents.len) - U << "ERROR: Artificial intelligence detected on terminal." + U << "ERROR: Artificial intelligence detected on terminal." else if (T.active) - U << "ERROR: Reconstruction in progress." + U << "ERROR: Reconstruction in progress." else if (!T.occupier) - U << "ERROR: Unable to locate artificial intelligence." \ No newline at end of file + U << "ERROR: Unable to locate artificial intelligence." \ No newline at end of file diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 1bcc4decc8e..76d084ffba7 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -3,35 +3,35 @@ desc = "random arcade machine" icon = 'icons/obj/computer.dmi' icon_state = "arcade" - var/list/prizes = list( /obj/item/weapon/storage/box/snappops = 2, - /obj/item/toy/AI = 2, - /obj/item/clothing/under/syndicate/tacticool = 2, - /obj/item/toy/sword = 2, - /obj/item/toy/gun = 2, - /obj/item/toy/crossbow = 2, - /obj/item/weapon/storage/box/fakesyndiesuit = 2, - /obj/item/weapon/storage/fancy/crayons = 2, - /obj/item/toy/spinningtoy = 2, - /obj/item/toy/prize/ripley = 1, - /obj/item/toy/prize/fireripley = 1, - /obj/item/toy/prize/deathripley = 1, - /obj/item/toy/prize/gygax = 1, - /obj/item/toy/prize/durand = 1, - /obj/item/toy/prize/honk = 1, - /obj/item/toy/prize/marauder = 1, - /obj/item/toy/prize/seraph = 1, - /obj/item/toy/prize/mauler = 1, - /obj/item/toy/prize/odysseus = 1, - /obj/item/toy/prize/phazon = 1, - /obj/item/toy/prize/reticence = 1, - /obj/item/toy/cards/deck = 2, - /obj/item/toy/nuke = 2, - /obj/item/toy/minimeteor = 2, - /obj/item/toy/carpplushie = 2, - /obj/item/toy/foamblade = 2, - /obj/item/toy/redbutton = 2, - /obj/item/toy/owl = 2, - /obj/item/toy/griffin = 2 + var/list/prizes = list( /obj/item/weapon/storage/box/snappops = 2, + /obj/item/toy/AI = 2, + /obj/item/clothing/under/syndicate/tacticool = 2, + /obj/item/toy/sword = 2, + /obj/item/toy/gun = 2, + /obj/item/weapon/gun/projectile/shotgun/toy/crossbow = 2, + /obj/item/weapon/storage/box/fakesyndiesuit = 2, + /obj/item/weapon/storage/fancy/crayons = 2, + /obj/item/toy/spinningtoy = 2, + /obj/item/toy/prize/ripley = 1, + /obj/item/toy/prize/fireripley = 1, + /obj/item/toy/prize/deathripley = 1, + /obj/item/toy/prize/gygax = 1, + /obj/item/toy/prize/durand = 1, + /obj/item/toy/prize/honk = 1, + /obj/item/toy/prize/marauder = 1, + /obj/item/toy/prize/seraph = 1, + /obj/item/toy/prize/mauler = 1, + /obj/item/toy/prize/odysseus = 1, + /obj/item/toy/prize/phazon = 1, + /obj/item/toy/prize/reticence = 1, + /obj/item/toy/cards/deck = 2, + /obj/item/toy/nuke = 2, + /obj/item/toy/minimeteor = 2, + /obj/item/toy/carpplushie = 2, + /obj/item/toy/foamblade = 2, + /obj/item/toy/redbutton = 2, + /obj/item/toy/owl = 2, + /obj/item/toy/griffin = 2 ) /obj/machinery/computer/arcade/New() @@ -367,9 +367,27 @@ else if(food <= 0) dat += "
You ran out of food and starved." + if(emagged) + user.nutrition = 0 //yeah you pretty hongry + user << "Your body instantly contracts to that of one who has not eaten in months. Agonizing cramps seize you as you fall to the floor." if(fuel <= 0) dat += "
You ran out of fuel, and drift, slowly, into a star." + if(emagged) + var/mob/living/M = user + M.adjust_fire_stacks(5) + M.IgniteMob() //flew into a star, so you're on fire + user << "You feel an immense wave of heat emanate from the arcade machine. Your skin bursts into flames." dat += "

OK...

" + + if(emagged) + user << "You're never going to make it to Orion..." + user.death() + emagged = 0 //removes the emagged status after you lose + playing = 0 //also a new game + name = "The Orion Trail" + desc = "Learn how our ancestors got to Orion, and have fun in the process!" + + else if(event) dat = eventdat else if(playing) @@ -427,6 +445,77 @@ if(prob(75)) event = pickweight(events) event() + if(emagged) + var/mob/living/carbon/M = usr //for some vars + switch(event) + if("Raiders") + if(prob(50)) + usr << "You hear battle shouts. The tramping of boots on cold metal. Screams of agony. The rush of venting air. Are you going insane?" + M.hallucination += 30 + else + usr << "Something strikes you from behind! It hurts like hell and feel like a blunt weapon, but nothing is there..." + M.take_organ_damage(30) + playsound(loc, 'sound/weapons/genhit2.ogg', 100, 1) + if("Illness") + var/severity = rand(1,3) //pray to RNGesus. PRAY, PIGS + if(severity == 1) + M << "You suddenly feel slightly nauseous." //got off lucky + if(severity == 2) + usr << "You suddenly feel extremely nauseous and hunch over until it passes." + M.Stun(3) + if(severity >= 3) //you didn't pray hard enough + M << "An overpowering wave of nausea consumes over you. You hunch over, your stomach's contents preparing for a spectacular exit." + M.Stun(5) + sleep(30) + M.visible_message("[M] throws up!", "You violently throw up!") + playsound(loc, 'sound/effects/splat.ogg', 50, 1) + M.nutrition -= 50 //lose a lot of food + var/turf/location = usr.loc + if(istype(location, /turf/simulated)) + location.add_vomit_floor(src, 1) + if("Interstellar Flux") + if(prob(75)) + M.Weaken(3) + M.visible_message("[M] is swept off their feet!", "A sudden gust of powerful wind slams you into the floor!") + M.take_organ_damage(25) + playsound(src.loc, 'sound/weapons/Genhit.ogg', 100, 1) + else + M << "A violent gale blows past you, and you barely manage to stay standing!" + if("Collision") //by far the most damaging event + if(prob(90)) + playsound(src.loc, 'sound/effects/bang.ogg', 100, 1) + var/turf/simulated/floor/F + for(F in orange(1, src)) + F.ChangeTurf(/turf/space) + src.visible_message("Something slams into the floor around [src], exposing it to space!") + if(hull) + sleep(10) + src.visible_message("A new floor suddenly appears around [src]. What the hell?") + playsound(src.loc, 'sound/weapons/Genhit.ogg', 100, 1) + var/turf/space/T + for(T in orange(1, src)) + T.ChangeTurf(/turf/simulated/floor/plating/) + else + src.visible_message("Something slams into the floor around [src] - luckily, it didn't get through!") + playsound(src.loc, 'sound/effects/bang.ogg', 50, 1) + if("Malfunction") + playsound(src.loc, 'sound/effects/EMPulse.ogg', 50, 1) + src.visible_message("[src] malfunctions, randomizing in-game stats!") + var/oldfood = food + var/oldfuel = fuel + food = rand(10,80) / rand(1,2) + fuel = rand(10,60) / rand(1,2) + if(electronics) + sleep(10) + if(oldfuel > fuel && oldfood > food) + src.audible_message("[src] lets out a somehow reassuring chime.") + else if(oldfuel < fuel || oldfood < food) + src.audible_message("[src] lets out a somehow ominous chime.") + food = oldfood + fuel = oldfuel + playsound(src.loc, 'sound/machines/chime.ogg', 50, 1) + + else if(href_list["newgame"]) //Reset everything newgame() else if(href_list["menu"]) //back to the main menu @@ -467,6 +556,15 @@ if(prob(75)) event = "BlackHole" event() + if(emagged) //has to be here because otherwise it doesn't work + playsound(src.loc, 'sound/effects/supermatter.ogg', 100, 1) + src.visible_message("A miniature black hole suddenly appears in front of [src], devouring [usr] alive!") + usr.Stun(10) //you can't run :^) + var/S = new /obj/singularity/academy(usr.loc) + emagged = 0 //immediately removes emagged status so people can't kill themselves by sprinting up and interacting + sleep(50) + src.visible_message("[S] winks out, just as suddenly as it appeared.") + qdel(S) else event = null turns += 1 @@ -499,7 +597,6 @@ eventdat += "
Fortunately you fended them off without any trouble." eventdat += "

Continue

" eventdat += "

Close

" - else if(event == "Interstellar Flux") eventdat += "This region of space is highly turbulent.
If we go slowly we may avoid more damage, but if we keep our speed we won't waste supplies." eventdat += "
What will you do?" @@ -513,7 +610,6 @@ alive -= 1 eventdat += "

Continue

" eventdat += "

Close

" - else if(event == "Breakdown") eventdat += "Oh no! The engine has broken down!" eventdat += "
You can repair it with an engine part, or you can make repairs for 3 days." @@ -560,4 +656,60 @@ /obj/machinery/computer/arcade/orion_trail/proc/win() playing = 0 - prizevend() + if(emagged) + new /obj/item/weapon/orion_ship(src.loc) + message_admins("[key_name_admin(usr)] made it to Orion on an emagged machine and got an explosive toy ship.") + log_game("[key_name(usr)] made it to Orion on an emagged machine and got an explosive toy ship.") + else + prizevend() + emagged = 0 + name = "The Orion Trail" + desc = "Learn how our ancestors got to Orion, and have fun in the process!" + +/obj/machinery/computer/arcade/orion_trail/emag_act(mob/user as mob) + if(!emagged) + user << "You override the cheat code menu and skip to Cheat #[rand(1, 50)]: Realism Mode." + name = "The Orion Trail: Realism Edition" + desc = "Learn how our ancestors got to Orion, and try not to die in the process!" + newgame() + emagged = 1 + +/obj/item/weapon/orion_ship + name = "model settler ship" + desc = "A model spaceship, it looks like those used back in the day when travelling to Orion! It even has a miniature FX-293 reactor, which was renowned for its instability and tendency to explode..." + icon = 'icons/obj/toy.dmi' + icon_state = "ship" + w_class = 2 + var/active = 0 //if the ship is on + +/obj/item/weapon/orion_ship/examine(mob/user) + ..() + if(!(in_range(user, src))) + return + if(!active) + user << "There's a little switch on the bottom. It's flipped down." + else + user << "There's a little switch on the bottom. It's flipped up." + +/obj/item/weapon/orion_ship/attack_self(mob/user) //Minibomb-level explosion. Should probably be more because of how hard it is to survive the machine! Also, just over a 5-second fuse + if(active) + return + + message_admins("[key_name_admin(usr)] primed an explosive Orion ship for detonation.") + log_game("[key_name(usr)] primed an explosive Orion ship for detonation.") + + user << "You flip the switch on the underside of [src]." + active = 1 + src.visible_message("[src] softly beeps and whirs to life!") + playsound(src.loc, 'sound/machines/defib_SaftyOn.ogg', 25, 1) + say("This is ship ID #[rand(1,1000)] to Orion Port Authority. We're coming in for landing, over.") + sleep(20) + src.visible_message("[src] begins to vibrate...") + say("Uh, Port? Having some issues with our reactor, could you check it out? Over.") + sleep(30) + say("Oh, God! Code Eight! CODE EIGHT! IT'S GONNA BL-") + playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 25, 1) + sleep(3.6) + src.visible_message("[src] explodes!") + explosion(src.loc, 1,2,4, flame_range = 3) + qdel(src) diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index e674e57bcac..1c0138f4c66 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 if(..()) return if (src.z > ZLEVEL_STATION) - usr << "Unable to establish a connection: \black You're too far away from the station!" + usr << "Unable to establish a connection: \black You're too far away from the station!" return usr.set_machine(src) @@ -339,7 +339,7 @@ var/const/CALL_SHUTTLE_REASON_LENGTH = 12 if(..()) return if (src.z > 6) - user << "Unable to establish a connection: \black You're too far away from the station!" + user << "Unable to establish a connection: \black You're too far away from the station!" return user.set_machine(src) diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm index 6f5f4334f02..dd5674f8f30 100644 --- a/code/game/machinery/computer/crew.dm +++ b/code/game/machinery/computer/crew.dm @@ -22,7 +22,7 @@ /obj/machinery/computer/crew/Topic(href, href_list) if(..()) return if (src.z > 6) - usr << "Unable to establish a connection: \black You're too far away from the station!" + usr << "Unable to establish a connection: \black You're too far away from the station!" return if( href_list["close"] ) usr << browse(null, "window=crewcomp") diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm index 1b9c7ca9682..3f677d16775 100644 --- a/code/game/machinery/computer/robot.dm +++ b/code/game/machinery/computer/robot.dm @@ -30,7 +30,7 @@ /obj/machinery/computer/robotics/interact(var/mob/user as mob) if (src.z > 6) - user << "Unable to establish a connection: \black You're too far away from the station!" + user << "Unable to establish a connection: \black You're too far away from the station!" return user.set_machine(src) var/dat diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index 1bb6fae821f..f4f5f3c9d00 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -37,7 +37,7 @@ if(..()) return if(src.z > 6) - user << "Unable to establish a connection: \black You're too far away from the station!" + user << "Unable to establish a connection: \black You're too far away from the station!" return var/dat diff --git a/code/game/machinery/computer/shuttle.dm b/code/game/machinery/computer/shuttle.dm index 73be97cc324..692bf826437 100644 --- a/code/game/machinery/computer/shuttle.dm +++ b/code/game/machinery/computer/shuttle.dm @@ -92,7 +92,7 @@ else if(istype(A, /mob/living)) // You Shall Not Pass! var/mob/living/M = A - if(!M.lying && !istype(M, /mob/living/carbon/monkey) && !istype(M, /mob/living/carbon/slime)) //If your not laying down, or a small creature, no pass. + if(!M.lying && !ismonkey(M) && !isslime(M)) //If your not laying down, or a small creature, no pass. return 0 return ..() @@ -132,6 +132,9 @@ icon_state = "supply" req_access = list(access_cargo) circuit = /obj/item/weapon/circuitboard/supplycomp + verb_say = "flashes" + verb_ask = "flashes" + verb_exclaim = "flashes" var/temp = null var/reqtime = 0 //Cooldown for requisitions - Quarxink var/hacked = 0 @@ -150,6 +153,9 @@ icon = 'icons/obj/computer.dmi' icon_state = "request" circuit = /obj/item/weapon/circuitboard/ordercomp + verb_say = "flashes" + verb_ask = "flashes" + verb_exclaim = "flashes" var/temp = null var/reqtime = 0 //Cooldown for requisitions - Quarxink - var/last_viewed_group = "categories" \ No newline at end of file + var/last_viewed_group = "categories" diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index 5e77e908e94..5c823178fad 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -381,6 +381,16 @@ to destroy them and players will be able to make replacements. /obj/item/weapon/stock_parts/manipulator = 1, /obj/item/weapon/stock_parts/console_screen = 1, /obj/item/weapon/stock_parts/cell = 1) + +/obj/item/weapon/circuitboard/chem_master + name = "circuit board (Chem Master 2999)" + build_path = /obj/machinery/chem_master/constructable + board_type = "machine" + origin_tech = "materials=2;programming=2;biotech=1" + req_components = list( + /obj/item/weapon/reagent_containers/glass/beaker = 2, + /obj/item/weapon/stock_parts/manipulator = 1, + /obj/item/weapon/stock_parts/console_screen = 1) /obj/item/weapon/circuitboard/chem_heater name = "circuit board (Chemical Heater)" diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index aa7e40ee737..2b1ef80ccff 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -38,7 +38,7 @@ var/obj/machinery/door/airlock/closeOther = null var/closeOtherId = null var/lockdownbyai = 0 - var/doortype = null + var/doortype = /obj/structure/door_assembly/door_assembly_0 var/justzap = 0 var/safe = 1 normalspeed = 1 diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index f3bee16d85f..f91fb5a6ddf 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -251,48 +251,6 @@ if(maptext != new_text) maptext = new_text - -/obj/machinery/door_timer/cell_1 - name = "Cell 1" - id = "Cell 1" - dir = 2 - pixel_y = -32 - - -/obj/machinery/door_timer/cell_2 - name = "Cell 2" - id = "Cell 2" - dir = 2 - pixel_y = -32 - - -/obj/machinery/door_timer/cell_3 - name = "Cell 3" - id = "Cell 3" - dir = 2 - pixel_y = -32 - - -/obj/machinery/door_timer/cell_4 - name = "Cell 4" - id = "Cell 4" - dir = 2 - pixel_y = -32 - - -/obj/machinery/door_timer/cell_5 - name = "Cell 5" - id = "Cell 5" - dir = 2 - pixel_y = -32 - - -/obj/machinery/door_timer/cell_6 - name = "Cell 6" - id = "Cell 6" - dir = 4 - pixel_x = 32 - #undef FONT_SIZE #undef FONT_COLOR #undef FONT_STYLE diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 6bfaf23190a..86434159b81 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -265,6 +265,8 @@ var/turf/location = src.loc if(istype(location, /turf/simulated)) //add_blood doesn't work for borgs/xenos, but add_blood_floor does. location.add_blood_floor(L) + for(var/obj/mecha/M in get_turf(src)) + M.take_damage(DOOR_CRUSH_DAMAGE) /obj/machinery/door/proc/requiresID() return 1 diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm index 7c47ceba176..ac30218b651 100644 --- a/code/game/machinery/doors/poddoor.dm +++ b/code/game/machinery/doors/poddoor.dm @@ -73,13 +73,14 @@ flick("closing", src) icon_state = "closed" SetOpacity(1) + sleep(5) + density = 1 + sleep(5) air_update_turf(1) update_freelook_sight() sleep(5) crush() - density = 1 sleep(5) - operating = 0 diff --git a/code/game/machinery/doors/unpowered.dm b/code/game/machinery/doors/unpowered.dm index c0da7ec0dba..df94284c2c5 100644 --- a/code/game/machinery/doors/unpowered.dm +++ b/code/game/machinery/doors/unpowered.dm @@ -9,7 +9,6 @@ /obj/machinery/door/unpowered/attackby(obj/item/I as obj, mob/user as mob, params) - if(istype(I, /obj/item/weapon/melee/energy/blade)) return if(src.locked) return ..() return diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index d9a02cecbfa..412048bb8a5 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -233,7 +233,7 @@ attack_generic(M, M.melee_damage_upper) -/obj/machinery/door/window/attack_slime(mob/living/carbon/slime/user as mob) +/obj/machinery/door/window/attack_slime(mob/living/simple_animal/slime/user as mob) user.do_attack_animation(src) if(!user.is_adult) return @@ -262,22 +262,6 @@ add_fingerprint(user) - //ninja sword garbage - if (src.density && istype(I, /obj/item/weapon/melee/energy/blade)) - src.operating = -1 - flick("[src.base_state]spark", src) - sleep(6) - desc += "
Its access panel is smoking slightly." - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, src.loc) - spark_system.start() - playsound(src.loc, "sparks", 50, 1) - playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1) - visible_message(" The glass door was sliced open by [user]!") - open(2) - emagged = 1 - return 1 - if(istype(I, /obj/item/weapon/screwdriver)) if(src.density || src.operating) user << "You need to open the door to access the maintenance panel." diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm index 892539285a8..83f986aaf19 100644 --- a/code/game/machinery/doppler_array.dm +++ b/code/game/machinery/doppler_array.dm @@ -7,6 +7,7 @@ var/list/doppler_arrays = list() icon_state = "tdoppler" density = 1 anchored = 1 + verb_say = "states coldly" /obj/machinery/doppler_array/New() ..() @@ -76,9 +77,6 @@ var/list/doppler_arrays = list() for(var/message in messages) say(message) -/obj/machinery/doppler_array/say_quote(text) - return "states coldly, \"[text]\"" - /obj/machinery/doppler_array/power_change() if(stat & BROKEN) icon_state = "[initial(icon_state)]-broken" diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index da34431eee6..f575ccd7778 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -78,26 +78,16 @@ last_flash = world.time use_power(1000) - for (var/mob/O in viewers(src, null)) - if (get_dist(src, O) > src.range) + for (var/mob/living/L in viewers(src, null)) + if (get_dist(src, L) > range) continue - if (istype(O, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = O - if(!H.eyecheck() <= 0) - continue + if(L.flash_eyes()) + L.Weaken(strength) + if(L.weakeyes) + L.Weaken(strength * 1.5) + L.visible_message("[L] gasps and shields their eyes!") - if (istype(O, /mob/living/carbon/alien))//So aliens don't get flashed (they have no external eyes)/N - continue - - O.Weaken(strength) - if ((O.eye_stat > 15 && prob(O.eye_stat + 50))) - flick("e_flash", O:flash) - O.eye_stat += rand(1, 2) - else - if(!O.eye_blind) - flick("flash", O:flash) - O.eye_stat += rand(0, 2) return 1 diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index ad61bfe4ece..b713085f801 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -85,11 +85,11 @@ var/const/HOLOPAD_MODE = RANGE_BASED /*This is the proc for special two-way communication between AI and holopad/people talking near holopad. For the other part of the code, check silicon say.dm. Particularly robot talk.*/ -/obj/machinery/hologram/holopad/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq) +/obj/machinery/hologram/holopad/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans) if(speaker && masters.len && !radio_freq)//Master is mostly a safety in case lag hits or something. Radio_freq so AIs dont hear holopad stuff through radios. for(var/mob/living/silicon/ai/master in masters) if(masters[master] && speaker != master) - raw_message = master.lang_treat(speaker, message_langs, raw_message) + raw_message = master.lang_treat(speaker, message_langs, raw_message, spans) var/name_used = speaker.GetVoice() var/rendered = "Holopad received, [name_used] [raw_message]" master.show_message(rendered, 2) diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index bd71a6f4005..bfa9f68ef65 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -93,6 +93,7 @@ Class Procs: /obj/machinery name = "machinery" icon = 'icons/obj/stationobjs.dmi' + verb_yell = "blares" var/stat = 0 var/emagged = 0 var/use_power = 1 @@ -143,7 +144,7 @@ Class Procs: pulse2.dir = pick(cardinal) spawn(10) - pulse2.delete() + qdel(pulse2) ..() /obj/machinery/proc/open_machine() diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index 29386370d5d..a69a1526de8 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -124,6 +124,9 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co desc = "A standard Nanotrasen-licensed newsfeed handler for use in commercial space stations. All the news you absolutely have no use for, in one place!" icon = 'icons/obj/terminals.dmi' icon_state = "newscaster_normal" + verb_say = "beeps" + verb_ask = "beeps" + verb_exclaim = "beeps" var/isbroken = 0 //1 if someone banged it with something heavy var/ispowered = 1 //starts powered, changes with power_change() //var/list/datum/feed_channel/channel_list = list() //This list will contain the names of the feed channels. Each name will refer to a data region where the messages of the feed channels are stored. @@ -860,7 +863,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co user << "You cannot interface with silicon photo uploading" //gtfo pAIs if(targetcam.aipictures.len == 0) - usr << "No images saved" + usr << "No images saved" return for(var/datum/picture/t in targetcam.aipictures) nametemp += t.fields["name"] @@ -1082,6 +1085,3 @@ obj/item/weapon/newspaper/attackby(obj/item/weapon/W as obj, mob/user as mob, pa say("Attention! Wanted issue distributed!") playsound(src.loc, 'sound/machines/warning-buzzer.ogg', 75, 1) return - -/obj/machinery/newscaster/say_quote(text) - return "beeps, \"[text]\"" diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index e357ff5cc1b..00d896cc6c0 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -369,12 +369,12 @@ var/list/obj/machinery/requests_console/allConsoles = list() updateUsrDialog() return -/obj/machinery/say_quote(var/text) - var/ending = copytext(text, length(text) - 2) +/obj/machinery/say_quote(var/input, list/spans) + var/ending = copytext(input, length(input) - 2) if (ending == "!!!") - return "blares, \"[text]\"" + return "blares, \"attach_spans(input, spans)\"" - return "beeps, \"[text]\"" + return ..() /obj/machinery/requests_console/proc/createmessage(source, title, message, priority, paper) var/linkedsender diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index 7f7a91b734a..1b1e68bbf6e 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -91,7 +91,7 @@ /obj/machinery/shield/hitby(AM as mob|obj) //Let everyone know we've been hit! - visible_message("[src] was hit by [AM].") + visible_message("[src] was hit by [AM].") //Super realistic, resource-intensive, real-time damage calculations. var/tforce = 0 diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 77472452150..e1755317dce 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -44,11 +44,11 @@ STORAGE_TYPE = /obj/item/weapon/tank/jetpack/oxygen /obj/machinery/suit_storage_unit/engine - SUIT_TYPE = /obj/item/clothing/suit/space/hardsuit + SUIT_TYPE = /obj/item/clothing/suit/space/hardsuit/engine MASK_TYPE = /obj/item/clothing/mask/breath /obj/machinery/suit_storage_unit/ce - SUIT_TYPE = /obj/item/clothing/suit/space/hardsuit/elite + SUIT_TYPE = /obj/item/clothing/suit/space/hardsuit/engine/elite MASK_TYPE = /obj/item/clothing/mask/breath STORAGE_TYPE= /obj/item/clothing/shoes/magboots/advance @@ -61,7 +61,7 @@ MASK_TYPE = /obj/item/clothing/mask/gas/sechailer /obj/machinery/suit_storage_unit/atmos - SUIT_TYPE = /obj/item/clothing/suit/space/hardsuit/atmos + SUIT_TYPE = /obj/item/clothing/suit/space/hardsuit/engine/atmos MASK_TYPE = /obj/item/clothing/mask/gas STORAGE_TYPE = /obj/item/weapon/watertank/atmos @@ -79,26 +79,22 @@ STORAGE_TYPE = /obj/item/weapon/tank/jetpack/oxygen/harness /obj/machinery/suit_storage_unit/ertCom - SUIT_TYPE = /obj/item/clothing/suit/space/ert - HELMET_TYPE = /obj/item/clothing/head/helmet/space/hardsuit/ert + SUIT_TYPE = /obj/item/clothing/suit/space/hardsuit/ert MASK_TYPE = /obj/item/clothing/mask/breath STORAGE_TYPE = /obj/item/weapon/tank/internals/emergency_oxygen/double /obj/machinery/suit_storage_unit/ertSec - SUIT_TYPE = /obj/item/clothing/suit/space/ert/sec - HELMET_TYPE = /obj/item/clothing/head/helmet/space/hardsuit/ert/sec + SUIT_TYPE = /obj/item/clothing/suit/space/hardsuit/ert/sec MASK_TYPE = /obj/item/clothing/mask/breath STORAGE_TYPE = /obj/item/weapon/tank/internals/emergency_oxygen/double /obj/machinery/suit_storage_unit/ertEngi - SUIT_TYPE = /obj/item/clothing/suit/space/ert/engi - HELMET_TYPE = /obj/item/clothing/head/helmet/space/hardsuit/ert/engi + SUIT_TYPE = /obj/item/clothing/suit/space/hardsuit/ert/engi MASK_TYPE = /obj/item/clothing/mask/breath STORAGE_TYPE = /obj/item/weapon/tank/internals/emergency_oxygen/double /obj/machinery/suit_storage_unit/ertMed - SUIT_TYPE = /obj/item/clothing/suit/space/ert/med - HELMET_TYPE = /obj/item/clothing/head/helmet/space/hardsuit/ert/med + SUIT_TYPE = /obj/item/clothing/suit/space/hardsuit/ert/med MASK_TYPE = /obj/item/clothing/mask/breath STORAGE_TYPE = /obj/item/weapon/tank/internals/emergency_oxygen/double diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm index 692d9c8951b..18e8a4c94e2 100644 --- a/code/game/machinery/telecomms/broadcaster.dm +++ b/code/game/machinery/telecomms/broadcaster.dm @@ -59,7 +59,8 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept Broadcast_Message(signal.data["mob"], signal.data["vmask"], signal.data["radio"], signal.data["message"], signal.data["name"], signal.data["job"], signal.data["realname"], - 0, signal.data["compression"], signal.data["level"], signal.frequency) + 0, signal.data["compression"], signal.data["level"], signal.frequency, signal.data["spans"], + signal.data["verb_say"], signal.data["verb_ask"], signal.data["verb_exclaim"], signal.data["verb_yell"]) /** #### - Simple Broadcast - #### **/ @@ -83,7 +84,8 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept signal.data["vmask"], signal.data["radio"], signal.data["message"], signal.data["name"], signal.data["job"], - signal.data["realname"], 4, signal.data["compression"], signal.data["level"], signal.frequency) + signal.data["realname"], 4, signal.data["compression"], signal.data["level"], signal.frequency, signal.data["spans"], + signal.data["verb_say"], signal.data["verb_ask"], signal.data["verb_exclaim"], signal.data["verb_yell"]) if(!message_delay) message_delay = 1 @@ -143,7 +145,8 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept signal.data["vmask"], signal.data["radio"], signal.data["message"], signal.data["name"], signal.data["job"], - signal.data["realname"],, signal.data["compression"], list(0, z), signal.frequency) + signal.data["realname"],, signal.data["compression"], list(0, z), signal.frequency, signal.data["spans"], + signal.data["verb_say"], signal.data["verb_ask"], signal.data["verb_exclaim"], signal.data["verb_yell"]) /** @@ -204,7 +207,8 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept /proc/Broadcast_Message(var/atom/movable/AM, var/vmask, var/obj/item/device/radio/radio, var/message, var/name, var/job, var/realname, - var/data, var/compression, var/list/level, var/freq) + var/data, var/compression, var/list/level, var/freq, var/list/spans, + var/verb_say, var/verb_ask, var/verb_exclaim, var/verb_yell) message = copytext(message, 1, MAX_BROADCAST_LEN) @@ -220,6 +224,10 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept virt.source = AM virt.faketrack = data == 4 ? 1 : 0 virt.radio = radio + virt.verb_say = verb_say + virt.verb_ask = verb_ask + virt.verb_exclaim = verb_exclaim + virt.verb_yell = verb_yell if(compression > 0) message = Gibberish(message, compression + 40) @@ -258,21 +266,21 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept var/list/receive = get_mobs_in_radio_ranges(radios) //this includes all hearers. for(var/mob/R in receive) //Filter receiver list. - if (R.client && !(R.client.prefs.chat_toggles & CHAT_RADIO)) //Adminning with 80 people on can be fun when you're trying to talk and all you can hear is radios. + if (R.client && R.client.holder && !(R.client.prefs.chat_toggles & CHAT_RADIO)) //Adminning with 80 people on can be fun when you're trying to talk and all you can hear is radios. receive -= R for(var/mob/M in player_list) if(isobserver(M) && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTRADIO)) receive |= M - var/rendered = virt.compose_message(virt, virt.languages, message, freq) //Always call this on the virtualspeaker to advoid issues. + var/rendered = virt.compose_message(virt, virt.languages, message, freq, spans) //Always call this on the virtualspeaker to advoid issues. for(var/atom/movable/hearer in receive) - hearer.Hear(rendered, virt, AM.languages, message, freq) + hearer.Hear(rendered, virt, AM.languages, message, freq, spans) if(length(receive)) // --- This following recording is intended for research and feedback in the use of department radio channels --- - var/blackbox_msg = "[AM] [AM.say_quote(message)]" + var/blackbox_msg = "[AM] [AM.say_quote(message, spans)]" if(istype(blackbox)) switch(freq) if(1459) diff --git a/code/game/machinery/telecomms/logbrowser.dm b/code/game/machinery/telecomms/logbrowser.dm index 829af0c35d1..b7ebd4314ac 100644 --- a/code/game/machinery/telecomms/logbrowser.dm +++ b/code/game/machinery/telecomms/logbrowser.dm @@ -75,7 +75,7 @@ var/list/humans = typesof(/mob/living/carbon/human, /mob/living/carbon/brain) var/list/monkeys = typesof(/mob/living/carbon/monkey) var/list/silicons = typesof(/mob/living/silicon) - var/list/slimes = typesof(/mob/living/carbon/slime) + var/list/slimes = typesof(/mob/living/simple_animal/slime) var/list/animals = typesof(/mob/living/simple_animal) if(mobtype in humans) diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm index 599c5a20429..c0c8d3abbf9 100644 --- a/code/game/machinery/telecomms/telecomunications.dm +++ b/code/game/machinery/telecomms/telecomunications.dm @@ -87,7 +87,12 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list() "type" = signal.data["type"], "server" = signal.data["server"], "reject" = signal.data["reject"], - "level" = signal.data["level"] + "level" = signal.data["level"], + "spans" = signal.data["spans"], + "verb_say" = signal.data["verb_say"], + "verb_ask" = signal.data["verb_ask"], + "verb_exclaim" = signal.data["verb_exclaim"], + "verb_yell" = signal.data["verb_yell"] ) // Keep the "original" signal constant diff --git a/code/game/machinery/turrets.dm b/code/game/machinery/turrets.dm index 590501e4cf0..0fb0bb0bd43 100644 --- a/code/game/machinery/turrets.dm +++ b/code/game/machinery/turrets.dm @@ -313,7 +313,7 @@ M.do_attack_animation(src) if(M.melee_damage_upper == 0) return if(!(stat & BROKEN)) - visible_message("[M] [M.attacktext] [src]!") + visible_message("[M] [M.attacktext] [src]!") add_logs(M, src, "attacked", admin=0) //src.attack_log += text("\[[time_stamp()]\] was attacked by [M.name] ([M.ckey])") src.health -= M.melee_damage_upper diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index baba1af6680..40d354f2fe9 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -14,6 +14,9 @@ layer = 2.9 anchored = 1 density = 1 + verb_say = "beeps" + verb_ask = "beeps" + verb_exclaim = "beeps" var/active = 1 //No sales pitches if off! var/vend_ready = 1 //Are we ready to vend?? Is it time?? var/vend_delay = 10 //How long does it take to vend? @@ -51,13 +54,26 @@ /obj/machinery/vending/New() ..() wires = new(src) - spawn(4) - slogan_list = text2list(product_slogans, ";") - // So not all machines speak at the exact same time. - // The first time this machine says something will be at slogantime + this random value, - // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated. - last_slogan = world.time + rand(0, slogan_delay) - power_change() + if(refill_canister) //constructable vending machine + component_parts = list() + var/obj/item/weapon/circuitboard/vendor/V = new(null) + V.set_type(type) + component_parts += V + component_parts += new refill_canister + component_parts += new refill_canister + component_parts += new refill_canister + RefreshParts() + else + build_inventory(products) + build_inventory(contraband, 1) + build_inventory(premium, 0, 1) + + slogan_list = text2list(product_slogans, ";") + // So not all machines speak at the exact same time. + // The first time this machine says something will be at slogantime + this random value, + // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated. + last_slogan = world.time + rand(0, slogan_delay) + power_change() /obj/machinery/vending/Destroy() qdel(wires) @@ -71,18 +87,18 @@ S.loc = get_turf(src) ..() -/obj/machinery/vending/initialize() - build_inventory(products) - build_inventory(contraband, 1) - build_inventory(premium, 0, 1) - /obj/machinery/vending/RefreshParts() //Better would be to make constructable child if(component_parts) + product_records = list() + hidden_records = list() + coin_records = list() build_inventory(products, start_empty = 1) - build_inventory(contraband, 1, 1) - build_inventory(premium, 0, 1, 1) + build_inventory(contraband, 1, start_empty = 1) + build_inventory(premium, 0, 1, start_empty = 1) for(var/obj/item/weapon/vending_refill/VR in component_parts) refill_inventory(VR, product_records) + refill_inventory(VR, coin_records) + refill_inventory(VR, hidden_records) /obj/machinery/vending/ex_act(severity, target) ..() @@ -119,7 +135,7 @@ else product_records += R -/obj/machinery/vending/proc/refill_inventory(obj/item/weapon/vending_refill/refill, datum/data/vending_product/machine, mob/user) +/obj/machinery/vending/proc/refill_inventory(obj/item/weapon/vending_refill/refill, datum/data/vending_product/machine) var/total = 0 var/to_restock = 0 @@ -218,8 +234,8 @@ return if(component_parts && istype(W, /obj/item/weapon/crowbar)) - var/datum/data/vending_product/machine = product_records - for(var/datum/data/vending_product/machine_content in machine) + var/list/all_products = product_records + hidden_records + coin_records + for(var/datum/data/vending_product/machine_content in all_products) while(machine_content.amount !=0) for(var/obj/item/weapon/vending_refill/VR in component_parts) VR.charges++ @@ -494,9 +510,6 @@ say(message) -/obj/machinery/vending/say_quote(text) - return "beeps, \"[text]\"" - /obj/machinery/vending/power_change() if(stat & BROKEN) icon_state = "[initial(icon_state)]-broken" @@ -608,7 +621,7 @@ /obj/item/weapon/reagent_containers/food/drinks/bottle/tomatojuice = 4,/obj/item/weapon/reagent_containers/food/drinks/bottle/limejuice = 4, /obj/item/weapon/reagent_containers/food/drinks/bottle/cream = 4,/obj/item/weapon/reagent_containers/food/drinks/soda_cans/tonic = 8, /obj/item/weapon/reagent_containers/food/drinks/soda_cans/cola = 8, /obj/item/weapon/reagent_containers/food/drinks/soda_cans/sodawater = 15, - /obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 30,/obj/item/weapon/reagent_containers/food/drinks/ice = 9, + /obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 30,/obj/item/weapon/reagent_containers/food/drinks/ice = 10, /obj/item/weapon/reagent_containers/food/drinks/drinkingglass/shotglass = 8) contraband = list(/obj/item/weapon/reagent_containers/food/drinks/tea = 10) vend_delay = 15 @@ -617,18 +630,6 @@ req_access_txt = "25" refill_canister = /obj/item/weapon/vending_refill/boozeomat - -/obj/machinery/vending/boozeomat/New() - ..() - component_parts = list() - var/obj/item/weapon/circuitboard/vendor/V = new(null) - V.set_type(type) - component_parts += V - component_parts += new /obj/item/weapon/vending_refill/boozeomat(0) - component_parts += new /obj/item/weapon/vending_refill/boozeomat(0) - component_parts += new /obj/item/weapon/vending_refill/boozeomat(0) - - /obj/machinery/vending/assist products = list( /obj/item/device/assembly/prox_sensor = 5,/obj/item/device/assembly/igniter = 3,/obj/item/device/assembly/signaler = 4, /obj/item/weapon/wirecutters = 1, /obj/item/weapon/cartridge/signal = 4) @@ -646,17 +647,6 @@ contraband = list(/obj/item/weapon/reagent_containers/food/drinks/ice = 10) refill_canister = /obj/item/weapon/vending_refill/coffee - -/obj/machinery/vending/coffee/New() - ..() - component_parts = list() - var/obj/item/weapon/circuitboard/vendor/V = new(null) - V.set_type(type) - component_parts += V - component_parts += new /obj/item/weapon/vending_refill/coffee(0) - component_parts += new /obj/item/weapon/vending_refill/coffee(0) - component_parts += new /obj/item/weapon/vending_refill/coffee(0) - /obj/machinery/vending/snack name = "\improper Getmore Chocolate Corp" desc = "A snack machine courtesy of the Getmore Chocolate Corporation, based out of Mars" @@ -666,20 +656,10 @@ products = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 5,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 5,/obj/item/weapon/reagent_containers/food/snacks/chips =5, /obj/item/weapon/reagent_containers/food/snacks/sosjerky = 5,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 5,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 5, /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 5) - contraband = list(/obj/item/weapon/reagent_containers/food/snacks/syndicake = 6) + contraband = list(/obj/item/weapon/reagent_containers/food/snacks/syndicake = 7) refill_canister = /obj/item/weapon/vending_refill/snack var/chef_compartment_access = "28" -/obj/machinery/vending/snack/New() - ..() - component_parts = list() - var/obj/item/weapon/circuitboard/vendor/V = new(null) - V.set_type(type) - component_parts += V - component_parts += new /obj/item/weapon/vending_refill/snack(0) - component_parts += new /obj/item/weapon/vending_refill/snack(0) - component_parts += new /obj/item/weapon/vending_refill/snack(0) - /obj/machinery/vending/sustenance name = "\improper Sustenance Vendor" desc = "A vending machine which vends food, as required by section 47-C of the NT's Prisoner Ethical Treatment Agreement." @@ -702,20 +682,9 @@ /obj/item/weapon/reagent_containers/food/drinks/soda_cans/dr_gibb = 10,/obj/item/weapon/reagent_containers/food/drinks/soda_cans/starkist = 10, /obj/item/weapon/reagent_containers/food/drinks/soda_cans/space_up = 10, /obj/item/weapon/reagent_containers/food/drinks/soda_cans/lemon_lime = 10) - contraband = list(/obj/item/weapon/reagent_containers/food/drinks/soda_cans/thirteenloko = 5) + contraband = list(/obj/item/weapon/reagent_containers/food/drinks/soda_cans/thirteenloko = 6) refill_canister = /obj/item/weapon/vending_refill/cola - -/obj/machinery/vending/cola/New() - ..() - component_parts = list() - var/obj/item/weapon/circuitboard/vendor/V = new(null) - V.set_type(type) - component_parts += V - component_parts += new /obj/item/weapon/vending_refill/cola(0) - component_parts += new /obj/item/weapon/vending_refill/cola(0) - component_parts += new /obj/item/weapon/vending_refill/cola(0) - //This one's from bay12 /obj/machinery/vending/cart name = "\improper PTech" @@ -753,7 +722,7 @@ /obj/item/weapon/storage/fancy/cigarettes/cigpack_uplift = 3, /obj/item/weapon/storage/fancy/cigarettes/cigpack_robust = 2, /obj/item/weapon/storage/fancy/cigarettes/cigpack_carp = 3, - /obj/item/weapon/storage/fancy/cigarettes/cigpack_midori = 1, + /obj/item/weapon/storage/fancy/cigarettes/cigpack_midori = 3, /obj/item/weapon/storage/box/matches = 10, /obj/item/weapon/lighter/grayscale = 4, /obj/item/weapon/storage/fancy/rollingpapers = 5) @@ -761,17 +730,6 @@ premium = list(/obj/item/clothing/mask/cigarette/cigar/havana = 2, /obj/item/weapon/storage/fancy/cigarettes/cigpack_robustgold = 1) refill_canister = /obj/item/weapon/vending_refill/cigarette - -/obj/machinery/vending/cigarette/New() - ..() - component_parts = list() - var/obj/item/weapon/circuitboard/vendor/V = new(null) - V.set_type(type) - component_parts += V - component_parts += new /obj/item/weapon/vending_refill/cigarette(0) - component_parts += new /obj/item/weapon/vending_refill/cigarette(0) - component_parts += new /obj/item/weapon/vending_refill/cigarette(0) - /obj/machinery/vending/medical name = "\improper NanoMed Plus" desc = "Medical drug dispenser." @@ -885,25 +843,17 @@ /obj/item/clothing/head/bandana = 1,/obj/item/clothing/under/soviet = 1,/obj/item/clothing/head/ushanka = 1,/obj/item/clothing/suit/imperium_monk = 1, /obj/item/clothing/mask/gas/cyborg = 1,/obj/item/clothing/suit/holidaypriest = 1,/obj/item/clothing/head/wizard/marisa/fake = 1, /obj/item/clothing/suit/wizrobe/marisa/fake = 1,/obj/item/clothing/under/sundress = 1,/obj/item/clothing/head/witchwig = 1,/obj/item/weapon/staff/broom = 1, - /obj/item/clothing/suit/wizrobe/fake = 1,/obj/item/clothing/head/wizard/fake = 1,/obj/item/weapon/staff = 3,/obj/item/clothing/mask/gas/sexyclown = 1, + /obj/item/clothing/suit/wizrobe/fake = 1,/obj/item/clothing/head/wizard/fake = 1,/obj/item/weapon/staff = 3,/obj/item/clothing/mask/gas/sexyclown = 1, /obj/item/clothing/under/sexyclown = 1,/obj/item/clothing/mask/gas/sexymime = 1,/obj/item/clothing/under/sexymime = 1,/obj/item/clothing/suit/apron/overalls = 1, /obj/item/clothing/head/rabbitears =1, /obj/item/clothing/head/sombrero = 1, /obj/item/clothing/head/sombrero/green = 1, /obj/item/clothing/suit/poncho = 1, /obj/item/clothing/suit/poncho/green = 1, /obj/item/clothing/suit/poncho/red = 1, - /obj/item/clothing/under/maid = 1, /obj/item/clothing/under/janimaid = 1) - contraband = list(/obj/item/clothing/suit/judgerobe = 1,/obj/item/clothing/head/powdered_wig = 1,/obj/item/weapon/gun/magic/wand = 1) + /obj/item/clothing/under/maid = 1, /obj/item/clothing/under/janimaid = 1,/obj/item/clothing/glasses/cold=1,/obj/item/clothing/glasses/heat=1, + /obj/item/clothing/suit/whitedress = 1, + /obj/item/clothing/under/jester = 1, /obj/item/clothing/head/jester = 1) + contraband = list(/obj/item/clothing/suit/judgerobe = 1,/obj/item/clothing/head/powdered_wig = 1,/obj/item/weapon/gun/magic/wand = 1,/obj/item/clothing/glasses/sunglasses/garb = 1) premium = list(/obj/item/clothing/suit/hgpirate = 1, /obj/item/clothing/head/hgpiratecap = 1, /obj/item/clothing/head/helmet/roman = 1, /obj/item/clothing/head/helmet/roman/legionaire = 1, /obj/item/clothing/under/roman = 1, /obj/item/clothing/shoes/roman = 1, /obj/item/weapon/shield/riot/roman = 1) refill_canister = /obj/item/weapon/vending_refill/autodrobe -/obj/machinery/vending/autodrobe/New() - ..() - component_parts = list() - var/obj/item/weapon/circuitboard/vendor/V = new(null) - V.set_type(type) - component_parts += V - component_parts += new /obj/item/weapon/vending_refill/autodrobe(0) - component_parts += new /obj/item/weapon/vending_refill/autodrobe(0) - component_parts += new /obj/item/weapon/vending_refill/autodrobe(0) - /obj/machinery/vending/dinnerware name = "\improper Plasteel Chef's Dinnerware Vendor" desc = "A kitchen and restaurant equipment vendor" @@ -992,18 +942,9 @@ /obj/item/clothing/under/plaid_skirt=1,/obj/item/clothing/under/plaid_skirt/blue=1,/obj/item/clothing/under/plaid_skirt/purple=1, /obj/item/clothing/glasses/regular=2,/obj/item/clothing/head/sombrero=1,/obj/item/clothing/suit/poncho=1, /obj/item/clothing/suit/ianshirt=1,/obj/item/clothing/shoes/laceup=2,/obj/item/clothing/shoes/sneakers/black=4, - /obj/item/clothing/shoes/sandal=1, /obj/item/clothing/gloves/fingerless=2, + /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) refill_canister = /obj/item/weapon/vending_refill/clothing -/obj/machinery/vending/clothing/New() - ..() - component_parts = list() - var/obj/item/weapon/circuitboard/vendor/V = new(null) - V.set_type(type) - component_parts += V - component_parts += new /obj/item/weapon/vending_refill/clothing(0) - component_parts += new /obj/item/weapon/vending_refill/clothing(0) - component_parts += new /obj/item/weapon/vending_refill/clothing(0) diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm index fb01666acf5..486d47a003c 100644 --- a/code/game/mecha/equipment/tools/medical_tools.dm +++ b/code/game/mecha/equipment/tools/medical_tools.dm @@ -47,7 +47,7 @@ if(occupant) occupant_message("The sleeper is already occupied") return - for(var/mob/living/carbon/slime/M in range(1,target)) + for(var/mob/living/simple_animal/slime/M in range(1,target)) if(M.Victim == target) occupant_message("[target] will not fit into the sleeper because they have a slime latched onto their head.") return @@ -59,7 +59,7 @@ if(chassis.loc!=C || target.loc!=T) return if(occupant) - occupant_message("The sleeper is already occupied!") + occupant_message("The sleeper is already occupied!") return target.forceMove(src) occupant = target diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm index ac3841fcae2..05cb1cb48a4 100644 --- a/code/game/mecha/equipment/tools/tools.dm +++ b/code/game/mecha/equipment/tools/tools.dm @@ -211,7 +211,7 @@ var/list/the_targets = list(T,T1,T2) spawn(0) for(var/a=0, a<5, a++) - var/obj/effect/effect/water/W = new /obj/effect/effect/water(get_turf(chassis)) + var/obj/effect/effect/water/W = PoolOrNew(/obj/effect/effect/water, get_turf(chassis)) if(!W) return var/turf/my_target = pick(the_targets) diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index 0d7436f6e94..c9ad3ae4189 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -4,6 +4,9 @@ origin_tech = "materials=3;combat=3" var/projectile var/fire_sound + var/projectiles_per_shot = 1 + var/deviation = 0 + var/shot_delay = 0 /obj/item/mecha_parts/mecha_equipment/weapon/can_attach(var/obj/mecha/combat/M as obj) if(..()) @@ -11,23 +14,40 @@ return 1 return 0 +/obj/item/mecha_parts/mecha_equipment/weapon/proc/get_shot_amount() + return 1 + /obj/item/mecha_parts/mecha_equipment/weapon/action(atom/target) - if(!action_checks(target)) return 0 + if(!action_checks(target)) + return 0 set_ready_state(0) - var/turf/curloc = chassis.loc - var/atom/targloc = get_turf(target) - if (!targloc || !istype(targloc, /turf) || !curloc) - return + + var/turf/curloc = get_turf(chassis) + var/turf/targloc = get_turf(target) + if (!targloc || !istype(targloc) || !curloc) + return 0 if (targloc == curloc) - return - playsound(chassis, fire_sound, 50, 1) - var/obj/item/projectile/A = new projectile(curloc) - A.firer = chassis.occupant - A.original = target - A.current = curloc - A.yo = targloc.y - curloc.y - A.xo = targloc.x - curloc.x - A.fire() + return 0 + + for(var/i=1 to get_shot_amount()) + var/obj/item/projectile/A = new projectile(curloc) + A.firer = chassis.occupant + A.original = target + A.current = curloc + + if(deviation) + A.yo = (targloc.y + round(gaussian(0,deviation),1)) - curloc.y + A.xo = (targloc.x + round(gaussian(0,deviation),1)) - curloc.x + else + A.yo = targloc.y - curloc.y + A.xo = targloc.x - curloc.x + + A.fire() + playsound(chassis, fire_sound, 50, 1) + + if(shot_delay) + sleep(shot_delay) + chassis.log_message("Fired from [src.name], targeting [target].") do_after_cooldown() return 1 @@ -36,9 +56,12 @@ /obj/item/mecha_parts/mecha_equipment/weapon/energy name = "general energy weapon" +/obj/item/mecha_parts/mecha_equipment/weapon/energy/get_shot_amount() + return min(round(chassis.cell.charge / energy_drain), projectiles_per_shot) + /obj/item/mecha_parts/mecha_equipment/weapon/energy/action(atom/target) ..() - chassis.use_power(energy_drain) + chassis.use_power(energy_drain * get_shot_amount()) /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser @@ -165,6 +188,9 @@ var/projectiles var/projectile_energy_cost +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/get_shot_amount() + return min(projectiles, projectiles_per_shot) + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/action_checks(target) if(!..()) return 0 @@ -196,7 +222,7 @@ /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/action(atom/target) if(..()) - src.projectiles-- + src.projectiles -= get_shot_amount() send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) @@ -227,39 +253,8 @@ projectile = /obj/item/projectile/bullet/midbullet projectiles = 40 projectile_energy_cost = 25 - var/projectiles_per_shot = 4 - var/deviation = 0.7 - -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot/action(atom/target) - if(!action_checks(target)) return - var/turf/curloc = get_turf(chassis) - var/turf/targloc = get_turf(target) - if(!curloc || !targloc) return - var/target_x = targloc.x - var/target_y = targloc.y - var/target_z = targloc.z - targloc = null - for(var/i=1 to min(projectiles, projectiles_per_shot)) - var/dx = round(gaussian(0,deviation),1) - var/dy = round(gaussian(0,deviation),1) - targloc = locate(target_x+dx, target_y+dy, target_z) - if(!targloc || targloc == curloc) - break - playsound(chassis, fire_sound, 80, 1) - var/obj/item/projectile/A = new projectile(curloc) - src.projectiles-- - A.firer = chassis.occupant - A.original = target - A.current = curloc - A.yo = targloc.y - curloc.y - A.xo = targloc.x - curloc.x - set_ready_state(0) - A.process() - log_message("Fired from [src.name], targeting [target].") - do_after_cooldown() - return - - + projectiles_per_shot = 4 + deviation = 0.7 /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg name = "\improper Ultra AC 2" @@ -269,41 +264,9 @@ projectile = /obj/item/projectile/bullet/weakbullet3 projectiles = 300 projectile_energy_cost = 20 - var/projectiles_per_shot = 3 - var/deviation = 0.3 - -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg/action(atom/target) - if(!action_checks(target)) return - var/turf/targloc = get_turf(target) - var/target_x = targloc.x - var/target_y = targloc.y - var/target_z = targloc.z - targloc = null - spawn for(var/i=1 to min(projectiles, projectiles_per_shot)) - if(!chassis) break - var/turf/curloc = get_turf(chassis) - var/dx = round(gaussian(0,deviation),1) - var/dy = round(gaussian(0,deviation),1) - targloc = locate(target_x+dx, target_y+dy, target_z) - if (!targloc || !curloc) - continue - if (targloc == curloc) - continue - - playsound(chassis, fire_sound, 50, 1) - var/obj/item/projectile/A = new projectile(curloc) - src.projectiles-- - A.firer = chassis.occupant - A.original = target - A.current = curloc - A.yo = targloc.y - curloc.y - A.xo = targloc.x - curloc.x - A.process() - sleep(2) - set_ready_state(0) - log_message("Fired from [src.name], targeting [target].") - do_after_cooldown() - return + projectiles_per_shot = 3 + deviation = 0.3 + shot_delay = 2 /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack name = "\improper SRM-8 missile rack" diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 3594f1d0e4a..88b7cc77e2d 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -236,9 +236,9 @@ obj/mecha/proc/can_use(mob/user) /obj/mecha/proc/drop_item()//Derpfix, but may be useful in future for engineering exosuits. return -/obj/mecha/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq) +/obj/mecha/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans) if(speaker == occupant && radio.broadcasting) - radio.talk_into(speaker, text) + radio.talk_into(speaker, text, , spans) return //////////////////////////// @@ -947,7 +947,7 @@ obj/mecha/proc/can_use(mob/user) user << "Access denied." src.log_append_to_last("Permission denied.") return - for(var/mob/living/carbon/slime/S in range(1,user)) + for(var/mob/living/simple_animal/slime/S in range(1,user)) if(S.Victim == user) user << "You're too busy getting your life sucked out of you." return diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index 78933650b03..ffc4db6400c 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -34,7 +34,7 @@ if(!can_buckle || !istype(M) || (M.loc != loc) || M.buckled || (buckle_requires_restraints && !M.restrained())) return 0 - if (istype(M, /mob/living/carbon/slime) || istype(M, /mob/living/simple_animal/slime)) + if (isslime(M)) return 0 M.buckled = src diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm index 5636d376136..3c314ee975c 100644 --- a/code/game/objects/effects/anomalies.dm +++ b/code/game/objects/effects/anomalies.dm @@ -27,7 +27,7 @@ /obj/effect/anomaly/proc/anomalyNeutralize() - new /obj/effect/effect/bad_smoke(loc) + PoolOrNew(/obj/effect/effect/bad_smoke, loc) for(var/atom/movable/O in src) O.loc = src.loc diff --git a/code/game/objects/effects/decals/crayon.dm b/code/game/objects/effects/decals/crayon.dm index db1952f145e..0ff875dd2f7 100644 --- a/code/game/objects/effects/decals/crayon.dm +++ b/code/game/objects/effects/decals/crayon.dm @@ -12,12 +12,16 @@ return -/obj/effect/decal/cleanable/crayon/New(location, main = "#FFFFFF", var/type = "rune1", var/e_name = "rune") +/obj/effect/decal/cleanable/crayon/New(location, main = "#FFFFFF", var/type = "rune1", var/e_name = "rune", var/rotation = 0) ..() loc = location name = e_name desc = "A [name] drawn in crayon." - icon_state = type - color = main \ No newline at end of file + + var/matrix/M = matrix() + M.Turn(rotation) + src.transform = M + + color = main diff --git a/code/game/objects/effects/effect_system/effect_system.dm b/code/game/objects/effects/effect_system/effect_system.dm index f085bf60e04..e150828bc99 100644 --- a/code/game/objects/effects/effect_system/effect_system.dm +++ b/code/game/objects/effects/effect_system/effect_system.dm @@ -13,11 +13,10 @@ would spawn and follow the beaker, even if it is carried or thrown. unacidable = 1//So effect are not targeted by alien acid. pass_flags = PASSTABLE | PASSGRILLE -/obj/effect/proc/delete() - loc = null - if(reagents) - reagents.delete() - return +/obj/effect/effect/Destroy() + ..() + PlaceInPool(src) + return 1 /datum/effect/effect/proc/fadeOut(var/atom/A, var/frames = 16) if(A.alpha == 0) //Handle already transparent case @@ -37,6 +36,11 @@ would spawn and follow the beaker, even if it is carried or thrown. var/atom/holder var/setup = 0 +/datum/effect/effect/system/Destroy() + holder = null + location = null + ..() + /datum/effect/effect/system/proc/set_up(n = 3, c = 0, turf/loc) if(n > 10) n = 10 diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm index d00614174e9..892bd547dc3 100644 --- a/code/game/objects/effects/effect_system/effects_foam.dm +++ b/code/game/objects/effects/effect_system/effects_foam.dm @@ -33,6 +33,9 @@ SSobj.processing.Add(src) playsound(src, 'sound/effects/bubbles2.ogg', 80, 1, -3) +/obj/effect/effect/foam/Destroy() + SSobj.processing.Remove(src) + return ..() /obj/effect/effect/foam/metal/New(loc) ..() @@ -45,7 +48,7 @@ SSobj.processing.Remove(src) flick("[icon_state]-disolve", src) spawn(5) - delete() + qdel(src) /obj/effect/effect/foam/process() @@ -84,7 +87,7 @@ if(foundfoam) continue - var/obj/effect/effect/foam/F = new type(T) + var/obj/effect/effect/foam/F = PoolOrNew(/obj/effect/effect/foam, T) F.amount = amount reagents.copy_to(F, (reagents.total_volume)) F.color = color @@ -102,7 +105,7 @@ /////////////////////////////////////////////// //FOAM EFFECT DATUM /datum/effect/effect/system/foam_spread - var/amount = 5 // the size of the foam spread. + var/amount = 10 // the size of the foam spread. var/obj/chemholder var/obj/effect/effect/foam/foamtype = /obj/effect/effect/foam var/metal = 0 @@ -114,11 +117,15 @@ /datum/effect/effect/system/foam_spread/New() ..() - chemholder = new/obj() + chemholder = PoolOrNew(/obj) var/datum/reagents/R = new/datum/reagents(1000) chemholder.reagents = R R.my_atom = chemholder +/datum/effect/effect/system/foam_spread/Destroy() + qdel(chemholder) + chemholder = null + return ..() /datum/effect/effect/system/foam_spread/set_up(amt=5, loca, var/datum/reagents/carry = null) if(istype(loca, /turf/)) @@ -126,7 +133,7 @@ else location = get_turf(loca) - amount = round(sqrt(amt / 3), 1) + amount = round(sqrt(amt / 2), 1) carry.copy_to(chemholder, carry.total_volume) @@ -139,7 +146,7 @@ if(foundfoam)//If there was already foam where we start, we add our foaminess to it. foundfoam.amount += amount else - var/obj/effect/effect/foam/F = new foamtype(src.location) + var/obj/effect/effect/foam/F = PoolOrNew(foamtype, location) var/foamcolor = mix_color_from_reagents(chemholder.reagents.reagent_list) chemholder.reagents.copy_to(F, chemholder.reagents.total_volume) F.color = foamcolor diff --git a/code/game/objects/effects/effect_system/effects_other.dm b/code/game/objects/effects/effect_system/effects_other.dm index 11271644ee1..0b54d310233 100644 --- a/code/game/objects/effects/effect_system/effects_other.dm +++ b/code/game/objects/effects/effect_system/effects_other.dm @@ -16,6 +16,10 @@ var/processing = 1 var/on = 1 +/datum/effect/effect/system/ion_trail_follow/Destroy() + oldposition = null + return ..() + /datum/effect/effect/system/ion_trail_follow/set_up(atom/atom) attach(atom) @@ -29,13 +33,12 @@ var/turf/T = get_turf(src.holder) if(T != src.oldposition) if(!has_gravity(T)) - var/obj/effect/effect/ion_trails/I = new /obj/effect/effect/ion_trails(src.oldposition) + var/obj/effect/effect/ion_trails/I = PoolOrNew(/obj/effect/effect/ion_trails, oldposition) I.dir = src.holder.dir flick("ion_fade", I) - I.icon_state = "ion_trails" + I.icon_state = "" spawn( 20 ) - if(I) - I.delete() + qdel(I) src.oldposition = T spawn(2) if(src.on) diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm index efca03256f6..d8a4a1804a6 100644 --- a/code/game/objects/effects/effect_system/effects_smoke.dm +++ b/code/game/objects/effects/effect_system/effects_smoke.dm @@ -28,12 +28,7 @@ /obj/effect/effect/harmless_smoke/New() ..() spawn (100) - delete() - return - -/obj/effect/effect/harmless_smoke/Move() - ..() - return + qdel(src) /datum/effect/effect/system/harmless_smoke_spread var/total_smoke = 0 // To stop it being spammed and lagging! @@ -60,7 +55,7 @@ spawn(0) if(holder) src.location = get_turf(holder) - var/obj/effect/effect/harmless_smoke/smoke = new /obj/effect/effect/harmless_smoke(src.location) + var/obj/effect/effect/harmless_smoke/smoke = PoolOrNew(/obj/effect/effect/harmless_smoke, location) src.total_smoke++ var/direction = src.direction if(!direction) @@ -74,7 +69,7 @@ spawn(75+rand(10,30)) if(smoke) fadeOut(smoke) - smoke.delete() + qdel(smoke) src.total_smoke-- @@ -96,8 +91,7 @@ /obj/effect/effect/bad_smoke/New() ..() spawn (200+rand(10,30)) - delete() - return + qdel(src) /obj/effect/effect/bad_smoke/Move() ..() @@ -163,7 +157,7 @@ spawn(0) if(holder) src.location = get_turf(holder) - var/obj/effect/effect/bad_smoke/smoke = new /obj/effect/effect/bad_smoke(src.location) + var/obj/effect/effect/bad_smoke/smoke = PoolOrNew(/obj/effect/effect/bad_smoke, location) src.total_smoke++ var/direction = src.direction if(!direction) @@ -177,7 +171,7 @@ spawn(150+rand(10,30)) if(smoke) fadeOut(smoke) - smoke.delete() + qdel(smoke) src.total_smoke-- @@ -201,25 +195,23 @@ ..() create_reagents(500) spawn(200+rand(10,30)) - delete() - return + qdel(src) /obj/effect/effect/chem_smoke/Move() ..() - for(var/atom/A in view(1, src)) - if(reagents.has_reagent("radium")||reagents.has_reagent("uranium")||reagents.has_reagent("carbon")||reagents.has_reagent("thermite"))//Prevents unholy radium spam by reducing the number of 'greenglows' down to something reasonable -Sieve - if(prob(5)) - reagents.reaction(A) - else - reagents.reaction(A) + for(var/mob/living/A in view(1, src)) + if(reagents.total_volume >= 1) + reagents.reaction(A, TOUCH) + reagents.trans_to(A.reagents, 10) return /obj/effect/effect/chem_smoke/Crossed(mob/living/carbon/M as mob ) ..() - reagents.reaction(M) - + if(reagents.total_volume >= 1) + reagents.reaction(M, TOUCH) + reagents.trans_to(M.reagents, 10) /datum/effect/effect/system/chem_smoke_spread var/total_smoke = 0 // To stop it being spammed and lagging! @@ -229,11 +221,15 @@ /datum/effect/effect/system/chem_smoke_spread/New() ..() - chemholder = new/obj() + chemholder = PoolOrNew(/obj) var/datum/reagents/R = new/datum/reagents(500) chemholder.reagents = R R.my_atom = chemholder +/datum/effect/effect/system/chem_smoke_spread/Destroy() + PlaceInPool(chemholder) + chemholder = null + ..() /datum/effect/effect/system/chem_smoke_spread/set_up(var/datum/reagents/carry = null, n = 5, c = 0, loca, direct, silent = 0) if(n > 20) @@ -285,7 +281,7 @@ spawn(0) if(holder) src.location = get_turf(holder) - var/obj/effect/effect/chem_smoke/smoke = new /obj/effect/effect/chem_smoke(src.location) + var/obj/effect/effect/chem_smoke/smoke = PoolOrNew(/obj/effect/effect/chem_smoke, location) src.total_smoke++ var/direction = src.direction if(!direction) @@ -310,7 +306,7 @@ spawn(150+rand(10,30)) if(smoke) fadeOut(smoke) - smoke.delete() + qdel(smoke) src.total_smoke-- @@ -335,8 +331,7 @@ /obj/effect/effect/sleep_smoke/New() ..() spawn (200+rand(10,30)) - delete() - return + qdel(src) /obj/effect/effect/sleep_smoke/Move() ..() @@ -396,7 +391,7 @@ spawn(0) if(holder) src.location = get_turf(holder) - var/obj/effect/effect/sleep_smoke/smoke = new /obj/effect/effect/sleep_smoke(src.location) + var/obj/effect/effect/sleep_smoke/smoke = PoolOrNew(/obj/effect/effect/sleep_smoke, location) src.total_smoke++ var/direction = src.direction if(!direction) @@ -410,5 +405,5 @@ spawn(150+rand(10,30)) if(smoke) fadeOut(smoke) - smoke.delete() + qdel(smoke) src.total_smoke-- \ No newline at end of file diff --git a/code/game/objects/effects/effect_system/effects_sparks.dm b/code/game/objects/effects/effect_system/effects_sparks.dm index 88f15977f84..2c7e6e9d6d1 100644 --- a/code/game/objects/effects/effect_system/effects_sparks.dm +++ b/code/game/objects/effects/effect_system/effects_sparks.dm @@ -14,20 +14,19 @@ /obj/effect/effect/sparks/New() ..() + flick("sparks", src) // replay the animation playsound(src.loc, "sparks", 100, 1) var/turf/T = src.loc if (istype(T, /turf)) T.hotspot_expose(1000,100) spawn (100) - delete() - return + qdel(src) /obj/effect/effect/sparks/Destroy() var/turf/T = src.loc if (istype(T, /turf)) T.hotspot_expose(1000,100) - ..() - return + return ..() /obj/effect/effect/sparks/Move() ..() @@ -57,7 +56,7 @@ spawn(0) if(holder) src.location = get_turf(holder) - var/obj/effect/effect/sparks/sparks = new /obj/effect/effect/sparks(src.location) + var/obj/effect/effect/sparks/sparks = PoolOrNew(/obj/effect/effect/sparks, location) src.total_sparks++ var/direction if(src.cardinals) @@ -68,8 +67,7 @@ sleep(5) step(sparks,direction) spawn(20) - if(sparks) // Might be deleted already - sparks.delete() + qdel(sparks) src.total_sparks-- @@ -101,7 +99,7 @@ spawn(0) if(holder) src.location = get_turf(holder) - var/obj/effect/effect/sparks/electricity/sparks = new /obj/effect/effect/sparks/electricity(src.location) + var/obj/effect/effect/sparks/electricity/sparks = PoolOrNew(/obj/effect/effect/sparks/electricity, location) src.total_sparks++ var/direction if(src.cardinals) @@ -112,6 +110,5 @@ sleep(5) step(sparks,direction) spawn(20) - if(sparks) // Might be deleted already - sparks.delete() + qdel(sparks) src.total_sparks-- \ No newline at end of file diff --git a/code/game/objects/effects/effect_system/effects_water.dm b/code/game/objects/effects/effect_system/effects_water.dm index f559d9fd8f8..1f860327ceb 100644 --- a/code/game/objects/effects/effect_system/effects_water.dm +++ b/code/game/objects/effects/effect_system/effects_water.dm @@ -10,21 +10,13 @@ /obj/effect/effect/water/New() ..() - //var/turf/T = src.loc - //if (istype(T, /turf)) - // T.firelevel = 0 //TODO: FIX spawn( 70 ) - delete() - return - return + qdel(src) /obj/effect/effect/water/Move(turf/newloc) - //var/turf/T = src.loc - //if (istype(T, /turf)) - // T.firelevel = 0 //TODO: FIX if (--src.life < 1) - //SN src = null - delete() + qdel(src) + return 0 if(newloc.density) return 0 .=..() @@ -71,7 +63,7 @@ steam.start() -- spawns the effect spawn(0) if(holder) src.location = get_turf(holder) - var/obj/effect/effect/steam/steam = new /obj/effect/effect/steam(src.location) + var/obj/effect/effect/steam/steam = PoolOrNew(/obj/effect/effect/steam, location) var/direction if(src.cardinals) direction = pick(cardinal) @@ -81,7 +73,7 @@ steam.start() -- spawns the effect sleep(5) step(steam,direction) spawn(20) - steam.delete() + qdel(steam) ///////////////////////////////////////////// @@ -106,12 +98,12 @@ steam.start() -- spawns the effect src.processing = 0 spawn(0) if(src.number < 3) - var/obj/effect/effect/steam/I = new /obj/effect/effect/steam(src.oldposition) + var/obj/effect/effect/steam/I = PoolOrNew(/obj/effect/effect/steam, oldposition) src.number++ src.oldposition = get_turf(holder) I.dir = src.holder.dir spawn(10) - I.delete() + qdel(I) src.number-- spawn(2) if(src.on) diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm index aa9c969d34f..538e98cb003 100644 --- a/code/game/objects/effects/spawners/lootdrop.dm +++ b/code/game/objects/effects/spawners/lootdrop.dm @@ -116,8 +116,5 @@ /obj/item/weapon/wirecutters = 1, /obj/item/weapon/wrench = 4, /obj/item/weapon/relic = 3, - /obj/item/weapon/reagent_containers/food/drinks/muriatic_acid = 3, - /obj/item/weapon/reagent_containers/food/drinks/caustic_soda = 3, - /obj/item/weapon/reagent_containers/food/drinks/hydrogen_chloride = 3, "" = 11 ) diff --git a/code/game/objects/empulse.dm b/code/game/objects/empulse.dm index 4ccb47e18cd..4f6350832ae 100644 --- a/code/game/objects/empulse.dm +++ b/code/game/objects/empulse.dm @@ -15,7 +15,7 @@ proc/empulse(turf/epicenter, heavy_range, light_range, log=0) pulse.name = "emp pulse" pulse.anchored = 1 spawn(20) - pulse.delete() + qdel(pulse) if(heavy_range > light_range) light_range = heavy_range diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm index 902fccd1660..45efaba9b5e 100644 --- a/code/game/objects/explosion.dm +++ b/code/game/objects/explosion.dm @@ -19,7 +19,7 @@ proc/trange(var/Dist=0,var/turf/Center=null)//alternative to range (ONLY process return block(x1y1,x2y2) -proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, ignorecap = 0, flame_range = 0) +proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, ignorecap = 0, flame_range = 0 ,silent = 0) src = null //so we don't abort once src is deleted epicenter = get_turf(epicenter) @@ -56,21 +56,22 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa far_dist += heavy_impact_range * 5 far_dist += devastation_range * 20 - var/frequency = get_rand_frequency() - for(var/mob/M in player_list) - // Double check for client - if(M && M.client) - var/turf/M_turf = get_turf(M) - if(M_turf && M_turf.z == epicenter.z) - var/dist = get_dist(M_turf, epicenter) - // If inside the blast radius + world.view - 2 - if(dist <= round(max_range + world.view - 2, 1)) - M.playsound_local(epicenter, get_sfx("explosion"), 100, 1, frequency, falloff = 5) // get_sfx() is so that everyone gets the same sound - // You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station. - else if(dist <= far_dist) - var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist - far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion - M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5) + if(!silent) + var/frequency = get_rand_frequency() + for(var/mob/M in player_list) + // Double check for client + if(M && M.client) + var/turf/M_turf = get_turf(M) + if(M_turf && M_turf.z == epicenter.z) + var/dist = get_dist(M_turf, epicenter) + // If inside the blast radius + world.view - 2 + if(dist <= round(max_range + world.view - 2, 1)) + M.playsound_local(epicenter, get_sfx("explosion"), 100, 1, frequency, falloff = 5) // get_sfx() is so that everyone gets the same sound + // You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station. + else if(dist <= far_dist) + var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist + far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion + M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5) //postpone light processing for a bit SSlighting.postpone() diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 7822199a274..20706d966fb 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -37,13 +37,13 @@ var/list/armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) var/list/allowed = null //suit storage stuff. var/obj/item/device/uplink/hidden/hidden_uplink = null // All items can have an uplink hidden inside, just remember to add the triggers. - var/reflect_chance = 0 //This var dictates what % of a time an object will reflect an energy based weapon's shot var/strip_delay = 40 var/put_on_delay = 20 var/m_amt = 0 // metal var/g_amt = 0 // glass var/reliability = 100 //Used by SOME devices to determine how reliable they are. var/origin_tech = null //Used by R&D to determine what research bonuses it grants. + var/needs_permit = 0 //Used by security bots to determine if this item is safe for public use. var/list/attack_verb = list() //Used in attackby() to say how something was attacked "[x] has been [z.attack_verb] by [y] with [z]" var/list/species_exception = list() // even if a species cannot put items in a certain slot, if the species id is in the item's exception list, it will be able to wear that item @@ -243,7 +243,7 @@ // afterattack() and attack() prototypes moved to _onclick/item_attack.dm for consistency -/obj/item/proc/talk_into(mob/M as mob, text) +/obj/item/proc/talk_into(mob/M, input, channel, spans) return /obj/item/proc/dropped(mob/user as mob) @@ -315,8 +315,7 @@ return 0 /obj/item/proc/IsReflect(var/def_zone) //This proc determines if and at what% an object will reflect energy projectiles if it's in l_hand,r_hand or wear_suit - if(prob(reflect_chance)) - return 1 + return 0 /obj/item/proc/eyestab(mob/living/carbon/M as mob, mob/living/carbon/user as mob) @@ -338,7 +337,7 @@ user << "You're going to need to remove that mask/helmet/glasses first." return - if(istype(M, /mob/living/carbon/alien) || istype(M, /mob/living/carbon/slime))//Aliens don't have eyes./N slimes also don't have eyes! + if(isalien(M))//Aliens don't have eyes./N slimes also don't have eyes! user << "You cannot locate any eyes on this creature!" return diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm index a7df044de11..0c5002a60f5 100644 --- a/code/game/objects/items/blueprints.dm +++ b/code/game/objects/items/blueprints.dm @@ -51,6 +51,7 @@ desc = "This is a one-use permit that allows the user to offically declare a built room as new addition to the station." fluffnotice = "Nanotrasen Engineering requires all on-station construction projects to be approved by a head of staff, as detailed in Nanotrasen Company Regulation 512-C (Mid-Shift Modifications to Company Property). \ By submitting this form, you accept any fines, fees, or personal injury/death that may occur during construction." + w_class = 1 /obj/item/areaeditor/permit/attack_self(mob/user as mob) diff --git a/code/game/objects/items/body_egg.dm b/code/game/objects/items/body_egg.dm new file mode 100644 index 00000000000..b1ab40cb28b --- /dev/null +++ b/code/game/objects/items/body_egg.dm @@ -0,0 +1,57 @@ +/obj/item/body_egg + name = "generic egg" + desc = "All slimy and yuck." + icon = 'icons/mob/alien.dmi' + icon_state = "larva0_dead" + var/mob/living/affected_mob + +/obj/item/body_egg/New() + if(istype(loc, /mob/living)) + affected_mob = loc + affected_mob.status_flags |= XENO_HOST + SSobj.processing |= src + if(istype(affected_mob,/mob/living/carbon)) + var/mob/living/carbon/H = affected_mob + H.med_hud_set_status() + spawn(0) + AddInfectionImages(affected_mob) + else + qdel(src) + +/obj/item/body_egg/Destroy() + if(affected_mob) + affected_mob.status_flags &= ~(XENO_HOST) + if(istype(affected_mob,/mob/living/carbon)) + var/mob/living/carbon/H = affected_mob + H.med_hud_set_status() + spawn(0) + RemoveInfectionImages(affected_mob) + ..() + +/obj/item/body_egg/process() + if(!affected_mob) return + if(loc != affected_mob) + affected_mob.status_flags &= ~(XENO_HOST) + SSobj.processing.Remove(src) + if(istype(affected_mob,/mob/living/carbon)) + var/mob/living/carbon/H = affected_mob + H.med_hud_set_status() + spawn(0) + RemoveInfectionImages(affected_mob) + affected_mob = null + return + + egg_process() + +/obj/item/body_egg/proc/egg_process() + return + +/obj/item/body_egg/proc/RefreshInfectionImage() + RemoveInfectionImages() + AddInfectionImages() + +/obj/item/body_egg/proc/AddInfectionImages() + return + +/obj/item/body_egg/proc/RemoveInfectionImages() + return \ No newline at end of file diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index 6450218c3d8..0fae4cdfa6e 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -111,4 +111,4 @@ foldedbag_path = /obj/item/bodybag/bluespace density = 0 mob_storage_capacity = 15 - max_mob_size = 2 \ No newline at end of file + max_mob_size = MOB_SIZE_LARGE \ No newline at end of file diff --git a/code/game/objects/items/devices/chameleonproj.dm b/code/game/objects/items/devices/chameleonproj.dm index 6319441cb71..f7b754a93d5 100644 --- a/code/game/objects/items/devices/chameleonproj.dm +++ b/code/game/objects/items/devices/chameleonproj.dm @@ -49,7 +49,8 @@ var/obj/effect/overlay/T = new/obj/effect/overlay(get_turf(src)) T.icon = 'icons/effects/effects.dmi' flick("emppulse",T) - spawn(8) T.delete() + spawn(8) + qdel(T) else playsound(get_turf(src), 'sound/effects/pop.ogg', 100, 1, -6) var/obj/O = new saved_item(src) @@ -61,7 +62,8 @@ var/obj/effect/overlay/T = new/obj/effect/overlay(get_turf(src)) T.icon = 'icons/effects/effects.dmi' flick("emppulse",T) - spawn(8) T.delete() + spawn(8) + qdel(T) /obj/item/device/chameleon/proc/disrupt(var/delete_dummy = 1) if(active_dummy) diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm index 5496413aff1..3e9018cb1bb 100644 --- a/code/game/objects/items/devices/flash.dm +++ b/code/game/objects/items/devices/flash.dm @@ -59,19 +59,22 @@ /obj/item/device/flash/proc/flash_carbon(var/mob/living/carbon/M, var/mob/user = null, var/power = 5, targeted = 1) add_logs(user, M, "flashed", object="[src.name]") - var/safety = M.eyecheck() - if(safety <= 0) - M.confused += power - flick("e_flash", M.flash) - if(user && targeted) + if(user && targeted) + if(M.weakeyes) + M.Weaken(3) //quick weaken bypasses eye protection but has no eye flash + if(M.flash_eyes(1, 1)) + M.confused += power terrible_conversion_proc(M, user) M.Stun(1) user.visible_message("[user] blinds [M] with the flash!") - return 1 - else - if(user && targeted) + if(M.weakeyes) + M.Stun(2) + M.visible_message("[M] gasps and shields their eyes!") + else user.visible_message("[user] fails to blind [M] with the flash!") - return 0 + else + if(M.flash_eyes()) + M.confused += power /obj/item/device/flash/attack(mob/living/M, mob/user) if(!try_use_flash(user)) @@ -82,8 +85,9 @@ return 1 else if(issilicon(M)) - M.Weaken(rand(5,10)) add_logs(user, M, "flashed", object="[src.name]") + flick("e_flash", M.flash) + M.Weaken(rand(5,10)) user.visible_message("[user] overloads [M]'s sensors with the flash!") return 1 diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm index fc6892d28aa..d773852de9b 100644 --- a/code/game/objects/items/devices/laserpointer.dm +++ b/code/game/objects/items/devices/laserpointer.dm @@ -96,52 +96,21 @@ //human/alien mobs if(iscarbon(target)) + var/mob/living/carbon/C = target if(user.zone_sel.selecting == "eyes") - var/mob/living/carbon/C = target + add_logs(user, C, "shone in the eyes", object="laser pointer") + + var/severity = 1 + if(prob(33)) + severity = 2 + else if(prob(50)) + severity = 0 //20% chance to actually hit the eyes - if(prob(effectchance * diode.rating)) - add_logs(user, C, "shone in the eyes", object="laser pointer") - - //eye target check + if(prob(effectchance * diode.rating) && C.flash_eyes(severity)) outmsg = "You blind [C] by shining [src] in their eyes." - var/eye_prot = C.eyecheck() - if(C.eye_blind || eye_prot >= 2) - eye_prot = 4 - var/severity = 3 - eye_prot - if(prob(33)) - severity += 1 - else if(prob(50)) - severity -= 1 - severity = min(max(severity, 0), 4) - - switch(severity) - if(0) - //no effect - C << "A small, bright dot appears in your vision." - if(1) - //industrial grade eye protection - C.eye_stat += rand(0, 2) - C << "Something bright flashes in the corner of your vision!" - if(2) - //basic eye protection (sunglasses) - flick("flash", C.flash) - C.eye_stat += rand(1, 6) - C << "Your eyes were blinded!" - if(3) - //no eye protection - if(prob(2)) - C.Weaken(1) - flick("e_flash", C.flash) - C.eye_stat += rand(3, 7) - C << "Your eyes were blinded!" - if(4) - //the effect has been worsened by something - if(prob(5)) - C.Weaken(1) - flick("e_flash", C.flash) - C.eye_stat += rand(5, 10) - C << "Your eyes were blinded!" + if(C.weakeyes) + C.Stun(1) else outmsg = "You fail to blind [C] by shining [src] at their eyes." @@ -150,6 +119,7 @@ var/mob/living/silicon/S = target //20% chance to actually hit the sensors if(prob(effectchance * diode.rating)) + flick("e_flash", S.flash) S.Weaken(rand(5,10)) S << "Your sensors were overloaded by a laser!" outmsg = "You overload [S] by shining [src] at their sensors." diff --git a/code/game/objects/items/devices/radio/beacon.dm b/code/game/objects/items/devices/radio/beacon.dm index a8e111e3097..eff5162edfb 100644 --- a/code/game/objects/items/devices/radio/beacon.dm +++ b/code/game/objects/items/devices/radio/beacon.dm @@ -6,10 +6,9 @@ var/code = "electronic" origin_tech = "bluespace=1" -/obj/item/device/radio/beacon/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq) +/obj/item/device/radio/beacon/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans) return - /obj/item/device/radio/beacon/send_hear() return null diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index a008a70b8bb..e87eb6da388 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -23,7 +23,7 @@ keyslot2 = null ..() -/obj/item/device/radio/headset/talk_into(mob/living/M as mob, message, channel) +/obj/item/device/radio/headset/talk_into(mob/living/M, message, channel, list/spans) if (!listening) return ..() diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index 41410f8594b..195ba80422d 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -50,7 +50,7 @@ return canhear_range -/obj/item/device/radio/intercom/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq) +/obj/item/device/radio/intercom/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans) if(!anyai && !(speaker in ai)) return ..() diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 8b038de7814..816c0f37b0a 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -233,7 +233,7 @@ /obj/item/device/radio/proc/isWireCut(var/index) return wires.IsIndexCut(index) -/obj/item/device/radio/talk_into(atom/movable/M, message, channel) +/obj/item/device/radio/talk_into(atom/movable/M, message, channel, list/spans) if(!on) return // the device has to be on // Fix for permacell radios, but kinda eh about actually fixing them. if(!M || !message) return @@ -359,7 +359,12 @@ "server" = null, // the last server to log this signal "reject" = 0, // if nonzero, the signal will not be accepted by any broadcasting machinery "level" = position.z, // The source's z level - "languages" = M.languages //The languages M is talking in. + "languages" = M.languages, //The languages M is talking in. + "spans" = spans, //the span classes of this message. + "verb_say" = M.verb_say, //the verb used when talking normally + "verb_ask" = M.verb_ask, //the verb used when asking + "verb_exclaim" = M.verb_exclaim, //the verb used when exclaiming + "verb_yell" = M.verb_yell //the verb used when yelling ) signal.frequency = freq @@ -403,7 +408,13 @@ "type" = 0, "server" = null, "reject" = 0, - "level" = position.z + "level" = position.z, + "languages" = languages, + "spans" = spans, + "verb_say" = M.verb_say, + "verb_ask" = M.verb_ask, + "verb_exclaim" = M.verb_exclaim, + "verb_yell" = M.verb_yell ) signal.frequency = text2num(freq) // Quick frequency set for(var/obj/machinery/telecomms/receiver/R in telecomms_list) @@ -420,14 +431,15 @@ // Send a mundane broadcast with limited targets: Broadcast_Message(M, voicemask, src, message, voice, jobname, real_name, - filter_type, signal.data["compression"], list(position.z), freq) + filter_type, signal.data["compression"], list(position.z), freq, spans, + verb_say, verb_ask, verb_exclaim, verb_yell) -/obj/item/device/radio/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq) +/obj/item/device/radio/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans) if(radio_freq) return if(broadcasting) if(get_dist(src, speaker) <= canhear_range) - talk_into(speaker, raw_message) + talk_into(speaker, raw_message, , spans) /* /obj/item/device/radio/proc/accept_rad(obj/item/device/radio/R as obj, message) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 833cf976128..487345421fd 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -123,6 +123,10 @@ MASS SPECTROMETER mob_status = "Deceased" oxy_loss = max(rand(1, 40), oxy_loss, (300 - (tox_loss + fire_loss + brute_loss))) // Random oxygen loss + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(H.heart_attack) + user.show_message("Subject suffering from heart attack: Apply defibrillator immediately.") user.show_message(text("Analyzing Results for []:\n\t Overall Status: []", M, mob_status), 1) if(ishuman(M)) var/mob/living/carbon/human/H = M @@ -196,11 +200,11 @@ MASS SPECTROMETER if(H.reagents.reagent_list.len) user.show_message("Subject contains the following reagents:") for(var/datum/reagent/R in H.reagents.reagent_list) - user.show_message("[R.volume]u of [R.name][R.overdosed == 1 ? " - OVERDOSING" : "."]") + user.show_message("[R.volume]u of [R.name][R.overdosed == 1 ? " - OVERDOSING" : "."]") else user.show_message("Subject contains no reagents.") if(H.reagents.addiction_list.len) - user.show_message("Subject is addicted to the following reagents:") + user.show_message("Subject is addicted to the following reagents:") for(var/datum/reagent/R in H.reagents.addiction_list) user.show_message("[R.name]") else @@ -381,7 +385,7 @@ MASS SPECTROMETER if (!isslime(M)) user.show_message("This device can only scan slimes!", 1) return - var/mob/living/carbon/slime/T = M + var/mob/living/simple_animal/slime/T = M user.show_message("Slime scan results:", 1) user.show_message(text("[T.colour] [] slime", T.is_adult ? "adult" : "baby"), 1) user.show_message(text("Nutrition: [T.nutrition]/[]", T.get_max_nutrition()), 1) diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm index ff22ee44971..8258d6dc4e2 100644 --- a/code/game/objects/items/devices/taperecorder.dm +++ b/code/game/objects/items/devices/taperecorder.dm @@ -97,7 +97,7 @@ icon_state = "taperecorder_idle" -/obj/item/device/taperecorder/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq) +/obj/item/device/taperecorder/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans) if(mytape && recording) mytape.timestamp += mytape.used_capacity mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [strip_html_properly(message)]" diff --git a/code/game/objects/items/devices/violin.dm b/code/game/objects/items/devices/violin.dm index dcc3c309c1e..e8481778326 100644 --- a/code/game/objects/items/devices/violin.dm +++ b/code/game/objects/items/devices/violin.dm @@ -19,6 +19,10 @@ song = null ..() +/obj/item/device/violin/initialize() + song.tempo = song.sanitize_tempo(song.tempo) // tick_lag isn't set when the map is loaded + ..() + /obj/item/device/violin/attack_self(mob/user as mob) if(!user.IsAdvancedToolUser()) user << "You don't have the dexterity to do this!" diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index b7ab6bf02d5..01dc031a466 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -171,7 +171,27 @@ qdel(D) for(var/obj/item/weapon/shovel/S in R.module.modules) qdel(S) - R.module.modules += new /obj/item/weapon/pickaxe/drill/diamonddrill(src) + R.module.modules += new /obj/item/weapon/pickaxe/drill/diamonddrill(R.module) + R.module.rebuild() + return 1 + +/obj/item/borg/upgrade/soh + name = "mining cyborg satchel of holding" + desc = "A satchel of holding replacement for mining cyborg's ore satchel module." + icon_state = "cyborg_upgrade3" + require_module = 1 + +/obj/item/borg/upgrade/soh/action(var/mob/living/silicon/robot/R) + if(..()) return 0 + + if(!istype(R.module, /obj/item/weapon/robot_module/miner)) + R << "Upgrade mounting error! No suitable hardpoint detected!" + usr << "There's no mounting point for the module!" + return 0 + else + for(var/obj/item/weapon/storage/bag/ore/cyborg/S in R.module.modules) + qdel(S) + R.module.modules += new /obj/item/weapon/storage/bag/ore/holding(R.module) R.module.rebuild() return 1 diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index 3e8c37ccb9a..e30fe1dda80 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -62,6 +62,7 @@ if(!user.IsAdvancedToolUser()) user << "You don't have the dexterity to do this!" return 0 + if(zero_amount()) return 0 var/title = "Sheet-Glass" title += " ([src.get_amount()] sheet\s left)" switch(alert(title, "Would you like full tile glass or one direction?", "One Direction", "Full Window", "Cancel", null)) diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 2a912e4319f..b941b9228d7 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -173,17 +173,24 @@ return 1 /obj/item/stack/proc/use(var/used) // return 0 = borked; return 1 = had enough + if(zero_amount()) + return 0 if (is_cyborg) return source.use_charge(used * cost) if (amount < used) return 0 amount -= used - if (amount <= 0) + zero_amount() + update_icon() + return 1 + +/obj/item/stack/proc/zero_amount() + if (amount < 1) if(usr) usr.unEquip(src, 1) qdel(src) - update_icon() - return 1 + return 1 + return 0 /obj/item/stack/proc/add(var/amount) if (is_cyborg) @@ -210,6 +217,7 @@ /obj/item/stack/attack_hand(mob/user as mob) if (user.get_inactive_hand() == src) + if(zero_amount()) return var/obj/item/stack/F = new src.type( user, 1) F.copy_evidences(src) user.put_in_hands(F) @@ -225,6 +233,7 @@ /obj/item/stack/attackby(obj/item/W as obj, mob/user as mob, params) if (istype(W, src.type)) + if(zero_amount()) return var/obj/item/stack/S = W if (S.is_cyborg) var/to_transfer = min(src.amount, round((S.source.max_energy - S.source.energy) / S.cost)) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index f21f71a1fa0..6d72b88b05d 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -186,120 +186,6 @@ ..() user << "There [amount_left == 1 ? "is" : "are"] [amount_left] cap\s left." -/* - * Toy crossbow - */ - -/obj/item/toy/crossbow - name = "foam dart crossbow" - desc = "A weapon favored by many overactive children. Ages 8 and up." - icon = 'icons/obj/guns/energy.dmi' - icon_state = "crossbow100" - item_state = "crossbow" - lefthand_file = 'icons/mob/inhands/guns_lefthand.dmi' - righthand_file = 'icons/mob/inhands/guns_righthand.dmi' - w_class = 2.0 - attack_verb = list("attacked", "struck", "hit") - var/bullets = 5 - -/obj/item/toy/crossbow/examine(mob/user) - ..() - if (bullets) - user << "It is loaded with [bullets] foam dart\s." - -/obj/item/toy/crossbow/attackby(obj/item/I as obj, mob/user as mob, params) - if(istype(I, /obj/item/toy/ammo/crossbow)) - if(bullets <= 4) - user.drop_item() - qdel(I) - bullets++ - user << "You load the foam dart into the crossbow." - else - usr << "It's already fully loaded." - - -/obj/item/toy/crossbow/afterattack(atom/target as mob|obj|turf|area, mob/user as mob, flag) - if(!isturf(target.loc) || target == user) return - if(flag) return - - if (locate (/obj/structure/table, src.loc)) - return - else if (bullets) - var/turf/trg = get_turf(target) - var/obj/effect/foam_dart_dummy/D = new/obj/effect/foam_dart_dummy(get_turf(src)) - bullets-- - D.icon_state = "foamdart" - D.name = "foam dart" - playsound(user.loc, 'sound/items/syringeproj.ogg', 50, 1) - - for(var/i=0, i<6, i++) - if (D) - if(D.loc == trg) break - step_towards(D,trg) - - for(var/mob/living/M in D.loc) - if(!istype(M,/mob/living)) continue - if(M == user) continue - D.visible_message("[M] was hit by the foam dart!") - new /obj/item/toy/ammo/crossbow(M.loc) - qdel(D) - return - - for(var/atom/A in D.loc) - if(A == user) continue - if(A.density) - new /obj/item/toy/ammo/crossbow(A.loc) - qdel(D) - - sleep(1) - - spawn(10) - if(D) - new /obj/item/toy/ammo/crossbow(D.loc) - qdel(D) - - return - else if (bullets == 0) - user.Weaken(5) - user.visible_message("[user] realized they were out of ammo and starting scrounging for some!") - - -/obj/item/toy/crossbow/attack(mob/M as mob, mob/user as mob) - src.add_fingerprint(user) - -// ******* Check - - if (src.bullets > 0 && M.lying) - - M.visible_message("[user] casually lines up a shot with [M]'s head and pulls the trigger!") - M.visible_message("[M] was hit in the head by the foam dart!", \ - "You're hit in the head by the foam dart!", \ - "You hear the sound of foam against skull.") - - playsound(user.loc, 'sound/items/syringeproj.ogg', 50, 1) - new /obj/item/toy/ammo/crossbow(M.loc) - src.bullets-- - else if (M.lying && src.bullets == 0) - M.visible_message("[user] casually lines up a shot with [M]'s head, pulls the trigger, then realizes they are out of ammo and drops to the floor in search of some!") - user.Weaken(5) - return - -/obj/item/toy/ammo/crossbow - name = "foam dart" - desc = "Its nerf or nothing! Ages 8 and up." - icon = 'icons/obj/toy.dmi' - icon_state = "foamdart" - w_class = 1.0 - -/obj/effect/foam_dart_dummy - name = "" - desc = "" - icon = 'icons/obj/toy.dmi' - icon_state = "null" - anchored = 1 - density = 0 - - /* * Toy swords */ @@ -434,8 +320,9 @@ attack_verb = list("attacked", "coloured") var/colour = "#FF0000" //RGB var/drawtype = "rune" - var/list/graffiti = list("amyjon","face","matt","revolution","engie","guy","end","dwarf","uboa","body","cyka") + var/list/graffiti = list("amyjon","face","matt","revolution","engie","guy","end","dwarf","uboa","body","cyka","arrow") var/list/letters = list("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z") + var/list/oriented = list("arrow","body") // These turn to face the same way as the drawer var/uses = 30 //0 for unlimited uses var/instant = 0 var/colourName = "red" //for updateIcon purposes @@ -515,9 +402,20 @@ temp = "letter" else if(graffiti.Find(drawtype)) temp = "graffiti" + var/graf_rot + if(oriented.Find(drawtype)) + switch(user.dir) + if(EAST) + graf_rot = 90 + if(SOUTH) + graf_rot = 180 + if(WEST) + graf_rot = 270 + else + graf_rot = 0 user << "You start drawing a [temp] on the [target.name]." if(instant || do_after(user, 50)) - new /obj/effect/decal/cleanable/crayon(target,colour,drawtype,temp) + new /obj/effect/decal/cleanable/crayon(target,colour,drawtype,temp,graf_rot) user << "You finish drawing [temp]." if(uses) uses-- diff --git a/code/game/objects/items/weapons/AI_modules.dm b/code/game/objects/items/weapons/AI_modules.dm index d1d30653cac..57f667ac382 100644 --- a/code/game/objects/items/weapons/AI_modules.dm +++ b/code/game/objects/items/weapons/AI_modules.dm @@ -43,12 +43,14 @@ AI MODULES var/law2log = src.transmitInstructions(reciever, user) //Freeforms return something extra we need to log user << "Upload complete. [reciever]'s laws have been modified." reciever.show_laws() + reciever.law_change_counter++ if(isAI(reciever)) var/mob/living/silicon/ai/A = reciever for(var/mob/living/silicon/robot/R in A.connected_robots) if(R.lawupdate) R << "From now on, these are your laws:" R.show_laws() + R.law_change_counter++ var/time = time2text(world.realtime,"hh:mm:ss") lawchanges.Add("[time] : [user.name]([user.key]) used [src.name] on [reciever.name]([reciever.key]).[law2log ? " The law specified [law2log]" : ""]") diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm index b71c719761a..e76181e672a 100644 --- a/code/game/objects/items/weapons/RCD.dm +++ b/code/game/objects/items/weapons/RCD.dm @@ -100,6 +100,11 @@ RCD return +/obj/item/weapon/rcd/Destroy() + qdel(spark_system) + spark_system = null + return ..() + /obj/item/weapon/rcd/attackby(obj/item/weapon/W, mob/user, params) ..() if(istype(W, /obj/item/weapon/rcd_ammo)) diff --git a/code/game/objects/items/weapons/courtroom.dm b/code/game/objects/items/weapons/courtroom.dm new file mode 100644 index 00000000000..c3f62193260 --- /dev/null +++ b/code/game/objects/items/weapons/courtroom.dm @@ -0,0 +1,35 @@ +// Contains: +// Gavel Hammer +// Gavel Block + +/obj/item/weapon/gavelhammer + name = "gavel hammer" + desc = "Order, order! No bombs in my courthouse." + icon = 'icons/obj/items.dmi' + icon_state = "gavelhammer" + force = 5.0 + throwforce = 6.0 + w_class = 2.0 + attack_verb = list("bashed", "battered", "judged", "whacked") + +/obj/item/weapon/gavelhammer/suicide_act(mob/user) + user.visible_message("[user] has sentenced \himself to death with the [src.name]! It looks like \he's trying to commit suicide.") + playsound(loc, 'sound/items/gavel.ogg', 50, 1, -1) + return (BRUTELOSS) + +/obj/item/weapon/gavelblock + name = "gavel block" + desc = "Smack it with a gavel hammer when the assistants get rowdy." + icon = 'icons/obj/items.dmi' + icon_state = "gavelblock" + force = 2.0 + throwforce = 2.0 + w_class = 1.0 + +/obj/item/weapon/gavelblock/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/weapon/gavelhammer)) + playsound(loc, 'sound/items/gavel.ogg', 100, 1) + user.visible_message("[user] strikes \the [src] with \the [I].") + user.changeNext_move(CLICK_CD_MELEE) + else + return \ No newline at end of file diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index ad5cb815cfa..fae1e6b4063 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -381,6 +381,9 @@ busy = 0 update_icon() return + if(H.heart_attack) + H.heart_attack = 0 + user.visible_message("[defib] pings: Patient's heart is now beating again.") if(H.stat == 2) var/health = H.health M.visible_message("[M]'s body convulses a bit.") diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm index e1e8d500734..e82f7403012 100644 --- a/code/game/objects/items/weapons/explosives.dm +++ b/code/game/objects/items/weapons/explosives.dm @@ -22,7 +22,6 @@ ..() /obj/item/weapon/c4/suicide_act(var/mob/user) - . = BRUTELOSS user.visible_message("[user] activates the [src.name] and holds it above his head! It looks like \he's going out with a bang!") var/message_say = "FOR NO RAISIN!" if(user.mind) @@ -33,12 +32,15 @@ else if(role == "changeling") message_say = "FOR THE HIVE!" else if(role == "cultist") - message_say = "FOR NARSIE!" + message_say = "FOR NAR-SIE!" + else if(role == "revolutionary" || role == "head revolutionary") + 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) + sleep(10) explode(get_turf(user)) - return . + user.gib() /obj/item/weapon/c4/attackby(var/obj/item/I, var/mob/user, params) if(istype(I, /obj/item/weapon/screwdriver)) @@ -61,6 +63,9 @@ return if (ismob(target) || istype(target, /turf/unsimulated) || istype(target, /turf/simulated/shuttle) || istype(target, /obj/item/weapon/storage/)) return + if(loc == target) + return + user << "Planting explosives..." if(do_after(user, 50) && in_range(user, target)) @@ -94,4 +99,4 @@ qdel(src) /obj/item/weapon/c4/attack(mob/M as mob, mob/user as mob, def_zone) - return \ No newline at end of file + return diff --git a/code/game/objects/items/weapons/extinguisher.dm b/code/game/objects/items/weapons/extinguisher.dm index 3b06377cccf..f4dd08ea68f 100644 --- a/code/game/objects/items/weapons/extinguisher.dm +++ b/code/game/objects/items/weapons/extinguisher.dm @@ -124,7 +124,7 @@ for(var/a=0, a<5, a++) spawn(0) - var/obj/effect/effect/water/W = new /obj/effect/effect/water( get_turf(src) ) + var/obj/effect/effect/water/W = PoolOrNew( /obj/effect/effect/water, get_turf(src) ) var/turf/my_target = pick(the_targets) if(precision) the_targets -= my_target diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm index 558844c688c..3a3e29af17d 100644 --- a/code/game/objects/items/weapons/flamethrower.dm +++ b/code/game/objects/items/weapons/flamethrower.dm @@ -157,6 +157,10 @@ update_icon() return +/obj/item/weapon/flamethrower/CheckParts() + weldtool = locate(/obj/item/weapon/weldingtool) in contents + igniter = locate(/obj/item/device/assembly/igniter) in contents + update_icon() //Called from turf.dm turf/dblclick /obj/item/weapon/flamethrower/proc/flame_turf(turflist) @@ -195,9 +199,11 @@ /obj/item/weapon/flamethrower/full/New(var/loc) ..() - weldtool = new /obj/item/weapon/weldingtool(src) + if(!weldtool) + weldtool = new /obj/item/weapon/weldingtool(src) weldtool.status = 0 - igniter = new /obj/item/device/assembly/igniter(src) + if(!igniter) + igniter = new /obj/item/device/assembly/igniter(src) igniter.secured = 0 status = 1 update_icon() @@ -205,4 +211,4 @@ /obj/item/weapon/flamethrower/full/tank/New(var/loc) ..() ptank = new /obj/item/weapon/tank/internals/plasma/full(src) - update_icon() \ No newline at end of file + update_icon() diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm index bda6191104b..5826fe552f9 100644 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm @@ -388,6 +388,25 @@ beakers += B1 beakers += B2 +/obj/item/weapon/grenade/chem_grenade/clf3 + name = "clf3 grenade" + desc = "BURN!-brand foaming clf3. In a special applicator for rapid purging of wide areas." + stage = READY + +/obj/item/weapon/grenade/chem_grenade/clf3/New() + ..() + var/obj/item/weapon/reagent_containers/glass/beaker/bluespace/B1 = new(src) + var/obj/item/weapon/reagent_containers/glass/beaker/bluespace/B2 = new(src) + + B1.reagents.add_reagent("fluorosurfactant", 290) + B1.reagents.add_reagent("clf3", 10) + B2.reagents.add_reagent("water", 290) + B2.reagents.add_reagent("clf3", 10) + + beakers += B1 + beakers += B2 + + #undef EMPTY #undef WIRED #undef READY diff --git a/code/game/objects/items/weapons/grenades/clusterbuster.dm b/code/game/objects/items/weapons/grenades/clusterbuster.dm index 63d4c41aa1c..31576237a04 100644 --- a/code/game/objects/items/weapons/grenades/clusterbuster.dm +++ b/code/game/objects/items/weapons/grenades/clusterbuster.dm @@ -76,7 +76,6 @@ ///////////////////////////////// /obj/item/weapon/grenade/flashbang/cluster icon_state = "flashbang_active" - banglet = 1 /obj/item/weapon/grenade/clusterbuster/emp name = "Electromagnetic Storm" diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm index 6db5b1f306d..9c39b6c5f3d 100644 --- a/code/game/objects/items/weapons/grenades/flashbang.dm +++ b/code/game/objects/items/weapons/grenades/flashbang.dm @@ -3,7 +3,6 @@ icon_state = "flashbang" item_state = "flashbang" origin_tech = "materials=2;combat=1" - var/banglet = 0 /obj/item/weapon/grenade/flashbang/prime() update_mob() @@ -23,33 +22,23 @@ M.show_message("BANG", 2) playsound(loc, 'sound/effects/bang.ogg', 25, 1) -//Checking for protections - var/eye_safety = 0 - var/ear_safety = 0 +//Checking for protection + var/ear_safety = M.check_ear_prot() var/distance = max(1,get_dist(src,T)) - var/takes_eye_damage = 0 - if(iscarbon(M)) - takes_eye_damage++ - var/mob/living/carbon/C = M - eye_safety = C.eyecheck() - if(ishuman(C)) - var/mob/living/carbon/human/H = C - if((H.ears && (H.ears.flags & EARBANGPROTECT)) || (H.head && (H.head.flags & HEADBANGPROTECT))) - ear_safety++ //Flash - if(!eye_safety) - flick("e_flash", M.flash) + if(M.weakeyes) + M.visible_message("[M] screams and collapses!") + M << "AAAAGH!" + M.Weaken(15) //hella stunned + M.Stun(15) + M.eye_stat += 8 + + if(M.flash_eyes()) M.eye_stat += rand(1, 3) M.Stun(max(10/distance, 3)) M.Weaken(max(10/distance, 3)) - if (M.eye_stat >= 20 && takes_eye_damage) - M << "Your eyes start to burn badly!" - M.disabilities |= NEARSIGHT - if(!banglet) - if (prob(M.eye_stat - 20 + 1)) - M << "You can't see anything!" - M.disabilities |= BLIND + //Bang if((loc == M) || loc == M.loc)//Holding on person or being exactly where lies is significantly more dangerous and voids protection @@ -61,10 +50,9 @@ M.setEarDamage(M.ear_damage + rand(0, 5), max(M.ear_deaf,15)) if (M.ear_damage >= 15) M << "Your ears start to ring badly!" - if(!banglet) - if(prob(M.ear_damage - 10 + 5)) - M << "You can't hear anything!" - M.disabilities |= DEAF + if(prob(M.ear_damage - 10 + 5)) + M << "You can't hear anything!" + M.disabilities |= DEAF else if (M.ear_damage >= 5) M << "Your ears start to ring!" diff --git a/code/game/objects/items/weapons/grenades/spawnergrenade.dm b/code/game/objects/items/weapons/grenades/spawnergrenade.dm index c104bfd9c73..9edf321b7e8 100644 --- a/code/game/objects/items/weapons/grenades/spawnergrenade.dm +++ b/code/game/objects/items/weapons/grenades/spawnergrenade.dm @@ -5,7 +5,6 @@ icon_state = "delivery" item_state = "flashbang" origin_tech = "materials=3;magnets=4" - var/banglet = 0 var/spawner_type = null // must be an object path var/deliveryamt = 1 // amount of type to deliver @@ -16,8 +15,7 @@ var/turf/T = get_turf(src) playsound(T, 'sound/effects/phasein.ogg', 100, 1) for(var/mob/living/carbon/human/M in viewers(T, null)) - if(M:eyecheck() <= 0) - flick("e_flash", M.flash) // flash dose faggots + M.flash_eyes() for(var/i=1, i<=deliveryamt, i++) var/atom/movable/x = new spawner_type diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm index 749a4b281ce..a8b7ae88590 100644 --- a/code/game/objects/items/weapons/implants/implant.dm +++ b/code/game/objects/items/weapons/implants/implant.dm @@ -141,7 +141,12 @@ /obj/item/weapon/implant/chem/activate(var/cause) if(!cause || !imp_in) return 0 var/mob/living/carbon/R = imp_in - reagents.trans_to(R, cause) + var/injectamount = null + if (cause == "action_button") + injectamount = reagents.total_volume + else + injectamount = cause + reagents.trans_to(R, injectamount) R << "You hear a faint *beep*." if(!reagents.total_volume) R << "You hear a faint click from your chest." diff --git a/code/game/objects/items/weapons/implants/implantchair.dm b/code/game/objects/items/weapons/implants/implantchair.dm index 8b31a4f662a..95c25363a96 100644 --- a/code/game/objects/items/weapons/implants/implantchair.dm +++ b/code/game/objects/items/weapons/implants/implantchair.dm @@ -77,7 +77,7 @@ if(istype(G, /obj/item/weapon/grab)) if(!ismob(G:affecting)) return - for(var/mob/living/carbon/slime/M in range(1,G:affecting)) + for(var/mob/living/simple_animal/slime/M in range(1,G:affecting)) if(M.Victim == G:affecting) usr << "[G:affecting:name] will not fit into the [src.name] because they have a slime latched onto their head." return @@ -107,10 +107,10 @@ /obj/machinery/implantchair/put_mob(mob/living/carbon/M as mob) if(!iscarbon(M)) - usr << "The [src.name] cannot hold this!" + usr << "The [src.name] cannot hold this!" return if(src.occupant) - usr << "The [src.name] is already occupied!" + usr << "The [src.name] is already occupied!" return if(M.client) M.client.perspective = EYE_PERSPECTIVE diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm index b7d25927991..94a1afa043c 100644 --- a/code/game/objects/items/weapons/manuals.dm +++ b/code/game/objects/items/weapons/manuals.dm @@ -680,7 +680,10 @@

Basic ingredients preparation:

- Dough: Add an egg to 15 flour. Dough can be transformed by using your knife and rolling pin or by adding milk. All doughs can be microwaved.
+ Dough: 10u water + 15u flour for simple dough.
+ 15u egg yolk + 15u flour + 5u sugar for cake batter.
+ Doughs can be transformed by using a knife and rolling pin.
+ All doughs can be microwaved.
Bowl: Add water to it for soup preparation.
Meat: Microwave it, process it, slice it into microwavable cutlets with your knife, or use it raw.
Cheese: Add 5u universal enzyme (catalyst) to milk and soy milk to prepare cheese (sliceable) and tofu. diff --git a/code/game/objects/items/weapons/melee/misc.dm b/code/game/objects/items/weapons/melee/misc.dm index 13420578704..fa346334278 100644 --- a/code/game/objects/items/weapons/melee/misc.dm +++ b/code/game/objects/items/weapons/melee/misc.dm @@ -1,3 +1,6 @@ +/obj/item/weapon/melee + needs_permit = 1 + /obj/item/weapon/melee/chainofcommand name = "chain of command" desc = "A tool used by great men to placate the frothing masses." @@ -79,6 +82,7 @@ item_state = null slot_flags = SLOT_BELT w_class = 2 + needs_permit = 0 force = 0 on = 0 diff --git a/code/game/objects/items/weapons/shields.dm b/code/game/objects/items/weapons/shields.dm index 2a9a15c156c..a8875117ade 100644 --- a/code/game/objects/items/weapons/shields.dm +++ b/code/game/objects/items/weapons/shields.dm @@ -70,7 +70,6 @@ w_class = 4 playsound(user, 'sound/weapons/saberon.ogg', 35, 1) user << "[src] is now active." - reflect_chance = 40 else force = 3 throwforce = 3 @@ -78,7 +77,6 @@ w_class = 1 playsound(user, 'sound/weapons/saberoff.ogg', 35, 1) user << "[src] can now be concealed." - reflect_chance = 0 add_fingerprint(user) /obj/item/weapon/shield/riot/tele diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm index fa45ef40477..b5b0d9f60b3 100644 --- a/code/game/objects/items/weapons/storage/bags.dm +++ b/code/game/objects/items/weapons/storage/bags.dm @@ -79,6 +79,9 @@ max_w_class = 3 can_hold = list(/obj/item/weapon/ore) +/obj/item/weapon/storage/bag/ore/cyborg + name = "cyborg mining satchel" + /obj/item/weapon/storage/bag/ore/holding //miners, your messiah has arrived name = "mining satchel of holding" desc = "A revolution in convenience, this satchel allows for infinite ore storage. It's been outfitted with anti-malfunction safety measures." @@ -87,7 +90,6 @@ origin_tech = "bluespace=3" icon_state = "satchel_bspace" - // ----------------------------- // Plant bag // ----------------------------- @@ -277,7 +279,7 @@ max_combined_w_class = 21 max_w_class = 3 w_class = 4 //Bigger than a book because physics - can_hold = list(/obj/item/weapon/book, /obj/item/weapon/spellbook) //No bibles, consistent with bookcase + can_hold = list(/obj/item/weapon/book, /obj/item/weapon/storage/book, /obj/item/weapon/spellbook) /* * Trays - Agouri diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm index 209191666fc..006b0c5936d 100644 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy.dm @@ -227,7 +227,7 @@ /obj/item/weapon/storage/fancy/cigarettes/cigpack_syndicate/New() ..() for(var/i = 1 to storage_slots) - reagents.add_reagent("doctorsdelight",15) + reagents.add_reagent("omnizine",15) /obj/item/weapon/storage/fancy/cigarettes/cigpack_midori diff --git a/code/game/objects/items/weapons/storage/lockbox.dm b/code/game/objects/items/weapons/storage/lockbox.dm index a8cbcbcb282..9b7d8f19952 100644 --- a/code/game/objects/items/weapons/storage/lockbox.dm +++ b/code/game/objects/items/weapons/storage/lockbox.dm @@ -35,18 +35,6 @@ else user << "Access Denied." return - else if(istype(W, /obj/item/weapon/melee/energy/blade) && !src.broken) - broken = 1 - locked = 0 - desc = "It appears to be broken." - icon_state = src.icon_broken - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, src.loc) - spark_system.start() - playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1) - playsound(src.loc, "sparks", 50, 1) - visible_message("[user] has sliced open \the [src] with an energy blade!", "You hear metal being sliced and sparks flying.") - return if(!locked) ..() else diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm index f39e702b365..a92d674a6e9 100644 --- a/code/game/objects/items/weapons/storage/secure.dm +++ b/code/game/objects/items/weapons/storage/secure.dm @@ -33,21 +33,6 @@ /obj/item/weapon/storage/secure/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(locked) - if (istype(W, /obj/item/weapon/melee/energy/blade) && !emagged) - emagged = 1 - src.overlays += image('icons/obj/storage.dmi', icon_sparking) - sleep(6) - src.overlays = null - overlays += image('icons/obj/storage.dmi', icon_locking) - locked = 0 - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, src.loc) - spark_system.start() - playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1) - playsound(src.loc, "sparks", 50, 1) - user << "You slice through the lock on [src]." - return - if (istype(W, /obj/item/weapon/screwdriver)) if (do_after(user, 20)) src.open =! src.open diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index 89b613af2e3..f9b6eecd4cc 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -178,4 +178,10 @@ new /obj/item/weapon/reagent_containers/glass/bottle/formaldehyde(src) new /obj/item/weapon/reagent_containers/glass/bottle/cyanide(src) new /obj/item/weapon/reagent_containers/glass/bottle/histamine(src) + new /obj/item/weapon/reagent_containers/glass/bottle/initropidril(src) + new /obj/item/weapon/reagent_containers/glass/bottle/pancuronium(src) + new /obj/item/weapon/reagent_containers/glass/bottle/sodium_thiopental(src) + new /obj/item/weapon/reagent_containers/glass/bottle/coniine(src) + new /obj/item/weapon/reagent_containers/glass/bottle/curare(src) + new /obj/item/weapon/reagent_containers/glass/bottle/amanitin(src) return diff --git a/code/game/objects/items/weapons/tanks/jetpack.dm b/code/game/objects/items/weapons/tanks/jetpack.dm index 6bb7562f847..65a043fa5de 100644 --- a/code/game/objects/items/weapons/tanks/jetpack.dm +++ b/code/game/objects/items/weapons/tanks/jetpack.dm @@ -106,4 +106,62 @@ ..() ion_trail = new /datum/effect/effect/system/ion_trail_follow() ion_trail.set_up(src) - air_contents.carbon_dioxide = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) \ No newline at end of file + air_contents.carbon_dioxide = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + + +/obj/item/weapon/tank/jetpack/suit + name = "suit inbuilt jetpack" + desc = "A device that will use your internals tank as a gas source for propulsion." + icon_state = "jetpack-void" + item_state = "jetpack-void" + var/obj/item/weapon/tank/internals/tank = null + +/obj/item/weapon/tank/jetpack/suit/New() + ..() + SSobj.processing -= src + air_contents = null + +/obj/item/weapon/tank/jetpack/suit/toggle() + set name = "Toggle Jetpack" + set category = "Object" + + if(istype(loc.loc,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = loc.loc + + if(!H.wear_suit) + H << "You must be wearing the suit to use the inbuilt jetpack." + return + if(!istype(H.s_store,/obj/item/weapon/tank/internals)) + H << "You must have a tank in your suit's storage to use the inbuilt jetpack." + return + if(usr.stat || !usr.canmove || usr.restrained()) + return + + on = !on + if(on) + ion_trail.start() + tank = H.s_store + air_contents = tank.air_contents + SSobj.processing |= src + icon_state = "[icon_state]-on" + else + turn_off() + H << "You toggle the inbuilt jetpack [on? "on":"off"]." + +/obj/item/weapon/tank/jetpack/suit/proc/turn_off() + on = 0 + SSobj.processing -= src + ion_trail.stop() + air_contents = null + tank = null + icon_state = initial(icon_state) + +/obj/item/weapon/tank/jetpack/suit/process() + if(!istype(loc.loc,/mob/living/carbon/human)) + turn_off() + return + var/mob/living/carbon/human/H = loc.loc + if(!tank || tank != H.s_store) + turn_off() + return + ..() \ No newline at end of file diff --git a/code/game/objects/items/weapons/tanks/tank_types.dm b/code/game/objects/items/weapons/tanks/tank_types.dm index 870e0115d75..d8934a1372f 100644 --- a/code/game/objects/items/weapons/tanks/tank_types.dm +++ b/code/game/objects/items/weapons/tanks/tank_types.dm @@ -96,6 +96,7 @@ F.ptank = src user.unEquip(src) src.loc = F + F.update_icon() return /obj/item/weapon/tank/internals/plasma/full/New() diff --git a/code/game/objects/items/weapons/tanks/watertank.dm b/code/game/objects/items/weapons/tanks/watertank.dm index 010ae17b7da..72389fa1df1 100644 --- a/code/game/objects/items/weapons/tanks/watertank.dm +++ b/code/game/objects/items/weapons/tanks/watertank.dm @@ -290,7 +290,7 @@ if(!Adj|| !istype(target, /turf)) return if(metal_synthesis_cooldown < 5) - var/obj/effect/effect/foam/metal/F = new /obj/effect/effect/foam/metal(get_turf(target)) + var/obj/effect/effect/foam/metal/F = PoolOrNew(/obj/effect/effect/foam/metal, get_turf(target)) F.amount = 0 metal_synthesis_cooldown++ spawn(100) @@ -309,7 +309,7 @@ pass_flags = PASSTABLE /obj/effect/nanofrost_container/proc/Smoke() - new /obj/effect/effect/freezing_smoke(src.loc, 6, 1) + PoolOrNew(/obj/effect/effect/freezing_smoke, list(loc, 6, 1)) var/obj/effect/decal/cleanable/flour/F = new /obj/effect/decal/cleanable/flour(src.loc) F.color = "#B2FFFF" F.name = "nanofrost residue" @@ -332,7 +332,7 @@ /obj/effect/effect/freezing_smoke/New(loc, var/amt, var/blast) ..() spawn(100+rand(10,30)) - delete() + qdel(src) amount = amt if(amount) var/datum/effect/effect/system/freezing_smoke_spread/F = new /datum/effect/effect/system/freezing_smoke_spread @@ -377,7 +377,7 @@ var/i = 0 for(i=0, i= amount) reagents.remove_reagent("fuel", amount) check_fuel() if(M) - eyecheck(M) + M.flash_eyes(2) return 1 else if(M) @@ -308,6 +308,7 @@ //Toggles the welder off and on /obj/item/weapon/weldingtool/proc/toggle(mob/user, message = 0) if(!status) + user << "[src] can't be turned on while unsecured." return welding = !welding if(welding) @@ -331,44 +332,6 @@ hitsound = "swing_hit" icon_state = "welder" - - -//Decides whether or not to damage a player's eyes based on what they're wearing as protection -//Note: This should probably be moved to mob -/obj/item/weapon/weldingtool/proc/eyecheck(mob/user) - if(!iscarbon(user)) - return 1 - var/mob/living/carbon/C = user - var/safety = C.eyecheck() - - switch(safety) - if(1) - usr << "Your eyes sting a little." - user.eye_stat += rand(1, 2) - if(user.eye_stat > 12) - user.eye_blurry += rand(3, 6) - if(0) - usr << "Your eyes burn." - user.eye_stat += rand(2, 4) - if(user.eye_stat > 10) - user.eye_blurry += rand(4, 10) - if(-1) - usr << "Your thermals intensify the welder's glow. Your eyes itch and burn severely!" - user.eye_blurry += rand(12, 20) - user.eye_stat += rand(12, 16) - if(user.eye_stat > 10 && safety < 2) - user << "Your eyes are really starting to hurt. This can't be good for you!" - if (prob(user.eye_stat - 25 + 1)) - user << "You go blind!" - user.disabilities |= BLIND - else if(prob(user.eye_stat - 15 + 1)) - user << "You go blind!" - user.eye_blind = 5 - user.eye_blurry = 5 - user.disabilities |= NEARSIGHT - spawn(100) - user.disabilities &= ~NEARSIGHT - /obj/item/weapon/weldingtool/proc/flamethrower_screwdriver(obj/item/I, mob/user) if(welding) user << "Turn it off first." diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index e72ac3aa40a..32349ddb581 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -192,7 +192,6 @@ obj/item/weapon/twohanded/ item_color = "green" attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") var/hacked = 0 - reflect_chance = 0 /obj/item/weapon/twohanded/dualsaber/New() item_color = pick("red", "blue", "green", "purple") @@ -234,7 +233,7 @@ obj/item/weapon/twohanded/ user << "You cant pick up such dangerous item with your meaty hands without losing fingers, better not to." return 1 -/obj/item/weapon/twohanded/dualsaber/wield(mob/living/carbon/M) //Specific wield () hulk checks due to reflect_chance var for balance issues and switches hitsounds. +/obj/item/weapon/twohanded/dualsaber/wield(mob/living/carbon/M) //Specific wield () hulk checks due to reflection chance for balance issues and switches hitsounds. if(istype(M)) if(M.dna.check_mutation(HULK)) M << "You lack the grace to wield this." diff --git a/code/game/objects/items/weapons/vending_items.dm b/code/game/objects/items/weapons/vending_items.dm index c88351ffb13..7edc9dba09b 100644 --- a/code/game/objects/items/weapons/vending_items.dm +++ b/code/game/objects/items/weapons/vending_items.dm @@ -32,7 +32,7 @@ /obj/item/weapon/vending_refill/boozeomat machine_name = "Booze-O-Mat" icon_state = "refill_booze" - charges = 46//of 138 + charges = 54//of 162 /obj/item/weapon/vending_refill/coffee machine_name = "Solar's Best Hot Drinks" @@ -41,24 +41,24 @@ /obj/item/weapon/vending_refill/snack machine_name = "Getmore Chocolate Corp" - charges = 16//of 48 + charges = 14//of 42 /obj/item/weapon/vending_refill/cola machine_name = "Robust Softdrinks" icon_state = "refill_cola" - charges = 21//of 65 + charges = 22//of 66 /obj/item/weapon/vending_refill/cigarette machine_name = "ShadyCigs Deluxe" icon_state = "refill_smoke" - charges = 9// of 29 + charges = 14// of 42 /obj/item/weapon/vending_refill/autodrobe machine_name = "AutoDrobe" icon_state = "refill_costume" - charges = 20// of 60 + charges = 26// of 77 /obj/item/weapon/vending_refill/clothing machine_name = "ClothesMate" icon_state = "refill_clothes" - charges = 20// of 62 + charges = 30// of 90 diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 7f91e9f022a..d657f0e1b25 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -14,7 +14,7 @@ var/wall_mounted = 0 //never solid (You can always pass over it) var/health = 100 var/lastbang - var/max_mob_size = 1 //Biggest mob_size accepted by the container + var/max_mob_size = MOB_SIZE_HUMAN //Biggest mob_size accepted by the container var/mob_storage_capacity = 3 // how many human sized mob/living can fit together inside a closet. var/storage_capacity = 30 //This is so that someone can't pack hundreds of items in a locker/crate //then open it in a populated area to crash clients. @@ -155,7 +155,7 @@ /obj/structure/closet/attackby(obj/item/weapon/W as obj, mob/user as mob, params) - if(src.opened) + if(opened) if(istype(W, /obj/item/weapon/grab)) if(src.large) var/obj/item/weapon/grab/G = W @@ -173,13 +173,13 @@ user << "You begin cutting \the [src] apart..." playsound(loc, 'sound/items/Welder.ogg', 40, 1) if(do_after(user,40,5,1)) - if( !src.opened || !istype(src, /obj/structure/closet) || !user || !WT || !WT.isOn() || !user.loc ) + if( !opened || !istype(src, /obj/structure/closet) || !user || !WT || !WT.isOn() || !user.loc ) return playsound(loc, 'sound/items/Welder2.ogg', 50, 1) new /obj/item/stack/sheet/metal(src.loc) visible_message("[user] has cut \the [src] apart with \the [WT].", "You hear welding.") qdel(src) - return + return if(isrobot(user)) return @@ -187,25 +187,25 @@ if(user.drop_item()) W.Move(loc) - else if(istype(W, /obj/item/stack/packageWrap)) - return - else if(istype(W, /obj/item/weapon/weldingtool)) - var/obj/item/weapon/weldingtool/WT = W - if(WT.remove_fuel(0,user)) - user << "You begin [welded ? "unwelding":"welding"] \the [src]..." - playsound(loc, 'sound/items/Welder2.ogg', 40, 1) - if(do_after(user,40,5,1)) - if(src.opened || !istype(src, /obj/structure/closet) || !user || !WT || !WT.isOn() || !user.loc ) - return - playsound(loc, 'sound/items/welder.ogg', 50, 1) - welded = !welded - user << "You [welded ? "welded [src] shut":"unwelded [src]"]." - update_icon() - user.visible_message("[user.name] has [welded ? "welded [src] shut":"unwelded [src]"].") - return - else if(!place(user, W)) - src.attack_hand(user) - return + else + if(istype(W, /obj/item/stack/packageWrap)) + return + if(istype(W, /obj/item/weapon/weldingtool)) + var/obj/item/weapon/weldingtool/WT = W + if(WT.remove_fuel(0,user)) + user << "You begin [welded ? "unwelding":"welding"] \the [src]..." + playsound(loc, 'sound/items/Welder2.ogg', 40, 1) + if(do_after(user,40,5,1)) + if(opened || !istype(src, /obj/structure/closet) || !user || !WT || !WT.isOn() || !user.loc ) + return + playsound(loc, 'sound/items/welder.ogg', 50, 1) + welded = !welded + user << "You [welded ? "welded [src] shut":"unwelded [src]"]." + update_icon() + user.visible_message("[user.name] has [welded ? "welded [src] shut":"unwelded [src]"].") + return + if(!place(user, W)) + src.attack_hand(user) /obj/structure/closet/proc/place(var/mob/user, var/obj/item/I) return 0 diff --git a/code/game/objects/structures/crates_lockers/closets/crittercrate.dm b/code/game/objects/structures/crates_lockers/closets/crittercrate.dm index efebaa75f45..82fd942e368 100644 --- a/code/game/objects/structures/crates_lockers/closets/crittercrate.dm +++ b/code/game/objects/structures/crates_lockers/closets/crittercrate.dm @@ -44,11 +44,11 @@ /obj/structure/closet/critter/corgi name = "corgi crate" - content_mob = /mob/living/simple_animal/corgi + content_mob = /mob/living/simple_animal/pet/corgi /obj/structure/closet/critter/corgi/New() if(prob(50)) - content_mob = /mob/living/simple_animal/corgi/Lisa + content_mob = /mob/living/simple_animal/pet/corgi/Lisa ..() /obj/structure/closet/critter/cow @@ -69,20 +69,20 @@ /obj/structure/closet/critter/cat name = "cat crate" - content_mob = /mob/living/simple_animal/cat + content_mob = /mob/living/simple_animal/pet/cat /obj/structure/closet/critter/cat/New() if(prob(50)) - content_mob = /mob/living/simple_animal/cat/Proc + content_mob = /mob/living/simple_animal/pet/cat/Proc ..() /obj/structure/closet/critter/pug name = "pug crate" - content_mob = /mob/living/simple_animal/pug + content_mob = /mob/living/simple_animal/pet/pug /obj/structure/closet/critter/fox name = "fox crate" - content_mob = /mob/living/simple_animal/fox + content_mob = /mob/living/simple_animal/pet/fox /obj/structure/closet/critter/butterfly name = "butterflies crate" diff --git a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm index c117504b4ea..9625cff53cd 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm @@ -14,6 +14,28 @@ wall_mounted = 0 //never solid (You can always pass over it) health = 200 +/obj/structure/closet/secure_closet/examine(mob/user) + ..() + if(broken || opened || !ishuman(user)) + return //Monkeys don't get a message, nor does anyone ief it's open or emagged + else + user << "Alt-click the locker to [locked ? "unlock" : "lock"] it." + +/obj/structure/closet/secure_closet/AltClick(var/mob/user) + ..() + if(!in_range(src, user)) + return + if(!ishuman(user)) + user << "You have no idea how this thing is supposed to work." + return + if(user.stat || !user.canmove || user.restrained() || broken) + user << "You can't do that right now." + return + if(src.opened) + return + else + togglelock(user) + /obj/structure/closet/secure_closet/can_open() if(src.locked || src.welded) return 0 @@ -65,18 +87,6 @@ if(!src.opened && src.broken) user << "The locker appears to be broken." return - else if(istype(W, /obj/item/weapon/melee/energy/blade) && !broken) - broken = 1 - locked = 0 - desc = "It appears to be broken." - icon_state = icon_off - flick(icon_broken, src) - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, src.loc) - spark_system.start() - playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1) - playsound(src.loc, "sparks", 50, 1) - visible_message("[user] has sliced the locker open with an energy blade!", "You hear metal being sliced and sparks flying.") else ..(W, user) @@ -113,26 +123,6 @@ /obj/structure/closet/secure_closet/attack_paw(mob/user as mob) return src.attack_hand(user) -/obj/structure/closet/secure_closet/verb/verb_togglelock() - set src in oview(1) // One square distance - set category = "Object" - set name = "Toggle Lock" - - if(!usr.canmove || usr.stat || usr.restrained()) // Don't use it if you're not able to! Checks for stuns, ghost and restrain - return - - if(get_dist(usr, src) != 1) - return - - if(src.broken) - return - - if (ishuman(usr)) - if (!opened) - togglelock(usr) - else - usr << "This mob type can't use this verb." - /obj/structure/closet/secure_closet/update_icon()//Putting the welded stuff in updateicon() so it's easy to overwrite for special cases (Fridges, cabinets, and whatnot) overlays.Cut() if(!opened) 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 59928592fa7..115a165649d 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -24,6 +24,7 @@ new /obj/item/weapon/cartridge/captain(src) new /obj/item/clothing/shoes/sneakers/brown(src) new /obj/item/device/radio/headset/heads/captain/alt(src) + new /obj/item/clothing/glasses/sunglasses/gar/supergar(src) new /obj/item/clothing/gloves/color/captain(src) new /obj/item/weapon/gun/energy/gun(src) return @@ -54,6 +55,7 @@ new /obj/item/clothing/glasses/sunglasses(src) new /obj/item/weapon/mining_voucher(src) new /obj/item/weapon/gun/energy/gun(src) + new /obj/item/clothing/tie/petcollar(src) return @@ -79,6 +81,7 @@ new /obj/item/clothing/under/rank/head_of_security/alt(src) new /obj/item/clothing/head/HoS(src) new /obj/item/clothing/glasses/hud/security/sunglasses/eyepatch(src) + new /obj/item/clothing/glasses/hud/security/sunglasses/gars/supergars(src) new /obj/item/weapon/storage/lockbox/loyalty(src) new /obj/item/weapon/storage/box/flashbangs(src) new /obj/item/device/megaphone/sec(src) @@ -136,6 +139,7 @@ /obj/structure/closet/secure_closet/security/New() ..() new /obj/item/clothing/suit/armor/vest(src) + new /obj/item/device/radio/headset/headset_sec(src) new /obj/item/device/radio/headset/headset_sec/alt(src) new /obj/item/clothing/head/beret/sec(src) new /obj/item/clothing/head/soft/sec(src) diff --git a/code/game/objects/structures/crates_lockers/closets/statue.dm b/code/game/objects/structures/crates_lockers/closets/statue.dm index 0a9f02bf133..7d1c5c2bffe 100644 --- a/code/game/objects/structures/crates_lockers/closets/statue.dm +++ b/code/game/objects/structures/crates_lockers/closets/statue.dm @@ -30,8 +30,10 @@ intialBrute = L.getBruteLoss() intialOxy = L.getOxyLoss() if(ishuman(L)) - name = "statue of [L.name]" - if(L.gender == "female") + var/mob/living/carbon/human/H = L + name = "statue of [H.name]" + H.bleedsuppress = 1 + if(H.gender == "female") icon_state = "human_female" else if(ismonkey(L)) name = "statue of a monkey" @@ -124,6 +126,7 @@ shatter(M) /obj/structure/closet/statue/attackby(obj/item/I as obj, mob/user as mob, params) + user.changeNext_move(CLICK_CD_MELEE) health -= I.force visible_message("[user] strikes [src] with [I].") if(health <= 0) diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index f6aa7b779b2..f64395b7f24 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -307,17 +307,6 @@ overlays += redlight add_fingerprint(user) return - else if (istype(W, /obj/item/weapon/melee/energy/blade) && locked && !broken) - overlays.Cut() - overlays += emag - overlays += sparks - spawn(6) overlays -= sparks //Tried lots of stuff but nothing works right. so i have to use this *sadface* - playsound(src.loc, "sparks", 60, 1) - src.locked = 0 - src.broken = 1 - user << "You unlock \the [src]." - add_fingerprint(user) - return return ..() diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm index 08123b5fec1..ee5684c24c6 100644 --- a/code/game/objects/structures/false_walls.dm +++ b/code/game/objects/structures/false_walls.dm @@ -118,7 +118,7 @@ else user << "You can't reach, close it first!" - if(istype(W, /obj/item/weapon/pickaxe/plasmacutter) || istype(W, /obj/item/weapon/melee/energy/blade)) + if(istype(W, /obj/item/weapon/pickaxe/plasmacutter)) dismantle(user) if(istype(W, /obj/item/weapon/pickaxe/drill/jackhammer)) diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 211b3ec3491..03df21e80a9 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -63,7 +63,7 @@ healthcheck() return -/obj/structure/grille/attack_slime(mob/living/carbon/slime/user as mob) +/obj/structure/grille/attack_slime(mob/living/simple_animal/slime/user as mob) user.changeNext_move(CLICK_CD_MELEE) user.do_attack_animation(src) if(!user.is_adult) return diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index 34a68cee94c..3de876924ca 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -250,9 +250,14 @@ else user << "You'll need the keys in one of your hands to drive this [callme]." - /obj/structure/stool/bed/chair/janicart/user_buckle_mob(mob/living/M, mob/user) - M.loc = loc + if(user.incapacitated()) //user can't move the mob on the janicart's turf if incapacitated + return + for(var/atom/movable/A in get_turf(src)) //we check for obstacles on the turf. + if(A.density) + if(A != src && A != M) + return + M.loc = loc //we move the mob on the janicart's turf before checking if we can buckle. ..() update_mob() diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm index f4ef857668b..34251cd9c17 100644 --- a/code/game/objects/structures/kitchen_spike.dm +++ b/code/game/objects/structures/kitchen_spike.dm @@ -1,9 +1,11 @@ #define SKINTYPE_MONKEY 1 #define SKINTYPE_ALIEN 2 +#define SKINTYPE_BEAR 3 #define MEATTYPE_MONKEY 1 #define MEATTYPE_ALIEN 2 +#define MEATTYPE_BEAR 3 //////Kitchen Spike @@ -55,6 +57,20 @@ qdel(G) else user << "The spike already has something on it, finish collecting its meat first!" + else if(istype(G.affecting, /mob/living/simple_animal/hostile/bear)) + if(src.occupied == 0) + src.icon_state = "spikebloodybearz" + src.occupied = 1 + src.meat = 5 + src.meattype = MEATTYPE_BEAR + src.skin = 1 + src.skintype = SKINTYPE_BEAR + for(var/mob/O in viewers(src, null)) + O.show_message(text("[user] has forced [G.affecting] onto the spike, killing them instantly!")) + qdel(G.affecting) + qdel(G) + else + user << "The spike already has something on it, finish collecting its meat first!" else user << "They are too big for the spike, try something smaller!" return @@ -98,9 +114,27 @@ usr << "You remove the last piece of meat from the alien!" src.icon_state = "spike" src.occupied = 0 + else if(src.meattype == MEATTYPE_BEAR && src.skintype == SKINTYPE_BEAR) + if(src.skin >= 1) + src.skin-- + new /obj/item/clothing/head/bearpelt(src.loc) + user << "You remove the hide from the bear!" + else if(src.meat > 1) + src.meat-- + new /obj/item/weapon/reagent_containers/food/snacks/meat/bear(src.loc ) + usr << "You remove some meat from the bear." + else if(src.meat == 1) + src.meat-- + new /obj/item/weapon/reagent_containers/food/snacks/meat/bear(src.loc) + usr << "You remove the last piece of meat from the bear!" + src.icon_state = "spike" + src.occupied = 0 + #undef SKINTYPE_MONKEY #undef SKINTYPE_ALIEN +#undef SKINTYPE_BEAR #undef MEATTYPE_MONKEY #undef MEATTYPE_ALIEN +#undef MEATTYPE_BEAR \ No newline at end of file diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index e29be23452d..914ab7ff4c2 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -95,28 +95,14 @@ desc = "A catwalk for easier EVA manuevering and cable placement." icon_state = "catwalkfull" -/obj/structure/lattice/catwalk/New() - var/turf/T = loc - T.cancable = 1 - ..() - /obj/structure/lattice/catwalk/Move() var/turf/T = loc - T.cancable = 0 for(var/obj/structure/cable/C in T) C.Deconstruct() ..() -/obj/structure/lattice/catwalk/Destroy() - var/turf/T = loc - T.cancable = 0 - for(var/obj/structure/cable/C in T) - C.Destroy() - ..() - /obj/structure/lattice/catwalk/Deconstruct() var/turf/T = loc - T.cancable = 0 for(var/obj/structure/cable/C in T) C.Deconstruct() ..() diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index 87809a71d38..050f225a6b4 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -100,4 +100,96 @@ playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1) return user.visible_message("[user] smashes [src]!") - shatter() \ No newline at end of file + shatter() + +/obj/structure/mirror/magic + name = "magic mirror" + desc = "Turn and face the strange... face." + icon_state = "magic_mirror" + + +/obj/structure/mirror/magic/attack_hand(mob/user as mob) + if(!ishuman(user)) + return + + var/mob/living/carbon/human/H = user + + var/choice = input(user, "Something to change?", "Magical Grooming") as null|anything in list("name", "race", "gender", "hair", "eyes") + + switch(choice) + if("name") + var/newname = copytext(sanitize(input(H, "Who are we again?", "Name change", H.name) as null|text),1,MAX_NAME_LEN) + + if(!newname) + return + + H.real_name = newname + H.name = newname + if(H.mind) + H.mind.name = newname + + if("race") + var/newrace + var/racechoice = input(H, "What are we again?", "Race change") as null|anything in species_list + newrace = species_list[racechoice] + + if(!newrace || !H.dna) + return + + H.dna.species = new newrace + + if(H.dna.species.use_skintones) + var/new_s_tone = input(user, "What are we again?", "Race change") as null|anything in skin_tones + + if(new_s_tone) + H.skin_tone = new_s_tone + + if(MUTCOLORS in H.dna.species.specflags) + var/new_mutantcolor = input(user, "Choose your skin color:", "Race change") as color|null + if(new_mutantcolor) + var/temp_hsv = RGBtoHSV(new_mutantcolor) + + if(ReadHSV(temp_hsv)[3] >= ReadHSV("#7F7F7F")[3]) // mutantcolors must be bright + H.dna.mutant_color = sanitize_hexcolor(new_mutantcolor) + + else + H << "Invalid color. Your color is not bright enough." + + H.regenerate_icons() + + if("gender") + if(!(H.gender in list("male", "female"))) //blame the patriarchy + return + + if(H.gender == "male") + if(alert(H, "Become a Witch?", "Confirmation", "Yes", "No") == "Yes") + H.gender = "female" + H << "Man, you feel like a woman!" + H.regenerate_icons() + else + if(alert(H, "Become a Warlock?", "Confirmation", "Yes", "No") == "Yes") + H.gender = "male" + H << "Whoa man, you feel like a man!" + H.regenerate_icons() + + if("hair") + var/hairchoice = alert(H, "Hair style or hair color?", "Change Hair", "Style", "Color") + + if(hairchoice == "Style") //So you just want to use a mirror then? + ..() + else + var/new_hair_color = input(H, "Choose your hair color", "Hair Color") as null|color + if(new_hair_color) + H.hair_color = sanitize_hexcolor(new_hair_color) + if(H.gender == "male") + var/new_face_color = input(H, "Choose your facial hair color", "Hair Color") as null|color + if(new_face_color) + H.facial_hair_color = sanitize_hexcolor(new_face_color) + + H.update_hair() + + if("eyes") + var/new_eye_color = input(H, "Choose your eye color", "Eye Color") as null|color + if(new_eye_color) + H.eye_color = sanitize_hexcolor(new_eye_color) + H.update_body() \ No newline at end of file diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm index 85875833820..2324c724ed4 100644 --- a/code/game/objects/structures/musician.dm +++ b/code/game/objects/structures/musician.dm @@ -3,7 +3,7 @@ /datum/song var/name = "Untitled" var/list/lines = new() - var/tempo = 5 + var/tempo = 5 // delay between notes var/playing = 0 // if we're playing var/help = 0 // if help is open @@ -16,6 +16,7 @@ var/obj/instrumentObj = null // the associated obj playing the sound /datum/song/New(dir, obj) + tempo = sanitize_tempo(tempo) instrumentDir = dir instrumentObj = obj @@ -58,13 +59,17 @@ // and play var/turf/source = get_turf(instrumentObj) for(var/mob/M in get_hearers_in_view(15, source)) + if(!M.client || !(M.client.prefs.toggles & SOUND_INSTRUMENTS)) + continue M.playsound_local(source, soundfile, 100, falloff = 5) /datum/song/proc/updateDialog(mob/user as mob) instrumentObj.updateDialog() // assumes it's an object in world, override if otherwise -/datum/song/proc/shouldStopPlaying() +/datum/song/proc/shouldStopPlaying(mob/user) if(instrumentObj) + if(!user.canUseTopic(instrumentObj)) + return 1 return !instrumentObj.anchored // add special cases to stop in subclasses else return 1 @@ -84,7 +89,7 @@ var/list/notes = text2list(beat, "/") for(var/note in text2list(notes[1], "-")) //world << "note: [note]" - if(!playing || shouldStopPlaying())//If the instrument is playing, or special case + if(!playing || shouldStopPlaying(user))//If the instrument is playing, or special case playing = 0 return if(lentext(note) == 0) @@ -104,7 +109,7 @@ cur_oct[cur_note] = text2num(ni) playnote(cur_note, cur_acc[cur_note], cur_oct[cur_note]) if(notes.len >= 2 && text2num(notes[2])) - sleep(tempo / text2num(notes[2])) + sleep(sanitize_tempo(tempo / text2num(notes[2]))) else sleep(tempo) repeat-- @@ -136,10 +141,8 @@ dat += "Hide Editor" dat += " Start a New Song" dat += " Import a Song

" - var/calctempo = round(600 / tempo) - var/calcstep = tempo - 600 / (calctempo+1) - var/calcstep_b = tempo - 600 / (calctempo+10) - dat += "Tempo: -- [calctempo] BPM ++

" + var/bpm = round(600 / tempo) + dat += "Tempo: - [bpm] BPM +

" var/linecount = 0 for(var/line in lines) linecount += 1 @@ -183,7 +186,7 @@ if(href_list["newsong"]) lines = new() - tempo = 5 // default 120 BPM + tempo = sanitize_tempo(5) // default 120 BPM name = "" else if(href_list["import"]) @@ -203,10 +206,10 @@ spawn() lines = text2list(t, "\n") if(copytext(lines[1],1,6) == "BPM: ") - tempo = 600 / max(1, text2num(copytext(lines[1],6))) + tempo = sanitize_tempo(600 / text2num(copytext(lines[1],6))) lines.Cut(1,2) else - tempo = 5 // default 120 BPM + tempo = sanitize_tempo(5) // default 120 BPM if(lines.len > 50) usr << "Too many lines!" lines.Cut(51) @@ -235,11 +238,7 @@ repeat = max_repeats else if(href_list["tempo"]) - tempo += text2num(href_list["tempo"]) - if(tempo < 1) - tempo = 1 - if(tempo > 600) - tempo = 600 + tempo = sanitize_tempo(tempo + text2num(href_list["tempo"])) else if(href_list["play"]) playing = 1 @@ -279,6 +278,9 @@ updateDialog(usr) return +/datum/song/proc/sanitize_tempo(new_tempo) + new_tempo = abs(new_tempo) + return max(round(new_tempo, world.tick_lag), world.tick_lag) // subclass for handheld instruments, like violin /datum/song/handheld @@ -322,6 +324,10 @@ song = null ..() +/obj/structure/piano/initialize() + song.tempo = song.sanitize_tempo(song.tempo) // tick_lag isn't set when the map is loaded + ..() + /obj/structure/piano/attack_hand(mob/user as mob) if(!user.IsAdvancedToolUser()) user << "You don't have the dexterity to do this!" diff --git a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm index 974a5a9af5e..594ce58d2d4 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm @@ -26,7 +26,7 @@ */ /obj/structure/stool/bed/nest/user_buckle_mob(mob/M as mob, mob/user as mob) - if ( !ismob(M) || (get_dist(src, user) > 1) || (M.loc != src.loc) || user.restrained() || usr.stat || M.buckled || istype(user, /mob/living/silicon/pai) ) + if ( !ismob(M) || (get_dist(src, user) > 1) || (M.loc != src.loc) || user.restrained() || user.stat || M.buckled || istype(user, /mob/living/silicon/pai) ) return if(istype(M,/mob/living/carbon/alien)) @@ -36,27 +36,22 @@ unbuckle_mob() - if(M == usr) - return - else + if(buckle_mob(M)) M.visible_message(\ "[user.name] secretes a thick vile goo, securing [M.name] into [src]!",\ "[user.name] drenches you in a foul-smelling resin, trapping you in [src]!",\ "You hear squelching...") - return /obj/structure/stool/bed/nest/post_buckle_mob(mob/living/M) if(M == buckled_mob) - M.pixel_y += 1 + M.pixel_y += 6 M.pixel_x += 2 overlays += image('icons/mob/alien.dmi', "nestoverlay", layer=6) else - buckled_mob.pixel_y -= 1 - buckled_mob.pixel_x -= 2 + M.pixel_x -= 2 + M.pixel_y = initial(M.pixel_y) overlays.Cut() - - /obj/structure/stool/bed/nest/attackby(obj/item/weapon/W as obj, mob/user as mob, params) var/aforce = W.force health = max(0, health - aforce) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 196ce0cbb0b..da22c57e321 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -314,16 +314,6 @@ if(isrobot(user)) return - if(istype(I, /obj/item/weapon/melee/energy/blade)) - var/datum/effect/effect/system/spark_spread/SS = new /datum/effect/effect/system/spark_spread() - SS.set_up(5, 0, src.loc) - SS.start() - playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1) - playsound(src.loc, "sparks", 50, 1) - user.visible_message("The [src.name] was sliced apart by [user]!") - table_destroy(1) - return - if(!(I.flags & ABSTRACT)) //rip more parems rip in peace ;_; if(user.drop_item()) I.Move(loc) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index a38bcadf6e0..42be0f87cec 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -172,7 +172,7 @@ attack_generic(M, M.melee_damage_upper) update_nearby_icons() -/obj/structure/window/attack_slime(mob/living/carbon/slime/user as mob) +/obj/structure/window/attack_slime(mob/living/simple_animal/slime/user as mob) user.do_attack_animation(src) if(!user.is_adult) return diff --git a/code/game/pooling/atom_pool.dm b/code/game/pooling/atom_pool.dm index ca6f8f19341..e35e80d4854 100644 --- a/code/game/pooling/atom_pool.dm +++ b/code/game/pooling/atom_pool.dm @@ -20,29 +20,30 @@ var/global/list/GlobalPool = list() //The new created atom when it eventually //Goes into the pool -/proc/PoolOrNew(var/get_type,var/new_loc) +//Second argument can be a new location +//Or a list of arguments +//Either way it gets passed to new + +/proc/PoolOrNew(var/get_type,var/second_arg) if(!get_type) return var/atom/movable/AM - if(new_loc) - AM = GetFromPool(get_type,new_loc) - else - AM = GetFromPool(get_type,null) + AM = GetFromPool(get_type,second_arg) if(!AM) if(ispath(get_type)) - if(new_loc) - AM = new get_type (new_loc) + if(islist(second_arg)) + AM = new get_type (arglist(second_arg)) else - AM = new get_type (null) + AM = new get_type (second_arg) if(AM) return AM -/proc/GetFromPool(var/get_type,var/new_loc) +/proc/GetFromPool(var/get_type,var/second_arg) if(!get_type) return 0 @@ -55,9 +56,12 @@ var/global/list/GlobalPool = list() var/atom/movable/AM = pick_n_take(GlobalPool[get_type]) if(AM) AM.ResetVars() - AM.New() - if(new_loc) - AM.loc = new_loc + if(islist(second_arg)) + AM.loc = second_arg[1] + AM.New(arglist(second_arg)) + else + AM.loc = second_arg + AM.New(second_arg) return AM return 0 @@ -70,17 +74,18 @@ var/global/list/GlobalPool = list() if(AM in GlobalPool[AM.type]) return - AM.ResetVars() - if(!GlobalPool[AM.type]) GlobalPool[AM.type] = list() - GlobalPool[AM.type] += AM + GlobalPool[AM.type] |= AM + + AM.Destroy() + AM.ResetVars() /atom/movable/proc/ResetVars() - var/list/excluded = list("loc", "locs", "parent_type", "vars", "verbs", "type") + var/list/excluded = list("animate_movement", "loc", "locs", "parent_type", "vars", "verbs", "type") for(var/V in vars) if(V in excluded) diff --git a/code/game/say.dm b/code/game/say.dm index 4b71d01d9bb..368488b2831 100644 --- a/code/game/say.dm +++ b/code/game/say.dm @@ -21,20 +21,25 @@ var/list/freqtospan = list( return if(message == "" || !message) return - send_speech(message) + var/list/spans = get_spans() + send_speech(message, 7, src, , spans) -/atom/movable/proc/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq) +/atom/movable/proc/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans) return /atom/movable/proc/can_speak() return 1 -/atom/movable/proc/send_speech(message, range) - var/rendered = compose_message(src, languages, message) +/atom/movable/proc/send_speech(message, range = 7, obj/source = src, bubble_type, list/spans) + var/rendered = compose_message(src, languages, message, , spans) for(var/atom/movable/AM in get_hearers_in_view(range, src)) - AM.Hear(rendered, src, languages, message) + AM.Hear(rendered, src, languages, message, , spans) -/atom/movable/proc/compose_message(atom/movable/speaker, message_langs, raw_message, radio_freq) +//To get robot span classes, stuff like that. +/atom/movable/proc/get_spans() + return list() + +/atom/movable/proc/compose_message(atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans) //This proc uses text() because it is faster than appending strings. Thanks BYOND. //Basic span var/spanpart1 = "" @@ -47,7 +52,7 @@ var/list/freqtospan = list( //End name span. var/endspanpart = "" //Message - var/messagepart = " [lang_treat(speaker, message_langs, raw_message)]
" + var/messagepart = " [lang_treat(speaker, message_langs, raw_message, spans)]" return "[spanpart1][spanpart2][freqpart][compose_track_href(speaker, message_langs, raw_message, radio_freq)][namepart][compose_job(speaker, message_langs, raw_message, radio_freq)][endspanpart][messagepart]" @@ -57,32 +62,36 @@ var/list/freqtospan = list( /atom/movable/proc/compose_job(atom/movable/speaker, message_langs, raw_message, radio_freq) return "" -/atom/movable/proc/say_quote(var/text) - if(!text) +/atom/movable/proc/say_quote(input, list/spans) + if(!input) return "says, \"...\"" //not the best solution, but it will stop a large number of runtimes. The cause is somewhere in the Tcomms code - var/ending = copytext(text, length(text)) + var/ending = copytext(input, length(input)) + if(copytext(input, length(input) - 1) == "!!") + spans |= SPAN_YELL + return "[verb_yell], \"[attach_spans(input, spans)]\"" + input = attach_spans(input, spans) if(ending == "?") - return "asks, \"[text]\"" - if(copytext(text, length(text) - 1) == "!!") - return "yells, \"[text]\"" + return "[verb_ask], \"[input]\"" if(ending == "!") - return "exclaims, \"[text]\"" + return "[verb_exclaim], \"[input]\"" - return "says, \"[text]\"" + return "[verb_say], \"[input]\"" -/atom/movable/proc/lang_treat(atom/movable/speaker, message_langs, raw_message) +/atom/movable/proc/lang_treat(atom/movable/speaker, message_langs, raw_message, list/spans) if(languages & message_langs) var/atom/movable/AM = speaker.GetSource() - if(AM) - return AM.say_quote(raw_message) + if(AM) //Basically means "if the speaker is virtual" + if(AM.verb_say != speaker.verb_say || AM.verb_ask != speaker.verb_ask || AM.verb_exclaim != speaker.verb_exclaim || AM.verb_yell != speaker.verb_yell) //If the saymod was changed + return speaker.say_quote(raw_message, spans) + return AM.say_quote(raw_message, spans) else - return speaker.say_quote(raw_message) + return speaker.say_quote(raw_message, spans) else if(message_langs & HUMAN) var/atom/movable/AM = speaker.GetSource() if(AM) - return AM.say_quote(stars(raw_message)) + return AM.say_quote(stars(raw_message), spans) else - return speaker.say_quote(stars(raw_message)) + return speaker.say_quote(stars(raw_message), spans) else if(message_langs & MONKEY) return "chimpers." else if(message_langs & ALIEN) @@ -106,6 +115,24 @@ var/list/freqtospan = list( return returntext return "[copytext("[freq]", 1, 4)].[copytext("[freq]", 4, 5)]" +/proc/attach_spans(input, list/spans) + return "[message_spans_start(spans)][input]" + +/proc/message_spans_start(list/spans) + var/output = "" + return output + +/mob/living/proc/say_test(var/text) + var/ending = copytext(text, length(text)) + if (ending == "?") + return "1" + else if (ending == "!") + return "2" + return "0" + /atom/movable/proc/GetVoice() return name @@ -113,20 +140,19 @@ var/list/freqtospan = list( return 1 /atom/movable/proc/get_alt_name() - return +//HACKY VIRTUALSPEAKER STUFF BEYOND THIS POINT //these exist mostly to deal with the AIs hrefs and job stuff. -/atom/movable/proc/GetJob() - return + +/atom/movable/proc/GetJob() //Get a job, you lazy butte /atom/movable/proc/GetTrack() - return /atom/movable/proc/GetSource() - return /atom/movable/proc/GetRadio() +//VIRTUALSPEAKERS /atom/movable/virtualspeaker var/job var/faketrack diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index df7601e52d2..fef4bbef000 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -45,4 +45,4 @@ M.inertia_dir = 0 return if(2) //lube - M.slip(0, 7, null, (STEP|SLIDE|GALOSHES_DONT_HELP)) \ No newline at end of file + M.slip(0, 7, null, (STEP|SLIDE|GALOSHES_DONT_HELP)) diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index 4a57dbdda30..fd1e0824295 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -182,4 +182,7 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3"," dirtoverlay = new/obj/effect/decal/cleanable/dirt(src) dirtoverlay.alpha = 10 else if(dirt > 100) - dirtoverlay.alpha = min(dirtoverlay.alpha+10, 200) \ No newline at end of file + dirtoverlay.alpha = min(dirtoverlay.alpha+10, 200) + +/turf/simulated/floor/can_have_cabling() + return !burnt & !broken & !lava diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm index 362db4f8cc3..b41e048e30c 100644 --- a/code/game/turfs/simulated/floor/plating.dm +++ b/code/game/turfs/simulated/floor/plating.dm @@ -12,7 +12,6 @@ name = "plating" icon_state = "plating" intact = 0 - cancable = 1 broken_states = list("platingdmg1", "platingdmg2", "platingdmg3") burnt_states = list("panelscorched") diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index bd54b2067b9..2c88719d4b9 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -136,13 +136,6 @@ if( thermite ) if(is_hot(W)) thermitemelt(user) - - if( istype(W, /obj/item/weapon/melee/energy/blade) ) - var/obj/item/weapon/melee/energy/blade/EB = W - EB.spark_system.start() - user << "You slash \the [src] with \the [EB]; the thermite ignites!" - playsound(src, "sparks", 50, 1) - playsound(src, 'sound/weapons/blade1.ogg', 50, 1) return var/turf/T = user.loc //get user's location for delay checks @@ -225,21 +218,6 @@ dismantle_wall() visible_message("[user] smashes through the [name] with the [W.name]!", "You hear the grinding of metal.") return 1 - else if( istype(W, /obj/item/weapon/melee/energy/blade) ) - var/obj/item/weapon/melee/energy/blade/EB = W - EB.spark_system.start() - user << "You stab \the [EB] into the wall and begin to slice it apart." - playsound(src, "sparks", 50, 1) - if(do_after(user, slicing_duration*0.7)) //energy blade slicing is faster than welding tool slicing - if( !istype(src, /turf/simulated/wall) || !user || !EB || !T ) - return 1 - if( user.loc == T && user.get_active_hand() == W ) - EB.spark_system.start() - playsound(src, "sparks", 50, 1) - playsound(src, 'sound/weapons/blade1.ogg', 50, 1) - dismantle_wall(1) - visible_message("The wall was sliced apart by [user]!", "You hear metal being sliced apart and sparks flying.") - return 1 return 0 diff --git a/code/game/turfs/simulated/walls_reinforced.dm b/code/game/turfs/simulated/walls_reinforced.dm index c66d1061e50..b7e71d69e0b 100644 --- a/code/game/turfs/simulated/walls_reinforced.dm +++ b/code/game/turfs/simulated/walls_reinforced.dm @@ -29,10 +29,7 @@ M << "This wall is far too strong for you to destroy." /turf/simulated/wall/r_wall/try_destroy(obj/item/weapon/W as obj, mob/user as mob, turf/T as turf) - if(istype(W, /obj/item/weapon/melee/energy/blade)) - user << "This wall is too thick to slice through. You will need to find a different path." - return 1 - else if(istype(W, /obj/item/weapon/pickaxe/drill/jackhammer)) + if(istype(W, /obj/item/weapon/pickaxe/drill/jackhammer)) var/obj/item/weapon/pickaxe/drill/jackhammer/D = W if(!D.bcell.use(800)) user << "Your [D.name] doesn't have enough power to break through the [name]." diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 876ed325a6f..38dcbe609c6 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -233,3 +233,8 @@ proc/setup_map_transitions() //listamania /turf/space/singularity_act() return + +/turf/space/can_have_cabling() + if(locate(/obj/structure/lattice/catwalk, src)) + return 1 + return 0 diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index e2f23e70f0b..74be224cc36 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -3,7 +3,6 @@ level = 1.0 var/intact = 1 - var/cancable = 0 //Properties for open tiles (/floor) var/oxygen = 0 @@ -43,7 +42,7 @@ user.Move_Pulled(src) /turf/attackby(obj/item/C, mob/user, params) - if(cancable && istype(C, /obj/item/stack/cable_coil)) + if(can_lay_cable() && istype(C, /obj/item/stack/cable_coil)) var/obj/item/stack/cable_coil/coil = C for(var/obj/structure/cable/LC in src) if((LC.d1==0)||(LC.d2==0)) @@ -190,10 +189,9 @@ /turf/proc/ReplaceWithCatwalk() src.ChangeTurf(/turf/space) - src.cancable = 1//so cables can be laid new /obj/structure/lattice/catwalk(locate(src.x, src.y, src.z) ) -/turf/proc/phase_damage_creatures(damage,mob/U = null)//>Ninja Code. Hurts and knocks out creatures on this turf +/turf/proc/phase_damage_creatures(damage,mob/U = null)//>Ninja Code. Hurts and knocks out creatures on this turf //NINJACODE for(var/mob/living/M in src) if(M==U) continue//Will not harm U. Since null != M, can be excluded to kill everyone. @@ -346,3 +344,9 @@ O.singularity_act() ChangeTurf(/turf/space) return(2) + +/turf/proc/can_have_cabling() + return !density + +/turf/proc/can_lay_cable() + return can_have_cabling() & !intact diff --git a/code/game/turfs/unsimulated/floor.dm b/code/game/turfs/unsimulated/floor.dm index 5799286f3ea..a3ba0d120b0 100644 --- a/code/game/turfs/unsimulated/floor.dm +++ b/code/game/turfs/unsimulated/floor.dm @@ -7,7 +7,6 @@ name = "plating" icon_state = "plating" intact = 0 - cancable = 1 /turf/unsimulated/floor/bluegrid icon = 'icons/turf/floors.dmi' @@ -25,4 +24,4 @@ /turf/unsimulated/floor/grass/New() ..() - icon_state = "grass[rand(1,4)]" \ No newline at end of file + icon_state = "grass[rand(1,4)]" diff --git a/code/game/verbs/suicide.dm b/code/game/verbs/suicide.dm index f743889fcf9..7fc2486a184 100644 --- a/code/game/verbs/suicide.dm +++ b/code/game/verbs/suicide.dm @@ -150,25 +150,6 @@ adjustOxyLoss(max(175 - getFireLoss() - getBruteLoss() - getOxyLoss(), 0)) updatehealth() - -/mob/living/carbon/slime/verb/suicide() - set hidden = 1 - if(!canSuicide()) - return - var/confirm = alert("Are you sure you want to commit suicide?", "Confirm Suicide", "Yes", "No") - if(!canSuicide()) - return - if(confirm == "Yes") - suiciding = 1 - visible_message("[src] is growing dull and lifeless. It looks like it's lost the will to live.", \ - "[src] is growing dull and lifeless. It looks like it's lost the will to live.") - setOxyLoss(100) - adjustBruteLoss(100 - getBruteLoss()) - setToxLoss(100) - setCloneLoss(100) - - updatehealth() - /mob/living/simple_animal/verb/suicide() set hidden = 1 if(!canSuicide()) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 2b2672214c7..6c0a2019fe7 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -498,7 +498,7 @@ var/global/floorIsLava = 0 if(confirm == "Cancel") return if(confirm == "Yes") - world << "Restarting world! Initiated by [usr.client.holder.fakekey ? "Admin" : usr.key]!" + world << "Restarting world! Initiated by [usr.client.holder.fakekey ? "Admin" : usr.key]!" log_admin("[key_name(usr)] initiated a reboot.") feedback_set_details("end_error","admin reboot - by [usr.key] [usr.client.holder.fakekey ? "(stealth)" : ""]") @@ -653,7 +653,7 @@ var/global/floorIsLava = 0 if(!usr.client.holder) return if( alert("Reboot server?",,"Yes","No") == "No") return - world << "Rebooting world! Initiated by [usr.client.holder.fakekey ? "Admin" : usr.key]!" + world << "Rebooting world! Initiated by [usr.client.holder.fakekey ? "Admin" : usr.key]!" log_admin("[key_name(usr)] initiated an immediate reboot.") feedback_set_details("end_error","immediate admin reboot - by [usr.key] [usr.client.holder.fakekey ? "(stealth)" : ""]") diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 29944163e29..03913c95eaf 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -83,7 +83,8 @@ var/list/admin_verbs_fun = list( /client/proc/object_say, /client/proc/toggle_random_events, /client/proc/set_ooc, - /client/proc/forceEvent + /client/proc/forceEvent, + /client/proc/bluespace_artillery ) var/list/admin_verbs_spawn = list( /datum/admins/proc/spawn_atom, /*allows us to spawn instances*/ @@ -319,7 +320,7 @@ var/list/admin_verbs_hideable = list( if(holder && mob) if(mob.invisibility == INVISIBILITY_OBSERVER) mob.invisibility = initial(mob.invisibility) - mob << "Invisimin off. Invisibility reset." + mob << "Invisimin off. Invisibility reset." else mob.invisibility = INVISIBILITY_OBSERVER mob << "Invisimin on. You are now as invisible as a ghost." diff --git a/code/modules/admin/create_mob.dm b/code/modules/admin/create_mob.dm index 656f0adfb7c..11ed127148b 100644 --- a/code/modules/admin/create_mob.dm +++ b/code/modules/admin/create_mob.dm @@ -21,4 +21,5 @@ H.facial_hair_color = H.hair_color H.eye_color = random_eye_color() H.dna.blood_type = random_blood_type() - H.update_icons() \ No newline at end of file + H.update_body() + H.update_hair() \ No newline at end of file diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index 10af3669fc4..e9bda2b7625 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -229,8 +229,6 @@ if(iscarbon(M)) //Carbon stuff if(ishuman(M)) M_job = M.job - else if(isslime(M)) - M_job = "slime" else if(ismonkey(M)) M_job = "Monkey" else if(isalien(M)) //aliens @@ -254,6 +252,8 @@ else if(isanimal(M)) //simple animals if(iscorgi(M)) M_job = "Corgi" + else if(isslime(M)) + M_job = "slime" else M_job = "Animal" diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 43aa60f2f6b..6808fc857aa 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -265,13 +265,13 @@ if("sentinel") M.change_mob_type( /mob/living/carbon/alien/humanoid/sentinel , null, null, delmob ) if("larva") M.change_mob_type( /mob/living/carbon/alien/larva , null, null, delmob ) if("human") M.change_mob_type( /mob/living/carbon/human , null, null, delmob ) - if("slime") M.change_mob_type( /mob/living/carbon/slime , null, null, delmob ) + if("slime") M.change_mob_type( /mob/living/simple_animal/slime , null, null, delmob ) if("monkey") M.change_mob_type( /mob/living/carbon/monkey , null, null, delmob ) if("robot") M.change_mob_type( /mob/living/silicon/robot , null, null, delmob ) - if("cat") M.change_mob_type( /mob/living/simple_animal/cat , null, null, delmob ) - if("runtime") M.change_mob_type( /mob/living/simple_animal/cat/Runtime , null, null, delmob ) - if("corgi") M.change_mob_type( /mob/living/simple_animal/corgi , null, null, delmob ) - if("ian") M.change_mob_type( /mob/living/simple_animal/corgi/Ian , null, null, delmob ) + if("cat") M.change_mob_type( /mob/living/simple_animal/pet/cat , null, null, delmob ) + if("runtime") M.change_mob_type( /mob/living/simple_animal/pet/cat/Runtime , null, null, delmob ) + if("corgi") M.change_mob_type( /mob/living/simple_animal/pet/corgi , null, null, delmob ) + if("ian") M.change_mob_type( /mob/living/simple_animal/pet/corgi/Ian , null, null, delmob ) if("crab") M.change_mob_type( /mob/living/simple_animal/crab , null, null, delmob ) if("coffee") M.change_mob_type( /mob/living/simple_animal/crab/Coffee , null, null, delmob ) if("parrot") M.change_mob_type( /mob/living/simple_animal/parrot , null, null, delmob ) @@ -372,7 +372,7 @@ DB_ban_unban(M.ckey, BANTYPE_APPEARANCE) appearance_unban(M) message_admins("[key_name_admin(usr)] removed [key_name_admin(M)]'s appearance ban") - M << "[usr.client.ckey] has removed your appearance ban." + M << "[usr.client.ckey] has removed your appearance ban." else switch(alert("Appearance ban [M.ckey]?",,"Yes","No", "Cancel")) if("Yes") @@ -386,8 +386,8 @@ appearance_fullban(M, "[reason]; By [usr.ckey] on [time2text(world.realtime)]") notes_add(M.ckey, "Appearance banned - [reason]") message_admins("[key_name_admin(usr)] appearance banned [key_name_admin(M)]") - M << "You have been appearance banned by [usr.client.ckey]." - M << "The reason is: [reason]" + M << "You have been appearance banned by [usr.client.ckey]." + M << "The reason is: [reason]" M << "Appearance ban can be lifted only upon request." if(config.banappeals) M << "To try to resolve this matter head to [config.banappeals]" @@ -767,8 +767,8 @@ msg += ", [job]" notes_add(M.ckey, "Banned from [msg] - [reason]") message_admins("[key_name_admin(usr)] banned [key_name_admin(M)] from [msg] for [mins] minutes") - M << "You have been jobbanned by [usr.client.ckey] from: [msg]." - M << "The reason is: [reason]" + M << "You have been jobbanned by [usr.client.ckey] from: [msg]." + M << "The reason is: [reason]" M << "This jobban will be lifted in [mins] minutes." href_list["jobban2"] = 1 // lets it fall through and refresh return 1 @@ -787,8 +787,8 @@ else msg += ", [job]" notes_add(M.ckey, "Banned from [msg] - [reason]") message_admins("[key_name_admin(usr)] banned [key_name_admin(M)] from [msg]") - M << "You have been jobbanned by [usr.client.ckey] from: [msg]." - M << "The reason is: [reason]" + M << "You have been jobbanned by [usr.client.ckey] from: [msg]." + M << "The reason is: [reason]" M << "Jobban can be lifted only upon request." href_list["jobban2"] = 1 // lets it fall through and refresh return 1 @@ -820,7 +820,7 @@ continue if(msg) message_admins("[key_name_admin(usr)] unbanned [key_name_admin(M)] from [msg]") - M << "You have been un-jobbanned by [usr.client.ckey] from [msg]." + M << "You have been un-jobbanned by [usr.client.ckey] from [msg]." href_list["jobban2"] = 1 // lets it fall through and refresh return 1 return 0 //we didn't do anything! @@ -884,7 +884,7 @@ return AddBan(M.ckey, M.computer_id, reason, usr.ckey, 1, mins) ban_unban_log_save("[usr.client.ckey] has banned [M.ckey]. - Reason: [reason] - This will be removed in [mins] minutes.") - M << "You have been banned by [usr.client.ckey].\nReason: [reason]" + M << "You have been banned by [usr.client.ckey].\nReason: [reason]" M << "This is a temporary ban, it will be removed in [mins] minutes." feedback_inc("ban_tmp",1) DB_ban_record(BANTYPE_TEMP, M, mins, reason) @@ -908,7 +908,7 @@ AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0, M.lastKnownIP) if("No") AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0) - M << "You have been banned by [usr.client.ckey].\nReason: [reason]" + M << "You have been banned by [usr.client.ckey].\nReason: [reason]" M << "This is a permanent ban." if(config.banappeals) M << "To try to resolve this matter head to [config.banappeals]" @@ -1469,40 +1469,8 @@ H << "Your prayers have been answered!! You received the best cookie!" else if(href_list["BlueSpaceArtillery"]) - if(!check_rights(R_ADMIN|R_FUN)) return - var/mob/living/M = locate(href_list["BlueSpaceArtillery"]) - if(!isliving(M)) - usr << "This can only be used on instances of type /mob/living" - return - - if(alert(src.owner, "Are you sure you wish to hit [key_name(M)] with Blue Space Artillery?", "Confirm Firing?" , "Yes" , "No") != "Yes") - return - - if(BSACooldown) - src.owner << "Standby! Reload cycle in progress! Gunnary crews ready in five seconds!" - return - - BSACooldown = 1 - spawn(50) - BSACooldown = 0 - - M << "You've been hit by bluespace artillery!" - log_admin("[key_name(M)] has been hit by Bluespace Artillery fired by [src.owner]") - message_admins("[key_name(M)] has been hit by Bluespace Artillery fired by [src.owner]") - - var/turf/simulated/floor/T = get_turf(M) - if(istype(T)) - if(prob(80)) T.break_tile_to_plating() - else T.break_tile() - - if(M.health == 1) - M.gib() - else - M.adjustBruteLoss( min( 99 , (M.health - 1) ) ) - M.Stun(20) - M.Weaken(20) - M.stuttering = 20 + M.client.bluespace_artillery(M) else if(href_list["CentcommReply"]) var/mob/living/carbon/human/H = locate(href_list["CentcommReply"]) @@ -1861,7 +1829,7 @@ 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]") + 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") @@ -1953,7 +1921,7 @@ 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 << "You suddenly feel stupid." H.setBrainLoss(60) message_admins("[key_name_admin(usr)] made everybody retarded") if("eagles")//SCRAW diff --git a/code/modules/admin/verbs/bluespacearty.dm b/code/modules/admin/verbs/bluespacearty.dm new file mode 100644 index 00000000000..c3c0c0d90b7 --- /dev/null +++ b/code/modules/admin/verbs/bluespacearty.dm @@ -0,0 +1,34 @@ +/client/proc/bluespace_artillery(var/mob/M in mob_list) + set name = "Bluespace Artillery" + set category = "Fun" + + if(!holder || !check_rights(R_FUN)) + return + + var/mob/living/target = M + + if(!isliving(target)) + usr << "This can only be used on instances of type /mob/living" + return + + if(alert(usr, "Are you sure you wish to hit [key_name(target)] with Blue Space Artillery?", "Confirm Firing?" , "Yes" , "No") != "Yes") + return + + explosion(target.loc, 0, 0, 0, 0) + + var/turf/simulated/floor/T = get_turf(target) + if(istype(T)) + if(prob(80)) T.break_tile_to_plating() + else T.break_tile() + + if(target.health <= 1) + target.gib() + else + target.adjustBruteLoss(min(99,(target.health - 1))) + target.Stun(20) + target.Weaken(20) + target.stuttering = 20 + + target << "You've been hit by bluespace artillery!" + log_admin("[target.name] has been hit by Bluespace Artillery fired by [usr]") + message_admins("[target.name] has been hit by Bluespace Artillery fired by [usr]") diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index ffc7ebe20e5..1e49686bd0e 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -1161,13 +1161,12 @@ var/global/list/g_fancy_list_of_types = null M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform) M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat/swat(M), slot_shoes) M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves) - M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/ert(M), slot_wear_suit) + M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/hardsuit/ert(M), slot_wear_suit) M.equip_to_slot_or_del(new /obj/item/weapon/card/id/ert(M), slot_wear_id) M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/captain(M), slot_back) M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/eyepatch(M), slot_glasses) M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(M), slot_in_backpack) - M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/hardsuit/ert(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer/swat(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/pistol/loyalpin(M), slot_in_backpack) @@ -1178,14 +1177,13 @@ var/global/list/g_fancy_list_of_types = null M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform) M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat/swat(M), slot_shoes) M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves) - M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/ert/sec(M), slot_wear_suit) + M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/hardsuit/ert/sec(M), slot_wear_suit) M.equip_to_slot_or_del(new /obj/item/weapon/card/id/ert/Security(M), slot_wear_id) M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/security(M), slot_back) M.equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/security/sunglasses(M), slot_glasses) M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/handcuffs(M), slot_in_backpack) - M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/hardsuit/ert/sec(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer/swat(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/carbine/loyalpin(M), slot_in_backpack) @@ -1195,13 +1193,12 @@ var/global/list/g_fancy_list_of_types = null M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform) M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat/swat(M), slot_shoes) M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves) - M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/ert/med(M), slot_wear_suit) + M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/hardsuit/ert/med(M), slot_wear_suit) M.equip_to_slot_or_del(new /obj/item/weapon/card/id/ert/Medical(M), slot_wear_id) M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/medic(M), slot_back) M.equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/health(M), slot_glasses) M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(M), slot_in_backpack) - M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/hardsuit/ert/med(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer/swat(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/hypospray/combat/nanites(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/pistol/loyalpin(M), slot_in_backpack) @@ -1214,13 +1211,12 @@ var/global/list/g_fancy_list_of_types = null M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform) M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat/swat(M), slot_shoes) M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves) - M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/ert/engi(M), slot_wear_suit) + M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/hardsuit/ert/engi(M), slot_wear_suit) M.equip_to_slot_or_del(new /obj/item/weapon/card/id/ert/Engineer(M), slot_wear_id) M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/industrial(M), slot_back) M.equip_to_slot_or_del(new /obj/item/clothing/glasses/meson/engine(M), slot_glasses) M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(M), slot_in_backpack) - M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/hardsuit/ert/engi(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer/swat(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/weapon/rcd/combat(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/pistol/loyalpin(M), slot_in_backpack) diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm index 8127159f7a0..22f77f0e643 100644 --- a/code/modules/admin/verbs/playsound.dm +++ b/code/modules/admin/verbs/playsound.dm @@ -13,7 +13,7 @@ var/sound/admin_sound log_admin("[key_name(src)] played sound [S]") message_admins("[key_name_admin(src)] played sound [S]") - if(SSevent.holiday == "April Fool's Day") + if(SSevent.holidays && SSevent.holidays[APRIL_FOOLS]) admin_sound.frequency = pick(0.5, 0.7, 0.8, 0.85, 0.9, 0.95, 1.1, 1.2, 1.4, 1.6, 2.0, 2.5) src << "You feel the Honkmother messing with your song..." diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index d3275f9cf76..7755e882965 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -327,7 +327,7 @@ Traitors and the like can also be revived with the previous role mostly intact. new_character.loc = get_turf(synd_spawn) call(/datum/game_mode/proc/equip_syndicate)(new_character) if("Space Ninja") - var/ninja_spawn[] = list() + var/list/ninja_spawn = list() for(var/obj/effect/landmark/L in landmarks_list) if(L.name=="carpspawn") ninja_spawn += L @@ -707,7 +707,7 @@ Traitors and the like can also be revived with the previous role mostly intact. set category = "Special Verbs" set name = "Attack Log" - usr << text("Attack Log for []", mob) + usr << "Attack Log for [mob]" for(var/t in M.attack_log) usr << t feedback_add_details("admin_verb","ATTL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index c1dcfa30e92..8c94dafb76f 100644 --- a/code/modules/assembly/mousetrap.dm +++ b/code/modules/assembly/mousetrap.dm @@ -57,7 +57,7 @@ H.updatehealth() else if(ismouse(target)) var/mob/living/simple_animal/mouse/M = target - visible_message("SPLAT!") + visible_message("SPLAT!") M.splat() playsound(src.loc, 'sound/effects/snap.ogg', 50, 1) armed = 0 diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm index 533213efd98..07395b77e10 100644 --- a/code/modules/assembly/proximity.dm +++ b/code/modules/assembly/proximity.dm @@ -42,8 +42,7 @@ /obj/item/device/assembly/prox_sensor/HasProximity(atom/movable/AM as mob|obj) if (istype(AM, /obj/effect/beam)) return - if (AM.move_speed < 12) sense() - return + sense() /obj/item/device/assembly/prox_sensor/sense() diff --git a/code/modules/assembly/voice.dm b/code/modules/assembly/voice.dm index 3706dd5fdf9..1042d781a0c 100644 --- a/code/modules/assembly/voice.dm +++ b/code/modules/assembly/voice.dm @@ -7,10 +7,13 @@ origin_tech = "magnets=1" flags = HEAR attachable = 1 + verb_say = "beeps" + verb_ask = "beeps" + verb_exclaim = "beeps" var/listening = 0 var/recorded = "" //the activation message -/obj/item/device/assembly/voice/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq) +/obj/item/device/assembly/voice/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans) if(speaker == src) return @@ -28,9 +31,6 @@ listening = !listening say("[listening ? "Now" : "No longer"] recording input.") -/obj/machinery/vending/say_quote(text) - return "beeps, \"[text]\"" - /obj/item/device/assembly/voice/attack_self(mob/user) if(!user) return 0 diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index 703962ae3ba..c52adc42c2c 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -105,10 +105,10 @@ icon_state = "grey baby slime" //sets the icon in the map editor /obj/effect/landmark/corpse/slimeCorpse/createCorpse() //proc creates a dead slime - var/A = locate(/mob/living/carbon/slime/) in loc //variable A looks for a slime at the location of the landmark + var/A = locate(/mob/living/simple_animal/slime/) in loc //variable A looks for a slime at the location of the landmark if(A) //if variable A is true return //stop executing the proc - var/mob/living/carbon/slime/M = new(src.loc) //variable M is a new slime at the location of the landmark + var/mob/living/simple_animal/slime/M = new(src.loc) //variable M is a new slime at the location of the landmark M.colour = src.mobcolour //slime colour is set by landmark's mobcolour var M.adjustToxLoss(9001) //kills the slime, death() doesn't update its icon correctly qdel(src) @@ -196,7 +196,7 @@ corpseidaccess = "Station Engineer" /obj/effect/landmark/corpse/engineer/rig - corpsesuit = /obj/item/clothing/suit/space/hardsuit + corpsesuit = /obj/item/clothing/suit/space/hardsuit/engine corpsemask = /obj/item/clothing/mask/breath /obj/effect/landmark/corpse/clown diff --git a/code/modules/awaymissions/zlevel.dm b/code/modules/awaymissions/zlevel.dm index a9debf6f524..f578a34ce14 100644 --- a/code/modules/awaymissions/zlevel.dm +++ b/code/modules/awaymissions/zlevel.dm @@ -3,7 +3,7 @@ proc/createRandomZlevel() return var/list/potentialRandomZlevels = list() - world << "Searching for away missions..." + world << "Searching for away missions..." var/list/Lines = file2list("_maps/RandomZLevels/fileList.txt") if(!Lines.len) return for (var/t in Lines) @@ -33,7 +33,7 @@ proc/createRandomZlevel() if(potentialRandomZlevels.len) - world << "Loading away mission..." + world << "Loading away mission..." var/map = pick(potentialRandomZlevels) var/file = file(map) @@ -46,8 +46,8 @@ proc/createRandomZlevel() continue awaydestinations.Add(L) - world << "Away mission loaded." + world << "Away mission loaded." else - world << "No away missions found." + world << "No away missions found." return \ No newline at end of file diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 51bab7dc9ba..8c058c98459 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -14,8 +14,9 @@ var/global/list/special_roles = list( //keep synced with the defines BE_* in set "pAI", //7 "cultist" = /datum/game_mode/cult, //8 "blob" = /datum/game_mode/blob, //9 - "monkey" = /datum/game_mode/monkey, //10 - "gangster" = /datum/game_mode/gang //11 + "ninja", //10 + "monkey" = /datum/game_mode/monkey, //11 + "gangster" = /datum/game_mode/gang //12 ) @@ -808,7 +809,7 @@ datum/preferences if("ghost_whispers") chat_toggles ^= CHAT_GHOSTWHISPER - + if("ghost_radio") chat_toggles ^= CHAT_GHOSTRADIO @@ -888,11 +889,5 @@ datum/preferences backbag = 1 //Same as above character.backbag = backbag - /* - //Debugging report to track down a bug, which randomly assigned the plural gender to people. - if(character.gender in list(PLURAL, NEUTER)) - if(isliving(src)) //Ghosts get neuter by default - message_admins("[character] ([character.ckey]) has spawned with their gender as plural or neuter. Please notify coders.") - character.gender = MALE - */ - + character.update_body() + character.update_hair() \ No newline at end of file diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index c1820717417..604bbd57069 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -2,7 +2,7 @@ #define SAVEFILE_VERSION_MIN 8 //This is the current version, anything below this will attempt to update (if it's not obsolete) -#define SAVEFILE_VERSION_MAX 10 +#define SAVEFILE_VERSION_MAX 11 /* SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn This proc checks if the current directory of the savefile S needs updating @@ -33,7 +33,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car /datum/preferences/proc/update_preferences(current_version) if(current_version < 10) toggles |= MEMBER_PUBLIC - return + if(current_version < 11) + chat_toggles = TOGGLES_DEFAULT_CHAT + toggles = TOGGLES_DEFAULT //should this proc get fairly long (say 3 versions long), //just increase SAVEFILE_VERSION_MIN so it's not as far behind @@ -99,6 +101,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["UI_style"] >> UI_style S["be_special"] >> be_special S["default_slot"] >> default_slot + S["chat_toggles"] >> chat_toggles S["toggles"] >> toggles S["ghost_form"] >> ghost_form @@ -132,6 +135,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["be_special"] << be_special S["default_slot"] << default_slot S["toggles"] << toggles + S["chat_toggles"] << chat_toggles S["ghost_form"] << ghost_form return 1 @@ -299,4 +303,4 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car /client/verb/savefile_import(path as text) var/savefile/S = new /savefile(path) S.ImportText("/",file("[path].txt")) -*/ \ No newline at end of file +*/ diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm index 52b9329094d..c1af4353e61 100644 --- a/code/modules/client/preferences_toggles.dm +++ b/code/modules/client/preferences_toggles.dm @@ -157,6 +157,19 @@ src << sound(null, repeat = 0, wait = 0, volume = 0, channel = 2) feedback_add_details("admin_verb","TAmbi") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +// This needs a toggle because you people are awful and spammed terrible music +/client/verb/toggle_instruments() + set name = "Hear/Silence Instruments" + set category = "Preferences" + set desc = "Toggles hearing musical instruments like the violin and piano" + prefs.toggles ^= SOUND_INSTRUMENTS + prefs.save_preferences() + if(prefs.toggles & SOUND_INSTRUMENTS) + src << "You will now hear people playing musical instruments." + else + src << "You will no longer hear musical instruments." + feedback_add_details("admin_verb","TInstru") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + //be special /client/verb/toggle_be_special(role in be_special_flags) set name = "Toggle SpecialRole Candidacy" diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index c84fd4b7916..230efee1fc6 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -9,6 +9,9 @@ righthand_file = 'icons/mob/inhands/clothing_righthand.dmi' var/alt_desc = null + var/obj/item/device/flashlight/F = null + var/can_flashlight = 0 + //Ears: currently only used for headsets and earmuffs /obj/item/clothing/ears name = "ears" @@ -76,6 +79,7 @@ BLIND // can't see anything icon = 'icons/obj/clothing/hats.dmi' body_parts_covered = HEAD slot_flags = SLOT_HEAD + var/blockTracking = 0 //For AI tracking //Mask /obj/item/clothing/mask @@ -266,7 +270,7 @@ atom/proc/generate_female_clothing(index,t_color,icon,type) female_clothing_icons[index] = female_clothing_icon /obj/item/clothing/under/verb/toggle() - set name = "Toggle Suit Sensors" + set name = "Adjust Suit Sensors" set category = "Object" set src in usr var/mob/M = usr @@ -329,7 +333,8 @@ atom/proc/generate_female_clothing(index,t_color,icon,type) usr << "You adjust the suit back to normal." src.adjusted = 0 else - src.fitted = NO_FEMALE_UNIFORM + if(src.fitted != FEMALE_UNIFORM_TOP) + src.fitted = NO_FEMALE_UNIFORM src.item_color += "_d" usr << "You adjust the suit to wear it more casually." src.adjusted = 1 @@ -402,3 +407,4 @@ atom/proc/generate_female_clothing(index,t_color,icon,type) if(!user.stat && user.canmove && !user.restrained()) return 1 return 0 + diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index bb52cd01980..9a26058d953 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -15,6 +15,17 @@ item_state = "nvgmeson" darkness_view = 8 +/obj/item/clothing/glasses/meson/gar + name = "gar mesons" + icon_state = "garm" + item_state = "garm" + desc = "Do the impossible, see the invisible!" + force = 10 + throwforce = 10 + throw_speed = 4 + attack_verb = list("sliced") + hitsound = 'sound/weapons/bladeslice.ogg' + /obj/item/clothing/glasses/science name = "Science Goggles" desc = "A pair of snazzy goggles used to protect against chemical spills." @@ -78,6 +89,44 @@ flash_protect = 1 tint = 1 +/obj/item/clothing/glasses/sunglasses/garb + desc = "Go beyond impossible and kick reason to the curb!" + name = "black gar glasses" + icon_state = "garb" + item_state = "garb" + force = 10 + throwforce = 10 + throw_speed = 4 + attack_verb = list("sliced") + hitsound = 'sound/weapons/bladeslice.ogg' + +/obj/item/clothing/glasses/sunglasses/garb/supergarb + desc = "Believe in us humans." + name = "black giga gar glasses" + icon_state = "supergarb" + item_state = "garb" + force = 12 + throwforce = 12 + +/obj/item/clothing/glasses/sunglasses/gar + desc = "Just who the hell do you think I am?!" + name = "gar glasses" + icon_state = "gar" + item_state = "gar" + force = 10 + throwforce = 10 + throw_speed = 4 + attack_verb = list("sliced") + hitsound = 'sound/weapons/bladeslice.ogg' + +/obj/item/clothing/glasses/sunglasses/gar/supergar + desc = "We evolve past the person we were a minute before. Little by little we advance with each turn. That's how a drill works!" + name = "giga gar glasses" + icon_state = "supergar" + item_state = "gar" + force = 12 + throwforce = 12 + /obj/item/clothing/glasses/welding name = "welding goggles" desc = "Protects the eyes from welders; approved by the mad scientist association." @@ -155,4 +204,29 @@ name = "Optical Thermal Eyepatch" desc = "An eyepatch with built-in thermal optics." icon_state = "eyepatch" - item_state = "eyepatch" \ No newline at end of file + item_state = "eyepatch" + +/obj/item/clothing/glasses/cold + name = "cold goggles" + desc = "A pair of goggles meant for low temperatures." + icon_state = "cold" + item_state = "cold" + +obj/item/clothing/glasses/heat + name = "heat goggles" + desc = "A pair of goggles meant for high temperatures." + icon_state = "heat" + item_state = "heat" + +obj/item/clothing/glasses/orange + name = "orange glasses" + desc = "A sweet pair of orange shades." + icon_state = "orangeglasses" + item_state = "orangeglasses" + +obj/item/clothing/glasses/red + name = "red glasses" + desc = "A sweet pair of red shades." + icon_state = "redglasses" + item_state = "redglasses" + diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index 012a260bba5..709f923534c 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -65,3 +65,21 @@ emagged = 1 desc = desc + " The display flickers slightly." +/obj/item/clothing/glasses/hud/security/sunglasses/gars + name = "HUD gar glasses" + desc = "GAR glasses with a HUD." + icon_state = "gars" + item_state = "garb" + force = 10 + throwforce = 10 + throw_speed = 4 + attack_verb = list("sliced") + hitsound = 'sound/weapons/bladeslice.ogg' + +/obj/item/clothing/glasses/hud/security/sunglasses/gars/supergars + name = "giga HUD gar glasses" + desc = "GIGA GAR glasses with a HUD." + icon_state = "supergars" + item_state = "garb" + force = 12 + throwforce = 12 \ No newline at end of file diff --git a/code/modules/clothing/gloves/ninja.dm b/code/modules/clothing/gloves/ninja.dm deleted file mode 100644 index 0b05f32fb8d..00000000000 --- a/code/modules/clothing/gloves/ninja.dm +++ /dev/null @@ -1,104 +0,0 @@ -/* - Dear ninja gloves - - This isn't because I like you - this is because your father is a bastard - - ... - I guess you're a little cool. - -Sayu -*/ - -/obj/item/clothing/gloves/space_ninja - desc = "These nano-enhanced gloves insulate from electricity and provide fire resistance." - name = "ninja gloves" - icon_state = "s-ninja" - item_state = "s-ninja" - siemens_coefficient = 0 - cold_protection = HANDS - min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT - heat_protection = HANDS - max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT - strip_delay = 120 - var/draining = 0 - var/candrain = 0 - var/mindrain = 200 - var/maxdrain = 400 - -/* - This runs the gamut of what ninja gloves can do - The other option would be a dedicated ninja touch bullshit proc on everything - which would probably more efficient, but ninjas are pretty rare. - This was mostly introduced to keep ninja code from contaminating other code; - with this in place it would be easier to untangle the rest of it. - - For the drain proc, see events/ninja.dm -*/ -/obj/item/clothing/gloves/space_ninja/Touch(var/atom/A,var/proximity) - if(!candrain || draining) return 0 - - var/mob/living/carbon/human/H = loc - if(!istype(H)) return 0 // what - var/obj/item/clothing/suit/space/space_ninja/suit = H.wear_suit - if(!istype(suit)) return 0 - if(isturf(A)) return 0 - - if(!proximity) // todo: you could add ninja stars or computer hacking here - return 0 - - A.add_fingerprint(H) - - // steal energy from powered things - if(istype(A,/mob/living/silicon/robot)) - drain("CYBORG",A,suit) - return 1 - - if(istype(A,/obj/machinery/power/apc)) - drain("APC",A,suit) - return 1 - - if(istype(A,/obj/structure/cable)) - drain("WIRE",A,suit) - return 1 - - if(istype(A,/obj/structure/grille)) - var/obj/structure/cable/C = locate() in A.loc - if(C) - drain("WIRE",C,suit) - return 1 - - if(istype(A,/obj/machinery/power/smes)) - drain("SMES",A,suit) - return 1 - - if(istype(A,/obj/mecha)) - drain("MECHA",A,suit) - return 1 - - if(istype(A,/obj/machinery/computer/rdconsole)) // download research - drain("RESEARCH",A,suit) - return 1 - - if(istype(A,/obj/machinery/r_n_d/server)) - A.add_fingerprint(H) - var/obj/machinery/r_n_d/server/S = A - if(S.disabled) - return 1 - if(S.shocked) - S.shock(H,50) - return 1 - drain("RESEARCH",A,suit) - return 1 - - //do AI transfers - if(istype(A,/mob/living/silicon/ai)) - suit.NAI.transfer_ai("AICORE", "AICARD", A, H) - return 1 - - if(istype(A,/obj/structure/AIcore/deactivated)) - suit.NAI.transfer_ai("INACTIVE","AICARD",A, H) - return 1 - - if(istype(A,/obj/machinery/computer/aifixer)) - suit.NAI.transfer_ai("AIFIXER","AICARD",A, H) - return 1 diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index d1b15282247..f10de9605ce 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -11,6 +11,28 @@ heat_protection = HEAD max_heat_protection_temperature = HELMET_MAX_TEMP_PROTECT strip_delay = 60 + var/obj/machinery/camera/portable/helmetCam = null + var/spawnWithHelmetCam = 0 + var/canAttachCam = 0 + + +/obj/item/clothing/head/helmet/New() + ..() + if(spawnWithHelmetCam) + helmetCam = new /obj/machinery/camera/portable(src) + helmetCam.c_tag = "Helmet-Mounted Camera (No User)([rand(1,999)])" + helmetCam.network = list("SS13") + update_icon() + +/obj/item/clothing/head/helmet/emp_act(severity) + if(helmetCam) //Transfer the EMP to the camera so you can still disable it this way. + helmetCam.emp_act(severity) + ..() + +/obj/item/clothing/head/helmet/sec + spawnWithHelmetCam = 1 + canAttachCam = 1 + can_flashlight = 1 /obj/item/clothing/head/helmet/alt name = "bulletproof helmet" @@ -115,3 +137,151 @@ obj/item/clothing/head/helmet/bluetaghelm armor = list(melee = 30, bullet = 10, laser = 20,energy = 10, bomb = 20, bio = 0, rad = 0) // Offer about the same protection as a hardhat. flags_inv = HIDEEARS|HIDEEYES + +//LightToggle + +/obj/item/clothing/head/helmet/update_icon() + + var/state = "[initial(icon_state)]" + if(helmetCam) + state += "-cam" //"helmet-cam" + if(F) + if(F.on) + state += "-flight-on" //"helmet-flight-on" // "helmet-cam-flight-on" + else + state += "-flight" //etc. + + icon_state = state + + if(istype(loc, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = loc + H.update_inv_head(0) + + return + +/obj/item/clothing/head/helmet/ui_action_click() + toggle_helmlight() + ..() + +/obj/item/clothing/head/helmet/attackby(var/obj/item/A as obj, mob/user as mob, params) + if(istype(A, /obj/item/device/flashlight/seclite)) + var/obj/item/device/flashlight/seclite/S = A + if(can_flashlight) + if(!F) + user.drop_item() + user << "You click [S] into place on [src]." + if(S.on) + SetLuminosity(0) + F = S + A.loc = src + update_icon() + update_helmlight(user) + verbs += /obj/item/clothing/head/helmet/proc/toggle_helmlight + return + + if(istype(A, /obj/item/weapon/screwdriver)) + if(F) + for(var/obj/item/device/flashlight/seclite/S in src) + user << "You unscrew the seclite from [src]." + F = null + S.loc = get_turf(user) + update_helmlight(user) + S.update_brightness(user) + update_icon() + usr.update_inv_head(0) + verbs -= /obj/item/clothing/head/helmet/proc/toggle_helmlight + return + + + if(istype(A, /obj/item/weapon/camera_assembly)) + if(!canAttachCam) + user << "You can't attach [A] to [src]!" + return + if(helmetCam) + user << "[src] already has a mounted camera." + return + user.drop_item() + helmetCam = new /obj/machinery/camera/portable(src) + helmetCam.assembly = A + A.loc = helmetCam + helmetCam.c_tag = "Helmet-Mounted Camera (No User)([rand(1,999)])" + helmetCam.network = list("SS13") + update_icon() + user.visible_message("[user] attaches [A] to [src]","You attach [A] to [src]") + return + + if(istype(A, /obj/item/weapon/crowbar)) + if(!helmetCam) + ..() + return + user.visible_message("[user] removes [helmetCam] from [src]","You remove [helmetCam] from [src]") + helmetCam.assembly.loc = get_turf(src) + helmetCam.assembly = null + qdel(helmetCam) + helmetCam = null + update_icon() + return + + ..() + return + +/obj/item/clothing/head/helmet/proc/toggle_helmlight() + set name = "Toggle Helmetlight" + set category = "Object" + set desc = "Click to toggle your helmet's attached flashlight." + + if(!F) + return + + var/mob/living/carbon/human/user = usr + if(!isturf(user.loc)) + user << "You cannot turn the light on while in this [user.loc]." + F.on = !F.on + user << "You toggle the helmetlight [F.on ? "on":"off"]." + + playsound(user, 'sound/weapons/empty.ogg', 100, 1) + update_helmlight(user) + return + +/obj/item/clothing/head/helmet/proc/update_helmlight(var/mob/user = null) + if(F) + action_button_name = "Toggle Helmetlight" + if(F.on) + if(loc == user) + user.AddLuminosity(F.brightness_on) + else if(isturf(loc)) + SetLuminosity(F.brightness_on) + else + if(loc == user) + user.AddLuminosity(-F.brightness_on) + else if(isturf(loc)) + SetLuminosity(0) + update_icon() + else + action_button_name = null + if(loc == user) + user.AddLuminosity(-5) + else if(isturf(loc)) + SetLuminosity(0) + return + +/obj/item/clothing/head/helmet/pickup(mob/user) + if(F) + if(F.on) + user.AddLuminosity(F.brightness_on) + SetLuminosity(0) + + +/obj/item/clothing/head/helmet/equipped(mob/user) + if(helmetCam) + spawn(10) //Gives time for the game to set a name (lol rhyme) to roundstart officers. + helmetCam.c_tag = "Helmet-Mounted Camera ([user.name])([rand(1,999)])" + +/obj/item/clothing/head/helmet/dropped(mob/user) + if(F) + if(F.on) + user.AddLuminosity(-F.brightness_on) + SetLuminosity(F.brightness_on) + + if(helmetCam) + helmetCam.c_tag = "Helmet-Mounted Camera (No User)([rand(1,999)])" \ No newline at end of file diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index 2ac171d76de..266bfda4689 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -210,4 +210,9 @@ icon_state = "santahatnorm" item_state = "that" cold_protection = HEAD - min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT \ No newline at end of file + min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT + +/obj/item/clothing/head/jester + name = "jester hat" + desc = "A hat with bells, to add some merryness to the suit." + icon_state = "jester_hat" diff --git a/code/modules/clothing/head/soft_caps.dm b/code/modules/clothing/head/soft_caps.dm index e16c312e45c..02fc5c460f7 100644 --- a/code/modules/clothing/head/soft_caps.dm +++ b/code/modules/clothing/head/soft_caps.dm @@ -11,19 +11,31 @@ src.flipped=0 ..() - verb/flip() + verb/flipcap() set category = "Object" set name = "Flip cap" - set src in usr - if(usr.canmove && !usr.stat && !usr.restrained()) - src.flipped = !src.flipped - if(src.flipped) - icon_state = "[item_color]soft_flipped" - usr << "You flip the hat backwards." - else - icon_state = "[item_color]soft" - usr << "You flip the hat back in normal position." - usr.update_inv_head(0) //so our mob-overlays update + + flip(usr) + + +/obj/item/clothing/head/soft/AltClick(var/mob/user) + flip(user) + + +/obj/item/clothing/head/soft/proc/flip(var/mob/user) + if(user.canmove && !user.stat && !user.restrained()) + src.flipped = !src.flipped + if(src.flipped) + icon_state = "[item_color]soft_flipped" + user << "You flip the hat backwards." + else + icon_state = "[item_color]soft" + user << "You flip the hat back in normal position." + usr.update_inv_head(0) //so our mob-overlays update + +/obj/item/clothing/head/soft/examine(mob/user) + ..() + user << "Alt-click the cap to flip it [flipped ? "forwards" : "backwards"]." /obj/item/clothing/head/soft/red name = "red cap" diff --git a/code/modules/clothing/masks/breath.dm b/code/modules/clothing/masks/breath.dm index d5ed2dc454a..da10a0170de 100644 --- a/code/modules/clothing/masks/breath.dm +++ b/code/modules/clothing/masks/breath.dm @@ -15,10 +15,17 @@ /obj/item/clothing/mask/breath/attack_self(var/mob/user) adjustmask(user) +/obj/item/clothing/mask/breath/AltClick(var/mob/user) + adjustmask(user) + +/obj/item/clothing/mask/breath/examine(mob/user) + ..() + user << "Alt-click [src] to adjust it." + /obj/item/clothing/mask/breath/medical desc = "A close-fitting sterile mask that can be connected to an air supply." name = "medical mask" icon_state = "medical" item_state = "m_mask" permeability_coefficient = 0.01 - put_on_delay = 10 \ No newline at end of file + put_on_delay = 10 diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index 2366d9f3877..c38e52f1736 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -219,35 +219,6 @@ vchange = !vchange user << "The voice changer is now [vchange ? "on" : "off"]!" -/obj/item/clothing/mask/gas/voice/space_ninja - name = "ninja mask" - desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement." - icon_state = "s-ninja" - item_state = "s-ninja_mask" - vchange = 1 - strip_delay = 120 - -/obj/item/clothing/mask/gas/voice/space_ninja/speechModification(message) - if(voice == "Unknown") - if(copytext(message, 1, 2) != "*") - var/list/temp_message = text2list(message, " ") - var/list/pick_list = list() - for(var/i = 1, i <= temp_message.len, i++) - pick_list += i - for(var/i=1, i <= abs(temp_message.len/3), i++) - var/H = pick(pick_list) - if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue - temp_message[H] = ninjaspeak(temp_message[H]) - pick_list -= H - message = list2text(temp_message, " ") - message = replacetext(message, "o", "?") - message = replacetext(message, "p", "?") - message = replacetext(message, "l", "?") - message = replacetext(message, "s", "?") - message = replacetext(message, "u", "?") - message = replacetext(message, "b", "?") - return message - /obj/item/clothing/mask/gas/clown_hat name = "clown wig and mask" diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index a1f83e984d2..cd9c96ae388 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -29,20 +29,6 @@ flags = NOSLIP armor = list(melee = 80, bullet = 60, laser = 50, energy = 50, bomb = 50, bio = 30, rad = 30) -/obj/item/clothing/shoes/space_ninja - name = "ninja shoes" - desc = "A pair of running shoes. Excellent for running and even better for smashing skulls." - icon_state = "s-ninja" - item_state = "secshoes" - permeability_coefficient = 0.01 - flags = NOSLIP - armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) - strip_delay = 120 - cold_protection = FEET - min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT - heat_protection = FEET - max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT - /obj/item/clothing/shoes/sandal desc = "A pair of rather plain, wooden sandals." name = "sandals" diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index c76fbd9c198..ab22fb8e773 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -1,6 +1,6 @@ - //Regular (engineering) hardsuits + //Baseline hardsuits /obj/item/clothing/head/helmet/space/hardsuit - name = "engineering hardsuit helmet" + name = "hardsuit helmet" desc = "A special helmet designed for work in a hazardous, low-pressure environment. Has radiation shielding." icon_state = "hardsuit0-engineering" item_state = "eng_helm" @@ -11,6 +11,7 @@ action_button_name = "Toggle Helmet Light" flags = HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPSPRESSUREDMAGE | THICKMATERIAL | NODROP + /obj/item/clothing/head/helmet/space/hardsuit/attack_self(mob/user) if(!isturf(user.loc)) user << "You cannot turn the light on while in this [user.loc]" //To prevent some lighting anomalities. @@ -35,7 +36,7 @@ /obj/item/clothing/suit/space/hardsuit - name = "engineering hardsuit" + name = "hardsuit" desc = "A special suit that protects against hazardous, low pressure environments. Has radiation shielding." icon_state = "hardsuit-engineering" item_state = "eng_hardsuit" @@ -45,9 +46,42 @@ var/obj/item/clothing/head/helmet/space/hardsuit/helmet action_button_name = "Toggle Helmet" var/helmettype = /obj/item/clothing/head/helmet/space/hardsuit + var/obj/item/weapon/tank/jetpack/suit/jetpack = null + +/obj/item/clothing/suit/space/hardsuit/verb/Jetpack() + set name = "Toggle Inbuilt Jetpack" + set category = "Object" + jetpack.toggle() + +/obj/item/clothing/suit/space/hardsuit/verb/Jetpack_Rockets() + set name = "Toggle Inbuilt Jetpack Stabilization" + set category = "Object" + jetpack.toggle_rockets() + + //Engineering +/obj/item/clothing/head/helmet/space/hardsuit/engine + name = "engineering hardsuit helmet" + desc = "A special helmet designed for work in a hazardous, low-pressure environment. Has radiation shielding." + icon_state = "hardsuit0-engineering" + item_state = "eng_helm" + armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 75) + item_color = "engineering" + +/obj/item/clothing/suit/space/hardsuit/engine + name = "engineering hardsuit" + desc = "A special suit that protects against hazardous, low pressure environments. Has radiation shielding." + icon_state = "hardsuit-engineering" + item_state = "eng_hardsuit" + armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 75) + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine + + +/obj/item/clothing/suit/space/hardsuit/engine/New() + jetpack = new /obj/item/weapon/tank/jetpack/suit(src) + ..() //Atmospherics -/obj/item/clothing/head/helmet/space/hardsuit/atmos +/obj/item/clothing/head/helmet/space/hardsuit/engine/atmos name = "atmospherics hardsuit helmet" desc = "A special helmet designed for work in a hazardous, low-pressure environment. Has thermal shielding." icon_state = "hardsuit0-atmospherics" @@ -57,6 +91,8 @@ heat_protection = HEAD //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT +/obj/item/clothing/suit/space/hardsuit/engine/atmos + /obj/item/clothing/suit/space/hardsuit/atmos name = "atmospherics hardsuit" desc = "A special suit that protects against hazardous, low pressure environments. Has thermal shielding." @@ -65,11 +101,11 @@ armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 0) heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT - helmettype = /obj/item/clothing/head/helmet/space/hardsuit/atmos + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine/atmos //Chief Engineer's hardsuit -/obj/item/clothing/head/helmet/space/hardsuit/elite +/obj/item/clothing/head/helmet/space/hardsuit/engine/elite name = "advanced hardsuit helmet" desc = "An advanced helmet designed for work in a hazardous, low pressure environment. Shines with a high polish." icon_state = "hardsuit0-white" @@ -79,7 +115,8 @@ heat_protection = HEAD //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT -/obj/item/clothing/suit/space/hardsuit/elite + +/obj/item/clothing/suit/space/hardsuit/engine/elite icon_state = "hardsuit-white" name = "advanced hardsuit" desc = "An advanced suit that protects against hazardous, low pressure environments. Shines with a high polish." @@ -87,7 +124,7 @@ armor = list(melee = 40, bullet = 5, laser = 10, energy = 5, bomb = 50, bio = 100, rad = 90) heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT - helmettype = /obj/item/clothing/head/helmet/space/hardsuit/elite + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine/elite //Mining hardsuit @@ -100,6 +137,7 @@ armor = list(melee = 40, bullet = 5, laser = 10, energy = 5, bomb = 50, bio = 100, rad = 50) brightness_on = 7 + /obj/item/clothing/suit/space/hardsuit/mining icon_state = "hardsuit-mining" name = "mining hardsuit" @@ -198,6 +236,9 @@ ..() flags ^= NODROP +/obj/item/clothing/suit/space/hardsuit/syndi/New() + jetpack = new /obj/item/weapon/tank/jetpack/suit(src) + ..() //The Owl Hardsuit /obj/item/clothing/head/helmet/space/hardsuit/syndi/owl @@ -208,6 +249,7 @@ item_state = "s_helmet" item_color = "owl" + /obj/item/clothing/suit/space/hardsuit/syndi/owl name = "owl hardsuit" desc = "A dual-mode advanced hardsuit designed for any crime-fighting situation. It is in travel mode." @@ -231,6 +273,7 @@ max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT unacidable = 1 + /obj/item/clothing/suit/space/hardsuit/wizard icon_state = "hardsuit-wiz" name = "gem-encrusted hardsuit" @@ -258,6 +301,7 @@ flags_inv = HIDEMASK|HIDEEARS|HIDEEYES armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 50) + /obj/item/clothing/suit/space/hardsuit/medical icon_state = "hardsuit-medical" name = "medical hardsuit" @@ -278,6 +322,7 @@ item_color = "sec" armor = list(melee = 30, bullet = 15, laser = 30,energy = 10, bomb = 10, bio = 100, rad = 50) + /obj/item/clothing/suit/space/hardsuit/security icon_state = "hardsuit-sec" name = "security hardsuit" @@ -294,6 +339,7 @@ item_color = "hos" armor = list(melee = 45, bullet = 25, laser = 30,energy = 10, bomb = 25, bio = 100, rad = 50) + /obj/item/clothing/suit/space/hardsuit/security/hos icon_state = "hardsuit-hos" name = "head of security's hardsuit" diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index 03bf0279300..09f52337f14 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -125,51 +125,58 @@ item_color = "ert_commander" armor = list(melee = 65, bullet = 50, laser = 50, energy = 50, bomb = 50, bio = 100, rad = 100) strip_delay = 130 - flags = HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPSPRESSUREDMAGE | THICKMATERIAL + flags = HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPSPRESSUREDMAGE | THICKMATERIAL | NODROP brightness_on = 7 +/obj/item/clothing/suit/space/hardsuit/ert + name = "emergency response team suit" + desc = "Standard issue command suit for the ERT." + icon_state = "ert_command" + item_state = "ert_command" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert + allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank/internals) + armor = list(melee = 65, bullet = 50, laser = 50, energy = 50, bomb = 50, bio = 100, rad = 100) + slowdown = 0 + strip_delay = 130 + + //ERT Security /obj/item/clothing/head/helmet/space/hardsuit/ert/sec desc = "Standard issue security helmet for the ERT." icon_state = "hardsuit0-ert_security" item_state = "hardsuit0-ert_security" item_color = "ert_security" +/obj/item/clothing/suit/space/hardsuit/ert/sec + desc = "Standard issue security suit for the ERT." + icon_state = "ert_security" + item_state = "ert_security" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/sec + + //ERT Engineering /obj/item/clothing/head/helmet/space/hardsuit/ert/engi desc = "Standard issue engineer helmet for the ERT." icon_state = "hardsuit0-ert_engineer" item_state = "hardsuit0-ert_engineer" item_color = "ert_engineer" +/obj/item/clothing/suit/space/hardsuit/ert/engi + desc = "Standard issue engineer suit for the ERT." + icon_state = "ert_engineer" + item_state = "ert_engineer" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/engi + + //ERT Medical /obj/item/clothing/head/helmet/space/hardsuit/ert/med desc = "Standard issue medical helmet for the ERT." icon_state = "hardsuit0-ert_medical" item_state = "hardsuit0-ert_medical" item_color = "ert_medical" -/obj/item/clothing/suit/space/ert - name = "emergency response team suit" - desc = "Standard issue command suit for the ERT." - icon_state = "ert_command" - item_state = "ert_command" - allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank/internals) - armor = list(melee = 65, bullet = 50, laser = 50, energy = 50, bomb = 50, bio = 100, rad = 100) - slowdown = 0 - strip_delay = 130 - -/obj/item/clothing/suit/space/ert/sec - desc = "Standard issue security suit for the ERT." - icon_state = "ert_security" - item_state = "ert_security" - -/obj/item/clothing/suit/space/ert/engi - desc = "Standard issue engineer suit for the ERT." - icon_state = "ert_engineer" - item_state = "ert_engineer" - -/obj/item/clothing/suit/space/ert/med +/obj/item/clothing/suit/space/hardsuit/ert/med desc = "Standard issue medical suit for the ERT." icon_state = "ert_medical" item_state = "ert_medical" + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/med /obj/item/clothing/suit/space/eva name = "EVA suit" diff --git a/code/modules/clothing/spacesuits/ninja.dm b/code/modules/clothing/spacesuits/ninja.dm deleted file mode 100644 index 9c6c98d6396..00000000000 --- a/code/modules/clothing/spacesuits/ninja.dm +++ /dev/null @@ -1,65 +0,0 @@ -/obj/item/clothing/head/helmet/space/space_ninja - desc = "What may appear to be a simple black garment is in fact a highly sophisticated nano-weave helmet. Standard issue ninja gear." - name = "ninja hood" - icon_state = "s-ninja" - item_state = "s-ninja_mask" - armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 25) - strip_delay = 12 - unacidable = 1 - - -/obj/item/clothing/suit/space/space_ninja - name = "ninja suit" - desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins." - icon_state = "s-ninja" - item_state = "s-ninja_suit" - allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank/internals,/obj/item/weapon/stock_parts/cell) - slowdown = 0 - unacidable = 1 - armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) - strip_delay = 12 - - //Important parts of the suit. - var/mob/living/carbon/affecting = null//The wearer. - var/obj/item/weapon/stock_parts/cell/cell//Starts out with a high-capacity cell using New(). - var/datum/effect/effect/system/spark_spread/spark_system//To create sparks. - var/reagent_list[] = list("omnizine","salbutamol","spaceacillin","charcoal","nutriment","radium","potass_iodide")//The reagents ids which are added to the suit at New(). - var/stored_research[]//For stealing station research. - var/obj/item/weapon/disk/tech_disk/t_disk//To copy design onto disk. - - //Other articles of ninja gear worn together, used to easily reference them after initializing. - var/obj/item/clothing/head/helmet/space/space_ninja/n_hood - var/obj/item/clothing/shoes/space_ninja/n_shoes - var/obj/item/clothing/gloves/space_ninja/n_gloves - - //Main function variables. - var/s_initialized = 0//Suit starts off. - var/s_coold = 0//If the suit is on cooldown. Can be used to attach different cooldowns to abilities. Ticks down every second based on suit ntick(). - var/s_cost = 5.0//Base energy cost each ntick. - var/s_acost = 25.0//Additional cost for additional powers active. - var/k_cost = 200.0//Kamikaze energy cost each ntick. - var/k_damage = 1.0//Brute damage potentially done by Kamikaze each ntick. - var/s_delay = 40.0//How fast the suit does certain things, lower is faster. Can be overridden in specific procs. Also determines adverse probability. - var/a_transfer = 20.0//How much reagent is transferred when injecting. - var/r_maxamount = 80.0//How much reagent in total there is. - - //Support function variables. - var/spideros = 0//Mode of SpiderOS. This can change so I won't bother listing the modes here (0 is hub). Check ninja_equipment.dm for how it all works. - var/s_active = 0//Stealth off. - var/s_busy = 0//Is the suit busy with a process? Like AI hacking. Used for safety functions. - var/kamikaze = 0//Kamikaze on or off. - var/k_unlock = 0//To unlock Kamikaze. - - //Ability function variables. - var/s_bombs = 10.0//Number of starting ninja smoke bombs. - var/a_boost = 3.0//Number of adrenaline boosters. - - //Onboard AI related variables. - - var/obj/item/device/aicard/NAI //Integrated intellicard. - - var/obj/item/device/paicard/pai//A slot for a pAI device - - var/obj/effect/overlay/hologram//Is the AI hologram on or off? Visible only to the wearer of the suit. This works by attaching an image to a blank overlay. - - var/s_control = 1//If user in control of the suit. diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index ff4daf648d0..d5ee7e59bcc 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -91,10 +91,9 @@ item_state = "armor_reflec" blood_overlay_type = "armor" armor = list(melee = 10, bullet = 10, laser = 80, energy = 50, bomb = 0, bio = 0, rad = 0) - reflect_chance = 40 + var/hit_reflect_chance = 40 /obj/item/clothing/suit/armor/laserproof/IsReflect(var/def_zone) - var/hit_reflect_chance = reflect_chance if(!(def_zone in list("chest", "groin"))) //If not shot where ablative is covering you, you don't get the reflection bonus! hit_reflect_chance = 0 if (prob(hit_reflect_chance)) diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index 0adae1c15a2..bd3c9d8368e 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -187,6 +187,15 @@ item_state = "ponchoshame" flags = NODROP +/obj/item/clothing/suit/whitedress + name = "white dress" + desc = "A fancy white dress." + icon_state = "white_dress" + item_state = "w_suit" + body_parts_covered = CHEST|GROIN|LEGS|FEET + flags_inv = HIDEJUMPSUIT|HIDESHOES + + /* * Misc */ @@ -306,4 +315,4 @@ name = "mining winter coat" icon_state = "coatminer" allowed = list(/obj/item/weapon/pickaxe,/obj/item/device/flashlight,/obj/item/weapon/tank/internals/emergency_oxygen,/obj/item/toy,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter) - armor = list(melee = 10, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) \ No newline at end of file + armor = list(melee = 10, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) diff --git a/code/modules/clothing/suits/toggles.dm b/code/modules/clothing/suits/toggles.dm index c9567e9c4ed..380e0262597 100644 --- a/code/modules/clothing/suits/toggles.dm +++ b/code/modules/clothing/suits/toggles.dm @@ -80,6 +80,9 @@ /obj/item/clothing/suit/space/hardsuit/New() MakeHelmet() + if(!jetpack) + verbs -= /obj/item/clothing/suit/space/hardsuit/verb/Jetpack + verbs -= /obj/item/clothing/suit/space/hardsuit/verb/Jetpack_Rockets ..() /obj/item/clothing/suit/space/hardsuit/proc/MakeHelmet() @@ -136,4 +139,4 @@ else H << "You disengage the helmet on the hardsuit." playsound(src.loc, 'sound/mecha/mechmove03.ogg', 50, 1) - RemoveHelmet() \ No newline at end of file + RemoveHelmet() diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index bec82edc7fe..c0d55ed45e4 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -455,7 +455,7 @@ item_state = "plaid_red" item_color = "plaid_red" fitted = FEMALE_UNIFORM_TOP - can_adjust = 0 + can_adjust = 1 /obj/item/clothing/under/plaid_skirt/blue name = "blue plaid skirt" @@ -470,3 +470,10 @@ icon_state = "plaid_purple" item_state = "plaid_purple" item_color = "plaid_purple" + +/obj/item/clothing/under/jester + name = "jester suit" + desc = "A jolly dress, well suited to entertain your master, nuncle." + icon_state = "jester" + item_color = "jester" + can_adjust = 0 diff --git a/code/modules/clothing/under/ties.dm b/code/modules/clothing/under/ties.dm index 1520f2cfcf7..17c224df9a3 100644 --- a/code/modules/clothing/under/ties.dm +++ b/code/modules/clothing/under/ties.dm @@ -277,3 +277,13 @@ name = "striped blue scarf" icon_state = "stripedbluescarf" item_color = "stripedbluescarf" + +/obj/item/clothing/tie/petcollar //don't really wear this though please c'mon seriously guys + name = "pet collar" + icon_state = "petcollar" + item_color = "petcollar" + var/tagname = null + +/obj/item/clothing/tie/petcollar/attack_self(mob/user as mob) + tagname = copytext(sanitize(input(user, "Would you like to change the name on the tag?", "Name your new pet", "Spot") as null|text),1,MAX_NAME_LEN) + name = "[initial(name)] - [tagname]" \ No newline at end of file diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm index dfc441d15e2..e9b2ab62b90 100644 --- a/code/modules/crafting/recipes.dm +++ b/code/modules/crafting/recipes.dm @@ -5,7 +5,7 @@ var/tools[] = list() //type paths of items needed but not consumed var/time = 30 //time in deciseconds var/parts[] = list() //type paths of items that will be placed in the result - var/chem_catalists[] = list() //like tools but for reagents + var/chem_catalysts[] = list() //like tools but for reagents /datum/table_recipe/IED @@ -49,7 +49,7 @@ name = "Secbot" result = /obj/machinery/bot/secbot reqs = list(/obj/item/device/assembly/signaler = 1, - /obj/item/clothing/head/helmet = 1, + /obj/item/clothing/head/helmet/sec = 1, /obj/item/weapon/melee/baton = 1, /obj/item/device/assembly/prox_sensor = 1, /obj/item/robot_parts/r_arm = 1) @@ -87,7 +87,9 @@ result = /obj/item/weapon/flamethrower reqs = list(/obj/item/weapon/weldingtool = 1, /obj/item/device/assembly/igniter = 1, - /obj/item/stack/rods = 2) + /obj/item/stack/rods = 1) + parts = list(/obj/item/device/assembly/igniter = 1, + /obj/item/weapon/weldingtool = 1) tools = list(/obj/item/weapon/screwdriver) time = 20 @@ -127,6 +129,42 @@ tools = list(/obj/item/weapon/screwdriver) time = 5 +/datum/table_recipe/ionslug + name = "Ion Scatter Shell" + result = /obj/item/ammo_casing/shotgun/ion + reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1, + /obj/item/weapon/stock_parts/micro_laser/ultra = 1, + /obj/item/weapon/stock_parts/subspace/crystal = 1) + tools = list(/obj/item/weapon/screwdriver) + time = 5 + +/datum/table_recipe/improvisedslug + name = "Improvised Shotgun Shell" + result = /obj/item/ammo_casing/shotgun/improvised + reqs = list(/obj/item/weapon/grenade/chem_grenade = 1, + /obj/item/stack/sheet/metal = 1, + /obj/item/stack/cable_coil = 1, + /datum/reagent/fuel = 10) + tools = list(/obj/item/weapon/screwdriver) + time = 5 + +/datum/table_recipe/improvisedslugoverload + name = "Overload Improvised Shell" + result = /obj/item/ammo_casing/shotgun/improvised/overload + reqs = list(/obj/item/ammo_casing/shotgun/improvised = 1, + /datum/reagent/blackpowder = 5) + tools = list(/obj/item/weapon/screwdriver) + time = 5 + +/datum/table_recipe/laserslug + name = "Laser Slug Shell" + result = /obj/item/ammo_casing/shotgun/laserslug + reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1, + /obj/item/weapon/stock_parts/capacitor/adv = 1, + /obj/item/weapon/stock_parts/micro_laser/high = 1) + tools = list(/obj/item/weapon/screwdriver) + time = 5 + /datum/table_recipe/ishotgun name = "Improvised Shotgun" result = /obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised diff --git a/code/modules/crafting/table.dm b/code/modules/crafting/table.dm index 1d4bfa561e9..684f3ec5eb2 100644 --- a/code/modules/crafting/table.dm +++ b/code/modules/crafting/table.dm @@ -12,16 +12,34 @@ check_table() main_loop: for(var/A in R.reqs) + var/needed_amount = R.reqs[A] for(var/B in table_contents) if(ispath(B, A)) if(table_contents[B] >= R.reqs[A]) continue main_loop + else + needed_amount -= table_contents[B] + if(needed_amount <= 0) + continue main_loop + else + continue return 0 - for(var/A in R.chem_catalists) - if(table_contents[A] < R.chem_catalists[A]) + for(var/A in R.chem_catalysts) + if(table_contents[A] < R.chem_catalysts[A]) return 0 return 1 +/obj/structure/table/proc/partial_check_contents(datum/table_recipe/R) + check_table() + var/required_amount = max(round(R.reqs.len/2), 1) + var/amount = 0 + for(var/A in R.reqs) + for(var/B in table_contents) + if(ispath(B, A)) + amount += 1 + if(amount >= required_amount) + return 1 + /obj/structure/table/proc/check_table() table_contents = list() for(var/obj/item/I in loc) @@ -65,6 +83,9 @@ if(!check_contents(R) || !check_tools(user, R)) return 0 var/atom/movable/I = new R.result (loc) + if(istype(I, /obj/item/weapon/reagent_containers/food/snacks)) + var/obj/item/weapon/reagent_containers/food/snacks/S = I + S.create_reagents(S.volume) var/list/parts = del_reqs(R, I) for(var/A in parts) if(istype(A, /obj/item)) @@ -104,15 +125,18 @@ item_loop: for(var/B in table_contents) if(ispath(B, A)) - while(amt > 0) + var/item_amount = table_contents[B] + while(item_amount > 0) I = locate(B) in loc Deletion.Add(I) I.loc = null //remove it from the table loc so that we don't locate the same item every time (will be relocated inside the crafted item in construct_item()) amt-- + item_amount-- if(reagenttransfer && istype(I,/obj/item/weapon/reagent_containers)) var/obj/item/weapon/reagent_containers/RC = I RC.reagents.trans_to(resultobject, RC.reagents.total_volume) - break item_loop + if(amt <= 0) + break item_loop else var/datum/reagent/RG = new A reagent_loop: @@ -164,11 +188,46 @@ dat += "Crafting in progress..." else for(var/datum/table_recipe/R in table_recipes) + var/name_text = "" + var/req_text = "" + var/tool_text = "" + var/catalist_text = "" if(check_contents(R)) - dat += "[R.name]
" + name_text ="[R.name]" + + else if(partial_check_contents(R)) + name_text = "[R.name]" + + if(name_text) + for(var/A in R.reqs) + if(ispath(A, /obj)) + var/obj/O = new A + req_text += " [R.reqs[A]] [O.name]" + qdel(O) + if(ispath(A, /datum/reagent)) + var/datum/reagent/RE = new A + req_text += " [R.reqs[A]] [RE.name]" + qdel(RE) + + if(R.chem_catalysts.len) + catalist_text += ", Catalysts:" + for(var/C in R.chem_catalysts) + if(ispath(C, /datum/reagent)) + var/datum/reagent/RE = new C + catalist_text += " [R.chem_catalysts[C]] [RE.name]" + qdel(RE) + if(R.tools.len) + tool_text += ", Tools:" + for(var/O in R.tools) + if(ispath(O, /obj)) + var/obj/T = new O + tool_text += " [R.tools[O]] [T.name]" + qdel(T) + + dat += "[name_text][req_text][tool_text][catalist_text]
" dat += "" - var/datum/browser/popup = new(user, "table", "Table", 300, 300) + var/datum/browser/popup = new(user, "table", "Table", 500, 500) popup.set_content(dat) popup.open() return diff --git a/code/modules/detectivework/scanner.dm b/code/modules/detectivework/scanner.dm index 71fc5d1b932..affb72d1381 100644 --- a/code/modules/detectivework/scanner.dm +++ b/code/modules/detectivework/scanner.dm @@ -5,7 +5,7 @@ /obj/item/device/detective_scanner name = "forensic scanner" desc = "Used to remotely scan objects and biomass for DNA and fingerprints. Can print a report of the findings." - icon_state = "forensic1" + icon_state = "forensicnew" w_class = 3.0 item_state = "electronic" flags = CONDUCT | NOBLUDGEON diff --git a/code/modules/events/anomaly_bluespace.dm b/code/modules/events/anomaly_bluespace.dm index 5171ca6a4b6..91f71dc1fe9 100644 --- a/code/modules/events/anomaly_bluespace.dm +++ b/code/modules/events/anomaly_bluespace.dm @@ -44,8 +44,7 @@ var/list/flashers = list() for(var/mob/living/carbon/human/M in viewers(TO, null)) - if(M:eyecheck() <= 0) - flick("e_flash", M.flash) // flash dose faggots + if(M.flash_eyes()) flashers += M var/y_distance = TO.y - FROM.y diff --git a/code/modules/events/anomaly_pyro.dm b/code/modules/events/anomaly_pyro.dm index 237e59a1d48..9f5feea38e1 100644 --- a/code/modules/events/anomaly_pyro.dm +++ b/code/modules/events/anomaly_pyro.dm @@ -30,7 +30,7 @@ if(newAnomaly.loc) explosion(get_turf(newAnomaly), -1,0,3, flame_range = 4) - var/mob/living/carbon/slime/S = new/mob/living/carbon/slime(get_turf(newAnomaly)) + var/mob/living/simple_animal/slime/S = new/mob/living/simple_animal/slime(get_turf(newAnomaly)) S.colour = pick("red", "orange") qdel(newAnomaly) \ No newline at end of file diff --git a/code/modules/events/event.dm b/code/modules/events/event.dm index 172a562905b..e55c3203f4c 100644 --- a/code/modules/events/event.dm +++ b/code/modules/events/event.dm @@ -13,7 +13,7 @@ var/max_occurrences = 20 //The maximum number of times this event can occur (naturally), it can still be forced. //By setting this to 0 you can effectively disable an event. - var/holidayID //string which should match the events.holiday variable if you wish this event to be holiday-specific + var/holidayID = "" //string which should be in the SSevents.holidays list if you wish this event to be holiday-specific //anything with a (non-null) holidayID which does not match holiday, cannot run. var/wizardevent = 0 diff --git a/code/modules/events/holiday/friday13th.dm b/code/modules/events/holiday/friday13th.dm index a227cb6f611..e1a393fb867 100644 --- a/code/modules/events/holiday/friday13th.dm +++ b/code/modules/events/holiday/friday13th.dm @@ -2,7 +2,7 @@ /datum/round_event_control/fridaythethirteen name = "Friday the 13th" - holidayID = "Friday the 13th" + holidayID = FRIDAY_13TH typepath = /datum/round_event/fridaythethirteen weight = -1 max_occurrences = 1 diff --git a/code/modules/events/holiday/halloween.dm b/code/modules/events/holiday/halloween.dm index 5e8996a8c1d..8c3536444de 100644 --- a/code/modules/events/holiday/halloween.dm +++ b/code/modules/events/holiday/halloween.dm @@ -1,6 +1,6 @@ /datum/round_event_control/spooky name = "2 SPOOKY! (Halloween)" - holidayID = "Halloween" + holidayID = HALLOWEEN typepath = /datum/round_event/spooky weight = -1 //forces it to be called, regardless of weight max_occurrences = 1 @@ -17,7 +17,7 @@ else hardset_dna(H, null, null, null, null, /datum/species/zombie) - for(var/mob/living/simple_animal/corgi/Ian/Ian in mob_list) + for(var/mob/living/simple_animal/pet/corgi/Ian/Ian in mob_list) Ian.place_on_head(new /obj/item/weapon/bedsheet(Ian)) /datum/round_event/spooky/announce() @@ -27,7 +27,7 @@ /datum/round_event_control/carp_migration/eyeballs name = "Eyeball Migration" typepath = /datum/round_event/carp_migration/eyeballs - holidayID = "Halloween" + holidayID = HALLOWEEN weight = 25 earliest_start = 0 @@ -40,7 +40,7 @@ /datum/round_event_control/meteor_wave/spooky name = "Pumpkin Wave" typepath = /datum/round_event/meteor_wave/spooky - holidayID = "Halloween" + holidayID = HALLOWEEN weight = 20 max_occurrences = 2 diff --git a/code/modules/events/holiday/xmas.dm b/code/modules/events/holiday/xmas.dm index 727c5a0dce2..eacc8eacaba 100644 --- a/code/modules/events/holiday/xmas.dm +++ b/code/modules/events/holiday/xmas.dm @@ -1,6 +1,6 @@ /datum/round_event_control/treevenge name = "Treevenge (Christmas)" - holidayID = "Xmas" + holidayID = CHRISTMAS typepath = /datum/round_event/treevenge max_occurrences = 1 weight = 20 @@ -17,7 +17,7 @@ //this is an example of a possible round-start event /datum/round_event_control/presents name = "Presents under Trees (Christmas)" - holidayID = "Xmas" + holidayID = CHRISTMAS typepath = /datum/round_event/presents weight = -1 //forces it to be called, regardless of weight max_occurrences = 1 @@ -29,7 +29,7 @@ for(var/turf/simulated/floor/T in orange(1,xmas)) for(var/i=1,i<=rand(1,5),i++) new /obj/item/weapon/a_gift(T) - for(var/mob/living/simple_animal/corgi/Ian/Ian in mob_list) + for(var/mob/living/simple_animal/pet/corgi/Ian/Ian in mob_list) Ian.place_on_head(new /obj/item/clothing/head/helmet/space/santahat(Ian)) for(var/obj/machinery/computer/security/telescreen/entertainment/Monitor in machines) Monitor.icon_state = "entertainment_xmas" @@ -81,7 +81,7 @@ /datum/round_event_control/santa name = "Santa is coming to town! (Christmas)" - holidayID = "Xmas" + holidayID = CHRISTMAS typepath = /datum/round_event/santa weight = 150 max_occurrences = 1 @@ -148,4 +148,4 @@ telespell.clothes_req = 0 //santa robes aren't actually magical. santa.mind.spell_list += telespell //does the station have chimneys? WHO KNOWS! - santa << "You are Santa! Your objective is to bring joy to the people on this station. You can conjure more presents using a spell, and there are several presents in your bag." + santa << "You are Santa! Your objective is to bring joy to the people on this station. You can conjure more presents using a spell, and there are several presents in your bag." diff --git a/code/modules/events/ninja.dm b/code/modules/events/ninja.dm deleted file mode 100644 index fba9d8a692c..00000000000 --- a/code/modules/events/ninja.dm +++ /dev/null @@ -1,2436 +0,0 @@ -//Note to future generations: I didn't write this god-awful code I just ported it to the event system and tried to make it less moon-speaky. -//Don't judge me D; ~Carn - -/datum/round_event_control/ninja - name = "Space Ninja" - typepath = /datum/round_event/ninja - max_occurrences = 1 - earliest_start = 30000 // 1 hour - -/datum/round_event/ninja - var/success_spawn = 0 - - var/helping_station - var/key - var/spawn_loc - var/mission - - var/mob/living/carbon/human/Ninja - -/datum/round_event/ninja/setup() - helping_station = rand(0,1) - -/datum/round_event/ninja/kill() - if(!success_spawn && control) - control.occurrences-- - return ..() - -/datum/round_event/ninja/start() - //selecting a spawn_loc - if(!spawn_loc) - var/list/spawn_locs = list() - for(var/obj/effect/landmark/L in landmarks_list) - if(isturf(L.loc)) - switch(L.name) - if("ninjaspawn","carpspawn") - spawn_locs += L.loc - if(!spawn_locs.len) - return kill() - spawn_loc = pick(spawn_locs) - if(!spawn_loc) - return kill() - - //selecting a candidate player - if(!key) - var/list/candidates = get_candidates(BE_NINJA) - if(!candidates.len) - return kill() - var/client/C = pick(candidates) - key = C.key - if(!key) - return kill() - - //We prepare the mind before we spawn the ninja mob, so we cannot simply do mob.key = key then modify the mind. - //instead we make the mind and modify it, then make sure it is active and mind.transfer_to(mob) - //alternatively we could do mob.mind = mind;mob.key=key - var/datum/mind/Mind = create_ninja_mind(key) - Mind.active = 1 - - //generate objectives - You'll generally get 6 objectives (Ninja is meant to be hardmode!) - if(mission) - var/datum/objective/O = new /datum/objective(mission) - O.owner = Mind - Mind.objectives += O - else - if(helping_station) //DS are the highest priority (if we're a helpful ninja) - for(var/datum/mind/M in ticker.minds) - if(M.current && M.current.stat != DEAD) - if(M.special_role == "Death Commando") - var/datum/objective/assassinate/O = new /datum/objective/assassinate() - O.owner = Mind - O.target = M - O.explanation_text = "Slay \the [M.current.real_name], the Death Commando." - Mind.objectives += O - - else //Xenos are the highest priority (if we're not so helpful) Although this makes zero sense at all... - for(var/mob/living/carbon/alien/humanoid/queen/Q in player_list) - if(Q.mind && Q.stat != DEAD) - var/datum/objective/assassinate/O = new /datum/objective/assassinate() - O.owner = Mind - O.target = Q.mind - O.explanation_text = "Slay \the [Q.real_name]." - Mind.objectives += O - - if(Mind.objectives.len < 4) //not enough objectives still! - var/list/possible_targets = list() - for(var/datum/mind/M in ticker.minds) - if(M.current && M.current.stat != DEAD) - if(istype(M.current,/mob/living/carbon/human)) - if(M.special_role) - possible_targets[M] = 0 //bad-guy - else if(M.assigned_role in command_positions) - possible_targets[M] = 1 //good-guy - - var/list/objectives = list(1,2,3,4) - while(Mind.objectives.len < 4) //still not enough objectives! - switch(pick_n_take(objectives)) - if(1) //research - var/datum/objective/download/O = new /datum/objective/download() - O.owner = Mind - O.gen_amount_goal() - Mind.objectives += O - - if(2) //steal - var/datum/objective/steal/special/O = new /datum/objective/steal/special() - O.owner = Mind - Mind.objectives += O - - if(3) //protect/kill - if(!possible_targets.len) continue - var/selected = rand(1,possible_targets.len) - var/datum/mind/M = possible_targets[selected] - var/is_bad_guy = possible_targets[M] - possible_targets.Cut(selected,selected+1) - - if(is_bad_guy ^ helping_station) //kill (good-ninja + bad-guy or bad-ninja + good-guy) - var/datum/objective/assassinate/O = new /datum/objective/assassinate() - O.owner = Mind - O.target = M - O.explanation_text = "Slay \the [M.current.real_name], the [M.assigned_role]." - Mind.objectives += O - else //protect - var/datum/objective/protect/O = new /datum/objective/protect() - O.owner = Mind - O.target = M - O.explanation_text = "Protect \the [M.current.real_name], the [M.assigned_role], from harm." - Mind.objectives += O - if(4) //debrain/capture - if(!possible_targets.len) continue - var/selected = rand(1,possible_targets.len) - var/datum/mind/M = possible_targets[selected] - var/is_bad_guy = possible_targets[M] - possible_targets.Cut(selected,selected+1) - - if(is_bad_guy ^ helping_station) //debrain (good-ninja + bad-guy or bad-ninja + good-guy) - var/datum/objective/debrain/O = new /datum/objective/debrain() - O.owner = Mind - O.target = M - O.explanation_text = "Steal the brain of [M.current.real_name]." - Mind.objectives += O - else //capture - var/datum/objective/capture/O = new /datum/objective/capture() - O.owner = Mind - O.gen_amount_goal() - Mind.objectives += O - else - break - - //Add a survival objective since it's usually broad enough for any round type. - var/datum/objective/O = new /datum/objective/survive() - O.owner = Mind - Mind.objectives += O - - //Finally, add their RP-directive - var/directive = generate_ninja_directive() - O = new /datum/objective(directive) //making it an objective so admins can reward the for completion - O.owner = Mind - Mind.objectives += O - - //add some RP-fluff - Mind.store_memory("I am an elite mercenary assassin of the mighty Spider Clan. A SPACE NINJA!") - Mind.store_memory("Suprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by right clicking on it, to use abilities like stealth)!") - Mind.store_memory("Officially, [helping_station?"Nanotrasen":"The Syndicate"] are my employer.") - - //spawn the ninja and assign the candidate - Ninja = create_space_ninja(spawn_loc) - Mind.transfer_to(Ninja) - - //initialise equipment - Ninja.wear_suit:randomize_param() - Ninja.internal = Ninja.s_store - if(Ninja.internals) - Ninja.internals.icon_state = "internal1" - - if(Ninja.mind != Mind) //something has gone wrong! - ERROR("The ninja wasn't assigned the right mind. ;ç;") - - Ninja << sound('sound/effects/ninja_greeting.ogg') //so ninja you probably wouldn't even know if you were made one - - success_spawn = 1 - -/* -This proc will give the ninja a directive to follow. They are not obligated to do so but it's a fun roleplay reminder. -Making this random or semi-random will probably not work without it also being incredibly silly. -As such, it's hard-coded for now. No reason for it not to be, really. -*/ -/datum/round_event/ninja/proc/generate_ninja_directive() - switch(rand(1,13)) - if(1) return "The Spider Clan must not be linked to this operation. Remain as hidden and covert as possible." - if(2) return "[station_name] is financed by an enemy of the Spider Clan. Cause as much structural damage as possible." - if(3) return "A wealthy animal rights activist has made a request we cannot refuse. Prioritize saving animal lives whenever possible." - if(4) return "The Spider Clan absolutely cannot be linked to this operation. Eliminate all witnesses using most extreme prejudice." - if(5) return "We are currently negotiating with Nanotrasen command. Prioritize saving human lives over ending them." - if(6) return "We are engaged in a legal dispute over [station_name]. If a laywer is present on board, force their cooperation in the matter." - if(7) return "A financial backer has made an offer we cannot refuse. Implicate Syndicate involvement in the operation." - if(8) return "Let no one question the mercy of the Spider Clan. Ensure the safety of all non-essential personnel you encounter." - if(9) return "A free agent has proposed a lucrative business deal. Implicate Nanotrasen involvement in the operation." - if(10) return "Our reputation is on the line. Harm as few civilians or innocents as possible." - if(11) return "Our honor is on the line. Utilize only honorable tactics when dealing with opponents." - if(12) return "We are currently negotiating with a Syndicate leader. Disguise assassinations as suicide or another natural cause." - else return "There are no special supplemental instructions at this time." - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -+++++++++++++++++++++++++++++++++++++// //++++++++++++++++++++++++++++++++++ -======================================SPACE NINJA SETUP==================================== -___________________________________________________________________________________________ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -/* - README: - - Data: - - >> space_ninja.dm << is this file. It contains a variety of procs related to either spawning space ninjas, - modifying their verbs, various help procs, testing debug-related content, or storing unused procs for later. - Similar functions should go into this file, along with anything else that may not have an explicit category. - IMPORTANT: actual ninja suit, gloves, etc, are stored under the appropriate clothing files. If you need to change - variables or look them up, look there. Easiest way is through the map file browser. - - >> ninja_abilities.dm << contains all the ninja-related powers. Spawning energy swords, teleporting, and the like. - If more powers are added, or perhaps something related to powers, it should go there. Make sure to describe - what an ability/power does so it's easier to reference later without looking at the code. - IMPORTANT: verbs are still somewhat funky to work with. If an argument is specified but is not referenced in a way - BYOND likes, in the code content, the verb will fail to trigger. Nothing will happen, literally, when clicked. - This can be bypassed by either referencing the argument properly, or linking to another proc with the argument - attached. The latter is what I like to do for certain cases--sometimes it's necessary to do that regardless. - - >> ninja_equipment.dm << deals with all the equipment-related procs for a ninja. Primarily it has the suit, gloves, - and mask. The suit is by far the largest section of code out of the three and includes a lot of code that ties in - to other functions. This file has gotten kind of large so breaking it up may be in order. I use section hearders. - IMPORTANT: not much to say here. Follow along with the comments and adding new functions should be a breeze. Also - know that certain equipment pieces are linked in other files. The energy blade, for example, has special - functions defined in the appropriate files (airlock, securestorage, etc). - - General Notes: - - I created space ninjas with the expressed purpose of spicing up boring rounds. That is, ninjas are to xenos as marauders are to - death squads. Ninjas are stealthy, tech-savvy, and powerful. Not to say marauders are all of those things, but a clever ninja - should have little problem murderampaging their way through just about anything. Short of admin wizards maybe. - HOWEVER! - Ninjas also have a fairly great weakness as they require energy to use abilities. If, theoretically, there is a game - mode based around space ninjas, make sure to account for their energy needs. - - Admin Notes: - - Ninjas are not admin PCs--please do not use them for that purpose. They are another way to participate in the game post-death, - like pais, xenos, death squads, and cyborgs. - I'm currently looking for feedback from regular players since beta testing is largely done. I would appreciate if - you spawned regular players as ninjas when rounds are boring. Or exciting, it's all good as long as there is feedback. - You can also spawn ninja gear manually if you want to. - - How to do that: - Make sure your character has a mind. - Change their assigned_role to "MODE", no quotes. Otherwise, the suit won't initialize. - Change their special_role to "Space Ninja", no quotes. Otherwise, the character will be gibbed. - Spawn ninja gear, put it on, hit initialize. Let the suit do the rest. You are now a space ninja. - I don't recommend messing with suit variables unless you really know what you're doing. - - Miscellaneous Notes: - - Potential Upgrade Tree: - Energy Shield: - Extra Ability - Syndicate Shield device? - Works like the force wall spell, except can be kept indefinitely as long as energy remains. Toggled on or off. - Would block bullets and the like. - Phase Shift - Extra Ability - Advanced Sensors? - Instead of being unlocked at the start, Phase Shieft would become available once requirements are met. - Uranium-based Recharger: - Suit Upgrade - Unsure - Instead of losing energy each second, the suit would regain the same amount of energy. - This would not count in activating stealth and similar. - Extended Battery Life: - Suit Upgrade - Battery of higher capacity - Already implemented. Replace current battery with one of higher capacity. - Advanced Cloak-Tech device. - Suit Upgrade - Syndicate Cloaking Device? - Remove cloak failure rate. -*/ - - -//=======//CURRENT PLAYER VERB//=======// - -/client/proc/cmd_admin_ninjafy(var/mob/living/carbon/human/H in player_list) - set category = null - set name = "Make Space Ninja" - - if(!ticker) - alert("Wait until the game starts") - return - - if(!istype(H)) - return - - if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes") - return - - log_admin("[key_name(src)] turned [H.key] into a Space Ninja.") - H.mind = create_ninja_mind(H.key) - H.mind_initialize() - H.equip_space_ninja(1) - if(istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja)) - H.wear_suit:randomize_param() - spawn(0) - H.wear_suit:ninitialize(10,H) - -//=======//CURRENT GHOST VERB//=======// - -/client/proc/send_space_ninja() - set category = "Fun" - set name = "Spawn Space Ninja" - set desc = "Spawns a space ninja for when you need a teenager with attitude." - set popup_menu = 0 - - if(!holder) - src << "Only administrators may use this command." - return - if(!ticker.mode) - alert("The game hasn't started yet!") - return - if(alert("Are you sure you want to send in a space ninja?",,"Yes","No")=="No") - return - - var/mission = copytext(sanitize(input(src, "Please specify which mission the space ninja shall undertake.", "Specify Mission", null) as text|null),1,MAX_MESSAGE_LEN) - - var/client/C = input("Pick character to spawn as the Space Ninja", "Key", "") as null|anything in clients - if(!C) - return - - var/datum/round_event/ninja/E = new /datum/round_event/ninja() - E.key=C.key - E.mission=mission - - message_admins("[key_name_admin(key)] has spawned [key_name_admin(C.key)] as a Space Ninja.") - log_admin("[key] used Spawn Space Ninja.") - - return - -//=======//NINJA CREATION PROCS//=======// - -/proc/create_space_ninja(spawn_loc) - var/mob/living/carbon/human/new_ninja = new(spawn_loc) - if(prob(50)) new_ninja.gender = "female" - var/datum/preferences/A = new()//Randomize appearance for the ninja. - A.real_name = "[pick(ninja_titles)] [pick(ninja_names)]" - A.copy_to(new_ninja) - ready_dna(new_ninja) - new_ninja.equip_space_ninja() - return new_ninja - -/mob/living/carbon/human/proc/equip_space_ninja(safety=0)//Safety in case you need to unequip stuff for existing characters. - if(safety) - qdel(w_uniform) - qdel(wear_suit) - qdel(wear_mask) - qdel(head) - qdel(shoes) - qdel(gloves) - - var/obj/item/device/radio/R = new /obj/item/device/radio/headset(src) - equip_to_slot_or_del(R, slot_ears) - equip_to_slot_or_del(new /obj/item/clothing/under/color/black(src), slot_w_uniform) - equip_to_slot_or_del(new /obj/item/clothing/shoes/space_ninja(src), slot_shoes) - equip_to_slot_or_del(new /obj/item/clothing/suit/space/space_ninja(src), slot_wear_suit) - equip_to_slot_or_del(new /obj/item/clothing/gloves/space_ninja(src), slot_gloves) - equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/space_ninja(src), slot_head) - equip_to_slot_or_del(new /obj/item/clothing/mask/gas/voice/space_ninja(src), slot_wear_mask) - equip_to_slot_or_del(new /obj/item/clothing/glasses/night(src), slot_glasses) - equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_belt) - equip_to_slot_or_del(new /obj/item/weapon/c4(src), slot_r_store) - equip_to_slot_or_del(new /obj/item/weapon/c4(src), slot_l_store) - equip_to_slot_or_del(new /obj/item/weapon/tank/internals/emergency_oxygen(src), slot_s_store) - equip_to_slot_or_del(new /obj/item/weapon/tank/jetpack/carbondioxide(src), slot_back) - - var/obj/item/weapon/implant/explosive/E = new/obj/item/weapon/implant/explosive(src) - E.imp_in = src - E.implanted = 1 - E.implanted(src) - return 1 - -//=======//HELPER PROCS//=======// - -//Randomizes suit parameters. -/obj/item/clothing/suit/space/space_ninja/proc/randomize_param() - s_cost = rand(1,20) - s_acost = rand(20,100) - k_cost = rand(100,500) - k_damage = rand(1,20) - s_delay = rand(10,100) - s_bombs = rand(5,20) - a_boost = rand(1,7) - -//This proc prevents the suit from being taken off. -/obj/item/clothing/suit/space/space_ninja/proc/lock_suit(mob/living/carbon/U, X = 0) - if(X)//If you want to check for icons. - icon_state = U.gender==FEMALE ? "s-ninjanf" : "s-ninjan" - U:gloves.icon_state = "s-ninjan" - U:gloves.item_state = "s-ninjan" - else - if(U.mind.special_role!="Space Ninja") - U << "\red fÄTaL ÈÈRRoR: 382200-*#00CÖDE RED\nUNAU†HORIZED USÈ DETÈC†††eD\nCoMMÈNCING SUB-R0U†IN3 13...\nTÈRMInATING U-U-USÈR..." - U.gib() - return 0 - if(!istype(U:head, /obj/item/clothing/head/helmet/space/space_ninja)) - U << "ERROR: 100113 UNABLE TO LOCATE HEAD GEAR\nABORTING..." - return 0 - if(!istype(U:shoes, /obj/item/clothing/shoes/space_ninja)) - U << "ERROR: 122011 UNABLE TO LOCATE FOOT GEAR\nABORTING..." - return 0 - if(!istype(U:gloves, /obj/item/clothing/gloves/space_ninja)) - U << "ERROR: 110223 UNABLE TO LOCATE HAND GEAR\nABORTING..." - return 0 - - affecting = U - flags |= NODROP //colons make me go all |= - slowdown = 0 - n_hood = U:head - n_hood.flags |= NODROP - n_shoes = U:shoes - n_shoes.flags |= NODROP - n_shoes.slowdown-- - n_gloves = U:gloves - n_gloves.flags |= NODROP - - return 1 - -//This proc allows the suit to be taken off. -/obj/item/clothing/suit/space/space_ninja/proc/unlock_suit() - affecting = null - flags &= ~NODROP - slowdown = 1 - icon_state = "s-ninja" - if(n_hood)//Should be attached, might not be attached. - n_hood.flags &= ~NODROP - if(n_shoes) - n_shoes.flags &= ~NODROP - n_shoes.slowdown++ - if(n_gloves) - n_gloves.icon_state = "s-ninja" - n_gloves.item_state = "s-ninja" - n_gloves.flags &= ~NODROP - n_gloves.candrain=0 - n_gloves.draining=0 - -//Allows the mob to grab a stealth icon. -/mob/proc/NinjaStealthActive(atom/A)//A is the atom which we are using as the overlay. - invisibility = INVISIBILITY_LEVEL_TWO//Set ninja invis to 2. - var/icon/opacity_icon = new(A.icon, A.icon_state) - var/icon/alpha_mask = getIconMask(src) - var/icon/alpha_mask_2 = new('icons/effects/effects.dmi', "at_shield1") - alpha_mask.AddAlphaMask(alpha_mask_2) - opacity_icon.AddAlphaMask(alpha_mask) - for(var/i=0,i<5,i++)//And now we add it as overlays. It's faster than creating an icon and then merging it. - var/image/I = image("icon" = opacity_icon, "icon_state" = A.icon_state, "layer" = layer+0.8)//So it's above other stuff but below weapons and the like. - switch(i)//Now to determine offset so the result is somewhat blurred. - if(1) - I.pixel_x -= 1 - if(2) - I.pixel_x += 1 - if(3) - I.pixel_y -= 1 - if(4) - I.pixel_y += 1 - - overlays += I//And finally add the overlay. - overlays += image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = layer+0.9) - -//When ninja steal malfunctions. -/mob/proc/NinjaStealthMalf() - invisibility = 0//Set ninja invis to 0. - overlays += image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = layer+0.9) - playsound(loc, 'sound/effects/stealthoff.ogg', 75, 1) - -//=======//GENERIC VERB MODIFIERS//=======// - -/obj/item/clothing/suit/space/space_ninja/proc/grant_equip_verbs() - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/init - verbs += /obj/item/clothing/suit/space/space_ninja/proc/deinit - verbs += /obj/item/clothing/suit/space/space_ninja/proc/spideros - verbs += /obj/item/clothing/suit/space/space_ninja/proc/stealth - n_gloves.verbs += /obj/item/clothing/gloves/space_ninja/proc/toggled - - s_initialized = 1 - -/obj/item/clothing/suit/space/space_ninja/proc/remove_equip_verbs() - verbs += /obj/item/clothing/suit/space/space_ninja/proc/init - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/deinit - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/spideros - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/stealth - if(n_gloves) - n_gloves.verbs -= /obj/item/clothing/gloves/space_ninja/proc/toggled - - s_initialized = 0 - -/obj/item/clothing/suit/space/space_ninja/proc/grant_ninja_verbs() - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjashift - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjasmoke - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjaboost - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjapulse - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjablade - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjastar - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjanet - - s_initialized=1 - slowdown=0 - -/obj/item/clothing/suit/space/space_ninja/proc/remove_ninja_verbs() - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjashift - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjasmoke - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjaboost - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjapulse - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjablade - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjastar - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjanet - -//=======//KAMIKAZE VERBS//=======// - -/obj/item/clothing/suit/space/space_ninja/proc/grant_kamikaze(mob/living/carbon/U) - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjashift - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjapulse - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjastar - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjanet - - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjaslayer - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjawalk - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjamirage - - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/stealth - - kamikaze = 1 - - icon_state = U.gender==FEMALE ? "s-ninjakf" : "s-ninjak" - if(n_gloves) - n_gloves.icon_state = "s-ninjak" - n_gloves.item_state = "s-ninjak" - n_gloves.candrain = 0 - n_gloves.draining = 0 - n_gloves.verbs -= /obj/item/clothing/gloves/space_ninja/proc/toggled - - cancel_stealth() - - U << browse(null, "window=spideros") - U << "Do or Die, LET'S ROCK!!" - -/obj/item/clothing/suit/space/space_ninja/proc/remove_kamikaze(mob/living/carbon/U) - if(kamikaze) - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjashift - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjapulse - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjastar - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjanet - - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjaslayer - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjawalk - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjamirage - - verbs += /obj/item/clothing/suit/space/space_ninja/proc/stealth - if(n_gloves) - n_gloves.verbs -= /obj/item/clothing/gloves/space_ninja/proc/toggled - - U.incorporeal_move = 0 - kamikaze = 0 - k_unlock = 0 - U << "Disengaging mode...\nCODE NAME: KAMIKAZE" - -//=======//AI VERBS//=======// - -/obj/item/clothing/suit/space/space_ninja/proc/grant_AI_verbs() - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_hack_ninja - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_return_control - - s_busy = 0 - s_control = 0 - -/obj/item/clothing/suit/space/space_ninja/proc/remove_AI_verbs() - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ai_hack_ninja - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ai_return_control - - s_control = 1 - - -//Alternate ninja speech replacement. -/*This text is hilarious but also absolutely retarded. -message = replacetext(message, "l", "r") -message = replacetext(message, "rr", "ru") -message = replacetext(message, "v", "b") -message = replacetext(message, "f", "hu") -message = replacetext(message, "'t", "") -message = replacetext(message, "t ", "to ") -message = replacetext(message, " I ", " ai ") -message = replacetext(message, "th", "z") -message = replacetext(message, "ish", "isu") -message = replacetext(message, "is", "izu") -message = replacetext(message, "ziz", "zis") -message = replacetext(message, "se", "su") -message = replacetext(message, "br", "bur") -message = replacetext(message, "ry", "ri") -message = replacetext(message, "you", "yuu") -message = replacetext(message, "ck", "cku") -message = replacetext(message, "eu", "uu") -message = replacetext(message, "ow", "au") -message = replacetext(message, "are", "aa") -message = replacetext(message, "ay", "ayu") -message = replacetext(message, "ea", "ii") -message = replacetext(message, "ch", "chi") -message = replacetext(message, "than", "sen") -message = replacetext(message, ".", "") -message = lowertext(message) -*/ - - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -+++++++++++++++++++++++++++++++++// //++++++++++++++++++++++++++++++++++ -==================================SPACE NINJA ABILITIES==================================== -___________________________________________________________________________________________ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -//=======//SAFETY CHECK//=======// -/* -X is optional, tells the proc to check for specific stuff. C is also optional. -All the procs here assume that the character is wearing the ninja suit if they are using the procs. -They should, as I have made every effort for that to be the case. -In the case that they are not, I imagine the game will run-time error like crazy. -s_cooldown ticks off each second based on the suit recharge proc, in seconds. Default of 1 seconds. Some abilities have no cool down. -*/ -/obj/item/clothing/suit/space/space_ninja/proc/ninjacost(C = 0,X = 0) - var/mob/living/carbon/human/U = affecting - if( (U.stat||U.incorporeal_move)&&X!=3 )//Will not return if user is using an adrenaline booster since you can use them when stat==1. - U << "You must be conscious and solid to do this."//It's not a problem of stat==2 since the ninja will explode anyway if they die. - return 1 - else if(C&&cell.chargeNot enough energy.
" - return 1 - switch(X) - if(1) - cancel_stealth()//Get rid of it. - if(2) - if(s_bombs<=0) - U << "There are no more smoke bombs remaining." - return 1 - if(3) - if(a_boost<=0) - U << "You do not have any more adrenaline boosters." - return 1 - return (s_coold)//Returns the value of the variable which counts down to zero. - -//=======//TELEPORT GRAB CHECK//=======// -/obj/item/clothing/suit/space/space_ninja/proc/handle_teleport_grab(turf/T, mob/living/U) - if(istype(U.get_active_hand(),/obj/item/weapon/grab))//Handles grabbed persons. - var/obj/item/weapon/grab/G = U.get_active_hand() - G.affecting.loc = locate(T.x+rand(-1,1),T.y+rand(-1,1),T.z)//variation of position. - if(istype(U.get_inactive_hand(),/obj/item/weapon/grab)) - var/obj/item/weapon/grab/G = U.get_inactive_hand() - G.affecting.loc = locate(T.x+rand(-1,1),T.y+rand(-1,1),T.z)//variation of position. - return - -//=======//SMOKE//=======// -/*Summons smoke in radius of user. -Not sure why this would be useful (it's not) but whatever. Ninjas need their smoke bombs.*/ -/obj/item/clothing/suit/space/space_ninja/proc/ninjasmoke() - set name = "Smoke Bomb" - set desc = "Blind your enemies momentarily with a well-placed smoke bomb." - set category = "Ninja Ability" - set popup_menu = 0//Will not see it when right clicking. - - if(!ninjacost(,2)) - var/mob/living/carbon/human/U = affecting - U << "There are [s_bombs] smoke bombs remaining." - var/datum/effect/effect/system/bad_smoke_spread/smoke = new /datum/effect/effect/system/bad_smoke_spread() - smoke.set_up(10, 0, U.loc) - smoke.start() - playsound(U.loc, 'sound/effects/bamf.ogg', 50, 2) - s_bombs-- - s_coold = 1 - return - -//=======//9-8 TILE TELEPORT//=======// -//Click to to teleport 9-10 tiles in direction facing. -/obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt() - set name = "Phase Jaunt (10E)" - set desc = "Utilizes the internal VOID-shift device to rapidly transit in direction facing." - set category = "Ninja Ability" - set popup_menu = 0 - - var/C = 100 - if(!ninjacost(C,1)) - var/mob/living/carbon/human/U = affecting - var/turf/destination = get_teleport_loc(U.loc,U,9,1,3,1,0,1) - var/turf/mobloc = get_turf(U.loc)//To make sure that certain things work properly below. - if(destination&&istype(mobloc, /turf))//The turf check prevents unusual behavior. Like teleporting out of cryo pods, cloners, mechs, etc. - spawn(0) - playsound(U.loc, "sparks", 50, 1) - anim(mobloc,src,'icons/mob/mob.dmi',,"phaseout",,U.dir) - - handle_teleport_grab(destination, U) - U.loc = destination - - spawn(0) - spark_system.start() - playsound(U.loc, 'sound/effects/phasein.ogg', 25, 1) - playsound(U.loc, "sparks", 50, 1) - anim(U.loc,U,'icons/mob/mob.dmi',,"phasein",,U.dir) - - spawn(0) - destination.phase_damage_creatures(20,U)//Paralyse and damage mobs and mechas on the turf - s_coold = 1 - cell.charge-=(C*10) - else - U << "The VOID-shift device is malfunctioning, teleportation failed." - return - -//=======//RIGHT CLICK TELEPORT//=======// -//Right click to teleport somewhere, almost exactly like admin jump to turf. -/obj/item/clothing/suit/space/space_ninja/proc/ninjashift(turf/T in oview()) - set name = "Phase Shift (20E)" - set desc = "Utilizes the internal VOID-shift device to rapidly transit to a destination in view." - set category = null//So it does not show up on the panel but can still be right-clicked. - set src = usr.contents//Fixes verbs not attaching properly for objects. Praise the DM reference guide! - - var/C = 200 - if(!ninjacost(C,1)) - var/mob/living/carbon/human/U = affecting - var/turf/mobloc = get_turf(U.loc)//To make sure that certain things work properly below. - if((!T.density)&&istype(mobloc, /turf)) - spawn(0) - playsound(U.loc, 'sound/effects/sparks4.ogg', 50, 1) - anim(mobloc,src,'icons/mob/mob.dmi',,"phaseout",,U.dir) - - handle_teleport_grab(T, U) - U.loc = T - - spawn(0) - spark_system.start() - playsound(U.loc, 'sound/effects/phasein.ogg', 25, 1) - playsound(U.loc, 'sound/effects/sparks2.ogg', 50, 1) - anim(U.loc,U,'icons/mob/mob.dmi',,"phasein",,U.dir) - - spawn(0)//Any living mobs in teleport area are gibbed. - T.phase_damage_creatures(20,U)//Paralyse and damage mobs and mechas on the turf - s_coold = 1 - cell.charge-=(C*10) - else - U << "You cannot teleport into solid walls or from solid matter" - return - -//=======//EM PULSE//=======// -//Disables nearby tech equipment. -/obj/item/clothing/suit/space/space_ninja/proc/ninjapulse() - set name = "EM Burst (25E)" - set desc = "Disable any nearby technology with a electro-magnetic pulse." - set category = "Ninja Ability" - set popup_menu = 0 - - var/C = 250 - if(!ninjacost(C,1)) - var/mob/living/carbon/human/U = affecting - playsound(U.loc, 'sound/effects/EMPulse.ogg', 60, 2) - empulse(U, 4, 6) //Procs sure are nice. Slightly weaker than wizard's disable tch. - s_coold = 2 - cell.charge-=(C*10) - return - -//=======//ENERGY BLADE//=======// -//Summons a blade of energy in active hand. -/obj/item/clothing/suit/space/space_ninja/proc/ninjablade() - set name = "Energy Blade (5E)" - set desc = "Create a focused beam of energy in your active hand." - set category = "Ninja Ability" - set popup_menu = 0 - - var/C = 50 - if(!ninjacost(C)) - var/mob/living/carbon/human/U = affecting - if(!kamikaze) - if(!U.get_active_hand()&&!istype(U.get_inactive_hand(), /obj/item/weapon/melee/energy/blade)) - var/obj/item/weapon/melee/energy/blade/W = new() - spark_system.start() - playsound(U.loc, "sparks", 50, 1) - U.put_in_hands(W) - cell.charge-=(C*10) - else - U << "You can only summon one blade. Try dropping an item first." - else//Else you can run around with TWO energy blades. I don't know why you'd want to but cool factor remains. - if(!U.get_active_hand()) - var/obj/item/weapon/melee/energy/blade/W = new() - U.put_in_hands(W) - if(!U.get_inactive_hand()) - var/obj/item/weapon/melee/energy/blade/W = new() - U.put_in_inactive_hand(W) - spark_system.start() - playsound(U.loc, "sparks", 50, 1) - s_coold = 1 - return - -//=======//NINJA STARS//=======// -/*Shoots ninja stars at random people. -This could be a lot better but I'm too tired atm.*/ -/obj/item/clothing/suit/space/space_ninja/proc/ninjastar() - set name = "Energy Star (5E)" - set desc = "Launches an energy star at a random living target." - set category = "Ninja Ability" - set popup_menu = 0 - - var/C = 50 - if(!ninjacost(C)) - var/mob/living/carbon/human/U = affecting - var/targets[] = list()//So yo can shoot while yo throw dawg - for(var/mob/living/M in oview(loc)) - if(M.stat) continue//Doesn't target corpses or paralyzed persons. - targets.Add(M) - if(targets.len) - var/mob/living/target=pick(targets)//The point here is to pick a random, living mob in oview to shoot stuff at. - - var/turf/curloc = U.loc - var/atom/targloc = get_turf(target) - if (!targloc || !istype(targloc, /turf) || !curloc) - return - if (targloc == curloc) - return - var/obj/item/projectile/energy/dart/A = new /obj/item/projectile/energy/dart(U.loc) - A.current = curloc - A.yo = targloc.y - curloc.y - A.xo = targloc.x - curloc.x - cell.charge-=(C*10) - A.fire() - else - U << "There are no targets in view." - return - -//=======//ENERGY NET//=======// -/*Allows the ninja to capture people, I guess. -Must right click on a mob to activate.*/ -/obj/item/clothing/suit/space/space_ninja/proc/ninjanet(mob/living/carbon/M in oview())//Only living carbon mobs. - set name = "Energy Net (20E)" - set desc = "Captures a fallen opponent in a net of energy. Will teleport them to a holding facility after 30 seconds." - set category = null - set src = usr.contents - - var/C = 200 - if(!ninjacost(C,1)&&iscarbon(M)) - var/mob/living/carbon/human/U = affecting - if(M.client)//Monkeys without a client can still step_to() and bypass the net. Also, netting inactive people is lame. - //if(M)//DEBUG - if(!locate(/obj/effect/energy_net) in M.loc)//Check if they are already being affected by an energy net. - for(var/turf/T in getline(U.loc, M.loc)) - if(T.density)//Don't want them shooting nets through walls. It's kind of cheesy. - U << "You may not use an energy net through solid obstacles!" - return - spawn(0) - U.Beam(M,"n_beam",,15) - M.anchored = 1//Anchors them so they can't move. - U.say("Get over here!") - var/obj/effect/energy_net/E = new /obj/effect/energy_net(M.loc) - E.layer = M.layer+1//To have it appear one layer above the mob. - for(var/mob/O in viewers(U, 3)) - O.show_message(text("[] caught [] with an energy net!", U, M), 1) - E.affecting = M - E.master = U - spawn(0)//Parallel processing. - E.process(M) - cell.charge-=(C*10) - else - U << "They are already trapped inside an energy net." - else - U << "They will bring no honor to your Clan!" - return - -//=======//ADRENALINE BOOST//=======// -/*Wakes the user so they are able to do their thing. Also injects a decent dose of radium. -Movement impairing would indicate drugs and the like.*/ -/obj/item/clothing/suit/space/space_ninja/proc/ninjaboost() - set name = "Adrenaline Boost" - set desc = "Inject a secret chemical that will counteract all movement-impairing effect." - set category = "Ninja Ability" - set popup_menu = 0 - - if(!ninjacost(,3))//Have to make sure stat is not counted for this ability. - var/mob/living/carbon/human/U = affecting - //Wouldn't need to track adrenaline boosters if there was a miracle injection to get rid of paralysis and the like instantly. - //For now, adrenaline boosters ARE the miracle injection. Well, radium, really. - U.SetParalysis(0) - U.SetStunned(0) - U.SetWeakened(0) - /* - Due to lag, it was possible to adrenaline boost but remain helpless while life.dm resets player stat. - This lead to me and others spamming adrenaline boosters because they failed to kick in on time. - It's technically possible to come back from crit with this but it is very temporary. - Life.dm will kick the player back into unconsciosness the next process loop. - */ - U.stat = 0//At least now you should be able to teleport away or shoot ninja stars. - spawn(30)//Slight delay so the enemy does not immedietly know the ability was used. Due to lag, this often came before waking up. - U.say(pick("A CORNERED FOX IS MORE DANGEROUS THAN A JACKAL!","HURT ME MOOORRREEE!","IMPRESSIVE!")) - spawn(70) - reagents.reaction(U, 2) - reagents.trans_id_to(U, "radium", a_transfer) - U << "You are beginning to feel the after-effect of the injection." - a_boost-- - s_coold = 3 - return - -/* -=================================================================================== -<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -=================================================================================== -Or otherwise known as anime mode. Which also happens to be ridiculously powerful. -*/ - -//=======//NINJA MOVEMENT//=======// -//Also makes you move like you're on crack. -/obj/item/clothing/suit/space/space_ninja/proc/ninjawalk() - set name = "Shadow Walk" - set desc = "Combines the VOID-shift and CLOAK-tech devices to freely move between solid matter. Toggle on or off." - set category = "Ninja Ability" - set popup_menu = 0 - - var/mob/living/carbon/human/U = affecting - if(!U.incorporeal_move) - U.incorporeal_move = 2 - U << "You will now phase through solid matter." - else - U.incorporeal_move = 0 - U << "You will no-longer phase through solid matter." - return - -//=======//5 TILE TELEPORT/GIB//=======// -//Allows to kill up to five squares in a straight line. Seriously. -/obj/item/clothing/suit/space/space_ninja/proc/ninjaslayer() - set name = "Phase Slayer" - set desc = "Utilizes the internal VOID-shift device to kill all creatures in a straight line." - set category = "Ninja Ability" - set popup_menu = 0 - - if(!ninjacost()) - var/mob/living/carbon/human/U = affecting - var/turf/destination = get_teleport_loc(U.loc,U,5) - var/turf/mobloc = get_turf(U.loc)//To make sure that certain things work properly below. - if(destination&&istype(mobloc, /turf)) - U.say("Ai Satsugai!") - spawn(0) - playsound(U.loc, "sparks", 50, 1) - anim(mobloc,U,'icons/mob/mob.dmi',,"phaseout",,U.dir) - - spawn(0) - for(var/turf/T in getline(mobloc, destination)) - spawn(0) - T.phase_damage_creatures(190,U) - if(T==mobloc||T==destination) continue - spawn(0) - anim(T,U,'icons/mob/mob.dmi',,"phasein",,U.dir) - - handle_teleport_grab(destination, U) - U.loc = destination - - spawn(0) - spark_system.start() - playsound(U.loc, 'sound/effects/phasein.ogg', 25, 1) - playsound(U.loc, "sparks", 50, 1) - anim(U.loc,U,'icons/mob/mob.dmi',,"phasein",,U.dir) - s_coold = 1 - else - U << "The VOID-shift device is malfunctioning, teleportation failed." - return - -//=======//TELEPORT BEHIND MOB//=======// -/*Appear behind a randomly chosen mob while a few decoy teleports appear. -This is so anime it hurts. But that's the point.*/ -/obj/item/clothing/suit/space/space_ninja/proc/ninjamirage() - set name = "Spider Mirage" - set desc = "Utilizes the internal VOID-shift device to create decoys and teleport behind a random target." - set category = "Ninja Ability" - set popup_menu = 0 - - if(!ninjacost())//Simply checks for stat. - var/mob/living/carbon/human/U = affecting - var/targets[] - targets = new() - for(var/mob/living/M in oview(6)) - if(M.stat) continue//Doesn't target corpses or paralyzed people. - targets.Add(M) - if(targets.len) - var/mob/living/target=pick(targets) - var/locx - var/locy - var/turf/mobloc = get_turf(target.loc) - var/safety = 0 - switch(target.dir) - if(NORTH) - locx = mobloc.x - locy = (mobloc.y-1) - if(locy<1) - safety = 1 - if(SOUTH) - locx = mobloc.x - locy = (mobloc.y+1) - if(locy>world.maxy) - safety = 1 - if(EAST) - locy = mobloc.y - locx = (mobloc.x-1) - if(locx<1) - safety = 1 - if(WEST) - locy = mobloc.y - locx = (mobloc.x+1) - if(locx>world.maxx) - safety = 1 - else safety=1 - if(!safety&&istype(mobloc, /turf)) - U.say("Kumo no Shinkiro!") - var/turf/picked = locate(locx,locy,mobloc.z) - spawn(0) - playsound(U.loc, "sparks", 50, 1) - anim(mobloc,U,'icons/mob/mob.dmi',,"phaseout",,U.dir) - - spawn(0) - var/limit = 4 - for(var/turf/T in oview(5)) - if(prob(20)) - spawn(0) - anim(T,U,'icons/mob/mob.dmi',,"phasein",,U.dir) - limit-- - if(limit<=0) break - - handle_teleport_grab(picked, U) - U.loc = picked - U.dir = target.dir - - spawn(0) - spark_system.start() - playsound(U.loc, 'sound/effects/phasein.ogg', 25, 1) - playsound(U.loc, "sparks", 50, 1) - anim(U.loc,U,'icons/mob/mob.dmi',,"phasein",,U.dir) - s_coold = 1 - else - U << "The VOID-shift device is malfunctioning, teleportation failed." - else - U << "There are no targets in view." - return - - -//For the love of god,space out your code! This is a nightmare to read. - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -+++++++++++++++++++++++++++++++++// //++++++++++++++++++++++++++++++++++ -===================================SPACE NINJA EQUIPMENT=================================== -___________________________________________________________________________________________ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -/* -=================================================================================== -<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -=================================================================================== -*/ - -//=======//NEW AND DEL//=======// - -/obj/item/clothing/suit/space/space_ninja/New() - ..() - verbs += /obj/item/clothing/suit/space/space_ninja/proc/init//suit initialize verb - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_instruction//for AIs - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_holo - //verbs += /obj/item/clothing/suit/space/space_ninja/proc/display_verb_procs//DEBUG. Doesn't work. - spark_system = new()//spark initialize - spark_system.set_up(5, 0, src) - spark_system.attach(src) - stored_research = new()//Stolen research initialize. - for(var/T in typesof(/datum/tech) - /datum/tech)//Store up on research. - stored_research += new T(src) - var/reagent_amount//reagent initialize - for(var/reagent_id in reagent_list) - reagent_amount += reagent_id == "radium" ? r_maxamount+(a_boost*a_transfer) : r_maxamount//AI can inject radium directly. - reagents = new(reagent_amount) - reagents.my_atom = src - for(var/reagent_id in reagent_list) - reagent_id == "radium" ? reagents.add_reagent(reagent_id, r_maxamount+(a_boost*a_transfer)) : reagents.add_reagent(reagent_id, r_maxamount)//It will take into account radium used for adrenaline boosting. - cell = new/obj/item/weapon/stock_parts/cell/high//The suit should *always* have a battery because so many things rely on it. - cell.charge = 9000//Starting charge should not be higher than maximum charge. It leads to problems with recharging. - NAI = new(src) //ninja intellicard - -/obj/item/clothing/suit/space/space_ninja/Destroy() - if(affecting)//To make sure the window is closed. - affecting << browse(null, "window=hack spideros") - if(AI)//If there are AIs present when the ninja kicks the bucket. - killai(NAI) - if(hologram)//If there is a hologram - qdel(hologram.i_attached)//Delete it and the attached image. - qdel(hologram) - ..() - -//Simply deletes all the attachments and self, killing all related procs. -/obj/item/clothing/suit/space/space_ninja/proc/terminate() - qdel(n_hood) - qdel(n_gloves) - qdel(n_shoes) - qdel(src) - - - -/obj/item/clothing/suit/space/space_ninja/proc/killai(var/obj/item/device/aicard/NAI) - for(var/mob/living/silicon/ai/A in src) - if(A.client) - A << "Self-erase protocol dete-- *bzzzzz*" - A << browse(null, "window=hack spideros") - NAI.flush = 1 - return - - - -//=======//SUIT VERBS//=======// -//Verbs link to procs because verb-like procs have a bug which prevents their use if the arguments are not readily referenced. - -/obj/item/clothing/suit/space/space_ninja/proc/init() - set name = "Initialize Suit" - set desc = "Initializes the suit for field operation." - set category = "Ninja Equip" - - ninitialize() - return - -/obj/item/clothing/suit/space/space_ninja/proc/deinit() - set name = "De-Initialize Suit" - set desc = "Begins procedure to remove the suit." - set category = "Ninja Equip" - - if(s_control&&!s_busy) - deinitialize() - else - affecting << "The function did not trigger!" - return - -/obj/item/clothing/suit/space/space_ninja/proc/spideros() - set name = "Display SpiderOS" - set desc = "Utilize built-in computer system." - set category = "Ninja Equip" - - if(s_control&&!s_busy&&!kamikaze) - display_spideros() - else - affecting << "The interface is locked!" - return - -/obj/item/clothing/suit/space/space_ninja/proc/stealth() - set name = "Toggle Stealth" - set desc = "Utilize the internal CLOAK-tech device to activate or deactivate stealth-camo." - set category = "Ninja Equip" - - if(s_control&&!s_busy) - toggle_stealth() - else - affecting << "Stealth does not appear to work!" - return - -//=======//PROCESS PROCS//=======// - -/obj/item/clothing/suit/space/space_ninja/proc/ntick(mob/living/carbon/human/U = affecting) - set background = BACKGROUND_ENABLED - - //Runs in the background while the suit is initialized. - spawn while(cell.charge>=0) - - //Let's check for some safeties. - if(s_initialized&&!affecting) terminate()//Kills the suit and attached objects. - if(!s_initialized) return//When turned off the proc stops. - for(var/mob/living/silicon/ai/A in NAI) - if(A&&A.stat==2)//If there is an AI and it's ded. Shouldn't happen without purging, could happen. - if(!s_control) - ai_return_control()//Return control to ninja if the AI was previously in control. - - //Now let's do the normal processing. - if(s_coold) s_coold--//Checks for ability s_cooldown first. - var/A = s_cost//s_cost is the default energy cost each ntick, usually 5. - if(!kamikaze) - if(blade_check(U))//If there is a blade held in hand. - A += s_acost - if(s_active)//If stealth is active. - A += s_acost - else - if(prob(s_delay))//Suit delay is used as probability. May change later. - U.adjustBruteLoss(k_damage)//Default damage done, usually 1. - A = k_cost//kamikaze cost. - cell.charge-=A - if(cell.charge<=0) - if(kamikaze) - U.say("I DIE TO LIVE AGAIN!") - U << browse(null, "window=spideros")//Just in case. - U.death() - return - cell.charge=0 - cancel_stealth() - sleep(10)//Checks every second. - -//=======//INITIALIZE//=======// - -/obj/item/clothing/suit/space/space_ninja/proc/ninitialize(delay = s_delay, mob/living/carbon/human/U = loc) - if(U.mind && U.mind.assigned_role=="MODE" && !s_initialized && !s_busy)//Shouldn't be busy... but anything is possible I guess. - s_busy = 1 - for(var/i,i<7,i++) - switch(i) - if(0) - U << "Now initializing..." - if(1) - if(!lock_suit(U))//To lock the suit onto wearer. - break - U << "Securing external locking mechanism...\nNeural-net established." - if(2) - U << "Extending neural-net interface...\nNow monitoring brain wave pattern..." - if(3) - if(U.stat==2||U.health<=0) - U << "FĆAL �Rr�R: 344--93#�&&21 BR��N |/|/aV� PATT$RN RED\nA-A-aB�rT�NG..." - unlock_suit() - break - lock_suit(U,1)//Check for icons. - U.regenerate_icons() - U << " Linking neural-net interface...\nPattern\green GREEN, continuing operation." - if(4) - U << "VOID-shift device status: ONLINE.\nCLOAK-tech device status: ONLINE." - if(5) - U << "Primary system status: ONLINE.\nBackup system status: ONLINE.\nCurrent energy capacity: [cell.charge]." - if(6) - U << "All systems operational. Welcome to SpiderOS, [U.real_name]." - grant_ninja_verbs() - grant_equip_verbs() - ntick() - sleep(delay) - s_busy = 0 - else - if(!U.mind||U.mind.assigned_role!="MODE")//Your run of the mill persons shouldn't know what it is. Or how to turn it on. - U << "You do not understand how this suit functions. Where the heck did it even come from?" - else if(s_initialized) - U << "The suit is already functioning. Please report this bug." - else - U << "ERROR: You cannot use this function at this time." - return - -//=======//DEINITIALIZE//=======// - -/obj/item/clothing/suit/space/space_ninja/proc/deinitialize(delay = s_delay) - if(affecting==loc&&!s_busy) - var/mob/living/carbon/human/U = affecting - if(!s_initialized) - U << "The suit is not initialized. Please report this bug." - return - if(alert("Are you certain you wish to remove the suit? This will take time and remove all abilities.",,"Yes","No")=="No") - return - if(s_busy || NAI.flush) - U << "ERROR: You cannot use this function at this time." - return - s_busy = 1 - for(var/i = 0,i<7,i++) - switch(i) - if(0) - U << "Now de-initializing..." - remove_kamikaze(U)//Shutdowns kamikaze. - spideros = 0//Spideros resets. - if(1) - U << "Logging off, [U:real_name]. Shutting down SpiderOS." - remove_ninja_verbs() - if(2) - U << "Primary system status: OFFLINE.\nBackup system status: OFFLINE." - if(3) - U << "VOID-shift device status: OFFLINE.\nCLOAK-tech device status: OFFLINE." - cancel_stealth()//Shutdowns stealth. - if(4) - U << "Disconnecting neural-net interface...\greenSuccess." - if(5) - U << "Disengaging neural-net interface...\greenSuccess." - if(6) - U << "Unsecuring external locking mechanism...\nNeural-net abolished.\nOperation status: FINISHED." - blade_check(U,2) - remove_equip_verbs() - unlock_suit() - U.regenerate_icons() - sleep(delay) - s_busy = 0 - return - -//=======//SPIDEROS PROC//=======// - -/obj/item/clothing/suit/space/space_ninja/proc/display_spideros() - if(!affecting) return//If no mob is wearing the suit. I almost forgot about this variable. - var/mob/living/carbon/human/U = affecting - var/mob/living/silicon/ai/A = AI - var/display_to = s_control ? U : A//Who do we want to display certain messages to? - - var/dat = "SpiderOS" - dat += " Refresh" - if(spideros) - dat += " | Return" - dat += " | Close" - dat += "
" - if(s_control) - dat += "

SpiderOS v.1.337

" - dat += "Welcome, [U.real_name].
" - else - dat += "

SpiderOS v.ERR-RR00123

" - dat += "
" - dat += " Current Time: [worldtime2text()]
" - dat += " Battery Life: [round(cell.charge/100)]%
" - dat += " Smoke Bombs: \Roman [s_bombs]
" - dat += " pai Device: " - if(pai) - dat += "Configure" - dat += " | " - dat += "Eject" - else - dat += "None Detected" - dat += "

" - - switch(spideros) - if(0) - dat += "

Available Functions:

" - dat += "" - if(3) - dat += "

Medical Report:

" - if(U.dna) - dat += "Fingerprints: [md5(U.dna.uni_identity)]
" - dat += "Unique identity: [U.dna.unique_enzymes]
" - dat += "

Overall Status: [U.stat > 1 ? "dead" : "[U.health]% healthy"]

" - dat += "

Nutrition Status: [U.nutrition]

" - dat += "Oxygen loss: [U.getOxyLoss()]" - dat += " | Toxin levels: [U.getToxLoss()]
" - dat += "Burn severity: [U.getFireLoss()]" - dat += " | Brute trauma: [U.getBruteLoss()]
" - dat += "Radiation Level: [U.radiation] rad
" - dat += "Body Temperature: [U.bodytemperature-T0C]°C ([U.bodytemperature*1.8-459.67]°F)
" - - for(var/datum/disease/D in U.viruses) - dat += "Warning: Virus Detected. Name: [D.name].Type: [D.spread_text]. Stage: [D.stage]/[D.max_stages]. Possible Cure: [D.cure_text].
" - dat += "" - if(1) - dat += "

Atmospheric Scan:

"//Headers don't need breaks. They are automatically placed. - var/turf/T = get_turf(U.loc) - if (isnull(T)) - dat += "Unable to obtain a reading." - else - var/datum/gas_mixture/environment = T.return_air() - - var/pressure = environment.return_pressure() - var/total_moles = environment.total_moles() - - dat += "Air Pressure: [round(pressure,0.1)] kPa" - - if (total_moles) - var/o2_level = environment.oxygen/total_moles - var/n2_level = environment.nitrogen/total_moles - var/co2_level = environment.carbon_dioxide/total_moles - var/plasma_level = environment.toxins/total_moles - var/unknown_level = 1-(o2_level+n2_level+co2_level+plasma_level) - dat += "
    " - dat += "
  • Nitrogen: [round(n2_level*100)]%
  • " - dat += "
  • Oxygen: [round(o2_level*100)]%
  • " - dat += "
  • Carbon Dioxide: [round(co2_level*100)]%
  • " - dat += "
  • Plasma: [round(plasma_level*100)]%
  • " - dat += "
" - if(unknown_level > 0.01) - dat += "OTHER: [round(unknown_level)]%
" - - dat += "Temperature: [round(environment.temperature-T0C)]°C" - if(2) - if(k_unlock==7||!s_control) - dat += " Hidden Menu" - dat += "

Anonymous Messenger:

"//Anonymous because the receiver will not know the sender's identity. - dat += "

Detected PDAs:

" - dat += "
    " - var/count = 0 - for (var/obj/item/device/pda/P in get_viewable_pdas()) - dat += "
  • [P]" - dat += "
  • " - count++ - dat += "
" - if (count == 0) - dat += "None detected.
" - if(32) - dat += "

Hidden Menu:

" - if(s_control) - dat += "Please input password: " - dat += "HERE
" - dat += "
" - dat += "Remember, you will not be able to recharge energy during this function. If energy runs out, the suit will auto self-destruct.
" - dat += "Use with caution. De-initialize the suit when energy is low." - else - //Only leaving this in for funnays. CAN'T LET YOU DO THAT STAR FOX - dat += "WARNING: Hostile runtime intrusion detected: operation locked. The Spider Clan is watching you, INTRUDER." - dat += "ERROR: TARANTULA.v.4.77.12 encryption algorithm detected. Unable to decrypt archive.
" - if(4) - dat += {" -

Ninja Manual:

-
Who they are:
- Space ninjas are a special type of ninja, specifically one of the space-faring type. The vast majority of space ninjas belong to the Spider Clan, a cult-like sect, which has existed for several hundred years. The Spider Clan practice a sort of augmentation of human flesh in order to achieve a more perfect state of being and follow Postmodern Space Bushido. They also kill people for money. Their leaders are chosen from the oldest of the grand-masters, people that have lived a lot longer than any mortal man should.
Being a sect of technology-loving fanatics, the Spider Clan have the very best to choose from in terms of hardware--cybernetic implants, exoskeleton rigs, hyper-capacity batteries, and you get the idea. Some believe that much of the Spider Clan equipment is based on reverse-engineered alien technology while others doubt such claims.
Whatever the case, their technology is absolutely superb. -
How they relate to other SS13 organizations:
-
    -
  • *Nanotrasen and the Syndicate are two sides of the same coin and that coin is valuable.
  • -
  • *The Space Wizard Federation is a problem, mainly because they are an extremely dangerous group of unpredictable individuals--not to mention the wizards hate technology and are in direct opposition of the Spider Clan. Best avoided or left well-enough alone. How to battle: wizards possess several powerful abilities to steer clear off. Blind in particular is a nasty spell--jaunt away if you are blinded and never approach a wizard in melee. Stealth may also work if the wizard is not wearing thermal scanners--don't count on this. Run away if you feel threatened and await a better opportunity.
  • -
  • *Changeling Hivemind: extremely dangerous and to be killed on sight. How to battle: they will likely try to absorb you. Adrenaline boost, then phase shift into them. If you get stung, use SpiderOS to inject counter-agents. Stealth may also work but detecting a changeling is the real battle.
  • -
  • *Xeno Hivemind: their skulls make interesting kitchen decorations and are challenging to best, especially in larger nests. How to battle: they can see through your stealth guise and energy stars will not work on them. Best killed with a Phase Shift or at range. If you happen on a projectile stun weapon, use it and then close in to melee.
  • -
-
The reason they (you) are here:
- Space ninjas are renowned throughout the known controlled space as fearless spies, infiltrators, and assassins. They are sent on missions of varying nature by Nanotrasen, the Syndicate, and other shady organizations and people. To hire a space ninja means serious business. -
Their playstyle:
- A mix of traitor, changeling, and wizard. Ninjas rely on energy, or electricity to be precise, to keep their suits running (when out of energy, a suit hibernates). Suits gain energy from objects or creatures that contain electrical charge. APCs, cell batteries, rechargers, SMES batteries, cyborgs, mechs, and exposed wires are currently supported. Through energy ninjas gain access to special powers--while all powers are tied to the ninja suit, the most useful of them are verb activated--to help them in their mission.
It is a constant struggle for a ninja to remain hidden long enough to recharge the suit and accomplish their objective; despite their arsenal of abilities, ninjas can die like any other. Unlike wizards, ninjas do not possess good crowd control and are typically forced to play more subdued in order to achieve their goals. Some of their abilities are specifically designed to confuse and disorient others.
With that said, it should be perfectly possible to completely flip the fuck out and rampage as a ninja. -
Their powers:
- There are two primary types: Equipment and Abilties. Passive effect are always on. Active effect must be turned on and remain active only when there is energy to do so. Ability costs are listed next to them. - Equipment: cannot be tracked by AI (passive), faster speed (passive), stealth (active), vision switch (passive if toggled), voice masking (passive), SpiderOS (passive if toggled), energy drain (passive if toggled). -
    -
  • Voice masking generates a random name the ninja can use over the radio and in-person. Although, the former use is recommended.
  • -
  • Toggling vision cycles to one of the following: thermal, meson, or darkness vision. The starting mode allows one to scout the identity of those in view, revealing their role. Traitors, revolutionaries, wizards, and other such people will be made known to you.
  • -
  • Stealth, when activated, drains more battery charge and works similarly to a syndicate cloak. The cloak will deactivate when most Abilities are utilized.
  • -
  • On-board AI: The suit is able to download an AI much like an intellicard. Check with SpiderOS for details once downloaded.
  • -
  • SpiderOS is a specialized, PDA-like screen that allows for a small variety of functions, such as injecting healing chemicals directly from the suit. You are using it now, if that was not already obvious. You may also download AI modules directly to the OS.
  • -
- Abilities: -
    -
  • *Phase Shift (2000E) and Phase Jaunt (1000E) are unique powers in that they can both be used for defense and offense. Jaunt launches the ninja forward facing up to 9 squares, somewhat randomly selecting the final destination. Shift can only be used on turf in view but is precise (cannot be used on walls). Any living mob in the area teleported to is instantly gibbed (mechs are damaged, huggers and other similar critters are killed). It is possible to teleport with a target, provided you grab them before teleporting.
  • -
  • *Energy Blade (500E) is a highly effective weapon. It is summoned directly to the ninja's hand and can also function as an EMAG for certain objects (doors/lockers/etc). You may also use it to cut through walls and disabled doors. Experiment! The blade will crit humans in two hits. This item cannot be placed in containers and when dropped or thrown disappears. Having an energy blade drains more power from the battery each tick.
  • -
  • *EM Pulse (2500E) is a highly useful ability that will create an electromagnetic shockwave around the ninja, disabling technology whenever possible. If used properly it can render a security force effectively useless. Of course, getting beat up with a toolbox is not accounted for.
  • -
  • *Energy Star (500E) is a ninja star made of green energy AND coated in poison. It works by picking a random living target within range and can be spammed to great effect in incapacitating foes. Just remember that the poison used is also used by the Xeno Hivemind (and will have no effect on them).
  • -
  • *Energy Net (2000E) is a non-lethal solution to incapacitating humanoids. The net is made of non-harmful phase energy and will halt movement as long as it remains in effect--it can be destroyed. If the net is not destroyed, after a certain time it will teleport the target to a holding facility for the Spider Clan and then vanish. You will be notified if the net fails or succeeds in capturing a target in this manner. Combine with energy stars or stripping to ensure success. Abduction never looked this leet.
  • -
  • *Adrenaline Boost (1 E. Boost/3) recovers the user from stun, weakness, and paralysis. Also injects 20 units of radium into the bloodstream.
  • -
  • *Smoke Bomb (1 Sm.Bomb/10) is a weak but potentially useful ability. It creates harmful smoke and can be used in tandem with other powers to confuse enemies.
  • -
  • *???: unleash the True Ultimate Power!
  • -

    IMPORTANT:

    -
      -
    • *Make sure to toggle Special Interaction from the Ninja Equipment menu to interact differently with certain objects.
    • -
    • *Your starting power cell can be replaced if you find one with higher maximum energy capacity by clicking on your suit with the higher capacity cell.
    • -
    • *Conserve your energy. Without it, you are very vulnerable.
    • -
    - That is all you will need to know. The rest will come with practice and talent. Good luck! -

    Master /N

    - "} - if(5) - dat += "

    AI Control:

    " - if(NAI) - NAI.attack_self(display_to) //Just accesses the integrated Intellicard. If an AI is in control of the suit then I guess it can interact with its own card. How meta. - - if(6) - dat += {" -

    Activate Abilities:

    - - "} - if(7) - dat += "

    Research Stored:

    " - if(t_disk) - dat += "Eject Disk
    " - dat += "
      " - if(istype(stored_research,/list))//If there is stored research. Should be but just in case. - for(var/datum/tech/current_data in stored_research) - dat += "
    • " - dat += "[current_data.name]: [current_data.level]" - if(t_disk)//If there is a disk inserted. We can either write or overwrite. - dat += " *Copy to Disk
      " - dat += "
    • " - dat += "
    " - dat += "" - - //Setting the can>resize etc to 0 remove them from the drag bar but still allows the window to be draggable. - display_to << browse(dat,"window=spideros;size=400x444;border=1;can_resize=1;can_close=0;can_minimize=0") - -//=======//SPIDEROS TOPIC PROC//=======// - -/obj/item/clothing/suit/space/space_ninja/Topic(href, href_list) - ..() - var/mob/living/carbon/human/U = affecting - var/mob/living/silicon/ai/A = AI - var/display_to = s_control ? U : A//Who do we want to display certain messages to? - - if(s_control) - if(!affecting||U.stat||!s_initialized)//Check to make sure the guy is wearing the suit after clicking and it's on. - U << "Your suit must be worn and active to use this function." - U << browse(null, "window=spideros")//Closes the window. - return - - if(k_unlock!=7&&href_list["choice"]!="Return") - var/u1=text2num(href_list["choice"]) - var/u2=(u1?abs(abs(k_unlock-u1)-2):1) - k_unlock=(!u2? k_unlock+1:0) - if(k_unlock==7) - U << "Anonymous Messenger blinks." - else - if(!affecting||A.stat||!s_initialized||A.loc!=src) - A << "This function is not available at this time." - A << browse(null, "window=spideros")//Closes the window. - return - - switch(href_list["choice"]) - if("Close") - display_to << browse(null, "window=spideros") - return - if("Refresh")//Refresh, goes to the end of the proc. - if("Return")//Return - if(spideros<=9) - spideros=0 - else - spideros = round(spideros/10)//Best way to do this, flooring to nearest integer. - - if("Shock") - var/damage = min(cell.charge, rand(50,150))//Uses either the current energy left over or between 50 and 150. - if(damage>1)//So they don't spam it when energy is a factor. - spark_system.start()//SPARKS THERE SHALL BE SPARKS - U.electrocute_act(damage, src,0.1,1)//The last argument is a safety for the human proc that checks for gloves. - cell.charge -= damage - else - A << "ERROR: Not enough energy remaining." - - if("Message") - var/obj/item/device/pda/P = locate(href_list["target"]) - var/t = input(U, "Please enter untraceable message.") as text - t = copytext(sanitize(t), 1, MAX_MESSAGE_LEN) - if(!t||U.stat||U.wear_suit!=src||!s_initialized)//Wow, another one of these. Man... - display_to << browse(null, "window=spideros") - return - if(isnull(P)||P.toff)//So it doesn't freak out if the object no-longer exists. - display_to << "Error: unable to deliver message." - display_spideros() - return - P.tnote += "← From [!s_control?(A):"an unknown source"]:
    [t]
    " - if (!P.silent) - playsound(P.loc, 'sound/machines/twobeep.ogg', 50, 1) - P.audible_message("\icon[P] *[P.ttone]*", null, 3) - P.overlays.Cut() - P.overlays += image('icons/obj/pda.dmi', "pda-r") - - if("Inject") - if( (href_list["tag"]=="radium"? (reagents.get_reagent_amount("radium"))<=(a_boost*a_transfer) : !reagents.get_reagent_amount(href_list["tag"])) )//Special case for radium. If there are only a_boost*a_transfer radium units left. - display_to << "Error: the suit cannot perform this function. Out of [href_list["name"]]." - else - reagents.reaction(U, 2) - reagents.trans_id_to(U, href_list["tag"], href_list["tag"]=="nutriment"?5:a_transfer)//Nutriment is a special case since it's very potent. Shouldn't influence actual refill amounts or anything. - display_to << "Injecting..." - U << "You feel a tiny prick and a sudden rush of substance in to your veins." - - if("Trigger Ability") - var/ability_name = href_list["name"]+href_list["cost"]//Adds the name and cost to create the full proc name. - var/proc_arguments//What arguments to later pass to the proc, if any. - var/targets[] = list()//To later check for. - var/safety = 0//To later make sure we're triggering the proc when needed. - switch(href_list["name"])//Special case. - if("Phase Shift") - safety = 1 - for(var/turf/T in oview(5,loc)) - targets.Add(T) - if("Energy Net") - safety = 1 - for(var/mob/living/carbon/M in oview(5,loc)) - targets.Add(M) - if(targets.len)//Let's create an argument for the proc if needed. - proc_arguments = pick(targets) - safety = 0 - if(!safety) - A << "You trigger [href_list["name"]]." - U << "[href_list["name"]] suddenly triggered!" - call(src,ability_name)(proc_arguments) - else - A << "There are no potential [href_list["name"]=="Phase Shift"?"destinations" : "targets"] in view." - - if("Unlock Kamikaze") - if(input(U)=="Divine Wind") - if( !(U.stat||U.wear_suit!=src||!s_initialized) ) - if( !(cell.charge<=1||s_busy) ) - s_busy = 1 - for(var/i, i<4, i++) - switch(i) - if(0) - U << "Engaging mode...\nCODE NAME: KAMIKAZE" - if(1) - U << "Re-routing power nodes... \nUnlocking limiter..." - if(2) - U << "Power nodes re-routed. \nLimiter unlocked." - if(3) - grant_kamikaze(U)//Give them verbs and change variables as necessary. - U.regenerate_icons()//Update their clothing. - ninjablade()//Summon two energy blades. - message_admins("[key_name_admin(U)] used KAMIKAZE mode.")//Let the admins know. - s_busy = 0 - return - sleep(s_delay) - else - U << "ERROR: Unable to initiate mode." - else - U << browse(null, "window=spideros") - s_busy = 0 - return - else - U << "ERROR: WRONG PASSWORD!" - k_unlock = 0 - spideros = 0 - s_busy = 0 - - if("Eject Disk") - var/turf/T = get_turf(loc) - if(!U.get_active_hand()) - U.put_in_hands(t_disk) - t_disk.add_fingerprint(U) - t_disk = null - else - if(T) - t_disk.loc = T - t_disk = null - else - U << "ERROR: Could not eject disk." - - if("Copy to Disk") - var/datum/tech/current_data = locate(href_list["target"]) - U << "[current_data.name] successfully [(!t_disk.stored) ? "copied" : "overwritten"] to disk." - t_disk.stored = current_data - - if("Configure pAI") - pai.attack_self(U) - - if("Eject pAI") - var/turf/T = get_turf(loc) - if(!U.get_active_hand()) - U.put_in_hands(pai) - pai.add_fingerprint(U) - pai = null - else - if(T) - pai.loc = T - pai = null - else - U << "ERROR: Could not eject pAI card." - - if("Override AI Laws") - var/law_zero = A.laws.zeroth//Remembers law zero, if there is one. - A.laws = new /datum/ai_laws/ninja_override - A.set_zeroth_law(law_zero)//Adds back law zero if there was one. - A.show_laws() - U << "Law Override: SUCCESS." - - if("Purge AI") - var/confirm = alert("Are you sure you want to purge the AI? This cannot be undone once started.", "Confirm purge", "Yes", "No") - if(U.stat||U.wear_suit!=src||!s_initialized) - U << browse(null, "window=spideros") - return - if(confirm == "Yes"&&AI) - if(A.laws.zeroth)//Gives a few seconds to re-upload the AI somewhere before it takes full control. - s_busy = 1 - for(var/i,i<5,i++) - if(AI==A) - switch(i) - if(0) - A << "WARNING: purge procedure detected. \nNow hacking host..." - U << "WARNING: HACKING AT��TEMP� IN PR0GRESs!" - spideros = 0 - k_unlock = 0 - U << browse(null, "window=spideros") - if(1) - A << "Disconnecting neural interface..." - U << "WAR�NING: �R�O0�Gr�--S 2&3%" - if(2) - A << "Shutting down external protocol..." - U << "WARNING: P����RֆGr�5S 677^%" - cancel_stealth() - if(3) - A << "Connecting to kernel..." - U << "WARNING: �R�r�R_404" - A.control_disabled = 0 - if(4) - A << "Connection established and secured. Menu updated." - U << "W�r#nING: #%@!!WȆ|_4�54@ \nUn�B88l3 T� L�-�o-L�CaT2 ##$!�RN�0..%.." - grant_AI_verbs() - return - sleep(s_delay) - else break - s_busy = 0 - U << "Hacking attempt disconnected. Resuming normal operation." - else - NAI.flush = 1 - A.suiciding = 1 - A << "Your core files are being purged! This is the end..." - spawn(0) - display_spideros()//To refresh the screen and let this finish. - while (A.stat != 2) - A.adjustOxyLoss(2) - A.updatehealth() - sleep(10) - killai(NAI) - U << "Artificial Intelligence was terminated. Rebooting..." - NAI.flush = 0 - - if("Wireless AI") - A.control_disabled = !A.control_disabled - A << "AI wireless has been [A.control_disabled ? "disabled" : "enabled"]." - else//If it's not a defined function, it's a menu. - spideros=text2num(href_list["choice"]) - - display_spideros()//Refreshes the screen by calling it again (which replaces current screen with new screen). - return - -//=======//SPECIAL AI FUNCTIONS//=======// - -/obj/item/clothing/suit/space/space_ninja/proc/ai_holo(var/turf/T in oview(3,affecting))//To have an internal AI display a hologram to the AI and ninja only. - set name = "Display Hologram" - set desc = "Channel a holographic image directly to the user's field of vision. Others will not see it." - set category = null - set src = usr.loc - - if(s_initialized&&affecting&&affecting.client&&istype(affecting.loc, /turf))//If the host exists and they are playing, and their location is a turf. - if(!hologram)//If there is not already a hologram. - hologram = new(T)//Spawn a blank effect at the location. - hologram.invisibility = 101//So that it doesn't show up, ever. This also means one could attach a number of images to a single obj and display them differently to differnet people. - hologram.anchored = 1//So it cannot be dragged by space wind and the like. - hologram.dir = get_dir(T,affecting.loc) - - for(var/mob/living/silicon/ai/A in NAI) - var/image/I = image(A.holo_icon,hologram)//Attach an image to object. - hologram.i_attached = I//To attach the image in order to later reference. - A << I - affecting << I - affecting << "An image flicks to life nearby. It appears visible to you only." - - verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_holo_clear - - ai_holo_process()//Move to initialize - else - AI << "ERROR: Image feed in progress." - else - AI << "ERROR: Unable to project image." - return - -/obj/item/clothing/suit/space/space_ninja/proc/ai_holo_process() - set background = BACKGROUND_ENABLED - - spawn while(hologram&&s_initialized&&AI)//Suit on and there is an AI present. - if(!s_initialized||get_dist(affecting,hologram.loc)>3)//Once suit is de-initialized or hologram reaches out of bounds. - qdel(hologram.i_attached) - qdel(hologram) - - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ai_holo_clear - return - sleep(10)//Checks every second. - -/obj/item/clothing/suit/space/space_ninja/proc/ai_instruction()//Let's the AI know what they can do. - set name = "Instructions" - set desc = "Displays a list of helpful information." - set category = "AI Ninja Equip" - set src = usr.loc - - AI << "The menu you are seeing will contain other commands if they become available.\nRight click a nearby turf to display an AI Hologram. It will only be visible to you and your host. You can move it freely using normal movement keys--it will disappear if placed too far away." - -/obj/item/clothing/suit/space/space_ninja/proc/ai_holo_clear() - set name = "Clear Hologram" - set desc = "Stops projecting the current holographic image." - set category = "AI Ninja Equip" - set src = usr.loc - - qdel(hologram.i_attached) - qdel(hologram) - - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ai_holo_clear - return - -/obj/item/clothing/suit/space/space_ninja/proc/ai_hack_ninja() - set name = "Hack SpiderOS" - set desc = "Hack directly into the Black Widow(tm) neuro-interface." - set category = "AI Ninja Equip" - set src = usr.loc - - display_spideros() - return - -/obj/item/clothing/suit/space/space_ninja/proc/ai_return_control() - set name = "Relinquish Control" - set desc = "Return control to the user." - set category = "AI Ninja Equip" - set src = usr.loc - - - for(var/mob/living/silicon/ai/A in NAI) - AI << browse(null, "window=spideros")//Close window - AI << "You have seized your hacking attempt. [affecting.real_name] has regained control." - affecting << "UPDATE: [A.real_name] has ceased hacking attempt. All systems clear." - - remove_AI_verbs() - return - -//=======//GENERAL SUIT PROCS//=======// - -/obj/item/clothing/suit/space/space_ninja/attackby(obj/item/I, mob/U, params) - if(U==affecting)//Safety, in case you try doing this without wearing the suit/being the person with the suit. - if(istype(I, /obj/item/device/aicard))//If it's an AI card. - if(s_control) - I:transfer_ai("NINJASUIT","AICARD",src,U) - else - U << "ERROR: Remote access channel disabled." - return//Return individually so that ..() can run properly at the end of the proc. - else if(istype(I, /obj/item/device/paicard) && !pai)//If it's a pai card. - U:drop_item() - I.loc = src - pai = I - U << "You slot \the [I] into \the [src]." - updateUsrDialog() - return - else if(istype(I, /obj/item/weapon/reagent_containers/glass))//If it's a glass beaker. - var/total_reagent_transfer//Keep track of this stuff. - for(var/reagent_id in reagent_list) - var/datum/reagent/R = I.reagents.has_reagent(reagent_id)//Mostly to pull up the name of the reagent after calculating. Also easier to use than writing long proc paths. - if(R&&reagents.get_reagent_amount(reagent_id)=a_transfer)//Radium is always special. - //Here we determine how much reagent will actually transfer if there is enough to transfer or there is a need of transfer. Minimum of max amount available (using a_transfer) or amount needed. - var/amount_to_transfer = min( (r_maxamount+(reagent_id == "radium"?(a_boost*a_transfer):0)-reagents.get_reagent_amount(reagent_id)) ,(round(R.volume/a_transfer))*a_transfer)//In the end here, we round the amount available, then multiply it again. - R.volume -= amount_to_transfer//Remove from reagent volume. Don't want to delete the reagent now since we need to perserve the name. - reagents.add_reagent(reagent_id, amount_to_transfer)//Add to suit. Reactions are not important. - total_reagent_transfer += amount_to_transfer//Add to total reagent trans. - U << "Added [amount_to_transfer] units of [R.name]."//Reports on the specific reagent added. - I.reagents.update_total()//Now we manually update the total to make sure everything is properly shoved under the rug. - - U << "Replenished a total of [total_reagent_transfer ? total_reagent_transfer : "zero"] chemical units."//Let the player know how much total volume was added. - return - else if(istype(I, /obj/item/weapon/stock_parts/cell)) - if(I:maxcharge>cell.maxcharge&&n_gloves&&n_gloves.candrain) - U << "Higher maximum capacity detected.\nUpgrading..." - if (n_gloves&&n_gloves.candrain&&do_after(U,s_delay)) - U.drop_item() - I.loc = src - I:charge = min(I:charge+cell.charge, I:maxcharge) - var/obj/item/weapon/stock_parts/cell/old_cell = cell - old_cell.charge = 0 - U.put_in_hands(old_cell) - old_cell.add_fingerprint(U) - old_cell.corrupt() - old_cell.updateicon() - cell = I - U << "Upgrade complete. Maximum capacity: [round(cell.maxcharge/100)]%" - else - U << "Procedure interrupted. Protocol terminated." - return - else if(istype(I, /obj/item/weapon/disk/tech_disk))//If it's a data disk, we want to copy the research on to the suit. - var/obj/item/weapon/disk/tech_disk/TD = I - if(TD.stored)//If it has something on it. - U << "Research information detected, processing..." - if(do_after(U,s_delay)) - for(var/datum/tech/current_data in stored_research) - if(current_data.id==TD.stored.id) - if(current_data.levelData analyzed and updated. Disk erased." - else - U << "ERROR: Procedure interrupted. Process terminated." - else - I.loc = src - t_disk = I - U << "You slot \the [I] into \the [src]." - return - ..() - -/obj/item/clothing/suit/space/space_ninja/proc/toggle_stealth() - var/mob/living/carbon/human/U = affecting - if(s_active) - cancel_stealth() - else - spawn(0) - anim(U.loc,U,'icons/mob/mob.dmi',,"cloak",,U.dir) - s_active=!s_active - U.alpha = 0 - U.visible_message("[U.name] vanishes into thin air!", \ - "You are now invisible to normal detection.") - return - -/obj/item/clothing/suit/space/space_ninja/proc/cancel_stealth() - var/mob/living/carbon/human/U = affecting - if(s_active) - spawn(0) - anim(U.loc,U,'icons/mob/mob.dmi',,"uncloak",,U.dir) - s_active=!s_active - U.alpha = 255 - U.visible_message("[U.name] appears from thin air!", \ - "You are now visible.") - return 1 - return 0 - -/obj/item/clothing/suit/space/space_ninja/proc/blade_check(mob/living/carbon/U, X = 1)//Default to checking for blade energy. - switch(X) - if(1) - if(istype(U.get_active_hand(), /obj/item/weapon/melee/energy/blade)) - if(cell.charge<=0)//If no charge left. - U.drop_item()//Blade is dropped from active hand (and deleted). - else return 1 - else if(istype(U.get_inactive_hand(), /obj/item/weapon/melee/energy/blade)) - if(cell.charge<=0) - U.swap_hand()//swap hand - U.drop_item()//drop blade - else return 1 - if(2) - if(istype(U.get_active_hand(), /obj/item/weapon/melee/energy/blade)) - U.drop_item() - if(istype(U.get_inactive_hand(), /obj/item/weapon/melee/energy/blade)) - U.swap_hand() - U.drop_item() - return 0 - -/obj/item/clothing/suit/space/space_ninja/examine(mob/user) - ..() - if(s_initialized) - if(user == affecting) - if(s_control) - user << "All systems operational. Current energy capacity: [cell.charge]." - if(!kamikaze) - user << "The CLOAK-tech device is [s_active?"active":"inactive"]." - else - user << "KAMIKAZE MODE ENGAGED!" - user << "There are [s_bombs] smoke bomb\s remaining." - user << "There are [a_boost] adrenaline booster\s remaining." - else - user << "�rr�R �a��a�� No-�-� f��N� 3RR�r" - -/* -=================================================================================== -<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -=================================================================================== -*/ - -//=======//ENERGY DRAIN PROCS//=======// - -/obj/item/clothing/gloves/space_ninja/proc/drain(target_type as text, target, obj/suit) -//Var Initialize - var/obj/item/clothing/suit/space/space_ninja/S = suit - var/mob/living/carbon/human/U = S.affecting - var/obj/item/clothing/gloves/space_ninja/G = S.n_gloves - - var/drain = 0//To drain from battery. - var/maxcapacity = 0//Safety check for full battery. - var/totaldrain = 0//Total energy drained. - - G.draining = 1 - - if(target_type!="RESEARCH")//I lumped research downloading here for ease of use. - U << "Now charging battery..." - - switch(target_type) - - if("APC") - var/obj/machinery/power/apc/A = target - if(A.cell&&A.cell.charge) - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, A.loc) - while(G.candrain&&A.cell.charge>0&&!maxcapacity) - drain = rand(G.mindrain,G.maxdrain) - if(A.cell.chargeS.cell.maxcharge) - drain = S.cell.maxcharge-S.cell.charge - maxcapacity = 1//Reached maximum battery capacity. - if (do_after(U,10)) - spark_system.start() - playsound(A.loc, "sparks", 50, 1) - A.cell.charge-=drain - S.cell.charge+=drain - totaldrain+=drain - else break - U << "Gained [totaldrain] energy from the APC." - if(!A.emagged) - flick("apc-spark", src) - A.emagged = 1 - A.locked = 0 - A.update_icon() - else - U << "This APC has run dry of power. You must find another source." - - if("SMES") - var/obj/machinery/power/smes/A = target - if(A.charge) - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, A.loc) - while(G.candrain&&A.charge>0&&!maxcapacity) - drain = rand(G.mindrain,G.maxdrain) - if(A.chargeS.cell.maxcharge) - drain = S.cell.maxcharge-S.cell.charge - maxcapacity = 1 - if (do_after(U,10)) - spark_system.start() - playsound(A.loc, "sparks", 50, 1) - A.charge-=drain - S.cell.charge+=drain - totaldrain+=drain - else break - U << "Gained [totaldrain] energy from the SMES cell." - else - U << "This SMES cell has run dry of power. You must find another source." - - if("CELL") - var/obj/item/weapon/stock_parts/cell/A = target - if(A.charge) - if (G.candrain&&do_after(U,30)) - U << "Gained [A.charge] energy from the cell." - if(S.cell.charge+A.charge>S.cell.maxcharge) - S.cell.charge=S.cell.maxcharge - else - S.cell.charge+=A.charge - A.charge = 0 - G.draining = 0 - A.corrupt() - A.updateicon() - else - U << "Procedure interrupted. Protocol terminated." - else - U << "This cell is empty and of no use." - - if("MACHINERY")//Can be applied to generically to all powered machinery. I'm leaving this alone for now. - var/obj/machinery/A = target - if(A.powered())//If powered. - - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, A.loc) - - var/obj/machinery/power/apc/B = A.loc.loc:get_apc()//Object.turf.area find APC - if(B)//If APC exists. Might not if the area is unpowered like Centcom. - var/datum/powernet/PN = B.terminal.powernet - while(G.candrain&&!maxcapacity&&!isnull(A))//And start a proc similar to drain from wire. - drain = rand(G.mindrain,G.maxdrain) - var/drained = 0 - if(PN&&do_after(U,10)) - drained = min(drain, PN.avail) - PN.load += drained - if(drained < drain)//if no power on net, drain apcs - for(var/obj/machinery/power/terminal/T in PN.nodes) - if(istype(T.master, /obj/machinery/power/apc)) - var/obj/machinery/power/apc/AP = T.master - if(AP.operating && AP.cell && AP.cell.charge>0) - AP.cell.charge = max(0, AP.cell.charge - 5) - drained += 5 - else break - S.cell.charge += drained - if(S.cell.charge>S.cell.maxcharge) - totaldrain += (drained-(S.cell.charge-S.cell.maxcharge)) - S.cell.charge = S.cell.maxcharge - maxcapacity = 1 - else - totaldrain += drained - spark_system.start() - if(drained==0) break - U << "Gained [totaldrain] energy from the power network." - else - U << "Power network could not be found. Aborting." - else - U << "This recharger is not providing energy. You must find another source." - - if("RESEARCH") - var/obj/machinery/A = target - U << "Hacking \the [A]..." - spawn(0) - var/turf/location = get_turf(U) - for(var/mob/living/silicon/ai/AI in player_list) - AI << "Network Alert: Hacking attempt detected[location?" in [location]":". Unable to pinpoint location"]." - if(A:files&&A:files.known_tech.len) - for(var/datum/tech/current_data in S.stored_research) - U << "Checking \the [current_data.name] database." - if(do_after(U, S.s_delay)&&G.candrain&&!isnull(A)) - for(var/datum/tech/analyzing_data in A:files.known_tech) - if(current_data.id==analyzing_data.id) - if(analyzing_data.level>current_data.level) - U << "Database: UPDATED." - current_data.level = analyzing_data.level - break//Move on to next. - else break//Otherwise, quit processing. - U << "Data analyzed. Process finished." - - if("WIRE") - var/obj/structure/cable/A = target - var/datum/powernet/PN = A.powernet - while(G.candrain&&!maxcapacity&&!isnull(A)) - drain = (round((rand(G.mindrain,G.maxdrain))/2)) - var/drained = 0 - if(PN&&do_after(U,10)) - drained = min(drain, PN.avail) - PN.load += drained - if(drained < drain)//if no power on net, drain apcs - for(var/obj/machinery/power/terminal/T in PN.nodes) - if(istype(T.master, /obj/machinery/power/apc)) - var/obj/machinery/power/apc/AP = T.master - if(AP.operating && AP.cell && AP.cell.charge>0) - AP.cell.charge = max(0, AP.cell.charge - 5) - drained += 5 - else break - S.cell.charge += drained - if(S.cell.charge>S.cell.maxcharge) - totaldrain += (drained-(S.cell.charge-S.cell.maxcharge)) - S.cell.charge = S.cell.maxcharge - maxcapacity = 1 - else - totaldrain += drained - S.spark_system.start() - if(drained==0) break - U << "Gained [totaldrain] energy from the power network." - - if("MECHA") - var/obj/mecha/A = target - A.occupant_message("Warning: Unauthorized access through sub-route 4, block H, detected.") - if(A.get_charge()) - while(G.candrain&&A.cell.charge>0&&!maxcapacity) - drain = rand(G.mindrain,G.maxdrain) - if(A.cell.chargeS.cell.maxcharge) - drain = S.cell.maxcharge-S.cell.charge - maxcapacity = 1 - if (do_after(U,10)) - A.spark_system.start() - playsound(A.loc, "sparks", 50, 1) - A.cell.use(drain) - S.cell.charge+=drain - totaldrain+=drain - else break - U << "Gained [totaldrain] energy from [src]." - else - U << "The exosuit's battery has run dry. You must find another source of power." - - if("CYBORG") - var/mob/living/silicon/robot/A = target - A << "Warning: Unauthorized access through sub-route 12, block C, detected." - G.draining = 1 - if(A.cell&&A.cell.charge) - while(G.candrain&&A.cell.charge>0&&!maxcapacity) - drain = rand(G.mindrain,G.maxdrain) - if(A.cell.chargeS.cell.maxcharge) - drain = S.cell.maxcharge-S.cell.charge - maxcapacity = 1 - if (do_after(U,10)) - A.spark_system.start() - playsound(A.loc, "sparks", 50, 1) - A.cell.charge-=drain - S.cell.charge+=drain - totaldrain+=drain - else break - U << "Gained [totaldrain] energy from [A]." - else - U << "Their battery has run dry of power. You must find another source." - - else//Else nothing :< - - G.draining = 0 - - return - -//=======//GENERAL PROCS//=======// - -/obj/item/clothing/gloves/space_ninja/proc/toggled() - set name = "Toggle Interaction" - set desc = "Toggles special interaction on or off." - set category = "Ninja Equip" - - var/mob/living/carbon/human/U = loc - U << "You [candrain?"disable":"enable"] special interaction." - candrain=!candrain - -/obj/item/clothing/gloves/space_ninja/examine(mob/user) - ..() - if(flags & NODROP) - user << "The energy drain mechanism is: [candrain?"active":"inactive"]." - -/* -=================================================================================== -<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -=================================================================================== -*/ - -/obj/item/clothing/mask/gas/voice/space_ninja/New() - verbs += /obj/item/clothing/mask/gas/voice/space_ninja/proc/togglev - -//This proc is linked to human life.dm. It determines what hud icons to display based on mind special role for most mobs. -/obj/item/clothing/mask/gas/voice/space_ninja/proc/assess_targets(list/target_list, mob/living/carbon/U) - var/icon/tempHud = 'icons/mob/hud.dmi' - for(var/mob/living/target in target_list) - if(iscarbon(target)) - switch(target.mind.special_role) - if("traitor") - U.client.images += image(tempHud,target,"hudtraitor") - if("Revolutionary","Head Revolutionary") - U.client.images += image(tempHud,target,"hudrevolutionary") - if("Cultist") - U.client.images += image(tempHud,target,"hudcultist") - if("Changeling") - U.client.images += image(tempHud,target,"hudchangeling") - if("Wizard","Fake Wizard") - U.client.images += image(tempHud,target,"hudwizard") - if("Hunter","Sentinel","Drone","Queen") - U.client.images += image(tempHud,target,"hudalien") - if("Syndicate") - U.client.images += image(tempHud,target,"hudoperative") - if("Death Commando") - U.client.images += image(tempHud,target,"huddeathsquad") - if("Space Ninja") - U.client.images += image(tempHud,target,"hudninja") - else//If we don't know what role they have but they have one. - U.client.images += image(tempHud,target,"hudunknown1") - else if(issilicon(target))//If the silicon mob has no law datum, no inherent laws, or a law zero, add them to the hud. - var/mob/living/silicon/silicon_target = target - if(!silicon_target.laws||(silicon_target.laws&&(silicon_target.laws.zeroth||!silicon_target.laws.inherent.len))) - if(isrobot(silicon_target))//Different icons for robutts and AI. - U.client.images += image(tempHud,silicon_target,"hudmalborg") - else - U.client.images += image(tempHud,silicon_target,"hudmalai") - return 1 - -/obj/item/clothing/mask/gas/voice/space_ninja/proc/togglev() - set name = "Toggle Voice" - set desc = "Toggles the voice synthesizer on or off." - set category = "Ninja Equip" - - var/mob/U = loc//Can't toggle voice when you're not wearing the mask. - var/vchange = (alert("Would you like to synthesize a new name or turn off the voice synthesizer?",,"New Name","Turn Off")) - if(vchange=="New Name") - var/chance = rand(1,100) - switch(chance) - if(1 to 50)//High chance of a regular name. - voice = "[rand(0,1)==1?pick(first_names_female):pick(first_names_male)] [pick(last_names)]" - if(51 to 80)//Smaller chance of a clown name. - voice = "[pick(clown_names)]" - if(81 to 90)//Small chance of a wizard name. - voice = "[pick(wizard_first)] [pick(wizard_second)]" - if(91 to 100)//Small chance of an existing crew name. - var/names[] = new() - for(var/mob/living/carbon/human/M in player_list) - if(M==U||!M.client||!M.real_name) continue - names.Add(M.real_name) - voice = !names.len ? "Cuban Pete" : pick(names) - U << "You are now mimicking [voice]." - else - U << "The voice synthesizer is [voice!="Unknown"?"now":"already"] deactivated." - voice = "Unknown" - return - -/obj/item/clothing/mask/gas/voice/space_ninja/examine(mob/user) - ..() - user << "Voice mimicking algorithm is set [!vchange?"inactive":"active"]." - -/* -=================================================================================== -<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -=================================================================================== -*/ - -/* -It will teleport people to a holding facility after 30 seconds. (Check the process() proc to change where teleport goes) -It is possible to destroy the net by the occupant or someone else. -*/ - -/obj/effect/energy_net - name = "energy net" - desc = "It's a net made of green energy." - icon = 'icons/effects/effects.dmi' - icon_state = "energynet" - - density = 1//Can't pass through. - opacity = 0//Can see through. - mouse_opacity = 1//So you can hit it with stuff. - anchored = 1//Can't drag/grab the trapped mob. - - var/health = 25//How much health it has. - var/mob/living/affecting = null//Who it is currently affecting, if anyone. - var/mob/living/master = null//Who shot web. Will let this person know if the net was successful or failed. - -/obj/effect/energy_net/proc/healthcheck() - if(health <=0) - density = 0 - if(affecting) - var/mob/living/carbon/M = affecting - M.anchored = 0 - for(var/mob/O in viewers(src, 3)) - O.show_message("[M.name] was recovered from the energy net!", 1, "You hear a grunt.", 2) - if(!isnull(master))//As long as they still exist. - master << "ERROR: unable to initiate transport protocol. Procedure terminated." - qdel(src) - return - -/obj/effect/energy_net/process(var/mob/living/carbon/M as mob) - var/check = 30//30 seconds before teleportation. Could be extended I guess. - var/mob_name = affecting.name//Since they will report as null if terminated before teleport. - //The person can still try and attack the net when inside. - while(!isnull(M)&&!isnull(src)&&check>0)//While M and net exist, and 30 seconds have not passed. - check-- - sleep(10) - - if(isnull(M)||M.loc!=loc)//If mob is gone or not at the location. - if(!isnull(master))//As long as they still exist. - master << "ERROR: unable to locate \the [mob_name]. Procedure terminated." - qdel(src)//Get rid of the net. - return - - if(!isnull(src))//As long as both net and person exist. - //No need to check for countdown here since while() broke, it's implicit that it finished. - - density = 0//Make the net pass-through. - invisibility = 101//Make the net invisible so all the animations can play out. - health = INFINITY//Make the net invincible so that an explosion/something else won't kill it while, spawn() is running. - for(var/obj/item/W in M) - if(istype(M,/mob/living/carbon/human)) - if(W==M:w_uniform) continue//So all they're left with are shoes and uniform. - if(W==M:shoes) continue - M.unEquip(W) - - spawn(0) - playsound(M.loc, 'sound/effects/sparks4.ogg', 50, 1) - anim(M.loc,M,'icons/mob/mob.dmi',,"phaseout",,M.dir) - - M.loc = pick(holdingfacility)//Throw mob in to the holding facility. - M << "You appear in a strange place!" - - spawn(0) - var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() - spark_system.set_up(5, 0, M.loc) - spark_system.start() - playsound(M.loc, 'sound/effects/phasein.ogg', 25, 1) - playsound(M.loc, 'sound/effects/sparks2.ogg', 50, 1) - anim(M.loc,M,'icons/mob/mob.dmi',,"phasein",,M.dir) - qdel(src)//Wait for everything to finish, delete the net. Else it will stop everything once net is deleted, including the spawn(0). - - for(var/mob/O in viewers(src, 3)) - O.show_message("[M] vanished!", 1, "You hear sparks flying!", 2) - - if(!isnull(master))//As long as they still exist. - master << "SUCCESS: transport procedure of \the [affecting] complete." - - M.anchored = 0//Important. - - else//And they are free. - M << "You are free of the net!" - return - -/obj/effect/energy_net/bullet_act(var/obj/item/projectile/Proj) - health -= Proj.damage - healthcheck() - ..() - -/obj/effect/energy_net/ex_act(severity, target) - switch(severity) - if(1.0) - health-=50 - if(2.0) - health-=50 - if(3.0) - health-=prob(50)?50:25 - healthcheck() - return - -/obj/effect/energy_net/blob_act() - health-=50 - healthcheck() - return - -/obj/effect/energy_net/hitby(AM as mob|obj) - ..() - visible_message("[src] was hit by [AM].") - var/tforce = 0 - if(ismob(AM)) - tforce = 10 - else - tforce = AM:throwforce - playsound(src.loc, 'sound/weapons/slash.ogg', 80, 1) - health = max(0, health - tforce) - healthcheck() - ..() - return - -/obj/effect/energy_net/attack_hulk(mob/living/carbon/human/user) - ..(user, 1) - user.visible_message("[user] rips the energy net apart!", \ - "You easily destroy the energy net.") - health-=50 - healthcheck() - -/obj/effect/energy_net/attack_paw(mob/user) - return attack_hand() - -/obj/effect/energy_net/attack_alien(mob/living/user as mob) - user.do_attack_animation(src) - if (islarva(user)) - return - playsound(src.loc, 'sound/weapons/slash.ogg', 80, 1) - health -= rand(10, 20) - if(health > 0) - user.visible_message("[user] claws at the energy net!", \ - "\green You claw at the net.") - else - user.visible_message("[user] slices the energy net apart!", \ - "\green You slice the energy net to pieces.") - healthcheck() - return - -/obj/effect/energy_net/attackby(obj/item/weapon/W as obj, mob/user as mob, params) - var/aforce = W.force - health = max(0, health - aforce) - healthcheck() - ..() - return - -proc/create_ninja_mind(key) - var/datum/mind/Mind = new /datum/mind(key) - Mind.assigned_role = "MODE" - Mind.special_role = "Space Ninja" - ticker.mode.traitors |= Mind //Adds them to current traitor list. Which is really the extra antagonist list. - return Mind diff --git a/code/modules/events/vent_clog.dm b/code/modules/events/vent_clog.dm index 037b2f4101f..7703be7fc73 100644 --- a/code/modules/events/vent_clog.dm +++ b/code/modules/events/vent_clog.dm @@ -37,4 +37,4 @@ smoke.set_up(R, rand(1, 2), 0, vent, 0, silent = 1) playsound(vent.loc, 'sound/effects/smoke.ogg', 50, 1, -3) smoke.start() - R.delete() //GC the reagents \ No newline at end of file + qdel(R) \ No newline at end of file diff --git a/code/modules/events/wizard/departmentrevolt.dm b/code/modules/events/wizard/departmentrevolt.dm index 59707297095..0408f97169a 100644 --- a/code/modules/events/wizard/departmentrevolt.dm +++ b/code/modules/events/wizard/departmentrevolt.dm @@ -1,6 +1,6 @@ /datum/round_event_control/wizard/deprevolt //stationwide! name = "Departmental Uprising" - weight = 2 + weight = 0 //An order that requires order in a round of chaos was maybe not the best idea. Requiescat in pace departmental uprising August 2014 - March 2015 typepath = /datum/round_event/wizard/deprevolt/ max_occurrences = 1 earliest_start = 0 diff --git a/code/modules/events/wizard/imposter.dm b/code/modules/events/wizard/imposter.dm index 1a55876b8e8..e3b4c5d1fb6 100644 --- a/code/modules/events/wizard/imposter.dm +++ b/code/modules/events/wizard/imposter.dm @@ -14,7 +14,7 @@ if(!candidates) return //Sad Trombone var/client/C = pick(candidates) - new /obj/effect/effect/harmless_smoke(W.loc) + PoolOrNew(/obj/effect/effect/harmless_smoke, W.loc) var/mob/living/carbon/human/I = new /mob/living/carbon/human(W.loc) I.real_name = W.real_name diff --git a/code/modules/events/wizard/summons.dm b/code/modules/events/wizard/summons.dm index afe85bad448..7b3e27e16c6 100644 --- a/code/modules/events/wizard/summons.dm +++ b/code/modules/events/wizard/summons.dm @@ -5,6 +5,11 @@ max_occurrences = 1 earliest_start = 0 +/datum/round_event_control/wizard/summonguns/New() + if(config.no_summon_guns) + weight = 0 + ..() + /datum/round_event/wizard/summonguns/start() rightandwrong(0,,10) @@ -15,5 +20,10 @@ max_occurrences = 1 earliest_start = 0 +/datum/round_event_control/wizard/summonmagic/New() + if(config.no_summon_magic) + weight = 0 + ..() + /datum/round_event/wizard/summonmagic/start() rightandwrong(1,,10) \ No newline at end of file diff --git a/code/modules/food&drinks/drinks/drinks/bottle.dm b/code/modules/food&drinks/drinks/drinks/bottle.dm index 5c0bdec3e23..5cdfcd67a2c 100644 --- a/code/modules/food&drinks/drinks/drinks/bottle.dm +++ b/code/modules/food&drinks/drinks/drinks/bottle.dm @@ -92,8 +92,8 @@ target.visible_message("[user] has hit [target][head_attack_message] with a bottle of [src.name]!", \ "[user] has hit [target][head_attack_message] with a bottle of [src.name]!") else - user.visible_message("[target] hits himself with a bottle of [src.name][head_attack_message]!", \ - "[target] hits himself with a bottle of [src.name][head_attack_message]!") + user.visible_message("[target] hits \himself with a bottle of [src.name][head_attack_message]!", \ + "[target] hits \himself with a bottle of [src.name][head_attack_message]!") //Attack logs add_logs(user, target, "attacked", object="bottle") diff --git a/code/modules/food&drinks/food/customizables.dm b/code/modules/food&drinks/food/customizables.dm index 46c1f0dace6..627a3b58b80 100644 --- a/code/modules/food&drinks/food/customizables.dm +++ b/code/modules/food&drinks/food/customizables.dm @@ -15,6 +15,7 @@ /obj/item/weapon/reagent_containers/food/snacks/customizable bitesize = 4 w_class = 3 + volume = 60 var/ingMax = 12 var/list/ingredients = list() @@ -67,9 +68,8 @@ return name = "[customname] [initial(name)]" - else . = ..() - return + /obj/item/weapon/reagent_containers/food/snacks/customizable/proc/update_name(obj/item/weapon/reagent_containers/food/snacks/S) for(var/obj/item/I in ingredients) @@ -109,12 +109,14 @@ I.pixel_x = rand(-1,1) I.pixel_y = rand(-1,1) if(INGREDIENTS_STACK) - I.pixel_y = ingredients.len + I.pixel_x = rand(-1,1) + I.pixel_y = 2 * ingredients.len - 1 if(INGREDIENTS_STACKPLUSTOP) - I.pixel_y = ingredients.len + I.pixel_x = rand(-1,1) + I.pixel_y = 2 * ingredients.len - 1 overlays.Cut(ingredients.len) var/image/TOP = new(icon, "[icon_state]_top") - TOP.pixel_y = ingredients.len + 4 + TOP.pixel_y = 2 * ingredients.len + 3 overlays += I overlays += TOP return @@ -127,7 +129,8 @@ overlays += I -/obj/item/weapon/reagent_containers/food/snacks/customizable/initialize_slice(obj/item/weapon/reagent_containers/food/snacks/slice) +/obj/item/weapon/reagent_containers/food/snacks/customizable/initialize_slice(obj/item/weapon/reagent_containers/food/snacks/slice, reagents_per_slice) + ..() slice.name = "[customname] [initial(slice.name)]" slice.filling_color = filling_color slice.update_overlays(src) @@ -233,12 +236,12 @@ BS.reagents.trans_to(src, BS.reagents.total_volume) ingMax = ingredients.len //can't add more ingredients after that var/image/TOP = new(icon, "[BS.icon_state]") - TOP.pixel_y = ingredients.len + 4 + TOP.pixel_y = 2 * ingredients.len + 3 overlays += TOP if(istype(BS, /obj/item/weapon/reagent_containers/food/snacks/breadslice/custom)) var/image/O = new(icon, "[initial(BS.icon_state)]_filling") O.color = BS.filling_color - O.pixel_y = ingredients.len + 4 + O.pixel_y = 2 * ingredients.len + 3 overlays += O qdel(BS) return diff --git a/code/modules/food&drinks/food/snacks.dm b/code/modules/food&drinks/food/snacks.dm index fc0b9137e77..3199cde393a 100644 --- a/code/modules/food&drinks/food/snacks.dm +++ b/code/modules/food&drinks/food/snacks.dm @@ -17,6 +17,7 @@ var/filling_color = "#FFFFFF" //color to use when added to custom food. var/custom_food_type = null //for food customizing. path of the custom food to create var/junkiness = 0 //for junk food. used to lower human satiety. + var/list/bonus_reagents = list() //the amount of reagents (usually nutriment and vitamin) added to crafted/cooked snacks, on top of the ingredients reagents. //Placeholder for effect that trigger on eating that aren't tied to reagents. @@ -50,7 +51,7 @@ M.unEquip(src) //so icons update :[ qdel(src) return 0 - if(istype(M, /mob/living/carbon)) + if(iscarbon(M)) if(!canconsume(M, user)) return 0 @@ -78,7 +79,7 @@ M << "You cannot force any more of \the [src] to go down your throat." return 0 else - if(! (isslime(M) || isbrain(M)) ) //If you're feeding it to someone else. + if(!isbrain(M)) //If you're feeding it to someone else. if(wrapped) return 0 if(fullness <= (600 * (1 + M.overeatduration / 1000))) @@ -154,6 +155,12 @@ if(slice(sharpness, W, user)) return 1 +//Called when you finish tablecrafting a snack. +/obj/item/weapon/reagent_containers/food/snacks/CheckParts() + if(bonus_reagents.len) + for(var/r_id in bonus_reagents) + var/amount = bonus_reagents[r_id] + reagents.add_reagent(r_id, amount) /obj/item/weapon/reagent_containers/food/snacks/proc/slice(var/accuracy, obj/item/weapon/W, mob/user) if((slices_num <= 0 || !slices_num) || !slice_path) //is the food sliceable? @@ -186,11 +193,12 @@ var/reagents_per_slice = reagents.total_volume/slices_num for(var/i=1 to (slices_num-slices_lost)) var/obj/item/weapon/reagent_containers/food/snacks/slice = new slice_path (loc) - initialize_slice(slice) - reagents.trans_to(slice,reagents_per_slice) + initialize_slice(slice, reagents_per_slice) qdel(src) -/obj/item/weapon/reagent_containers/food/snacks/proc/initialize_slice(obj/item/weapon/reagent_containers/food/snacks/slice) +/obj/item/weapon/reagent_containers/food/snacks/proc/initialize_slice(obj/item/weapon/reagent_containers/food/snacks/slice, reagents_per_slice) + slice.create_reagents(slice.volume) + reagents.trans_to(slice,reagents_per_slice) return /obj/item/weapon/reagent_containers/food/snacks/proc/update_overlays(obj/item/weapon/reagent_containers/food/snacks/S) @@ -204,9 +212,14 @@ overlays += I // initialize_cooked_food() is called when microwaving the food -/obj/item/weapon/reagent_containers/food/snacks/proc/initialize_cooked_food(obj/item/weapon/reagent_containers/food/snacks/S) +/obj/item/weapon/reagent_containers/food/snacks/proc/initialize_cooked_food(obj/item/weapon/reagent_containers/food/snacks/S, cooking_efficiency = 1) + S.create_reagents(S.volume) if(reagents) reagents.trans_to(S, reagents.total_volume) + if(S.bonus_reagents.len) + for(var/r_id in S.bonus_reagents) + var/amount = S.bonus_reagents[r_id] * cooking_efficiency + S.reagents.add_reagent(r_id, amount) /obj/item/weapon/reagent_containers/food/snacks/Destroy() if(contents) diff --git a/code/modules/food&drinks/food/snacks/dough.dm b/code/modules/food&drinks/food/snacks/dough.dm index aca417a2473..d03339809cd 100644 --- a/code/modules/food&drinks/food/snacks/dough.dm +++ b/code/modules/food&drinks/food/snacks/dough.dm @@ -8,9 +8,8 @@ icon = 'icons/obj/food_ingredients.dmi' icon_state = "dough" cooked_type = /obj/item/weapon/reagent_containers/food/snacks/store/bread/plain - list_reagents = list("nutriment" = 3) + list_reagents = list("nutriment" = 6) w_class = 3 - flags = OPENCONTAINER // Dough + rolling pin = flat dough @@ -35,9 +34,8 @@ slice_path = /obj/item/weapon/reagent_containers/food/snacks/doughslice slices_num = 3 cooked_type = /obj/item/weapon/reagent_containers/food/snacks/pizzabread - list_reagents = list("nutriment" = 3) + list_reagents = list("nutriment" = 6) w_class = 3 - flags = OPENCONTAINER /obj/item/weapon/reagent_containers/food/snacks/pizzabread name = "pizza bread" @@ -56,7 +54,6 @@ icon_state = "doughslice" cooked_type = /obj/item/weapon/reagent_containers/food/snacks/bun filling_color = "#CD853F" - flags = OPENCONTAINER /obj/item/weapon/reagent_containers/food/snacks/bun @@ -74,7 +71,7 @@ icon = 'icons/obj/food_ingredients.dmi' icon_state = "cakebatter" cooked_type = /obj/item/weapon/reagent_containers/food/snacks/store/cake/plain - list_reagents = list("nutriment" = 3) + list_reagents = list("nutriment" = 9) w_class = 3 // Cake batter + rolling pin = pie dough @@ -97,7 +94,7 @@ slice_path = /obj/item/weapon/reagent_containers/food/snacks/rawpastrybase slices_num = 3 cooked_type = /obj/item/weapon/reagent_containers/food/snacks/pie/plain - list_reagents = list("nutriment" = 3) + list_reagents = list("nutriment" = 9) w_class = 3 /obj/item/weapon/reagent_containers/food/snacks/rawpastrybase diff --git a/code/modules/food&drinks/food/snacks/meat.dm b/code/modules/food&drinks/food/snacks/meat.dm index 14634bb1f9d..7fe20242799 100644 --- a/code/modules/food&drinks/food/snacks/meat.dm +++ b/code/modules/food&drinks/food/snacks/meat.dm @@ -10,7 +10,8 @@ slices_num = 3 filling_color = "#FF0000" -/obj/item/weapon/reagent_containers/food/snacks/meat/initialize_slice(obj/item/weapon/reagent_containers/food/snacks/rawcutlet/slice) +/obj/item/weapon/reagent_containers/food/snacks/meat/initialize_slice(obj/item/weapon/reagent_containers/food/snacks/rawcutlet/slice, reagents_per_slice) + ..() var/image/I = new(icon, "rawcutlet_coloration") I.color = filling_color slice.overlays += I @@ -18,7 +19,7 @@ slice.name = "raw [name] cutlet" slice.meat_type = name -/obj/item/weapon/reagent_containers/food/snacks/meat/initialize_cooked_food(obj/item/weapon/reagent_containers/food/snacks/S) +/obj/item/weapon/reagent_containers/food/snacks/meat/initialize_cooked_food(obj/item/weapon/reagent_containers/food/snacks/S, cooking_efficiency) ..() S.name = "[name] steak" @@ -32,7 +33,7 @@ cooked_type = /obj/item/weapon/reagent_containers/food/snacks/meatsteak/plain/human slice_path = /obj/item/weapon/reagent_containers/food/snacks/rawcutlet/plain/human -/obj/item/weapon/reagent_containers/food/snacks/meat/human/initialize_slice(obj/item/weapon/reagent_containers/food/snacks/rawcutlet/plain/human/slice) +/obj/item/weapon/reagent_containers/food/snacks/meat/human/initialize_slice(obj/item/weapon/reagent_containers/food/snacks/rawcutlet/plain/human/slice, reagents_per_slice) ..() if(subjectname) slice.subjectname = subjectname @@ -41,7 +42,7 @@ slice.subjectjob = subjectjob slice.name = "raw [subjectjob] cutlet" -/obj/item/weapon/reagent_containers/food/snacks/meat/human/initialize_cooked_food(obj/item/weapon/reagent_containers/food/snacks/S) +/obj/item/weapon/reagent_containers/food/snacks/meat/human/initialize_cooked_food(obj/item/weapon/reagent_containers/food/snacks/S, cooking_efficiency) ..() if(subjectname) S.name = "[subjectname] meatsteak" @@ -170,7 +171,8 @@ name = "steak" desc = "A piece of hot spicy meat." icon_state = "meatsteak" - list_reagents = list("nutriment" = 2, "vitamin" = 1) + list_reagents = list("nutriment" = 5) + bonus_reagents = list("nutriment" = 2, "vitamin" = 1) trash = /obj/item/trash/plate filling_color = "#B22222" @@ -198,10 +200,11 @@ icon_state = "rawcutlet" cooked_type = /obj/item/weapon/reagent_containers/food/snacks/cutlet/plain bitesize = 2 + list_reagents = list("nutriment" = 1) filling_color = "#B22222" var/meat_type = "meat" -/obj/item/weapon/reagent_containers/food/snacks/rawcutlet/initialize_cooked_food(obj/item/weapon/reagent_containers/food/snacks/S) +/obj/item/weapon/reagent_containers/food/snacks/rawcutlet/initialize_cooked_food(obj/item/weapon/reagent_containers/food/snacks/S, cooking_efficiency) ..() S.name = "[meat_type] cutlet" @@ -213,7 +216,7 @@ var/subjectname = "" var/subjectjob = null -/obj/item/weapon/reagent_containers/food/snacks/rawcutlet/plain/human/initialize_cooked_food(obj/item/weapon/reagent_containers/food/snacks/S) +/obj/item/weapon/reagent_containers/food/snacks/rawcutlet/plain/human/initialize_cooked_food(obj/item/weapon/reagent_containers/food/snacks/S, cooking_efficiency) ..() if(subjectname) S.name = "[subjectname] [initial(S.name)]" @@ -236,7 +239,8 @@ desc = "A cooked meat cutlet." icon_state = "cutlet" bitesize = 2 - list_reagents = list("nutriment" = 1, "vitamin" = 1) + list_reagents = list("nutriment" = 2) + bonus_reagents = list("nutriment" = 1, "vitamin" = 1) filling_color = "#B22222" /obj/item/weapon/reagent_containers/food/snacks/cutlet/plain diff --git a/code/modules/food&drinks/food/snacks_bread.dm b/code/modules/food&drinks/food/snacks_bread.dm index 5fc55b66394..694ed000946 100644 --- a/code/modules/food&drinks/food/snacks_bread.dm +++ b/code/modules/food&drinks/food/snacks_bread.dm @@ -13,7 +13,8 @@ name = "bread" desc = "Some plain old Earthen bread." icon_state = "bread" - list_reagents = list("nutriment" = 7) + bonus_reagents = list("nutriment" = 7) + list_reagents = list("nutriment" = 10) custom_food_type = /obj/item/weapon/reagent_containers/food/snacks/customizable/bread slice_path = /obj/item/weapon/reagent_containers/food/snacks/breadslice/plain @@ -27,7 +28,8 @@ desc = "The culinary base of every self-respecting eloquen/tg/entleman." icon_state = "meatbread" slice_path = /obj/item/weapon/reagent_containers/food/snacks/breadslice/meat - list_reagents = list("nutriment" = 5, "vitamin" = 10) + bonus_reagents = list("nutriment" = 5, "vitamin" = 10) + list_reagents = list("nutriment" = 30, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/breadslice/meat name = "meatbread slice" @@ -39,33 +41,38 @@ desc = "The culinary base of every self-respecting eloquen/tg/entleman. Extra Heretical." icon_state = "xenomeatbread" slice_path = /obj/item/weapon/reagent_containers/food/snacks/breadslice/xenomeat - list_reagents = list("nutriment" = 5, "vitamin" = 10) + bonus_reagents = list("nutriment" = 5, "vitamin" = 10) + list_reagents = list("nutriment" = 30, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/breadslice/xenomeat name = "xenomeatbread slice" desc = "A slice of delicious meatbread. Extra Heretical." icon_state = "xenobreadslice" filling_color = "#32CD32" + list_reagents = list("nutriment" = 6, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/store/bread/spidermeat name = "spider meat loaf" desc = "Reassuringly green meatloaf made from spider meat." icon_state = "spidermeatbread" slice_path = /obj/item/weapon/reagent_containers/food/snacks/breadslice/spidermeat - list_reagents = list("nutriment" = 5, "vitamin" = 10) + bonus_reagents = list("nutriment" = 5, "vitamin" = 10) + list_reagents = list("nutriment" = 30, "toxin" = 15, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/breadslice/spidermeat name = "spider meat bread slice" desc = "A slice of meatloaf made from an animal that most likely still wants you dead." icon_state = "xenobreadslice" filling_color = "#7CFC00" + list_reagents = list("nutriment" = 6, "toxin" = 3, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/store/bread/banana name = "banana-nut bread" desc = "A heavenly and filling treat." icon_state = "bananabread" slice_path = /obj/item/weapon/reagent_containers/food/snacks/breadslice/banana - list_reagents = list("nutriment" = 5, "banana" = 20) + bonus_reagents = list("nutriment" = 5, "banana" = 20) + list_reagents = list("nutriment" = 20, "banana" = 20) /obj/item/weapon/reagent_containers/food/snacks/breadslice/banana @@ -73,32 +80,37 @@ desc = "A slice of delicious banana bread." icon_state = "bananabreadslice" filling_color = "#FFD700" + list_reagents = list("nutriment" = 4, "banana" = 4) /obj/item/weapon/reagent_containers/food/snacks/store/bread/tofu name = "Tofubread" desc = "Like meatbread but for vegetarians. Not guaranteed to give superpowers." icon_state = "tofubread" slice_path = /obj/item/weapon/reagent_containers/food/snacks/breadslice/tofu - list_reagents = list("nutriment" = 5, "vitamin" = 10) + bonus_reagents = list("nutriment" = 5, "vitamin" = 10) + list_reagents = list("nutriment" = 20, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/breadslice/tofu name = "tofubread slice" desc = "A slice of delicious tofubread." icon_state = "tofubreadslice" filling_color = "#FF8C00" + list_reagents = list("nutriment" = 4, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/store/bread/creamcheese name = "cream cheese bread" desc = "Yum yum yum!" icon_state = "creamcheesebread" slice_path = /obj/item/weapon/reagent_containers/food/snacks/breadslice/creamcheese - list_reagents = list("nutriment" = 5, "vitamin" = 5) + bonus_reagents = list("nutriment" = 5, "vitamin" = 5) + list_reagents = list("nutriment" = 20, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/breadslice/creamcheese name = "cream cheese bread slice" desc = "A slice of yum!" icon_state = "creamcheesebreadslice" filling_color = "#FF8C00" + list_reagents = list("nutriment" = 4, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/breadslice/custom name = "bread slice" @@ -109,6 +121,7 @@ name = "baguette" desc = "Bon appetit!" icon_state = "baguette" - list_reagents = list("nutriment" = 2, "vitamin" = 2) + bonus_reagents = list("nutriment" = 2, "vitamin" = 2) + list_reagents = list("nutriment" = 6, "vitamin" = 1) bitesize = 3 w_class = 3 \ No newline at end of file diff --git a/code/modules/food&drinks/food/snacks_burgers.dm b/code/modules/food&drinks/food/snacks_burgers.dm index 83340dc3f14..9f77bfce846 100644 --- a/code/modules/food&drinks/food/snacks_burgers.dm +++ b/code/modules/food&drinks/food/snacks_burgers.dm @@ -2,134 +2,145 @@ /obj/item/weapon/reagent_containers/food/snacks/burger filling_color = "#CD853F" icon_state = "hburger" + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/burger/plain name = "burger" desc = "The cornerstone of every nutritious breakfast." - list_reagents = list("vitamin" = 1) - bitesize = 3 + bonus_reagents = list("vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/burger/human var/hname = "" var/job = null name = "-burger" desc = "A bloody burger." - list_reagents = list("vitamin" = 4) + bonus_reagents = list("vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/burger/appendix name = "appendix burger" desc = "Tastes like appendicitis." - list_reagents = list("nutriment" = 6, "vitamin" = 6) + bonus_reagents = list("nutriment" = 6, "vitamin" = 6) icon_state = "appendixburger" /obj/item/weapon/reagent_containers/food/snacks/burger/fish name = "fillet -o- carp sandwich" desc = "Almost like a carp is yelling somewhere... Give me back that fillet -o- carp, give me that carp." icon_state = "fishburger" - list_reagents = list("nutriment" = 2, "vitamin" = 3) + bonus_reagents = list("nutriment" = 2, "vitamin" = 3) /obj/item/weapon/reagent_containers/food/snacks/burger/tofu name = "tofu burger" desc = "What.. is that meat?" icon_state = "tofuburger" - list_reagents = list("nutriment" = 2, "vitamin" = 2) + bonus_reagents = list("nutriment" = 2, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/burger/roburger name = "roburger" desc = "The lettuce is the only organic component. Beep." icon_state = "roburger" - list_reagents = list("nutriment" = 2, "nanomachines" = 2, "vitamin" = 5) + bonus_reagents = list("nutriment" = 2, "nanomachines" = 2, "vitamin" = 5) + list_reagents = list("nutriment" = 6, "nanomachines" = 5, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/burger/roburgerbig name = "roburger" desc = "This massive patty looks like poison. Beep." icon_state = "roburger" volume = 120 - list_reagents = list("nutriment" = 5, "nanomachines" = 70, "vitamin" = 10) + bonus_reagents = list("nutriment" = 5, "nanomachines" = 70, "vitamin" = 10) + list_reagents = list("nutriment" = 6, "nanomachines" = 70, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/burger/xeno name = "xenoburger" desc = "Smells caustic. Tastes like heresy." icon_state = "xburger" - list_reagents = list("nutriment" = 2, "vitamin" = 6) + bonus_reagents = list("nutriment" = 2, "vitamin" = 6) + +/obj/item/weapon/reagent_containers/food/snacks/burger/bearger + name = "bearger" + desc = "Best served rawr." + icon_state = "bearger" + bonus_reagents = list("nutriment" = 3, "vitamin" = 6) /obj/item/weapon/reagent_containers/food/snacks/burger/clown name = "clown burger" desc = "This tastes funny..." icon_state = "clownburger" - list_reagents = list("nutriment" = 4, "vitamin" = 6, "banana" = 6) + bonus_reagents = list("nutriment" = 4, "vitamin" = 6, "banana" = 6) /obj/item/weapon/reagent_containers/food/snacks/burger/mime name = "mime burger" desc = "Its taste defies language." icon_state = "mimeburger" - list_reagents = list("nutriment" = 4, "vitamin" = 6, "nothing" = 6) + bonus_reagents = list("nutriment" = 4, "vitamin" = 6, "nothing" = 6) /obj/item/weapon/reagent_containers/food/snacks/burger/brain name = "brainburger" desc = "A strange looking burger. It looks almost sentient." icon_state = "brainburger" - list_reagents = list("nutriment" = 6, "mannitol" = 6, "vitamin" = 5) + bonus_reagents = list("nutriment" = 6, "mannitol" = 6, "vitamin" = 5) + list_reagents = list("nutriment" = 6, "mannitol" = 5, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/burger/ghost name = "ghost burger" desc = "Too Spooky!" alpha = 125 - list_reagents = list("nutriment" = 5, "vitamin" = 12) + bonus_reagents = list("nutriment" = 5, "vitamin" = 12) /obj/item/weapon/reagent_containers/food/snacks/burger/red name = "red burger" desc = "Perfect for hiding the fact it's burnt to a crisp." icon_state = "cburger" color = "#DA0000FF" - list_reagents = list("redcrayonpowder" = 10, "vitamin" = 5) + bonus_reagents = list("redcrayonpowder" = 10, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/burger/orange name = "orange burger" desc = "Contains 0% juice." icon_state = "cburger" color = "#FF9300FF" - list_reagents = list("orangecrayonpowder" = 10, "vitamin" = 5) + bonus_reagents = list("orangecrayonpowder" = 10, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/burger/yellow name = "yellow burger" desc = "Bright to the last bite." icon_state = "cburger" color = "#FFF200FF" - list_reagents = list("yellowcrayonpowder" = 10, "vitamin" = 5) + bonus_reagents = list("yellowcrayonpowder" = 10, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/burger/green name = "green burger" desc = "It's not tainted meat, it's painted meat!" icon_state = "cburger" color = "#A8E61DFF" - list_reagents = list("greencrayonpowder" = 10, "vitamin" = 5) + bonus_reagents = list("greencrayonpowder" = 10, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/burger/blue name = "blue burger" desc = "Is this blue rare?" icon_state = "cburger" color = "#00B7EFFF" - list_reagents = list("bluecrayonpowder" = 10, "vitamin" = 5) + bonus_reagents = list("bluecrayonpowder" = 10, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/burger/purple name = "purple burger" desc = "Regal and low class at the same time." icon_state = "cburger" color = "#DA00FFFF" - list_reagents = list("purplecrayonpowder" = 10, "vitamin" = 5) + bonus_reagents = list("purplecrayonpowder" = 10, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/burger/spell name = "spell burger" desc = "This is absolutely Ei Nath." icon_state = "spellburger" - list_reagents = list("nutriment" = 6, "vitamin" = 10) + bonus_reagents = list("nutriment" = 6, "vitamin" = 10) /obj/item/weapon/reagent_containers/food/snacks/burger/bigbite name = "big bite burger" desc = "Forget the Big Mac. THIS is the future!" icon_state = "bigbiteburger" - list_reagents = list("vitamin" = 6) + bonus_reagents = list("vitamin" = 6) + list_reagents = list("nutriment" = 10, "vitamin" = 2) w_class = 3 /obj/item/weapon/reagent_containers/food/snacks/burger/jelly @@ -138,15 +149,18 @@ icon_state = "jellyburger" /obj/item/weapon/reagent_containers/food/snacks/burger/jelly/slime - list_reagents = list("slimejelly" = 5, "vitamin" = 5) + bonus_reagents = list("slimejelly" = 5, "vitamin" = 5) + list_reagents = list("nutriment" = 6, "slimejelly" = 5, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/burger/jelly/cherry - list_reagents = list("cherryjelly" = 5, "vitamin" = 5) + bonus_reagents = list("cherryjelly" = 5, "vitamin" = 5) + list_reagents = list("nutriment" = 6, "cherryjelly" = 5, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/burger/superbite name = "super bite burger" desc = "This is a mountain of a burger. FOOD!" icon_state = "superbiteburger" - list_reagents = list("vitamin" = 10) + bonus_reagents = list("vitamin" = 10) + list_reagents = list("nutriment" = 40, "vitamin" = 5) w_class = 3 volume = 80 diff --git a/code/modules/food&drinks/food/snacks_cake.dm b/code/modules/food&drinks/food/snacks_cake.dm index d8a65be515b..f1ccae6255e 100644 --- a/code/modules/food&drinks/food/snacks_cake.dm +++ b/code/modules/food&drinks/food/snacks_cake.dm @@ -3,17 +3,18 @@ slice_path = /obj/item/weapon/reagent_containers/food/snacks/cakeslice/plain slices_num = 5 bitesize = 3 + list_reagents = list("nutriment" = 20, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/cakeslice trash = /obj/item/trash/plate - bitesize = 3 + list_reagents = list("nutriment" = 4, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/store/cake/plain name = "vanilla cake" desc = "A plain cake, not a lie." icon_state = "plaincake" custom_food_type = /obj/item/weapon/reagent_containers/food/snacks/customizable/cake - list_reagents = list("nutriment" = 10, "vitamin" = 2) + bonus_reagents = list("nutriment" = 10, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/cakeslice/plain name = "vanilla cake slice" @@ -27,13 +28,15 @@ icon_state = "carrotcake" slice_path = /obj/item/weapon/reagent_containers/food/snacks/cakeslice/carrot slices_num = 5 - list_reagents = list("nutriment" = 3, "oculine" = 5, "vitamin" = 10) + bonus_reagents = list("nutriment" = 3, "oculine" = 5, "vitamin" = 10) + list_reagents = list("nutriment" = 20, "oculine" = 10, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/cakeslice/carrot name = "carrot cake slice" desc = "Carrotty slice of Carrot Cake, carrots are good for your eyes! Also not a lie." icon_state = "carrotcake_slice" filling_color = "#FFA500" + list_reagents = list("nutriment" = 4, "oculine" = 2, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/store/cake/brain @@ -42,7 +45,8 @@ icon_state = "braincake" slice_path = /obj/item/weapon/reagent_containers/food/snacks/cakeslice/brain slices_num = 5 - list_reagents = list("nutriment" = 5, "mannitol" = 10, "vitamin" = 10) + bonus_reagents = list("nutriment" = 5, "mannitol" = 10, "vitamin" = 10) + list_reagents = list("nutriment" = 20, "mannitol" = 10, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/cakeslice/brain @@ -50,6 +54,7 @@ desc = "Lemme tell you something about prions. THEY'RE DELICIOUS." icon_state = "braincakeslice" filling_color = "#FF69B4" + list_reagents = list("nutriment" = 4, "mannitol" = 2, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/store/cake/cheese name = "cheese cake" @@ -57,7 +62,7 @@ icon_state = "cheesecake" slice_path = /obj/item/weapon/reagent_containers/food/snacks/cakeslice/cheese slices_num = 5 - list_reagents = list("vitamin" = 10) + bonus_reagents = list("vitamin" = 10) /obj/item/weapon/reagent_containers/food/snacks/cakeslice/cheese @@ -73,7 +78,7 @@ icon_state = "orangecake" slice_path = /obj/item/weapon/reagent_containers/food/snacks/cakeslice/orange slices_num = 5 - list_reagents = list("nutriment" = 3, "vitamin" = 10) + bonus_reagents = list("nutriment" = 3, "vitamin" = 10) /obj/item/weapon/reagent_containers/food/snacks/cakeslice/orange name = "orange cake slice" @@ -87,7 +92,7 @@ icon_state = "limecake" slice_path = /obj/item/weapon/reagent_containers/food/snacks/cakeslice/lime slices_num = 5 - list_reagents = list("nutriment" = 3, "vitamin" = 10) + bonus_reagents = list("nutriment" = 3, "vitamin" = 10) /obj/item/weapon/reagent_containers/food/snacks/cakeslice/lime name = "lime cake slice" @@ -102,7 +107,7 @@ icon_state = "lemoncake" slice_path = /obj/item/weapon/reagent_containers/food/snacks/cakeslice/lemon slices_num = 5 - list_reagents = list("nutriment" = 3, "vitamin" = 10) + bonus_reagents = list("nutriment" = 3, "vitamin" = 10) /obj/item/weapon/reagent_containers/food/snacks/cakeslice/lemon @@ -118,7 +123,7 @@ icon_state = "chocolatecake" slice_path = /obj/item/weapon/reagent_containers/food/snacks/cakeslice/chocolate slices_num = 5 - list_reagents = list("nutriment" = 3, "vitamin" = 10) + bonus_reagents = list("nutriment" = 3, "vitamin" = 10) /obj/item/weapon/reagent_containers/food/snacks/cakeslice/chocolate @@ -134,13 +139,15 @@ icon_state = "birthdaycake" slice_path = /obj/item/weapon/reagent_containers/food/snacks/cakeslice/birthday slices_num = 5 - list_reagents = list("nutriment" = 7, "sprinkles" = 10, "vitamin" = 5) + bonus_reagents = list("nutriment" = 7, "sprinkles" = 10, "vitamin" = 5) + list_reagents = list("nutriment" = 20, "sprinkles" = 10, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/cakeslice/birthday name = "birthday cake slice" desc = "A slice of your birthday." icon_state = "birthdaycakeslice" filling_color = "#DC143C" + list_reagents = list("nutriment" = 4, "sprinkles" = 2, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/store/cake/apple @@ -149,7 +156,7 @@ icon_state = "applecake" slice_path = /obj/item/weapon/reagent_containers/food/snacks/cakeslice/apple slices_num = 5 - list_reagents = list("nutriment" = 3, "vitamin" = 10) + bonus_reagents = list("nutriment" = 3, "vitamin" = 10) /obj/item/weapon/reagent_containers/food/snacks/cakeslice/apple name = "apple cake slice" @@ -168,7 +175,7 @@ icon_state = "slimecake" slice_path = /obj/item/weapon/reagent_containers/food/snacks/cakeslice/slimecake slices_num = 5 - list_reagents = list("nutriment" = 1, "vitamin" = 3) + bonus_reagents = list("nutriment" = 1, "vitamin" = 3) /obj/item/weapon/reagent_containers/food/snacks/cakeslice/slimecake name = "Slime cake slice" diff --git a/code/modules/food&drinks/food/snacks_egg.dm b/code/modules/food&drinks/food/snacks_egg.dm index 8d9a585c2f8..23c80a6bf4b 100644 --- a/code/modules/food&drinks/food/snacks_egg.dm +++ b/code/modules/food&drinks/food/snacks_egg.dm @@ -5,7 +5,8 @@ name = "chocolate egg" desc = "Such, sweet, fattening food." icon_state = "chocolateegg" - list_reagents = list("nutriment" = 1, "vitamin" = 1) + bonus_reagents = list("nutriment" = 1, "vitamin" = 1) + list_reagents = list("nutriment" = 4, "sugar" = 2, "cocoa" = 2) filling_color = "#A0522D" /obj/item/weapon/reagent_containers/food/snacks/egg @@ -73,23 +74,26 @@ name = "fried egg" desc = "A fried egg, with a touch of salt and pepper." icon_state = "friedegg" - list_reagents = list("nutriment" = 1, "vitamin" = 1) + bonus_reagents = list("nutriment" = 1, "vitamin" = 1) bitesize = 1 filling_color = "#FFFFF0" + list_reagents = list("nutriment" = 3) /obj/item/weapon/reagent_containers/food/snacks/boiledegg name = "boiled egg" desc = "A hard boiled egg." icon_state = "egg" - list_reagents = list("nutriment" = 1, "vitamin" = 1) + bonus_reagents = list("nutriment" = 1, "vitamin" = 1) filling_color = "#FFFFF0" + list_reagents = list("nutriment" = 2, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/omelette //FUCK THIS name = "omelette du fromage" desc = "That's all you can say!" icon_state = "omelette" trash = /obj/item/trash/plate - list_reagents = list("nutriment" = 1, "vitamin" = 2) + bonus_reagents = list("nutriment" = 1, "vitamin" = 2) + list_reagents = list("nutriment" = 8, "vitamin" = 1) bitesize = 1 w_class = 3 @@ -113,6 +117,7 @@ name = "eggs benedict" desc = "There is only one egg on this, how rude." icon_state = "benedict" - list_reagents = list("vitamin" = 4) + bonus_reagents = list("vitamin" = 4) trash = /obj/item/trash/plate - w_class = 3 \ No newline at end of file + w_class = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 4) \ No newline at end of file diff --git a/code/modules/food&drinks/food/snacks_meat.dm b/code/modules/food&drinks/food/snacks_meat.dm index 04fbc48c49d..62cf5fcc05b 100644 --- a/code/modules/food&drinks/food/snacks_meat.dm +++ b/code/modules/food&drinks/food/snacks_meat.dm @@ -8,15 +8,16 @@ desc = "A grifftastic sandwich that burns your tongue and then leaves it numb!" icon_state = "cubancarp" trash = /obj/item/trash/plate - list_reagents = list("nutriment" = 1, "vitamin" = 4) + bonus_reagents = list("nutriment" = 1, "vitamin" = 4) bitesize = 3 filling_color = "#CD853F" + list_reagents = list("nutriment" = 6, "capsaicin" = 1) /obj/item/weapon/reagent_containers/food/snacks/carpmeat name = "carp fillet" desc = "A fillet of spess carp meat." icon_state = "fishfillet" - list_reagents = list("nutriment" = 2, "carpotoxin" = 2, "vitamin" = 2) + list_reagents = list("nutriment" = 3, "carpotoxin" = 2, "vitamin" = 2) bitesize = 6 filling_color = "#FA8072" @@ -32,7 +33,8 @@ name = "fish fingers" desc = "A finger of fish." icon_state = "fishfingers" - list_reagents = list("nutriment" = 1, "vitamin" = 2) + bonus_reagents = list("nutriment" = 1, "vitamin" = 2) + list_reagents = list("nutriment" = 4) bitesize = 1 filling_color = "#CD853F" @@ -40,7 +42,8 @@ name = "fish and chips" desc = "I do say so myself chap." icon_state = "fishandchips" - list_reagents = list("nutriment" = 1, "vitamin" = 2) + bonus_reagents = list("nutriment" = 1, "vitamin" = 2) + list_reagents = list("nutriment" = 6) filling_color = "#FA8072" ////////////////////////////////////////////MEATS AND ALIKE//////////////////////////////////////////// @@ -65,7 +68,16 @@ desc = "Now you can feel like a real tourist vacationing in Ireland." icon_state = "cornedbeef" trash = /obj/item/trash/plate - list_reagents = list("nutriment" = 1, "vitamin" = 4) + bonus_reagents = list("nutriment" = 1, "vitamin" = 4) + list_reagents = list("nutriment" = 5) + +/obj/item/weapon/reagent_containers/food/snacks/bearsteak + name = "Filet migrawr" + desc = "Because eating bear wasn't manly enough." + icon_state = "bearsteak" + trash = /obj/item/trash/plate + bonus_reagents = list("nutriment" = 2, "vitamin" = 6) + list_reagents = list("nutriment" = 2, "vitamin" = 5, "manlydorf" = 5) /obj/item/weapon/reagent_containers/food/snacks/faggot name = "faggot" @@ -79,6 +91,8 @@ desc = "A piece of mixed, long meat." icon_state = "sausage" filling_color = "#CD5C5C" + bonus_reagents = list("nutriment" = 1, "vitamin" = 1) + list_reagents = list("nutriment" = 6, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/sausage/New() ..() @@ -89,27 +103,29 @@ desc = "A savory dish of alien wing wang in soy." icon_state = "wingfangchu" trash = /obj/item/weapon/reagent_containers/glass/bowl - list_reagents = list("nutriment" = 1, "vitamin" = 2) + bonus_reagents = list("nutriment" = 1, "vitamin" = 2) + list_reagents = list("nutriment" = 6, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/kebab trash = /obj/item/stack/rods icon_state = "kebab" w_class = 3 + list_reagents = list("nutriment" = 8) /obj/item/weapon/reagent_containers/food/snacks/kebab/human name = "human-kebab" desc = "A human meat, on a stick." - list_reagents = list("nutriment" = 1, "vitamin" = 6) + bonus_reagents = list("nutriment" = 1, "vitamin" = 6) /obj/item/weapon/reagent_containers/food/snacks/kebab/monkey name = "meat-kebab" desc = "Delicious meat, on a stick." - list_reagents = list("nutriment" = 1, "vitamin" = 2) + bonus_reagents = list("nutriment" = 1, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/kebab/tofu name = "tofu-kebab" desc = "Vegan meat, on a stick." - list_reagents = list("nutriment" = 1) + bonus_reagents = list("nutriment" = 1) /obj/item/weapon/reagent_containers/food/snacks/monkeycube name = "monkey cube" @@ -153,16 +169,18 @@ name = "enchiladas" desc = "Viva La Mexico!" icon_state = "enchiladas" - list_reagents = list("nutriment" = 1, "vitamin" = 2) + bonus_reagents = list("nutriment" = 1, "vitamin" = 2) bitesize = 4 filling_color = "#FFA07A" + list_reagents = list("nutriment" = 8, "capsaicin" = 6) /obj/item/weapon/reagent_containers/food/snacks/stewedsoymeat name = "stewed soy meat" desc = "Even non-vegetarians will LOVE this!" icon_state = "stewedsoymeat" trash = /obj/item/trash/plate - list_reagents = list("nutriment" = 1) + bonus_reagents = list("nutriment" = 1) + list_reagents = list("nutriment" = 8) filling_color = "#D2691E" /obj/item/weapon/reagent_containers/food/snacks/stewedsoymeat/New() @@ -174,7 +192,8 @@ desc = "A giant spider's leg that's still twitching after being cooked. Gross!" icon_state = "spiderlegcooked" trash = /obj/item/trash/plate - list_reagents = list("nutriment" = 1, "capsaicin" = 2, "vitamin" = 2) + bonus_reagents = list("nutriment" = 1, "capsaicin" = 2, "vitamin" = 2) + list_reagents = list("nutriment" = 3, "capsaicin" = 2) filling_color = "#000000" /obj/item/weapon/reagent_containers/food/snacks/spidereggsham @@ -182,7 +201,8 @@ desc = "Would you eat them on a train? Would you eat them on a plane? Would you eat them on a state of the art corporate deathtrap floating through space?" icon_state = "spidereggsham" trash = /obj/item/trash/plate - list_reagents = list("nutriment" = 1, "vitamin" = 3) + bonus_reagents = list("nutriment" = 1, "vitamin" = 3) + list_reagents = list("nutriment" = 6) bitesize = 4 filling_color = "#7FFF00" @@ -190,5 +210,6 @@ name = "carp sashimi" desc = "Celebrate surviving attack from hostile alien lifeforms by hospitalising yourself." icon_state = "sashimi" - list_reagents = list("nutriment" = 1, "capsaicin" = 4, "vitamin" = 4) - filling_color = "#FA8072" \ No newline at end of file + bonus_reagents = list("nutriment" = 1, "capsaicin" = 4, "vitamin" = 4) + list_reagents = list("nutriment" = 6, "capsaicin" = 5) + filling_color = "#FA8072" diff --git a/code/modules/food&drinks/food/snacks_other.dm b/code/modules/food&drinks/food/snacks_other.dm index 5abc827d954..735b65f5048 100644 --- a/code/modules/food&drinks/food/snacks_other.dm +++ b/code/modules/food&drinks/food/snacks_other.dm @@ -15,6 +15,7 @@ desc = "A wedge of delicious Cheddar. The cheese wheel it was cut from can't have gone far." icon_state = "cheesewedge" filling_color = "#FFD700" + list_reagents = list("nutriment" = 3, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/watermelonslice name = "watermelon slice" @@ -78,7 +79,8 @@ name = "loaded baked potato" desc = "Totally baked." icon_state = "loadedbakedpotato" - list_reagents = list("nutriment" = 1, "vitamin" = 2) + bonus_reagents = list("nutriment" = 1, "vitamin" = 2) + list_reagents = list("nutriment" = 6) filling_color = "#D2B48C" /obj/item/weapon/reagent_containers/food/snacks/fries @@ -102,7 +104,8 @@ desc = "Fries. Covered in cheese. Duh." icon_state = "cheesyfries" trash = /obj/item/trash/plate - list_reagents = list("nutriment" = 1, "vitamin" = 2) + bonus_reagents = list("nutriment" = 1, "vitamin" = 2) + list_reagents = list("nutriment" = 6) filling_color = "#FFD700" /obj/item/weapon/reagent_containers/food/snacks/badrecipe @@ -125,7 +128,8 @@ desc = "An apple coated in sugary sweetness." icon_state = "candiedapple" bitesize = 3 - list_reagents = list("nutriment" = 2, "sugar" = 3) + bonus_reagents = list("nutriment" = 2, "sugar" = 3) + list_reagents = list("nutriment" = 3, "sugar" = 2) filling_color = "#FF4500" /obj/item/weapon/reagent_containers/food/snacks/mint @@ -141,14 +145,16 @@ name = "egg wrap" desc = "The precursor to Pigs in a Blanket." icon_state = "wrap" - list_reagents = list("nutriment" = 1, "vitamin" = 3) + bonus_reagents = list("nutriment" = 1, "vitamin" = 3) + list_reagents = list("nutriment" = 5) filling_color = "#F0E68C" /obj/item/weapon/reagent_containers/food/snacks/beans name = "tin of beans" desc = "Musical fruit in a slightly less musical container." icon_state = "beans" - list_reagents = list("nutriment" = 1, "vitamin" = 1) + bonus_reagents = list("nutriment" = 1, "vitamin" = 1) + list_reagents = list("nutriment" = 10) filling_color = "#B22222" /obj/item/weapon/reagent_containers/food/snacks/spidereggs @@ -162,14 +168,16 @@ name = "chocolate coin" desc = "A completely edible but nonflippable festive coin." icon_state = "chococoin" - list_reagents = list("nutriment" = 1, "sugar" = 1) + bonus_reagents = list("nutriment" = 1, "sugar" = 1) + list_reagents = list("nutriment" = 3, "cocoa" = 1) filling_color = "#A0522D" /obj/item/weapon/reagent_containers/food/snacks/chocoorange name = "chocolate orange" desc = "A festive chocolate orange" icon_state = "chocoorange" - list_reagents = list("nutriment" = 1, "sugar" = 1) + bonus_reagents = list("nutriment" = 1, "sugar" = 1) + list_reagents = list("nutriment" = 3, "sugar" = 1) filling_color = "#A0522D" /obj/item/weapon/reagent_containers/food/snacks/eggplantparm @@ -177,5 +185,6 @@ desc = "The only good recipe for eggplant." icon_state = "eggplantparm" trash = /obj/item/trash/plate - list_reagents = list("nutriment" = 1, "vitamin" = 3) + bonus_reagents = list("nutriment" = 1, "vitamin" = 3) + list_reagents = list("nutriment" = 6, "vitamin" = 2) filling_color = "#BA55D3" \ No newline at end of file diff --git a/code/modules/food&drinks/food/snacks_pastry.dm b/code/modules/food&drinks/food/snacks_pastry.dm index 20171e5e471..ffd7f5dc9fc 100644 --- a/code/modules/food&drinks/food/snacks_pastry.dm +++ b/code/modules/food&drinks/food/snacks_pastry.dm @@ -7,8 +7,10 @@ desc = "Goes great with Robust Coffee." icon_state = "donut1" bitesize = 5 - list_reagents = list("sugar" = 1) + bonus_reagents = list("sugar" = 1) + list_reagents = list("nutriment" = 3, "sugar" = 2) var/extra_reagent = null + filling_color = "#D2691E" /obj/item/weapon/reagent_containers/food/snacks/donut/New() ..() @@ -16,6 +18,8 @@ icon_state = "donut2" name = "frosted donut" reagents.add_reagent("sprinkles", 2) + bonus_reagents = list("sprinkles" = 2, "sugar" = 1) + filling_color = "#FF69B4" /obj/item/weapon/reagent_containers/food/snacks/donut/chaos name = "chaos donut" @@ -26,25 +30,31 @@ ..() extra_reagent = pick("nutriment", "capsaicin", "frostoil", "krokodil", "plasma", "cocoa", "slimejelly", "banana", "berryjuice", "omnizine") reagents.add_reagent("[extra_reagent]", 3) + bonus_reagents = list("[extra_reagent]" = 3, "sugar" = 1) if(prob(30)) icon_state = "donut2" name = "frosted chaos donut" reagents.add_reagent("sprinkles", 2) + bonus_reagents = list("sprinkles" = 2, "[extra_reagent]" = 3, "sugar" = 1) + filling_color = "#FF69B4" /obj/item/weapon/reagent_containers/food/snacks/donut/jelly name = "jelly donut" desc = "You jelly?" icon_state = "jdonut1" - list_reagents = list("sugar" = 1, "vitamin" = 1) + bonus_reagents = list("sugar" = 1, "vitamin" = 1) extra_reagent = "berryjuice" /obj/item/weapon/reagent_containers/food/snacks/donut/jelly/New() ..() - reagents.add_reagent("[extra_reagent]", 5) + if(extra_reagent) + reagents.add_reagent("[extra_reagent]", 3) if(prob(30)) icon_state = "jdonut2" name = "frosted jelly Donut" reagents.add_reagent("sprinkles", 2) + bonus_reagents = list("sprinkles" = 2, "sugar" = 1) + filling_color = "#FF69B4" /obj/item/weapon/reagent_containers/food/snacks/donut/jelly/slimejelly name = "jelly donut" @@ -64,7 +74,9 @@ name = "muffin" desc = "A delicious and spongy little cake." icon_state = "muffin" - list_reagents = list("vitamin" = 1) + bonus_reagents = list("vitamin" = 1) + list_reagents = list("nutriment" = 6) + filling_color = "#F4A460" /obj/item/weapon/reagent_containers/food/snacks/muffin/berry name = "berry muffin" @@ -82,7 +94,9 @@ desc = "A legendary egg custard that makes friends out of enemies. Probably too hot for a cat to eat." icon_state = "chawanmushi" trash = /obj/item/weapon/reagent_containers/glass/bowl - list_reagents = list("vitamin" = 1) + bonus_reagents = list("vitamin" = 1) + list_reagents = list("nutriment" = 5) + filling_color = "#FFE4E1" ////////////////////////////////////////////WAFFLES//////////////////////////////////////////// @@ -91,7 +105,8 @@ desc = "Mmm, waffles." icon_state = "waffles" trash = /obj/item/trash/waffles - list_reagents = list("vitamin" = 1) + bonus_reagents = list("vitamin" = 1) + list_reagents = list("nutriment" = 8, "vitamin" = 1) filling_color = "#D2691E" /obj/item/weapon/reagent_containers/food/snacks/soylentgreen @@ -99,7 +114,8 @@ desc = "Not made of people. Honest." //Totally people. icon_state = "soylent_green" trash = /obj/item/trash/waffles - list_reagents = list("vitamin" = 1) + bonus_reagents = list("vitamin" = 1) + list_reagents = list("nutriment" = 10, "vitamin" = 1) filling_color = "#9ACD32" /obj/item/weapon/reagent_containers/food/snacks/soylenviridians @@ -107,7 +123,8 @@ desc = "Not made of people. Honest." //Actually honest for once. icon_state = "soylent_yellow" trash = /obj/item/trash/waffles - list_reagents = list("vitamin" = 1) + bonus_reagents = list("vitamin" = 1) + list_reagents = list("nutriment" = 10, "vitamin" = 1) filling_color = "#9ACD32" /obj/item/weapon/reagent_containers/food/snacks/rofflewaffles @@ -116,7 +133,8 @@ icon_state = "rofflewaffles" trash = /obj/item/trash/waffles bitesize = 4 - list_reagents = list("vitamin" = 2) + bonus_reagents = list("vitamin" = 2) + list_reagents = list("nutriment" = 8, "mushroomhallucinogen" = 2, "vitamin" = 2) filling_color = "#00BFFF" ////////////////////////////////////////////OTHER//////////////////////////////////////////// @@ -126,7 +144,7 @@ desc = "COOKIE!!!" icon_state = "COOKIE!!!" bitesize = 1 - list_reagents = list("nutriment" = 1) + bonus_reagents = list("nutriment" = 1) filling_color = "#F0E68C" /obj/item/weapon/reagent_containers/food/snacks/donkpocket @@ -140,27 +158,31 @@ /obj/item/weapon/reagent_containers/food/snacks/donkpocket/warm name = "\improper Warm Donk-pocket" desc = "The heated food of choice for the seasoned traitor." - list_reagents = list("omnizine" = 4) + bonus_reagents = list("omnizine" = 3) + list_reagents = list("nutriment" = 4, "omnizine" = 3) /obj/item/weapon/reagent_containers/food/snacks/fortunecookie name = "fortune cookie" desc = "A true prophecy in each cookie!" icon_state = "fortune_cookie" - list_reagents = list("nutriment" = 2) + bonus_reagents = list("nutriment" = 2) + list_reagents = list("nutriment" = 3) filling_color = "#F4A460" /obj/item/weapon/reagent_containers/food/snacks/poppypretzel name = "poppy pretzel" desc = "It's all twisted up!" icon_state = "poppypretzel" - list_reagents = list("nutriment" = 1, "vitamin" = 2) + bonus_reagents = list("nutriment" = 1, "vitamin" = 2) + list_reagents = list("nutriment" = 5) filling_color = "#F0E68C" /obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit name = "plump helmet biscuit" desc = "This is a finely-prepared plump helmet biscuit. The ingredients are exceptionally minced plump helmet, and well-minced dwarven wheat flour." icon_state = "phelmbiscuit" - list_reagents = list("nutriment" = 1, "vitamin" = 1) + bonus_reagents = list("nutriment" = 1, "vitamin" = 1) + list_reagents = list("nutriment" = 5) filling_color = "#F0E68C" /obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit/New() @@ -169,12 +191,14 @@ name = "exceptional plump helmet biscuit" desc = "Microwave is taken by a fey mood! It has cooked an exceptional plump helmet biscuit!" reagents.add_reagent("omnizine", 5) + bonus_reagents = list("omnizine" = 5, "nutriment" = 1, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/cracker name = "cracker" desc = "It's a salted cracker." icon_state = "cracker" bitesize = 1 + bonus_reagents = list("nutriment" = 1) list_reagents = list("nutriment" = 1) filling_color = "#F0E68C" @@ -183,26 +207,30 @@ desc = "Fresh footlong ready to go down on." icon_state = "hotdog" bitesize = 3 - list_reagents = list("nutriment" = 1, "vitamin" = 3) + bonus_reagents = list("nutriment" = 1, "vitamin" = 3) + list_reagents = list("nutriment" = 6, "ketchup" = 3, "vitamin" = 3) filling_color = "#8B0000" /obj/item/weapon/reagent_containers/food/snacks/meatbun name = "meat bun" desc = "Has the potential to not be Dog." icon_state = "meatbun" - list_reagents = list("nutriment" = 1, "vitamin" = 2) + bonus_reagents = list("nutriment" = 1, "vitamin" = 2) + list_reagents = list("nutriment" = 6, "vitamin" = 2) filling_color = "#8B0000" /obj/item/weapon/reagent_containers/food/snacks/sugarcookie name = "sugar cookie" desc = "Just like your little sister used to make." icon_state = "sugarcookie" - list_reagents = list("nutriment" = 1, "sugar" = 3) + bonus_reagents = list("nutriment" = 1, "sugar" = 3) + list_reagents = list("nutriment" = 3, "sugar" = 3) filling_color = "#CD853F" /obj/item/weapon/reagent_containers/food/snacks/chococornet name = "chocolate cornet" desc = "Which side's the head, the fat end or the thin end?" icon_state = "chococornet" - list_reagents = list("nutriment" = 1, "vitamin" = 1) + bonus_reagents = list("nutriment" = 1, "vitamin" = 1) + list_reagents = list("nutriment" = 5, "vitamin" = 1) filling_color = "#FFE4C4" diff --git a/code/modules/food&drinks/food/snacks_pie.dm b/code/modules/food&drinks/food/snacks_pie.dm index 1c4547d3f26..1a69a62b334 100644 --- a/code/modules/food&drinks/food/snacks_pie.dm +++ b/code/modules/food&drinks/food/snacks_pie.dm @@ -3,20 +3,22 @@ trash = /obj/item/trash/plate bitesize = 3 w_class = 3 + list_reagents = list("nutriment" = 10, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/pie/plain name = "plain pie" desc = "A simple pie, still delicious." icon_state = "pie" custom_food_type = /obj/item/weapon/reagent_containers/food/snacks/customizable/pie - list_reagents = list("nutriment" = 8, "vitamin" = 1) + bonus_reagents = list("nutriment" = 8, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/pie/cream name = "banana cream pie" desc = "Just like back home, on clown planet! HONK!" icon_state = "pie" trash = /obj/item/trash/plate - list_reagents = list("nutriment" = 2, "vitamin" = 2) + bonus_reagents = list("nutriment" = 2, "vitamin" = 2) + list_reagents = list("nutriment" = 6, "banana" = 5, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/pie/cream/throw_impact(atom/hit_atom) ..() @@ -29,22 +31,28 @@ name = "berry clafoutis" desc = "No black birds, this is a good sign." icon_state = "berryclafoutis" - list_reagents = list("nutriment" = 1, "vitamin" = 2) + bonus_reagents = list("nutriment" = 1, "vitamin" = 2) + list_reagents = list("nutriment" = 10, "berryjuice" = 5, "vitamin" = 2) +/obj/item/weapon/reagent_containers/food/snacks/pie/bearypie + name = "beary pie" + desc = "No brown bears, this is a good sign." + icon_state = "bearypie" + bonus_reagents = list("nutriment" = 2, "vitamin" = 3) + list_reagents = list("nutriment" = 2, "vitamin" = 3) /obj/item/weapon/reagent_containers/food/snacks/pie/meatpie name = "meat-pie" icon_state = "meatpie" desc = "An old barber recipe, very delicious!" - list_reagents = list("nutriment" = 1, "vitamin" = 5) + bonus_reagents = list("nutriment" = 1, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/pie/tofupie name = "tofu-pie" icon_state = "meatpie" desc = "A delicious tofu pie." - list_reagents = list("nutriment" = 1, "vitamin" = 2) - + bonus_reagents = list("nutriment" = 1, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/pie/amanita_pie @@ -52,14 +60,15 @@ desc = "Sweet and tasty poison pie." icon_state = "amanita_pie" bitesize = 4 - list_reagents = list("nutriment" = 1, "vitamin" = 4) + bonus_reagents = list("nutriment" = 1, "vitamin" = 4) + list_reagents = list("nutriment" = 6, "amatoxin" = 3, "mushroomhallucinogen" = 1, "vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/pie/plump_pie name = "plump pie" desc = "I bet you love stuff made out of plump helmets!" icon_state = "plump_pie" - list_reagents = list("nutriment" = 1, "vitamin" = 4) + bonus_reagents = list("nutriment" = 1, "vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/pie/plump_pie/New() ..() @@ -67,6 +76,7 @@ name = "exceptional plump pie" desc = "Microwave is taken by a fey mood! It has cooked an exceptional plump pie!" reagents.add_reagent("omnizine", 5) + bonus_reagents = list("nutriment" = 1, "omnizine" = 5, "vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/pie/xemeatpie @@ -74,15 +84,14 @@ icon_state = "xenomeatpie" desc = "A delicious meatpie. Probably heretical." trash = /obj/item/trash/plate - list_reagents = list("nutriment" = 1, "vitamin" = 5) - + bonus_reagents = list("nutriment" = 1, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/pie/applepie name = "apple pie" desc = "A pie containing sweet sweet love...or apple." icon_state = "applepie" - list_reagents = list("nutriment" = 1, "vitamin" = 3) + bonus_reagents = list("nutriment" = 1, "vitamin" = 3) @@ -90,7 +99,7 @@ name = "cherry pie" desc = "Taste so good, make a grown man cry." icon_state = "cherrypie" - list_reagents = list("nutriment" = 1, "vitamin" = 2) + bonus_reagents = list("nutriment" = 1, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/pumpkinpie @@ -99,16 +108,18 @@ icon_state = "pumpkinpie" slice_path = /obj/item/weapon/reagent_containers/food/snacks/pumpkinpieslice slices_num = 5 - list_reagents = list("nutriment" = 1, "vitamin" = 5) + bonus_reagents = list("nutriment" = 1, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/pumpkinpieslice name = "pumpkin pie slice" desc = "A slice of pumpkin pie, with whipped cream on top. Perfection." icon_state = "pumpkinpieslice" trash = /obj/item/trash/plate + list_reagents = list("nutriment" = 2) /obj/item/weapon/reagent_containers/food/snacks/pie/appletart name = "golden apple streusel tart" desc = "A tasty dessert that won't make it through a metal detector." icon_state = "gappletart" - list_reagents = list("nutriment" = 1, "vitamin" = 4) \ No newline at end of file + bonus_reagents = list("nutriment" = 1, "vitamin" = 4) + list_reagents = list("nutriment" = 8, "gold" = 5, "vitamin" = 4) diff --git a/code/modules/food&drinks/food/snacks_pizza.dm b/code/modules/food&drinks/food/snacks_pizza.dm index deb170a95be..6237ce52192 100644 --- a/code/modules/food&drinks/food/snacks_pizza.dm +++ b/code/modules/food&drinks/food/snacks_pizza.dm @@ -5,15 +5,17 @@ w_class = 3 slices_num = 6 +/obj/item/weapon/reagent_containers/food/snacks/pizzaslice + list_reagents = list("nutriment" = 5) + /obj/item/weapon/reagent_containers/food/snacks/pizza/margherita name = "margherita" desc = "The most cheezy pizza in galaxy." icon_state = "pizzamargherita" slice_path = /obj/item/weapon/reagent_containers/food/snacks/pizzaslice/margherita slices_num = 6 - list_reagents = list("nutriment" = 5, "vitamin" = 5) - - + bonus_reagents = list("nutriment" = 5, "vitamin" = 5) + list_reagents = list("nutriment" = 30, "tomatojuice" = 6, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/pizzaslice/margherita name = "margherita slice" @@ -27,7 +29,8 @@ icon_state = "meatpizza" slice_path = /obj/item/weapon/reagent_containers/food/snacks/pizzaslice/meatpizza slices_num = 6 - list_reagents = list("nutriment" = 5, "vitamin" = 8) + bonus_reagents = list("nutriment" = 5, "vitamin" = 8) + list_reagents = list("nutriment" = 30, "tomatojuice" = 6, "vitamin" = 8) /obj/item/weapon/reagent_containers/food/snacks/pizzaslice/meatpizza name = "meatpizza slice" @@ -41,7 +44,8 @@ icon_state = "mushroompizza" slice_path = /obj/item/weapon/reagent_containers/food/snacks/pizzaslice/mushroompizza slices_num = 6 - list_reagents = list("nutriment" = 5, "vitamin" = 5) + bonus_reagents = list("nutriment" = 5, "vitamin" = 5) + list_reagents = list("nutriment" = 30, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/pizzaslice/mushroompizza name = "mushroom pizza slice" @@ -55,7 +59,8 @@ icon_state = "vegetablepizza" slice_path = /obj/item/weapon/reagent_containers/food/snacks/pizzaslice/vegetablepizza slices_num = 6 - list_reagents = list("nutriment" = 5, "vitamin" = 5) + bonus_reagents = list("nutriment" = 5, "vitamin" = 5) + list_reagents = list("nutriment" = 25, "tomatojuice" = 6, "oculine" = 12, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/pizzaslice/vegetablepizza name = "vegetable pizza slice" @@ -226,28 +231,20 @@ /obj/item/pizzabox/margherita/New() pizza = new /obj/item/weapon/reagent_containers/food/snacks/pizza/margherita(src) - pizza.reagents.add_reagent("nutriment", 25) - pizza.reagents.add_reagent("tomatojuice", 6) boxtag = "Margherita Deluxe" update_icon() /obj/item/pizzabox/vegetable/New() pizza = new /obj/item/weapon/reagent_containers/food/snacks/pizza/vegetablepizza(src) - pizza.reagents.add_reagent("nutriment", 20) - pizza.reagents.add_reagent("tomatojuice", 6) - pizza.reagents.add_reagent("oculine", 12) boxtag = "Gourmet Vegatable" update_icon() /obj/item/pizzabox/mushroom/New() pizza = new /obj/item/weapon/reagent_containers/food/snacks/pizza/mushroompizza(src) - pizza.reagents.add_reagent("nutriment", 25) boxtag = "Mushroom Special" update_icon() /obj/item/pizzabox/meat/New() pizza = new /obj/item/weapon/reagent_containers/food/snacks/pizza/meatpizza(src) - pizza.reagents.add_reagent("nutriment", 25) - pizza.reagents.add_reagent("tomatojuice", 6) boxtag = "Meatlover's Supreme" update_icon() \ No newline at end of file diff --git a/code/modules/food&drinks/food/snacks_salad.dm b/code/modules/food&drinks/food/snacks_salad.dm index a39f11820cb..0e9cb68f107 100644 --- a/code/modules/food&drinks/food/snacks_salad.dm +++ b/code/modules/food&drinks/food/snacks_salad.dm @@ -13,16 +13,19 @@ name = "\improper Aesir salad" desc = "Probably too incredible for mortal men to fully enjoy." icon_state = "aesirsalad" - list_reagents = list("omnizine" = 8, "vitamin" = 6) + bonus_reagents = list("omnizine" = 2, "vitamin" = 6) + list_reagents = list("nutriment" = 8, "omnizine" = 8, "vitamin" = 6) /obj/item/weapon/reagent_containers/food/snacks/salad/herbsalad name = "herb salad" desc = "A tasty salad with apples on top." icon_state = "herbsalad" - list_reagents = list("vitamin" = 4) + bonus_reagents = list("vitamin" = 4) + list_reagents = list("nutriment" = 8, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/salad/validsalad name = "valid salad" desc = "It's just an herb salad with meatballs and fried potato slices. Nothing suspicious about it." icon_state = "validsalad" - list_reagents = list("doctorsdelight" = 5, "vitamin" = 4) + bonus_reagents = list("doctorsdelight" = 5, "vitamin" = 4) + list_reagents = list("nutriment" = 8, "doctorsdelight" = 5, "vitamin" = 2) diff --git a/code/modules/food&drinks/food/snacks_sandwichtoast.dm b/code/modules/food&drinks/food/snacks_sandwichtoast.dm index c4c3d246324..b1196ce7ff5 100644 --- a/code/modules/food&drinks/food/snacks_sandwichtoast.dm +++ b/code/modules/food&drinks/food/snacks_sandwichtoast.dm @@ -4,7 +4,8 @@ desc = "A grand creation of meat, cheese, bread, and several leaves of lettuce! Arthur Dent would be proud." icon_state = "sandwich" trash = /obj/item/trash/plate - list_reagents = list("nutriment" = 1, "vitamin" = 1) + bonus_reagents = list("nutriment" = 1, "vitamin" = 1) + list_reagents = list("nutriment" = 6, "vitamin" = 1) cooked_type = /obj/item/weapon/reagent_containers/food/snacks/toastedsandwich /obj/item/weapon/reagent_containers/food/snacks/toastedsandwich @@ -12,14 +13,16 @@ desc = "Now if you only had a pepper bar." icon_state = "toastedsandwich" trash = /obj/item/trash/plate - list_reagents = list("nutriment" = 1, "carbon" = 2) + bonus_reagents = list("nutriment" = 1, "carbon" = 2) + list_reagents = list("nutriment" = 6, "carbon" = 2) /obj/item/weapon/reagent_containers/food/snacks/grilledcheese name = "grilled cheese sandwich" desc = "Goes great with Tomato soup!" icon_state = "toastedsandwich" trash = /obj/item/trash/plate - list_reagents = list("nutriment" = 1, "vitamin" = 1) + bonus_reagents = list("nutriment" = 1, "vitamin" = 1) + list_reagents = list("nutriment" = 7, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/jellysandwich name = "jelly sandwich" @@ -29,23 +32,27 @@ bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/jellysandwich/slime - list_reagents = list("slimejelly" = 5, "vitamin" = 2) + bonus_reagents = list("slimejelly" = 5, "vitamin" = 2) + list_reagents = list("nutriment" = 2, "slimejelly" = 5, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/jellysandwich/cherry - list_reagents = list("cherryjelly" = 5, "vitamin" = 2) + bonus_reagents = list("cherryjelly" = 5, "vitamin" = 2) + list_reagents = list("nutriment" = 2, "cherryjelly" = 5, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/icecreamsandwich name = "icecream sandwich" desc = "Portable Ice-cream in it's own packaging." icon_state = "icecreamsandwich" - list_reagents = list("nutriment" = 1, "ice" = 2) + bonus_reagents = list("nutriment" = 1, "ice" = 2) + list_reagents = list("nutriment" = 2, "ice" = 2) /obj/item/weapon/reagent_containers/food/snacks/notasandwich name = "not-a-sandwich" desc = "Something seems to be wrong with this, you can't quite figure what. Maybe it's his moustache." icon_state = "notasandwich" trash = /obj/item/trash/plate - list_reagents = list("vitamin" = 6) + bonus_reagents = list("vitamin" = 6) + list_reagents = list("nutriment" = 6, "vitamin" = 6) /obj/item/weapon/reagent_containers/food/snacks/jelliedtoast name = "jellied toast" @@ -55,13 +62,16 @@ bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/jelliedtoast/cherry - list_reagents = list("cherryjelly" = 5, "vitamin" = 2) + bonus_reagents = list("cherryjelly" = 5, "vitamin" = 2) + list_reagents = list("nutriment" = 1, "cherryjelly" = 5, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/jelliedtoast/slime - list_reagents = list("slimejelly" = 5, "vitamin" = 2) + bonus_reagents = list("slimejelly" = 5, "vitamin" = 2) + list_reagents = list("nutriment" = 1, "slimejelly" = 5, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/twobread name = "two bread" desc = "This seems awfully bitter." icon_state = "twobread" - list_reagents = list("nutriment" = 1, "vitamin" = 2) + bonus_reagents = list("nutriment" = 1, "vitamin" = 2) + list_reagents = list("nutriment" = 2, "vitamin" = 2) diff --git a/code/modules/food&drinks/food/snacks_soup.dm b/code/modules/food&drinks/food/snacks_soup.dm index 742f6f0d9b5..3df14169642 100644 --- a/code/modules/food&drinks/food/snacks_soup.dm +++ b/code/modules/food&drinks/food/snacks_soup.dm @@ -2,6 +2,7 @@ w_class = 3 trash = /obj/item/weapon/reagent_containers/glass/bowl bitesize = 5 + list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/soup/New() ..() @@ -11,7 +12,7 @@ name = "wish soup" desc = "I wish this was soup." icon_state = "wishsoup" - list_reagents = list("water" = 1) + list_reagents = list("water" = 10) /obj/item/weapon/reagent_containers/food/snacks/soup/wish/New() ..() @@ -19,98 +20,107 @@ desc = "A wish come true!" reagents.add_reagent("nutriment", 9) reagents.add_reagent("vitamin", 1) - else - reagents.add_reagent("water", 10) + bonus_reagents = list("nutriment" = 9, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/soup/meatball name = "meatball soup" desc = "You've got balls kid, BALLS!" icon_state = "meatballsoup" - list_reagents = list("nutriment" = 1, "vitamin" = 5) + bonus_reagents = list("nutriment" = 1, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/soup/slime name = "slime soup" desc = "If no water is available, you may substitute tears." icon_state = "slimesoup" - list_reagents = list("nutriment" = 1, "slimejelly" = 5, "vitamin" = 5) + bonus_reagents = list("nutriment" = 1, "slimejelly" = 5, "vitamin" = 5) + list_reagents = list("nutriment" = 5, "slimejelly" = 5, "water" = 5, "vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/soup/blood name = "tomato soup" desc = "Smells like copper." icon_state = "tomatosoup" - list_reagents = list("nutriment" = 1, "vitamin" = 6) + bonus_reagents = list("nutriment" = 1, "vitamin" = 6) + list_reagents = list("nutriment" = 2, "blood" = 10, "water" = 5, "vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/soup/clownstears name = "clown's tears" desc = "Not very funny." icon_state = "clownstears" - list_reagents = list("nutriment" = 1, "banana" = 5, "vitamin" = 8) + bonus_reagents = list("nutriment" = 1, "banana" = 5, "vitamin" = 8) + list_reagents = list("nutriment" = 4, "banana" = 5, "water" = 5, "vitamin" = 8) /obj/item/weapon/reagent_containers/food/snacks/soup/vegetable name = "vegetable soup" desc = "A true vegan meal." icon_state = "vegetablesoup" - list_reagents = list("nutriment" = 1, "vitamin" = 4) + bonus_reagents = list("nutriment" = 1, "vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/soup/nettle name = "nettle soup" desc = "To think, the botanist would've beat you to death with one of these." icon_state = "nettlesoup" - list_reagents = list("nutriment" = 1, "omnizine" = 5, "vitamin" = 5) + bonus_reagents = list("nutriment" = 1, "omnizine" = 5, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/soup/mystery name = "mystery soup" desc = "The mystery is, why aren't you eating it?" icon_state = "mysterysoup" - list_reagents = list("nutriment" = 1, "tomatojuice" = 2) var/extra_reagent = null + list_reagents = list("nutriment" = 6) + /obj/item/weapon/reagent_containers/food/snacks/soup/mystery/New() ..() - extra_reagent = pick("capsaicin", "frostoil", "omnizine", "banana", "blood", "slimejelly", "toxin", "banana", "carbon", "oculine") reagents.add_reagent("[extra_reagent]", 5) + bonus_reagents = list("[extra_reagent]" = 5, "nutriment" = 6) /obj/item/weapon/reagent_containers/food/snacks/soup/hotchili name = "hot chili" desc = "A five alarm Texan Chili!" icon_state = "hotchili" - list_reagents = list("nutriment" = 1, "tomatojuice" = 2, "vitamin" = 2) + bonus_reagents = list("nutriment" = 1, "tomatojuice" = 2, "vitamin" = 2) + list_reagents = list("nutriment" = 5, "capsaicin" = 1, "tomatojuice" = 2, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/soup/coldchili name = "cold chili" desc = "This slush is barely a liquid!" icon_state = "coldchili" - list_reagents = list("nutriment" = 1, "tomatojuice" = 2, "vitamin" = 2) + bonus_reagents = list("nutriment" = 1, "tomatojuice" = 2, "vitamin" = 2) + list_reagents = list("nutriment" = 5, "frostoil" = 1, "tomatojuice" = 2, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/soup/monkeysdelight name = "monkey's delight" desc = "A delicious soup with dumplings and hunks of monkey meat simmered to perfection, in a broth that tastes faintly of bananas." icon_state = "monkeysdelight" - list_reagents = list("nutriment" = 1, "vitamin" = 5) + bonus_reagents = list("nutriment" = 1, "vitamin" = 5) + list_reagents = list("nutriment" = 10, "banana" = 5, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/soup/tomato name = "tomato soup" desc = "Drinking this feels like being a vampire! A tomato vampire..." icon_state = "tomatosoup" - list_reagents = list("nutriment" = 1, "tomatojuice" = 10, "vitamin" = 3) + bonus_reagents = list("nutriment" = 1, "tomatojuice" = 10, "vitamin" = 3) + list_reagents = list("nutriment" = 5, "tomatojuice" = 10, "vitamin" = 3) /obj/item/weapon/reagent_containers/food/snacks/soup/milo name = "milosoup" desc = "The universes best soup! Yum!!!" icon_state = "milosoup" - list_reagents = list("nutriment" = 1, "vitamin" = 3) + bonus_reagents = list("nutriment" = 1, "vitamin" = 3) /obj/item/weapon/reagent_containers/food/snacks/soup/mushroom name = "chantrelle soup" desc = "A delicious and hearty mushroom soup." icon_state = "mushroomsoup" - list_reagents = list("nutriment" = 1, "vitamin" = 5) + bonus_reagents = list("nutriment" = 1, "vitamin" = 5) + list_reagents = list("nutriment" = 8, "vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/soup/beet name = "beet soup" desc = "Wait, how do you spell it again..?" icon_state = "beetsoup" - list_reagents = list("nutriment" = 1, "vitamin" = 5) + bonus_reagents = list("nutriment" = 1, "vitamin" = 5) + list_reagents = list("nutriment" = 8, "vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/soup/beet/New() ..() @@ -122,18 +132,21 @@ desc = "Jello gelatin, from Alfred Hubbard's cookbook." icon_state = "spacylibertyduff" bitesize = 3 - list_reagents = list("nutriment" = 1, "vitamin" = 5) + bonus_reagents = list("nutriment" = 1, "vitamin" = 5) + list_reagents = list("nutriment" = 6, "mushroomhallucinogen" = 6) /obj/item/weapon/reagent_containers/food/snacks/soup/amanitajelly name = "amanita jelly" desc = "Looks curiously toxic." icon_state = "amanitajelly" bitesize = 3 - list_reagents = list("nutriment" = 1, "vitamin" = 5) + bonus_reagents = list("nutriment" = 1, "vitamin" = 5) + list_reagents = list("nutriment" = 6, "mushroomhallucinogen" = 3, "amatoxin" = 6) /obj/item/weapon/reagent_containers/food/snacks/soup/stew name = "stew" desc = "A nice and warm stew. Healthy and strong." icon_state = "stew" - list_reagents = list("nutriment" = 1, "tomatojuice" = 5, "vitamin" = 5) + bonus_reagents = list("nutriment" = 1, "tomatojuice" = 5, "vitamin" = 5) + list_reagents = list("nutriment" = 10, "oculine" = 5, "tomatojuice" = 5, "vitamin" = 5) bitesize = 7 diff --git a/code/modules/food&drinks/food/snacks_spaghetti.dm b/code/modules/food&drinks/food/snacks_spaghetti.dm index 88ae3114c57..1545ae518fc 100644 --- a/code/modules/food&drinks/food/snacks_spaghetti.dm +++ b/code/modules/food&drinks/food/snacks_spaghetti.dm @@ -12,7 +12,8 @@ desc = "A plain dish of noodles, this needs more ingredients." icon_state = "spaghettiboiled" trash = /obj/item/trash/plate - list_reagents = list("nutriment" = 2) + bonus_reagents = list("nutriment" = 2) + list_reagents = list("nutriment" = 2, "vitamin" = 1) custom_food_type = /obj/item/weapon/reagent_containers/food/snacks/customizable/pasta filling_color = "#F0E68C" @@ -22,7 +23,8 @@ icon_state = "pastatomato" trash = /obj/item/trash/plate bitesize = 4 - list_reagents = list("nutriment" = 1, "vitamin" = 4) + bonus_reagents = list("nutriment" = 1, "tomatojuice" = 10, "vitamin" = 4) + list_reagents = list("nutriment" = 6, "tomatojuice" = 10, "vitamin" = 4) filling_color = "#DC143C" /obj/item/weapon/reagent_containers/food/snacks/copypasta @@ -31,7 +33,8 @@ icon_state = "copypasta" trash = /obj/item/trash/plate bitesize = 4 - list_reagents = list("nutriment" = 1, "vitamin" = 4) + bonus_reagents = list("nutriment" = 1, "vitamin" = 4) + list_reagents = list("nutriment" = 12, "tomatojuice" = 20, "vitamin" = 8) filling_color = "#DC143C" /obj/item/weapon/reagent_containers/food/snacks/meatballspaghetti @@ -39,7 +42,8 @@ desc = "Now that's a nic'e meatball!" icon_state = "meatballspaghetti" trash = /obj/item/trash/plate - list_reagents = list("nutriment" = 1, "vitamin" = 4) + bonus_reagents = list("nutriment" = 1, "vitamin" = 4) + list_reagents = list("nutriment" = 8, "vitamin" = 4) filling_color = "#F0E68C" /obj/item/weapon/reagent_containers/food/snacks/spesslaw @@ -47,5 +51,6 @@ desc = "A lawyers favourite." icon_state = "spesslaw" trash = /obj/item/trash/plate - list_reagents = list("nutriment" = 1, "vitamin" = 6) + bonus_reagents = list("nutriment" = 1, "vitamin" = 6) + list_reagents = list("nutriment" = 8, "vitamin" = 6) filling_color = "#F0E68C" diff --git a/code/modules/food&drinks/kitchen machinery/microwave.dm b/code/modules/food&drinks/kitchen machinery/microwave.dm index 432fae10ead..48b0cff7ad5 100644 --- a/code/modules/food&drinks/kitchen machinery/microwave.dm +++ b/code/modules/food&drinks/kitchen machinery/microwave.dm @@ -245,7 +245,7 @@ for(var/obj/item/weapon/reagent_containers/food/snacks/F in contents) if(F.cooked_type) var/obj/item/weapon/reagent_containers/food/snacks/S = new F.cooked_type (get_turf(src)) - F.initialize_cooked_food(S) + F.initialize_cooked_food(S, efficiency) else new /obj/item/weapon/reagent_containers/food/snacks/badrecipe(src) if(dirty < 100) diff --git a/code/modules/food&drinks/kitchen machinery/processor.dm b/code/modules/food&drinks/kitchen machinery/processor.dm index 1a3be0f8587..f34053de43c 100644 --- a/code/modules/food&drinks/kitchen machinery/processor.dm +++ b/code/modules/food&drinks/kitchen machinery/processor.dm @@ -53,7 +53,7 @@ /datum/food_processor_process/mob/slime/process(loc, what) - var/mob/living/carbon/slime/S = what + var/mob/living/simple_animal/slime/S = what var/C = S.cores if(S.stat != DEAD) S.loc = loc @@ -64,7 +64,7 @@ feedback_add_details("slime_core_harvested","[replacetext(S.colour," ","_")]") ..() -/datum/food_processor_process/mob/slime/input = /mob/living/carbon/slime +/datum/food_processor_process/mob/slime/input = /mob/living/simple_animal/slime /datum/food_processor_process/mob/slime/output = null /datum/food_processor_process/mob/monkey/process(loc, what) diff --git a/code/modules/food&drinks/recipes/food_mixtures.dm b/code/modules/food&drinks/recipes/food_mixtures.dm index d468f33dfde..593dce5b8db 100644 --- a/code/modules/food&drinks/recipes/food_mixtures.dm +++ b/code/modules/food&drinks/recipes/food_mixtures.dm @@ -111,43 +111,6 @@ required_reagents = list("capsaicin" = 1, "hot_ramen" = 6) result_amount = 6 -/datum/chemical_reaction/cakebatter - name = "Cake Batter" - id = "cakebatter" - result = null - required_reagents = list("milk" = 5) - result_amount = 1 - required_container = /obj/item/weapon/reagent_containers/food/snacks/dough - mix_message = "The dough forms a cake batter." - -/datum/chemical_reaction/cakebatter/on_reaction(var/datum/reagents/holder) - var/obj/item/weapon/reagent_containers/food/snacks/S = new /obj/item/weapon/reagent_containers/food/snacks/cakebatter - S.loc = get_turf(holder.my_atom) - if(holder && holder.my_atom) - qdel(holder.my_atom) - -/datum/chemical_reaction/piedough - name = "Pie Dough" - id = "piedough" - result = null - required_reagents = list("milk" = 5) - result_amount = 1 - required_container = /obj/item/weapon/reagent_containers/food/snacks/flatdough - mix_message = "The dough forms a pie dough." - -/datum/chemical_reaction/piedough/on_reaction(var/datum/reagents/holder) - var/obj/item/weapon/reagent_containers/food/snacks/S = new /obj/item/weapon/reagent_containers/food/snacks/piedough - S.loc = get_turf(holder.my_atom) - if(holder && holder.my_atom) - qdel(holder.my_atom) - -/datum/chemical_reaction/cakebatter/alt - id = "cakebatteralt" - required_reagents = list("soymilk" = 5) - -/datum/chemical_reaction/piedough/alt - id = "piedoughalt" - required_reagents = list("soymilk" = 5) /datum/chemical_reaction/imitationcarpmeat name = "Imitation Carpmeat" @@ -164,22 +127,33 @@ if(holder && holder.my_atom) qdel(holder.my_atom) -/datum/chemical_reaction/rawpastrybase - name = "Raw Pastry Base" - id = "rawpastrybase" +/datum/chemical_reaction/dough + name = "Dough" + id = "dough" result = null - required_reagents = list("milk" = 5) + required_reagents = list("water" = 10, "flour" = 15) result_amount = 1 - required_container = /obj/item/weapon/reagent_containers/food/snacks/doughslice - mix_message = "The doughslice forms a raw pastry base" + mix_message = "The ingredients form a dough." -/datum/chemical_reaction/rawpastrybase/on_reaction(var/datum/reagents/holder) - var/obj/item/weapon/reagent_containers/food/snacks/S = new /obj/item/weapon/reagent_containers/food/snacks/rawpastrybase - S.loc = get_turf(holder.my_atom) - if(holder && holder.my_atom) - qdel(holder.my_atom) +/datum/chemical_reaction/dough/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/dough(location) -/datum/chemical_reaction/rawpastrybase/alt - id = "rawpastrybasealt" - required_reagents = list("soymilk" = 5) +/datum/chemical_reaction/cakebatter + name = "Cake Batter" + id = "cakebatter" + result = null + required_reagents = list("eggyolk" = 15, "flour" = 15, "sugar" = 5) + result_amount = 1 + mix_message = "The ingredients form a cake batter." + +/datum/chemical_reaction/cakebatter/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/cakebatter(location) + +/datum/chemical_reaction/cakebatter/vegan + id = "vegancakebatter" + required_reagents = list("soymilk" = 15, "flour" = 15, "sugar" = 5) diff --git a/code/modules/food&drinks/recipes/tablecraft/recipes_burger.dm b/code/modules/food&drinks/recipes/tablecraft/recipes_burger.dm index f25344c9621..53fea3217ec 100644 --- a/code/modules/food&drinks/recipes/tablecraft/recipes_burger.dm +++ b/code/modules/food&drinks/recipes/tablecraft/recipes_burger.dm @@ -45,6 +45,14 @@ ) result = /obj/item/weapon/reagent_containers/food/snacks/burger/xeno +datum/table_recipe/bearger + name = "Bearger" + reqs = list( + /obj/item/weapon/reagent_containers/food/snacks/meatsteak/bear = 1, + /obj/item/weapon/reagent_containers/food/snacks/bun = 1 + ) + result = /obj/item/weapon/reagent_containers/food/snacks/burger/bearger + /datum/table_recipe/fishburger name = "Fish burger" reqs = list( diff --git a/code/modules/food&drinks/recipes/tablecraft/recipes_dough.dm b/code/modules/food&drinks/recipes/tablecraft/recipes_dough.dm deleted file mode 100644 index a81fee36e52..00000000000 --- a/code/modules/food&drinks/recipes/tablecraft/recipes_dough.dm +++ /dev/null @@ -1,53 +0,0 @@ - - -// see code/module/crafting/table.dm - -////////////////////////////////////////////////DOUGH//////////////////////////////////////////////// - -//these recipes can also be done with attackby. - -/datum/table_recipe/cakebatter - name = "Cake Batter" - reqs = list( - /datum/reagent/consumable/milk = 5, - /obj/item/weapon/reagent_containers/food/snacks/dough = 1 - ) - result = /obj/item/weapon/reagent_containers/food/snacks/cakebatter - -/datum/table_recipe/cakebatter/alt - reqs = list( - /datum/reagent/consumable/soymilk = 5, - /obj/item/weapon/reagent_containers/food/snacks/dough = 1 - ) - -/datum/table_recipe/piedough - name = "Pie Dough" - reqs = list( - /datum/reagent/consumable/milk = 5, - /obj/item/weapon/reagent_containers/food/snacks/flatdough = 1 - ) - result = /obj/item/weapon/reagent_containers/food/snacks/piedough - -/datum/table_recipe/piedough/alt - reqs = list( - /datum/reagent/consumable/soymilk = 5, - /obj/item/weapon/reagent_containers/food/snacks/flatdough = 1 - ) - -/datum/table_recipe/rawpastrybase - name = "Raw Pastry Base" - reqs = list( - /datum/reagent/consumable/milk = 5, - /obj/item/weapon/reagent_containers/food/snacks/doughslice = 1 - ) - result = /obj/item/weapon/reagent_containers/food/snacks/rawpastrybase - -/datum/table_recipe/rawpastrybase/alt - reqs = list( - /datum/reagent/consumable/soymilk = 5, - /obj/item/weapon/reagent_containers/food/snacks/doughslice = 1 - ) - - - - diff --git a/code/modules/food&drinks/recipes/tablecraft/recipes_meat.dm b/code/modules/food&drinks/recipes/tablecraft/recipes_meat.dm index 1322c7bf8cd..d0855fabe69 100644 --- a/code/modules/food&drinks/recipes/tablecraft/recipes_meat.dm +++ b/code/modules/food&drinks/recipes/tablecraft/recipes_meat.dm @@ -87,6 +87,15 @@ ) result = /obj/item/weapon/reagent_containers/food/snacks/cornedbeef +/datum/table_recipe/bearsteak + name = "Filet migrawr" + reqs = list( + /datum/reagent/consumable/ethanol/manly_dorf = 5, + /obj/item/weapon/reagent_containers/food/snacks/meatsteak/bear = 1, + /obj/item/weapon/lighter/grayscale + ) + result = /obj/item/weapon/reagent_containers/food/snacks/bearsteak + /datum/table_recipe/wingfangchu name = "Wingfangchu" reqs = list( diff --git a/code/modules/food&drinks/recipes/tablecraft/recipes_pie.dm b/code/modules/food&drinks/recipes/tablecraft/recipes_pie.dm index 89793d65b33..56bd20f6b4b 100644 --- a/code/modules/food&drinks/recipes/tablecraft/recipes_pie.dm +++ b/code/modules/food&drinks/recipes/tablecraft/recipes_pie.dm @@ -54,6 +54,15 @@ ) result = /obj/item/weapon/reagent_containers/food/snacks/pie/berryclafoutis +/datum/table_recipe/bearypie + name = "Beary Pie" + reqs = list( + /obj/item/weapon/reagent_containers/food/snacks/pie/plain = 1, + /obj/item/weapon/reagent_containers/food/snacks/grown/berries = 1, + /obj/item/weapon/reagent_containers/food/snacks/meatsteak/bear = 1 + ) + result = /obj/item/weapon/reagent_containers/food/snacks/pie/bearypie + /datum/table_recipe/amanitapie name = "Amanita pie" reqs = list( diff --git a/code/modules/food&drinks/recipes/tablecraft/recipes_sandwich.dm b/code/modules/food&drinks/recipes/tablecraft/recipes_sandwich.dm index 41aa0f936e6..57e1a1f6614 100644 --- a/code/modules/food&drinks/recipes/tablecraft/recipes_sandwich.dm +++ b/code/modules/food&drinks/recipes/tablecraft/recipes_sandwich.dm @@ -52,7 +52,7 @@ name = "Not a sandwich" reqs = list( /obj/item/weapon/reagent_containers/food/snacks/breadslice/plain = 2, - /obj/item/clothing/mask/fakemoustache + /obj/item/clothing/mask/fakemoustache = 1 ) result = /obj/item/weapon/reagent_containers/food/snacks/notasandwich diff --git a/code/modules/holiday/easter.dm b/code/modules/holiday/easter.dm new file mode 100644 index 00000000000..d6cfdca9759 --- /dev/null +++ b/code/modules/holiday/easter.dm @@ -0,0 +1,235 @@ +//Easter start +/datum/holiday/easter/greet() + return "Greetings! Have a Happy Easter and keep an eye out for Easter Bunnies!" + +/datum/round_event_control/easter + name = "Easter Eggselence" + holidayID = EASTER + typepath = /datum/round_event/easter + weight = -1 + max_occurrences = 1 + earliest_start = 0 + +/datum/round_event/easter/announce() + priority_announce(pick("Hip-hop into Easter!","Find some Bunny's stash!","Today is National 'Hunt a Wabbit' Day.","Be kind, give Chocolate Eggs!")) + + +/datum/round_event_control/rabbitrelease + name = "Release the Rabbits!" + typepath = /datum/round_event/rabbitrelease + weight = 5 + max_occurrences = 10 + +/datum/round_event/rabbitrelease/announce() + priority_announce("Unidentified furry objects detected coming aboard [station_name()]. Beware of Adorable-ness.", "Fluffy Alert", 'sound/AI/aliens.ogg') + + +/datum/round_event/rabbitrelease/start() + for(var/obj/effect/landmark/R in landmarks_list) + if(R.name != "blobspawn") + if(prob(35)) + if(istype(R.loc,/turf/space)) + new /mob/living/simple_animal/chicken/rabbit/space(R.loc) + else + new /mob/living/simple_animal/chicken/rabbit(R.loc) + +/mob/living/simple_animal/chicken/rabbit + name = "\improper rabbit" + desc = "The hippiest hop around." + icon = 'icons/mob/Easter.dmi' + icon_state = "rabbit" + icon_living = "rabbit" + icon_dead = "rabbit_dead" + speak = list("Hop into Easter!","Come get your eggs!","Prizes for everyone!") + speak_emote = list("sniffles","twitches") + emote_hear = list("hops.") + emote_see = list("hops around","bounces up and down") + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + egg_type = /obj/item/weapon/reagent_containers/food/snacks/egg/loaded + food_type = /obj/item/weapon/reagent_containers/food/snacks/grown/carrot + meat_amount = 1 + eggsleft = 10 + eggsFertile = FALSE + icon_prefix = "rabbit" + feedMessages = list("It nibbles happily.","It noms happily.") + layMessage = list("hides an egg.","scampers around suspiciously.","begins making a huge racket.","begins shuffling.") + +/mob/living/simple_animal/chicken/rabbit/space + icon_prefix = "s_rabbit" + icon_state = "s_rabbit" + icon_living = "s_rabbit" + icon_dead = "s_rabbit_dead" + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + minbodytemp = 0 + maxbodytemp = 1500 + unsuitable_atmos_damage = 0 //This damage is taken when atmos doesn't fit all the requirements above + +//Easter Baskets +/obj/item/weapon/storage/bag/easterbasket + name = "Easter Basket" + icon = 'icons/mob/Easter.dmi' + icon_state = "basket" + can_hold = list(/obj/item/weapon/reagent_containers/food/snacks/egg,/obj/item/weapon/reagent_containers/food/snacks/chocolateegg,/obj/item/weapon/reagent_containers/food/snacks/boiledegg) + +/obj/item/weapon/storage/bag/easterbasket/proc/countEggs() + overlays.Cut() + overlays += image("icon" = icon, "icon_state" = "basket-grass", "layer" = -1) + overlays += image("icon" = icon, "icon_state" = "basket-egg[contents.len <= 5 ? contents.len : 5]", "layer" = -1) + +/obj/item/weapon/storage/bag/easterbasket/remove_from_storage(obj/item/W as obj, atom/new_location) + ..() + countEggs() + +/obj/item/weapon/storage/bag/easterbasket/handle_item_insertion(obj/item/I, prevent_warning = 0) + ..() + countEggs() + +//Bunny Suit +/obj/item/clothing/head/bunnyhead + name = "Easter Bunny Head" + icon_state = "bunnyhead" + item_state = "bunnyhead" + desc = "Considerably more cute than 'Frank'" + slowdown = -1 + flags = BLOCKHAIR + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE + +/obj/item/clothing/suit/bunnysuit + name = "Easter Bunny Suit" + desc = "Hop Hop Hop!" + icon_state = "bunnysuit" + item_state = "bunnysuit" + slowdown = -1 + body_parts_covered = CHEST|GROIN|LEGS|ARMS + flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + +//Egg prizes and egg spawns! +/obj/item/weapon/reagent_containers/food/snacks/egg + var/containsPrize = FALSE + +/obj/item/weapon/reagent_containers/food/snacks/egg/loaded + containsPrize = TRUE + +/obj/item/weapon/reagent_containers/food/snacks/egg/loaded/New() + ..() + var/color = pick("blue","green","mime","orange","purple","rainbow","red","yellow") + icon_state = "egg-[color]" + item_color = "[color]" + +/obj/item/weapon/reagent_containers/food/snacks/egg/proc/dispensePrize(var/turf/where) + var/won = pick(/obj/item/clothing/head/bunnyhead, + /obj/item/clothing/suit/bunnysuit, + /obj/item/weapon/reagent_containers/food/snacks/grown/carrot, + /obj/item/weapon/reagent_containers/food/snacks/chocolateegg, + /obj/item/toy/balloon, + /obj/item/toy/gun, + /obj/item/toy/sword, + /obj/item/toy/foamblade, + /obj/item/toy/prize/ripley, + /obj/item/toy/prize/honk, + /obj/item/toy/carpplushie, + /obj/item/toy/redbutton, + /obj/item/clothing/head/collectable/rabbitears) + new won(where) + new/obj/item/weapon/reagent_containers/food/snacks/chocolateegg(where) + +/obj/item/weapon/reagent_containers/food/snacks/egg/attack_self(mob/user as mob) + ..() + if(containsPrize) + user << "You unwrap the [src] and find a prize inside!" + dispensePrize(get_turf(user)) + containsPrize = FALSE + qdel(src) + +/obj/effect/spawner/lootdrop/maintenance/New() + ..() + loot += list(/obj/item/weapon/reagent_containers/food/snacks/egg/loaded = 15, /obj/item/weapon/storage/bag/easterbasket = 15) + +//Easter Recipes + food +/obj/item/weapon/reagent_containers/food/snacks/hotcrossbun + bitesize = 2 + name = "hot-cross bun" + desc = "The Cross represents the Assistants that died for your sins." + icon_state = "hotcrossbun" + +/datum/table_recipe/hotcrossbun + name = "Hot-Cross Bun" + reqs = list( + /obj/item/weapon/reagent_containers/food/snacks/store/bread/plain = 1, + /datum/reagent/consumable/sugar = 1 + ) + result = /obj/item/weapon/reagent_containers/food/snacks/hotcrossbun + + +/obj/item/weapon/reagent_containers/food/snacks/store/cake/brioche + name = "brioche cake" + desc = "A ring of sweet, glazed buns." + icon_state = "briochecake" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/cakeslice/brioche + slices_num = 6 + bonus_reagents = list("nutriment" = 10, "vitamin" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/cakeslice/brioche + name = "brioche cake slice" + desc = "Delicious sweet-bread. Who needs anything else?" + icon_state = "briochecake_slice" + filling_color = "#FFD700" + +/datum/table_recipe/briochecake + name = "Brioche cake" + reqs = list( + /obj/item/weapon/reagent_containers/food/snacks/store/cake/plain = 1, + /datum/reagent/consumable/sugar = 2 + ) + result = /obj/item/weapon/reagent_containers/food/snacks/store/cake/brioche + +/obj/item/weapon/reagent_containers/food/snacks/scotchegg + name = "scotch egg" + desc = "A boiled egg wrapped in a delicious, seasoned meatball." + icon_state = "scotchegg" + bonus_reagents = list("nutriment" = 2, "vitamin" = 2) + bitesize = 3 + filling_color = "#FFFFF0" + list_reagents = list("nutriment" = 6) + +/datum/table_recipe/scotchegg + name = "Scotch egg" + reqs = list( + /datum/reagent/consumable/sodiumchloride = 1, + /datum/reagent/consumable/blackpepper = 1, + /obj/item/weapon/reagent_containers/food/snacks/boiledegg = 1, + /obj/item/weapon/reagent_containers/food/snacks/faggot = 1 + ) + result = /obj/item/weapon/reagent_containers/food/snacks/scotchegg + +/obj/item/weapon/reagent_containers/food/snacks/soup/mammi + name = "Mämmi" + desc = "A bowl of mushy bread and milk. It reminds you, not too fondly, of a bowel movement." + icon_state = "mammi" + bonus_reagents = list("nutriment" = 3, "vitamin" = 1) + list_reagents = list("nutriment" = 8, "vitamin" = 1) + +/datum/table_recipe/mammi + name = "Mämmi" + reqs = list( + /obj/item/weapon/reagent_containers/food/snacks/store/bread/plain = 1, + /obj/item/weapon/reagent_containers/food/snacks/chocolatebar = 1, + /datum/reagent/consumable/milk = 5 + ) + result = /obj/item/weapon/reagent_containers/food/snacks/soup/mammi + +/obj/item/weapon/reagent_containers/food/snacks/chocolatebunny + name = "chocolate bunny" + desc = "Contains less than 10% real rabbit!" + icon_state = "chocolatebunny" + bonus_reagents = list("nutriment" = 1, "vitamin" = 1) + list_reagents = list("nutriment" = 4, "sugar" = 2, "cocoa" = 2) + filling_color = "#A0522D" + +/datum/table_recipe/chocolatebunny + name = "Chocolate bunny" + reqs = list( + /datum/reagent/consumable/sugar = 2, + /obj/item/weapon/reagent_containers/food/snacks/chocolatebar = 1 + ) + result = /obj/item/weapon/reagent_containers/food/snacks/chocolatebunny diff --git a/code/modules/holiday/halloween.dm b/code/modules/holiday/halloween.dm index 8850b6e3f4d..1f74c911de0 100644 --- a/code/modules/holiday/halloween.dm +++ b/code/modules/holiday/halloween.dm @@ -234,8 +234,6 @@ maxHealth = 1e6 health = 1e6 emote_see = list("silently stares") - heat_damage_per_tick = 0 - cold_damage_per_tick = 0 unsuitable_atmos_damage = 0 var/timer @@ -288,3 +286,6 @@ visible_message("[src] seems to be resisting the effect!") else ..() + +/mob/living/simple_animal/hostile/retaliate/clown/insane/handle_temperature_damage() + return \ No newline at end of file diff --git a/code/modules/holiday/holidays.dm b/code/modules/holiday/holidays.dm new file mode 100644 index 00000000000..50190ce4e67 --- /dev/null +++ b/code/modules/holiday/holidays.dm @@ -0,0 +1,316 @@ +/datum/holiday + var/name = "Bugsgiving" + //Right now, only holidays that take place on a certain day or within a time period are supported + //It would be nice to support things like "the second monday in march" or "the first sunday after the second sunday in june" + var/begin_day = 1 + var/begin_month = 0 + var/end_day = 0 // Default of 0 means the holiday lasts a single day + var/end_month = 0 + +// This proc gets run before the game starts when the holiday is activated. Do festive shit here. +/datum/holiday/proc/celebrate() + +// When the round starts, this proc is ran to get a text message to display to everyone to wish them a happy holiday +/datum/holiday/proc/greet() + return "Have a happy [name]!" + +// Returns special prefixes for the station name on certain days. You wind up with names like "Christmas Object Epsilon". See new_station_name() +/datum/holiday/proc/getStationPrefix() + //get the first word of the Holiday and use that + var/i = findtext(name," ",1,0) + return copytext(name,1,i) + +// Return 1 if this holidy should be celebrated today +/datum/holiday/proc/shouldCelebrate(dd, mm, yy) + if(!end_day) + end_day = begin_day + if(!end_month) + end_month = begin_month + + if(end_month > begin_month) //holiday spans multiple months in one year + if(mm == end_month) //in final month + if(dd <= end_day) + return 1 + + else if(mm == begin_month)//in first month + if(dd >= begin_day) + return 1 + + else if(mm in begin_month to end_month) //holiday spans 3+ months and we're in the middle, day doesn't matter at all + return 1 + + else if(end_month == begin_month) // starts and stops in same month, simplest case + if(mm == begin_month && (dd in begin_day to end_day)) + return 1 + + else // starts in one year, ends in the next + if(mm >= begin_month && dd >= begin_day) // Holiday ends next year + return 1 + if(mm <= end_month && dd <= end_day) // Holiday started last year + return 1 + + return 0 + +// The actual holidays + +/datum/holiday/new_year + name = NEW_YEAR + begin_day = 30 // 1 day early + begin_month = DECEMBER + end_day = 5 //4 days extra + end_month = JANUARY + +/datum/holiday/groundhog + name = "Groundhog Day" + begin_day = 2 + begin_month = FEBRUARY + +/datum/holiday/valentines + name = VALENTINES + begin_day = 9 //6 days early + begin_month = FEBRUARY + end_day = 15 //1 day extra + +/datum/holiday/random_kindness + name = "Random Acts of Kindness Day" + begin_day = 17 + begin_month = FEBRUARY + +/datum/holiday/random_kindness/greet() + return "Go do some random acts of kindness for a stranger!" //haha yeah right + +/datum/holiday/pi + name = "Pi Day" + begin_day = 14 + begin_month = MARCH + +/datum/holiday/no_this_is_patrick + name = "St. Patrick's Day" + begin_day = 17 + begin_month = MARCH + +/datum/holiday/april_fools + name = APRIL_FOOLS + begin_day = 1 + begin_month = APRIL + end_day = 8 //7 days extra so everyone can enjoy the festivities + +/datum/holiday/fourtwenty + name = "Four-Twenty" + begin_day = 20 + begin_month = APRIL + +/datum/holiday/earth + name = "Earth Day" + begin_day = 22 + begin_month = APRIL + +/datum/holiday/labor + name = "Labor Day" + begin_day = 1 + begin_month = MAY + +/datum/holiday/firefighter + name = "Firefighter's Day" + begin_day = 4 + begin_month = MAY + +// No holidays in June :'( + +/datum/holiday/doctor + name = "Doctor's Day" + begin_day = 1 + begin_month = JULY + +/datum/holiday/UFO + name = "UFO Day" + begin_day = 2 + begin_month = JULY + +/datum/holiday/writer + name = "Writer's Day" + begin_day = 8 + begin_month = JULY + +/datum/holiday/friendship + name = "Friendship Day" + begin_day = 30 + begin_month = JULY + +/datum/holiday/friendship/greet() + return "Have a magical [name]!" + +/datum/holiday/beer + name = "Beer Day" + begin_day = 5 + begin_month = AUGUST + +/datum/holiday/pirate + name = "Talk-Like-a-Pirate Day" + begin_day = 19 + begin_month = SEPTEMBER + +/datum/holiday/pirate/greet() + return "Ye be talkin' like a pirate today or else ye'r walkin' tha plank, matey!" + +/datum/holiday/questions + name = "Stupid-Questions Day" + begin_day = 28 + begin_month = SEPTEMBER + +/datum/holiday/questions/greet() + return "Are you having a happy [name]?" + +/datum/holiday/animal + name = "Animal's Day" + begin_day = 4 + begin_month = OCTOBER + +/datum/holiday/smile + name = "Smiling Day" + begin_day = 7 + begin_month = OCTOBER + +/datum/holiday/boss + name = "Boss' Day" + begin_day = 16 + begin_month = OCTOBER + +/datum/holiday/halloween + name = HALLOWEEN + begin_day = 24 //7 days early + begin_month = OCTOBER + end_day = 7 //7 days extra + end_month = NOVEMBER + +/datum/holiday/halloween/greet() + return "Have a spooky Halloween!" + +/datum/holiday/vegan + name = "Vegan Day" + begin_day = 1 + begin_month = NOVEMBER + +/datum/holiday/kindness + name = "Kindness Day" + begin_day = 13 + begin_month = NOVEMBER + +/datum/holiday/flowers + name = "Flowers Day" + begin_day = 19 + begin_month = NOVEMBER + +/datum/holiday/hello + name = "Saying-'Hello' Day" + begin_day = 21 + begin_month = NOVEMBER + +/datum/holiday/hello/greet() + return "[pick(list("Aloha", "Bonjour", "Hello", "Hi", "Greetings", "Salutations", "Bienvenidos", "Hola", "Howdy"))]! " + ..() + +/datum/holiday/human_rights + name = "Human-Rights Day" + begin_day = 10 + begin_month = DECEMBER + +/datum/holiday/monkey + name = "Monkey Day" + begin_day = 14 + begin_month = DECEMBER + +/datum/holiday/xmas + name = CHRISTMAS + begin_day = 18 //7 days early + begin_month = DECEMBER + end_day = 8 //14 days extra, christmas is important + end_month = JANUARY + +/datum/holiday/xmas/greet() + return "Have a merry Christmas!" + +/datum/holiday/boxing + name = "Boxing Day" + begin_day = 26 + begin_month = DECEMBER + +/datum/holiday/friday_thirteenth + name = "Friday the 13th" + +/datum/holiday/friday_thirteenth/shouldCelebrate(dd, mm, yy) + if(dd == 13) + if(time2text(world.timeofday, "DDD") == "Fri") + return 1 + return 0 + +/datum/holiday/friday_thirteenth/getStationPrefix() + return pick("Mike","Friday","Evil","Myers","Murder","Deathly","Stabby") + +/datum/holiday/easter + name = EASTER + var/const/days_early = 1 //to make editing the holiday easier + var/const/days_extra = 6 + +/datum/holiday/easter/shouldCelebrate(dd, mm, yy) +// Easter's celebration day is as snowflakey as Uhangi's code + + if(!begin_month) + + var/yy_string = "[yy]" +// year = days after March 22that Easter falls on that year. +// For 2015 Easter is on April 5th, so 2015 = 14 since the 5th is 14 days past the 22nd +// If it's 2040 and this is still in use, invent a time machine and teach me a better way to do this. Also tell us about HL3. + var/list/easters = list( + "15" = 14,\ + "16" = 6,\ + "17" = 25,\ + "18" = 10,\ + "19" = 30,\ + "20" = 22,\ + "21" = 13,\ + "22" = 26,\ + "23" = 18,\ + "24" = 9,\ + "25" = 29,\ + "26" = 14,\ + "27" = 6,\ + "28" = 25,\ + "29" = 10,\ + "30" = 30,\ + "31" = 23,\ + "32" = 6,\ + "33" = 26,\ + "34" = 18,\ + "35" = 3,\ + "36" = 22,\ + "37" = 14,\ + "38" = 34,\ + "39" = 19,\ + "40" = 9,\ + ) + + begin_day = easters[yy_string] + if(begin_day <= 9) + begin_day += 22 + begin_month = MARCH + else + begin_day -= 9 + begin_month = APRIL + + end_day = begin_day + days_extra + end_month = begin_month + if(end_day >= 32 && end_month == MARCH) //begins in march, ends in april + end_day -= 31 + end_month++ + if(end_day >= 31 && end_month == APRIL) //begins in april, ends in june + end_day -= 30 + end_month++ + + begin_day -= days_early + if(begin_day <= 0) + if(begin_month == APRIL) + begin_day += 31 + begin_month-- //begins in march, ends in april + +// world << "Easter calculates to be on [begin_day] of [begin_month] ([days_early] early) to [end_day] of [end_month] ([days_extra] extra) for 20[yy]" + return ..() \ No newline at end of file diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index 66ff37b9a56..7b33f64ab76 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -148,7 +148,7 @@ /obj/item/weapon/reagent_containers/food/snacks/grown/poppy/add_juice() if(..()) reagents.add_reagent("nutriment", 1 + round((potency / 20), 1)) - reagents.add_reagent("hotline", 3 + round((potency / 10), 1)) + reagents.add_reagent("salglu_solution", 1 + round((potency / 20), 1)) bitesize = 1 + round(reagents.total_volume / 3, 1) /obj/item/weapon/reagent_containers/food/snacks/grown/poppy/lily @@ -619,6 +619,7 @@ name = "mimana" desc = "It's an excellent prop for a mime." icon_state = "mimana" + trash = /obj/item/weapon/grown/bananapeel/mimanapeel filling_color = "#FFFFEE" /obj/item/weapon/reagent_containers/food/snacks/grown/mimana/add_juice() @@ -650,7 +651,7 @@ /obj/item/weapon/reagent_containers/food/snacks/grown/icepepper seed = /obj/item/seeds/icepepperseed - name = "ice-pepper" + name = "ice pepper" desc = "It's a mutant strain of chili" icon_state = "icepepper" filling_color = "#0000CD" @@ -665,7 +666,7 @@ /obj/item/weapon/reagent_containers/food/snacks/grown/icepepper/attackby(var/obj/item/O as obj, var/mob/user as mob, params) . = ..() if (istype(O, /obj/item/device/analyzer/plant_analyzer)) - user << "- Frostoil: [reagents.get_reagent_amount("frostoil")]%" + user << "- Frost Oil: [reagents.get_reagent_amount("frostoil")]%" /obj/item/weapon/reagent_containers/food/snacks/grown/ghost_chili @@ -969,6 +970,9 @@ obj/item/weapon/reagent_containers/food/snacks/grown/shell/eggy/add_juice() GT.amount = GT.max_amount else GT.amount = grassAmt + for(var/obj/item/stack/tile/grass/GR in user.loc) + if(GR != GT && GR.amount < GR.max_amount) + GR.attackby(GT, user) //we try to transfer all old unfinished stacks to the new stack we created. grassAmt -= GT.max_amount qdel(src) return @@ -991,6 +995,9 @@ obj/item/weapon/reagent_containers/food/snacks/grown/shell/eggy/add_juice() CT.amount = CT.max_amount else CT.amount = carpetAmt + for(var/obj/item/stack/tile/carpet/CA in user.loc) + if(CA != CT && CA.amount < CA.max_amount) + CA.attackby(CT, user) //we try to transfer all old unfinished stacks to the new stack we created. carpetAmt -= CT.max_amount qdel(src) return @@ -1024,6 +1031,8 @@ obj/item/weapon/reagent_containers/food/snacks/grown/shell/eggy/add_juice() reagents.add_reagent("oculine", 3+round(potency / 5, 1)) bitesize = 1 + round(reagents.total_volume / 2, 1) +/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom + name = "mushroom" /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/reishi seed = /obj/item/seeds/reishimycelium diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm index 27c3ff1d38e..f3993846124 100644 --- a/code/modules/hydroponics/growninedible.dm +++ b/code/modules/hydroponics/growninedible.dm @@ -4,7 +4,7 @@ /obj/item/weapon/grown // Grown weapons name = "grown_weapon" - icon = 'icons/obj/weapons.dmi' + icon = 'icons/obj/hydroponics/harvest.dmi' var/seed = null var/plantname = "" var/product //a type path @@ -45,7 +45,6 @@ seed = /obj/item/seeds/towermycelium name = "tower-cap log" desc = "It's better than bad, it's good!" - icon = 'icons/obj/hydroponics/harvest.dmi' icon_state = "logs" force = 5 throwforce = 5 @@ -55,6 +54,8 @@ plant_type = 2 origin_tech = "materials=1" attack_verb = list("bashed", "battered", "bludgeoned", "whacked") + var/plank_type = /obj/item/stack/sheet/mineral/wood + var/plank_name = "wooden planks" var/list/accepted = list(/obj/item/weapon/reagent_containers/food/snacks/grown/tobacco, /obj/item/weapon/reagent_containers/food/snacks/grown/tobacco/space, /obj/item/weapon/reagent_containers/food/snacks/grown/tea/aspera, @@ -67,19 +68,16 @@ /obj/item/weapon/grown/log/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if(istype(W, /obj/item/weapon/circular_saw) || istype(W, /obj/item/weapon/hatchet) || (istype(W, /obj/item/weapon/twohanded/fireaxe) && W:wielded) || istype(W, /obj/item/weapon/melee/energy)) - user.show_message("You make planks out of \the [src]!", 1) - for(var/i = 0,i < 2,i++) - var/obj/item/stack/sheet/mineral/wood/NG = new (user.loc) - for (var/obj/item/stack/sheet/mineral/wood/G in user.loc) - if(G == NG) - continue - if(G.amount >= G.max_amount) - continue - G.amount += round(potency / 25) - G.attackby(NG, user) - usr << "You add the newly-formed wood to the stack. It now contains [NG.amount] planks." + user.show_message("You make [plank_name] out of \the [src]!", 1) + var/obj/item/stack/plank = new plank_type(user.loc, 1 + round(potency / 25)) + var/old_plank_amount = plank.amount + for(var/obj/item/stack/ST in user.loc) + if(ST != plank && istype(ST, plank_type) && ST.amount < ST.max_amount) + ST.attackby(plank, user) //we try to transfer all old unfinished stacks to the new stack we created. + if(plank.amount > old_plank_amount) + user << "You add the newly-formed [plank_name] to the stack. It now contains [plank.amount] [plank_name]." qdel(src) - return + if(is_type_in_list(W,accepted)) var/obj/item/weapon/reagent_containers/food/snacks/grown/leaf = W if(leaf.dry) @@ -93,11 +91,19 @@ else usr << " You must dry this first." +/obj/item/weapon/grown/log/steel + seed = /obj/item/seeds/steelmycelium + name = "steel-cap log" + desc = "It's made of metal." + icon_state = "steellogs" + accepted = list() + plank_type = /obj/item/stack/rods + plank_name = "rods" + /obj/item/weapon/grown/sunflower // FLOWER POWER! seed = /obj/item/seeds/sunflowerseed name = "sunflower" desc = "It's beautiful! A certain person might beat you to death if you trample these." - icon = 'icons/obj/hydroponics/harvest.dmi' icon_state = "sunflower" damtype = "fire" force = 0 @@ -116,7 +122,6 @@ seed = /obj/item/seeds/novaflowerseed name = "novaflower" desc = "These beautiful flowers have a crisp smokey scent, like a summer bonfire." - icon = 'icons/obj/hydroponics/harvest.dmi' icon_state = "novaflower" damtype = "fire" force = 0 @@ -217,7 +222,7 @@ /obj/item/weapon/grown/nettle/death seed = /obj/item/seeds/deathnettleseed name = "deathnettle" - desc = "The glowing \black nettle incites rage\black in you just from looking at it!" + desc = "The glowing \black nettle incites rage\black in you just from looking at it!" icon_state = "deathnettle" force = 30 throwforce = 15 @@ -288,7 +293,6 @@ /obj/item/weapon/grown/corncob name = "corn cob" desc = "A reminder of meals gone by." - icon = 'icons/obj/hydroponics/harvest.dmi' icon_state = "corncob" item_state = "corncob" w_class = 1.0 @@ -308,7 +312,6 @@ /obj/item/weapon/grown/snapcorn name = "snap corn" desc = "A cob with snap pops" - icon = 'icons/obj/hydroponics/harvest.dmi' icon_state = "snapcorn" item_state = "corncob" w_class = 1.0 diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index e5d6f4c5d53..7294b806112 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -845,7 +845,9 @@ obj/machinery/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob, p podman.ckey = ckey_holder podman.gender = blood_gender podman.faction |= factions - hardset_dna(podman,null,null,podman.real_name,blood_type,/datum/species/plant/pod)//Discard SE's and UI's, podman cloning is inaccurate, and always make them a podman + if(!mutant_color) + mutant_color = "#59CE00" + hardset_dna(podman,null,null,podman.real_name,blood_type,/datum/species/plant/pod,mutant_color)//Discard SE's and UI's, podman cloning is inaccurate, and always make them a podman podman.set_cloned_appearance() else //else, one packet of seeds. maybe two diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm index 287a8e398e2..4c42141cd91 100644 --- a/code/modules/hydroponics/seeds.dm +++ b/code/modules/hydroponics/seeds.dm @@ -90,6 +90,7 @@ var/datum/mind/mind = null var/blood_gender = null var/blood_type = null + var/mutant_color = null var/factions = null var/contains_sample = 0 @@ -103,6 +104,7 @@ realName = bloodSample.data["real_name"] blood_gender = bloodSample.data["gender"] blood_type = bloodSample.data["blood_type"] + mutant_color = bloodSample.data["mutant_color"] factions = bloodSample.data["factions"] W.reagents.clear_reagents() user << "You inject the contents of the syringe into the seeds." @@ -475,11 +477,11 @@ growthstages = 4 /obj/item/seeds/icepepperseed - name = "pack of ice-pepper seeds" - desc = "These seeds grow into ice-pepper plants." + name = "pack of ice pepper seeds" + desc = "These seeds grow into ice pepper plants." icon_state = "seed-icepepper" species = "chiliice" - plantname = "Ice-Pepper Plants" + plantname = "Ice Pepper Plants" product = /obj/item/weapon/reagent_containers/food/snacks/grown/icepepper lifespan = 25 endurance = 15 @@ -548,7 +550,7 @@ desc = "These may, or may not, grow into oat." icon_state = "seed-oat" species = "oat" - plantname = "oat Stalks" + plantname = "Oat Stalks" product = /obj/item/weapon/reagent_containers/food/snacks/grown/oat lifespan = 25 endurance = 15 @@ -565,7 +567,7 @@ desc = "These may, or may not, grow into rice." icon_state = "seed-rice" species = "rice" - plantname = "rice Stalks" + plantname = "Rice Stalks" product = /obj/item/weapon/reagent_containers/food/snacks/grown/rice lifespan = 25 endurance = 15 @@ -719,11 +721,11 @@ /obj/item/seeds/steelmycelium name = "pack of steel-cap mycelium" - desc = "This mycelium grows into metal rods." + desc = "This mycelium grows into steel logs." icon_state = "mycelium-steelcap" species = "steelcap" plantname = "Steel Caps" - product = /obj/item/stack/rods + product = /obj/item/weapon/grown/log/steel lifespan = 80 endurance = 50 maturation = 15 diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index 2e10f1d241b..2bc127de6db 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -162,6 +162,9 @@ var/global/list/datum/cachedbook/cachedbooks // List of our cached book datums name = "book inventory management console" var/arcanecheckout = 0 screenstate = 0 // 0 - Main Menu, 1 - Inventory, 2 - Checked Out, 3 - Check Out a Book + verb_say = "beeps" + verb_ask = "beeps" + verb_exclaim = "beeps" var/buffer_book var/buffer_mob var/upload_category = "Fiction" @@ -430,11 +433,6 @@ var/global/list/datum/cachedbook/cachedbooks // List of our cached book datums src.updateUsrDialog() return -/obj/machinery/computer/libraryconsole/bookmanagement/say_quote(text) - return "flashes, \"[text]\"" - - - /* * Library Scanner */ diff --git a/code/modules/mining/equipment_locker.dm b/code/modules/mining/equipment_locker.dm index 4ce35c8a06e..59845e2bff9 100644 --- a/code/modules/mining/equipment_locker.dm +++ b/code/modules/mining/equipment_locker.dm @@ -171,6 +171,8 @@ if(out.amount >= 1) inp.amount -= out.amount unload_mineral(out) + if(inp.amount < 1) + stack_list -= text2path(href_list["release"]) else usr << "Required access not found." if(href_list["plasteel"]) @@ -239,6 +241,7 @@ new /datum/data/mining_equipment("Alien Toy", /obj/item/clothing/mask/facehugger/toy, 300), new /datum/data/mining_equipment("Advanced Scanner", /obj/item/device/t_scanner/adv_mining_scanner, 400), new /datum/data/mining_equipment("Mining Drone", /mob/living/simple_animal/hostile/mining_drone, 500), + new /datum/data/mining_equipment("GAR mesons", /obj/item/clothing/glasses/meson/gar, 500), new /datum/data/mining_equipment("Kinetic Accelerator", /obj/item/weapon/gun/energy/kinetic_accelerator, 750), new /datum/data/mining_equipment("Resonator", /obj/item/weapon/resonator, 800), new /datum/data/mining_equipment("Lazarus Injector", /obj/item/weapon/lazarus_injector, 1000), @@ -579,14 +582,7 @@ mouse_opacity = 1 faction = list("neutral") a_intent = "harm" - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 wander = 0 idle_vision_range = 5 @@ -628,7 +624,7 @@ return ..() -/mob/living/simple_animal/hostile/mining_drone/Die() +/mob/living/simple_animal/hostile/mining_drone/death() ..() visible_message("[src] is destroyed!") new /obj/effect/decal/cleanable/robot_debris(src.loc) diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index 73374998632..50633e0c792 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -38,17 +38,22 @@ points = 1 refined_type = /obj/item/stack/sheet/glass -/obj/item/weapon/ore/glass/attack_self(mob/living/user as mob) //It's magic I ain't gonna explain how instant conversion with no tool works. -- Urist +/obj/item/weapon/ore/glass/attack_self(mob/living/user as mob) user << "You use the sand to make sandstone." - for(var/i = 0,i < 1,i++) - var/obj/item/stack/sheet/mineral/sandstone/S = new (user.loc) - for (var/obj/item/weapon/ore/glass/G in user.loc) - if(S.amount < S.max_amount) - S.amount++ - qdel(G) - else - i-- - break + var/sandAmt = 1 + for(var/obj/item/weapon/ore/glass/G in user.loc) // The sand on the floor + sandAmt += 1 + qdel(G) + while(sandAmt > 0) + var/obj/item/stack/sheet/mineral/sandstone/SS = new /obj/item/stack/sheet/mineral/sandstone(user.loc) + if(sandAmt >= SS.max_amount) + SS.amount = SS.max_amount + else + SS.amount = sandAmt + for(var/obj/item/stack/sheet/mineral/sandstone/SA in user.loc) + if(SA != SS && SA.amount < SA.max_amount) + SA.attackby(SS, user) //we try to transfer all old unfinished stacks to the new stack we created. + sandAmt -= SS.max_amount qdel(src) return diff --git a/code/modules/mob/dead/observer/say.dm b/code/modules/mob/dead/observer/say.dm index 039a69b6e9e..bab94a00cac 100644 --- a/code/modules/mob/dead/observer/say.dm +++ b/code/modules/mob/dead/observer/say.dm @@ -16,7 +16,7 @@ . = src.say_dead(message) -/mob/dead/observer/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq) +/mob/dead/observer/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans) if(radio_freq) var/atom/movable/virtualspeaker/V = speaker speaker = V.source diff --git a/code/modules/mob/interactive.dm b/code/modules/mob/interactive.dm index 243534fb3c8..c7d0cd73725 100644 --- a/code/modules/mob/interactive.dm +++ b/code/modules/mob/interactive.dm @@ -131,7 +131,7 @@ zone_sel.selecting = "chest" if(prob(10)) //my x is augmented //arms - if(prob(rand(FUZZY_CHANCE_LOW,FUZZY_CHANCE_HIGH))) + if(prob((FUZZY_CHANCE_LOW+FUZZY_CHANCE_HIGH)/2)) var/obj/item/organ/limb/r_arm/R = locate(/obj/item/organ/limb/r_arm) in organs del(R) organs += new /obj/item/organ/limb/robot/r_arm @@ -140,7 +140,7 @@ del(L) organs += new /obj/item/organ/limb/robot/l_arm //legs - if(prob(rand(FUZZY_CHANCE_LOW,FUZZY_CHANCE_HIGH))) + if(prob((FUZZY_CHANCE_LOW+FUZZY_CHANCE_HIGH)/2)) var/obj/item/organ/limb/r_leg/R = locate(/obj/item/organ/limb/r_leg) in organs del(R) organs += new /obj/item/organ/limb/robot/r_leg @@ -149,7 +149,7 @@ del(L) organs += new /obj/item/organ/limb/robot/l_leg //chest and head - if(prob(rand(FUZZY_CHANCE_LOW,FUZZY_CHANCE_HIGH))) + if(prob((FUZZY_CHANCE_LOW+FUZZY_CHANCE_HIGH)/2)) var/obj/item/organ/limb/chest/R = locate(/obj/item/organ/limb/chest) in organs del(R) organs += new /obj/item/organ/limb/robot/chest @@ -341,14 +341,14 @@ //---------TOOLS if(istype(TARGET, /obj/item/weapon)) var/obj/item/weapon/W = TARGET - if(W.force >= best_force || prob(rand(FUZZY_CHANCE_LOW,FUZZY_CHANCE_HIGH))) + if(W.force >= best_force || prob((FUZZY_CHANCE_LOW+FUZZY_CHANCE_HIGH)/2)) if(!l_hand || !r_hand) take_to_slot(W) else insert_into_backpack() //---------FASHION if(istype(TARGET,/obj/item/clothing)) - if(prob(rand(FUZZY_CHANCE_LOW,FUZZY_CHANCE_HIGH))) + if(prob((FUZZY_CHANCE_LOW+FUZZY_CHANCE_HIGH)/2)) if(!l_hand || !r_hand) var/obj/item/clothing/C = TARGET take_to_slot(C) @@ -395,15 +395,15 @@ if(nearby.len > 4) //i'm crowded, time to leave TARGET = pick(target_filter(orange(MAX_RANGE_FIND,src))) - else if(prob(rand(FUZZY_CHANCE_LOW,FUZZY_CHANCE_HIGH))) + else if(prob((FUZZY_CHANCE_LOW+FUZZY_CHANCE_HIGH)/2)) //chance to chase an item TARGET = locate(/obj/item) in orange(MIN_RANGE_FIND,src) - else if(prob(rand(FUZZY_CHANCE_LOW,FUZZY_CHANCE_HIGH))) + else if(prob((FUZZY_CHANCE_LOW+FUZZY_CHANCE_HIGH)/2)) //chance to leave TARGET = locate(/obj/machinery/door) in orange(MIN_RANGE_FIND,src) // this is a sort of fix for the current pathing. else //else, target whatever, or go to our department - if(prob(rand(FUZZY_CHANCE_LOW,FUZZY_CHANCE_HIGH))) + if(prob((FUZZY_CHANCE_LOW+FUZZY_CHANCE_HIGH)/2)) TARGET = pick(target_filter(orange(MIN_RANGE_FIND,src))) else TARGET = pick(get_area_turfs(job2area(myjob))) diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index cba4f274cf5..da83251d5ce 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -5,14 +5,14 @@ /mob/living/carbon/alien name = "alien" voice_name = "alien" - say_message = "hisses" icon = 'icons/mob/alien.dmi' gender = NEUTER dna = null faction = list("alien") ventcrawler = 2 languages = ALIEN - nightvision = 1 + verb_say = "hisses" + var/nightvision = 1 var/storedPlasma = 250 var/max_plasma = 500 @@ -50,7 +50,7 @@ /mob/living/carbon/alien/proc/getPlasma() return storedPlasma -/mob/living/carbon/alien/eyecheck() +/mob/living/carbon/alien/check_eye_prot() return 2 /mob/living/carbon/alien/getToxLoss() @@ -185,7 +185,7 @@ Des: Gives the client of the alien an image on each infected mob. if (client) for (var/mob/living/C in mob_list) if(C.status_flags & XENO_HOST) - var/obj/item/alien_embryo/A = locate() in C + var/obj/item/body_egg/alien_embryo/A = locate() in C var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[A.stage]") client.images += I return diff --git a/code/modules/mob/living/carbon/alien/alien_defense.dm b/code/modules/mob/living/carbon/alien/alien_defense.dm index bb032d309ef..51e086ae669 100644 --- a/code/modules/mob/living/carbon/alien/alien_defense.dm +++ b/code/modules/mob/living/carbon/alien/alien_defense.dm @@ -76,3 +76,11 @@ In all, this is a lot like the monkey code. /N adjustBruteLoss(damage) updatehealth() +/mob/living/carbon/alien/attack_slime(mob/living/simple_animal/slime/M as mob) + if(..()) //successful slime attack + var/damage = rand(5, 35) + if(M.is_adult) + damage = rand(10, 40) + adjustBruteLoss(damage) + add_logs(M, src, "attacked", admin=0) + updatehealth() diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index 50f8ed4b4a1..337f05ebbff 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -7,7 +7,6 @@ var/leap_on_click = 0 var/pounce_cooldown = 0 var/pounce_cooldown_time = 30 - update_icon = 1 //This is fine right now, if we're adding organ specific damage this needs to be updated /mob/living/carbon/alien/humanoid/New() @@ -28,16 +27,6 @@ if(l_store) l_store.emp_act(severity) ..() -/mob/living/carbon/alien/humanoid/attack_slime(mob/living/carbon/slime/M as mob) - ..() - var/damage = rand(5, 35) - if(M.is_adult) - damage = rand(10, 40) - adjustBruteLoss(damage) - add_logs(M, src, "attacked", admin=0) - updatehealth() - return - /mob/living/carbon/alien/humanoid/attack_hulk(mob/living/carbon/human/user) if(user.a_intent == "harm") ..(user, 1) diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm index a42e347ac21..e1aae3cc6e2 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm @@ -74,7 +74,7 @@ icon = 'icons/mob/alienqueen.dmi' icon_state = "queen_s" pixel_x = -16 - mob_size = 2 + mob_size = MOB_SIZE_LARGE /mob/living/carbon/alien/humanoid/queen/large/update_icons() update_hud() //TODO: remove the need for this to be here diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm index 6bdcbb4307d..c560c3d7f3e 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -3,7 +3,7 @@ real_name = "alien larva" icon_state = "larva0" pass_flags = PASSTABLE | PASSMOB - mob_size = 0 + mob_size = MOB_SIZE_SMALL maxHealth = 25 health = 25 @@ -38,17 +38,6 @@ /mob/living/carbon/alien/larva/attack_ui(slot_id) return -/mob/living/carbon/alien/larva/attack_slime(mob/living/carbon/slime/M as mob) - - ..() - var/damage = rand(5, 35) - if(M.is_adult) - damage = rand(20, 40) - adjustBruteLoss(damage) - add_logs(M, src, "attacked", admin=0) - updatehealth() - return - /mob/living/carbon/alien/larva/attack_hulk(mob/living/carbon/human/user) if(user.a_intent == "harm") ..(user, 1) diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm index 248333825ae..4df5469296f 100644 --- a/code/modules/mob/living/carbon/alien/life.dm +++ b/code/modules/mob/living/carbon/alien/life.dm @@ -31,25 +31,21 @@ handle_breath_temperature(breath) -/mob/living/carbon/alien/handle_regular_status_updates() +/mob/living/carbon/alien/handle_status_effects() ..() //natural reduction of movement delay due to stun. if(move_delay_add > 0) move_delay_add = max(0, move_delay_add - rand(1, 2)) - return 1 +/mob/living/carbon/alien/update_sight() -/mob/living/carbon/alien/handle_vision() - - client.screen.Remove(global_hud.blurry, global_hud.druggy, global_hud.vimpaired, global_hud.darkMask) - - if (stat == 2) + if(stat == DEAD) sight |= SEE_TURFS sight |= SEE_MOBS sight |= SEE_OBJS see_in_dark = 8 see_invisible = SEE_INVISIBLE_LEVEL_TWO - else if (stat != 2) + else sight |= SEE_MOBS sight &= ~SEE_TURFS sight &= ~SEE_OBJS @@ -62,40 +58,8 @@ if(see_override) see_invisible = see_override - if ((blind && stat != 2)) - if((eye_blind)) - blind.layer = 18 - else - blind.layer = 0 - - if (disabilities & NEARSIGHT) - client.screen += global_hud.vimpaired - - if (eye_blurry) - client.screen += global_hud.blurry - - if (druggy) - client.screen += global_hud.druggy - - if (stat != 2) - if(machine) - if (!( machine.check_eye(src) )) - reset_view(null) - else - if(!client.adminobs) - reset_view(null) - - /mob/living/carbon/alien/handle_hud_icons() handle_hud_icons_health() - if(pullin) - if(pulling) - pullin.icon_state = "pull" - else - pullin.icon_state = "pull0" - - - return 1 diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm index 19d37221c19..d7c223124b6 100644 --- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm +++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm @@ -2,50 +2,11 @@ // It functions almost identically (see code/datums/diseases/alien_embryo.dm) var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds -/obj/item/alien_embryo +/obj/item/body_egg/alien_embryo name = "alien embryo" - desc = "All slimy and yuck." - icon = 'icons/mob/alien.dmi' - icon_state = "larva0_dead" - var/mob/living/affected_mob var/stage = 0 -/obj/item/alien_embryo/New() - if(istype(loc, /mob/living)) - affected_mob = loc - affected_mob.status_flags |= XENO_HOST - SSobj.processing |= src - if(istype(affected_mob,/mob/living/carbon)) - var/mob/living/carbon/H = affected_mob - H.med_hud_set_status() - spawn(0) - AddInfectionImages(affected_mob) - else - qdel(src) - -/obj/item/alien_embryo/Destroy() - if(affected_mob) - affected_mob.status_flags &= ~(XENO_HOST) - if(istype(affected_mob,/mob/living/carbon)) - var/mob/living/carbon/H = affected_mob - H.med_hud_set_status() - spawn(0) - RemoveInfectionImages(affected_mob) - ..() - -/obj/item/alien_embryo/process() - if(!affected_mob) return - if(loc != affected_mob) - affected_mob.status_flags &= ~(XENO_HOST) - SSobj.processing.Remove(src) - if(istype(affected_mob,/mob/living/carbon)) - var/mob/living/carbon/H = affected_mob - H.med_hud_set_status() - spawn(0) - RemoveInfectionImages(affected_mob) - affected_mob = null - return - +/obj/item/body_egg/alien_embryo/egg_process() if(stage < 5 && prob(3)) stage++ spawn(0) @@ -87,7 +48,9 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds if(prob(50)) AttemptGrow() -/obj/item/alien_embryo/proc/AttemptGrow(var/gib_on_success = 1) + + +/obj/item/body_egg/alien_embryo/proc/AttemptGrow(var/gib_on_success = 1) var/list/candidates = get_candidates(BE_ALIEN, ALIEN_AFK_BRACKET) var/client/C = null @@ -123,7 +86,7 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds Proc: RefreshInfectionImage() Des: Removes the current icons located in the infected mob adds the current stage ----------------------------------------*/ -/obj/item/alien_embryo/proc/RefreshInfectionImage() +/obj/item/body_egg/alien_embryo/RefreshInfectionImage() RemoveInfectionImages() AddInfectionImages() @@ -131,7 +94,7 @@ Des: Removes the current icons located in the infected mob adds the current stag Proc: AddInfectionImages(C) Des: Adds the infection image to all aliens for this embryo ----------------------------------------*/ -/obj/item/alien_embryo/proc/AddInfectionImages() +/obj/item/body_egg/alien_embryo/AddInfectionImages() for(var/mob/living/carbon/alien/alien in player_list) if(alien.client) var/I = image('icons/mob/alien.dmi', loc = affected_mob, icon_state = "infected[stage]") @@ -141,7 +104,7 @@ Des: Adds the infection image to all aliens for this embryo Proc: RemoveInfectionImage(C) Des: Removes all images from the mob infected by this embryo ----------------------------------------*/ -/obj/item/alien_embryo/proc/RemoveInfectionImages() +/obj/item/body_egg/alien_embryo/RemoveInfectionImages() for(var/mob/living/carbon/alien/alien in player_list) if(alien.client) for(var/image/I in alien.client.images) diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm index 6749b8d2108..a4c27b35cf4 100644 --- a/code/modules/mob/living/carbon/alien/special/facehugger.dm +++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm @@ -48,11 +48,11 @@ var/const/MAX_ACTIVE_TIME = 400 return switch(stat) if(DEAD,UNCONSCIOUS) - user << "[src] is not moving." + user << "[src] is not moving." if(CONSCIOUS) - user << "[src] seems to be active!" + user << "[src] seems to be active!" if (sterile) - user << "It looks like the proboscis has been removed." + user << "It looks like the proboscis has been removed." /obj/item/clothing/mask/facehugger/attackby(var/obj/item/O,var/mob/m, params) if(O.force) @@ -115,7 +115,7 @@ var/const/MAX_ACTIVE_TIME = 400 if(loc == L) return 0 if(stat != CONSCIOUS) return 0 - if(locate(/obj/item/alien_embryo) in L) return 0 + if(locate(/obj/item/body_egg/alien_embryo) in L) return 0 if(!sterile) L.take_organ_damage(strength,0) //done here so that even borgs and humans in helmets take damage L.visible_message("[src] leaps at [L]'s face!", \ @@ -145,7 +145,7 @@ var/const/MAX_ACTIVE_TIME = 400 if(!sterile) L.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings else if (iscorgi(M)) - var/mob/living/simple_animal/corgi/C = M + var/mob/living/simple_animal/pet/corgi/C = M loc = C C.facehugger = src @@ -174,11 +174,11 @@ var/const/MAX_ACTIVE_TIME = 400 icon_state = "[initial(icon_state)]_impregnated" if(!target.getlimb(/obj/item/organ/limb/robot/chest) && !(target.status_flags & XENO_HOST)) - new /obj/item/alien_embryo(target) + new /obj/item/body_egg/alien_embryo(target) if(iscorgi(target)) - var/mob/living/simple_animal/corgi/C = target + var/mob/living/simple_animal/pet/corgi/C = target src.loc = get_turf(C) C.facehugger = null else @@ -223,7 +223,7 @@ var/const/MAX_ACTIVE_TIME = 400 icon_state = "[initial(icon_state)]_dead" stat = DEAD - src.visible_message("[src] curls up into a ball!") + visible_message("[src] curls up into a ball!") return diff --git a/code/modules/mob/living/carbon/brain/death.dm b/code/modules/mob/living/carbon/brain/death.dm index 51b17b8e7fa..05cc69ba948 100644 --- a/code/modules/mob/living/carbon/brain/death.dm +++ b/code/modules/mob/living/carbon/brain/death.dm @@ -1,8 +1,8 @@ /mob/living/carbon/brain/death(gibbed) if(stat == DEAD) return if(!gibbed && container && istype(container, /obj/item/device/mmi))//If not gibbed but in a container. - for(var/mob/O in viewers(container, null)) - O.show_message(text("[]'s MMI flatlines!", src), 1, "You hear something flatline.", 2) + container.visible_message("[src]'s MMI flatlines!", \ + "You hear something flatline.") if(istype(src,/obj/item/organ/brain/alien)) container.icon_state = "mmi_alien_dead" else diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm index 0f1ef27541f..be2b01d8732 100644 --- a/code/modules/mob/living/carbon/brain/life.dm +++ b/code/modules/mob/living/carbon/brain/life.dm @@ -64,10 +64,7 @@ death() eye_blind = max(eye_blind, 1) silent = 0 - return 1 - if(health < config.health_threshold_crit) - stat = UNCONSCIOUS - eye_blind = max(eye_blind, 1) + return else stat = CONSCIOUS @@ -124,8 +121,13 @@ else eye_blind = 0 - return 1 + return 1 +/mob/living/carbon/brain/handle_disabilities() + return + +/mob/living/carbon/brain/handle_status_effects() + return /mob/living/carbon/brain/handle_regular_hud_updates() diff --git a/code/modules/mob/living/carbon/brain/say.dm b/code/modules/mob/living/carbon/brain/say.dm index a5bb0a956d5..ac45baaf338 100644 --- a/code/modules/mob/living/carbon/brain/say.dm +++ b/code/modules/mob/living/carbon/brain/say.dm @@ -9,11 +9,11 @@ message = Gibberish(message, (emp_damage*6))//scrambles the message, gets worse when emp_damage is higher ..() -/mob/living/carbon/brain/radio(message, message_mode) +/mob/living/carbon/brain/radio(message, message_mode, list/spans) if(message_mode && istype(container, /obj/item/device/mmi/radio_enabled)) var/obj/item/device/mmi/radio_enabled/R = container if(R.radio) - R.radio.talk_into(src, message) + R.radio.talk_into(src, message, , spans) return ITALICS | REDUCE_RANGE /mob/living/carbon/brain/lingcheck() diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index a9b1f519542..22a879adae3 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -86,6 +86,8 @@ "You feel a powerful shock coursing through your body!", \ "You hear a heavy electrical crack." \ ) + if(prob(25) && heart_attack) + heart_attack = 0 jitteriness += 1000 //High numbers for violent convulsions do_jitter_animation(jitteriness) stuttering += 2 @@ -133,8 +135,6 @@ else mode() // Activate held item - - /mob/living/carbon/proc/help_shake_act(mob/living/carbon/M) if(health >= 0) @@ -154,8 +154,48 @@ playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) +/mob/living/carbon/flash_eyes(intensity = 1, override_blindness_check = 0) + var/damage = intensity - check_eye_prot() + if(..()) // we've been flashed + if(weakeyes) + Stun(2) + switch(damage) + if(1) + src << "Your eyes sting a little." + if(prob(40)) + eye_stat += 1 + + if(2) + src << "Your eyes burn." + eye_stat += rand(2, 4) + + else + src << "Your eyes itch and burn severely!" + eye_stat += rand(12, 16) + + if(eye_stat > 10) + eye_blind += damage + eye_blurry += damage * rand(3, 6) + + if(eye_stat > 20) + if (prob(eye_stat - 20)) + src << "Your eyes start to burn badly!" + disabilities |= NEARSIGHT + else if(prob(eye_stat - 25)) + src << "You can't see anything!" + disabilities |= BLIND + else + src << "Your eyes are really starting to hurt. This can't be good for you!" + return 1 + + else if(damage == 0) // just enough protection + if(prob(20)) + src << "Something bright flashes in the corner of your vision!" /mob/living/carbon/proc/eyecheck() + var/obj/item/cybernetic_implant/eyes/EFP = locate() in src + if(EFP) + return EFP.flash_protect return 0 /mob/living/carbon/proc/tintcheck() @@ -254,55 +294,6 @@ /mob/living/carbon/proc/canBeHandcuffed() return 0 -/mob/living/carbon/unEquip(obj/item/I) //THIS PROC DID NOT CALL ..() AND THAT COST ME AN ENTIRE DAY OF DEBUGGING. - . = ..() //Sets the default return value to what the parent returns. - if(!. || !I) //We don't want to set anything to null if the parent returned 0. - return - - if(I == back) - back = null - update_inv_back(0) - else if(I == wear_mask) - if(istype(src, /mob/living/carbon/human)) //If we don't do this hair won't be properly rebuilt. - return - wear_mask = null - update_inv_wear_mask(0) - else if(I == handcuffed) - handcuffed = null - if(buckled && buckled.buckle_requires_restraints) - buckled.unbuckle_mob() - update_inv_handcuffed(0) - else if(I == legcuffed) - legcuffed = null - update_inv_legcuffed(0) - - -/mob/living/carbon/proc/get_temperature(var/datum/gas_mixture/environment) - var/loc_temp = T0C - if(istype(loc, /obj/mecha)) - var/obj/mecha/M = loc - loc_temp = M.return_temperature() - - else if(istype(loc, /obj/structure/transit_tube_pod)) - loc_temp = environment.temperature - - else if(istype(get_turf(src), /turf/space)) - var/turf/heat_turf = get_turf(src) - loc_temp = heat_turf.temperature - - else if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) - var/obj/machinery/atmospherics/unary/cryo_cell/C = loc - - if(C.air_contents.total_moles() < 10) - loc_temp = environment.temperature - else - loc_temp = C.air_contents.temperature - - else - loc_temp = environment.temperature - - return loc_temp - /mob/living/carbon/show_inv(mob/user) user.set_machine(src) @@ -310,6 +301,7 @@
    [name]
    +
    Head: [(head && !(head.flags&ABSTRACT)) ? head : "Nothing"]
    Mask: [(wear_mask && !(wear_mask.flags&ABSTRACT)) ? wear_mask : "Nothing"]
    Left Hand: [(l_hand && !(l_hand.flags&ABSTRACT)) ? l_hand : "Nothing"]
    Right Hand: [(r_hand && !(r_hand.flags&ABSTRACT)) ? r_hand : "Nothing"]"} @@ -378,6 +370,12 @@ var/const/GALOSHES_DONT_HELP = 8 /mob/living/carbon/is_muzzled() return(istype(src.wear_mask, /obj/item/clothing/mask/muzzle)) + +/mob/living/carbon/revive() + heart_attack = 0 + ..() + return + /mob/living/carbon/blob_act() if (stat == DEAD) return diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 6e6516ccd0f..49e93256442 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -13,9 +13,9 @@ /mob/living/carbon/attackby(obj/item/I, mob/user, params) - if(lying || isslime(src)) + if(lying) if(surgeries.len) - if(user.a_intent == "help") + if(user != src && user.a_intent == "help") for(var/datum/surgery/S in surgeries) if(S.next_step(user, src)) return 1 @@ -34,7 +34,7 @@ if(D.IsSpreadByTouch()) ContractDisease(D) - if(lying || isslime(src)) + if(lying) if(user.a_intent == "help") if(surgeries.len) for(var/datum/surgery/S in surgeries) @@ -65,15 +65,27 @@ return 0 -/mob/living/carbon/attack_slime(mob/living/carbon/slime/M) - if(..()) - var/power = M.powerlevel + rand(0,3) - Weaken(power) - if (stuttering < power) - stuttering = power - Stun(power) - var/stunprob = M.powerlevel * 7 + 10 - if (prob(stunprob) && M.powerlevel >= 8) - adjustFireLoss(M.powerlevel * rand(6,10)) - updatehealth() +/mob/living/carbon/attack_slime(mob/living/simple_animal/slime/M) + if(..()) //successful slime attack + if(M.powerlevel > 0) + var/stunprob = M.powerlevel * 7 + 10 // 17 at level 1, 80 at level 10 + if(prob(stunprob)) + M.powerlevel -= 3 + if(M.powerlevel < 0) + M.powerlevel = 0 + + visible_message("The [M.name] has shocked [src]!", \ + "The [M.name] has shocked [src]!") + + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(5, 1, src) + s.start() + var/power = M.powerlevel + rand(0,3) + Weaken(power) + if(stuttering < power) + stuttering = power + Stun(power) + if (prob(stunprob) && M.powerlevel >= 8) + adjustFireLoss(M.powerlevel * rand(6,10)) + updatehealth() return 1 diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index c24bf2d75b4..1f96e677eaf 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -13,10 +13,12 @@ var/obj/item/back = null var/obj/item/clothing/mask/wear_mask = null var/obj/item/weapon/tank/internal = null + var/obj/item/head = null var/datum/dna/dna = null//Carbon + var/heart_attack = 0 var/failed_last_breath = 0 //This is used to determine if the mob failed a breath. If they did fail a brath, they will attempt to breathe each tick, otherwise just once per 4 ticks. var/co2overloadtime = null - var/temperature_resistance = T0C+75 + var/temperature_resistance = T0C+75 diff --git a/code/modules/mob/living/carbon/death.dm b/code/modules/mob/living/carbon/death.dm index deca15ff0f7..2cef64b3c89 100644 --- a/code/modules/mob/living/carbon/death.dm +++ b/code/modules/mob/living/carbon/death.dm @@ -1,4 +1,5 @@ /mob/living/carbon/death(gibbed) + silent = 0 med_hud_set_health() med_hud_set_status() ..(gibbed) diff --git a/code/modules/mob/living/carbon/human/blood.dm b/code/modules/mob/living/carbon/human/blood.dm index e8c04f0444b..48da639f97e 100644 --- a/code/modules/mob/living/carbon/human/blood.dm +++ b/code/modules/mob/living/carbon/human/blood.dm @@ -30,7 +30,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 /mob/living/carbon/human/proc/fixblood() for(var/datum/reagent/blood/B in vessel.reagent_list) if(B.id == "blood") - B.data = list("donor"=src,"viruses"=null,"blood_DNA"=dna.unique_enzymes,"blood_type"=dna.blood_type,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) + B.data = list("donor"=src,"viruses"=null,"blood_DNA"=dna.unique_enzymes,"blood_type"=dna.blood_type,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"mutant_color"=null, "factions"=null) /mob/living/carbon/human/proc/suppress_bloodloss(var/amount) if(bleedsuppress) @@ -171,6 +171,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 B.data["blood_type"] = copytext(src.dna.blood_type,1,0) B.data["gender"] = src.gender B.data["real_name"] = src.real_name + B.data["mutant_color"] = src.dna.mutant_color B.data["factions"] = src.faction return B diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 71327284c39..f20afceaaa3 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -266,7 +266,8 @@ if(istype(user, /mob/living/carbon/human)) var/mob/living/carbon/human/H = user - if(istype(H.glasses, /obj/item/clothing/glasses/hud)) + var/obj/item/cybernetic_implant/eyes/hud/CIH = locate(/obj/item/cybernetic_implant/eyes/hud) in internal_organs + if(istype(H.glasses, /obj/item/clothing/glasses/hud) || CIH) var/perpname = get_face_name(get_id_name("")) if(perpname) var/datum/data/record/R = find_record("name", perpname, data_core.general) @@ -274,7 +275,7 @@ msg += "Rank: [R.fields["rank"]]
    " msg += "\[Front photo\] " msg += "\[Side photo\]
    " - if(istype(H.glasses, /obj/item/clothing/glasses/hud/health)) + if(istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(CIH,/obj/item/cybernetic_implant/eyes/hud/medical)) if(R) var/health = R.fields["p_stat"] msg += "\[[health]\]" @@ -284,7 +285,8 @@ if(R) msg += "\[Medical evaluation\]
    " - if(istype(H.glasses, /obj/item/clothing/glasses/hud/security)) + + if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(CIH,/obj/item/cybernetic_implant/eyes/hud/security)) if(!user.stat && user != src) //|| !user.canmove || user.restrained()) Fluff: Sechuds have eye-tracking technology and sets 'arrest' to people that the wearer looks and blinks at. var/criminal = "None" diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 1710e8535c4..087e499a732 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -73,8 +73,12 @@ if(mind.changeling) stat("Chemical Storage", "[mind.changeling.chem_charges]/[mind.changeling.chem_storage]") stat("Absorbed DNA", mind.changeling.absorbedcount) - if (istype(wear_suit, /obj/item/clothing/suit/space/space_ninja)&&wear_suit:s_initialized) - stat("Energy Charge", round(wear_suit:cell:charge/100)) + + //NINJACODE + if(istype(wear_suit, /obj/item/clothing/suit/space/space_ninja)) + var/obj/item/clothing/suit/space/space_ninja/SN = wear_suit + if(SN.s_initialized) + stat("Energy Charge", round(SN.cell.charge/100)) /mob/living/carbon/human/ex_act(severity, ex_target) @@ -494,15 +498,6 @@ /mob/living/carbon/human/proc/canUseHUD() return !(src.stat || src.weakened || src.stunned || src.restrained()) -/mob/living/carbon/human/proc/play_xylophone() - if(!src.xylophone) - visible_message("[src] begins playing \his ribcage like a xylophone. It's quite spooky.","You begin to play a spooky refrain on your ribcage.","You hear a spooky xylophone melody.") - var/song = pick('sound/effects/xylophone1.ogg','sound/effects/xylophone2.ogg','sound/effects/xylophone3.ogg') - playsound(loc, song, 50, 1, -1) - xylophone = 1 - spawn(1200) - xylophone = 0 - /mob/living/carbon/human/can_inject(var/mob/user, var/error_msg, var/target_zone) . = 1 // Default to returning true. if(user && !target_zone) @@ -651,19 +646,17 @@ -/mob/living/carbon/human/help_shake_act(mob/living/carbon/human/M) +/mob/living/carbon/human/help_shake_act(mob/living/carbon/M) if(!istype(M)) return - var/mob/living/carbon/human/H = src - if(health >= 0) if(src == M) visible_message( \ "[src] examines \himself.", \ "You check yourself for injuries.") - for(var/obj/item/organ/limb/org in H.organs) + for(var/obj/item/organ/limb/org in organs) var/status = "" var/brutedamage = org.brute_dam var/burndamage = org.burn_dam @@ -693,22 +686,20 @@ src << "\t [status == "OK" ? "\blue" : "\red"] My [org.getDisplayName()] is [status]." for(var/obj/item/I in org.embedded_objects) - src << "\t \red There is \a [I] embedded in your [org.getDisplayName()]!" + src << "\t \red There is \a [I] embedded in your [org.getDisplayName()]!" - if(H.blood_max) + if(blood_max) src << "You are bleeding!" if(staminaloss) if(staminaloss > 30) src << "You're completely exhausted." else src << "You feel fatigued." - if(dna && dna.species.id && dna.species.id == "skeleton" && !H.w_uniform && !H.wear_suit) - H.play_xylophone() else - if(H.wear_suit) - H.wear_suit.add_fingerprint(M) - else if(H.w_uniform) - H.w_uniform.add_fingerprint(M) + if(wear_suit) + wear_suit.add_fingerprint(M) + else if(w_uniform) + w_uniform.add_fingerprint(M) ..() diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 0748e9d3747..555feee5791 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -67,7 +67,7 @@ emp_act return 2 return (..(P , def_zone)) -/mob/living/carbon/human/proc/check_reflect(var/def_zone) //Reflection checks for anything in your l_hand, r_hand, or wear_suit based on reflect_chance var of the object +/mob/living/carbon/human/proc/check_reflect(var/def_zone) //Reflection checks for anything in your l_hand, r_hand, or wear_suit based on the reflection chance of the object if(wear_suit && istype(wear_suit, /obj/item/)) var/obj/item/I = wear_suit if(I.IsReflect(def_zone) == 1) @@ -398,25 +398,21 @@ emp_act updatehealth() -/mob/living/carbon/human/attack_slime(mob/living/carbon/slime/M as mob) - ..() - var/damage = rand(1, 3) +/mob/living/carbon/human/attack_slime(mob/living/simple_animal/slime/M as mob) + if(..()) //successful slime attack + var/damage = rand(5, 25) + if(M.is_adult) + damage = rand(10, 35) - if(M.is_adult) - damage = rand(10, 35) - else - damage = rand(5, 25) + if(check_shields(damage, "the [M.name]")) + return 0 - if(check_shields(damage, "the [M.name]")) - return 0 + var/dam_zone = pick("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg", "groin") - var/dam_zone = pick("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg", "groin") + var/obj/item/organ/limb/affecting = get_organ(ran_zone(dam_zone)) + var/armor_block = run_armor_check(affecting, "melee") + apply_damage(damage, BRUTE, affecting, armor_block) - var/obj/item/organ/limb/affecting = get_organ(ran_zone(dam_zone)) - var/armor_block = run_armor_check(affecting, "melee") - apply_damage(damage, BRUTE, affecting, armor_block) - - return /mob/living/carbon/human/mech_melee_attack(obj/mecha/M) if(M.occupant.a_intent == "harm") diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index efcec3c28ee..df617e2c68e 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -31,7 +31,6 @@ var/obj/item/belt = null var/obj/item/gloves = null var/obj/item/glasses = null - var/obj/item/head = null var/obj/item/ears = null var/obj/item/wear_id = null var/obj/item/r_store = null @@ -44,8 +43,6 @@ var/special_voice = "" // For changing our voice. Used by a symptom. - var/xylophone = 0 //For the spoooooooky xylophone cooldown - var/gender_ambiguous = 0 //if something goes wrong during gender reassignment this generates a line in examine var/blood_max = 0 //how much are we bleeding diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index ccdc5aa956c..902cce6896a 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -75,9 +75,9 @@ if(wear_id) return wear_id.GetID() -///eyecheck() +///checkeyeprot() ///Returns a number between -1 to 2 -/mob/living/carbon/human/eyecheck() +/mob/living/carbon/human/check_eye_prot() var/number = 0 if(istype(src.head, /obj/item/clothing/head)) //are they wearing something on their head var/obj/item/clothing/head/HFP = src.head //if yes gets the flash protection value from that item @@ -88,8 +88,15 @@ if(istype(src.wear_mask, /obj/item/clothing/mask)) //mask var/obj/item/clothing/mask/MFP = src.wear_mask number += MFP.flash_protect + var/obj/item/cybernetic_implant/eyes/EFP = locate() in src + if(EFP) + number += EFP.flash_protect return number +/mob/living/carbon/human/check_ear_prot() + if((ears && (ears.flags & EARBANGPROTECT)) || (head && (head.flags & HEADBANGPROTECT))) + return 1 + ///tintcheck() ///Checks eye covering items for visually impairing tinting, such as welding masks ///Checked in life.dm. 0 & 1 = no impairment, 2 = welding mask overlay, 3 = You can see jack, but you can't see shit. diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 01a14d53a6d..5e914e68242 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -15,6 +15,10 @@ var/obj/item/weapon/tank/jetpack/J = back if((movement_dir || J.stabilization_on) && J.allow_thrust(0.01, src)) return 1 + if(istype(wear_suit, /obj/item/clothing/suit/space/hardsuit/engine) && isturf(loc)) //Second check is so you can't use a jetpack in a mech + var/obj/item/clothing/suit/space/hardsuit/engine/C = wear_suit + if((movement_dir || C.jetpack.stabilization_on) && C.jetpack.allow_thrust(0.01, src)) + return 1 return 0 diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 6da553aaf24..c1e89721f8a 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -268,11 +268,6 @@ else if(I == glasses) glasses = null update_inv_glasses(0) - else if(I == head) - head = null - if(I.flags & BLOCKHAIR) - update_hair(0) //rebuild hair - update_inv_head(0) else if(I == ears) ears = null update_inv_ears(0) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 4f55665b3e5..8aa7647ac50 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -38,6 +38,9 @@ tinttotal = tintcheck() //here as both hud updates and status updates call it if(..()) + if(dna) + for(var/datum/mutation/human/HM in dna.mutations) + HM.on_life(src) //Stuff jammed in your limbs hurts handle_embedded_objects() @@ -356,4 +359,13 @@ I.loc = get_turf(src) visible_message("\the [I] falls out of [name]'s [L.getDisplayName()]!","\the [I] falls out of your [L.getDisplayName()]!") -#undef HUMAN_MAX_OXYLOSS +/mob/living/carbon/human/handle_heart() + if(!heart_attack) + return + else + losebreath += 5 + adjustOxyLoss(5) + adjustBruteLoss(1) + return + +#undef HUMAN_MAX_OXYLOSS diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index c5b2f914a64..491f878b2ec 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -1,26 +1,12 @@ -/mob/living/carbon/human/say_quote(text) - if(!text) - return "says, \"...\""; //not the best solution, but it will stop a large number of runtimes. The cause is somewhere in the Tcomms code - var/ending = copytext(text, length(text)) - if (src.stuttering) - return "stammers, \"[text]\""; +/mob/living/carbon/human/say_quote(input, spans) + if(!input) + return "says, \"...\"" //not the best solution, but it will stop a large number of runtimes. The cause is somewhere in the Tcomms code + verb_say = dna.species.say_mod if(src.slurring) - return "slurs, \"[text]\""; - if(isliving(src)) - var/mob/living/L = src - if (L.getBrainLoss() >= 60) - return "gibbers, \"[text]\""; - if(ending == "?") - return "asks, \"[text]\""; - if(copytext(text, length(text) - 1) == "!!") - return "yells, \"[text]\""; - if(ending == "!") - return "exclaims, \"[text]\""; + input = attach_spans(input, spans) + return "slurs, \"[input]\"" - if(dna) - return "[dna.species.say_mod], \"[text]\""; - - return "says, \"[text]\""; + return ..() /mob/living/carbon/human/treat_message(message) if(dna) @@ -43,6 +29,9 @@ message = dna.mutations_say_mods(message) return message +/mob/living/carbon/human/get_spans() + return ..() | dna.mutations_get_spans() + /mob/living/carbon/human/GetVoice() if(istype(wear_mask, /obj/item/clothing/mask/gas/voice)) var/obj/item/clothing/mask/gas/voice/V = wear_mask @@ -83,7 +72,7 @@ if(!istype(dongle)) return 0 if(dongle.translate_binary) return 1 -/mob/living/carbon/human/radio(message, message_mode) +/mob/living/carbon/human/radio(message, message_mode, list/spans) . = ..() if(. != 0) return . @@ -91,22 +80,22 @@ switch(message_mode) if(MODE_HEADSET) if (ears) - ears.talk_into(src, message) + ears.talk_into(src, message, , spans) return ITALICS | REDUCE_RANGE if(MODE_SECURE_HEADSET) if (ears) - ears.talk_into(src, message, 1) + ears.talk_into(src, message, 1, spans) return ITALICS | REDUCE_RANGE if(MODE_DEPARTMENT) if (ears) - ears.talk_into(src, message, message_mode) + ears.talk_into(src, message, message_mode, spans) return ITALICS | REDUCE_RANGE if(message_mode in radiochannels) if(ears) - ears.talk_into(src, message, message_mode) + ears.talk_into(src, message, message_mode, spans) return ITALICS | REDUCE_RANGE return 0 diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 8a062045601..46f561695db 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -510,10 +510,16 @@ H.see_in_dark = 8 if(!H.druggy) H.see_invisible = SEE_INVISIBLE_LEVEL_TWO else - H.sight &= ~(SEE_TURFS|SEE_MOBS|SEE_OBJS) + if(!(SEE_TURFS & H.permanent_sight_flags)) + H.sight &= ~SEE_TURFS + if(!(SEE_MOBS & H.permanent_sight_flags)) + H.sight &= ~SEE_MOBS + if(!(SEE_OBJS & H.permanent_sight_flags)) + H.sight &= ~SEE_OBJS + + H.see_in_dark = (H.sight == SEE_TURFS|SEE_MOBS|SEE_OBJS) ? 8 : darksight var/see_temp = H.see_invisible H.see_invisible = invis_sight - H.see_in_dark = darksight if(H.seer) H.see_invisible = SEE_INVISIBLE_OBSERVER @@ -608,14 +614,6 @@ else H.throw_alert("nutrition","starving") - if(H.pullin) - if(H.pulling) H.pullin.icon_state = "pull" - else H.pullin.icon_state = "pull0" -// if(rest) //Not used with new UI -// if(resting || lying || sleeping) rest.icon_state = "rest1" -// else rest.icon_state = "rest0" - - return 1 /datum/species/proc/handle_mutations_and_radiation(var/mob/living/carbon/human/H) @@ -755,7 +753,8 @@ atk_verb = M.dna.species.attack_verb var/damage = rand(0, 9) - damage += punchmod + if(M.dna) + damage += M.dna.species.punchmod if(!damage) if(M.dna) @@ -1005,10 +1004,8 @@ var/datum/gas_mixture/environment = H.loc.return_air() var/datum/gas_mixture/breath - // HACK NEED CHANGING LATER if(H.health <= config.health_threshold_crit) H.losebreath++ - if(H.losebreath>0) //Suffocating so do not take a breath H.losebreath-- if (prob(10)) //Gasp per 10 ticks? Sounds about right. diff --git a/code/modules/mob/living/carbon/human/species_types.dm b/code/modules/mob/living/carbon/human/species_types.dm index f88fde9ee1b..68db5b14894 100644 --- a/code/modules/mob/living/carbon/human/species_types.dm +++ b/code/modules/mob/living/carbon/human/species_types.dm @@ -157,7 +157,7 @@ specflags = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD) hair_color = "mutcolor" hair_alpha = 150 - ignored_by = list(/mob/living/carbon/slime) + ignored_by = list(/mob/living/simple_animal/slime) meat = /obj/item/weapon/reagent_containers/food/snacks/meat/human/mutant/slime exotic_blood = /datum/reagent/toxin/slimejelly var/recently_changed = 1 @@ -311,3 +311,9 @@ message_list.Insert(insertpos, "[pick("BRAINS", "Brains", "Braaaiinnnsss", "BRAAAIIINNSSS")]...") return list2text(message_list, " ") + +/datum/species/cosmetic_zombie + name = "Human" + id = "zombie" + sexes = 0 + meat = /obj/item/weapon/reagent_containers/food/snacks/meat/human/mutant/zombie diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 9139c933661..8d1c801472a 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -43,12 +43,6 @@ There are several things that need to be remembered: update_hair() //Handles updating your hair overlay (used to be update_face, but mouth and eyes were merged into update_body()) -> I repurposed an old unused variable which was in the code called (coincidentally) var/update_icon - It can be used as another method of triggering regenerate_icons(). It's basically a flag that when set to non-zero - will call regenerate_icons() at the next life() call and then reset itself to 0. - The idea behind it is icons are regenerated only once, even if multiple events requested it. - //NOTE: fairly unused, maybe this could be removed? - If you have any questions/constructive-comments/bugs-to-report Please contact me on #coderbus IRC. ~Carnie x //Carn can sometimes be hard to reach now. However IRC is still your best bet for getting help. @@ -144,7 +138,7 @@ Please contact me on #coderbus IRC. ~Carnie x //HAIR OVERLAY -/mob/living/carbon/human/proc/update_hair() +/mob/living/carbon/human/update_hair() //Reset our hair remove_overlay(HAIR_LAYER) diff --git a/code/modules/mob/living/carbon/human/whisper.dm b/code/modules/mob/living/carbon/human/whisper.dm index 24d98e205e7..23bb31ead56 100644 --- a/code/modules/mob/living/carbon/human/whisper.dm +++ b/code/modules/mob/living/carbon/human/whisper.dm @@ -63,15 +63,16 @@ for(var/mob/M in watching) M.show_message(rendered, 2) - rendered = "[GetVoice()][alt_name] [whispers], \"[message]\"" + var/spans = list(SPAN_ITALICS) + rendered = "[GetVoice()][alt_name] [whispers], \"[attach_spans(message, spans)]\"" for(var/mob/M in listening) - M.Hear(rendered, src, languages, message) + M.Hear(rendered, src, languages, message, , spans) message = stars(message) - rendered = "[GetVoice()][alt_name] [whispers], \"[message]\"" + rendered = "[GetVoice()][alt_name] [whispers], \"[attach_spans(message, spans)]\"" for(var/mob/M in eavesdropping) - M.Hear(rendered, src, languages, message) + M.Hear(rendered, src, languages, message, , spans) if(critical) //Dying words. succumb(1) diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm index 5a7455748cf..876f23fc37a 100644 --- a/code/modules/mob/living/carbon/inventory.dm +++ b/code/modules/mob/living/carbon/inventory.dm @@ -4,6 +4,8 @@ return back if(slot_wear_mask) return wear_mask + if(slot_head) + return head if(slot_handcuffed) return handcuffed if(slot_legcuffed) @@ -12,4 +14,33 @@ return l_hand if(slot_r_hand) return r_hand - return null \ No newline at end of file + return null + + +/mob/living/carbon/unEquip(obj/item/I) //THIS PROC DID NOT CALL ..() AND THAT COST ME AN ENTIRE DAY OF DEBUGGING. + . = ..() //Sets the default return value to what the parent returns. + if(!. || !I) //We don't want to set anything to null if the parent returned 0. + return + + if(I == head) + head = null + if(I.flags & BLOCKHAIR) + update_hair(0) + update_inv_head(0) + else if(I == back) + back = null + update_inv_back(0) + else if(I == wear_mask) + if(istype(src, /mob/living/carbon/human)) //If we don't do this hair won't be properly rebuilt. + return + wear_mask = null + update_inv_wear_mask(0) + else if(I == handcuffed) + handcuffed = null + if(buckled && buckled.buckle_requires_restraints) + buckled.unbuckle_mob() + update_inv_handcuffed(0) + else if(I == legcuffed) + legcuffed = null + update_inv_legcuffed(0) + diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index b4181b590a0..7cfa8b72f96 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -1,11 +1,3 @@ - -/mob/living/carbon - var/oxygen_alert = 0 - var/toxins_alert = 0 - var/fire_alert = 0 - var/pressure_alert = 0 - var/temperature_alert = 0 - /mob/living/carbon/Life() set invisibility = 0 set background = BACKGROUND_ENABLED @@ -14,60 +6,21 @@ return if(!loc) return - var/datum/gas_mixture/environment = loc.return_air() - - if(stat != DEAD) - - //Breathing, if applicable - handle_breathing() + if(..()) //Updates the number of stored chemicals for powers handle_changeling() - - //Mutations and radiation - handle_mutations_and_radiation() - - //Chemicals in the body - handle_chemicals_in_body() - - //Blud - handle_blood() - - //Random events (vomiting etc) - handle_random_events() + //Heart Attacks, etc. + handle_heart() . = 1 - //Handle temperature/pressure differences between body and environment - handle_environment(environment) - - handle_fire() - - //stuff in the stomach - handle_stomach() - - update_canmove() - - update_gravity(mob_has_gravity()) - - for(var/obj/item/weapon/grab/G in src) - G.process() - - handle_regular_status_updates() // Status updates, death etc. - - if(client) - handle_regular_hud_updates() - - return . - - - /////////////// // BREATHING // /////////////// //Start of a breath chain, calls breathe() -/mob/living/carbon/proc/handle_breathing() +/mob/living/carbon/handle_breathing() if(SSmob.times_fired%4==2 || failed_last_breath) breathe() //Breathe per 4 ticks, unless suffocating else @@ -235,7 +188,7 @@ //Fourth and final link in a breath chain /mob/living/carbon/proc/handle_breath_temperature(datum/gas_mixture/breath) - + return /mob/living/carbon/proc/get_breath_from_internal(volume_needed) if(internal) @@ -256,7 +209,7 @@ /mob/living/carbon/proc/handle_changeling() return -/mob/living/carbon/proc/handle_mutations_and_radiation() +/mob/living/carbon/handle_mutations_and_radiation() if(radiation) switch(radiation) @@ -281,39 +234,21 @@ radiation = Clamp(radiation, 0, 100) -/mob/living/carbon/proc/handle_chemicals_in_body() +/mob/living/carbon/handle_chemicals_in_body() if(reagents) reagents.metabolize(src) - if(drowsyness) - drowsyness-- - eye_blurry = max(2, eye_blurry) - if(prob(5)) - sleeping += 1 - Paralyse(5) - - confused = max(0, confused - 1) - // decrement dizziness counter, clamped to 0 - if(resting) - dizziness = max(0, dizziness - 5) - jitteriness = max(0, jitteriness - 5) - else - dizziness = max(0, dizziness - 1) - jitteriness = max(0, jitteriness - 1) - - updatehealth() +/mob/living/carbon/handle_blood() return -/mob/living/carbon/proc/handle_blood() +/mob/living/carbon/handle_random_events() return -/mob/living/carbon/proc/handle_random_events() +/mob/living/carbon/proc/handle_heart() return +/mob/living/carbon/handle_environment(var/datum/gas_mixture/environment) return -/mob/living/carbon/proc/handle_environment(var/datum/gas_mixture/environment) - return - -/mob/living/carbon/proc/handle_stomach() +/mob/living/carbon/handle_stomach() spawn(0) for(var/mob/living/M in stomach_contents) if(M.loc != src) @@ -330,55 +265,59 @@ M.adjustBruteLoss(5) nutrition += 10 -/mob/living/carbon/proc/handle_regular_status_updates() +//This updates the health and status of the mob (conscious, unconscious, dead) +/mob/living/carbon/handle_regular_status_updates() + + if(..()) //alive - if(stat == DEAD) - eye_blind = max(eye_blind, 1) - silent = 0 - else - updatehealth() if(health <= config.health_threshold_dead || !getorgan(/obj/item/organ/brain)) death() - eye_blind = max(eye_blind, 1) - silent = 0 - return 1 + return - if( (getOxyLoss() > 50) || (config.health_threshold_crit >= health) ) + if(getOxyLoss() > 50 || health <= config.health_threshold_crit) Paralyse(3) - - if(paralysis) - AdjustParalysis(-1) - stat = UNCONSCIOUS - else if(sleeping) - handle_dreams() - adjustStaminaLoss(-10) - sleeping = max(sleeping-1, 0) - stat = UNCONSCIOUS - if( prob(10) && health && !hal_crit ) - spawn(0) - emote("snore") - - else if (status_flags & FAKEDEATH) stat = UNCONSCIOUS - else - stat = CONSCIOUS + if(sleeping) + stat = UNCONSCIOUS - handle_disabilities() + CheckStamina() + return 1 - //Dizziness - if(dizziness) - var/client/C = client - var/pixel_x_diff = 0 - var/pixel_y_diff = 0 - var/temp - var/saved_dizz = dizziness - dizziness = max(dizziness-1, 0) - if(C) - var/oldsrc = src - var/amplitude = dizziness*(sin(dizziness * 0.044 * world.time) + 1) / 70 // This shit is annoying at high strength - src = null - spawn(0) +//this updates all special effects: stunned, sleeping, weakened, druggy, stuttering, etc.. +/mob/living/carbon/handle_status_effects() + ..() + + if(sleeping) + handle_dreams() + adjustStaminaLoss(-10) + sleeping = max(sleeping-1, 0) + if( prob(10) && health && !hal_crit ) + spawn(0) + emote("snore") + + var/restingpwr = 1 + 4 * resting + + //Dizziness + if(dizziness) + var/client/C = client + var/pixel_x_diff = 0 + var/pixel_y_diff = 0 + var/temp + var/saved_dizz = dizziness + if(C) + var/oldsrc = src + var/amplitude = dizziness*(sin(dizziness * 0.044 * world.time) + 1) / 70 // This shit is annoying at high strength + src = null + spawn(0) + if(C) + temp = amplitude * sin(0.008 * saved_dizz * world.time) + pixel_x_diff += temp + C.pixel_x += temp + temp = amplitude * cos(0.008 * saved_dizz * world.time) + pixel_y_diff += temp + C.pixel_y += temp + sleep(3) if(C) temp = amplitude * sin(0.008 * saved_dizz * world.time) pixel_x_diff += temp @@ -386,84 +325,54 @@ temp = amplitude * cos(0.008 * saved_dizz * world.time) pixel_y_diff += temp C.pixel_y += temp - sleep(3) - if(C) - temp = amplitude * sin(0.008 * saved_dizz * world.time) - pixel_x_diff += temp - C.pixel_x += temp - temp = amplitude * cos(0.008 * saved_dizz * world.time) - pixel_y_diff += temp - C.pixel_y += temp - sleep(3) - if(C) - C.pixel_x -= pixel_x_diff - C.pixel_y -= pixel_y_diff - src = oldsrc + sleep(3) + if(C) + C.pixel_x -= pixel_x_diff + C.pixel_y -= pixel_y_diff + src = oldsrc + dizziness = max(dizziness - restingpwr, 0) - //Jitteryness - if(jitteriness) - do_jitter_animation(jitteriness) - jitteriness = max(jitteriness-1, 0) + if(drowsyness) + dizziness = max(drowsyness - restingpwr, 0) + eye_blurry = max(2, eye_blurry) + if(prob(5)) + sleeping += 1 + Paralyse(5) - //Other + if(confused) + confused = max(0, confused - 1) - if(stuttering) - stuttering = max(stuttering-1, 0) + //Jitteryness + if(jitteriness) + do_jitter_animation(jitteriness) + jitteriness = max(jitteriness - restingpwr, 0) - if(slurring) - slurring = max(slurring-1,0) + if(stuttering) + stuttering = max(stuttering-1, 0) - if(silent) - silent = max(silent-1, 0) + if(slurring) + slurring = max(slurring-1,0) - if(druggy) - druggy = max(druggy-1, 0) + if(silent) + silent = max(silent-1, 0) - if(stunned) - AdjustStunned(-1) - if(!stunned) - update_icons() + if(druggy) + druggy = max(druggy-1, 0) - if(weakened) - weakened = max(weakened-1,0) - if(!weakened) - update_icons() - - if(hallucination) - spawn handle_hallucinations() - - if(hallucination<=2) - hallucination = 0 - else - hallucination -= 2 + if(hallucination) + spawn handle_hallucinations() + if(hallucination<=2) + hallucination = 0 else - for(var/atom/a in hallucinations) - qdel(a) + hallucination -= 2 - CheckStamina() - return 1 - -/mob/living/carbon/proc/handle_disabilities() - //Eyes - if(disabilities & BLIND || stat) //blindness from disability or unconsciousness doesn't get better on its own - eye_blind = max(eye_blind, 1) - else if(eye_blind) //blindness, heals slowly over time - eye_blind = max(eye_blind-1,0) - else if(eye_blurry) //blurry eyes heal slowly - eye_blurry = max(eye_blurry-1, 0) - - //Ears - if(disabilities & DEAF) //disabled-deaf, doesn't get better on its own - setEarDamage(-1, max(ear_deaf, 1)) else - // deafness heals slowly over time, unless ear_damage is over 100 - if(ear_damage < 100) - adjustEarDamage(-0.05,-1) + for(var/atom/a in hallucinations) + qdel(a) - -//this handles hud updates. Calles update_vision() and handle_hud_icons() -/mob/living/carbon/proc/handle_regular_hud_updates() +//this handles hud updates. Calls update_vision() and handle_hud_icons() +/mob/living/carbon/handle_regular_hud_updates() if(!client) return 0 update_action_buttons() @@ -544,15 +453,11 @@ damageoverlay.overlays += I damageoverlay.overlays += black - - handle_vision() - handle_hud_icons() + ..() return 1 -/mob/living/carbon/proc/handle_vision() - - client.screen.Remove(global_hud.blurry, global_hud.druggy, global_hud.vimpaired, global_hud.darkMask) +/mob/living/carbon/update_sight() if(stat == DEAD) sight |= SEE_TURFS @@ -561,46 +466,23 @@ see_in_dark = 8 see_invisible = SEE_INVISIBLE_LEVEL_TWO else - sight &= ~SEE_TURFS - sight &= ~SEE_MOBS - sight &= ~SEE_OBJS - see_in_dark = 2 + if(!(SEE_TURFS & permanent_sight_flags)) + sight &= ~SEE_TURFS + if(!(SEE_MOBS & permanent_sight_flags)) + sight &= ~SEE_MOBS + if(!(SEE_OBJS & permanent_sight_flags)) + sight &= ~SEE_OBJS + + see_in_dark = (sight == SEE_TURFS|SEE_MOBS|SEE_OBJS) ? 8 : 2 //Xray flag combo see_invisible = SEE_INVISIBLE_LIVING if(see_override) see_invisible = see_override - if(blind) - if(eye_blind) - blind.layer = 18 - else - blind.layer = 0 - if (disabilities & NEARSIGHT) - client.screen += global_hud.vimpaired - - if (eye_blurry) - client.screen += global_hud.blurry - - if (druggy) - client.screen += global_hud.druggy - - if(eye_stat > 20) - if(eye_stat > 30) - client.screen += global_hud.darkMask - else - client.screen += global_hud.vimpaired - - if(machine) - if (!( machine.check_eye(src) )) - reset_view(null) - else - if(!client.adminobs) - reset_view(null) - -/mob/living/carbon/proc/handle_hud_icons() +/mob/living/carbon/handle_hud_icons() return -/mob/living/carbon/proc/handle_hud_icons_health() +/mob/living/carbon/handle_hud_icons_health() if(healths) if (stat != DEAD) switch(health) @@ -619,4 +501,4 @@ else healths.icon_state = "health6" else - healths.icon_state = "health7" \ No newline at end of file + healths.icon_state = "health7" diff --git a/code/modules/mob/living/carbon/monkey/examine.dm b/code/modules/mob/living/carbon/monkey/examine.dm index a3686d7a478..48963b00eed 100644 --- a/code/modules/mob/living/carbon/monkey/examine.dm +++ b/code/modules/mob/living/carbon/monkey/examine.dm @@ -3,8 +3,10 @@ if (src.handcuffed) msg += "It is \icon[src.handcuffed] handcuffed!\n" + if (src.head) + msg += "It has \icon[src.head] \a [src.head] on its head. \n" if (src.wear_mask) - msg += "It has \icon[src.wear_mask] \a [src.wear_mask] on its head.\n" + msg += "It has \icon[src.wear_mask] \a [src.wear_mask] on its face.\n" if (src.l_hand) msg += "It has \icon[src.l_hand] \a [src.l_hand] in its left hand.\n" if (src.r_hand) diff --git a/code/modules/mob/living/carbon/monkey/inventory.dm b/code/modules/mob/living/carbon/monkey/inventory.dm index 95ff775c0a4..c0ae3e21920 100644 --- a/code/modules/mob/living/carbon/monkey/inventory.dm +++ b/code/modules/mob/living/carbon/monkey/inventory.dm @@ -14,6 +14,12 @@ if( !(I.slot_flags & SLOT_MASK) ) return 0 return 1 + if(slot_head) + if(head) + return 0 + if( !(I.slot_flags & SLOT_HEAD) ) + return 0 + return 1 if(slot_back) if(back) return 0 @@ -43,6 +49,10 @@ wear_mask = I I.equipped(src, slot) update_inv_wear_mask(redraw_mob) + if(slot_head) + head = I + I.equipped(src, slot) + update_inv_head(redraw_mob) if(slot_handcuffed) handcuffed = I update_inv_handcuffed(redraw_mob) @@ -70,3 +80,6 @@ I.loc = src I.equipped(src, slot) I.layer = 20 + + + diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm index f9589c35ca9..12cac68350c 100644 --- a/code/modules/mob/living/carbon/monkey/life.dm +++ b/code/modules/mob/living/carbon/monkey/life.dm @@ -97,16 +97,6 @@ handle_hud_icons_health() - - - if(pullin) - if(pulling) - pullin.icon_state = "pull" - else - pullin.icon_state = "pull0" - - //blame the person who coded them. Temporary fix added. - return 1 /mob/living/carbon/monkey/handle_random_events() diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index 6519cd2b39a..d275d0744ba 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -1,13 +1,12 @@ /mob/living/carbon/monkey name = "monkey" voice_name = "monkey" - say_message = "chimpers" + verb_say = "chimpers" icon = 'icons/mob/monkey.dmi' icon_state = "monkey1" gender = NEUTER pass_flags = PASSTABLE languages = MONKEY - update_icon = 0 ///no need to call regenerate_icon ventcrawler = 1 /mob/living/carbon/monkey/New() @@ -138,7 +137,6 @@ if (M.a_intent == "disarm") playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1) - var/damage = 5 if(prob(95)) Weaken(10) visible_message("[M] has tackled down [name]!", \ @@ -148,7 +146,6 @@ visible_message("[M] has disarmed [name]!", \ "[M] has disarmed [name]!") add_logs(M, src, "disarmed", admin=0) - adjustBruteLoss(damage) updatehealth() return @@ -159,18 +156,13 @@ updatehealth() -/mob/living/carbon/monkey/attack_slime(mob/living/carbon/slime/M as mob) - ..() - var/damage = rand(1, 3) - - if(M.is_adult) - damage = rand(20, 40) - else - damage = rand(5, 35) - adjustBruteLoss(damage) - updatehealth() - - return +/mob/living/carbon/monkey/attack_slime(mob/living/simple_animal/slime/M as mob) + if(..()) //successful slime attack + var/damage = rand(5, 35) + if(M.is_adult) + damage = rand(20, 40) + adjustBruteLoss(damage) + updatehealth() /mob/living/carbon/monkey/Stat() ..() @@ -262,5 +254,4 @@ src << "Your mask protects you from the acid." return - if(!unacidable) - take_organ_damage(min(6*toxpwr, acid_volume * toxpwr)) + take_organ_damage(min(6*toxpwr, acid_volume * toxpwr)) diff --git a/code/modules/mob/living/carbon/monkey/say.dm b/code/modules/mob/living/carbon/monkey/say.dm deleted file mode 100644 index 58cfe0e35f8..00000000000 --- a/code/modules/mob/living/carbon/monkey/say.dm +++ /dev/null @@ -1,2 +0,0 @@ -/mob/living/carbon/monkey/say_quote(var/text) - return "[say_message], \"[text]\""; diff --git a/code/modules/mob/living/carbon/monkey/update_icons.dm b/code/modules/mob/living/carbon/monkey/update_icons.dm index bcdbbb6b633..5be5fbc43b8 100644 --- a/code/modules/mob/living/carbon/monkey/update_icons.dm +++ b/code/modules/mob/living/carbon/monkey/update_icons.dm @@ -1,11 +1,12 @@ //Monkey Overlays Indexes//////// -#define M_FIRE_LAYER 6 -#define M_MASK_LAYER 5 +#define M_FIRE_LAYER 7 +#define M_MASK_LAYER 6 +#define M_HEAD_LAYER 5 #define M_BACK_LAYER 4 #define M_HANDCUFF_LAYER 3 #define M_L_HAND_LAYER 2 #define M_R_HAND_LAYER 1 -#define M_TOTAL_LAYERS 6 +#define M_TOTAL_LAYERS 7 ///////////////////////////////// /mob/living/carbon/monkey @@ -14,6 +15,7 @@ /mob/living/carbon/monkey/regenerate_icons() ..() update_inv_wear_mask(0) + update_inv_head(0) update_inv_back(0) update_inv_r_hand(0) update_inv_l_hand(0) @@ -39,7 +41,7 @@ if(client && hud_used) client.screen += wear_mask overlays -= overlays_standing[M_MASK_LAYER] - var/image/standing = image("icon" = 'icons/mob/monkey.dmi', "icon_state" = "[wear_mask.icon_state]", "layer" = -M_MASK_LAYER) + var/image/standing = image("icon" = 'icons/mob/mask.dmi', "icon_state" = "[wear_mask.icon_state]", "layer" = -M_MASK_LAYER) if(!istype(wear_mask, /obj/item/clothing/mask/cigarette) && wear_mask.blood_DNA ) standing.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "maskblood") overlays_standing[M_MASK_LAYER] = standing @@ -50,6 +52,21 @@ if(update_icons) update_icons() +/mob/living/carbon/monkey/update_inv_head(var/update_icons=1) + if(head) + head.screen_loc = ui_monkey_head + if(client && hud_used) + client.screen += head + overlays -= overlays_standing[M_HEAD_LAYER] + var/image/standing = image("icon" = 'icons/mob/head.dmi', "icon_state" = "[head.icon_state]", "layer" = -M_HEAD_LAYER) + overlays_standing[M_HEAD_LAYER] = standing + overlays += overlays_standing[M_HEAD_LAYER] + else + overlays -= overlays_standing[M_HEAD_LAYER] + overlays_standing[M_HEAD_LAYER] = null + if(update_icons) update_icons() + + /mob/living/carbon/monkey/update_inv_r_hand(var/update_icons=1) if (handcuffed) drop_r_hand() @@ -61,7 +78,9 @@ var/t_state = r_hand.item_state if(!t_state) t_state = r_hand.icon_state overlays -= overlays_standing[M_R_HAND_LAYER] - overlays_standing[M_R_HAND_LAYER] = image("icon" = r_hand.righthand_file, "icon_state" = t_state, "layer" = -M_R_HAND_LAYER) + var/image/standing = image("icon" = r_hand.righthand_file, "icon_state" = t_state, "layer" = -M_R_HAND_LAYER) + standing.pixel_y = 2 + overlays_standing[M_R_HAND_LAYER] = standing overlays += overlays_standing[M_R_HAND_LAYER] else overlays -= overlays_standing[M_R_HAND_LAYER] @@ -80,7 +99,9 @@ var/t_state = l_hand.item_state if(!t_state) t_state = l_hand.icon_state overlays -= overlays_standing[M_L_HAND_LAYER] - overlays_standing[M_L_HAND_LAYER] = image("icon" = l_hand.lefthand_file, "icon_state" = t_state, "layer" = -M_L_HAND_LAYER) + var/image/standing = image("icon" = l_hand.lefthand_file, "icon_state" = t_state, "layer" = -M_L_HAND_LAYER) + standing.pixel_y = 2 + overlays_standing[M_L_HAND_LAYER] = standing overlays += overlays_standing[M_L_HAND_LAYER] else overlays -= overlays_standing[M_L_HAND_LAYER] diff --git a/code/modules/mob/living/carbon/slime/examine.dm b/code/modules/mob/living/carbon/slime/examine.dm deleted file mode 100644 index 609addde9f5..00000000000 --- a/code/modules/mob/living/carbon/slime/examine.dm +++ /dev/null @@ -1,31 +0,0 @@ -/mob/living/carbon/slime/examine(mob/user) - - var/msg = "*---------*\nThis is \icon[src] \a [src]!\n" - if (src.stat == DEAD) - msg += "It is limp and unresponsive.\n" - else - if (src.getBruteLoss()) - msg += "" - if (src.getBruteLoss() < 40) - msg += "It has some punctures in its flesh!" - else - msg += "It has severe punctures and tears in its flesh!" - msg += "\n" - - switch(powerlevel) - - if(2 to 3) - msg += "It is flickering gently with a little electrical activity.\n" - - if(4 to 5) - msg += "It is glowing gently with moderate levels of electrical activity.\n" - - if(6 to 9) - msg += "It is glowing brightly with high levels of electrical activity.\n" - - if(10) - msg += "It is radiating with massive levels of electrical activity!\n" - - msg += "*---------*" - user << msg - return \ No newline at end of file diff --git a/code/modules/mob/living/carbon/slime/login.dm b/code/modules/mob/living/carbon/slime/login.dm deleted file mode 100644 index d3ac320f2f4..00000000000 --- a/code/modules/mob/living/carbon/slime/login.dm +++ /dev/null @@ -1,4 +0,0 @@ -/mob/living/carbon/slime/Login() - ..() - update_hud() - return diff --git a/code/modules/mob/living/carbon/slime/say.dm b/code/modules/mob/living/carbon/slime/say.dm deleted file mode 100644 index b7049020653..00000000000 --- a/code/modules/mob/living/carbon/slime/say.dm +++ /dev/null @@ -1,20 +0,0 @@ -/mob/living/carbon/slime/say(var/message) - ..() - -/mob/living/carbon/slime/say_quote(var/text) - var/ending = copytext(text, length(text)) - - if (ending == "?") - return "telepathically asks, \"[text]\""; - else if (ending == "!") - return "telepathically cries, \"[text]\""; - - return "telepathically chirps, \"[text]\""; - -/mob/living/carbon/slime/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq) - if(speaker != src && !radio_freq) - if (speaker in Friends) - speech_buffer = list() - speech_buffer += speaker - speech_buffer += lowertext(html_decode(message)) - ..() diff --git a/code/modules/mob/living/carbon/slime/slime.dm b/code/modules/mob/living/carbon/slime/slime.dm deleted file mode 100644 index 50a4d58086c..00000000000 --- a/code/modules/mob/living/carbon/slime/slime.dm +++ /dev/null @@ -1,912 +0,0 @@ -/mob/living/carbon/slime - name = "baby slime" - icon = 'icons/mob/slimes.dmi' - icon_state = "grey baby slime" - pass_flags = PASSTABLE - say_message = "hums" - ventcrawler = 2 - var/is_adult = 0 - var/docile = 0 - languages = SLIME | HUMAN - faction = list("slime") - - layer = 5 - - maxHealth = 150 - health = 150 - gender = NEUTER - - update_icon = 0 - nutrition = 700 - - see_in_dark = 8 - update_slimes = 0 - - // canstun and canweaken don't affect slimes because they ignore stun and weakened variables - // for the sake of cleanliness, though, here they are. - status_flags = CANPARALYSE|CANPUSH - - var/cores = 1 // the number of /obj/item/slime_extract's the slime has left inside - var/mutation_chance = 30 // Chance of mutating, should be between 25 and 35 - - var/powerlevel = 0 // 1-10 controls how much electricity they are generating - var/amount_grown = 0 // controls how long the slime has been overfed, if 10, grows or reproduces - - var/number = 0 // Used to understand when someone is talking to it - - var/mob/living/Victim = null // the person the slime is currently feeding on - var/mob/living/Target = null // AI variable - tells the slime to hunt this down - var/mob/living/Leader = null // AI variable - tells the slime to follow this person - - var/attacked = 0 // Determines if it's been attacked recently. Can be any number, is a cooloff-ish variable - var/rabid = 0 // If set to 1, the slime will attack and eat anything it comes in contact with - var/holding_still = 0 // AI variable, cooloff-ish for how long it's going to stay in one place - var/target_patience = 0 // AI variable, cooloff-ish for how long it's going to follow its target - - var/list/Friends = list() // A list of friends; they are not considered targets for feeding; passed down after splitting - - var/list/speech_buffer = list() // Last phrase said near it and person who said it - - var/mood = "" // To show its face - - ///////////TIME FOR SUBSPECIES - - var/colour = "grey" - var/coretype = /obj/item/slime_extract/grey - var/list/slime_mutation[4] - -/mob/living/carbon/slime/New() - create_reagents(100) - spawn (0) - number = rand(1, 1000) - name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])" - icon_state = "[colour] [is_adult ? "adult" : "baby"] slime" - real_name = name - slime_mutation = mutation_table(colour) - mutation_chance = rand(25, 35) - var/sanitizedcolour = replacetext(colour, " ", "") - coretype = text2path("/obj/item/slime_extract/[sanitizedcolour]") - ..() - -/mob/living/carbon/slime/regenerate_icons() - icon_state = "[colour] [is_adult ? "adult" : "baby"] slime" - overlays.len = 0 - if (mood) - overlays += image('icons/mob/slimes.dmi', icon_state = "aslime-[mood]") - ..() - -/mob/living/carbon/slime/movement_delay() - if (bodytemperature >= 330.23) // 135 F - return -1 // slimes become supercharged at high temperatures - - var/tally = 0 - - var/health_deficiency = (100 - health) - if(health_deficiency >= 45) tally += (health_deficiency / 25) - - if (bodytemperature < 183.222) - tally += (283.222 - bodytemperature) / 10 * 1.75 - - if(reagents) - if(reagents.has_reagent("morphine")) // morphine slows slimes down - tally *= 2 - - if(reagents.has_reagent("frostoil")) // Frostoil also makes them move VEEERRYYYYY slow - tally *= 5 - - if(health <= 0) // if damaged, the slime moves twice as slow - tally *= 2 - - return tally + config.slime_delay - -/mob/living/carbon/slime/ObjBump(obj/O) - if(!client && powerlevel > 0) - var/probab = 10 - switch(powerlevel) - if(1 to 2) probab = 20 - if(3 to 4) probab = 30 - if(5 to 6) probab = 40 - if(7 to 8) probab = 60 - if(9) probab = 70 - if(10) probab = 95 - if(prob(probab)) - if(istype(O, /obj/structure/window) || istype(O, /obj/structure/grille)) - if(nutrition <= get_hunger_nutrition() && !Atkcool) - if (is_adult || prob(5)) - O.attack_slime(src) - Atkcool = 1 - spawn(45) - Atkcool = 0 - -/mob/living/carbon/slime/MobBump(mob/M) - if(istype(M, /mob/living/carbon/human)) //pushing humans - if(is_adult && prob(10)) //only if we're adult, and 10% of the time - return 0 - else - return 1 - -/mob/living/carbon/slime/Process_Spacemove(var/movement_dir = 0) - return 2 - -/mob/living/carbon/slime/Stat() - ..() - - if(statpanel("Status")) - if(is_adult) - stat(null, "Health: [round((health / 200) * 100)]%") - else - stat(null, "Health: [round((health / 150) * 100)]%") - if(!docile) - stat(null, "Nutrition: [nutrition]/[get_max_nutrition()]") - if(amount_grown >= 10) - if(is_adult) - stat(null, "You can reproduce!") - else - stat(null, "You can evolve!") - - stat(null,"Power Level: [powerlevel]") - -/mob/living/carbon/slime/adjustFireLoss(amount) - ..(-abs(amount)) // Heals them - return - -/mob/living/carbon/slime/bullet_act(var/obj/item/projectile/Proj) - attacked += 10 - ..(Proj) - return 0 - -/mob/living/carbon/slime/emp_act(severity) - powerlevel = 0 // oh no, the power! - ..() - -/mob/living/carbon/slime/ex_act(severity, target) - ..() - - switch (severity) - if (1.0) - gib() - return - - if (2.0) - adjustBruteLoss(60) - adjustFireLoss(60) - - if(3.0) - adjustBruteLoss(30) - - updatehealth() - -/mob/living/carbon/slime/MouseDrop(var/atom/movable/A as mob|obj) - if(isliving(A) && A != src && usr == src) - var/mob/living/Food = A - if(Food.Adjacent(src) && !stat && Food.stat != DEAD) //messy - Feedon(Food) - ..() - -/mob/living/carbon/slime/unEquip(obj/item/W as obj) - return - -/mob/living/carbon/slime/start_pulling(var/atom/movable/AM) - return - -/mob/living/carbon/slime/attack_ui(slot) - return - -/mob/living/carbon/slime/attack_slime(mob/living/carbon/slime/M as mob) - ..() - if(src.Victim) - src.Victim = null - visible_message("[M] pulls [src] off!") - return - attacked += 5 - if(src.nutrition >= 100) //steal some nutrition. negval handled in life() - src.nutrition -= (50 + (5 * M.amount_grown)) - M.add_nutrition(50 + (5 * M.amount_grown)) - if(src.health > 0) - src.adjustBruteLoss(4 + (2 * M.amount_grown)) //amt_grown isn't very linear but it works - src.updatehealth() - M.adjustBruteLoss(-4 + (-2 * M.amount_grown)) - M.updatehealth() - return - -/mob/living/carbon/slime/attack_animal(mob/living/simple_animal/M as mob) - if(..()) - var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) - attacked += 10 - adjustBruteLoss(damage) - updatehealth() - -/mob/living/carbon/slime/attack_paw(mob/living/carbon/monkey/M as mob) - if(..()) //successful monkey bite. - if(stat != DEAD) - attacked += 10 - adjustBruteLoss(rand(1, 3)) - updatehealth() - return - -/mob/living/carbon/slime/attack_larva(mob/living/carbon/alien/larva/L as mob) - if(..()) //successful larva bite. - var/damage = rand(1, 3) - if(stat != DEAD) - L.amount_grown = min(L.amount_grown + damage, L.max_grown) - adjustBruteLoss(damage) - updatehealth() - -/mob/living/carbon/slime/attack_hulk(mob/living/carbon/human/user) - if(user.a_intent == "harm") - adjustBruteLoss(5) - if(Victim || Target) - Victim = null - Target = null - anchored = 0 - if(prob(80) && !client) - Discipline++ - spawn(0) - step_away(src,user,15) - sleep(3) - step_away(src,user,15) - - -/mob/living/carbon/slime/attack_hand(mob/living/carbon/human/M as mob) - if(Victim) - if(Victim == M) - if(prob(60)) - visible_message("[M] attempts to wrestle \the [name] off!") - playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - - else - visible_message(" [M] manages to wrestle \the [name] off!") - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - - if(prob(90) && !client) - Discipline++ - - spawn() - SStun = 1 - sleep(rand(45,60)) - if(src) - SStun = 0 - - Victim = null - anchored = 0 - step_away(src,M) - - return - - else - M.do_attack_animation(src) - if(prob(30)) - visible_message("[M] attempts to wrestle \the [name] off of [Victim]!") - playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - - else - visible_message(" [M] manages to wrestle \the [name] off of [Victim]!") - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - - if(prob(80) && !client) - Discipline++ - - if(!is_adult) - if(Discipline == 1) - attacked = 0 - - spawn() - SStun = 1 - sleep(rand(55,65)) - if(src) - SStun = 0 - - Victim = null - anchored = 0 - step_away(src,M) - - return - - if(..()) //To allow surgery to return properly. - return - - switch(M.a_intent) - if("help") - help_shake_act(M) - if("grab") - grabbedby(M) - else - M.do_attack_animation(src) - var/damage = rand(1, 9) - attacked += 10 - if (prob(90)) - playsound(loc, "punch", 25, 1, -1) - add_logs(M, src, "attacked", admin=0) - visible_message("[M] has punched [src]!", \ - "[M] has punched [src]!") - - if (stat != DEAD) - adjustBruteLoss(damage) - updatehealth() - else - playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - visible_message("[M] has attempted to punch [src]!") - return - - - -/mob/living/carbon/slime/attack_alien(mob/living/carbon/alien/humanoid/M as mob) - if(..()) //if harm or disarm intent. - - if (M.a_intent == "harm") - if (prob(95)) - attacked += 10 - playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1) - var/damage = rand(15, 30) - if (damage >= 25) - damage = rand(20, 40) - visible_message("[M] has slashed [name]!", \ - "[M] has slashed [name]!") - else - visible_message("[M] has wounded [name]!", \ - ")[M] has wounded [name]!") - - add_logs(M, src, "attacked", admin=0) - if (health != DEAD) - adjustBruteLoss(damage) - updatehealth() - else - playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1) - visible_message("[M] has attempted to lunge at [name]!", \ - "[M] has attempted to lunge at [name]!") - - if (M.a_intent == "disarm") - playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1) - var/damage = 5 - attacked += 10 - - if(prob(95)) - visible_message("[M] has tackled [name]!", \ - "[M] has tackled [name]!") - - if(Victim || Target) - Victim = null - Target = null - anchored = 0 - if(prob(80) && !client) - Discipline++ - if(!istype(src, /mob/living/carbon/slime)) - if(Discipline == 1) - attacked = 0 - - spawn() - SStun = 1 - sleep(rand(5,20)) - SStun = 0 - - spawn(0) - - step_away(src,M,15) - sleep(3) - step_away(src,M,15) - - else - drop_item() - visible_message("[M] has disarmed [name]!", - "[M] has disarmed [name]!") - add_logs(M, src, "disarmed", admin=0) - adjustBruteLoss(damage) - updatehealth() - return - -/mob/living/carbon/slime/attackby(obj/item/W, mob/living/user, params) - if(istype(W,/obj/item/stack/sheet/mineral/plasma)) //Let's you feed slimes plasma. - if (user in Friends) - ++Friends[user] - else - Friends[user] = 1 - user << "You feed the slime the plasma. It chirps happily." - var/obj/item/stack/sheet/mineral/plasma/S = W - S.use(1) - return - else if(W.force > 0) - attacked += 10 - if(prob(25)) - user.do_attack_animation(src) - user << "[W] passes right through [src]!" - return - if(Discipline && prob(50)) // wow, buddy, why am I getting attacked?? - Discipline = 0 - else if(W.force >= 3) - if(is_adult) - if(prob(5 + round(W.force/2))) - if(Victim || Target) - if(prob(80) && !client) - Discipline++ - - Victim = null - Target = null - anchored = 0 - - spawn() - SStun = 1 - sleep(rand(5,20)) - SStun = 0 - - spawn(0) - if(user) - canmove = 0 - step_away(src, user) - if(prob(25 + W.force)) - sleep(2) - if(user) - step_away(src, user) - canmove = 1 - - else - if(prob(10 + W.force*2)) - if(Victim || Target) - if(prob(80) && !client) - Discipline++ - if(Discipline == 1) - attacked = 0 - spawn() - SStun = 1 - sleep(rand(5,20)) - SStun = 0 - - Victim = null - Target = null - anchored = 0 - - spawn(0) - if(user) - canmove = 0 - step_away(src, user) - if(prob(25 + W.force*4)) - sleep(2) - if(user) - step_away(src, user) - canmove = 1 - ..() - -/mob/living/carbon/slime/restrained() - return 0 - -/mob/living/carbon/slime/show_inv(mob/user) - return - -/mob/living/carbon/slime/toggle_throw_mode() - return - -/mob/living/carbon/slime/proc/apply_water() - adjustToxLoss(rand(15,20)) - if (!client) - if (Target) // Like cats - Target = null - ++Discipline - return - -/obj/item/slime_extract - name = "slime extract" - desc = "Goo extracted from a slime. Legends claim these to have \"magical powers\"." - icon = 'icons/mob/slimes.dmi' - icon_state = "grey slime extract" - force = 1.0 - w_class = 1.0 - throwforce = 0 - throw_speed = 3 - throw_range = 6 - origin_tech = "biotech=4" - var/Uses = 1 // uses before it goes inert - var/enhanced = 0 //has it been enhanced before? - - attackby(obj/item/O as obj, mob/user as mob) - if(istype(O, /obj/item/weapon/slimesteroid2)) - if(enhanced == 1) - user << " This extract has already been enhanced!" - return ..() - if(Uses == 0) - user << " You can't enhance a used extract!" - return ..() - user <<"You apply the enhancer. It now has triple the amount of uses." - Uses = 3 - enhanced = 1 - qdel(O) - -/obj/item/slime_extract/New() - ..() - create_reagents(100) - -/obj/item/slime_extract/grey - name = "grey slime extract" - icon_state = "grey slime extract" - -/obj/item/slime_extract/gold - name = "gold slime extract" - icon_state = "gold slime extract" - -/obj/item/slime_extract/silver - name = "silver slime extract" - icon_state = "silver slime extract" - -/obj/item/slime_extract/metal - name = "metal slime extract" - icon_state = "metal slime extract" - -/obj/item/slime_extract/purple - name = "purple slime extract" - icon_state = "purple slime extract" - -/obj/item/slime_extract/darkpurple - name = "dark purple slime extract" - icon_state = "dark purple slime extract" - -/obj/item/slime_extract/orange - name = "orange slime extract" - icon_state = "orange slime extract" - -/obj/item/slime_extract/yellow - name = "yellow slime extract" - icon_state = "yellow slime extract" - -/obj/item/slime_extract/red - name = "red slime extract" - icon_state = "red slime extract" - -/obj/item/slime_extract/blue - name = "blue slime extract" - icon_state = "blue slime extract" - -/obj/item/slime_extract/darkblue - name = "dark blue slime extract" - icon_state = "dark blue slime extract" - -/obj/item/slime_extract/pink - name = "pink slime extract" - icon_state = "pink slime extract" - -/obj/item/slime_extract/green - name = "green slime extract" - icon_state = "green slime extract" - -/obj/item/slime_extract/lightpink - name = "light pink slime extract" - icon_state = "light pink slime extract" - -/obj/item/slime_extract/black - name = "black slime extract" - icon_state = "black slime extract" - -/obj/item/slime_extract/oil - name = "oil slime extract" - icon_state = "oil slime extract" - -/obj/item/slime_extract/adamantine - name = "adamantine slime extract" - icon_state = "adamantine slime extract" - -/obj/item/slime_extract/bluespace - name = "bluespace slime extract" - icon_state = "bluespace slime extract" - -/obj/item/slime_extract/pyrite - name = "pyrite slime extract" - icon_state = "pyrite slime extract" - -/obj/item/slime_extract/cerulean - name = "cerulean slime extract" - icon_state = "cerulean slime extract" - -/obj/item/slime_extract/sepia - name = "sepia slime extract" - icon_state = "sepia slime extract" - -/obj/item/slime_extract/rainbow - name = "rainbow slime extract" - icon_state = "rainbow slime extract" - -////Pet Slime Creation/// - -/obj/item/slimepotion - name = "docility potion" - desc = "A potent chemical mix that nullifies a slime's hunger, causing it to become docile and tame." - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle19" - -/obj/item/slimepotion/attack(mob/living/carbon/slime/M as mob, mob/user as mob) - if(!isslime(M)) - user << "The potion only works on slimes!" - return ..() - if(M.stat) - user << "The slime is dead!" - return..() - - M.docile = 1 - M.nutrition = 700 - M <<" You absorb the potion and feel your intense desire to feed melt away." - user <<" You feed the slime the potion, removing it's hunger and calming it." - var/newname = copytext(sanitize(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text),1,MAX_NAME_LEN) - - if (!newname) - newname = "pet slime" - M.name = newname - M.real_name = newname - qdel(src) - -/obj/item/slimepotion2 - name = "sentience potion" - desc = "A miraculous chemical mix that can raise the intelligence of creatures to human levels." - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle19" - -/obj/item/slimepotion2/afterattack(mob/living/M as mob, mob/user as mob) - if(!(isslime(M) || isanimal(M) || ismonkey(M) || !M.ckey)) //I'm sorry for this line - user << "[M] is already too intelligent for this to work!" - return ..() - if(M.stat) - user << "[M] is dead!" - return..() - - var/list/candidates = get_candidates(BE_ALIEN, ALIEN_AFK_BRACKET) - var/client/C = null - - if(candidates.len) - C = pick(candidates) - M.key = C.key - M.languages |= HUMAN - M << "All at once it makes sense, you know what you are and who you are! Self awareness is yours!" - M << "You are grateful to be self aware and owe [user] a great debt. Serve [user], and assist them in completing their goals at any cost." - user << "[M] is suddenly attentive and aware. It worked!" - qdel(src) - else - user << "[M] looks interested for a moment, but then looks back down. Maybe you should try again later..." - ..() - -/obj/item/weapon/slimesteroid - name = "slime steroid" - desc = "A potent chemical mix that will cause a slime to generate more extract." - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle16" - - attack(mob/living/carbon/slime/M as mob, mob/user as mob) - if(!istype(M, /mob/living/carbon/slime))//If target is not a slime. - user << " The steroid only works on baby slimes!" - return ..() - if(M.is_adult) //Can't tame adults - user << " Only baby slimes can use the steroid!" - return..() - if(M.stat) - user << " The slime is dead!" - return..() - if(M.cores == 3) - user <<" The slime already has the maximum amount of extract!" - return..() - - user <<"You feed the slime the steroid. It now has triple the amount of extract." - M.cores = 3 - qdel(src) - -/obj/item/weapon/slimesteroid2 - name = "extract enhancer" - desc = "A potent chemical mix that will give a slime extract three uses." - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle17" - - /*afterattack(obj/target, mob/user , flag) - if(istype(target, /obj/item/slime_extract)) - if(target.enhanced == 1) - user << " This extract has already been enhanced!" - return ..() - if(target.Uses == 0) - user << " You can't enhance a used extract!" - return ..() - user <<"You apply the enhancer. It now has triple the amount of uses." - target.Uses = 3 - target.enahnced = 1 - qdel(src)*/ - -////////Adamantine Golem stuff I dunno where else to put it - -// This will eventually be removed. - -/obj/item/clothing/under/golem - name = "adamantine skin" - desc = "a golem's skin" - icon_state = "golem" - item_state = "golem" - item_color = "golem" - flags = ABSTRACT | NODROP - has_sensor = 0 - -/obj/item/clothing/suit/golem - name = "adamantine shell" - desc = "a golem's thick outter shell" - icon_state = "golem" - item_state = "golem" - w_class = 4//bulky item - gas_transfer_coefficient = 0.90 - permeability_coefficient = 0.50 - body_parts_covered = FULL_BODY - flags_inv = HIDEGLOVES | HIDESHOES | HIDEJUMPSUIT - flags = ABSTRACT | NODROP - -/obj/item/clothing/shoes/golem - name = "golem's feet" - desc = "sturdy adamantine feet" - icon_state = "golem" - item_state = null - flags = NOSLIP | ABSTRACT | NODROP - - -/obj/item/clothing/mask/breath/golem - name = "golem's face" - desc = "the imposing face of an adamantine golem" - icon_state = "golem" - item_state = "golem" - siemens_coefficient = 0 - unacidable = 1 - flags = ABSTRACT | NODROP - - -/obj/item/clothing/gloves/golem - name = "golem's hands" - desc = "strong adamantine hands" - icon_state = "golem" - item_state = null - siemens_coefficient = 0 - flags = ABSTRACT | NODROP - - -/obj/item/clothing/head/space/golem - icon_state = "golem" - item_state = "dermal" - item_color = "dermal" - name = "golem's head" - desc = "a golem's head" - unacidable = 1 - flags = ABSTRACT | NODROP - -/obj/effect/golemrune - anchored = 1 - desc = "a strange rune used to create golems. It glows when spirits are nearby." - name = "rune" - icon = 'icons/obj/rune.dmi' - icon_state = "golem" - unacidable = 1 - layer = TURF_LAYER - - New() - ..() - SSobj.processing |= src - -/obj/effect/golemrune/process() - var/mob/dead/observer/ghost - for(var/mob/dead/observer/O in src.loc) - if(!O.client) continue - if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue - ghost = O - break - if(ghost) - icon_state = "golem2" - else - icon_state = "golem" - -/obj/effect/golemrune/attack_hand(mob/living/user as mob) - var/mob/dead/observer/ghost - for(var/mob/dead/observer/O in src.loc) - if(!O.client) continue - if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue - ghost = O - break - if(!ghost) - user << "The rune fizzles uselessly. There is no spirit nearby." - return - var/mob/living/carbon/human/G = new /mob/living/carbon/human - if(prob(50)) G.gender = "female" - hardset_dna(G, null, null, null, null, /datum/species/golem/adamantine) - - G.set_cloned_appearance() - G.real_name = text("Adamantine Golem ([rand(1, 1000)])") - G.dna.species.auto_equip(G) - G.loc = src.loc - G.key = ghost.key - G << "You are an adamantine golem. You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools. Serve [user], and assist them in completing their goals at any cost." - qdel(src) - -/mob/living/carbon/slime/getTrail() - return null - -/mob/living/carbon/slime/slip(var/s_amount, var/w_amount, var/obj/O, var/lube) - if(lube>=2) - return 0 - .=..() - -/mob/living/carbon/slime/stripPanelUnequip(obj/item/what, mob/who) - src << "You don't have the dexterity to do this!" - return - -/mob/living/carbon/slime/stripPanelEquip(obj/item/what, mob/who) - src << "You don't have the dexterity to do this!" - return - - -//////////////////////////////Old shit from metroids/RoRos, and the old cores, would not take much work to re-add them//////////////////////// - -/* -// Basically this slime Core catalyzes reactions that normally wouldn't happen anywhere -/obj/item/slime_core - name = "slime extract" - desc = "Goo extracted from a slime. Legends claim these to have \"magical powers\"." - icon = 'icons/mob/slimes.dmi' - icon_state = "slime extract" - force = 1.0 - w_class = 1.0 - throwforce = 1.0 - throw_speed = 2 - throw_range = 6 - origin_tech = "biotech=4" - var/POWERFLAG = 0 // sshhhhhhh - var/Flush = 30 - var/Uses = 5 // uses before it goes inert - -/obj/item/slime_core/New() - ..() - create_reagents(100) - POWERFLAG = rand(1,10) - Uses = rand(7, 25) - //flags |= NOREACT -/* - spawn() - Life() - - proc/Life() - while(src) - sleep(25) - Flush-- - if(Flush <= 0) - reagents.clear_reagents() - Flush = 30 -*/ - - - -/obj/item/weapon/reagent_containers/food/snacks/egg/slime - name = "slime egg" - desc = "A small, gelatinous egg." - icon = 'icons/mob/mob.dmi' - icon_state = "slime egg-growing" - bitesize = 12 - origin_tech = "biotech=4" - var/grown = 0 - -/obj/item/weapon/reagent_containers/food/snacks/egg/slime/New() - ..() - reagents.add_reagent("nutriment", 4) - reagents.add_reagent("slimejelly", 1) - spawn(rand(1200,1500))//the egg takes a while to "ripen" - Grow() - -/obj/item/weapon/reagent_containers/food/snacks/egg/slime/proc/Grow() - grown = 1 - icon_state = "slime egg-grown" - SSobj.processing.Add(src) - return - -/obj/item/weapon/reagent_containers/food/snacks/egg/slime/proc/Hatch() - SSobj.processing.Remove(src) - var/turf/T = get_turf(src) - src.visible_message(" The [name] pulsates and quivers!") - spawn(rand(50,100)) - src.visible_message(" The [name] bursts open!") - new/mob/living/carbon/slime(T) - qdel(src) - - -/obj/item/weapon/reagent_containers/food/snacks/egg/slime/process() - var/turf/location = get_turf(src) - var/datum/gas_mixture/environment = location.return_air() - if (environment.toxins > MOLES_PLASMA_VISIBLE)//plasma exposure causes the egg to hatch - src.Hatch() - -/obj/item/weapon/reagent_containers/food/snacks/egg/slime/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype( W, /obj/item/toy/crayon )) - return - else - ..() -*/ diff --git a/code/modules/mob/living/carbon/slime/update_icons.dm b/code/modules/mob/living/carbon/slime/update_icons.dm deleted file mode 100644 index 3edf65b6f83..00000000000 --- a/code/modules/mob/living/carbon/slime/update_icons.dm +++ /dev/null @@ -1,4 +0,0 @@ -//no special icon processing - -/mob/living/carbon/slime/update_transform() //They're slimes, they don't lie down. - return \ No newline at end of file diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index 9b0accbe230..a41939c595d 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -32,6 +32,7 @@ flick(flick_name, animate) /mob/living/death(gibbed) + eye_blind = max(eye_blind, 1) timeofdeath = world.time living_mob_list -= src diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index 35817513e08..8c712e7c83c 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -85,6 +85,12 @@ message = "[src] flaps its wings." m_type = 2 + if ("flip") + if (!src.restrained()) + message = "[src] does a flip!" + src.SpinAnimation(5,1) + m_type = 2 + if ("frown") message = "[src] frowns." m_type = 1 diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm new file mode 100644 index 00000000000..89a2a13a753 --- /dev/null +++ b/code/modules/mob/living/life.dm @@ -0,0 +1,180 @@ +/mob/living/Life() + set invisibility = 0 + set background = BACKGROUND_ENABLED + + if (notransform) + return + if(!loc) + return + var/datum/gas_mixture/environment = loc.return_air() + + if(stat != DEAD) + + //Breathing, if applicable + handle_breathing() + + //Mutations and radiation + handle_mutations_and_radiation() + + //Chemicals in the body + handle_chemicals_in_body() + + //Blud + handle_blood() + + //Random events (vomiting etc) + handle_random_events() + + . = 1 + + //Handle temperature/pressure differences between body and environment + if(environment) + handle_environment(environment) + + handle_fire() + + //stuff in the stomach + handle_stomach() + + update_gravity(mob_has_gravity()) + + for(var/obj/item/weapon/grab/G in src) + G.process() + + if(handle_regular_status_updates()) // Status & health update, are we dead or alive etc. + handle_disabilities() // eye, ear, brain damages + handle_status_effects() //all special effects, stunned, weakened, jitteryness, hallucination, sleeping, etc + + update_canmove() + + if(client) + handle_regular_hud_updates() + + return . + + + +/mob/living/proc/handle_breathing() + return + +/mob/living/proc/handle_mutations_and_radiation() + return + +/mob/living/proc/handle_chemicals_in_body() + return + +/mob/living/proc/handle_blood() + return + +/mob/living/proc/handle_random_events() + return + +/mob/living/proc/handle_environment(var/datum/gas_mixture/environment) + return + +/mob/living/proc/handle_stomach() + return + +//This updates the health and status of the mob (conscious, unconscious, dead) +/mob/living/proc/handle_regular_status_updates() + + updatehealth() + + if(stat != DEAD) + + if(paralysis) + stat = UNCONSCIOUS + + else if (status_flags & FAKEDEATH) + stat = UNCONSCIOUS + + else + stat = CONSCIOUS + + return 1 + +//this updates all special effects: stunned, sleeping, weakened, druggy, stuttering, etc.. +/mob/living/proc/handle_status_effects() + if(paralysis) + AdjustParalysis(-1) + if(stunned) + AdjustStunned(-1) + if(!stunned) + update_icons() + + if(weakened) + AdjustWeakened(-1) + if(!weakened) + update_icons() + +/mob/living/proc/handle_disabilities() + //Eyes + if(disabilities & BLIND || stat) //blindness from disability or unconsciousness doesn't get better on its own + eye_blind = max(eye_blind, 1) + else if(eye_blind) //blindness, heals slowly over time + eye_blind = max(eye_blind-1,0) + else if(eye_blurry) //blurry eyes heal slowly + eye_blurry = max(eye_blurry-1, 0) + + //Ears + if(disabilities & DEAF) //disabled-deaf, doesn't get better on its own + setEarDamage(-1, max(ear_deaf, 1)) + else + // deafness heals slowly over time, unless ear_damage is over 100 + if(ear_damage < 100) + adjustEarDamage(-0.05,-1) + + +//this handles hud updates. Calls update_vision() and handle_hud_icons() +/mob/living/proc/handle_regular_hud_updates() + if(!client) return 0 + + handle_vision() + handle_hud_icons() + + return 1 + +/mob/living/proc/handle_vision() + + client.screen.Remove(global_hud.blurry, global_hud.druggy, global_hud.vimpaired, global_hud.darkMask) + + update_sight() + + if(stat != DEAD) + if(blind) + if(eye_blind) + blind.layer = 18 + else + blind.layer = 0 + + if (disabilities & NEARSIGHT) + client.screen += global_hud.vimpaired + + if (eye_blurry) + client.screen += global_hud.blurry + + if (druggy) + client.screen += global_hud.druggy + + if(eye_stat > 20) + if(eye_stat > 30) + client.screen += global_hud.darkMask + else + client.screen += global_hud.vimpaired + + if(machine) + if (!( machine.check_eye(src) )) + reset_view(null) + else + if(!client.adminobs) + reset_view(null) + +/mob/living/proc/update_sight() + return + +/mob/living/proc/handle_hud_icons() + handle_hud_icons_health() + return + +/mob/living/proc/handle_hud_icons_health() + return diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 3772bd681fa..8ad4fa5796c 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -8,7 +8,6 @@ Sorry Giacom. Please don't be mad :( push_mob_back(src, A.push_dir) */ - /mob/living/New() . = ..() generateStaticOverlay() @@ -97,7 +96,7 @@ Sorry Giacom. Please don't be mad :( M.loc = oldloc M.LAssailant = src - for(var/mob/living/carbon/slime/slime in view(1,M)) + for(var/mob/living/simple_animal/slime/slime in view(1,M)) if(slime.Victim == M) slime.UpdateFeed() @@ -443,10 +442,10 @@ Sorry Giacom. Please don't be mad :( C.reagents.clear_reagents() for(var/datum/disease/D in viruses) D.cure(0) - if(stat == 2) + if(stat == DEAD) dead_mob_list -= src living_mob_list += src - if(!isanimal(src)) stat = CONSCIOUS + stat = CONSCIOUS if(ishuman(src)) var/mob/living/carbon/human/human_mob = src human_mob.restore_blood() @@ -454,8 +453,7 @@ Sorry Giacom. Please don't be mad :( update_fire() regenerate_icons() - ..() - return + /mob/living/proc/update_damage_overlays() return @@ -549,7 +547,7 @@ Sorry Giacom. Please don't be mad :( s_active.close(src) if(update_slimes) - for(var/mob/living/carbon/slime/M in view(1,src)) + for(var/mob/living/simple_animal/slime/M in view(1,src)) M.UpdateFeed(src) /mob/living/proc/makeTrail(var/turf/T, var/mob/living/M) @@ -782,6 +780,20 @@ Sorry Giacom. Please don't be mad :( animate(src, pixel_y = initial(pixel_y), time = 10) floating = 0 +//called when the mob receives a bright flash +/mob/living/proc/flash_eyes(intensity = 1, override_blindness_check = 0) + if(check_eye_prot() < intensity && (override_blindness_check || !(disabilities & BLIND))) + flick("e_flash", flash) + return 1 + +//this returns the mob's protection against eye damage (number between -1 and 2) +/mob/living/proc/check_eye_prot() + return 0 + +//this returns the mob's protection against ear damage (0 or 1) +/mob/living/proc/check_ear_prot() + return 0 + // The src mob is trying to strip an item from someone // Override if a certain type of mob should be behave differently when stripping items (can't, for example) /mob/living/stripPanelUnequip(obj/item/what, mob/who, where) @@ -869,3 +881,28 @@ Sorry Giacom. Please don't be mad :( animate(pixel_x = initial(pixel_x) , pixel_y = initial(pixel_y) , time = 2) floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure to restart it in next life(). +/mob/living/proc/get_temperature(var/datum/gas_mixture/environment) + var/loc_temp = T0C + if(istype(loc, /obj/mecha)) + var/obj/mecha/M = loc + loc_temp = M.return_temperature() + + else if(istype(loc, /obj/structure/transit_tube_pod)) + loc_temp = environment.temperature + + else if(istype(get_turf(src), /turf/space)) + var/turf/heat_turf = get_turf(src) + loc_temp = heat_turf.temperature + + else if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) + var/obj/machinery/atmospherics/unary/cryo_cell/C = loc + + if(C.air_contents.total_moles() < 10) + loc_temp = environment.temperature + else + loc_temp = C.air_contents.temperature + + else + loc_temp = environment.temperature + + return loc_temp diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 812d9705c4f..28acd2aa693 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -138,8 +138,7 @@ proc/vol_by_throwforce_and_or_w_class(var/obj/item/I) /mob/living/acid_act(var/acidpwr, var/toxpwr, var/acid_volume) - if(!unacidable) - take_organ_damage(min(10*toxpwr, acid_volume * toxpwr)) + take_organ_damage(min(10*toxpwr, acid_volume * toxpwr)) /mob/living/proc/grabbedby(mob/living/carbon/user) if(user == src || anchored) @@ -162,7 +161,7 @@ proc/vol_by_throwforce_and_or_w_class(var/obj/item/I) visible_message("[user] has grabbed [src] passively!") -/mob/living/attack_slime(mob/living/carbon/slime/M as mob) +/mob/living/attack_slime(mob/living/simple_animal/slime/M as mob) if (!ticker) M << "You cannot attack people before the game has started." return @@ -171,26 +170,11 @@ proc/vol_by_throwforce_and_or_w_class(var/obj/item/I) return // can't attack while eating! if (stat != DEAD) + add_logs(M, src, "attacked", admin=0) M.do_attack_animation(src) visible_message("The [M.name] glomps [src]!", \ "The [M.name] glomps [src]!") - - if(M.powerlevel > 0) - var/stunprob = M.powerlevel * 7 + 10 // 17 at level 1, 80 at level 10 - if(prob(stunprob)) - M.powerlevel -= 3 - if(M.powerlevel < 0) - M.powerlevel = 0 - - visible_message("The [M.name] has shocked [src]!", \ - "The [M.name] has shocked [src]!") - - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(5, 1, src) - s.start() - return 1 - add_logs(M, src, "attacked", admin=0) - return + return 1 /mob/living/attack_animal(mob/living/simple_animal/M as mob) if(M.melee_damage_upper == 0) diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index e1f88b45cb0..f949030014d 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -39,8 +39,7 @@ var/ventcrawler = 0 //0 No vent crawling, 1 vent crawling in the nude, 2 vent crawling always var/floating = 0 - var/nightvision = 0 - var/mob_size = 1 //size of the mob. 0 is small, 1 is human sized, and 2 is large. + var/mob_size = MOB_SIZE_HUMAN var/metabolism_efficiency = 1 //more or less efficiency to metabolize helpful/harmful reagents and regulate body temperature.. var/list/image/staticOverlays = list() \ No newline at end of file diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index d158b3648c1..c7a13f69e26 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -1,22 +1,3 @@ -//bitflag #defines for radio return. -#define ITALICS 1 -#define REDUCE_RANGE 2 -#define NOPASS 4 - -//message modes. you're not supposed to mess with these. -#define MODE_HEADSET "headset" -#define MODE_ROBOT "robot" -#define MODE_R_HAND "right hand" -#define MODE_L_HAND "left hand" -#define MODE_INTERCOM "intercom" -#define MODE_BINARY "binary" -#define MODE_WHISPER "whisper" -#define MODE_SECURE_HEADSET "secure headset" -#define MODE_DEPARTMENT "department" -#define MODE_ALIEN "alientalk" -#define MODE_HOLOPAD "holopad" -#define MODE_CHANGELING "changeling" - var/list/department_radio_keys = list( ":r" = "right hand", "#r" = "right hand", ".r" = "right hand", ":l" = "left hand", "#l" = "left hand", ".l" = "left hand", @@ -73,10 +54,7 @@ var/list/department_radio_keys = list( ":ï" = "changeling", "#ï" = "changeling", ".ï" = "changeling" ) -/mob/proc/binarycheck() - return 0 - -/mob/living/say(message, bubble_type) +/mob/living/say(message, bubble_type,) message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) if(stat == DEAD) @@ -108,17 +86,18 @@ var/list/department_radio_keys = list( return message = treat_message(message) + var/spans = list() + spans += get_spans() if(!message || message == "") return - var/italics = 0 var/message_range = 7 - var/radio_return = radio(message, message_mode) + var/radio_return = radio(message, message_mode, spans) if(radio_return & NOPASS) //There's a whisper() message_mode, no need to continue the proc if that is called return if(radio_return & ITALICS) - italics = 1 + spans |= SPAN_ITALICS if(radio_return & REDUCE_RANGE) message_range = 1 @@ -130,64 +109,50 @@ var/list/department_radio_keys = list( message_range = 1 if(pressure < ONE_ATMOSPHERE*0.4) //Thin air, let's italicise the message - italics = 1 + spans |= SPAN_ITALICS - if(italics) - message = "[message]" - - send_speech(message, message_range, src, bubble_type) + send_speech(message, message_range, src, bubble_type, spans) log_say("[name]/[key] : [message]") return 1 -/mob/living/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq) +/mob/living/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans) if(!client) return var/deaf_message var/deaf_type if(speaker != src) if(!radio_freq) //These checks have to be seperate, else people talking on the radio will make "You can't hear yourself!" appear when hearing people over the radio while deaf. - deaf_message = "[speaker] talks but you cannot hear them." + deaf_message = "[speaker] [speaker.verb_say] something but you cannot hear them." deaf_type = 1 else deaf_message = "You can't hear yourself!" deaf_type = 2 // Since you should be able to hear yourself without looking if(!(message_langs & languages) || force_compose) //force_compose is so AIs don't end up without their hrefs. - message = compose_message(speaker, message_langs, raw_message, radio_freq) + message = compose_message(speaker, message_langs, raw_message, radio_freq, spans) show_message(message, 2, deaf_message, deaf_type) return message -/mob/living/send_speech(message, message_range = 7, obj/source = src, bubble_type) +/mob/living/send_speech(message, message_range = 7, obj/source = src, bubble_type, list/spans) var/list/listening = get_hearers_in_view(message_range, source) - var/list/listening_dead = list() for(var/mob/M in player_list) if(M.stat == DEAD && M.client && ((M.client.prefs.chat_toggles & CHAT_GHOSTEARS) || (get_dist(M, src) <= 7)) && client) // client is so that ghosts don't have to listen to mice - listening_dead |= M + listening |= M - listening -= listening_dead //so ghosts dont hear stuff twice - - var/rendered = compose_message(src, languages, message) + var/rendered = compose_message(src, languages, message, , spans) for(var/atom/movable/AM in listening) - AM.Hear(rendered, src, languages, message) - - for(var/mob/M in listening_dead) - M.Hear(rendered, src, languages, message) + AM.Hear(rendered, src, languages, message, , spans) //speech bubble var/list/speech_bubble_recipients = list() - for(var/mob/M in (listening + listening_dead)) + for(var/mob/M in listening) if(M.client) speech_bubble_recipients.Add(M.client) spawn(0) flick_overlay(image('icons/mob/talk.dmi', src, "h[bubble_type][say_test(message)]",MOB_LAYER+1), speech_bubble_recipients, 30) -/mob/living/proc/say_test(var/text) - var/ending = copytext(text, length(text)) - if (ending == "?") - return "1" - else if (ending == "!") - return "2" - return "0" +/mob/proc/binarycheck() + return 0 /mob/living/can_speak(message) //For use outside of Say() if(can_speak_basic(message) && can_speak_vocal(message)) @@ -268,21 +233,21 @@ var/list/department_radio_keys = list( return message -/mob/living/proc/radio(message, message_mode, steps) +/mob/living/proc/radio(message, message_mode, list/spans) switch(message_mode) if(MODE_R_HAND) if (r_hand) - r_hand.talk_into(src, message) + r_hand.talk_into(src, message, , spans) return ITALICS | REDUCE_RANGE if(MODE_L_HAND) if (l_hand) - l_hand.talk_into(src, message) + l_hand.talk_into(src, message, , spans) return ITALICS | REDUCE_RANGE if(MODE_INTERCOM) for (var/obj/item/device/radio/intercom/I in view(1, null)) - I.talk_into(src, message) + I.talk_into(src, message, , spans) return ITALICS | REDUCE_RANGE if(MODE_BINARY) @@ -302,9 +267,10 @@ var/list/department_radio_keys = list( return 1 return 0 -/mob/living/say_quote() +/mob/living/say_quote(input, list/spans) + var/tempinput = attach_spans(input, spans) if (stuttering) - return "stammers, \"[text]\"" + return "stammers, \"[tempinput]\"" if (getBrainLoss() >= 60) - return "gibbers, \"[text]\"" + return "gibbers, \"[tempinput]\"" return ..() diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 1b3b9fbe187..05ba0479602 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -783,6 +783,6 @@ var/list/ai_list = list() set_autosay() -/mob/living/silicon/ai/attack_slime(mob/living/carbon/slime/user) +/mob/living/silicon/ai/attack_slime(mob/living/simple_animal/slime/user) return diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index a3fd584aac4..8566b31eff0 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -1,11 +1,11 @@ /mob/living/silicon/ai/Life() - if (src.stat == 2) + if (src.stat == DEAD) return else //I'm not removing that shitton of tabs, unneeded as they are. -- Urist //Being dead doesn't mean your temperature never changes var/turf/T = get_turf(src) - if (src.stat!=0) + if (src.stat!= CONSCIOUS) src.cameraFollow = null src.reset_view(null) src.unset_machine() diff --git a/code/modules/mob/living/silicon/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm index e10b6e59fc4..f448d22680b 100644 --- a/code/modules/mob/living/silicon/ai/say.dm +++ b/code/modules/mob/living/silicon/ai/say.dm @@ -19,26 +19,14 @@ //Also includes the for AI hrefs, for convenience. return " [radio_freq ? "(" + speaker.GetJob() + ")" : ""]" + "[speaker.GetSource() ? "" : ""]" -/mob/living/silicon/ai/say_quote(var/text) - var/ending = copytext(text, length(text)) - - if(ending == "?") - return "queries, \"[text]\""; - else if(copytext(text, length(text) - 1) == "!!") - return "alarms, \"[text]\""; - else if(ending == "!") - return "declares, \"[text]\""; - - return "states, \"[text]\""; - /mob/living/silicon/ai/IsVocal() return !config.silent_ai -/mob/living/silicon/ai/radio(message, message_mode) +/mob/living/silicon/ai/radio(message, message_mode, list/spans) if(!radio_enabled || aiRestorePowerRoutine || stat) //AI cannot speak if radio is disabled (via intellicard) or depowered. src << "Your radio transmitter is offline!" return 0 - ..(message,message_mode) + ..() /mob/living/silicon/ai/get_message_mode(message) if(copytext(message, 1, 3) in list(":h", ":H", ".h", ".H", "#h", "#H")) diff --git a/code/modules/mob/living/silicon/pai/life.dm b/code/modules/mob/living/silicon/pai/life.dm index 04e80299d9a..c0017863de6 100644 --- a/code/modules/mob/living/silicon/pai/life.dm +++ b/code/modules/mob/living/silicon/pai/life.dm @@ -1,5 +1,5 @@ /mob/living/silicon/pai/Life() - if (src.stat == 2) + if (src.stat == DEAD) return if(src.cable) if(get_dist(src, src.cable) > 1) diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 8962f12e241..8e0c98192a7 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -3,7 +3,7 @@ icon = 'icons/obj/status_display.dmi' //invisibility! mouse_opacity = 0 density = 0 - mob_size = 0 + mob_size = MOB_SIZE_SMALL var/network = "SS13" var/obj/machinery/camera/current = null diff --git a/code/modules/mob/living/silicon/pai/say.dm b/code/modules/mob/living/silicon/pai/say.dm index 81b1840e879..6e93366f713 100644 --- a/code/modules/mob/living/silicon/pai/say.dm +++ b/code/modules/mob/living/silicon/pai/say.dm @@ -1,15 +1,3 @@ -/mob/living/silicon/pai/say_quote(var/text) - var/ending = copytext(text, length(text)) - - if (ending == "?") - return "[src.speakQuery], \"[text]\""; - else if(copytext(text, length(text) - 1) == "!!") - return "[src.speakDoubleExclamation], \"[text]\""; - else if (ending == "!") - return "[src.speakExclamation], \"[text]\""; - - return "[src.speakStatement], \"[text]\""; - /mob/living/silicon/pai/say(var/msg) if(silence_time) src << "Communication circuits remain unitialized." diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index 949e1df5b5b..c7e6135380f 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -109,7 +109,7 @@
    [right_part]
    - "} + "} //" usr << browse(dat, "window=pai;size=640x480;border=0;can_close=1;can_resize=1;can_minimize=1;titlebar=1") onclose(usr, "pai") temp = null @@ -252,7 +252,7 @@ add_med_hud() if("translator") if(href_list["toggle"]) - languages = languages == ALL ? HUMAN & ROBOT : ALL + languages = (languages == ALL) ? (HUMAN | ROBOT) : ALL if("doorjack") if(href_list["jack"]) if(src.cable && src.cable.machine) diff --git a/code/modules/mob/living/silicon/robot/death.dm b/code/modules/mob/living/silicon/robot/death.dm index e8767275e01..e12b5db835b 100644 --- a/code/modules/mob/living/silicon/robot/death.dm +++ b/code/modules/mob/living/silicon/robot/death.dm @@ -19,7 +19,8 @@ ..(animate, "dust-r") /mob/living/silicon/robot/death(gibbed) - if(stat == DEAD) return + if(stat == DEAD) + return if(!gibbed) emote("deathgasp") stat = DEAD @@ -29,7 +30,8 @@ uneq_all() // particularly to ensure sight modes are cleared - if(blind) blind.layer = 0 + if(blind) + blind.layer = 0 sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS see_in_dark = 8 see_invisible = SEE_INVISIBLE_LEVEL_TWO diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index d90e464cee2..09aef431b21 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -5,23 +5,8 @@ if (src.notransform) return - //Status updates, death etc. clamp_values() - handle_regular_status_updates() - - if(client) - handle_regular_hud_updates() - update_items() - if (src.stat != DEAD) //still using power - use_power() - - update_canmove() - - update_gravity(mob_has_gravity()) - - handle_fire() - - + ..() /mob/living/silicon/robot/proc/clamp_values() @@ -36,51 +21,40 @@ /mob/living/silicon/robot/proc/use_power() - if (src.cell) - if(src.cell.charge <= 0) + if(cell) + if(cell.charge <= 0) uneq_all() - src.stat = 1 - else if (src.cell.charge <= 100) + stat = UNCONSCIOUS + else if (cell.charge <= 100) uneq_all() - src.cell.use(1) + cell.use(1) else - if(src.module_state_1) - src.cell.use(5) - if(src.module_state_2) - src.cell.use(5) - if(src.module_state_3) - src.cell.use(5) - src.cell.use(1) - src.eye_blind = 0 - src.stat = 0 + if(module_state_1) + cell.use(5) + if(module_state_2) + cell.use(5) + if(module_state_3) + cell.use(5) + cell.use(1) else uneq_all() - src.stat = 1 + stat = UNCONSCIOUS -/mob/living/silicon/robot/proc/handle_regular_status_updates() +/mob/living/silicon/robot/handle_regular_status_updates() - if(src.camera && !scrambledcodes) - if(src.stat == 2 || wires.IsCameraCut()) - src.camera.status = 0 + if(camera && !scrambledcodes) + if(stat == DEAD || wires.IsCameraCut()) + camera.status = 0 else - src.camera.status = 1 + camera.status = 1 - health = maxHealth - (getOxyLoss() + getFireLoss() + getBruteLoss()) + if (..()) //Alive. - if(getOxyLoss() > 50) Paralyse(3) + if(health <= config.health_threshold_dead) //die only once + death() + return - if(src.sleeping) - Paralyse(3) - src.sleeping-- - - if(src.resting) - Weaken(5) - - if(health <= config.health_threshold_dead && src.stat != 2) //die only once - death() - - if (src.stat != 2) //Alive. if(health < 50) //Gradual break down of modules as more damage is sustained if(uneq_module(module_state_3)) src << "SYSTEM ERROR: Module 3 OFFLINE." @@ -91,47 +65,48 @@ if(uneq_module(module_state_1)) src << "CRITICAL ERROR: All modules OFFLINE." - if (src.paralysis || src.stunned || src.weakened) //Stunned etc. - src.stat = 1 - if (src.stunned > 0) - AdjustStunned(-1) - if (src.weakened > 0) - AdjustWeakened(-1) - if (src.paralysis > 0) - AdjustParalysis(-1) - src.eye_blind = max(eye_blind, 1) - else - src.eye_blind = 0 + if(getOxyLoss() > 50) + Paralyse(3) - else //Not stunned. - src.stat = 0 + if (paralysis || stunned || weakened) //Stunned etc. + stat = UNCONSCIOUS - else //Dead. - src.eye_blind = 1 + use_power() - if (src.stuttering) src.stuttering-- + return 1 - if (src.eye_blind) - src.eye_blind-- +/mob/living/silicon/robot/handle_status_effects() + ..() + if (stuttering) + stuttering = max(0, stuttering - 1) - src.density = !( src.lying ) + if (druggy) + druggy = max(0, druggy - 1) - if (src.disabilities & BLIND) - src.eye_blind = max(1, eye_blind) +/mob/living/silicon/robot/handle_regular_hud_updates() - if (src.eye_blurry > 0) - src.eye_blurry-- - src.eye_blurry = max(0, src.eye_blurry) - - if (src.druggy > 0) - src.druggy-- - src.druggy = max(0, src.druggy) + if(!client) + return + if (syndicate) + if(ticker.mode.name == "traitor") + for(var/datum/mind/tra in ticker.mode.traitors) + if(tra.current) + var/I = image('icons/mob/mob.dmi', loc = tra.current, icon_state = "traitor") //no traitor sprite in that dmi! + src.client.images += I + if(connected_ai) + connected_ai.connected_robots -= src + connected_ai = null + if(mind) + if(!mind.special_role) + mind.special_role = "traitor" + ticker.mode.traitors += mind + ..() return 1 -/mob/living/silicon/robot/proc/handle_regular_hud_updates() +/mob/living/silicon/robot/update_sight() - if (src.stat == 2 || src.sight_mode & BORGXRAY) + if (stat == DEAD || src.sight_mode & BORGXRAY) src.sight |= SEE_TURFS src.sight |= SEE_MOBS src.sight |= SEE_OBJS @@ -150,7 +125,7 @@ else if (src.sight_mode & BORGTHERM) src.sight |= SEE_MOBS src.see_invisible = SEE_INVISIBLE_LEVEL_TWO - else if (src.stat != 2) + else if (src.stat != DEAD) src.sight &= ~SEE_MOBS src.sight &= ~SEE_TURFS src.sight &= ~SEE_OBJS @@ -158,39 +133,32 @@ if(see_override) see_invisible = see_override - if (src.healths) - if (src.stat != 2) +/mob/living/silicon/robot/handle_hud_icons() + update_items() + update_cell() + ..() + +/mob/living/silicon/robot/handle_hud_icons_health() + if (healths) + if (stat != DEAD) switch(health) if(100 to INFINITY) - src.healths.icon_state = "health0" + healths.icon_state = "health0" if(50 to 100) - src.healths.icon_state = "health2" + healths.icon_state = "health2" if(0 to 50) - src.healths.icon_state = "health3" + healths.icon_state = "health3" if(-50 to 0) - src.healths.icon_state = "health4" + healths.icon_state = "health4" if(config.health_threshold_dead to -50) - src.healths.icon_state = "health5" + healths.icon_state = "health5" else - src.healths.icon_state = "health6" + healths.icon_state = "health6" else - src.healths.icon_state = "health7" + healths.icon_state = "health7" - if (src.syndicate && src.client) - if(ticker.mode.name == "traitor") - for(var/datum/mind/tra in ticker.mode.traitors) - if(tra.current) - var/I = image('icons/mob/mob.dmi', loc = tra.current, icon_state = "traitor") - src.client.images += I - if(src.connected_ai) - src.connected_ai.connected_robots -= src - src.connected_ai = null - if(src.mind) - if(!src.mind.special_role) - src.mind.special_role = "traitor" - ticker.mode.traitors += src.mind - - if (src.cell) +/mob/living/silicon/robot/proc/update_cell() + if (cell) var/cellcharge = src.cell.charge/src.cell.maxcharge switch(cellcharge) if(0.75 to INFINITY) @@ -206,51 +174,18 @@ else throw_alert("charge","nocell") - - if(pullin) - if(pulling) - pullin.icon_state = "pull" - else - pullin.icon_state = "pull0" - - client.screen.Remove(global_hud.blurry,global_hud.druggy,global_hud.vimpaired) - - if ((src.blind && src.stat != 2)) - if(src.eye_blind) - src.blind.layer = 18 - else - src.blind.layer = 0 - if (src.disabilities & NEARSIGHT) - src.client.screen += global_hud.vimpaired - - if (src.eye_blurry) - src.client.screen += global_hud.blurry - - if (src.druggy) - src.client.screen += global_hud.druggy - - if (src.stat != 2) - if (src.machine) - if (!( src.machine.check_eye(src) )) - src.reset_view(null) - else - if(!client.adminobs) - reset_view(null) - - return 1 - /mob/living/silicon/robot/proc/update_items() - if (src.client) - src.client.screen -= src.contents - for(var/obj/I in src.contents) + if (client) + client.screen -= contents + for(var/obj/I in contents) if(I && !(istype(I,/obj/item/weapon/stock_parts/cell) || istype(I,/obj/item/device/radio) || istype(I,/obj/machinery/camera) || istype(I,/obj/item/device/mmi))) - src.client.screen += I - if(src.module_state_1) - src.module_state_1:screen_loc = ui_inv1 - if(src.module_state_2) - src.module_state_2:screen_loc = ui_inv2 - if(src.module_state_3) - src.module_state_3:screen_loc = ui_inv3 + client.screen += I + if(module_state_1) + module_state_1:screen_loc = ui_inv1 + if(module_state_2) + module_state_2:screen_loc = ui_inv2 + if(module_state_3) + module_state_3:screen_loc = ui_inv3 //Robots on fire @@ -276,6 +211,8 @@ IgniteMob() /mob/living/silicon/robot/update_canmove() - if(paralysis || stunned || weakened || buckled || lockcharge) canmove = 0 - else canmove = 1 + if(paralysis || stunned || weakened || buckled || lockcharge) + canmove = 0 + else + canmove = 1 return canmove diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 9b0ada14b2b..6fcf7c2c9d1 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -123,7 +123,7 @@ if(mmi.brainmob) mind.transfer_to(mmi.brainmob) else - src << "Oops! Something went very wrong, your MMI was unable to receive your mind. You have been ghosted. Please make a bug report so we can fix this bug." + src << "Oops! Something went very wrong, your MMI was unable to receive your mind. You have been ghosted. Please make a bug report so we can fix this bug." ghostize() ERROR("A borg has been destroyed, but its MMI lacked a brainmob, so the mind could not be transferred. Player: [ckey].") mmi = null @@ -469,7 +469,7 @@ else if(istype(W, /obj/item/weapon/wrench) && opened && !cell) //Deconstruction. The flashes break from the fall, to prevent this from being a ghetto reset module. if(!lockcharge) - user << "[src]'s bolts spark! Maybe you should lock them down first!" + user << "[src]'s bolts spark! Maybe you should lock them down first!" spark_system.start() return else @@ -636,7 +636,7 @@ -/mob/living/silicon/robot/attack_slime(mob/living/carbon/slime/M as mob) +/mob/living/silicon/robot/attack_slime(mob/living/simple_animal/slime/M as mob) if(..()) //successful slime shock flick("noise", flash) var/stunprob = M.powerlevel * 7 + 10 diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 1afc3eaea7f..374bfa98088 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -237,7 +237,7 @@ ..() modules += new /obj/item/borg/sight/meson(src) emag = new /obj/item/borg/stun(src) - modules += new /obj/item/weapon/storage/bag/ore(src) + modules += new /obj/item/weapon/storage/bag/ore/cyborg(src) modules += new /obj/item/weapon/pickaxe/drill/cyborg(src) modules += new /obj/item/weapon/shovel(src) modules += new /obj/item/device/flashlight/lantern(src) diff --git a/code/modules/mob/living/silicon/robot/say.dm b/code/modules/mob/living/silicon/robot/say.dm index 8cf1cd3fc2e..e28efe10f32 100644 --- a/code/modules/mob/living/silicon/robot/say.dm +++ b/code/modules/mob/living/silicon/robot/say.dm @@ -1,14 +1,2 @@ -/mob/living/silicon/robot/say_quote(var/text) - var/ending = copytext(text, length(text)) - - if(ending == "?") - return "queries, \"[text]\""; - else if(copytext(text, length(text) - 1) == "!!") - return "alarms, \"[text]\""; - else if(ending == "!") - return "declares, \"[text]\""; - - return "states, \"[text]\""; - /mob/living/silicon/robot/IsVocal() return !config.silent_borg diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm index 9dd1325113a..f15bf738781 100644 --- a/code/modules/mob/living/silicon/say.dm +++ b/code/modules/mob/living/silicon/say.dm @@ -1,6 +1,9 @@ /mob/living/silicon/say(var/message) return ..(message, "R") +/mob/living/silicon/get_spans() + return ..() | SPAN_ROBOT + /mob/living/proc/robot_talk(var/message) log_say("[key_name(src)] : [message]") var/desig = "Default Cyborg" //ezmode for taters @@ -23,19 +26,19 @@ /mob/living/silicon/lingcheck() return 0 //Borged or AI'd lings can't speak on the ling channel. -/mob/living/silicon/radio(message, message_mode) +/mob/living/silicon/radio(message, message_mode, list/spans) . = ..() if(. != 0) return . if(message_mode == "robot") if (radio) - radio.talk_into(src, message) + radio.talk_into(src, message, , spans) return REDUCE_RANGE else if(message_mode in radiochannels) if(radio) - radio.talk_into(src, message, message_mode) + radio.talk_into(src, message, message_mode, spans) return ITALICS | REDUCE_RANGE return 0 diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 461456ff887..24bb007c3d2 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -3,6 +3,10 @@ voice_name = "synthesized voice" languages = ROBOT | HUMAN has_unlimited_silicon_privilege = 1 + verb_say = "states" + verb_ask = "queries" + verb_exclaim = "declares" + verb_yell = "alarms" var/syndicate = 0 var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS var/list/alarms_to_show = list() @@ -22,6 +26,8 @@ var/med_hud = DATA_HUD_MEDICAL_ADVANCED //Determines the med hud to use var/sec_hud = DATA_HUD_SECURITY_ADVANCED //Determines the sec hud to use + var/law_change_counter = 0 + /mob/living/silicon/contents_explosion(severity, target) return @@ -338,7 +344,7 @@ var/datum/atom_hud/medsensor = huds[med_hud] medsensor.add_hud_to(src) -/mob/living/silicon/verb/sensor_mode() +/mob/living/silicon/proc/sensor_mode() set name = "Set Sensor Augmentation" var/sensor_type = input("Please select sensor type.", "Sensor Integration", null) in list("Security", "Medical","Disable") remove_med_sec_hud() @@ -416,6 +422,9 @@ /mob/living/silicon/setEarDamage() return +/mob/living/silicon/check_eye_prot() + return 2 + /mob/living/silicon/proc/GetPhoto() if (aicamera) return aicamera.selectpicture(aicamera) diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index 2f515596d37..4005451ecc9 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -7,21 +7,13 @@ response_help = "thinks better of touching" response_disarm = "flails at" response_harm = "punches" - icon_dead = "shade_dead" icon = 'icons/mob/mob.dmi' speed = 0 a_intent = "harm" stop_automated_movement = 1 status_flags = CANPUSH attack_sound = 'sound/weapons/punch1.ogg' - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 faction = list("cult") var/list/construct_spells = list() @@ -34,8 +26,8 @@ for(var/spell in construct_spells) mob_spell_list += new spell(src) -/mob/living/simple_animal/construct/Die() - ..() +/mob/living/simple_animal/construct/death() + ..(1) new /obj/item/weapon/ectoplasm (src.loc) visible_message("[src] collapses in a shattered heap.") ghostize() @@ -57,7 +49,7 @@ /mob/living/simple_animal/construct/attack_animal(mob/living/simple_animal/M as mob) if(istype(M, /mob/living/simple_animal/construct/builder)) - health += 5 + adjustBruteLoss(-5) M.emote("me", 1, "mends some of \the [src]'s wounds.") else if(src != M) ..() @@ -94,7 +86,7 @@ environment_smash = 2 attack_sound = 'sound/weapons/punch3.ogg' status_flags = 0 - mob_size = 2 + mob_size = MOB_SIZE_SMALL force_threshold = 11 construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/lesserforcewall) playstyle_string = "You are a Juggernaut. Though slow, your shell can withstand extreme punishment, \ diff --git a/code/modules/mob/living/simple_animal/friendly/butterfly.dm b/code/modules/mob/living/simple_animal/friendly/butterfly.dm index ee9bdc720ac..e4f9e562e37 100644 --- a/code/modules/mob/living/simple_animal/friendly/butterfly.dm +++ b/code/modules/mob/living/simple_animal/friendly/butterfly.dm @@ -16,7 +16,7 @@ friendly = "nudges" pass_flags = PASSTABLE ventcrawler = 2 - mob_size = 0 + mob_size = MOB_SIZE_SMALL /mob/living/simple_animal/butterfly/New() ..() diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index b449ffb30bf..16d35c5a486 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -1,7 +1,8 @@ //Cat -/mob/living/simple_animal/cat +/mob/living/simple_animal/pet/cat name = "cat" desc = "Kitty!!" + icon = 'icons/mob/pets.dmi' icon_state = "cat2" icon_living = "cat2" icon_dead = "cat2_dead" @@ -13,8 +14,8 @@ speak_chance = 1 turns_per_move = 5 see_in_dark = 6 - species = /mob/living/simple_animal/cat - childtype = /mob/living/simple_animal/cat/kitten + species = /mob/living/simple_animal/pet/cat + childtype = /mob/living/simple_animal/pet/cat/kitten meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat meat_amount = 3 response_help = "pets" @@ -22,7 +23,7 @@ response_harm = "kicks" //RUNTIME IS ALIVE! SQUEEEEEEEE~ -/mob/living/simple_animal/cat/Runtime +/mob/living/simple_animal/pet/cat/Runtime name = "Runtime" desc = "GCAT" icon_state = "cat" @@ -31,8 +32,9 @@ gender = FEMALE var/turns_since_scan = 0 var/mob/living/simple_animal/mouse/movement_target + pcollar = /obj/item/clothing/tie/petcollar -/mob/living/simple_animal/cat/Runtime/Life() +/mob/living/simple_animal/pet/cat/Runtime/Life() //MICE! if((src.loc) && isturf(src.loc)) if(!stat && !resting && !buckled) @@ -67,14 +69,14 @@ stop_automated_movement = 1 walk_to(src,movement_target,0,3) -/mob/living/simple_animal/cat/Proc +/mob/living/simple_animal/pet/cat/Proc name = "Proc" -/mob/living/simple_animal/cat/kitten +/mob/living/simple_animal/pet/cat/kitten name = "kitten" desc = "D'aaawwww" icon_state = "kitten" icon_living = "kitten" icon_dead = "kitten_dead" gender = NEUTER - mob_size = 0 + mob_size = MOB_SIZE_SMALL diff --git a/code/modules/mob/living/simple_animal/friendly/corgi.dm b/code/modules/mob/living/simple_animal/friendly/corgi.dm index 6cfff764b88..1521cf8602e 100644 --- a/code/modules/mob/living/simple_animal/friendly/corgi.dm +++ b/code/modules/mob/living/simple_animal/friendly/corgi.dm @@ -1,5 +1,42 @@ //Corgi -/mob/living/simple_animal/corgi +/mob/living/simple_animal/pet + icon = 'icons/mob/pets.dmi' + var/obj/item/clothing/tie/petcollar/pcollar = null + var/image/collar = null + var/image/pettag = null + var/accept_collar = 1 + +/mob/living/simple_animal/pet/attackby(var/obj/item/O as obj, var/mob/user as mob, params) + if(istype(O, /obj/item/clothing/tie/petcollar) && accept_collar && !pcollar) + var/obj/item/clothing/tie/petcollar/P = O + pcollar = P + update_collar() + if(P.tagname) + name = P.tagname + user << "You put the [P] around [src]'s neck." + qdel(P) + else + ..() + +/mob/living/simple_animal/pet/New() + ..() + if(pcollar) + pcollar = new(src) + update_collar() + +/mob/living/simple_animal/pet/death(gibbed) + ..(gibbed) + update_collar() + +/mob/living/simple_animal/pet/proc/update_collar() + overlays.Cut() + collar = image('icons/mob/pets.dmi', src, "[icon_state]collar") + pettag = image('icons/mob/pets.dmi', src, "[icon_state]tag") + overlays += collar + overlays += pettag + + +/mob/living/simple_animal/pet/corgi name = "\improper corgi" real_name = "corgi" desc = "It's a corgi." @@ -19,31 +56,32 @@ response_disarm = "bops" response_harm = "kicks" see_in_dark = 5 - childtype = /mob/living/simple_animal/corgi/puppy - species = /mob/living/simple_animal/corgi + childtype = /mob/living/simple_animal/pet/corgi/puppy + species = /mob/living/simple_animal/pet/corgi var/obj/item/inventory_head var/obj/item/inventory_back var/facehugger + accept_collar = 0 //corgis have their own item handling -/mob/living/simple_animal/corgi/New() +/mob/living/simple_animal/pet/corgi/New() ..() regenerate_icons() -/mob/living/simple_animal/corgi/Die() +/mob/living/simple_animal/pet/corgi/death(gibbed) + ..(gibbed) + regenerate_icons() + +/mob/living/simple_animal/pet/corgi/revive() ..() regenerate_icons() -/mob/living/simple_animal/corgi/revive() - ..() - regenerate_icons() - -/mob/living/simple_animal/corgi/sac_act(var/obj/effect/rune/R, victim) +/mob/living/simple_animal/pet/corgi/sac_act(var/obj/effect/rune/R, victim) usr << "Even dark gods from another plane have standards, sicko." usr.reagents.add_reagent("hell_water", 2) R.stone_or_gib(victim) -/mob/living/simple_animal/corgi/show_inv(mob/user as mob) +/mob/living/simple_animal/pet/corgi/show_inv(mob/user as mob) user.set_machine(src) if(user.stat) return @@ -61,7 +99,7 @@ onclose(user, "mob[real_name]") return -/mob/living/simple_animal/corgi/attackby(var/obj/item/O as obj, var/mob/user as mob, params) +/mob/living/simple_animal/pet/corgi/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(inventory_head && inventory_back) //helmet and armor = 100% protection if( istype(inventory_head,/obj/item/clothing/head/helmet) && istype(inventory_back,/obj/item/clothing/suit/armor) ) @@ -86,7 +124,7 @@ ..() -/mob/living/simple_animal/corgi/Topic(href, href_list) +/mob/living/simple_animal/pet/corgi/Topic(href, href_list) if(usr.stat) return //Removing from inventory @@ -156,7 +194,8 @@ /obj/item/clothing/suit/cardborg, /obj/item/weapon/tank/internals/oxygen, /obj/item/weapon/tank/internals/air, - /obj/item/weapon/extinguisher + /obj/item/weapon/extinguisher, + /obj/item/clothing/tie/petcollar ) if( ! ( item_to_add.type in allowed_types ) ) @@ -184,7 +223,7 @@ //Corgis are supposed to be simpler, so only a select few objects can actually be put //to be compatible with them. The objects are below. //Many hats added, Some will probably be removed, just want to see which ones are popular. -/mob/living/simple_animal/corgi/proc/place_on_head(obj/item/item_to_add, var/mob/user as mob) +/mob/living/simple_animal/pet/corgi/proc/place_on_head(obj/item/item_to_add, var/mob/user as mob) if(istype(item_to_add,/obj/item/weapon/c4)) // last thing he ever wears, I guess item_to_add.afterattack(src,user,1) @@ -361,7 +400,7 @@ //IAN! SQUEEEEEEEEE~ -/mob/living/simple_animal/corgi/Ian +/mob/living/simple_animal/pet/corgi/Ian name = "Ian" real_name = "Ian" //Intended to hold the name without altering it. gender = MALE @@ -372,7 +411,7 @@ response_disarm = "bops" response_harm = "kicks" -/mob/living/simple_animal/corgi/Ian/Life() +/mob/living/simple_animal/pet/corgi/Ian/Life() ..() //Feeding, chasing food, FOOOOODDDD @@ -428,7 +467,7 @@ -/mob/living/simple_animal/corgi/regenerate_icons() +/mob/living/simple_animal/pet/corgi/regenerate_icons() overlays.Cut() if(inventory_head) @@ -452,7 +491,7 @@ overlays += back_icon if(facehugger) - if(istype(src, /mob/living/simple_animal/corgi/puppy)) + if(istype(src, /mob/living/simple_animal/pet/corgi/puppy)) overlays += image('icons/mob/mask.dmi',"facehugger_corgipuppy") else overlays += image('icons/mob/mask.dmi',"facehugger_corgi") @@ -461,17 +500,18 @@ -/mob/living/simple_animal/corgi/puppy +/mob/living/simple_animal/pet/corgi/puppy name = "\improper corgi puppy" real_name = "corgi" desc = "It's a corgi puppy." icon_state = "puppy" icon_living = "puppy" icon_dead = "puppy_dead" - mob_size = 0 + mob_size = MOB_SIZE_SMALL + accept_collar = 1 //puppies cannot wear anything. -/mob/living/simple_animal/corgi/puppy/Topic(href, href_list) +/mob/living/simple_animal/pet/corgi/puppy/Topic(href, href_list) if(href_list["remove_inv"] || href_list["add_inv"]) usr << "You can't fit this on [src]" return @@ -479,7 +519,7 @@ //LISA! SQUEEEEEEEEE~ -/mob/living/simple_animal/corgi/Lisa +/mob/living/simple_animal/pet/corgi/Lisa name = "Lisa" real_name = "Lisa" gender = FEMALE @@ -492,15 +532,16 @@ response_harm = "kicks" var/turns_since_scan = 0 var/puppies = 0 + accept_collar = 1 //Lisa already has a cute bow! -/mob/living/simple_animal/corgi/Lisa/Topic(href, href_list) +/mob/living/simple_animal/pet/corgi/Lisa/Topic(href, href_list) if(href_list["remove_inv"] || href_list["add_inv"]) usr << "[src] already has a cute bow!" return ..() -/mob/living/simple_animal/corgi/Lisa/Life() +/mob/living/simple_animal/pet/corgi/Lisa/Life() ..() make_babies() @@ -513,13 +554,13 @@ dir = i sleep(1) -/mob/living/simple_animal/corgi/attack_hand(mob/living/carbon/human/M) +/mob/living/simple_animal/pet/corgi/attack_hand(mob/living/carbon/human/M) . = ..() switch(M.a_intent) if("help") wuv(1,M) if("harm") wuv(-1,M) -/mob/living/simple_animal/corgi/proc/wuv(change, mob/M) +/mob/living/simple_animal/pet/corgi/proc/wuv(change, mob/M) if(change) if(change > 0) if(M && stat != DEAD) // Added check to see if this mob (the corgi) is dead to fix issue 2454 diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm index 4a003c9a72f..6b7f731e675 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm @@ -19,8 +19,6 @@ gender = NEUTER health = 30 maxHealth = 30 - heat_damage_per_tick = 0 - cold_damage_per_tick = 0 unsuitable_atmos_damage = 0 wander = 0 speed = 0 @@ -31,7 +29,7 @@ gender = NEUTER voice_name = "synthesized chirp" languages = DRONE - mob_size = 0 + mob_size = MOB_SIZE_SMALL has_unlimited_silicon_privilege = 1 staticOverlays = list() var/staticChoice = "static" @@ -94,8 +92,8 @@ pickVisualAppearence() -/mob/living/simple_animal/drone/Die() - ..() +/mob/living/simple_animal/drone/death(gibbed) + ..(gibbed) drop_l_hand() drop_r_hand() if(internal_storage) @@ -119,15 +117,6 @@ user << "The drone's LED screen shows a BSOD, Blue screen of Death!" -/mob/living/simple_animal/drone/Move() - if(pullin) - if(pulling) - pullin.icon_state = "pull" - else - pullin.icon_state = "pull0" - ..() - - /mob/living/simple_animal/drone/IsAdvancedToolUser() return 1 @@ -180,4 +169,10 @@ cleared = 1 L -= I if(cleared) - src << "--- [class] alarm in [A.name] has been cleared." \ No newline at end of file + src << "--- [class] alarm in [A.name] has been cleared." + +/mob/living/simple_animal/drone/check_eye_prot() + return 2 + +/mob/living/simple_animal/drone/handle_temperature_damage() + return diff --git a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm index 1a9dfb7db3e..d5d8cf19f5c 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm @@ -94,7 +94,8 @@ if(health < health_repair_max) user << "You start to tighten loose screws on [src]." if(do_after(user,80)) - health = health_repair_max + var/repair = health_repair_max - health + adjustBruteLoss(-repair) visible_message("[user] tightens [src == user ? "their" : "[src]'s"] loose screws!") else user << "You need to remain still to tighten [src]'s screws." diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index d976a50bf86..8ade1262914 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -168,7 +168,7 @@ ventcrawler = 2 var/amount_grown = 0 pass_flags = PASSTABLE | PASSGRILLE - mob_size = 0 + mob_size = MOB_SIZE_SMALL /mob/living/simple_animal/chick/New() ..() @@ -201,6 +201,8 @@ var/global/chicken_count = 0 speak_chance = 2 turns_per_move = 3 meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + var/egg_type = /obj/item/weapon/reagent_containers/food/snacks/egg + var/food_type = /obj/item/weapon/reagent_containers/food/snacks/grown/wheat meat_amount = 2 response_help = "pets" response_disarm = "gently pushes aside" @@ -209,28 +211,34 @@ var/global/chicken_count = 0 health = 10 ventcrawler = 2 var/eggsleft = 0 + var/eggsFertile = TRUE var/body_color + var/icon_prefix = "chicken" pass_flags = PASSTABLE + var/list/feedMessages = list("It clucks happily.","It clucks happily.") + var/list/layMessage = list("lays an egg.","squats down and croons.","begins making a huge racket.","begins clucking raucously.") + var/list/validColors = list("brown","black","white") /mob/living/simple_animal/chicken/New() ..() if(!body_color) - body_color = pick( list("brown","black","white") ) - icon_state = "chicken_[body_color]" - icon_living = "chicken_[body_color]" - icon_dead = "chicken_[body_color]_dead" + body_color = pick(validColors) + icon_state = "[icon_prefix]_[body_color]" + icon_living = "[icon_prefix]_[body_color]" + icon_dead = "[icon_prefix]_[body_color]_dead" pixel_x = rand(-6, 6) pixel_y = rand(0, 10) chicken_count += 1 -/mob/living/simple_animal/chicken/Die() - ..() +/mob/living/simple_animal/chicken/death(gibbed) + ..(gibbed) chicken_count -= 1 /mob/living/simple_animal/chicken/attackby(var/obj/item/O as obj, var/mob/user as mob, params) - if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown/wheat)) //feedin' dem chickens + if(istype(O, food_type)) //feedin' dem chickens if(!stat && eggsleft < 8) - user.visible_message("[user] feeds [O] to [name]! It clucks happily.","You feed [O] to [name]! It clucks happily.") + var/feedmsg = "[user] feeds [O] to [name]! [pick(feedMessages)]" + user.visible_message(feedmsg) user.drop_item() qdel(O) eggsleft += rand(1, 4) @@ -245,13 +253,14 @@ var/global/chicken_count = 0 if(!.) return if(!stat && prob(3) && eggsleft > 0) - visible_message("[src] [pick("lays an egg.","squats down and croons.","begins making a huge racket.","begins clucking raucously.")]") + visible_message("[src] [pick(layMessage)]") eggsleft-- - var/obj/item/weapon/reagent_containers/food/snacks/egg/E = new(get_turf(src)) + var/obj/item/E = new egg_type(get_turf(src)) E.pixel_x = rand(-6,6) E.pixel_y = rand(-6,6) - if(chicken_count < MAX_CHICKENS && prob(25)) - SSobj.processing |= E + if(eggsFertile) + if(chicken_count < MAX_CHICKENS && prob(25)) + SSobj.processing |= E /obj/item/weapon/reagent_containers/food/snacks/egg/var/amount_grown = 0 /obj/item/weapon/reagent_containers/food/snacks/egg/process() diff --git a/code/modules/mob/living/simple_animal/friendly/fox.dm b/code/modules/mob/living/simple_animal/friendly/fox.dm index dc614d5665c..d9322aa283d 100644 --- a/code/modules/mob/living/simple_animal/friendly/fox.dm +++ b/code/modules/mob/living/simple_animal/friendly/fox.dm @@ -1,7 +1,8 @@ //Foxxy -/mob/living/simple_animal/fox +/mob/living/simple_animal/pet/fox name = "fox" desc = "It's a fox. I wonder what it says?" + icon = 'icons/mob/pets.dmi' icon_state = "fox" icon_living = "fox" icon_dead = "fox_dead" @@ -18,6 +19,7 @@ response_harm = "kicks" //Captain fox -/mob/living/simple_animal/fox/Renault +/mob/living/simple_animal/pet/fox/Renault name = "Renault" - desc = "Renault, the Captain's trustworthy fox. I wonder what it says?" \ No newline at end of file + desc = "Renault, the Captain's trustworthy fox. I wonder what it says?" + pcollar = /obj/item/clothing/tie/petcollar \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/friendly/lizard.dm b/code/modules/mob/living/simple_animal/friendly/lizard.dm index c9b23b18904..3e97c6d41e9 100644 --- a/code/modules/mob/living/simple_animal/friendly/lizard.dm +++ b/code/modules/mob/living/simple_animal/friendly/lizard.dm @@ -15,4 +15,4 @@ response_disarm = "shoos" response_harm = "stomps on" ventcrawler = 2 - mob_size = 0 \ No newline at end of file + mob_size = MOB_SIZE_SMALL \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index ae67489e9e0..38e9f399ae1 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -21,7 +21,7 @@ density = 0 ventcrawler = 2 pass_flags = PASSTABLE | PASSGRILLE - mob_size = 0 + mob_size = MOB_SIZE_SMALL var/body_color //brown, gray and white, leave blank for random /mob/living/simple_animal/mouse/New() @@ -36,14 +36,16 @@ /mob/living/simple_animal/mouse/proc/splat() src.health = 0 src.icon_dead = "mouse_[body_color]_splat" - Die() + death() -/mob/living/simple_animal/mouse/Die() - ..() +/mob/living/simple_animal/mouse/death(gibbed) if(!ckey) + ..(1) var/obj/item/trash/deadmouse/M = new(src.loc) - M.icon_state = src.icon_dead + M.icon_state = icon_dead qdel(src) + else + ..(gibbed) /mob/living/simple_animal/mouse/Crossed(AM as mob|obj) if( ishuman(AM) ) diff --git a/code/modules/mob/living/simple_animal/friendly/pug.dm b/code/modules/mob/living/simple_animal/friendly/pug.dm index f685428fa4d..5d0359f7478 100644 --- a/code/modules/mob/living/simple_animal/friendly/pug.dm +++ b/code/modules/mob/living/simple_animal/friendly/pug.dm @@ -1,8 +1,8 @@ -//Corgi //best comment 2014 -/mob/living/simple_animal/pug +/mob/living/simple_animal/pet/pug name = "\improper pug" real_name = "pug" desc = "It's a pug." + icon = 'icons/mob/pets.dmi' icon_state = "pug" icon_living = "pug" icon_dead = "pug_dead" @@ -19,7 +19,7 @@ response_harm = "kicks" see_in_dark = 5 -/mob/living/simple_animal/pug/Life() +/mob/living/simple_animal/pet/pug/Life() ..() if(!stat && !resting && !buckled) @@ -30,7 +30,7 @@ dir = i sleep(1) -/mob/living/simple_animal/pug/attackby(var/obj/item/O as obj, var/mob/user as mob, params) //Marker -Agouri +/mob/living/simple_animal/pet/pug/attackby(var/obj/item/O as obj, var/mob/user as mob, params) //Marker -Agouri if(istype(O, /obj/item/weapon/newspaper)) if(!stat) user.visible_message("[user] baps [name] on the nose with the rolled up [O]") diff --git a/code/modules/mob/living/simple_animal/friendly/slime.dm b/code/modules/mob/living/simple_animal/friendly/slime.dm deleted file mode 100644 index 85405278096..00000000000 --- a/code/modules/mob/living/simple_animal/friendly/slime.dm +++ /dev/null @@ -1,35 +0,0 @@ -/mob/living/simple_animal/slime - name = "pet slime" - desc = "A lovable, domesticated slime." - icon = 'icons/mob/slimes.dmi' - icon_state = "grey baby slime" - icon_living = "grey baby slime" - icon_dead = "grey baby slime dead" - speak_emote = list("chirps") - health = 100 - maxHealth = 100 - response_help = "pets" - response_disarm = "shoos" - response_harm = "stomps on" - emote_see = list("jiggles", "bounces in place") - ventcrawler = 2 - var/colour = "grey" - -/mob/living/simple_animal/slime/adult - health = 200 - maxHealth = 200 - icon_state = "grey adult slime" - icon_living = "grey adult slime" - -/mob/living/simple_animal/slime/adult/New() - ..() - overlays += "aslime-:33" - -/mob/living/simple_animal/slime/adult/Die() - for(var/i = 0, i<=1, i++) - var/mob/living/simple_animal/slime/S1 = new /mob/living/simple_animal/slime (src.loc) - S1.icon_state = "[colour] baby slime" - S1.icon_living = "[colour] baby slime" - S1.icon_dead = "[colour] baby slime dead" - S1.colour = "[colour]" - qdel(src) diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm index b00b0c95e70..0af9b62a638 100644 --- a/code/modules/mob/living/simple_animal/hostile/alien.dm +++ b/code/modules/mob/living/simple_animal/hostile/alien.dm @@ -21,19 +21,13 @@ attacktext = "slashes" a_intent = "harm" attack_sound = 'sound/weapons/bladeslice.ogg' - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 15 faction = list("alien") status_flags = CANPUSH minbodytemp = 0 - heat_damage_per_tick = 20 + see_in_dark = 8 + see_invisible = SEE_INVISIBLE_MINIMUM /mob/living/simple_animal/hostile/alien/drone name = "alien drone" @@ -129,14 +123,20 @@ move_to_delay = 4 maxHealth = 400 health = 400 - mob_size = 2 + mob_size = MOB_SIZE_LARGE /obj/item/projectile/neurotox name = "neurotoxin" damage = 30 icon_state = "toxin" -/mob/living/simple_animal/hostile/alien/Die() - ..() +/mob/living/simple_animal/hostile/alien/death(gibbed) + ..(gibbed) visible_message("[src] lets out a waning guttural screech, green blood bubbling from its maw...") playsound(src, 'sound/voice/hiss6.ogg', 100, 1) + +/mob/living/simple_animal/hostile/alien/handle_temperature_damage() + if(bodytemperature < minbodytemp) + adjustBruteLoss(2) + else if(bodytemperature > maxbodytemp) + adjustBruteLoss(20) diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm index 6e6022cd1ee..5a05889ccd9 100644 --- a/code/modules/mob/living/simple_animal/hostile/bear.dm +++ b/code/modules/mob/living/simple_animal/hostile/bear.dm @@ -28,14 +28,7 @@ friendly = "bear hugs" //Space bears aren't affected by cold. - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 maxbodytemp = 1500 diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm index 66707ccf069..31316587039 100644 --- a/code/modules/mob/living/simple_animal/hostile/bees.dm +++ b/code/modules/mob/living/simple_animal/hostile/bees.dm @@ -3,7 +3,6 @@ desc = "" icon_state = "bee_1" icon_living = "bee" - icon_dead = "" speak_emote = list("buzzes") emote_hear = list("buzzes") turns_per_move = 0 @@ -23,14 +22,7 @@ pass_flags = PASSTABLE //Spaceborn beings don't get hurt by space - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 /mob/living/simple_animal/hostile/poison/bees/Process_Spacemove(var/movement_dir = 0) @@ -40,8 +32,9 @@ ..() update_bees() -/mob/living/simple_animal/hostile/poison/bees/Die() - ..() +/mob/living/simple_animal/hostile/poison/bees/death(gibbed) + ..(1) + ghostize() qdel(src) return diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm index a7683dd7847..651ed536c0d 100644 --- a/code/modules/mob/living/simple_animal/hostile/carp.dm +++ b/code/modules/mob/living/simple_animal/hostile/carp.dm @@ -23,14 +23,7 @@ attack_sound = 'sound/weapons/bite.ogg' //Space carp aren't affected by cold. - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 maxbodytemp = 1500 @@ -57,7 +50,9 @@ icon_living = "holocarp" maxbodytemp = INFINITY -/mob/living/simple_animal/hostile/carp/holocarp/Die() +/mob/living/simple_animal/hostile/carp/holocarp/death() + ..(1) + ghostize() qdel(src) return @@ -72,7 +67,7 @@ maxHealth = 65 health = 65 pixel_x = -16 - mob_size = 2 + mob_size = MOB_SIZE_LARGE melee_damage_lower = 20 melee_damage_upper = 20 \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/eyeballs.dm b/code/modules/mob/living/simple_animal/hostile/eyeballs.dm index 46f2e679e22..313798c6b22 100644 --- a/code/modules/mob/living/simple_animal/hostile/eyeballs.dm +++ b/code/modules/mob/living/simple_animal/hostile/eyeballs.dm @@ -5,7 +5,6 @@ desc = "An odd looking creature, it won't stop staring..." icon_state = "eyeball" icon_living = "eyeball" - icon_dead = "" icon_gib = "" meat_type = null meat_amount = 0 @@ -29,6 +28,7 @@ if(.) emote("me", 1, "glares at [.]") -/mob/living/simple_animal/hostile/carp/eyeball/Die() +/mob/living/simple_animal/hostile/carp/eyeball/death() + ..(1) + ghostize() qdel(src) - return \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/faithless.dm b/code/modules/mob/living/simple_animal/hostile/faithless.dm index 51465393c2c..aa8912cb618 100644 --- a/code/modules/mob/living/simple_animal/hostile/faithless.dm +++ b/code/modules/mob/living/simple_animal/hostile/faithless.dm @@ -19,14 +19,7 @@ attacktext = "grips" attack_sound = 'sound/hallucinations/growl1.ogg' - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 faction = list("faithless") diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm index b4582cd4d46..c0219aac81b 100644 --- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm @@ -43,8 +43,6 @@ health = 200 melee_damage_lower = 15 melee_damage_upper = 20 - heat_damage_per_tick = 20 - cold_damage_per_tick = 20 faction = list("spiders") var/busy = 0 pass_flags = PASSTABLE @@ -264,6 +262,12 @@ busy = 0 stop_automated_movement = 0 +/mob/living/simple_animal/hostile/poison/giant_spider/handle_temperature_damage() + if(bodytemperature < minbodytemp) + adjustBruteLoss(20) + else if(bodytemperature > maxbodytemp) + adjustBruteLoss(20) + #undef SPINNING_WEB #undef LAYING_EGGS #undef MOVING_TO_TARGET diff --git a/code/modules/mob/living/simple_animal/hostile/headcrab.dm b/code/modules/mob/living/simple_animal/hostile/headcrab.dm new file mode 100644 index 00000000000..4065fcfe198 --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/headcrab.dm @@ -0,0 +1,59 @@ +#define EGG_INCUBATION_TIME 180 + +/mob/living/simple_animal/hostile/headcrab + name = "Headslug" + desc = "Absolutely not de-beaked or harmless. Keep away from corpses." + icon_state = "headcrab" + icon_living = "headcrab" + icon_dead = "headcrab_dead" + health = 20 + maxHealth = 20 + melee_damage_lower = 5 + melee_damage_upper = 5 + attacktext = "chomps" + attack_sound = 'sound/weapons/bite.ogg' + faction = list("creature") + robust_searching = 1 + stat_attack = 2 + environment_smash = 0 + var/datum/mind/origin + +/mob/living/simple_animal/hostile/headcrab/proc/Infect(var/mob/living/carbon/human/victim) + var/obj/item/body_egg/changeling_egg/egg = new(victim) + egg.owner = origin + victim.internal_organs += egg + visible_message("[src] lays an egg in a [victim]!") + +/mob/living/simple_animal/hostile/headcrab/AttackingTarget() + if(ishuman(target)) + var/mob/living/carbon/human/H = target + if(H.stat == DEAD) + Infect(target) + death() + return + target.attack_animal(src) + + + + +/obj/item/body_egg/changeling_egg + name = "changeling egg" + desc = "Twitching and disgusting" + var/datum/mind/owner + var/time + +/obj/item/body_egg/changeling_egg/egg_process() + //Changeling eggs grow in dead people + time++ + if(time >= EGG_INCUBATION_TIME) + Pop() + +obj/item/body_egg/changeling_egg/proc/Pop() + var/mob/living/carbon/monkey/M = new(affected_mob.loc) + owner.transfer_to(M) + owner.changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/humanform(null) + M.key = owner.key + affected_mob.gib() + qdel(src) + +#undef EGG_INCUBATION_TIME diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm index 11bbfa8a561..b79fecee6ef 100644 --- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm +++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm @@ -17,14 +17,7 @@ projectilesound = 'sound/weapons/Gunshot.ogg' projectiletype = /obj/item/projectile/hivebotbullet faction = list("hivebot") - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 /mob/living/simple_animal/hostile/hivebot/range @@ -46,13 +39,14 @@ health = 80 ranged = 1 -/mob/living/simple_animal/hostile/hivebot/Die() - ..() - visible_message("[src] blows apart!") +/mob/living/simple_animal/hostile/hivebot/death(gibbed) + ..(1) + visible_message("[src] blows apart!") new /obj/effect/decal/cleanable/robot_debris(src.loc) var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(3, 1, src) s.start() + ghostize() qdel(src) return @@ -72,38 +66,35 @@ var/spawn_delay = 600 var/turn_on = 0 var/auto_spawn = 1 - proc - warpbots() + +/mob/living/simple_animal/hostile/hivebot/tele/New() + ..() + var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread() + smoke.set_up(5, 0, src.loc) + smoke.start() + visible_message("The [src] warps in!") + playsound(src.loc, 'sound/effects/EMPulse.ogg', 25, 1) + +/mob/living/simple_animal/hostile/hivebot/tele/proc/warpbots() + icon_state = "def_radar" + visible_message("The [src] turns on!") + while(bot_amt > 0) + bot_amt-- + switch(bot_type) + if("norm") + new /mob/living/simple_animal/hostile/hivebot(get_turf(src)) + if("range") + new /mob/living/simple_animal/hostile/hivebot/range(get_turf(src)) + if("rapid") + new /mob/living/simple_animal/hostile/hivebot/rapid(get_turf(src)) + spawn(100) + qdel(src) + return - New() - ..() - var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread() - smoke.set_up(5, 0, src.loc) - smoke.start() - visible_message("The [src] warps in!") - playsound(src.loc, 'sound/effects/EMPulse.ogg', 25, 1) - - warpbots() - icon_state = "def_radar" - visible_message("The [src] turns on!") - while(bot_amt > 0) - bot_amt-- - switch(bot_type) - if("norm") - new /mob/living/simple_animal/hostile/hivebot(get_turf(src)) - if("range") - new /mob/living/simple_animal/hostile/hivebot/range(get_turf(src)) - if("rapid") - new /mob/living/simple_animal/hostile/hivebot/rapid(get_turf(src)) - spawn(100) - qdel(src) - return - - - Life() - ..() - if(stat == 0) - if(prob(2))//Might be a bit low, will mess with it likely - warpbots() +/mob/living/simple_animal/hostile/hivebot/tele/Life() + ..() + if(stat == 0) + if(prob(2))//Might be a bit low, will mess with it likely + warpbots() diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 3828dbdce6c..91a67fcb380 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -30,6 +30,8 @@ var/stat_exclusive = 0 //Mobs with this set to 1 will exclusively attack things defined by stat_attack, stat_attack 2 means they will only attack corpses var/attack_same = 0 //Set us to 1 to allow us to attack our own faction, or 2, to only ever attack our own faction + var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_SLEEP (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever) + /mob/living/simple_animal/hostile/Life() . = ..() @@ -40,6 +42,8 @@ ranged_cooldown-- if(client) return 0 + if(!AICanContinue()) + return 0 if(!stat) switch(stance) if(HOSTILE_STANCE_IDLE) @@ -56,6 +60,9 @@ AttackTarget() DestroySurroundings() + if(AIShouldSleep()) + AIStatus = AI_SLEEP + //////////////HOSTILE MOB TARGETTING AND AGGRESSION//////////// @@ -229,9 +236,9 @@ //////////////END HOSTILE MOB TARGETTING AND AGGRESSION//////////// -/mob/living/simple_animal/hostile/Die() +/mob/living/simple_animal/hostile/death(gibbed) LoseAggro() - ..() + ..(gibbed) walk(src, 0) /mob/living/simple_animal/hostile/proc/OpenFire(var/the_target) @@ -313,4 +320,33 @@ if(ranged && ranged_cooldown <= 0) target = A OpenFire(A) - ..() \ No newline at end of file + ..() + + + +////// AI Status /////// +/mob/living/simple_animal/hostile/proc/AICanContinue() + switch(AIStatus) + if(AI_ON) + . = 1 + if(AI_SLEEP) + if(AIShouldWake()) + . = 1 + AIStatus = AI_ON //Wake up for more than one Life() cycle. + else + . = 0 + if(AI_OFF) + . = 0 + + +//Returns 1 if the AI should wake up +//Returns 0 if the AI should remain asleep +/mob/living/simple_animal/hostile/proc/AIShouldWake() + . = 0 + if(FindTarget()) + . = 1 + + +//Convenience +/mob/living/simple_animal/hostile/proc/AIShouldSleep() + . = !(AIShouldWake()) diff --git a/code/modules/mob/living/simple_animal/hostile/killertomato.dm b/code/modules/mob/living/simple_animal/hostile/killertomato.dm index 5f746f8a27f..efddba87b34 100644 --- a/code/modules/mob/living/simple_animal/hostile/killertomato.dm +++ b/code/modules/mob/living/simple_animal/hostile/killertomato.dm @@ -20,13 +20,6 @@ ventcrawler = 2 faction = list("plants") - min_oxy = 5 - max_oxy = 0 - min_tox = 0 - max_tox = 5 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 + atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 150 maxbodytemp = 500 diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm index e6f77f15489..85089cae53c 100644 --- a/code/modules/mob/living/simple_animal/hostile/mimic.dm +++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm @@ -23,14 +23,7 @@ attack_sound = 'sound/weapons/bite.ogg' var/Attackemote = "growls at" - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 faction = list("mimic") @@ -41,9 +34,10 @@ if(.) emote("me", 1, "[Attackemote] [.].") -/mob/living/simple_animal/hostile/mimic/Die() - ..() - visible_message("[src] stops moving!") +/mob/living/simple_animal/hostile/mimic/death() + ..(1) + visible_message("[src] stops moving!") + ghostize() qdel(src) @@ -107,7 +101,7 @@ ..() icon_state = initial(icon_state) -/mob/living/simple_animal/hostile/mimic/crate/Die() +/mob/living/simple_animal/hostile/mimic/crate/death() var/obj/structure/closet/crate/C = new(get_turf(src)) // Put loot in crate @@ -144,9 +138,9 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca /mob/living/simple_animal/hostile/mimic/copy/Life() ..() for(var/mob/living/M in contents) //a fix for animated statues from the flesh to stone spell - Die() + death() -/mob/living/simple_animal/hostile/mimic/copy/Die() +/mob/living/simple_animal/hostile/mimic/copy/death() for(var/atom/movable/M in src) M.loc = get_turf(src) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm index 0e62f7f61b7..2dde6d08408 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm @@ -1,18 +1,10 @@ /mob/living/simple_animal/hostile/asteroid/ vision_range = 2 - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 15 faction = list("mining") environment_smash = 2 minbodytemp = 0 - heat_damage_per_tick = 20 response_help = "pokes" response_disarm = "shoves" response_harm = "strikes" @@ -20,6 +12,8 @@ a_intent = "harm" var/throw_message = "bounces off of" var/icon_aggro = null // for swapping to when we get aggressive + see_in_dark = 8 + see_invisible = SEE_INVISIBLE_MINIMUM /mob/living/simple_animal/hostile/asteroid/Aggro() ..() @@ -108,12 +102,12 @@ if(3.0) adjustBruteLoss(110) -/mob/living/simple_animal/hostile/asteroid/basilisk/Die() +/mob/living/simple_animal/hostile/asteroid/basilisk/death(gibbed) var/counter for(counter=0, counter<2, counter++) var/obj/item/weapon/ore/diamond/D = new /obj/item/weapon/ore/diamond(src.loc) D.layer = 4.1 - ..() + ..(gibbed) /mob/living/simple_animal/hostile/asteroid/goldgrub name = "goldgrub" @@ -204,10 +198,10 @@ visible_message("The [P.name] was repelled by [src.name]'s girth!") return -/mob/living/simple_animal/hostile/asteroid/goldgrub/Die() +/mob/living/simple_animal/hostile/asteroid/goldgrub/death(gibbed) alerted = 0 Reward() - ..() + ..(gibbed) /mob/living/simple_animal/hostile/asteroid/goldgrub/adjustBruteLoss(var/damage) idle_vision_range = 9 @@ -253,10 +247,10 @@ /mob/living/simple_animal/hostile/asteroid/hivelord/AttackingTarget() OpenFire() -/mob/living/simple_animal/hostile/asteroid/hivelord/Die() +/mob/living/simple_animal/hostile/asteroid/hivelord/death(gibbed) new /obj/item/asteroid/hivelord_core(src.loc) mouse_opacity = 1 - ..() + ..(gibbed) /obj/item/asteroid/hivelord_core name = "hivelord remains" @@ -318,7 +312,7 @@ spawn(100) qdel(src) -/mob/living/simple_animal/hostile/asteroid/hivelordbrood/Die() +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/death() qdel(src) /mob/living/simple_animal/hostile/asteroid/goliath @@ -349,7 +343,7 @@ aggro_vision_range = 9 idle_vision_range = 5 anchored = 1 //Stays anchored until death as to be unpullable - mob_size = 2 + mob_size = MOB_SIZE_LARGE var/pre_attack = 0 /mob/living/simple_animal/hostile/asteroid/goliath/Life() @@ -367,9 +361,9 @@ anchored = 1 ..() -/mob/living/simple_animal/hostile/asteroid/goliath/Die() +/mob/living/simple_animal/hostile/asteroid/goliath/death(gibbed) anchored = 0 - ..() + ..(gibbed) /mob/living/simple_animal/hostile/asteroid/goliath/OpenFire() var/tturf = get_turf(target) @@ -434,10 +428,10 @@ spawn(50) qdel(src) -/mob/living/simple_animal/hostile/asteroid/goliath/Die() +/mob/living/simple_animal/hostile/asteroid/goliath/death(gibbed) var/obj/item/asteroid/goliath_hide/G = new /obj/item/asteroid/goliath_hide(src.loc) G.layer = 4.1 - ..() + ..(gibbed) /obj/item/asteroid/goliath_hide name = "goliath hide plates" @@ -481,3 +475,9 @@ else user << "You can't improve [D] any further." return + +/mob/living/simple_animal/hostile/asteroid/handle_temperature_damage() + if(bodytemperature < minbodytemp) + adjustBruteLoss(2) + else if(bodytemperature > maxbodytemp) + adjustBruteLoss(20) diff --git a/code/modules/mob/living/simple_animal/hostile/mushroom.dm b/code/modules/mob/living/simple_animal/hostile/mushroom.dm index c93b394050e..aacc4da57f3 100644 --- a/code/modules/mob/living/simple_animal/hostile/mushroom.dm +++ b/code/modules/mob/living/simple_animal/hostile/mushroom.dm @@ -42,7 +42,7 @@ /mob/living/simple_animal/hostile/mushroom/Life() ..() if(!stat)//Mushrooms slowly regenerate if conscious, for people who want to save them from being eaten - health = min(health+2, maxHealth) + adjustBruteLoss(-2) /mob/living/simple_animal/hostile/mushroom/New()//Makes every shroom a little unique melee_damage_lower += rand(3, 5) @@ -78,7 +78,7 @@ if(level_gain < 1)//So we still gain a level if two mushrooms were the same level level_gain = 1 M.LevelUp(level_gain) - M.health = M.maxHealth + M.adjustBruteLoss(-M.maxHealth) qdel(src) ..() @@ -87,9 +87,10 @@ icon_state = "mushroom_color" UpdateMushroomCap() -/mob/living/simple_animal/hostile/mushroom/Die() - visible_message("[src] fainted.") - ..() +/mob/living/simple_animal/hostile/mushroom/death(gibbed) + if(!gibbed) + visible_message("[src] fainted.") + ..(gibbed) UpdateMushroomCap() /mob/living/simple_animal/hostile/mushroom/proc/UpdateMushroomCap() @@ -101,9 +102,8 @@ /mob/living/simple_animal/hostile/mushroom/proc/Recover() visible_message("[src] slowly begins to recover.") - health = 5 faint_ticker = 0 - icon_state = icon_living + revive() UpdateMushroomCap() recovery_cooldown = 1 spawn(300) @@ -117,7 +117,7 @@ else melee_damage_upper += (level_gain * rand(1,5)) maxHealth += (level_gain * rand(1,5)) - health = maxHealth //They'll always heal, even if they don't gain a level, in case you want to keep this shroom around instead of harvesting it + adjustBruteLoss(-maxHealth) //They'll always heal, even if they don't gain a level, in case you want to keep this shroom around instead of harvesting it /mob/living/simple_animal/hostile/mushroom/proc/Bruise() if(!bruised && !stat) diff --git a/code/modules/mob/living/simple_animal/hostile/pirate.dm b/code/modules/mob/living/simple_animal/hostile/pirate.dm index aae825a6538..2bd4ffb6341 100644 --- a/code/modules/mob/living/simple_animal/hostile/pirate.dm +++ b/code/modules/mob/living/simple_animal/hostile/pirate.dm @@ -20,14 +20,7 @@ attacktext = "slashes" attack_sound = 'sound/weapons/bladeslice.ogg' - min_oxy = 5 - max_oxy = 0 - min_tox = 0 - max_tox = 1 - min_co2 = 0 - max_co2 = 5 - min_n2 = 0 - max_n2 = 0 + atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 15 var/corpse = /obj/effect/landmark/mobcorpse/pirate var/weapon1 = /obj/item/weapon/melee/energy/sword/pirate @@ -49,11 +42,13 @@ weapon1 = /obj/item/weapon/gun/energy/laser -/mob/living/simple_animal/hostile/pirate/Die() - ..() +/mob/living/simple_animal/hostile/pirate/death() + ..(1) + visible_message("[src] stops moving.") if(corpse) new corpse (src.loc) if(weapon1) new weapon1 (src.loc) + ghostize() qdel(src) return \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm index 1173ef3418c..bf79c041a63 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm @@ -23,16 +23,12 @@ attack_sound = 'sound/weapons/bite.ogg' environment_smash = 0 ventcrawler = 2 - mob_size = 0 + mob_size = MOB_SIZE_SMALL + var/max_co2 = 0 //to be removed once metastation map no longer use those for Sgt Araneus + var/min_oxy = 0 + var/max_tox = 0 //Space bats need no air to fly in. - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm index 23fc3a7db42..3fca1ad51b4 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm @@ -25,16 +25,13 @@ attack_sound = 'sound/items/bikehorn.ogg' environment_smash = 0 - min_oxy = 5 - max_oxy = 0 - min_tox = 0 - max_tox = 1 - min_co2 = 0 - max_co2 = 5 - min_n2 = 0 - max_n2 = 0 + atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) minbodytemp = 270 maxbodytemp = 370 - heat_damage_per_tick = 15 //amount of damage applied if animal's body temperature is higher than maxbodytemp - cold_damage_per_tick = 10 //same as heat_damage_per_tick, only if the bodytemperature it's lower than minbodytemp - unsuitable_atmos_damage = 10 \ No newline at end of file + unsuitable_atmos_damage = 10 + +/mob/living/simple_animal/hostile/retaliate/clown/handle_temperature_damage() + if(bodytemperature < minbodytemp) + adjustBruteLoss(10) + else if(bodytemperature > maxbodytemp) + adjustBruteLoss(15) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/russian.dm b/code/modules/mob/living/simple_animal/hostile/russian.dm index 3f143ea19fe..1f96f9533a4 100644 --- a/code/modules/mob/living/simple_animal/hostile/russian.dm +++ b/code/modules/mob/living/simple_animal/hostile/russian.dm @@ -21,14 +21,7 @@ a_intent = "harm" var/corpse = /obj/effect/landmark/mobcorpse/russian var/weapon1 = /obj/item/weapon/kitchenknife - min_oxy = 5 - max_oxy = 0 - min_tox = 0 - max_tox = 1 - min_co2 = 0 - max_co2 = 5 - min_n2 = 0 - max_n2 = 0 + atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 15 faction = list("russian") status_flags = CANPUSH @@ -51,11 +44,13 @@ weapon1 = /obj/item/weapon/gun/projectile/shotgun/boltaction casingtype = /obj/item/ammo_casing/a762 -/mob/living/simple_animal/hostile/russian/Die() - ..() +/mob/living/simple_animal/hostile/russian/death(gibbed) + ..(1) + visible_message("[src] stops moving.") if(corpse) new corpse (src.loc) if(weapon1) new weapon1 (src.loc) + ghostize() qdel(src) return diff --git a/code/modules/mob/living/simple_animal/hostile/statue.dm b/code/modules/mob/living/simple_animal/hostile/statue.dm index 5f9fcd35428..29dcdd93ebc 100644 --- a/code/modules/mob/living/simple_animal/hostile/statue.dm +++ b/code/modules/mob/living/simple_animal/hostile/statue.dm @@ -23,14 +23,7 @@ attacktext = "claws" attack_sound = 'sound/hallucinations/growl1.ogg' - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 faction = list("statue") diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index 72b30675077..bfd39fc4f7c 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -22,20 +22,13 @@ var/corpse = /obj/effect/landmark/mobcorpse/syndicatesoldier var/weapon1 var/weapon2 - min_oxy = 5 - max_oxy = 0 - min_tox = 0 - max_tox = 1 - min_co2 = 0 - max_co2 = 5 - min_n2 = 0 - max_n2 = 0 + atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 15 faction = list("syndicate") status_flags = CANPUSH -/mob/living/simple_animal/hostile/syndicate/Die() - ..() +/mob/living/simple_animal/hostile/syndicate/death(gibbed) + ..(gibbed) if(corpse) new corpse (src.loc) if(weapon1) @@ -79,19 +72,12 @@ if((Proj.damage_type == BRUTE || Proj.damage_type == BURN)) src.health -= Proj.damage else - visible_message("[src] blocks [Proj] with its shield!") + visible_message("[src] blocks [Proj] with its shield!") return 0 /mob/living/simple_animal/hostile/syndicate/melee/space - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 icon_state = "syndicatemeleespace" icon_living = "syndicatemeleespace" @@ -119,14 +105,7 @@ icon_state = "syndicaterangedpsace" icon_living = "syndicaterangedpsace" name = "Syndicate Commando" - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 corpse = /obj/effect/landmark/mobcorpse/syndicatecommando speed = 1 @@ -149,19 +128,12 @@ attacktext = "cuts" attack_sound = 'sound/weapons/bladeslice.ogg' faction = list("syndicate") - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 - mob_size = 0 + mob_size = MOB_SIZE_SMALL -/mob/living/simple_animal/hostile/viscerator/Die() - ..() +/mob/living/simple_animal/hostile/viscerator/death(gibbed) + ..(gibbed) visible_message("[src] is smashed into pieces!") qdel(src) return \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/tree.dm b/code/modules/mob/living/simple_animal/hostile/tree.dm index 43ee23cf49b..79edd57a33f 100644 --- a/code/modules/mob/living/simple_animal/hostile/tree.dm +++ b/code/modules/mob/living/simple_animal/hostile/tree.dm @@ -14,7 +14,7 @@ speed = 1 maxHealth = 250 health = 250 - mob_size = 2 + mob_size = MOB_SIZE_LARGE pixel_x = -16 @@ -25,17 +25,11 @@ attack_sound = 'sound/weapons/bite.ogg' //Space carp aren't affected by atmos. - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 faction = list("hostile") + var/drop_type = /obj/item/stack/sheet/mineral/wood /mob/living/simple_animal/hostile/tree/FindTarget() . = ..() @@ -50,10 +44,11 @@ L.Weaken(3) L.visible_message("\The [src] knocks down \the [L]!") -/mob/living/simple_animal/hostile/tree/Die() - ..() - visible_message("[src] is hacked into pieces!") - new /obj/item/stack/sheet/mineral/wood(loc) +/mob/living/simple_animal/hostile/tree/death(gibbed) + ..(1) + visible_message("[src] is hacked into pieces!") + new drop_type(loc) + ghostize() qdel(src) /mob/living/simple_animal/hostile/tree/festivus @@ -63,9 +58,5 @@ icon_living = "festivus_pole" icon_dead = "festivus_pole" icon_gib = "festivus_pole" + drop_type = /obj/item/stack/rods -/mob/living/simple_animal/hostile/tree/festivus/Die() - ..() - visible_message("[src] is hacked into pieces!") - new /obj/item/stack/rods(loc) - qdel(src) diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index d49855fc02f..bc1e35d3b6a 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -54,7 +54,7 @@ a_intent = "harm" //parrots now start "aggressive" since only player parrots will nuzzle. attacktext = "chomps" friendly = "grooms" - mob_size = 0 + mob_size = MOB_SIZE_SMALL var/parrot_damage_upper = 10 var/parrot_state = PARROT_WANDER //Hunt for a perch when created @@ -113,12 +113,12 @@ /mob/living/simple_animal/parrot/proc/toggle_mode) -/mob/living/simple_animal/parrot/Die() +/mob/living/simple_animal/parrot/death(gibbed) if(held_item) held_item.loc = src.loc held_item = null walk(src,0) - ..() + ..(gibbed) /mob/living/simple_animal/parrot/Stat() ..() @@ -126,14 +126,14 @@ stat("Held Item", held_item) stat("Mode",a_intent) -/mob/living/simple_animal/parrot/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq) +/mob/living/simple_animal/parrot/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans) if(speaker != src && prob(20)) //Dont imitate ourselves if(speech_buffer.len >= 20) speech_buffer -= pick(speech_buffer) speech_buffer |= html_decode(raw_message) ..() -/mob/living/simple_animal/parrot/radio(message, message_mode) //literally copied from human/radio(), but there's no other way to do this. at least it's better than it used to be. +/mob/living/simple_animal/parrot/radio(message, message_mode, list/spans) //literally copied from human/radio(), but there's no other way to do this. at least it's better than it used to be. . = ..() if(. != 0) return . @@ -141,22 +141,22 @@ switch(message_mode) if(MODE_HEADSET) if (ears) - ears.talk_into(src, message) + ears.talk_into(src, message, , spans) return ITALICS | REDUCE_RANGE if(MODE_SECURE_HEADSET) if (ears) - ears.talk_into(src, message, 1) + ears.talk_into(src, message, 1, spans) return ITALICS | REDUCE_RANGE if(MODE_DEPARTMENT) if (ears) - ears.talk_into(src, message, message_mode) + ears.talk_into(src, message, message_mode, spans) return ITALICS | REDUCE_RANGE if(message_mode in radiochannels) if(ears) - ears.talk_into(src, message, message_mode) + ears.talk_into(src, message, message_mode, spans) return ITALICS | REDUCE_RANGE return 0 @@ -347,25 +347,21 @@ /mob/living/simple_animal/parrot/Life() ..() - //Sprite and AI update for when a parrot gets pulled + //Sprite update for when a parrot gets pulled if(pulledby && stat == CONSCIOUS) icon_state = "parrot_fly" if(!client) parrot_state = PARROT_WANDER return - if(client || stat) - return //Lets not force players or dead/incap parrots to move - - if(!isturf(src.loc) || !canmove || buckled) - return //If it can't move, dont let it move. (The buckled check probably isn't necessary thanks to canmove) - //-----SPEECH /* Parrot speech mimickry! Phrases that the parrot Hear()s get added to speach_buffer. Every once in a while, the parrot picks one of the lines from the buffer and replaces an element of the 'speech' list. Then it clears the buffer to make sure they dont magically remember something from hours ago. */ +/mob/living/simple_animal/parrot/handle_automated_speech() + ..() if(speech_buffer.len && prob(10)) if(speak.len) speak.Remove(pick(speak)) @@ -374,6 +370,11 @@ clearlist(speech_buffer) +/mob/living/simple_animal/parrot/handle_automated_movement() + if(!isturf(src.loc) || !canmove || buckled) + return //If it can't move, dont let it move. (The buckled check probably isn't necessary thanks to canmove) + + //-----SLEEPING if(parrot_state == PARROT_PERCH) if(parrot_perch && parrot_perch.loc != src.loc) //Make sure someone hasnt moved our perch on us diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm index ebca47633b9..a1982d4d0bd 100644 --- a/code/modules/mob/living/simple_animal/shade.dm +++ b/code/modules/mob/living/simple_animal/shade.dm @@ -5,7 +5,6 @@ icon = 'icons/mob/mob.dmi' icon_state = "shade" icon_living = "shade" - icon_dead = "shade_dead" maxHealth = 50 health = 50 speak_emote = list("hisses") @@ -18,9 +17,7 @@ attacktext = "drains the life from" minbodytemp = 0 maxbodytemp = 4000 - min_oxy = 0 - max_co2 = 0 - max_tox = 0 + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) speed = -1 stop_automated_movement = 1 status_flags = 0 @@ -28,14 +25,13 @@ status_flags = CANPUSH -/mob/living/simple_animal/shade/Life() - ..() - if(stat == 2) - new /obj/item/weapon/ectoplasm (src.loc) - visible_message("[src] lets out a contented sigh as their form unwinds.") - ghostize() - qdel(src) - return +/mob/living/simple_animal/shade/death() + ..(1) + new /obj/item/weapon/ectoplasm (src.loc) + visible_message("[src] lets out a contented sigh as their form unwinds.") + ghostize() + qdel(src) + return /mob/living/simple_animal/shade/attackby(var/obj/item/O as obj, var/mob/user as mob, params) //Marker -Agouri diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 0570e89ff65..f81bdac5d59 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -35,21 +35,11 @@ //Temperature effect var/minbodytemp = 250 var/maxbodytemp = 350 - var/heat_damage_per_tick = 3 //amount of damage applied if animal's body temperature is higher than maxbodytemp - var/cold_damage_per_tick = 2 //same as heat_damage_per_tick, only if the bodytemperature it's lower than minbodytemp //Atmos effect - Yes, you can make creatures that require plasma or co2 to survive. N2O is a trace gas and handled separately, hence why it isn't here. It'd be hard to add it. Hard and me don't mix (Yes, yes make all the dick jokes you want with that.) - Errorage - var/min_oxy = 5 - var/max_oxy = 0 //Leaving something at 0 means it's off - has no maximum - var/min_tox = 0 - var/max_tox = 1 - var/min_co2 = 0 - var/max_co2 = 5 - var/min_n2 = 0 - var/max_n2 = 0 + var/list/atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) //Leaving something at 0 means it's off - has no maximum var/unsuitable_atmos_damage = 2 //This damage is taken when atmos doesn't fit all the requirements above - //LETTING SIMPLE ANIMALS ATTACK? WHAT COULD GO WRONG. Defaults to zero so Ian can still be cuddly var/melee_damage_lower = 0 var/melee_damage_upper = 0 @@ -81,52 +71,61 @@ ..() /mob/living/simple_animal/updatehealth() - return + health = max(maxHealth - getBruteLoss(), 0) /mob/living/simple_animal/Life() + if(..()) + if(!client && !stat) + handle_automated_movement() - update_gravity(mob_has_gravity()) + handle_automated_speech() + return 1 - //Health - if(stat == DEAD) - if(health > 0) - icon_state = icon_living - dead_mob_list -= src - living_mob_list += src - stat = CONSCIOUS - density = 1 - update_canmove() - return 0 +/mob/living/simple_animal/handle_regular_status_updates() + if(..()) //alive + if(health < 1) + death() + return 0 + return 1 +/mob/living/simple_animal/handle_disabilities() + //Eyes + if(disabilities & BLIND || stat) + eye_blind = max(eye_blind, 1) + else + if(eye_blind) + eye_blind = 0 + if(eye_blurry) + eye_blurry = 0 - if(health < 1 && stat != DEAD) - Die() + //Ears + if(disabilities & DEAF) + setEarDamage(-1, max(ear_deaf, 1)) + else if(ear_damage < 100) + setEarDamage(0, 0) - if(health > maxHealth) - health = maxHealth +/mob/living/simple_animal/handle_status_effects() + ..() + if(stuttering) + stuttering = 0 - if(stunned) - AdjustStunned(-1) - if(weakened) - AdjustWeakened(-1) - if(paralysis) - AdjustParalysis(-1) + if(druggy) + druggy = 0 - adjustEarDamage((ear_damage < 25 ? -0.05 : 0), -1) - - //Movement - if(!client && !stop_automated_movement && wander) +/mob/living/simple_animal/proc/handle_automated_movement() + if(!stop_automated_movement && wander) if(isturf(src.loc) && !resting && !buckled && canmove) //This is so it only moves if it's not inside a closet, gentics machine, etc. turns_since_move++ if(turns_since_move >= turns_per_move) - if(!(stop_automated_movement_when_pulled && pulledby)) //Soma animals don't move when pulled + if(!(stop_automated_movement_when_pulled && pulledby)) //Some animals don't move when pulled var/anydir = pick(cardinal) if(Process_Spacemove(anydir)) Move(get_step(src, anydir), anydir) turns_since_move = 0 + return 1 - //Speaking - if(!client && speak_chance) +/mob/living/simple_animal/proc/handle_automated_speech() + if(speak_chance) if(rand(0,200) < speak_chance) if(speak && speak.len) if((emote_hear && emote_hear.len) || (emote_see && emote_see.len)) @@ -160,13 +159,13 @@ emote("me", 2, pick(emote_hear)) - //Atmos +/mob/living/simple_animal/handle_environment(datum/gas_mixture/environment) var/atmos_suitable = 1 var/atom/A = src.loc if(isturf(A)) var/turf/T = A - var/areatemp = T.temperature + var/areatemp = get_temperature(environment) if( abs(areatemp - bodytemperature) > 40 ) var/diff = areatemp - bodytemperature diff = diff / 5 @@ -181,40 +180,33 @@ var/n2 = ST.air.nitrogen var/co2 = ST.air.carbon_dioxide - if(min_oxy) - if(oxy < min_oxy) - atmos_suitable = 0 - if(max_oxy) - if(oxy > max_oxy) - atmos_suitable = 0 - if(min_tox) - if(tox < min_tox) - atmos_suitable = 0 - if(max_tox) - if(tox > max_tox) - atmos_suitable = 0 - if(min_n2) - if(n2 < min_n2) - atmos_suitable = 0 - if(max_n2) - if(n2 > max_n2) - atmos_suitable = 0 - if(min_co2) - if(co2 < min_co2) - atmos_suitable = 0 - if(max_co2) - if(co2 > max_co2) - atmos_suitable = 0 + if(atmos_requirements["min_oxy"] && oxy < atmos_requirements["min_oxy"]) + atmos_suitable = 0 + else if(atmos_requirements["max_oxy"] && oxy > atmos_requirements["max_oxy"]) + atmos_suitable = 0 + else if(atmos_requirements["min_tox"] && tox < atmos_requirements["min_tox"]) + atmos_suitable = 0 + else if(atmos_requirements["max_tox"] && tox > atmos_requirements["max_tox"]) + atmos_suitable = 0 + else if(atmos_requirements["min_n2"] && n2 < atmos_requirements["min_n2"]) + atmos_suitable = 0 + else if(atmos_requirements["max_n2"] && n2 > atmos_requirements["max_n2"]) + atmos_suitable = 0 + else if(atmos_requirements["min_co2"] && co2 < atmos_requirements["min_co2"]) + atmos_suitable = 0 + else if(atmos_requirements["max_co2"] && co2 > atmos_requirements["max_co2"]) + atmos_suitable = 0 - //Atmos effect + if(!atmos_suitable) + adjustBruteLoss(unsuitable_atmos_damage) + + handle_temperature_damage() + +/mob/living/simple_animal/proc/handle_temperature_damage() if(bodytemperature < minbodytemp) - adjustBruteLoss(cold_damage_per_tick) + adjustBruteLoss(2) else if(bodytemperature > maxbodytemp) - adjustBruteLoss(heat_damage_per_tick) - - if(!atmos_suitable) - adjustBruteLoss(unsuitable_atmos_damage) - return 1 + adjustBruteLoss(3) /mob/living/simple_animal/gib(var/animation = 0) if(icon_gib) @@ -231,12 +223,13 @@ adjustBruteLoss(20) return -/mob/living/simple_animal/say_quote(var/text) - if(speak_emote && speak_emote.len) +/mob/living/simple_animal/say_quote(input) + var/ending = copytext(input, length(input)) + if(speak_emote && speak_emote.len && ending != "?" && ending != "!") var/emote = pick(speak_emote) if(emote) - return "[emote], \"[text]\"" - return "says, \"[text]\""; + return "[emote], \"[input]\"" + return ..() /mob/living/simple_animal/emote(var/act, var/m_type=1, var/message = null) if(stat) @@ -250,6 +243,7 @@ if(..()) var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) attack_threshold_check(damage) + return 1 /mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj) if(!Proj) @@ -274,16 +268,17 @@ M.do_attack_animation(src) visible_message("[M] [response_harm] [src]!") playsound(loc, "punch", 25, 1, -1) - adjustBruteLoss(harm_intent_damage) + attack_threshold_check(harm_intent_damage) add_logs(M, src, "attacked", admin=0) updatehealth() - return + return 1 /mob/living/simple_animal/attack_paw(mob/living/carbon/monkey/M as mob) if(..()) //successful monkey bite. if(stat != DEAD) var/damage = rand(1, 3) attack_threshold_check(damage) + return 1 if (M.a_intent == "help") if (health > 0) visible_message("[M.name] [response_help] [src].") @@ -293,13 +288,19 @@ /mob/living/simple_animal/attack_alien(mob/living/carbon/alien/humanoid/M as mob) if(..()) //if harm or disarm intent. - var/damage = rand(15, 30) - visible_message("[M] has slashed at [src]!", \ - "[M] has slashed at [src]!") - playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1) - add_logs(M, src, "attacked", admin=0) - attack_threshold_check(damage) - return + if(M.a_intent == "disarm") + playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1) + visible_message("[M] [response_disarm] [name]!", \ + "[M] [response_disarm] [name]!") + add_logs(M, src, "disarmed", admin=0) + else + var/damage = rand(15, 30) + visible_message("[M] has slashed at [src]!", \ + "[M] has slashed at [src]!") + playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1) + add_logs(M, src, "attacked", admin=0) + attack_threshold_check(damage) + return 1 /mob/living/simple_animal/attack_larva(mob/living/carbon/alien/larva/L as mob) if(..()) //successful larva bite @@ -307,17 +308,15 @@ if(stat != DEAD) L.amount_grown = min(L.amount_grown + damage, L.max_grown) attack_threshold_check(damage) + return 1 -/mob/living/simple_animal/attack_slime(mob/living/carbon/slime/M as mob) - ..() - var/damage = rand(1, 3) - - if(M.is_adult) - damage = rand(20, 40) - else - damage = rand(5, 35) - attack_threshold_check(damage) - return +/mob/living/simple_animal/attack_slime(mob/living/simple_animal/slime/M as mob) + if(..()) //successful slime attack + var/damage = rand(15, 25) + if(M.is_adult) + damage = rand(20, 35) + attack_threshold_check(damage) + return 1 /mob/living/simple_animal/proc/attack_threshold_check(var/damage) if(damage <= force_threshold) @@ -331,9 +330,8 @@ if(O.flags & NOBLUDGEON) return - user.changeNext_move(CLICK_CD_MELEE) - if(istype(O, /obj/item/stack/medical)) + user.changeNext_move(CLICK_CD_MELEE) if(stat != DEAD) var/obj/item/stack/medical/MED = O if(health < maxHealth) @@ -356,28 +354,13 @@ return if((meat_type || skin_type) && (stat == DEAD)) //if the animal has a meat, and if it is dead. + user.changeNext_move(CLICK_CD_MELEE) var/sharpness = is_sharp(O) if(sharpness) harvest(user, sharpness) return - user.do_attack_animation(src) - var/damage = 0 - if(O.force) - if(O.force >= force_threshold) - damage = O.force - if (O.damtype == STAMINA) - damage = 0 - visible_message("[user] has [O.attack_verb.len ? "[pick(O.attack_verb)]": "attacked"] [src] with [O]!",\ - "[user] has [O.attack_verb.len ? "[pick(O.attack_verb)]": "attacked"] you with [O]!") - else - visible_message("[O] bounces harmlessly off of [src].",\ - "[O] bounces harmlessly off of [src].") - playsound(loc, O.hitsound, 50, 1, -1) - else - user.visible_message("[user] gently taps [src] with [O].",\ - "This weapon is ineffective, it does no damage.") - adjustBruteLoss(damage) + ..() /mob/living/simple_animal/movement_delay() var/tally = 0 //Incase I need to add stuff other than "speed" later @@ -391,23 +374,17 @@ if(statpanel("Status")) stat(null, "Health: [round((health / maxHealth) * 100)]%") + return 1 -/mob/living/simple_animal/proc/Die() - health = 0 // so /mob/living/simple_animal/Life() doesn't magically revive them - dead_mob_list += src +/mob/living/simple_animal/death(gibbed) + health = 0 icon_state = icon_dead stat = DEAD density = 0 - return - -/mob/living/simple_animal/death(gibbed) - if(stat == DEAD) - return - + lying = 1 if(!gibbed) visible_message("\the [src] stops moving...") - - Die() + ..() /mob/living/simple_animal/ex_act(severity, target) ..() @@ -419,14 +396,9 @@ if (2.0) adjustBruteLoss(60) - if(3.0) adjustBruteLoss(30) - -/mob/living/simple_animal/adjustBruteLoss(damage) - health = Clamp(health - damage, 0, maxHealth) - if(health < 1 && stat != DEAD) - Die() + updatehealth() /mob/living/simple_animal/proc/CanAttack(var/atom/the_target) if(see_invisible < the_target.invisibility) @@ -441,6 +413,8 @@ return 0 return 1 +/mob/living/simple_animal/handle_fire() + return /mob/living/simple_animal/update_fire() return @@ -451,6 +425,10 @@ /mob/living/simple_animal/revive() health = maxHealth + icon_state = icon_living + lying = 0 + density = 1 + update_canmove() ..() /mob/living/simple_animal/proc/make_babies() // <3 <3 <3 diff --git a/code/modules/mob/living/carbon/slime/death.dm b/code/modules/mob/living/simple_animal/slime/death.dm similarity index 57% rename from code/modules/mob/living/carbon/slime/death.dm rename to code/modules/mob/living/simple_animal/slime/death.dm index ecf01af344b..81493941d34 100644 --- a/code/modules/mob/living/carbon/slime/death.dm +++ b/code/modules/mob/living/simple_animal/slime/death.dm @@ -1,11 +1,12 @@ -/mob/living/carbon/slime/death(gibbed) +/mob/living/simple_animal/slime/death(gibbed) if(stat == DEAD) return if(!gibbed) if(is_adult) - var/mob/living/carbon/slime/M = new /mob/living/carbon/slime(loc) + var/mob/living/simple_animal/slime/M = new /mob/living/simple_animal/slime(loc) M.colour = colour M.rabid = 1 + M.regenerate_icons() is_adult = 0 maxHealth = 150 revive() @@ -13,21 +14,19 @@ number = rand(1, 1000) name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])" return - else - visible_message("The [name] seizes up and falls limp...") stat = DEAD - icon_state = "[colour] baby slime dead" overlays.len = 0 update_canmove() - if(blind) blind.layer = 0 + if(blind) + blind.layer = 0 if(ticker && ticker.mode) ticker.mode.check_win() return ..(gibbed) -/mob/living/carbon/slime/gib() +/mob/living/simple_animal/slime/gib() death(1) - qdel(src) \ No newline at end of file + qdel(src) diff --git a/code/modules/mob/living/carbon/slime/emote.dm b/code/modules/mob/living/simple_animal/slime/emote.dm similarity index 95% rename from code/modules/mob/living/carbon/slime/emote.dm rename to code/modules/mob/living/simple_animal/slime/emote.dm index d8d70595333..7f8127d3bcf 100644 --- a/code/modules/mob/living/carbon/slime/emote.dm +++ b/code/modules/mob/living/simple_animal/slime/emote.dm @@ -1,4 +1,4 @@ -/mob/living/carbon/slime/emote(var/act) +/mob/living/simple_animal/slime/emote(var/act) if (findtext(act, "-", 1, null)) @@ -76,7 +76,7 @@ else src << "Unusable emote '[act]'. Say *help for a list." - if ((message && src.stat == 0)) + if ((message && stat == CONSCIOUS)) if(client) log_emote("[name]/[key] : [message]") if (m_type & 1) diff --git a/code/modules/mob/living/carbon/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm similarity index 78% rename from code/modules/mob/living/carbon/slime/life.dm rename to code/modules/mob/living/simple_animal/slime/life.dm index 484f2700ae8..904803ff26c 100644 --- a/code/modules/mob/living/carbon/slime/life.dm +++ b/code/modules/mob/living/simple_animal/slime/life.dm @@ -1,11 +1,13 @@ -/mob/living/carbon/slime + +/mob/living/simple_animal/slime var/AIproc = 0 // determines if the AI loop is activated var/Atkcool = 0 // attack cooldown var/Tempstun = 0 // temporary temperature stuns var/Discipline = 0 // if a slime has been hit with a freeze gun, or wrestled/attacked off a human, they become disciplined and don't attack anymore for a while var/SStun = 0 // stun variable -/mob/living/carbon/slime/Life() + +/mob/living/simple_animal/slime/Life() set invisibility = 0 set background = BACKGROUND_ENABLED @@ -15,12 +17,10 @@ handle_nutrition() handle_targets() if (!ckey) - handle_speech_and_mood() + handle_mood() + handle_speech() -/mob/living/carbon/slime/handle_breathing() - return - -/mob/living/carbon/slime/proc/AIprocess() // the master AI process +/mob/living/simple_animal/slime/proc/AIprocess() // the master AI process if(AIproc || stat == DEAD || client) return @@ -45,7 +45,7 @@ break if(Target) - for(var/mob/living/carbon/slime/M in view(1,Target)) + for(var/mob/living/simple_animal/slime/M in view(1,Target)) if(M.Victim == Target) Target = null AIproc = 0 @@ -99,9 +99,8 @@ AIproc = 0 -/mob/living/carbon/slime/handle_environment(datum/gas_mixture/environment) +/mob/living/simple_animal/slime/handle_environment(datum/gas_mixture/environment) if(!environment) - adjustToxLoss(rand(10,20)) return //var/environment_heat_capacity = environment.heat_capacity() @@ -120,9 +119,9 @@ if(bodytemperature <= (T0C - 50)) // hurt temperature if(bodytemperature <= 50) // sqrting negative numbers is bad - adjustToxLoss(200) + adjustBruteLoss(200) else - adjustToxLoss(round(sqrt(bodytemperature)) * 2) + adjustBruteLoss(round(sqrt(bodytemperature)) * 2) else Tempstun = 0 @@ -131,7 +130,7 @@ return //TODO: DEFERRED -/mob/living/carbon/slime/proc/adjust_body_temperature(current, loc_temp, boost) +/mob/living/simple_animal/slime/proc/adjust_body_temperature(current, loc_temp, boost) var/temperature = current var/difference = abs(current-loc_temp) //get difference var/increments// = difference/10 //find how many increments apart they are @@ -148,9 +147,10 @@ temp_change = (temperature - current) return temp_change -/mob/living/carbon/slime/handle_chemicals_in_body() +/mob/living/simple_animal/slime/handle_chemicals_in_body() - if(reagents) reagents.metabolize(src) + if(reagents) + reagents.metabolize(src) if (reagents.get_reagent_amount("plasma")>=5) mutation_chance = min(mutation_chance + 5,50) //Prevents mutation chance going >50% @@ -158,81 +158,15 @@ if (reagents.get_reagent_amount("epinephrine")>=5) mutation_chance = max(mutation_chance - 5,0) //Prevents muation chance going <0% reagents.remove_reagent("epinephrine", 5) - src.updatehealth() + updatehealth() - return //TODO: DEFERRED +/mob/living/simple_animal/slime/handle_regular_status_updates() + if(..()) + if(prob(30)) + adjustBruteLoss(-1) -/mob/living/carbon/slime/handle_mutations_and_radiation() - return - -/mob/living/carbon/slime/handle_regular_hud_updates() - return - -/mob/living/carbon/slime/handle_regular_status_updates() - - if(is_adult) - health = 200 - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss()) - else - health = 150 - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss()) - - if(health < config.health_threshold_dead && stat != DEAD) - death() - return - - else if(health < config.health_threshold_crit) - - if(!reagents.has_reagent("epinephrine")) - adjustOxyLoss(3) - - if(stat != DEAD) - Paralyse(3) - stat = UNCONSCIOUS - else - if(stat != DEAD) - stat = CONSCIOUS - - if(prob(30)) - adjustOxyLoss(-1) - adjustToxLoss(-1) - adjustFireLoss(-1) - adjustCloneLoss(-1) - adjustBruteLoss(-1) - - if (stat == DEAD) - lying = 1 - eye_blind = max(eye_blind, 1) - else - if(stunned > 0) - AdjustStunned(-1) - if(weakened > 0) - AdjustWeakened(-1) - if (paralysis > 0) - AdjustParalysis(-1) - - if(stuttering) - stuttering = 0 - - if(eye_blind) - eye_blind = 0 - eye_blind = max(eye_blind, 1) - - setEarDamage((ear_damage < 25 ? 0 : ear_damage),(disabilities & DEAF ? 1 :0)) - - density = !( src.lying ) - - if(disabilities & BLIND) - eye_blind = max(eye_blind, 1) - - if(eye_blurry > 0) - eye_blurry = 0 - - if(druggy > 0) - druggy = 0 - - return 1 - -/mob/living/carbon/slime/proc/handle_nutrition() +/mob/living/simple_animal/slime/proc/handle_nutrition() if(docile) //God as my witness, I will never go hungry again nutrition = 700 @@ -244,7 +178,7 @@ if(nutrition <= 0) nutrition = 0 if(prob(75)) - adjustToxLoss(rand(0,5)) + adjustBruteLoss(rand(0,5)) else if (nutrition >= get_grow_nutrition() && amount_grown < 10) nutrition -= 20 @@ -256,7 +190,7 @@ else Evolve() -/mob/living/carbon/slime/proc/add_nutrition(var/nutrition_to_add = 0, var/lastnut = 0) +/mob/living/simple_animal/slime/proc/add_nutrition(var/nutrition_to_add = 0, var/lastnut = 0) nutrition = min((nutrition + nutrition_to_add), get_max_nutrition()) if(nutrition >= (lastnut + 50)) if(prob(80)) @@ -264,11 +198,11 @@ powerlevel++ if(powerlevel > 10) powerlevel = 10 - adjustToxLoss(-10) + adjustBruteLoss(-10) -/mob/living/carbon/slime/proc/handle_targets() +/mob/living/simple_animal/slime/proc/handle_targets() if(Tempstun) if(!Victim) // not while they're eating! canmove = 0 @@ -336,7 +270,7 @@ if(!L.canmove) // Only one slime can latch on at a time. var/notarget = 0 - for(var/mob/living/carbon/slime/M in view(1,L)) + for(var/mob/living/simple_animal/slime/M in view(1,L)) if(M.Victim == L) notarget = 1 if(notarget) @@ -365,7 +299,7 @@ if(!Target) // If we have no target, we are wandering or following orders if (Leader) - if (holding_still) + if(holding_still) holding_still = max(holding_still - 1, 0) else if(canmove && isturf(loc)) step_to(src, Leader) @@ -377,20 +311,30 @@ step(src, pick(cardinal)) else - if (holding_still) + if(holding_still) holding_still = max(holding_still - 1, 0) + else if (docile && pulledby) + holding_still = 10 else if(canmove && isturf(loc) && prob(33)) step(src, pick(cardinal)) else if(!AIproc) spawn() AIprocess() -/mob/living/carbon/slime/proc/handle_speech_and_mood() - //Mood starts here +/mob/living/simple_animal/slime/handle_automated_movement() + return //slime random movement is currently handled in handle_targets() + +/mob/living/simple_animal/slime/handle_automated_speech() + return //slime random speech is currently handled in handle_speech() + +/mob/living/simple_animal/slime/proc/handle_mood() var/newmood = "" - if (rabid || attacked) newmood = "angry" - else if (docile) newmood = ":3" - else if (Target) newmood = "mischevous" + if (rabid || attacked) + newmood = "angry" + else if (docile) + newmood = ":3" + else if (Target) + newmood = "mischevous" if (!newmood) if (Discipline && prob(25)) @@ -399,12 +343,14 @@ newmood = pick("sad", ":3", "pout") if ((mood == "sad" || mood == ":3" || mood == "pout") && !newmood) - if (prob(75)) newmood = mood + if(prob(75)) + newmood = mood if (newmood != mood) // This is so we don't redraw them every time mood = newmood regenerate_icons() +/mob/living/simple_animal/slime/proc/handle_speech() //Speech understanding starts here var/to_say if (speech_buffer.len > 0) @@ -481,17 +427,17 @@ emote(pick("bounce","sway","light","vibrate","jiggle")) else var/t = 10 - var/slimes_near = -1 // Don't count myself + var/slimes_near = 0 var/dead_slimes = 0 var/friends_near = list() - for (var/mob/living/carbon/M in view(7,src)) - if (isslime(M)) + for (var/mob/living/L in view(7,src)) + if(isslime(L) && L != src) ++slimes_near - if (M.stat == DEAD) + if (L.stat == DEAD) ++dead_slimes - if (M in Friends) + if (L in Friends) t += 20 - friends_near += M + friends_near += L if (nutrition < get_hunger_nutrition()) t += 10 if (nutrition < get_starve_nutrition()) t += 10 if (prob(2) && prob(t)) @@ -517,12 +463,12 @@ phrases += "Purr..." if (attacked) phrases += "Grrr..." - if (getToxLoss() > 30) + if (bodytemperature < T0C) phrases += "Cold..." - if (getToxLoss() > 60) + if (bodytemperature < T0C - 30) phrases += "So... cold..." phrases += "Very... cold..." - if (getToxLoss() > 90) + if (bodytemperature < T0C - 50) phrases += "..." phrases += "C... c..." if (Victim) @@ -543,23 +489,23 @@ phrases += "[M]... feed me..." say (pick(phrases)) -/mob/living/carbon/slime/proc/get_max_nutrition() // Can't go above it +/mob/living/simple_animal/slime/proc/get_max_nutrition() // Can't go above it if (is_adult) return 1200 else return 1000 -/mob/living/carbon/slime/proc/get_grow_nutrition() // Above it we grow, below it we can eat +/mob/living/simple_animal/slime/proc/get_grow_nutrition() // Above it we grow, below it we can eat if (is_adult) return 1000 else return 800 -/mob/living/carbon/slime/proc/get_hunger_nutrition() // Below it we will always eat +/mob/living/simple_animal/slime/proc/get_hunger_nutrition() // Below it we will always eat if (is_adult) return 600 else return 500 -/mob/living/carbon/slime/proc/get_starve_nutrition() // Below it we will eat before everything else - if (is_adult) return 300 +/mob/living/simple_animal/slime/proc/get_starve_nutrition() // Below it we will eat before everything else + if(is_adult) return 300 else return 200 -/mob/living/carbon/slime/proc/will_hunt(var/hunger = -1) // Check for being stopped from feeding and chasing +/mob/living/simple_animal/slime/proc/will_hunt(var/hunger = -1) // Check for being stopped from feeding and chasing if (docile) return 0 if (hunger == 2 || rabid || attacked) return 1 if (Leader) return 0 diff --git a/code/modules/mob/living/carbon/slime/powers.dm b/code/modules/mob/living/simple_animal/slime/powers.dm similarity index 56% rename from code/modules/mob/living/carbon/slime/powers.dm rename to code/modules/mob/living/simple_animal/slime/powers.dm index 01918ec5fc5..e39b9400dfd 100644 --- a/code/modules/mob/living/carbon/slime/powers.dm +++ b/code/modules/mob/living/simple_animal/slime/powers.dm @@ -1,6 +1,25 @@ -/mob/living/carbon/slime/verb/Feed() +/mob/living/simple_animal/slime/verb/Feed() set category = "Slime" set desc = "This will let you feed on any valid creature in the surrounding area. This should also be used to halt the feeding process." + + if(stat) + return 0 + + var/list/choices = list() + for(var/mob/living/C in view(1,src)) + if(C!=src && !isslime(C) && Adjacent(C)) + choices += C + + var/mob/living/M = input(src,"Who do you wish to feed on?") in null|choices + if(!M) return 0 + if(CanFeedon(M)) + Feedon(M) + return 1 + +/mob/living/simple_animal/slime/proc/CanFeedon(var/mob/living/M) + if(!Adjacent(M)) + return 0 + if(Victim) Feedstop() return 0 @@ -13,64 +32,35 @@ src << "I must be conscious to do this..." return 0 - var/list/choices = list() - for(var/mob/living/C in view(1,src)) - if(C!=src && !istype(C,/mob/living/carbon/slime) && Adjacent(C)) - choices += C + if(M.stat == DEAD) + src << "This subject does not have a strong enough life energy..." + return 0 - var/mob/living/M = input(src,"Who do you wish to feed on?") in null|choices - if(!M) return 0 - if(Adjacent(M)) - - if(istype(M, /mob/living/carbon/brain)) - src << "This subject does not have an edible life energy..." + for(var/mob/living/simple_animal/slime/met in view()) + if(met.Victim == M && met != src) + src << "The [met.name] is already feeding on this subject..." return 0 + return 1 - if(istype(M, /mob/living/carbon) && (M.health < -70)) - src << "This subject does not have a strong enough life energy..." - return 0 +/mob/living/simple_animal/slime/proc/Feedon(var/mob/living/M) - if(istype(M, /mob/living/simple_animal) && (M.health < 1))//animals don't go into crit, stupid; fixes infinite energy exploit - src << "This subject does not have a strong enough life energy..." - return 0 + src << "I have latched onto the subject and begun feeding..." + M << "The [name] has latched onto [M.name]!" - for(var/mob/living/carbon/slime/met in view()) - if(met.Victim == M && met != src) - src << "The [met.name] is already feeding on this subject..." - return 0 - - src << "I have latched onto the subject and begun feeding..." - M << "The [src.name] has latched onto your head!" - - Feedon(M) - return 1 - - -/mob/living/carbon/slime/proc/Feedon(var/mob/living/M) Victim = M src.loc = M.loc canmove = 0 anchored = 1 var/lastnut = nutrition var/fed_succesfully = 0 - var/health_minimum = -70 - if(is_adult) - icon_state = "[colour] adult slime eat" - else - icon_state = "[colour] baby slime eat" - - - if(istype(Victim, /mob/living/simple_animal)) - health_minimum = 0 - - while(Victim && Victim.health > health_minimum && stat != 2) + while(Victim && Victim == M && Victim.stat != DEAD && stat != DEAD) canmove = 0 if(Adjacent(Victim)) loc = M.loc - if(istype(Victim, /mob/living/carbon)) + if(iscarbon(Victim)) Victim.adjustCloneLoss(rand(5,6)) Victim.adjustToxLoss(rand(1,2)) if(Victim.health <= 0) @@ -87,12 +77,12 @@ fed_succesfully = 1 - else if(health_minimum == 0) //we already know it's a simple_animal from above + else if(isanimal(Victim)) //we already know it's a simple_animal from above Victim.adjustBruteLoss(is_adult ? rand(7, 15) : rand(4, 12)) fed_succesfully = 1 else - src << "[pick("This subject is incompatable", \ + src << "[pick("This subject is incompatible", \ "This subject does not have a life energy", "This subject is empty", \ "I am not satisified", "I can not feed from this subject", \ "I do not feel nourished", "This subject is not food")]..." @@ -101,10 +91,7 @@ add_nutrition(rand(15,30), lastnut) //Heal yourself. - adjustOxyLoss(-10) adjustBruteLoss(-10) - adjustFireLoss(-10) - adjustCloneLoss(-10) updatehealth() if(Victim) @@ -115,62 +102,45 @@ else break - if(stat == 2) //why the fuck are you doing icon updating here - if(!is_adult) - icon_state = "[colour] baby slime dead" - - else - if(is_adult) - icon_state = "[colour] adult slime" - else - icon_state = "[colour] baby slime" - canmove = 1 anchored = 0 - if(M) - if(M.health < health_minimum) - M.canmove = 0 - if(!client) - if(Victim && !rabid && !attacked) - if(Victim.LAssailant && Victim.LAssailant != Victim) - if(prob(50)) - if(!(Victim.LAssailant in Friends)) - Friends[Victim.LAssailant] = 1 - //Friends.Add(Victim.LAssailant) // no idea why i was using the |= operator - else - ++Friends[Victim.LAssailant] + if(M && M.stat == DEAD) + if(!client) + if(Victim && !rabid && !attacked) + if(Victim.LAssailant && Victim.LAssailant != Victim) + if(prob(50)) + if(!(Victim.LAssailant in Friends)) + Friends[Victim.LAssailant] = 1 + else + ++Friends[Victim.LAssailant] - if(M.client && istype(src, /mob/living/carbon/human)) - if(prob(85)) - rabid = 1 // UUUNNBGHHHH GONNA EAT JUUUUUU + if(M.client && ishuman(M)) + if(prob(85)) + rabid = 1 // UUUNNBGHHHH GONNA EAT JUUUUUU - if(client) - src << "This subject does not have a strong enough life energy anymore..." - else - M.canmove = 1 - - if(client) - src << "I have stopped feeding..." - else if(client) - src << "I have stopped feeding..." + src << "This subject does not have a strong enough life energy anymore..." + + else if(client) + src << "I have stopped feeding..." Victim = null -/mob/living/carbon/slime/proc/Feedstop() +/mob/living/simple_animal/slime/proc/Feedstop() if(Victim) - if(Victim.client) Victim << "[src] has let go of your head!" + if(Victim.client) + Victim << "[src] has let go of your head!" Victim = null -/mob/living/carbon/slime/proc/UpdateFeed(var/mob/M) +/mob/living/simple_animal/slime/proc/UpdateFeed(var/mob/M) if(Victim) if(Victim == M) loc = M.loc // simple "attach to head" effect! -/mob/living/carbon/slime/verb/Evolve() +/mob/living/simple_animal/slime/verb/Evolve() set category = "Slime" set desc = "This will let you evolve from baby to adult slime." @@ -189,7 +159,7 @@ else src << "I have already evolved..." -/mob/living/carbon/slime/verb/Reproduce() +/mob/living/simple_animal/slime/verb/Reproduce() set category = "Slime" set desc = "This will make you split into four Slimes." @@ -207,7 +177,7 @@ var/new_nutrition = round(nutrition * 0.9) var/new_powerlevel = round(powerlevel / 4) for(var/i=1,i<=4,i++) - var/mob/living/carbon/slime/M = new /mob/living/carbon/slime/(loc) + var/mob/living/simple_animal/slime/M = new /mob/living/simple_animal/slime/(loc) if(prob(mutation_chance)) M.colour = slime_mutation[rand(1,4)] else @@ -219,7 +189,7 @@ babies += M feedback_add_details("slime_babies_born","slimebirth_[replacetext(M.colour," ","_")]") - var/mob/living/carbon/slime/new_slime = pick(babies) + var/mob/living/simple_animal/slime/new_slime = pick(babies) new_slime.a_intent = "harm" new_slime.languages = languages if(src.mind) diff --git a/code/modules/mob/living/simple_animal/slime/say.dm b/code/modules/mob/living/simple_animal/slime/say.dm new file mode 100644 index 00000000000..a45b9fad0b3 --- /dev/null +++ b/code/modules/mob/living/simple_animal/slime/say.dm @@ -0,0 +1,7 @@ +/mob/living/simple_animal/slime/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans) + if(speaker != src && !radio_freq) + if (speaker in Friends) + speech_buffer = list() + speech_buffer += speaker + speech_buffer += lowertext(html_decode(message)) + ..() diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm new file mode 100644 index 00000000000..44cd079bca5 --- /dev/null +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -0,0 +1,383 @@ +/mob/living/simple_animal/slime + name = "baby slime" + icon = 'icons/mob/slimes.dmi' + icon_state = "grey baby slime" + pass_flags = PASSTABLE + ventcrawler = 2 + var/is_adult = 0 + var/docile = 0 + languages = SLIME | HUMAN + faction = list("slime") + + harm_intent_damage = 5 + icon_living = "grey baby slime" + icon_dead = "grey baby slime dead" + response_help = "pets" + response_disarm = "shoos" + response_harm = "stomps on" + emote_see = list("jiggles", "bounces in place") + speak_emote = list("chirps") + + layer = 5 + + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + + maxHealth = 150 + health = 150 + gender = NEUTER + + nutrition = 700 + + see_in_dark = 8 + update_slimes = 0 + + verb_say = "telepathically chirps" + verb_ask = "telepathically asks" + verb_exclaim = "telepathically cries" + verb_yell = "telephatically cries" + + // canstun and canweaken don't affect slimes because they ignore stun and weakened variables + // for the sake of cleanliness, though, here they are. + status_flags = CANPARALYSE|CANPUSH + + var/cores = 1 // the number of /obj/item/slime_extract's the slime has left inside + var/mutation_chance = 30 // Chance of mutating, should be between 25 and 35 + + var/powerlevel = 0 // 1-10 controls how much electricity they are generating + var/amount_grown = 0 // controls how long the slime has been overfed, if 10, grows or reproduces + + var/number = 0 // Used to understand when someone is talking to it + + var/mob/living/Victim = null // the person the slime is currently feeding on + var/mob/living/Target = null // AI variable - tells the slime to hunt this down + var/mob/living/Leader = null // AI variable - tells the slime to follow this person + + var/attacked = 0 // Determines if it's been attacked recently. Can be any number, is a cooloff-ish variable + var/rabid = 0 // If set to 1, the slime will attack and eat anything it comes in contact with + var/holding_still = 0 // AI variable, cooloff-ish for how long it's going to stay in one place + var/target_patience = 0 // AI variable, cooloff-ish for how long it's going to follow its target + + var/list/Friends = list() // A list of friends; they are not considered targets for feeding; passed down after splitting + + var/list/speech_buffer = list() // Last phrase said near it and person who said it + + var/mood = "" // To show its face + + ///////////TIME FOR SUBSPECIES + + var/colour = "grey" + var/coretype = /obj/item/slime_extract/grey + var/list/slime_mutation[4] + +/mob/living/simple_animal/slime/New() + if(is_adult) + health = 200 + maxHealth = 200 + create_reagents(100) + spawn (0) + number = rand(1, 1000) + name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])" + icon_state = "[colour] [is_adult ? "adult" : "baby"] slime" + icon_dead = "[icon_state] dead" + real_name = name + slime_mutation = mutation_table(colour) + mutation_chance = rand(25, 35) + var/sanitizedcolour = replacetext(colour, " ", "") + coretype = text2path("/obj/item/slime_extract/[sanitizedcolour]") + ..() + +/mob/living/simple_animal/slime/regenerate_icons() + overlays.len = 0 + var/icon_text = "[colour] [is_adult ? "adult" : "baby"] slime" + icon_dead = "[icon_text] dead" + if(stat != DEAD) + icon_state = icon_text + if(mood) + overlays += image('icons/mob/slimes.dmi', icon_state = "aslime-[mood]") + else + icon_state = icon_dead + ..() + +/mob/living/simple_animal/slime/movement_delay() + if(bodytemperature >= 330.23) // 135 F + return -1 // slimes become supercharged at high temperatures + + var/tally = 0 + + var/health_deficiency = (100 - health) + if(health_deficiency >= 45) + tally += (health_deficiency / 25) + + if(bodytemperature < 183.222) + tally += (283.222 - bodytemperature) / 10 * 1.75 + + if(reagents) + if(reagents.has_reagent("morphine")) // morphine slows slimes down + tally *= 2 + + if(reagents.has_reagent("frostoil")) // Frostoil also makes them move VEEERRYYYYY slow + tally *= 5 + + if(health <= 0) // if damaged, the slime moves twice as slow + tally *= 2 + + return tally + config.slime_delay + +/mob/living/simple_animal/slime/ObjBump(obj/O) + if(!client && powerlevel > 0) + var/probab = 10 + switch(powerlevel) + if(1 to 2) probab = 20 + if(3 to 4) probab = 30 + if(5 to 6) probab = 40 + if(7 to 8) probab = 60 + if(9) probab = 70 + if(10) probab = 95 + if(prob(probab)) + if(istype(O, /obj/structure/window) || istype(O, /obj/structure/grille)) + if(nutrition <= get_hunger_nutrition() && !Atkcool) + if (is_adult || prob(5)) + O.attack_slime(src) + Atkcool = 1 + spawn(45) + Atkcool = 0 + +/mob/living/simple_animal/slime/MobBump(mob/M) + if(istype(M, /mob/living/carbon/human)) //pushing humans + if(is_adult && prob(10)) //only if we're adult, and 10% of the time + return 0 + else + return 1 + +/mob/living/simple_animal/slime/Process_Spacemove(var/movement_dir = 0) + return 2 + +/mob/living/simple_animal/slime/Stat() + if(..()) + + if(!docile) + stat(null, "Nutrition: [nutrition]/[get_max_nutrition()]") + if(amount_grown >= 10) + if(is_adult) + stat(null, "You can reproduce!") + else + stat(null, "You can evolve!") + + stat(null,"Power Level: [powerlevel]") + +/mob/living/simple_animal/slime/bullet_act(var/obj/item/projectile/Proj) + if(!Proj) + return + attacked += 10 + if((Proj.damage_type == BURN)) + adjustBruteLoss(-abs(Proj.damage)) //fire projectiles heals slimes. + Proj.on_hit(src, 0) + else + ..(Proj) + return 0 + +/mob/living/simple_animal/slime/emp_act(severity) + powerlevel = 0 // oh no, the power! + ..() + +/mob/living/simple_animal/slime/MouseDrop(var/atom/movable/A as mob|obj) + if(isliving(A) && A != src) + var/mob/living/Food = A + if(CanFeedon(Food)) + Feedon(Food) + ..() + +/mob/living/simple_animal/slime/unEquip(obj/item/W as obj) + return + +/mob/living/simple_animal/slime/start_pulling(var/atom/movable/AM) + return + +/mob/living/simple_animal/slime/attack_ui(slot) + return + +/mob/living/simple_animal/slime/attack_slime(mob/living/simple_animal/slime/M as mob) + if(..()) //successful slime attack + if(M == src) + return + if(Victim) + Victim = null + visible_message("[M] pulls [src] off!") + return + attacked += 5 + if(nutrition >= 100) //steal some nutrition. negval handled in life() + nutrition -= (50 + (40 * M.is_adult)) + M.add_nutrition(50 + (40 * M.is_adult)) + if(health > 0) + M.adjustBruteLoss(-10 + (-10 * M.is_adult)) + M.updatehealth() + +/mob/living/simple_animal/slime/attack_animal(mob/living/simple_animal/M as mob) + if(..()) + attacked += 10 + + +/mob/living/simple_animal/slime/attack_paw(mob/living/carbon/monkey/M as mob) + if(..()) //successful monkey bite. + attacked += 10 + +/mob/living/simple_animal/slime/attack_larva(mob/living/carbon/alien/larva/L as mob) + if(..()) //successful larva bite. + attacked += 10 + +/mob/living/simple_animal/slime/attack_hulk(mob/living/carbon/human/user) + if(user.a_intent == "harm") + adjustBruteLoss(10) + discipline_slime(user) + + +/mob/living/simple_animal/slime/attack_hand(mob/living/carbon/human/M as mob) + if(Victim) + if(Victim == M) + if(prob(60)) + visible_message("[M] attempts to wrestle \the [name] off!") + playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + + else + visible_message(" [M] manages to wrestle \the [name] off!") + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + + discipline_slime(M) + + else + M.do_attack_animation(src) + if(prob(30)) + visible_message("[M] attempts to wrestle \the [name] off of [Victim]!") + playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + + else + visible_message(" [M] manages to wrestle \the [name] off of [Victim]!") + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + + discipline_slime(M) + else + if(stat == DEAD && surgeries.len) + if(M.a_intent == "help") + for(var/datum/surgery/S in surgeries) + if(S.next_step(M, src)) + return 1 + if(..()) //successful attack + attacked += 10 + +/mob/living/simple_animal/slime/attack_alien(mob/living/carbon/alien/humanoid/M as mob) + if(..()) //if harm or disarm intent. + attacked += 10 + discipline_slime(M) + + +/mob/living/simple_animal/slime/attackby(obj/item/W, mob/living/user, params) + if(stat == DEAD && surgeries.len) + if(user.a_intent == "help") + for(var/datum/surgery/S in surgeries) + if(S.next_step(user, src)) + return 1 + if(istype(W,/obj/item/stack/sheet/mineral/plasma)) //Let's you feed slimes plasma. + if (user in Friends) + ++Friends[user] + else + Friends[user] = 1 + user << "You feed the slime the plasma. It chirps happily." + var/obj/item/stack/sheet/mineral/plasma/S = W + S.use(1) + return + if(W.force > 0) + attacked += 10 + if(prob(25)) + user.do_attack_animation(src) + user.changeNext_move(CLICK_CD_MELEE) + user << "[W] passes right through [src]!" + return + if(Discipline && prob(50)) // wow, buddy, why am I getting attacked?? + Discipline = 0 + if(W.force >= 3) + var/force_effect = 2 * W.force + if(is_adult) + force_effect = round(W.force/2) + if(prob(10 + force_effect)) + discipline_slime(user) + ..() + +/mob/living/simple_animal/slime/show_inv(mob/user) + return + +/mob/living/simple_animal/slime/proc/apply_water() + adjustBruteLoss(rand(15,20)) + if(!client) + if(Target) // Like cats + Target = null + ++Discipline + return + +/mob/living/simple_animal/slime/getTrail() + return null + +/mob/living/simple_animal/slime/examine(mob/user) + + var/msg = "*---------*\nThis is \icon[src] \a [src]!\n" + if (src.stat == DEAD) + msg += "It is limp and unresponsive.\n" + else + if (src.getBruteLoss()) + msg += "" + if (src.getBruteLoss() < 40) + msg += "It has some punctures in its flesh!" + else + msg += "It has severe punctures and tears in its flesh!" + msg += "\n" + + switch(powerlevel) + + if(2 to 3) + msg += "It is flickering gently with a little electrical activity.\n" + + if(4 to 5) + msg += "It is glowing gently with moderate levels of electrical activity.\n" + + if(6 to 9) + msg += "It is glowing brightly with high levels of electrical activity.\n" + + if(10) + msg += "It is radiating with massive levels of electrical activity!\n" + + msg += "*---------*" + user << msg + return + +/mob/living/simple_animal/slime/proc/discipline_slime(mob/user) + + if(stat == DEAD) + return + + if(prob(80) && !client) + Discipline++ + + if(!is_adult) + if(Discipline == 1) + attacked = 0 + + if(Victim || Target) + Victim = null + Target = null + anchored = 0 + + spawn(0) + SStun = 1 + sleep(rand(20,60)) + SStun = 0 + + spawn(0) + canmove = 0 + if(user) + step_away(src,user,15) + sleep(3) + if(user) + step_away(src,user,15) + canmove = 1 + +/mob/living/simple_animal/slime/pet + docile = 1 diff --git a/code/modules/mob/living/carbon/slime/subtypes.dm b/code/modules/mob/living/simple_animal/slime/subtypes.dm similarity index 95% rename from code/modules/mob/living/carbon/slime/subtypes.dm rename to code/modules/mob/living/simple_animal/slime/subtypes.dm index 35d38e31a48..55a6eee734d 100644 --- a/code/modules/mob/living/carbon/slime/subtypes.dm +++ b/code/modules/mob/living/simple_animal/slime/subtypes.dm @@ -1,4 +1,4 @@ -proc/mutation_table(var/colour) +/mob/living/simple_animal/slime/proc/mutation_table(var/colour) var/list/slime_mutation[4] switch(colour) //Tier 1 diff --git a/code/modules/mob/living/simple_animal/slime/update_icons.dm b/code/modules/mob/living/simple_animal/slime/update_icons.dm new file mode 100644 index 00000000000..14525b1e8a0 --- /dev/null +++ b/code/modules/mob/living/simple_animal/slime/update_icons.dm @@ -0,0 +1,4 @@ +//no special icon processing + +/mob/living/simple_animal/slime/update_transform() //They're slimes, they don't lie down. + return \ No newline at end of file diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index e9b5cc5f4c9..8762927332f 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -390,6 +390,8 @@ var/list/slot_equipment_priority = list( \ src.pulling = AM AM.pulledby = src + if(pullin) + pullin.update_icon(src) if(ismob(AM)) var/mob/M = AM if(!iscarbon(src)) @@ -405,6 +407,8 @@ var/list/slot_equipment_priority = list( \ if(pulling) pulling.pulledby = null pulling = null + if(pullin) + pullin.update_icon(src) /mob/verb/mode() set name = "Activate Held Object" @@ -786,9 +790,6 @@ var/list/slot_equipment_priority = list( \ density = !lying update_transform() lying_prev = lying - if(update_icon) //forces a full overlay update - update_icon = 0 - regenerate_icons() return canmove diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 3f3581d1dc9..308239422d8 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -17,7 +17,6 @@ var/obj/screen/m_select = null var/obj/screen/healths = null var/obj/screen/throw_icon = null - var/obj/screen/pressure = null var/obj/screen/damageoverlay = null /*A bunch of this stuff really needs to go under their own defines instead of being globally attached to mob. A variable should only be globally attached to turfs/objects/whatever, when it is in fact needed as such. @@ -60,7 +59,6 @@ var/canmove = 1 var/eye_stat = null//Living, potentially Carbon var/lastpuke = 0 - var/unacidable = 0 var/name_archive //For admin things like possession @@ -113,7 +111,6 @@ //see: setup.dm for list of mutations var/voice_name = "unidentifiable voice" - var/say_message = null // When you are understood by others. Currently only used by aliens and monkeys in their say_quote procs var/list/faction = list("neutral") //A list of factions that this mob is currently in, for hostile mob targetting, amongst other things var/move_on_shuttle = 1 // Can move on the shuttle. @@ -137,23 +134,22 @@ mouse_drag_pointer = MOUSE_ACTIVE_POINTER - var/update_icon = 1 //Set to 1 to trigger update_icons() at the next life() call var/status_flags = CANSTUN|CANWEAKEN|CANPARALYSE|CANPUSH //bitflags defining which status effects can be inflicted (replaces canweaken, canstun, etc) var/area/lastarea = null var/digitalcamo = 0 // Can they be tracked by the AI? + var/weakeyes = 0 //Are they vulnerable to flashes? var/has_unlimited_silicon_privilege = 0 // Can they interact with station electronics - var/list/radar_blips = list() // list of screen objects, radar blips - var/radar_open = 0 // nonzero is radar is open - var/force_compose = 0 //If this is nonzero, the mob will always compose it's own hear message instead of using the one given in the arguments. var/obj/control_object //Used by admins to possess objects. All mobs should have this var var/atom/movable/remote_control //Calls relaymove() to whatever it is var/turf/listed_turf = null //the current turf being examined in the stat panel - var/last_movement = 0 // Last world.time the mob actually moved of its own accord. \ No newline at end of file + + var/list/permanent_huds = list() + var/permanent_sight_flags = 0 \ No newline at end of file diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 6db29529209..5b9be5c61c9 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -31,7 +31,7 @@ return 0 /proc/isslime(A) - if(istype(A, /mob/living/carbon/slime)) + if(istype(A, /mob/living/simple_animal/slime)) return 1 return 0 @@ -46,7 +46,7 @@ return 0 /proc/iscorgi(A) - if(istype(A, /mob/living/simple_animal/corgi)) + if(istype(A, /mob/living/simple_animal/pet/corgi)) return 1 return 0 @@ -56,7 +56,7 @@ return 0 /proc/iscat(A) - if(istype(A, /mob/living/simple_animal/cat)) + if(istype(A, /mob/living/simple_animal/pet/cat)) return 1 return 0 @@ -286,7 +286,7 @@ proc/Gibberish(t, p)//t is the inputted message, and any value higher than 70 fo return returntext -/proc/ninjaspeak(n) +/proc/ninjaspeak(n) //NINJACODE /* The difference with stutter is that this proc can stutter more than 1 letter The issue here is that anything that does not have a space is treated as one word (in many instances). For instance, "LOOKING," is a word, including the comma. diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 754753b239e..1d34da24490 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -200,7 +200,6 @@ step(mob, pick(cardinal)) else . = ..() - mob.last_movement=world.time moving = 0 if(mob && .) diff --git a/code/modules/mob/say_readme.dm b/code/modules/mob/say_readme.dm index f57b4249549..ddc9f2b148b 100644 --- a/code/modules/mob/say_readme.dm +++ b/code/modules/mob/say_readme.dm @@ -32,6 +32,15 @@ global procs get_hear(range, atom/source) Like view(), but ignores luminosity. + + message_spans_start(spans) + Turns each element of spans into a span class. + + message_spans_end(length) + Returns lenght times "" + + attach_spans(input, spans) + Attaches span classes around input. /atom/movable flags @@ -42,34 +51,41 @@ global procs Bitmask variable. What languages this object speaks/understands. If the languages of the speaker don't match the languages of the hearer, the message will be modified in the hearer's lang_treat(). + + verb_say/verb_ask/verb_exclaim/verb_yell + These determine what the verb is for their respective action. Used in say_quote(). say(message) Say() is the "mother-proc". It calls all the other procs required for speaking, but does little itself. At the atom/movable level, say() just calls send_speech. - Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq) + Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans) This proc handles hearing. What it does varies. For mobs, it treats the message with hearer-specific things like language and deafness, then outputs it to the hearer. IMPORTANT NOTE: If radio_freq is not null, the code will assume that the speaker is virtual! (more info on this in the Radios section below) - send_speech(message, range) + send_speech(message, range, source, bubble_type, spans) This proc composes a list of hearers (things with the HEAR flag + dead people) and calls Hear() on them. Message treatment or composition of output are not done by this proc, these are handled by the rest of say() and the hearer respectively. - lang_treat(message, atom/movable/speaker, message_langs, raw_message) + lang_treat(message, atom/movable/speaker, message_langs, raw_message, spans) Modifies the message by comparing the languages of the speaker with the languages of the hearer. Called on the hearer. - say_quote(text) - Adds a verb and quotes to a message, according to the type of mob. Called on the speaker. + say_quote(input, spans) + Adds a verb and quotes to a message. Also attaches span classes to a message. Verbs are determined by verb_say/verb_ask/verb_yell variables. Called on the speaker. + + get_spans(input, spans) + Returns the list of spans that are always applied to messages of this atom. + Always return ..() | + youroutput when overriding this proc! /mob say_dead(message) Sends a message to all dead people. Does not use Hear(). - compose_message(message, atom/movable/speaker, message_langs, raw_message, radio_freq) + compose_message(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans) Composes the message mobs see on their screen when they hear something. compose_track_href(message, atom/movable/speaker, message_langs, raw_message, radio_freq) @@ -118,7 +134,7 @@ global procs Please try to keep things in a logical order (e.g. don't have masks handled before mutations), even if that means you have to call ..() in the middle of the proc. - radio(message, message_mode) + radio(message, message_mode, spans) Handles talking into radios. Uses a switch to determine what radio to speak into and in which manner to do so. Return is a bitflag. diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 00cbe4f88c1..a261287a103 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -373,18 +373,18 @@ for(var/t in organs) qdel(t) - var/mob/living/carbon/slime/new_slime + var/mob/living/simple_animal/slime/new_slime if(reproduce) var/number = pick(14;2,3,4) //reproduce (has a small chance of producing 3 or 4 offspring) var/list/babies = list() for(var/i=1,i<=number,i++) - var/mob/living/carbon/slime/M = new/mob/living/carbon/slime(loc) + var/mob/living/simple_animal/slime/M = new/mob/living/simple_animal/slime(loc) M.nutrition = round(nutrition/number) step_away(M,src) babies += M new_slime = pick(babies) else - new_slime = new /mob/living/carbon/slime(loc) + new_slime = new /mob/living/simple_animal/slime(loc) new_slime.a_intent = "harm" new_slime.key = key @@ -420,7 +420,7 @@ for(var/t in organs) //this really should not be necessary qdel(t) - var/mob/living/simple_animal/corgi/new_corgi = new /mob/living/simple_animal/corgi (loc) + var/mob/living/simple_animal/pet/corgi/new_corgi = new /mob/living/simple_animal/pet/corgi (loc) new_corgi.a_intent = "harm" new_corgi.key = key @@ -494,9 +494,9 @@ return 0 //Verbs do not appear for players. //Good mobs! - if(ispath(MP, /mob/living/simple_animal/cat)) + if(ispath(MP, /mob/living/simple_animal/pet/cat)) return 1 - if(ispath(MP, /mob/living/simple_animal/corgi)) + if(ispath(MP, /mob/living/simple_animal/pet/corgi)) return 1 if(ispath(MP, /mob/living/simple_animal/crab)) return 1 diff --git a/code/modules/mob/update_icons.dm b/code/modules/mob/update_icons.dm index 28934e23b88..13ec3f05463 100644 --- a/code/modules/mob/update_icons.dm +++ b/code/modules/mob/update_icons.dm @@ -43,6 +43,9 @@ /mob/proc/update_inv_head() return +/mob/proc/update_hair() + return + /mob/proc/update_inv_gloves() return diff --git a/code/modules/ninja/Ninja_Readme.dm b/code/modules/ninja/Ninja_Readme.dm new file mode 100644 index 00000000000..2d383f9b1fa --- /dev/null +++ b/code/modules/ninja/Ninja_Readme.dm @@ -0,0 +1,10 @@ + +/* + +Removing Snowflake: +- Search for NINJACODE (one word, all caps) to find Space Ninja Code outside of the /modules/ninja folder. + +Ninja Folder: +- This folder contains 90% of Ninja code and will eventually contain it all, once snowflake is cleaned out + +*/ diff --git a/code/modules/ninja/__ninjaDefines.dm b/code/modules/ninja/__ninjaDefines.dm new file mode 100644 index 00000000000..a8dc65f9f13 --- /dev/null +++ b/code/modules/ninja/__ninjaDefines.dm @@ -0,0 +1,13 @@ + +/* + +Contents: +- Definitions, because the original Ninja code has so much magic. + +*/ + + +//ninjacost() specificCheck defines +#define N_STEALTH_CANCEL 1 +#define N_SMOKE_BOMB 2 +#define N_ADRENALINE 3 \ No newline at end of file diff --git a/code/modules/ninja/admin_ninja_verbs.dm b/code/modules/ninja/admin_ninja_verbs.dm new file mode 100644 index 00000000000..59baa2c48e9 --- /dev/null +++ b/code/modules/ninja/admin_ninja_verbs.dm @@ -0,0 +1,61 @@ + +/* + +Contents: +- Admin procs that make ninjas + +*/ + + +//ADMIN CREATE NINJA (From Player) +/client/proc/cmd_admin_ninjafy(var/mob/living/carbon/human/H in player_list) + set category = null + set name = "Make Space Ninja" + + if(!ticker) + alert("Wait until the game starts") + return + + if(!istype(H)) + return + + if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes") + return + + log_admin("[key_name(src)] turned [H.key] into a Space Ninja.") + H.mind = create_ninja_mind(H.key) + H.mind_initialize() + H.equip_space_ninja(1) + if(istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja)) + H.wear_suit:randomize_param() + spawn(0) + H.wear_suit:ninitialize(10,H) + + +//ADMIN CREATE NINJA (From Ghost) +/client/proc/send_space_ninja() + set category = "Fun" + set name = "Spawn Space Ninja" + set desc = "Spawns a space ninja for when you need a teenager with attitude." + set popup_menu = 0 + + if(!holder) + src << "Only administrators may use this command." + return + if(!ticker.mode) + alert("The game hasn't started yet!") + return + if(alert("Are you sure you want to send in a space ninja?",,"Yes","No")=="No") + return + + var/client/C = input("Pick character to spawn as the Space Ninja", "Key", "") as null|anything in clients + if(!C) + return + + var/datum/round_event/ninja/E = new /datum/round_event/ninja() + E.key=C.key + + message_admins("[key_name_admin(key)] has spawned [key_name_admin(C.key)] as a Space Ninja.") + log_admin("[key] used Spawn Space Ninja.") + + return \ No newline at end of file diff --git a/code/modules/ninja/energy_katana.dm b/code/modules/ninja/energy_katana.dm new file mode 100644 index 00000000000..0a398a7ba27 --- /dev/null +++ b/code/modules/ninja/energy_katana.dm @@ -0,0 +1,20 @@ + + +/obj/item/weapon/katana/energy + name = "energy katana" + desc = "a katana infused with a strong energy" + icon_state = "energy_katana" + item_state = "energy_katana" + force = 40 + throwforce = 20 + +/obj/item/weapon/katana/energy/afterattack(atom/target, mob/user, proximity_flag, click_parameters) + if(!user || !target) + return + + if(proximity_flag) + target.emag_act() + user.visible_message("[user] masterfully slices [target]!", "You masterfully slice [target]!") + playsound(user, "sparks", 50, 1) + playsound(user, 'sound/weapons/blade1.ogg', 50, 1) + diff --git a/code/modules/ninja/ninja_event.dm b/code/modules/ninja/ninja_event.dm new file mode 100644 index 00000000000..47251f6f556 --- /dev/null +++ b/code/modules/ninja/ninja_event.dm @@ -0,0 +1,214 @@ +//Note to future generations: I didn't write this god-awful code I just ported it to the event system and tried to make it less moon-speaky. +//Don't judge me D; ~Carn //Maximum judging occuring - Remie. + + +/* + +Contents: +- The Ninja "Random" Event +- Ninja creation code + +*/ + +/datum/round_event_control/ninja + name = "Space Ninja" + typepath = /datum/round_event/ninja + max_occurrences = 1 + earliest_start = 30000 // 1 hour + + +/datum/round_event/ninja + var/success_spawn = 0 + + var/helping_station + var/key + var/spawn_loc + + var/mob/living/carbon/human/Ninja + + +/datum/round_event/ninja/setup() + helping_station = rand(0,1) + + +/datum/round_event/ninja/kill() + if(!success_spawn && control) + control.occurrences-- + return ..() + + +/datum/round_event/ninja/start() + //selecting a spawn_loc + if(!spawn_loc) + var/list/spawn_locs = list() + for(var/obj/effect/landmark/L in landmarks_list) + if(isturf(L.loc)) + switch(L.name) + if("ninjaspawn","carpspawn") + spawn_locs += L.loc + if(!spawn_locs.len) + return kill() + spawn_loc = pick(spawn_locs) + if(!spawn_loc) + return kill() + + //selecting a candidate player + if(!key) + var/list/candidates = get_candidates(BE_NINJA) + if(!candidates.len) + return kill() + var/client/C = pick(candidates) + key = C.key + if(!key) + return kill() + + //Prepare ninja player mind + var/datum/mind/Mind = create_ninja_mind(key) + Mind.active = 1 + + //generate objectives - You'll generally get 6 objectives (Ninja is meant to be hardmode!) + var/list/possible_targets = list() + for(var/datum/mind/M in ticker.minds) + if(M.current && M.current.stat != DEAD) + if(istype(M.current,/mob/living/carbon/human)) + if(M.special_role) + possible_targets[M] = 0 //bad-guy + else if(M.assigned_role in command_positions) + possible_targets[M] = 1 //good-guy + + var/list/objectives = list(1,2,3,4) + while(Mind.objectives.len < 6) //still not enough objectives! + switch(pick_n_take(objectives)) + if(1) //research + var/datum/objective/download/O = new /datum/objective/download() + O.owner = Mind + O.gen_amount_goal() + Mind.objectives += O + + if(2) //steal + var/datum/objective/steal/special/O = new /datum/objective/steal/special() + O.owner = Mind + Mind.objectives += O + + if(3) //protect/kill + if(!possible_targets.len) continue + var/selected = rand(1,possible_targets.len) + var/datum/mind/M = possible_targets[selected] + var/is_bad_guy = possible_targets[M] + possible_targets.Cut(selected,selected+1) + + if(is_bad_guy ^ helping_station) //kill (good-ninja + bad-guy or bad-ninja + good-guy) + var/datum/objective/assassinate/O = new /datum/objective/assassinate() + O.owner = Mind + O.target = M + O.explanation_text = "Slay \the [M.current.real_name], the [M.assigned_role]." + Mind.objectives += O + else //protect + var/datum/objective/protect/O = new /datum/objective/protect() + O.owner = Mind + O.target = M + O.explanation_text = "Protect \the [M.current.real_name], the [M.assigned_role], from harm." + Mind.objectives += O + if(4) //debrain/capture + if(!possible_targets.len) continue + var/selected = rand(1,possible_targets.len) + var/datum/mind/M = possible_targets[selected] + var/is_bad_guy = possible_targets[M] + possible_targets.Cut(selected,selected+1) + + if(is_bad_guy ^ helping_station) //debrain (good-ninja + bad-guy or bad-ninja + good-guy) + var/datum/objective/debrain/O = new /datum/objective/debrain() + O.owner = Mind + O.target = M + O.explanation_text = "Steal the brain of [M.current.real_name]." + Mind.objectives += O + else //capture + var/datum/objective/capture/O = new /datum/objective/capture() + O.owner = Mind + O.gen_amount_goal() + Mind.objectives += O + else + break + + //Add a survival objective since it's usually broad enough for any round type. + var/datum/objective/O = new /datum/objective/survive() + O.owner = Mind + Mind.objectives += O + + //add some RP-fluff + Mind.store_memory("I am an elite mercenary assassin of the mighty Spider Clan. A SPACE NINJA!") + Mind.store_memory("Suprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by right clicking on it, to use abilities like stealth)!") + Mind.store_memory("Officially, [helping_station?"Nanotrasen":"The Syndicate"] are my employer.") + + //spawn the ninja and assign the candidate + Ninja = create_space_ninja(spawn_loc) + Mind.transfer_to(Ninja) + + //initialise equipment + if(istype(Ninja.wear_suit,/obj/item/clothing/suit/space/space_ninja)) + //Should be true but we have to check these things. + var/obj/item/clothing/suit/space/space_ninja/N = Ninja.wear_suit + N.randomize_param() + + Ninja.internal = Ninja.s_store + if(Ninja.internals) + Ninja.internals.icon_state = "internal1" + + if(Ninja.mind != Mind) //something has gone wrong! + ERROR("The ninja wasn't assigned the right mind. ;ç;") + + Ninja << sound('sound/effects/ninja_greeting.ogg') //so ninja you probably wouldn't even know if you were made one + + success_spawn = 1 + + +//=======//NINJA CREATION PROCS//=======// + +/proc/create_space_ninja(spawn_loc) + var/mob/living/carbon/human/new_ninja = new(spawn_loc) + if(prob(50)) new_ninja.gender = "female" + var/datum/preferences/A = new()//Randomize appearance for the ninja. + A.real_name = "[pick(ninja_titles)] [pick(ninja_names)]" + A.copy_to(new_ninja) + ready_dna(new_ninja) + new_ninja.equip_space_ninja() + return new_ninja + + +proc/create_ninja_mind(key) + var/datum/mind/Mind = new /datum/mind(key) + Mind.assigned_role = "MODE" + Mind.special_role = "Space Ninja" + ticker.mode.traitors |= Mind //Adds them to current traitor list. Which is really the extra antagonist list. + return Mind + + +/mob/living/carbon/human/proc/equip_space_ninja(safety=0)//Safety in case you need to unequip stuff for existing characters. + if(safety) + qdel(w_uniform) + qdel(wear_suit) + qdel(wear_mask) + qdel(head) + qdel(shoes) + qdel(gloves) + + var/obj/item/device/radio/R = new /obj/item/device/radio/headset(src) + equip_to_slot_or_del(R, slot_ears) + equip_to_slot_or_del(new /obj/item/clothing/under/color/black(src), slot_w_uniform) + equip_to_slot_or_del(new /obj/item/clothing/shoes/space_ninja(src), slot_shoes) + equip_to_slot_or_del(new /obj/item/clothing/suit/space/space_ninja(src), slot_wear_suit) + equip_to_slot_or_del(new /obj/item/clothing/gloves/space_ninja(src), slot_gloves) + equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/space_ninja(src), slot_head) + equip_to_slot_or_del(new /obj/item/clothing/mask/gas/voice/space_ninja(src), slot_wear_mask) + equip_to_slot_or_del(new /obj/item/clothing/glasses/night(src), slot_glasses) + equip_to_slot_or_del(new /obj/item/weapon/katana/energy(src), slot_belt) + equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_r_store) + equip_to_slot_or_del(new /obj/item/weapon/c4(src), slot_l_store) + equip_to_slot_or_del(new /obj/item/weapon/tank/internals/emergency_oxygen(src), slot_s_store) + equip_to_slot_or_del(new /obj/item/weapon/tank/jetpack/carbondioxide(src), slot_back) + + var/obj/item/weapon/implant/explosive/E = new/obj/item/weapon/implant/explosive(src) + E.imp_in = src + E.implanted = 1 + E.implanted(src) + return 1 diff --git a/code/modules/ninja/suit/SpiderOS.dm b/code/modules/ninja/suit/SpiderOS.dm new file mode 100644 index 00000000000..f73a6cbc3d0 --- /dev/null +++ b/code/modules/ninja/suit/SpiderOS.dm @@ -0,0 +1,277 @@ + + +//HERE BE A VERY LARGE DRAGON + +/obj/item/clothing/suit/space/space_ninja/proc/spideros() + set name = "Display SpiderOS" + set desc = "Utilize built-in computer system." + set category = "Ninja Equip" + + if(!s_busy) + display_spideros() + else + affecting << "The interface is locked!" + + +/obj/item/clothing/suit/space/space_ninja/proc/display_spideros() + if(!affecting) return//If no mob is wearing the suit. I almost forgot about this variable. + var/mob/living/carbon/human/U = affecting + var/display_to = U//Who do we want to display certain messages to? + + var/dat = "SpiderOS" + dat += " Refresh" + if(spideros) + dat += " | Return" + dat += " | Close" + dat += "
    " + dat += "

    SpiderOS v.1.337

    " + dat += "Welcome, [U.real_name].
    " + dat += "
    " + dat += " Current Time: [worldtime2text()]
    " + dat += " Battery Life: [round(cell.charge/100)]%
    " + dat += " Smoke Bombs: \Roman [s_bombs]
    " + dat += "

    " + + switch(spideros) + if(0) + dat += "

    Available Functions:

    " + dat += "" + if(3) + dat += "

    Medical Report:

    " + if(U.dna) + dat += "Fingerprints: [md5(U.dna.uni_identity)]
    " + dat += "Unique identity: [U.dna.unique_enzymes]
    " + dat += "

    Overall Status: [U.stat > 1 ? "dead" : "[U.health]% healthy"]

    " + dat += "

    Nutrition Status: [U.nutrition]

    " + dat += "Oxygen loss: [U.getOxyLoss()]" + dat += " | Toxin levels: [U.getToxLoss()]
    " + dat += "Burn severity: [U.getFireLoss()]" + dat += " | Brute trauma: [U.getBruteLoss()]
    " + dat += "Radiation Level: [U.radiation] rad
    " + dat += "Body Temperature: [U.bodytemperature-T0C]°C ([U.bodytemperature*1.8-459.67]°F)
    " + + for(var/datum/disease/D in U.viruses) + dat += "Warning: Virus Detected. Name: [D.name].Type: [D.spread_text]. Stage: [D.stage]/[D.max_stages]. Possible Cure: [D.cure_text].
    " + dat += "" + if(1) + dat += "

    Atmospheric Scan:

    "//Headers don't need breaks. They are automatically placed. + var/turf/T = get_turf(U.loc) + if (isnull(T)) + dat += "Unable to obtain a reading." + else + var/datum/gas_mixture/environment = T.return_air() + + var/pressure = environment.return_pressure() + var/total_moles = environment.total_moles() + + dat += "Air Pressure: [round(pressure,0.1)] kPa" + + if (total_moles) + var/o2_level = environment.oxygen/total_moles + var/n2_level = environment.nitrogen/total_moles + var/co2_level = environment.carbon_dioxide/total_moles + var/plasma_level = environment.toxins/total_moles + var/unknown_level = 1-(o2_level+n2_level+co2_level+plasma_level) + dat += "
      " + dat += "
    • Nitrogen: [round(n2_level*100)]%
    • " + dat += "
    • Oxygen: [round(o2_level*100)]%
    • " + dat += "
    • Carbon Dioxide: [round(co2_level*100)]%
    • " + dat += "
    • Plasma: [round(plasma_level*100)]%
    • " + dat += "
    " + if(unknown_level > 0.01) + dat += "OTHER: [round(unknown_level)]%
    " + + dat += "Temperature: [round(environment.temperature-T0C)]°C" + if(2) + dat += "

    Anonymous Messenger:

    "//Anonymous because the receiver will not know the sender's identity. + dat += "

    Detected PDAs:

    " + dat += "
      " + var/count = 0 + for (var/obj/item/device/pda/P in get_viewable_pdas()) + dat += "
    • [P]" + dat += "
    • " + count++ + dat += "
    " + if (count == 0) + dat += "None detected.
    " + if(4) + dat += {" +

    Ninja Manual:

    +
    Who they are:
    + Space ninjas are a special type of ninja, specifically one of the space-faring type. The vast majority of space ninjas belong to the Spider Clan, a cult-like sect, which has existed for several hundred years. The Spider Clan practice a sort of augmentation of human flesh in order to achieve a more perfect state of being and follow Postmodern Space Bushido. They also kill people for money. Their leaders are chosen from the oldest of the grand-masters, people that have lived a lot longer than any mortal man should.
    Being a sect of technology-loving fanatics, the Spider Clan have the very best to choose from in terms of hardware--cybernetic implants, exoskeleton rigs, hyper-capacity batteries, and you get the idea. Some believe that much of the Spider Clan equipment is based on reverse-engineered alien technology while others doubt such claims.
    Whatever the case, their technology is absolutely superb. +
    How they relate to other SS13 organizations:
    +
      +
    • *Nanotrasen and the Syndicate are two sides of the same coin and that coin is valuable.
    • +
    • *The Space Wizard Federation is a problem, mainly because they are an extremely dangerous group of unpredictable individuals--not to mention the wizards hate technology and are in direct opposition of the Spider Clan. Best avoided or left well-enough alone. How to battle: wizards possess several powerful abilities to steer clear off. Blind in particular is a nasty spell--jaunt away if you are blinded and never approach a wizard in melee. Stealth may also work if the wizard is not wearing thermal scanners--don't count on this. Run away if you feel threatened and await a better opportunity.
    • +
    • *Changeling Hivemind: extremely dangerous and to be killed on sight. How to battle: they will likely try to absorb you. Adrenaline boost, then phase shift into them. If you get stung, use SpiderOS to inject counter-agents. Stealth may also work but detecting a changeling is the real battle.
    • +
    • *Xeno Hivemind: their skulls make interesting kitchen decorations and are challenging to best, especially in larger nests. How to battle: they can see through your stealth guise and energy stars will not work on them. Best killed with a Phase Shift or at range. If you happen on a projectile stun weapon, use it and then close in to melee.
    • +
    +
    The reason they (you) are here:
    + Space ninjas are renowned throughout the known controlled space as fearless spies, infiltrators, and assassins. They are sent on missions of varying nature by Nanotrasen, the Syndicate, and other shady organizations and people. To hire a space ninja means serious business. +
    Their playstyle:
    + A mix of traitor, changeling, and wizard. Ninjas rely on energy, or electricity to be precise, to keep their suits running (when out of energy, a suit hibernates). Suits gain energy from objects or creatures that contain electrical charge. APCs, cell batteries, rechargers, SMES batteries, cyborgs, mechs, and exposed wires are currently supported. Through energy ninjas gain access to special powers--while all powers are tied to the ninja suit, the most useful of them are verb activated--to help them in their mission.
    It is a constant struggle for a ninja to remain hidden long enough to recharge the suit and accomplish their objective; despite their arsenal of abilities, ninjas can die like any other. Unlike wizards, ninjas do not possess good crowd control and are typically forced to play more subdued in order to achieve their goals. Some of their abilities are specifically designed to confuse and disorient others.
    With that said, it should be perfectly possible to completely flip the fuck out and rampage as a ninja. +
    Their powers:
    + There are two primary types: Equipment and Abilties. Passive effect are always on. Active effect must be turned on and remain active only when there is energy to do so. Ability costs are listed next to them. + Equipment: cannot be tracked by AI (passive), faster speed (passive), stealth (active), vision switch (passive if toggled), voice masking (passive), SpiderOS (passive if toggled), energy drain (passive if toggled). +
      +
    • Voice masking generates a random name the ninja can use over the radio and in-person. Although, the former use is recommended.
    • +
    • Toggling vision cycles to one of the following: thermal, meson, or darkness vision. The starting mode allows one to scout the identity of those in view, revealing their role. Traitors, revolutionaries, wizards, and other such people will be made known to you.
    • +
    • Stealth, when activated, drains more battery charge and works similarly to a syndicate cloak. The cloak will deactivate when most Abilities are utilized.
    • +
    • On-board AI: The suit is able to download an AI much like an intellicard. Check with SpiderOS for details once downloaded.
    • +
    • SpiderOS is a specialized, PDA-like screen that allows for a small variety of functions, such as injecting healing chemicals directly from the suit. You are using it now, if that was not already obvious. You may also download AI modules directly to the OS.
    • +
    + Abilities: +
      +
    • *Phase Shift (2000E) and Phase Jaunt (1000E) are unique powers in that they can both be used for defense and offense. Jaunt launches the ninja forward facing up to 9 squares, somewhat randomly selecting the final destination. Shift can only be used on turf in view but is precise (cannot be used on walls). Any living mob in the area teleported to is instantly gibbed (mechs are damaged, huggers and other similar critters are killed). It is possible to teleport with a target, provided you grab them before teleporting.
    • +
    • *Energy Blade (500E) is a highly effective weapon. It is summoned directly to the ninja's hand and can also function as an EMAG for certain objects (doors/lockers/etc). You may also use it to cut through walls and disabled doors. Experiment! The blade will crit humans in two hits. This item cannot be placed in containers and when dropped or thrown disappears. Having an energy blade drains more power from the battery each tick.
    • +
    • *EM Pulse (2500E) is a highly useful ability that will create an electromagnetic shockwave around the ninja, disabling technology whenever possible. If used properly it can render a security force effectively useless. Of course, getting beat up with a toolbox is not accounted for.
    • +
    • *Energy Star (500E) is a ninja star made of green energy AND coated in poison. It works by picking a random living target within range and can be spammed to great effect in incapacitating foes. Just remember that the poison used is also used by the Xeno Hivemind (and will have no effect on them).
    • +
    • *Energy Net (2000E) is a non-lethal solution to incapacitating humanoids. The net is made of non-harmful phase energy and will halt movement as long as it remains in effect--it can be destroyed. If the net is not destroyed, after a certain time it will teleport the target to a holding facility for the Spider Clan and then vanish. You will be notified if the net fails or succeeds in capturing a target in this manner. Combine with energy stars or stripping to ensure success. Abduction never looked this leet.
    • +
    • *Adrenaline Boost (1 E. Boost/3) recovers the user from stun, weakness, and paralysis. Also injects 20 units of radium into the bloodstream.
    • +
    • *Smoke Bomb (1 Sm.Bomb/10) is a weak but potentially useful ability. It creates harmful smoke and can be used in tandem with other powers to confuse enemies.
    • +
    • *???: unleash the True Ultimate Power!
    • +

      IMPORTANT:

      +
        +
      • *Make sure to toggle Special Interaction from the Ninja Equipment menu to interact differently with certain objects.
      • +
      • *Your starting power cell can be replaced if you find one with higher maximum energy capacity by clicking on your suit with the higher capacity cell.
      • +
      • *Conserve your energy. Without it, you are very vulnerable.
      • +
      + That is all you will need to know. The rest will come with practice and talent. Good luck! +

      Master /N

      + "} + if(6) + dat += {" +

      Activate Abilities:

      + + "} + if(7) + dat += "

      Research Stored:

      " + if(t_disk) + dat += "Eject Disk
      " + dat += "
        " + if(istype(stored_research,/list))//If there is stored research. Should be but just in case. + for(var/datum/tech/current_data in stored_research) + dat += "
      • " + dat += "[current_data.name]: [current_data.level]" + if(t_disk)//If there is a disk inserted. We can either write or overwrite. + dat += " *Copy to Disk
        " + dat += "
      • " + dat += "
      " + dat += "" + + //Setting the can>resize etc to 0 remove them from the drag bar but still allows the window to be draggable. + display_to << browse(dat,"window=spideros;size=400x444;border=1;can_resize=1;can_close=0;can_minimize=0") + +//=======//SPIDEROS TOPIC PROC//=======// + +/obj/item/clothing/suit/space/space_ninja/Topic(href, href_list) + ..() + var/mob/living/carbon/human/U = affecting + var/display_to = U + + + if(!affecting||U.stat||!s_initialized)//Check to make sure the guy is wearing the suit after clicking and it's on. + U << "Your suit must be worn and active to use this function." + U << browse(null, "window=spideros")//Closes the window. + return + + switch(href_list["choice"]) + if("Close") + display_to << browse(null, "window=spideros") + return + if("Refresh")//Refresh, goes to the end of the proc. + if("Return")//Return + if(spideros<=9) + spideros=0 + else + spideros = round(spideros/10)//Best way to do this, flooring to nearest integer. + + if("Message") + var/obj/item/device/pda/P = locate(href_list["target"]) + var/t = input(U, "Please enter untraceable message.") as text + t = copytext(sanitize(t), 1, MAX_MESSAGE_LEN) + if(!t||U.stat||U.wear_suit!=src||!s_initialized)//Wow, another one of these. Man... + display_to << browse(null, "window=spideros") + return + if(isnull(P)||P.toff)//So it doesn't freak out if the object no-longer exists. + display_to << "Error: unable to deliver message." + display_spideros() + return + P.tnote += "← From an unknown source:
      [t]
      " + if (!P.silent) + playsound(P.loc, 'sound/machines/twobeep.ogg', 50, 1) + P.audible_message("\icon[P] *[P.ttone]*", null, 3) + P.overlays.Cut() + P.overlays += image('icons/obj/pda.dmi', "pda-r") + + if("Inject") + if( (href_list["tag"]=="radium"? (reagents.get_reagent_amount("radium"))<=(a_boost*a_transfer) : !reagents.get_reagent_amount(href_list["tag"])) )//Special case for radium. If there are only a_boost*a_transfer radium units left. + display_to << "Error: the suit cannot perform this function. Out of [href_list["name"]]." + else + reagents.reaction(U, 2) + reagents.trans_id_to(U, href_list["tag"], href_list["tag"]=="nutriment"?5:a_transfer)//Nutriment is a special case since it's very potent. Shouldn't influence actual refill amounts or anything. + display_to << "Injecting..." + U << "You feel a tiny prick and a sudden rush of substance in to your veins." + + if("Trigger Ability") + var/ability_name = href_list["name"]+href_list["cost"]//Adds the name and cost to create the full proc name. + var/proc_arguments//What arguments to later pass to the proc, if any. + var/list/targets = list()//To later check for. + var/safety = 0//To later make sure we're triggering the proc when needed. + switch(href_list["name"])//Special case. + if("Phase Shift") + safety = 1 + for(var/turf/T in oview(5,loc)) + targets.Add(T) + if("Energy Net") + safety = 1 + for(var/mob/living/carbon/M in oview(5,loc)) + targets.Add(M) + if(targets.len)//Let's create an argument for the proc if needed. + proc_arguments = pick(targets) + safety = 0 + if(!safety) + U << "[href_list["name"]] suddenly triggered!" + call(src,ability_name)(proc_arguments) + + if("Eject Disk") + var/turf/T = get_turf(loc) + if(!U.get_active_hand()) + U.put_in_hands(t_disk) + t_disk.add_fingerprint(U) + t_disk = null + else + if(T) + t_disk.loc = T + t_disk = null + else + U << "ERROR: Could not eject disk." + + if("Copy to Disk") + var/datum/tech/current_data = locate(href_list["target"]) + U << "[current_data.name] successfully [(!t_disk.stored) ? "copied" : "overwritten"] to disk." + t_disk.stored = current_data + + + display_spideros()//Refreshes the screen by calling it again (which replaces current screen with new screen). + return diff --git a/code/modules/ninja/suit/gloves.dm b/code/modules/ninja/suit/gloves.dm new file mode 100644 index 00000000000..3f23ac333e2 --- /dev/null +++ b/code/modules/ninja/suit/gloves.dm @@ -0,0 +1,343 @@ + + + +/* + Dear ninja gloves + + This isn't because I like you + this is because your father is a bastard + + ... + I guess you're a little cool. + -Sayu +*/ + +/obj/item/clothing/gloves/space_ninja + desc = "These nano-enhanced gloves insulate from electricity and provide fire resistance." + name = "ninja gloves" + icon_state = "s-ninja" + item_state = "s-ninja" + siemens_coefficient = 0 + cold_protection = HANDS + min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT + heat_protection = HANDS + max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT + strip_delay = 120 + var/draining = 0 + var/candrain = 0 + var/mindrain = 200 + var/maxdrain = 400 + +/* + This runs the gamut of what ninja gloves can do + The other option would be a dedicated ninja touch bullshit proc on everything + which would probably more efficient, but ninjas are pretty rare. + This was mostly introduced to keep ninja code from contaminating other code; + with this in place it would be easier to untangle the rest of it. + + For the drain proc, see events/ninja.dm +*/ +/obj/item/clothing/gloves/space_ninja/Touch(var/atom/A,var/proximity) + if(!candrain || draining) + return 0 + var/mob/living/carbon/human/H = loc + if(!istype(H)) + return 0 // what + var/obj/item/clothing/suit/space/space_ninja/suit = H.wear_suit + if(!istype(suit)) + return 0 + if(isturf(A)) + return 0 + + if(!proximity) // todo: you could add ninja stars or computer hacking here + return 0 + + A.add_fingerprint(H) + + // steal energy from powered things + if(istype(A,/mob/living/silicon/robot)) + drain("CYBORG",A,suit) + return 1 + + if(istype(A, /obj/item/weapon/stock_parts/cell)) + drain("CELL", A,suit) + return 1 + + if(istype(A,/obj/machinery/power/apc)) + drain("APC",A,suit) + return 1 + + if(istype(A,/obj/structure/cable)) + drain("WIRE",A,suit) + return 1 + + if(istype(A,/obj/structure/grille)) + var/obj/structure/cable/C = locate() in A.loc + if(C) + drain("WIRE",C,suit) + return 1 + + if(istype(A,/obj/machinery/power/smes)) + drain("SMES",A,suit) + return 1 + + if(istype(A,/obj/mecha)) + drain("MECHA",A,suit) + return 1 + + if(istype(A,/obj/machinery/computer/rdconsole)) // download research + drain("RESEARCH",A,suit) + return 1 + + if(istype(A,/obj/machinery/r_n_d/server)) + A.add_fingerprint(H) + var/obj/machinery/r_n_d/server/S = A + if(S.disabled) + return 1 + if(S.shocked) + S.shock(H,50) + return 1 + drain("RESEARCH",A,suit) + return 1 + + +/obj/item/clothing/gloves/space_ninja/proc/drain(target_type as text, target, obj/suit) + //Var Initialize + var/obj/item/clothing/suit/space/space_ninja/S = suit + var/mob/living/carbon/human/U = S.affecting + var/obj/item/clothing/gloves/space_ninja/G = S.n_gloves + + var/drain = 0//To drain from battery. + var/maxcapacity = 0//Safety check for full battery. + var/totaldrain = 0//Total energy drained. + + G.draining = 1 + + if(target_type!="RESEARCH")//I lumped research downloading here for ease of use. + U << "Now charging battery..." + + switch(target_type) + + if("APC") + var/obj/machinery/power/apc/A = target + if(A.cell&&A.cell.charge) + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, A.loc) + while(G.candrain&&A.cell.charge>0&&!maxcapacity) + drain = rand(G.mindrain,G.maxdrain) + if(A.cell.chargeS.cell.maxcharge) + drain = S.cell.maxcharge-S.cell.charge + maxcapacity = 1//Reached maximum battery capacity. + if (do_after(U,10)) + spark_system.start() + playsound(A.loc, "sparks", 50, 1) + A.cell.charge-=drain + S.cell.charge+=drain + totaldrain+=drain + else break + U << "Gained [totaldrain] energy from the APC." + if(!A.emagged) + flick("apc-spark", src) + A.emagged = 1 + A.locked = 0 + A.update_icon() + else + U << "This APC has run dry of power. You must find another source." + + if("SMES") + var/obj/machinery/power/smes/A = target + if(A.charge) + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, A.loc) + while(G.candrain&&A.charge>0&&!maxcapacity) + drain = rand(G.mindrain,G.maxdrain) + if(A.chargeS.cell.maxcharge) + drain = S.cell.maxcharge-S.cell.charge + maxcapacity = 1 + if (do_after(U,10)) + spark_system.start() + playsound(A.loc, "sparks", 50, 1) + A.charge-=drain + S.cell.charge+=drain + totaldrain+=drain + else break + U << "Gained [totaldrain] energy from the SMES cell." + else + U << "This SMES cell has run dry of power. You must find another source." + + if("CELL") + var/obj/item/weapon/stock_parts/cell/A = target + if(A.charge) + if (G.candrain&&do_after(U,30)) + U << "Gained [A.charge] energy from the cell." + if(S.cell.charge+A.charge>S.cell.maxcharge) + S.cell.charge=S.cell.maxcharge + else + S.cell.charge+=A.charge + A.charge = 0 + G.draining = 0 + A.corrupt() + A.updateicon() + else + U << "Procedure interrupted. Protocol terminated." + else + U << "This cell is empty and of no use." + + if("MACHINERY")//Can be applied to generically to all powered machinery. I'm leaving this alone for now. + var/obj/machinery/A = target + if(A.powered())//If powered. + + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, A.loc) + + var/area/A_Area = get_area(A) + var/obj/machinery/power/apc/B = A_Area.get_apc() //find APC + if(B)//If APC exists. Might not if the area is unpowered like Centcom. + var/datum/powernet/PN = B.terminal.powernet + while(G.candrain&&!maxcapacity&&!isnull(A))//And start a proc similar to drain from wire. + drain = rand(G.mindrain,G.maxdrain) + var/drained = 0 + if(PN&&do_after(U,10)) + drained = min(drain, PN.avail) + PN.load += drained + if(drained < drain)//if no power on net, drain apcs + for(var/obj/machinery/power/terminal/T in PN.nodes) + if(istype(T.master, /obj/machinery/power/apc)) + var/obj/machinery/power/apc/AP = T.master + if(AP.operating && AP.cell && AP.cell.charge>0) + AP.cell.charge = max(0, AP.cell.charge - 5) + drained += 5 + else break + S.cell.charge += drained + if(S.cell.charge>S.cell.maxcharge) + totaldrain += (drained-(S.cell.charge-S.cell.maxcharge)) + S.cell.charge = S.cell.maxcharge + maxcapacity = 1 + else + totaldrain += drained + spark_system.start() + if(drained==0) break + U << "Gained [totaldrain] energy from the power network." + else + U << "Power network could not be found. Aborting." + else + U << "This recharger is not providing energy. You must find another source." + + if("RESEARCH") + var/obj/machinery/A = target + U << "Hacking \the [A]..." + spawn(0) + var/turf/location = get_turf(U) + for(var/mob/living/silicon/ai/AI in player_list) + AI << "Network Alert: Hacking attempt detected[location?" in [location]":". Unable to pinpoint location"]." + if(A:files&&A:files.known_tech.len) + for(var/datum/tech/current_data in S.stored_research) + U << "Checking \the [current_data.name] database." + if(do_after(U, S.s_delay)&&G.candrain&&!isnull(A)) + for(var/datum/tech/analyzing_data in A:files.known_tech) + if(current_data.id==analyzing_data.id) + if(analyzing_data.level>current_data.level) + U << "Database: UPDATED." + current_data.level = analyzing_data.level + break//Move on to next. + else break//Otherwise, quit processing. + U << "Data analyzed. Process finished." + + if("WIRE") + var/obj/structure/cable/A = target + var/datum/powernet/PN = A.powernet + while(G.candrain&&!maxcapacity&&!isnull(A)) + drain = (round((rand(G.mindrain,G.maxdrain))/2)) + var/drained = 0 + if(PN&&do_after(U,10)) + drained = min(drain, PN.avail) + PN.load += drained + if(drained < drain)//if no power on net, drain apcs + for(var/obj/machinery/power/terminal/T in PN.nodes) + if(istype(T.master, /obj/machinery/power/apc)) + var/obj/machinery/power/apc/AP = T.master + if(AP.operating && AP.cell && AP.cell.charge>0) + AP.cell.charge = max(0, AP.cell.charge - 5) + drained += 5 + else break + S.cell.charge += drained + if(S.cell.charge>S.cell.maxcharge) + totaldrain += (drained-(S.cell.charge-S.cell.maxcharge)) + S.cell.charge = S.cell.maxcharge + maxcapacity = 1 + else + totaldrain += drained + S.spark_system.start() + if(drained==0) break + U << "Gained [totaldrain] energy from the power network." + + if("MECHA") + var/obj/mecha/A = target + A.occupant_message("Warning: Unauthorized access through sub-route 4, block H, detected.") + if(A.get_charge()) + while(G.candrain&&A.cell.charge>0&&!maxcapacity) + drain = rand(G.mindrain,G.maxdrain) + if(A.cell.chargeS.cell.maxcharge) + drain = S.cell.maxcharge-S.cell.charge + maxcapacity = 1 + if (do_after(U,10)) + A.spark_system.start() + playsound(A.loc, "sparks", 50, 1) + A.cell.use(drain) + S.cell.charge+=drain + totaldrain+=drain + else break + U << "Gained [totaldrain] energy from [src]." + else + U << "The exosuit's battery has run dry. You must find another source of power." + + if("CYBORG") + var/mob/living/silicon/robot/A = target + A << "Warning: Unauthorized access through sub-route 12, block C, detected." + G.draining = 1 + if(A.cell&&A.cell.charge) + while(G.candrain&&A.cell.charge>0&&!maxcapacity) + drain = rand(G.mindrain,G.maxdrain) + if(A.cell.chargeS.cell.maxcharge) + drain = S.cell.maxcharge-S.cell.charge + maxcapacity = 1 + if (do_after(U,10)) + A.spark_system.start() + playsound(A.loc, "sparks", 50, 1) + A.cell.charge-=drain + S.cell.charge+=drain + totaldrain+=drain + else break + U << "Gained [totaldrain] energy from [A]." + else + U << "Their battery has run dry of power. You must find another source." + + else//Else nothing :< + + G.draining = 0 + + return + + +/obj/item/clothing/gloves/space_ninja/proc/toggled() + set name = "Toggle Interaction" + set desc = "Toggles special interaction on or off." + set category = "Ninja Equip" + + var/mob/living/carbon/human/U = loc + U << "You [candrain?"disable":"enable"] special interaction." + candrain=!candrain + + +/obj/item/clothing/gloves/space_ninja/examine(mob/user) + ..() + if(flags & NODROP) + user << "The energy drain mechanism is: [candrain?"active":"inactive"]." diff --git a/code/modules/ninja/suit/head.dm b/code/modules/ninja/suit/head.dm new file mode 100644 index 00000000000..5707a1bd809 --- /dev/null +++ b/code/modules/ninja/suit/head.dm @@ -0,0 +1,11 @@ + + +/obj/item/clothing/head/helmet/space/space_ninja + desc = "What may appear to be a simple black garment is in fact a highly sophisticated nano-weave helmet. Standard issue ninja gear." + name = "ninja hood" + icon_state = "s-ninja" + item_state = "s-ninja_mask" + armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 25) + strip_delay = 12 + unacidable = 1 + blockTracking = 1//Roughly the only unique thing about this helmet. \ No newline at end of file diff --git a/code/modules/ninja/suit/mask.dm b/code/modules/ninja/suit/mask.dm new file mode 100644 index 00000000000..cd8a2ba822d --- /dev/null +++ b/code/modules/ninja/suit/mask.dm @@ -0,0 +1,137 @@ + +/* + +Contents: +- The Ninja Space Mask +- Ninja Space Mask speech modification + +*/ + + + + +/obj/item/clothing/mask/gas/voice/space_ninja + name = "ninja mask" + desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement." + icon_state = "s-ninja" + item_state = "s-ninja_mask" + vchange = 1 + strip_delay = 120 + +/obj/item/clothing/mask/gas/voice/space_ninja/speechModification(message) + if(voice == "Unknown") + if(copytext(message, 1, 2) != "*") + var/list/temp_message = text2list(message, " ") + var/list/pick_list = list() + for(var/i = 1, i <= temp_message.len, i++) + pick_list += i + for(var/i=1, i <= abs(temp_message.len/3), i++) + var/H = pick(pick_list) + if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue + temp_message[H] = ninjaspeak(temp_message[H]) + pick_list -= H + message = list2text(temp_message, " ") + + //The Alternate speech mod is now the main one. + message = replacetext(message, "l", "r") + message = replacetext(message, "rr", "ru") + message = replacetext(message, "v", "b") + message = replacetext(message, "f", "hu") + message = replacetext(message, "'t", "") + message = replacetext(message, "t ", "to ") + message = replacetext(message, " I ", " ai ") + message = replacetext(message, "th", "z") + message = replacetext(message, "is", "izu") + message = replacetext(message, "ziz", "zis") + message = replacetext(message, "se", "su") + message = replacetext(message, "br", "bur") + message = replacetext(message, "ry", "ri") + message = replacetext(message, "you", "yuu") + message = replacetext(message, "ck", "cku") + message = replacetext(message, "eu", "uu") + message = replacetext(message, "ow", "au") + message = replacetext(message, "are", "aa") + message = replacetext(message, "ay", "ayu") + message = replacetext(message, "ea", "ii") + message = replacetext(message, "ch", "chi") + message = replacetext(message, "than", "sen") + message = replacetext(message, ".", "") + message = lowertext(message) + + return message + + + +/obj/item/clothing/mask/gas/voice/space_ninja/New() + verbs += /obj/item/clothing/mask/gas/voice/space_ninja/proc/togglev + + +//This proc is linked to human life.dm. It determines what hud icons to display based on mind special role for most mobs. +/obj/item/clothing/mask/gas/voice/space_ninja/proc/assess_targets(list/target_list, mob/living/carbon/U) + var/icon/tempHud = 'icons/mob/hud.dmi' + for(var/mob/living/target in target_list) + if(iscarbon(target)) + switch(target.mind.special_role) + if("traitor") + U.client.images += image(tempHud,target,"hudtraitor") + if("Revolutionary","Head Revolutionary") + U.client.images += image(tempHud,target,"hudrevolutionary") + if("Cultist") + U.client.images += image(tempHud,target,"hudcultist") + if("Changeling") + U.client.images += image(tempHud,target,"hudchangeling") + if("Wizard","Fake Wizard") + U.client.images += image(tempHud,target,"hudwizard") + if("Hunter","Sentinel","Drone","Queen") + U.client.images += image(tempHud,target,"hudalien") + if("Syndicate") + U.client.images += image(tempHud,target,"hudoperative") + if("Death Commando") + U.client.images += image(tempHud,target,"huddeathsquad") + if("Space Ninja") + U.client.images += image(tempHud,target,"hudninja") + else//If we don't know what role they have but they have one. + U.client.images += image(tempHud,target,"hudunknown1") + else if(issilicon(target))//If the silicon mob has no law datum, no inherent laws, or a law zero, add them to the hud. + var/mob/living/silicon/silicon_target = target + if(!silicon_target.laws||(silicon_target.laws&&(silicon_target.laws.zeroth||!silicon_target.laws.inherent.len))) + if(isrobot(silicon_target))//Different icons for robutts and AI. + U.client.images += image(tempHud,silicon_target,"hudmalborg") + else + U.client.images += image(tempHud,silicon_target,"hudmalai") + return 1 + + +/obj/item/clothing/mask/gas/voice/space_ninja/proc/togglev() + set name = "Toggle Voice" + set desc = "Toggles the voice synthesizer on or off." + set category = "Ninja Equip" + + var/mob/U = loc//Can't toggle voice when you're not wearing the mask. + var/vchange = (alert("Would you like to synthesize a new name or turn off the voice synthesizer?",,"New Name","Turn Off")) + if(vchange == "New Name") + var/chance = rand(1,100) + switch(chance) + if(1 to 50)//High chance of a regular name. + voice = "[rand(0,1) == 1 ? pick(first_names_female) : pick(first_names_male)] [pick(last_names)]" + if(51 to 80)//Smaller chance of a clown name. + voice = "[pick(clown_names)]" + if(81 to 90)//Small chance of a wizard name. + voice = "[pick(wizard_first)] [pick(wizard_second)]" + if(91 to 100)//Small chance of an existing crew name. + var/list/names = list() + for(var/mob/living/carbon/human/M in player_list) + if(M == U || !M.client || !M.real_name) + continue + names.Add(M.real_name) + voice = !names.len ? "Cuban Pete" : pick(names) + U << "You are now mimicking [voice]." + else + U << "The voice synthesizer is [voice!="Unknown"?"now":"already"] deactivated." + voice = "Unknown" + return + + +/obj/item/clothing/mask/gas/voice/space_ninja/examine(mob/user) + ..() + user << "Voice mimicking algorithm is set [!vchange?"inactive":"active"]." 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 new file mode 100644 index 00000000000..86d1cc128f8 --- /dev/null +++ b/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm @@ -0,0 +1,174 @@ +/* +It will teleport people to a holding facility after 30 seconds. (Check the process() proc to change where teleport goes) +It is possible to destroy the net by the occupant or someone else. +*/ + +/obj/effect/energy_net + name = "energy net" + desc = "It's a net made of green energy." + icon = 'icons/effects/effects.dmi' + icon_state = "energynet" + + density = 1//Can't pass through. + opacity = 0//Can see through. + mouse_opacity = 1//So you can hit it with stuff. + anchored = 1//Can't drag/grab the trapped mob. + + var/health = 25//How much health it has. + var/mob/living/affecting = null//Who it is currently affecting, if anyone. + var/mob/living/master = null//Who shot web. Will let this person know if the net was successful or failed. + + + +/obj/effect/energy_net/proc/healthcheck() + if(health <=0) + density = 0 + if(affecting) + var/mob/living/carbon/M = affecting + M.anchored = 0 + for(var/mob/O in viewers(src, 3)) + O.show_message("[M.name] was recovered from the energy net!", 1, "You hear a grunt.", 2) + if(!isnull(master))//As long as they still exist. + master << "ERROR: unable to initiate transport protocol. Procedure terminated." + qdel(src) + return + + + +/obj/effect/energy_net/process(var/mob/living/carbon/M as mob) + var/check = 30//30 seconds before teleportation. Could be extended I guess. + var/mob_name = affecting.name//Since they will report as null if terminated before teleport. + //The person can still try and attack the net when inside. + while(!isnull(M)&&!isnull(src)&&check>0)//While M and net exist, and 30 seconds have not passed. + check-- + sleep(10) + + if(isnull(M)||M.loc!=loc)//If mob is gone or not at the location. + if(!isnull(master))//As long as they still exist. + master << "ERROR: unable to locate \the [mob_name]. Procedure terminated." + qdel(src)//Get rid of the net. + return + + if(!isnull(src))//As long as both net and person exist. + //No need to check for countdown here since while() broke, it's implicit that it finished. + + density = 0//Make the net pass-through. + invisibility = 101//Make the net invisible so all the animations can play out. + health = INFINITY//Make the net invincible so that an explosion/something else won't kill it while, spawn() is running. + for(var/obj/item/W in M) + if(istype(M,/mob/living/carbon/human)) + if(W==M:w_uniform) continue//So all they're left with are shoes and uniform. + if(W==M:shoes) continue + M.unEquip(W) + + spawn(0) + playsound(M.loc, 'sound/effects/sparks4.ogg', 50, 1) + anim(M.loc,M,'icons/mob/mob.dmi',,"phaseout",,M.dir) + + M.loc = pick(holdingfacility)//Throw mob in to the holding facility. + M << "You appear in a strange place!" + + spawn(0) + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, M.loc) + spark_system.start() + playsound(M.loc, 'sound/effects/phasein.ogg', 25, 1) + playsound(M.loc, 'sound/effects/sparks2.ogg', 50, 1) + anim(M.loc,M,'icons/mob/mob.dmi',,"phasein",,M.dir) + qdel(src)//Wait for everything to finish, delete the net. Else it will stop everything once net is deleted, including the spawn(0). + + for(var/mob/O in viewers(src, 3)) + O.show_message("[M] vanished!", 1, "You hear sparks flying!", 2) + + if(!isnull(master))//As long as they still exist. + master << "SUCCESS: transport procedure of \the [affecting] complete." + + M.anchored = 0//Important. + + else//And they are free. + M << "You are free of the net!" + return + + + +/obj/effect/energy_net/bullet_act(var/obj/item/projectile/Proj) + health -= Proj.damage + healthcheck() + ..() + + + +/obj/effect/energy_net/ex_act(severity, target) + switch(severity) + if(1.0) + health-=50 + if(2.0) + health-=50 + if(3.0) + health-=prob(50)?50:25 + healthcheck() + return + + + +/obj/effect/energy_net/blob_act() + health-=50 + healthcheck() + return + + + +/obj/effect/energy_net/hitby(AM as mob|obj) + ..() + visible_message("[src] was hit by [AM].") + var/tforce = 0 + if(ismob(AM)) + tforce = 10 + else + tforce = AM:throwforce + playsound(src.loc, 'sound/weapons/slash.ogg', 80, 1) + health = max(0, health - tforce) + healthcheck() + ..() + return + + + +/obj/effect/energy_net/attack_hulk(mob/living/carbon/human/user) + ..(user, 1) + user.visible_message("[user] rips the energy net apart!", \ + "You easily destroy the energy net.") + health-=50 + healthcheck() + + + +/obj/effect/energy_net/attack_paw(mob/user) + return attack_hand() + + + +/obj/effect/energy_net/attack_alien(mob/living/user as mob) + user.do_attack_animation(src) + if (islarva(user)) + return + playsound(src.loc, 'sound/weapons/slash.ogg', 80, 1) + health -= rand(10, 20) + if(health > 0) + user.visible_message("[user] claws at the energy net!", \ + "\green You claw at the net.") + else + user.visible_message("[user] slices the energy net apart!", \ + "\green You slice the energy net to pieces.") + healthcheck() + return + + + +/obj/effect/energy_net/attackby(obj/item/weapon/W as obj, mob/user as mob, params) + var/aforce = W.force + health = max(0, health - aforce) + healthcheck() + ..() + return + diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_adrenaline.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_adrenaline.dm new file mode 100644 index 00000000000..d6dc568105f --- /dev/null +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_adrenaline.dm @@ -0,0 +1,26 @@ + + +//Wakes the user so they are able to do their thing. Also injects a decent dose of radium. +//Movement impairing would indicate drugs and the like. +/obj/item/clothing/suit/space/space_ninja/proc/ninjaboost() + set name = "Adrenaline Boost" + set desc = "Inject a secret chemical that will counteract all movement-impairing effect." + set category = "Ninja Ability" + set popup_menu = 0 + + if(!ninjacost(0,N_ADRENALINE))//Have to make sure stat is not counted for this ability. + var/mob/living/carbon/human/H = affecting + H.SetParalysis(0) + H.SetStunned(0) + H.SetWeakened(0) + + H.stat = 0//At least now you should be able to teleport away or shoot ninja stars. + spawn(30)//Slight delay so the enemy does not immedietly know the ability was used. Due to lag, this often came before waking up. + H.say(pick("A CORNERED FOX IS MORE DANGEROUS THAN A JACKAL!","HURT ME MOOORRREEE!","IMPRESSIVE!")) + spawn(70) + reagents.reaction(H, 2) + reagents.trans_id_to(H, "radium", a_transfer) + H << "You are beginning to feel the after-effect of the injection." + a_boost-- + s_coold = 3 + return \ No newline at end of file diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_cost_check.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_cost_check.dm new file mode 100644 index 00000000000..1675dda4530 --- /dev/null +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_cost_check.dm @@ -0,0 +1,29 @@ + + +//Cost function for suit Procs/Verbs/Abilities +/obj/item/clothing/suit/space/space_ninja/proc/ninjacost(cost = 0, specificCheck = 0) + var/mob/living/carbon/human/H = affecting + if((H.stat || H.incorporeal_move) && (specificCheck != N_ADRENALINE))//Will not return if user is using an adrenaline booster since you can use them when stat==1. + H << "You must be conscious and solid to do this."//It's not a problem of stat==2 since the ninja will explode anyway if they die. + return 1 + + var/actualCost = cost*10 + if(cost && cell.charge < actualCost) + H << "Not enough energy." + return 1 + else + //This shit used to be handled individually on every proc.. why even bother with a universal check proc then? + cell.charge-=(actualCost) + + switch(specificCheck) + if(N_STEALTH_CANCEL) + cancel_stealth()//Get rid of it. + if(N_SMOKE_BOMB) + if(!s_bombs) + H << "There are no more smoke bombs remaining." + return 1 + if(N_ADRENALINE) + if(!a_boost) + H << "You do not have any more adrenaline boosters." + return 1 + return (s_coold)//Returns the value of the variable which counts down to zero. \ No newline at end of file diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_empulse.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_empulse.dm new file mode 100644 index 00000000000..8cfc6b89370 --- /dev/null +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_empulse.dm @@ -0,0 +1,15 @@ + + +//Disables nearby tech equipment. +/obj/item/clothing/suit/space/space_ninja/proc/ninjapulse() + set name = "EM Burst (25E)" + set desc = "Disable any nearby technology with a electro-magnetic pulse." + set category = "Ninja Ability" + set popup_menu = 0 + + if(!ninjacost(250,N_STEALTH_CANCEL)) + var/mob/living/carbon/human/H = affecting + playsound(H.loc, 'sound/effects/EMPulse.ogg', 60, 2) + empulse(H, 4, 6) //Procs sure are nice. Slightly weaker than wizard's disable tch. + s_coold = 2 + return \ No newline at end of file diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_net.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_net.dm new file mode 100644 index 00000000000..0a28094ca91 --- /dev/null +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_net.dm @@ -0,0 +1,32 @@ + +//Allows the ninja to kidnap people +/obj/item/clothing/suit/space/space_ninja/proc/ninjanet(mob/living/carbon/C in oview())//Only living carbon mobs. + set name = "Energy Net (20E)" + set desc = "Captures a fallen opponent in a net of energy. Will teleport them to a holding facility after 30 seconds." + set category = null + set src = usr.contents + + if(!ninjacost(200,N_STEALTH_CANCEL) && iscarbon(C)) + var/mob/living/carbon/human/H = affecting + if(C.client)//Monkeys without a client can still step_to() and bypass the net. Also, netting inactive people is lame. + if(!locate(/obj/effect/energy_net) in C.loc)//Check if they are already being affected by an energy net. + for(var/turf/T in getline(H.loc, C.loc)) + if(T.density)//Don't want them shooting nets through walls. It's kind of cheesy. + H << "You may not use an energy net through solid obstacles!" + return + spawn(0) + H.Beam(C,"n_beam",,15) + C.anchored = 1//Anchors them so they can't move. + H.say("Get over here!") + var/obj/effect/energy_net/E = new /obj/effect/energy_net(C.loc) + E.layer = C.layer+1//To have it appear one layer above the mob. + H.visible_message("[H] caught [C] with an energy net!","You caught [C] with an energy net!") + E.affecting = C + E.master = H + spawn(0)//Parallel processing. + E.process(C) + else + H << "They are already trapped inside an energy net." + else + H << "They will bring no honor to your Clan!" + return \ No newline at end of file diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_smoke.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_smoke.dm new file mode 100644 index 00000000000..8d2ff7c3cfe --- /dev/null +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_smoke.dm @@ -0,0 +1,19 @@ + + +//Smoke bomb +/obj/item/clothing/suit/space/space_ninja/proc/ninjasmoke() + set name = "Smoke Bomb" + set desc = "Blind your enemies momentarily with a well-placed smoke bomb." + set category = "Ninja Ability" + set popup_menu = 0//Will not see it when right clicking. + + if(!ninjacost(0,N_SMOKE_BOMB)) + var/mob/living/carbon/human/H = affecting + H << "There are [s_bombs] smoke bombs remaining." + var/datum/effect/effect/system/bad_smoke_spread/smoke = new /datum/effect/effect/system/bad_smoke_spread() + smoke.set_up(10, 0, H.loc) + smoke.start() + playsound(H.loc, 'sound/effects/bamf.ogg', 50, 2) + s_bombs-- + s_coold = 1 + return \ No newline at end of file diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_stars.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_stars.dm new file mode 100644 index 00000000000..9196ed92be7 --- /dev/null +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_stars.dm @@ -0,0 +1,33 @@ + + +//Shoots ninja stars at a random target +/obj/item/clothing/suit/space/space_ninja/proc/ninjastar() + set name = "Energy Star (5E)" + set desc = "Launches an energy star at a random living target." + set category = "Ninja Ability" + set popup_menu = 0 + + if(!ninjacost(50)) + var/mob/living/carbon/human/H = affecting + var/list/targets = list() + for(var/mob/living/M in oview(loc)) + if(M.stat) continue//Doesn't target corpses or paralyzed persons. + targets.Add(M) + if(targets.len) + var/mob/living/target=pick(targets)//The point here is to pick a random, living mob in oview to shoot stuff at. + + var/turf/curloc = get_turf(H) + var/turf/targloc = get_turf(target) + if (!targloc || !curloc) + return + if (targloc == curloc) + return + var/obj/item/projectile/energy/dart/A = new /obj/item/projectile/energy/dart(curloc) + A.current = curloc + A.yo = targloc.y - curloc.y + A.xo = targloc.x - curloc.x + + A.fire() + else + H << "There are no targets in view." + return diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm new file mode 100644 index 00000000000..e87ac8e1ff8 --- /dev/null +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm @@ -0,0 +1,78 @@ + +/* + +Contents: +- Stealth Verbs +- Stealth Icon Stuff + +*/ + + +/obj/item/clothing/suit/space/space_ninja/proc/toggle_stealth() + var/mob/living/carbon/human/U = affecting + if(s_active) + cancel_stealth() + else + spawn(0) + anim(U.loc,U,'icons/mob/mob.dmi',,"cloak",,U.dir) + s_active=!s_active + U.alpha = 0 + U.visible_message("[U.name] vanishes into thin air!", \ + "You are now invisible to normal detection.") + return + + +/obj/item/clothing/suit/space/space_ninja/proc/cancel_stealth() + var/mob/living/carbon/human/U = affecting + if(s_active) + spawn(0) + anim(U.loc,U,'icons/mob/mob.dmi',,"uncloak",,U.dir) + s_active=!s_active + U.alpha = 255 + U.visible_message("[U.name] appears from thin air!", \ + "You are now visible.") + return 1 + return 0 + + +/obj/item/clothing/suit/space/space_ninja/proc/stealth() + set name = "Toggle Stealth" + set desc = "Utilize the internal CLOAK-tech device to activate or deactivate stealth-camo." + set category = "Ninja Equip" + + if(!s_busy) + toggle_stealth() + else + affecting << "Stealth does not appear to work!" + + +//Allows the mob to grab a stealth icon. +/mob/proc/NinjaStealthActive(atom/A)//A is the atom which we are using as the overlay. + invisibility = INVISIBILITY_LEVEL_TWO//Set ninja invis to 2. + var/icon/opacity_icon = new(A.icon, A.icon_state) + var/icon/alpha_mask = getIconMask(src) + var/icon/alpha_mask_2 = new('icons/effects/effects.dmi', "at_shield1") + alpha_mask.AddAlphaMask(alpha_mask_2) + opacity_icon.AddAlphaMask(alpha_mask) + for(var/i=0,i<5,i++)//And now we add it as overlays. It's faster than creating an icon and then merging it. + var/image/I = image("icon" = opacity_icon, "icon_state" = A.icon_state, "layer" = layer+0.8)//So it's above other stuff but below weapons and the like. + switch(i)//Now to determine offset so the result is somewhat blurred. + if(1) + I.pixel_x -= 1 + if(2) + I.pixel_x += 1 + if(3) + I.pixel_y -= 1 + if(4) + I.pixel_y += 1 + + overlays += I//And finally add the overlay. + overlays += image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = layer+0.9) + +//When ninja steal malfunctions. +/mob/proc/NinjaStealthMalf() + invisibility = 0//Set ninja invis to 0. + overlays += image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = layer+0.9) + playsound(loc, 'sound/effects/stealthoff.ogg', 75, 1) + + diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_teleporting.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_teleporting.dm new file mode 100644 index 00000000000..27f46f0d8ee --- /dev/null +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_teleporting.dm @@ -0,0 +1,89 @@ + + +/* + +Contents: +- Proc for handling teleporting while grabbing someone +- Telport Ability +- Right-Click Teleport Ability + +*/ + + +//Handles elporting while grabbing someone +/obj/item/clothing/suit/space/space_ninja/proc/handle_teleport_grab(turf/T, mob/living/H) + if(istype(H.get_active_hand(),/obj/item/weapon/grab))//Handles grabbed persons. + var/obj/item/weapon/grab/G = H.get_active_hand() + G.affecting.loc = locate(T.x+rand(-1,1),T.y+rand(-1,1),T.z)//variation of position. + if(istype(H.get_inactive_hand(),/obj/item/weapon/grab)) + var/obj/item/weapon/grab/G = H.get_inactive_hand() + G.affecting.loc = locate(T.x+rand(-1,1),T.y+rand(-1,1),T.z)//variation of position. + return + + +//Jaunt +/obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt() + set name = "Phase Jaunt (10E)" + set desc = "Utilizes the internal VOID-shift device to rapidly transit in direction facing." + set category = "Ninja Ability" + set popup_menu = 0 + + if(!ninjacost(100,N_STEALTH_CANCEL)) + var/mob/living/carbon/human/H = affecting + var/turf/destination = get_teleport_loc(H.loc,H,9,1,3,1,0,1) + var/turf/mobloc = get_turf(H.loc)//Safety + + if(destination&&istype(mobloc, /turf))//So we don't teleport out of containers + spawn(0) + playsound(H.loc, "sparks", 50, 1) + anim(mobloc,src,'icons/mob/mob.dmi',,"phaseout",,H.dir) + + handle_teleport_grab(destination, H) + H.loc = destination + + spawn(0) + spark_system.start() + playsound(H.loc, 'sound/effects/phasein.ogg', 25, 1) + playsound(H.loc, "sparks", 50, 1) + anim(H.loc,H,'icons/mob/mob.dmi',,"phasein",,H.dir) + + spawn(0) + destination.phase_damage_creatures(20,H)//Paralyse and damage mobs and mechas on the turf + s_coold = 1 + else + H << "The VOID-shift device is malfunctioning, teleportation failed." + return + + +//Right-Click teleport: It's basically admin "jump to turf" +/obj/item/clothing/suit/space/space_ninja/proc/ninjashift(turf/T in oview()) + set name = "Phase Shift (20E)" + set desc = "Utilizes the internal VOID-shift device to rapidly transit to a destination in view." + set category = null//So it does not show up on the panel but can still be right-clicked. + set src = usr.contents//Fixes verbs not attaching properly for objects. Praise the DM reference guide! + + if(!ninjacost(200,N_STEALTH_CANCEL)) + var/mob/living/carbon/human/H = affecting + var/turf/mobloc = get_turf(H.loc)//To make sure that certain things work properly below. + if((!T.density)&&istype(mobloc, /turf)) + spawn(0) + playsound(H.loc, 'sound/effects/sparks4.ogg', 50, 1) + anim(mobloc,src,'icons/mob/mob.dmi',,"phaseout",,H.dir) + + handle_teleport_grab(T, H) + H.loc = T + + spawn(0) + spark_system.start() + playsound(H.loc, 'sound/effects/phasein.ogg', 25, 1) + playsound(H.loc, 'sound/effects/sparks2.ogg', 50, 1) + anim(H.loc,H,'icons/mob/mob.dmi',,"phasein",,H.dir) + + spawn(0)//Any living mobs in teleport area are gibbed. + T.phase_damage_creatures(20,H)//Paralyse and damage mobs and mechas on the turf + s_coold = 1 + else + H << "You cannot teleport into solid walls or from solid matter" + return + + diff --git a/code/modules/ninja/suit/shoes.dm b/code/modules/ninja/suit/shoes.dm new file mode 100644 index 00000000000..732f8a37e8d --- /dev/null +++ b/code/modules/ninja/suit/shoes.dm @@ -0,0 +1,14 @@ + +/obj/item/clothing/shoes/space_ninja + name = "ninja shoes" + desc = "A pair of running shoes. Excellent for running and even better for smashing skulls." + icon_state = "s-ninja" + item_state = "secshoes" + permeability_coefficient = 0.01 + flags = NOSLIP + armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) + strip_delay = 120 + cold_protection = FEET + min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT + heat_protection = FEET + max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT \ No newline at end of file diff --git a/code/modules/ninja/suit/suit.dm b/code/modules/ninja/suit/suit.dm new file mode 100644 index 00000000000..cfe6dc3c807 --- /dev/null +++ b/code/modules/ninja/suit/suit.dm @@ -0,0 +1,172 @@ + +/* + +Contents: +- The Ninja Space Suit +- Ninja Space Suit Procs + +*/ + + +// /obj/item/clothing/suit/space/space_ninja + + +/obj/item/clothing/suit/space/space_ninja + name = "ninja suit" + desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins." + icon_state = "s-ninja" + item_state = "s-ninja_suit" + allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank/internals,/obj/item/weapon/stock_parts/cell) + slowdown = 0 + unacidable = 1 + armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) + strip_delay = 12 + + //Important parts of the suit. + var/mob/living/carbon/human/affecting = null + var/obj/item/weapon/stock_parts/cell/cell + var/datum/effect/effect/system/spark_spread/spark_system + var/list/reagent_list = list("omnizine","salbutamol","spaceacillin","charcoal","nutriment","radium","potass_iodide")//The reagents ids which are added to the suit at New(). + var/list/stored_research = list()//For stealing station research. + var/obj/item/weapon/disk/tech_disk/t_disk//To copy design onto disk. + + //Other articles of ninja gear worn together, used to easily reference them after initializing. + var/obj/item/clothing/head/helmet/space/space_ninja/n_hood + var/obj/item/clothing/shoes/space_ninja/n_shoes + var/obj/item/clothing/gloves/space_ninja/n_gloves + + //Main function variables. + var/s_initialized = 0//Suit starts off. + var/s_coold = 0//If the suit is on cooldown. Can be used to attach different cooldowns to abilities. Ticks down every second based on suit ntick(). + var/s_cost = 5.0//Base energy cost each ntick. + var/s_acost = 25.0//Additional cost for additional powers active. + var/s_delay = 40.0//How fast the suit does certain things, lower is faster. Can be overridden in specific procs. Also determines adverse probability. + var/a_transfer = 20.0//How much reagent is transferred when injecting. + var/r_maxamount = 80.0//How much reagent in total there is. + + //Support function variables. + var/spideros = 0//Mode of SpiderOS. This can change so I won't bother listing the modes here (0 is hub). Check ninja_equipment.dm for how it all works. + var/s_active = 0//Stealth off. + var/s_busy = 0//Is the suit busy with a process? Like AI hacking. Used for safety functions. + + //Ability function variables. + var/s_bombs = 10.0//Number of starting ninja smoke bombs. + var/a_boost = 3.0//Number of adrenaline boosters. + + +/obj/item/clothing/suit/space/space_ninja/New() + ..() + verbs += /obj/item/clothing/suit/space/space_ninja/proc/init//suit initialize verb + + //Spark Init + spark_system = new() + spark_system.set_up(5, 0, src) + spark_system.attach(src) + + //Research Init + stored_research = new() + for(var/T in typesof(/datum/tech) - /datum/tech)//Store up on research. + stored_research += new T(src) + + //Reagent Init + var/reagent_amount + for(var/reagent_id in reagent_list) + reagent_amount += reagent_id == "radium" ? r_maxamount+(a_boost*a_transfer) : r_maxamount + reagents = new(reagent_amount) + reagents.my_atom = src + for(var/reagent_id in reagent_list) + reagent_id == "radium" ? reagents.add_reagent(reagent_id, r_maxamount+(a_boost*a_transfer)) : reagents.add_reagent(reagent_id, r_maxamount)//It will take into account radium used for adrenaline boosting. + + //Cell Init + cell = new/obj/item/weapon/stock_parts/cell/high + cell.charge = 9000 + + + +/obj/item/clothing/suit/space/space_ninja/Destroy() + if(affecting) + affecting << browse(null, "window=hack spideros") + ..() + + +//Simply deletes all the attachments and self, killing all related procs. +/obj/item/clothing/suit/space/space_ninja/proc/terminate() + qdel(n_hood) + qdel(n_gloves) + qdel(n_shoes) + qdel(src) + + +//Randomizes suit parameters. +/obj/item/clothing/suit/space/space_ninja/proc/randomize_param() + s_cost = rand(1,20) + s_acost = rand(20,100) + s_delay = rand(10,100) + s_bombs = rand(5,20) + a_boost = rand(1,7) + + +//This proc prevents the suit from being taken off. +/obj/item/clothing/suit/space/space_ninja/proc/lock_suit(mob/living/carbon/human/H, var/checkIcons = 0) + if(!istype(H)) + return 0 + if(checkIcons) + icon_state = H.gender==FEMALE ? "s-ninjanf" : "s-ninjan" + H.gloves.icon_state = "s-ninjan" + H.gloves.item_state = "s-ninjan" + else + if(H.mind.special_role!="Space Ninja") + H << "\red fÄTaL ÈÈRRoR: 382200-*#00CÖDE RED\nUNAU†HORIZED USÈ DETÈC†††eD\nCoMMÈNCING SUB-R0U†IN3 13...\nTÈRMInATING U-U-USÈR..." + H.gib() + return 0 + if(!istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja)) + H << "ERROR: 100113 UNABLE TO LOCATE HEAD GEAR\nABORTING..." + return 0 + if(!istype(H.shoes, /obj/item/clothing/shoes/space_ninja)) + H << "ERROR: 122011 UNABLE TO LOCATE FOOT GEAR\nABORTING..." + return 0 + if(!istype(H.gloves, /obj/item/clothing/gloves/space_ninja)) + H << "ERROR: 110223 UNABLE TO LOCATE HAND GEAR\nABORTING..." + return 0 + + affecting = H + flags |= NODROP //colons make me go all |= + slowdown = 0 + n_hood = H.head + n_hood.flags |= NODROP + n_shoes = H.shoes + n_shoes.flags |= NODROP + n_shoes.slowdown-- + n_gloves = H.gloves + n_gloves.flags |= NODROP + + return 1 + + +//This proc allows the suit to be taken off. +/obj/item/clothing/suit/space/space_ninja/proc/unlock_suit() + affecting = null + flags &= ~NODROP + slowdown = 1 + icon_state = "s-ninja" + if(n_hood)//Should be attached, might not be attached. + n_hood.flags &= ~NODROP + if(n_shoes) + n_shoes.flags &= ~NODROP + n_shoes.slowdown++ + if(n_gloves) + n_gloves.icon_state = "s-ninja" + n_gloves.item_state = "s-ninja" + n_gloves.flags &= ~NODROP + n_gloves.candrain=0 + n_gloves.draining=0 + + +/obj/item/clothing/suit/space/space_ninja/examine(mob/user) + ..() + if(s_initialized) + if(user == affecting) + user << "All systems operational. Current energy capacity: [cell.charge]." + user << "The CLOAK-tech device is [s_active?"active":"inactive"]." + user << "There are [s_bombs] smoke bomb\s remaining." + user << "There are [a_boost] adrenaline booster\s remaining." diff --git a/code/modules/ninja/suit/suit_attackby.dm b/code/modules/ninja/suit/suit_attackby.dm new file mode 100644 index 00000000000..e7098179d6a --- /dev/null +++ b/code/modules/ninja/suit/suit_attackby.dm @@ -0,0 +1,61 @@ + + +/obj/item/clothing/suit/space/space_ninja/attackby(obj/item/I, mob/U, params) + if(U==affecting)//Safety, in case you try doing this without wearing the suit/being the person with the suit. + + if(istype(I, /obj/item/weapon/reagent_containers/glass))//If it's a glass beaker. + var/total_reagent_transfer//Keep track of this stuff. + for(var/reagent_id in reagent_list) + var/datum/reagent/R = I.reagents.has_reagent(reagent_id)//Mostly to pull up the name of the reagent after calculating. Also easier to use than writing long proc paths. + if(R&&reagents.get_reagent_amount(reagent_id)=a_transfer)//Radium is always special. + //Here we determine how much reagent will actually transfer if there is enough to transfer or there is a need of transfer. Minimum of max amount available (using a_transfer) or amount needed. + var/amount_to_transfer = min( (r_maxamount+(reagent_id == "radium"?(a_boost*a_transfer):0)-reagents.get_reagent_amount(reagent_id)) ,(round(R.volume/a_transfer))*a_transfer)//In the end here, we round the amount available, then multiply it again. + R.volume -= amount_to_transfer//Remove from reagent volume. Don't want to delete the reagent now since we need to perserve the name. + reagents.add_reagent(reagent_id, amount_to_transfer)//Add to suit. Reactions are not important. + total_reagent_transfer += amount_to_transfer//Add to total reagent trans. + U << "Added [amount_to_transfer] units of [R.name]."//Reports on the specific reagent added. + I.reagents.update_total()//Now we manually update the total to make sure everything is properly shoved under the rug. + + U << "Replenished a total of [total_reagent_transfer ? total_reagent_transfer : "zero"] chemical units."//Let the player know how much total volume was added. + return + + else if(istype(I, /obj/item/weapon/stock_parts/cell)) + var/obj/item/weapon/stock_parts/cell/CELL + if(CELL.maxcharge > cell.maxcharge && n_gloves && n_gloves.candrain) + U << "Higher maximum capacity detected.\nUpgrading..." + if (n_gloves && n_gloves.candrain && do_after(U,s_delay)) + U.drop_item() + CELL.loc = src + CELL.charge = min(CELL.charge+cell.charge, CELL.maxcharge) + var/obj/item/weapon/stock_parts/cell/old_cell = cell + old_cell.charge = 0 + U.put_in_hands(old_cell) + old_cell.add_fingerprint(U) + old_cell.corrupt() + old_cell.updateicon() + cell = CELL + U << "Upgrade complete. Maximum capacity: [round(cell.maxcharge/100)]%" + else + U << "Procedure interrupted. Protocol terminated." + return + + else if(istype(I, /obj/item/weapon/disk/tech_disk))//If it's a data disk, we want to copy the research on to the suit. + var/obj/item/weapon/disk/tech_disk/TD = I + if(TD.stored)//If it has something on it. + U << "Research information detected, processing..." + if(do_after(U,s_delay)) + for(var/datum/tech/current_data in stored_research) + if(current_data.id==TD.stored.id) + if(current_data.levelData analyzed and updated. Disk erased." + else + U << "ERROR: Procedure interrupted. Process terminated." + else + I.loc = src + t_disk = I + U << "You slot \the [I] into \the [src]." + return + ..() \ No newline at end of file diff --git a/code/modules/ninja/suit/suit_initialisation.dm b/code/modules/ninja/suit/suit_initialisation.dm new file mode 100644 index 00000000000..967f6e3871e --- /dev/null +++ b/code/modules/ninja/suit/suit_initialisation.dm @@ -0,0 +1,102 @@ + +//Verbs link to procs because verb-like procs have a bug which prevents their use if the arguments are not readily referenced. +//^ Old coder words may be false these days, Not taking the risk for now. + +/obj/item/clothing/suit/space/space_ninja/proc/init() + set name = "Initialize Suit" + set desc = "Initializes the suit for field operation." + set category = "Ninja Equip" + + ninitialize() + +/obj/item/clothing/suit/space/space_ninja/proc/deinit() + set name = "De-Initialize Suit" + set desc = "Begins procedure to remove the suit." + set category = "Ninja Equip" + + if(!s_busy) + deinitialize() + else + affecting << "The function did not trigger!" + + +/obj/item/clothing/suit/space/space_ninja/proc/ninitialize(delay = s_delay, mob/living/carbon/human/U = loc) + if(U.mind && U.mind.assigned_role=="MODE" && !s_initialized && !s_busy)//Shouldn't be busy... but anything is possible I guess. + s_busy = 1 + for(var/i,i<7,i++) + switch(i) + if(0) + U << "Now initializing..." + if(1) + if(!lock_suit(U))//To lock the suit onto wearer. + break + U << "Securing external locking mechanism...\nNeural-net established." + if(2) + U << "Extending neural-net interface...\nNow monitoring brain wave pattern..." + if(3) + if(U.stat==2||U.health<=0) + U << "FĆAL �Rr�R: 344--93#�&&21 BR��N |/|/aV� PATT$RN RED\nA-A-aB�rT�NG..." + unlock_suit() + break + lock_suit(U,1)//Check for icons. + U.regenerate_icons() + U << " Linking neural-net interface...\nPattern\green GREEN, continuing operation." + if(4) + U << "VOID-shift device status: ONLINE.\nCLOAK-tech device status: ONLINE." + if(5) + U << "Primary system status: ONLINE.\nBackup system status: ONLINE.\nCurrent energy capacity: [cell.charge]." + if(6) + U << "All systems operational. Welcome to SpiderOS, [U.real_name]." + grant_ninja_verbs() + grant_equip_verbs() + ntick() + sleep(delay) + s_busy = 0 + else + if(!U.mind||U.mind.assigned_role!="MODE")//Your run of the mill persons shouldn't know what it is. Or how to turn it on. + U << "You do not understand how this suit functions. Where the heck did it even come from?" + else if(s_initialized) + U << "The suit is already functioning. Please report this bug." + else + U << "ERROR: You cannot use this function at this time." + return + + + +/obj/item/clothing/suit/space/space_ninja/proc/deinitialize(delay = s_delay) + if(affecting==loc&&!s_busy) + var/mob/living/carbon/human/U = affecting + if(!s_initialized) + U << "The suit is not initialized. Please report this bug." + return + if(alert("Are you certain you wish to remove the suit? This will take time and remove all abilities.",,"Yes","No")=="No") + return + if(s_busy) + U << "ERROR: You cannot use this function at this time." + return + s_busy = 1 + for(var/i = 0,i<7,i++) + switch(i) + if(0) + U << "Now de-initializing..." + spideros = 0//Spideros resets. + if(1) + U << "Logging off, [U:real_name]. Shutting down SpiderOS." + remove_ninja_verbs() + if(2) + U << "Primary system status: OFFLINE.\nBackup system status: OFFLINE." + if(3) + U << "VOID-shift device status: OFFLINE.\nCLOAK-tech device status: OFFLINE." + cancel_stealth()//Shutdowns stealth. + if(4) + U << "Disconnecting neural-net interface...\greenSuccess." + if(5) + U << "Disengaging neural-net interface...\greenSuccess." + if(6) + U << "Unsecuring external locking mechanism...\nNeural-net abolished.\nOperation status: FINISHED." + remove_equip_verbs() + unlock_suit() + U.regenerate_icons() + sleep(delay) + s_busy = 0 + return \ No newline at end of file diff --git a/code/modules/ninja/suit/suit_process.dm b/code/modules/ninja/suit/suit_process.dm new file mode 100644 index 00000000000..6440ffc71c9 --- /dev/null +++ b/code/modules/ninja/suit/suit_process.dm @@ -0,0 +1,28 @@ + + +/obj/item/clothing/suit/space/space_ninja/proc/ntick(mob/living/carbon/human/U = affecting) + set background = BACKGROUND_ENABLED + + //Runs in the background while the suit is initialized. + spawn while(cell.charge) + + //Let's check for some safeties. + if(s_initialized && !affecting) + terminate()//Kills the suit and attached objects. + if(!s_initialized) + return//When turned off the proc stops. + + //Now let's do the normal processing. + if(s_coold) + s_coold--//Checks for ability s_cooldown first. + + var/A = s_cost//s_cost is the default energy cost each ntick, usually 5. + if(s_active)//If stealth is active. + A += s_acost + cell.charge-=A + + if(!cell.charge) + cell.charge=0 + cancel_stealth() + + sleep(10)//Checks every second. diff --git a/code/modules/ninja/suit/suit_verbs_handlers.dm b/code/modules/ninja/suit/suit_verbs_handlers.dm new file mode 100644 index 00000000000..17ba1ca3910 --- /dev/null +++ b/code/modules/ninja/suit/suit_verbs_handlers.dm @@ -0,0 +1,52 @@ +/* + +Contents: +- Procs that add ninja verbs to ninjas +- Procs that remove ninja verbs from ninjas +- Procs that add ninjasuit verbs to ninjas +- Procs that remove ninjasuit verbs from ninjas + +*/ + +/obj/item/clothing/suit/space/space_ninja/proc/grant_equip_verbs() + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/init + verbs += /obj/item/clothing/suit/space/space_ninja/proc/deinit + verbs += /obj/item/clothing/suit/space/space_ninja/proc/spideros + verbs += /obj/item/clothing/suit/space/space_ninja/proc/stealth + n_gloves.verbs += /obj/item/clothing/gloves/space_ninja/proc/toggled + + s_initialized = 1 + + +/obj/item/clothing/suit/space/space_ninja/proc/remove_equip_verbs() + verbs += /obj/item/clothing/suit/space/space_ninja/proc/init + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/deinit + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/spideros + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/stealth + if(n_gloves) + n_gloves.verbs -= /obj/item/clothing/gloves/space_ninja/proc/toggled + + s_initialized = 0 + + +/obj/item/clothing/suit/space/space_ninja/proc/grant_ninja_verbs() + verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjashift + verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt + verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjasmoke + verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjaboost + verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjapulse + verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjastar + verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjanet + + s_initialized=1 + slowdown=0 + + +/obj/item/clothing/suit/space/space_ninja/proc/remove_ninja_verbs() + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjashift + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjasmoke + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjaboost + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjapulse + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjastar + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjanet diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 5d4d98b84a8..cf006b775cc 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -81,7 +81,7 @@ /obj/item/weapon/paper/attack_self(mob/user) user.examinate(src) - if(rigged && (SSevent.holiday == "April Fool's Day")) + if(rigged && (SSevent.holidays && SSevent.holidays[APRIL_FOOLS])) if(spam_flag == 0) spam_flag = 1 playsound(loc, 'sound/items/bikehorn.ogg', 50, 1) diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm index 248f36b8967..a26c0497223 100644 --- a/code/modules/paperwork/paperbin.dm +++ b/code/modules/paperwork/paperbin.dm @@ -47,7 +47,7 @@ papers.Remove(P) else P = new /obj/item/weapon/paper - if(SSevent.holiday == "April Fool's Day") + if(SSevent.holidays && SSevent.holidays[APRIL_FOOLS]) if(prob(30)) P.info = "HONK HONK HONK HONK HONK HONK HONK
      HOOOOOOOOOOOOOOOOOOOOOONK
      APRIL FOOLS
      " P.rigged = 1 diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index f49516e8f76..95220c1e344 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -132,6 +132,8 @@ temp_img = icon("icons/ass/assfemale.png") else //In case anyone ever makes the generic ass. For now I'll be using male asses. temp_img = icon("icons/ass/assmale.png") + else if(isdrone (ass) || istype(ass,/mob/living/simple_animal/drone)) //Drones are hot + temp_img = icon("icons/ass/assdrone.png") else break var/obj/item/weapon/photo/p = new /obj/item/weapon/photo (loc) @@ -188,7 +190,7 @@ var/datum/picture/selection var/mob/living/silicon/ai/tempAI = usr if(tempAI.aicamera.aipictures.len == 0) - usr << "No images saved" + usr << "No images saved" return for(var/datum/picture/t in tempAI.aicamera.aipictures) nametemp += t.fields["name"] diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index f24dc009643..a759a817464 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -336,7 +336,7 @@ obj/item/device/camera/siliconcam/proc/selectpicture(var/obj/item/device/camera/ var/list/nametemp = list() var/find if(targetloc.aipictures.len == 0) - usr << "No images saved" + usr << "No images saved" return for(var/datum/picture/t in targetloc.aipictures) nametemp += t.fields["name"] diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index ad6c46d0540..10054d21e52 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -627,7 +627,7 @@ obj/structure/cable/proc/avail() if(!isturf(user.loc)) return - if(!T.cancable) + if(!T.can_have_cabling()) user << "You can only lay cables on catwalks and plating!" return @@ -639,10 +639,6 @@ obj/structure/cable/proc/avail() user << "You can't lay cable at a place that far away." return - if(T.intact) // Ff floor is intact, complain - user << "You can't lay cable there unless the floor tiles are removed." - return - else var/dirn @@ -706,7 +702,7 @@ obj/structure/cable/proc/avail() // one end of the clicked cable is pointing towards us if(C.d1 == dirn || C.d2 == dirn) - if(!U.cancable) //checking if it's a plating or catwalk + if(!U.can_have_cabling()) //checking if it's a plating or catwalk user << "You can only lay cables on catwalks and plating!" return if(U.intact) //can't place a cable if it's a plating with a tile on it diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 97fa83a7f47..a73e924ee08 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -57,15 +57,6 @@ else user << "The charge meter reads [round(src.percent() )]%." -/obj/item/weapon/stock_parts/cell/attack_self(mob/user as mob) - src.add_fingerprint(user) - if(ishuman(user)) - var/mob/living/carbon/human/H = user - var/obj/item/clothing/gloves/space_ninja/SNG = H.gloves - if(!istype(SNG) || !SNG.candrain || SNG.draining) return - - SNG.drain("CELL",src,H.wear_suit) - return /obj/item/weapon/stock_parts/cell/attackby(obj/item/W, mob/user, params) ..() diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index d7554e0cbb6..36936dfdc80 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -464,7 +464,7 @@ // return a knot cable (O-X) if one is present in the turf // null if there's none /turf/proc/get_cable_node() - if(!istype(src, /turf/simulated/floor)) + if(!can_have_cabling()) return null for(var/obj/structure/cable/C in src) if(C.d1 == 0) @@ -475,4 +475,4 @@ for(var/area/RA in src.related) var/obj/machinery/power/apc/FINDME = locate() in RA if (FINDME) - return FINDME \ No newline at end of file + return FINDME diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index c502e814eff..1d86b12c944 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -42,7 +42,7 @@ user << "Your soul is too far away." return makeNewConstruct(/mob/living/simple_animal/construct/harvester, user, null, 1) - new /obj/effect/effect/sleep_smoke(user.loc) + PoolOrNew(/obj/effect/effect/sleep_smoke, user.loc) /obj/singularity/narsie/process() diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index 8793962e77f..5ff242be8aa 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -34,6 +34,25 @@ BB = new projectile_type(src) return +/obj/item/ammo_casing/attackby(obj/item/ammo_box/box as obj, mob/user as mob, params) + if (!istype(box, /obj/item/ammo_box)) + return + if(isturf(src.loc)) + var/boolets = 0 + for(var/obj/item/ammo_casing/bullet in src.loc) + if (box.stored_ammo.len >= box.max_ammo) + break + if (bullet.BB) + if (box.give_round(bullet, 0)) + boolets++ + else + continue + if (boolets > 0) + box.update_icon() + user << "You collect [boolets] shell\s. [box] now contains [box.stored_ammo.len] shell\s." + else + user << "You fail to collect anything." + //Boxes of ammo /obj/item/ammo_box name = "ammo box (null_reference_exception)" @@ -55,7 +74,6 @@ var/caliber var/multiload = 1 - /obj/item/ammo_box/New() for(var/i = 1, i <= max_ammo, i++) stored_ammo += new ammo_type(src) @@ -72,7 +90,8 @@ return b /obj/item/ammo_box/proc/give_round(var/obj/item/ammo_casing/R, var/replace_spent = 0) - if(!R || (R.caliber != caliber)) + // Boxes don't have a caliber type, magazines do. Not sure if it's intended or not, but if we fail to find a caliber, then we fall back to ammo_type. + if(!R || (caliber && R.caliber != caliber) || (!caliber && R.type != ammo_type)) return 0 if (stored_ammo.len < max_ammo) diff --git a/code/modules/projectiles/ammunition/ammo_casings.dm b/code/modules/projectiles/ammunition/ammo_casings.dm index 00cda09da83..e26c9b31e92 100644 --- a/code/modules/projectiles/ammunition/ammo_casings.dm +++ b/code/modules/projectiles/ammunition/ammo_casings.dm @@ -61,13 +61,28 @@ /obj/item/ammo_casing/shotgun/improvised name = "improvised shell" desc = "An extremely weak shotgun shell with multiple small pellets made out of metal shards." - icon_state = "gshell" + icon_state = "improvshell" projectile_type = /obj/item/projectile/bullet/pellet/weak m_amt = 250 pellets = 5 variance = 0.8 +/obj/item/ammo_casing/shotgun/improvised/overload + name = "overloaded improvised shell" + desc = "An extremely weak shotgun shell with multiple small pellets made out of metal shards. This one has been packed with even more \ + propellant. It's like playing russian roulette, with a shotgun." + icon_state = "improvshell" + projectile_type = /obj/item/projectile/bullet/pellet/random + m_amt = 250 + pellets = 5 + variance = 1.0 + +/obj/item/ammo_casing/shotgun/improvised/overload/New() + ..() + pellets = rand(3, 8) + + /obj/item/ammo_casing/shotgun/stunslug name = "taser slug" desc = "A stunning taser slug." @@ -110,6 +125,21 @@ pellets = 4 variance = 0.9 +/obj/item/ammo_casing/shotgun/ion + name = "ion shell" + desc = "An advanced shotgun shell which uses a subspace ansible crystal to produce an effect similar to a standard ion rifle. \ + The unique properties of the crystal splot the pulse into a spread of individually weaker bolts." + icon_state = "ionshell" + projectile_type = /obj/item/projectile/ion/weak + pellets = 4 + variance = 0.9 + +/obj/item/ammo_casing/shotgun/laserslug + name = "laser slug" + desc = "An advanced shotgun shell that uses a micro laser to replicate the effects of a laser weapon in a ballistic package." + icon_state = "lshell" + projectile_type = /obj/item/projectile/beam + /obj/item/ammo_casing/shotgun/techshell name = "unloaded technological shell" desc = "A high-tech shotgun shell which can be loaded with materials to produce unique effects." @@ -153,10 +183,14 @@ else return 0 +/obj/item/ammo_casing/caseless/update_icon() + ..() + icon_state = "[initial(icon_state)]" /obj/item/ammo_casing/caseless/a75 desc = "A .75 bullet casing." caliber = "75" + icon_state = "s-casing-live" projectile_type = /obj/item/projectile/bullet/gyro /obj/item/ammo_casing/a40mm @@ -169,8 +203,45 @@ /obj/item/ammo_casing/caseless/magspear name = "magnetic spear" desc = "A reusable spear that is typically loaded into kinetic spearguns." - projectile_type = /obj/item/projectile/bullet/magspear + projectile_type = /obj/item/projectile/bullet/reusable/magspear caliber = "speargun" icon_state = "magspear" throwforce = 15 //still deadly when thrown throw_speed = 3 + +/obj/item/ammo_casing/caseless/foam_dart + name = "foam dart" + desc = "Its nerf or nothing! Ages 8 and up." + projectile_type = /obj/item/projectile/bullet/reusable/foam_dart + caliber = "foam_force" + icon = 'icons/obj/guns/toy.dmi' + icon_state = "foamdart" + var/modified = 0 + +/obj/item/ammo_casing/caseless/foam_dart/update_icon() + ..() + if (modified) + icon_state = "foamdart_empty" + desc = "Its nerf or nothing! ...Although, this one doesn't look too safe." + +/obj/item/ammo_casing/caseless/foam_dart/attackby(var/obj/item/A as obj, mob/user as mob, params) + ..() + if (istype(A, /obj/item/weapon/screwdriver) && !modified) + modified = 1 + BB.damage_type = BRUTE + icon_state = "foamdart_empty" + 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() + A.loc = BB + BB.damage = 5 + BB.nodamage = 0 + user << "You insert [A] into [src]." + return + +/obj/item/ammo_casing/caseless/foam_dart/riot + name = "riot foam dart" + desc = "Who's smart idea was it to use toys as crowd control? Ages 18 and up." + projectile_type = /obj/item/projectile/bullet/reusable/foam_dart/riot + icon_state = "foamdart_riot" diff --git a/code/modules/projectiles/ammunition/boxes.dm b/code/modules/projectiles/ammunition/boxes.dm index 59076dc6da8..a7d14066c38 100644 --- a/code/modules/projectiles/ammunition/boxes.dm +++ b/code/modules/projectiles/ammunition/boxes.dm @@ -47,3 +47,14 @@ ammo_type = /obj/item/ammo_casing/a762 max_ammo = 5 multiple_sprites = 1 + +/obj/item/ammo_box/foambox + name = "ammo box (Foam Darts)" + icon = 'icons/obj/guns/toy.dmi' + icon_state = "foambox" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart + max_ammo = 40 + +/obj/item/ammo_box/foambox/riot + icon_state = "foambox_riot" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot \ No newline at end of file diff --git a/code/modules/projectiles/ammunition/energy.dm b/code/modules/projectiles/ammunition/energy.dm index e7c81acfbcf..c6f8fbf6eba 100644 --- a/code/modules/projectiles/ammunition/energy.dm +++ b/code/modules/projectiles/ammunition/energy.dm @@ -59,7 +59,7 @@ select_name = "stun" fire_sound = 'sound/weapons/taser.ogg' e_cost = 200 - delay = 20 + delay = 15 /obj/item/ammo_casing/energy/electrode/gun fire_sound = 'sound/weapons/gunshot.ogg' diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm index 6addb24a524..b1296f8b2cf 100644 --- a/code/modules/projectiles/ammunition/magazines.dm +++ b/code/modules/projectiles/ammunition/magazines.dm @@ -104,6 +104,14 @@ max_ammo = 5 multiload = 1 +/obj/item/ammo_box/magazine/internal/shot/toy + ammo_type = /obj/item/ammo_casing/caseless/foam_dart + caliber = "foam_force" + max_ammo = 4 + +/obj/item/ammo_box/magazine/internal/shot/toy/crossbow + max_ammo = 5 + ///////////EXTERNAL MAGAZINES//////////////// /obj/item/ammo_box/magazine/m10mm @@ -216,3 +224,49 @@ obj/item/ammo_box/magazine/tommygunm45 name = "shotgun magazine (12g dragon's breath)" icon_state = "m12gf" ammo_type = /obj/item/ammo_casing/shotgun/incendiary/dragonsbreath + +/obj/item/ammo_box/magazine/toy + name = "foam force META magazine" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart + caliber = "foam_force" + +/obj/item/ammo_box/magazine/toy/smg + name = "foam force SMG magazine" + icon_state = "smg9mm-20" + max_ammo = 20 + +/obj/item/ammo_box/magazine/toy/smg/update_icon() + ..() + icon_state = "smg9mm-[round(ammo_count(),5)]" + +/obj/item/ammo_box/magazine/toy/smg/riot + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot + +/obj/item/ammo_box/magazine/toy/pistol + name = "foam force pistol magazine" + icon_state = "9x19p" + max_ammo = 8 + multiple_sprites = 2 + +/obj/item/ammo_box/magazine/toy/pistol/riot + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot + +/obj/item/ammo_box/magazine/toy/smgm45 + name = "donksoft SMG magazine" + caliber = "foam_force" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot + max_ammo = 20 + +/obj/item/ammo_box/magazine/toy/smgm45/update_icon() + ..() + icon_state = "c20r45-[round(ammo_count(),2)]" + +/obj/item/ammo_box/magazine/toy/m762 + name = "donksoft box magazine" + caliber = "foam_force" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot + max_ammo = 50 + +/obj/item/ammo_box/magazine/toy/m762/update_icon() + ..() + icon_state = "a762-[round(ammo_count(),10)]" \ No newline at end of file diff --git a/code/modules/projectiles/firing.dm b/code/modules/projectiles/firing.dm index c5f2b3a0e7d..d130f56e32b 100644 --- a/code/modules/projectiles/firing.dm +++ b/code/modules/projectiles/firing.dm @@ -25,8 +25,7 @@ if(reagents && BB.reagents) reagents.trans_to(BB, reagents.total_volume) //For chemical darts/bullets - reagents.delete() - return + qdel(reagents) /obj/item/ammo_casing/proc/throw_proj(var/turf/targloc, mob/living/user as mob|obj, params) var/turf/curloc = user.loc diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 9b14f51bf4d..4139a3e348c 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -17,6 +17,7 @@ throw_range = 5 force = 5.0 origin_tech = "combat=1" + needs_permit = 1 attack_verb = list("struck", "hit", "bashed") var/fire_sound = "gunshot" diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index d255add4028..f1e7f779d14 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -14,6 +14,7 @@ desc = "A modified version of the basic laser gun, this one fires less concentrated energy bolts designed for target practice." ammo_type = list(/obj/item/ammo_casing/energy/laser/practice) clumsy_check = 0 + needs_permit = 0 obj/item/weapon/gun/energy/laser/retro name ="retro laser" @@ -105,6 +106,7 @@ obj/item/weapon/gun/energy/laser/retro ammo_type = list(/obj/item/ammo_casing/energy/laser/bluetag) origin_tech = "combat=1;magnets=2" clumsy_check = 0 + needs_permit = 0 var/charge_tick = 0 pin = /obj/item/device/firing_pin/tag/blue @@ -135,6 +137,7 @@ obj/item/weapon/gun/energy/laser/retro ammo_type = list(/obj/item/ammo_casing/energy/laser/redtag) origin_tech = "combat=1;magnets=2" clumsy_check = 0 + needs_permit = 0 var/charge_tick = 0 pin = /obj/item/device/firing_pin/tag/red diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 96822335fce..ec025ada176 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -123,6 +123,7 @@ item_state = "kineticgun" ammo_type = list(/obj/item/ammo_casing/energy/kinetic) cell_type = "/obj/item/weapon/stock_parts/cell/emproof" + needs_permit = 0 // Aparently these are safe to carry? I'm sure Golliaths would disagree. var/overheat = 0 var/recent_reload = 1 var/range_add = 0 diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm index acce8548cde..1281adc83e5 100644 --- a/code/modules/projectiles/guns/projectile.dm +++ b/code/modules/projectiles/guns/projectile.dm @@ -11,7 +11,8 @@ /obj/item/weapon/gun/projectile/New() ..() - magazine = new mag_type(src) + if (!magazine) + magazine = new mag_type(src) chamber_round() update_icon() return @@ -133,7 +134,7 @@ return boolets /obj/item/weapon/gun/projectile/suicide_act(mob/user) - if (src.chambered) + if (src.chambered && src.chambered.BB && !src.chambered.BB.nodamage) user.visible_message("[user] is putting the barrel of the [src.name] in \his mouth. It looks like \he's trying to commit suicide.") sleep(25) if(user.l_hand == src || user.r_hand == src) diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index fe5eab9f33e..0073e04b2fe 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -127,7 +127,7 @@ /obj/item/weapon/gun/projectile/revolver/russian name = "russian revolver" - desc = "A Russian-made revolver for drinking games. Uses .357 ammo, and has a mechanism that spins the chamber before each trigger pull." + desc = "A Russian-made revolver for drinking games. Uses .357 ammo, and has a mechanism requiring you to spin the chamber before each trigger pull." origin_tech = "combat=2;materials=2" mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rus357 var/spun = 0 @@ -175,13 +175,17 @@ user << "[src] is empty." /obj/item/weapon/gun/projectile/revolver/russian/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, flag, params) - if(user.a_intent == "harm") // Flogging action - return + if(flag) + if(!(target in user.contents) && ismob(target)) + if(user.a_intent == "harm") // Flogging action + return + if(isliving(user)) if(!can_trigger_gun(user)) return if(target != user) - user << "A mechanism prevents you from shooting anyone but yourself." + if(ismob(target)) + user << "A mechanism prevents you from shooting anyone but yourself." return if(ishuman(user)) diff --git a/code/modules/projectiles/guns/projectile/toy.dm b/code/modules/projectiles/guns/projectile/toy.dm new file mode 100644 index 00000000000..ed3a7e38e68 --- /dev/null +++ b/code/modules/projectiles/guns/projectile/toy.dm @@ -0,0 +1,86 @@ +/obj/item/weapon/gun/projectile/automatic/toy + name = "foam force SMG" + desc = "A prototype three-round burst toy submachine gun. Ages 8 and up." + icon = 'icons/obj/guns/toy.dmi' + icon_state = "saber" + item_state = "gun" + mag_type = /obj/item/ammo_box/magazine/toy/smg + fire_sound = 'sound/weapons/Gunshot_smg.ogg' + force = 0 + throwforce = 0 + burst_size = 3 + can_suppress = 0 + clumsy_check = 0 + needs_permit = 0 + +/obj/item/weapon/gun/projectile/automatic/toy/process_chamber(var/eject_casing = 0, var/empty_chamber = 1) + ..() + +/obj/item/weapon/gun/projectile/automatic/toy/pistol + name = "foam force pistol" + desc = "A small, easily concealable toy handgun. Ages 8 and up." + icon_state = "pistol" + w_class = 2 + mag_type = /obj/item/ammo_box/magazine/toy/pistol + fire_sound = 'sound/weapons/Gunshot.ogg' + can_suppress = 0 + burst_size = 1 + fire_delay = 0 + action_button_name = null + +/obj/item/weapon/gun/projectile/automatic/toy/pistol/update_icon() + ..() + icon_state = "[initial(icon_state)][chambered ? "" : "-e"]" + +/obj/item/weapon/gun/projectile/automatic/toy/pistol/riot/New() + magazine = new /obj/item/ammo_box/magazine/toy/pistol/riot(src) + ..() + +/obj/item/weapon/gun/projectile/shotgun/toy + name = "foam force shotgun" + desc = "A toy shotgun with wood furniture and a four-shell capacity underneath. Ages 8 and up." + icon = 'icons/obj/guns/toy.dmi' + force = 0 + throwforce = 0 + origin_tech = null + mag_type = /obj/item/ammo_box/magazine/internal/shot/toy + clumsy_check = 0 + needs_permit = 0 + +/obj/item/weapon/gun/projectile/shotgun/toy/process_chamber() + ..() + if(chambered && !chambered.BB) + qdel(chambered) + +/obj/item/weapon/gun/projectile/shotgun/toy/crossbow + name = "foam force crossbow" + desc = "A weapon favored by many overactive children. Ages 8 and up." + icon = 'icons/obj/toy.dmi' + icon_state = "foamcrossbow" + item_state = "crossbow" + mag_type = /obj/item/ammo_box/magazine/internal/shot/toy/crossbow + fire_sound = 'sound/items/syringeproj.ogg' + slot_flags = SLOT_BELT + w_class = 2 + +/obj/item/weapon/gun/projectile/automatic/c20r/toy + name = "donksoft SMG" + desc = "A bullpup two-round burst toy SMG, designated 'C-20r'. Ages 8 and up." + icon = 'icons/obj/guns/toy.dmi' + can_suppress = 0 + needs_permit = 0 + mag_type = /obj/item/ammo_box/magazine/toy/smgm45 + +/obj/item/weapon/gun/projectile/automatic/c20r/toy/process_chamber(var/eject_casing = 0, var/empty_chamber = 1) + ..() + +/obj/item/weapon/gun/projectile/automatic/l6_saw/toy + name = "donksoft LMG" + desc = "A heavily modified toy light machine gun, designated 'L6 SAW'. Ages 8 and up." + icon = 'icons/obj/guns/toy.dmi' + can_suppress = 0 + needs_permit = 0 + mag_type = /obj/item/ammo_box/magazine/toy/m762 + +/obj/item/weapon/gun/projectile/automatic/l6_saw/toy/process_chamber(var/eject_casing = 0, var/empty_chamber = 1) + ..() \ No newline at end of file diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index b8b32f5cf16..78f8f83bfcf 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -27,6 +27,9 @@ /obj/item/projectile/bullet/pellet/weak damage = 3 +/obj/item/projectile/bullet/pellet/random/New() + damage = rand(10) + /obj/item/projectile/bullet/midbullet damage = 20 stamina = 65 //two round bursts from the c20r knocks people down @@ -68,8 +71,9 @@ /obj/item/projectile/bullet/incendiary/shell/Move() ..() var/turf/location = get_turf(src) - new/obj/effect/hotspot(location) - location.hotspot_expose(700, 50, 1) + if(location) + new /obj/effect/hotspot(location) + location.hotspot_expose(700, 50, 1) /obj/item/projectile/bullet/incendiary/shell/dragonsbreath name = "dragonsbreath round" diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index 845f914ac15..d485784109c 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -164,9 +164,9 @@ proc/wabbajack(mob/living/M) else new_mob.languages |= HUMAN if("slime") - new_mob = new /mob/living/carbon/slime(M.loc) + new_mob = new /mob/living/simple_animal/slime(M.loc) if(prob(50)) - var/mob/living/carbon/slime/Slime = new_mob + var/mob/living/simple_animal/slime/Slime = new_mob Slime.is_adult = 1 new_mob.languages |= HUMAN if("xeno") @@ -203,15 +203,15 @@ proc/wabbajack(mob/living/M) var/animal = pick("parrot","corgi","crab","pug","cat","mouse","chicken","cow","lizard","chick","fox","butterfly") switch(animal) if("parrot") new_mob = new /mob/living/simple_animal/parrot(M.loc) - if("corgi") new_mob = new /mob/living/simple_animal/corgi(M.loc) + if("corgi") new_mob = new /mob/living/simple_animal/pet/corgi(M.loc) if("crab") new_mob = new /mob/living/simple_animal/crab(M.loc) - if("pug") new_mob = new /mob/living/simple_animal/pug(M.loc) - if("cat") new_mob = new /mob/living/simple_animal/cat(M.loc) + if("pug") new_mob = new /mob/living/simple_animal/pet/pug(M.loc) + if("cat") new_mob = new /mob/living/simple_animal/pet/cat(M.loc) if("mouse") new_mob = new /mob/living/simple_animal/mouse(M.loc) if("chicken") new_mob = new /mob/living/simple_animal/chicken(M.loc) if("cow") new_mob = new /mob/living/simple_animal/cow(M.loc) if("lizard") new_mob = new /mob/living/simple_animal/lizard(M.loc) - if("fox") new_mob = new /mob/living/simple_animal/fox(M.loc) + if("fox") new_mob = new /mob/living/simple_animal/pet/fox(M.loc) if("butterfly") new_mob = new /mob/living/simple_animal/butterfly(M.loc) else new_mob = new /mob/living/simple_animal/chick(M.loc) new_mob.languages |= HUMAN diff --git a/code/modules/projectiles/projectile/reusable.dm b/code/modules/projectiles/projectile/reusable.dm new file mode 100644 index 00000000000..0e9d010d3fe --- /dev/null +++ b/code/modules/projectiles/projectile/reusable.dm @@ -0,0 +1,49 @@ +/obj/item/projectile/bullet/reusable + name = "reusable bullet" + desc = "How do you even reuse a bullet?" + var/obj/item/ammo_casing/caseless/ammo_type = /obj/item/ammo_casing/caseless/ + +/obj/item/projectile/bullet/reusable/on_hit(var/atom/target, var/blocked = 0) + if(!proj_hit) + proj_hit = 1 + if (src.contents.len) + var/obj/content + for(content in src.contents) + content.loc = src.loc + else + new ammo_type(src.loc) + ..() + +/obj/item/projectile/bullet/reusable/on_range() + if(!proj_hit) + if (src.contents.len) + var/obj/content + for(content in src.contents) + content.loc = src.loc + else + new ammo_type(src.loc) + ..() + +/obj/item/projectile/bullet/reusable/magspear + name = "magnetic spear" + desc = "WHITE WHALE, HOLY GRAIL" + damage = 30 //takes 3 spears to kill a mega carp, one to kill a normal carp + icon_state = "magspear" + ammo_type = /obj/item/ammo_casing/caseless/magspear + +/obj/item/projectile/bullet/reusable/foam_dart + name = "foam dart" + desc = "I hope you're wearing eye protection." + damage = 0 // It's a damn toy. + damage_type = OXY + nodamage = 1 + icon = 'icons/obj/guns/toy.dmi' + icon_state = "foamdart" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart + range = 10 + +/obj/item/projectile/bullet/reusable/foam_dart/riot + name = "riot foam dart" + icon_state = "foamdart_riot" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot + stamina = 25 \ No newline at end of file diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index 130f131e4a8..d866f286ecb 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -12,6 +12,13 @@ return 1 +/obj/item/projectile/ion/weak + +/obj/item/projectile/ion/weak/on_hit(atom/target, blocked = 0) + empulse(target, 0, 0) + return 1 + + /obj/item/projectile/bullet/gyro name ="explosive bolt" icon_state= "bolter" @@ -188,19 +195,6 @@ obj/item/projectile/kinetic/New() damage = 25 weaken = 5 -/obj/item/projectile/bullet/magspear - name = "magnetic spear" - desc = "WHITE WHALE, HOLY GRAIL" - damage = 30 //takes 3 spears to kill a mega carp, one to kill a normal carp - icon_state = "magspear" - -/obj/item/projectile/bullet/magspear/on_hit(var/atom/target, var/blocked = 0) - if(!proj_hit) - proj_hit = 1 - new /obj/item/ammo_casing/caseless/magspear(src.loc) - ..() - -/obj/item/projectile/bullet/magspear/on_range() - if(!proj_hit) - new /obj/item/ammo_casing/caseless/magspear(src.loc) - ..() +/obj/item/projectile/bullet/frag12/on_hit(atom/target, blocked = 0) + explosion(target, -1, 0, 1) + return 1 \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Goon-420BlazeIt.dm b/code/modules/reagents/Chemistry-Goon-420BlazeIt.dm index 130cf6a2675..dacb964d7ab 100644 --- a/code/modules/reagents/Chemistry-Goon-420BlazeIt.dm +++ b/code/modules/reagents/Chemistry-Goon-420BlazeIt.dm @@ -7,7 +7,7 @@ datum/reagent/nicotine name = "Nicotine" id = "nicotine" - description = "Stun reduction per cycle, slight stamina regeneration buff. Overdoses become rapidly deadly." + description = "Slightly reduces stun times. If overdosed it will deal toxin and oxygen damage." reagent_state = LIQUID color = "#60A584" // rgb: 96, 165, 132 overdose_threshold = 35 @@ -34,7 +34,7 @@ datum/reagent/nicotine/overdose_process(var/mob/living/M as mob) datum/reagent/crank name = "Crank" id = "crank" - description = "2x stun reduction per cycle. Warms you up, makes you jittery as hell." + description = "Reduces stun times by about 200%. If overdosed or addicted it will deal significant Toxin, Brute and Brain damage." reagent_state = LIQUID color = "#60A584" // rgb: 96, 165, 132 overdose_threshold = 20 @@ -87,7 +87,7 @@ datum/reagent/crank/addiction_act_stage4(var/mob/living/M as mob) /datum/reagent/krokodil name = "Krokodil" id = "krokodil" - description = "Cools and calms you down, occasional BRAIN and TOX damage." + description = "Cools and calms you down. If overdosed it will deal significant Brain and Toxin damage. If addicted it will begin to deal fatal amounts of Brute damage as the subject's skin falls off." reagent_state = LIQUID color = "#60A584" // rgb: 96, 165, 132 overdose_threshold = 20 @@ -126,12 +126,16 @@ datum/reagent/crank/addiction_act_stage4(var/mob/living/M as mob) M.adjustBruteLoss(3*REM) ..() return + /datum/reagent/krokodil/addiction_act_stage4(var/mob/living/carbon/human/M as mob) - M << "Your skin sloughs off!" - M.adjustBruteLoss(rand(50,80)*REM) // holy shit your skin just FELL THE FUCK OFF + if(!istype(M.dna.species, /datum/species/cosmetic_zombie)) + M << "Your skin falls off easily!" + M.adjustBruteLoss(rand(50,80)*REM) // holy shit your skin just FELL THE FUCK OFF + hardset_dna(M, null, null, null, null, /datum/species/cosmetic_zombie) + else + M.adjustBruteLoss(5*REM) ..() return - /datum/chemical_reaction/krokodil name = "Krokodil" id = "krokodil" @@ -144,7 +148,7 @@ datum/reagent/crank/addiction_act_stage4(var/mob/living/M as mob) /datum/reagent/methamphetamine name = "Methamphetamine" id = "methamphetamine" - description = "3x stun reduction per cycle, significant stamina regeneration buff, makes you really jittery, dramatically increases movement speed." + description = "Reduces stun times by about 300%, speeds the user up, and allows the user to quickly recover stamina while dealing a small amount of Brain damage. If overdosed the subject will move randomly, laugh randomly, drop items and suffer from Toxin and Brain damage. If addicted the subject will constantly jitter and drool, before becoming dizzy and losing motor control and eventually suffer heavy toxin damage." reagent_state = LIQUID color = "#60A584" // rgb: 96, 165, 132 overdose_threshold = 20 @@ -169,7 +173,7 @@ datum/reagent/crank/addiction_act_stage4(var/mob/living/M as mob) return /datum/reagent/methamphetamine/overdose_process(var/mob/living/M as mob) - if(M.canmove && !istype(M.loc, /turf/space)) + if(M.canmove && !istype(M.loc, /atom/movable)) for(var/i = 0, i < 4, i++) step(M, pick(cardinal)) if(prob(20)) @@ -199,7 +203,7 @@ datum/reagent/crank/addiction_act_stage4(var/mob/living/M as mob) ..() return /datum/reagent/methamphetamine/addiction_act_stage3(var/mob/living/M as mob) - if(M.canmove && !istype(M.loc, /turf/space)) + if(M.canmove && !istype(M.loc, /atom/movable)) for(var/i = 0, i < 4, i++) step(M, pick(cardinal)) M.Jitter(15) @@ -209,7 +213,7 @@ datum/reagent/crank/addiction_act_stage4(var/mob/living/M as mob) ..() return /datum/reagent/methamphetamine/addiction_act_stage4(var/mob/living/carbon/human/M as mob) - if(M.canmove && !istype(M.loc, /turf/space)) + if(M.canmove && !istype(M.loc, /atom/movable)) for(var/i = 0, i < 8, i++) step(M, pick(cardinal)) M.Jitter(20) @@ -228,59 +232,6 @@ datum/reagent/crank/addiction_act_stage4(var/mob/living/M as mob) result_amount = 4 required_temp = 374 -/datum/chemical_reaction/methamphetamine_two - name = "methamphetamine_two" - id = "methamphetamine_two" - result = "methamphetamine" - required_reagents = list("muriatic_acid" = 1, "caustic_soda" = 1, "hydrogen_chloride" = 1) - result_amount = 3 - required_temp = 374 - -/datum/reagent/muriatic_acid - name = "Muriatic Acid" - id = "muriatic_acid" - description = "A chemical compound." - reagent_state = LIQUID - color = "#60A584" // rgb: 96, 165, 132 - -/datum/reagent/caustic_soda - name = "Caustic Soda" - id = "caustic_soda" - description = "A chemical compound." - reagent_state = LIQUID - color = "#60A584" // rgb: 96, 165, 132 - -/datum/reagent/hydrogen_chloride - name = "Hydrogen Chloride" - id = "hydrogen_chloride" - description = "A chemical compound." - reagent_state = LIQUID - color = "#60A584" // rgb: 96, 165, 132 - -/datum/chemical_reaction/muriatic_acid - name = "muriatic_acid" - id = "muriatic_acid" - result = "muriatic_acid" - required_reagents = list("mutadone" = 1, "sacid" = 1) - result_amount = 2 - required_temp = 500 - -/datum/chemical_reaction/caustic_soda - name = "caustic_soda" - id = "caustic_soda" - result = "caustic_soda" - required_reagents = list("sacid" = 1, "cola" = 1) - result_amount = 2 - required_temp = 500 - -/datum/chemical_reaction/hydrogen_chloride - name = "hydrogen_chloride" - id = "hydrogen_chloride" - result = "hydrogen_chloride" - required_reagents = list("hydrogen" = 1, "chlorine" = 1) - result_amount = 2 - required_temp = 500 - /datum/chemical_reaction/saltpetre name = "saltpetre" id = "saltpetre" @@ -317,7 +268,7 @@ datum/reagent/crank/addiction_act_stage4(var/mob/living/M as mob) M.adjustBrainLoss(1) M.adjustToxLoss(0.1) M.hallucination += 10 - if(M.canmove && !istype(M.loc, /turf/space)) + if(M.canmove && !istype(M.loc, /atom/movable)) step(M, pick(cardinal)) step(M, pick(cardinal)) ..() @@ -333,7 +284,7 @@ datum/reagent/crank/addiction_act_stage4(var/mob/living/M as mob) /datum/reagent/bath_salts/overdose_process(var/mob/living/M as mob) M.hallucination += 10 - if(M.canmove && !istype(M.loc, /turf/space)) + if(M.canmove && !istype(M.loc, /atom/movable)) for(var/i = 0, i < 8, i++) step(M, pick(cardinal)) if(prob(20)) @@ -347,7 +298,7 @@ datum/reagent/crank/addiction_act_stage4(var/mob/living/M as mob) /datum/reagent/bath_salts/addiction_act_stage1(var/mob/living/M as mob) M.hallucination += 10 - if(M.canmove && !istype(M.loc, /turf/space)) + if(M.canmove && !istype(M.loc, /atom/movable)) for(var/i = 0, i < 8, i++) step(M, pick(cardinal)) M.Jitter(5) @@ -358,7 +309,7 @@ datum/reagent/crank/addiction_act_stage4(var/mob/living/M as mob) return /datum/reagent/bath_salts/addiction_act_stage2(var/mob/living/M as mob) M.hallucination += 20 - if(M.canmove && !istype(M.loc, /turf/space)) + if(M.canmove && !istype(M.loc, /atom/movable)) for(var/i = 0, i < 8, i++) step(M, pick(cardinal)) M.Jitter(10) @@ -370,7 +321,7 @@ datum/reagent/crank/addiction_act_stage4(var/mob/living/M as mob) return /datum/reagent/bath_salts/addiction_act_stage3(var/mob/living/M as mob) M.hallucination += 30 - if(M.canmove && !istype(M.loc, /turf/space)) + if(M.canmove && !istype(M.loc, /atom/movable)) for(var/i = 0, i < 12, i++) step(M, pick(cardinal)) M.Jitter(15) @@ -382,7 +333,7 @@ datum/reagent/crank/addiction_act_stage4(var/mob/living/M as mob) return /datum/reagent/bath_salts/addiction_act_stage4(var/mob/living/carbon/human/M as mob) M.hallucination += 40 - if(M.canmove && !istype(M.loc, /turf/space)) + if(M.canmove && !istype(M.loc, /atom/movable)) for(var/i = 0, i < 16, i++) step(M, pick(cardinal)) M.Jitter(50) @@ -404,7 +355,7 @@ datum/reagent/crank/addiction_act_stage4(var/mob/living/M as mob) /datum/reagent/aranesp name = "Aranesp" id = "aranesp" - description = "Volatile." + description = "Amps you up and gets you going, fixes all stamina damage you might have but can cause toxin and oxygen damage.." reagent_state = LIQUID color = "#60A584" // rgb: 96, 165, 132 @@ -415,91 +366,8 @@ datum/reagent/crank/addiction_act_stage4(var/mob/living/M as mob) M << "[high_message]" M.adjustStaminaLoss(-35) M.adjustToxLoss(1) - if(prob(rand(1,100))) + if(prob(50)) M.losebreath++ M.adjustOxyLoss(20) ..() return - -/obj/item/weapon/reagent_containers/food/drinks/muriatic_acid - name = "jug of muriatic acid" - desc = "We needed those cooks." - icon_state = "chem_jug" - item_state = "carton" - list_reagents = list("muriatic_acid" = 50) - -/obj/item/weapon/reagent_containers/food/drinks/caustic_soda - name = "jug of caustic soda" - desc = "We needed those cooks." - icon_state = "chem_jug" - item_state = "carton" - list_reagents = list("caustic_soda" = 50) - -/obj/item/weapon/reagent_containers/food/drinks/hydrogen_chloride - name = "jug of hydrogen chloride" - desc = "We needed those cooks." - icon_state = "chem_jug" - item_state = "carton" - list_reagents = list("hydrogen_chloride" = 50) - -datum/reagent/hotline - name = "Hotline" - id = "hotline" - description = "It isn't just wrong. It's dead wrong." - reagent_state = LIQUID - color = "#60A584" // rgb: 96, 165, 132 - overdose_threshold = 15 - addiction_threshold = 10 - -datum/reagent/hotline/on_mob_life(var/mob/living/M as mob) - if(!M) M = holder.my_atom - var/high_message = pick("You feel alert.", "You feel like you can see everything more clearly.", "You feel like you need to relax and examine your surroundings.") - if(prob(5)) - M << "[high_message]" - M.druggy = max(M.druggy, 15) - M.hallucination += 10 - M.adjustBrainLoss(0.2) - M.adjustBruteLoss(-0.2) - M.adjustFireLoss(-0.2) - M.status_flags |= GOTTAGOFAST - M.adjustStaminaLoss(-3) - ..() - return -datum/reagent/hotline/overdose_process(var/mob/living/M as mob) - M.adjustBrainLoss(rand(1,20)*REM) - M.adjustToxLoss(rand(1,20)*REM) - M.adjustBruteLoss(rand(1,20)*REM) - M.druggy = max(M.druggy, 30) - M.hallucination += 30 - if(prob(5)) - M << pick("Your head feels like it's ripping apart!","You wonder why the fuck did you decide to take [src.name].","It hurts so bad!","Please, end it now!","Dear [ticker.Bible_deity_name] please no it hurts!") - ..() - return - -datum/reagent/hotline/addiction_act_stage1(var/mob/living/M as mob) - M.adjustBrainLoss(rand(1,10)) - M.hallucination += 30 - M.druggy = max(M.druggy, 30) - ..() - return -datum/reagent/hotline/addiction_act_stage2(var/mob/living/M as mob) - M.adjustBrainLoss(rand(1,20)) - M.hallucination += 30 - M.druggy = max(M.druggy, 30) - ..() - return -datum/reagent/hotline/addiction_act_stage3(var/mob/living/M as mob) - M.adjustBrainLoss(rand(1,30)) - M.hallucination += 30 - M.druggy = max(M.druggy, 30) - ..() - return -datum/reagent/hotline/addiction_act_stage4(var/mob/living/M as mob) - M.adjustBrainLoss(rand(1,30)) - M.hallucination += 30 - M.druggy = max(M.druggy, 30) - if(prob(1)) - M.visible_message("[M] clutches at their chest! It looks like they're having a heart attack!") - M.adjustBruteLoss(80) // don't do drugs kids - ..() - return diff --git a/code/modules/reagents/Chemistry-Goon-Medicine.dm b/code/modules/reagents/Chemistry-Goon-Medicine.dm index ab16118b87f..88860f358f5 100644 --- a/code/modules/reagents/Chemistry-Goon-Medicine.dm +++ b/code/modules/reagents/Chemistry-Goon-Medicine.dm @@ -7,21 +7,22 @@ datum/reagent/silver_sulfadiazine name = "Silver Sulfadiazine" id = "silver_sulfadiazine" - description = "100% chance per cycle of healing 2 points of BURN damage." + description = "On touch, quickly heals burn damage. Basic anti-burn healing drug. On ingestion, deals minor toxin damage." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" metabolization_rate = 2 datum/reagent/silver_sulfadiazine/reaction_mob(var/mob/living/M as mob, var/method=TOUCH, var/volume, var/show_message = 1) - if(method == TOUCH) - M.adjustFireLoss(-volume) - if(show_message) - M << "You feel your burns healing!" - M.emote("scream") - if(method == INGEST) - M.adjustToxLoss(0.5*volume) - if(show_message) - M << "You probably shouldn't have eaten that. Maybe you should of splashed it on, or applied a patch?" + if(iscarbon(M)) + if(method == TOUCH) + M.adjustFireLoss(-volume) + if(show_message) + M << "You feel your burns healing!" + M.emote("scream") + if(method == INGEST) + M.adjustToxLoss(0.5*volume) + if(show_message) + M << "You probably shouldn't have eaten that. Maybe you should of splashed it on, or applied a patch?" ..() return @@ -34,21 +35,22 @@ datum/reagent/silver_sulfadiazine/on_mob_life(var/mob/living/M as mob) datum/reagent/styptic_powder name = "Styptic Powder" id = "styptic_powder" - description = "100% chance per cycle of healing 2 points of BRUTE damage." + description = "On touch, quickly heals brute damage. Basic anti-brute healing drug. On ingestion, deals minor toxin damage." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" metabolization_rate = 2 datum/reagent/styptic_powder/reaction_mob(var/mob/living/M as mob, var/method=TOUCH, var/volume, var/show_message = 1) - if(method == TOUCH) - M.adjustBruteLoss(-volume) - if(show_message) - M << "You feel your wounds knitting back together!" - M.emote("scream") - if(method == INGEST) - M.adjustToxLoss(0.5*volume) - if(show_message) - M << "You probably shouldn't have eaten that. Maybe you should of splashed it on, or applied a patch?" + if(iscarbon(M)) + if(method == TOUCH) + M.adjustBruteLoss(-volume) + if(show_message) + M << "You feel your wounds knitting back together!" + M.emote("scream") + if(method == INGEST) + M.adjustToxLoss(0.5*volume) + if(show_message) + M << "You probably shouldn't have eaten that. Maybe you should of splashed it on, or applied a patch?" ..() return @@ -62,9 +64,9 @@ datum/reagent/styptic_powder/on_mob_life(var/mob/living/M as mob) datum/reagent/salglu_solution name = "Saline-Glucose Solution" id = "salglu_solution" - description = "33% chance per cycle of healing 1 point each of BRUTE and BURN damage." + description = "Has a 33% chance per metabolism cycle to heal brute and burn damage." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" datum/reagent/salglu_solution/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom @@ -77,26 +79,27 @@ datum/reagent/salglu_solution/on_mob_life(var/mob/living/M as mob) datum/reagent/synthflesh name = "Synthflesh" id = "synthflesh" - description = "100% chance per cycle of healing 1 point each of BRUTE and BURN damage." + description = "Has a 100% chance of instantly healing brute and burn damage. One unit of the chemical will heal one point of damage. Touch application only." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" datum/reagent/synthflesh/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume,var/show_message = 1) if(!M) M = holder.my_atom - if(method == TOUCH) - M.adjustBruteLoss(-1.5*volume) - M.adjustFireLoss(-1.5*volume) - if(show_message) - M << "You feel your burns healing and your flesh knitting together!" + if(iscarbon(M)) + if(method == TOUCH) + M.adjustBruteLoss(-1.5*volume) + M.adjustFireLoss(-1.5*volume) + if(show_message) + M << "You feel your burns healing and your flesh knitting together!" ..() return datum/reagent/charcoal name = "Charcoal" id = "charcoal" - description = "Heals 3 TOX damage per cycle and purges other chemicals slowly." + description = "Heals toxin damage, and will also slowly remove any other chemicals." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" datum/reagent/charcoal/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom @@ -148,9 +151,9 @@ datum/reagent/charcoal/on_mob_life(var/mob/living/M as mob) datum/reagent/omnizine name = "Omnizine" id = "omnizine" - description = "Heals one each of OXY, TOX, BRUTE and BURN per cycle." + description = "Heals 1 of each damage type a cycle. If overdosed it will deal significant amounts of each damage type." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" metabolization_rate = 0.2 overdose_threshold = 30 @@ -174,9 +177,9 @@ datum/reagent/omnizine/overdose_process(var/mob/living/M as mob) datum/reagent/calomel name = "Calomel" id = "calomel" - description = "Increases all depletion rates by 5. +5 TOX damage while health > 20." + description = "Quickly purges the body of all chemicals. If your health is above 20, toxin damage is dealt. When you hit 20 health or lower, the damage will cease." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" datum/reagent/calomel/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom @@ -199,9 +202,9 @@ datum/reagent/calomel/on_mob_life(var/mob/living/M as mob) datum/reagent/potass_iodide name = "Potassium Iodide" id = "potass_iodide" - description = "80% chance of removing 1 RAD. Radiation is cumulative and causes tox+burn." + description = "Reduces low radiation damage very effectively." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" datum/reagent/potass_iodide/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom @@ -223,9 +226,9 @@ datum/reagent/potass_iodide/on_mob_life(var/mob/living/M as mob) datum/reagent/pen_acid name = "Pentetic Acid" id = "pen_acid" - description = "Reduces 7 RAD, heals 4 TOX damage, increases all depletion rates by 4. 33% chance of taking 1 unit brute damage" + description = "Reduces massive amounts of radiation and toxin damage while purging other chemicals from the body. Has a chance of dealing brute damage." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" datum/reagent/pen_acid/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom @@ -252,9 +255,9 @@ datum/reagent/pen_acid/on_mob_life(var/mob/living/M as mob) datum/reagent/sal_acid name = "Salicyclic Acid" id = "sal_acid" - description = "If BRUTE damage is under 50, 50% chance to heal one unit." + description = "If you have less than 50 brute damage, there is a 50% chance to heal one unit. If overdosed it will have a 50% chance to deal 2 brute damage if the patient has less than 50 brute damage already." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" overdose_threshold = 25 datum/reagent/sal_acid/on_mob_life(var/mob/living/M as mob) @@ -282,9 +285,9 @@ datum/reagent/sal_acid/overdose_process(var/mob/living/M as mob) datum/reagent/salbutamol name = "Salbutamol" id = "salbutamol" - description = "Heals 6 OXY damage, reduces LOSEBREATH by 4." + description = "Quickly heals oxygen damage while slowing down suffocation. Great for stabilizing critical patients!" reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" metabolization_rate = 0.2 datum/reagent/salbutamol/on_mob_life(var/mob/living/M as mob) @@ -305,9 +308,9 @@ datum/reagent/salbutamol/on_mob_life(var/mob/living/M as mob) datum/reagent/perfluorodecalin name = "Perfluorodecalin" id = "perfluorodecalin" - description = "Heals 25 OXY damage, but you can't talk. 33% chance of healing 1 BRUTE and 1 BURN." + description = "Heals suffocation damage so quickly that you could have a spacewalk, but it mutes your voice. Has a 33% chance of healing brute and burn damage per cycle as well." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" metabolization_rate = 0.2 datum/reagent/perfluorodecalin/on_mob_life(var/mob/living/carbon/human/M as mob) @@ -332,9 +335,9 @@ datum/reagent/perfluorodecalin/on_mob_life(var/mob/living/carbon/human/M as mob) datum/reagent/ephedrine name = "Ephedrine" id = "ephedrine" - description = "Stun reduction per cycle, increases run speed slightly, minor stamina regeneration buff, stabilizes crit." + description = "Reduces stun times, increases run speed. If overdosed it will deal toxin and oxyloss damage." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" metabolization_rate = 0.3 overdose_threshold = 45 addiction_threshold = 30 @@ -392,9 +395,9 @@ datum/reagent/ephedrine/addiction_act_stage4(var/mob/living/M as mob) datum/reagent/diphenhydramine name = "Diphenhydramine" id = "diphenhydramine" - description = "Causes a little bit of drowsiness, reduces jitteriness. Raises histamine depletion rates by 3" + description = "Purges body of lethal Histamine and reduces jitteriness while causing minor drowsiness." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" datum/reagent/diphenhydramine/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom M.drowsyness += 1 @@ -414,9 +417,9 @@ datum/reagent/diphenhydramine/on_mob_life(var/mob/living/M as mob) datum/reagent/morphine name = "Morphine" id = "morphine" - description = "Dramatically counters movement reduction from severe injury. Reduces jitteriness if someone is shaking like crazy from whatever. Will knock you out within 36 cycles if any remains in you." + description = "Will allow you to ignore slowdown from equipment and damage. Will eventually knock you out if you take too much. If overdosed it will cause jitteriness, dizziness, force the victim to drop items in their hands and eventually deal toxin damage." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" var/cycle_count = 0 overdose_threshold = 30 addiction_threshold = 25 @@ -425,8 +428,8 @@ datum/reagent/morphine datum/reagent/morphine/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom M.status_flags |= IGNORESLOWDOWN - if(cycle_count == 36) - M.drowsyness += 1 + if(cycle_count >= 36) + M.sleeping += 3 cycle_count++ ..() return @@ -507,18 +510,18 @@ datum/reagent/oculine/on_mob_life(var/mob/living/M as mob) datum/reagent/oculine name = "Oculine" id = "oculine" - description = "30% chance to remove blindness, 80% chance to slightly reduce eye damage." + description = "Cures blindness and heals eye damage over time." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" metabolization_rate = 0.4 var/cycle_amount = 0 datum/reagent/atropine name = "Atropine" id = "atropine" - description = "1 TOX damage if used over -60 health. Causes dizziness and confusion. If under -25 health, heals 3 BRUTE + 3 BURN. Attempts to cap OXY damage at 65 and LOSEBREATH at 5." + description = "If patients health is below -25 it will heal 3 brute and burn damage per cycle, as well as stop any oxyloss. Good for stabilising critical patients." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" metabolization_rate = 0.2 overdose_threshold = 35 @@ -557,9 +560,9 @@ datum/reagent/atropine/overdose_process(var/mob/living/M as mob) datum/reagent/epinephrine name = "Epinephrine" id = "epinephrine" - description = "Reduces most of the knockout/stun effects, minor stamina regeneration buff. Attempts to cap OXY damage at 35 and LOSEBREATH at 10. If health is between -10 to -65, heals 1 TOX, 1 BRUTE, 1 BURN." + description = "mReduces most of the knockout/stun effects, minor stamina regeneration buff. Attempts to stop you taking too much oxygen damage. If the patient is in low to severe crit, heals toxins, brute, and burn very effectively. Will not heal patients who are almost dead. If overdosed will stun and deal toxin damage" reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" metabolization_rate = 0.2 overdose_threshold = 30 @@ -571,8 +574,10 @@ datum/reagent/epinephrine/on_mob_life(var/mob/living/M as mob) M.adjustFireLoss(-1*REM) if(M.oxyloss > 35) M.setOxyLoss(35) - if(M.losebreath >= 10) - M.losebreath = max(10, M.losebreath-5) + if(M.losebreath >= 4) + M.losebreath -= 4 + if(M.losebreath < 0) + M.losebreath = 0 M.adjustStaminaLoss(-1*REM) if(prob(30)) M.AdjustParalysis(-1) @@ -599,9 +604,9 @@ datum/reagent/epinephrine/overdose_process(var/mob/living/M as mob) datum/reagent/strange_reagent name = "Strange Reagent" id = "strange_reagent" - description = "A miracle medical chem, this little beauty can bring the dead back to life!" + description = "A miracle drug that can bring a dead body back to life! If the corpse has suffered too much damage, however, no change will occur to the body. If used on a living person it will deal Brute and Burn damage." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" datum/reagent/strange_reagent/reaction_mob(var/mob/living/carbon/human/M as mob, var/method=TOUCH, var/volume) if(M.stat == DEAD) @@ -622,7 +627,7 @@ datum/reagent/strange_reagent/reaction_mob(var/mob/living/carbon/human/M as mob, return datum/reagent/strange_reagent/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom - if(prob(rand(1,100))) + if(prob(50)) M.adjustBruteLoss(2*REM) M.adjustFireLoss(2*REM) ..() @@ -638,9 +643,9 @@ datum/reagent/strange_reagent/on_mob_life(var/mob/living/M as mob) datum/reagent/life name = "Life" id = "life" - description = "" + description = "Can create a life form, however it is not guaranteed to be friendly. May want to have Security on hot standby." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" metabolization_rate = 0.2 /datum/chemical_reaction/life @@ -698,8 +703,7 @@ proc/chemical_mob_spawn(var/datum/reagents/holder, var/amount_to_spawn, var/reac playsound(get_turf(holder.my_atom), 'sound/effects/phasein.ogg', 100, 1) for(var/mob/living/carbon/human/H in viewers(get_turf(holder.my_atom), null)) - if(H:eyecheck() <= 0) - flick("e_flash", H.flash) + H.flash_eyes() for(var/i = 1, i <= amount_to_spawn, i++) var/chosen = pick(critters) var/mob/living/simple_animal/hostile/C = new chosen @@ -725,8 +729,8 @@ proc/chemical_mob_spawn(var/datum/reagents/holder, var/amount_to_spawn, var/reac /datum/reagent/mannitol name = "Mannitol" id = "mannitol" - description = "Heals 3 BRAIN damage." - color = "#C8A5DC" // rgb: 200, 165, 220 + description = "Heals brain damage effectively. Use it in cyro tubes alongside Cryoxadone." + color = "#C8A5DC" /datum/reagent/mutadone/on_mob_life(var/mob/living/carbon/human/M as mob) M.jitteriness = 0 @@ -746,14 +750,14 @@ proc/chemical_mob_spawn(var/datum/reagents/holder, var/amount_to_spawn, var/reac /datum/reagent/mutadone name = "Mutadone" id = "mutadone" - description = "Chance to remove genetic disabilities." - color = "#C8A5DC" // rgb: 200, 165, 220 + description = "Heals your genetic defects." + color = "#C8A5DC" datum/reagent/antihol name = "Antihol" id = "antihol" - description = "A powerful oxidizer that reacts with ethanol." - color = "#C8A5DC" // rgb: 200, 165, 220 + description = "Helps remove Alcohol from someone's body, as well as eliminating its side effects." + color = "#C8A5DC" datum/reagent/antihol/on_mob_life(var/mob/living/M as mob) M.dizziness = 0 @@ -781,8 +785,8 @@ datum/reagent/antihol/on_mob_life(var/mob/living/M as mob) /datum/reagent/stimulants name = "Stimulants" id = "stimulants" - description = "Sets all stun-related vars to zero, gets you running really fast. Heals 5 OXY, TOX, BRUTE, and BURN damage if health is below 50. Reduces all stuns." - color = "#C8A5DC" // rgb: 200, 165, 220 + description = "Increases run speed and eliminates stuns, can heal minor damage. If overdosed it will deal toxin damage and stun." + color = "#C8A5DC" metabolization_rate = 0.4 overdose_threshold = 60 @@ -815,7 +819,7 @@ datum/reagent/insulin id = "insulin" description = "Increases sugar depletion rates." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" datum/reagent/insulin/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom if(M.sleeping) diff --git a/code/modules/reagents/Chemistry-Goon-Other.dm b/code/modules/reagents/Chemistry-Goon-Other.dm index 13bb4cabef6..bda6a4441d8 100644 --- a/code/modules/reagents/Chemistry-Goon-Other.dm +++ b/code/modules/reagents/Chemistry-Goon-Other.dm @@ -8,42 +8,41 @@ var/list/random_color_list = list("#00aedb","#a200ff","#f47835","#d41243","#d111 datum/reagent/oil name = "Oil" id = "oil" - description = "A slippery solution." + description = "Burns in a small smoky fire, mostly used to get Ash." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" datum/reagent/stable_plasma name = "Stable Plasma" id = "stable_plasma" description = "Non-flammable plasma locked into a liquid form that cannot ignite or become gaseous/solid." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" datum/reagent/iodine name = "Iodine" id = "iodine" description = "A slippery solution." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" datum/reagent/fluorine name = "Fluorine" id = "fluorine" description = "A slippery solution." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" datum/reagent/carpet name = "Carpet" id = "carpet" description = "A slippery solution." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" /datum/reagent/carpet/reaction_turf(var/turf/simulated/T, var/volume) if(istype(T, /turf/simulated/floor/plating) || istype(T, /turf/simulated/floor/plasteel)) var/turf/simulated/floor/F = T - F.visible_message("[T] gets a layer of carpeting applied!") F.ChangeTurf(/turf/simulated/floor/fancy/carpet) ..() return @@ -53,28 +52,28 @@ datum/reagent/bromine id = "bromine" description = "A slippery solution." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" datum/reagent/phenol name = "Phenol" id = "phenol" - description = "A slippery solution." + description = "Used for certain medical recipes." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" datum/reagent/ash name = "Ash" id = "ash" - description = "A burnt solution." + description = "Basic ingredient in a couple of recipes." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" datum/reagent/acetone name = "Acetone" id = "acetone" - description = "A solution." + description = "Common ingredient in other recipes." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" /datum/chemical_reaction/acetone name = "acetone" @@ -118,7 +117,7 @@ datum/reagent/colorful_reagent id = "colorful_reagent" description = "A solution." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" /datum/chemical_reaction/colorful_reagent name = "colorful_reagent" @@ -155,7 +154,7 @@ datum/reagent/triple_citrus id = "triple_citrus" description = "A solution." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" /datum/chemical_reaction/triple_citrus name = "triple_citrus" @@ -169,7 +168,7 @@ datum/reagent/corn_starch id = "corn_starch" description = "A slippery solution." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" /datum/chemical_reaction/corn_syrup name = "corn_syrup" @@ -184,7 +183,7 @@ datum/reagent/corn_syrup id = "corn_syrup" description = "Decays into sugar." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" datum/reagent/corn_syrup/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom @@ -206,11 +205,11 @@ datum/reagent/corgium id = "corgium" description = "Creates a corgi at the reaction location." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" /datum/chemical_reaction/corgium/on_reaction(var/datum/reagents/holder, var/created_volume) var/location = get_turf(holder.my_atom) - new /mob/living/simple_animal/corgi(location) + new /mob/living/simple_animal/pet/corgi(location) ..() return @@ -219,7 +218,7 @@ datum/reagent/hair_dye id = "hair_dye" description = "A solution." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" var/list/potential_colors = list("0ad","a0f","f73","d14","d14","0b5","0ad","f73","fc2","084","05e","d22","fa0") // fucking hair code /datum/chemical_reaction/hair_dye @@ -243,7 +242,7 @@ datum/reagent/barbers_aid id = "barbers_aid" description = "A solution to hair loss across the world." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" /datum/chemical_reaction/barbers_aid name = "barbers_aid" @@ -268,7 +267,7 @@ datum/reagent/concentrated_barbers_aid id = "concentrated_barbers_aid" description = "A concentrated solution to hair loss across the world." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#C8A5DC" /datum/chemical_reaction/concentrated_barbers_aid name = "concentrated_barbers_aid" diff --git a/code/modules/reagents/Chemistry-Goon-Pyrotechnics.dm b/code/modules/reagents/Chemistry-Goon-Pyrotechnics.dm index 1190b7b77a8..59ce545d9bc 100644 --- a/code/modules/reagents/Chemistry-Goon-Pyrotechnics.dm +++ b/code/modules/reagents/Chemistry-Goon-Pyrotechnics.dm @@ -4,12 +4,26 @@ #define REM REAGENTS_EFFECT_MULTIPLIER +/datum/reagent/stabilizing_agent + name = "Stabilizing Agent" + id = "stabilizing_agent" + description = "Keeps unstable chemicals stable. This does not work on everything." + reagent_state = LIQUID + color = "#FFFFFF" + +/datum/chemical_reaction/stabilizing_agent + name = "stabilizing_agent" + id = "stabilizing_agent" + result = "stabilizing_agent" + required_reagents = list("iron" = 1, "oxygen" = 1, "hydrogen" = 1) + result_amount = 3 + /datum/reagent/clf3 name = "Chlorine Trifluoride" id = "clf3" description = "Makes a temporary 3x3 fireball when it comes into existence, so be careful when mixing. ClF3 applied to a surface burns things that wouldn't otherwise burn, sometimes through the very floors of the station and exposing it to the vacuum of space." reagent_state = LIQUID - color = "#60A584" // rgb: 96, 165, 132 + color = "#FF0000" metabolization_rate = 4 /datum/chemical_reaction/clf3 @@ -22,15 +36,14 @@ /datum/reagent/clf3/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom - M.adjust_fire_stacks(5) - M.IgniteMob() - M.adjustFireLoss(5*REM) + M.adjust_fire_stacks(4) + M.adjustFireLoss(0.35*M.fire_stacks) ..() return /datum/chemical_reaction/clf3/on_reaction(var/datum/reagents/holder, var/created_volume) - var/turf/simulated/T = get_turf(holder.my_atom) - for(var/turf/simulated/turf in range(1,T)) + var/turf/T = get_turf(holder.my_atom) + for(var/turf/turf in range(1,T)) new /obj/effect/hotspot(turf) holder.chem_temp = 1000 // hot as shit return @@ -53,7 +66,7 @@ return /datum/reagent/clf3/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume) - if(method == TOUCH && ishuman(M)) + if(method == TOUCH && isliving(M)) M.adjust_fire_stacks(5) M.IgniteMob() new /obj/effect/hotspot(M.loc) @@ -64,7 +77,7 @@ id = "sorium" description = "Sends everything flying from the detonation point." reagent_state = LIQUID - color = "#60A584" //rgb: 96, 165, 132 + color = "#FFA500" /datum/chemical_reaction/sorium name = "Sorium" @@ -72,20 +85,22 @@ result = "sorium" required_reagents = list("mercury" = 1, "oxygen" = 1, "nitrogen" = 1, "carbon" = 1) result_amount = 4 + +/datum/chemical_reaction/sorium_vortex + name = "sorium_vortex" + id = "sorium_vortex" + result = null + required_reagents = list("sorium" = 1) required_temp = 474 -/datum/reagent/sorium/reaction_turf(var/turf/simulated/T, var/volume) - if(istype(T, /turf/simulated/floor/)) - goonchem_vortex(T, 1, 5, 3) -/datum/reagent/sorium/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume) - if(!istype(M, /mob/living)) - return - if(method == TOUCH) - var/turf/simulated/T = get_turf(M) - goonchem_vortex(T, 1, 5, 3) - +/datum/chemical_reaction/sorium_vortex/on_reaction(var/datum/reagents/holder, var/created_volume) + var/turf/simulated/T = get_turf(holder.my_atom) + goonchem_vortex(T, 1, 5, 6) /datum/chemical_reaction/sorium/on_reaction(var/datum/reagents/holder, var/created_volume) + if(holder.has_reagent("stabilizing_agent")) + return + holder.remove_reagent("sorium", created_volume) var/turf/simulated/T = get_turf(holder.my_atom) goonchem_vortex(T, 1, 5, 6) @@ -94,28 +109,30 @@ id = "liquid_dark_matter" description = "Sucks everything into the detonation point." reagent_state = LIQUID - color = "#60A584" //rgb: 96, 165, 132 + color = "#800080" /datum/chemical_reaction/liquid_dark_matter name = "Liquid Dark Matter" id = "liquid_dark_matter" result = "liquid_dark_matter" required_reagents = list("stable_plasma" = 1, "radium" = 1, "carbon" = 1) - result_amount = null + result_amount = 3 + +/datum/chemical_reaction/ldm_vortex + name = "LDM Vortex" + id = "ldm_vortex" + result = null + required_reagents = list("liquid_dark_matter" = 1) required_temp = 474 -/*/datum/reagent/liquid_dark_matter/reaction_turf(var/turf/simulated/T, var/volume) - if(istype(T, /turf/simulated/floor/)) - goonchem_vortex(T, 0, 5, 3) - return -/datum/reagent/liquid_dark_matter/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume) - if(!istype(M, /mob/living)) - return - if(method == TOUCH) - var/turf/simulated/T = get_turf(M) - goonchem_vortex(T, 0, 5, 3) - return*/ //o god what the fuck goof +/datum/chemical_reaction/ldm_vortex/on_reaction(var/datum/reagents/holder, var/created_volume) + var/turf/simulated/T = get_turf(holder.my_atom) + goonchem_vortex(T, 0, 5, 6) + return /datum/chemical_reaction/liquid_dark_matter/on_reaction(var/datum/reagents/holder, var/created_volume) + if(holder.has_reagent("stabilizing_agent")) + return + holder.remove_reagent("liquid_dark_matter", created_volume) var/turf/simulated/T = get_turf(holder.my_atom) goonchem_vortex(T, 0, 5, 6) return @@ -138,7 +155,7 @@ id = "blackpowder" description = "Explodes. Violently." reagent_state = LIQUID - color = "#000000" //rgb: 96, 165, 132 + color = "#000000" metabolization_rate = 0.05 /datum/chemical_reaction/blackpowder @@ -155,7 +172,7 @@ required_reagents = list("blackpowder" = 1) result_amount = 1 required_temp = 474 - mix_message = "Sparks start flying around the black powder!" + mix_message = "Sparks start flying around the black powder!" /datum/chemical_reaction/blackpowder_explosion/on_reaction(var/datum/reagents/holder, var/created_volume) sleep(rand(50,100)) @@ -166,3 +183,280 @@ var/ex_flash = round(created_volume / 8) explosion(T,ex_severe,ex_heavy,ex_light,ex_flash, 1) return + +/datum/reagent/flash_powder + name = "Flash Powder" + id = "flash_powder" + description = "Makes a very bright flash." + reagent_state = LIQUID + color = "#FFFF00" + +/datum/chemical_reaction/flash_powder + name = "Flash powder" + id = "flash_powder" + result = "flash_powder" + required_reagents = list("aluminium" = 1, "potassium" = 1, "sulfur" = 1 ) + result_amount = 3 + +/datum/chemical_reaction/flash_powder_flash + name = "Flash powder activation" + id = "flash_powder_flash" + result = null + required_reagents = list("flash_powder" = 1) + required_temp = 374 + +/datum/chemical_reaction/flash_powder_flash/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 1, location) + s.start() + for(var/mob/living/carbon/C in get_hearers_in_view(created_volume/10, location)) + if(C.check_eye_prot()) + continue + flick("e_flash", C.flash) + if(get_dist(C, location) < 4) + C.Weaken(5) + continue + C.Stun(5) + +/datum/chemical_reaction/flash_powder/on_reaction(var/datum/reagents/holder, var/created_volume) + if(holder.has_reagent("stabilizing_agent")) + return + var/location = get_turf(holder.my_atom) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 1, location) + s.start() + for(var/mob/living/carbon/C in get_hearers_in_view(created_volume/10, location)) + if(C.check_eye_prot()) + continue + flick("e_flash", C.flash) + if(get_dist(C, location) < 4) + C.Weaken(5) + continue + C.Stun(5) + holder.remove_reagent("flash_powder", created_volume) + +/datum/reagent/smoke_powder + name = "Smoke Powder" + id = "smoke_powder" + description = "Makes a large cloud of smoke that can carry reagents." + reagent_state = LIQUID + color = "#808080" + +/datum/chemical_reaction/smoke_powder + name = "smoke_powder" + id = "smoke_powder" + result = "smoke_powder" + required_reagents = list("potassium" = 1, "sugar" = 1, "phosphorus" = 1) + result_amount = 3 + + +/datum/chemical_reaction/smoke_powder_smoke + name = "smoke_powder_smoke" + id = "smoke_powder_smoke" + result = null + required_reagents = list("smoke_powder" = 1) + required_temp = 374 + secondary = 1 + mob_react = 1 + +/datum/chemical_reaction/smoke_powder_smoke/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + var/datum/effect/effect/system/chem_smoke_spread/S = new /datum/effect/effect/system/chem_smoke_spread + S.attach(location) + playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3) + spawn(0) + if(S) + S.set_up(holder, 10, 0, location) + S.start() + sleep(10) + S.start() + if(holder && holder.my_atom) + holder.clear_reagents() + return + +/datum/chemical_reaction/smoke_powder/on_reaction(var/datum/reagents/holder, var/created_volume) + if(holder.has_reagent("stabilizing_agent")) + return + holder.remove_reagent("smoke_powder", created_volume) + var/location = get_turf(holder.my_atom) + var/datum/effect/effect/system/chem_smoke_spread/S = new /datum/effect/effect/system/chem_smoke_spread + S.attach(location) + playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3) + spawn(0) + if(S) + S.set_up(holder, 10, 0, location) + S.start() + sleep(10) + S.start() + if(holder && holder.my_atom) + holder.clear_reagents() + return + +/datum/reagent/sonic_powder + name = "Sonic Powder" + id = "sonic_powder" + description = "Makes a deafening noise." + reagent_state = LIQUID + color = "#0000FF" + +/datum/chemical_reaction/sonic_powder + name = "sonic_powder" + id = "sonic_powder" + result = "sonic_powder" + required_reagents = list("oxygen" = 1, "cola" = 1, "phosphorus" = 1) + result_amount = 3 + + +/datum/chemical_reaction/sonic_powder_deafen + name = "sonic_powder_deafen" + id = "sonic_powder_deafen" + result = null + required_reagents = list("sonic_powder" = 1) + required_temp = 374 + +/datum/chemical_reaction/sonic_powder_deafen/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + playsound(location, 'sound/effects/bang.ogg', 25, 1) + for(var/mob/living/carbon/C in get_hearers_in_view(created_volume/10, location)) + if(ishuman(C)) + var/mob/living/carbon/human/H = C + if((H.ears && (H.ears.flags & EARBANGPROTECT)) || (H.head && (H.head.flags & HEADBANGPROTECT))) + continue + C.show_message("BANG", 2) + C.Stun(5) + C.Weaken(5) + C.setEarDamage(C.ear_damage + rand(0, 5), max(C.ear_deaf,15)) + if(C.ear_damage >= 15) + C << "Your ears start to ring badly!" + else if(C.ear_damage >= 5) + C << "Your ears start to ring!" + +/datum/chemical_reaction/sonic_powder/on_reaction(var/datum/reagents/holder, var/created_volume) + if(holder.has_reagent("stabilizing_agent")) + return + holder.remove_reagent("sonic_powder", created_volume) + var/location = get_turf(holder.my_atom) + playsound(location, 'sound/effects/bang.ogg', 25, 1) + for(var/mob/living/carbon/C in get_hearers_in_view(created_volume/10, location)) + if(ishuman(C)) + var/mob/living/carbon/human/H = C + if((H.ears && (H.ears.flags & EARBANGPROTECT)) || (H.head && (H.head.flags & HEADBANGPROTECT))) + continue + C.show_message("BANG", 2) + C.Stun(5) + C.Weaken(5) + C.setEarDamage(C.ear_damage + rand(0, 5), max(C.ear_deaf,15)) + if(C.ear_damage >= 15) + C << "Your ears start to ring badly!" + else if(C.ear_damage >= 5) + C << "Your ears start to ring!" + +/datum/reagent/phlogiston + name = "Phlogiston" + id = "phlogiston" + description = "Catches you on fire and makes you ignite." + reagent_state = LIQUID + color = "#FF9999" + +/datum/chemical_reaction/phlogiston + name = "phlogiston" + id = "phlogiston" + result = "phlogiston" + required_reagents = list("phosphorus" = 1, "sacid" = 1, "stable_plasma" = 1) + result_amount = 3 + +/datum/chemical_reaction/phlogiston/on_reaction(var/datum/reagents/holder, var/created_volume) + if(holder.has_reagent("stabilizing_agent")) + return + var/turf/simulated/T = get_turf(holder.my_atom) + if(istype(T)) + T.atmos_spawn_air(SPAWN_HEAT | SPAWN_TOXINS, created_volume) + return + +/datum/reagent/phlogiston/on_mob_life(var/mob/living/M as mob) + if(!M) M = holder.my_atom + M.adjust_fire_stacks(1) + M.IgniteMob() + M.adjustFireLoss(0.2*M.fire_stacks) + ..() + return + +/datum/reagent/napalm + name = "Napalm" + id = "napalm" + description = "Very flammable." + reagent_state = LIQUID + color = "#FF9999" + +/datum/reagent/napalm/on_mob_life(var/mob/living/M as mob) + if(!M) M = holder.my_atom + M.adjust_fire_stacks(1) + ..() + return + +/datum/reagent/napalm/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume) + if(method == TOUCH && isliving(M)) + M.adjust_fire_stacks(7) + return + +/datum/chemical_reaction/napalm + name = "Napalm" + id = "napalm" + result = null + required_reagents = list("aluminium" = 1, "plasma" = 1, "sacid" = 1 ) + result_amount = 1 + +datum/reagent/cryostylane + name = "Cryostylane" + id = "cryostylane" + description = "Comes into existence at 20K. As long as there is sufficient oxygen for it to react with, Cryostylane slowly cools all other reagents in the mob down to 0K." + color = "#B2B2FF" // rgb: 139, 166, 233 + +/datum/chemical_reaction/cryostylane + name = "cryostylane" + id = "cryostylane" + result = "cryostylane" + required_reagents = list("water" = 1, "stable_plasma" = 1, "nitrogen" = 1) + result_amount = 3 + +/datum/chemical_reaction/cryostylane/on_reaction(var/datum/reagents/holder, var/created_volume) + holder.chem_temp = 20 // cools the fuck down + return + + +datum/reagent/cryostylane/on_mob_life(var/mob/living/M as mob) //TODO: code freezing into an ice cube + if(M.reagents.has_reagent("oxygen")) + M.reagents.remove_reagent("oxygen", 1) + M.bodytemperature -= 30 * TEMPERATURE_DAMAGE_COEFFICIENT + ..() + return + +datum/reagent/cryostylane/reaction_turf(var/turf/simulated/T, var/volume) + if(volume >= 5) + for(var/mob/living/simple_animal/slime/M in T) + M.adjustToxLoss(rand(15,30)) + +datum/reagent/pyrosium + name = "Pyrosium" + id = "pyrosium" + description = "Comes into existence at 20K. As long as there is sufficient oxygen for it to react with, Pyrosium slowly cools all other reagents in the mob down to 0K." + color = "#B20000" // rgb: 139, 166, 233 + +/datum/chemical_reaction/pyrosium + name = "pyrosium" + id = "pyrosium" + result = "pyrosium" + required_reagents = list("stable_plasma" = 1, "radium" = 1, "phosphorus" = 1) + result_amount = 3 + +/datum/chemical_reaction/pyrosium/on_reaction(var/datum/reagents/holder, var/created_volume) + holder.chem_temp = 20 // also cools the fuck down + return + +datum/reagent/pyrosium/on_mob_life(var/mob/living/M as mob) + if(M.reagents.has_reagent("oxygen")) + M.reagents.remove_reagent("oxygen", 1) + M.bodytemperature += 30 * TEMPERATURE_DAMAGE_COEFFICIENT + ..() + return diff --git a/code/modules/reagents/Chemistry-Goon-Toxins.dm b/code/modules/reagents/Chemistry-Goon-Toxins.dm index d7066b8abd1..7693d241c0b 100644 --- a/code/modules/reagents/Chemistry-Goon-Toxins.dm +++ b/code/modules/reagents/Chemistry-Goon-Toxins.dm @@ -7,9 +7,9 @@ datum/reagent/polonium name = "Polonium" id = "polonium" - description = "+8 RAD." + description = "Cause significant Radiation damage over time." reagent_state = LIQUID - color = "#CF3600" // rgb: 207, 54, 0 + color = "#CF3600" metabolization_rate = 0.1 datum/reagent/polonium/on_mob_life(var/mob/living/M as mob) @@ -24,7 +24,7 @@ datum/reagent/histamine id = "histamine" description = "A dose-dependent toxin, ranges from annoying to incredibly lethal." reagent_state = LIQUID - color = "#CF3600" // rgb: 207, 54, 0 + color = "#CF3600" metabolization_rate = 0.2 overdose_threshold = 30 @@ -54,9 +54,9 @@ datum/reagent/histamine/overdose_process(var/mob/living/M as mob) datum/reagent/formaldehyde name = "Formaldehyde" id = "formaldehyde" - description = "+1 TOX, 10% chance to decay into 5-15 units of histamine." + description = "Deals a moderate amount of Toxin damage over time. 10% chance to decay into 10-15 histamine." reagent_state = LIQUID - color = "#CF3600" // rgb: 207, 54, 0 + color = "#CF3600" datum/reagent/formaldehyde/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom @@ -78,9 +78,9 @@ datum/reagent/formaldehyde/on_mob_life(var/mob/living/M as mob) datum/reagent/venom name = "Venom" id = "venom" - description = "Scaling TOX and BRUTE damage with dose. 25% chance to decay into 5-10 histamine." + description = "Will deal scaling amounts of Toxin and Brute damage over time. 25% chance to decay into 5-10 histamine." reagent_state = LIQUID - color = "#CF3600" // rgb: 207, 54, 0 + color = "#CF3600" metabolization_rate = 0.2 datum/reagent/venom/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom @@ -95,9 +95,9 @@ datum/reagent/venom/on_mob_life(var/mob/living/M as mob) datum/reagent/neurotoxin2 name = "Neurotoxin" id = "neurotoxin2" - description = "+1 TOX, +1 BRAIN up to 60 before it slows down, confusion, knockout after 17 elapsed cycles." + description = "Deals toxin and brain damage up to 60 before it slows down, causing confusion and a knockout after 17 elapsed cycles." reagent_state = LIQUID - color = "#CF3600" // rgb: 207, 54, 0 + color = "#CF3600" var/cycle_count = 0 metabolization_rate = 1 @@ -117,14 +117,14 @@ datum/reagent/neurotoxin2/on_mob_life(var/mob/living/M as mob) result = "neurotoxin2" required_reagents = list("space_drugs" = 1) result_amount = 1 - required_temp = 370 + required_temp = 674 datum/reagent/cyanide name = "Cyanide" id = "cyanide" - description = "+1.5 TOX, 10% chance of +1 LOSEBREATH, 8% chance of stun and extra +2 TOX." + description = "Deals toxin damage, alongside some oxygen loss. 8% chance of stun and some extra toxin damage." reagent_state = LIQUID - color = "#CF3600" // rgb: 207, 54, 0 + color = "#CF3600" metabolization_rate = 0.1 datum/reagent/cyanide/on_mob_life(var/mob/living/M as mob) @@ -152,7 +152,7 @@ datum/reagent/cyanide/on_mob_life(var/mob/living/M as mob) id = "????" description = "????" reagent_state = LIQUID - color = "#CF3600" // rgb: 207, 54, 0 + color = "#CF3600" metabolization_rate = 0.2 datum/reagent/questionmark/on_mob_life(var/mob/living/M as mob) @@ -164,9 +164,9 @@ datum/reagent/questionmark/on_mob_life(var/mob/living/M as mob) datum/reagent/itching_powder name = "Itching Powder" id = "itching_powder" - description = "Lots of annoying random effects, chances to do BRUTE damage from scratching. 6% chance to decay into 1-3 units of histamine." + description = "Lots of annoying random effects, chances to do some brute damage from scratching. 6% chance to decay into 1-3 units of histamine." reagent_state = LIQUID - color = "#CF3600" // rgb: 207, 54, 0 + color = "#CF3600" metabolization_rate = 0.3 /datum/reagent/itching_powder/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume) @@ -176,13 +176,13 @@ datum/reagent/itching_powder datum/reagent/itching_powder/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom - if(prob(rand(5,50))) + if(prob(27)) M << "You scratch at your head." M.adjustBruteLoss(0.2*REM) - if(prob(rand(5,50))) + if(prob(27)) M << "You scratch at your leg." M.adjustBruteLoss(0.2*REM) - if(prob(rand(5,50))) + if(prob(27)) M << "You scratch at your arm." M.adjustBruteLoss(0.2*REM) if(prob(6)) @@ -204,4 +204,166 @@ datum/reagent/itching_powder/on_mob_life(var/mob/living/M as mob) result = "facid" required_reagents = list("sacid" = 1, "fluorine" = 1, "hydrogen" = 1, "potassium" = 1) result_amount = 4 - required_temp = 380 \ No newline at end of file + required_temp = 380 + +datum/reagent/initropidril + name = "Initropidril" + id = "initropidril" + description = "33% chance to hit with a random amount of toxin damage, 5-10% chances to cause stunning, suffocation, or immediate heart failure." + reagent_state = LIQUID + color = "#CF3600" + metabolization_rate = 0.4 + +datum/reagent/initropidril/on_mob_life(var/mob/living/M as mob) + if(!M) M = holder.my_atom + if(prob(33)) + M.adjustToxLoss(rand(5,25)) + if(prob(7)) + var/picked_option = rand(1,3) + switch(picked_option) + if(1) + M.Stun(3) + M.Weaken(3) + if(2) + M.losebreath += 10 + M.adjustOxyLoss(rand(5,25)) + if(3) + var/mob/living/carbon/human/H = M + if(!H.heart_attack) + H.visible_message("[H] clutches at their chest as if their heart stopped!") + H.heart_attack = 1 // rip in pepperoni + else + H.losebreath += 10 + H.adjustOxyLoss(rand(5,25)) + ..() + return + +datum/reagent/pancuronium + name = "Pancuronium" + id = "pancuronium" + description = "Knocks you out after 30 seconds, 7% chance to cause some oxygen loss." + reagent_state = LIQUID + color = "#CF3600" + metabolization_rate = 0.2 + +datum/reagent/pancuronium/on_mob_life(var/mob/living/M as mob) + if(!M) M = holder.my_atom + if(current_cycle >= 10) + M.SetParalysis(3) + if(prob(7)) + M.losebreath += rand(3,5) + ..() + return + +datum/reagent/sodium_thiopental + name = "Sodium Thiopental" + id = "sodium_thiopental" + description = "Puts you to sleep after 30 seconds, along with some major stamina loss." + reagent_state = LIQUID + color = "#CF3600" + metabolization_rate = 0.7 + +datum/reagent/sodium_thiopental/on_mob_life(var/mob/living/M as mob) + if(!M) M = holder.my_atom + if(current_cycle >= 10) + M.sleeping += 3 + M.adjustStaminaLoss(10) + ..() + return + +datum/reagent/sulfonal + name = "Sulfonal" + id = "sulfonal" + description = "Deals some toxin damage, and puts you to sleep after 66 seconds." + reagent_state = LIQUID + color = "#CF3600" + metabolization_rate = 0.1 + +/datum/chemical_reaction/sulfonal + name = "sulfonal" + id = "sulfonal" + result = "sulfonal" + required_reagents = list("acetone" = 1, "diethylamine" = 1, "sulfur" = 1) + result_amount = 3 + +datum/reagent/sulfonal/on_mob_life(var/mob/living/M as mob) + if(!M) M = holder.my_atom + if(current_cycle >= 22) + M.sleeping += 3 + M.adjustToxLoss(1) + ..() + return + +datum/reagent/amanitin + name = "Amanitin" + id = "amanitin" + description = "On the last second that it's in you, it hits you with a stack of toxin damage based on how long it's been in you. The more you use, the longer it takes before anything happens, but the harder it hits when it does." + reagent_state = LIQUID + color = "#CF3600" + +datum/reagent/amanitin/on_mob_life(var/mob/living/M as mob) + if(!M) M = holder.my_atom + ..() + return + +datum/reagent/amanitin/on_mob_delete(var/mob/living/M as mob) + if(!M) M = holder.my_atom + M.adjustToxLoss(current_cycle*rand(2,4)) + ..() + +datum/reagent/lipolicide + name = "Lipolicide" + id = "lipolicide" + description = "Deals some toxin damage unless they keep eating food. Will reduce nutrition values." + reagent_state = LIQUID + color = "#CF3600" + +/datum/chemical_reaction/lipolicide + name = "lipolicide" + id = "lipolicide" + result = "lipolicide" + required_reagents = list("mercury" = 1, "diethylamine" = 1, "ephedrine" = 1) + result_amount = 3 + +datum/reagent/lipolicide/on_mob_life(var/mob/living/M as mob) + if(!M) M = holder.my_atom + if(!holder.has_reagent("nutriment")) + M.adjustToxLoss(1) + M.nutrition -= 10 * REAGENTS_METABOLISM + M.overeatduration = 0 + if(M.nutrition < 0)//Prevent from going into negatives. + M.nutrition = 0 + ..() + return + +datum/reagent/coniine + name = "Coniine" + id = "coniine" + description = "Does moderate toxin damage and oxygen loss." + reagent_state = LIQUID + color = "#CF3600" + metabolization_rate = 0.05 + +datum/reagent/coniine/on_mob_life(var/mob/living/M as mob) + if(!M) M = holder.my_atom + M.losebreath += 5 + M.adjustToxLoss(2) + ..() + return + +datum/reagent/curare + name = "Curare" + id = "curare" + description = "Does some oxygen and toxin damage, weakens you after 33 seconds." + reagent_state = LIQUID + color = "#CF3600" + metabolization_rate = 0.1 + +datum/reagent/curare/on_mob_life(var/mob/living/M as mob) + if(!M) M = holder.my_atom + if(current_cycle >= 11) + M.Weaken(3) + M.adjustToxLoss(1) + M.adjustOxyLoss(1) + ..() + return \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/Chemistry-Holder.dm index 6041066d737..48ddea37276 100644 --- a/code/modules/reagents/Chemistry-Holder.dm +++ b/code/modules/reagents/Chemistry-Holder.dm @@ -51,6 +51,15 @@ datum/reagents/New(maximum=100) chemical_reactions_list[id] += D break // Don't bother adding ourselves to other reagent ids, it is redundant. +datum/reagents/Destroy() + ..() + for(var/datum/reagent/R in reagent_list) + qdel(R) + reagent_list.Cut() + reagent_list = null + if(my_atom && my_atom.reagents == src) + my_atom.reagents = null + datum/reagents/proc/remove_any(var/amount=1) var/total_transfered = 0 var/current_list_element = 1 @@ -356,19 +365,18 @@ datum/reagents/proc/isolate_reagent(var/reagent) update_total() datum/reagents/proc/del_reagent(var/reagent) - for(var/A in reagent_list) - var/datum/reagent/R = A + for(var/datum/reagent/R in reagent_list) if (R.id == reagent) - reagent_list -= A - del(A) + if(istype(my_atom, /mob/living)) + var/mob/living/M = my_atom + R.on_mob_delete(M) + qdel(R) + reagent_list -= R update_total() my_atom.on_reagent_change() check_ignoreslow(my_atom) check_gofast(my_atom) check_goreallyfast(my_atom) - return 0 - - return 1 datum/reagents/proc/check_ignoreslow(var/mob/M) @@ -380,7 +388,7 @@ datum/reagents/proc/check_ignoreslow(var/mob/M) datum/reagents/proc/check_gofast(var/mob/M) if(istype(M, /mob)) - if(M.reagents.has_reagent("unholywater")||M.reagents.has_reagent("nuka_cola")||M.reagents.has_reagent("hotline")) + if(M.reagents.has_reagent("unholywater")||M.reagents.has_reagent("nuka_cola")) return 1 else M.status_flags &= ~GOTTAGOFAST @@ -532,12 +540,6 @@ datum/reagents/proc/remove_all_type(var/reagent_type, var/amount, var/strict = 0 return has_removed_reagent -datum/reagents/proc/delete() - for(var/datum/reagent/R in reagent_list) - R.holder = null - if(my_atom) - my_atom.reagents = null - //two helper functions to preserve data across reactions (needed for xenoarch) datum/reagents/proc/get_data(var/reagent_id) for(var/datum/reagent/D in reagent_list) @@ -578,6 +580,6 @@ datum/reagents/proc/copy_data(var/datum/reagent/current_reagent) // Max vol is maximum volume of holder atom/proc/create_reagents(var/max_vol) if(reagents) - reagents.delete() + qdel(reagents) reagents = new/datum/reagents(max_vol) reagents.my_atom = src diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index a23de90b69c..68118cdbcf4 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -575,6 +575,67 @@ desc = "Used to create condiments and other cooking supplies." condi = 1 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/obj/machinery/chem_master/constructable + name = "ChemMaster 2999" + desc = "Used to seperate chemicals and distribute them in a variety of forms." + +/obj/machinery/chem_master/constructable/New() + ..() + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/chem_master(null) + component_parts += new /obj/item/weapon/stock_parts/manipulator(null) + component_parts += new /obj/item/weapon/stock_parts/console_screen(null) + component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(null) + component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(null) + +/obj/machinery/chem_master/constructable/attackby(var/obj/item/B as obj, var/mob/user as mob, params) + + if(default_deconstruction_screwdriver(user, "mixer0_nopower", "mixer0_", B)) + if(beaker) + beaker.loc = src.loc + beaker = null + reagents.clear_reagents() + if(loaded_pill_bottle) + loaded_pill_bottle.loc = src.loc + loaded_pill_bottle = null + return + + if(exchange_parts(user, B)) + return + + if(panel_open) + if(istype(B, /obj/item/weapon/crowbar)) + default_deconstruction_crowbar(B) + return 1 + else + user << "You can't use the [src.name] while it's panel is opened." + return 1 + + if(istype(B, /obj/item/weapon/reagent_containers/glass)) + if(src.beaker) + user << "A beaker is already loaded into the machine." + return + src.beaker = B + user.drop_item() + B.loc = src + user << "You add the beaker to the machine!" + src.updateUsrDialog() + icon_state = "mixer1" + + else if(!condi && istype(B, /obj/item/weapon/storage/pill_bottle)) + if(src.loaded_pill_bottle) + user << "A pill bottle is already loaded into the machine." + return + src.loaded_pill_bottle = B + user.drop_item() + B.loc = src + user << "You add the pill bottle into the dispenser slot!" + src.updateUsrDialog() + + return + //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// @@ -922,6 +983,7 @@ obj/machinery/computer/pandemic/proc/replicator_cooldown(var/waittime) /obj/item/weapon/reagent_containers/food/snacks/grown/wheat = list("flour" = -5), /obj/item/weapon/reagent_containers/food/snacks/grown/oat = list("flour" = -5), /obj/item/weapon/reagent_containers/food/snacks/grown/cherries = list("cherryjelly" = 0), + /obj/item/weapon/reagent_containers/food/snacks/egg = list("eggyolk" = -5), //Grinder stuff, but only if dry /obj/item/weapon/reagent_containers/food/snacks/grown/coffee/arabica = list("coffeepowder" = 0), diff --git a/code/modules/reagents/Chemistry-Reagents/Blob-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Blob-Reagents.dm index 0e8e44ee1ed..0ddd41ef092 100644 --- a/code/modules/reagents/Chemistry-Reagents/Blob-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Blob-Reagents.dm @@ -81,10 +81,11 @@ datum/reagent/blob/acid datum/reagent/blob/acid/reaction_mob(var/mob/living/M as mob, var/method=TOUCH, var/volume, var/show_message = 1) if(method == TOUCH) - M.acid_act(10,1,5) + if(prob(50)) + M.acid_act(5,1,5) + if(show_message) + M << "The blob's tendrils melt through your equipment!" M.apply_damage(10, BRUTE) - if(show_message) - M << "The blob's tendrils melt though your equipment!" datum/reagent/blob/radioactive_liquid name = "Radioactive Liquid" diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents.dm index 79a43aa5d05..85bc7b597ff 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents.dm @@ -19,9 +19,9 @@ datum/reagent var/datum/reagents/holder = null var/reagent_state = LIQUID var/list/data + var/current_cycle = 0 var/volume = 0 - //var/list/viruses = list() - var/color = "#000000" // rgb: 0, 0, 0 (does not support alpha channels - yet!) + var/color = "#000000" // rgb: 0, 0, 0 var/can_synth = 1 var/metabolization_rate = REAGENTS_METABOLISM var/overrides_metab = 0 @@ -30,6 +30,10 @@ datum/reagent var/addiction_stage = 0 var/overdosed = 0 // You fucked up and this is now triggering it's overdose effects, purge that shit quick. +datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references + ..() + holder = null + datum/reagent/proc/reaction_mob(var/mob/M, var/method=TOUCH, var/volume, var/show_message = 1) //By default we have a chance to transfer some if(!istype(M, /mob/living)) return 0 @@ -74,11 +78,16 @@ datum/reagent/proc/reaction_turf(var/turf/T, var/volume) return datum/reagent/proc/on_mob_life(var/mob/living/M as mob) + current_cycle++ if(!istype(M, /mob/living)) return //Noticed runtime errors from facid trying to damage ghosts, this should fix. --NEO holder.remove_reagent(src.id, metabolization_rate * M.metabolism_efficiency) //By default it slowly disappears. return +// Called when this reagent is removed while inside a mob +datum/reagent/proc/on_mob_delete(mob/M) + return + datum/reagent/proc/on_move(var/mob/M) return @@ -117,7 +126,7 @@ datum/reagent/proc/addiction_act_stage3(var/mob/living/M as mob) datum/reagent/proc/addiction_act_stage4(var/mob/living/M as mob) if(prob(30)) - M << "You're not feeling good at all! You really need some [name]." + M << "You're not feeling good at all! You really need some [name]." return datum/reagent/blood @@ -208,14 +217,6 @@ datum/reagent/blood/reaction_turf(var/turf/simulated/T, var/volume)//splash the newVirus.holder = blood_prop return -/* Must check the transfering of reagents and their data first. They all can point to one disease datum. - - Del() - if(src.data["virus"]) - var/datum/disease/D = src.data["virus"] - D.cure(0) - ..() -*/ datum/reagent/vaccine //data must contain virus type name = "Vaccine" @@ -251,7 +252,7 @@ datum/reagent/water/reaction_turf(var/turf/simulated/T, var/volume) if(volume >= 10) T.MakeSlippery() - for(var/mob/living/carbon/slime/M in T) + for(var/mob/living/simple_animal/slime/M in T) M.apply_water() var/hotspot = (locate(/obj/effect/hotspot) in T) @@ -261,12 +262,10 @@ datum/reagent/water/reaction_turf(var/turf/simulated/T, var/volume) G.temperature = max(min(G.temperature-(CT*1000),G.temperature/CT),0) G.react() qdel(hotspot) - T.color = initial(T.color) return datum/reagent/water/reaction_obj(var/obj/O, var/volume) src = null - O.color = initial(O.color) if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/monkeycube)) var/obj/item/weapon/reagent_containers/food/snacks/monkeycube/cube = O if(!cube.wrapped) @@ -276,7 +275,6 @@ datum/reagent/water/reaction_obj(var/obj/O, var/volume) datum/reagent/water/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume)//Splashing people with water can help put them out! if(!istype(M, /mob/living)) return - M.color = initial(M.color) if(method == TOUCH) M.adjust_fire_stacks(-(volume / 10)) if(M.fire_stacks <= 0) @@ -676,16 +674,14 @@ datum/reagent/space_cleaner/reaction_obj(var/obj/O, var/volume) else if(O) O.clean_blood() - O.color = initial(O.color) datum/reagent/space_cleaner/reaction_turf(var/turf/T, var/volume) if(volume >= 1) T.clean_blood() - T.color = initial(T.color) for(var/obj/effect/decal/cleanable/C in T) qdel(C) - for(var/mob/living/carbon/slime/M in T) + for(var/mob/living/simple_animal/slime/M in T) M.adjustToxLoss(rand(5,10)) if(istype(T, /turf/simulated/floor)) var/turf/simulated/floor/F = T @@ -695,7 +691,6 @@ datum/reagent/space_cleaner/reaction_turf(var/turf/T, var/volume) datum/reagent/space_cleaner/reaction_mob(var/mob/M, var/method=TOUCH, var/volume) if(iscarbon(M)) var/mob/living/carbon/C = M - C.color = initial(C.color) if(C.r_hand) C.r_hand.clean_blood() if(C.l_hand) diff --git a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Drink-Reagents/Alcohols.dm b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Drink-Reagents/Alcohols.dm index 600de7a525c..f494d01b409 100644 --- a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Drink-Reagents/Alcohols.dm +++ b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Drink-Reagents/Alcohols.dm @@ -22,18 +22,16 @@ datum/reagent/consumable/ethanol var/boozepwr = 10 //lower numbers mean the booze will have an effect faster. datum/reagent/consumable/ethanol/on_mob_life(var/mob/living/M as mob) - if(!data) - data = 1 - data++ + current_cycle++ M.jitteriness = max(M.jitteriness-5,0) - if(data >= boozepwr) + if(current_cycle >= boozepwr) if (!M.slurring) M.slurring = 1 M.slurring += 4 M.Dizzy(5) - if(data >= boozepwr*2.5 && prob(33)) + if(current_cycle >= boozepwr*2.5 && prob(33)) if (!M.confused) M.confused = 1 M.confused += 3 - if(data >= boozepwr*10 && prob(33)) + if(current_cycle >= boozepwr*10 && prob(33)) M.adjustToxLoss(2) ..() return diff --git a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Drink-Reagents/Drinks.dm b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Drink-Reagents/Drinks.dm index 3e5ddf8d0dc..87496ff1a82 100644 --- a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Drink-Reagents/Drinks.dm +++ b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Drink-Reagents/Drinks.dm @@ -53,15 +53,13 @@ datum/reagent/consumable/carrotjuice datum/reagent/consumable/carrotjuice/on_mob_life(var/mob/living/M as mob) M.eye_blurry = max(M.eye_blurry-1 , 0) M.eye_blind = max(M.eye_blind-1 , 0) - if(!data) - data = 1 - switch(data) + switch(current_cycle) if(1 to 20) //nothing if(21 to INFINITY) - if (prob(data-10)) + if (prob(current_cycle-10)) M.disabilities &= ~NEARSIGHT - data++ + current_cycle++ ..() return @@ -418,10 +416,8 @@ datum/reagent/consumable/atomicbomb/on_mob_life(var/mob/living/M as mob) if (!M.slurring) M.slurring = 1 M.slurring += 3 - if(!data) - data = 1 - data++ - switch(data) + current_cycle++ + switch(current_cycle) if(51 to 200) M.sleeping += 1 if(201 to INFINITY) @@ -437,19 +433,17 @@ datum/reagent/consumable/gargle_blaster color = "#664300" // rgb: 102, 67, 0 datum/reagent/consumable/gargle_blaster/on_mob_life(var/mob/living/M as mob) - if(!data) - data = 1 - data++ + current_cycle++ M.dizziness +=6 - if(data >= 15 && data <45) + if(current_cycle >= 15 && current_cycle <45) if (!M.slurring) M.slurring = 1 M.slurring += 3 - else if(data >= 45 && prob(50) && data <55) + else if(current_cycle >= 45 && prob(50) && current_cycle <55) M.confused = max(M.confused+3,0) - else if(data >=55) + else if(current_cycle >=55) M.druggy = max(M.druggy, 55) - else if(data >=200) + else if(current_cycle >=200) M.adjustToxLoss(2) ..() return @@ -462,19 +456,17 @@ datum/reagent/consumable/neurotoxin datum/reagent/consumable/neurotoxin/on_mob_life(var/mob/living/carbon/M as mob) M.weakened = max(M.weakened, 3) - if(!data) - data = 1 - data++ + current_cycle++ M.dizziness +=6 - if(data >= 15 && data <45) + if(current_cycle >= 15 && current_cycle <45) if (!M.slurring) M.slurring = 1 M.slurring += 3 - else if(data >= 45 && prob(50) && data <55) + else if(current_cycle >= 45 && prob(50) && current_cycle <55) M.confused = max(M.confused+3,0) - else if(data >=55) + else if(current_cycle >=55) M.druggy = max(M.druggy, 55) - else if(data >=200) + else if(current_cycle >=200) M.adjustToxLoss(2) ..() return @@ -489,10 +481,8 @@ datum/reagent/consumable/hippies_delight datum/reagent/consumable/hippies_delight/on_mob_life(var/mob/living/M as mob) M.druggy = max(M.druggy, 50) - if(!data) - data = 1 - data++ - switch(data) + current_cycle++ + switch(current_cycle) if(1 to 5) if (!M.slurring) M.slurring = 1 M.Dizzy(10) diff --git a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm index 994ef10178d..504f23c54c7 100644 --- a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm @@ -95,27 +95,58 @@ datum/reagent/consumable/capsaicin color = "#B31008" // rgb: 179, 16, 8 datum/reagent/consumable/capsaicin/on_mob_life(var/mob/living/M as mob) - if(!data) - data = 1 - switch(data) + switch(current_cycle) if(1 to 15) M.bodytemperature += 5 * TEMPERATURE_DAMAGE_COEFFICIENT - if(holder.has_reagent("frostoil")) - holder.remove_reagent("frostoil", 5) - if(istype(M, /mob/living/carbon/slime)) + if(holder.has_reagent("cryostylane")) + holder.remove_reagent("cryostylane", 5) + if(isslime(M)) M.bodytemperature += rand(5,20) if(15 to 25) M.bodytemperature += 10 * TEMPERATURE_DAMAGE_COEFFICIENT - if(istype(M, /mob/living/carbon/slime)) + if(isslime(M)) M.bodytemperature += rand(10,20) if(25 to INFINITY) M.bodytemperature += 15 * TEMPERATURE_DAMAGE_COEFFICIENT - if(istype(M, /mob/living/carbon/slime)) + if(isslime(M)) M.bodytemperature += rand(15,20) - data++ ..() return +datum/reagent/consumable/frostoil + name = "Frost Oil" + id = "frostoil" + description = "A special oil that noticably chills the body. Extraced from Icepeppers." + color = "#B31008" // rgb: 139, 166, 233 + +datum/reagent/consumable/frostoil/on_mob_life(var/mob/living/M as mob) + switch(current_cycle) + if(1 to 15) + M.bodytemperature -= 10 * TEMPERATURE_DAMAGE_COEFFICIENT + if(holder.has_reagent("capsaicin")) + holder.remove_reagent("capsaicin", 5) + if(isslime(M)) + M.bodytemperature -= rand(5,20) + if(15 to 25) + M.bodytemperature -= 15 * TEMPERATURE_DAMAGE_COEFFICIENT + if(isslime(M)) + M.bodytemperature -= rand(10,20) + if(25 to INFINITY) + M.bodytemperature -= 20 * TEMPERATURE_DAMAGE_COEFFICIENT + if(prob(1)) + M.emote("shiver") + if(isslime(M)) + M.bodytemperature -= rand(15,20) + ..() + return + +datum/reagent/consumable/frostoil/reaction_turf(var/turf/simulated/T, var/volume) + if(volume >= 5) + for(var/mob/living/simple_animal/slime/M in T) + M.adjustToxLoss(rand(15,30)) + //if(istype(T)) + // T.atmos_spawn_air(SPAWN_COLD) + datum/reagent/consumable/condensedcapsaicin name = "Condensed Capsaicin" id = "condensedcapsaicin" @@ -190,42 +221,6 @@ datum/reagent/consumable/condensedcapsaicin/on_mob_life(var/mob/living/M as mob) ..() return -datum/reagent/consumable/frostoil - name = "Frost Oil" - id = "frostoil" - description = "A special oil that noticably chills the body. Extraced from Icepeppers." - color = "#B31008" // rgb: 139, 166, 233 - -datum/reagent/consumable/frostoil/on_mob_life(var/mob/living/M as mob) - if(!data) data = 1 - switch(data) - if(1 to 15) - M.bodytemperature -= 10 * TEMPERATURE_DAMAGE_COEFFICIENT - if(holder.has_reagent("capsaicin")) - holder.remove_reagent("capsaicin", 5) - if(istype(M, /mob/living/carbon/slime)) - M.bodytemperature -= rand(5,20) - if(15 to 25) - M.bodytemperature -= 15 * TEMPERATURE_DAMAGE_COEFFICIENT - if(istype(M, /mob/living/carbon/slime)) - M.bodytemperature -= rand(10,20) - if(25 to INFINITY) - M.bodytemperature -= 20 * TEMPERATURE_DAMAGE_COEFFICIENT - if(prob(1)) - M.emote("shiver") - if(istype(M, /mob/living/carbon/slime)) - M.bodytemperature -= rand(15,20) - data++ - ..() - return - -datum/reagent/consumable/frostoil/reaction_turf(var/turf/simulated/T, var/volume) - if(volume >= 5) - for(var/mob/living/carbon/slime/M in T) - M.adjustToxLoss(rand(15,30)) - //if(istype(T)) - // T.atmos_spawn_air(SPAWN_COLD) - datum/reagent/consumable/sodiumchloride name = "Table Salt" id = "sodiumchloride" @@ -270,9 +265,7 @@ datum/reagent/mushroomhallucinogen datum/reagent/mushroomhallucinogen/on_mob_life(var/mob/living/M as mob) M.druggy = max(M.druggy, 30) - if(!data) - data = 1 - switch(data) + switch(current_cycle) if(1 to 5) if (!M.slurring) M.slurring = 1 @@ -295,7 +288,7 @@ datum/reagent/mushroomhallucinogen/on_mob_life(var/mob/living/M as mob) M.druggy = max(M.druggy, 40) if(prob(30)) M.emote(pick("twitch","giggle")) - data++ + current_cycle++ ..() return @@ -404,3 +397,9 @@ datum/reagent/consumable/vanilla reagent_state = SOLID nutriment_factor = 5 * REAGENTS_METABOLISM color = "#FFFACD" + +datum/reagent/consumable/eggyolk + name = "Egg Yolk" + id = "eggyolk" + description = "It's full of protein." + color = "#FFB500" diff --git a/code/modules/reagents/Chemistry-Reagents/Medicine-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Medicine-Reagents.dm index 2fc73900f9a..1765a0929af 100644 --- a/code/modules/reagents/Chemistry-Reagents/Medicine-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Medicine-Reagents.dm @@ -14,20 +14,6 @@ datum/reagent/medicine datum/reagent/medicine/on_mob_life(var/mob/living/M as mob) holder.remove_reagent(src.id, metabolization_rate / M.metabolism_efficiency) //medicine reagents stay longer if you have a better metabolism -datum/reagent/medicine/lipozine - name = "Lipozine" // The anti-nutriment. - id = "lipozine" - description = "A chemical compound that causes a powerful fat-burning reaction." - color = "#BBEDA4" // rgb: 187, 237, 164 - -datum/reagent/medicine/lipozine/on_mob_life(var/mob/living/M as mob) - M.nutrition -= 10 * REAGENTS_METABOLISM - M.overeatduration = 0 - if(M.nutrition < 0)//Prevent from going into negatives. - M.nutrition = 0 - ..() - return - datum/reagent/medicine/leporazine name = "Leporazine" id = "leporazine" @@ -141,10 +127,8 @@ datum/reagent/medicine/rezadone color = "#669900" // rgb: 102, 153, 0 datum/reagent/medicine/rezadone/on_mob_life(var/mob/living/M as mob) - if(!data) - data = 1 - data++ - switch(data) + current_cycle++ + switch(current_cycle) if(1 to 15) M.adjustCloneLoss(-1) M.heal_organ_damage(1,1) diff --git a/code/modules/reagents/Chemistry-Reagents/Toxin-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Toxin-Reagents.dm index 79e7cb5308b..96a1095694e 100644 --- a/code/modules/reagents/Chemistry-Reagents/Toxin-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Toxin-Reagents.dm @@ -158,10 +158,8 @@ datum/reagent/toxin/zombiepowder/on_mob_life(var/mob/living/carbon/M as mob) ..() return -datum/reagent/toxin/zombiepowder/Del() - if(holder && ismob(holder.my_atom)) - var/mob/M = holder.my_atom - M.status_flags &= ~FAKEDEATH +datum/reagent/toxin/zombiepowder/on_mob_delete(mob/M) + M.status_flags &= ~FAKEDEATH ..() datum/reagent/toxin/mindbreaker @@ -258,10 +256,8 @@ datum/reagent/toxin/chloralhydrate metabolization_rate = 1.5 * REAGENTS_METABOLISM datum/reagent/toxin/chloralhydrate/on_mob_life(var/mob/living/M as mob) - if(!data) - data = 1 - data++ - switch(data) + current_cycle++ + switch(current_cycle) if(1 to 10) M.confused += 2 M.drowsyness += 2 @@ -269,7 +265,7 @@ datum/reagent/toxin/chloralhydrate/on_mob_life(var/mob/living/M as mob) M.sleeping += 1 if(51 to INFINITY) M.sleeping += 1 - M.adjustToxLoss((data - 50)*REM) + M.adjustToxLoss((current_cycle - 50)*REM) ..() return @@ -281,54 +277,16 @@ datum/reagent/toxin/beer2 //disguised as normal beer for use by emagged brobots metabolization_rate = 1.5 * REAGENTS_METABOLISM datum/reagent/toxin/beer2/on_mob_life(var/mob/living/M as mob) - if(!data) - data = 1 - switch(data) + switch(current_cycle) if(1 to 50) M.sleeping += 1 if(51 to INFINITY) M.sleeping += 1 - M.adjustToxLoss((data - 50)*REM) - data++ + M.adjustToxLoss((current_cycle - 50)*REM) + current_cycle++ ..() return - - -//ACID - - -datum/reagent/toxin/acid - name = "Sulphuric acid" - id = "sacid" - description = "A strong mineral acid with the molecular formula H2SO4." - color = "#DB5008" // rgb: 219, 80, 8 - toxpwr = 1 - var/acidpwr = 10 //the amount of protection removed from the armour - -datum/reagent/toxin/acid/reaction_mob(var/mob/living/carbon/C, var/method=TOUCH, var/volume) - if(!istype(C)) - return - if(method != TOUCH) - if(!C.unacidable) - C.take_organ_damage(min(6*toxpwr, volume * toxpwr)) - return - - C.acid_act(acidpwr, toxpwr, volume) - -datum/reagent/toxin/acid/reaction_obj(var/obj/O, var/volume) - if(istype(O.loc, /mob)) //handled in human acid_act() - return - O.acid_act(acidpwr, toxpwr, volume) - -datum/reagent/toxin/acid/fluacid - name = "Fluorosulfuric acid" - id = "facid" - description = "Fluorosulfuric acid is a an extremely corrosive chemical substance." - color = "#8E18A9" // rgb: 142, 24, 169 - toxpwr = 2 - acidpwr = 20 - datum/reagent/toxin/coffeepowder name = "Coffee Grounds" id = "coffeepowder" @@ -353,7 +311,7 @@ datum/reagent/toxin/mutetoxin //the new zombie powder. toxpwr = 0 datum/reagent/toxin/mutetoxin/on_mob_life(mob/living/carbon/M) - M.silent += REM + 1 //If this var is increased by one or less, it will have no effect since silent is decreased right after reagents are handled in Life(). Hence the + 1. + M.silent = max(M.silent, 3) ..() datum/reagent/toxin/staminatoxin @@ -370,5 +328,38 @@ datum/reagent/toxin/staminatoxin/on_mob_life(mob/living/carbon/M) ..() +//ACID + + +datum/reagent/toxin/acid + name = "Sulphuric acid" + id = "sacid" + description = "A strong mineral acid with the molecular formula H2SO4." + color = "#DB5008" // rgb: 219, 80, 8 + toxpwr = 1 + var/acidpwr = 10 //the amount of protection removed from the armour + +datum/reagent/toxin/acid/reaction_mob(var/mob/living/carbon/C, var/method=TOUCH, var/volume) + if(!istype(C)) + return + if(method != TOUCH) + C.take_organ_damage(min(6*toxpwr, volume * toxpwr)) + return + + C.acid_act(acidpwr, toxpwr, volume) + +datum/reagent/toxin/acid/reaction_obj(var/obj/O, var/volume) + if(istype(O.loc, /mob)) //handled in human acid_act() + return + O.acid_act(acidpwr, toxpwr, volume) + +datum/reagent/toxin/acid/fluacid + name = "Fluorosulfuric acid" + id = "facid" + description = "Fluorosulfuric acid is a an extremely corrosive chemical substance." + color = "#8E18A9" // rgb: 142, 24, 169 + toxpwr = 2 + acidpwr = 20 + // Undefine the alias for REAGENTS_EFFECT_MULTIPLER #undef REM \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index 59764ed8e08..0f99675d8e2 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -58,12 +58,6 @@ silicate required_reagents = list("aluminium" = 1, "silicon" = 1, "oxygen" = 1) result_amount = 3 */ -/datum/chemical_reaction/stoxin - name = "Sleep Toxin" - id = "stoxin" - result = "stoxin" - required_reagents = list("chloralhydrate" = 1, "sugar" = 4) - result_amount = 5 /datum/chemical_reaction/sterilizine name = "Sterilizine" @@ -186,90 +180,6 @@ silicate required_reagents = list("water" = 1, "sodium" = 1, "chlorine" = 1) result_amount = 3 -/datum/chemical_reaction/flash_powder - name = "Flash powder" - id = "flash_powder" - result = null - required_reagents = list("aluminium" = 1, "potassium" = 1, "sulfur" = 1 ) - result_amount = null -/datum/chemical_reaction/flash_powder/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(2, 1, location) - s.start() - for(var/mob/living/carbon/C in get_hearers_in_view(5, location)) - if(C.eyecheck()) - continue - flick("e_flash", C.flash) - if(get_dist(C, location) < 4) - C.Weaken(5) - continue - C.Stun(5) - -/datum/chemical_reaction/napalm - name = "Napalm" - id = "napalm" - result = null - required_reagents = list("aluminium" = 1, "plasma" = 1, "sacid" = 1 ) - result_amount = 1 -/datum/chemical_reaction/napalm/on_reaction(var/datum/reagents/holder, var/created_volume) - var/turf/simulated/T = get_turf(holder.my_atom) - if(istype(T)) - T.atmos_spawn_air(SPAWN_HEAT | SPAWN_TOXINS, created_volume) - holder.del_reagent(id) - return - -/* -/datum/chemical_reaction/smoke - name = "Smoke" - id = "smoke" - result = null - required_reagents = list("potassium" = 1, "sugar" = 1, "phosphorus" = 1 ) - result_amount = null - secondary = 1 - on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - var/datum/effect/system/bad_smoke_spread/S = new /datum/effect/system/bad_smoke_spread - S.attach(location) - S.set_up(10, 0, location) - playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3) - spawn(0) - S.start() - sleep(10) - S.start() - sleep(10) - S.start() - sleep(10) - S.start() - sleep(10) - S.start() - holder.clear_reagents() - return */ - -/datum/chemical_reaction/chemsmoke - name = "Chemsmoke" - id = "chemsmoke" - result = null - required_reagents = list("potassium" = 1, "sugar" = 1, "phosphorus" = 1) - result_amount = null - secondary = 1 - mob_react = 1 - -/datum/chemical_reaction/chemsmoke/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - var/datum/effect/effect/system/chem_smoke_spread/S = new /datum/effect/effect/system/chem_smoke_spread - S.attach(location) - playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3) - spawn(0) - if(S) - S.set_up(holder, 10, 0, location) - S.start() - sleep(10) - S.start() - if(holder && holder.my_atom) - holder.clear_reagents() - return - /datum/chemical_reaction/chloralhydrate name = "Chloral Hydrate" id = "chloralhydrate" @@ -288,7 +198,7 @@ silicate name = "Zombie Powder" id = "zombiepowder" result = "zombiepowder" - required_reagents = list("carpotoxin" = 5, "stoxin" = 5, "copper" = 5) + required_reagents = list("carpotoxin" = 5, "morphine" = 5, "copper" = 5) result_amount = 2 /datum/chemical_reaction/rezadone @@ -305,13 +215,6 @@ silicate required_reagents = list("silicon" = 1, "hydrogen" = 1, "charcoal" = 1) result_amount = 5 -/datum/chemical_reaction/lipozine - name = "Lipozine" - id = "Lipozine" - result = "lipozine" - required_reagents = list("sodiumchloride" = 1, "ethanol" = 1, "radium" = 1) - result_amount = 3 - /datum/chemical_reaction/plasmasolidification name = "Solid Plasma" id = "solidplasma" @@ -530,7 +433,7 @@ datum/chemical_reaction/pestkiller feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") for(var/mob/O in viewers(get_turf(holder.my_atom), null)) O.show_message(text("Infused with plasma, the core begins to quiver and grow, and soon a new baby slime emerges from it!"), 1) - var/mob/living/carbon/slime/S = new /mob/living/carbon/slime + var/mob/living/simple_animal/slime/S = new /mob/living/simple_animal/slime S.loc = get_turf(holder.my_atom) /datum/chemical_reaction/slimeinaprov @@ -640,8 +543,7 @@ datum/chemical_reaction/pestkiller playsound(get_turf(holder.my_atom), 'sound/effects/phasein.ogg', 100, 1) for(var/mob/living/carbon/human/M in viewers(get_turf(holder.my_atom), null)) - if(M:eyecheck() <= 0) - flick("e_flash", M.flash) + M.flash_eyes() for(var/i = 1, i <= 4 + rand(1,2), i++) var/chosen = pick(borks) @@ -671,8 +573,7 @@ datum/chemical_reaction/pestkiller playsound(get_turf(holder.my_atom), 'sound/effects/phasein.ogg', 100, 1) for(var/mob/living/carbon/human/M in viewers(get_turf(holder.my_atom), null)) - if(M:eyecheck() <= 0) - flick("e_flash", M.flash) + M.flash_eyes() for(var/i = 1, i <= 4 + rand(1,2), i++) var/chosen = pick(borks) @@ -854,7 +755,7 @@ datum/chemical_reaction/pestkiller required_other = 1 /datum/chemical_reaction/slimebloodlust/on_reaction(var/datum/reagents/holder) feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") - for(var/mob/living/carbon/slime/slime in viewers(get_turf(holder.my_atom), null)) + for(var/mob/living/simple_animal/slime/slime in viewers(get_turf(holder.my_atom), null)) slime.rabid = 1 for(var/mob/O in viewers(get_turf(holder.my_atom), null)) O.show_message(text("The [slime] is driven into a frenzy!"), 1) diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index c0051eb3b8a..4803a311e33 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -77,21 +77,3 @@ return 0 return 1 - -/obj/item/weapon/reagent_containers/attackby(obj/item/weapon/W as obj, mob/user as mob, params) - if(istype(W,/obj/item/weapon/reagent_containers/food/snacks/egg)) //making dough - var/obj/item/weapon/reagent_containers/food/snacks/egg/E = W - if(flags & OPENCONTAINER) - if(reagents) - if(reagents.has_reagent("flour")) - if(reagents.get_reagent_amount("flour") >= 15) - var/obj/item/weapon/reagent_containers/food/snacks/S = new /obj/item/weapon/reagent_containers/food/snacks/dough(get_turf(src)) - user << "You mix egg and flour to make some dough." - reagents.remove_reagent("flour", 15) - if(E.reagents) - E.reagents.trans_to(S,E.reagents.total_volume) - qdel(E) - else - user << "Not enough flour to make dough." - return - ..() \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/bottle.dm b/code/modules/reagents/reagent_containers/bottle.dm index 239782e0faa..2787742c3fc 100644 --- a/code/modules/reagents/reagent_containers/bottle.dm +++ b/code/modules/reagents/reagent_containers/bottle.dm @@ -141,6 +141,42 @@ icon_state = "bottle16" list_reagents = list("formaldehyde" = 30) +/obj/item/weapon/reagent_containers/glass/bottle/initropidril + name = "initropidril bottle" + desc = "A small bottle. Contains initropidril." + icon_state = "bottle16" + list_reagents = list("initropidril" = 30) + +/obj/item/weapon/reagent_containers/glass/bottle/pancuronium + name = "pancuronium bottle" + desc = "A small bottle. Contains pancuronium." + icon_state = "bottle16" + list_reagents = list("pancuronium" = 30) + +/obj/item/weapon/reagent_containers/glass/bottle/sodium_thiopental + name = "sodium thiopental bottle" + desc = "A small bottle. Contains sodium thiopental." + icon_state = "bottle16" + list_reagents = list("sodium_thiopental" = 30) + +/obj/item/weapon/reagent_containers/glass/bottle/coniine + name = "coniine bottle" + desc = "A small bottle. Contains coniine." + icon_state = "bottle16" + list_reagents = list("coniine" = 30) + +/obj/item/weapon/reagent_containers/glass/bottle/curare + name = "curare bottle" + desc = "A small bottle. Contains curare." + icon_state = "bottle16" + list_reagents = list("curare" = 30) + +/obj/item/weapon/reagent_containers/glass/bottle/amanitin + name = "amanitin bottle" + desc = "A small bottle. Contains amanitin." + icon_state = "bottle16" + list_reagents = list("amanitin" = 30) + /obj/item/weapon/reagent_containers/glass/bottle/histamine name = "histamine bottle" desc = "A small bottle. Contains Histamine." diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index 7079ae6bf26..365ce4e9b70 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -80,6 +80,7 @@ user << "You transfer [trans] unit\s of the solution to [target]." //Safety for dumping stuff into a ninja suit. It handles everything through attackby() and this is unnecessary. //gee thanks noize + //NINJACODE else if(istype(target, /obj/item/clothing/suit/space/space_ninja)) return @@ -101,6 +102,17 @@ reagents.handle_reactions() else user << "[src] is already hotter than [I]." + + if(istype(I,/obj/item/weapon/reagent_containers/food/snacks/egg)) //breaking eggs + var/obj/item/weapon/reagent_containers/food/snacks/egg/E = I + if(reagents) + if(reagents.total_volume >= reagents.maximum_volume) + user << "[src] is full." + else + user << "You break [E] in [src]." + reagents.add_reagent("eggyolk", 5) + qdel(E) + return ..() diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 6eae3e52b29..43484c7cc4b 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -62,19 +62,36 @@ /obj/item/weapon/reagent_containers/spray/proc/spray(var/atom/A) + var/range = max(min(spray_currentrange, get_dist(src, A)), 1) var/obj/effect/decal/chempuff/D = new /obj/effect/decal/chempuff(get_turf(src)) D.create_reagents(amount_per_transfer_from_this) - reagents.trans_to(D, amount_per_transfer_from_this, 1/spray_currentrange) + reagents.trans_to(D, amount_per_transfer_from_this, 1/range) D.color = mix_color_from_reagents(D.reagents.reagent_list) - spawn(0) - for(var/i=0, i 0) + D.reagents.reaction(get_turf(D)) + puff_reagent_left -= 1 + + if(puff_reagent_left <= 0) // we used all the puff so we delete it. + qdel(D) + return + qdel(D) /obj/item/weapon/reagent_containers/spray/attack_self(var/mob/user) @@ -146,41 +163,16 @@ /obj/item/weapon/reagent_containers/spray/chemsprayer/spray(var/atom/A) - var/Sprays[3] - for(var/i=1, i<=3, i++) // intialize sprays - if(src.reagents.total_volume < 1) break - var/obj/effect/decal/chempuff/D = new/obj/effect/decal/chempuff(get_turf(src)) - D.create_reagents(amount_per_transfer_from_this) - src.reagents.trans_to(D, amount_per_transfer_from_this) - - D.color = mix_color_from_reagents(D.reagents.reagent_list) - - Sprays[i] = D - var/direction = get_dir(src, A) var/turf/T = get_turf(A) var/turf/T1 = get_step(T,turn(direction, 90)) var/turf/T2 = get_step(T,turn(direction, -90)) var/list/the_targets = list(T,T1,T2) - for(var/i=1, i<=Sprays.len, i++) - spawn() - var/obj/effect/decal/chempuff/D = Sprays[i] - if(!D) continue - - // Spreads the sprays a little bit - var/turf/my_target = pick(the_targets) - the_targets -= my_target - - for(var/j=0, j<=spray_currentrange, j++) - step_towards(D, my_target) - D.reagents.reaction(get_turf(D)) - for(var/atom/t in get_turf(D)) - D.reagents.reaction(t) - sleep(2) - qdel(D) - - + for(var/i=1, i<=3, i++) // intialize sprays + if(reagents.total_volume < 1) + return + ..(the_targets[i]) /obj/item/weapon/reagent_containers/spray/chemsprayer/attack_self(var/mob/user) diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 2a5353b3085..5c2928a6556 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -67,12 +67,12 @@ return if(2.0) if (prob(50)) - new /obj/effect/effect/water(src.loc) + PoolOrNew(/obj/effect/effect/water, src.loc) qdel(src) return if(3.0) if (prob(5)) - new /obj/effect/effect/water(src.loc) + PoolOrNew(/obj/effect/effect/water, src.loc) qdel(src) return else @@ -80,7 +80,7 @@ /obj/structure/reagent_dispensers/watertank/blob_act() if(prob(50)) - new /obj/effect/effect/water(src.loc) + PoolOrNew(/obj/effect/effect/water, loc) qdel(src) /obj/structure/reagent_dispensers/fueltank diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index ef4b2049d97..b7815cfad11 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -115,10 +115,6 @@ else return - if(istype(I, /obj/item/weapon/melee/energy/blade)) - user << "You can't place \the [I] into \the [src]." - return - if(istype(I, /obj/item/weapon/storage/bag/trash)) var/obj/item/weapon/storage/bag/trash/T = I user << " You empty the bag." @@ -152,7 +148,7 @@ /obj/machinery/disposal/proc/stuff_mob_in(mob/living/target, mob/living/user) if(!iscarbon(user) && !user.ventcrawler) //only carbon and ventcrawlers can climb into disposal by themselves. return - if(target.mob_size > 1) + if(target.mob_size > MOB_SIZE_HUMAN) user << "[target] doesn't fit inside [src]." return src.add_fingerprint(user) diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index 13f4a491588..de964360207 100644 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -190,7 +190,7 @@ /obj/item/device/destTagger name = "destination tagger" desc = "Used to set the destination of properly wrapped packages." - icon_state = "forensic0" + icon_state = "cargotagger" var/currTag = 0 //The whole system for the sorttype var is determined based on the order of this list, //disposals must always be 1, since anything that's untagged will automatically go to disposals, or sorttype = 1 --Superxpdude diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm index c6c852b409a..1cf5dc99795 100644 --- a/code/modules/research/designs/autolathe_designs.dm +++ b/code/modules/research/designs/autolathe_designs.dm @@ -386,6 +386,14 @@ build_path = /obj/item/device/assembly/prox_sensor category = list("initial", "Misc") +/datum/design/foam_dart + name = "Box of Foam Darts" + id = "foam_dart" + build_type = AUTOLATHE + materials = list("$metal" = 500) + build_path = /obj/item/ammo_box/foambox + category = list("initial", "Misc") + //hacked autolathe recipes /datum/design/flamethrower name = "Flamethrower" diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index ff5e33b0ef3..ee333ef117b 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -6,7 +6,7 @@ name = "Machine Design (SMES Board)" desc = "The circuit board for a SMES." id = "smes" - req_tech = list("programming" = 4, "power" = 5, "engineering" = 4) + req_tech = list("programming" = 4, "powerstorage" = 5, "engineering" = 4) build_type = IMPRINTER materials = list("$glass" = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/smes @@ -16,7 +16,7 @@ name = "Computer Design (Power Turbine Console Board)" desc = "The circuit board for a power turbine console." id = "power_turbine_console" - req_tech = list("programming" = 4, "power" = 4, "engineering" = 4) + req_tech = list("programming" = 4, "powerstorage" = 4, "engineering" = 4) build_type = IMPRINTER materials = list("$glass" = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/turbine_computer @@ -26,7 +26,7 @@ name = "Machine Design (Power Compressor Board)" desc = "The circuit board for a power compressor." id = "power_compressor" - req_tech = list("programming" = 4, "power" = 5, "engineering" = 4) + req_tech = list("programming" = 4, "powerstorage" = 5, "engineering" = 4) build_type = IMPRINTER materials = list("$glass" = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/power_compressor @@ -36,7 +36,7 @@ name = "Machine Design (Power Turbine Board)" desc = "The circuit board for a power turbine." id = "power_turbine" - req_tech = list("programming" = 4, "power" = 4, "engineering" = 5) + req_tech = list("programming" = 4, "powerstorage" = 4, "engineering" = 5) build_type = IMPRINTER materials = list("$glass" = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/power_turbine @@ -111,6 +111,16 @@ materials = list("$glass" = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/chem_dispenser category = list ("Medical Machinery") + +/datum/design/chem_master + name = "Machine Design (Chem Master Board)" + desc = "The circuit board for a Chem Master 2999." + id = "chem_master" + req_tech = list("biotech" = 1, "materials" = 2, "programming" = 2) + build_type = IMPRINTER + materials = list("$glass" = 1000, "sacid" = 20) + build_path = /obj/item/weapon/circuitboard/chem_master + category = list ("Medical Machinery") /datum/design/chem_heater name = "Machine Design (Chemical Heater Board)" diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index b04f53bdff7..73eab21ea2e 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -640,7 +640,7 @@ id = "borg_upgrade_disablercooler" build_type = MECHFAB build_path = /obj/item/borg/upgrade/disablercooler - req_tech = list("combat" = 5, "power" = 4) + req_tech = list("combat" = 5, "powerstorage" = 4) materials = list("$metal"=80000 , "$glass"=6000 , "$gold"= 2000, "$diamond" = 500) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -650,7 +650,7 @@ id = "borg_upgrade_jetpack" build_type = MECHFAB build_path = /obj/item/borg/upgrade/jetpack - req_tech = list("engineering" = 4, "power" = 4) + req_tech = list("engineering" = 4, "powerstorage" = 4) materials = list("$metal"=10000, "$plasma"=5000, "$uranium" = 6000) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -665,6 +665,16 @@ construction_time = 120 category = list("Cyborg Upgrade Modules") +/datum/design/borg_upgrade_holding + name = "Cyborg Upgrade (Ore Satchel of Holding)" + id = "borg_upgrade_holding" + build_type = MECHFAB + build_path = /obj/item/borg/upgrade/soh + req_tech = list("engineering" = 5, "materials" = 5, "bluespace" = 3) + materials = list("$metal" = 10000, "$gold" = 250, "$uranium" = 500) + construction_time = 120 + category = list("Cyborg Upgrade Modules") + /datum/design/borg_syndicate_module name = "Cyborg Illegal Upgrades Module" desc = "Allows for the construction of restricted upgrades for cyborgs" diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 1e8e50a3be1..2c7ae702d64 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -92,3 +92,68 @@ datum/design/bluespacebodybag reliability = 76 build_path = /obj/item/bodybag/bluespace category = list("Medical Designs") + + +///////////////////////////////////////// +//////////Cybernetic Implants//////////// +///////////////////////////////////////// + +/datum/design/cyberimp_medical_hud + name = "Medical HUD implant" + desc = "These cybernetic eyes will display a medical HUD over everything you see. Wiggle eyes to control." + id = "ci-medhud" + req_tech = list("materials" = 5, "programming" = 4, "biotech" = 4) + build_type = PROTOLATHE | MECHFAB + materials = list("$metal" = 200, "$glass" = 200, "$silver" = 200, "$gold" = 100) + build_path = /obj/item/cybernetic_implant/eyes/hud/medical + category = list("Medical Designs") + +/datum/design/cyberimp_security_hud + name = "Security HUD implant" + desc = "These cybernetic eyes will display a security HUD over everything you see. Wiggle eyes to control." + id = "ci-sechud" + req_tech = list("materials" = 5, "programming" = 5, "biotech" = 5, "combat" = 2) + build_type = PROTOLATHE | MECHFAB + materials = list("$metal" = 200, "$glass" = 200, "$silver" = 300, "$gold" = 300) + build_path = /obj/item/cybernetic_implant/eyes/hud/security + category = list("Medical Designs") + +/datum/design/cyberimp_xray + 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" = 5, "magnets" = 5, "plasmatech" = 3) + build_type = PROTOLATHE | MECHFAB + materials = list("$metal" = 200, "$glass" = 200, "$silver" = 200, "$gold" = 200, "$plasma" = 200, "$diamond" = 500) + build_path = /obj/item/cybernetic_implant/eyes/xray + category = list("Medical Designs") + +/datum/design/cyberimb_thermals + 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) + build_type = PROTOLATHE | MECHFAB + materials = list("$metal" = 200, "$glass" = 200, "$silver" = 200, "$gold" = 200, "$plasma" = 200, "$diamond" = 500) + build_path = /obj/item/cybernetic_implant/eyes/thermals + category = list("Medical Designs") + +/datum/design/cyberimb_antidrop + name = "Anti-Drop implant" + desc = "This cybernetic brain implant will allow you to force your hand muscles to contract, preventing item dropping. Twitch ear to toggle." + id = "ci-antidrop" + req_tech = list("materials" = 6, "programming" = 5, "biotech" = 5) + build_type = PROTOLATHE | MECHFAB + materials = list("$metal" = 200, "$glass" = 200, "$silver" = 400, "$gold" = 400) + build_path = /obj/item/cybernetic_implant/brain/anti_drop + category = list("Medical Designs") + +/datum/design/cyberimb_antistun + name = "CNS Rebooter implant" + desc = "This implant will automatically give you back control over your central nervous system, reducing downtime when stunned." + id = "ci-antistun" + req_tech = list("materials" = 6, "programming" = 5, "biotech" = 5) + build_type = PROTOLATHE | MECHFAB + materials = list("$metal" = 200, "$glass" = 200, "$silver" = 400, "$gold" = 600) + build_path = /obj/item/cybernetic_implant/brain/anti_stun + category = list("Medical Designs") \ No newline at end of file diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index 62aca6fca2a..42fcc6c1b1f 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -16,7 +16,7 @@ name = "loyalty firing pin" desc = "This is a security firing pin which only authorizes users who are loyalty-implanted." id = "pin_loyalty" - req_tech = list("combat" = 10, "materials" = 3, "powerstorage" = 3) + req_tech = list("combat" = 6, "materials" = 6, "powerstorage" = 3) build_type = PROTOLATHE materials = list("$silver" = 600, "$diamond" = 600, "$uranium" = 200) build_path = /obj/item/device/firing_pin/implant/loyalty diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index f61f7a59e99..5dc00bd72e0 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -92,8 +92,8 @@ component_parts += new /obj/item/weapon/stock_parts/manipulator(src) component_parts += new /obj/item/weapon/stock_parts/micro_laser(src) component_parts += new /obj/item/weapon/stock_parts/micro_laser(src) - trackedIan = locate(/mob/living/simple_animal/corgi/Ian) in mob_list - trackedRuntime = locate(/mob/living/simple_animal/cat/Runtime) in mob_list + trackedIan = locate(/mob/living/simple_animal/pet/corgi/Ian) in mob_list + trackedRuntime = locate(/mob/living/simple_animal/pet/cat/Runtime) in mob_list SetTypeReactions() RefreshParts() @@ -325,7 +325,7 @@ smoke.set_up(R, 1, 0, src, 0, silent = 1) playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3) smoke.start() - R.delete() + qdel(R) ejectItem(TRUE) if(prob(EFFECT_PROB_VERYLOW-badThingCoeff)) visible_message("[src]'s chemical chamber has sprung a leak!") @@ -337,7 +337,7 @@ smoke.set_up(R, 1, 0, src, 0, silent = 1) playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3) smoke.start() - R.delete() + qdel(R) ejectItem(TRUE) warn_admins(usr, "[chosenchem] smoke") investigate_log("Experimentor has released [chosenchem] smoke!", "experimentor") @@ -424,7 +424,7 @@ smoke.set_up(R, 1, 0, src, 0, silent = 1) playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3) smoke.start() - R.delete() + qdel(R) ejectItem(TRUE) if(prob(EFFECT_PROB_LOW-badThingCoeff)) visible_message("[src] malfunctions, shattering [exp_on] and leaking cold air!.") @@ -510,7 +510,7 @@ trackedIan.loc = src.loc investigate_log("Experimentor has stolen Ian!", "experimentor") //...if anyone ever fixes it... else - new /mob/living/simple_animal/corgi(src.loc) + new /mob/living/simple_animal/pet/corgi(src.loc) investigate_log("Experimentor has spawned a new corgi.", "experimentor") ejectItem(TRUE) if(globalMalf > 36 && globalMalf < 50) @@ -532,7 +532,7 @@ trackedRuntime.loc = src.loc investigate_log("Experimentor has stolen Runtime!", "experimentor") else - new /mob/living/simple_animal/cat(src.loc) + new /mob/living/simple_animal/pet/cat(src.loc) investigate_log("Experimentor failed to steal runtime, and instead spawned a new cat.", "experimentor") ejectItem(TRUE) if(globalMalf > 76) @@ -627,6 +627,8 @@ /obj/item/weapon/relic/proc/reveal() + if(revealed) //Re-rolling your relics seems a bit overpowered, yes? + return revealed = TRUE name = realName cooldownMax = rand(60,300) @@ -654,14 +656,16 @@ /obj/item/weapon/relic/proc/corgicannon(var/mob/user) playsound(src.loc, "sparks", rand(25,50), 1) - var/mob/living/simple_animal/corgi/C = new/mob/living/simple_animal/corgi(get_turf(user)) + var/mob/living/simple_animal/pet/corgi/C = new/mob/living/simple_animal/pet/corgi(get_turf(user)) C.throw_at(pick(oview(10,user)),10,rand(3,8)) throwSmoke(get_turf(C)) + warn_admins(user, "Corgi Cannon", 0) /obj/item/weapon/relic/proc/clean(var/mob/user) playsound(src.loc, "sparks", rand(25,50), 1) var/obj/item/weapon/grenade/chem_grenade/cleaner/CL = new/obj/item/weapon/grenade/chem_grenade/cleaner(get_turf(user)) CL.prime() + warn_admins(user, "Smoke", 0) /obj/item/weapon/relic/proc/flash(var/mob/user) playsound(src.loc, "sparks", rand(25,50), 1) @@ -670,17 +674,22 @@ warn_admins(user, "Flash") /obj/item/weapon/relic/proc/petSpray(var/mob/user) - visible_message("[src] begans to shake, and in the distance the sound of rampaging animals arises!") + var/message = "[src] begans to shake, and in the distance the sound of rampaging animals arises!" + visible_message(message) + user << message var/animals = rand(1,25) var/counter - var/list/valid_animals = list(/mob/living/simple_animal/parrot,/mob/living/simple_animal/butterfly,/mob/living/simple_animal/cat,/mob/living/simple_animal/corgi,/mob/living/simple_animal/crab,/mob/living/simple_animal/fox,/mob/living/simple_animal/lizard,/mob/living/simple_animal/mouse,/mob/living/simple_animal/pug,/mob/living/simple_animal/hostile/bear,/mob/living/simple_animal/hostile/poison/bees,/mob/living/simple_animal/hostile/carp) + var/list/valid_animals = list(/mob/living/simple_animal/parrot,/mob/living/simple_animal/butterfly,/mob/living/simple_animal/pet/cat,/mob/living/simple_animal/pet/corgi,/mob/living/simple_animal/crab,/mob/living/simple_animal/pet/fox,/mob/living/simple_animal/lizard,/mob/living/simple_animal/mouse,/mob/living/simple_animal/pet/pug,/mob/living/simple_animal/hostile/bear,/mob/living/simple_animal/hostile/poison/bees,/mob/living/simple_animal/hostile/carp) for(counter = 1; counter < animals; counter++) var/mobType = pick(valid_animals) new mobType(get_turf(src)) warn_admins(user, "Mass Mob Spawn") + if(prob(60)) + user << "[src] falls apart!" + qdel(src) /obj/item/weapon/relic/proc/rapidDupe(var/mob/user) - visible_message("[src] emits a loud pop!") + audible_message("[src] emits a loud pop!") var/list/dupes = list() var/counter var/max = rand(5,10) @@ -698,26 +707,33 @@ for(counter = 1; counter <= dupes.len; counter++) var/obj/item/weapon/relic/R = dupes[counter] qdel(R) + warn_admins(user, "Rapid duplicator", 0) /obj/item/weapon/relic/proc/explode(var/mob/user) - visible_message("[src] begins to heat up!") + user << "[src] begins to heat up!" spawn(rand(35,100)) if(src.loc == user) visible_message("The [src]'s top opens, releasing a powerful blast!") explosion(user.loc, -1, rand(1,5), rand(1,5), rand(1,5), rand(1,5), flame_range = 2) warn_admins(user, "Explosion") + qdel(src) //Comment this line to produce a light grenade (the bomb that keeps on exploding when used)!! /obj/item/weapon/relic/proc/teleport(var/mob/user) - visible_message("The [src] begins to vibrate!") + user << "The [src] begins to vibrate!" spawn(rand(10,30)) - if(src.loc == user) + var/turf/userturf = get_turf(user) + if(src.loc == user && userturf.z != ZLEVEL_CENTCOM) //Because Nuke Ops bringing this back on their shuttle, then looting the ERT area is 2fun4you! visible_message("The [src] twists and bends, relocating itself!") + throwSmoke(userturf) + do_teleport(user, userturf, 8, asoundin = 'sound/effects/phasein.ogg') throwSmoke(get_turf(user)) - do_teleport(user, get_turf(user), 8, asoundin = 'sound/effects/phasein.ogg') - throwSmoke(get_turf(user)) + warn_admins(user, "Teleport", 0) //Admin Warning proc for relics -/obj/item/weapon/relic/proc/warn_admins(var/mob/user, var/RelicType) +/obj/item/weapon/relic/proc/warn_admins(var/mob/user, var/RelicType, var/priority = 1) var/turf/T = get_turf(src) - message_admins("[RelicType] relic activated by [key_name(user, user.client)](?) in ([T.x],[T.y],[T.z] - JMP)",0,1) - log_game("[RelicType] relic used by [user.ckey]([user]) in ([T.x],[T.y],[T.z])") + var/log_msg = "[RelicType] relic used by [user.ckey]([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) + log_game(log_msg) + investigate_log(log_msg, "experimentor") diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm new file mode 100644 index 00000000000..12b76321f27 --- /dev/null +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -0,0 +1,365 @@ + +/// Slime Extracts /// + +/obj/item/slime_extract + name = "slime extract" + desc = "Goo extracted from a slime. Legends claim these to have \"magical powers\"." + icon = 'icons/mob/slimes.dmi' + icon_state = "grey slime extract" + force = 1.0 + w_class = 1.0 + throwforce = 0 + throw_speed = 3 + throw_range = 6 + origin_tech = "biotech=4" + var/Uses = 1 // uses before it goes inert + var/enhanced = 0 //has it been enhanced before? + +/obj/item/slime_extract/attackby(obj/item/O as obj, mob/user as mob) + if(istype(O, /obj/item/weapon/slimesteroid2)) + if(enhanced == 1) + user << " This extract has already been enhanced!" + return ..() + if(Uses == 0) + user << " You can't enhance a used extract!" + return ..() + user <<"You apply the enhancer. It now has triple the amount of uses." + Uses = 3 + enhanced = 1 + qdel(O) + +/obj/item/slime_extract/New() + ..() + create_reagents(100) + +/obj/item/slime_extract/grey + name = "grey slime extract" + icon_state = "grey slime extract" + +/obj/item/slime_extract/gold + name = "gold slime extract" + icon_state = "gold slime extract" + +/obj/item/slime_extract/silver + name = "silver slime extract" + icon_state = "silver slime extract" + +/obj/item/slime_extract/metal + name = "metal slime extract" + icon_state = "metal slime extract" + +/obj/item/slime_extract/purple + name = "purple slime extract" + icon_state = "purple slime extract" + +/obj/item/slime_extract/darkpurple + name = "dark purple slime extract" + icon_state = "dark purple slime extract" + +/obj/item/slime_extract/orange + name = "orange slime extract" + icon_state = "orange slime extract" + +/obj/item/slime_extract/yellow + name = "yellow slime extract" + icon_state = "yellow slime extract" + +/obj/item/slime_extract/red + name = "red slime extract" + icon_state = "red slime extract" + +/obj/item/slime_extract/blue + name = "blue slime extract" + icon_state = "blue slime extract" + +/obj/item/slime_extract/darkblue + name = "dark blue slime extract" + icon_state = "dark blue slime extract" + +/obj/item/slime_extract/pink + name = "pink slime extract" + icon_state = "pink slime extract" + +/obj/item/slime_extract/green + name = "green slime extract" + icon_state = "green slime extract" + +/obj/item/slime_extract/lightpink + name = "light pink slime extract" + icon_state = "light pink slime extract" + +/obj/item/slime_extract/black + name = "black slime extract" + icon_state = "black slime extract" + +/obj/item/slime_extract/oil + name = "oil slime extract" + icon_state = "oil slime extract" + +/obj/item/slime_extract/adamantine + name = "adamantine slime extract" + icon_state = "adamantine slime extract" + +/obj/item/slime_extract/bluespace + name = "bluespace slime extract" + icon_state = "bluespace slime extract" + +/obj/item/slime_extract/pyrite + name = "pyrite slime extract" + icon_state = "pyrite slime extract" + +/obj/item/slime_extract/cerulean + name = "cerulean slime extract" + icon_state = "cerulean slime extract" + +/obj/item/slime_extract/sepia + name = "sepia slime extract" + icon_state = "sepia slime extract" + +/obj/item/slime_extract/rainbow + name = "rainbow slime extract" + icon_state = "rainbow slime extract" + +////Pet Slime Creation/// + +/obj/item/slimepotion + name = "docility potion" + desc = "A potent chemical mix that nullifies a slime's hunger, causing it to become docile and tame." + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle19" + +/obj/item/slimepotion/attack(mob/living/simple_animal/slime/M as mob, mob/user as mob) + if(!isslime(M)) + user << "The potion only works on slimes!" + return ..() + if(M.stat) + user << "The slime is dead!" + return..() + + M.docile = 1 + M.nutrition = 700 + M <<" You absorb the potion and feel your intense desire to feed melt away." + user <<" You feed the slime the potion, removing it's hunger and calming it." + var/newname = copytext(sanitize(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text),1,MAX_NAME_LEN) + + if (!newname) + newname = "pet slime" + M.name = newname + M.real_name = newname + qdel(src) + +/obj/item/slimepotion2 + name = "sentience potion" + desc = "A miraculous chemical mix that can raise the intelligence of creatures to human levels." + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle19" + var/list/not_interested = list() + var/being_used = 0 + +/obj/item/slimepotion2/afterattack(mob/living/M as mob, mob/user as mob) + if(being_used || !ismob(M)) + return + if( !(isanimal(M) || ismonkey(M)) || M.ckey) //only works on monkeys and animals that aren't player controlled + user << "[M] is already too intelligent for this to work!" + return ..() + if(M.stat) + user << "[M] is dead!" + return..() + + user << "You begin to apply the potion to [M]..." + being_used = 1 + + var/list/candidates = get_candidates(BE_ALIEN, ALIEN_AFK_BRACKET) + + shuffle(candidates) + + var/time_passed = world.time + var/list/consenting_candidates = list() + + for(var/candidate in candidates) + + if(candidate in not_interested) + continue + + spawn(0) + switch(alert(candidate, "Would you like to play as [M.name]? Please choose quickly!","Confirmation","Yes","No")) + if("Yes") + if((world.time-time_passed)>=50 || !src) + return + consenting_candidates += candidate + if("No") + if(!src) + return + not_interested += candidate + + sleep(50) + + if(!src) + return + + if(consenting_candidates.len) + var/client/C = null + C = pick(consenting_candidates) + M.key = C.key + M.languages |= HUMAN + M.faction -= "neutral" + M << "All at once it makes sense, you know what you are and who you are! Self awareness is yours!" + M << "You are grateful to be self aware and owe [user] a great debt. Serve [user], and assist them in completing their goals at any cost." + user << "[M] is suddenly attentive and aware. It worked!" + qdel(src) + else + user << "[M] looks interested for a moment, but then looks back down. Maybe you should try again later..." + being_used = 0 + ..() + +/obj/item/weapon/slimesteroid + name = "slime steroid" + desc = "A potent chemical mix that will cause a slime to generate more extract." + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle16" + +/obj/item/weapon/slimesteroid/attack(mob/living/simple_animal/slime/M as mob, mob/user as mob) + if(!isslime(M))//If target is not a slime. + user << " The steroid only works on baby slimes!" + return ..() + if(M.is_adult) //Can't tame adults + user << " Only baby slimes can use the steroid!" + return..() + if(M.stat) + user << " The slime is dead!" + return..() + if(M.cores == 3) + user <<" The slime already has the maximum amount of extract!" + return..() + + user <<"You feed the slime the steroid. It now has triple the amount of extract." + M.cores = 3 + qdel(src) + +/obj/item/weapon/slimesteroid2 + name = "extract enhancer" + desc = "A potent chemical mix that will give a slime extract three uses." + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle17" + + /*afterattack(obj/target, mob/user , flag) + if(istype(target, /obj/item/slime_extract)) + if(target.enhanced == 1) + user << " This extract has already been enhanced!" + return ..() + if(target.Uses == 0) + user << " You can't enhance a used extract!" + return ..() + user <<"You apply the enhancer. It now has triple the amount of uses." + target.Uses = 3 + target.enahnced = 1 + qdel(src)*/ + + +////////Adamantine Golem stuff I dunno where else to put it + +// This will eventually be removed. + +/obj/item/clothing/under/golem + name = "adamantine skin" + desc = "a golem's skin" + icon_state = "golem" + item_state = "golem" + item_color = "golem" + flags = ABSTRACT | NODROP + has_sensor = 0 + +/obj/item/clothing/suit/golem + name = "adamantine shell" + desc = "a golem's thick outter shell" + icon_state = "golem" + item_state = "golem" + w_class = 4//bulky item + gas_transfer_coefficient = 0.90 + permeability_coefficient = 0.50 + body_parts_covered = FULL_BODY + flags_inv = HIDEGLOVES | HIDESHOES | HIDEJUMPSUIT + flags = ABSTRACT | NODROP + +/obj/item/clothing/shoes/golem + name = "golem's feet" + desc = "sturdy adamantine feet" + icon_state = "golem" + item_state = null + flags = NOSLIP | ABSTRACT | NODROP + + +/obj/item/clothing/mask/breath/golem + name = "golem's face" + desc = "the imposing face of an adamantine golem" + icon_state = "golem" + item_state = "golem" + siemens_coefficient = 0 + unacidable = 1 + flags = ABSTRACT | NODROP + + +/obj/item/clothing/gloves/golem + name = "golem's hands" + desc = "strong adamantine hands" + icon_state = "golem" + item_state = null + siemens_coefficient = 0 + flags = ABSTRACT | NODROP + + +/obj/item/clothing/head/space/golem + icon_state = "golem" + item_state = "dermal" + item_color = "dermal" + name = "golem's head" + desc = "a golem's head" + unacidable = 1 + flags = ABSTRACT | NODROP + +/obj/effect/golemrune + anchored = 1 + desc = "a strange rune used to create golems. It glows when spirits are nearby." + name = "rune" + icon = 'icons/obj/rune.dmi' + icon_state = "golem" + unacidable = 1 + layer = TURF_LAYER + + New() + ..() + SSobj.processing |= src + +/obj/effect/golemrune/process() + var/mob/dead/observer/ghost + for(var/mob/dead/observer/O in src.loc) + if(!O.client) continue + if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue + ghost = O + break + if(ghost) + icon_state = "golem2" + else + icon_state = "golem" + +/obj/effect/golemrune/attack_hand(mob/living/user as mob) + var/mob/dead/observer/ghost + for(var/mob/dead/observer/O in src.loc) + if(!O.client) continue + if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue + ghost = O + break + if(!ghost) + user << "The rune fizzles uselessly. There is no spirit nearby." + return + var/mob/living/carbon/human/G = new /mob/living/carbon/human + if(prob(50)) G.gender = "female" + hardset_dna(G, null, null, null, null, /datum/species/golem/adamantine) + + G.set_cloned_appearance() + G.real_name = text("Adamantine Golem ([rand(1, 1000)])") + G.dna.species.auto_equip(G) + G.loc = src.loc + G.key = ghost.key + G << "You are an adamantine golem. You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools. Serve [user], and assist them in completing their goals at any cost." + qdel(src) \ No newline at end of file diff --git a/code/modules/surgery/cavity_implant.dm b/code/modules/surgery/cavity_implant.dm index 72223b4716f..289dadeec2d 100644 --- a/code/modules/surgery/cavity_implant.dm +++ b/code/modules/surgery/cavity_implant.dm @@ -25,7 +25,7 @@ /datum/surgery_step/handle_cavity/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(tool) - if(IC || tool.w_class > 3 || tool.GetTypeInAllContents(/obj/item/weapon/disk/nuclear) || istype(tool, /obj/item/weapon/disk/nuclear) || istype(tool, /obj/item/organ)) + if(IC || tool.w_class > 3 || NODROP in tool.flags || tool.GetTypeInAllContents(/obj/item/weapon/disk/nuclear) || istype(tool, /obj/item/weapon/disk/nuclear) || istype(tool, /obj/item/organ)) user.visible_message("[user] can't seem to fit [tool] in [target]'s [target_zone].") return 0 else diff --git a/code/modules/surgery/core_removal.dm b/code/modules/surgery/core_removal.dm index 0064b7d1541..2f8dff6988f 100644 --- a/code/modules/surgery/core_removal.dm +++ b/code/modules/surgery/core_removal.dm @@ -1,7 +1,7 @@ /datum/surgery/core_removal name = "core removal" steps = list(/datum/surgery_step/incise, /datum/surgery_step/incise, /datum/surgery_step/extract_core) - species = list(/mob/living/carbon/slime) + species = list(/mob/living/simple_animal/slime) target_must_be_dead = 1 @@ -14,7 +14,7 @@ user.visible_message("[user] begins to extract a core from [target].") /datum/surgery_step/extract_core/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - var/mob/living/carbon/slime/slime = target + var/mob/living/simple_animal/slime/slime = target if(slime.cores > 0) slime.cores-- user.visible_message("[user] successfully extracts a core from [target]!") diff --git a/code/modules/surgery/cybernetic_implants.dm b/code/modules/surgery/cybernetic_implants.dm new file mode 100644 index 00000000000..6d289144127 --- /dev/null +++ b/code/modules/surgery/cybernetic_implants.dm @@ -0,0 +1,56 @@ +#define MAX_BRAIN_IMPLANT 2 + +/datum/surgery/eye_cybernetic_implant/eyes + name = "eye cybernetic implant" + steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/cybernetic_implant/eyes, /datum/surgery_step/fix_eyes, /datum/surgery_step/close) + location = "eyes" + +/datum/surgery/eye_cybernetic_implant/brain + name = "brain cybernetic implant" + steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/cybernetic_implant/brain, /datum/surgery_step/close) + location = "head" + +/datum/surgery_step/cybernetic_implant/eyes + implements = list(/obj/item/cybernetic_implant/eyes = 100) + time = 32 + +/datum/surgery_step/cybernetic_implant/brain + implements = list(/obj/item/cybernetic_implant/brain = 100) + time = 32 + +/datum/surgery_step/cybernetic_implant/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/cybernetic_implant/implant, datum/surgery/surgery) + user.visible_message("[user] begins to implant [target] with [implant].") + +/datum/surgery_step/cybernetic_implant/eyes/success(mob/user, mob/living/carbon/target, target_zone, obj/item/cybernetic_implant/eyes/implant, datum/surgery/surgery) + if(implant) + var/full = 0 + if(locate(/obj/item/cybernetic_implant/eyes,target.internal_organs)) + full = 1 + + insert(user,target,implant,target_zone,full) + return 1 + +/datum/surgery_step/cybernetic_implant/brain/success(mob/user, mob/living/carbon/target, target_zone, obj/item/cybernetic_implant/brain/implant, datum/surgery/surgery) + if(implant) + var/full = 0 + for(var/obj/item/I in target.contents) + if(istype(I,/obj/item/cybernetic_implant/brain)) + full++ + + if(full < MAX_BRAIN_IMPLANT) + full = 0 + + insert(user,target,implant,target_zone,full) + return 1 + + +/datum/surgery_step/cybernetic_implant/proc/insert(mob/user, mob/living/carbon/target, obj/item/cybernetic_implant/implant,target_zone,full) + if(full) + user.visible_message("[user] can't seem to implant anything else into the [target]'s [target_zone].") + else + user.visible_message("[user] inserts [implant] into the [target]'s [target_zone == "head" ? "brain" : target_zone]!") + implant.owner = target + implant.function() + user.drop_item() + implant.loc = target + target.internal_organs |= implant \ No newline at end of file diff --git a/code/modules/surgery/organs/cybernetic_implants.dm b/code/modules/surgery/organs/cybernetic_implants.dm new file mode 100644 index 00000000000..5b5a928148b --- /dev/null +++ b/code/modules/surgery/organs/cybernetic_implants.dm @@ -0,0 +1,236 @@ +#define STUN_SET_AMOUNT 2 + +/obj/item/cybernetic_implant + name = "cybernetic implant" + desc = "a state-of-the-art implant that improves a baseline's functionality" + icon = 'icons/obj/surgery.dmi' + var/mob/living/carbon/owner = null + var/implant_color = "#FFFFFF" + +/obj/item/cybernetic_implant/New(var/mob/M = null) + if(M) + owner = M + return ..() + +/obj/item/cybernetic_implant/proc/function() + return + + +//[[[[EYES]]]] + +/obj/item/cybernetic_implant/eyes + name = "cybernetic eyes" + desc = "artificial photoreceptors with specialized functionality" + icon_state = "eye_implant" + var/eye_color = "fff" + var/flash_protect = 0 + +/obj/item/cybernetic_implant/eyes/New() + var/icon/overlay = new /icon('icons/obj/surgery.dmi',"eye_implant_overlay") + overlay.ColorTone(implant_color) + overlays |= overlay + ..() + +/obj/item/cybernetic_implant/eyes/proc/update_eye_color(fluff_message) + if(istype(owner,/mob/living/carbon/human)) + var/mob/living/carbon/human/HMN = owner + HMN.eye_color = eye_color + HMN.regenerate_icons() + if(fluff_message) + owner << "[fluff_message]" + +/obj/item/cybernetic_implant/eyes/hud/medical + name = "medical hud implant" + desc = "These cybernetic eyes will display a medical HUD over everything you see. Wiggle eyes to control." + eye_color = "0ff" + implant_color = "#00FFFF" + +/obj/item/cybernetic_implant/eyes/hud/medical/function() + if(!owner) + return + + var/datum/atom_hud/H = huds[DATA_HUD_MEDICAL_ADVANCED] + H.add_hud_to(owner) + owner.permanent_huds |= H + update_eye_color("You suddenly see health bars floating above people's heads...") + +/obj/item/cybernetic_implant/eyes/hud/security + name = "security hud implant" + desc = "These cybernetic eyes will display a security HUD over everything you see. Wiggle eyes to control." + eye_color = "d00" + implant_color = "#CC0000" + +/obj/item/cybernetic_implant/eyes/hud/security/function() + if(!owner) + return + + var/datum/atom_hud/H = huds[DATA_HUD_SECURITY_ADVANCED] + H.add_hud_to(owner) + owner.permanent_huds |= H + update_eye_color("Job indicator icons pop up in your vision. That is not a certified surgeon...") + +/obj/item/cybernetic_implant/eyes/xray + name = "xray implant" + desc = "These cybernetic eyes will give you X-ray vision. Blinking is futile." + eye_color = "000" + implant_color = "#000000" + +/obj/item/cybernetic_implant/eyes/xray/function() + if(!owner) + return + + owner.sight |= SEE_MOBS + owner.sight |= SEE_OBJS + owner.sight |= SEE_TURFS + owner.permanent_sight_flags |= SEE_MOBS + owner.permanent_sight_flags |= SEE_OBJS + owner.permanent_sight_flags |= SEE_TURFS + update_eye_color("Your vision is augmented!") + +/obj/item/cybernetic_implant/eyes/thermals + name = "thermals implant" + desc = "These cybernetic eyes will give you Thermal vision. Vertical slit pupil included." + eye_color = "FC0" + implant_color = "#FFCC00" + flash_protect = -1 + +/obj/item/cybernetic_implant/eyes/thermals/function() + if(!owner) + return + + owner.sight |= SEE_MOBS + owner.permanent_sight_flags |= SEE_MOBS + update_eye_color("You see prey everywhere you look...") + +/obj/item/cybernetic_implant/eyes/emp_act(severity) + if(severity > 1) + if(prob(5)) + return + var/save_sight = owner.sight + owner.sight &= 0 + owner.disabilities |= BLIND + owner << "Static obfuscates your vision!" + spawn(50) + owner.sight |= save_sight + owner.disabilities ^= BLIND + + +//[[[[BRAIN]]]] + +/obj/item/cybernetic_implant/brain + name = "cybernetic brain implant" + desc = "injectors of extra sub-routines for the brain" + icon_state = "brain_implant" + +/obj/item/cybernetic_implant/brain/New() + var/icon/overlay = new /icon('icons/obj/surgery.dmi',"brain_implant_overlay") + overlay.ColorTone(implant_color) + overlays |= overlay + ..() + +/obj/item/cybernetic_implant/brain/emp_act(severity) + var/stun_amount = 5 + (severity-1 ? 0 : 5) + owner.Stun(stun_amount) + owner << "Your body seizes up!" + return stun_amount + +/obj/item/cybernetic_implant/brain/anti_drop + name = "anti-drop implant" + desc = "This cybernetic brain implant will allow you to force your hand muscles to contract, preventing item dropping. Twitch ear to toggle." + var/active = 0 + var/l_hand_ignore = 0 + var/r_hand_ignore = 0 + var/obj/item/l_hand_obj = null + var/obj/item/r_hand_obj = null + implant_color = "#DE7E00" + +/obj/item/cybernetic_implant/brain/anti_drop/function() + action_button_name = "Toggle Anti-Drop" + +/obj/item/cybernetic_implant/brain/anti_drop/ui_action_click() + active = !active + if(active) + l_hand_obj = owner.l_hand + r_hand_obj = owner.r_hand + if(l_hand_obj) + if(owner.l_hand.flags & NODROP) + l_hand_ignore = 1 + else + owner.l_hand.flags |= NODROP + l_hand_ignore = 0 + + if(r_hand_obj) + if(owner.r_hand.flags & NODROP) + r_hand_ignore = 1 + else + owner.r_hand.flags |= NODROP + r_hand_ignore = 0 + + if(!l_hand_obj && !r_hand_obj) + owner << "You are not holding any items, your hands relax..." + active = 0 + else + var/msg = 0 + msg += !l_hand_ignore && l_hand_obj ? 1 : 0 + msg += !r_hand_ignore && r_hand_obj ? 2 : 0 + switch(msg) + if(1) + owner << "Your left hand's grip tightens." + if(2) + owner << "Your right hand's grip tightens." + if(3) + owner << "Both of your hand's grips tighten." + else + release_items() + owner << "Your hands relax..." + l_hand_obj = null + r_hand_obj = null + +/obj/item/cybernetic_implant/brain/anti_drop/emp_act(severity) + var/range = severity ? 10 : 5 + var/atom/A + var/obj/item/L_item = owner.l_hand + var/obj/item/R_item = owner.r_hand + + release_items() + ..() + if(L_item) + A = pick(oview(range)) + L_item.throw_at(A, range, 2) + owner << "Your left arm spasms and throws the [L_item.name]!" + if(R_item) + A = pick(oview(range)) + R_item.throw_at(A, range, 2) + owner << "Your right arm spasms and throws the [R_item.name]!" + +/obj/item/cybernetic_implant/brain/anti_drop/proc/release_items() + if(!l_hand_ignore && l_hand_obj in owner.contents) + l_hand_obj.flags ^= NODROP + if(!r_hand_ignore && r_hand_obj in owner.contents) + r_hand_obj.flags ^= NODROP + +/obj/item/cybernetic_implant/brain/anti_stun + name = "CNS Rebooter implant" + desc = "This implant will automatically give you back control over your central nervous system, reducing downtime when stunned." + implant_color = "#FFFF00" + +/obj/item/cybernetic_implant/brain/anti_stun/function() + SSobj.processing |= src + +/obj/item/cybernetic_implant/brain/anti_stun/process() + if(!owner) + SSobj.processing.Remove(src) + qdel(src) + return + if(owner.stat == DEAD) + return + + if(owner.stunned > STUN_SET_AMOUNT) + owner.stunned = STUN_SET_AMOUNT + if(owner.weakened > STUN_SET_AMOUNT) + owner.weakened = STUN_SET_AMOUNT + +/obj/item/cybernetic_implant/brain/anti_stun/emp_act(severity) + SSobj.processing.Remove(src) + spawn(..() * 10) + SSobj.processing |= src \ No newline at end of file diff --git a/code/modules/surgery/xenomorph_removal.dm b/code/modules/surgery/xenomorph_removal.dm index 9143713034d..98b81efcf5e 100644 --- a/code/modules/surgery/xenomorph_removal.dm +++ b/code/modules/surgery/xenomorph_removal.dm @@ -23,7 +23,7 @@ return 1 /datum/surgery_step/xenomorph_removal/proc/remove_xeno(mob/user, mob/living/carbon/target) - var/obj/item/alien_embryo/A = locate() in target.contents + var/obj/item/body_egg/alien_embryo/A = locate() in target.contents if(A) user << "You found an unknown alien organism in [target]'s chest!" if(A.stage < 4) @@ -38,7 +38,7 @@ /datum/surgery_step/xenomorph_removal/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - var/obj/item/alien_embryo/A = locate() in target.contents + var/obj/item/body_egg/alien_embryo/A = locate() in target.contents if(A) if(prob(50)) A.AttemptGrow(0) diff --git a/code/modules/telesci/bscrystal.dm b/code/modules/telesci/bscrystal.dm index 9249d0c9ccd..7c64352ca8f 100644 --- a/code/modules/telesci/bscrystal.dm +++ b/code/modules/telesci/bscrystal.dm @@ -18,7 +18,7 @@ /obj/item/bluespace_crystal/attack_self(var/mob/user) user.visible_message("[user] crushes [src]!") - new /obj/effect/effect/sparks(src.loc) + PoolOrNew(/obj/effect/effect/sparks, loc) playsound(src.loc, "sparks", 50, 1) blink_mob(user) user.drop_item() @@ -30,7 +30,7 @@ /obj/item/bluespace_crystal/throw_impact(atom/hit_atom) ..() visible_message("[src] fizzles and disappears upon impact!") - new /obj/effect/effect/sparks(src.loc) + PoolOrNew(/obj/effect/effect/sparks, loc) playsound(src.loc, "sparks", 50, 1) if(isliving(hit_atom)) blink_mob(hit_atom) diff --git a/config/game_options.txt b/config/game_options.txt index 84b6750c697..683ec17b46b 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -234,4 +234,12 @@ STARLIGHT MIDROUND_ANTAG_TIME_CHECK 60 ## A ratio of living to total crew members, the lower this is, the more people will have to die in order for midround antag to be skipped -MIDROUND_ANTAG_LIFE_CHECK 0.7 \ No newline at end of file +MIDROUND_ANTAG_LIFE_CHECK 0.7 + +###Limit Spell Choices## +## Uncomment to disallow wizards from using certain spells that may be too chaotic/fun for your playerbase + +#NO_SUMMON_GUNS +#NO_SUMMON_MAGIC +#NO_SUMMON_EVENTS + diff --git a/html/changelog.html b/html/changelog.html index 4978c9b7418..5d1d06ac242 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -55,6 +55,244 @@ -->
      +

      25 March 2015

      +

      AnturK updated:

      +
        +
      • Added an arrow graffiti, made arrow and body graffiti face the same way as the user
      • +
      • New changeling ability : Last Resort : Explode and infect corpses if the situation looks grim
      • +
      +

      Fayrik updated:

      +
        +
      • Deleted the toy crossbow that wasn't a gun, but flung projectiles like a gun. Why was that even a thing?
      • +
      • Added an abstract new type of reusable ammo.
      • +
      • Added three new foam force guns and a foam force crossbow, all of which take the new foam dart ammo.
      • +
      • Added foam force dart boxes to the autolathe, and two crates orderable from cargo containing the new guns.
      • +
      • Added two new donksoft guns, the syndicate's own brand of Foam Force. Available in all good uplinks!
      • +
      • New crossbow can be won as an arcade prize.
      • +
      • All kinds of ammo containers can now be used to rapidly collect live ammunition on the ground.
      • +
      • Speedloaders and traditional ammo boxes can now be restocked.
      • +
      • Security bots now react to being shot.
      • +
      +

      MrPerson updated:

      +
        +
      • Added a preference toggle for hearing instruments play as suggested by PKPenguin321.
      • +
      +

      Pennwick updated:

      +
        +
      • Added a buildable Chem Master, board is in Circuit Imprinter.
      • +
      +

      Wjohnston updated:

      +
        +
      • Finally fixed the gulag shuttle missing a redemption console.
      • +
      + +

      24 March 2015

      +

      Cheridan updated:

      +
        +
      • Adds pet collars. Use them to rename pets; Can also be worn if you're a weirdo.
      • +
      • Adds the matyr objective to be dead at the round's end. You can get this objective if you have no others that would need you to survive.
      • +
      +

      Dannno updated:

      +
        +
      • GAR glasses return. Yes, I got permission. Just who the hell do you think I am?
      • +
      +

      Incoming5643 updated:

      +
        +
      • Summon Events has been reworked to be a bit less manic.
      • +
      • Summon Events will turn off if the wizard and all apprentices die. Any lingering effects are not reversed however.
      • +
      • Improving Summon Events will reduce the average time between events, but not the minimum time between events.
      • +
      • Departmental Uprising has been made admin only for being an RP heavy event that creates antags in an enviroment that doesn't really support that.
      • +
      +

      Mandurrrh updated:

      +
        +
      • Added a cyborg upgrade module for the satchel of holding.
      • +
      +

      Miauw updated:

      +
        +
      • Added a fancy white dress and a jester outfit. Sprites by Nienhaus.
      • +
      +

      Steelpoint, RemieRichards, and Gun Hog updated:

      +
        +
      • Nanotrasen Security has authorized modifications to the standard issue helmets for officers. These helmets are now issued with a mounted camera, automatically synced to your assigned station's camera network. In addition, the helmets also include mounting points for the Seclite model of flashlights, found in your station's security vendors.
      • +
      • Nanotrasen Security helmets are designed for easy repairs in the field. Officers may remove their Seclite attachment with any screwdriver, and the camera's assembly may be pried off with a crowbar. The assembly is also compatible with analyzer upgrades for scanning through the station's structure, and EMP shielding is possible by applying a sheet of plasma.
      • +
      + +

      22 March 2015

      +

      Iamgoofball updated:

      +
        +
      • Fixes Morphine not knocking you out.
      • +
      • Hotline no longer exists. Poppies now have Saline-Glucose Solution.
      • +
      • Muriatic Acid, Caustic Soda, and Hydrogen Chloride have been removed, along with the secondary meth recipe. The original recipe still works.
      • +
      • Foam now produces more bang for your buck when mixed. Your foam grenades should be larger now to account for the slowdown.
      • +
      • Adds Stabilizing Agent. This chemical will prevent the effects of certain reactions from taking place in the container it is in, such as Smoke Powder and Flash Powder, allowing you to get the raw forms of the powders for heating up later.
      • +
      • Smoke Powder and Flash Powder can now be mixed along with Stabilizing Agent in order to produce a powder version of the effects. You can then heat these powders to 374K to get the effects.
      • +
      • Mixing them without Stabilizing Agent gives the default effects.
      • +
      • Adds Sonic Powder, a chemical that deafens and stuns within 5 tiles of the reaction. It also follows the reaction rules of the other 2 powders.
      • +
      • Liquid Dark Matter and Sorium also now work like the powders do.
      • +
      • CLF3 now has a higher chance of making plating tiles, and the burn damage caused by it scales based on your fire stacks.
      • +
      • Adds Pyrosium. This reagent heats up mobs by 30 degrees every 3 seconds if it has oxygen to react with. Useful for when you want a delayed mix inside of someone.
      • +
      • Adds Cryostylane. This reagent does the opposite of Pyrosium, but it still requires oxygen to react with.
      • +
      • Adds Phlogiston. This reagent ignites you and gives you a single fire stack every 3 seconds. Burn damage from this chemical scales up with the fire stacks you have. Counter this with literally any chemical that purges other chems.
      • +
      • Smoke now transfers reagents to the mob, and applies touch reactions on them. This means smoke can run out of reagents, no more infinite acid smoke. It also only works on mobs, use the new Reagent Foam(tm) for your hellfoam needs. I suggest a CLF3 Fluoroacid Black Powder mix.
      • +
      • Added a derelict medibot to the code, will place a few on the derelict when this PR is merged as to prevent mapping conflicts.
      • +
      • Adds Initropidril. 33% chance to hit with 5-25 TOX damage every 3 seconds, and a 5-10% chance to either stun, cause lots of oxygen damage, or cause your heart to stop. Get it from the traitor Poison Kit.
      • +
      • Adds Pancuronium. Paralyses you after 30 seconds, with a 7% chance to cause 3-5 loss of breath. Get it from the traitor Poison Kit.
      • +
      • Adds Sodium Thiopental. Knocks you out after 30 seconds, and destroys your stamina. Get it from the traitor Poison Kit.
      • +
      • Adds Sulfonal. +1 TOX per 3 seconds, knocks you out in 66 seconds. Mix it with Acetone, Diethylamine, and Sulfur.
      • +
      • Adds Amantin. On the last second it is in you, it hits you with a stack of TOX damage based on how long it's been in you. Get it from the traitor Poison Kit.
      • +
      • Adds Lipolicide. +1 TOX unless you have nutriment in you. Mix it with Mercury, Diethylamine, and Ephedrine.
      • +
      • Adds Coiine. +2 TOX and +5 loss of breath every 3 seconds. Get it from the traitor Poison Kit.
      • +
      • Adds Curare. +1 TOX, +1 OXY, paralyzes after 33 seconds. Get it from the traitor Poison Kit.
      • +
      • Adds a reagent_deleted() proc to reagents for effects upon the last time it processes in you, like with Amantin.
      • +
      • Neurotoxin required temperature for mixing has been set to 674K, it was 370K for some reason.
      • +
      +

      xxalpha updated:

      +
        +
      • Added Cybernetic Implants: Security HUD, Medical HUD, X-Ray, Thermals, Anti-Drop, Anti-Stun. All implants are researchable and producible by R&D and Robotics.
      • +
      + +

      21 March 2015

      +

      Chocobro updated:

      +
        +
      • Checkered skirts can be adjusted to be worn shorter.
      • +
      +

      Incoming5643 updated:

      +
        +
      • Player controller uplifted mobs will be attacked by gold core mobs of different species.
      • +
      +

      Jordie0608 updated:

      +
        +
      • The backup shuttle will no longer be called if the emergency shuttle is coming.
      • +
      +

      MMMiracles updated:

      +
        +
      • Adds 3 new bear-based foods.
      • +
      • Beary Pie -1 Plain Pie, 1 berry, 1 bear steak
      • +
      • Filet Migrawr - 5u of Manlydorf, 1 bear steak, 1 lighter(not used in crafting)
      • +
      • Bearger - 1 bun, 1 bear steak
      • +
      +

      Phil235 updated:

      +
        +
      • Silicons are no longer blinded by welding.
      • +
      +

      Xhuis updated:

      +
        +
      • A new software update has given the Orion Trail game a cheat code menu. While you can't access this normally (that's for a later software update), maybe an emag could do it...?
      • +
      +

      Zelacks updated:

      +
        +
      • The chemical implant action button should now correctly inject all chemicals when pressed.
      • +
      +

      pudl updated:

      +
        +
      • Adds normal security headsets to security lockers.
      • +
      +

      xxalpha updated:

      +
        +
      • Fixed cables on catwalks being destroyed when creating plating floor.
      • +
      • Portable machines can be mounted on any turf that could hold a cable.
      • +
      + +

      19 March 2015

      +

      Dannno updated:

      +
        +
      • Adds a few cosmetic glasses to the autodrobe and clothing vendors.
      • +
      +

      Gun Hog updated:

      +
        +
      • Explosion relics will now destroy themselves in their own explosion.
      • +
      • The Experimentor can no longer re-roll the function of an already scanned relic.
      • +
      +

      Incoming5643 updated:

      +
        +
      • Ghosts are now asked if they want to become a sentient slime.
      • +
      +

      JJRcop updated:

      +
        +
      • Adds the :rollie: and :ambrosia: emojis.
      • +
      +

      MMMiracles updated:

      +
        +
      • ERT suits now use helmet toggling like hardsuits.
      • +
      +

      Menshin updated:

      +
        +
      • Fixed mechs ballistic guns not firing bullets.
      • +
      +

      Xhuis updated:

      +
        +
      • Allows alt-clicking to adjust breath masks, flip caps, and unlock/lock closets.
      • +
      +

      xxalpha updated:

      +
        +
      • Fixed jetpack trail animation.
      • +
      + +

      17 March 2015

      +

      CandyClownTG updated:

      +
        +
      • Syndicate cigarettes' non-healing Doctor's Delight replaced with Omnizine.
      • +
      +

      Fayrik updated:

      +
        +
      • Expanded the Centcom area for better station-Centcom interaction.
      • +
      +

      Iamgoofball updated:

      +
        +
      • Acid blobs are less likely to melt equipment.
      • +
      +

      MMMiracles updated:

      +
        +
      • Adds the ability to spike bears on a meatspike for their pelt. Yields 5 meat instead of the usual 3 from a knife.
      • +
      +

      Thunder12345 updated:

      +
        +
      • Two new shotgun shells. Ion shell, shotgun version of ion rifle, built with 1 x techshell, 1 x ultra microlaser, 1 x ansible crystal.
      • +
      • Laser slug, regular laser shot in a shotgun shell, build with 1 x techshell, 1 x high power microlaser, 1 x advanced capacitor.
      • +
      • Improvised shotgun shells can now be constructed with 1 x grenade casing, 1 x metal sheet, 1 x cable, 10 units welding fuel. Can be packed with a further 5 units of gunpowder to turn it into a potentially lethal diceroll.
      • +
      • FRAG-12 shotgun shells are no longer duds, now explosive.
      • +
      +

      phil235 updated:

      +
        +
      • Makes the message when you're attacked slightly bigger for better visibility.
      • +
      + +

      15 March 2015

      +

      Ahammer18 updated:

      +
        +
      • Adds ass photocopying for drones
      • +
      +

      Gun Hog updated:

      +
        +
      • Nanotrasen has approved distribution of Loyalty Implant Firing Pin designs. They can be fabricated with sufficient research into weapons technology. If inserted into a firearm, it will only fire upon successful interface with a user's Loyalty Implant.
      • +
      +

      Incoming5643 updated:

      +
        +
      • Utilizing a new magic mirror found in the den, wizards can now customize their appearance to a high degree before descending upon the station.
      • +
      +

      Miauw updated:

      +
        +
      • Firing delay for tasers has been shortened.
      • +
      +

      RemieRichards updated:

      +
        +
      • Beginning major rework and refactor of messy Ninja code.
      • +
      • Roleplay based, kill deathsquad and kill alien queen objectives removed.
      • +
      • Kamikaze mode removed.
      • +
      • AIs and pAIs can no longer be integrated into a ninja suit.
      • +
      • Energy blade power replaced by an energy katana that can be dropped but is more deadly.
      • +
      • Energy katana can emag any object it hits.
      • +
      +

      phil235 updated:

      +
        +
      • Bookbags have a new sprite and can hold bibles.
      • +
      • Adds egg yolk reagent. You can break eggs in open reagent containers or blend them to get egg yolk.
      • +
      • Changes how doughs are made. 10water+15flour chem reaction for dough. 15flour+15eggyolk+5sugar for cake batter (or alternatively soymilk instead of the eggyolk for vegans).
      • +
      • Change customizable snack max volume to 60 and buffs nutriment amount in doughs.
      • +
      • Doors can damage mechs by crushing them now.
      • +
      • The tablecrafting window now also shows partial recipes in grey, if there's some of the things required for the recipe on the table. Recipe requirements are now also shown next to the names of recipes listed in the window.
      • +
      +

      11 March 2015

      MMMiracles updated:

        diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index b91c3d3fa55..fe2e446ccca 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -1737,3 +1737,227 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. Miauw: - rscadd: Added a toggle for ghosts that allows them to hear radio chatter without having to hover near intercoms/over people with headsets. +2015-03-15: + Ahammer18: + - bugfix: Adds ass photocopying for drones + Gun Hog: + - rscadd: Nanotrasen has approved distribution of Loyalty Implant Firing Pin designs. + They can be fabricated with sufficient research into weapons technology. If + inserted into a firearm, it will only fire upon successful interface with a + user's Loyalty Implant. + Incoming5643: + - rscadd: Utilizing a new magic mirror found in the den, wizards can now customize + their appearance to a high degree before descending upon the station. + Miauw: + - tweak: Firing delay for tasers has been shortened. + RemieRichards: + - wip: Beginning major rework and refactor of messy Ninja code. + - rscdel: Roleplay based, kill deathsquad and kill alien queen objectives removed. + - rscdel: Kamikaze mode removed. + - rscdel: AIs and pAIs can no longer be integrated into a ninja suit. + - tweak: Energy blade power replaced by an energy katana that can be dropped but + is more deadly. + - rscadd: Energy katana can emag any object it hits. + phil235: + - rscadd: Bookbags have a new sprite and can hold bibles. + - rscadd: Adds egg yolk reagent. You can break eggs in open reagent containers or + blend them to get egg yolk. + - tweak: Changes how doughs are made. 10water+15flour chem reaction for dough. 15flour+15eggyolk+5sugar + for cake batter (or alternatively soymilk instead of the eggyolk for vegans). + - tweak: Change customizable snack max volume to 60 and buffs nutriment amount in + doughs. + - rscadd: Doors can damage mechs by crushing them now. + - rscadd: The tablecrafting window now also shows partial recipes in grey, if there's + some of the things required for the recipe on the table. Recipe requirements + are now also shown next to the names of recipes listed in the window. +2015-03-17: + CandyClownTG: + - bugfix: Syndicate cigarettes' non-healing Doctor's Delight replaced with Omnizine. + Fayrik: + - rscadd: Expanded the Centcom area for better station-Centcom interaction. + Iamgoofball: + - tweak: Acid blobs are less likely to melt equipment. + MMMiracles: + - rscadd: Adds the ability to spike bears on a meatspike for their pelt. Yields + 5 meat instead of the usual 3 from a knife. + Thunder12345: + - rscadd: Two new shotgun shells. Ion shell, shotgun version of ion rifle, built + with 1 x techshell, 1 x ultra microlaser, 1 x ansible crystal. + - rscadd: Laser slug, regular laser shot in a shotgun shell, build with 1 x techshell, + 1 x high power microlaser, 1 x advanced capacitor. + - rscadd: Improvised shotgun shells can now be constructed with 1 x grenade casing, + 1 x metal sheet, 1 x cable, 10 units welding fuel. Can be packed with a further + 5 units of gunpowder to turn it into a potentially lethal diceroll. + - bugfix: FRAG-12 shotgun shells are no longer duds, now explosive. + phil235: + - tweak: Makes the message when you're attacked slightly bigger for better visibility. +2015-03-19: + Dannno: + - rscadd: Adds a few cosmetic glasses to the autodrobe and clothing vendors. + Gun Hog: + - tweak: Explosion relics will now destroy themselves in their own explosion. + - bugfix: The Experimentor can no longer re-roll the function of an already scanned + relic. + Incoming5643: + - tweak: Ghosts are now asked if they want to become a sentient slime. + JJRcop: + - rscadd: 'Adds the :rollie: and :ambrosia: emojis.' + MMMiracles: + - tweak: ERT suits now use helmet toggling like hardsuits. + Menshin: + - bugfix: Fixed mechs ballistic guns not firing bullets. + Xhuis: + - rscadd: Allows alt-clicking to adjust breath masks, flip caps, and unlock/lock + closets. + xxalpha: + - bugfix: Fixed jetpack trail animation. +2015-03-21: + Chocobro: + - rscadd: Checkered skirts can be adjusted to be worn shorter. + Incoming5643: + - tweak: Player controller uplifted mobs will be attacked by gold core mobs of different + species. + Jordie0608: + - bugfix: The backup shuttle will no longer be called if the emergency shuttle is + coming. + MMMiracles: + - rscadd: Adds 3 new bear-based foods. + - rscadd: Beary Pie -1 Plain Pie, 1 berry, 1 bear steak + - rscadd: Filet Migrawr - 5u of Manlydorf, 1 bear steak, 1 lighter(not used in crafting) + - rscadd: 'Bearger - 1 bun, 1 bear steak ' + Phil235: + - bugfix: Silicons are no longer blinded by welding. + Xhuis: + - rscadd: A new software update has given the Orion Trail game a cheat code menu. + While you can't access this normally (that's for a later software update), maybe + an emag could do it...? + Zelacks: + - bugfix: The chemical implant action button should now correctly inject all chemicals + when pressed. + pudl: + - rscadd: Adds normal security headsets to security lockers. + xxalpha: + - bugfix: Fixed cables on catwalks being destroyed when creating plating floor. + - rscadd: Portable machines can be mounted on any turf that could hold a cable. +2015-03-22: + Iamgoofball: + - bugfix: Fixes Morphine not knocking you out. + - rscdel: Hotline no longer exists. Poppies now have Saline-Glucose Solution. + - rscdel: Muriatic Acid, Caustic Soda, and Hydrogen Chloride have been removed, + along with the secondary meth recipe. The original recipe still works. + - experiment: Foam now produces more bang for your buck when mixed. Your foam grenades + should be larger now to account for the slowdown. + - rscadd: Adds Stabilizing Agent. This chemical will prevent the effects of certain + reactions from taking place in the container it is in, such as Smoke Powder + and Flash Powder, allowing you to get the raw forms of the powders for heating + up later. + - rscadd: Smoke Powder and Flash Powder can now be mixed along with Stabilizing + Agent in order to produce a powder version of the effects. You can then heat + these powders to 374K to get the effects. + - rscadd: Mixing them without Stabilizing Agent gives the default effects. + - rscadd: Adds Sonic Powder, a chemical that deafens and stuns within 5 tiles of + the reaction. It also follows the reaction rules of the other 2 powders. + - tweak: Liquid Dark Matter and Sorium also now work like the powders do. + - tweak: CLF3 now has a higher chance of making plating tiles, and the burn damage + caused by it scales based on your fire stacks. + - rscadd: Adds Pyrosium. This reagent heats up mobs by 30 degrees every 3 seconds + if it has oxygen to react with. Useful for when you want a delayed mix inside + of someone. + - rscadd: Adds Cryostylane. This reagent does the opposite of Pyrosium, but it + still requires oxygen to react with. + - rscadd: Adds Phlogiston. This reagent ignites you and gives you a single fire + stack every 3 seconds. Burn damage from this chemical scales up with the fire + stacks you have. Counter this with literally any chemical that purges other + chems. + - experiment: Smoke now transfers reagents to the mob, and applies touch reactions + on them. This means smoke can run out of reagents, no more infinite acid smoke. + It also only works on mobs, use the new Reagent Foam(tm) for your hellfoam needs. + I suggest a CLF3 Fluoroacid Black Powder mix. + - experiment: Added a derelict medibot to the code, will place a few on the derelict + when this PR is merged as to prevent mapping conflicts. + - rscadd: Adds Initropidril. 33% chance to hit with 5-25 TOX damage every 3 seconds, + and a 5-10% chance to either stun, cause lots of oxygen damage, or cause your + heart to stop. Get it from the traitor Poison Kit. + - rscadd: Adds Pancuronium. Paralyses you after 30 seconds, with a 7% chance to + cause 3-5 loss of breath. Get it from the traitor Poison Kit. + - rscadd: Adds Sodium Thiopental. Knocks you out after 30 seconds, and destroys + your stamina. Get it from the traitor Poison Kit. + - rscadd: Adds Sulfonal. +1 TOX per 3 seconds, knocks you out in 66 seconds. Mix + it with Acetone, Diethylamine, and Sulfur. + - rscadd: Adds Amantin. On the last second it is in you, it hits you with a stack + of TOX damage based on how long it's been in you. Get it from the traitor Poison + Kit. + - rscadd: Adds Lipolicide. +1 TOX unless you have nutriment in you. Mix it with + Mercury, Diethylamine, and Ephedrine. + - rscadd: Adds Coiine. +2 TOX and +5 loss of breath every 3 seconds. Get it from + the traitor Poison Kit. + - rscadd: Adds Curare. +1 TOX, +1 OXY, paralyzes after 33 seconds. Get it from the + traitor Poison Kit. + - rscadd: Adds a reagent_deleted() proc to reagents for effects upon the last time + it processes in you, like with Amantin. + - bugfix: Neurotoxin required temperature for mixing has been set to 674K, it was + 370K for some reason. + xxalpha: + - rscadd: 'Added Cybernetic Implants: Security HUD, Medical HUD, X-Ray, Thermals, + Anti-Drop, Anti-Stun. All implants are researchable and producible by R&D and + Robotics.' +2015-03-24: + Cheridan: + - rscadd: Adds pet collars. Use them to rename pets; Can also be worn if you're + a weirdo. + - rscadd: Adds the matyr objective to be dead at the round's end. You can get this + objective if you have no others that would need you to survive. + Dannno: + - rscadd: GAR glasses return. Yes, I got permission. Just who the hell do you think + I am? + Incoming5643: + - bugfix: Summon Events has been reworked to be a bit less manic. + - rscadd: Summon Events will turn off if the wizard and all apprentices die. Any + lingering effects are not reversed however. + - rscadd: Improving Summon Events will reduce the average time between events, but + not the minimum time between events. + - rscdel: Departmental Uprising has been made admin only for being an RP heavy event + that creates antags in an enviroment that doesn't really support that. + Mandurrrh: + - rscadd: Added a cyborg upgrade module for the satchel of holding. + Miauw: + - imageadd: Added a fancy white dress and a jester outfit. Sprites by Nienhaus. + Steelpoint, RemieRichards, and Gun Hog: + - rscadd: Nanotrasen Security has authorized modifications to the standard issue + helmets for officers. These helmets are now issued with a mounted camera, automatically + synced to your assigned station's camera network. In addition, the helmets also + include mounting points for the Seclite model of flashlights, found in your + station's security vendors. + - rscadd: Nanotrasen Security helmets are designed for easy repairs in the field. + Officers may remove their Seclite attachment with any screwdriver, and the camera's + assembly may be pried off with a crowbar. The assembly is also compatible with + analyzer upgrades for scanning through the station's structure, and EMP shielding + is possible by applying a sheet of plasma. +2015-03-25: + AnturK: + - rscadd: Added an arrow graffiti, made arrow and body graffiti face the same way + as the user + - rscadd: 'New changeling ability : Last Resort : Explode and infect corpses if + the situation looks grim' + Fayrik: + - rscdel: Deleted the toy crossbow that wasn't a gun, but flung projectiles like + a gun. Why was that even a thing? + - rscadd: Added an abstract new type of reusable ammo. + - rscadd: Added three new foam force guns and a foam force crossbow, all of which + take the new foam dart ammo. + - rscadd: Added foam force dart boxes to the autolathe, and two crates orderable + from cargo containing the new guns. + - rscadd: Added two new donksoft guns, the syndicate's own brand of Foam Force. + Available in all good uplinks! + - tweak: New crossbow can be won as an arcade prize. + - tweak: All kinds of ammo containers can now be used to rapidly collect live ammunition + on the ground. + - tweak: Speedloaders and traditional ammo boxes can now be restocked. + - bugfix: Security bots now react to being shot. + MrPerson: + - rscadd: Added a preference toggle for hearing instruments play as suggested by + PKPenguin321. + Pennwick: + - rscadd: Added a buildable Chem Master, board is in Circuit Imprinter. + Wjohnston: + - bugfix: Finally fixed the gulag shuttle missing a redemption console. diff --git a/html/changelogs/AnturK-LightningBolt.yml b/html/changelogs/AnturK-LightningBolt.yml new file mode 100644 index 00000000000..c5d672d4ab7 --- /dev/null +++ b/html/changelogs/AnturK-LightningBolt.yml @@ -0,0 +1,6 @@ +author: AnturK + +delete-after: True + +changes: + - rscadd: "Added new wizard spell : Lightning Bolt" diff --git a/html/changelogs/Iamgoofball-Flipping.yml b/html/changelogs/Iamgoofball-Flipping.yml new file mode 100644 index 00000000000..c92481bd5b4 --- /dev/null +++ b/html/changelogs/Iamgoofball-Flipping.yml @@ -0,0 +1,7 @@ +author: Iamgoofball + +delete-after: True + +changes: + - rscadd: "You can now *flip." + - experiment: "Objects now spin when thrown. Please report any oddities." \ No newline at end of file diff --git a/html/changelogs/RemieRichards-PR-8554.yml b/html/changelogs/RemieRichards-PR-8554.yml new file mode 100644 index 00000000000..580c5c98167 --- /dev/null +++ b/html/changelogs/RemieRichards-PR-8554.yml @@ -0,0 +1,5 @@ +author: RemieRichards +delete-after: True +changes: + - rscadd: "Monkeys can now wear ANY mask, not just ones they had specific icons for." + - rscadd: "Monkeys can now wear HATS, That's right, Monkey Hats!" diff --git a/html/changelogs/dannno-gavel.yml b/html/changelogs/dannno-gavel.yml new file mode 100644 index 00000000000..3ab904e6626 --- /dev/null +++ b/html/changelogs/dannno-gavel.yml @@ -0,0 +1,6 @@ +author: Dannno + +delete-after: True + +changes: + - rscadd: "Added a hammer and gavel. Court is now in session." diff --git a/html/changelogs/phil235-SlimeAnimal.yml b/html/changelogs/phil235-SlimeAnimal.yml new file mode 100644 index 00000000000..416a7460cab --- /dev/null +++ b/html/changelogs/phil235-SlimeAnimal.yml @@ -0,0 +1,7 @@ +author: phil235 +delete-after: True + +changes: + - tweak: "All slimes are now simple animals instead of carbon life forms." + - rscdel: "Remove crit status from brain and slimes." + - rscadd: "Simple animal aliens can now see in the dark like regular aliens." diff --git a/html/changelogs/pudl-resprite.yml b/html/changelogs/pudl-resprite.yml new file mode 100644 index 00000000000..052adc0ed1c --- /dev/null +++ b/html/changelogs/pudl-resprite.yml @@ -0,0 +1,10 @@ +author: pudl + + +delete-after: True + + +changes: + - rscadd: "The detective's forensic scanner has been resprited." + - rscadd: "So has the cargo tagger." + - rscadd: "And the RPED." \ No newline at end of file diff --git a/html/changelogs/szunti-mining-mobs-night-vision.yml b/html/changelogs/szunti-mining-mobs-night-vision.yml new file mode 100644 index 00000000000..a1dfef5ae13 --- /dev/null +++ b/html/changelogs/szunti-mining-mobs-night-vision.yml @@ -0,0 +1,36 @@ +################################ +# 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: Szunti + +# 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: "Mining mobs vision adapted to darkness of the asteroids." diff --git a/html/create_object.html b/html/create_object.html index aa36cad8163..f4e0aa8644c 100644 --- a/html/create_object.html +++ b/html/create_object.html @@ -27,7 +27,7 @@
        - Type
        + Type
        Offset: A diff --git a/icons/ass/assdrone.png b/icons/ass/assdrone.png new file mode 100644 index 00000000000..748d207ff93 Binary files /dev/null and b/icons/ass/assdrone.png differ diff --git a/icons/effects/crayondecal.dmi b/icons/effects/crayondecal.dmi index 21331ed175a..e22bf5c64b9 100644 Binary files a/icons/effects/crayondecal.dmi and b/icons/effects/crayondecal.dmi differ diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index 14a4b7f8fef..0b9074d181b 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/emoji.dmi b/icons/emoji.dmi index 723c5b5b9d2..918acdaccb6 100644 Binary files a/icons/emoji.dmi and b/icons/emoji.dmi differ diff --git a/icons/mob/Easter.dmi b/icons/mob/Easter.dmi new file mode 100644 index 00000000000..f2c97d95ebc Binary files /dev/null and b/icons/mob/Easter.dmi differ diff --git a/icons/mob/alienqueen.dmi b/icons/mob/alienqueen.dmi index e34bc5bffed..72449bc2ea7 100644 Binary files a/icons/mob/alienqueen.dmi and b/icons/mob/alienqueen.dmi differ diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi index 29d459c6260..672d83db4da 100644 Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index 0b038856b89..b35a33aa5c4 100644 Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ diff --git a/icons/mob/belt.dmi b/icons/mob/belt.dmi index 459051e1c73..140bca9a4b2 100644 Binary files a/icons/mob/belt.dmi and b/icons/mob/belt.dmi differ diff --git a/icons/mob/corgi_back.dmi b/icons/mob/corgi_back.dmi index c3a34d66566..657a7c01a54 100644 Binary files a/icons/mob/corgi_back.dmi and b/icons/mob/corgi_back.dmi differ diff --git a/icons/mob/eyes.dmi b/icons/mob/eyes.dmi index 3479dda2dd1..e3229507a35 100644 Binary files a/icons/mob/eyes.dmi and b/icons/mob/eyes.dmi differ diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index b8eedb8f334..b62a5d7b4dc 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/inhands/clothing_lefthand.dmi b/icons/mob/inhands/clothing_lefthand.dmi index df394b37f25..269ec744d08 100644 Binary files a/icons/mob/inhands/clothing_lefthand.dmi and b/icons/mob/inhands/clothing_lefthand.dmi differ diff --git a/icons/mob/inhands/clothing_righthand.dmi b/icons/mob/inhands/clothing_righthand.dmi index 0ad3c2436b7..00f5e23eb0e 100644 Binary files a/icons/mob/inhands/clothing_righthand.dmi and b/icons/mob/inhands/clothing_righthand.dmi differ diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index b7eb6f96670..56503f0210d 100644 Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index d6492bd957e..86ee365b5c8 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/mob/monkey.dmi b/icons/mob/monkey.dmi index d1872d6aaff..fd2ca052740 100644 Binary files a/icons/mob/monkey.dmi and b/icons/mob/monkey.dmi differ diff --git a/icons/mob/pets.dmi b/icons/mob/pets.dmi new file mode 100644 index 00000000000..8179f08d362 Binary files /dev/null and b/icons/mob/pets.dmi differ diff --git a/icons/mob/screen_alert.dmi b/icons/mob/screen_alert.dmi index f1b776ad5a1..cf8d94b9594 100644 Binary files a/icons/mob/screen_alert.dmi and b/icons/mob/screen_alert.dmi differ diff --git a/icons/mob/screen_alien.dmi b/icons/mob/screen_alien.dmi index 8b37786d021..6cee26d4000 100644 Binary files a/icons/mob/screen_alien.dmi and b/icons/mob/screen_alien.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index ead9c0f14ba..af783f10da5 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/mob/ties.dmi b/icons/mob/ties.dmi index bab5533b140..51baed09306 100644 Binary files a/icons/mob/ties.dmi and b/icons/mob/ties.dmi differ diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index 271ef078024..00fdce1a431 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 c6a26c91778..3258cb936d1 100644 Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ diff --git a/icons/obj/clothing/glasses.dmi b/icons/obj/clothing/glasses.dmi index b0d6821f3a2..86209503cd1 100644 Binary files a/icons/obj/clothing/glasses.dmi and b/icons/obj/clothing/glasses.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index 276aaa7e525..9e67d990c48 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index d94332944a2..ccda4d6b1cd 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/clothing/ties.dmi b/icons/obj/clothing/ties.dmi index 7be081f9579..c3a27ecee84 100644 Binary files a/icons/obj/clothing/ties.dmi and b/icons/obj/clothing/ties.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index dcdb7691b5c..28247e78c06 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index 2ea63e08ba0..e501b24f404 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/icons/obj/food.dmi b/icons/obj/food.dmi index a3bc7cb5293..89112e632d9 100644 Binary files a/icons/obj/food.dmi and b/icons/obj/food.dmi differ diff --git a/icons/obj/food_ingredients.dmi b/icons/obj/food_ingredients.dmi index 6e122ca9a36..b5504ea1546 100644 Binary files a/icons/obj/food_ingredients.dmi and b/icons/obj/food_ingredients.dmi differ diff --git a/icons/obj/guns/toy.dmi b/icons/obj/guns/toy.dmi new file mode 100644 index 00000000000..e3700ae841a Binary files /dev/null and b/icons/obj/guns/toy.dmi differ diff --git a/icons/obj/hydroponics/harvest.dmi b/icons/obj/hydroponics/harvest.dmi index f841e089491..a6973c6bf1e 100644 Binary files a/icons/obj/hydroponics/harvest.dmi and b/icons/obj/hydroponics/harvest.dmi differ diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi index ab9b69c469f..0dd8ac348bd 100644 Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ diff --git a/icons/obj/kitchen.dmi b/icons/obj/kitchen.dmi index 5e15820d45e..4988bb5a4c6 100644 Binary files a/icons/obj/kitchen.dmi and b/icons/obj/kitchen.dmi differ diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi index a1610b9e284..e15935f6ff3 100644 Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index ee4ae2f82cf..98aa12253ce 100644 Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index 28390abff25..93ebade829d 100644 Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ diff --git a/icons/obj/toy.dmi b/icons/obj/toy.dmi index 5c62c63a925..428dd8df22f 100644 Binary files a/icons/obj/toy.dmi and b/icons/obj/toy.dmi differ diff --git a/icons/obj/watercloset.dmi b/icons/obj/watercloset.dmi index 2b0a66d9ac5..e31bb79d247 100644 Binary files a/icons/obj/watercloset.dmi and b/icons/obj/watercloset.dmi differ diff --git a/icons/obj/weapons.dmi b/icons/obj/weapons.dmi index 3bedbd10ad3..3ffe470d625 100644 Binary files a/icons/obj/weapons.dmi and b/icons/obj/weapons.dmi differ diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm index 574427f927b..98df3b72e06 100644 --- a/interface/stylesheet.dm +++ b/interface/stylesheet.dm @@ -11,6 +11,8 @@ em {font-style: normal; font-weight: bold;} .motd a, .motd a:link, .motd a:visited, .motd a:active, .motd a:hover {color: #638500;} +.italics { font-style: italic;} + .prefix { font-weight: bold;} .ooc { font-weight: bold;} @@ -48,10 +50,11 @@ h1.alert, h2.alert {color: #000000;} .disarm {color: #990000;} .passive {color: #660000;} -.userdanger {color: #ff0000; font-weight: bold;} +.userdanger {color: #ff0000; font-weight: bold; font-size: 3;} .danger {color: #ff0000;} .warning {color: #ff0000; font-style: italic;} .announce {color: #228b22; font-weight: bold;} +.boldannounce {color: #ff0000; font-weight: bold;} .rose {color: #ff5050;} .info {color: #0000CC;} .notice {color: #000099;} diff --git a/sound/effects/xylophone1.ogg b/sound/effects/xylophone1.ogg deleted file mode 100644 index 516d0f1a713..00000000000 Binary files a/sound/effects/xylophone1.ogg and /dev/null differ diff --git a/sound/effects/xylophone2.ogg b/sound/effects/xylophone2.ogg deleted file mode 100644 index b5adafcc5ce..00000000000 Binary files a/sound/effects/xylophone2.ogg and /dev/null differ diff --git a/sound/effects/xylophone3.ogg b/sound/effects/xylophone3.ogg deleted file mode 100644 index a3e7907d4a5..00000000000 Binary files a/sound/effects/xylophone3.ogg and /dev/null differ diff --git a/sound/items/gavel.ogg b/sound/items/gavel.ogg new file mode 100644 index 00000000000..751eb0ea219 Binary files /dev/null and b/sound/items/gavel.ogg differ diff --git a/tgstation.dme b/tgstation.dme index c8412f7f2b1..1c8c71dedb4 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -28,6 +28,7 @@ #include "code\__DEFINES\math.dm" #include "code\__DEFINES\misc.dm" #include "code\__DEFINES\preferences.dm" +#include "code\__DEFINES\say.dm" #include "code\__DEFINES\sight.dm" #include "code\__DEFINES\stat.dm" #include "code\__HELPERS\_logging.dm" @@ -228,6 +229,7 @@ #include "code\datums\spells\genetic.dm" #include "code\datums\spells\inflict_handler.dm" #include "code\datums\spells\knock.dm" +#include "code\datums\spells\lightning.dm" #include "code\datums\spells\mime.dm" #include "code\datums\spells\mind_transfer.dm" #include "code\datums\spells\projectile.dm" @@ -303,6 +305,7 @@ #include "code\game\gamemodes\changeling\powers\fakedeath.dm" #include "code\game\gamemodes\changeling\powers\fleshmend.dm" #include "code\game\gamemodes\changeling\powers\glands.dm" +#include "code\game\gamemodes\changeling\powers\headcrab.dm" #include "code\game\gamemodes\changeling\powers\hivemind.dm" #include "code\game\gamemodes\changeling\powers\humanform.dm" #include "code\game\gamemodes\changeling\powers\lesserform.dm" @@ -538,6 +541,7 @@ #include "code\game\objects\effects\spawners\vaultspawner.dm" #include "code\game\objects\items\apc_frame.dm" #include "code\game\objects\items\blueprints.dm" +#include "code\game\objects\items\body_egg.dm" #include "code\game\objects\items\bodybag.dm" #include "code\game\objects\items\candle.dm" #include "code\game\objects\items\crayons.dm" @@ -600,6 +604,7 @@ #include "code\game\objects\items\weapons\cigs_lighters.dm" #include "code\game\objects\items\weapons\clown_items.dm" #include "code\game\objects\items\weapons\cosmetics.dm" +#include "code\game\objects\items\weapons\courtroom.dm" #include "code\game\objects\items\weapons\defib.dm" #include "code\game\objects\items\weapons\dice.dm" #include "code\game\objects\items\weapons\dna_injector.dm" @@ -786,6 +791,7 @@ #include "code\modules\admin\verbs\adminpm.dm" #include "code\modules\admin\verbs\adminsay.dm" #include "code\modules\admin\verbs\atmosdebug.dm" +#include "code\modules\admin\verbs\bluespacearty.dm" #include "code\modules\admin\verbs\BrokenInhands.dm" #include "code\modules\admin\verbs\buildmode.dm" #include "code\modules\admin\verbs\cinematic.dm" @@ -850,7 +856,6 @@ #include "code\modules\clothing\gloves\boxing.dm" #include "code\modules\clothing\gloves\color.dm" #include "code\modules\clothing\gloves\miscellaneous.dm" -#include "code\modules\clothing\gloves\ninja.dm" #include "code\modules\clothing\head\collectable.dm" #include "code\modules\clothing\head\hardhat.dm" #include "code\modules\clothing\head\helmet.dm" @@ -869,7 +874,6 @@ #include "code\modules\clothing\spacesuits\chronosuit.dm" #include "code\modules\clothing\spacesuits\hardsuit.dm" #include "code\modules\clothing\spacesuits\miscellaneous.dm" -#include "code\modules\clothing\spacesuits\ninja.dm" #include "code\modules\clothing\spacesuits\syndi.dm" #include "code\modules\clothing\suits\armor.dm" #include "code\modules\clothing\suits\bio.dm" @@ -919,7 +923,6 @@ #include "code\modules\events\mass_hallucination.dm" #include "code\modules\events\meateor_wave.dm" #include "code\modules\events\meteor_wave.dm" -#include "code\modules\events\ninja.dm" #include "code\modules\events\prison_break.dm" #include "code\modules\events\radiation_storm.dm" #include "code\modules\events\shuttle_loan.dm" @@ -985,7 +988,6 @@ #include "code\modules\food&drinks\recipes\tablecraft\recipes_bread.dm" #include "code\modules\food&drinks\recipes\tablecraft\recipes_burger.dm" #include "code\modules\food&drinks\recipes\tablecraft\recipes_cake.dm" -#include "code\modules\food&drinks\recipes\tablecraft\recipes_dough.dm" #include "code\modules\food&drinks\recipes\tablecraft\recipes_egg.dm" #include "code\modules\food&drinks\recipes\tablecraft\recipes_meat.dm" #include "code\modules\food&drinks\recipes\tablecraft\recipes_misc.dm" @@ -996,6 +998,8 @@ #include "code\modules\food&drinks\recipes\tablecraft\recipes_sandwich.dm" #include "code\modules\food&drinks\recipes\tablecraft\recipes_soup.dm" #include "code\modules\food&drinks\recipes\tablecraft\recipes_spaghetti.dm" +#include "code\modules\holiday\easter.dm" +#include "code\modules\holiday\holidays.dm" #include "code\modules\hydroponics\biogenerator.dm" #include "code\modules\hydroponics\grown.dm" #include "code\modules\hydroponics\growninedible.dm" @@ -1045,6 +1049,7 @@ #include "code\modules\mob\living\damage_procs.dm" #include "code\modules\mob\living\death.dm" #include "code\modules\mob\living\emote.dm" +#include "code\modules\mob\living\life.dm" #include "code\modules\mob\living\living.dm" #include "code\modules\mob\living\living_defense.dm" #include "code\modules\mob\living\living_defines.dm" @@ -1124,18 +1129,7 @@ #include "code\modules\mob\living\carbon\monkey\life.dm" #include "code\modules\mob\living\carbon\monkey\login.dm" #include "code\modules\mob\living\carbon\monkey\monkey.dm" -#include "code\modules\mob\living\carbon\monkey\say.dm" #include "code\modules\mob\living\carbon\monkey\update_icons.dm" -#include "code\modules\mob\living\carbon\slime\death.dm" -#include "code\modules\mob\living\carbon\slime\emote.dm" -#include "code\modules\mob\living\carbon\slime\examine.dm" -#include "code\modules\mob\living\carbon\slime\life.dm" -#include "code\modules\mob\living\carbon\slime\login.dm" -#include "code\modules\mob\living\carbon\slime\powers.dm" -#include "code\modules\mob\living\carbon\slime\say.dm" -#include "code\modules\mob\living\carbon\slime\slime.dm" -#include "code\modules\mob\living\carbon\slime\subtypes.dm" -#include "code\modules\mob\living\carbon\slime\update_icons.dm" #include "code\modules\mob\living\silicon\death.dm" #include "code\modules\mob\living\silicon\laws.dm" #include "code\modules\mob\living\silicon\login.dm" @@ -1187,7 +1181,6 @@ #include "code\modules\mob\living\simple_animal\friendly\lizard.dm" #include "code\modules\mob\living\simple_animal\friendly\mouse.dm" #include "code\modules\mob\living\simple_animal\friendly\pug.dm" -#include "code\modules\mob\living\simple_animal\friendly\slime.dm" #include "code\modules\mob\living\simple_animal\friendly\drone\_drone.dm" #include "code\modules\mob\living\simple_animal\friendly\drone\drones_as_items.dm" #include "code\modules\mob\living\simple_animal\friendly\drone\extra_drone_types.dm" @@ -1204,6 +1197,7 @@ #include "code\modules\mob\living\simple_animal\hostile\eyeballs.dm" #include "code\modules\mob\living\simple_animal\hostile\faithless.dm" #include "code\modules\mob\living\simple_animal\hostile\giant_spider.dm" +#include "code\modules\mob\living\simple_animal\hostile\headcrab.dm" #include "code\modules\mob\living\simple_animal\hostile\hivebot.dm" #include "code\modules\mob\living\simple_animal\hostile\hostile.dm" #include "code\modules\mob\living\simple_animal\hostile\killertomato.dm" @@ -1218,6 +1212,14 @@ #include "code\modules\mob\living\simple_animal\hostile\retaliate\bat.dm" #include "code\modules\mob\living\simple_animal\hostile\retaliate\clown.dm" #include "code\modules\mob\living\simple_animal\hostile\retaliate\retaliate.dm" +#include "code\modules\mob\living\simple_animal\slime\death.dm" +#include "code\modules\mob\living\simple_animal\slime\emote.dm" +#include "code\modules\mob\living\simple_animal\slime\life.dm" +#include "code\modules\mob\living\simple_animal\slime\powers.dm" +#include "code\modules\mob\living\simple_animal\slime\say.dm" +#include "code\modules\mob\living\simple_animal\slime\slime.dm" +#include "code\modules\mob\living\simple_animal\slime\subtypes.dm" +#include "code\modules\mob\living\simple_animal\slime\update_icons.dm" #include "code\modules\mob\new_player\login.dm" #include "code\modules\mob\new_player\logout.dm" #include "code\modules\mob\new_player\new_player.dm" @@ -1230,6 +1232,30 @@ #include "code\modules\nano\nanoexternal.dm" #include "code\modules\nano\nanomanager.dm" #include "code\modules\nano\nanoui.dm" +#include "code\modules\ninja\__ninjaDefines.dm" +#include "code\modules\ninja\admin_ninja_verbs.dm" +#include "code\modules\ninja\energy_katana.dm" +#include "code\modules\ninja\ninja_event.dm" +#include "code\modules\ninja\Ninja_Readme.dm" +#include "code\modules\ninja\suit\gloves.dm" +#include "code\modules\ninja\suit\head.dm" +#include "code\modules\ninja\suit\mask.dm" +#include "code\modules\ninja\suit\shoes.dm" +#include "code\modules\ninja\suit\SpiderOS.dm" +#include "code\modules\ninja\suit\suit.dm" +#include "code\modules\ninja\suit\suit_attackby.dm" +#include "code\modules\ninja\suit\suit_initialisation.dm" +#include "code\modules\ninja\suit\suit_process.dm" +#include "code\modules\ninja\suit\suit_verbs_handlers.dm" +#include "code\modules\ninja\suit\n_suit_verbs\energy_net_nets.dm" +#include "code\modules\ninja\suit\n_suit_verbs\ninja_adrenaline.dm" +#include "code\modules\ninja\suit\n_suit_verbs\ninja_cost_check.dm" +#include "code\modules\ninja\suit\n_suit_verbs\ninja_empulse.dm" +#include "code\modules\ninja\suit\n_suit_verbs\ninja_net.dm" +#include "code\modules\ninja\suit\n_suit_verbs\ninja_smoke.dm" +#include "code\modules\ninja\suit\n_suit_verbs\ninja_stars.dm" +#include "code\modules\ninja\suit\n_suit_verbs\ninja_stealth.dm" +#include "code\modules\ninja\suit\n_suit_verbs\ninja_teleporting.dm" #include "code\modules\paperwork\clipboard.dm" #include "code\modules\paperwork\filingcabinet.dm" #include "code\modules\paperwork\folders.dm" @@ -1305,10 +1331,12 @@ #include "code\modules\projectiles\guns\projectile\pistol.dm" #include "code\modules\projectiles\guns\projectile\revolver.dm" #include "code\modules\projectiles\guns\projectile\shotgun.dm" +#include "code\modules\projectiles\guns\projectile\toy.dm" #include "code\modules\projectiles\projectile\beams.dm" #include "code\modules\projectiles\projectile\bullets.dm" #include "code\modules\projectiles\projectile\energy.dm" #include "code\modules\projectiles\projectile\magic.dm" +#include "code\modules\projectiles\projectile\reusable.dm" #include "code\modules\projectiles\projectile\special.dm" #include "code\modules\reagents\Chemistry-Colours.dm" #include "code\modules\reagents\Chemistry-Goon-420BlazeIt.dm" @@ -1368,6 +1396,7 @@ #include "code\modules\research\designs\stock_parts_designs.dm" #include "code\modules\research\designs\telecomms_designs.dm" #include "code\modules\research\designs\weapon_designs.dm" +#include "code\modules\research\xenobiology\xenobiology.dm" #include "code\modules\scripting\Errors.dm" #include "code\modules\scripting\IDE.dm" #include "code\modules\scripting\Options.dm" @@ -1395,6 +1424,7 @@ #include "code\modules\surgery\brain_removal.dm" #include "code\modules\surgery\cavity_implant.dm" #include "code\modules\surgery\core_removal.dm" +#include "code\modules\surgery\cybernetic_implants.dm" #include "code\modules\surgery\eye_surgery.dm" #include "code\modules\surgery\gender_reassignment.dm" #include "code\modules\surgery\generic_steps.dm" @@ -1409,6 +1439,7 @@ #include "code\modules\surgery\tools.dm" #include "code\modules\surgery\xenomorph_removal.dm" #include "code\modules\surgery\organs\augments.dm" +#include "code\modules\surgery\organs\cybernetic_implants.dm" #include "code\modules\surgery\organs\helpers.dm" #include "code\modules\surgery\organs\organ.dm" #include "code\modules\telesci\bscrystal.dm"