Files
Bubberstation/code/modules/unit_tests/heretic_rituals.dm
T
carlarctgandGitHub 2ab4fa3a92 Heretic Rebalance - Main Knowledge gives free Side points, reduced rune drawing time, Codex Cicatrix is easier and roundstart knowledge (#77939)
## About The Pull Request

Heretic Rebalance

Researching the Main Knowledge paths that unlock Side Paths will grant
one Side Point that can be used only on those side paths. You can still
spend normal knowledge points on them if you wish.

Rune drawing time has been reduced from 30->20 seconds. Codex drawing
time has been reduced from 15->8.

Codex Cicatrix is now a roundstart knowledge, works as an amber focus
when held in-hand and opened, and has had its recipe changed to: 1 of
any non-standard pen (literally anything that isn't the base pen), any
book, and either animal hide OR a corpse, any kind.

Added support for using a list inside ritual requirements and a special
'snowflake check' rituals can utilize.

The first non-path knowledge, the Mansus Hand Mark, has had its cost
reduced from 2->1 points.
## Why It's Good For The Game

Heretic is an extremely top-heavy antagonist that is EXCEEDINGLY weak in
the early-game, free get out of jail card aside, and gets utterly
overwhelmed with options extremely quickly once hopping past the
mid-game hurdle. You're completely starved for knowledge points to the..
point that you feel like you can't blow any on side paths, even though
these are often essential as well!


Once you hop the hurdle - 40 minutes in, usually - you suddenly find
yourself blazing through path after path obtaining a ridiculous amount
of points that you don't know what to do with and unlocking spell after
spell all at once rather than slowly, meaning it becomes extremely hard
to keep focus and actually use these things - attempting to keep 5 new
spells in mind during combat will just cause you to stretch yourself
thin and die.

This PR is meant to address this by giving Heretics a lot more leeway on
the early game so they don't feel nearly as stifled as they are right
now, which will also, ideally, help them unlock singular abilities
earlier on so they can practice with them. **None of these changes are
straight buffs to combat ability, they simply relax the extremely tight
restrictions early-game heretics have.**

> Researching the Main Knowledge paths that unlock Side Paths will grant
one Side Point that can be used only on those side paths. You can still
spend normal knowledge points on them if you wish.

This idea in specific is supported by @MrMelbert - which I'm using as a
request to not instaclose this PR due to the slightly lower than neutral
GBP I have. He supports this specific bit at least and doesn't outright
disagree with me on the rest, as far as I'm aware from my last
conversation with him on the subject a while back. Besides, I have a
refactor on mirrors open!

Meta aside, this bit is meant to combat how claustrophobic early heretic
feels by allowing the guy to pick one of two side paths for free* after
unlocking that path's equivalent of Ash Jaunt, so they have *something*
to use besides their sword and stink hand at the start.

> Rune drawing time has been reduced from 30->20 seconds. Codex drawing
time has been reduced from 15->8.

The absurdly long drawing time is just extremely arduous and
frustrating. It's way too slow but just not enough to let you zone out,
and it has a ridiculously noticeable animation the whole way through
which guarantees you being found out if you're found out midway through.
It makes heretic even SLOWER early on as they need to set up one or
several bases which takes forever.

> Codex Cicatrix is now a roundstart knowledge, works as an amber focus
when held in-hand and opened, and has had its recipe changed to: 1 of
any non-standard pen (literally anything that isn't the base pen), any
book, and either animal hide OR a corpse, any kind.

Quite the buff, but I think all of these are good changes. Codex
Cicatrix being a roundstart change lets one decide - do they want to
rush the book to get multiplied influence strength, or do they want to
get all the influences ASAP? It also lets them set up bases quicker at,
again, the cost of having a blatantly evil item inside the bag.

The Codex recipe was annoyingly complicated, requiring you to run all
around the station in yet another of Heretic's many fetch quests just
for something that used to be part of the default kit, especially with
how annoying getting animal hide can be. Now it's a lot easier to
handle.

The Amber Focus bit is just as a panic option for heretics if they get
caught without one, at least they can use the book, and wielding a book
in combat is awesome.

> The first non-path knowledge, the Mansus Hand Mark, has had its cost
reduced from 2->1 points.

I don't think there ever really was a need to gate this behind two
points, it's the very first unlockable research and it needs you to get
two influences for some reason. The reasoning is probably 'heretic setup
time so they dont start at full strength', which is solid, but is
already well handled enough by their other systems and restrictions as
mentioned in the rest of the PR.

Heretics have been on a constant trend of just.. not doing anything.
Getting caught early and flopping or never managing to do things of
note. They need changes, not because They're UnderPowered And The
Competitive Balance Is Skewed, but because it's simply not that fun to
*be* a heretic with these issues, and not that fun to FIGHT a heretic
that merelay has a stink hand, a blade, two pieces of lint in their
pocket, and a dead rat.

I also think the Ritual of Knowledge should 1. not cost points, and 2.
be split across the 33% and 66% mark and give 2 points, but that's for
another PR.
2023-09-30 13:25:04 -05:00

119 lines
6.0 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.
*/
/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,
))
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)
created_atoms += new ritual_item_path(get_turf(our_heretic))
// 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
// 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)