Initial work on new power network

This commit is contained in:
modmuss50 2016-03-07 19:05:56 +00:00
parent a9fed5d933
commit 10c593e3c1
5 changed files with 365 additions and 6 deletions

View file

@ -45,6 +45,7 @@ import techreborn.init.RecipeCompact;
import techreborn.lib.ModInfo;
import techreborn.packets.PacketAesu;
import techreborn.packets.PacketIdsu;
import techreborn.power.PowerTickEvent;
import techreborn.proxies.CommonProxy;
import techreborn.tiles.idsu.IDSUManager;
import techreborn.world.TROreGen;

View file

@ -3,15 +3,23 @@ package techreborn.events;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.potion.Potion;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import techreborn.init.ModItems;
import techreborn.power.PowerTickEvent;
import techreborn.power.TRPowerNet;
import java.util.ArrayList;
import java.util.List;
public class TRTickHandler {
public Item previouslyWearing;
public static List<TRPowerNet> oldNets = new ArrayList<>();
@SubscribeEvent(priority = EventPriority.NORMAL, receiveCanceled = true)
public void onPlayerTick(TickEvent.PlayerTickEvent e) {
EntityPlayer player = e.player;
@ -24,5 +32,16 @@ public class TRTickHandler {
previouslyWearing = chestslot;
}
@SubscribeEvent
public void worldTick(TickEvent.WorldTickEvent e) {
if(!oldNets.isEmpty()){
for(TRPowerNet powerNet : oldNets){
MinecraftForge.EVENT_BUS.unregister(powerNet);
}
oldNets.clear();
}
if(!e.world.isRemote)
MinecraftForge.EVENT_BUS.post(new PowerTickEvent());
}
}

View file

@ -25,6 +25,7 @@ import net.minecraftforge.common.property.Properties;
import reborncore.api.power.IEnergyInterfaceTile;
import reborncore.common.misc.Functions;
import reborncore.common.misc.vecmath.Vecs3dCube;
import techreborn.power.TRPowerNet;
import techreborn.utils.damageSources.ElectrialShockSource;
import java.util.*;
@ -169,6 +170,12 @@ public abstract class CableMultipart extends Multipart implements IOccludingPart
if (cableMultipart != null && cableMultipart.internalShouldConnectTo(dir.getOpposite())) {
return true;
}
} else {
TileEntity tile = getNeighbourTile(dir);
if (tile instanceof IEnergyInterfaceTile) {
return true;
}
}
}
return false;
@ -186,13 +193,9 @@ public abstract class CableMultipart extends Multipart implements IOccludingPart
return false;
}
if (getPartFromWorld(getWorld(), getPos().offset(dir), dir.getOpposite()) != null) {
return true;
}
CableMultipart cableMultipart = getPartFromWorld(getWorld(), getPos().offset(dir), dir.getOpposite());
TileEntity tile = getNeighbourTile(dir);
if (tile instanceof IEnergyInterfaceTile) {
if (cableMultipart != null && cableMultipart.getCableType() == getCableType()) {
return true;
}
return false;
@ -229,6 +232,9 @@ public abstract class CableMultipart extends Multipart implements IOccludingPart
checkConnectedSides();
}
}
if (network == null) {
this.findAndJoinNetwork(getWorld(), getPos());
}
}
@Override
@ -300,4 +306,56 @@ public abstract class CableMultipart extends Multipart implements IOccludingPart
public ItemStack getPickBlock(EntityPlayer player, PartMOP hit) {
return new ItemStack(TechRebornParts.cables, 1, getCableType().ordinal());
}
private TRPowerNet network;
public final void findAndJoinNetwork(World world, BlockPos pos) {
network = new TRPowerNet();
network.setIOLimit(this.getCableType().transferRate);
network.addElement(this);
for(EnumFacing dir : EnumFacing.VALUES){
CableMultipart cableMultipart = getPartFromWorld(getWorld(), getPos().offset(dir), dir);
if(cableMultipart != null && cableMultipart.getCableType() == getCableType()){
TRPowerNet net = cableMultipart.getNetwork();
if(net != null){
net.merge(network);
}
}
TileEntity te = getNeighbourTile(dir);
if(te != null && te instanceof IEnergyInterfaceTile){
if(((IEnergyInterfaceTile) te).canAcceptEnergy(dir) || ((IEnergyInterfaceTile) te).canProvideEnergy(dir)){
network.addConnection((IEnergyInterfaceTile) te, dir.getOpposite());
}
}
}
}
public final TRPowerNet getNetwork() {
return network;
}
public final void setNetwork(TRPowerNet n) {
if (n == null) {
} else {
network = n;
network.addElement(this);
}
}
public final void removeFromNetwork() {
if (network == null) {
} else
network.removeElement(this);
}
public final void rebuildNetwork() {
this.removeFromNetwork();
this.resetNetwork();
this.findAndJoinNetwork(getWorld(), getPos());
}
public final void resetNetwork() {
network = null;
}
}

