Jump to content

Need help understanding getWatchableObjectByte()


wog890

Recommended Posts

This code is in EntityWolf

 

     /**
     * Determines whether this wolf is angry or not.
     */
    public boolean isAngry()
    {
        return (this.dataWatcher.getWatchableObjectByte(16) & 2) != 0;
    }

    /**
     * Sets whether this wolf is angry or not.
     */
    public void setAngry(boolean par1)
    {
        byte var2 = this.dataWatcher.getWatchableObjectByte(16);

        if (par1)
        {
            this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var2 | 2)));
        }
        else
        {
            this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var2 & -3)));
        }
    }

 

And this code is in EntityTameable

 

public boolean isTamed()
    {
        return (this.dataWatcher.getWatchableObjectByte(16) & 4) != 0;
    }

    public void setTamed(boolean par1)
    {
        byte var2 = this.dataWatcher.getWatchableObjectByte(16);

        if (par1)
        {
            this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var2 | 4)));
        }
        else
        {
            this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var2 & -5)));
        }
    }

 

I have looked this up online, and haven't been able to quite figure it out yet. I'm assuming that these functions are saving or loading a byte. Another assumption I'm making is that 16 is the number referencing to which byte to save or load. What really confuses me though, is that both taming and angry use 16, so wouldn't these override each other? I'm messing with this because I need to do the same thing as isTamed and isAngry do, to change the texture of my animal if you click it with a pink dye. Since this is how the game does it, I figured I should do it this way as well. If you can help me understand what this function does, I would really appreciate it.

Link to comment
Share on other sites

I also found it here

 

public boolean isSitting()
    {
        return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0;
    }

    public void setSitting(boolean par1)
    {
        byte var2 = this.dataWatcher.getWatchableObjectByte(16);

        if (par1)
        {
            this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var2 | 1)));
        }
        else
        {
            this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var2 & -2)));
        }
    }

Link to comment
Share on other sites

Minecraft uses Bit operations here to store multiple things in one byte.

e.g.: 14 & 1 gives you the value of the first bit in 14 (which is 0, because 14 = 1110 in binary) and 15 & 4 gives 4 (15 = 1111 in binary).

 

I'm still a little bit confused. If I understand correctly with the function (dataWatcher.getWatchableObjectByte(16) & 1), this means the value in the first byte of 16 (which I believe to be 10000) which would normally be 0) since the zero in that bit means false to that value. Now if it had been (17) & 1, or (10001), it would have returned 1 since a one in that bit means true to that value, and that bit represents a value of one.

 

If I have that correct, then here is my confusion, in your example above you state (15) & 1 gives 4, but wouldn't it give 8, since the fourth bit over represents a value of 8 and the third byte over represents 4.

 

If I am wrong in my above statements, I would appreciate it if you would explain what I've done wrong. If I am correct I hope I have not offended you, as you just saved my butt majorly. I have been looking all over the place and asking a lot of people and getting no help at all. You are amazing!

Link to comment
Share on other sites

I decided to try and step through isSitting() and setSitting(), to see if I now understand them. And I'm just going to assume I misunderstood something, since the way I'm doing it will always come up with the same return in isSitting(). If it isn't to much to ask, would you mind stepping through isSitting() and setSitting() and explaining them. If it is unreasonable, I understand.

Link to comment
Share on other sites

Ok, why not :)

First isSitting():

return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0;

dataWatcher.getWatchableObjectByte(16) gets a byte with Index 16 from the data watcher (the data watcher is the thing that syncs entity data between client & server).

A byte is 8 bits, e.g. 0000 0001, their "values" are 1, 2, 4, 8, 16, ... (2^n).

The & operator compares two numbers bitwise. If you compare lets say 1010 and 1000 with & you get: 1010 & 1000 = 1000 (only the bits which are set in both numbers are set in the result).

Now the number 1 looks like this (only 4 bits for simplicity): 0001. If you now compare that to any byte with & you only get the first bit of that byte. Examples:

1010 & 0001 == 0000

1011 & 0001 == 0001

So isSitting returns true if the first bit of the byte with ID 16 in the data watcher is set.

 

Now setSitting(boolean sitting).

First it gets the byte value with ID 16 again.

Then there are 2 options: either sitting is true or false. If its true we want to set the first bit to 1. Therefor we use the | (bitwise or) operator. Examples:

1010 | 0001 == 1011

1011 | 0001 == 1011

You see: If you combine any byte value with 1  by bitwise or, you get the same byte back, except that the first bit is always set, no matter if it was set before or not. That's exactly what we want for letting the dog sit (sitting == true).

 

Now if the dog should stop sitting. Now we need to set the first bit to 0, no matter what it was before. Easy task:

1010 & 1110 == 1010

1011 & 1110 == 1010

Now whats the value of 1111 1110? -2 :D

There you go, I hope that was at least a bit helpful :D

 

Yes Sir/Mam, that makes sense now. So with your previous example, it gave four because it was returning the byte in the bit representing four, not returning the bit four places over.

 

The only thing I don't understand is why 1111 1110 becomes a negative number, but I'm sure I can find that on the internet. I'm assuming we need a number with all ones (except for in the place we are resetting to 0) so that any other ones won't be reset. So if I wanted to change the bit representing 8 to 0, I would use, 1111 0111.

 

I should be able to continue now!!!!!!

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.