package crazypants.enderio.machine.solar; import java.util.EnumSet; import java.util.List; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.util.ForgeDirection; import cofh.api.energy.EnergyStorage; import com.google.common.collect.Lists; public class SolarPanelNetwork { private List<TileEntitySolarPanel> panels; private boolean empty = true; private EnergyStorage energy; public static final int ENERGY_PER = 10000; public static final EnumSet<ForgeDirection> VALID_CONS = EnumSet.of(ForgeDirection.NORTH, ForgeDirection.SOUTH, ForgeDirection.EAST, ForgeDirection.WEST); public SolarPanelNetwork() { panels = Lists.newArrayList(); energy = new EnergyStorage(ENERGY_PER); } SolarPanelNetwork(TileEntitySolarPanel initial) { this(); panels.add(initial); empty = false; } void onUpdate(TileEntitySolarPanel panel) { } boolean addToNetwork(TileEntitySolarPanel panel) { if(panel.network == this && panel.network.isValid() && panels.contains(panel)) { return false; } if(panel.network == null || !panel.network.isValid() || panel.network == this) { if (!panels.contains(panel)) { panels.add(panel); } panel.setNetwork(this); updateEnergy(); } else { SolarPanelNetwork other = panel.network; for (TileEntitySolarPanel otherPanel : other.panels) { panels.add(otherPanel); otherPanel.setNetwork(this); } updateEnergy(); this.energy.setEnergyStored(energy.getEnergyStored() + other.energy.getEnergyStored()); other.invalidate(); } empty = false; return true; } void removeFromNetwork(TileEntitySolarPanel panel) { // build list of formerly connected neighbors List<TileEntitySolarPanel> neighbors = Lists.newArrayList(); for (ForgeDirection dir : VALID_CONS) { TileEntity te = panel.getLocation().getLocation(dir).getTileEntity(panel.getWorldObj()); if(te != null && te instanceof TileEntitySolarPanel) { neighbors.add((TileEntitySolarPanel) te); } } // distribute power from split networks evenly to neighbors for (TileEntitySolarPanel te : neighbors) { int dist = energy.getEnergyStored() / neighbors.size(); te.destroyedNetworkBuffer = new EnergyStorage(dist); te.destroyedNetworkBuffer.setEnergyStored(dist); } // allow solars to reform networks destroyNetwork(); } private void updateEnergy() { energy.setCapacity(ENERGY_PER * panels.size()); energy.setMaxExtract(energy.getMaxEnergyStored()); } /** * Actually destroys all references to this network, creating an invalid * network for each panel on this current one. */ void destroyNetwork() { for (TileEntitySolarPanel te : panels) { te.setNetwork(new SolarPanelNetwork()); } invalidate(); } /** * Does nothing but clear this network, other panels may still hold a * reference to this network. */ private void invalidate() { panels.clear(); empty = true; } public boolean isValid() { return !empty; } public int extractEnergy(int maxExtract, boolean simulate) { return isValid() ? energy.extractEnergy(maxExtract, simulate) : 0; } public int getEnergyStored() { return energy.getEnergyStored(); } public int setEnergyStored(int energy) { if(isValid()) { this.energy.setEnergyStored(energy); } return this.energy.getEnergyStored(); } public int getMaxEnergyStored() { return energy.getMaxEnergyStored(); } public int getMaxEnergyExtracted() { return energy.getMaxExtract(); } public void addBuffer(EnergyStorage destroyedNetworkBuffer) { energy.receiveEnergy(destroyedNetworkBuffer.getEnergyStored(), false); } TileEntitySolarPanel getMaster() { return panels.get(0); } boolean shouldSave(TileEntitySolarPanel panel) { return getMaster() == panel; } public int size() { return panels.size(); } void writeToNBT(NBTTagCompound tag) { tag.setBoolean("validSolar", true); energy.writeToNBT(tag); } void readFromNBT(TileEntitySolarPanel panel, NBTTagCompound tag) { if(tag.getBoolean("validSolar")) { energy.readFromNBT(tag); addToNetwork(panel); } } }