001 package org.bukkit.potion;
002
003 import java.util.HashMap;
004 import java.util.Map;
005
006 import org.apache.commons.lang.Validate;
007
008 /**
009 * Represents a type of potion and its effect on an entity.
010 */
011 public abstract class PotionEffectType {
012 /**
013 * Increases movement speed.
014 */
015 public static final PotionEffectType SPEED = new PotionEffectTypeWrapper(1);
016
017 /**
018 * Decreases movement speed.
019 */
020 public static final PotionEffectType SLOW = new PotionEffectTypeWrapper(2);
021
022 /**
023 * Increases dig speed.
024 */
025 public static final PotionEffectType FAST_DIGGING = new PotionEffectTypeWrapper(3);
026
027 /**
028 * Decreases dig speed.
029 */
030 public static final PotionEffectType SLOW_DIGGING = new PotionEffectTypeWrapper(4);
031
032 /**
033 * Increases damage dealt.
034 */
035 public static final PotionEffectType INCREASE_DAMAGE = new PotionEffectTypeWrapper(5);
036
037 /**
038 * Heals an entity.
039 */
040 public static final PotionEffectType HEAL = new PotionEffectTypeWrapper(6);
041
042 /**
043 * Hurts an entity.
044 */
045 public static final PotionEffectType HARM = new PotionEffectTypeWrapper(7);
046
047 /**
048 * Increases jump height.
049 */
050 public static final PotionEffectType JUMP = new PotionEffectTypeWrapper(8);
051
052 /**
053 * Warps vision on the client.
054 */
055 public static final PotionEffectType CONFUSION = new PotionEffectTypeWrapper(9);
056
057 /**
058 * Regenerates health.
059 */
060 public static final PotionEffectType REGENERATION = new PotionEffectTypeWrapper(10);
061
062 /**
063 * Decreases damage dealt to an entity.
064 */
065 public static final PotionEffectType DAMAGE_RESISTANCE = new PotionEffectTypeWrapper(11);
066
067 /**
068 * Stops fire damage.
069 */
070 public static final PotionEffectType FIRE_RESISTANCE = new PotionEffectTypeWrapper(12);
071
072 /**
073 * Allows breathing underwater.
074 */
075 public static final PotionEffectType WATER_BREATHING = new PotionEffectTypeWrapper(13);
076
077 /**
078 * Grants invisibility.
079 */
080 public static final PotionEffectType INVISIBILITY = new PotionEffectTypeWrapper(14);
081
082 /**
083 * Blinds an entity.
084 */
085 public static final PotionEffectType BLINDNESS = new PotionEffectTypeWrapper(15);
086
087 /**
088 * Allows an entity to see in the dark.
089 */
090 public static final PotionEffectType NIGHT_VISION = new PotionEffectTypeWrapper(16);
091
092 /**
093 * Increases hunger.
094 */
095 public static final PotionEffectType HUNGER = new PotionEffectTypeWrapper(17);
096
097 /**
098 * Decreases damage dealt by an entity.
099 */
100 public static final PotionEffectType WEAKNESS = new PotionEffectTypeWrapper(18);
101
102 /**
103 * Deals damage to an entity over time.
104 */
105 public static final PotionEffectType POISON = new PotionEffectTypeWrapper(19);
106
107 /**
108 * Deals damage to an entity over time and gives the health to the
109 * shooter.
110 */
111 public static final PotionEffectType WITHER = new PotionEffectTypeWrapper(20);
112
113 /**
114 * Increases the maximum health of an entity.
115 */
116 public static final PotionEffectType HEALTH_BOOST = new PotionEffectTypeWrapper(21);
117
118 /**
119 * Increases the maximum health of an entity with health that cannot be
120 * regenerated, but is refilled every 30 seconds.
121 */
122 public static final PotionEffectType ABSORPTION = new PotionEffectTypeWrapper(22);
123
124 /**
125 * Increases the food level of an entity each tick.
126 */
127 public static final PotionEffectType SATURATION = new PotionEffectTypeWrapper(23);
128
129 private final int id;
130
131 protected PotionEffectType(int id) {
132 this.id = id;
133 }
134
135 /**
136 * Creates a PotionEffect from this PotionEffectType, applying duration
137 * modifiers and checks.
138 *
139 * @see PotionBrewer#createEffect(PotionEffectType, int, int)
140 * @param duration time in ticks
141 * @param amplifier the effect's amplifier
142 * @return a resulting potion effect
143 */
144 public PotionEffect createEffect(int duration, int amplifier) {
145 return Potion.getBrewer().createEffect(this, duration, amplifier);
146 }
147
148 /**
149 * Returns the duration modifier applied to effects of this type.
150 *
151 * @return duration modifier
152 */
153 public abstract double getDurationModifier();
154
155 /**
156 * Returns the unique ID of this type.
157 *
158 * @return Unique ID
159 * @deprecated Magic value
160 */
161 @Deprecated
162 public int getId() {
163 return id;
164 }
165
166 /**
167 * Returns the name of this effect type.
168 *
169 * @return The name of this effect type
170 */
171 public abstract String getName();
172
173 /**
174 * Returns whether the effect of this type happens once, immediately.
175 *
176 * @return whether this type is normally instant
177 */
178 public abstract boolean isInstant();
179
180 @Override
181 public boolean equals(Object obj) {
182 if (obj == null) {
183 return false;
184 }
185 if (!(obj instanceof PotionEffectType)) {
186 return false;
187 }
188 final PotionEffectType other = (PotionEffectType) obj;
189 if (this.id != other.id) {
190 return false;
191 }
192 return true;
193 }
194
195 @Override
196 public int hashCode() {
197 return id;
198 }
199
200 @Override
201 public String toString() {
202 return "PotionEffectType[" + id + ", " + getName() + "]";
203 }
204
205 private static final PotionEffectType[] byId = new PotionEffectType[24];
206 private static final Map<String, PotionEffectType> byName = new HashMap<String, PotionEffectType>();
207 // will break on updates.
208 private static boolean acceptingNew = true;
209
210 /**
211 * Gets the effect type specified by the unique id.
212 *
213 * @param id Unique ID to fetch
214 * @return Resulting type, or null if not found.
215 * @deprecated Magic value
216 */
217 @Deprecated
218 public static PotionEffectType getById(int id) {
219 if (id >= byId.length || id < 0)
220 return null;
221 return byId[id];
222 }
223
224 /**
225 * Gets the effect type specified by the given name.
226 *
227 * @param name Name of PotionEffectType to fetch
228 * @return Resulting PotionEffectType, or null if not found.
229 */
230 public static PotionEffectType getByName(String name) {
231 Validate.notNull(name, "name cannot be null");
232 return byName.get(name.toLowerCase());
233 }
234
235 /**
236 * Registers an effect type with the given object.
237 * <p>
238 * Generally not to be used from within a plugin.
239 *
240 * @param type PotionType to register
241 */
242 public static void registerPotionEffectType(PotionEffectType type) {
243 if (byId[type.id] != null || byName.containsKey(type.getName().toLowerCase())) {
244 throw new IllegalArgumentException("Cannot set already-set type");
245 } else if (!acceptingNew) {
246 throw new IllegalStateException(
247 "No longer accepting new potion effect types (can only be done by the server implementation)");
248 }
249
250 byId[type.id] = type;
251 byName.put(type.getName().toLowerCase(), type);
252 }
253
254 /**
255 * Stops accepting any effect type registrations.
256 */
257 public static void stopAcceptingRegistrations() {
258 acceptingNew = false;
259 }
260
261 /**
262 * Returns an array of all the registered {@link PotionEffectType}s.
263 *
264 * @return Array of types.
265 */
266 public static PotionEffectType[] values() {
267 return byId.clone();
268 }
269 }