package minefantasy.mf2.block.tileentity; import java.util.List; import java.util.Random; import minefantasy.mf2.api.crafting.IBasicMetre; import minefantasy.mf2.api.crafting.engineer.IBombComponent; import minefantasy.mf2.api.helpers.ToolHelper; import minefantasy.mf2.api.knowledge.ResearchLogic; import minefantasy.mf2.api.rpg.RPGElements; import minefantasy.mf2.api.rpg.SkillList; import minefantasy.mf2.item.gadget.ItemBomb; import minefantasy.mf2.item.gadget.ItemExplodingArrow; import minefantasy.mf2.item.list.ToolListMF; import minefantasy.mf2.knowledge.KnowledgeListMF; import minefantasy.mf2.network.packet.BombBenchPacket; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.ISidedInventory; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.StatCollector; import net.minecraft.world.WorldServer; public class TileEntityBombBench extends TileEntity implements IInventory, ISidedInventory, IBasicMetre { private ItemStack[] inv = new ItemStack[6]; private Random rand = new Random(); public float progress; public float maxProgress = 25F; public boolean hasRecipe; private int ticksExisted; @Override public void updateEntity() { ++ticksExisted; if(!worldObj.isRemote && (hasRecipe || ticksExisted % 100 == 0)) { syncData(); } } public boolean tryCraft(EntityPlayer user, boolean pressUsed) { boolean sticky = !pressUsed && ResearchLogic.hasInfoUnlocked(user, KnowledgeListMF.stickybomb) && user.getHeldItem() != null && user.getHeldItem().getItem() == Items.slime_ball; if(!worldObj.isRemote && sticky && applySlime()) { user.inventory.consumeInventoryItem(Items.slime_ball); return true; } ItemStack result = findResult(); hasRecipe = result != null; if(result == null) { progress = 0F; } else if((pressUsed || ToolHelper.getCrafterTool(user.getHeldItem()).equalsIgnoreCase("spanner"))) { if(!pressUsed && user.getHeldItem() != null) { worldObj.playSoundEffect(xCoord+0.5, yCoord, zCoord+0.5, "minefantasy2:block.twistbolt", 0.25F, 1.0F); user.getHeldItem().damageItem(1, user); if(user.getHeldItem().getItemDamage() >= user.getHeldItem().getMaxDamage()) { user.destroyCurrentEquippedItem(); } } float efficiency = pressUsed ? maxProgress : ToolHelper.getCrafterEfficiency(user.getHeldItem()); if(!pressUsed && user.swingProgress > 0 && user.swingProgress <= 1.0) { efficiency *= (0.5F-user.swingProgress); } if(!worldObj.isRemote) { progress += efficiency; } if((progress >= maxProgress && craftItem(result))) { worldObj.playSoundEffect(xCoord+0.5, yCoord, zCoord+0.5, "random.door_open", 0.35F, 0.5F); progress = 0; if(user != null) { SkillList.engineering.addXP(user, 2); } boolean isArrow = isMatch(0, "arrow") || isMatch(0, "bolt"); for(int a = 0; a < 4; a++) { if(!(isArrow && a == 3)) { ItemStack item = getStackInSlot(a); if(item != null && item.getItem().getContainerItem(item) != null) { //START CONTAINER CODE ItemStack cont = item.getItem().getContainerItem(item); ItemStack spare = getStackInSlot(5); if(spare == null) { setInventorySlotContents(5, cont); cont = null; } else if(spare.isItemEqual(cont)) { if(spare.stackSize + cont.stackSize <= spare.getMaxStackSize()) { spare.stackSize += cont.stackSize; cont = null; } else { int room_left = spare.getMaxStackSize() - spare.stackSize; spare.stackSize += room_left; cont.stackSize -= room_left; } } if(cont != null && !worldObj.isRemote) { EntityItem ei = new EntityItem(worldObj, xCoord+0.5, yCoord+0.5, zCoord+0.5, cont); worldObj.spawnEntityInWorld(ei); } } //END CONTAINER CODE decrStackSize(a, 1); } } } return true; } return false; } private boolean applySlime() { ItemStack res = getStackInSlot(4); if(res != null && res.getItem() instanceof ItemBomb) { if(res.hasTagCompound() && !res.getTagCompound().hasKey("stickyBomb")) { res.getTagCompound().setBoolean("stickyBomb", true); return true; } } return false; } private boolean craftItem(ItemStack result) { if(inv[4] == null) { this.setInventorySlotContents(4, result); return true; } else { if(areItemsEqual(result, inv[4]) && (inv[4].stackSize + result.stackSize) <= inv[4].getMaxStackSize()) { inv[4].stackSize++; return true; } else { return false; } } } public void syncData() { if(worldObj.isRemote)return; List<EntityPlayer> players = ((WorldServer)worldObj).playerEntities; for(int i = 0; i < players.size(); i++) { EntityPlayer player = players.get(i); ((WorldServer)worldObj).getEntityTracker().func_151248_b(player, new BombBenchPacket(this).generatePacket()); } } private boolean areItemsEqual(ItemStack bomb1, ItemStack bomb2) { if(ItemBomb.getCasing(bomb1) != ItemBomb.getCasing(bomb2)) { return false; } if(ItemBomb.getPowder(bomb1) != ItemBomb.getPowder(bomb2)) { return false; } if(ItemBomb.getFilling(bomb1) != ItemBomb.getFilling(bomb2)) { return false; } if(ItemBomb.getFuse(bomb1) != ItemBomb.getFuse(bomb2)) { return false; } return bomb1.isItemEqual(bomb2); } public void onInventoryChanged() { } private ItemStack findResult() { boolean isArrow = isMatch(0, "arrow") || isMatch(0, "bolt"); if(!isMatch(1, "powder") || (!isArrow && !isMatch(3, "fuse"))) { return null; } byte caseTier = -1; byte filling = 0; byte fuse = -1; byte powder = -1; Item design = null; String com0 = getComponentType(inv[0]); String com1 = getComponentType(inv[1]); String com2 = getComponentType(inv[2]); String com3 = getComponentType(inv[3]); if(com0 != null) { caseTier = getComponentTier(inv[0]); String type = com0; design = getDesignCrafted(type); } if(com1 != null) { if(com1.equalsIgnoreCase("powder")) { powder = getComponentTier(inv[1]); } else { return null; } } else return null; if(com2 != null) { if(com2.equalsIgnoreCase("filling")) { filling = getComponentTier(inv[2]); } else { return null; } } if(isArrow || com3 != null) { if(!isArrow) { if(com3.equalsIgnoreCase("fuse")) { fuse = getComponentTier(inv[3]); } else { return null; } } } else return null; if(design != null && isArrow && powder > -1) { return ItemExplodingArrow.createBombArrow(design, powder, filling); } else if(design != null && fuse > -1 && powder > -1) { return ItemBomb.createExplosive(design, caseTier, filling, fuse, powder, 1, false); } return null; } private Item getDesignCrafted(String type) { if(type.equalsIgnoreCase("bombcase")) { return ToolListMF.bomb_custom; } if(type.equalsIgnoreCase("minecase")) { return ToolListMF.mine_custom; } if(type.equalsIgnoreCase("arrow")) { return ToolListMF.exploding_arrow; } if(type.equalsIgnoreCase("bolt")) { return ToolListMF.exploding_bolt; } return null; } private boolean isMatch(int slot, String type) { return isMatch(inv[slot], type); } public static boolean isMatch(ItemStack item, String type) { String component = getComponentType(item); return component != null && component.equalsIgnoreCase(type); } public static String getComponentType(ItemStack item) { if(item != null && item.getItem() != null && item.getItem() instanceof IBombComponent) { return ((IBombComponent)item.getItem()).getComponentType(); } return null; } public static byte getComponentTier(ItemStack item) { if(item != null && item.getItem() != null && item.getItem() instanceof IBombComponent) { return ((IBombComponent)item.getItem()).getTier(); } return (byte)0; } //INVENORY @Override public int getSizeInventory() { return inv.length; } @Override public ItemStack getStackInSlot(int slot) { return inv[slot]; } @Override public ItemStack decrStackSize(int slot, int num) { onInventoryChanged(); if (this.inv[slot] != null) { ItemStack itemstack; if (this.inv[slot].stackSize <= num) { itemstack = this.inv[slot]; this.inv[slot] = null; return itemstack; } else { itemstack = this.inv[slot].splitStack(num); if (this.inv[slot].stackSize == 0) { this.inv[slot] = null; } return itemstack; } } else { return null; } } @Override public ItemStack getStackInSlotOnClosing(int slot) { return inv[slot]; } @Override public void setInventorySlotContents(int slot, ItemStack item) { onInventoryChanged(); inv[slot] = item; } @Override public String getInventoryName() { return "gui.bombcraftmf.name"; } @Override public boolean hasCustomInventoryName() { return false; } @Override public int getInventoryStackLimit() { return 64; } @Override public boolean isUseableByPlayer(EntityPlayer user) { return user.getDistance(xCoord+0.5D, yCoord+0.5D, zCoord+0.5D) < 8D; } @Override public void openInventory() { } @Override public void closeInventory() { } @Override public boolean isItemValidForSlot(int slot, ItemStack item) { if(this.isMatch(item, "bolt") || this.isMatch(item, "arrow") || this.isMatch(item, "bombcase") || this.isMatch(item, "minecase")) { return slot == 0; } if(this.isMatch(item, "powder")) { return slot == 1; } if(this.isMatch(item, "filling")) { return slot == 2; } if(this.isMatch(item, "fuse")) { return slot == 3; } return false; } @Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); NBTTagList savedItems = nbt.getTagList("Items", 10); this.inv = new ItemStack[this.getSizeInventory()]; for (int i = 0; i < savedItems.tagCount(); ++i) { NBTTagCompound savedSlot = savedItems.getCompoundTagAt(i); byte slotNum = savedSlot.getByte("Slot"); if (slotNum >= 0 && slotNum < this.inv.length) { this.inv[slotNum] = ItemStack.loadItemStackFromNBT(savedSlot); } } progress = nbt.getFloat("progress"); maxProgress = nbt.getFloat("maxProgress"); hasRecipe = nbt.getBoolean("hasRecipe"); } @Override public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); NBTTagList savedItems = new NBTTagList(); for (int i = 0; i < this.inv.length; ++i) { if (this.inv[i] != null) { NBTTagCompound savedSlot = new NBTTagCompound(); savedSlot.setByte("Slot", (byte)i); this.inv[i].writeToNBT(savedSlot); savedItems.appendTag(savedSlot); } } nbt.setTag("Items", savedItems); nbt.setFloat("progress", progress); nbt.setFloat("maxProgress", maxProgress); nbt.setBoolean("hasRecipe", hasRecipe); } @Override public int[] getAccessibleSlotsFromSide(int side) { return new int[]{0, 1, 2, 3, 4}; } @Override public boolean canInsertItem(int slot, ItemStack item, int side) { return this.isItemValidForSlot(slot, item); } @Override public boolean canExtractItem(int slot, ItemStack item, int side) { return slot == 4; } @Override public int getMetreScale(int size) { return (int)Math.min(size, (float)size / maxProgress * progress); } @Override public boolean shouldShowMetre() { return true; } @Override public String getLocalisedName() { return StatCollector.translateToLocal("tile.bombBench.name"); } }