Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e0bf7223e0 | |||
| ba9af94228 | |||
| 122b6163dc | |||
| fab42ccc75 | |||
| f5dd2c8b0a | |||
| a126112a2d | |||
| 99cda5f5a3 | |||
| 56a5363528 | |||
| be65edbd5b | |||
| fe5d9251eb | |||
| 3cf48b2291 |
@@ -23,7 +23,6 @@ import java.text.NumberFormat;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import net.minecraft.client.util.ITooltipFlag;
|
|
||||||
import net.minecraft.inventory.Container;
|
import net.minecraft.inventory.Container;
|
||||||
import net.minecraft.inventory.Slot;
|
import net.minecraft.inventory.Slot;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
@@ -43,70 +42,17 @@ public abstract class AEBaseMEGui extends AEBaseGui
|
|||||||
super( container );
|
super( container );
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> handleItemTooltip( final ItemStack stack, final int mouseX, final int mouseY, final List<String> currentToolTip )
|
|
||||||
{
|
|
||||||
if( !stack.isEmpty() )
|
|
||||||
{
|
|
||||||
final Slot s = this.getSlot( mouseX, mouseY );
|
|
||||||
if( s instanceof SlotME )
|
|
||||||
{
|
|
||||||
final int BigNumber = AEConfig.instance().useTerminalUseLargeFont() ? 999 : 9999;
|
|
||||||
|
|
||||||
IAEItemStack myStack = null;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
final SlotME theSlotField = (SlotME) s;
|
|
||||||
myStack = theSlotField.getAEStack();
|
|
||||||
}
|
|
||||||
catch( final Throwable ignore )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
if( myStack != null )
|
|
||||||
{
|
|
||||||
if( myStack.getStackSize() > BigNumber || ( myStack.getStackSize() > 1 && stack.isItemDamaged() ) )
|
|
||||||
{
|
|
||||||
final String local = ButtonToolTips.ItemsStored.getLocal();
|
|
||||||
final String formattedAmount = NumberFormat.getNumberInstance( Locale.US ).format( myStack.getStackSize() );
|
|
||||||
final String format = String.format( local, formattedAmount );
|
|
||||||
|
|
||||||
currentToolTip.add( TextFormatting.GRAY + format );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( myStack.getCountRequestable() > 0 )
|
|
||||||
{
|
|
||||||
final String local = ButtonToolTips.ItemsRequestable.getLocal();
|
|
||||||
final String formattedAmount = NumberFormat.getNumberInstance( Locale.US ).format( myStack.getCountRequestable() );
|
|
||||||
final String format = String.format( local, formattedAmount );
|
|
||||||
|
|
||||||
currentToolTip.add( TextFormatting.GRAY + format );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if( stack.getCount() > BigNumber || ( stack.getCount() > 1 && stack.isItemDamaged() ) )
|
|
||||||
{
|
|
||||||
final String local = ButtonToolTips.ItemsStored.getLocal();
|
|
||||||
final String formattedAmount = NumberFormat.getNumberInstance( Locale.US ).format( stack.getCount() );
|
|
||||||
final String format = String.format( local, formattedAmount );
|
|
||||||
|
|
||||||
currentToolTip.add( TextFormatting.GRAY + format );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return currentToolTip;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vanilla version...
|
|
||||||
// protected void drawItemStackTooltip(ItemStack stack, int x, int y)
|
|
||||||
@Override
|
@Override
|
||||||
protected void renderToolTip( final ItemStack stack, final int x, final int y )
|
protected void renderToolTip( final ItemStack stack, final int x, final int y )
|
||||||
{
|
{
|
||||||
final Slot s = this.getSlot( x, y );
|
final Slot s = this.getSlot( x, y );
|
||||||
|
|
||||||
if( s instanceof SlotME && !stack.isEmpty() )
|
if( s instanceof SlotME && !stack.isEmpty() )
|
||||||
{
|
{
|
||||||
final int BigNumber = AEConfig.instance().useTerminalUseLargeFont() ? 999 : 9999;
|
final int bigNumber = AEConfig.instance().useTerminalUseLargeFont() ? 999 : 9999;
|
||||||
|
|
||||||
IAEItemStack myStack = null;
|
IAEItemStack myStack = null;
|
||||||
|
final List<String> currentToolTip = this.getItemToolTip( stack );
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -117,33 +63,44 @@ public abstract class AEBaseMEGui extends AEBaseGui
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ITooltipFlag.TooltipFlags tooltipFlag = this.mc.gameSettings.advancedItemTooltips ? ITooltipFlag.TooltipFlags.ADVANCED : ITooltipFlag.TooltipFlags.NORMAL;
|
|
||||||
if( myStack != null )
|
if( myStack != null )
|
||||||
{
|
{
|
||||||
final List<String> currentToolTip = stack.getTooltip( this.mc.player, tooltipFlag );
|
if( myStack.getStackSize() > bigNumber || ( myStack.getStackSize() > 1 && stack.isItemDamaged() ) )
|
||||||
|
|
||||||
if( myStack.getStackSize() > BigNumber || ( myStack.getStackSize() > 1 && stack.isItemDamaged() ) )
|
|
||||||
{
|
{
|
||||||
currentToolTip.add( "Items Stored: " + NumberFormat.getNumberInstance( Locale.US ).format( myStack.getStackSize() ) );
|
final String local = ButtonToolTips.ItemsStored.getLocal();
|
||||||
|
final String formattedAmount = NumberFormat.getNumberInstance( Locale.US ).format( myStack.getStackSize() );
|
||||||
|
final String format = String.format( local, formattedAmount );
|
||||||
|
|
||||||
|
currentToolTip.add( TextFormatting.GRAY + format );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( myStack.getCountRequestable() > 0 )
|
if( myStack.getCountRequestable() > 0 )
|
||||||
{
|
{
|
||||||
currentToolTip.add( "Items Requestable: " + NumberFormat.getNumberInstance( Locale.US ).format( myStack.getCountRequestable() ) );
|
final String local = ButtonToolTips.ItemsRequestable.getLocal();
|
||||||
|
final String formattedAmount = NumberFormat.getNumberInstance( Locale.US ).format( myStack.getCountRequestable() );
|
||||||
|
final String format = String.format( local, formattedAmount );
|
||||||
|
|
||||||
|
currentToolTip.add( format );
|
||||||
}
|
}
|
||||||
|
|
||||||
this.drawTooltip( x, y, currentToolTip );
|
this.drawHoveringText( currentToolTip, x, y, this.fontRenderer );
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if( stack.getCount() > BigNumber )
|
else if( stack.getCount() > bigNumber )
|
||||||
{
|
{
|
||||||
List<String> var4 = stack.getTooltip( this.mc.player, tooltipFlag );
|
final String local = ButtonToolTips.ItemsStored.getLocal();
|
||||||
var4.add( "Items Stored: " + NumberFormat.getNumberInstance( Locale.US ).format( stack.getCount() ) );
|
final String formattedAmount = NumberFormat.getNumberInstance( Locale.US ).format( stack.getCount() );
|
||||||
this.drawTooltip( x, y, var4 );
|
final String format = String.format( local, formattedAmount );
|
||||||
|
|
||||||
|
currentToolTip.add( TextFormatting.GRAY + format );
|
||||||
|
|
||||||
|
this.drawHoveringText( currentToolTip, x, y, this.fontRenderer );
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.renderToolTip( stack, x, y );
|
super.renderToolTip( stack, x, y );
|
||||||
// super.drawItemStackTooltip( stack, x, y );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,10 +237,11 @@ public class GuiNetworkStatus extends AEBaseGui implements ISortSource
|
|||||||
this.getScrollBar().setRange( 0, ( size + 4 ) / 5 - this.rows, 1 );
|
this.getScrollBar().setRange( 0, ( size + 4 ) / 5 - this.rows, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vanilla version...
|
@Override
|
||||||
protected void drawItemStackTooltip( final ItemStack stack, final int x, final int y )
|
protected void renderToolTip( final ItemStack stack, final int x, final int y )
|
||||||
{
|
{
|
||||||
final Slot s = this.getSlot( x, y );
|
final Slot s = this.getSlot( x, y );
|
||||||
|
|
||||||
if( s instanceof SlotME && stack != null )
|
if( s instanceof SlotME && stack != null )
|
||||||
{
|
{
|
||||||
IAEItemStack myStack = null;
|
IAEItemStack myStack = null;
|
||||||
@@ -270,7 +271,8 @@ public class GuiNetworkStatus extends AEBaseGui implements ISortSource
|
|||||||
this.drawTooltip( x, y, currentToolTip );
|
this.drawTooltip( x, y, currentToolTip );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// super.drawItemStackTooltip( stack, x, y );
|
|
||||||
|
super.renderToolTip( stack, x, y );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ public class ApiGrid implements IGridHelper
|
|||||||
Preconditions.checkNotNull( a );
|
Preconditions.checkNotNull( a );
|
||||||
Preconditions.checkNotNull( b );
|
Preconditions.checkNotNull( b );
|
||||||
|
|
||||||
return new GridConnection( a, b, AEPartLocation.INTERNAL );
|
return GridConnection.create( a, b, AEPartLocation.INTERNAL );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import appeng.api.config.Actionable;
|
|||||||
import appeng.api.config.SecurityPermissions;
|
import appeng.api.config.SecurityPermissions;
|
||||||
import appeng.api.networking.IGrid;
|
import appeng.api.networking.IGrid;
|
||||||
import appeng.api.networking.IGridNode;
|
import appeng.api.networking.IGridNode;
|
||||||
|
import appeng.api.networking.crafting.ICraftingGrid;
|
||||||
import appeng.api.networking.energy.IEnergyGrid;
|
import appeng.api.networking.energy.IEnergyGrid;
|
||||||
import appeng.api.networking.security.ISecurityGrid;
|
import appeng.api.networking.security.ISecurityGrid;
|
||||||
import appeng.api.networking.storage.IStorageGrid;
|
import appeng.api.networking.storage.IStorageGrid;
|
||||||
@@ -132,6 +133,7 @@ public class PacketJEIRecipe extends AppEngPacket
|
|||||||
final IStorageGrid inv = grid.getCache( IStorageGrid.class );
|
final IStorageGrid inv = grid.getCache( IStorageGrid.class );
|
||||||
final IEnergyGrid energy = grid.getCache( IEnergyGrid.class );
|
final IEnergyGrid energy = grid.getCache( IEnergyGrid.class );
|
||||||
final ISecurityGrid security = grid.getCache( ISecurityGrid.class );
|
final ISecurityGrid security = grid.getCache( ISecurityGrid.class );
|
||||||
|
final ICraftingGrid crafting = grid.getCache( ICraftingGrid.class );
|
||||||
final IItemHandler craftMatrix = cct.getInventoryByName( "crafting" );
|
final IItemHandler craftMatrix = cct.getInventoryByName( "crafting" );
|
||||||
final IItemHandler playerInventory = cct.getInventoryByName( "player" );
|
final IItemHandler playerInventory = cct.getInventoryByName( "player" );
|
||||||
|
|
||||||
@@ -179,13 +181,23 @@ public class PacketJEIRecipe extends AppEngPacket
|
|||||||
{
|
{
|
||||||
request.setStackSize( 1 );
|
request.setStackSize( 1 );
|
||||||
IAEItemStack out;
|
IAEItemStack out;
|
||||||
|
|
||||||
if( cct.useRealItems() )
|
if( cct.useRealItems() )
|
||||||
{
|
{
|
||||||
out = Platform.poweredExtraction( energy, storage, request, cct.getActionSource() );
|
out = Platform.poweredExtraction( energy, storage, request, cct.getActionSource() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
out = storage.extractItems( request, Actionable.SIMULATE, cct.getActionSource() );
|
// Query the crafting grid if there is a pattern providing the item
|
||||||
|
if( !crafting.getCraftingFor( request, null, 0, null ).isEmpty() )
|
||||||
|
{
|
||||||
|
out = request;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Fall back using an existing item
|
||||||
|
out = storage.extractItems( request, Actionable.SIMULATE, cct.getActionSource() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( out != null )
|
if( out != null )
|
||||||
|
|||||||
@@ -363,7 +363,7 @@ public class CraftingTreeNode
|
|||||||
|
|
||||||
if( this.howManyEmitted > 0 )
|
if( this.howManyEmitted > 0 )
|
||||||
{
|
{
|
||||||
final IAEItemStack i = this.what.copy();
|
final IAEItemStack i = this.what.copy().reset();
|
||||||
i.setStackSize( this.howManyEmitted );
|
i.setStackSize( this.howManyEmitted );
|
||||||
craftingCPUCluster.addEmitable( i );
|
craftingCPUCluster.addEmitable( i );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,13 +54,12 @@ public class NetworkToolViewer implements INetworkTool, IAEAppEngInventory
|
|||||||
@Override
|
@Override
|
||||||
public void saveChanges()
|
public void saveChanges()
|
||||||
{
|
{
|
||||||
this.inv.markDirty( -1 );
|
this.inv.writeToNBT( Platform.openNbtData( this.is ), "inv" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChangeInventory( IItemHandler inv, int slot, InvOperation mc, ItemStack removedStack, ItemStack newStack )
|
public void onChangeInventory( IItemHandler inv, int slot, InvOperation mc, ItemStack removedStack, ItemStack newStack )
|
||||||
{
|
{
|
||||||
this.inv.writeToNBT( Platform.openNbtData( this.is ), "inv" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -54,80 +54,11 @@ public class GridConnection implements IGridConnection, IPathItem
|
|||||||
private AEPartLocation fromAtoB;
|
private AEPartLocation fromAtoB;
|
||||||
private GridNode sideB;
|
private GridNode sideB;
|
||||||
|
|
||||||
public GridConnection( final IGridNode aNode, final IGridNode bNode, final AEPartLocation fromAtoB ) throws FailedConnectionException
|
private GridConnection( final GridNode aNode, final GridNode bNode, final AEPartLocation fromAtoB )
|
||||||
{
|
{
|
||||||
|
this.sideA = aNode;
|
||||||
final GridNode a = (GridNode) aNode;
|
|
||||||
final GridNode b = (GridNode) bNode;
|
|
||||||
|
|
||||||
if( Platform.securityCheck( a, b ) )
|
|
||||||
{
|
|
||||||
if( AEConfig.instance().isFeatureEnabled( AEFeature.LOG_SECURITY_AUDITS ) )
|
|
||||||
{
|
|
||||||
final DimensionalCoord aCoordinates = a.getGridBlock().getLocation();
|
|
||||||
final DimensionalCoord bCoordinates = b.getGridBlock().getLocation();
|
|
||||||
|
|
||||||
AELog.info( "Security audit 1 failed at [%s] belonging to player [id=%d]", aCoordinates.toString(), a.getPlayerID() );
|
|
||||||
AELog.info( "Security audit 2 failed at [%s] belonging to player [id=%d]", bCoordinates.toString(), b.getPlayerID() );
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new SecurityConnectionException();
|
|
||||||
}
|
|
||||||
|
|
||||||
if( a == null || b == null )
|
|
||||||
{
|
|
||||||
throw new NullNodeConnectionException();
|
|
||||||
}
|
|
||||||
|
|
||||||
if( a.hasConnection( b ) || b.hasConnection( a ) )
|
|
||||||
{
|
|
||||||
final String aMachineClass = a.getGridBlock().getMachine().getClass().getSimpleName();
|
|
||||||
final String bMachineClass = b.getGridBlock().getMachine().getClass().getSimpleName();
|
|
||||||
final String aCoordinates = a.getGridBlock().getLocation().toString();
|
|
||||||
final String bCoordinates = b.getGridBlock().getLocation().toString();
|
|
||||||
|
|
||||||
throw new ExistingConnectionException( String.format( EXISTING_CONNECTION_MESSAGE, aMachineClass, aCoordinates, bMachineClass, bCoordinates,
|
|
||||||
fromAtoB ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
this.sideA = a;
|
|
||||||
this.fromAtoB = fromAtoB;
|
this.fromAtoB = fromAtoB;
|
||||||
this.sideB = b;
|
this.sideB = bNode;
|
||||||
|
|
||||||
if( b.getMyGrid() == null )
|
|
||||||
{
|
|
||||||
b.setGrid( a.getInternalGrid() );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( a.getMyGrid() == null )
|
|
||||||
{
|
|
||||||
final GridPropagator gp = new GridPropagator( b.getInternalGrid() );
|
|
||||||
a.beginVisit( gp );
|
|
||||||
}
|
|
||||||
else if( b.getMyGrid() == null )
|
|
||||||
{
|
|
||||||
final GridPropagator gp = new GridPropagator( a.getInternalGrid() );
|
|
||||||
b.beginVisit( gp );
|
|
||||||
}
|
|
||||||
else if( this.isNetworkABetter( a, b ) )
|
|
||||||
{
|
|
||||||
final GridPropagator gp = new GridPropagator( a.getInternalGrid() );
|
|
||||||
b.beginVisit( gp );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
final GridPropagator gp = new GridPropagator( b.getInternalGrid() );
|
|
||||||
a.beginVisit( gp );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// a connection was destroyed RE-PATH!!
|
|
||||||
final IPathingGrid p = this.sideA.getInternalGrid().getCache( IPathingGrid.class );
|
|
||||||
p.repath();
|
|
||||||
|
|
||||||
this.sideA.addConnection( this );
|
|
||||||
this.sideB.addConnection( this );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isNetworkABetter( final GridNode a, final GridNode b )
|
private boolean isNetworkABetter( final GridNode a, final GridNode b )
|
||||||
@@ -291,4 +222,81 @@ public class GridConnection implements IGridConnection, IPathItem
|
|||||||
{
|
{
|
||||||
this.visitorIterationNumber = visitorIterationNumber;
|
this.visitorIterationNumber = visitorIterationNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static GridConnection create( final IGridNode aNode, final IGridNode bNode, final AEPartLocation fromAtoB ) throws FailedConnectionException
|
||||||
|
{
|
||||||
|
if( aNode == null || bNode == null )
|
||||||
|
{
|
||||||
|
throw new NullNodeConnectionException();
|
||||||
|
}
|
||||||
|
|
||||||
|
final GridNode a = (GridNode) aNode;
|
||||||
|
final GridNode b = (GridNode) bNode;
|
||||||
|
|
||||||
|
if( a.hasConnection( b ) || b.hasConnection( a ) )
|
||||||
|
{
|
||||||
|
final String aMachineClass = a.getGridBlock().getMachine().getClass().getSimpleName();
|
||||||
|
final String bMachineClass = b.getGridBlock().getMachine().getClass().getSimpleName();
|
||||||
|
final String aCoordinates = a.getGridBlock().getLocation().toString();
|
||||||
|
final String bCoordinates = b.getGridBlock().getLocation().toString();
|
||||||
|
|
||||||
|
throw new ExistingConnectionException( String.format( EXISTING_CONNECTION_MESSAGE, aMachineClass, aCoordinates, bMachineClass, bCoordinates,
|
||||||
|
fromAtoB ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !Platform.securityCheck( a, b ) )
|
||||||
|
{
|
||||||
|
if( AEConfig.instance().isFeatureEnabled( AEFeature.LOG_SECURITY_AUDITS ) )
|
||||||
|
{
|
||||||
|
final DimensionalCoord aCoordinates = a.getGridBlock().getLocation();
|
||||||
|
final DimensionalCoord bCoordinates = b.getGridBlock().getLocation();
|
||||||
|
|
||||||
|
AELog.info( "Security audit 1 failed at [%s] belonging to player [id=%d]", aCoordinates.toString(), a.getPlayerID() );
|
||||||
|
AELog.info( "Security audit 2 failed at [%s] belonging to player [id=%d]", bCoordinates.toString(), b.getPlayerID() );
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new SecurityConnectionException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the actual connection
|
||||||
|
final GridConnection connection = new GridConnection( a, b, fromAtoB );
|
||||||
|
|
||||||
|
// Update both nodes with the new connection.
|
||||||
|
if( a.getMyGrid() == null )
|
||||||
|
{
|
||||||
|
b.setGrid( a.getInternalGrid() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( a.getMyGrid() == null )
|
||||||
|
{
|
||||||
|
final GridPropagator gp = new GridPropagator( b.getInternalGrid() );
|
||||||
|
aNode.beginVisit( gp );
|
||||||
|
}
|
||||||
|
else if( b.getMyGrid() == null )
|
||||||
|
{
|
||||||
|
final GridPropagator gp = new GridPropagator( a.getInternalGrid() );
|
||||||
|
bNode.beginVisit( gp );
|
||||||
|
}
|
||||||
|
else if( connection.isNetworkABetter( a, b ) )
|
||||||
|
{
|
||||||
|
final GridPropagator gp = new GridPropagator( a.getInternalGrid() );
|
||||||
|
b.beginVisit( gp );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
final GridPropagator gp = new GridPropagator( b.getInternalGrid() );
|
||||||
|
a.beginVisit( gp );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// a connection was destroyed RE-PATH!!
|
||||||
|
final IPathingGrid p = connection.sideA.getInternalGrid().getCache( IPathingGrid.class );
|
||||||
|
p.repath();
|
||||||
|
|
||||||
|
connection.sideA.addConnection( connection );
|
||||||
|
connection.sideB.addConnection( connection );
|
||||||
|
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
import appeng.api.exceptions.FailedConnectionException;
|
import appeng.api.exceptions.FailedConnectionException;
|
||||||
|
import appeng.api.exceptions.SecurityConnectionException;
|
||||||
import appeng.api.networking.GridFlags;
|
import appeng.api.networking.GridFlags;
|
||||||
import appeng.api.networking.GridNotification;
|
import appeng.api.networking.GridNotification;
|
||||||
import appeng.api.networking.IGrid;
|
import appeng.api.networking.IGrid;
|
||||||
@@ -50,6 +51,7 @@ import appeng.api.util.AEColor;
|
|||||||
import appeng.api.util.AEPartLocation;
|
import appeng.api.util.AEPartLocation;
|
||||||
import appeng.api.util.DimensionalCoord;
|
import appeng.api.util.DimensionalCoord;
|
||||||
import appeng.api.util.IReadOnlyCollection;
|
import appeng.api.util.IReadOnlyCollection;
|
||||||
|
import appeng.core.AELog;
|
||||||
import appeng.core.worlddata.WorldData;
|
import appeng.core.worlddata.WorldData;
|
||||||
import appeng.hooks.TickHandler;
|
import appeng.hooks.TickHandler;
|
||||||
import appeng.me.pathfinding.IPathItem;
|
import appeng.me.pathfinding.IPathItem;
|
||||||
@@ -216,7 +218,7 @@ public class GridNode implements IGridNode, IPathItem
|
|||||||
this.compressedData |= ( 1 << ( dir.ordinal() + 8 ) );
|
this.compressedData |= ( 1 << ( dir.ordinal() + 8 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
this.FindConnections();
|
this.findConnections();
|
||||||
this.getInternalGrid();
|
this.getInternalGrid();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -393,7 +395,7 @@ public class GridNode implements IGridNode, IPathItem
|
|||||||
return this.usedChannels;
|
return this.usedChannels;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FindConnections()
|
private void findConnections()
|
||||||
{
|
{
|
||||||
if( !this.gridProxy.isWorldAccessible() )
|
if( !this.gridProxy.isWorldAccessible() )
|
||||||
{
|
{
|
||||||
@@ -455,11 +457,18 @@ public class GridNode implements IGridNode, IPathItem
|
|||||||
// construct a new connection between these two nodes.
|
// construct a new connection between these two nodes.
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
new GridConnection( node, this, f.getOpposite() );
|
GridConnection.create( node, this, f.getOpposite() );
|
||||||
|
}
|
||||||
|
catch( SecurityConnectionException e )
|
||||||
|
{
|
||||||
|
AELog.debug( e );
|
||||||
|
TickHandler.INSTANCE.addCallable( node.getWorld(), new MachineSecurityBreak( this ) );
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
catch( final FailedConnectionException e )
|
catch( final FailedConnectionException e )
|
||||||
{
|
{
|
||||||
TickHandler.INSTANCE.addCallable( node.getWorld(), new MachineSecurityBreak( this ) );
|
AELog.debug( e );
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -482,11 +491,19 @@ public class GridNode implements IGridNode, IPathItem
|
|||||||
// construct a new connection between these two nodes.
|
// construct a new connection between these two nodes.
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
new GridConnection( node, this, f.getOpposite() );
|
GridConnection.create( node, this, f.getOpposite() );
|
||||||
|
}
|
||||||
|
catch( SecurityConnectionException e )
|
||||||
|
{
|
||||||
|
AELog.debug( e );
|
||||||
|
|
||||||
|
TickHandler.INSTANCE.addCallable( node.getWorld(), new MachineSecurityBreak( this ) );
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
catch( final FailedConnectionException e )
|
catch( final FailedConnectionException e )
|
||||||
{
|
{
|
||||||
TickHandler.INSTANCE.addCallable( node.getWorld(), new MachineSecurityBreak( this ) );
|
AELog.debug( e );
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -440,7 +440,6 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
|
|||||||
this.lastTime = 0;
|
this.lastTime = 0;
|
||||||
this.elapsedTime = 0;
|
this.elapsedTime = 0;
|
||||||
this.isComplete = true;
|
this.isComplete = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateCPU()
|
private void updateCPU()
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import appeng.api.networking.IGridHost;
|
|||||||
import appeng.api.networking.IGridNode;
|
import appeng.api.networking.IGridNode;
|
||||||
import appeng.api.util.AEPartLocation;
|
import appeng.api.util.AEPartLocation;
|
||||||
import appeng.api.util.WorldCoord;
|
import appeng.api.util.WorldCoord;
|
||||||
|
import appeng.core.AELog;
|
||||||
import appeng.me.cache.helpers.ConnectionWrapper;
|
import appeng.me.cache.helpers.ConnectionWrapper;
|
||||||
import appeng.me.cluster.IAECluster;
|
import appeng.me.cluster.IAECluster;
|
||||||
import appeng.tile.qnb.TileQuantumBridge;
|
import appeng.tile.qnb.TileQuantumBridge;
|
||||||
@@ -161,6 +162,7 @@ public class QuantumCluster implements ILocatable, IAECluster
|
|||||||
catch( final FailedConnectionException e )
|
catch( final FailedConnectionException e )
|
||||||
{
|
{
|
||||||
// :(
|
// :(
|
||||||
|
AELog.debug( e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -241,11 +241,11 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
new GridConnection( cn, sn, AEPartLocation.INTERNAL );
|
GridConnection.create( cn, sn, AEPartLocation.INTERNAL );
|
||||||
}
|
}
|
||||||
catch( final FailedConnectionException e )
|
catch( final FailedConnectionException e )
|
||||||
{
|
{
|
||||||
// ekk!
|
AELog.debug( e );
|
||||||
|
|
||||||
bp.removeFromWorld();
|
bp.removeFromWorld();
|
||||||
this.setCenter( null );
|
this.setCenter( null );
|
||||||
@@ -292,11 +292,11 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
new GridConnection( cn, sn, AEPartLocation.INTERNAL );
|
GridConnection.create( cn, sn, AEPartLocation.INTERNAL );
|
||||||
}
|
}
|
||||||
catch( final FailedConnectionException e )
|
catch( final FailedConnectionException e )
|
||||||
{
|
{
|
||||||
// ekk!
|
AELog.debug( e );
|
||||||
|
|
||||||
bp.removeFromWorld();
|
bp.removeFromWorld();
|
||||||
this.setSide( side, null );
|
this.setSide( side, null );
|
||||||
@@ -637,6 +637,7 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
|||||||
catch( final FailedConnectionException e )
|
catch( final FailedConnectionException e )
|
||||||
{
|
{
|
||||||
// ekk
|
// ekk
|
||||||
|
AELog.debug( e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1087,7 +1088,7 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
|||||||
this.getFacadeContainer().readFromNBT( data );
|
this.getFacadeContainer().readFromNBT( data );
|
||||||
}
|
}
|
||||||
|
|
||||||
public List getDrops( final List drops )
|
public List<ItemStack> getDrops( final List<ItemStack> drops )
|
||||||
{
|
{
|
||||||
for( final AEPartLocation s : AEPartLocation.values() )
|
for( final AEPartLocation s : AEPartLocation.values() )
|
||||||
{
|
{
|
||||||
@@ -1111,7 +1112,7 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
|||||||
return drops;
|
return drops;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List getNoDrops( final List drops )
|
public List<ItemStack> getNoDrops( final List<ItemStack> drops )
|
||||||
{
|
{
|
||||||
for( final AEPartLocation s : AEPartLocation.values() )
|
for( final AEPartLocation s : AEPartLocation.values() )
|
||||||
{
|
{
|
||||||
@@ -1150,12 +1151,15 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
|||||||
@Override
|
@Override
|
||||||
public CableBusRenderState getRenderState()
|
public CableBusRenderState getRenderState()
|
||||||
{
|
{
|
||||||
PartCable cable = (PartCable) this.getCenter();
|
final PartCable cable = (PartCable) this.getCenter();
|
||||||
|
|
||||||
CableBusRenderState renderState = new CableBusRenderState();
|
final CableBusRenderState renderState = new CableBusRenderState();
|
||||||
|
|
||||||
if( cable != null )
|
if( cable != null )
|
||||||
{
|
{
|
||||||
|
final boolean isSmart = cable.getCableConnectionType() == AECableType.SMART || cable.getCableConnectionType() == AECableType.DENSE_SMART;
|
||||||
|
final boolean isDense = cable.getCableConnectionType() == AECableType.DENSE_COVERED || cable.getCableConnectionType() == AECableType.DENSE_SMART;
|
||||||
|
|
||||||
renderState.setCableColor( cable.getCableColor() );
|
renderState.setCableColor( cable.getCableColor() );
|
||||||
renderState.setCableType( cable.getCableConnectionType() );
|
renderState.setCableType( cable.getCableConnectionType() );
|
||||||
renderState.setCoreType( CableCoreType.fromCableType( cable.getCableConnectionType() ) );
|
renderState.setCoreType( CableCoreType.fromCableType( cable.getCableConnectionType() ) );
|
||||||
@@ -1175,12 +1179,12 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
|||||||
// Only use the incoming cable-type of the adjacent block, if it's not a cable bus itself
|
// Only use the incoming cable-type of the adjacent block, if it's not a cable bus itself
|
||||||
// Dense cables however also respect the adjacent cable-type since their outgoing connection
|
// Dense cables however also respect the adjacent cable-type since their outgoing connection
|
||||||
// point would look too big for other cable types
|
// point would look too big for other cable types
|
||||||
BlockPos adjacentPos = this.getTile().getPos().offset( facing );
|
final BlockPos adjacentPos = this.getTile().getPos().offset( facing );
|
||||||
TileEntity adjacentTe = this.getTile().getWorld().getTileEntity( adjacentPos );
|
final TileEntity adjacentTe = this.getTile().getWorld().getTileEntity( adjacentPos );
|
||||||
|
|
||||||
if( adjacentTe instanceof IGridHost )
|
if( adjacentTe instanceof IGridHost )
|
||||||
{
|
{
|
||||||
if( !( adjacentTe instanceof IPartHost ) || cable.getCableConnectionType() == AECableType.DENSE_SMART || cable
|
if( !( adjacentTe instanceof IPartHost ) || isDense )
|
||||||
.getCableConnectionType() == AECableType.DENSE_COVERED )
|
|
||||||
{
|
{
|
||||||
IGridHost gridHost = (IGridHost) adjacentTe;
|
IGridHost gridHost = (IGridHost) adjacentTe;
|
||||||
connectionType = gridHost.getCableConnectionType( AEPartLocation.fromFacing( facing.getOpposite() ) );
|
connectionType = gridHost.getCableConnectionType( AEPartLocation.fromFacing( facing.getOpposite() ) );
|
||||||
@@ -1201,7 +1205,7 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
|||||||
// adjacent tile requires it
|
// adjacent tile requires it
|
||||||
for( EnumFacing facing : EnumFacing.values() )
|
for( EnumFacing facing : EnumFacing.values() )
|
||||||
{
|
{
|
||||||
int channels = cable.getChannelsOnSide( facing );
|
int channels = isSmart ? cable.getChannelsOnSide( facing ) : 0;
|
||||||
renderState.getChannelsOnSide().put( facing, channels );
|
renderState.getChannelsOnSide().put( facing, channels );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1209,14 +1213,14 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
|||||||
// Determine attachments and facades
|
// Determine attachments and facades
|
||||||
for( EnumFacing facing : EnumFacing.values() )
|
for( EnumFacing facing : EnumFacing.values() )
|
||||||
{
|
{
|
||||||
|
final FacadeRenderState facadeState = this.getFacadeRenderState( facing );
|
||||||
|
|
||||||
FacadeRenderState facadeState = this.getFacadeRenderState( facing );
|
|
||||||
if( facadeState != null )
|
if( facadeState != null )
|
||||||
{
|
{
|
||||||
renderState.getFacades().put( facing, facadeState );
|
renderState.getFacades().put( facing, facadeState );
|
||||||
}
|
}
|
||||||
|
|
||||||
IPart part = this.getPart( facing );
|
final IPart part = this.getPart( facing );
|
||||||
|
|
||||||
if( part == null )
|
if( part == null )
|
||||||
{
|
{
|
||||||
@@ -1224,15 +1228,17 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This will add the part's bounding boxes to the render state, which is required for facades
|
// This will add the part's bounding boxes to the render state, which is required for facades
|
||||||
AEPartLocation loc = AEPartLocation.fromFacing( facing );
|
final AEPartLocation loc = AEPartLocation.fromFacing( facing );
|
||||||
IPartCollisionHelper bch = new BusCollisionHelper( renderState.getBoundingBoxes(), loc, null, true );
|
final IPartCollisionHelper bch = new BusCollisionHelper( renderState.getBoundingBoxes(), loc, null, true );
|
||||||
|
|
||||||
part.getBoxes( bch );
|
part.getBoxes( bch );
|
||||||
|
|
||||||
if( part instanceof IGridHost )
|
if( part instanceof IGridHost )
|
||||||
{
|
{
|
||||||
// Some attachments want a thicker cable than glass, account for that
|
// Some attachments want a thicker cable than glass, account for that
|
||||||
IGridHost gridHost = (IGridHost) part;
|
final IGridHost gridHost = (IGridHost) part;
|
||||||
AECableType desiredType = gridHost.getCableConnectionType( AEPartLocation.INTERNAL );
|
final AECableType desiredType = gridHost.getCableConnectionType( AEPartLocation.INTERNAL );
|
||||||
|
|
||||||
if( renderState.getCoreType() == CableCoreType.GLASS && ( desiredType == AECableType.SMART || desiredType == AECableType.COVERED ) )
|
if( renderState.getCoreType() == CableCoreType.GLASS && ( desiredType == AECableType.SMART || desiredType == AECableType.COVERED ) )
|
||||||
{
|
{
|
||||||
renderState.setCoreType( CableCoreType.COVERED );
|
renderState.setCoreType( CableCoreType.COVERED );
|
||||||
@@ -1254,14 +1260,16 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
|||||||
private FacadeRenderState getFacadeRenderState( EnumFacing side )
|
private FacadeRenderState getFacadeRenderState( EnumFacing side )
|
||||||
{
|
{
|
||||||
// Store the "masqueraded" itemstack for the given side, if there is a facade
|
// Store the "masqueraded" itemstack for the given side, if there is a facade
|
||||||
IFacadePart facade = this.getFacade( side.ordinal() );
|
final IFacadePart facade = this.getFacade( side.ordinal() );
|
||||||
|
|
||||||
if( facade != null )
|
if( facade != null )
|
||||||
{
|
{
|
||||||
ItemStack textureItem = facade.getTextureItem();
|
final ItemStack textureItem = facade.getTextureItem();
|
||||||
IBlockState blockState = facade.getBlockState();
|
final IBlockState blockState = facade.getBlockState();
|
||||||
|
|
||||||
if( blockState != null && textureItem != null )
|
if( blockState != null && textureItem != null )
|
||||||
{
|
{
|
||||||
EnumSet<EnumFacing> openFaces = this.calculateFaceOpenFaces( side );
|
final EnumSet<EnumFacing> openFaces = this.calculateFaceOpenFaces( side );
|
||||||
return new FacadeRenderState( blockState, openFaces, textureItem );
|
return new FacadeRenderState( blockState, openFaces, textureItem );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1273,9 +1281,9 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
|||||||
{
|
{
|
||||||
final EnumSet<EnumFacing> out = EnumSet.of( side, side.getOpposite() );
|
final EnumSet<EnumFacing> out = EnumSet.of( side, side.getOpposite() );
|
||||||
final IFacadePart facade = this.getFacade( side.ordinal() );
|
final IFacadePart facade = this.getFacade( side.ordinal() );
|
||||||
|
final IBlockAccess blockAccess = this.getTile().getWorld();
|
||||||
|
final BlockPos pos = this.getTile().getPos();
|
||||||
|
|
||||||
IBlockAccess blockAccess = this.getTile().getWorld();
|
|
||||||
BlockPos pos = this.getTile().getPos();
|
|
||||||
for( final EnumFacing it : EnumFacing.values() )
|
for( final EnumFacing it : EnumFacing.values() )
|
||||||
{
|
{
|
||||||
if( !out.contains( it ) && this.hasAlphaDiff( blockAccess.getTileEntity( pos.offset( it ) ), side, facade ) )
|
if( !out.contains( it ) && this.hasAlphaDiff( blockAccess.getTileEntity( pos.offset( it ) ), side, facade ) )
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import net.minecraft.util.math.Vec3d;
|
|||||||
import appeng.api.AEApi;
|
import appeng.api.AEApi;
|
||||||
import appeng.api.config.Actionable;
|
import appeng.api.config.Actionable;
|
||||||
import appeng.api.config.FuzzyMode;
|
import appeng.api.config.FuzzyMode;
|
||||||
import appeng.api.config.PowerMultiplier;
|
|
||||||
import appeng.api.config.RedstoneMode;
|
import appeng.api.config.RedstoneMode;
|
||||||
import appeng.api.config.Settings;
|
import appeng.api.config.Settings;
|
||||||
import appeng.api.config.Upgrades;
|
import appeng.api.config.Upgrades;
|
||||||
@@ -41,7 +40,6 @@ import appeng.api.networking.ticking.TickRateModulation;
|
|||||||
import appeng.api.networking.ticking.TickingRequest;
|
import appeng.api.networking.ticking.TickingRequest;
|
||||||
import appeng.api.parts.IPartCollisionHelper;
|
import appeng.api.parts.IPartCollisionHelper;
|
||||||
import appeng.api.parts.IPartModel;
|
import appeng.api.parts.IPartModel;
|
||||||
import appeng.api.storage.IMEInventory;
|
|
||||||
import appeng.api.storage.IMEMonitor;
|
import appeng.api.storage.IMEMonitor;
|
||||||
import appeng.api.storage.channels.IItemStorageChannel;
|
import appeng.api.storage.channels.IItemStorageChannel;
|
||||||
import appeng.api.storage.data.IAEItemStack;
|
import appeng.api.storage.data.IAEItemStack;
|
||||||
@@ -72,9 +70,7 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
|
|||||||
public static final IPartModel MODELS_HAS_CHANNEL = new PartModel( MODEL_BASE, new ResourceLocation( AppEng.MOD_ID, "part/import_bus_has_channel" ) );
|
public static final IPartModel MODELS_HAS_CHANNEL = new PartModel( MODEL_BASE, new ResourceLocation( AppEng.MOD_ID, "part/import_bus_has_channel" ) );
|
||||||
|
|
||||||
private final IActionSource source;
|
private final IActionSource source;
|
||||||
private IMEInventory<IAEItemStack> destination = null;
|
private int itemsToSend; // used in tickingRequest
|
||||||
private IAEItemStack lastItemChecked = null;
|
|
||||||
private int itemToSend; // used in tickingRequest
|
|
||||||
private boolean worked; // used in tickingRequest
|
private boolean worked; // used in tickingRequest
|
||||||
|
|
||||||
@Reflected
|
@Reflected
|
||||||
@@ -95,14 +91,24 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final IAEItemStack out = this.destination.injectItems(
|
try
|
||||||
this.lastItemChecked = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( stack ), Actionable.SIMULATE,
|
|
||||||
this.source );
|
|
||||||
if( out == null )
|
|
||||||
{
|
{
|
||||||
return true;
|
final IMEMonitor<IAEItemStack> inv = this.getProxy().getStorage().getInventory(
|
||||||
|
AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
|
||||||
|
|
||||||
|
final IAEItemStack out = inv.injectItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( stack ),
|
||||||
|
Actionable.SIMULATE,
|
||||||
|
this.source );
|
||||||
|
if( out == null )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return out.getStackSize() != stack.getCount();
|
||||||
|
}
|
||||||
|
catch( GridAccessException ex )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return out.getStackSize() != stack.getCount();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -165,9 +171,7 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this.itemToSend = this.calculateItemsToSend();
|
this.itemsToSend = this.calculateItemsToSend();
|
||||||
this.itemToSend = Math.min( this.itemToSend,
|
|
||||||
(int) ( 0.01 + this.getProxy().getEnergy().extractAEPower( this.itemToSend, Actionable.SIMULATE, PowerMultiplier.CONFIG ) ) );
|
|
||||||
|
|
||||||
final IMEMonitor<IAEItemStack> inv = this.getProxy().getStorage().getInventory(
|
final IMEMonitor<IAEItemStack> inv = this.getProxy().getStorage().getInventory(
|
||||||
AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
|
AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
|
||||||
@@ -177,10 +181,10 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
|
|||||||
for( int x = 0; x < this.availableSlots(); x++ )
|
for( int x = 0; x < this.availableSlots(); x++ )
|
||||||
{
|
{
|
||||||
final IAEItemStack ais = this.getConfig().getAEStackInSlot( x );
|
final IAEItemStack ais = this.getConfig().getAEStackInSlot( x );
|
||||||
if( ais != null && this.itemToSend > 0 )
|
if( ais != null && itemsToSend > 0 )
|
||||||
{
|
{
|
||||||
Configured = true;
|
Configured = true;
|
||||||
while( this.itemToSend > 0 )
|
while( itemsToSend > 0 )
|
||||||
{
|
{
|
||||||
if( this.importStuff( myAdaptor, ais, inv, energy, fzMode ) )
|
if( this.importStuff( myAdaptor, ais, inv, energy, fzMode ) )
|
||||||
{
|
{
|
||||||
@@ -192,7 +196,7 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
|
|||||||
|
|
||||||
if( !Configured )
|
if( !Configured )
|
||||||
{
|
{
|
||||||
while( this.itemToSend > 0 )
|
while( itemsToSend > 0 )
|
||||||
{
|
{
|
||||||
if( this.importStuff( myAdaptor, null, inv, energy, fzMode ) )
|
if( this.importStuff( myAdaptor, null, inv, energy, fzMode ) )
|
||||||
{
|
{
|
||||||
@@ -221,38 +225,32 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
|
|||||||
|
|
||||||
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
|
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
|
||||||
{
|
{
|
||||||
newItems = myAdaptor.removeSimilarItems( toSend, whatToImport == null ? ItemStack.EMPTY : whatToImport.getDefinition(), fzMode,
|
newItems = myAdaptor.removeSimilarItems( toSend, whatToImport == null ? ItemStack.EMPTY : whatToImport.getDefinition(), fzMode, this );
|
||||||
this.configDestination( inv ) );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newItems = myAdaptor.removeItems( toSend, whatToImport == null ? ItemStack.EMPTY : whatToImport.getDefinition(), this.configDestination( inv ) );
|
newItems = myAdaptor.removeItems( toSend, whatToImport == null ? ItemStack.EMPTY : whatToImport.getDefinition(), this );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !newItems.isEmpty() )
|
if( !newItems.isEmpty() )
|
||||||
{
|
{
|
||||||
newItems.setCount( (int) ( Math.min( newItems.getCount(),
|
final IAEItemStack aeStack = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( newItems );
|
||||||
energy.extractAEPower( newItems.getCount(), Actionable.SIMULATE, PowerMultiplier.CONFIG ) ) + 0.01 ) );
|
final IAEItemStack failed = Platform.poweredInsert( energy, inv, aeStack, this.source );
|
||||||
this.itemToSend -= newItems.getCount();
|
|
||||||
|
|
||||||
if( this.lastItemChecked == null || !this.lastItemChecked.isSameType( newItems ) )
|
|
||||||
{
|
|
||||||
this.lastItemChecked = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( newItems );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.lastItemChecked.setStackSize( newItems.getCount() );
|
|
||||||
}
|
|
||||||
|
|
||||||
final IAEItemStack failed = Platform.poweredInsert( energy, this.destination, this.lastItemChecked, this.source );
|
|
||||||
|
|
||||||
if( failed != null )
|
if( failed != null )
|
||||||
{
|
{
|
||||||
myAdaptor.addItems( failed.createItemStack() );
|
// try unpowered insert, better be a bit lenient then void items
|
||||||
|
final IAEItemStack spill = inv.injectItems( failed, Actionable.MODULATE, this.source );
|
||||||
|
if( spill != null )
|
||||||
|
{
|
||||||
|
// last resort try to put it back .. lets hope it's a chest type of thing
|
||||||
|
myAdaptor.addItems( spill.createItemStack() );
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
this.itemsToSend -= newItems.getCount();
|
||||||
this.worked = true;
|
this.worked = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -266,7 +264,7 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
|
|||||||
|
|
||||||
private int calculateMaximumAmountToImport( final InventoryAdaptor myAdaptor, final IAEItemStack whatToImport, final IMEMonitor<IAEItemStack> inv, final FuzzyMode fzMode )
|
private int calculateMaximumAmountToImport( final InventoryAdaptor myAdaptor, final IAEItemStack whatToImport, final IMEMonitor<IAEItemStack> inv, final FuzzyMode fzMode )
|
||||||
{
|
{
|
||||||
final int toSend = Math.min( this.itemToSend, 64 );
|
final int toSend = Math.min( this.itemsToSend, 64 );
|
||||||
final ItemStack itemStackToImport;
|
final ItemStack itemStackToImport;
|
||||||
|
|
||||||
if( whatToImport == null )
|
if( whatToImport == null )
|
||||||
@@ -282,13 +280,13 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
|
|||||||
final ItemStack simResult;
|
final ItemStack simResult;
|
||||||
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
|
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
|
||||||
{
|
{
|
||||||
simResult = myAdaptor.simulateSimilarRemove( toSend, itemStackToImport, fzMode, this.configDestination( inv ) );
|
simResult = myAdaptor.simulateSimilarRemove( toSend, itemStackToImport, fzMode, this );
|
||||||
itemAmountNotStorable = this.destination.injectItems( AEItemStack.fromItemStack( simResult ), Actionable.SIMULATE, this.source );
|
itemAmountNotStorable = inv.injectItems( AEItemStack.fromItemStack( simResult ), Actionable.SIMULATE, this.source );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
simResult = myAdaptor.simulateRemove( toSend, itemStackToImport, this.configDestination( inv ) );
|
simResult = myAdaptor.simulateRemove( toSend, itemStackToImport, this );
|
||||||
itemAmountNotStorable = this.destination.injectItems( AEItemStack.fromItemStack( simResult ), Actionable.SIMULATE, this.source );
|
itemAmountNotStorable = inv.injectItems( AEItemStack.fromItemStack( simResult ), Actionable.SIMULATE, this.source );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( itemAmountNotStorable != null )
|
if( itemAmountNotStorable != null )
|
||||||
@@ -299,12 +297,6 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
|
|||||||
return toSend;
|
return toSend;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IInventoryDestination configDestination( final IMEMonitor<IAEItemStack> itemInventory )
|
|
||||||
{
|
|
||||||
this.destination = itemInventory;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isSleeping()
|
protected boolean isSleeping()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,10 +19,10 @@
|
|||||||
package appeng.parts.misc;
|
package appeng.parts.misc;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -36,11 +36,12 @@ import appeng.api.networking.storage.IBaseMonitor;
|
|||||||
import appeng.api.networking.ticking.TickRateModulation;
|
import appeng.api.networking.ticking.TickRateModulation;
|
||||||
import appeng.api.storage.IMEInventory;
|
import appeng.api.storage.IMEInventory;
|
||||||
import appeng.api.storage.IMEMonitorHandlerReceiver;
|
import appeng.api.storage.IMEMonitorHandlerReceiver;
|
||||||
import appeng.api.storage.IStorageChannel;
|
|
||||||
import appeng.api.storage.channels.IItemStorageChannel;
|
import appeng.api.storage.channels.IItemStorageChannel;
|
||||||
import appeng.api.storage.data.IAEItemStack;
|
import appeng.api.storage.data.IAEItemStack;
|
||||||
import appeng.api.storage.data.IItemList;
|
import appeng.api.storage.data.IItemList;
|
||||||
import appeng.core.AELog;
|
import appeng.core.AELog;
|
||||||
|
import appeng.me.GridAccessException;
|
||||||
|
import appeng.me.helpers.IGridProxyable;
|
||||||
import appeng.me.storage.ITickingMonitor;
|
import appeng.me.storage.ITickingMonitor;
|
||||||
import appeng.util.Platform;
|
import appeng.util.Platform;
|
||||||
import appeng.util.item.AEItemStack;
|
import appeng.util.item.AEItemStack;
|
||||||
@@ -51,20 +52,17 @@ import appeng.util.item.AEItemStack;
|
|||||||
*/
|
*/
|
||||||
class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAEItemStack>, ITickingMonitor
|
class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAEItemStack>, ITickingMonitor
|
||||||
{
|
{
|
||||||
|
|
||||||
private final Map<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap<>();
|
private final Map<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap<>();
|
||||||
|
|
||||||
private IActionSource mySource;
|
private IActionSource mySource;
|
||||||
|
|
||||||
private final IItemHandler itemHandler;
|
private final IItemHandler itemHandler;
|
||||||
|
private final IGridProxyable proxyable;
|
||||||
|
private final InventoryCache cache;
|
||||||
|
|
||||||
private ItemStack[] cachedStacks = new ItemStack[0];
|
ItemHandlerAdapter( IItemHandler itemHandler, IGridProxyable proxy )
|
||||||
|
|
||||||
private IAEItemStack[] cachedAeStacks = new IAEItemStack[0];
|
|
||||||
|
|
||||||
ItemHandlerAdapter( IItemHandler itemHandler )
|
|
||||||
{
|
{
|
||||||
this.itemHandler = itemHandler;
|
this.itemHandler = itemHandler;
|
||||||
|
this.proxyable = proxy;
|
||||||
|
this.cache = new InventoryCache( this.itemHandler );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -91,7 +89,14 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
|||||||
|
|
||||||
if( type == Actionable.MODULATE )
|
if( type == Actionable.MODULATE )
|
||||||
{
|
{
|
||||||
this.onTick();
|
try
|
||||||
|
{
|
||||||
|
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
||||||
|
}
|
||||||
|
catch( GridAccessException ex )
|
||||||
|
{
|
||||||
|
// meh
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return AEItemStack.fromItemStack( remaining );
|
return AEItemStack.fromItemStack( remaining );
|
||||||
@@ -167,7 +172,14 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
|||||||
{
|
{
|
||||||
if( mode == Actionable.MODULATE )
|
if( mode == Actionable.MODULATE )
|
||||||
{
|
{
|
||||||
this.onTick();
|
try
|
||||||
|
{
|
||||||
|
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
|
||||||
|
}
|
||||||
|
catch( GridAccessException ex )
|
||||||
|
{
|
||||||
|
// meh
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return AEItemStack.fromItemStack( gathered );
|
return AEItemStack.fromItemStack( gathered );
|
||||||
@@ -176,72 +188,10 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ItemStack getItemStackInCachedSlot( int pos )
|
|
||||||
{
|
|
||||||
if( pos > this.cachedStacks.length )
|
|
||||||
{
|
|
||||||
return ItemStack.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( this.cachedStacks[pos] == null )
|
|
||||||
{
|
|
||||||
return ItemStack.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.cachedStacks[pos];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TickRateModulation onTick()
|
public TickRateModulation onTick()
|
||||||
{
|
{
|
||||||
LinkedList<IAEItemStack> changes = new LinkedList<>();
|
List<IAEItemStack> changes = this.cache.update();
|
||||||
|
|
||||||
int slots = this.itemHandler.getSlots();
|
|
||||||
|
|
||||||
// Make room for new slots
|
|
||||||
if( slots > this.cachedStacks.length )
|
|
||||||
{
|
|
||||||
this.cachedStacks = Arrays.copyOf( this.cachedStacks, slots );
|
|
||||||
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
|
|
||||||
}
|
|
||||||
|
|
||||||
for( int slot = 0; slot < slots; slot++ )
|
|
||||||
{
|
|
||||||
// Save the old stuff
|
|
||||||
ItemStack oldIS = this.getItemStackInCachedSlot( slot );
|
|
||||||
IAEItemStack oldAeIS = this.cachedAeStacks[slot];
|
|
||||||
|
|
||||||
ItemStack newIS = this.itemHandler.getStackInSlot( slot );
|
|
||||||
|
|
||||||
if( this.isDifferent( newIS, oldIS ) )
|
|
||||||
{
|
|
||||||
this.addItemChange( slot, oldAeIS, newIS, changes );
|
|
||||||
}
|
|
||||||
else if( !newIS.isEmpty() && !oldIS.isEmpty() )
|
|
||||||
{
|
|
||||||
this.addPossibleStackSizeChange( slot, oldAeIS, newIS, changes );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle cases where the number of slots actually is lower now than before
|
|
||||||
if( slots < this.cachedStacks.length )
|
|
||||||
{
|
|
||||||
for( int slot = slots; slot < this.cachedStacks.length; slot++ )
|
|
||||||
{
|
|
||||||
IAEItemStack aeStack = this.cachedAeStacks[slot];
|
|
||||||
if( aeStack != null )
|
|
||||||
{
|
|
||||||
IAEItemStack a = aeStack.copy();
|
|
||||||
a.setStackSize( -a.getStackSize() );
|
|
||||||
changes.add( a );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reduce the cache size
|
|
||||||
this.cachedStacks = Arrays.copyOf( this.cachedStacks, slots );
|
|
||||||
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !changes.isEmpty() )
|
if( !changes.isEmpty() )
|
||||||
{
|
{
|
||||||
this.postDifference( changes );
|
this.postDifference( changes );
|
||||||
@@ -253,73 +203,6 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addItemChange( int slot, IAEItemStack oldAeIS, ItemStack newIS, List<IAEItemStack> changes )
|
|
||||||
{
|
|
||||||
// Completely different item
|
|
||||||
this.cachedStacks[slot] = newIS;
|
|
||||||
this.cachedAeStacks[slot] = AEItemStack.fromItemStack( newIS );
|
|
||||||
|
|
||||||
// If we had a stack previously in this slot, notify the newtork about its disappearance
|
|
||||||
if( oldAeIS != null )
|
|
||||||
{
|
|
||||||
oldAeIS.setStackSize( -oldAeIS.getStackSize() );
|
|
||||||
changes.add( oldAeIS );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notify the network about the new stack. Note that this is null if newIS was null
|
|
||||||
if( this.cachedAeStacks[slot] != null )
|
|
||||||
{
|
|
||||||
changes.add( this.cachedAeStacks[slot] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addPossibleStackSizeChange( int slot, IAEItemStack oldAeIS, ItemStack newIS, List<IAEItemStack> changes )
|
|
||||||
{
|
|
||||||
// Still the same item, but amount might have changed
|
|
||||||
long diff = newIS.getCount() - oldAeIS.getStackSize();
|
|
||||||
|
|
||||||
if( diff != 0 )
|
|
||||||
{
|
|
||||||
IAEItemStack stack = oldAeIS.copy();
|
|
||||||
stack.setStackSize( newIS.getCount() );
|
|
||||||
|
|
||||||
this.cachedStacks[slot] = newIS;
|
|
||||||
this.cachedAeStacks[slot] = stack;
|
|
||||||
|
|
||||||
final IAEItemStack a = stack.copy();
|
|
||||||
a.setStackSize( diff );
|
|
||||||
changes.add( a );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isDifferent( final ItemStack a, final ItemStack b )
|
|
||||||
{
|
|
||||||
if( a == b && b.isEmpty() )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.isEmpty() || b.isEmpty() || !Platform.itemComparisons().isSameItem( a, b );
|
|
||||||
}
|
|
||||||
|
|
||||||
private void postDifference( Iterable<IAEItemStack> a )
|
|
||||||
{
|
|
||||||
final Iterator<Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
|
|
||||||
while( i.hasNext() )
|
|
||||||
{
|
|
||||||
final Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> l = i.next();
|
|
||||||
final IMEMonitorHandlerReceiver<IAEItemStack> key = l.getKey();
|
|
||||||
if( key.isValid( l.getValue() ) )
|
|
||||||
{
|
|
||||||
key.postChange( this, a, this.mySource );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
i.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setActionSource( final IActionSource mySource )
|
public void setActionSource( final IActionSource mySource )
|
||||||
{
|
{
|
||||||
@@ -339,7 +222,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IStorageChannel getChannel()
|
public IItemStorageChannel getChannel()
|
||||||
{
|
{
|
||||||
return AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class );
|
return AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class );
|
||||||
}
|
}
|
||||||
@@ -355,4 +238,152 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
|
|||||||
{
|
{
|
||||||
this.listeners.remove( l );
|
this.listeners.remove( l );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void postDifference( Iterable<IAEItemStack> a )
|
||||||
|
{
|
||||||
|
final Iterator<Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
|
||||||
|
while( i.hasNext() )
|
||||||
|
{
|
||||||
|
final Map.Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> l = i.next();
|
||||||
|
final IMEMonitorHandlerReceiver<IAEItemStack> key = l.getKey();
|
||||||
|
if( key.isValid( l.getValue() ) )
|
||||||
|
{
|
||||||
|
key.postChange( this, a, this.mySource );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class InventoryCache
|
||||||
|
{
|
||||||
|
private ItemStack[] cachedStacks = new ItemStack[0];
|
||||||
|
private IAEItemStack[] cachedAeStacks = new IAEItemStack[0];
|
||||||
|
private final IItemHandler itemHandler;
|
||||||
|
|
||||||
|
public InventoryCache( IItemHandler itemHandler )
|
||||||
|
{
|
||||||
|
this.itemHandler = itemHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<IAEItemStack> update()
|
||||||
|
{
|
||||||
|
List<IAEItemStack> changes = new ArrayList<>();
|
||||||
|
|
||||||
|
int slots = this.itemHandler.getSlots();
|
||||||
|
|
||||||
|
// Make room for new slots
|
||||||
|
if( slots > this.cachedStacks.length )
|
||||||
|
{
|
||||||
|
this.cachedStacks = Arrays.copyOf( this.cachedStacks, slots );
|
||||||
|
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
|
||||||
|
}
|
||||||
|
|
||||||
|
for( int slot = 0; slot < slots; slot++ )
|
||||||
|
{
|
||||||
|
// Save the old stuff
|
||||||
|
ItemStack oldIS = this.getItemStackInCachedSlot( slot );
|
||||||
|
IAEItemStack oldAeIS = this.cachedAeStacks[slot];
|
||||||
|
|
||||||
|
ItemStack newIS = this.itemHandler.getStackInSlot( slot );
|
||||||
|
|
||||||
|
if( isDifferent( newIS, oldIS ) )
|
||||||
|
{
|
||||||
|
this.addItemChange( slot, oldAeIS, newIS, changes );
|
||||||
|
}
|
||||||
|
else if( !newIS.isEmpty() && !oldIS.isEmpty() )
|
||||||
|
{
|
||||||
|
this.addPossibleStackSizeChange( slot, oldAeIS, newIS, changes );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle cases where the number of slots actually is lower now than before
|
||||||
|
if( slots < this.cachedStacks.length )
|
||||||
|
{
|
||||||
|
for( int slot = slots; slot < this.cachedStacks.length; slot++ )
|
||||||
|
{
|
||||||
|
IAEItemStack aeStack = this.cachedAeStacks[slot];
|
||||||
|
if( aeStack != null )
|
||||||
|
{
|
||||||
|
IAEItemStack a = aeStack.copy();
|
||||||
|
a.setStackSize( -a.getStackSize() );
|
||||||
|
changes.add( a );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reduce the cache size
|
||||||
|
this.cachedStacks = Arrays.copyOf( this.cachedStacks, slots );
|
||||||
|
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
|
||||||
|
}
|
||||||
|
|
||||||
|
return changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addPossibleStackSizeChange( int slot, IAEItemStack oldAeIS, ItemStack newIS, List<IAEItemStack> changes )
|
||||||
|
{
|
||||||
|
// Still the same item, but amount might have changed
|
||||||
|
long diff = newIS.getCount() - oldAeIS.getStackSize();
|
||||||
|
|
||||||
|
if( diff != 0 )
|
||||||
|
{
|
||||||
|
IAEItemStack stack = oldAeIS.copy();
|
||||||
|
stack.setStackSize( newIS.getCount() );
|
||||||
|
|
||||||
|
this.cachedStacks[slot] = newIS;
|
||||||
|
this.cachedAeStacks[slot] = stack;
|
||||||
|
|
||||||
|
final IAEItemStack a = stack.copy();
|
||||||
|
a.setStackSize( diff );
|
||||||
|
changes.add( a );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemStack getItemStackInCachedSlot( int pos )
|
||||||
|
{
|
||||||
|
if( pos > this.cachedStacks.length )
|
||||||
|
{
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( this.cachedStacks[pos] == null )
|
||||||
|
{
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.cachedStacks[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addItemChange( int slot, IAEItemStack oldAeIS, ItemStack newIS, List<IAEItemStack> changes )
|
||||||
|
{
|
||||||
|
// Completely different item
|
||||||
|
this.cachedStacks[slot] = newIS;
|
||||||
|
this.cachedAeStacks[slot] = AEItemStack.fromItemStack( newIS );
|
||||||
|
|
||||||
|
// If we had a stack previously in this slot, notify the newtork about its disappearance
|
||||||
|
if( oldAeIS != null )
|
||||||
|
{
|
||||||
|
oldAeIS.setStackSize( -oldAeIS.getStackSize() );
|
||||||
|
changes.add( oldAeIS );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify the network about the new stack. Note that this is null if newIS was null
|
||||||
|
if( this.cachedAeStacks[slot] != null )
|
||||||
|
{
|
||||||
|
changes.add( this.cachedAeStacks[slot] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isDifferent( final ItemStack a, final ItemStack b )
|
||||||
|
{
|
||||||
|
if( a == b && b.isEmpty() )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return a.isEmpty() || b.isEmpty() || !Platform.itemComparisons().isSameItem( a, b );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,6 @@ import appeng.api.storage.IStorageMonitorable;
|
|||||||
import appeng.api.storage.IStorageMonitorableAccessor;
|
import appeng.api.storage.IStorageMonitorableAccessor;
|
||||||
import appeng.api.storage.channels.IItemStorageChannel;
|
import appeng.api.storage.channels.IItemStorageChannel;
|
||||||
import appeng.api.storage.data.IAEItemStack;
|
import appeng.api.storage.data.IAEItemStack;
|
||||||
import appeng.api.storage.data.IAEStack;
|
|
||||||
import appeng.api.storage.data.IItemList;
|
import appeng.api.storage.data.IItemList;
|
||||||
import appeng.api.util.AECableType;
|
import appeng.api.util.AECableType;
|
||||||
import appeng.api.util.AEPartLocation;
|
import appeng.api.util.AEPartLocation;
|
||||||
@@ -112,7 +111,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
|||||||
private int priority = 0;
|
private int priority = 0;
|
||||||
private boolean cached = false;
|
private boolean cached = false;
|
||||||
private ITickingMonitor monitor = null;
|
private ITickingMonitor monitor = null;
|
||||||
private MEInventoryHandler<? extends IAEStack> handler = null;
|
private MEInventoryHandler<IAEItemStack> handler = null;
|
||||||
private int handlerHash = 0;
|
private int handlerHash = 0;
|
||||||
private boolean wasActive = false;
|
private boolean wasActive = false;
|
||||||
private byte resetCacheLogic = 0;
|
private byte resetCacheLogic = 0;
|
||||||
@@ -355,22 +354,18 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
|||||||
|
|
||||||
final IMEInventory<IAEItemStack> out = this.getInternalHandler();
|
final IMEInventory<IAEItemStack> out = this.getInternalHandler();
|
||||||
|
|
||||||
if( this.monitor != null )
|
if( in != out )
|
||||||
{
|
{
|
||||||
this.monitor.onTick();
|
IItemList<IAEItemStack> after = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||||
|
if( out != null )
|
||||||
|
{
|
||||||
|
after = out.getAvailableItems( after );
|
||||||
|
}
|
||||||
|
Platform.postListChanges( before, after, this, this.mySrc );
|
||||||
}
|
}
|
||||||
|
|
||||||
IItemList<IAEItemStack> after = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
|
||||||
if( out != null )
|
|
||||||
{
|
|
||||||
after = out.getAvailableItems( after );
|
|
||||||
}
|
|
||||||
|
|
||||||
Platform.postListChanges( before, after, this, this.mySrc );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings( "unchecked" )
|
private IMEInventory<IAEItemStack> getInventoryWrapper( TileEntity target )
|
||||||
private IMEInventory<? extends IAEItemStack> getInventoryWrapper( TileEntity target )
|
|
||||||
{
|
{
|
||||||
|
|
||||||
EnumFacing targetSide = this.getSide().getFacing().getOpposite();
|
EnumFacing targetSide = this.getSide().getFacing().getOpposite();
|
||||||
@@ -397,7 +392,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
|||||||
IItemHandler handlerExt = target.getCapability( CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, targetSide );
|
IItemHandler handlerExt = target.getCapability( CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, targetSide );
|
||||||
if( handlerExt != null )
|
if( handlerExt != null )
|
||||||
{
|
{
|
||||||
return new ItemHandlerAdapter( handlerExt );
|
return new ItemHandlerAdapter( handlerExt, this );
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -428,7 +423,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MEInventoryHandler getInternalHandler()
|
public MEInventoryHandler<IAEItemStack> getInternalHandler()
|
||||||
{
|
{
|
||||||
if( this.cached )
|
if( this.cached )
|
||||||
{
|
{
|
||||||
@@ -452,7 +447,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
|||||||
this.monitor = null;
|
this.monitor = null;
|
||||||
if( target != null )
|
if( target != null )
|
||||||
{
|
{
|
||||||
IMEInventory<? extends IAEStack> inv = this.getInventoryWrapper( target );
|
IMEInventory<IAEItemStack> inv = this.getInventoryWrapper( target );
|
||||||
|
|
||||||
if( inv instanceof MEMonitorIInventory )
|
if( inv instanceof MEMonitorIInventory )
|
||||||
{
|
{
|
||||||
@@ -470,7 +465,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
|||||||
{
|
{
|
||||||
this.checkInterfaceVsStorageBus( target, this.getSide().getOpposite() );
|
this.checkInterfaceVsStorageBus( target, this.getSide().getOpposite() );
|
||||||
|
|
||||||
this.handler = new MEInventoryHandler( inv, AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
|
this.handler = new MEInventoryHandler<IAEItemStack>( inv, AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
|
||||||
|
|
||||||
this.handler.setBaseAccess( (AccessRestriction) this.getConfigManager().getSetting( Settings.ACCESS ) );
|
this.handler.setBaseAccess( (AccessRestriction) this.getConfigManager().getSetting( Settings.ACCESS ) );
|
||||||
this.handler.setWhitelist( this.getInstalledUpgrades( Upgrades.INVERTER ) > 0 ? IncludeExclude.BLACKLIST : IncludeExclude.WHITELIST );
|
this.handler.setWhitelist( this.getInstalledUpgrades( Upgrades.INVERTER ) > 0 ? IncludeExclude.BLACKLIST : IncludeExclude.WHITELIST );
|
||||||
@@ -491,16 +486,17 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
|||||||
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
|
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
|
||||||
{
|
{
|
||||||
this.handler
|
this.handler
|
||||||
.setPartitionList( new FuzzyPriorityList( priorityList, (FuzzyMode) this.getConfigManager().getSetting( Settings.FUZZY_MODE ) ) );
|
.setPartitionList( new FuzzyPriorityList<IAEItemStack>( priorityList, (FuzzyMode) this.getConfigManager()
|
||||||
|
.getSetting( Settings.FUZZY_MODE ) ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.handler.setPartitionList( new PrecisePriorityList( priorityList ) );
|
this.handler.setPartitionList( new PrecisePriorityList<IAEItemStack>( priorityList ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( inv instanceof IBaseMonitor )
|
if( inv instanceof IBaseMonitor )
|
||||||
{
|
{
|
||||||
( (IBaseMonitor) inv ).addListener( this, this.handler );
|
( (IBaseMonitor<IAEItemStack>) inv ).addListener( this, this.handler );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -570,7 +566,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
|
|||||||
{
|
{
|
||||||
if( channel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
|
if( channel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
|
||||||
{
|
{
|
||||||
final IMEInventoryHandler out = this.getProxy().isActive() ? this.getInternalHandler() : null;
|
final IMEInventoryHandler<IAEItemStack> out = this.getProxy().isActive() ? this.getInternalHandler() : null;
|
||||||
if( out != null )
|
if( out != null )
|
||||||
{
|
{
|
||||||
return Collections.singletonList( out );
|
return Collections.singletonList( out );
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import appeng.api.parts.IPartHost;
|
|||||||
import appeng.api.parts.IPartModel;
|
import appeng.api.parts.IPartModel;
|
||||||
import appeng.api.util.AECableType;
|
import appeng.api.util.AECableType;
|
||||||
import appeng.api.util.AEPartLocation;
|
import appeng.api.util.AEPartLocation;
|
||||||
|
import appeng.core.AELog;
|
||||||
import appeng.core.AppEng;
|
import appeng.core.AppEng;
|
||||||
import appeng.helpers.Reflected;
|
import appeng.helpers.Reflected;
|
||||||
import appeng.items.parts.PartModels;
|
import appeng.items.parts.PartModels;
|
||||||
@@ -208,6 +209,7 @@ public class PartToggleBus extends PartBasicState
|
|||||||
catch( final FailedConnectionException e )
|
catch( final FailedConnectionException e )
|
||||||
{
|
{
|
||||||
// :(
|
// :(
|
||||||
|
AELog.debug( e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -247,6 +247,8 @@ public class PartP2PTunnelME extends PartP2PTunnel<PartP2PTunnelME> implements I
|
|||||||
{
|
{
|
||||||
final TileEntity start = this.getTile();
|
final TileEntity start = this.getTile();
|
||||||
final TileEntity end = me.getTile();
|
final TileEntity end = me.getTile();
|
||||||
|
|
||||||
|
AELog.debug( e );
|
||||||
|
|
||||||
AELog.warn( "Failed to establish a ME P2P Tunnel between the tunnels at [x=%d, y=%d, z=%d] and [x=%d, y=%d, z=%d]",
|
AELog.warn( "Failed to establish a ME P2P Tunnel between the tunnels at [x=%d, y=%d, z=%d] and [x=%d, y=%d, z=%d]",
|
||||||
start.getPos().getX(), start.getPos().getY(), start.getPos().getZ(), end.getPos().getX(), end.getPos().getY(),
|
start.getPos().getX(), start.getPos().getY(), start.getPos().getZ(), end.getPos().getX(), end.getPos().getY(),
|
||||||
|
|||||||
@@ -19,19 +19,34 @@
|
|||||||
package appeng.recipes.factories.recipes;
|
package appeng.recipes.factories.recipes;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
import com.google.gson.JsonSyntaxException;
|
import com.google.gson.JsonSyntaxException;
|
||||||
|
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.crafting.IRecipe;
|
import net.minecraft.item.crafting.IRecipe;
|
||||||
|
import net.minecraft.item.crafting.Ingredient;
|
||||||
import net.minecraft.util.JsonUtils;
|
import net.minecraft.util.JsonUtils;
|
||||||
|
import net.minecraft.util.NonNullList;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraftforge.common.crafting.CraftingHelper;
|
import net.minecraftforge.common.crafting.CraftingHelper;
|
||||||
import net.minecraftforge.common.crafting.IRecipeFactory;
|
import net.minecraftforge.common.crafting.IRecipeFactory;
|
||||||
import net.minecraftforge.common.crafting.JsonContext;
|
import net.minecraftforge.common.crafting.JsonContext;
|
||||||
|
import net.minecraftforge.oredict.ShapedOreRecipe;
|
||||||
|
import net.minecraftforge.oredict.ShapelessOreRecipe;
|
||||||
|
|
||||||
|
import appeng.api.recipes.ResolverResult;
|
||||||
|
import appeng.core.AELog;
|
||||||
|
import appeng.core.Api;
|
||||||
import appeng.core.AppEng;
|
import appeng.core.AppEng;
|
||||||
import appeng.recipes.helpers.PartShapedCraftingFactory;
|
|
||||||
import appeng.recipes.helpers.PartShapelessCraftingFactory;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -45,25 +60,149 @@ public class PartRecipeFactory implements IRecipeFactory
|
|||||||
String type = JsonUtils.getString( json, "type" );
|
String type = JsonUtils.getString( json, "type" );
|
||||||
if( type.contains( "shaped" ) )
|
if( type.contains( "shaped" ) )
|
||||||
{
|
{
|
||||||
PartShapedCraftingFactory recipe = PartShapedCraftingFactory.factory( context, json );
|
return shapedFactory( context, json );
|
||||||
CraftingHelper.ShapedPrimer primer = new CraftingHelper.ShapedPrimer();
|
|
||||||
primer.width = recipe.getWidth();
|
|
||||||
primer.height = recipe.getHeight();
|
|
||||||
primer.mirrored = JsonUtils.getBoolean( json, "mirrored", true );
|
|
||||||
primer.input = recipe.getIngredients();
|
|
||||||
|
|
||||||
return new PartShapedCraftingFactory( new ResourceLocation( AppEng.MOD_ID, "part_shaped_crafting" ), recipe.getRecipeOutput(), primer );
|
|
||||||
}
|
}
|
||||||
else if( type.contains( "shapeless" ) )
|
else if( type.contains( "shapeless" ) )
|
||||||
{
|
{
|
||||||
PartShapelessCraftingFactory recipe = PartShapelessCraftingFactory.factory( context, json );
|
return shapelessFactory( context, json );
|
||||||
|
|
||||||
return new PartShapelessCraftingFactory( new ResourceLocation( AppEng.MOD_ID, "part_shapeless_crafting" ), recipe.getIngredients(), recipe
|
|
||||||
.getRecipeOutput() );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new JsonSyntaxException( "Applied Energistics 2 was given a custom recipe that it does not know how to handle!\n" + "Type should either be '" + AppEng.MOD_ID + ":shapeless' or '" + AppEng.MOD_ID + ":shaped', got '" + type + "'!" );
|
throw new JsonSyntaxException( "Applied Energistics 2 was given a custom recipe that it does not know how to handle!\n" + "Type should either be '" + AppEng.MOD_ID + ":shapeless' or '" + AppEng.MOD_ID + ":shaped', got '" + type + "'!" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copied from ShapedOreRecipe.java, modified a bit.
|
||||||
|
private static ShapedOreRecipe shapedFactory( JsonContext context, JsonObject json )
|
||||||
|
{
|
||||||
|
String group = JsonUtils.getString( json, "group", "" );
|
||||||
|
|
||||||
|
Map<Character, Ingredient> ingMap = Maps.newHashMap();
|
||||||
|
for( Map.Entry<String, JsonElement> entry : JsonUtils.getJsonObject( json, "key" ).entrySet() )
|
||||||
|
{
|
||||||
|
if( entry.getKey().length() != 1 )
|
||||||
|
{
|
||||||
|
throw new JsonSyntaxException( "Invalid key entry: '" + entry.getKey() + "' is an invalid symbol (must be 1 character only)." );
|
||||||
|
}
|
||||||
|
if( " ".equals( entry.getKey() ) )
|
||||||
|
{
|
||||||
|
throw new JsonSyntaxException( "Invalid key entry: ' ' is a reserved symbol." );
|
||||||
|
}
|
||||||
|
|
||||||
|
ingMap.put( entry.getKey().toCharArray()[0], CraftingHelper.getIngredient( entry.getValue(), context ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
ingMap.put( ' ', net.minecraft.item.crafting.Ingredient.EMPTY );
|
||||||
|
|
||||||
|
JsonArray patternJ = JsonUtils.getJsonArray( json, "pattern" );
|
||||||
|
|
||||||
|
if( patternJ.size() == 0 )
|
||||||
|
{
|
||||||
|
throw new JsonSyntaxException( "Invalid pattern: empty pattern not allowed" );
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] pattern = new String[patternJ.size()];
|
||||||
|
for( int x = 0; x < pattern.length; ++x )
|
||||||
|
{
|
||||||
|
String line = JsonUtils.getString( patternJ.get( x ), "pattern[" + x + "]" );
|
||||||
|
if( x > 0 && pattern[0].length() != line.length() )
|
||||||
|
{
|
||||||
|
throw new JsonSyntaxException( "Invalid pattern: each row must be the same width" );
|
||||||
|
}
|
||||||
|
pattern[x] = line;
|
||||||
|
}
|
||||||
|
|
||||||
|
CraftingHelper.ShapedPrimer primer = new CraftingHelper.ShapedPrimer();
|
||||||
|
primer.width = pattern[0].length();
|
||||||
|
primer.height = pattern.length;
|
||||||
|
primer.mirrored = JsonUtils.getBoolean( json, "mirrored", true );
|
||||||
|
primer.input = NonNullList.withSize( primer.width * primer.height, net.minecraft.item.crafting.Ingredient.EMPTY );
|
||||||
|
|
||||||
|
Set<Character> keys = Sets.newHashSet( ingMap.keySet() );
|
||||||
|
keys.remove( ' ' );
|
||||||
|
|
||||||
|
int x = 0;
|
||||||
|
for( String line : pattern )
|
||||||
|
{
|
||||||
|
for( char chr : line.toCharArray() )
|
||||||
|
{
|
||||||
|
net.minecraft.item.crafting.Ingredient ing = ingMap.get( chr );
|
||||||
|
if( ing == null )
|
||||||
|
{
|
||||||
|
throw new JsonSyntaxException( "Pattern references symbol '" + chr + "' but it's not defined in the key" );
|
||||||
|
}
|
||||||
|
primer.input.set( x++, ing );
|
||||||
|
keys.remove( chr );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !keys.isEmpty() )
|
||||||
|
{
|
||||||
|
throw new JsonSyntaxException( "Key defines symbols that aren't used in pattern: " + keys );
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject resultObject = (JsonObject) json.get( "result" );
|
||||||
|
int count = JsonUtils.getInt( resultObject, "count", 1 );
|
||||||
|
|
||||||
|
String ingredient = resultObject.get( "part" ).getAsString();
|
||||||
|
Object result = (Object) Api.INSTANCE.registries().recipes().resolveItem( AppEng.MOD_ID, ingredient );
|
||||||
|
if( result instanceof ResolverResult )
|
||||||
|
{
|
||||||
|
ResolverResult resolverResult = (ResolverResult) result;
|
||||||
|
|
||||||
|
Item item = Item.getByNameOrId( AppEng.MOD_ID + ":" + resolverResult.itemName );
|
||||||
|
if( item == null )
|
||||||
|
{
|
||||||
|
AELog.warn( "item was null for " + resolverResult.itemName + " ( " + ingredient + " )!" );
|
||||||
|
throw new JsonSyntaxException( "Got a null item for " + resolverResult.itemName + " ( " + ingredient + " ). This should never happen!" );
|
||||||
|
}
|
||||||
|
ItemStack itemStack = new ItemStack( item, count, resolverResult.damageValue, resolverResult.compound );
|
||||||
|
|
||||||
|
return new ShapedOreRecipe( group.isEmpty() ? null : new ResourceLocation( group ), itemStack, primer );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should never reach this part unless mangled JSON or bug in AE.
|
||||||
|
throw new JsonSyntaxException( "Couldn't find the resulting item in AE. This means AE was provided a recipe that it shouldn't be handling.\nWas looking for : '" + ingredient + "'." );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copied from ShapelessOreRecipe.java, modified a bit.
|
||||||
|
private static ShapelessOreRecipe shapelessFactory( JsonContext context, JsonObject json )
|
||||||
|
{
|
||||||
|
String group = JsonUtils.getString( json, "group", "" );
|
||||||
|
|
||||||
|
NonNullList<Ingredient> ings = NonNullList.create();
|
||||||
|
for( JsonElement ele : JsonUtils.getJsonArray( json, "ingredients" ) )
|
||||||
|
{
|
||||||
|
ings.add( CraftingHelper.getIngredient( ele, context ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ings.isEmpty() )
|
||||||
|
{
|
||||||
|
throw new JsonParseException( "No ingredients for shapeless recipe" );
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject resultObject = (JsonObject) json.get( "result" );
|
||||||
|
int count = JsonUtils.getInt( resultObject, "count", 1 );
|
||||||
|
|
||||||
|
String ingredient = resultObject.get( "part" ).getAsString();
|
||||||
|
Object result = (Object) Api.INSTANCE.registries().recipes().resolveItem( AppEng.MOD_ID, ingredient );
|
||||||
|
if( result instanceof ResolverResult )
|
||||||
|
{
|
||||||
|
ResolverResult resolverResult = (ResolverResult) result;
|
||||||
|
|
||||||
|
Item item = Item.getByNameOrId( AppEng.MOD_ID + ":" + resolverResult.itemName );
|
||||||
|
|
||||||
|
if( item == null )
|
||||||
|
{
|
||||||
|
AELog.warn( "item was null for " + resolverResult.itemName + " ( " + ingredient + " )!" );
|
||||||
|
throw new JsonSyntaxException( "Got a null item for " + resolverResult.itemName + " ( " + ingredient + " ). This should never happen!" );
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack itemStack = new ItemStack( item, count, resolverResult.damageValue, resolverResult.compound );
|
||||||
|
|
||||||
|
return new ShapelessOreRecipe( group.isEmpty() ? null : new ResourceLocation( group ), ings, itemStack );
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new JsonSyntaxException( "Couldn't find the resulting item in AE. This means AE was provided a recipe that it shouldn't be handling.\n" + "Was looking for : '" + ingredient + "'." );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,153 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Applied Energistics 2.
|
|
||||||
* Copyright (c) 2013 - 2017, AlgorithmX2, All rights reserved.
|
|
||||||
*
|
|
||||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package appeng.recipes.helpers;
|
|
||||||
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonSyntaxException;
|
|
||||||
|
|
||||||
import net.minecraft.item.Item;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.item.crafting.Ingredient;
|
|
||||||
import net.minecraft.util.JsonUtils;
|
|
||||||
import net.minecraft.util.NonNullList;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
import net.minecraftforge.common.crafting.CraftingHelper;
|
|
||||||
import net.minecraftforge.common.crafting.JsonContext;
|
|
||||||
import net.minecraftforge.oredict.ShapedOreRecipe;
|
|
||||||
|
|
||||||
import appeng.api.recipes.ResolverResult;
|
|
||||||
import appeng.core.AELog;
|
|
||||||
import appeng.core.Api;
|
|
||||||
import appeng.core.AppEng;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author GuntherDW
|
|
||||||
*/
|
|
||||||
public class PartShapedCraftingFactory extends ShapedOreRecipe
|
|
||||||
{
|
|
||||||
|
|
||||||
public PartShapedCraftingFactory( ResourceLocation group, @Nonnull ItemStack result, CraftingHelper.ShapedPrimer primer )
|
|
||||||
{
|
|
||||||
super( group, result, primer );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copied from ShapedOreRecipe.java, modified a bit.
|
|
||||||
public static PartShapedCraftingFactory factory( JsonContext context, JsonObject json )
|
|
||||||
{
|
|
||||||
String group = JsonUtils.getString( json, "group", "" );
|
|
||||||
|
|
||||||
Map<Character, Ingredient> ingMap = Maps.newHashMap();
|
|
||||||
for( Map.Entry<String, JsonElement> entry : JsonUtils.getJsonObject( json, "key" ).entrySet() )
|
|
||||||
{
|
|
||||||
if( entry.getKey().length() != 1 )
|
|
||||||
{
|
|
||||||
throw new JsonSyntaxException( "Invalid key entry: '" + entry.getKey() + "' is an invalid symbol (must be 1 character only)." );
|
|
||||||
}
|
|
||||||
if( " ".equals( entry.getKey() ) )
|
|
||||||
{
|
|
||||||
throw new JsonSyntaxException( "Invalid key entry: ' ' is a reserved symbol." );
|
|
||||||
}
|
|
||||||
|
|
||||||
ingMap.put( entry.getKey().toCharArray()[0], CraftingHelper.getIngredient( entry.getValue(), context ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
ingMap.put( ' ', net.minecraft.item.crafting.Ingredient.EMPTY );
|
|
||||||
|
|
||||||
JsonArray patternJ = JsonUtils.getJsonArray( json, "pattern" );
|
|
||||||
|
|
||||||
if( patternJ.size() == 0 )
|
|
||||||
{
|
|
||||||
throw new JsonSyntaxException( "Invalid pattern: empty pattern not allowed" );
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] pattern = new String[patternJ.size()];
|
|
||||||
for( int x = 0; x < pattern.length; ++x )
|
|
||||||
{
|
|
||||||
String line = JsonUtils.getString( patternJ.get( x ), "pattern[" + x + "]" );
|
|
||||||
if( x > 0 && pattern[0].length() != line.length() )
|
|
||||||
{
|
|
||||||
throw new JsonSyntaxException( "Invalid pattern: each row must be the same width" );
|
|
||||||
}
|
|
||||||
pattern[x] = line;
|
|
||||||
}
|
|
||||||
|
|
||||||
CraftingHelper.ShapedPrimer primer = new CraftingHelper.ShapedPrimer();
|
|
||||||
primer.width = pattern[0].length();
|
|
||||||
primer.height = pattern.length;
|
|
||||||
primer.mirrored = JsonUtils.getBoolean( json, "mirrored", true );
|
|
||||||
primer.input = NonNullList.withSize( primer.width * primer.height, net.minecraft.item.crafting.Ingredient.EMPTY );
|
|
||||||
|
|
||||||
Set<Character> keys = Sets.newHashSet( ingMap.keySet() );
|
|
||||||
keys.remove( ' ' );
|
|
||||||
|
|
||||||
int x = 0;
|
|
||||||
for( String line : pattern )
|
|
||||||
{
|
|
||||||
for( char chr : line.toCharArray() )
|
|
||||||
{
|
|
||||||
net.minecraft.item.crafting.Ingredient ing = ingMap.get( chr );
|
|
||||||
if( ing == null )
|
|
||||||
{
|
|
||||||
throw new JsonSyntaxException( "Pattern references symbol '" + chr + "' but it's not defined in the key" );
|
|
||||||
}
|
|
||||||
primer.input.set( x++, ing );
|
|
||||||
keys.remove( chr );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !keys.isEmpty() )
|
|
||||||
{
|
|
||||||
throw new JsonSyntaxException( "Key defines symbols that aren't used in pattern: " + keys );
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonObject resultObject = (JsonObject) json.get( "result" );
|
|
||||||
int count = JsonUtils.getInt( resultObject, "count", 1 );
|
|
||||||
|
|
||||||
String ingredient = resultObject.get( "part" ).getAsString();
|
|
||||||
Object result = (Object) Api.INSTANCE.registries().recipes().resolveItem( AppEng.MOD_ID, ingredient );
|
|
||||||
if( result instanceof ResolverResult )
|
|
||||||
{
|
|
||||||
ResolverResult resolverResult = (ResolverResult) result;
|
|
||||||
|
|
||||||
Item item = Item.getByNameOrId( AppEng.MOD_ID + ":" + resolverResult.itemName );
|
|
||||||
if( item == null )
|
|
||||||
{
|
|
||||||
AELog.warn( "item was null for " + resolverResult.itemName + " ( " + ingredient + " )!" );
|
|
||||||
throw new JsonSyntaxException( "Got a null item for " + resolverResult.itemName + " ( " + ingredient + " ). This should never happen!" );
|
|
||||||
}
|
|
||||||
ItemStack itemStack = new ItemStack( item, count, resolverResult.damageValue, resolverResult.compound );
|
|
||||||
|
|
||||||
return new PartShapedCraftingFactory( group.isEmpty() ? null : new ResourceLocation( group ), itemStack, primer );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Should never reach this part unless mangled JSON or bug in AE.
|
|
||||||
throw new JsonSyntaxException( "Couldn't find the resulting item in AE. This means AE was provided a recipe that it shouldn't be handling.\nWas looking for : '" + ingredient + "'." );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Applied Energistics 2.
|
|
||||||
* Copyright (c) 2013 - 2017, AlgorithmX2, All rights reserved.
|
|
||||||
*
|
|
||||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package appeng.recipes.helpers;
|
|
||||||
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonParseException;
|
|
||||||
import com.google.gson.JsonSyntaxException;
|
|
||||||
|
|
||||||
import net.minecraft.item.Item;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.item.crafting.Ingredient;
|
|
||||||
import net.minecraft.util.JsonUtils;
|
|
||||||
import net.minecraft.util.NonNullList;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
import net.minecraftforge.common.crafting.CraftingHelper;
|
|
||||||
import net.minecraftforge.common.crafting.JsonContext;
|
|
||||||
import net.minecraftforge.oredict.ShapelessOreRecipe;
|
|
||||||
|
|
||||||
import appeng.api.recipes.ResolverResult;
|
|
||||||
import appeng.core.AELog;
|
|
||||||
import appeng.core.Api;
|
|
||||||
import appeng.core.AppEng;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author GuntherDW
|
|
||||||
*/
|
|
||||||
public class PartShapelessCraftingFactory extends ShapelessOreRecipe
|
|
||||||
{
|
|
||||||
|
|
||||||
public PartShapelessCraftingFactory( ResourceLocation group, NonNullList<Ingredient> input, @Nonnull ItemStack result )
|
|
||||||
{
|
|
||||||
super( group, input, result );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copied from ShapelessOreRecipe.java, modified a bit.
|
|
||||||
public static PartShapelessCraftingFactory factory( JsonContext context, JsonObject json )
|
|
||||||
{
|
|
||||||
String group = JsonUtils.getString( json, "group", "" );
|
|
||||||
|
|
||||||
NonNullList<Ingredient> ings = NonNullList.create();
|
|
||||||
for( JsonElement ele : JsonUtils.getJsonArray( json, "ingredients" ) )
|
|
||||||
{
|
|
||||||
ings.add( CraftingHelper.getIngredient( ele, context ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( ings.isEmpty() )
|
|
||||||
{
|
|
||||||
throw new JsonParseException( "No ingredients for shapeless recipe" );
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonObject resultObject = (JsonObject) json.get( "result" );
|
|
||||||
int count = JsonUtils.getInt( resultObject, "count", 1 );
|
|
||||||
|
|
||||||
String ingredient = resultObject.get( "part" ).getAsString();
|
|
||||||
Object result = (Object) Api.INSTANCE.registries().recipes().resolveItem( AppEng.MOD_ID, ingredient );
|
|
||||||
if( result instanceof ResolverResult )
|
|
||||||
{
|
|
||||||
ResolverResult resolverResult = (ResolverResult) result;
|
|
||||||
|
|
||||||
Item item = Item.getByNameOrId( AppEng.MOD_ID + ":" + resolverResult.itemName );
|
|
||||||
|
|
||||||
if( item == null )
|
|
||||||
{
|
|
||||||
AELog.warn( "item was null for " + resolverResult.itemName + " ( " + ingredient + " )!" );
|
|
||||||
throw new JsonSyntaxException( "Got a null item for " + resolverResult.itemName + " ( " + ingredient + " ). This should never happen!" );
|
|
||||||
}
|
|
||||||
|
|
||||||
ItemStack itemStack = new ItemStack( item, count, resolverResult.damageValue, resolverResult.compound );
|
|
||||||
|
|
||||||
return new PartShapelessCraftingFactory( group.isEmpty() ? null : new ResourceLocation( group ), ings, itemStack );
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new JsonSyntaxException( "Couldn't find the resulting item in AE. This means AE was provided a recipe that it shouldn't be handling.\n" + "Was looking for : '" + ingredient + "'." );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -27,7 +27,7 @@ public class BiomeGenStorage extends Biome
|
|||||||
|
|
||||||
public BiomeGenStorage()
|
public BiomeGenStorage()
|
||||||
{
|
{
|
||||||
super( new BiomeProperties( "Storage Cell" ).setRainDisabled().setTemperature( -100 ) );
|
super( new BiomeProperties( "Storage Cell" ).setBaseBiome( "void" ).setRainDisabled().setTemperature( -100 ) );
|
||||||
|
|
||||||
this.decorator.treesPerChunk = 0;
|
this.decorator.treesPerChunk = 0;
|
||||||
this.decorator.flowersPerChunk = 0;
|
this.decorator.flowersPerChunk = 0;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import java.util.Map.Entry;
|
|||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.ITickable;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.NextTickListEntry;
|
import net.minecraft.world.NextTickListEntry;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
@@ -34,7 +35,6 @@ import net.minecraft.world.chunk.Chunk;
|
|||||||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||||
|
|
||||||
import appeng.api.AEApi;
|
import appeng.api.AEApi;
|
||||||
import appeng.api.definitions.IBlockDefinition;
|
|
||||||
import appeng.api.movable.IMovableHandler;
|
import appeng.api.movable.IMovableHandler;
|
||||||
import appeng.api.movable.IMovableRegistry;
|
import appeng.api.movable.IMovableRegistry;
|
||||||
import appeng.api.util.AEPartLocation;
|
import appeng.api.util.AEPartLocation;
|
||||||
@@ -61,7 +61,6 @@ public class CachedPlane
|
|||||||
private final World world;
|
private final World world;
|
||||||
private final IMovableRegistry reg = AEApi.instance().registries().movable();
|
private final IMovableRegistry reg = AEApi.instance().registries().movable();
|
||||||
private final LinkedList<WorldCoord> updates = new LinkedList<>();
|
private final LinkedList<WorldCoord> updates = new LinkedList<>();
|
||||||
private final IBlockDefinition matrixFrame = AEApi.instance().definitions().blocks().matrixFrame();
|
|
||||||
private int verticalBits;
|
private int verticalBits;
|
||||||
private final IBlockState matrixBlockState;
|
private final IBlockState matrixBlockState;
|
||||||
|
|
||||||
@@ -146,11 +145,11 @@ public class CachedPlane
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
final Object[] details = this.myColumns[tePOS.getX() - minX][tePOS.getZ() - minZ].getDetails( tePOS.getY() );
|
final BlockStorageData details = new BlockStorageData();
|
||||||
final IBlockState blkState = (IBlockState) details[0];
|
this.myColumns[tePOS.getX() - minX][tePOS.getZ() - minZ].fillData( tePOS.getY(), details );
|
||||||
|
|
||||||
// don't skip air, just let the code replace it...
|
// don't skip air, just let the code replace it...
|
||||||
if( blkState != null && blkState.getBlock() == Platform.AIR_BLOCK && blkState.getMaterial().isReplaceable() )
|
if( details.state != null && details.state.getBlock() == Platform.AIR_BLOCK && details.state.getMaterial().isReplaceable() )
|
||||||
{
|
{
|
||||||
w.setBlockToAir( tePOS );
|
w.setBlockToAir( tePOS );
|
||||||
}
|
}
|
||||||
@@ -168,12 +167,11 @@ public class CachedPlane
|
|||||||
}
|
}
|
||||||
|
|
||||||
final long k = this.getWorld().getTotalWorldTime();
|
final long k = this.getWorld().getTotalWorldTime();
|
||||||
final List list = this.getWorld().getPendingBlockUpdates( c, false );
|
final List<NextTickListEntry> list = this.getWorld().getPendingBlockUpdates( c, false );
|
||||||
if( list != null )
|
if( list != null )
|
||||||
{
|
{
|
||||||
for( final Object o : list )
|
for( final NextTickListEntry entry : list )
|
||||||
{
|
{
|
||||||
final NextTickListEntry entry = (NextTickListEntry) o;
|
|
||||||
final BlockPos tePOS = entry.position;
|
final BlockPos tePOS = entry.position;
|
||||||
if( tePOS.getX() >= minX && tePOS.getX() <= maxX && tePOS.getY() >= minY && tePOS.getY() <= maxY && tePOS.getZ() >= minZ && tePOS
|
if( tePOS.getX() >= minX && tePOS.getX() <= maxX && tePOS.getY() >= minY && tePOS.getY() <= maxY && tePOS.getZ() >= minZ && tePOS
|
||||||
.getZ() <= maxZ )
|
.getZ() <= maxZ )
|
||||||
@@ -192,6 +190,10 @@ public class CachedPlane
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
this.getWorld().loadedTileEntityList.remove( te );
|
this.getWorld().loadedTileEntityList.remove( te );
|
||||||
|
if( te instanceof ITickable )
|
||||||
|
{
|
||||||
|
this.getWorld().tickableTileEntities.remove( te );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch( final Exception e )
|
catch( final Exception e )
|
||||||
{
|
{
|
||||||
@@ -215,6 +217,8 @@ public class CachedPlane
|
|||||||
AELog.info( "Block Copy Scale: " + this.x_size + ", " + this.y_size + ", " + this.z_size );
|
AELog.info( "Block Copy Scale: " + this.x_size + ", " + this.y_size + ", " + this.z_size );
|
||||||
|
|
||||||
long startTime = System.nanoTime();
|
long startTime = System.nanoTime();
|
||||||
|
final BlockStorageData aD = new BlockStorageData();
|
||||||
|
final BlockStorageData bD = new BlockStorageData();
|
||||||
|
|
||||||
for( int x = 0; x < this.x_size; x++ )
|
for( int x = 0; x < this.x_size; x++ )
|
||||||
{
|
{
|
||||||
@@ -230,8 +234,8 @@ public class CachedPlane
|
|||||||
|
|
||||||
if( a.doNotSkip( src_y ) && b.doNotSkip( dst_y ) )
|
if( a.doNotSkip( src_y ) && b.doNotSkip( dst_y ) )
|
||||||
{
|
{
|
||||||
final Object[] aD = a.getDetails( src_y );
|
a.fillData( src_y, aD );
|
||||||
final Object[] bD = b.getDetails( dst_y );
|
b.fillData( dst_y, bD );
|
||||||
|
|
||||||
a.setBlockIDWithMetadata( src_y, bD );
|
a.setBlockIDWithMetadata( src_y, bD );
|
||||||
b.setBlockIDWithMetadata( dst_y, aD );
|
b.setBlockIDWithMetadata( dst_y, aD );
|
||||||
@@ -386,14 +390,17 @@ public class CachedPlane
|
|||||||
return this.world;
|
return this.world;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class BlockStorageData
|
||||||
|
{
|
||||||
|
public IBlockState state;
|
||||||
|
public int light;
|
||||||
|
}
|
||||||
|
|
||||||
private class Column
|
private class Column
|
||||||
{
|
{
|
||||||
|
|
||||||
private final int x;
|
private final int x;
|
||||||
private final int z;
|
private final int z;
|
||||||
private final Chunk c;
|
private final Chunk c;
|
||||||
private final Object[] ch = { 0, 0 };
|
|
||||||
private final ExtendedBlockStorage[] storage;
|
|
||||||
private List<Integer> skipThese = null;
|
private List<Integer> skipThese = null;
|
||||||
|
|
||||||
public Column( final Chunk chunk, final int x, final int z, final int chunkY, final int chunkHeight )
|
public Column( final Chunk chunk, final int x, final int z, final int chunkY, final int chunkHeight )
|
||||||
@@ -401,44 +408,46 @@ public class CachedPlane
|
|||||||
this.x = x;
|
this.x = x;
|
||||||
this.z = z;
|
this.z = z;
|
||||||
this.c = chunk;
|
this.c = chunk;
|
||||||
this.storage = this.c.getBlockStorageArray();
|
|
||||||
|
final ExtendedBlockStorage[] storage = this.c.getBlockStorageArray();
|
||||||
|
|
||||||
// make sure storage exists before hand...
|
// make sure storage exists before hand...
|
||||||
for( int ay = 0; ay < chunkHeight; ay++ )
|
for( int ay = 0; ay < chunkHeight; ay++ )
|
||||||
{
|
{
|
||||||
final int by = ( ay + chunkY );
|
final int by = ( ay + chunkY );
|
||||||
ExtendedBlockStorage extendedblockstorage = this.storage[by];
|
ExtendedBlockStorage extendedblockstorage = storage[by];
|
||||||
if( extendedblockstorage == null )
|
if( extendedblockstorage == null )
|
||||||
{
|
{
|
||||||
extendedblockstorage = this.storage[by] = new ExtendedBlockStorage( by << 4, !this.c.getWorld().provider.hasSkyLight() );
|
extendedblockstorage = storage[by] = new ExtendedBlockStorage( by << 4, !this.c.getWorld().provider.hasSkyLight() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setBlockIDWithMetadata( final int y, final Object[] blk )
|
private void setBlockIDWithMetadata( final int y, BlockStorageData data )
|
||||||
{
|
{
|
||||||
if( blk[0] == CachedPlane.this.matrixBlockState )
|
if( data.state == CachedPlane.this.matrixBlockState )
|
||||||
{
|
{
|
||||||
blk[0] = Platform.AIR_BLOCK.getDefaultState();
|
data.state = Platform.AIR_BLOCK.getDefaultState();
|
||||||
}
|
}
|
||||||
|
final ExtendedBlockStorage[] storage = this.c.getBlockStorageArray();
|
||||||
final ExtendedBlockStorage extendedBlockStorage = this.storage[y >> 4];
|
final ExtendedBlockStorage extendedBlockStorage = storage[y >> 4];
|
||||||
extendedBlockStorage.set( this.x, y & 15, this.z, (IBlockState) blk[0] );
|
extendedBlockStorage.set( this.x, y & 15, this.z, data.state );
|
||||||
// extendedBlockStorage.setExtBlockID( x, y & 15, z, blk[0] );
|
extendedBlockStorage.setBlockLight( this.x, y & 15, this.z, data.light );
|
||||||
extendedBlockStorage.setBlockLight( this.x, y & 15, this.z, (Integer) blk[1] );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object[] getDetails( final int y )
|
private void fillData( final int y, BlockStorageData data )
|
||||||
{
|
{
|
||||||
final ExtendedBlockStorage extendedblockstorage = this.storage[y >> 4];
|
final ExtendedBlockStorage[] storage = this.c.getBlockStorageArray();
|
||||||
this.ch[0] = extendedblockstorage.get( this.x, y & 15, this.z );
|
final ExtendedBlockStorage extendedblockstorage = storage[y >> 4];
|
||||||
this.ch[1] = extendedblockstorage.getBlockLight( this.x, y & 15, this.z );
|
|
||||||
return this.ch;
|
data.state = extendedblockstorage.get( this.x, y & 15, this.z );
|
||||||
|
data.light = extendedblockstorage.getBlockLight( this.x, y & 15, this.z );
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean doNotSkip( final int y )
|
private boolean doNotSkip( final int y )
|
||||||
{
|
{
|
||||||
final ExtendedBlockStorage extendedblockstorage = this.storage[y >> 4];
|
final ExtendedBlockStorage[] storage = this.c.getBlockStorageArray();
|
||||||
|
final ExtendedBlockStorage extendedblockstorage = storage[y >> 4];
|
||||||
if( CachedPlane.this.reg.isBlacklisted( extendedblockstorage.get( this.x, y & 15, this.z ).getBlock() ) )
|
if( CachedPlane.this.reg.isBlacklisted( extendedblockstorage.get( this.x, y & 15, this.z ).getBlock() ) )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
package appeng.spatial;
|
package appeng.spatial;
|
||||||
|
|
||||||
|
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
@@ -54,8 +55,9 @@ public class DefaultSpatialHandler implements IMovableHandler
|
|||||||
|
|
||||||
if( c.isLoaded() )
|
if( c.isLoaded() )
|
||||||
{
|
{
|
||||||
|
final IBlockState state = w.getBlockState( newPosition );
|
||||||
w.addTileEntity( te );
|
w.addTileEntity( te );
|
||||||
w.notifyBlockUpdate( newPosition, w.getBlockState( newPosition ), w.getBlockState( newPosition ), 0 );
|
w.notifyBlockUpdate( newPosition, state, state, 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,6 +122,11 @@ public class StorageHelper
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// really remove from world, forge only marks it as removed
|
||||||
|
final boolean wasDead = entity.isDead;
|
||||||
|
oldWorld.removeEntityDangerously( entity );
|
||||||
|
entity.isDead = wasDead;
|
||||||
|
|
||||||
entity.getServer().getPlayerList().transferEntityToWorld( entity, entity.dimension,
|
entity.getServer().getPlayerList().transferEntityToWorld( entity, entity.dimension,
|
||||||
entity.getServer().getWorld( entity.dimension ), (WorldServer) link.dim, new METeleporter( newWorld, link ) );
|
entity.getServer().getWorld( entity.dimension ), (WorldServer) link.dim, new METeleporter( newWorld, link ) );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ public class AppEngInternalAEInventory implements IInternalItemHandler, Iterable
|
|||||||
private final IAEItemStack[] inv;
|
private final IAEItemStack[] inv;
|
||||||
private final int size;
|
private final int size;
|
||||||
private int maxStack;
|
private int maxStack;
|
||||||
|
private boolean dirtyFlag = false;
|
||||||
|
|
||||||
public AppEngInternalAEInventory( final IAEAppEngInventory te, final int s )
|
public AppEngInternalAEInventory( final IAEAppEngInventory te, final int s )
|
||||||
{
|
{
|
||||||
@@ -252,8 +253,10 @@ public class AppEngInternalAEInventory implements IInternalItemHandler, Iterable
|
|||||||
{
|
{
|
||||||
if( this.te != null && Platform.isServer() )
|
if( this.te != null && Platform.isServer() )
|
||||||
{
|
{
|
||||||
|
this.dirtyFlag = true;
|
||||||
this.te.onChangeInventory( this, slot, op, removed, inserted );
|
this.te.onChangeInventory( this, slot, op, removed, inserted );
|
||||||
this.te.saveChanges();
|
this.te.saveChanges();
|
||||||
|
this.dirtyFlag = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,6 +286,9 @@ public class AppEngInternalAEInventory implements IInternalItemHandler, Iterable
|
|||||||
@Override
|
@Override
|
||||||
public void markDirty( int slot )
|
public void markDirty( int slot )
|
||||||
{
|
{
|
||||||
this.fireOnChangeInventory( slot, InvOperation.DIRTY, ItemStack.EMPTY, ItemStack.EMPTY );
|
if( !this.dirtyFlag )
|
||||||
|
{
|
||||||
|
this.fireOnChangeInventory( slot, InvOperation.DIRTY, ItemStack.EMPTY, ItemStack.EMPTY );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ public class AppEngInternalInventory extends ItemStackHandler implements IIntern
|
|||||||
private final int[] maxStack;
|
private final int[] maxStack;
|
||||||
private ItemStack previousStack = ItemStack.EMPTY;
|
private ItemStack previousStack = ItemStack.EMPTY;
|
||||||
private IAEItemFilter filter;
|
private IAEItemFilter filter;
|
||||||
|
private boolean dirtyFlag = false;
|
||||||
|
|
||||||
public AppEngInternalInventory( final IAEAppEngInventory inventory, final int size, final int maxStack, IAEItemFilter filter )
|
public AppEngInternalInventory( final IAEAppEngInventory inventory, final int size, final int maxStack, IAEItemFilter filter )
|
||||||
{
|
{
|
||||||
@@ -118,6 +119,7 @@ public class AppEngInternalInventory extends ItemStackHandler implements IIntern
|
|||||||
{
|
{
|
||||||
if( this.getTileEntity() != null && this.eventsEnabled() )
|
if( this.getTileEntity() != null && this.eventsEnabled() )
|
||||||
{
|
{
|
||||||
|
this.dirtyFlag = true;
|
||||||
ItemStack newStack = this.getStackInSlot( slot ).copy();
|
ItemStack newStack = this.getStackInSlot( slot ).copy();
|
||||||
ItemStack oldStack = this.previousStack;
|
ItemStack oldStack = this.previousStack;
|
||||||
InvOperation op = InvOperation.SET;
|
InvOperation op = InvOperation.SET;
|
||||||
@@ -141,6 +143,7 @@ public class AppEngInternalInventory extends ItemStackHandler implements IIntern
|
|||||||
this.getTileEntity().onChangeInventory( this, slot, op, oldStack, newStack );
|
this.getTileEntity().onChangeInventory( this, slot, op, oldStack, newStack );
|
||||||
this.getTileEntity().saveChanges();
|
this.getTileEntity().saveChanges();
|
||||||
this.previousStack = ItemStack.EMPTY;
|
this.previousStack = ItemStack.EMPTY;
|
||||||
|
this.dirtyFlag = false;
|
||||||
}
|
}
|
||||||
super.onContentsChanged( slot );
|
super.onContentsChanged( slot );
|
||||||
}
|
}
|
||||||
@@ -158,10 +161,12 @@ public class AppEngInternalInventory extends ItemStackHandler implements IIntern
|
|||||||
@Override
|
@Override
|
||||||
public void markDirty( final int slot )
|
public void markDirty( final int slot )
|
||||||
{
|
{
|
||||||
if( this.getTileEntity() != null && this.eventsEnabled() )
|
if( this.getTileEntity() != null && this.eventsEnabled() && !this.dirtyFlag )
|
||||||
{
|
{
|
||||||
|
this.dirtyFlag = true;
|
||||||
this.getTileEntity().onChangeInventory( this, slot, InvOperation.DIRTY, ItemStack.EMPTY, ItemStack.EMPTY );
|
this.getTileEntity().onChangeInventory( this, slot, InvOperation.DIRTY, ItemStack.EMPTY, ItemStack.EMPTY );
|
||||||
this.getTileEntity().saveChanges();
|
this.getTileEntity().saveChanges();
|
||||||
|
this.dirtyFlag = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -209,8 +209,7 @@ public class TileController extends AENetworkPowerTile
|
|||||||
*/
|
*/
|
||||||
private boolean checkController( final BlockPos pos )
|
private boolean checkController( final BlockPos pos )
|
||||||
{
|
{
|
||||||
final BlockPos ownPos = this.getPos();
|
if( this.world.getChunkProvider().getLoadedChunk( pos.getX() >> 4, pos.getZ() >> 4 ) != null )
|
||||||
if( this.world.getChunkProvider().getLoadedChunk( ownPos.getX() >> 4, ownPos.getZ() >> 4 ) != null )
|
|
||||||
{
|
{
|
||||||
return this.world.getTileEntity( pos ) instanceof TileController;
|
return this.world.getTileEntity( pos ) instanceof TileController;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1296,11 +1296,11 @@ public class Platform
|
|||||||
{
|
{
|
||||||
if( a.getLastSecurityKey() == -1 && b.getLastSecurityKey() == -1 )
|
if( a.getLastSecurityKey() == -1 && b.getLastSecurityKey() == -1 )
|
||||||
{
|
{
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
else if( a.getLastSecurityKey() == b.getLastSecurityKey() )
|
else if( a.getLastSecurityKey() == b.getLastSecurityKey() )
|
||||||
{
|
{
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean a_isSecure = isPowered( a.getGrid() ) && a.getLastSecurityKey() != -1;
|
final boolean a_isSecure = isPowered( a.getGrid() ) && a.getLastSecurityKey() != -1;
|
||||||
@@ -1308,15 +1308,17 @@ public class Platform
|
|||||||
|
|
||||||
if( AEConfig.instance().isFeatureEnabled( AEFeature.LOG_SECURITY_AUDITS ) )
|
if( AEConfig.instance().isFeatureEnabled( AEFeature.LOG_SECURITY_AUDITS ) )
|
||||||
{
|
{
|
||||||
AELog.info(
|
final String locationA = a.getGridBlock().isWorldAccessible() ? a.getGridBlock().getLocation().toString() : "notInWorld";
|
||||||
"Audit: " + a_isSecure + " : " + b_isSecure + " @ " + a.getLastSecurityKey() + " vs " + b.getLastSecurityKey() + " & " + a
|
final String locationB = b.getGridBlock().isWorldAccessible() ? b.getGridBlock().getLocation().toString() : "notInWorld";
|
||||||
.getPlayerID() + " vs " + b.getPlayerID() );
|
|
||||||
|
AELog.info( "Audit: Node A [isSecure=%b, key=%d, playerID=%d, location={%s}] vs Node B[isSecure=%b, key=%d, playerID=%d, location={%s}]",
|
||||||
|
a_isSecure, a.getLastSecurityKey(), a.getPlayerID(), locationA, b_isSecure, b.getLastSecurityKey(), b.getPlayerID(), locationB );
|
||||||
}
|
}
|
||||||
|
|
||||||
// can't do that son...
|
// can't do that son...
|
||||||
if( a_isSecure && b_isSecure )
|
if( a_isSecure && b_isSecure )
|
||||||
{
|
{
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !a_isSecure && b_isSecure )
|
if( !a_isSecure && b_isSecure )
|
||||||
@@ -1329,7 +1331,7 @@ public class Platform
|
|||||||
return checkPlayerPermissions( a.getGrid(), b.getPlayerID() );
|
return checkPlayerPermissions( a.getGrid(), b.getPlayerID() );
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isPowered( final IGrid grid )
|
private static boolean isPowered( final IGrid grid )
|
||||||
@@ -1347,22 +1349,22 @@ public class Platform
|
|||||||
{
|
{
|
||||||
if( grid == null )
|
if( grid == null )
|
||||||
{
|
{
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
final ISecurityGrid gs = grid.getCache( ISecurityGrid.class );
|
final ISecurityGrid gs = grid.getCache( ISecurityGrid.class );
|
||||||
|
|
||||||
if( gs == null )
|
if( gs == null )
|
||||||
{
|
{
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !gs.isAvailable() )
|
if( !gs.isAvailable() )
|
||||||
{
|
{
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !gs.hasPermission( playerID, SecurityPermissions.BUILD );
|
return gs.hasPermission( playerID, SecurityPermissions.BUILD );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void configurePlayer( final EntityPlayer player, final AEPartLocation side, final TileEntity tile )
|
public static void configurePlayer( final EntityPlayer player, final AEPartLocation side, final TileEntity tile )
|
||||||
|
|||||||
Reference in New Issue
Block a user