Bug - Fixed Sometimes unable to buy limited items from Underground Fireworks Shop

Autoscend often takes the +combat hat because it's usually pretty easy to get -combat to the softcap, while +combat is hard to come by. If it believes you can get 25% noncombat without the hats, then it will usually get the +combat hat. (Also, reporting issues with it should be done in the ASS discord rather than here unless you've been told your issue is with Mafia in particular.)

In other news, autoscend may soon not have this problem anymore, assuming my PR to use visit_url instead of retrieve_item is accepted. This only resolves issues seen with autoscend in particular, and only if the problem has something to do with using retrieve_item (my ~20 consistent failures before changes and ~20 consistent successes after changes say it does, but this may not be the only reason people encounter this issue).
 
Last edited:

Veracity

Developer
Staff member
…. my PR to use visit_url instead of retrieve_item is accepted. This only resolves issues seen with autoscend in particular, and only if the problem has something to do with using retrieve_item (my ~20 consistent failures before changes and ~20 consistent successes after changes say it does, but this may not be the only reason people encounter this issue).
Ooh! Aah! You have “consistent” failures!

Unless you are using that word in a non-standard way, that means it is reproducible for you.

Please share how to “consistently” reproduce it, so that a KoLmafia dev can fix it, since none of us has even seen the issue, much less been able to reproduce it.

Thanks for helping us fix it for everyone.
 
Thank you for responding to my post as though I was accusing you of something, while completely ignoring the guy who gave you some great details in November. I explicitly mentioned that I was aware it may not be the /only/ reason it fails, but it at the very least solved the reason it fails for /me/ (and at least one other person, who suggested the fix in the first place).

You want the reproduction steps? Install autoscend. Begin any hardcore standard ascension, any class. Run autoscend. Fail to purchase the hat. You want more than that? The aforementioned post from November combined with this indicates that a good place to check might be whether mafia is refusing to even attempt to purchase one because it believes there are none available.
 

Veracity

Developer
Staff member
You want the reproduction steps? Install autoscend. Begin any hardcore standard ascension, any class. Run autoscend.
That's a non-starter.

In any case, that is nothing close to complete or even necessary.

Are you required to start in a clan with the fireworks shop?
Does the script know that you did so?
If not, does it change clans to a clan with a fireworks shop?
Did you do anything at all after ascending before running the script?

I already studied and was unable to reproduce the situation using the "great details" earlier supplied.
I was honestly excited that, perhaps, you had come up with something reproducible (as opposed to "doesn't always happen" from the OP).
Instead, you chose to take offense where none was intended.

You've done this before. I baleeted you. After a year of silence, I relented.
And here you are again, the same as ever. Sheesh.

I'll let somebody else look at this again, if they are interested.

Perhaps if somebody comes up with a way to reproduce this using retrieve_item() that does not require running a huge complicated script that does a whole bunch of unwanted shit - instead, say, doing such-and-such and then simply typing "acquire xxx" and having it fail - somebody else will feel motivated to look into it some more.

Good day.
 

fronobulax

Developer
Staff member
Thank you for responding to my post as though I was accusing you of something, while completely ignoring the guy who gave you some great details in November. I explicitly mentioned that I was aware it may not be the /only/ reason it fails, but it at the very least solved the reason it fails for /me/ (and at least one other person, who suggested the fix in the first place).

You want the reproduction steps? Install autoscend. Begin any hardcore standard ascension, any class. Run autoscend. Fail to purchase the hat. You want more than that? The aforementioned post from November combined with this indicates that a good place to check might be whether mafia is refusing to even attempt to purchase one because it believes there are none available.
Your attitude is somewhat disturbing. Perhaps I am reading things you did not intend? However, pretend I am actually then idiot you might think the devs are. Tell me, in simple steps, how to reproduce this? If the first step is to download and run autoscend then understand that those are not sufficient instructions. Do I use the autoscend defaults? What class? What path? What skills should be permed? I ask because autoascend was not particularly good at auto ascending for me so I fully expect there are things the autoscend devs expect that I am not complying with. If I can only reproduce this in the beginning of an ascension then it is less likely to get fixed if there are a couple of days required to ascend again before anyone knows the fix worked.

