Results 1 to 8 of 8

Thread: Buy Script Intended Use

  1. #1
    Senior Member
    Join Date
    Apr 2018
    Posts
    249

    Default Buy Script Intended Use

    I’ve gathered that a buyScript script is meant to resolve to a boolean value, where “true” means “purchase” and “false” means “create”. However, I’m interested in creating a buyScript that can actually procure the items. If running the script changes the quantity of items you have, would KoLmafia recognize the change? I do not want KoLmafia to acquire more items than necessary.

  2. #2
    Senior Member Pazleysox's Avatar
    Join Date
    Feb 2009
    Posts
    463

    Default

    I’ve gathered that a buyScript script is meant to resolve to a boolean value, where “true” means “purchase” and “false” means “create”. However, I’m interested in creating a buyScript that can actually procure the items. If running the script changes the quantity of items you have, would KoLmafia recognize the change? I do not want KoLmafia to acquire more items than necessary.
    Originally Posted by Saklad5 View Post
    If I understand your question correctly, you want your script to check if you have Y items. If you have X, you want to purchase up to Y, then create Z.

    In my experience Mafia does not over buy unless you tell it to. The eat drink portion of my daily script looks for the multiple items it needs to create the food it wants. If o already have some of the items, it only buys what it needs to make up the rest.

    If needed, you can always refresh your inventory after each creation, but I'm not sure this is needed, because mafia will already know everything you have. (Does this cause a server hit?). I believe the only time this is needed is when someone sends you an item.
    Scripts I have written:
    Unlock Dread A Script to save you a bunch of clicks.
    Standard Rollover Bonus A Script that shows best items to pull/equip for bonus turns.
    Standard PVP Bonus A Script that shows the best items to pull/equip for bonus PVP Fights.
    Rollover Management A Script that does all the daily deeds you might have forgotten, or might have missed.
    Chatbot A Chatbot script. Simple start for those who want/need one for their clan.
    Zap Wand A Dungeon of Doom ZAP WAND getting script.

  3. #3
    Senior Member
    Join Date
    Apr 2018
    Posts
    249

    Default

    I want to override the behavior of the retrieve_item() to use the Clan Stash for items that are min-priced in the mall, along with a few other conditions according to the rules of my clan.

    The min-price bit isn’t technically a rule of my clan, but that should make it obvious what I’m going for here. If KoLmafia is planning to buy something, potentially use the Clan Stash instead.

    The built-in behavior for using the Clan Stash is extremely clumsy, without even paying attention to my ability to take items. I’ve made a few feature requests for changing it, but there doesn’t seem to be much interest.
    Last edited by Saklad5; 03-04-2019 at 02:49 PM.

  4. #4
    Senior Member Pazleysox's Avatar
    Join Date
    Feb 2009
    Posts
    463

    Default

    I'm not really sure what you're trying to do, but can't you run a check for stuff in your stash first?

    I have a free fights script that pulls up to 3 items from the stash, and puts them back when it's done. It wouldn't be that hard to do.

    Instead of using retrieve_item you could do this:
    PHP Code:
    if ($item[yellow pixel potion].available_amount() < 1// I have 0 left.  Lets do something about it.
      
    {
       
    int ineed 10// need 10 pixels to make the potion
       
    int ihave $item[yellow pixel].available_amount(); //this is how many I have on hand
       
    refresh_stash(); 
       
    int stashhas stash_amount($item[yellow pixel]); // this is how many the clan stash has
       
    ineed ihave stashhas// this will figure out how many I can grab from the stash up to what I need.
       
    take_stash(ineed$item[yellow pixel]); // take what the stash has
       
    ineed 10 $item[yellow pixel].available_amount(); // I needed 10
          
    if ($item[yellow pixel].available_amount() < 10// if I still don't have the 10 I need, I will buy just what I need to get me there.
             
    {
              
    buy(ineed$item[yellow pixel]);
             }
       }
    create (1$item[yellow pixel potion]); 
    There's probably multiple ways of doing this. This is just the first one I came up with in a pinch. I tested this exact code, and it worked as expected.

  5. #5
    Developer
    Join Date
    Aug 2009
    Posts
    2,916

    Default

    I’ve gathered that a buyScript script is meant to resolve to a boolean value, where “true” means “purchase” and “false” means “create”. However, I’m interested in creating a buyScript that can actually procure the items. If running the script changes the quantity of items you have, would KoLmafia recognize the change? I do not want KoLmafia to acquire more items than necessary.
    Originally Posted by Saklad5 View Post
    While this should work as you intend (it looks like InventoryManager checks if target - inventory.getCount(item) <= 0 after all existing calls to invokeBuyScript), IMO this is an implementation detail that you shouldn't rely upon, as its behavior may change with a refactor.

    I'm not really sure what you're trying to do, but can't you run a check for stuff in your stash first?

    I have a free fights script that pulls up to 3 items from the stash, and puts them back when it's done. It wouldn't be that hard to do.

    Instead of using retrieve_item you could do this:
    PHP Code:
    if ($item[yellow pixel potion].available_amount() < 1// I have 0 left.  Lets do something about it.
      
    {
       
    int ineed 10// need 10 pixels to make the potion
       
    int ihave $item[yellow pixel].available_amount(); //this is how many I have on hand
       
    refresh_stash(); 
       
    int stashhas stash_amount($item[yellow pixel]); // this is how many the clan stash has
       
    ineed ihave stashhas// this will figure out how many I can grab from the stash up to what I need.
       
    take_stash(ineed$item[yellow pixel]); // take what the stash has
       
    ineed 10 $item[yellow pixel].available_amount(); // I needed 10
          
    if ($item[yellow pixel].available_amount() < 10// if I still don't have the 10 I need, I will buy just what I need to get me there.
             
    {
              
    buy(ineed$item[yellow pixel]);
             }
       }
    create (1$item[yellow pixel potion]); 
    There's probably multiple ways of doing this. This is just the first one I came up with in a pinch. I tested this exact code, and it worked as expected.
    Originally Posted by Pazleysox View Post
    That doesn't look like it computes ineed correctly before taking from stash. Presumably you'd want ineed = ineed - ihave (which is basically just 10 - available_amount(YELLOW_PIXEL), then take_stash(min(ineed, stashhas), YELLOW_PIXEL).

  6. #6
    Senior Member
    Join Date
    Apr 2018
    Posts
    249

    Default

    While this should work as you intend (it looks like InventoryManager checks if target - inventory.getCount(item) <= 0 after all existing calls to invokeBuyScript), IMO this is an implementation detail that you shouldn't rely upon, as its behavior may change with a refactor.
    Originally Posted by heeheehee View Post
    I saw that, and came to a similar conclusion. While I’m fairly sure this would work, I don’t want to do it unless it is actually supposed to work that way. Anything else is undefined behavior, and this is a very dangerous thing to mess up. That’s why this thread is titled “Buy Script Intended Use”.

  7. #7
    Developer
    Join Date
    Aug 2009
    Posts
    2,916

    Default

    One oft-cited example for a buyScript is where Mafia doesn't truly account for the value of creation, e.g. in the case of a Sauceror crafting sauce potions in triplicate. Natively, Mafia simply compares the cost of a reagent + whatever material, then compares that to the cost of one item in the mall. There have been times in the past where the mall price has provided plenty of opportunity for Sauceror arbitrage (although one of my personal projects has been to drastically limit that inefficiency in the market).

    example: glass of goat's milk costs 2000, scrumptious reagent costs 1000, milk of magnesium costs 1500. retrieveItem will by default always buy from the mall, even though buying the ingredients and making manually is more cost-effective (especially since it's a potion you _will_ use).

  8. #8
    Senior Member
    Join Date
    Apr 2018
    Posts
    249

    Default

    In summary: Buy Scripts are implemented with the assumption that KoLmafia’s default behavior for creating or purchasing items is desired, and they are only meant to choose between the two. Anything beyond that is undefined behavior, and should not be relied upon.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •