Jump to content

[Solved] Limiting what goes in inventory slots


defiant810

Recommended Posts

Hey there, quick question:

 

How does one block certain items from going into an inventory (like how the vanilla Furnace doesn't allow non-fuels in the bottom slot)?

 

Right now this is my code in my tile entity:

@Override
public void setInventorySlotContents(int slot, ItemStack toPut)
{
	ItemStack old = getStackInSlot(slot);

	if (toPut != null && (toPut.itemID == Item.stick.shiftedIndex || toPut.itemID == Item.pickaxeWood.shiftedIndex 
			|| toPut.itemID == Item.shovelWood.shiftedIndex))
	{
		inventory[slot] = toPut;

		if (toPut.itemID == Item.stick.shiftedIndex) 
		{
			capsuleContained = CapsuleType.LOW;
		} 
		else if (toPut.itemID == Item.pickaxeWood.shiftedIndex) 
		{
			capsuleContained = CapsuleType.MEDIUM;
		}
		else if (toPut.itemID == Item.shovelWood.shiftedIndex)
		{
			capsuleContained = CapsuleType.HIGH;
		}

		if(toPut.stackSize > getInventoryStackLimit())
		{
			toPut.stackSize = getInventoryStackLimit();
		}
	}
	else if (toPut == null)
	{
		inventory[slot] = toPut;
		capsuleContained = CapsuleType.NONE;
	}
	else
	{
		//It eats other items...
	}
}

 

As of right now, the inventory (of only one slot) only allows sticks, wooden picks, and wooden shovels (testing items). When I try to put other things in, instead of doing nothing, the slot remains empty but the original item disappears. How can I make it so that item doesn't disappear, and just stays in the player's cursor?

 

And yes, I've already looked at the furnace code, it didn't help.

Creator and co-author of the mod Essencraft: https://github.com/defiant810/Essencraft

 

Please, dear God, learn Java before trying to mod. It saves ALL of us time.

Link to comment
Share on other sites

The vanilla furnace allows non-fuels in the bottom slot, it just doesn't burn them when it's time to get new fuel.

 

There would have to be a function elsewhere that determines what can/can't be put in to a slot, before that function gets called. It seems that setInventorySlotContents happens after the testing, whereever that could be.

Link to comment
Share on other sites

Hmmm... OK, that makes sense.

 

Does anyone out there know if there is a method that defines what can and can't be put into certain slots? Or another way to solve this problem?

Creator and co-author of the mod Essencraft: https://github.com/defiant810/Essencraft

 

Please, dear God, learn Java before trying to mod. It saves ALL of us time.

Link to comment
Share on other sites

I looked through the same two classes and came up with the same results. I guess the dropping the inventory solution will be good temporarily until I figure out how to block items from slots, if it is possible.

Creator and co-author of the mod Essencraft: https://github.com/defiant810/Essencraft

 

Please, dear God, learn Java before trying to mod. It saves ALL of us time.

Link to comment
Share on other sites

So I tried making a method that takes the item if it is invalid, sets the slot to null, and ejects the item into the world.

 

Good news: it works.

Bad news: it works twice.

 

Whenever it ejects the ItemStack, it makes one legit version that can be picked up, and then it also ejects a ghost version of the same stack that cant be picked up; it just sits there and mocks you.

 

Here is the TileEntity code:

@Override
public void setInventorySlotContents(int slot, ItemStack toPut)
{
	inventory[slot] = toPut;

	if(toPut != null)
	{
		if(toPut.itemID == Item.stick.shiftedIndex)
		{
			this.capsuleContained = CapsuleType.LOW;
		}
		else if(toPut.itemID == Item.pickaxeWood.shiftedIndex)
		{
			this.capsuleContained = CapsuleType.MEDIUM;	
		}
		else if(toPut.itemID == Item.shovelWood.shiftedIndex)
		{
			this.capsuleContained = CapsuleType.HIGH;
		}
		else
		{
			capsuleContained = CapsuleType.NONE;
			checkSlot(slot);
		}
	}
	else
	{
		capsuleContained = CapsuleType.NONE;
	}

	if(toPut != null && toPut.stackSize > getInventoryStackLimit())
	{
		toPut.stackSize = getInventoryStackLimit();
	}
	}

@Override
protected void checkSlot(int slot)
{
	ItemStack contents = getStackInSlot(slot);

	boolean valid = (contents.itemID == Item.stick.shiftedIndex || 
		contents.itemID == Item.pickaxeWood.shiftedIndex ||
		contents.itemID == Item.shovelWood.shiftedIndex);

	if(!valid)
	{
		inventory[slot] = null;
		dropItem(contents);
	}
}

 

And here is the dropItem method from the super class:

protected void dropItem(ItemStack contents)
{
	Random rand = new Random();

	float rx = rand.nextFloat() * 0.8F + 0.1F;
	float ry = rand.nextFloat() * 0.8F + 0.1F;
	float rz = rand.nextFloat() * 0.8F + 0.1F;

	EntityItem entity = new EntityItem(this.getWorldObj(), this.xCoord + rx, this.yCoord + ry,
		this.zCoord + rz, new ItemStack(contents.itemID, contents.stackSize, contents.getItemDamage()));

	if(contents.hasTagCompound())
	{
		entity.item.setTagCompound((NBTTagCompound)contents.getTagCompound().copy());
	}

	entity.motionX = rand.nextGaussian() * 0.8f;
	entity.motionY = rand.nextGaussian() * 0.8f;
	entity.motionZ = rand.nextGaussian() * 0.8f;
	this.getWorldObj().spawnEntityInWorld(entity);
}

 

I don't see where it could be creating two stacks. This is (almost) the same code I use to eject the items out of my other blocks, and that works just fine.

 

EDIT:

 

Here are the two files that are being used here:

https://github.com/SeanMoss/QuantumCraft/tree/master/src/common/quantumcraft/common/tileentity

Creator and co-author of the mod Essencraft: https://github.com/defiant810/Essencraft

 

Please, dear God, learn Java before trying to mod. It saves ALL of us time.

Link to comment
Share on other sites

The dupe item would be a client-side spawned item.  Make sure in your code that spawns the entityItem, that it is only called server-side.

 

For custom inventory validation--I used a custom slot and used the isItemValidForSlot method in the slot.  However, I had to use some workarounds in order to get it to work while shift-clicking items. (normal transfer is easy with the slot method).

 

Using this method, I am able to sucessfully tell a 12 slot inventory that it can only accept certain items in slots 0-5, different items in 6-8, and finally a different set it slots 9-11.

 

I can provide links to source if needed.

Link to comment
Share on other sites

A link to source would be massively appreciated. And how would one make sure that the item spawn only happens on the server? Would the @Sided annotation do that, ir does it need to happen some other way?

 

Creator and co-author of the mod Essencraft: https://github.com/defiant810/Essencraft

 

Please, dear God, learn Java before trying to mod. It saves ALL of us time.

Link to comment
Share on other sites

if(world.isRemote){

EntityItem entity = new EntityItem(this.getWorldObj(), this.xCoord + rx, this.yCoord + ry,

    this.zCoord + rz, new ItemStack(contents.itemID, contents.stackSize, contents.getItemDamage()));

}

 

What he meant was

if (!world.isRemote){
EntityItem entity = new EntityItem(this.getWorldObj(), this.xCoord + rx, this.yCoord + ry,
    this.zCoord + rz, new ItemStack(contents.itemID, contents.stackSize, contents.getItemDamage()));
}

(you spawn server-side, not client-side)

Protip: try and find answers yourself before asking on the forum.

It's pretty likely that there is an answer.

 

Was I helpful? Give me a thank you!

 

 

width=635 height=903http://bit.ly/HZ03zy[/img]

 

 

Tired of waiting for mods to port to bukkit?

use BukkitForge! (now with a working version of WorldEdit!)

Link to comment
Share on other sites

*Facepalm* I completely forgot about the world.isRemote flag.

 

And that appears to have fixed my error, there are no longer any ghost ItemStacks appearing.

 

Thanks to everyone who helped.

Creator and co-author of the mod Essencraft: https://github.com/defiant810/Essencraft

 

Please, dear God, learn Java before trying to mod. It saves ALL of us time.

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.