Feature - Implemented Include variable/scaling monsters in monster stat functions

Okay... jasonharper added a few of these modifiers into the modifier evaluator.
A = GetAscensions
MUS = GetAdjustedMuscle
MYS = GetAdjustedMysticality
MOX = GetAdjustedMoxie
ML = GetMonsterLevelAdjustment
MCD = GetMindControlLevel

The question is, since these are now all in the base evaluator, should I scrap the work I'd done to split out the evaluator into 3 sections and just give an updated monsters.txt file that uses these? Everyone now has access to these, so the only work I'd need to keep around is the monster loading and file update... the evaluator should be a non-event since it's in base already.

The only thing this doesn't do is note whether MCD is detuned or one of the other 3 choices... if I understand properly, Wormwood only avoid detuned MCD, and take MCD from the elevator/canadian MCD/annoy-o-tron... If this is not the case, and all MCDs are in fact created equal in this, then the only update the evaluator needs is implementing Rinn's multi-string allowance.
 
That's where it currently is on mine... his work is implemented into Rinn's work, which is integrated into my work. But the question with the stats becomes, if adjusted stats and everything else we'd want are implemented into all 3 evaluator sets, what's the difference between MonsterEvaluator and Evaluator? MonE uses only items from the base evaluator now...

If I'm not supposed to get rid of all of it, still sort of tempted to kill MonE, and just keep ModE and pureE. Monsters don't need access to familiar weight or other zone issues, at least not currently, and everything else is in pureE now...

And I wouldn't be scrapping all of it. Just the Evaluator changes, which are stuck and unlikely to get unstuck due to needing to recode the base structure. I'd just focus on the MonsterDatabase changes, which would be potentially releasable today/tomorrow for people to try.

The bottom line on Evaluator is that the point of its recode, as I understand it, is to make it act exactly the same, but more efficiently. The issue I have is not understanding exactly how it's working now, making it very difficult to emulate. I suppose I could turn the private functions public, and then generally call the main Evaluator functions with the exception of value... the problem with trying to do that is that term calls factor, and factor calls value, and value calls expr, and expr calls term... so if I was using the public/base of any of those 4 functions, it would call the base of all 4 functions, not the one I want. Basically, I don't know how to make it run in a more efficient way without making the whole system not work.

Anyways, since I have no clue at the moment how to make it more efficient, here's where I'm up to/stuck at. Not including my monsters.txt currently, because I'll likely recode it to use jason's MUS-type bits instead of my currently single letters (visible in the MonsterEvaluator section).

Edit: Set my system to use his bits. Now Rats evaluates like this...
> ash monster_attack(to_monster("ratsworth"))

Returned: 223

> ash monster_defense(to_monster("ratsworth"))

Returned: 121
Anyways, time to ignore this until either there's a breakthrough, or I get the go-ahead to ignore further Evaluator changes in one method or another. :)

Edit2: Sidenote on my MonsterDatabase - Includes two updates to unspaded item behaviour that were talked about on the pickpocket thread. Unspaded items retain their former behaviour and pickpocket attempts will follow them, and also deciding that its behaviour should follow pickpocket more than bounty and those... pickpocket chance is set to use its drop chance, or 1% if not set.
 

Attachments

Last edited:
I just looked at your patch.

I think you miss the point of classes and subclasses: when a class extends another class, the subclass does not need to copy every single thing from the superclass. Instead, if properly designed, it only changes things that differ.

I told you how you could adjust the superclass to make that work in this case. You did not do what I suggested.

I'll refactor your patch and submit it.
 
Thanks. Like I said, I have no clue how to adjust the superclass... I tried removing the parts that were the same from the ModifierEvaluator and MonsterEvaluator, and it completely failed to compile/run/work. I did really try... It was just an abject failure.
 
Veracity is all sorts of awesome and cleaned up my confused garble into a more pretty and properly looking state... Problem I'm getting now is that the code that was properly working before to pull monster data is now returning this:
Evaluator bytecode invalid at 0: L€+胈mr

Is there a good way to tell what/where is passing this invalid Evaluator, or even what it's supposed to be?

Edit: Found it. There was a 'L' left from when I had that for ML before. However, the letters aren't properly evaluating anymore...
> ash monster_defense(to_monster("ratswor"))

Returned: 3

