Guest User

ParticleEffect

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