diff --git a/core/Registration.java b/core/Registration.java index 0b4c3d54..6708eab9 100644 --- a/core/Registration.java +++ b/core/Registration.java @@ -464,6 +464,7 @@ public class Registration 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.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" ); FMLCommonHandler.instance().bus().register( TickHandler.instance ); @@ -600,7 +601,7 @@ public class Registration mr.whiteListTileEntity( net.minecraft.tileentity.TileEntityHopper.class ); /** - * Whitelist AE + * Whitelist AE2 */ mr.whiteListTileEntity( AEBaseTile.class ); diff --git a/core/features/AEFeature.java b/core/features/AEFeature.java index e94732fb..7ce99846 100644 --- a/core/features/AEFeature.java +++ b/core/features/AEFeature.java @@ -41,8 +41,8 @@ public enum AEFeature DenseEnergyCells("HigherCapacity"), DenseCables("HigherCapacity"), - P2PTunnelME("P2PTunnels"), P2PTunnelItems("P2PTunnels"), P2PTunnelRedstone("P2PTunnels"), P2PTunnelEU("P2PTunnels"), P2PTunnelMJ("P2PTunnels"), P2PTunnelLiquids( - "P2PTunnels"), + P2PTunnelRF("P2PTunnels"), P2PTunnelME("P2PTunnels"), P2PTunnelItems("P2PTunnels"), P2PTunnelRedstone("P2PTunnels"), P2PTunnelEU("P2PTunnels"), P2PTunnelMJ( + "P2PTunnels"), P2PTunnelLiquids("P2PTunnels"), MassCannonBlockDamage("BlockFeatures"), TinyTNTBlockDamage("BlockFeatures"), Facades("Facades"), diff --git a/core/localization/GuiText.java b/core/localization/GuiText.java index 64696dae..36e0a245 100644 --- a/core/localization/GuiText.java +++ b/core/localization/GuiText.java @@ -26,7 +26,7 @@ public enum GuiText 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; diff --git a/integration/modules/helpers/NullRFHandler.java b/integration/modules/helpers/NullRFHandler.java new file mode 100644 index 00000000..d0249d65 --- /dev/null +++ b/integration/modules/helpers/NullRFHandler.java @@ -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; + } + +} diff --git a/items/parts/PartType.java b/items/parts/PartType.java index 1e3f56ab..c48a2344 100644 --- a/items/parts/PartType.java +++ b/items/parts/PartType.java @@ -25,6 +25,7 @@ import appeng.parts.p2p.PartP2PBCPower; import appeng.parts.p2p.PartP2PIC2Power; import appeng.parts.p2p.PartP2PItems; import appeng.parts.p2p.PartP2PLiquids; +import appeng.parts.p2p.PartP2PRFPower; import appeng.parts.p2p.PartP2PRedstone; import appeng.parts.p2p.PartP2PTunnelME; import appeng.parts.reporting.PartConversionMonitor; @@ -92,7 +93,9 @@ public enum PartType 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 features; private final Class myPart; diff --git a/me/storage/NetworkInventoryHandler.java b/me/storage/NetworkInventoryHandler.java index fc20055f..cd437446 100644 --- a/me/storage/NetworkInventoryHandler.java +++ b/me/storage/NetworkInventoryHandler.java @@ -59,20 +59,31 @@ public class NetworkInventoryHandler> implements IMEInvent static int currentPass = 0; int myPass = 0; - final static public LinkedList depth = new LinkedList(); + static final ThreadLocal depth = new ThreadLocal(); + + private LinkedList getDepth() + { + LinkedList s = depth.get(); + + if ( s == null ) + depth.set( s = new LinkedList() ); + + return s; + } private boolean diveList(NetworkInventoryHandler networkInventoryHandler) { - if ( depth.contains( networkInventoryHandler ) ) + LinkedList cDepth = getDepth(); + if ( cDepth.contains( networkInventoryHandler ) ) return true; - depth.push( this ); + cDepth.push( this ); return false; } private boolean diveIteration(NetworkInventoryHandler networkInventoryHandler) { - if ( depth.isEmpty() ) + if ( getDepth().isEmpty() ) { currentPass++; myPass = currentPass; @@ -85,14 +96,13 @@ public class NetworkInventoryHandler> implements IMEInvent myPass = currentPass; } - depth.push( this ); + getDepth().push( this ); return false; } private void surface(NetworkInventoryHandler networkInventoryHandler) { - Object last = depth.pop(); - if ( last != this ) + if ( getDepth().pop() != this ) throw new RuntimeException( "Invalid Access to Networked Storage API detected." ); } diff --git a/parts/p2p/PartP2PRFPower.java b/parts/p2p/PartP2PRFPower.java new file mode 100644 index 00000000..f154a660 --- /dev/null +++ b/parts/p2p/PartP2PRFPower.java @@ -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 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> depth = new ThreadLocal>(); + + private Stack getDepth() + { + Stack s = depth.get(); + + if ( s == null ) + depth.set( s = new Stack() ); + + return s; + } + + @Override + public int receiveEnergy(ForgeDirection from, int maxReceive, boolean simulate) + { + if ( output ) + return 0; + + if ( isActive() ) + { + Stack 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 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 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; + } +} diff --git a/parts/p2p/PartP2PTunnel.java b/parts/p2p/PartP2PTunnel.java index ac3c370a..dc9626b0 100644 --- a/parts/p2p/PartP2PTunnel.java +++ b/parts/p2p/PartP2PTunnel.java @@ -118,6 +118,10 @@ public class PartP2PTunnel extends PartBasicState switch (tt) { + case RF_POWER: + newType = AEApi.instance().parts().partP2PTunnelRF.stack( 1 ); + break; + case BC_POWER: newType = AEApi.instance().parts().partP2PTunnelMJ.stack( 1 ); break;