diff --git a/aurorastation.dme b/aurorastation.dme
index ae7dfe488cc..b1dd88d38c5 100644
--- a/aurorastation.dme
+++ b/aurorastation.dme
@@ -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"
diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm
index b642bc8c198..1714b70d357 100644
--- a/code/_helpers/global_lists.dm
+++ b/code/_helpers/global_lists.dm
@@ -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()
diff --git a/code/controllers/subsystems/cult.dm b/code/controllers/subsystems/cult.dm
new file mode 100644
index 00000000000..f432b46c9a2
--- /dev/null
+++ b/code/controllers/subsystems/cult.dm
@@ -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 += "[R.name]: [R.desc]"
+ tome_data += "This rune [R.can_be_talisman() ? "can" : "cannot"] be turned into a talisman.
"
+
+/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
diff --git a/code/controllers/subsystems/garbage-debug.dm b/code/controllers/subsystems/garbage-debug.dm
index e0031ccb557..01b1f7aa05d 100644
--- a/code/controllers/subsystems/garbage-debug.dm
+++ b/code/controllers/subsystems/garbage-debug.dm
@@ -316,7 +316,6 @@
SearchVar(exclude_jobs)
SearchVar(visual_nets)
SearchVar(cameranet)
- SearchVar(rune_list)
SearchVar(escape_list)
SearchVar(endgame_exits)
SearchVar(endgame_safespawns)
diff --git a/code/game/gamemodes/cult/hell_universe.dm b/code/game/gamemodes/cult/hell_universe.dm
index 2bff07e1403..e2858ae4a6e 100644
--- a/code/game/gamemodes/cult/hell_universe.dm
+++ b/code/game/gamemodes/cult/hell_universe.dm
@@ -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)
diff --git a/code/game/gamemodes/cult/items/talisman.dm b/code/game/gamemodes/cult/items/talisman.dm
index bc1a056acb5..e0bc85b3384 100644
--- a/code/game/gamemodes/cult/items/talisman.dm
+++ b/code/game/gamemodes/cult/items/talisman.dm
@@ -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 = "

