BatBrain -- a central nervous system for consult scripts

Theraze

Active member
I personally quite like that it will increase my item drop rate with disco combos when in a 100% run...
 

Rinn

Developer
So what's the word on someone making an all handling combat script with BatBrain? There were a few scripts a ton of pages back and in the spamattack thread but I haven't heard anything since and it's hard to track down random attachments in thread posts.
 
Last edited:

Winterbay

Active member
There are currently, to my knowledge, three different scripts based on BatBrain: mine, Theraze's and Bale's.

They all cater to slightly different playstyles I think. Mine tries to find the cheapest and quickest way to kill the monster with your skills but is currently not working very well with moxie classes (may be because I don't have very many moxierelated skills and also dislike moxie classes...).

It works with almost all fights as a myst-class, haven't tried it yet with a muscle class but it should work there as well. The problem with moxie-classes is that it doesn't take delevelling into account, and the restoration options are not working as well as I'd like them to...

If anyone wants to play with it it's attached here (it requires the edit to batfactors that Bale posted a few posts up to include the new Fist-skills).
 

Theraze

Active member
One quick problem... you've made that moxie classes always try to use drunken baby, but only use noodles if you're in a fist-path. Also, there's no alternative provided for non-fist path or fist pre-drunken. Anyways, here's the problem code:
Code:
	if(my_path() == "Way of the Surprising Fist")
		if(get_action($skill[entangling noodles]).stun > 1 && die_rounds() < 5)
			enqueue(get_action($skill[entangling noodles]));
		if(get_action(get_action($skill[Drunken Baby Style]).id != "")
			enqueue(get_action($skill[Drunken Baby Style]), "");
I think what you wanted was this:
Code:
	if(my_path() == "Way of the Surprising Fist")
	{
		if(get_action($skill[entangling noodles]).stun > 1 && die_rounds() < 5)
			enqueue(get_action($skill[entangling noodles]));
		if(get_action(get_action($skill[Drunken Baby Style]).id != "")
			enqueue(get_action($skill[Drunken Baby Style]), "");
	}

Also, it's possible that your bee hp+ detection code is off... you work based on monster_hp, but I believe that's already been increased. As such, you'd need to do *5/(5+bs) to get base hp, and subtract monster_hp from that. So if it's a 2 b with 10 base, it should detect as 14 from monster_hp. 14*5 = 70, 70 / 7 = 10, and monster_hp - (monster_hp * 5 / (5+bs)) = 4. :)

Guess I should post my latest SA on that thread though. Not too much changed, but I'll talk about what I remember doing there.
 
Last edited:

Bale

Minion
So what's the word on someone making an all handling combat script with BatBrain? There were a few scripts a ton of pages back and in the spamattack thread but I haven't heard anything since and it's hard to track down random attachments in thread posts.

Well, I have held off on releasing my script because it won't work with the current build of BatBrain. On the other hand, even zarqon doesn't know when zarqon is going to update BatBrain so perhaps I ought to just post my version of BatBrain along with my consult script.

Another point is that unfortunately zarqon's map manager is not currently capable of updating his map scripts, so to use this with Way of the Surprising Fist, you'd need to update batfactors.

What the heck, I'll attach my combat script, BatBrain and batfactors to this post in case you'd like to try it out. It's not perfect and needs a lot of custom support files, but I think it is slightly awesome and I'd like some feedback on it.

DestroyAllMonsters v0.2 beta

Download this batfactors (overwrite the current version) to /data
Download this BatBrain (overwrite the current version) to /scripts
Download DestroyAllMonsters to /scripts

Make sure you have SmartStasis already in /scripts since it will be imported by DestroyAllMonsters.

Your CCS should be the following lines only:

Code:
[ default ]
consult DestroyAllMonsters.ash

DestroyAllMonsters will run a modified version of SS and then kill any monster for you. Hopefully. It works best if you have a nice selection of combat skills.

EDIT: Destroy All Monsters has been updated to 0.2.1 beta

EDIT 2: Script removed. It's now HERE.
 
Last edited:

Theraze

Active member
Hmm... did your copy of BatBrain miss the shieldbutt-moxie bugfix? Or is that not needed anymore? That would be the middle line of this:
Code:
        case 7081: fvars["botcharges"] = get_property("bagOTricksCharges").to_int();
        case 2003: case 2005: case 2015: case 2103: case 2105: case 2106: case 2107: if (weapon_type(equipped_item($slot[weapon])) == $stat[Moxie]) continue;
        default: dam = eval(fields.dmg,fvars);
 

zarqon

Well-known member
On my way to work today I noticed my new motherboard has arrived. This is good news for users of my scripts. Hopefully I'll be able to swiftly consolidate the forking which has taken place in my pseudo-absence.
 

Winterbay

Active member
One quick problem... you've made that moxie classes always try to use drunken baby, but only use noodles if you're in a fist-path. Also, there's no alternative provided for non-fist path or fist pre-drunken. Anyways, here's the problem code:
Code:
	if(my_path() == "Way of the Surprising Fist")
		if(get_action($skill[entangling noodles]).stun > 1 && die_rounds() < 5)
			enqueue(get_action($skill[entangling noodles]));
		if(get_action(get_action($skill[Drunken Baby Style]).id != "")
			enqueue(get_action($skill[Drunken Baby Style]), "");
I think what you wanted was this:
Code:
	if(my_path() == "Way of the Surprising Fist")
	{
		if(get_action($skill[entangling noodles]).stun > 1 && die_rounds() < 5)
			enqueue(get_action($skill[entangling noodles]));
		if(get_action(get_action($skill[Drunken Baby Style]).id != "")
			enqueue(get_action($skill[Drunken Baby Style]), "");
	}

Also, yes that should be encapsulated, but otoh that function only gets called if you are in a fist-run anyway so it is currently a moot problem :)
(it should sooner or later be expanded to take deleveling and so on into account but doesn't yet and so isn't called)
Hmm... did your copy of BatBrain miss the shieldbutt-moxie bugfix? Or is that not needed anymore? That would be the middle line of this:
Code:
        case 7081: fvars["botcharges"] = get_property("bagOTricksCharges").to_int();
        case 2003: case 2005: case 2015: case 2103: case 2105: case 2106: case 2107: if (weapon_type(equipped_item($slot[weapon])) == $stat[Moxie]) continue;
        default: dam = eval(fields.dmg,fvars);

I believe that Bale has a special function in his script (I have it in mine as well now) that disallows things that cannot be used such as shields with a ranged weapon.
 
Last edited:

Bale

Minion
That is awesome news zarqon. I hope the bats I've been sending you have kept up your spirits during this hard time.

Hmm... did your copy of BatBrain miss the shieldbutt-moxie bugfix? Or is that not needed anymore?

"Destroy All Monsters" checks for that so it was left out of my modified BatBrain. Forking code ftw. This is the relevant function:

PHP:
boolean ok(advevent a) {
	matcher aid = create_matcher("(skill |use |attack|jiggle)(?:(\\d+),?(\\d+)?)?",a.id);
	if(aid.find())
		switch(aid.group(1)+aid.group(2)) {
		case "skill 66": //Flying Fire Fist
			// Don't auto-use this if it will expend Salamanderenity.
			if(have_effect($effect[Salamanderenity]) > 3* get_property("fistSkillsKnown").to_int()) return false;
			return true;
		case "skill 2005": //Shieldbutt
		case "skill 2105": //Head + Shield Combo
		case "skill 2106": //Knee + Shield Combo
		case "skill 2107": //Head + Knee + Shield Combo
			if(item_type(equipped_item($slot[off-hand])) != "shield") return false;
		case "skill 1003": //Thrust-Smack
		case "skill 1004": //Lunge-Smack
		case "skill 1005": //Lunging Thrust-Smack
		case "skill 2003": //Headbutt
		case "skill 2015": //Kneebutt
		case "skill 2103": //Head + Knee Combo
			if(weapon_type(equipped_item($slot[weapon])) == $stat[Moxie]) return false;
		case "attack":
			if(m == $monster[Procrastination Giant] 
			  && weapon_type(equipped_item($slot[weapon])) != $stat[Moxie]) return false;
		}
	return true;
}

That wonderful subroutine handles all shield and range issues while ensuring that I won't get Cunctatitis or expend a whole lot of Salamanderenity for no reason.
 

Theraze

Active member
Sounds good. :) Though it's probably still good to have in the main source, since other consult scripts don't necessarily have your functions in them. ;) Unless they make their way into the BatBrain source instead of the consult script itself.

Trying it out today, so far it's doing quite well in general. It did decide to use attack to kill a frat boy in the war as cleanup as a pastamancer with under 120 muscle instead of using spaghetti spear or something that would have actually hit, which ended beaten up. This after using weapon to get them just BARELY alive. Ah well. Not sure why it happened, but in general it's definitely faster than the SpamAttack I was using, and I liked that it actually used the sceptre to kill hippies while getting the war hippy outfit when I had a damage familiar on a moxie class. Much less painful then manually moxious maneuvering them.
 

Bale

Minion
Yeah, it's got some quirkiness that I haven't eliminated yet. However, sometimes it is shockingly efficient and it is quite fast, even if you have every attack skill in the game.
 

Winterbay

Active member
Yeah, it's got some quirkiness that I haven't eliminated yet. However, sometimes it is shockingly efficient and it is quite fast, even if you have every attack skill in the game.

Since I think I'm going to continue tweaking my own (now that I've managed to make a big fun script, however suboptimal it may be) I wonder how long time it takes to kill a monster from the start of a fight to the end of it. Mine takes roughly 5 seconds with my skill-setup (available on my BCC-page) from calling it to executing and finishing the fight.
 

