Jump to content

[1.10.2] Add non-lapis item to compatible Enchantment Table slot?


IceMetalPunk

Recommended Posts

Is there any way to add an item--which is *not* ore dictionary'd to lapis--to be allowed in the lapis slot of the enchantment table's GUI? I thought I was clever in using reflection to access the slot's "ores" list in the PlayerContainerEvent.open event, but that's how I learned the list is unmodifiable.

 

What's the best way to allow my custom item to also be used in the enchantment table's lapis slot (without being used like lapis anywhere else)?

Whatever Minecraft needs, it is most likely not yet another tool tier.

Link to comment
Share on other sites

Is there any way to add an item--which is *not* ore dictionary'd to lapis--to be allowed in the lapis slot of the enchantment table's GUI? I thought I was clever in using reflection to access the slot's "ores" list in the PlayerContainerEvent.open event, but that's how I learned the list is unmodifiable.

 

What's the best way to allow my custom item to also be used in the enchantment table's lapis slot (without being used like lapis anywhere else)?

you would have to override the vanilla ContainerEnchantment with your own custom one.

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

You should be able to subscribe to

PlayerContainerEvent.Open

to detect when the player opens a

ContainerEnchantment

and replace the lapis

Slot

in

Container#inventorySlots

with your own

Slot

that allows other items to be placed in it.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

You should be able to subscribe to

PlayerContainerEvent.Open

to detect when the player opens a

ContainerEnchantment

and replace the lapis

Slot

in

Container#inventorySlots

with your own

Slot

that allows other items to be placed in it.

Ah! Sounds like the elegant way to do it, thanks!

 