"
/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: [rune].")
+ to_chat(user, "The spell inscription reads: [rune.name].")
/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()
diff --git a/code/game/gamemodes/cult/items/tome.dm b/code/game/gamemodes/cult/items/tome.dm
index 65ca7fcf51d..56ff89647e1 100644
--- a/code/game/gamemodes/cult/items/tome.dm
+++ b/code/game/gamemodes/cult/items/tome.dm
@@ -8,76 +8,6 @@
w_class = 2.0
unique = TRUE
slot_flags = SLOT_BELT
- var/tomedat = ""
-
- tomedat = {"
-
-
-
-
- The scriptures of Nar-Sie, The One Who Sees, The Geometer of Blood.
-
- The book is written in an unknown dialect, there are lots of pictures of various complex geometric shapes. You find some notes in Tau Ceti Basic that give you basic understanding of the many runes written in the book.
- Below is the summary of the runes.
-
- Rune Descriptions
- Teleport self
- 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.
- Teleport other
- 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.
- Summon new tome
- Invoking this rune summons a new arcane tome.
- Convert a person
- This rune opens target's mind to the realm of Nar-Sie, which usually results in this person joining the cult. However, some people (mostly the ones who possess high authority) have strong enough will to stay true to their old ideals.
- Summon Nar-Sie
- The ultimate rune. It summons the Avatar of Nar-Sie himself, tearing a huge hole in reality and consuming everything around it. Summoning it is the final goal of any cult.
- Disable Technology
- Invoking this rune creates a strong electromagnetic pulse in a small radius, making it basically analogous to an EMP grenade. You can imbue this rune into a talisman, making it a decent defensive item.
- Drain Blood
- This rune instantly heals you of some brute damage at the expense of a person placed on top of the rune. Whenever you invoke a drain rune, ALL drain runes on the station are activated, draining blood from anyone located on top of those runes. This includes yourself, though the blood you drain from yourself just comes back to you. This might help you identify this rune when studying words. One drain gives up to 25HP per each victim, but you can repeat it if you need more. Draining only works on living people, so you might need to recharge your "Battery" once its empty. Drinking too much blood at once might cause blood hunger.
- Raise Dead
- This rune allows for the resurrection of any dead person. You will need a dead human body and a living human sacrifice. Make 2 raise dead runes. Put a living, 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.
- Hide runes
- This rune makes all nearby runes completely invisible. They are still there and will work if activated somehow, but you cannot invoke them directly if you do not see them.
- Reveal runes
- This rune is made to reverse the process of hiding a rune. It reveals all hidden runes in a rather large area around it.
- Leave your body
- This rune gently rips your soul out of your body, leaving it intact. You can observe the surroundings as a ghost as well as communicate with other ghosts. Your body takes damage while you are there, so ensure your journey is not too long, or you might never come back.
- Manifest a ghost
- Unlike the Raise Dead rune, this rune does not require any special preparations or vessels. Instead of using full lifeforce of a sacrifice, it will drain YOUR lifeforce. Stand on the rune and invoke it. If 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.
- Imbue a talisman
- This rune allows you to imbue the magic of some runes into paper talismans. Create an imbue rune, then an appropriate rune beside it. Put an empty piece of paper on the imbue rune and invoke it. You will now have a one-use talisman with the power of the target rune. Using a talisman drains some health, so be careful with it. You can imbue a talisman with power of the following runes: summon tome, reveal, conceal, teleport, disable technology, communicate, deafen, blind and stun.
- Sacrifice
- Sacrifice rune allows you to sacrifice a living thing or a body to the Geometer of Blood. Monkeys and dead humans are the most basic sacrifices, they might or might not be enough to gain His favor. A living human is what a real sacrifice should be, however, you will need 3 people chanting the invocation to sacrifice a living person.
- Create a wall
- Invoking this rune solidifies the air above it, creating an an invisible wall. To remove the wall, simply invoke the rune again.
- Summon cultist
- This rune allows you to summon a fellow cultist to your location. The target cultist must be unhandcuffed 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.
- Free a cultist
- 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.
- Deafen
- This rune temporarily deafens all non-cultists around you.
- Blind
- This rune temporarily blinds all non-cultists around you. Very robust. Use together with the deafen rune to leave your enemies completely helpless.
- Blood boil
- This rune boils the blood all non-cultists in visible range. The damage is enough to instantly critically hurt any person. You need 3 cultists invoking the rune for it to work. This rune is unreliable and may cause unpredicted effect when invoked. It also drains significant amount of your health when successfully invoked.
- Communicate
- Invoking this rune allows you to relay a message to all cultists on the station and nearby space objects.
- Stun
- 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.
- Equip Armor
- When this rune is invoked, either from a rune or a talisman, it will equip the user with the armor of the followers of Nar-Sie. To use this rune to its fullest extent, make sure you are not wearing any form of headgear, armor, gloves or shoes, and make sure you are not holding anything in your hands.
- See Invisible
- When invoked when standing on it, this rune allows the user to see the world beyond as long as he does not move.
-
-
- "}
/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
\ No newline at end of file
diff --git a/code/game/gamemodes/cult/runes/_runes.dm b/code/game/gamemodes/cult/runes/_runes.dm
new file mode 100644
index 00000000000..f23e23cf795
--- /dev/null
+++ b/code/game/gamemodes/cult/runes/_runes.dm
@@ -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)
diff --git a/code/game/gamemodes/cult/runes/armor.dm b/code/game/gamemodes/cult/runes/armor.dm
index 41ec46d337c..a863f14cc8f 100644
--- a/code/game/gamemodes/cult/runes/armor.dm
+++ b/code/game/gamemodes/cult/runes/armor.dm
@@ -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."))
diff --git a/code/game/gamemodes/cult/runes/blind_others.dm b/code/game/gamemodes/cult/runes/blind_others.dm
index ec6c7d6f402..a675840ee01 100644
--- a/code/game/gamemodes/cult/runes/blind_others.dm
+++ b/code/game/gamemodes/cult/runes/blind_others.dm
@@ -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
\ No newline at end of file
+ return fizzle(user, A)
\ No newline at end of file
diff --git a/code/game/gamemodes/cult/runes/blood_boil.dm b/code/game/gamemodes/cult/runes/blood_boil.dm
index 8c648308d87..b7028a378bf 100644
--- a/code/game/gamemodes/cult/runes/blood_boil.dm
+++ b/code/game/gamemodes/cult/runes/blood_boil.dm
@@ -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)
\ No newline at end of file
+ return fizzle(user, A)
\ No newline at end of file
diff --git a/code/game/gamemodes/cult/runes/blood_drain.dm b/code/game/gamemodes/cult/runes/blood_drain.dm
index 434c752dc67..99e0819ade8 100644
--- a/code/game/gamemodes/cult/runes/blood_drain.dm
+++ b/code/game/gamemodes/cult/runes/blood_drain.dm
@@ -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("Blood flows from the rune into [user]!", \
- "The blood starts flowing from the rune and into your frail body. You feel... empowered.", \
- "You hear a liquid flowing.")
- 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("[user]'s eyes give off an eerie red glow!", \
- "...but it wasn't nearly enough. You crave, crave for more. The hunger consumes you from within.", \
- "You hear a heartbeat.")
- user.bhunger += drain
- 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
\ No newline at end of file
+/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)
\ No newline at end of file
diff --git a/code/game/gamemodes/cult/runes/communicate.dm b/code/game/gamemodes/cult/runes/communicate.dm
index 2843255fbd7..1dfd1d47b7f 100644
--- a/code/game/gamemodes/cult/runes/communicate.dm
+++ b/code/game/gamemodes/cult/runes/communicate.dm
@@ -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
\ No newline at end of file
+ to_chat(H.current, SPAN_CULT("The familiar voice of [H.current] fills your mind: [input]"))
+ qdel(A)
diff --git a/code/game/gamemodes/cult/runes/conversion.dm b/code/game/gamemodes/cult/runes/convert.dm
similarity index 85%
rename from code/game/gamemodes/cult/runes/conversion.dm
rename to code/game/gamemodes/cult/runes/convert.dm
index ec505a127c8..7d53e002f29 100644
--- a/code/game/gamemodes/cult/runes/conversion.dm
+++ b/code/game/gamemodes/cult/runes/convert.dm
@@ -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
\ No newline at end of file
+ LAZYCLEARLIST(converting)
+ return TRUE
diff --git a/code/game/gamemodes/cult/runes/create_construct.dm b/code/game/gamemodes/cult/runes/create_construct.dm
index 51133e273e1..875fa049b13 100644
--- a/code/game/gamemodes/cult/runes/create_construct.dm
+++ b/code/game/gamemodes/cult/runes/create_construct.dm
@@ -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
\ No newline at end of file
+/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)
diff --git a/code/game/gamemodes/cult/runes/create_talisman.dm b/code/game/gamemodes/cult/runes/create_talisman.dm
index 2ff8e794026..bd8f9e5f534 100644
--- a/code/game/gamemodes/cult/runes/create_talisman.dm
+++ b/code/game/gamemodes/cult/runes/create_talisman.dm
@@ -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)
\ No newline at end of file
+ return fizzle(user, A)
\ No newline at end of file
diff --git a/code/game/gamemodes/cult/runes/deafen_others.dm b/code/game/gamemodes/cult/runes/deafen_others.dm
index 17624f73c11..48ab178b4a8 100644
--- a/code/game/gamemodes/cult/runes/deafen_others.dm
+++ b/code/game/gamemodes/cult/runes/deafen_others.dm
@@ -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
\ No newline at end of file
+ return fizzle(user, A)
\ No newline at end of file
diff --git a/code/game/gamemodes/cult/runes/emp.dm b/code/game/gamemodes/cult/runes/emp.dm
index 39c58c77607..c5ca928b263 100644
--- a/code/game/gamemodes/cult/runes/emp.dm
+++ b/code/game/gamemodes/cult/runes/emp.dm
@@ -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
\ No newline at end of file
+ qdel(A)
diff --git a/code/game/gamemodes/cult/runes/free_cultist.dm b/code/game/gamemodes/cult/runes/free_cultist.dm
index 0bbc635196b..af2470a24cf 100644
--- a/code/game/gamemodes/cult/runes/free_cultist.dm
+++ b/code/game/gamemodes/cult/runes/free_cultist.dm
@@ -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)
\ No newline at end of file
+ C.say("Khari'd! Gual'te nikka!")
+ qdel(A)
+ return fizzle(user, A)
\ No newline at end of file
diff --git a/code/game/gamemodes/cult/runes/ghost_mode.dm b/code/game/gamemodes/cult/runes/ghost_mode.dm
index eb908d3eead..a17eade9859 100644
--- a/code/game/gamemodes/cult/runes/ghost_mode.dm
+++ b/code/game/gamemodes/cult/runes/ghost_mode.dm
@@ -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("[user]'s eyes glow blue as \he freezes in place, absolutely motionless.", \
+ user.say("Fwe'sh maherl! Nyag r'ya!")
+ user.visible_message("[user]'s eyes glow red as \he freezes in place, absolutely motionless.", \
"The shadow that is your spirit separates itself from your body. You are now in the realm beyond. While this is a great sight, being here strains your mind and body. Hurry...", \
"You hear only complete silence for a moment.")
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)
\ No newline at end of file
+ return fizzle(user, A)
\ No newline at end of file
diff --git a/code/game/gamemodes/cult/runes/hide_runes.dm b/code/game/gamemodes/cult/runes/hide_runes.dm
index a5b87b85c55..34fb9cf58ca 100644
--- a/code/game/gamemodes/cult/runes/hide_runes.dm
+++ b/code/game/gamemodes/cult/runes/hide_runes.dm
@@ -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
\ No newline at end of file
diff --git a/code/game/gamemodes/cult/runes/manifest_ghost.dm b/code/game/gamemodes/cult/runes/manifest_ghost.dm
index ec66cf33c4d..55e082986bb 100644
--- a/code/game/gamemodes/cult/runes/manifest_ghost.dm
+++ b/code/game/gamemodes/cult/runes/manifest_ghost.dm
@@ -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("A shape forms in the center of the rune. A shape of... a man.", \
"A shape forms in the center of the rune. A shape of... a man.", \
"You hear liquid flowing.")
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 ..()
\ No newline at end of file
diff --git a/code/game/gamemodes/cult/runes/raise_dead.dm b/code/game/gamemodes/cult/runes/raise_dead.dm
index 0cce47fd19c..e3e8d5a0963 100644
--- a/code/game/gamemodes/cult/runes/raise_dead.dm
+++ b/code/game/gamemodes/cult/runes/raise_dead.dm
@@ -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)] A cultist is attempting to revive a body in [A.name]!")
+ to_chat(M, "[ghost_follow_link(user, M)] A cultist is attempting to revive a body in [Ar.name]!")
return fizzle(user)
corpse_to_raise.revive()
diff --git a/code/game/gamemodes/cult/runes/reveal_runes.dm b/code/game/gamemodes/cult/runes/reveal_runes.dm
index 95cdecb09ec..557e5ca8424 100644
--- a/code/game/gamemodes/cult/runes/reveal_runes.dm
+++ b/code/game/gamemodes/cult/runes/reveal_runes.dm
@@ -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
\ No newline at end of file
+ if(iscultist(user))
+ user.say("Nikt'o barada kla'atu!")
+ A.visible_message(message)
+ qdel(A)
diff --git a/code/game/gamemodes/cult/runes/rune.dm b/code/game/gamemodes/cult/runes/rune.dm
index 3f4e878cc1c..3ddd1d5fa13 100644
--- a/code/game/gamemodes/cult/runes/rune.dm
+++ b/code/game/gamemodes/cult/runes/rune.dm
@@ -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: [cult_description].")
- to_chat(user, "This rune [can_talisman ? "can" : "cannot"] be turned into a talisman.")
+ to_chat(user, rune.get_cultist_fluff_text())
+ to_chat(user, "This rune [rune.can_be_talisman() ? "can" : "cannot"] 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
\ No newline at end of file
diff --git a/code/game/gamemodes/cult/runes/sacrifice.dm b/code/game/gamemodes/cult/runes/sacrifice.dm
index 97c38c374f8..83523549f4d 100644
--- a/code/game/gamemodes/cult/runes/sacrifice.dm
+++ b/code/game/gamemodes/cult/runes/sacrifice.dm
@@ -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
diff --git a/code/game/gamemodes/cult/runes/see_invisible.dm b/code/game/gamemodes/cult/runes/see_invisible.dm
index 65ec9daf0a1..eac259abacb 100644
--- a/code/game/gamemodes/cult/runes/see_invisible.dm
+++ b/code/game/gamemodes/cult/runes/see_invisible.dm
@@ -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)
diff --git a/code/game/gamemodes/cult/runes/stun.dm b/code/game/gamemodes/cult/runes/stun.dm
index 319b3f73a9a..5b43bbf77a0 100644
--- a/code/game/gamemodes/cult/runes/stun.dm
+++ b/code/game/gamemodes/cult/runes/stun.dm
@@ -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)
diff --git a/code/game/gamemodes/cult/runes/summon_cultist.dm b/code/game/gamemodes/cult/runes/summon_cultist.dm
index ea7f9908c50..1ebc978775a 100644
--- a/code/game/gamemodes/cult/runes/summon_cultist.dm
+++ b/code/game/gamemodes/cult/runes/summon_cultist.dm
@@ -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("The rune disappears with a flash of red light, and in its place now a body lies.", \
"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.", \
"You hear a pop and smell ozone.")
- qdel(src)
- return fizzle(user)
\ No newline at end of file
+ qdel(A)
+ return fizzle(user, A)
\ No newline at end of file
diff --git a/code/game/gamemodes/cult/runes/summon_narsie.dm b/code/game/gamemodes/cult/runes/summon_narsie.dm
index 8bbe042318f..10f9b4b1514 100644
--- a/code/game/gamemodes/cult/runes/summon_narsie.dm
+++ b/code/game/gamemodes/cult/runes/summon_narsie.dm
@@ -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)
\ No newline at end of file
+ return fizzle(user, A)
\ No newline at end of file
diff --git a/code/game/gamemodes/cult/runes/summon_soulstone.dm b/code/game/gamemodes/cult/runes/summon_soulstone.dm
index 34b49dc6c73..bfffa844cf6 100644
--- a/code/game/gamemodes/cult/runes/summon_soulstone.dm
+++ b/code/game/gamemodes/cult/runes/summon_soulstone.dm
@@ -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
\ No newline at end of file
diff --git a/code/game/gamemodes/cult/runes/summon_tome.dm b/code/game/gamemodes/cult/runes/summon_tome.dm
index 14763bd3326..6f452fbe176 100644
--- a/code/game/gamemodes/cult/runes/summon_tome.dm
+++ b/code/game/gamemodes/cult/runes/summon_tome.dm
@@ -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("Rune disappears with a flash of red light, and in its place now a book lies.", \
- "You are blinded by the flash of red light! After you're able to see again, you see that now instead of the rune there's a book.", \
+/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("\The [A] disappears with a flash of red light, and in its place lies a book.", \
+ "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].", \
"You hear a pop and smell ozone.")
- new /obj/item/book/tome(get_turf(O))
- qdel(O)
+ new /obj/item/book/tome(get_turf(A))
+ qdel(A)
return TRUE
\ No newline at end of file
diff --git a/code/game/gamemodes/cult/runes/teleport.dm b/code/game/gamemodes/cult/runes/teleport.dm
index 61730119847..0f1dcdd6110 100644
--- a/code/game/gamemodes/cult/runes/teleport.dm
+++ b/code/game/gamemodes/cult/runes/teleport.dm
@@ -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: [network].")
+ 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: [network]."
+
+/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("[user] disappears in a flash of red light!", \
- "You feel as your body gets dragged through the dimension of Nar-Sie!", \
+ "You feel as if your body gets dragged through Redspace!", \
"You hear a sickening crunch and sloshing of viscera.")
- 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
- . = ..()
\ No newline at end of file
diff --git a/code/game/gamemodes/cult/runes/wall.dm b/code/game/gamemodes/cult/runes/wall.dm
index 20702dd62e1..48e0e59d117 100644
--- a/code/game/gamemodes/cult/runes/wall.dm
+++ b/code/game/gamemodes/cult/runes/wall.dm
@@ -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
\ No newline at end of file
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index a408d2b365a..f5938da57c8 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -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))
diff --git a/code/game/objects/items/weapons/chaplain_items.dm b/code/game/objects/items/weapons/chaplain_items.dm
index cc3d66cce1f..9f5da0d35b8 100644
--- a/code/game/objects/items/weapons/chaplain_items.dm
+++ b/code/game/objects/items/weapons/chaplain_items.dm
@@ -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
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index ab1a06bad41..7900e085930 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -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"
diff --git a/code/modules/mob/abstract/observer/observer.dm b/code/modules/mob/abstract/observer/observer.dm
index 260397472e3..474619bfa61 100644
--- a/code/modules/mob/abstract/observer/observer.dm
+++ b/code/modules/mob/abstract/observer/observer.dm
@@ -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
diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm
index 610f616f544..d2957d0fe76 100644
--- a/code/modules/mob/living/carbon/human/species/species.dm
+++ b/code/modules/mob/living/carbon/human/species/species.dm
@@ -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)
diff --git a/code/modules/spell_system/spells/spell_list/self/generic/rune_write.dm b/code/modules/spell_system/spells/spell_list/self/generic/rune_write.dm
index 5d40b8708ba..1599721c1ae 100644
--- a/code/modules/spell_system/spells/spell_list/self/generic/rune_write.dm
+++ b/code/modules/spell_system/spells/spell_list/self/generic/rune_write.dm
@@ -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)
diff --git a/html/changelogs/mattatlas-cultboys.yml b/html/changelogs/mattatlas-cultboys.yml
new file mode 100644
index 00000000000..72ba2916714
--- /dev/null
+++ b/html/changelogs/mattatlas-cultboys.yml
@@ -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."
diff --git a/icons/obj/rune.dmi b/icons/obj/rune.dmi
index d7b1a5d9013..7cded0f02a9 100644
Binary files a/icons/obj/rune.dmi and b/icons/obj/rune.dmi differ