Jump to content

[SOLVED] [1.12.2] Restrict item to certain slots


Daeruin

Recommended Posts

Is there any way to control which slots of the vanilla inventory my custom item can go into? Specifically, I would like my item to only be allowed in the hot bar, not in the main inventory. I can't think of a way to do this without making a custom player inventory, and I'm not sure I want to go that far.

 

Maybe a player tick event that searches the inventory for my item and moves it to the hot bar, or expels it otherwise? It seems like searching the entire inventory of every player every tick could lead to performance problems.

 

I really wish there were some events that dealt with inventory interactions.

Edited by Daeruin
solved
Link to comment
Share on other sites

7 minutes ago, Daeruin said:

Maybe a player tick event that searches the inventory for my item and moves it to the hot bar, or expels it otherwise?

This would be the preferred solution.

7 minutes ago, Daeruin said:

It seems like searching the entire inventory of every player every tick could lead to performance problems.

a) Don't search it every tick but instead say every 10 ticks.

b) Realise that the size of the vanilla player's inventory is only 44 slots and that will take virtually no time to iterate through and stop worrying.

 

That said you might try to do something interesting with the MouseEvent. I wonder if

  • Detecting the slot under the cursor
  • Checking whether that slot can accept your item with your custom checks
  • Cancelling the event if not

will work. I suspect it will but I can't test it right now.

  • Like 1
Link to comment
Share on other sites

1 hour ago, Daeruin said:

Specifically, I would like my item to only be allowed in the hot bar, not in the main inventory.

You could modify Container#inventorySlots to change the mainInventorySlots to your own slots. Do this in EntityJoinWorldEvent by using the EntityPlayer#inventoryContainer field.

  • Like 1

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

Interesting ideas!

 

I like the idea of trying the MouseEvent most. It would directly stop the player from putting the item in the hot bar while being not resource intensive and potentially more compatible with other mods. I might try that out tomorrow if I have time.

 

Any other ideas are still welcome.

Link to comment
Share on other sites

1 hour ago, Daeruin said:

and potentially more compatible with other mods.

Doing what I said if you do it correctly will not cause incompatibility with other mods.

 

Edit: Also. Either way you would have to determine if the container had the hotbar. In case of my way all you would have to do is subscribe to the ContainerEvent.Open (might have the name wrong) and apply the search and change the slots.

Edited by Animefan8888

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

2 hours ago, Animefan8888 said:

Doing what I said if you do it correctly will not cause incompatibility with other mods.

 

Edit: Also. Either way you would have to determine if the container had the hotbar. In case of my way all you would have to do is subscribe to the ContainerEvent.Open (might have the name wrong) and apply the search and change the slots.

I was thinking about other mods that might be doing their own crap to modify the slots.

 

Since I can't sleep I decided to give this a try. I have no idea how to detect which slots are in the hot bar. The indices of the hot bar slots change depending on whether you're looking at the standard inventory, crafting table, furnace, etc... because the order in which the slots are added is different in each case. WTF.

 

And InventoryPlayer seems to organize things completely different, with different lists of items for the main inventory, armor, etc., so the indices of the items in the inventory list don't match indices of the slots they belong in. At least, not as far as I can tell. WTF.

Link to comment
Share on other sites

I think I figured out how to identify the hot bar, but my custom Slot class isn't working. I think it's because PlayerContainerEvent only fires on the server. I'm swapping out the slots, but the client isn't being notified. So when putting stuff in my inventory, it looks like I can put the items in the slot, but they aren't actually there.

 

Also, when I do the exact same thing in the EntityJoinWorldEvent on the player's inventory, the inventory slots that are swapped out for my custom ones can't be interacted with at all.

 

EventHandler code

Link to comment
Share on other sites

3 hours ago, Daeruin said:

the inventory slots that are swapped out for my custom ones can't be interacted with at all.

Try removing the stack.isEmpty || part.

3 hours ago, Daeruin said:

because PlayerContainerEvent only fires on the server.

If this is the case also use GuiOpenEvent and interact with EntityPlayer#openContainer, but only if it is not inventory container.

  • Like 1

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

17 minutes ago, Animefan8888 said:

Try removing the stack.isEmpty || part.

Thank you for the reply! I originally didn't have that there. When things weren't working, I added it. Just throwing crap at the wall to see if it would help.

17 minutes ago, Animefan8888 said:

If this is the case also use GuiOpenEvent and interact with EntityPlayer#openContainer, but only if it is not inventory container.

I see what you are getting at, but GuiOpenEvent doesn't seem to have access to the EntityPlayer.

Link to comment
Share on other sites

21 hours ago, V0idWa1k3r said:

That said you might try to do something interesting with the MouseEvent. I wonder if

  • Detecting the slot under the cursor
  • Checking whether that slot can accept your item with your custom checks
  • Cancelling the event if not

will work. I suspect it will but I can't test it right now.

How would you detect the slot under the cursor? The event doesn't seem to have access to the slots. If it did, I could see comparing the mouse x and y to the slot's x and y coordinates.

Link to comment
Share on other sites

39 minutes ago, Daeruin said:

I see what you are getting at, but GuiOpenEvent doesn't seem to have access to the EntityPlayer.

Minecraft.getMinecraft().player

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

40 minutes ago, Daeruin said:

Thank you for the reply! I originally didn't have that there. When things weren't working, I added it. Just throwing crap at the wall to see if it would help.

Is it ever calling the super method, is that returning false?

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

2 hours ago, Animefan8888 said:

If this is the case also use GuiOpenEvent and interact with EntityPlayer#openContainer, but only if it is not inventory container.

What did you mean by this? EntityPlayer#inventoryContainer? Because openContainer and inventoryContainer always seem to be identical as far as I can see.

 

1 hour ago, Animefan8888 said:

Minecraft.getMinecraft().player

Silly me. It's been a while since I did anything client side. Haha.

 

1 hour ago, Animefan8888 said:

Is it ever calling the super method, is that returning false?

I checked, super method is not getting called unless the item is valid, in which case super is called and returns true. I haven't seen it return false. This is really strange because I have another Slot extension that has the exact same code, and it works just fine (in my custom inventory).

Link to comment
Share on other sites

1 hour ago, Daeruin said:

What did you mean by this? EntityPlayer#inventoryContainer? Because openContainer and inventoryContainer always seem to be identical as far as I can see.

This is not true, openContainer is always the container the player has open, it seems to default to inventoryContainer instead of null.

 

1 hour ago, Daeruin said:

I checked, super method is not getting called unless the item is valid, in which case super is called and returns true. I haven't seen it return false. This is really strange because I have another Slot extension that has the exact same code, and it works just fine (in my custom inventory).

Try stepping through your code in the debugging when you are replacing the slots and when you are trying to put the item in the slot.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

I couldn't figure out how to make the slot-swapping idea work.

 

I went back to the very first idea I had of using a PlayerTickEvent to search the player inventory. Based on a tip from an old Minecraftforum post, I found out that I can see what's loaded on the mouse cursor with InventoryPlayer#getItemStack. I just need to store that value, and anytime it changes, the player must have clicked on a slot. Only when it changes from my item to something else do I need to iterate over the inventory to check if my item has been put somewhere it shouldn't. I feel like it ended up being relatively elegant, and it works well, too.

 

For the record: Final code here

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.