Return Items When Moving Away from Crafting Table
hammy275 opened this issue ยท 6 comments
Crafting tables lend themselves a lot to leaving items in. To make crafting much quicker, we should return extra items placed in a crafting table to the player when they walk away.
Implementation-wise, this is actually pretty fun to do, since multiple players can put items into tables. Here's how I plan for it to work:
- Crafting tables keep track of how many items have been placed inside and by what players for each slot. This is done in a way hidden to the user.
- When crafting an output, the inputs are subtracted from the player who placed items in when possible, and taken from other players otherwise on a FIFO basis. For example, when crafting a chest, if player 1 places 64 planks in 4 slots, then player 2 places 64 planks in the other 4 slots, each chest craft will take one from each slot from each player. However, if player 1 places 8 planks in 8 slots then player 2 places 8 planks in 8 slots and player 1 does the craft, all planks from player 1 will be taken first before player 2's. Lastly, if player 3 also added 8 planks after player 2, player 2's would be taken first.
- When far enough away from the immersive, we return items to the player. To fit with the system currently in place, the client will ask the server for its items back, though this will change to be server-authoritative if/when I transition to a more server-driven model for immersives. This can easily be done when an immersive is removed, though we should up the maximum amount of crafting table immersives that can be tracked to prevent confusion from getting items back when we shouldn't.
- Grabbing items out of the table manually uses the same system as crafting, but only for the slot being grabbed from.
This will be a setting that's enabled by default*. All players who have this setting disabled will be lumped into a "generic" pool. We should use a hardcoded UUID that isn't v4 (likely v3 or v5, hashing a string such as "generic"). The generic pool bypasses the otherwise FIFO nature of things and is consumed immediately after the player doing the craft. For example, in the second players 1 and 2 example above, chest crafting would take from player 1 (since they're the one crafting the chests), then from the generic pool, then from player 2.
We can't use a HashMap to store all of this info, as there needs to be some priority. Instead, we'll use a Queue (probably a LinkedList). When a player goes to craft, we search through the list first to see if they're there. If they aren't found, use the queue data instead. Note that we actually need to store 9 queues, one for each slot.
*: This is a server-authoritative setting when disabled, in the same way the immersives are. If the server has this off, no player can use this feature.
That said, this is going to be moved to ImmersiveStorage
, since everything that uses that makes sense to have it for. People don't store stuff in crafting tables, anvils, smithing tables, or enchanting tables, so returning the item on leave makes sense here.
The changing queue is too complex for basically no reason. I think it should be a FIFO queue to make it easier to explain to people and for implementation
Issue on this branch: https://github.com/hammy275/immersive-mc/tree/1.18.x-itemreturn
Things left to do for this:
- Config support
- Return items when immersive is removed due to other removal means (such as reaching the client-enforced cap)
- Test that bag immersive crafting doesn't break
- Port to other versions
First two of the above covered in 34b1126