Quick and dirty armour guide
#1
RKTnoob asked on IRC about armour piercing (actually, he said "armor", but I'll assume this was just a typo :P), and the answer to his question wasn't the sort of thing I wanted to explain in the channel, spamming it endlesssly. So...here's the question and my attempt at an answer. It's complicated...
Quote:<Pi_RKTnoob> some weapons have armor bypass, listed in percents, while armor also protects the hp in percents. How do those two percentages add up?
<Pi_RKTnoob> for instance, the carbine has an armor piercing rating of 40%, while armor protects in tiers, 16%, 33%, 37% and 41%. Does it just subtract the percentages, or does it bypass 40% of the current armor percentage, and finally, does it round up or down in the later case?
RKTnoob is getting his data from here. Obviously, if these weapon and armour stats change in the future, the calculations below could be out of date.

Firstly, it's not quite true that armour protects in tiers. It's actually a lot more analogue. Here's the entire damage code (scroll down to see it all):
// just subtract damage here, can set death, etc. later in code calling this
    int dodamage(int damage, int gun)
    {
        guninfo gi = guns[gun];
        if(damage == INT_MAX)
        {
            damage = health;
            armour = health = 0;
            return damage;
        }

        // 4-level armour - tiered approach: 16%, 33%, 37%, 41%
        // Please update ./ac_website/htdocs/docs/introduction.html if this changes.
        int armoursection = 0;
        int ad = damage;
        if(armour > 25) armoursection = 1;
        if(armour > 50) armoursection = 2;
        if(armour > 75) armoursection = 3;
        switch(armoursection)
        {
            case 0: ad = (int) (16.0f/25.0f * armour); break;             // 16
            case 1: ad = (int) (17.0f/25.0f * armour) - 1; break;         // 33
            case 2: ad = (int) (4.0f/25.0f * armour) + 25; break;         // 37
            case 3: ad = (int) (4.0f/25.0f * armour) + 25; break;         // 41
            default: break;
        }
        
        //ra - reduced armor
        //rd - reduced damage
        int ra = (int) (ad * damage/100.0f);
        int rd = ra-(ra*(gi.piercing/100.0f)); //Who cares about rounding errors anyways?
        
        armour -= ra;
        damage -= rd;
            
        health -= damage;
        return damage;
    }

I'll start by concentrating on the armour part:
[code=Armour_part]int armoursection = 0;
int ad = damage;
if(armour > 25) armoursection = 1;
if(armour > 50) armoursection = 2;
if(armour > 75) armoursection = 3;
switch(armoursection)
{
case 0: ad = (int) (16.0f/25.0f * armour); break; // 16
case 1: ad = (int) (17.0f/25.0f * armour) - 1; break; // 33
case 2: ad = (int) (4.0f/25.0f * armour) + 25; break; // 37
case 3: ad = (int) (4.0f/25.0f * armour) + 25; break; // 41
default: break;
}[/code]
If this means nothing to you, the value of ad changes depending on not just the 'group' of armour (0-25, 26-50, 51-75 or 76-100), but the actual armour value. ad is later used in the calculation of how much the armour is reduced by when hit - as a percentage of the weapon's damage value.
(int) is simply the integer part of the value, ie. it always rounds down to the nearest whole number. An armour level of 56 uses armoursection2, where ad = (int) (4.0f/25.0f * 56) + 25, or 33.
Here's a graph of ad against armour...As you can see, there aren't four clearly defined tiers, but there is a clear change in rate when your armour goes above 50. An armour value between 26 and 50 doesn't always equate to an ad of 33; it rises from 16 to 33 at a linear rate.

Now, what does ad do?
[code=Reduction_part]//ra - reduced armor
//rd - reduced damage
int ra = (int) (ad * damage/100.0f);
int rd = ra-(ra*(gi.piercing/100.0f)); //Who cares about rounding errors anyways?

armour -= ra;
damage -= rd;

health -= damage;[/code]
ad is a factor in calculating the amount by which armour is reduced after it's hit. The piercing capability of the weapon is not taken into consideration in this calculation. As an example, a sniper shot does 82 damage. With 100 armour, ad=41, so the armour is reduced by:
(int) (41 * 82/100.0f)
or 41% of 82; 33, when rounded down. For the carbine it's 41% of 60; 24.
So, this armour reduction value, (ra), serves two purposes. It sets the new armour value:
armour -= ra;
or, in English, 'armour after shot' = 'armour before shot' - ra
It is also used in the health reduction calculation, where piercing is taken into consideration.

Going back to the "Reduction_part" code window above, the reduced damage value, rd is calculated with:
ra-(ra*(gi.piercing/100.0f))
Using my previous example of a sniper shot on 100 armour (ra=33, piercing=25%), rd will be:
33-(33*(25/100.0f)
or 33-(25% of 33); 24 when rounded down. At 100 armour, the carbine (ra=24, piercing=40%) has an rd of 24-(40% of 24), or 14. The rd value is used to calculate the amount of physical damage done by the shot:
damage -= rd;
or, in English, 'physical damage' = 'max. weapon damage' - rd.
This means if a player has 100 armour, a sniper shot (max. 82 damage) will do 82-24, or 58 damage. A carbine shot (max. 60 damage, rd of 14) will do 60-14, or 46 damage. Here's another graph which plots damage done by the sniper and the carbine against armour:
In an attempt to summarise:
  • Protection from armour isn't tiered; it's linear in four tiers (although, practically, there are only two).
  • Having armour reduces the percentage of a weapon's damage that's done to your health.
  • 100 armour means 41% of a weapon's max. damage will be done to your armour.
  • Piercing doesn't affect damage to armour, only damage to health.
  • The amount of damage done to the armour is used to calculate the damage done to health.
  • 40% piercing means 60% of the weapon's damage done to armour is removed from the weapon's max. damage done to health. (I said it was complicated).
  • The greater the amount of piercing, the less a weapon's max. damage is reduced by armour. (Obviously)
  • Calculations are (int)'d, or rounded down.

I hope this helps, and if I've made mistakes, please let me know.
Thanks given by: