Making Blocks Float (Sand, Gravel)

Discussion in 'Plugin Development' started by TehVoyager, Aug 2, 2014.

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

    TehVoyager

    Hello,
    I am making a plugin that regenerates explosion damage and I have come across an issue. If a block explodes and there is gravel/sand/anvil/ect above it that block will fall and the regeration will be messed up. Is there a way to disable physics from a single block?
     
  2. Offline

    Gerov

    TehVoyager Try doing a block physics event and cancel it if the block is part of the explosion's block list.
     
  3. Offline

    TehVoyager

    Gerov
    I have looked at the block physics event but I don't want it to be for every block on the server and I don't see a way to get if the block is one that was not exploded but the block below it was.

    Bump

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 9, 2016
  4. Offline

    megasaad44

    How are you saving the blocks in the explosion to regenerate them in the first place?
    And get the tnt block and get the radius around it for like 20 radius, then search in that radius for sand/gravel/anvil. If found, put those in an array list. Then cancel the physics even when you find those blocks. I can give you a radius template if you like.
     
  5. Offline

    NathanWolf

    What I do for this, which works pretty well, is to catch the "spawn" event for falling blocks (it's the entity change block event, I think) and detect when it's in the volume of my explosion.

    You can then track or remove the falling block, and record the block it removed.

    Finally, you also have to constantly expand your tracking volume to catch stacked falling blocks.

    Works pretty well, though quite complex and took me a while to work out.
     
  6. Offline

    TehVoyager

    megasaad44
    I am going through the explosion's blocklist and checking if the block above the current block is in the blocklist, if not(its not in the explosion) I can get that block but I'm stuck there.

    NathanWolf
    That could work for those blocks but I also need floating flowers, carpet, ect

    bump

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 9, 2016
  7. Offline

    NathanWolf

    Oh... yeah that's a pain, too! Well I think you have the right idea- check the block above each block that got exploded, and then check if it's something that "attaches" to the block beneath it. Unfortunately, I'm not aware of an easy check for this- I just have a list...

    https://github.com/elBukkit/MagicPl...esources/defaults/materials.defaults.yml#L203

    I load that list into a HashSet, and use it to detect block types that attach to other blocks, and would need addition to an undo list.

    I wish there was an event or something for this kind of breakage, but as far as I know, there is not.
     
  8. Offline

    desht

    If you want to keep attachable blocks floating after the solid block they're attached to gets broken, you can use the BlockPhysicsEvent like this (untested code):
    PHP:
    @EventHandler(ignoreCancelled true)
    public 
    void onBlockPhysics(BlockPhysicsEvent event) {
      
    Block b event.getBlock();
      
    // yeah, it's deprecated... it'll still work
      
    MaterialData matData b.getType().getNewData(b.getData());
      if (
    matData instanceof Attachable) {
         
    BlockFace face = ((AttachablematData).getAttachedFace();
         if (!
    b.getRelative(face).isSolid()) {
            
    // block it was attached to is no longer there
            // cancelling the physics event stops the attachable popping off
            
    event.setCancelled(true);
         }
      }
    }
     
    NathanWolf likes this.
  9. Offline

    NathanWolf

    Oooh, "instanceof Attachable" ... does that cover all the cases, or is that just "wall attachable" stuff... I will have to look closer.

    I'd imagine for the OP's desires, instead of canceling the event, you'll want to let it happen, but record that block as part of your "regeneration" list. But this is a great suggestion nonetheless.

    However, I would strongly caution about the BlockPhysicsEvent - I've found it's very expensive to implement, even if you're just doing a very simple "should I cancel it?" check. That event gets called a lot. I had to dynamically add and remove my event listener to keep that under control- so just keep an eye on your timings.

    Disclaimer: the ridiculously destructive/creative nature of my plugin probably makes this way worse.. like when friendly griefers magic up a giant ball of water, for instance... but I still contend it's an expensive event, and you should be wary.
     
    desht likes this.
  10. Offline

    desht

    Actually Attachable won't cover things like doors or pressure plates, so it's not a 100% solution - good point.

    And yeah, BlockPhysicsEvent does get called a lot. It's the only way to absolutely know 100% if an adjacent block has changed, though.
     
    NathanWolf likes this.
Thread Status:
Not open for further replies.

Share This Page