From 8ead3e8628cfd2deb93d61b7b99e6dd8f34be5db Mon Sep 17 00:00:00 2001 From: Tkdrg Date: Thu, 10 Dec 2015 14:43:42 -0300 Subject: [PATCH] Cult Overhaul Cult is awful, so let's try to improve it. Idea by KorPhaeron. I also took some inspiration from adrix89's sacrifice cult, so credits to him. Also thanks a lot specially to MrPerson and Iamgoofball for helping me brainstorm this, and Joan for the sprites for the summoning orb, the large nar-sie shell, and the new cult antag hud. Basically, we remove conversion, and turn cult into a magic version of nuke, with a small team of stealth elite cultists that have to build a base in the station and sacrifice people in order to build an army of constructs and get materials to eventually summon Nar-Sie. Stun talismans and conversion are gone. Nar-Sie is now the only objective. Sacrifice runes now provide summoning orbs, which you can use to drop a large shell. Insert enough orbs in the shell and you trigger a Delta. Defend the shell for 3 minutes and Nar-sie will arise. This shell is bombproof and singularityproof. It may be summoned up to three times if destroyed, but you will have to start from the beginning sac-wise. Runes are now RNG. Each cultist only gets 50% of the runes. Inspiration is basically The Binding of Isaac here (thank you MrPerson for this!). Furthermore, many old runes were merged/removed and other new ones were added. Almost all were massively rebalanced. Cult now also has a stealthy ritual dagger with high bleeding and throw effects. --- code/datums/mind.dm | 69 +--- code/game/gamemodes/cult/cult.dm | 200 ++-------- code/game/gamemodes/cult/cult_items.dm | 65 ++++ code/game/gamemodes/cult/cult_structures.dm | 146 ++++++- code/game/gamemodes/cult/ritual.dm | 116 ++---- code/game/gamemodes/cult/runes.dm | 361 ++++++------------ code/game/gamemodes/cult/talisman.dm | 189 +++------ code/game/gamemodes/wizard/soulstone.dm | 15 +- .../objects/items/weapons/storage/book.dm | 7 - code/modules/admin/verbs/debug.dm | 91 ----- code/modules/admin/verbs/one_click_antag.dm | 3 +- code/modules/mob/living/bloodcrawl.dm | 6 +- .../mob/living/carbon/human/species.dm | 3 - code/modules/mob/mob_defines.dm | 1 - code/modules/paperwork/paper.dm | 4 - code/modules/power/singularity/narsie.dm | 2 +- code/modules/power/singularity/singularity.dm | 2 +- .../chemistry/reagents/other_reagents.dm | 5 +- html/changelogs/Tkdrg-Cult-Overhaul.yml | 15 + icons/mob/hud.dmi | Bin 9768 -> 9657 bytes icons/obj/cult.dmi | Bin 14583 -> 15762 bytes icons/obj/cult_large.dmi | Bin 0 -> 2312 bytes 22 files changed, 474 insertions(+), 826 deletions(-) create mode 100644 html/changelogs/Tkdrg-Cult-Overhaul.yml create mode 100644 icons/obj/cult_large.dmi diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 8d61b841478..40af75b2a57 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -46,7 +46,6 @@ var/list/datum/objective/objectives = list() var/list/datum/objective/special_verbs = list() - var/list/cult_words = list() var/list/spell_list = list() // Wizard mode & "Give Spell" badmin button. var/datum/faction/faction //associated faction @@ -147,12 +146,7 @@ if(src in ticker.mode.cult) ticker.mode.cult -= src ticker.mode.update_cult_icons_removed(src) - var/datum/game_mode/cult/cult = ticker.mode - if(istype(cult)) - cult.memorize_cult_objectives(src) special_role = null - remove_objectives() - remove_antag_equip() /datum/mind/proc/remove_rev() if(src in ticker.mode.revolutionaries) @@ -342,11 +336,8 @@ text = "[text]: " if (src in ticker.mode.cult) text += "loyal|employee|CULTIST" - text += "
Give tome|amulet." -/* - if (objectives.len==0) - text += "
Objectives are empty! Set to sacrifice and escape or summon." -*/ + text += "
Equip" + else if(isloyal(current)) text += "LOYAL|employee|cultist" else @@ -1008,31 +999,9 @@ ticker.mode.add_cultist(src) message_admins("[key_name_admin(usr)] has cult'ed [current].") log_admin("[key_name(usr)] has cult'ed [current].") - if("tome") - var/mob/living/carbon/human/H = current - if (istype(H)) - var/obj/item/weapon/tome/T = new(H) - - var/list/slots = list ( - "backpack" = slot_in_backpack, - "left pocket" = slot_l_store, - "right pocket" = slot_r_store, - "left hand" = slot_l_hand, - "right hand" = slot_r_hand, - ) - var/where = H.equip_in_one_of_slots(T, slots) - if (!where) - usr << "Spawning tome failed!" - else - H << "A tome, a message from your new master, appears in your [where]." - if(where == "backpack") - var/obj/item/weapon/storage/B = H.back - B.orient2hud(H) - B.show_to(H) - - if("amulet") + if("equip") if (!ticker.mode.equip_cultist(current)) - usr << "Spawning amulet failed!" + usr << "equip_cultist() failed! [current]'s starting equipment will be incomplete." else if (href_list["wizard"]) switch(href_list["wizard"]) @@ -1430,34 +1399,8 @@ special_role = "Cultist" current << "You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie." current << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." - var/datum/game_mode/cult/cult = ticker.mode - if (istype(cult)) - cult.memorize_cult_objectives(src) - else - var/explanation = "Summon Nar-Sie via the use of the appropriate rune (Hell join self). It will only work if nine cultists stand on and around it." - current << "Objective #1: [explanation]" - current.memory += "Objective #1: [explanation]
" - current << "The convert rune is join blood self" - current.memory += "The convert rune is join blood self
" - - var/mob/living/carbon/human/H = current - if (istype(H)) - var/obj/item/weapon/tome/T = new(H) - - var/list/slots = list ( - "backpack" = slot_in_backpack, - "left pocket" = slot_l_store, - "right pocket" = slot_r_store, - "left hand" = slot_l_hand, - "right hand" = slot_r_hand, - ) - var/where = H.equip_in_one_of_slots(T, slots) - if (!where) - else - H << "A tome, a message from your new master, appears in your [where]." - - if (!ticker.mode.equip_cultist(current)) - H << "Spawning an amulet from your Master failed." + current << "Your objective is to summon Nar-Sie by building and defending a suitable shell for the Geometer. Adequate supplies can be procured through human sacrifices." + ticker.mode.equip_cultist(current) /datum/mind/proc/make_Rev() if (ticker.mode.head_revolutionaries.len>0) diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index cd0d3b4315a..7b43cb7958e 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -2,29 +2,11 @@ /datum/game_mode var/list/datum/mind/cult = list() - var/list/cult_objectives = list() - /proc/iscultist(mob/living/M) return istype(M) && M.mind && ticker && ticker.mode && (M.mind in ticker.mode.cult) -/proc/is_sacrifice_target(datum/mind/mind) - if(ticker.mode.name == "cult") - var/datum/game_mode/cult/cult_mode = ticker.mode - if(mind == cult_mode.sacrifice_target) - return 1 - return 0 - -/proc/is_convertable_to_cult(datum/mind/mind) - if(!istype(mind)) return 0 - if(istype(mind.current, /mob/living/carbon/human) && (mind.assigned_role in list("Captain", "Chaplain"))) return 0 - if(isloyal(mind.current)) - return 0 - if (ticker.mode.name == "cult") //redundent? - if(is_sacrifice_target(mind)) return 0 - return 1 - -/proc/cultist_commune(mob/living/user, clear = 0, say = 0, message) +/proc/cultist_commune(mob/living/user, say = 0, message) if(!message) return if(say) @@ -40,10 +22,7 @@ user.whisper(message) for(var/mob/M in mob_list) if(iscultist(M) || (M in dead_mob_list)) - if(clear || !ishuman(user)) - M << "[(ishuman(user) ? "Acolyte" : "Construct")] [user]: [message]" - else //Emergency comms - M << "Acolyte ???: [message]" + M << "[(ishuman(user) ? "Acolyte" : "Construct")] [user]: [message]" log_say("[user.real_name]/[user.key] : [message]") @@ -54,42 +33,31 @@ antag_flag = ROLE_CULTIST restricted_jobs = list("Chaplain","AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel") protected_jobs = list() - required_players = 20 - required_enemies = 4 - recommended_enemies = 4 + required_players = 10 + required_enemies = 2 + recommended_enemies = 2 enemy_minimum_age = 14 - - var/finished = 0 - - var/eldergod = 1 //for the summon god objective - - var/acolytes_needed = 10 //for the survive objective - var/acolytes_survived = 0 - - var/datum/mind/sacrifice_target = null//The target to be sacrificed - + var/eldergod = 0 + var/orbs_needed = 3 + var/large_shell_summoned = 0 + var/attempts_left = 3 /datum/game_mode/cult/announce() world << "The current game mode is - Cult!" - world << "Some crewmembers are attempting to start a cult!
\nCultists - complete your objectives. Convert crewmembers to your cause by using the convert rune. Remember - there is no you, there is only the cult.
\nPersonnel - Do not let the cult succeed in its mission. Brainwashing them with the chaplain's bible reverts them to whatever Centcom-allowed faith they had.
" + world << "Some crewmembers are attempting to start a cult!
\nCultists - summon the elder god. Sacrifice crewmembers and turn them into constructs. Remember - there is no you, there is only the cult.
\nPersonnel - Do not let the cult succeed in its mission. Deal with the cultists and any constructs that they might summon.
" /datum/game_mode/cult/pre_setup() - cult_objectives += "sacrifice" - if(prob(50)) - cult_objectives += "survive" - else - cult_objectives += "eldergod" - if(config.protect_roles_from_antagonist) restricted_jobs += protected_jobs if(config.protect_assistant_from_antagonist) restricted_jobs += "Assistant" - acolytes_needed = round(num_players()/5,1) //Scales the escape requirement with the amount of people in the round; for every 5 players, one cultist added to the count, i.e. 25 players = 5 to escape - acolytes_needed = Clamp(acolytes_needed, 1, 15) //Max at 15 and minimum at 1 - before the update, people rarely got even 15 + //cult scaling goes here + recommended_enemies = 1 + round(num_players()/8) + orbs_needed = recommended_enemies for(var/cultists_number = 1 to recommended_enemies) if(!antag_candidates.len) @@ -106,22 +74,6 @@ /datum/game_mode/cult/post_setup() modePlayer += cult - if("sacrifice" in cult_objectives) - var/list/possible_targets = get_unconvertables() - - if(!possible_targets.len) - message_admins("Cult Sacrifice: Could not find unconvertable target, checking for convertable target.") - for(var/mob/living/carbon/human/player in player_list) - if(player.mind && !(player.mind in cult)) - possible_targets += player.mind - - if(possible_targets.len > 0) - sacrifice_target = pick(possible_targets) - if(!sacrifice_target) - message_admins("Cult Sacrifice: ERROR - Null target chosen!") - else - message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!") - for(var/datum/mind/cult_mind in cult) equip_cultist(cult_mind.current) update_cult_icons_added(cult_mind) @@ -131,20 +83,7 @@ /datum/game_mode/cult/proc/memorize_cult_objectives(datum/mind/cult_mind) - for(var/obj_count = 1,obj_count <= cult_objectives.len,obj_count++) - var/explanation - switch(cult_objectives[obj_count]) - if("survive") - explanation = "Our knowledge must live on. Make sure at least [acolytes_needed] acolytes escape on the shuttle to spread their work on an another station." - if("sacrifice") - if(sacrifice_target) - explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. You will need the Sacrifice rune and three acolytes to do so." - else - explanation = "Free objective." - if("eldergod") - explanation = "Summon Nar-Sie via the rune 'Call Forth The Geometer'. It will only work if nine acolytes stand on and around it." - cult_mind.current << "Objective #[obj_count]: [explanation]" - cult_mind.memory += "Objective #[obj_count]: [explanation]
" + cult_mind.current << "Your objective is to summon Nar-Sie by building and defending a suitable shell for the Geometer. Adequate supplies can be procured through human sacrifices." /datum/game_mode/proc/equip_cultist(mob/living/carbon/human/mob) if(!istype(mob)) @@ -155,20 +94,27 @@ mob << "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself." mob.dna.remove_mutation(CLOWNMUT) + . += cult_give_item(/obj/item/weapon/tome, mob) + . += cult_give_item(/obj/item/weapon/paper/talisman/supply, mob) + . += cult_give_item(/obj/item/weapon/melee/cultblade/dagger, mob) + mob << "These will help you start the cult on this station. Use them well, and remember - you are not the only one." - var/obj/item/weapon/paper/talisman/supply/T = new(mob) - var/list/slots = list ( +/datum/game_mode/proc/cult_give_item(obj/item/item_path, mob/living/carbon/human/mob) + var/list/slots = list( "backpack" = slot_in_backpack, "left pocket" = slot_l_store, "right pocket" = slot_r_store, "left hand" = slot_l_hand, "right hand" = slot_r_hand, ) + var/T = new item_path(mob) + var/item_name = initial(item_path.name) var/where = mob.equip_in_one_of_slots(T, slots) if(!where) - mob << "Unfortunately, you weren't able to get a talisman. This is very bad and you should adminhelp immediately." + mob << "Unfortunately, you weren't able to get a [item_name]. This is very bad and you should adminhelp immediately (press F1)." + return 0 else - mob << "You have a talisman in your [where], one that will help you start the cult on this station. Use it well, and remember - you are not the only one." + mob << "You have a [item_name] in your [where]." mob.update_icons() if(where == "backpack") var/obj/item/weapon/storage/B = mob.back @@ -176,20 +122,18 @@ B.show_to(mob) return 1 - /datum/game_mode/proc/add_cultist(datum/mind/cult_mind) //BASE - if (!istype(cult_mind)) + if (!istype(cult_mind) || (cult_mind in cult)) return 0 - if(!(cult_mind in cult) && is_convertable_to_cult(cult_mind)) - cult_mind.current.Paralyse(5) - cult += cult_mind - cult_mind.current.faction |= "cult" - cult_mind.current.cult_add_comm() - update_cult_icons_added(cult_mind) - cult_mind.current.attack_log += "\[[time_stamp()]\] Has been converted to the cult!" - if(jobban_isbanned(cult_mind.current, ROLE_CULTIST)) - replace_jobbaned_player(cult_mind.current, ROLE_CULTIST, ROLE_CULTIST) - return 1 + cult_mind.current.Paralyse(5) + cult += cult_mind + cult_mind.current.faction |= "cult" + cult_mind.current.cult_add_comm() + update_cult_icons_added(cult_mind) + cult_mind.current.attack_log += "\[[time_stamp()]\] Has been converted to the cult!" + if(jobban_isbanned(cult_mind.current, ROLE_CULTIST)) + replace_jobbaned_player(cult_mind.current, ROLE_CULTIST, ROLE_CULTIST) + return 1 /datum/game_mode/cult/add_cultist(datum/mind/cult_mind) //INHERIT @@ -222,85 +166,13 @@ culthud.leave_hud(cult_mind.current) set_antag_hud(cult_mind.current, null) -/datum/game_mode/cult/proc/get_unconvertables() - var/list/ucs = list() - for(var/mob/living/carbon/human/player in player_list) - if(player.mind && !is_convertable_to_cult(player.mind)) - ucs += player.mind - return ucs - - -/datum/game_mode/cult/proc/check_cult_victory() - var/cult_fail = 0 - if(cult_objectives.Find("survive")) - cult_fail += check_survive() //the proc returns 1 if there are not enough cultists on the shuttle, 0 otherwise - if(cult_objectives.Find("eldergod")) - cult_fail += eldergod //1 by default, 0 if the elder god has been summoned at least once - if(cult_objectives.Find("sacrifice")) - if(sacrifice_target && !sacrificed.Find(sacrifice_target)) //if the target has been sacrificed, ignore this step. otherwise, add 1 to cult_fail - cult_fail++ - - return cult_fail //if any objectives aren't met, failure - - -/datum/game_mode/cult/proc/check_survive() - acolytes_survived = 0 - for(var/datum/mind/cult_mind in cult) - if (cult_mind.current && cult_mind.current.stat != DEAD) - if(cult_mind.current.onCentcom() || cult_mind.current.onSyndieBase()) - acolytes_survived++ - if(acolytes_survived>=acolytes_needed) - return 0 - else - return 1 - - /datum/game_mode/cult/declare_completion() - - if(!check_cult_victory()) + if(eldergod) feedback_set_details("round_end_result","win - cult win") - feedback_set("round_end_result",acolytes_survived) world << "The cult wins! It has succeeded in serving its dark master!" else feedback_set_details("round_end_result","loss - staff stopped the cult") - feedback_set("round_end_result",acolytes_survived) world << "The staff managed to stop the cult!" - - var/text = "" - - if(cult_objectives.len) - text += "
The cultists' objectives were:" - for(var/obj_count=1, obj_count <= cult_objectives.len, obj_count++) - var/explanation - switch(cult_objectives[obj_count]) - if("survive") - if(!check_survive()) - explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) Success!" - feedback_add_details("cult_objective","cult_survive|SUCCESS|[acolytes_needed]") - else - explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) Fail." - feedback_add_details("cult_objective","cult_survive|FAIL|[acolytes_needed]") - if("sacrifice") - if(sacrifice_target) - if(sacrifice_target in sacrificed) - explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Success!" - feedback_add_details("cult_objective","cult_sacrifice|SUCCESS") - else if(sacrifice_target && sacrifice_target.current) - explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Fail." - feedback_add_details("cult_objective","cult_sacrifice|FAIL") - else - explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Fail (Gibbed)." - feedback_add_details("cult_objective","cult_sacrifice|FAIL|GIBBED") - if("eldergod") - if(!eldergod) - explanation = "Summon Nar-Sie. Success!" - feedback_add_details("cult_objective","cult_narsie|SUCCESS") - else - explanation = "Summon Nar-Sie. Fail." - feedback_add_details("cult_objective","cult_narsie|FAIL") - text += "
Objective #[obj_count]: [explanation]" - - world << text ..() return 1 diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index af5df6a2f62..67acdd9d67a 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -4,6 +4,7 @@ icon_state = "cultblade" item_state = "cultblade" flags = CONDUCT + sharpness = IS_SHARP w_class = 4 force = 30 throwforce = 10 @@ -31,6 +32,21 @@ user << "An overwhelming sense of nausea overpowers you!" user.Dizzy(120) +/obj/item/weapon/melee/cultblade/dagger + name = "sacrificial dagger" + desc = "A strange dagger said to be used by sinister groups for \"preparing\" a corpse before sacrificing it to their dark gods." + icon = 'icons/obj/wizard.dmi' + icon_state = "render" + w_class = 2 + force = 15 + throwforce = 25 + embed_chance = 75 + +/obj/item/weapon/melee/cultblade/dagger/attack(mob/living/target, mob/living/carbon/human/user) + ..() + if(ishuman(target)) + var/mob/living/carbon/human/H = target + H.drip(50) /obj/item/clothing/head/culthood name = "ancient cultist hood" @@ -108,3 +124,52 @@ w_class = 3 allowed = list(/obj/item/weapon/tome,/obj/item/weapon/melee/cultblade,/obj/item/weapon/tank/internals/) armor = list(melee = 70, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) + +/obj/item/summoning_orb + name = "summoning orb" + desc = "A mysterious orb that glows eerily. You could swear that it just moved on its own." + icon = 'icons/obj/cult.dmi' + icon_state = "summoning_orb" + w_class = 1 + +/obj/item/summoning_orb/afterattack(atom/target, mob/user, proximity_flag) + if(!iscultist(user)) + return ..() + if(proximity_flag && isliving(target) && iscultist(target)) + var/mob/living/L = target + if(L.stat == DEAD) + user << "You shouldn't waste that." + return ..() + target << "You feel the Geometer's essence violating your insides." + target << "It feels... good." + target.reagents.add_reagent("unholywater", 15) + qdel(src) + ..() + +/obj/item/summoning_orb/attack_self(mob/user) + if(!iscultist(user)) + return ..() + if(ticker.mode.name != "cult") + return + var/datum/game_mode/cult/cult = ticker.mode + if(!cult.attempts_left) + user << "You attempt to call out to the Geometer, but there is no answer..." + return + switch(alert(user,"Are you sure you wish to summon the large construct shell? [cult.attempts_left] attempts left!","Summoning Large Shell","Yes","No")) + if("Yes") + cult.attempts_left-- + place_down_large_shell(user) + qdel(src) + +/obj/item/summoning_orb/proc/place_down_large_shell(mob/user) + if(!(ticker.mode.name == "cult")) + user << "You attempt to call out to the Geometer for Her shell, but you fail..." + return + var/datum/game_mode/cult/cult = ticker.mode + if(cult.large_shell_summoned) + user << "Another Acolyte has already summoned Her shell. You must go forth and contact them." + return + if(cult.attempts_left <= 0) + user << "The Geometer is no longer interested in you." + new /obj/structure/constructshell/large(get_turf(src)) + cult.large_shell_summoned = 1 diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm index 95b685beb29..b5b5cb9d0c4 100644 --- a/code/game/gamemodes/cult/cult_structures.dm +++ b/code/game/gamemodes/cult/cult_structures.dm @@ -1,3 +1,148 @@ +/obj/structure/constructshell/large + name = "large empty shell" + icon = 'icons/obj/cult_large.dmi' + icon_state = "shell_narsie_grey" + desc = "An oversized construct shell, fit for an elder god. Only a lunatic would even dream of such a crazed contraption." + pixel_x = -16 + pixel_y = -16 + density = 1 + anchored = 0 + var/maxhealth = 200 + var/health = 200 + var/image/black_overlay = null + var/orbs = 0 + var/orbs_needed = 1 + var/time_to_win = 1800 //3 minutes + var/timer_id = null + +/obj/structure/constructshell/large/New() + ..() + if(ticker.mode.name == "cult") + var/datum/game_mode/cult/cult = ticker.mode + orbs_needed = cult.orbs_needed + black_overlay = image('icons/obj/cult_large.dmi', "shell_narsie_black") + +/obj/structure/constructshell/large/Destroy() + priority_announce("The extra-dimensional flow has ceased. All personnel should return to their routine activities.","Central Command Higher Dimensions Affairs") + if(get_security_level() == "delta") + set_security_level("red") + if(ticker.mode.name == "cult") + var/datum/game_mode/cult/cult = ticker.mode + cult.large_shell_summoned = 0 + black_overlay = null + if(timer_id) + deltimer(timer_id) + ..() + +/obj/structure/constructshell/large/examine(mob/user) + ..() + user << "You see a number of round holes on the surface of the shell. They number [orbs_needed], and [orbs ? orbs : "none"] of them [orbs > 1 ? "are" : "is"] filled." + +/obj/structure/constructshell/large/update_icon() + var/new_alpha = round((orbs/orbs_needed)*255) + if(new_alpha) + overlays -= black_overlay + black_overlay.alpha = new_alpha + overlays += black_overlay + +/obj/structure/constructshell/large/attackby(obj/item/O, mob/user, params) + if(istype(O, /obj/item/summoning_orb) && (orbs < orbs_needed)) + if(!iscultist(user)) + return + visible_message("\The [src] glows.") + orbs++ + qdel(O) + update_icon() + if(orbs >= orbs_needed) + start_takeover() + return + + if( (O.flags&NOBLUDGEON) || !O.force ) + return + add_fingerprint(user) + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) + playsound(src, 'sound/weapons/smash.ogg', 50, 1) + visible_message("[user] has hit \the [src] with [O].") + if(O.damtype == BURN || O.damtype == BRUTE) + damaged(O.force) + +//this stuff is mostly copy-pasted from gang dominators, with some changes +/obj/structure/constructshell/large/proc/start_takeover() + anchored = 1 + animate(black_overlay, alpha = 255, 5, -1) + set_security_level("delta") + var/area/A = get_area(src) + var/locname = initial(A.name) + priority_announce("Figments from an eldritch god have begun pouring into [locname] from an unknown dimension. Eliminate its vessel before it reaches a critical point.","Central Command Higher Dimensions Affairs") + timer_id = addtimer(src, "summon_narnar", time_to_win) + +/obj/structure/constructshell/large/proc/damaged(damage) + health -= damage + if(health <= 0) + new /obj/item/stack/sheet/plasteel(get_turf(src)) + qdel(src) + +/obj/structure/constructshell/large/bullet_act(obj/item/projectile/P) + if(P.damage) + playsound(src, 'sound/effects/bang.ogg', 50, 1) + visible_message("[src] was hit by [P].") + damaged(P.damage) + +/obj/structure/constructshell/large/attack_alien(mob/living/user) + user.do_attack_animation(src) + playsound(src, 'sound/effects/bang.ogg', 50, 1) + user.visible_message("[user] smashes against [src] with its claws.",\ + "You smash against [src] with your claws.") + damaged(15) + +/obj/structure/constructshell/large/attack_animal(mob/living/user) + if(!isanimal(user)) + return + var/mob/living/simple_animal/M = user + M.do_attack_animation(src) + if(M.melee_damage_upper <= 0) + return + damaged(M.melee_damage_upper) + +/obj/structure/constructshell/large/mech_melee_attack(obj/mecha/M) + if(M.damtype == "brute") + playsound(src, 'sound/effects/bang.ogg', 50, 1) + visible_message("[M.name] has hit [src].") + damaged(M.force) + +/obj/structure/constructshell/large/attack_hulk(mob/user) + playsound(src, 'sound/effects/bang.ogg', 50, 1) + user.visible_message("[user] smashes [src].",\ + "You punch [src].") + damaged(5) + +/obj/structure/constructshell/large/ex_act() + return //nope + +/obj/structure/constructshell/large/singularity_pull() + return //nope + +/obj/structure/constructshell/large/singularity_act(current_size, obj/singularity/S) + var/atom/target = get_edge_target_turf(src, get_dir(src, S)) + S.throw_at(target, 5, 1) //aaand nope + +/obj/structure/constructshell/large/proc/summon_narnar() + if(ticker.mode.name != "cult") + visible_message("\The [src] glows brightly once, then falls dark. It looks strangely dull and lifeless...") + log_game("Summon Nar-Sie rune failed - gametype is not cult") + return + var/datum/game_mode/cult/cult_mode = ticker.mode + if(cult_mode.eldergod) + return //this should never happen, so we don't need any special fluff + world << 'sound/effects/dimensional_rend.ogg' + world << "Rip... Rrrip... RRRRRRRRRR--" + var/turf/target_turf = get_turf(src) + spawn(40) + new /obj/singularity/narsie/large(target_turf) //Causes Nar-Sie to spawn even if the rune has been removed + cult_mode.eldergod = 1 + + /obj/structure/cult density = 1 anchored = 1 @@ -8,7 +153,6 @@ desc = "A bloodstained altar dedicated to Nar-Sie" icon_state = "talismanaltar" - /obj/structure/cult/forge name = "daemon forge" desc = "A forge used in crafting the unholy weapons used by the armies of Nar-Sie" diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index 55ce399d19a..5ccc6d9e3f2 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -1,9 +1,6 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 - /* This file contains the arcane tome files as well as innate cultist emergency communications. -It also contains rune words, which are soon to be removed. */ @@ -12,7 +9,7 @@ It also contains rune words, which are soon to be removed. /mob/living/proc/cult_innate_comm() set category = "Cultist" - set name = "Imperfect Communion" + set name = "Communion" if(!iscultist(usr)) //they shouldn't have this verb, but just to be sure... return @@ -24,24 +21,7 @@ It also contains rune words, which are soon to be removed. if(!input) // TO-DO: Add some kind of filter to corrupt the inputted text return - if(ishuman(usr) || ismonkey(usr)) //Damage only applies to humans and monkeys, to allow constructs to communicate - usr.visible_message("[usr] starts clawing at \his arms with \his fingernails!", "You begin slicing open your arms with your fingernails!") - apply_damage(10,BRUTE, "l_arm") - apply_damage(10,BRUTE, "r_arm") - sleep(50) - if(usr.incapacitated()) - return //Hard to drawn intrinsic symbols when you're bleeding out in your cell. - var/turf/location = loc - if(istype(location, /turf/simulated)) // tearing your arms apart is going to spill a bit of blood, in fact thats the idea - location.add_blood(usr) // TO-DO change this to a badly drawn rune - apply_damage(10,BRUTE, "l_arm") // does a metric fuck ton of damage because this meant to be an emergency method of communication. - apply_damage(10,BRUTE, "r_arm") - if(usr.incapacitated()) - return - usr.visible_message("[usr] paints strange symbols with their own blood.", "You paint a messy rune with your own blood.") - sleep(20) - - cultist_commune(usr, 0, 1, input) + cultist_commune(usr, 0, input) return @@ -52,6 +32,13 @@ It also contains rune words, which are soon to be removed. throw_speed = 2 throw_range = 5 w_class = 2 + var/list/known_runes = null + +/obj/item/weapon/tome/New() + ..() + known_runes = shuffle(subtypesof(/obj/effect/rune) - /obj/effect/rune/malformed) + var/known_amount = round((known_runes.len)/2) + known_runes.Cut(known_amount) /obj/item/weapon/tome/examine(mob/user) ..() @@ -92,47 +79,20 @@ It also contains rune words, which are soon to be removed. open_tome(user) /obj/item/weapon/tome/proc/open_tome(mob/user) - var/choice = alert(user,"You open the tome...",,"Commune","Scribe Rune","Read Tome") + var/choice = alert(user,"You open the tome...",,"Scribe Rune","Read Tome") switch(choice) if("Read Tome") read_tome(user) if("Scribe Rune") scribe_rune(user) - if("Commune") - var/input = stripped_input(usr, "Please enter a message to tell to the other acolytes.", "Voice of Blood", "") - if(!input) - return - cultist_commune(user, 1, 0, input) /obj/item/weapon/tome/proc/read_tome(mob/user) var/text = "" text += "
Archives of the Dark One



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

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


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

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

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

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


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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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


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

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

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

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

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

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

