--- a/net/minecraft/world/level/block/TntBlock.java
+++ b/net/minecraft/world/level/block/TntBlock.java
@@ -45,7 +_,13 @@
     @Override
     protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean isMoving) {
         if (!oldState.is(state.getBlock())) {
-            if (level.hasNeighborSignal(pos)) {
+            if (level.hasNeighborSignal(pos) && org.bukkit.craftbukkit.event.CraftEventFactory.callTNTPrimeEvent(level, pos, org.bukkit.event.block.TNTPrimeEvent.PrimeCause.REDSTONE, null, null)) { // CraftBukkit - TNTPrimeEvent
+                // Paper start - TNTPrimeEvent
+                org.bukkit.block.Block tntBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos);
+                if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent()) {
+                    return;
+                }
+                // Paper end - TNTPrimeEvent
                 explode(level, pos);
                 level.removeBlock(pos, false);
             }
@@ -54,7 +_,13 @@
 
     @Override
     protected void neighborChanged(BlockState state, Level level, BlockPos pos, Block neighborBlock, @Nullable Orientation orientation, boolean movedByPiston) {
-        if (level.hasNeighborSignal(pos)) {
+        if (level.hasNeighborSignal(pos) && org.bukkit.craftbukkit.event.CraftEventFactory.callTNTPrimeEvent(level, pos, org.bukkit.event.block.TNTPrimeEvent.PrimeCause.REDSTONE, null, null)) { // CraftBukkit - TNTPrimeEvent
+            // Paper start - TNTPrimeEvent
+            org.bukkit.block.Block tntBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos);
+            if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent()) {
+                return;
+            }
+            // Paper end - TNTPrimeEvent
             explode(level, pos);
             level.removeBlock(pos, false);
         }
@@ -62,7 +_,7 @@
 
     @Override
     public BlockState playerWillDestroy(Level level, BlockPos pos, BlockState state, Player player) {
-        if (!level.isClientSide() && !player.isCreative() && state.getValue(UNSTABLE)) {
+        if (!level.isClientSide() && !player.isCreative() && state.getValue(UNSTABLE) && org.bukkit.craftbukkit.event.CraftEventFactory.callTNTPrimeEvent(level, pos, org.bukkit.event.block.TNTPrimeEvent.PrimeCause.BLOCK_BREAK, player, null)) { // CraftBukkit - TNTPrimeEvent
             explode(level, pos);
         }
 
@@ -71,6 +_,13 @@
 
     @Override
     public void wasExploded(ServerLevel level, BlockPos pos, Explosion explosion) {
+        // Paper start - TNTPrimeEvent
+        org.bukkit.block.Block tntBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos);
+        org.bukkit.entity.Entity source = explosion.getDirectSourceEntity() != null ? explosion.getDirectSourceEntity().getBukkitEntity() : null;
+        if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.EXPLOSION, source).callEvent()) {
+            return;
+        }
+        // Paper end - TNTPrimeEvent
         PrimedTnt primedTnt = new PrimedTnt(level, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, explosion.getIndirectSourceEntity());
         int fuse = primedTnt.getFuse();
         primedTnt.setFuse((short)(level.random.nextInt(fuse / 4) + fuse / 8));
@@ -97,6 +_,17 @@
         if (!stack.is(Items.FLINT_AND_STEEL) && !stack.is(Items.FIRE_CHARGE)) {
             return super.useItemOn(stack, state, level, pos, player, hand, hitResult);
         } else {
+            // CraftBukkit start - TNTPrimeEvent
+            if (!org.bukkit.craftbukkit.event.CraftEventFactory.callTNTPrimeEvent(level, pos, org.bukkit.event.block.TNTPrimeEvent.PrimeCause.PLAYER, player, null)) {
+                return InteractionResult.CONSUME;
+            }
+            // CraftBukkit end
+            // Paper start - TNTPrimeEvent
+            org.bukkit.block.Block tntBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos);
+            if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.ITEM, player.getBukkitEntity()).callEvent()) {
+                return InteractionResult.FAIL;
+            }
+            // Paper end - TNTPrimeEvent
             explode(level, pos, player);
             level.setBlock(pos, Blocks.AIR.defaultBlockState(), 11);
             Item item = stack.getItem();
@@ -117,6 +_,17 @@
             BlockPos blockPos = hit.getBlockPos();
             Entity owner = projectile.getOwner();
             if (projectile.isOnFire() && projectile.mayInteract(serverLevel, blockPos)) {
+                // CraftBukkit start
+                if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(projectile, blockPos, state.getFluidState().createLegacyBlock()) || !org.bukkit.craftbukkit.event.CraftEventFactory.callTNTPrimeEvent(level, blockPos, org.bukkit.event.block.TNTPrimeEvent.PrimeCause.PROJECTILE, projectile, null)) { // Paper - fix wrong block state
+                    return;
+                }
+                // CraftBukkit end
+                // Paper start - TNTPrimeEvent
+                org.bukkit.block.Block tntBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, blockPos);
+                if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.PROJECTILE, projectile.getBukkitEntity()).callEvent()) {
+                    return;
+                }
+                // Paper end - TNTPrimeEvent
                 explode(level, blockPos, owner instanceof LivingEntity ? (LivingEntity)owner : null);
                 level.removeBlock(blockPos, false);
             }
