Search in sources :

Example 26 with IEnergyContainer

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

the class ItemMekaTool method use.

@Nonnull
@Override
public ActionResult<ItemStack> use(World world, PlayerEntity player, @Nonnull Hand hand) {
    ItemStack stack = player.getItemInHand(hand);
    if (!world.isClientSide()) {
        IModule<ModuleTeleportationUnit> module = getModule(stack, MekanismModules.TELEPORTATION_UNIT);
        if (module != null && module.isEnabled()) {
            BlockRayTraceResult result = MekanismUtils.rayTrace(player, MekanismConfig.gear.mekaToolMaxTeleportReach.get());
            // If we don't require a block target or are not a miss, allow teleporting
            if (!module.getCustomInstance().requiresBlockTarget() || result.getType() != RayTraceResult.Type.MISS) {
                BlockPos pos = result.getBlockPos();
                // make sure we fit
                if (isValidDestinationBlock(world, pos.above()) && isValidDestinationBlock(world, pos.above(2))) {
                    double distance = player.distanceToSqr(pos.getX(), pos.getY(), pos.getZ());
                    if (distance < 5) {
                        return new ActionResult<>(ActionResultType.PASS, stack);
                    }
                    IEnergyContainer energyContainer = StorageUtils.getEnergyContainer(stack, 0);
                    FloatingLong energyNeeded = MekanismConfig.gear.mekaToolEnergyUsageTeleport.get().multiply(distance / 10D);
                    if (energyContainer == null || energyContainer.getEnergy().smallerThan(energyNeeded)) {
                        return new ActionResult<>(ActionResultType.FAIL, stack);
                    }
                    energyContainer.extract(energyNeeded, Action.EXECUTE, AutomationType.MANUAL);
                    if (player.isPassenger()) {
                        player.stopRiding();
                    }
                    player.teleportTo(pos.getX() + 0.5, pos.getY() + 1.5, pos.getZ() + 0.5);
                    player.fallDistance = 0.0F;
                    Mekanism.packetHandler.sendToAllTracking(new PacketPortalFX(pos.above()), world, pos);
                    world.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.ENDERMAN_TELEPORT, SoundCategory.PLAYERS, 1.0F, 1.0F);
                    return new ActionResult<>(ActionResultType.SUCCESS, stack);
                }
            }
        }
    }
    return new ActionResult<>(ActionResultType.PASS, stack);
}
Also used : FloatingLong(mekanism.api.math.FloatingLong) PacketPortalFX(mekanism.common.network.to_client.PacketPortalFX) IEnergyContainer(mekanism.api.energy.IEnergyContainer) ActionResult(net.minecraft.util.ActionResult) ModuleTeleportationUnit(mekanism.common.content.gear.mekatool.ModuleTeleportationUnit) BlockPos(net.minecraft.util.math.BlockPos) BlockRayTraceResult(net.minecraft.util.math.BlockRayTraceResult) ItemStack(net.minecraft.item.ItemStack) Nonnull(javax.annotation.Nonnull)

Example 27 with IEnergyContainer

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

the class ItemMekaTool method onBlockStartBreak.

