Added P2P RF Tunnel.

Added Added thread local for network recursion for later ( 1.8 ).
This commit is contained in:
AlgorithmX2 2014-05-02 00:00:14 -05:00
parent 5bacb015e5
commit cd5e4caf7b
8 changed files with 317 additions and 12 deletions

View file

@ -464,6 +464,7 @@ public class Registration
ph.registerNewLayer( "appeng.api.parts.layers.LayerIPowerEmitter", "buildcraft.api.power.IPowerEmitter" ); ph.registerNewLayer( "appeng.api.parts.layers.LayerIPowerEmitter", "buildcraft.api.power.IPowerEmitter" );
ph.registerNewLayer( "appeng.api.parts.layers.LayerIPowerReceptor", "buildcraft.api.power.IPowerReceptor" ); ph.registerNewLayer( "appeng.api.parts.layers.LayerIPowerReceptor", "buildcraft.api.power.IPowerReceptor" );
ph.registerNewLayer( "appeng.api.parts.layers.LayerIFluidHandler", "net.minecraftforge.fluids.IFluidHandler" ); ph.registerNewLayer( "appeng.api.parts.layers.LayerIFluidHandler", "net.minecraftforge.fluids.IFluidHandler" );
ph.registerNewLayer( "appeng.api.parts.layers.LayerIEnergyHandler", "cofh.api.energy.IEnergyHandler" );
ph.registerNewLayer( "appeng.api.parts.layers.LayerITileStorageMonitorable", "appeng.api.implementations.tiles.ITileStorageMonitorable" ); ph.registerNewLayer( "appeng.api.parts.layers.LayerITileStorageMonitorable", "appeng.api.implementations.tiles.ITileStorageMonitorable" );
FMLCommonHandler.instance().bus().register( TickHandler.instance ); FMLCommonHandler.instance().bus().register( TickHandler.instance );
@ -600,7 +601,7 @@ public class Registration
mr.whiteListTileEntity( net.minecraft.tileentity.TileEntityHopper.class ); mr.whiteListTileEntity( net.minecraft.tileentity.TileEntityHopper.class );
/** /**
* Whitelist AE * Whitelist AE2
*/ */
mr.whiteListTileEntity( AEBaseTile.class ); mr.whiteListTileEntity( AEBaseTile.class );

View file

@ -41,8 +41,8 @@ public enum AEFeature
DenseEnergyCells("HigherCapacity"), DenseCables("HigherCapacity"), DenseEnergyCells("HigherCapacity"), DenseCables("HigherCapacity"),
P2PTunnelME("P2PTunnels"), P2PTunnelItems("P2PTunnels"), P2PTunnelRedstone("P2PTunnels"), P2PTunnelEU("P2PTunnels"), P2PTunnelMJ("P2PTunnels"), P2PTunnelLiquids( P2PTunnelRF("P2PTunnels"), P2PTunnelME("P2PTunnels"), P2PTunnelItems("P2PTunnels"), P2PTunnelRedstone("P2PTunnels"), P2PTunnelEU("P2PTunnels"), P2PTunnelMJ(
"P2PTunnels"), "P2PTunnels"), P2PTunnelLiquids("P2PTunnels"),
MassCannonBlockDamage("BlockFeatures"), TinyTNTBlockDamage("BlockFeatures"), Facades("Facades"), MassCannonBlockDamage("BlockFeatures"), TinyTNTBlockDamage("BlockFeatures"), Facades("Facades"),

View file

@ -26,7 +26,7 @@ public enum GuiText
METunnel, ItemTunnel, RedstoneTunnel, MJTunnel, EUTunnel, FluidTunnel, StoredSize, METunnel, ItemTunnel, RedstoneTunnel, MJTunnel, EUTunnel, FluidTunnel, StoredSize,
StoredPower, MaxPower, RequiredPower, Efficiency, InWorldCrafting, inWorldFluix, inWorldPurification, inWorldSingularity, OfSecondOutput, NoSecondOutput; StoredPower, MaxPower, RequiredPower, Efficiency, InWorldCrafting, inWorldFluix, inWorldPurification, inWorldSingularity, OfSecondOutput, NoSecondOutput, RFTunnel;
String root; String root;

View file

@ -0,0 +1,38 @@
package appeng.integration.modules.helpers;
import net.minecraftforge.common.util.ForgeDirection;
import cofh.api.energy.IEnergyHandler;
public class NullRFHandler implements IEnergyHandler
{
@Override
public int receiveEnergy(ForgeDirection from, int maxReceive, boolean simulate)
{
return 0;
}
@Override
public int extractEnergy(ForgeDirection from, int maxExtract, boolean simulate)
{
return 0;
}
@Override
public boolean canInterface(ForgeDirection from)
{
return true;
}
@Override
public int getEnergyStored(ForgeDirection from)
{
return 0;
}
@Override
public int getMaxEnergyStored(ForgeDirection from)
{
return 0;
}
}

