Search in sources :

Example 6 with IEnergyContainer

use of mekanism.api.energy.IEnergyContainer in project Mekanism by mekanism.

the class TileEntityMekanism method getTotalEnergy.

private FloatingLong getTotalEnergy(Function<IEnergyContainer, FloatingLong> getter) {
    FloatingLong total = FloatingLong.ZERO;
    List<IEnergyContainer> energyContainers = getEnergyContainers(null);
    for (IEnergyContainer energyContainer : energyContainers) {
        total = total.plusEqual(getter.apply(energyContainer));
    }
    return total;
}
Also used : SyncableFloatingLong(mekanism.common.inventory.container.sync.SyncableFloatingLong) FloatingLong(mekanism.api.math.FloatingLong) IEnergyContainer(mekanism.api.energy.IEnergyContainer)

Example 7 with IEnergyContainer

use of mekanism.api.energy.IEnergyContainer in project Mekanism by mekanism.

the class TileEntityMekanism method insertEnergy.

@Nonnull
@Override
public FloatingLong insertEnergy(int container, @Nonnull FloatingLong amount, @Nullable Direction side, @Nonnull Action action) {
    IEnergyContainer energyContainer = getEnergyContainer(container, side);
    if (energyContainer == null) {
        return amount;
    }
    FloatingLong remainder = energyContainer.insert(amount, action, side == null ? AutomationType.INTERNAL : AutomationType.EXTERNAL);
    if (action.execute()) {
        lastEnergyReceived = lastEnergyReceived.plusEqual(amount.subtract(remainder));
    }
    return remainder;
}
Also used : SyncableFloatingLong(mekanism.common.inventory.container.sync.SyncableFloatingLong) FloatingLong(mekanism.api.math.FloatingLong) IEnergyContainer(mekanism.api.energy.IEnergyContainer) Nonnull(javax.annotation.Nonnull)

Example 8 with IEnergyContainer

use of mekanism.api.energy.IEnergyContainer 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)

Example 9 with IEnergyContainer

use of mekanism.api.energy.IEnergyContainer in project Mekanism by mekanism.

the class ItemMekaTool method mineBlock.

@Override
public boolean mineBlock(@Nonnull ItemStack stack, @Nonnull World world, @Nonnull BlockState state, @Nonnull BlockPos pos, @Nonnull LivingEntity entityliving) {
    IEnergyContainer energyContainer = StorageUtils.getEnergyContainer(stack, 0);
    if (energyContainer != null) {
        FloatingLong energyRequired = getDestroyEnergy(stack, state.getDestroySpeed(world, pos), isModuleEnabled(stack, MekanismModules.SILK_TOUCH_UNIT));
        FloatingLong extractedEnergy = energyContainer.extract(energyRequired, Action.EXECUTE, AutomationType.MANUAL);
        if (extractedEnergy.equals(energyRequired) || entityliving instanceof PlayerEntity && ((PlayerEntity) entityliving).isCreative()) {
            // Only disarm tripwires if we had all the energy we tried to use (or are creative). Otherwise, treat it as if we may have failed to disarm it
            if (state.is(Blocks.TRIPWIRE) && !state.getValue(TripWireBlock.DISARMED) && isModuleEnabled(stack, MekanismModules.SHEARING_UNIT)) {
                world.setBlock(pos, state.setValue(TripWireBlock.DISARMED, true), BlockFlags.NO_RERENDER);
            }
        }
    }
    return true;
}
Also used : FloatingLong(mekanism.api.math.FloatingLong) IEnergyContainer(mekanism.api.energy.IEnergyContainer) PlayerEntity(net.minecraft.entity.player.PlayerEntity) ServerPlayerEntity(net.minecraft.entity.player.ServerPlayerEntity)

Example 10 with IEnergyContainer

use of mekanism.api.energy.IEnergyContainer in project Mekanism by mekanism.

the class ItemMekaTool method getDestroySpeed.

@Override
public float getDestroySpeed(@Nonnull ItemStack stack, @Nonnull BlockState state) {
    IEnergyContainer energyContainer = StorageUtils.getEnergyContainer(stack, 0);
    if (energyContainer == null) {
        return 0;
    }
    // Use raw hardness to get the best guess of if it is zero or not
    FloatingLong energyRequired = getDestroyEnergy(stack, state.destroySpeed, isModuleEnabled(stack, MekanismModules.SILK_TOUCH_UNIT));
    FloatingLong energyAvailable = energyContainer.extract(energyRequired, Action.SIMULATE, AutomationType.MANUAL);
    if (energyAvailable.smallerThan(energyRequired)) {
        // If we can't extract all the energy we need to break it go at base speed reduced by how much we actually have available
        return MekanismConfig.gear.mekaToolBaseEfficiency.get() * energyAvailable.divide(energyRequired).floatValue();
    }
    IModule<ModuleExcavationEscalationUnit> module = getModule(stack, MekanismModules.EXCAVATION_ESCALATION_UNIT);
    return module == null || !module.isEnabled() ? MekanismConfig.gear.mekaToolBaseEfficiency.get() : module.getCustomInstance().getEfficiency();
}
Also used : FloatingLong(mekanism.api.math.FloatingLong) IEnergyContainer(mekanism.api.energy.IEnergyContainer) ModuleExcavationEscalationUnit(mekanism.common.content.gear.mekatool.ModuleExcavationEscalationUnit)

Aggregations

IEnergyContainer (mekanism.api.energy.IEnergyContainer)34 FloatingLong (mekanism.api.math.FloatingLong)26 BlockPos (net.minecraft.util.math.BlockPos)13 PlayerEntity (net.minecraft.entity.player.PlayerEntity)12 ItemStack (net.minecraft.item.ItemStack)12 Nonnull (javax.annotation.Nonnull)10 Direction (net.minecraft.util.Direction)8 World (net.minecraft.world.World)8 BlockState (net.minecraft.block.BlockState)6 ServerPlayerEntity (net.minecraft.entity.player.ServerPlayerEntity)6 ArrayList (java.util.ArrayList)5 List (java.util.List)4 Map (java.util.Map)4 Nullable (javax.annotation.Nullable)4 TileEntityMekanism (mekanism.common.tile.base.TileEntityMekanism)4 TileEntity (net.minecraft.tileentity.TileEntity)4 SyncableFloatingLong (mekanism.common.inventory.container.sync.SyncableFloatingLong)3 EnumMap (java.util.EnumMap)2 HashMap (java.util.HashMap)2 Set (java.util.Set)2