SPIGOT-1638 / SPIGOT-1673: Rework Potions API

By: t00thpick1 <t00thpick1dirko@gmail.com>
This commit is contained in:
CraftBukkit/Spigot
2016-03-02 20:43:58 -05:00
parent d490a6e384
commit 104519f08f
20 changed files with 622 additions and 121 deletions

View File

@@ -2,13 +2,22 @@ package org.bukkit.craftbukkit.entity;
import java.util.List;
import net.minecraft.server.EntityAreaEffectCloud;
import net.minecraft.server.MobEffect;
import net.minecraft.server.MobEffectList;
import org.apache.commons.lang.Validate;
import org.bukkit.Color;
import org.bukkit.Particle;
import org.bukkit.craftbukkit.CraftParticle;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.potion.CraftPotionUtil;
import org.bukkit.entity.AreaEffectCloud;
import org.bukkit.entity.EntityType;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.potion.PotionData;
import com.google.common.collect.ImmutableList;
public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud {
@@ -106,26 +115,6 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud
getHandle().setParticle(CraftParticle.toNMS(particle));
}
@Override
public List<PotionEffect> getEffects() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void addEffect(PotionEffect effect) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void removeEffect(PotionEffect effect) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void setEffects(List<PotionEffect> effects) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public Color getColor() {
return Color.fromRGB(getHandle().getColor());
@@ -135,4 +124,82 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud
public void setColor(Color color) {
getHandle().setColor(color.asRGB());
}
@Override
public boolean addCustomEffect(PotionEffect effect, boolean override) {
int effectId = effect.getType().getId();
MobEffect existing = null;
for (MobEffect mobEffect : getHandle().effects) {
if (MobEffectList.getId(mobEffect.getMobEffect()) == effectId) {
existing = mobEffect;
}
}
if (existing != null) {
if (!override) {
return false;
}
getHandle().effects.remove(existing);
}
getHandle().a(CraftPotionUtil.fromBukkit(effect));
getHandle().refreshEffects();
return true;
}
@Override
public void clearCustomEffects() {
getHandle().effects.clear();
getHandle().refreshEffects();
}
@Override
public List<PotionEffect> getCustomEffects() {
ImmutableList.Builder<PotionEffect> builder = ImmutableList.builder();
for (MobEffect effect : getHandle().effects) {
builder.add(CraftPotionUtil.toBukkit(effect));
}
return builder.build();
}
@Override
public boolean hasCustomEffect(PotionEffectType type) {
for (MobEffect effect : getHandle().effects) {
if (CraftPotionUtil.equals(effect.getMobEffect(), type)) {
return true;
}
}
return false;
}
@Override
public boolean hasCustomEffects() {
return !getHandle().effects.isEmpty();
}
@Override
public boolean removeCustomEffect(PotionEffectType effect) {
int effectId = effect.getId();
MobEffect existing = null;
for (MobEffect mobEffect : getHandle().effects) {
if (MobEffectList.getId(mobEffect.getMobEffect()) == effectId) {
existing = mobEffect;
}
}
if (existing == null) {
return false;
}
getHandle().effects.remove(existing);
getHandle().refreshEffects();
return true;
}
@Override
public void setBasePotionData(PotionData data) {
Validate.notNull(data, "PotionData cannot be null");
getHandle().setType(CraftPotionUtil.fromBukkit(data));
}
@Override
public PotionData getBasePotionData() {
return CraftPotionUtil.toBukkit(getHandle().getType());
}
}

View File

