From 50b4194ed370042c1e5ecc77c8be7ff1e8ed71ea Mon Sep 17 00:00:00 2001 From: Shadowlight213 Date: Tue, 8 Dec 2015 15:52:38 -0800 Subject: [PATCH 01/57] Removes the ability to listen in on the syndicate frequency via telecomms modifications --- code/game/machinery/telecomms/machine_interactions.dm | 9 ++++++--- code/game/machinery/telecomms/machines/bus.dm | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm index c4ce6fa4612..2a84cb6eea9 100644 --- a/code/game/machinery/telecomms/machine_interactions.dm +++ b/code/game/machinery/telecomms/machine_interactions.dm @@ -254,9 +254,12 @@ if(newfreq && canAccess(usr)) if(findtext(num2text(newfreq), ".")) newfreq *= 10 // shift the decimal one place - if(!(newfreq in freq_listening) && newfreq < 10000) - freq_listening.Add(newfreq) - temp = "-% New frequency filter assigned: \"[newfreq] GHz\" %-" + if(newfreq == 1213) + temp = "-% Error: Interference preventing filtering frequency: \"[newfreq] GHz\" %-" + else + if(!(newfreq in freq_listening) && newfreq < 10000) + freq_listening.Add(newfreq) + temp = "-% New frequency filter assigned: \"[newfreq] GHz\" %-" if(href_list["delete"]) diff --git a/code/game/machinery/telecomms/machines/bus.dm b/code/game/machinery/telecomms/machines/bus.dm index c81ecec4b32..680e668ba92 100644 --- a/code/game/machinery/telecomms/machines/bus.dm +++ b/code/game/machinery/telecomms/machines/bus.dm @@ -26,7 +26,8 @@ if(is_freq_listening(signal)) if(change_frequency) - signal.frequency = change_frequency + if(!(signal.frequency == 1213)) + signal.frequency = change_frequency if(!istype(machine_from, /obj/machinery/telecomms/processor) && machine_from != src) // Signal must be ready (stupid assuming machine), let's send it // send to one linked processor unit From 9210f7459ae111b4949b06058fc6f2a0585ab738 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Thu, 10 Dec 2015 04:32:31 -0600 Subject: [PATCH 02/57] Reactive Fixes --- code/modules/clothing/suits/armor.dm | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index b2219ef32e9..b595d3455b9 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -100,7 +100,7 @@ put_on_delay = 50 /obj/item/clothing/suit/armor/laserproof - name = "ablative armor vest" + name = "reflector vest" desc = "A vest that excels in protecting the wearer against energy projectiles, as well as occasionally reflecting them." icon_state = "armor_reflec" item_state = "armor_reflec" @@ -172,13 +172,13 @@ continue turfs += T if(!turfs.len) - turfs += pick(/turf in orange(6, src)) - var/turf/picked = pick(turfs) - if(!isturf(picked)) - return - if(H.buckled) - H.buckled.unbuckle_mob() - H.forceMove(picked) + turfs += pick(/turf in orange(6, H)) + var/turf/picked = pick(turfs) + if(!isturf(picked)) + return + if(H.buckled) + H.buckled.unbuckle_mob() + H.forceMove(picked) return 1 return 0 From f333562223346b508c1caf7305a171501f4057f3 Mon Sep 17 00:00:00 2001 From: AnturK Date: Fri, 11 Dec 2015 12:01:28 +0100 Subject: [PATCH 03/57] Adds Med Beam Gun --- code/modules/projectiles/guns/medbeam.dm | 114 +++++++++++++++++++++++ tgstation.dme | 1 + 2 files changed, 115 insertions(+) create mode 100644 code/modules/projectiles/guns/medbeam.dm diff --git a/code/modules/projectiles/guns/medbeam.dm b/code/modules/projectiles/guns/medbeam.dm new file mode 100644 index 00000000000..e20d878776a --- /dev/null +++ b/code/modules/projectiles/guns/medbeam.dm @@ -0,0 +1,114 @@ +/obj/item/weapon/gun/medbeam + name = "Medical Beamgun" + desc = "Delivers medical nanites in a focused beam." + icon = 'icons/obj/chronos.dmi' + icon_state = "chronogun" + item_state = "chronogun" + w_class = 3.0 + + var/mob/living/current_target + var/last_check = 0 + var/check_delay = 10 //Check los as often as possible, max resolution is SSobj tick though + var/max_range = 8 + var/active = 0 + var/datum/beam/current_beam = null + + heavy_weapon = 1 + +/obj/item/weapon/gun/medbeam/New() + ..() + SSobj.processing |= src + +/obj/item/weapon/gun/medbeam/dropped(mob/user) + ..() + LoseTarget() + +/obj/item/weapon/gun/medbeam/proc/LoseTarget() + if(active) + qdel(current_beam) + active = 0 + on_beam_relase(current_target) + current_target = null + +/obj/item/weapon/gun/medbeam/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override) + add_fingerprint(user) + + if(!isliving(target)) + return + if(current_target) + LoseTarget() + + current_target = target + active = 1 + current_beam = new(user,current_target,time=6000) + spawn(0) + current_beam.Start() + + feedback_add_details("gun_fired","[src.type]") + +/obj/item/weapon/gun/medbeam/afterattack(obj/target, mob/user, proximity) + if(target.loc == loc || target == user) + return + + if(!current_target && isliving(target)) + current_target = target + active = 1 + current_beam = new(user,current_target,time=6000) + spawn(0) + current_beam.Start() + +/obj/item/weapon/gun/medbeam/process() + var/mob/living/carbon/human/H = loc + if(!istype(H)) + LoseTarget() + return + + if(!current_target) + LoseTarget() + return + + if(world.time <= last_check+check_delay) + return + + last_check = world.time + + if(get_dist(H,current_target)>max_range || !los_check(H,current_target)) + LoseTarget() + H << "You lose control of the beam!" + return + + if(current_target) + on_beam_tick(current_target) + +/obj/item/weapon/gun/medbeam/proc/los_check(mob/user,mob/target) + var/turf/user_turf = user.loc + if(!istype(user_turf)) + return 0 + var/obj/dummy = new(user_turf) + dummy.pass_flags |= PASSTABLE & PASSGLASS & PASSGRILLE //Grille/Glass so it can be used through common windows + for(var/turf/turf in getline(user_turf,target)) + if(turf.density) + qdel(dummy) + return 0 + for(var/atom/movable/AM in turf) + if(!AM.CanPass(dummy,turf,1)) + qdel(dummy) + return 0 + for(var/obj/effect/overlay/beam/O in turf)// Don't cross the str-beams! + if(O.BeamSource!=user) + explosion(O.loc,0,3,5,8) + qdel(dummy) + return 0 + qdel(dummy) + return 1 + +/obj/item/weapon/gun/medbeam/proc/on_beam_hit(var/mob/living/target) + return + +/obj/item/weapon/gun/medbeam/proc/on_beam_tick(var/mob/living/target) + target.adjustBruteLoss(-4) + target.adjustFireLoss(-4) + return + +/obj/item/weapon/gun/medbeam/proc/on_beam_relase(var/mob/living/target) + return \ No newline at end of file diff --git a/tgstation.dme b/tgstation.dme index 1df1db2c615..89257801662 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1463,6 +1463,7 @@ #include "code\modules\projectiles\guns\energy.dm" #include "code\modules\projectiles\guns\grenade_launcher.dm" #include "code\modules\projectiles\guns\magic.dm" +#include "code\modules\projectiles\guns\medbeam.dm" #include "code\modules\projectiles\guns\projectile.dm" #include "code\modules\projectiles\guns\syringe_gun.dm" #include "code\modules\projectiles\guns\energy\laser.dm" From a54c9632fa41fb08a381ebb3376fc56ea8d94a70 Mon Sep 17 00:00:00 2001 From: The-Albinobigfoot Date: Fri, 11 Dec 2015 13:52:12 -0800 Subject: [PATCH 04/57] Shadowpeople (i.e. ???) born of the Wish-granter can now properly see in the dark as (presumably) intended :cl: bugfix: The Wishgranter now displays its faith in humans with a bit less enthusiasm. /:cl: --- code/modules/mob/living/carbon/human/species_types.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/mob/living/carbon/human/species_types.dm b/code/modules/mob/living/carbon/human/species_types.dm index 69732a8e1a4..f2240d7ad07 100644 --- a/code/modules/mob/living/carbon/human/species_types.dm +++ b/code/modules/mob/living/carbon/human/species_types.dm @@ -163,6 +163,7 @@ datum/species/human/spec_death(gibbed, mob/living/carbon/human/H) name = "???" id = "shadow" darksight = 8 + invis_sight = SEE_INVISIBLE_MINIMUM sexes = 0 ignored_by = list(/mob/living/simple_animal/hostile/faithless) meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/shadow From b274d3ddc5a5a80a936468fde552b5d9431c230b Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Fri, 11 Dec 2015 18:33:00 -0500 Subject: [PATCH 05/57] Dualsabers will now make you flip only twice, instead of up to twelve times. --- code/game/objects/items/weapons/twohanded.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index f48b7f6e9b1..889d629d926 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -235,7 +235,7 @@ spawn(0) for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2)) user.dir = i - if(prob(20)) + if(i == 8) user.emote("flip") sleep(1) From ec85d5ceec0fa6b1f7ea7785d9b41cb964479e7a Mon Sep 17 00:00:00 2001 From: AnturK Date: Fri, 11 Dec 2015 20:44:53 +0100 Subject: [PATCH 06/57] Fixes beam crossing Adds Medbeam gun to Nukeop Uplink Adds Medbeam gun to ERT medic equipment --- code/datums/uplink_item.dm | 7 +++++++ code/modules/clothing/outfits/ert.dm | 3 ++- code/modules/projectiles/guns/medbeam.dm | 11 +++++++---- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index 561a583bc7c..b7884ff874c 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -698,6 +698,13 @@ var/list/uplink_items = list() gamemodes = list(/datum/game_mode/nuclear,/datum/game_mode/gang) surplus = 20 +/datum/uplink_item/device_tools/medgun + name = "Medbeam Gun" + desc = "Medical Beam Gun, useful in prolonged firefights." + item = /obj/item/weapon/gun/medbeam + cost = 15 + gamemodes = list(/datum/game_mode/nuclear) + // IMPLANTS diff --git a/code/modules/clothing/outfits/ert.dm b/code/modules/clothing/outfits/ert.dm index 0e1b16d75fd..7209b40e937 100644 --- a/code/modules/clothing/outfits/ert.dm +++ b/code/modules/clothing/outfits/ert.dm @@ -104,7 +104,8 @@ /obj/item/weapon/melee/baton/loaded=1,\ /obj/item/clothing/mask/gas/sechailer=1,\ /obj/item/weapon/gun/energy/gun=1,\ - /obj/item/weapon/reagent_containers/hypospray/combat=1) + /obj/item/weapon/reagent_containers/hypospray/combat=1,\ + /obj/item/weapon/gun/medbeam=1) /datum/outfit/ert/medic/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) ..() diff --git a/code/modules/projectiles/guns/medbeam.dm b/code/modules/projectiles/guns/medbeam.dm index e20d878776a..48a56421ff6 100644 --- a/code/modules/projectiles/guns/medbeam.dm +++ b/code/modules/projectiles/guns/medbeam.dm @@ -94,9 +94,9 @@ if(!AM.CanPass(dummy,turf,1)) qdel(dummy) return 0 - for(var/obj/effect/overlay/beam/O in turf)// Don't cross the str-beams! - if(O.BeamSource!=user) - explosion(O.loc,0,3,5,8) + for(var/obj/effect/ebeam/medical/B in turf)// Don't cross the str-beams! + if(B.owner != current_beam) + explosion(B.loc,0,3,5,8) qdel(dummy) return 0 qdel(dummy) @@ -111,4 +111,7 @@ return /obj/item/weapon/gun/medbeam/proc/on_beam_relase(var/mob/living/target) - return \ No newline at end of file + return + +/obj/effect/ebeam/medical + name = "medical beam" \ No newline at end of file From a2d008676228800fa0459dab36e6c08826369319 Mon Sep 17 00:00:00 2001 From: MMMiracles Date: Sat, 12 Dec 2015 19:09:47 -0500 Subject: [PATCH 07/57] consistency is a virtue --- code/modules/awaymissions/corpse.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index a6d4c9eac07..39705e54307 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -317,7 +317,7 @@ /obj/effect/landmark/corpse/skeleton name = "skeletal remains" mobname = "skeleton" - mob_species = "skeleton" + mob_species = /datum/species/skeleton //why doesnt this use the species' id? mobgender = NEUTER @@ -332,7 +332,7 @@ /obj/effect/landmark/corpse/zombie name = "rotting corpse" mobname = "zombie" - mob_species = "zombie" + mob_species = /datum/species/zombie /obj/effect/landmark/corpse/zombie/alive death = FALSE From bf902bbe7cd06479c1271a2c724dcf282ef181e3 Mon Sep 17 00:00:00 2001 From: MMMiracles Date: Sat, 12 Dec 2015 19:15:49 -0500 Subject: [PATCH 08/57] question answered, then. --- code/modules/awaymissions/corpse.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index 39705e54307..82e20eaa287 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -317,7 +317,7 @@ /obj/effect/landmark/corpse/skeleton name = "skeletal remains" mobname = "skeleton" - mob_species = /datum/species/skeleton //why doesnt this use the species' id? + mob_species = /datum/species/skeleton mobgender = NEUTER From 401a947a0872c400e77c6d0d4625c668f6b190e6 Mon Sep 17 00:00:00 2001 From: MMMiracles Date: Sat, 12 Dec 2015 23:54:00 -0500 Subject: [PATCH 09/57] fixes plasmaman corpse spawner, adds a comment about it using the typepath. --- code/modules/awaymissions/corpse.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index 82e20eaa287..ad7447c66a9 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -8,7 +8,7 @@ name = "Unknown" var/mobname = "default" //Use for the ghost spawner variant, so they don't come out named "sleeper" var/mobgender = MALE //Set to male by default due to the patriarchy. Other options include FEMALE and NEUTER - var/mob_species = null //Set to make them a mutant race such as lizard or skeleton + var/mob_species = null //Set to make them a mutant race such as lizard or skeleton. Uses the datum typepath instead of the ID. var/corpseuniform = null //Set this to an object path to have the slot filled with said object on the corpse. var/corpsesuit = null var/corpseshoes = null @@ -259,7 +259,7 @@ /obj/effect/landmark/corpse/plasmaman - mob_species = "plasmaman" + mob_species = /datum/species/plasmaman corpsehelmet = /obj/item/clothing/head/helmet/space/plasmaman corpseuniform = /obj/item/clothing/under/plasmaman corpseback = /obj/item/weapon/tank/internals/plasmaman/full From 2c9adb12f39f3b1afd8066fc69dd6b009e2b61fd Mon Sep 17 00:00:00 2001 From: AnturK Date: Sun, 13 Dec 2015 15:00:19 +0100 Subject: [PATCH 10/57] Fixes spell logging runtime Fixes lava runtime Fixes mecha ore scanner runtime Fixes crayon writing runtime Fixes latejoin headrev runtime --- code/datums/spell.dm | 2 +- code/game/gamemodes/revolution/revolution.dm | 2 +- code/game/mecha/equipment/tools/mining_tools.dm | 7 ++++--- code/game/turfs/simulated/floor/plating.dm | 5 +++-- code/modules/paperwork/paper.dm | 3 ++- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/code/datums/spell.dm b/code/datums/spell.dm index 29fe4dfd7ed..f717b4534e4 100644 --- a/code/datums/spell.dm +++ b/code/datums/spell.dm @@ -176,7 +176,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin /obj/effect/proc_holder/spell/proc/perform(list/targets, recharge = 1, mob/user = usr) //if recharge is started is important for the trigger spells before_cast(targets) invocation(user) - if(user.ckey) + if(user && user.ckey) user.attack_log += text("\[[time_stamp()]\] [user.real_name] ([user.ckey]) cast the spell [name].") spawn(0) if(charge_type == "recharge" && recharge) diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm index fe21e018bd8..43d2b2f6ae7 100644 --- a/code/game/gamemodes/revolution/revolution.dm +++ b/code/game/gamemodes/revolution/revolution.dm @@ -192,7 +192,7 @@ if(khrushchev.current && khrushchev.current.client && khrushchev.current.stat != DEAD) if(ROLE_REV in khrushchev.current.client.prefs.be_special) promotable_revs += khrushchev - if(promotable_revs) + if(promotable_revs.len) var/datum/mind/stalin = pick(promotable_revs) revolutionaries -= stalin head_revolutionaries += stalin diff --git a/code/game/mecha/equipment/tools/mining_tools.dm b/code/game/mecha/equipment/tools/mining_tools.dm index 8d94ed2e15e..07231ed8854 100644 --- a/code/game/mecha/equipment/tools/mining_tools.dm +++ b/code/game/mecha/equipment/tools/mining_tools.dm @@ -118,12 +118,13 @@ var/obj/mecha/working/mecha = loc if(!mecha.occupant) return + var/mob/pilot = mecha.occupant var/list/occupant = list() - occupant |= mecha.occupant - mecha.occupant.sight |= SEE_TURFS + occupant |= pilot + pilot.sight |= SEE_TURFS scanning = 1 mineral_scan_pulse(occupant,get_turf(loc)) spawn(equip_cooldown) scanning = 0 - mecha.occupant.sight -= SEE_TURFS + pilot.sight -= SEE_TURFS diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm index 0465b15341e..5ba6f4a7ac4 100644 --- a/code/game/turfs/simulated/floor/plating.dm +++ b/code/game/turfs/simulated/floor/plating.dm @@ -214,8 +214,9 @@ else if (istype(AM, /mob/living)) var/mob/living/L = AM L.adjustFireLoss(20) - L.adjust_fire_stacks(20) - L.IgniteMob() + if(L) //mobs turning into object corpses could get deleted here. + L.adjust_fire_stacks(20) + L.IgniteMob() /turf/simulated/floor/plating/lava/attackby(obj/item/C, mob/user, params) //Lava isn't a good foundation to build on return diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 739b17cfff0..076fb9526e1 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -202,6 +202,7 @@ t = "[t]" else // If it is a crayon, and he still tries to use these, make them empty! + var/obj/item/toy/crayon/C = P t = replacetext(t, "\[*\]", "") t = replacetext(t, "\[hr\]", "") t = replacetext(t, "\[small\]", "") @@ -209,7 +210,7 @@ t = replacetext(t, "\[list\]", "") t = replacetext(t, "\[/list\]", "") - t = "[t]" + t = "[t]" // t = replacetext(t, "#", "") // Junk converted to nothing! From c301b51e9a7f4d8c79c70a4aaac3796a8384e36a Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Sun, 13 Dec 2015 08:06:54 -0600 Subject: [PATCH 11/57] Sentience Fixes --- .../living/simple_animal/hostile/statue.dm | 4 ++ .../mob/living/simple_animal/simple_animal.dm | 4 ++ .../research/xenobiology/xenobiology.dm | 56 +++++-------------- 3 files changed, 22 insertions(+), 42 deletions(-) diff --git a/code/modules/mob/living/simple_animal/hostile/statue.dm b/code/modules/mob/living/simple_animal/hostile/statue.dm index b16d811e5ac..301c22d736b 100644 --- a/code/modules/mob/living/simple_animal/hostile/statue.dm +++ b/code/modules/mob/living/simple_animal/hostile/statue.dm @@ -216,3 +216,7 @@ else target.see_invisible = SEE_INVISIBLE_LIVING name = "Toggle Nightvision \[OFF]" + + +/mob/living/simple_animal/hostile/statue/sentience_act() + faction -= "neutral" \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 4773aafbce5..1f9895bd796 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -513,3 +513,7 @@ nest.spawned_mobs -= src nest = null return ..() + + +/mob/living/simple_animal/proc/sentience_act() //Called when a simple animal gains sentience via gold slime potion + return \ No newline at end of file diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index ad6483d7408..e6422c4ed95 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -175,56 +175,28 @@ return..() var/mob/living/simple_animal/SM = M if(SM.sentience_type != sentience_type) - user << "The potion won't work on [M]." + user << "The potion won't work on [SM]." return ..() - user << "You offer the sentience potion to [M]..." + user << "You offer the sentience potion to [SM]..." being_used = 1 - var/list/candidates = get_candidates(ROLE_ALIEN, ALIEN_AFK_BRACKET) - - shuffle(candidates) - - var/time_passed = world.time - var/list/consenting_candidates = list() - - for(var/candidate in candidates) - - if(candidate in not_interested) - continue - - spawn(0) - switch(alert(candidate, "Would you like to play as [M.name]? Please choose quickly!","Confirmation","Yes","No")) - if("Yes") - if((world.time-time_passed)>=50 || !src) - return - consenting_candidates += candidate - if("No") - if(!src) - return - not_interested += candidate - - sleep(50) - - if(!src) - return - - listclearnulls(consenting_candidates) //some candidates might have left during sleep(50) - - if(consenting_candidates.len) - var/client/C = null - C = pick(consenting_candidates) - M.key = C.key - M.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] accepts the potion and suddenly becomes attentive and aware. It worked!" + var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as [SM.name]?", ROLE_ALIEN, null, ROLE_ALIEN, 50) + var/mob/dead/observer/theghost = null + if(candidates.len) + theghost = pick(candidates) + SM.key = theghost.key + SM.languages |= HUMAN + SM.faction = user.faction + SM.sentience_act() + SM << "All at once it makes sense: you know what you are and who you are! Self awareness is yours!" + SM << "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 << "[SM] accepts the potion and suddenly becomes attentive and aware. It worked!" qdel(src) else - user << "[M] looks interested for a moment, but then looks back down. Maybe you should try again later." + user << "[SM] looks interested for a moment, but then looks back down. Maybe you should try again later." being_used = 0 ..() From e9e4ff735db5f9e21483e66f5c7d83cb2cdddfc7 Mon Sep 17 00:00:00 2001 From: xxalpha Date: Mon, 14 Dec 2015 00:48:01 +0000 Subject: [PATCH 12/57] Added maintenance glass airlock and external glass airlock. --- code/game/machinery/doors/airlock_types.dm | 14 ++++++++++++++ code/game/objects/structures/door_assembly.dm | 10 ++++++++++ .../obj/doors/airlocks/external/external.dmi | Bin 6174 -> 6568 bytes .../obj/doors/airlocks/external/overlays.dmi | Bin 3131 -> 3277 bytes 4 files changed, 24 insertions(+) diff --git a/code/game/machinery/doors/airlock_types.dm b/code/game/machinery/doors/airlock_types.dm index a9855999280..852f62ffeca 100644 --- a/code/game/machinery/doors/airlock_types.dm +++ b/code/game/machinery/doors/airlock_types.dm @@ -108,6 +108,12 @@ doortype = /obj/structure/door_assembly/door_assembly_viro/glass glass = 1 +/obj/machinery/door/airlock/glass_maintenance + icon = 'icons/obj/doors/airlocks/station/maintenance.dmi' + opacity = 0 + doortype = /obj/structure/door_assembly/door_assembly_mai/glass + glass = 1 + ////////////////////////////////// /* Station Airlocks Mineral @@ -216,6 +222,14 @@ overlays_file = 'icons/obj/doors/airlocks/external/overlays.dmi' doortype = /obj/structure/door_assembly/door_assembly_ext +/obj/machinery/door/airlock/glass_external + name = "external airlock" + icon = 'icons/obj/doors/airlocks/external/external.dmi' + overlays_file = 'icons/obj/doors/airlocks/external/overlays.dmi' + doortype = /obj/structure/door_assembly/door_assembly_ext/glass + opacity = 0 + glass = 1 + ////////////////////////////////// /* Centcom Airlocks diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm index aed76f2b6dc..2054d013079 100644 --- a/code/game/objects/structures/door_assembly.dm +++ b/code/game/objects/structures/door_assembly.dm @@ -142,20 +142,30 @@ icon = 'icons/obj/doors/airlocks/station/maintenance.dmi' typetext = "maintenance" icontext = "mai" + glass_type = /obj/machinery/door/airlock/glass_maintenance airlock_type = /obj/machinery/door/airlock/maintenance anchored = 1 state = 1 +/obj/structure/door_assembly/door_assembly_mai/glass + mineral = "glass" + material = "glass" + /obj/structure/door_assembly/door_assembly_ext name = "external airlock assembly" icon = 'icons/obj/doors/airlocks/external/external.dmi' overlays_file = 'icons/obj/doors/airlocks/external/overlays.dmi' typetext = "external" icontext = "ext" + glass_type = /obj/machinery/door/airlock/glass_external airlock_type = /obj/machinery/door/airlock/external anchored = 1 state = 1 +/obj/structure/door_assembly/door_assembly_ext/glass + mineral = "glass" + material = "glass" + /obj/structure/door_assembly/door_assembly_fre name = "freezer airlock assembly" icon = 'icons/obj/doors/airlocks/station/freezer.dmi' diff --git a/icons/obj/doors/airlocks/external/external.dmi b/icons/obj/doors/airlocks/external/external.dmi index 1130408c810b75d220cf3d9a98285efcefe91b7d..4b0461ed59a2119013ad7c72b207d5a3f50d2570 100644 GIT binary patch literal 6568 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 b@xXNRbgqUoEmz{N7l5v|kyeAo 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 LFwt(*bcy>fSKE6& diff --git a/icons/obj/doors/airlocks/external/overlays.dmi b/icons/obj/doors/airlocks/external/overlays.dmi index ce68af3e209fa7e3c527b7d3fc4794bffabcc3eb..9bd8e5dfa92c7dce3178ae86253fe4b38e9625f5 100644 GIT binary patch literal 3277 zcmai1c{r478y`y<99d3?j&KmNRSxA?MzUlHp=2k`Xe?Q>Z!;ovl9HlfY{{0Gm`3(N z5!v_MD5qowW0{2+GxLqkIoJ1{>s+1hkN16__kEuGe((Ewe)sSGJ$G%b%>?))`2YZb zfcXVuJN9#N{{kLl-zC+2KLP+80?`gvLyf_=yhETtq0qpa06-+NDx=-^?a3dK2PyWc z6yGjn+I)zFvRn#9^fz(8y9mFdy?!gR)Q7bYS+8}a)~SsZbUaibFqaD9A=iC0OS|5j z$mgD)ucIrG7hPVcdX_L88Yg+|v4c^$C-~x|;tU-=P=B)%p`B64*)#3q!1L3(eKRJ1 zy$#fS@iD(&=s~icTS)2f3rz=^JBJ@>65@8MiV8nXb_Aj_qib$7XeaWdNi|aRh$^P7 zM%}}%i6J+rRpi%?O{~47hvpO12VjS5g+M;)zgP9V@3{_1s_Q<`3u^z-Iq%e$ffLW> z@_q=Ku&#C|Ds>XIB??@&3bhtO7#?-W{ng3Qvm5-+0)DL*n=IG>0Qh6fjn6qmBG=|| zfeuiq_nU#RsqlOE0-$$~E(Mv?2XSSEp9fZ!$ah_|uu6rX4)9i-x>j@aV%t=Ds&HoQ zONd;I?B0RWqd$shM_-y)6}1Njp}*dlaVx&5vYy_g((!u9#3y-lW$&za)WGtJ9?{Y0 ztJNTqsH4A)SYAP_?AG=5_e%ioUm+g^$jZUtLLA&lKp7ch0Ea9m5GZVDm_9-@K_#lUKt{ zjU;PJCeE2=&8F056|`(^d2%_)!jlL}1)V=><*P-0t5@v=gObf3QK>v2Wj zPQ{xg8P9VhZJ5kj=Mwr8@~nLmojCs{j9ko9J)#2D(mE86MUZh#f%k^#AzQjN=>aoavcZpEcq5bP!$`NLS29D6AYt(s>~d@BgcV(VkE zRxQLc&qf-@*ul=Tt^u+`rbRW;cRH};_mRpcV5_$gYKMJIu!<-c3-kah9cM_gaxFfg z7vA0{#)pZ0ff8F~z7ezO3~bp>n_kL8)dvSJ@RiqCZ8Gl|spZx)w;nadZ#s}Zz28r9 zbV4gjd0bFdK+doSb%PaJXEj@T)z75-0Gi9WvS!#-l3uv%Rfh zs<2Sd^VrvwzX*W2xs#4?aJ+w!2S4S_&HbD`{s-*-fynMkCfrxn{fUZ2+@4t-3_M>u ziKF)?;hHR?$V1=ewU_q?Dua2Vk|uh$tauw32un`0GG!3A7z* zL?ABbD#J)kBc8di{}}^vyY%(FM`tcOtRhO83Lj&qa%V)^R&9zIdH}zKC2ht`zr&0B zMs03qQ+fQad%FQ!KzXzsaU5UwJi3v*)Er>zjj&^TL@gxSQh6TpHGKP#MgXH@B8PmG z*K)d+fH(8)Q5ca9nlQjbzB4!yX-5eCY!34Uvp1k1_vuk3EG{JjC1Svvsi$uF^r5r< zr<|IbB{Y1%=A}^{+o+)>Qi`Ro?$kk$j-clz&mhNzW1w3s9r~^3TaK`CQsoHCd=eEt zi}6*fc~n|WL>reD;-Q6tST2PYDLkY4wN$HrrcDkrqHX9gsD~GhL$XX_k=iZQeh<>D zmPJQpO!~K=KEDLvGcR4$C>OTX7uB{j;Qo;5i81wlX`u?2Z58a2SiH=Jp;~(yTo%L| zI~5^a*KXF%Ewmw=t?*sO`N!7(myGtOX56av@~oFrQc^76Xd==sUc7kVmecJasx(QjqWfVq7t=0cnW51))rS>tQ|!W%yMZ6c<)Yp zo!)7Z{kge#0Y(O<(b$%Gd3oXLE&dS5@<{K5!K-Q~fBS7O))TptibeQazj8uOOXzBj zLm&{J(wUb8O2A*Xu1HRCmdV@H%hp^^`yp#jP--qQgk!oeic@w;^YaDPmhg^Ohulf~ zMH=#85Cl>Rc5%#Jn`;M1N#dnaoT%%FsFY{eOf$$oepKMXmZsxdOE#j0XiG=s0u4Fz^N;^xU&=4 ztALK3Tzxs6Ay?fSW!Avb)YMcHKO{X6L7amwEiK)B&^D~RLCHTOg7QFeQYn;ZT`tR) zI=v;9*;~IUCTJMpU=F4c@`kC{WWe{@%KzEqKbz6AqY0Oh=<>)Ow@{G$K$tnNOios# zjuol#dFQORx3^!GEc}MEfvZH5d&CLrjzVZf?%Q`O)}270&zQZTW&rHnS%$0x$H%lr zP+=qJ8gku%TWFxX431}}2Gh=qv>pF)9;OF|8HRmZxGVMQZp9$y3p&>ex?IjUQP3Qa z`?L|1|IPTB6NCBiwIY{@Z52qKjl#3MTz~JAeHyKGi?uQZnnfP=87)q9s=3U`@jj4(-Hxx?8;Nz+eL4 z=d7)y$xF8VF}PsB?_A|5NfwqgND}~V@-+OfQmf`2 zh1+WMABs4_;TYhbJN4=Pa?V=sIv@6a_TJB4zu#}K_3US_o#yO#T1-?y6aWA* zTZD}(54(OgVL@K+`stDo514W8o+z6O*Mg(MuAssqBLE<#@M(5;R*#DG$#JHPUaLk( zaY*!~--n2MIeT8+J)tXc6BymxIBMj0+3ty^lyP<;I%eZ&;ByXg-I<{f_xgSYS|zZ3 zyZCDmYS{{|p+z4>VLD*09`aT_Jq0x*^cm1^wAMWuRHDcT-Ks-+{>&$v=|0*8RQnmNeNd9J#-J^}BEsBbe)`jygYwwM{zx5vK~cjb;jC*~r^r_6~8 zjn?l5miRhoQ5IbOWwz-~Y$s88v5>LKnOnx7P5Y^l)y`TtM3pjKP~0{MKpYpuxd;CZ zG`4JXm%f`MCft0{m_A#k{nx;6rQab#kSgzW+GLL#iE*AV#wxX4gL!C4x0$6S1fshg z(Kgg9*%rT09z%e*nqva`qex@A%^_uqJ?x~&hF?Uf?K<^^fF0H)rX}sPncYm56iWRv zabP%qjTBXsUk!1BASf?VTDK_>pTBa5IhwE?b=+4%{KT4tp09twd2W0mp)_j2AIM(U z@hl?{o(&uuUZs2K`n)Z4up38XJu77Ys>hlsJ{mX{!ST{PI0TWZr6MtbxyzmLf}7-k z+V?nAlB|UYH~c*?*63w+N82}Hb475%g&UT2m#@|VgcwJjtmrVR+kJ_?*^!q2u)(oE z5otS)F9RE49I6;-wTr$#&&{HWb#<=bLp_S`6?=`bs!F{b{NI0L6NJ6;QJ64S4w~P& z#-oX^*q!|&uE1>1?sy(>7uncGm8wl(bmBW1n424pHf8*N-u%v$q}#5TupkcOYQ&!X z6f#X`2K&C2;GN@;clDtj2^ko%6m+h&<68XX)gukn)ZwQsnu9H@@J8m!C95`U6)V}H zmAfoI(|7hu1sOhzlf90DP@1c`T#DE7>Ybm3&0-FfS8<6OkJ<;fv)~s1-W(BIlwYIg zP|r1BqIrN3@kzJ*{jgEL~O!}AVA`jzd10r3PO#2)JNd)RIL3g)pkxF$oUWyhBIQV zf)JOvhs8^Id4(gmh&G8i;qQbl^NtSFbUoJ*Bq1>NBZC}rY<}sRkLqlK zh3M&B6<@aF70qiDKW{V0-gfch>WyN==JsZ+vo~A}hnjzE`6D!Yps<T!a}$qsE#np^IE+WGnOvgSgLAKQ3P>k*&2YUg zR@=waMaR3IOsP&YilgPYO1QNZ#`!U!PLB*<{yk7*Rnh#wKi|cAw=$k=>czL2wXF@| zRLntg>KJXo`&1E)NVt)iqUnb=aPf+T2?GZmtLF09lGwu;a4M+-Z294L_g%RxgaF90 z(f}YT{2eUaho~6Fl`KoGg`;6Hl}@uMb&e&W8ozFJ*sGOEv*|F58FnU4Uf|B055LBd zgi0f&BIp8wg2*Mn=v61xEBhzU(bzzPTv0ng-00kErJ{C^s>jX}$=y)UzKs3+w_bqtXduHF!pkw0H@wZ?G5g0O_bL*r+3K*SCUcbaeVN8+->wV@e;2R3 z&G6yBC)8;+fx5Bo80|r=zfOA|kG$T9ukr7n%l9uKkEbC0saXUo5PjD>??P=&O{;(2 z1yUwhT1c7k?9WlD>qlb89yf#%Y&WCVBVa$`OQV2#$*=27R=Z8rOA zH<=&cZDi`7IdRVZY&x9l_A(l}jm9XEIyzbzhJfmS4y1c}F75$zbk^1C>Qq0eJtwkZ zrpJ@FN=KZhDP05MoQ0`s7{~xnt#toS%MSU#7bwlskE}O+kVa%vhvifGgk6s2r)R25 z$|)*Z^F|*yky5`HEx(O@P&bgFA>!+*C*NX@4ZPL#HP4NqpiF#ltjHUTCj|bG51uy^ z5)2Lr&3Q9#pl^7H7gqgO*d&@leSLjU=<{>e^R2SV*Nb@O5F=vqkJ|bt-TfWsRUVvV z0nR1nL_89liM_9$iQ3DOM8w@OD)E3rlzpS_82Kf-9C;+z1+yhDL_E(`XG&&xi5v$g z+Q?IA?&xODxS4(NYk9BoeG3r zSg|6~YJ>HQB+{9U!Frvk^BgTP2kl>kpm5Hb3piV;;283qsUtU^eK5fCG9M~k!VA2>QgK*Z&EDV9G9Qb1+? zj~aVWTZl%Da%?$YwsMhw95&JCsBAnsJgoi7}Z#*$DGS7H$B4TDrN@}xPG1BP9QVGj`%4_GO zx`oWiQSl0(Ep{#g%G-pdcs=t!DA&aWcGf;6zI^4!Vbv~na+j{%;4Vl=M@nCfiIVJN zIWeC?sa>0cdY}C&{uqqZo1B8So5U{{vRj)eh0W-8eH{B9Ta8n)aC`Bz+Wh?7;^*m? zbu#In{kC8xs0EdX>e}Fh?F)t5lOu}CeYJiskkpP?(92xgiKfgoO8e$&S}=OK z6J*dTzZci5pS-%dy1qi|H-JK?pX~<~Kd7@;Ni#?!3MG{+7)Hw?;_kysR8B=E+3j~j zNcVaI#M5?~qCtyjoL1%;r?2|ag4xR2e`=-H0XAXPacU`b00IwolI~q7g8v+R4K)JB zXs@KUWi<(4}e)^2xuc|EcS&if4jwkI8JYTyBh{{_t< B>PY|q From 51ef838b0b0f0f2f664713c8c39241c4c49875d8 Mon Sep 17 00:00:00 2001 From: Incoming Date: Mon, 14 Dec 2015 02:55:31 -0500 Subject: [PATCH 13/57] Bugfix and a bit of flavor Moves the nuke team spawn area a bit away from the shuttle to solve #12766 Gives the nuke ops a nuclear fission explosive toy Creates a hidden nuke op memorial easter egg with the extra space created by the move --- _maps/map_files/generic/z2.dmm | 72 +++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/_maps/map_files/generic/z2.dmm b/_maps/map_files/generic/z2.dmm index b621acee5fa..d53eed0af51 100644 --- a/_maps/map_files/generic/z2.dmm +++ b/_maps/map_files/generic/z2.dmm @@ -372,6 +372,8 @@ "hh" = (/turf/simulated/floor/plasteel/yellowsiding{dir = 8},/area/centcom/evac) "hi" = (/turf/simulated/floor/plasteel/warning{dir = 4},/area/centcom/evac) "hj" = (/obj/structure/cult/talisman{desc = "A altar dedicated to the Wizard's Federation"},/obj/item/weapon/kitchen/knife/ritual,/obj/item/clothing/suit/wizrobe/santa,/obj/item/clothing/head/wizard/santa,/turf/simulated/floor/plasteel/cult,/area/wizard_station) +"hk" = (/obj/item/weapon/disk/data,/turf/simulated/floor/plating/snow,/area/syndicate_mothership) +"hl" = (/obj/item/toy/figure/syndie,/turf/simulated/floor/plating/snow,/area/syndicate_mothership) "hm" = (/turf/indestructible/riveted,/area/syndicate_mothership) "hn" = (/obj/structure/closet/wardrobe/cargotech,/turf/simulated/floor/plasteel/loadingarea,/area/centcom/supply) "ho" = (/obj/structure/closet,/turf/simulated/floor/plasteel/warning/corner{dir = 1},/area/centcom/supply) @@ -385,11 +387,15 @@ "hw" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin,/turf/simulated/floor/plasteel/red/side{dir = 2},/area/centcom/evac) "hx" = (/obj/structure/table/reinforced,/obj/item/toy/carpplushie,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plasteel/red/side{dir = 6},/area/centcom/evac) "hy" = (/obj/structure/table/reinforced,/obj/item/weapon/pen,/turf/simulated/floor/plasteel/red/side{dir = 2},/area/centcom/evac) +"hz" = (/turf/simulated/floor/plating/snow,/obj/structure/flora/bush,/turf/simulated/floor/plating/snow/gravsnow/corner,/area/syndicate_mothership) +"hA" = (/turf/simulated/floor/plating/snow,/obj/structure/flora/grass/brown,/turf/simulated/floor/plating/snow/gravsnow/corner,/area/syndicate_mothership) +"hB" = (/obj/structure/table/wood,/obj/item/toy/nuke,/turf/simulated/floor/wood,/area/syndicate_mothership) "hC" = (/turf/simulated/floor/plating/snow,/area/syndicate_mothership) "hD" = (/obj/structure/flora/grass/brown,/turf/simulated/floor/plating/snow,/area/syndicate_mothership) "hE" = (/obj/structure/flora/tree/pine,/turf/simulated/floor/plating/snow,/area/syndicate_mothership) "hF" = (/obj/structure/flora/grass/both,/turf/simulated/floor/plating/snow,/area/syndicate_mothership) "hG" = (/turf/indestructible/fakeglass{icon_state = "fakewindows2"; dir = 6},/area/centcom/supply) +"hH" = (/obj/structure/cult/tome{step_y = 1},/turf/simulated/floor/plasteel/cult,/area/wizard_station) "hI" = (/turf/simulated/floor/plasteel,/area/centcom/supply) "hJ" = (/turf/simulated/floor/plasteel/warning{dir = 8},/area/centcom/supply) "hK" = (/turf/simulated/floor/plasteel/green/corner{dir = 1},/area/centcom/control) @@ -399,12 +405,15 @@ "hO" = (/turf/simulated/floor/plasteel/yellowsiding{dir = 1},/area/centcom/evac) "hP" = (/turf/simulated/floor/plasteel/yellowsiding/corner{dir = 1},/area/centcom/evac) "hQ" = (/obj/machinery/door/airlock/external{name = "Supply Shuttle"; req_access_txt = "106"},/turf/simulated/floor/plasteel/delivery,/area/centcom/supply) +"hR" = (/obj/item/toy/figure/syndie,/turf/simulated/floor/plating/snow/gravsnow,/area/syndicate_mothership) "hS" = (/obj/machinery/door/airlock/centcom{name = "Centcom Supply"; req_access_txt = "106"},/turf/simulated/floor/plasteel/brown{dir = 4},/area/centcom/supply) "hT" = (/turf/simulated/floor/plasteel/brown{dir = 8},/area/centcom/control) "hU" = (/obj/machinery/door/airlock/centcom{name = "Centcom Docks"; opacity = 1; req_access_txt = "101"},/turf/simulated/floor/plasteel/black,/area/centcom/control) "hV" = (/obj/machinery/door/poddoor/preopen{id = "CentComPort"; name = "security door"},/turf/simulated/floor/plasteel/loadingarea{dir = 8},/area/centcom/control) "hW" = (/turf/simulated/floor/plasteel/warning{dir = 8},/area/centcom/evac) +"hX" = (/obj/structure/statue/uranium/nuke,/turf/simulated/floor/plating/snow/gravsnow,/area/syndicate_mothership) "hY" = (/obj/structure/flora/bush,/turf/simulated/floor/plating/snow,/area/syndicate_mothership) +"hZ" = (/turf/simulated/floor/plating/snow,/turf/simulated/floor/plating/snow/gravsnow/corner{tag = "icon-gravsnow_corner (NORTHWEST)"; icon_state = "gravsnow_corner"; dir = 9},/area/syndicate_mothership) "ia" = (/obj/machinery/computer/supplycomp,/turf/simulated/floor/plasteel/warning{dir = 8},/area/centcom/supply) "ib" = (/turf/simulated/floor/plasteel/green/corner{dir = 8},/area/centcom/control) "ic" = (/turf/simulated/floor/plasteel/warning/corner{dir = 4},/area/centcom/evac) @@ -614,7 +623,6 @@ "nw" = (/turf/simulated/floor/plasteel/green/side{dir = 4},/area/tdome/arena) "nx" = (/obj/effect/landmark{name = "tdome1"},/turf/simulated/floor/plasteel,/area/tdome/tdome1) "ny" = (/obj/structure/rack,/obj/item/clothing/under/color/green,/obj/item/clothing/shoes/sneakers/brown,/obj/item/clothing/suit/armor/tdome/green,/obj/item/clothing/head/helmet/thunderdome,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/melee/energy/sword/saber/green,/turf/simulated/floor/plasteel/black,/area/tdome/arena) -"nz" = (/obj/structure/cult/tome,/turf/simulated/floor/plasteel/cult,/area/wizard_station) "nA" = (/turf/indestructible/fakeglass{color = "#008000"; dir = 1; icon_state = "fakewindows"},/area/wizard_station) "nB" = (/obj/effect/decal/cleanable/blood/splatter,/turf/simulated/floor/plasteel/cult,/area/wizard_station) "nC" = (/obj/structure/closet/crate{icon_state = "crateopen"; opened = 1},/obj/item/clothing/suit/wizrobe/red,/obj/item/clothing/head/wizard/red,/obj/item/weapon/staff,/obj/item/clothing/shoes/sandal,/turf/simulated/floor/plasteel/cult,/area/wizard_station) @@ -953,37 +961,37 @@ acacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac acacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacfYgCfYgCfYgnfYgCfYgCfYfYfYfYflgEgDgDgDgDgDhghfhhgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac acacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacfYgQgbgRgngngngngngTgSgUgUgVflgEgDgDgDgDhwhyhxhhgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBgBgBgBgBgBgBgQhcgRgngngnhdfYgCfYfYgUheflgEgDgDgDgDhOhOhOhPgDgDhigygzacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBhohnhphnhqgBgQgmgRgngngnhrgCgQfYhthshuflhvgDgDgDgDgDgDgDgDgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChChChChDhChChChEhFhChChChEhChChChChChChEhChChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacachGhJhIhIhIhIgBgCfYhKgngngnhLfYgCfYgChMgCflhNgDgDgDgDgDgDgDgDgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChDhChChChChChChChChChChChEhChChChChChEhChChChChChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacachQhJhIhIhIhIhShTgngngngngngngngThUgUgUgUhVhWgDgDgDgDgDhbgDgDgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChChYhChChChChChDhChChFhEhChChEhChChEhFhChEhChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacachGiahIhIhIhIgBgCfYibgngngnhdfYgCfYfYfYfYflicgDgDgDgDgDgDgDgDgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChChChChChChChChChChChChChDhChChEhFhChChEhChFhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgAhQhJhIhIhIhIgBgQgbgRgngngniggbgQfYacacacflihgDgDgDgDgDgDgDgDgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChChChChChChChChChChDhChChChChChFhChEhFhChEhChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacilhJhIhIhIhIgBgQhcgRgngngnighcgQfYacacacflingDgDgDgDidididiegDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChCisisisisisisishChChChChChChChEhChChYhFhChChChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacithJhIhIhIhIgBgQgmiuibgnhdivgmgQfYacacacflingDgDgDgDiiikijhhgDgDhigFacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChCgGacacacacacacacgGhChChChChYhCishDishDhChEhChEhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciJhJhIhIhIhIgBiLiLiNiMiOiNiMiLiLiLacacacflingDgDgDgDgDipiohhgDgDhigHacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChCacacacacacacacacaciYhChCishmhmjaiZhmhmisjbjcishmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBjijhjjhIhIgBjljkjnjmjpjojrjqjsiLacacacfljujtjtjtjwjvjygshhgDgDhigIacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChCacacacacacacacacaciYhCjChmhmjDjEjEjDhmhmhmhmhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBgBgBgBjIgBgBjJjpjKjmjpjojKjpjLiLacacacflflflflflflflflgWgvgxixguflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajQjPjSjRaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChCacacacacacacacacaciYhYjChmjXjWjWjWjWjYkajZkckbkekdhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBkfkfkfgBkgjpjKjmjpjojKjpkhiLacacacacacacacacacacacflgDgDgDgDflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaknaakpkokqjRjRaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChCgGacacacacacacacgGhChCkuhmkvjWkwkwkxjWjWjWkzkykykyhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBkfkfkfgBkAjpjKjmjpjojKjpkBiLacacacacacacacacacacacflgDjMikiiflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaknkEkGkFkqkHjRaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChCacacacacackKisisiskLhmjWkwkNkMkwjWkPkOkckQkRhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBkfkfkfgBkTkSkSkUjpkVkWkWkXiLacacacacacacacacacacacflgDkiipkjflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaajRlalbkHldlcjRaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChCacacacacaclhlglglgiZhmjWkwljlikwjWkPlkhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBgBgBgBgBiNlliMiLjpiLiNlliMiLacacacacacacacacacacackCgDgDgDgDflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaajRjRlnlmlnjRjRaaaaaaaaaaaaaaaaaaaaacacacacacachmhChCgGacacacacacacacacaclrlqlqlqlqlsjWjWjWjWjWjWkPlkhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciLltltltlujplultltltiLacacacacacacacacacacacflkYjwjwkZflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaknknjRlwlvlxjRaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChCacacacacacacacacacaclBlAjalgiZhmlCkwkwkwjWjWkPlDhmlElFhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciLiLiLiLiLiLiLiLiOiLiLiLiLiLiLiLiLacacacacacacacacflflflflflflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaalHlGlJlIlLlKlxlMknaaaaaaaaaaaaaaaaaaaaacacacacacachmhChCacacacacacacacacacacacgJacgGlShmlUlTlVlTlTjWjWjWlXlWlWlYhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciLlZmamamamamalZlZlZmamamamamalZiLacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaaaambmdmcmfmelLlxmhmgmiknknaaaaaaaaaaaaaaaaacacacacacachmmjhCacacacacacacacacacacacacacackuhmmmmlmmmmmnjWjWjWhmmomplYhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmqlZlZlZmrlZlZlZlZlZlZlZmrlZlZlZmqacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaaknaalJmsmsmtlLlxmumhmiaamwmvaaaaaaaaaaaaaaacacacacacachmhChCacacacacacacacacacacacacacacjChmhmkOmAmzmBhmmChmhmhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciLlZmamamamamalZlZlZmamamamamalZiLacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaalMknaaaaknmDmFmEmGmElMknknaaaaaaaaaaaaaaaaacacacacacachmhChCacacacacacacacacacacacacacacmKlShmhmhmhmhmhmmLmLmNmMmPmOhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciLiNlllllllllllllllllllllllllliMiLacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaajRjRmQjRjRjRjRjRjRmRjRjRjRjRjRjRaaknaaaaaaaaaaacacacacacachmhCgGacacacacacacacacacacacacacacacgGmTmTmTmUlShmmLmLmLmLmLmLhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVmVmVmVmVmVmVmVmVmWmXmXmXmXmXmXmXmXmXmXmXmXmXmWmVmVmVmVmVmVmVmVmVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaajRmYlxlxmYjRnamZlxlxlxnbncjRnendngnfknknaaaaaaacacacacacachmhCacacacacacacacacacacacacacacacacachChDhChChFkcmLmLmLmLmLnqhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnsnsnsnsnvnumXmXmXmXmXmXmXmXmXmXmXmXmXnwnvnxnxnxnxnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaanAnzlxlxnznAnBnBlxlxlxlxnCnAnEnDmsmsnFaaaaaaaaacacacacacachmhCacacacacacacacacacacacacacacacacachChYhEhDhYhmnJnJnJnJnJnKhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnLnsnLnsnvnumXmXmXmXmXmXmXmXmXmXmXmXmXnwnvnxnMnxnMnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaanOnNlxmhlxnPmumhlxhjlxlxnRnOnTnSnVnUnXnWaaaaaaacacacacacachmhCacacacacacacacacacacacacacacacacachChChChEjChmhmhmhmhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnsobnsnsnvnumXmXmXmXmXocodocmXmXmXmXmXnwnvnxnxoenxnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaofnzlxmEmuogmElxlxohlxlxlxofojoinFoklHaaaaaaaaacacacacacachmhCacacacacacacacacacacacacacacacacachChEhChYjChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnsnsnsnsnvnumXmXmXmXmXocorocmXmXmXmXmXnwnvnxnxnxnxnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaajRoslxlxosjRotlxmhmElxlxotjRovouoxowaaaaaaaaaaacacacacacachmhCacacacacacacacacacacacacacacacacachChChDhCjChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnLnsnLnsnvnumXmXmXmXmXmXmXmXmXmXmXmXmXnwnvnxnMnxnMnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaajRjRoBjRjRjRjRjRlnoClnjRjRjRjRjRknknknaaaaaaaaacacacacacachmhCacacacacachCacacacacachCacacacacachChChChCjChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnsnsnsnsnvnumXmXmXmXmXmXmXmXmXmXmXmXmXnwnvnxnxnxnxnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaamDlbaaknaaknoKlKmDaaaaknaaaaaaaaknaaaaaaaaacacacacacachmhCacacacacachCgGacacacgGhCacacacacachChChChCjChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVmVmVoOoOoOoOoOmVmWmXmXmXmXmXmXmXmXmXmXmXmXmXmWmVoOoOoOoOoOmVmVmVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaaknknaaoPlbaaoRoQmDknaaoSaaaaaaaaaaaaaaaaaaacacacacacachmhCgGacacacgGhChChChChChChCgGacacacgGhChChChCjChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVoToToToToTmVoUoVoVoVoVoVoVoVoVoVoVoVoVoVoWmVoXoXoXoXoXmVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaknknaaoYmhoZaaaaaaknaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChChChChChChChChChChChChChChChChCjChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVmVmVmVmVmVmVpapbpbpbpbpbpcpepdpbpbpbpbpbpamVmVmVmVmVmVmVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac -acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaknjRjRpfjRjRknaaknknaaaaaaaaaaaaaaacacacacacachmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacpgpapapaphpapipipipipipaphpapapapgacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBhohnhphnhqgBgQgmgRgngngnhrgCgQfYhthshuflhvgDgDgDgDgDgDgDgDgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChChChChDhChChChEhFhChChChChChEhChChChChChkhEhChChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacachGhJhIhIhIhIgBgCfYhKgngngnhLfYgCfYgChMgCflhNgDgDgDgDgDgDgDgDgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChDhChChChChChChChChChChChEhChChChChChChChEhChlhChChChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacachQhJhIhIhIhIhShTgngngngngngngngThUgUgUgUhVhWgDgDgDgDgDhbgDgDgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChChYhChChChChChDhChChFhChChEhChChEhChChEhFhChEhChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacachGiahIhIhIhIgBgCfYibgngngnhdfYgCfYfYfYfYflicgDgDgDgDgDgDgDgDgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChChChChChChChChChChChChEhChChDhChChEhFhChChEhChFhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgAhQhJhIhIhIhIgBgQgbgRgngngniggbgQfYacacacflihgDgDgDgDgDgDgDgDgDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChChChChChChChChChChDhChChChChChChChFhChEhFhChEhChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacilhJhIhIhIhIgBgQhcgRgngngnighcgQfYacacacflingDgDgDgDidididiegDgDhigyacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChCisisisisisisishChChChChChFhChChChEhChChYhFhChChChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacithJhIhIhIhIgBgQgmiuibgnhdivgmgQfYacacacflingDgDgDgDiiikijhhgDgDhigFacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChCgGacacacacacacacgGhChChChChChChzisishAishAhChEhChEhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciJhJhIhIhIhIgBiLiLiNiMiOiNiMiLiLiLacacacflingDgDgDgDgDipiohhgDgDhigHacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChCacacacacacacacacaciYhChChChCishmhmjaiZhmhmisjbjcishmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBjijhjjhIhIgBjljkjnjmjpjojrjqjsiLacacacfljujtjtjtjwjvjygshhgDgDhigIacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChCacacacacacacacacaciYhChChCjChmhmjDjEjEjDhmhmhmhmhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBgBgBgBjIgBgBjJjpjKjmjpjojKjpjLiLacacacflflflflflflflflgWgvgxixguflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajQjPjSjRaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChCacacacacacacacacaciYhYhChCjChmjXjWjWjWjWjYkajZkckbkekdhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBkfkfkfgBkgjpjKjmjpjojKjpkhiLacacacacacacacacacacacflgDgDgDgDflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaknaakpkokqjRjRaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChCgGacacacacacacacgGhChChChCkuhmkvjWkwkwkxjWjWjWkzkykykyhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBkfkfkfgBkAjpjKjmjpjojKjpkBiLacacacacacacacacacacacflgDjMikiiflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaknkEkGkFkqkHjRaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChCacacacacackKisisisisiskLhmjWkwkNkMkwjWkPkOkckQkRhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBkfkfkfgBkTkSkSkUjpkVkWkWkXiLacacacacacacacacacacacflgDkiipkjflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaajRlalbkHldlcjRaaaaaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChCacacacacaclhlglglglglgiZhmjWkwljlikwjWkPlkhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacgBgBgBgBgBiNlliMiLjpiLiNlliMiLacacacacacacacacacacackCgDgDgDgDflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaajRjRlnlmlnjRjRaaaaaaaaaaaaaaaaaaaaacacacacacachmhChCgGacacacacacacacacaclrlqlqlqlqlqlqlsjWjWjWjWjWjWkPlkhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciLltltltlujplultltltiLacacacacacacacacacacacflkYjwjwkZflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaknknjRlwlvlxjRaaaaaaaaaaaaaaaaaaaaaaacacacacacachmhChCacacacacacacacacacaclBlAjalglglgiZhmlCkwkwkwjWjWkPlDhmlElFhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciLiLiLiLiLiLiLiLiOiLiLiLiLiLiLiLiLacacacacacacacacflflflflflflacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaalHlGlJlIlLlKlxlMknaaaaaaaaaaaaaaaaaaaaacacacacacachmhChCacacacacacacacacacacacgJacgGmTmTlShmlUlTlVlThBjWjWjWlXlWlWlYhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciLlZmamamamamalZlZlZmamamamamalZiLacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaaaambmdmcmfmelLlxmhmgmiknknaaaaaaaaaaaaaaaaacacacacacachmmjhCacacacacacacacacacacacacacachChCkuhmmmmlmmmmmnjWjWjWhmmomplYhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmqlZlZlZmrlZlZlZlZlZlZlZmrlZlZlZmqacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaaknaalJmsmsmtlLlxmumhmiaamwmvaaaaaaaaaaaaaaacacacacacachmhChCacacacacacacacacacacacacacachChYjChmhmkOmAmzmBhmmChmhmhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciLlZmamamamamalZlZlZmamamamamalZiLacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaalMknaaaaknmDmFmEmGmElMknknaaaaaaaaaaaaaaaaacacacacacachmhChCacacacacacacacacacacacacacacmKhChClShmhmhmhmhmhmmLmLmNmMmPmOhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaciLiNlllllllllllllllllllllllllliMiLacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaajRjRmQjRjRjRjRjRjRmRjRjRjRjRjRjRaaknaaaaaaaaaaacacacacacachmhCgGacacacacacacacacacacacacacacacgGhChCmTmTmTmUlShmmLmLmLmLmLmLhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVmVmVmVmVmVmVmVmVmWmXmXmXmXmXmXmXmXmXmXmXmXmXmWmVmVmVmVmVmVmVmVmVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaajRmYlxlxmYjRnamZlxlxlxnbncjRnendngnfknknaaaaaaacacacacacachmhCacacacacacacacacacacacacacacacacachChChChDhChChFkcmLmLmLmLmLnqhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnsnsnsnsnvnumXmXmXmXmXmXmXmXmXmXmXmXmXnwnvnxnxnxnxnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaanAhHlxlxhHnAnBnBlxlxlxlxnCnAnEnDmsmsnFaaaaaaaaacacacacacachmhCacacacacacacacacacacacacacacacacachChChChYhEhDhYhmnJnJnJnJnJnKhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnLnsnLnsnvnumXmXmXmXmXmXmXmXmXmXmXmXmXnwnvnxnMnxnMnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaanOnNlxmhlxnPmumhlxhjlxlxnRnOnTnSnVnUnXnWaaaaaaacacacacacachmhCacacacacacacacacacacacacacacacacachChChChChChEjChmhmhmhmhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnsobnsnsnvnumXmXmXmXmXocodocmXmXmXmXmXnwnvnxnxoenxnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaofhHlxmEmuogmElxlxohlxlxlxofojoinFoklHaaaaaaaaacacacacacachmhCacacacacacacacacacacacacacacacacachChChChEhChYhChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnsnsnsnsnvnumXmXmXmXmXocorocmXmXmXmXmXnwnvnxnxnxnxnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaajRoslxlxosjRotlxmhmElxlxotjRovouoxowaaaaaaaaaaacacacacacachmhCacacacacacacacacacacacacacacacacachChChChCishChChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnLnsnLnsnvnumXmXmXmXmXmXmXmXmXmXmXmXmXnwnvnxnMnxnMnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaajRjRoBjRjRjRjRjRlnoClnjRjRjRjRjRknknknaaaaaaaaacacacacacachmhCacacacacachCacacacacachCacacacacachChChCkLhRmKhChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVnrntnsnsnsnsnsnvnumXmXmXmXmXmXmXmXmXmXmXmXmXnwnvnxnxnxnxnxntnymVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaamDlbaaknaaknoKlKmDaaaaknaaaaaaaaknaaaaaaaaacacacacacachmhCacacacacachCgGacacacgGhCacacacacachChCjChRhXhRiYhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVmVmVoOoOoOoOoOmVmWmXmXmXmXmXmXmXmXmXmXmXmXmXmWmVoOoOoOoOoOmVmVmVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaaknknaaoPlbaaoRoQmDknaaoSaaaaaaaaaaaaaaaaaaacacacacacachmhCgGacacacgGhChChChChChChCgGacacacgGhChChClShRhZhChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVoToToToToTmVoUoVoVoVoVoVoVoVoVoVoVoVoVoVoWmVoXoXoXoXoXmVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaknknaaoYmhoZaaaaaaknaaaaaaaaaaaaaaaaacacacacacachmhChChChChChChChChChChChChChChChChChChChChChCmThChChmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacmVmVmVmVmVmVmVpapbpbpbpbpbpcpepdpbpbpbpbpbpamVmVmVmVmVmVmVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac +acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaknjRjRpfjRjRknaaknknaaaaaaaaaaaaaaacacacacacachmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmhmacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacpgpapapaphpapipipipipipaphpapapapgacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaajRpkpjpjjRoPnDmeplpmknaaaaaaaaaaacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacpgpgpnpgpgpgpgpopqpppgpgpgpgpnpgpgacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaalnpjprpjlnptpsmfpukqjRaaaaaaaaaaacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacpgpgpgpgpgacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac acacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaapvknjRpwpjpxjRkFpymfpuaaknaaaaaaaaaaacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac From 82aad54c80a4716f6b9e6474b00c3572fd1e80ac Mon Sep 17 00:00:00 2001 From: Incoming5643 Date: Mon, 14 Dec 2015 03:02:49 -0500 Subject: [PATCH 14/57] step what are you doing there I didn't even touch you --- _maps/map_files/generic/z2.dmm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_maps/map_files/generic/z2.dmm b/_maps/map_files/generic/z2.dmm index d53eed0af51..0d8cbeae00e 100644 --- a/_maps/map_files/generic/z2.dmm +++ b/_maps/map_files/generic/z2.dmm @@ -395,7 +395,7 @@ "hE" = (/obj/structure/flora/tree/pine,/turf/simulated/floor/plating/snow,/area/syndicate_mothership) "hF" = (/obj/structure/flora/grass/both,/turf/simulated/floor/plating/snow,/area/syndicate_mothership) "hG" = (/turf/indestructible/fakeglass{icon_state = "fakewindows2"; dir = 6},/area/centcom/supply) -"hH" = (/obj/structure/cult/tome{step_y = 1},/turf/simulated/floor/plasteel/cult,/area/wizard_station) +"hH" = (/obj/structure/cult/tome,/turf/simulated/floor/plasteel/cult,/area/wizard_station) "hI" = (/turf/simulated/floor/plasteel,/area/centcom/supply) "hJ" = (/turf/simulated/floor/plasteel/warning{dir = 8},/area/centcom/supply) "hK" = (/turf/simulated/floor/plasteel/green/corner{dir = 1},/area/centcom/control) @@ -804,7 +804,7 @@ "rw" = (/obj/effect/landmark/abductor/agent{team = 2},/turf/simulated/floor/plating/abductor,/area/abductor_ship) "rx" = (/obj/effect/landmark/abductor/scientist{team = 3},/turf/simulated/floor/plating/abductor,/area/abductor_ship) "ry" = (/obj/effect/landmark/abductor/agent{team = 3},/turf/simulated/floor/plating/abductor,/area/abductor_ship) - + (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacadaeaeaeaeaeadaeaeaeaeaeadaeaeaeaeaeadaeaeaeaeaeadaeaeaeaeaeadaeaeaeaeaead aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacafaiagajajakahanalapaoaqaharararararahasasasasasahatatatatatahaxauauauayam From a6194f472571486b984b9ec607dc37f660789363 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Mon, 14 Dec 2015 05:40:19 -0600 Subject: [PATCH 15/57] Adds an optional challenge mode to nuclear operatives --- code/game/gamemodes/nuclear/nuclear.dm | 5 ++ .../gamemodes/nuclear/nuclear_challenge.dm | 46 +++++++++++++++++++ .../machinery/computer/syndicate_shuttle.dm | 13 ++++++ tgstation.dme | 1 + 4 files changed, 65 insertions(+) create mode 100644 code/game/gamemodes/nuclear/nuclear_challenge.dm diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index 378a8c7cd65..f696f271a83 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -113,6 +113,10 @@ synd_mind.current.real_name = "[syndicate_name()] [leader_title]" synd_mind.current << "You are the Syndicate [leader_title] for this mission. You are responsible for the distribution of telecrystals and your ID is the only one who can open the launch bay doors." synd_mind.current << "If you feel you are not up to this task, give your ID to another operative." + synd_mind.current << "In your hand you will find a special item capable of triggering a greater challenge for your team. Examine it carefully and consult with your fellow operatives before activating it." + + var/obj/item/device/nuclear_challenge/challenge = new /obj/item/device/nuclear_challenge + synd_mind.current.equip_to_slot_or_del(challenge, slot_r_hand) var/list/foundIDs = synd_mind.current.search_contents_for(/obj/item/weapon/card/id) if(foundIDs.len) @@ -135,6 +139,7 @@ return + /datum/game_mode/proc/forge_syndicate_objectives(datum/mind/syndicate) var/datum/objective/nuclear/syndobj = new syndobj.owner = syndicate diff --git a/code/game/gamemodes/nuclear/nuclear_challenge.dm b/code/game/gamemodes/nuclear/nuclear_challenge.dm new file mode 100644 index 00000000000..dbbf58be170 --- /dev/null +++ b/code/game/gamemodes/nuclear/nuclear_challenge.dm @@ -0,0 +1,46 @@ +#define CHALLENGE_TIME_LIMIT 3000 +#define MIN_CHALLENGE_PLAYERS 50 + +/obj/item/device/nuclear_challenge + name = "Declaration of War (Challenge Mode)" + icon_state = "gangtool-red" + item_state = "walkietalkie" + desc = "Use to send a declaration of hostilities to the target, delaying your shuttle departure for 20 minutes while they prepare for your assault. \ + Such a brazen move will attract the attention of powerful benefactors within the Syndicate, who will supply your team with a massive amount of bonus telecrystals. \ + Must be used within five minutes, or your benefactors will lose interest." + + + +/obj/item/device/nuclear_challenge/attack_self(mob/living/user) + if(player_list.len < MIN_CHALLENGE_PLAYERS) + user << "The enemy crew is too small to be worth declaring war on." + return + if(user.z != ZLEVEL_CENTCOM) + user << "You have to be at your base to use this." + return + + if(world.time > CHALLENGE_TIME_LIMIT) + user << "It's too late to declare hostilities. Your benefactors are already busy with other schemes. You'll have to make do with what you have on hand." + return + + var/are_you_sure = alert(user, "Consult your team carefully before you declare war on [station_name()]]. Are you sure you want to alert the enemy crew?", "Declare war?", "Yes", "No") + if(are_you_sure == "No") + user << "On second thought, the element of surprise isn't so bad after all." + return + + var/war_declaration = "[user.real_name] has declared his intent to utterly destroy [station_name()] with a nuclear device, and dares the crew to try and stop them." + priority_announce(war_declaration, title = "Declaration of War", sound = 'sound/machines/Alarm.ogg') + user << "You've attracted the attention of powerful forces within the syndicate. A bonus bundle of telecrystals has been granted to your team. Great things await you if you complete the mission." + + for(var/obj/machinery/computer/shuttle/syndicate/S in machines) + S.challenge = TRUE + + var/obj/item/device/radio/uplink/U = new /obj/item/device/radio/uplink(get_turf(user)) + U.hidden_uplink.uplink_owner= "[user.key]" + U.hidden_uplink.uses = 200 + U.hidden_uplink.mode_override = /datum/game_mode/nuclear //Maybe we can have a special set of items for the challenge uplink eventually + qdel(src) + + +#undef CHALLENGE_TIME_LIMIT +#undef MIN_CHALLENGE_PLAYERS \ No newline at end of file diff --git a/code/game/machinery/computer/syndicate_shuttle.dm b/code/game/machinery/computer/syndicate_shuttle.dm index 5b9eb5d0de3..ff7669a4b47 100644 --- a/code/game/machinery/computer/syndicate_shuttle.dm +++ b/code/game/machinery/computer/syndicate_shuttle.dm @@ -1,3 +1,5 @@ +#define SYNDICATE_CHALLENGE_TIMER 12000 //20 minutes + /obj/machinery/computer/shuttle/syndicate name = "syndicate shuttle terminal" icon_screen = "syndishuttle" @@ -5,7 +7,18 @@ req_access = list(access_syndicate) shuttleId = "syndicate" possible_destinations = "syndicate_away;syndicate_z5;syndicate_z3;syndicate_z4;syndicate_ne;syndicate_nw;syndicate_n;syndicate_se;syndicate_sw;syndicate_s" + var/challenge = FALSE /obj/machinery/computer/shuttle/syndicate/recall name = "syndicate shuttle recall terminal" possible_destinations = "syndicate_away" + + +/obj/machinery/computer/shuttle/syndicate/Topic(href, href_list) + if(href_list["move"]) + if(challenge && world.time < SYNDICATE_CHALLENGE_TIMER) + usr << "You've issued a combat challenge to the station! You've got to give them at least [round(((SYNDICATE_CHALLENGE_TIMER - world.time) / 10) / 60)] more minutes to allow them to prepare." + return 0 + ..() + +#undef SYNDICATE_CHALLENGE_TIMER \ No newline at end of file diff --git a/tgstation.dme b/tgstation.dme index 8c72aa916b8..aec6717270b 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -377,6 +377,7 @@ #include "code\game\gamemodes\meteor\meteors.dm" #include "code\game\gamemodes\monkey\monkey.dm" #include "code\game\gamemodes\nuclear\nuclear.dm" +#include "code\game\gamemodes\nuclear\nuclear_challenge.dm" #include "code\game\gamemodes\nuclear\nuclearbomb.dm" #include "code\game\gamemodes\nuclear\pinpointer.dm" #include "code\game\gamemodes\revolution\revolution.dm" From a1634f2b51b57a4923bf23226d01ae8c6216c3bd Mon Sep 17 00:00:00 2001 From: bgobandit Date: Mon, 14 Dec 2015 14:32:27 -0500 Subject: [PATCH 16/57] Santa will no longer deliver the parent types of action figures. Certain action figures will now play appropriate sounds. --- code/game/objects/items/toys.dm | 10 +++++++++- code/game/objects/items/weapons/gift_wrappaper.dm | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index fcd96f4fbf7..d0ce999bfad 100755 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -1234,6 +1234,7 @@ icon_state = "nuketoy" var/cooldown = 0 var/toysay = "What the fuck did you do?" + var/toysound = 'sound/machines/click.ogg' /obj/item/toy/figure/New() desc = "A \"Space Life\" brand [src]." @@ -1242,7 +1243,7 @@ if(cooldown <= world.time) cooldown = world.time + 50 user << "The [src] says \"[toysay]\"" - playsound(user, 'sound/machines/click.ogg', 20, 1) + playsound(user, toysound, 20, 1) /obj/item/toy/figure/cmo name = "Chief Medical Officer action figure" @@ -1268,6 +1269,7 @@ name = "Cyborg action figure" icon_state = "borg" toysay = "I. LIVE. AGAIN." + toysound = 'sound/voice/liveagain.ogg' /obj/item/toy/figure/botanist name = "Botanist action figure" @@ -1308,6 +1310,7 @@ name = "Clown action figure" icon_state = "clown" toysay = "Honk!" + toysound = 'sound/items/bikehorn.ogg' /obj/item/toy/figure/ian name = "Ian action figure" @@ -1373,6 +1376,7 @@ name = "Mime action figure" icon_state = "mime" toysay = "..." + toysound = null /obj/item/toy/figure/miner name = "Shaft Miner action figure" @@ -1388,6 +1392,7 @@ name = "Wizard action figure" icon_state = "wizard" toysay = "Ei Nath!" + toysound = 'sound/magic/Disintegrate.ogg' /obj/item/toy/figure/rd name = "Research Director action figure" @@ -1398,11 +1403,13 @@ name = "Roboticist action figure" icon_state = "roboticist" toysay = "Big stompy mechs!" + toysound = 'sound/mecha/mechstep.ogg' /obj/item/toy/figure/scientist name = "Scientist action figure" icon_state = "scientist" toysay = "For science!" + toysound = 'sound/effects/explosionfar.ogg' /obj/item/toy/figure/syndie name = "Nuclear Operative action figure" @@ -1413,6 +1420,7 @@ name = "Security Officer action figure" icon_state = "secofficer" toysay = "I am the law!" + toysound = 'sound/voice/complionator/dredd.ogg' /obj/item/toy/figure/virologist name = "Virologist action figure" diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm index 793948a60ff..bde9fa7fa01 100644 --- a/code/game/objects/items/weapons/gift_wrappaper.dm +++ b/code/game/objects/items/weapons/gift_wrappaper.dm @@ -63,7 +63,7 @@ /obj/item/clothing/head/snowman) gift_type_list += subtypesof(/obj/item/clothing/head/collectable) - gift_type_list += subtypesof(/obj/item/toy) - (((typesof(/obj/item/toy/cards) - /obj/item/toy/cards/deck) + /obj/item/toy/ammo)) //All toys, except for abstract types and syndicate cards. + gift_type_list += subtypesof(/obj/item/toy) - (((typesof(/obj/item/toy/cards) - /obj/item/toy/cards/deck) + /obj/item/toy/figure + /obj/item/toy/ammo)) //All toys, except for abstract types and syndicate cards. var/gift_type = pick(gift_type_list) From 112cf3c96c1d6e699b3dc4109a7a4d205aa3e3ad Mon Sep 17 00:00:00 2001 From: bgobandit Date: Mon, 14 Dec 2015 14:47:32 -0500 Subject: [PATCH 17/57] AIs with wireless disabled can no longer interact with papers held up to cameras. --- code/game/machinery/camera/camera.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 9257aad65c2..643a588c8c1 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -203,6 +203,8 @@ for(var/mob/O in player_list) if(istype(O, /mob/living/silicon/ai)) var/mob/living/silicon/ai/AI = O + if(AI.control_disabled) + return if(U.name == "Unknown") AI << "[U] holds \a [itemname] up to one of your cameras ..." else From e79301c304b8f50df0dd9ea49fbf5139193641c0 Mon Sep 17 00:00:00 2001 From: bgobandit Date: Mon, 14 Dec 2015 14:50:35 -0500 Subject: [PATCH 18/57] dead AIs too --- code/game/machinery/camera/camera.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 643a588c8c1..9528ce6311b 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -203,7 +203,7 @@ for(var/mob/O in player_list) if(istype(O, /mob/living/silicon/ai)) var/mob/living/silicon/ai/AI = O - if(AI.control_disabled) + if(AI.control_disabled || (AI.stat == DEAD)) return if(U.name == "Unknown") AI << "[U] holds \a [itemname] up to one of your cameras ..." From d20fe3478290b17913530c7945c95b8ca798741d Mon Sep 17 00:00:00 2001 From: bgobandit Date: Mon, 14 Dec 2015 17:55:20 -0500 Subject: [PATCH 19/57] king and 6 of diamonds in syndi deck are properly named --- icons/obj/toy.dmi | Bin 32798 -> 32796 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/obj/toy.dmi b/icons/obj/toy.dmi index 01c99551ed6ca893b16ea9bb194e13c658afc945..91e2b25eb2ee840f22b6938d58f5cc45c2ddb72e 100644 GIT binary patch delta 1050 zcmV+#1m*jlfC8L=0+1vDDv>2Ke@Ehx#9AU%l8WOz{VaTy8-vtuWEJ55L{T~?@v-z# z{PE?l=WpWa>+|@9ty4yel}LX7G#+i0^p#kN$LV-fu_`OS|HXOoELP$}VW^R0{fF^L zD(l2bB;!$GsbMEpVsZ}V)Rvt-$0qN`3PVk9jdPjVMuoGQBnOjDQ`?$0f1GPG^BPQT z$+OL~W3Ue>umUi%Yi^y%`;swd_^SI_J3f=jVv~n{U>dwDFc4>vhr9 z^g-i2quW47CL$6IiCOoWXJq%LOc# zu-rESM2~F%;ZqYp`q%;xJ~RMir@|EC&$`Q?>PKLL!W4xw6wXn&K;aUF`?5#mvFZ_f zDtZJTYaX$Ok{?X3e};~9D3}ffk3&HcH*UF|mMSOD17^Xqi5~^eCVCP)lej_f^0bgS z@Z^V%frH>93KJBjD4d~ij=}{BmniIwe}m-J^f$;}4}XL3)$BLO_D8?r6@U70JiO*H zn&33W=?tfHoGx&>#Oc+<2lW7^f1UTBKEU+#v^TsL4xf{Ue|G``6BMQ>oS|@z!UYPK zDC`Y+P~{``dc=dO9PvNt}22ef`ZJfHRR;qk1WkC-sK4c~kgI~`v>?*0WSS%)vsA)6a>V@|wSBz;KF zuu)ny?Ah4he;PU2wyir?sfY)!+dA&SXlYeZsK|$|u2SK56};K4Us;>z;JR}xqtcD( zT=*>WCcHK|r<^B!;|++*q;HH1rZTdgwdC+!%#01c!;l$ITHSg-qgNBHCl&rqCMR1O z&v_M2MqJ>E+B$00io;)lZKIlqS5lOYI4`aA4+^HX z>Wyspyka6IGm$sj<%+eBN^)+BLgf+rbvrF1{#CpvYid)*EWRZxZ+`*&QGEIKB%Z!L UkN*ef2hS%toU*u$vsnbid!?KWz5oCK delta 1052 zcmV+%1mpXhfC8R?0+1vDERiKMf5+mH#6}`jl8WOz{Vd{}+!!Q(qpJY_CyLTJu8*aU z;*T$XJ$@4pUmwTMY@IS%tVH(vr}1d3q_4$F+)u}&npIW%w?CXG&tfG$l!jVK)_)j} zq_R$|L^d9kmRfdVB_^j}L0#4BQ*82ntTfaX);PB@+o~3*)b^uFNaAQ_=4ez|!h3}KH9G{j3l4HFt z`=&`oH8o{2Y9c;UE)BPx57*Y<%(R?@3qk3s;exDOOS9EyD~4&Yo(fZnznQFeiSizn z87y;H&R{u*KAyTRr+ z*x3zseuG`yV3#-8w{`&Wp&>wiYzfdGngZnewgB~1m{R=Lkz}YXAeq53hvf{Gb6755 zxrF6gBS7@f1`s|r0i+Kt0O5TDKz1rjDgJEw4OIOI%utx4aE8J;3Ku9`qVTQk5qYS3 z#2$+t!H1eh?7rlaf9b{0k*9)bD!5MtS=_kgc3P@}JSWV8Clfyko=o&4cp`Cw;Q47G zbKudZj)6(=9)%eSa}>@{I7i_Eg-a9;#=j(aG5sak%i%8xU(9|T zG{b3*Q!&Hs9H$GME^&G>@0bxF)JBlFz8v?`n_>S&e>uGs5SXDbN8t>Ga}+L6 zxJ2P#%7ZE&v6nL*^zo0_;e?l7@o(Rg(+eJO8R&A*%|JH?-2!w=(47xS*ALAL9f-qkAN$?LX>doo&CRhBC9sjI71_+_%3dY4Zp;&F`l%#_JYQsCOS_l{G&`k zwlbcJI-HESz%_ME)T%Xye*-CMZlku^m~D7TMd6HOf6s+i&*7a)_p_&PZL+SE=7^hL zv1YG|nC;dP?*-KnmHD#`Mt+c1KH>wYq3teWla1O~vN1QJ4PV+;wGr>6C>?QLTInAY zOl{RG+3 Date: Mon, 14 Dec 2015 20:23:10 -0500 Subject: [PATCH 20/57] Update mixer.dm --- code/ATMOSPHERICS/components/trinary_devices/mixer.dm | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm index 9e39a0b40f3..6ac8ab95b1c 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm @@ -3,9 +3,6 @@ density = 0 name = "gas mixer" - - req_access = list(access_atmospherics) - can_unwrench = 1 var/on = 0 From a5df034693a186ac12bb96f3642f73be6f8d1a7c Mon Sep 17 00:00:00 2001 From: Supermichael777 Date: Mon, 14 Dec 2015 20:25:32 -0500 Subject: [PATCH 21/57] noaccsesrequirements on mixers --- code/ATMOSPHERICS/components/trinary_devices/filter.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm index 11b47197251..b37e8b08a86 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm @@ -11,8 +11,6 @@ name = "gas filter" - req_access = list(access_atmospherics) - can_unwrench = 1 var/on = 0 From 249c8a8789e675af7c26068f8d493210c65b4dc4 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Mon, 14 Dec 2015 19:38:21 -0600 Subject: [PATCH 22/57] No teleporter nonsense --- code/game/machinery/teleporter.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index b88cc1e0923..ecaecfae372 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -287,6 +287,8 @@ return power_station /obj/machinery/teleport/hub/Bumped(M as mob|obj) + if(z == ZLEVEL_CENTCOM) + M << "You can't use this here." if(power_station && power_station.engaged && !panel_open) teleport(M) use_power(5000) From 2e71b5e1227978a832721e88402f06938ce81510 Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Mon, 14 Dec 2015 21:05:03 -0500 Subject: [PATCH 23/57] Changes blob pulsing to use ultra_range and orange. Blobs now properly remember their overmind and get color from it predictably. Oh god, I hope I did this right. --- code/game/gamemodes/blob/blobs/blob_mobs.dm | 18 +-- code/game/gamemodes/blob/blobs/core.dm | 18 ++- code/game/gamemodes/blob/blobs/factory.dm | 3 +- code/game/gamemodes/blob/blobs/node.dm | 13 +- code/game/gamemodes/blob/blobs/resource.dm | 2 +- code/game/gamemodes/blob/blobs/storage.dm | 11 +- code/game/gamemodes/blob/overmind.dm | 5 +- code/game/gamemodes/blob/powers.dm | 17 +-- code/game/gamemodes/blob/theblob.dm | 150 +++++++++----------- 9 files changed, 115 insertions(+), 122 deletions(-) diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm index f41c8e3ad2c..538ec4ca851 100644 --- a/code/game/gamemodes/blob/blobs/blob_mobs.dm +++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm @@ -13,9 +13,10 @@ maxbodytemp = 360 var/mob/camera/blob/overmind = null -/mob/living/simple_animal/hostile/blob/proc/adjustcolors(a_color) - if(a_color) - color = a_color +/mob/living/simple_animal/hostile/blob/update_icons() + ..() + if(overmind) + color = overmind.blob_reagent_datum.color /mob/living/simple_animal/hostile/blob/blob_act() return @@ -121,19 +122,8 @@ M.loc = src.loc return ..() - /mob/living/simple_animal/hostile/blob/blobspore/update_icons() ..() - - if(overmind && overmind.blob_reagent_datum) - adjustcolors(overmind.blob_reagent_datum.color) - else - adjustcolors(color) //to ensure zombie/other overlays update - - -/mob/living/simple_animal/hostile/blob/blobspore/adjustcolors(a_color) - color = a_color - if(is_zombie) overlays.Cut() overlays = human_overlays diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm index 6f9d1d34320..18d2551e9e4 100644 --- a/code/game/gamemodes/blob/blobs/core.dm +++ b/code/game/gamemodes/blob/blobs/core.dm @@ -17,25 +17,30 @@ /obj/effect/blob/core/New(loc, var/h = 200, var/client/new_overmind = null, var/new_rate = 2, offspring) blob_cores += src SSobj.processing |= src - adjustcolors(color) //so it atleast appears + update_icon() //so it atleast appears if(!overmind) create_overmind(new_overmind) if(overmind) - adjustcolors(overmind.blob_reagent_datum.color) + update_icon() if(offspring) is_offspring = 1 point_rate = new_rate ..(loc, h) -/obj/effect/blob/core/adjustcolors(a_color) +/obj/effect/blob/core/update_icon() overlays.Cut() color = null var/image/I = new('icons/mob/blob.dmi', "blob") - I.color = a_color + if(overmind) + I.color = overmind.blob_reagent_datum.color overlays += I var/image/C = new('icons/mob/blob.dmi', "blob_core_overlay") overlays += C + return +/obj/effect/blob/core/PulseAnimation() + update_icon() + return /obj/effect/blob/core/Destroy() blob_cores -= src @@ -69,7 +74,7 @@ health = min(maxhealth, health+health_regen) if(overmind) overmind.update_health() - pulseLoop(0) + Pulse_Area(overmind, 12, 4, 3) for(var/b_dir in alldirs) if(!prob(5)) continue @@ -77,7 +82,8 @@ if(B) var/obj/effect/blob/N = B.change_to(/obj/effect/blob/shield) if(overmind) - N.color = overmind.blob_reagent_datum.color + N.overmind = overmind + N.update_icon() color = null ..() diff --git a/code/game/gamemodes/blob/blobs/factory.dm b/code/game/gamemodes/blob/blobs/factory.dm index e750d359d27..accb937990f 100644 --- a/code/game/gamemodes/blob/blobs/factory.dm +++ b/code/game/gamemodes/blob/blobs/factory.dm @@ -33,6 +33,7 @@ var/mob/living/simple_animal/hostile/blob/blobspore/BS = new/mob/living/simple_animal/hostile/blob/blobspore(src.loc, src) BS.color = color BS.overmind = overmind - overmind.blob_mobs.Add(BS) + if(overmind) + overmind.blob_mobs.Add(BS) return 0 diff --git a/code/game/gamemodes/blob/blobs/node.dm b/code/game/gamemodes/blob/blobs/node.dm index 240f67f5256..dfef151bc22 100644 --- a/code/game/gamemodes/blob/blobs/node.dm +++ b/code/game/gamemodes/blob/blobs/node.dm @@ -5,6 +5,7 @@ desc = "A large, pulsating yellow mass." health = 200 maxhealth = 200 + health_regen = 3 point_return = 25 atmosblock = 1 @@ -14,14 +15,19 @@ SSobj.processing |= src ..(loc, h) -/obj/effect/blob/node/adjustcolors(a_color) +/obj/effect/blob/node/update_icon() overlays.Cut() color = null var/image/I = new('icons/mob/blob.dmi', "blob") - I.color = a_color + if(overmind) + I.color = overmind.blob_reagent_datum.color src.overlays += I var/image/C = new('icons/mob/blob.dmi', "blob_node_overlay") src.overlays += C + return + +/obj/effect/blob/node/PulseAnimation() + return /obj/effect/blob/node/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) return @@ -32,6 +38,5 @@ return ..() /obj/effect/blob/node/Life() - pulseLoop(5) - health = min(initial(health), health + 1) + Pulse_Area(overmind, 10, 3, 2) color = null diff --git a/code/game/gamemodes/blob/blobs/resource.dm b/code/game/gamemodes/blob/blobs/resource.dm index 819d991a00c..03bb6164280 100644 --- a/code/game/gamemodes/blob/blobs/resource.dm +++ b/code/game/gamemodes/blob/blobs/resource.dm @@ -21,7 +21,7 @@ PulseAnimation(1) - resource_delay = world.time + 40 // 4 seconds + resource_delay = world.time + 45 // 4 and a half seconds if(overmind) overmind.add_points(1) diff --git a/code/game/gamemodes/blob/blobs/storage.dm b/code/game/gamemodes/blob/blobs/storage.dm index e64d32fd84b..968101b6b14 100644 --- a/code/game/gamemodes/blob/blobs/storage.dm +++ b/code/game/gamemodes/blob/blobs/storage.dm @@ -1,7 +1,7 @@ /obj/effect/blob/storage name = "storage blob" icon = 'icons/mob/blob.dmi' - icon_state = "blob_resource" + icon_state = "blob_factory" desc = "A huge, smooth mass supported by tendrils." health = 60 maxhealth = 60 @@ -12,13 +12,10 @@ /obj/effect/blob/storage/creation_action() if(overmind) overmind.max_blob_points += point_bonus + overmind.storage_blobs++ /obj/effect/blob/storage/Destroy() - if(overmind) + if(overmind && overmind.storage_blobs) //if the overmind doesn't have any recorded storage blobs, don't TAKE ALL THE POINTS THEY HAVE overmind.max_blob_points -= point_bonus + overmind.storage_blobs-- return ..() - -/obj/effect/blob/storage/PulseAnimation(activate = 0) - if(activate) - ..() - return diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm index 0d814fd6efb..2af309967a4 100644 --- a/code/game/gamemodes/blob/overmind.dm +++ b/code/game/gamemodes/blob/overmind.dm @@ -14,6 +14,7 @@ var/obj/effect/blob/core/blob_core = null // The blob overmind's core var/blob_points = 0 var/max_blob_points = 100 + var/storage_blobs = 0 var/last_attack = 0 var/datum/reagent/blob/blob_reagent_datum = new/datum/reagent/blob() var/list/blob_mobs = list() @@ -29,7 +30,7 @@ possible_reagents.Add(new type) blob_reagent_datum = pick(possible_reagents) if(blob_core) - blob_core.adjustcolors(blob_reagent_datum.color) + blob_core.update_icon() ghostimage = image(src.icon,src,src.icon_state) ghost_darkness_images |= ghostimage //so ghosts can see the blob cursor when they disable darkness @@ -90,7 +91,7 @@ return var/message_a = say_quote(message, get_spans()) - var/rendered = "Blob Telepathy, [name]([blob_reagent_datum.name]) [message_a]" + var/rendered = "Blob Telepathy, [name]([blob_reagent_datum.name]) [message_a]" for (var/mob/M in mob_list) if(isovermind(M) || isobserver(M)) diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm index 41f4788a18c..3cce86aae48 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -161,14 +161,15 @@ if(!can_buy(5)) return last_attack = world.time - OB.expand(T, 0, blob_reagent_datum.color) + OB.expand(T, 0, src) for(var/mob/living/L in T) if("blob" in L.faction) //no friendly fire continue var/mob_protection = L.get_permeability_protection() blob_reagent_datum.reaction_mob(L, VAPOR, 25, 1, mob_protection) blob_reagent_datum.send_message(L) - OB.color = blob_reagent_datum.color + OB.overmind = src + OB.update_icon() /mob/camera/blob/verb/rally_spores_power() set category = "Blob" @@ -209,13 +210,13 @@ set category = "Blob" set name = "Blob Broadcast" set desc = "Speak with your blob spores and blobbernauts as your mouthpieces. This action is free." - var/speak_text = input(usr, "What would you like to say with your minions?", "Blob Broadcast", null) as text + var/speak_text = input(src, "What would you like to say with your minions?", "Blob Broadcast", null) as text if(!speak_text) return else - usr << "You broadcast with your minions, [speak_text]" - for(var/mob/living/simple_animal/hostile/blob_minion in blob_mobs) - if(blob_minion.stat == CONSCIOUS) + src << "You broadcast with your minions, [speak_text]" + for(var/mob/living/simple_animal/hostile/blob/blob_minion in blob_mobs) + if(blob_minion.stat == CONSCIOUS && blob_minion.overmind == src) blob_minion.say(speak_text) /mob/camera/blob/verb/chemical_reroll() @@ -227,9 +228,9 @@ var/datum/reagent/blob/B = pick((subtypesof(/datum/reagent/blob) - blob_reagent_datum.type)) blob_reagent_datum = new B for(var/obj/effect/blob/BL in blobs) - BL.adjustcolors(blob_reagent_datum.color) + BL.update_icon() for(var/mob/living/simple_animal/hostile/blob/BLO) - BLO.adjustcolors(blob_reagent_datum.color) + BLO.update_icons() src << "Your reagent is now: [blob_reagent_datum.name]!" src << "The [blob_reagent_datum.name] reagent [blob_reagent_datum.description]" diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm index 82c6a955d74..2b538a48fc6 100644 --- a/code/game/gamemodes/blob/theblob.dm +++ b/code/game/gamemodes/blob/theblob.dm @@ -12,12 +12,14 @@ var/health = 30 var/maxhealth = 30 var/health_regen = 2 //how much health this blob regens when pulsed - var/health_timestamp = 0 + var/health_timestamp = 0 //we got healed when? + var/pulse_timestamp = 0 //we got pulsed when? var/brute_resist = 2 //divides brute damage by this var/fire_resist = 1 //divides burn damage by this var/atmosblock = 0 //if the blob blocks atmos and heat spread var/mob/camera/blob/overmind + /obj/effect/blob/New(loc) var/area/Ablob = get_area(loc) if(Ablob.blob_allowed) //Is this area allowed for winning as blob? @@ -34,15 +36,6 @@ /obj/effect/blob/proc/creation_action() //When it's created by the overmind, do this. return -/obj/effect/blob/proc/check_health() - if(health <= 0) - qdel(src) - return - return - -/obj/effect/blob/update_icon() //Used for normal blobs, to update icon when weakened. - return - /obj/effect/blob/Destroy() if(atmosblock) atmosblock = 0 @@ -69,6 +62,20 @@ return 0 +/obj/effect/blob/proc/check_health() + if(health <= 0) + qdel(src) //we dead now + return + return + +/obj/effect/blob/update_icon() //Updates color based on overmind color if we have an overmind. + if(overmind) + color = overmind.blob_reagent_datum.color + else + color = null + return + + /obj/effect/blob/process() Life() return @@ -81,70 +88,57 @@ /obj/effect/blob/proc/Life() return +/obj/effect/blob/proc/Pulse_Area(pulsing_overmind = overmind, claim_range = 10, pulse_range = 3, expand_range = 2) + src.Be_Pulsed() + if(claim_range) + for(var/obj/effect/blob/B in ultra_range(claim_range, src, 1)) + B.update_icon() + if(!B.overmind && !istype(B, /obj/effect/blob/core) && prob(30)) + B.overmind = pulsing_overmind //reclaim unclaimed, non-core blobs. + B.update_icon() + if(pulse_range) + for(var/obj/effect/blob/B in orange(pulse_range, src)) + B.Be_Pulsed() + if(expand_range) + src.expand() + for(var/obj/effect/blob/B in orange(expand_range, src)) + if(prob(12)) + B.expand() + return + +/obj/effect/blob/proc/Be_Pulsed() + if(pulse_timestamp <= world.time) + PulseAnimation() + ConsumeTile() + RegenHealth() + run_action() + pulse_timestamp = world.time + 10 + return 1 //we did it, we were pulsed! + return 0 //oh no we failed + /obj/effect/blob/proc/ConsumeTile() for(var/atom/A in loc) A.blob_act() /obj/effect/blob/proc/PulseAnimation() - if(!istype(src, /obj/effect/blob/core) || !istype(src, /obj/effect/blob/node)) - flick("[icon_state]_glow", src) - return - -/obj/effect/blob/proc/RegenHealth() - // All blobs heal over time when pulsed, but it has a cool down - if(health_timestamp > world.time) - return 0 - health = min(maxhealth, health+health_regen) - update_icon() - health_timestamp = world.time + 10 // 1 seconds - -/obj/effect/blob/proc/pulseLoop(num) - var/a_color - if(overmind) - a_color = overmind.blob_reagent_datum.color - for(var/i = 1; i < 8; i += i) - Pulse(num, i, a_color) - -/obj/effect/blob/proc/Pulse(pulse = 0, origin_dir = 0, a_color)//Todo: Fix spaceblob expand - - set background = BACKGROUND_ENABLED - - PulseAnimation() - ConsumeTile() - RegenHealth() - - if(run_action())//If we can do something here then we dont need to pulse more - return - - if(pulse > 30) - return//Inf loop check - - //Looking for another blob to pulse - var/list/dirs = list(1,2,4,8) - dirs.Remove(origin_dir)//Dont pulse the guy who pulsed us - for(var/i = 1 to 4) - if(!dirs.len) - break - var/dirn = pick(dirs) - dirs.Remove(dirn) - var/turf/T = get_step(src, dirn) - var/obj/effect/blob/B = (locate(/obj/effect/blob) in T) - if(!B) - expand(T,1,a_color)//No blob here so try and expand - return - B.adjustcolors(a_color) - - B.Pulse((pulse+1),get_dir(src.loc,T), a_color) - return + flick("[icon_state]_glow", src) return +/obj/effect/blob/proc/RegenHealth() //when pulsed, heal! + if(health_timestamp <= world.time) + health = min(maxhealth, health+health_regen) + update_icon() + health_timestamp = world.time + 10 //1 second between heals + return 1 + return 0 /obj/effect/blob/proc/run_action() return 0 -/obj/effect/blob/proc/expand(turf/T = null, prob = 1, a_color) - if(prob && !prob(health)) return +/obj/effect/blob/proc/expand(turf/T = null, prob = 1, controller = null) + if(prob && !prob(health)) + return if(!T) var/list/dirs = list(1,2,4,8) for(var/i = 1 to 4) @@ -157,20 +151,23 @@ T = null if(!T) return 0 - var/Blob_spawnable = 1 + var/make_blob = 1 //can we make a blob? if(istype(T, /turf/space) && prob(65)) - Blob_spawnable = 0 + make_blob = 0 playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) //Let's give some feedback that we DID try to spawn in space, since players are used to it for(var/atom/A in T) - if(A.density) //Unless density is 0, don't spawn a blob - Blob_spawnable = 0 + if(A.density) + make_blob = 0 A.blob_act() //Hit everything if(T.density) //Check for walls and such dense turfs - Blob_spawnable = 0 + make_blob = 0 T.blob_act() //Hit the turf - if(Blob_spawnable) + if(make_blob) //well, can we? var/obj/effect/blob/B = new /obj/effect/blob/normal(src.loc) - B.color = a_color + if(controller) + B.overmind = controller + else + B.overmind = overmind B.density = 1 if(T.Enter(B,src)) //NOW we can attempt to move into the tile B.density = initial(B.density) @@ -240,25 +237,19 @@ if(controller) B.overmind = controller B.creation_action() - B.adjustcolors(color) + B.update_icon() qdel(src) return B -/obj/effect/blob/proc/adjustcolors(a_color) - if(a_color) - color = a_color - return - /obj/effect/blob/examine(mob/user) ..() user << "It seems to be made of [get_chem_name()]." return /obj/effect/blob/proc/get_chem_name() - for(var/mob/camera/blob/B in mob_list) - if(lowertext(B.blob_reagent_datum.color) == lowertext(src.color)) // Goddamit why we use strings for these - return B.blob_reagent_datum.name - return "unknown" + if(overmind) + return overmind.blob_reagent_datum.name + return "an unknown variant" /obj/effect/blob/normal icon_state = "blob" @@ -269,6 +260,7 @@ brute_resist = 4 /obj/effect/blob/normal/update_icon() + ..() if(health <= 10) icon_state = "blob_damaged" name = "fragile blob" From 6ad8d63c1d4a25dbe1ba024789ae09eb4feb3478 Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Mon, 14 Dec 2015 21:32:44 -0500 Subject: [PATCH 24/57] No stealing other people's resource nodes, shitface. --- code/game/gamemodes/blob/blobs/core.dm | 1 - code/game/gamemodes/blob/powers.dm | 2 -- 2 files changed, 3 deletions(-) diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm index 18d2551e9e4..31e01a2fd4c 100644 --- a/code/game/gamemodes/blob/blobs/core.dm +++ b/code/game/gamemodes/blob/blobs/core.dm @@ -39,7 +39,6 @@ return /obj/effect/blob/core/PulseAnimation() - update_icon() return /obj/effect/blob/core/Destroy() diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm index 3cce86aae48..dd4eed4b1ff 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -168,8 +168,6 @@ var/mob_protection = L.get_permeability_protection() blob_reagent_datum.reaction_mob(L, VAPOR, 25, 1, mob_protection) blob_reagent_datum.send_message(L) - OB.overmind = src - OB.update_icon() /mob/camera/blob/verb/rally_spores_power() set category = "Blob" From 5202917b9fb0ef889a2061302c3aeb096244f5b1 Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Mon, 14 Dec 2015 22:26:51 -0500 Subject: [PATCH 25/57] Tweaks revenant reveal times down slightly. Fixes blight still doing stamina damage at final stage. --- code/modules/mob/living/simple_animal/revenant/revenant.dm | 2 +- .../mob/living/simple_animal/revenant/revenant_abilities.dm | 5 ++--- .../mob/living/simple_animal/revenant/revenant_blight.dm | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/code/modules/mob/living/simple_animal/revenant/revenant.dm b/code/modules/mob/living/simple_animal/revenant/revenant.dm index f782e2c0778..3ee6cdb9bd5 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant.dm @@ -24,7 +24,7 @@ see_in_dark = 8 languages = ALL response_help = "passes through" - response_disarm = "swings at" + response_disarm = "swings through" response_harm = "punches through" unsuitable_atmos_damage = 0 damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) //I don't know how you'd apply those, but revenants no-sell them anyway. diff --git a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm index 75b0a52335c..525c6a3f414 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm @@ -89,10 +89,9 @@ charge_max = 200 range = 5 stun = 30 - reveal = 100 cast_amount = 40 var/shock_range = 2 - var/shock_damage = 18 + var/shock_damage = 20 action_icon_state = "overload_lights" /obj/effect/proc_holder/spell/aoe_turf/revenant/overload/cast(list/targets, mob/living/simple_animal/revenant/user = usr) @@ -217,7 +216,7 @@ desc = "Causes nearby living things to waste away." charge_max = 200 range = 3 - reveal = 60 + reveal = 50 cast_amount = 50 unlock_amount = 200 action_icon_state = "blight" diff --git a/code/modules/mob/living/simple_animal/revenant/revenant_blight.dm b/code/modules/mob/living/simple_animal/revenant/revenant_blight.dm index 924f5522c6f..11ca11e7d3b 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant_blight.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant_blight.dm @@ -37,7 +37,7 @@ stagedamage++ affected_mob.adjustToxLoss(stage*3) //should, normally, do about 45 toxin damage. PoolOrNew(/obj/effect/overlay/temp/revenant, affected_mob.loc) - if(prob(45)) + if(!finalstage && prob(45)) affected_mob.adjustStaminaLoss(stage*2) ..() //So we don't increase a stage before applying the stage damage. switch(stage) From f160b752290dfb2f0c6177488c17b5fde6de88b5 Mon Sep 17 00:00:00 2001 From: KazeEspada Date: Mon, 14 Dec 2015 21:51:47 -0700 Subject: [PATCH 26/57] Lizards only triple single s instead of double ss or more. This makes them slightly less annoying. --- code/modules/mob/living/carbon/human/species_types.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/carbon/human/species_types.dm b/code/modules/mob/living/carbon/human/species_types.dm index 69732a8e1a4..347553ae8c2 100644 --- a/code/modules/mob/living/carbon/human/species_types.dm +++ b/code/modules/mob/living/carbon/human/species_types.dm @@ -82,9 +82,9 @@ datum/species/human/spec_death(gibbed, mob/living/carbon/human/H) return 1 /datum/species/lizard/handle_speech(message) - // jesus christ why + if(copytext(message, 1, 2) != "*") - message = replacetext(message, "s", "sss") + message = regex_replaceall(message, "(? Date: Tue, 15 Dec 2015 00:52:38 -0700 Subject: [PATCH 27/57] Lizard s is now case sensitive. No more "sssYNDICATEsss". ss is now ssss, which makes it Assssissstantsss. --- code/modules/mob/living/carbon/human/species_types.dm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/human/species_types.dm b/code/modules/mob/living/carbon/human/species_types.dm index 347553ae8c2..fa93d52e5ef 100644 --- a/code/modules/mob/living/carbon/human/species_types.dm +++ b/code/modules/mob/living/carbon/human/species_types.dm @@ -84,7 +84,10 @@ datum/species/human/spec_death(gibbed, mob/living/carbon/human/H) /datum/species/lizard/handle_speech(message) if(copytext(message, 1, 2) != "*") - message = regex_replaceall(message, "(? Date: Thu, 10 Dec 2015 14:43:42 -0300 Subject: [PATCH 28/57] Cult Overhaul Cult is awful, so let's try to improve it. Idea by KorPhaeron. I also took some inspiration from adrix89's sacrifice cult, so credits to him. Also thanks a lot specially to MrPerson and Iamgoofball for helping me brainstorm this, and Joan for the sprites for the summoning orb, the large nar-sie shell, and the new cult antag hud. Basically, we remove conversion, and turn cult into a magic version of nuke, with a small team of stealth elite cultists that have to build a base in the station and sacrifice people in order to build an army of constructs and get materials to eventually summon Nar-Sie. Stun talismans and conversion are gone. Nar-Sie is now the only objective. Sacrifice runes now provide summoning orbs, which you can use to drop a large shell. Insert enough orbs in the shell and you trigger a Delta. Defend the shell for 3 minutes and Nar-sie will arise. This shell is bombproof and singularityproof. It may be summoned up to three times if destroyed, but you will have to start from the beginning sac-wise. Runes are now RNG. Each cultist only gets 50% of the runes. Inspiration is basically The Binding of Isaac here (thank you MrPerson for this!). Furthermore, many old runes were merged/removed and other new ones were added. Almost all were massively rebalanced. Cult now also has a stealthy ritual dagger with high bleeding and throw effects. --- code/datums/mind.dm | 69 +--- code/game/gamemodes/cult/cult.dm | 200 ++-------- code/game/gamemodes/cult/cult_items.dm | 65 ++++ code/game/gamemodes/cult/cult_structures.dm | 146 ++++++- code/game/gamemodes/cult/ritual.dm | 116 ++---- code/game/gamemodes/cult/runes.dm | 361 ++++++------------ code/game/gamemodes/cult/talisman.dm | 189 +++------ code/game/gamemodes/wizard/soulstone.dm | 15 +- .../objects/items/weapons/storage/book.dm | 7 - code/modules/admin/verbs/debug.dm | 91 ----- code/modules/admin/verbs/one_click_antag.dm | 3 +- code/modules/mob/living/bloodcrawl.dm | 6 +- .../mob/living/carbon/human/species.dm | 3 - code/modules/mob/mob_defines.dm | 1 - code/modules/paperwork/paper.dm | 4 - code/modules/power/singularity/narsie.dm | 2 +- code/modules/power/singularity/singularity.dm | 2 +- .../chemistry/reagents/other_reagents.dm | 5 +- html/changelogs/Tkdrg-Cult-Overhaul.yml | 15 + icons/mob/hud.dmi | Bin 9768 -> 9657 bytes icons/obj/cult.dmi | Bin 14583 -> 15762 bytes icons/obj/cult_large.dmi | Bin 0 -> 2312 bytes 22 files changed, 474 insertions(+), 826 deletions(-) create mode 100644 html/changelogs/Tkdrg-Cult-Overhaul.yml create mode 100644 icons/obj/cult_large.dmi diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 8d61b841478..40af75b2a57 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -46,7 +46,6 @@ var/list/datum/objective/objectives = list() var/list/datum/objective/special_verbs = list() - var/list/cult_words = list() var/list/spell_list = list() // Wizard mode & "Give Spell" badmin button. var/datum/faction/faction //associated faction @@ -147,12 +146,7 @@ if(src in ticker.mode.cult) ticker.mode.cult -= src ticker.mode.update_cult_icons_removed(src) - var/datum/game_mode/cult/cult = ticker.mode - if(istype(cult)) - cult.memorize_cult_objectives(src) special_role = null - remove_objectives() - remove_antag_equip() /datum/mind/proc/remove_rev() if(src in ticker.mode.revolutionaries) @@ -342,11 +336,8 @@ text = "[text]: " if (src in ticker.mode.cult) text += "loyal|employee|CULTIST" - text += "
Give tome|amulet." -/* - if (objectives.len==0) - text += "
Objectives are empty! Set to sacrifice and escape or summon." -*/ + text += "
Equip" + else if(isloyal(current)) text += "LOYAL|employee|cultist" else @@ -1008,31 +999,9 @@ ticker.mode.add_cultist(src) message_admins("[key_name_admin(usr)] has cult'ed [current].") log_admin("[key_name(usr)] has cult'ed [current].") - if("tome") - var/mob/living/carbon/human/H = current - if (istype(H)) - var/obj/item/weapon/tome/T = new(H) - - var/list/slots = list ( - "backpack" = slot_in_backpack, - "left pocket" = slot_l_store, - "right pocket" = slot_r_store, - "left hand" = slot_l_hand, - "right hand" = slot_r_hand, - ) - var/where = H.equip_in_one_of_slots(T, slots) - if (!where) - usr << "Spawning tome failed!" - else - H << "A tome, a message from your new master, appears in your [where]." - if(where == "backpack") - var/obj/item/weapon/storage/B = H.back - B.orient2hud(H) - B.show_to(H) - - if("amulet") + if("equip") if (!ticker.mode.equip_cultist(current)) - usr << "Spawning amulet failed!" + usr << "equip_cultist() failed! [current]'s starting equipment will be incomplete." else if (href_list["wizard"]) switch(href_list["wizard"]) @@ -1430,34 +1399,8 @@ special_role = "Cultist" current << "You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie." current << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." - var/datum/game_mode/cult/cult = ticker.mode - if (istype(cult)) - cult.memorize_cult_objectives(src) - else - var/explanation = "Summon Nar-Sie via the use of the appropriate rune (Hell join self). It will only work if nine cultists stand on and around it." - current << "Objective #1: [explanation]" - current.memory += "Objective #1: [explanation]
" - current << "The convert rune is join blood self" - current.memory += "The convert rune is join blood self
" - - var/mob/living/carbon/human/H = current - if (istype(H)) - var/obj/item/weapon/tome/T = new(H) - - var/list/slots = list ( - "backpack" = slot_in_backpack, - "left pocket" = slot_l_store, - "right pocket" = slot_r_store, - "left hand" = slot_l_hand, - "right hand" = slot_r_hand, - ) - var/where = H.equip_in_one_of_slots(T, slots) - if (!where) - else - H << "A tome, a message from your new master, appears in your [where]." - - if (!ticker.mode.equip_cultist(current)) - H << "Spawning an amulet from your Master failed." + current << "Your objective is to summon Nar-Sie by building and defending a suitable shell for the Geometer. Adequate supplies can be procured through human sacrifices." + ticker.mode.equip_cultist(current) /datum/mind/proc/make_Rev() if (ticker.mode.head_revolutionaries.len>0) diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index cd0d3b4315a..7b43cb7958e 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -2,29 +2,11 @@ /datum/game_mode var/list/datum/mind/cult = list() - var/list/cult_objectives = list() - /proc/iscultist(mob/living/M) return istype(M) && M.mind && ticker && ticker.mode && (M.mind in ticker.mode.cult) -/proc/is_sacrifice_target(datum/mind/mind) - if(ticker.mode.name == "cult") - var/datum/game_mode/cult/cult_mode = ticker.mode - if(mind == cult_mode.sacrifice_target) - return 1 - return 0 - -/proc/is_convertable_to_cult(datum/mind/mind) - if(!istype(mind)) return 0 - if(istype(mind.current, /mob/living/carbon/human) && (mind.assigned_role in list("Captain", "Chaplain"))) return 0 - if(isloyal(mind.current)) - return 0 - if (ticker.mode.name == "cult") //redundent? - if(is_sacrifice_target(mind)) return 0 - return 1 - -/proc/cultist_commune(mob/living/user, clear = 0, say = 0, message) +/proc/cultist_commune(mob/living/user, say = 0, message) if(!message) return if(say) @@ -40,10 +22,7 @@ user.whisper(message) for(var/mob/M in mob_list) if(iscultist(M) || (M in dead_mob_list)) - if(clear || !ishuman(user)) - M << "[(ishuman(user) ? "Acolyte" : "Construct")] [user]: [message]" - else //Emergency comms - M << "Acolyte ???: [message]" + M << "[(ishuman(user) ? "Acolyte" : "Construct")] [user]: [message]" log_say("[user.real_name]/[user.key] : [message]") @@ -54,42 +33,31 @@ antag_flag = ROLE_CULTIST restricted_jobs = list("Chaplain","AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel") protected_jobs = list() - required_players = 20 - required_enemies = 4 - recommended_enemies = 4 + required_players = 10 + required_enemies = 2 + recommended_enemies = 2 enemy_minimum_age = 14 - - var/finished = 0 - - var/eldergod = 1 //for the summon god objective - - var/acolytes_needed = 10 //for the survive objective - var/acolytes_survived = 0 - - var/datum/mind/sacrifice_target = null//The target to be sacrificed - + var/eldergod = 0 + var/orbs_needed = 3 + var/large_shell_summoned = 0 + var/attempts_left = 3 /datum/game_mode/cult/announce() world << "The current game mode is - Cult!" - world << "Some crewmembers are attempting to start a cult!
\nCultists - complete your objectives. Convert crewmembers to your cause by using the convert rune. Remember - there is no you, there is only the cult.
\nPersonnel - Do not let the cult succeed in its mission. Brainwashing them with the chaplain's bible reverts them to whatever Centcom-allowed faith they had.
" + world << "Some crewmembers are attempting to start a cult!
\nCultists - summon the elder god. Sacrifice crewmembers and turn them into constructs. Remember - there is no you, there is only the cult.
\nPersonnel - Do not let the cult succeed in its mission. Deal with the cultists and any constructs that they might summon.
" /datum/game_mode/cult/pre_setup() - cult_objectives += "sacrifice" - if(prob(50)) - cult_objectives += "survive" - else - cult_objectives += "eldergod" - if(config.protect_roles_from_antagonist) restricted_jobs += protected_jobs if(config.protect_assistant_from_antagonist) restricted_jobs += "Assistant" - acolytes_needed = round(num_players()/5,1) //Scales the escape requirement with the amount of people in the round; for every 5 players, one cultist added to the count, i.e. 25 players = 5 to escape - acolytes_needed = Clamp(acolytes_needed, 1, 15) //Max at 15 and minimum at 1 - before the update, people rarely got even 15 + //cult scaling goes here + recommended_enemies = 1 + round(num_players()/8) + orbs_needed = recommended_enemies for(var/cultists_number = 1 to recommended_enemies) if(!antag_candidates.len) @@ -106,22 +74,6 @@ /datum/game_mode/cult/post_setup() modePlayer += cult - if("sacrifice" in cult_objectives) - var/list/possible_targets = get_unconvertables() - - if(!possible_targets.len) - message_admins("Cult Sacrifice: Could not find unconvertable target, checking for convertable target.") - for(var/mob/living/carbon/human/player in player_list) - if(player.mind && !(player.mind in cult)) - possible_targets += player.mind - - if(possible_targets.len > 0) - sacrifice_target = pick(possible_targets) - if(!sacrifice_target) - message_admins("Cult Sacrifice: ERROR - Null target chosen!") - else - message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!") - for(var/datum/mind/cult_mind in cult) equip_cultist(cult_mind.current) update_cult_icons_added(cult_mind) @@ -131,20 +83,7 @@ /datum/game_mode/cult/proc/memorize_cult_objectives(datum/mind/cult_mind) - for(var/obj_count = 1,obj_count <= cult_objectives.len,obj_count++) - var/explanation - switch(cult_objectives[obj_count]) - if("survive") - explanation = "Our knowledge must live on. Make sure at least [acolytes_needed] acolytes escape on the shuttle to spread their work on an another station." - if("sacrifice") - if(sacrifice_target) - explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. You will need the Sacrifice rune and three acolytes to do so." - else - explanation = "Free objective." - if("eldergod") - explanation = "Summon Nar-Sie via the rune 'Call Forth The Geometer'. It will only work if nine acolytes stand on and around it." - cult_mind.current << "Objective #[obj_count]: [explanation]" - cult_mind.memory += "Objective #[obj_count]: [explanation]
" + cult_mind.current << "Your objective is to summon Nar-Sie by building and defending a suitable shell for the Geometer. Adequate supplies can be procured through human sacrifices." /datum/game_mode/proc/equip_cultist(mob/living/carbon/human/mob) if(!istype(mob)) @@ -155,20 +94,27 @@ mob << "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself." mob.dna.remove_mutation(CLOWNMUT) + . += cult_give_item(/obj/item/weapon/tome, mob) + . += cult_give_item(/obj/item/weapon/paper/talisman/supply, mob) + . += cult_give_item(/obj/item/weapon/melee/cultblade/dagger, mob) + mob << "These will help you start the cult on this station. Use them well, and remember - you are not the only one." - var/obj/item/weapon/paper/talisman/supply/T = new(mob) - var/list/slots = list ( +/datum/game_mode/proc/cult_give_item(obj/item/item_path, mob/living/carbon/human/mob) + var/list/slots = list( "backpack" = slot_in_backpack, "left pocket" = slot_l_store, "right pocket" = slot_r_store, "left hand" = slot_l_hand, "right hand" = slot_r_hand, ) + var/T = new item_path(mob) + var/item_name = initial(item_path.name) var/where = mob.equip_in_one_of_slots(T, slots) if(!where) - mob << "Unfortunately, you weren't able to get a talisman. This is very bad and you should adminhelp immediately." + mob << "Unfortunately, you weren't able to get a [item_name]. This is very bad and you should adminhelp immediately (press F1)." + return 0 else - mob << "You have a talisman in your [where], one that will help you start the cult on this station. Use it well, and remember - you are not the only one." + mob << "You have a [item_name] in your [where]." mob.update_icons() if(where == "backpack") var/obj/item/weapon/storage/B = mob.back @@ -176,20 +122,18 @@ B.show_to(mob) return 1 - /datum/game_mode/proc/add_cultist(datum/mind/cult_mind) //BASE - if (!istype(cult_mind)) + if (!istype(cult_mind) || (cult_mind in cult)) return 0 - if(!(cult_mind in cult) && is_convertable_to_cult(cult_mind)) - cult_mind.current.Paralyse(5) - cult += cult_mind - cult_mind.current.faction |= "cult" - cult_mind.current.cult_add_comm() - update_cult_icons_added(cult_mind) - cult_mind.current.attack_log += "\[[time_stamp()]\] Has been converted to the cult!" - if(jobban_isbanned(cult_mind.current, ROLE_CULTIST)) - replace_jobbaned_player(cult_mind.current, ROLE_CULTIST, ROLE_CULTIST) - return 1 + cult_mind.current.Paralyse(5) + cult += cult_mind + cult_mind.current.faction |= "cult" + cult_mind.current.cult_add_comm() + update_cult_icons_added(cult_mind) + cult_mind.current.attack_log += "\[[time_stamp()]\] Has been converted to the cult!" + if(jobban_isbanned(cult_mind.current, ROLE_CULTIST)) + replace_jobbaned_player(cult_mind.current, ROLE_CULTIST, ROLE_CULTIST) + return 1 /datum/game_mode/cult/add_cultist(datum/mind/cult_mind) //INHERIT @@ -222,85 +166,13 @@ culthud.leave_hud(cult_mind.current) set_antag_hud(cult_mind.current, null) -/datum/game_mode/cult/proc/get_unconvertables() - var/list/ucs = list() - for(var/mob/living/carbon/human/player in player_list) - if(player.mind && !is_convertable_to_cult(player.mind)) - ucs += player.mind - return ucs - - -/datum/game_mode/cult/proc/check_cult_victory() - var/cult_fail = 0 - if(cult_objectives.Find("survive")) - cult_fail += check_survive() //the proc returns 1 if there are not enough cultists on the shuttle, 0 otherwise - if(cult_objectives.Find("eldergod")) - cult_fail += eldergod //1 by default, 0 if the elder god has been summoned at least once - if(cult_objectives.Find("sacrifice")) - if(sacrifice_target && !sacrificed.Find(sacrifice_target)) //if the target has been sacrificed, ignore this step. otherwise, add 1 to cult_fail - cult_fail++ - - return cult_fail //if any objectives aren't met, failure - - -/datum/game_mode/cult/proc/check_survive() - acolytes_survived = 0 - for(var/datum/mind/cult_mind in cult) - if (cult_mind.current && cult_mind.current.stat != DEAD) - if(cult_mind.current.onCentcom() || cult_mind.current.onSyndieBase()) - acolytes_survived++ - if(acolytes_survived>=acolytes_needed) - return 0 - else - return 1 - - /datum/game_mode/cult/declare_completion() - - if(!check_cult_victory()) + if(eldergod) feedback_set_details("round_end_result","win - cult win") - feedback_set("round_end_result",acolytes_survived) world << "The cult wins! It has succeeded in serving its dark master!" else feedback_set_details("round_end_result","loss - staff stopped the cult") - feedback_set("round_end_result",acolytes_survived) world << "The staff managed to stop the cult!" - - var/text = "" - - if(cult_objectives.len) - text += "
The cultists' objectives were:" - for(var/obj_count=1, obj_count <= cult_objectives.len, obj_count++) - var/explanation - switch(cult_objectives[obj_count]) - if("survive") - if(!check_survive()) - explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) Success!" - feedback_add_details("cult_objective","cult_survive|SUCCESS|[acolytes_needed]") - else - explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) Fail." - feedback_add_details("cult_objective","cult_survive|FAIL|[acolytes_needed]") - if("sacrifice") - if(sacrifice_target) - if(sacrifice_target in sacrificed) - explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Success!" - feedback_add_details("cult_objective","cult_sacrifice|SUCCESS") - else if(sacrifice_target && sacrifice_target.current) - explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Fail." - feedback_add_details("cult_objective","cult_sacrifice|FAIL") - else - explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Fail (Gibbed)." - feedback_add_details("cult_objective","cult_sacrifice|FAIL|GIBBED") - if("eldergod") - if(!eldergod) - explanation = "Summon Nar-Sie. Success!" - feedback_add_details("cult_objective","cult_narsie|SUCCESS") - else - explanation = "Summon Nar-Sie. Fail." - feedback_add_details("cult_objective","cult_narsie|FAIL") - text += "
Objective #[obj_count]: [explanation]" - - world << text ..() return 1 diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index af5df6a2f62..67acdd9d67a 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -4,6 +4,7 @@ icon_state = "cultblade" item_state = "cultblade" flags = CONDUCT + sharpness = IS_SHARP w_class = 4 force = 30 throwforce = 10 @@ -31,6 +32,21 @@ user << "An overwhelming sense of nausea overpowers you!" user.Dizzy(120) +/obj/item/weapon/melee/cultblade/dagger + name = "sacrificial dagger" + desc = "A strange dagger said to be used by sinister groups for \"preparing\" a corpse before sacrificing it to their dark gods." + icon = 'icons/obj/wizard.dmi' + icon_state = "render" + w_class = 2 + force = 15 + throwforce = 25 + embed_chance = 75 + +/obj/item/weapon/melee/cultblade/dagger/attack(mob/living/target, mob/living/carbon/human/user) + ..() + if(ishuman(target)) + var/mob/living/carbon/human/H = target + H.drip(50) /obj/item/clothing/head/culthood name = "ancient cultist hood" @@ -108,3 +124,52 @@ w_class = 3 allowed = list(/obj/item/weapon/tome,/obj/item/weapon/melee/cultblade,/obj/item/weapon/tank/internals/) armor = list(melee = 70, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) + +/obj/item/summoning_orb + name = "summoning orb" + desc = "A mysterious orb that glows eerily. You could swear that it just moved on its own." + icon = 'icons/obj/cult.dmi' + icon_state = "summoning_orb" + w_class = 1 + +/obj/item/summoning_orb/afterattack(atom/target, mob/user, proximity_flag) + if(!iscultist(user)) + return ..() + if(proximity_flag && isliving(target) && iscultist(target)) + var/mob/living/L = target + if(L.stat == DEAD) + user << "You shouldn't waste that." + return ..() + target << "You feel the Geometer's essence violating your insides." + target << "It feels... good." + target.reagents.add_reagent("unholywater", 15) + qdel(src) + ..() + +/obj/item/summoning_orb/attack_self(mob/user) + if(!iscultist(user)) + return ..() + if(ticker.mode.name != "cult") + return + var/datum/game_mode/cult/cult = ticker.mode + if(!cult.attempts_left) + user << "You attempt to call out to the Geometer, but there is no answer..." + return + switch(alert(user,"Are you sure you wish to summon the large construct shell? [cult.attempts_left] attempts left!","Summoning Large Shell","Yes","No")) + if("Yes") + cult.attempts_left-- + place_down_large_shell(user) + qdel(src) + +/obj/item/summoning_orb/proc/place_down_large_shell(mob/user) + if(!(ticker.mode.name == "cult")) + user << "You attempt to call out to the Geometer for Her shell, but you fail..." + return + var/datum/game_mode/cult/cult = ticker.mode + if(cult.large_shell_summoned) + user << "Another Acolyte has already summoned Her shell. You must go forth and contact them." + return + if(cult.attempts_left <= 0) + user << "The Geometer is no longer interested in you." + new /obj/structure/constructshell/large(get_turf(src)) + cult.large_shell_summoned = 1 diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm index 95b685beb29..b5b5cb9d0c4 100644 --- a/code/game/gamemodes/cult/cult_structures.dm +++ b/code/game/gamemodes/cult/cult_structures.dm @@ -1,3 +1,148 @@ +/obj/structure/constructshell/large + name = "large empty shell" + icon = 'icons/obj/cult_large.dmi' + icon_state = "shell_narsie_grey" + desc = "An oversized construct shell, fit for an elder god. Only a lunatic would even dream of such a crazed contraption." + pixel_x = -16 + pixel_y = -16 + density = 1 + anchored = 0 + var/maxhealth = 200 + var/health = 200 + var/image/black_overlay = null + var/orbs = 0 + var/orbs_needed = 1 + var/time_to_win = 1800 //3 minutes + var/timer_id = null + +/obj/structure/constructshell/large/New() + ..() + if(ticker.mode.name == "cult") + var/datum/game_mode/cult/cult = ticker.mode + orbs_needed = cult.orbs_needed + black_overlay = image('icons/obj/cult_large.dmi', "shell_narsie_black") + +/obj/structure/constructshell/large/Destroy() + priority_announce("The extra-dimensional flow has ceased. All personnel should return to their routine activities.","Central Command Higher Dimensions Affairs") + if(get_security_level() == "delta") + set_security_level("red") + if(ticker.mode.name == "cult") + var/datum/game_mode/cult/cult = ticker.mode + cult.large_shell_summoned = 0 + black_overlay = null + if(timer_id) + deltimer(timer_id) + ..() + +/obj/structure/constructshell/large/examine(mob/user) + ..() + user << "You see a number of round holes on the surface of the shell. They number [orbs_needed], and [orbs ? orbs : "none"] of them [orbs > 1 ? "are" : "is"] filled." + +/obj/structure/constructshell/large/update_icon() + var/new_alpha = round((orbs/orbs_needed)*255) + if(new_alpha) + overlays -= black_overlay + black_overlay.alpha = new_alpha + overlays += black_overlay + +/obj/structure/constructshell/large/attackby(obj/item/O, mob/user, params) + if(istype(O, /obj/item/summoning_orb) && (orbs < orbs_needed)) + if(!iscultist(user)) + return + visible_message("\The [src] glows.") + orbs++ + qdel(O) + update_icon() + if(orbs >= orbs_needed) + start_takeover() + return + + if( (O.flags&NOBLUDGEON) || !O.force ) + return + add_fingerprint(user) + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) + playsound(src, 'sound/weapons/smash.ogg', 50, 1) + visible_message("[user] has hit \the [src] with [O].") + if(O.damtype == BURN || O.damtype == BRUTE) + damaged(O.force) + +//this stuff is mostly copy-pasted from gang dominators, with some changes +/obj/structure/constructshell/large/proc/start_takeover() + anchored = 1 + animate(black_overlay, alpha = 255, 5, -1) + set_security_level("delta") + var/area/A = get_area(src) + var/locname = initial(A.name) + priority_announce("Figments from an eldritch god have begun pouring into [locname] from an unknown dimension. Eliminate its vessel before it reaches a critical point.","Central Command Higher Dimensions Affairs") + timer_id = addtimer(src, "summon_narnar", time_to_win) + +/obj/structure/constructshell/large/proc/damaged(damage) + health -= damage + if(health <= 0) + new /obj/item/stack/sheet/plasteel(get_turf(src)) + qdel(src) + +/obj/structure/constructshell/large/bullet_act(obj/item/projectile/P) + if(P.damage) + playsound(src, 'sound/effects/bang.ogg', 50, 1) + visible_message("[src] was hit by [P].") + damaged(P.damage) + +/obj/structure/constructshell/large/attack_alien(mob/living/user) + user.do_attack_animation(src) + playsound(src, 'sound/effects/bang.ogg', 50, 1) + user.visible_message("[user] smashes against [src] with its claws.",\ + "You smash against [src] with your claws.") + damaged(15) + +/obj/structure/constructshell/large/attack_animal(mob/living/user) + if(!isanimal(user)) + return + var/mob/living/simple_animal/M = user + M.do_attack_animation(src) + if(M.melee_damage_upper <= 0) + return + damaged(M.melee_damage_upper) + +/obj/structure/constructshell/large/mech_melee_attack(obj/mecha/M) + if(M.damtype == "brute") + playsound(src, 'sound/effects/bang.ogg', 50, 1) + visible_message("[M.name] has hit [src].") + damaged(M.force) + +/obj/structure/constructshell/large/attack_hulk(mob/user) + playsound(src, 'sound/effects/bang.ogg', 50, 1) + user.visible_message("[user] smashes [src].",\ + "You punch [src].") + damaged(5) + +/obj/structure/constructshell/large/ex_act() + return //nope + +/obj/structure/constructshell/large/singularity_pull() + return //nope + +/obj/structure/constructshell/large/singularity_act(current_size, obj/singularity/S) + var/atom/target = get_edge_target_turf(src, get_dir(src, S)) + S.throw_at(target, 5, 1) //aaand nope + +/obj/structure/constructshell/large/proc/summon_narnar() + if(ticker.mode.name != "cult") + visible_message("\The [src] glows brightly once, then falls dark. It looks strangely dull and lifeless...") + log_game("Summon Nar-Sie rune failed - gametype is not cult") + return + var/datum/game_mode/cult/cult_mode = ticker.mode + if(cult_mode.eldergod) + return //this should never happen, so we don't need any special fluff + world << 'sound/effects/dimensional_rend.ogg' + world << "Rip... Rrrip... RRRRRRRRRR--" + var/turf/target_turf = get_turf(src) + spawn(40) + new /obj/singularity/narsie/large(target_turf) //Causes Nar-Sie to spawn even if the rune has been removed + cult_mode.eldergod = 1 + + /obj/structure/cult density = 1 anchored = 1 @@ -8,7 +153,6 @@ desc = "A bloodstained altar dedicated to Nar-Sie" icon_state = "talismanaltar" - /obj/structure/cult/forge name = "daemon forge" desc = "A forge used in crafting the unholy weapons used by the armies of Nar-Sie" diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index 55ce399d19a..5ccc6d9e3f2 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -1,9 +1,6 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 - /* This file contains the arcane tome files as well as innate cultist emergency communications. -It also contains rune words, which are soon to be removed. */ @@ -12,7 +9,7 @@ It also contains rune words, which are soon to be removed. /mob/living/proc/cult_innate_comm() set category = "Cultist" - set name = "Imperfect Communion" + set name = "Communion" if(!iscultist(usr)) //they shouldn't have this verb, but just to be sure... return @@ -24,24 +21,7 @@ It also contains rune words, which are soon to be removed. if(!input) // TO-DO: Add some kind of filter to corrupt the inputted text return - if(ishuman(usr) || ismonkey(usr)) //Damage only applies to humans and monkeys, to allow constructs to communicate - usr.visible_message("[usr] starts clawing at \his arms with \his fingernails!", "You begin slicing open your arms with your fingernails!") - apply_damage(10,BRUTE, "l_arm") - apply_damage(10,BRUTE, "r_arm") - sleep(50) - if(usr.incapacitated()) - return //Hard to drawn intrinsic symbols when you're bleeding out in your cell. - var/turf/location = loc - if(istype(location, /turf/simulated)) // tearing your arms apart is going to spill a bit of blood, in fact thats the idea - location.add_blood(usr) // TO-DO change this to a badly drawn rune - apply_damage(10,BRUTE, "l_arm") // does a metric fuck ton of damage because this meant to be an emergency method of communication. - apply_damage(10,BRUTE, "r_arm") - if(usr.incapacitated()) - return - usr.visible_message("[usr] paints strange symbols with their own blood.", "You paint a messy rune with your own blood.") - sleep(20) - - cultist_commune(usr, 0, 1, input) + cultist_commune(usr, 0, input) return @@ -52,6 +32,13 @@ It also contains rune words, which are soon to be removed. throw_speed = 2 throw_range = 5 w_class = 2 + var/list/known_runes = null + +/obj/item/weapon/tome/New() + ..() + known_runes = shuffle(subtypesof(/obj/effect/rune) - /obj/effect/rune/malformed) + var/known_amount = round((known_runes.len)/2) + known_runes.Cut(known_amount) /obj/item/weapon/tome/examine(mob/user) ..() @@ -92,47 +79,20 @@ It also contains rune words, which are soon to be removed. open_tome(user) /obj/item/weapon/tome/proc/open_tome(mob/user) - var/choice = alert(user,"You open the tome...",,"Commune","Scribe Rune","Read Tome") + var/choice = alert(user,"You open the tome...",,"Scribe Rune","Read Tome") switch(choice) if("Read Tome") read_tome(user) if("Scribe Rune") scribe_rune(user) - if("Commune") - var/input = stripped_input(usr, "Please enter a message to tell to the other acolytes.", "Voice of Blood", "") - if(!input) - return - cultist_commune(user, 1, 0, input) /obj/item/weapon/tome/proc/read_tome(mob/user) var/text = "" text += "
Archives of the Dark One