Realistically, if you want this fixed you need to distill it down to a set of preconditions and commands than anyone can confirm they meet and then run, without introducing a "third-party" script. Going back to the presumption that I am an Idiot, I cannot figure out what those steps are. If you can then tell us and there's a chance someone will look at this. Better yet maybe someone else will submit a PR.
 

MCroft

Developer
Staff member
I have one character that I run autoscend with frequently. He’s currently in a HC Ed ascension. What would I look for to see this error? Is BAFH going to be a clan that has this problem?
 

Veracity

Developer
Staff member
If I can only reproduce this in the beginning of an ascension then it is less likely to get fixed if there are a couple of days required to ascend again before anyone knows the fix worked.
That could be a key detail, not previously mentioned.

We know that you have to actually visit a fireworks shop - in any clan - to "unlock" it before you can actually buy something. That "unlocks" it for any clan with the shop for the rest of the day.

That is a "_" property, so we reset it on ascension. Does KoL require you to visit again after you ascend?
If so, do we re-visit your clan - or at least the fireworks shop - when you do so?
If not, that property should persist across ascensions but not rollover.
We have a mechanism for either case.

If KoL itself requires you to do the "daily unlock" again after ascending, if your clan has a fireworks shop, we need to visit it upon ascension.
If KoL's "daily unlock" really is "rollover only", then we need a property on Preferences.onlyResetsOnRollover.

I'll be ascending later today. I'll try an experiment:

- Put "fireworksShop" (no "_") on "resetPerRollover".
- Ascend with that set to true
- In the same session, see if I can "acquire" an item from the fireworks shop.

If so, KoL's "daily unlock" persists across ascension.
If not, it should remain a "_" setting and we need to revisit the fireworks shop after ascending.
 
Your attitude is somewhat disturbing. Perhaps I am reading things you did not intend? However, pretend I am actually then idiot you might think the devs are. Tell me, in simple steps, how to reproduce this? If the first step is to download and run autoscend then understand that those are not sufficient instructions. Do I use the autoscend defaults? What class? What path? What skills should be permed? I ask because autoascend was not particularly good at auto ascending for me so I fully expect there are things the autoscend devs expect that I am not complying with. If I can only reproduce this in the beginning of an ascension then it is less likely to get fixed if there are a couple of days required to ascend again before anyone knows the fix worked.

Realistically, if you want this fixed you need to distill it down to a set of preconditions and commands than anyone can confirm they meet and then run, without introducing a "third-party" script. Going back to the presumption that I am an Idiot, I cannot figure out what those steps are. If you can then tell us and there's a chance someone will look at this. Better yet maybe someone else will submit a PR.
My post was intended solely to help the person immediately prior who appeared to be having exactly the same issue in exactly the same manner. I deemed the particular way I am fixing it (in autoscend) to be highly unlikely to be an acceptable fix for mafia itself, since it is bypassing all manner of checks and whatever that mafia would normally perform on the process - not to mention I'd have no idea where to even put the code in mafia, while autoscend already has a section specifically for obtaining the fireworks shop hats. I do not particularly 'want this fixed' anymore beyond that it would probably be nice for whatever small amount of people are encountering it and have said nothing to anyone, and I had already resigned myself to it being not interesting/impactful enough for anyone with actual insight into mafia to care about. That, and Veracity had already gone off on someone already for simply mentioning ASS.

That said, here are the additional details I am willing to give, as I am not invested enough to try and learn enough ash scripting to make a pared-down version. If someone wants to provide a premade script that does nothing but attempt to visit the fireworks shop and buy a hat, I might try running it and see if the results are the same.

