Bug - Fixed Conditions and KoLmafia.continuationState / KoLmafia.hadPendingState

slyz

Developer
I have had a few problems in a script because of ASH functions with boolean return values. They were returning false even when the action was successful.

After checking RuntimeLibrary.java, it seems like all the ASH functions affected are those that use:
PHP:
return RuntimeLibrary.continueValue();
What led me to this is that, when successful, restore_mp() would return false while restore_hp() returned true:
Code:
> ash my_mp()

Returned: 615

> ash restore_mp( 10 )

[B]Returned: false[/B]

> ash my_hp()

Returned: 202

> ash restore_hp( 10 )

[B]Returned: true[/B]
It just happens that restore_hp() doesn't return RuntimeLibrary.continueValue(), while restore_mp() does.

I also tested other functions: equip(), restore_mp(), use_skill(), outfit(), use_familiar() and change_mcd():
Code:
> ash equip( $item[ perforated battle paddle ] )

Wielding perforated battle paddle...
Equipment changed.
[B]Returned: false[/B]

> ash use_skill( 1, $skill[ rage of the reindeer] )

Casting Rage of the Reindeer 1 times...
You acquire an effect: Rage of the Reindeer (duration: 10 Adventures)
Rage of the Reindeer was successfully cast.
[B]Returned: false[/B]

> ash outfit("castle")

Putting on outfit: castle
Equipment changed.
[B]Returned: false[/B]

> ash use_familiar( $familiar[ hobo monkey ] );

Putting Dom Casmurro the Llama Lama back into terrarium...
Taking Ultralord of the Hobo Jungle the Hobo Monkey out of terrarium...
[B]Returned: false[/B]

> ash change_mcd( 0 )

Resetting mind control device...
Mind control device reset.
[B]Returned: false[/B]
The next function I found that returned RuntimeLibrary.continueValue() was adventure():
Code:
> ash adventure( 1, $location[ icy peak ] );

Visit to McLarge: Icy Peak in progress...

[2821] Icy Peak
Encounter: Knott Yeti
Strategy: D:\dloads\KoLMafia\ccs\peak.ccs [knott yeti]
Round 0: slyz wins initiative!
Round 1: slyz executes a macro!
Round 1: slyz attacks!
Round 2: knott yeti takes 257 damage.
Round 2: slyz wins the fight!
After Battle: Ultralord of the Hobo Jungle sits on your fallen opponent's body, blows a smoke ring, and winks at you.
You gain 900 Meat
You gain 11 Beefiness
You gain 21 Magicalness
You gain 10 Sarcasm

[B]Returned: true[/B]
After using adventure() successfully, I tested the functions above again:
Code:
> ash equip( $item[ perforated battle paddle ] )

Wielding perforated battle paddle...
Equipment changed.
[B]Returned: true[/B]

> ash use_skill( 1, $skill[ rage of the reindeer] )

Casting Rage of the Reindeer 1 times...
You acquire an effect: Rage of the Reindeer (duration: 10 Adventures)
Rage of the Reindeer was successfully cast.
[B]Returned: true[/B]

> ash outfit("castle")

Putting on outfit: castle
Equipment changed.
[B]Returned: true[/B]

> ash use_familiar( $familiar[ baby sandworm ] );

Putting Ultralord of the Hobo Jungle the Hobo Monkey back into terrarium...
Taking Dusty the Baby Sandworm out of terrarium...
string of dingle balls is better than (none). Switching items...
Putting on string of dingle balls...
Equipment changed.
[B]Returned: true[/B]

> ash change_mcd( 10 )

Resetting mind control device...
Mind control device reset.
[B]Returned: true[/B]
I can only guess that either KoLmafia.continuationState or KoLmafia.hadPendingState had not been reset prior to using those functions, but adventuring restored them.

Before having this problem, I had just adventured until a goal was fulfilled. I can consistently reproduce this now:
Code:
> ash restore_mp( 10 )

[B]Returned: true[/B]

