--- a/net/minecraft/world/entity/projectile/EntityPotion.java
+++ b/net/minecraft/world/entity/projectile/EntityPotion.java
@@ -34,6 +34,16 @@
 import net.minecraft.world.phys.MovingObjectPositionBlock;
 import net.minecraft.world.phys.MovingObjectPositionEntity;
 
+// CraftBukkit start
+import java.util.HashMap;
+import java.util.Map;
+import net.minecraft.server.level.EntityPlayer;
+import net.minecraft.world.level.block.Blocks;
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.entity.LivingEntity;
+// CraftBukkit end
+
 public class EntityPotion extends EntityProjectileThrowable implements ItemSupplier {
 
     public static final double SPLASH_RANGE = 4.0D;
@@ -100,7 +110,7 @@
 
             if (flag) {
                 this.splash();
-            } else if (!list.isEmpty()) {
+            } else if (true || !list.isEmpty()) { // CraftBukkit - Call event even if no effects to apply
                 if (this.isLingering()) {
                     this.a(itemstack, potionregistry);
                 } else {
@@ -146,6 +156,7 @@
     private void a(List<MobEffect> list, @Nullable Entity entity) {
         AxisAlignedBB axisalignedbb = this.getBoundingBox().grow(4.0D, 2.0D, 4.0D);
         List<EntityLiving> list1 = this.level.a(EntityLiving.class, axisalignedbb);
+        Map<LivingEntity, Double> affected = new HashMap<LivingEntity, Double>(); // CraftBukkit
 
         if (!list1.isEmpty()) {
             Entity entity1 = this.x();
@@ -164,21 +175,47 @@
                             d1 = 1.0D;
                         }
 
-                        Iterator iterator1 = list.iterator();
+                        // CraftBukkit start
+                        affected.put((LivingEntity) entityliving.getBukkitEntity(), d1);
+                    }
+                }
+            }
+        }
+
+        org.bukkit.event.entity.PotionSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPotionSplashEvent(this, affected);
+        if (!event.isCancelled() && list != null && !list.isEmpty()) { // do not process effects if there are no effects to process
+            Entity entity1 = this.x();
+            for (LivingEntity victim : event.getAffectedEntities()) {
+                if (!(victim instanceof CraftLivingEntity)) {
+                    continue;
+                }
+
+                EntityLiving entityliving = ((CraftLivingEntity) victim).getHandle();
+                double d1 = event.getIntensity(victim);
+                // CraftBukkit end
+
+                Iterator iterator1 = list.iterator();
+
+                while (iterator1.hasNext()) {
+                    MobEffect mobeffect = (MobEffect) iterator1.next();
+                    MobEffectList mobeffectlist = mobeffect.getMobEffect();
+                    // CraftBukkit start - Abide by PVP settings - for players only!
+                    if (!this.level.pvpMode && this.getShooter() instanceof EntityPlayer && entityliving instanceof EntityPlayer && entityliving != this.getShooter()) {
+                        int i = MobEffectList.getId(mobeffectlist);
+                        // Block SLOWER_MOVEMENT, SLOWER_DIG, HARM, BLINDNESS, HUNGER, WEAKNESS and POISON potions
+                        if (i == 2 || i == 4 || i == 7 || i == 15 || i == 17 || i == 18 || i == 19) {
+                            continue;
+                        }
+                    }
+                    // CraftBukkit end
+
+                    if (mobeffectlist.isInstant()) {
+                        mobeffectlist.applyInstantEffect(this, this.getShooter(), entityliving, mobeffect.getAmplifier(), d1);
+                    } else {
+                        int i = (int) (d1 * (double) mobeffect.getDuration() + 0.5D);
 
-                        while (iterator1.hasNext()) {
-                            MobEffect mobeffect = (MobEffect) iterator1.next();
-                            MobEffectList mobeffectlist = mobeffect.getMobEffect();
-
-                            if (mobeffectlist.isInstant()) {
-                                mobeffectlist.applyInstantEffect(this, this.getShooter(), entityliving, mobeffect.getAmplifier(), d1);
-                            } else {
-                                int i = (int) (d1 * (double) mobeffect.getDuration() + 0.5D);
-
-                                if (i > 20) {
-                                    entityliving.addEffect(new MobEffect(mobeffectlist, i, mobeffect.getAmplifier(), mobeffect.isAmbient(), mobeffect.isShowParticles()), entity1);
-                                }
-                            }
+                        if (i > 20) {
+                            entityliving.addEffect(new MobEffect(mobeffectlist, i, mobeffect.getAmplifier(), mobeffect.isAmbient(), mobeffect.isShowParticles()), entity1, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.POTION_SPLASH); // CraftBukkit
                         }
                     }
                 }
@@ -214,7 +251,14 @@
             entityareaeffectcloud.setColor(nbttagcompound.getInt("CustomPotionColor"));
         }
 
-        this.level.addEntity(entityareaeffectcloud);
+        // CraftBukkit start
+        org.bukkit.event.entity.LingeringPotionSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callLingeringPotionSplashEvent(this, entityareaeffectcloud);
+        if (!(event.isCancelled() || entityareaeffectcloud.isRemoved())) {
+            this.level.addEntity(entityareaeffectcloud);
+        } else {
+            entityareaeffectcloud.die();
+        }
+        // CraftBukkit end
     }
 
     public boolean isLingering() {
@@ -225,13 +269,25 @@
         IBlockData iblockdata = this.level.getType(blockposition);
 
         if (iblockdata.a((Tag) TagsBlock.FIRE)) {
-            this.level.a(blockposition, false);
+            // CraftBukkit start
+            if (!CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, Blocks.AIR.getBlockData()).isCancelled()) {
+                this.level.a(blockposition, false);
+            }
+            // CraftBukkit end
         } else if (AbstractCandleBlock.b(iblockdata)) {
-            AbstractCandleBlock.a((EntityHuman) null, iblockdata, (GeneratorAccess) this.level, blockposition);
+            // CraftBukkit start
+            if (!CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, iblockdata.set(AbstractCandleBlock.LIT, false)).isCancelled()) {
+                AbstractCandleBlock.a((EntityHuman) null, iblockdata, (GeneratorAccess) this.level, blockposition);
+            }
+            // CraftBukkit end
         } else if (BlockCampfire.g(iblockdata)) {
-            this.level.a((EntityHuman) null, 1009, blockposition, 0);
-            BlockCampfire.a(this.getShooter(), (GeneratorAccess) this.level, blockposition, iblockdata);
-            this.level.setTypeUpdate(blockposition, (IBlockData) iblockdata.set(BlockCampfire.LIT, false));
+            // CraftBukkit start
+            if (!CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, iblockdata.set(BlockCampfire.LIT, false)).isCancelled()) {
+                this.level.a((EntityHuman) null, 1009, blockposition, 0);
+                BlockCampfire.a(this.getShooter(), (GeneratorAccess) this.level, blockposition, iblockdata);
+                this.level.setTypeUpdate(blockposition, (IBlockData) iblockdata.set(BlockCampfire.LIT, false));
+            }
+            // CraftBukkit end
         }
 
     }