View file

@ -25,6 +25,7 @@ import appeng.parts.p2p.PartP2PBCPower;
import appeng.parts.p2p.PartP2PIC2Power; import appeng.parts.p2p.PartP2PIC2Power;
import appeng.parts.p2p.PartP2PItems; import appeng.parts.p2p.PartP2PItems;
import appeng.parts.p2p.PartP2PLiquids; import appeng.parts.p2p.PartP2PLiquids;
import appeng.parts.p2p.PartP2PRFPower;
import appeng.parts.p2p.PartP2PRedstone; import appeng.parts.p2p.PartP2PRedstone;
import appeng.parts.p2p.PartP2PTunnelME; import appeng.parts.p2p.PartP2PTunnelME;
import appeng.parts.reporting.PartConversionMonitor; import appeng.parts.reporting.PartConversionMonitor;
@ -92,7 +93,9 @@ public enum PartType
ConversionMonitor(AEFeature.PartConversionMonitor, PartConversionMonitor.class), ConversionMonitor(AEFeature.PartConversionMonitor, PartConversionMonitor.class),
Interface(AEFeature.Core, PartInterface.class); Interface(AEFeature.Core, PartInterface.class),
P2PTunnelRF(AEFeature.P2PTunnelRF, PartP2PRFPower.class, GuiText.RFTunnel);
private final EnumSet<AEFeature> features; private final EnumSet<AEFeature> features;
private final Class<? extends IPart> myPart; private final Class<? extends IPart> myPart;

View file

@ -59,20 +59,31 @@ public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInvent
static int currentPass = 0; static int currentPass = 0;
int myPass = 0; int myPass = 0;
final static public LinkedList depth = new LinkedList(); static final ThreadLocal<LinkedList> depth = new ThreadLocal<LinkedList>();
private LinkedList getDepth()
{
LinkedList s = depth.get();
if ( s == null )
depth.set( s = new LinkedList() );
return s;
}
private boolean diveList(NetworkInventoryHandler<T> networkInventoryHandler) private boolean diveList(NetworkInventoryHandler<T> networkInventoryHandler)
{ {
if ( depth.contains( networkInventoryHandler ) ) LinkedList cDepth = getDepth();
if ( cDepth.contains( networkInventoryHandler ) )
return true; return true;
depth.push( this ); cDepth.push( this );
return false; return false;
} }
private boolean diveIteration(NetworkInventoryHandler<T> networkInventoryHandler) private boolean diveIteration(NetworkInventoryHandler<T> networkInventoryHandler)
{ {
if ( depth.isEmpty() ) if ( getDepth().isEmpty() )
{ {
currentPass++; currentPass++;
myPass = currentPass; myPass = currentPass;
@ -85,14 +96,13 @@ public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInvent
myPass = currentPass; myPass = currentPass;
} }
depth.push( this ); getDepth().push( this );
return false; return false;
} }
private void surface(NetworkInventoryHandler<T> networkInventoryHandler) private void surface(NetworkInventoryHandler<T> networkInventoryHandler)
{ {
Object last = depth.pop(); if ( getDepth().pop() != this )
if ( last != this )
throw new RuntimeException( "Invalid Access to Networked Storage API detected." ); throw new RuntimeException( "Invalid Access to Networked Storage API detected." );
} }

View file

