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 checked through tileEntity and Iinventory and couldn't find anything useful.

 

What you could do is accept the item into the slot, then poit it out if it's incorrect. Sort of like when the crafting table is closed and everything gets dropped.

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

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • https://pastebin.com/FaQ43RnJ  Este es un error que me lanza al momento de querer iniciar forge Intente de todo pero no sirve nada. This is an error that I get when I want to start forge. I tried everything but nothing works.
    • It was a stupid Eclipse problem ,the debugger was set to a lower version of java.  In what world would i want my development version different from the debugger version.   ty for looking
    • Caused by: java.lang.NullPointerException: Cannot read field "level" because "this.minecraft" is null This is my first big error when coding. I looked it up, but there are a bunch of references to Dawncraft and not enough to figure out what was going wrong. I found this, but it involves a command and my GUI only opens when you shift + right-click while holding an item. They fixed it by not calling it with a command, but I am not using a command. Here's the render of my menu, which is the only part that changed between it working and not:   @Override public void render(@Nonnull PoseStack mstack, int mouseX, int mouseY, float partialTicks) { int midx = this.width / 2; int midy = this.height / 2; this.renderBackground(mstack); drawCenteredString(mstack, font, I18n.get("config.shape_tool"), midx, 4, 0xC3D1D8); Utils.renderImage(midx - 12, midy, 20, 20, "textures/gui/plus.png", mstack); addRenderableWidget(new Button(midx - 12, midy, 10, 10, Component.translatable(""), this::increaseax)); Utils.renderImage(midx + 12, midy, 20, 20, "textures/gui/minus.png", mstack); addRenderableWidget(new Button(midx + 12, midy, 10, 10, Component.translatable(""), this::decreaseax)); drawCenteredString(mstack, font, String.valueOf(shapetoolax), midx, midy + 10, 0xC3D1D8); super.render(mstack, mouseX, mouseY, partialTicks); } Utils.renderImage is this:   public static void renderImage(int x, int y, int width, int height, String img, PoseStack mstack) { RenderSystem.setShaderColor(1, 1, 1, 1); RenderSystem.enableBlend(); RenderSystem.defaultBlendFunc(); RenderSystem.setShaderTexture(0, new ResourceLocation(PNegative.MODID, img)); blit(mstack, x, y, 0, 0, width, height, width, height); RenderSystem.disableBlend(); } I have used it before and it has worked, so it can't be a problem. 
    • I found a topic  with the very simmilar problems. I run modpack Direwolf20 1.19.2 version from FTB with dedicated server with my friends and i am the only who have this type of crashes. It has been through login process and after 5-6 crashes i can connect. And randombly it could crash me in game but mostly when i am tp'ing using Nether portals etc. I already setted up all privileges for javaw in firewall, flushed dns, reset network settings and etc. Changed java version to from FAQ too. Here's some logs from client side https://gnomebot.dev/paste/1158502890168664194 https://gnomebot.dev/paste/1158187264657063946    
    • Don't know why game keeps crashing after a few seconds or walking towards something, tried removing larger mods and someaddon performance mods but it's not working. Minecraft launchers telling me "Exit Code 1"
  • Topics

×
×
  • Create New...

Important Information

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