> goals add 1 yeti fur

Condition added: yeti fur
yeti fur

> adventure 10 icy peak

Request 1 of 10 (McLarge: Icy Peak) in progress...

[2822] Icy Peak
Encounter: Knott Yeti
Strategy: D:\dloads\KoLMafia\ccs\peak.ccs [knott yeti]
Round 0: slyz wins initiative!
Round 1: slyz executes a macro!
Round 1: slyz attacks!
Round 2: knott yeti takes 204 damage.
Round 2: slyz wins the fight!
You gain 566 Meat
After Battle: Boule does a couple of karate moves, then swivels his hips and gyrates his pelvis.
You acquire an item: yeti fur
You gain 6 Strengthliness
You gain 12 Enchantedness
You gain 7 Sarcasm

Conditions satisfied after 1 adventures.

> ash restore_mp( 10 )

[B]Returned: false[/B]

> adventure 1 icy peak

Visit to McLarge: Icy Peak in progress...

[2823] Icy Peak
Encounter: Knott Yeti
Strategy: D:\dloads\KoLMafia\ccs\peak.ccs [knott yeti]
Round 0: slyz wins initiative!
Round 1: slyz executes a macro!
Round 1: slyz attacks!
Round 2: knott yeti takes 200 damage.
Round 2: slyz wins the fight!
You gain 487 Meat
After Battle: Boule does a couple of karate moves, then swivels his hips and gyrates his pelvis.
You acquire an item: yeti fur
You gain 3 Muscleboundness
You gain 7 Magicalness
You gain 15 Chutzpah

Requests complete.

> ash restore_mp( 10 )

[B]Returned: true[/B]
Pinpointing the issue further, only completing the conditions seems to cause the problem:
Code:
> ash restore_mp( 10 )

[B]Returned: true[/B]

> goals add 1 steaming evil

Condition added: steaming evil
steaming evil

> adventure 1 icy peak

Visit to McLarge: Icy Peak in progress...

[2824] Icy Peak
Encounter: upgraded ram
Strategy: D:\dloads\KoLMafia\ccs\peak.ccs [default]
Round 0: slyz wins initiative!
Round 1: slyz executes a macro!
Round 1: slyz attacks!
Round 2: upgraded ram takes 200 damage.
Round 2: slyz wins the fight!
You gain 225 Meat
After Battle: Boule does a couple of karate moves, then swivels his hips and gyrates his pelvis.
You acquire an item: Ram's Face Lager
You gain 8 Beefiness
You gain 12 Enchantedness
You gain a Mysticality point!
You gain 6 Roguishness

[COLOR="#ff0000"]Conditions not satisfied after 1 adventure.[/COLOR]

> ash restore_mp( 10 )

[B]Returned: true[/B]
 
Apparently, fulfilling conditions sets Mafia in a PENDING_STATE in KoLmafia.executeAdventureOnce(). KoLmafia.hadPendingState is then set to true in KoLmafia.executeRequest().

The return value of the ASh adventure() function should probably take into account KoLmafia.hadPendingState, but maybe it shouldn't be considered for all the other ASH functions?

EDIT: or maybe KoLmafia.hadPendingState should be reset to false before executing any ASH function?
 
Last edited:
put_closet() doesn't return correct value

Hi,

as described here, put_closet( int qty , item it ) should return true if the move succeeds and false if it does not.

In Mafia V14.6, it always returns false, even if the transfer worked. Here is what i did in the CLI:

Code:
> inv goofball

goofballs

> ash put_closet(1,$item[goofballs]);

Placing items into closet...
Returned: false

> inv goofball

[I]## [COLOR="red"]no more goofballs, so the transfer worked[/COLOR][/I]

> ash put_closet(1,$item[goofballs]);

Placing items into closet...
Transfer failed for goofballs
Returned: false

> inv goofball

[I]## [COLOR="red"]still no goofballs[/COLOR][/I]

oska
 
