Applied-Energistics-2-tiler.../src/main/java/appeng/container/AEBaseContainer.java
yueh c9ef1beea1 Refactored the logging
Using LogManager instead of FMLRelaunchLog to access the logger instance.
Added logging of the name of failed exports instead of exception.
Improved crafting log to include issuer including their location and the
requested item.
Removed superfluous FMLRelaunchLog instance.
Removed superfluous parameters for PlayerData constructor.

Closes #2009
Refs #2069
2015-12-26 23:14:29 +01:00

1339 lines
31 KiB
Java

/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, 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.container;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ICrafting;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.config.SecurityPermissions;
import appeng.api.implementations.guiobjects.IGuiItemObject;
import appeng.api.networking.IGrid;
import appeng.api.networking.IGridNode;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.energy.IEnergySource;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.networking.security.IActionHost;
import appeng.api.networking.security.ISecurityGrid;
import appeng.api.networking.security.PlayerSource;
import appeng.api.parts.IPart;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.data.IAEItemStack;
import appeng.client.me.InternalSlotME;
import appeng.client.me.SlotME;
import appeng.container.guisync.GuiSync;
import appeng.container.guisync.SyncData;
import appeng.container.slot.AppEngSlot;
import appeng.container.slot.SlotCraftingMatrix;
import appeng.container.slot.SlotCraftingTerm;
import appeng.container.slot.SlotDisabled;
import appeng.container.slot.SlotFake;
import appeng.container.slot.SlotInaccessible;
import appeng.container.slot.SlotPlayerHotBar;
import appeng.container.slot.SlotPlayerInv;
import appeng.core.AELog;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketInventoryAction;
import appeng.core.sync.packets.PacketPartialItem;
import appeng.core.sync.packets.PacketValueConfig;
import appeng.helpers.ICustomNameObject;
import appeng.helpers.InventoryAction;
import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import appeng.util.inv.AdaptorPlayerHand;
import appeng.util.item.AEItemStack;
public abstract class AEBaseContainer extends Container
{
private final InventoryPlayer invPlayer;
private final BaseActionSource mySrc;
private final HashSet<Integer> locked = new HashSet<Integer>();
private final TileEntity tileEntity;
private final IPart part;
private final IGuiItemObject obj;
private final List<PacketPartialItem> dataChunks = new LinkedList<PacketPartialItem>();
private final HashMap<Integer, SyncData> syncData = new HashMap<Integer, SyncData>();
private boolean isContainerValid = true;
private String customName;
private ContainerOpenContext openContext;
private IMEInventoryHandler<IAEItemStack> cellInv;
private IEnergySource powerSrc;
private boolean sentCustomName;
private int ticksSinceCheck = 900;
private IAEItemStack clientRequestedTargetItem = null;
public AEBaseContainer( final InventoryPlayer ip, final TileEntity myTile, final IPart myPart )
{
this( ip, myTile, myPart, null );
}
public AEBaseContainer( final InventoryPlayer ip, final TileEntity myTile, final IPart myPart, final IGuiItemObject gio )
{
this.invPlayer = ip;
this.tileEntity = myTile;
this.part = myPart;
this.obj = gio;
this.mySrc = new PlayerSource( ip.player, this.getActionHost() );
this.prepareSync();
}
protected IActionHost getActionHost()
{
if( this.obj instanceof IActionHost )
{
return (IActionHost) this.obj;
}
if( this.tileEntity instanceof IActionHost )
{
return (IActionHost) this.tileEntity;
}
if( this.part instanceof IActionHost )
{
return (IActionHost) this.part;
}
return null;
}
private void prepareSync()
{
for( final Field f : this.getClass().getFields() )
{
if( f.isAnnotationPresent( GuiSync.class ) )
{
final GuiSync annotation = f.getAnnotation( GuiSync.class );
if( this.syncData.containsKey( annotation.value() ) )
{
AELog.warn( "Channel already in use: " + annotation.value() + " for " + f.getName() );
}
else
{
this.syncData.put( annotation.value(), new SyncData( this, f, annotation ) );
}
}
}
}
public AEBaseContainer( final InventoryPlayer ip, final Object anchor )
{
this.invPlayer = ip;
this.tileEntity = anchor instanceof TileEntity ? (TileEntity) anchor : null;
this.part = anchor instanceof IPart ? (IPart) anchor : null;
this.obj = anchor instanceof IGuiItemObject ? (IGuiItemObject) anchor : null;
if( this.tileEntity == null && this.part == null && this.obj == null )
{
throw new IllegalArgumentException( "Must have a valid anchor, instead " + anchor + " in " + ip );
}
this.mySrc = new PlayerSource( ip.player, this.getActionHost() );
this.prepareSync();
}
public void postPartial( final PacketPartialItem packetPartialItem )
{
this.dataChunks.add( packetPartialItem );
if( packetPartialItem.getPageCount() == this.dataChunks.size() )
{
this.parsePartials();
}
}
private void parsePartials()
{
int total = 0;
for( final PacketPartialItem ppi : this.dataChunks )
{
total += ppi.getSize();
}
final byte[] buffer = new byte[total];
int cursor = 0;
for( final PacketPartialItem ppi : this.dataChunks )
{
cursor = ppi.write( buffer, cursor );
}
try
{
final NBTTagCompound data = CompressedStreamTools.readCompressed( new ByteArrayInputStream( buffer ) );
if( data != null )
{
this.setTargetStack( AEApi.instance().storage().createItemStack( ItemStack.loadItemStackFromNBT( data ) ) );
}
}
catch( final IOException e )
{
AELog.debug( e );
}
this.dataChunks.clear();
}
public IAEItemStack getTargetStack()
{
return this.clientRequestedTargetItem;
}
public void setTargetStack( final IAEItemStack stack )
{
// client doesn't need to re-send, makes for lower overhead rapid packets.
if( Platform.isClient() )
{
final ItemStack a = stack == null ? null : stack.getItemStack();
final ItemStack b = this.clientRequestedTargetItem == null ? null : this.clientRequestedTargetItem.getItemStack();
if( Platform.isSameItemPrecise( a, b ) )
{
return;
}
final ByteArrayOutputStream stream = new ByteArrayOutputStream();
final NBTTagCompound item = new NBTTagCompound();
if( stack != null )
{
stack.writeToNBT( item );
}
try
{
CompressedStreamTools.writeCompressed( item, stream );
final int maxChunkSize = 30000;
final List<byte[]> miniPackets = new LinkedList<byte[]>();
final byte[] data = stream.toByteArray();
final ByteArrayInputStream bis = new ByteArrayInputStream( data, 0, stream.size() );
while( bis.available() > 0 )
{
final int nextBLock = bis.available() > maxChunkSize ? maxChunkSize : bis.available();
final byte[] nextSegment = new byte[nextBLock];
bis.read( nextSegment );
miniPackets.add( nextSegment );
}
bis.close();
stream.close();
int page = 0;
for( final byte[] packet : miniPackets )
{
final PacketPartialItem ppi = new PacketPartialItem( page, miniPackets.size(), packet );
page++;
NetworkHandler.instance.sendToServer( ppi );
}
}
catch( final IOException e )
{
AELog.debug( e );
return;
}
}
this.clientRequestedTargetItem = stack == null ? null : stack.copy();
}
public BaseActionSource getActionSource()
{
return this.mySrc;
}
public void verifyPermissions( final SecurityPermissions security, final boolean requirePower )
{
if( Platform.isClient() )
{
return;
}
this.ticksSinceCheck++;
if( this.ticksSinceCheck < 20 )
{
return;
}
this.ticksSinceCheck = 0;
this.setValidContainer( this.isValidContainer() && this.hasAccess( security, requirePower ) );
}
protected boolean hasAccess( final SecurityPermissions perm, final boolean requirePower )
{
final IActionHost host = this.getActionHost();
if( host != null )
{
final IGridNode gn = host.getActionableNode();
if( gn != null )
{
final IGrid g = gn.getGrid();
if( g != null )
{
if( requirePower )
{
final IEnergyGrid eg = g.getCache( IEnergyGrid.class );
if( !eg.isNetworkPowered() )
{
return false;
}
}
final ISecurityGrid sg = g.getCache( ISecurityGrid.class );
if( sg.hasPermission( this.getInventoryPlayer().player, perm ) )
{
return true;
}
}
}
}
return false;
}
public void lockPlayerInventorySlot( final int idx )
{
this.locked.add( idx );
}
public Object getTarget()
{
if( this.tileEntity != null )
{
return this.tileEntity;
}
if( this.part != null )
{
return this.part;
}
if( this.obj != null )
{
return this.obj;
}
return null;
}
public InventoryPlayer getPlayerInv()
{
return this.getInventoryPlayer();
}
public TileEntity getTileEntity()
{
return this.tileEntity;
}
public final void updateFullProgressBar( final int idx, final long value )
{
if( this.syncData.containsKey( idx ) )
{
this.syncData.get( idx ).update( value );
return;
}
this.updateProgressBar( idx, (int) value );
}
public void stringSync( final int idx, final String value )
{
if( this.syncData.containsKey( idx ) )
{
this.syncData.get( idx ).update( value );
}
}
protected void bindPlayerInventory( final InventoryPlayer inventoryPlayer, final int offsetX, final int offsetY )
{
// bind player inventory
for( int i = 0; i < 3; i++ )
{
for( int j = 0; j < 9; j++ )
{
if( this.locked.contains( j + i * 9 + 9 ) )
{
this.addSlotToContainer( new SlotDisabled( inventoryPlayer, j + i * 9 + 9, 8 + j * 18 + offsetX, offsetY + i * 18 ) );
}
else
{
this.addSlotToContainer( new SlotPlayerInv( inventoryPlayer, j + i * 9 + 9, 8 + j * 18 + offsetX, offsetY + i * 18 ) );
}
}
}
// bind player hotbar
for( int i = 0; i < 9; i++ )
{
if( this.locked.contains( i ) )
{
this.addSlotToContainer( new SlotDisabled( inventoryPlayer, i, 8 + i * 18 + offsetX, 58 + offsetY ) );
}
else
{
this.addSlotToContainer( new SlotPlayerHotBar( inventoryPlayer, i, 8 + i * 18 + offsetX, 58 + offsetY ) );
}
}
}
@Override
protected Slot addSlotToContainer( final Slot newSlot )
{
if( newSlot instanceof AppEngSlot )
{
final AppEngSlot s = (AppEngSlot) newSlot;
s.setContainer( this );
return super.addSlotToContainer( newSlot );
}
else
{
throw new IllegalArgumentException( "Invalid Slot [" + newSlot + "]for AE Container instead of AppEngSlot." );
}
}
@Override
public void detectAndSendChanges()
{
this.sendCustomName();
if( Platform.isServer() )
{
for( final Object crafter : this.crafters )
{
final ICrafting icrafting = (ICrafting) crafter;
for( final SyncData sd : this.syncData.values() )
{
sd.tick( icrafting );
}
}
}
super.detectAndSendChanges();
}
@Override
public ItemStack transferStackInSlot( final EntityPlayer p, final int idx )
{
if( Platform.isClient() )
{
return null;
}
boolean hasMETiles = false;
for( final Object is : this.inventorySlots )
{
if( is instanceof InternalSlotME )
{
hasMETiles = true;
break;
}
}
if( hasMETiles && Platform.isClient() )
{
return null;
}
final AppEngSlot clickSlot = (AppEngSlot) this.inventorySlots.get( idx ); // require AE SLots!
if( clickSlot instanceof SlotDisabled || clickSlot instanceof SlotInaccessible )
{
return null;
}
if( clickSlot != null && clickSlot.getHasStack() )
{
ItemStack tis = clickSlot.getStack();
if( tis == null )
{
return null;
}
final List<Slot> selectedSlots = new ArrayList<Slot>();
/**
* Gather a list of valid destinations.
*/
if( clickSlot.isPlayerSide() )
{
tis = this.shiftStoreItem( tis );
// target slots in the container...
for( final Object inventorySlot : this.inventorySlots )
{
final AppEngSlot cs = (AppEngSlot) inventorySlot;
if( !( cs.isPlayerSide() ) && !( cs instanceof SlotFake ) && !( cs instanceof SlotCraftingMatrix ) )
{
if( cs.isItemValid( tis ) )
{
selectedSlots.add( cs );
}
}
}
}
else
{
// target slots in the container...
for( final Object inventorySlot : this.inventorySlots )
{
final AppEngSlot cs = (AppEngSlot) inventorySlot;
if( ( cs.isPlayerSide() ) && !( cs instanceof SlotFake ) && !( cs instanceof SlotCraftingMatrix ) )
{
if( cs.isItemValid( tis ) )
{
selectedSlots.add( cs );
}
}
}
}
/**
* Handle Fake Slot Shift clicking.
*/
if( selectedSlots.isEmpty() && clickSlot.isPlayerSide() )
{
if( tis != null )
{
// target slots in the container...
for( final Object inventorySlot : this.inventorySlots )
{
final AppEngSlot cs = (AppEngSlot) inventorySlot;
final ItemStack destination = cs.getStack();
if( !( cs.isPlayerSide() ) && cs instanceof SlotFake )
{
if( Platform.isSameItemPrecise( destination, tis ) )
{
return null;
}
else if( destination == null )
{
cs.putStack( tis.copy() );
cs.onSlotChanged();
this.updateSlot( cs );
return null;
}
}
}
}
}
if( tis != null )
{
// find partials..
for( final Slot d : selectedSlots )
{
if( d instanceof SlotDisabled || d instanceof SlotME )
{
continue;
}
if( d.isItemValid( tis ) )
{
if( d.getHasStack() )
{
final ItemStack t = d.getStack();
if( Platform.isSameItemPrecise( tis, t ) ) // t.isItemEqual(tis))
{
int maxSize = t.getMaxStackSize();
if( maxSize > d.getSlotStackLimit() )
{
maxSize = d.getSlotStackLimit();
}
int placeAble = maxSize - t.stackSize;
if( tis.stackSize < placeAble )
{
placeAble = tis.stackSize;
}
t.stackSize += placeAble;
tis.stackSize -= placeAble;
if( tis.stackSize <= 0 )
{
clickSlot.putStack( null );
d.onSlotChanged();
// if ( hasMETiles ) updateClient();
this.updateSlot( clickSlot );
this.updateSlot( d );
return null;
}
else
{
this.updateSlot( d );
}
}
}
}
}
// any match..
for( final Slot d : selectedSlots )
{
if( d instanceof SlotDisabled || d instanceof SlotME )
{
continue;
}
if( d.isItemValid( tis ) )
{
if( d.getHasStack() )
{
final ItemStack t = d.getStack();
if( Platform.isSameItemPrecise( t, tis ) )
{
int maxSize = t.getMaxStackSize();
if( d.getSlotStackLimit() < maxSize )
{
maxSize = d.getSlotStackLimit();
}
int placeAble = maxSize - t.stackSize;
if( tis.stackSize < placeAble )
{
placeAble = tis.stackSize;
}
t.stackSize += placeAble;
tis.stackSize -= placeAble;
if( tis.stackSize <= 0 )
{
clickSlot.putStack( null );
d.onSlotChanged();
// if ( worldEntity != null )
// worldEntity.markDirty();
// if ( hasMETiles ) updateClient();
this.updateSlot( clickSlot );
this.updateSlot( d );
return null;
}
else
{
this.updateSlot( d );
}
}
}
else
{
int maxSize = tis.getMaxStackSize();
if( maxSize > d.getSlotStackLimit() )
{
maxSize = d.getSlotStackLimit();
}
final ItemStack tmp = tis.copy();
if( tmp.stackSize > maxSize )
{
tmp.stackSize = maxSize;
}
tis.stackSize -= tmp.stackSize;
d.putStack( tmp );
if( tis.stackSize <= 0 )
{
clickSlot.putStack( null );
d.onSlotChanged();
// if ( worldEntity != null )
// worldEntity.markDirty();
// if ( hasMETiles ) updateClient();
this.updateSlot( clickSlot );
this.updateSlot( d );
return null;
}
else
{
this.updateSlot( d );
}
}
}
}
}
clickSlot.putStack( tis != null ? tis.copy() : null );
}
this.updateSlot( clickSlot );
return null;
}
@Override
public final void updateProgressBar( final int idx, final int value )
{
if( this.syncData.containsKey( idx ) )
{
this.syncData.get( idx ).update( (long) value );
}
}
@Override
public boolean canInteractWith( final EntityPlayer entityplayer )
{
if( this.isValidContainer() )
{
if( this.tileEntity instanceof IInventory )
{
return ( (IInventory) this.tileEntity ).isUseableByPlayer( entityplayer );
}
return true;
}
return false;
}
@Override
public boolean canDragIntoSlot( final Slot s )
{
return ( (AppEngSlot) s ).isDraggable();
}
public void doAction( final EntityPlayerMP player, final InventoryAction action, final int slot, final long id )
{
if( slot >= 0 && slot < this.inventorySlots.size() )
{
final Slot s = this.getSlot( slot );
if( s instanceof SlotCraftingTerm )
{
switch( action )
{
case CRAFT_SHIFT:
case CRAFT_ITEM:
case CRAFT_STACK:
( (SlotCraftingTerm) s ).doClick( action, player );
this.updateHeld( player );
default:
}
}
if( s instanceof SlotFake )
{
final ItemStack hand = player.inventory.getItemStack();
switch( action )
{
case PICKUP_OR_SET_DOWN:
if( hand == null )
{
s.putStack( null );
}
else
{
s.putStack( hand.copy() );
}
break;
case PLACE_SINGLE:
if( hand != null )
{
final ItemStack is = hand.copy();
is.stackSize = 1;
s.putStack( is );
}
break;
case SPLIT_OR_PLACE_SINGLE:
ItemStack is = s.getStack();
if( is != null )
{
if( hand == null )
{
is.stackSize--;
}
else if( hand.isItemEqual( is ) )
{
is.stackSize = Math.min( is.getMaxStackSize(), is.stackSize + 1 );
}
else
{
is = hand.copy();
is.stackSize = 1;
}
s.putStack( is );
}
else if( hand != null )
{
is = hand.copy();
is.stackSize = 1;
s.putStack( is );
}
break;
case CREATIVE_DUPLICATE:
case MOVE_REGION:
case SHIFT_CLICK:
default:
break;
}
}
if( action == InventoryAction.MOVE_REGION )
{
final List<Slot> from = new LinkedList<Slot>();
for( final Object j : this.inventorySlots )
{
if( j instanceof Slot && j.getClass() == s.getClass() )
{
from.add( (Slot) j );
}
}
for( final Slot fr : from )
{
this.transferStackInSlot( player, fr.slotNumber );
}
}
return;
}
// get target item.
final IAEItemStack slotItem = this.clientRequestedTargetItem;
switch( action )
{
case SHIFT_CLICK:
if( this.getPowerSource() == null || this.getCellInventory() == null )
{
return;
}
if( slotItem != null )
{
IAEItemStack ais = slotItem.copy();
ItemStack myItem = ais.getItemStack();
ais.setStackSize( myItem.getMaxStackSize() );
final InventoryAdaptor adp = InventoryAdaptor.getAdaptor( player, ForgeDirection.UNKNOWN );
myItem.stackSize = (int) ais.getStackSize();
myItem = adp.simulateAdd( myItem );
if( myItem != null )
{
ais.setStackSize( ais.getStackSize() - myItem.stackSize );
}
ais = Platform.poweredExtraction( this.getPowerSource(), this.getCellInventory(), ais, this.getActionSource() );
if( ais != null )
{
adp.addItems( ais.getItemStack() );
}
}
break;
case ROLL_DOWN:
if( this.getPowerSource() == null || this.getCellInventory() == null )
{
return;
}
final int releaseQty = 1;
final ItemStack isg = player.inventory.getItemStack();
if( isg != null && releaseQty > 0 )
{
IAEItemStack ais = AEApi.instance().storage().createItemStack( isg );
ais.setStackSize( 1 );
final IAEItemStack extracted = ais.copy();
ais = Platform.poweredInsert( this.getPowerSource(), this.getCellInventory(), ais, this.getActionSource() );
if( ais == null )
{
final InventoryAdaptor ia = new AdaptorPlayerHand( player );
final ItemStack fail = ia.removeItems( 1, extracted.getItemStack(), null );
if( fail == null )
{
this.getCellInventory().extractItems( extracted, Actionable.MODULATE, this.getActionSource() );
}
this.updateHeld( player );
}
}
break;
case ROLL_UP:
case PICKUP_SINGLE:
if( this.getPowerSource() == null || this.getCellInventory() == null )
{
return;
}
if( slotItem != null )
{
int liftQty = 1;
final ItemStack item = player.inventory.getItemStack();
if( item != null )
{
if( item.stackSize >= item.getMaxStackSize() )
{
liftQty = 0;
}
if( !Platform.isSameItemPrecise( slotItem.getItemStack(), item ) )
{
liftQty = 0;
}
}
if( liftQty > 0 )
{
IAEItemStack ais = slotItem.copy();
ais.setStackSize( 1 );
ais = Platform.poweredExtraction( this.getPowerSource(), this.getCellInventory(), ais, this.getActionSource() );
if( ais != null )
{
final InventoryAdaptor ia = new AdaptorPlayerHand( player );
final ItemStack fail = ia.addItems( ais.getItemStack() );
if( fail != null )
{
this.getCellInventory().injectItems( ais, Actionable.MODULATE, this.getActionSource() );
}
this.updateHeld( player );
}
}
}
break;
case PICKUP_OR_SET_DOWN:
if( this.getPowerSource() == null || this.getCellInventory() == null )
{
return;
}
if( player.inventory.getItemStack() == null )
{
if( slotItem != null )
{
IAEItemStack ais = slotItem.copy();
ais.setStackSize( ais.getItemStack().getMaxStackSize() );
ais = Platform.poweredExtraction( this.getPowerSource(), this.getCellInventory(), ais, this.getActionSource() );
if( ais != null )
{
player.inventory.setItemStack( ais.getItemStack() );
}
else
{
player.inventory.setItemStack( null );
}
this.updateHeld( player );
}
}
else
{
IAEItemStack ais = AEApi.instance().storage().createItemStack( player.inventory.getItemStack() );
ais = Platform.poweredInsert( this.getPowerSource(), this.getCellInventory(), ais, this.getActionSource() );
if( ais != null )
{
player.inventory.setItemStack( ais.getItemStack() );
}
else
{
player.inventory.setItemStack( null );
}
this.updateHeld( player );
}
break;
case SPLIT_OR_PLACE_SINGLE:
if( this.getPowerSource() == null || this.getCellInventory() == null )
{
return;
}
if( player.inventory.getItemStack() == null )
{
if( slotItem != null )
{
IAEItemStack ais = slotItem.copy();
final long maxSize = ais.getItemStack().getMaxStackSize();
ais.setStackSize( maxSize );
ais = this.getCellInventory().extractItems( ais, Actionable.SIMULATE, this.getActionSource() );
if( ais != null )
{
final long stackSize = Math.min( maxSize, ais.getStackSize() );
ais.setStackSize( ( stackSize + 1 ) >> 1 );
ais = Platform.poweredExtraction( this.getPowerSource(), this.getCellInventory(), ais, this.getActionSource() );
}
if( ais != null )
{
player.inventory.setItemStack( ais.getItemStack() );
}
else
{
player.inventory.setItemStack( null );
}
this.updateHeld( player );
}
}
else
{
IAEItemStack ais = AEApi.instance().storage().createItemStack( player.inventory.getItemStack() );
ais.setStackSize( 1 );
ais = Platform.poweredInsert( this.getPowerSource(), this.getCellInventory(), ais, this.getActionSource() );
if( ais == null )
{
final ItemStack is = player.inventory.getItemStack();
is.stackSize--;
if( is.stackSize <= 0 )
{
player.inventory.setItemStack( null );
}
this.updateHeld( player );
}
}
break;
case CREATIVE_DUPLICATE:
if( player.capabilities.isCreativeMode && slotItem != null )
{
final ItemStack is = slotItem.getItemStack();
is.stackSize = is.getMaxStackSize();
player.inventory.setItemStack( is );
this.updateHeld( player );
}
break;
case MOVE_REGION:
if( this.getPowerSource() == null || this.getCellInventory() == null )
{
return;
}
if( slotItem != null )
{
final int playerInv = 9 * 4;
for( int slotNum = 0; slotNum < playerInv; slotNum++ )
{
IAEItemStack ais = slotItem.copy();
ItemStack myItem = ais.getItemStack();
ais.setStackSize( myItem.getMaxStackSize() );
final InventoryAdaptor adp = InventoryAdaptor.getAdaptor( player, ForgeDirection.UNKNOWN );
myItem.stackSize = (int) ais.getStackSize();
myItem = adp.simulateAdd( myItem );
if( myItem != null )
{
ais.setStackSize( ais.getStackSize() - myItem.stackSize );
}
ais = Platform.poweredExtraction( this.getPowerSource(), this.getCellInventory(), ais, this.getActionSource() );
if( ais != null )
{
adp.addItems( ais.getItemStack() );
}
else
{
return;
}
}
}
break;
default:
break;
}
}
protected void updateHeld( final EntityPlayerMP p )
{
if( Platform.isServer() )
{
try
{
NetworkHandler.instance.sendTo( new PacketInventoryAction( InventoryAction.UPDATE_HAND, 0, AEItemStack.create( p.inventory.getItemStack() ) ), p );
}
catch( final IOException e )
{
AELog.debug( e );
}
}
}
private ItemStack shiftStoreItem( final ItemStack input )
{
if( this.getPowerSource() == null || this.getCellInventory() == null )
{
return input;
}
final IAEItemStack ais = Platform.poweredInsert( this.getPowerSource(), this.getCellInventory(), AEApi.instance().storage().createItemStack( input ), this.getActionSource() );
if( ais == null )
{
return null;
}
return ais.getItemStack();
}
private void updateSlot( final Slot clickSlot )
{
// ???
this.detectAndSendChanges();
}
private void sendCustomName()
{
if( !this.sentCustomName )
{
this.sentCustomName = true;
if( Platform.isServer() )
{
ICustomNameObject name = null;
if( this.part instanceof ICustomNameObject )
{
name = (ICustomNameObject) this.part;
}
if( this.tileEntity instanceof ICustomNameObject )
{
name = (ICustomNameObject) this.tileEntity;
}
if( this.obj instanceof ICustomNameObject )
{
name = (ICustomNameObject) this.obj;
}
if( this instanceof ICustomNameObject )
{
name = (ICustomNameObject) this;
}
if( name != null )
{
if( name.hasCustomName() )
{
this.setCustomName( name.getCustomName() );
}
if( this.getCustomName() != null )
{
try
{
NetworkHandler.instance.sendTo( new PacketValueConfig( "CustomName", this.getCustomName() ), (EntityPlayerMP) this.getInventoryPlayer().player );
}
catch( final IOException e )
{
AELog.debug( e );
}
}
}
}
}
}
public void swapSlotContents( final int slotA, final int slotB )
{
final Slot a = this.getSlot( slotA );
final Slot b = this.getSlot( slotB );
// NPE protection...
if( a == null || b == null )
{
return;
}
final ItemStack isA = a.getStack();
final ItemStack isB = b.getStack();
// something to do?
if( isA == null && isB == null )
{
return;
}
// can take?
if( isA != null && !a.canTakeStack( this.getInventoryPlayer().player ) )
{
return;
}
if( isB != null && !b.canTakeStack( this.getInventoryPlayer().player ) )
{
return;
}
// swap valid?
if( isB != null && !a.isItemValid( isB ) )
{
return;
}
if( isA != null && !b.isItemValid( isA ) )
{
return;
}
ItemStack testA = isB == null ? null : isB.copy();
ItemStack testB = isA == null ? null : isA.copy();
// can put some back?
if( testA != null && testA.stackSize > a.getSlotStackLimit() )
{
if( testB != null )
{
return;
}
final int totalA = testA.stackSize;
testA.stackSize = a.getSlotStackLimit();
testB = testA.copy();
testB.stackSize = totalA - testA.stackSize;
}
if( testB != null && testB.stackSize > b.getSlotStackLimit() )
{
if( testA != null )
{
return;
}
final int totalB = testB.stackSize;
testB.stackSize = b.getSlotStackLimit();
testA = testB.copy();
testA.stackSize = totalB - testA.stackSize;
}
a.putStack( testA );
b.putStack( testB );
}
public void onUpdate( final String field, final Object oldValue, final Object newValue )
{
}
public void onSlotChange( final Slot s )
{
}
public boolean isValidForSlot( final Slot s, final ItemStack i )
{
return true;
}
public IMEInventoryHandler<IAEItemStack> getCellInventory()
{
return this.cellInv;
}
public void setCellInventory( final IMEInventoryHandler<IAEItemStack> cellInv )
{
this.cellInv = cellInv;
}
public String getCustomName()
{
return this.customName;
}
public void setCustomName( final String customName )
{
this.customName = customName;
}
public InventoryPlayer getInventoryPlayer()
{
return this.invPlayer;
}
public boolean isValidContainer()
{
return this.isContainerValid;
}
public void setValidContainer( final boolean isContainerValid )
{
this.isContainerValid = isContainerValid;
}
public ContainerOpenContext getOpenContext()
{
return this.openContext;
}
public void setOpenContext( final ContainerOpenContext openContext )
{
this.openContext = openContext;
}
public IEnergySource getPowerSource()
{
return this.powerSrc;
}
public void setPowerSource( final IEnergySource powerSrc )
{
this.powerSrc = powerSrc;
}
}