New Content New Shadow Rift NCs, buffs, and buff extension

beldur

New member
Very much adjacent to the March IOTM (but accessible without it), a new free (does not take a turn) NC has been added to Shadow Rifts. It is choice 1499.
Screenshot_2023-03-03_at_2.11.14_PM.png
There's a few things of note about this choice. It occurs every 11 adventures in a Shadow Rift. The first and fifth options (and simply refreshing the page) give you a "new" version of this adventure, and every time it loads, it has semi randomized text and a random image from one of the monsters in shadow rifts. Option 6 exits the choice. It can be forced by using something like sneakisol or parka spikes, which resets the counter towards the next occurrence.

Now where things get weird: options 2-4's outcomes are semi-randomized on page load as well, and based on keywords in the options' text they will have different outcomes. Here's an excerpt of a writeup from Kataran:
The result of choices A, B and C depend on the theme of the button
Fire: 90-100 Muscle Substats
Math: 90-100 Mysticality Substats
Water: 90-100 Moxie Substats
Time: Effect extension (+3 turns to 3 random effects)
Blood: Shadow's Heart Maximum HP +300% /desc_effect.php?whicheffect=ae985c01dcfdcbdcdd0c324716ff2c6d
Cold: Shadow's Chill Maximum MP +300% /desc_effect.php?whicheffect=7164c53309fdee5c3e7367e22d0ba9be
Ghost: Shadow's Thickness Superhuman Spooky Resistance (+5) Superhuman Hot Resistance (+5) Superhuman Sleaze Resistance (+5) /desc_effect.php?whicheffect=cec0a45b03817e4e0b9a4fa6833c556a

And some spading from Nasurte and Tobyous turned up these descriptors in options 2-4:
Fire: steaming, scalded, scalding, flame-choked, blazing, ember-lit, scorching, blistering, sizzling, charred, white-hot
Math: Pythagorean, exponential, fractional, parabolic, sinusoidal, monomial, boolean, integer, hyperbolic, Riemannian, irrational, geometric, fractal, ordinal, logarithmic, angular, Cartesian, prime, multiplicative, Fibonacci, self-referential, trigonometric, cubic, vector
Water: humid, dripping, water-logged, runny, soaked, drowning, watery, aqueous, sodden, moist, foggy, damp
Time: rickety, ramshackle, old, broken-down, ancient, derelict, shabby, crumbling, ruined, decaying, antique, dilapidated, unkempt
Blood: bloodstained, vein-shot, blood-soaked, blood-drenched, crimson, pulsing, sanguine, veiny, bloody, hematic, bleeding
Cold: frost-rimed, icy, iced-over, frozen, freezing, frosty, spectral, cold-numbed, snow-covered, chilly, hyperborean, wintry, arctic, frigid
Ghost: ghostly, insubstantial, diaphanous, translucent, see-through, gossamer, half-there, nearly invisible, wispy, ephemeral

It's worth noting here that there's two interactions with March's IOTM. Firstly, the new IOTM can cause a boss monster to overwrite this choice adventure, operating on the same counter and appearing if sneakisol et al. are used. Secondly, the new IOTM can replace options 2-4 with a new option type that drops a relevant quest item. I'm pretty sure these aren't perfectly spaded interactions yet, and would probably be covered in a writeup for the new IOTM.

Attached are a few examples of the choice adventure's html.
 

Attachments

  • test_adventure_shadow_rift_a_labyrinth_of_shadows.txt
    7.7 KB · Views: 0
  • test_adventure_shadow_rift_a_labyrinth_of_shadows2.txt
    8.3 KB · Views: 0
  • test_adventure_shadow_rift_a_labyrinth_of_shadows3.txt
    8.3 KB · Views: 1
  • test_adventure_shadow_rift_a_labyrinth_of_shadows4.txt
    8.3 KB · Views: 0
  • test_adventure_shadow_rift_a_labyrinth_of_shadows5.txt
    8.3 KB · Views: 1
Last edited:

Linknoid

Member
Just want to point out that the listed adjectives are not complete.

I discovered so far:

Fire: singed
Math: algebraic
Ghost: transparent

I imagine there are more.
 

Veracity

Developer
Staff member
Thanks!

I have a PR which uses the adjectives. By all means, continue telling us ones we are missing.
 

Linknoid

Member
I wrote a little script to collect the rest. It found the following that were missing, and then it went 100 rounds without finding anything new:

"burnt", "decimal", "drowned", "wet", "seared", "drenched", "periodic", "quadratic", "Euclidean", "burning",
"underwater", "binomial", "scorched"

