From d62993211f88621e18c42f081425815346e4495e Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sun, 2 Jun 2013 15:57:09 +1000
Subject: [PATCH] Add Particle API


diff --git a/src/main/java/org/bukkit/Effect.java b/src/main/java/org/bukkit/Effect.java
index 2474a2d..9964203 100644
--- a/src/main/java/org/bukkit/Effect.java
+++ b/src/main/java/org/bukkit/Effect.java
@@ -5,6 +5,7 @@ import java.util.Map;
 import com.google.common.collect.Maps;
 
 import org.bukkit.block.BlockFace;
+import org.bukkit.material.MaterialData;
 import org.bukkit.potion.Potion;
 
 /**
@@ -79,27 +80,183 @@ public enum Effect {
     /**
      * The flames seen on a mobspawner; a visual effect.
      */
-    MOBSPAWNER_FLAMES(2004, Type.VISUAL);
+    MOBSPAWNER_FLAMES(2004, Type.VISUAL),
+    /**
+     * The spark that comes off a fireworks
+     */
+    FIREWORKS_SPARK("fireworksSpark", Type.PARTICLE),
+    /**
+     * Critical hit particles
+     */
+    CRIT("crit", Type.PARTICLE),
+    /**
+     * Blue critical hit particles
+     */
+    MAGIC_CRIT("magicCrit", Type.PARTICLE),
+    /**
+     * Multicolored potion effect particles
+     */
+    POTION_SWIRL("mobSpell", Type.PARTICLE),
+    /**
+     * Multicolored potion effect particles that are slightly transparent
+     */
+    POTION_SWIRL_TRANSPARENT("mobSpellAmbient", Type.PARTICLE),
+    /**
+     * A puff of white potion swirls
+     */
+    SPELL("spell", Type.PARTICLE),
+    /**
+     * A puff of white stars
+     */
+    INSTANT_SPELL("instantSpell", Type.PARTICLE),
+    /**
+     * A puff of purple particles
+     */
+    WITCH_MAGIC("witchMagic", Type.PARTICLE),
+    /**
+     * The note that appears above note blocks
+     */
+    NOTE("note", Type.PARTICLE),
+    /**
+     * The particles shown at nether portals
+     */
+    PORTAL("portal", Type.PARTICLE),
+    /**
+     * The symbols that fly towards the enchantment table
+     */
+    FLYING_GLYPH("enchantmenttable", Type.PARTICLE),
+    /**
+     * Fire particles
+     */
+    FLAME("flame", Type.PARTICLE),
+    /**
+     * The particles that pop out of lava
+     */
+    LAVA_POP("lava", Type.PARTICLE),
+    /**
+     * A small gray square
+     */
+    FOOTSTEP("footstep", Type.PARTICLE),
+    /**
+     * Water particles
+     */
+    SPLASH("splash", Type.PARTICLE),
+    /**
+     * Smoke particles
+     */
+    PARTICLE_SMOKE("smoke", Type.PARTICLE),
+    /**
+     * The biggest explosion particle effect
+     */
+    EXPLOSION_HUGE("hugeexplosion", Type.PARTICLE),
+    /**
+     * A larger version of the explode particle
+     */
+    EXPLOSION_LARGE("largeexplode", Type.PARTICLE),
+    /**
+     * Explosion particles
+     */
+    EXPLOSION("explode", Type.PARTICLE),
+    /**
+     * Small gray particles
+     */
+    VOID_FOG("depthsuspend", Type.PARTICLE),
+    /**
+     * Small gray particles
+     */
+    SMALL_SMOKE("townaura", Type.PARTICLE),
+    /**
+     * A puff of white smoke
+     */
+    CLOUD("cloud", Type.PARTICLE),
+    /**
+     * Multicolored dust particles
+     */
+    COLOURED_DUST("reddust", Type.PARTICLE),
+    /**
+     * Snowball breaking
+     */
+    SNOWBALL_BREAK("snowballpoof", Type.PARTICLE),
+    /**
+     * The water drip particle that appears on blocks under water
+     */
+    WATERDRIP("dripWater", Type.PARTICLE),
+    /**
+     * The lava drip particle that appears on blocks under lava
+     */
+    LAVADRIP("dripLava", Type.PARTICLE),
+    /**
+     * White particles
+     */
+    SNOW_SHOVEL("snowshovel", Type.PARTICLE),
+    /**
+     * The particle shown when a slime jumps
+     */
+    SLIME("slime", Type.PARTICLE),
+    /**
+     * The particle that appears when breading animals
+     */
+    HEART("heart", Type.PARTICLE),
+    /**
+     * The particle that appears when hitting a villager
+     */
+    VILLAGER_THUNDERCLOUD("angryVillager", Type.PARTICLE),
+    /**
+     * The particle that appears when trading with a villager
+     */
+    HAPPY_VILLAGER("happyVillager", Type.PARTICLE),
+    /**
+     * The particles generated when a tool breaks.
+     * This particle requires a Material so that the client can select the correct texture.
+     */
+    ITEM_BREAK("iconcrack", Type.PARTICLE, Material.class),
+    /**
+     * The particles generated while breaking a block.
+     * This particle requires a Material and data value so that the client can select the correct texture.
+     */
+    TILE_BREAK("blockcrack", Type.PARTICLE, MaterialData.class),
+    /**
+     * The particles generated while sprinting a block
+     * This particle requires a Material and data value so that the client can select the correct texture.
+     */
+    TILE_DUST("blockdust", Type.PARTICLE, MaterialData.class);
 
     private final int id;
     private final Type type;
     private final Class<?> data;
     private static final Map<Integer, Effect> BY_ID = Maps.newHashMap();
