package io.izzel.taboolib.util.lite; import io.izzel.taboolib.Version; import io.izzel.taboolib.module.nms.NMS; import io.izzel.taboolib.module.packet.TPacketHandler; import io.izzel.taboolib.util.Reflection; import org.bukkit.Bukkit; import org.bukkit.Color; import org.bukkit.Location; import org.bukkit.block.data.BlockData; import org.bukkit.configuration.MemorySection; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.material.MaterialData; import org.bukkit.util.NumberConversions; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Random; /** * ParticleEffect Library *
* This library was created by @DarkBlade12 and allows you to display all Minecraft particle effects on a Bukkit server *
* You are welcome to use it, modify it and redistribute it under the following conditions: *
* Special thanks: *
* It would be nice if you provide credit to me if you use this class in a published project
*
* @author DarkBlade12
* @version 1.8
*/
@Deprecated
public enum Particles {
BARRIER,
BLOCK_CRACK(ParticleProperty.REQUIRES_DATA),
BLOCK_DUST(ParticleProperty.REQUIRES_DATA),
BUBBLE_COLUMN_UP(13),
BUBBLE_POP(13),
CLOUD,
CRIT,
CRIT_MAGIC,
CURRENT_DOWN(13),
DAMAGE_INDICATOR(9),
DOLPHIN(13),
DRAGON_BREATH(9),
DRIP_LAVA,
DRIP_WATER,
ENCHANTMENT_TABLE,
END_ROD(9),
EXPLOSION_HUGE,
EXPLOSION_LARGE,
EXPLOSION_NORMAL,
FALLING_DUST(10),
FIREWORKS_SPARK,
FLAME,
FOOTSTEP(0, 12),
HEART,
ITEM_CRACK(ParticleProperty.REQUIRES_DATA),
ITEM_TAKE,
LAVA,
MOB_APPEARANCE,
NAUTILUS(13),
NOTE(ParticleProperty.COLORABLE),
PORTAL,
REDSTONE(ParticleProperty.COLORABLE),
SLIME,
SMOKE_LARGE,
SMOKE_NORMAL,
SNOW_SHOVEL,
SNOWBALL,
SPELL,
SPELL_INSTANT,
SPELL_MOB(ParticleProperty.COLORABLE),
SPELL_MOB_AMBIENT(ParticleProperty.COLORABLE),
SPELL_WITCH,
SPIT(11),
SQUID_INK(13),
SUSPENDED,
SUSPENDED_DEPTH(0, 12),
SWEEP_ATTACK(9),
TOTEM(11),
TOWN_AURA,
VILLAGER_ANGRY,
VILLAGER_HAPPY,
WATER_BUBBLE,
WATER_DROP,
WATER_SPLASH,
WATER_WAKE,
;
private static final int mcVersion = NumberConversions.toInt(Version.getBukkitVersion().split("_")[1]);
private org.bukkit.Particle bukkitParticle;
private final List
* This class is part of the ParticleEffect Library and follows the same usage conditions
*
* @author DarkBlade12
* @since 1.7
*/
public enum ParticleProperty {
/**
* The particle effect requires water to be displayed
*/
@Deprecated
REQUIRES_WATER,
/**
* The particle effect requires block or item data to be displayed
*/
REQUIRES_DATA,
/**
* The particle effect uses the offsets as direction values
*/
@Deprecated
DIRECTIONAL,
/**
* The particle effect uses the offsets as color values
*/
COLORABLE
}
/**
* Represents the color for effects like {@link Particles#SPELL_MOB}, {@link Particles#SPELL_MOB_AMBIENT}, {@link Particles#REDSTONE} and {@link Particles#NOTE}
*
* This class is part of the ParticleEffect Library and follows the same usage conditions
*
* @author DarkBlade12
* @since 1.7
*/
public static abstract class ParticleColor {
/**
* Returns the value for the offsetX field
*
* @return The offsetX value
*/
public abstract float getValueX();
/**
* Returns the value for the offsetY field
*
* @return The offsetY value
*/
public abstract float getValueY();
/**
* Returns the value for the offsetZ field
*
* @return The offsetZ value
*/
public abstract float getValueZ();
}
/**
* Represents the color for effects like {@link Particles#SPELL_MOB}, {@link Particles#SPELL_MOB_AMBIENT} and {@link Particles#NOTE}
*
* This class is part of the ParticleEffect Library and follows the same usage conditions
*
* @author DarkBlade12
* @since 1.7
*/
public static class OrdinaryColor extends ParticleColor {
private final int red;
private final int green;
private final int blue;
/**
* Construct a new ordinary color
*
* @param red Red value of the RGB format
* @param green Green value of the RGB format
* @param blue Blue value of the RGB format
* @throws IllegalArgumentException If one of the values is lower than 0 or higher than 255
*/
public OrdinaryColor(int red, int green, int blue) throws IllegalArgumentException {
if (red < 0) {
throw new IllegalArgumentException("The red value is lower than 0");
}
if (red > 255) {
throw new IllegalArgumentException("The red value is higher than 255");
}
this.red = red;
if (green < 0) {
throw new IllegalArgumentException("The green value is lower than 0");
}
if (green > 255) {
throw new IllegalArgumentException("The green value is higher than 255");
}
this.green = green;
if (blue < 0) {
throw new IllegalArgumentException("The blue value is lower than 0");
}
if (blue > 255) {
throw new IllegalArgumentException("The blue value is higher than 255");
}
this.blue = blue;
}
/**
* Construct a new ordinary color
*
* @param color Bukkit color
*/
public OrdinaryColor(Color color) {
this(color.getRed(), color.getGreen(), color.getBlue());
}
/**
* Returns the red value of the RGB format
*
* @return The red value
*/
public int getRed() {
return red;
}
/**
* Returns the green value of the RGB format
*
* @return The green value
*/
public int getGreen() {
return green;
}
/**
* Returns the blue value of the RGB format
*
* @return The blue value
*/
public int getBlue() {
return blue;
}
/**
* Returns the red value divided by 255
*
* @return The offsetX value
*/
public float getValueX() {
return (float) red / 255F;
}
/**
* Returns the green value divided by 255
*
* @return The offsetY value
*/
public float getValueY() {
return (float) green / 255F;
}
/**
* Returns the blue value divided by 255
*
* @return The offsetZ value
*/
public float getValueZ() {
return (float) blue / 255F;
}
}
/**
* Represents the color for the {@link Particles#NOTE} effect
*
* This class is part of the ParticleEffect Library and follows the same usage conditions
*
* @author DarkBlade12
* @since 1.7
*/
public static final class NoteColor extends ParticleColor {
private final int note;
/**
* Construct a new note color
*
* @param note Note id which determines color
* @throws IllegalArgumentException If the note value is lower than 0 or higher than 24
*/
public NoteColor(int note) throws IllegalArgumentException {
if (note < 0) {
throw new IllegalArgumentException("The note value is lower than 0");
}
if (note > 24) {
throw new IllegalArgumentException("The note value is higher than 24");
}
this.note = note;
}
/**
* Returns the note value divided by 24
*
* @return The offsetX value
*/
public float getValueX() {
return (float) note / 24F;
}
/**
* Returns zero because the offsetY value is unused
*
* @return zero
*/
public float getValueY() {
return 0;
}
/**
* Returns zero because the offsetZ value is unused
*
* @return zero
*/
public float getValueZ() {
return 0;
}
}
public enum ParticleShape {
POINT, NEAR, BAR, EXCLAMATION, SPOT
}
public static class Particle {
private static final Random random = new Random();
private final Particles effect;
private final ParticleShape shape;
private final OrdinaryColor color;
private final byte typeCode;
public Particle(Particles effect, ParticleShape shape, OrdinaryColor color) {
this.effect = effect;
this.shape = shape;
this.color = color;
this.typeCode = (byte) (effect == Particles.NOTE ? 2 : (effect.hasProperty(ParticleProperty.COLORABLE) ? 1 : 0));
}
public String toString() {
return effect.name() + " in shape " + shape.name() + (typeCode != 0 ? " with color \"R" + (typeCode == 1 ? color.getRed() + " G" + color.getGreen() + " B" + color.getBlue() : "random") + "\"" : "");
}
public void send(LivingEntity en, List
* This class is part of the ParticleEffect Library and follows the same usage conditions
*
* @author DarkBlade12
* @since 1.6
*/
private static final class ObjectException extends RuntimeException {
private static final long serialVersionUID = 3203085387160737484L;
/**
* Construct a new particle data exception
*
* @param message Message that will be logged
*/
public ObjectException(String message) {
super(message);
}
}
/**
* Represents a runtime exception that is thrown either if the displayed particle effect is not colorable or if the particle color type is incorrect
*
* This class is part of the ParticleEffect Library and follows the same usage conditions
*
* @author DarkBlade12
* @since 1.7
*/
private static final class ParticleColorException extends RuntimeException {
private static final long serialVersionUID = 3203085387160737484L;
/**
* Construct a new particle color exception
*
* @param message Message that will be logged
*/
public ParticleColorException(String message) {
super(message);
}
}
/**
* Represents a runtime exception that is thrown if the displayed particle effect requires a newer version
*
* This class is part of the ParticleEffect Library and follows the same usage conditions
*
* @author DarkBlade12
* @since 1.6
*/
private static final class ParticleVersionException extends RuntimeException {
private static final long serialVersionUID = 3203085387160737484L;
/**
* Construct a new particle version exception
*/
public ParticleVersionException() {
super("This particle effect is not supported by your server version");
}
}
/**
* Represents a particle effect packet with all attributes which is used for sending packets to the players
*
* This class is part of the ParticleEffect Library and follows the same usage conditions
*
* @author DarkBlade12
* @since 1.5
*/
public static final class ParticlePacket {
private static boolean initialized;
/*private static Class> enumParticle;
private static String ver;
private static String pack;*/
private final Particles effect;
private float offsetX;
private float offsetY;
private float offsetZ;
private final float speed;
private int amount;
private final int size = 1;
private final boolean longDistance;
private Object data;
private Object packet;
private int timesSending = 1;
/**
* Construct a new particle packet
*
* @param effect Particle effect
* @param offsetX Maximum distance particles can fly away from the center on the x-axis
* @param offsetY Maximum distance particles can fly away from the center on the y-axis
* @param offsetZ Maximum distance particles can fly away from the center on the z-axis
* @param speed Display speed of the particles
* @param amount Amount of particles
* @param longDistance Indicates whether the maximum distance is increased from 256 to 65536
* @param data Data of the effect
* @throws IllegalArgumentException If the speed or amount is lower than 0
*/
public ParticlePacket(Particles effect, double offsetX, double offsetY, double offsetZ, double speed, int amount, boolean longDistance, Object data) throws IllegalArgumentException {
initialize();
if (speed < 0) {
throw new IllegalArgumentException("The speed is lower than 0");
}
if (amount < 0) {
throw new IllegalArgumentException("The amount is lower than 0");
}
this.effect = effect;
this.offsetX = (float) offsetX;
this.offsetY = (float) offsetY;
this.offsetZ = (float) offsetZ;
this.speed = (float) speed;
this.amount = amount;
this.longDistance = longDistance;
this.data = data;
}
/**
* Construct a new particle packet of a single particle flying into a determined direction
*
* @param effect Particle effect
* @param direction Direction of the particle
* @param speed Display speed of the particle
* @param longDistance Indicates whether the maximum distance is increased from 256 to 65536
* @param data Data of the effect
* @throws IllegalArgumentException If the speed is lower than 0
*/
/*public ParticlePacket(ParticleEffect effect, Vector direction, float speed, boolean longDistance, Object data) throws IllegalArgumentException {
this(effect, (float) direction.getX(), (float) direction.getY(), (float) direction.getZ(), speed, 0, longDistance, data);
}*/
/**
* Initializes and sets initialized to
* Note: These fields only have to be initialized once, so it will return if initialized is already set to
* This class is part of the ParticleEffect Library and follows the same usage conditions
*
* @author DarkBlade12
* @since 1.4
*/
private static final class PacketInstantiationException extends RuntimeException {
private static final long serialVersionUID = 3203085387160737484L;
/**
* Construct a new packet instantiation exception
*
* @param message Message that will be logged
* @param cause Cause of the exception
*/
public PacketInstantiationException(String message, Throwable cause) {
super(message, cause);
}
}
/**
* Represents a runtime exception that is thrown if packet sending fails
*
* This class is part of the ParticleEffect Library and follows the same usage conditions
*
* @author DarkBlade12
* @since 1.4
*/
private static final class PacketSendingException extends RuntimeException {
private static final long serialVersionUID = 3203085387160737484L;
/**
* Construct a new packet sending exception
*
* @param message Message that will be logged
* @param cause Cause of the exception
*/
public PacketSendingException(String message, Throwable cause) {
super(message, cause);
}
}
}
}true
if it succeeds
* true
*/
public static void initialize() {
if (initialized) {
return;
}
initialized = true;
}
/**
* Determine if packet is initialized
*
* @return Whether these fields are initialized or not
*/
public static boolean isInitialized() {
return initialized;
}
/**
* Initializes packet with all set values
*
* @param center Center location of the effect
* @throws PacketInstantiationException If instantion fails due to an unknown error
*/
private void initializePacket(Location center) throws PacketInstantiationException {
if (packet != null) {
return;
}
try {
//int tmpAmount = amount;
if (effect.hasProperty(ParticleProperty.COLORABLE) && data instanceof ParticleColor) {
if (mcVersion < 13 || data instanceof NoteColor) {
ParticleColor color = (ParticleColor) data;
offsetX = color.getValueX();
offsetY = color.getValueY();
offsetZ = color.getValueZ();
timesSending = amount < 2 ? 1 : amount;
amount = 0;
data = null;
if (color instanceof OrdinaryColor && ((OrdinaryColor) color).getRed() == 0) {
offsetX = Float.MIN_NORMAL;
}
} else if (mcVersion >= 13 && data instanceof OrdinaryColor) {
data = getDustColor((OrdinaryColor) data, size);
}
}
this.packet = NMS.handle().toPacketPlayOutWorldParticles(effect.getBukkitParticle(), longDistance, (float) center.getX(), (float) center.getY(), (float) center.getZ(), offsetX, offsetY, offsetZ, speed, amount, data);
} catch (Throwable exception) {
throw new PacketInstantiationException("Packet instantiation failed", exception);
}
}
public static Object getDustColor(OrdinaryColor color, int size) {
try {
return Reflection.instantiateObject(Class.forName("org.bukkit.Particle$DustOptions"), Color.fromBGR(color.getBlue(), color.getGreen(), color.getRed()), size);
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
/**
* Sends the packet to a single player and caches it
*
* @param center Center location of the effect
* @param player Receiver of the packet
* @throws PacketInstantiationException If instantion fails due to an unknown error
* @throws PacketSendingException If sending fails due to an unknown error
*/
public void sendTo(Location center, Player player) throws PacketInstantiationException, PacketSendingException {
initializePacket(center);
try {
if (timesSending == 1) {
TPacketHandler.sendPacket(player, packet);
} else {
for (int i = 0; i < timesSending; i++) {
TPacketHandler.sendPacket(player, packet);
}
}
//sendPacket.invoke(playerConnection.get(getHandle.invoke(player)), packet);
//((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
} catch (Throwable exception) {
throw new PacketSendingException("Failed to send the packet to player '" + player.getName() + "'", exception);
}
}
/**
* Sends the packet to all players in the list
*
* @param center Center location of the effect
* @param players Receivers of the packet
* @throws IllegalArgumentException If the player list is empty
*/
public void sendTo(Location center, List