Code:
string[] adjectives = 
{
"steaming", "scalded", "scalding", "flame-choked", "blazing", "ember-lit", "scorching", "blistering", "sizzling", "charred", "white-hot", "singed",
"Pythagorean", "exponential", "fractional", "parabolic", "sinusoidal", "monomial", "boolean", "integer", "hyperbolic", "Riemannian", "irrational", "geometric", "fractal", "ordinal", "logarithmic", "angular", "Cartesian", "prime", "multiplicative", "Fibonacci", "self-referential", "trigonometric", "cubic", "vector", "algebraic",
"humid", "dripping", "water-logged", "runny", "soaked", "drowning", "watery", "aqueous", "sodden", "moist", "foggy", "damp",
"rickety", "ramshackle", "old", "broken-down", "ancient", "derelict", "shabby", "crumbling", "ruined", "decaying", "antique", "dilapidated", "unkempt",
"bloodstained", "vein-shot", "blood-soaked", "blood-drenched", "crimson", "pulsing", "sanguine", "veiny", "bloody", "hematic", "bleeding",
"frost-rimed", "icy", "iced-over", "frozen", "freezing", "frosty", "spectral", "cold-numbed", "snow-covered", "chilly", "hyperborean", "wintry", "arctic", "frigid",
"ghostly", "insubstantial", "diaphanous", "translucent", "see-through", "gossamer", "half-there", "nearly invisible", "wispy", "ephemeral", "transparent",

// The following were missing:
"burnt", "decimal", "drowned", "wet", "seared", "drenched", "periodic", "quadratic", "Euclidean", "burning",
"underwater", "binomial", "scorched"
};

string result = "";

void TryDump(string choice)
{
    boolean found = false;
    foreach ix, value in adjectives
    {
        if (choice.contains_text(value))
        {
            found = true;
            break;
        }
    }
    if (!found)
    {
        result += "\r\n" + choice;
        print(choice);
    }
}

void Dump()
{
    foreach key, value in available_choice_options()
    {
        if (key == 2 || key == 3 || key == 4)
            TryDump(value);
    }
}

void main(int count)
{
    for (int i = 0; i < count; i++)
    {
        Dump();
        run_choice(1);
    }
    print(result);
}
 

Veracity

Developer
Staff member
I wrote a little script to collect the rest. It found the following that were missing, and then it went 100 rounds without finding anything new:

"burnt", "decimal", "drowned", "wet", "seared", "drenched", "periodic", "quadratic", "Euclidean", "burning",
"underwater", "binomial", "scorched"
Thanks!

r27260 has some support for this choice adventure.

In particular, it gives choice spoilers in the Relay Browser for each of the variable options.

More can/should/will be done, by and by

1) The spoilers include both the stats or effect AND the artifact that would be found there, if you accepted that quest from Rufus.
We don't track Rufus's quests, yet, but we will. Once we have that, a spoiler should be either the non-artifact, or the specific artifact Rufus asked you to get.
2) We should have three properties with the current "theme" of the variable buttons, for use by scripts. Or one property with three comma separated themes, say.
 

Veracity

Developer
Staff member
Revision r27267 adjusts our choice spoiler for the Shadow Labyrinth to show only the artifact if you are actually on a quest to retrieve the specific artifact that a choice will give you.

Code:
[1377] Shadow Rift (The Misspelled Cemetary)
Encounter: A Labyrinth of Shadows

> get rufusQuestTarget

shadow heart

> choice

