BatBrain -- a central nervous system for consult scripts

I think I found a minor bug, which would sometimes cause add_skill to mistakenly return early, causing no skills to be added to the list of available combat options. Changing line 1273 from
Code:
if (fields.special.contains_text("custom attract") && (have_effect($effect[on the trail]) > 0 || happened("attracted")) || are_attracting()) return;
to
Code:
if (fields.special.contains_text("custom attract") && (have_effect($effect[on the trail]) > 0 || happened("attracted") || are_attracting())) return;
seems to have fixed it for me.
 
Excellent bugsleuthsmanship! Oh, what a difference a parenthesis placement makes. That's an important bug to squash, so r114.
 
r115 Update

I've been adding support for FantasyRealm monsters as I go through collecting factoids, and today as I was fighting flocks of every birds, I decided to consolidate a lot of special case code for monsters that can only be damaged by area of effect skills/items. Such monsters can now be designated in batfactors using the onlyhurtby keyword, by specifying onlyhurtby aoe.

It also brought to light at least two errors with the old code, where non-aoe actions were getting through into opts[]. This new method will catch any damage source not flagged as aoe.

It also also brought to light something interesting: it appears that Käsesoßesturm is no longer an area of effect spell. The birds are unaffected by it. I tried it against a clan of cave bars, and it behaved as it would versus a single target (no "two of them" wording like what appeared when I followed up with Cannelloni Cannon). So that's something a person with Wiki access may want to change.

While I was at it, I added support for Sing Along, and a "note" field for monsters.

Enjoy!
 
Is there anything preventing multiple sixgun usage in a fight? I have a consult script using batbrain where I tell it to use a porquoise-handled sixgun then in a later round attack_action() returns a hamethyst-handled sixgun and the combat aborts due the second sixgun being unusable.
 
Is there anything preventing multiple sixgun usage in a fight? I have a consult script using batbrain where I tell it to use a porquoise-handled sixgun then in a later round attack_action() returns a hamethyst-handled sixgun and the combat aborts due the second sixgun being unusable.
Yeah, that’s not allowed. You see, your character is absolutely terrible with six-guns (note that they shoot all six bullets and only hit once), and they can’t remember which gun they’ve fired that battle. So they assume all of them are empty, and just reload all of them later.

Now, if you’re playing as an Avatar of West of Loathing, that’s a different story. They aren’t used as combat items then, however.
 
Any chance you can add support for Disguises Delimit enemy masks? Most of them should be fairly easy to implement, I think, since they have mechanics BatBrain is already coded to understand.
 
Is there anything preventing multiple sixgun usage in a fight?

No, there was no such logic in place for sixguns. r118 adds a "sixgun" happening if you use one, and will ignore all sixguns from that point on.

@Saklad5: Tell me what the string is in random_modifiers for each mask and I can add support. I'm not going to get to Disguises Delimit for a few weeks yet myself.
 
Last edited:
Thanks Theraze, being able to do a diff really sped up the editing process (especially since no line number is given yet for the friendly warnings).

r119 uses correct capitalization for monster names, as well as adds some round tracking fixes for Pocket Familiars (which is relevant for the Pocket Familiars support I'll be adding to Batman RE).
 
r120 brings us Disguises Delimit support!

  • Initial support for mask effects. I assumed 20% for most of the elemental damage masks, which I would be happy to replace with actual spading.
  • Correctly detect combat completion when you don't win.
  • To make the "instead of attacking" monsters work, I added a new monster keyword: dmgformula. This keyword can be used to specify a unique damage formula for monsters that don't follow the normal damage formula. It is expressed as a spread and can contain fvars; for instance, the batfactors entry for Your Shadow now contains "dmgformula 95+maxhp/6". This also let me streamline m_regular() (the function that returns expected monster damage) by moving a lot of custom cases into batfactors. Felt nice to compact 34 lines into 1!
Enjoy and have a happy Chuseok everyone!
 
Hey Zargon, I am getting this [110493] The Neverending Party
Encounter: "plain" girl
Round 0: txranger wins initiative!
Unexpected error, debug log printed.
Script execution aborted (java.lang.NullPointerException): (zlib.ash, line 316)
Unexpected error, debug log printed.
Script execution aborted (java.lang.NullPointerException): (zlib.ash, line 316)
You're on your own, partner.

on the newest build with WHAM, Smartstatis and Batbrain
 
on the newest build with WHAM, Smartstatis and Batbrain

And what revision of mafia?

You might also want to look up the debug file generated by this (I think on windows they are generated into the directory where you run mafia from?) and post it as an attachment. Or just copypaste relevant stack trace from it, if you can do that.
 
Code:
Unexpected error, debug log printed.
class java.lang.NullPointerException: null
java.lang.NullPointerException
    at java.base/java.io.ByteArrayInputStream.<init>(Unknown Source)
    at net.sourceforge.kolmafia.textui.DataFileCache.getReader(DataFileCache.java:193)
    at net.sourceforge.kolmafia.textui.RuntimeLibrary.file_to_map(RuntimeLibrary.java:7315)
    at net.sourceforge.kolmafia.textui.RuntimeLibrary.file_to_map(RuntimeLibrary.java:7306)
    at jdk.internal.reflect.GeneratedMethodAccessor185.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.base/java.lang.reflect.Method.invoke(Unknown Source)
    at net.sourceforge.kolmafia.textui.parsetree.LibraryFunction.execute(LibraryFunction.java:104)
    at net.sourceforge.kolmafia.textui.parsetree.FunctionCall.execute(FunctionCall.java:154)
    at net.sourceforge.kolmafia.textui.parsetree.BasicScope.execute(BasicScope.java:417)
    at net.sourceforge.kolmafia.textui.Interpreter.executeScope(Interpreter.java:393)
    at net.sourceforge.kolmafia.textui.Interpreter.execute(Interpreter.java:341)
    at net.sourceforge.kolmafia.textui.Interpreter.execute(Interpreter.java:334)
    at net.sourceforge.kolmafia.request.FightRequest.nextRound(FightRequest.java:1037)
    at net.sourceforge.kolmafia.request.FightRequest.runOnce(FightRequest.java:1917)
    at net.sourceforge.kolmafia.request.FightRequest.run(FightRequest.java:1979)
    at net.sourceforge.kolmafia.request.FightRequest.run(FightRequest.java:1950)
    at net.sourceforge.kolmafia.webui.RelayAutoCombatThread.run(RelayAutoCombatThread.java:76)
 
Last edited by a moderator:
Back
Top