Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

[1.16.5] Help with custom Backpack (slot background and mouse wheel move)


Recommended Posts

I created a custom backpack.

which should get a few additional features (adding the armor slots, offhand slot, tool swicht slot).

the armor slots and the offhand slot of the player work.

i need some help for the siwtch slot tool:

1. the slot should have a custom background (like the player armor slots).

I've already tried this on the way as vanilla does it (it doesn't work).

this is the slot code:

 

	public static class ToolSlot extends SlotItemHandler {
		
		public static final ResourceLocation LOCATION_BLOCKS_TEXTURE = new ResourceLocation("textures/atlas/blocks.png");
		public static final ResourceLocation EMPTY_TOOL_SLOT = new ResourceLocation("cave:textures/items/empty_tool_slot.png");

		public ToolSlot(IItemHandler itemHandler, int index, int xPosition, int yPosition) {
			
			super(itemHandler, index, xPosition, yPosition);
			
		}
		
		@Override
		public int getSlotStackLimit() {
			
			return 1;
			
		}
		
		@Override
		public boolean isItemValid(ItemStack stack) {
			
			return stack.getItem() instanceof TieredItem;
			
		}
		
		@Override
		public Pair<ResourceLocation, ResourceLocation> getBackground() {
			
			return Pair.of(LOCATION_BLOCKS_TEXTURE, EMPTY_TOOL_SLOT);
			
		}
		
	}

 

2. I want that when the player sneaks and moves the mouse wheel,

the item in the hand is swapped with the item in the backpack slot.

Now how do I check whether the mouse wheel is moving (even if the gui is not open),

and how do I prevent the scrolling in the hotbar?

 

Link to post
Share on other sites
On 3/3/2021 at 8:47 AM, Luis_ST said:

he slot should have a custom background (like the player armor slots).

I've already tried this on the way as vanilla does it (it doesn't work).

Just add the background to your GUI texture...? Slot#getBackground does not seem to be used at all in rendering the slot, it only seems to be relevant during dragging, and nothing ever sets the background as far as I can tell.

 

On 3/3/2021 at 8:47 AM, Luis_ST said:

Now how do I check whether the mouse wheel is moving (even if the gui is not open),

and how do I prevent the scrolling in the hotbar?

InputEvent.MouseScrollEvent is fired outside of GUIs and can be cancelled.

While the GUI is open, you can override mouseScrolled in your screen.

Link to post
Share on other sites
1 hour ago, diesieben07 said:

Just add the background to your GUI texture...? Slot#getBackground does not seem to be used at all in rendering the slot, it only seems to be relevant during dragging, and nothing ever sets the background as far as I can tell.

I've already tried that and it's not how it's supposed to work.

For example, if I put an item in the offand slot, the background texture is set to default.

that's how it should work

 

1 hour ago, diesieben07 said:

InputEvent.MouseScrollEvent is fired outside of GUIs and can be cancelled.

While the GUI is open, you can override mouseScrolled in your screen

I'll try the event

 

Another question which event should I use to open my BackpackContainer.

I know that there is the KeyInputEvent when I use this I don't get a ServerPlayerEntity which I need to open the GUI with NetworkHooks#openGui.

I currently use TickEvent#PlayerTickEvent which is not the best solution.

Is there another / better way to do this?

Link to post
Share on other sites
3 minutes ago, Luis_ST said:

I've already tried that and it's not how it's supposed to work.

For example, if I put an item in the offand slot, the background texture is set to default.

that's how it should work

I do not understand. How is the offhand slot relevant regarding the background color of your slot?

 

4 minutes ago, Luis_ST said:

Another question which event should I use to open my BackpackContainer.

I know that there is the KeyInputEvent when I use this I don't get a ServerPlayerEntity which I need to open the GUI with NetworkHooks#openGui.

I currently use TickEvent#PlayerTickEvent which is not the best solution.

Is there another / better way to do this?

Assuming you want a keyboard key to open the GUI:

  • Make a KeyBinding.
  • Use ClientTickEvent to check if its pressed.
  • If it is, send a packet to the server, which then calls NetworkHooks#openGui. You can preemptively also open it on the client to hide the latency of the two network roundtrips.
Link to post
Share on other sites
31 minutes ago, diesieben07 said:

I do not understand. How is the offhand slot relevant regarding the background color of your slot?

it is an example of how the slot background should work

 

33 minutes ago, diesieben07 said:

If it is, send a packet to the server, which then calls NetworkHooks#openGui

using a SimpleChannel?

 

34 minutes ago, diesieben07 said:

