PDA

View Full Version : Thoughts on Armor Class


killspree
03-25-2004, 12:23 AM
When looking at the AC formula for the EMU I've noticed one major flaw that is incorporated when compared to EQLive. EQLive AC does not actually lower the maximum hit of the NPC, but EQEMU code does.

What AC seems to do though, is lower the average damage taken - basically making it so while you sometimes can take a max hit, you will often take lower damage overall the higher your AC is.

So what I propose is an added factor into the mitigation equation, sort of a mod which determines "will this hit do max damage? or will it be mitigated slightly?" Obviously we'll need to include other factors which I believe haven't been coded yet, like monster attack values, level vs player level, etc. All of those should have an impact on the effectiveness of mitigation as well - much like they seem to do on EQLive.

I'm going to be testing this out on my server over the next few days - so far all I've done is added a random factor of sorts called "acFac" that creates a random value to decrease the hit by - starting at 0 and going up to the value that previously decreased the hit every time.

Old code looks like this:
if (damage > 1 && spell_id == 0xFFFF){
double acMod = GetAC()/100;
double acDam = (damage/100)*acMod;
damage = (sint32)((float)damage-acDam);
if(damage <= 0)
damage = 1;
}

And with acFac added:
if (damage > 1 && spell_id == 0xFFFF){
double acMod = GetAC()/100;
float acFac = MakeRandomFloat(0, acMod);
double acDam = (damage/100)*acFac;
damage = (sint32)((float)damage-acDam);
if(damage <= 0)
damage = 1;
}

Now currently it uses MakeRandomFloat(), but I'd like to hear opinions. Should it use this or MakeRandomInt()? I'm not sure myself, MakeRandomFloat() gives a wider array of possible damage values, but so far in the minor testing I've done, I've yet to be hit for max damage.

But the good news is, even with insane AC, the hit values are much more inline with what you'd expect from EQLive. I'll be parsing the averages as well during testing to see if there's any positive effect of higher AC in that regard.

Basically to give an example:

With the old code above, an even con NPC with a max hit of 500 with the character having over 6k AC(yes this is VERY extreme, but I wanted to confirm what I expected) would hit for around 108 at most - this was over a 10 minute period of being hit constantly, never once was I hit for more than that.

Now, with acFac added in, the max hit was at about 496. I'll update with tests of various AC values to see if decreases in average damage occur like I hope they will.

Scorpious2k
03-25-2004, 02:23 AM
I took a slightly different approach to this.

I would think that AC should always give *some* protection against damage. The amount should vary with each hit. I agree with you that it should not be a constant.

Here's what I did:

if (IsClient() && damage>0)
{
int acwork=GetAC()/20;

if (acwork>0)
{
damage-=acwork;
damage-=rand()%acwork;
if (damage<0) damage=0;
}
}

So you get 5% to 10% protection from each hit. These values need to be adjusted. But it doesn't seem to me that if you have a lot of AC that you should ever get hit for the maxdmg.

killspree
03-25-2004, 02:27 AM
I did a few brief parses with some test items I created to see if higher AC does indeed decrease average damage while allowing the max hit to remain possible, with this code. I found some interesting things out that I hadn't checked yet.

