Bukkit-API  1.7.9-R0.2
The inofficial Bukkit-API
Potion.java
1 package org.bukkit.potion;
2 
3 import java.util.Collection;
4 
5 import org.apache.commons.lang.Validate;
6 import org.bukkit.Material;
9 
10 import com.google.common.collect.ImmutableList;
11 
12 /**
13  * Represents a minecraft potion
14  */
15 public class Potion {
16  private boolean extended = false;
17  private boolean splash = false;
18  private int level = 1;
19  private int name = -1;
20  private PotionType type;
21 
22  /**
23  * Construct a new potion of the given type. Unless the type is {@link
24  * PotionType#WATER}, it will be level one, without extended duration.
25  * Don't use this constructor to create a no-effect potion other than
26  * water bottle.
27  *
28  * @param type The potion type
29  * @see #Potion(int)
30  */
31  public Potion(PotionType type) {
32  this.type = type;
33  if (type != null) {
34  this.name = type.getDamageValue();
35  }
36  if (type == null || type == PotionType.WATER) {
37  this.level = 0;
38  }
39  }
40 
41  /**
42  * @deprecated In favour of {@link #Potion(PotionType, int)}
43  */
44  @SuppressWarnings("javadoc")
45  @Deprecated
46  public Potion(PotionType type, Tier tier) {
47  this(type, tier == Tier.TWO ? 2 : 1);
48  Validate.notNull(type, "Type cannot be null");
49  }
50 
51  /**
52  * @deprecated In favour of {@link #Potion(PotionType, int, boolean)}
53  */
54  @SuppressWarnings("javadoc")
55  @Deprecated
56  public Potion(PotionType type, Tier tier, boolean splash) {
57  this(type, tier == Tier.TWO ? 2 : 1, splash);
58  }
59 
60  /**
61  * @deprecated In favour of {@link #Potion(PotionType, int, boolean,
62  * boolean)}
63  */
64  @SuppressWarnings("javadoc")
65  @Deprecated
66  public Potion(PotionType type, Tier tier, boolean splash, boolean extended) {
67  this(type, tier, splash);
68  this.extended = extended;
69  }
70 
71  /**
72  * Create a new potion of the given type and level.
73  *
74  * @param type The type of potion.
75  * @param level The potion's level.
76  */
77  public Potion(PotionType type, int level) {
78  this(type);
79  Validate.notNull(type, "Type cannot be null");
80  Validate.isTrue(type != PotionType.WATER, "Water bottles don't have a level!");
81  Validate.isTrue(level > 0 && level < 3, "Level must be 1 or 2");
82  this.level = level;
83  }
84 
85  /**
86  * Create a new potion of the given type and level.
87  *
88  * @param type The type of potion.
89  * @param level The potion's level.
90  * @param splash Whether it is a splash potion.
91  * @deprecated In favour of using {@link #Potion(PotionType)} with {@link
92  * #splash()}.
93  */
94  @Deprecated
95  public Potion(PotionType type, int level, boolean splash) {
96  this(type, level);
97  this.splash = splash;
98  }
99 
100  /**
101  * Create a new potion of the given type and level.
102  *
103  * @param type The type of potion.
104  * @param level The potion's level.
105  * @param splash Whether it is a splash potion.
106  * @param extended Whether it has an extended duration.
107  * @deprecated In favour of using {@link #Potion(PotionType)} with {@link
108  * #extend()} and possibly {@link #splash()}.
109  */
110  @Deprecated
111  public Potion(PotionType type, int level, boolean splash, boolean extended) {
112  this(type, level, splash);
113  this.extended = extended;
114  }
115 
116  /**
117  * Create a potion with a specific name.
118  *
119  * @param name The name index (0-63)
120  */
121  public Potion(int name) {
122  this(PotionType.getByDamageValue(name & POTION_BIT));
123  this.name = name & NAME_BIT;
124  if ((name & POTION_BIT) == 0) {
125  // If it's 0 it would've become PotionType.WATER, but it should actually be mundane potion
126  this.type = null;
127  }
128  }
129 
130  /**
131  * Chain this to the constructor to make the potion a splash potion.
132  *
133  * @return The potion.
134  */
135  public Potion splash() {
136  setSplash(true);
137  return this;
138  }
139 
140  /**
141  * Chain this to the constructor to extend the potion's duration.
142  *
143  * @return The potion.
144  */
145  public Potion extend() {
147  return this;
148  }
149 
150  /**
151  * Applies the effects of this potion to the given {@link ItemStack}. The
152  * ItemStack must be a potion.
153  *
154  * @param to The itemstack to apply to
155  */
156  public void apply(ItemStack to) {
157  Validate.notNull(to, "itemstack cannot be null");
158  Validate.isTrue(to.getType() == Material.POTION, "given itemstack is not a potion");
160  }
161 
162  /**
163  * Applies the effects that would be applied by this potion to the given
164  * {@link LivingEntity}.
165  *
166  * @see LivingEntity#addPotionEffects(Collection)
167  * @param to The entity to apply the effects to
168  */
169  public void apply(LivingEntity to) {
170  Validate.notNull(to, "entity cannot be null");
172  }
173 
174  @Override
175  public boolean equals(Object obj) {
176  if (this == obj) {
177  return true;
178  }
179  if (obj == null || getClass() != obj.getClass()) {
180  return false;
181  }
182  Potion other = (Potion) obj;
183  return extended == other.extended && splash == other.splash && level == other.level && type == other.type;
184  }
185 
186  /**
187  * Returns a collection of {@link PotionEffect}s that this {@link Potion}
188  * would confer upon a {@link LivingEntity}.
189  *
190  * @see PotionBrewer#getEffectsFromDamage(int)
191  * @see Potion#toDamageValue()
192  * @return The effects that this potion applies
193  */
194  public Collection<PotionEffect> getEffects() {
195  if (type == null) return ImmutableList.<PotionEffect>of();
197  }
198 
199  /**
200  * Returns the level of this potion.
201  *
202  * @return The level of this potion
203  */
204  public int getLevel() {
205  return level;
206  }
207 
208  /**
209  * Returns the {@link Tier} of this potion.
210  *
211  * @return The tier of this potion
212  */
213  @Deprecated
214  public Tier getTier() {
215  return level == 2 ? Tier.TWO : Tier.ONE;
216  }
217 
218  /**
219  * Returns the {@link PotionType} of this potion.
220  *
221  * @return The type of this potion
222  */
223  public PotionType getType() {
224  return type;
225  }
226 
227  /**
228  * Returns whether this potion has an extended duration.
229  *
230  * @return Whether this potion has extended duration
231  */
232  public boolean hasExtendedDuration() {
233  return extended;
234  }
235 
236  @Override
237  public int hashCode() {
238  final int prime = 31;
239  int result = prime + level;
240  result = prime * result + (extended ? 1231 : 1237);
241  result = prime * result + (splash ? 1231 : 1237);
242  result = prime * result + ((type == null) ? 0 : type.hashCode());
243  return result;
244  }
245 
246  /**
247  * Returns whether this potion is a splash potion.
248  *
249  * @return Whether this is a splash potion
250  */
251  public boolean isSplash() {
252  return splash;
253  }
254 
255  /**
256  * Set whether this potion has extended duration. This will cause the
257  * potion to have roughly 8/3 more duration than a regular potion.
258  *
259  * @param isExtended Whether the potion should have extended duration
260  */
261  public void setHasExtendedDuration(boolean isExtended) {
262  Validate.isTrue(type == null || !type.isInstant(), "Instant potions cannot be extended");
263  extended = isExtended;
264  }
265 
266  /**
267  * Sets whether this potion is a splash potion. Splash potions can be
268  * thrown for a radius effect.
269  *
270  * @param isSplash Whether this is a splash potion
271  */
272  public void setSplash(boolean isSplash) {
273  splash = isSplash;
274  }
275 
276  /**
277  * Sets the {@link Tier} of this potion.
278  *
279  * @param tier The new tier of this potion
280  * @deprecated In favour of {@link #setLevel(int)}
281  */
282  @Deprecated
283  public void setTier(Tier tier) {
284  Validate.notNull(tier, "tier cannot be null");
285  this.level = (tier == Tier.TWO ? 2 : 1);
286  }
287 
288  /**
289  * Sets the {@link PotionType} of this potion.
290  *
291  * @param type The new type of this potion
292  */
293  public void setType(PotionType type) {
294  this.type = type;
295  }
296 
297  /**
298  * Sets the level of this potion.
299  *
300  * @param level The new level of this potion
301  */
302  public void setLevel(int level) {
303  Validate.notNull(this.type, "No-effect potions don't have a level.");
304  int max = type.getMaxLevel();
305  Validate.isTrue(level > 0 && level <= max, "Level must be " + (max == 1 ? "" : "between 1 and ") + max + " for this potion");
306  this.level = level;
307  }
308 
309  /**
310  * Converts this potion to a valid potion damage short, usable for potion
311  * item stacks.
312  *
313  * @return The damage value of this potion
314  * @deprecated Magic value
315  */
316  @Deprecated
317  public short toDamageValue() {
318  short damage;
319  if (type == PotionType.WATER) {
320  return 0;
321  } else if (type == null) {
322  // Without this, mundanePotion.toDamageValue() would return 0
323  damage = (short) (name == 0 ? 8192 : name);
324  } else {
325  damage = (short) (level - 1);
326  damage <<= TIER_SHIFT;
327  damage |= (short) type.getDamageValue();
328  }
329  if (splash) {
330  damage |= SPLASH_BIT;
331  }
332  if (extended) {
333  damage |= EXTENDED_BIT;
334  }
335  return damage;
336  }
337 
338  /**
339  * Converts this potion to an {@link ItemStack} with the specified amount
340  * and a correct damage value.
341  *
342  * @param amount The amount of the ItemStack
343  * @return The created ItemStack
344  */
345  public ItemStack toItemStack(int amount) {
346  return new ItemStack(Material.POTION, amount, toDamageValue());
347  }
348 
349  @Deprecated
350  public enum Tier {
351  ONE(0),
352  TWO(0x20);
353 
354  private int damageBit;
355 
356  Tier(int bit) {
357  damageBit = bit;
358  }
359 
360  public int getDamageBit() {
361  return damageBit;
362  }
363 
364  public static Tier getByDamageBit(int damageBit) {
365  for (Tier tier : Tier.values()) {
366  if (tier.damageBit == damageBit)
367  return tier;
368  }
369  return null;
370  }
371  }
372 
373  private static PotionBrewer brewer;
374 
375  private static final int EXTENDED_BIT = 0x40;
376  private static final int POTION_BIT = 0xF;
377  private static final int SPLASH_BIT = 0x4000;
378  private static final int TIER_BIT = 0x20;
379  private static final int TIER_SHIFT = 5;
380  private static final int NAME_BIT = 0x3F;
381 
382  /**
383  *
384  * @deprecated Magic value
385  */
386  @Deprecated
387  public static Potion fromDamage(int damage) {
388  PotionType type = PotionType.getByDamageValue(damage & POTION_BIT);
389  Potion potion;
390  if (type == null || (type == PotionType.WATER && damage != 0)) {
391  potion = new Potion(damage & NAME_BIT);
392  } else {
393  int level = (damage & TIER_BIT) >> TIER_SHIFT;
394  level++;
395  potion = new Potion(type, level);
396  }
397  if ((damage & SPLASH_BIT) > 0) {
398  potion = potion.splash();
399  }
400  if ((damage & EXTENDED_BIT) > 0) {
401  potion = potion.extend();
402  }
403  return potion;
404  }
405 
406  public static Potion fromItemStack(ItemStack item) {
407  Validate.notNull(item, "item cannot be null");
408  if (item.getType() != Material.POTION)
409  throw new IllegalArgumentException("item is not a potion");
410  return fromDamage(item.getDurability());
411  }
412 
413  /**
414  * Returns an instance of {@link PotionBrewer}.
415  *
416  * @return An instance of PotionBrewer
417  */
418  public static PotionBrewer getBrewer() {
419  return brewer;
420  }
421 
422  /**
423  * Sets the current instance of {@link PotionBrewer}. Generally not to be
424  * used from within a plugin.
425  *
426  * @param other The new PotionBrewer
427  */
428  public static void setPotionBrewer(PotionBrewer other) {
429  if (brewer != null)
430  throw new IllegalArgumentException("brewer can only be set internally");
431  brewer = other;
432  }
433 
434  /**
435  *
436  * @deprecated Magic value
437  */
438  @Deprecated
439  public int getNameId() {
440  return name;
441  }
442 }
PotionType getType()
Definition: Potion.java:223
void apply(LivingEntity to)
Definition: Potion.java:169
Potion(PotionType type)
Definition: Potion.java:31
void apply(ItemStack to)
Definition: Potion.java:156
Collection< PotionEffect > getEffectsFromDamage(int damage)
Potion(PotionType type, int level, boolean splash)
Definition: Potion.java:95
void setType(PotionType type)
Definition: Potion.java:293
void setLevel(int level)
Definition: Potion.java:302
Potion(PotionType type, int level)
Definition: Potion.java:77
Potion(PotionType type, Tier tier, boolean splash)
Definition: Potion.java:56
boolean hasExtendedDuration()
Definition: Potion.java:232
static Potion fromDamage(int damage)
Definition: Potion.java:387
Potion(PotionType type, Tier tier, boolean splash, boolean extended)
Definition: Potion.java:66
boolean addPotionEffects(Collection< PotionEffect > effects)
void setDurability(final short durability)
Definition: ItemStack.java:253
void setHasExtendedDuration(boolean isExtended)
Definition: Potion.java:261
void setSplash(boolean isSplash)
Definition: Potion.java:272
void setTier(Tier tier)
Definition: Potion.java:283
static PotionType getByDamageValue(int damage)
Definition: PotionType.java:54
static PotionBrewer getBrewer()
Definition: Potion.java:418
Collection< PotionEffect > getEffects()
Definition: Potion.java:194
ItemStack toItemStack(int amount)
Definition: Potion.java:345
Potion(PotionType type, int level, boolean splash, boolean extended)
Definition: Potion.java:111
static void setPotionBrewer(PotionBrewer other)
Definition: Potion.java:428
Potion(PotionType type, Tier tier)
Definition: Potion.java:46