Unfortunately, it's not quite working. It's behaving oddly: it will occasionally accept the stack of amethysts (the gem item I'm trying to make it accept), but it usually won't. When I try placing the amethysts in the slot and it doesn't accept it, my player's hand blinks in the background as if switching items, even though I'm not. And if I double-click in the lapis slot with amethysts, even when it doesn't accept them, it'll still pull a full stack from my inventory as if the gems were properly in the slot.

 

Here's my event handler code:

 

@SubscribeEvent
public void onOpenContainer(PlayerContainerEvent.Open ev) {
    Container cont = ev.getContainer();
    if (cont instanceof ContainerEnchantment) {
        ContainerEnchantment ench = (ContainerEnchantment) cont;
        Slot newSlot = new Slot(ench.tableInventory, 1, 35, 47) {
            List<ItemStack> ores = OreDictionary.getOres("gemLapis");

            public boolean isItemValid(@Nullable ItemStack stack) {
                if (stack.getItem() == Amethystic.items.AMETHYST) {
                    return true;
                }
                for (ItemStack ore : ores) {
                    if (OreDictionary.itemMatches(ore, stack, false)) {
                        return true;
                    }
                }
                return false;
            }
        };
        ench.inventorySlots.set(1, newSlot);
    }
}

 

Am I missing something here?

Whatever Minecraft needs, it is most likely not yet another tool tier.

Link to comment
Share on other sites

You should be able to subscribe to

PlayerContainerEvent.Open

to detect when the player opens a

ContainerEnchantment

and replace the lapis

Slot

in

Container#inventorySlots

with your own

Slot

that allows other items to be placed in it.

Ah! Sounds like the elegant way to do it, thanks!

 

Unfortunately, it's not quite working. It's behaving oddly: it will occasionally accept the stack of amethysts (the gem item I'm trying to make it accept), but it usually won't. When I try placing the amethysts in the slot and it doesn't accept it, my player's hand blinks in the background as if switching items, even though I'm not. And if I double-click in the lapis slot with amethysts, even when it doesn't accept them, it'll still pull a full stack from my inventory as if the gems were properly in the slot.

 

Here's my event handler code:

 

	@SubscribeEvent
public void onOpenContainer(PlayerContainerEvent.Open ev) {
	Container cont = ev.getContainer();
	if (cont instanceof ContainerEnchantment) {
		ContainerEnchantment ench = (ContainerEnchantment) cont;
		Slot newSlot = new Slot(ench.tableInventory, 1, 35, 47) {
			List<ItemStack> ores = OreDictionary.getOres("gemLapis");

			/**
			 * Check if the stack is a valid item for this slot. Always true
			 * beside for the armor slots.
			 */
			public boolean isItemValid(@Nullable ItemStack stack) {
				if (stack.getItem() == Amethystic.items.AMETHYST) {
					return true;
				}
				for (ItemStack ore : ores)
					if (OreDictionary.itemMatches(ore, stack, false))
						return true;
				return false;
			}
		};
		ench.inventorySlots.set(1, newSlot);
	}
}

 

Am I missing something here?

Are you talking about shift clicking or normally placing the item into the slot? Could you show some images?

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 meant normally placing the items into the lapis slot. If I shift-click, it puts them in the main item slot (i.e. the place where you put the item you're trying to enchant). But if I place them manually into the lapis slot, it occasionally accepts them, but more often rejects them with the player hand movement you get when switching items (or, for example, when your shield takes damage; that "hand bobbing" motion).

 

Screenshots won't show anything; visually, everything looks normal (except the hand bobbing which is too fast to catch in a screenshot). It's the behavior of accepting/rejecting the items in the lapis slot that's a problem.

 

Give me about 10 or 15 minutes and I'll try to capture a GIF of it for you; that would show the issue much better than a screenshot.

 

*EDIT* In recording the GIF, I discovered the glitch is very much a visual one: if I place the amethysts in the lapis slot, it seems not to accept them, but then if I put the rest of the stack in my inventory and click it again, the display updates and shows the correct number of items in the lapis slot.

 

Here's the GIF; note that I am not holding shift at any point here, just clicking normally with the left and right mouse button:

 

AmethystEnchantingGlitch.gif

Whatever Minecraft needs, it is most likely not yet another tool tier.

Link to comment
Share on other sites

I meant normally placing the items into the lapis slot. If I shift-click, it puts them in the main item slot (i.e. the place where you put the item you're trying to enchant). But if I place them manually into the lapis slot, it occasionally accepts them, but more often rejects them with the player hand movement you get when switching items (or, for example, when your shield takes damage; that "hand bobbing" motion).

 

Screenshots won't show anything; visually, everything looks normal (except the hand bobbing which is too fast to catch in a screenshot). It's the behavior of accepting/rejecting the items in the lapis slot that's a problem.

 

Give me about 10 or 15 minutes and I'll try to capture a GIF of it for you; that would show the issue much better than a screenshot.

 

*EDIT* In recording the GIF, I discovered the glitch is very much a visual one: if I place the amethysts in the lapis slot, it seems not to accept them, but then if I put the rest of the stack in my inventory and click it again, the display updates and shows the correct number of items in the lapis slot.

 

Here's the GIF; note that I am not holding shift at any point here, just clicking normally with the left and right mouse button:

 

AmethystEnchantingGlitch.gif

You will also have to subscribe to the GuiOpenEvent not sure if there is a player specific version, but you need to replace the whole gui displayed because the container slot there doesn't have you slot it has the original.

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

You'll need to subscribe to

GuiOpenEvent

to detect when the player opens a

GuiEnchantment

and perform the same

Slot

replacement on the client-side

Container

(

GuiContainer#inventorySlots

).

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

Okay...we're definitely getting closer, as now, it always accepts the amethyst item. The only problem is that even if I drop the amethyst in the lapis slot, it always moves to the first, enchanted item slot instead. I thought maybe the client-side container had the slots indexed differently, but it's just another instance of the same ContainerEnchantment class, so it should be the same index, right? So why would it move to the other slot instead of the one I drop it in?

 

I don't usually like to do this, but here's all the relevant code in my event handler:

 

    // Method to replace the lapis slot on any passed ContainerEnchantment, to
    // allow amethyst
    private void ReplaceLapisSlot(ContainerEnchantment ench) {
        Slot newSlot = new Slot(ench.tableInventory, 1, 35, 47) {
            List<ItemStack> ores = OreDictionary.getOres("gemLapis");

            public boolean isItemValid(@Nullable ItemStack stack) {
                if (stack.getItem() == Amethystic.items.AMETHYST) {
                    return true;
                }
                for (ItemStack ore : ores)
                    if (OreDictionary.itemMatches(ore, stack, false))
                        return true;
                return false;
            }
        };
        ench.inventorySlots.set(1, newSlot);
    }

    // Server-side replacement of lapis slot
    @SubscribeEvent
    public void onOpenContainer(PlayerContainerEvent.Open ev) {
        Container cont = ev.getContainer();
        if (cont instanceof ContainerEnchantment) {
            ContainerEnchantment ench = (ContainerEnchantment) cont;
            ReplaceLapisSlot(ench);
        }
    }

    // Client-side replacement of lapis slot
    @SubscribeEvent
    public void onOpenGui(GuiOpenEvent ev) {
        Gui gui = ev.getGui();
        if (gui instanceof GuiEnchantment) {
            ContainerEnchantment ench = (ContainerEnchantment) ((GuiEnchantment) gui).inventorySlots;
            ReplaceLapisSlot(ench);
        }
    }

Whatever Minecraft needs, it is most likely not yet another tool tier.

Link to comment
Share on other sites

That worked, thank you! It does leave me curious: what's are the functions of slotNumber vs. index? Clearly they're two different things, and one is set in the slot constructor while the other isn't; but their names are confusingly similar.

 

And another quality-of-life question that's not super-important: is there a way (without replacing the entire container with a custom one) to make shift-clicking of amethysts into the lapis/gem slot work? The transferStackInSlot() code seems pretty set in the ContainerEnchantment class, but perhaps there's an elegant way to "override" it without replacing the entire class?

Whatever Minecraft needs, it is most likely not yet another tool tier.

Link to comment
Share on other sites

That worked, thank you! It does leave me curious: what's are the functions of slotNumber vs. index? Clearly they're two different things, and one is set in the slot constructor while the other isn't; but their names are confusingly similar.

 

slotIndex

is the inventory slot that the

Slot

represents.

slotNumber

is the index of the

Slot

in the

Container

.

 

If a

Container

has slots from two inventories (e.g. a chest and a player),

slotIndex

will be 0 to X for the first inventory and 0 to Y for the second inventory, while

slotNumber

will be 0 to X+Y.

 

 

And another quality-of-life question that's not super-important: is there a way (without replacing the entire container with a custom one) to make shift-clicking of amethysts into the lapis/gem slot work? The transferStackInSlot() code seems pretty set in the ContainerEnchantment class, but perhaps there's an elegant way to "override" it without replacing the entire class?

 

I don't think there is.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

That worked, thank you! It does leave me curious: what's are the functions of slotNumber vs. index? Clearly they're two different things, and one is set in the slot constructor while the other isn't; but their names are confusingly similar.

 

slotIndex

is the inventory slot that the

Slot

represents.

slotNumber

is the index of the

Slot

in the

Container

.

 

If a

Container

has slots from two inventories (e.g. a chest and a player),

slotIndex

will be 0 to X for the first inventory and 0 to Y for the second inventory, while

slotNumber

will be 0 to X+Y.

 

 

And another quality-of-life question that's not super-important: is there a way (without replacing the entire container with a custom one) to make shift-clicking of amethysts into the lapis/gem slot work? The transferStackInSlot() code seems pretty set in the ContainerEnchantment class, but perhaps there's an elegant way to "override" it without replacing the entire class?

 

I don't think there is.

 

Ah, okay! That makes sense; thanks for the explanation. I wish I could make stack transfers work, but honestly, it's such a small detail that it's not worth remaking the enchantment container entirely just for it. Players will have to be content with click-and-drop xD

 

Thanks again!

Whatever Minecraft needs, it is most likely not yet another tool tier.

Link to comment
Share on other sites

That worked, thank you! It does leave me curious: what's are the functions of slotNumber vs. index? Clearly they're two different things, and one is set in the slot constructor while the other isn't; but their names are confusingly similar.

 

slotIndex

is the inventory slot that the

Slot

represents.

slotNumber

is the index of the

Slot

in the

Container

.

 

If a

Container

has slots from two inventories (e.g. a chest and a player),

slotIndex

will be 0 to X for the first inventory and 0 to Y for the second inventory, while

slotNumber

will be 0 to X+Y.

 

 

And another quality-of-life question that's not super-important: is there a way (without replacing the entire container with a custom one) to make shift-clicking of amethysts into the lapis/gem slot work? The transferStackInSlot() code seems pretty set in the ContainerEnchantment class, but perhaps there's an elegant way to "override" it without replacing the entire class?

 

I don't think there is.

 

Ah, okay! That makes sense; thanks for the explanation. I wish I could make stack transfers work, but honestly, it's such a small detail that it's not worth remaking the enchantment container entirely just for it. Players will have to be content with click-and-drop xD

 

Thanks again!

Just extend ContainerEnchantment and GuiEnchantment and override transferStackInSlot in the container. Ahh the wonders of OOP.

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

And how would I make that subclassed container/UI show when the player uses a normal enchantment table, though? Isn't the default UI hardcoded to be displayed for that?

In the events replace the gui or container, or in your GuiHandler.

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

And how would I make that subclassed container/UI show when the player uses a normal enchantment table, though? Isn't the default UI hardcoded to be displayed for that?

In the events replace the gui or container, or in your GuiHandler.

O_o I didn't realize those were replaceable via event hooks...shows how often I deal with GUIs in Minecraft, eh? xD Thank you!

Whatever Minecraft needs, it is most likely not yet another tool tier.

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.



×
×
  • Create New...

Important Information

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