Access to Internal Data

BDrag0n

Member
Would it be possible to have an ASH variant of the CLI commands to detect stat bonus days?
e.g. stat_today and stat_tomorrow, returning none, muscle, mysticality or moxie.

I have 2 examples of use here, for my clan manager/buffbot:

Code:
if(stat_today=$stat[moxie])
 {
    adventure(my_adventures(), $location[pump up moxie]);
 }
 else
{
          if($stat_tomorrow=$stat[moxie])
           {
              adventure(my_adventures()-100, $location[Castle in the Clouds in the sky]);
           }
}
That isn't enough for it to be non-boolean, but returning the stat would be more useful for calling some scripts I've made for buying the clan buffs, called statbuff, moxiebuff, musclebuff and mysticalitybuff
Code:
if(stat_today=$stat[none])
{
  cli_execute( "call clan\statbuff");
}
else
{
 cli_execute( "call clan\"+stat_to_string(stat_today)+"buff")
}
 

holatuwol

Developer
This has the same problem that I noticed with the proposed zodiac_to_stat function. Most of the time, you're not doing anything with that value except checking it for equality (or inequality) against muscle, moxie or mysticality. But, in this case, I can see how the value would actually be passed to a different function, and as such:

stat stat_bonus_today()
stat stat_bonus_tomorrow()
 

macman104

Member
Since mafia already calculates your monster level+ info, and it has information about never being hit in the location details panel I'm here to request to things.

Is it possible to get a survival value (or safe adventuring value), and a monster level value. I imagine

int safeadv(location)
int my_monster_level();

safeadv is esentially, the toughest monster in your area + 9 + your monster level.

Application you say? Well, I've got just the script, this one automatically updates the MCD as my moxie climbs, however, I use monster_base_attack, and current_mind_control_level. The check I use is (and right now I'm in the castle, so it's for an alphabet giant:
Code:
int buffmox = my_buffedstat($stat[moxie]);
monster alpha = $monster[Alphabet Giant];
boolean mystsign = in_mysticality_sign();

if((monster_base_attack(alpha) + 9) < (buffmox - current_mind_control_level()) && mystsign)
{
	if(buffmox <= monster_base_attack(alpha) + 21)
	{
		mind_control(buffmox - monster_base_attack(alpha) - 9);
	}
	else
	{
		print("You can't set that thing any higher");
	}
}
This could be better replaced by
Code:
int safemox = my_buffedstat($stat[moxie]) + my_monster_level();
int MCD_left = 11 - current_mind_control_level();
location curloc = my_location();
boolean mystsign = in_mysticality_sign();

if(safeadv(curloc) < safemox && mystsign)
{
	if(safemox <= safeadv(curloc) + MCD_left)
	{
		mind_control(safemox - safeadv(curloc));
	}
	else
	{
		print("You can't set that thing any higher");
	}
}

I use this as an inbetween battle script. Let's say I need 155 to start using the MCD at the giants, but I'm at 132, I can type
Code:
conditions add 155 moxie
adventure * penultimate
And as my moxie climbs, this will keep the MCD up with me, and then my adventuring stops when I reach my next target area.

macman104 walks off to sit down in a chair await Judge Holatuwol's ruling :)
 

macman104

Member
[quote author=Nightmist link=topic=250.msg1817#msg1817 date=1155267813]Now for my request... Not really adding functions but I am curious where mafia currently stores the values for the ML mods and such (Since they are not currently in the .dat files as far as I know)??[/quote]They're pulled from monsters.dat and modifiers.dat, you can see them in the data folder of the SVN repository
 

Nightmist

Member
[quote author=macman104 link=topic=250.msg1818#msg1818 date=1155268459]
They're pulled from monsters.dat and modifiers.dat, you can see them in the data folder of the SVN repository
[/quote]

>> Yeah... ok thats a new .dat file. >> So wasnt in 8.5 release... *Checks his 8.6*... Yup >> Ok thanks. =)
 

macman104

Member
[quote author=Nightmist link=topic=250.msg1819#msg1819 date=1155269026]
>> Yeah... ok thats a new .dat file. >> So wasnt in 8.5 release... *Checks his 8.6*... Yup >> Ok thanks. =)
[/quote]Nope, they've been there ever since the location info, if you click on one of the files you can see their history, and see that veracity first put the monster.dat in on
Added Sat Apr 15 22:37:36 2006 UTC (3 months, 3 weeks ago) by veracity0
and the modifier info, used to be part of KoLCharacter.java
but was moved to it's own file
Mon Aug 7 08:22:43 2006 UTC (3 days, 19 hours ago) by shwei
Anyway, we're getting off track here, but yea, it's been there since the information was present (just ML stuff wasn't in a .dat file).

EDIT: To Picklish, it probably is useful functionality, that would be used for non-evil, but at the same time, holatuwol can't assume everybody who would use it the way it was intended. He also tries to be conscientious of server load, and not hitting the servers too much, and mallbotting is something that does do that (remember that one person who coded their's badly and used up 3% of the bandwidth, all by them self :eek:).
 

Veracity

Developer
Staff member
[quote author=macman104 link=topic=250.msg1818#msg1818 date=1155268459]
They're pulled from monsters.dat and modifiers.dat, you can see them in the data folder of the SVN repository
[/quote]

Yes, currently. Mostly. Things like Aria have an effect on +ML which varies by level, so that's still in the code, not the new modifiers.dat file.

I originally had them in KoLCharacter.java, back when I added the Location Details. I wanted to store all the modifiers - +ML, +items, +meat, and so on - in simple variables that internal functions could simply query when they needed them, and which would be kept up to date every time you swapped equippment, reset the MCD, gained or lost an effect, etc. holatuwol recently moved them to a data file. Now it's trivial to add new items and let users update the data files to get the new modifiers, rather than forcing them to wait for another release.

I think that all of those modifers could and should be available as ASH functions. Let KoLmafia worry about keeping up to date with new items.

The following data are recalculated every time you swap equipment, etc:

Code:
    private static int monsterLevelAdjustment = 0;
    private static int familiarWeightAdjustment = 0;
    private static int dodecapedeWeightAdjustment = 0;
    private static int familiarItemWeightAdjustment = 0;
    private static int manaCostModifier = 0;
    private static double combatPercentAdjustment = 0.0;
    private static double initiativeAdjustment = 0.0;
    private static double fixedXPAdjustment = 0.0;
    private static double meatDropPercentAdjustment = 0.0;
    private static double itemDropPercentAdjustment = 0.0;
    private static boolean rigatoniActive = false;

I'd probably not make a "rigatoni_active" function but would have something like "int my_buffed_hit_stat()" which would return the current (buffed) value of muscle, mysticality, or moxie, as appropriate.
 

peterbones

New member
Hopefully this is the right place for this.  I've been writing ASH scripts for about a week now, but gotten pretty far along.  It turns out the one thing that is missing for me is quest data.  So I went and added a couple of functions to mafia's ASH handling:

Code:
//substring search
boolean contains_text( string searchedString, string searchString );

//runs a url and returns the output html
string run_url( string url );

Just to be nice, I won't post the code I put into KoLmafiaASH.java, but it's only a few lines and pretty easy to figure out if you know java and/or have looked at the mafia source at all.  Anyway, now I can do fun things like:

Code:
boolean have_quest( string questString )
{
    return contains_text( run_url( "questlog.php?which=1" ), questString );
}

Anyway, reading the threads here it seems like this might be overpowered for inclusion in ASH, but I thought I'd propose it anyway.  I don't see how the two functions I've listed could be used for mallbotting or other nefarious purposes, at least without better string parsing functions.  And let's face it, if someone wanted to write a mallbot by parsing the raw html output they would probably be hacking the java anyway.

Of course, since the only thing I use them for is checking the quest log (and the trapper for what ore he wants) some sort of check_for_quest( string questString ) or with a quest data type-- check_for_quest( quest qu ) would work as well (see Tirian's post: http://kolmafia.us/index.php/topic,35.msg959.html#msg959).  Is the quest functionality something that hasn't been considered important enough or just not gotten around to, or is there an ethical reason for not adding it?
 

Tirian

Member
Personally, I think that your two functions are much easier on the developers than coming up with an entire new quest type. I've thought for some time that a quest datatype would be a good thing, but I'm not sure that we'd all have the same definition of quests. (For instance, I would argue that unlocking the store in your guild is a quest even though it doesn't even show up in the quest logs.) But we could probably design quest types more cleanly if had some working scripts that used something similar.

I think that functions to get the HTML from a URL call and then a substring check are excellent, and that it wouldnt enable evil-doers any more than persistent data that could be read or written by the player inside or outside of KoLmafia. It is simple to do, and I get the feeling that Holatuwol would tolerate the function as long as he doesn't have the make the change himself, but I don't know who among the developers would check in the file.
 

Veracity

Developer
Staff member
On a completely different topic, I've just added some functions to ASH that give you access to all the various modifiers that KoLmafia calculates based on your current equipment, active effects, passive skills, current familiar, etc.

First, I defined a new data type:

element el = $element[hot];
string element_to_string(  $element[cold] );
element string_to_element( "stench" );
int element_to_int( $element[stench] );
element int_to_element( 4);

(the choices are, as you might guess, hot, cold, sleaze, spooky, and stench)

I ended up not using it for the functions I provided, but, have fun.

The new functions can best be illustrated with an example:

Code:
print( "Monster Level Adjustment = " + monster_level_adjustment() );
print( "Familiar Weight Adjustment = " + familiar_weight_adjustment() );
print( "Mana Cost Modifier = " + mana_cost_modifier() );
print( "Raw Damage Absorption = " + raw_damage_absorption() + " (" + damage_absorption_percent() + "%)" );
print( "Damage Reduction = " + damage_reduction() );
print( "Cold Resistance = " + cold_resistance() );
print( "Hot Resistance = " + hot_resistance() );
print( "Sleaze Resistance = " + sleaze_resistance() );
print( "Spooky Resistance = " + spooky_resistance() );
print( "Stench Resistance = " + stench_resistance() );
print( "Combat Percent Modifier = " + combat_percent_modifier() );
print( "Initiative Modifier = " + initiative_modifier() );
print( "Fixed XP Bonus = " + fixed_experience_bonus() );
print( "Meat Drop Modifier = " + meat_drop_modifier() );
print( "Item Drop Modifier = " + item_drop_modifier() );
print( "Hit stat is " + current_hit_stat() + ", current buffed value = " + buffed_hit_stat() );

yields (for me, currently):

> boni.ash
Monster Level Adjustment = 5
Familiar Weight Adjustment = 15
Mana Cost Modifier = 0
Raw Damage Absorption = 170 (28.585659373582427%)
Damage Reduction = 0
Cold Resistance = 40.0
Hot Resistance = 20.0
Sleaze Resistance = 20.0
Spooky Resistance = 20.0
Stench Resistance = 20.0
Combat Percent Modifier = 0.0
Initiative Modifier = 60.0
Fixed XP Bonus = 9.75
Meat Drop Modifier = 205.0
Item Drop Modifier = 70.0
Hit stat is Muscle, current buffed value = 64
Script succeeded!

I considered having "double elemental_resistance( element )" rather than cold_resistance, hot_resistance, etc. - hence the new data type - but I decided that any actual use of this would be testing a particular known stat: checking specifically cold_resistance, say, to see if you can pass a cold test in the DD (not that KoLmafia lets you script that...)
 

peterbones

New member
Neat. I know nothing about stasis, so I can't comment on the script other than to say that it looks like it will work. If it does not meet the "embodies all the mathematical calculations handled by people who currently use a stasis-like strategy" I hope there's a reference given to what those are. As for my_ml() and skill discount and whatnot looks like that is taken care of...

Veracity - yay! Now I don't need the stuff I wrote for calculating familiar weight, XP and whatnot using picklish's maps. One question, we have familiar weight adjustment, is there a function for familiar weight? I don't see it on the function reference.
 

Veracity

Developer
Staff member
[quote author=peterbones link=topic=250.msg1888#msg1888 date=1155522896]Veracity - yay!  Now I don't need the stuff I wrote for calculating familiar weight, XP and whatnot using picklish's maps.  One question, we have familiar weight adjustment, is there a function for familiar weight?  I don't see it on the function reference.[/quote]

You are correct, so I added one.

Code:
familiar fam = my_familiar();
print( "My " + fam + " is at my side and weighs " + familiar_weight( fam ) + " lbs.");
fam = $familiar[ sleazy gravy fairy ];
print( "My " + fam + " is in the terrarium and weighs " + familiar_weight( fam ) + " lbs.");

yields

> fam.ash
My Cheshire Bat is at my side and weighs 20 lbs.
My Sleazy Gravy Fairy is in the terrarium and weighs 1 lbs.
Script succeeded!

If there's any other basic datum like that you need, let me know.
Also, if you'd prefer different names or calling sequences for any of these, now's the time to speak up. For example, if you really would prefer "int elemental_resistance( element )" to "int cold_resistance()" et al - or in addition to them - tell me how you'd use the alternate function, and I just may add it...

Although, now that the weekend is all but over, I'm probably out of time for a while :)
 

macman104

Member
Holatuwol, did my safeadv(location) function, on the last page get rejected? or missed? or is it still stewing?
 

macman104

Member
[quote author=holatuwol link=topic=250.msg1899#msg1899 date=1155542641]Still pondering. I don't like the name safeadv(), but the best name I can come up with is perfect_dodge(), which is a name which makes sense, but doesn't read well in any of the code examples. One which reads better is moxie_survival(), but it doesn't make much sense as a name. I'll come up with something (or wind up choosing one of the two).[/quote]Heh, too be honest, when I was writing my code, I didn't know what to call it either, and I just knew, it was to make sure I never got hit, so I was safe. But it's certainly not by any means a name where you immediately know its function (which, despite some of the longer command names, is something I really like, all ASH commands are intuitive, no guessing what that function does). Now that I know you're still pondering it, I'll go....ummm, oh my it's 3:30am, maybe I'll go sleep :D.
 

Tirian

Member
Here's another thing that's exposing KoLmafia functionality rather than data, but it should be easy if you agree with it:

boolean leaflet( boolean magic_word )) - runs either the Leaflet (No stats) or Leaflet (Stats) hardcoded scripts.

Code:
boolean go_for_it = ( stat_bonus_today() != $stat[ none ] || stat_bonus_tomorrow() == $stat[ none ]);
leaflet( go_for_it );
if ( !go_for_it)
  print( "Don't forget to finish the leaflet tomorrow!" );

Similarly, boolean entryway( boolean use_a_clover ) would expose both of the Entryway scripts (which I'd personally choose based on whether I was a fighter class and had enough HP to survive several bad rolls on a single full heal). That's a little trickier as entryway() is already defined, but you've enabled function overloading. You might even deprecate the old function, as you're forcing us to rewrite our scripts this release anyway with the consumption function changes. :)
 

Tirian

Member
[quote author=Veracity link=topic=250.msg1891#msg1891 date=1155525105]
Also, if you'd prefer different names or calling sequences for any of these, now's the time to speak up. For example, if you really would prefer "int elemental_resistance( element )" to "int cold_resistance()" et al - or in addition to them - tell me how you'd use the alternate function, and I just may add it...[/quote]

I could imagine wanting to know elemental_resistance( elemental_type[ monster_i_am_fighting ]) so that I could calculate (in theory) the amount of damage that I'm likely to take per round of combat. (I'm assuming here that element [monster] elemental_type is a user-defined map.) And with visit_url() I suppose we could code the DD now, so run-time elemental checking seems preferable.

Also, I did some testing of your familiar weight functions. It seems to me that one would want it to be that, if we were to equip some familiar "pet" currently in our terrarium, we would know that its weight would be familiar_weight( pet ) + familiar_weight_adjustment(). Currently, that rule wouldn't hold because the adjustment from the familiar's gear is tallied with the weight adjustment instead of the pet-specific weight.
 

peterbones

New member
Ah, thought of one more thing. So far as I know, there's no functions for substat information. Sure, it'll be possible to do a visit_url and a bunch of comparisons, though looking at the source for the player info page it's slightly evil if you happen to have 2 stats that have the same base. Anyway, as long as they're being tracked a function to access them would be nice. my_substat( stat ) or something. I'd imagine it'd be relative, so if you had 8 moxie and were 9/17 substats towards 9, my_substat( $stat[ moxie ] ) would return 9 and not 73.
 
Top