Feature In Combat queries

dier_cire

New member
noticed we have will_usually_miss() and will_usuall_dodge() but I was thinking it'd be nice to have more info than a bool. Perhaps expanding these to include some that give the rough percents? Currently, since I want to be able to adjust when I attack beyond the 50% mark, I'm doing it manually.

Also, possibly getting an expected damage that you would inflict when attacking function? Currently, we only have how much the player will take. Accounting for skill attacks would be nice too, but just regular attack would be a great start.
 

Alhifar

Member
Actually it returns the maximum damage taken and the minimum damage done. Most of the numbers would need updated for an average result.
 

dier_cire

New member
yeah, both things are fairly well known formulas, just thought they'd be useful as built in functions so we all don't have to do it manually/copy from other sources. Sorta just expanding the sorta hook that the expected_damage(), will_usually_dodge(), will_usually_miss() grouping started.
 

StDoodle

Minion
Yeah, the problem is, if you want to truly account for the range of possibilities it gets a bit complicated. Criticals, fumbles, etc...
 

dier_cire

New member
Not so much complicated, as requires more functions. expected output would mostly ignore those (and your hit %), since it'd have to assume a normal hit. Total average expected damage per round would be neat, but not sure how great since you'd normally choose your attack style based on your % to hit since it's tied to either your damage or your ability to take less. That said, I could see how it'd be nice to just determine easily whether you'll survive the fight.

So maybe I (others are free to join in) should come up with a list of functions?
 

StDoodle

Minion
Feel free to discuss this further, as far as what you'd like to see, as I really am in the process of writing a fight logic library. For reals.
 
A library could be pretty useful. I guess Zarqon must have something already, for Batman, and I have a set of routines as well, for FightOptimizer. One of the problems I found with the original FightOptimizer was that all the formulae take the most pessimistic values (like Alhifar mentions above). This will prevent you from ever getting beaten up, but can make for a very expensive fighting strategy, and sometimes, particularly when plinking, it couldn't find a winning strategy at all.

So, you'll probably need monster_damage_max(), monster_damage_average(), player_damage_min(), player_damage_average(), player_hit_probability(), monster_hit_probability(). They all need to take a monster as a parameter, and it may also be useful to take a ML adjustment parameter, so you can experiment with "how much do I need to delevel monster by to get player_hit_probability() > 0.5 ?"

Spell damage is another interesting area; spell_damage_min() and spell_damage_average() would be useful, but can get quite complicated. You need to know the monster you're fighting, and if the spells are elementally aligned (flavour, immaculate). For sauce spells you'll want to know if splashback applies.
 

slyz

Developer
Zarqon's combat suits considers 'spreads', from which you can take min, max, or whatever weight you want. I think a fight library should also do this.
 

StDoodle

Minion
Yeah, I'm thinking of using records actually, with a .min .max and possibly .avg as well as .critp (crit percent) and whatever else seems appropriate. Though now that I think about it it will likely have these for all of physical and each element in some manner... probably as an array of the above, I dunno yet. I should probably look further into zarqon's scripts and see what he has first.

Edit to add: In a perfect world, I'd like my script to get along as well as possible with other scripts. ;)
 
If you include crits, you'll find that avg != (min+max)/2, so it's useful to include it as a separate result. I wonder if it's worth talking to Zarqon; he may move some of his functions into zlib. Do you want functions that just use monster_hp(), monster_attack() etc., or do you want to say things like: "what will be the monster_damage() if I cast tango of terror?" If you just want something that reflects the current battle situation, you can use a lot of Mafia built-in functions, but if you want functions that can be used to simulate a strategy, you'll need to pass in the monster, it's current HP, attack, defense etc.
 

dier_cire

New member
I think more often than not you want the current situation. Now a good suite would include passing in a $monster[] so you can predict a bit. Generally, you'd take the toughest monster in a zone and check against that. If there is a good chance (or any chance depending on your style), you'd add a buff or two (possibly calculating how many you need based on percent) and re-check. Kinda clunky but avoids the horrendous code of passing in additional effect you'd want to use.

I'd definitely keep crits and non crits seperate since you can calculate the average of them on your own easily assuming you have min, max, hit %, crit min, crit max, and crit %.

In addition, another concept might be for my_(avg/max/min/etc)_dmg(), you might include a passable (defaults to attack) attack type. I.e. my_avg_dmg($skill[Toss]) would return 1-17 based on your familiar weight.

And I look forward to a suite. Running 5 turns with 1100+ lines of code (okay so half are comments) is getting crazy.

EDIT: Should this get moved to Scripting Discussion since it's sorta outside "feature" anymore?
 
Last edited:

StDoodle

Minion
Well, this probably would be better off in scripting discussion, but the fact is that I'm just going to come up with my own method and roll with it. ;) Every time we try to discuss the "perfect framework," we tend to get bogged down on one or two details and then things get stuck. Better to ask forgiveness than permission, right? :p
 

dier_cire

New member
lol, sorta.

But yeah, doing something is better than nothing. It's easier to tweak something that exists versus trying to get it perfect first. I'd just start out fairly simple and low level (which is mostly what has been described here) and once that's in, we can develop more complex and intelligent functions later. No sense in trying to go crazy only to find out what you did was pretty much worthless.

If you need any assist or want a second pair of eyes, let me know.
 

Theraze

Active member
Here's a question... noticed in either the wiki or KoLspading recently (think it might have been spurred by someone here, but can't remember) that someone found that the 'safe' level is actually 11, not 7, and they kept getting hit through 10 (though rarely, at that point) ML off. I think our current safe check assumes 7 is safe... should I change that to 11 and spin a patch, or are we happy as it is?
 

slyz

Developer
If there is a good chance (or any chance depending on your style), you'd add a buff or two (possibly calculating how many you need based on percent) and re-check.
There's the "whatif" CLI command: you could pass a string to the library containing the whatif command and work with numeric_modifier("_spec", modifier) instead of simply numeric_modifier(modifier).
 

Fluxxdog

Active member
Here's a question... noticed in either the wiki or KoLspading recently (think it might have been spurred by someone here, but can't remember) that someone found that the 'safe' level is actually 11, not 7, and they kept getting hit through 10 (though rarely, at that point) ML off. I think our current safe check assumes 7 is safe... should I change that to 11 and spin a patch, or are we happy as it is?
Um, the wiki and the spading linked from the wiki both say ML+10, not 11. What am I missing?
 

Theraze

Active member
Looks like you're right and it's 10 points above where you're safe, 9 points below where you'll always miss. Think I might have gotten mixed on the 10.5 figure and gone up/down from there instead of between 9/10. Anyways, the fact remains that when I was poking through mafia, its safe counter was still set to 6 or so... This is from MonsterDatabase...
PHP:
  public boolean willUsuallyDodge( final int offenseModifier )
  {
   int ml = KoLCharacter.getMonsterLevelAdjustment() + offenseModifier;
   int dodgeRate = KoLCharacter.getAdjustedMoxie() - ( this.attack + ml ) - 6;
   return dodgeRate > 0;
  }

Assuming no offense or level adjustment, it returns that will 'usually' dodge if moxie - attack - 6 (so for second form NS, 211) is less/equal to zero. The part I'm not sure about is whether this is meant to say that you'll only get hit if it's a critical hit, or not get hit > 50% of the time. By the second, it's right. My guess though is that it's based on the first instead... By that, the -6 should be -10 instead, so that 215 moxie gets the dodge consideration properly.
 
Top