Jump to content

[1.10.2] Deleting an ItemStack from Item#onUpdate/tick counting


Roboguy99

Recommended Posts

I am trying to create an itemstack "half-life" system, in that every x number of ticks the itemstack halves in size. Then, when the stack is at a size of 1 and halves, I want the stack to be deleted.

 

I am sure this is really simple, but I have tried everything I can think of and the stack does not delete properly. Instead, it displays with a stack size of 0 in red, and then as soon as you right click/drop/attempt to move in inventory it is instantly deleted (making me think it's an odd sync issue).

 

This runs in the item's OnUpdate() method

 

                 Math.floor(stack.stackSize /= 2F); //Reduce stack size

				if (stack.stackSize <= 0)
				{
					Chemistry.INSTANCE.getNetworkWrapper().sendToServer(new ItemDelete(stack));

					EntityPlayer player = Minecraft.getMinecraft().thePlayer;
					player.inventory.markDirty();
					player.inventory.deleteStack(stack);

					stack.stackSize = 0;
					stack = null;
				}

 

 

As you can see, there is a lot of things there, and I'm fairly certain everything there results in the same odd 0-sized stack.

 

Here is the ItemDelete packet referenced in the above code (again, I've tried pretty much everything):

 

                        ItemStack stack = message.stack;
                	stack.useItemRightClick(ctx.getServerHandler().playerEntity.worldObj, ctx.getServerHandler().playerEntity, ctx.getServerHandler().playerEntity.getActiveHand());
                	stack.stackSize = 0;
                stack = null;
                ctx.getServerHandler().playerEntity.inventory.deleteStack(stack);

 

 

Sorry the indentation is a bit off...

I have no idea what I'm doing.

Link to comment
Share on other sites

What in the heck are you doing? You don't need packets or anything like that for this...

onUpdate

is called on both client and server. Check that you are on the server and then do the deletion directly.

 

I didn't actually think I needed a packet, I just quickly made one to be 100% sure...The reason I left such a mess of code in was mainly to give people an idea of what I had actually tried.

 

Anyway, to my understanding I was already doing that? I've tidied the code up:

 

if(!world.isRemote)
{
Math.floor(stack.stackSize /= 2F); //Reduce stack size
f(stack.stackSize == 0) stack = null;
}

 

But this doesn't run.

 

After some investigation, though, I have discovered that this is due to the half-life tick system and lag/desync. I'm afraid I'm about to hijack my own thread a little bit here.

 

Currently I am attempting to reduce

ticksUntilUpdate

every time the item updates, but the number does not decrease by 1 every time and the server and client threads are on different numbers (either that or IntelliJ has a problem keeping up with printing numbers so often?). As a result, the update code is never actually fired server-side.

 

Is there a "proper" way of counting ticks/firing code every second?

 

Code here

I have no idea what I'm doing.

Link to comment
Share on other sites

So, first of all, calling Math.floor like that does not actually do anything. Math.floor has a return value, which you completely ignore. You do half the stack size, but not because you call Math.floor.

stack

is a local variable. Assigning a value to it does not change anything about the players inventory. You have to actually set the slot to null in the inventory.

 

As for the ticksUntilUpdate: You cannot store data in the Item object like that. There is one instance of your Item class for everything, it is shared between client and server in singleplayer and shared across the whole server on a Dedicated Server. If you want a countdown, you need to store it in the ItemStack.

 

Everything you just said made total sense and seems so obvious I feel really stupid. I saw Math.Floor earlier and thought "Oh I put /=, it doesn't matter I'm ignoring the return".

 

One thing though: How would I store it on the ItemStack (principally as opposed to literally)? Is there an ItemStack tick method, or do I need a TickEvent or something else? At this point I've gone from stupid to blank.

 

This is why you don't leave unfinished code for months...I started this method like half a year ago...

 

Thanks for all the help so far.

I have no idea what I'm doing.

Link to comment
Share on other sites

You can store things in ItemStacks either using their NBT tag or using the metadata ("damage value").

 

Ok I thought of that and dismissed it for some reason. NBT would probably be better due the number of variables I need to store. Is it safe/efficient to update NBT every tick?

I have no idea what I'm doing.

Link to comment
Share on other sites

Rather than update the NBT every tick, you can save a "start" time and compare with the current time, waiting for the elapsed distance in time to be large enough.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Right - I've taken everything into account (and overall the code is a lot better), but I'm still getting the same issue (stack size 0). I think maybe this is because I'm using

Minecraft.getMinecraft().thePlayer

so the update is inevitably still client-side only, in which case how do I get the player from the server? Or is it something else (it normally is...)?

 

Code here.

I have no idea what I'm doing.

Link to comment
Share on other sites

Right - I've taken everything into account (and overall the code is a lot better), but I'm still getting the same issue (stack size 0). I think maybe this is because I'm using

Minecraft.getMinecraft().thePlayer

so the update is inevitably still client-side only, in which case how do I get the player from the server? Or is it something else (it normally is...)?

 

Code here.

Hmmm I wonder

public void onUpdate(ItemStack stack, World world, "Entity entity", int par4, boolean par5)

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

Right - I've taken everything into account (and overall the code is a lot better), but I'm still getting the same issue (stack size 0). I think maybe this is because I'm using

Minecraft.getMinecraft().thePlayer

so the update is inevitably still client-side only, in which case how do I get the player from the server? Or is it something else (it normally is...)?

 

Code here.

Hmmm I wonder

public void onUpdate(ItemStack stack, World world, "Entity entity", int par4, boolean par5)

 

Ah! I forgot casting existed. I assumed that was related to the actual item rather than the player. Thanks.

 

--

 

I know it may seem stupid to you, and I fully understand why you get annoyed, but perhaps a little less of the sarcasm please? People have to start somewhere...

I have no idea what I'm doing.

Link to comment
Share on other sites

Right - I've taken everything into account (and overall the code is a lot better), but I'm still getting the same issue (stack size 0). I think maybe this is because I'm using

Minecraft.getMinecraft().thePlayer

so the update is inevitably still client-side only, in which case how do I get the player from the server? Or is it something else (it normally is...)?

 

Code here.

Hmmm I wonder

public void onUpdate(ItemStack stack, World world, "Entity entity", int par4, boolean par5)

 

Ah! I forgot casting existed. I assumed that was related to the actual item rather than the player. Thanks.

 

--

 

I know it may seem stupid to you, and I fully understand why you get annoyed, but perhaps a little less of the sarcasm please? People have to start somewhere...

Ok I am sorry for the sarcasm, but just for future reference read the JavaDoc's above the method/field.

    /**
     * Called each tick as long the item is on a player inventory. Uses by maps to check if is on a player hand and
     * update it's contents.
     */

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

Got everything working now, thanks a lot everyone!

 

If Item#onUpdate only fires when the item is in a player's inventory, is there any advantage to keeping the parameter as an Entity as opposed to a PlayerEntity?

I have no Idea why they haven't changed it from Entity to at least EntityLivingBase...

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

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.