Bug Using the replica Deck of Every Card via CLI causes an error state, even if successful

VeeArr

New member
A user in Discord reported that their automation was failing because cli_execute("cheat ancestral recall"); was producing an error state despite being successful. Updating the automation to instead use cli_execute("try ; cheat ancestral recall"); succeeds.

I haven't run Legacy of Loathing enough times to check personally, but I suspect that this is happening because DeckOfEveryCardRequest uses InventoryManager.retrieveItem to check if a (non-replica) Deck of Every Card is present, and this failing produces the error state even though the request is recoverable because the user has a replica Deck of Every Card.
 
Java:
if (InventoryManager.retrieveItem(ItemPool.DECK_OF_EVERY_CARD, 1, true)) {
      deckUsed = ItemPool.DECK_OF_EVERY_CARD;
    } else if (KoLCharacter.inLegacyOfLoathing()
        && InventoryManager.retrieveItem(ItemPool.REPLICA_DECK_OF_EVERY_CARD, 1, true)) {
      deckUsed = ItemPool.REPLICA_DECK_OF_EVERY_CARD;
    } else {
      // If you can't get a deck into inventory, punt
      KoLmafia.updateDisplay(MafiaState.ERROR, "You don't have a Deck of Every Card available");
      return;
    }

From DeckOfEveryCards request.

I read that is it checks for the Deck. If it finds one, continue. If it doesn't then check for the replica. If it finds one then continue otherwise exit with an error.

So I don't understand how the failure message can occur without checking for both the Deck and the Replica and failing.

Is there a way to have access to the replica but not be in Legacy of Loathing?

Could the difference in command behavior be due to the card already been drawn or an absence of blue mana?

IIRC "try" command will silently swallow the error state and continue if there is no corresponding catch so the it may be that the absence of an error state does not actually mean drawing the card succeeced.

I guess I need more info.
 
So I don't understand how the failure message can occur without checking for both the Deck and the Replica and failing.

The error message from DeckOfEveryCardRequest request doesn't fire (because it does find the replica Deck of Every Card and does successfully use it). However, within InventoryManager.retrieveItem, it prints an error message due to not being able to acquire the (non-replica) Deck of Every Card; and it seemed feasible that this was setting the "hey an error occurred, so cli_execute should return false" flag (even though this error does not preclude the request "succeeding" for any meaningful definition of the word).

I attached the image from their original post. In it, it seems that the error message from InventoryManager.retrieveItem is printed when trying to find the non-replica Deck of Every Card, and then the request finds the replica Deck of Every Card and succeeds, but then cli_execute returns false and breaks the automation anyway or something?
 

Attachments

  • Replica_Deck.png
    Replica_Deck.png
    24.9 KB · Views: 2
Last edited:
retrieveItem sets MafiaState to ERROR if it fails; presumably something later aborts based on that.

An easy fix would seem to be to move the replica deck check before the non-replica deck check.
 
Perhaps related?

 
retrieveItem sets MafiaState to ERROR if it fails; presumably something later aborts based on that.

An easy fix would seem to be to move the replica deck check before the non-replica deck check.

I think that fix would just make it break in the case where a user has a non-replica deck but no replica deck, which would probably end up making the problem more common. (edit: No, the "am I in LoL?" check would avoid this being a problem most of the time) A better fix would probably be to either (1) use simRetrieveItem (which doesn't seem to emit an error message for a failure) for the first check (and then actually retrieve it if the sim result is not "fail"); or (2) keep the retrieval code as-is but manually reset the error flag if either deck is found.

Perhaps related?

I don't think so--that actually looks like it was the same issue as this one, which has seemingly been fixed.
 
Last edited:
Is there any circumstance where a user can have both an original and a replica? Maybe in a softcore LoL run that is out of Ronin? If so is that too niche to support?

I'd love to push this back on the script - that's why there are try and catch, after all, but if I detect a failure because the original wasn't present then what do I do to force the replica to be used?

retrieveItem is used in to many places to want to suppress the error message or make it less fatal.

I think I'm with @Ryo_Sangnoir and we should try checking got legacy and replica first.

If you're not in LoL then there should never be an extra message.
 
Is there any circumstance where a user can have both an original and a replica? Maybe in a softcore LoL run that is out of Ronin? If so is that too niche to support?

I'd love to push this back on the script - that's why there are try and catch, after all, but if I detect a failure because the original wasn't present then what do I do to force the replica to be used?

Yea I think technically if you're out of Ronin in LoL you can pull a non-replica deck. Maybe that's too niche to support, but I think something like this (untested) could maybe cover that case anyway:

Code:
    if (KoLCharacter.inLegacyOfLoathing() 
        && !"fail".equals(InventoryManager.simRetrieveItem(ItemPool.REPLICA_DECK_OF_EVERY_CARD, true))
        && InventoryManager.retrieveItem(ItemPool.REPLICA_DECK_OF_EVERY_CARD, 1, true)) {
      deckUsed = ItemPool.REPLICA_DECK_OF_EVERY_CARD;
    } else if (InventoryManager.retrieveItem(ItemPool.DECK_OF_EVERY_CARD, 1, true)) {
      deckUsed = ItemPool.DECK_OF_EVERY_CARD;
    } else {
      // If you can't get a deck into inventory, punt
      KoLmafia.updateDisplay(MafiaState.ERROR, "You don't have a Deck of Every Card available");
      return;
    }

edit: Actually maybe simRetrieveItem is overkill here. Mafia really just needs to check if there's one in their inventory I think; it's not like you're going to be crafting or pulling a replica Deck of Every Card.
 
Last edited:
Back
Top