While it is true that autoscend does not function in exactly the same manner for every account, the logic surrounding the fireworks hats is fairly simple. If you are in a path where the shop is accessible (not KoE) and where gear gives you buffs (not Gelatinous Noob, not TCRS), and you have access to a fireworks shop (have a VIP key and are in a clan with the shop and _fireworksShop is True), and you have not already bought a hat, and you have enough meat to buy a hat, it will attempt to buy one near the start of the day. (There is some additional logic on when this happens such that it does not occur at the very start of the first day when you have no meat - I am not going to attempt to parse through that to figure out what.) It will buy the porkpie if it thinks you can't reach 25 -combat. Otherwise, it will buy the sombrero if it thinks you can't reach 25 +combat. Otherwise, it will buy the fedora as long as your current ML is lower than the safety cap you have set (this is commented as being a placeholder check, and I have never had it attempt to buy the fedora.)

It attempts to do this at/near the start of each day, and in my experience was failing every time, including for the first attempt of a life where I had just finished up an ascension and started a new one. The changes I made left in the original retrieve_item() attempt (since it does work for some proportion of users, and there's no sense skipping the preferred method unconditionally), and only moves on to using visit_url() if that fails.

My original attempts to resolve the issue included putting a visit_url() to the fireworks shop in my login script (no change), and putting the same in the autoscend logic immediately before it attempts to retrieve a hat (no change).

I have not touched any of autoscend's settings, so any variations in its behavior are purely based on what my account has access to - therefore, here is my account snapshot: https://api.aventuristo.net/av-snapshot?u=Laserrobotics . Note that this is well beyond the rather basic requirements autoscend has to function in a reasonable manner, though of course every ascension-relevant skill and iotm helps.

As mentioned already, any class, hardcore standard (because that is the only thing I've been doing since Crimbo, not necessarily because I have seen it /not/ fail under other conditions). Sign should not matter but in my case I was always taking the one with degrassi knoll access purely because they are first in the list.

Oh, and here's the session log from one of the days where it happened twice (once for the 3rd day of the ascension, once for the 1st of the next). I don't know that it will be much help beyond knowing what order some things happen in, as this is after implementing the changes and doesn't have debugging on regardless, but am including it for the sake of completeness.
 

Attachments

  • Laserrobotics_20230126.zip
    186.2 KB · Views: 1
Last edited:

Veracity

Developer
Staff member
Experiment:

1) changed "_fireworksShop" to "fireworksShop" and made it a "reset on rollover" property.
2) logged in with a clan with a fireworks shop
-> "fireworksShop" is true
3) jumped into the gash
-> in Valhalla. "fireworksShop" is still true
4) ascended (same session)
-> "fireworksShop" is still true
-> As part of ascension processing, KoLmafia visited the clan lounge and looked at clan furniture
--> (speakeasy, floundry, hotdog stand) -> "That clan thing is too old to be used on this path."
-> We did NOT visit the fireworks store. Perhaps because "fireworksShop" is already true?
5) Set up my model train set and opened the guild, at which point, my Mine Sluice had given me Meat
6) "acquire 1 yellow rocket" failed. DEBUG log says: "You still haven't found the shop that you're looking for."
7) set "fireworksShop" to false
8) Logged out and logged in again to same clan
-> This time, when login processing visited clan, it looked at fireworks shop
9) "acquire 1 yellow rocket" worked

Conclusions:

1) KoL does treat visiting the Fireworks Shop as a once per day thing which is reset on Ascension.
2) Therefore, the "daily" property "_fireworksShop" is correct and "resets at rollover" property "fireworksShop" is incorrect.
3) Therefore, when you ascend and we visit the clan VIP lounge, we need to visit the fireworks shop if we see it there.
--> I would have thought that "_fireworksShop" being false would force that, but perhaps not.

That's as much experimentation as I can do for at least three days.

Perhaps somebody else can check whether ascending (which visits the clan lounge) visits the Fireworks Shop - and if not, why not.
 

Crowther

Active member
I run autoscend and this month it has obtained 17 sombrero-mounted sparkler and 1 porkpie-mounted popper from the fireworks shop and not one error. It seems people consistently have a problem or consistently don't. Hopefully, someone will figure out what's different.
 

Aventuristo

Member
And I'm one of those with consistent problems. Mysterious. Crowther, do you have Mafia run any scripts at the beginning of the day? I don't.
 

Magus_Prime