" var/datum/browser/popup = new(user, "tome", "", 800, 600) popup.set_content(text) @@ -242,10 +182,10 @@ It also contains rune words, which are soon to be removed. var/rune_to_scribe var/entered_rune_name var/list/possible_runes = list() - for(var/T in subtypesof(/obj/effect/rune) - /obj/effect/rune/malformed) + for(var/T in known_runes) var/obj/effect/rune/R = T if(initial(R.cultist_name)) - possible_runes.Add(initial(R.cultist_name)) //This is to allow the menu to let cultists select runes by name rather than by object path. I don't know a better way to do this + possible_runes += initial(R.cultist_name) //This is to allow the menu to let cultists select runes by name rather than by object path. I don't know a better way to do this if(!possible_runes.len) return entered_rune_name = input(user, "Choose a rite to scribe.", "Sigils of Power") as null|anything in possible_runes diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 9be02034637..6ecc6a696c3 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -1,6 +1,3 @@ -var/list/sacrificed = list() -var/list/non_revealed_runes = (subtypesof(/obj/effect/rune) - /obj/effect/rune/malformed) - /* This file contains runes. @@ -9,18 +6,7 @@ They are drawn with an arcane tome in blood, and are distinguishable to cultists Fake runes can be drawn in crayon to fool people. Runes can either be invoked by one's self or with many different cultists. Each rune has a specific incantation that the cultists will say when invoking it. -To draw a rune, use an arcane tome and enter the words required. These words are in the tongue of the Geometer and must be entered as such. -Word definitions: -"ire" is Travel -"ego" is Self -"nahlizet" is Blood -"certum" is Join -"veri" is Hell -"jatkaa" is Other -"mgar" is Destroy -"balaq" is Technology -"karazet" is See -"geeri" is Hide +To draw a rune, use an arcane tome. */ @@ -38,7 +24,6 @@ Word definitions: mouse_opacity = 2 var/invocation = "Aiy ele-mayo!" //This is said by cultists when the rune is invoked. - var/grammar //This is only framework at the moment, but may be required to draw runes in the future var/req_cultists = 1 //The amount of cultists required around the rune to invoke it. If only 1, any cultist can invoke it. var/rune_in_use = 0 // Used for some runes, this is for when you want a rune to not be usable when in use. @@ -55,7 +40,6 @@ Word definitions: if(iscultist(user) || user.stat == DEAD) //If they're a cultist or a ghost, tell them the effects user << "Name: [cultist_name]" user << "Effects: [cultist_desc]" - //user << "Words: [grammar]" user << "Required Acolytes: [req_cultists]" if(req_keyword && keyword) user << "Keyword: [keyword]" @@ -77,6 +61,9 @@ Word definitions: return if(can_invoke(user)) invoke(user) + var/oldtransform = transform + animate(src, transform = matrix()*2, alpha = 0, time = 5) //fade out + animate(transform = oldtransform, alpha = 255, time = 0) else fail_invoke(user) @@ -151,7 +138,6 @@ structure_check() searches for nearby cultist structures required for the invoca cultist_name = "malformed rune" cultist_desc = "A senseless rune written in gibberish. No good can come from invoking this." invocation = "Ra'sha yoka!" - grammar = "N/A" /obj/effect/rune/malformed/New() ..() @@ -177,7 +163,6 @@ var/list/teleport_runes = list() invocation = "Sas'so c'arta forbici!" icon_state = "2" color = rgb(0, 0, 255) - grammar = "ire ego" req_keyword = 1 /obj/effect/rune/teleport/New() @@ -216,7 +201,6 @@ var/list/teleport_other_runes = list() invocation = "Sas'so c'arta forbica!" icon_state = "1" color = rgb(200, 0, 0) - grammar = "ire jatkaa" req_keyword = 1 /obj/effect/rune/teleport_other/New() @@ -264,62 +248,6 @@ var/list/teleport_other_runes = list() "Your vision blurs, and you suddenly appear somewhere else.") target.forceMove(get_turf(selected_rune)) - -//Rite of Knowledge: Creates an arcane tome at the rune's location and destroys the rune. -/obj/effect/rune/summon_tome - cultist_name = "Summon Tome" - cultist_desc = "Pulls an arcane tome from the archives of the Geometer." - invocation = "N'ath reth sh'yro eth d'raggathnor!" - icon_state = "5" - color = rgb(0, 0, 255) - grammar = "karazet nahlizet ego" - -/obj/effect/rune/summon_tome/invoke(mob/living/user) - visible_message("A frayed tome materializes on the surface of [src], which dissolves into nothing.") - new /obj/item/weapon/tome(get_turf(src)) - qdel(src) - - -//Rite of Enlightenment: Converts a normal crewmember to the cult. Faster for every cultist nearby. -/obj/effect/rune/convert - cultist_name = "Convert" - cultist_desc = "Converts a normal crewmember on top of it to the cult. Does not work on loyalty-implanted crew." - invocation = "Mah'weyh pleggh at e'ntrath!" - icon_state = "3" - color = rgb(255, 0, 0) - grammar = "certum nahlizet ego" - req_cultists = 2 - -/obj/effect/rune/convert/invoke(mob/living/user) - var/list/convertees = list() - var/turf/T = get_turf(src) - for(var/mob/living/M in T.contents) - if(!iscultist(M) && !isloyal(M)) - convertees.Add(M) - if(!convertees.len) - fail_invoke() - log_game("Convert rune failed - no eligible convertees") - return - var/mob/living/new_cultist = pick(convertees) - if(!is_convertable_to_cult(new_cultist.mind) || new_cultist.null_rod_check()) - user << "Something is shielding [new_cultist]'s mind!" - fail_invoke() - log_game("Convert rune failed - convertee could not be converted") - if(is_sacrifice_target(new_cultist.mind)) - for(var/mob/living/M in orange(1,src)) - if(iscultist(M)) - M << "\"I desire this one for myself. SACRIFICE THEM!\"" - return - new_cultist.visible_message("[new_cultist] writhes in pain as the markings below them glow a bloody red!", \ - "AAAAAAAAAAAAAA-") - ticker.mode.add_cultist(new_cultist.mind) - new_cultist.mind.special_role = "Cultist" - new_cultist << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible, truth. The veil of reality has been ripped away \ - and something evil takes root." - new_cultist << "Assist your new compatriots in their dark dealings. Your goal is theirs, and theirs is yours. You serve the Geometer above all else. Bring it back.\ - " - - //Rite of Tribute: Sacrifices a crew member to Nar-Sie. Places them into a soul shard if they're in their body. /obj/effect/rune/sacrifice cultist_name = "Sacrifice" @@ -327,7 +255,6 @@ var/list/teleport_other_runes = list() icon_state = "3" invocation = "Barhah hra zar'garis!" color = rgb(255, 255, 255) - grammar = "veri nahlizet certum" rune_in_use = 0 /obj/effect/rune/sacrifice/New() @@ -357,13 +284,13 @@ var/list/teleport_other_runes = list() fail_invoke() rune_in_use = 0 return - if(((ishuman(offering) || isrobot(offering)) && offering.stat != DEAD) || is_sacrifice_target(offering.mind)) //Requires three people to sacrifice living targets or the round's target + if(((ishuman(offering) || isrobot(offering)) && offering.stat != DEAD)) //Requires two people to sacrifice living targets var/cultists_nearby = 1 - for(var/mob/living/M in orange(1,src)) + for(var/mob/living/M in range(1,src)) if(iscultist(M) && M != user) cultists_nearby++ M.say(invocation) - if(cultists_nearby < 3) + if(cultists_nearby < 2) user << "[offering] is too greatly linked to the world! You need more acolytes!" fail_invoke() log_game("Sacrifice rune failed - not enough acolytes and target is living") @@ -376,29 +303,17 @@ var/list/teleport_other_runes = list() sac(offering) /obj/effect/rune/sacrifice/proc/sac(mob/living/T) - var/sacrifice_fulfilled if(T) - if(istype(T, /mob/living/simple_animal/pet/dog)) - for(var/mob/living/carbon/C in range(3,src)) - if(iscultist(C)) - C << "\"Even I have standards, such as they are!\"" - if(C.reagents) - C.reagents.add_reagent("hell_water", 2) - if(T.mind) - sacrificed.Add(T.mind) - if(is_sacrifice_target(T.mind)) - sacrifice_fulfilled = 1 PoolOrNew(/obj/effect/overlay/temp/cult/sac, src.loc) for(var/mob/living/M in range(3,src)) if(iscultist(M)) - if(sacrifice_fulfilled) - M << "\"Yes! This is the one I desire! You have done well.\"" + if(ishuman(T) || isrobot(T)) + M << "\"I accept this sacrifice.\"" else - if(ishuman(T) || isrobot(T)) - M << "\"I accept this sacrifice.\"" - else - M << "\"I accept this meager sacrifice.\"" + M << "\"I accept this meager sacrifice.\"" if(T.mind) + if(ishuman(T) || isrobot(T)) + new /obj/item/summoning_orb(get_turf(src)) var/obj/item/device/soulstone/stone = new /obj/item/device/soulstone(get_turf(src)) stone.invisibility = INVISIBILITY_MAXIMUM //so it's not picked up during transfer_soul() if(!stone.transfer_soul("FORCE", T, usr)) //If it cannot be added @@ -417,65 +332,6 @@ var/list/teleport_other_runes = list() rune_in_use = 0 -//Ritual of Dimensional Rending: Calls forth the avatar of Nar-Sie upon the station. -/obj/effect/rune/narsie - cultist_name = "Call Forth The Geometer" - cultist_desc = "Tears apart dimensional barriers, calling forth the avatar of the Geometer." - invocation = null - req_cultists = 9 - icon = 'icons/effects/96x96.dmi' - icon_state = "rune_large" - pixel_x = -32 //So the big ol' 96x96 sprite shows up right - pixel_y = -32 - grammar = "veri certum ego" - var/used - -/obj/effect/rune/narsie/invoke(mob/living/user) - if(used) - return - if(ticker.mode.name == "cult") - var/datum/game_mode/cult/cult_mode = ticker.mode - if(!("eldergod" in cult_mode.cult_objectives)) - message_admins("[usr.real_name]([user.ckey]) tried to summon Nar-Sie when the objective was wrong") - for(var/mob/living/M in range(1,src)) - if(iscultist(M)) - M << "\"YOUR SOUL BURNS WITH YOUR ARROGANCE!!!\"" - if(M.reagents) - M.reagents.add_reagent("hell_water", 10) - M.Weaken(5) - fail_invoke() - log_game("Summon Nar-Sie rune failed - improper objective") - return - else - if(cult_mode.sacrifice_target && !(cult_mode.sacrifice_target in sacrificed)) - for(var/mob/living/M in orange(1,src)) - if(iscultist(M)) - M << "The sacrifice is not complete. The portal lacks the power to open!" - fail_invoke() - log_game("Summon Nar-Sie rune failed - sacrifice not complete") - return - if(!cult_mode.eldergod) - for(var/mob/living/M in range(1,src)) - if(iscultist(M)) - M << "The avatar of Nar-Sie is already on this plane!" - log_game("Summon Nar-Sie rune failed - already summoned") - return - //BEGIN THE SUMMONING - used = 1 - for(var/mob/living/M in range(1,src)) - if(iscultist(M)) - M.say("TOK-LYR RQA-NAP G'OLT-ULOFT!!") - world << 'sound/effects/dimensional_rend.ogg' - world << "Rip... Rrrip... RRRRRRRRRR--" - sleep(40) - new /obj/singularity/narsie/large(get_turf(user)) //Causes Nar-Sie to spawn even if the rune has been removed - cult_mode.eldergod = 0 - else - fail_invoke() - log_game("Summon Nar-Sie rune failed - gametype is not cult") - return - - //Rite of Resurrection: Requires two corpses. Revives one and gibs the other. /obj/effect/rune/raise_dead cultist_name = "Raise Dead" @@ -483,7 +339,6 @@ var/list/teleport_other_runes = list() invocation = null //Depends on the name of the user - see below icon_state = "1" color = rgb(255, 0, 0) - grammar = "nahlizet certum veri" /obj/effect/rune/raise_dead/invoke(mob/living/user) var/turf/T = get_turf(src) @@ -540,9 +395,9 @@ var/list/teleport_other_runes = list() mob_to_sacrifice.visible_message("[mob_to_sacrifice]'s body rises into the air, connected to [mob_to_revive] by a glowing tendril!") mob_to_revive.Beam(mob_to_sacrifice,icon_state="sendbeam",icon='icons/effects/effects.dmi',time=20) sleep(20) - if(mob_to_sacrifice) //sighing noise - mob_to_sacrifice.visible_message("[mob_to_sacrifice] disintegrates into a pile of bones[mob_to_revive ? ", the glowing tendril sinking into [mob_to_revive]'s body":""].") + if(!mob_to_sacrifice || !in_range(mob_to_sacrifice, src)) return + mob_to_sacrifice.visible_message("[mob_to_sacrifice] disintegrates into a pile of bones[mob_to_revive ? ", the glowing tendril sinking into [mob_to_revive]'s body":""].") mob_to_sacrifice.dust() if(!mob_to_revive || mob_to_revive.stat != DEAD) visible_message("The glowing tendril snaps against the rune with a shocking crack.") @@ -561,63 +416,27 @@ var/list/teleport_other_runes = list() M.visible_message("[M] twitches.") -//Rite of Obscurity: Turns all runes within a 3-tile radius invisible. +//Rite of Obscurity: Turns all runes within a 3-tile radius invisible or reveals them again. /obj/effect/rune/hide_runes cultist_name = "Veil Runes" - cultist_desc = "Turns nearby runes invisible. They can be revealed by using the Reveal Runes rune." + cultist_desc = "Turns nearby runes invisible. They can be revealed by using this rune again." invocation = "Kla'atu barada nikt'o!" icon_state = "1" color = rgb(0,0,255) - grammar = "geeri karazet nahlizet" /obj/effect/rune/hide_runes/invoke(mob/living/user) visible_message("[src] darkens to black and vanishes.") for(var/obj/effect/rune/R in orange(3,src)) - R.visible_message("[R] fades away.") - R.invisibility = INVISIBILITY_OBSERVER - R.alpha = 100 //To help ghosts distinguish hidden runes - for(var/mob/dead/observer/O in orange(3,src)) - if(!O.invisibility) - O << "You suddenly feel as if you've vanished..." - O.invisibility = INVISIBILITY_OBSERVER + if(R.invisibility == INVISIBILITY_OBSERVER) + R.invisibility = 0 + R.alpha = initial(R.alpha) + else + R.visible_message("[R] fades away.") + R.invisibility = INVISIBILITY_OBSERVER + R.alpha = 100 //To help ghosts distinguish hidden runes qdel(src) -//Rite of True Sight: Turns ghosts and obscured runes visible -/obj/effect/rune/true_sight - cultist_name = "Reveal Runes" - cultist_desc = "Reveals all invisible objects nearby, from spirits to runes." - invocation = "Nikt'o barada kla'atu!" - icon_state = "4" - color = rgb(255, 255, 255) - grammar = "karazet geeri nahlizet" - -/obj/effect/rune/true_sight/invoke() - visible_message("[src] explodes in a flash of blinding light!") - for(var/mob/dead/observer/O in orange(3,src)) - O << "You suddenly feel very obvious..." - O.invisibility = 0 - for(var/obj/effect/rune/R in orange(3,src)) - R.invisibility = 0 - R.alpha = initial(R.alpha) - qdel(src) - - -//Rite of False Truths: Makes runes appear like crayon ones -/obj/effect/rune/make_runes_fake - cultist_name = "Disguise Runes" - cultist_desc = "Causes all nearby runes (including itself) to resemble those drawn in crayon." - invocation = "By'o isit!" - icon_state = "4" - color = rgb(0, 150, 0) - grammar = "geeri nahlizet jatkaa" - -/obj/effect/rune/make_runes_fake/invoke(mob/living/user) - visible_message("[src] flares brightly, then slowly dulls and appears mundane.") - for(var/obj/effect/rune/R in range(3,src)) - R.desc = "A rune drawn in crayon." - - //Rite of Disruption: Emits an EMP blast. /obj/effect/rune/emp cultist_name = "Electromagnetic Disruption" @@ -625,7 +444,6 @@ var/list/teleport_other_runes = list() invocation = "Ta'gh fara'qha fel d'amar det!" icon_state = "5" color = rgb(255, 0, 0) - grammar = "mgar karazet balaq" /obj/effect/rune/emp/invoke(mob/living/user) visible_message("[src] glows blue for a moment before vanishing.") @@ -645,7 +463,6 @@ var/list/teleport_other_runes = list() color = rgb(126, 23, 23) rune_in_use = 0 //One at a time, please! var/mob/living/affecting = null - grammar = "veri ire ego" /obj/effect/rune/astral/examine(mob/user) ..() @@ -713,7 +530,6 @@ var/list/teleport_other_runes = list() invocation = "Khari'd! Eske'te tannin!" icon_state = "1" color = rgb(255, 0, 0) - grammar = "mgar ire ego" /obj/effect/rune/wall/examine(mob/user) ..() @@ -729,73 +545,62 @@ var/list/teleport_other_runes = list() C.apply_damage(2, BRUTE, pick("l_arm", "r_arm")) -//Rite of the Unheard Whisper: Deafens all non-cultists nearby. +//Rite of the Shadowed Mind: Deafens, blinds and mutes all non-cultists nearby. /obj/effect/rune/deafen - cultist_name = "Deafen" - cultist_desc = "Causes all non-followers nearby to lose their hearing." + cultist_name = "Debilitate" + cultist_desc = "Causes all non-followers nearby to lose their hearing, sight and voice." invocation = "Sti kaliedir!" - grammar = "geeri jatkaa karazet" color = rgb(0, 255, 0) icon_state = "4" /obj/effect/rune/deafen/invoke(mob/living/user) - visible_message("[src] blurs for a moment before fading away.") - for(var/mob/living/carbon/C in range(7,src)) - if(!iscultist(C) && !C.null_rod_check()) - C << "The world around you goes quiet." - C.adjustEarDamage(0,50) - qdel(src) - - -//Rite of the Unseen Glance: Blinds all non-cultists nearby. -/obj/effect/rune/blind - cultist_name = "Blind" - cultist_desc = "Causes all non-followers nearby to lose their sight." - invocation = "Sti kaliesin!" - icon_state = "4" - color = rgb(0, 0, 255) - grammar = "mgar jatkaa karazet" - -/obj/effect/rune/blind/invoke(mob/living/user) visible_message("[src] emits a blinding red flash!") for(var/mob/living/carbon/C in viewers(src)) if(!iscultist(C) && !C.null_rod_check()) - C << "You can't see!" + C << "You feel oily shadows cover your senses." + C.adjustEarDamage(0,50) C.flash_eyes(1, 1) C.eye_blurry += 50 C.eye_blind += 20 + C.silent += 10 qdel(src) - -//Rite of Disorientation: Stuns all non-cultists nearby for a brief time +//Rite of Disorientation: Stuns and mutes all non-cultists nearby for a brief time /obj/effect/rune/stun cultist_name = "Stun" - cultist_desc = "Stuns all nearby non-followers for a brief time." + cultist_desc = "Stuns and mutes all nearby non-followers for a brief time." invocation = "Fuu ma'jin!" icon_state = "2" color = rgb(100, 0, 100) - grammar = "certum geeri balaq" /obj/effect/rune/stun/invoke(mob/living/user) visible_message("[src] explodes in a bright flash!") for(var/mob/living/M in viewers(src)) - if(!iscultist(M) && !M.null_rod_check()) - M << "You are disoriented by [src]!" - M.Weaken(3) - M.Stun(3) - M.flash_eyes(1,1) + stun_he(M) qdel(src) +/obj/effect/rune/stun/Crossed(atom/movable/AM) + ..() + if(isliving(AM)) + stun_he(AM) -//Rite of Joined Souls: Summons a single cultist. Requires 2 cultists. +/obj/effect/rune/stun/proc/stun_he(mob/living/M) + if(!iscultist(M) && !M.null_rod_check()) + M << "You are disoriented by [src]!" + M.Weaken(3) + M.Stun(3) + M.flash_eyes(1,1) + if(iscarbon(M)) + var/mob/living/carbon/C = M + C.silent += 3 + +//Rite of Joined Souls: Summons a single cultist. /obj/effect/rune/summon cultist_name = "Summon Cultist" cultist_desc = "Summons a single cultist to the rune." invocation = "N'ath reth sh'yro eth d'rekkathnor!" - req_cultists = 2 icon_state = "5" color = rgb(0, 255, 0) - grammar = "certum jatkaa ego" /obj/effect/rune/summon/invoke(mob/living/user) var/list/cultists = list() @@ -817,9 +622,7 @@ var/list/teleport_other_runes = list() cultist_to_summon.visible_message("[cultist_to_summon] suddenly disappears in a flash of red light!", \ "Overwhelming vertigo consumes you as you are hurled through the air!") visible_message("A foggy shape materializes atop [src] and solidifes into [cultist_to_summon]!") - for(var/mob/living/carbon/C in orange(1,src)) - if(iscultist(C)) - C.apply_damage(10, BRUTE, "head") + user.apply_damage(10, BRUTE, "head") cultist_to_summon.loc = get_turf(src) qdel(src) @@ -831,7 +634,6 @@ var/list/teleport_other_runes = list() invocation = null //no talisman made, no invocation. icon_state = "3" color = rgb(0, 0, 255) - grammar = "veri balaq certum" /obj/effect/rune/imbue/invoke(mob/living/user) var/turf/T = get_turf(src) @@ -881,7 +683,6 @@ var/list/teleport_other_runes = list() invocation = null //see below; doesn't say the invocation unless there's enough sheets. icon_state = "5" color = rgb(150, 150, 150) - grammar = "ire veri balaq" /obj/effect/rune/construct_shell/invoke(mob/living/user) var/turf/T = get_turf(src) @@ -911,7 +712,6 @@ var/list/teleport_other_runes = list() invocation = "N'ath reth sh'yro eth draggathnor!" icon_state = "4" color = rgb(255, 0, 0) - grammar = "veri mgar jatkaa" /obj/effect/rune/armor/invoke(mob/living/user) visible_message("With the sound of clanging metal, [src] crumbles to dust!") @@ -930,7 +730,6 @@ var/list/teleport_other_runes = list() invocation = null //see below; doesn't say the invocation if it has no targets. icon_state = "2" color = rgb(255, 0, 0) - grammar = "ire nahlizet ego" /obj/effect/rune/leeching/invoke(mob/living/user) var/turf/T = get_turf(src) @@ -961,8 +760,7 @@ var/list/teleport_other_runes = list() invocation = "Dedo ol'btoh!" icon_state = "4" color = rgb(255, 0, 0) - req_cultists = 3 - grammar = "mgar karazet nahlizet" + req_cultists = 2 /obj/effect/rune/blood_boil/invoke(mob/living/user) visible_message("[src] briefly bubbles before exploding!") @@ -973,7 +771,7 @@ var/list/teleport_other_runes = list() continue C << "Your blood boils in your veins!" C.take_overall_damage(51,51) - for(var/mob/living/carbon/M in orange(1,src)) + for(var/mob/living/carbon/M in range(1,src)) if(iscultist(M)) M.apply_damage(15, BRUTE, pick("l_arm", "r_arm")) M << "[src] saps your strength!" @@ -981,6 +779,27 @@ var/list/teleport_other_runes = list() qdel(src) +//Rite of the Cleansing Flame: Sets all non-cultists on fire. +/obj/effect/rune/flame + cultist_name = "Immolate" + cultist_desc = "Sets any non-believers who can see the rune on fire." + invocation = "Dedo va'batoh!" + icon_state = "2" + color = rgb(255, 0, 0) + +/obj/effect/rune/flame/invoke(mob/living/user) + visible_message("[src] burns away, scorching the floor below!") + for(var/mob/living/carbon/C in viewers(src)) + if(!iscultist(C) && !C.null_rod_check()) + C << "You feel your skin crisp as you burst into flames!" + C.fire_act() + user.apply_damage(15, BURN, pick("l_arm", "r_arm")) + user << "[src] burns your arms!" + var/turf/simulated/T = get_turf(src) + T.burn_tile() + qdel(src) + + //Rite of Spectral Manifestation: Summons a ghost on top of the rune as a cultist human with no items. User must stand on the rune at all times, and takes damage for each summoned ghost. /obj/effect/rune/manifest cultist_name = "Manifest Spirit" @@ -988,7 +807,6 @@ var/list/teleport_other_runes = list() invocation = "Gal'h'rfikk harfrandid mud'gib!" //how the fuck do you pronounce this icon_state = "6" color = rgb(255, 0, 0) - grammar = "nahlizet karazet ire" /obj/effect/rune/manifest/invoke(mob/living/user) if(!(user in get_turf(src))) @@ -1027,3 +845,40 @@ var/list/teleport_other_runes = list() for(var/obj/I in new_human) new_human.unEquip(I) new_human.dust() + +//Rite of Dimensional Corruption: Stops time around the rune for all non-cultists. +/obj/effect/rune/timestop + cultist_name = "Time Stop" + cultist_desc = "Stops time around the rune for all non-cultists." + invocation = "T'ak ot'marzah oahr'du!" + icon_state = "2" + color = rgb(0, 0, 255) + req_cultists = 2 + +/obj/effect/rune/timestop/invoke(mob/living/user) + visible_message("[src] flares up for a moment, and then disappears into itself!") + new /obj/effect/timestop/cult(get_turf(src)) + for(var/mob/living/carbon/M in range(1,src)) + if(iscultist(M)) + M.apply_damage(20, BRUTE, "chest") + M << "[src] temporarily stops your heart from beating!" + qdel(src) + +/obj/effect/timestop/cult + name = "Dimensional Corruption" + desc = "Something not from this world has corrupted the spacetime continuum in this exact spot." + icon = 'icons/effects/96x96.dmi' + icon_state = "rune_large" + pixel_x = -32 + pixel_y = -32 + duration = 50 + alpha = 0 + color = rgb(255, 0, 0) + +/obj/effect/timestop/cult/timestop() + animate(src, alpha = 255, time = 5, loop = -1) + SpinAnimation(speed = 5) + for(var/mob/living/M in player_list) + if(iscultist(M) || M.null_rod_check()) + immune |= M + ..() diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm index e92cf3fd43e..ed9b106e3ce 100644 --- a/code/game/gamemodes/cult/talisman.dm +++ b/code/game/gamemodes/cult/talisman.dm @@ -26,8 +26,8 @@ Rite of Disorientation user << "Name: [cultist_name]" user << "Effect: [cultist_desc]" user << "Uses Remaining: [uses]" - return - ..() + else + user << "There are indecipherable images scrawled on the paper in what looks to be... blood?" /obj/item/weapon/paper/talisman/attack_self(mob/living/user) if(!iscultist(user)) @@ -70,12 +70,11 @@ Rite of Disorientation var/dat = "There are [uses] bloody runes on the parchment.
" dat += "Please choose the chant to be imbued into the fabric of reality.
" dat += "
" - dat += "N'ath reth sh'yro eth d'raggathnor! - Allows you to summon an arcane tome.
" dat += "Sas'so c'arta forbici! - Allows you to move to a Rite of Dislocation with the keyword of \"veri\".
" dat += "Ta'gh fara'qha fel d'amar det! - Allows you to destroy technology in a short range.
" - dat += "Kla'atu barada nikt'o! - Allows you to conceal nearby runes.
" - dat += "Nikt'o barada kla'atu! - Allows you to reveal nearby runes.
" - dat += "Fuu ma'jin! - Allows you to stun a person by attacking them with the talisman.
" + dat += "Kla'atu barada nikt'o! - Allows you to conceal nearby runes, or reveal previously concealed runes.
" + dat += "Dedo va'batoh! - Allows you to set nearby non-believers on fire.
" + dat += "Barhah hra zar'garis! - A sacrifice rune appears under your feet, ready to be invoked in the name of Nar-sie.
" dat += "Kal'om neth! - Summons a soul stone, used to capure the spirits of dead or dying humans.
" dat += "Daa'ig osk! - Summons a construct shell for use with captured souls. It is too large to carry on your person.
" var/datum/browser/popup = new(user, "talisman", "", 400, 400) @@ -85,46 +84,37 @@ Rite of Disorientation return 1 /obj/item/weapon/paper/talisman/supply/Topic(href, href_list) - if(src) - if(usr.stat || usr.restrained() || !in_range(src, usr)) - return - if(href_list["rune"]) - switch(href_list["rune"]) - if("newtome") - var/obj/item/weapon/paper/talisman/summon_tome/T = new(usr) - usr.put_in_hands(T) - if("teleport") - var/obj/item/weapon/paper/talisman/teleport/T = new(usr) - T.keyword = "veri" - usr.put_in_hands(T) - if("emp") - var/obj/item/weapon/paper/talisman/emp/T = new(usr) - usr.put_in_hands(T) - if("conceal") - var/obj/item/weapon/paper/talisman/hide_runes/T = new(usr) - usr.put_in_hands(T) - if("reveal") - var/obj/item/weapon/paper/talisman/true_sight/T = new(usr) - usr.put_in_hands(T) - if("runestun") - var/obj/item/weapon/paper/talisman/stun/T = new(usr) - usr.put_in_hands(T) - if("soulstone") - var/obj/item/device/soulstone/T = new(usr) - usr.put_in_hands(T) - if("construct") - new /obj/structure/constructshell(get_turf(usr)) - src.uses-- - if(src.uses <= 0) - if(iscarbon(usr)) - var/mob/living/carbon/C = usr - C.drop_item() - visible_message("[src] crumbles to dust.") - qdel(src) + if(!src || usr.stat || usr.restrained() || !in_range(src, usr)) return - else - return - + if(href_list["rune"]) + switch(href_list["rune"]) + if("teleport") + var/obj/item/weapon/paper/talisman/teleport/T = new(usr) + T.keyword = "veri" + usr.put_in_hands(T) + if("emp") + var/obj/item/weapon/paper/talisman/emp/T = new(usr) + usr.put_in_hands(T) + if("conceal") + var/obj/item/weapon/paper/talisman/hide_runes/T = new(usr) + usr.put_in_hands(T) + if("flame") + var/obj/item/weapon/paper/talisman/flame/T = new(usr) + usr.put_in_hands(T) + if("sacrune") + new /obj/effect/rune/sacrifice(get_turf(usr)) + if("soulstone") + var/obj/item/device/soulstone/T = new(usr) + usr.put_in_hands(T) + if("construct") + new /obj/structure/constructshell(get_turf(usr)) + src.uses-- + if(src.uses <= 0) + if(iscarbon(usr)) + var/mob/living/carbon/C = usr + C.drop_item() + visible_message("[src] crumbles to dust.") + qdel(src) //Rite of Translocation: Same as rune /obj/item/weapon/paper/talisman/teleport @@ -162,65 +152,24 @@ Rite of Disorientation user << "Keyword: [keyword]" -//Rite of Knowledge: Same as rune, but has two uses -/obj/item/weapon/paper/talisman/summon_tome - cultist_name = "Talisman of Tome Summoning" - cultist_desc = "A one-use talisman that will call an untranslated tome from the archives of the Geometer." - invocation = "N'ath reth sh'yro eth d'raggathnor!" - health_cost = 1 - -/obj/item/weapon/paper/talisman/summon_tome/invoke(mob/living/user) - user.visible_message("[user]'s hand glows red for a moment.", \ - "You speak the words of the talisman!") - var/obj/item/weapon/tome/T = new(get_turf(user)) - if(user.put_in_hands(T)) - user.visible_message("A tome appears in [user]'s hand!", \ - "An arcane tome materializes in your free hand.") - else - user.visible_message("A tome appears at [user]'s feet!", \ - "An arcane tome materialzies at your feet.") - -//Rite of Obscurity: Same as rune, but less range +//Talisman of Obscurity: Same as rune /obj/item/weapon/paper/talisman/hide_runes cultist_name = "Talisman of Veiling" - cultist_desc = "A talisman that will make all runes within a small radius invisible." + cultist_desc = "A talisman that will make all runes within a small radius invisible, or make invisible runes visible again." invocation = "Kla'atu barada nikt'o!" health_cost = 1 /obj/item/weapon/paper/talisman/hide_runes/invoke(mob/living/user) user.visible_message("Dust flows from [user]'s hand.", \ "You speak the words of the talisman, veiling nearby runes.") - for(var/obj/effect/rune/R in orange(3,user)) - R.visible_message("[R] fades away.") - R.invisibility = INVISIBILITY_OBSERVER - - -//Rite of True Sight: Same as rune, but doesn't work on ghosts -/obj/item/weapon/paper/talisman/true_sight - cultist_name = "Talisman of Revealing" - cultist_desc = "A talisman that reveals nearby invisible runes." - invocation = "Nikt'o barada kla'atu!" - health_cost = 1 - -/obj/item/weapon/paper/talisman/true_sight/invoke(mob/living/user) - user.visible_message("A flash of light shines from [user]'s hand!", \ - "You speak the words of the talisman, revealing nearby runes.") - for(var/obj/effect/rune/R in orange(3,user)) - R.invisibility = 0 - - -//Rite of False Truths: Same as rune -/obj/item/weapon/paper/talisman/make_runes_fake - cultist_name = "Talisman of Disguising" - cultist_desc = "A talisman that will make nearby runes appear fake." - invocation = "By'o isit!" - health_cost = 3 - -/obj/item/weapon/paper/talisman/make_runes_fake/invoke(mob/living/user) - user.visible_message("Dust flows from [user]s hand.", \ - "You speak the words of the talisman, making nearby runes appear fake.") - for(var/obj/effect/rune/R in orange(3,user)) - R.desc = "A rune drawn in crayon." + for(var/obj/effect/rune/R in orange(3,src)) + if(R.invisibility == INVISIBILITY_OBSERVER) + R.invisibility = 0 + R.alpha = initial(R.alpha) + else + R.visible_message("[R] fades away.") + R.invisibility = INVISIBILITY_OBSERVER + R.alpha = 100 //To help ghosts distinguish hidden runes //Rite of Disruption: Same as rune @@ -236,42 +185,20 @@ Rite of Disorientation empulse(src, 4, 8) -//Rite of Disorientation: Stuns and mutes a single target for quite some time -/obj/item/weapon/paper/talisman/stun - cultist_name = "Talisman of Stunning" - cultist_desc = "A talisman that will stun and mute a single target. To use, attack target directly." - invocation = "Fuu ma'jin!" - health_cost = 10 //A lot of health because of how powerful this is +//Rite of the Cleansing Flame: Same as rune +/obj/item/weapon/paper/talisman/flame + cultist_name = "Talisman of Immolation" + cultist_desc = "A talisman that sets any non-believers who can see you on fire." + invocation = "Dedo va'batoh!" + health_cost = 10 -/obj/item/weapon/paper/talisman/stun/attack_self(mob/living/user) - if(iscultist(user)) - user << "To use this talisman, attack the target directly." - else - user << "There are indecipherable images scrawled on the paper in what looks to be... blood?" - -/obj/item/weapon/paper/talisman/stun/attack(mob/living/target, mob/living/user) - if(iscultist(user)) - user.whisper(invocation) - user.visible_message("[user] holds up [src], which explodes in a flash of red light!", \ - "You stun [target] with the talisman!") - var/obj/item/weapon/nullrod/N = locate() in target - if(N) - target.visible_message("[target]'s null rod absorbs the talisman's light!", \ - "Your null rod absorbs the blinding light!") - else - target.Weaken(10) - target.Stun(10) - target.flash_eyes(1,1) - if(issilicon(target)) - var/mob/living/silicon/S = target - S.emp_act(1) - if(iscarbon(target)) - var/mob/living/carbon/C = target - C.silent += 10 - user.drop_item() - qdel(src) - return - ..() +/obj/item/weapon/paper/talisman/flame/invoke(mob/living/user) + user.visible_message("\The [src] in [user]'s hand suddenly burns away in a red flash!", \ + "You speak the words of the talisman, setting your enemies on fire.") + for(var/mob/living/carbon/C in viewers(user)) + if(!iscultist(C) && !C.null_rod_check()) + C << "You feel your skin crisp as you burst into flames!" + C.fire_act() //Rite of Arming: Equips cultist armor on the user, where available diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index eee99d5d765..d6fd311404b 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -28,9 +28,12 @@ if(!istype(M, /mob/living/carbon/human))//If target is not a human. return ..() if(istype(M, /mob/living/carbon/human/dummy)) - return..() + return ..() add_logs(user, M, "captured [M.name]'s soul", src) + if(iscultist(user) && M && M.mind) + new /obj/item/summoning_orb(get_turf(M)) + transfer_soul("VICTIM", M, user) return @@ -104,7 +107,7 @@ /obj/item/device/soulstone/proc/transfer_soul(choice as text, target, mob/user). switch(choice) if("FORCE") - if(!iscarbon(target)) //TO-DO: Add sacrifice stoning for non-organics, just because you have no body doesnt mean you dont have a soul + if(!iscarbon(target)) //TODO: Add sacrifice stoning for non-organics, just because you have no body doesnt mean you dont have a soul return 0 if(contents.len) return 0 @@ -120,12 +123,6 @@ if("VICTIM") var/mob/living/carbon/human/T = target - if(ticker.mode.name == "cult" && T.mind == ticker.mode:sacrifice_target) - if(iscultist(user)) - user << "The Geometer of blood wants this mortal sacrificed with the rune." - else - user << "The soul stone doesn't work for no apparent reason." - return 0 if(imprinted != "empty") user << "Capture failed!: The soul stone has already been imprinted with [imprinted]'s mind!" else @@ -200,7 +197,7 @@ if(stoner && iswizard(stoner)) newstruct << "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs." else if(stoner && iscultist(stoner)) - newstruct << "You are still bound to serve the cult, follow their orders and help them complete their goals at all costs." + newstruct << "You are still bound to serve the cult, follow their orders and help them summon the Geometer at all costs." else newstruct << "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs." newstruct.cancel_camera() diff --git a/code/game/objects/items/weapons/storage/book.dm b/code/game/objects/items/weapons/storage/book.dm index e1b957259e4..a8d05a6c91b 100644 --- a/code/game/objects/items/weapons/storage/book.dm +++ b/code/game/objects/items/weapons/storage/book.dm @@ -146,17 +146,10 @@ var/global/list/bibleitemstates = list("bible", "koran", "scrapbook", "bible", " user.Paralyse(20) return -// if(..() == BLOCKED) -// return - if (M.stat !=2) if(M.mind && (M.mind.assigned_role == "Chaplain")) user << "You can't heal yourself!" return - /*if((M.mind in ticker.mode.cult) && (prob(20))) - M << "\red The power of [src.deity_name] clears your mind of heresy!" - user << "\red You see how [M]'s eyes become clear, the cult no longer holds control over him!" - ticker.mode.remove_cultist(M.mind)*/ if ((istype(M, /mob/living/carbon/human) && prob(60))) bless(M) if(ishuman(M)) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index e6dd19001ae..ec18cdd4bd2 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -310,97 +310,6 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that else alert("Invalid mob") -/* -/client/proc/cmd_admin_monkeyize(var/mob/M in world) - set category = "Fun" - set name = "Make Monkey" - - if(!ticker) - alert("Wait until the game starts") - return - if(istype(M, /mob/living/carbon/human)) - var/mob/living/carbon/human/target = M - log_admin("[key_name(src)] is attempting to monkeyize [M.key].") - spawn(10) - target.monkeyize() - else - alert("Invalid mob") - -/client/proc/cmd_admin_changelinginize(var/mob/M in world) - set category = "Fun" - set name = "Make Changeling" - - if(!ticker) - alert("Wait until the game starts") - return - if(istype(M, /mob/living/carbon/human)) - log_admin("[key_name(src)] has made [M.key] a changeling.") - spawn(10) - M.absorbed_dna[M.real_name] = M.dna - M.make_changeling() - if(M.mind) - M.mind.special_role = "Changeling" - else - alert("Invalid mob") -*/ -/* -/client/proc/cmd_admin_abominize(var/mob/M in world) - set category = null - set name = "Make Abomination" - - usr << "Ruby Mode disabled. Command aborted." - return - if(!ticker) - alert("Wait until the game starts.") - return - if(istype(M, /mob/living/carbon/human)) - log_admin("[key_name(src)] has made [M.key] an abomination.") - - // spawn(10) - // M.make_abomination() - -*/ -/* -/client/proc/make_cultist(var/mob/M in world) - set category = "Fun" - set name = "Make Cultist" - set desc = "Makes target a cultist" - if(!wordtravel) - runerandom() - if(M) - if(M.mind in ticker.mode.cult) - return - else - if(alert("Spawn that person a tome?",,"Yes","No")=="Yes") - M << "\red You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie. A tome, a message from your new master, appears on the ground." - new /obj/item/weapon/tome(M.loc) - else - M << "\red You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie." - var/glimpse=pick("1","2","3","4","5","6","7","8") - switch(glimpse) - if("1") - M << "\red You remembered one thing from the glimpse... [wordtravel] is travel..." - if("2") - M << "\red You remembered one thing from the glimpse... [wordblood] is blood..." - if("3") - M << "\red You remembered one thing from the glimpse... [wordjoin] is join..." - if("4") - M << "\red You remembered one thing from the glimpse... [wordhell] is Hell..." - if("5") - M << "\red You remembered one thing from the glimpse... [worddestr] is destroy..." - if("6") - M << "\red You remembered one thing from the glimpse... [wordtech] is technology..." - if("7") - M << "\red You remembered one thing from the glimpse... [wordself] is self..." - if("8") - M << "\red You remembered one thing from the glimpse... [wordsee] is see..." - - if(M.mind) - M.mind.special_role = "Cultist" - ticker.mode.cult += M.mind - src << "Made [M] a cultist." -*/ - var/list/TYPES_SHORTCUTS = list( /obj/effect/decal/cleanable = "CLEANABLE", /obj/item/device/radio/headset = "HEADSET", diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index c60bcca1fc3..be7c7f7c7cb 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -194,7 +194,6 @@ /datum/admins/proc/makeCult() - var/datum/game_mode/cult/temp = new if(config.protect_roles_from_antagonist) temp.restricted_jobs += temp.protected_jobs @@ -216,7 +215,7 @@ candidates += applicant if(candidates.len) - var/numCultists = min(candidates.len, 4) + var/numCultists = min(candidates.len, 5) for(var/i = 0, iThere are indecipherable images scrawled on the paper in what looks to be... blood?
" - return if(in_range(user, src) || isobserver(user)) if( !(ishuman(user) || isobserver(user) || issilicon(user)) ) user << browse("[name][stars(info)]
[stamps]", "window=[name]") diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index a7eb8fac14b..0c64d0d67d5 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -61,7 +61,7 @@ return /obj/singularity/narsie/proc/godsmack(atom/A) - if(istype(A,/obj/)) + if(isobj(A)) var/obj/O = A O.ex_act(1) if(O) qdel(O) diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 6fe3f6f91b8..4a9fe63c99a 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -246,7 +246,7 @@ /obj/singularity/proc/consume(atom/A) - var/gain = A.singularity_act(current_size) + var/gain = A.singularity_act(current_size, src) src.energy += gain if(istype(A, /obj/machinery/power/supermatter_shard) && !consumedSupermatter) desc = "[initial(desc)] It glows fiercely with inner fire." diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 35b159a3aa6..2ea48e3d0cf 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -183,13 +183,10 @@ if (!M.stuttering) M.stuttering = 1 M.stuttering += 4 M.Dizzy(5) - if(iscultist(M) && prob(5)) - M.say(pick("Av'te Nar'sie","Pa'lid Mors","INO INO ORA ANA","SAT ANA!","Daim'niodeis Arc'iai Le'eones","Egkau'haom'nai en Chaous","Ho Diak'nos tou Ap'iron","R'ge Na'sie","Diabo us Vo'iscum","Si gn'um Co'nu")) if(data >= 75 && prob(33)) // 30 units, 135 seconds if (!M.confused) M.confused = 1 M.confused += 3 - if(iscultist(M) || (is_handofgod_cultist(M) && !is_handofgod_prophet(M))) - ticker.mode.remove_cultist(M.mind) + if((is_handofgod_cultist(M) && !is_handofgod_prophet(M))) ticker.mode.remove_hog_follower(M.mind) holder.remove_reagent(src.id, src.volume) // maybe this is a little too perfect and a max() cap on the statuses would be better?? M.jitteriness = 0 diff --git a/html/changelogs/Tkdrg-Cult-Overhaul.yml b/html/changelogs/Tkdrg-Cult-Overhaul.yml new file mode 100644 index 00000000000..bec05a6ed85 --- /dev/null +++ b/html/changelogs/Tkdrg-Cult-Overhaul.yml @@ -0,0 +1,15 @@ +author: Tkdrg + +delete-after: True + +changes: + - experiment: "Cult has been overhauled in an attempt to make the gamemode more fun." + - rscdel: "Cult onversion and stunpapers have been removed. So have most cult objectives." + - tweak: "The cult's single objective is now defend and feed a large construct shell in order to summon the Geometer." + - tweak: "The cult must sacrifice souls in order to acquire summoning orbs, which must be inserted inside said shell." + - tweak: "The large construct shell can be procured by using a summoning orb in hand, but it is vulnerable to attack." + - tweak: "Once enough orbs are inserted, the station will go Delta. After three minutes, the cult will have won." + - rscadd: "Cult communications now no longer damage you when done without a tome." + - rscadd: "Cultists now start with a sacrificial dagger, with bleeding effects and high throwing damage." + - rscadd: "Most existing runes were buffed, merged, or removed. A Immolate rune and a Time Stop rune were added. Experiment!" + - experiment: "Each cultist now gets a random set of runes in their tomes. Pool together your knowledge in order to thrive." diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index 81d7d489e48c900bb498a819925e97aa580411ad..0bd0e0fefb5da33d924d250ea1e61b3d9fb6e7f3 100644 GIT binary patch literal 9657 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 literal 9768 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 literal 14583 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 DkihZd diff --git a/icons/obj/cult_large.dmi b/icons/obj/cult_large.dmi new file mode 100644 index 0000000000000000000000000000000000000000..83e5b7e077ee525669463bba409286a017f9d834 GIT binary patch literal 2312 zcmV+j3HSDiP)i#3H76%NFA=CKH9jdPF*#d_i!&v&s2C_| z$ie8zc0uT)ARN;_~X%tLfDDMzRR}z9osvAPCZ_ z@GimPU;FLaHQ$<9`aDJvl)_R;STjqX$4G$dzCShPr;{n)zmZI$>FMd2nVD!5fDp5@ zBAv`41lgoi3d3*&fj{N{e$&69MMcQAbat_Hx>^*eWY5=}=K)oN{i zzE(g0fY~hU2nQH+I4Ctj#Bs2&5EK#k_wL=R`*kihywv^M^?DuG^8WqB#lWUyC7LV5EiVq$R~i{il2-Xo_Y*`1gx&DNx6oXq7dNuDnxvr7AbrRKV8a3s zcq}5DI*bTGkd^?#9;PYKEl2?nvF%1tt%ly7uhptL*o#Zca!Kl}$VHxd8UYI@0O(5# zfKti?dQ}jDKnB3mG)*!0Abr~cAbk*!%g|b7r9!QiHUU>Y*Sy?${+u9oc6Q`**^;(? zK)DtCRMeW?1YG$#3qj0S!vJz=nT$m~fWIu=mjIw%-%TU1n*n(0g;FotFY$s4mFdU4 zCcz;<83^w6-Bf-z1Mny;aj-{mu=hl{y2{@25DmVz3MJ%P?wbhg%LbJ^B-H_=+if5m zH~=wwOO^ym`@RXlzTgzFCD6|XKqy%Ni1;cQ3kb+)Dn!sQ8K4|ASijThDAj7UlmbD^ z=u>xRN#NQt1(4)`^M z79(`UzcTW#^esZ<&{GrGJqQ4bF)=&_K_e-6C^x9wiG%ea4f#$}br66~$Bux|IS8yq z$ciuVC*GW>1WH^5mJ7gODCg8$+~c~x(dhIIavWR|fO_5SD%I`wn(DCoS{bR!T!T3mGa z(FdbUKc@7vFHj>`0Qg{!rPa!;xz!VvKOp;f8pKRH|k9mf;8Kd_Fo(`Sf5Ww{0kQW6xqwc0Xdz@ zV*tRZxqlIWYXBJWFHZdcuo`~|z=M7ZtM8D-bUH8d2-Mko2jKmgIx~G(qAg!=jm7a^ z9zijHNBX1=dG^^$0I1XVwiN|}D?IVpO8}&&lq3ReZ7wagnxyVsfDa$7o9g2S)&KCx z^g*CoJ7lX7IpesLL-BSP`Hf8w@Nj4wJC!V@I6V2+kiY%$sKmz(_UU6$0om489Ek7^zZj z2%K9EBml@*EP&Iq9DwikJ@w;g!klF>N%?-y(BMpn%}pKsj;EJ(3g<>?QAevK!;+Cn2zJj0q42Zp_C8@YFx9 z$$TFV03mQqX1o&61V8L998*6{LN*&)-&6now3={ieNQadO*p