0

I am trying to update some variables in my class, in a Minecraft forge environment. First of all, I would like to say that the length of the class exceeds 600 lines so I have taken snippets of the code (this will be why certain variables don't get initialised in the following code snippets as they are initialised elsewhere in the class.) I have tried different methods trying to call and changed the variable but none have successfully worked.

Edit: (isAccelerating being set to 2):

if(slot.isItemEqual(new ItemStack(ModItems.Particles, 1, 19))){
            if(this.isAccelerating == 0){
                if(this.module == 1){
                    if(this.energyStored >= 600000){
                        this.j = 1200;
                        this.stoneBuffer = 8;
                        this.isAccelerating = 2;
                        return true;
                    }
                }
                else{
                    this.j = 1200;
                    this.stoneBuffer = 8;

Edit:

It seems that the isAccelerating variable is being set to 2 and is running, however, the energy is not being reduced. Here is where the energy is consumed:

if(i<1200){
            System.out.println("1");
            i++;
            if(i%20 == 0){
                worldObj.playSound(xCoord+5, yCoord, zCoord, "random.explode", 1F, 1F, true);
                worldObj.playSound(xCoord-5, yCoord, zCoord, "random.explode", 1F, 1F, true);
                worldObj.playSound(xCoord, yCoord, zCoord+5, "random.explode", 1F, 1F, true);
                worldObj.playSound(xCoord, yCoord, zCoord-5, "random.explode", 1F, 1F, true);
                worldObj.playSound(xCoord-5, yCoord, zCoord-5, "random.explode", 1F, 1F, true);
                worldObj.playSound(xCoord+5, yCoord, zCoord-5, "random.explode", 1F, 1F, true);
                worldObj.playSound(xCoord-5, yCoord, zCoord+5, "random.explode", 1F, 1F, true);
                worldObj.playSound(xCoord+5, yCoord, zCoord+5, "random.explode", 1F, 1F, true);
            }
            if(this.energyStored < 500){
                System.out.println("2");
                this.energyStored = 0;
                this.isAccelerating = 0;
            }
            else{
                System.out.println("3");
                this.energyStored -= 500;
            }
        }
        else{
            j = 0;
            i = 0;
            this.isAccelerating = 0;
            this.stoneBuffer = 0;
            Entity entity = new EntityItem(worldObj);
            ItemStack itemstack = new ItemStack(ModItems.Particles, 1, 8);
            this.output(itemstack);
        }

In this code, the system will print 1 and 3, suggesting it is running the code where the energy is consumed but not actually doing so.

Edit:

I have found a solution to this issue. For future reference I had to add these lines of code to sync the server and client:

this.markDirty();
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);

Thanks to those who gave help.

ripple 1
  • 1
  • 1
  • 1
  • 4

3 Answers3

0

Probably, you run in a concurrency problem. For example, if int j is not declared as volatile then the changes that have been made in another thread may never become visible.

howlger
  • 31,050
  • 11
  • 59
  • 99
  • I had an extensive look at the concurrency documentation and tried declaring the variable volatile and synchronizing the methods. None of this worked so I wonder if you can give me more information or an example. Thank you for the help so far. – ripple 1 Jul 04 '16 at 10:48
  • Make sure both `this.j` are a field of the **same instance** of this class. – howlger Jul 04 '16 at 11:36
  • I can confirm that they are both the same instance. – ripple 1 Jul 04 '16 at 11:44
  • How you can confirm this? Please describe what you have checked. – howlger Jul 04 '16 at 11:59
  • It is declared outside of a method (as my understand goes) as public int j = 0; This variable does not appear in any local method. this is my understanding of what instances are but I might be wrong here/ – ripple 1 Jul 04 '16 at 12:04
  • If you have a class _MyClass_ then each `new MyClass()` will create a new instance of this class and the same (non-static) field of different instances of the same class are different. – howlger Jul 04 '16 at 12:17
  • Ah! I see; that clears things a bit more. However, I only have one instance and that is the main class itself as all of the variables are updated within the class itself and therefore a new instance is not necessary. However, i do call the class from another class to check the stats of the block; does this cause another instance to be created? - TileEntityPa te = (TileEntityPa) entity; – ripple 1 Jul 04 '16 at 12:23
0

When you say the variables are not updating, how do you know they aren't? Have you got output lines in your code listing them? Or breakpoints?

You are not correctly decreasing the stack size of the chest. You are decreasing the size of the stack in the passed in slot by 1 and then decreasing the size of the stack in slot i (0) by the new stack size of the passed in slot. You should be passing in the slot index instead of the slot, and then calling chest.decrStackSize(slotIndex, 1); Another tip is to use this.energyStored >= 600000 instead of checking for more than and equal to seperately. Based on your example, the isAccelerating field is never set to 2, so the update code will never run.

Alpvax
  • 144
  • 2
  • 10
  • I used output lines which showed that the variable being set to 2 in the method worked but not outside of that method. The block gets the item in the chest but never uses energy. this isn't the entire code as the entire class is >600 lines long. That was an example of what an itemstack triggers. the isAccelerating field is set to 2 when another itemstack sets it to 2, but that is not working. – ripple 1 Jul 04 '16 at 11:19
  • Could you show the method where isAccelerating is set to 2? That may help me follow exactly what is going on. What are i and j, what do they mean? – Alpvax Jul 04 '16 at 11:32
  • I have changed the layout of things since the original post but the main purpose is the same. This is the code for isAccelerating being set to 2 (see main code in a minute for update) – ripple 1 Jul 04 '16 at 11:37
  • I would recommend renaming i and j to more meaningful names. Am I correct in assuming that that code is also called from your update method? – Alpvax Jul 04 '16 at 11:46
  • That is a good suggestion. I automatically always use i from increment and then the letter after that, j, as a limit to the increment. – ripple 1 Jul 04 '16 at 11:49
  • You could also simplify your code by having `if(this.module != 1 || this.energyStored >= 600000){` and then only having the changing variables code once. – Alpvax Jul 04 '16 at 11:51
  • i and j are good, and often used like that, but it is best to keep them local variables in those cases (e.g. inside loops, where it is really clear what they both mean) – Alpvax Jul 04 '16 at 11:52
  • Would that work? It has to check whether a module is installed, and if it has enough energy that run but if it doesn't, then run anyway (this is a safety module which stops it running if it doesn't have enough power). – ripple 1 Jul 04 '16 at 11:53
  • yes, because you would be saying if the module is not installed or if the power is high enough, run the code in the block. Due to how the `||` operator works, if the first boolean evaluates to true, the second is never checked, so if the second is being checked then it means the first must have evaluated to false (i.e. the module is enabled) – Alpvax Jul 04 '16 at 11:57
  • Ah! That makes sense. Didn't realise the || operator ran like that. Thanks for the info. – ripple 1 Jul 04 '16 at 11:58
  • They are called short-circuit operators. See http://stackoverflow.com/a/8759917/3713256 for quite a good explanation. – Alpvax Jul 04 '16 at 12:03
0

I have found a solution to this issue. For future reference I had to add these lines of code to sync the server and client:

this.markDirty(); worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);

Thanks to those who gave help.

ripple 1
  • 1
  • 1
  • 1
  • 4