Well-known member
It seems people consistently have a problem or consistently don't. Hopefully, someone will figure out what's different.
I've used autoscend to run through the 2023 HC and SC loops and have had no failures when trying to get hats from the fireworks shop.
 

lazy_fire

New member
I've run into this issue on previous autoscend runs and I noticed that the 1/day items are not acquirable via retrieve_item if autoSatisfyWithMall is false. The unlimited items (rockets, etc.) are not affected.

I had not purchased any items from the Fireworks Shop today before running the commands below.
> prefref autoSatisfyWithMall
NameValueDefaultScope
autoSatisfyWithMallfalseN/Aglobal
autoSatisfyWithMallfalsefalseuser

> ash retrieve_item(1,$item[fire crackers]);

Putting on designer sweatpants...
Equipment changed.
Purchasing fire crackers (1 @ 90)...
You spent 90 Meat
You acquire an item: fire crackers
Putting on Pantsgiving...
Equipment changed.
Purchases complete.
Returned: true

> ash retrieve_item(1,$item[sombrero-mounted sparkler]);

You need 1 more sombrero-mounted sparkler to continue.
Returned: false

> set autoSatisfyWithMall = true

autoSatisfyWithMall => true

> ash retrieve_item(1,$item[sombrero-mounted sparkler]);

Putting on designer sweatpants...
Equipment changed.
Purchasing sombrero-mounted sparkler (1 @ 450)...
You spent 450 Meat
You acquire an item: sombrero-mounted sparkler
Putting on Pantsgiving...
Equipment changed.
Purchases complete.
Returned: true

> ash retrieve_item(1,$item[catherine wheel]);

Putting on designer sweatpants...
Equipment changed.
Purchasing Catherine Wheel (1 @ 900)...
You spent 900 Meat
You acquire an item: Catherine Wheel
Putting on Pantsgiving...
Equipment changed.
Purchases complete.
Returned: true

> set autoSatisfyWithMall = false

autoSatisfyWithMall => false

> ash retrieve_item(1,$item[rocket boots]);

You need 1 more rocket boots to continue.
Returned: false
 

Veracity

Developer
Staff member
That's odd, since it is an NPC shop, not a Mall store.
I'd expect the needed setting to be autoSatisfyWithNPCs

Edit: huh.

Code:
> get autoSatisfyWithMall

true

> get autoSatisfyWithNPCs

true

> get autoSatisfyWithMall=false

autoSatisfyWithMall => false

> get autoSatisfyWithNPCs=false

autoSatisfyWithNPCs => false

> acquire fire crackers

You need 1 more fire crackers to continue.

> acquire sombrero-mounted sparkler

You need 1 more sombrero-mounted sparkler to continue.

> get autoSatisfyWithNPCs=true

autoSatisfyWithNPCs => true

> acquire fire crackers

Purchasing fire crackers (1 @ 95)...
You spent 95 Meat
You acquire an item: fire crackers
Purchases complete.

> acquire sombrero-mounted sparkler

You need 1 more sombrero-mounted sparkler to continue.

> get autoSatisfyWithMall=true

autoSatisfyWithMall => true

> acquire sombrero-mounted sparkler

Purchasing sombrero-mounted sparkler (1 @ 475)...
You spent 475 Meat
You acquire an item: sombrero-mounted sparkler
Purchases complete.
Searching for sombrero...
Search complete.
 
Last edited:

heeheehee

