--- a/net/minecraft/server/EntityPotion.java
+++ b/net/minecraft/server/EntityPotion.java
@@ -6,6 +6,12 @@
 import javax.annotation.Nullable;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
+// CraftBukkit start
+import java.util.HashMap;
+import java.util.Map;
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
+import org.bukkit.entity.LivingEntity;
+// CraftBukkit end
 
 public class EntityPotion extends EntityProjectile {
 
@@ -87,7 +93,7 @@
 
             if (flag) {
                 this.n();
-            } 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 {
@@ -124,6 +130,7 @@
     private void a(MovingObjectPosition movingobjectposition, List<MobEffect> list) {
         AxisAlignedBB axisalignedbb = this.getBoundingBox().grow(4.0D, 2.0D, 4.0D);
         List list1 = this.world.a(EntityLiving.class, axisalignedbb);
+        Map<LivingEntity, Double> affected = new HashMap<LivingEntity, Double>(); // CraftBukkit
 
         if (!list1.isEmpty()) {
             Iterator iterator = list1.iterator();
@@ -141,21 +148,46 @@
                             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
+            for (LivingEntity victim : event.getAffectedEntities()) {
+                if (!(victim instanceof CraftLivingEntity)) {
+                    continue;
+                }
 
-                        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()));
-                                }
-                            }
+                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.world.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);
+
+                        if (i > 20) {
+                            entityliving.addEffect(new MobEffect(mobeffectlist, i, mobeffect.getAmplifier(), mobeffect.isAmbient(), mobeffect.isShowParticles()));
                         }
                     }
                 }
@@ -167,6 +199,7 @@
     private void a(ItemStack itemstack, PotionRegistry potionregistry) {
         EntityAreaEffectCloud entityareaeffectcloud = new EntityAreaEffectCloud(this.world, this.locX, this.locY, this.locZ);
 
+        entityareaeffectcloud.projectileSource = this.projectileSource; // CraftBukkit
         entityareaeffectcloud.setSource(this.getShooter());
         entityareaeffectcloud.setRadius(3.0F);
         entityareaeffectcloud.setRadiusOnUse(-0.5F);
@@ -187,7 +220,14 @@
             entityareaeffectcloud.setColor(nbttagcompound.getInt("CustomPotionColor"));
         }
 
-        this.world.addEntity(entityareaeffectcloud);
+        // CraftBukkit start
+        org.bukkit.event.entity.LingeringPotionSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callLingeringPotionSplashEvent(this, entityareaeffectcloud);
+        if (!(event.isCancelled() || entityareaeffectcloud.dead)) {
+            this.world.addEntity(entityareaeffectcloud);
+        } else {
+            entityareaeffectcloud.dead = true;
+        }
+        // CraftBukkit end
     }
 
     public boolean isLingering() {