In the TileEntity:
public abstract class CoalGeneratorTileEntity extends TileEntity implements INamedContainerProvider {
protected ITextComponent customName;
protected I inventory;
protected BaseEnergyStorage energy = new BaseEnergyStorage(getCapacity(), getMaxReceive(), getMaxExtract(), getStartEnergy());
public int currentProcessingTime;
protected boolean isProcessing = false;
public static final String CURRENT_PROCESSING_TIME = "CurrentProcessingTime";
public static final String CUSTOM_NAME = "CustomName";
public CoalGeneratorTileEntity(TileEntityType<?> tileEntityTypeIn) {
super(tileEntityTypeIn);
inventory = new BaseItemHandler(1);
}
@Override
public Container createMenu(int windowId, PlayerInventory playerInventory, PlayerEntity player) {
return new CoalGeneratorContainer(windowId, playerInventory, this, ModContainerTypes.COAL_GENERATOR);
}
@Override
public ITextComponent getDisplayName() {
return getName();
}
public void setCustomName(ITextComponent name) {
customName = name;
}
public ITextComponent getName() {
return customName != null ? customName : getDefaultName();
}
private ITextComponent getDefaultName() {
return new TranslationTextComponent("container." + TodayAndTomorrow.MOD_ID + "." + "coal_generator");
}
@Override
public void read(CompoundNBT compound) {
super.read(compound);
if (compound.contains(CUSTOM_NAME, Constants.NBT.TAG_STRING)) {
customName = ITextComponent.Serializer.fromJson(compound.getString(CUSTOM_NAME));
}
NonNullList<ItemStack> inv = NonNullList.withSize(inventory.getSlots(), ItemStack.EMPTY);
ItemStackHelper.loadAllItems(compound, inv);
inventory.setNonNullList(inv);
energy.readFromNBT(compound);
currentProcessingTime = compound.getInt(CURRENT_PROCESSING_TIME);
}
@Override
public CompoundNBT write(CompoundNBT compound) {
super.write(compound);
if (customName != null) {
compound.putString("CustomName", ITextComponent.Serializer.toJson(this.customName));
}
ItemStackHelper.saveAllItems(compound, inventory.toNonNullList());
energy.writeToNBT(compound);
compound.putInt(CURRENT_PROCESSING_TIME, currentProcessingTime);
return compound;
}
public I getInventory() {
return inventory;
}
@Override
public SUpdateTileEntityPacket getUpdatePacket() {
CompoundNBT nbt = new CompoundNBT();
this.write(nbt);
return new SUpdateTileEntityPacket(this.pos, 0, nbt);
}
@Override
public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) {
this.read(pkt.getNbtCompound());
}
@Override
public CompoundNBT getUpdateTag() {
CompoundNBT nbt = new CompoundNBT();
this.write(nbt);
return nbt;
}
@Override
public void handleUpdateTag(CompoundNBT nbt) {
this.read(nbt);
}
@Override
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
LazyOptional<T> inventory = CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.orEmpty(cap, LazyOptional.of(() -> inventory));
if (inventory.isPresent()) {
return inventory;
}
return CapabilityEnergy.ENERGY.orEmpty(cap, LazyOptional.of(() -> energy));
}
@Override
public Container createMenu(int windowId, PlayerInventory playerInventory, PlayerEntity player) {
return createMenu(windowId, playerInventory, player);
}
@Override
public void tick() {
boolean dirty = false;
if (world != null && !world.isRemote()) {
if ((energy.getMaxEnergyStored() > energy.getEnergyStored() && inventory.getStackInSlot(0).getCount() > 0)
|| isProcessing) {
if (currentProcessingTime < getProcessingTime()) {
if (currentProcessingTime == 0) {
inventory.decrStackSize(0, 1);
isProcessing = true;
}
energy.receiveEnergyRaw(ENERGY_PER_TICK, false);
setLit(true);
currentProcessingTime++;
dirty = true;
} else {
currentProcessingTime = 0;
isProcessing = false;
}
} else {
currentProcessingTime = 0;
setLit(false);
}
}
if (dirty) {
markDirty();
world.notifyBlockUpdate(getPos(), getBlockState(), getBlockState(), Constants.BlockFlags.BLOCK_UPDATE);
}
}
protected void setLit(boolean lit) {
if (getBlockState().getBlock() instanceof LitGuiBlock) {
world.setBlockState(getPos(), getBlockState().with("lit", lit));
}
}
}
BaseEnergyStorage is a class that extends EnergyStorage.
In the wire I've gone through all connected wires and checked if a tile entity with energy capacity is there.
public class CopperWireTileEntity extends TileEntity implements ITickableTileEntity {
boolean[] machineAt = new boolean[6];
public CopperWireTileEntity(TileEntityType<?> tileEntityTypeIn) {
super(tileEntityTypeIn);
Arrays.fill(machineAt, false);
}
public CopperWireTileEntity() {
this(ModTileEntityTypes.COPPER_WIRE.get());
}
@Override
public void tick() {
updateSide(0, getPos().north(), Direction.NORTH);
updateSide(1, getPos().east(), Direction.EAST);
updateSide(2, getPos().south(), Direction.SOUTH);
updateSide(3, getPos().west(), Direction.WEST);
updateSide(4, getPos().up(), Direction.UP);
updateSide(5, getPos().down(), Direction.DOWN);
int energyAvailable = getEnergyAvailable();
if (energyAvailable != 0) {
int takeAway = scatterEnergy(energyAvailable);
takeAwayEnergy(takeAway, energyAvailable);
}
}
protected void updateSide(int index, BlockPos pos, Direction direction) {
if (!machineAt[index]) {
TileEntity tileEntity = world.getTileEntity(pos);
if (tileEntity != null && tileEntity.getCapability(CapabilityEnergy.ENERGY).isPresent()) {
machineAt[index] = true;
}
} else if (world.getBlockState(pos).getBlock() == Blocks.AIR) {
machineAt[index] = false;
}
}
protected int getEnergyAvailable() {
AtomicInteger energyAvailable = new AtomicInteger();
for (int i = 0; i < machineAt.length; i++) {
if (machineAt[i]) {
world.getTileEntity(getBlockPosByIndex(pos, i)).getCapability(CapabilityEnergy.ENERGY).ifPresent((e) -> energyAvailable.addAndGet(e.extractEnergy(Integer.MAX_VALUE, true)));
}
}
return energyAvailable.get();
}
protected int scatterEnergy(int energyAvailable) {
ArrayList<BlockPos> visited = new ArrayList<>();
ArrayList<IEnergyStorage> outputMachinePositions = new ArrayList<>();
getOutputMachinesEnergy(getPos(), visited, outputMachinePositions);
int maxReceives = 0;
for (IEnergyStorage energy : outputMachinePositions) {
maxReceives += energy.receiveEnergy(Integer.MAX_VALUE, true);
}
if (maxReceives <= energyAvailable) {
for (IEnergyStorage energy : outputMachinePositions) {
int sent = energy.receiveEnergy(Integer.MAX_VALUE, false);
}
return maxReceives;
}
int energyGiven = 0;
for (IEnergyStorage energy : outputMachinePositions) {
int energyNeeded = energy.receiveEnergy(Integer.MAX_VALUE, true);
int energyToGive = (int)((float)energyNeeded / (float)maxReceives * (float)energyAvailable);
energyGiven += energyToGive;
int a = energy.receiveEnergy(energyToGive, false);
}
return energyGiven;
}
protected void takeAwayEnergy(int takeAway, int energyAvailable) {
for (int i = 0; i < machineAt.length; i++) {
if (machineAt[i]) {
world.getTileEntity(getBlockPosByIndex(pos, i)).getCapability(CapabilityEnergy.ENERGY).ifPresent((e) -> {
int energyProviding = e.extractEnergy(Integer.MAX_VALUE, true);
int energyToTakeAway = (int)((float)energyProviding / (float)energyAvailable * (float)takeAway);
e.extractEnergy(energyToTakeAway, false);
});
}
}
}
protected void getOutputMachinesEnergy(BlockPos pos, ArrayList<BlockPos> visited, ArrayList<IEnergyStorage> outEnergies) {
if (!visited.contains(pos)) {
if (world.getBlockState(pos).getBlock() == BlockInit.COPPER_WIRE.get()) {
visited.add(pos);
getOutputMachinesEnergy(pos.north(), visited, outEnergies);
getOutputMachinesEnergy(pos.east(), visited, outEnergies);
getOutputMachinesEnergy(pos.south(), visited, outEnergies);
getOutputMachinesEnergy(pos.west(), visited, outEnergies);
getOutputMachinesEnergy(pos.up(), visited, outEnergies);
getOutputMachinesEnergy(pos.down(), visited, outEnergies);
} else if (world.getTileEntity(pos) != null && world.getTileEntity(pos).getCapability(CapabilityEnergy.ENERGY).isPresent()) {
AtomicReference<IEnergyStorage> energy = new AtomicReference<>();
world.getTileEntity(pos).getCapability(CapabilityEnergy.ENERGY).ifPresent(energy::set);
outEnergies.add(energy.get());
}
}
}
protected BlockPos getBlockPosByIndex(BlockPos pos, int index) {
switch (index) {
case 0:
return pos.north();
case 1:
return pos.east();
case 2:
return pos.south();
case 3:
return pos.west();
case 4:
return pos.up();
case 5:
return pos.down();
}
throw new IllegalArgumentException("Invalid index: " + index);
}
}
I thought that the energy consuming machines from other Mods would have EnergyStorge with maxReceive from more that 0 so that I could give them energy. But when i tested it with Mekansim:
int energyNeeded = energy.receiveEnergy(Integer.MAX_VALUE, true);
and energyNeeded was 0 so the wire didn't extract any energy.