Cult backend rework + new features. (#8996)

Guess who the baton passes to.

Convert all runes to datums

Rework arcane tome mechanics, holy shit it's terrible

Convert rune effects to actually use rune datums

Add additional effects that are now possible because of non-shitcode code
This commit is contained in:
Matt Atlas
2020-06-07 09:07:32 +02:00
committed by GitHub
parent eaa47b6eb2
commit 32278e1ad1
42 changed files with 650 additions and 703 deletions
+3 -1
View File
@@ -175,6 +175,7 @@
#include "code\controllers\subsystems\battle_monsters.dm"
#include "code\controllers\subsystems\cargo.dm"
#include "code\controllers\subsystems\chemistry.dm"
#include "code\controllers\subsystems\cult.dm"
#include "code\controllers\subsystems\documents.dm"
#include "code\controllers\subsystems\economy.dm"
#include "code\controllers\subsystems\effects.dm"
@@ -454,12 +455,13 @@
#include "code\game\gamemodes\cult\items\sword.dm"
#include "code\game\gamemodes\cult\items\talisman.dm"
#include "code\game\gamemodes\cult\items\tome.dm"
#include "code\game\gamemodes\cult\runes\_runes.dm"
#include "code\game\gamemodes\cult\runes\armor.dm"
#include "code\game\gamemodes\cult\runes\blind_others.dm"
#include "code\game\gamemodes\cult\runes\blood_boil.dm"
#include "code\game\gamemodes\cult\runes\blood_drain.dm"
#include "code\game\gamemodes\cult\runes\communicate.dm"
#include "code\game\gamemodes\cult\runes\conversion.dm"
#include "code\game\gamemodes\cult\runes\convert.dm"
#include "code\game\gamemodes\cult\runes\create_construct.dm"
#include "code\game\gamemodes\cult\runes\create_talisman.dm"
#include "code\game\gamemodes\cult\runes\deafen_others.dm"
-1
View File
@@ -68,7 +68,6 @@ var/list/datum/visualnet/visual_nets = list()
var/datum/visualnet/camera/cameranet = new()
// Runes
var/global/list/rune_list = new()
var/global/list/escape_list = list()
var/global/list/endgame_exits = list()
var/global/list/endgame_safespawns = list()
+44
View File
@@ -0,0 +1,44 @@
#define DEFAULT_MAX_RUNES 25
/var/datum/controller/subsystem/cult/SScult
/datum/controller/subsystem/cult
name = "Cult"
flags = SS_NO_FIRE
var/list/runes_by_name = list()
var/list/rune_list = list()
var/list/teleport_runes = list()
var/list/static/teleport_network = list("Vernuth", "Koglan", "Irgros", "Akon")
var/rune_limit = DEFAULT_MAX_RUNES //in the SS so admins can easily modify it if needed
var/rune_boost = 0
var/tome_data = ""
/datum/controller/subsystem/cult/New()
NEW_SS_GLOBAL(SScult)
/datum/controller/subsystem/cult/Initialize()
. = ..()
for(var/rune in subtypesof(/datum/rune))
var/datum/rune/R = new rune
runes_by_name[R.name] = rune
tome_data += "<b>[R.name]</b>: <i>[R.desc]</i>"
tome_data += "This rune [R.can_be_talisman() ? "<b><i>can</i></b>" : "<b><i>cannot</i></b>"] be turned into a talisman.<br>"
/datum/controller/subsystem/cult/proc/add_rune(var/datum/rune/R)
if(check_rune_limit())
return FALSE
else
rune_list += R
return TRUE
/datum/controller/subsystem/cult/proc/check_rune_limit()
return ((length(rune_list) + rune_boost + length(cult.current_antagonists)) >= rune_limit)
/datum/controller/subsystem/cult/proc/remove_rune(var/datum/rune/R)
if(R in rune_list)
rune_list -= R
return TRUE
else
return FALSE
@@ -316,7 +316,6 @@
SearchVar(exclude_jobs)
SearchVar(visual_nets)
SearchVar(cameranet)
SearchVar(rune_list)
SearchVar(escape_list)
SearchVar(endgame_exits)
SearchVar(endgame_safespawns)
+1 -1
View File
@@ -48,7 +48,7 @@ In short:
KillMobs()
OverlayAndAmbientSet()
rune_boost += 9001 //basically removing the rune cap
SScult.rune_boost += 9001 //basically removing the rune cap
/datum/universal_state/hell/proc/AreaSet()
for(var/area/A in all_areas)
+11 -10
View File
@@ -1,9 +1,7 @@
/obj/item/paper/talisman
icon_state = "paper_talisman"
var/datum/callback/imbued_rune
var/network // Which network the teleport talisman is on
var/uses = 1
var/rune
var/datum/rune/rune
info = "<center><img src='talisman.png'></center><br/><br/>"
/obj/item/paper/talisman/Initialize()
@@ -11,22 +9,25 @@
name = "bloodied paper"
color = "FF6D6D"
/obj/item/paper/talisman/Destroy()
QDEL_NULL(rune)
return ..()
/obj/item/paper/talisman/examine(mob/user)
..()
if(iscultist(user) && rune)
to_chat(user, "The spell inscription reads: <span class='cult'><b><i>[rune]</i></b></span>.")
to_chat(user, "The spell inscription reads: <span class='cult'><b><i>[rune.name]</i></b></span>.")
/obj/item/paper/talisman/attack_self(mob/living/user)
if(iscultist(user))
if(imbued_rune)
if(imbued_rune.Invoke(user, src))
user.take_organ_damage(5, 0)
use()
if(rune)
user.say("INVOKE!")
rune.activate(user, src)
return
else
to_chat(user, span("cult", "This talisman has not been imbued with power!"))
to_chat(user, SPAN_CULT("This talisman has no power."))
else
to_chat(user, span("cult", "You see strange symbols on the paper. Are they supposed to mean something?"))
to_chat(user, SPAN_CULT("The smell of blood permeates this paper. That can't be good."))
return
/obj/item/paper/talisman/proc/use()
+35 -114
View File
@@ -8,76 +8,6 @@
w_class = 2.0
unique = TRUE
slot_flags = SLOT_BELT
var/tomedat = ""
tomedat = {"<html>
<head>
<style>
h1 {font-size: 25px; margin: 15px 0px 5px;}
h2 {font-size: 20px; margin: 15px 0px 5px;}
li {margin: 2px 0px 2px 15px;}
ul {list-style: none; margin: 5px; padding: 0px;}
ol {margin: 5px; padding: 0px 15px;}
</style>
</head>
<body>
<h1>The scriptures of Nar-Sie, The One Who Sees, The Geometer of Blood.</h1>
<i>The book is written in an unknown dialect, there are lots of pictures of various complex geometric shapes. You find some notes in Tau Ceti Basic that give you basic understanding of the many runes written in the book.</i><br>
<i>Below is the summary of the runes.</i> <br>
<h2>Rune Descriptions</h2>
<h3>Teleport self</h3>
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. You can imbue this rune into a talisman, giving you a great escape mechanism.<br>
<h3>Teleport other</h3>
Teleport other allows for teleportation for any movable object to another rune with the same third word. You need 3 cultists chanting the invocation for this rune to work.<br>
<h3>Summon new tome</h3>
Invoking this rune summons a new arcane tome.
<h3>Convert a person</h3>
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 possess high authority) have strong enough will to stay true to their old ideals. <br>
<h3>Summon Nar-Sie</h3>
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.<br>
<h3>Disable Technology</h3>
Invoking this rune creates a strong electromagnetic pulse in a small radius, making it basically analogous to an EMP grenade. You can imbue this rune into a talisman, making it a decent defensive item.<br>
<h3>Drain Blood</h3>
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.<br>
<h3>Raise Dead</h3>
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, awake 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.<br>
<h3>Hide runes</h3>
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.<br>
<h3>Reveal runes</h3>
This rune is made to reverse the process of hiding a rune. It reveals all hidden runes in a rather large area around it.
<h3>Leave your body</h3>
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.<br>
<h3>Manifest a ghost</h3>
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 there's a ghost standing over the rune, it will materialise, and will live as long as you don't 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.<br>
<h3>Imbue a talisman</h3>
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, disable technology, communicate, deafen, blind and stun.<br>
<h3>Sacrifice</h3>
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.
<h3>Create a wall</h3>
Invoking this rune solidifies the air above it, creating an an invisible wall. To remove the wall, simply invoke the rune again.
<h3>Summon cultist</h3>
This rune allows you to summon a fellow cultist to your location. The target cultist must be unhandcuffed and 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.<br>
<h3>Free a cultist</h3>
This rune unhandcuffs and unbuckles any cultist of your choice, no matter where he is. You need to have 3 people invoking the rune for it to work. Invoking it takes heavy strain on the bodies of all chanting cultists.<br>
<h3>Deafen</h3>
This rune temporarily deafens all non-cultists around you.<br>
<h3>Blind</h3>
This rune temporarily blinds all non-cultists around you. Very robust. Use together with the deafen rune to leave your enemies completely helpless.<br>
<h3>Blood boil</h3>
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.<br>
<h3>Communicate</h3>
Invoking this rune allows you to relay a message to all cultists on the station and nearby space objects.
<h3>Stun</h3>
When invoked directly as a rune, it releases some dark energy, briefly stunning everyone around. When imbued into a talisman, you can force some dark energy into a person, causing their eyes to flash, and their words to falter, keeping them quiet. However, the effect wears off rather fast.<br>
<h3>Equip Armor</h3>
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.<br>
<h3>See Invisible</h3>
When invoked when standing on it, this rune allows the user to see the world beyond as long as he does not move.<br>
</body>
</html>
"}
/obj/item/book/tome/attack(mob/living/M, mob/living/user)
if(isobserver(M))
@@ -108,23 +38,27 @@
/obj/item/book/tome/attack_self(mob/living/user)
if(use_check_and_message(user))
if(!ishuman(user))
return
if(iscultist(user))
if(!istype(user.loc, /turf))
to_chat(user, span("warning", "You do not have enough space to write a proper rune."))
var/mob/living/carbon/human/scribe = user
if(use_check_and_message(scribe))
return
if(iscultist(scribe))
if(!isturf(scribe.loc))
to_chat(scribe, span("warning", "You do not have enough space to write a proper rune."))
return
var/turf/T = get_turf(user)
var/turf/T = get_turf(scribe)
if(T.is_hole || T.is_space())
to_chat(user, span("warning", "You are unable to write a rune here."))
to_chat(scribe, span("warning", "You are unable to write a rune here."))
return
// This counts how many runes exist in the game, for some sort of arbitrary rune limit. I trust the old devs had their reasons. - Geeves
if(length(rune_list) >= 25 + rune_boost + cult.current_antagonists.len)
to_chat(user, span("warning", "The cloth of reality can't take that much of a strain. Remove some runes first!"))
if(SScult.check_rune_limit())
to_chat(scribe, span("warning", "The cloth of reality can't take that much of a strain. Remove some runes first!"))
return
else
switch(alert("What shall you do with the tome?", "Tome of Nar'sie", "Read it", "Scribe a rune", "Cancel"))
@@ -133,69 +67,56 @@
if("Read it")
if(use_check_and_message(user))
return
user << browse("[tomedat]", "window=Arcane Tome")
user << browse("[SScult.tome_data]", "window=Arcane Tome")
return
//only check if they want to scribe a rune, so they can still read if standing on a rune
if(locate(/obj/effect/rune) in user.loc)
to_chat(user, span("warning", "There is already a rune in this location."))
if(locate(/obj/effect/rune) in scribe.loc)
to_chat(scribe, span("warning", "There is already a rune in this location."))
return
if(use_check_and_message(user))
if(use_check_and_message(scribe))
return
var/chosen_rune
var/network
chosen_rune = input("Choose a rune to scribe.") in rune_types
//var/network
chosen_rune = input("Choose a rune to scribe.") as null|anything in SScult.runes_by_name
if(!chosen_rune)
return
if(chosen_rune == "None")
to_chat(user, span("notice", "You decide against scribing a rune, perhaps you should take this time to study your notes."))
return
if(chosen_rune == "Teleport")
network = input(user, "Choose a teleportation network for the rune to connect to.", "Teleportation Rune") in teleport_network
if(use_check_and_message(user))
if(use_check_and_message(scribe))
return
user.visible_message(span("warning", "\The [user] slices open a finger and begins to chant and paint symbols on the floor."), span("notice", "You slice open one of your fingers and begin drawing a rune on the floor whilst softly 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
scribe.visible_message(SPAN_CULT("[scribe] slices open their palm with a ceremonial knife, drawing arcane symbols with their blood..."))
playsound(scribe, 'sound/weapons/bladeslice.ogg', 50, FALSE)
scribe.drip(4)
if(do_after(user, 50))
var/area/A = get_area(user)
if(use_check_and_message(user))
if(do_after(scribe, 50))
var/area/A = get_area(scribe)
if(use_check_and_message(scribe))
return
//prevents using multiple dialogs to layer runes.
if(locate(/obj/effect/rune) in user.loc) //This is check is done twice. once when choosing to scribe a rune, once here
to_chat(user, span("warning", "There is already a rune in this location."))
if(locate(/obj/effect/rune) in get_turf(scribe)) //This is check is done twice. once when choosing to scribe a rune, once here
to_chat(scribe, span("warning", "There is already a rune in this location."))
return
log_and_message_admins("created \an [chosen_rune] rune at \the [A.name] - [user.loc.x]-[user.loc.y]-[user.loc.z].") //only message if it's actually made
log_and_message_admins("created \an [chosen_rune] at \the [A.name] - [user.loc.x]-[user.loc.y]-[user.loc.z].") //only message if it's actually made
var/mob/living/carbon/human/H = user
var/rune_path = rune_types[chosen_rune]
var/obj/effect/rune/R = new rune_path(get_turf(user))
to_chat(user, span("notice", "You finish drawing the arcane markings of the Geometer."))
R.blood_DNA = list()
R.blood_DNA[H.dna.unique_enzymes] = H.dna.b_type
if(network)
R.network = network
R.cult_description = chosen_rune
if(ishuman(user))
var/mob/living/carbon/human/scribe = user
R.color = scribe.species.blood_color
return
var/obj/effect/rune/R = new(get_turf(scribe), SScult.runes_by_name[chosen_rune])
to_chat(scribe, SPAN_CULT("You finish drawing the Geometer's markings."))
scribe.blood_DNA = list()
scribe.blood_DNA[scribe.dna.unique_enzymes] = scribe.dna.b_type
R.color = scribe.species.blood_color
else
to_chat(user, span("cult", "The book seems full of illegible scribbles."))
return
/obj/item/book/tome/examine(mob/user)
..(user)
if(!iscultist(user) || !isobserver(user))
desc = "An old, dusty tome with frayed edges and a sinister looking cover."
to_chat(user, "An old, dusty tome with frayed edges and a sinister looking cover.")
else
desc = "The scriptures of Nar-Sie, The One Who Sees, The Geometer of Blood. Contains the details of every ritual his followers could think of. Most of these are useless, though."
to_chat(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. Most of these are useless, though.")
/obj/item/book/tome/cultify()
return
+44
View File
@@ -0,0 +1,44 @@
#define NO_TALISMAN 1
#define HAS_SPECIAL_TALISMAN_ACTION 2
/datum/rune
var/name // The rune's name.
var/desc // The rune's description. This and the name are used in the guide.
var/rune_flags // Things like if it can be a talisman or not.
var/atom/movable/parent
/datum/rune/New(atom/owner)
..()
parent = owner
/datum/rune/proc/activate(var/mob/living/user, var/atom/movable/A)
if(!isliving(user))
return
if(!istype(A, /obj/effect/rune) && (rune_flags & HAS_SPECIAL_TALISMAN_ACTION) && can_be_talisman())
do_talisman_action(user, A)
else
do_rune_action(user, A)
/datum/rune/proc/do_rune_action(var/mob/living/user, var/atom/movable/A)
return
/datum/rune/proc/do_talisman_action(var/mob/living/user, var/atom/movable/A)
return
/datum/rune/proc/do_tome_action(var/mob/living/user, var/atom/movable/A)
to_chat(user, span("notice", "You retrace your steps, carefully undoing the lines of the rune."))
playsound(parent, 'sound/effects/projectile_impact/energy_meat1.ogg')
qdel(parent)
/datum/rune/proc/fizzle(var/mob/living/user, var/atom/movable/A)
to_chat(user, SPAN_CULT("The rune sizzles with no result."))
playsound(A, 'sound/effects/projectile_impact/energy_meat2.ogg', 30)
/datum/rune/proc/get_normal_fluff_text()
. = SPAN_WARNING("A heavy smell of blood permeates the area around the arcane drawings.")
/datum/rune/proc/get_cultist_fluff_text()
. = SPAN_CULT("You remember clear as the night that this is \an [name].")
/datum/rune/proc/can_be_talisman()
return !(rune_flags & NO_TALISMAN)
+12 -13
View File
@@ -1,12 +1,11 @@
/obj/effect/rune/armor
can_talisman = TRUE
/datum/rune/armor
name = "forging rune"
desc = "A rune used to create a set of armor and a sword for the acolytes to use."
/obj/effect/rune/armor/do_rune_action(mob/living/user, obj/O = src)
if(istype(O, /obj/effect/rune))
user.say("N'ath reth sh'yro eth d[pick("'","`")]raggathnor!")
else
user.whisper("N'ath reth sh'yro eth d[pick("'","`")]raggathnor!")
user.visible_message(span("warning", "The rune disappears with a flash of red light, and a set of armor appears on [user]..."), span("cult", "You are blinded by the flash of red light! You feel the armor of the Dark One form around you."))
/datum/rune/armor/do_rune_action(mob/living/user, atom/movable/A)
user.say("N'ath reth sh'yro eth d'raggathnor!")
user.visible_message(SPAN_DANGER("A flash of red light appears around [user], as a set of armor envelops their body!"),
SPAN_CULT("A refreshing feeling envelops you; the armor of the Dark One is once again protecting you."))
if(istype(user, /mob/living/simple_animal/construct))
var/mob/living/simple_animal/construct/C = user
@@ -17,9 +16,9 @@
construct_class = alert(C, "Please choose which type of construct you wish to become.", "Construct Selection", "Juggernaut", "Wraith", "Artificer")
var/list/static/construct_types = list("Juggernaut" = /mob/living/simple_animal/construct/armoured,
"Wraith" = /mob/living/simple_animal/construct/wraith,
"Artificer" = /mob/living/simple_animal/construct/builder,
"Harvester" = /mob/living/simple_animal/construct/harvester)
"Wraith" = /mob/living/simple_animal/construct/wraith,
"Artificer" = /mob/living/simple_animal/construct/builder,
"Harvester" = /mob/living/simple_animal/construct/harvester)
var/construct_path = construct_types[construct_class]
var/mob/living/simple_animal/construct/Z = new construct_path(get_turf(C))
@@ -37,10 +36,10 @@
user.equip_to_slot_or_del(new /obj/item/storage/backpack/cultpack(user), slot_back)
user.put_in_hands(new /obj/item/melee/cultblade(user))
qdel(O)
qdel(A)
return TRUE
/obj/effect/rune/armor/proc/construct_msg(mob/construct, var/type)
/datum/rune/armor/proc/construct_msg(mob/living/construct, var/type)
switch(type)
if("Juggernaut")
to_chat(construct, span("cult", "You are playing a Juggernaut. Though slow, you can withstand extreme punishment, and rip apart enemies and walls alike."))
+32 -44
View File
@@ -1,46 +1,34 @@
/obj/effect/rune/blind
can_talisman = TRUE
/datum/rune/blind
name = "blinding rune"
desc = "A rune used to blind the unbelievers."
rune_flags = HAS_SPECIAL_TALISMAN_ACTION
/obj/effect/rune/blind/do_rune_action(mob/living/user, obj/O = src)
if(istype(O, /obj/effect/rune))
var/list/affected = list()
for(var/mob/living/carbon/C in viewers(get_turf(O)))
if(iscultist(C))
continue
var/obj/item/nullrod/N = locate() in C
if(N)
continue
C.eye_blurry += 50
C.eye_blind += 20
if(prob(5))
C.disabilities |= NEARSIGHTED
if(prob(10))
C.sdisabilities |= BLIND
to_chat(C, span("danger", "Suddenly you see a red flash that blinds you!"))
affected += C
if(length(affected))
user.say("Sti[pick("'","`")] kaliesin!")
to_chat(user, span("warning", "The rune flashes, blinding those who not follow the Nar-Sie, and dissipates into fine dust."))
admin_attacker_log_many_victims(user, affected, "Used a blindness rune.", "Was victim of a blindness rune.", "used a blindness rune on")
qdel(O)
return TRUE
else
return fizzle(user)
/datum/rune/blind/do_rune_action(mob/living/user, atom/movable/A)
do_blind(user, A, 3, 1, TRUE)
/datum/rune/blind/do_talisman_action(mob/living/user, var/atom/movable/A)
do_blind(user, A, 3, 0.5, FALSE)
/datum/rune/blind/proc/do_blind(mob/living/user, atom/movable/A, var/range = 7, var/effect_mod = 1, var/special_effects = TRUE)
var/list/affected = list()
for(var/mob/living/carbon/C in view(A, range))
if(iscultist(C))
continue
var/obj/item/nullrod/N = locate() in C
if(N)
continue
C.eye_blurry += 50 / effect_mod
C.eye_blind += 20 / effect_mod
if(prob(5) && special_effects)
C.disabilities |= NEARSIGHTED
if(prob(10))
C.sdisabilities |= BLIND
to_chat(C, span("danger", "Suddenly you see a red flash that blinds you!"))
affected += C
if(length(affected))
user.say("Sti'kaliesin!")
to_chat(user, span("warning", "The rune flashes, blinding those who not follow the Nar-Sie, and dissipates into fine dust."))
admin_attacker_log_many_victims(user, affected, "Used a blindness rune.", "Was victim of a blindness rune.", "used a blindness rune on")
qdel(A)
else
var/list/affected = list()
for(var/mob/living/carbon/C in view(2,user))
if(iscultist(C))
continue
var/obj/item/nullrod/N = locate() in C
if(N)
continue
C.eye_blurry += 30
C.eye_blind += 10
//talismans is weaker.
affected += C
to_chat(C, span("warning", "You feel a sharp pain in your eyes, and the world disappears into darkness.."))
if(length(affected))
user.whisper("Sti[pick("'","`")] kaliesin!")
to_chat(user, span("warning", "Your talisman turns into gray dust, blinding those who not follow the Nar-Sie."))
admin_attacker_log_many_victims(user, affected, "Used a blindness talisman.", "Was victim of a blindness talisman.", "used a blindness talisman on")
return TRUE
return fizzle(user, A)
+12 -7
View File
@@ -1,7 +1,12 @@
/obj/effect/rune/blood_boil/do_rune_action(mob/living/user) //cultists need at least one DANGEROUS rune. Even if they're all stealthy.
/datum/rune/blood_boil
name = "blood boiling rune"
desc = "A rune used to evaporate the blood of the non-believers. Show them the will of the Dark One!"
rune_flags = NO_TALISMAN
/datum/rune/blood_boil/do_rune_action(mob/living/user, atom/movable/A) //cultists need at least one DANGEROUS rune. Even if they're all stealthy.
var/list/cultists = list()
var/list/victims = list()
for(var/mob/living/carbon/C in orange(1, src))
for(var/mob/living/carbon/C in orange(1, A))
if(iscultist(C) && !C.stat)
cultists += C
if(length(cultists) >= 3)
@@ -12,15 +17,15 @@
if(N)
continue
M.take_overall_damage(50, 50)
to_chat(M, span("danger", "Your blood boils!"))
to_chat(M, SPAN_DANGER(FONT_HUGE("You're burning from the inside!")))
victims += M
for(var/mob/living/carbon/human/C in orange(1, src))
for(var/mob/living/carbon/human/C in orange(1, A))
if(iscultist(C) && !C.stat)
C.say("Dedo ol[pick("'","`")]btoh!")
C.say("Dedo ol'btoh! A'oil'e!")
C.take_overall_damage(15, 0)
admin_attacker_log_many_victims(user, victims, "Used a blood boil rune.", "Was the victim of a blood boil rune.", "used a blood boil rune on")
log_and_message_admins_many(cultists - user, "assisted activating a blood boil rune.")
qdel(src)
qdel(A)
return TRUE
else
return fizzle(user)
return fizzle(user, A)
+48 -38
View File
@@ -1,40 +1,50 @@
/obj/effect/rune/blood_drain
can_talisman = TRUE
/datum/rune/blood_drain
name = "blood draining rune"
desc = "This rune is used to drain the blood of non-believers into a fellow acolyte. All must be standing on the rune."
rune_flags = NO_TALISMAN
var/list/mob/living/carbon/human/lambs
var/mob/living/carbon/human/target
/obj/effect/rune/blood_drain/do_rune_action(mob/living/user)
var/drain
for(var/obj/effect/rune/blood_drain/R in rune_list)
for(var/mob/living/carbon/D in get_turf(R))
if(D.stat != DEAD)
admin_attack_log(user, D, "Used a blood drain rune.", "Was victim of a blood drain rune.", "used a blood drain rune on")
var/bdrain = rand(1, 25)
to_chat(D, span("warning", "You feel weakened."))
D.take_overall_damage(bdrain, 0)
drain += bdrain
if(!drain)
return fizzle(user)
user.say("Yu[pick("'","`")]gular faras desdae. Havas mithum javara. Umathar uf'kal thenar!")
user.visible_message("<span class='danger'>Blood flows from the rune into [user]!</span>", \
"<span class='danger'>The blood starts flowing from the rune and into your frail body. You feel... empowered.</span>", \
"<span class='warning'>You hear a liquid flowing.</span>")
playsound(user, 'sound/magic/enter_blood.ogg', 100, 1)
/datum/rune/blood_drain/Destroy()
STOP_PROCESSING(SSprocessing, src)
LAZYCLEARLIST(lambs)
target = null
return ..()
if(user.bhunger)
user.bhunger = max(user.bhunger-2*drain,0)
if(drain >= 50)
user.visible_message("<span class='danger'>[user]'s eyes give off an eerie red glow!</span>", \
"<span class='danger'>...but it wasn't nearly enough. You crave, crave for more. The hunger consumes you from within.</span>", \
"<span class='warning'>You hear a heartbeat.</span>")
user.bhunger += drain
while(user.bhunger)
user.bhunger--
sleep(50)
user.take_overall_damage(3, 0)
return
user.heal_organ_damage(drain%5, 0)
drain-=drain%5
while(drain)
drain -= 5
sleep(2)
user.heal_organ_damage(5, 0)
return TRUE
/datum/rune/blood_drain/do_rune_action(mob/living/user, atom/movable/A)
LAZYINITLIST(lambs)
for(var/mob/living/carbon/human/H in get_turf(A))
if(iscultist(H))
if(!target)
target = H
continue
if(H.stat == DEAD)
continue
if(H.species.flags & NO_BLOOD)
continue
LAZYADD(lambs, H)
if(length(lambs))
START_PROCESSING(SSprocessing, src)
else
fizzle(user, A)
return TRUE
/datum/rune/blood_drain/process()
if(target && length(lambs) && (get_turf(target) == get_turf(parent)))
for(var/mob/living/carbon/human/H in lambs)
if(get_turf(H) == get_turf(parent))
if(target.vessel.get_reagent_amount("blood") + 10 > H.species.blood_volume)
to_chat(target, SPAN_CULT("You feel refreshed!"))
interrupt()
target.whisper("Sa'ii, ble-nii...")
H.vessel.trans_to_mob(target, 10, CHEM_BLOOD)
H.take_overall_damage(10, 10)
playsound(target, 'sound/magic/enter_blood.ogg', 50, 1)
else
interrupt()
else
interrupt()
/datum/rune/blood_drain/proc/interrupt()
parent.visible_message(SPAN_CULT("\The [parent] suddenly disappears, the incantation broken!"))
qdel(parent)
+9 -14
View File
@@ -1,23 +1,18 @@
// returns FALSE if the rune is not used. returns TRUE if the rune is used.
/obj/effect/rune/communicate/do_rune_action(mob/living/user)
. = TRUE // Default output is TRUE. If the rune is deleted it will return TRUE
/datum/rune/communicate
name = "communication rune"
desc = "This rune is used to send a message to all acolytes."
/datum/rune/communicate/do_rune_action(mob/living/user, atom/movable/A)
var/input = input(user, "Please choose a message to tell to the other acolytes.", "Voice of Blood", "")//sanitize() below, say() and whisper() have their own
if(!input)
if(istype(src))
fizzle(user)
return FALSE
fizzle(user, A)
if(istype(src, /obj/effect/rune))
user.say("O bidai nabora se[pick("'","`")]sma!")
user.say("[input]")
else
user.whisper("O bidai nabora se[pick("'","`")]sma!")
user.say("O bidai nabora se'sma!")
user.whisper("[input]")
input = sanitize(input)
log_and_message_admins("used a communicate rune to say '[input]'")
for(var/datum/mind/H in cult.current_antagonists)
if(H.current)
to_chat(H.current, span("cult", "Cult Broadcast: \"[input]\""))
qdel(src)
return TRUE
to_chat(H.current, SPAN_CULT("The familiar voice of [H.current] fills your mind: [input]"))
qdel(A)
@@ -1,25 +1,33 @@
/obj/effect/rune/convert/do_rune_action(mob/living/user)
var/mob/living/attacker = user
var/mob/living/carbon/target = null
for(var/mob/living/carbon/M in src.loc)
/datum/rune/convert
name = "conversion rune"
desc = "A rune used to convert the Unenlightened."
rune_flags = NO_TALISMAN
var/list/converting
/datum/rune/convert/do_rune_action(mob/living/user, atom/movable/A)
LAZYINITLIST(converting)
var/mob/living/carbon/target
for(var/mob/living/carbon/M in get_turf(A))
if(!iscultist(M) && M.stat < DEAD && !(M in converting))
target = M
break
if(!target) //didn't find any new targets
if(!converting.len)
fizzle(user)
fizzle(user, A)
LAZYCLEARLIST(converting)
else
to_chat(user, span("cult", "You sense that the power of the dark one is already working away at them."))
to_chat(user, SPAN_CULT("They are already being enlightened by the Dark One."))
return
user.say("Mah[pick("'","`")]weyh pleggh at e'ntrath!")
user.say("Mah'weyh pleggh at e'ntrath!")
converting |= target
LAZYDISTINCTADD(converting, target)
var/list/waiting_for_input = list(target = 0) //need to box this up in order to be able to reset it again from inside spawn, apparently
var/initial_message = 0
while(target in converting)
if(target.loc != src.loc || target.stat == DEAD)
if(get_turf(target) != get_turf(A) || target.stat == DEAD)
converting -= target
if(target.getFireLoss() < 100)
target.hallucination = min(target.hallucination, 500)
@@ -28,7 +36,7 @@
target.take_overall_damage(0, rand(5, 20)) // You dirty resister cannot handle the damage to your mind. Easily. - even cultists who accept right away should experience some effects
// Resist messages go!
if(initial_message) //don't do this stuff right away, only if they resist or hesitate.
admin_attack_log(attacker, target, "Used a convert rune", "Was subjected to a convert rune", "used a convert rune on")
admin_attack_log(user, target, "Used a convert rune", "Was subjected to a convert rune", "used a convert rune on")
switch(target.getFireLoss())
if(0 to 25)
to_chat(target, span("cult", "Your blood boils as you force yourself to resist the corruption invading every corner of your mind."))
@@ -83,4 +91,5 @@
target.setBrainLoss(0) // nar'sie heals you
sound_to(target, 'sound/effects/bloodcult.ogg')
sleep(100) //proc once every 10 seconds
return TRUE
LAZYCLEARLIST(converting)
return TRUE
@@ -1,8 +1,8 @@
/obj/effect/rune/create_construct
can_talisman = TRUE
/datum/rune/construct
name = "construct rune"
desc = "This rune is used to create a shell for one of our constructs. We must populate it with a soul in a soul shard, however."
/obj/effect/rune/create_construct/do_rune_action(mob/living/user, obj/O = src)
user.say("N[pick("'","`")]ath reth sh'yro eth d'raggathnor!")
new /obj/structure/constructshell/cult(get_turf(O))
qdel(O)
return TRUE
/datum/rune/construct/do_rune_action(mob/living/user, atom/movable/A)
user.say("N'ath reth! Sh'yro eth! D'raggathnor!")
new /obj/structure/constructshell/cult(get_turf(A))
qdel(A)
@@ -1,9 +1,13 @@
//only hide, emp, teleport, deafen, blind and tome runes can be imbued atm
/obj/effect/rune/create_talisman/do_rune_action(mob/living/user)
/datum/rune/talisman
name = "talisman creation rune"
desc = "This rune creates a talisman out of a rune around it."
rune_flags = NO_TALISMAN
/datum/rune/talisman/do_rune_action(mob/living/user, atom/movable/A)
var/obj/item/paper/new_talisman
var/cant_talisman
for(var/obj/item/paper/P in get_turf(src))
for(var/obj/item/paper/P in get_turf(A))
if(!P.info)
new_talisman = P
break
@@ -11,26 +15,24 @@
cant_talisman = TRUE
if(!new_talisman)
if(cant_talisman)
to_chat(user, span("cult", "The paper is tainted. It is unsuitable."))
return fizzle(user)
to_chat(user, SPAN_CULT("A tainted paper is unsuitable to bear the markings of the Dark One!"))
return fizzle(user, A)
var/obj/effect/rune/imbued_from
for(var/obj/effect/rune/R in orange(1, src))
if(R == src)
for(var/obj/effect/rune/R in orange(1, A))
if(R.rune?.type == src.type)
continue
if(!R.can_talisman)
if(!R.rune?.can_be_talisman())
continue
var/obj/item/paper/talisman/T = new /obj/item/paper/talisman(get_turf(src))
T.imbued_rune = CALLBACK(R, /obj/effect/rune/.proc/do_rune_action)
T.rune = R.cult_description
var/obj/item/paper/talisman/T = new /obj/item/paper/talisman(get_turf(A))
imbued_from = R
if(R.network)
T.network = R.network
T.rune = R.rune
break
if(imbued_from)
visible_message(span("warning", "The runes turn into dust, which then forms into an arcane image on the paper."))
user.say("H'drak v[pick("'","`")]loso, mir'kanas verbot!")
A.visible_message(SPAN_CULT("The blood from \the [imbued_from] floods into a talisman!"))
user.say("H'drak v'loso! Mir'kanas verbot!")
qdel(imbued_from)
qdel(new_talisman)
playsound(A, 'sound/magic/enter_blood.ogg', 50)
else
return fizzle(user)
return fizzle(user, A)
+28 -42
View File
@@ -1,44 +1,30 @@
/obj/effect/rune/deafen
can_talisman = TRUE
/datum/rune/deafen
name = "deafening rune"
desc = "This rune is used to deafen all unbelievers in a wide range around us."
rune_flags = HAS_SPECIAL_TALISMAN_ACTION
/obj/effect/rune/deafen/do_rune_action(mob/living/user, obj/O = src)
if(istype(O, /obj/effect/rune))
var/list/affected = list()
for(var/mob/living/carbon/C in range(7, get_turf(O)))
if(iscultist(C))
continue
var/obj/item/nullrod/N = locate() in C
if(N)
continue
C.ear_deaf += 50
to_chat(C, span("warning", "The world around you suddenly becomes quiet."))
affected += C
if(prob(1))
C.sdisabilities |= DEAF
if(affected.len)
user.say("Sti[pick("'","`")] kaliedir!")
to_chat(user, span("cult", "The world becomes quiet as the deafening rune dissipates into fine dust."))
admin_attacker_log_many_victims(user, affected, "Used a deafen rune.", "Was victim of a deafen rune.", "used a deafen rune on")
qdel(O)
else
return fizzle(user)
/datum/rune/deafen/do_rune_action(mob/living/user, atom/movable/A)
do_deafen(user, A, 1, TRUE)
/datum/rune/deafen/do_talisman_action(mob/living/user, var/atom/movable/A)
do_deafen(user, A, 5, 0.5, FALSE)
/datum/rune/deafen/proc/do_deafen(mob/living/user, atom/movable/A, var/radius = 7, var/effect_mod = 1, var/special_effects = TRUE)
var/list/affected = list()
for(var/mob/living/carbon/C in range(radius, get_turf(A)))
if(iscultist(C))
continue
var/obj/item/nullrod/N = locate() in C
if(N)
continue
C.ear_deaf += 50 / effect_mod
to_chat(C, SPAN_DANGER("Your ears ring as you go deaf!"))
affected += C
if(prob(1) && special_effects)
C.sdisabilities |= DEAF
if(affected.len)
user.say("Sti'kaliedir!")
admin_attacker_log_many_victims(user, affected, "Used a deafen rune.", "Was victim of a deafen rune.", "used a deafen rune on")
qdel(A)
else
var/list/affected = list()
for(var/mob/living/carbon/C in range(7, user))
if(iscultist(C))
continue
var/obj/item/nullrod/N = locate() in C
if(N)
continue
C.ear_deaf += 30
//talismans is weaker.
to_chat(C, span("warning", "The world around you suddenly becomes quiet."))
affected += C
if(affected.len)
user.whisper("Sti[pick("'","`")] kaliedir!")
to_chat(user, span("warning", "Your talisman turns into gray dust, deafening everyone around."))
admin_attacker_log_many_victims(user, affected, "Used a deafen rune.", "Was victim of a deafen rune.", "used a deafen rune on")
for(var/mob/V in orange(1, get_turf(O)))
if(!iscultist(V))
to_chat(V, span("warning", "Dust flows from [user]'s hands for a moment, and the world suddenly becomes quiet.."))
return TRUE
return fizzle(user, A)
+16 -17
View File
@@ -1,24 +1,23 @@
/obj/effect/rune/emp
can_talisman = TRUE
/datum/rune/emp
name = "EMP rune"
desc = "This rune is used to disable electronics in an area around us."
rune_flags = HAS_SPECIAL_TALISMAN_ACTION
/obj/effect/rune/emp/do_rune_action(mob/living/user, obj/O = src)
var/radius = 4
if(istype(O, /obj/effect/rune))
user.say("Ta'gh fara[pick("'","`")]qha fel d'amar det!")
log_and_message_admins("activated an EMP rune.")
else
user.whisper("Ta'gh fara[pick("'","`")]qha fel d'amar det!")
radius = 2
log_and_message_admins("activated an EMP talisman.")
var/turf/T = get_turf(O)
/datum/rune/emp/do_rune_action(mob/living/user, atom/movable/A)
do_emp(user, A, 2)
/datum/rune/emp/do_talisman_action(mob/living/user, var/atom/movable/A)
do_emp(user, A, 1)
/datum/rune/emp/proc/do_emp(mob/living/user, atom/movable/A, radius = 2)
user.say("Ta'gh fara'qha fel d'amar det!")
log_and_message_admins("activated an EMP [A].")
var/turf/T = get_turf(A)
playsound(T, 'sound/magic/Disable_Tech.ogg', 25, 1)
var/list/ex = list(user) // exclude caster
for(var/mob/M in range(radius, T))
for(var/mob/M in range(2, T))
if(iscultist(M))
ex += M
else
continue
empulse(T, 1, radius, exclude = ex)
qdel(O)
return TRUE
qdel(A)
+13 -9
View File
@@ -1,18 +1,23 @@
/obj/effect/rune/freedom/do_rune_action(mob/living/user)
/datum/rune/freedom
name = "freedom rune"
desc = "This rune is used to free a cultist of our choice from captivity."
rune_flags = NO_TALISMAN
/datum/rune/freedom/do_rune_action(mob/living/user, atom/movable/A)
var/list/mob/living/carbon/human/cultists = list()
for(var/datum/mind/H in cult.current_antagonists)
if(istype(H.current,/mob/living/carbon/human))
if(ishuman(H.current))
cultists += H.current
var/list/mob/living/carbon/users = list()
for(var/mob/living/carbon/C in orange(1, src))
for(var/mob/living/carbon/C in orange(1, A))
if(iscultist(C) && !C.stat)
users += C
if(users.len >= 3)
if(length(users) >= 3)
var/mob/living/carbon/human/cultist = input("Choose a cultist you wish to free.", "Followers of Geometer") as null|anything in (cultists - users)
if(!cultist)
return fizzle(user)
return fizzle(user, A)
if(cultist == user) //just to be sure.
return
@@ -55,7 +60,6 @@
if(cultist_free)
to_chat(C, span("cult", "\The [cultist] is already free."))
else
C.say("Khari[pick("'","`")]d! Gual'te nikka!")
qdel(src)
else if(istype(src, /obj/effect/rune))
return fizzle(user)
C.say("Khari'd! Gual'te nikka!")
qdel(A)
return fizzle(user, A)
+10 -5
View File
@@ -1,8 +1,13 @@
/obj/effect/rune/ethereal/do_rune_action(mob/living/user) //some bits copypastaed from admin tools - Urist
if(get_turf(user) == get_turf(src))
/datum/rune/ethereal
name = "ethereal rune"
desc = "This rune is used to temporarily send an acolyte into the afterlife."
rune_flags = NO_TALISMAN
/datum/rune/ethereal/do_rune_action(mob/living/user, atom/movable/A) //some bits copypastaed from admin tools - Urist
if(get_turf(user) == get_turf(A) && ishuman(user))
var/mob/living/carbon/human/L = user
user.say("Fwe[pick("'","`")]sh mah erl nyag r'ya!")
user.visible_message("<span class='warning'>[user]'s eyes glow blue as \he freezes in place, absolutely motionless.</span>", \
user.say("Fwe'sh maherl! Nyag r'ya!")
user.visible_message("<span class='warning'>[user]'s eyes glow red as \he freezes in place, absolutely motionless.</span>", \
"<span class='warning'>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...</span>", \
"<span class='warning'>You hear only complete silence for a moment.</span>")
announce_ghost_joinleave(user.ghostize(TRUE), 1, "You feel that they had to use some [pick("dark", "black", "blood", "forgotten", "forbidden")] magic to [pick("invade","disturb","disrupt","infest","taint","spoil","blight")] this place!")
@@ -16,4 +21,4 @@
sleep(100)
else
to_chat(user, span("warning", "You must be standing on the rune!"))
return fizzle(user)
return fizzle(user, A)
+10 -17
View File
@@ -1,24 +1,17 @@
/obj/effect/rune/hiderunes
can_talisman = TRUE
/datum/rune/hide_runes
name = "concealment rune"
desc = "This rune is used to conceal other runes in an area around us."
/obj/effect/rune/hiderunes/do_rune_action(mob/living/user, obj/O = src)
/datum/rune/hide_runes/do_rune_action(mob/living/user, atom/movable/A)
var/rune_found
for(var/obj/effect/rune/R in orange(4, get_turf(O)))
if(R == O)
for(var/obj/effect/rune/R in orange(4, get_turf(A)))
if(R == A)
continue
R.invisibility = INVISIBILITY_OBSERVER
rune_found = TRUE
if(rune_found)
if(istype(O,/obj/effect/rune))
user.say("Kla[pick("'","`")]atu barada nikt'o!")
for(var/mob/V in viewers(get_turf(O)))
to_chat(V, span("warning", "The rune turns into gray dust, veiling the surrounding runes."))
qdel(O)
else
user.whisper("Kla[pick("'","`")]atu barada nikt'o!")
to_chat(user, span("warning", "Your talisman turns into gray dust, veiling the surrounding runes."))
for(var/mob/V in orange(1, get_turf(O)))
if(V == user)
continue
to_chat(V, span("warning", "Dust emanates from [user]'s hands for a moment."))
user.say("Kla'atu barada nikt'o!")
for(var/mob/V in viewers(get_turf(A)))
to_chat(V, span("warning", "\The [A] dissipates into a bloody cloud, veiling the surrounding runes."))
qdel(A)
return TRUE
@@ -1,14 +1,22 @@
/obj/effect/rune/manifest
/datum/rune/apparition
name = "apparition rune"
desc = "This rune is used to turn a spirit around us into an apparition."
rune_flags = NO_TALISMAN
var/mob/living/carbon/human/apparition/apparition
/obj/effect/rune/manifest/do_rune_action(mob/living/carbon/user)
/datum/rune/apparition/Destroy()
apparition_check()
return ..()
/datum/rune/apparition/do_rune_action(mob/living/user, atom/movable/A)
if(!iscarbon(user))
to_chat(user, span("warning", "Your primitive form cannot use this rune!"))
if(apparition)
to_chat(user, span("warning", "This rune already has an active apparition!"))
var/mob/living/carbon/C = user
var/mob/abstract/observer/ghost
for(var/mob/abstract/observer/O in get_turf(src))
for(var/mob/abstract/observer/O in get_turf(A))
if(!O.client)
continue
if(jobban_isbanned(O, "cultist"))
@@ -20,13 +28,13 @@
return fizzle(user)
user.say("Gal'h'rfikk harfrandid mud[pick("'","`")]gib!")
apparition = new /mob/living/carbon/human/apparition(get_turf(src))
apparition = new /mob/living/carbon/human/apparition(get_turf(A))
user.visible_message("<span class='warning'>A shape forms in the center of the rune. A shape of... a man.</span>", \
"<span class='warning'>A shape forms in the center of the rune. A shape of... a man.</span>", \
"<span class='warning'>You hear liquid flowing.</span>")
var/chose_name = FALSE
for(var/obj/item/paper/P in get_turf(src))
for(var/obj/item/paper/P in get_turf(A))
if(P.info)
apparition.real_name = copytext(P.info, findtext(P.info,">")+1, findtext(P.info,"<",2) )
chose_name = TRUE
@@ -35,7 +43,7 @@
apparition.all_underwear.Cut()
apparition.key = ghost.key
cult.add_antagonist(apparition.mind)
playsound(loc, 'sound/magic/exit_blood.ogg', 100, 1)
playsound(get_turf(A), 'sound/magic/exit_blood.ogg', 100, 1)
if(!chose_name)
apparition.real_name = pick("Anguished", "Blasphemous", "Corrupt", "Cruel", "Depraved", "Despicable", "Disturbed", "Exacerbated", "Foul", "Hateful", "Inexorable", "Implacable", "Impure", "Malevolent", "Malignant", "Malicious", "Pained", "Profane", "Profligate", "Relentless", "Resentful", "Restless", "Spiteful", "Tormented", "Unclean", "Unforgiving", "Vengeful", "Vindictive", "Wicked", "Wronged")
@@ -46,20 +54,15 @@
// The cultist doesn't have to stand on the rune, but they will continually take damage for as long as they have a summoned ghost
var/can_manifest = TRUE
while(user?.stat == CONSCIOUS && user.client && can_manifest)
can_manifest = user.species.take_manifest_ghost_damage(user)
sleep(30)
while(user?.stat == CONSCIOUS && C.client && can_manifest && apparition)
can_manifest = C.species.take_manifest_ghost_damage(user)
apparition_check()
return
/obj/effect/rune/manifest/proc/apparition_check()
/datum/rune/apparition/proc/apparition_check()
if(apparition)
apparition.visible_message(FONT_LARGE(SPAN_WARNING("\The [apparition] slowly dissipates into dust and bones.")), \
FONT_LARGE(SPAN_WARNING("You feel pain, as bonds formed between your soul and this homunculus break.")), \
SPAN_WARNING("You hear a faint rustling."))
apparition.dust()
apparition = null
/obj/effect/rune/manifest/Destroy()
apparition_check()
return ..()
+12 -7
View File
@@ -1,9 +1,14 @@
/obj/effect/rune/raise_dead/do_rune_action(mob/living/user)
/datum/rune/raise_dead
name = "revival rune"
desc = "This rune is used to revive a body in exchange for a dead sacrifice."
rune_flags = NO_TALISMAN
/datum/rune/raise_dead/do_rune_action(mob/living/user, atom/movable/A)
var/mob/living/carbon/human/corpse_to_raise
var/mob/living/carbon/human/body_to_maim
var/is_sacrifice_target
for(var/mob/living/carbon/human/M in get_turf(src))
for(var/mob/living/carbon/human/M in get_turf(A))
if(M.stat == DEAD)
if(M.mind == cult?.sacrifice_target)
is_sacrifice_target = TRUE
@@ -18,9 +23,9 @@
return fizzle(user)
is_sacrifice_target = FALSE
for(var/obj/effect/rune/raise_dead/R in rune_list)
for(var/datum/rune/R in SScult.rune_list)
var/found_sacrifice = FALSE
for(var/mob/living/carbon/human/N in get_turf(R))
for(var/mob/living/carbon/human/N in get_turf(R.parent))
if(N?.mind == cult?.sacrifice_target)
is_sacrifice_target = TRUE
else
@@ -39,7 +44,7 @@
return fizzle(user)
var/mob/abstract/observer/ghost
for(var/mob/abstract/observer/O in get_turf(src))
for(var/mob/abstract/observer/O in get_turf(A))
if(!O.client)
continue
if(O.mind?.current?.stat != DEAD)
@@ -51,9 +56,9 @@
if(!ghost)
to_chat(user, span("warning", "You require a restless spirit which clings to this world. Beckon their prescence with the sacred chants of Nar-Sie."))
var/area/A = get_area(src)
var/area/Ar = get_area(A)
for(var/mob/M in dead_mob_list)
to_chat(M, "[ghost_follow_link(user, M)] <span class='cult'>A cultist is attempting to revive a body in [A.name]!</span>")
to_chat(M, "[ghost_follow_link(user, M)] <span class='cult'>A cultist is attempting to revive a body in [Ar.name]!</span>")
return fizzle(user)
corpse_to_raise.revive()
+20 -45
View File
@@ -1,48 +1,23 @@
/obj/effect/rune/revealrunes
can_talisman = TRUE
/datum/rune/reveal_runes
name = "revealing rune"
desc = "This rune is used to reveal hidden runes in a radius around us."
rune_flags = HAS_SPECIAL_TALISMAN_ACTION
/obj/effect/rune/revealrunes/do_rune_action(mob/living/user, obj/O = src)
var/reveal = FALSE
var/rad
/datum/rune/reveal_runes/do_rune_action(mob/living/user, atom/movable/A)
reveal(user, A, 6, SPAN_WARNING("\The [A] turns into red dust, reveaing the surrounding runes."))
/datum/rune/reveal_runes/do_talisman_action(mob/living/user, atom/movable/A)
reveal(user, A, 4, SPAN_WARNING("\The [A] turns into red dust, reveaing the surrounding runes."))
/datum/rune/reveal_runes/proc/reveal(mob/living/user, atom/movable/A, var/radius = 6, var/message = SPAN_WARNING("The rune turns into red dust, reveaing the surrounding runes."))
var/did_reveal
if(istype(O, /obj/effect/rune))
rad = 6
reveal = TRUE
if(istype(O, /obj/item/paper/talisman))
rad = 4
reveal = TRUE
if(istype(O, /obj/item/nullrod))
rad = 2
reveal = TRUE
if(reveal)
for(var/obj/effect/rune/R in orange(rad, get_turf(src)))
if(R == src)
continue
R.invisibility = 0
did_reveal = TRUE
for(var/obj/effect/rune/R in orange(radius, get_turf(A)))
if(R == src)
continue
R.invisibility = 0
did_reveal = TRUE
if(did_reveal)
if(istype(O, /obj/item/nullrod))
visible_message(span("warning", "Arcane markings suddenly glow from underneath a thin layer of dust!"))
return
if(istype(O, /obj/effect/rune))
user.say("Nikt[pick("'","`")]o barada kla'atu!")
for(var/mob/V in viewers(src))
to_chat(V, span("warning", "The rune turns into red dust, reveaing the surrounding runes."))
qdel(src)
return TRUE
if(istype(O, /obj/item/paper/talisman))
user.whisper("Nikt[pick("'","`")]o barada kla'atu!")
to_chat(user, span("warning", "Your talisman turns into red dust, revealing the surrounding runes."))
for(var/mob/V in orange(1, user.loc))
if(V == user)
continue
to_chat(V, span("warning", "Red dust emanates from [user]'s hands for a moment."))
qdel(src)
return
return TRUE
if(istype(O, /obj/effect/rune))
return fizzle(user)
if(istype(O, /obj/item/paper/talisman))
var/datum/callback/cb = CALLBACK(src, /obj/effect/rune/.proc/fizzle)
cb.Invoke(user)
return
if(iscultist(user))
user.say("Nikt'o barada kla'atu!")
A.visible_message(message)
qdel(A)
+17 -65
View File
@@ -1,34 +1,3 @@
var/global/rune_boost = 0 // How many extra runes the cult can lay down
var/global/list/static/rune_types = list(
"Create Armor" = /obj/effect/rune/armor,
"Create Construct" = /obj/effect/rune/create_construct,
"Summon Tome" = /obj/effect/rune/summon_tome,
"Summon Soulstone" = /obj/effect/rune/summon_soulstone,
"Become Ethereal" = /obj/effect/rune/ethereal,
"Manifest Ghost" = /obj/effect/rune/manifest,
"Raise Dead" = /obj/effect/rune/raise_dead,
"Rune Wall" = /obj/effect/rune/wall,
"Blind" = /obj/effect/rune/blind,
"Blood Boil" = /obj/effect/rune/blood_boil,
"Blood Drain" = /obj/effect/rune/blood_drain,
"Communicate" = /obj/effect/rune/communicate,
"Convert" = /obj/effect/rune/convert,
"Create Talisman" = /obj/effect/rune/create_talisman,
"Deafen Others" = /obj/effect/rune/deafen,
"EMP" = /obj/effect/rune/emp,
"Free Cultist" = /obj/effect/rune/freedom,
"Hide Runes" = /obj/effect/rune/hiderunes,
"Reveal Runes" = /obj/effect/rune/revealrunes,
"Teleport" = /obj/effect/rune/teleport,
"Sacrifice" = /obj/effect/rune/sacrifice,
"See Invisible" = /obj/effect/rune/see_invisible,
"Stun" = /obj/effect/rune/stun,
"Summon Cultist" = /obj/effect/rune/summon_cultist,
"Summon Nar'sie" = /obj/effect/rune/summon_narsie,
"None" = /obj/effect/rune
)
/obj/effect/rune
desc = "A strange collection of symbols drawn in blood."
anchored = 1
@@ -36,37 +5,33 @@ var/global/list/static/rune_types = list(
icon_state = "1"
unacidable = TRUE
layer = AO_LAYER
var/datum/rune/rune
var/can_talisman = FALSE // some runes just don't work with talisman stuff
var/cult_description // what does the cult see the rune as?
var/network // For teleportation runes. Can connect to other runes in the network.
var/list/converting = list()
/obj/effect/rune/Initialize()
/obj/effect/rune/Initialize(mapload, var/R)
. = ..()
rune_list += src
name = "graffiti"
icon_state = pick("1", "2", "3", "4", "5", "6")
if(!R)
return INITIALIZE_HINT_QDEL
icon_state = "[rand(1, 6)]"
filters = filter(type="drop_shadow", x = 1, y = 1, size = 4, color = "#FF0000")
rune = new R(src, src)
SScult.add_rune(rune)
/obj/effect/rune/Destroy()
rune_list -= src
SScult.remove_rune(rune)
QDEL_NULL(rune)
return ..()
/obj/effect/rune/examine(mob/user)
..(user)
if(iscultist(user) || isobserver(user))
desc = "A powerful rune drawn with blood magic gifted by Nar'sie Himself."
if(cult_description)
to_chat(user, "This spell circle reads: <span class='cult'><b><i>[cult_description]</i></b></span>.")
to_chat(user, "This rune [can_talisman ? "<span class='cult'><b><i>can</i></b></span>" : "<span class='warning'><b><i>cannot</i></b></span>"] be turned into a talisman.")
to_chat(user, rune.get_cultist_fluff_text())
to_chat(user, "This rune [rune.can_be_talisman() ? "<span class='cult'><b><i>can</i></b></span>" : "<span class='warning'><b><i>cannot</i></b></span>"] be turned into a talisman.")
else
desc = "A strange collection of symbols drawn in blood."
to_chat(user, rune.get_normal_fluff_text())
/obj/effect/rune/attackby(obj/I, mob/user)
if(istype(I, /obj/item/book/tome) && iscultist(user))
to_chat(user, span("notice", "You retrace your steps, carefully undoing the lines of the rune."))
qdel(src)
rune.do_tome_action(user, I)
return
else if(istype(I, /obj/item/nullrod))
to_chat(user, span("notice", "You disrupt the vile magic with the deadening field of \the [I]!"))
@@ -76,25 +41,12 @@ var/global/list/static/rune_types = list(
/obj/effect/rune/attack_hand(mob/living/user)
if(!iscultist(user))
to_chat(user, span("notice", "You can't mouth the arcane scratchings without fumbling over them."))
to_chat(user, SPAN_NOTICE("You can't mouth the arcane scratchings without fumbling over them."))
return
if(istype(user.wear_mask, /obj/item/clothing/mask/muzzle))
to_chat(user, span("warning", "You are unable to speak the words of the rune."))
return
return do_rune_action(user)
// Runes should override this
/obj/effect/rune/proc/do_rune_action(var/mob/living/user, var/obj/O = src)
return
/obj/effect/rune/proc/fizzle(var/mob/living/user)
if(istype(src,/obj/effect/rune))
user.say(pick("Hakkrutju gopoenjim.", "Nherasai pivroiashan.", "Firjji prhiv mazenhor.", "Tanah eh wakantahe.", "Obliyae na oraie.", "Miyf hon vnor'c.", "Wakabai hij fen juswix."))
else
user.whisper(pick("Hakkrutju gopoenjim.", "Nherasai pivroiashan.", "Firjji prhiv mazenhor.", "Tanah eh wakantahe.", "Obliyae na oraie.", "Miyf hon vnor'c.", "Wakabai hij fen juswix."))
for(var/mob/V in viewers(src))
to_chat(V, span("warning", "The markings pulse with a small burst of light, then fall dark."))
to_chat(user, SPAN_WARNING("You are unable to speak the words of the rune."))
return
return rune.activate(user, src)
/obj/effect/rune/cultify()
return
+12 -7
View File
@@ -1,12 +1,17 @@
/obj/effect/rune/sacrifice/do_rune_action(mob/living/user)
/datum/rune/sacrifice
name = "sacrificial rune"
desc = "This rune is used to sacrifice an unbeliever."
rune_flags = NO_TALISMAN
/datum/rune/sacrifice/do_rune_action(mob/living/user, atom/movable/A)
var/list/mob/living/carbon/human/cultists_in_range = list()
var/list/mob/living/carbon/human/victims = list()
for(var/mob/living/carbon/human/V in get_turf(src)) // Checks for non-cultist humans to sacrifice
for(var/mob/living/carbon/human/V in get_turf(A)) // Checks for non-cultist humans to sacrifice
if(ishuman(V) && !iscultist(V))
victims += V // Checks for cult status and mob type
for(var/obj/item/I in get_turf(src)) // Checks for MMIs/brains/Intellicards
for(var/obj/item/I in get_turf(A)) // Checks for MMIs/brains/Intellicards
if(istype(I,/obj/item/organ/internal/brain))
var/obj/item/organ/internal/brain/B = I
victims += B.brainmob
@@ -16,10 +21,10 @@
victims += B.brainmob
else if(istype(I,/obj/item/aicard))
for(var/mob/living/silicon/ai/A in I)
victims += A
for(var/mob/living/silicon/ai/AI in I)
victims += AI
for(var/mob/living/carbon/C in orange(1, src))
for(var/mob/living/carbon/C in orange(1, A))
if(iscultist(C) && !C.stat)
cultists_in_range += C
C.say("Barhah hra zar[pick("'","`")]garis!")
@@ -52,7 +57,7 @@
for(var/mob/C in cultists_in_range)
to_chat(C, output)
/obj/effect/rune/sacrifice/proc/do_sacrifice(var/list/mob/cultists, var/mob/victim, var/victim_status, var/probability, var/worthy)
/datum/rune/sacrifice/proc/do_sacrifice(var/list/mob/cultists, var/mob/victim, var/victim_status, var/probability, var/worthy)
var/victim_dead
if(victim_status == DEAD)
victim_dead = TRUE
@@ -1,6 +1,11 @@
/obj/effect/rune/see_invisible/do_rune_action(mob/living/user)
/datum/rune/see_invisible
name = "visibility rune"
desc = "This rune is used to see the invisible."
rune_flags = NO_TALISMAN
/datum/rune/see_invisible/do_rune_action(mob/living/user, atom/movable/A)
if(user.seer == TRUE)
user.say("Rash'tla sektath mal[pick("'","`")]zua. Zasan therium viortia.")
user.say("Rash'tla sektath mal'zua! Zasan therium viortia!")
to_chat(user, span("warning", "The world beyond fades from your vision."))
user.see_invisible = SEE_INVISIBLE_LIVING
user.seer = FALSE
@@ -9,8 +14,8 @@
user.see_invisible = SEE_INVISIBLE_CULT
user.seer = FALSE
else
user.say("Rash'tla sektath mal[pick("'","`")]zua. Zasan therium vivira. Itonis al'ra matum!")
user.say("Rash'tla sektath mal'zua! Zasan therium vivira! Itonis al'ra matum!")
to_chat(user, span("warning", "The world beyond opens to your eyes."))
user.see_invisible = SEE_INVISIBLE_CULT
user.seer = TRUE
return fizzle(user)
return fizzle(user, A)
+12 -11
View File
@@ -1,16 +1,17 @@
/obj/effect/rune/stun
can_talisman = TRUE
/datum/rune/stun
name = "incapacitation rune"
desc = "This rune is used to deafen, silence, flash and confuse the unbelievers in a radius around us."
rune_flags = HAS_SPECIAL_TALISMAN_ACTION
/obj/effect/rune/stun/do_rune_action(mob/living/user, obj/O = src)
user.say("Fuu ma[pick("'","`")]jin!")
/datum/rune/stun/do_rune_action(mob/living/user, atom/movable/A)
do_stun(user, A, 5, TRUE)
var/radius = 5
var/is_rune = TRUE
if(!istype(O, /obj/effect/rune))
radius = 2
is_rune = FALSE
/datum/rune/stun/do_talisman_action(mob/living/user, atom/movable/A)
do_stun(user, A, 3, FALSE)
for(var/mob/living/L in range(radius, O))
/datum/rune/stun/proc/do_stun(mob/living/user, atom/movable/A, var/radius, var/is_rune)
user.say("Fuu ma'jin!")
for(var/mob/living/L in range(radius, A))
if(iscultist(L))
continue
if(iscarbon(L))
@@ -32,4 +33,4 @@
S.silent += 15
to_chat(S, span("danger", "BZZZT... The rune has exploded in a bright flash!"))
admin_attack_log(user, S, "Used a stun rune.", "Was victim of a stun rune.", "used a stun rune on")
qdel(O)
qdel(A)
@@ -1,25 +1,30 @@
/obj/effect/rune/summon_cultist/do_rune_action(mob/living/user)
/datum/rune/summon_cultist
name = "cultist summoning rune"
desc = "This rune is used to summon a cultist to our location. It will not work if they are restrained."
rune_flags = NO_TALISMAN
/datum/rune/summon_cultist/do_rune_action(mob/living/user, atom/movable/A)
var/list/mob/living/carbon/cultists = list()
for(var/datum/mind/H in cult.current_antagonists)
if(istype(H.current, /mob/living/carbon))
if(iscarbon(H.current))
cultists += H.current
var/list/mob/living/carbon/users = list()
for(var/mob/living/carbon/C in orange(1, src))
for(var/mob/living/carbon/C in orange(1, A))
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)
return fizzle(user, A)
if(cultist == user) //just to be sure.
return
if(cultist.buckled || cultist.handcuffed || (!isturf(cultist.loc) && !istype(cultist.loc, /obj/structure/closet)))
for(var/mob/C in users)
to_chat(C, span("warning", "You cannot summon \the [cultist], for \his shackles of blood are strong."))
return fizzle(user)
cultist.forceMove(get_turf(src))
return fizzle(user, A)
cultist.forceMove(get_turf(A))
cultist.lying = TRUE
cultist.regenerate_icons()
@@ -35,5 +40,5 @@
user.visible_message("<span class='warning'>The rune disappears with a flash of red light, and in its place now a body lies.</span>", \
"<span class='warning'>You are blinded by a flash of red light! After you're able to see again, you see that now instead of the rune there's a body.</span>", \
"<span class='warning'>You hear a pop and smell ozone.</span>")
qdel(src)
return fizzle(user)
qdel(A)
return fizzle(user, A)
@@ -1,23 +1,28 @@
/obj/effect/rune/summon_narsie/do_rune_action(mob/living/user)
if(!cult.allow_narsie)
return fizzle(user)
/datum/rune/summon_narsie
name = "geometer rune"
desc = "This rune is used to summon the Geometer of Blood. It requires nine cultists around it to bring Him into our dimension."
rune_flags = NO_TALISMAN
var/turf/T = get_turf(src)
/datum/rune/summon_narsie/do_rune_action(mob/living/user, atom/movable/A)
if(!cult.allow_narsie)
return fizzle(user, A)
var/turf/T = get_turf(A)
if(isNotStationLevel(T.z))
to_chat(user, span("warning", "You are too far from the station, Nar'sie can not be summoned here."))
return fizzle(user)
return fizzle(user, A)
var/list/cultists = list()
for(var/mob/M in range(1, src))
for(var/mob/M in range(1, A))
if(istype(M, /mob/living/carbon/human/apparition))
to_chat(M, span("warning", "Apparitions cannot partake in the summoning of the Great Dark One! Clear the area and defend the cultists!"))
continue
if(iscultist(M) && !M.stat)
M.say("Tok-lyr rqa'nap g[pick("'","`")]lt-ulotf!")
M.say("Tok-lyr rqa'nap! Qur'man-ze! Gi'lt-lu-nulotf!")
cultists += M
if(cultists.len >= 9)
log_and_message_admins_many(cultists, "summoned Nar-sie.")
new /obj/singularity/narsie/large(src.loc)
new /obj/singularity/narsie/large(get_turf(A))
// Can't summon a singular entity twice.
cult.allow_narsie = FALSE
@@ -27,4 +32,4 @@
if(!iscultist(M))
continue
to_chat(M, span("warning", "Not enough cultists are around to summon the Great Dark One!"))
return fizzle(user)
return fizzle(user, A)
@@ -1,8 +1,9 @@
/obj/effect/rune/summon_soulstone
can_talisman = TRUE
/datum/rune/summon_soulstone
name = "soul stone creation rune"
desc = "This rune is used to create a soul stone for our usage."
/obj/effect/rune/summon_soulstone/do_rune_action(mob/living/user, obj/O = src)
user.say("N[pick("'","`")]ath reth sh'yro eth d'raggathnor!")
new /obj/item/device/soulstone(get_turf(O))
qdel(O)
/datum/rune/summon_soulstone/do_rune_action(mob/living/user, atom/movable/A)
user.say("N'ath reth sh'yro eth d'raggathnor!")
new /obj/item/device/soulstone(get_turf(A))
qdel(A)
return TRUE
+9 -11
View File
@@ -1,14 +1,12 @@
/obj/effect/rune/summon_tome
can_talisman = TRUE
/datum/rune/summon_tome
name = "tome summoning rune"
desc = "This rune is used to summon a tome for our usage."
/obj/effect/rune/summon_tome/do_rune_action(mob/living/user, obj/O = src)
if(istype(O, /obj/effect/rune))
user.say("N[pick("'","`")]ath reth sh'yro eth d'raggathnor!")
else
user.whisper("N[pick("'","`")]ath reth sh'yro eth d'raggathnor!")
user.visible_message("<span class='warning'>Rune disappears with a flash of red light, and in its place now a book lies.</span>", \
"<span class='warning'>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.</span>", \
/datum/rune/summon_tome/do_rune_action(mob/living/user, atom/movable/A)
user.say("N'ath reth sh'yro eth d'raggathnor!")
user.visible_message("<span class='warning'>\The [A] disappears with a flash of red light, and in its place lies a book.</span>", \
"<span class='warning'>You are blinded by the flash of red light! After you're able to see again, you see a book in place of \the [A].</span>", \
"<span class='warning'>You hear a pop and smell ozone.</span>")
new /obj/item/book/tome(get_turf(O))
qdel(O)
new /obj/item/book/tome(get_turf(A))
qdel(A)
return TRUE
+55 -36
View File
@@ -1,30 +1,53 @@
var/global/list/teleport_runes = list()
var/global/list/static/teleport_network = list("Vernuth", "Koglan", "Irgros", "Akon")
/datum/rune/teleport
name = "teleportation rune"
desc = "This rune is used to teleport around to other teleport runes of our creation. Use your tome on the rune to configure it."
var/network
var/last_tp_time = 0
/obj/effect/rune/teleport
can_talisman = TRUE
/obj/effect/rune/teleport/Initialize()
. = ..()
addtimer(CALLBACK(src, .proc/random_network), 10) // if this rune somehow spawned without a network, we assign a random one
/obj/effect/rune/teleport/examine(mob/user)
/datum/rune/teleport/New()
..()
if(iscultist(user) && network)
to_chat(user, "This rune's network tag reads: <span class='cult'><b><i>[network]</i></b></span>.")
addtimer(CALLBACK(src, .proc/random_network), 5) // if this rune somehow spawned without a network, we assign a random one
SScult.teleport_runes += src
/obj/effect/rune/teleport/proc/random_network()
/datum/rune/teleport/Destroy()
SScult.teleport_runes -= src
return ..()
/datum/rune/teleport/get_cultist_fluff_text()
. = ..()
if(network)
. += "This rune's network tag reads: <span class='cult'><b><i>[network]</i></b></span>."
/datum/rune/teleport/proc/random_network()
if(!network) // check if it hasn't been assigned yet
network = pick(teleport_network)
network = pick(SScult.teleport_network)
/obj/effect/rune/teleport/do_rune_action(mob/living/user)
/datum/rune/teleport/do_tome_action(var/mob/living/user, atom/movable/A)
var/choice = alert(user, "Do you wish to delete this rune or configure it?", "Teleportation Rune", "Delete", "Configure")
if(choice == "Configure")
var/configure = input(user, "Choose a network.", "Teleportation Rune") as null|anything in SScult.teleport_network
if(configure)
network = configure
else
return FALSE //don't wipe the rune if they don't wanna change it
else
return ..()
/datum/rune/teleport/do_talisman_action(mob/living/user, atom/movable/A)
teleport(user, A)
qdel(A)
/datum/rune/teleport/do_rune_action(mob/living/user, atom/movable/A)
teleport(user, A)
/datum/rune/teleport/proc/teleport(mob/living/user, atom/movable/A)
var/turf/T = get_turf(user)
if(isNotStationLevel(T.z))
to_chat(user, span("warning", "You are too far from the station, Nar'sie is unable to reach you here."))
return fizzle(user)
return fizzle(user, A)
var/list/obj/effect/rune/teleport/possible_runes = list()
for(var/obj/effect/rune/R in teleport_runes)
var/list/datum/rune/teleport/possible_runes = list()
for(var/datum/rune/teleport/R in SScult.teleport_runes)
if(R == src)
continue
if(R.network != src.network)
@@ -32,25 +55,21 @@ var/global/list/static/teleport_network = list("Vernuth", "Koglan", "Irgros", "A
possible_runes += R
if(length(possible_runes))
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!")
if(last_tp_time + 5 SECONDS > world.time)
to_chat(user, SPAN_CULT("The rune is still recharging!"))
return fizzle(user, A)
user.say("Sas'so c'arta forbici!")//Only you can stop auto-muting
user.visible_message("<span class='warning'>[user] disappears in a flash of red light!</span>", \
"<span class='cult'>You feel as your body gets dragged through the dimension of Nar-Sie!</span>", \
"<span class='cult'>You feel as if your body gets dragged through Redspace!</span>", \
"<span class='warning'>You hear a sickening crunch and sloshing of viscera.</span>")
user.forceMove(get_turf(pick(possible_runes)))
return TRUE
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)(user)
return
var/datum/rune/teleport/valid_rune = pick(possible_runes)
gibs(get_turf(user))
playsound(user, 'sound/magic/enter_blood.ogg', 50, 1)
user.forceMove(get_turf(valid_rune.parent))
playsound(user, 'sound/magic/enter_blood.ogg', 50, 1) //Gotta play it twice, at the destination AND source.
gibs(get_turf(user))
valid_rune.last_tp_time = world.time
last_tp_time = world.time
return fizzle(user, A)
/obj/effect/rune/teleport/Initialize()
. = ..()
teleport_runes += src
/obj/effect/rune/teleport/Destroy()
teleport_runes -= src
. = ..()
+11 -4
View File
@@ -1,9 +1,16 @@
/obj/effect/rune/wall/do_rune_action(mob/living/user)
user.say("Khari[pick("'","`")]d! Eske'te tannin!")
src.density = !src.density
/datum/rune/wall
name = "wall rune"
desc = "This rune is used to create a wall that the unbelievers cannot go through."
rune_flags = NO_TALISMAN
/datum/rune/wall/do_rune_action(mob/living/user, atom/movable/A)
user.say("Khari'd! Eske'te tannin!")
A.density = !A.density
user.take_organ_damage(2, 0)
if(src.density)
if(A.density)
to_chat(user, span("cult", "Your blood flows into the rune, and you feel that the very space over the rune thickens."))
parent.filters = filter(type="blur", size = 5)
else
to_chat(user, span("cult", "Your blood flows into the rune, and you feel as the rune releases its grasp on space."))
parent.filters = filter(type="drop_shadow", x = 1, y = 1, size = 4, color = "#FF0000")
return
+1 -1
View File
@@ -869,7 +869,7 @@ datum/objective/heist/salvage
possible_targets += player.mind
if(possible_targets.len > 0)
target = pick(possible_targets)
if(target) explanation_text = "Sacrifice [target.name], the [target.assigned_role]. You will need the sacrifice rune (Hell blood join) and three acolytes to do so."
if(target) explanation_text = "Sacrifice [target.name], the [target.assigned_role]. You will need the sacrifice rune and three acolytes to do so."
/datum/objective/cult/sacrifice/check_completion()
return (target && cult && !cult.sacrificed.Find(target))
@@ -129,8 +129,14 @@
cooldown = world.time
user.visible_message(span("notice", "[user] loudly taps their [src.name] against the floor."))
playsound(user.loc, 'sound/effects/shieldbash.ogg', 50, 1)
var/datum/callback/cb = CALLBACK(src, /obj/effect/rune/revealrunes/.proc/do_rune_action)
cb.Invoke(user, src)
var/rune_found = FALSE
for(var/obj/effect/rune/R in orange(2, get_turf(src)))
if(R == src)
continue
rune_found = TRUE
R.invisibility = 0
if(rune_found)
visible_message(SPAN_NOTICE("A holy glow permeates the air!"))
return
/obj/item/reagent_containers/spray/aspergillum
-91
View File
@@ -89,97 +89,6 @@
else
alert("Invalid mob")
/*
/client/proc/cmd_admin_monkeyize(var/mob/M in mob_list)
set category = "Fun"
set name = "Make Monkey"
if(!ROUND_IS_STARTED)
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 mob_list)
set category = "Fun"
set name = "Make Changeling"
if(!ROUND_IS_STARTED)
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.Clone()
M.make_changeling()
if(M.mind)
M.mind.special_role = "Changeling"
else
alert("Invalid mob")
*/
/*
/client/proc/cmd_admin_abominize(var/mob/M in mob_list)
set category = null
set name = "Make Abomination"
to_chat(usr, "Ruby Mode disabled. Command aborted.")
return
if(!ROUND_IS_STARTED)
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 mob_list) // -- TLE, modified by Urist
set category = "Fun"
set name = "Make Cultist"
set desc = "Makes target a cultist"
if(!cultwords["travel"])
runerandom()
if(M)
if(M.mind in SSticker.mode.cult)
return
else
if(alert("Spawn that person a tome?",,"Yes","No")=="Yes")
to_chat(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/book/tome(M.loc)
else
to_chat(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")
to_chat(M, "\red You remembered one thing from the glimpse... [cultwords["travel"]] is travel...")
if("2")
to_chat(M, "\red You remembered one thing from the glimpse... [cultwords["blood"]] is blood...")
if("3")
to_chat(M, "\red You remembered one thing from the glimpse... [cultwords["join"]] is join...")
if("4")
to_chat(M, "\red You remembered one thing from the glimpse... [cultwords["hell"]] is Hell...")
if("5")
to_chat(M, "\red You remembered one thing from the glimpse... [cultwords["destroy"]] is destroy...")
if("6")
to_chat(M, "\red You remembered one thing from the glimpse... [cultwords["technology"]] is technology...")
if("7")
to_chat(M, "\red You remembered one thing from the glimpse... [cultwords["self"]] is self...")
if("8")
to_chat(M, "\red You remembered one thing from the glimpse... [cultwords["see"]] is see...")
if(M.mind)
M.mind.special_role = "Cultist"
SSticker.mode.cult += M.mind
to_chat(src, "Made [M] a cultist.")
*/
//TODO: merge the vievars version into this or something maybe mayhaps
/client/proc/cmd_debug_del_all()
set category = "Debug"
@@ -281,9 +281,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
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/found_rune
for(var/obj/effect/rune/ethereal/R in get_turf(mind.current)) //whilst corpse is alive, we can only reenter the body if it's on the rune
found_rune = TRUE
break
for(var/obj/effect/rune/R in get_turf(mind.current)) //whilst corpse is alive, we can only reenter the body if it's on the rune
if(R.rune.type == /datum/rune/ethereal)
found_rune = TRUE
break
if(!found_rune)
to_chat(usr, span("cult", "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
@@ -459,8 +459,10 @@
if(!H.druggy)
H.see_in_dark = (H.sight == (SEE_TURFS|SEE_MOBS|SEE_OBJS)) ? 8 : min(darksight + H.equipment_darkness_modifier, 8)
if(H.seer && locate(/obj/effect/rune/see_invisible) in get_turf(H))
H.see_invisible = SEE_INVISIBLE_CULT
if(H.seer)
var/obj/effect/rune/R = locate(/obj/effect/rune) in get_turf(H)
if(R && R.type == /datum/rune/see_invisible)
H.see_invisible = SEE_INVISIBLE_CULT
if(H.see_invisible != SEE_INVISIBLE_CULT && H.equipment_see_invis)
H.see_invisible = min(H.see_invisible, H.equipment_see_invis)
@@ -20,20 +20,16 @@
if(!isturf(user.loc))
to_chat(user, span("warning", "You do not have enough space to write a proper rune."))
var/rune = input(user, "Choose a rune to scribe", "Rune Scribing") in rune_types //not cancellable.
var/rune = input(user, "Choose a rune to scribe", "Rune Scribing") as null|anything in SScult.runes_by_name//not cancellable.
if(locate(/obj/effect/rune) in get_turf(user))
to_chat(user, span("warning", "There is already a rune in this location."))
return
var/rune_path = rune_types[rune]
var/obj/effect/rune/R = new rune_path(get_turf(user))
if(!rune)
return
var/network
if(istype(R, /obj/effect/rune/teleport))
network = input(user, "Choose a teleportation network for the rune to connect to.", "Teleport Rune") in teleport_network
if(network)
R.network = network
R.cult_description = rune
var/RD = SScult.runes_by_name[rune]
var/obj/effect/rune/R = new(get_turf(user), RD)
R.color = "#A10808"
var/area/A = get_area(R)
+47
View File
@@ -0,0 +1,47 @@
################################
# Example Changelog File
#
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
#
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
# When it is, any changes listed below will disappear.
#
# Valid Prefixes:
# bugfix
# wip (For works in progress)
# tweak
# soundadd
# sounddel
# rscadd (general adding of nice things)
# rscdel (general deleting of nice things)
# imageadd
# imagedel
# maptweak
# spellcheck (typo fixes)
# experiment
# balance
# admin
# backend
# security
# refactor
#################################
# Your name.
author: MattAtlas
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
delete-after: True
# Any changes you've made. See valid prefix list above.
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
# SCREW THIS UP AND IT WON'T WORK.
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
changes:
- backend: "Cult has received an overhaul in backend code. Everything should now be more stable."
- tweak: "A lot of cult runes have gotten an overhaul in looks and presentation."
- tweak: "Teleport runes now have a short 5 second cooldown between teleports."
- tweak: "Teleport runes now create gibs and play a sound when you teleport."
- tweak: "The blood drain rune now drains blood from non-cult humans on the rune into the cultist standing on the rune."
- tweak: "The cult tome now actually makes you bleed when you create runes."
- tweak: "The cult tome reading is now actually useful, containing better information."
Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB