Solar panels now act as multiblock

This commit is contained in:
Calclavia 2014-02-16 21:11:11 +08:00
parent 0358d65ee1
commit 7e94dbee68
7 changed files with 238 additions and 188 deletions

View file

@ -1,61 +0,0 @@
package resonantinduction.electrical.battery;
import java.util.Arrays;
import universalelectricity.core.net.Network;
public class BatteryNetwork extends Network<BatteryNetwork, TileBattery>
{
public void redistribute(TileBattery... exclusion)
{
long totalEnergy = 0;
long totalCapacity = 0;
for (TileBattery battery : this.getConnectors())
{
totalEnergy += battery.energy.getEnergy();
totalCapacity += battery.energy.getEnergyCapacity();
}
/**
* Apply energy loss.
*/
double percentageLoss = Math.max(0, (1 - (getConnectors().size() * 6 / 100d)));
long energyLoss = (long) (percentageLoss * 100);
totalEnergy -= energyLoss;
int amountOfNodes = this.getConnectors().size() - exclusion.length;
if (totalEnergy > 0 && amountOfNodes > 0)
{
long remainingEnergy = totalEnergy;
TileBattery firstNode = this.getFirstConnector();
for (TileBattery battery : this.getConnectors())
{
if (battery != firstNode && !Arrays.asList(exclusion).contains(battery))
{
double percentage = ((double) battery.energy.getEnergyCapacity() / (double) totalCapacity);
long energyForBattery = Math.round(totalEnergy * percentage);
battery.energy.setEnergy(energyForBattery);
remainingEnergy -= energyForBattery;
}
}
firstNode.energy.setEnergy(remainingEnergy);
}
}
@Override
protected void reconstructConnector(TileBattery node)
{
node.setNetwork(this);
}
@Override
public BatteryNetwork newInstance()
{
return new BatteryNetwork();
}
}

View file