You can preemptively also open it on the client to hide the latency of the two network roundtrips.

and then send the change in the container to the server?

Link to post
Share on other sites
1 minute ago, Luis_ST said:

it is an example of how the slot background should work

Apparently I was too stupid to operate my IDE. getBackground should work fine. You just need to ensure that that textures are actually stitched onto the texture sheet, using TextureStitchEvent.Pre.

 

4 minutes ago, Luis_ST said:

using a SimpleChannel?

Yes, that is how you make custom packets.

 

4 minutes ago, Luis_ST said:

and then send the change in the container to the server?

What?

Link to post
Share on other sites
17 minutes ago, diesieben07 said:

Apparently I was too stupid to operate my IDE. getBackground should work fine. You just need to ensure that that textures are actually stitched onto the texture sheet, using TextureStitchEvent.Pre

like this (dosent work):

	@SubscribeEvent
	public static void TextureStitch(TextureStitchEvent.Pre event) {
		
		event.addSprite(new ResourceLocation("cave:items/empty_tool_slot.png"));
		
	}

 

25 minutes ago, diesieben07 said:

Yes, that is how you make custom packets.

Because of the Simple Channel,

I've read the associated Forge doc several times and just didn't understand it.

I understand how I have to create the simple channel, but how do I create the required packet / message.

Can I do this like minecraft (creat class which implements IPackackt)?

 

31 minutes ago, diesieben07 said:

What?

was a question about the other possibility (only open on the client).

but I try that with the NetworkHooks#openGui

Link to post
Share on other sites
1 hour ago, Luis_ST said:

ke this (dosent work):

More context is needed.

 

1 hour ago, Luis_ST said:

I understand how I have to create the simple channel, but how do I create the required packet / message.

The docs explain this. Have you tried anything?

 

1 hour ago, Luis_ST said:

Can I do this like minecraft (creat class which implements IPackackt)?

No.

Link to post
Share on other sites
1 hour ago, Luis_ST said:

was a question about the other possibility (only open on the client).

but I try that with the NetworkHooks#openGu

No! You cannot open it only on the client. I said you can open it on the client, too, to hide the network latency.

Link to post
Share on other sites
13 hours ago, diesieben07 said:

More context is needed.

I don't know what code I would still be helpful, so here are the relevant classes in my git repo:

TextureStitchEvent:

https://github.com/Luis-st/Forge-1.16.5-36.0.1-mdk/blob/main/forge-1.16.5-36.0.1-mdk/src/main/java/net/luis/cave/events/other/OnTextureStitchEvent.java

BackpackContainer (with custom slot subclass):

https://github.com/Luis-st/Forge-1.16.5-36.0.1-mdk/blob/main/forge-1.16.5-36.0.1-mdk/src/main/java/net/luis/cave/common/inventory/container/BackpackContainer.java

 

13 hours ago, diesieben07 said:

The docs explain this. Have you tried anything?

I think I understood after trying something:

my message class requires 3 methods (encode, decode, handle)

which I then have to specify when registering the message (parameter 3 - 6).

Am I right?

Link to post
Share on other sites
  • First of all, this is completely broken. Key bindings are client side. You are reaching across logical sides here. You must send a packet.
  • Please start with basic troubleshooting. Your textures that you tried to stitch don't work. So what is the first step? Put a breakpoint in the stitch event handler. Oh, it's not called at all. Why would that be? Let's look at where TextureStitchEvent.Pre is fired: here. Oh look, its fired on the mod event bus. I wonder why your event handler does not work. This is absolute basic debugging. Please try to do it yourself before simply always screaming "it doesn't work". This stuff is not hard.
Link to post
Share on other sites
50 minutes ago, diesieben07 said:

First of all, this is completely broken.

21 hours ago, Luis_ST said:

I currently use TickEvent#PlayerTickEvent which is not the best solution.

Is there another / better way to do this?

I know this is not the best solution and I have already pointed out that I am currently using the TickEvent#PlayerTickEvent to open the container.

 

5 hours ago, Luis_ST said:

I think I understood after trying something:

my message class requires 3 methods (encode, decode, handle)

which I then have to specify when registering the message (parameter 3 - 6).

so i tried something with the simple channel and i think i understood how it works.

that's why I asked if I was right there so i am right?

 

59 minutes ago, diesieben07 said:

Please start with basic troubleshooting. Your textures that you tried to stitch don't work. So what is the first step? Put a breakpoint in the stitch event handler. Oh, it's not called at all. Why would that be? Let's look at where TextureStitchEvent.Pre is fired: here. Oh look, its fired on the mod event bus. I wonder why your event handler does not work. This is absolute basic debugging. Please try to do it yourself before simply always screaming "it doesn't work". This stuff is not hard.