@ -0,0 +1,249 @@
package appeng.parts.p2p;
import java.util.Stack;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.IIcon;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.config.TunnelType;
import appeng.core.AppEng;
import appeng.integration.modules.helpers.NullRFHandler;
import appeng.me.GridAccessException;
import appeng.transformer.annotations.integration.Interface;
import appeng.transformer.annotations.integration.InterfaceList;
import appeng.util.Platform;
import cofh.api.energy.IEnergyHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@InterfaceList(value = { @Interface(iface = "cofh.api.energy.IEnergyHandler", iname = "RF") })
public class PartP2PRFPower extends PartP2PTunnel<PartP2PRFPower> implements cofh.api.energy.IEnergyHandler
{
private static final IEnergyHandler myNullHandler = new NullRFHandler();
boolean cachedTarget = false;
IEnergyHandler outputTarget;
public TunnelType getTunnelType()
{
return TunnelType.RF_POWER;
}
public PartP2PRFPower(ItemStack is) {
super( is );
if ( !AppEng.instance.isIntegrationEnabled( "RF" ) )
throw new RuntimeException( "RF Not installed!" );
}
@Override
public void writeToNBT(NBTTagCompound tag)
{
super.writeToNBT( tag );
}
@Override
public void readFromNBT(NBTTagCompound tag)
{
super.readFromNBT( tag );
}
@Override
public void onNeighborChanged()
{
super.onNeighborChanged();
cachedTarget = false;
}
@SideOnly(Side.CLIENT)
public IIcon getTypeTexture()
{
return Blocks.iron_block.getBlockTextureFromSide( 0 );
}
@Override
public void onChange()
{
getHost().partChanged();
}
public float getPowerDrainPerTick()
{
return 0.5f;
}
static final ThreadLocal<Stack<PartP2PRFPower>> depth = new ThreadLocal<Stack<PartP2PRFPower>>();
private Stack<PartP2PRFPower> getDepth()
{
Stack<PartP2PRFPower> s = depth.get();
if ( s == null )
depth.set( s = new Stack<PartP2PRFPower>() );
return s;
}
@Override
public int receiveEnergy(ForgeDirection from, int maxReceive, boolean simulate)
{
if ( output )
return 0;
if ( isActive() )
{
Stack<PartP2PRFPower> stack = getDepth();
for (PartP2PRFPower t : stack)
if ( t == this )
return 0;
stack.push( this );
int total = 0;
try
{
for (PartP2PRFPower t : getOutputs())
{
if ( Platform.getRandomInt() % 2 > 0 )
{
int recv = t.getOutput().receiveEnergy( t.side.getOpposite(), maxReceive, simulate );
maxReceive -= recv;
total += recv;
if ( maxReceive <= 0 )
break;
}
}
if ( maxReceive > 0 )
{
for (PartP2PRFPower t : getOutputs())
{
int recv = t.getOutput().receiveEnergy( t.side.getOpposite(), maxReceive, simulate );
maxReceive -= recv;
total += recv;
if ( maxReceive <= 0 )
break;
}
}
}
catch (GridAccessException e)
{
}
if ( stack.pop() != this )
throw new RuntimeException( "Invalid Recursion detected." );
return total;
}
return 0;
}
@Override
public int extractEnergy(ForgeDirection from, int maxExtract, boolean simulate)
{
return 0;
}
@Override
public boolean canInterface(ForgeDirection from)
{
return true;
}
@Override
public int getEnergyStored(ForgeDirection from)
{
if ( output || !isActive() )
return 0;
int total = 0;
Stack<PartP2PRFPower> stack = getDepth();
for (PartP2PRFPower t : stack)
if ( t == this )
return 0;
stack.push( this );
try
{
for (PartP2PRFPower t : getOutputs())
{
total += t.getOutput().getEnergyStored( t.side.getOpposite() );
}
}
catch (GridAccessException e)
{
return 0;
}
if ( stack.pop() != this )
throw new RuntimeException( "Invalid Recursion detected." );
return total;
}
@Override
public int getMaxEnergyStored(ForgeDirection from)
{
if ( output || !isActive() )
return 0;
int total = 0;
Stack<PartP2PRFPower> stack = getDepth();
for (PartP2PRFPower t : stack)
if ( t == this )
return 0;
stack.push( this );
try
{
for (PartP2PRFPower t : getOutputs())
{
total += t.getOutput().getMaxEnergyStored( t.side.getOpposite() );
}
}
catch (GridAccessException e)
{
return 0;
}
if ( stack.pop() != this )
throw new RuntimeException( "Invalid Recursion detected." );
return total;
}
private IEnergyHandler getOutput()
{
if ( output )
{
if ( !cachedTarget )
{
TileEntity self = getTile();
TileEntity te = self.getWorldObj().getTileEntity( self.xCoord + side.offsetX, self.yCoord + side.offsetY, self.zCoord + side.offsetZ );
outputTarget = te instanceof IEnergyHandler ? (IEnergyHandler) te : null;
cachedTarget = true;
}
if ( outputTarget == null )
return myNullHandler;
return outputTarget;
}
return myNullHandler;
}
}

View file

@ -118,6 +118,10 @@ public class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicState
switch (tt) switch (tt)
{ {
case RF_POWER:
newType = AEApi.instance().parts().partP2PTunnelRF.stack( 1 );
break;
case BC_POWER: case BC_POWER:
newType = AEApi.instance().parts().partP2PTunnelMJ.stack( 1 ); newType = AEApi.instance().parts().partP2PTunnelMJ.stack( 1 );
break; break;