@ -40,8 +40,21 @@ public class BlockBattery extends BlockSidedIO implements ITileEntityProvider
{ {
if (!world.isRemote) if (!world.isRemote)
{ {
TileBattery battery = (TileBattery) world.getBlockTileEntity(x, y, z); TileEnergyDistribution distribution = (TileEnergyDistribution) world.getBlockTileEntity(x, y, z);
battery.updateStructure(); distribution.updateStructure();
}
}
@Override
public void onNeighborBlockChange(World world, int x, int y, int z, int id)
{
if (!world.isRemote)
{
if (id == blockID)
{
TileEnergyDistribution distribution = (TileEnergyDistribution) world.getBlockTileEntity(x, y, z);
distribution.updateStructure();
}
} }
} }
@ -59,19 +72,6 @@ public class BlockBattery extends BlockSidedIO implements ITileEntityProvider
} }
} }
@Override
public void onNeighborBlockChange(World world, int x, int y, int z, int id)
{
if (!world.isRemote)
{
if (id == blockID)
{
TileBattery battery = (TileBattery) world.getBlockTileEntity(x, y, z);
battery.updateStructure();
}
}
}
@Override @Override
public boolean onSneakUseWrench(World world, int x, int y, int z, EntityPlayer entityPlayer, int side, float hitX, float hitY, float hitZ) public boolean onSneakUseWrench(World world, int x, int y, int z, EntityPlayer entityPlayer, int side, float hitX, float hitY, float hitZ)
{ {

View file

@ -0,0 +1,61 @@
package resonantinduction.electrical.battery;
import java.util.Arrays;
import universalelectricity.core.net.Network;
public class EnergyDistributionNetwork extends Network<EnergyDistributionNetwork, TileEnergyDistribution>
{
public void redistribute(TileEnergyDistribution... exclusion)
{
long totalEnergy = 0;
long totalCapacity = 0;
for (TileEnergyDistribution energyContainer : this.getConnectors())
{
totalEnergy += energyContainer.energy.getEnergy();
totalCapacity += energyContainer.energy.getEnergyCapacity();
}
/**
* Apply energy loss.
*/
double percentageLoss = Math.max(0, (1 - (getConnectors().size() * 6 / 100d)));
long energyLoss = (long) (percentageLoss * 100);
totalEnergy -= energyLoss;
int amountOfNodes = this.getConnectors().size() - exclusion.length;
if (totalEnergy > 0 && amountOfNodes > 0)
{
long remainingEnergy = totalEnergy;
TileEnergyDistribution firstNode = this.getFirstConnector();
for (TileEnergyDistribution node : this.getConnectors())
{
if (node != firstNode && !Arrays.asList(exclusion).contains(node))
{
double percentage = ((double) node.energy.getEnergyCapacity() / (double) totalCapacity);
long energyForBattery = Math.round(totalEnergy * percentage);
node.energy.setEnergy(energyForBattery);
remainingEnergy -= energyForBattery;
}
}
firstNode.energy.setEnergy(remainingEnergy);
}
}
@Override
protected void reconstructConnector(TileEnergyDistribution node)
{
node.setNetwork(this);
}
@Override
public EnergyDistributionNetwork newInstance()
{
return new EnergyDistributionNetwork();
}
}

View file

@ -26,7 +26,7 @@ import com.google.common.io.ByteArrayDataInput;
* *
* @author Calclavia * @author Calclavia
*/ */
public class TileBattery extends TileElectrical implements IConnector<BatteryNetwork>, IVoltageInput, IVoltageOutput, IPacketSender, IPacketReceiver, IEnergyInterface, IEnergyContainer public class TileBattery extends TileEnergyDistribution implements IVoltageInput, IVoltageOutput, IPacketSender, IPacketReceiver, IEnergyInterface, IEnergyContainer
{ {
/** /**
* Tiers: 0, 1, 2 * Tiers: 0, 1, 2
@ -39,11 +39,6 @@ public class TileBattery extends TileElectrical implements IConnector<BatteryNet
/** Voltage increases as series connection increases */ /** Voltage increases as series connection increases */
public static final long DEFAULT_VOLTAGE = UniversalElectricity.DEFAULT_VOLTAGE; public static final long DEFAULT_VOLTAGE = UniversalElectricity.DEFAULT_VOLTAGE;
private BatteryNetwork network;
public boolean markClientUpdate = false;
public boolean markDistributionUpdate = false;
public TileBattery() public TileBattery()
{ {
this.energy = new EnergyStorageHandler(0); this.energy = new EnergyStorageHandler(0);
@ -62,67 +57,20 @@ public class TileBattery extends TileElectrical implements IConnector<BatteryNet
@Override @Override
public void initiate() public void initiate()
{ {
this.updateStructure(); super.initiate();
energy.setCapacity(getEnergyForTier(getBlockMetadata())); energy.setCapacity(getEnergyForTier(getBlockMetadata()));
} }
public void updateStructure()
{
if (!this.worldObj.isRemote)
{
for (Object obj : getConnections())
{
if (obj instanceof TileBattery)
{
this.getNetwork().merge(((TileBattery) obj).getNetwork());
}
}
markDistributionUpdate = true;
markClientUpdate = true;
}
}
@Override @Override
public void updateEntity() public void updateEntity()
{ {
super.updateEntity();
if (!this.worldObj.isRemote) if (!this.worldObj.isRemote)
{ {
energy.setMaxTransfer((long) Math.min(Math.pow(10000, this.getNetwork().getConnectors().size()), energy.getEnergyCapacity())); energy.setMaxTransfer((long) Math.min(Math.pow(10000, this.getNetwork().getConnectors().size()), energy.getEnergyCapacity()));
markDistributionUpdate |= produce() > 0;
long produce = produce();
if ((markDistributionUpdate || produce > 0) && ticks % 5 == 0)
{
getNetwork().redistribute();
markDistributionUpdate = false;
} }
if (markClientUpdate && ticks % 5 == 0) super.updateEntity();
{
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
}
}
@Override
public long onReceiveEnergy(ForgeDirection from, long receive, boolean doReceive)
{
long returnValue = super.onReceiveEnergy(from, receive, doReceive);
markDistributionUpdate = true;
markClientUpdate = true;
return returnValue;
}
@Override
public long onExtractEnergy(ForgeDirection from, long extract, boolean doExtract)
{
long returnValue = super.onExtractEnergy(from, extract, doExtract);
markDistributionUpdate = true;
markClientUpdate = true;
return returnValue;
} }
@Override @Override
@ -147,50 +95,6 @@ public class TileBattery extends TileElectrical implements IConnector<BatteryNet
return data; return data;
} }
@Override
public BatteryNetwork getNetwork()
{
if (this.network == null)
{
this.network = new BatteryNetwork();
this.network.addConnector(this);
}
return this.network;
}
@Override
public void setNetwork(BatteryNetwork structure)
{
this.network = structure;
}
@Override
public Object[] getConnections()
{
Object[] connections = new Object[6];
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS)
{
TileEntity tile = new Vector3(this).translate(dir).getTileEntity(this.worldObj);
if (tile instanceof TileBattery)
{
connections[dir.ordinal()] = tile;
}
}
return connections;
}
@Override
public void invalidate()
{
this.getNetwork().redistribute(this);
this.getNetwork().split(this);
super.invalidate();
}
@Override @Override
public long getVoltageOutput(ForgeDirection side) public long getVoltageOutput(ForgeDirection side)
{ {
@ -209,12 +113,6 @@ public class TileBattery extends TileElectrical implements IConnector<BatteryNet
} }
@Override
public IConnector<BatteryNetwork> getInstance(ForgeDirection from)
{
return this;
}
@Override @Override
public void setIO(ForgeDirection dir, int type) public void setIO(ForgeDirection dir, int type)
{ {

View file

@ -0,0 +1,128 @@
package resonantinduction.electrical.battery;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.api.net.IConnector;
import universalelectricity.api.vector.Vector3;
import calclavia.lib.prefab.tile.TileElectrical;
public class TileEnergyDistribution extends TileElectrical implements IConnector<EnergyDistributionNetwork>
{
private EnergyDistributionNetwork network;
public boolean markClientUpdate = false;
public boolean markDistributionUpdate = false;
@Override
public void initiate()
{
super.initiate();
this.updateStructure();
}
@Override
public void updateEntity()
{
super.updateEntity();
if (!this.worldObj.isRemote)
{
if (markDistributionUpdate && ticks % 5 == 0)
{
getNetwork().redistribute();
markDistributionUpdate = false;
}
if (markClientUpdate && ticks % 5 == 0)
{
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
}
}
@Override
public long onReceiveEnergy(ForgeDirection from, long receive, boolean doReceive)
{
long returnValue = super.onReceiveEnergy(from, receive, doReceive);
markDistributionUpdate = true;
markClientUpdate = true;
return returnValue;
}
@Override
public long onExtractEnergy(ForgeDirection from, long extract, boolean doExtract)
{
long returnValue = super.onExtractEnergy(from, extract, doExtract);
markDistributionUpdate = true;
markClientUpdate = true;
return returnValue;
}
@Override
public EnergyDistributionNetwork getNetwork()
{
if (this.network == null)
{
this.network = new EnergyDistributionNetwork();
this.network.addConnector(this);
}
return this.network;
}
@Override
public void setNetwork(EnergyDistributionNetwork structure)
{
this.network = structure;
}
public void updateStructure()
{
if (!this.worldObj.isRemote)
{
for (Object obj : getConnections())
{
if (obj != null)
{
this.getNetwork().merge(((TileEnergyDistribution) obj).getNetwork());
}
}
markDistributionUpdate = true;
markClientUpdate = true;
}
}
@Override
public Object[] getConnections()
{
Object[] connections = new Object[6];
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS)
{
TileEntity tile = new Vector3(this).translate(dir).getTileEntity(this.worldObj);
if (tile != null && tile.getClass() == this.getClass())
{
connections[dir.ordinal()] = tile;
}
}
return connections;
}
@Override
public void invalidate()
{
this.getNetwork().redistribute(this);
this.getNetwork().split(this);
super.invalidate();
}
@Override
public IConnector<EnergyDistributionNetwork> getInstance(ForgeDirection from)
{
return this;
}
}

View file

@ -6,6 +6,7 @@ import net.minecraft.util.Icon;
import net.minecraft.world.World; import net.minecraft.world.World;
import resonantinduction.core.Reference; import resonantinduction.core.Reference;
import resonantinduction.core.render.RIBlockRenderingHandler; import resonantinduction.core.render.RIBlockRenderingHandler;
import resonantinduction.electrical.battery.TileEnergyDistribution;
import universalelectricity.api.UniversalElectricity; import universalelectricity.api.UniversalElectricity;
import calclavia.lib.prefab.block.BlockTile; import calclavia.lib.prefab.block.BlockTile;
import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.Side;
@ -23,6 +24,29 @@ public class BlockSolarPanel extends BlockTile
setBlockBounds(0, 0, 0, 1, 0.3f, 1); setBlockBounds(0, 0, 0, 1, 0.3f, 1);
} }
@Override
public void onBlockAdded(World world, int x, int y, int z)
{
if (!world.isRemote)
{
TileEnergyDistribution distribution = (TileEnergyDistribution) world.getBlockTileEntity(x, y, z);
distribution.updateStructure();
}
}
@Override
public void onNeighborBlockChange(World world, int x, int y, int z, int id)
{
if (!world.isRemote)
{
if (id == blockID)
{
TileEnergyDistribution distribution = (TileEnergyDistribution) world.getBlockTileEntity(x, y, z);
distribution.updateStructure();
}
}
}
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
@Override @Override
public void registerIcons(IconRegister iconReg) public void registerIcons(IconRegister iconReg)

View file

@ -1,21 +1,19 @@
package resonantinduction.electrical.generator.solar; package resonantinduction.electrical.generator.solar;
import resonantinduction.electrical.battery.TileEnergyDistribution;
import universalelectricity.api.energy.EnergyStorageHandler; import universalelectricity.api.energy.EnergyStorageHandler;
import calclavia.lib.prefab.tile.TileElectrical;
public class TileSolarPanel extends TileElectrical public class TileSolarPanel extends TileEnergyDistribution
{ {
public TileSolarPanel() public TileSolarPanel()
{ {
this.energy = new EnergyStorageHandler(500); this.energy = new EnergyStorageHandler(800);
this.ioMap = 728; this.ioMap = 728;
} }
@Override @Override
public void updateEntity() public void updateEntity()
{ {
super.updateEntity();
if (!this.worldObj.isRemote) if (!this.worldObj.isRemote)
{ {
if (this.worldObj.canBlockSeeTheSky(xCoord, yCoord + 1, zCoord) && !this.worldObj.provider.hasNoSky) if (this.worldObj.canBlockSeeTheSky(xCoord, yCoord + 1, zCoord) && !this.worldObj.provider.hasNoSky)
@ -25,11 +23,13 @@ public class TileSolarPanel extends TileElectrical
if (!(this.worldObj.isThundering() || this.worldObj.isRaining())) if (!(this.worldObj.isThundering() || this.worldObj.isRaining()))
{ {
this.energy.receiveEnergy(25, true); this.energy.receiveEnergy(25, true);
this.produce(); markDistributionUpdate |= produce() > 0;
}
} }
} }
} }
} }
super.updateEntity();
}
} }