" text += "As a member of the cult, your goals are almost or entirely impossible to complete without special aid from the Geometer's plane. The primary method of doing this are runes. These \ scribings, drawn in blood, are concentrated nodes of the magic within Nar-Sie's realm and will allow the performance of many tasks to aid you and the rest of the cult in your objectives. Runes \ - have many different names, and almost all of them are known as Rites. The only rune that is not a Rite is the Ritual of Dimensional Rending, which can only be performed with nine cultists and calls \ - forth the avatar of the Geometer herself (so long as she consents). A small description of each rune can be found below.

A rune's name and effects can be \ - revealed by examining the rune.


"/*In order to write a rune, you must know the combination of words required for the rune. These words are in the tongue of the Geometer and must be written as such. \ - A rune will always have a specific combination, and the combination for runes may be revealed by perfomring actions such as conversion or sacrifice. Once a rune has been written, any cultists can \ - examine it to find out its \"grammar\", or the words required to scribe it. To scribe the rune, the words must be entered in lowercase and separated by exactly one space. For instance, to draw a \ - Rite of Enlightenment, one would enter the sentence \"certum nahlizet ego\", which means \"join blood self\". You may guess at combinations or perform actions to discover them.

A full list of \ - the Words of Power as well as their meanings in plain English are listed below, although a more complete archive may be accessed at a research desk.

