Solved Casting a Chest

Discussion in 'Plugin Development' started by mrCookieSlime, Jan 5, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    mrCookieSlime

    Hey, well has Bukkit changed anything on the Chest?

    Because I'm getting this Error:
    Code:java
    1.  
    2. java.lang.ClassCastException: org.bukkit.craftbukkit.v1_7_R1.block.CraftBlockSta
    3. te cannot be cast to org.bukkit.block.Chest
    4.  

    on this part:

    Code:java
    1. if (location.getBlock().getType() == Material.CHEST) {
    2. Chest c = (Chest) location.getBlock().getState();
    3. /...
    4. }


    Have I forgot something, or is it a Bukkit Bug?
     
  2. Offline

    dillyg10

    That's odd... try this debug:

    System.out.println(Chest instanceof BlockState);
     
  3. Offline

    mrCookieSlime

    dillyg10
    The Code doesn't even trigger since the Exception is made before.

    Also just looking through Bukkit's Source code:
    Code:java
    1. public abstract interface Chest extends BlockState, ContainerBlock
    2. {
    3. public abstract Inventory getBlockInventory();
    4. }


    So I should be able to cast it to a Chest since it's an extension of BlockState
     
  4. Offline

    CeramicTitan

    mrCookieSlime
    Check if the block is an instanceof Chest. If that doesnt work, check if block.get state() is an instanceof Chest
     
  5. Offline

    mrCookieSlime

    CeramicTitan

    I made sure it is a Chest, also I did
    Code:java
    1. if (location.getBlock().getType() == Material.CHEST) {
     
  6. Offline

    CeramicTitan

    Trust me. Do what I said...
     
  7. Offline

    RawCode

    what about reading javadocs and souce code before coding?

    Code:
        public BlockState getState() {
            Material material = getType();
     
            switch (material) {
            case SIGN:
            case SIGN_POST:
            case WALL_SIGN:
                return new CraftSign(this);
            case CHEST:
            case TRAPPED_CHEST:
                return new CraftChest(this);
            case BURNING_FURNACE:
            case FURNACE:
                return new CraftFurnace(this);
            case DISPENSER:
                return new CraftDispenser(this);
            case DROPPER:
                return new CraftDropper(this);
            case HOPPER:
                return new CraftHopper(this);
            case MOB_SPAWNER:
                return new CraftCreatureSpawner(this);
            case NOTE_BLOCK:
                return new CraftNoteBlock(this);
            case JUKEBOX:
                return new CraftJukebox(this);
            case BREWING_STAND:
                return new CraftBrewingStand(this);
            case SKULL:
                return new CraftSkull(this);
            case COMMAND:
                return new CraftCommandBlock(this);
            case BEACON:
                return new CraftBeacon(this);
            default:
                return new CraftBlockState(this);
            }
        }
     
  8. Offline

    mrCookieSlime

    RawCode
    ... Dude I was using this Method like 100 times before and it always worked, I'm just confused that it doesn't work anymore

    Also: CeramicTitan

    somehow I got this:

    Code:java
    1. System.Out.println(location.getBlock().getType() == Material.CHEST); -> true
    2. System.Out.println(location.getBlock().getState() instanceof Chest); -> false
    3.  
    4.  


    I have no idea... Seems like it is a Chest but it isn't a Chest :?
     
  9. Offline

    BillyGalbreath

    Code:java
    1.  
    2. Block block = location.getBlock();
    3. if (block.getType() == Material.CHEST) {
    4. Chest c = (Chest) block.getState();
    5. /...
    6. }
    7.  

    Yes, this really matters. Retarded, I know.
     
  10. Offline

    mrCookieSlime

    BillyGalbreath
    ? What do you mean?

    Also: Somehow it works now, I changed nothing, but it works
     
  11. Offline

    BillyGalbreath

    You were getting the block, and checking if it was material chest. Since it was, you grabbed a new block object and tried casting it. Since this new object wasnt checked, it errors. Store the block object, check it, cast it, profit.
     
  12. Offline

    mrCookieSlime

    BillyGalbreath
    Errr, no. since it's the same Location. location.getBlock() will always return the same Block
     
  13. Offline

    BillyGalbreath

    Yes, its the same block. But not the same block object. location.getBlock() grabs a block object. You need to store it so you can reuse that block object instead of grabbing a new one.
     
  14. Offline

    CeramicTitan

    That's not what he saying though. It keeps creating a new block instance, you need to save that instance in a variable and use that to check. Not whether the block changes or not.
     
    BillyGalbreath likes this.
  15. Offline

    mrCookieSlime

    CeramicTitan
    Yes but there's seriously no difference if I get the Object twice since it's always the same Block
     
  16. Offline

    BillyGalbreath

    Ok, think of it this way. (analogy time! yay!)

    The block is a file on the internet. You put in the URL and download it. I decide to download the same file. We both have the same file downloaded now. But they are not the same. They are copies.

    Same concept here. Every time you getBlock() you are getting an instance of that block (a copy, so to speak). You are checking one copy, and then casting a different copy without checking it too. Thats where the error is coming from.
     
  17. Offline

    mrCookieSlime

    BillyGalbreath
    No, your understanding it completely wrong... It will always be the same Block, yes it will be another Object but there's no difference...

    For example: You open a Chest ingame and close it. Then I'll open and close it again. But since we didn't change anything. It IS the same Chest.
     
  18. Offline

    BillyGalbreath

    Idk how else to explain this to you...

    Here, see if you can follow this:

    http://jd.bukkit.org/rb/doxygen/d4/dd8/Location_8java_source.html

    As you can see on line 82, world.getBlockAt(Location); So lets go look at that, shall we?

    https://github.com/Bukkit/CraftBukk...a/org/bukkit/craftbukkit/CraftWorld.java#L493

    Ok, so that splits the Location up into x/y/z for that world; Lets move on.

    https://github.com/Bukkit/CraftBukk...va/org/bukkit/craftbukkit/CraftWorld.java#L82

    As we see here, the block is actually being called from the chunk. So lets have a look at that.

    https://github.com/Bukkit/CraftBukk...va/org/bukkit/craftbukkit/CraftChunk.java#L80

    Oh snap! Its a NEW copy of the block object! :O
     
  19. Offline

    CeramicTitan

    lol, personally I think this was the most confusing explanation
     
    jimbo8 likes this.
  20. Offline

    BillyGalbreath

    Well, I tried. lol :p
     
  21. Offline

    mrCookieSlime

    BillyGalbreath
    Sure believe whatever you're thinking...

    but I don't know if you have heard of this, but Minecraft has a X/Y/Z coordinate System and if you for example get the Block at -23 64 823 and you get it again, you'll always get the same Block, cause it's bound to it's coordinates P:
     
  22. Offline

    BillyGalbreath

    Oh!!! I see where you're getting confused. You don't understand what an Object is... I suggest reading up on some basic Java Objects to get a better understanding.

    Edit: I'll be nice, and try to explain as best I know how:

    I know the block is the same. You know the block is the same. I know that you know the block is the exact same. But trust me, the computer doesn't. All it knows is it has an instance of an object. It checks what that object is. Then it tries to cast a completely new object it hasn't seen before. It doesn't know what it is, so it refuses to cast it.
     
  23. Offline

    CeramicTitan

    But you see, what he is trying to is that in the PROGRAM(your plugin) the block you get, wont change but the progam sees it as a new block each time. So saving in a variable will only return the block we are interested in.

    Object oriented, its like the first thing you learn in every programming tutorial :p
     
  24. Offline

    mrCookieSlime

    BillyGalbreath
    Dude, I know what an Object is...
    But you should definitely try this new activity called "listening".
    I never said it's the same Object...
    But it will always be the same Block.
    CeramicTitan
    I know that it sees it like this, but since the Location is the same I'll always get the Block I'm interested in.
     
  25. Offline

    CeramicTitan

    lol, are you trolling? If not ill try one more time. So we have a chest at a location, the code will get that block but it will always return a new version of it. We want the old version and we want to keep using that OLD version, so we store it in a variable.
     
  26. Offline

    BillyGalbreath

    Ok, this is seriously going to be my last attempt. I'm starting to get bored with this now...

    Another analogy:

    Think of a computer as a blind man, and all your blocks/variables are cards in a deck that are spread across the table. You (the programmer) tell the blind man to grab a card at a certain location on the table and check if its actually a chest. It is. Now, since you didnt tell him to save that card that we now know is actually a chest into a variable the blind man discards it back onto the table. Next, you tell him to grab a card in the same exact position and cast it to a chest. He reaches out and grabs the card and picks it up. But wait. He doesnt know what this card is. Is it a chest? Is it something else? Did someone else at the table shift the playing cards around? He doesnt know, so he refuses to cast it to a chest.

    Checks like this are put in place for ignorant programmers. It prevents them from releasing a product that has the potential to crash a server.
     
    Bart and CeramicTitan like this.
  27. Offline

    Chinwe

    Seems you're using the wrong kind of blockstate: use Bukkit's BlockState instead of CraftBukkit's ?
     
  28. Offline

    mrCookieSlime

    CeramicTitan
    ... I know I could store it, but I still don't see a reason for it why.

    BillyGalbreath
    Ok, to explain it so you can understand this:
    The Blind man takes a card and puts it on the exact same position again. Nothing changes then and he takes it again and it's still the same Card since nothing changed...

    Also: I don't know why you guys keep trying to explain this to me.
    Every Coder has it's own way of coding things so why don't you let me do it on my way?

    Chinwe
    I'm not, but also thought this at the beginning.
     
  29. Offline

    BillyGalbreath

    Because the blind man doesnt know if anything on the table has changed. There are all sorts of safeguards like this coded into Bukkit all over the place to prevent ignorant/new developers from accidentally crashing servers.

    You have to remember, computers are dumb. They comprehend nothing.
    Yes, there is more than one way to skin a cat. However, you are blatantly ignoring why your error appears. You came here for help, I am trying to help you.
     
  30. Offline

    RawCode

    Looks like everyone on this forum ignore direct answers if they require a bit of brain activity or reading more then single line.
    I will test my teory now and place answer on 4th line of post
    getState() returns CraftChest() not Chest()
     
Thread Status:
Not open for further replies.

Share This Page