diff --git a/client/gui/AEBaseGui.java b/client/gui/AEBaseGui.java index c15da2d2a..951ff8cc4 100644 --- a/client/gui/AEBaseGui.java +++ b/client/gui/AEBaseGui.java @@ -41,6 +41,7 @@ import appeng.container.slot.SlotDisabled; import appeng.container.slot.SlotFake; import appeng.container.slot.SlotInaccessable; import appeng.container.slot.SlotOutput; +import appeng.container.slot.SlotPatternTerm; import appeng.container.slot.SlotRestrictedInput; import appeng.core.AEConfig; import appeng.core.AELog; @@ -167,7 +168,21 @@ public abstract class AEBaseGui extends GuiContainer return; } - if ( slot instanceof SlotCraftingTerm ) + if ( slot instanceof SlotPatternTerm ) + { + if ( key == 6 ) + return; // prevent weird double clicks.. + + try + { + NetworkHandler.instance.sendToServer( ((SlotPatternTerm) slot).getRequest( key == 1 ) ); + } + catch (IOException e) + { + AELog.error( e ); + } + } + else if ( slot instanceof SlotCraftingTerm ) { if ( key == 6 ) return; // prevent weird double clicks.. diff --git a/container/implementations/ContainerCraftingTerm.java b/container/implementations/ContainerCraftingTerm.java index 77bac8923..3009da045 100644 --- a/container/implementations/ContainerCraftingTerm.java +++ b/container/implementations/ContainerCraftingTerm.java @@ -48,7 +48,7 @@ public class ContainerCraftingTerm extends ContainerMEMonitorable implements IAE for (int x = 0; x < 3; x++) addSlotToContainer( craftingSlots[x + y * 3] = new SlotCraftingMatrix( this, crafting, x + y * 3, 37 + x * 18, -72 + y * 18 ) ); - addSlotToContainer( outputSlot = new SlotCraftingTerm( getPlayerInv().player, mySrc, powerSrc, montiorable, crafting, output, 131, -72 + 18 ) ); + addSlotToContainer( outputSlot = new SlotCraftingTerm( getPlayerInv().player, mySrc, powerSrc, montiorable, crafting, crafting, output, 131, -72 + 18 ) ); bindPlayerInventory( ip, 0, 0 ); diff --git a/container/implementations/ContainerPatternTerm.java b/container/implementations/ContainerPatternTerm.java index bf68b7bca..675feac26 100644 --- a/container/implementations/ContainerPatternTerm.java +++ b/container/implementations/ContainerPatternTerm.java @@ -1,26 +1,43 @@ package appeng.container.implementations; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.ICrafting; import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.inventory.SlotCrafting; import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.CraftingManager; +import net.minecraft.item.crafting.IRecipe; +import net.minecraftforge.common.util.ForgeDirection; +import appeng.api.config.Actionable; +import appeng.api.networking.security.MachineSource; +import appeng.api.storage.IMEMonitor; import appeng.api.storage.ITerminalHost; +import appeng.api.storage.data.IAEItemStack; +import appeng.api.storage.data.IItemList; +import appeng.container.ContainerNull; import appeng.container.slot.IOptionalSlotHost; import appeng.container.slot.OptionalSlotFake; import appeng.container.slot.SlotFake; import appeng.container.slot.SlotPatternTerm; import appeng.container.slot.SlotRestrictedInput; import appeng.container.slot.SlotRestrictedInput.PlaceableItemType; +import appeng.core.sync.packets.PacketPatternSlot; import appeng.parts.reporting.PartPatternTerminal; import appeng.tile.inventory.AppEngInternalInventory; import appeng.tile.inventory.IAEAppEngInventory; import appeng.tile.inventory.InvOperation; +import appeng.util.InventoryAdaptor; +import appeng.util.Platform; +import appeng.util.inv.AdaptorPlayerHand; +import appeng.util.item.AEItemStack; public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEAppEngInventory, IOptionalSlotHost { - AppEngInternalInventory output = new AppEngInternalInventory( this, 1 ); - AppEngInternalInventory craftSlotInv = new AppEngInternalInventory( this, 3 ); + AppEngInternalInventory cOut = new AppEngInternalInventory( null, 1 ); + IInventory crafting; SlotFake craftingSlots[] = new SlotFake[9]; OptionalSlotFake outputSlots[] = new OptionalSlotFake[3]; @@ -39,14 +56,13 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA IInventory patternInv = ct.getInventoryByName( "pattern" ); IInventory output = ct.getInventoryByName( "output" ); - IInventory crafting = ct.getInventoryByName( "crafting" ); + crafting = ct.getInventoryByName( "crafting" ); for (int y = 0; y < 3; y++) for (int x = 0; x < 3; x++) addSlotToContainer( craftingSlots[x + y * 3] = new SlotFake( crafting, x + y * 3, 18 + x * 18, -76 + y * 18 ) ); - addSlotToContainer( craftSlot = new SlotPatternTerm( ip.player, mySrc, powerSrc, montiorable, crafting, patternInv, craftSlotInv, output, 0, 110, - -76 + 18, this, 2 ) ); + addSlotToContainer( craftSlot = new SlotPatternTerm( ip.player, mySrc, powerSrc, montiorable, crafting, patternInv, cOut, 110, -76 + 18, this, 2 ) ); craftSlot.IIcon = -1; for (int y = 0; y < 3; y++) @@ -55,6 +71,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA outputSlots[y].renderDisabled = false; outputSlots[y].IIcon = -1; } + addSlotToContainer( patternSlotIN = new SlotRestrictedInput( PlaceableItemType.BLANK_PATTERN, patternInv, 0, 147, -72 - 9 ) ); addSlotToContainer( patternSlotOUT = new SlotRestrictedInput( PlaceableItemType.ENCODED_PATTERN, patternInv, 1, 147, -72 + 34 ) ); @@ -82,19 +99,46 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA } } + @Override + public void putStackInSlot(int par1, ItemStack par2ItemStack) + { + super.putStackInSlot( par1, par2ItemStack ); + updateOutput(); + } + + @Override + public void putStacksInSlots(ItemStack[] par1ArrayOfItemStack) + { + super.putStacksInSlots( par1ArrayOfItemStack ); + updateOutput(); + } + + public void updateOutput() + { + InventoryCrafting ic = new InventoryCrafting( this, 3, 3 ); + for (int x = 0; x < ic.getSizeInventory(); x++) + ic.setInventorySlotContents( x, crafting.getStackInSlot( x ) ); + + ItemStack is = CraftingManager.getInstance().findMatchingRecipe( ic, this.getPlayerInv().player.worldObj ); + cOut.setInventorySlotContents( 0, is ); + } + @Override public void detectAndSendChanges() { super.detectAndSendChanges(); - if ( craftingMode != ct.craftingMode ) + if ( Platform.isServer() ) { - craftingMode = ct.craftingMode; - updateOrderOfOutputSlots(); - - for (Object c : this.crafters) + if ( craftingMode != ct.craftingMode ) { - if ( c instanceof ICrafting ) - ((ICrafting) c).sendProgressBarUpdate( this, 97, craftingMode ? 1 : 0 ); + craftingMode = ct.craftingMode; + updateOrderOfOutputSlots(); + + for (Object c : this.crafters) + { + if ( c instanceof ICrafting ) + ((ICrafting) c).sendProgressBarUpdate( this, 97, craftingMode ? 1 : 0 ); + } } } } @@ -106,6 +150,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA if ( idx == 97 ) { craftingMode = value == 1; + updateOutput(); updateOrderOfOutputSlots(); } } @@ -116,12 +161,6 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA } - @Override - public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removedStack, ItemStack newStack) - { - - } - public void encode() { @@ -136,4 +175,94 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA return craftingMode == true; return false; } + + @Override + public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removedStack, ItemStack newStack) + { + + } + + public void craftOrGetItem(PacketPatternSlot packetPatternSlot) + { + if ( packetPatternSlot.slotItem != null && cellInv != null ) + { + IAEItemStack out = packetPatternSlot.slotItem.copy(); + + InventoryAdaptor inv = new AdaptorPlayerHand( getPlayerInv().player ); + InventoryAdaptor playerInv = InventoryAdaptor.getAdaptor( getPlayerInv().player, ForgeDirection.UNKNOWN ); + if ( packetPatternSlot.shift ) + inv = playerInv; + + if ( inv.simulateAdd( out.getItemStack() ) != null ) + return; + + IAEItemStack extracted = Platform.poweredExtraction( powerSrc, cellInv, out, mySrc ); + if ( extracted != null ) + { + inv.addItems( extracted.getItemStack() ); + detectAndSendChanges(); + return; + } + + InventoryCrafting ic = new InventoryCrafting( new ContainerNull(), 3, 3 ); + InventoryCrafting real = new InventoryCrafting( new ContainerNull(), 3, 3 ); + for (int x = 0; x < 9; x++) + { + ic.setInventorySlotContents( x, packetPatternSlot.pattern[x] == null ? null : packetPatternSlot.pattern[x].getItemStack() ); + } + + EntityPlayer p = getPlayerInv().player; + IRecipe r = Platform.findMatchingRecipe( ic, p.worldObj ); + + if ( r == null ) + return; + + IMEMonitor storage = ct.getItemInventory(); + IItemList all = storage.getStorageList(); + + ItemStack is = r.getCraftingResult( ic ); + + if ( r != null && inv != null ) + { + for (int x = 0; x < ic.getSizeInventory(); x++) + { + if ( ic.getStackInSlot( x ) != null ) + { + ItemStack pulled = Platform.extractItemsByRecipe( powerSrc, mySrc, storage, p.worldObj, r, is, ic, ic.getStackInSlot( x ), x, all ); + real.setInventorySlotContents( x, pulled ); + } + } + } + + IRecipe rr = Platform.findMatchingRecipe( real, p.worldObj ); + + if ( rr == r && Platform.isSameItemPrecise( rr.getCraftingResult( real ), is ) ) + { + SlotCrafting sc = new SlotCrafting( p, real, cOut, 0, 0, 0 ); + sc.onPickupFromSlot( p, is ); + + for (int x = 0; x < real.getSizeInventory(); x++) + { + ItemStack failed = playerInv.addItems( real.getStackInSlot( x ) ); + if ( failed != null ) + p.dropPlayerItemWithRandomChoice( failed, false ); + } + + inv.addItems( is ); + detectAndSendChanges(); + } + else + { + for (int x = 0; x < real.getSizeInventory(); x++) + { + ItemStack failed = real.getStackInSlot( x ); + if ( failed != null ) + { + cellInv.injectItems( AEItemStack.create( failed ), Actionable.MODULATE, new MachineSource( ct ) ); + } + } + } + + } + } } diff --git a/container/slot/SlotCraftingTerm.java b/container/slot/SlotCraftingTerm.java index 6b5894c88..7894d8b50 100644 --- a/container/slot/SlotCraftingTerm.java +++ b/container/slot/SlotCraftingTerm.java @@ -8,9 +8,7 @@ import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipe; -import net.minecraft.world.World; import appeng.api.config.Actionable; -import appeng.api.config.PowerMultiplier; import appeng.api.networking.energy.IEnergySource; import appeng.api.networking.security.BaseActionSource; import appeng.api.storage.IMEMonitor; @@ -27,8 +25,8 @@ import appeng.util.item.AEItemStack; public class SlotCraftingTerm extends AppEngCraftingSlot { - private final IInventory craftInv; - private final IInventory pattern; + protected final IInventory craftInv; + protected final IInventory pattern; private final BaseActionSource mySrc; private final IEnergySource energySrc; @@ -60,54 +58,9 @@ public class SlotCraftingTerm extends AppEngCraftingSlot { } - private ItemStack extractItemsByRecipe(IMEMonitor src, World w, IRecipe r, ItemStack output, InventoryCrafting ci, - ItemStack providedTemplate, int slot, IItemList aitems) + public void makeItem(EntityPlayer p, ItemStack is) { - if ( energySrc.extractAEPower( 1, Actionable.SIMULATE, PowerMultiplier.CONFIG ) > 0.9 ) - { - if ( providedTemplate == null ) - return null; - - AEItemStack ae_req = AEItemStack.create( providedTemplate ); - ae_req.setStackSize( 1 ); - - IAEItemStack ae_ext = src.extractItems( ae_req, Actionable.MODULATE, mySrc ); - if ( ae_ext != null ) - { - ItemStack extracted = ae_ext.getItemStack(); - if ( extracted != null ) - { - energySrc.extractAEPower( 1, Actionable.MODULATE, PowerMultiplier.CONFIG ); - return extracted; - } - } - - if ( aitems != null && (ae_req.isOre() || providedTemplate.hasTagCompound() || providedTemplate.isItemStackDamageable()) ) - { - for (IAEItemStack x : aitems) - { - ItemStack sh = x.getItemStack(); - if ( (Platform.isSameItemType( providedTemplate, sh ) || ae_req.sameOre( x )) && !Platform.isSameItem( sh, output ) ) - { // Platform.isSameItemType( sh, providedTemplate ) - ItemStack cp = Platform.cloneItemStack( sh ); - cp.stackSize = 1; - ci.setInventorySlotContents( slot, cp ); - if ( r.matches( ci, w ) && Platform.isSameItem( r.getCraftingResult( ci ), output ) ) - { - IAEItemStack ex = src.extractItems( AEItemStack.create( cp ), Actionable.MODULATE, mySrc ); - if ( ex != null ) - { - energySrc.extractAEPower( 1, Actionable.MODULATE, PowerMultiplier.CONFIG ); - return ex.getItemStack(); - } - } - ci.setInventorySlotContents( slot, providedTemplate ); - } - } - } - - } - return null; + super.onPickupFromSlot( p, is ); } public ItemStack craftItem(EntityPlayer p, ItemStack request, IMEMonitor inv, IItemList all) @@ -139,7 +92,7 @@ public class SlotCraftingTerm extends AppEngCraftingSlot { if ( pattern.getStackInSlot( x ) != null ) { - set[x] = extractItemsByRecipe( inv, p.worldObj, r, is, ic, pattern.getStackInSlot( x ), x, all ); + set[x] = Platform.extractItemsByRecipe( energySrc, mySrc, inv, p.worldObj, r, is, ic, pattern.getStackInSlot( x ), x, all ); ic.setInventorySlotContents( x, set[x] ); } } @@ -148,7 +101,7 @@ public class SlotCraftingTerm extends AppEngCraftingSlot if ( preCraft( p, inv, set, is ) ) { - super.onPickupFromSlot( p, is ); + makeItem( p, is ); postCraft( p, inv, set, is ); } diff --git a/container/slot/SlotPatternTerm.java b/container/slot/SlotPatternTerm.java index 8d8891794..d8f0e16ab 100644 --- a/container/slot/SlotPatternTerm.java +++ b/container/slot/SlotPatternTerm.java @@ -1,11 +1,16 @@ package appeng.container.slot; +import java.io.IOException; + import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; +import appeng.api.AEApi; import appeng.api.networking.energy.IEnergySource; import appeng.api.networking.security.BaseActionSource; import appeng.api.storage.IStorageMonitorable; +import appeng.core.sync.AppEngPacket; +import appeng.core.sync.packets.PacketPatternSlot; public class SlotPatternTerm extends SlotCraftingTerm { @@ -43,4 +48,9 @@ public class SlotPatternTerm extends SlotCraftingTerm return host.isSlotEnabled( groupNum ); } + public AppEngPacket getRequest(boolean shift) throws IOException + { + return new PacketPatternSlot( this.pattern, AEApi.instance().storage().createItemStack( getStack() ), shift ); + } + } diff --git a/core/sync/AppEngPacketHandlerBase.java b/core/sync/AppEngPacketHandlerBase.java index 5748f04d0..3e48d391c 100644 --- a/core/sync/AppEngPacketHandlerBase.java +++ b/core/sync/AppEngPacketHandlerBase.java @@ -19,6 +19,7 @@ import appeng.core.sync.packets.PacketMockExplosion; import appeng.core.sync.packets.PacketMultiPart; import appeng.core.sync.packets.PacketNewStorageDimension; import appeng.core.sync.packets.PacketPartPlacement; +import appeng.core.sync.packets.PacketPatternSlot; import appeng.core.sync.packets.PacketProgressBar; import appeng.core.sync.packets.PacketSwapSlots; import appeng.core.sync.packets.PacketSwitchGuis; @@ -64,7 +65,9 @@ public class AppEngPacketHandlerBase PACKET_SWITCH_GUIS(PacketSwitchGuis.class), - PACKET_SWAP_SLOTS(PacketSwapSlots.class); + PACKET_SWAP_SLOTS(PacketSwapSlots.class), + + PACKET_PATTERN_SLOT(PacketPatternSlot.class); final public Class pc; final public Constructor con; diff --git a/core/sync/packets/PacketPatternSlot.java b/core/sync/packets/PacketPatternSlot.java new file mode 100644 index 000000000..b26bea248 --- /dev/null +++ b/core/sync/packets/PacketPatternSlot.java @@ -0,0 +1,92 @@ +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 net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.inventory.IInventory; +import appeng.api.AEApi; +import appeng.api.storage.data.IAEItemStack; +import appeng.container.implementations.ContainerPatternTerm; +import appeng.core.sync.AppEngPacket; +import appeng.core.sync.network.INetworkInfo; +import appeng.util.item.AEItemStack; + +public class PacketPatternSlot extends AppEngPacket +{ + + final public IAEItemStack slotItem; + + final public IAEItemStack pattern[] = new IAEItemStack[9]; + + final public boolean shift; + + public IAEItemStack readItem(ByteBuf stream) throws IOException + { + boolean hasItem = stream.readBoolean(); + + if ( hasItem ) + return AEItemStack.loadItemStackFromPacket( stream ); + + return null; + } + + // automatic. + public PacketPatternSlot(ByteBuf stream) throws IOException { + + shift = stream.readBoolean(); + + slotItem = readItem( stream ); + + for (int x = 0; x < 9; x++) + pattern[x] = readItem( stream ); + } + + @Override + public void serverPacketData(INetworkInfo manager, AppEngPacket packet, EntityPlayer player) + { + EntityPlayerMP sender = (EntityPlayerMP) player; + if ( sender.openContainer instanceof ContainerPatternTerm ) + { + ContainerPatternTerm aebc = (ContainerPatternTerm) sender.openContainer; + aebc.craftOrGetItem( this ); + } + } + + private void writeItem(IAEItemStack slotItem, ByteBuf data) throws IOException + { + if ( slotItem == null ) + data.writeBoolean( false ); + else + { + data.writeBoolean( true ); + slotItem.writeToPacket( data ); + } + } + + // api + public PacketPatternSlot(IInventory pat, IAEItemStack slotItem, boolean shift) throws IOException { + + this.slotItem = slotItem; + this.shift = shift; + + ByteBuf data = Unpooled.buffer(); + + data.writeInt( getPacketID() ); + + data.writeBoolean( shift ); + + writeItem( slotItem, data ); + for (int x = 0; x < 9; x++) + { + pattern[x] = AEApi.instance().storage().createItemStack( pat.getStackInSlot( x ) ); + writeItem( pattern[x], data ); + } + + configureWrite( data ); + } + +} diff --git a/util/Platform.java b/util/Platform.java index ac7067bbb..e16d811ea 100644 --- a/util/Platform.java +++ b/util/Platform.java @@ -65,6 +65,7 @@ import appeng.api.networking.security.BaseActionSource; import appeng.api.networking.security.ISecurityGrid; import appeng.api.networking.storage.IStorageGrid; import appeng.api.storage.IMEInventory; +import appeng.api.storage.IMEMonitor; import appeng.api.storage.IMEMonitorHandlerReceiver; import appeng.api.storage.StorageChannel; import appeng.api.storage.data.IAEFluidStack; @@ -1516,4 +1517,54 @@ public class Platform player.rotationYaw = player.prevCameraYaw = player.cameraYaw = yaw; } + public static ItemStack extractItemsByRecipe(IEnergySource energySrc, BaseActionSource mySrc, IMEMonitor src, World w, IRecipe r, + ItemStack output, InventoryCrafting ci, ItemStack providedTemplate, int slot, IItemList aitems) + { + if ( energySrc.extractAEPower( 1, Actionable.SIMULATE, PowerMultiplier.CONFIG ) > 0.9 ) + { + if ( providedTemplate == null ) + return null; + + AEItemStack ae_req = AEItemStack.create( providedTemplate ); + ae_req.setStackSize( 1 ); + + IAEItemStack ae_ext = src.extractItems( ae_req, Actionable.MODULATE, mySrc ); + if ( ae_ext != null ) + { + ItemStack extracted = ae_ext.getItemStack(); + if ( extracted != null ) + { + energySrc.extractAEPower( 1, Actionable.MODULATE, PowerMultiplier.CONFIG ); + return extracted; + } + } + + if ( aitems != null && (ae_req.isOre() || providedTemplate.hasTagCompound() || providedTemplate.isItemStackDamageable()) ) + { + for (IAEItemStack x : aitems) + { + ItemStack sh = x.getItemStack(); + if ( (Platform.isSameItemType( providedTemplate, sh ) || ae_req.sameOre( x )) && !Platform.isSameItem( sh, output ) ) + { // Platform.isSameItemType( sh, providedTemplate ) + ItemStack cp = Platform.cloneItemStack( sh ); + cp.stackSize = 1; + ci.setInventorySlotContents( slot, cp ); + if ( r.matches( ci, w ) && Platform.isSameItem( r.getCraftingResult( ci ), output ) ) + { + IAEItemStack ex = src.extractItems( AEItemStack.create( cp ), Actionable.MODULATE, mySrc ); + if ( ex != null ) + { + energySrc.extractAEPower( 1, Actionable.MODULATE, PowerMultiplier.CONFIG ); + return ex.getItemStack(); + } + } + ci.setInventorySlotContents( slot, providedTemplate ); + } + } + } + + } + return null; + } + }