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)
{
TileBattery battery = (TileBattery) world.getBlockTileEntity(x, y, z);
battery.updateStructure();
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();
}
}
}
@ -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
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
*/
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
@ -39,11 +39,6 @@ public class TileBattery extends TileElectrical implements IConnector<BatteryNet
/** Voltage increases as series connection increases */
public static final long DEFAULT_VOLTAGE = UniversalElectricity.DEFAULT_VOLTAGE;
private BatteryNetwork network;
public boolean markClientUpdate = false;
public boolean markDistributionUpdate = false;
public TileBattery()
{
this.energy = new EnergyStorageHandler(0);
@ -62,67 +57,20 @@ public class TileBattery extends TileElectrical implements IConnector<BatteryNet
@Override
public void initiate()
{
this.updateStructure();
super.initiate();
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
public void updateEntity()
{
super.updateEntity();
if (!this.worldObj.isRemote)
{
energy.setMaxTransfer((long) Math.min(Math.pow(10000, this.getNetwork().getConnectors().size()), energy.getEnergyCapacity()));
long produce = produce();
if ((markDistributionUpdate || produce > 0) && ticks % 5 == 0)
{
getNetwork().redistribute();
markDistributionUpdate = false;
markDistributionUpdate |= produce() > 0;
}
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;
super.updateEntity();
}
@Override
@ -147,50 +95,6 @@ public class TileBattery extends TileElectrical implements IConnector<BatteryNet
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
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
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 resonantinduction.core.Reference;
import resonantinduction.core.render.RIBlockRenderingHandler;
import resonantinduction.electrical.battery.TileEnergyDistribution;
import universalelectricity.api.UniversalElectricity;
import calclavia.lib.prefab.block.BlockTile;
import cpw.mods.fml.relauncher.Side;
@ -23,6 +24,29 @@ public class BlockSolarPanel extends BlockTile
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)
@Override
public void registerIcons(IconRegister iconReg)

View file

@ -1,21 +1,19 @@
package resonantinduction.electrical.generator.solar;
import resonantinduction.electrical.battery.TileEnergyDistribution;
import universalelectricity.api.energy.EnergyStorageHandler;
import calclavia.lib.prefab.tile.TileElectrical;
public class TileSolarPanel extends TileElectrical
public class TileSolarPanel extends TileEnergyDistribution
{
public TileSolarPanel()
{
this.energy = new EnergyStorageHandler(500);
this.energy = new EnergyStorageHandler(800);
this.ioMap = 728;
}
@Override
public void updateEntity()
{
super.updateEntity();
if (!this.worldObj.isRemote)
{
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()))
{
this.energy.receiveEnergy(25, true);
this.produce();
}
markDistributionUpdate |= produce() > 0;
}
}
}
}
super.updateEntity();
}
}