From ff12aa1673e9e9ad3235da28d770b9155a2620a1 Mon Sep 17 00:00:00 2001 From: AlgorithmX2 Date: Mon, 12 May 2014 23:11:19 -0500 Subject: [PATCH] Added Shit+Mouse wheel to pick up / drop items. Added Partial ItemStack packets to report to the server what itemstack is the target of interation. Fixed Repairing Items in CraftingTerminal. --- client/gui/AEBaseGui.java | 54 ++++-- container/AEBaseContainer.java | 173 +++++++++++++++++-- container/slot/SlotCraftingTerm.java | 21 +++ core/sync/AppEngPacketHandlerBase.java | 5 +- core/sync/packets/PacketInventoryAction.java | 7 +- core/sync/packets/PacketPartialItem.java | 63 +++++++ helpers/InventoryAction.java | 2 +- 7 files changed, 291 insertions(+), 34 deletions(-) create mode 100644 core/sync/packets/PacketPartialItem.java diff --git a/client/gui/AEBaseGui.java b/client/gui/AEBaseGui.java index c27b68549..3b4975273 100644 --- a/client/gui/AEBaseGui.java +++ b/client/gui/AEBaseGui.java @@ -115,11 +115,41 @@ public abstract class AEBaseGui extends GuiContainer { super.handleMouseInput(); - if ( myScrollBar != null ) + int i = Mouse.getEventDWheel(); + if ( i != 0 && isShiftKeyDown() ) { - int i = Mouse.getEventDWheel(); - if ( i != 0 ) - myScrollBar.wheel( i ); + int x = Mouse.getEventX() * this.width / this.mc.displayWidth; + int y = this.height - Mouse.getEventY() * this.height / this.mc.displayHeight - 1; + mouseWheelEvent( x, y, i / Math.abs( i ) ); + } + else if ( i != 0 && myScrollBar != null ) + myScrollBar.wheel( i ); + } + + protected void mouseWheelEvent(int x, int y, int wheel) + { + Slot slot = getSlot( x, y ); + if ( slot instanceof SlotME ) + { + IAEItemStack item = ((SlotME) slot).getAEStack(); + if ( item != null ) + { + try + { + ((AEBaseContainer) inventorySlots).setTargetStack( item ); + InventoryAction direction = wheel > 0 ? InventoryAction.ROLLDOWN : InventoryAction.ROLLUP; + int times = Math.abs( wheel ); + for (int h = 0; h < times; h++) + { + PacketInventoryAction p = new PacketInventoryAction( direction, inventorySlots.inventorySlots.size(), null ); + NetworkHandler.instance.sendToServer( p ); + } + } + catch (IOException e) + { + AELog.error( e ); + } + } } } @@ -149,15 +179,13 @@ public abstract class AEBaseGui extends GuiContainer if ( slot instanceof SlotFake ) { InventoryAction action = null; - IAEItemStack stack = null; action = ctrlDown == 1 ? InventoryAction.SPLIT_OR_PLACESINGLE : InventoryAction.PICKUP_OR_SETDOWN; if ( action != null ) { - PacketInventoryAction p; try { - p = new PacketInventoryAction( action, slotIdx, stack ); + PacketInventoryAction p = new PacketInventoryAction( action, slotIdx, null ); NetworkHandler.instance.sendToServer( p ); } catch (IOException e) @@ -175,7 +203,6 @@ public abstract class AEBaseGui extends GuiContainer return; // prevent weird double clicks.. InventoryAction action = null; - IAEItemStack stack = null; if ( key == 1 ) action = InventoryAction.CRAFT_SHIFT; else @@ -183,10 +210,9 @@ public abstract class AEBaseGui extends GuiContainer if ( action != null ) { - PacketInventoryAction p; try { - p = new PacketInventoryAction( action, slotIdx, stack ); + PacketInventoryAction p = new PacketInventoryAction( action, slotIdx, null ); NetworkHandler.instance.sendToServer( p ); } catch (IOException e) @@ -204,7 +230,6 @@ public abstract class AEBaseGui extends GuiContainer if ( slot instanceof SlotME ) stack = ((SlotME) slot).getAEStack(); - PacketInventoryAction p; try { int slotNum = inventorySlots.inventorySlots.size(); @@ -212,7 +237,8 @@ public abstract class AEBaseGui extends GuiContainer if ( !(slot instanceof SlotME) && slot != null ) slotNum = slot.slotNumber; - p = new PacketInventoryAction( InventoryAction.MOVE_REGION, slotNum, stack ); + ((AEBaseContainer) inventorySlots).setTargetStack( stack ); + PacketInventoryAction p = new PacketInventoryAction( InventoryAction.MOVE_REGION, slotNum, null ); NetworkHandler.instance.sendToServer( p ); } catch (IOException e) @@ -257,10 +283,10 @@ public abstract class AEBaseGui extends GuiContainer if ( action != null ) { - PacketInventoryAction p; try { - p = new PacketInventoryAction( action, inventorySlots.inventorySlots.size(), stack ); + ((AEBaseContainer) inventorySlots).setTargetStack( stack ); + PacketInventoryAction p = new PacketInventoryAction( action, inventorySlots.inventorySlots.size(), null ); NetworkHandler.instance.sendToServer( p ); } catch (IOException e) diff --git a/container/AEBaseContainer.java b/container/AEBaseContainer.java index c1aa4923e..335aeb0cb 100644 --- a/container/AEBaseContainer.java +++ b/container/AEBaseContainer.java @@ -1,5 +1,6 @@ package appeng.container; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; @@ -13,6 +14,8 @@ import net.minecraft.inventory.Container; 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; @@ -42,6 +45,7 @@ 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; @@ -50,6 +54,8 @@ import appeng.util.Platform; import appeng.util.inv.AdaptorPlayerHand; import appeng.util.item.AEItemStack; +import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream; + public abstract class AEBaseContainer extends Container { @@ -65,6 +71,101 @@ public abstract class AEBaseContainer extends Container int ticksSinceCheck = 900; + IAEItemStack clientRequestedTargetItem = null; + List dataChunks = new LinkedList(); + + public void postPartial(PacketPartialItem packetPartialItem) + { + dataChunks.add( packetPartialItem ); + if ( packetPartialItem.getPageCount() == dataChunks.size() ) + parsePartials(); + } + + private void parsePartials() + { + int total = 0; + for (PacketPartialItem ppi : dataChunks) + total += ppi.getSize(); + + byte[] buffer = new byte[total]; + int cursor = 0; + + for (PacketPartialItem ppi : dataChunks) + cursor = ppi.write( buffer, cursor ); + + try + { + NBTTagCompound data = CompressedStreamTools.readCompressed( new ByteArrayInputStream( buffer ) ); + if ( data != null ) + setTargetStack( AEApi.instance().storage().createItemStack( ItemStack.loadItemStackFromNBT( data ) ) ); + } + catch (IOException e) + { + AELog.error( e ); + } + + dataChunks.clear(); + } + + public void setTargetStack(IAEItemStack stack) + { + // client dosn't need to re-send, makes for lower overhead rapid packets. + if ( Platform.isClient() ) + { + ItemStack a = stack == null ? null : stack.getItemStack(); + ItemStack b = clientRequestedTargetItem == null ? null : clientRequestedTargetItem.getItemStack(); + + if ( Platform.isSameItemPrecise( a, b ) ) + return; + + ByteOutputStream stream = new ByteOutputStream(); + NBTTagCompound item = new NBTTagCompound(); + + if ( stack != null ) + stack.writeToNBT( item ); + + try + { + CompressedStreamTools.writeCompressed( item, stream ); + + int maxChunkSize = 30000; + List miniPackets = new LinkedList(); + + byte[] data = stream.getBytes(); + + ByteArrayInputStream bis = new ByteArrayInputStream( data, 0, stream.size() ); + while (bis.available() > 0) + { + int nextBLock = bis.available() > maxChunkSize ? maxChunkSize : bis.available(); + byte[] nextSegment = new byte[nextBLock]; + bis.read( nextSegment ); + miniPackets.add( nextSegment ); + } + bis.close(); + stream.close(); + + int page = 0; + for (byte[] packet : miniPackets) + { + PacketPartialItem ppi = new PacketPartialItem( page++, miniPackets.size(), packet ); + NetworkHandler.instance.sendToServer( ppi ); + } + } + catch (IOException e) + { + AELog.error( e ); + return; + } + } + + clientRequestedTargetItem = stack == null ? null : stack.copy(); + } + + public IAEItemStack getTargetStack() + { + return clientRequestedTargetItem; + } + public BaseActionSource getSource() { return mySrc; @@ -492,7 +593,7 @@ public abstract class AEBaseContainer extends Container return ais.getItemStack(); } - public void doAction(EntityPlayerMP player, InventoryAction action, int slot, IAEItemStack slotItem) + public void doAction(EntityPlayerMP player, InventoryAction action, int slot) { if ( slot >= 0 && slot < inventorySlots.size() ) { @@ -576,6 +677,9 @@ public abstract class AEBaseContainer extends Container return; } + // get target item. + IAEItemStack slotItem = getTargetStack(); + switch (action) { case SHIFT_CLICK: @@ -601,6 +705,34 @@ public abstract class AEBaseContainer extends Container adp.addItems( ais.getItemStack() ); } break; + case ROLLDOWN: + if ( powerSrc == null || cellInv == null ) + return; + + int releaseQty = 1; + ItemStack isg = player.inventory.getItemStack(); + + if ( isg != null && releaseQty > 0 ) + { + IAEItemStack ais = AEApi.instance().storage().createItemStack( isg ); + ais.setStackSize( 1 ); + IAEItemStack extracted = ais.copy(); + + ais = Platform.poweredInsert( powerSrc, cellInv, ais, mySrc ); + if ( ais == null ) + { + InventoryAdaptor ia = new AdaptorPlayerHand( player ); + + ItemStack fail = ia.removeItems( 1, extracted.getItemStack(), null ); + if ( fail == null ) + cellInv.extractItems( extracted, Actionable.MODULATE, mySrc ); + + updateHeld( player ); + } + } + + break; + case ROLLUP: case PICKUP_SINGLE: if ( powerSrc == null || cellInv == null ) return; @@ -608,13 +740,13 @@ public abstract class AEBaseContainer extends Container if ( slotItem != null ) { int liftQty = 1; - ItemStack isg = player.inventory.getItemStack(); + ItemStack isgg = player.inventory.getItemStack(); - if ( isg != null ) + if ( isgg != null ) { - if ( isg.stackSize >= isg.getMaxStackSize() ) + if ( isgg.stackSize >= isgg.getMaxStackSize() ) liftQty = 0; - if ( !Platform.isSameItemPrecise( slotItem.getItemStack(), isg ) ) + if ( !Platform.isSameItemPrecise( slotItem.getItemStack(), isgg ) ) liftQty = 0; } @@ -623,14 +755,16 @@ public abstract class AEBaseContainer extends Container IAEItemStack ais = slotItem.copy(); ais.setStackSize( 1 ); ais = Platform.poweredExtraction( powerSrc, cellInv, ais, mySrc ); + if ( ais != null ) + { + InventoryAdaptor ia = new AdaptorPlayerHand( player ); - InventoryAdaptor ia = new AdaptorPlayerHand( player ); + ItemStack fail = ia.addItems( ais.getItemStack() ); + if ( fail != null ) + cellInv.injectItems( ais, Actionable.MODULATE, mySrc ); - ItemStack fail = ia.addItems( ais.getItemStack() ); - if ( fail != null ) - cellInv.injectItems( ais, Actionable.MODULATE, mySrc ); - - updateHeld( player ); + updateHeld( player ); + } } } break; @@ -751,13 +885,17 @@ public abstract class AEBaseContainer extends Container private void updateHeld(EntityPlayerMP p) { - try + if ( Platform.isServer() ) { - NetworkHandler.instance.sendTo( new PacketInventoryAction( InventoryAction.UPDATE_HAND, 0, AEItemStack.create( p.inventory.getItemStack() ) ), p ); - } - catch (IOException e) - { - AELog.error( e ); + try + { + NetworkHandler.instance.sendTo( new PacketInventoryAction( InventoryAction.UPDATE_HAND, 0, AEItemStack.create( p.inventory.getItemStack() ) ), + p ); + } + catch (IOException e) + { + AELog.error( e ); + } } } @@ -824,4 +962,5 @@ public abstract class AEBaseContainer extends Container a.putStack( testA ); b.putStack( testB ); } + } diff --git a/container/slot/SlotCraftingTerm.java b/container/slot/SlotCraftingTerm.java index 77dc6fe03..b607cb612 100644 --- a/container/slot/SlotCraftingTerm.java +++ b/container/slot/SlotCraftingTerm.java @@ -6,6 +6,7 @@ import java.util.List; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipe; import net.minecraft.world.World; @@ -123,7 +124,27 @@ public class SlotCraftingTerm extends AppEngCraftingSlot IRecipe r = Platform.findMatchingRecipe( ic, p.worldObj ); if ( r == null ) + { + Item target = request.getItem(); + if ( target.isDamageable() && target.isRepairable() ) + { + boolean isBad = false; + for (int x = 0; x < ic.getSizeInventory(); x++) + { + ItemStack pis = ic.getStackInSlot( x ); + if ( pis == null ) + continue; + if ( pis.getItem() != target ) + isBad = true; + } + if ( !isBad ) + { + super.onPickupFromSlot( p, is ); + return request; + } + } return null; + } is = r.getCraftingResult( ic ); diff --git a/core/sync/AppEngPacketHandlerBase.java b/core/sync/AppEngPacketHandlerBase.java index a1e9adf63..d776d0b70 100644 --- a/core/sync/AppEngPacketHandlerBase.java +++ b/core/sync/AppEngPacketHandlerBase.java @@ -20,6 +20,7 @@ import appeng.core.sync.packets.PacketMultiPart; import appeng.core.sync.packets.PacketNEIRecipe; import appeng.core.sync.packets.PacketNewStorageDimension; import appeng.core.sync.packets.PacketPartPlacement; +import appeng.core.sync.packets.PacketPartialItem; import appeng.core.sync.packets.PacketProgressBar; import appeng.core.sync.packets.PacketSwapSlots; import appeng.core.sync.packets.PacketSwitchGuis; @@ -67,7 +68,9 @@ public class AppEngPacketHandlerBase PACKET_SWAP_SLOTS(PacketSwapSlots.class), - PACKET_RECIPE_NEI(PacketNEIRecipe.class); + PACKET_RECIPE_NEI(PacketNEIRecipe.class), + + PACKET_PARTIAL_ITEM(PacketPartialItem.class); final public Class pc; final public Constructor con; diff --git a/core/sync/packets/PacketInventoryAction.java b/core/sync/packets/PacketInventoryAction.java index 7cc42efc3..1588b015e 100644 --- a/core/sync/packets/PacketInventoryAction.java +++ b/core/sync/packets/PacketInventoryAction.java @@ -13,6 +13,7 @@ import appeng.container.AEBaseContainer; import appeng.core.sync.AppEngPacket; import appeng.core.sync.network.INetworkInfo; import appeng.helpers.InventoryAction; +import appeng.util.Platform; import appeng.util.item.AEItemStack; public class PacketInventoryAction extends AppEngPacket @@ -40,7 +41,7 @@ public class PacketInventoryAction extends AppEngPacket if ( sender.openContainer instanceof AEBaseContainer ) { AEBaseContainer aebc = (AEBaseContainer) sender.openContainer; - aebc.doAction( sender, action, slot, slotItem ); + aebc.doAction( sender, action, slot ); } } @@ -58,6 +59,10 @@ public class PacketInventoryAction extends AppEngPacket // api public PacketInventoryAction(InventoryAction action, int slot, IAEItemStack slotItem) throws IOException { + + if ( Platform.isClient() && slotItem != null ) + throw new RuntimeException( "invalid packet, client cannot post inv actions with stacks." ); + this.action = action; this.slot = slot; this.slotItem = slotItem; diff --git a/core/sync/packets/PacketPartialItem.java b/core/sync/packets/PacketPartialItem.java new file mode 100644 index 000000000..6c7b7536c --- /dev/null +++ b/core/sync/packets/PacketPartialItem.java @@ -0,0 +1,63 @@ +package appeng.core.sync.packets; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; + +import java.io.IOException; + +import net.minecraft.entity.player.EntityPlayer; +import appeng.container.AEBaseContainer; +import appeng.core.sync.AppEngPacket; +import appeng.core.sync.network.INetworkInfo; + +public class PacketPartialItem extends AppEngPacket +{ + + short pageNum; + byte[] data; + + // automatic. + public PacketPartialItem(ByteBuf stream) throws IOException { + pageNum = stream.readShort(); + stream.readBytes( data = new byte[stream.readableBytes()] ); + } + + @Override + public void serverPacketData(INetworkInfo manager, AppEngPacket packet, EntityPlayer player) + { + if ( player.openContainer instanceof AEBaseContainer ) + { + ((AEBaseContainer) player.openContainer).postPartial( this ); + } + } + + // api + public PacketPartialItem(int page, int maxPages, byte[] buf) throws IOException { + + ByteBuf data = Unpooled.buffer(); + + pageNum = (short) (page | (maxPages << 8)); + this.data = buf; + data.writeInt( getPacketID() ); + data.writeShort( pageNum ); + data.writeBytes( buf ); + + configureWrite( data ); + } + + public int getPageCount() + { + return pageNum >> 8; + } + + public int getSize() + { + return data.length; + } + + public int write(byte[] buffer, int cursor) + { + System.arraycopy( data, 0, buffer, cursor, data.length ); + return cursor + data.length; + } +} diff --git a/helpers/InventoryAction.java b/helpers/InventoryAction.java index 8c958dc37..6dc6e6181 100644 --- a/helpers/InventoryAction.java +++ b/helpers/InventoryAction.java @@ -9,5 +9,5 @@ public enum InventoryAction CRAFT_STACK, CRAFT_ITEM, CRAFT_SHIFT, // extra... - MOVE_REGION, PICKUP_SINGLE, UPDATE_HAND + MOVE_REGION, PICKUP_SINGLE, UPDATE_HAND, ROLLUP, ROLLDOWN }