> ash monster_attack(to_monster("ratswor"))

Returned: 3

Those are using
Def: MUS+min(3*A,12) Atk: MOX+min(3*A,12)

Edit2: Looks like something about the extending of multiple-character bits isn't working currently?
> ash monster_eval("MOX")

Returned: 0.0
I rebuilt my base_eval and monster_eval functions using the newly updated modifier_eval. It's detecting as a valid option... but pulling 0 as its number.

Edit3: Think I found it... MonsterExpression, line 87. return 0.0f instead of return v.
> ash monster_attack(to_monster("ratswor"))

Returned: 223

> ash monster_defense(to_monster("ratswor"))

Returned: 121
 
Last edited:
I did not check in your changes to MonsterDatabase.java. I assume you changed them to use a MonsterExpression?

Edit: Never mind. I found it.

> ash monster_eval( "MOX+min(3*A,12)" );

Returned: 506.0
 
Last edited:
Here's the fix to make MonsterExpression work properly. As it stands, it always evalues a float of 0 currently, ignoring any set value of v.

And yes, with this fix, my scaled monsters are. :)
 

Attachments

Theraze, I've finally found time to look over your patch in detail, and I'm seeing several major problems...

1. The way you're currently parsing the expression out of the monster details will break if there's ever a space inside an expression (which could happen with a text function, although none are currently very useful with monster stats). There's a reason why modifiers.txt expressions are enclosed in brackets...

2. Maybe I'm looking at an old version of the patch, but it appears that you're creating the expressions when monsters.txt is loaded, evaluating them right then, then discarding the expressions - in other words, the stats of scaling monsters wouldn't have anything to do with the player's current stats.

3. It doesn't seem that the stat values returned for scaling monsters would have the same meaning as those for ordinary monsters. The callers of the MonsterDatabase info functions are currently applying ML adjustments themselves; that's inappropriate for scaling monsters, where whatever ML effects might exist would be included in the expression. Proper support of scaling monsters is probably going to require modifications to every MonsterDatabase access, to let it handle all ML adjustments itself. I would have done that already, if I had the slightest idea of where the full monster defense values are supposed to be used, and where the 90% actual monster defense values are used. For that matter, it's not really clear which version of monster defense is being returned by the proposed scaling monster formulas...
 
Guessing you're using the old version... the newer version runs differently. Mostly.

1) Yes, spaces break. That's because the way the parsing in current committed code works, spaces are the breaks between segments, and I didn't change that... I left it as it was. If we want to force paragraphs between each entry, we could do that... but it's a change to the way the existing system works. My goal was leaving things as similar as possible, in a non-breaking way.

2) Not anymore. And actually, not even in the old one. Except the first one. In the old (working) one, it evaluated when it saved the string, as well as when it called the values. In the original, yes, it evaluated when it first loaded, and nothing ever worked. You'd get values of 3 for Baron von Rats, because that was the min, and that's the only guaranteed value. That version was just depressing. In the most recent one, it just saves the string if evaluating, and does its calculation when you're actually calling the value, not otherwise. Less wasted effort, basically.

3) True. Which is why the values got fixed. Ish. In my copy, FightRequest checks against Monster.getEvaluating() to see if it's a static monster or not. The function getHealthAdjusted already takes scaling monsters into account, as that's in MonsterDatabase. The two in FightRequest are getAttack and getDefense, and both should return just the base value if getEvaluating is true. The dodge checks and the like should already be fine, as those run off of the attack/defense checks. What still needs to be fixed up is RuntimeLibrary and its checks... think everything else should work.

For that matter, what I thought you were going to bring up with number 3 is the statgain for scaling mobs... as statgain is based on attack, and their attack varies, the former statgain calculations don't work too well. On my copy, it works for scaling or not.

But yes, ignore the earlier patches, they've been rejected. I accidentally deleted the patch that Veracity worked through. I'll reattach it to its post, above... It's semi-irrelevant now, as its pieces have either been implemented, rejected, or refactored... but it gives some ideas on how MonsterDatabase is tweaked, pre-new-submittal.
 
I know this isn't complicated enough yet, so there's yet another mechanic now with crimbo monsters where they only scale if you wear an accessory for to make them scale.
 
And I love it. When I want to level up I go with the accessory, when I just want to farm CRIMBCO Scrip I do not. It is perfect :)
 
