Paper icon indicating copy to clipboard operation
Paper copied to clipboard

Add BeehiveNectarDepositEvent

Open maxcom1 opened this issue 1 year ago • 1 comments

Adds cancellable BeehiveNectarDepositEvent. The event is fired after a Bee is released from a Beehive, when bee deposits nectar to the beehive.

Can be used to e.g.:

  • change amount of deposited nectar, modify final hive's honey level after deposition (deposited nectar amount is normally 1 or 2, we can set the value to e.g. 5)
  • use in various mechanisms
  • just cancel deposit of nectar to the hive

maxcom1 avatar Mar 08 '24 17:03 maxcom1

So I started testing

I changed Paper-server code of BeehiveBlockEntity as follows:

// Paper start - Fire EntityChangeBlockEvent in more places
BlockState newBlockState = iblockdata.setValue(BeehiveBlock.HONEY_LEVEL, i + j);

if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entitybee, blockposition, newBlockState)) {
    world.setBlockAndUpdate(blockposition, newBlockState);
}
// Paper end - Fire EntityChangeBlockEvent in more places

and modified my test plugin:

@EventHandler
public void onNectarDeposit(EntityChangeBlockEvent e) {
    if (!(e.getBlockData() instanceof Beehive newBeeHive)) return;
    if (!(e.getEntity() instanceof Bee bee)) return;

    Beehive oldBeeHive = (Beehive) e.getBlock().getBlockData();

    int oldHoneyLevel = oldBeeHive.getHoneyLevel();
    int newHoneyLevel = newBeeHive.getHoneyLevel();
    int difference = newHoneyLevel-oldHoneyLevel;

    Location beehiveLoc = e.getBlock().getLocation();

    String debug = "[NectarDepositListener] <yellow>Bee " + e.getEntity().getUniqueId() +
            " <white>dropped <gold>" + difference +
            " nectars <white>into "+
            " <yellow>Beehive at x: " + beehiveLoc.getBlockX() + ", y: " + beehiveLoc.getBlockY() + ", z: " + beehiveLoc.getBlockZ() + "<white>." +
            " The <aqua>old honey level <white>is <aqua>" + oldHoneyLevel + "<white>, <light_purple>new honey level <white>is <light_purple>" + newHoneyLevel;

    Bukkit.getServer().sendMessage(MiniMessage.miniMessage().deserialize(debug));

    ((Beehive) e.getBlockData()).setHoneyLevel(5);
}

The output from plugin (debug message) is sent correctly - it shows values before modifying: image

But the honey level of the hive does not change, it increases as if its value is not changed. No errors in console. Are you sure that the new block state is mutable/effective?

maxcom1 avatar Mar 10 '24 16:03 maxcom1

It technically is, however the existing logic does not feed it back. you are passing the NMS one. @Machine-Maker given no other call seems to respect "mutating" the block data of entity block change event, what is the best way to process here?

I mean, tbf, we could just stick to cancel + set yourself.

lynxplay avatar Mar 12 '24 08:03 lynxplay

Sure, I understand - I was planning to change this to fire EntityChangeBlockEvent, just will look into it when I have some time :>

maxcom1 avatar Mar 16 '24 21:03 maxcom1

Done

maxcom1 avatar Mar 16 '24 22:03 maxcom1