For one, minhit doesn't appear to be working correctly, I'll see about fixing it(or adding it if it just wasn't ever put in), and trying the parses again later. I'm wondering just how much minhit not working properly factors into the decrease in average damage - we shall see.

Now on to the parses:
Time..................AC...................MinHit. ...........MaxHit...........Avg
4:28..................762.................163(1).. ..........498(2)..........365
4:42................1548.................159(1)... .........499(1)..........352
4:46................2336.................136(1)... .........496(1)..........325
4:43................3123.................100(1)... .........496(1)..........304
4:50................3910...................93(1).. ..........489(1)..........280
4:46................4697...................73(1).. ..........499(1)..........261
4:50................5485...................45(1).. ..........495(1)..........235
4:46................6271.....................1(4). ...........490(1)..........201

Now some info on the NPC in question - it was a level 65 NPC with a minimum hit of 125 and a maximum hit of 500. As you'll see from the parses, even with extreme increases in AC, max hit is still possible to acheive, while average hit continues to decrease.

I used fairly drastic increases in AC with these parses, I'll be creating a few realistic item sets over the next day or so and running tests with them. For anyone wondering, those AC values were the client values. Below is a list of each AC value and the #showstats value in parenthesis.

762(1306)
1548(2592)
2336(3880)
3123(5167)
3910(6453)
4697(7741)
5485(9028)
6271(10315)

As you can see the AC code definitely needs tweaking as the server thinks the player has way more AC than the client does.

killspree
03-25-2004, 02:31 AM
I took a slightly different approach to this.

I would think that AC should always give *some* protection against damage. The amount should vary with each hit. I agree with you that it should not be a constant.

Here's what I did:

if (IsClient() && damage>0)
{
int acwork=GetAC()/20;

if (acwork>0)
{
damage-=acwork;
damage-=rand()%acwork;
if (damage<0) damage=0;
}
}

So you get 5% to 10% protection from each hit. These values need to be adjusted. But it doesn't seem to me that if you have a lot of AC that you should ever get hit for the maxdmg.

That's a really good idea as well. One of the main reasons I thought it would be good to always make max possible when factoring raw AC is because of other variables that I'll be adding on my server, such as certain stats lowering max hit, etc.

smogo
03-25-2004, 02:36 AM
I would think that AC should always give *some* protection against damage
Rolemaster vs Ad&d styles =).
Good to see computers didn't bury the question 8)

RexChaos
03-25-2004, 02:47 AM
I would think that AC should always give *some* protection against damage
Rolemaster vs Ad&d styles =).
Good to see computers didn't bury the question 8)

Rolemaster > AD&D ....especially since this type of combat could be computed on the fly and not interrupt game play. :)

Anyway, back to the AC topic - I'm looking forward to this being implemented... my level 8 ranger was killing mobs that were level 20 because their AC was funked up. Hehe... just not right.

Scorpious2k
03-25-2004, 03:23 AM
We've been testing this on our server for about a month. After several adjustments, this is what we ended up with. As I say it isn't right, but its better than nothing.

If you're thinking of adding unque functions and methods to your server then I would #ifdef it and make it right for you. The code for our server is full of #ifdef SCORPIOUS2K. :-)

Scorpious2k
03-25-2004, 03:24 AM
Rolemaster vs Ad&d styles =).
Good to see computers didn't bury the question 8)

Heh... busted. Yup, I'm and old AD&D player.

Scorpious2k
03-25-2004, 03:27 AM
Anyway, back to the AC topic - I'm looking forward to this being implemented... my level 8 ranger was killing mobs that were level 20 because their AC was funked up. Hehe... just not right.

That's not the code, its the DB. When you have a DB designed for virtually no AC, when it comes into the calculation you find mobs suddenly can't touch you. The values for mindmg and maxdmg have to be adjusted. We made several DB value changes before we felt it was right.

Fair is fair... I'm looking at way way to give mobs AC too. That should make things more interesting.

RexChaos
03-25-2004, 04:20 AM
That's not the code, its the DB. When you have a DB designed for virtually no AC, when it comes into the calculation you find mobs suddenly can't touch you. The values for mindmg and maxdmg have to be adjusted. We made several DB value changes before we felt it was right.

Fair is fair... I'm looking at way way to give mobs AC too. That should make things more interesting.

Well the min and max dmg of a mob does little to combat a ranger with a bow. :) I like your idea of AC for mobs though. I think the game will improve a LOT once ac is factored for pc's and ac is added for mobs.

killspree
07-24-2004, 08:15 PM
A bump to a very old post, I know, but I've been away for a long time due to many reasons and figured I'd update folks with the minhit not working that I found.

It's because AvoidDamage in attack.cpp doesn't recognize it as minhit - it still reduces the damage done when factoring in AC, even for the minhit.

To give an example:

NPC has minhit of 200, maxhit of 500
NPC hits for minhit and it's then sent to Mob::AvoidDamage() as the damage amount - which has AC factored in to lower that damage even more.

