When a unit in combat is hit, it runs a risk of suffering a devastating critical hit, also known as an armor-defeating hit in the combat log. In short, the risk to take a critical hit is normally 1/36, or 3/36 when above 50 fatigue, or 6/36 when immobilised. A critical hit reduces protection by 25%.
Note that critical hits are a separate mechanic from head hits.
On a hit, first armor-piercing effects (AP weapon, AN weapon, piercing weapon) are applied to the targeted unit's protection. AP and piercing are done separately, so they are multiplicative (60% armor reduced when stacked).
Note that this differs substantially from the manual's description. In particular, Fatigue does not apply a "-1 per 15" scaling reduction, only a small bump at 50 and a larger one at 100.
When a critical hit occurs, the unit's current protection (after AP stuff above) is reduced by 25% (rounded down, all divisions are btw). Afterward, the protection DRN is added to that protection to get the protection used against damage.
The manual says critical hits reduce prot by 25%, but the code below appears to show a 50% reduction to base prot. Since the manual is wrong on this topic in several ways, can we confirm the code is more accurate?
Note that it is the same DRN roll that is used for both reducing damage and deciding whether a critical hit happened, which leads to critical hits being even more devastating.
This disassembly snippet was posted by iRFNA's in 2015:
v128 = opendice(6, 2); protdrn = v128; if ( hascurseluck > 0 && randnum(100) < 50 ) // curse luck is internal effect 255 protdrn -= openroll(6); if ( *(__int16 *)((char *)fatigue + hitunitoffset3) >= 50 ) --protdrn; posprotdrn = ((protdrn <= 0) - 1) & protdrn; // set negative prot drn to 0 if ( posprotdrn > 2 && (immobileunit(hitunitid2) || !immobilized(hitunitid2) || posprotdrn > 4) )// mobile unit has 1/36 chance to crit (protdrn <= 2) // immobilized unit has 1/6 chance to crit (protdrn <= 4) // this is ignoring the two protdrn alterations above protaftercrit = prot; else protaftercrit = prot / 2; isprotneg = posprotdrn + protaftercrit < 0; adjprot = posprotdrn + protaftercrit; prot = adjprot & (isprotneg - 1); //set negative prot to 0