Feature ASH location_accessible function.

can_adventure can be "trusted"

Maybe we should have a preference to run prepareForAdventure before relay visits
 
Will this properly account for when a relay script tells you if you can adventure there or not?

Quick example, say I have a script that tells me to go to this location for whatever reason, maybe its something I run in gCLI, something I run in a relay script.
It has a bunch of locations, but recommends I visit this area.

Is the relay script supposed to now include a bunch of checks for if that area needs unlocking, because can_adventure can't be trusted?
Given that the script isn't going there, it's the player.
As gausie said, can_adventure() can be trusted: if it returns true, you really can go there without using unavailable (or expensive) resources.
In particular, without spending adventures or Meat to buy things you don't already have.

If a relay script (Guide, say) suggests you go to such-and-such a place that can_adventure() says is available and the player decides to do it in the Relay Browser, the player will have to do those simple things to finish unlocking the area.

If a relay or gCLI script suggests you go such and such a place and the player chooses to go there via automation - GUI or script - prepare_for_adventure will do those simple things for you.

Now, if the script suggests you go somewhere unlocked by an IOTM, can_adventure requires that it be currently unlocked; prepare_for_adventure will not use expensive day passes.
 
Maybe we should have a preference to run prepareForAdventure before relay visits
I like that idea. We have a preference to perform restoration before relay visits.

The thing is, you have to actually "see" a location before you can visit it in the Relay Browser. A lot of prepare_for_adventure is making it possible to "see" the zone. But there are certain zones where we could usefully do something. In particular, GenericRequest -> RequestLogger.registerRequest -> KoLAdventure.prepareToAdventure. (Subtly different than prepareForAdventure. :))

That is the method that uses Cap'm Caronch's chore items before adventuring in the F'cl'e in order to complete his quest, if you have them.

And there is specific code there for one case:

Code:
    if (this.formSource.equals("cobbsknob.php") && this.canAdventure()) {
      this.prepareForAdventure();
    }

Because you actually can see the Throne Room before it is "unlocked". Note that it's not even under a preference.

Probably worthwhile to look again at prepare_for_adventure and see if there are other areas you can see in the browser that could/should be unlocked like that before you go there.
 
It may interest you to know that we have worked really hard to make can_adventure/prepare_for_adventure be "correct".
I've been working on this for almost two months now and KoLAdventureValidationTest has 398 tests in it - out of 3537 tests for the whole project.

I still have a To Do list, but I am steadily working my through it.

For example, I just did a 2-day Hardcore Kingdom of Exploathing run, and we handle that path correctly now - complete with tests. Assuming anybody ever does that path any more.

And I just made prepare_for_adventure talk to the bartender before going to the cellar. There are tests for that, too.

FYI, here is my remaining To Do list (details omitted)

7) Astral
8) Shape of Mole
9) Grimstone
11) Gingerbread City
12) PirateRealm
13) Batfellow Area
14) Spelunky Area
16) Casino
17) Twitch
18) Holidays

KoLCharacter.mysteriousIslandAccessible()
KoLCharacter.desertBeachAccessible()

The Sea:
- A big job to figure out which of the many zones has been unlocked.
- Do we parse the map of the Sea Floor?
Note that we have support for a lot of those, but I want to look more closely, add missing features, and, yes - write lots of tests.

I'm hoping to finish in October.
 
I think it's fantastic work and is very worthwhile.

I've started on canAdventure support for clan basement zones... quite a new frontier in terms of mafia support.
 
I found a bug:
If you have a Cobb's Knob Menagerie key in Inventory, can_adventure returns "true" for the Menagerie even if you can't access it (like in post-CS).
 
There is no code to support CS or post-CS.

To be honest, I have never tried that path - and have zero desire to ever do so, even to check things out (for science!).

How can one tell if you are "post-CS"? How is it possible to get the Menagerie key (from the Laboratory) and not have access to it?
 
