Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.
Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
I have a custom armor set replacing the standard armor.
Every piece has its "save percent", "save amount" etc. and it (seems to) works just fine absorbing the damage and getting damaged, but I noticed one annoying thing:
When the damage is too low, the only armor piece that will absorbed and consequently damaged is the last piece that the player worn.
I tried to avoid it by having a random chance (based on the number of worn armor pieces) to skip the "absorption", hoping that it will let another armor piece to absorb the damage, but it doesn't clearly work like that.
So I wonder, is there a way to randomize the armor piece that will absorb the damage when the damage itself is too low to trigger the "absorption" on the other pieces too?
This is my AbsorbDamage() function for the armor set:
override void AbsorbDamage (int damage, Name damageType, out int newdamage) {
if(damage > 0 && owner && owner.health > 0) {
double depletion = 1.0; //armor depletion chance
double dmgAbsorbed; //damage absorbed by the armor
double tankChance; //chance to completely tank low damage
newdamage = max(0, ApplyDamageFactors(GetClass(), damageType, damage, damage)); //reduce the damage applying the armor damage factors
if (!DamageTypeDefinition.IgnoreArmor(damageType) && newdamage > 0 && Defense > 0) { //if the damage type do not bypass armor and the armor piece has some defense
if(Defense > 1.0)
Defense = 1.0;
newdamage = round(damage * (1.0 - Defense)); //apply the armor piece defense to the damage
if(newdamage >= damage)
newdamage = damage - 1;//reduce the actual damage taken by 1 if = to the original damage
}
if(newdamage > 0 && newdamage <= wornPieces) {//if the damage is lower than the number of worn pieces of armor
tankChance = ApplyDamageFactor(damageType, 100) * 2.56; //chance out of 256 to not receive damage based on the damagefactor
if(random() >= tankChance)
newdamage = 0;
}
dmgAbsorbed = floor((damage - newdamage) * depletion); //damage absorbed by the armor
if(dmgAbsorbed > 0) { //if the damage absorbed is not 0
if(Amount >= dmgAbsorbed) { //if the amount of worn armor is >= of the absorbed damage
if(!bNOTARMOR) //if it gave armor points
owner.TakeInventory("BasicArmor", dmgAbsorbed); //reduce the armor points by the absorbed amount
}
else { //if <
if(!bNOTARMOR) //if it gave armor points
owner.TakeInventory("BasicArmor", Amount); //take all the armor points given by the armor piece
newdamage += (dmgAbsorbed - Amount); //and add the difference between the absorbed damage and the armor amount to the damage
}
Amount -= dmgAbsorbed; //reduce the worn armor by the absorbed amount
A_LogInt(Amount);
if(Amount <= 0) //if there's no more armor
Destroy(); //remove it
}
}
}