--- a/net/minecraft/world/entity/AreaEffectCloud.java
+++ b/net/minecraft/world/entity/AreaEffectCloud.java
@@ -49,19 +_,19 @@
     private static final int DEFAULT_WAIT_TIME = 20;
     private static final int DEFAULT_REAPPLICATION_DELAY = 20;
     private static final ColorParticleOption DEFAULT_PARTICLE = ColorParticleOption.create(ParticleTypes.ENTITY_EFFECT, -1);
-    private PotionContents potionContents = PotionContents.EMPTY;
+    public PotionContents potionContents = PotionContents.EMPTY;
     private float potionDurationScale = 1.0F;
     private final Map<Entity, Integer> victims = Maps.newHashMap();
     private int duration = -1;
-    private int waitTime = 20;
-    private int reapplicationDelay = 20;
-    private int durationOnUse = 0;
-    private float radiusOnUse = 0.0F;
-    private float radiusPerTick = 0.0F;
-    @Nullable
-    private LivingEntity owner;
-    @Nullable
-    private UUID ownerUUID;
+    public int waitTime = 20;
+    public int reapplicationDelay = 20;
+    public int durationOnUse = 0;
+    public float radiusOnUse = 0.0F;
+    public float radiusPerTick = 0.0F;
+    @Nullable
+    private net.minecraft.world.entity.LivingEntity owner;
+    @Nullable
+    public UUID ownerUUID;
 
     public AreaEffectCloud(EntityType<? extends AreaEffectCloud> entityType, Level level) {
         super(entityType, level);
@@ -108,7 +_,7 @@
         this.potionDurationScale = potionDurationScale;
     }
 
-    private void updateColor() {
+    public void updateColor() {
         ParticleOptions particleOptions = this.entityData.get(DATA_PARTICLE);
         if (particleOptions instanceof ColorParticleOption colorParticleOption) {
             int i = this.potionContents.equals(PotionContents.EMPTY) ? 0 : this.potionContents.getColor();
@@ -144,6 +_,16 @@
         this.duration = duration;
     }
 
+    // Paper start - EAR 2
+    @Override
+    public void inactiveTick() {
+        super.inactiveTick();
+        if (this.tickCount >= this.waitTime + this.duration) {
+            this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
+        }
+    }
+    // Paper end - EAR 2
+
     @Override
     public void tick() {
         super.tick();
@@ -193,7 +_,7 @@
 
     private void serverTick(ServerLevel level) {
         if (this.duration != -1 && this.tickCount >= this.waitTime + this.duration) {
-            this.discard();
+            this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
         } else {
             boolean isWaiting = this.isWaiting();
             boolean flag = this.tickCount < this.waitTime;
@@ -206,7 +_,7 @@
                 if (this.radiusPerTick != 0.0F) {
                     radius += this.radiusPerTick;
                     if (radius < 0.5F) {
-                        this.discard();
+                        this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
                         return;
                     }
 
@@ -222,6 +_,7 @@
                         this.potionContents.forEachEffect(list::add, this.potionDurationScale);
                         List<LivingEntity> entitiesOfClass = this.level().getEntitiesOfClass(LivingEntity.class, this.getBoundingBox());
                         if (!entitiesOfClass.isEmpty()) {
+                            List<org.bukkit.entity.LivingEntity> entities = new java.util.ArrayList<>(); // CraftBukkit
                             for (LivingEntity livingEntity : entitiesOfClass) {
                                 if (!this.victims.containsKey(livingEntity)
                                     && livingEntity.isAffectedByPotions()
@@ -230,6 +_,17 @@
                                     double d1 = livingEntity.getZ() - this.getZ();
                                     double d2 = d * d + d1 * d1;
                                     if (d2 <= radius * radius) {
+                                        // CraftBukkit start
+                                        entities.add((org.bukkit.entity.LivingEntity) livingEntity.getBukkitEntity());
+                                    }
+                                }
+                            }
+                            org.bukkit.event.entity.AreaEffectCloudApplyEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callAreaEffectCloudApplyEvent(this, entities);
+                            if (!event.isCancelled()) {
+                                for (org.bukkit.entity.LivingEntity entity : event.getAffectedEntities()) {
+                                    if (entity instanceof org.bukkit.craftbukkit.entity.CraftLivingEntity) {
+                                        net.minecraft.world.entity.LivingEntity livingEntity = ((org.bukkit.craftbukkit.entity.CraftLivingEntity) entity).getHandle();
+                                        // CraftBukkit end
                                         this.victims.put(livingEntity, this.tickCount + this.reapplicationDelay);
 
                                         for (MobEffectInstance mobEffectInstance : list) {
@@ -238,14 +_,14 @@
                                                     .value()
                                                     .applyInstantenousEffect(level, this, this.getOwner(), livingEntity, mobEffectInstance.getAmplifier(), 0.5);
                                             } else {
-                                                livingEntity.addEffect(new MobEffectInstance(mobEffectInstance), this);
+                                                livingEntity.addEffect(new MobEffectInstance(mobEffectInstance), this, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.AREA_EFFECT_CLOUD); // CraftBukkit
                                             }
                                         }
 
                                         if (this.radiusOnUse != 0.0F) {
                                             radius += this.radiusOnUse;
                                             if (radius < 0.5F) {
-                                                this.discard();
+                                                this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
                                                 return;
                                             }
 
@@ -255,7 +_,7 @@
                                         if (this.durationOnUse != 0 && this.duration != -1) {
                                             this.duration = this.duration + this.durationOnUse;
                                             if (this.duration <= 0) {
-                                                this.discard();
+                                                this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
                                                 return;
                                             }
                                         }
