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);
}
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);
}
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;
}
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);
}
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;
}
Aggregations