View Full Version : Access to Internal Data
holatuwol
06-30-2006, 02:53 AM
A lot of people seem to be writing ASH libraries which equate to access to data that KoLmafia manages anyway through the course of doing what it does. So, I decided I'd create this thread to address this -- why waste time writing giant libraries and maps for data KoLmafia already has?
If you have the suspicion that there's information that KoLmafia uses in order to do its internal data management, post the kind of information you think KoLmafia has access to, give a name for the ASH version of the method and give justification for why this is a good name for that method. My hope is that anyone can READ ASH scripts to find out what they're doing and I prefer highly "literate" function names.
That's about it -- new functions which KoLmafia does not have access to will need some sort of GUI equivalent to justify their existence (otherwise, an ASH library script is just as good). So, if you'd like KoLmafia to handle something internally, instead of having to import a library script (ie: you think the idea should be included in KoLmafia), you're more than welcome to produce an idea on how it can be used in the GUI and we'll consider it. But, even if we like it, you'll have to do the data entry, meaning you have to specify a format. :) That's about it!
holatuwol
06-30-2006, 05:57 AM
While I see reasons for providing the information, which can be useful (as was the case when adding $stat[none]), I was asking for reasons why you believe it to be a good name.* This can be as simple as providing a code sample showing how it's easy to understand from context, without explanation or comments.* Therefore, while I'm sure the data is useful:
Verdict: All your suggestions have been rejected because you have failed to satisfy the request requirements.
macman104
06-30-2006, 07:16 AM
I was asking for reasons why you believe it to be a good name.I'm a little confused by that statement. Does that mean he didn't explain why his function names are good ones? Just looking for clarification.
efilnikufecin
06-30-2006, 10:01 AM
Hmm, access to internal data...I could build quite a list. I'll try to limit them though.
boolean have_musshroomplot() return true if the player has one, false if the don't.
if(have_mushroom_plot())
* {
* int PreFarmShrooms;
* int iterations;
* PreFarmShrooms = item_amount($item[knoll mushroom]);
* cli_execute("field harvest");
* if(item_amount($item[knoll mushroom]) > PreFarmShrooms)
* * {
* * iterations = 1;
* * While(iterations != 17)
* * * {
* * * cli_execute("field plant " + int_to_string(iterations) + " " + MushroomToFarm);
* * * iterations = iterations + 1;
* * * }
* * }
* }
effect skill_to_effect(skill my_skill) returns the effect given by casting the skill, none if the skill is not a self buff.
skill effect_to_skill(effect my_effect) skill_to_effects counterpart returns the skill needed to obtain an effect. None if the effect is not given by a skill.
adv_per_cast(skill my_skill) returns the number of adventures of the effect given by a 1 cast of a skill 0 or -1 if the skill passed does not give an effect.
int skill_cost(skill my_skill) returns the number of mp used for 1 cast a skill or:
int cost_to_cast(int times, skill myskill) would return the total cost to cast the given skill the given number of times
finally, the last request in this group is actually not a request for internal data, but more of a bypass of the way things are normally handled which will fit into the scheme of my other requests:
restore_mp(int restore_to) would ignore the fact that I have auto restore disabled, and restore mp to the amount specified or higher the best possible way in which kolmafia can see.
restore_hp(int restore_to) would do the same as above, but for hp
the following function would allow turning off auto restore so that I am not restoring after I self buff but instead will restore only before I self buff. Usefull with the saucephere buff, the star starfish, and when meat/mp restorers are at a premium.
void DoBuff(skill buff, int length)
{
int TotalTimesToCast;
int LengthNeeded;
int MaxTimesCast;
LengthNeeded = length - have_effect(Skill_To_Effect(buff));
if(LengthNeeded > 0)
* {
* TotalTimesToCast = (length / Adv_Per_Cast(buff)) + 1;
* MaxTimesCast = my_maxmp() / skillcost(buff) - 1;
* if(MaxTimesCast < TotalTimesToCast)
* * {
* * While(TotalTimesToCast > MaxTimesCast)
* * * {
* * * restore_mp(MaxTimesCast * skill_cost(buff));
* * * use_skill(MaxTimesCast, buff);
* * * TotalTimesToCast = TotalTimesToCast - MaxTimesCast;
* * * }
* * }
* restore_mp(TotalTimesToCast * skill_cost(buff));
* use_skill(TotalTimesToCast, buff);
* }
}
next up: stat info
stat my_zodiac_stat() returns muscle if you are a muscle sign and so on. This can be determined in a script already with the following function:
Stat my_zodiac_stat()
* {
* if(my_zodiac() == $zodiac[wallaby] || my_zodiac() == $zodiac[vole] || my_zodiac() == $zodiac[mongoose]){return $Stat[Muscle];}
* if(my_zodiac() == $zodiac[Platypus] || my_zodiac() == $zodiac[Opossum] || my_zodiac() == $zodiac[Marmot]){return $Stat[Mysticality];}
* if(my_zodiac() == $zodiac[Wombat] || my_zodiac() == $zodiac[Blender] || my_zodiac() == $zodiac[Packrat]){return $Stat[Moxie];}
* return $Stat[none];
* }
but kolmafia processes internal functions much faster than functions written in a script.
if(my_zodiac_stat() == $stat[muscle])
{
buy(1, $item[spring]);
}
else
{
//start adventuring with objectives.
}
stat primary_stat() return the characters main stat.
if(my_primary_stat() == $stat[muscle])
* {
* eat(1. $item[knob sausage chow mein]);
* }
boolean have_outfit(string outfitname) returns true if you have the outfit, false if you don't.
if(!have_outfit("filthy hippy disguise"))
* {
* if(current_equipment($slot[hat]) != $item[filthy knitted dread sack] && item_amount($item[filthy knitted dread sack]) < 1){buy(1, $item[filthy knitted dread sack]);}
* if(current_equipment($slot[pants]) != $item[filthy corduroys] && item_amount($item[filthy corduroys]) < 1){buy(1, $item[filthy corduroys]);}
* }
cli_execute("outfit filthy hippy disguise");
holatuwol
06-30-2006, 08:14 PM
I'm a little confused by that statement.* Does that mean he didn't explain why his function names are good ones?* Just looking for clarification.
Correct.* One of the reasons I'm phrasing the request this way is I find that I read through built-in functions fine (with a little struggle for things like stats handling), but I have trouble figuring out what people are trying to do in many ASH scripts when I'm trying to reflect on what that function does.
While I certainly can't force readable names in everyone's ASH scripts, I'd like readable names in KoLmafia's built-in functions.* Also, since the easiest way to show how a function is useful is through a code example, and that's the suggested reasoning behind documenting why it's readable, it also helps me see the way people plan on using the built-in function, and my hope is that people tweak the name of the function to the point where it's easily readable by anyone (especially me).
This is a highly subjective process, and I'm prone to reject a lot of ideas outright, either because people aren't following the requirements (ie: they don't provide a reason for the name of the method), or because I don't find the name readable (which might be me being anal-retentive).* In the second case, if I see a code sample, or some justification for why it's a good name, it's really easy for me to come up with a new name that's easy to read.
As a result, I'm sure a few people think to themselves, "Wow, what a waste of time" as I'm prone to change names to my liking or reject things, even after good explanation of how they're used, if I see no explanation of the name.* Possibly even Tirian, who made ten proposals and had them all rejected in one cold-blooded line of red text.* However, I'm not intentionally being a tyrant, or a jerk, or any of those things that might come to mind: I'd simply like to have persons submitting requests to do some of the work Veracity and I do before adding new ASH functions and to encourage a different mentality about ASH function requests.
In hindsight, I feel as though I was coming off as overly harsh rejecting the very first request, so this morning, I thought about adding a few of the requested functions that were self-explanatory (you know, the kinds of functions where people might think, "Why should I explain why that's a good name?* The answer is DUH).* But, they've disappeared (I'm guessing deleted for revision, or out of annoyance with me being a tyrant?), and I only remember two (Update: three).
boolean in_hardcore(): Added
slot item_to_slot(item): Added
boolean have_equipped(item): Added
If you go as far as a code example, if it's genuinely how you'd use it (I'm hoping this is the case), you're not doing any extra work, since when I say, "Approved" your script is done, and when I say "Renamed" you just replace-all and you're set.* I wasn't joking around when I made this a sticky: if it's truly something that KoLmafia maintains internally, and provided it's something I haven't rejected before (getting the response text from a raw URL request), it will be added if you provide your code example OR if you give me a good reason for the name.
Hmm, access to internal data...I could build quite a list. I'll try to limit them though.
Don't worry too much about limiting it: if you can come up with all the code examples for all the internal functions you'd like access to, and you still find all of them necessary, then feel free to make your request.* Now for your suggestions (Update: So that's where the have_ prefixes came from ... the existing functions in the ASH use have_.* Okay, I've undone the renames):
boolean have_mushroom_plot(): Added
effect skill_to_effect(skill): Added
skill effect_to_skill(effect): Added
boolean restore_hp(int): Added
boolean restore_mp(int): Added
int skill_cost(skill): Renamed to int mp_cost(skill)
stat my_zodiac_stat(): Renamed to boolean in_muscle_sign(), boolean in_mysticality_sign(), boolean in_moxie_sign()
boolean have_outfit(string): Added
stat my_primary_stat(): Renamed to stat my_primestat()
boolean outfit(string): Added to supplement boolean have_outfit(string)
As a side note, I have also changed skill usage to automatically trigger restoration wherever needed, regardless of HP/MP restore settings.* Also, mp_cost does not check whether or not you have the skill; it simply lets you know what the cost of casting the skill would be if you had the skill.* Passives return a value of zero.
int adv_per_cast(skill): KoLmafia does not maintain this data.* The buffbot module recalculates it whenever it needs to for buffs, which are easy, since there are well-defined rules for when it's 5, 10 or 15, and you have the luxury of assuming a rock and roll legend for anyone running a buffbot, but other than that, KoLmafia has no idea what the adventure yield is for each skill.
macman104
06-30-2006, 08:49 PM
Correct. One of the reasons I'm phrasing the request this way is I find that I read through built-in functions fine (with a little struggle for things like stats handling), but I have trouble figuring out what people are trying to do in many ASH scripts when I'm trying to reflect on what that function does.Ok, sounds good. Thanks for the clarification.
stat my_zodiac_stat(): Renamed to boolean in_muscle_sign(), boolean in_mysticality_sign(), boolean in_moxie_sign()Could I suggest an alternative, one that requires only one function and returns a stat instead? A stat zodiac_to_stat($zodiac) which given a zodiac, would return either muscle, mysticality, or moxie, it also more closely reflects the script that it would replace
holatuwol
06-30-2006, 09:03 PM
stat my_zodiac_stat(): Renamed to boolean in_muscle_sign(), boolean in_mysticality_sign(), boolean in_moxie_sign()
Could I suggest an alternative, one that requires only one function and returns a stat instead?* A stat zodiac_to_stat($zodiac) which given a zodiac, would return either muscle, mysticality, or moxie, it also more closely reflects the script that it would replace
It seemed to me as though the only thing that was used from that method was to compare the result to either muscle, mysticality or moxie -- in of itself, it'd never be passed to a different method that would do anything other than, once again, test the result against muscle, mysticality or moxie.* So I renamed the method to match what it'd actually be used for.* Unless there's a planned use for it that I'm not seeing?
For comparison:
if ( my_zodiac_stat() == $stat[muscle] )
{
* * buy( 1, $item[spring] );
}
else
{
* * // start adventuring with objectives.
}
vs.
if ( in_muscle_sign() )
{
* * buy( 1, $item[spring] );
}
else
{
* * // start adventuring with objectives.
}
macman104
06-30-2006, 09:16 PM
It seemed to me as though the only thing that was used from that method was to compare the result to either muscle, mysticality or moxie -- in of itself, it'd never be passed to a different method that would do anything other than, once again, test the result against muscle, mysticality or moxie. So I renamed the method to match what it'd actually be used for. Unless there's a planned use for it that I'm not seeing?Fair enough. /me scrounges for a good use that would convice holatuwol. Damn, I can't really come up with something. I guess, I'll just adjust, I just like the condensed one function thing, versus three different ones (albeit they're very similar). Your explanation makes perfect sense, so I've no qualms.
Nightmist
06-30-2006, 10:56 PM
slot item_to_slot(item): Added
This pulls the data based on where the item sits in the inventory screen (im assuming it isnt reading each item desc since that would mean massive server hitting) or is there a database somewhere that has listed information (If there is im rather interested and could someone link me).
Other then that and me being curious the rest looks good ^^. Cant wait until 8.2 =D.
Tirian
07-01-2006, 12:46 AM
In hindsight, I feel as though I was coming off as overly harsh rejecting the very first request, so this morning, I thought about adding a few of the requested functions that were self-explanatory (you know, the kinds of functions where people might think, "Why should I explain why that's a good name? The answer is DUH). But, they've disappeared (I'm guessing deleted for revision, or out of annoyance with me being a tyrant?), and I only remember two (Update: three).
A combination of the two, and furthermore I didn't want anyone else to feel like they shouldn't independently duplicate my proposals if they thought that they were good ideas out of a sense either that they were "mine" or that they had been rejected. To be frank, I was frustrated that I spent an hour writing my proposals and you gave the appearance of spending much less time rejecting them (rather than asking for further input before consideration), but I assumed that we would both be of a clearer mind over the course of time.
I still have a copy of my list and I'm going to go through it more carefully and come up with some pseudocode for the unimplemented ideas. I don't think I've got a lot of notions about why my ideas for the names of the functions are outstanding, other than the fact that I am quite certain that they are the same name that you would have devised. :)
efilnikufecin
07-01-2006, 04:51 AM
If you go as far as a code example, if it's genuinely how you'd use it (I'm hoping this is the case), you're not doing any extra work, since when I say, "Approved" your script is done, and when I say "Renamed" you just replace-all and you're set.* I wasn't joking around when I made this a sticky: if it's truly something that KoLmafia maintains internally, and provided it's something I haven't rejected before (getting the response text from a raw URL request), it will be added if you provide your code example OR if you give me a good reason for the name.
I totally agree with the rejection of the request for the response text from a raw url request. We don't need any raw url based mall bots made from kolmafia.
All of the requests I made will replace a lot of the existing contents of my icypeak.ash script. This will reduce the memory used by my script, and reduce the overall size of the script which makes editing easier. Fact is I have to re-write the script because it contains a lot of work-arounds for previous fixed glitches in kolmafia or even kol itself.
Don't worry too much about limiting it: if you can come up with all the code examples for all the internal functions you'd like access to, and you still find all of them necessary, then feel free to make your request.* Now for your suggestions (Update: So that's where the have_ prefixes came from ... the existing functions in the ASH use have_.* Okay, I've undone the renames):
I tried to parse through my script and find the functions which could be internal data. After finding all of them, I modified the names of the functions to match the general scripting commands already there. If I didn't see a comparable function the I tried to use a name that fit kolmafia's format. That is why the underscores were added to the names. For debugging I didn't use underscores in my function names so I could quickly distinguish between a built in function and one I wrote and forgot.
boolean have_mushroom_plot(): Added
effect skill_to_effect(skill): Added
skill effect_to_skill(effect): Added
boolean restore_hp(int): Added
boolean restore_mp(int): Added
int skill_cost(skill): Renamed to int mp_cost(skill)
stat my_zodiac_stat(): Renamed to boolean in_muscle_sign(), boolean in_mysticality_sign(), boolean in_moxie_sign()
OK, pretty much right back to where it started. The original function was Boolean IsZodiacStat(stat Test) in my script for the same reason you gave 3 functions. I figured my_zodiac_stat() would be similar to my_hp and my_max_hp and their mp equivalents.
It seemed to me as though the only thing that was used from that method was to compare the result to either muscle, mysticality or moxie -- in of itself, it'd never be passed to a different method that would do anything other than, once again, test the result against muscle, mysticality or moxie.* So I renamed the method to match what it'd actually be used for.* Unless there's a planned use for it that I'm not seeing?
I see one possibility...and it's a possibility only because ash does not support the feature yet, and may never support it:
case my_zodiac_stat() of
* :$stat[muscle]
* * * {
* * * //do something
* * * }
* :$stat[moxie]
* * * {
* * * *//do something else
* * * }
* :$stat[mysticality]
* * * {
* * * //do something entirely different.
* * * }
I know the formatting is poor, but the idea is there, and if you think you will ever possibly add the functionality then making it compatible now would save work in the future.
boolean have_outfit(string): Added
stat my_primary_stat(): Renamed to stat my_primestat()
boolean outfit(string): Added to supplement boolean have_outfit(string)
As a side note, I have also changed skill usage to automatically trigger restoration wherever needed, regardless of HP/MP restore settings.* Also, mp_cost does not check whether or not you have the skill; it simply lets you know what the cost of casting the skill would be if you had the skill.* Passives return a value of zero.
At this point I must say great! That's the majority of my requests with mild renames of the functions. It is not hard at all to adapt to the new names.
One question: does skill usage automattically trigger restore after using the skill as it does when auto restore is turned on, or just before?
int adv_per_cast(skill): KoLmafia does not maintain this data.* The buffbot module recalculates it whenever it needs to for buffs, which are easy, since there are well-defined rules for when it's 5, 10 or 15, and you have the luxury of assuming a rock and roll legend for anyone running a buffbot, but other than that, KoLmafia has no idea what the adventure yield is for each skill.
I was unaware of that. I already have the function written that returns this data anyway so I am OK with it. The function isn't as massive as one might believe, it's just very hard to read because I condensed it as much as I could.
All in all I have to say thanks a million for your efforts. The changes are going to be great, and since icypeak.ash was running on the slow side on my machine, I will definitely be glad to take some of the data return functions out of it. The thread on this board for my current icy peak script is going to be moved to outdated scripts as soon as I do some editing.
holatuwol
07-01-2006, 08:44 AM
... or is there a database somewhere that has listed information (If there is im rather interested and could someone link me).
The item data table (tradeitems.dat) stores how the item should be "used".* This ranges from using the item, using the item from the restores screen, using the item multiply, eating or drinking the item, transforming the item into a familiar, or equipping the item into an available slot.
I don't think I've got a lot of notions about why my ideas for the names of the functions are outstanding, other than the fact that I am quite certain that they are the same name that you would have devised.
Don't worry too much about explanations of the names: the code samples are intended to replace that explanation, in the event that an explanation cannot be constructed.
Before I posted my rejection notice, I did recognize that each function had at least one or two sentences detailing how it would be used, so I knew that time had been invested in describing the use of the functions you wanted added, and a part of me thought, "Hey, he showed a substantial effort, I should let this slide."* At the same time, I felt it'd be a bad precedent to accept the functions as presented, as you hadn't done what I'd asked at all.
It took me awhile to come up with an idea to present the information I requested without resorting to full-blown legibility discussions (code samples), so while I didn't spend as much time as you did creating the proposal, it wasn't an immediate dismissal, as it might have appeared.* When I was replying, it was supposed to read as, "Probably yes, but follow instructions first," but I'm guessing that it read as, "No, the iron fist has spoken, go away."
Also, by providing code samples, I can ask questions like, "Is this easier to read, or is this easier to read?" based on the kinds of functions people are writing.* I'd just like to make it easier for me to discuss things, and rather than coming up with my own code examples (which might look nothing like how you guys wind up using them), using your code examples helps communication.
I guess, I'll just adjust, I just like the condensed one function thing, versus three different ones (albeit they're very similar).* Your explanation makes perfect sense, so I've no qualms.
If I weren't going for readability, I'd have liked the condensed one function version as well, as it is the easiest way to think about things once you're used to imperative programming.* Simply call a function, cache its result, and test its value along the way.* But, I've also discovered that it's definitely not the natural way to read things.* So, unless stats are not being used strictly for equality tests, I've come to prefer allowance of multiple functions.
On that note, I might break on the stat day test if someone shows me a decent script with some legible function names, since KoLmafia does handle that data internally and the CLI already has that test available.* You can totally forget about holiday tests, though.
If I didn't see a comparable function the I tried to use a name that fit kolmafia's format. That is why the underscores were added to the names.
Oh no, I was looking at the "have" portion, actually.* I was wondering why it was that the functions weren't something like "has_" as it's more natural for me to say "has" than "have".* Then I realized that all of the ASH functions were have_ not has_.
One question: does skill usage automatically trigger restore after using the skill as it does when auto restore is turned on, or just before?
It used to always trigger after casting a skill (as well as before casting a skill), but this has not been true for some time, and nobody has reported any bugs regarding "loss in functionality" -- this means that whoever relied on it before has stopped relying on it now, or it's so infrequently required that nobody ever noticed.
Tirian
07-02-2006, 12:18 AM
Okay, you've already taken care of four of my proposals (in_hardcore, item_to_slot, have_outfit, and skill_to_effect -- I was only using has_equipped as an example of something that we could do with item_to_slot, but I sure don't mind it being added to ASH!), but while I was coming up with all of my code samples three new ideas came into my mind. Enjoy!
int pulls_remaining() - The number of pulls that I have remaining from Hagnk's today. I suppose that if I'm in softcore but not in ronin it would return a very large number and if I'm in hardcore but haven't rescured the king it would return 0.
void pull_for_feng_shui()
{
if (pulls_remaining() < 3)
{
print("Sorry, you don't have enough pulls to get all the pieces");
return;
}
take_storage(1, $item[decorative fountain]);
take_storage(1, $item[Feng Shui for Big Dumb Idiots]);
take_storage(1, $item[windchimes]);
use(1, $item[Feng Shui for Big Dumb Idiots]);
}
Note that without the pre-check, I'd have wasted a pull or two that I might have used for something productive.
int ronin_remaining() - The number of adventures of ronin left. This seems like the opposite of pulls_remaining, returning -1 if I'm out of ronin and a very very large number if I'm in hardcore.
This sample is going to miss twenty different levels of subtlety, but let's assume for the moment that it's a fighter character who has already eaten and doesn't have Ode to Booze but would want to save as much drinking as possible for a post-ronin buffbot visit.
[...]
while (my_adventures() < ronin_remaining() && my_inebriation() + 4 <= drunkenness_limit())
{
drink(1, $item[fuzzbump]);
}
[...]
int drunkenness_limit() - returns either 15 or 20 depending on whether you have Liver of Steel. See the code sample above.
int still_lights() - It would be a nice part of a bedtime script to just make enough tonic waters to clear out the still. Maybe you're not catching this one at the moment.
[...]
buy(still_lights(), $item[soda water]);
create(still_lights(), $item[tonic water]);
[...]
boolean can_equip(item it) - Do I satisfy the stat requirements to equip this item?
This code sample is from the adventure-boosting portion of my bedtime script, specifically the part where you pick what weapon to wear.
boolean wear_if_can_and_have(item it, boolean worth_a_pull)
{
if (!can_equip(it)) return false;
if (item_amount(it) == 0)
{
if (!worth_a_pull || storage_amount(it) == 0 || pulls_left() == 0) return false;
take_storage(1, it);
}
equip(it);
return true;
}
boolean new_manage_arms()
{
if (wear_if_can_and_have($item[time sword], true)
{
if (have_skill($skill[Double-Fisted Skull Smashing]))
pull_to_wear($slot[off-hand], $item[time sword]);
return true;
}
item sword = $item[chrome sword];
item xbow = $item[chrome crossbow];
item staff = $item[chrome staff];
if (wear_if_can_and_have(sword, false) return true;
if (wear_if_can_and_have(staff, false) return true;
if (wear_if_can_and_have(xbow, false) return true;
if (wear_if_can_and_have(sword, true) return true;
if (wear_if_can_and_have(staff, true) return true;
if (wear_if_can_and_have(xbow, true) return true;
return false;
}
At the moment, manage_arms() is much longer because I have to query for moxie and muscle for each weapon instead of being able to pass it to the helper function. (Note also the use of pulls_left() so that I wouldn't have to check after the pull to make sure that it succeeded.)
item familiar_equipment(familiar pet) - I suppose that there is at least one familiar with more than one piece of specific equipment, but knowing the general one and having the new ones being added as quickly as they are supported in KoLmafia would be great.
This might be a little trickier, so I'll show you part of the code as it exists at this moment and you'll see the dilemma. This is something that I would run just out of ronin that would put all of the familiars in their gear. I've got a map elsewhere that contains the data except that it falls out of date more regularly than your data does.
boolean dress_pet(familiar pet)
{
item it = Mfam_equipment[pet];
if (item_amount(it)==0) return false;
if (!equip_familiar(pet)) return false;
if (!equip(it)) return false;
if (item_amount(it)>0) sell_item(item_amount(it), it);
return true;
}
void main()
{
familiar at_start = my_familiar();
foreach pet in Mfam_equipment dress_pet(pet);
equip_familiar(at_start);
}
The hitch is that I am using Mfam_equipment both for its associative qualities and as an iterator through the familiars. I suppose that exposing some data as an immutable map instead of a function might be more an offer than you had in mind, but you might be able to come up with a way around the problem.
boolean is_song(skill sk) and int song_count() - I'm glad that you implemented the skill to effect function. If part of your mood overhaul is a greater attention to AT buffs and their limitations, then this would be another useful thing to expose to scripts.
Here is part of my working code, in which this is implemented with a set (by which I mean a map in which the values are irrelevant) and another function.
boolean skill_upkeep(skill sk)
{
if (!have_skill(sk)) return false;
if (have_effect(Mskill_to_effect[sk]) > 0) return true;
if (Ssong contains sk && active_songs() == 3) return false;
use_skill(1, sk);
return (have_effect(skill_to_effect(sk)) > 0);
}
void main()
{
[...]
if (my_maxmp() >= 15) skill_upkeep($skill[empathy]);
if (my_maxmp() >= 12) skill_upkeep($skill[leash of linguini]);
if (my_maxmp() >= 40 && my_level() < 11) skill_upkeep($skill[aloysius' antiphon of aptitude]);
if (my_maxmp() >= 7) skill_upkeep($skill[polka of plenty]);
[...]
}
boolean can_adventure(location spot) - I know that there are a few spots where you determine if a location is legal for adventuring before visiting. It would be similarly useful for us to not have to calculate if the Icy Peak or Valley was unlocked. Ideally, this functionality could eventually be strengthened to cover most of the locations and checking stat values and/or zodiac signs or whatever else would be necessary to pre-determine if an adventure would be legal. In the mean time, I would accept that this function would throw an error message and abort if it was queried about a location that you didn't have a test for.
I'm not sure exactly how pervasive the current functionality would be, but as I'm pretty sure you check the Valley at the moment, we could check to make sure that they don't accidentally try to get the abridged dictionary twice:
{
[...]
if (can_adventure($location[valley beyond orc chasm]))
{
print("You have already finished the dictionary subquest!");
return true;
}
[...]
}
efilnikufecin
07-02-2006, 08:25 AM
boolean have_familiar(familiar tocheck) returns true if you have the familiar either in your terrarium or equipped.
if(have_familiar($familiar[coffee pixie]))
* {
* equip_familiar($familiar[Coffee pixie]);
* }
* else
* {
* equip_familiar($familiar[leprechaun]);
* }
This would be an alternate to previously used code:
equip_familiar($familiar[leprechaun]);
cli_execute("familiar.php?action=newfam&newfam=22");
which did the exact same thing but if you have the coffee pixie then the leprechaun would be equipped followed by the Coffee Pixie.
The reason for the direct link is to avoid halting of the script when you don't have the familiar. I don't know if kolmafia still aborts at this moment, but I do know that it once did, and this was the workaround I came up with.
How does kolmafia currently handle the following?
equip_familiar($familiar[leprechaun]);
equip($item[lucky tam o shanter]);
I haven't tried it, but kolmafia's familiar trainer steals familiar equipment from other familiars as needed. Is this also the case with scripted commands to equip an item?
Presto Ragu
07-03-2006, 12:01 PM
I go into these suggestions with my eyes wide open. In other words, I do not expect them to be welcomed with open arms, if they are welcomed at all. The reasoning behind that is because I know there is potential for abuse, even potential that I can not see. But I have tried to eliminate that abuseability of them as much as possible.
That being said:
Store managing helper:
boolean at_mall_minimum( [item to check])
example:
if( at_mall_minimum( $item[disco mask]))
{
take_shop( shop_amount( $item[disco mask]), $item[disco mask]);
sell_item( $item[disco mask]);
}
The intended functionality is to be able to check your store for all of those items sitting at minimum selling price. That way you can just take them out and autosell them, since the likelihood of them selling at that price is pretty slim. (and since not every item mins at 100 meat, it is difficult to scan them using the store manager to see which ones should be removed.)
On a related note... With the autoselling price change that is coming up... I do not know how simple it will be to add the requested functionality... It might just be better to wait and see how that turns out before going forward.
Mall purchasing helper:
boolean cheaper_to_farm( [item to check])
example:
if( cheaper_to_farm( $item[box]))
{
while( item_amount( $item[box]) < 1)
{
advnture( 1, $location[fun house]);
}
}
else
{
buy( 1, $item[box]);
}
The thought behind this one is that mafia tracks the approximate drop percentage of an item and can rough guess the average number of adventures it would take to farm any given item. Even if we give an arbitrary amount to the "price" of an adventure farming... Say, 1000 meat. Mafia can guess if it would just be cheaper to farm an item than buy one in the mall.
Now, I realize that most of the time cheaper_to_farm() will return true... But it would give scripters a minimal way to compare the mall prices of a given item, to make sure they are getting something of a deal...
And to cover my bases, if an item that is manufactured is checked (like a nothing-in-the-box) it should always return false. Also, as a secondary thought, have the "price per adventure" user definable. Now that global variables are allowed, there can be an optional system used variable: float adventure_price. That the individual scripter can set at the beginning of their script to use with cheaper_to_farm().
Of course... Not being aware of how the drop percentage is stored, this might be more work that its return value....
But then I am just thinking out loud anyway.
Veracity
07-03-2006, 01:59 PM
boolean have_familiar(familiar tocheck) returns true if you have the familiar either in your terrarium or equipped.
OK.
I haven't tried it, but kolmafia's familiar trainer steals familiar equipment from other familiars as needed. Is this also the case with scripted commands to equip an item?
Yes. The familiar-item-stealing is built into EquipmentRequest, so it will kick in any place in KoLmafia where you try to equip a familiar item.
I'll demonstrate the new function and equipment stealing:
print( have_familiar( $familiar[feather boa constrictor] ) );
print( have_familiar( $familiar[leprechaun] ) );
familiar fam = my_familiar();
item it = current_equipment( $slot[familiar] );
print( "Current familiar = " + fam + " wearing " + it );
equip_familiar( $familiar[leprechaun] );
equip( it );
print( "Current familiar = " + my_familiar() + " wearing " + current_equipment( $slot[familiar] ) );
equip_familiar( fam );
equip( it );
print( "Current familiar = " + my_familiar() + " wearing " + current_equipment( $slot[familiar] ) );
yields:
>*fam.ash
false
true
Current familiar = Cheshire Bat wearing annoying pitchfork
Putting Grinning Grrl the Cheshire Bat back into terrarium...
Taking Lucky Grrl the Leprechaun out of terrarium...
Request completed.
Stealing annoying pitchfork from Cheshire Bat...
Putting on annoying pitchfork...
Gear changed.
Request completed.
Current familiar = Leprechaun wearing annoying pitchfork
Putting Lucky Grrl the Leprechaun back into terrarium...
Taking Grinning Grrl the Cheshire Bat out of terrarium...
Request completed.
Stealing annoying pitchfork from Leprechaun...
Putting on annoying pitchfork...
Gear changed.
Request completed.
Current familiar = Cheshire Bat wearing annoying pitchfork
Script succeeded!
efilnikufecin
07-04-2006, 04:44 AM
Thanks Veracity!
I have another. Well it's not data, but it's a feature that kolmafia has built into the store manager...or similar anyway. I like the "end of run sale" feature, but I always have items I do not want kolmafia to modify the price of in my store. I would however like to put items like dry noodles, reagents, and cocktailcrafting ingredients in the mall and have kolmafia figure the price of those items based on the same principles it uses to price items in the main interface.
Best name I can see would be:
undercut_item(item tosell)
My personal preference would be that it would take all of that item in my inventory and place it in the mall at the price it would have done so in the event that I used the put_shop command followed by the undercut cli command. The key here is that it would not change the price of any other item in my store including the 999,999,999 priced items.
use_skill($skill[Pastamastery]);
undercut_item($item[dry noodles]);
Then my [insert item here] would not end up sold before I actually want to do so. Leaving the item tucked away in the mall is a way of preventing mistakenly sending it in a kmail when I didn't want to do it.
another minor clarification: My preference would be that it didn't care what the price already was on the item if in my store already. The net effect would be re-pricing the items each time as needed. Also, in the event that the item isn't in inventory but in my store, if the function is called then i think the results should be re-pricing what is alredy there.
Tirian
07-06-2006, 01:45 AM
Take your pick. :)
string last_encounter() - the name of the monster or non-combat encounter name faced most recently. If the enounter listing is empty, then this can return null.
int encounter_listing(string encounter) - this would return the number of times that the listed monster name or non-combat enounter name was faced in this session.
If anyone has been living under a rock and wants to spade out the new zone for themselves, they shouldn't read this code sample.
void white_citadel()
{
cli_execute("guild.php?place=paco");
while (last_enounter() != "It's A Sign")
{
adventure(1, $location[whitey's grove]);
}
item glider = $item[hang glider];
boolean have_a_glider = false;
while (!have_a_glider || last_encounter() != "Summer Holiday")
{
adventure(1, $location[the road to the white citadel]);
if (item_amount(glider) > 0) have_a_glider = true;
}
cli_execute(...);
cli_execute("guild.php?place=paco");
}
holatuwol
07-08-2006, 05:29 AM
int pulls_remaining(): Added
int drunkenness_limit(): Renamed to int inebriety_limit()
int still_lights(): Renamed to int stills_available()
boolean can_equip(item): Added
item familiar_equipment(familiar): Added
int ronin_remaining():* KoLmafia calculates this on the fly; it does not maintain this information.* However, there is a very similar function which may help ASH scripts calculate this as well, and that has been added instead.
boolean can_adventure(location): Since KoLmafia can only do this by going to the server, this doesn't count as internal data.* Therefore, this request has been rejected.
boolean is_song(skill): KoLmafia calculates this on the fly (it converts the skill to an ID and checks to see if the ID is between 6001 and 7000); it does not maintain this information.* If it does get transformed into internal information (ie: the calculation gets centralized somewhere), this might become available.
int song_count(): KoLmafia calculates this on the fly, though in a way much messier than the previous one (it converts each effect to a skill, then the skill to an ID, then if the ID is between 6001 and 7000, and adds up the result); it does not maintain this information.* If it does get transformed into internal information (ie: the calculation gets centralized somewhere), this might become available.
boolean at_mall_minimum(item): I'm not sure what the "at mall minimum" function is intended to do?* Is this function testing if the current price is twice autosell or at exactly 100 meat, or...?
boolean cheaper_to_farm(item): KoLmafia doesn't track where items drop; it merely tracks what items drop where.* The difference is subtle, but it means that this function is not "internal data" at this time.
void undercut_item(item):* Every time an item is added, KoLmafia's memory of all the other items' prices are wiped.* This is why undercutting occurs in bulk, rather than one at a time, as KoLmafia always goes to the server to refresh this information.* So, if I were to add this function, it'd be two server hits per undercut, and it'd hit the slowest of the servers ... as such, no.
string last_encounter(): KoLmafia doesn't store this data anywhere ... it simply registers the encounter and throws the information away.* So, there's no way to provide this information.
int encounter_listing(string): This requires a little bit of code adjustment, and while a few of the others involved this as well, this is one of those, "Help you automate brand new content => no" features.
int my_turncount(): Added
Presto Ragu
07-08-2006, 08:02 PM
boolean at_mall_minimum(item): I'm not sure what the "at mall minimum" function is intended to do? Is this function testing if the current price is twice autosell or at exactly 100 meat, or...?
Well, it would be twice autosell, or 100 meat. Whichever is higher. But with the looming autosell nerf, I am not certain 2x autosell will be the actual minimum. So do not feel bad if you do not feel like adding it.
boolean cheaper_to_farm(item): KoLmafia doesn't track where items drop; it merely tracks what items drop where. The difference is subtle, but it means that this function is not "internal data" at this time.
Understood. I suspected that might be the case. But it was the best "non-abusable" way I could think of for checking purchase prices to make sure a scripter was not getting royally screwed on a buy command.
Thanks for the consideration.
BDrag0n
07-30-2006, 09:14 AM
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:
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
if(stat_today=$stat[none])
{
* cli_execute( "call clan\statbuff");
}
else
{
cli_execute( "call clan\"+stat_to_string(stat_today)+"buff")
}
holatuwol
07-31-2006, 08:43 PM
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
08-10-2006, 07:40 PM
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:
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
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
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
08-11-2006, 03:54 AM
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)??They're pulled from monsters.dat and modifiers.dat, you can see them in the data folder of the SVN repository (http://svn.sourceforge.net/viewvc/kolmafia/src/data/)
Nightmist
08-11-2006, 04:03 AM
They're pulled from monsters.dat and modifiers.dat, you can see them in the data folder of the SVN repository (http://svn.sourceforge.net/viewvc/kolmafia/src/data/)
>> Yeah... ok thats a new .dat file. >> So wasnt in 8.5 release... *Checks his 8.6*... Yup >> Ok thanks. =)
macman104
08-11-2006, 04:12 AM
>> Yeah... ok thats a new .dat file. >> So wasnt in 8.5 release... *Checks his 8.6*... Yup >> Ok thanks. =)
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 (http://svn.sourceforge.net/viewvc/kolmafia/src/net/sourceforge/kolmafia/KoLCharacter.java?r1=1198&r2=1200&pathrev=1200)
but was moved to it's own file
Mon Aug 7 08:22:43 2006 UTC (3 days, 19 hours ago) by shweiAnyway, 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 :o).
Veracity
08-11-2006, 05:06 AM
They're pulled from monsters.dat and modifiers.dat, you can see them in the data folder of the SVN repository (http://svn.sourceforge.net/viewvc/kolmafia/src/data/)
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:
* * 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
08-12-2006, 07:07 PM
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:
//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:
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
08-12-2006, 11:08 PM
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
08-13-2006, 10:34 PM
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:
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
08-14-2006, 02:34 AM
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
08-14-2006, 03:11 AM
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.
You are correct, so I added one.
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
08-14-2006, 04:56 AM
Holatuwol, did my safeadv(location) function, on the last page get rejected? or missed? or is it still stewing?
macman104
08-14-2006, 08:33 AM
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).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
08-15-2006, 06:23 AM
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.
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
08-16-2006, 05:48 AM
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...
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
08-17-2006, 10:36 PM
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.
Powered by vBulletin® Version 4.1.12 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.