SmartStasis -- a complex script for a simple CCS

fronobulax

Developer
Staff member
Wow. A year plus of posting in other threads.

I recently switched from WHAM to SimpleSmack because WHAM was losing winnable fights. Fighting the Tower Contestants generated numerous combats that I lost. However something reported that I had won the fight during stasis for most of them. I don't know whether SS just got incredibly lucky and the monster and I went to zero in the final round or whether SS exited and SimpleSmack misunderstood that the combat had been won and not lost. In any event, since I can easily dispatch the contestants manually, I would prefer that SS acknowledged that. There may be bad or missing BatBrain data on the contestants. There may be a parameter set to a value I want to change. I certainly would like to know why SS tries to stasis against these monsters because by the time I get to the tower adventures are usually more valuable than anything I could stasis for.
 

gausie

D̰͕̝͚̤̥̙̐̇̑͗̒e͍͔͎͈͔ͥ̉̔̅́̈l̠̪̜͓̲ͧ̍̈́͛v̻̾ͤe͗̃ͥ̐̊ͬp̔͒ͪ
Staff member
Could we get a custom action for using a "Daily Affirmation: Keep Free Hate in your Heart" if you have one for the 3 PvP fights?
 

zarqon

Well-known member
@gausie: Would that be a desirable action for everyone whose hippy_stone_broken()? I have never done PvP so I'm not sure if you'd always rather have fights than the item (especially as the item has another pretty useful function). But would be happy to add it.

@frono: I'm suspicious that the contestants have scaling dodge and penetration (something for which we have basically no information). SimpleSmack is usually able to take them all down for me, though it has sometimes failed with lower-skilled characters.
 

gausie

D̰͕̝͚̤̥̙̐̇̑͗̒e͍͔͎͈͔ͥ̉̔̅́̈l̠̪̜͓̲ͧ̍̈́͛v̻̾ͤe͗̃ͥ̐̊ͬp̔͒ͪ
Staff member
It's a good point and honestly I don't know if others would want it. Having used SimpleSmack for a while I've been trying to move over to my own SmartStasis/BatBrain combat script recently. Is there a way I can add my own stasis-y custom actions? I tried this

Code:
    build_custom()

    item KEEP_FREE_HATE = $item[Daily Affirmation: Keep Free Hate In Your Heart];
    if ( get_property( "_affirmationHateUsed" ).to_boolean() == false && KEEP_FREE_HATE.item_amount() > 0 )
    {
        custom[count(custom)] = DA_KEEP_FREE_HATE.get_action();
    }

before doing enqueue_custom(), stasis() etc but while I can add a new custom action as above fairly easily, I'm not sure how to get SmartStasis to consider actually using it. Any advice?

EDIT: Ah, I see - I also need to add it as an option in the first place. My code ended up being

Code:
    item KEEP_FREE_HATE = $item[Daily Affirmation: Keep Free Hate In Your Heart];
    advevent event = to_event(`use {KEEP_FREE_HATE.to_int()}`, "once", 1);
    event.addopt(0, 0);

    if ( get_property( "_affirmationHateUsed" ).to_boolean() == false && KEEP_FREE_HATE.item_amount() > 0 )
    {
        custom[count(custom)] = KEEP_FREE_HATE.get_action();
    }

Does that seem like I'm using it the way you intended? It might be nice to be able to add an event and its matching opt in a single command!
 
Last edited:

zarqon

Well-known member
Ah, I just noted that for some reason that item was missing from batfactors, so I've added it as a custom action. It should now be present in opts when it's available (and not, otherwise; no need to check for it in inventory). BatBrain attempts to achieve omniscience regarding your available combat actions, so that was an oversight on my side.

You can look at the various encustom() functions at the top of SS's build_custom() to see how I added actions to custom. The most important difference is that I add copies of advevents rather than the advevents themselves.

...and thinking about it, I really have no good reason not to move those functions out into the main scope. You're the first scripter to engage in dialog about writing a script using BatBrain in quite some time so I'm quite willing to make it easier for you where possible!

Done in r45. Now you can just do a property check and encustom() it up prior to either try_custom or enqueue_custom:

PHP:
if (!get_property("_affirmationHateUsed").to_boolean()) 
   encustom(get_action($item[9485]));

This update also added some additional custom actions:

  • Throw short writ of habeas corpi at unimportant pygmies during your run.
  • Pickpocket for a fifth hacienda key when needed.
  • Throw a chaos butterfly at a generic duck if it's your first turn in the Barn.

As always, hope this helps!
 

gausie

D̰͕̝͚̤̥̙̐̇̑͗̒e͍͔͎͈͔ͥ̉̔̅́̈l̠̪̜͓̲ͧ̍̈́͛v̻̾ͤe͗̃ͥ̐̊ͬp̔͒ͪ
Staff member
Thank you so much, z!

I think the script is super smart and beyond impressive and I'm kicking myself for only interfacing with it through BatMan RE for many years.

I had ended up being more smart about what the meat cost of the item was by using my own pvp_fight_value() function. I don't suppose there's any way I can still make use of that now that it's included in batfactors?

Code:
    advevent event = to_event( `use {KEEP_FREE_HATE.to_int()}`, "once, att -25, def -25", 1 );
    float meatcost = KEEP_FREE_HATE.item_val() - ( 3 * pvp_fight_value() );
    event.addopt( meatcost, 0 );

