aqualectrix
Member
PriceAdvisor 1.62
PriceAdvisor requires SmashLib and ZLib, and daily build 7915 or greater (13.8 will work).
Have you ever looked at your inventory and wondered, What's the most meat I could make with this item? Are you chafing at the confines of comparing mallsell to autosell? Do you wish you could price out every possiblity -- crafting, smashing, using, etc. -- without searching for prices for all of the possible ingredients and results? Doesn't this seem like the sort of boring calculation that a script might excel at? (At which a script might excel?)
That's what PriceAdvisor does. Taking your skills and the opportunity cost of other ingredients (plus chef/bartender uses, adventures, etc.) into account, it calculates the maximum profit you can make from an item. And it tells you exactly how to make it. Use an item? It tells you what to do with the results, too. And it gives you the profit and actions to take for any other action (even those that result in negative profit, if you have your ZLib verbosity at 4 or greater), in case you don't like the advice it thinks is best.
For example, at the time of posting, this is the advice for a Penultimate Fantasy Chest:
PriceAdvisor considers autoselling, mallselling, pulverizing, untinkering, malusing, cooking, cocktailcrafting, smithing, stilling, jewelrycrafting, using, multi-using, stars, pixels, supertinkering, and sugar-folding. It does not currently consider zapping. Moreover, it will not consider anything you cannot currently do because you lack the skill or access to the equipment or are the wrong gender. Except pulverizing and malusing, because wadbot's pretty darn easy to use.
PriceAdvisor has three settings which you can set via CLI after running PriceAdvisor at least once. They all default to false.
zlib priceAdvisor_obeyPriceLimit = true : Forces PriceAdvisor to never recommend doing anything where an ingredient costs more than your Mafia autoBuyPriceLimit setting.
zlib priceAdvisor_conservative = true : Is even more conservative -- PriceAdvisor will never recommend doing anything where an ingredient is not either a) available from an NPC or b) available for minimum price in the mall
zlib priceAdvisor_CLIexecutable = true : Forces PriceAdvisor to only output advice that is executable in the CLI. You'll probably only want to use this if you're using PriceAdvisor in another script.
For Scripters:
PriceAdvisor uses historical prices to minimize server hits, and also caches its own decisions, so it is most efficient when used within a script. Its main purpose within a script is to serve as a more-sophisticated valuation than simple mallsell vs. autosell can be. (If only that comparison is desired, however, all relevant functions take a boolean consider_more that can be set to false to prevent considering anything more than mall or autosell.)
The basic data structure is the price_advice record, which contains a string action and a float price.
price_advice best_advice(item it, boolean consider_more) : Returns only the most profitable price_advice.
price_advice [int] price_advisor(item it, boolean consider_more) : Returns all advice with > 0 profit, sorted from best to worst (keys 0 to count-1).
price_advice max(price_advice a, price_advice b) : Returns a copy of the price_advice with higher price. Returns a copy of a if there's a tie.
void clear_advice_cache() : resets the internal advice caches
Both best_advice() and price_advisor() are overloaded to take multiple items:
price_advice [item] best_advice(boolean [item] its, boolean consider_more)
price_advice [item] [int] price_advisor(boolean [item] its, boolean consider_more)
print() has been overloaded in a few handy ways:
void print(price_advice advice)
void print(price_advice [int] advice)
PriceAdvisor also contains some maps of interest:
float [item] meat_use : the expected value of using an item, in meat; you can also load this from use_for_meat.txt, available via MapManager.
float [item] [item] item_use : the expected value of getting an item from using an item. This is mainly loaded from use_for_items.txt, available via MapManager, but some items with conditional results (Frat Army FGF, Hippy Army MPE, etc.) are only calculated and added within PriceAdvisor.
string [item] [item] ingredients : map from ingredient to concoction and concoction type (see concoctions.txt in Mafia data files). This serves as a complement to Mafia's get_ingredients(), and like get_ingredients() it does not contain things that you can't do. Except for smashing and malusing, because you can always have wadbot do that.
Scripts using PriceAdvisor extensively are encouraged to add the lines
cli_execute("update prices http://zachbardon.com/mafiatools/updateprices.php?action=getmap");
cli_execute("update prices http://nixietube.info/mallprices.txt");
at the beginning of said script to use shared price data, and the line
cli_execute("spade prices http://zachbardon.com/mafiatools/updateprices.php");
at the end to share gathered price data.
For Users:
PriceAdvisor can be called by creating this handy alias:
alias pa => ash import <PriceAdvisor.ash> print(price_advisor($items[%%], true))
The alias allows you to list several items at once at get PriceAdvisor's advice for each. For example, pa spring, sprocket, cog is a valid use (although the advice is pretty boring).
In response to the question "How can I get PA to tell me about a whole class of items", That FN Ninja came up with this alias:
alias pam => ash import <PriceAdvisor.ash> foreach itm in $items[] if(contains_text(to_string(itm),"%%")) print(price_advisor(itm, true))
It will report on all items which share the string you give it: pam tiny plastic will tell you about all tiny plastics.
If you use PriceAdvisor extensively, I encourage you to add the lines
cli_execute("update prices http://zachbardon.com/mafiatools/updateprices.php?action=getmap");
cli_execute("update prices http://nixietube.info/mallprices.txt");
to your breakfast/login script to use shared price data, and the line
cli_execute("spade prices http://zachbardon.com/mafiatools/updateprices.php");
to your pajamas/logout script to share gathered price data.
Disclaimer: PriceAdvisor can't think for you. It can only do the math, and is limited by Mafia's customary mallprice == price of the fifth item available, which may be unrealistic for expensive or rarely-sold items. It's your responsibility to determine if its advice is realistic.
Version history:
1.62: cli-executable "trade gloomy for oily" (from heeheehee); updated to use awesome new load_current_map() from ZLib 14
1.61: improved regex from xKiv, fixed bug where container-keys were being valued at negative opportunity cost
1.6: added _obeyPriceLimit, _conservative, and _CLIexecutable vars; renamed best_advice cache -> best_cache, best_price() -> best_advice(), smashed_advice() -> smash_advice(); changed boolean parameter of smash_advice() to just be consider_more; now using currently_considering[] for all infinite recursion and circular op. cost prevention; fixed best_cache to cache based on consider_more; invalid sub-results now invalidate final result; fixed final == starting to recognize the first sell in an action; now using xKiv's regex in replace_with_multiple(); best_advice() returns newly-constructed price_advice so return value can't mess with cache. Whew.
1.51: bug fixes: final product = starting item, trying again; added vodka as a fermenting powder booze; fixed some result-is-multiple issues
1.5: really eliminated final product = starting item (I hope); switched to vprint() -- negative prices displayed only at verbosity 4+; switched to CLI-executable output
1.42: eliminated recommendations where final product = starting item, cleaned up some artifacts resulting from item_use entries overlapping with SUSE entries
1.41: clearer "do x times" advice for results dealing with multiples of an item
1.4: added handling of usable-items-that-require-something-else-and-produce-more-than-one-thing; added better output for items that have no autosell value but sell for min mallprice (so aren't worth selling)
1.3: changed fix for circular opportunity costs so it doesn't block legitimate further consideration; changed opportunity cost for autosell-valued items to be mallsell if you have to buy them; eliminated a few non-results from printing
1.2: fixed bug in max(), added consideration of untinkering, added detection of clockwork servants; now displays actions with negative profit
1.11: added trading gloomies for oily goldens, malusing elemental nuggets for wads (transmutation was interfering)
PriceAdvisor requires SmashLib and ZLib, and daily build 7915 or greater (13.8 will work).
Have you ever looked at your inventory and wondered, What's the most meat I could make with this item? Are you chafing at the confines of comparing mallsell to autosell? Do you wish you could price out every possiblity -- crafting, smashing, using, etc. -- without searching for prices for all of the possible ingredients and results? Doesn't this seem like the sort of boring calculation that a script might excel at? (At which a script might excel?)
That's what PriceAdvisor does. Taking your skills and the opportunity cost of other ingredients (plus chef/bartender uses, adventures, etc.) into account, it calculates the maximum profit you can make from an item. And it tells you exactly how to make it. Use an item? It tells you what to do with the results, too. And it gives you the profit and actions to take for any other action (even those that result in negative profit, if you have your ZLib verbosity at 4 or greater), in case you don't like the advice it thinks is best.
For example, at the time of posting, this is the advice for a Penultimate Fantasy Chest:
Code:
[B]Penultimate Fantasy chest:[/B]
mallsell 1 Penultimate Fantasy chest: 1310.0 meat
use Penultimate Fantasy chest; acquire 1 cocoa eggshell fragment; make 1 large cocoa eggshell fragment;
acquire 1 large cocoa eggshell fragment; make 1 cocoa egg; acquire 1 spooky wad; make 1 Spooky Surprise Egg;
mallsell 1 Spooky Surprise Egg; autosell 1 phonics down; mallsell 1 scroll of drastic healing;
autosell 1 soft green echo eyedrop antidote; autosell 1 super-spiky hair gel; autosell 1 tiny house: 1040.7269 meat
autosell 1 Penultimate Fantasy chest: 108.0 meat
PriceAdvisor considers autoselling, mallselling, pulverizing, untinkering, malusing, cooking, cocktailcrafting, smithing, stilling, jewelrycrafting, using, multi-using, stars, pixels, supertinkering, and sugar-folding. It does not currently consider zapping. Moreover, it will not consider anything you cannot currently do because you lack the skill or access to the equipment or are the wrong gender. Except pulverizing and malusing, because wadbot's pretty darn easy to use.
PriceAdvisor has three settings which you can set via CLI after running PriceAdvisor at least once. They all default to false.
zlib priceAdvisor_obeyPriceLimit = true : Forces PriceAdvisor to never recommend doing anything where an ingredient costs more than your Mafia autoBuyPriceLimit setting.
zlib priceAdvisor_conservative = true : Is even more conservative -- PriceAdvisor will never recommend doing anything where an ingredient is not either a) available from an NPC or b) available for minimum price in the mall
zlib priceAdvisor_CLIexecutable = true : Forces PriceAdvisor to only output advice that is executable in the CLI. You'll probably only want to use this if you're using PriceAdvisor in another script.
For Scripters:
PriceAdvisor uses historical prices to minimize server hits, and also caches its own decisions, so it is most efficient when used within a script. Its main purpose within a script is to serve as a more-sophisticated valuation than simple mallsell vs. autosell can be. (If only that comparison is desired, however, all relevant functions take a boolean consider_more that can be set to false to prevent considering anything more than mall or autosell.)
The basic data structure is the price_advice record, which contains a string action and a float price.
price_advice best_advice(item it, boolean consider_more) : Returns only the most profitable price_advice.
price_advice [int] price_advisor(item it, boolean consider_more) : Returns all advice with > 0 profit, sorted from best to worst (keys 0 to count-1).
price_advice max(price_advice a, price_advice b) : Returns a copy of the price_advice with higher price. Returns a copy of a if there's a tie.
void clear_advice_cache() : resets the internal advice caches
Both best_advice() and price_advisor() are overloaded to take multiple items:
price_advice [item] best_advice(boolean [item] its, boolean consider_more)
price_advice [item] [int] price_advisor(boolean [item] its, boolean consider_more)
print() has been overloaded in a few handy ways:
void print(price_advice advice)
void print(price_advice [int] advice)
PriceAdvisor also contains some maps of interest:
float [item] meat_use : the expected value of using an item, in meat; you can also load this from use_for_meat.txt, available via MapManager.
float [item] [item] item_use : the expected value of getting an item from using an item. This is mainly loaded from use_for_items.txt, available via MapManager, but some items with conditional results (Frat Army FGF, Hippy Army MPE, etc.) are only calculated and added within PriceAdvisor.
string [item] [item] ingredients : map from ingredient to concoction and concoction type (see concoctions.txt in Mafia data files). This serves as a complement to Mafia's get_ingredients(), and like get_ingredients() it does not contain things that you can't do. Except for smashing and malusing, because you can always have wadbot do that.
Scripts using PriceAdvisor extensively are encouraged to add the lines
cli_execute("update prices http://zachbardon.com/mafiatools/updateprices.php?action=getmap");
cli_execute("update prices http://nixietube.info/mallprices.txt");
at the beginning of said script to use shared price data, and the line
cli_execute("spade prices http://zachbardon.com/mafiatools/updateprices.php");
at the end to share gathered price data.
For Users:
PriceAdvisor can be called by creating this handy alias:
alias pa => ash import <PriceAdvisor.ash> print(price_advisor($items[%%], true))
The alias allows you to list several items at once at get PriceAdvisor's advice for each. For example, pa spring, sprocket, cog is a valid use (although the advice is pretty boring).
In response to the question "How can I get PA to tell me about a whole class of items", That FN Ninja came up with this alias:
alias pam => ash import <PriceAdvisor.ash> foreach itm in $items[] if(contains_text(to_string(itm),"%%")) print(price_advisor(itm, true))
It will report on all items which share the string you give it: pam tiny plastic will tell you about all tiny plastics.
If you use PriceAdvisor extensively, I encourage you to add the lines
cli_execute("update prices http://zachbardon.com/mafiatools/updateprices.php?action=getmap");
cli_execute("update prices http://nixietube.info/mallprices.txt");
to your breakfast/login script to use shared price data, and the line
cli_execute("spade prices http://zachbardon.com/mafiatools/updateprices.php");
to your pajamas/logout script to share gathered price data.
Disclaimer: PriceAdvisor can't think for you. It can only do the math, and is limited by Mafia's customary mallprice == price of the fifth item available, which may be unrealistic for expensive or rarely-sold items. It's your responsibility to determine if its advice is realistic.
Version history:
1.62: cli-executable "trade gloomy for oily" (from heeheehee); updated to use awesome new load_current_map() from ZLib 14
1.61: improved regex from xKiv, fixed bug where container-keys were being valued at negative opportunity cost
1.6: added _obeyPriceLimit, _conservative, and _CLIexecutable vars; renamed best_advice cache -> best_cache, best_price() -> best_advice(), smashed_advice() -> smash_advice(); changed boolean parameter of smash_advice() to just be consider_more; now using currently_considering[] for all infinite recursion and circular op. cost prevention; fixed best_cache to cache based on consider_more; invalid sub-results now invalidate final result; fixed final == starting to recognize the first sell in an action; now using xKiv's regex in replace_with_multiple(); best_advice() returns newly-constructed price_advice so return value can't mess with cache. Whew.
1.51: bug fixes: final product = starting item, trying again; added vodka as a fermenting powder booze; fixed some result-is-multiple issues
1.5: really eliminated final product = starting item (I hope); switched to vprint() -- negative prices displayed only at verbosity 4+; switched to CLI-executable output
1.42: eliminated recommendations where final product = starting item, cleaned up some artifacts resulting from item_use entries overlapping with SUSE entries
1.41: clearer "do x times" advice for results dealing with multiples of an item
1.4: added handling of usable-items-that-require-something-else-and-produce-more-than-one-thing; added better output for items that have no autosell value but sell for min mallprice (so aren't worth selling)
1.3: changed fix for circular opportunity costs so it doesn't block legitimate further consideration; changed opportunity cost for autosell-valued items to be mallsell if you have to buy them; eliminated a few non-results from printing
1.2: fixed bug in max(), added consideration of untinkering, added detection of clockwork servants; now displays actions with negative profit
1.11: added trading gloomies for oily goldens, malusing elemental nuggets for wads (transmutation was interfering)
Attachments
Last edited: