Advertisement
Guest User

Untitled

a guest
May 26th, 2016
294
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 59.62 KB | None | 0 0
  1. package me.flash110;
  2.  
  3. import java.lang.reflect.Constructor;
  4. import java.lang.reflect.Field;
  5. import java.lang.reflect.Method;
  6. import java.util.Arrays;
  7. import java.util.HashMap;
  8. import java.util.List;
  9. import java.util.Map;
  10. import java.util.Map.Entry;
  11.  
  12. import org.bukkit.Bukkit;
  13. import org.bukkit.Color;
  14. import org.bukkit.Location;
  15. import org.bukkit.Material;
  16. import org.bukkit.entity.Player;
  17. import org.bukkit.util.Vector;
  18.  
  19. import me.flash110.ParticleEffect.ParticleData;
  20. import me.flash110.ReflectionUtils.PackageType;
  21.  
  22. /**
  23.  * <b>ParticleEffect Library</b>
  24.  * <p>
  25.  * This library was created by @DarkBlade12 and allows you to display all Minecraft particle effects on a Bukkit server
  26.  * <p>
  27.  * You are welcome to use it, modify it and redistribute it under the following conditions:
  28.  * <ul>
  29.  * <li>Don't claim this class as your own
  30.  * <li>Don't remove this disclaimer
  31.  * </ul>
  32.  * <p>
  33.  * Special thanks:
  34.  * <ul>
  35.  * <li>@microgeek (original idea, names and packet parameters)
  36.  * <li>@ShadyPotato (1.8 names, ids and packet parameters)
  37.  * <li>@RingOfStorms (particle behavior)
  38.  * <li>@Cybermaxke (particle behavior)
  39.  * <li>@JamieSinn (hosting a jenkins server and documentation for particleeffect)
  40.  * </ul>
  41.  * <p>
  42.  * <i>It would be nice if you provide credit to me if you use this class in a published project</i>
  43.  *
  44.  * @author DarkBlade12
  45.  * @version 1.7
  46.  */
  47. public enum ParticleEffect {
  48.     /**
  49.      * A particle effect which is displayed by exploding tnt and creepers:
  50.      * <ul>
  51.      * <li>It looks like a white cloud
  52.      * <li>The speed value influences the velocity at which the particle flies off
  53.      * </ul>
  54.      */
  55.     EXPLOSION_NORMAL("explode", 0, -1, ParticleProperty.DIRECTIONAL),
  56.     /**
  57.      * A particle effect which is displayed by exploding ghast fireballs and wither skulls:
  58.      * <ul>
  59.      * <li>It looks like a gray ball which is fading away
  60.      * <li>The speed value slightly influences the size of this particle effect
  61.      * </ul>
  62.      */
  63.     EXPLOSION_LARGE("largeexplode", 1, -1),
  64.     /**
  65.      * A particle effect which is displayed by exploding tnt and creepers:
  66.      * <ul>
  67.      * <li>It looks like a crowd of gray balls which are fading away
  68.      * <li>The speed value has no influence on this particle effect
  69.      * </ul>
  70.      */
  71.     EXPLOSION_HUGE("hugeexplosion", 2, -1),
  72.     /**
  73.      * A particle effect which is displayed by launching fireworks:
  74.      * <ul>
  75.      * <li>It looks like a white star which is sparkling
  76.      * <li>The speed value influences the velocity at which the particle flies off
  77.      * </ul>
  78.      */
  79.     FIREWORKS_SPARK("fireworksSpark", 3, -1, ParticleProperty.DIRECTIONAL),
  80.     /**
  81.      * A particle effect which is displayed by swimming entities and arrows in water:
  82.      * <ul>
  83.      * <li>It looks like a bubble
  84.      * <li>The speed value influences the velocity at which the particle flies off
  85.      * </ul>
  86.      */
  87.     WATER_BUBBLE("bubble", 4, -1, ParticleProperty.DIRECTIONAL, ParticleProperty.REQUIRES_WATER),
  88.     /**
  89.      * A particle effect which is displayed by swimming entities and shaking wolves:
  90.      * <ul>
  91.      * <li>It looks like a blue drop
  92.      * <li>The speed value has no influence on this particle effect
  93.      * </ul>
  94.      */
  95.     WATER_SPLASH("splash", 5, -1, ParticleProperty.DIRECTIONAL),
  96.     /**
  97.      * A particle effect which is displayed on water when fishing:
  98.      * <ul>
  99.      * <li>It looks like a blue droplet
  100.      * <li>The speed value influences the velocity at which the particle flies off
  101.      * </ul>
  102.      */
  103.     WATER_WAKE("wake", 6, 7, ParticleProperty.DIRECTIONAL),
  104.     /**
  105.      * A particle effect which is displayed by water:
  106.      * <ul>
  107.      * <li>It looks like a tiny blue square
  108.      * <li>The speed value has no influence on this particle effect
  109.      * </ul>
  110.      */
  111.     SUSPENDED("suspended", 7, -1, ParticleProperty.REQUIRES_WATER),
  112.     /**
  113.      * A particle effect which is displayed by air when close to bedrock and the in the void:
  114.      * <ul>
  115.      * <li>It looks like a tiny gray square
  116.      * <li>The speed value has no influence on this particle effect
  117.      * </ul>
  118.      */
  119.     SUSPENDED_DEPTH("depthSuspend", 8, -1, ParticleProperty.DIRECTIONAL),
  120.     /**
  121.      * A particle effect which is displayed when landing a critical hit and by arrows:
  122.      * <ul>
  123.      * <li>It looks like a light brown cross
  124.      * <li>The speed value influences the velocity at which the particle flies off
  125.      * </ul>
  126.      */
  127.     CRIT("crit", 9, -1, ParticleProperty.DIRECTIONAL),
  128.     /**
  129.      * A particle effect which is displayed when landing a hit with an enchanted weapon:
  130.      * <ul>
  131.      * <li>It looks like a cyan star
  132.      * <li>The speed value influences the velocity at which the particle flies off
  133.      * </ul>
  134.      */
  135.     CRIT_MAGIC("magicCrit", 10, -1, ParticleProperty.DIRECTIONAL),
  136.     /**
  137.      * A particle effect which is displayed by primed tnt, torches, droppers, dispensers, end portals, brewing stands and monster spawners:
  138.      * <ul>
  139.      * <li>It looks like a little gray cloud
  140.      * <li>The speed value influences the velocity at which the particle flies off
  141.      * </ul>
  142.      */
  143.     SMOKE_NORMAL("smoke", 11, -1, ParticleProperty.DIRECTIONAL),
  144.     /**
  145.      * A particle effect which is displayed by fire, minecarts with furnace and blazes:
  146.      * <ul>
  147.      * <li>It looks like a large gray cloud
  148.      * <li>The speed value influences the velocity at which the particle flies off
  149.      * </ul>
  150.      */
  151.     SMOKE_LARGE("largesmoke", 12, -1, ParticleProperty.DIRECTIONAL),
  152.     /**
  153.      * A particle effect which is displayed when splash potions or bottles o' enchanting hit something:
  154.      * <ul>
  155.      * <li>It looks like a white swirl
  156.      * <li>The speed value causes the particle to only move upwards when set to 0
  157.      * <li>Only the motion on the y-axis can be controlled, the motion on the x- and z-axis are multiplied by 0.1 when setting the values to 0
  158.      * </ul>
  159.      */
  160.     SPELL("spell", 13, -1),
  161.     /**
  162.      * A particle effect which is displayed when instant splash potions hit something:
  163.      * <ul>
  164.      * <li>It looks like a white cross
  165.      * <li>The speed value causes the particle to only move upwards when set to 0
  166.      * <li>Only the motion on the y-axis can be controlled, the motion on the x- and z-axis are multiplied by 0.1 when setting the values to 0
  167.      * </ul>
  168.      */
  169.     SPELL_INSTANT("instantSpell", 14, -1),
  170.     /**
  171.      * A particle effect which is displayed by entities with active potion effects:
  172.      * <ul>
  173.      * <li>It looks like a colored swirl
  174.      * <li>The speed value causes the particle to be colored black when set to 0
  175.      * <li>The particle color gets lighter when increasing the speed and darker when decreasing the speed
  176.      * </ul>
  177.      */
  178.     SPELL_MOB("mobSpell", 15, -1, ParticleProperty.COLORABLE),
  179.     /**
  180.      * A particle effect which is displayed by entities with active potion effects applied through a beacon:
  181.      * <ul>
  182.      * <li>It looks like a transparent colored swirl
  183.      * <li>The speed value causes the particle to be always colored black when set to 0
  184.      * <li>The particle color gets lighter when increasing the speed and darker when decreasing the speed
  185.      * </ul>
  186.      */
  187.     SPELL_MOB_AMBIENT("mobSpellAmbient", 16, -1, ParticleProperty.COLORABLE),
  188.     /**
  189.      * A particle effect which is displayed by witches:
  190.      * <ul>
  191.      * <li>It looks like a purple cross
  192.      * <li>The speed value causes the particle to only move upwards when set to 0
  193.      * <li>Only the motion on the y-axis can be controlled, the motion on the x- and z-axis are multiplied by 0.1 when setting the values to 0
  194.      * </ul>
  195.      */
  196.     SPELL_WITCH("witchMagic", 17, -1),
  197.     /**
  198.      * A particle effect which is displayed by blocks beneath a water source:
  199.      * <ul>
  200.      * <li>It looks like a blue drip
  201.      * <li>The speed value has no influence on this particle effect
  202.      * </ul>
  203.      */
  204.     DRIP_WATER("dripWater", 18, -1),
  205.     /**
  206.      * A particle effect which is displayed by blocks beneath a lava source:
  207.      * <ul>
  208.      * <li>It looks like an orange drip
  209.      * <li>The speed value has no influence on this particle effect
  210.      * </ul>
  211.      */
  212.     DRIP_LAVA("dripLava", 19, -1),
  213.     /**
  214.      * A particle effect which is displayed when attacking a villager in a village:
  215.      * <ul>
  216.      * <li>It looks like a cracked gray heart
  217.      * <li>The speed value has no influence on this particle effect
  218.      * </ul>
  219.      */
  220.     VILLAGER_ANGRY("angryVillager", 20, -1),
  221.     /**
  222.      * A particle effect which is displayed when using bone meal and trading with a villager in a village:
  223.      * <ul>
  224.      * <li>It looks like a green star
  225.      * <li>The speed value has no influence on this particle effect
  226.      * </ul>
  227.      */
  228.     VILLAGER_HAPPY("happyVillager", 21, -1, ParticleProperty.DIRECTIONAL),
  229.     /**
  230.      * A particle effect which is displayed by mycelium:
  231.      * <ul>
  232.      * <li>It looks like a tiny gray square
  233.      * <li>The speed value has no influence on this particle effect
  234.      * </ul>
  235.      */
  236.     TOWN_AURA("townaura", 22, -1, ParticleProperty.DIRECTIONAL),
  237.     /**
  238.      * A particle effect which is displayed by note blocks:
  239.      * <ul>
  240.      * <li>It looks like a colored note
  241.      * <li>The speed value causes the particle to be colored green when set to 0
  242.      * </ul>
  243.      */
  244.     NOTE("note", 23, -1, ParticleProperty.COLORABLE),
  245.     /**
  246.      * A particle effect which is displayed by nether portals, endermen, ender pearls, eyes of ender, ender chests and dragon eggs:
  247.      * <ul>
  248.      * <li>It looks like a purple cloud
  249.      * <li>The speed value influences the spread of this particle effect
  250.      * </ul>
  251.      */
  252.     PORTAL("portal", 24, -1, ParticleProperty.DIRECTIONAL),
  253.     /**
  254.      * A particle effect which is displayed by enchantment tables which are nearby bookshelves:
  255.      * <ul>
  256.      * <li>It looks like a cryptic white letter
  257.      * <li>The speed value influences the spread of this particle effect
  258.      * </ul>
  259.      */
  260.     ENCHANTMENT_TABLE("enchantmenttable", 25, -1, ParticleProperty.DIRECTIONAL),
  261.     /**
  262.      * A particle effect which is displayed by torches, active furnaces, magma cubes and monster spawners:
  263.      * <ul>
  264.      * <li>It looks like a tiny flame
  265.      * <li>The speed value influences the velocity at which the particle flies off
  266.      * </ul>
  267.      */
  268.     FLAME("flame", 26, -1, ParticleProperty.DIRECTIONAL),
  269.     /**
  270.      * A particle effect which is displayed by lava:
  271.      * <ul>
  272.      * <li>It looks like a spark
  273.      * <li>The speed value has no influence on this particle effect
  274.      * </ul>
  275.      */
  276.     LAVA("lava", 27, -1),
  277.     /**
  278.      * A particle effect which is currently unused:
  279.      * <ul>
  280.      * <li>It looks like a transparent gray square
  281.      * <li>The speed value has no influence on this particle effect
  282.      * </ul>
  283.      */
  284.     FOOTSTEP("footstep", 28, -1),
  285.     /**
  286.      * A particle effect which is displayed when a mob dies:
  287.      * <ul>
  288.      * <li>It looks like a large white cloud
  289.      * <li>The speed value influences the velocity at which the particle flies off
  290.      * </ul>
  291.      */
  292.     CLOUD("cloud", 29, -1, ParticleProperty.DIRECTIONAL),
  293.     /**
  294.      * A particle effect which is displayed by redstone ore, powered redstone, redstone torches and redstone repeaters:
  295.      * <ul>
  296.      * <li>It looks like a tiny colored cloud
  297.      * <li>The speed value causes the particle to be colored red when set to 0
  298.      * </ul>
  299.      */
  300.     REDSTONE("reddust", 30, -1, ParticleProperty.COLORABLE),
  301.     /**
  302.      * A particle effect which is displayed when snowballs hit a block:
  303.      * <ul>
  304.      * <li>It looks like a little piece with the snowball texture
  305.      * <li>The speed value has no influence on this particle effect
  306.      * </ul>
  307.      */
  308.     SNOWBALL("snowballpoof", 31, -1),
  309.     /**
  310.      * A particle effect which is currently unused:
  311.      * <ul>
  312.      * <li>It looks like a tiny white cloud
  313.      * <li>The speed value influences the velocity at which the particle flies off
  314.      * </ul>
  315.      */
  316.     SNOW_SHOVEL("snowshovel", 32, -1, ParticleProperty.DIRECTIONAL),
  317.     /**
  318.      * A particle effect which is displayed by slimes:
  319.      * <ul>
  320.      * <li>It looks like a tiny part of the slimeball icon
  321.      * <li>The speed value has no influence on this particle effect
  322.      * </ul>
  323.      */
  324.     SLIME("slime", 33, -1),
  325.     /**
  326.      * A particle effect which is displayed when breeding and taming animals:
  327.      * <ul>
  328.      * <li>It looks like a red heart
  329.      * <li>The speed value has no influence on this particle effect
  330.      * </ul>
  331.      */
  332.     HEART("heart", 34, -1),
  333.     /**
  334.      * A particle effect which is displayed by barriers:
  335.      * <ul>
  336.      * <li>It looks like a red box with a slash through it
  337.      * <li>The speed value has no influence on this particle effect
  338.      * </ul>
  339.      */
  340.     BARRIER("barrier", 35, 8),
  341.     /**
  342.      * A particle effect which is displayed when breaking a tool or eggs hit a block:
  343.      * <ul>
  344.      * <li>It looks like a little piece with an item texture
  345.      * </ul>
  346.      */
  347.     ITEM_CRACK("iconcrack", 36, -1, ParticleProperty.DIRECTIONAL, ParticleProperty.REQUIRES_DATA),
  348.     /**
  349.      * A particle effect which is displayed when breaking blocks or sprinting:
  350.      * <ul>
  351.      * <li>It looks like a little piece with a block texture
  352.      * <li>The speed value has no influence on this particle effect
  353.      * </ul>
  354.      */
  355.     BLOCK_CRACK("blockcrack", 37, -1, ParticleProperty.REQUIRES_DATA),
  356.     /**
  357.      * A particle effect which is displayed when falling:
  358.      * <ul>
  359.      * <li>It looks like a little piece with a block texture
  360.      * </ul>
  361.      */
  362.     BLOCK_DUST("blockdust", 38, 7, ParticleProperty.DIRECTIONAL, ParticleProperty.REQUIRES_DATA),
  363.     /**
  364.      * A particle effect which is displayed when rain hits the ground:
  365.      * <ul>
  366.      * <li>It looks like a blue droplet
  367.      * <li>The speed value has no influence on this particle effect
  368.      * </ul>
  369.      */
  370.     WATER_DROP("droplet", 39, 8),
  371.     /**
  372.      * A particle effect which is currently unused:
  373.      * <ul>
  374.      * <li>It has no visual effect
  375.      * </ul>
  376.      */
  377.     ITEM_TAKE("take", 40, 8),
  378.     /**
  379.      * A particle effect which is displayed by elder guardians:
  380.      * <ul>
  381.      * <li>It looks like the shape of the elder guardian
  382.      * <li>The speed value has no influence on this particle effect
  383.      * <li>The offset values have no influence on this particle effect
  384.      * </ul>
  385.      */
  386.     MOB_APPEARANCE("mobappearance", 41, 8);
  387.  
  388.     private static final Map<String, ParticleEffect> NAME_MAP = new HashMap<String, ParticleEffect>();
  389.     private static final Map<Integer, ParticleEffect> ID_MAP = new HashMap<Integer, ParticleEffect>();
  390.     private final String name;
  391.     private final int id;
  392.     private final int requiredVersion;
  393.     private final List<ParticleProperty> properties;
  394.  
  395.     // Initialize map for quick name and id lookup
  396.     static {
  397.         for (ParticleEffect effect : values()) {
  398.             NAME_MAP.put(effect.name, effect);
  399.             ID_MAP.put(effect.id, effect);
  400.         }
  401.     }
  402.  
  403.     /**
  404.      * Construct a new particle effect
  405.      *
  406.      * @param name Name of this particle effect
  407.      * @param id Id of this particle effect
  408.      * @param requiredVersion Version which is required (1.x)
  409.      * @param properties Properties of this particle effect
  410.      */
  411.     private ParticleEffect(String name, int id, int requiredVersion, ParticleProperty... properties) {
  412.         this.name = name;
  413.         this.id = id;
  414.         this.requiredVersion = requiredVersion;
  415.         this.properties = Arrays.asList(properties);
  416.     }
  417.  
  418.     /**
  419.      * Returns the name of this particle effect
  420.      *
  421.      * @return The name
  422.      */
  423.     public String getName() {
  424.         return name;
  425.     }
  426.  
  427.     /**
  428.      * Returns the id of this particle effect
  429.      *
  430.      * @return The id
  431.      */
  432.     public int getId() {
  433.         return id;
  434.     }
  435.  
  436.     /**
  437.      * Returns the required version for this particle effect (1.x)
  438.      *
  439.      * @return The required version
  440.      */
  441.     public int getRequiredVersion() {
  442.         return requiredVersion;
  443.     }
  444.  
  445.     /**
  446.      * Determine if this particle effect has a specific property
  447.      *
  448.      * @return Whether it has the property or not
  449.      */
  450.     public boolean hasProperty(ParticleProperty property) {
  451.         return properties.contains(property);
  452.     }
  453.  
  454.     /**
  455.      * Determine if this particle effect is supported by your current server version
  456.      *
  457.      * @return Whether the particle effect is supported or not
  458.      */
  459.     public boolean isSupported() {
  460.         if (requiredVersion == -1) {
  461.             return true;
  462.         }
  463.         return ParticlePacket.getVersion() >= requiredVersion;
  464.     }
  465.  
  466.     /**
  467.      * Returns the particle effect with the given name
  468.      *
  469.      * @param name Name of the particle effect
  470.      * @return The particle effect
  471.      */
  472.     public static ParticleEffect fromName(String name) {
  473.         for (Entry<String, ParticleEffect> entry : NAME_MAP.entrySet()) {
  474.             if (!entry.getKey().equalsIgnoreCase(name)) {
  475.                 continue;
  476.             }
  477.             return entry.getValue();
  478.         }
  479.         return null;
  480.     }
  481.  
  482.     /**
  483.      * Returns the particle effect with the given id
  484.      *
  485.      * @param id Id of the particle effect
  486.      * @return The particle effect
  487.      */
  488.     public static ParticleEffect fromId(int id) {
  489.         for (Entry<Integer, ParticleEffect> entry : ID_MAP.entrySet()) {
  490.             if (entry.getKey() != id) {
  491.                 continue;
  492.             }
  493.             return entry.getValue();
  494.         }
  495.         return null;
  496.     }
  497.  
  498.     /**
  499.      * Determine if water is at a certain location
  500.      *
  501.      * @param location Location to check
  502.      * @return Whether water is at this location or not
  503.      */
  504.     private static boolean isWater(Location location) {
  505.         Material material = location.getBlock().getType();
  506.         return material == Material.WATER || material == Material.STATIONARY_WATER;
  507.     }
  508.  
  509.     /**
  510.      * Determine if the distance between @param location and one of the players exceeds 256
  511.      *
  512.      * @param location Location to check
  513.      * @return Whether the distance exceeds 256 or not
  514.      */
  515.     private static boolean isLongDistance(Location location, List<Player> players) {
  516.         String world = location.getWorld().getName();
  517.         for (Player player : players) {
  518.             Location playerLocation = player.getLocation();
  519.             if (!world.equals(playerLocation.getWorld().getName()) || playerLocation.distanceSquared(location) < 65536) {
  520.                 continue;
  521.             }
  522.             return true;
  523.         }
  524.         return false;
  525.     }
  526.  
  527.     /**
  528.      * Determine if the data type for a particle effect is correct
  529.      *
  530.      * @param effect Particle effect
  531.      * @param data Particle data
  532.      * @return Whether the data type is correct or not
  533.      */
  534.     private static boolean isDataCorrect(ParticleEffect effect, ParticleData data) {
  535.         return ((effect == BLOCK_CRACK || effect == BLOCK_DUST) && data instanceof BlockData) || (effect == ITEM_CRACK && data instanceof ItemData);
  536.     }
  537.  
  538.     /**
  539.      * Determine if the color type for a particle effect is correct
  540.      *
  541.      * @param effect Particle effect
  542.      * @param color Particle color
  543.      * @return Whether the color type is correct or not
  544.      */
  545.     private static boolean isColorCorrect(ParticleEffect effect, ParticleColor color) {
  546.         return ((effect == SPELL_MOB || effect == SPELL_MOB_AMBIENT || effect == REDSTONE) && color instanceof OrdinaryColor) || (effect == NOTE && color instanceof NoteColor);
  547.     }
  548.  
  549.     /**
  550.      * Displays a particle effect which is only visible for all players within a certain range in the world of @param center
  551.      *
  552.      * @param offsetX Maximum distance particles can fly away from the center on the x-axis
  553.      * @param offsetY Maximum distance particles can fly away from the center on the y-axis
  554.      * @param offsetZ Maximum distance particles can fly away from the center on the z-axis
  555.      * @param speed Display speed of the particles
  556.      * @param amount Amount of particles
  557.      * @param center Center location of the effect
  558.      * @param range Range of the visibility
  559.      * @throws ParticleVersionException If the particle effect is not supported by the server version
  560.      * @throws ParticleDataException If the particle effect requires additional data
  561.      * @throws IllegalArgumentException If the particle effect requires water and none is at the center location
  562.      * @see ParticlePacket
  563.      * @see ParticlePacket#sendTo(Location, double)
  564.      */
  565.     public void display(float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, double range) throws ParticleVersionException, ParticleDataException, IllegalArgumentException {
  566.         if (!isSupported()) {
  567.             throw new ParticleVersionException("This particle effect is not supported by your server version");
  568.         }
  569.         if (hasProperty(ParticleProperty.REQUIRES_DATA)) {
  570.             throw new ParticleDataException("This particle effect requires additional data");
  571.         }
  572.         if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) {
  573.             throw new IllegalArgumentException("There is no water at the center location");
  574.         }
  575.         new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, range > 256, null).sendTo(center, range);
  576.     }
  577.  
  578.     /**
  579.      * Displays a particle effect which is only visible for the specified players
  580.      *
  581.      * @param offsetX Maximum distance particles can fly away from the center on the x-axis
  582.      * @param offsetY Maximum distance particles can fly away from the center on the y-axis
  583.      * @param offsetZ Maximum distance particles can fly away from the center on the z-axis
  584.      * @param speed Display speed of the particles
  585.      * @param amount Amount of particles
  586.      * @param center Center location of the effect
  587.      * @param players Receivers of the effect
  588.      * @throws ParticleVersionException If the particle effect is not supported by the server version
  589.      * @throws ParticleDataException If the particle effect requires additional data
  590.      * @throws IllegalArgumentException If the particle effect requires water and none is at the center location
  591.      * @see ParticlePacket
  592.      * @see ParticlePacket#sendTo(Location, List)
  593.      */
  594.     public void display(float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, List<Player> players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException {
  595.         if (!isSupported()) {
  596.             throw new ParticleVersionException("This particle effect is not supported by your server version");
  597.         }
  598.         if (hasProperty(ParticleProperty.REQUIRES_DATA)) {
  599.             throw new ParticleDataException("This particle effect requires additional data");
  600.         }
  601.         if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) {
  602.             throw new IllegalArgumentException("There is no water at the center location");
  603.         }
  604.         new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, isLongDistance(center, players), null).sendTo(center, players);
  605.     }
  606.  
  607.     /**
  608.      * Displays a particle effect which is only visible for the specified players
  609.      *
  610.      * @param offsetX Maximum distance particles can fly away from the center on the x-axis
  611.      * @param offsetY Maximum distance particles can fly away from the center on the y-axis
  612.      * @param offsetZ Maximum distance particles can fly away from the center on the z-axis
  613.      * @param speed Display speed of the particles
  614.      * @param amount Amount of particles
  615.      * @param center Center location of the effect
  616.      * @param players Receivers of the effect
  617.      * @throws ParticleVersionException If the particle effect is not supported by the server version
  618.      * @throws ParticleDataException If the particle effect requires additional data
  619.      * @throws IllegalArgumentException If the particle effect requires water and none is at the center location
  620.      * @see #display(float, float, float, float, int, Location, List)
  621.      */
  622.     public void display(float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, Player... players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException {
  623.         display(offsetX, offsetY, offsetZ, speed, amount, center, Arrays.asList(players));
  624.     }
  625.  
  626.     /**
  627.      * Displays a single particle which flies into a determined direction and is only visible for all players within a certain range in the world of @param center
  628.      *
  629.      * @param direction Direction of the particle
  630.      * @param speed Display speed of the particle
  631.      * @param center Center location of the effect
  632.      * @param range Range of the visibility
  633.      * @throws ParticleVersionException If the particle effect is not supported by the server version
  634.      * @throws ParticleDataException If the particle effect requires additional data
  635.      * @throws IllegalArgumentException If the particle effect is not directional or if it requires water and none is at the center location
  636.      * @see ParticlePacket#ParticlePacket(ParticleEffect, Vector, float, boolean, ParticleData)
  637.      * @see ParticlePacket#sendTo(Location, double)
  638.      */
  639.     public void display(Vector direction, float speed, Location center, double range) throws ParticleVersionException, ParticleDataException, IllegalArgumentException {
  640.         if (!isSupported()) {
  641.             throw new ParticleVersionException("This particle effect is not supported by your server version");
  642.         }
  643.         if (hasProperty(ParticleProperty.REQUIRES_DATA)) {
  644.             throw new ParticleDataException("This particle effect requires additional data");
  645.         }
  646.         if (!hasProperty(ParticleProperty.DIRECTIONAL)) {
  647.             throw new IllegalArgumentException("This particle effect is not directional");
  648.         }
  649.         if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) {
  650.             throw new IllegalArgumentException("There is no water at the center location");
  651.         }
  652.         new ParticlePacket(this, direction, speed, range > 256, null).sendTo(center, range);
  653.     }
  654.  
  655.     /**
  656.      * Displays a single particle which flies into a determined direction and is only visible for the specified players
  657.      *
  658.      * @param direction Direction of the particle
  659.      * @param speed Display speed of the particle
  660.      * @param center Center location of the effect
  661.      * @param players Receivers of the effect
  662.      * @throws ParticleVersionException If the particle effect is not supported by the server version
  663.      * @throws ParticleDataException If the particle effect requires additional data
  664.      * @throws IllegalArgumentException If the particle effect is not directional or if it requires water and none is at the center location
  665.      * @see ParticlePacket#ParticlePacket(ParticleEffect, Vector, float, boolean, ParticleData)
  666.      * @see ParticlePacket#sendTo(Location, List)
  667.      */
  668.     public void display(Vector direction, float speed, Location center, List<Player> players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException {
  669.         if (!isSupported()) {
  670.             throw new ParticleVersionException("This particle effect is not supported by your server version");
  671.         }
  672.         if (hasProperty(ParticleProperty.REQUIRES_DATA)) {
  673.             throw new ParticleDataException("This particle effect requires additional data");
  674.         }
  675.         if (!hasProperty(ParticleProperty.DIRECTIONAL)) {
  676.             throw new IllegalArgumentException("This particle effect is not directional");
  677.         }
  678.         if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) {
  679.             throw new IllegalArgumentException("There is no water at the center location");
  680.         }
  681.         new ParticlePacket(this, direction, speed, isLongDistance(center, players), null).sendTo(center, players);
  682.     }
  683.  
  684.     /**
  685.      * Displays a single particle which flies into a determined direction and is only visible for the specified players
  686.      *
  687.      * @param direction Direction of the particle
  688.      * @param speed Display speed of the particle
  689.      * @param center Center location of the effect
  690.      * @param players Receivers of the effect
  691.      * @throws ParticleVersionException If the particle effect is not supported by the server version
  692.      * @throws ParticleDataException If the particle effect requires additional data
  693.      * @throws IllegalArgumentException If the particle effect is not directional or if it requires water and none is at the center location
  694.      * @see #display(Vector, float, Location, List)
  695.      */
  696.     public void display(Vector direction, float speed, Location center, Player... players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException {
  697.         display(direction, speed, center, Arrays.asList(players));
  698.     }
  699.  
  700.     /**
  701.      * Displays a single particle which is colored and only visible for all players within a certain range in the world of @param center
  702.      *
  703.      * @param color Color of the particle
  704.      * @param center Center location of the effect
  705.      * @param range Range of the visibility
  706.      * @throws ParticleVersionException If the particle effect is not supported by the server version
  707.      * @throws ParticleColorException If the particle effect is not colorable or the color type is incorrect
  708.      * @see ParticlePacket#ParticlePacket(ParticleEffect, ParticleColor, boolean)
  709.      * @see ParticlePacket#sendTo(Location, double)
  710.      */
  711.     public void display(ParticleColor color, Location center, double range) throws ParticleVersionException, ParticleColorException {
  712.         if (!isSupported()) {
  713.             throw new ParticleVersionException("This particle effect is not supported by your server version");
  714.         }
  715.         if (!hasProperty(ParticleProperty.COLORABLE)) {
  716.             throw new ParticleColorException("This particle effect is not colorable");
  717.         }
  718.         if (!isColorCorrect(this, color)) {
  719.             throw new ParticleColorException("The particle color type is incorrect");
  720.         }
  721.         new ParticlePacket(this, color, range > 256).sendTo(center, range);
  722.     }
  723.  
  724.     /**
  725.      * Displays a single particle which is colored and only visible for the specified players
  726.      *
  727.      * @param color Color of the particle
  728.      * @param center Center location of the effect
  729.      * @param players Receivers of the effect
  730.      * @throws ParticleVersionException If the particle effect is not supported by the server version
  731.      * @throws ParticleColorException If the particle effect is not colorable or the color type is incorrect
  732.      * @see ParticlePacket#ParticlePacket(ParticleEffect, ParticleColor, boolean)
  733.      * @see ParticlePacket#sendTo(Location, List)
  734.      */
  735.     public void display(ParticleColor color, Location center, List<Player> players) throws ParticleVersionException, ParticleColorException {
  736.         if (!isSupported()) {
  737.             throw new ParticleVersionException("This particle effect is not supported by your server version");
  738.         }
  739.         if (!hasProperty(ParticleProperty.COLORABLE)) {
  740.             throw new ParticleColorException("This particle effect is not colorable");
  741.         }
  742.         if (!isColorCorrect(this, color)) {
  743.             throw new ParticleColorException("The particle color type is incorrect");
  744.         }
  745.         new ParticlePacket(this, color, isLongDistance(center, players)).sendTo(center, players);
  746.     }
  747.  
  748.     /**
  749.      * Displays a single particle which is colored and only visible for the specified players
  750.      *
  751.      * @param color Color of the particle
  752.      * @param center Center location of the effect
  753.      * @param players Receivers of the effect
  754.      * @throws ParticleVersionException If the particle effect is not supported by the server version
  755.      * @throws ParticleColorException If the particle effect is not colorable or the color type is incorrect
  756.      * @see #display(ParticleColor, Location, List)
  757.      */
  758.     public void display(ParticleColor color, Location center, Player... players) throws ParticleVersionException, ParticleColorException {
  759.         display(color, center, Arrays.asList(players));
  760.     }
  761.  
  762.     /**
  763.      * Displays a particle effect which requires additional data and is only visible for all players within a certain range in the world of @param center
  764.      *
  765.      * @param data Data of the effect
  766.      * @param offsetX Maximum distance particles can fly away from the center on the x-axis
  767.      * @param offsetY Maximum distance particles can fly away from the center on the y-axis
  768.      * @param offsetZ Maximum distance particles can fly away from the center on the z-axis
  769.      * @param speed Display speed of the particles
  770.      * @param amount Amount of particles
  771.      * @param center Center location of the effect
  772.      * @param range Range of the visibility
  773.      * @throws ParticleVersionException If the particle effect is not supported by the server version
  774.      * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect
  775.      * @see ParticlePacket
  776.      * @see ParticlePacket#sendTo(Location, double)
  777.      */
  778.     public void display(ParticleData data, float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, double range) throws ParticleVersionException, ParticleDataException {
  779.         if (!isSupported()) {
  780.             throw new ParticleVersionException("This particle effect is not supported by your server version");
  781.         }
  782.         if (!hasProperty(ParticleProperty.REQUIRES_DATA)) {
  783.             throw new ParticleDataException("This particle effect does not require additional data");
  784.         }
  785.         if (!isDataCorrect(this, data)) {
  786.             throw new ParticleDataException("The particle data type is incorrect");
  787.         }
  788.         new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, range > 256, data).sendTo(center, range);
  789.     }
  790.  
  791.     /**
  792.      * Displays a particle effect which requires additional data and is only visible for the specified players
  793.      *
  794.      * @param data Data of the effect
  795.      * @param offsetX Maximum distance particles can fly away from the center on the x-axis
  796.      * @param offsetY Maximum distance particles can fly away from the center on the y-axis
  797.      * @param offsetZ Maximum distance particles can fly away from the center on the z-axis
  798.      * @param speed Display speed of the particles
  799.      * @param amount Amount of particles
  800.      * @param center Center location of the effect
  801.      * @param players Receivers of the effect
  802.      * @throws ParticleVersionException If the particle effect is not supported by the server version
  803.      * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect
  804.      * @see ParticlePacket
  805.      * @see ParticlePacket#sendTo(Location, List)
  806.      */
  807.     public void display(ParticleData data, float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, List<Player> players) throws ParticleVersionException, ParticleDataException {
  808.         if (!isSupported()) {
  809.             throw new ParticleVersionException("This particle effect is not supported by your server version");
  810.         }
  811.         if (!hasProperty(ParticleProperty.REQUIRES_DATA)) {
  812.             throw new ParticleDataException("This particle effect does not require additional data");
  813.         }
  814.         if (!isDataCorrect(this, data)) {
  815.             throw new ParticleDataException("The particle data type is incorrect");
  816.         }
  817.         new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, isLongDistance(center, players), data).sendTo(center, players);
  818.     }
  819.  
  820.     /**
  821.      * Displays a particle effect which requires additional data and is only visible for the specified players
  822.      *
  823.      * @param data Data of the effect
  824.      * @param offsetX Maximum distance particles can fly away from the center on the x-axis
  825.      * @param offsetY Maximum distance particles can fly away from the center on the y-axis
  826.      * @param offsetZ Maximum distance particles can fly away from the center on the z-axis
  827.      * @param speed Display speed of the particles
  828.      * @param amount Amount of particles
  829.      * @param center Center location of the effect
  830.      * @param players Receivers of the effect
  831.      * @throws ParticleVersionException If the particle effect is not supported by the server version
  832.      * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect
  833.      * @see #display(ParticleData, float, float, float, float, int, Location, List)
  834.      */
  835.     public void display(ParticleData data, float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, Player... players) throws ParticleVersionException, ParticleDataException {
  836.         display(data, offsetX, offsetY, offsetZ, speed, amount, center, Arrays.asList(players));
  837.     }
  838.  
  839.     /**
  840.      * Displays a single particle which requires additional data that flies into a determined direction and is only visible for all players within a certain range in the world of @param center
  841.      *
  842.      * @param data Data of the effect
  843.      * @param direction Direction of the particle
  844.      * @param speed Display speed of the particles
  845.      * @param center Center location of the effect
  846.      * @param range Range of the visibility
  847.      * @throws ParticleVersionException If the particle effect is not supported by the server version
  848.      * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect
  849.      * @see ParticlePacket
  850.      * @see ParticlePacket#sendTo(Location, double)
  851.      */
  852.     public void display(ParticleData data, Vector direction, float speed, Location center, double range) throws ParticleVersionException, ParticleDataException {
  853.         if (!isSupported()) {
  854.             throw new ParticleVersionException("This particle effect is not supported by your server version");
  855.         }
  856.         if (!hasProperty(ParticleProperty.REQUIRES_DATA)) {
  857.             throw new ParticleDataException("This particle effect does not require additional data");
  858.         }
  859.         if (!isDataCorrect(this, data)) {
  860.             throw new ParticleDataException("The particle data type is incorrect");
  861.         }
  862.         new ParticlePacket(this, direction, speed, range > 256, data).sendTo(center, range);
  863.     }
  864.  
  865.     /**
  866.      * Displays a single particle which requires additional data that flies into a determined direction and is only visible for the specified players
  867.      *
  868.      * @param data Data of the effect
  869.      * @param direction Direction of the particle
  870.      * @param speed Display speed of the particles
  871.      * @param center Center location of the effect
  872.      * @param players Receivers of the effect
  873.      * @throws ParticleVersionException If the particle effect is not supported by the server version
  874.      * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect
  875.      * @see ParticlePacket
  876.      * @see ParticlePacket#sendTo(Location, List)
  877.      */
  878.     public void display(ParticleData data, Vector direction, float speed, Location center, List<Player> players) throws ParticleVersionException, ParticleDataException {
  879.         if (!isSupported()) {
  880.             throw new ParticleVersionException("This particle effect is not supported by your server version");
  881.         }
  882.         if (!hasProperty(ParticleProperty.REQUIRES_DATA)) {
  883.             throw new ParticleDataException("This particle effect does not require additional data");
  884.         }
  885.         if (!isDataCorrect(this, data)) {
  886.             throw new ParticleDataException("The particle data type is incorrect");
  887.         }
  888.         new ParticlePacket(this, direction, speed, isLongDistance(center, players), data).sendTo(center, players);
  889.     }
  890.  
  891.     /**
  892.      * Displays a single particle which requires additional data that flies into a determined direction and is only visible for the specified players
  893.      *
  894.      * @param data Data of the effect
  895.      * @param direction Direction of the particle
  896.      * @param speed Display speed of the particles
  897.      * @param center Center location of the effect
  898.      * @param players Receivers of the effect
  899.      * @throws ParticleVersionException If the particle effect is not supported by the server version
  900.      * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect
  901.      * @see #display(ParticleData, Vector, float, Location, List)
  902.      */
  903.     public void display(ParticleData data, Vector direction, float speed, Location center, Player... players) throws ParticleVersionException, ParticleDataException {
  904.         display(data, direction, speed, center, Arrays.asList(players));
  905.     }
  906.  
  907.     /**
  908.      * Represents the property of a particle effect
  909.      * <p>
  910.      * This class is part of the <b>ParticleEffect Library</b> and follows the same usage conditions
  911.      *
  912.      * @author DarkBlade12
  913.      * @since 1.7
  914.      */
  915.     public static enum ParticleProperty {
  916.         /**
  917.          * The particle effect requires water to be displayed
  918.          */
  919.         REQUIRES_WATER,
  920.         /**
  921.          * The particle effect requires block or item data to be displayed
  922.          */
  923.         REQUIRES_DATA,
  924.         /**
  925.          * The particle effect uses the offsets as direction values
  926.          */
  927.         DIRECTIONAL,
  928.         /**
  929.          * The particle effect uses the offsets as color values
  930.          */
  931.         COLORABLE;
  932.     }
  933.  
  934.     /**
  935.      * Represents the particle data for effects like {@link ParticleEffect#ITEM_CRACK}, {@link ParticleEffect#BLOCK_CRACK} and {@link ParticleEffect#BLOCK_DUST}
  936.      * <p>
  937.      * This class is part of the <b>ParticleEffect Library</b> and follows the same usage conditions
  938.      *
  939.      * @author DarkBlade12
  940.      * @since 1.6
  941.      */
  942.     public static abstract class ParticleData {
  943.         private final Material material;
  944.         private final byte data;
  945.         private final int[] packetData;
  946.  
  947.         /**
  948.          * Construct a new particle data
  949.          *
  950.          * @param material Material of the item/block
  951.          * @param data Data value of the item/block
  952.          */
  953.         @SuppressWarnings("deprecation")
  954.         public ParticleData(Material material, byte data) {
  955.             this.material = material;
  956.             this.data = data;
  957.             this.packetData = new int[] { material.getId(), data };
  958.         }
  959.  
  960.         /**
  961.          * Returns the material of this data
  962.          *
  963.          * @return The material
  964.          */
  965.         public Material getMaterial() {
  966.             return material;
  967.         }
  968.  
  969.         /**
  970.          * Returns the data value of this data
  971.          *
  972.          * @return The data value
  973.          */
  974.         public byte getData() {
  975.             return data;
  976.         }
  977.  
  978.         /**
  979.          * Returns the data as an int array for packet construction
  980.          *
  981.          * @return The data for the packet
  982.          */
  983.         public int[] getPacketData() {
  984.             return packetData;
  985.         }
  986.  
  987.         /**
  988.          * Returns the data as a string for pre 1.8 versions
  989.          *
  990.          * @return The data string for the packet
  991.          */
  992.         public String getPacketDataString() {
  993.             return "_" + packetData[0] + "_" + packetData[1];
  994.         }
  995.     }
  996.  
  997.     /**
  998.      * Represents the item data for the {@link ParticleEffect#ITEM_CRACK} effect
  999.      * <p>
  1000.      * This class is part of the <b>ParticleEffect Library</b> and follows the same usage conditions
  1001.      *
  1002.      * @author DarkBlade12
  1003.      * @since 1.6
  1004.      */
  1005.     public static final class ItemData extends ParticleData {
  1006.         /**
  1007.          * Construct a new item data
  1008.          *
  1009.          * @param material Material of the item
  1010.          * @param data Data value of the item
  1011.          * @see ParticleData#ParticleData(Material, byte)
  1012.          */
  1013.         public ItemData(Material material, byte data) {
  1014.             super(material, data);
  1015.         }
  1016.     }
  1017.  
  1018.     /**
  1019.      * Represents the block data for the {@link ParticleEffect#BLOCK_CRACK} and {@link ParticleEffect#BLOCK_DUST} effects
  1020.      * <p>
  1021.      * This class is part of the <b>ParticleEffect Library</b> and follows the same usage conditions
  1022.      *
  1023.      * @author DarkBlade12
  1024.      * @since 1.6
  1025.      */
  1026.     public static final class BlockData extends ParticleData {
  1027.         /**
  1028.          * Construct a new block data
  1029.          *
  1030.          * @param material Material of the block
  1031.          * @param data Data value of the block
  1032.          * @throws IllegalArgumentException If the material is not a block
  1033.          * @see ParticleData#ParticleData(Material, byte)
  1034.          */
  1035.         public BlockData(Material material, byte data) throws IllegalArgumentException {
  1036.             super(material, data);
  1037.             if (!material.isBlock()) {
  1038.                 throw new IllegalArgumentException("The material is not a block");
  1039.             }
  1040.         }
  1041.     }
  1042.  
  1043.     /**
  1044.      * Represents the color for effects like {@link ParticleEffect#SPELL_MOB}, {@link ParticleEffect#SPELL_MOB_AMBIENT}, {@link ParticleEffect#REDSTONE} and {@link ParticleEffect#NOTE}
  1045.      * <p>
  1046.      * This class is part of the <b>ParticleEffect Library</b> and follows the same usage conditions
  1047.      *
  1048.      * @author DarkBlade12
  1049.      * @since 1.7
  1050.      */
  1051.     public static abstract class ParticleColor {
  1052.         /**
  1053.          * Returns the value for the offsetX field
  1054.          *
  1055.          * @return The offsetX value
  1056.          */
  1057.         public abstract float getValueX();
  1058.  
  1059.         /**
  1060.          * Returns the value for the offsetY field
  1061.          *
  1062.          * @return The offsetY value
  1063.          */
  1064.         public abstract float getValueY();
  1065.  
  1066.         /**
  1067.          * Returns the value for the offsetZ field
  1068.          *
  1069.          * @return The offsetZ value
  1070.          */
  1071.         public abstract float getValueZ();
  1072.     }
  1073.  
  1074.     /**
  1075.      * Represents the color for effects like {@link ParticleEffect#SPELL_MOB}, {@link ParticleEffect#SPELL_MOB_AMBIENT} and {@link ParticleEffect#NOTE}
  1076.      * <p>
  1077.      * This class is part of the <b>ParticleEffect Library</b> and follows the same usage conditions
  1078.      *
  1079.      * @author DarkBlade12
  1080.      * @since 1.7
  1081.      */
  1082.     public static final class OrdinaryColor extends ParticleColor {
  1083.         private final int red;
  1084.         private final int green;
  1085.         private final int blue;
  1086.  
  1087.         /**
  1088.          * Construct a new ordinary color
  1089.          *
  1090.          * @param red Red value of the RGB format
  1091.          * @param green Green value of the RGB format
  1092.          * @param blue Blue value of the RGB format
  1093.          * @throws IllegalArgumentException If one of the values is lower than 0 or higher than 255
  1094.          */
  1095.         public OrdinaryColor(int red, int green, int blue) throws IllegalArgumentException {
  1096.             if (red < 0) {
  1097.                 throw new IllegalArgumentException("The red value is lower than 0");
  1098.             }
  1099.             if (red > 255) {
  1100.                 throw new IllegalArgumentException("The red value is higher than 255");
  1101.             }
  1102.             this.red = red;
  1103.             if (green < 0) {
  1104.                 throw new IllegalArgumentException("The green value is lower than 0");
  1105.             }
  1106.             if (green > 255) {
  1107.                 throw new IllegalArgumentException("The green value is higher than 255");
  1108.             }
  1109.             this.green = green;
  1110.             if (blue < 0) {
  1111.                 throw new IllegalArgumentException("The blue value is lower than 0");
  1112.             }
  1113.             if (blue > 255) {
  1114.                 throw new IllegalArgumentException("The blue value is higher than 255");
  1115.             }
  1116.             this.blue = blue;
  1117.         }
  1118.  
  1119.         /**
  1120.          * Construct a new ordinary color
  1121.          *
  1122.          * @param color Bukkit color
  1123.          */
  1124.         public OrdinaryColor(Color color) {
  1125.             this(color.getRed(), color.getGreen(), color.getBlue());
  1126.         }
  1127.  
  1128.         /**
  1129.          * Returns the red value of the RGB format
  1130.          *
  1131.          * @return The red value
  1132.          */
  1133.         public int getRed() {
  1134.             return red;
  1135.         }
  1136.  
  1137.         /**
  1138.          * Returns the green value of the RGB format
  1139.          *
  1140.          * @return The green value
  1141.          */
  1142.         public int getGreen() {
  1143.             return green;
  1144.         }
  1145.  
  1146.         /**
  1147.          * Returns the blue value of the RGB format
  1148.          *
  1149.          * @return The blue value
  1150.          */
  1151.         public int getBlue() {
  1152.             return blue;
  1153.         }
  1154.  
  1155.         /**
  1156.          * Returns the red value divided by 255
  1157.          *
  1158.          * @return The offsetX value
  1159.          */
  1160.         @Override
  1161.         public float getValueX() {
  1162.             return (float) red / 255F;
  1163.         }
  1164.  
  1165.         /**
  1166.          * Returns the green value divided by 255
  1167.          *
  1168.          * @return The offsetY value
  1169.          */
  1170.         @Override
  1171.         public float getValueY() {
  1172.             return (float) green / 255F;
  1173.         }
  1174.  
  1175.         /**
  1176.          * Returns the blue value divided by 255
  1177.          *
  1178.          * @return The offsetZ value
  1179.          */
  1180.         @Override
  1181.         public float getValueZ() {
  1182.             return (float) blue / 255F;
  1183.         }
  1184.     }
  1185.  
  1186.     /**
  1187.      * Represents the color for the {@link ParticleEffect#NOTE} effect
  1188.      * <p>
  1189.      * This class is part of the <b>ParticleEffect Library</b> and follows the same usage conditions
  1190.      *
  1191.      * @author DarkBlade12
  1192.      * @since 1.7
  1193.      */
  1194.     public static final class NoteColor extends ParticleColor {
  1195.         private final int note;
  1196.  
  1197.         /**
  1198.          * Construct a new note color
  1199.          *
  1200.          * @param note Note id which determines color
  1201.          * @throws IllegalArgumentException If the note value is lower than 0 or higher than 24
  1202.          */
  1203.         public NoteColor(int note) throws IllegalArgumentException {
  1204.             if (note < 0) {
  1205.                 throw new IllegalArgumentException("The note value is lower than 0");
  1206.             }
  1207.             if (note > 24) {
  1208.                 throw new IllegalArgumentException("The note value is higher than 24");
  1209.             }
  1210.             this.note = note;
  1211.         }
  1212.  
  1213.         /**
  1214.          * Returns the note value divided by 24
  1215.          *
  1216.          * @return The offsetX value
  1217.          */
  1218.         @Override
  1219.         public float getValueX() {
  1220.             return (float) note / 24F;
  1221.         }
  1222.  
  1223.         /**
  1224.          * Returns zero because the offsetY value is unused
  1225.          *
  1226.          * @return zero
  1227.          */
  1228.         @Override
  1229.         public float getValueY() {
  1230.             return 0;
  1231.         }
  1232.  
  1233.         /**
  1234.          * Returns zero because the offsetZ value is unused
  1235.          *
  1236.          * @return zero
  1237.          */
  1238.         @Override
  1239.         public float getValueZ() {
  1240.             return 0;
  1241.         }
  1242.  
  1243.     }
  1244.  
  1245.     /**
  1246.      * Represents a runtime exception that is thrown either if the displayed particle effect requires data and has none or vice-versa or if the data type is incorrect
  1247.      * <p>
  1248.      * This class is part of the <b>ParticleEffect Library</b> and follows the same usage conditions
  1249.      *
  1250.      * @author DarkBlade12
  1251.      * @since 1.6
  1252.      */
  1253.     private static final class ParticleDataException extends RuntimeException {
  1254.         private static final long serialVersionUID = 3203085387160737484L;
  1255.  
  1256.         /**
  1257.          * Construct a new particle data exception
  1258.          *
  1259.          * @param message Message that will be logged
  1260.          */
  1261.         public ParticleDataException(String message) {
  1262.             super(message);
  1263.         }
  1264.     }
  1265.  
  1266.     /**
  1267.      * Represents a runtime exception that is thrown either if the displayed particle effect is not colorable or if the particle color type is incorrect
  1268.      * <p>
  1269.      * This class is part of the <b>ParticleEffect Library</b> and follows the same usage conditions
  1270.      *
  1271.      * @author DarkBlade12
  1272.      * @since 1.7
  1273.      */
  1274.     private static final class ParticleColorException extends RuntimeException {
  1275.         private static final long serialVersionUID = 3203085387160737484L;
  1276.  
  1277.         /**
  1278.          * Construct a new particle color exception
  1279.          *
  1280.          * @param message Message that will be logged
  1281.          */
  1282.         public ParticleColorException(String message) {
  1283.             super(message);
  1284.         }
  1285.     }
  1286.  
  1287.     /**
  1288.      * Represents a runtime exception that is thrown if the displayed particle effect requires a newer version
  1289.      * <p>
  1290.      * This class is part of the <b>ParticleEffect Library</b> and follows the same usage conditions
  1291.      *
  1292.      * @author DarkBlade12
  1293.      * @since 1.6
  1294.      */
  1295.     private static final class ParticleVersionException extends RuntimeException {
  1296.         private static final long serialVersionUID = 3203085387160737484L;
  1297.  
  1298.         /**
  1299.          * Construct a new particle version exception
  1300.          *
  1301.          * @param message Message that will be logged
  1302.          */
  1303.         public ParticleVersionException(String message) {
  1304.             super(message);
  1305.         }
  1306.     }
  1307.  
  1308.     /**
  1309.      * Represents a particle effect packet with all attributes which is used for sending packets to the players
  1310.      * <p>
  1311.      * This class is part of the <b>ParticleEffect Library</b> and follows the same usage conditions
  1312.      *
  1313.      * @author DarkBlade12
  1314.      * @since 1.5
  1315.      */
  1316.     public static final class ParticlePacket {
  1317.         private static int version;
  1318.         private static Class<?> enumParticle;
  1319.         private static Constructor<?> packetConstructor;
  1320.         private static Method getHandle;
  1321.         private static Field playerConnection;
  1322.         private static Method sendPacket;
  1323.         private static boolean initialized;
  1324.         private final ParticleEffect effect;
  1325.         private float offsetX;
  1326.         private final float offsetY;
  1327.         private final float offsetZ;
  1328.         private final float speed;
  1329.         private final int amount;
  1330.         private final boolean longDistance;
  1331.         private final ParticleData data;
  1332.         private Object packet;
  1333.  
  1334.         /**
  1335.          * Construct a new particle packet
  1336.          *
  1337.          * @param effect Particle effect
  1338.          * @param offsetX Maximum distance particles can fly away from the center on the x-axis
  1339.          * @param offsetY Maximum distance particles can fly away from the center on the y-axis
  1340.          * @param offsetZ Maximum distance particles can fly away from the center on the z-axis
  1341.          * @param speed Display speed of the particles
  1342.          * @param amount Amount of particles
  1343.          * @param longDistance Indicates whether the maximum distance is increased from 256 to 65536
  1344.          * @param data Data of the effect
  1345.          * @throws IllegalArgumentException If the speed or amount is lower than 0
  1346.          * @see #initialize()
  1347.          */
  1348.         public ParticlePacket(ParticleEffect effect, float offsetX, float offsetY, float offsetZ, float speed, int amount, boolean longDistance, ParticleData data) throws IllegalArgumentException {
  1349.             initialize();
  1350.             if (speed < 0) {
  1351.                 throw new IllegalArgumentException("The speed is lower than 0");
  1352.             }
  1353.             if (amount < 0) {
  1354.                 throw new IllegalArgumentException("The amount is lower than 0");
  1355.             }
  1356.             this.effect = effect;
  1357.             this.offsetX = offsetX;
  1358.             this.offsetY = offsetY;
  1359.             this.offsetZ = offsetZ;
  1360.             this.speed = speed;
  1361.             this.amount = amount;
  1362.             this.longDistance = longDistance;
  1363.             this.data = data;
  1364.         }
  1365.  
  1366.         /**
  1367.          * Construct a new particle packet of a single particle flying into a determined direction
  1368.          *
  1369.          * @param effect Particle effect
  1370.          * @param direction Direction of the particle
  1371.          * @param speed Display speed of the particle
  1372.          * @param longDistance Indicates whether the maximum distance is increased from 256 to 65536
  1373.          * @param data Data of the effect
  1374.          * @throws IllegalArgumentException If the speed is lower than 0
  1375.          * @see #ParticleEffect(ParticleEffect, float, float, float, float, int, boolean, ParticleData)
  1376.          */
  1377.         public ParticlePacket(ParticleEffect effect, Vector direction, float speed, boolean longDistance, ParticleData data) throws IllegalArgumentException {
  1378.             this(effect, (float) direction.getX(), (float) direction.getY(), (float) direction.getZ(), speed, 0, longDistance, data);
  1379.         }
  1380.  
  1381.         /**
  1382.          * Construct a new particle packet of a single colored particle
  1383.          *
  1384.          * @param effect Particle effect
  1385.          * @param color Color of the particle
  1386.          * @param longDistance Indicates whether the maximum distance is increased from 256 to 65536
  1387.          * @see #ParticleEffect(ParticleEffect, float, float, float, float, int, boolean, ParticleData)
  1388.          */
  1389.         public ParticlePacket(ParticleEffect effect, ParticleColor color, boolean longDistance) {
  1390.             this(effect, color.getValueX(), color.getValueY(), color.getValueZ(), 1, 0, longDistance, null);
  1391.             if (effect == ParticleEffect.REDSTONE && color instanceof OrdinaryColor && ((OrdinaryColor) color).getRed() == 0) {
  1392.                 offsetX = Float.MIN_NORMAL;
  1393.             }
  1394.         }
  1395.  
  1396.         /**
  1397.          * Initializes {@link #packetConstructor}, {@link #getHandle}, {@link #playerConnection} and {@link #sendPacket} and sets {@link #initialized} to <code>true</code> if it succeeds
  1398.          * <p>
  1399.          * <b>Note:</b> These fields only have to be initialized once, so it will return if {@link #initialized} is already set to <code>true</code>
  1400.          *
  1401.          * @throws VersionIncompatibleException if your bukkit version is not supported by this library
  1402.          */
  1403.         public static void initialize() throws VersionIncompatibleException {
  1404.             if (initialized) {
  1405.                 return;
  1406.             }
  1407.             try {
  1408.                 version = Integer.parseInt(Character.toString(PackageType.getServerVersion().charAt(3)));
  1409.                 if (version > 7) {
  1410.                     enumParticle = PackageType.MINECRAFT_SERVER.getClass("EnumParticle");
  1411.                 }
  1412.                 Class<?> packetClass = PackageType.MINECRAFT_SERVER.getClass(version < 7 ? "Packet63WorldParticles" : "PacketPlayOutWorldParticles");
  1413.                 packetConstructor = ReflectionUtils.getConstructor(packetClass);
  1414.                 getHandle = ReflectionUtils.getMethod("CraftPlayer", PackageType.CRAFTBUKKIT_ENTITY, "getHandle");
  1415.                 playerConnection = ReflectionUtils.getField("EntityPlayer", PackageType.MINECRAFT_SERVER, false, "playerConnection");
  1416.                 sendPacket = ReflectionUtils.getMethod(playerConnection.getType(), "sendPacket", PackageType.MINECRAFT_SERVER.getClass("Packet"));
  1417.             } catch (Exception exception) {
  1418.                 throw new VersionIncompatibleException("Your current bukkit version seems to be incompatible with this library", exception);
  1419.             }
  1420.             initialized = true;
  1421.         }
  1422.  
  1423.         /**
  1424.          * Returns the version of your server (1.x)
  1425.          *
  1426.          * @return The version number
  1427.          */
  1428.         public static int getVersion() {
  1429.             if (!initialized) {
  1430.                 initialize();
  1431.             }
  1432.             return version;
  1433.         }
  1434.  
  1435.         /**
  1436.          * Determine if {@link #packetConstructor}, {@link #getHandle}, {@link #playerConnection} and {@link #sendPacket} are initialized
  1437.          *
  1438.          * @return Whether these fields are initialized or not
  1439.          * @see #initialize()
  1440.          */
  1441.         public static boolean isInitialized() {
  1442.             return initialized;
  1443.         }
  1444.  
  1445.         /**
  1446.          * Initializes {@link #packet} with all set values
  1447.          *
  1448.          * @param center Center location of the effect
  1449.          * @throws PacketInstantiationException If instantion fails due to an unknown error
  1450.          */
  1451.         private void initializePacket(Location center) throws PacketInstantiationException {
  1452.             if (packet != null) {
  1453.                 return;
  1454.             }
  1455.             try {
  1456.                 packet = packetConstructor.newInstance();
  1457.                 if (version < 8) {
  1458.                     String name = effect.getName();
  1459.                     if (data != null) {
  1460.                         name += data.getPacketDataString();
  1461.                     }
  1462.                     ReflectionUtils.setValue(packet, true, "a", name);
  1463.                 } else {
  1464.                     ReflectionUtils.setValue(packet, true, "a", enumParticle.getEnumConstants()[effect.getId()]);
  1465.                     ReflectionUtils.setValue(packet, true, "j", longDistance);
  1466.                     if (data != null) {
  1467.                         int[] packetData = data.getPacketData();
  1468.                         ReflectionUtils.setValue(packet, true, "k", effect == ParticleEffect.ITEM_CRACK ? packetData : new int[] { packetData[0] | (packetData[1] << 12) });
  1469.                     }
  1470.                 }
  1471.                 ReflectionUtils.setValue(packet, true, "b", (float) center.getX());
  1472.                 ReflectionUtils.setValue(packet, true, "c", (float) center.getY());
  1473.                 ReflectionUtils.setValue(packet, true, "d", (float) center.getZ());
  1474.                 ReflectionUtils.setValue(packet, true, "e", offsetX);
  1475.                 ReflectionUtils.setValue(packet, true, "f", offsetY);
  1476.                 ReflectionUtils.setValue(packet, true, "g", offsetZ);
  1477.                 ReflectionUtils.setValue(packet, true, "h", speed);
  1478.                 ReflectionUtils.setValue(packet, true, "i", amount);
  1479.             } catch (Exception exception) {
  1480.                 throw new PacketInstantiationException("Packet instantiation failed", exception);
  1481.             }
  1482.         }
  1483.  
  1484.         /**
  1485.          * Sends the packet to a single player and caches it
  1486.          *
  1487.          * @param center Center location of the effect
  1488.          * @param player Receiver of the packet
  1489.          * @throws PacketInstantiationException If instantion fails due to an unknown error
  1490.          * @throws PacketSendingException If sending fails due to an unknown error
  1491.          * @see #initializePacket(Location)
  1492.          */
  1493.         public void sendTo(Location center, Player player) throws PacketInstantiationException, PacketSendingException {
  1494.             initializePacket(center);
  1495.             try {
  1496.                 sendPacket.invoke(playerConnection.get(getHandle.invoke(player)), packet);
  1497.             } catch (Exception exception) {
  1498.                 throw new PacketSendingException("Failed to send the packet to player '" + player.getName() + "'", exception);
  1499.             }
  1500.         }
  1501.  
  1502.         /**
  1503.          * Sends the packet to all players in the list
  1504.          *
  1505.          * @param center Center location of the effect
  1506.          * @param players Receivers of the packet
  1507.          * @throws IllegalArgumentException If the player list is empty
  1508.          * @see #sendTo(Location center, Player player)
  1509.          */
  1510.         public void sendTo(Location center, List<Player> players) throws IllegalArgumentException {
  1511.             if (players.isEmpty()) {
  1512.                 throw new IllegalArgumentException("The player list is empty");
  1513.             }
  1514.             for (Player player : players) {
  1515.                 sendTo(center, player);
  1516.             }
  1517.         }
  1518.  
  1519.         /**
  1520.          * Sends the packet to all players in a certain range
  1521.          *
  1522.          * @param center Center location of the effect
  1523.          * @param range Range in which players will receive the packet (Maximum range for particles is usually 16, but it can differ for some types)
  1524.          * @throws IllegalArgumentException If the range is lower than 1
  1525.          * @see #sendTo(Location center, Player player)
  1526.          */
  1527.         public void sendTo(Location center, double range) throws IllegalArgumentException {
  1528.             if (range < 1) {
  1529.                 throw new IllegalArgumentException("The range is lower than 1");
  1530.             }
  1531.             String worldName = center.getWorld().getName();
  1532.             double squared = range * range;
  1533.             for (Player player : Bukkit.getOnlinePlayers()) {
  1534.                 if (!player.getWorld().getName().equals(worldName) || player.getLocation().distanceSquared(center) > squared) {
  1535.                     continue;
  1536.                 }
  1537.                 sendTo(center, player);
  1538.             }
  1539.         }
  1540.  
  1541.         /**
  1542.          * Represents a runtime exception that is thrown if a bukkit version is not compatible with this library
  1543.          * <p>
  1544.          * This class is part of the <b>ParticleEffect Library</b> and follows the same usage conditions
  1545.          *
  1546.          * @author DarkBlade12
  1547.          * @since 1.5
  1548.          */
  1549.         private static final class VersionIncompatibleException extends RuntimeException {
  1550.             private static final long serialVersionUID = 3203085387160737484L;
  1551.  
  1552.             /**
  1553.              * Construct a new version incompatible exception
  1554.              *
  1555.              * @param message Message that will be logged
  1556.              * @param cause Cause of the exception
  1557.              */
  1558.             public VersionIncompatibleException(String message, Throwable cause) {
  1559.                 super(message, cause);
  1560.             }
  1561.         }
  1562.  
  1563.         /**
  1564.          * Represents a runtime exception that is thrown if packet instantiation fails
  1565.          * <p>
  1566.          * This class is part of the <b>ParticleEffect Library</b> and follows the same usage conditions
  1567.          *
  1568.          * @author DarkBlade12
  1569.          * @since 1.4
  1570.          */
  1571.         private static final class PacketInstantiationException extends RuntimeException {
  1572.             private static final long serialVersionUID = 3203085387160737484L;
  1573.  
  1574.             /**
  1575.              * Construct a new packet instantiation exception
  1576.              *
  1577.              * @param message Message that will be logged
  1578.              * @param cause Cause of the exception
  1579.              */
  1580.             public PacketInstantiationException(String message, Throwable cause) {
  1581.                 super(message, cause);
  1582.             }
  1583.         }
  1584.  
  1585.         /**
  1586.          * Represents a runtime exception that is thrown if packet sending fails
  1587.          * <p>
  1588.          * This class is part of the <b>ParticleEffect Library</b> and follows the same usage conditions
  1589.          *
  1590.          * @author DarkBlade12
  1591.          * @since 1.4
  1592.          */
  1593.         private static final class PacketSendingException extends RuntimeException {
  1594.             private static final long serialVersionUID = 3203085387160737484L;
  1595.  
  1596.             /**
  1597.              * Construct a new packet sending exception
  1598.              *
  1599.              * @param message Message that will be logged
  1600.              * @param cause Cause of the exception
  1601.              */
  1602.             public PacketSendingException(String message, Throwable cause) {
  1603.                 super(message, cause);
  1604.             }
  1605.         }
  1606.     }
  1607. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement