Results 1 to 10 of 10

Thread: accessing item/effect modifiers in ash script

  1. #1
    Junior Member
    Join Date
    Jun 2019
    Posts
    5

    Default accessing item/effect modifiers in ash script

    I'm returning to kol after nearly a decade away, crazy this game is still kicking. I see some of your names and get flashbacks and nostalgia from high school. Its kind of weird.

    Anyway, I need to farm a bunch of meat to make up for giving all my sweet loot away and I am trying to make my farming script smart enough to check mall prices of +meat% and +familiar weight items and buy them if their cost is cheaper than what I expect to get from the bonus. Something like

    Code:
    boolean is_meat_item_economical(item i, int meat_per_adv, float meat_buff_percent, int turns){
      int purchase_price = mall_price(i);
      return ((meat_per_adv * meat_buff_percent) * turns) > purchase_price;
    }
    Ideally I would be able to loop over items looking for ones that contains meat/item/familiar buffs so I wouldnt need to keep hard coded lists around I'd need to update to take advantage of new items. The problem is I cant find any way of determining what the meat (/item/familiar weight/foo) buff and number of turns an effect lasts at runtime. I can get the item, the effect and the "effect modifier" but never enough information to do what I need.

    Code:
    void main(){
      print($item[love song of icy revenge]);
      print(effect_modifier($item[love song of icy revenge], "effect"));
      print(numeric_modifier(effect_modifier($item[love song of icy revenge], "effect"), "familiar weight"));
    }
    
    Prints:
    love song of icy revenge
    Cold Hearted
    1.0
    I found the source file kolmafia uses internally (from what I can tell): https://sourceforge.net/p/kolmafia/c.../modifiers.txt which is probably perfect but I dont think I can make use of it and I see other scripts seemingly making their own databases that end up in the data/ in the installation directiony.

    Am I missing something obvious? Is there a simpler way? At this point I'll just hard code my own lists when I have time, I havent figured out how to do file IO yet, need to dig into a more complicated script like Universal Recovery to see what they do. Any tips are appreciated, thanks.

  2. #2
    Senior Member
    Join Date
    Sep 2006
    Posts
    361

    Default

    You might want to check out Veracity's meat farming script: https://kolmafia.us/showthread.php?2...farming-script That would probably save you a lot of time.

  3. #3
    Junior Member
    Join Date
    Jun 2019
    Posts
    5

    Default

    Yes, I reference that from time to time. Veracity doesnt do something exactly like this, though I think there are a couple hard coded effect's they check for and maintain, skills they have that dont require purchasing iirc.

    I do use things like SmartStasis, an auto dinseylandfill quest script and some others to speed things up, but I didnt like the existing meat farming scripts I saw and wanted to stitch together my own. This is also for my own fun and interest as well.

  4. #4
    Developer
    Join Date
    Aug 2009
    Posts
    2,960

    Default

    You probably want to use whatif (aka speculate). I usually get lazy and just linearize meat drop from familiars, since it's "close enough" in the regime I care about, though.

    Code:
    > ash numeric_modifier("Generated:_spec", "Meat Drop")
    
    Returned: 76.49719092257398
    
    > speculate up empathy; up leash of linguini
    
    Familiar Weight  18.00 (+10.00)
    Meat Drop  116.65 (+40.16)
    
    > ash numeric_modifier("Generated:_spec", "Meat Drop")

  5. #5
    Developer Veracity's Avatar
    Join Date
    Mar 2006
    Location
    The Unseelie Court
    Posts
    11,996

    Default

    The problem is I cant find any way of determining what the meat (/item/familiar weight/foo) buff and number of turns an effect lasts at runtime. I can get the item, the effect and the "effect modifier" but never enough information to do what I need.
    Originally Posted by landstander View Post
    You have access to everything in modifiers.txt.

    Code:
    > ash string_modifier( $item[ love song of icy revenge ], "Modifiers" )
    
    Returned: Effect: "Cold Hearted", Effect Duration: 5
    
    > ash numeric_modifier( $item[ love song of icy revenge ], "Effect Duration" )
    
    Returned: 5.0
    Ph'nglui mglw'nafh Cthulhu
    R'lyeh wgah-nagl fhtagn.

  6. #6
    Junior Member
    Join Date
    Jun 2019
    Posts
    5

    Default

    You have access to everything in modifiers.txt.

    Code:
    > ash string_modifier( $item[ love song of icy revenge ], "Modifiers" )
    
    Returned: Effect: "Cold Hearted", Effect Duration: 5
    
    > ash numeric_modifier( $item[ love song of icy revenge ], "Effect Duration" )
    
    Returned: 5.0
    Originally Posted by Veracity View Post
    See, I thought I was missing something. The api reference is very helpful but rarely as thorough as I'd like. I havent gotten to the point of looking at kolmafia source code yet but suspect ill be there soon. I'm spoiled by strongly typed languages (which ash is from what I can tell, but isnt used to its fullest in some cases like there not being a modifier class/enum that you could use here) and debuggers and unit tests.

    Do you have any tips on discovering what properties are available on an object, e.g. what are the options I can provide as the second parameter to *_modifier(). I tried a couple methods like to_string() but it just printed the name. Usually I resort to looking at how other scripts do similar tasks but I cant always find what I am looking for.

    Edit: ash string_modifier( $item[ love song of icy revenge ], "Modifiers" ) will work for this case, but general discoverability tips are still appreciated.
    Last edited by landstander; 06-18-2019 at 01:30 PM. Reason: clarity

  7. #7

    Default

    Code:
    modref
    is a good way of seeing the modifiers you can check for.

  8. #8
    Senior Member ckb's Avatar
    Join Date
    Mar 2006
    Posts
    906

    Default

    I wrote this a while ago, but I believe it does what you want. As a side note, don't expect to regularly find anything profitable in the mall worth using.

    PHP Code:
    void MeatBuff() {
        
    float [itemilist;
        
    int base 250;
        foreach 
    it in $items[] {
            if (
    it.fullness==&& it.inebriety==&& it.spleen==&& it.tradeable==true && it.usable==true) {
                
    effect eff effect_modifier(it"Effect");
                
    float toe numeric_modifier(it"Effect Duration");
                
    float mtd numeric_modifier(eff"Meat Drop");
                
    float gain base*mtd*toe/100.0;
                if (
    gain>0.0) {
                    
    int hpc mall_price(it);
                    
    //print(it+" : +"+mtd+" X "+toe+" = "+gain+" @ "+hpc,"blue");
                    
    if (gain/to_float(hpc) > 1.10) {
                        
    float cpt = (gain/hpc);
                        
    ilist[it] = cpt;
                        
    //ilist[it] = gain;
                    
    }
                }
            }
        }
        
        
    //sort ilist by value;
        
    string rpt "";
        
    rpt += "<table border=1 cellpadding=1 cellspacing=1>";
        
    rpt += "<tr><td><b>ITEM</b></td><td><b>CPT</b></td></tr>";
        foreach 
    ii in ilist {
            
    string col "red";
            if (
    have_effect(effect_modifier(ii"Effect"))>0) { col="green"; }
            
    rpt += "<tr><td  style=color:"+col+">"+ii+"</td><td>"+to_string(ilist[ii],"%.5f")+"</td></tr>";
        }
        
    rpt += "</table>";
        
    print_html(rpt);
        


  9. #9
    Junior Member
    Join Date
    Jun 2019
    Posts
    5

    Default

    Code:
    modref
    is a good way of seeing the modifiers you can check for.
    Originally Posted by lostcalpolydude View Post
    Good one, thanks!

    I wrote this a while ago, but I believe it does what you want. As a side note, don't expect to regularly find anything profitable in the mall worth using.
    Originally Posted by ckb View Post
    Thanks, Ill check it out tomorrow when I have time to play around with kol some more. And yes, I also expect this to rarely be beneficial. All but the most common items, like the manual that gives +300% meat in barfmountain (which I have plenty of anyway), should basically balance out to as much as you would earn using it, because economics. But if I can script it I might as well look.

  10. #10
    Junior Member
    Join Date
    Jun 2019
    Posts
    5

    Default

    I attached the script I came up with in case anyone in the future is interested. It will calculate meat drop buffs and familiar weight buffs (assumes hobo monkey right now). For normal farming, it is pretty rare to find any economic meat or familiar weight buff items in the mall. However, if you are fighting copies of knob goblin embezzlers everyday it actually buys several buff items.

    You can just run it to get a simulation, the first time each day will be a little slow as it has to load up a map of items to check against but its very quick after that. You'll need to explicitly turn off the simluation mode using the
    Code:
    farming_econ_simulate
    property if you want to use it as a between battle script. See the source code for what else you can change.

    Here is the code relevant to the immediate question I asked about how to look up item effects:

    Code:
    static effect[item] meat_buff_items;
    static effect[item] meat_buff_ignore;
    static effect[item] familiar_buff_items;
    static effect[item] familiar_buff_ignore;
    
    boolean potentially_useable(item i){
      return(i.fullness == 0 && i.inebriety == 0 && i.spleen == 0 && i.usable == true && i.tradeable==true);
    }
    
    static{
      meat_buff_ignore[$item[How to Avoid Scams]] = effect_modifier($item[How to Avoid Scams], "Effect");
      meat_buff_ignore[$item[Uncle Greenspan's Bathroom Finance Guide]] = effect_modifier($item[Uncle Greenspan's Bathroom Finance Guide], "Effect");
    
      foreach it in $items[] {
        if(potentially_useable(it)){
          effect e = effect_modifier(it, "Effect");
          float duration = numeric_modifier(it, "Effect Duration");
          float meat_drop = numeric_modifier(e, "Meat Drop");
          float familiar_weight = numeric_modifier(e, "Familiar Weight");
          if(meat_drop > 0.0 && !(meat_buff_ignore contains it)){
            meat_buff_items[it] = e;
          }
          if(familiar_weight > 0.0 && !(familiar_buff_ignore contains it)){
            familiar_buff_items[it] = e;
          }
        }
      }
    }
    Attached Files

Posting Permissions

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