that is a point that i can understand from you,

i did not test it for long time (use debugger etc.) and then immediately asked for help

 

But now I have tested something and I know (now) that I have to change the EventBus

and that I have to remove the .png from the texture because minecaft adds this automatically.

it still doesn't work, but it's not the TextureStitchEvent because it is running.

so I think it's because of how I use the texture in the slot:

 

	public static class ToolSlot extends SlotItemHandler {
		
		public static final ResourceLocation EMPTY_TOOL_SLOT = new ResourceLocation("cave:items/empty_tool_slot.png");

		// remove two needless methods and the constructor
		
		@Override
		public Pair<ResourceLocation, ResourceLocation> getBackground() {
			
			return Pair.of(PlayerContainer.LOCATION_BLOCKS_TEXTURE, EMPTY_TOOL_SLOT);
			
		}
		
	}

 

Link to post
Share on other sites
36 minutes ago, Luis_ST said:

I know this is not the best solution and I have already pointed out that I am currently using the TickEvent#PlayerTickEvent to open the container.

It is not a solution at all. It is broken.

 

Update your Git repo please.

Link to post
Share on other sites
54 minutes ago, diesieben07 said:

Update your Git repo please.

updated

 

54 minutes ago, diesieben07 said:

It is not a solution at all. It is broken.

I give up...

 

8 hours ago, Luis_ST said:

I think I understood after trying something:

my message class requires 3 methods (encode, decode, handle)

which I then have to specify when registering the message (parameter 3 - 6).

Am I right?

can you please just give me an answer to this question that would really helpful

Link to post
Share on other sites
20 minutes ago, Luis_ST said:

updated

The ResourceLocation returned from getBackground should not have the .png extension.

 

21 minutes ago, Luis_ST said:

I give up...

Why?

 

21 minutes ago, Luis_ST said:

can you please just give me an answer to this question that would really helpful

You do not need to use methods here. You just need to give an encoder, decoder and handler when registering your message. You could even implement them as standalone classes, if you wanted to. You could use lambdas. Or anonymous inner classes. Or method references. It doesn't matter. All that matters is that you conform to the required interface.

Link to post
Share on other sites
9 minutes ago, diesieben07 said:

The ResourceLocation returned from getBackground should not have the .png extension.

that's working

 

11 minutes ago, diesieben07 said:

You do not need to use methods here. You just need to give an encoder, decoder and handler when registering your message. You could even implement them as standalone classes, if you wanted to. You could use lambdas. Or anonymous inner classes. Or method references. It doesn't matter. All that matters is that you conform to the required interface.

Okay, I'll try, but in which method I have to call NetworkHooks#openGui

Link to post
Share on other sites
17 minutes ago, diesieben07 said:

What do you mean?

the message I send has to call NetworkHooks # openGui in which of the methods of the message class I have to call this (encode, decode, handle).

i'm not sure but i think handle because i can't get a player from the other methods

and do I need the remaining methods for something?

Link to post
Share on other sites

Your question shows that you have not understood the concept of packets.

Server and client can only communicate via the network, which means they can only exchange bytes. Packets are an abstraction of this. Encode tells the game how to turn your packet into bytes, decode tells the game how to turn those bytes back into the packet. Handle is then called (on the receiving side) to perform whatever action you need to perform when the packet is received.

Link to post
Share on other sites
14 minutes ago, diesieben07 said:

Server and client can only communicate via the network, which means they can only exchange bytes. Packets are an abstraction of this. Encode tells the game how to turn your packet into bytes, decode tells the game how to turn those bytes back into the packet. Handle is then called (on the receiving side) to perform whatever action you need to perform when the packet is received.

that makes the whole thing not clearer.

 

okay soI should send a message/packet in the ClientTickEvent with the help of the SimpleChannel.

should i add a player to the constructor of the message,

convert it into bytes using the encode method and then back into a player using the decode method

 

Or do I just think too much about the whole thing and I am right to use the handle method because it is carried out on the receiving side.

So I can just check whether the receiving side is server and then open the container?

 

Link to post
Share on other sites
3 minutes ago, Luis_ST said:

that makes the whole thing not clearer.

What are your questions?

 

2 minutes ago, Luis_ST said:

okay soI should send a message/packet in the ClientTickEvent with the help of the SimpleChannel.

should i add a player to the constructor of the message,

convert it into bytes using the encode method and then back into a player using the decode method

No, you don't need to send the player, because this is a client-to-server packet, and the server can just look at which player sent the packet.

 

