use of mekanism.api.gear.ICustomModule.ModuleDamageAbsorbInfo in project Mekanism by mekanism.
the class ItemMekaSuitArmor method getDamageAbsorbed.
private static float getDamageAbsorbed(PlayerEntity player, DamageSource source, float amount, @Nullable List<Runnable> energyUseCallbacks) {
if (amount <= 0) {
return 0;
}
float ratioAbsorbed = 0;
List<FoundArmorDetails> armorDetails = new ArrayList<>();
// Start by looping the armor, allowing modules to absorb damage if they can
for (ItemStack stack : player.inventory.armor) {
if (!stack.isEmpty() && stack.getItem() instanceof ItemMekaSuitArmor) {
IEnergyContainer energyContainer = StorageUtils.getEnergyContainer(stack, 0);
if (energyContainer != null) {
FoundArmorDetails details = new FoundArmorDetails(energyContainer, (ItemMekaSuitArmor) stack.getItem());
armorDetails.add(details);
for (Module<?> module : details.armor.getModules(stack)) {
if (module.isEnabled()) {
ModuleDamageAbsorbInfo damageAbsorbInfo = getModuleDamageAbsorbInfo(module, source);
if (damageAbsorbInfo != null) {
float absorption = damageAbsorbInfo.getAbsorptionRatio().getAsFloat();
ratioAbsorbed += absorbDamage(details.usageInfo, amount, absorption, ratioAbsorbed, damageAbsorbInfo.getEnergyCost());
if (ratioAbsorbed >= 1) {
// If we have fully absorbed the damage, stop checking/trying to absorb more
break;
}
}
}
}
if (ratioAbsorbed >= 1) {
// If we have fully absorbed the damage, stop checking/trying to absorb more
break;
}
}
}
}
if (ratioAbsorbed < 1) {
// If we haven't fully absorbed it check the individual pieces of armor for if they can absorb any
FloatSupplier absorbRatio = null;
for (FoundArmorDetails details : armorDetails) {
if (absorbRatio == null) {
// stop checking if the armor is able to
if (!ALWAYS_SUPPORTED_SOURCES.contains(source) && source.isBypassArmor()) {
break;
}
// Next lookup the ratio at which we can absorb the given damage type from the config
absorbRatio = MekanismConfig.gear.mekaSuitDamageRatios.getOrDefault(source, MekanismConfig.gear.mekaSuitUnspecifiedDamageRatio);
if (absorbRatio.getAsFloat() == 0) {
// stop checking if the armor is able to
break;
}
}
float absorption = details.armor.absorption * absorbRatio.getAsFloat();
ratioAbsorbed += absorbDamage(details.usageInfo, amount, absorption, ratioAbsorbed, MekanismConfig.gear.mekaSuitEnergyUsageDamage);
if (ratioAbsorbed >= 1) {
// If we have fully absorbed the damage, stop checking/trying to absorb more
break;
}
}
}
for (FoundArmorDetails details : armorDetails) {
// Use energy/or enqueue usage for each piece as needed
if (!details.usageInfo.energyUsed.isZero()) {
if (energyUseCallbacks == null) {
details.energyContainer.extract(details.usageInfo.energyUsed, Action.EXECUTE, AutomationType.MANUAL);
} else {
energyUseCallbacks.add(() -> details.energyContainer.extract(details.usageInfo.energyUsed, Action.EXECUTE, AutomationType.MANUAL));
}
}
}
return Math.min(ratioAbsorbed, 1);
}
Aggregations