Stop FallingBlock from becoming solid when they hit the ground

Discussion in 'Plugin Development' started by jensdeboom, Nov 12, 2014.

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

    jensdeboom

    Hi,
    Does anyone know how to stop a FallingBlock from becoming solid when they hit the ground?
    Ive tried two things:
    1. Canceling EntityChangeBlockEvent (Entity still dies)
    2. Checking the blocks position with a scheduler.
    Both didnt give good results. I want the block to be on the ground (or a little bit higher if necesarry) but I still want to be able to give them Velocitys so they need to stay a FallingBlock/Entity.

    Does anyone know a solution to this?
    Thanks
     
  2. Offline

    jensdeboom

  3. jensdeboom can you give me a example? you have a fallingblock like sand and it falls down until it hits a solid block. at this timepoint the sand changes to a solid block and is no longer a fallingblock, is this what you want to say? and what would blocking this do for you? why do you need to do this?
     
  4. Offline

    Rocoty

    jensdeboom One solution is to send the packet of falling blocks to clients. This would mean there is no falling block really present in the world, but the players perceive such.

    Another solution would be to make your own implementation of EntityFallingBlock that never turns into a solid block. This would require more work, but in turn you would actually have a falling block entity in the world which would give you a bit more control.
     
  5. Offline

    Skionz

    EntityBlockFormEvent
     
  6. Offline

    jensdeboom

    Skionz pretty sure that does the same as EntityChangeBlockEvent: a solid block will not be formed but the fallingblock entity still dies.

    Shmobi I have a fallingblock wich can be controlled by a player but if they look down, the fallingblock will turn solid. I would like it to stay a fallingblock so I can still apply velocities on it.

    Rocoty Sending the packet is no options because I need to detect where the block is and need it to trigger events. Your second solution seems pretty hard but I might try it. I'm not to familiar with NMS but I've worked with it before. I think I would have to extend FallingBlock and override the methods that turn the block solid, right? Also, I have no idea wich methods I should override. Where can I find them?
     
  7. jensdeboom if the entity dies, there should be a entitydeathevent you can cancel, shouldn't it? also i would try the entityblockformevent. there wouldn't be a different event if it would do the same. just give it a chance
     
  8. Offline

    jensdeboom

    Shmobi I don't think there is such an event ;P . I know EntityBlockFormEvent wont work because I've read a million threads about this and they all said EntityBlockChangeEvent and EntityBlockFormEvent prevent the block from becoming solid but the entity still dies. I'll test it tough.
     
  9. jensdeboom entitydeathevent is thrown if an entity dies, isn't it? if it really "dies" you can cancel this event and it wont be removed :)
     
  10. Offline

    jensdeboom

    Shmobi Oh yeah but thats bot cancelable I think because when I tried to do it when a player or a mob dies, it doesnt work. But maybe it does with a FallingBlock entity.
     
  11. jensdeboom what if you spawn a new fallingblock at the same position and the same material and set this one to the players falling block. will it die, too or will it survive because it won't hit the ground?
     
  12. Offline

    Rocoty

  13. Offline

    jensdeboom

  14. jensdeboom what if you just don't let the fallingblock let tutch the ground? check with every move its location and look if the location right under it is a solid block. if so stop moving it down. hold it in air instead :) this should work fine :D
     
  15. Offline

    jensdeboom

    Shmobi Already tried that, didn't work out as I wanted it to work.
     
  16. jensdeboom can you show me how you tried that?
     
  17. Offline

    jensdeboom

    Rocoty When trying to extend the class and import all the stuff, It says "the method getById() is undefined for Block"... Imported Block from net.minecraft.server.v1_7_R1.Block. Any ideas?
     
  18. Offline

    TheCodingCat

    why dont you just get the distance it is from the ground, do a little math by getting the speed of the falling block, and then create a BukkitRunnable and if you did your calculations crrectly you can kill the block
     
  19. Offline

    jensdeboom

    TheCodingCat I tried that by calculating the distance to the ground and placing them a few blocks higher but somehow it didn't work... Probably wrong calculations because I rushed it. I'll try that again if the thing I'm trying now really doesn't work. Any ideas about my last post?
     
  20. Offline

    Skionz

    jensdeboom
    Your going to cancel the EntityChangeBlockEvent
    Code:
    public void onForm(EntityChangeBlockEvent event) {
        if(event.getEntity().getType() == EntityType.FALLING_BLOCK) {
            event.setCancelled(true);
    }}}
    It will still spawn a bunch of annoying Items so you should also cancel the ItemSpawnEvent when necessary.
     
    kicjow likes this.
  21. Offline

    TheCodingCat

    hmmm check the available functions and see if there are any things that relate to ids OR check the javadocs.
     
  22. Offline

    jensdeboom

    Skionz I've tried that but it still removes the FallingBlock altough no solid block is spawned.
     
  23. Offline

    Skionz

    jensdeboom What do you want then? I thought you wanted to prevent falling blocks from forming into Blocks?
     
  24. Offline

    jensdeboom

    Skionz I'd like to prevent the FallingBlock from dissapearing, that's why I'm trying to create my custom FallingBlock, no succes so far.
    TheCodingCat Huh? This method is in the Block class:
    Code:
    public static Block getById(int i) {
            return (Block) REGISTRY.a(i);
        }
    This is my code + imports (It's basicly just this code: https://github.com/Bukkit/mc-dev/blob/master/net/minecraft/server/EntityFallingBlock.java + imports <-- I think something went wrong there :
    Code:
    package me.jensdeboom.PvPNetwork;
     
    import java.util.ArrayList;
    import java.util.Iterator;
     
    import net.minecraft.server.v1_7_R1.Block;
    import net.minecraft.server.v1_7_R1.BlockFalling;
    import net.minecraft.server.v1_7_R1.Blocks;
    import net.minecraft.server.v1_7_R1.CrashReportSystemDetails;
    import net.minecraft.server.v1_7_R1.DamageSource;
    import net.minecraft.server.v1_7_R1.Entity;
    import net.minecraft.server.v1_7_R1.EntityFallingBlock;
    import net.minecraft.server.v1_7_R1.IContainer;
    import net.minecraft.server.v1_7_R1.ItemStack;
    import net.minecraft.server.v1_7_R1.Material;
    import net.minecraft.server.v1_7_R1.MathHelper;
    import net.minecraft.server.v1_7_R1.NBTBase;
    import net.minecraft.server.v1_7_R1.NBTTagCompound;
    import net.minecraft.server.v1_7_R1.TileEntity;
    import net.minecraft.server.v1_7_R1.World;
     
    public class CustomFallingBlock extends EntityFallingBlock {
     
        private Block id;
        public int data;
        public int ticksLived;
        public boolean dropItem;
        private boolean f;
        private boolean hurtEntities;
        private int fallHurtMax;
        private float fallHurtAmount;
        public NBTTagCompound tileEntityData;
     
        public CustomFallingBlock(World world) {
            super(world);
            this.dropItem = true;
            this.fallHurtMax = 40;
            this.fallHurtAmount = 2.0F;
        }
     
        public CustomFallingBlock(World world, double d0, double d1, double d2, Block block) {
            this(world, d0, d1, d2, block, 0);
        }
     
        public CustomFallingBlock(World world, double d0, double d1, double d2, Block block, int i) {
            super(world);
            this.dropItem = true;
            this.fallHurtMax = 40;
            this.fallHurtAmount = 2.0F;
            this.id = block;
            this.data = i;
            this.a(0.98F, 0.98F);
            this.height = this.length / 2.0F;
            this.setPosition(d0, d1, d2);
            this.motX = 0.0D;
            this.motY = 0.0D;
            this.motZ = 0.0D;
            this.lastX = d0;
            this.lastY = d1;
            this.lastZ = d2;
        }
     
        protected boolean g_() {
            return false;
        }
     
        protected void c() {}
     
        public boolean R() {
            return !this.dead;
        }
     
        public void h() {
            if (this.id.getMaterial() == Material.AIR) {
                this.die();
            } else {
                this.lastX = this.locX;
                this.lastY = this.locY;
                this.lastZ = this.locZ;
                ++this.ticksLived;
                this.motY -= 0.03999999910593033D;
                this.move(this.motX, this.motY, this.motZ);
                this.motX *= 0.9800000190734863D;
                this.motY *= 0.9800000190734863D;
                this.motZ *= 0.9800000190734863D;
                if (!this.world.isStatic) {
                    int i = MathHelper.floor(this.locX);
                    int j = MathHelper.floor(this.locY);
                    int k = MathHelper.floor(this.locZ);
     
                    if (this.ticksLived == 1) {
                        if (this.world.getType(i, j, k) != this.id) {
                            this.die();
                            return;
                        }
     
                        this.world.setAir(i, j, k);
                    }
     
                    if (this.onGround) {
                        this.motX *= 0.699999988079071D;
                        this.motZ *= 0.699999988079071D;
                        this.motY *= -0.5D;
                        if (this.world.getType(i, j, k) != Blocks.PISTON_MOVING) {
                            this.die();
                            if (!this.f && this.world.mayPlace(this.id, i, j, k, true, 1, (Entity) null, (ItemStack) null) && !BlockFalling.canFall(this.world, i, j - 1, k) && this.world.setTypeAndData(i, j, k, this.id, this.data, 3)) {
                                if (this.id instanceof BlockFalling) {
                                    ((BlockFalling) this.id).a(this.world, i, j, k, this.data);
                                }
     
                                if (this.tileEntityData != null && this.id instanceof IContainer) {
                                    TileEntity tileentity = this.world.getTileEntity(i, j, k);
     
                                    if (tileentity != null) {
                                        NBTTagCompound nbttagcompound = new NBTTagCompound();
     
                                        tileentity.b(nbttagcompound);
                                        Iterator iterator = this.tileEntityData.c().iterator();
     
                                        while (iterator.hasNext()) {
                                            String s = (String) iterator.next();
                                            NBTBase nbtbase = this.tileEntityData.get(s);
     
                                            if (!s.equals("x") && !s.equals("y") && !s.equals("z")) {
                                                nbttagcompound.set(s, nbtbase.clone());
                                            }
                                        }
     
                                        tileentity.a(nbttagcompound);
                                        tileentity.update();
                                    }
                                }
                            } else if (this.dropItem && !this.f) {
                                this.a(new ItemStack(this.id, 1, this.id.getDropData(this.data)), 0.0F);
                            }
                        }
                    } else if (this.ticksLived > 100 && !this.world.isStatic && (j < 1 || j > 256) || this.ticksLived > 600) {
                        if (this.dropItem) {
                            this.a(new ItemStack(this.id, 1, this.id.getDropData(this.data)), 0.0F);
                        }
     
                        this.die();
                    }
                }
            }
        }
     
        protected void b(float f) {
            if (this.hurtEntities) {
                int i = MathHelper.f(f - 1.0F);
     
                if (i > 0) {
                    ArrayList arraylist = new ArrayList(this.world.getEntities(this, this.boundingBox));
                    boolean flag = this.id == Blocks.ANVIL;
                    DamageSource damagesource = flag ? DamageSource.ANVIL : DamageSource.FALLING_BLOCK;
                    Iterator iterator = arraylist.iterator();
     
                    while (iterator.hasNext()) {
                        Entity entity = (Entity) iterator.next();
     
                        entity.damageEntity(damagesource, (float) Math.min(MathHelper.d((float) i * this.fallHurtAmount), this.fallHurtMax));
                    }
     
                    if (flag && (double) this.random.nextFloat() < 0.05000000074505806D + (double) i * 0.05D) {
                        int j = this.data >> 2;
                        int k = this.data & 3;
     
                        ++j;
                        if (j > 2) {
                            this.f = true;
                        } else {
                            this.data = k | j << 2;
                        }
                    }
                }
            }
        }
     
        protected void b(NBTTagCompound nbttagcompound) {
            nbttagcompound.setByte("Tile", (byte) Block.getId(this.id));
            nbttagcompound.setInt("TileID", Block.getId(this.id));
            nbttagcompound.setByte("Data", (byte) this.data);
            nbttagcompound.setByte("Time", (byte) this.ticksLived);
            nbttagcompound.setBoolean("DropItem", this.dropItem);
            nbttagcompound.setBoolean("HurtEntities", this.hurtEntities);
            nbttagcompound.setFloat("FallHurtAmount", this.fallHurtAmount);
            nbttagcompound.setInt("FallHurtMax", this.fallHurtMax);
            if (this.tileEntityData != null) {
                nbttagcompound.set("TileEntityData", this.tileEntityData);
            }
        }
     
        protected void a(NBTTagCompound nbttagcompound) {
            if (nbttagcompound.hasKeyOfType("TileID", 99)) {
                this.id = Block.getById(nbttagcompound.getInt("TileID"));
            } else {
                this.id = Block.getById(nbttagcompound.getByte("Tile") & 255);
            }
     
            this.data = nbttagcompound.getByte("Data") & 255;
            this.ticksLived = nbttagcompound.getByte("Time") & 255;
            if (nbttagcompound.hasKeyOfType("HurtEntities", 99)) {
                this.hurtEntities = nbttagcompound.getBoolean("HurtEntities");
                this.fallHurtAmount = nbttagcompound.getFloat("FallHurtAmount");
                this.fallHurtMax = nbttagcompound.getInt("FallHurtMax");
            } else if (this.id == Blocks.ANVIL) {
                this.hurtEntities = true;
            }
     
            if (nbttagcompound.hasKeyOfType("DropItem", 99)) {
                this.dropItem = nbttagcompound.getBoolean("DropItem");
            }
     
            if (nbttagcompound.hasKeyOfType("TileEntityData", 10)) {
                this.tileEntityData = nbttagcompound.getCompound("TileEntityData");
            }
     
            if (this.id.getMaterial() == Material.AIR) {
                this.id = Blocks.SAND;
            }
        }
     
        public void a(boolean flag) {
            this.hurtEntities = flag;
        }
     
        public void a(CrashReportSystemDetails crashreportsystemdetails) {
            super.a(crashreportsystemdetails);
            crashreportsystemdetails.a("Immitating block ID", Integer.valueOf(Block.getId(this.id)));
            crashreportsystemdetails.a("Immitating block data", Integer.valueOf(this.data));
        }
     
        public Block f() {
            return this.id;
        }
     
    }
    
    EDIT: My Block class (net.minecraft.server.v1_7_R1.Block) contains a method e(int) wich returns a block so I guess that's it, still wondering why my Block class is different to the GitHub one... Maybe because I'm building against CraftBukkit 1.7.2?
     
Thread Status:
Not open for further replies.

Share This Page