Jump to content

[SOLVED]Check for and consume multiple itemstacks?


Hakaan256

Recommended Posts

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;
}

 

 

Link to comment
Share on other sites

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)

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.