TraFa - The familiar helper

TraFa 1.7 - The familiar helper
Training Familiars the Mafia way.

This hodgepodge of ash functions will do a variety of things depending on how you set up the user preferences at the beginning of the script. Hurray for my first published script! Kolmafia ash scripting is the first scripting I've ever done and I'm still fairly unsure of my work, so feedback please! Comments & suggestions on ways to clean up the code and reduce server hits is most welcome!

Requires Zlib.

User Preferences

boolean trainall
string famtotrain
int trainweight
int trainturns
If trainall is true the script will train any of your collected familiars whose base weight is < trainweight for trainturns amount of turns or until all familiars base weight equals trainweight.
If famtotrain is anything other than empty quotation marks the script will train the famtotrain while it's base weight is < trainweight for trainturns amount of turns. Uses mafia's fuzzy matching (i.e. "lep" = "Leprechaun").

boolean trophy_train
boolean buytrophies
If trophy_train is true the script will check the total weight of your terrarium and current familiar weight trophies and then train each familiar one pound until the next trophies weight requirements are met or until trainturns reaches zero. If you don't have enough familiars for the next trophy it will tell you how many more you need to collect before you can obtain that trophy, but it will still attempt to train if you have familiars whose base weight is less then 20 lbs.
If buytrophies is true after the training the script will attempt to buy any familiar weight trophies you qualify for as long as you have enough meat.

boolean arena_tt
boolean arena_wt
string locale
If arena_tt is true the script will train familiars in the arena until either they reach the trainweight or trainturns reaches zero.
If arena_wt is true the script will train familiars in the arena until they reach the trainweight. Please note that if arena_wt is true trainturns is disregarded.
If arena_wt & arena_tt are false the script will train familiars by farming with them at locale until either they reach the trainweight or trainturns reaches zero.

boolean get_fe
If get_fe is true the script will check which of your familiars are missing their familiar specific equipment and then obtain it. It evaluates whether it would be cheaper to buy the equipment or to train in the arena for it.

boolean feed_stocking
If feed_stocking is true any time the script uses your stocking mimic it will try feed it to gain weight. The script will buy the cheapest candy and feed your stocking.

Uses Mafias valueOfAdventure.
The default for this setting is 500. To change it type
set valueOfAdventure=X into the cli, where X is the value you want to set it to.

The valueOfAdventure is the value of one adventure and should be set to the average amount of meat you make per adventure. Obviously the more meat you make the more meat is lost with every adventure not used farming. If you train a familiar 2 times in the arena not only does it cost you 200 meat(100 per arena match), it also costs you the meat you would have made if you had used those adventures elsewhere. This will change from time to time depending on what areas a character has access to, what they are wearing, etc., etc. Anyways, this is factored into the familiar equipment obtaining logic to make sure meat is not wasted by getting the equipment in the arena.


Notable Functions:

void faminfo()
Prints various info about your familiars. It tells you the total base weight of all the familiars in your terrarium, it lists which familiars you have and haven't collected, it tells you how many familiars you've collected out of the total currently available. Of the familiars you have collected it tells you their base weight, if they have their familiar specific equipment, and if they have a 100% run associated with them. Also tells you exactly how many tour guide runs you've completed. Use finfo("missing") for a list of familiars you have not collected yet. See aliases in the preceded post.

boolean have_fe(familiar famtocheck)
Returns true if you have the familiar specific equipment for famtocheck. This works without switching out your current familiar.

boolean famequip(string famtoequip)
Equips the famtoequip with their familiar specific equipment. If you don't have it it will obtain it first. Returns true upon successfully equipping famtoequip.

boolean tune(string to_tune)
Tunes your Frumious Bandersnatch to the stat specified in to_tune. Valid arguments for to_tune - moxie, muscle, mysticality, mox, mus, & myst.

boolean feast(familiar famtofeed)
Ruturns true if it successfully gorges famtofeed with the Moveable Feast or if famtofeed is already extremely well-fed. Using feast() without passing a familiar attempts to gorge your currently equipped familiar. Each day, after the Moveable Feast has been used five times the script sets the property "_feastDepleted".

hatter.ash, The Function:
boolean hatter(string command)
Returns true if it successfully gets a buff from the Mad Hatter. For the most part it works the same as the hatter.ash script. For a valid list of command arguments see the main hatter.ash thread.