I'm not even sure about that after I read slyz' thread, but if a mod wants my posting moved, feel free to do so
 
put_closet() uses "RuntimeLibrary.continueValue()" for its return value, so I merged the threads.
 
Does create also use that? My sushi script keeps failing even though it has obviously eaten/created the sushi it intended to create.

It uses the following command:
Code:
return cli_execute("create " + amount + " " + sushi_for_eating.name);

And lately it appears to be returning false even though it eats the sushi...
 
cli_execute() does return "RuntimeLibrary.continueValue()", and the return value is also affected by hadPendingState().

I think the best fix would to to reset KoLmafia.hadPendingState to false before executing any ASH command, but I don't really know where that should happen. I'll try looking at it more closely.
 
Here is my attempt to correct the problem.

1) I added a forgetPendingState() function to KoLmafia.java that resets KoLmafia.hadPendingState to false
2) forgetPendingState() is called in Interpreter.java before executing any ASH
3) forgetPendingState() is called when necessary each time KoLmafia.hadPendingState is used as part of a function's return value.

A little bit of testing seemed to show that the functions that use RuntimeLibrary.continueValue() as a return value now consistently have return values that show if they were successful or not.

I know there are more pressing issues due to changes in KoL, but I hope this won't fall off the devs' radar. Being able to use the return values of those functions can be very useful for scripters that wish to account for all kinds of errors.
 

Attachments

Thanks.

I started looking into how executing ASH works, but I thought it wouldn't be efficient to add forgetPendingState() before every function executed.

Since it seems like hadPendingState was added exclusively for ASH functions that use continueValue(), continueValue() seemed like the right place to add forgetPendingState(). And, of course, whenever an ASH interpreter is created, so hadPendingState starts out as false.
 
Yay, all those functions now have a meaningful return value. Even cli_execute()!

You did all the work. I just placed myself in harm's way if it turns out that this is not the Good Idea that you and I think it is ;-)
 
Cool. Now the code I added to my sushi-script to avoid that problem is meaningless. I will probably keep it anyway since it does no harm :)
 
Did find a bug that I believe is related to this... when satisfying a condition, you now get this:
Conditions satisfied after 10 adventures.
Out of adventures.
At present time, I have 16 adventures remaining.
 
That's strange, I can't find the "Out of adventures." message anywhere in the code. Which probably means Mafia was passing a long an error message from KoL itself?

Did it appear immediately after the conditions had been satisfied?

EDIT:
I have no idea of how exceptions work, but the "catch" in KoLmafia.makeRequest() could have caused the "Out of adventures." message to be printed in the gCLI. Now, to find out more about exceptions ...
 
Last edited:
Sorry, should have specified... that comes when zlib obtain runs adventure to get an item.
Code:
   if(length(filter) > 0){ if(adventure(my_adventures(), locale, filter)) return vprint("Out of adventures.",-1); }
   else if (adventure(my_adventures(), locale)) return vprint("Out of adventures.",-1);
   if (cond == "choiceadv") return (my_adventures() > 0);
   return (have_item(cond) >= n);
I'm running the no-filter (so second line, else version) obtain for getting 1 of whatever item I'm looking for... so what's returning the 'out of adventures' message is actually adventure(my_adventures(), locale) returning true since the change...
 
That's strange. Fulfilling your goals sets Mafia in a PENDING_STATE and stops your adventuring. KoLmafia.hadPendingState is then set to true, and RuntimeLibrary.continueValue() should return false.

I think the problem is that, once the adventuring is done and KoLmafia.hadPendingState is set to true, Mafia does its usual rounds, calling the recoveryScript (and maybe the betweenBattleScript?). A new interpreter is created for recovery, for example, and that calls KoLmafia.forgetPendingState().

It seems like Interpreter isn't the right place to call KoLmafia.forgetPendingState(). I'll have to think a little more about it =/
 
Ah... that makes sense. It still works, it just thinks that it's run out of adventures. Not sure who else's scripts might cause odd results though.
 
Back
Top