--- a/net/minecraft/world/level/block/entity/vault/VaultBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/vault/VaultBlockEntity.java
@@ -46,6 +46,13 @@
 import net.minecraft.world.phys.Vec3D;
 import org.slf4j.Logger;
 
+// CraftBukkit start
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
+import org.bukkit.event.block.BlockDispenseLootEvent;
+import org.bukkit.event.block.VaultDisplayItemEvent;
+// CraftBukkit end
+
 public class VaultBlockEntity extends TileEntity {
 
     private static final Logger LOGGER = LogUtils.getLogger();
@@ -96,18 +103,18 @@
             dataresult = VaultServerData.CODEC.parse(dynamicops, nbttagcompound.get("server_data"));
             logger = VaultBlockEntity.LOGGER;
             Objects.requireNonNull(logger);
-            optional = dataresult.resultOrPartial(logger::error);
+            optional = ((DataResult<VaultServerData>) dataresult).resultOrPartial(logger::error); // CraftBukkit - decompile error
             VaultServerData vaultserverdata = this.serverData;
 
             Objects.requireNonNull(this.serverData);
-            optional.ifPresent(vaultserverdata::set);
+            ((Optional<VaultServerData>) optional).ifPresent(vaultserverdata::set); // CraftBukkit - decompile error
         }
 
         if (nbttagcompound.contains("config")) {
             dataresult = VaultConfig.CODEC.parse(dynamicops, nbttagcompound.get("config"));
             logger = VaultBlockEntity.LOGGER;
             Objects.requireNonNull(logger);
-            dataresult.resultOrPartial(logger::error).ifPresent((vaultconfig) -> {
+            ((DataResult<VaultConfig>) dataresult).resultOrPartial(logger::error).ifPresent((vaultconfig) -> { // CraftBukkit - decompile error
                 this.config = vaultconfig;
             });
         }
@@ -116,11 +123,11 @@
             dataresult = VaultSharedData.CODEC.parse(dynamicops, nbttagcompound.get("shared_data"));
             logger = VaultBlockEntity.LOGGER;
             Objects.requireNonNull(logger);
-            optional = dataresult.resultOrPartial(logger::error);
+            optional = ((DataResult<VaultSharedData>) dataresult).resultOrPartial(logger::error); // CraftBukkit - decompile error
             VaultSharedData vaultshareddata = this.sharedData;
 
             Objects.requireNonNull(this.sharedData);
-            optional.ifPresent(vaultshareddata::set);
+            ((Optional<VaultSharedData>) optional).ifPresent(vaultshareddata::set); // CraftBukkit - decompile error
         }
 
     }
@@ -320,6 +327,14 @@
                     if (!list.isEmpty()) {
                         entityhuman.awardStat(StatisticList.ITEM_USED.get(itemstack.getItem()));
                         itemstack.consume(vaultconfig.keyItem().getCount(), entityhuman);
+                        // CraftBukkit start
+                        BlockDispenseLootEvent vaultDispenseLootEvent = CraftEventFactory.callBlockDispenseLootEvent(worldserver, blockposition, entityhuman, list);
+                        if (vaultDispenseLootEvent.isCancelled()) {
+                            return;
+                        }
+
+                        list = vaultDispenseLootEvent.getDispensedLoot().stream().map(CraftItemStack::asNMSCopy).toList();
+                        // CraftBukkit end
                         unlock(worldserver, iblockdata, blockposition, vaultconfig, vaultserverdata, vaultshareddata, list);
                         vaultserverdata.addToRewardedPlayers(entityhuman);
                         vaultshareddata.updateConnectedPlayersWithinRange(worldserver, blockposition, vaultserverdata, vaultconfig, vaultconfig.deactivationRange());
@@ -341,6 +356,14 @@
                 vaultshareddata.setDisplayItem(ItemStack.EMPTY);
             } else {
                 ItemStack itemstack = getRandomDisplayItemFromLootTable(worldserver, blockposition, (ResourceKey) vaultconfig.overrideLootTableToDisplay().orElse(vaultconfig.lootTable()));
+                // CraftBukkit start
+                VaultDisplayItemEvent event = CraftEventFactory.callVaultDisplayItemEvent(worldserver, blockposition, itemstack);
+                if (event.isCancelled()) {
+                    return;
+                }
+
+                itemstack = CraftItemStack.asNMSCopy(event.getDisplayItem());
+                // CraftBukkit end
 
                 vaultshareddata.setDisplayItem(itemstack);
             }