Sellbot(#1053259) functions:
int[item] sellbot_gifts()
Returns a map of the items currently being sold by Sellbot and their price.
boolean sellbot_buygift(int amount, item gift)
Attempts to buy amount gift from Sellbot. Returns true if it successfully buys gift from Sellbot.
boolean sellbot_buygifts(int[item]gifts)
Attempts to buy the requested amount of each item in gifts from Sellbot. Returns true if it successfully buys from Sellbot.
boolean sellbot_buygifts(boolean[item]gifts)
Attempts to buy one of each item in gifts from Sellbot. Returns true if it successfully buys from Sellbot.


If you find this script useful donations in the form of in-game ninja paraphernalia are always appreciated! Thanks and enjoy the script!

Change log:
09.22.09 - The faminfo() function now also displays which familiars have a 100% run.
10.18.09 - Fixed version tracking. Small tweak in how faminfo() is displayed.
11.19.09 - v1.1 Added special handling of familiars that cannot be trained in the arena.
12.01.09 - v1.2 Trophy training now trains the lightest familiar first. Now uses the valueOfAdventure Mafia setting instead of adv_value.
12.02.09 - v1.3 Fixed some bugs with familiar weight trophy detection & buying. Cleaned up the code.
01.11.10 - v1.4 Fixed a bug that was preventing 100% runs from being parsed correctly, added a tour guide run count to faminfo(), added special handling for bander equipment, added support for the stocking mimic.
06.01.10 - v1.5 Re-factored code, changed prints to vprints, changed aborts to exits, improved familiar equipment obtaining logic, added tune() function, added special handling for various familiars. See details here.
10.02.10 - v1.6 Re-factored code some more, added the feast() function, special handling for the Hipster, Stocking Mimic is no longer calculated or trained when trying to get the trophies, fixed a bug when training arena handicapped familiars.
05.29.11 - v1.7 Re-factored code, Holiday Log support, Sellbot(#1053259) support & functions, hatter() function, gets the Three Days Slow buff from the Mad Hatter, now maximizes familiar xp when combat training.
 

Attachments

  • trafa.ash
    42.1 KB · Views: 153
Last edited:
If that's not enough trafa fun for you, here are some useful aliases that utilize this script. (Of course, feel free to alter these to meet your specific needs. These are just examples I made and tested recently when I learned about the joy of aliases! The ash functions in these are explained above. Change their values before you set the aliases for optimal performance.)

alias efam => ashq import <trafa.ash> if(length("%%") != 0) famequip(to_familiar(substring("%%",0,length("%%")-1))); else famequip(my_familiar());
Equips a specified familiar with it's familiar specific equipment. Obtains it's equipment if you don't already have it. Uses mafia's fuzzy matching. For example, you could type "efam lep" or "efam star" sans quotes to equip your Leprechaun or Starfish. Passing no familiar attempts to equip your current familiar.

alias efall => ashq import <trafa.ash> getfamequip();
Obtains and equips all collected familiars with their familiar specific equipment.

alias finfo => ashq import <trafa.ash> faminfo();
Prints a good deal of info about your familiars. (see faminfo above)

alias fmiss => ashq import <trafa.ash> faminfo("missing");
Prints all the familiars you are missing.

alias ttrain => ashq import <trafa.ash> trainturns=%%; arena_wt=false; locale="castle"; trophytrain();
Trains your familiars for the next weight trophy by farming at the Giant's Castle for the specified amount of turns. (i.e. "ttrain 20")

alias tfam => ashq import <trafa.ash> trainturns=%%; trophy_train=false; arena_wt=false; arena_tt=false; locale="castle"; famtotrain=to_string(my_familiar()); trainweight=20; trainone();
Trains your current familiar at the Giant's Castle for a specified amount of turns or until it reaches base weight 20. (i.e. "tfam 5")

alias tfamw => ashq import <trafa.ash> trophy_train=false; arena_wt=true; famtotrain=to_string(my_familiar()); trainweight=%%; trainone();
Trains your current familiar at the arena until it reaches base the specified train weight. (i.e. "tfamw 20")

alias tfamt => ashq import <trafa.ash> trainturns=%%; trophy_train=false; arena_tt=true; arena_wt=false; famtotrain=to_string(my_familiar()); trainweight=20; trainone();

Trains your current familiar at the arena for the specified number of turns. (i.e. "tfamt 5")

alias tf => ashq import <trafa.ash> use_familiar($familiar[%%]); trainturns=my_adventures(); trophy_train=false; arena_wt=false; arena_tt=false; locale="castle"; famtotrain=to_string(my_familiar()); trainweight=20; trainone();
Trains a specified familiar at the Giant's Castle until it reaches base weight 20. For example, you could type "tf lep" or "tf star" sans quotes to train your Leprechaun or Starfish.

alias tune => ashq import <trafa.ash> tune("%%");
Tunes your Frumious Bandersnatch to the stat passed. (i.e. "tune myst")

alias feast => ashq import <trafa.ash> if(length("%%") != 0) use_familiar(to_familiar(substring("%%",0,length("%%")-1))); feast();
Gorges a specified familiar with the Moveable Feast. Uses mafia's fuzzy matching. For example, you could type "feast lep" or "feast star" sans quotes to gorge your Leprechaun or Starfish. Passing no familiar attempts to gorge your current familiar.

alias sellbot => ashq import <trafa.ash> int[item]inv = sellbot_gifts(); print_html("<a href='displaycollection.php?who=1053259'>Sellbot inventory:</a>"); foreach itm, int in inv print(itm + " - Cost: " +int);
Prints Sellbot(#1053259) gift item inventory and each items cost.
 
Last edited:

dj_d

Member
Nice work! This looks very cool.

Eatdrink.ash has a "value of an adventure" variable that, right now, is eatdrink_valueOfAdventure. I will probably leave it because of inertia and user expectation, but if I need to get that info again, I'll probably use your common variable.
 

zarqon

Well-known member
Yeah, this is super nifty. I very seldom train familiars, but when I do I'll probably do it using this script. But I'm really enjoying the thoroughness of fam_info(). Very handy.

And, there's a small error in line 346:

Code:
check_version("TraFa","trafa","1",17241);

That last number should be the thread number for your script, in this case 2575. And unfortunately, no one will know when you fix it! :)
 
@dj_d: I was thinking eatdrink had a "value of an adventure" variable it just seemed like this variable could be used for a lot of scripts, so I decided to make it global.

@Z: I was wondering why that wasn't working. I was going to ask about it, but I got sidetracked. Thanks.

Thank you both for the feedback. :D I'm glad you guys like it.
 

HikerMike

New member
Using your script to equip all my familiars. It gets to the Pet Rock:

Checking familiars equipment...
Searching for pet rock "Snooty" disguise...
Don't know how to train a Pet Rock yet.

Then stops. Is this an error?
 
Yes, this is something I was unaware of when I wrote this script. Thanks for the heads up.

Update v1.1

Added special handling of familiars that cannot use the arena to train. (Pet Rock, Toothsome Rock, Bulky Buddy Box) This is untested.
 

HikerMike

New member
Another problem....

I am using the script to get my fam weight trophies. Already cleared 300 and on the way to 500. I had my semi-rare counters set from eating Fortune Cookies and the script blew right through them then errored out:

[5024] Cake-Shaped Arena
Mosquito gains 5 experience.
Round 6: Mosquito vs. Scurvy Cur...
Fortune Cookie counter expired.
Unexpected error, debug log printed.
 

HikerMike

New member
No - I just let mafia tell me when a window comes up, then I manually adventure in the area I want the semi-rare. Usually scented massage oil or irradiated pet snacks.

Also, TraFa goes through familiars in alphabetical order. I wonder if it would be more efficient to go by weight? Low weight fams earn weight much more quickly than high weight ones (thus less meat needed). So fewer turns and less meat needed for equivalent weight, at least for the close to 0 weight fams.
 
I don't think I've ever had this script running when a semi-rare counter expired. I'll try and do some tests on that soon.

TraFa goes through familiars in alphabetical order. I wonder if it would be more efficient to go by weight?
Not a bad idea. How many turns/meat do you estimate adding this feature would save? I think it would only really make a significant difference for those people with upwards of 35 familiars. Honestly the reason I added the string locale was so I could castle farm while training my familiars for the weight trophies. I never even considered utilizing the arena as the sole means to train for the trophies.
 
Last edited:

zarqon

Well-known member
It would be significantly more efficient to always train the lightest familiar rather than training each familiar up to 20 lbs before continuing. The easy way would be to have a function that chooses your lightest familiar, and then train that one up a pound -- then keep running that, choosing the lightest familiar every time. The more involved but more efficient way would be to calculate how many pounds each familiar needs to gain, to avoid all that familiar swapping, then run that.

For example, suppose we want to train the following terrarium up to 50 lbs. using a sequential algorithm:

a - 18 lbs +2 (76 exp)
b - 1 lb +12 (169 exp)
c - 6 lbs
d - 1 lb
e - 10 lbs

Total experience needed: 245

Starting with familiar a would take a good bit of turns just to get those last 2 pounds, whereas if you distribute the needed weight (14 lbs) over the lightest familiars, familiar a will never even be trained, for a significant overall savings in turns (and meat, if you're using the arena):

a - 18 lbs
b - 1 lb +7 (64 exp)
c - 6 lbs +1 (13 exp)
d - 1 lb +6 (49 exp)
e - 10 lbs

Total experience needed: 126

That's a difference of 119 experience, just to get +14 pounds. Even assuming you get 5 exp every time in the arena, that's a savings of 24 turns. If you're adventuring for that weight, it's a much more significant turn savings.
 
Last edited:

lostcalpolydude

Developer
Staff member
Assuming there's a reasonable way to count how many familiars you have, the simplest way to find the target weight to use is ceiling(500.0/numFamiliars), turned into real code of course. This will probably lead to some familiars being trained 1 lb more than necessary. You could train 500 % numFamiliars to ceiling(500.0/numFamiliars) and numFamiliars - (500 % numFamiliars) to floor(500.0/numFamiliars), which means that there's very little waste as long as none of your familiars already weigh more than ceiling(500.0/numFamiliars). None of these would be perfect, but they're all pretty close, and they should be a lot easier to implement than the perfect case. (The perfect case, by the way, means you figure out the best time to let effects like white candy heart run out when it isn't needed to finish training a familiar, and you switch between familiars to save on that type of stuff as much as possible. I doubt anyone needs that level of perfection though, just stick with what's reasonable.)
 

HikerMike

New member
This should be the only time I have to do this. I am killing time right before Crimbo in aftercore right now. I only run one character. I am cleaning up a bunch of OCD stuff this aftercore - making recipes, drinks, jewelry, tattoos, aqua de vida, and getting the familiar trophies. I have about 36 familiars including the rocks that can't be trained. I was looking for an easy way to finish them up to 300 lbs which I was close to and found your script. Then I figured, geez, once at 300 may as well get the 500 lb trophy and I never have to do them again. I first started adventuring in the castle but getting experience there was burning too many turns. It is easier to train in the arena and then go farm for meat in the castle with meat increasing fams when needed.
 
Update v1.2

Trophy Training now trains the lightest familiar first.
Now uses the valueOfAdventure Mafia setting instead of adv_value.

I am using the script to get my fam weight trophies. Already cleared 300 and on the way to 500. I had my semi-rare counters set from eating Fortune Cookies and the script blew right through them then errored out...

I just tested this while running Bale's wonderful CounterChecker and it farmed the semi-rare just fine. Further testing without a counter script running is required, but for now I would suggest looking into CounterChecker.
 
Update v1.3

Fixed a bug with familiar weight trophy detection & buying.
Other minor bug fixes.
Cleaned up the code a bit.

I had my semi-rare counters set from eating Fortune Cookies and the script blew right through them then errored out

I've tested this over half a dozen times now with and without a counterscript running and cannot reproduce this behavior. Without a counterscript it aborts. With a counterscript it farmed the simi-rare and continued on its merry way.
 

HikerMike

New member
Thanks for the updates! Sorry I can't provide more info on what happened with the semi-rare window - I just copy pasta-d what happened to me. BTW, 500 lb trophy, achieved!
 
Small bug report: My bander has a charpuce jub-jub. Using the "efall" alias, TraFa decided that since it didn't have an aquaviolet jub-jub, obtaining one was necessary.

This is not really a bug in your code, just a result of the bander having a squeezable equipment and Mafia only being able to give one of the forms in familiar_equipment(). Still, a special case for the bander would be nice. (I think the Frog has zappable equipment, so he might need a special case too -- I don't have one so I can't test.)
 
Top