Files
Bubberstation/code/modules/unit_tests/heretic_rituals.dm
EnterTheJake 5a85095111 Introduces 6 New Heretic sideknowledges, 1 new spell to Blade Path. + changes to the Research Tree. (#89169)
Introduces 6 new Heretic Sideknowledges.

**Warren King's Welcome:** Starting side-knowledge, Grants to the
Heretic's id Maints and External Airlock access.

**Phylactery Of Damnation:** T1 Knowledge, located between Imperfect
Ritual and Keykeeper's Burden, creates a bottle that can Siphon a small
quantity of blood from your victim, (they'll still feel a tiny prick).

![potion_red](https://github.com/user-attachments/assets/b000300a-2f2c-47f1-9fd3-b9d8e0f4f587)

**Ether Of The Newborn:** T2 knowledge, replaces Curse Of Paralysis slot
in the tree (Inbetween Mark of Madness and Moonlight Amulette).

![potion_green](https://github.com/user-attachments/assets/bc45c69f-4a16-4879-b788-661112e35638)

1 use potion, fully restores the inbiber to full health, removes any
sort of affliction,trauma,disease or implant at the cost of knocking the
user out for 1 minute.

**Codex Morbus:** T3 knowledge, located between Caretaker's Refuge and
Ringleader's RIse.

![codex
gif](https://github.com/user-attachments/assets/8a15dc78-30b9-4a21-93eb-bafbeebd59a4)

![Codex Morbius
Final](https://github.com/user-attachments/assets/04c8739c-5c65-4246-9408-3cbdbc57a164)

Upgrade of the Codex Cicatrix, draws and siphons runes and essences a
bit faster, can be used on a rune to curse a crewmember, provided their
blood is on the rune or on the Heretic.

**Greaves Of The Prophet:** T3 knowledge, located between Entropic Plume
and Wolves Among Sheep.

![Greaves](https://github.com/user-attachments/assets/287b592e-b771-40ed-99b3-25820550d6a0)

They work as magical magboots minus the slowdown; they confer full
immunity to slips (yes, even space lube).

**Rust Sower Grenade:** T2 knowledge, replaces curse of corrosion in the
tree (between Aggressive Spread and Star Blast).

![Rustsower](https://github.com/user-attachments/assets/297f045c-38c3-4ed0-9046-52d797610339)

Eldritch grenade, Releases a smoke that rusts all affected turfs, blinds
whoever doesn't have mask protection and utterly annihilates silicons,
mechs, augs and bots.

Video Showcase: https://www.youtube.com/watch?v=H1GeO7MYFek

**New Blade Path Spell: Wolves Among Sheep**

Video Showcase: https://www.youtube.com/watch?v=2LsmUiQzpzA

- Briefly transforms the surrounding the heretic into an arena.

- Both The Heretic and Crew members caught inside the spell cannot leave
or change z level until the spell expires.

- The arena is impassable to outsiders.

- Everyone caught inside the spell receives a special buff that makes
them immune to most enviromental hazards and all forms of Crowd Control
while blocking teleportation.

- Non Heretics are granted a temporary Heretic Blade and an antag datum.

- Scoring a critical hit grants the winner the ability to leave the
arena, Critting the heretic fully dissolves the spell.

- Critting yourself doesn't remove the debuff.

- The Heretic receives a heal upon critting someone.

- Breaking a blade while inside the arena will rip off your arm
regardless if you are crew or a Heretic.

- 2 minutes cooldown.

- Replaces Furious Steel as the last spell unlocked pre-ascension.

Lastly as you may have guessed, curses have been completely refactored,
they are now bound to the new item (Codex Morbus), are no longer
empowered by blood but require it as a reagent.

Curse of Corrosion and Paralysis have been rebalanced to be slightly
stronger than they were at their base value now that they can no longer
be empowered.

2 new curses have be introduced.

**Curse Of Indulgence:** tanks the target hunger, makes them a carnivore
and drastically increases their hunger decay rate, lasts 8 minutes.

**Curse Of Transmogrification:** Allows the Heretic to change the
target's Race(minus plasmamen for obvious reasons), lasts until the
Codex Morbus is destroyed.

Lastly the Blade Heretic tree has been shuffled a bit to introduce the
new spell.

Stance Of the Torn Champion has been **TEMPORARILY** Removed, it will
come back in a later PR.

Code by me and Xander

Sprites by INFRARED_BARON and OrcaCora.

Lore tibids by NecromancerAnne.

The following is an atomisation of The Heretic Knowledge Rework I'm
currently working on alongside Edge (Heretic's Grandaddy).

Given the whole PR was probably going to be impossibly big to review; I
asked Melbert If could introduce the new knowledges first, so here we
are.

Do not stress the locations of these knowledges in the tree; While they
do fill what few empty slots we still have, it doesn't change the fact
that the Heretic tree is an incomprehensible mess and will soon be
reworked.

**Warren King's Welcome:**

Not having mantainence access as an antag sucks.

Arguably it sucks even more for Heretics as they are required to find
some place discrete in order to be able to cast their rituals.

It's not unusual for the station to be so crowded, that setting up a
base in space is the only option, the external access helps with that a
little bit.

**Phylactery Of Damnation and Codex Morbus**

Explaining them in the same paragraph as they are intended to be used
together.

Curses might as well not exist in their current state.

The process of cursing a crewmember is way too machineous, annoying, and
nowhere near as affective as simply running to your victim and smacking
it with your blade.

All Curses have now been bundled to the new Codex, they no longer
require X reagents, only a drip of the victim's blood.

That's when the phylactery comes into play.

Victims still feel "a tiny prick" upon being juiced, so beware.

**Ether Of The Newborn:** The point of this knowledge is to serve as a
backup plan to "random bullshittery".

It's not really fun rolling one bad trauma or disease and have it
completely invalidate your Heretic round.

We already have potions that either heal or provide remedies against
wounds/limb loss, the Ether is supposed to be an extreme solution, hence
why it causes a 1 minute sleep upon consumption.

**Greaves Of The Prophet:** Heretic to this day is fairly lacking when
it comes to passive immunities or tools we grant to most of our core
antagonists.

Specifically, for a melee-focused antagonist, a total lack of antislip
is kinda lame, being one of the most common defense tools employed by
the crew against newbie antagonist players.

Given these cannot be concealed unlike the traitor counterpart and how
far down the tree they are, i felt like making them lube resistant was a
unique twist and sensible for what's essentialy our core progression
antagonist.

**Rust Sower Grenade:** directly inspired by the 40k Blight Grenades.

The Rust Sower nades serve a double purpose.

1) They introduce a new form of area Denial available to all heretic
paths.

2) They confer to non Rust Heretics a way to deal with the so hated
Silicon Menace.

I'm of the not-so-unpopular school of thought of "Mechs and Silicons
have had it too good for too long".

A massive chunk of our threat roster gets to this day completely shut
down by mechs.

I feel like it was about time to make everything Inorganic feel afraid
again.

To make it a bit more fair, these grenades have a fairly long detonation
timer and have been given a couple of unique SFX.

**Wolves Among Sheep**

Even after the last batch of Changes, Blade Heretic still felt a bit
uninspired to me.

The path is still essentialy just about running at people and stabbing
them in the face.

While that's part of the appreal, I'd reckon it's still lacking a bit on
the eldritch side of things.

Trapping opponents into an arena when they are forced to either engage
you or betray their friends to escape can create some potentially
interesting story-telling.

It also warps the ,oh, so beloathed stun meta we live in by forcing
participants to resort to lethal weaponry.

Ultimately, this is supposed to be a high risk/high reward spell, if you
trap 5 people arm them with heretic blades, and make them all fully stun
immune, you are likely gonna get lynched.

To free up a slot in the tree I **TEMPORARILY** Removed Stance of the
Torn champion, it will come back in my nextish pr, so don't worry about
it too much.

🆑
add: New Heretic starting Side-Knowdge Warren King's Welcome
add: New Heretic T1 Side knowledge, Phylactery Of Damnation.
add: New Heretic T2 Side knowledge, Ether Of The Newborn.
add: New Heretic T3 Side knowledge, Codex Morbus.
add: New Heretic T2 Side knowledge, Rust Sower grenade.
add: New Heretic T3 Side knowledge, Greaves Of The Prophet.
add: New Blade Path Spell, Wolves Among Sheep.
balance: Heretic curses have been removed from the tree and bundled in
the new Knowledge, Codex Morbus.
balance: Blade Path tree has been shuffled a bit, all spells have been
moved up by one tier to make space for the new spell.
removal: Stance Of The Torn Champion has been removed.
/🆑

---------

Co-authored-by: Xander3359 <66163761+Xander3359@users.noreply.github.com>
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
Co-authored-by: carlarctg <53100513+carlarctg@users.noreply.github.com>
Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
2025-03-16 01:53:44 -04:00

128 lines
6.3 KiB
Plaintext

/*
* This test checks that all heretic knowledges that unlocks rituals
* properly consume all used atoms and creates all resulting atoms.
*
* This test ONLY checks knowledges that unlock rituals which consume atoms and produce atoms.
* - Rituals that consume atoms, but do not create any atoms (such as rituals of knowledge) are not tested.
* - Summon rituals sleep after completing as they expect a ghost candidate to fill the summon, so they're skipped.
* - Final rituals results in a bunch of side-effects and vary a good deal so they're skipped explicitly.
* - Sacrifice ritual (Hunt and Sacrifice) requires sacrifice targets, as well as spawning a new z-level, so it's better not to test.
* - Codex Morbus doesn't consume the body that is required in it's ritual.
*/
/datum/unit_test/heretic_rituals
/datum/unit_test/heretic_rituals/Run()
// Gotta create ourselves a rune and a user to start.
var/obj/effect/heretic_rune/big/our_rune = allocate(/obj/effect/heretic_rune/big)
var/mob/living/carbon/human/our_heretic = allocate(/mob/living/carbon/human/consistent)
// -- Note for the human dummy we create:
// The user does not actually NEED a heretic antag datum for the type of rituals we're testing,
// so we don't give them one here. The heretic antag datum has side effects when applied,
// like creating influences and learning the default knowledge types, so better safe than sorry.
// Slap them down somewhere. The "heretic" should be in the middle of the rune, though this doesn't really matter.
our_rune.forceMove(run_loc_floor_bottom_left)
our_heretic.forceMove(locate((run_loc_floor_bottom_left.x + 1), (run_loc_floor_bottom_left.y + 1), run_loc_floor_bottom_left.z))
// Set up the blacklist for types we don't want to test here. See above for reasons.
var/list/blacklist_typecache = typecacheof(list(
/datum/heretic_knowledge/summon,
/datum/heretic_knowledge/ultimate,
/datum/heretic_knowledge/hunt_and_sacrifice,
/datum/heretic_knowledge/codex_morbus,
))
var/list/all_ritual_knowledge = list()
// Now, let's instantiate our all_ritual_knowledge list with knowledge we're gonna test.
for(var/knowledge_type in typesof(/datum/heretic_knowledge))
// Skip blacklisted types
if(is_type_in_typecache(knowledge_type, blacklist_typecache))
continue
var/datum/heretic_knowledge/instantiated_knowledge = new knowledge_type()
// No required atoms = it's not a ritual, delete it and move on
// No resulting atoms = it's not a ritual we test here, delete it and move on
if(!LAZYLEN(instantiated_knowledge.required_atoms) || !LAZYLEN(instantiated_knowledge.result_atoms))
qdel(instantiated_knowledge)
continue
all_ritual_knowledge += instantiated_knowledge
// All the knowledge we want to test is instantiated, let's actually test their rituals now.
for(var/datum/heretic_knowledge/knowledge as anything in all_ritual_knowledge)
// Let's do a dry run of any special checks the knowledge may have
// without any atoms passed at all. This is to ensure that,
// if the ritual requires specific circumstances we can't setup in this test,
// such as freezing temperatures or humans that are augmented on completion,
// that we don't proceede to try to test them (as they'll fail anyways).
if(!knowledge.recipe_snowflake_check(our_heretic, list(), list(), get_turf(our_rune)))
continue
// Okay, so we've got a knowledge by this point we definitely want to test.
// Go though all the atoms it wants for it's ritual and create them on the rune.
var/list/created_atoms = list()
for(var/ritual_item_path in knowledge.required_atoms)
var/amount_to_create = knowledge.required_atoms[ritual_item_path]
if(islist(ritual_item_path))
ritual_item_path = pick(ritual_item_path)
for(var/i in 1 to amount_to_create)
var/obj/item/item = new ritual_item_path(get_turf(our_heretic))
if(isitem(item))
item.item_flags &= ~ABSTRACT
created_atoms += item
// Now, we can ACTUALLY run the ritual. Let's do it.
// Attempt to run the knowledge via the sacrifice rune.
// If do_ritual() returns FALSE with our knowledge, it messed up.
// If do_ritual() returns TRUE, then it was successful.
if(!our_rune.do_ritual(our_heretic, knowledge))
// We failed. The knowledge should have everything to succeed, yet it returned FALSE!
// Clean up the atoms it was meant to consume, so we can keep testing.
for(var/atom/leftover as anything in created_atoms)
created_atoms -= leftover
qdel(leftover)
// Aaand throw a fail.
TEST_FAIL("Heretic rituals: ([knowledge.type]) Despite having all required atoms present, the ritual failed to transmute.")
continue
// Making it here means the ritual was a success.
// Let's check all the atoms nearby to see if we got what we wanted.
var/list/atom/movable/nearby_atoms = range(1, our_heretic)
nearby_atoms -= our_heretic // Our dude is supposed to be there
nearby_atoms -= our_rune // Same with our rune
// Did we get all the results we want?
for(var/result_item_path in knowledge.result_atoms)
var/atom/result = locate(result_item_path) in nearby_atoms
// No, we couldn't find the a resulting atom on the rune. Throw a fail.
if(!result)
TEST_FAIL("Heretic rituals: ([knowledge.type]) Despite successfully completing the ritual, a resulting atom could not be found ([result_item_path])")
continue
// Yes, we got a resulting atom we expected! Remove it from the list and clean up.
nearby_atoms -= result
qdel(result)
// Finally, we checked all of our resulting atoms and cleaned them up.
// The nearby_atoms list should be devoid of any atom/movables now. Let's double-check that.
for(var/atom/thing as anything in nearby_atoms)
if(!ismovable(thing))
continue
if(isitem(thing))
var/obj/item/item = thing
if(item.item_flags & ABSTRACT) //bodyparts and stuff will get registered otherwise
continue
// There are atoms around the rune still, and there shouldn't be.
// All component atoms were consumed, and all resulting atoms were cleaned up.
// This means the ritual may have messed up somewhere. Throw a fail and clean them up so we can keep testing.
TEST_FAIL("Heretic rituals: ([knowledge.type]) After completing the ritual, there were non-result atoms remaining on the rune. ([thing] - [thing.type])")
nearby_atoms -= thing
qdel(thing)
// All done, clean up the knowledge list.
QDEL_LIST(all_ritual_knowledge)