you can fight the Knob Goblin Very Mad Scientist without having access to anything in Cobb Knob (well, outskirts in CS. No clue if the key drops if you don't even have access to that).

I am sorry, when I reported this I assumed it is a bug because it is called "can_adventure" - and it can't adventure in the Menagerie in this path even with the key.
If that is out of scope for it, okay. Disregard the report then.
 
you can fight the Knob Goblin Very Mad Scientist without having access to anything in Cobb Knob (well, outskirts in CS. No clue if the key drops if you don't even have access to that).

I am sorry, when I reported this I assumed it is a bug because it is called "can_adventure" - and it can't adventure in the Menagerie in this path even with the key.
If that is out of scope for it, okay. Disregard the report then.
Don't worry - it is not out of scope. It really is a bug.

I suppose you have a laboratory key, too, but the interior of the Knob is unavailable because you have not even started the Knob Goblin "Quest"?

In which case, DURING the CS run can_adventure() SHOULD return true for various locations that are normally accessible via quest, progress, but in aftercore, they suddenly are unavailable because you didn't actually do the quests? Did you try can_adventure during your run?

I recently did a KoE run (for the first time in years) to make sure in-run and aftercore were accurate there.
I imagine such should be done (by someone) to support CS - but it will not be me, I expect. Reading the Wiki page makes me shudder.
 
No "inside" Cobb-Location is available in CS - you only have access to the outskirts, the level 5 quest just doesn't exist, never giving you the encryption key.
I used the locket to get a Very Mad Scientist because I needed a scrumptious reagent because I was stupid before, and this seemed the easiest way - and they key just dropped. Never got a laboratory key, but also didn't try if it was possible to get, or if the location was thought to be available.
The key dropping by itself is already a bit strange, honestly, but I assume it is just, you know, a game-code age thing of a niche that just is.

ETA: I assume this is a rather niche case because, honestly, killing a Very Mad Scientist for scrumptious reagent in CS is probably dumb anyway, and having mafia think the menagerie is available is probably not really a problem too in most cases.
(I noticed because garbo tried to adventure there for mayfly-runaways)
 
Last edited:
On a different topic, I'm wondering what to do about mining (in disguise) -> mining.php.

Those are "adventures".
They each require an outfit.
And KoLmafia has no support for Automating them.

Yes, we recognize when you go there and log them appropriately in your session log and so on, but AdventureRequest.run():

Code:
    if (this.formSource.equals("mining.php")) {
      KoLmafia.updateDisplay(MafiaState.ERROR, "Automated mining is not currently implemented.");
      return;
    }

can_adventure() COULD detect if you have access - and even if you have the appropriate outfit.
prepare_for_adventure() COULD put on the outfit.

But actually trying to run the adventure will fail, as above.

Thoughts?
 
I think it's probably related to work going on here for can_adventure, I've been having questM20Necklace and questM21Dance get set to finished when refreshing quests in day 2 in post community service aftercore (looks like after logging out and back in) so mafia is returning I can adventure in the spookyraven zones I can't access:

Code:
> set questM20Necklace=unstarted

questM20Necklace => unstarted
Preference questM20Necklace changed from finished to unstarted

> set questM21Dance=unstarted

questM21Dance => unstarted
Preference questM21Dance changed from finished to unstarted

> debug on

> ashq visit_url("questlog.php")

Preference questM20Necklace changed from unstarted to started
Preference questM21Dance changed from unstarted to finished
Preference questM20Necklace changed from started to finished

> debug off

I've attached the debug log.
 

Attachments

Last edited:
I cannot reproduce it with your HTML. I wrote a test based on exactly what I saw in the questlog.
- We do not have data in questslog.txt for detecting the start of the Armor's quest
- For some reason, it did not match Melvign's quest
- For every other quest which was there, it went from "unstarted" to "started"
- For a few quests I tried - including questM21Dance - they remained "unstarted"

Looking at all the places where SPOOKYRAVEN_DANCE gets set to "finished" when parsing the questlog, it is only if SPOOKYRAVEN_BABIES or MANOR quests are started.

Code:
    @Test
    public void canReadQuestLog() {
      var builder = new FakeHttpClientBuilder();
      var client = builder.client;
      var cleanups =
          new Cleanups(
              withHttpClientBuilder(builder),
              withQuestProgress(Quest.MYST, QuestDatabase.UNSTARTED),
              withQuestProgress(Quest.ARTIST, QuestDatabase.UNSTARTED),
              withQuestProgress(Quest.MEATSMITH, QuestDatabase.UNSTARTED),
              withQuestProgress(Quest.DOC, QuestDatabase.UNSTARTED),
              withQuestProgress(Quest.ARMORER, QuestDatabase.UNSTARTED),
              withQuestProgress(Quest.SPOOKYRAVEN_NECKLACE, QuestDatabase.UNSTARTED),
              withQuestProgress(Quest.SEA_OLD_GUY, QuestDatabase.UNSTARTED),
              withQuestProgress(Quest.SHIRT, QuestDatabase.UNSTARTED),
              withQuestProgress(Quest.GUZZLR, QuestDatabase.UNSTARTED),
              // Things that were NOT mentioned in the Quest Log
              withQuestProgress(Quest.SPOOKYRAVEN_DANCE, QuestDatabase.UNSTARTED),
              withQuestProgress(Quest.SPOOKYRAVEN_BABIES, QuestDatabase.UNSTARTED), 
              withQuestProgress(Quest.MANOR, QuestDatabase.UNSTARTED));
      try (cleanups) {
        client.addResponse(200, html("request/test_questlog_post_cs.html"));
        GenericRequest request = new GenericRequest("questlog.php");
        request.run();
        assertThat(Quest.MYST, isStarted());
        assertThat(Quest.ARTIST, isStarted());
        assertThat(Quest.MEATSMITH, isStarted());
        assertThat(Quest.DOC, isStarted());
        // We don't actually detect this one.
        // assertThat(Quest.ARMORER, isStarted());
        assertThat(Quest.SPOOKYRAVEN_NECKLACE, isStarted());
        assertThat(Quest.SEA_OLD_GUY, isStarted());
        // Doesn't match, for some reason
        // assertThat(Quest.SHIRT, isStarted());
        assertThat(Quest.GUZZLR, isStarted());

        // Things that were NOT mentioned in the Quest Log
        assertThat(Quest.SPOOKYRAVEN_DANCE, isUnstarted());
        assertThat(Quest.SPOOKYRAVEN_BABIES, isUnstarted());
        assertThat(Quest.MANOR, isUnstarted());
      }
    }
 
hm questL11Manor is step1 for me, questM17Babies is unstarted. I'll search my logs and see when it was set to step1, because that's not correct for after cs
 
Okay it looks like it's related to acquiring a scroll of ancient forbidden unspeakable evil or attempting to summon a demon when the summoning chamber is unavailable maybe:

Code:
Use 1 disintegrating quill pen + 1 inkwell + 1 tattered scrap of paper
You acquire an item: scroll of ancient forbidden unspeakable evil
Preference questL11Manor changed from unstarted to step1
Preference lastSecondFloorUnlock changed from 836 to 837

summon Ak'gyxoth
[no error & no effect gained here]

I'll fix my logout script to not do that but there's probably something weird there.
 
Yeah, that's definitely a bug. Visiting the Manor basement level is sufficient for us to mark the Manor quest as being started.
We should verify that you actually managed to visit the basement.
 
SummoningChamberRequest.run():
Code:
    // Go to the Summoning Chamber
    RequestThread.postRequest(new PlaceRequest("manor4", "manor4_chamber", true));

That was without even checking you have access to it. We could/should cut off requests here.
Also, the summon demon command could give you a friendly message right away if it is not accessable.

QuestManager, if you get a response from place.php?whichplace=manor4:

Code:
            if (responseText.contains("sr_brickhole.gif")) {
              QuestDatabase.setQuestIfBetter(Quest.MANOR, "step3");
            } else {
              QuestDatabase.setQuestIfBetter(Quest.MANOR, "step1");
            }

It assumes it succeeded. This is where your quest step was set.

What is the responseText from attempting to go to the Summoning Chamber when it is not open?
 
SummoningChamberRequest.run():
Code:
    // Go to the Summoning Chamber
    RequestThread.postRequest(new PlaceRequest("manor4", "manor4_chamber", true));

That was without even checking you have access to it. We could/should cut off requests here.
Also, the summon demon command could give you a friendly message right away if it is not accessable.

QuestManager, if you get a response from place.php?whichplace=manor4:

Code:
            if (responseText.contains("sr_brickhole.gif")) {
              QuestDatabase.setQuestIfBetter(Quest.MANOR, "step3");
            } else {
              QuestDatabase.setQuestIfBetter(Quest.MANOR, "step1");
            }

It assumes it succeeded. This is where your quest step was set.

What is the responseText from attempting to go to the Summoning Chamber when it is not open?

Code:
<html><head><link rel="stylesheet" type="text/css" href="https://d2uyhvukfffg5a.cloudfront.net/styles.css"></head><body><center><table  width=95%  cellspacing=0 cellpadding=0><tr><td style="color: white;" align=center bgcolor=blue><b>Uh Oh!</b></td></tr><tr><td style="padding: 5px; border: 1px solid blue;"><center><table><tr><td>You shouldn't be down here yet.  I mean here.  Wherever here is.<p><center><A href=main.php>Back to the Main Map</a></center></td></tr></table></center></td></tr><tr><td height=4></td></tr></table></body></html>
 
Today can_adventure($location[The Laugh Floor]) returned true although I had not done the intro NC. I had completed the friar's quest. So when garbo attempted to adventure there, it failed as it could not. When I completed the intro NC, garbo could adventure there. I'm not sure the method garbo uses to adventure in locations. Believe this is important info, will ask them.
 
Back
Top