SmartStasis -- a complex script for a simple CCS

heeheehee

Developer
Staff member
I tested my damage and decided the following low-tech CCS would do the job
[ default ]
skill noodles
skill saucestorm
item bottle gone

Protip: "skill noodles" will return Noodles of Fire (the skill granted by the Pastamancer Ultimate Legendary Epic Weapon), not Entangling Noodles.
 

Veracity

Developer
Staff member
Protip: "skill noodles" will return Noodles of Fire (the skill granted by the Pastamancer Ultimate Legendary Epic Weapon), not Entangling Noodles.

That is almost guaranteed to be precisely what people do NOT expect with that CCS.
Hmm.
 

heeheehee

Developer
Staff member
Yeah, it cropped up when I tossed it into my CCS, thinking it'd return Entangling Noodles, as it used to way back in the day...
 

lostcalpolydude

Developer
Staff member
That is almost guaranteed to be precisely what people do NOT expect with that CCS.
Hmm.

With a CCS, mafia at least translates to the full skill name when you save it, so you can see what mafia will do with it without really going out of your way. Not so much with the CLI cast command.
 

zarqon

Well-known member
It's not mafia's fault that KoL named the new skill thusly -- mafia is still matching against skill names intelligently. Besides, I highly doubt that anyone casts skills in combat using the CLI.

(Also, after two days of running -- I mean playing -- Progress Quest at the office, I reached level 8! Hahaha)
 

lostcalpolydude

Developer
Staff member
If it's ambiguous, why guess at which skill the person means instead of making the user be more specific? Preferring skills that people have over ones they don't have would be good if mafia isn't going to make the user be more specific.
 

Bale

Minion
Preferring skills that people have over ones they don't have would be good if mafia isn't going to make the user be more specific.
That sounds like a good idea at first, but can you imagine the confusion it will cause when a trusted and familiar command starts behaving differently just because you learn a new skill? Very bad idea.
 

Raven434

Member
Protip: "skill noodles" will return Noodles of Fire (the skill granted by the Pastamancer Ultimate Legendary Epic Weapon), not Entangling Noodles.

DOH!

I did see that when I ran it the other night. Thanks for the reminder (hee)^3

[ default ]
skill enta
skill sauces
item bottle gone
 

Bale

Minion
I've been getting a lot of this today:

Code:
Request 1 of 5 (Junkyard: Near an Abandoned Refrigerator) in progress...

[916]     Near an Abandoned Refrigerator
Encounter: spider gremlin
Strategy:     H:\KolMafia\ccs\default.ccs [default]
Round 0: bale loses initiative!
Round     1: Chohoshi lolls back and forth, holding his growling stomach and     drooling.
You lose 5 hit points
1/5 monsters dropping 1 goals.
This     monster drops all your remaining goals!
Round 1: bale uses the     facsimile dictionary!
You lose 5 hit points
[COLOR="#808000"]Your     ghost is hongry.[/COLOR]
Round 2: bale uses the facsimile dictionary!
You     lose 5 hit points
[COLOR="#808000"]Your ghost is hongry.[/COLOR]
Round     3: bale uses the facsimile dictionary!
You lose 4 hit points
[COLOR="#808000"]Your     ghost is hongry.[/COLOR]
Round 4: bale uses the facsimile dictionary!
You     lose 6 hit points
[COLOR="#808000"]Your ghost is hongry.[/COLOR]
Round     5: bale casts SAUCY SALVE!
KoLmafia thinks it is round 6 but KoL thinks     it is round 5
You gain 12 hit points
Round 6: bale uses the     facsimile dictionary!
KoLmafia thinks it is round 7 but KoL thinks it     is round 6
You lose 4 hit points
[COLOR="#808000"]Your ghost is     hongry.[/COLOR]
Round 7: bale uses the facsimile dictionary!
KoLmafia     thinks it is round 8 but KoL thinks it is round 7
You lose 5 hit points
[COLOR="#808000"]Your     ghost is hongry.[/COLOR]
Round 8: bale uses the facsimile dictionary!
KoLmafia     thinks it is round 9 but KoL thinks it is round 8
You lose 4 hit points
[COLOR="#808000"]Your     ghost is hongry.[/COLOR]
Round 9: bale casts SAUCY SALVE!
KoLmafia     thinks it is round 10 but KoL thinks it is round 8
You gain 28 hit     points
Round 10: bale uses the facsimile dictionary!
KoLmafia thinks     it is round 11 but KoL thinks it is round 9
You lose 5 hit points
[COLOR="#808000"]Your     ghost is hongry.[/COLOR]
Round 11: bale uses the molybdenum magnet!
KoLmafia     thinks it is round 12 but KoL thinks it is round 10
You acquire an     item: molybdenum pliers
You gain 25 Muscularity Points
You gain 84     Meat
After Battle: Chohoshi smiles broadly, revealing his pearly     whites. Er, greens, in this case.
You gain 32 Beefiness
You gain 12     Wizardliness
You gain 15 Chutzpah
[COLOR="#808000"]Your ghost is     hongry.
Your ghost is hongry.
Your     ghost is hongry.
Your ghost is hongry.
Your     ghost is hongry.
Your ghost is hongry.
Your     ghost is hongry.
Your ghost is hongry.
Your     ghost is hongry.
Your ghost is hongry.
Your     ghost is hongry.
Your ghost is hongry.
Your     ghost is hongry.
Your ghost is hongry.
Your     ghost is hongry.
Your ghost is hongry.[/COLOR]