3 minutes ago, Luis_ST said:

So I can just check whether the receiving side is server and then open the container?

When registering your messages to the SimpleChannel you can specify a NetworkDirection. You should do this, as this message makes no sense being sent from server to client. In that case you do not need to check the receiving side, because it will always be server.

Link to post
Share on other sites
56 minutes ago, diesieben07 said:

When registering your messages to the SimpleChannel you can specify a NetworkDirection. You should do this, as this message makes no sense being sent from server to client. In that case you do not need to check the receiving side, because it will always be server

I tried to create a massage and ClientTickEvent from your explanation:

My message:

https://github.com/Luis-st/Forge-1.16.5-36.0.1-mdk/blob/main/forge-1.16.5-36.0.1-mdk/src/main/java/net/luis/cave/core/BackpackMessage.java

my PacketHandler:

https://github.com/Luis-st/Forge-1.16.5-36.0.1-mdk/blob/main/forge-1.16.5-36.0.1-mdk/src/main/java/net/luis/cave/core/ModPacketHandler.java

and the ClientTickEvent :

https://github.com/Luis-st/Forge-1.16.5-36.0.1-mdk/blob/main/forge-1.16.5-36.0.1-mdk/src/main/java/net/luis/cave/events/other/OnClientTickEvent.java

 

is that correct or do I have to change something?

Link to post
Share on other sites
15 minutes ago, diesieben07 said:

The IMessage interface is not needed. But yes, that works.

okay i already thought so, but why is the interface unnecessary?

 

to the tools switch slots. I probably also need a message for this, right?

 

 

Link to post
Share on other sites
Just now, Luis_ST said:

okay i already thought so, but why is the interface unnecessary?

Because you're just using method references anyways, so you don't need the interface.

 

1 minute ago, Luis_ST said:

to the tools switch slots. I probably also need a message for this, right?

What?

Link to post
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.

Guest
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.



  • Recently Browsing

    No registered users viewing this page.

  • Posts

    • So I had no clue what topic to put this under because its not really modding with forge but modding forge itself. So I have terrain generation mods that are only server side and Bungeecord that has Geyser packet translator so people on bedrock edition can play as well, but when a bedrock player connects it gets a unknown packet error. I tested the proxy on a Spigot server verifying it was forge. With no mods installed I still get the error. I got a wireshark log of it all and I found the packet where it aborts the connection due to the invalid packet but I have no clue how to stop it. When I still had the mods installed I disabled the forge handshake protocol but it did not fix the issue. If you know what part of forge is doing this or a way to fix it all together that would be awesome. I know modifying forge can end really baddy (definitely the handshake protocol) but I think that is my only fix here. Im open to any suggestions tho. I have run out of ideas to fix it so any help would be nice. Also it seems the packet id causing the connection error is 0xFE but im not sure cause the client also sends back a packet with that ID. I have a whole bunch of info collected so if you need any more information on the issue, I willing to give it, just not the ips on the wireshark log.
    • Okay, I got it working correctly now, but I'm not sure how to make it work with multiple blocks.   My Block Code:   package expanded.blocks; import javax.annotation.Nullable; import expanded.VanillaBuildingBlocks; import net.minecraft.block.BlockState; import net.minecraft.block.RotatedPillarBlock; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.common.ToolType; public class CustomLog extends RotatedPillarBlock {            public CustomLog(Properties properties) {         super(properties);     }      @Override     @Nullable     public BlockState getToolModifiedState(BlockState state, World world, BlockPos pos, PlayerEntity player, ItemStack stack, ToolType toolType) {         return toolType == ToolType.AXE ? VanillaBuildingBlocks.acacia_log.defaultBlockState() : null;     } }
    • ? Registering the block and overriding a function inside the class are two completely different things
    • Ya but I'm not sure how I would actually add/implement it into the class correctly, and then registering the block correctly in my register class.
    • This tutorial from 1.12.2 is as easy as anyone could possibly explain it, it hasn't changed much til now except some slight changes here and there for you to figure out, it's pretty straightforward (https://www.planetminecraft.com/blog/forge-tutorial-capability-system/). Obviously instead of mana you'd just replace it with whatever else you're doing. All a capability is in essence is the ability to serialize/deserialize standard data types to an entity. When the player dies the game creates a new instance of a PlayerEntity object so your data won't automatically "transfer" over to that new object unless as you say, you copy the data over in an event hook. After you have this set up, if you want to access the data you store in player capabilities you create a class with a static get function that retrieves it.
  • Topics

  • Who's Online (See full list)

×
×
  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.