\ - The Words of Power
\ - \"ire\" is Travel
\ - \"ego\" is Self
\ - \"nahlizet\" is Blood
\ - \"certum\" is Join
\ - \"veri\" is Hell
\ - \"jatkaa\" is Other
\ - \"mgar\" is Destroy
\ - \"balaq\" is Technology
\ - \"karazet\" is See
\ - \"geeri\" is Hide

\ - A few basic runes
\ - Rite of Translocation: \"ire ego\"
\ - Rite of Enlightenment: \"certum nahlizet ego\"
\ - Rite of Tribute: \"veri nahlizet certum\"
\ - Rite of Knowledge: \"karazet nahlizet ego\"
\ -


"*/ + have many different names, and almost all of them are known as Rites. Each follower of the Geometer is only able to use a subset of these, thus you must go forth and meet your fellow followers. \ + A small description of each rune can be found below.

A rune's name and effects can be revealed by examining the rune.


" text += "Teleport
The Rite of Translocation is a unique rite in that it requires a keyword before the scribing can begin. When invoked, the rune will \ search for other Rites of Translocation with the same keyword. Assuming one is found, the user will be instantaneously transported to the location of the other rune. If more than two runes are scribed \ @@ -141,13 +101,6 @@ It also contains rune words, which are soon to be removed. text += "Teleport Other
The Rite of Forced Translocation, like the Rite of Translocation, works by teleporting the person on the rune to one of the \ same keyword. However, this rune will only work on people other than the user, allowing the user to send any living creature somewhere else.