And while I have you, do you accept patches? I was looking at adding support for the various other sources of drip damage, but navigating the damage coming from Drip Blast vs coming from regular attacks was too complicated - might wait for you to do it if/when you chose (for now, my script just has a separate silo'd handler for drippy enemies.
 

zarqon

Well-known member
You're quite welcome! Thanks for taking an interest in the actual intended purpose of BatBrain.

Re: fight value, if you're only going to use the affirmation once/day for PvP fights regardless of the item's value (custom actions are custom because usually they exist outside BatBrain's usual profit-driven approach), then I don't see where valuing PvP fights would be necessary? That said, I'd be happy to assign them a value as part of BatBrain's evaluation methods. What other combat items grant fights and how do you value fights?

As for Drip stuff, I haven't gotten around to the second wave of content yet. I do think a numeric modifier for Drippy Damage in mafia would be excellent, similar to what we do for DB Bonus Damage, but there are few enough sources yet that we can hardcode values nearly as easily. I'd also be happy to take a look at any patches you submit.
 

gausie

D̰͕̝͚̤̥̙̐̇̑͗̒e͍͔͎͈͔ͥ̉̔̅́̈l̠̪̜͓̲ͧ̍̈́͛v̻̾ͤe͗̃ͥ̐̊ͬp̔͒ͪ
Staff member
You're quite welcome! Thanks for taking an interest in the actual intended purpose of BatBrain.

Re: fight value, if you're only going to use the affirmation once/day for PvP fights regardless of the item's value (custom actions are custom because usually they exist outside BatBrain's usual profit-driven approach), then I don't see where valuing PvP fights would be necessary? That said, I'd be happy to assign them a value as part of BatBrain's evaluation methods. What other combat items grant fights and how do you value fights?

Eh I just wanted to be thorough. I can manage the profitability from outside BatBrain. I only want to use one (rather than, for example, put it in the mall) if the swagger from the 3 PvP fights is more valuable to me. I do that in a complicated way - I value coinmaster tokens by checking the value of items you can buy with them using CFStat. I can just decide whether to do it at the [tt

As for Drip stuff, I haven't gotten around to the second wave of content yet. I do think a numeric modifier for Drippy Damage in mafia would be excellent, similar to what we do for DB Bonus Damage, but there are few enough sources yet that we can hardcode values nearly as easily. I'd also be happy to take a look at any patches you submit.

I'll just see if i can support it in mafia.

Another small q: I was reading over my rewrite of SimpleSmack and am wondering if you could explain the difference between try_{custom,combos}. I can't quite get my head around why one might do one or the other.

Code:
    if ( count(queue) > 0 && queue[0].id == "pickpocket" && my_class() == $class[Disco Bandit] )
    {
        try_custom();
    }
    else
    {
        enqueue_custom();
    }

    build_combos();

    if ( ($familiars[Hobo Monkey, Gluttonous Green Ghost, Slimeling] contains my_fam() && !happened("famspent") ) || have_equipped($item[Crown of Thrones]) )
    {
        try_combos();
    }
    else
    {
        enqueue_combos();
    }
 

zarqon

Well-known member
Thanks for adding that! I'll have a look at that soon.

x_custom is for all the custom actions. x_combos are specifically for DB combos, which are specific combinations of non-custom actions that apply in custom situations and therefore require separate handling.
 

zarqon

Well-known member
Recent changes regarding monster ID have made the gremlin-stasising logic fire only for gremlins that lack the tools. Haha!

r46 fixes that, and additionally ignores the Yossarian location/tool properties, based on something lost said in the Monster ID thread. So a specific gremlin will always be stasis'd in a particular location for a particular tool.

Hope no one else burned over 50 turns trying to complete that sidequest, like frono and I did! :D
 

lostcalpolydude

Developer
Staff member
So a specific gremlin will always be stasis'd in a particular location for a particular tool.

If someone happens to fax the correct gremlin, they don't need to be in the correct location. Checking that you have the magnet, don't have the tool, and that it is the correct gremlin should be a complete check for all corner cases.
 

Crowther

Active member
If someone happens to fax the correct gremlin, they don't need to be in the correct location. Checking that you have the magnet, don't have the tool, and that it is the correct gremlin should be a complete check for all corner cases.
Wouldn't it be cool if faxes had a monster ID in them...
 

Crowther

Active member
The Heavy Rains fax thing does at least? And I would hope no one would load the wrong gremlin into a fax machine.
There are a few other monsters with identical names. I get complaints from time to time that people can't always fax the one they want, but without fighting the fax you can't tell which one it is.
 

trip

New member
Is there any support for supplying a specific monster to digitize after an appropriate amount of previous encounters? How about Cosplay Saber or Pocket Professor copies? Would this be the right place to implement these kinds of things, or are they best left to another script? I'd be happy to help contribute, if this is where it'd make sense to do so.
 

zarqon

Well-known member
r47 is location-agnostic regarding tool-bearing gremlids.

@trip: This is the right place to implement those things. I had a look at supporting the Saber when it came out, but since it can't be performed like most actions I saved it for later. I'll take another look.

How would you envision Digitize support? It probably shouldn't share attract or copy custom handling, so I guess a list of monsters that you want to Digitize? SS could re-up your Digitize on one of your copies if you are becoming inefficient.
 

Viking_Hippie

New member
Any plans to include support for using the new IOTM Everfull Dart Holster darts? They sound really useful, but since I'm used to letting SmartStasis and WHAM handle combat for me, I probably won't get much use out of them if I have to do it manually every time..
 
Top