diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index 333142996be1d..ff8d97e36eae3 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -2,8 +2,6 @@ /datum/game_mode var/list/datum/mind/cult = list() - var/list/allwords = list("travel","self","see","hell","blood","join","tech","destroy", "other", "hide") - var/list/grantwords = list("travel", "see", "hell", "tech", "destroy", "other", "hide") var/list/cult_objectives = list() @@ -54,9 +52,6 @@ var/finished = 0 - var/list/startwords = list("blood","join","self","hell") - var/list/secondwords = list("travel", "see", "tech", "destroy", "other", "hide") - var/eldergod = 1 //for the summon god objective var/acolytes_needed = 10 //for the survive objective @@ -86,6 +81,7 @@ if(config.protect_assistant_from_antagonist) restricted_jobs += "Assistant" + acolytes_needed = max(2, round(num_players()/5)) //Scales the escape requirement with the amount of people in the round for(var/cultists_number = 1 to recommended_enemies) if(!antag_candidates.len) @@ -120,10 +116,8 @@ for(var/datum/mind/cult_mind in cult) equip_cultist(cult_mind.current) -// grant_runeword(cult_mind.current) -// grant_secondword(cult_mind.current) update_cult_icons_added(cult_mind) - cult_mind.current << "You are a member of the cult!" + cult_mind.current << "You are a member of the cult!" memorize_cult_objectives(cult_mind) ..() @@ -136,24 +130,18 @@ 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 (Hell blood join) and three acolytes to do so." + explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. You will need the Rite of Tribute and three acolytes to do so." else explanation = "Free objective." if("eldergod") - 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." + explanation = "Summon Nar-Sie via the use of the Ritual of Dimensional Rending. It will only work if nine cultists stand on and around it." cult_mind.current << "Objective #[obj_count]: [explanation]" cult_mind.memory += "Objective #[obj_count]: [explanation]
" - cult_mind.current << "The Geometer of Blood grants you the knowledge to sacrifice non-believers. (Hell Blood Join)" - cult_mind.memory += "The Geometer of Blood grants you the knowledge to sacrifice non-believers. (Hell Blood Join)
" - for(var/startingword in startwords) - grant_runeword(cult_mind.current,startingword) -// grant_runeword(cult_mind.current,"blood") -// grant_runeword(cult_mind.current,"hell") /datum/game_mode/proc/equip_cultist(mob/living/carbon/human/mob) if(!istype(mob)) return - + mob.cult_add_comm() if (mob.mind) if (mob.mind.assigned_role == "Clown") mob << "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself." @@ -169,10 +157,10 @@ "right hand" = slot_r_hand, ) var/where = mob.equip_in_one_of_slots(T, slots) - if (!where) + if(!where) mob << "Unfortunately, you weren't able to get a talisman. This is very bad and you should adminhelp immediately." 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 - there are others." + 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.update_icons() if(where == "backpack") var/obj/item/weapon/storage/B = mob.back @@ -181,58 +169,6 @@ return 1 -//datum/game_mode/cult/proc/grant_secondword(mob/living/carbon/human/cult_mob, var/word) -// if (!word) -// if(secondwords.len > 0) -// word=pick(secondwords) -// secondwords -= word -// grant_runeword(cult_mob,word) - -//datum/game_mode/cult/grant_runeword(mob/living/carbon/human/cult_mob, var/word) -// if (!word) -// if(startwords.len > 0) -// word=pick(startwords) -// startwords -= word -// return ..(cult_mob,word) - -/datum/game_mode/proc/grant_runeword(mob/living/carbon/human/cult_mob, word) - if(!wordtravel) - runerandom() - if (!word) - word=pick(grantwords) - var/wordexp - switch(word) - if("travel") - wordexp = "[wordtravel] is travel..." - if("blood") - wordexp = "[wordblood] is blood..." - if("join") - wordexp = "[wordjoin] is join..." - if("hell") - wordexp = "[wordhell] is Hell..." - if("self") - wordexp = "[wordself] is self..." - if("see") - wordexp = "[wordsee] is see..." - if("tech") - wordexp = "[wordtech] is technology..." - if("destroy") - wordexp = "[worddestr] is destroy..." - if("other") - wordexp = "[wordother] is other..." -// if("hear") -// wordexp = "[wordhear] is hear..." -// if("free") -// wordexp = "[wordfree] is free..." - if("hide") - wordexp = "[wordhide] is hide..." - cult_mob << "[pick("You remember something from the dark teachings of your master","You hear a dark voice on the wind","Black blood oozes into your vision and forms into symbols","You catch a brief glimmer of the otherside")]... [wordexp]" - cult_mob.mind.store_memory("You remember that [wordexp]", 0, 0) - cult_mob.mind.cult_words += word - if(cult_mob.mind.cult_words.len == allwords.len) - cult_mob << "\green You feel enlightened, as if you have gained all the secrets of the other side." - - /datum/game_mode/proc/add_cultist(datum/mind/cult_mind) //BASE if (!istype(cult_mind)) return 0 @@ -258,7 +194,6 @@ cult_mind.current.Paralyse(5) cult_mind.current << "An unfamiliar white light flashes through your mind, cleansing the taint of the dark-one and the memories of your time as his servant with it." cult_mind.memory = "" - cult_mind.cult_words = initial(cult_mind.cult_words) update_cult_icons_removed(cult_mind) cult_mind.current.attack_log += "\[[time_stamp()]\] Has renounced the cult!" if(show_message) diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index 6aaeba719313f..c519f805608a4 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -1,6 +1,6 @@ /obj/item/weapon/melee/cultblade - name = "cult blade" - desc = "An arcane weapon wielded by the followers of Nar-Sie" + name = "eldritch longsword" + desc = "A sword humming with unholy energy. It glows with a dim red light." icon_state = "cultblade" item_state = "cultblade" flags = CONDUCT @@ -11,28 +11,31 @@ attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + /obj/item/weapon/melee/cultblade/attack(mob/living/target, mob/living/carbon/human/user) - if(iscultist(user)) - return ..() - else - user.Paralyse(5) - user << "An unexplicable force powerfully repels the sword from [target]!" - var/organ = ((user.hand ? "l_":"r_") + "arm") - var/obj/item/organ/limb/affecting = user.get_organ(organ) - if(affecting.take_damage(rand(force/2, force))) //random amount of damage between half of the blade's force and the full force of the blade. - user.update_damage_overlays(0) - return + if(!iscultist(user)) + user.Weaken(5) + user.visible_message("A powerful force shoves [user] away from [target]!", \ + "\"You shouldn't play with sharp things. You'll poke someone's eye out.\"") + if(ishuman(user)) + var/mob/living/carbon/human/H = user + H.apply_damage(rand(force/2, force), BRUTE, pick("l_arm", "r_arm")) + else + user.adjustBruteLoss(rand(force/2,force)) + return + ..() /obj/item/weapon/melee/cultblade/pickup(mob/living/user) if(!iscultist(user)) - user << "An overwhelming feeling of dread comes over you as you pick up the cultist's sword. It would be wise to be rid of this blade quickly." + user << "\"I wouldn't advise that.\"" + user << "An overwhelming sense of nausea overpowers you!" user.Dizzy(120) /obj/item/clothing/head/culthood - name = "cult hood" + name = "ancient cultist hood" icon_state = "culthood" - desc = "A hood worn by the followers of Nar-Sie." + desc = "A torn, dust-caked hood. Strange letters line the inside." flags_inv = HIDEFACE flags_cover = HEADCOVERSEYES armor = list(melee = 30, bullet = 10, laser = 5,energy = 5, bomb = 0, bio = 0, rad = 0) @@ -41,18 +44,9 @@ heat_protection = HEAD max_heat_protection_temperature = HELMET_MAX_TEMP_PROTECT - -/obj/item/clothing/head/culthood/alt - icon_state = "cult_hoodalt" - item_state = "cult_hoodalt" - -/obj/item/clothing/suit/cultrobes/alt - icon_state = "cultrobesalt" - item_state = "cultrobesalt" - /obj/item/clothing/suit/cultrobes - name = "cult robes" - desc = "A set of armored robes worn by the followers of Nar-Sie" + name = "ancient cultist robes" + desc = "A ragged, dusty set of robes. Strange letters line the inside." icon_state = "cultrobes" item_state = "cultrobes" body_parts_covered = CHEST|GROIN|LEGS|ARMS @@ -64,6 +58,20 @@ heat_protection = CHEST|GROIN|LEGS|ARMS max_heat_protection_temperature = ARMOR_MAX_TEMP_PROTECT + +/obj/item/clothing/head/culthood/alt + name = "cultist hood" + desc = "An armored hood worn by the followers of Nar-Sie." + icon_state = "cult_hoodalt" + item_state = "cult_hoodalt" + +/obj/item/clothing/suit/cultrobes/alt + name = "cultist hood" + desc = "An armored set of robes worn by the followers of Nar-Sie." + icon_state = "cultrobesalt" + item_state = "cultrobesalt" + + /obj/item/clothing/head/magus name = "magus helm" icon_state = "magus" @@ -86,18 +94,18 @@ /obj/item/clothing/head/helmet/space/cult - name = "cult helmet" - desc = "A space worthy helmet used by the followers of Nar-Sie" + name = "nar-sian bruiser's helmet" + desc = "A heavily-armored helmet worn by warriors of the Nar-Sian cult. It can withstand hard vacuum." icon_state = "cult_helmet" item_state = "cult_helmet" armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) /obj/item/clothing/suit/space/cult - name = "cult armor" + name = "nar-sian bruiser's armor" icon_state = "cult_armor" item_state = "cult_armor" - desc = "A bulky suit of armor, bristling with spikes. It looks space proof." + desc = "A heavily-armored exosuit worn by warriors of the Nar-Sian cult. It can withstand hard vacuum." w_class = 3 - allowed = list(/obj/item/weapon/tome,/obj/item/weapon/melee/cultblade,/obj/item/weapon/tank/internals/emergency_oxygen) + allowed = list(/obj/item/weapon/tome,/obj/item/weapon/melee/cultblade,/obj/item/weapon/tank/internals/) slowdown = 1 - armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) \ No newline at end of file + armor = list(melee = 70, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index 090f077b4661a..000120ef61a9a 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -1,35 +1,18 @@ //This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 +/* -var/wordtravel = null -var/wordself = null -var/wordsee = null -var/wordhell = null -var/wordblood = null -var/wordjoin = null -var/wordtech = null -var/worddestr = null -var/wordother = null -//var/wordhear = null -//var/wordfree = null -var/wordhide = null -var/runedec = 0 -var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", "self", "see", "other", "hide") - -/client/proc/check_words() // -- Urist - set category = "Special Verbs" - set name = "Check Rune Words" - set desc = "Check the rune-word meaning" - if(!wordtravel) - runerandom() - usr << "[wordtravel] is travel, [wordblood] is blood, [wordjoin] is join, [wordhell] is Hell, [worddestr] is destroy, [wordtech] is technology, [wordself] is self, [wordsee] is see, [wordother] is other, [wordhide] is hide." - -/mob/proc/cult_add_comm() +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. + +*/ + +/mob/proc/cult_add_comm() //why the fuck does this have its own proc? not removing it because it might be used somewhere but... verbs += /mob/living/proc/cult_innate_comm /mob/living/proc/cult_innate_comm() set category = "Cultist" - set name = "Communicate" + set name = "Imperfect Communion" if(!iscultist(usr)) //they shouldn't have this verb, but just to be sure... return @@ -42,7 +25,7 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", return if(ishuman(usr) || ismonkey(usr)) //Damage only applies to humans and monkeys, to allow constructs to communicate - usr.visible_message("[usr.name] starts clawing at \his arms with \his fingernails!", "You begin slicing open your arms with your fingers!") + 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) @@ -55,447 +38,31 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", apply_damage(10,BRUTE, "r_arm") if(usr.incapacitated()) return - usr.visible_message("[usr.name] paints strange symbols with their own blood.", "You paint a messy rune with your own blood.") + 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) return -/proc/runerandom() //randomizes word meaning - var/list/runewords=list("ire","ego","nahlizet","certum","veri","jatkaa","mgar","balaq", "karazet", "geeri") ///"orkan" and "allaq" removed. - wordtravel=pick(runewords) - runewords-=wordtravel - wordself=pick(runewords) - runewords-=wordself - wordsee=pick(runewords) - runewords-=wordsee - wordhell=pick(runewords) - runewords-=wordhell - wordblood=pick(runewords) - runewords-=wordblood - wordjoin=pick(runewords) - runewords-=wordjoin - wordtech=pick(runewords) - runewords-=wordtech - worddestr=pick(runewords) - runewords-=worddestr - wordother=pick(runewords) - runewords-=wordother -// wordhear=pick(runewords) -// runewords-=wordhear -// wordfree=pick(runewords) -// runewords-=wordfree - wordhide=pick(runewords) - runewords-=wordhide - - -/obj/effect/rune - desc = "A strange collection of symbols drawn in blood." - anchored = 1 - icon = 'icons/obj/rune.dmi' - icon_state = "1" - unacidable = 1 - layer = TURF_LAYER - - - var/word1 - var/word2 - var/word3 -// Places these combos are mentioned: this file - twice in the rune code, once in imbued tome, once in tome's HTML runes.dm - in the imbue rune code. If you change a combination - dont forget to change it everywhere. - -// travel self [word] - Teleport to random [rune with word destination matching] -// travel other [word] - Portal to rune with word destination matching - kinda doesnt work. At least the icon. No idea why. -// see blood Hell - Create a new tome -// join blood self - Incorporate person over the rune into the group -// Hell join self - Summon TERROR -// destroy see technology - EMP rune -// travel blood self - Drain blood -// see Hell join - See invisible -// blood join Hell - Raise dead - -// hide see blood - Hide nearby runes -// blood see hide - Reveal nearby runes - The point of this rune is that its reversed obscure rune. So you always know the words to reveal the rune once oyu have obscured it. - -// Hell travel self - Leave your body and ghost around -// blood see travel - Manifest a ghost into a mortal body -// Hell tech join - Imbue a rune into a talisman -// Hell blood join - Sacrifice rune -// destroy travel self - Wall rune -// join other self - Summon cultist rune -// travel technology other - Freeing rune // other blood travel was freedom join other - -// hide other see - Deafening rune // was destroy see hear -// destroy see other - Blinding rune -// destroy see blood - BLOOD BOIL - -// self other technology - Communication rune //was other hear blood -// join hide technology - stun rune. Rune color: bright pink. -/obj/effect/rune/New() - ..() - var/image/blood = image(loc = src) - blood.override = 1 - for(var/mob/living/silicon/ai/AI in player_list) - AI.client.images += blood - -/obj/effect/rune/examine(mob/user) - ..() - if(iscultist(user)) - user << "This spell circle reads: [word1] [word2] [word3]." - - - -/obj/effect/rune/attackby(obj/I, mob/user, params) - if(istype(I, /obj/item/weapon/tome) && iscultist(user)) - user << "You retrace your steps, carefully undoing the lines of the rune." - qdel(src) - return - else if(istype(I, /obj/item/weapon/nullrod)) - user << "You disrupt the vile magic with the deadening field of the null rod!" - qdel(src) - return - return - - -/obj/effect/rune/attack_hand(mob/living/user) // OH GOD this is horrible - if(!iscultist(user)) - user << "You can't mouth the arcane scratchings without fumbling over them!" - return - var/message = "You are unable to speak the words of the rune!" - if(!user.can_speak(message) && (user.mind && !user.mind.miming)) - user << message - return - if(!word1 || !word2 || !word3 || prob(user.getBrainLoss())) - return fizzle(user) - if(word1 == wordtravel && word2 == wordself) - return teleport(src.word3) - if(word1 == wordsee && word2 == wordblood && word3 == wordhell) - return tomesummon() - if(word1 == wordhell && word2 == worddestr && word3 == wordother) - return armor() - if(word1 == wordjoin && word2 == wordblood && word3 == wordself) - return convert() - if(word1 == wordhell && word2 == wordjoin && word3 == wordself) - return tearreality() - if(word1 == worddestr && word2 == wordsee && word3 == wordtech) - return emp(src.loc,3) - if(word1 == wordtravel && word2 == wordblood && word3 == wordself) - return drain() - if(word1 == wordblood && word2 == wordjoin && word3 == wordhell) - return raise() - if(word1 == wordhide && word2 == wordsee && word3 == wordblood) - return obscure(4) - if(word1 == wordhell && word2 == wordtravel && word3 == wordself) - return ajourney() - if(word1 == wordblood && word2 == wordsee && word3 == wordtravel) - return manifest() - if(word1 == wordhell && word2 == wordtech && word3 == wordjoin) - return talisman() - if(word1 == wordhell && word2 == wordblood && word3 == wordjoin) - return sacrifice() - if(word1 == wordblood && word2 == wordsee && word3 == wordhide) - return revealrunes(src) - if(word1 == worddestr && word2 == wordtravel && word3 == wordself) - return wall() - if(word1 == wordtravel && word2 == wordtech && word3 == wordother) - return freedom() - if(word1 == wordjoin && word2 == wordother && word3 == wordself) - return cultsummon() - if(word1 == wordhide && word2 == wordother && word3 == wordsee) - return deafen() - if(word1 == worddestr && word2 == wordsee && word3 == wordother) - return blind() - if(word1 == worddestr && word2 == wordsee && word3 == wordblood) - return bloodboil() - if(word1 == wordself && word2 == wordother && word3 == wordtech) - return communicate() - if(word1 == wordtravel && word2 == wordother) - return itemport(src.word3) - if(word1 == wordjoin && word2 == wordhide && word3 == wordtech) - return runestun() - if(word1 == wordtravel && word2 == wordhell && word3 == wordtech) - return summon_shell() - else - user.take_overall_damage(30, 0) - user << "You feel the life draining from you, as if Lord Nar-Sie is displeased with you." - return fizzle(user) - - -/obj/effect/rune/proc/fizzle(mob/living/cultist = null) - var/gibberish = pick("B'ADMINES SP'WNIN SH'T","IC'IN O'OC","RO'SHA'M I'SA GRI'FF'N ME'AI","TOX'IN'S O'NM FI'RAH","IA BL'AME TOX'IN'S","FIR'A NON'AN RE'SONA","A'OI I'RS ROUA'GE","LE'OAN JU'STA SP'A'C Z'EE SH'EF","IA PT'WOBEA'RD, IA A'DMI'NEH'LP") - - if(cultist) - if(istype(src,/obj/effect/rune)) - cultist.say(gibberish) - else - cultist.whisper(gibberish) - visible_message("The markings pulse with a small burst of light, then fall dark.", 3, "You hear a faint fizzle.", 2) - return - -/obj/effect/rune/proc/check_icon() - src.color = rgb(255, 0, 0) - if(word1 == wordtravel && word2 == wordself) - icon_state = "2" - src.color = rgb(0, 0, 255) - return - if(word1 == wordjoin && word2 == wordblood && word3 == wordself) - icon_state = "3" - return - if(word1 == wordhell && word2 == wordjoin && word3 == wordself) - icon_state = "4" - return - if(word1 == wordsee && word2 == wordblood && word3 == wordhell) - icon_state = "5" - src.color = rgb(0, 0 , 255) - return - if(word1 == worddestr && word2 == wordsee && word3 == wordtech) - icon_state = "5" - return - if(word1 == wordtravel && word2 == wordblood && word3 == wordself) - icon_state = "2" - return - if(word1 == wordsee && word2 == wordhell && word3 == wordjoin) - icon_state = "4" - src.color = rgb(0, 0 , 255) - return - if(word1 == wordblood && word2 == wordjoin && word3 == wordhell) - icon_state = "1" - return - if(word1 == wordhide && word2 == wordsee && word3 == wordblood) - icon_state = "1" - src.color = rgb(0, 0 , 255) - return - if(word1 == wordhell && word2 == wordtravel && word3 == wordself) - icon_state = "6" - src.color = rgb(0, 0 , 255) - return - if(word1 == wordblood && word2 == wordsee && word3 == wordtravel) - icon_state = "6" - return - if(word1 == wordhell && word2 == wordtech && word3 == wordjoin) - icon_state = "3" - src.color = rgb(0, 0 , 255) - return - if(word1 == wordhell && word2 == wordblood && word3 == wordjoin) - icon_state = "[rand(1,6)]" - src.color = rgb(255, 255, 255) - return - if(word1 == wordblood && word2 == wordsee && word3 == wordhide) - icon_state = "4" - src.color = rgb(255, 255, 255) - return - if(word1 == worddestr && word2 == wordtravel && word3 == wordself) - icon_state = "1" - src.color = rgb(255, 0, 0) - return - if(word1 == wordtravel && word2 == wordtech && word3 == wordother) - icon_state = "4" - src.color = rgb(255, 0, 255) - return - if(word1 == wordjoin && word2 == wordother && word3 == wordself) - icon_state = "2" - src.color = rgb(0, 255, 0) - return - if(word1 == wordhide && word2 == wordother && word3 == wordsee) - icon_state = "4" - src.color = rgb(0, 255, 0) - return - if(word1 == worddestr && word2 == wordsee && word3 == wordother) - icon_state = "4" - src.color = rgb(0, 0, 255) - return - if(word1 == worddestr && word2 == wordsee && word3 == wordblood) - icon_state = "4" - src.color = rgb(255, 0, 0) - return - if(word1 == wordself && word2 == wordother && word3 == wordtech) - icon_state = "3" - src.color = rgb(200, 0, 0) - return - if(word1 == wordtravel && word2 == wordother) - icon_state = "1" - src.color = rgb(200, 0, 0) - return - if(word1 == wordjoin && word2 == wordhide && word3 == wordtech) - icon_state = "2" - src.color = rgb(100, 0, 100) - return - icon_state="[rand(1,6)]" //random shape and color for dummy runes - src.color = rgb(rand(1,255),rand(1,255),rand(1,255)) - - /obj/item/weapon/tome name = "arcane tome" - desc = "An old, dusty tome with frayed edges and a sinister looking cover." + desc = "An old, dusty tome with frayed edges and a sinister-looking cover." icon_state ="tome" throw_speed = 2 throw_range = 5 w_class = 2 - var/notedat = "" - var/tomedat = "" - var/list/words = list("ire" = "ire", "ego" = "ego", "nahlizet" = "nahlizet", "certum" = "certum", "veri" = "veri", "jatkaa" = "jatkaa", "balaq" = "balaq", "mgar" = "mgar", "karazet" = "karazet", "geeri" = "geeri") - - - tomedat = {" - - - - -

The scriptures of Nar-Sie, The One Who Sees, The Geometer of Blood.

- - The book is written in an unknown dialect, there are lots of pictures of various complex geometric shapes. You find some notes in english that give you basic understanding of the many runes written in the book. The notes give you an understanding what the words for the runes should be. However, you do not know how to write all these words in this dialect.
- Below is the summary of the runes.
- -

Contents

-

- Teleport self: Travel Self (word)
- Teleport other: Travel Other (word)
- Summon new tome: See Blood Hell
- Convert a person: Join Blood Self
- Summon Nar-Sie: Hell Join Self
- Disable technology: Destroy See Technology
- Drain blood: Travel Blood Self
- Raise dead: Blood Join Hell
- Hide runes: Hide See Blood
- Reveal hidden runes: Blood See Hide
- Leave your body: Hell travel self
- Ghost Manifest: Blood See Travel
- Imbue a talisman: Hell Technology Join
- Sacrifice: Hell Blood Join
- Create a wall: Destroy Travel Self
- Summon cultist: Join Other Self
- Free a cultist: Travel technology other
- Deafen: Hide Other See
- Blind: Destroy See Other
- Blood Boil: Destroy See Blood
- Communicate: Self Other Technology
- Stun: Join Hide Technology
- Summon Cultist Armor: Hell Destroy Other
- See Invisible: See Hell Join
-

-

Rune Descriptions

-

Teleport self

- Teleport rune is a special rune, as it only needs two words, with the third word being destination. Basically, when you have two runes with the same destination, invoking one will teleport you to the other one. If there are more than 2 runes, you will be teleported to a random one. Runes with different third words will create separate networks. You can imbue this rune into a talisman, giving you a great escape mechanism.
-

Teleport other

- Teleport other allows for teleportation for any movable object to another rune with the same third word.
-

Summon new tome

- Invoking this rune summons a new arcane tome. -

Convert a person

- This rune opens target's mind to the realm of Nar-Sie, which usually results in this person joining the cult. However, some people (mostly the ones who posess high authority) have strong enough will to stay true to their old ideals.
-

Summon Nar-Sie

- The ultimate rune. It summons the Avatar of Nar-Sie himself, tearing a huge hole in reality and consuming everything around it. Summoning it is the final goal of any cult.
-

Disable Technology

- Invoking this rune creates a strong electromagnetic pulse in a small radius, making it basically analogic to an EMP grenade. You can imbue this rune into a talisman, making it a decent defensive item.
-

Drain Blood

- This rune instantly heals you of some brute damage at the expense of a person placed on top of the rune. Whenever you invoke a drain rune, ALL drain runes on the station are activated, draining blood from anyone located on top of those runes. This includes yourself, though the blood you drain from yourself just comes back to you. This might help you identify this rune when studying words. One drain gives up to 25HP per each victim, but you can repeat it if you need more. Draining only works on living people, so you might need to recharge your "Battery" once its empty. Drinking too much blood at once might cause blood hunger.
-

Raise Dead

- This rune allows for the resurrection of any dead person. You will need a dead human body and a living human sacrifice. Make 2 raise dead runes. Put a living non-braindead human on top of one, and a dead body on the other one. When you invoke the rune, the life force of the living human will be transferred into the dead body, allowing a ghost standing on top of the dead body to enter it, instantly and fully healing it. Use other runes to ensure there is a ghost ready to be resurrected.
-

Hide runes

- This rune makes all nearby runes completely invisible. They are still there and will work if activated somehow, but you cannot invoke them directly if you do not see them.
-

Reveal runes

- This rune is made to reverse the process of hiding a rune. It reveals all hidden runes in a rather large area around it. -

Leave your body

- This rune gently rips your soul out of your body, leaving it intact. You can observe the surroundings as a ghost as well as communicate with other ghosts. Your body takes damage while you are there, so ensure your journey is not too long, or you might never come back.
-

Manifest a ghost

- Unlike the Raise Dead rune, this rune does not require any special preparations or vessels. Instead of using full lifeforce of a sacrifice, it will drain YOUR lifeforce. Stand on the rune and invoke it. If theres a ghost standing over the rune, it will materialise, and will live as long as you dont move off the rune or die. You can put a paper with a name on the rune to make the new body look like that person.
-

Imbue a talisman

- This rune allows you to imbue the magic of some runes into paper talismans. Create an imbue rune, then an appropriate rune beside it. Put an empty piece of paper on the imbue rune and invoke it. You will now have a one-use talisman with the power of the target rune. Using a talisman drains some health, so be careful with it. You can imbue a talisman with power of the following runes: summon tome, reveal, conceal, teleport, tisable technology, communicate, deafen, blind and stun.
-

Sacrifice

- Sacrifice rune allows you to sacrifice a living thing or a body to the Geometer of Blood. Monkeys and dead humans are the most basic sacrifices, they might or might not be enough to gain His favor. A living human is what a real sacrifice should be, however, you will need 3 people chanting the invocation to sacrifice a living person. -

Create a wall

- Invoking this rune solidifies the air above it, creating an an invisible wall. To remove the wall, simply invoke the rune again. -

Summon cultist

- This rune allows you to summon a fellow cultist to your location. The target cultist must be unhandcuffed ant not buckled to anything. You also need to have 3 people chanting at the rune to successfully invoke it. Invoking it takes heavy strain on the bodies of all chanting cultists.
-

Free a cultist

- This rune unhandcuffs and unbuckles any cultist of your choice, no matter where he is. Invoking it takes heavy strain on the bodies of all chanting cultists.
-

Deafen

- This rune temporarily deafens all non-cultists around you.
-

Blind

- This rune temporarily blinds all non-cultists around you. Very robust. Use together with the deafen rune to leave your enemies completely helpless.
-

Blood boil

- This rune boils the blood all non-cultists in visible range. The damage is enough to instantly critically hurt any person. You need 3 cultists invoking the rune for it to work. This rune is unreliable and may cause unpredicted effect when invoked. It also drains significant amount of your health when successfully invoked.
-

Communicate

- Invoking this rune allows you to relay a message to all cultists on the station and nearby space objects. -

Stun

- Unlike other runes, this ons is supposed to be used in talisman form. When invoked directly, it simply releases some dark energy, briefly stunning everyone around. When imbued into a talisman, you can force all of its energy into one person, stunning him so hard he cant even speak. However, effect wears off rather fast.
-

Equip Armor

- When this rune is invoked, either from a rune or a talisman, it will equip the user with the armor of the followers of Nar-Sie. To use this rune to its fullest extent, make sure you are not wearing any form of headgear, armor, gloves or shoes, and make sure you are not holding anything in your hands.
-

See Invisible

- When invoked when standing on it, this rune allows the user to see the the world beyond as long as he does not move.
- - - "} - - -/obj/item/weapon/tome/Topic(href,href_list[]) - if (src.loc == usr) - var/number = text2num(href_list["number"]) - if (usr.stat|| usr.restrained()) - return - switch(href_list["action"]) - if("clear") - words[words[number]] = words[number] - if("read") - if(usr.get_active_hand() != src) - return - usr << browse("[tomedat]", "window=Arcane Tome") - return - if("change") - words[words[number]] = input("Enter the translation for [words[number]]", "Word notes") in engwords - for (var/entry in words) - if ((words[entry] == words[words[number]]) && (entry != words[number])) - words[entry] = entry - notedat = {" -
Word translation notes
- [words[1]] is [words[words[1]]] Clear
- [words[2]] is [words[words[2]]] Clear
- [words[3]] is [words[words[3]]] Clear
- [words[4]] is [words[words[4]]] Clear
- [words[5]] is [words[words[5]]] Clear
- [words[6]] is [words[words[6]]] Clear
- [words[7]] is [words[words[7]]] Clear
- [words[8]] is [words[words[8]]] Clear
- [words[9]] is [words[words[9]]] Clear
- [words[10]] is [words[words[10]]] Clear
- "} - usr << browse("[notedat]", "window=notes") -// call(/obj/item/weapon/tome/proc/edit_notes)() - else - usr << browse(null, "window=notes") - return - -// proc/edit_notes() FUCK IT. Cant get it to work properly. - K0000 -// world << "its been called! [usr]" -// notedat = {" -//
Word translation notes
-// [words[1]] is [words[words[1]]] Clear
-// [words[2]] is [words[words[2]]] Clear
-// [words[3]] is [words[words[3]]] Clear
-// [words[4]] is [words[words[4]]] Clear
-// [words[5]] is [words[words[5]]] Clear
-// [words[6]] is [words[words[6]]] Clear
-// [words[7]] is [words[words[7]]] Clear
-// [words[8]] is [words[words[8]]] Clear
-// [words[9]] is [words[words[9]]] Clear
-// [words[10]] is [words[words[10]]] Clear
-// "} -// usr << "whatev" -// usr << browse(null, "window=tank") +/obj/item/weapon/tome/examine(mob/user) + ..() + if(iscultist(user)) + user << "The scriptures of the Geometer. Allows the scribing of runes and access of knowledge archives." /obj/item/weapon/tome/attack(mob/living/M, mob/living/user) - if(istype(M,/mob/dead)) + if(istype(M,/mob/dead/observer)) M.invisibility = 0 - user.visible_message( \ - "[user] drags the ghost to our plane of reality!", \ - "You drag the ghost to our plane of reality!" \ - ) + user.visible_message("[user] strikes the air with [src], and a spirit appears!", \ + "You drag the ghost to your plane of reality!") add_logs(user, M, "smacked", src) return if(!istype(M)) @@ -510,334 +77,203 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", M.reagents.add_reagent("unholywater",holy2unholy) add_logs(user, M, "smacked", src, " removing the holy water from them") return - M.take_organ_damage(0,rand(5,20)) //really lucky - 5 hits for a crit - M.visible_message("[user] beats [M] with the arcane tome!", \ - "[user] beats you with the tome, and you feel a searing heat inside you!") + M.take_organ_damage(0, 15) //Used to be a random between 5 and 20 + playsound(M, 'sound/weapons/sear.ogg', 50, 1) + M.visible_message("[user] strikes [M] with the arcane tome!", \ + "[user] strikes you with the tome, searing your flesh!") add_logs(user, M, "smacked", src) - -/obj/item/weapon/tome/attack_self(mob/living/user) - usr = user - if(!usr.canmove || usr.stat || usr.restrained()) - return - - if(!wordtravel) - runerandom() - if(iscultist(user)) - var/C = 0 - for(var/obj/effect/rune/N in world) - C++ - if (!istype(user.loc,/turf)) - user << "You do not have enough space to write a proper rune." - return - switch(alert("You open the tome",,"Commune","Scribe a rune", "Notes")) //Fuck the "Cancel" option. Rewrite the whole tome interface yourself if you want it to work better. And input() is just ugly. - K0000 - if("Cancel") - return - if("Commune") - if(usr.get_active_hand() != src) - return - var/input = stripped_input(usr, "Please choose a message to tell to the other acolytes.", "Voice of Blood", "") - if(!input) - return - cultist_commune(user, 1, 0, input) - return - if("Notes") - if(usr.get_active_hand() != src) - return - notedat = {" - Read the Arcane Tome.
-
Word translation notes
- [words[1]] is [words[words[1]]] Clear
- [words[2]] is [words[words[2]]] Clear
- [words[3]] is [words[words[3]]] Clear
- [words[4]] is [words[words[4]]] Clear
- [words[5]] is [words[words[5]]] Clear
- [words[6]] is [words[words[6]]] Clear
- [words[7]] is [words[words[7]]] Clear
- [words[8]] is [words[words[8]]] Clear
- [words[9]] is [words[words[9]]] Clear
- [words[10]] is [words[words[10]]] Clear
- "} // whoever screwed the tabbing on this originally is an asshole. -// call(/obj/item/weapon/tome/proc/edit_notes)() - user << browse("[notedat]", "window=notes") - return - if("Scribe a rune") //fixed more assbackward tabbing - if(usr.get_active_hand() != src) - return - if (C>=26+runedec+ticker.mode.cult.len) //including the useless rune at the secret room, shouldn't count against the limit of 25 runes - Urist - alert("The cloth of reality can't take that much of a strain. Remove some runes first!") - return - var/list/dictionary = list( - "convert" = list("join","blood","self"), - "wall" = list("destroy","travel","self"), - "blood boil" = list("destroy","see","blood"), - "blood drain" = list("travel","blood","self"), - "raise dead" = list("blood","join","hell"), - "summon narsie" = list("hell","join","self"), - "communicate" = list("self","other","technology"), - "emp" = list("destroy","see","technology"), - "manifest" = list("blood","see","travel"), - "summon tome" = list("see","blood","hell"), - "see invisible" = list("see","hell","join"), - "hide" = list("hide","see","blood"), - "reveal" = list("blood","see","hide"), - "astral journey" = list("hell","travel","self"), - "imbue" = list("hell","technology","join"), - "sacrifice" = list("hell","blood","join"), - "summon cultist" = list("join","other","self"), - "free cultist" = list("travel","technology","other"), - "deafen" = list("hide","other","see"), - "blind" = list("destroy","see","other"), - "stun" = list("join","hide","technology"), - "armor" = list("hell","destroy","other"), - "teleport" = list("travel","self"), - "teleport other" = list("travel","other"), - "summon shell" = list("travel","hell","technology") - ) - - - var/list/scribewords = list("none") - - var/list/english = list() - - for (var/entry in words) - if (words[entry] != entry) - english+=list(words[entry] = entry) - - for (var/entry in dictionary) - var/list/required = dictionary[entry] - if (length(english&required) == required.len) - scribewords += entry - - var/chosen_rune = null - - - if(usr) - chosen_rune = input ("Choose a rune to scribe.") in scribewords - if (!chosen_rune) - return - if (chosen_rune == "none") - user << "You decide against scribing a rune, perhaps you should take this time to study your notes." - return - if (chosen_rune == "teleport") - dictionary[chosen_rune] += input ("Choose a destination word") in english - if (chosen_rune == "teleport other") - dictionary[chosen_rune] += input ("Choose a destination word") in english - - if(user.get_active_hand() != src) - return - - for (var/mob/V in viewers(src)) - V.show_message("[user] slices open a finger and begins to chant and paint symbols on the floor.", 3, "You hear chanting.", 2) - user << "You slice open one of your fingers and begin drawing a rune on the floor whilst chanting the ritual that binds your life essence with the dark arcane energies flowing through the surrounding world." - user.take_overall_damage((rand(9)+1)/10) // 0.1 to 1.0 damage - if(do_after(user, 50, target = user)) - if(usr.get_active_hand() != src) - return - var/mob/living/carbon/human/H = user - var/obj/effect/rune/R = new /obj/effect/rune(user.loc) - user << "You finish drawing the arcane markings of the Geometer." - var/list/required = dictionary[chosen_rune] - R.word1 = english[required[1]] - R.word2 = english[required[2]] - R.word3 = english[required[3]] - R.check_icon() - R.blood_DNA = list() - R.blood_DNA[H.dna.unique_enzymes] = H.dna.blood_type +/obj/item/weapon/tome/attack_self(mob/user) + if(!iscultist(user)) + user << "[src] seems full of unintelligible shapes, scribbles, and notes. Is this some sort of joke?" + return + open_tome(user) + +/obj/item/weapon/tome/proc/open_tome(mob/user) + var/choice = alert(user,"You open the tome...",,"Commune","Scribe Rune","(More...)") + switch(choice) + if("(More...)") + var/choice2 = alert(user,"You open the tome...",,"(Back...)", "Information") + switch(choice2) + if("(Back...)") + return open_tome(user) + if("Information") + 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 - else - user << "The book seems full of illegible scribbles. Is this a joke?" - 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 itself (so long as it consents). A small description of each rune can be found below.

Do note that sometimes runes can be drawn incorrectly. Runes such as these \ + will be colorful and written in gibberish. They are malformed, and invoking them serves only to ignite the Geometer's wrath. Be cautious in your scribings.

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\"
\ +


"*/ + + text += "Rite of Translocation
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 \ + with the same keyword, it will choose randomly between all eligible runes and send the invoker to one of them.

" + + text += "Rite of Forced Translocation
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 += "Rite of Knowledge
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 += "Rite of Enlightenment
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 may take some time, depending on the amount of cultists nearby. It takes twenty seconds, with each additional cultist shaving \ + off ten seconds of the conversion. With three or more cultists, conversion is instantaneous. Once invoked, only the original user must remain. If the target is loyalty-implanted or has a null rod in \ + their possession, this will not work.

" + + text += "Rite of Tribute
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.

" + + text += "Rite of Resurrection
The Rite of Resurrection is a delicate rite that requires two corpses. To perform the ritual, place the corpse you wish to revive onto \ + the rune and the offering body adjacent to it. When the rune is invoked, the body to be sacrificed will turn to ashes, the life force flowing into the revival target. Assuming the target is not moved \ + within a few seconds, they will be brought back to life, healed of all ailments.

" + + text += "Rite of Obscurity
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 is unusuable directly.

" + + text += "Rite of True Sight
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 partially corporeal.

" + + text += "Rite of False Truths
Many crew men 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.

" + + text += "Rite of 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.

" + + text += "Rite of Astral Communion
The Rite of Astral Communion is perhaps the most ingenious rune that is usable by a single person. Upon invoking the rune, the \ + user's spirit will be ripped from their body. In this state, the user's physical body will be locked in place to the rune itself - any attempts to move it will result in the rune pulling it back. \ + The body will also take constant damage while in this form, and may even die. The user's spirit will contain their consciousness, and will allow them to freely wander the station as a ghost. This may \ + also be used to commune with the dead.

" + + text += "Rite of the Corporeal Shield
While simple, the Rite of the Corporeal Shield serves an important purpose in defense and hindering passage. When invoked, the \ + 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 += "Rite of the Unheard Whisper
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 += "Rite of the Unseen Glance
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 += "Rite of Disorientation
A somewhat empowered version of the Rite of the Unseen Glance, this rune will cause any non-cultists that can see the rune to become \ + disoriented, disabling them for a short time.

" + + text += "Rite of Joined Souls
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.

" + + text += "Rite of Binding
The Rite of Binding is the only way to create talismans. A blank sheet of paper must be on top of the rune, with a valid rune nearby. After \ + invoking it, the paper will be converted into a talisman, and the rune inlaid upon it.

" + + text += "Rite of Fabrication
The Rite of Fabrication is the main way of creating construct shells. To use it, one must place five sheets of plasteel on top of the rune \ + and invoke it. The sheets will them be twisted into a construct shell, ready to recieve a soul to occupy it.

" + + text += "Rite of Arming
The Rite of Arming will equip the user with invoker's robes, a backpack, a Nar-Sian longsword, and a pair of boots. Any items that cannot \ + be equipped will instead not be summoned regardless.

" + + text += "Rite of Leeching
The Rite of Leeching will drain the life of any non-cultist above the rune and heal the invoker for the same amount.

" + + text += "Rite of Boiling Blood
The Rite of Boiling Blood may be considered one of the most dangerous rites composed by the Nar-Sian cult. 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 += "Rite of Spectral Manifestation
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 += "Ritual of Dimensional Rending
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.


" + + text += "Talisman of Translocation
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 Knowledge
This talisman functions identically to the rune. It can be used once, then disappears.

" + + text += "Talismans of Obscurity, True Sight, and False Truths
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.

" -/obj/item/weapon/tome/attackby(obj/item/weapon/tome/T, mob/living/user, params) - if(istype(T, /obj/item/weapon/tome)) // sanity check to prevent a runtime error - switch(alert("Copy the runes from your tome?",,"Copy", "Cancel")) - if("cancel") - return - // var/list/nearby = viewers(1,src) //- Fuck this as well. No clue why this doesnt work. -K0000 - // if (T.loc != user) - // return - // for(var/mob/M in nearby) - // if(M == user) - for(var/entry in words) - words[entry] = T.words[entry] - user << "You copy the translation notes from your tome." + text += "Talisman of Disruption
This talisman functions like the Rite of Disruption, but with halved range. It disappears after one use.

" + text += "Talisman of Disorientation
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." -/obj/item/weapon/tome/examine(mob/user) - ..() - if(iscultist(user)) - user << "The scriptures of Nar-Sie, The One Who Sees, The Geometer of Blood. Contains the details of every ritual his followers could think of." + var/datum/browser/popup = new(user, "tome", "", 800, 600) + popup.set_content(text) + popup.open() + return 1 -/obj/item/weapon/tome/imbued //admin tome, spawns working runes without waiting - w_class = 2 - var/cultistsonly = 1 - attack_self(mob/user as mob) - if(src.cultistsonly && !iscultist(usr)) - return - if(!wordtravel) - runerandom() - if(user) - var/r - if (!istype(user.loc,/turf)) - user << "You do not have enough space to write a proper rune." - var/list/runes = list("teleport", "itemport", "tome", "armor", "convert", "tear in reality", "emp", "drain", "raise", "obscure", "reveal", "astral journey", "manifest", "imbue talisman", "sacrifice", "wall", "freedom", "cultsummon", "deafen", "blind", "bloodboil", "communicate", "stun", "summon shell") - r = input("Choose a rune to scribe", "Rune Scribing") in runes //not cancellable. - var/obj/effect/rune/R = new /obj/effect/rune - if(istype(user, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - R.blood_DNA = list() - R.blood_DNA[H.dna.unique_enzymes] = H.dna.blood_type - switch(r) - if("teleport") - var/list/words = list("ire", "ego", "nahlizet", "certum", "veri", "jatkaa", "balaq", "mgar", "karazet", "geeri") - var/beacon - if(usr) - beacon = input("Select the last rune", "Rune Scribing") in words - R.word1=wordtravel - R.word2=wordself - R.word3=beacon - R.loc = user.loc - R.check_icon() - if("itemport") - var/list/words = list("ire", "ego", "nahlizet", "certum", "veri", "jatkaa", "balaq", "mgar", "karazet", "geeri") - var/beacon - if(usr) - beacon = input("Select the last rune", "Rune Scribing") in words - R.word1=wordtravel - R.word2=wordother - R.word3=beacon - R.loc = user.loc - R.check_icon() - if("tome") - R.word1=wordsee - R.word2=wordblood - R.word3=wordhell - R.loc = user.loc - R.check_icon() - if("armor") - R.word1=wordhell - R.word2=worddestr - R.word3=wordother - R.loc = user.loc - R.check_icon() - if("convert") - R.word1=wordjoin - R.word2=wordblood - R.word3=wordself - R.loc = user.loc - R.check_icon() - if("tear in reality") - R.word1=wordhell - R.word2=wordjoin - R.word3=wordself - R.loc = user.loc - R.check_icon() - if("emp") - R.word1=worddestr - R.word2=wordsee - R.word3=wordtech - R.loc = user.loc - R.check_icon() - if("drain") - R.word1=wordtravel - R.word2=wordblood - R.word3=wordself - R.loc = user.loc - R.check_icon() - if("raise") - R.word1=wordblood - R.word2=wordjoin - R.word3=wordhell - R.loc = user.loc - R.check_icon() - if("obscure") - R.word1=wordhide - R.word2=wordsee - R.word3=wordblood - R.loc = user.loc - R.check_icon() - if("astral journey") - R.word1=wordhell - R.word2=wordtravel - R.word3=wordself - R.loc = user.loc - R.check_icon() - if("manifest") - R.word1=wordblood - R.word2=wordsee - R.word3=wordtravel - R.loc = user.loc - R.check_icon() - if("imbue talisman") - R.word1=wordhell - R.word2=wordtech - R.word3=wordjoin - R.loc = user.loc - R.check_icon() - if("sacrifice") - R.word1=wordhell - R.word2=wordblood - R.word3=wordjoin - R.loc = user.loc - R.check_icon() - if("reveal") - R.word1=wordblood - R.word2=wordsee - R.word3=wordhide - R.loc = user.loc - R.check_icon() - if("wall") - R.word1=worddestr - R.word2=wordtravel - R.word3=wordself - R.loc = user.loc - R.check_icon() - if("freedom") - R.word1=wordtravel - R.word2=wordtech - R.word3=wordother - R.loc = user.loc - R.check_icon() - if("cultsummon") - R.word1=wordjoin - R.word2=wordother - R.word3=wordself - R.loc = user.loc - R.check_icon() - if("deafen") - R.word1=wordhide - R.word2=wordother - R.word3=wordsee - R.loc = user.loc - R.check_icon() - if("blind") - R.word1=worddestr - R.word2=wordsee - R.word3=wordother - R.loc = user.loc - R.check_icon() - if("bloodboil") - R.word1=worddestr - R.word2=wordsee - R.word3=wordblood - R.loc = user.loc - R.check_icon() - if("communicate") - R.word1=wordself - R.word2=wordother - R.word3=wordtech - R.loc = user.loc - R.check_icon() - if("stun") - R.word1=wordjoin - R.word2=wordhide - R.word3=wordtech - R.loc = user.loc - R.check_icon() - if("summon shell") - R.word1=wordtravel - R.word2=wordhell - R.word3=wordtech - R.loc = user.loc - R.check_icon() +/obj/item/weapon/tome/proc/scribe_rune(mob/user) + var/chosen_keyword + var/rune_to_scribe + var/entered_rune_name + var/list/possible_runes = list() + for(var/T in typesof(/obj/effect/rune) - /obj/effect/rune/malformed - /obj/effect/rune) + 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 + if(!possible_runes.len) + return + entered_rune_name = input(user, "Choose a rite to scribe.", "Sigils of Power") as null|anything in possible_runes + for(var/T in typesof(/obj/effect/rune)) + var/obj/effect/rune/R = T + if(initial(R.cultist_name) == entered_rune_name) + rune_to_scribe = R + if(initial(R.req_keyword)) + var/the_keyword = stripped_input(usr, "Please enter a keyword for the rune.", "Enter Keyword", "") + if(!the_keyword) + return + chosen_keyword = the_keyword + break + if(!rune_to_scribe) + return + user.visible_message("[user] cuts open their arm and begins writing in their own blood!", \ + "You slice open your arm and begin drawing a sigil of the Geometer.") + if(iscarbon(user)) + var/mob/living/carbon/C = user + C.apply_damage(1, BRUTE, pick("l_arm", "r_arm")) + if(!do_after(user, 50, target = get_turf(user))) + return + user.visible_message("[user] creates a strange circle in their own blood.", \ + "You finish drawing the arcane markings of the Geometer.") + var/obj/effect/rune/R = new rune_to_scribe(get_turf(user)) + if(chosen_keyword) + R.keyword = chosen_keyword diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 28459980c9703..b0cfaeabe4d15 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -1,1053 +1,1013 @@ var/list/sacrificed = list() +var/list/non_revealed_runes = (typesof(/obj/effect/rune) - /obj/effect/rune/malformed - /obj/effect/rune ) + +/* + +This file contains runes. +Runes are used by the cult to cause many different effects and are paramount to their success. +They are drawn with an arcane tome in blood, and are distinguishable to cultists and normal crew by examining. +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 + +*/ /obj/effect/rune - - -///Teleport: Teleports the user to a random teleport rune with the same rune. Can be imbued into a talisman. - - -/obj/effect/rune/proc/teleport(key) - var/mob/living/user = usr - var/allrunesloc[] - allrunesloc = new/list() - var/index = 0 - // var/tempnum = 0 - for(var/obj/effect/rune/R in world) - if(R == src) - continue - if(R.word1 == wordtravel && R.word2 == wordself && R.word3 == key && R.z != ZLEVEL_CENTCOM) - index++ - allrunesloc.len = index - allrunesloc[index] = R.loc - if(index >= 5) - user << "You feel pain, as rune disappears in reality shift caused by too much wear of space-time fabric" - if (istype(user, /mob/living)) - user.take_overall_damage(5, 0) + name = "rune" + var/cultist_name = "basic rune" + desc = "An odd collection of symbols drawn in what seems to be blood." + var/cultist_desc = "A basic rune with no function." //This is shown to cultists who examine the rune in order to determine its true purpose. + anchored = 1 + icon = 'icons/obj/rune.dmi' + icon_state = "1" + unacidable = 1 + layer = TURF_LAYER + color = rgb(255,0,0) + 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/req_pylons = 0 + var/req_forges = 0 + var/req_archives = 0 + var/req_altars = 0 + + var/req_keyword = 0 //If the rune requires a keyword - go figure amirite + var/keyword //The actual keyword for the rune + +/obj/effect/rune/examine(mob/user) + ..() + 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]" + +/obj/effect/rune/attackby(obj/I, mob/user, params) + if(istype(I, /obj/item/weapon/tome) && iscultist(user)) + user << "You carefully erase [src]." qdel(src) - if(allrunesloc && index != 0) - if(istype(src,/obj/effect/rune)) - user.say("Sas[pick("'","`")]so c'arta forbici!")//Only you can stop auto-muting - else - user.whisper("Sas[pick("'","`")]so c'arta forbici!") - user.visible_message("[user] disappears in a flash of red light!", \ - "You feel as your body gets dragged through the dimension of Nar-Sie!", \ - "You hear a sickening crunch and sloshing of viscera.") - user.loc = allrunesloc[rand(1,index)] return - if(istype(src,/obj/effect/rune)) - return fizzle(user) //Use friggin manuals, Dorf, your list was of zero length. - else - call(/obj/effect/rune/proc/fizzle)() - return - - -//Subtype of teleport, teleports any items and mobs on top of the rune rather than the user themselves -/obj/effect/rune/proc/itemport(key) -// var/allrunesloc[] -// allrunesloc = new/list() -// var/index = 0 -// var/tempnum = 0 - var/culcount = 0 - var/runecount = 0 - var/obj/effect/rune/IP = null - var/mob/living/user = usr - for(var/obj/effect/rune/R in world) - if(R == src) - continue - if(R.word1 == wordtravel && R.word2 == wordother && R.word3 == key) - IP = R - runecount++ - if(runecount >= 2) - user << "You feel pain, as the rune disappears in reality shift caused by too much wear of space-time fabric" - if (istype(user, /mob/living)) - user.take_overall_damage(5, 0) + else if(istype(I, /obj/item/weapon/nullrod)) + user << "You disrupt the magic with [I]." qdel(src) - for(var/mob/living/C in orange(1,src)) - if(iscultist(C) && !C.stat) - culcount++ - if(user.loc==src.loc) - return fizzle(user) - if(culcount>=1) - user.say("Sas[pick("'","`")]so c'arta forbici tarem!") - user.visible_message("You feel air moving from the rune - like as it was swapped with somewhere else.", \ - "You feel air moving from the rune - like as it was swapped with somewhere else.", \ - "You smell ozone.") - for(var/obj/O in src.loc) - if(!O.anchored) - O.loc = IP.loc - for(var/mob/M in src.loc) - M.loc = IP.loc return + return - return fizzle(user) +/obj/effect/rune/attack_hand(mob/living/user) + if(!iscultist(user)) + user << "You aren't able to understand the words of [src]." + return + if(can_invoke(user)) + invoke(user) + else + fail_invoke(user) + +/* + +There are a few different procs each rune runs through when a cultist activates it. +can_invoke() is called when a cultist activates the rune with an empty hand. If there are multiple cultists, this rune determines if the required amount is nearby. +invoke() is the rune's actual effects. +fail_invoke() is called when the rune fails, via not enough people around or otherwise. Typically this just has a generic 'fizzle' effect. +structure_check() searches for nearby cultist structures required for the invocation. Proper structures are pylons, forges, archives, and altars. + +*/ + +/obj/effect/rune/proc/can_invoke(var/mob/living/user) + //This proc determines if the rune can be invoked at the time. If there are multiple required cultists, it will find all nearby cultists. + if(!structure_check(req_pylons, req_forges, req_archives, req_altars)) + return 0 + if(!keyword && req_keyword) + return 0 + if(req_cultists <= 1) + if(invocation) + user.say(invocation) + return 1 + else + var/cultists_in_range = 0 + for(var/mob/living/L in range(1, src)) + if(iscultist(L)) + var/mob/living/carbon/human/H = L + if(!istype(H)) + if(istype(L, /mob/living/simple_animal/construct)) + if(invocation) + L.say(invocation) + cultists_in_range++ + continue + if(L.stat || (H.disabilities & MUTE) || H.silent) + continue + if(invocation) + L.say(invocation) + cultists_in_range++ + if(cultists_in_range >= req_cultists) + return 1 + else + return 0 +/obj/effect/rune/proc/invoke(var/mob/living/user) + //This proc contains the effects of the rune as well as things that happen afterwards. If you want it to spawn an object and then delete itself, have both here. + +/obj/effect/rune/proc/fail_invoke(var/mob/living/user) + //This proc contains the effects of a rune if it is not invoked correctly, through either invalid wording or not enough cultists. By default, it's just a basic fizzle. + visible_message("The markings pulse with a small flash of red light, then fall dark.") + +/obj/effect/rune/proc/structure_check(var/rpylons, var/rforges, var/rarchives, var/raltars) + var/pylons = 0 + var/forges = 0 + var/archives = 0 + var/altars = 0 + for(var/obj/structure/cult/pylon in orange(3,src)) + pylons++ + for(var/obj/structure/cult/forge in orange(3,src)) + forges++ + for(var/obj/structure/cult/tome in orange(3,src)) + archives++ + for(var/obj/structure/cult/talisman in orange(3,src)) + altars++ + if(pylons >= rpylons && forges >= rforges && archives >= rarchives && altars >= raltars) + return 1 + return 0 + + +//Malformed Rune: This forms if a rune is not drawn correctly. Invoking it does nothing but hurt the user. +/obj/effect/rune/malformed + 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() + ..() + icon_state = "[rand(1,6)]" + color = rgb(rand(0,255), rand(0,255), rand(0,255)) + +/obj/effect/rune/malformed/invoke(mob/living/user) + user << "You feel your life force draining. The Geometer is displeased." + user.apply_damage(30, BRUTE) + qdel(src) -///Summon Tome: Summons a completely untranslated tome. +/mob/proc/null_rod_check() //The null rod, if equipped, will protect the holder from the effects of most runes + var/obj/item/weapon/nullrod/N = locate() in src + if(N) + return 1 + return 0 + +var/list/teleport_runes = list() +//Rite of Translocation: Warps the user to a random teleport rune with the same keyword. +/obj/effect/rune/teleport + cultist_name = "Rite of Translocation" + cultist_desc = "Warps the user to a random rune of the same keyword." + 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() + ..() + teleport_runes.Add(src) + +/obj/effect/rune/teleport/Destroy() + teleport_runes.Remove(src) + ..() + +/obj/effect/rune/teleport/invoke(mob/living/user) + var/list/potential_runes = list() + for(var/obj/effect/rune/teleport/T in teleport_runes) + if(T.keyword == src.keyword && T != src) + potential_runes.Add(T) + + if(!potential_runes.len) + user << "There are no runes with the same keyword!" + fail_invoke() + log_game("Teleport rune failed - no candidates with matching keyword") + return + var/obj/effect/rune/selected_rune = pick(potential_runes) + if(user.buckled) + user.buckled.unbuckle_mob() + user.visible_message("[user] vanishes in a flash of red light!", \ + "Your vision blurs, and you suddenly appear somewhere else.") + user.forceMove(get_turf(selected_rune)) + + +var/list/teleport_other_runes = list() +//Rite of Forced Translocation: Warps the target to a random teleport rune with the same keyword. +/obj/effect/rune/teleport_other + cultist_name = "Rite of Forced Translocation" + cultist_desc = "Warps the target to a random rune of the same keyword." + 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() + ..() + teleport_other_runes.Add(src) + +/obj/effect/rune/teleport_other/Destroy() + teleport_other_runes.Remove(src) + ..() + +/obj/effect/rune/teleport_other/invoke(mob/living/user) + var/list/potential_runes = list() + for(var/obj/effect/rune/teleport_other/T in teleport_other_runes) + if(T.keyword == src.keyword && T != src) + potential_runes.Add(T) + + if(!potential_runes.len) + user << "There are no runes with the same keyword!" + fail_invoke() + log_game("Teleport Other rune failed - no candidates with matching keyword") + return -/obj/effect/rune/proc/tomesummon() - if(istype(src,/obj/effect/rune)) - usr.say("N[pick("'","`")]ath reth sh'yro eth d'raggathnor!") - else - usr.whisper("N[pick("'","`")]ath reth sh'yro eth d'raggathnor!") - usr.visible_message("Rune disappears with a flash of red light, and in its place now a book lies.", \ - "You are blinded by the flash of red light! After you're able to see again, you see that now instead of the rune there's a book.", \ - "You hear a pop and smell ozone.") - if(istype(src,/obj/effect/rune)) - new /obj/item/weapon/tome(src.loc) + var/obj/effect/rune/selected_rune = pick(potential_runes) + var/mob/living/target + + var/list/targets = list() + for(var/mob/living/L in get_turf(src)) + if(L != user) + targets.Add(L) + if(!targets.len) + user << "There are no targets standing on the rune!" + fail_invoke() + log_game("Teleport Other rune failed - no targets on rune") + return + if(targets.len > 1) + target = input(user, "Choose a person to teleport.", "Rite of Forced Translocation") as null|anything in targets - user + if(!target) + fail_invoke() + return else - new /obj/item/weapon/tome(usr.loc) + target = targets[targets.len] + if(target.buckled) + target.buckled.unbuckle_mob() + target.visible_message("[target] vanishes in a flash of red light!", \ + "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 = "Rite of Knowledge" + cultist_desc = "Pulls an unstranslated 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) - return -///Convert: The primary method of gaining new followers. Requires three cultists, doesn't work on loyalty implanted people, captains, or chaplains. - - -/obj/effect/rune/proc/convert() - var/list/mob/living/cultsinrange = list() - for(var/mob/living/carbon/M in src.loc) +//Rite of Enlightenment: Converts a normal crewmember to the cult. Faster for every cultist nearby. +/obj/effect/rune/convert + cultist_name = "Rite of Enlightenment" + 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" + +/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") + return + var/time = 300 + for(var/mob/living/M in orange(1,src)) if(iscultist(M)) - continue - if(M.stat==2) - continue - for(var/mob/living/C in orange(1,src)) - if(iscultist(C) && !C.stat) //converting requires three cultists - cultsinrange += C - C.say("Mah[pick("'","`")]weyh pleggh at e'ntrath!") - if(cultsinrange.len >= 3) - M.visible_message("[M] writhes in pain as the markings below him glow a bloody red.", \ - "AAAAAAHHHH!", \ - "You hear an anguished scream.") - if(is_convertable_to_cult(M.mind)) - ticker.mode.add_cultist(M.mind) - M.mind.special_role = "Cultist" - M << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." - M << "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." - else - M << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." - M << "And not a single fuck was given, exterminate the cult at all costs." - if(ticker.mode.name == "cult") - if(M.mind == ticker.mode.sacrifice_target) - for(var/mob/living/carbon/human/cultist in cultsinrange) - cultist << "The Chosen One!!
KILL THE CHOSEN ONE!!!
" - return 0 - else - for(var/mob/living/carbon/human/cultist in cultsinrange) - cultist << "You need more brothers to overcome their lies and make them see Truth. " - return fizzle() - - -///Summon Nar-Sie: Summons the avatar of Nar-Sie to wreak havoc on the station. Will turn walls and floors to cult version and make anyone it touches into a harvester. - - -/obj/effect/rune/proc/tearreality() - var/list/mob/living/cultist_count = list() - var/mob/living/user = usr - user.say("Tok-lyr rqa'nap g[pick("'","`")]lt-ulotf!") - for(var/mob/M in range(1,src)) - if(iscultist(M) && !M.stat) - cultist_count += M - if(cultist_count.len >= 9) - if(ticker.mode.name == "cult") - var/datum/game_mode/cult/cultmode = ticker.mode - if(!("eldergod" in cultmode.cult_objectives)) - message_admins("[usr.real_name]([usr.ckey]) tried to summon a god when she didn't want to come out to play.") // Admin alert because you *KNOW* dickbutts are going to abuse this. - for(var/mob/M in cultist_count) - M.reagents.add_reagent("hell_water", 10) - M << "YOUR SOUL BURNS WITH YOUR ARROGANCE!!!" - return - else - for(var/obj_count=1, obj_count <= cultmode.cult_objectives.len, obj_count++) - if(cultmode.cult_objectives[obj_count] == "sacrifice") - if(cultmode.sacrifice_target) - if(!(cultmode.sacrifice_target in sacrificed)) - for(var/mob/M in cultist_count) - M << "Nar-sie refuses to be summoned while the sacrifice isn't complete." - return - cultmode.eldergod = 0 - var/narsie_type = /obj/singularity/narsie/large - // Moves narsie if she was already summoned. - var/obj/her = locate(narsie_type, SSobj.processing) - if(her) - her.loc = get_turf(src) + time -= 100 + time = Clamp(time, 0, 300) + if(time) + visible_message("[src] begins to glow with a sinister light...") + for(var/mob/living/M in orange(1,src)) + if(iscultist(M)) + if(M != user) + M << "You have aided [user] in invoking the [cultist_name]. You may now safely depart." + else + M << "You begin the enlightenment of [new_cultist]. This will take [time / 10] seconds and you must stand still." + new_cultist << "Your head begins to ache..." + if(!do_mob(user, new_cultist, time)) + visible_message("[src] reluctantly falls dark.") + new_cultist << "Your headache fades." return - // Otherwise... - new narsie_type(src.loc) // Summon her! - qdel(src) // Stops cultists from spamming the rune to summon narsie more than once. - // Might actually be wise to straight up del() this + if(new_cultist == ticker.mode.sacrifice_target) + for(var/mob/living/M in orange(1,src)) + if(iscultist(M)) + M << "\"I desire this one for myself. SACRIFICE THEM!\"" + fail_invoke() + log_game("Convert rune failed - convertee is sacrifice target") + 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 = "Rite of Tribute" + cultist_desc = "Sacrifices a crew member to the Geometer. May place them into a soul shard if their spirit remains in their body." + icon_state = "3" + invocation = "Barhah hra zar'garis!" + color = rgb(255, 255, 255) + grammar = "veri nahlizet certum" + var/rune_in_use = 0 + +/obj/effect/rune/sacrifice/invoke(mob/living/user) + if(rune_in_use) return - else - return fizzle() - - -///EMP: Lets out a large EMP blast - - -/obj/effect/rune/proc/emp(U,range_red) //range_red - var which determines by which number to reduce the default emp range, U is the source loc, needed because of talisman emps which are held in hand at the moment of using and that apparently messes things up -- Urist - if(istype(src,/obj/effect/rune)) - usr.say("Ta'gh fara[pick("'","`")]qha fel d'amar det!") - else - usr.whisper("Ta'gh fara[pick("'","`")]qha fel d'amar det!") - playsound(U, 'sound/items/Welder2.ogg', 25, 1) - var/turf/T = get_turf(U) - if(T) - T.hotspot_expose(700,125) - var/rune = src // detaching the proc - in theory - empulse(U, (range_red - 2), range_red) - qdel(rune) - -///Blood Drain: Deals 1-25 damage to someone on top of it and heals an equivalent amount of brute damage to the user. Can be stacked. Too much blood drain = blood hunger that must be sated. - -/obj/effect/rune/proc/drain() - var/drain = 0 - for(var/obj/effect/rune/R in world) - if(R.word1==wordtravel && R.word2==wordblood && R.word3==wordself) - for(var/mob/living/carbon/D in R.loc) - if(D.stat!=2) - var/bdrain = rand(1,25) - D << "You feel weakened." - D.take_overall_damage(bdrain, 0) - drain += bdrain - if(!drain) - return fizzle() - usr.say ("Yu[pick("'","`")]gular faras desdae. Havas mithum javara. Umathar uf'kal thenar!") - usr.visible_message("Blood flows from the rune into [usr]!", \ - "The blood starts flowing from the rune and into your frail mortal body. You feel... empowered.", \ - "You hear a liquid flowing.") - var/mob/living/user = usr - if(user.bhunger) - user.bhunger = max(user.bhunger-2*drain,0) - if(drain>=50) - user.visible_message("[user]'s eyes give off eerie red glow!", \ - "...but it wasn't nearly enough. You crave, crave for more. The hunger consumes you from within.", \ - "You hear a heartbeat.") - user.bhunger += drain - src = user - spawn() - for (,user.bhunger>0,user.bhunger--) - sleep(50) - user.take_overall_damage(3, 0) + rune_in_use = 1 + var/turf/T = get_turf(src) + var/list/possible_targets = list() + for(var/mob/living/M in T.contents) + if(!iscultist(M)) + possible_targets.Add(M) + var/mob/offering + if(possible_targets.len > 1) //If there's more than one target, allow choice + offering = input(user, "Choose an offering to sacrifice.", "Unholy Tribute") as null|anything in possible_targets + else if(possible_targets.len) //Otherwise, if there's a target at all, pick the only one + offering = possible_targets[possible_targets.len] + if(!offering) + rune_in_use = 0 return - user.heal_organ_damage(drain%5, 0) - drain-=drain%5 - for (,drain>0,drain-=5) - sleep(2) - user.heal_organ_damage(5, 0) - return - - -///Raise Dead: Requires two corpses. Brings one to life and gibs the other. - - -/obj/effect/rune/proc/raise() - var/mob/living/carbon/human/corpse_to_raise - var/mob/living/carbon/human/body_to_sacrifice - - var/is_sacrifice_target = 0 - for(var/mob/living/carbon/human/M in src.loc) - if(M.stat == DEAD) - if(ticker.mode.name == "cult" && M.mind == ticker.mode:sacrifice_target) - is_sacrifice_target = 1 - else - corpse_to_raise = M - if(M.key) - M.ghostize(1) //kick them out of their body - break - if(!corpse_to_raise) - if(is_sacrifice_target) - usr << "The Geometer of blood wants this mortal for himself." - return fizzle() - - - is_sacrifice_target = 0 - find_sacrifice: - for(var/obj/effect/rune/R in world) - if(R.word1==wordblood && R.word2==wordjoin && R.word3==wordhell) - for(var/mob/living/carbon/human/N in R.loc) - if(ticker.mode.name == "cult" && N.mind && N.mind == ticker.mode:sacrifice_target) - is_sacrifice_target = 1 + if(offering.null_rod_check()) + user << "Something is blocking the Geometer's magic!" + log_game("Sacrifice rune failed - target has null rod") + fail_invoke() + rune_in_use = 0 + return + if(((ishuman(offering) || isrobot(offering)) && offering.stat != DEAD) || ticker.mode.sacrifice_target == offering) //Requires three people to sacrifice living targets or the round's target + var/cultists_nearby = 1 + for(var/mob/living/M in orange(1,src)) + if(iscultist(M) && M != user) + cultists_nearby++ + M.say(invocation) + if(cultists_nearby < 3) + user << "You require three acolytes to sacrifice greater targets!" + fail_invoke() + log_game("Sacrifice rune failed - not enough acolytes and target is living") + rune_in_use = 0 + return + visible_message("[src] pulses blood red!") + color = rgb(255, 0, 0) + spawn(5) + color = initial(color) + sac(offering) + +/obj/effect/rune/sacrifice/proc/sac(mob/living/T) + var/sacrifice_fulfilled + if(T) + if(T.mind) + var/obj/item/device/soulstone/stone = new /obj/item/device/soulstone(get_turf(src)) + if(!stone.transfer_soul("FORCE", T, usr)) //If it cannot be added + qdel(stone) + if(!T) + rune_in_use = 0 + return + if(istype(T, /mob/living/simple_animal/pet/dog/corgi)) + for(var/mob/living/carbon/C in orange(1,src)) + if(iscultist(C)) + C << "Even dark gods from another plane have standards, sicko." + if(C.reagents) + C.reagents.add_reagent("hell_water", 2) + sacrificed.Add(T) + if(T == ticker.mode.sacrifice_target) + sacrifice_fulfilled = 1 + if(isrobot(T)) + playsound(T, 'sound/magic/Disable_Tech.ogg', 100, 1) + T.dust() //To prevent the MMI from remaining + else + playsound(T, 'sound/magic/Disintegrate.ogg', 100, 1) + T.gib() + for(var/mob/living/M in orange(1,src)) + if(iscultist(M)) + if(sacrifice_fulfilled) + M << "\"Yes! This is the one I desire! You have done well.\"" + else + if(ishuman(T) || isrobot(T)) + M << "\"I accept this sacrifice.\"" else - if(N.stat!= DEAD) - body_to_sacrifice = N - break find_sacrifice - - if(!body_to_sacrifice) - if (is_sacrifice_target) - usr << "The Geometer of blood wants that corpse for himself." + M << "\"I accept this meager sacrifice.\"" + rune_in_use = 0 + + +//Ritual of Dimensional Rending: Calls forth the avatar of Nar-Sie upon the station. +/obj/effect/rune/narsie + cultist_name = "Ritual of Dimensional Rending" + cultist_desc = "Tears apart dimensional barriers, calling forth the avatar of the Geometer." + invocation = "Tok-lyr rqa'nap g'olt-ulotf!" + 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 orange(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 - usr << "The sacrifical corpse is not dead. You must free it from this world of illusions before it may be used." - return fizzle() - - var/mob/dead/observer/ghost - for(var/mob/dead/observer/O in loc) - if(!O.client) continue - if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue - ghost = O - break - - if(!ghost) - usr << "You require a restless spirit which clings to this world. Beckon their prescence with the sacred chants of Nar-Sie." - return fizzle() - - for(var/obj/item/organ/limb/affecting in corpse_to_raise.organs) - affecting.heal_damage(1000, 1000, 0) - corpse_to_raise.setToxLoss(0) - corpse_to_raise.setOxyLoss(0) - corpse_to_raise.SetParalysis(0) - corpse_to_raise.SetStunned(0) - corpse_to_raise.SetWeakened(0) - corpse_to_raise.radiation = 0 - corpse_to_raise.stat = CONSCIOUS - corpse_to_raise.updatehealth() - corpse_to_raise.update_damage_overlays(0) - - corpse_to_raise.key = ghost.key //the corpse will keep its old mind! but a new player takes ownership of it (they are essentially possessed) - //This means, should that player leave the body, the original may re-enter - if(usr.real_name == "Herbert West") - usr.say("To life, to life, I bring them!") + 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 orange(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 + 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 - usr.say("Pasnar val'keriam usinar. Savrae ines amutan. Yam'toth remium il'tarat!") - corpse_to_raise.visible_message("[corpse_to_raise]'s eyes glow with a faint red as he stands up, slowly starting to breathe again.", \ - "Life... I'm alive again...", \ - "You hear a faint, slightly familiar whisper.") - body_to_sacrifice.visible_message("[body_to_sacrifice] is torn apart, a black smoke swiftly dissipating from his remains!", \ - "You feel a horrible sensation of being torn apart, and--", \ - "You hear a thousand voices, all crying in pain.") - body_to_sacrifice.gib() - corpse_to_raise << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." - corpse_to_raise << "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." - return - - -///Veil: Makes all surrounding runes invisible. They cannot be used directly but still used indirectly (i.e. teleport...) - + fail_invoke() + log_game("Summon Nar-Sie rune failed - gametype is not cult") + return -/obj/effect/rune/proc/obscure(rad) - var/S=0 - for(var/obj/effect/rune/R in orange(rad,src)) - if(R!=src) - R.invisibility=INVISIBILITY_OBSERVER - S=1 - if(S) - if(istype(src,/obj/effect/rune)) - usr.say("Kla[pick("'","`")]atu barada nikt'o!") - for (var/mob/V in viewers(src)) - V.show_message("The rune turns into gray dust, veiling the surrounding runes.", 3) - qdel(src) - else - usr.whisper("Kla[pick("'","`")]atu barada nikt'o!") - usr << "Your talisman turns into gray dust, veiling the surrounding runes." - for (var/mob/V in orange(1,src)) - if(V!=usr) - V.show_message("Dust emanates from [usr]'s hands for a moment.", 3) +//Rite of Resurrection: Requires two corpses. Revives one and gibs the other. +/obj/effect/rune/raise_dead + cultist_name = "Rite of Resurrection" + cultist_desc = "Requires two corpses. The one placed upon the rune is brought to life, the other is turned to ash." + invocation = null //Depends on the name of the user - see below + color = rgb(150, 0, 0) + grammar = "nahlizet certum veri" + +/obj/effect/rune/raise_dead/invoke(mob/living/user) + var/turf/T = get_turf(src) + var/mob/living/mob_to_sacrifice + var/mob/living/mob_to_revive + var/list/potential_sacrifice_mobs = list() + var/list/potential_revive_mobs = list() + for(var/mob/living/M in orange(1,src)) + if(!(M in T.contents) && M.stat == DEAD) + potential_sacrifice_mobs.Add(M) + if(!potential_sacrifice_mobs.len) + user << "There is no eligible sacrifices nearby!" + log_game("Raise Dead rune failed - no catalyst corpse") return - if(istype(src,/obj/effect/rune)) - return fizzle() - else - call(/obj/effect/rune/proc/fizzle)() + mob_to_sacrifice = input(user, "Choose a corpse to sacrifice.", "Corpse to Sacrifice") as null|anything in potential_sacrifice_mobs + for(var/mob/living/M in T.contents) + if(M.stat == DEAD) + potential_revive_mobs.Add(M) + if(!potential_revive_mobs.len) + user << "There is no eligible revival target on the rune!" + log_game("Raise Dead rune failed - no corpse to revived") return + mob_to_revive = input(user, "Choose a corpse to revive.", "Corpse to Revive") as null|anything in potential_revive_mobs - -///Astral Journey: Lets a player explore around as a ghost but does 10 brute damage for every tick they are like that. If they are moved from the rune they cannot return. - - -/obj/effect/rune/proc/ajourney() //some bits copypastaed from admin tools - Urist - if(usr.loc==src.loc) - var/mob/living/carbon/human/L = usr - usr.say("Fwe[pick("'","`")]sh mah erl nyag r'ya!") - usr.visible_message("[usr]'s eyes glow blue as \he freezes in place, absolutely motionless.", \ - "The shadow that is your spirit separates itself from your body. You are now in the realm beyond. While this is a great sight, being here strains your mind and body. Hurry...", \ - "You hear only complete silence for a moment.") - usr.ghostize(1) - L.ajourn = 1 - while(L) - if(L.key) - L.ajourn=0 - return - else - L.take_organ_damage(10, 0) - sleep(100) - return fizzle() - - -///Manifest: User must be standing on rune. When invoked, makes a culted human spawn. The user takes damage depending on how many humans there are. If the user moves, all manifested humans are killed. - - -/obj/effect/rune/proc/manifest() - var/obj/effect/rune/this_rune = src - src = null - if(usr.loc!=this_rune.loc) - return this_rune.fizzle() - var/mob/dead/observer/ghost - for(var/mob/dead/observer/O in this_rune.loc) - if(!O.client) continue - if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue - ghost = O - break - if(!ghost) - return this_rune.fizzle() - - usr.say("Gal'h'rfikk harfrandid mud[pick("'","`")]gib!") - var/mob/living/carbon/human/dummy/D = new(this_rune.loc) - usr.visible_message("A shape forms in the center of the rune. A shape of... a man.", \ - "A shape forms in the center of the rune. A shape of... a man.", \ - "You hear liquid flowing.") - D.real_name = "[pick(first_names_male)] [pick(last_names)]" - D.status_flags = CANSTUN|CANWEAKEN|CANPARALYSE|CANPUSH - - D.key = ghost.key - - if(ticker.mode.name == "cult") - ticker.mode:add_cultist(D.mind) + //Begin revival + if(!in_range(mob_to_sacrifice,src)) + user << "The sacrificial target has been moved!" + fail_invoke() + log_game("Raise Dead rune failed - catalyst corpse moved") + return + if(!(mob_to_revive in T.contents)) + user << "The corpse to revived has been moved!" + fail_invoke() + log_game("Raise Dead rune failed - revival target moved") + return + if(mob_to_sacrifice.stat != DEAD) + user << "The sacrifical target must be dead!" + fail_invoke() + log_game("Raise Dead rune failed - catalyst corpse is not dead") + return + if(user.name == "Herbert West") + user.say("To life, to life, I bring them!") else - ticker.mode.cult+=D.mind - - D.mind.special_role = "Cultist" - D << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." - D << "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/mob/living/user = usr - while(this_rune && user && user.stat==CONSCIOUS && user.client && user.loc==this_rune.loc) - user.take_organ_damage(1, 0) - sleep(30) - if(D) - D.visible_message("[D] slowly dissipates into dust and bones.", \ - "You feel pain, as bonds formed between your soul and this homunculus break.", \ - "You hear faint rustle.") - D.dust() - return - - -///Imbue Talisman: Put a compatible rune near this one and a paper on top of the imbue rune. Activate, and the compatible rune will be imbued into the paper. - + user.say("Pasnar val'keriam usinar. Savrae ines amutan. Yam'toth remium il'tarat!") + mob_to_sacrifice.visible_message("[mob_to_sacrifice] disintegrates into black mist. The mist lingers, and then flows into [mob_to_revive]!") + mob_to_sacrifice.dust() + sleep(20) + if(!mob_to_revive || mob_to_revive.stat != DEAD) + visible_message("The black mist rises and dissipates.") + return + mob_to_revive << "\"PASNAR SAVRAE YAM'TOTH. Arise.\"" + mob_to_revive.visible_message("[mob_to_revive] draws in a huge breath, red light shining from their eyes.", \ + "You awaken suddenly from the void. You're alive!") + mob_to_revive.revive() //This does remove disabilities and such, but the rune might actually see some use because of it! -/obj/effect/rune/proc/talisman()//only hide, emp, teleport, deafen, blind and tome runes can be imbued atm - var/obj/item/weapon/paper/newtalisman - var/unsuitable_newtalisman = 0 - for(var/obj/item/weapon/paper/P in src.loc) - if(!P.info) - newtalisman = P - break - else - unsuitable_newtalisman = 1 - if (!newtalisman) - if (unsuitable_newtalisman) - usr << "The blank is tainted. It is unsuitable." - return fizzle() - - var/obj/effect/rune/imbued_from - var/obj/item/weapon/paper/talisman/T - for(var/obj/effect/rune/R in orange(1,src)) - if(R==src) - continue - if(R.word1==wordtravel && R.word2==wordself) //teleport - T = new(src.loc) - T.imbue = "[R.word3]" - T.info = "[R.word3]" - imbued_from = R - break - if(R.word1==wordsee && R.word2==wordblood && R.word3==wordhell) //tome - T = new(src.loc) - T.imbue = "newtome" - imbued_from = R - break - if(R.word1==worddestr && R.word2==wordsee && R.word3==wordtech) //emp - T = new(src.loc) - T.imbue = "emp" - imbued_from = R - break - if(R.word1==wordblood && R.word2==wordsee && R.word3==worddestr) //conceal - T = new(src.loc) - T.imbue = "conceal" - imbued_from = R - break - if(R.word1==wordhell && R.word2==worddestr && R.word3==wordother) //armor - T = new(src.loc) - T.imbue = "armor" - imbued_from = R - break - if(R.word1==wordblood && R.word2==wordsee && R.word3==wordhide) //reveal - T = new(src.loc) - T.imbue = "revealrunes" - imbued_from = R - break - if(R.word1==wordhide && R.word2==wordother && R.word3==wordsee) //deafen - T = new(src.loc) - T.imbue = "deafen" - imbued_from = R - break - if(R.word1==worddestr && R.word2==wordsee && R.word3==wordother) //blind - T = new(src.loc) - T.imbue = "blind" - imbued_from = R - break - if(R.word1==wordself && R.word2==wordother && R.word3==wordtech) //communicat - T = new(src.loc) - T.imbue = "communicate" - imbued_from = R - break - if(R.word1==wordjoin && R.word2==wordhide && R.word3==wordtech) //communicat - T = new(src.loc) - T.imbue = "runestun" - imbued_from = R - break - if (imbued_from) - for (var/mob/V in viewers(src)) - V.show_message("The runes turn into dust, which then forms into an arcane image on the paper.", 3) - usr.say("H'drak v[pick("'","`")]loso, mir'kanas verbot!") - qdel(imbued_from) - qdel(newtalisman) - else - return fizzle() +/obj/effect/rune/raise_dead/fail_invoke() + for(var/mob/living/M in orange(1,src)) + if(M.stat == DEAD) + M.visible_message("[M] twitches.") + + +//Rite of Obscurity: Turns all runes within a 3-tile radius invisible. +/obj/effect/rune/hide_runes + cultist_name = "Rite of Obscurity" + cultist_desc = "Turns nearby runes invisible. They can be revealed by using the Rite of True Sight." + invocation = "Kla'atu barada nikt'o!" + icon_state = "3" + color = rgb(255,255,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 + qdel(src) -///Communicate: Static communication rune. Somewhat pointless with free communications with tomes. +//Rite of True Sight: Turns ghosts and obscured runes visible +/obj/effect/rune/true_sight + cultist_name = "Rite of True Sight" + cultist_desc = "Reveals all invisible objects nearby, from spirits to runes." + invocation = "Nikt'o barada kla'atu!" + icon_state = "6" + color = rgb(255, 162, 33) + 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) -/obj/effect/rune/proc/communicate() - var/input = stripped_input(usr, "Please enter a message to tell to the other acolytes.", "Voice of Blood", "") - if(!input) - if(istype(src)) - fizzle() - return 0 - else - return 0 - cultist_commune(usr , 1, 1, input) - return 1 - - -///Sacrifice: Gibs a target as an offering. Gives tome words as a reward and if the target has a mind, spawns a soul shard with their shade contained within. - - -/obj/effect/rune/proc/sacrifice() - var/list/mob/living/carbon/human/cultsinrange = list() - var/list/mob/living/carbon/human/victims = list() - for(var/mob/living/carbon/human/V in src.loc)//Checks for non-cultist humans to sacrifice - if(ishuman(V)) - if(!(iscultist(V))) - victims += V//Checks for cult status and mob type - for(var/obj/item/I in src.loc)//Checks for MMIs/brains/Intellicards - if(istype(I,/obj/item/organ/internal/brain)) - var/obj/item/organ/internal/brain/B = I - victims += B.brainmob - else if(istype(I,/obj/item/device/mmi)) - var/obj/item/device/mmi/B = I - victims += B.brainmob - else if(istype(I,/obj/item/device/aicard)) - for(var/mob/living/silicon/ai/A in I) - victims += A +//Rite of False Truths: Makes runes appear like crayon ones +/obj/effect/rune/make_runes_fake + cultist_name = "Rite of False Truths" + 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 = "Rite of Disruption" + cultist_desc = "Emits a large electromagnetic pulse, hindering electronics and disabling silicons." + invocation = "Ta'gh fara'qha fel d'amar det!" + icon_state = "1" + color = rgb(0, 0, 255) + grammar = "mgar karazet balaq" + +/obj/effect/rune/emp/invoke(mob/living/user) + visible_message("[src] wavers for a moment before vanishing.") for(var/mob/living/carbon/C in orange(1,src)) - if(iscultist(C) && !C.stat) - cultsinrange += C - C.say("Barhah hra zar[pick("'","`")]garis!") - if(cultsinrange.len >= 3) break //we only need to check for three alive cultists, loop breaks so their aren't extra cultists getting word rewards - for(var/mob/H in victims) - if (ticker.mode.name == "cult") - if(H.mind == ticker.mode:sacrifice_target) - if(cultsinrange.len >= 3) - sacrificed += H.mind - stone_or_gib(H) - for(var/mob/living/carbon/C in cultsinrange) - C << "The Geometer of Blood accepts this sacrifice, your objective is now complete." - C << "He is pleased!" - sac_grant_word(C) - sac_grant_word(C) - sac_grant_word(C) //Little reward for completing the objective - else - usr << "Your target's earthly bonds are too strong. You need more cultists to succeed in this ritual." - else - if(cultsinrange.len >= 3) - if(H.stat !=2) - for(var/mob/living/carbon/C in cultsinrange) - C << "The Geometer of Blood accepts this sacrifice." - sac_grant_word(C) - stone_or_gib(H) - else - if(prob(60)) - usr << "The Geometer of blood accepts this sacrifice." - sac_grant_word(usr) - else - usr << "The Geometer of blood accepts this sacrifice." - usr << "However, a mere dead body is not enough to satisfy Him." - stone_or_gib(H) - else - if(H.stat !=2) - usr << "The victim is still alive, you will need more cultists chanting for the sacrifice to succeed." - else - if(prob(60)) - usr << "The Geometer of blood accepts this sacrifice." - sac_grant_word(usr) - else - usr << "The Geometer of blood accepts this sacrifice." - usr << "However, a mere dead body is not enough to satisfy Him." - stone_or_gib(H) - else - if(cultsinrange.len >= 3) - if(H.stat !=2) - for(var/mob/living/carbon/C in cultsinrange) - C << "The Geometer of Blood accepts this sacrifice." - sac_grant_word(C) - stone_or_gib(H) - else - if(prob(60)) - usr << "The Geometer of blood accepts this sacrifice." - sac_grant_word(usr) - else - usr << "The Geometer of blood accepts this sacrifice." - usr << "However, a mere dead body is not enough to satisfy Him." - stone_or_gib(H) - else - if(H.stat !=2) - usr << "The victim is still alive, you will need more cultists chanting for the sacrifice to succeed." - else - if(prob(60)) - usr << "The Geometer of blood accepts this sacrifice." - sac_grant_word(usr) - else - usr << "The Geometer of blood accepts this sacrifice." - usr << "However, a mere dead body is not enough to satisfy Him." - stone_or_gib(H) - for(var/mob/living/carbon/monkey/M in src.loc) - if (ticker.mode.name == "cult") - if(M.mind == ticker.mode:sacrifice_target) - if(cultsinrange.len >= 3) - sacrificed += M.mind - for(var/mob/living/carbon/C in cultsinrange) - C << "The Geometer of Blood accepts this sacrifice, your objective is now complete." - C << "He is pleased!" - sac_grant_word(C) - sac_grant_word(C) - sac_grant_word(C) //Little reward for completing the objective - else - usr << "Your target's earthly bonds are too strong. You need more cultists to succeed in this ritual." - continue - else - if(prob(30)) - usr << "The Geometer of Blood accepts your meager sacrifice." - sac_grant_word(usr) - else - usr << "The Geometer of blood accepts this sacrifice." - usr << "However, a mere monkey is not enough to satisfy Him." - else - usr << "The Geometer of Blood accepts your meager sacrifice." - if(prob(30)) - ticker.mode.grant_runeword(usr) - stone_or_gib(M) - for(var/mob/victim in src.loc) //TO-DO: Move the shite above into the mob's own sac_act - see /mob/living/simple_animal/pet/dog/corgi/sac_act for an example - victim.sac_act(src, victim) //Sacrifice procs are now seperate per mob, this allows us to allow sacrifice on as many mob types as we want without making an already clunky system worse - -/obj/effect/rune/proc/sac_grant_word(mob/living/C) //The proc that which chooses a word rewarded for a successful sacrifice, sacrifices always give a currently unknown word if the normal checks pass - if(C.mind.cult_words.len != ticker.mode.allwords.len) // No point running if they already know everything - var/convert_word - var/pick_list = ticker.mode.allwords - C.mind.cult_words - convert_word = pick(pick_list) - ticker.mode.grant_runeword(C, convert_word) - -/obj/effect/rune/proc/stone_or_gib(mob/T) - var/obj/item/device/soulstone/stone = new /obj/item/device/soulstone(get_turf(src)) - if(!stone.transfer_soul("FORCE", T, usr)) //if it fails to add soul - qdel(stone) - if(T) - if(isrobot(T)) - T.dust()//To prevent the MMI from remaining - else - T.gib() + C << "You feel a minute vibration pass through you!" + playsound(get_turf(src), 'sound/items/Welder2.ogg', 25, 1) + empulse(src, 4, 8) //A bit less than an EMP grenade + qdel(src) -///Reveal: Reverses the Veil rune's effect, revealing all hidden runes. - - -/obj/effect/rune/proc/revealrunes(obj/W) - var/go=0 - var/rad - var/S=0 - if(istype(W,/obj/effect/rune)) - rad = 6 - go = 1 - if (istype(W,/obj/item/weapon/paper/talisman)) - rad = 4 - go = 1 - if (istype(W,/obj/item/weapon/storage/book/bible)) - rad = 1 - go = 1 - if(go) - for(var/obj/effect/rune/R in orange(rad,src)) - if(R!=src) - R.invisibility=0 - S=1 - if(S) - if(istype(W,/obj/item/weapon/storage/book/bible)) - usr << "Arcane markings suddenly glow from underneath a thin layer of dust!" - return - if(istype(W,/obj/effect/rune)) - usr.say("Nikt[pick("'","`")]o barada kla'atu!") - for (var/mob/V in viewers(src)) - V.show_message("The rune turns into red dust, reveaing the surrounding runes.", 3) - qdel(src) - return - if(istype(W,/obj/item/weapon/paper/talisman)) - usr.whisper("Nikt[pick("'","`")]o barada kla'atu!") - usr << "Your talisman turns into red dust, revealing the surrounding runes." - for (var/mob/V in orange(1,usr.loc)) - if(V!=usr) - V.show_message("Red dust emanates from [usr]'s hands for a moment.", 3) - return +//Rite of Astral Communion: Separates one's spirit from their body. They will take damage while it is active. +/obj/effect/rune/astral + cultist_name = "Rite of Astral Communion" + cultist_desc = "Severs the link between one's spirit and body. This effect is taxing and one's physical body will take damage while this is active." + invocation = "Fwe'sh mah erl nyag r'ya!" + icon_state = "1" + color = rgb(68, 47, 255) + var/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) + ..() + if(affecting) + user << "A translucent field encases [user] above the rune!" + +/obj/effect/rune/astral/invoke(mob/living/user) + if(rune_in_use) + user << "[src] cannot support more than one body!" + fail_invoke() + log_game("Astral Communion rune failed - more than one user") return - if(istype(W,/obj/effect/rune)) - return fizzle() - if(istype(W,/obj/item/weapon/paper/talisman)) - call(/obj/effect/rune/proc/fizzle)() + var/turf/T = get_turf(src) + if(!user in T.contents) + user << "You must be standing on top of [src]!" + fail_invoke() + log_game("Astral Communion rune failed - user not standing on rune") return - - -///Wall: Makes the rune dense and uncrossable. You can invoke it again to make it normal again. Deals 2 brute damage when used. - - -/obj/effect/rune/proc/wall() - usr.say("Khari[pick("'","`")]d! Eske'te tannin!") - src.density = !src.density - var/mob/living/user = usr - user.take_organ_damage(2, 0) - if(src.density) - usr << "Your blood flows into the rune, and you feel that the very space over the rune thickens." - else - usr << "Your blood flows into the rune, and you feel as the rune releases its grasp on space." - return - - -///Free Cultist: If the cultist is not walking free, makes it so. - - -/obj/effect/rune/proc/freedom() //MURICA ;_;7 - var/mob/living/user = usr - var/list/mob/living/cultists = new - for(var/datum/mind/H in ticker.mode.cult) - if (istype(H.current,/mob/living/carbon)) - cultists+=H.current - var/list/mob/living/users = new - for(var/mob/living/C in orange(1,src)) - if(iscultist(C) && !C.stat) - users+=C - if(users.len>=1) - var/mob/living/carbon/cultist = input("Choose the one who you want to free", "Followers of Geometer") as null|anything in (cultists - users) - if(!cultist) - return fizzle(user) - if (cultist == user) //just to be sure. + rune_in_use = 1 + affecting = user + user.color = src.color + user.visible_message("[user] freezes statue-still, their eyes glowing blue.", \ + "You see what lies beyond. All is revealed. While this is a wondrous experience, your physical form will waste away in this state. Hurry...") + user.ghostize(1) + while(user) + if(!affecting) + visible_message("[src] pulses gently before falling dark.") + affecting = null //In case it's assigned to a number or something + rune_in_use = 0 return - if(!(cultist.buckled || \ - cultist.handcuffed || \ - istype(cultist.wear_mask, /obj/item/clothing/mask/muzzle) || \ - (istype(cultist.loc, /obj/structure/closet)&&cultist.loc:welded) || \ - (istype(cultist.loc, /obj/structure/closet/secure_closet)&&cultist.loc:locked) || \ - (istype(cultist.loc, /obj/machinery/dna_scannernew)&&cultist.loc:locked) \ - )) - user << "The [cultist] is already free." + affecting.apply_damage(1, BRUTE) + if(!(user in T.contents)) + user.visible_message("A spectral tendril wraps around [user] and pulls them away!") + src.Beam(user,icon_state="b_beam",icon='icons/effects/beam.dmi',time=1) + user.forceMove(get_turf(src)) //NO ESCAPE :^) + if(user.key) + user.visible_message("[user] slowly relaxes, the glow in their eyes dimming.", \ + "You are re-united with your physical form. [src] releases its hold over you.") + user.color = initial(user.color) + user.Weaken(3) + rune_in_use = 0 + affecting = null return - if(cultist.buckled) - cultist.buckled.unbuckle_mob() - if (cultist.handcuffed) - cultist.handcuffed.loc = cultist.loc - cultist.handcuffed = null - cultist.update_inv_handcuffed() - if (cultist.legcuffed) - cultist.legcuffed.loc = cultist.loc - cultist.legcuffed = null - cultist.update_inv_legcuffed() - if (istype(cultist.wear_mask, /obj/item/clothing/mask/muzzle)) - cultist.unEquip(cultist.wear_mask) - if(istype(cultist.loc, /obj/structure/closet)&&cultist.loc:welded) - cultist.loc:welded = 0 - if(istype(cultist.loc, /obj/structure/closet/secure_closet)&&cultist.loc:locked) - cultist.loc:locked = 0 - if(istype(cultist.loc, /obj/machinery/dna_scannernew)&&cultist.loc:locked) - cultist.loc:locked = 0 - for(var/mob/living/C in users) - user.take_overall_damage(15, 0) - C.say("Khari[pick("'","`")]d! Gual'te nikka!") - qdel(src) - return fizzle(user) - - -///Summon Cultist: Requires 3 cultists, summons a cultist to the rune's location and does 25 brute to all users. - - -/obj/effect/rune/proc/cultsummon() - var/mob/living/user = usr - var/list/mob/living/carbon/cultists = new - for(var/datum/mind/H in ticker.mode.cult) - if (istype(H.current,/mob/living/carbon)) - cultists+=H.current - var/list/mob/living/users = new - for(var/mob/living/C in orange(1,src)) - if(iscultist(C) && !C.stat) - users+=C - if(users.len>=3) - var/mob/living/carbon/cultist = input("Choose the one who you want to summon", "Followers of Geometer") as null|anything in (cultists - user) - if(!cultist) - return fizzle(user) - if(cultist == user) //just to be sure. + if(user.stat == UNCONSCIOUS) + if(prob(10)) + var/mob/dead/observer/G = user.get_ghost() + if(G) + G << "You feel the link between you and your body weakening... you must hurry!" + if(user.stat == DEAD) + user.color = initial(user.color) + rune_in_use = 0 + affecting = null + var/mob/dead/observer/G = user.get_ghost() + if(G) + G << "You suddenly feel your physical form pass on. [src]'s exertion has killed you!" return - if(cultist.buckled || cultist.handcuffed || (!isturf(cultist.loc) && !istype(cultist.loc, /obj/structure/closet))) - user << "You cannot summon the [cultist], for his shackles of blood are strong" - return fizzle(user) - cultist.loc = src.loc - cultist.Weaken(5) - cultist.regenerate_icons() - for(var/mob/living/C in orange(1,src)) - if(iscultist(C) && !C.stat) - C.say("N'ath reth sh'yro eth d[pick("'","`")]rekkathnor!") - C.take_overall_damage(25, 0) - user.visible_message("Rune disappears with a flash of red light, and in its place now a body lies.", \ - "You are blinded by the flash of red light! After you're able to see again, you see that now instead of the rune there's a body.", \ - "You hear a pop and smell ozone.") - qdel(src) - return fizzle(user) - - -///Deafen: Makes all nearby non-cultists deaf. - - -/obj/effect/rune/proc/deafen() - if(istype(src,/obj/effect/rune)) - var/affected = 0 - for(var/mob/living/carbon/C in range(7,src)) - if (iscultist(C)) - continue - var/obj/item/weapon/nullrod/N = locate() in C - if(N) - continue - C.adjustEarDamage(0, 50) - C.show_message("The world around you suddenly becomes quiet.", 3) - affected++ - if(prob(1) && ishuman(C)) - C.dna.add_mutation(DEAFMUT) - if(affected) - usr.say("Sti[pick("'","`")] kaliedir!") - usr << "The world becomes quiet as the deafening rune dissipates into fine dust." - qdel(src) - else - return fizzle() - else - var/affected = 0 - for(var/mob/living/carbon/C in range(7,usr)) - if (iscultist(C)) - continue - var/obj/item/weapon/nullrod/N = locate() in C - if(N) - continue - C.adjustEarDamage(0, 30) - //talismans is weaker. - C.show_message("The world around you suddenly becomes quiet.", 3) - affected++ - if(affected) - usr.whisper("Sti[pick("'","`")] kaliedir!") - usr << "Your talisman turns into gray dust, deafening everyone around." - for (var/mob/V in orange(1,src)) - if(!(iscultist(V))) - V.show_message("Dust flows from [usr]'s hands for a moment, and the world suddenly becomes quiet..", 3) - return - - -///Blind: Makes all non-cultists nearby blind. Combine with Deafen to make the entire shuttle go into a panic and laugh as they bumble around. + sleep(10) + rune_in_use = 0 + + +//Rite of the Corporeal Shield: When invoked, becomes solid and cannot be passed. Invoke again to undo. +/obj/effect/rune/wall + cultist_name = "Rite of the Corporeal Shield" + cultist_desc = "When invoked, makes the rune block passage. Can be invoked again to reverse this." + invocation = "Khari'd! Eske'te tannin!" + icon_state = "1" + grammar = "mgar ire ego" + +/obj/effect/rune/wall/examine(mob/user) + ..() + if(density) + user << "There is a barely perceptible shimmering of the air above [src]." + +/obj/effect/rune/wall/invoke(mob/living/user) + density = !density + user.visible_message("[user] places their hands on [src], and [density ? "the air above it begins to shimmer" : "the shimmer above it fades"].", \ + "You channel your life energy into [src], [density ? "preventing" : "allowing"] passage above it.") + if(iscarbon(user)) + var/mob/living/carbon/C = user + C.apply_damage(2, BRUTE, pick("l_arm", "r_arm")) + + +//Rite of the Unheard Whisper: Deafens all non-cultists nearby. +/obj/effect/rune/deafen + cultist_name = "Rite of the Unheard Whisper" + cultist_desc = "Causes all non-followers nearby to lose their hearing." + invocation = "Sti kaliedir!" + grammar = "geeri jatkaa karazet" + +/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) -/obj/effect/rune/proc/blind() - if(istype(src,/obj/effect/rune)) - var/affected = 0 - for(var/mob/living/carbon/C in viewers(src)) - if (iscultist(C)) - continue - var/obj/item/weapon/nullrod/N = locate() in C - if(N) - continue +//Rite of the Unseen Glance: Blinds all non-cultists nearby. +/obj/effect/rune/blind + cultist_name = "Rite of the Unseen Glance" + cultist_desc = "Causes all non-followers nearby to lose their sight." + invocation = "Sti kaliesin!" + icon_state = "1" + color = rgb(0, 255, 0) + 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.flash_eyes(1, 1) C.eye_blurry += 50 C.eye_blind += 20 - if(prob(5)) - C.disabilities |= NEARSIGHT - if(prob(10)) - C.disabilities |= BLIND - C.show_message("Suddenly you see red flash that blinds you.", 3) - affected++ - if(affected) - usr.say("Sti[pick("'","`")] kaliesin!") - usr << "The rune flashes, blinding those who not follow the Nar-Sie, and dissipates into fine dust." - qdel(src) - else - return fizzle() - else - var/affected = 0 - for(var/mob/living/carbon/C in view(2,usr)) - if (iscultist(C)) - continue - var/obj/item/weapon/nullrod/N = locate() in C - if(N) - continue - C.eye_blurry += 30 - C.eye_blind += 10 - //talismans is weaker. - affected++ - C.show_message("You feel a sharp pain in your eyes, and the world disappears into darkness..", 3) - if(affected) - usr.whisper("Sti[pick("'","`")] kaliesin!") - usr << "Your talisman turns into gray dust, blinding those who not follow the Nar-Sie." - return + qdel(src) -///Blood Boil: Every non-cultist nearby will take 51 burn and 51 brute damage. 5% chance for them to gib as well. Users will take 15 brute. 10% chance for the rune to blow up. +//Rite of Disorientation: Stuns all non-cultists nearby for a brief time +/obj/effect/rune/stun + cultist_name = "Rite of Disorientation" + cultist_desc = "Stuns all nearby non-followers for a brief time." + invocation = "Fuu ma'jin!" + icon_state = "2" + color = rgb(150, 0, 255) + 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) + qdel(src) -/obj/effect/rune/proc/bloodboil() //cultists need at least one DANGEROUS rune. Even if they're all stealthy. - var/culcount = 0 +//Rite of Joined Souls: Summons a single cultist. Requires 2 cultists. +/obj/effect/rune/summon + cultist_name = "Rite of Joined Souls" + 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() + for(var/datum/mind/M in ticker.mode.cult) + cultists.Add(M.current) + var/mob/living/cultist_to_summon = input("Who do you wish to call to [src]?", "Followers of the Geometer") as null|anything in (cultists - user) + if(!cultist_to_summon) + user << "You require a summoning target!" + fail_invoke() + log_game("Summon Cultist rune failed - no target") + return + if(!iscultist(cultist_to_summon)) + user << "[cultist_to_summon] is not a follower of the Geometer!" + fail_invoke() + log_game("Summon Cultist rune failed - no target") + return + if(cultist_to_summon.buckled) + cultist_to_summon.buckled.unbuckle_mob() + 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.stat) - culcount++ - if(culcount>=3) - for(var/mob/living/carbon/M in viewers(usr)) - if(iscultist(M)) - continue - var/obj/item/weapon/nullrod/N = locate() in M - if(N) - continue - M.take_overall_damage(51,51) - M << "Your blood boils!" - for(var/obj/effect/rune/R in view(src)) - if(prob(10)) - explosion(R.loc, -1, 0, 1, 5) - for(var/mob/living/carbon/human/C in orange(1,src)) - if(iscultist(C) && !C.stat) - C.say("Dedo ol[pick("'","`")]btoh!") - C.take_overall_damage(15, 0) - qdel(src) - else - return fizzle() - return - + if(iscultist(C)) + C.apply_damage(10, BRUTE, "head") + cultist_to_summon.loc = get_turf(src) + qdel(src) -///Stun: Everyone nearby would be stunned for a -very- short time. If used in a talisman, it stuns and mutes a single target. +//Rite of Binding: Turns a nearby rune and a paper on top of the rune to a talisman, if both are valid. +/obj/effect/rune/imbue + cultist_name = "Rite of Binding" + cultist_desc = "Transforms papers and valid runes into talismans." + invocation = "H'drak v'loso, mir'kanas verbot!" + icon_state = "3" + color = rgb(150, 0, 255) + grammar = "veri balaq certum" -/obj/effect/rune/proc/runestun(mob/living/T) - if(istype(src,/obj/effect/rune)) ///When invoked as rune, flash and stun everyone around. - usr.say("Fuu ma[pick("'","`")]jin!") - for(var/mob/living/L in viewers(src)) +/obj/effect/rune/imbue/invoke(mob/living/user) + var/turf/T = get_turf(src) + var/list/papers_on_rune = list() + for(var/obj/item/weapon/paper/P in T) + if(!P.info) + papers_on_rune.Add(P) + if(!papers_on_rune.len) + user << "There must be a blank paper on top of [src]!" + fail_invoke() + log_game("Talisman Imbue rune failed - no blank papers on rune") + return + var/obj/item/weapon/paper/paper_to_imbue = pick(papers_on_rune) + var/list/nearby_runes = list() + for(var/obj/effect/rune/R in orange(1,src)) + nearby_runes.Add(R) + if(!nearby_runes.len) + user << "There are no runes near [src]!" + fail_invoke() + log_game("Talisman Imbue rune failed - no nearby runes") + return + var/obj/effect/rune/picked_rune = pick(nearby_runes) + var/list/split_rune_type = text2list("[picked_rune.type]", "/") + var/imbue_type = split_rune_type[split_rune_type.len] + var/talisman_type = text2path("/obj/item/weapon/paper/talisman/[imbue_type]") + if(ispath(talisman_type)) + var/obj/item/weapon/paper/talisman/TA = new talisman_type(get_turf(src)) + if(istype(picked_rune, /obj/effect/rune/teleport)) + var/obj/effect/rune/teleport/TR = picked_rune + var/obj/item/weapon/paper/talisman/teleport/TT = TA + TT.keyword = TR.keyword + else + user << "The chosen rune was not a valid target!" + fail_invoke() + log_game("Talisman Imbue rune failed - chosen rune invalid") + return + visible_message("[picked_rune] crumbles to dust, and bloody images form themselves on [paper_to_imbue].") + if(iscarbon(user)) + var/mob/living/carbon/C = user + C.apply_damage(5, BRUTE, pick("l_arm", "r_arm")) + else + user.adjustBruteLoss(5) + qdel(paper_to_imbue) + qdel(picked_rune) + + +//Rite of Fabrication: Creates a construct shell out of 5 metal sheets. +/obj/effect/rune/construct_shell + cultist_name = "Rite of Fabrication" + cultist_desc = "Turns five plasteel sheets into an empty construct shell, suitable for containing a soul shard." + invocation = "Ethra p'ni dedol!" + 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) + for(var/obj/item/stack/sheet/S in T) + if(istype(S, /obj/item/stack/sheet/plasteel)) + var/obj/item/stack/sheet/plasteel/M = S + if(M.amount >= 5) + new /obj/structure/constructshell(T) + M.visible_message("[M] bends and twists into a new form!") + M.amount -= 5 + if(M.amount <= 0) + qdel(M) + qdel(src) + return + else + user << "There must be at least five sheets of plasteel on [src]!" + fail_invoke() + log_game("Construct Shell rune failed - not enough plasteel sheets") + return - if(iscarbon(L)) - var/mob/living/carbon/C = L - flick("e_flash", C.flash) - C.stuttering = 1 - C.Weaken(1) - C.Stun(1) - C.show_message("The rune explodes in a bright flash.", 3) - else if(issilicon(L)) - var/mob/living/silicon/S = L - S.Weaken(5) - S.show_message("!@(%* BZZZZZT !@(%!)$", 3) - qdel(src) - else ///When invoked as talisman, stun and mute the target mob. - usr.say("Dream sign ''Evil sealing talisman'[pick("'","`")]!") - var/obj/item/weapon/nullrod/N = locate() in T - if(N) - for(var/mob/O in viewers(T, null)) - O.show_message(text("[] invokes a talisman at [], but they are unaffected!", usr, T), 1) - else - for(var/mob/O in viewers(T, null)) - O.show_message(text("[] invokes a talisman at []", usr, T), 1) - - if(issilicon(T)) - T.Weaken(10) - - else if(iscarbon(T)) - var/mob/living/carbon/C = T - flick("e_flash", C.flash) - C.silent += 15 - C.Weaken(10) - C.Stun(10) - return +//Rite of Arming: Creates cult robes, a trophy rack, and a cult sword on the rune. +/obj/effect/rune/armor + cultist_name = "Rite of Arming" + cultist_desc = "Equips the user with robes, shoes, a backpack, and a longsword. Items that cannot be equipped will not be summoned." + 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!") + user.equip_to_slot_or_del(new /obj/item/clothing/head/culthood/alt(user), slot_head) + user.equip_to_slot_or_del(new /obj/item/clothing/suit/cultrobes/alt(user), slot_wear_suit) + user.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult/alt(user), slot_shoes) + user.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/cultpack(user), slot_back) + user.put_in_hands(new /obj/item/weapon/melee/cultblade(user)) + qdel(src) -///Armor: The user will be armed with cultist garb, a trophy rack, and a high-damage sword. If items are in these slots, they will not be equipped and simply deleted. - - -/obj/effect/rune/proc/armor() - var/list/armors = list("zealot") - var/armorworn - var/mob/living/carbon/human/user = usr - if(istype(user.wear_suit, /obj/item/clothing/suit/wizrobe) && istype(user.head, /obj/item/clothing/head/wizard)) - armors += "summoner" - if(istype(user.wear_suit, /obj/item/clothing/suit/space) && istype(user.head, /obj/item/clothing/head/helmet/space)) - armors += "traveler" - if(istype(user.wear_suit, /obj/item/clothing/suit/space/captain) && istype(user.head, /obj/item/clothing/head/helmet/space/captain)) - armors += "marauder" - if(istype(user.wear_suit, /obj/item/clothing/suit/armor/reactive)) - armors += "trickster" - if(istype(user.wear_suit, /obj/item/clothing/suit/toggle/labcoat/cmo)) - armors += "physician" - if(istype(src,/obj/effect/rune)) - armorworn = input ("Choose your attire.") in armors - else - armorworn = "zealot" - if (armorworn == "zealot") - usr.say("N'ath reth sh'yro eth d[pick("'","`")]raggathnor!") - user.equip_to_slot_or_del(new /obj/item/clothing/head/culthood/alt(user), slot_head) - user.equip_to_slot_or_del(new /obj/item/clothing/suit/cultrobes/alt(user), slot_wear_suit) - user.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult(user), slot_shoes) - user.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/cultpack(user), slot_back) - user.put_in_hands(new /obj/item/weapon/melee/cultblade(user)) - usr.visible_message("\red The rune disappears with a flash of red light, and a set of armor appears on [usr]...", \ - "\red You are blinded by the flash of red light! After you're able to see again, you see that you are now wearing a set of armor.") - if (armorworn == "summoner" || armorworn == "trickster" || armorworn == "physician") - usr.say("Uln Shogg Hafh[pick("'","`")]drn!") - user << "\red You quietly prick your finger and make a pact with the geometer of blood to acquire more power." - user.take_overall_damage(rand(5,20)) - qdel(user.head) - qdel(user.wear_suit) - user.equip_to_slot_or_del(new /obj/item/clothing/head/magus(user), slot_head) - user.equip_to_slot_or_del(new /obj/item/clothing/suit/magusred(user), slot_wear_suit) - user.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult(user), slot_shoes) - user.spellremove(user) - usr.visible_message("\red The rune disappears with a flash of red light, and a set of robes appears on [usr]...", \ - "\red You are blinded by the flash of red light! After you're able to see again, you see that you are now wearing a set of robes.") - if (armorworn == "summoner") - user.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/soulstone/cult(user) - user.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/construct/lesser/cult(user) - if (armorworn == "trickster") - user.put_in_hands(new /obj/item/weapon/gun/magic/wand/door(user)) - user.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/turf_teleport/blink/cult(user) - if (armorworn == "physician") - user.put_in_hands(new /obj/item/weapon/gun/magic/wand/resurrection(user)) - if (armorworn == "traveler" || armorworn == "marauder") - usr.say("Tharanak n[pick("'","`")]ghft!") - qdel(user.head) - qdel(user.wear_suit) - user.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/cult(user), slot_head) - user.equip_to_slot_or_del(new /obj/item/clothing/suit/space/cult(user), slot_wear_suit) - user.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult(user), slot_shoes) - user.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/cultpack(user), slot_back) - user.put_in_hands(new /obj/item/weapon/melee/cultblade(user)) - user.spellremove(user) - usr.visible_message("\red The rune disappears with a flash of red light, and an armored space suit appears on [usr]...", \ - "\red You are blinded by the flash of red light! After you're able to see again, you see that you are now wearing an armored space suit.") - if (armorworn == "marauder") - user.spellremove(user) - user.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/creature/cult(user) +//Rite of Leeching: Deals brute damage to the target and heals the same amount to the invoker. +/obj/effect/rune/leeching + cultist_name = "Rite of Leeching" + cultist_desc = "Drains the life of the target on the rune, restoring it to the user." + invocation = "Yu'gular faras desdae. Havas mithum javara. Umathar uf'kal thenar!" //that's a mouthful + 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) + var/list/potential_targets = list() + for(var/mob/living/carbon/M in T) + if(M.stat != DEAD && M != user) + potential_targets.Add(M) + if(!potential_targets.len) + user << "There must be a valid target on the rune!" + fail_invoke() + log_game("Leeching rune failed - no valid targets") + return + var/mob/living/carbon/target = pick(potential_targets) + var/drained_amount = rand(5,25) + target.apply_damage(drained_amount, BRUTE, "chest") + user.adjustBruteLoss(-drained_amount) + target << "You feel extremely weak." + user.visible_message("Blood flows from the rune into [user]!", \ + "[target]'s blood flows into you, healing your wounds and revitalizing your spirit.") + + +//Rite of Boiling Blood: Deals extremely high amounts of damage to non-cultists nearby +/obj/effect/rune/blood_boil + cultist_name = "Rite of Boiling Blood" + cultist_desc = "Boils the blood of non-believers who can see the rune, dealing extreme amounts of damage." + invocation = "Dedo ol'btoh!" + icon_state = "4" + color = rgb(255, 0, 0) + req_cultists = 3 + grammar = "mgar karazet nahlizet" + +/obj/effect/rune/blood_boil/invoke(mob/living/user) + visible_message("[src] briefly bubbles before exploding!") + for(var/mob/living/carbon/C in viewers(src)) + if(!iscultist(C)) + if(C.null_rod_check()) + C << "The null rod suddenly burns hotly before returning to normal!" + continue + C << "Agonizing heat overwhelms you!" + C.take_overall_damage(51,51) + for(var/mob/living/carbon/M in orange(1,src)) + if(iscultist(M)) + M.apply_damage(15, BRUTE, pick("l_arm", "r_arm")) + M << "[src] saps your strength!" + explosion(get_turf(src), -1, 0, 1, 5) qdel(src) - return -///Summon Shell: Summons a construct shell if there's four plasteel sheets on top of the rune +//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 = "Rite of Spectral Manifestation" + cultist_desc = "Manifests a spirit as a servant of the Geometer. The invoker must not move from atop the rune, and will take damage for each summoned spirit." + 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))) + user << "You must be standing on [src]!" + fail_invoke() + log_game("Manifest rune failed - user not standing on rune") + return + var/list/ghosts_on_rune = list() + for(var/mob/dead/observer/O in get_turf(src)) + if(O.client) + ghosts_on_rune.Add(O) + if(!ghosts_on_rune.len) + user << "There are no spirits near [src]!" + fail_invoke() + log_game("Manifest rune failed - no nearby ghosts") + return + var/mob/dead/observer/ghost_to_spawn = pick(ghosts_on_rune) + var/mob/living/carbon/human/new_human = new(get_turf(src)) + new_human.real_name = ghost_to_spawn.real_name + new_human.alpha = 150 //Makes them translucent + visible_message("A cloud of red mist forms above [src], and from within steps... a man.") + user << "Your blood begins flowing into [src]. You must remain in place and conscious to maintain the forms of those summoned. This will hurt you slowly but surely..." + new_human.key = ghost_to_spawn.key + ticker.mode.add_cultist(new_human.mind) + new_human << "You are a servant of the Geometer. You have been made semi-corporeal by the cult, and you are to serve them at all costs." + + while(user in get_turf(src)) + if(user.stat) + break + user.apply_damage(1, BRUTE) + sleep(30) -/obj/effect/rune/proc/summon_shell() // Summons a construct shell - for(var/obj/item/stack/sheet/plasteel/PS in src.loc) //I could probably combine the amounts but I'm too lazy to compensate for others' lazyness - if(PS.amount >= 4) // may need increasing? - usr.say("Eth ra p'ni[pick("'","`")]dedo ol!") //I have no idea if these are written in a proper made up language or just Urist smacking his face on the keyboard - new /obj/structure/constructshell(src.loc) -//? PS.remove_amount(4) //TO-DO: Write a proc for removing sheets from a stack and deleting when stack is empty... why doesnt this exist yet?? - PS.amount -= 4 - if(PS.amount <= 0) - qdel(PS) - qdel(src) - return 1 - return fizzle() + if(new_human) + new_human.visible_message("[new_human] suddenly dissolves into bones and ashes.", \ + "Your link to the world fades. Your form breaks apart.") + for(var/obj/I in new_human) + new_human.unEquip(I) + new_human.dust() diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm index 76e97bc7371d1..2a63281e1fb44 100644 --- a/code/game/gamemodes/cult/talisman.dm +++ b/code/game/gamemodes/cult/talisman.dm @@ -1,125 +1,256 @@ -/obj/item/weapon/paper/talisman - icon_state = "paper_talisman" - var/imbue = null - var/uses = 0 - - attack_self(mob/living/user) - if(iscultist(user)) - var/delete = 1 - switch(imbue) - if("newtome") - call(/obj/effect/rune/proc/tomesummon)() - if("armor") - call(/obj/effect/rune/proc/armor)() - if("emp") - call(/obj/effect/rune/proc/emp)(usr.loc,3) - if("conceal") - call(/obj/effect/rune/proc/obscure)(2) - if("revealrunes") - call(/obj/effect/rune/proc/revealrunes)(src) - if("ire", "ego", "nahlizet", "certum", "veri", "jatkaa", "balaq", "mgar", "karazet", "geeri") - call(/obj/effect/rune/proc/teleport)(imbue) - if("communicate") - //If the user cancels the talisman this var will be set to 0 - delete = call(/obj/effect/rune/proc/communicate)() - if("deafen") - call(/obj/effect/rune/proc/deafen)() - if("blind") - call(/obj/effect/rune/proc/blind)() - if("runestun") - user << "To use this talisman, attack your target directly." - return - if("supply") - supply() -// user.take_organ_damage(5, 0) - if(src && src.imbue!="supply" && src.imbue!="runestun") - if(delete) - user.drop_item(src) - qdel(src) - return - else - user << "You see strange symbols on the paper. Are they supposed to mean something?" - return +/* +Talismans are portable versions of runes that resemble blank sheets of paper. They may have different effects than their parent runes and are created by using a Rite of Binding with a paper on top and +a compatible rune somewhere nearby. A list of compatible runes can found below. - attack(mob/living/carbon/T, mob/living/user) - if(iscultist(user)) - if(imbue == "runestun") - user.take_organ_damage(10, 0) - call(/obj/effect/rune/proc/runestun)(T) - user.drop_item(src) - qdel(src) - else - ..() ///If its some other talisman, use the generic attack code, is this supposed to work this way? - else - ..() +Basic Runes: +Rite of Translocation +Rite of Knowledge +Rite of Obscurity +Rite of True Sight +Rite of False Truths +Rite of Disruption +Rite of Disorientation +*/ - proc/supply(key) - if (!src.uses) - qdel(src) - return +/obj/item/weapon/paper/talisman + var/cultist_name = "talisman" + var/cultist_desc = "A basic talisman. It serves no purpose." + var/invocation = "Naise meam!" + var/uses = 1 + +/obj/item/weapon/paper/talisman/examine(mob/user) + ..() + if(iscultist(user) || user.stat == DEAD) + user << "Name: [cultist_name]" + user << "Effect: [cultist_desc]" + user << "Uses Remaining: [uses]" - var/dat = "There are [src.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 a new arcane tome.
" - dat += "Sas'so c'arta forbici! - Allows you to move to a rune with the same last word.
" - 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 the runes you placed on the floor.
" - dat += "O bidai nabora se'sma! - Allows you to coordinate with others of your cult.
" - dat += "Fuu ma'jin - Allows you to stun a person by attacking them with the talisman.
" - dat += "Kal om neth - Summons a soul stone
" - dat += "Da A'ig Osk - Summons a construct shell for use with captured souls. It is too large to carry on your person.
" - usr << browse(dat, "window=id_com;size=350x200") +/obj/item/weapon/paper/talisman/attack_self(mob/living/user) + if(!iscultist(user)) + user << "There are strange, illegible symbols drawn on [src]. Maybe some sort of blueprint?" return + if(invocation) + user.whisper(invocation) + src.invoke(user) + uses-- + if(uses <= 0) + user.drop_item() + qdel(src) +/obj/item/weapon/paper/talisman/proc/invoke(mob/living/user) - Topic(href, href_list) - if(!src) return - if (usr.stat || usr.restrained() || !in_range(src, usr)) return - if (href_list["rune"]) +//Malformed Talisman: If something goes wrong. +/obj/item/weapon/paper/talisman/malformed + cultist_name = "malformed talisman" + cultist_desc = "A talisman with gibberish scrawlings. No good can come from invoking this." + invocation = "Ra'sha yoka!" + +/obj/item/weapon/paper/talisman/malformed/invoke(mob/living/user) + user << "You feel a pain in your head. The Geometer is displeased." + if(iscarbon(user)) + var/mob/living/carbon/C = user + C.apply_damage(10, BRUTE, "head") + + +//Supply Talisman: Has a few unique effects. Granted only to starter cultists. +/obj/item/weapon/paper/talisman/supply + cultist_name = "Supply Talisman" + cultist_desc = "A multi-use talisman that can create various objects. Intended to increase the cult's strength early on." + invocation = null + uses = 3 + +/obj/item/weapon/paper/talisman/supply/invoke(mob/living/user) + 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 += "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", "", 800, 600) + popup.set_content(dat) + popup.open() + uses++ //To prevent uses being consumed just by opening it + 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/T = new /obj/item/weapon/paper/talisman(usr) + var/obj/item/weapon/paper/talisman/summon_tome/T = new(usr) usr.put_in_hands(T) - T.imbue = "newtome" if("teleport") - var/obj/item/weapon/paper/talisman/T = new /obj/item/weapon/paper/talisman(usr) + var/obj/item/weapon/paper/talisman/teleport/T = new(usr) + T.keyword = "veri" usr.put_in_hands(T) - T.imbue = "[pick("ire", "ego", "nahlizet", "certum", "veri", "jatkaa", "balaq", "mgar", "karazet", "geeri", "orkan", "allaq")]" - T.info = "[T.imbue]" if("emp") - var/obj/item/weapon/paper/talisman/T = new /obj/item/weapon/paper/talisman(usr) + var/obj/item/weapon/paper/talisman/emp/T = new(usr) usr.put_in_hands(T) - T.imbue = "emp" if("conceal") - var/obj/item/weapon/paper/talisman/T = new /obj/item/weapon/paper/talisman(usr) + var/obj/item/weapon/paper/talisman/hide_runes/T = new(usr) usr.put_in_hands(T) - T.imbue = "conceal" - if("communicate") - var/obj/item/weapon/paper/talisman/T = new /obj/item/weapon/paper/talisman(usr) + if("reveal") + var/obj/item/weapon/paper/talisman/true_sight/T = new(usr) usr.put_in_hands(T) - T.imbue = "communicate" if("runestun") - var/obj/item/weapon/paper/talisman/T = new /obj/item/weapon/paper/talisman(usr) - usr.put_in_hands(T) - T.imbue = "runestun" - if("armor") - var/obj/item/weapon/paper/talisman/T = new /obj/item/weapon/paper/talisman(usr) + var/obj/item/weapon/paper/talisman/stun/T = new(usr) usr.put_in_hands(T) - T.imbue = "armor" if("soulstone") - var/obj/item/device/soulstone/T = new /obj/item/device/soulstone(usr) + var/obj/item/device/soulstone/T = new(usr) usr.put_in_hands(T) if("construct") new /obj/structure/constructshell(get_turf(usr)) src.uses-- - supply() + if(src.uses <= 0) + if(iscarbon(usr)) + var/mob/living/carbon/C = usr + C.drop_item() + visible_message("[src] crumbles to dust.") + qdel(src) + return + else return -/obj/item/weapon/paper/talisman/supply - imbue = "supply" - uses = 3 +//Rite of Translocation: Same as rune +/obj/item/weapon/paper/talisman/teleport + cultist_name = "Rite of Translocation" + cultist_desc = "A single-use talisman that will teleport a user to a random rune of the same keyword." + invocation = "Sas'so c'arta forbici!" + var/keyword = "ire" + +/obj/item/weapon/paper/talisman/teleport/invoke(mob/living/user) + var/list/possible_runes = list() + for(var/obj/effect/rune/teleport/R in teleport_runes) + if(R.keyword == src.keyword) + possible_runes.Add(R) + if(!possible_runes.len) + user << "There are no Rites of Translocation with the same keyword!" + log_game("Teleportation talisman failed - no teleport runes of the same keyword") + uses++ //To prevent deletion + return + var/chosen_rune = pick(possible_runes) + user.visible_message("Dust flows from [user]'s hand, and they disappear in a flash of red light!", \ + "You speak the words of the talisman and find yourself somewhere else!") + if(user.buckled) + user.buckled.unbuckle_mob() + user.loc = get_turf(chosen_rune) + +/obj/item/weapon/paper/talisman/teleport/New() + ..() + spawn(1) //To give the keyword time to change from the imbue rune + info += keyword + + +//Rite of Knowledge: Same as rune, but has two uses +/obj/item/weapon/paper/talisman/summon_tome + cultist_name = "Rite of Knowledge" + cultist_desc = "A two-use talisman that will call untranslated tomes from the archives of the Geometer." + invocation = "N'ath reth sh'yro eth d'raggathnor!" + +/obj/item/weapon/paper/talisman/summon_tome/invoke(mob/living/user) + user.visible_message("Dust flows from [user]'s hand 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 +/obj/item/weapon/paper/talisman/hide_runes + cultist_name = "Rite of Obscurity" + cultist_desc = "A talisman that will make all runes within a small radius invisible." + invocation = "Kla'atu barada nikt'o!" + +/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 = "Rite of True Sight" + cultist_desc = "A talisman that reveals nearby invisible runes." + invocation = "Nikt'o barada kla'atu!" + +/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 = "Rite of False Truths" + cultist_desc = "A talisman that will make nearby runes appear fake." + invocation = "By'o isit!" + +/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." + + +//Rite of Disruption: Same as rune, halved radius +/obj/item/weapon/paper/talisman/emp + cultist_name = "Rite of Disruption" + cultist_desc = "A talisman that will cause a moderately-sized electromagnetic pulse." + invocation = "Ta'gh fara'qha fel d'amar det!" + +/obj/item/weapon/paper/talisman/emp/invoke(mob/living/user) + user.visible_message("[user]'s hand glows a bright blue!", \ + "You speak the words of the talisman, emitting an EMP blast.") + empulse(src, 2, 4) + + +//Rite of Disorientation: Stuns and mutes a single target for quite some time +/obj/item/weapon/paper/talisman/stun + cultist_name = "Rite of Disorientation" + cultist_desc = "A talisman that will stun and mute a single target. To use, attack target directly." + invocation = "Fuu ma'jin!" + +/obj/item/weapon/paper/talisman/stun/attack_self(mob/living/user) + user << "To use this talisman, attack the target directly." + return + +/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 power!", \ + "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 + ..() diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 269822a24a6da..7198a152c31e0 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -5,6 +5,7 @@ * Wood * Cloth * Cardboard + * Runed Metal (cult) */ /* @@ -152,4 +153,33 @@ var/global/list/datum/stack_recipe/cardboard_recipes = list ( \ /obj/item/stack/sheet/cardboard/New(var/loc, var/amount=null) recipes = cardboard_recipes - return ..() \ No newline at end of file + return ..() + +/* + * Runed Metal +*/ + +var/global/list/datum/stack_recipe/runed_metal_recipes = list ( \ + new/datum/stack_recipe("pylon", /obj/structure/cult/pylon, 4, time = 40, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("forge", /obj/structure/cult/forge, 6, time = 40, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("archives", /obj/structure/cult/tome, 4, time = 40, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("altar", /obj/structure/cult/talisman, 10, time = 40, one_per_turf = 1, on_floor = 1), \ + ) + +/obj/item/stack/sheet/runed_metal + name = "runed metal" + desc = "Sheets of cold metal with shifting inscriptions writ upon them." + singular_name = "runed metal" + icon_state = "sheet-runed" + icon = 'icons/obj/items.dmi' + sheettype = "runed" + +/obj/item/stack/sheet/runed_metal/New(var/loc, var/amount=null) + recipes = runed_metal_recipes + return ..() + +/obj/item/stack/sheet/runed_metal/attack_self(mob/user) + if(!iscultist(user)) + user << "You aren't able to think of anything [src] could build..." + return + ..() diff --git a/code/game/objects/items/weapons/storage/book.dm b/code/game/objects/items/weapons/storage/book.dm index 0272a07c6b82e..e1b957259e439 100644 --- a/code/game/objects/items/weapons/storage/book.dm +++ b/code/game/objects/items/weapons/storage/book.dm @@ -196,7 +196,8 @@ var/global/list/bibleitemstates = list("bible", "koran", "scrapbook", "bible", " if (istype(A, /turf/simulated/floor)) user << "You hit the floor with the bible." if(user.mind && (user.mind.assigned_role == "Chaplain")) - call(/obj/effect/rune/proc/revealrunes)(src) + for(var/obj/effect/rune/R in orange(2,user)) + R.invisibility = 0 if(user.mind && (user.mind.assigned_role == "Chaplain")) if(A.reagents && A.reagents.has_reagent("water")) //blesses all the water in the holder user << "You bless [A]." diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index a52769f13f2fa..92ea19f1afc85 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -60,7 +60,6 @@ var/list/admin_verbs_admin = list( /client/proc/cmd_admin_world_narrate, /*sends text to all players with no padding*/ /client/proc/cmd_admin_local_narrate, //sends text to all mobs within view of atmo /client/proc/cmd_admin_create_centcom_report, - /client/proc/check_words, /*displays cult-words*/ /client/proc/reset_all_tcs /*resets all telecomms scripts*/ ) var/list/admin_verbs_ban = list( @@ -170,7 +169,6 @@ var/list/admin_verbs_hideable = list( /client/proc/cmd_admin_direct_narrate, /client/proc/cmd_admin_world_narrate, /client/proc/cmd_admin_local_narrate, - /client/proc/check_words, /client/proc/play_local_sound, /client/proc/play_sound, /client/proc/set_round_end_sound, diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 1a7ea85761760..03d01a2cf24f9 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -222,7 +222,6 @@ H = pick(candidates) H.mind.make_Cultist() candidates.Remove(H) - temp.grant_runeword(H) return 1 diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index 3015b00ca88f7..097f1c6985dae 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -117,7 +117,7 @@ put_on_delay = 40 /obj/item/clothing/shoes/cult - name = "cultist boots" + name = "nar-sian invoker boots" desc = "A pair of boots worn by the followers of Nar-Sie." icon_state = "cult" item_state = "cult" @@ -127,6 +127,10 @@ heat_protection = FEET max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT +/obj/item/clothing/shoes/cult/alt + name = "cultist boots" + icon_state = "cultalt" + /obj/item/clothing/shoes/cyborg name = "cyborg boots" desc = "Shoes for a cyborg costume." diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 10dd6348a922c..b6649aada216b 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -160,12 +160,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(mind.current.key && copytext(mind.current.key,1,2)!="@") //makes sure we don't accidentally kick any clients usr << "Another consciousness is in your body...It is resisting you." return - if(mind.current.ajourn && mind.current.stat != DEAD) //check if the corpse is astral-journeying (it's client ghosted using a cultist rune). - var/obj/effect/rune/R = locate() in mind.current.loc //whilst corpse is alive, we can only reenter the body if it's on the rune - if(!(R && R.word1 == wordhell && R.word2 == wordtravel && R.word3 == wordself)) //astral journeying rune - usr << "The astral cord that ties your body and your spirit has been severed. You are likely to wander the realm beyond until your body is finally dead and thus reunited with you." - return - mind.current.ajourn=0 mind.current.key = key return 1 diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index 1231747ed6bc7..fa542a77592cf 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -55,12 +55,6 @@ ..() regenerate_icons() -/mob/living/simple_animal/pet/dog/corgi/sac_act(obj/effect/rune/R, victim) //Still the best thing in this game - usr << "Even dark gods from another plane have standards, sicko." - usr.reagents.add_reagent("hell_water", 2) - R.stone_or_gib(victim) - - /mob/living/simple_animal/pet/dog/corgi/show_inv(mob/user) user.set_machine(src) if(user.stat) return diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index a0c72c0ee0990..d5d378ee71078 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -289,6 +289,9 @@ else user << "You don't know how to read or write." return + if(istype(src, /obj/item/weapon/paper/talisman/)) + user << "[P]'s ink fades away shortly after it is written." + return else if(istype(P, /obj/item/weapon/stamp)) if(!in_range(src, usr) && loc != user && !istype(loc, /obj/item/weapon/clipboard) && loc.loc != user && user.get_active_hand() != P) diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index d8aa85ac91e1c..f991cfc847839 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -25,7 +25,7 @@ /obj/singularity/narsie/large/New() ..() world << "NAR-SIE HAS RISEN" - world << pick(sound('sound/hallucinations/im_here1.ogg'), sound('sound/hallucinations/im_here2.ogg')) + world << 'sound/effects/narsie.ogg' var/area/A = get_area(src) if(A) @@ -77,7 +77,7 @@ for(var/mob/living/carbon/M in oviewers(8, src)) if(M.stat == CONSCIOUS) if(!iscultist(M)) - M << "You feel your sanity crumble away in an instant as you gaze upon [src.name]..." + M << "You feel conscious thought crumble away in an instant as you gaze upon [src.name]..." M.apply_effect(3, STUN) diff --git a/html/changelogs/phil235-CultRefactor.yml b/html/changelogs/phil235-CultRefactor.yml new file mode 100644 index 0000000000000..4e89baa68d62d --- /dev/null +++ b/html/changelogs/phil235-CultRefactor.yml @@ -0,0 +1,19 @@ +author: Xhuis +delete-after: True + +changes: + - experimental: "Cultists will now be able to create all runes without needing to research or collect words. This is subject to change." + - tweak: "Cult code has been significantly improved and will run much faster and be more responsive." + - tweak: "Conversion runes can now be invoked with less than three cultists, but take a small amount of time to convert the target." + - tweak: "Armor runes will only outfit the user with standard armor, rather than having different loadouts for different worn clothing items." + - tweak: "Astral Journey runes will now pull the user back to the rune if they are moved. The user also has a different color while on the rune." + - tweak: "Free Cultist has been removed. Summon Cultist now works even if the target is restrained." + - tweak: "Sacrifice and Raise Dead runes now offer more precise target selection." + - soundadd: "Sacrifice runes now have different sounds, and gib rather than dust (assuming the target is not a silicon)." + - tweak: "There is no longer a maximum cap on active runes." + - tweak: "Runes have been renamed to Rites. For instance, the Teleport rune is now the Rite of Translocation. The only exception to this is the rune to summon Nar-Sie, which is a Ritual." + - tweak: "Nar-Sie now has a new summon sound." + - tweak: "The Nar-Sie summon rune has a new 3x3 sprite." + - tweak: "The stun rune no longer stuns cultists." + - rscadd: "The Rite of False Truths had been added, that will make all nearby runes appear as if they were drawn in crayon." + - rscadd: "Runes can now be examined by cultists to determine their name, function, and words." \ No newline at end of file diff --git a/icons/effects/96x96.dmi b/icons/effects/96x96.dmi index 25f1fd71bcdad..fdc1a69dccaa8 100644 Binary files a/icons/effects/96x96.dmi and b/icons/effects/96x96.dmi differ diff --git a/icons/mob/feet.dmi b/icons/mob/feet.dmi index 0994856ff60be..08e019fafc503 100644 Binary files a/icons/mob/feet.dmi and b/icons/mob/feet.dmi differ diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi index e4326609bbde6..0b2cf364302c4 100644 Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ diff --git a/icons/obj/cult.dmi b/icons/obj/cult.dmi index 7d73fe97be3da..ece38c80f9c15 100644 Binary files a/icons/obj/cult.dmi and b/icons/obj/cult.dmi differ diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi index f8487ed72da21..c621ffbe65429 100644 Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm index 9417f0fd6ed7e..c6e664acdcc50 100644 --- a/interface/stylesheet.dm +++ b/interface/stylesheet.dm @@ -65,6 +65,8 @@ h1.alert, h2.alert {color: #000000;} .suicide {color: #ff5050; font-style: italic;} .green {color: #03ff39;} .shadowling {color: #3b2769;} +.cult {color: #960000; font-weight: bold; font-size: 3;} +.purple {color: #5e2d79;} .newscaster {color: #800000;} .ghostalert {color: #5c00e6; font-style: italic; font-weight: bold;} diff --git a/sound/effects/dimensional_rend.ogg b/sound/effects/dimensional_rend.ogg new file mode 100644 index 0000000000000..98bd3ef193f11 Binary files /dev/null and b/sound/effects/dimensional_rend.ogg differ diff --git a/sound/effects/narsie.ogg b/sound/effects/narsie.ogg new file mode 100644 index 0000000000000..af14ea5861c00 Binary files /dev/null and b/sound/effects/narsie.ogg differ