Hello, I am doing a troll plugin and in one of its functions I want to make all the lava look like water (without using texture packages), but that the rest of the players see how it really is, try this code: Code (Text): public static void b() { (new BukkitRunnable() { public void run() { for (Player bb : lavahide) try { getBlocks(bb.getLocation().getBlock(), 50, bb); } catch (Exception e) { } } }).runTaskTimer(plugin, 5L, 5L); } public static ArrayList<Block> getBlocks(Block start, int radius, Player p){ ArrayList<Block> blocks = new ArrayList<Block>(); for(double x = start.getLocation().getX() - radius; x <= start.getLocation().getX() + radius; x++){ for(double y = start.getLocation().getY() - radius; y <= start.getLocation().getY() + radius; y++){ for(double z = start.getLocation().getZ() - radius; z <= start.getLocation().getZ() + radius; z++){ Location loc = new Location(start.getWorld(), x, y, z); if (loc.getBlock().getType() == Material.LAVA) { p.sendBlockChange(loc, Material.WATER, loc.getBlock().getData()); } if (loc.getBlock().getType() == Material.STATIONARY_LAVA) { p.sendBlockChange(loc, Material.STATIONARY_WATER, loc.getBlock().getData()); } } } } return blocks; } But the problem is that the server wipes and you get to see that it is lava. How can I solve that? PS: Sorry for the translator, I'm from Argentina
You're using a BukkitRunnable, which means it will be delayed by 1/4 of a second. If you want it to be instantly, listen for the bucket use event and check if it is lava or listen for the block update change event.
Here is what is happening now: 1. You place the lava block (or the lava block flows into another block) 2. The lava block (or update) is sent to the player 3. You then overwrite the block to be water through the runnable The time in between 2 and 3 is the reason why you see the lava. In order to stop this, you need to prevent step 2 from happening by intercepting any block change or map chunk packets where the lava block is sent to the player and replace it with water. This is where something like ProtocolLib would be useful.
PlayerBucketEmptyEvent and Im not sure, but I think fluid liquids also trigger the BlockPhysicsEvent.
So it works with the block physics event, did you set up the player bucket empty event too^ Whats your current code
I don't want to detect when a player uses a lava bucket, but I'm going to put it, this is the code Code (Text): @SuppressWarnings({ "deprecation", "static-access" }) @EventHandler private void onBlockPhysics(BlockPhysicsEvent e) { if(e.getChangedType() == Material.LAVA || e.getBlock().getType() == Material.LAVA) { for(Player p : plugin.tl.lavahide) { p.sendBlockChange(e.getBlock().getLocation(), Material.WATER, e.getBlock().getData()); } } }
ProtocolLib is definitely the way to go here IMO, you can intercept the packets to make it seamless. Your current method is going to not work whenever a player loads the chunk. If you would like an implementation of ProtocolLib, I have one on my git. https://github.com/BigBadE/Enchantm...ntmenttokens/listeners/SignPacketHandler.java has my code for doing the same thing with signs. In your case you should use MAP_CHUNK (chunk load), Block change, and Block update. Check https://wiki.vg/Protocol for the packet data.