choice 1: Run forward (Randomize themes)
choice 2: Swim to the bloodstained road (shadow heart)
choice 3: Jump towards the icy opening (30 Shadow's Chill: Maximum MP +300%)
choice 4: Select the crumbling portal (+3 turns to 3 random effects)
choice 5: Turn in a circle (Randomize themes)
choice 6: Withdraw in fear (Leave with nothing)

> ash available_choice_options(true)

Returned: aggregate string [int]
1 => Run forward (Randomize themes)
2 => Swim to the bloodstained road (shadow heart)
3 => Jump towards the icy opening (30 Shadow's Chill: Maximum MP +300%)
4 => Select the crumbling portal (+3 turns to 3 random effects)
5 => Turn in a circle (Randomize themes)
6 => Withdraw in fear (Leave with nothing)

The spoilers appear in the Relay Browser, in the "choice" command, and are available to scripts.

Depending on how scripts might want to handle this choice, we could still, say, make a property.

shadowLabyrinthThemes = "blood,cold,time"

for the above instance.

What do you think, as scripters? What additional support, if any, would make your life easier?
 

Malibu Stacey

Active member
What do you think, as scripters? What additional support, if any, would make your life easier?
Being able to set a target property similarly to how louvreDesiredGoal would be nice but TBH available_choice_options() already does all the stuff you need to handle getting the buff or item you want/need for the quest since you can just submit option 1 or 5 until the one you're looking for appears.
 

Malibu Stacey

Active member
One thing I would request is a tracking property for when the Non-combat/Boss is scheduled similarly to how encountersUntilNEPChoice works for The Neverending Party.
cannonfire said:
fwiw
it's not turnsinzone % 11 == 0 precisely, it's (turnsinzone - lastnc) >= 11
which may help your intuitions
(this is how all scheduled NC forcing works)
also, the bosses are NCs.
and
the lodestone is a superlikely
not an NC
when asked if the "Like a Loded Stone" encounter resets the schedule too.

Also
because the NC does not advance turnsinzone
but bosses do
Presumably because the NC is turn free while the boss is a resolved combat.
 

ckb

Minion
Staff member
Being able to set a target property similarly to how louvreDesiredGoal would be nice but TBH available_choice_options() already does all the stuff you need to handle getting the buff or item you want/need for the quest since you can just submit option 1 or 5 until the one you're looking for appears.
I would like to second this request - it would be great to be able to set "choiceAdventure1499" to something that would automatically get the artifact (or even the desired buff).
As it is now, the only way to script this is to process available_choice_options() after a visit_url()
If you are adventuring through the Shadow Rifts with adventure() or adv1(), Mafia will abort when trying to process choiceAdventure1499.

Edit: maybe this is possible to script with a choiceAdventureScript... but also tricky given the nature of how this choice works.
 
Last edited:
As it is now, the only way to script this is to process available_choice_options() after a visit_url()
Thirding the request for a shadowLabyrinthDesiredGoal or similarly named preference, but also for future readers: you should specifically parse available_choice_options(true) so you can access mafia spoilertext
 

Malibu Stacey

Active member
If you are adventuring through the Shadow Rifts with adventure() or adv1(), Mafia will abort when trying to process choiceAdventure1499.

Edit: maybe this is possible to script with a choiceAdventureScript... but also tricky given the nature of how this choice works.
I had a choiceAdventureScript calling available_choice_options(true) and parsing the strings (and rerolling when the quest item option wasn't there. Also what even is the point of this non-combat anyway, just list all the options instead of this charade of rerolling until what you want shows up) but it is also now aborting when trying to process choiceAdventure1499.
 
Last edited:

Veracity

Developer
Staff member
it is also now aborting when trying to process choiceAdventure1499.
What do you mean? It is not calling your choiceAdventureScript?
Oh, I see. That is "Calling Rufus Back". Yeah. That is not configurable.
It should take option 1 "Yeah, I got it" if questRufus is "step1" or option 6 "hang up" otherwise.
But, really - it SHOULD call your choiceAdventureScript.

I'm thinking we could have a configurable choice option in "shadowLabyrinthGoal" with the following choices:

show in browser
90-100 Muscle substats
90-100 Mysticality substats
90-100 Moxie substats
+3 turns to 3 random effects
Maximum HP +300%
Maximum MP +300%
+5 Spooky, Hot, Sleaze resistance

And when you automate and encounter this adventure, it rerolls until if gets the desired result

If questRufus is started and rufusQuestType is artifact, that will ignore the setting (other than "show in browser") and it will go for the artifact in rufusQuestTarget
 

ckb

Minion
Staff member
FWIW I successfully automated the artifact quest with a choiceAdventureScript for choiceAdventure1499, using
Code:
foreach ii,ss in available_choice_options(true) {
    if (contains_text(ss,get_property("rufusQuestTarget"))) { nn = ii; }
}
run_choice(nn)
 

Malibu Stacey

Active member
What do you mean? It is not calling your choiceAdventureScript?
Oh, I see. That is "Calling Rufus Back". Yeah. That is not configurable.
choiceAdventure1499 is "A Labyrinth of Shadows" as in the Shadow Rift scheduled non-combat -> https://kol.coldfront.net/thekolwiki/index.php/A_Labyrinth_of_Shadows

choiceAdventure1498 is "Calling Rufus Back".

And yes it now aborts my choiceAdventureScript.

FWIW I successfully automated the artifact quest with a choiceAdventureScript for choiceAdventure1499, using
Code:
foreach ii,ss in available_choice_options(true) {
    if (contains_text(ss,get_property("rufusQuestTarget"))) { nn = ii; }
}
run_choice(nn)
I have effectively the same assuming you're initialising nn to 1 or 5 so it randomises the choices if the choice we're looking for isn't there. And it stopped working yesterday after being fine for at least 2 or 3 days.
 

Veracity

Developer
Staff member
And yes it now aborts my choiceAdventureScript.
Huh.

Code:
      if (ChoiceManager.invokeChoiceAdventureScript(choice, responseText)) {
        if (FightRequest.choiceFollowsFight) {
          // The choice redirected to a fight, which was immediately lost,
          // but which leads to another choice.
          // Let the caller automate that one, if desired.
          return;
        }

        if (!ChoiceManager.handlingChoice) {
          // The choiceAdventureScript processed this choice.
          return;
        }

        // We are still handling a choice. Maybe it is a different one.
        if (ChoiceManager.lastResponseText != null
            && choice != ChoiceUtilities.extractChoice(ChoiceManager.lastResponseText)) {
          responseText = ChoiceManager.lastResponseText;
          continue;
        }
      }

      // Either no choiceAdventure script or it left us in the same choice.
      if (!ChoiceManager.automateChoice(choice, request, stepCount)) {
        return;
      }

As coded, a choiceAdventureScript is expected to handle a single step of a choice chain.
If it chooses not to handle a particular choice, it returns.

This might be the first example of a choice that, when you submit a choice option, leaves you in the "same" choice.
I wonder how we can distinguish between the script not handling a choice and handling the step but remaining in the choice?

I think the script has to follow this choice chain until it is in a different choice - or is no longer in a choice.

I have effectively the same assuming you're initialising nn to 1 or 5 so it randomises the choices if the choice we're looking for isn't there. And it stopped working yesterday after being fine for at least 2 or 3 days.

I suspect you lucked out and the desired option was in the first response.
 

heeheehee

Developer
Staff member
This might be the first example of a choice that, when you submit a choice option, leaves you in the "same" choice.
Doesn't Hunt the Wumpus do the same?

(I thought Violet Fog did too, but apparently those are all different choices, just with the same name.)
 

ckb

Minion
Staff member
My choiceAdventureStript worked just fine today for A Labyrinth of Shadows

For reference, my script is this:
Code:
void main(int choice, string page) {
    print("In choiceAdventure"+choice,"blue");
    switch (choice) {
        case 1499: //A Labyrinth of Shadows
        if (get_property("rufusQuestType")=="artifact") {
            int xx = 1;
            int nn = 1;
            while (nn==1) {
                foreach ii,ss in available_choice_options(true) {
                    if (contains_text(ss,get_property("rufusQuestTarget"))) { nn = ii; }
                }
                run_choice(nn);
                xx += 1;
                if (xx>11) { abort("too many choices"); }
            }
        }
        break;
    }
    print("ckbchoiceAdventure DONE","purple");
}

And the results were:
Code:
[57] Shadow Rift (The Misspelled Cemetary)
Preference lastEncounter changed from shadow tree to A Labyrinth of Shadows
Encounter: A Labyrinth of Shadows
In choiceAdventure1499
Submitting option 1 for choice 1499
Encounter: A Labyrinth of Shadows
Submitting option 1 for choice 1499
Encounter: A Labyrinth of Shadows
Submitting option 1 for choice 1499
Encounter: A Labyrinth of Shadows
Submitting option 1 for choice 1499
Encounter: A Labyrinth of Shadows
Submitting option 1 for choice 1499
Encounter: A Labyrinth of Shadows
Submitting option 3 for choice 1499
You acquire an item: shadow lighter
Preference questRufus changed from started to step1
ckbchoiceAdventure DONE
 

Veracity

Developer
Staff member
Yeah. Your choiceAdventureScript loops, submitting choice options, until it gets what it wants.

By the way - I have a PR up for review that gave me these results with no choiceAdventureScript:

Code:
Request 11 of 20 (Shadow Rift: Shadow Rift (The Nearby Plains)) in progress...

[1515] Shadow Rift (The Nearby Plains)
Encounter: A Labyrinth of Shadows
Encounter: A Labyrinth of Shadows
Encounter: A Labyrinth of Shadows
You acquire an effect: Shadow's Heart (30)

Conditions satisfied after 11 adventures.

Configured to get me "Maximum HP +300%". No Rufus Quest active.
Adventure via GUI for 20 turns in "Shadow Rift (The Nearby Plains)" with goal of "1 choiceadv"

Code:
Request 12 of 20 (Shadow Rift: Shadow Rift (The Misspelled Cemetary)) in progress...

[1526] Shadow Rift (The Misspelled Cemetary)
Encounter: A Labyrinth of Shadows
Encounter: A Labyrinth of Shadows
You acquire an item: shadow wave

Conditions satisfied after 12 adventures.

Configured to get me "Maximum HP +300%" - but Rufus wants a shadow wave.
Adventure via GUI for 20 turns in "Shadow Rift (The Misspelled Cemetery)" with goal of "1 choiceadv"
 
Top