Posted August 3, 201411 yr I'm making a mod that has magic spells in it, and you cast these spells by selecting the spell from a book and then right-clicking a staff, which then casts the spell, provided that you have the correct number of runes, and the runes are removed. The problem is that if the player has enough of one rune but not another, the spell isn't cast but the rune they do have is still removed. For example, a spell called "destroy undead" requires 2 earth and 2 life runes. Right now, if a player has 2 earth but only 1 life rune, the earth runes and life rune are removed, but the spell isn't cast. I've tried two methods, and both produce similar results (this is in my staff class): static boolean consumeItems(IInventory inventory, int itemID, int count) { boolean flag = false; for (int slot = 0, remain = count; slot < inventory.getSizeInventory(); ++slot) { ItemStack itemstack = inventory.getStackInSlot(slot); if (itemstack != null && itemstack.itemID == itemID) { if ((remain -= itemstack.stackSize) <= 0) { flag = true; break; } } } if (flag) { for (int slot = 0; count > 0 && slot < inventory.getSizeInventory(); ++slot) { ItemStack itemstack = inventory.getStackInSlot(slot); if (itemstack != null && itemstack.itemID == itemID) { if ((count -= itemstack.stackSize) >= 0) { inventory.setInventorySlotContents(slot, (ItemStack)null); } else { itemstack.stackSize = -count; } } } } return flag; } public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { if(MagicGui.SelectedSpell == "DestroyUndead") if ((consumeItems(par3EntityPlayer.inventory, CombatOverhaul.EarthRune.itemID, 2)&& consumeItems(par3EntityPlayer.inventory, CombatOverhaul.LifeRune.itemID, 2))||par3EntityPlayer.capabilities.isCreativeMode) { par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); //change to custom sound later if (!par2World.isRemote) { par2World.spawnEntityInWorld(new EntityDestroyUndead(par2World, par3EntityPlayer)); } } return par1ItemStack; } public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { if(MagicGui.SelectedSpell == "DestroyUndead") { if(par3EntityPlayer.capabilities.isCreativeMode||(par3EntityPlayer.inventory.consumeInventoryItem(CombatOverhaul.LifeRune.itemID)&& par3EntityPlayer.inventory.consumeInventoryItem(CombatOverhaul.LifeRune.itemID)&& par3EntityPlayer.inventory.consumeInventoryItem(CombatOverhaul.EarthRune.itemID)&& par3EntityPlayer.inventory.consumeInventoryItem(CombatOverhaul.EarthRune.itemID))) { par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); //change to custom sound later if (!par2World.isRemote) { par2World.spawnEntityInWorld(new EntityDestroyUndead(par2World, par3EntityPlayer)); } } } return par1ItemStack; }
August 3, 201411 yr have you tried making your own method to look for runes and the amount of them and return a boolean? public boolean checkForItemsAndAmounts(ItemStack[] items, int[] amounts, InventoryPlayer invPlayer) { if (items.length != amounts.length)//Just to make sure you checked right { System.out.println("items and amounts do not match up in lengths."); return false; } boolean[] correctAmount = new boolean[items.length]; int[] amountCounter = new int[amounts.length]; for (int i = 0; i < correctAmount.length; i++) { correctAmount[i] = false; amountCounter[i] = 0; } //Check the players inventory for (int slot = 0; slot < invPlayer.getSizeInventory();slot++) { if (invPlayer.getStackInSlot(slot) != null) { //If something is in the slot check to see if it matches one of the given items for (int item = 0; item < items.length; item++) { if (invPlayer.getStackInSlot(slot).equals(items[item]) && !correctAmount[item]) { //If the found stack matches the item and don't have the correct amount amountCounter[item] += invPlayer.getStackInSlot(slot).stackSize; if (amountCounter[item] >= amounts[item]) { correctAmount[item] = true; } break;//no need to go through the rest of the loop, found the item. } } } } //make sure that all the amounts were found for (int i = 0; i < correctAmount.length; i++) { if (!correctAmount[i])return false; //If one of the amounts didn't add up, return false. } return true; } then you would call it with: public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { if(MagicGui.SelectedSpell == "DestroyUndead") { if (checkForItemsAndAmounts(new ItemStack[]{CombatOverhaul.LifeRune,CombatOverhaul.EarthRune}, new int[]{2,2}, par3EntityPlayer.inventory)) { if(par3EntityPlayer.capabilities.isCreativeMode||(par3EntityPlayer.inventory.consumeInventoryItem(CombatOverhaul.LifeRune.itemID)&& par3EntityPlayer.inventory.consumeInventoryItem(CombatOverhaul.LifeRune.itemID)&& par3EntityPlayer.inventory.consumeInventoryItem(CombatOverhaul.EarthRune.itemID)&& par3EntityPlayer.inventory.consumeInventoryItem(CombatOverhaul.EarthRune.itemID))) { par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); //change to custom sound later if (!par2World.isRemote) { par2World.spawnEntityInWorld(new EntityDestroyUndead(par2World, par3EntityPlayer)); } } } } return par1ItemStack; } You might have to tweak it here and there but the basic idea of the new method (posted in spoiler) is that it checks first before you use consumeInventoryItem (because that method when used does just eat an item if it can, so bad idea to run it in a IF statement) Currently updating my Mod to 1.10.2 https://bitbucket.org/hugo_the_dwarf/riseoftristram2016/src?at=master
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.