" - text += "Summon Tome
The Rite of Knowledge is a simplistic rune. When invoked, it will summon a single arcane tome to the rune's location before vanishing. \ -

" - - text += "Convert
The Rite of Enlightment is paramount to the success of the cult. It will allow you to convert normal crew members into cultists. \ - To do this, simply place the crew member upon the rune and invoke it. This rune requires two acolytes to use. If the target to be converted is loyalty-implanted or a certain assignment, they will \ - be unable to be converted. People the Geometer wishes sacrificed will also be ineligible for conversion, and anyone with a shielding presence like the null rod will not be converted.

" - text += "Sacrifice
The Rite of Tribute is used to offer sacrifice to the Geometer. Simply place any living creature upon the rune and invoke it (this will not \ target cultists!). If this creature has a mind, a soul shard will be created and the creature's soul transported to it. This rune is required if the cult's objectives include the sacrifice of a crew \ member.

" @@ -157,14 +110,7 @@ It also contains rune words, which are soon to be removed. within a few seconds, they will be brought back to life, healed of all ailments.

" text += "Veil Runes
The Rite of Obscurity is a rite that will cause all nearby runes to become invisible. The runes will still be considered by other rites \ - (such as the Rite of Translocation) but will be unusuable directly.

" - - text += "Reveal Runes
The Rite of True Sight is the foil of the Rite of Obscurity. It will turn all invisible runes visible once more, in addition to causing \ - all spirits nearby to become visible.

