--- a/net/minecraft/world/inventory/BeaconMenu.java
+++ b/net/minecraft/world/inventory/BeaconMenu.java
@@ -22,20 +_,14 @@
     private static final int USE_ROW_SLOT_START = 28;
     private static final int USE_ROW_SLOT_END = 37;
     private static final int NO_EFFECT = 0;
-    private final Container beacon = new SimpleContainer(1) {
-        @Override
-        public boolean canPlaceItem(int slot, ItemStack stack) {
-            return stack.is(ItemTags.BEACON_PAYMENT_ITEMS);
-        }
-
-        @Override
-        public int getMaxStackSize() {
-            return 1;
-        }
-    };
-    private final BeaconMenu.PaymentSlot paymentSlot;
+    private final Container beacon; // Paper - Add missing InventoryHolders Move down
+    private final PaymentSlot paymentSlot;
     private final ContainerLevelAccess access;
     private final ContainerData beaconData;
+    // CraftBukkit start
+    private @Nullable org.bukkit.craftbukkit.inventory.view.CraftBeaconView view = null;
+    private final net.minecraft.world.entity.player.Inventory inventory;
+    // CraftBukkit end
 
     public BeaconMenu(int containerId, Container container) {
         this(containerId, container, new SimpleContainerData(3), ContainerLevelAccess.NULL);
@@ -43,6 +_,25 @@
 
     public BeaconMenu(int containerId, Container container, ContainerData beaconData, ContainerLevelAccess access) {
         super(MenuType.BEACON, containerId);
+        this.inventory = (net.minecraft.world.entity.player.Inventory) container; // CraftBukkit - TODO: check this
+        // Paper - Add missing InventoryHolders
+        this.beacon = new SimpleContainer(this.createBlockHolder(access), 1) {
+            @Override
+            public boolean canPlaceItem(int slot, ItemStack stack) {
+                return stack.is(ItemTags.BEACON_PAYMENT_ITEMS);
+            }
+
+            @Override
+            public int getMaxStackSize() {
+                return 1;
+            }
+
+            @Override
+            public org.bukkit.Location getLocation() {
+                return access.getLocation();
+            }
+        };
+        // Paper end
         checkContainerDataCount(beaconData, 3);
         this.beaconData = beaconData;
         this.access = access;
@@ -65,6 +_,7 @@
 
     @Override
     public boolean stillValid(Player player) {
+        if (!this.checkReachable) return true; // CraftBukkit
         return stillValid(this.access, player, Blocks.BEACON);
     }
 
@@ -141,13 +_,30 @@
     public Holder<MobEffect> getSecondaryEffect() {
         return decodeEffect(this.beaconData.get(2));
     }
+    // Paper start - Add PlayerChangeBeaconEffectEvent
+    private static @Nullable org.bukkit.potion.PotionEffectType convert(Optional<Holder<MobEffect>> optionalEffect) {
+        return optionalEffect.map(org.bukkit.craftbukkit.potion.CraftPotionEffectType::minecraftHolderToBukkit).orElse(null);
+    }
+    // Paper end - Add PlayerChangeBeaconEffectEvent
 
     public void updateEffects(Optional<Holder<MobEffect>> primaryEffect, Optional<Holder<MobEffect>> secondaryEffect) {
+        // Paper start - fix MC-174630 - validate secondary power
+        if (secondaryEffect.isPresent() && secondaryEffect.get() != net.minecraft.world.effect.MobEffects.REGENERATION && (primaryEffect.isPresent() && secondaryEffect.get() != primaryEffect.get())) {
+            secondaryEffect = Optional.empty();
+        }
+        // Paper end
         if (this.paymentSlot.hasItem()) {
-            this.beaconData.set(1, encodeEffect(primaryEffect.orElse(null)));
-            this.beaconData.set(2, encodeEffect(secondaryEffect.orElse(null)));
+            // Paper start - Add PlayerChangeBeaconEffectEvent
+            io.papermc.paper.event.player.PlayerChangeBeaconEffectEvent event = new io.papermc.paper.event.player.PlayerChangeBeaconEffectEvent((org.bukkit.entity.Player) this.inventory.player.getBukkitEntity(), convert(primaryEffect), convert(secondaryEffect), this.access.getLocation().getBlock());
+            if (event.callEvent()) {
+                // Paper end - Add PlayerChangeBeaconEffectEvent
+                this.beaconData.set(1, BeaconMenu.encodeEffect(event.getPrimary() == null ? null : org.bukkit.craftbukkit.potion.CraftPotionEffectType.bukkitToMinecraftHolder(event.getPrimary())));// CraftBukkit - decompile error
+                this.beaconData.set(2, BeaconMenu.encodeEffect(event.getSecondary() == null ? null : org.bukkit.craftbukkit.potion.CraftPotionEffectType.bukkitToMinecraftHolder(event.getSecondary())));// CraftBukkit - decompile error
+            if (event.willConsumeItem()) { // Paper
             this.paymentSlot.remove(1);
+            } // Paper
             this.access.execute(Level::blockEntityChanged);
+            } // Paper end - Add PlayerChangeBeaconEffectEvent
         }
     }
 
@@ -170,4 +_,17 @@
             return 1;
         }
     }
+
+    // CraftBukkit start
+    @Override
+    public org.bukkit.craftbukkit.inventory.view.CraftBeaconView getBukkitView() {
+        if (this.view != null) {
+            return this.view;
+        }
+
+        org.bukkit.craftbukkit.inventory.CraftInventoryBeacon inventory = new org.bukkit.craftbukkit.inventory.CraftInventoryBeacon(this.beacon);
+        this.view = new org.bukkit.craftbukkit.inventory.view.CraftBeaconView(this.inventory.player.getBukkitEntity(), inventory, this);
+        return this.view;
+    }
+    // CraftBukkit end
 }
