diff --git a/Spigot-API-Patches/add-DragonEggFormEvent.patch b/Spigot-API-Patches/add-DragonEggFormEvent.patch
new file mode 100644
index 0000000000..3df2fe335f
--- /dev/null
+++ b/Spigot-API-Patches/add-DragonEggFormEvent.patch
@@ -0,0 +1,75 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Trigary <trigary0@gmail.com>
+Date: Mon, 25 Jan 2021 14:53:49 +0100
+Subject: [PATCH] add DragonEggFormEvent
+
+
+diff --git a/src/main/java/io/papermc/paper/event/block/DragonEggFormEvent.java b/src/main/java/io/papermc/paper/event/block/DragonEggFormEvent.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/event/block/DragonEggFormEvent.java
+@@ -0,0 +0,0 @@
++package io.papermc.paper.event.block;
++
++import org.bukkit.Material;
++import org.bukkit.block.Block;
++import org.bukkit.block.BlockState;
++import org.bukkit.boss.DragonBattle;
++import org.bukkit.entity.EnderDragon;
++import org.bukkit.event.Cancellable;
++import org.bukkit.event.HandlerList;
++import org.bukkit.event.block.BlockFormEvent;
++import org.jetbrains.annotations.NotNull;
++
++/**
++ * Called when the {@link EnderDragon} is defeated (killed) in a {@link DragonBattle},
++ * causing a {@link Material#DRAGON_EGG} (more formally: {@link #getNewState()})
++ * to possibly appear depending on {@link #isCancelled()}.
++ * <b>This event might be cancelled by default depending on
++ * eg. {@link DragonBattle#hasBeenPreviouslyKilled()} and server configuration.</b>
++ */
++public class DragonEggFormEvent extends BlockFormEvent implements Cancellable {
++	private static final HandlerList handlers = new HandlerList();
++	private final DragonBattle dragonBattle;
++	private boolean cancelled;
++	
++	public DragonEggFormEvent(@NotNull Block block, @NotNull BlockState newState,
++			@NotNull DragonBattle dragonBattle) {
++		super(block, newState);
++		this.dragonBattle = dragonBattle;
++	}
++	
++	@Override
++	public boolean isCancelled() {
++		return cancelled;
++	}
++	
++	@Override
++	public void setCancelled(boolean cancelled) {
++		this.cancelled = cancelled;
++	}
++	
++	/**
++	 * Gets the {@link DragonBattle} associated with this event.
++	 * Keep in mind that the {@link EnderDragon} is already dead
++	 * when this event is called.
++	 *
++	 * @return the dragon battle
++	 */
++	@NotNull
++	public DragonBattle getDragonBattle() {
++		return dragonBattle;
++	}
++	
++	@NotNull
++	@Override
++	public HandlerList getHandlers() {
++		return handlers;
++	}
++	
++	@NotNull
++	public static HandlerList getHandlerList() {
++		return handlers;
++	}
++}
diff --git a/Spigot-Server-Patches/add-DragonEggFormEvent.patch b/Spigot-Server-Patches/add-DragonEggFormEvent.patch
new file mode 100644
index 0000000000..6f396406c5
--- /dev/null
+++ b/Spigot-Server-Patches/add-DragonEggFormEvent.patch
@@ -0,0 +1,66 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Trigary <trigary0@gmail.com>
+Date: Mon, 25 Jan 2021 14:53:57 +0100
+Subject: [PATCH] add DragonEggFormEvent
+
+
+diff --git a/src/main/java/net/minecraft/server/EnderDragonBattle.java b/src/main/java/net/minecraft/server/EnderDragonBattle.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/server/EnderDragonBattle.java
++++ b/src/main/java/net/minecraft/server/EnderDragonBattle.java
+@@ -0,0 +0,0 @@ import java.util.function.Predicate;
+ import javax.annotation.Nullable;
+ import org.apache.logging.log4j.LogManager;
+ import org.apache.logging.log4j.Logger;
++import io.papermc.paper.event.block.DragonEggFormEvent; // Paper - DragonEggFormEvent
+ 
+ public class EnderDragonBattle {
+ 
+@@ -0,0 +0,0 @@ public class EnderDragonBattle {
+             this.bossBattle.setVisible(false);
+             this.generateExitPortal(true);
+             this.n();
++            // Paper start - DragonEggFormEvent
++            BlockPosition eggPosition = this.world.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, WorldGenEndTrophy.getPosition());
++            org.bukkit.craftbukkit.block.CraftBlock eggBlock = org.bukkit.craftbukkit.block.CraftBlock.at(this.world, eggPosition);
++            org.bukkit.craftbukkit.block.CraftBlockState eggState = new org.bukkit.craftbukkit.block.CraftBlockState(eggBlock);
++            eggState.setData(Blocks.DRAGON_EGG.getBlockData());
++            DragonEggFormEvent eggEvent = new DragonEggFormEvent(eggBlock, eggState,
++                    new org.bukkit.craftbukkit.boss.CraftDragonBattle(this));
++            // Paper end - DragonEggFormEvent
+             if (this.world.paperConfig.enderDragonsDeathAlwaysPlacesDragonEgg || !this.previouslyKilled) { // Paper - always place dragon egg
+-                this.world.setTypeUpdate(this.world.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, WorldGenEndTrophy.a), Blocks.DRAGON_EGG.getBlockData());
++                // Paper start - DragonEggFormEvent
++                //this.world.setTypeUpdate(this.world.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, WorldGenEndTrophy.a), Blocks.DRAGON_EGG.getBlockData());
++            } else {
++                eggEvent.setCancelled(true);
++            }
++            if (eggEvent.callEvent()) {
++                eggEvent.getNewState().update(true);
+             }
++            // Paper end - DragonEggFormEvent
+ 
+             this.previouslyKilled = true;
+             this.dragonKilled = true;
+diff --git a/src/main/java/net/minecraft/server/WorldGenEndTrophy.java b/src/main/java/net/minecraft/server/WorldGenEndTrophy.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/server/WorldGenEndTrophy.java
++++ b/src/main/java/net/minecraft/server/WorldGenEndTrophy.java
+@@ -0,0 +0,0 @@ import java.util.Random;
+ 
+ public class WorldGenEndTrophy extends WorldGenerator<WorldGenFeatureEmptyConfiguration> {
+ 
+-    public static final BlockPosition a = BlockPosition.ZERO;
++    public static final BlockPosition a = BlockPosition.ZERO; public static BlockPosition getPosition() { return a; } // Paper - OBFHELPER
+     private final boolean ab;
+ 
+     public WorldGenEndTrophy(boolean flag) {
+@@ -0,0 +0,0 @@ public class WorldGenEndTrophy extends WorldGenerator<WorldGenFeatureEmptyConfig
+         this.ab = flag;
+     }
+ 
+-    public boolean a(GeneratorAccessSeed generatoraccessseed, ChunkGenerator chunkgenerator, Random random, BlockPosition blockposition, WorldGenFeatureEmptyConfiguration worldgenfeatureemptyconfiguration) {
++    public boolean generate(GeneratorAccessSeed generatoraccessseed, ChunkGenerator chunkgenerator, Random random, BlockPosition blockposition, WorldGenFeatureEmptyConfiguration worldgenfeatureemptyconfiguration) { // Paper - decompile fix
+         Iterator iterator = BlockPosition.a(new BlockPosition(blockposition.getX() - 4, blockposition.getY() - 1, blockposition.getZ() - 4), new BlockPosition(blockposition.getX() + 4, blockposition.getY() + 32, blockposition.getZ() + 4)).iterator();
+ 
+         while (iterator.hasNext()) {