Conditions     satisfied after 1 adventures.

As hongry as my ghost is, I wish he'd shut up about it after the fight is over!
 
Last edited:

Winterbay

Active member
Question: What would I have to do to get the script to use Rave nirvana and Concentration instead of the discoversions that cost a lot more MP?
 

zarqon

Well-known member
@Winterbay: You would have to either 1) edit SS to handle these combos (Bale's Rave combo consult script might give you some clues, or 2) wait for someone to have time to add this to SS. Glazius messaged me about adding Bale's code into FTF or somesuch, and he may be posting that.

Otherwise, I'll definitely be adding this eventually. As I feared, the new school year (I'm a teacher and the school year started at the beginning of this month) meant that I have had little or no time for playing KoL, much less scripting for it. (And of course, that would be when they release a huge content update.) I'll be able to get back into it soon I hope, once people (students and teachers) get into the swing of things.

@Bale: fixed locally, you'll have to wait for the update like everyone else.

I'm thinking of doing a "maintenance" update soon for FTF and SS, since there were quite a few changes to them, and they still work, even though BatMan doesn't yet. Might have time for that this weekend.

I hope everyone had a lovely St. Paddy's Day.
 

Bale

Minion
Glad to hear that, zarqon! I hope your schedule lightens up soon.

@Winterbay: My consult script that zarqon refers to is here.

More relevant info:
raveCombo1 = Rave Concentration = Item Drop +30
raveCombo2 = Rave Nirvana = Meat Drop +50
raveCombo3 = Rave Knockout = multi-round stun + damage
raveCombo4 = Rave Bleeding = recurring damage
raveCombo5 = Rave Steal = extra auto-pickpocket (if no pickpocket this round)
raveCombo6 = Rave Substats = immediate substats​
 

Bale

Minion
@Winterbay: I wasn't originally intending to answer your question, but I your question inspired me to spend a little time studying SS to consider if it would take much rewriting. I may be over-simplifying zarqon's algorithm, but I think that this is what you'd have to do to get the script to use Rave nirvana and Concentration instead of the discoversions that cost a lot more MP.

