FallingBlocks disappearing?

Discussion in 'Plugin Development' started by flash110, Jun 30, 2016.

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

    flash110

    Ok so I have had some problems with fallingblocks disappearing when riding on another entity. I have tried listening to multiple events and canceling but nothing has worked. Also it may be important to note that nothing is triggering it, like the silverfish going next to a block or into a block like grass or a torch. Here is my current code:

    Code:
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Entity;
    import org.bukkit.entity.EntityType;
    import org.bukkit.entity.FallingBlock;
    import org.bukkit.entity.Player;
    import org.bukkit.entity.Silverfish;
    import org.bukkit.event.Listener;
    import org.bukkit.plugin.java.JavaPlugin;
    
    public class RandomTest extends JavaPlugin implements Listener {
        Entity Cactus;
        public void onEnable() {
        Bukkit.getPluginManager().registerEvents(this, this);  
        }
        public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
           
             Player p = (Player) sender;
         if (cmd.getName().equalsIgnoreCase("random")) {
             Location loc = p.getLocation();
             @SuppressWarnings("deprecation")
            FallingBlock block = (FallingBlock) p.getWorld().spawnFallingBlock(loc, Material.CACTUS, (byte)1);
             Silverfish base = (Silverfish) p.getWorld().spawnEntity(loc, EntityType.SILVERFISH);
             base.setPassenger(block);
             block.setDropItem(false);
             Cactus = block;
         }
         Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
             public void run() {
                 Cactus.setTicksLived(1);
             }
    }, 20, 20);
        return true;
         }
    }
     
  2. Offline

    I Al Istannen

    @flash110
    Falling sand will stay for 600 ticks or 30 seconds. This is determined by the ticksLived of the fallingsand. In normal minecraft you won't reach this limit, but if it rides an entity, you will.
    What you need to do is resetting the ticks lived every few seconds. What you tried.

    To your Java: variables start with a lowercase letter and then use camelCase.

    The reason why your code doesn't work is that the setTicksLived method does just nothing on falling blocks. I have no idea why. I needed to use some cheeky NMS to get it to work.

    I don't know how fit you are with reflection, but it would be this:
    Code:
    // get the class of the falling block. Needed for nearly all Reflection operations
    Class<?> clazz = fallingBlock#getClass()
    
    // Now we have a CraftFallingBlock. We need the NMS class. Invoke the getHandle method, to get the EntityFallingBlock
    Method getHandle = clazz.getMethod("getHandle")
    
    // now invoke it to get it
    Object handle = getHandle.invoke(block)
    
    // Get the ticks the entity has lived. In this case it is a public field, so using getField() should work.
    Field ticksLived = handle.getField("ticksLived")
    
    // set the value of the field to 1 for the object handle (which is the falling block)
    ticksLived.set(handle, 1)
    Put it in a Util method and call it instead of using setTicksLived. It is stupid such a simple thing takes so much effort, but I haven't found a better way yet.
     
  3. Offline

    flash110

    @I Al Istannen Ok I'll try that. I was going to make most of it in NMS like creating the fake entity but I have yet to figure out or use reflection or NMS. (which is why I stayed away from it.) Do you have any threads that could help me with some basic concepts?
     
  4. Offline

    I Al Istannen

    @flash110
    NMS is not documented and changes over versions. You will have to google for stuff and then try to adapt it. What is really helpful is having a decompiler (I mentioned two here) and having a look at the spigot/bukkit.jar. This way you can look at how the server handles it and figure it out from there.
    Another way is the minecraft coder pack, which has completly decompiled and renamed sources (meaning the names of most methods and fields have a meaning and are not "a" "b" "c" and so on). Can also be helpful somtimes.

    But NMS is mostly trial and error, printing out class fields and cursing. Doesn't help that it oftentimes changes over minor versions and often over major ones.

    I would stay away from it as often as you can. Seriously. Don't use it if you don't have to :p

    Reflection: The oracle "The Reflection API" trail.
     
Thread Status:
Not open for further replies.

Share This Page