To make things a bit more transparent, here is how OXCE handles damage wrt. to the scripts:
random_damage = getRandomDamage(power_of_weapon); // apply damageRange (0-200% in vanilla ufo)
TileEngine.hitUnit(targetUnit, random_damage)
{
targetUnit.damage(random_damage)
}
BattleUnit.damage(random_damage)
{
if (random_damage < 0) return; // DO NOTHING
random_damage = reduceByResistance(random_damage, ResistType); // apply armor damage modifiers (resistances)
CALL SCRIPT: HitUnit(random_damage as power)
adjusted_damage -= getArmor(side) * ArmorEffectiveness; // apply armor on respective side, taking armor effectiveness into account
CALL SCRIPT: DamageUnit(random_damage as original_damage, adjusted_damage as damage)
=> Apply Damage directly from output of DamageUnit script
}