Bug - Not A Bug fight.php relay overrides use previous encounter data for round 1

StDoodle

Minion
Why not just request an ash funtion to return the currently displayed page without hitting the server? Ugh, sorry if that doesn't sound correct, I'm struggling to follow this. ;)
 

Bale

Minion
It is a not insignificant problem for me to script around, so I wondered if people who know more than me might be able to suggest a workaround or implement a change that would help this particular situation, without requiring a significant rewrite of my approaching-1500-lines script, which was originally written as a purely consult script, where mafia's monster functions always refer to the current monster.

Well, you could replace all the 0-parameter versions with the 1-parameter versions of those functions and in all cases, have the parameter be a variable named foe. When called from a consult script foe is determined by the parameters of main, or in the case of the relay version you'd determine the value of foe by parsing the result of visit_url().
 
Last edited:

zarqon

Well-known member
Let me try to make it a bit clearer:

Mafia automatically, invisibly updates the parameter-less versions of monster functions every time a monster is encountered. This means that in consult scripts, we can use ASH's last_monster() function rather than needlessly passing around a monster parameter in all of our functions. Very handy; I've done this in all my consult scripts, to streamline them.

For a relay override script, at the moment it is called basically nothing has happened yet. It has not visited any URLs on the KoL server. The override script is overriding mafia's default (fetching the page, which would update monster functions) and instead doing whatever the script specifies first, which could be as simple as the default plus a few changes, or as complicated as never fetching the page and instead constructing an entirely new replacement page.

When we override fight.php, at the moment our fight.ash is called, the actual combat has not even started, so all the monster functions have not been updated. It's waiting for the actual visit_url() to be called, parameter-less (specific to relay scripts), which actually fetches the page, causing all the monster info to be updated.

My problem is that I've built a library intended for both consult/relay use using ASH monster commands -- and included scripts must be included before any commands, which means the relay script can't load the page before the library script runs. In the library, everything needs to be in a certain order, but I left quite a lot of things at top-level. I can't move all the top-level stuff into a single function -- it would need to be in multiple functions, scattered throughout the script, and then called in order by a parent init()-type function, simply for the purpose of delaying until the calling script could actually start the combat. It's beyond inelegant and well into ugly.

It looks like either this ugly hack or a significant rewrite is in order.

@Bale: We can't use the versions of these functions that include a monster parameter, because later we'll want return values that are specific to the monster we're fighting, not static starting values. Even in the first round, events could already have happened which alter the monster's HP/attack/defense.
 
Last edited:

Winterbay

Active member
Just throwing this out there: Would it be possible to have, as the first included-script, a script that basically just calls the 0-parameter version of visit_url in order to update the monster data and then the rest is hadnled as normal?
It would require yet another script but would possibly solve the problem. However I have no idea if that work.
 

holatuwol

Developer
That should work, since if it's the first import, the visit_url() will be the first thing in the global execution scope. But instead of just calling visit_url() blindly, which would make it so you can't pass gibberish, what you could do is wrap that inside of a call to get_path_variables(), which returns the query string that was passed along.

Edit: Actually, get_path_variables() would only work for a get request. Would probably be better to do a count() on the form_fields().

PHP:
if (count(form_fields()) == 0)
{
	visit_url();
}
 
Last edited:

Veracity

Developer
Staff member
Would probably be better to do a count() on the form_fields().

PHP:
if (count(form_fields()) == 0)
{
	visit_url();
}
I just wrote a little fight.ash relay override to experiment with this, and it turns out that you never get fight.php with 0 parameters; they now pass "ireallymeantit". This script:

PHP:
void main()
{
	string [string] fields = form_fields();

	buffer url;
	string sep = "?";
	url.append( "fight.php" );
	if ( count(fields) > 0 ) {
		foreach field, val in fields {
			url.append( sep );
			sep = "&";
			url.append( field );
			url.append( "=" );
			url.append( val );
		}
	}
	print( url );

	string page = visit_url();
	write(page);
}

Says this:

fight.php?ireallymeanit=1295968851

[292603] Giant's Castle
Encounter: Goth Giant
Round 0: Brianna wins initiative!
fight.php?action=steal
Round 1: Brianna tries to steal an item!
You acquire an item: thin black candle
fight.php?action=attack
Round 2: Brianna attacks!
Round 3: goth giant takes 1435 damage.
Round 3: Brianna wins the fight!
After Battle: Gort winks at you.
You gain 437 Meat
You gain 5 Beefiness
You gain 13 Mysteriousness
You gain 15 Smarm
 

Theraze

Active member
Okay... so taking Veracity's code, and applying it to what Winterbay had done, we can do the following, right...?
Code:
void main() 
{ 
string [string] fields = form_fields(); 
 
   if ( count(fields) == 0 ) visit_url();
   else if ( count(fields) == 1 ) { 
       foreach field, val in fields { 
       if (field.equals("ireallymeanit")) visit_url();
       } 
   } 
}
 

Veracity

Developer
Staff member
You will never have count(fields) == 0. And you do not want to stick the call into a main() function since you want it as a command in the global scope.

Do this:
Code:
string [string] fields = form_fields();  
if ( fields contains "ireallymeanit" ) {
   visit_url();
}
 
Last edited:

Theraze

Active member
Well, I put the count == 0 check in there so that if someone launches a relay script (relay_adventureadvisor or something like that) in the middle of combat, then relaunches the relay window, it will properly launch combat... Not sure if it launches pure or not in that case.

And does "ireallymeanit" only happen by itself, or can it happen in other rounds as well if someone has incorrectly formed their combat script or closed the relay window and reopened it or something similar? That's why I tossed in the count check... if it can only ever happen on its own, then searching with contains is great though.
 

Veracity

Developer
Staff member
I might just rework all of KoLmafia's round tracking to rely on the server's information (since it already provides that data to us) if it turns out that it's a problem in the round tracker.
I'd love it if you wanted to do this - AFTER I spin 14.4 (after the February IOTM is supported). :)

Here is a (merged) thread with lots of discussion about KoL vs. KoLmafia round tracking.
 
Top