We are re-implementing the code that calculates damage to the hit cell and surrounding cells of an ArmorGridAPI and resulting damage (without any other modifiers) to the hull for our Starsector

but do not quite know how it works and cannot find any reference implementation or a rigorous specification for one, so I have proposed one below. Is it exactly correct?

` private static float getPooledArmor(`

final int iHit,

final int jHit,

final ArmorGridAPI armorGrid,

) {

float pooledArmor = 0;

for (int i = 0; i < 5; i++)

for (int j = 0; i < 5; j++)

if ((i == 0 || i == 5) && (j == 0 || j == 5)) //skip corners

continue;

else if (i == 0 || i == 5 || j == 0 || j == 5) //edges contribute half value

pooledArmor += 0.5 * armorGrid.getArmorValue(iHit + i, jHit + j);

else //center 9 contribute full value

pooledArmor += armorGrid.getArmorValue(iHit + i, jHit + j);

return pooledArmor;

}

private static float getHullDamage(

final float damage,

final float pooledArmor,

final float armorRating,

final float minimumArmorFactorForHullDamageReduction

) {

return damage

* damage

/ (damage + Math.max(pooledArmor, armorRating * minimumArmorFactorForHullDamageReduction));

}

private static float getArmorDamage(

final boolean isBeam,

final float damage,

final float pooledArmor,

final float maxArmorDamageReductionFactor,

final DamageType damageType

) {

float hitStrengthAgainstArmor = damage * (isBeam ? 0.5f : 1);

switch (damageType) {

case KINETIC: hitStrengthAgainstArmor *= 0.5;

case HIGH_EXPLOSIVE: hitStrengthAgainstArmor *= 2;

case FRAGMENTAETION: hitStrengthAgainstArmor *= 0.25f;

}

return hitStrengthAgainstArmor

* Math.max(1 - maxArmorDamageReductionFactor,

hitStrengthAgainstArmor / (hitStrengthAgainstArmor + pooledArmor));

}

private static void damageArmorGrid(

final int iHit,

final int jHit,

final float armorDamage,

final ArmorGridAPI armorGrid

) {

for (int i = 0; i < 5; i++)

for (int j = 0; i < 5; j++)

if ((i == 0 || i == 5) && (j == 0 || j == 5)) //skip corners

continue;

else if (i == 0 || i == 5 || j == 0 || j == 5) //edges take half damage

armorGrid.setArmorValue(i, j, Math.max(0, armorGrid.getArmorValue(i,j) - 0.5 * armorDamage));

else //center 9 take full damage

armorGrid.setArmorValue(i, j, Math.max(0, armorGrid.getArmorValue(i,j) - armorDamage));

}

private static void applyDamage(

final boolean isBeam,

final int iHit,

final int jHit,

final float damage,

final float minimumArmorFactorForHullDamageReduction,

final float maxArmorDamageReductionFactor,

final DamageType damageType,

final ShipAPI ship

) {

final ArmorGridAPI armorGrid = ship.getArmorGrid();

//calculate damage

final float pooledArmor = getPooledArmor(armorGrid, iHit, jHit);

final float hullDamage = getHullDamage(damage, pooledArmor, armorGrid.getArmorRating(), minimumArmorFactorForHullDamageReduction);

final float armorDamage = getArmorDamage(isBeam, damage, pooledArmor, maxArmorDamageReductionFactor, damageType);

//apply damage

damageArmorGrid(iHit, jHit, armorDamage, armorGrid);

ship.setHitpoints(Math.max(ship.getHitpoints() - hullDamage, 0)); //obviously makes ship disappear rather than explode, but we don't care about that effect

}