--- a/net/minecraft/world/entity/vehicle/VehicleEntity.java
+++ b/net/minecraft/world/entity/vehicle/VehicleEntity.java
@@ -14,7 +14,15 @@
 import net.minecraft.world.level.Level;
 import net.minecraft.world.level.gameevent.GameEvent;
 
+// CraftBukkit start
+import org.bukkit.entity.Vehicle;
+import org.bukkit.event.entity.EntityRemoveEvent;
+import org.bukkit.event.vehicle.VehicleDamageEvent;
+import org.bukkit.event.vehicle.VehicleDestroyEvent;
+// CraftBukkit end
+
 public abstract class VehicleEntity extends Entity {
+
     protected static final EntityDataAccessor<Integer> DATA_ID_HURT = SynchedEntityData.defineId(VehicleEntity.class, EntityDataSerializers.INT);
     protected static final EntityDataAccessor<Integer> DATA_ID_HURTDIR = SynchedEntityData.defineId(VehicleEntity.class, EntityDataSerializers.INT);
     protected static final EntityDataAccessor<Float> DATA_ID_DAMAGE = SynchedEntityData.defineId(VehicleEntity.class, EntityDataSerializers.FLOAT);
@@ -25,25 +33,58 @@
 
     @Override
     public boolean hurt(DamageSource source, float amount) {
-        if (this.level().isClientSide || this.isRemoved()) {
-            return true;
-        } else if (this.isInvulnerableTo(source)) {
-            return false;
-        } else {
-            this.setHurtDir(-this.getHurtDir());
-            this.setHurtTime(10);
-            this.markHurt();
-            this.setDamage(this.getDamage() + amount * 10.0F);
-            this.gameEvent(GameEvent.ENTITY_DAMAGE, source.getEntity());
-            boolean bl = source.getEntity() instanceof Player && ((Player)source.getEntity()).getAbilities().instabuild;
-            if ((bl || !(this.getDamage() > 40.0F)) && !this.shouldSourceDestroy(source)) {
-                if (bl) {
-                    this.discard();
-                }
+        if (!this.level().isClientSide && !this.isRemoved()) {
+            if (this.isInvulnerableTo(source)) {
+                return false;
             } else {
-                this.destroy(source);
-            }
+                // CraftBukkit start
+                Vehicle vehicle = (Vehicle) this.getBukkitEntity();
+                org.bukkit.entity.Entity attacker = (source.getEntity() == null) ? null : source.getEntity().getBukkitEntity();
+
+                VehicleDamageEvent event = new VehicleDamageEvent(vehicle, attacker, (double) amount);
+                this.level().getCraftServer().getPluginManager().callEvent(event);
+
+                if (event.isCancelled()) {
+                    return false;
+                }
+                amount = (float) event.getDamage();
+                // CraftBukkit end
+                this.setHurtDir(-this.getHurtDir());
+                this.setHurtTime(10);
+                this.markHurt();
+                this.setDamage(this.getDamage() + amount * 10.0F);
+                this.gameEvent(GameEvent.ENTITY_DAMAGE, source.getEntity());
+                boolean flag = source.getEntity() instanceof Player && ((Player) source.getEntity()).getAbilities().instabuild;
+
+                if ((flag || this.getDamage() <= 40.0F) && !this.shouldSourceDestroy(source)) {
+                    if (flag) {
+                        // CraftBukkit start
+                        VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, attacker);
+                        this.level().getCraftServer().getPluginManager().callEvent(destroyEvent);
 
+                        if (destroyEvent.isCancelled()) {
+                            this.setDamage(40.0F); // Maximize damage so this doesn't get triggered again right away
+                            return true;
+                        }
+                        // CraftBukkit end
+                        this.discard(EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause
+                    }
+                } else {
+                    // CraftBukkit start
+                    VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, attacker);
+                    this.level().getCraftServer().getPluginManager().callEvent(destroyEvent);
+
+                    if (destroyEvent.isCancelled()) {
+                        this.setDamage(40.0F); // Maximize damage so this doesn't get triggered again right away
+                        return true;
+                    }
+                    // CraftBukkit end
+                    this.destroy(source);
+                }
+
+                return true;
+            }
+        } else {
             return true;
         }
     }
@@ -55,41 +96,42 @@
     public void destroy(Item selfAsItem) {
         this.kill();
         if (this.level().getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) {
-            ItemStack itemStack = new ItemStack(selfAsItem);
-            itemStack.set(DataComponents.CUSTOM_NAME, this.getCustomName());
-            this.spawnAtLocation(itemStack);
+            ItemStack itemstack = new ItemStack(selfAsItem);
+
+            itemstack.set(DataComponents.CUSTOM_NAME, this.getCustomName());
+            this.spawnAtLocation(itemstack);
         }
     }
 
     @Override
     protected void defineSynchedData(SynchedEntityData.Builder builder) {
-        builder.define(DATA_ID_HURT, 0);
-        builder.define(DATA_ID_HURTDIR, 1);
-        builder.define(DATA_ID_DAMAGE, 0.0F);
+        builder.define(VehicleEntity.DATA_ID_HURT, 0);
+        builder.define(VehicleEntity.DATA_ID_HURTDIR, 1);
+        builder.define(VehicleEntity.DATA_ID_DAMAGE, 0.0F);
     }
 
     public void setHurtTime(int damageWobbleTicks) {
-        this.entityData.set(DATA_ID_HURT, damageWobbleTicks);
+        this.entityData.set(VehicleEntity.DATA_ID_HURT, damageWobbleTicks);
     }
 
     public void setHurtDir(int damageWobbleSide) {
-        this.entityData.set(DATA_ID_HURTDIR, damageWobbleSide);
+        this.entityData.set(VehicleEntity.DATA_ID_HURTDIR, damageWobbleSide);
     }
 
     public void setDamage(float damageWobbleStrength) {
-        this.entityData.set(DATA_ID_DAMAGE, damageWobbleStrength);
+        this.entityData.set(VehicleEntity.DATA_ID_DAMAGE, damageWobbleStrength);
     }
 
     public float getDamage() {
-        return this.entityData.get(DATA_ID_DAMAGE);
+        return (Float) this.entityData.get(VehicleEntity.DATA_ID_DAMAGE);
     }
 
     public int getHurtTime() {
-        return this.entityData.get(DATA_ID_HURT);
+        return (Integer) this.entityData.get(VehicleEntity.DATA_ID_HURT);
     }
 
     public int getHurtDir() {
-        return this.entityData.get(DATA_ID_HURTDIR);
+        return (Integer) this.entityData.get(VehicleEntity.DATA_ID_HURTDIR);
     }
 
     protected void destroy(DamageSource source) {
