Adjusted Terminal Packet Limits.

Fixed random errors thrown when FMP is installed.
Finished Crafting Terminal Basic Features.
This commit is contained in:
AlgorithmX2 2014-02-05 01:25:44 -06:00
parent a165d533b6
commit e79e866417
13 changed files with 544 additions and 23 deletions

View file

@ -28,9 +28,11 @@ import appeng.client.gui.widgets.ITooltip;
import appeng.client.me.InternalSlotME;
import appeng.client.me.SlotME;
import appeng.client.render.AppEngRenderItem;
import appeng.container.slot.AppEngCraftingSlot;
import appeng.container.slot.AppEngSlot;
import appeng.container.slot.AppEngSlot.hasCalculatedValidness;
import appeng.container.slot.OptionalSlotFake;
import appeng.container.slot.SlotCraftingTerm;
import appeng.container.slot.SlotDisabled;
import appeng.container.slot.SlotFake;
import appeng.container.slot.SlotInaccessable;
@ -124,6 +126,35 @@ public abstract class AEBaseGui extends GuiContainer
return;
}
if ( slot instanceof SlotCraftingTerm )
{
if ( key == 6 )
return; // prevent weird double clicks..
InventoryAction action = null;
IAEItemStack stack = null;
if ( key == 1 )
action = InventoryAction.CRAFT_SHIFT;
else
action = ctrlDown == 1 ? InventoryAction.CRAFT_STACK : InventoryAction.CRAFT_ITEM;
if ( action != null )
{
PacketInventoryAction p;
try
{
p = new PacketInventoryAction( action, slotIdx, stack );
PacketDispatcher.sendPacketToServer( p.getPacket() );
}
catch (IOException e)
{
e.printStackTrace();
}
}
return;
}
if ( slot instanceof SlotME )
{
InventoryAction action = null;
@ -513,8 +544,8 @@ public abstract class AEBaseGui extends GuiContainer
{
if ( ((AppEngSlot) s).isValid == hasCalculatedValidness.NotAvailable )
{
boolean isValid = s.isItemValid( is ) || s instanceof SlotOutput || s instanceof SlotDisabled || s instanceof SlotInaccessable
|| s instanceof SlotFake;
boolean isValid = s.isItemValid( is ) || s instanceof SlotOutput || s instanceof AppEngCraftingSlot || s instanceof SlotDisabled
|| s instanceof SlotInaccessable || s instanceof SlotFake;
if ( isValid && s instanceof SlotRestrictedInput )
{
try

View file

@ -31,6 +31,7 @@ import appeng.client.me.InternalSlotME;
import appeng.client.me.SlotME;
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.SlotInaccessable;
@ -48,7 +49,7 @@ public abstract class AEBaseContainer extends Container
final TileEntity tileEntity;
final IPart part;
BaseActionSource mySrc;
final protected BaseActionSource mySrc;
int ticksSinceCheck = 900;
@ -431,6 +432,18 @@ public abstract class AEBaseContainer extends Container
{
Slot s = getSlot( slot );
if ( s instanceof SlotCraftingTerm )
{
switch (action)
{
case CRAFT_SHIFT:
case CRAFT_ITEM:
case CRAFT_STACK:
((SlotCraftingTerm) s).doClick( action, player );
default:
}
}
if ( s instanceof SlotFake )
{
ItemStack hand = player.inventory.getItemStack();

View file

@ -1,24 +1,69 @@
package appeng.container.implementations;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.CraftingManager;
import appeng.api.storage.IStorageMonitorable;
import appeng.container.slot.SlotNormal;
import appeng.container.slot.SlotOutput;
import appeng.container.ContainerNull;
import appeng.container.slot.SlotCraftingMatrix;
import appeng.container.slot.SlotCraftingTerm;
import appeng.parts.reporting.PartCraftingTerminal;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.IAEAppEngInventory;
import appeng.tile.inventory.InvOperation;
public class ContainerCraftingTerm extends ContainerMEMonitorable
public class ContainerCraftingTerm extends ContainerMEMonitorable implements IAEAppEngInventory
{
AppEngInternalInventory output = new AppEngInternalInventory( this, 1 );
SlotCraftingMatrix craftingSlots[] = new SlotCraftingMatrix[9];
SlotCraftingTerm outputSlot;
PartCraftingTerminal ct;
SlotNormal craftingSlots[] = new SlotNormal[9];
SlotOutput outputSlot;
/**
* Callback for when the crafting matrix is changed.
*/
public void onCraftMatrixChanged(IInventory par1IInventory)
{
ContainerNull cn = new ContainerNull();
InventoryCrafting ic = new InventoryCrafting( cn, 3, 3 );
for (int x = 0; x < 9; x++)
ic.setInventorySlotContents( x, craftingSlots[x].getStack() );
outputSlot.putStack( CraftingManager.getInstance().findMatchingRecipe( ic, getPlayerInv().player.worldObj ) );
}
public ContainerCraftingTerm(InventoryPlayer ip, IStorageMonitorable montiorable) {
super( ip, montiorable, false );
ct = (PartCraftingTerminal) montiorable;
IInventory crafting = ct.getInventoryByName( "crafting" );
for (int y = 0; y < 3; y++)
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 ) );
bindPlayerInventory( ip, 0, 0 );
onCraftMatrixChanged( crafting );
}
@Override
public void saveChanges()
{
}
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removedStack, ItemStack newStack)
{
}
}

View file

@ -137,7 +137,7 @@ public class ContainerMEMonitorable extends AEBaseContainer implements IMEMonito
int items = 0;
for (IAEItemStack send : monitorCache)
{
if ( items > 2000 )
if ( piu.getLength() > 20000 )
{
items = 0;
Packet p = piu.getPacket();

View file

@ -1,15 +1,155 @@
package appeng.container.slot;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.SlotCrafting;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.stats.AchievementList;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent;
import cpw.mods.fml.common.registry.GameRegistry;
public class AppEngCraftingSlot extends SlotCrafting
public class AppEngCraftingSlot extends AppEngSlot
{
public AppEngCraftingSlot(EntityPlayer par1EntityPlayer, IInventory par2iInventory, IInventory par3iInventory, int par4,
int par5, int par6) {
super( par1EntityPlayer, par2iInventory, par3iInventory, par4, par5, par6 );
/** The craft matrix inventory linked to this result slot. */
private final IInventory craftMatrix;
/** The player that is using the GUI where this slot resides. */
private EntityPlayer thePlayer;
/**
* The number of items that have been crafted so far. Gets passed to ItemStack.onCrafting before being reset.
*/
private int amountCrafted;
public AppEngCraftingSlot(EntityPlayer par1EntityPlayer, IInventory par2IInventory, IInventory par3IInventory, int par4, int par5, int par6) {
super( par3IInventory, par4, par5, par6 );
this.thePlayer = par1EntityPlayer;
this.craftMatrix = par2IInventory;
}
/**
* Check if the stack is a valid item for this slot. Always true beside for the armor slots.
*/
public boolean isItemValid(ItemStack par1ItemStack)
{
return false;
}
/**
* Decrease the size of the stack in slot (first int arg) by the amount of the second int arg. Returns the new
* stack.
*/
public ItemStack decrStackSize(int par1)
{
if ( this.getHasStack() )
{
this.amountCrafted += Math.min( par1, this.getStack().stackSize );
}
return super.decrStackSize( par1 );
}
/**
* the itemStack passed in is the output - ie, iron ingots, and pickaxes, not ore and wood. Typically increases an
* internal count then calls onCrafting(item).
*/
protected void onCrafting(ItemStack par1ItemStack, int par2)
{
this.amountCrafted += par2;
this.onCrafting( par1ItemStack );
}
/**
* the itemStack passed in is the output - ie, iron ingots, and pickaxes, not ore and wood.
*/
protected void onCrafting(ItemStack par1ItemStack)
{
par1ItemStack.onCrafting( this.thePlayer.worldObj, this.thePlayer, this.amountCrafted );
this.amountCrafted = 0;
if ( par1ItemStack.itemID == Block.workbench.blockID )
{
this.thePlayer.addStat( AchievementList.buildWorkBench, 1 );
}
else if ( par1ItemStack.itemID == Item.pickaxeWood.itemID )
{
this.thePlayer.addStat( AchievementList.buildPickaxe, 1 );
}
else if ( par1ItemStack.itemID == Block.furnaceIdle.blockID )
{
this.thePlayer.addStat( AchievementList.buildFurnace, 1 );
}
else if ( par1ItemStack.itemID == Item.hoeWood.itemID )
{
this.thePlayer.addStat( AchievementList.buildHoe, 1 );
}
else if ( par1ItemStack.itemID == Item.bread.itemID )
{
this.thePlayer.addStat( AchievementList.makeBread, 1 );
}
else if ( par1ItemStack.itemID == Item.cake.itemID )
{
this.thePlayer.addStat( AchievementList.bakeCake, 1 );
}
else if ( par1ItemStack.itemID == Item.pickaxeStone.itemID )
{
this.thePlayer.addStat( AchievementList.buildBetterPickaxe, 1 );
}
else if ( par1ItemStack.itemID == Item.swordWood.itemID )
{
this.thePlayer.addStat( AchievementList.buildSword, 1 );
}
else if ( par1ItemStack.itemID == Block.enchantmentTable.blockID )
{
this.thePlayer.addStat( AchievementList.enchantments, 1 );
}
else if ( par1ItemStack.itemID == Block.bookShelf.blockID )
{
this.thePlayer.addStat( AchievementList.bookcase, 1 );
}
}
public void onPickupFromSlot(EntityPlayer par1EntityPlayer, ItemStack par2ItemStack)
{
GameRegistry.onItemCrafted( par1EntityPlayer, par2ItemStack, craftMatrix );
this.onCrafting( par2ItemStack );
for (int i = 0; i < this.craftMatrix.getSizeInventory(); ++i)
{
ItemStack itemstack1 = this.craftMatrix.getStackInSlot( i );
if ( itemstack1 != null )
{
this.craftMatrix.decrStackSize( i, 1 );
if ( itemstack1.getItem().hasContainerItem() )
{
ItemStack itemstack2 = itemstack1.getItem().getContainerItemStack( itemstack1 );
if ( itemstack2.isItemStackDamageable() && itemstack2.getItemDamage() > itemstack2.getMaxDamage() )
{
MinecraftForge.EVENT_BUS.post( new PlayerDestroyItemEvent( thePlayer, itemstack2 ) );
itemstack2 = null;
}
if ( itemstack2 != null
&& (!itemstack1.getItem().doesContainerItemLeaveCraftingGrid( itemstack1 ) || !this.thePlayer.inventory
.addItemStackToInventory( itemstack2 )) )
{
if ( this.craftMatrix.getStackInSlot( i ) == null )
{
this.craftMatrix.setInventorySlotContents( i, itemstack2 );
}
else
{
this.thePlayer.dropPlayerItem( itemstack2 );
}
}
}
}
}
}
}

View file

@ -1,12 +1,45 @@
package appeng.container.slot;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
public class SlotCraftingMatrix extends AppEngSlot
{
public SlotCraftingMatrix(IInventory par1iInventory, int par2, int par3, int par4) {
Container c;
public SlotCraftingMatrix(Container c, IInventory par1iInventory, int par2, int par3, int par4) {
super( par1iInventory, par2, par3, par4 );
this.c = c;
}
@Override
public boolean isPlayerSide()
{
return true;
}
@Override
public void clearStack()
{
super.clearStack();
c.onCraftMatrixChanged( inventory );
}
@Override
public ItemStack decrStackSize(int par1)
{
ItemStack is = super.decrStackSize( par1 );
c.onCraftMatrixChanged( inventory );
return is;
}
@Override
public void putStack(ItemStack par1ItemStack)
{
super.putStack( par1ItemStack );
c.onCraftMatrixChanged( inventory );
}
}

View file

@ -0,0 +1,231 @@
package appeng.container.slot;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
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;
import appeng.api.storage.IStorageMonitorable;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.container.ContainerNull;
import appeng.helpers.InventoryAction;
import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import appeng.util.inv.AdaptorPlayerHand;
import appeng.util.item.AEItemStack;
public class SlotCraftingTerm extends AppEngCraftingSlot
{
private final IInventory craftMatrix;
private final BaseActionSource mySrc;
private final IEnergySource energySrc;
private final IStorageMonitorable storage;
public SlotCraftingTerm(EntityPlayer player, BaseActionSource mySrc, IEnergySource energySrc, IStorageMonitorable storage, IInventory cMatrix,
IInventory output, int x, int y) {
super( player, cMatrix, output, 0, x, y );
this.energySrc = energySrc;
this.storage = storage;
this.mySrc = mySrc;
craftMatrix = cMatrix;
}
@Override
public boolean canTakeStack(EntityPlayer par1EntityPlayer)
{
return false;
}
@Override
public void onPickupFromSlot(EntityPlayer p, ItemStack is)
{
}
private ItemStack extractItemsByRecipe(IMEMonitor<IAEItemStack> src, World w, IRecipe r, ItemStack output, InventoryCrafting ci,
ItemStack providedTemplate, int slot, IItemList<IAEItemStack> 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;
}
ItemStack craftItem(EntityPlayer p, ItemStack request, IMEMonitor<IAEItemStack> inv, IItemList all)
{
// update crafting matrx...
ItemStack is = getStack();
if ( is != null && Platform.isSameItem( request, is ) )
{
ItemStack[] set = new ItemStack[craftMatrix.getSizeInventory()];
// add one of each item to the items on the board...
List<ItemStack> drops = new ArrayList();
if ( Platform.isServer() )
{
InventoryCrafting ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
for (int x = 0; x < 9; x++)
ic.setInventorySlotContents( x, craftMatrix.getStackInSlot( x ) );
IRecipe r = Platform.findMatchingRecipe( ic, p.worldObj );
if ( r == null )
return null;
is = r.getCraftingResult( ic );
if ( r != null && inv != null )
{
for (int x = 0; x < craftMatrix.getSizeInventory(); x++)
{
if ( craftMatrix.getStackInSlot( x ) != null )
{
set[x] = extractItemsByRecipe( inv, p.worldObj, r, is, ic, craftMatrix.getStackInSlot( x ), x, all );
ic.setInventorySlotContents( x, set[x] );
}
}
}
}
super.onPickupFromSlot( p, is );
// add one of each item to the items on the board...
if ( Platform.isServer() )
{
// set new items onto the crafting table...
for (int x = 0; x < craftMatrix.getSizeInventory(); x++)
{
if ( craftMatrix.getStackInSlot( x ) == null )
craftMatrix.setInventorySlotContents( x, set[x] );
else if ( set[x] != null )
{
// eek! put it back!
IAEItemStack fail = inv.injectItems( AEItemStack.create( set[x] ), Actionable.MODULATE, mySrc );
if ( fail != null )
drops.add( fail.getItemStack() );
}
}
}
// shouldn't be nessiary...
p.openContainer.onCraftMatrixChanged( craftMatrix );
if ( drops.size() > 0 )
Platform.spawnDrops( p.worldObj, (int) p.posX, (int) p.posY, (int) p.posZ, drops );
return is;
}
return null;
}
public void doClick(InventoryAction action, EntityPlayer who)
{
if ( getStack() == null )
return;
if ( Platform.isClient() )
return;
IMEMonitor<IAEItemStack> inv = storage.getItemInventory();
int howManyPerCraft = getStack().stackSize;
int maxTimesToCraft = 0;
InventoryAdaptor ia = null;
if ( action == InventoryAction.CRAFT_SHIFT ) // craft into player inventory...
{
ia = InventoryAdaptor.getAdaptor( who, null );
maxTimesToCraft = (int) Math.floor( (double) getStack().getMaxStackSize() / (double) howManyPerCraft );
}
else if ( action == InventoryAction.CRAFT_STACK ) // craft into hand, full stack
{
ia = new AdaptorPlayerHand( who );
maxTimesToCraft = (int) Math.floor( (double) getStack().getMaxStackSize() / (double) howManyPerCraft );
}
else
// pick up what was crafted...
{
ia = new AdaptorPlayerHand( who );
maxTimesToCraft = 1;
}
if ( ia == null )
return;
ItemStack rs = Platform.cloneItemStack( getStack() );
if ( rs == null )
return;
for (int x = 0; x < maxTimesToCraft; x++)
{
if ( ia.simulateAdd( rs ) == null )
{
IItemList<IAEItemStack> all = inv.getStorageList();
ItemStack extra = ia.addItems( craftItem( who, rs, inv, all ) );
if ( extra != null )
{
List<ItemStack> drops = new ArrayList();
drops.add( extra );
Platform.spawnDrops( who.worldObj, (int) who.posX, (int) who.posY, (int) who.posZ, drops );
return;
}
}
}
((EntityPlayerMP) who).updateHeldItem();
}
}

View file

@ -274,16 +274,19 @@ public class ApiPart implements IPartHelper
AELog.severe( "Error, Expected layer to NOT implement LayerBase but it DID." );
}
if ( !(fish instanceof TileCableBus) )
if ( !fullPath.contains( ".fmp." ) )
{
bads = true;
AELog.severe( "Error, Expected layer to implement TileCableBus did not." );
}
if ( !(fish instanceof TileCableBus) )
{
bads = true;
AELog.severe( "Error, Expected layer to implement TileCableBus did not." );
}
if ( !(fish instanceof TileEntity) )
{
bads = true;
AELog.severe( "Error, Expected layer to implement TileEntity did not." );
if ( !(fish instanceof TileEntity) )
{
bads = true;
AELog.severe( "Error, Expected layer to implement TileEntity did not." );
}
}
if ( !bads )

View file

@ -77,6 +77,11 @@ public class PacketMEInventoryUpdate extends AppEngPacket
empty = false;
}
public int getLength()
{
return data.size();
}
public boolean isEmpty()
{
return empty;

View file

@ -5,6 +5,9 @@ public enum InventoryAction
// standard vanilla mechanics.
PICKUP_OR_SETDOWN, SPLIT_OR_PLACESINGLE, CREATIVE_DUPLICATE, SHIFT_CLICK,
// crafting term
CRAFT_STACK, CRAFT_ITEM, CRAFT_SHIFT,
// extra...
MOVE_REGION, PICKUP_SINGLE
}

View file

@ -42,4 +42,12 @@ public class PartCraftingTerminal extends PartTerminal implements IAEAppEngInven
// :)
}
@Override
public IInventory getInventoryByName(String name)
{
if ( name.equals( "crafting" ) )
return craftingGrid;
return super.getInventoryByName( name );
}
}

View file

@ -30,6 +30,8 @@ public class AEItemDef
@SideOnly(Side.CLIENT)
public List tooltip;
public boolean isOre;
public AEItemDef copy()
{
AEItemDef t = new AEItemDef();
@ -39,6 +41,7 @@ public class AEItemDef
t.dspDamage = dspDamage;
t.maxDamage = maxDamage;
t.tagCompound = tagCompound;
t.isOre = isOre;
return t;
}

View file

@ -85,6 +85,7 @@ public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemS
setCountRequestable( 0 );
def.reHash();
def.isOre = OreHelper.instance.isOre( this );
}
public static AEItemStack create(Object a)
@ -553,4 +554,9 @@ public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemS
{
return StorageChannel.ITEMS;
}
public boolean isOre()
{
return def.isOre;
}
}