use of mekanism.api.energy.IEnergyContainer in project Mekanism by mekanism.
the class ItemSeismicReader method use.
@Nonnull
@Override
public ActionResult<ItemStack> use(World world, PlayerEntity player, @Nonnull Hand hand) {
ItemStack stack = player.getItemInHand(hand);
if (world.isClientSide) {
return new ActionResult<>(ActionResultType.SUCCESS, stack);
}
if (!WorldUtils.isChunkVibrated(new ChunkPos(player.blockPosition()), player.level)) {
player.sendMessage(MekanismUtils.logFormat(EnumColor.RED, MekanismLang.NO_VIBRATIONS), Util.NIL_UUID);
} else {
if (!player.isCreative()) {
IEnergyContainer energyContainer = StorageUtils.getEnergyContainer(stack, 0);
FloatingLong energyUsage = MekanismConfig.gear.seismicReaderEnergyUsage.get();
if (energyContainer == null || energyContainer.extract(energyUsage, Action.SIMULATE, AutomationType.MANUAL).smallerThan(energyUsage)) {
player.sendMessage(MekanismUtils.logFormat(EnumColor.RED, MekanismLang.NEEDS_ENERGY), Util.NIL_UUID);
return new ActionResult<>(ActionResultType.SUCCESS, stack);
}
energyContainer.extract(energyUsage, Action.EXECUTE, AutomationType.MANUAL);
}
MekanismContainerTypes.SEISMIC_READER.tryOpenGui((ServerPlayerEntity) player, hand, stack);
}
return new ActionResult<>(ActionResultType.SUCCESS, stack);
}
use of mekanism.api.energy.IEnergyContainer in project Mekanism by mekanism.
the class ItemAtomicDisassembler 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);
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 DisassemblerMode.NORMAL.getEfficiency() * energyAvailable.divide(energyRequired).floatValue();
}
return getMode(stack).getEfficiency();
}
use of mekanism.api.energy.IEnergyContainer in project Mekanism by mekanism.
the class ItemNetworkReader method useOn.
@Nonnull
@Override
public ActionResultType useOn(ItemUseContext context) {
PlayerEntity player = context.getPlayer();
World world = context.getLevel();
if (!world.isClientSide && player != null) {
BlockPos pos = context.getClickedPos();
TileEntity tile = WorldUtils.getTileEntity(world, pos);
if (tile != null) {
if (!player.isCreative()) {
FloatingLong energyPerUse = MekanismConfig.gear.networkReaderEnergyUsage.get();
IEnergyContainer energyContainer = StorageUtils.getEnergyContainer(context.getItemInHand(), 0);
if (energyContainer == null || energyContainer.extract(energyPerUse, Action.SIMULATE, AutomationType.MANUAL).smallerThan(energyPerUse)) {
return ActionResultType.FAIL;
}
energyContainer.extract(energyPerUse, Action.EXECUTE, AutomationType.MANUAL);
}
Direction opposite = context.getClickedFace().getOpposite();
if (tile instanceof TileEntityTransmitter) {
displayTransmitterInfo(player, ((TileEntityTransmitter) tile).getTransmitter(), tile, opposite);
} else {
Optional<IHeatHandler> heatHandler = CapabilityUtils.getCapability(tile, Capabilities.HEAT_HANDLER_CAPABILITY, opposite).resolve();
if (heatHandler.isPresent()) {
IHeatHandler transfer = heatHandler.get();
displayBorder(player, MekanismLang.MEKANISM, true);
sendTemperature(player, transfer);
displayEndBorder(player);
} else {
displayConnectedNetworks(player, world, pos);
}
}
return ActionResultType.SUCCESS;
} else if (player.isShiftKeyDown() && MekanismAPI.debug) {
displayBorder(player, MekanismLang.DEBUG_TITLE, true);
for (ITextComponent component : TransmitterNetworkRegistry.getInstance().toComponents()) {
player.sendMessage(TextComponentUtil.build(EnumColor.DARK_GRAY, component), Util.NIL_UUID);
}
displayEndBorder(player);
}
}
return ActionResultType.PASS;
}
use of mekanism.api.energy.IEnergyContainer in project Mekanism by mekanism.
the class ModuleGeothermalGeneratorUnit method tickServer.
@Override
public void tickServer(IModule<ModuleGeothermalGeneratorUnit> module, PlayerEntity player) {
IEnergyContainer energyContainer = module.getEnergyContainer();
if (energyContainer != null && !energyContainer.getNeeded().isZero()) {
double highestScaledDegrees = 0;
double legHeight = player.isCrouching() ? 0.6 : 0.7;
Map<Fluid, FluidInDetails> fluidsIn = MekanismUtils.getFluidsIn(player, bb -> new AxisAlignedBB(bb.minX, bb.minY, bb.minZ, bb.maxX, Math.min(bb.minY + legHeight, bb.maxY), bb.maxZ));
for (Map.Entry<Fluid, FluidInDetails> entry : fluidsIn.entrySet()) {
FluidInDetails details = entry.getValue();
double height = details.getMaxHeight();
if (height < 0.25) {
// Skip fluids that we are barely submerged in
continue;
}
double temperature = 0;
List<BlockPos> positions = details.getPositions();
for (BlockPos position : positions) {
temperature += entry.getKey().getAttributes().getTemperature(player.level, position);
}
// Divide the temperature by how many positions there are in case there is a difference due to the position in the world
// Strictly speaking we should take the height of the position into account for calculating the average as a "weighted"
// average, but we don't worry about that as it is highly unlikely the positions will actually have different temperatures,
// and it would add a bunch of complexity to the calculations to account for it
temperature /= positions.size();
if (temperature > HeatAPI.AMBIENT_TEMP) {
// If the temperature is above the ambient temperature, calculate how many degrees above
// and factor in how much of the legs are submerged
double scaledDegrees = (temperature - HeatAPI.AMBIENT_TEMP) * height / legHeight;
if (scaledDegrees > highestScaledDegrees) {
highestScaledDegrees = scaledDegrees;
}
}
}
if (highestScaledDegrees > 0 || player.isOnFire()) {
// Note: We compare this against zero as we adjust against ambient before scaling
if (highestScaledDegrees < 200 && player.isOnFire()) {
// Treat fire as having a temperature of ~500K, this is on the cooler side of what fire tends to
// be but should be good enough for factoring in how much a heat adapter would be able to transfer
highestScaledDegrees = 200;
}
// Insert energy
FloatingLong rate = MekanismGeneratorsConfig.gear.mekaSuitGeothermalChargingRate.get().multiply(module.getInstalledCount()).multiply(highestScaledDegrees);
energyContainer.insert(rate, Action.EXECUTE, AutomationType.MANUAL);
}
}
}
use of mekanism.api.energy.IEnergyContainer in project Mekanism by mekanism.
the class ModuleFarmingUnit method tillAOE.
private ActionResultType tillAOE(ItemUseContext context, ToolType toolType, SoundEvent sound, FloatingLong energyUsage) {
PlayerEntity player = context.getPlayer();
if (player == null || player.isShiftKeyDown()) {
// Skip if we don't have a player, or they are sneaking
return ActionResultType.PASS;
}
Direction sideHit = context.getClickedFace();
if (sideHit == Direction.DOWN) {
// Don't allow tilling a block from underneath
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();
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 tilledState = world.getBlockState(pos).getToolModifiedState(world, pos, player, stack, toolType);
if (tilledState == null) {
// Skip tilling the blocks if the one we clicked cannot be tilled
return ActionResultType.PASS;
}
BlockPos abovePos = pos.above();
BlockState aboveState = world.getBlockState(abovePos);
// Check to make sure the block above is not opaque
if (aboveState.isSolidRender(world, abovePos)) {
// If the block above our source is opaque, just skip tiling in general
return ActionResultType.PASS;
}
if (world.isClientSide) {
return ActionResultType.SUCCESS;
}
// Processing did not happen, so we need to process it
world.setBlock(pos, tilledState, BlockFlags.DEFAULT_AND_RERENDER);
Material aboveMaterial = aboveState.getMaterial();
if (aboveMaterial == Material.PLANT || aboveMaterial == Material.REPLACEABLE_PLANT) {
world.destroyBlock(abovePos, true);
}
world.playSound(null, pos, sound, SoundCategory.BLOCKS, 1.0F, 1.0F);
FloatingLong energyUsed = energyUsage.copy();
int radius = (diameter - 1) / 2;
for (BlockPos newPos : BlockPos.betweenClosed(pos.offset(-radius, 0, -radius), pos.offset(radius, 0, radius))) {
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;
}
BlockState stateAbove = world.getBlockState(newPos.above());
// the same as the one we got on the initial block we interacted with
if (!stateAbove.isSolidRender(world, newPos.above()) && tilledState == world.getBlockState(newPos).getToolModifiedState(world, newPos, player, stack, toolType)) {
// 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 HoeItem/ShovelItem do)
world.setBlock(newPos, tilledState, BlockFlags.DEFAULT_AND_RERENDER);
aboveMaterial = stateAbove.getMaterial();
if (aboveMaterial == Material.PLANT || aboveMaterial == Material.REPLACEABLE_PLANT) {
// If the block above the one we tilled is a plant, then we try to remove it
world.destroyBlock(newPos.above(), true);
}
world.playSound(null, newPos, sound, SoundCategory.BLOCKS, 1.0F, 1.0F);
Mekanism.packetHandler.sendToAllTracking(new PacketLightningRender(LightningPreset.TOOL_AOE, Objects.hash(pos, newPos), Vector3d.upFromBottomCenterOf(pos, 0.94), Vector3d.upFromBottomCenterOf(newPos, 0.94), 10), world, pos);
}
}
energyContainer.extract(energyUsed, Action.EXECUTE, AutomationType.MANUAL);
return ActionResultType.SUCCESS;
}
Aggregations