+    private static final Map<String, Effect> BY_NAME = Maps.newHashMap();
+    private final String particleName;
 
-    Effect(int id, Type type) {
+    private Effect(int id, Type type) {
         this(id,type,null);
     }
 
-    Effect(int id, Type type, Class<?> data) {
+    private Effect(int id, Type type, Class<?> data) {
         this.id = id;
         this.type = type;
         this.data = data;
+        particleName = null;
+    }
+
+    private Effect(String particleName, Type type, Class<?> data) {
+        this.particleName = particleName;
+        this.type = type;
+        id = 0;
+        this.data = data;
+    }
+
+    private Effect(String particleName, Type type) {
+        this.particleName = particleName;
+        this.type = type;
+        id = 0;
+        this.data = null;
     }
 
     /**
      * Gets the ID for this effect.
      *
-     * @return ID of this effect
+     * @return if this Effect isn't of type PARTICLE it returns ID of this effect
      * @deprecated Magic value
      */
     @Deprecated
@@ -108,6 +265,15 @@ public enum Effect {
     }
 
     /**
+     * Returns the effect's name. This returns null if the effect is not a particle
+     *
+     * @return The effect's name
+     */
+    public String getName() {
+        return particleName;
+    }
+
+    /**
      * @return The type of the effect.
      */
     public Type getType() {
@@ -115,8 +281,7 @@ public enum Effect {
     }
 
     /**
-     * @return The class which represents data for this effect, or null if
-     *     none
+     * @return if this Effect isn't of type PARTICLE it returns the class which represents data for this effect, or null if none
      */
     public Class<?> getData() {
         return this.data;
@@ -136,12 +301,32 @@ public enum Effect {
 
     static {
         for (Effect effect : values()) {
-            BY_ID.put(effect.id, effect);
+            if (effect.type != Type.PARTICLE) {
+                BY_ID.put(effect.id, effect);
+            }
+        }
+    }
+
+    /**
+     * Gets the Effect associated with the given name.
+     *
+     * @param name name of the Effect to return
+     * @return Effect with the given name
+     */
+    public static Effect getByName(String name) {
+        return BY_NAME.get(name);
+    }
+
+    static {
+        for (Effect effect : values()) {
+            if (effect.type == Type.PARTICLE) {
+                BY_NAME.put(effect.particleName, effect);
+            }
         }
     }
 
     /**
      * Represents the type of an effect.
      */
-    public enum Type {SOUND, VISUAL}
+    public enum Type {SOUND, VISUAL, PARTICLE}
 }
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
index 9bf2c41..6cf3ff0 100644
--- a/src/main/java/org/bukkit/World.java
+++ b/src/main/java/org/bukkit/World.java
@@ -1155,6 +1155,56 @@ public interface World extends PluginMessageRecipient, Metadatable {
      */
     public boolean isGameRule(String rule);
 
+    // Spigot start
+    public class Spigot
+    {
+
+        /**
+         * Plays an effect to all players within a default radius around a given
+         * location.
+         *
+         * @param location the {@link Location} around which players must be to
+         * see the effect
+         * @param effect the {@link Effect}
+         * @throws IllegalArgumentException if the location or effect is null.
+         * It also throws when the effect requires a material or a material data
+         */
+        public void playEffect(Location location, Effect effect)
+        {
+            throw new UnsupportedOperationException( "Not supported yet." );
+        }
+
+        /**
+         * Plays an effect to all players within a default radius around a given
+         * location. The effect will use the provided material (and material
+         * data if required). The particle's position on the client will be the
+         * given location, adjusted on each axis by a normal distribution with
+         * mean 0 and standard deviation given in the offset parameters, each
+         * particle has independently calculated offsets. The effect will have
+         * the given speed and particle count if the effect is a particle. Some
+         * effect will create multiple particles.
+         *
+         * @param location the {@link Location} around which players must be to
+         * see the effect
+         * @param effect effect the {@link Effect}
+         * @param id the item/block/data id for the effect
+         * @param data the data value of the block/item for the effect
+         * @param offsetX the amount to be randomly offset by in the X axis
+         * @param offsetY the amount to be randomly offset by in the Y axis
+         * @param offsetZ the amount to be randomly offset by in the Z axis
+         * @param speed the speed of the particles
+         * @param particleCount the number of particles
+         * @param radius the radius around the location
+         */
+        public void playEffect(Location location, Effect effect, int id, int data, float offsetX, float offsetY, float offsetZ, float speed, int particleCount, int radius)
+        {
+            throw new UnsupportedOperationException( "Not supported yet." );
+        }
+    }
+
+    Spigot spigot();
+    // Spigot end
+
     /**
      * Represents various map environment types that a world may be
      */
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
index e851b98..c6bb787 100644
--- a/src/main/java/org/bukkit/entity/Player.java
+++ b/src/main/java/org/bukkit/entity/Player.java
@@ -1050,6 +1050,11 @@ public interface Player extends HumanEntity, Conversable, CommandSender, Offline
         {
             throw new UnsupportedOperationException( "Not supported yet." );
         }
+
+        public void playEffect(Location location, Effect effect, int id, int data, float offsetX, float offsetY, float offsetZ, float speed, int particleCount, int radius)
+        {
+            throw new UnsupportedOperationException( "Not supported yet." );
+        }
     }
 
     Spigot spigot();
diff --git a/src/test/java/org/bukkit/EffectTest.java b/src/test/java/org/bukkit/EffectTest.java
index 08aa71d..5217aec 100644
--- a/src/test/java/org/bukkit/EffectTest.java
+++ b/src/test/java/org/bukkit/EffectTest.java
@@ -9,7 +9,11 @@ public class EffectTest {
     @Test
     public void getById() {
         for (Effect effect : Effect.values()) {
-            assertThat(Effect.getById(effect.getId()), is(effect));
+            if (effect.getType() != Effect.Type.PARTICLE) {
+                assertThat(Effect.getById(effect.getId()), is(effect));
+            } else {
+                assertThat(Effect.getByName(effect.getName()), is(effect));
+            }
         }
     }
 }
-- 
1.8.5.2.msysgit.0