Search in sources :

Example 1 with ModuleDamageAbsorbInfo

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);
}
Also used : IEnergyContainer(mekanism.api.energy.IEnergyContainer) FloatSupplier(mekanism.api.functions.FloatSupplier) ArrayList(java.util.ArrayList) ModuleDamageAbsorbInfo(mekanism.api.gear.ICustomModule.ModuleDamageAbsorbInfo) ItemStack(net.minecraft.item.ItemStack)

Aggregations

ArrayList (java.util.ArrayList)1 IEnergyContainer (mekanism.api.energy.IEnergyContainer)1 FloatSupplier (mekanism.api.functions.FloatSupplier)1 ModuleDamageAbsorbInfo (mekanism.api.gear.ICustomModule.ModuleDamageAbsorbInfo)1 ItemStack (net.minecraft.item.ItemStack)1