" - - text += "Disguise Runes
Many crewmen enjoy drawing runes in crayon that resemble spell circles in order to play pranks on their fellow crewmen. The Rite of \ - False Truths takes advantage of this very joke. When invoked, all nearby runes will appear dull, precisely resembling those drawn in crayon. They still cannot be cleaned by conventional means, so \ - anyone trying to clean up the rune may become suspicious as it does not respond.

" + (such as the Rite of Translocation) but will be unusuable directly. Use the same rite once more to reveal these runes once more.

" text += "Electromagnetic Disruption
Robotic lifeforms have time and time again been the downfall of fledgling cults. The Rite of Disruption may allow you to gain the upper \ hand against these pests. By using the rune, a large electromagnetic pulse will be emitted from the rune's location.

" @@ -178,14 +124,11 @@ It also contains rune words, which are soon to be removed. rune will draw a small amount of life force from the user and make the space above the rune completely dense, rendering it impassable to all but the most complex means. The rune may be invoked again to \ undo this effect and allow passage again.

" - text += "Deafen
The Rite of the Unheard Whisper is simple. When invoked, it will cause all non-cultists within a radius of seven tiles to become \ - completely deaf for a large amount of time.

" + text += "Debilitate
The Rite of the Shadowed Mind is simple. When invoked, it will cause all non-cultists that can see its rune to become deaf, blind and mute for a \ + considerable amount of time.

" - text += "Blind
Much like the Rite of the Unheard Whisper, the Rite of the Unseen Glance serves a single purpose. Any non-cultists who can see \ - the rune will instantly be blinded for a substantial amount of time.

" - - text += "Stun
Though the Rite of Blazing Light is weak when invoked normally, using it in conjuction with the Rite of Binding makes it much more useful. \ - This rune will cause any non-cultists that can see the rune to become disoriented, disabling them for a short time.

" + text += "Stun
Though the Rite of Blazing Light is weak when invoked normally, merely disorienting and disabling nearby non-cultists, non-cultists that step on the rune \ + will be stunned without expending its power. However, the disorientation caused by this rune is quite brief, and when invoked directly, it will not remain for further invocation.

" text += "Summon Cultist
The Rite of Joined Souls requires two acolytes to use. When invoked, it will allow the user to summon a single cultist to the rune from \ any location. This will deal a moderate amount of damage to all invokers.

" @@ -204,15 +147,18 @@ It also contains rune words, which are soon to be removed. text += "Blood Boil
The Rite of Boiling Blood may be considered one of the most dangerous rites composed by the cult of Nar-Sie. When invoked, it will do a \ massive amount of damage to all non-cultist viewers, but it will also emit an explosion upon invocation. Use with caution

" + text += "Immolate
The Rite of the Cleansing Flame is a weaker offensive rite, fit to be used by a lone cultist. When its rune is invoked, it will set any non-cultists \ + that can see it on fire. However, it will also burn its user.

" + + text += "Time Stop
The Rite of Dimensional Corruption is a versatile rite that can be very strong when protecting our cult from the enemies of the Geometer. \ + As it is invoked, it will rend and reshape reality around itself, stopping time for all those who don't follow the teachings of the Geometer. However, it requires more than one ritual soul as a \ + catalyst, and its power is bound to overflow and hurt its casters.

" + text += "Manifest Spirit
If you wish to bring a spirit back from the dead with a wish for vengeance and desire to serve, the Rite of Spectral \ Manifestation can do just that. When invoked, any spirits above the rune will be brought to life as a human wearing nothing that seeks only to serve you and the Geometer. However, the spirit's link \ to reality is fragile - you must remain on top of the rune, and you will slowly take damage. Upon stepping off the rune, the spirits will dissipate, dropping their items to the ground. You may manifest \ multiple spirits with one rune, but you will rapidly take damage in doing so.

" - text += "Call Forth The Geometer
There is only one way to summon the avatar of Nar-Sie, and that is the Ritual of Dimensional Rending. This ritual, in \ - comparison to other runes, is very large, requiring a 3x3 space of empty tiles to create. To invoke the rune, nine cultists must stand on the rune, so that all of them are within its circle. Then, \ - simply invoke it. A brief tearing will be heard as the barrier between dimensions is torn open, and the avatar will come forth.


" - text += "While runes are excellent for many tasks, they lack portability. The advent of talismans has, to a degree, solved this inconvenience. Simply put, a talisman is a piece of paper with a \ rune inlaid within it. The words of the rune can be whispered in order to invoke its effects, although usually to a lesser extent. To create a talisman, simply use a Rite of Binding as described above. \ Unless stated otherwise, talismans are invoked by activating them in your hand. A list of valid rites, as well as the effects of their talisman form, can be found below.


" @@ -220,17 +166,11 @@ It also contains rune words, which are soon to be removed. text += "Talisman of Teleportation
The talisman form of the Rite of Translocation will transport the invoker to a randomly chosen rune of the same keyword, then \ disappear.

" - text += "Talisman of Tome Summoning
This talisman functions nearly identically to the rune. The talisman will attempt to place the tome in your hand \ - instead of on the ground, though this is the only advantage it has over the rune. It can be used once, then disappears.

" - - text += "Talismans of Veiling, Revealing, and Disguising
These talismans all function identically to their rune counterparts, but with less range. In addition, \ - the Talisman of True Sight will not reveal spirits. They will disappear after one use.

" + text += "Talismans of Veiling
This talisman functions identically to its rune counterpart.It will disappear after one use.

" text += "Talisman of Electromagnetic Pulse
This talisman functions like the Rite of Disruption. It disappears after one use.

" - text += "Talisman of Stunning
Without this talisman, the cult would have no way of easily acquiring targets to convert. Commonly called \"stunpapers\", this \ - talisman functions differently from others. Rather than simply reading the words, the target must be attacked directly with the talisman. The talisman will then knock down the target for a long \ - duration in addition to rendering them incapable of speech. Robotic lifeforms will suffer the effects of a heavy electromagnetic pulse instead." + text += "Talisman of Immolation
This talisman functions exactly like the Rite of Cleansing Flame. It can only be used once.