Bale

Minion
Mine takes much less than that with all the skills. I tried yours and didn't like the execution time.
 

Winterbay

Active member
I find 5s to be ok but if I remove the bit that makes it not try all permutations the execution times goes up stupidly high :)
 

Bale

Minion
Well, yours is definitely more exacting than mine. But I like combats to take less than 1 second.
 
DestroyAllMonsters v0.2 beta

Thank you very much! I appreciate your work and it's amazing to see what comes out of it!

I have two issues though:

Download this BatBrain (overwrite the current version) to /scripts

I did that, but next thing that happened was that the changes were reverted:

> Updating batfactors.txt from '2011-07-08T01:46:07-05:00, checked 20110708'...
> ...batfactors.txt updated.

I'm not sure where to tell it that the current version is actually much newer than that.


Then, I tried to use DestroyAllMonsters in some fights. First I tried an "easy" one, adventuring in the oasis as a level 16 AT, where I was outmoxying all of the monsters. I had a Slimeling, so DestroyAllMonsters decided to stasis:

> SmartStasis: 28 profit is good enough to stasis with spectre scepter

However, for some reason, at round 7 it said:

> DestroyAllMonsters: Frosty's iceball, toy soldier... killrounds: 1, dierounds: 550

This obviously killed the monster, so got its job done.

