-
-
Notifications
You must be signed in to change notification settings - Fork 26
Description
Hello!
I use CustomBlockData in my ODailyQuests plugin, to store blocks placed by players so they don't progress on PLACE quests. And it works perfectly, thank you very much for your work! I've only noticed one small flaw: blocks subject to gravity, such as sand or gravel, lose their associated CBD once they've fallen.
I've done a bit of research to try and figure out how to get around this problem and guide you, but I'd rather not make a pull request so as not to touch sensitive things.
When a block falls, the EntityChangeEvent is triggered twice: at the beginning of the fall, with its original state, and at the end of the fall, with its destination. The event recovers the entity, which is an instance of FallingBlock. The entity's UUID is the same for both events.
The only solution I've found is to store the UUIDs of the falling blocks, when the first event is triggered, in a Set. At the second event, if the Set contains the UUID, the block in question has completed its fall. We can then make the necessary modifications (transfer of CBD) and remove it from the Set.
The result would be something like this:
private final Set<UUID> fallingBlocks = new HashSet<>();
@EventHandler
public void onEntityChangeBlockEvent(EntityChangeBlockEvent event) {
// check if the entity is a falling block (sand, gravel...)
if (event.getEntity() instanceof FallingBlock fallingBlock) {
final UUID entityId = fallingBlock.getUniqueId();
final Location location = fallingBlock.getLocation();
if (!fallingBlocks.contains(entityId)) {
// first event : bloc not yet registered, storing UUID and source location
fallingBlocks.add(entityId);
Bukkit.getServer().getLogger().info("block falling from: " + location);
} else {
// second event : bloc already registered and landed
Bukkit.getServer().getLogger().info("bloc falling to: " + location);
Block block = location.getBlock();
/* TO DO: apply modifications to the new block (same logic as you use with pistons I assume) */
// remove the bloc from the list
fallingBlocks.remove(entityId);
}
}
}However, it's important to anticipate all cases where the block fails to reach its destination and is deleted. When the player breaks the block, if the block is broken by a torch or another entity... Just in case, perhaps it would be interesting to set up a Scheduler that cleans up regularly, but it remains to be seen what this would achieve in terms of performance.
If there's anything more I can do, please let me know. Thanks a lot!