package de.ellpeck.naturesaura.blocks.tiles; import de.ellpeck.naturesaura.ModConfig; import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk; import de.ellpeck.naturesaura.blocks.multi.Multiblocks; import de.ellpeck.naturesaura.packet.PacketHandler; import de.ellpeck.naturesaura.packet.PacketParticles; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; import net.minecraft.util.Mth; import net.minecraft.world.level.block.state.BlockState; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.energy.CapabilityEnergy; import net.minecraftforge.energy.EnergyStorage; import net.minecraftforge.energy.IEnergyStorage; import javax.annotation.Nullable; public class BlockEntityRFConverter extends BlockEntityImpl implements ITickableBlockEntity { public final RFStorage storage = new RFStorage(); private final LazyOptional storageOptional = LazyOptional.of(() -> this.storage); private int lastEnergy; public BlockEntityRFConverter(BlockPos pos, BlockState state) { super(ModBlockEntities.RF_CONVERTER, pos, state); } @Override public void writeNBT(CompoundTag compound, SaveType type) { super.writeNBT(compound, type); compound.putInt("energy", this.storage.getEnergyStored()); } @Override public void readNBT(CompoundTag compound, SaveType type) { super.readNBT(compound, type); this.storage.setEnergy(compound.getInt("energy")); } @Override public void tick() { if (!this.level.isClientSide && ModConfig.instance.rfConverter.get()) { if (this.lastEnergy != this.storage.getEnergyStored() && this.level.getGameTime() % 10 == 0) { this.sendToClients(); this.lastEnergy = this.storage.getEnergyStored(); } for (var facing : Direction.values()) { var tile = this.level.getBlockEntity(this.worldPosition.relative(facing)); if (tile == null) continue; var storage = tile.getCapability(CapabilityEnergy.ENERGY, facing.getOpposite()).orElse(null); if (storage == null) continue; var canStore = storage.receiveEnergy(Integer.MAX_VALUE, true); if (canStore <= 0) continue; var extracted = this.storage.extractEnergy(canStore, false); if (extracted <= 0) continue; storage.receiveEnergy(extracted, false); break; } var emptyPart = this.storage.getMaxEnergyStored() - this.storage.getEnergyStored(); if (emptyPart <= 0) return; if (this.level.getGameTime() % 20 != 0) return; if (!Multiblocks.RF_CONVERTER.isComplete(this.level, this.worldPosition)) return; var aura = IAuraChunk.getAuraInArea(this.level, this.worldPosition, 45); if (aura <= IAuraChunk.DEFAULT_AURA) return; var amountToGen = Math.min(Math.min(10000, aura / 1000), emptyPart); var amountToUse = Mth.ceil(amountToGen / ModConfig.instance.auraToRFRatio.get()); this.storage.setEnergy(this.storage.getEnergyStored() + amountToGen); var pos = IAuraChunk.getHighestSpot(this.level, this.worldPosition, 45, this.worldPosition); IAuraChunk.getAuraChunk(this.level, pos).drainAura(pos, amountToUse); PacketHandler.sendToAllAround(this.level, this.worldPosition, 32, new PacketParticles(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ(), PacketParticles.Type.RF_CONVERTER)); } } @Nullable @Override public LazyOptional getCapability(Capability capability, @Nullable Direction facing) { if (capability == CapabilityEnergy.ENERGY) return this.storageOptional.cast(); else return super.getCapability(capability, facing); } @Override public void setRemoved() { super.setRemoved(); this.storageOptional.invalidate(); } public static class RFStorage extends EnergyStorage { public RFStorage() { super(50000, 0, 2000); } public void setEnergy(int energy) { this.energy = energy; } } }