r18 Update!
Since the number 18 sounds kind of like a curse word in Korean, I'm going to swear in this post!
Me: Post, do you solemnly swear to contain the awesome updates in r18?
Post: I do.
Cool, post sworn in! Now, for the updates, and they are many and awesome:
The big change -- which just broke WHAM until Winterbay fixes it -- is that the custom field is now a string. You won't fully realize how awesome this is until SS updates, but when it does, prepare to be pleased. We can now not only specify custom actions in batfactors, we can also append a category after the custom keyword for actions which provide a similar custom mechanic. So far, the categories SS is going to support are:
attract, banish, yellow, copy, and
runaway. Then, when you want to banish a monster, you'll be able to -- oh, what's this? A new
custom_action(type) function in BatBrain? And it returns the most profitable action in a given custom category? So wait -- if I had specified some monsters to attract in
BatMan_attract, and SS encountered one of those monsters, it would Olfact that monster OR jiggle the cream staff if I was in AoJ? Fantastic! Or if I had specified certain monsters in
BatMan_banish, SS could use this function to choose the cheapest banishing option and banish the specified monster with a banishing skill
or item? Oh my goodness! 18!!
Another very cool feature that happened as a result of this process is that BatBrain now adds informational counters whenever you banish a monster with a temporary banishment, such as a crystal skull. The counter shows the item or skill you used to banish the monster, and contains the name of the monster, plus "banished". It is set to the number of banished rounds specified in batfactors for the action. So it is now possible to detect with great accuracy whether or not a monster is currently banished. In fact, look at this nifty function from the upcoming BatMan RE release:
PHP:
boolean is_banished(monster m) {
if (m == $monster[none] || m.boss) return false;
if (m == to_monster(get_property("_nanorhinoBanishedMonster"))) return true;
switch (my_class()) {
case $class[avatar of boris]:
case $class[zombie master]: foreach i,s in split_string(get_property("banishingShoutMonsters"),"\\|") if (m == to_monster(s)) return true; break;
case $class[avatar of jarlsberg]: foreach i,s in split_string(get_property("_jiggleCheesedMonsters"),"\\|") if (m == to_monster(s)) return true; break;
}
if (get_counters(m+" banished",0,20) != "") return true;
return false;
}
It's going to use that function to dim banished monsters in the combat queue. But I'm getting ahead of myself! Eighteenit!
As mentioned previously, the autoresponses for Colosseum monsters are mostly working. It's still not safe to fully automate combat against monsters there, however, since the script may use your Mer-kin skills as a normal combat action, preventing that skill from being available later as an autoresponse. But combats in BatMan RE were working nicely. The macro section is also not fully finished, as I haven't yet made the macro loop on itself, or whatever it has to do there. So it only macrofies the first autoresponse, and all the following autoresponses are single server hits. Once I add Mer-kin weapon skills to the temp blacklist when in the Colosseum and fix the macro, that will be all done and we will be able to completely automate that zone.
And now for a significant pile of smaller but not unimportant fixes!
- More vprints() for better debugging. Now when there's a formula error, verbosity 9 will let you narrow it down to which line in batfactors contains the error.
- Slightly faster matcher in to_event(), allows us to ditch two contains_text() calls. Sonofaneighteen!
- Refactored the loading of batfactors to fix several order-of-operations errors! Since we're now loading monster information from batfactors, we can't normalize the damage types (which calls dmg_dealt(), which needs to know monster resistances) until after we've set the monster. However, we can't set the monster until after we load batfactors. So I split the batfactors loading and parsing into two separate functions, and call them both from within set_monster(), towards the beginning and end of the function, respectively. This means several excellent things:
- BatBrain can now be used predictively outside of combat, sequentially simulating combats for a series of monsters, as batfactors itself is completely reloaded when you set the monster.
- Sauceror skills with Immaculate Seasoning now properly choose an element.
- "perfect" damage now correctly chooses an element. You get the picture.
- Related to the above fixing of tuning damage, I let BatBrain know about a few heretofore unknown pieces of equipment which also tune damage: the slime-covered staff, The Necbromancer's stein, and the Wand of Oscus.
- Fixed another OoP error: Calculation of poison danger was being performed in set_monster(), calling attack_action(), before opts[] was even populated. So now we calculate poison danger in build_options().
- Cap DA and DR on the low end at 0.
Enjoy, you eighteening eighteeners!