" var/datum/browser/popup = new(user, "tome", "", 800, 600) popup.set_content(text) @@ -242,10 +182,10 @@ It also contains rune words, which are soon to be removed. var/rune_to_scribe var/entered_rune_name var/list/possible_runes = list() - for(var/T in subtypesof(/obj/effect/rune) - /obj/effect/rune/malformed) + for(var/T in known_runes) var/obj/effect/rune/R = T if(initial(R.cultist_name)) - possible_runes.Add(initial(R.cultist_name)) //This is to allow the menu to let cultists select runes by name rather than by object path. I don't know a better way to do this + possible_runes += initial(R.cultist_name) //This is to allow the menu to let cultists select runes by name rather than by object path. I don't know a better way to do this if(!possible_runes.len) return entered_rune_name = input(user, "Choose a rite to scribe.", "Sigils of Power") as null|anything in possible_runes diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 9be02034637..6ecc6a696c3 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -1,6 +1,3 @@ -var/list/sacrificed = list() -var/list/non_revealed_runes = (subtypesof(/obj/effect/rune) - /obj/effect/rune/malformed) - /* This file contains runes. @@ -9,18 +6,7 @@ They are drawn with an arcane tome in blood, and are distinguishable to cultists Fake runes can be drawn in crayon to fool people. Runes can either be invoked by one's self or with many different cultists. Each rune has a specific incantation that the cultists will say when invoking it. -To draw a rune, use an arcane tome and enter the words required. These words are in the tongue of the Geometer and must be entered as such. -Word definitions: -"ire" is Travel -"ego" is Self -"nahlizet" is Blood -"certum" is Join -"veri" is Hell -"jatkaa" is Other -"mgar" is Destroy -"balaq" is Technology -"karazet" is See -"geeri" is Hide +To draw a rune, use an arcane tome. */ @@ -38,7 +24,6 @@ Word definitions: mouse_opacity = 2 var/invocation = "Aiy ele-mayo!" //This is said by cultists when the rune is invoked. - var/grammar //This is only framework at the moment, but may be required to draw runes in the future var/req_cultists = 1 //The amount of cultists required around the rune to invoke it. If only 1, any cultist can invoke it. var/rune_in_use = 0 // Used for some runes, this is for when you want a rune to not be usable when in use. @@ -55,7 +40,6 @@ Word definitions: if(iscultist(user) || user.stat == DEAD) //If they're a cultist or a ghost, tell them the effects user << "Name: [cultist_name]" user << "Effects: [cultist_desc]" - //user << "Words: [grammar]" user << "Required Acolytes: [req_cultists]" if(req_keyword && keyword) user << "Keyword: [keyword]" @@ -77,6 +61,9 @@ Word definitions: return if(can_invoke(user)) invoke(user) + var/oldtransform = transform + animate(src, transform = matrix()*2, alpha = 0, time = 5) //fade out + animate(transform = oldtransform, alpha = 255, time = 0) else fail_invoke(user) @@ -151,7 +138,6 @@ structure_check() searches for nearby cultist structures required for the invoca cultist_name = "malformed rune" cultist_desc = "A senseless rune written in gibberish. No good can come from invoking this." invocation = "Ra'sha yoka!" - grammar = "N/A" /obj/effect/rune/malformed/New() ..() @@ -177,7 +163,6 @@ var/list/teleport_runes = list() invocation = "Sas'so c'arta forbici!" icon_state = "2" color = rgb(0, 0, 255) - grammar = "ire ego" req_keyword = 1 /obj/effect/rune/teleport/New() @@ -216,7 +201,6 @@ var/list/teleport_other_runes = list() invocation = "Sas'so c'arta forbica!" icon_state = "1" color = rgb(200, 0, 0) - grammar = "ire jatkaa" req_keyword = 1 /obj/effect/rune/teleport_other/New() @@ -264,62 +248,6 @@ var/list/teleport_other_runes = list() "Your vision blurs, and you suddenly appear somewhere else.") target.forceMove(get_turf(selected_rune)) - -//Rite of Knowledge: Creates an arcane tome at the rune's location and destroys the rune. -/obj/effect/rune/summon_tome - cultist_name = "Summon Tome" - cultist_desc = "Pulls an arcane tome from the archives of the Geometer." - invocation = "N'ath reth sh'yro eth d'raggathnor!" - icon_state = "5" - color = rgb(0, 0, 255) - grammar = "karazet nahlizet ego" - -/obj/effect/rune/summon_tome/invoke(mob/living/user) - visible_message("A frayed tome materializes on the surface of [src], which dissolves into nothing.") - new /obj/item/weapon/tome(get_turf(src)) - qdel(src) - - -//Rite of Enlightenment: Converts a normal crewmember to the cult. Faster for every cultist nearby. -/obj/effect/rune/convert - cultist_name = "Convert" - cultist_desc = "Converts a normal crewmember on top of it to the cult. Does not work on loyalty-implanted crew." - invocation = "Mah'weyh pleggh at e'ntrath!" - icon_state = "3" - color = rgb(255, 0, 0) - grammar = "certum nahlizet ego" - req_cultists = 2 - -/obj/effect/rune/convert/invoke(mob/living/user) - var/list/convertees = list() - var/turf/T = get_turf(src) - for(var/mob/living/M in T.contents) - if(!iscultist(M) && !isloyal(M)) - convertees.Add(M) - if(!convertees.len) - fail_invoke() - log_game("Convert rune failed - no eligible convertees") - return - var/mob/living/new_cultist = pick(convertees) - if(!is_convertable_to_cult(new_cultist.mind) || new_cultist.null_rod_check()) - user << "Something is shielding [new_cultist]'s mind!" - fail_invoke() - log_game("Convert rune failed - convertee could not be converted") - if(is_sacrifice_target(new_cultist.mind)) - for(var/mob/living/M in orange(1,src)) - if(iscultist(M)) - M << "\"I desire this one for myself. SACRIFICE THEM!\"" - return - new_cultist.visible_message("[new_cultist] writhes in pain as the markings below them glow a bloody red!", \ - "AAAAAAAAAAAAAA-") - ticker.mode.add_cultist(new_cultist.mind) - new_cultist.mind.special_role = "Cultist" - new_cultist << "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 something evil takes root." - new_cultist << "Assist your new compatriots in their dark dealings. Your goal is theirs, and theirs is yours. You serve the Geometer above all else. Bring it back.\ - " - - //Rite of Tribute: Sacrifices a crew member to Nar-Sie. Places them into a soul shard if they're in their body. /obj/effect/rune/sacrifice cultist_name = "Sacrifice" @@ -327,7 +255,6 @@ var/list/teleport_other_runes = list() icon_state = "3" invocation = "Barhah hra zar'garis!" color = rgb(255, 255, 255) - grammar = "veri nahlizet certum" rune_in_use = 0 /obj/effect/rune/sacrifice/New() @@ -357,13 +284,13 @@ var/list/teleport_other_runes = list() fail_invoke() rune_in_use = 0 return - if(((ishuman(offering) || isrobot(offering)) && offering.stat != DEAD) || is_sacrifice_target(offering.mind)) //Requires three people to sacrifice living targets or the round's target + if(((ishuman(offering) || isrobot(offering)) && offering.stat != DEAD)) //Requires two people to sacrifice living targets var/cultists_nearby = 1 - for(var/mob/living/M in orange(1,src)) + for(var/mob/living/M in range(1,src)) if(iscultist(M) && M != user) cultists_nearby++ M.say(invocation) - if(cultists_nearby < 3) + if(cultists_nearby < 2) user << "[offering] is too greatly linked to the world! You need more acolytes!" fail_invoke() log_game("Sacrifice rune failed - not enough acolytes and target is living") @@ -376,29 +303,17 @@ var/list/teleport_other_runes = list() sac(offering) /obj/effect/rune/sacrifice/proc/sac(mob/living/T) - var/sacrifice_fulfilled if(T) - if(istype(T, /mob/living/simple_animal/pet/dog)) - for(var/mob/living/carbon/C in range(3,src)) - if(iscultist(C)) - C << "\"Even I have standards, such as they are!\"" - if(C.reagents) - C.reagents.add_reagent("hell_water", 2) - if(T.mind) - sacrificed.Add(T.mind) - if(is_sacrifice_target(T.mind)) - sacrifice_fulfilled = 1 PoolOrNew(/obj/effect/overlay/temp/cult/sac, src.loc) for(var/mob/living/M in range(3,src)) if(iscultist(M)) - if(sacrifice_fulfilled) - M << "\"Yes! This is the one I desire! You have done well.\"" + if(ishuman(T) || isrobot(T)) + M << "\"I accept this sacrifice.\"" else - if(ishuman(T) || isrobot(T)) - M << "\"I accept this sacrifice.\"" - else - M << "\"I accept this meager sacrifice.\"" + M << "\"I accept this meager sacrifice.\"" if(T.mind) + if(ishuman(T) || isrobot(T)) + new /obj/item/summoning_orb(get_turf(src)) var/obj/item/device/soulstone/stone = new /obj/item/device/soulstone(get_turf(src)) stone.invisibility = INVISIBILITY_MAXIMUM //so it's not picked up during transfer_soul() if(!stone.transfer_soul("FORCE", T, usr)) //If it cannot be added @@ -417,65 +332,6 @@ var/list/teleport_other_runes = list() rune_in_use = 0 -//Ritual of Dimensional Rending: Calls forth the avatar of Nar-Sie upon the station. -/obj/effect/rune/narsie - cultist_name = "Call Forth The Geometer" - cultist_desc = "Tears apart dimensional barriers, calling forth the avatar of the Geometer." - invocation = null - req_cultists = 9 - icon = 'icons/effects/96x96.dmi' - icon_state = "rune_large" - pixel_x = -32 //So the big ol' 96x96 sprite shows up right - pixel_y = -32 - grammar = "veri certum ego" - var/used - -/obj/effect/rune/narsie/invoke(mob/living/user) - if(used) - return - if(ticker.mode.name == "cult") - var/datum/game_mode/cult/cult_mode = ticker.mode - if(!("eldergod" in cult_mode.cult_objectives)) - message_admins("[usr.real_name]([user.ckey]) tried to summon Nar-Sie when the objective was wrong") - for(var/mob/living/M in range(1,src)) - if(iscultist(M)) - M << "\"YOUR SOUL BURNS WITH YOUR ARROGANCE!!!\"" - if(M.reagents) - M.reagents.add_reagent("hell_water", 10) - M.Weaken(5) - fail_invoke() - log_game("Summon Nar-Sie rune failed - improper objective") - return - else - if(cult_mode.sacrifice_target && !(cult_mode.sacrifice_target in sacrificed)) - for(var/mob/living/M in orange(1,src)) - if(iscultist(M)) - M << "The sacrifice is not complete. The portal lacks the power to open!" - fail_invoke() - log_game("Summon Nar-Sie rune failed - sacrifice not complete") - return - if(!cult_mode.eldergod) - for(var/mob/living/M in range(1,src)) - if(iscultist(M)) - M << "The avatar of Nar-Sie is already on this plane!" - log_game("Summon Nar-Sie rune failed - already summoned") - return - //BEGIN THE SUMMONING - used = 1 - for(var/mob/living/M in range(1,src)) - if(iscultist(M)) - M.say("TOK-LYR RQA-NAP G'OLT-ULOFT!!") - world << 'sound/effects/dimensional_rend.ogg' - world << "Rip... Rrrip... RRRRRRRRRR--" - sleep(40) - new /obj/singularity/narsie/large(get_turf(user)) //Causes Nar-Sie to spawn even if the rune has been removed - cult_mode.eldergod = 0 - else - fail_invoke() - log_game("Summon Nar-Sie rune failed - gametype is not cult") - return - - //Rite of Resurrection: Requires two corpses. Revives one and gibs the other. /obj/effect/rune/raise_dead cultist_name = "Raise Dead" @@ -483,7 +339,6 @@ var/list/teleport_other_runes = list() invocation = null //Depends on the name of the user - see below icon_state = "1" color = rgb(255, 0, 0) - grammar = "nahlizet certum veri" /obj/effect/rune/raise_dead/invoke(mob/living/user) var/turf/T = get_turf(src) @@ -540,9 +395,9 @@ var/list/teleport_other_runes = list() mob_to_sacrifice.visible_message("[mob_to_sacrifice]'s body rises into the air, connected to [mob_to_revive] by a glowing tendril!") mob_to_revive.Beam(mob_to_sacrifice,icon_state="sendbeam",icon='icons/effects/effects.dmi',time=20) sleep(20) - if(mob_to_sacrifice) //sighing noise - mob_to_sacrifice.visible_message("[mob_to_sacrifice] disintegrates into a pile of bones[mob_to_revive ? ", the glowing tendril sinking into [mob_to_revive]'s body":""].") + if(!mob_to_sacrifice || !in_range(mob_to_sacrifice, src)) return + mob_to_sacrifice.visible_message("[mob_to_sacrifice] disintegrates into a pile of bones[mob_to_revive ? ", the glowing tendril sinking into [mob_to_revive]'s body":""].") mob_to_sacrifice.dust() if(!mob_to_revive || mob_to_revive.stat != DEAD) visible_message("The glowing tendril snaps against the rune with a shocking crack.") @@ -561,63 +416,27 @@ var/list/teleport_other_runes = list() M.visible_message("[M] twitches.") -//Rite of Obscurity: Turns all runes within a 3-tile radius invisible. +//Rite of Obscurity: Turns all runes within a 3-tile radius invisible or reveals them again. /obj/effect/rune/hide_runes cultist_name = "Veil Runes" - cultist_desc = "Turns nearby runes invisible. They can be revealed by using the Reveal Runes rune." + cultist_desc = "Turns nearby runes invisible. They can be revealed by using this rune again." invocation = "Kla'atu barada nikt'o!" icon_state = "1" color = rgb(0,0,255) - grammar = "geeri karazet nahlizet" /obj/effect/rune/hide_runes/invoke(mob/living/user) visible_message("[src] darkens to black and vanishes.") for(var/obj/effect/rune/R in orange(3,src)) - R.visible_message("[R] fades away.") - R.invisibility = INVISIBILITY_OBSERVER - R.alpha = 100 //To help ghosts distinguish hidden runes - for(var/mob/dead/observer/O in orange(3,src)) - if(!O.invisibility) - O << "You suddenly feel as if you've vanished..." - O.invisibility = INVISIBILITY_OBSERVER + if(R.invisibility == INVISIBILITY_OBSERVER) + R.invisibility = 0 + R.alpha = initial(R.alpha) + else + R.visible_message("[R] fades away.") + R.invisibility = INVISIBILITY_OBSERVER + R.alpha = 100 //To help ghosts distinguish hidden runes qdel(src) -//Rite of True Sight: Turns ghosts and obscured runes visible -/obj/effect/rune/true_sight - cultist_name = "Reveal Runes" - cultist_desc = "Reveals all invisible objects nearby, from spirits to runes." - invocation = "Nikt'o barada kla'atu!" - icon_state = "4" - color = rgb(255, 255, 255) - grammar = "karazet geeri nahlizet" - -/obj/effect/rune/true_sight/invoke() - visible_message("[src] explodes in a flash of blinding light!") - for(var/mob/dead/observer/O in orange(3,src)) - O << "You suddenly feel very obvious..." - O.invisibility = 0 - for(var/obj/effect/rune/R in orange(3,src)) - R.invisibility = 0 - R.alpha = initial(R.alpha) - qdel(src) - - -//Rite of False Truths: Makes runes appear like crayon ones -/obj/effect/rune/make_runes_fake - cultist_name = "Disguise Runes" - cultist_desc = "Causes all nearby runes (including itself) to resemble those drawn in crayon." - invocation = "By'o isit!" - icon_state = "4" - color = rgb(0, 150, 0) - grammar = "geeri nahlizet jatkaa" - -/obj/effect/rune/make_runes_fake/invoke(mob/living/user) - visible_message("[src] flares brightly, then slowly dulls and appears mundane.") - for(var/obj/effect/rune/R in range(3,src)) - R.desc = "A rune drawn in crayon." - - //Rite of Disruption: Emits an EMP blast. /obj/effect/rune/emp cultist_name = "Electromagnetic Disruption" @@ -625,7 +444,6 @@ var/list/teleport_other_runes = list() invocation = "Ta'gh fara'qha fel d'amar det!" icon_state = "5" color = rgb(255, 0, 0) - grammar = "mgar karazet balaq" /obj/effect/rune/emp/invoke(mob/living/user) visible_message("[src] glows blue for a moment before vanishing.") @@ -645,7 +463,6 @@ var/list/teleport_other_runes = list() color = rgb(126, 23, 23) rune_in_use = 0 //One at a time, please! var/mob/living/affecting = null - grammar = "veri ire ego" /obj/effect/rune/astral/examine(mob/user) ..() @@ -713,7 +530,6 @@ var/list/teleport_other_runes = list() invocation = "Khari'd! Eske'te tannin!" icon_state = "1" color = rgb(255, 0, 0) - grammar = "mgar ire ego" /obj/effect/rune/wall/examine(mob/user) ..() @@ -729,73 +545,62 @@ var/list/teleport_other_runes = list() C.apply_damage(2, BRUTE, pick("l_arm", "r_arm")) -//Rite of the Unheard Whisper: Deafens all non-cultists nearby. +//Rite of the Shadowed Mind: Deafens, blinds and mutes all non-cultists nearby. /obj/effect/rune/deafen - cultist_name = "Deafen" - cultist_desc = "Causes all non-followers nearby to lose their hearing." + cultist_name = "Debilitate" + cultist_desc = "Causes all non-followers nearby to lose their hearing, sight and voice." invocation = "Sti kaliedir!" - grammar = "geeri jatkaa karazet" color = rgb(0, 255, 0) icon_state = "4" /obj/effect/rune/deafen/invoke(mob/living/user) - visible_message("[src] blurs for a moment before fading away.") - for(var/mob/living/carbon/C in range(7,src)) - if(!iscultist(C) && !C.null_rod_check()) - C << "The world around you goes quiet." - C.adjustEarDamage(0,50) - qdel(src) - - -//Rite of the Unseen Glance: Blinds all non-cultists nearby. -/obj/effect/rune/blind - cultist_name = "Blind" - cultist_desc = "Causes all non-followers nearby to lose their sight." - invocation = "Sti kaliesin!" - icon_state = "4" - color = rgb(0, 0, 255) - grammar = "mgar jatkaa karazet" - -/obj/effect/rune/blind/invoke(mob/living/user) visible_message("[src] emits a blinding red flash!") for(var/mob/living/carbon/C in viewers(src)) if(!iscultist(C) && !C.null_rod_check()) - C << "You can't see!" + C << "You feel oily shadows cover your senses." + C.adjustEarDamage(0,50) C.flash_eyes(1, 1) C.eye_blurry += 50 C.eye_blind += 20 + C.silent += 10 qdel(src) - -//Rite of Disorientation: Stuns all non-cultists nearby for a brief time +//Rite of Disorientation: Stuns and mutes all non-cultists nearby for a brief time /obj/effect/rune/stun cultist_name = "Stun" - cultist_desc = "Stuns all nearby non-followers for a brief time." + cultist_desc = "Stuns and mutes all nearby non-followers for a brief time." invocation = "Fuu ma'jin!" icon_state = "2" color = rgb(100, 0, 100) - grammar = "certum geeri balaq" /obj/effect/rune/stun/invoke(mob/living/user) visible_message("[src] explodes in a bright flash!") for(var/mob/living/M in viewers(src)) - if(!iscultist(M) && !M.null_rod_check()) - M << "You are disoriented by [src]!" - M.Weaken(3) - M.Stun(3) - M.flash_eyes(1,1) + stun_he(M) qdel(src) +/obj/effect/rune/stun/Crossed(atom/movable/AM) + ..() + if(isliving(AM)) + stun_he(AM) -//Rite of Joined Souls: Summons a single cultist. Requires 2 cultists. +/obj/effect/rune/stun/proc/stun_he(mob/living/M) + if(!iscultist(M) && !M.null_rod_check()) + M << "You are disoriented by [src]!" + M.Weaken(3) + M.Stun(3) + M.flash_eyes(1,1) + if(iscarbon(M)) + var/mob/living/carbon/C = M + C.silent += 3 + +//Rite of Joined Souls: Summons a single cultist. /obj/effect/rune/summon cultist_name = "Summon Cultist" cultist_desc = "Summons a single cultist to the rune." invocation = "N'ath reth sh'yro eth d'rekkathnor!" - req_cultists = 2 icon_state = "5" color = rgb(0, 255, 0) - grammar = "certum jatkaa ego" /obj/effect/rune/summon/invoke(mob/living/user) var/list/cultists = list() @@ -817,9 +622,7 @@ var/list/teleport_other_runes = list() cultist_to_summon.visible_message("[cultist_to_summon] suddenly disappears in a flash of red light!", \ "Overwhelming vertigo consumes you as you are hurled through the air!") visible_message("A foggy shape materializes atop [src] and solidifes into [cultist_to_summon]!") - for(var/mob/living/carbon/C in orange(1,src)) - if(iscultist(C)) - C.apply_damage(10, BRUTE, "head") + user.apply_damage(10, BRUTE, "head") cultist_to_summon.loc = get_turf(src) qdel(src) @@ -831,7 +634,6 @@ var/list/teleport_other_runes = list() invocation = null //no talisman made, no invocation. icon_state = "3" color = rgb(0, 0, 255) - grammar = "veri balaq certum" /obj/effect/rune/imbue/invoke(mob/living/user) var/turf/T = get_turf(src) @@ -881,7 +683,6 @@ var/list/teleport_other_runes = list() invocation = null //see below; doesn't say the invocation unless there's enough sheets. icon_state = "5" color = rgb(150, 150, 150) - grammar = "ire veri balaq" /obj/effect/rune/construct_shell/invoke(mob/living/user) var/turf/T = get_turf(src) @@ -911,7 +712,6 @@ var/list/teleport_other_runes = list() invocation = "N'ath reth sh'yro eth draggathnor!" icon_state = "4" color = rgb(255, 0, 0) - grammar = "veri mgar jatkaa" /obj/effect/rune/armor/invoke(mob/living/user) visible_message("With the sound of clanging metal, [src] crumbles to dust!") @@ -930,7 +730,6 @@ var/list/teleport_other_runes = list() invocation = null //see below; doesn't say the invocation if it has no targets. icon_state = "2" color = rgb(255, 0, 0) - grammar = "ire nahlizet ego" /obj/effect/rune/leeching/invoke(mob/living/user) var/turf/T = get_turf(src) @@ -961,8 +760,7 @@ var/list/teleport_other_runes = list() invocation = "Dedo ol'btoh!" icon_state = "4" color = rgb(255, 0, 0) - req_cultists = 3 - grammar = "mgar karazet nahlizet" + req_cultists = 2 /obj/effect/rune/blood_boil/invoke(mob/living/user) visible_message("[src] briefly bubbles before exploding!") @@ -973,7 +771,7 @@ var/list/teleport_other_runes = list() continue C << "Your blood boils in your veins!" C.take_overall_damage(51,51) - for(var/mob/living/carbon/M in orange(1,src)) + for(var/mob/living/carbon/M in range(1,src)) if(iscultist(M)) M.apply_damage(15, BRUTE, pick("l_arm", "r_arm")) M << "[src] saps your strength!" @@ -981,6 +779,27 @@ var/list/teleport_other_runes = list() qdel(src) +//Rite of the Cleansing Flame: Sets all non-cultists on fire. +/obj/effect/rune/flame + cultist_name = "Immolate" + cultist_desc = "Sets any non-believers who can see the rune on fire." + invocation = "Dedo va'batoh!" + icon_state = "2" + color = rgb(255, 0, 0) + +/obj/effect/rune/flame/invoke(mob/living/user) + visible_message("[src] burns away, scorching the floor below!") + for(var/mob/living/carbon/C in viewers(src)) + if(!iscultist(C) && !C.null_rod_check()) + C << "You feel your skin crisp as you burst into flames!" + C.fire_act() + user.apply_damage(15, BURN, pick("l_arm", "r_arm")) + user << "[src] burns your arms!" + var/turf/simulated/T = get_turf(src) + T.burn_tile() + qdel(src) + + //Rite of Spectral Manifestation: Summons a ghost on top of the rune as a cultist human with no items. User must stand on the rune at all times, and takes damage for each summoned ghost. /obj/effect/rune/manifest cultist_name = "Manifest Spirit" @@ -988,7 +807,6 @@ var/list/teleport_other_runes = list() invocation = "Gal'h'rfikk harfrandid mud'gib!" //how the fuck do you pronounce this icon_state = "6" color = rgb(255, 0, 0) - grammar = "nahlizet karazet ire" /obj/effect/rune/manifest/invoke(mob/living/user) if(!(user in get_turf(src))) @@ -1027,3 +845,40 @@ var/list/teleport_other_runes = list() for(var/obj/I in new_human) new_human.unEquip(I) new_human.dust() + +//Rite of Dimensional Corruption: Stops time around the rune for all non-cultists. +/obj/effect/rune/timestop + cultist_name = "Time Stop" + cultist_desc = "Stops time around the rune for all non-cultists." + invocation = "T'ak ot'marzah oahr'du!" + icon_state = "2" + color = rgb(0, 0, 255) + req_cultists = 2 + +/obj/effect/rune/timestop/invoke(mob/living/user) + visible_message("[src] flares up for a moment, and then disappears into itself!") + new /obj/effect/timestop/cult(get_turf(src)) + for(var/mob/living/carbon/M in range(1,src)) + if(iscultist(M)) + M.apply_damage(20, BRUTE, "chest") + M << "[src] temporarily stops your heart from beating!" + qdel(src) + +/obj/effect/timestop/cult + name = "Dimensional Corruption" + desc = "Something not from this world has corrupted the spacetime continuum in this exact spot." + icon = 'icons/effects/96x96.dmi' + icon_state = "rune_large" + pixel_x = -32 + pixel_y = -32 + duration = 50 + alpha = 0 + color = rgb(255, 0, 0) + +/obj/effect/timestop/cult/timestop() + animate(src, alpha = 255, time = 5, loop = -1) + SpinAnimation(speed = 5) + for(var/mob/living/M in player_list) + if(iscultist(M) || M.null_rod_check()) + immune |= M + ..() diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm index e92cf3fd43e..ed9b106e3ce 100644 --- a/code/game/gamemodes/cult/talisman.dm +++ b/code/game/gamemodes/cult/talisman.dm @@ -26,8 +26,8 @@ Rite of Disorientation user << "Name: [cultist_name]" user << "Effect: [cultist_desc]" user << "Uses Remaining: [uses]" - return - ..() + else + user << "There are indecipherable images scrawled on the paper in what looks to be... blood?" /obj/item/weapon/paper/talisman/attack_self(mob/living/user) if(!iscultist(user)) @@ -70,12 +70,11 @@ Rite of Disorientation var/dat = "There are [uses] bloody runes on the parchment.
" dat += "Please choose the chant to be imbued into the fabric of reality.
" dat += "
" - dat += "N'ath reth sh'yro eth d'raggathnor! - Allows you to summon an arcane tome.
" dat += "Sas'so c'arta forbici! - Allows you to move to a Rite of Dislocation with the keyword of \"veri\".
" dat += "Ta'gh fara'qha fel d'amar det! - Allows you to destroy technology in a short range.
" - dat += "Kla'atu barada nikt'o! - Allows you to conceal nearby runes.
" - dat += "Nikt'o barada kla'atu! - Allows you to reveal nearby runes.
" - dat += "Fuu ma'jin! - Allows you to stun a person by attacking them with the talisman.
" + dat += "Kla'atu barada nikt'o! - Allows you to conceal nearby runes, or reveal previously concealed runes.
" + dat += "Dedo va'batoh! - Allows you to set nearby non-believers on fire.
" + dat += "Barhah hra zar'garis! - A sacrifice rune appears under your feet, ready to be invoked in the name of Nar-sie.
" dat += "Kal'om neth! - Summons a soul stone, used to capure the spirits of dead or dying humans.
" dat += "Daa'ig osk! - Summons a construct shell for use with captured souls. It is too large to carry on your person.
" var/datum/browser/popup = new(user, "talisman", "", 400, 400) @@ -85,46 +84,37 @@ Rite of Disorientation return 1 /obj/item/weapon/paper/talisman/supply/Topic(href, href_list) - if(src) - if(usr.stat || usr.restrained() || !in_range(src, usr)) - return - if(href_list["rune"]) - switch(href_list["rune"]) - if("newtome") - var/obj/item/weapon/paper/talisman/summon_tome/T = new(usr) - usr.put_in_hands(T) - if("teleport") - var/obj/item/weapon/paper/talisman/teleport/T = new(usr) - T.keyword = "veri" - usr.put_in_hands(T) - if("emp") - var/obj/item/weapon/paper/talisman/emp/T = new(usr) - usr.put_in_hands(T) - if("conceal") - var/obj/item/weapon/paper/talisman/hide_runes/T = new(usr) - usr.put_in_hands(T) - if("reveal") - var/obj/item/weapon/paper/talisman/true_sight/T = new(usr) - usr.put_in_hands(T) - if("runestun") - var/obj/item/weapon/paper/talisman/stun/T = new(usr) - usr.put_in_hands(T) - if("soulstone") - var/obj/item/device/soulstone/T = new(usr) - usr.put_in_hands(T) - if("construct") - new /obj/structure/constructshell(get_turf(usr)) - src.uses-- - if(src.uses <= 0) - if(iscarbon(usr)) - var/mob/living/carbon/C = usr - C.drop_item() - visible_message("[src] crumbles to dust.") - qdel(src) + if(!src || usr.stat || usr.restrained() || !in_range(src, usr)) return - else - return - + if(href_list["rune"]) + switch(href_list["rune"]) + if("teleport") + var/obj/item/weapon/paper/talisman/teleport/T = new(usr) + T.keyword = "veri" + usr.put_in_hands(T) + if("emp") + var/obj/item/weapon/paper/talisman/emp/T = new(usr) + usr.put_in_hands(T) + if("conceal") + var/obj/item/weapon/paper/talisman/hide_runes/T = new(usr) + usr.put_in_hands(T) + if("flame") + var/obj/item/weapon/paper/talisman/flame/T = new(usr) + usr.put_in_hands(T) + if("sacrune") + new /obj/effect/rune/sacrifice(get_turf(usr)) + if("soulstone") + var/obj/item/device/soulstone/T = new(usr) + usr.put_in_hands(T) + if("construct") + new /obj/structure/constructshell(get_turf(usr)) + src.uses-- + if(src.uses <= 0) + if(iscarbon(usr)) + var/mob/living/carbon/C = usr + C.drop_item() + visible_message("[src] crumbles to dust.") + qdel(src) //Rite of Translocation: Same as rune /obj/item/weapon/paper/talisman/teleport @@ -162,65 +152,24 @@ Rite of Disorientation user << "Keyword: [keyword]" -//Rite of Knowledge: Same as rune, but has two uses -/obj/item/weapon/paper/talisman/summon_tome - cultist_name = "Talisman of Tome Summoning" - cultist_desc = "A one-use talisman that will call an untranslated tome from the archives of the Geometer." - invocation = "N'ath reth sh'yro eth d'raggathnor!" - health_cost = 1 - -/obj/item/weapon/paper/talisman/summon_tome/invoke(mob/living/user) - user.visible_message("[user]'s hand glows red for a moment.", \ - "You speak the words of the talisman!") - var/obj/item/weapon/tome/T = new(get_turf(user)) - if(user.put_in_hands(T)) - user.visible_message("A tome appears in [user]'s hand!", \ - "An arcane tome materializes in your free hand.") - else - user.visible_message("A tome appears at [user]'s feet!", \ - "An arcane tome materialzies at your feet.") - -//Rite of Obscurity: Same as rune, but less range +//Talisman of Obscurity: Same as rune /obj/item/weapon/paper/talisman/hide_runes cultist_name = "Talisman of Veiling" - cultist_desc = "A talisman that will make all runes within a small radius invisible." + cultist_desc = "A talisman that will make all runes within a small radius invisible, or make invisible runes visible again." invocation = "Kla'atu barada nikt'o!" health_cost = 1 /obj/item/weapon/paper/talisman/hide_runes/invoke(mob/living/user) user.visible_message("Dust flows from [user]'s hand.", \ "You speak the words of the talisman, veiling nearby runes.") - for(var/obj/effect/rune/R in orange(3,user)) - R.visible_message("[R] fades away.") - R.invisibility = INVISIBILITY_OBSERVER - - -//Rite of True Sight: Same as rune, but doesn't work on ghosts -/obj/item/weapon/paper/talisman/true_sight - cultist_name = "Talisman of Revealing" - cultist_desc = "A talisman that reveals nearby invisible runes." - invocation = "Nikt'o barada kla'atu!" - health_cost = 1 - -/obj/item/weapon/paper/talisman/true_sight/invoke(mob/living/user) - user.visible_message("A flash of light shines from [user]'s hand!", \ - "You speak the words of the talisman, revealing nearby runes.") - for(var/obj/effect/rune/R in orange(3,user)) - R.invisibility = 0 - - -//Rite of False Truths: Same as rune -/obj/item/weapon/paper/talisman/make_runes_fake - cultist_name = "Talisman of Disguising" - cultist_desc = "A talisman that will make nearby runes appear fake." - invocation = "By'o isit!" - health_cost = 3 - -/obj/item/weapon/paper/talisman/make_runes_fake/invoke(mob/living/user) - user.visible_message("Dust flows from [user]s hand.", \ - "You speak the words of the talisman, making nearby runes appear fake.") - for(var/obj/effect/rune/R in orange(3,user)) - R.desc = "A rune drawn in crayon." + for(var/obj/effect/rune/R in orange(3,src)) + if(R.invisibility == INVISIBILITY_OBSERVER) + R.invisibility = 0 + R.alpha = initial(R.alpha) + else + R.visible_message("[R] fades away.") + R.invisibility = INVISIBILITY_OBSERVER + R.alpha = 100 //To help ghosts distinguish hidden runes //Rite of Disruption: Same as rune @@ -236,42 +185,20 @@ Rite of Disorientation empulse(src, 4, 8) -//Rite of Disorientation: Stuns and mutes a single target for quite some time -/obj/item/weapon/paper/talisman/stun - cultist_name = "Talisman of Stunning" - cultist_desc = "A talisman that will stun and mute a single target. To use, attack target directly." - invocation = "Fuu ma'jin!" - health_cost = 10 //A lot of health because of how powerful this is +//Rite of the Cleansing Flame: Same as rune +/obj/item/weapon/paper/talisman/flame + cultist_name = "Talisman of Immolation" + cultist_desc = "A talisman that sets any non-believers who can see you on fire." + invocation = "Dedo va'batoh!" + health_cost = 10 -/obj/item/weapon/paper/talisman/stun/attack_self(mob/living/user) - if(iscultist(user)) - user << "To use this talisman, attack the target directly." - else - user << "There are indecipherable images scrawled on the paper in what looks to be... blood?" - -/obj/item/weapon/paper/talisman/stun/attack(mob/living/target, mob/living/user) - if(iscultist(user)) - user.whisper(invocation) - user.visible_message("[user] holds up [src], which explodes in a flash of red light!", \ - "You stun [target] with the talisman!") - var/obj/item/weapon/nullrod/N = locate() in target - if(N) - target.visible_message("[target]'s null rod absorbs the talisman's light!", \ - "Your null rod absorbs the blinding light!") - else - target.Weaken(10) - target.Stun(10) - target.flash_eyes(1,1) - if(issilicon(target)) - var/mob/living/silicon/S = target - S.emp_act(1) - if(iscarbon(target)) - var/mob/living/carbon/C = target - C.silent += 10 - user.drop_item() - qdel(src) - return - ..() +/obj/item/weapon/paper/talisman/flame/invoke(mob/living/user) + user.visible_message("\The [src] in [user]'s hand suddenly burns away in a red flash!", \ + "You speak the words of the talisman, setting your enemies on fire.") + for(var/mob/living/carbon/C in viewers(user)) + if(!iscultist(C) && !C.null_rod_check()) + C << "You feel your skin crisp as you burst into flames!" + C.fire_act() //Rite of Arming: Equips cultist armor on the user, where available diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index eee99d5d765..d6fd311404b 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -28,9 +28,12 @@ if(!istype(M, /mob/living/carbon/human))//If target is not a human. return ..() if(istype(M, /mob/living/carbon/human/dummy)) - return..() + return ..() add_logs(user, M, "captured [M.name]'s soul", src) + if(iscultist(user) && M && M.mind) + new /obj/item/summoning_orb(get_turf(M)) + transfer_soul("VICTIM", M, user) return @@ -104,7 +107,7 @@ /obj/item/device/soulstone/proc/transfer_soul(choice as text, target, mob/user). switch(choice) if("FORCE") - if(!iscarbon(target)) //TO-DO: Add sacrifice stoning for non-organics, just because you have no body doesnt mean you dont have a soul + if(!iscarbon(target)) //TODO: Add sacrifice stoning for non-organics, just because you have no body doesnt mean you dont have a soul return 0 if(contents.len) return 0 @@ -120,12 +123,6 @@ if("VICTIM") var/mob/living/carbon/human/T = target - if(ticker.mode.name == "cult" && T.mind == ticker.mode:sacrifice_target) - if(iscultist(user)) - user << "The Geometer of blood wants this mortal sacrificed with the rune." - else - user << "The soul stone doesn't work for no apparent reason." - return 0 if(imprinted != "empty") user << "Capture failed!: The soul stone has already been imprinted with [imprinted]'s mind!" else @@ -200,7 +197,7 @@ if(stoner && iswizard(stoner)) newstruct << "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs." else if(stoner && iscultist(stoner)) - newstruct << "You are still bound to serve the cult, follow their orders and help them complete their goals at all costs." + newstruct << "You are still bound to serve the cult, follow their orders and help them summon the Geometer at all costs." else newstruct << "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs." newstruct.cancel_camera() diff --git a/code/game/objects/items/weapons/storage/book.dm b/code/game/objects/items/weapons/storage/book.dm index e1b957259e4..a8d05a6c91b 100644 --- a/code/game/objects/items/weapons/storage/book.dm +++ b/code/game/objects/items/weapons/storage/book.dm @@ -146,17 +146,10 @@ var/global/list/bibleitemstates = list("bible", "koran", "scrapbook", "bible", " user.Paralyse(20) return -// if(..() == BLOCKED) -// return - if (M.stat !=2) if(M.mind && (M.mind.assigned_role == "Chaplain")) user << "You can't heal yourself!" return - /*if((M.mind in ticker.mode.cult) && (prob(20))) - M << "\red The power of [src.deity_name] clears your mind of heresy!" - user << "\red You see how [M]'s eyes become clear, the cult no longer holds control over him!" - ticker.mode.remove_cultist(M.mind)*/ if ((istype(M, /mob/living/carbon/human) && prob(60))) bless(M) if(ishuman(M)) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index e6dd19001ae..ec18cdd4bd2 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -310,97 +310,6 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that else alert("Invalid mob") -/* -/client/proc/cmd_admin_monkeyize(var/mob/M in world) - set category = "Fun" - set name = "Make Monkey" - - if(!ticker) - alert("Wait until the game starts") - return - if(istype(M, /mob/living/carbon/human)) - var/mob/living/carbon/human/target = M - log_admin("[key_name(src)] is attempting to monkeyize [M.key].") - spawn(10) - target.monkeyize() - else - alert("Invalid mob") - -/client/proc/cmd_admin_changelinginize(var/mob/M in world) - set category = "Fun" - set name = "Make Changeling" - - if(!ticker) - alert("Wait until the game starts") - return - if(istype(M, /mob/living/carbon/human)) - log_admin("[key_name(src)] has made [M.key] a changeling.") - spawn(10) - M.absorbed_dna[M.real_name] = M.dna - M.make_changeling() - if(M.mind) - M.mind.special_role = "Changeling" - else - alert("Invalid mob") -*/ -/* -/client/proc/cmd_admin_abominize(var/mob/M in world) - set category = null - set name = "Make Abomination" - - usr << "Ruby Mode disabled. Command aborted." - return - if(!ticker) - alert("Wait until the game starts.") - return - if(istype(M, /mob/living/carbon/human)) - log_admin("[key_name(src)] has made [M.key] an abomination.") - - // spawn(10) - // M.make_abomination() - -*/ -/* -/client/proc/make_cultist(var/mob/M in world) - set category = "Fun" - set name = "Make Cultist" - set desc = "Makes target a cultist" - if(!wordtravel) - runerandom() - if(M) - if(M.mind in ticker.mode.cult) - return - else - if(alert("Spawn that person a tome?",,"Yes","No")=="Yes") - M << "\red You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie. A tome, a message from your new master, appears on the ground." - new /obj/item/weapon/tome(M.loc) - else - M << "\red You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie." - var/glimpse=pick("1","2","3","4","5","6","7","8") - switch(glimpse) - if("1") - M << "\red You remembered one thing from the glimpse... [wordtravel] is travel..." - if("2") - M << "\red You remembered one thing from the glimpse... [wordblood] is blood..." - if("3") - M << "\red You remembered one thing from the glimpse... [wordjoin] is join..." - if("4") - M << "\red You remembered one thing from the glimpse... [wordhell] is Hell..." - if("5") - M << "\red You remembered one thing from the glimpse... [worddestr] is destroy..." - if("6") - M << "\red You remembered one thing from the glimpse... [wordtech] is technology..." - if("7") - M << "\red You remembered one thing from the glimpse... [wordself] is self..." - if("8") - M << "\red You remembered one thing from the glimpse... [wordsee] is see..." - - if(M.mind) - M.mind.special_role = "Cultist" - ticker.mode.cult += M.mind - src << "Made [M] a cultist." -*/ - var/list/TYPES_SHORTCUTS = list( /obj/effect/decal/cleanable = "CLEANABLE", /obj/item/device/radio/headset = "HEADSET", diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index c60bcca1fc3..be7c7f7c7cb 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -194,7 +194,6 @@ /datum/admins/proc/makeCult() - var/datum/game_mode/cult/temp = new if(config.protect_roles_from_antagonist) temp.restricted_jobs += temp.protected_jobs @@ -216,7 +215,7 @@ candidates += applicant if(candidates.len) - var/numCultists = min(candidates.len, 4) + var/numCultists = min(candidates.len, 5) for(var/i = 0, iThere are indecipherable images scrawled on the paper in what looks to be... blood?
" - return if(in_range(user, src) || isobserver(user)) if( !(ishuman(user) || isobserver(user) || issilicon(user)) ) user << browse("[name][stars(info)]
[stamps]", "window=[name]") diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index a7eb8fac14b..0c64d0d67d5 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -61,7 +61,7 @@ return /obj/singularity/narsie/proc/godsmack(atom/A) - if(istype(A,/obj/)) + if(isobj(A)) var/obj/O = A O.ex_act(1) if(O) qdel(O) diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 6fe3f6f91b8..4a9fe63c99a 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -246,7 +246,7 @@ /obj/singularity/proc/consume(atom/A) - var/gain = A.singularity_act(current_size) + var/gain = A.singularity_act(current_size, src) src.energy += gain if(istype(A, /obj/machinery/power/supermatter_shard) && !consumedSupermatter) desc = "[initial(desc)] It glows fiercely with inner fire." diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 35b159a3aa6..2ea48e3d0cf 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -183,13 +183,10 @@ if (!M.stuttering) M.stuttering = 1 M.stuttering += 4 M.Dizzy(5) - if(iscultist(M) && prob(5)) - M.say(pick("Av'te Nar'sie","Pa'lid Mors","INO INO ORA ANA","SAT ANA!","Daim'niodeis Arc'iai Le'eones","Egkau'haom'nai en Chaous","Ho Diak'nos tou Ap'iron","R'ge Na'sie","Diabo us Vo'iscum","Si gn'um Co'nu")) if(data >= 75 && prob(33)) // 30 units, 135 seconds if (!M.confused) M.confused = 1 M.confused += 3 - if(iscultist(M) || (is_handofgod_cultist(M) && !is_handofgod_prophet(M))) - ticker.mode.remove_cultist(M.mind) + if((is_handofgod_cultist(M) && !is_handofgod_prophet(M))) ticker.mode.remove_hog_follower(M.mind) holder.remove_reagent(src.id, src.volume) // maybe this is a little too perfect and a max() cap on the statuses would be better?? M.jitteriness = 0 diff --git a/html/changelogs/Tkdrg-Cult-Overhaul.yml b/html/changelogs/Tkdrg-Cult-Overhaul.yml new file mode 100644 index 00000000000..bec05a6ed85 --- /dev/null +++ b/html/changelogs/Tkdrg-Cult-Overhaul.yml @@ -0,0 +1,15 @@ +author: Tkdrg + +delete-after: True + +changes: + - experiment: "Cult has been overhauled in an attempt to make the gamemode more fun." + - rscdel: "Cult onversion and stunpapers have been removed. So have most cult objectives." + - tweak: "The cult's single objective is now defend and feed a large construct shell in order to summon the Geometer." + - tweak: "The cult must sacrifice souls in order to acquire summoning orbs, which must be inserted inside said shell." + - tweak: "The large construct shell can be procured by using a summoning orb in hand, but it is vulnerable to attack." + - tweak: "Once enough orbs are inserted, the station will go Delta. After three minutes, the cult will have won." + - rscadd: "Cult communications now no longer damage you when done without a tome." + - rscadd: "Cultists now start with a sacrificial dagger, with bleeding effects and high throwing damage." + - rscadd: "Most existing runes were buffed, merged, or removed. A Immolate rune and a Time Stop rune were added. Experiment!" + - experiment: "Each cultist now gets a random set of runes in their tomes. Pool together your knowledge in order to thrive." diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index 81d7d489e48c900bb498a819925e97aa580411ad..0bd0e0fefb5da33d924d250ea1e61b3d9fb6e7f3 100644 GIT binary patch literal 9657 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 literal 9768 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 literal 14583 zcmaL8byQT{8$UX9cS@&#qO{U8bP9+xNC?v1Jv7oGAq`R@EhQ2IQYtZo4Bau3L+3Da z=l!nVUH9I9?pi0-*=L`#pY!a`e)=Tn>8OzrGZ6y-05T1AWqr)K53`pN;$x0x{I+i~ zr;%U-6JO=`KDORYp1w{V?f^hwVQgv-akMaPEPPww`H#41$Gx0N{vidcvY22RoGJCp z_M0nKX_GxpMfFePWtst=`yJkIZ{I)ubA|diY9QB)5{G`dP3TOY&*ey_c%U zsfH0&@B3Hq!{OG0pEe}tx8GhfuWg=6?{p8xzu8Y`;X8q0No()z9YU*Z>BwB}sA*BO|FO6A`B>_qd_Y z!Cpg%y+tpOtL4X!s^GsfGjC_bR-g*nx_&xxc^L@iQ`JFc=u@`ff1EFxA}@)h4w>is z@Z%E52o*1JLGer(w2J+KKp%bz372J?Dq$n<5*bq}BZm?JyF z`>%u2PNPJ@z-LPu6C#3ceuD2T!4XMA7CrK`t2lF(2Y+I*0lTw}Y&SBJVGozA6E-J} zw9gl)*8AG#q)+fo!XFL@P}t-aA@#Kq1qPaxWlW$-115TjJREYIh5Ps-iA__OlTzp?R$ThQg7Sv#vDQ?@m`>1i^l-h&TqMNfO#|gZzQfo8jAwE^h;VWypcA zAL{IdLjV0Zun4#xP>e6Eog)w>zUW1)rk^N!_LEPpYz654R2|(hL`1T6UYX5}=aThD z2V<@D=)&+99>!qK7}{2;O1tLjvovcLNuaX_7cS^SM6DdQZ$NL;Br0c#$SNJj4u2AX zNBWsyKfJ$(yN}~%ll$>8RcV0!ccvS&#e0W;WD25Vvj^JCfm?}?=#lVEKIyg2`42M2 zjc)|935}ghgB8Aa{o?A2_5aBri+w@fzw)vzU#@TN2kaq)tl|27T@IF=kff3aX|YWk zskIz;2s$aYaK$H`#0kwSgXv}ze)nv^Z|!d!R-J74dRe@3M~h#4*rRVH(9oNKca^t| zr~}Axs6znZG$K4xH_UnH)|e!BOvkeW%U8x60yUZe{2*%xp9%}iQdx+;yrXZUX8j9M0@*dLvDkJro)ic{=4;#evMH0%{@r}3XK#S;hj#FW5=Fug zY4{|fH-yT*^Sj+H;8CzuUsS@z6ADO^C+)wtaV%L_q|(>+&&t;L3vHwj=qT1wD+=-C zRq&^U(r6v|gQ4wc3StvR>@N`HXk^<%HiaBd@Dey3`7}XGl=r*IafC}TdK)i+9dJ%TV(kCyx25(y20F`N^g|Kr z>X3WseSY?^es9PmvIk#M9W|vJu79$pn{@uRWf7STxvMQZ6}rxM#~pC* zxmU8My70>(9M1lD@`A^qSoq?SLxO*% zBjht){1UFSip{c#jU3?D%dn}ZRgc_}*}#(lRi%}bndiQzJo`6kmFt*3LVfS_kvtR9 zp-4>HtE`W37~s!nrM?u%;Z0q7s`bs{{pt?K$6xsLzsf1Tf>ejs9>(&N$jcQq>7&Sl zX&H?ov$7j>z537otxSLDS^Si(?=+jzWL(e^g3Gj>s27k>p^yqNP2l+iM!Dj$#Nd#3 zf&OUDRe$FXx>$t-FzA_(`OfkEo8=yF1KlPR7;OU5*1~|%A4cNea^M-Y z%MaoGE;rV!?4?+c!EKC_2Nqft`crcEz1tt_!4vyzm>3_Tww~O$^a%eor-KQezV*(* z8w*jHe$&WA%ZsOd+6TiCsirwHJn-%UCOfa;TVv{9sw991l ze|qJpAp&rsGu5nw=w1hBNO4@ejOq*yGhFL86H5QaVj)@!dUPkX&cO`H1yABh$K|1V z=$oc51)giNvBouG0PqR#DZZ(2`4UzL91wj7`0sP#3d!Wp{G`&XVC+_@#i)we=1gQ8#<(Hk+>B_JdSRTbLNia z%`h)?wS33dQM-d8aQ(Yyj9`BXE2Pn7?L#;iLnNXbL0+A;{impF((FxRaX(XZbDXMv zxuFMD2Msx!G+rN0Nw}v9nN81mqo1!#-#dKCFCiw$;04afkX65yrB1*6rvb;rlacaxY;BE28pr`Q2Rf&bnaa{WKY{gn^tdysJew8Jox|l_YJ9*zmEkWg676` z_(Y^dS{*+oDJEaav4gVMhxVDWmkE82ow2;&NH z4|ZS^yP6fj&83XH*DzyYn?vm2~E38QVXMld(>2(IHo%Rz7%5 zWRidIr2B|ZAe4dBHyK$Fp$V@D8Fz5)QfHWq28)tYK)<+bJT zrLpXOeR>U`>*{x4rc528BMc7{||?@(c2?wl4&e= zV>kiFp+^NJ7KfklYC({@q?bRAW@b!WG?FNL*!@j>eD7EX1SP?Cw}xh4 zLvsWFpwIJ5Hlb`cJiiOp0DZb^^H#LiNo!xjFB5=wtk3`67)PQ1clp1=*c=*bJ!9zc zI*Dq8YI&-DqLFQ!EuTw~jk%`Adu8f5c)Dm5pcVE7l+J@w*95g3n+#$>Tf;gM2pJPijtibc*aKydqPR4K1fQUR+MGf!1I zo*>&0$3O(zpp*x%6V&_AAiHycY1pxFw9uu{`#CO_MptaRgxL}9Ng3!f+3;d2C!p1@ z_Pk|EOUv*r0=W_hB?ImOe1n+Z2;^F?_A2q_3G6tv=36u`A=H+=4pQ7JSU;M?x6`|k z+EA8O@Ob&C3#hm5UIVWV<4qc1)${BrrwFj4Pzibs9b=Ff(0gh)X2=XUTyD-=`*97$ z3cL*iZzQ*w2o9U&4^s>DdmthM&`7AXE$gr$6^PqE^kfFy^Z15AGNLWjRm+O7->Nq# z&L77ptEstoYWkTUR1^DAo=*0@*c^zO=Kt%kK?ar& zLr2&JPFn(ryHsPNRGWYzH)sFMC?WrL)U7HKI_oQkwT8Kg!sEw z!DPq(8e~+ti;CIKx7TRbzpa)!=#fy}$`K|SyIJcx!foNR@ukrQGQ=ZQ6V2CuR$6Och1Z#I*3EvZN%r==66`A6akjmEj@3!yci8UMO2M`b ze6jd9yOdr)2S3r{ubJy2?X=^4h`U6Awr+~o=GbO|HzIHa?8%p(i9X2(j~u$DG@{0V zXLINiA>7w}yED}{%{eyIH&!Y`@WgQN0G6MNlgq0eHC>#O?07t&saNQZP5-FX;ms6# z(UumNp(!XdMyw?%iI_AK%|dW9ah>}5Nv@L-r&UzBZr|PjDxfV6znaL0>e4=&M`K>v zaQEgn(~kr33A&}>nzn<%OZq42jBZjAOZN9UuiZO09F_^>&#IGx!-pY3X)jSUx(c-z zB%Iby*8Tj&BYSooy@kH)KvfhJegas3ElNl4hMx^LN$Gqb#(S(=vQrZ^sHxGru$iB; zbJ|Qypi}bMLg3s>AkeMl)sk7S>8xwP1PvdP8|!l?F{9Jk$IclZFs_%-UMs%D)tp!bxH z_6>jJ(1^~Bk)oFth$rP+t!=jcFyTGHr4Dlx{N)5C78M5`a=8&g76C+gT%UeBGM}9A zSMA8{F*!Zq&S^B3SbEHRtM2{T{zHKT@sKEC|Di=ag2kHm27I`a*cj@zhl~W@zWn~w z|9E$g8@2P&zGnlg8~*!kax#A^TanF-U2JHBx;*eFUDv2%ebC+fYqJEaV=)*O)sK~* zW=ffk?XS{o-lb#_*FV!NVkWsh8!`OguV{lCzE=>v18Kg+-8u4HFDZM00}1iJyzNS{ zVoq|z@BZbanJ`GC@Jf;;O8q8RmO&GHeP6Z6gGE+dCsy4dy?iV5;n3;JkilcxVH2kM znC}mV!|37;OT^>h5iCNcM22lVC`9p0H?94<{egjWjXy2+Z+3LYy&iTi_}++?o|9Mo z`)*~EN6E|H@hxoI4PWQb*S*P^QEwb-m+!05K881qz4@u9LfJsTq=sV4?B^-h*RKXr zzCjq0VYE@AHuGG>XSgn$6GVnQ@17c1+1-8Pi3s*Y(gD-s^xTdy_ZSVR%XZ@^PNXPb+Y?yC} zZvG?bHH}O913HS>A@GP8dX0t)--yB4x6eI_^DBxN9o78>Mjh)k6n~qz@;eUv?yjI$ zA#}-`%+DCKDa66cpe-ck6>5r8i+p8EmqppyR%zDwnYA!qYIM8(D2%T}ALL|53owp; z%JsW=<>W8tv?1N7-S(CXwhBLQxs9^cL0v-N@$-2w#|E>+C@g_0+3)XCoN9}PHLHWO zL{+=CsBzL9Ef`?^t`p4smCIVa62i=$0$;#BnASFK{4fgaEu1~X6^kwtMF5;C3z>;a=;nkOR!TDGVQ_Y z``LXM#wCzY|NaH({BAc+ArXCVLuVheYP)fD z5gaJLMKe?p(fs?BlZib;*wxzoeDr2+_^~u!M5zhai=2A%Qd<6fvyUcP{O?Dm`l!sc zk|9ua&7Xz5Ui1R%H`;V=a_GUol8R$%w!n)mC|oERBKkuXrIW-a@1MLP}-}oExO@ z6CP4_Xv~XojkxRTCj)Ah)Auk}*&+45xKlPSPQC9KQGzaZ-62NGJxc=b3XmgPz^Hwv z@7YR|afmKh0IAprT*_JOy#7;cs!*3ZDt}G7S3LYl0pm0HhV~DSbW0iPkwU$w`5zcN zu8^Fk+=;ZVh?f%ObHGyhhta0=OUG_}2*#@mZ4Tv;=q;Lhr|$hjGkNP2r@@CJs8YDb z=l!*H5qIV^;)VHW*Oz0e-0N1?W^2a>vRfMWlmhIHdQ*x@CH$6D-SB+_2^T}$9c6%HG~CxipBDq zUuNlcs2Op)_-yP|Pqhut{+8{W2B-oAaPLQ38v_&_vT*L8bnH5J4$MEhmPboUZZ&}+vf+_^CR(3RFPIk(%-)dPGav1Nq6$3F zgVI@)^M8NU`+cz>3=WT46T&ATEC&=hDwc9>AbJlGnlcKnF}84wo~C%z=Zo{y>Sqz< z#X2Y)7VJq_WV3vmGJg{hl%C-73_S!V7+CX)5GIv68xwQQTO7RDtuOj6lBk$0Vls0W zT9w7~f@tDV7O}9`^xj5RmSlCFn>00fXwi9FEu%)a<|+6AZ2Z1Q1R*p&&lJCDa{8RyoFh3UNx**hk8c8fHYWvsnR&`p zn6ILf@^fmYl{hnWX8MV`?+S;S5AG%ITVkqNMhT{O_A~~(ePd1)S?av$`Zp&dw>*#q zv*>%w5{@gQNuiF)5t(o~kIJs!i)O-fk_MR*)h>6ZBU*$?;9X z-6_+Ca_Utcy%dNrp_x4UY7u6(|7u(fxPV5UG~LLMpM(UgJU#yYpxR*@{NsGIu0w0{ zE{avVlBdl++Cqm~g*USbfz@Jpa%jYLsUQD^e?JC!=p}|O~+zeVa>>M_OBbNFPUEN-95tM`=3eS_ia8)qIv?`}Y z>BkIl#kTV>u~v$Nuowz*d?niEN_OFhEiHWWPgrsC_~M%)QA`X!gNU))*_5tecwo2* zk_0wuR^NcU^j#QZ)aupaOmHDdF0~M}Jw4cXEuyyUSY9z`au8B{0e|DLzZ`~`4u)Kg zAv`7FlOJv6mlw8aHvi@bB!XlLe(9uA3lN#}0hDA-xv+n!@$)A5C)>34o2aEve1I0_ z$u*wh>^YWAnpc6Cw^N;>lx;g)RZNs*>C$c` z0?n|E!dD@z?0(K}w}|V|!zdm8dIwa2N8pxJi@1y1-Gdynqyp%30pk(nG;?~(YKFBu zjNyZW1d0@La`jT`0IC1k3!hWjVL*sf@!ipzALp-Q^s!R>Svhehq?8vCX7FD|OtB~B zlkxI*4lX%hCD!2og4p|$%qDXtD<2oN`k)Y$U#c&eENqctMKSYDrZC|o3?5uyQ1P`T zTZn@}z0hwvtHMoCG+iAz9q9UuII?-Tkt7;8@!?#GhdR^b-e8doM$soZU);tpha84ztsz*xTWAVU19KY56z#;fpnu=^19AN{}Zdmad#Ibm| zI>d>$EVHUE(O}l|#$dt=SEkeY!SsKO^%B!&;uBh_l6sPbev+cGIIk!POZ)|KxiB=A zJ(E0`lx)JceVD9jJ5{6OjQ}kSCe1siOwz*#@zK(7t63@zG1R#LPKa(Qz;PcplBYkT zqV^fvgog|9Bq3?4KBfLIIAL@|hJNIC);IODAWd5GdRuMjZu?ty`~+CO1&4w(we8EB zIVtocUq5zaX5O`QX#Pj#4-G5ExJQGfZJgcGxt}!ppmV(JO*|wxSY3YYd+(Nr3Jmtf# z+)ek-|Fu|^pe{A&ryP)-bLix!Dp+RB)LTsxBvYEZFT;x^WgFcerfW-dEA@BB7EJ4A z#TWDayJD3n@raW**2SvlJA-H{En@Vjo2+Bg@LIar4nlJ5mp8v{cH~5l=r&lPNL zN~Qk=3K{s?%c11H7YkSoAwwo=cpn z4>K(O)>* zX*9SO+6O?;{m{gc-~;BBj_afHDNT%lBn&$pK<{R|uC+T^mOQKi;ng0YAMej8z@h!J z98c2$%fGoU^ZMBL3Ds##W;D{2A|f*05&c^OX!V!T^r{7;8d$@fNI`KCN+zDa-k)1R zB}h;xYv`zz25OJ(`Ff%5Re#h$YBK`wNyrBPfMM;wT7YjGi1=)0^mzmJ+dBDs28iK< z^9djOZr{0O%NO}Bti_2k+@fbL)qZf3wcC@`o)E7-kK;A)>OtZVONwd%NYl5FW7_w9 zMQIx@YIS(xP~yAt61d9+(rJ+$}x)CB^2B*LSb)!0HXsH zq~q!2)3_;E0)xXp-KX?~$e1(b^~3AwuO|K8!(j>VaX;I#6=~ zXW3DkU^+UFur(Ph>AS;Oo-%jR%4o|^|8|7@L)|G@xBd(4L^+nphdiF))M&GzbX}75 zn;7r|214SkSW*=^&klaWHj~*YEAbAeZ@RWdD^G-y6@*fOV!f6qtEV@@9Adrhg2@p= zZs8^?S5}nRD?tO7?#|ws?fyJ&zmqz&o5Q+xXac}r8|ClA0#?UI+dayT1QkI_1wmmq zYJb8m7PJ@%T3QU{FRH`IDK)>e*`~_-L=BxVhg@TypdON7GRMi}kmdkHl!h0h%AngT zxe0@5YVXL3de+KN^)FB;hF6~Bmgp$Rve?{2GRMI~-^kY$k$*!c4m6YQDEEm&_%R$} z?}2m0AR}^9IR^Z2g^&aR!>-ta^0xbh8XM$8&COLugNi#`Lg4+qOA@!IPvyeN0-ECy zs)$5A4qjVZy8M(MYxo`X6+DEm3Q% zU>GTTfMGQFQX(?N`yapBD^0V=O?6j+R9(Hi<-z{>lfc8k?)QP;^H2J6se3JFYve<+ zw;bS~Y7H}NusjP3Yq;+I&G0Qk!;}52AAY#ST_3Nd`Se~R*zSI?%buf_t|zqe?QUSU zYbq||7?<%^r3zPH8Oz?|u}vh!x3ortkOd_ek-0K-f`}&Bg~Y`koaTz6ITo#=C|p#Z zlpCn_ti$Otw&%i)n#5v?%B;<#uapyyBG-ddhE~0QX*~_PqQ}N;mIlO~8+1~Z7Mc8< z^U@+e)jPE*=^dS{q;>{fQ!-xBd@5eldqPNvy`z%sne`_~_0JIAoM1bDy2Q_xp%|;X zyO&aa_HoUB2$|Hxbbh(pb|O~>(9S0T*PmCA5F>tHR9E3`S9AW6Q2#+o$6|h-Su$;= zx(3@r@s4)wxOUe{#+R#4a}LJ(es16D@R*(XL=3%aX8mBW|acgcUq5aumN}bW}2M#*yMpxyPrN_H(8qUG}$MpyAF9 z6Wa9?7~gyA%~sOtr#5=Jn`BTVH^aEhRLC^~-V<{Dxx%6eH(1^-1(pQTtjH2)@>{En zdGbnS4_ZP75n5W3jfaHX9Hl5&wRbE8z|RzK(wZA-!Y|GO8h>0cDGaYM$5}XI2trTr zd^avx@wB-+L#N_g?6>H8oZX#3JF!z);)`ZD$J=pe>*=@8 zqQanW$A&V}qV6=FW9r{TI}_VE7Vg39GWSQx(A${mgvR_epEqz2_u zS_hpu#v0nbv4a-l1EOp2Sxb@4dR0gFZz&f~n25e$lhgU*R90aBKpGTrS44r{!4m?k zhrJb`3~ASX{cGpLnbg-5{AsCSRW&Dx{MNR|4E)F`83md~(Ix|wYhYM~k+K2HZYFn!80$RY9ac&u%#jmX zSUE}eMxJ?fj_=yRwKXaW%Ua+ofV|cTk-PErViwuKnJ)<`q_v=$G6SqjK z6wA(c$dy`=8H*O{G#_@*-DV3^?Ne3vfk=g*%~2&3qrcX600UDF0TVWrKqjY%&dw*< ze+XqdT&qO&D;6E2F0-x3tK+$^v^_S~n;q_6Odi)4Ffucjo1Jek+=vmVgDqz(2sph( z0U@Wzo|=x@Q3!$s73P%o>5+4*AI;JenY@AmrC*~d;GHGN7GPl7fg<*N)H+hxG$A9k z(=6rp>Fc_-ggOafpH3GarS%eQaB&E7pdw3&VFWSjx+J?cw{&0bp>#e!=S5V}>Z>L+rJu>!Gts z3UDz1U0`0)yR7q_h?w<_5y(jU_#1WW3Jb*p+}2k~syCG5rqS)w?5(QlCTjA;RMW;* z-OD#cr*~48R5lN%R_gac>hWxG^7rPeC&9+Q;ghhN4GovZ1+H1-NAo6>B+ehANI*rfn87NU#k`zr0wqNJUQH{%|xVQ5l_RLhwLT07x~b{EVh~7&A?QBinrM~JVw1Ft(^rPZw8wqV zrmR{Nf1*wyZ?2^y(CYbxAH?CccilDmspR5UiCHyL%MD#ts}v2=$kv>FBu>tY(>lH_ zh!nQ>TSB=X00NQBnmt;?M>N5exNV`zsw|e7Vo$WFVZ^A^- z`ioW;&2F{P8+$FllfBAp=tAHA`l3rC>(w(-y8foi+m}s|He8Opaq4$7qSPNw39=t< zwR7n$M|qwKDsW6n&o~(WoA(ePxZ(ZV$3&V~cyV`#AD`=>eYwEtCmKsK2f}T~{(k<} z!^hO{w|{17TiIKWvXn;V(EkcDME=yj#vOn;K(bC{5M2WTyg|ROdvNO|F83eRi7>i2 z@<^Cn(tF8lj5nSWq_W*yL^G#04O80P9lB{r_X`td%~AP<>-KS}Q%7g&eekwROj@}+ zj16UT1DPwyYp(e)>Etzt0rKQ!axU!76uY*0`{8-z)h^VyVr!&D!QMd;R97K{O!xG+LHUwGbhIC3gsFuMKj-X zLGDf}YB&CE#o`tRF-)n3*U~c&Pw-8ouDfJElcKO|*p(%tEfMzb`jHoI^#t%`t{|!!le)XLAK~?8Y_H{UIt&4#-_gGu4 ztWWz;dkt578nj`I%+-2`($PgYFSPYMTP()lyWkB0Y9}EY5PE$=Wf^>VzR+W9u2#}x z=8;}Ov&*k1Ssrxp?-cLuP}8hQo*)`j25<%YT~UNxly9;51(@2H zU_XUcgOhw|6qz1lqh8C} z;^y3@PxDl(|!DFT-avekfsX!Br<|WgK%JS&HoNe{)_Icwcr`GTj(AOZtU{( zHS1X?woeK^>~E+N9%mbjO{aFX?~#@PKc%WvdZubm@x&vR2{X@B{t|BYwts<_En|T2O9l_$rRwTtSSF(q zbx8D!|B6!z9^;!)%KITP6a`H*6v-k#0duccsvoBMGpPFCj6gFPSI%9TNkA@S|4EjR zj90;aEHvBR=e9AI#J;f^RCPX#Mb?W%3bdS+Jc8R^F#UQMzwwjrzSyk0K7XAhG%Gie z?ZaG-;`{uSjuQ5g{@-9k<`r26sytp{oQWL?G zd+<#>RJy|S;Fms==xxrSuFEs8ccF?U(aH`r6sX$)P+3Id_cb&Y|u|M`k5iC!?yW|ODQgx&J@n@_nTDIIgK zmdLa8O&mO7Ni2^XkcDz$E(L6T{TWZ`dTQ@zq?25pUPbCt*QWqYvp&zllApx36a6G! zbgG%J|M;F9C^k~eT2LdQD<)xBQByEB#@O!mUDsO-k{2)I)-v!h^;_zkO>pl0{(#Iq+b_AUiT-)^5;+#f zP{)bU9dIkspNf?D;x2}t-(_HyP88r-424z&&lsEvds8)uqeSV63T5m%%Vp=2Sno&H z8gdAswJZ97+4F|~3KH^G^{rif!>5DyeUq9KKQB;fYtsraJY|s!r>0ZkITg&-Bu^ha zit#TW-{3x1)OYy$sv_NW%|bzQ2=<$5HGJS;nE-gUm%>{n5n=t`=l7d{S2?Vn*c5RS zDm6I;+J^CZafTw8=*}2j^xk&$3?=5;bW8{XpB|@K^&a5|3{9-ah7B@<%lC@fW_7+8 zNpN#xsijRcIek-!s&_`SM)wlQFiEafQO@80TFr^p%t_APrQlH7f z6OT*?hB9t>O?(onBdpvBMZ^5-C5ZX6N%%X3y<7zDknlGisOdS#?`yeh;;P5PQqx~P z4(2OP0+F3NRm`j~&blK;5y{pUxC-f2)-n|rB4C5D`?t0kuRieB@3Y+MQ}OW*o9#Z#~Zj4m-+ot=d%FP=U}Ood7N=XCAxoBlpsu+=aB>h}0xYUs49rzT;`p>_A|f z?X_7!#CQ>R+9-t!t%9OgAMS-fC1_blNi8*A;=5*L+lKw~4|g#*kEgbMsE+KyX9puG zA_04#IC)ks<6rlcORe!~%+I`IWn(kE^TpxP%mgSa;H zc?2=H*iT-49F{s8;-c3w`DIhD#9x9+rsNr?&u)G_U2X?|g(n?)$cU-aS)be}KU{uY zHkJGvu81*lHF*zcSxUXCUZCIB7^J}RB}K$tL>`Z0Ik!nH1-$yd)5F~3sydU43c|i& zC^o{4m!D%!eq^q1or46}9c1E_BQj~9yx;fnq5Z>aus$2nq9m@$oD7TU{1vY-@l5(r zFML(^gSkg=x!AC8a;wP)dPxOfYu6Rwrrie1yYmbBI_o)fi< z@d^>*eyy;=`k@%j*Mj`cDKR0(_a7zRBM&SY95HMDVN!?sGr#hq1WHQcgseoP7NTKF zI%3Bn`WazW{pRzj)&pZp^~ugEa9N}1J_`1pi_rpCLE>xBw6 z02;m`w$&2Q%-9Rogt%tSV$~VX_WYBww1#I}Yk>bm9wOE__5}Yxzw9j^&l5s^e5_%| z<2w+#rKbb(U=N4p5fx@xi<=_TBCNVES&th+P+t%bvZx3*^NzE>8v{kqZyXXlxR6yjQNC!cJL`+rtT zOgbU_CR*I0bL(oUur2)M98o%aLBnmxP4iaqs}Y$Z9;<0qz;a+Y34Xq^jNX+=Hb7p`HA269jj}*u}!zeA9&~hmoh!Gk%3s2cN9EuSfXB!mj*l zV}Bl;;AR--y%?5Bq_21i#8&$XO;vLBHDP8HMS)d;u`S-R7GTVui~tQ49pwf^>!|+= DkihZd diff --git a/icons/obj/cult_large.dmi b/icons/obj/cult_large.dmi new file mode 100644 index 0000000000000000000000000000000000000000..83e5b7e077ee525669463bba409286a017f9d834 GIT binary patch literal 2312 zcmV+j3HSDiP)i#3H76%NFA=CKH9jdPF*#d_i!&v&s2C_| z$ie8zc0uT)ARN;_~X%tLfDDMzRR}z9osvAPCZ_ z@GimPU;FLaHQ$<9`aDJvl)_R;STjqX$4G$dzCShPr;{n)zmZI$>FMd2nVD!5fDp5@ zBAv`41lgoi3d3*&fj{N{e$&69MMcQAbat_Hx>^*eWY5=}=K)oN{i zzE(g0fY~hU2nQH+I4Ctj#Bs2&5EK#k_wL=R`*kihywv^M^?DuG^8WqB#lWUyC7LV5EiVq$R~i{il2-Xo_Y*`1gx&DNx6oXq7dNuDnxvr7AbrRKV8a3s zcq}5DI*bTGkd^?#9;PYKEl2?nvF%1tt%ly7uhptL*o#Zca!Kl}$VHxd8UYI@0O(5# zfKti?dQ}jDKnB3mG)*!0Abr~cAbk*!%g|b7r9!QiHUU>Y*Sy?${+u9oc6Q`**^;(? zK)DtCRMeW?1YG$#3qj0S!vJz=nT$m~fWIu=mjIw%-%TU1n*n(0g;FotFY$s4mFdU4 zCcz;<83^w6-Bf-z1Mny;aj-{mu=hl{y2{@25DmVz3MJ%P?wbhg%LbJ^B-H_=+if5m zH~=wwOO^ym`@RXlzTgzFCD6|XKqy%Ni1;cQ3kb+)Dn!sQ8K4|ASijThDAj7UlmbD^ z=u>xRN#NQt1(4)`^M z79(`UzcTW#^esZ<&{GrGJqQ4bF)=&_K_e-6C^x9wiG%ea4f#$}br66~$Bux|IS8yq z$ciuVC*GW>1WH^5mJ7gODCg8$+~c~x(dhIIavWR|fO_5SD%I`wn(DCoS{bR!T!T3mGa z(FdbUKc@7vFHj>`0Qg{!rPa!;xz!VvKOp;f8pKRH|k9mf;8Kd_Fo(`Sf5Ww{0kQW6xqwc0Xdz@ zV*tRZxqlIWYXBJWFHZdcuo`~|z=M7ZtM8D-bUH8d2-Mko2jKmgIx~G(qAg!=jm7a^ z9zijHNBX1=dG^^$0I1XVwiN|}D?IVpO8}&&lq3ReZ7wagnxyVsfDa$7o9g2S)&KCx z^g*CoJ7lX7IpesLL-BSP`Hf8w@Nj4wJC!V@I6V2+kiY%$sKmz(_UU6$0om489Ek7^zZj z2%K9EBml@*EP&Iq9DwikJ@w;g!klF>N%?-y(BMpn%}pKsj;EJ(3g<>?QAevK!;+Cn2zJj0q42Zp_C8@YFx9 z$$TFV03mQqX1o&61V8L998*6{LN*&)-&6now3={ieNQadO*p Date: Sun, 6 Dec 2015 19:48:11 -0600 Subject: [PATCH 29/57] Begin rewrite of NanoUI frontend. * Remove jQuery in favor of polyfills. * Make NanoUI work with IE8-IE11 * Upstream doT * Change NanoUI template syntax * Event driven code --- .../components/binary_devices/passive_gate.dm | 2 +- .../components/binary_devices/pump.dm | 2 +- .../components/binary_devices/volume_pump.dm | 2 +- .../components/trinary_devices/filter.dm | 2 +- .../components/trinary_devices/mixer.dm | 2 +- .../components/unary_devices/cryo.dm | 2 +- code/controllers/subsystem/nano.dm | 2 +- code/game/machinery/alarm.dm | 2 +- code/game/machinery/atmoalter/canister.dm | 2 +- .../machinery/doors/airlock_electronics.dm | 2 +- code/game/machinery/spaceheater.dm | 2 +- .../game/objects/items/weapons/tanks/tanks.dm | 2 +- code/modules/client/client procs.dm | 3 + code/modules/games/playing_cards.dmi | Bin 611 -> 610 bytes code/modules/nano/nanoui.dm | 127 +- code/modules/power/apc.dm | 2 +- code/modules/power/smes.dm | 2 +- code/modules/power/solar.dm | 2 +- .../chemistry/machinery/chem_dispenser.dm | 2 +- .../chemistry/machinery/chem_heater.dm | 2 +- nano/image_source/{icon-eye.xcf => eye.xcf} | Bin .../{source/NTLogoRevised.fla => ntlogo.fla} | Bin nano/image_source/oldsource/NTLogoRevised.fla | Bin 0 -> 43161 bytes .../{source => oldsource}/icon-eye.xcf | Bin .../uiBackground-Syndicate.xcf | Bin .../{source => oldsource}/uiBackground.fla | Bin .../{source => oldsource}/uiBackground.xcf | Bin .../uiBasicBackground.xcf | Bin .../{source => oldsource}/uiIcons16Green.xcf | Bin .../{source => oldsource}/uiIcons16Red.xcf | Bin .../{source => oldsource}/uiIcons24.xcf | Bin .../uiNoticeBackground.xcf | Bin .../uiTitleBackground.xcf | Bin .../{uiIcons24.xcf => statusicon.xcf} | Bin nano/images/background.png | Bin 0 -> 2290 bytes nano/images/background_nanotrasen.png | Bin 0 -> 4857 bytes nano/images/background_notice.jpg | Bin 0 -> 34641 bytes nano/images/background_syndicate.png | Bin 0 -> 19973 bytes nano/images/c_charging.gif | Bin 960 -> 0 bytes nano/images/c_discharging.gif | Bin 922 -> 0 bytes nano/images/c_max.gif | Bin 125 -> 0 bytes nano/images/logo_nanotrasen.png | Bin 0 -> 509 bytes nano/images/logo_syndicate.png | Bin 0 -> 1002 bytes nano/images/nanomapBackground.png | Bin 15927 -> 0 bytes nano/images/nanomap_z1.png | Bin 569507 -> 0 bytes nano/images/statusicon.png | Bin 0 -> 928 bytes nano/images/uiBackground-Syndicate.png | Bin 213007 -> 0 bytes nano/images/uiBackground.png | Bin 16733 -> 0 bytes nano/images/uiBasicBackground.png | Bin 5865 -> 0 bytes nano/images/uiIcons16.png | Bin 3080 -> 0 bytes nano/images/uiIcons16Green.png | Bin 29139 -> 0 bytes nano/images/uiIcons16Red.png | Bin 28279 -> 0 bytes nano/images/uiIcons24.png | Bin 1045 -> 0 bytes nano/images/uiLinkPendingIcon.gif | Bin 673 -> 0 bytes nano/images/uiMaskBackground.png | Bin 226 -> 0 bytes nano/images/uiNoticeBackground.jpg | Bin 40135 -> 0 bytes nano/images/uiTitleFluff-Syndicate.png | Bin 1429 -> 0 bytes nano/images/uiTitleFluff.png | Bin 670 -> 0 bytes .../{air_alarm.tmpl => air_alarm.dot} | 140 +- ...ectronics.tmpl => airlock_electronics.dot} | 8 +- nano/interfaces/{apc.tmpl => apc.dot} | 120 +- .../{atmos_filter.tmpl => atmos_filter.dot} | 0 .../{atmos_mixer.tmpl => atmos_mixer.dot} | 0 .../{atmos_pump.tmpl => atmos_pump.dot} | 6 +- .../{canister.tmpl => canister.dot} | 18 +- ...chem_dispenser.tmpl => chem_dispenser.dot} | 30 +- .../{chem_heater.tmpl => chem_heater.dot} | 16 +- nano/interfaces/{cryo.tmpl => cryo.dot} | 44 +- nano/interfaces/{smes.tmpl => smes.dot} | 16 +- .../{solar_control.tmpl => solar_control.dot} | 12 +- nano/interfaces/space_heater.dot | 76 + nano/interfaces/space_heater.tmpl | 75 - nano/interfaces/{tanks.tmpl => tanks.dot} | 10 +- nano/layouts/layout_basic.css | 8 +- nano/layouts/layout_basic.tmpl | 4 +- nano/layouts/layout_default.css | 89 +- nano/layouts/layout_default.tmpl | 39 +- nano/scripts/doT.js | 157 - nano/scripts/jquery-ui.js | 16617 ---------------- nano/scripts/jquery.js | 10491 ---------- nano/scripts/nano_base_callbacks.js | 126 - nano/scripts/nano_base_helpers.js | 213 - nano/scripts/nano_config.js | 100 - nano/scripts/nano_state.js | 121 - nano/scripts/nano_state_default.js | 14 - nano/scripts/nano_state_manager.js | 220 - nano/scripts/nano_template.js | 135 - nano/scripts/nano_update.js | 236 - nano/scripts/nano_utility.js | 161 - nano/scripts/nanoui.handlers.js | 84 + nano/scripts/nanoui.helpers.js | 71 + nano/scripts/nanoui.js | 97 + nano/scripts/nanoui.template.js | 108 + nano/scripts/nanoui.util.js | 55 + nano/styles/icons.css | 314 - nano/styles/{shared.css => nanoui.css} | 192 +- nano/styles/normalize.css | 427 - 97 files changed, 830 insertions(+), 29984 deletions(-) rename nano/image_source/{icon-eye.xcf => eye.xcf} (100%) rename nano/image_source/{source/NTLogoRevised.fla => ntlogo.fla} (100%) create mode 100644 nano/image_source/oldsource/NTLogoRevised.fla rename nano/image_source/{source => oldsource}/icon-eye.xcf (100%) rename nano/image_source/{source => oldsource}/uiBackground-Syndicate.xcf (100%) rename nano/image_source/{source => oldsource}/uiBackground.fla (100%) rename nano/image_source/{source => oldsource}/uiBackground.xcf (100%) rename nano/image_source/{source => oldsource}/uiBasicBackground.xcf (100%) rename nano/image_source/{source => oldsource}/uiIcons16Green.xcf (100%) rename nano/image_source/{source => oldsource}/uiIcons16Red.xcf (100%) rename nano/image_source/{source => oldsource}/uiIcons24.xcf (100%) rename nano/image_source/{source => oldsource}/uiNoticeBackground.xcf (100%) rename nano/image_source/{source => oldsource}/uiTitleBackground.xcf (100%) rename nano/image_source/{uiIcons24.xcf => statusicon.xcf} (100%) create mode 100644 nano/images/background.png create mode 100644 nano/images/background_nanotrasen.png create mode 100644 nano/images/background_notice.jpg create mode 100644 nano/images/background_syndicate.png delete mode 100644 nano/images/c_charging.gif delete mode 100644 nano/images/c_discharging.gif delete mode 100644 nano/images/c_max.gif create mode 100644 nano/images/logo_nanotrasen.png create mode 100644 nano/images/logo_syndicate.png delete mode 100644 nano/images/nanomapBackground.png delete mode 100644 nano/images/nanomap_z1.png create mode 100644 nano/images/statusicon.png delete mode 100644 nano/images/uiBackground-Syndicate.png delete mode 100644 nano/images/uiBackground.png delete mode 100644 nano/images/uiBasicBackground.png delete mode 100644 nano/images/uiIcons16.png delete mode 100644 nano/images/uiIcons16Green.png delete mode 100644 nano/images/uiIcons16Red.png delete mode 100644 nano/images/uiIcons24.png delete mode 100644 nano/images/uiLinkPendingIcon.gif delete mode 100644 nano/images/uiMaskBackground.png delete mode 100644 nano/images/uiNoticeBackground.jpg delete mode 100644 nano/images/uiTitleFluff-Syndicate.png delete mode 100644 nano/images/uiTitleFluff.png rename nano/interfaces/{air_alarm.tmpl => air_alarm.dot} (82%) rename nano/interfaces/{airlock_electronics.tmpl => airlock_electronics.dot} (86%) rename nano/interfaces/{apc.tmpl => apc.dot} (65%) rename nano/interfaces/{atmos_filter.tmpl => atmos_filter.dot} (100%) rename nano/interfaces/{atmos_mixer.tmpl => atmos_mixer.dot} (100%) rename nano/interfaces/{atmos_pump.tmpl => atmos_pump.dot} (95%) rename nano/interfaces/{canister.tmpl => canister.dot} (93%) rename nano/interfaces/{chem_dispenser.tmpl => chem_dispenser.dot} (70%) rename nano/interfaces/{chem_heater.tmpl => chem_heater.dot} (79%) rename nano/interfaces/{cryo.tmpl => cryo.dot} (87%) rename nano/interfaces/{smes.tmpl => smes.dot} (95%) rename nano/interfaces/{solar_control.tmpl => solar_control.dot} (95%) create mode 100644 nano/interfaces/space_heater.dot delete mode 100644 nano/interfaces/space_heater.tmpl rename nano/interfaces/{tanks.tmpl => tanks.dot} (82%) delete mode 100644 nano/scripts/doT.js delete mode 100644 nano/scripts/jquery-ui.js delete mode 100644 nano/scripts/jquery.js delete mode 100644 nano/scripts/nano_base_callbacks.js delete mode 100644 nano/scripts/nano_base_helpers.js delete mode 100644 nano/scripts/nano_config.js delete mode 100644 nano/scripts/nano_state.js delete mode 100644 nano/scripts/nano_state_default.js delete mode 100644 nano/scripts/nano_state_manager.js delete mode 100644 nano/scripts/nano_template.js delete mode 100644 nano/scripts/nano_update.js delete mode 100644 nano/scripts/nano_utility.js create mode 100644 nano/scripts/nanoui.handlers.js create mode 100644 nano/scripts/nanoui.helpers.js create mode 100644 nano/scripts/nanoui.js create mode 100644 nano/scripts/nanoui.template.js create mode 100644 nano/scripts/nanoui.util.js delete mode 100644 nano/styles/icons.css rename nano/styles/{shared.css => nanoui.css} (76%) delete mode 100644 nano/styles/normalize.css diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm index c43e9c33b72..86fe16ca1cf 100644 --- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm +++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm @@ -100,7 +100,7 @@ Passive gate is similar to the regular pump except: /obj/machinery/atmospherics/components/binary/passive_gate/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0) ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open) if (!ui) - ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 400, 100) + ui = new(user, src, ui_key, "atmos_pump.dot", name, 400, 100) ui.open() /obj/machinery/atmospherics/components/binary/passive_gate/get_ui_data() diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm index 5062bd6dcf3..7032618d919 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm @@ -108,7 +108,7 @@ Thus, the two variables affect pump operation are set in New(): /obj/machinery/atmospherics/components/binary/pump/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0) ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open) if (!ui) - ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 400, 100) + ui = new(user, src, ui_key, "atmos_pump.dot", name, 400, 100) ui.open() /obj/machinery/atmospherics/components/binary/pump/get_ui_data() diff --git a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm index ead30d5e6d9..a9b11200d58 100644 --- a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm @@ -105,7 +105,7 @@ Thus, the two variables affect pump operation are set in New(): /obj/machinery/atmospherics/components/binary/volume_pump/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0) ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open) if (!ui) - ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 400, 100) + ui = new(user, src, ui_key, "atmos_pump.dot", name, 400, 100) ui.open() /obj/machinery/atmospherics/components/binary/volume_pump/get_ui_data() diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm index 11b47197251..591ca7c7931 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm @@ -172,7 +172,7 @@ Filter types: /obj/machinery/atmospherics/components/trinary/filter/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0) ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open) if (!ui) - ui = new(user, src, ui_key, "atmos_filter.tmpl", name, 400, 120) + ui = new(user, src, ui_key, "atmos_filter.dot", name, 400, 120) ui.open() /obj/machinery/atmospherics/components/trinary/filter/get_ui_data() diff --git a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm index 9e39a0b40f3..28cadf48539 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm @@ -135,7 +135,7 @@ /obj/machinery/atmospherics/components/trinary/mixer/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0) ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open) if (!ui) - ui = new(user, src, ui_key, "atmos_mixer.tmpl", name, 400, 145) + ui = new(user, src, ui_key, "atmos_mixer.dot", name, 400, 145) ui.open() /obj/machinery/atmospherics/components/trinary/mixer/get_ui_data() diff --git a/code/ATMOSPHERICS/components/unary_devices/cryo.dm b/code/ATMOSPHERICS/components/unary_devices/cryo.dm index 88fb4e5bc03..9414f305397 100644 --- a/code/ATMOSPHERICS/components/unary_devices/cryo.dm +++ b/code/ATMOSPHERICS/components/unary_devices/cryo.dm @@ -113,7 +113,7 @@ /obj/machinery/atmospherics/components/unary/cryo_cell/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0) ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open) if (!ui) - ui = new(user, src, ui_key, "cryo.tmpl", name, 520, 560, state = notcontained_state) + ui = new(user, src, ui_key, "cryo.dot", name, 520, 560, state = notcontained_state) ui.open() /obj/machinery/atmospherics/components/unary/cryo_cell/get_ui_data() diff --git a/code/controllers/subsystem/nano.dm b/code/controllers/subsystem/nano.dm index 30434484c5f..48b6bfb4612 100644 --- a/code/controllers/subsystem/nano.dm +++ b/code/controllers/subsystem/nano.dm @@ -2,7 +2,7 @@ var/datum/subsystem/nano/SSnano /datum/subsystem/nano name = "NanoUI" - wait = 10 + wait = 5 priority = 16 display = 6 diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index fe5c1be83a6..7ff29041ad9 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -187,7 +187,7 @@ /obj/machinery/alarm/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0) ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open) if (!ui) - ui = new(user, src, ui_key, "air_alarm.tmpl", name, 480, 625) + ui = new(user, src, ui_key, "air_alarm.dot", name, 480, 625) ui.open() /obj/machinery/alarm/get_ui_data(mob/user) diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 3e36bf39410..8b506bc1ef9 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -277,7 +277,7 @@ update_flag /obj/machinery/portable_atmospherics/canister/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0) ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open) if (!ui) - ui = new(user, src, ui_key, "canister.tmpl", name, 470, 400, state = physical_state) + ui = new(user, src, ui_key, "canister.dot", name, 470, 400, state = physical_state) ui.open() /obj/machinery/portable_atmospherics/canister/get_ui_data() diff --git a/code/game/machinery/doors/airlock_electronics.dm b/code/game/machinery/doors/airlock_electronics.dm index 63bce544e72..c53f3e9fde7 100644 --- a/code/game/machinery/doors/airlock_electronics.dm +++ b/code/game/machinery/doors/airlock_electronics.dm @@ -16,7 +16,7 @@ /obj/item/weapon/electronics/airlock/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, force_open = 0) SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open) if (!ui) - ui = new(user, src, ui_key, "airlock_electronics.tmpl", name, 975, 415, state = hands_state) + ui = new(user, src, ui_key, "airlock_electronics.dot", name, 975, 415, state = hands_state) ui.open() /obj/item/weapon/electronics/airlock/get_ui_data() diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index 737d22ee22d..ee2a8ae7ca0 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -159,7 +159,7 @@ /obj/machinery/space_heater/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0) ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open) if (!ui) - ui = new(user, src, ui_key, "space_heater.tmpl", name, 490, 350, state = physical_state) + ui = new(user, src, ui_key, "space_heater.dot", name, 490, 350, state = physical_state) ui.open() /obj/machinery/space_heater/Topic(href, href_list) diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index ac41c83c18c..279d6fcde71 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -122,7 +122,7 @@ /obj/item/weapon/tank/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, force_open = 0) ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open) if (!ui) - ui = new(user, src, ui_key, "tanks.tmpl", name, 525, 175, state = inventory_state) + ui = new(user, src, ui_key, "tanks.dot", name, 525, 175, state = inventory_state) ui.open() /obj/item/weapon/tank/get_ui_data() diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index f05466bf81d..09a7c0985a3 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -22,6 +22,9 @@ /client/Topic(href, href_list, hsrc) if(!usr || usr != mob) //stops us calling Topic for somebody else's client. Also helps prevent usr=null return + if(href_list["nanoui_error"]) + src << href_list["nanoui_error"] + throw EXCEPTION("NanoUI: [href_list["nanoui_error"]]") if(href_list["asset_cache_confirm_arrival"]) //src << "ASSET JOB [href_list["asset_cache_confirm_arrival"]] ARRIVED." var/job = text2num(href_list["asset_cache_confirm_arrival"]) diff --git a/code/modules/games/playing_cards.dmi b/code/modules/games/playing_cards.dmi index 47b5b3e745ad0c9f3c572e97fb7fc53888af19dd..ac8916a64e5561b7edc5b0c7464828f27b531913 100644 GIT binary patch delta 13 UcmaFN@`#0{Gr-S%BWoNJ03!wjRsaA1 delta 14 VcmaFF@|cCSGr-TCcOy$2696WR1Y-aI diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm index 69ec116fbd3..b09bc9c21a1 100644 --- a/code/modules/nano/nanoui.dm +++ b/code/modules/nano/nanoui.dm @@ -28,13 +28,10 @@ var/list/stylesheets = list() // The list of CSS stylesheets to apply to the NanoUI.. var/list/scripts = list() // The list of Javascript scripts to apply to the NanoUI. var/templates[0] // The list of NanoUI templates available to the NanoUI. - var/layout_key = "default" // The layout_key used to load alternate layouts and CSS. - var/state_key = "default" // The state of the frontend. + var/layout = "default" // The layout used to load alternate layouts and CSS. var/auto_update = 1 // Update the NanoUI every MC tick. var/auto_update_layout = 0 // Re-render the layout every update. var/auto_update_content = 1 // Re-render the content every update. - var/show_map = 0 // Show the Map UI. - var/map_z_level = 1 // Map Z-level. var/list/initial_data // The data (and datastructure) used to initialize the NanoUI var/status = NANO_INTERACTIVE // The status/visibility of the NanoUI. var/datum/topic_state/state = null // Topic state used to determine status. Topic states are in interactions/. @@ -96,30 +93,13 @@ * Add the assets required by all NanoUIs. **/ /datum/nanoui/proc/add_common_assets() - // Libraries: jQuery, jQuery-UI, and doT. - add_script("jquery.js") - add_script("jquery-ui.js") - add_script("doT.js") - // Nano Utility: Utility functions and sanity checks. - add_script("nano_utility.js") // The NanoUtility JS, this is used to store utility functions. - // Nano Template: Renders templates using doT. - add_script("nano_template.js") - // Nano State Manager: Handles server updates and passes them to the current state. - add_script("nano_state_manager.js") - // Nano State: Base state. - add_script("nano_state.js") - // Nano State/Default: State used by all NanoUIs by default. - add_script("nano_state_default.js") - // Nano Base Callbacks: Used to set up callbacks across all NanoUIs. - add_script("nano_base_callbacks.js") - // Nano Base Helpers: Template helpers common across all NanoUIs. - add_script("nano_base_helpers.js") - // CSS reset. - add_stylesheet("normalize.css") - // Common style elements. - add_stylesheet("shared.css") - // Icons. - add_stylesheet("icons.css") + add_script("nanoui.js") + add_script("nanoui.util.js") + add_script("nanoui.template.js") + add_script("nanoui.helpers.js") + add_script("nanoui.handlers.js") + + add_stylesheet("nanoui.css") /** * private @@ -190,12 +170,9 @@ "srcObject" = list( "name" = src_object.name ), - "stateKey" = state_key, "status" = status, "autoUpdateLayout" = auto_update_layout, "autoUpdateContent" = auto_update_content, - "showMap" = show_map, - "mapZLevel" = map_z_level, "user" = list( "name" = user.name ) @@ -266,13 +243,13 @@ /** * public * - * Set the layout key for this NanoUI. - * This loads two files during get_html(): 'layout_[layout_key].tmpl' and 'layout_[layout_key].css'. + * Set the layout for this NanoUI. + * This loads two files during get_html(): 'layout_[layout].dot' and 'layout_[layout].css'. * * required layout_key string The new layout key. **/ -/datum/nanoui/proc/set_layout_key(layout_key) - src.layout_key = lowertext(layout_key) +/datum/nanoui/proc/set_layout(layout) + src.layout = lowertext(layout) /** * public @@ -294,36 +271,6 @@ /datum/nanoui/proc/set_auto_update_content(state) auto_update_content = state - /** - * public - * - * Set the state key used in the frontend. - * - * required state_key string The new state key.. - **/ -/datum/nanoui/proc/set_state_key(state_key) - src.state_key = state_key - - /** - * public - * - * Toggle showing the Map UI. - * - * required state bool Enable/disable the Map UI. - **/ -/datum/nanoui/proc/set_show_map(state) - show_map = state - - /** - * public - * - * Set the map Z-level. - * - * required z int The new Z-level. - **/ -/datum/nanoui/proc/set_map_z_level(z) - map_z_level = z - /** * public * @@ -343,8 +290,8 @@ **/ /datum/nanoui/proc/get_html() // Add files based on the layout key. - add_stylesheet("layout_[layout_key].css") - add_template("layout", "layout_[layout_key].tmpl") + add_template("layout", "layout_[layout].dot") + add_stylesheet("layout_[layout].css") // Generate + + + + + + + + [script_html] + + [stylesheet_html] - -
+ +