From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Thu, 31 Aug 2023 10:23:06 +0200 Subject: [PATCH] PaperPR: Fix some beacon event issues Original license: GPLv3 Original project: https://github.com/PaperMC/Paper Paper pull request: https://github.com/PaperMC/Paper/pull/9674 Closes Paper#8947 Moves the deactivate event call into the onRemove method for the beacon block itself to prevent it from running when the block entity is unloaded. Also fixes an issue where the events were not being called when the beacon beam gets blocked. The field I added feels a bit wrong but it works, it's to prevent the activation event being called immediately after loading, can't see any better way to differentiate between a newly placed beacon and a newly loaded one. diff --git a/src/main/java/net/minecraft/world/level/block/BeaconBlock.java b/src/main/java/net/minecraft/world/level/block/BeaconBlock.java index debe8dbf1d5f3e58774903c5fcdcea672274ea61..413d6978d3acd441c90cdba6128bd35411048645 100644 --- a/src/main/java/net/minecraft/world/level/block/BeaconBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BeaconBlock.java @@ -57,4 +57,16 @@ public class BeaconBlock extends BaseEntityBlock implements BeaconBeamBlock { protected RenderShape getRenderShape(BlockState state) { return RenderShape.MODEL; } + + // Paper start - BeaconDeactivatedEvent + @Override + public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean moved) { + if (!state.is(newState.getBlock()) && world.getBlockEntity(pos) instanceof BeaconBlockEntity beacon && beacon.levels > 0 && !beacon.getBeamSections().isEmpty()) { + org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(world, pos); + new io.papermc.paper.event.block.BeaconDeactivatedEvent(block).callEvent(); + } + + super.onRemove(state, world, pos, newState, moved); + } + // Paper end } diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java index 2d190b3a6378b8cbadfa65510df1ccfbd5882ef8..f2f5ef254e21134bf85f10d32541c9fbf883042f 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java @@ -122,6 +122,8 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name return BeaconBlockEntity.VALID_EFFECTS.contains(effect) ? effect : null; } + public boolean justLoadedAndPreviouslyActive; // Paper - consider beacon previously active for first tick to skip activate event/sound + public BeaconBlockEntity(BlockPos pos, BlockState state) { super(BlockEntityType.BEACON, pos, state); this.lockKey = LockCode.NO_LOCK; @@ -240,10 +242,15 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name } } // Paper start - beacon activation/deactivation events - if (i1 <= 0 && blockEntity.levels > 0) { + // Paper start + final boolean prevActive = i1 > 0 && (!blockEntity.beamSections.isEmpty() || (blockEntity.justLoadedAndPreviouslyActive && !blockEntity.checkingBeamSections.isEmpty())); + blockEntity.justLoadedAndPreviouslyActive = false; + final boolean newActive = blockEntity.levels > 0 && !blockEntity.checkingBeamSections.isEmpty(); + if (!prevActive && newActive) { + // Paper end org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(world, pos); new io.papermc.paper.event.block.BeaconActivatedEvent(block).callEvent(); - } else if (i1 > 0 && blockEntity.levels <= 0) { + } else if (prevActive && !newActive) { // Paper org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(world, pos); new io.papermc.paper.event.block.BeaconDeactivatedEvent(block).callEvent(); } @@ -251,11 +258,11 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name if (blockEntity.lastCheckY >= l) { blockEntity.lastCheckY = world.getMinY() - 1; - boolean flag = i1 > 0; + boolean flag = prevActive; // Paper - Fix MC-183981 blockEntity.beamSections = blockEntity.checkingBeamSections; if (!world.isClientSide) { - boolean flag1 = blockEntity.levels > 0; + boolean flag1 = newActive; // Paper - Fix MC-183981 if (!flag && flag1) { BeaconBlockEntity.playSound(world, pos, SoundEvents.BEACON_ACTIVATE); @@ -305,10 +312,6 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name @Override public void setRemoved() { - // Paper start - beacon activation/deactivation events - org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(level, worldPosition); - new io.papermc.paper.event.block.BeaconDeactivatedEvent(block).callEvent(); - // Paper end - beacon activation/deactivation events // Paper start - fix MC-153086 if (this.levels > 0 && !this.beamSections.isEmpty()) { BeaconBlockEntity.playSound(this.level, this.worldPosition, SoundEvents.BEACON_DEACTIVATE); @@ -466,6 +469,7 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name this.primaryPower = BeaconBlockEntity.loadEffect(nbt, "primary_effect"); this.secondaryPower = BeaconBlockEntity.loadEffect(nbt, "secondary_effect"); this.levels = nbt.getInt("Levels"); // CraftBukkit - SPIGOT-5053, use where available + this.justLoadedAndPreviouslyActive = this.levels > 0; // Paper if (nbt.contains("CustomName", 8)) { this.name = parseCustomNameSafe(nbt.getString("CustomName"), registries); }