Lately some IF users have been trying to do things that are impossible without using indeterministic magic codes when it comes to slot position, that is, the user tries to find an item in the inventory that he expects to be in a specific slot by looking in that slot, however, the IF has several features that allow a player to move the item within the inventory and the reference to that item remains intact, thus causing the user code to fail.
The idea here is to make an item reference system, this idea was taken from Vue Template Refs that ran into the same problem we have here.
The problem
As I said before, the user may want to make the player be able to move items within the inventory but keep track of these items regardless of where they are, this is already possible using handlers, however, this is internal to the item itself and only in its scope, so, for example, it's not possible to make an item that updates another specific item, like this:
boolean goldRush = true;
firstSlot().onRender(render -> new ItemStack(goldRush ? Material.GOLD_INGOT : Material.IRON_INGOT));
// we we want this item to upgrade gold bar to iron bar and vice versa
lastSlot(new ItemStack(Material.ARROW)).onClick(click -> { /* how??? */ });
A possible workaround for this is to update the entire inventory.
The problem is that we don't want to update the entire inventory, because we don't need to.
lastSlot(new ItemStack(Material.ARROW)).onClick(ViewContext::update);
Maybe we can take the item slot and update ourselves
But that doesn't work either, as we allow the player to move the item in the inventory, once they move, this code will no longer work.
lastSlot(new ItemStack(Material.ARROW)).onClick(click -> click.update(getFirstSlot()));
API Design
As inspired by Vue's template references, it will be possible to reference an item and take that item later and use it however we want.
-
We will add a reference to an item using a referencedBy or ref.
private static final String GOLD_REF_KEY = "gold";
firstSlot(new ItemStack(Material.GOLD_INGOT))
.referencedBy(GOLD_REF_KEY);
-
And take the reference and use it however you want later.
The method for getting the reference will return a ViewSlotContext that can be manipulated freely.
private static final String GOLD_REF_KEY = "gold";
private boolean goldRush = true;
firstSlot()
.referencedBy(GOLD_REF_KEY);
.onUpdate($ -> goldRush = !goldRush)
.onRender(render ->
render.setItem(new ItemStack(goldRush ? Material.GOLD_INGOT : Material.IRON_INGOT))
);
// ... and then ...
lastSlot(new ItemStack(Material.ARROW)).onClick(click -> {
ViewSlotContext gold = click.ref(GOLD_REF_KEY);
// update the gold item
gold.updateSlot();
});
You will even be able to know where the item is positioned through ViewSlotContext#getSlot.
Paginated contexts will also work, so you will be able to get the current paging index and value of that item even if it is in another slot.
Lately some IF users have been trying to do things that are impossible without using indeterministic magic codes when it comes to slot position, that is, the user tries to find an item in the inventory that he expects to be in a specific slot by looking in that slot, however, the IF has several features that allow a player to move the item within the inventory and the reference to that item remains intact, thus causing the user code to fail.
The idea here is to make an item reference system, this idea was taken from Vue Template Refs that ran into the same problem we have here.
The problem
As I said before, the user may want to make the player be able to move items within the inventory but keep track of these items regardless of where they are, this is already possible using handlers, however, this is internal to the item itself and only in its scope, so, for example, it's not possible to make an item that updates another specific item, like this:
A possible workaround for this is to update the entire inventory.
The problem is that we don't want to update the entire inventory, because we don't need to.
Maybe we can take the item slot and update ourselves
But that doesn't work either, as we allow the player to move the item in the inventory, once they move, this code will no longer work.
API Design
As inspired by Vue's template references, it will be possible to reference an item and take that item later and use it however we want.
We will add a reference to an item using a
referencedByorref.And take the reference and use it however you want later.
The method for getting the reference will return a
ViewSlotContextthat can be manipulated freely.You will even be able to know where the item is positioned through
ViewSlotContext#getSlot.Paginated contexts will also work, so you will be able to get the current paging index and value of that item even if it is in another slot.