I know this isn't complicated enough yet, so there's yet another mechanic now with crimbo monsters where they only scale if you wear an accessory for to make them scale.

They are at least simple, it seems :

Att = Moxie + ML, uncapped
Def = Muscle + ML, uncapped
HP = Def x 0.75, rounded down
 
Yeah... mine has them. I decided to just always use the scaled stat, since the unscaled is just 10 for each... 10 attack, 10 defense (drops to 9 combat), 10 health. Suppose I should probably fling out an updated MonsterDatabase, FightRequest, and RuntimeLibrary patch sometime soon for perusal.
 
Okay, here's my current scaling/full patches. Just scaling is the file ScalingMonsterStructure.patch, which does this:
Adds handling for scaling monsters to MonsterDatabase, FightRequest, and RuntimeLibrary.
Changes pickpocketting of unspaded drops to always trigger, as it does for 0% drops, in the MonsterDatabase.
Adds the ability to check monster_attack/monster_defense/monster_hp against the desired ML+- to RuntimeLibrary. This doesn't trigger on scaling monsters, but should for anything static.

Full patch is ScalingMonsterStructurePlus.patch, which includes the following:
Above changes.
Adds HotTub as an automated health healing option to HPRestoreItemList. Detects if you've used your 5 soaks yet, will only automatically trigger if selected as an option and your health is currently less than half.
Adds a bit of new Tavern handling to KoLmafia file and TavernRequest. Specifically, changes the 'where' to use 'whichspot' and sets the action to 'explore' so that it actually checks the square. Also, faucet adventure is now named Of Course!, the Baron's mansion adventure is named is it Still a Mansion, and any other choice adventure should be tagged as the second (non-combat) type of adventure. I started this, but eventually gave up as I didn't find a good way to random-hunt.
Adds the ability to HolidayDatabase and RuntimeLibrary to pull the specific gametime to an int. This allows for checking rollover statistics and delay without multiple server hits, as this pulls based on the information set on logon (I believe). Basically, a server friendly way to do this.
Adds sushis to ItemDatabase as negative IDs. This allows them to be created with ASH, instead of just working with CLI commands.
Adds Inigo handling to ConcoctionDatabase and CreateItemRequest. Basically, when it asks how many turns it will take, subtract 5 turn-sets of Inigos from the needed adventure count.
Add categories to the lookup command, in SkillDatabase and WikiLookupCommand. Normally the lookup command works as it did before. If you run lookup effect/familiar/item/skill (or their plurals), it will check only on that one category. Autocapitalize familiars before passing to the Wiki, to properly get the Black Cat familiar instead of the black cat monster.
Disable tower automation while Form of... Bird! is active in SorceressLairManager. If you can't use items, you can't automate the tower.
Put the Warm Subject Gift Certificate along with the other items in CleanupJunkRequest. It may have had a purpose historically for having its own section, but it's now using exactly the same code as the others, so it might as well join them and clean up the code a bit.
 

Attachments

Well, since we've passed a week without complaint on this version... here's my monster data diff. This mostly sets the scaling/variable monsters to what they've been tested to, though it also fixes a typo or two like the CRMIBCO Cubicles heading. As well, some of the other monsters that had Hp: 0 and nothing else (mostly sea monsters of various sorts) now have proper information. One other bit is that some of the monsters have their Initiative set now, since the code supports it (but none of the current datafile monsters had it).

Oh yes... not a change to the datafile here, but a change that happened to the patch above that I can't remember whether it was noted or not. Added HP as a keyword with a unicode bit. This is based on monsters like http://kol.coldfront.net/thekolwiki/index.php/Data:Candied_Yam_Golem where their health is based on 75% of the player health. Wasn't sure if it was meant to be max or current health, so did max health, since that should estimate stronger/same.
Summary: HP returns my_maxhp().

Edit: Looks like the cubicle typo did get fixed in commit already. :) I just missed seeing that since I can't implement those changes.
 

Attachments

Last edited:
I can drop a new version of the patch if people are interested. Otherwise, I think it's still waiting for people to either come up with problems with it, or the devs to suggest/change/reject/commit.

That being said, I'm guessing they're waiting on the new main version spin. After that happens, maybe this can enter their timesphere again.
 
Back
Top