@@ -138,12 +138,19 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
else { return new CraftComplexPart(server, (EntityComplexPart) entity); }
}
else if (entity instanceof EntityExperienceOrb) { return new CraftExperienceOrb(server, (EntityExperienceOrb) entity); }
else if (entity instanceof EntityTippedArrow) {
if (((EntityTippedArrow) entity).isTipped()) { return new CraftTippedArrow(server, (EntityTippedArrow) entity); }
else { return new CraftArrow(server, (EntityArrow) entity); }
}
else if (entity instanceof EntityArrow) { return new CraftArrow(server, (EntityArrow) entity); }
else if (entity instanceof EntityBoat) { return new CraftBoat(server, (EntityBoat) entity); }
else if (entity instanceof EntityProjectile) {
if (entity instanceof EntityEgg) { return new CraftEgg(server, (EntityEgg) entity); }
else if (entity instanceof EntitySnowball) { return new CraftSnowball(server, (EntitySnowball) entity); }
else if (entity instanceof EntityPotion) { return new CraftThrownPotion(server, (EntityPotion) entity); }
else if (entity instanceof EntityPotion) {
if (!((EntityPotion) entity).n()) { return new CraftSplashPotion(server, (EntityPotion) entity); }
else { return new CraftLingeringPotion(server, (EntityPotion) entity); }
}
else if (entity instanceof EntityEnderPearl) { return new CraftEnderPearl(server, (EntityEnderPearl) entity); }
else if (entity instanceof EntityThrownExpBottle) { return new CraftThrownExpBottle(server, (EntityThrownExpBottle) entity); }
}

View File

@@ -0,0 +1,41 @@
package org.bukkit.craftbukkit.entity;
import net.minecraft.server.EntityPotion;
import org.apache.commons.lang.Validate;
import org.bukkit.Material;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
public class CraftLingeringPotion extends CraftThrownPotion {
public CraftLingeringPotion(CraftServer server, EntityPotion entity) {
super(server, entity);
}
public void setItem(ItemStack item) {
// The ItemStack must not be null.
Validate.notNull(item, "ItemStack cannot be null.");
// The ItemStack must be a potion.
Validate.isTrue(item.getType() == Material.LINGERING_POTION, "ItemStack must be a lingering potion. This item stack was " + item.getType() + ".");
getHandle().setItem(CraftItemStack.asNMSCopy(item));
}
@Override
public EntityPotion getHandle() {
return (EntityPotion) entity;
}
@Override
public String toString() {
return "CraftLingeringPotion";
}
@Override
public EntityType getType() {
return EntityType.LINGERING_POTION;
}
}

View File