Developer
Staff member
thoughts on this chunk from KoLmafia.java?
Java:
    if (isAutomated) {
      // PC stores can be cheaper than NPC stores.  If we are
      // not allowed to purchase from the mall, skip through
      // requests until we find an NPC seller, if any.

      if (!Preferences.getBoolean("autoSatisfyWithMall")) {
        while (firstIndex < purchases.length) {
          PurchaseRequest currentRequest = purchases[firstIndex];
          if (currentRequest.getQuantity() == PurchaseRequest.MAX_QUANTITY) {
            break;
          }

          firstIndex++;
        }

In particular, NPCPurchaseRequest#getQuantity() delegates to NPCStoreDatabase.getQuantity(), which returns 1 for these items.
 

Veracity

Developer
Staff member
KoLmafia.makePurchases is used in the "buy" command and ASH buy()
InventoryManager.retrieveItem is used by the "acquire" command and ASH retrieve_item()

The items in question are quest items, so there will be only a single PurchaseRequest - an NPCPurchaseRequest - in the array
(You can see this in the Purchases frame; search for sombrero-mounted sparkler, for example, and you will see a single store offering it: the Clan Underground Fireworks Shop has one available. Unless you've already bought a hat from the store, in which case it is greyed out and 0 are available.)

If it turns out that retrieveItem ends up calling makePurchases, then yes - this would be the bug.

Presumably, it should use (currentRequest instanceof NPCPurchaseRequest) or something, rather than checking quantity like that.
 

heeheehee

Developer
Staff member
doRetrieveItem has...
Java:
    if (shouldUseNPCStore || scriptSaysBuy) {
      if (sim) {
        return shouldUseNPCStore ? "buy from NPC" : "buy";
      }

      // If buying from the mall will leave the item in storage, use only NPCs
      AdventureResult instance = item.getInstance(missingCount);
      boolean onlyNPC = forceNoMall || !InventoryManager.canUseMall();
      List<PurchaseRequest> results =
          onlyNPC ? MallPriceManager.searchNPCs(item) : MallPriceManager.searchMall(instance);
      KoLmafia.makePurchases(
          results,
          results.toArray(new PurchaseRequest[0]),
          InventoryManager.getPurchaseCount(itemId, missingCount),
          isAutomated,
          0);

I'm not sure whether `instanceof NPCPurchaseRequest` is adequate, especially for items that you've already purchased up to the limit.
 
KoLmafia.makePurchases is used in the "buy" command and ASH buy()
InventoryManager.retrieveItem is used by the "acquire" command and ASH retrieve_item()
...
If it turns out that retrieveItem ends up calling makePurchases, then yes - this would be the bug.

Presumably, it should use (currentRequest instanceof NPCPurchaseRequest) or something, rather than checking quantity like that.
Is there potentially also an issue in the opposite direction, then? Either I'm not following this logic correctly, or the CLI 'buy' command requires the ability to purchase from the mall. I semi-regularly use the script "Rollover Management" (https://kolmafia.us/threads/rollover-management.22074/) to end a day, which among other things will cast Rainbow's Gravity, buying any missing wads where necessary. It has been doing this successfully for me on the days where I finish a run and regain access to the mall, which would not be noteworthy except for that I apparently have "Buy items for the mall whenever needed" unchecked.

The relevant code snippet, which seems to be using the CLI to execute the 'buy' command:
if(have_skill($skill[Rainbow Gravitation]) && get_property("prismaticSummons").to_int() < 3) { foreach wad in $items[hot wad, cold wad, sleaze wad, stench wad, spooky wad, twinkly wad] if(available_amount(wad) > 2) { cli_execute("cast * Rainbow Gravitation"); } else if(have_skill($skill[Rainbow Gravitation]) && get_property("prismaticSummons").to_int() == 2) { foreach wad in $items[hot wad, cold wad, sleaze wad, stench wad, spooky wad, twinkly wad] if(available_amount(wad) < 1) { cli_execute ("buy 1 " + (wad)); cli_execute("cast * Rainbow Gravitation"); } } else if(have_skill($skill[Rainbow Gravitation]) && get_property("prismaticSummons").to_int() == 1) { foreach wad in $items[hot wad, cold wad, sleaze wad, stench wad, spooky wad, twinkly wad] if(available_amount(wad) < 2) { cli_execute ("buy 2 " + (wad)); cli_execute("cast * Rainbow Gravitation"); } } else if(have_skill($skill[Rainbow Gravitation]) && get_property("prismaticSummons").to_int() == 0) { foreach wad in $items[hot wad, cold wad, sleaze wad, stench wad, spooky wad, twinkly wad] if(available_amount(wad) < 3) { cli_execute ("buy 3 " + (wad)); cli_execute("cast * Rainbow Gravitation"); } } }
 
Top