PHP:
// cast a disco combo if possible (checks for profitability are included for nirvana/concentration)
string disco_combo(skill[int] seq, effect grants, int damage, string page) {
   if (my_class() != $class[disco bandit]) return page;
   int combocost;
   foreach key,val in seq combocost = combocost + mp_cost(val);
   if (my_mp() < combocost || have_effect(grants) > 0 || monster_hp() <= damage + to_int(have_equipped($item[disco banjo]))*3 +
      to_int(have_equipped($item[shagadelic disco banjo]))*7 + to_int(have_equipped($item[makeshift castanets]))*10 +
      to_int(have_equipped($item[Chester's moustache]))*20 + to_int(string_modifier("Outfit") == "Tawdry Tramp Togs")*20 +
      to_int(my_familiar() == $familiar[frumious bandersnatch])*count(seq)*0.75*(familiar_weight(my_familiar())+numeric_modifier("Familiar Weight")) ||
      round > 30 - count(seq)) return page;
   float compen = 0;
   if (intheclear() && inmp > mpforstasis) compen = max((28.0 - round)*inmp,0);
   float dcprofit, base, adjusted;
   switch (grants) {
      case $effect[rave concentration]: 
         foreach it,chance in item_drops() {
            base = minmax((100.0+numeric_modifier("Item Drop"))/100.0*chance,0,100);
            if (base == 100) continue;
            adjusted = minmax((130.0+numeric_modifier("Item Drop"))/100.0*chance,0,100);
            if (base == adjusted) continue;
            if (is_goal(it)) { dcprofit = 9999999; break; }
            dcprofit = dcprofit + (adjusted - base)*autosell_price(it);
         }
         if (dcprofit < meatpermp*(to_float(combocost) - compen)) return page;
         break;
      case $effect[disco concentration]:
         foreach it,chance in item_drops() {
            base = minmax((100.0+numeric_modifier("Item Drop"))/100.0*chance,0,100);
            if (base == 100) continue;
            adjusted = minmax((120.0+numeric_modifier("Item Drop"))/100.0*chance,0,100);
            if (base == adjusted) continue;
            if (is_goal(it)) { dcprofit = 9999999; break; }
            dcprofit = dcprofit + (adjusted - base)*autosell_price(it);
         }
         if (dcprofit < meatpermp*(to_float(combocost) - compen)) return page;
         break;
      case $effect[rave nirvana]: if (nowfightingonstageone != $monster[dirty thieving brigand] &&
              0.5*to_float(meat_drop()) < meatpermp*(to_float(combocost) - compen)) return page;
      case $effect[disco nirvana]: if (nowfightingonstageone != $monster[dirty thieving brigand] &&
              0.3*to_float(meat_drop()) < meatpermp*(to_float(combocost) - compen)) return page;
   }
   foreach key,val in seq page = act(try_skill(page,val));
   return page;
}

string try_combos(string page) {
   skill[int] dcomb;
   boolean can_rave = have_skill($skill[Break It On Down]) && have_skill($skill[Pop and Lock It]) 
      && have_skill($skill[Run Like the Wind]);
   int rave_cost = mp_cost($skill[Break It On Down]) + mp_cost($skill[Pop and Lock It]) + mp_cost($skill[Run Like the Wind]);
   boolean can_rave_concentrate = (my_class() == $class[disco bandit] && count(item_drops()) > 0 && can_rave && monster_hp() > 25 &&
      my_mp() >= rave_cost);
   boolean can_rave_nirvana = (my_class() == $class[disco bandit] && meat_drop() > 0 && can_rave && monster_hp() > 17 &&
      my_mp() >= rave_cost);
   if (can_rave_concentrate) {
      matcher combo = create_matcher("(.+),(.+),(.+)", get_property("raveCombo1")); 
      if(combo.find()) {
         for i from 1 to 3
            dcomb[i] = combo.group(i).to_skill(); 
         page = disco_combo(dcomb,$effect[rave concentration],25,page);
      }
   }
   if (can_rave_nirvana) {
      matcher combo = create_matcher("(.+),(.+),(.+)", get_property("raveCombo2")); 
      if(combo.find()) {
         for i from 0 to 2
            dcomb[i] = combo.group(i).to_skill(); 
         page = disco_combo(dcomb,$effect[rave nirvana],25,page);
      }
   }
   if (can_nirvana) {
      dcomb[0] = $skill[disco dance of doom];
      dcomb[1] = $skill[disco dance ii: electric boogaloo];
      page = disco_combo(dcomb,$effect[disco nirvana],17,page);
   }
   if (can_concentrate) {
      dcomb[0] = $skill[disco eye-poke];
      dcomb[1] = $skill[disco dance of doom];
      dcomb[2] = $skill[disco dance ii: electric boogaloo];
      return disco_combo(dcomb,$effect[disco concentration],19,page);
   }
   return page;
}

My answer is crude, and an obvious paste-in to SmartStasis and I'm certain zarqon's final version will be more elegant, but I think that this will do the job. (Plus I pretty much ignore Disco Pickpocketing since that will best be handled by FTF, I think.
 
Last edited:

Winterbay

Active member
Thanks Bale! I'll try that out tomorrow.
My programming skills are not good enough to see through ash/php-code, they are rather limited to easy Fortran 90 and Excel VBA codes :)
 

Glazius

Member
Here's a slight update to SmartStasis. It'll try to perform the various rave combos if you're capable of them and they make sense to do, including the rave pickpocket combo if you haven't stolen something with FirstThingsFirst.

FirstThingsFirst was tweaked slightly to incorporate these changes, as detailed in this post.

It assumes that any given rave combo will do 30 damage, which is probably a bit on the high side.

As an added bonus it handles the corner case where an enemy will only drop one item and you've already pickpocketed it or you're going to rave-pickpocket it, and doesn't fire off either Concentration combo.
 

Attachments

  • SmartStasis.ash
    16.3 KB · Views: 45

Bale

Minion
A very good point and one I didn't think of while writing up my 10 minute kludge.

Fortunately Glazius has posted his fix so my code is now obsolete. If I had anything to do with him posting that now, then it was worth it.
 

Jatopian

Member
Yes -- please also post the CLI output from a combat where this is happening, if you can (mafia saves all your sessions in its "sessions" directory so hopefully it wouldn't be too hard to track down).
> "fastest.txt" loaded (14 steps).
> Verifying Wossname progress...
> Current step: 11
> Completing step 11 of 14...
> Step 11: Junkyard sidequest
> Visiting Yossarian...

bigisland.php?action=junkman&pwd
> getting molybdenum crescent wrench...

[4663] Over Where the Old Tires Are
Encounter: erudite gremlin
Round 0: Jatopian wins initiative!
> 1/5 monsters dropping 1 goals.
> This monster drops all your remaining goals!
Round 1: Jatopian uses the facsimile dictionary!
You gain 20 hit points
You lose 9 hit points
Round 2: Jatopian uses the molybdenum magnet!
Round 3: Jatopian uses the molybdenum magnet!
Round 4: Jatopian uses the molybdenum magnet!
Round 5: Jatopian uses the molybdenum magnet!
Round 6: Jatopian uses the molybdenum magnet!
Round 7: Jatopian uses the molybdenum magnet!
Round 8: Jatopian uses the molybdenum magnet!
Round 9: Jatopian uses the molybdenum magnet!
Round 10: Jatopian uses the molybdenum magnet!
Round 11: Jatopian uses the molybdenum magnet!
Round 12: Jatopian uses the molybdenum magnet!
Round 13: Jatopian uses the molybdenum magnet!
Round 14: Jatopian uses the molybdenum magnet!
Round 15: Jatopian uses the molybdenum magnet!
Round 16: Jatopian uses the molybdenum magnet!
Round 17: Jatopian uses the molybdenum magnet!
Round 18: Jatopian uses the molybdenum magnet!
Round 19: Jatopian uses the molybdenum magnet!
Round 20: Jatopian uses the molybdenum magnet!
Round 21: Jatopian uses the molybdenum magnet!
Round 22: Jatopian uses the molybdenum magnet!
Round 23: Jatopian uses the molybdenum magnet!
Round 24: Jatopian uses the molybdenum magnet!
Round 25: Jatopian uses the molybdenum magnet!
Round 26: Jatopian uses the molybdenum magnet!
Round 27: Jatopian uses the molybdenum magnet!
Round 28: Jatopian uses the molybdenum magnet!
Round 29: Jatopian uses the molybdenum magnet!
Round 30: Jatopian uses the molybdenum magnet!
Round 31: Jatopian uses the molybdenum magnet!
Round 32: Jatopian uses the molybdenum magnet!
Round 33: Jatopian uses the molybdenum magnet!
Round 34: Jatopian uses the molybdenum magnet!
Round 35: Jatopian uses the molybdenum magnet!
Round 36: Jatopian uses the molybdenum magnet!
Round 37: Jatopian uses the molybdenum magnet!
Round 38: Jatopian uses the molybdenum magnet!
Round 39: Jatopian uses the molybdenum magnet!
Round 40: Jatopian uses the molybdenum magnet!
Round 41: Jatopian uses the molybdenum magnet!
Round 42: Jatopian uses the molybdenum magnet!
Round 43: Jatopian uses the molybdenum magnet!
Round 44: Jatopian uses the molybdenum magnet!
Round 45: Jatopian uses the molybdenum magnet!
Round 46: Jatopian uses the molybdenum magnet!
Round 47: Jatopian uses the molybdenum magnet!
Round 48: Jatopian uses the molybdenum magnet!
Round 49: Jatopian uses the molybdenum magnet!
Round 50: Jatopian uses the molybdenum magnet!
Round 51: Jatopian uses the molybdenum magnet!
Round 52: Jatopian uses the molybdenum magnet!
Round 53: Jatopian uses the molybdenum magnet!
Round 54: Jatopian uses the molybdenum magnet!
Round 55: Jatopian uses the molybdenum magnet!
Round 56: Jatopian uses the molybdenum magnet!
Round 57: Jatopian uses the molybdenum magnet!
Round 58: Jatopian uses the molybdenum magnet!
Round 59: Jatopian uses the molybdenum magnet!
Round 60: Jatopian uses the molybdenum magnet!
Round 61: Jatopian uses the molybdenum magnet!
Round 62: Jatopian uses the molybdenum magnet!
Round 63: Jatopian uses the molybdenum magnet!
Round 64: Jatopian uses the molybdenum magnet!
Round 65: Jatopian uses the molybdenum magnet!
Round 66: Jatopian uses the molybdenum magnet!
Round 67: Jatopian uses the molybdenum magnet!
Round 68: Jatopian uses the molybdenum magnet!
Round 69: Jatopian uses the molybdenum magnet!
Round 70: Jatopian uses the molybdenum magnet!
Round 71: Jatopian uses the molybdenum magnet!
Round 72: Jatopian uses the facsimile dictionary!
You lose 10 hit points
Round 73: Jatopian uses the facsimile dictionary!
You gain 25 hit points
You lose 11 hit points
Round 74: Jatopian uses the facsimile dictionary!
You gain 21 hit points
You lose 10 hit points
Round 75: Jatopian uses the facsimile dictionary!
You lose 12 hit points
Round 76: Jatopian attacks!
Round 77: erudite gremlin takes 135 damage.
You gain 39 Meat
You gain 24 Strongness
You gain 10 Enchantedness
You gain 14 Sarcasm
 

zarqon

Well-known member
Did you, by chance, have a hammer of some kind equipped? A similar (same?) issue has been mentioned in the FTF thread (sorry for all the thread-hopping!), where fighting gremlins while having a hammer equipped will do exactly as you have posted here. A fix for that is on its way.
 

Glazius

Member
A very good point and one I didn't think of while writing up my 10 minute kludge.

Fortunately Glazius has posted his fix so my code is now obsolete. If I had anything to do with him posting that now, then it was worth it.

A bit belatedly, but no, I wasn't trying to steal your thunder. I looked at your (earlier) rave consult script, the one that just pickpocketed, and adapted the logic. Then I posted it the next morning once I was satisfied it'd work. There may still be a bug or two somewhere, but it's nothing that a few days as a Disco Bandit in various places has uncovered.
 
Top