What I did to fix this was add another field to Mob::AvoidDamage() and called it minhit. This then pulled the minimum damage an npc can hit for and factored it into AvoidDamage. I then put a check in Mob::AvoidDamage in attack.cpp to ensure that if after the AC mods were factored in, the damage was lower than minhit, it used minhit as the damage value.

sotonin
07-25-2004, 03:53 AM
Killspree i would very much like your code additions for this. and I would love them to be put in the CVS as well.

I am very unsatisfied with the way combat is working for my server. With ac added that is on par with or less than the average player of the same lvl, combat is very trivial as the mobs can barely hit the player.

I like your numbers and they appear to be more like live that the current ac system allows.

Armanthuz
07-25-2004, 04:55 AM
The exact formula for mob dmg is already known for most part it is..

ripping this from.. http://www.thesteelwarrior.org/forum/showthread.php?t=13


Restatement of model:

Quote:
The damage a mob does on a standard hit is DB + x*DI, where DB stands for Damage Bonus, DI stands for Damage Interval, and x is an integer between 1 and 20 (inclusive)


Breakdowns:

Damage = DB + (x*DI)
DI (Damage Interval) = (max hit) - (min hit) / 19
DB (Damage Base) = (min hit) - DI
x = integer between 1 and 20, inclusive
min hit = DB + DI
max hit = DB + 20*DI



So youd have to rewrite the dmg model first as it stands, then figure out a way to incorporate AC from a mob hitting a PC.

There is no way to figure the exact curve because of several reasons.

1. We have no way of knowing the MOBs ATK value.
2. We dont know the exact effects of def. AA on AC and mitigation.


In general if you chart a curve based on mobs atk vs clients AC it is not linear, in fact there is a "soft cap" where adding more ac gets you less and less dmg reduction.

sotonin
07-25-2004, 05:10 AM
Hmm. very interesting read. perhaps they can use this to re-vamp the combat system.

animepimp
07-25-2004, 05:57 AM
Yeah but the problem is this formula is probably not entirely accurate, and it doesn't take into account AC or attack or anything else. The formulas posted everywhere on the web are just guesses that fit the data most of the time. Also those variables are different for every mob and theres no good way to figure them out. Its pretty much useless because the formula for the initial calculation of damage at least is pretty good and reasonably accurate in the Emu. Our problem is mostly in factoring in AC and attack which this doesn't touch.

killspree
07-25-2004, 08:08 AM
Rewriting the damage code would bring about a whole extra project of redoing the database and adding new fields, so it's probably too much for something that's currently minor in the bigger scheme of things.

However, min_dmg working right would be nice and is a pretty simple change if someone gets the time to look into it.

Armanthuz
07-25-2004, 10:39 AM
actually your putting the chicken before the egg.

You cant accurately figure out ac calcs unless you have reasonably close base dmg calcs. Your right that the formula doesnt work 100 percent of time, but id say its inn 90-95 percent of cases, the exception being low levels off the top of my head.


You dont have to add any more DB fields that im aware of because all you need to plug in are min/max dmg, which are already in DB.

The hard part is figuring and applying the ac/atk comparison to the base damage AFTER that :) Because well never know the ac/atk of mobs well always have t olive with an approximation of it, but im fairly sure even there we can get far closer that where we are at now. Too bad i cant code at more than a beginner level :0

If there are any good coders out there that would like to work with me on it, id be interested.

killspree
07-25-2004, 11:08 PM
No no, you're misunderstanding. My fix is to actually get minhit working correctly, it doesn't deal with ac at all other than the fact that it doesn't work like it's supposed to.

The suggestion of adding DB/DI would make min/max hit fields in the database useless, as everything would need to be calculated based on those new fields. So you'd have to make everyone change their DB for something that frankly isn't needed yet because no AC/ATK calcs work precisely like EQLive.

Min_dmg working on the otherhand is something that's already coded and someone just forgot to add it in places so that it isn't reduced by the current mitigation code.