@@ -26,6 +26,7 @@ import net.minecraft.server.EntitySmallFireball;
import net.minecraft.server.EntitySnowball;
import net.minecraft.server.EntityThrownExpBottle;
import net.minecraft.server.EntityTippedArrow;
import net.minecraft.server.EntitySpectralArrow;
import net.minecraft.server.EntityWither;
import net.minecraft.server.EntityWitherSkull;
import net.minecraft.server.GenericAttributes;
@@ -42,6 +43,7 @@ import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.inventory.CraftEntityEquipment;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.craftbukkit.potion.CraftPotionUtil;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.DragonFireball;
import org.bukkit.entity.Egg;
@@ -51,19 +53,24 @@ import org.bukkit.entity.EntityType;
import org.bukkit.entity.Fireball;
import org.bukkit.entity.Fish;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.LingeringPotion;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.SmallFireball;
import org.bukkit.entity.Snowball;
import org.bukkit.entity.SpectralArrow;
import org.bukkit.entity.ThrownExpBottle;
import org.bukkit.entity.ThrownPotion;
import org.bukkit.entity.TippedArrow;
import org.bukkit.entity.WitherSkull;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionData;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.potion.PotionType;
import org.bukkit.util.BlockIterator;
import org.bukkit.util.NumberConversions;
import org.bukkit.util.Vector;
@@ -337,10 +344,21 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
launch = new EntityEnderPearl(world, getHandle());
((EntityProjectile) launch).a(getHandle(), getHandle().pitch, getHandle().yaw, 0.0F, 1.5F, 1.0F); // ItemEnderPearl
} else if (Arrow.class.isAssignableFrom(projectile)) {
launch = new EntityTippedArrow(world, getHandle());
if (TippedArrow.class.isAssignableFrom(projectile)) {
launch = new EntityTippedArrow(world);
((EntityTippedArrow) launch).setType(CraftPotionUtil.fromBukkit(new PotionData(PotionType.WATER, false, false)));
} else if (SpectralArrow.class.isAssignableFrom(projectile)) {
launch = new EntitySpectralArrow(world);
} else {
launch = new EntityTippedArrow(world);
}
((EntityArrow) launch).a(getHandle(), getHandle().pitch, getHandle().yaw, 0.0F, 3.0F, 1.0F); // ItemBow
} else if (ThrownPotion.class.isAssignableFrom(projectile)) {
launch = new EntityPotion(world, getHandle(), CraftItemStack.asNMSCopy(new ItemStack(Material.POTION, 1)));
if (LingeringPotion.class.isAssignableFrom(projectile)) {
launch = new EntityPotion(world, getHandle(), CraftItemStack.asNMSCopy(new ItemStack(org.bukkit.Material.LINGERING_POTION, 1)));
} else {
launch = new EntityPotion(world, getHandle(), CraftItemStack.asNMSCopy(new ItemStack(org.bukkit.Material.SPLASH_POTION, 1)));
}
((EntityProjectile) launch).a(getHandle(), getHandle().pitch, getHandle().yaw, -20.0F, 0.5F, 1.0F); // ItemSplashPotion
} else if (ThrownExpBottle.class.isAssignableFrom(projectile)) {
launch = new EntityThrownExpBottle(world, getHandle());

View File

@@ -0,0 +1,42 @@
package org.bukkit.craftbukkit.entity;
import net.minecraft.server.EntityPotion;
import org.apache.commons.lang.Validate;
import org.bukkit.Material;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
public class CraftSplashPotion extends CraftThrownPotion {
public CraftSplashPotion(CraftServer server, EntityPotion entity) {
super(server, entity);
}
@Override
public void setItem(ItemStack item) {
// The ItemStack must not be null.
Validate.notNull(item, "ItemStack cannot be null.");
// The ItemStack must be a potion.
Validate.isTrue(item.getType() == Material.SPLASH_POTION, "ItemStack must be a splash potion. This item stack was " + item.getType() + ".");
getHandle().setItem(CraftItemStack.asNMSCopy(item));
}
@Override
public EntityPotion getHandle() {
return (EntityPotion) entity;
}
@Override
public String toString() {
return "CraftSplashPotion";
}
@Override
public EntityType getType() {
return EntityType.SPLASH_POTION;
}
}

View File

@@ -1,55 +1,41 @@
package org.bukkit.craftbukkit.entity;
import java.util.Collection;
import net.minecraft.server.EntityPotion;
import net.minecraft.server.MobEffect;
import net.minecraft.server.PotionUtil;
import org.apache.commons.lang.Validate;
import org.bukkit.Material;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.craftbukkit.potion.CraftPotionUtil;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.ThrownPotion;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.Potion;
import org.bukkit.potion.PotionEffect;
public class CraftThrownPotion extends CraftProjectile implements ThrownPotion {
import com.google.common.collect.ImmutableList;
public abstract class CraftThrownPotion extends CraftProjectile implements ThrownPotion {
public CraftThrownPotion(CraftServer server, EntityPotion entity) {
super(server, entity);
}
// TODO: This one does not handle custom NBT potion effects does it?
// In that case this method could be said to be misleading or incorrect
public Collection<PotionEffect> getEffects() {
return Potion.getBrewer().getEffectsFromDamage(getHandle().getItem().getData());
ImmutableList.Builder<PotionEffect> builder = ImmutableList.builder();
for (MobEffect effect : PotionUtil.getEffects(getHandle().getItem())) {
builder.add(CraftPotionUtil.toBukkit(effect));
}
return builder.build();
}
public ItemStack getItem() {
return CraftItemStack.asBukkitCopy(getHandle().getItem());
}
public void setItem(ItemStack item) {
// The ItemStack must not be null.
Validate.notNull(item, "ItemStack cannot be null.");
// The ItemStack must be a potion.
Validate.isTrue(item.getType() == Material.POTION, "ItemStack must be a potion. This item stack was " + item.getType() + ".");
getHandle().setItem(CraftItemStack.asNMSCopy(item));
}
@Override
public EntityPotion getHandle() {
return (EntityPotion) entity;
}
@Override
public String toString() {
return "CraftThrownPotion";
}
public EntityType getType() {
return EntityType.SPLASH_POTION;
}
}

View File

@@ -0,0 +1,122 @@
package org.bukkit.craftbukkit.entity;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.potion.CraftPotionUtil;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.TippedArrow;
import org.bukkit.potion.PotionData;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.potion.PotionType;
import com.google.common.collect.ImmutableList;
import net.minecraft.server.EntityTippedArrow;
import net.minecraft.server.MobEffect;
import net.minecraft.server.MobEffectList;
public class CraftTippedArrow extends CraftArrow implements TippedArrow {
public CraftTippedArrow(CraftServer server, EntityTippedArrow entity) {
super(server, entity);
}
@Override
public EntityTippedArrow getHandle() {
return (EntityTippedArrow) entity;
}
@Override
public String toString() {
return "CraftTippedArrow";
}
@Override
public EntityType getType() {
return EntityType.TIPPED_ARROW;
}
@Override
public boolean addCustomEffect(PotionEffect effect, boolean override) {
int effectId = effect.getType().getId();
MobEffect existing = null;
for (MobEffect mobEffect : getHandle().h) {
if (MobEffectList.getId(mobEffect.getMobEffect()) == effectId) {
existing = mobEffect;
}
}
if (existing != null) {
if (!override) {
return false;
}
getHandle().h.remove(existing);
}
getHandle().a(CraftPotionUtil.fromBukkit(effect));
getHandle().refreshEffects();
return true;
}
@Override
public void clearCustomEffects() {
Validate.isTrue(getBasePotionData().getType() != PotionType.UNCRAFTABLE, "Tipped Arrows must have at least 1 effect");
getHandle().h.clear();
getHandle().refreshEffects();
}
@Override
public List<PotionEffect> getCustomEffects() {
ImmutableList.Builder<PotionEffect> builder = ImmutableList.builder();
for (MobEffect effect : getHandle().h) {
builder.add(CraftPotionUtil.toBukkit(effect));
}
return builder.build();
}
@Override
public boolean hasCustomEffect(PotionEffectType type) {
for (MobEffect effect : getHandle().h) {
if (CraftPotionUtil.equals(effect.getMobEffect(), type)) {
return true;
}
}
return false;
}
@Override
public boolean hasCustomEffects() {
return !getHandle().h.isEmpty();
}
@Override
public boolean removeCustomEffect(PotionEffectType effect) {
int effectId = effect.getId();
MobEffect existing = null;
for (MobEffect mobEffect : getHandle().h) {
if (MobEffectList.getId(mobEffect.getMobEffect()) == effectId) {
existing = mobEffect;
}
}
if (existing == null) {
return false;
}
Validate.isTrue(getBasePotionData().getType() != PotionType.UNCRAFTABLE || getHandle().h.size() != 1, "Tipped Arrows must have at least 1 effect");
getHandle().h.remove(existing);
getHandle().refreshEffects();
return true;
}
@Override
public void setBasePotionData(PotionData data) {
Validate.notNull(data, "PotionData cannot be null");
Validate.isTrue(data.getType() != PotionType.UNCRAFTABLE || !getHandle().h.isEmpty(), "Tipped Arrows must have at least 1 effect");
getHandle().setType(CraftPotionUtil.fromBukkit(data));
}
@Override
public PotionData getBasePotionData() {
return CraftPotionUtil.toBukkit(getHandle().getType());
}
}