--- a/net/minecraft/world/level/chunk/ChunkGenerator.java
+++ b/net/minecraft/world/level/chunk/ChunkGenerator.java
@@ -312,7 +312,7 @@
         }
     }
 
-    public void applyBiomeDecoration(GeneratorAccessSeed generatoraccessseed, IChunkAccess ichunkaccess, StructureManager structuremanager) {
+    public void addVanillaDecorations(GeneratorAccessSeed generatoraccessseed, IChunkAccess ichunkaccess, StructureManager structuremanager) { // CraftBukkit
         ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos();
 
         if (!SharedConstants.debugVoidTerrain(chunkcoordintpair)) {
@@ -334,7 +334,7 @@
 
                 for (int k = 0; k < j; ++k) {
                     ChunkSection chunksection = achunksection[k];
-                    PalettedContainerRO palettedcontainerro = chunksection.getBiomes();
+                    PalettedContainerRO<Holder<BiomeBase>> palettedcontainerro = chunksection.getBiomes(); // CraftBukkit - decompile error
 
                     Objects.requireNonNull(set);
                     palettedcontainerro.getAll(set::add);
@@ -445,6 +445,33 @@
         }
     }
 
+   // CraftBukkit start
+    public void applyBiomeDecoration(GeneratorAccessSeed generatoraccessseed, IChunkAccess ichunkaccess, StructureManager structuremanager) {
+        applyBiomeDecoration(generatoraccessseed, ichunkaccess, structuremanager, true);
+    }
+
+    public void applyBiomeDecoration(GeneratorAccessSeed generatoraccessseed, IChunkAccess ichunkaccess, StructureManager structuremanager, boolean vanilla) {
+        if (vanilla) {
+            addVanillaDecorations(generatoraccessseed, ichunkaccess, structuremanager);
+        }
+
+        org.bukkit.World world = generatoraccessseed.getMinecraftWorld().getWorld();
+        // only call when a populator is present (prevents unnecessary entity conversion)
+        if (!world.getPopulators().isEmpty()) {
+            org.bukkit.craftbukkit.generator.CraftLimitedRegion limitedRegion = new org.bukkit.craftbukkit.generator.CraftLimitedRegion(generatoraccessseed, ichunkaccess.getPos());
+            int x = ichunkaccess.getPos().x;
+            int z = ichunkaccess.getPos().z;
+            for (org.bukkit.generator.BlockPopulator populator : world.getPopulators()) {
+                SeededRandom seededrandom = new SeededRandom(new net.minecraft.world.level.levelgen.LegacyRandomSource(generatoraccessseed.getSeed()));
+                seededrandom.setDecorationSeed(generatoraccessseed.getSeed(), x, z);
+                populator.populate(world, new org.bukkit.craftbukkit.util.RandomSourceWrapper.RandomWrapper(seededrandom), x, z, limitedRegion);
+            }
+            limitedRegion.saveEntities();
+            limitedRegion.breakLink();
+        }
+    }
+    // CraftBukkit end
+
     private static StructureBoundingBox getWritableArea(IChunkAccess ichunkaccess) {
         ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos();
         int i = chunkcoordintpair.getMinBlockX();
@@ -582,6 +609,14 @@
         StructureStart structurestart = structure.generate(structureset_a.structure(), resourcekey, iregistrycustom, this, this.biomeSource, randomstate, structuretemplatemanager, i, chunkcoordintpair, j, ichunkaccess, predicate);
 
         if (structurestart.isValid()) {
+            // CraftBukkit start
+            StructureBoundingBox box = structurestart.getBoundingBox();
+            org.bukkit.event.world.AsyncStructureSpawnEvent event = new org.bukkit.event.world.AsyncStructureSpawnEvent(structuremanager.level.getMinecraftWorld().getWorld(), org.bukkit.craftbukkit.generator.structure.CraftStructure.minecraftToBukkit(structure), new org.bukkit.util.BoundingBox(box.minX(), box.minY(), box.minZ(), box.maxX(), box.maxY(), box.maxZ()), chunkcoordintpair.x, chunkcoordintpair.z);
+            org.bukkit.Bukkit.getPluginManager().callEvent(event);
+            if (event.isCancelled()) {
+                return true;
+            }
+            // CraftBukkit end
             structuremanager.setStartForStructure(sectionposition, structure, structurestart, ichunkaccess);
             return true;
         } else {