View file

@ -0,0 +1,9 @@
package techreborn.power;
import net.minecraftforge.fml.common.eventhandler.Event;
public class PowerTickEvent extends Event {
public PowerTickEvent() {
}
}

View file

@ -0,0 +1,272 @@
package techreborn.power;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import reborncore.api.power.IEnergyInterfaceTile;
import techreborn.parts.CableMultipart;
import java.util.ArrayList;
public class TRPowerNet {
int i = 0;
private ArrayList<CableMultipart> cables = new ArrayList();
private ArrayList<EnergyHandler> endpoints = new ArrayList();
private int energy = 0;
private int networkLimit = 1000;
public TRPowerNet() {
MinecraftForge.EVENT_BUS.register(this);
}
public int getIOLimit() {
return networkLimit;
}
public void setIOLimit(int limit) {
if (networkLimit != limit) {
networkLimit = limit;
for (int i = 0; i < cables.size(); i++) {
CableMultipart cable = cables.get(i);
if (cable.getCableType().transferRate!= networkLimit) {
networkLimit = cable.getCableType().transferRate;
}
}
}
}
@SubscribeEvent
public void tick(PowerTickEvent evt) {
// if (i > 10) {
// for (CableMultipart modCablePart : ModCablePart.partsInWorld) {
// if (!ModPartUtils.hasCable(modCablePart.world, modCablePart.location)) {
// ModCablePart.partsInWorld.remove(modCablePart);
// }
// }
// }
if (!cables.isEmpty()) {
ArrayList<EnergyHandler> collectibles = new ArrayList();
ArrayList<EnergyHandler> insertibles = new ArrayList();
int maxCanPush = energy;
for (int i = 0; i < endpoints.size(); i++) {
EnergyHandler ei = endpoints.get(i);
maxCanPush += ei.getTotalInsertible();
if (ei.isCollectible()) {
collectibles.add(ei);
}
if (ei.isInsertible()) {
insertibles.add(ei);
}
}
maxCanPush = Math.min(this.getIOLimit(), maxCanPush);
for(EnergyHandler handler : collectibles){
int space = maxCanPush - energy;
energy += handler.collectEnergy(space);
}
for(EnergyHandler handler : insertibles){
int add = Math.min(energy, 1 + energy / insertibles.size());
energy -= handler.addEnergy(add);
}
System.out.println(energy);
}
}
public void addElement(CableMultipart te) {
if (!cables.contains(te)) {
cables.add(te);
if (te.getCableType().transferRate > 0 && te.getCableType().transferRate != networkLimit) {
this.setIOLimit(Math.min(te.getCableType().transferRate, this.getIOLimit()));
}
}
}
public void removeElement(CableMultipart te) {
cables.remove(te);
this.rebuild();
}
private void rebuild() {
System.out.println("Remapping RF network " + this);
for (int i = 0; i < cables.size(); i++) {
CableMultipart te = cables.get(i);
te.findAndJoinNetwork(te.getWorld(), te.getPos());
}
this.clear(true);
}
public void addConnection(IEnergyInterfaceTile ih, EnumFacing dir) {
if (ih instanceof CableMultipart)
return;
EnergyHandler has = this.getHandleFrom(ih);
if (has == null) {
endpoints.add(new EnergyHandler(ih, dir));
} else {
has.addSide(dir);
}
}
public void merge(TRPowerNet n) {
if (n != this) {
ArrayList<CableMultipart> li = new ArrayList();
for (int i = 0; i < n.cables.size(); i++) {
CableMultipart wire = n.cables.get(i);
li.add(wire);
}
for (int i = 0; i < n.endpoints.size(); i++) {
EnergyHandler ei = n.endpoints.get(i);
EnergyHandler has = this.getHandleFrom(ei.tile);
if (has == null) {
endpoints.add(ei);
} else {
has.merge(ei);
}
}
n.clear(false);
for (int i = 0; i < li.size(); i++) {
CableMultipart wire = li.get(i);
wire.setNetwork(this);
}
if (n.getIOLimit() != 0 && n.networkLimit != networkLimit)
this.setIOLimit(Math.min(n.getIOLimit(), this.getIOLimit()));
}
}
private EnergyHandler getHandleFrom(IEnergyInterfaceTile tile) {
for (int i = 0; i < endpoints.size(); i++) {
EnergyHandler ei = endpoints.get(i);
if (ei.contains(tile))
return ei;
}
return null;
}
private void clear(boolean clearTiles) {
if (clearTiles) {
for (int i = 0; i < cables.size(); i++) {
cables.get(i).resetNetwork();
}
}
cables.clear();
endpoints.clear();
energy = 0;
try {
MinecraftForge.EVENT_BUS.unregister(this);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return cables.size() + ": " + endpoints.toString();
}
public int drainEnergy(int maxReceive, boolean simulate) {
maxReceive = Math.min(maxReceive, this.getIOLimit());
int drain = Math.min(maxReceive, energy);
if (!simulate)
energy -= drain;
return drain;
}
public int addEnergy(int maxAdd, boolean simulate) {
if (energy >= this.getIOLimit())
return 0;
maxAdd = Math.min(this.getIOLimit(), maxAdd);
if (!simulate)
energy += maxAdd;
return maxAdd;
}
private static class EnergyHandler {
private final IEnergyInterfaceTile tile;
private final ArrayList<EnumFacing> sides = new ArrayList();
private EnergyHandler(IEnergyInterfaceTile ih, EnumFacing... dirs) {
tile = ih;
for (int i = 0; i < dirs.length; i++) {
this.addSide(dirs[i]);
}
}
public boolean isInsertible() {
return this.getTotalInsertible() > 0;
}
public boolean isCollectible() {
return this.getTotalCollectible() > 0;
}
public boolean contains(IEnergyInterfaceTile tile) {
return tile == this.tile;
}
public void addSide(EnumFacing dir) {
if (!sides.contains(dir))
sides.add(dir);
}
public void merge(EnergyHandler ei) {
for (int i = 0; i < ei.sides.size(); i++) {
this.addSide(ei.sides.get(i));
}
}
public int collectEnergy(int max) {
int total = 0;
for (int i = 0; i < sides.size(); i++) {
EnumFacing dir = sides.get(i);
if (tile.canProvideEnergy(dir)) {
int collect = max - total;
total += tile.useEnergy(collect, false);
}
}
return total;
}
public int addEnergy(int max) {
int total = 0;
for (int i = 0; i < sides.size(); i++) {
EnumFacing dir = sides.get(i);
if (tile.canAcceptEnergy(dir)) {
int add = max - total;
total += tile.addEnergy(add, false);
}
}
return total;
}
public int getTotalCollectible() {
int total = 0;
for (int i = 0; i < sides.size(); i++) {
EnumFacing dir = sides.get(i);
if (tile.canProvideEnergy(dir)) {
total += tile.useEnergy(Integer.MAX_VALUE, true);
}
}
return total;
}
public int getTotalInsertible() {
int total = 0;
for (int i = 0; i < sides.size(); i++) {
EnumFacing dir = sides.get(i);
if (tile.canAcceptEnergy(dir)) {
total += tile.addEnergy(Integer.MAX_VALUE, true);
}
}
return total;
}
@Override
public String toString() {
return tile + " @ " + sides;
}
}
}