use of mekanism.api.energy.IEnergyContainer in project Mekanism by mekanism.
the class ModuleFarmingUnit method stripLogsAOE.
private ActionResultType stripLogsAOE(ItemUseContext context) {
PlayerEntity player = context.getPlayer();
if (player == null || player.isShiftKeyDown()) {
// Skip if we don't have a player, or they are sneaking
return ActionResultType.PASS;
}
int diameter = farmingRadius.get().getRadius();
if (diameter == 0) {
// If we don't have any blocks we are going to want to do, then skip it
return ActionResultType.PASS;
}
ItemStack stack = context.getItemInHand();
IEnergyContainer energyContainer = StorageUtils.getEnergyContainer(stack, 0);
if (energyContainer == null) {
return ActionResultType.FAIL;
}
FloatingLong energy = energyContainer.getEnergy();
FloatingLong energyUsage = MekanismConfig.gear.mekaToolEnergyUsageAxe.get();
if (energy.smallerThan(energyUsage)) {
// Fail if we don't have enough energy or using the item failed
return ActionResultType.FAIL;
}
World world = context.getLevel();
BlockPos pos = context.getClickedPos();
BlockState clickedState = world.getBlockState(pos);
BlockState strippedState = clickedState.getToolModifiedState(world, pos, player, stack, ToolType.AXE);
if (strippedState == null) {
// Skip stripping the blocks if the one we clicked cannot be stripped
return ActionResultType.PASS;
} else if (world.isClientSide) {
return ActionResultType.SUCCESS;
}
Axis axis = clickedState.getValue(RotatedPillarBlock.AXIS);
// Process the block we interacted with initially and play the sound
world.setBlock(pos, strippedState, BlockFlags.DEFAULT_AND_RERENDER);
world.playSound(null, pos, SoundEvents.AXE_STRIP, SoundCategory.BLOCKS, 1.0F, 1.0F);
Direction side = context.getClickedFace();
FloatingLong energyUsed = energyUsage.copy();
Vector3d offset = Vector3d.atLowerCornerOf(side.getNormal()).scale(0.44);
for (BlockPos newPos : getStrippingArea(pos, side, (diameter - 1) / 2)) {
if (pos.equals(newPos)) {
// Skip the source position as it is free, and we manually handled it before the loop
continue;
} else if (energyUsed.add(energyUsage).greaterThan(energy)) {
break;
}
// Check to make that the result we would get from stripping the other block is the same as the one we got on the initial block we interacted with
// Also make sure that it is on the same axis as the block we initially clicked
BlockState state = world.getBlockState(newPos);
if (strippedState == state.getToolModifiedState(world, newPos, player, stack, ToolType.AXE) && axis == state.getValue(RotatedPillarBlock.AXIS)) {
// Some of the below methods don't behave properly when the BlockPos is mutable, so now that we are onto ones where it may actually
// matter we make sure to get an immutable instance of newPos
newPos = newPos.immutable();
// Add energy cost
energyUsed = energyUsed.plusEqual(energyUsage);
// Replace the block. Note it just directly sets it (in the same way that AxeItem does).
world.setBlock(newPos, strippedState, BlockFlags.DEFAULT_AND_RERENDER);
world.playSound(null, pos, SoundEvents.AXE_STRIP, SoundCategory.BLOCKS, 1.0F, 1.0F);
Mekanism.packetHandler.sendToAllTracking(new PacketLightningRender(LightningPreset.TOOL_AOE, Objects.hash(pos, newPos), Vector3d.atCenterOf(pos).add(offset), Vector3d.atCenterOf(newPos).add(offset), 10), world, pos);
}
}
energyContainer.extract(energyUsed, Action.EXECUTE, AutomationType.MANUAL);
return ActionResultType.SUCCESS;
}
use of mekanism.api.energy.IEnergyContainer in project Mekanism by mekanism.
the class ModuleShearingUnit method onDispense.
@Nonnull
@Override
public ModuleDispenseResult onDispense(IModule<ModuleShearingUnit> module, IBlockSource source) {
IEnergyContainer energyContainer = module.getEnergyContainer();
if (energyContainer != null) {
ServerWorld world = source.getLevel();
Direction facing = source.getBlockState().getValue(DispenserBlock.FACING);
BlockPos pos = source.getPos().relative(facing);
if (tryShearBlock(energyContainer, world, pos, facing.getOpposite()) || tryShearLivingEntity(energyContainer, world, pos, module.getContainer())) {
return ModuleDispenseResult.HANDLED;
}
}
return ModuleDispenseResult.FAIL_PREVENT_DROP;
}
use of mekanism.api.energy.IEnergyContainer in project Mekanism by mekanism.
the class StorageUtils method getEnergyRatio.
public static double getEnergyRatio(ItemStack stack) {
IEnergyContainer container = getEnergyContainer(stack, 0);
double ratio = 0.0D;
if (container != null) {
ratio = container.getEnergy().divideToLevel(container.getMaxEnergy());
}
return ratio;
}
use of mekanism.api.energy.IEnergyContainer in project Mekanism by mekanism.
the class TileEntityMekanism method addContainerTrackers.
@Override
public void addContainerTrackers(MekanismContainer container) {
// setup dynamic container syncing
SyncMapper.INSTANCE.setup(container, getClass(), () -> this);
for (ITileComponent component : components) {
component.trackForMainContainer(container);
}
if (supportsRedstone()) {
container.track(SyncableEnum.create(RedstoneControl::byIndexStatic, RedstoneControl.DISABLED, () -> controlType, value -> controlType = value));
}
boolean isClient = isRemote();
if (canHandleGas() && handles(SubstanceType.GAS)) {
List<IGasTank> gasTanks = getGasTanks(null);
for (IGasTank gasTank : gasTanks) {
container.track(SyncableGasStack.create(gasTank, isClient));
}
}
if (canHandleInfusion() && handles(SubstanceType.INFUSION)) {
List<IInfusionTank> infusionTanks = getInfusionTanks(null);
for (IInfusionTank infusionTank : infusionTanks) {
container.track(SyncableInfusionStack.create(infusionTank, isClient));
}
}
if (canHandlePigment() && handles(SubstanceType.PIGMENT)) {
List<IPigmentTank> pigmentTanks = getPigmentTanks(null);
for (IPigmentTank pigmentTank : pigmentTanks) {
container.track(SyncablePigmentStack.create(pigmentTank, isClient));
}
}
if (canHandleSlurry() && handles(SubstanceType.SLURRY)) {
List<ISlurryTank> slurryTanks = getSlurryTanks(null);
for (ISlurryTank slurryTank : slurryTanks) {
container.track(SyncableSlurryStack.create(slurryTank, isClient));
}
}
if (canHandleFluid() && handles(SubstanceType.FLUID)) {
List<IExtendedFluidTank> fluidTanks = getFluidTanks(null);
for (IExtendedFluidTank fluidTank : fluidTanks) {
container.track(SyncableFluidStack.create(fluidTank, isClient));
}
}
if (canHandleHeat() && handles(SubstanceType.HEAT)) {
List<IHeatCapacitor> heatCapacitors = getHeatCapacitors(null);
for (IHeatCapacitor capacitor : heatCapacitors) {
container.track(SyncableDouble.create(capacitor::getHeat, capacitor::setHeat));
if (capacitor instanceof BasicHeatCapacitor) {
container.track(SyncableDouble.create(capacitor::getHeatCapacity, capacity -> ((BasicHeatCapacitor) capacitor).setHeatCapacity(capacity, false)));
}
}
}
if (canHandleEnergy() && handles(SubstanceType.ENERGY)) {
container.track(SyncableFloatingLong.create(this::getInputRate, this::setInputRate));
List<IEnergyContainer> energyContainers = getEnergyContainers(null);
for (IEnergyContainer energyContainer : energyContainers) {
container.track(SyncableFloatingLong.create(energyContainer::getEnergy, energyContainer::setEnergy));
if (energyContainer instanceof MachineEnergyContainer) {
MachineEnergyContainer<?> machineEnergy = (MachineEnergyContainer<?>) energyContainer;
if (supportsUpgrades() || machineEnergy.adjustableRates()) {
container.track(SyncableFloatingLong.create(machineEnergy::getMaxEnergy, machineEnergy::setMaxEnergy));
container.track(SyncableFloatingLong.create(machineEnergy::getEnergyPerTick, machineEnergy::setEnergyPerTick));
}
}
}
}
}
use of mekanism.api.energy.IEnergyContainer in project Mekanism by mekanism.
the class PacketPortableTeleporterTeleport method handle.
@Override
public void handle(NetworkEvent.Context context) {
ServerPlayerEntity player = context.getSender();
if (player == null) {
return;
}
ItemStack stack = player.getItemInHand(currentHand);
if (!stack.isEmpty() && stack.getItem() instanceof ItemPortableTeleporter) {
// Note: We make use of the player's own UUID, given they shouldn't be allowed to teleport to a private frequency of another player
TeleporterFrequency found = FrequencyType.TELEPORTER.getFrequency(identity, player.getUUID());
if (found == null) {
return;
}
Coord4D coords = found.getClosestCoords(new Coord4D(player));
if (coords != null) {
World teleWorld = ServerLifecycleHooks.getCurrentServer().getLevel(coords.dimension);
TileEntityTeleporter teleporter = WorldUtils.getTileEntity(TileEntityTeleporter.class, teleWorld, coords.getPos());
if (teleporter != null) {
if (!player.isCreative()) {
FloatingLong energyCost = TileEntityTeleporter.calculateEnergyCost(player, coords);
IEnergyContainer energyContainer = StorageUtils.getEnergyContainer(stack, 0);
if (energyContainer == null || energyContainer.extract(energyCost, Action.SIMULATE, AutomationType.MANUAL).smallerThan(energyCost)) {
return;
}
energyContainer.extract(energyCost, Action.EXECUTE, AutomationType.MANUAL);
}
// TODO: Figure out what this try catch is meant to be catching as I don't see much of a reason for it to exist
try {
teleporter.didTeleport.add(player.getUUID());
teleporter.teleDelay = 5;
player.connection.aboveGroundTickCount = 0;
player.closeContainer();
Mekanism.packetHandler.sendToAllTracking(new PacketPortalFX(player.blockPosition()), player.level, coords.getPos());
if (player.isPassenger()) {
player.stopRiding();
}
double oldX = player.getX();
double oldY = player.getY();
double oldZ = player.getZ();
World oldWorld = player.level;
BlockPos teleporterTargetPos = teleporter.getTeleporterTargetPos();
TileEntityTeleporter.teleportEntityTo(player, teleWorld, teleporterTargetPos);
TileEntityTeleporter.alignPlayer(player, teleporterTargetPos, teleporter);
if (player.level != oldWorld || player.distanceToSqr(oldX, oldY, oldZ) >= 25) {
// If the player teleported over 5 blocks, play the sound at both the destination and the source
oldWorld.playSound(null, oldX, oldY, oldZ, SoundEvents.ENDERMAN_TELEPORT, SoundCategory.PLAYERS, 1.0F, 1.0F);
}
player.level.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.ENDERMAN_TELEPORT, SoundCategory.PLAYERS, 1.0F, 1.0F);
teleporter.sendTeleportParticles();
} catch (Exception ignored) {
}
}
}
}
}
Aggregations