Afterwards, it tried to do this a second and a third time, with equal success; next time it didn't work anymore though:

> DestroyAllMonsters: Frosty's iceball, toy soldier... killrounds: 1, dierounds: 490
> Round 4: Zerotonine executes a macro!
> KoLmafia thinks it is round 5 but KoL thinks it is round 3
> You're on your own, partner.
> Click here to continue in the relay browser.

The reason was probably that by the third usage, the iceball had melted. Oops.

Is it a good idea to just remove the iceball line from batfactors, when I get around to getting a new one? Or is this a "bug" in BatBrain, or DestroyAllMonsters?
 

Winterbay

Active member
Yes, looking at your code it either saucesplashes, plinks (which mine admittedly doesn't), shieldbutts or attacks with the cheapest most high damaging skill/item which would definitely speed up execution. Seeing as my knowlegde of what skills are going to do what damage is very limited a normal manula combat would take a lot longer than the 5s it currently takes with the script I still save tons of time :)
 

Winterbay

Active member
Is it a good idea to just remove the iceball line from batfactors, when I get around to getting a new one? Or is this a "bug" in BatBrain, or DestroyAllMonsters?

I think the problem is that the item is flagged as multi usable and that there is no way of currently knowing that the item is limited to a specific number of turns (without saving that somewhere in a variable that is). An item is either multiusable or it isn't, which may be a lack of featur in Mafia rather than a bug in the script (even though the script should probably compensate for it somehow).
This is one of the reasons I've not included items in my one, that and the fact that the execution time would be even longer :)
 

Bale

Minion
Ick. I'm really sorry that this script destroyed your iceball. My script thought that there was no cost associated with using this item. I'd have to explicitly remove item 3391 from consideration. Fortunately that is not hard. I've updated the script in the previous post to prevent anyone else from losing their iceballs. You can download v0.2.1 beta there or here: View attachment 5238

Yes, looking at your code it either saucesplashes, plinks (which mine admittedly doesn't), shieldbutts or attacks with the cheapest most high damaging skill/item which would definitely speed up execution. Seeing as my knowlegde of what skills are going to do what damage is very limited a normal manula combat would take a lot longer than the 5s it currently takes with the script I still save tons of time :)

That is definitely not true. Take a look at this example:

[430] F'c'le
Encounter: bee thoven
Round 0: bale wins initiative!
Round 1: Princess Vina is looking a little thin.
You lose 12 hit points
2/6 monsters drop goals here.
DestroyAllMonsters: attack... killrounds: 3, dierounds: 3
Round 1: bale executes a macro!
Round 1: bale casts STRINGOZZI SERPENT!
Round 2: bee thoven takes 35 damage.
Round 2: bee thoven takes 18 damage.
You lose 39 hit points
Your slimeling needs sating.
DestroyAllMonsters: attack... killrounds: 1, dierounds: 2
Round 2: bale executes a macro!
Round 2: bale attacks!
Round 3: bee thoven takes 20 damage.
Round 3: bee thoven takes 9 damage.
Round 3: bale wins the fight!
After Battle: Princess Vina hops around, dancing a jig accompanied by wet squelching noises.
You acquire an item: handful of honey
You gain 13 Fortitude
You gain 10 Mysteriousness
You gain 19 Chutzpah

DAM noted that my attack would hit the monster, but wouldn't kill my enemy before it killed me so it attacked with stringozzi serpent and finished it off with attack. Cool beans!

I've also had some great success in early aftercore farming when my best item gear used ranged weaponry that I could not hit with (because I was a muscle class) so DAM killed the monsters with funkslunging Destroy-o-bots. That's a good reason not to exclude items. Here's another nice example of my consult script in action:

[217] Haunted Gallery
Encounter: empty suit of armor
Round 0: bale wins initiative!
attack
SmartStasis: -14 profit is too low to stasis with attack
skill 2023
DestroyAllMonsters: Toss... killrounds: 10, dierounds: 13
Round 1: bale executes a macro!
Round 1: bale casts ENTANGLING NOODLES!
Round 2: Gog pulls it into an impromptu mosh pit, stomping it for 17 damage.
Round 2: empty suit of armor takes 17 damage.
Round 2: bale casts TOSS!
Round 3: You pick up Gog and toss him at your opponent, dealing 14 damage. Go Gog!
Round 3: empty suit of armor takes 14 damage.
Round 3: Gog kicks it into next week, for a time-traveling 29 damage.
Round 3: empty suit of armor takes 29 damage.
Round 3: bale casts TOSS!
Round 4: You pick up Gog and toss him at your opponent, dealing 14 damage. Go Gog!
Round 4: empty suit of armor takes 14 damage.
Round 4: Gog kicks it into next week, for a time-traveling 28 damage.
Round 4: empty suit of armor takes 28 damage.
You lose 19 hit points
Round 4: bale casts TOSS!
Round 5: You pick up Gog and toss him at your opponent, dealing 14 damage. Go Gog!
Round 5: empty suit of armor takes 14 damage.
Round 5: Gog does a little dance on top of it, to the tune of 22 damage.
Round 5: empty suit of armor takes 22 damage.
Round 5: bale wins the fight!
After Battle: Gog does a few high kicks. When you're a pair of boots with no legs, the sky's the limit for how high you can kick.
You acquire an item: antique spear
You acquire an item: antique shield
You gain 16 Strongness
You gain 8 Magicalness
You gain a Mysticality point!
You gain 9 Chutzpah

I would have thought to use entangling noodles and two shieldbutts. DAM decided to use entangling noodles and three tosses. I saved 10 MP at a cost of 19 HP! I think that DAM made the best choice.
 

Winterbay

Active member
DAM noted that my attack would hit the monster, but wouldn't kill my enemy before it killed me so it attacked with stringozzi serpent and finished it off with attack. Cool beans!

Yep, but it had to stop in the middle to recalculate that :)
I quite like to have it figure out the entire strategy in one go (like your last example, mine does things like that quite often if ti can get away with it). As I said in my reply to Rinn the main difference is playstyle choices (well that and speed...). I like to consider all my skills and combinations of them because that's fun :)

Edit: I'd really like it to be able to consider "attack" as a skill though which it currently doesn't. It either attacks or uses skills not both.
 
Top