@Override
public boolean onBlockStartBreak(ItemStack stack, BlockPos pos, PlayerEntity player) {
    if (player.level.isClientSide || player.isCreative()) {
        return super.onBlockStartBreak(stack, pos, player);
    }
    IEnergyContainer energyContainer = StorageUtils.getEnergyContainer(stack, 0);
    if (energyContainer != null) {
        World world = player.level;
        BlockState state = world.getBlockState(pos);
        boolean silk = isModuleEnabled(stack, MekanismModules.SILK_TOUCH_UNIT);
        FloatingLong energyRequired = getDestroyEnergy(stack, state.getDestroySpeed(world, pos), silk);
        if (energyContainer.extract(energyRequired, Action.SIMULATE, AutomationType.MANUAL).greaterOrEqual(energyRequired)) {
            IModule<ModuleVeinMiningUnit> veinMiningUnit = getModule(stack, MekanismModules.VEIN_MINING_UNIT);
            // Even though we now handle breaking bounding blocks properly, don't allow vein mining them
            if (veinMiningUnit != null && veinMiningUnit.isEnabled() && !(state.getBlock() instanceof BlockBounding)) {
                boolean isOre = state.is(MekanismTags.Blocks.ATOMIC_DISASSEMBLER_ORE);
                // If it is extended or should be treated as an ore
                if (isOre || veinMiningUnit.getCustomInstance().isExtended()) {
                    // Don't include bonus energy required by efficiency modules when calculating energy of vein mining targets
                    FloatingLong baseDestroyEnergy = getDestroyEnergy(silk);
                    Set<BlockPos> found = ModuleVeinMiningUnit.findPositions(state, pos, world, isOre ? -1 : veinMiningUnit.getCustomInstance().getExcavationRange());
                    MekanismUtils.veinMineArea(energyContainer, world, pos, (ServerPlayerEntity) player, stack, this, found, isModuleEnabled(stack, MekanismModules.SHEARING_UNIT), hardness -> getDestroyEnergy(baseDestroyEnergy, hardness), distance -> 0.5 * Math.pow(distance, isOre ? 1.5 : 2), state);
                }
            }
        }
    }
    return super.onBlockStartBreak(stack, pos, player);
}
Also used : FloatingLong(mekanism.api.math.FloatingLong) IEnergyContainer(mekanism.api.energy.IEnergyContainer) BlockState(net.minecraft.block.BlockState) BlockBounding(mekanism.common.block.BlockBounding) ModuleVeinMiningUnit(mekanism.common.content.gear.mekatool.ModuleVeinMiningUnit) BlockPos(net.minecraft.util.math.BlockPos) World(net.minecraft.world.World)

Example 28 with IEnergyContainer

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

the class ItemMekaTool method hurtEnemy.

@Override
public boolean hurtEnemy(@Nonnull ItemStack stack, @Nonnull LivingEntity target, @Nonnull LivingEntity attacker) {
    IEnergyContainer energyContainer = StorageUtils.getEnergyContainer(stack, 0);
    FloatingLong energy = energyContainer == null ? FloatingLong.ZERO : energyContainer.getEnergy();
    FloatingLong energyCost = FloatingLong.ZERO;
    int minDamage = MekanismConfig.gear.mekaToolBaseDamage.get(), maxDamage = minDamage;
    IModule<ModuleAttackAmplificationUnit> attackAmplificationUnit = getModule(stack, MekanismModules.ATTACK_AMPLIFICATION_UNIT);
    if (attackAmplificationUnit != null && attackAmplificationUnit.isEnabled()) {
        maxDamage = attackAmplificationUnit.getCustomInstance().getDamage();
        if (maxDamage > minDamage) {
            energyCost = MekanismConfig.gear.mekaToolEnergyUsageWeapon.get().multiply((maxDamage - minDamage) / 4F);
        }
        minDamage = Math.min(minDamage, maxDamage);
    }
    int damageDifference = maxDamage - minDamage;
    // If we don't have enough power use it at a reduced power level
    double percent = 1;
    if (energy.smallerThan(energyCost)) {
        percent = energy.divideToLevel(energyCost);
    }
    float damage = (float) (minDamage + damageDifference * percent);
    if (attacker instanceof PlayerEntity) {
        target.hurt(DamageSource.playerAttack((PlayerEntity) attacker), damage);
    } else {
        target.hurt(DamageSource.mobAttack(attacker), damage);
    }
    if (energyContainer != null && !energy.isZero()) {
        energyContainer.extract(energyCost, Action.EXECUTE, AutomationType.MANUAL);
    }
    return false;
}
Also used : FloatingLong(mekanism.api.math.FloatingLong) IEnergyContainer(mekanism.api.energy.IEnergyContainer) ModuleAttackAmplificationUnit(mekanism.common.content.gear.mekatool.ModuleAttackAmplificationUnit) PlayerEntity(net.minecraft.entity.player.PlayerEntity) ServerPlayerEntity(net.minecraft.entity.player.ServerPlayerEntity)

Example 29 with IEnergyContainer

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

the class ItemAtomicDisassembler method onBlockStartBreak.

@Override
public boolean onBlockStartBreak(ItemStack stack, BlockPos pos, PlayerEntity player) {
    if (player.level.isClientSide || player.isCreative()) {
        return super.onBlockStartBreak(stack, pos, player);
    }
    IEnergyContainer energyContainer = StorageUtils.getEnergyContainer(stack, 0);
    if (energyContainer != null && getMode(stack) == DisassemblerMode.VEIN) {
        World world = player.level;
        BlockState state = world.getBlockState(pos);
        FloatingLong baseDestroyEnergy = getDestroyEnergy(stack);
        FloatingLong energyRequired = getDestroyEnergy(baseDestroyEnergy, state.getDestroySpeed(world, pos));
        if (energyContainer.extract(energyRequired, Action.SIMULATE, AutomationType.MANUAL).greaterOrEqual(energyRequired)) {
            // only allow mining things that are considered an ore
            if (!(state.getBlock() instanceof BlockBounding) && state.is(MekanismTags.Blocks.ATOMIC_DISASSEMBLER_ORE)) {
                List<BlockPos> found = findPositions(state, pos, world);
                MekanismUtils.veinMineArea(energyContainer, world, pos, (ServerPlayerEntity) player, stack, this, found, false, hardness -> getDestroyEnergy(baseDestroyEnergy, hardness), distance -> 0.5 * Math.pow(distance, 1.5), state);
            }
        }
    }
    return super.onBlockStartBreak(stack, pos, player);
}
Also used : FloatingLong(mekanism.api.math.FloatingLong) IEnergyContainer(mekanism.api.energy.IEnergyContainer) BlockState(net.minecraft.block.BlockState) BlockBounding(mekanism.common.block.BlockBounding) BlockPos(net.minecraft.util.math.BlockPos) World(net.minecraft.world.World)

Example 30 with IEnergyContainer

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

the class ItemAtomicDisassembler method hurtEnemy.

@Override
public boolean hurtEnemy(@Nonnull ItemStack stack, @Nonnull LivingEntity target, @Nonnull LivingEntity attacker) {
    IEnergyContainer energyContainer = StorageUtils.getEnergyContainer(stack, 0);
    FloatingLong energy = energyContainer == null ? FloatingLong.ZERO : energyContainer.getEnergy();
    FloatingLong energyCost = MekanismConfig.gear.disassemblerEnergyUsageWeapon.get();
    int minDamage = MekanismConfig.gear.disassemblerMinDamage.get();
    int damageDifference = MekanismConfig.gear.disassemblerMaxDamage.get() - minDamage;
    // If we don't have enough power use it at a reduced power level
    double percent = 1;
    if (energy.smallerThan(energyCost)) {
        percent = energy.divideToLevel(energyCost);
    }
    float damage = (float) (minDamage + damageDifference * percent);
    if (attacker instanceof PlayerEntity) {
        target.hurt(DamageSource.playerAttack((PlayerEntity) attacker), damage);
    } else {
        target.hurt(DamageSource.mobAttack(attacker), damage);
    }
    if (energyContainer != null && !energy.isZero()) {
        energyContainer.extract(energyCost, Action.EXECUTE, AutomationType.MANUAL);
    }
    return false;
}
Also used : FloatingLong(mekanism.api.math.FloatingLong) IEnergyContainer(mekanism.api.energy.IEnergyContainer) PlayerEntity(net.minecraft.entity.player.PlayerEntity) ServerPlayerEntity(net.minecraft.entity.player.ServerPlayerEntity)

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