I have an item that is supposed to tick every second and add one to the damage every second. But it is not working, at least not how I want it to. It seems that if multiple of these items are in your hotbar, only some of them tick. I don't know what is causing this, so here is the class file:
public class ItemBlockTorchLit extends ItemBlock
{
public ItemBlockTorchLit(Block block) {
super(block);
setMaxDamage(BlockTorchLit.MAX_FUEL);
}
private int tickCounter = 0;
@Override
public void onUpdate(ItemStack itemstack, World world, Entity player, int p0, boolean p1) {
tickCounter ++;
if (tickCounter == 20) {
// Increment the damage
setDamage(itemstack, getDamage(itemstack) + 1);
// If the new damage is greater than the max damage, replace the item with a Burnt Torch
if (getDamage(itemstack) > getMaxDamage(itemstack)){
itemstack.func_150996_a(Item.getItemFromBlock(ModBlocks.torchBurnt));
}
tickCounter = 0;
}
}
}
If anybody knows what is causing this strange behavior, that would be great, because it makes no sense to me.
UPDATE: Here is a picture showing it. Each of these torches should have equal durability, as I got them at the same time and the durability decreases. But only some of them are actually affected.
* Every item in minecraft has only 1 object, this means that every potato uses the same object, every piece of coal uses the same object, and also every lit torch uses the same object. as a result of this fields within this object will be globally shared across all items. In your case this means that the value of tickCounter is the same for every lit torch.
You can fix this problem by using data which is different for every itemstack: damagevalue or nbt. Since you're already using the damagevalue you will have to write the ticktimer to the nbtdata of the itemstack.
*The onUpdate method runs twice per tick, once on the server and once on the client. Timers should only be run on the server. You are not checking wether it is a tick on the client or on the server, and so the value of the timer updates on the client and on the server independently, this can cause desync issues. You should only run the timer on the server and if needed update the client with the new information.
you can fix this problem by adding a if(!world.isRemote()){...} in your onUpdate method.
Ok, I'll look into that and post any problems I have here. I have never done packets or server-client sync or anything like that before...
First Problem:
public void onUpdate(ItemStack itemstack, World world, Entity player, int p0, boolean p1) {
if(!world.isRemote()) {
tickCounter ++;
if (tickCounter == 20) {
// Increment the damage
setDamage(itemstack, getDamage(itemstack) + 1);
// If the new damage is greater than the max damage, replace the item with a Burnt Torch
if (getDamage(itemstack) > getMaxDamage(itemstack)){
itemstack.func_150996_a(Item.getItemFromBlock(ModBlocks.torchBurnt));
}
tickCounter = 0;
}
}
}
Gives me and error on isRemote: The method isRemote() is undefined for the type World. But that doesn't make sense... isn't isRemote() a function specifically for World? Or am I completely misunderstanding this?
You're still using a tickCounter field, put the tick counter in the NBT.
Rollback Post to RevisionRollBack
Chisel Facades: For all your decorative pipe-hiding needs.
Please don't PM me to ask for help or to join your mod development team. Asking your question in a public thread preserves it for people who are having the same problem in the future. I'm not interested in developing mods with people.
So is a field like a variable? If it's not a method, do I not use the () at the end? I'm confused, mostly because I'm unfamiliar with this part of modding. I should probably read some tutorials...
As for the tick counter, can I do that later? I want to fix the server-client thing first. Or do I have to do both at once, because they are dependent on each other?
Gives me and error on isRemote: The method isRemote() is undefined for the type World. But that doesn't make sense... isn't isRemote() a function specifically for World? Or am I completely misunderstanding this?
Sorry, my bad, isRemote is indeed a field, i shouldn't have put the brackets in my example...
Ah ok the isRemote works fine now. But the first thing you were mentioning, could you explain a bit more? So do I just add NBT to an Item? because it would be ideal not to, for both lag reasons and the fact that they won't be able to stack. Could I set up a global counter and all torches are updated at once?
So is a field like a variable? If it's not a method, do I not use the () at the end? I'm confused, mostly because I'm unfamiliar with this part of modding. I should probably read some tutorials...
A field is a variable of an object, this is basic java, removing the brackets should fix the error.
As for the tick counter, can I do that later? I want to fix the server-client thing first. Or do I have to do both at once, because they are dependent on each other?
The 'server-client thing' you are fixing now is not directly causing your problems, but could cause problems in the future and is therefore a good thing to fix.
It is also a relatively easy fix.
The tickCounter as a field is what's causing your problem, if you write that to the nbt your problem should be fixed.
So is a field like a variable? If it's not a method, do I not use the () at the end? I'm confused, mostly because I'm unfamiliar with this part of modding. I should probably read some tutorials...
As for the tick counter, can I do that later? I want to fix the server-client thing first. Or do I have to do both at once, because they are dependent on each other?
Fields are essentially a type of variable, yes. This is an extremely basic Java concept.
Access it with world.isRemote instead of world.isRemote().
You can probably fix the server-client issue first, but it's a very simple fix.
Chisel Facades: For all your decorative pipe-hiding needs.
Please don't PM me to ask for help or to join your mod development team. Asking your question in a public thread preserves it for people who are having the same problem in the future. I'm not interested in developing mods with people.
Ok, so what exactly is the client-server thing? I don't know that much about client-server stuff, so what exactly is happening, and what do I need to do to fix it?
So do I just add NBT to an Item? because it would be ideal not to, for both lag reasons and the fact that they won't be able to stack. Could I set up a global counter and all torches are updated at once?
I think it's best to save the timer to the nbt. If i understand you correctly what you are trying to do is make a torch that burns out after some time. This would mean that every torch can burn for x amount of ticks. so every torch should track how long it has been burning and therefore have its own data.
if you were to make a global timer different torches would burn for different amounts of time depending on wether the timer has just ticked or is about to tick etc... This seems to me like odd behavior, but if that is what you want to achieve you could use a global timer i guess...
for the not stacking thing:
torches with different damagevalues would not be able to stack anyway.
nbt is stored per itemstack, and therefore items that normally stack will have the same nbt and will as a result still stack.
I don't know how big the impact is on performance when using nbt for your items, but i find it hard to believe that it will cause (bad) lag...
I think it's best to save the timer to the nbt. If i understand you correctly what you are trying to do is make a torch that burns out after some time. This would mean that every torch can burn for x amount of ticks. so every torch should track how long it has been burning and therefore have its own data.
if you were to make a global timer different torches would burn for different amounts of time depending on wether the timer has just ticked or is about to tick etc... This seems to me like odd behavior, but if that is what you want to achieve you could use a global timer i guess...
for the not stacking thing:
torches with different damagevalues would not be able to stack anyway.
nbt is stored per itemstack, and therefore items that normally stack will have the same nbt and will as a result still stack.
I don't know how big the impact is on performance when using nbt for your items, but i find it hard to believe that it will cause (bad) lag...
OK, I guess you will just stack unlit torches and light them as you need them, which is what I do right now anyways. Now that you explained it more, I think that NBT would probably be more stable, correct? But I still want the green bar, and the actual damage value, for a few reasons. Is that possible?
UPDATE: I've decided to just make lit torches one per stack.
OK, I guess you will just stack unlit torches and light them as you need them, which is what I do right now anyways. Now that you explained it more, I think that NBT would probably be more stable, correct? But I still want the green bar, and the actual damage value, for a few reasons. Is that possible?
NBT is indeed more reliable for what you are trying to achieve.
You can update the damagevalue on the server in your onUpdate() method. I think minecraft will automatically sync the client and the server when you change the damagevalue and therefor the damagebar should still update.
OK, thanks! So that is probably what's causing the problem? Because it's almost like it's combining the effect on some torches, and removing it on others. Some torches do not decrease, some increase at a very fast rate.
Either way I'll try and figure out how to do item NBT and stuff.
OK, I think set the NBT right, but I can't seem to get the value of the NBT in a different method. Here is my code:
public void onCreated(ItemStack itemstack, World world, EntityPlayer player) {
itemstack.stackTagCompound = new NBTTagCompound();
itemstack.stackTagCompound.setInteger("tickCounter", 0);
}
@Override
public void onUpdate(ItemStack itemstack, World world, Entity player, int p0, boolean p1) {
if (!world.isRemote) {
int tickCounter = itemstack.stackTagCompound.tickCounter;
}
}
Also, do I have to do all the "world saving" and "mark dirty" that you have to do with block NBT?
OK, I think set the NBT right, but I can't seem to get the value of the NBT in a different method. Here is my code:
You are indeed setting the data the right way, I usually use itemstack.setTagCompound(NBTTagCompound) instead of using the field of the itemstack directly, but i don't think that really matters.
However, the code you use to get the data isn't right.
I see you use itemstack.stackTagCompound to get the NBTTagCompound, i usually use itemstack.getTagCompound(), but again i don't think that matters.
then to get the tickCounter you use stackTagCompound.tickCounter, your IDE probably shows an error for this. You are currently trying to get the field tickCounter of the NBTTagCompound object, but it doesn't contain such a field and therefor it will tell you that you are trying to reference data that doesn't exist in that location. Instead of referencing it as a field you should use the stackTagCompound.getInteger() method. (The Integer part is because you are storing an integer, this is dependent of what kind of data you store). This method requires a String argument, and this String should match the string you use to set the data. (in your case "tickCounter")
So I think that using the set and get methods are a better way to do it, but this happens:
public void onCreated(ItemStack itemstack, World world, EntityPlayer player) {
itemstack.setTagCompound(NBTTagCompound);
itemstack.stackTagCompound.setInteger("tickCounter", 0);
}
Error on NBTTagCompound: NBTTagCompound cannot be resolved to a variable.
Then I did this:
@Override
public void onUpdate(ItemStack itemstack, World world, Entity player, int p0, boolean p1) {
NBTTagCompound compound = itemstack.getTagCompound();
tickCounter = compound.getInteger("tickCounter");
tickCounter ++;
if (tickCounter == 20) {
// Increment the damage
setDamage(itemstack, getDamage(itemstack) + 1);
// If the new damage is greater than the max damage, replace the item with a Burnt Torch
if (getDamage(itemstack) > getMaxDamage(itemstack)){
itemstack.func_150996_a(Item.getItemFromBlock(ModBlocks.torchBurntCoke));
}
tickCounter = 0;
}
}
Is that the correct way to do it? Just checking to make sure I didn't put methods in the wrong place or if there is a better way to code it or something.
So I think that using the set and get methods are a better way to do it, but this happens:
public void onCreated(ItemStack itemstack, World world, EntityPlayer player) {
itemstack.setTagCompound(NBTTagCompound);
itemstack.stackTagCompound.setInteger("tickCounter", 0);
}
Error on NBTTagCompound: NBTTagCompound cannot be resolved to a variable.
This error occurs because there is no variable called NBTTagCompound, just like you did before you should make a new one.
before you did: itemstack.stackTagCompound = new NBTTagCompound().
so you were creating a new NBTTagCompound, but now you just give it a NBTTagCompound without creating it. replacing 'NBTTagCompound' with 'new NBTTagCompound()' should fix it.
@Override
public void onUpdate(ItemStack itemstack, World world, Entity player, int p0, boolean p1) {
NBTTagCompound compound = itemstack.getTagCompound();
tickCounter = compound.getInteger("tickCounter");
tickCounter ++;
if (tickCounter == 20) {
// Increment the damage
setDamage(itemstack, getDamage(itemstack) + 1);
// If the new damage is greater than the max damage, replace the item with a Burnt Torch
if (getDamage(itemstack) > getMaxDamage(itemstack)){
itemstack.func_150996_a(Item.getItemFromBlock(ModBlocks.torchBurntCoke));
}
tickCounter = 0;
}
}
Is that the correct way to do it? Just checking to make sure I didn't put methods in the wrong place or if there is a better way to code it or something.
The code you have now will run, but it won't work, let's walk through what you are doing:
First you get the NBTTagCompound by using: NBTTagCompound compound = itemStack.getTagCompound();
then you create a local variable called tickCounter and assign it a value that you read from the NBTTagCompound.
Then you increase the value of your local variable by 1.
and if the local variable equals 20 you do your logic (which should work for the most part)
The problem is that the value inside the NBTTagCompound never changes, and therefor the value of tickCounter will be the same every time onUpdate() is run.
I'll let you think of a way to solve this problem, but be sure to ask questions if you get stuck
I have an item that is supposed to tick every second and add one to the damage every second. But it is not working, at least not how I want it to. It seems that if multiple of these items are in your hotbar, only some of them tick. I don't know what is causing this, so here is the class file:
If anybody knows what is causing this strange behavior, that would be great, because it makes no sense to me.
UPDATE: Here is a picture showing it. Each of these torches should have equal durability, as I got them at the same time and the durability decreases. But only some of them are actually affected.
There are a two errors in the code you have now:
* Every item in minecraft has only 1 object, this means that every potato uses the same object, every piece of coal uses the same object, and also every lit torch uses the same object. as a result of this fields within this object will be globally shared across all items. In your case this means that the value of tickCounter is the same for every lit torch.
You can fix this problem by using data which is different for every itemstack: damagevalue or nbt. Since you're already using the damagevalue you will have to write the ticktimer to the nbtdata of the itemstack.
*The onUpdate method runs twice per tick, once on the server and once on the client. Timers should only be run on the server. You are not checking wether it is a tick on the client or on the server, and so the value of the timer updates on the client and on the server independently, this can cause desync issues. You should only run the timer on the server and if needed update the client with the new information.
you can fix this problem by adding a if(!world.isRemote()){...} in your onUpdate method.
and the Chunked pvp mod: http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/2128311-chunked-pvp#c2
Ok, I'll look into that and post any problems I have here. I have never done packets or server-client sync or anything like that before...
First Problem:
Gives me and error on isRemote: The method isRemote() is undefined for the type World. But that doesn't make sense... isn't isRemote() a function specifically for World? Or am I completely misunderstanding this?
World#isRemote is a field, not a method.
You're still using a tickCounter field, put the tick counter in the NBT.
Chisel Facades: For all your decorative pipe-hiding needs.
Please don't PM me to ask for help or to join your mod development team. Asking your question in a public thread preserves it for people who are having the same problem in the future. I'm not interested in developing mods with people.
So is a field like a variable? If it's not a method, do I not use the () at the end? I'm confused, mostly because I'm unfamiliar with this part of modding. I should probably read some tutorials...
As for the tick counter, can I do that later? I want to fix the server-client thing first. Or do I have to do both at once, because they are dependent on each other?
I don't think you have to worry about syncing the client and the server in your case, unless you want to render something based on the tickCounter.
Sorry, my bad, isRemote is indeed a field, i shouldn't have put the brackets in my example...
and the Chunked pvp mod: http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/2128311-chunked-pvp#c2
Ah ok the isRemote works fine now. But the first thing you were mentioning, could you explain a bit more? So do I just add NBT to an Item? because it would be ideal not to, for both lag reasons and the fact that they won't be able to stack. Could I set up a global counter and all torches are updated at once?
A field is a variable of an object, this is basic java, removing the brackets should fix the error.
The 'server-client thing' you are fixing now is not directly causing your problems, but could cause problems in the future and is therefore a good thing to fix.
It is also a relatively easy fix.
The tickCounter as a field is what's causing your problem, if you write that to the nbt your problem should be fixed.
and the Chunked pvp mod: http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/2128311-chunked-pvp#c2
Fields are essentially a type of variable, yes. This is an extremely basic Java concept.
Access it with world.isRemote instead of world.isRemote().
You can probably fix the server-client issue first, but it's a very simple fix.
Chisel Facades: For all your decorative pipe-hiding needs.
Please don't PM me to ask for help or to join your mod development team. Asking your question in a public thread preserves it for people who are having the same problem in the future. I'm not interested in developing mods with people.
Ok, so what exactly is the client-server thing? I don't know that much about client-server stuff, so what exactly is happening, and what do I need to do to fix it?
I think it's best to save the timer to the nbt. If i understand you correctly what you are trying to do is make a torch that burns out after some time. This would mean that every torch can burn for x amount of ticks. so every torch should track how long it has been burning and therefore have its own data.
if you were to make a global timer different torches would burn for different amounts of time depending on wether the timer has just ticked or is about to tick etc... This seems to me like odd behavior, but if that is what you want to achieve you could use a global timer i guess...
for the not stacking thing:
torches with different damagevalues would not be able to stack anyway.
nbt is stored per itemstack, and therefore items that normally stack will have the same nbt and will as a result still stack.
I don't know how big the impact is on performance when using nbt for your items, but i find it hard to believe that it will cause (bad) lag...
and the Chunked pvp mod: http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/2128311-chunked-pvp#c2
OK, I guess you will just stack unlit torches and light them as you need them, which is what I do right now anyways. Now that you explained it more, I think that NBT would probably be more stable, correct? But I still want the green bar, and the actual damage value, for a few reasons. Is that possible?
UPDATE: I've decided to just make lit torches one per stack.
NBT is indeed more reliable for what you are trying to achieve.
You can update the damagevalue on the server in your onUpdate() method. I think minecraft will automatically sync the client and the server when you change the damagevalue and therefor the damagebar should still update.
and the Chunked pvp mod: http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/2128311-chunked-pvp#c2
OK, thanks! So that is probably what's causing the problem? Because it's almost like it's combining the effect on some torches, and removing it on others. Some torches do not decrease, some increase at a very fast rate.
Either way I'll try and figure out how to do item NBT and stuff.
You should be able to figure it out, nbt data is pretty straight forward.
You could use this tutorial if you need more explanation on how to use itemStacks nbt data.
If you run into any problems be sure to ask for help
and the Chunked pvp mod: http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/2128311-chunked-pvp#c2
OK, I think set the NBT right, but I can't seem to get the value of the NBT in a different method. Here is my code:
Also, do I have to do all the "world saving" and "mark dirty" that you have to do with block NBT?
You are indeed setting the data the right way, I usually use itemstack.setTagCompound(NBTTagCompound) instead of using the field of the itemstack directly, but i don't think that really matters.
However, the code you use to get the data isn't right.
I see you use itemstack.stackTagCompound to get the NBTTagCompound, i usually use itemstack.getTagCompound(), but again i don't think that matters.
then to get the tickCounter you use stackTagCompound.tickCounter, your IDE probably shows an error for this. You are currently trying to get the field tickCounter of the NBTTagCompound object, but it doesn't contain such a field and therefor it will tell you that you are trying to reference data that doesn't exist in that location. Instead of referencing it as a field you should use the stackTagCompound.getInteger() method. (The Integer part is because you are storing an integer, this is dependent of what kind of data you store). This method requires a String argument, and this String should match the string you use to set the data. (in your case "tickCounter")
I don't think you will have to do that in this case, since you are not rendering the tickCounter directly.
and the Chunked pvp mod: http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/2128311-chunked-pvp#c2
So I think that using the set and get methods are a better way to do it, but this happens:
Error on NBTTagCompound: NBTTagCompound cannot be resolved to a variable.
Then I did this:
Is that the correct way to do it? Just checking to make sure I didn't put methods in the wrong place or if there is a better way to code it or something.
This error occurs because there is no variable called NBTTagCompound, just like you did before you should make a new one.
before you did: itemstack.stackTagCompound = new NBTTagCompound().
so you were creating a new NBTTagCompound, but now you just give it a NBTTagCompound without creating it. replacing 'NBTTagCompound' with 'new NBTTagCompound()' should fix it.
The code you have now will run, but it won't work, let's walk through what you are doing:
First you get the NBTTagCompound by using: NBTTagCompound compound = itemStack.getTagCompound();
then you create a local variable called tickCounter and assign it a value that you read from the NBTTagCompound.
Then you increase the value of your local variable by 1.
and if the local variable equals 20 you do your logic (which should work for the most part)
The problem is that the value inside the NBTTagCompound never changes, and therefor the value of tickCounter will be the same every time onUpdate() is run.
I'll let you think of a way to solve this problem, but be sure to ask questions if you get stuck
and the Chunked pvp mod: http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/2128311-chunked-pvp#c2