Files
Bubberstation/code/datums/components/cult_ritual_item.dm
T
carlarctgandGitHub 4eaa299c0b Cult Vs. Heretic: 7 Months Later Edition (#82877)
## About The Pull Request

This PR was originally meant as a replacement for the Bloody Bastard
blade, but then I stopped existing for 7 months. Now that I'm here
again, I'm finishing the job once and for all.

### **HERETICS VERSUS CULTISTS**

### Heretics

Heretics can now sacrifice cultists, which will give them one of three
gifts: The Cursed Blade, the Crimson Focus, and the Rusted Harvester.
The gifts given are weighted to be spread out equally with each type.
They will also gain one knowledge point.

- The Cursed Blade is a free heretic blade that is more powerful than
the normal heretic blade, including a small block chance. It can also be
used to draw heretic runes off combat mode.
- The Crimson Focus is a necklace that grants focusing and a minor
regeneration effect which also affects nearby heretics, at the cost of
gaining the BLOODY_MESS trait while wearing it. Additionally, it can be
squeezed to heal 50 points of brute/burn damage, injecting yourself with
three to six (separately) units of Eldritch ~~Water~~ Essence and Unholy
Water. Yes, this isn't good.
- The Rusted Harvester is a heretic 'monster' summon. It's a normal
Harvester, but instead of Area Conversion and Forcewall, it has
Aggressive Spread and Rust Construction (Raise Wall). It can delimb, but
only cultists, with a delay. It has an aura of decay, corroding the
environment and withering enemies near it, but it's VERY fragile.

Rusting cultist item dispensers will now cause them to turn into a
Heretic object. Altars turn into small heretic runes, Archives turn into
Codex Cicatrixi, Forges turn into Mawed Crucibles.

Ideally, Heretics would be able to gain an amount of these new powers
and use them to turn the tide against the cultists, amassing their power
and almost forming a sect of their own in turn which sweeps over and
converts the cult.

### Cultists

When a Cultist sacrifices a heretic, two things will happen:

- A new item will be available for creation at one of the dispensers.
- The Heretic will be trapped inside a powerful Haunted Blade.

`/obj/item/melee/cultblade/haunted`
`	name = "haunted longsword"`
` desc = "An eerie sword with a blade that is less 'black' than it is
'absolute nothingness'. It glows with furious, restrained green
energy."`

This blade will be stronger across-the-board than a normal cult sword,
and will even allow those who wield it to cast one heretic spell from
their previous path. The only downside? The heretic can also cast one
spell. It's up to the trapped spirit if it wants to help you, or be a
nuisance.

The unlocked items are:
- The Cursed Blade, again. For cultists, it can be used to draw runes
twice as fast as usual, and they can even right-click it to teleport to
safety, just like a heretic!
- The Crimson Focus, again. Cultists are twice as fast at carving spells
into their body, and they gain a 5th spellslot as long as they wear the
amulet. It still causes hemophilia and grants weak regeneration.
- The Proteon Orb. This orb will create a gateway to Nar'sie's own
realm, spawning one Proteon every 15 seconds, which ghosts can possess.
The gateways cannot be placed close to one another.

Originally, they were going to be able to create a Harvester Shell, but
there were some concerns of it being too OP.

The true Bastard sword has been fully deleted. The null rod conversion
has been changed to a Bloody Halberd instead.

I'm considering re-enabling Stun Hand on Heretics, with Mansus Grasp
stats.

### Other

All the items above can be used by both Heretics and Cultists, no matter
how they were first created. Hell, even normal crew can use them! This
is probably not the best idea a lot of the time, though.

There are a lot of other changes in this PR. A loooooot. I will likely
miss some in the changelog, but I'll try to be as thorough as possible.
There's probably also some leftover garbo that I didn't find and clear
out yet.

## Why It's Good For The Game

Cult and Heretics, despite being mortally opposed, have very few
interactions with eachother, especially now that the Blade's gone. The
only thing of note is just the Heretic's unfair complete resistance to
stun hand, which is only marginally better than the alternative. This PR
will reintroduce their animosity, and give both sides a very, very good
reason to fight eachother.

The Cult will gain a sick sword that keeps the heretic in the game, and
unlike with the original implementation, will recieve a cult-wide bonus
in the form of a powerful, well deserved, and fun new item to summon.

The Heretic will gain powerful trinkets and knowledge from the
sacrifices, incentivizing them to become a terrifying cult-hunter. And
if they do succeed in wiping out the cult, they will have quite the
rewards to help with their ascension.

The crew, while mostly unaffected, will have a damn good reason to not
just Side with the heretic, out of fear of what they may become after
the cult is stomped down. They can also use a few of the items here in
an attempt to get one up on either side, as long as they manage to stay
clear of the side-effects.

Let the heretics eradicate the apostates.

Let the cultists root out the heathens.

![image](https://github.com/tgstation/tgstation/assets/53100513/b43d5d94-d06d-43b8-9b10-57f5a4a32bdb)
The haunted longsword creates an aura of darkness (disabled for the
cultist for the image)
Sprites... are not great. Hopefully someone comes by and improves them.

code: Added get_inactive_hand() as an easy shortcut for carbons
code: Wall walker element can now accept a trait for wall-checking
fix: Fixed soulsword component being unable to invoke the post summon
callback
refactor: Turned Heretic rust turf healing into an element, given to
Rust Walkers and Rusted Harvesters
refactor: Converted Limb Amputation from an element to a component

Blade and Sword sprites by meyhaza!!! I did the inhands though. Cuz im
cool
2024-06-29 12:40:33 -05:00

493 lines
18 KiB
Plaintext

/*
* Component for items that are used by cultists to conduct rituals.
*
* - Draws runes, including the rune to summon Nar'sie.
* - Purges cultists of holy water on attack.
* - (Un/re)anchors cult structures when hit.
* - Instantly destroys cult girders on hit.
*/
/datum/component/cult_ritual_item
/// Whether we are currently being used to draw a rune.
var/drawing_a_rune = FALSE
/// The message displayed when the parent is examined, if supplied.
var/examine_message
/// A list of turfs that we scribe runes at double speed on.
var/list/turfs_that_boost_us
/// A list of all shields surrounding us while drawing certain runes (Nar'sie).
var/list/obj/structure/emergency_shield/cult/narsie/shields
/// Weakref to an action added to our parent item that allows for quick drawing runes
var/datum/weakref/linked_action_ref
/datum/component/cult_ritual_item/Initialize(
examine_message,
action = /datum/action/item_action/cult_dagger,
turfs_that_boost_us = /turf/open/floor/engine/cult,
)
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
src.examine_message = examine_message
if(islist(turfs_that_boost_us))
src.turfs_that_boost_us = turfs_that_boost_us
else if(ispath(turfs_that_boost_us))
src.turfs_that_boost_us = list(turfs_that_boost_us)
if(ispath(action))
var/obj/item/item_parent = parent
var/datum/action/added_action = item_parent.add_item_action(action)
linked_action_ref = WEAKREF(added_action)
/datum/component/cult_ritual_item/Destroy(force)
cleanup_shields()
QDEL_NULL(linked_action_ref)
return ..()
/datum/component/cult_ritual_item/RegisterWithParent()
RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, PROC_REF(try_scribe_rune))
RegisterSignal(parent, COMSIG_ITEM_ATTACK, PROC_REF(try_purge_holywater))
RegisterSignal(parent, COMSIG_ITEM_ATTACK_ATOM, PROC_REF(try_hit_object))
RegisterSignal(parent, COMSIG_ITEM_ATTACK_EFFECT, PROC_REF(try_clear_rune))
if(examine_message)
RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine))
/datum/component/cult_ritual_item/UnregisterFromParent()
UnregisterSignal(parent, list(
COMSIG_ITEM_ATTACK_SELF,
COMSIG_ITEM_ATTACK,
COMSIG_ITEM_ATTACK_ATOM,
COMSIG_ITEM_ATTACK_EFFECT,
COMSIG_ATOM_EXAMINE,
))
/*
* Signal proc for [COMSIG_ATOM_EXAMINE].
* Gives the examiner, if they're a cultist, our set examine message.
* Usually, this will include various instructions on how to use the thing.
*/
/datum/component/cult_ritual_item/proc/on_examine(datum/source, mob/examiner, list/examine_text)
SIGNAL_HANDLER
if(!IS_CULTIST(examiner))
return
examine_text += examine_message
/*
* Signal proc for [COMSIG_ITEM_ATTACK_SELF].
* Allows the user to begin scribing runes.
*/
/datum/component/cult_ritual_item/proc/try_scribe_rune(datum/source, mob/user)
SIGNAL_HANDLER
if(!isliving(user))
return
if(!can_scribe_rune(source, user))
return
if(drawing_a_rune)
to_chat(user, span_warning("You are already drawing a rune."))
return
INVOKE_ASYNC(src, PROC_REF(start_scribe_rune), source, user)
return COMPONENT_CANCEL_ATTACK_CHAIN
/*
* Signal proc for [COMSIG_ITEM_ATTACK].
* Allows for a cultist (user) to hit another cultist (target)
* to purge them of all holy water in their system, transforming it into unholy water.
*/
/datum/component/cult_ritual_item/proc/try_purge_holywater(datum/source, mob/living/target, mob/living/user)
SIGNAL_HANDLER
if(!IS_CULTIST(user) || !IS_CULTIST(target))
return
. = COMPONENT_CANCEL_ATTACK_CHAIN // No hurting other cultists.
if(!target.has_reagent(/datum/reagent/water/holywater))
return
INVOKE_ASYNC(src, PROC_REF(do_purge_holywater), target, user)
/*
* Signal proc for [COMSIG_ITEM_ATTACK_ATOM].
* Allows the ritual items to unanchor cult buildings or destroy rune girders.
*/
/datum/component/cult_ritual_item/proc/try_hit_object(datum/source, obj/structure/target, mob/cultist)
SIGNAL_HANDLER
if(!isliving(cultist) || !IS_CULTIST(cultist))
return
if(istype(target, /obj/structure/girder/cult))
INVOKE_ASYNC(src, PROC_REF(do_destroy_girder), target, cultist)
return COMPONENT_NO_AFTERATTACK
if(istype(target, /obj/structure/destructible/cult))
INVOKE_ASYNC(src, PROC_REF(do_unanchor_structure), target, cultist)
return COMPONENT_NO_AFTERATTACK
/*
* Signal proc for [COMSIG_ITEM_ATTACK_EFFECT].
* Allows the ritual items to remove runes.
*/
/datum/component/cult_ritual_item/proc/try_clear_rune(datum/source, obj/effect/target, mob/living/cultist, params)
SIGNAL_HANDLER
if(!isliving(cultist) || !IS_CULTIST(cultist))
return
if(istype(target, /obj/effect/rune))
INVOKE_ASYNC(src, PROC_REF(do_scrape_rune), target, cultist)
return COMPONENT_NO_AFTERATTACK
/*
* Actually go through and remove all holy water from [target] and convert it to unholy water.
*
* target - the target being hit, and having their holywater converted
* cultist - the target doing the hitting, can be the same as target
*/
/datum/component/cult_ritual_item/proc/do_purge_holywater(mob/living/target, mob/living/cultist)
// Allows cultists to be rescued from the clutches of ordained religion
to_chat(cultist, span_cult("You remove the taint from [target] using [parent]."))
var/holy_to_unholy = target.reagents.get_reagent_amount(/datum/reagent/water/holywater)
target.reagents.del_reagent(/datum/reagent/water/holywater)
// For carbonss we also want to clear out the stomach of any holywater
if(iscarbon(target))
var/mob/living/carbon/carbon_target = target
var/obj/item/organ/internal/stomach/belly = carbon_target.get_organ_slot(ORGAN_SLOT_STOMACH)
if(belly)
holy_to_unholy += belly.reagents.get_reagent_amount(/datum/reagent/water/holywater)
belly.reagents.del_reagent(/datum/reagent/water/holywater)
target.reagents.add_reagent(/datum/reagent/fuel/unholywater, holy_to_unholy)
log_combat(cultist, target, "smacked", parent, " removing the holy water from them")
/*
* Destoys the target cult girder [cult_girder], acted upon by [cultist].
*
* cult_girder - the girder being destoyed
* cultist - the mob doing the destroying
*/
/datum/component/cult_ritual_item/proc/do_destroy_girder(obj/structure/girder/cult/cult_girder, mob/living/cultist)
playsound(cult_girder, 'sound/weapons/resonator_blast.ogg', 40, TRUE, ignore_walls = FALSE)
cultist.visible_message(
span_warning("[cultist] strikes [cult_girder] with [parent]!"),
span_notice("You demolish [cult_girder].")
)
new /obj/item/stack/sheet/runed_metal(cult_girder.drop_location(), 1)
qdel(cult_girder)
/*
* Unanchors the target cult building.
*
* cult_structure - the structure being unanchored or reanchored.
* cultist - the mob doing the unanchoring.
*/
/datum/component/cult_ritual_item/proc/do_unanchor_structure(obj/structure/cult_structure, mob/living/cultist)
playsound(cult_structure, 'sound/items/deconstruct.ogg', 30, TRUE, ignore_walls = FALSE)
cult_structure.set_anchored(!cult_structure.anchored)
to_chat(cultist, span_notice("You [cult_structure.anchored ? "":"un"]secure \the [cult_structure] [cult_structure.anchored ? "to":"from"] the floor."))
/*
* Removes the targeted rune. If the rune is important, asks for confirmation and logs it.
*
* rune - the rune being deleted. Instance of a rune.
* cultist - the mob deleting the rune
*/
/datum/component/cult_ritual_item/proc/do_scrape_rune(obj/effect/rune/rune, mob/living/cultist)
if(rune.log_when_erased)
var/confirm = tgui_alert(cultist, "Erasing this [rune.cultist_name] rune may work against your goals.", "Begin to erase the [rune.cultist_name] rune?", list("Proceed", "Abort"))
if(confirm != "Proceed")
return
// Gee, good thing we made sure cultists can't input stall to grief their team and get banned anyway
if(!can_scrape_rune(rune, cultist))
return
SEND_SOUND(cultist, 'sound/items/sheath.ogg')
if(!do_after(cultist, rune.erase_time, target = rune))
return
if(!can_scrape_rune(rune, cultist))
return
if(rune.log_when_erased)
cultist.log_message("erased a [rune.cultist_name] rune with [parent].", LOG_GAME)
message_admins("[ADMIN_LOOKUPFLW(cultist)] erased a [rune.cultist_name] rune with [parent].")
to_chat(cultist, span_notice("You carefully erase the [LOWER_TEXT(rune.cultist_name)] rune."))
qdel(rune)
/*
* Wraps the entire act of [/proc/do_scribe_rune] to ensure it properly enables or disables [var/drawing_a_rune].)
*
* tool - the parent, source of the signal - the item inscribing the rune, casted to item.
* cultist - the mob scribing the rune
*/
/datum/component/cult_ritual_item/proc/start_scribe_rune(obj/item/tool, mob/living/cultist)
drawing_a_rune = TRUE
do_scribe_rune(tool, cultist)
drawing_a_rune = FALSE
/*
* Actually give the user input to begin scribing a rune.
* Creates the new instance of the rune if successful.
*
* tool - the parent, source of the signal - the item inscribing the rune, casted to item.
* cultist - the mob scribing the rune
*/
/datum/component/cult_ritual_item/proc/do_scribe_rune(obj/item/tool, mob/living/cultist)
var/turf/our_turf = get_turf(cultist)
var/obj/effect/rune/rune_to_scribe
var/entered_rune_name
var/chosen_keyword
var/datum/antagonist/cult/user_antag = cultist.mind.has_antag_datum(/datum/antagonist/cult, TRUE)
var/datum/team/cult/user_team = user_antag?.get_team()
if(!user_antag || !user_team)
stack_trace("[type] - [cultist] attempted to scribe a rune, but did not have an associated [user_antag ? "cult team":"cult antag datum"]!")
return FALSE
if(!LAZYLEN(GLOB.rune_types))
to_chat(cultist, span_cult("There appears to be no runes to scribe. Contact your god about this!"))
stack_trace("[type] - [cultist] attempted to scribe a rune, but the global rune list is empty!")
return FALSE
entered_rune_name = tgui_input_list(cultist, "Choose a rite to scribe", "Sigils of Power", GLOB.rune_types)
if(isnull(entered_rune_name))
return FALSE
if(!can_scribe_rune(tool, cultist))
return FALSE
rune_to_scribe = GLOB.rune_types[entered_rune_name]
if(!ispath(rune_to_scribe))
stack_trace("[type] - [cultist] attempted to scribe a rune, but did not find a path from the global rune list!")
return FALSE
if(initial(rune_to_scribe.req_keyword))
chosen_keyword = tgui_input_text(cultist, "Keyword for the new rune", "Words of Power", max_length = MAX_NAME_LEN)
if(!chosen_keyword)
drawing_a_rune = FALSE
start_scribe_rune(tool, cultist)
return FALSE
our_turf = get_turf(cultist) //we may have moved. adjust as needed...
if(!can_scribe_rune(tool, cultist))
return FALSE
if(ispath(rune_to_scribe, /obj/effect/rune/summon) && (!is_station_level(our_turf.z) || istype(get_area(cultist), /area/space)))
to_chat(cultist, span_cult_italic("The veil is not weak enough here to summon a cultist, you must be on station!"))
return
if(ispath(rune_to_scribe, /obj/effect/rune/apocalypse))
if((world.time - SSticker.round_start_time) <= 6000)
var/wait = 6000 - (world.time - SSticker.round_start_time)
to_chat(cultist, span_cult_italic("The veil is not yet weak enough for this rune - it will be available in [DisplayTimeText(wait)]."))
return
if(!check_if_in_ritual_site(cultist, user_team, TRUE))
return
if(ispath(rune_to_scribe, /obj/effect/rune/narsie))
if(!scribe_narsie_rune(cultist, user_team))
return
cultist.visible_message(
span_warning("[cultist] [cultist.blood_volume ? "cuts open [cultist.p_their()] arm and begins writing in [cultist.p_their()] own blood":"begins sketching out a strange design"]!"),
span_cult("You [cultist.blood_volume ? "slice open your arm and ":""]begin drawing a sigil of the Geometer.")
)
if(cultist.blood_volume)
cultist.apply_damage(initial(rune_to_scribe.scribe_damage), BRUTE, pick(GLOB.arm_zones), wound_bonus = CANT_WOUND) // *cuts arm* *bone explodes* ever have one of those days?
var/scribe_mod = initial(rune_to_scribe.scribe_delay)
if(!initial(rune_to_scribe.no_scribe_boost) && (our_turf.type in turfs_that_boost_us))
scribe_mod *= 0.5
var/scribe_started = initial(rune_to_scribe.started_creating)
var/scribe_failed = initial(rune_to_scribe.failed_to_create)
if(scribe_started)
var/datum/callback/startup = CALLBACK(GLOBAL_PROC, scribe_started)
startup.Invoke()
var/datum/callback/failed
if(scribe_failed)
failed = CALLBACK(GLOBAL_PROC, scribe_failed)
SEND_SOUND(cultist, sound('sound/weapons/slice.ogg', 0, 1, 10))
if(!do_after(cultist, scribe_mod, target = get_turf(cultist), timed_action_flags = IGNORE_SLOWDOWNS))
cleanup_shields()
failed?.Invoke()
return FALSE
if(!can_scribe_rune(tool, cultist))
cleanup_shields()
failed?.Invoke()
return FALSE
cultist.visible_message(
span_warning("[cultist] creates a strange circle[cultist.blood_volume ? " in [cultist.p_their()] own blood":""]."),
span_cult("You finish drawing the arcane markings of the Geometer.")
)
cleanup_shields()
var/obj/effect/rune/made_rune = new rune_to_scribe(our_turf, chosen_keyword)
made_rune.add_mob_blood(cultist)
to_chat(cultist, span_cult("The [LOWER_TEXT(made_rune.cultist_name)] rune [made_rune.cultist_desc]"))
cultist.log_message("scribed \a [LOWER_TEXT(made_rune.cultist_name)] rune using [parent] ([parent.type])", LOG_GAME)
SSblackbox.record_feedback("tally", "cult_runes_scribed", 1, made_rune.cultist_name)
return TRUE
/*
* The process of scribing the nar'sie rune.
*
* cultist - the mob placing the rune
* cult_team - the team of the mob placing the rune
*/
/datum/component/cult_ritual_item/proc/scribe_narsie_rune(mob/living/cultist, datum/team/cult/cult_team)
var/datum/objective/eldergod/summon_objective = locate() in cult_team.objectives
var/datum/objective/sacrifice/sac_objective = locate() in cult_team.objectives
if(!check_if_in_ritual_site(cultist, cult_team))
return FALSE
if(sac_objective && !sac_objective.check_completion())
to_chat(cultist, span_warning("The sacrifice is not complete. The portal would lack the power to open if you tried!"))
return FALSE
if(summon_objective.check_completion())
to_chat(cultist, span_cult_large("\"I am already here. There is no need to try to summon me now.\""))
return FALSE
var/confirm_final = tgui_alert(cultist, "This is the FINAL step to summon Nar'Sie; it is a long, painful ritual and the crew will be alerted to your presence.", "Are you prepared for the final battle?", list("My life for Nar'Sie!", "No"))
if(confirm_final == "No")
to_chat(cultist, span_cult("You decide to prepare further before scribing the rune."))
return
if(!check_if_in_ritual_site(cultist, cult_team))
return FALSE
var/area/summon_location = get_area(cultist)
priority_announce(
text = "Figments from an eldritch god are being summoned by [cultist.real_name] into [summon_location.get_original_area_name()] from an unknown dimension. Disrupt the ritual at all costs!",
sound = 'sound/ambience/antag/bloodcult/bloodcult_scribe.ogg',
sender_override = "[command_name()] Higher Dimensional Affairs",
has_important_message = TRUE,
)
for(var/shielded_turf in spiral_range_turfs(1, cultist, 1))
LAZYADD(shields, new /obj/structure/emergency_shield/cult/narsie(shielded_turf))
notify_ghosts(
"[cultist] has begun scribing a Nar'Sie rune!",
source = cultist,
header = "Maranax Infirmux!",
notify_flags = NOTIFY_CATEGORY_NOFLASH,
)
return TRUE
/*
* Helper to check if a rune can be scraped by a cultist.
* Used in between inputs of [do_scrape_rune] for sanity checking.
*
* rune - the rune being deleted. Instance of a rune.
* cultist - the mob deleting the rune
*/
/datum/component/cult_ritual_item/proc/can_scrape_rune(obj/effect/rune/rune, mob/living/cultist)
if(!IS_CULTIST(cultist))
return FALSE
if(!cultist.is_holding(parent))
return FALSE
if(!rune.Adjacent(cultist))
return FALSE
if(cultist.incapacitated())
return FALSE
if(cultist.stat == DEAD)
return FALSE
return TRUE
/*
* Helper to check if a rune can be scribed by a cultist.
* Used in between inputs of [do_scribe_rune] for sanity checking.
*
* tool - the parent - the item being used to scribe the rune, casted to item
* cultist - the mob making the rune
*/
/datum/component/cult_ritual_item/proc/can_scribe_rune(obj/item/tool, mob/living/cultist)
if(!IS_CULTIST(cultist))
to_chat(cultist, span_warning("[tool] is covered in unintelligible shapes and markings."))
return FALSE
if(QDELETED(tool) || !cultist.is_holding(tool))
return FALSE
if(cultist.incapacitated() || cultist.stat == DEAD)
to_chat(cultist, span_warning("You can't draw a rune right now."))
return FALSE
if(!check_rune_turf(get_turf(cultist), cultist))
return FALSE
return TRUE
/*
* Checks if a turf is valid for having a rune placed there.
*
* target - the turf being checked
* cultist - the mob placing the rune
*/
/datum/component/cult_ritual_item/proc/check_rune_turf(turf/target, mob/living/cultist)
if(isspaceturf(target))
to_chat(cultist, span_warning("You cannot scribe runes in space!"))
return FALSE
if(locate(/obj/effect/rune) in target)
to_chat(cultist, span_cult("There is already a rune here."))
return FALSE
var/area/our_area = get_area(target)
if((!is_station_level(target.z) && !is_mining_level(target.z)) || (our_area && !(our_area.area_flags & CULT_PERMITTED)))
to_chat(cultist, span_warning("The veil is not weak enough here."))
return FALSE
return TRUE
/*
* Helper to check a cultist is located in one of the ritual / summoning sites.
*
* cultist - the mob making the rune
* cult_team - the team of the mob making the rune
* fail_if_last_site - whether the check fails if it's the last site in the summoning list.
*/
/datum/component/cult_ritual_item/proc/check_if_in_ritual_site(mob/living/cultist, datum/team/cult/cult_team, fail_if_last_site = FALSE)
var/datum/objective/eldergod/summon_objective = locate() in cult_team.objectives
var/area/our_area = get_area(cultist)
if(!summon_objective)
to_chat(cultist, span_warning("There are no ritual sites on this station to scribe this rune!"))
return FALSE
if(!(our_area in summon_objective.summon_spots))
to_chat(cultist, span_warning("This veil is not weak enough here - it can only be scribed in [english_list(summon_objective.summon_spots)]!"))
return FALSE
if(fail_if_last_site && length(summon_objective.summon_spots) <= 1)
to_chat(cultist, span_warning("This rune cannot be scribed here - the ritual site must be reserved for the final summoning!"))
return FALSE
return TRUE
/*
* Removes all shields from the shields list.
*/
/datum/component/cult_ritual_item/proc/cleanup_shields()
for(var/obj/structure/emergency_shield/cult/narsie/shield as anything in shields)
LAZYREMOVE(shields, shield)
if(!QDELETED(shield))
qdel(shield)