├── .gitignore ├── CHANGELOG.md ├── Compatibility ├── common │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── de │ │ └── slikey │ │ └── effectlib │ │ └── util │ │ ├── DynamicLocation.java │ │ ├── ParticleDisplay.java │ │ ├── ParticleEffectManager.java │ │ ├── ParticleOptions.java │ │ ├── ParticleUtil.java │ │ └── VectorUtils.java ├── main │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── de │ │ └── slikey │ │ └── effectlib │ │ └── util │ │ └── ParticleDisplayFactory.java ├── modern │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── de │ │ └── slikey │ │ └── effectlib │ │ └── util │ │ └── versions │ │ └── ParticleDisplay_Modern.java ├── pom.xml ├── v1_12 │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── de │ │ └── slikey │ │ └── effectlib │ │ └── util │ │ └── versions │ │ └── ParticleDisplay_12.java ├── v1_13 │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── de │ │ └── slikey │ │ └── effectlib │ │ └── util │ │ └── versions │ │ └── ParticleDisplay_13.java └── v1_21_4 │ ├── pom.xml │ └── src │ └── main │ └── java │ └── de │ └── slikey │ └── effectlib │ └── util │ └── versions │ └── ParticleDisplay_21_4.java ├── EffectLib.doxyfile ├── EffectLib ├── pom.xml └── src │ └── main │ ├── java │ └── de │ │ └── slikey │ │ └── effectlib │ │ ├── Effect.java │ │ ├── EffectLib.java │ │ ├── EffectManager.java │ │ ├── EffectType.java │ │ ├── effect │ │ ├── AnimatedBallEffect.java │ │ ├── ArcEffect.java │ │ ├── AtomEffect.java │ │ ├── BigBangEffect.java │ │ ├── BleedEffect.java │ │ ├── CircleEffect.java │ │ ├── CloudEffect.java │ │ ├── ColoredImageEffect.java │ │ ├── ConeEffect.java │ │ ├── CubeEffect.java │ │ ├── CuboidEffect.java │ │ ├── CylinderEffect.java │ │ ├── DiscoBallEffect.java │ │ ├── DnaEffect.java │ │ ├── DonutEffect.java │ │ ├── DragonEffect.java │ │ ├── EarthEffect.java │ │ ├── EquationEffect.java │ │ ├── ExplodeEffect.java │ │ ├── FlameEffect.java │ │ ├── FountainEffect.java │ │ ├── GridEffect.java │ │ ├── HeartEffect.java │ │ ├── HelixEffect.java │ │ ├── HillEffect.java │ │ ├── IconEffect.java │ │ ├── ImageEffect.java │ │ ├── JumpEffect.java │ │ ├── LineEffect.java │ │ ├── LoveEffect.java │ │ ├── ModifiedEffect.java │ │ ├── MusicEffect.java │ │ ├── ParticleEffect.java │ │ ├── PlotEffect.java │ │ ├── PyramidEffect.java │ │ ├── ShieldEffect.java │ │ ├── SkyRocketEffect.java │ │ ├── SmokeEffect.java │ │ ├── SoundEffect.java │ │ ├── SphereEffect.java │ │ ├── SquareEffect.java │ │ ├── StarEffect.java │ │ ├── TextEffect.java │ │ ├── TornadoEffect.java │ │ ├── TraceEffect.java │ │ ├── TurnEffect.java │ │ ├── VortexEffect.java │ │ ├── WarpEffect.java │ │ └── WaveEffect.java │ │ ├── math │ │ ├── ConstantTransform.java │ │ ├── EchoTransform.java │ │ ├── EquationStore.java │ │ ├── EquationTransform.java │ │ ├── EquationVariableProvider.java │ │ ├── MultiplyTransform.java │ │ ├── SequenceTransform.java │ │ ├── SumTransform.java │ │ ├── Transform.java │ │ ├── Transforms.java │ │ ├── VectorTransform.java │ │ ├── dQuadraticTransform.java │ │ └── dSinTransform.java │ │ └── util │ │ ├── BaseImageEffect.java │ │ ├── ConfigUtils.java │ │ ├── CustomSound.java │ │ ├── Disposable.java │ │ ├── ImageLoadCallback.java │ │ ├── ImageLoadTask.java │ │ ├── MathUtils.java │ │ ├── RandomUtils.java │ │ └── StringParser.java │ └── resources │ ├── migrate.php │ └── plugin.yml ├── LICENSE ├── README.md ├── TODO.md └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /.git/ 3 | /.settings/ 4 | /.classpath 5 | /.project 6 | target 7 | .idea 8 | *.iml 9 | dependency-reduced-pom.xml -------------------------------------------------------------------------------- /Compatibility/common/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | com.elmakers.mine.bukkit.compatibility 7 | EffectLib-Compatibility 8 | 10.11-SNAPSHOT 9 | 10 | 11 | EffectLib-Compatibility-common 12 | 13 | 14 | 15 | org.spigotmc 16 | spigot-api 17 | 1.11-R0.1-SNAPSHOT 18 | provided 19 | 20 | 21 | 22 | 23 | 24 | 25 | org.apache.maven.plugins 26 | maven-compiler-plugin 27 | 3.11.0 28 | 29 | 8 30 | 8 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /Compatibility/common/src/main/java/de/slikey/effectlib/util/DynamicLocation.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.util; 2 | 3 | import java.lang.ref.WeakReference; 4 | 5 | import org.bukkit.Location; 6 | import org.bukkit.util.Vector; 7 | import org.bukkit.entity.Entity; 8 | import org.bukkit.entity.LivingEntity; 9 | 10 | /** 11 | * Represents a Location that can move, possibly bound to an Entity. 12 | */ 13 | public class DynamicLocation { 14 | 15 | private final Location location; 16 | private final Location originalLocation; 17 | private final WeakReference entity; 18 | 19 | private float yawOffset; 20 | private float pitchOffset; 21 | 22 | private Vector offset; 23 | private Vector relativeOffset; 24 | private Vector entityOffset; 25 | 26 | private Float yaw = null; 27 | private Float pitch = null; 28 | 29 | private boolean updateLocation = true; 30 | private boolean updateDirection = true; 31 | 32 | public DynamicLocation(Location location) { 33 | if (location != null) this.location = location.clone(); 34 | else this.location = null; 35 | originalLocation = location; 36 | entity = null; 37 | } 38 | 39 | public DynamicLocation(Entity entity) { 40 | if (entity != null) { 41 | this.entity = new WeakReference<>(entity); 42 | location = getEntityLocation(entity); 43 | } else { 44 | this.entity = null; 45 | location = null; 46 | } 47 | originalLocation = location; 48 | } 49 | 50 | public DynamicLocation(Location location, Entity entity) { 51 | if (location != null) this.location = location.clone(); 52 | else if (entity != null) this.location = getEntityLocation(entity); 53 | else this.location = null; 54 | 55 | if (entity != null) { 56 | this.entity = new WeakReference<>(entity); 57 | entityOffset = this.location.toVector().subtract(getEntityLocation(entity).toVector()); 58 | } else { 59 | this.entity = null; 60 | } 61 | 62 | originalLocation = this.location == null ? null : this.location.clone(); 63 | } 64 | 65 | public void addOffset(Vector offset) { 66 | if (this.offset == null) this.offset = offset.clone(); 67 | else this.offset.add(offset); 68 | updateOffsets(); 69 | } 70 | 71 | public void subtractOffset(Vector offset) { 72 | if (this.offset == null) this.offset = offset.clone(); 73 | else this.offset.subtract(offset); 74 | updateOffsets(); 75 | } 76 | 77 | public void addRelativeOffset(Vector offset) { 78 | if (relativeOffset == null) relativeOffset = offset.clone(); 79 | else relativeOffset.add(offset); 80 | updateOffsets(); 81 | } 82 | 83 | public void subtractRelativeOffset(Vector offset) { 84 | if (relativeOffset == null) relativeOffset = offset.clone(); 85 | else relativeOffset.subtract(offset); 86 | updateOffsets(); 87 | } 88 | 89 | public Entity getEntity() { 90 | return entity == null ? null : entity.get(); 91 | } 92 | 93 | public Location getLocation() { 94 | return location; 95 | } 96 | 97 | protected Location getEntityLocation(Entity entity) { 98 | if (entity instanceof LivingEntity) return ((LivingEntity) entity).getEyeLocation(); 99 | return entity.getLocation(); 100 | } 101 | 102 | public void setDirection(Vector direction) { 103 | if (location == null || direction == null) return; 104 | location.setDirection(direction); 105 | updateDirection(); 106 | } 107 | 108 | public void updateDirection() { 109 | if (location == null) return; 110 | if (yaw != null) location.setYaw(yaw); 111 | if (pitch != null) location.setPitch(pitch); 112 | if (yawOffset != 0) location.setYaw(location.getYaw() + yawOffset); 113 | if (pitchOffset != 0) location.setPitch(location.getPitch() + pitchOffset); 114 | } 115 | 116 | public void updateFrom(Location newLocation) { 117 | if (originalLocation != null) { 118 | originalLocation.setX(newLocation.getX()); 119 | originalLocation.setY(newLocation.getY()); 120 | originalLocation.setZ(newLocation.getZ()); 121 | } 122 | updateOffsets(); 123 | } 124 | 125 | public void updateOffsets() { 126 | if (originalLocation == null || location == null) return; 127 | location.setX(originalLocation.getX()); 128 | location.setY(originalLocation.getY()); 129 | location.setZ(originalLocation.getZ()); 130 | 131 | if (offset != null) location.add(offset); 132 | if (relativeOffset != null) location.add(VectorUtils.rotateVector(relativeOffset, location)); 133 | if (entityOffset != null) location.add(entityOffset); 134 | } 135 | 136 | public void setUpdateLocation(boolean update) { 137 | updateLocation = update; 138 | } 139 | 140 | public void update() { 141 | if (location == null || (!updateLocation && !updateDirection)) return; 142 | 143 | Entity entityReference = entity == null ? null : entity.get(); 144 | if (entityReference == null) return; 145 | 146 | Location currentLocation = getEntityLocation(entityReference); 147 | if (updateDirection) setDirection(currentLocation.getDirection()); 148 | if (updateLocation) updateFrom(currentLocation); 149 | } 150 | 151 | public void setUpdateDirection(boolean updateDirection) { 152 | this.updateDirection = updateDirection; 153 | } 154 | 155 | public void setDirectionOffset(float yawOffset, float pitchOffset) { 156 | this.pitchOffset = pitchOffset; 157 | this.yawOffset = yawOffset; 158 | } 159 | 160 | public void setPitch(Float pitch) { 161 | this.pitch = pitch; 162 | } 163 | 164 | public void setYaw(Float yaw) { 165 | this.yaw = yaw; 166 | } 167 | 168 | public boolean hasValidEntity() { 169 | Entity entity = this.getEntity(); 170 | return entity != null && entity.isValid(); 171 | } 172 | 173 | @Override 174 | public DynamicLocation clone() { 175 | try { 176 | return (DynamicLocation) super.clone(); 177 | } catch (CloneNotSupportedException e) { 178 | e.printStackTrace(); 179 | return null; 180 | } 181 | } 182 | 183 | } 184 | -------------------------------------------------------------------------------- /Compatibility/common/src/main/java/de/slikey/effectlib/util/ParticleDisplay.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.util; 2 | 3 | import java.util.List; 4 | 5 | import org.bukkit.Color; 6 | import org.bukkit.Bukkit; 7 | import org.bukkit.Location; 8 | import org.bukkit.Material; 9 | import org.bukkit.Particle; 10 | import org.bukkit.entity.Player; 11 | import org.bukkit.inventory.ItemStack; 12 | 13 | public abstract class ParticleDisplay { 14 | 15 | protected ParticleEffectManager manager; 16 | 17 | protected boolean hasColorTransition = false; 18 | protected boolean hasColorDataType = false; 19 | 20 | protected static Particle SPELL_MOB; 21 | protected static Particle SPELL_MOB_AMBIENT; 22 | protected static Particle ITEM_CRACK; 23 | protected static Particle BLOCK_CRACK; 24 | protected static Particle BLOCK_DUST; 25 | protected static Particle FALLING_DUST; 26 | protected static Particle REDSTONE; 27 | protected static Particle DUST_COLOR_TRANSITION; 28 | protected static Particle VIBRATION; 29 | protected static Particle SHRIEK; 30 | protected static Particle SCULK_CHARGE; 31 | 32 | protected static void initializeConstants() { 33 | if (SPELL_MOB != null) return; 34 | SPELL_MOB = ParticleUtil.getParticle("SPELL_MOB"); 35 | SPELL_MOB_AMBIENT = ParticleUtil.getParticle("SPELL_MOB_AMBIENT"); 36 | ITEM_CRACK = ParticleUtil.getParticle("ITEM_CRACK"); 37 | BLOCK_CRACK = ParticleUtil.getParticle("BLOCK_CRACK"); 38 | BLOCK_DUST = ParticleUtil.getParticle("BLOCK_DUST"); 39 | FALLING_DUST = ParticleUtil.getParticle("FALLING_DUST"); 40 | REDSTONE = ParticleUtil.getParticle("REDSTONE"); 41 | DUST_COLOR_TRANSITION = ParticleUtil.getParticle("DUST_COLOR_TRANSITION"); 42 | VIBRATION = ParticleUtil.getParticle("VIBRATION"); 43 | SHRIEK = ParticleUtil.getParticle("SHRIEK"); 44 | SCULK_CHARGE = ParticleUtil.getParticle("SCULK_CHARGE"); 45 | } 46 | 47 | public void setHasColorTransition(boolean hasColorTransition) { 48 | this.hasColorTransition = hasColorTransition; 49 | } 50 | 51 | public void setHasColorDataType(boolean hasColorDataType) { 52 | this.hasColorDataType = hasColorDataType; 53 | } 54 | 55 | public void display(Particle particle, ParticleOptions options, Location center, double range, List targetPlayers) { 56 | initializeConstants(); 57 | 58 | // Legacy colorizeable particles 59 | if (options.color != null && particle == SPELL_MOB) { 60 | displayLegacyColored(particle, options, center, range, targetPlayers); 61 | return; 62 | } 63 | 64 | if (particle == ITEM_CRACK) { 65 | displayItem(particle, options, center, range, targetPlayers); 66 | return; 67 | } 68 | 69 | spawnParticle(particle, options, center, range, targetPlayers); 70 | } 71 | 72 | protected void spawnParticle(Particle particle, ParticleOptions options, Location center, double range, List targetPlayers) { 73 | try { 74 | if (targetPlayers == null) { 75 | double squared = range * range; 76 | for (final Player player : Bukkit.getOnlinePlayers()) { 77 | if (!manager.isVisiblePlayer(player, center, squared)) continue; 78 | 79 | if (hasColorDataType && particle == SPELL_MOB) { 80 | player.spawnParticle(particle, center, options.amount, options.offsetX, options.offsetY, options.offsetZ, options.speed, options.color == null ? Color.WHITE : options.color); 81 | } else { 82 | player.spawnParticle(particle, center, options.amount, options.offsetX, options.offsetY, options.offsetZ, options.speed, options.data); 83 | } 84 | 85 | displayFakeBlock(player, center, options); 86 | } 87 | return; 88 | } 89 | 90 | for (final Player player : targetPlayers) { 91 | if (manager.isPlayerIgnored(player)) continue; 92 | player.spawnParticle(particle, center, options.amount, options.offsetX, options.offsetY, options.offsetZ, options.speed, options.data); 93 | displayFakeBlock(player, center, options); 94 | } 95 | 96 | } catch (Exception ex) { 97 | if (manager != null) manager.onError(ex); 98 | } 99 | } 100 | 101 | protected void displayFakeBlock(final Player player, Location center, ParticleOptions options) { 102 | // Implemented in 1.13+ 103 | } 104 | 105 | @SuppressWarnings({"deprecation"}) 106 | protected void displayItem(Particle particle, ParticleOptions options, Location center, double range, List targetPlayers) { 107 | Material material = options.material; 108 | if (material == null || material == Material.AIR) return; 109 | 110 | ItemStack item = new ItemStack(material); 111 | item.setDurability(options.materialData); 112 | options.data = item; 113 | spawnParticle(particle, options, center, range, targetPlayers); 114 | } 115 | 116 | protected void displayLegacyColored(Particle particle, ParticleOptions options, Location center, double range, List targetPlayers) { 117 | // Colored particles can't have a speed of 0. 118 | Color color = options.color; 119 | if (color == null) color = Color.RED; 120 | if (options.speed == 0) options.speed = 1; 121 | // Amount = 0 is a special flag that means use the offset as color 122 | options.amount = 0; 123 | 124 | float offsetX = (float) color.getRed() / 255; 125 | float offsetY = (float) color.getGreen() / 255; 126 | float offsetZ = (float) color.getBlue() / 255; 127 | 128 | // The redstone particle reverts to red if R is 0! 129 | if (offsetX < Float.MIN_NORMAL) offsetX = Float.MIN_NORMAL; 130 | 131 | options.offsetX = offsetX; 132 | options.offsetY = offsetY; 133 | options.offsetZ = offsetZ; 134 | 135 | spawnParticle(particle, options, center, range, targetPlayers); 136 | } 137 | 138 | public void setManager(ParticleEffectManager manager) { 139 | this.manager = manager; 140 | } 141 | 142 | public boolean hasColorTransition() { 143 | return hasColorTransition; 144 | } 145 | 146 | } 147 | -------------------------------------------------------------------------------- /Compatibility/common/src/main/java/de/slikey/effectlib/util/ParticleEffectManager.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.util; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.plugin.Plugin; 6 | 7 | public interface ParticleEffectManager { 8 | void onError(String message, Throwable ex); 9 | void onError(Throwable ex); 10 | void onError(String message); 11 | boolean isVisiblePlayer(Player player, Location center, double distanceSquared); 12 | boolean isPlayerIgnored(Player player); 13 | boolean getForceShow(); 14 | Plugin getOwningPlugin(); 15 | } 16 | -------------------------------------------------------------------------------- /Compatibility/common/src/main/java/de/slikey/effectlib/util/ParticleOptions.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.util; 2 | 3 | import org.bukkit.Color; 4 | import org.bukkit.Material; 5 | 6 | public class ParticleOptions { 7 | 8 | public Color color; 9 | public Color toColor; 10 | 11 | public float offsetX; 12 | public float offsetY; 13 | public float offsetZ; 14 | 15 | public float speed; 16 | public int amount; 17 | public int arrivalTime; 18 | public float size; 19 | 20 | public Material material; 21 | public byte materialData; 22 | 23 | public String blockData; 24 | public long blockDuration; 25 | 26 | public Object data; 27 | 28 | public DynamicLocation target; 29 | 30 | public int shriekDelay; 31 | public float sculkChargeRotation; 32 | 33 | public boolean forceShow = false; 34 | 35 | public ParticleOptions() { 36 | 37 | } 38 | 39 | public ParticleOptions(float offsetX, float offsetY, float offsetZ, float speed, int amount, float size, Color color, Material material, byte materialData) { 40 | this.offsetX = offsetX; 41 | this.offsetY = offsetY; 42 | this.offsetZ = offsetZ; 43 | this.speed = speed; 44 | this.amount = amount; 45 | this.size = size; 46 | this.color = color; 47 | this.material = material; 48 | this.materialData = materialData; 49 | } 50 | 51 | public ParticleOptions(float offsetX, float offsetY, float offsetZ, float speed, int amount, float size, Color color, Color toColor, int arrivalTime, Material material, byte materialData) { 52 | this.offsetX = offsetX; 53 | this.offsetY = offsetY; 54 | this.offsetZ = offsetZ; 55 | this.speed = speed; 56 | this.amount = amount; 57 | this.size = size; 58 | this.color = color; 59 | this.toColor = toColor; 60 | this.material = material; 61 | this.materialData = materialData; 62 | this.arrivalTime = arrivalTime; 63 | } 64 | 65 | public ParticleOptions(float offsetX, float offsetY, float offsetZ, float speed, int amount, float size, Color color, Color toColor, int arrivalTime, Material material, byte materialData, String blockData, long blockDuration) { 66 | this.offsetX = offsetX; 67 | this.offsetY = offsetY; 68 | this.offsetZ = offsetZ; 69 | this.speed = speed; 70 | this.amount = amount; 71 | this.size = size; 72 | this.color = color; 73 | this.toColor = toColor; 74 | this.material = material; 75 | this.materialData = materialData; 76 | this.arrivalTime = arrivalTime; 77 | this.blockData = blockData; 78 | this.blockDuration = blockDuration; 79 | } 80 | 81 | public ParticleOptions(float offsetX, float offsetY, float offsetZ, float speed, int amount, float size, Color color, Color toColor, int arrivalTime, Material material, byte materialData, String blockData, long blockDuration, int shriekDelay, float sculkChargeRotation) { 82 | this.offsetX = offsetX; 83 | this.offsetY = offsetY; 84 | this.offsetZ = offsetZ; 85 | this.speed = speed; 86 | this.amount = amount; 87 | this.size = size; 88 | this.color = color; 89 | this.toColor = toColor; 90 | this.material = material; 91 | this.materialData = materialData; 92 | this.arrivalTime = arrivalTime; 93 | this.blockData = blockData; 94 | this.blockDuration = blockDuration; 95 | this.shriekDelay = shriekDelay; 96 | this.sculkChargeRotation = sculkChargeRotation; 97 | } 98 | 99 | public ParticleOptions(float offsetX, float offsetY, float offsetZ, float speed, int amount, float size, boolean forceShow, Color color, Color toColor, int arrivalTime, Material material, byte materialData, String blockData, long blockDuration, int shriekDelay, float sculkChargeRotation) { 100 | this.offsetX = offsetX; 101 | this.offsetY = offsetY; 102 | this.offsetZ = offsetZ; 103 | this.speed = speed; 104 | this.amount = amount; 105 | this.size = size; 106 | this.color = color; 107 | this.toColor = toColor; 108 | this.material = material; 109 | this.materialData = materialData; 110 | this.arrivalTime = arrivalTime; 111 | this.blockData = blockData; 112 | this.blockDuration = blockDuration; 113 | this.shriekDelay = shriekDelay; 114 | this.sculkChargeRotation = sculkChargeRotation; 115 | this.forceShow = forceShow; 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /Compatibility/common/src/main/java/de/slikey/effectlib/util/ParticleUtil.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.util; 2 | 3 | import java.util.Map; 4 | import java.util.HashMap; 5 | 6 | import org.bukkit.Particle; 7 | 8 | public enum ParticleUtil { 9 | 10 | EXPLOSION_NORMAL("explosion_normal", "poof", "explode"), 11 | EXPLOSION_LARGE("explosion_large", "explosion", "largeexplode"), 12 | EXPLOSION_HUGE("explosion_huge", "explosion_emitter", "hugeexplosion"), 13 | WATER_BUBBLE("water_bubble", "bubble"), 14 | WATER_SPLASH("water_splash", "splash"), 15 | WATER_WAKE("water_wake", "fishing", "wake"), 16 | WATER_DROP("water_drop", "rain", "droplet"), 17 | SPELL("spell", "effect"), 18 | SPELL_INSTANT("spell_instant", "instant_effect", "instantspell"), 19 | SPELL_MOB("spell_mob", "entity_effect", "mobspell"), 20 | SPELL_MOB_AMBIENT("spell_mob_ambient", "ambient_entity_effect", "mobspellambient"), 21 | SPELL_WITCH("spell_witch", "witch", "witchmagic"), 22 | ITEM_CRACK("item_crack", "item", "iconcrack"), 23 | BLOCK_CRACK("block_crack", "blockcrack"), 24 | BLOCK_DUST("block_dust", "blockdust", "block"), 25 | SMOKE_NORMAL("smoke_normal", "smoke"), 26 | SMOKE_LARGE("smoke_large", "large_smoke", "largesmoke"), 27 | DRIP_WATER("drip_water", "dripping_water", "dripwater"), 28 | DRIP_LAVA("drip_lava", "dripping_lava", "driplava"), 29 | VILLAGER_ANGRY("villager_angry", "angry_villager", "angryvillager"), 30 | VILLAGER_HAPPY("villager_happy", "happy_villager", "happyvillager"), 31 | FIREWORKS_SPARK("fireworks_spark", "firework", "fireworksspark"), 32 | SUSPENDED("suspended", "underwater"), 33 | SUSPENDED_DEPTH("suspended_depth", "depthsuspend"), 34 | CRIT_MAGIC("crit_magic", "enchanted_hit", "magiccrit"), 35 | TOWN_AURA("town_aura", "mycelium", "townaura"), 36 | ENCHANTMENT_TABLE("enchantment_table", "enchant", "enchantmenttable"), 37 | REDSTONE("redstone", "dust", "reddust"), 38 | SNOWBALL("snowball", "item_snowball", "snowballpoof"), 39 | SLIME("slime", "item_slime"), 40 | MOB_APPEARANCE("mob_appearance", "elder_guardian", "mobappearance"), 41 | SNOW_SHOVEL("snow_shovel", "snowshovel"), 42 | DRAGON_BREATH("dragon_breath", "dragonbreath"), 43 | END_ROD("end_rod", "endrod"), 44 | DAMAGE_INDICATOR("damage_indicator", "damageindicator"), 45 | SWEEP_ATTACK("sweep_attack", "sweepattack"), 46 | FALLING_DUST("falling_dust", "fallingdust"), 47 | ; 48 | 49 | private static final Map namesToType = new HashMap<>(); 50 | private static boolean initialized = false; 51 | 52 | private final String[] names; 53 | 54 | ParticleUtil(String... names) { 55 | this.names = names; 56 | } 57 | 58 | private static void initialize() { 59 | if (initialized) return; 60 | 61 | for (ParticleUtil p : ParticleUtil.values()) { 62 | Particle particle = null; 63 | 64 | try { 65 | particle = Particle.valueOf(p.name()); 66 | } catch (Exception e) { 67 | // ignored 68 | } 69 | 70 | if (particle == null) continue; 71 | 72 | // handle the names 73 | namesToType.put(p.name().toLowerCase(), particle); 74 | for (String s : p.names) { 75 | namesToType.put(s.toLowerCase(), particle); 76 | } 77 | 78 | } 79 | 80 | initialized = true; 81 | } 82 | 83 | public static Particle getParticle(String particleName) { 84 | initialize(); 85 | 86 | Particle particle = namesToType.get(particleName.toLowerCase()); 87 | if (particle != null) return particle; 88 | 89 | try { 90 | particle = Particle.valueOf(particleName.toUpperCase()); 91 | } catch (IllegalArgumentException ignored) {} 92 | 93 | return particle; 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /Compatibility/common/src/main/java/de/slikey/effectlib/util/VectorUtils.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.util; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.util.Vector; 5 | 6 | public final class VectorUtils { 7 | 8 | private VectorUtils() { 9 | } 10 | 11 | public static Vector rotateAroundAxisX(Vector vector, double angle) { 12 | double y, z, cos, sin; 13 | cos = Math.cos(angle); 14 | sin = Math.sin(angle); 15 | y = vector.getY() * cos - vector.getZ() * sin; 16 | z = vector.getY() * sin + vector.getZ() * cos; 17 | return vector.setY(y).setZ(z); 18 | } 19 | 20 | public static Vector rotateAroundAxisY(Vector vector, double angle) { 21 | double x, z, cos, sin; 22 | cos = Math.cos(angle); 23 | sin = Math.sin(angle); 24 | x = vector.getX() * cos + vector.getZ() * sin; 25 | z = vector.getX() * -sin + vector.getZ() * cos; 26 | return vector.setX(x).setZ(z); 27 | } 28 | 29 | public static Vector rotateAroundAxisZ(Vector vector, double angle) { 30 | double x, y, cos, sin; 31 | cos = Math.cos(angle); 32 | sin = Math.sin(angle); 33 | x = vector.getX() * cos - vector.getY() * sin; 34 | y = vector.getX() * sin + vector.getY() * cos; 35 | return vector.setX(x).setY(y); 36 | } 37 | 38 | public static Vector rotateVector(Vector vector, double angleX, double angleY, double angleZ) { 39 | // double x = vector.getX(), y = vector.getY(), z = vector.getZ(); 40 | // double cosX = Math.cos(angleX), sinX = Math.sin(angleX), cosY = 41 | // Math.cos(angleY), sinY = Math.sin(angleY), cosZ = Math.cos(angleZ), 42 | // sinZ = Math.sin(angleZ); 43 | // double nx, ny, nz; 44 | // nx = (x * cosY + z * sinY) * (x * cosZ - y * sinZ); 45 | // ny = (y * cosX - z * sinX) * (x * sinZ + y * cosZ); 46 | // nz = (y * sinX + z * cosX) * (-x * sinY + z * cosY); 47 | // return vector.setX(nx).setY(ny).setZ(nz); 48 | // Having some strange behavior up there.. Have to look in it later. TODO 49 | rotateAroundAxisX(vector, angleX); 50 | rotateAroundAxisY(vector, angleY); 51 | rotateAroundAxisZ(vector, angleZ); 52 | return vector; 53 | } 54 | 55 | /** 56 | * Rotate a vector about a location using that location's direction 57 | * 58 | * @param vector vector to rotate 59 | * @param location location to get yaw and pitch from 60 | * @return rotated vector 61 | */ 62 | public static Vector rotateVector(Vector vector, Location location) { 63 | return rotateVector(vector, location.getYaw(), location.getPitch()); 64 | } 65 | 66 | /** 67 | * This handles non-unit vectors, with yaw and pitch instead of X,Y,Z angles. 68 | * 69 | * Thanks to SexyToad! 70 | * 71 | * @param vector vector to rotate 72 | * @param yawDegrees yaw degrees 73 | * @param pitchDegrees pitch degrees 74 | * @return rotated vector 75 | */ 76 | public static Vector rotateVector(Vector vector, float yawDegrees, float pitchDegrees) { 77 | double yaw = Math.toRadians(-1 * (yawDegrees + 90)); 78 | double pitch = Math.toRadians(-pitchDegrees); 79 | 80 | double cosYaw = Math.cos(yaw); 81 | double cosPitch = Math.cos(pitch); 82 | double sinYaw = Math.sin(yaw); 83 | double sinPitch = Math.sin(pitch); 84 | 85 | double initialX, initialY, initialZ; 86 | double x, y, z; 87 | 88 | // Z_Axis rotation (Pitch) 89 | initialX = vector.getX(); 90 | initialY = vector.getY(); 91 | x = initialX * cosPitch - initialY * sinPitch; 92 | y = initialX * sinPitch + initialY * cosPitch; 93 | 94 | // Y_Axis rotation (Yaw) 95 | initialZ = vector.getZ(); 96 | initialX = x; 97 | z = initialZ * cosYaw - initialX * sinYaw; 98 | x = initialZ * sinYaw + initialX * cosYaw; 99 | 100 | return new Vector(x, y, z); 101 | } 102 | 103 | public static double angleToXAxis(Vector vector) { 104 | return Math.atan2(vector.getX(), vector.getY()); 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /Compatibility/main/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | com.elmakers.mine.bukkit.compatibility 7 | EffectLib-Compatibility 8 | 10.11-SNAPSHOT 9 | 10 | 11 | EffectLib-Compatibility-main 12 | 13 | 14 | 15 | org.spigotmc 16 | spigot-api 17 | 1.19.3-R0.1-SNAPSHOT 18 | provided 19 | 20 | 21 | com.elmakers.mine.bukkit.compatibility 22 | EffectLib-Compatibility-common 23 | 10.11-SNAPSHOT 24 | compile 25 | 26 | 27 | com.elmakers.mine.bukkit.compatibility 28 | EffectLib-Compatibility-v1_12 29 | 10.11-SNAPSHOT 30 | compile 31 | 32 | 33 | com.elmakers.mine.bukkit.compatibility 34 | EffectLib-Compatibility-v1_13 35 | 10.11-SNAPSHOT 36 | compile 37 | 38 | 39 | com.elmakers.mine.bukkit.compatibility 40 | EffectLib-Compatibility-v1_21_4 41 | 10.11-SNAPSHOT 42 | compile 43 | 44 | 45 | 46 | 47 | 48 | 49 | org.apache.maven.plugins 50 | maven-compiler-plugin 51 | 3.11.0 52 | 53 | 8 54 | 8 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Compatibility/main/src/main/java/de/slikey/effectlib/util/ParticleDisplayFactory.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.util; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.Particle; 5 | import org.bukkit.entity.Player; 6 | 7 | import de.slikey.effectlib.util.versions.ParticleDisplay_12; 8 | import de.slikey.effectlib.util.versions.ParticleDisplay_13; 9 | import de.slikey.effectlib.util.versions.ParticleDisplay_21_4; 10 | 11 | public class ParticleDisplayFactory { 12 | public static ParticleDisplay newInstance() { 13 | ParticleDisplay display; 14 | boolean hasColorTransition = false; 15 | boolean hasColorDataType = false; 16 | 17 | try { 18 | // @NotNull Particle var1, @NotNull Location var2, int var3, double var4, double var6, double var8, double var10, @Nullable T var12, boolean var13 19 | // particle, center, options.amount, options.offsetX, options.offsetY, options.offsetZ, options.speed, options.data, options.forceShow 20 | Player.class.getMethod("spawnParticle", Particle.class, Location.class, Integer.TYPE, Double.TYPE, Double.TYPE, Double.TYPE, Double.TYPE, Object.class, Boolean.TYPE); 21 | display = new ParticleDisplay_21_4(); 22 | hasColorTransition = true; 23 | hasColorDataType = true; 24 | } catch (Throwable not21_4) { 25 | // TODO: This could all be cleaned up a bit. 26 | try { 27 | Particle.valueOf("DUST"); 28 | display = new ParticleDisplay_13(); 29 | hasColorTransition = true; 30 | hasColorDataType = true; 31 | } catch (Throwable not20_5) { 32 | try { 33 | Particle.valueOf("SHRIEK"); 34 | display = new ParticleDisplay_13(); 35 | hasColorTransition = true; 36 | } catch (Throwable not19) { 37 | try { 38 | Particle.valueOf("VIBRATION"); 39 | display = new ParticleDisplay_13(); 40 | hasColorTransition = true; 41 | } catch (Throwable not17) { 42 | try { 43 | Particle.valueOf("SQUID_INK"); 44 | display = new ParticleDisplay_13(); 45 | } catch (Throwable not13) { 46 | display = new ParticleDisplay_12(); 47 | } 48 | } 49 | } 50 | } 51 | } 52 | display.setHasColorTransition(hasColorTransition); 53 | display.setHasColorDataType(hasColorDataType); 54 | 55 | return display; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Compatibility/modern/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | com.elmakers.mine.bukkit.compatibility 7 | EffectLib-Compatibility 8 | 10.11-SNAPSHOT 9 | 10 | 11 | EffectLib-Compatibility-modern 12 | 13 | 14 | 15 | org.spigotmc 16 | spigot-api 17 | 1.17-R0.1-SNAPSHOT 18 | provided 19 | 20 | 21 | com.elmakers.mine.bukkit.compatibility 22 | EffectLib-Compatibility-common 23 | 10.11-SNAPSHOT 24 | compile 25 | 26 | 27 | 28 | 29 | 30 | 31 | org.apache.maven.plugins 32 | maven-compiler-plugin 33 | 3.11.0 34 | 35 | 8 36 | 8 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Compatibility/modern/src/main/java/de/slikey/effectlib/util/versions/ParticleDisplay_Modern.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.util.versions; 2 | 3 | import java.util.List; 4 | 5 | import org.bukkit.Color; 6 | import org.bukkit.Location; 7 | import org.bukkit.Material; 8 | import org.bukkit.Particle; 9 | import org.bukkit.Vibration; 10 | import org.bukkit.entity.Entity; 11 | import org.bukkit.entity.Player; 12 | import org.bukkit.inventory.ItemStack; 13 | 14 | import de.slikey.effectlib.util.ParticleDisplay; 15 | import de.slikey.effectlib.util.ParticleOptions; 16 | 17 | public class ParticleDisplay_Modern extends ParticleDisplay { 18 | 19 | public void display(Particle particle, ParticleOptions options, Location center, double range, List targetPlayers) { 20 | initializeConstants(); 21 | 22 | // Legacy colorizeable particles 23 | // 1.20.5 has removed Particle#SPELL_MOB_AMBIENT and SPELL_MOB is now ENTITY_EFFECT (handled by ParticleUtil) 24 | if (options.color != null && particle == SPELL_MOB) { 25 | displayLegacyColored(particle, options, center, range, targetPlayers); 26 | return; 27 | } 28 | 29 | if (particle == ITEM_CRACK) { 30 | displayItem(particle, options, center, range, targetPlayers); 31 | return; 32 | } 33 | 34 | if (particle == BLOCK_DUST || particle == FALLING_DUST) { 35 | Material material = options.material; 36 | if (material == null || material.name().contains("AIR")) return; 37 | try { 38 | options.data = material.createBlockData(); 39 | } catch (Exception ex) { 40 | manager.onError("Error creating block data for " + material, ex); 41 | } 42 | if (options.data == null) return; 43 | } 44 | 45 | if (particle == REDSTONE) { 46 | // color is required 47 | if (options.color == null) options.color = Color.RED; 48 | options.data = new Particle.DustOptions(options.color, options.size); 49 | } 50 | 51 | if (particle == DUST_COLOR_TRANSITION) { 52 | if (options.color == null) options.color = Color.RED; 53 | if (options.toColor == null) options.toColor = options.color; 54 | options.data = new Particle.DustTransition(options.color, options.toColor, options.size); 55 | } 56 | 57 | if (particle == VIBRATION) { 58 | if (options.target == null) return; 59 | 60 | Vibration.Destination destination; 61 | Entity targetEntity = options.target.getEntity(); 62 | if (targetEntity != null) destination = new Vibration.Destination.EntityDestination(targetEntity); 63 | else { 64 | Location targetLocation = options.target.getLocation(); 65 | if (targetLocation == null) return; 66 | 67 | destination = new Vibration.Destination.BlockDestination(targetLocation); 68 | } 69 | 70 | options.data = new Vibration(center, destination, options.arrivalTime); 71 | } 72 | 73 | if (particle == SHRIEK) { 74 | if (options.shriekDelay < 0) options.shriekDelay = 0; 75 | options.data = options.shriekDelay; 76 | } 77 | 78 | if (particle == SCULK_CHARGE) { 79 | options.data = options.sculkChargeRotation; 80 | } 81 | 82 | spawnParticle(particle, options, center, range, targetPlayers); 83 | } 84 | 85 | @SuppressWarnings({"deprecation"}) 86 | protected void displayItem(Particle particle, ParticleOptions options, Location center, double range, List targetPlayers) { 87 | Material material = options.material; 88 | if (material == null || material.isAir()) return; 89 | 90 | ItemStack item = new ItemStack(material); 91 | item.setDurability(options.materialData); 92 | options.data = item; 93 | spawnParticle(particle, options, center, range, targetPlayers); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /Compatibility/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | com.elmakers.mine.bukkit 6 | EffectLib-parent 7 | 10.11-SNAPSHOT 8 | ../pom.xml 9 | 10 | 11 | 4.0.0 12 | com.elmakers.mine.bukkit.compatibility 13 | EffectLib-Compatibility 14 | 10.11-SNAPSHOT 15 | 16 | EffectLib-Compatibility 17 | The compatibility layer for EffectLib 18 | 19 | pom 20 | 21 | 22 | common 23 | modern 24 | v1_12 25 | v1_13 26 | v1_21_4 27 | main 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Compatibility/v1_12/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | com.elmakers.mine.bukkit.compatibility 7 | EffectLib-Compatibility 8 | 10.11-SNAPSHOT 9 | 10 | 11 | EffectLib-Compatibility-v1_12 12 | 13 | 14 | 15 | org.spigotmc 16 | spigot-api 17 | 1.12-R0.1-SNAPSHOT 18 | provided 19 | 20 | 21 | com.elmakers.mine.bukkit.compatibility 22 | EffectLib-Compatibility-common 23 | 10.11-SNAPSHOT 24 | compile 25 | 26 | 27 | 28 | 29 | 30 | 31 | org.apache.maven.plugins 32 | maven-compiler-plugin 33 | 3.11.0 34 | 35 | 8 36 | 8 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Compatibility/v1_12/src/main/java/de/slikey/effectlib/util/versions/ParticleDisplay_12.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.util.versions; 2 | 3 | import de.slikey.effectlib.util.ParticleDisplay; 4 | 5 | public class ParticleDisplay_12 extends ParticleDisplay { 6 | // This class is a placeholder now that the display() logic has been made 7 | // cross-version and generic, see ParticleDisplay.display 8 | } 9 | -------------------------------------------------------------------------------- /Compatibility/v1_13/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | com.elmakers.mine.bukkit.compatibility 7 | EffectLib-Compatibility 8 | 10.11-SNAPSHOT 9 | 10 | 11 | EffectLib-Compatibility-v1_13 12 | 13 | 14 | 15 | org.spigotmc 16 | spigot-api 17 | 1.13-R0.1-SNAPSHOT 18 | provided 19 | 20 | 21 | com.elmakers.mine.bukkit.compatibility 22 | EffectLib-Compatibility-common 23 | 10.11-SNAPSHOT 24 | compile 25 | 26 | 27 | 28 | 29 | 30 | 31 | org.apache.maven.plugins 32 | maven-compiler-plugin 33 | 3.11.0 34 | 35 | 8 36 | 8 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Compatibility/v1_13/src/main/java/de/slikey/effectlib/util/versions/ParticleDisplay_13.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.util.versions; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.Location; 5 | import org.bukkit.block.data.BlockData; 6 | import org.bukkit.entity.Player; 7 | 8 | import de.slikey.effectlib.util.ParticleDisplay; 9 | import de.slikey.effectlib.util.ParticleOptions; 10 | 11 | public class ParticleDisplay_13 extends ParticleDisplay { 12 | 13 | protected void displayFakeBlock(final Player player, Location center, ParticleOptions options) { 14 | if (options.blockData == null) return; 15 | if (!center.getBlock().isEmpty()) return; 16 | 17 | BlockData blockData = Bukkit.createBlockData(options.blockData.toLowerCase()); 18 | final Location b = center.getBlock().getLocation().clone(); 19 | player.sendBlockChange(b, blockData); 20 | 21 | Bukkit.getScheduler().runTaskLaterAsynchronously(manager.getOwningPlugin(), new Runnable() { 22 | @Override 23 | public void run() { 24 | player.sendBlockChange(b, b.getBlock().getBlockData()); 25 | } 26 | }, options.blockDuration); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Compatibility/v1_21_4/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | com.elmakers.mine.bukkit.compatibility 7 | EffectLib-Compatibility 8 | 10.11-SNAPSHOT 9 | 10 | 11 | EffectLib-Compatibility-v1_21_4 12 | 13 | 14 | 15 | org.spigotmc 16 | spigot-api 17 | 1.21.4-R0.1-SNAPSHOT 18 | provided 19 | 20 | 21 | com.elmakers.mine.bukkit.compatibility 22 | EffectLib-Compatibility-common 23 | 10.11-SNAPSHOT 24 | compile 25 | 26 | 27 | com.elmakers.mine.bukkit.compatibility 28 | EffectLib-Compatibility-modern 29 | 10.11-SNAPSHOT 30 | compile 31 | 32 | 33 | 34 | 35 | 36 | 37 | org.apache.maven.plugins 38 | maven-compiler-plugin 39 | 3.11.0 40 | 41 | 8 42 | 8 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /Compatibility/v1_21_4/src/main/java/de/slikey/effectlib/util/versions/ParticleDisplay_21_4.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.util.versions; 2 | 3 | import java.util.List; 4 | 5 | import org.bukkit.Bukkit; 6 | import org.bukkit.Color; 7 | import org.bukkit.Location; 8 | import org.bukkit.Particle; 9 | import org.bukkit.block.data.BlockData; 10 | import org.bukkit.entity.Player; 11 | 12 | import de.slikey.effectlib.util.ParticleOptions; 13 | 14 | public class ParticleDisplay_21_4 extends ParticleDisplay_Modern { 15 | 16 | protected void spawnParticle(Particle particle, ParticleOptions options, Location center, double range, List targetPlayers) { 17 | try { 18 | boolean forceShow = options.forceShow || manager.getForceShow(); 19 | if (targetPlayers == null) { 20 | double squared = range * range; 21 | for (final Player player : Bukkit.getOnlinePlayers()) { 22 | if (!manager.isVisiblePlayer(player, center, squared)) continue; 23 | 24 | if (hasColorDataType && particle == Particle.valueOf("ENTITY_EFFECT")) { 25 | player.spawnParticle(particle, center, options.amount, options.offsetX, options.offsetY, options.offsetZ, options.speed, options.color == null ? Color.WHITE : options.color, forceShow); 26 | } else { 27 | player.spawnParticle(particle, center, options.amount, options.offsetX, options.offsetY, options.offsetZ, options.speed, options.data, forceShow); 28 | } 29 | 30 | displayFakeBlock(player, center, options); 31 | } 32 | return; 33 | } 34 | 35 | for (final Player player : targetPlayers) { 36 | if (manager.isPlayerIgnored(player)) continue; 37 | player.spawnParticle(particle, center, options.amount, options.offsetX, options.offsetY, options.offsetZ, options.speed, options.data, forceShow); 38 | displayFakeBlock(player, center, options); 39 | } 40 | 41 | } catch (Exception ex) { 42 | if (manager != null) manager.onError(ex); 43 | } 44 | } 45 | 46 | protected void displayFakeBlock(final Player player, Location center, ParticleOptions options) { 47 | if (options.blockData == null) return; 48 | if (!center.getBlock().isPassable() && !center.getBlock().isEmpty()) return; 49 | 50 | BlockData blockData = Bukkit.createBlockData(options.blockData.toLowerCase()); 51 | final Location b = center.getBlock().getLocation().clone(); 52 | player.sendBlockChange(b, blockData); 53 | 54 | Bukkit.getScheduler().runTaskLaterAsynchronously(manager.getOwningPlugin(), new Runnable() { 55 | @Override 56 | public void run() { 57 | player.sendBlockChange(b, b.getBlock().getBlockData()); 58 | } 59 | }, options.blockDuration); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /EffectLib/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 4.0.0 5 | com.elmakers.mine.bukkit 6 | EffectLib 7 | 10.11-SNAPSHOT 8 | 9 | EffectLib 10 | A library for Bukkit plugins to make complicated particle effects 11 | https://github.com/elBukkit/EffectLib/ 12 | 13 | 14 | elMakers 15 | http://www.elmakers.com/ 16 | 17 | 18 | 19 | 20 | Nathan Wolf 21 | nathan@elmakers.com 22 | elMakers 23 | http://www.elmakers.com 24 | 25 | 26 | PikaMug 27 | 28 | 29 | Chronoken 30 | 31 | 32 | Slikey 33 | 34 | 35 | 36 | 37 | 38 | MIT License 39 | http://opensource.org/licenses/mit-license 40 | 41 | 42 | 43 | 44 | scm:git:git://github.com/elBukkit/EffectLib.git 45 | scm:git:git@github.com:elBukkit/EffectLib.git 46 | https://github.com/elBukkit/EffectLib/ 47 | master 48 | 49 | 50 | 51 | 52 | ossrh 53 | https://oss.sonatype.org/content/repositories/snapshots 54 | 55 | 56 | ossrh 57 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 58 | 59 | 60 | 61 | 62 | 63 | org.spigotmc 64 | spigot-api 65 | 66 | 1.19.3-R0.1-SNAPSHOT 67 | 68 | 69 | 70 | provided 71 | 72 | 73 | javax.annotation 74 | javax.annotation-api 75 | 1.3.2 76 | 77 | 78 | com.elmakers.math 79 | exp4j 80 | 1.0 81 | compile 82 | 83 | 84 | com.elmakers.mine.bukkit.compatibility 85 | EffectLib-Compatibility-main 86 | 10.11-SNAPSHOT 87 | compile 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | src/main/resources/ 96 | true 97 | 98 | 99 | 100 | 101 | 102 | org.apache.maven.plugins 103 | maven-compiler-plugin 104 | 3.11.0 105 | 106 | 8 107 | 8 108 | 109 | 110 | 111 | 112 | org.apache.maven.plugins 113 | maven-shade-plugin 114 | 3.4.1 115 | 116 | 117 | package 118 | 119 | shade 120 | 121 | 122 | 123 | 124 | net.objecthunter.exp4j 125 | de.slikey.exp4j 126 | 127 | 128 | 129 | 130 | com.elmakers.math:exp4j 131 | 132 | META-INF/MANIFEST.MF 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | org.apache.maven.plugins 144 | maven-javadoc-plugin 145 | 146 | -Xdoclint:none 147 | 148 | 3.5.0 149 | 150 | 151 | deploy 152 | attach-javadocs 153 | 154 | jar 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | org.apache.maven.plugins 163 | maven-source-plugin 164 | 3.2.1 165 | 166 | 167 | attach-sources 168 | 169 | jar-no-fork 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | org.apache.maven.plugins 178 | maven-gpg-plugin 179 | 3.0.1 180 | 181 | 182 | sign-artifacts 183 | deploy 184 | 185 | sign 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | org.sonatype.plugins 194 | nexus-staging-maven-plugin 195 | 1.6.13 196 | true 197 | 198 | ossrh 199 | https://oss.sonatype.org/ 200 | true 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/EffectLib.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib; 2 | 3 | import java.util.List; 4 | 5 | import org.bukkit.event.HandlerList; 6 | import org.bukkit.plugin.java.JavaPlugin; 7 | 8 | /*! \mainpage EffectLib Plugin API 9 | * 10 | * \section intro_sec Introduction 11 | * 12 | * This is the API for EffectLib, which gives developers access 13 | * to a wide variety of visual effects for use in their Plugins. 14 | * 15 | * \section issues_sec Issues 16 | * 17 | * For issues with the API, or suggestions, please use the devbukkit 18 | * project page: 19 | * 20 | * http://dev.bukkit.org/bukkit-plugins/effectlib/ 21 | * 22 | * \section start_sec Getting Started 23 | * 24 | * If you haven't done so already, get started with Bukkit by getting a basic 25 | * shell of a plugin working. You should at least have a working Plugin that 26 | * loads in Bukkit (add a debug print to onEnable to be sure!) before you 27 | * start trying to integrate with other Plugins. See here for general help: 28 | * 29 | * http://wiki.bukkit.org/Plugin_Tutorial 30 | * 31 | * \section maven_sec Building with Maven 32 | * 33 | * Once you have a project set up, it is easy to build against EffectLib 34 | * with Maven. Simply add the elmakers repository to your repository list, 35 | * and then add a dependency for EffectLib. A typical setup would look like: 36 | * 37 | *
 38 | * <dependencies>
 39 | * <dependency>
 40 | *     <groupId>org.bukkit</groupId>
 41 | *     <artifactId>bukkit</artifactId>
 42 | *     <version>1.6.4-R2.0</version>
 43 | *     <scope>provided</scope>
 44 | * </dependency>
 45 | * <dependency>
 46 | *     <groupId>de.slikey</groupId>
 47 | *     <artifactId>EffectLib</artifactId>
 48 | *     <version>1.4</version>
 49 | *     <scope>provided</scope>
 50 | * </dependency>
 51 | * </dependencies>
 52 | * <repositories>
 53 | * <repository>
 54 | *     <id>bukkit-repo</id>
 55 | *     <url>http://repo.bukkit.org/content/groups/public/ </url>
 56 | * </repository>
 57 | * <repository>
 58 | *     <id>elmakers-repo</id>
 59 | *     <url>http://maven.elmakers.com/repository/ </url>
 60 | * </repository>
 61 | * </repositories>
 62 | * 
63 | * 64 | * If you don't want to depend on EffectLib as an external library, you 65 | * can use the Maven shade plugin to "shade" the library into your own plugin. 66 | * This will relocate the library so you don't conflict with another instance 67 | * of it, even though all the EffectLib code is built in. Here is an example pom section: 68 | * 69 | *
 70 | * <plugin>
 71 | *     <groupId>org.apache.maven.plugins</groupId>
 72 | *     <artifactId>maven-shade-plugin</artifactId>
 73 | *     <version>1.5</version>
 74 | *     <executions>
 75 | *         <execution>
 76 | *             <phase>package</phase>
 77 | *             <goals>
 78 | *                 <goal>shade</goal>
 79 | *             </goals>
 80 | *             <configuration>
 81 | *                 <relocations>
 82 | *                     <relocation>
 83 | *                         <pattern>de.slikey</pattern>
 84 | *                         <shadedPattern>org.myplugin.slikey</shadedPattern>
 85 | *                     </relocation>
 86 | *                 </relocations>
 87 | *             </configuration>
 88 | *         </execution>
 89 | *     </executions>
 90 | * </plugin>
 91 | * 
92 | * 93 | * Once shaded, you can instantiate an EffectManager directly, passing it your Plugin 94 | * instance. 95 | * 96 | * \section plugin_sec Unshaded Usage 97 | * 98 | * 1. Get the instance of EffectLib first: 99 | * EffectLib lib = getEffectLib(); // See below 100 | * 2. Create a new EffectManager to handle your effects: 101 | * EffectManager em = new EffectManager(lib); 102 | * 3. Create a new Effect and add start it: 103 | * new BleedEntityEffect(em, player); 104 | * 4. Dispose the EffectManager after creating the last effect: 105 | * em.disposeOnTermination(); 106 | * 107 | * If you wish to softdepend to EffectLib, make sure to not use any of the effect classes 108 | * unless you know the EffectLib plugin is loaded. Make sure you're not building the Lib 109 | * into your plugin, it should always be referenced externally (e.g. "provided" in Maven). 110 | * 111 | *
112 | *       public EffectLib getEffectLib() {
113 | *           Plugin effectLib = Bukkit.getPluginManager().getPlugin("EffectLib");
114 | *             if (effectLib == null || !(effectLib instanceof EffectLib)) {
115 | *                 return null;
116 | *             }
117 | *           return (EffectLib)effectLib;
118 | *       }
119 | * 
120 | * 121 | */ 122 | public final class EffectLib extends JavaPlugin { 123 | 124 | private static EffectLib instance; 125 | 126 | public EffectLib() { 127 | instance = this; 128 | } 129 | 130 | @Override 131 | public void onEnable() { 132 | 133 | } 134 | 135 | @Override 136 | public void onDisable() { 137 | EffectManager.disposeAll(); 138 | HandlerList.unregisterAll(this); 139 | } 140 | 141 | public List getEffectManagers() { 142 | return EffectManager.getManagers(); 143 | } 144 | 145 | public static EffectLib instance() { 146 | return instance; 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/EffectType.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib; 2 | 3 | public enum EffectType { 4 | 5 | /** 6 | * Effect is once played instantly. 7 | */ 8 | INSTANT, 9 | /** 10 | * Effect is several times played instantly. Set the interval with {@link Effect#period}. 11 | */ 12 | REPEATING, 13 | /** 14 | * Effect is once delayed played. Set delay with {@link Effect#delay}. 15 | */ 16 | DELAYED 17 | 18 | } 19 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/AnimatedBallEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Particle; 4 | import org.bukkit.Location; 5 | import org.bukkit.util.Vector; 6 | 7 | import de.slikey.effectlib.Effect; 8 | import de.slikey.effectlib.EffectType; 9 | import de.slikey.effectlib.EffectManager; 10 | import de.slikey.effectlib.util.MathUtils; 11 | import de.slikey.effectlib.util.ParticleUtil; 12 | import de.slikey.effectlib.util.VectorUtils; 13 | 14 | /** 15 | * Creates an animated Sphere.. Thanks to the author for sharing it! 16 | * Demo on YouTube 17 | * 18 | * @author Qukie 19 | */ 20 | public class AnimatedBallEffect extends Effect { 21 | 22 | /** 23 | * Ball particles total (150) 24 | */ 25 | public int particles = 150; 26 | 27 | /** 28 | * The amount of particles, displayed in one iteration (10) 29 | */ 30 | public int particlesPerIteration = 10; 31 | 32 | /** 33 | * Size of this ball (1) 34 | */ 35 | public float size = 1F; 36 | 37 | /** 38 | * Factors (1, 2, 1) 39 | */ 40 | public float xFactor = 1F, yFactor = 2F, zFactor = 1F; 41 | 42 | /** 43 | * Offsets (0, 0.8, 0) 44 | */ 45 | public float xOffset, yOffset = 0.8F, zOffset; 46 | 47 | /** 48 | * Rotation of the ball. 49 | */ 50 | public double xRotation, yRotation, zRotation = 0; 51 | 52 | /** 53 | * Internal Counter 54 | */ 55 | protected int step = 0; 56 | 57 | public AnimatedBallEffect(EffectManager effectManager) { 58 | super(effectManager); 59 | type = EffectType.REPEATING; 60 | particle = ParticleUtil.getParticle("SPELL_WITCH"); 61 | iterations = 500; 62 | period = 1; 63 | } 64 | 65 | @Override 66 | public void reset() { 67 | step = 0; 68 | } 69 | 70 | @Override 71 | public void onRun() { 72 | Vector vector = new Vector(); 73 | Location location = getLocation(); 74 | 75 | if (location == null) { 76 | cancel(); 77 | return; 78 | } 79 | 80 | float t; 81 | float r; 82 | float s; 83 | 84 | for (int i = 0; i < particlesPerIteration; i++) { 85 | step++; 86 | 87 | t = (MathUtils.PI / particles) * step; 88 | r = MathUtils.sin(t) * size; 89 | s = 2 * MathUtils.PI * t; 90 | 91 | vector.setX(xFactor * r * MathUtils.cos(s) + xOffset); 92 | vector.setZ(zFactor * r * MathUtils.sin(s) + zOffset); 93 | vector.setY(yFactor * size * MathUtils.cos(t) + yOffset); 94 | 95 | VectorUtils.rotateVector(vector, xRotation, yRotation, zRotation); 96 | 97 | display(particle, location.add(vector)); 98 | location.subtract(vector); 99 | } 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/ArcEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Particle; 4 | import org.bukkit.Location; 5 | import org.bukkit.util.Vector; 6 | 7 | import de.slikey.effectlib.Effect; 8 | import de.slikey.effectlib.EffectType; 9 | import de.slikey.effectlib.EffectManager; 10 | 11 | public class ArcEffect extends Effect { 12 | 13 | /** 14 | * Height of the arc in blocks 15 | */ 16 | public float height = 2; 17 | 18 | /** 19 | * Particles per arc 20 | */ 21 | public int particles = 100; 22 | 23 | /** 24 | * Internal counter 25 | */ 26 | protected int step = 0; 27 | 28 | public ArcEffect(EffectManager effectManager) { 29 | super(effectManager); 30 | type = EffectType.REPEATING; 31 | particle = Particle.FLAME; 32 | period = 1; 33 | iterations = 200; 34 | } 35 | 36 | @Override 37 | public void reset() { 38 | step = 0; 39 | } 40 | 41 | @Override 42 | public void onRun() { 43 | Location location = getLocation(); 44 | Location target = getTarget(); 45 | 46 | if (target == null) { 47 | cancel(); 48 | return; 49 | } 50 | 51 | if (location == null) { 52 | cancel(); 53 | return; 54 | } 55 | 56 | Vector link = target.toVector().subtract(location.toVector()); 57 | float length = (float) link.length(); 58 | float pitch = (float) (4 * height / Math.pow(length, 2)); 59 | 60 | Vector v; 61 | float x; 62 | float y; 63 | 64 | for (int i = 0; i < particles; i++) { 65 | v = link.clone().normalize().multiply(length * i / particles); 66 | x = ((float) i / particles) * length - length / 2; 67 | y = (float) (-pitch * Math.pow(x, 2) + height); 68 | 69 | location.add(v).add(0, y, 0); 70 | display(particle, location); 71 | location.subtract(0, y, 0).subtract(v); 72 | 73 | step++; 74 | } 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/AtomEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Color; 4 | import org.bukkit.Location; 5 | import org.bukkit.Particle; 6 | import org.bukkit.util.Vector; 7 | 8 | import de.slikey.effectlib.Effect; 9 | import de.slikey.effectlib.EffectType; 10 | import de.slikey.effectlib.EffectManager; 11 | import de.slikey.effectlib.util.ParticleUtil; 12 | import de.slikey.effectlib.util.RandomUtils; 13 | import de.slikey.effectlib.util.VectorUtils; 14 | 15 | public class AtomEffect extends Effect { 16 | 17 | /** 18 | * ParticleType of the nucleus 19 | */ 20 | public Particle particleNucleus = ParticleUtil.getParticle("DRIP_WATER"); 21 | public Color colorNucleus = null; 22 | 23 | /** 24 | * ParticleType of orbitals 25 | */ 26 | public Particle particleOrbital = ParticleUtil.getParticle("DRIP_LAVA"); 27 | public Color colorOrbital = null; 28 | 29 | /** 30 | * Radius of the atom 31 | */ 32 | public double radius = 3; 33 | 34 | /** 35 | * Radius of the nucleus as a fraction of the atom-radius 36 | */ 37 | public float radiusNucleus = 0.2f; 38 | 39 | /** 40 | * Particles to be spawned in the nucleus per iteration 41 | */ 42 | public int particlesNucleus = 10; 43 | 44 | /** 45 | * Particles to be spawned per orbital per iteration 46 | */ 47 | public int particlesOrbital = 10; 48 | 49 | /** 50 | * Orbitals around the nucleus 51 | */ 52 | public int orbitals = 3; 53 | 54 | /** 55 | * Rotation around the Y-axis 56 | */ 57 | public double rotation = 0; 58 | 59 | /** 60 | * Whether or not to orient to the direction of the source location 61 | */ 62 | public boolean orient = false; 63 | 64 | /** 65 | * Velocity of the orbitals 66 | */ 67 | public double angularVelocity = Math.PI / 80D; 68 | 69 | /** 70 | * Internal counter 71 | */ 72 | protected int step = 0; 73 | 74 | public AtomEffect(EffectManager effectManager) { 75 | super(effectManager); 76 | type = EffectType.REPEATING; 77 | period = 2; 78 | iterations = 200; 79 | } 80 | 81 | @Override 82 | public void reset() { 83 | step = 0; 84 | } 85 | 86 | @Override 87 | public void onRun() { 88 | Location location = getLocation(); 89 | 90 | if (location == null) { 91 | cancel(); 92 | return; 93 | } 94 | 95 | Vector v; 96 | double angle; 97 | double xRotation; 98 | 99 | for (int i = 0; i < particlesNucleus; i++) { 100 | v = RandomUtils.getRandomVector().multiply(radius * radiusNucleus); 101 | if (orient) v = VectorUtils.rotateVector(v, location); 102 | 103 | location.add(v); 104 | display(particleNucleus, location, colorNucleus); 105 | location.subtract(v); 106 | } 107 | 108 | for (int i = 0; i < particlesOrbital; i++) { 109 | angle = step * angularVelocity; 110 | for (int j = 0; j < orbitals; j++) { 111 | xRotation = (Math.PI / orbitals) * j; 112 | v = new Vector(Math.cos(angle), Math.sin(angle), 0).multiply(radius); 113 | 114 | VectorUtils.rotateAroundAxisX(v, xRotation); 115 | VectorUtils.rotateAroundAxisY(v, rotation); 116 | if (orient) v = VectorUtils.rotateVector(v, location); 117 | 118 | location.add(v); 119 | display(particleOrbital, location, colorOrbital); 120 | location.subtract(v); 121 | } 122 | step++; 123 | } 124 | } 125 | 126 | } 127 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/BigBangEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Color; 4 | import org.bukkit.Sound; 5 | import org.bukkit.Location; 6 | import org.bukkit.util.Vector; 7 | import org.bukkit.FireworkEffect; 8 | import org.bukkit.entity.Firework; 9 | import org.bukkit.entity.EntityType; 10 | import org.bukkit.FireworkEffect.Builder; 11 | import org.bukkit.inventory.meta.FireworkMeta; 12 | 13 | import de.slikey.effectlib.Effect; 14 | import de.slikey.effectlib.EffectType; 15 | import de.slikey.effectlib.EffectManager; 16 | import de.slikey.effectlib.util.RandomUtils; 17 | 18 | public class BigBangEffect extends Effect { 19 | 20 | private static EntityType fireworkEntityType; 21 | 22 | public FireworkEffect.Type fireworkType = FireworkEffect.Type.BURST; 23 | public Color color2 = Color.ORANGE; 24 | public Color color3 = Color.BLACK; 25 | public Color fadeColor = Color.BLACK; 26 | public int intensity = 2; 27 | public float radius = 2; 28 | public int explosions = 10; 29 | public int soundInterval = 5; 30 | public Sound sound = Sound.ENTITY_GENERIC_EXPLODE; 31 | public float soundVolume = 100; 32 | public float soundPitch = 1; 33 | protected int step = 0; 34 | 35 | protected FireworkEffect firework; 36 | 37 | private static void initializeConstants() { 38 | if (fireworkEntityType != null) return; 39 | 40 | try { 41 | fireworkEntityType = EntityType.valueOf("FIREWORK_ROCKET"); 42 | } catch (Exception legacy) { 43 | fireworkEntityType = EntityType.valueOf("FIREWORK"); 44 | } 45 | 46 | } 47 | 48 | public BigBangEffect(EffectManager effectManager) { 49 | super(effectManager); 50 | color = Color.RED; 51 | type = EffectType.REPEATING; 52 | period = 2; 53 | iterations = 400; 54 | asynchronous = false; 55 | } 56 | 57 | @Override 58 | public void reset() { 59 | step = 0; 60 | } 61 | 62 | @Override 63 | public void onRun() { 64 | Location location = getLocation(); 65 | Vector v; 66 | 67 | if (location == null || location.getWorld() == null) { 68 | cancel(); 69 | return; 70 | } 71 | 72 | if (firework == null) { 73 | Builder b = FireworkEffect.builder().with(fireworkType); 74 | b.withColor(color).withColor(color2).withColor(color3); 75 | b.withFade(fadeColor); 76 | b.trail(true); 77 | firework = b.build(); 78 | } 79 | 80 | for (int i = 0; i < explosions; i++) { 81 | v = RandomUtils.getRandomVector().multiply(radius); 82 | detonate(location, v); 83 | if (soundInterval != 0 && step % soundInterval == 0) { 84 | location.getWorld().playSound(location, sound, soundVolume, soundPitch); 85 | } 86 | } 87 | step++; 88 | } 89 | 90 | protected void detonate(Location location, Vector v) { 91 | initializeConstants(); 92 | if (location != null && location.getWorld() != null) { 93 | final Firework firework = (Firework) location.getWorld().spawnEntity(location.add(v), fireworkEntityType); 94 | location.subtract(v); 95 | FireworkMeta meta = firework.getFireworkMeta(); 96 | meta.setPower(0); 97 | for (int i = 0; i < intensity; i++) { 98 | meta.addEffect(this.firework); 99 | } 100 | firework.setFireworkMeta(meta); 101 | firework.detonate(); 102 | } 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/BleedEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.Material; 5 | import org.bukkit.entity.Entity; 6 | 7 | import de.slikey.effectlib.Effect; 8 | import de.slikey.effectlib.EffectType; 9 | import de.slikey.effectlib.EffectManager; 10 | import de.slikey.effectlib.util.RandomUtils; 11 | 12 | public class BleedEffect extends Effect { 13 | 14 | /** 15 | * Play the Hurt Effect for the Player 16 | */ 17 | public boolean hurt = true; 18 | 19 | /** 20 | * Height of the blood spurt 21 | */ 22 | public double height = 1.75; 23 | 24 | /** 25 | * Color of blood. Default is red (152) 26 | */ 27 | public Material material = Material.REDSTONE_BLOCK; 28 | 29 | public BleedEffect(EffectManager effectManager) { 30 | super(effectManager); 31 | type = EffectType.REPEATING; 32 | period = 4; 33 | iterations = 25; 34 | } 35 | 36 | @Override 37 | public void onRun() { 38 | // Location to spawn the blood-item. 39 | Location location = getLocation(); 40 | 41 | if (location == null || location.getWorld() == null) { 42 | cancel(); 43 | return; 44 | } 45 | 46 | location.add(0, RandomUtils.random.nextFloat() * height, 0); 47 | location.getWorld().playEffect(location, org.bukkit.Effect.STEP_SOUND, material); 48 | 49 | Entity entity = getEntity(); 50 | if (hurt && entity != null) entity.playEffect(org.bukkit.EntityEffect.HURT); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/CircleEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Particle; 4 | import org.bukkit.Location; 5 | import org.bukkit.util.Vector; 6 | 7 | import de.slikey.effectlib.Effect; 8 | import de.slikey.effectlib.EffectType; 9 | import de.slikey.effectlib.EffectManager; 10 | import de.slikey.effectlib.util.MathUtils; 11 | import de.slikey.effectlib.util.ParticleUtil; 12 | import de.slikey.effectlib.util.VectorUtils; 13 | 14 | public class CircleEffect extends Effect { 15 | 16 | /** 17 | * Whether or not to orient to the direction of the source location 18 | */ 19 | public boolean orient = false; 20 | 21 | /** 22 | * Rotation of the torus. 23 | */ 24 | public double xRotation, yRotation, zRotation = 0; 25 | 26 | /** 27 | * Turns the circle by this angle each iteration around the x-axis 28 | */ 29 | public double angularVelocityX = Math.PI / 200; 30 | 31 | /** 32 | * Turns the circle by this angle each iteration around the y-axis 33 | */ 34 | public double angularVelocityY = Math.PI / 170; 35 | 36 | /** 37 | * Turns the circle by this angle each iteration around the z-axis 38 | */ 39 | public double angularVelocityZ = Math.PI / 155; 40 | 41 | /** 42 | * Radius of circle above head 43 | */ 44 | public float radius = 0.4F; 45 | 46 | /** 47 | * Used to make a partial circle 48 | */ 49 | public double maxAngle = Math.PI * 2; 50 | 51 | /** 52 | * Start at the same location each step, use this 53 | * along with maxAngle and wholeCircle to form persistent semicircles 54 | */ 55 | public boolean resetCircle = false; 56 | 57 | /** 58 | * Current step. Works as a counter 59 | */ 60 | protected float step = 0; 61 | 62 | /** 63 | * Subtracts from location if needed 64 | */ 65 | public double xSubtract, ySubtract, zSubtract; 66 | 67 | /** 68 | * Should it rotate? 69 | */ 70 | public boolean enableRotation = true; 71 | 72 | /** 73 | * Amount of particles per circle 74 | */ 75 | public int particles = 20; 76 | 77 | /** 78 | * To make a whole circle each iteration 79 | */ 80 | public boolean wholeCircle = false; 81 | 82 | public CircleEffect(EffectManager effectManager) { 83 | super(effectManager); 84 | type = EffectType.REPEATING; 85 | particle = ParticleUtil.getParticle("VILLAGER_HAPPY"); 86 | period = 2; 87 | iterations = 50; 88 | } 89 | 90 | @Override 91 | public void reset() { 92 | step = 0; 93 | } 94 | 95 | @Override 96 | public void onRun() { 97 | Location location = getLocation(); 98 | 99 | if (location == null) { 100 | cancel(); 101 | return; 102 | } 103 | 104 | location.subtract(xSubtract, ySubtract, zSubtract); 105 | double inc = maxAngle / particles; 106 | int steps = wholeCircle ? particles : 1; 107 | 108 | double angle; 109 | Vector v; 110 | 111 | for (int i = 0; i < steps; i++) { 112 | angle = step * inc; 113 | v = new Vector(); 114 | 115 | v.setX(Math.cos(angle) * radius); 116 | v.setZ(Math.sin(angle) * radius); 117 | 118 | VectorUtils.rotateVector(v, xRotation, yRotation, zRotation); 119 | VectorUtils.rotateAroundAxisX(v, location.getPitch() * MathUtils.degreesToRadians); 120 | VectorUtils.rotateAroundAxisY(v, -location.getYaw() * MathUtils.degreesToRadians); 121 | 122 | if (enableRotation) { 123 | VectorUtils.rotateVector(v, angularVelocityX * step, angularVelocityY * step, angularVelocityZ * step); 124 | } 125 | 126 | if (orient) v = VectorUtils.rotateVector(v, location); 127 | 128 | display(particle, location.clone().add(v)); 129 | step++; 130 | } 131 | 132 | if (resetCircle) step = 0; 133 | } 134 | 135 | } 136 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/CloudEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Color; 4 | import org.bukkit.Location; 5 | import org.bukkit.Particle; 6 | import org.bukkit.util.Vector; 7 | 8 | import de.slikey.effectlib.Effect; 9 | import de.slikey.effectlib.EffectType; 10 | import de.slikey.effectlib.EffectManager; 11 | import de.slikey.effectlib.util.ParticleUtil; 12 | import de.slikey.effectlib.util.RandomUtils; 13 | 14 | public class CloudEffect extends Effect { 15 | 16 | /** 17 | * Particle of the cloud 18 | */ 19 | public Particle cloudParticle = Particle.CLOUD; 20 | public Color cloudColor = null; 21 | public float cloudSpeed = 0; 22 | public int cloudParticles = 50; 23 | 24 | /** 25 | * Particle of the rain/snow 26 | */ 27 | public Particle mainParticle = ParticleUtil.getParticle("DRIP_WATER"); 28 | public int mainParticles = 15; 29 | 30 | /** 31 | * Size of the cloud 32 | */ 33 | public float cloudSize = 0.7F; 34 | 35 | /** 36 | * Radius of the rain/snow 37 | */ 38 | public float particleRadius = cloudSize - 0.1F; 39 | 40 | /** 41 | * Y-Offset from location 42 | */ 43 | public double yOffset = 0.8; 44 | 45 | // Should the effect increase its height every iteration? 46 | public boolean increaseHeight = true; 47 | 48 | public CloudEffect(EffectManager manager) { 49 | super(manager); 50 | type = EffectType.REPEATING; 51 | period = 5; 52 | iterations = 50; 53 | } 54 | 55 | @Override 56 | public void onRun() { 57 | Location location = getLocation(); 58 | 59 | if (location == null) { 60 | cancel(); 61 | return; 62 | } 63 | 64 | location.add(0, yOffset, 0); 65 | 66 | Vector v; 67 | 68 | for (int i = 0; i < cloudParticles; i++) { 69 | v = RandomUtils.getRandomCircleVector().multiply(RandomUtils.random.nextDouble() * cloudSize); 70 | display(cloudParticle, location.add(v), cloudColor, cloudSpeed, 1); 71 | location.subtract(v); 72 | } 73 | 74 | Location l; 75 | if (increaseHeight) l = location.add(0, 0.2, 0); 76 | else l = location; 77 | 78 | int r; 79 | double x; 80 | double z; 81 | 82 | for (int i = 0; i < mainParticles; i++) { 83 | r = RandomUtils.random.nextInt(2); 84 | x = RandomUtils.random.nextDouble() * particleRadius; 85 | z = RandomUtils.random.nextDouble() * particleRadius; 86 | 87 | l.add(x, 0, z); 88 | if (r != 1) display(mainParticle, l); 89 | 90 | l.subtract(x, 0, z); 91 | l.subtract(x, 0, z); 92 | 93 | if (r != 1) display(mainParticle, l); 94 | l.add(x, 0, z); 95 | } 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/ColoredImageEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import java.awt.Color; 4 | import java.awt.image.BufferedImage; 5 | 6 | import org.bukkit.Location; 7 | import org.bukkit.util.Vector; 8 | 9 | import de.slikey.effectlib.EffectManager; 10 | import de.slikey.effectlib.util.BaseImageEffect; 11 | 12 | public class ColoredImageEffect extends BaseImageEffect { 13 | 14 | public ColoredImageEffect(EffectManager effectManager) { 15 | super(effectManager); 16 | } 17 | 18 | protected void display(BufferedImage image, Vector v, Location location, int pixel) { 19 | Color c = new Color(pixel); 20 | display(particle, location.add(v), org.bukkit.Color.fromRGB(c.getRed(), c.getGreen(), c.getBlue())); 21 | location.subtract(v); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/ConeEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Particle; 4 | import org.bukkit.Location; 5 | import org.bukkit.util.Vector; 6 | 7 | import de.slikey.effectlib.Effect; 8 | import de.slikey.effectlib.EffectType; 9 | import de.slikey.effectlib.EffectManager; 10 | import de.slikey.effectlib.util.MathUtils; 11 | import de.slikey.effectlib.util.RandomUtils; 12 | import de.slikey.effectlib.util.VectorUtils; 13 | 14 | public class ConeEffect extends Effect { 15 | 16 | /** 17 | * Growing per iteration in the length (0.05) 18 | */ 19 | public float lengthGrow = 0.05F; 20 | 21 | /** 22 | * Radials per iteration to spawn the next particle (PI / 16) 23 | */ 24 | public double angularVelocity = Math.PI / 16; 25 | 26 | /** 27 | * Cone-particles per interation (10) 28 | */ 29 | public int particles = 10; 30 | 31 | /** 32 | * Growth in blocks per iteration on the radius (0.006) 33 | */ 34 | public float radiusGrow = 0.006F; 35 | 36 | /** 37 | * Conesize in particles per cone 38 | */ 39 | public int particlesCone = 180; 40 | 41 | /** 42 | * Start-angle or rotation of the cone 43 | */ 44 | public double rotation = 0; 45 | 46 | /** 47 | * Randomize every cone on creation (false) 48 | */ 49 | public boolean randomize = false; 50 | 51 | /** 52 | * Solid cone 53 | */ 54 | public boolean solid = false; 55 | 56 | /** 57 | * Amount of strands 58 | */ 59 | public int strands = 1; 60 | 61 | /** 62 | * Current step. Works as counter 63 | */ 64 | protected int step = 0; 65 | 66 | public ConeEffect(EffectManager effectManager) { 67 | super(effectManager); 68 | type = EffectType.REPEATING; 69 | particle = Particle.FLAME; 70 | period = 1; 71 | iterations = 200; 72 | } 73 | 74 | @Override 75 | public void reset() { 76 | step = 0; 77 | } 78 | 79 | @Override 80 | public void onRun() { 81 | Location location = getLocation(); 82 | 83 | if (location == null) { 84 | cancel(); 85 | return; 86 | } 87 | 88 | double angle; 89 | float radius; 90 | float length; 91 | 92 | Vector v; 93 | 94 | for (int x = 0; x < particles; x++) { 95 | 96 | if (step > particlesCone) step = 0; 97 | if (randomize && step == 0) rotation = RandomUtils.getRandomAngle(); 98 | for (int y = 0; y < strands; y++) { 99 | angle = step * angularVelocity + rotation + (2 * Math.PI * y / strands); 100 | radius = step * radiusGrow; 101 | if (solid) { 102 | radius *= RandomUtils.random.nextFloat(); 103 | } 104 | length = step * lengthGrow; 105 | 106 | v = new Vector(Math.cos(angle) * radius, length, Math.sin(angle) * radius); 107 | VectorUtils.rotateAroundAxisX(v, (location.getPitch() + 90) * MathUtils.degreesToRadians); 108 | VectorUtils.rotateAroundAxisY(v, -location.getYaw() * MathUtils.degreesToRadians); 109 | 110 | location.add(v); 111 | display(particle, location); 112 | location.subtract(v); 113 | } 114 | step++; 115 | } 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/CubeEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Particle; 4 | import org.bukkit.Location; 5 | import org.bukkit.util.Vector; 6 | 7 | import de.slikey.effectlib.Effect; 8 | import de.slikey.effectlib.EffectType; 9 | import de.slikey.effectlib.EffectManager; 10 | import de.slikey.effectlib.util.MathUtils; 11 | import de.slikey.effectlib.util.VectorUtils; 12 | 13 | public class CubeEffect extends Effect { 14 | 15 | /** 16 | * Length of the edges 17 | */ 18 | public float edgeLength = 3; 19 | 20 | /** 21 | * Turns the cube by this angle each iteration around the x-axis 22 | */ 23 | public double angularVelocityX = Math.PI / 200; 24 | 25 | /** 26 | * Turns the cube by this angle each iteration around the y-axis 27 | */ 28 | public double angularVelocityY = Math.PI / 170; 29 | 30 | /** 31 | * Turns the cube by this angle each iteration around the z-axis 32 | */ 33 | public double angularVelocityZ = Math.PI / 155; 34 | 35 | /** 36 | * Particles in each row 37 | */ 38 | public int particles = 8; 39 | 40 | /** 41 | * True if rotation is enable 42 | */ 43 | public boolean enableRotation = true; 44 | 45 | /** 46 | * Only the outlines are drawn 47 | */ 48 | public boolean outlineOnly = true; 49 | 50 | /** 51 | * Should it orient pitch and yaw? 52 | */ 53 | public boolean orient = false; 54 | 55 | /** 56 | * Current step. Works as counter 57 | */ 58 | protected int step = 0; 59 | 60 | public CubeEffect(EffectManager effectManager) { 61 | super(effectManager); 62 | type = EffectType.REPEATING; 63 | particle = Particle.FLAME; 64 | period = 5; 65 | iterations = 200; 66 | } 67 | 68 | @Override 69 | public void reset() { 70 | step = 0; 71 | } 72 | 73 | @Override 74 | public void onRun() { 75 | Location location = getLocation(); 76 | 77 | if (outlineOnly) drawCubeOutline(location); 78 | else drawCubeWalls(location); 79 | 80 | step++; 81 | } 82 | 83 | private void drawCubeOutline(Location location) { 84 | double xRotation = 0, yRotation = 0, zRotation = 0; 85 | if (enableRotation) { 86 | xRotation = step * angularVelocityX; 87 | yRotation = step * angularVelocityY; 88 | zRotation = step * angularVelocityZ; 89 | } 90 | float a = edgeLength / 2; 91 | // top and bottom 92 | double angleX, angleY; 93 | Vector v = new Vector(); 94 | for (int i = 0; i < 4; i++) { 95 | angleY = i * Math.PI / 2; 96 | for (int j = 0; j < 2; j++) { 97 | angleX = j * Math.PI; 98 | for (int p = 0; p <= particles; p++) { 99 | v.setX(a).setY(a); 100 | v.setZ(edgeLength * p / particles - a); 101 | VectorUtils.rotateAroundAxisX(v, angleX); 102 | VectorUtils.rotateAroundAxisY(v, angleY); 103 | 104 | if (enableRotation) VectorUtils.rotateVector(v, xRotation, yRotation, zRotation); 105 | if (orient) rotateLocation(location, v); 106 | display(particle, location.add(v)); 107 | location.subtract(v); 108 | } 109 | } 110 | // pillars 111 | for (int p = 0; p <= particles; p++) { 112 | v.setX(a).setZ(a); 113 | v.setY(edgeLength * p / particles - a); 114 | VectorUtils.rotateAroundAxisY(v, angleY); 115 | 116 | if (enableRotation) VectorUtils.rotateVector(v, xRotation, yRotation, zRotation); 117 | if (orient) rotateLocation(location, v); 118 | display(particle, location.add(v)); 119 | location.subtract(v); 120 | } 121 | } 122 | } 123 | 124 | private void drawCubeWalls(Location location) { 125 | double xRotation = 0, yRotation = 0, zRotation = 0; 126 | 127 | if (enableRotation) { 128 | xRotation = step * angularVelocityX; 129 | yRotation = step * angularVelocityY; 130 | zRotation = step * angularVelocityZ; 131 | } 132 | 133 | float a = edgeLength / 2; 134 | float posX; 135 | float posY; 136 | float posZ; 137 | Vector v; 138 | 139 | for (int x = 0; x <= particles; x++) { 140 | posX = edgeLength * ((float) x / particles) - a; 141 | for (int y = 0; y <= particles; y++) { 142 | posY = edgeLength * ((float) y / particles) - a; 143 | for (int z = 0; z <= particles; z++) { 144 | if (x != 0 && x != particles && y != 0 && y != particles && z != 0 && z != particles) continue; 145 | 146 | posZ = edgeLength * ((float) z / particles) - a; 147 | v = new Vector(posX, posY, posZ); 148 | if (enableRotation) VectorUtils.rotateVector(v, xRotation, yRotation, zRotation); 149 | if (orient) rotateLocation(location, v); 150 | 151 | display(particle, location.add(v)); 152 | location.subtract(v); 153 | } 154 | } 155 | } 156 | } 157 | 158 | private void rotateLocation(Location location, Vector v) { 159 | VectorUtils.rotateAroundAxisX(v, location.getPitch() * MathUtils.degreesToRadians); 160 | VectorUtils.rotateAroundAxisY(v, -location.getYaw() * MathUtils.degreesToRadians); 161 | } 162 | 163 | } 164 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/CuboidEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.Particle; 5 | import org.bukkit.util.Vector; 6 | 7 | import de.slikey.effectlib.Effect; 8 | import de.slikey.effectlib.EffectType; 9 | import de.slikey.effectlib.EffectManager; 10 | 11 | public class CuboidEffect extends Effect { 12 | 13 | /** 14 | * Particles in each row 15 | */ 16 | public int particles = 8; 17 | 18 | /** 19 | * Length of x component of cuboid 20 | */ 21 | public double xLength = 0; 22 | 23 | /** 24 | * Length of y component of cuboid 25 | */ 26 | public double yLength = 0; 27 | 28 | /** 29 | * Length of z component of cuboid 30 | */ 31 | public double zLength = 0; 32 | 33 | /** 34 | * Amount of padding to add around the cube 35 | */ 36 | public double padding = 0; 37 | 38 | /** 39 | * Use corners of blocks 40 | */ 41 | public boolean blockSnap = false; 42 | 43 | /** 44 | * Calculated length 45 | */ 46 | private double useXLength = 0; 47 | private double useYLength = 0; 48 | private double useZLength = 0; 49 | 50 | /** 51 | * State variables 52 | */ 53 | protected Location minCorner; 54 | protected boolean initialized; 55 | 56 | public CuboidEffect(EffectManager effectManager) { 57 | super(effectManager); 58 | type = EffectType.REPEATING; 59 | particle = Particle.FLAME; 60 | period = 5; 61 | iterations = 200; 62 | } 63 | 64 | @Override 65 | public void reloadParameters() { 66 | initialized = false; 67 | } 68 | 69 | @Override 70 | public void onRun() { 71 | Location target = getTarget(); 72 | Location location = getLocation(); 73 | if (target == null || location == null) { 74 | cancel(); 75 | return; 76 | } 77 | 78 | if (!initialized) { 79 | if (blockSnap) { 80 | target = target.getBlock().getLocation(); 81 | minCorner = location.getBlock().getLocation(); 82 | } else { 83 | minCorner = location.clone(); 84 | } 85 | 86 | if (xLength == 0 && yLength == 0 && zLength == 0) { 87 | if (target.getWorld() == null || location.getWorld() == null) { 88 | return; 89 | } 90 | if (!target.getWorld().getName().equals(location.getWorld().getName())) { 91 | cancel(); 92 | return; 93 | } 94 | 95 | if (target.getX() < minCorner.getX()) minCorner.setX(target.getX()); 96 | if (target.getY() < minCorner.getY()) minCorner.setY(target.getY()); 97 | if (target.getZ() < minCorner.getZ()) minCorner.setZ(target.getZ()); 98 | 99 | useXLength = Math.abs(location.getX() - target.getX()); 100 | useYLength = Math.abs(location.getY() - target.getY()); 101 | useZLength = Math.abs(location.getZ() - target.getZ()); 102 | } else { 103 | useXLength = xLength; 104 | useYLength = yLength; 105 | useZLength = zLength; 106 | } 107 | 108 | double extra = padding * 2; 109 | if (blockSnap) extra++; 110 | 111 | useXLength += extra; 112 | useYLength += extra; 113 | useZLength += extra; 114 | 115 | if (padding != 0) minCorner.add(-padding, -padding, -padding); 116 | 117 | initialized = true; 118 | } 119 | drawOutline(); 120 | } 121 | 122 | private void drawOutline() { 123 | Vector v = new Vector(); 124 | for (int i = 0; i < particles; i++) { 125 | // X edges 126 | drawEdge(v, i, 0, 2, 2); 127 | drawEdge(v, i, 0, 1, 2); 128 | drawEdge(v, i, 0, 1, 1); 129 | drawEdge(v, i, 0, 2, 1); 130 | 131 | // Y edges 132 | drawEdge(v, i, 2, 0, 2); 133 | drawEdge(v, i, 1,0, 2); 134 | drawEdge(v, i, 1,0, 1); 135 | drawEdge(v, i, 2,0, 1); 136 | 137 | // Z edges 138 | drawEdge(v, i, 2, 2, 0); 139 | drawEdge(v, i, 1, 2, 0); 140 | drawEdge(v, i, 1, 1, 0); 141 | drawEdge(v, i, 2, 1, 0); 142 | } 143 | } 144 | 145 | private void drawEdge(Vector v, int i, int dx, int dy, int dz) { 146 | if (dx == 0) v.setX(useXLength * i / particles); 147 | else v.setX(useXLength * (dx - 1)); 148 | 149 | if (dy == 0) v.setY(useYLength * i / particles); 150 | else v.setY(useYLength * (dy - 1)); 151 | 152 | if (dz == 0) v.setZ(useZLength * i / particles); 153 | else v.setZ(useZLength * (dz - 1)); 154 | 155 | display(particle, minCorner.add(v)); 156 | minCorner.subtract(v); 157 | } 158 | 159 | } 160 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/CylinderEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import java.util.Random; 4 | 5 | import org.bukkit.Particle; 6 | import org.bukkit.Location; 7 | import org.bukkit.util.Vector; 8 | 9 | import de.slikey.effectlib.Effect; 10 | import de.slikey.effectlib.EffectType; 11 | import de.slikey.effectlib.EffectManager; 12 | import de.slikey.effectlib.util.MathUtils; 13 | import de.slikey.effectlib.util.RandomUtils; 14 | import de.slikey.effectlib.util.VectorUtils; 15 | 16 | public class CylinderEffect extends Effect { 17 | 18 | /** 19 | * Radius of cylinder 20 | */ 21 | public float radius = 1; 22 | 23 | /** 24 | * Height of Cylinder 25 | */ 26 | public float height = 3; 27 | 28 | /** 29 | * Turns the cube by this angle each iteration around the x-axis 30 | */ 31 | public double angularVelocityX = Math.PI / 200; 32 | 33 | /** 34 | * Turns the cube by this angle each iteration around the y-axis 35 | */ 36 | public double angularVelocityY = Math.PI / 170; 37 | 38 | /** 39 | * Turns the cube by this angle each iteration around the z-axis 40 | */ 41 | public double angularVelocityZ = Math.PI / 155; 42 | 43 | /** 44 | * Rotation of the cylinder 45 | */ 46 | public double rotationX, rotationY, rotationZ; 47 | 48 | /** 49 | * Particles in each row 50 | */ 51 | public int particles = 100; 52 | 53 | /** 54 | * True if rotation is enable 55 | */ 56 | public boolean enableRotation = true; 57 | 58 | /** 59 | * Toggles the cylinder to be solid 60 | */ 61 | public boolean solid = false; 62 | 63 | /** 64 | * Current step. Works as counter 65 | */ 66 | protected int step = 0; 67 | 68 | /** 69 | * Ratio of sides to entire surface 70 | */ 71 | protected float sideRatio = 0; 72 | 73 | /** 74 | * Whether or not to orient the effect in the direction 75 | * of the source Location 76 | */ 77 | public boolean orient = false; 78 | 79 | public CylinderEffect(EffectManager effectManager) { 80 | super(effectManager); 81 | type = EffectType.REPEATING; 82 | particle = Particle.FLAME; 83 | period = 2; 84 | iterations = 200; 85 | } 86 | 87 | @Override 88 | public void reset() { 89 | step = 0; 90 | } 91 | 92 | @Override 93 | public void onRun() { 94 | Location location = getLocation(); 95 | 96 | if (location == null) { 97 | cancel(); 98 | return; 99 | } 100 | 101 | if (sideRatio == 0) calculateSideRatio(); 102 | 103 | Random r = RandomUtils.random; 104 | double xRotation = rotationX, yRotation = rotationY, zRotation = rotationZ; 105 | 106 | if (orient) { 107 | xRotation = Math.toRadians(90 - location.getPitch()) + rotationX; 108 | yRotation = Math.toRadians(180 - location.getYaw()) + rotationY; 109 | } 110 | 111 | if (enableRotation) { 112 | xRotation += step * angularVelocityX; 113 | yRotation += step * angularVelocityY; 114 | zRotation += step * angularVelocityZ; 115 | } 116 | 117 | float multi; 118 | Vector v; 119 | 120 | for (int i = 0; i < particles; i++) { 121 | multi = (solid) ? r.nextFloat() : 1; 122 | v = RandomUtils.getRandomCircleVector().multiply(radius); 123 | if (r.nextFloat() <= sideRatio) { 124 | // SIDE PARTICLE 125 | v.multiply(multi); 126 | v.setY((r.nextFloat() * 2 - 1) * (height / 2)); 127 | } else { 128 | // GROUND PARTICLE 129 | v.multiply(r.nextFloat()); 130 | if (r.nextFloat() < 0.5) { 131 | // TOP 132 | v.setY(multi * (height / 2)); 133 | } else { 134 | // BOTTOM 135 | v.setY(-multi * (height / 2)); 136 | } 137 | } 138 | if (enableRotation || orient) VectorUtils.rotateVector(v, xRotation, yRotation, zRotation); 139 | 140 | display(particle, location.add(v)); 141 | location.subtract(v); 142 | } 143 | display(particle, location); 144 | step++; 145 | } 146 | 147 | protected void calculateSideRatio() { 148 | float grounds, side; 149 | grounds = MathUtils.PI * MathUtils.PI * radius * 2; 150 | side = 2 * MathUtils.PI * radius * height; 151 | sideRatio = side / (side + grounds); 152 | } 153 | 154 | } 155 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/DiscoBallEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | /** 4 | * Idea by coco5843 5 | */ 6 | 7 | import org.bukkit.Color; 8 | import org.bukkit.Location; 9 | import org.bukkit.Particle; 10 | import org.bukkit.util.Vector; 11 | 12 | import de.slikey.effectlib.Effect; 13 | import de.slikey.effectlib.EffectType; 14 | import de.slikey.effectlib.EffectManager; 15 | import de.slikey.effectlib.util.ParticleUtil; 16 | import de.slikey.effectlib.util.RandomUtils; 17 | 18 | public class DiscoBallEffect extends Effect { 19 | 20 | /** 21 | * Radius of the sphere 22 | */ 23 | public float sphereRadius = 0.6F; 24 | 25 | /** 26 | * Min and max sizes of the lines 27 | */ 28 | public int max = 15; 29 | 30 | /** 31 | * Particle of the sphere and of the lines 32 | */ 33 | public Particle sphereParticle = Particle.FLAME; 34 | public Particle lineParticle = ParticleUtil.getParticle("REDSTONE"); 35 | 36 | public Color sphereColor = null; 37 | public Color lineColor = null; 38 | 39 | /** 40 | * Max number of lines 41 | */ 42 | public int maxLines = 7; 43 | 44 | /** 45 | * Max number of particles per line 46 | */ 47 | public int lineParticles = 100; 48 | public int sphereParticles = 50; 49 | 50 | /** 51 | * Direction of the lines 52 | */ 53 | public Direction direction = Direction.DOWN; 54 | 55 | public DiscoBallEffect(EffectManager manager) { 56 | super(manager); 57 | type = EffectType.REPEATING; 58 | period = 7; 59 | iterations = 500; 60 | } 61 | 62 | public void onRun() { 63 | Location location = getLocation(); 64 | 65 | if (location == null) { 66 | cancel(); 67 | return; 68 | } 69 | 70 | //Lines 71 | int mL = RandomUtils.random.nextInt(maxLines - 2) + 2; 72 | 73 | double x; 74 | double y; 75 | double z; 76 | 77 | Location loc; 78 | Location target; 79 | 80 | Vector v; 81 | Vector link; 82 | Vector vector; 83 | 84 | float length; 85 | float ratio; 86 | 87 | for (int m = 0; m < mL * 2; m++) { 88 | x = RandomUtils.random.nextInt(max - max * (-1)) + max * (-1); 89 | y = RandomUtils.random.nextInt(max - max * (-1)) + max * (-1); 90 | z = RandomUtils.random.nextInt(max - max * (-1)) + max * (-1); 91 | 92 | if (direction == Direction.DOWN) y = RandomUtils.random.nextInt(max * 2 - max) + max; 93 | else if (direction == Direction.UP) y = RandomUtils.random.nextInt(max * (-1) - max * (-2)) + max * (-2); 94 | 95 | target = location.clone().subtract(x, y, z); 96 | 97 | link = target.toVector().subtract(location.toVector()); 98 | length = (float) link.length(); 99 | link.normalize(); 100 | 101 | ratio = length / lineParticles; 102 | v = link.multiply(ratio); 103 | loc = location.clone().subtract(v); 104 | for (int i = 0; i < lineParticles; i++) { 105 | loc.add(v); 106 | display(lineParticle, loc, lineColor); 107 | } 108 | } 109 | 110 | //Sphere 111 | for (int i = 0; i < sphereParticles; i++) { 112 | vector = RandomUtils.getRandomVector().multiply(sphereRadius); 113 | location.add(vector); 114 | display(sphereParticle, location, sphereColor); 115 | location.subtract(vector); 116 | } 117 | } 118 | 119 | public enum Direction { 120 | 121 | UP, DOWN, BOTH; 122 | } 123 | 124 | } 125 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/DnaEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Color; 4 | import org.bukkit.Location; 5 | import org.bukkit.Particle; 6 | import org.bukkit.util.Vector; 7 | 8 | import de.slikey.effectlib.Effect; 9 | import de.slikey.effectlib.EffectType; 10 | import de.slikey.effectlib.EffectManager; 11 | import de.slikey.effectlib.util.MathUtils; 12 | import de.slikey.effectlib.util.ParticleUtil; 13 | import de.slikey.effectlib.util.VectorUtils; 14 | 15 | public class DnaEffect extends Effect { 16 | 17 | /** 18 | * ParticleType of spawned particle 19 | */ 20 | public Particle particleHelix = Particle.FLAME; 21 | public Color colorHelix = null; 22 | 23 | /** 24 | * Particle of base 1 25 | */ 26 | public Particle particleBase1 = ParticleUtil.getParticle("WATER_WAKE"); 27 | public Color colorBase1 = null; 28 | 29 | /** 30 | * Particle of base 2 31 | */ 32 | public Particle particleBase2 = ParticleUtil.getParticle("REDSTONE"); 33 | public Color colorBase2 = null; 34 | 35 | /** 36 | * Radials to turn per step 37 | */ 38 | public double radials = Math.PI / 30; 39 | 40 | /** 41 | * Radius of dna-double-helix 42 | */ 43 | public float radius = 1.5F; 44 | 45 | /** 46 | * Particles to spawn per interation 47 | */ 48 | public int particlesHelix = 3; 49 | 50 | /** 51 | * Particles per base 52 | */ 53 | public int particlesBase = 15; 54 | 55 | /** 56 | * Length of the dna-double-helix 57 | */ 58 | public float length = 15; 59 | 60 | /** 61 | * Growth per particle 62 | */ 63 | public float grow = 0.2F; 64 | 65 | /** 66 | * Particles between every base 67 | */ 68 | public float baseInterval = 10; 69 | 70 | /** 71 | * Current step. Works as counter 72 | */ 73 | protected int step = 0; 74 | 75 | public DnaEffect(EffectManager effectManager) { 76 | super(effectManager); 77 | type = EffectType.REPEATING; 78 | period = 1; 79 | iterations = 500; 80 | } 81 | 82 | @Override 83 | public void reset() { 84 | step = 0; 85 | } 86 | 87 | @Override 88 | public void onRun() { 89 | Location location = getLocation(); 90 | 91 | if (location == null) { 92 | cancel(); 93 | return; 94 | } 95 | 96 | double angle; 97 | Vector v; 98 | Particle particle; 99 | Color color; 100 | 101 | for (int j = 0; j < particlesHelix; j++) { 102 | if (step * grow > length) step = 0; 103 | 104 | for (int i = 0; i < 2; i++) { 105 | angle = step * radials + Math.PI * i; 106 | v = new Vector(Math.cos(angle) * radius, step * grow, Math.sin(angle) * radius); 107 | drawParticle(location, v, particleHelix, colorHelix); 108 | } 109 | 110 | if (step % baseInterval == 0) { 111 | for (int i = -particlesBase; i <= particlesBase; i++) { 112 | if (i == 0) continue; 113 | 114 | particle = particleBase1; 115 | color = colorBase1; 116 | if (i < 0) { 117 | particle = particleBase2; 118 | color = colorBase2; 119 | } 120 | angle = step * radials; 121 | v = new Vector(Math.cos(angle), 0, Math.sin(angle)).multiply(radius * i / particlesBase).setY(step * grow); 122 | drawParticle(location, v, particle, color); 123 | } 124 | } 125 | step++; 126 | } 127 | } 128 | 129 | protected void drawParticle(Location location, Vector v, Particle particle, Color color) { 130 | VectorUtils.rotateAroundAxisX(v, (location.getPitch() + 90) * MathUtils.degreesToRadians); 131 | VectorUtils.rotateAroundAxisY(v, -location.getYaw() * MathUtils.degreesToRadians); 132 | 133 | location.add(v); 134 | display(particle, location, color); 135 | location.subtract(v); 136 | } 137 | 138 | } 139 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/DonutEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Particle; 4 | import org.bukkit.Location; 5 | import org.bukkit.util.Vector; 6 | 7 | import de.slikey.effectlib.Effect; 8 | import de.slikey.effectlib.EffectType; 9 | import de.slikey.effectlib.EffectManager; 10 | import de.slikey.effectlib.util.MathUtils; 11 | import de.slikey.effectlib.util.VectorUtils; 12 | 13 | public class DonutEffect extends Effect { 14 | 15 | /** 16 | * Amount of particles inside of a single vertical circle 17 | */ 18 | public int particlesCircle = 10; 19 | 20 | /** 21 | * Amount of circles to build the torus 22 | */ 23 | public int circles = 36; 24 | 25 | /** 26 | * Radius of the torus 27 | */ 28 | public float radiusDonut = 2; 29 | 30 | /** 31 | * Radius of the tube (the circles on the outside). 32 | */ 33 | public float radiusTube = 0.5F; 34 | 35 | /** 36 | * Rotation of the torus. 37 | */ 38 | public double xRotation, yRotation, zRotation = 0; 39 | 40 | public DonutEffect(EffectManager effectManager) { 41 | super(effectManager); 42 | type = EffectType.REPEATING; 43 | particle = Particle.FLAME; 44 | period = 10; 45 | iterations = 20; 46 | } 47 | 48 | @Override 49 | public void onRun() { 50 | Location location = getLocation(); 51 | Vector v = new Vector(); 52 | 53 | if (location == null) { 54 | cancel(); 55 | return; 56 | } 57 | 58 | double theta; 59 | double phi; 60 | double cosPhi; 61 | 62 | for (int i = 0; i < circles; i++) { 63 | theta = 2 * Math.PI * i / circles; 64 | for (int j = 0; j < particlesCircle; j++) { 65 | phi = 2 * Math.PI * j / particlesCircle; 66 | cosPhi = Math.cos(phi); 67 | v.setX((radiusDonut + radiusTube * cosPhi) * Math.cos(theta)); 68 | v.setY((radiusDonut + radiusTube * cosPhi) * Math.sin(theta)); 69 | v.setZ(radiusTube * Math.sin(phi)); 70 | 71 | VectorUtils.rotateVector(v, xRotation, yRotation, zRotation); 72 | VectorUtils.rotateAroundAxisX(v, (location.getPitch() + 90) * MathUtils.degreesToRadians); 73 | VectorUtils.rotateAroundAxisY(v, -location.getYaw() * MathUtils.degreesToRadians); 74 | 75 | display(particle, location.add(v)); 76 | location.subtract(v); 77 | } 78 | } 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/DragonEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import java.util.List; 4 | import java.util.ArrayList; 5 | 6 | import org.bukkit.Location; 7 | import org.bukkit.Particle; 8 | import org.bukkit.util.Vector; 9 | 10 | import de.slikey.effectlib.Effect; 11 | import de.slikey.effectlib.EffectType; 12 | import de.slikey.effectlib.EffectManager; 13 | import de.slikey.effectlib.util.MathUtils; 14 | import de.slikey.effectlib.util.RandomUtils; 15 | import de.slikey.effectlib.util.VectorUtils; 16 | 17 | public class DragonEffect extends Effect { 18 | 19 | protected final List rndF; 20 | protected final List rndAngle; 21 | 22 | /** 23 | * Pitch of the dragon arc 24 | */ 25 | public float pitch = 0.1F; 26 | 27 | /** 28 | * Arcs to build the breath 29 | */ 30 | public int arcs = 20; 31 | 32 | /** 33 | * Particles per arc 34 | */ 35 | public int particles = 30; 36 | 37 | /** 38 | * Steps per iteration 39 | */ 40 | public int stepsPerIteration = 2; 41 | 42 | /** 43 | * Length in blocks 44 | */ 45 | public float length = 4; 46 | 47 | /** 48 | * Current step. Works as counter 49 | */ 50 | protected int step = 0; 51 | 52 | public DragonEffect(EffectManager effectManager) { 53 | super(effectManager); 54 | type = EffectType.REPEATING; 55 | particle = Particle.FLAME; 56 | period = 2; 57 | iterations = 200; 58 | rndF = new ArrayList<>(arcs); 59 | rndAngle = new ArrayList<>(arcs); 60 | } 61 | 62 | @Override 63 | public void reset() { 64 | step = 0; 65 | } 66 | 67 | @Override 68 | public void onRun() { 69 | Location location = getLocation(); 70 | 71 | if (location == null) { 72 | cancel(); 73 | return; 74 | } 75 | 76 | float pitch; 77 | float x; 78 | float y; 79 | Vector v; 80 | 81 | for (int j = 0; j < stepsPerIteration; j++) { 82 | if (step % particles == 0) { 83 | rndF.clear(); 84 | rndAngle.clear(); 85 | } 86 | 87 | while (rndF.size() < arcs) { 88 | rndF.add(RandomUtils.random.nextFloat()); 89 | } 90 | 91 | while (rndAngle.size() < arcs) { 92 | rndAngle.add(RandomUtils.getRandomAngle()); 93 | } 94 | 95 | for (int i = 0; i < arcs; i++) { 96 | pitch = rndF.get(i) * 2 * this.pitch - this.pitch; 97 | x = (step % particles) * length / particles; 98 | y = (float) (pitch * Math.pow(x, 2)); 99 | v = new Vector(x, y, 0); 100 | VectorUtils.rotateAroundAxisX(v, rndAngle.get(i)); 101 | VectorUtils.rotateAroundAxisZ(v, -location.getPitch() * MathUtils.degreesToRadians); 102 | VectorUtils.rotateAroundAxisY(v, -(location.getYaw() + 90) * MathUtils.degreesToRadians); 103 | display(particle, location.add(v)); 104 | location.subtract(v); 105 | } 106 | step++; 107 | } 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/EarthEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import java.util.Set; 4 | import java.util.HashSet; 5 | 6 | import org.bukkit.Color; 7 | import org.bukkit.Location; 8 | import org.bukkit.Particle; 9 | import org.bukkit.util.Vector; 10 | 11 | import de.slikey.effectlib.Effect; 12 | import de.slikey.effectlib.EffectType; 13 | import de.slikey.effectlib.EffectManager; 14 | import de.slikey.effectlib.util.MathUtils; 15 | import de.slikey.effectlib.util.ParticleUtil; 16 | import de.slikey.effectlib.util.RandomUtils; 17 | import de.slikey.effectlib.util.VectorUtils; 18 | 19 | public class EarthEffect extends Effect { 20 | 21 | public Particle particleLand = ParticleUtil.getParticle("VILLAGER_HAPPY"); 22 | public Particle particleOcean = ParticleUtil.getParticle("DRIP_WATER"); 23 | 24 | public Color colorLand = null; 25 | public Color colorOcean = null; 26 | 27 | public int particlesLand = 3; 28 | public int particlesOcean = 1; 29 | 30 | public float speedLand = 0F; 31 | public float speedOcean = 0F; 32 | 33 | /** 34 | * Precision of generation. Higher numbers have better results, but increase the time of generation. Don't pick Number above 10.000 35 | */ 36 | public int precision = 100; 37 | 38 | /** 39 | * Amount of Particles to form the World 40 | */ 41 | public int particles = 500; 42 | 43 | /** 44 | * Radius of the World 45 | */ 46 | public float radius = 1; 47 | 48 | /** 49 | * Height of the mountains. 50 | */ 51 | public float mountainHeight = 0.5F; 52 | 53 | /** 54 | * Triggers invalidation on first run 55 | */ 56 | protected boolean firstStep = true; 57 | 58 | /** 59 | * Caches vectors to increase performance 60 | */ 61 | protected final Set cacheGreen, cacheBlue; 62 | 63 | public EarthEffect(EffectManager effectManager) { 64 | super(effectManager); 65 | type = EffectType.REPEATING; 66 | period = 5; 67 | iterations = 200; 68 | cacheGreen = new HashSet<>(); 69 | cacheBlue = new HashSet<>(); 70 | } 71 | 72 | @Override 73 | public void reset() { 74 | firstStep = true; 75 | } 76 | 77 | public void invalidate() { 78 | firstStep = false; 79 | cacheGreen.clear(); 80 | cacheBlue.clear(); 81 | 82 | Set cache = new HashSet<>(); 83 | int sqrtParticles = (int) Math.sqrt(particles); 84 | float theta = 0, phi, thetaStep = MathUtils.PI / sqrtParticles, phiStep = MathUtils.PI2 / sqrtParticles; 85 | 86 | float x; 87 | float y; 88 | float z; 89 | 90 | for (int i = 0; i < sqrtParticles; i++) { 91 | theta += thetaStep; 92 | phi = 0; 93 | for (int j = 0; j < sqrtParticles; j++) { 94 | phi += phiStep; 95 | x = radius * MathUtils.sin(theta) * MathUtils.cos(phi); 96 | y = radius * MathUtils.sin(theta) * MathUtils.sin(phi); 97 | z = radius * MathUtils.cos(theta); 98 | cache.add(new Vector(x, y, z)); 99 | } 100 | } 101 | 102 | float increase = mountainHeight / precision; 103 | double r1; 104 | double r2; 105 | double r3; 106 | 107 | for (int i = 0; i < precision; i++) { 108 | r1 = RandomUtils.getRandomAngle(); 109 | r2 = RandomUtils.getRandomAngle(); 110 | r3 = RandomUtils.getRandomAngle(); 111 | for (Vector v : cache) { 112 | if (v.getY() > 0) v.setY(v.getY() + increase); 113 | else v.setY(v.getY() - increase); 114 | 115 | if (i != precision - 1) VectorUtils.rotateVector(v, r1, r2, r3); 116 | } 117 | } 118 | 119 | float minSquared = Float.POSITIVE_INFINITY, maxSquared = Float.NEGATIVE_INFINITY; 120 | for (Vector current : cache) { 121 | float lengthSquared = (float) current.lengthSquared(); 122 | 123 | if (minSquared > lengthSquared) minSquared = lengthSquared; 124 | if (maxSquared < lengthSquared) maxSquared = lengthSquared; 125 | } 126 | 127 | // COLOR PARTICLES 128 | float average = (minSquared + maxSquared) / 2; 129 | for (Vector v : cache) { 130 | float lengthSquared = (float) v.lengthSquared(); 131 | 132 | if (lengthSquared >= average) cacheGreen.add(v); 133 | else cacheBlue.add(v); 134 | } 135 | } 136 | 137 | @Override 138 | public void onRun() { 139 | Location location = getLocation(); 140 | 141 | if (location == null) { 142 | cancel(); 143 | return; 144 | } 145 | 146 | if (firstStep) invalidate(); 147 | 148 | for (Vector v : cacheGreen) { 149 | display(particleLand, location.add(v), colorLand, speedLand, particlesLand); 150 | location.subtract(v); 151 | } 152 | for (Vector v : cacheBlue) { 153 | display(particleOcean, location.add(v), colorOcean, speedOcean, particlesOcean); 154 | location.subtract(v); 155 | } 156 | } 157 | 158 | } 159 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/ExplodeEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Sound; 4 | import org.bukkit.Location; 5 | import org.bukkit.Particle; 6 | 7 | import de.slikey.effectlib.Effect; 8 | import de.slikey.effectlib.EffectType; 9 | import de.slikey.effectlib.EffectManager; 10 | import de.slikey.effectlib.util.ParticleUtil; 11 | import de.slikey.effectlib.util.RandomUtils; 12 | 13 | public class ExplodeEffect extends Effect { 14 | 15 | public Particle particle1 = ParticleUtil.getParticle("EXPLOSION_NORMAL"); 16 | public Particle particle2 = ParticleUtil.getParticle("EXPLOSION_HUGE"); 17 | 18 | /** 19 | * Amount of spawned smoke-sparks 20 | */ 21 | public int amount = 25; 22 | public Sound sound = Sound.ENTITY_GENERIC_EXPLODE; 23 | 24 | public ExplodeEffect(EffectManager effectManager) { 25 | super(effectManager); 26 | type = EffectType.INSTANT; 27 | speed = 0.5F; 28 | } 29 | 30 | @Override 31 | public void onRun() { 32 | Location location = getLocation(); 33 | 34 | if (location == null || location.getWorld() == null) { 35 | cancel(); 36 | return; 37 | } 38 | 39 | location.getWorld().playSound(location, sound, 4.0F, (1.0F + (RandomUtils.random.nextFloat() - RandomUtils.random.nextFloat()) * 0.2F) * 0.7F); 40 | display(particle1, location); 41 | display(particle2, location); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/FlameEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.Particle; 5 | import org.bukkit.util.Vector; 6 | 7 | import de.slikey.effectlib.Effect; 8 | import de.slikey.effectlib.EffectType; 9 | import de.slikey.effectlib.EffectManager; 10 | import de.slikey.effectlib.util.RandomUtils; 11 | 12 | public class FlameEffect extends Effect { 13 | 14 | public int particles = 10; 15 | 16 | public FlameEffect(EffectManager effectManager) { 17 | super(effectManager); 18 | type = EffectType.REPEATING; 19 | particle = Particle.FLAME; 20 | period = 1; 21 | iterations = 600; 22 | } 23 | 24 | @Override 25 | public void onRun() { 26 | Location location = getLocation(); 27 | Vector v; 28 | 29 | if (location == null) { 30 | cancel(); 31 | return; 32 | } 33 | 34 | for (int i = 0; i < particles; i++) { 35 | v = RandomUtils.getRandomCircleVector().multiply(RandomUtils.random.nextDouble() * 0.6D); 36 | v.setY(RandomUtils.random.nextFloat() * 1.8); 37 | location.add(v); 38 | display(particle, location); 39 | location.subtract(v); 40 | } 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/FountainEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.Particle; 5 | import org.bukkit.util.Vector; 6 | 7 | import de.slikey.effectlib.Effect; 8 | import de.slikey.effectlib.EffectType; 9 | import de.slikey.effectlib.EffectManager; 10 | import de.slikey.effectlib.util.ParticleUtil; 11 | import de.slikey.effectlib.util.RandomUtils; 12 | 13 | public class FountainEffect extends Effect { 14 | 15 | /** 16 | * Amount of strands (10) 17 | */ 18 | public int strands = 10; 19 | 20 | /** 21 | * Particles per iteration per strand (100) 22 | */ 23 | public int particlesStrand = 150; 24 | 25 | /** 26 | * Particles per iteration in the spout 27 | */ 28 | public int particlesSpout = 200; 29 | 30 | /** 31 | * Radius of strands in blocks 32 | */ 33 | public float radius = 5; 34 | 35 | /** 36 | * Radius of spout as a fraction of the fountain (0.1) 37 | */ 38 | public float radiusSpout = 0.1F; 39 | 40 | /** 41 | * Height of the fountain 42 | */ 43 | public float height = 3; 44 | 45 | /** 46 | * Height of the spout in blocks 47 | */ 48 | public float heightSpout = 7; 49 | 50 | /** 51 | * Rotation of the fountain on the Y-Axis (Fraction of PI) 52 | */ 53 | public double rotation = Math.PI / 4; 54 | 55 | public FountainEffect(EffectManager effectManager) { 56 | super(effectManager); 57 | type = EffectType.REPEATING; 58 | particle = ParticleUtil.getParticle("WATER_SPLASH"); 59 | period = 2; 60 | iterations = 100; 61 | } 62 | 63 | @Override 64 | public void onRun() { 65 | Location location = getLocation(); 66 | 67 | if (location == null) { 68 | cancel(); 69 | return; 70 | } 71 | 72 | double angle; 73 | float ratio; 74 | double x, y, z; 75 | Vector v; 76 | 77 | for (int i = 1; i <= strands; i++) { 78 | angle = 2 * i * Math.PI / strands + rotation; 79 | for (int j = 1; j <= particlesStrand; j++) { 80 | 81 | ratio = (float) j / particlesStrand; 82 | 83 | x = Math.cos(angle) * radius * ratio; 84 | y = Math.sin(Math.PI * j / particlesStrand) * height; 85 | z = Math.sin(angle) * radius * ratio; 86 | 87 | location.add(x, y, z); 88 | display(particle, location); 89 | location.subtract(x, y, z); 90 | } 91 | } 92 | 93 | for (int i = 0; i < particlesSpout; i++) { 94 | v = RandomUtils.getRandomCircleVector().multiply(RandomUtils.random.nextFloat() * radius * radiusSpout); 95 | v.setY(RandomUtils.random.nextFloat() * heightSpout); 96 | location.add(v); 97 | display(particle, location); 98 | location.subtract(v); 99 | } 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/GridEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.Particle; 5 | import org.bukkit.util.Vector; 6 | 7 | import de.slikey.effectlib.Effect; 8 | import de.slikey.effectlib.EffectType; 9 | import de.slikey.effectlib.EffectManager; 10 | import de.slikey.effectlib.util.VectorUtils; 11 | 12 | public class GridEffect extends Effect { 13 | 14 | /** 15 | * Rows of the grid 16 | */ 17 | public int rows = 5; 18 | 19 | /** 20 | * Columns of the grid 21 | */ 22 | public int columns = 10; 23 | 24 | /** 25 | * Width per cell in blocks 26 | */ 27 | public float widthCell = 1; 28 | 29 | /** 30 | * Height per cell in blocks 31 | */ 32 | public float heightCell = 1; 33 | 34 | /** 35 | * Particles to be spawned on the horizontal borders of the cell 36 | */ 37 | public int particlesWidth = 4; 38 | 39 | /** 40 | * Particles to be spawned on the vertical borders of the cell 41 | */ 42 | public int particlesHeight = 3; 43 | 44 | /** 45 | * Rotation around the Y-axis 46 | */ 47 | public double rotation = 0; 48 | 49 | /** 50 | * Rotation around the X-axis 51 | */ 52 | public double rotationX = 0; 53 | 54 | /** 55 | * Rotation around the Z-axis 56 | */ 57 | public double rotationZ = 0; 58 | 59 | /** 60 | * To center the grid on the location 61 | */ 62 | public boolean center = false; 63 | 64 | public GridEffect(EffectManager effectManager) { 65 | super(effectManager); 66 | type = EffectType.INSTANT; 67 | particle = Particle.FLAME; 68 | period = 5; 69 | iterations = 50; 70 | } 71 | 72 | @Override 73 | public void onRun() { 74 | Location location = getLocation(); 75 | Vector v = new Vector(); 76 | 77 | if (location == null) { 78 | cancel(); 79 | return; 80 | } 81 | 82 | // Draw rows 83 | for (int i = 0; i <= (rows + 1); i++) { 84 | for (int j = 0; j < particlesWidth * (columns + 1); j++) { 85 | v.setY(i * heightCell); 86 | v.setX(j * widthCell / particlesWidth); 87 | addParticle(location, v); 88 | } 89 | } 90 | // Draw columns 91 | for (int i = 0; i <= (columns + 1); i++) { 92 | for (int j = 0; j < particlesHeight * (rows + 1); j++) { 93 | v.setX(i * widthCell); 94 | v.setY(j * heightCell / particlesHeight); 95 | addParticle(location, v); 96 | } 97 | } 98 | } 99 | 100 | protected void addParticle(Location location, Vector v) { 101 | v.setZ(0); 102 | if (center) { 103 | v.setY(v.getY() + heightCell * -(rows + 1) / 2); 104 | v.setX(v.getX() + widthCell * -(columns + 1) / 2); 105 | } 106 | VectorUtils.rotateAroundAxisY(v, rotation); 107 | if (rotationX != 0) VectorUtils.rotateAroundAxisX(v, rotationX); 108 | if (rotationZ != 0) VectorUtils.rotateAroundAxisZ(v, rotationZ); 109 | location.add(v); 110 | display(particle, location); 111 | location.subtract(v); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/HeartEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.Particle; 5 | import org.bukkit.util.Vector; 6 | 7 | import de.slikey.effectlib.Effect; 8 | import de.slikey.effectlib.EffectManager; 9 | import de.slikey.effectlib.util.MathUtils; 10 | import de.slikey.effectlib.util.ParticleUtil; 11 | import de.slikey.effectlib.util.VectorUtils; 12 | 13 | /** 14 | * Creates a 2D Heart in 3D space. Thanks to the author for sharing it! 15 | * 16 | * @author Qukie 17 | */ 18 | public class HeartEffect extends Effect { 19 | 20 | /** 21 | * Heart-particles per interation (100) 22 | */ 23 | public int particles = 50; 24 | 25 | /** 26 | * Rotation of the heart. 27 | */ 28 | public double xRotation, yRotation, zRotation = 0; 29 | 30 | /** 31 | * Stretch/Compress factor along the x or y axis (1, 1) 32 | */ 33 | public double yFactor = 1, xFactor = 1; 34 | 35 | /** 36 | * Defines the size of the that inner sting (0.8) \/ 37 | */ 38 | public double factorInnerSpike = 0.8; 39 | 40 | /** 41 | * Compresses the heart along the y axis. (2) 42 | */ 43 | public double compressYFactorTotal = 2; 44 | 45 | /** 46 | * Compilation of the heart. (2) 47 | */ 48 | public float compilation = 2F; 49 | 50 | public HeartEffect(EffectManager effectManager) { 51 | super(effectManager); 52 | particle = ParticleUtil.getParticle("CRIT_MAGIC"); 53 | } 54 | 55 | @Override 56 | public void onRun() { 57 | Location location = getLocation(); 58 | Vector vector = new Vector(); 59 | 60 | if (location == null) { 61 | cancel(); 62 | return; 63 | } 64 | 65 | float alpha; 66 | double phi; 67 | 68 | for (int i = 0; i < particles; i++) { 69 | alpha = ((MathUtils.PI / compilation) / particles) * i; 70 | phi = Math.pow(Math.abs(MathUtils.sin(2 * compilation * alpha)) + factorInnerSpike * Math.abs(MathUtils.sin(compilation * alpha)), 1 / compressYFactorTotal); 71 | 72 | vector.setY(phi * (MathUtils.sin(alpha) + MathUtils.cos(alpha)) * yFactor); 73 | vector.setZ(phi * (MathUtils.cos(alpha) - MathUtils.sin(alpha)) * xFactor); 74 | 75 | VectorUtils.rotateVector(vector, xRotation, yRotation, zRotation); 76 | 77 | display(particle, location.add(vector)); 78 | location.subtract(vector); 79 | } 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/HelixEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Particle; 4 | import org.bukkit.Location; 5 | import org.bukkit.util.Vector; 6 | 7 | import de.slikey.effectlib.Effect; 8 | import de.slikey.effectlib.EffectType; 9 | import de.slikey.effectlib.EffectManager; 10 | import de.slikey.effectlib.util.VectorUtils; 11 | 12 | public class HelixEffect extends Effect { 13 | 14 | /** 15 | * Amount of strands 16 | */ 17 | public int strands = 8; 18 | 19 | /** 20 | * Particles per strand 21 | */ 22 | public int particles = 80; 23 | 24 | /** 25 | * Radius of helix 26 | */ 27 | public float radius = 10; 28 | 29 | /** 30 | * Factor for the curves. Negative values reverse rotation. 31 | */ 32 | public float curve = 10; 33 | 34 | /** 35 | * Rotation of the helix (Fraction of PI) 36 | */ 37 | public double rotation = Math.PI / 4; 38 | 39 | /** 40 | * Whether to orient to the direction of the source location 41 | */ 42 | public boolean orient = false; 43 | 44 | /** 45 | * Should it rotate? 46 | */ 47 | public boolean enableRotation = false; 48 | 49 | /** 50 | * Rotation of the torus. 51 | */ 52 | public double xRotation, yRotation, zRotation = 0; 53 | 54 | /** 55 | * Turns the helix by this angle each iteration around the x-axis 56 | */ 57 | public double angularVelocityX = Math.PI / 200; 58 | 59 | /** 60 | * Turns the helix by this angle each iteration around the y-axis 61 | */ 62 | public double angularVelocityY = Math.PI / 170; 63 | 64 | /** 65 | * Turns the helix by this angle each iteration around the z-axis 66 | */ 67 | public double angularVelocityZ = Math.PI / 155; 68 | 69 | /** 70 | * Current step. Works as a counter 71 | */ 72 | protected float step = 0; 73 | 74 | public HelixEffect(EffectManager effectManager) { 75 | super(effectManager); 76 | type = EffectType.REPEATING; 77 | particle = Particle.FLAME; 78 | period = 10; 79 | iterations = 8; 80 | } 81 | 82 | @Override 83 | public void reset() { 84 | step = 0; 85 | } 86 | 87 | @Override 88 | public void onRun() { 89 | Location location = getLocation(); 90 | Vector v; 91 | 92 | if (location == null) { 93 | cancel(); 94 | return; 95 | } 96 | 97 | float ratio; 98 | double angle; 99 | 100 | for (int i = 1; i <= strands; i++) { 101 | for (int j = 1; j <= particles; j++) { 102 | 103 | v = new Vector(); 104 | ratio = (float) j / particles; 105 | angle = curve * ratio * 2 * Math.PI / strands + (2 * Math.PI * i / strands) + rotation; 106 | 107 | v.setX(Math.cos(angle) * ratio * radius); 108 | v.setZ(Math.sin(angle) * ratio * radius); 109 | 110 | VectorUtils.rotateVector(v, xRotation, yRotation, zRotation); 111 | 112 | if (enableRotation) { 113 | VectorUtils.rotateVector(v, angularVelocityX * step, angularVelocityY * step, angularVelocityZ * step); 114 | } 115 | 116 | if (orient) v = VectorUtils.rotateVector(v, location); 117 | 118 | location.add(v); 119 | display(particle, location); 120 | location.subtract(v); 121 | 122 | step++; 123 | } 124 | } 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/HillEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.Particle; 5 | import org.bukkit.util.Vector; 6 | 7 | import de.slikey.effectlib.Effect; 8 | import de.slikey.effectlib.EffectType; 9 | import de.slikey.effectlib.EffectManager; 10 | import de.slikey.effectlib.util.VectorUtils; 11 | /** 12 | * Taken from http://en.wikipedia.org/wiki/Torus 13 | * 14 | * @author Kevin 15 | */ 16 | public class HillEffect extends Effect { 17 | 18 | /** 19 | * Height of the hill in blocks 20 | */ 21 | public float height = 2.5F; 22 | 23 | /** 24 | * Amount of particles per row 25 | */ 26 | public float particles = 30; 27 | 28 | /** 29 | * Length of the edge 30 | */ 31 | public float edgeLength = 6.5F; 32 | 33 | /** 34 | * Rotation of the Hill 35 | */ 36 | public double yRotation = Math.PI / 7; 37 | 38 | public HillEffect(EffectManager effectManager) { 39 | super(effectManager); 40 | type = EffectType.REPEATING; 41 | particle = Particle.FLAME; 42 | period = 10; 43 | iterations = 20; 44 | } 45 | 46 | @Override 47 | public void onRun() { 48 | Location location = getLocation(); 49 | Vector v = new Vector(); 50 | 51 | if (location == null) { 52 | cancel(); 53 | return; 54 | } 55 | 56 | double y1; 57 | double y2; 58 | 59 | for (int x = 0; x <= particles; x++) { 60 | y1 = Math.sin(Math.PI * x / particles); 61 | for (int z = 0; z <= particles; z++) { 62 | y2 = Math.sin(Math.PI * z / particles); 63 | v.setX(edgeLength * x / particles).setZ(edgeLength * z / particles); 64 | v.setY(height * y1 * y2); 65 | VectorUtils.rotateAroundAxisY(v, yRotation); 66 | 67 | display(particle, location.add(v)); 68 | location.subtract(v); 69 | } 70 | } 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/IconEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Particle; 4 | import org.bukkit.Location; 5 | 6 | import de.slikey.effectlib.Effect; 7 | import de.slikey.effectlib.EffectType; 8 | import de.slikey.effectlib.EffectManager; 9 | import de.slikey.effectlib.util.ParticleUtil; 10 | 11 | public class IconEffect extends Effect { 12 | 13 | public int yOffset = 2; 14 | 15 | public IconEffect(EffectManager effectManager) { 16 | super(effectManager); 17 | type = EffectType.REPEATING; 18 | particle = ParticleUtil.getParticle("VILLAGER_ANGRY"); 19 | period = 4; 20 | iterations = 25; 21 | } 22 | 23 | @Override 24 | public void onRun() { 25 | Location location = getLocation(); 26 | 27 | if (location == null) { 28 | cancel(); 29 | return; 30 | } 31 | 32 | location.add(0, yOffset, 0); 33 | display(particle, location); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/ImageEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import java.awt.Color; 4 | import java.awt.image.BufferedImage; 5 | 6 | import org.bukkit.Location; 7 | import org.bukkit.util.Vector; 8 | 9 | import de.slikey.effectlib.EffectManager; 10 | import de.slikey.effectlib.util.BaseImageEffect; 11 | 12 | public class ImageEffect extends BaseImageEffect { 13 | 14 | /** 15 | * Invert the image 16 | */ 17 | public boolean invert = false; 18 | 19 | public ImageEffect(EffectManager effectManager) { 20 | super(effectManager); 21 | } 22 | 23 | protected void display(BufferedImage image, Vector v, Location location, int pixel) { 24 | if (!invert && Color.black.getRGB() != pixel) return; 25 | else if (invert && Color.black.getRGB() == pixel) return; 26 | 27 | display(particle, location.add(v)); 28 | location.subtract(v); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/JumpEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.util.Vector; 4 | import org.bukkit.entity.Entity; 5 | 6 | import de.slikey.effectlib.Effect; 7 | import de.slikey.effectlib.EffectType; 8 | import de.slikey.effectlib.EffectManager; 9 | 10 | public class JumpEffect extends Effect { 11 | 12 | /** 13 | * Power of jump. (0.5F) 14 | */ 15 | public float power = 0.5F; 16 | 17 | public JumpEffect(EffectManager effectManager) { 18 | super(effectManager); 19 | type = EffectType.INSTANT; 20 | period = 20; 21 | iterations = 1; 22 | asynchronous = false; 23 | } 24 | 25 | @Override 26 | public void onRun() { 27 | Entity entity = getEntity(); 28 | if (entity == null) { 29 | cancel(); 30 | return; 31 | } 32 | Vector v = entity.getVelocity(); 33 | v.setY(v.getY() + power); 34 | entity.setVelocity(v); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/LineEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Particle; 4 | import org.bukkit.Location; 5 | import org.bukkit.util.Vector; 6 | import org.bukkit.configuration.ConfigurationSection; 7 | 8 | import de.slikey.effectlib.Effect; 9 | import de.slikey.effectlib.EffectType; 10 | import de.slikey.effectlib.EffectManager; 11 | import de.slikey.effectlib.util.VectorUtils; 12 | 13 | public class LineEffect extends Effect { 14 | 15 | /** 16 | * Should it do a zig zag? 17 | */ 18 | public boolean isZigZag = false; 19 | 20 | /** 21 | * Number of zig zags in the line 22 | */ 23 | public int zigZags = 10; 24 | 25 | /** 26 | * Direction of zig-zags 27 | */ 28 | public Vector zigZagOffset = new Vector(0, 0.1, 0); 29 | 30 | /** 31 | * Relative direction of zig-zags 32 | */ 33 | public Vector zigZagRelativeOffset = new Vector(0, 0, 0); 34 | 35 | /** 36 | * Particles per arc 37 | */ 38 | public int particles = 100; 39 | 40 | /** 41 | * Length of arc 42 | * A non-zero value here will use a length instead of the target endpoint 43 | */ 44 | public double length = 0; 45 | 46 | /** 47 | * Max length of arc 48 | * A non-zero value here will use this as the upper bound for the computed length 49 | */ 50 | public double maxLength = 0; 51 | 52 | /** 53 | * Sub effect at end. 54 | * This will play a subeffect at the end location of the line 55 | */ 56 | private String subEffectAtEndClass = null; 57 | public ConfigurationSection subEffectAtEnd = null; 58 | 59 | /** 60 | * Sub effect at end. 61 | * This will play a subeffect at the end location of the line 62 | * This effect will also be cached 63 | */ 64 | private String subEffectAtEndCachedClass = null; 65 | public ConfigurationSection subEffectAtEndCached = null; 66 | 67 | /** 68 | * Internal boolean 69 | */ 70 | protected boolean zag = false; 71 | 72 | /** 73 | * Internal counter 74 | */ 75 | protected int step = 0; 76 | 77 | /** 78 | * Internal effectAtEnd instance 79 | */ 80 | protected Effect effectAtEndCached = null; 81 | 82 | public LineEffect(EffectManager effectManager) { 83 | super(effectManager); 84 | type = EffectType.REPEATING; 85 | particle = Particle.FLAME; 86 | period = 1; 87 | iterations = 1; 88 | } 89 | 90 | @Override 91 | public void reset() { 92 | step = 0; 93 | if (effectAtEndCached != null) { 94 | effectAtEndCached.cancel(); 95 | effectAtEndCached = null; 96 | } 97 | } 98 | 99 | @Override 100 | public void onRun() { 101 | Location location = getLocation(); 102 | Location target; 103 | 104 | if (location == null) { 105 | cancel(); 106 | return; 107 | } 108 | 109 | if (length > 0) target = location.clone().add(location.getDirection().normalize().multiply(length)); 110 | else target = getTarget(); 111 | 112 | int amount = particles / zigZags; 113 | if (target == null) { 114 | cancel(); 115 | return; 116 | } 117 | Vector link = target.toVector().subtract(location.toVector()); 118 | float length = (float) link.length(); 119 | if (maxLength > 0) length = (float) Math.min(length, maxLength); 120 | 121 | link.normalize(); 122 | 123 | float ratio = length / particles; 124 | Vector v = link.multiply(ratio); 125 | Location loc = location.clone().subtract(v); 126 | Vector rel; 127 | 128 | for (int i = 0; i < particles; i++) { 129 | if (isZigZag) { 130 | rel = VectorUtils.rotateVector(zigZagRelativeOffset, loc); 131 | if (zag) { 132 | loc.add(rel); 133 | loc.add(zigZagOffset); 134 | } else { 135 | loc.subtract(rel); 136 | loc.subtract(zigZagOffset); 137 | } 138 | } 139 | if (step >= amount) { 140 | zag = !zag; 141 | step = 0; 142 | } 143 | step++; 144 | loc.add(v); 145 | display(particle, loc); 146 | } 147 | 148 | if (subEffectAtEndClass != null) effectManager.start(subEffectAtEndClass, subEffectAtEnd, loc); 149 | if (subEffectAtEndCachedClass != null && effectAtEndCached == null) effectAtEndCached = effectManager.start(subEffectAtEndCachedClass, subEffectAtEndCached, loc); 150 | } 151 | 152 | @Override 153 | protected void initialize() { 154 | super.initialize(); 155 | 156 | if (subEffectAtEnd != null) { 157 | subEffectAtEndClass = subEffectAtEnd.getString("subEffectAtEndClass"); 158 | } 159 | 160 | if (subEffectAtEndCached != null) { 161 | subEffectAtEndCachedClass = subEffectAtEndCached.getString("subEffectAtEndCachedClass"); 162 | } 163 | } 164 | 165 | } 166 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/LoveEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.Particle; 5 | 6 | import de.slikey.effectlib.Effect; 7 | import de.slikey.effectlib.EffectType; 8 | import de.slikey.effectlib.EffectManager; 9 | import de.slikey.effectlib.util.RandomUtils; 10 | 11 | public class LoveEffect extends Effect { 12 | 13 | public LoveEffect(EffectManager effectManager) { 14 | super(effectManager); 15 | type = EffectType.REPEATING; 16 | particle = Particle.HEART; 17 | period = 2; 18 | iterations = 600; 19 | } 20 | 21 | @Override 22 | public void onRun() { 23 | Location location = getLocation(); 24 | 25 | if (location == null) { 26 | cancel(); 27 | return; 28 | } 29 | 30 | location.add(RandomUtils.getRandomCircleVector().multiply(RandomUtils.random.nextDouble() * 0.6d)); 31 | location.add(0, RandomUtils.random.nextFloat() * 2, 0); 32 | display(particle, location); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/MusicEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Particle; 4 | import org.bukkit.Location; 5 | 6 | import de.slikey.effectlib.Effect; 7 | import de.slikey.effectlib.EffectType; 8 | import de.slikey.effectlib.EffectManager; 9 | 10 | public class MusicEffect extends Effect { 11 | 12 | /** 13 | * Radials to spawn next note. 14 | */ 15 | public double radialsPerStep = Math.PI / 8; 16 | 17 | /** 18 | * Radius of circle above head 19 | */ 20 | public float radius = 0.4F; 21 | 22 | /** 23 | * Current step. Works as a counter 24 | */ 25 | protected float step = 0; 26 | 27 | public MusicEffect(EffectManager effectManager) { 28 | super(effectManager); 29 | type = EffectType.REPEATING; 30 | particle = Particle.NOTE; 31 | iterations = 400; 32 | period = 1; 33 | } 34 | 35 | @Override 36 | public void reset() { 37 | step = 0; 38 | } 39 | 40 | @Override 41 | public void onRun() { 42 | Location location = getLocation(); 43 | 44 | if (location == null) { 45 | cancel(); 46 | return; 47 | } 48 | 49 | location.add(0, 1.9F, 0); 50 | location.add(Math.cos(radialsPerStep * step) * radius, 0, Math.sin(radialsPerStep * step) * radius); 51 | 52 | display(particle, location); 53 | step++; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/ParticleEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Particle; 4 | 5 | import de.slikey.effectlib.Effect; 6 | import de.slikey.effectlib.EffectType; 7 | import de.slikey.effectlib.EffectManager; 8 | import de.slikey.effectlib.util.ParticleUtil; 9 | 10 | public class ParticleEffect extends Effect { 11 | 12 | public ParticleEffect(EffectManager effectManager) { 13 | super(effectManager); 14 | type = EffectType.REPEATING; 15 | particle = ParticleUtil.getParticle("VILLAGER_ANGRY"); 16 | period = 1; 17 | iterations = 1; 18 | } 19 | 20 | @Override 21 | public void onRun() { 22 | display(particle, getLocation()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/PlotEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import java.util.Set; 4 | import java.util.Arrays; 5 | import java.util.HashSet; 6 | 7 | import org.bukkit.Particle; 8 | import org.bukkit.Location; 9 | 10 | import de.slikey.effectlib.Effect; 11 | import de.slikey.effectlib.EffectType; 12 | import de.slikey.effectlib.EffectManager; 13 | import de.slikey.effectlib.math.EquationStore; 14 | import de.slikey.effectlib.math.EquationTransform; 15 | import de.slikey.effectlib.util.ParticleUtil; 16 | 17 | public class PlotEffect extends Effect { 18 | 19 | private final static String[] _variables = {"t", "i"}; 20 | private final static Set variables = new HashSet<>(Arrays.asList(_variables)); 21 | 22 | /** 23 | * The equation to use for x-values. If not set, the iteration count will be used. 24 | */ 25 | public String xEquation; 26 | 27 | /** 28 | * The equation to use for y-values. If not set, the iteration count will be used. 29 | */ 30 | public String yEquation; 31 | 32 | /** 33 | * The equation to use for y-values. If not set, 0 will be used. 34 | */ 35 | public String zEquation; 36 | 37 | /** 38 | * This is a shortcut to quickly scaling the x value. 39 | */ 40 | public double xScale = 1.0; 41 | 42 | /** 43 | * This is a shortcut to quickly scaling the y value. 44 | */ 45 | public double yScale = 1.0; 46 | 47 | /** 48 | * This is a shortcut to quickly scaling the z value. 49 | */ 50 | public double zScale = 1.0; 51 | 52 | /** 53 | * This will re-spawn particles as the plot moves to make a solid line. 54 | */ 55 | public boolean persistent = true; 56 | 57 | private int step = 0; 58 | 59 | public PlotEffect(EffectManager effectManager) { 60 | super(effectManager); 61 | type = EffectType.REPEATING; 62 | particle = ParticleUtil.getParticle("REDSTONE"); 63 | period = 1; 64 | iterations = 100; 65 | } 66 | 67 | @Override 68 | public void onRun() { 69 | int base = persistent ? 0 : step; 70 | 71 | Location location; 72 | 73 | if (getLocation() == null) { 74 | cancel(); 75 | return; 76 | } 77 | 78 | double xOffset; 79 | double yOffset; 80 | double zOffset; 81 | 82 | EquationTransform transform; 83 | 84 | for (int i = base; i <= step; i++) { 85 | location = getLocation().clone(); 86 | xOffset = step; 87 | yOffset = step; 88 | zOffset = 0; 89 | 90 | if (xEquation != null && !xEquation.isEmpty()) { 91 | transform = EquationStore.getInstance().getTransform(xEquation, variables); 92 | xOffset = transform.get(i, maxIterations); 93 | } 94 | 95 | if (yEquation != null && !yEquation.isEmpty()) { 96 | transform = EquationStore.getInstance().getTransform(yEquation, variables); 97 | yOffset = transform.get(i, maxIterations); 98 | } 99 | 100 | if (zEquation != null && !zEquation.isEmpty()) { 101 | transform = EquationStore.getInstance().getTransform(zEquation, variables); 102 | zOffset = transform.get(i, maxIterations); 103 | } 104 | 105 | location.add(xOffset * xScale, yOffset * yScale, zOffset * zScale); 106 | display(particle, location); 107 | } 108 | 109 | step++; 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/PyramidEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.Particle; 5 | import org.bukkit.util.Vector; 6 | 7 | import de.slikey.effectlib.Effect; 8 | import de.slikey.effectlib.EffectManager; 9 | import de.slikey.effectlib.EffectType; 10 | 11 | public class PyramidEffect extends Effect { 12 | 13 | /** 14 | * Particles in each row 15 | */ 16 | public int particles = 8; 17 | 18 | /** 19 | * Center to edge distance 20 | */ 21 | public double radius = 0; 22 | 23 | public PyramidEffect(EffectManager effectManager) { 24 | super(effectManager); 25 | type = EffectType.REPEATING; 26 | particle = Particle.FLAME; 27 | period = 5; 28 | iterations = 200; 29 | } 30 | 31 | @Override 32 | public void onRun() { 33 | Location location = getLocation(); 34 | drawOutline(location); 35 | } 36 | 37 | private void drawOutline(Location location) { 38 | Vector v = new Vector(); 39 | for (int i = 0; i < particles; i++) { 40 | // X base 41 | drawEdge(location, v, i, 0, 0, -1); 42 | drawEdge(location, v, i, 0, 0, 1); 43 | 44 | // Z base 45 | drawEdge(location, v, i, -1, 0, 0); 46 | drawEdge(location, v, i, 1, 0, 0); 47 | 48 | // diagonals 49 | drawEdge(location, v, i, -1, 1, -1); 50 | drawEdge(location, v, i, -1, 1, 1); 51 | drawEdge(location, v, i, 1, 1, -1); 52 | drawEdge(location, v, i, 1, 1, 1); 53 | } 54 | } 55 | 56 | private void drawEdge(Location center, Vector v, int i, int dx, int dy, int dz) { 57 | // Y goes from 0 to 1 58 | // X and Z go from -1 to 1 59 | double ratio = (double)i / particles; 60 | if (dy == 1) { 61 | v.setY(ratio); 62 | 63 | if (dx < 0) v.setX(ratio - 1); 64 | else v.setX(1 - ratio); 65 | 66 | if (dz < 0) v.setZ(ratio - 1); 67 | else v.setZ(1 - ratio); 68 | } else { 69 | v.setY(0); 70 | 71 | if (dx == 0) v.setX(ratio * 2 - 1); 72 | else v.setX(dx); 73 | 74 | if (dz == 0) v.setZ(ratio * 2 - 1); 75 | else v.setZ(dz); 76 | } 77 | display(particle, center.add(v.multiply(radius))); 78 | center.subtract(v); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/ShieldEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Particle; 4 | import org.bukkit.Location; 5 | import org.bukkit.util.Vector; 6 | 7 | import de.slikey.effectlib.Effect; 8 | import de.slikey.effectlib.EffectType; 9 | import de.slikey.effectlib.EffectManager; 10 | import de.slikey.effectlib.util.RandomUtils; 11 | 12 | public class ShieldEffect extends Effect { 13 | 14 | /** 15 | * Radius of the shield 16 | */ 17 | public double radius = 3; 18 | 19 | /** 20 | * Particles to display 21 | */ 22 | public int particles = 50; 23 | 24 | /** 25 | * Set to false for a half-sphere and true for a complete sphere 26 | */ 27 | public boolean sphere = false; 28 | 29 | // Set to true to reverse the direction of the shield (works only if sphere is set to false) 30 | public boolean reverse = false; 31 | 32 | public ShieldEffect(EffectManager effectManager) { 33 | super(effectManager); 34 | type = EffectType.REPEATING; 35 | particle = Particle.FLAME; 36 | iterations = 500; 37 | period = 1; 38 | } 39 | 40 | @Override 41 | public void onRun() { 42 | Location location = getLocation(); 43 | Vector v; 44 | 45 | if (location == null) { 46 | cancel(); 47 | return; 48 | } 49 | 50 | for (int i = 0; i < particles; i++) { 51 | v = RandomUtils.getRandomVector().multiply(radius); 52 | if (!sphere) { 53 | if (reverse) v.setY(Math.abs(v.getY()) * -1); 54 | else v.setY(Math.abs(v.getY())); 55 | } 56 | 57 | location.add(v); 58 | display(particle, location); 59 | location.subtract(v); 60 | } 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/SkyRocketEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import de.slikey.effectlib.EffectManager; 4 | 5 | public class SkyRocketEffect extends JumpEffect { 6 | 7 | public SkyRocketEffect(EffectManager effectManager) { 8 | super(effectManager); 9 | power = 10; 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/SmokeEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.Particle; 5 | 6 | import de.slikey.effectlib.Effect; 7 | import de.slikey.effectlib.EffectType; 8 | import de.slikey.effectlib.EffectManager; 9 | import de.slikey.effectlib.util.ParticleUtil; 10 | import de.slikey.effectlib.util.RandomUtils; 11 | 12 | public class SmokeEffect extends Effect { 13 | 14 | /** 15 | * Number of particles to display 16 | */ 17 | public int particles = 20; 18 | 19 | public SmokeEffect(EffectManager effectManager) { 20 | super(effectManager); 21 | type = EffectType.REPEATING; 22 | particle = ParticleUtil.getParticle("SMOKE_NORMAL"); 23 | period = 1; 24 | iterations = 300; 25 | } 26 | 27 | @Override 28 | public void onRun() { 29 | Location location = getLocation(); 30 | 31 | if (location == null) { 32 | cancel(); 33 | return; 34 | } 35 | 36 | for (int i = 0; i < particles; i++) { 37 | location.add(RandomUtils.getRandomCircleVector().multiply(RandomUtils.random.nextDouble() * 0.6d)); 38 | location.add(0, RandomUtils.random.nextFloat() * 2, 0); 39 | display(particle, location); 40 | } 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/SoundEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import de.slikey.effectlib.Effect; 4 | import de.slikey.effectlib.EffectType; 5 | import de.slikey.effectlib.EffectManager; 6 | import de.slikey.effectlib.util.CustomSound; 7 | 8 | public class SoundEffect extends Effect { 9 | 10 | /** 11 | * Sound effect to play 12 | * Format: ,,, 13 | */ 14 | public CustomSound sound; 15 | 16 | public SoundEffect(EffectManager effectManager) { 17 | super(effectManager); 18 | type = EffectType.REPEATING; 19 | period = 1; 20 | iterations = 1; 21 | } 22 | 23 | @Override 24 | public void onRun() { 25 | if (sound == null) return; 26 | sound.play(effectManager.getOwningPlugin(), getLocation()); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/SphereEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Particle; 4 | import org.bukkit.Location; 5 | import org.bukkit.util.Vector; 6 | 7 | import de.slikey.effectlib.Effect; 8 | import de.slikey.effectlib.EffectType; 9 | import de.slikey.effectlib.EffectManager; 10 | import de.slikey.effectlib.util.ParticleUtil; 11 | import de.slikey.effectlib.util.RandomUtils; 12 | 13 | public class SphereEffect extends Effect { 14 | 15 | /** 16 | * Radius of the sphere 17 | */ 18 | public double radius = 0.6; 19 | 20 | /** 21 | * Y-Offset of the sphere 22 | */ 23 | public double yOffset = 0; 24 | 25 | /** 26 | * Particles to display 27 | */ 28 | public int particles = 50; 29 | 30 | /** 31 | * Amount to increase the radius per tick 32 | */ 33 | public double radiusIncrease = 0; 34 | 35 | // Amount to increase the particles per tick 36 | public int particleIncrease = 0; 37 | 38 | public SphereEffect(EffectManager effectManager) { 39 | super(effectManager); 40 | type = EffectType.REPEATING; 41 | particle = ParticleUtil.getParticle("SPELL_MOB"); 42 | iterations = 500; 43 | period = 1; 44 | } 45 | 46 | @Override 47 | public void onRun() { 48 | if (radiusIncrease != 0) radius += radiusIncrease; 49 | if (particleIncrease != 0) particles += particleIncrease; 50 | 51 | Location location = getLocation(); 52 | 53 | if (location == null) { 54 | cancel(); 55 | return; 56 | } 57 | 58 | location.add(0, yOffset, 0); 59 | Vector v; 60 | 61 | for (int i = 0; i < particles; i++) { 62 | v = RandomUtils.getRandomVector().multiply(radius); 63 | location.add(v); 64 | display(particle, location); 65 | location.subtract(v); 66 | } 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/SquareEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Particle; 4 | import org.bukkit.Location; 5 | import org.bukkit.util.Vector; 6 | 7 | import de.slikey.effectlib.Effect; 8 | import de.slikey.effectlib.EffectType; 9 | import de.slikey.effectlib.EffectManager; 10 | import de.slikey.effectlib.util.ParticleUtil; 11 | import de.slikey.effectlib.util.RandomUtils; 12 | 13 | public class SquareEffect extends Effect { 14 | 15 | /** 16 | * Radius of the square 17 | */ 18 | public double radius = 0.6; 19 | 20 | /** 21 | * y-offset of the square 22 | */ 23 | public double yOffset = 0; 24 | 25 | /** 26 | * Amount of particles to display 27 | */ 28 | public int particles = 50; 29 | 30 | /** 31 | * Amount to increase the radius per tick 32 | */ 33 | public double radiusIncrease = 0; 34 | 35 | /** 36 | * Amount to increase the particles per tick 37 | */ 38 | public int particleIncrease = 0; 39 | 40 | public SquareEffect(EffectManager effectManager) { 41 | super(effectManager); 42 | type = EffectType.REPEATING; 43 | particle = ParticleUtil.getParticle("SPELL_MOB"); 44 | iterations = 500; 45 | period = 1; 46 | } 47 | 48 | @Override 49 | public void onRun() { 50 | if (radiusIncrease != 0) radius += radiusIncrease; 51 | if (particleIncrease != 0) particles += particleIncrease; 52 | 53 | Location location = getLocation(); 54 | 55 | if (location == null) { 56 | cancel(); 57 | return; 58 | } 59 | 60 | location.add(0, yOffset, 0); 61 | Vector v; 62 | 63 | for (int i = 0; i < particles; i++) { 64 | v = RandomUtils.getRandomFlatVector().multiply(radius); 65 | location.add(v); 66 | display(particle, location); 67 | location.subtract(v); 68 | } 69 | location.subtract(0, yOffset, 0); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/StarEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.Particle; 5 | import org.bukkit.util.Vector; 6 | 7 | import de.slikey.effectlib.Effect; 8 | import de.slikey.effectlib.EffectType; 9 | import de.slikey.effectlib.EffectManager; 10 | import de.slikey.effectlib.util.MathUtils; 11 | import de.slikey.effectlib.util.RandomUtils; 12 | import de.slikey.effectlib.util.VectorUtils; 13 | 14 | public class StarEffect extends Effect { 15 | 16 | /** 17 | * Particles per spike 18 | */ 19 | public int particles = 50; 20 | 21 | /** 22 | * Height of the spikes in blocks 23 | */ 24 | public float spikeHeight = 3.5F; 25 | 26 | /** 27 | * Half amount of spikes. Creation is only done half and then mirrored. 28 | */ 29 | public int spikesHalf = 3; 30 | 31 | /** 32 | * Inner radius of the star. (0.5) 33 | */ 34 | public float innerRadius = 0.5F; 35 | 36 | public StarEffect(EffectManager effectManager) { 37 | super(effectManager); 38 | type = EffectType.REPEATING; 39 | particle = Particle.FLAME; 40 | period = 4; 41 | iterations = 50; 42 | } 43 | 44 | @Override 45 | public void onRun() { 46 | Location location = getLocation(); 47 | 48 | if (location == null) { 49 | cancel(); 50 | return; 51 | } 52 | 53 | float radius = 3 * innerRadius / MathUtils.SQRT_3; 54 | 55 | double xRotation; 56 | double angle; 57 | float height; 58 | Vector v; 59 | 60 | for (int i = 0; i < spikesHalf * 2; i++) { 61 | xRotation = i * Math.PI / spikesHalf; 62 | for (int x = 0; x < particles; x++) { 63 | angle = 2 * Math.PI * x / particles; 64 | height = RandomUtils.random.nextFloat() * spikeHeight; 65 | v = new Vector(Math.cos(angle), 0, Math.sin(angle)); 66 | v.multiply((spikeHeight - height) * radius / spikeHeight); 67 | v.setY(innerRadius + height); 68 | 69 | VectorUtils.rotateAroundAxisX(v, xRotation); 70 | location.add(v); 71 | display(particle, location); 72 | location.subtract(v); 73 | 74 | VectorUtils.rotateAroundAxisX(v, Math.PI); 75 | VectorUtils.rotateAroundAxisY(v, Math.PI / 2); 76 | 77 | location.add(v); 78 | display(particle, location); 79 | location.subtract(v); 80 | } 81 | } 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/TextEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import java.awt.Font; 4 | import java.awt.Color; 5 | import java.util.Objects; 6 | import java.awt.image.BufferedImage; 7 | 8 | import org.bukkit.Location; 9 | import org.bukkit.Particle; 10 | import org.bukkit.util.Vector; 11 | 12 | import de.slikey.effectlib.Effect; 13 | import de.slikey.effectlib.EffectType; 14 | import de.slikey.effectlib.EffectManager; 15 | import de.slikey.effectlib.util.MathUtils; 16 | import de.slikey.effectlib.util.ParticleUtil; 17 | import de.slikey.effectlib.util.VectorUtils; 18 | import de.slikey.effectlib.util.StringParser; 19 | 20 | public class TextEffect extends Effect { 21 | 22 | /** 23 | * Text to display 24 | */ 25 | public String text = "Text"; 26 | 27 | /** 28 | * Invert the text 29 | */ 30 | public boolean invert = false; 31 | 32 | /** 33 | * Each stepX pixel will be shown. Saves packets for lower fontsizes. 34 | */ 35 | public int stepX = 1; 36 | 37 | /** 38 | * Each stepY pixel will be shown. Saves packets for lower fontsizes. 39 | */ 40 | public int stepY = 1; 41 | 42 | /** 43 | * Scale the font down 44 | */ 45 | public float size = (float) 1 / 5; 46 | 47 | /** 48 | * Set this only to true if you are working with changing text. I'll advice 49 | * the parser to recalculate the BufferedImage every iteration. 50 | * Recommended FALSE 51 | */ 52 | public boolean realtime = false; 53 | 54 | /** 55 | * Font to create the Text 56 | */ 57 | public Font font; 58 | 59 | /** 60 | * Contains an image version of the String 61 | */ 62 | protected BufferedImage image = null; 63 | 64 | /** 65 | * Track the text used most recently when parsing 66 | */ 67 | private String lastParsedText = null; 68 | 69 | /** 70 | * Track the font used most recently when parsing 71 | */ 72 | private Font lastParsedFont = null; 73 | 74 | public TextEffect(EffectManager effectManager) { 75 | super(effectManager); 76 | font = new Font("Tahoma", Font.PLAIN, 16); 77 | type = EffectType.REPEATING; 78 | particle = ParticleUtil.getParticle("FIREWORKS_SPARK"); 79 | period = 40; 80 | iterations = 20; 81 | } 82 | 83 | public void setFont(Font font) { 84 | this.font = font; 85 | } 86 | 87 | @Override 88 | public void onRun() { 89 | if (font == null) { 90 | cancel(); 91 | return; 92 | } 93 | 94 | Location location = getLocation(); 95 | 96 | if (location == null) { 97 | cancel(); 98 | return; 99 | } 100 | 101 | int clr; 102 | Vector v; 103 | 104 | try { 105 | if (image == null || shouldRecalculateImage()) { 106 | lastParsedText = text; 107 | lastParsedFont = font; 108 | // Use last parsed references instead for additional thread safety 109 | image = StringParser.stringToBufferedImage(lastParsedFont, lastParsedText); 110 | } 111 | for (int y = 0; y < image.getHeight(); y += stepY) { 112 | for (int x = 0; x < image.getWidth(); x += stepX) { 113 | clr = image.getRGB(x, y); 114 | if (!invert && Color.black.getRGB() != clr) continue; 115 | else if (invert && Color.black.getRGB() == clr) continue; 116 | 117 | v = new Vector((float) image.getWidth() / 2 - x, (float) image.getHeight() / 2 - y, 0).multiply(size); 118 | VectorUtils.rotateAroundAxisY(v, -location.getYaw() * MathUtils.degreesToRadians); 119 | display(particle, location.add(v)); 120 | location.subtract(v); 121 | } 122 | } 123 | } catch (Exception ex) { 124 | // This seems to happen on bad characters in strings, 125 | // I'm choosing to ignore the exception and cancel the effect for now. 126 | cancel(); 127 | } 128 | } 129 | 130 | private boolean shouldRecalculateImage() { 131 | // Don't bother if we don't use real time updates 132 | if (!realtime) return false; 133 | 134 | // Text content or font is different, recalculate 135 | return !Objects.equals(lastParsedText, text) || !Objects.equals(lastParsedFont, font); 136 | } 137 | 138 | } 139 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/TornadoEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import java.util.List; 4 | import java.util.ArrayList; 5 | 6 | import org.bukkit.Color; 7 | import org.bukkit.Location; 8 | import org.bukkit.Particle; 9 | import org.bukkit.util.Vector; 10 | 11 | import de.slikey.effectlib.Effect; 12 | import de.slikey.effectlib.EffectType; 13 | import de.slikey.effectlib.EffectManager; 14 | import de.slikey.effectlib.util.RandomUtils; 15 | 16 | public class TornadoEffect extends Effect { 17 | 18 | /** 19 | * Tornado particle 20 | */ 21 | public Particle tornadoParticle = Particle.FLAME; 22 | public Color tornadoColor = null; 23 | 24 | /** 25 | * Particle of the cloud 26 | */ 27 | public Particle cloudParticle = Particle.CLOUD; 28 | public Color cloudColor = null; 29 | public float cloudSpeed = 0; 30 | 31 | /** 32 | * Size of the cloud 33 | */ 34 | public float cloudSize = 2.5F; 35 | 36 | /** 37 | * Y-Offset from location 38 | */ 39 | public double yOffset = 0.8; 40 | 41 | /** 42 | * Height of the Tornado 43 | */ 44 | public float tornadoHeight = 5F; 45 | 46 | /** 47 | * Max radius of the Tornado 48 | */ 49 | public float maxTornadoRadius = 5F; 50 | 51 | /** 52 | * Should the cloud appear? 53 | */ 54 | public boolean showCloud = true; 55 | 56 | /** 57 | * Should the tornado appear? 58 | */ 59 | public boolean showTornado = true; 60 | 61 | /** 62 | * Distance between each row 63 | */ 64 | public double distance = .375d; 65 | 66 | /** 67 | * Number of particles per circle 68 | */ 69 | public int circleParticles = 64; 70 | 71 | /** 72 | * Number of particles in the cloud 73 | */ 74 | public int cloudParticles = 100; 75 | 76 | /** 77 | * Amount of y-jitter between circle particles 78 | */ 79 | public double circleHeight = 0; 80 | 81 | /** 82 | * Internal counter 83 | */ 84 | protected int step = 0; 85 | 86 | public TornadoEffect(EffectManager manager) { 87 | super(manager); 88 | type = EffectType.REPEATING; 89 | period = 5; 90 | iterations = 20; 91 | } 92 | 93 | @Override 94 | public void reset() { 95 | step = 0; 96 | } 97 | 98 | @Override 99 | public void onRun() { 100 | if (getLocation() == null) { 101 | cancel(); 102 | return; 103 | } 104 | 105 | Location l = getLocation().add(0, yOffset, 0); 106 | Vector vector; 107 | 108 | for (int i = 0; i < (cloudParticles * cloudSize); i++) { 109 | vector = RandomUtils.getRandomCircleVector().multiply(RandomUtils.random.nextDouble() * cloudSize); 110 | if (showCloud) { 111 | display(cloudParticle, l.add(vector), cloudColor, cloudSpeed, 1); 112 | l.subtract(vector); 113 | } 114 | } 115 | 116 | Location t = l.clone().add(0, 0.2, 0); 117 | double r = 0.45 * (maxTornadoRadius * (2.35 / tornadoHeight)); 118 | double fr; 119 | 120 | for (double y = 0; y < tornadoHeight; y += distance) { 121 | fr = r * y; 122 | if (fr > maxTornadoRadius) fr = maxTornadoRadius; 123 | 124 | for (Vector v : createCircle(y, fr)) { 125 | if (showTornado) { 126 | if (circleHeight > 0) v.setY(v.getY() + RandomUtils.random.nextDouble() * circleHeight / 2 - circleHeight / 2); 127 | display(tornadoParticle, t.add(v), tornadoColor); 128 | t.subtract(v); 129 | step++; 130 | } 131 | } 132 | } 133 | l.subtract(0, yOffset, 0); 134 | } 135 | 136 | public List createCircle(double y, double radius) { 137 | double amount = radius * circleParticles; 138 | double inc = (2 * Math.PI) / amount; 139 | List vectors = new ArrayList<>(); 140 | 141 | double angle; 142 | double x; 143 | double z; 144 | Vector v; 145 | 146 | for (int i = 0; i < amount; i++) { 147 | angle = i * inc; 148 | x = radius * Math.cos(angle); 149 | z = radius * Math.sin(angle); 150 | v = new Vector(x, y, z); 151 | vectors.add(v); 152 | } 153 | return vectors; 154 | } 155 | 156 | } 157 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/TraceEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import java.util.List; 4 | import java.util.ArrayList; 5 | 6 | import org.bukkit.World; 7 | import org.bukkit.Location; 8 | import org.bukkit.Particle; 9 | import org.bukkit.util.Vector; 10 | 11 | import de.slikey.effectlib.Effect; 12 | import de.slikey.effectlib.EffectType; 13 | import de.slikey.effectlib.EffectManager; 14 | 15 | public class TraceEffect extends Effect { 16 | 17 | /** 18 | * Iterations to wait before refreshing particles 19 | */ 20 | public int refresh = 5; 21 | 22 | /** 23 | * Maximum amount of way points 24 | */ 25 | public int maxWayPoints = 30; 26 | 27 | /** 28 | * Waypoints of the trace 29 | */ 30 | protected final List wayPoints = new ArrayList<>(); 31 | 32 | /** 33 | * Internal counter 34 | */ 35 | protected int step = 0; 36 | 37 | /** 38 | * World of the trace 39 | */ 40 | protected World world; 41 | 42 | public TraceEffect(EffectManager effectManager) { 43 | super(effectManager); 44 | type = EffectType.REPEATING; 45 | particle = Particle.FLAME; 46 | period = 1; 47 | iterations = 600; 48 | } 49 | 50 | @Override 51 | public void reset() { 52 | step = 0; 53 | } 54 | 55 | @Override 56 | public void onRun() { 57 | Location location = getLocation(); 58 | 59 | if (location == null) { 60 | cancel(); 61 | return; 62 | } 63 | 64 | if (world == null) { 65 | world = location.getWorld(); 66 | } else if (!location.getWorld().equals(world)) { 67 | cancel(); 68 | return; 69 | } 70 | 71 | synchronized(wayPoints) { 72 | if (wayPoints.size() >= maxWayPoints) wayPoints.remove(0); 73 | } 74 | 75 | wayPoints.add(location.toVector()); 76 | step++; 77 | if (step % refresh != 0) return; 78 | 79 | synchronized(wayPoints) { 80 | Location particleLocation; 81 | for (Vector position : wayPoints) { 82 | particleLocation = new Location(world, position.getX(), position.getY(), position.getZ()); 83 | display(particle, particleLocation); 84 | } 85 | } 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/TurnEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.entity.Entity; 5 | 6 | import de.slikey.effectlib.Effect; 7 | import de.slikey.effectlib.EffectType; 8 | import de.slikey.effectlib.EffectManager; 9 | 10 | public class TurnEffect extends Effect { 11 | 12 | /** 13 | * Angular movement per iteration 14 | */ 15 | public float step = 11.25F; 16 | 17 | public TurnEffect(EffectManager effectManager) { 18 | super(effectManager); 19 | type = EffectType.REPEATING; 20 | period = 1; 21 | iterations = (int) (360 * 5 / step); 22 | asynchronous = false; 23 | } 24 | 25 | @Override 26 | public void onRun() { 27 | Entity entity = getEntity(); 28 | if (entity == null) { 29 | cancel(); 30 | return; 31 | } 32 | Location loc = entity.getLocation(); 33 | loc.setYaw(loc.getYaw() + step); 34 | entity.teleport(loc); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/VortexEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.Particle; 5 | import org.bukkit.util.Vector; 6 | 7 | import de.slikey.effectlib.Effect; 8 | import de.slikey.effectlib.EffectType; 9 | import de.slikey.effectlib.EffectManager; 10 | import de.slikey.effectlib.util.MathUtils; 11 | import de.slikey.effectlib.util.VectorUtils; 12 | 13 | public class VortexEffect extends Effect { 14 | 15 | /** 16 | * Radius of vortex (2) 17 | */ 18 | public float radius = 2; 19 | 20 | /** 21 | * Radius grow per iteration (0.00) 22 | */ 23 | public float radiusGrow = 0.00F; 24 | 25 | /** 26 | * Initial range of the vortex (0.0) 27 | */ 28 | public float initRange = 0.0F; 29 | 30 | /** 31 | * Growing per iteration (0.05) 32 | */ 33 | public float grow = 0.05F; 34 | 35 | /** 36 | * Radials per iteration (PI / 16) 37 | */ 38 | public double radials = Math.PI / 16; 39 | 40 | /** 41 | * Helix-circles per iteration (3) 42 | */ 43 | public int circles = 3; 44 | 45 | /** 46 | * Amount of helices (4) 47 | * Yay for the typo 48 | */ 49 | public int helixes = 4; 50 | 51 | /** 52 | * Current step. Works as counter 53 | */ 54 | protected int step = 0; 55 | 56 | public VortexEffect(EffectManager effectManager) { 57 | super(effectManager); 58 | type = EffectType.REPEATING; 59 | particle = Particle.FLAME; 60 | period = 1; 61 | iterations = 200; 62 | } 63 | 64 | @Override 65 | public void reset() { 66 | step = 0; 67 | } 68 | 69 | @Override 70 | public void onRun() { 71 | Location location = getLocation(); 72 | double angle; 73 | Vector v; 74 | 75 | if (location == null) { 76 | cancel(); 77 | return; 78 | } 79 | 80 | for (int x = 0; x < circles; x++) { 81 | for (int i = 0; i < helixes; i++) { 82 | angle = step * radials + (2 * Math.PI * i / helixes); 83 | v = new Vector(Math.cos(angle) * (radius + step * radiusGrow), initRange + step * grow, Math.sin(angle) * (radius + step * radiusGrow)); 84 | VectorUtils.rotateAroundAxisX(v, (location.getPitch() + 90) * MathUtils.degreesToRadians); 85 | VectorUtils.rotateAroundAxisY(v, -location.getYaw() * MathUtils.degreesToRadians); 86 | 87 | location.add(v); 88 | display(particle, location); 89 | location.subtract(v); 90 | } 91 | step++; 92 | } 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/effect/WarpEffect.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.effect; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.Particle; 5 | 6 | import de.slikey.effectlib.Effect; 7 | import de.slikey.effectlib.EffectType; 8 | import de.slikey.effectlib.EffectManager; 9 | import de.slikey.effectlib.util.ParticleUtil; 10 | 11 | public class WarpEffect extends Effect { 12 | 13 | /** 14 | * Radius of the spawned circles 15 | */ 16 | public float radius = 1; 17 | 18 | /** 19 | * Particles per circle 20 | */ 21 | public int particles = 20; 22 | 23 | /** 24 | * Interval of the circles 25 | */ 26 | public float grow = 0.2F; 27 | 28 | /** 29 | * Circles to display 30 | */ 31 | public int rings = 12; 32 | 33 | /** 34 | * Internal counter 35 | */ 36 | protected int step = 0; 37 | 38 | public WarpEffect(EffectManager effectManager) { 39 | super(effectManager); 40 | type = EffectType.REPEATING; 41 | particle = ParticleUtil.getParticle("FIREWORKS_SPARK"); 42 | period = 2; 43 | iterations = rings; 44 | } 45 | 46 | @Override 47 | public void reset() { 48 | step = 0; 49 | } 50 | 51 | @Override 52 | public void onRun() { 53 | Location location = getLocation(); 54 | 55 | if (location == null) { 56 | cancel(); 57 | return; 58 | } 59 | 60 | if (step > rings) step = 0; 61 | 62 | double x, y, z; 63 | double angle; 64 | 65 | y = step * grow; 66 | location.add(0, y, 0); 67 | 68 | for (int i = 0; i < particles; i++) { 69 | angle = (double) 2 * Math.PI * i / particles; 70 | x = Math.cos(angle) * radius; 71 | z = Math.sin(angle) * radius; 72 | location.add(x, 0, z); 73 | display(particle, location); 74 | location.subtract(x, 0, z); 75 | } 76 | location.subtract(0, y, 0); 77 | step++; 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/math/ConstantTransform.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.math; 2 | 3 | import org.bukkit.configuration.ConfigurationSection; 4 | 5 | public class ConstantTransform implements Transform { 6 | 7 | private double value; 8 | 9 | public ConstantTransform() { 10 | 11 | } 12 | 13 | public ConstantTransform(double value) { 14 | this.value = value; 15 | } 16 | 17 | @Override 18 | public void load(ConfigurationSection parameters) { 19 | value = parameters.getDouble("value"); 20 | } 21 | 22 | @Override 23 | public double get(double input) { 24 | return value; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/math/EchoTransform.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.math; 2 | 3 | import org.bukkit.configuration.ConfigurationSection; 4 | 5 | public class EchoTransform implements Transform { 6 | 7 | @Override 8 | public void load(ConfigurationSection parameters) { 9 | } 10 | 11 | @Override 12 | public double get(double input) { 13 | return input; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/math/EquationStore.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.math; 2 | 3 | import java.util.Map; 4 | import java.util.HashMap; 5 | import java.util.Collection; 6 | 7 | public class EquationStore { 8 | 9 | private static final String DEFAULT_VARIABLE = "x"; 10 | private static EquationStore instance; 11 | private final Map transforms = new HashMap<>(); 12 | 13 | public EquationTransform getTransform(String equation) { 14 | return getTransform(equation, DEFAULT_VARIABLE); 15 | } 16 | 17 | public EquationTransform getTransform(String equation, String variable) { 18 | EquationTransform transform = transforms.get(equation); 19 | if (transform == null) { 20 | transform = new EquationTransform(equation, variable); 21 | transforms.put(equation, transform); 22 | } 23 | 24 | return transform; 25 | } 26 | 27 | public EquationTransform getTransform(String equation, String... variables) { 28 | String equationKey = equation + ":" + String.join(",", variables); 29 | EquationTransform transform = transforms.get(equationKey); 30 | if (transform == null) { 31 | transform = new EquationTransform(equation, variables); 32 | transforms.put(equationKey, transform); 33 | } 34 | 35 | return transform; 36 | } 37 | 38 | public EquationTransform getTransform(String equation, Collection variables) { 39 | String equationKey = equation + ":" + String.join(",", variables); 40 | EquationTransform transform = transforms.get(equationKey); 41 | if (transform == null) { 42 | transform = new EquationTransform(equation, variables); 43 | transforms.put(equationKey, transform); 44 | } 45 | 46 | return transform; 47 | } 48 | 49 | public static void clear() { 50 | if (instance != null) instance.transforms.clear(); 51 | } 52 | 53 | public static EquationStore getInstance() { 54 | if (instance == null) instance = new EquationStore(); 55 | 56 | return instance; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/math/EquationVariableProvider.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.math; 2 | 3 | public interface EquationVariableProvider { 4 | Double getVariable(String variable); 5 | } 6 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/math/MultiplyTransform.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.math; 2 | 3 | import java.util.Collection; 4 | 5 | import org.bukkit.configuration.ConfigurationSection; 6 | 7 | public class MultiplyTransform implements Transform { 8 | 9 | private Collection inputs; 10 | 11 | @Override 12 | public void load(ConfigurationSection parameters) { 13 | inputs = Transforms.loadTransformList(parameters, "inputs"); 14 | } 15 | 16 | @Override 17 | public double get(double input) { 18 | double value = 1; 19 | for (Transform transform : inputs) { 20 | value *= transform.get(input); 21 | } 22 | return value; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/math/SequenceTransform.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.math; 2 | 3 | import java.util.List; 4 | import java.util.ArrayList; 5 | import java.util.Collection; 6 | import java.util.Collections; 7 | 8 | import de.slikey.effectlib.util.ConfigUtils; 9 | 10 | import org.bukkit.configuration.ConfigurationSection; 11 | 12 | public class SequenceTransform implements Transform { 13 | 14 | private List steps; 15 | 16 | private static class Sequence { 17 | 18 | private final Transform transform; 19 | private final double start; 20 | 21 | public Sequence(ConfigurationSection configuration) { 22 | transform = Transforms.loadTransform(configuration, "transform"); 23 | start = configuration.getDouble("start", 0); 24 | } 25 | 26 | public double getStart() { 27 | return start; 28 | } 29 | 30 | public double get(double t) { 31 | return transform.get(t); 32 | } 33 | 34 | } 35 | 36 | @Override 37 | public void load(ConfigurationSection parameters) { 38 | steps = new ArrayList<>(); 39 | Collection stepConfigurations = ConfigUtils.getNodeList(parameters, "steps"); 40 | for (ConfigurationSection stepConfig : stepConfigurations) { 41 | steps.add(new Sequence(stepConfig)); 42 | } 43 | Collections.reverse(steps); 44 | } 45 | 46 | @Override 47 | public double get(double input) { 48 | double value = 0; 49 | for (Sequence step : steps) { 50 | if (step.getStart() <= input) return step.get(input); 51 | } 52 | return value; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/math/SumTransform.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.math; 2 | 3 | import java.util.Collection; 4 | 5 | import org.bukkit.configuration.ConfigurationSection; 6 | 7 | public class SumTransform implements Transform { 8 | 9 | private Collection inputs; 10 | 11 | @Override 12 | public void load(ConfigurationSection parameters) { 13 | inputs = Transforms.loadTransformList(parameters, "inputs"); 14 | } 15 | 16 | @Override 17 | public double get(double input) { 18 | double value = 0; 19 | for (Transform transform : inputs) { 20 | value += transform.get(input); 21 | } 22 | return value; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/math/Transform.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.math; 2 | 3 | import org.bukkit.configuration.ConfigurationSection; 4 | 5 | public interface Transform { 6 | 7 | public void load(ConfigurationSection parameters); 8 | 9 | public double get(double input); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/math/Transforms.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.math; 2 | 3 | import java.util.Map; 4 | import java.util.List; 5 | import java.util.HashMap; 6 | import java.util.ArrayList; 7 | import java.util.Collection; 8 | 9 | import de.slikey.effectlib.EffectManager; 10 | import de.slikey.effectlib.util.ConfigUtils; 11 | 12 | import org.bukkit.configuration.ConfigurationSection; 13 | 14 | public class Transforms { 15 | 16 | private static final String TRANSFORM_BUILTIN_CLASSPATH = "de.slikey.effectlib.math"; 17 | private static Map> transformClasses = new HashMap<>(); 18 | private static List effectManagers = EffectManager.getManagers(); 19 | 20 | public static Transform loadTransform(ConfigurationSection base, String value) { 21 | if (base.isConfigurationSection(value)) return loadTransform(ConfigUtils.getConfigurationSection(base, value)); 22 | if (base.isDouble(value) || base.isInt(value)) return new ConstantTransform(base.getDouble(value)); 23 | if (base.isString(value)) { 24 | String equation = base.getString(value); 25 | if (equation.equalsIgnoreCase("t") || equation.equalsIgnoreCase("time")) return new EchoTransform(); 26 | EquationTransform transform = EquationStore.getInstance().getTransform(equation, "t"); 27 | Exception ex = transform.getException(); 28 | if (ex != null && !effectManagers.isEmpty()) { 29 | for (EffectManager effectManager : effectManagers) { 30 | if (effectManager == null) continue; 31 | effectManager.onError("Error parsing equation: " + equation, ex); 32 | break; 33 | } 34 | } 35 | return transform; 36 | } 37 | return new ConstantTransform(0); 38 | } 39 | 40 | public static Collection loadTransformList(ConfigurationSection base, String value) { 41 | Collection transformConfigs = ConfigUtils.getNodeList(base, value); 42 | List transforms = new ArrayList<>(); 43 | 44 | for (ConfigurationSection transformConfig : transformConfigs) { 45 | transforms.add(loadTransform(transformConfig)); 46 | } 47 | 48 | return transforms; 49 | } 50 | 51 | public static Transform loadTransform(ConfigurationSection parameters) { 52 | Transform transform = null; 53 | if (parameters != null && parameters.contains("class")) { 54 | String className = parameters.getString("class"); 55 | if (className != null) { 56 | try { 57 | if (!className.contains(".")) className = TRANSFORM_BUILTIN_CLASSPATH + "." + className; 58 | 59 | Class genericClass = transformClasses.get(className); 60 | if (genericClass == null) { 61 | try { 62 | genericClass = Class.forName(className + "Transform"); 63 | } catch (Exception ex) { 64 | genericClass = Class.forName(className); 65 | } 66 | 67 | if (!Transform.class.isAssignableFrom(genericClass)) throw new Exception("Must extend Transform"); 68 | transformClasses.put(className, genericClass); 69 | } 70 | 71 | @SuppressWarnings("unchecked") 72 | Class transformClass = (Class)genericClass; 73 | transform = transformClass.newInstance(); 74 | parameters.set("class", null); 75 | transform.load(parameters); 76 | } catch (Exception ex) { 77 | if (!effectManagers.isEmpty()) { 78 | for (EffectManager effectManager : effectManagers) { 79 | if (effectManager == null) continue; 80 | effectManager.onError("Error loading class " + className, ex); 81 | break; 82 | } 83 | } 84 | } 85 | } 86 | } 87 | 88 | return transform == null ? new ConstantTransform(0) : transform; 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/math/VectorTransform.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.math; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.util.Vector; 5 | import org.bukkit.configuration.ConfigurationSection; 6 | 7 | import de.slikey.effectlib.util.VectorUtils; 8 | 9 | public class VectorTransform { 10 | 11 | private final Transform xTransform; 12 | private final Transform yTransform; 13 | private final Transform zTransform; 14 | 15 | private final boolean orient; 16 | 17 | public VectorTransform(ConfigurationSection configuration) { 18 | xTransform = Transforms.loadTransform(configuration, "x"); 19 | yTransform = Transforms.loadTransform(configuration, "y"); 20 | zTransform = Transforms.loadTransform(configuration, "z"); 21 | orient = configuration.getBoolean("orient", true); 22 | } 23 | 24 | public Vector get(Location source, double t) { 25 | // This returns a unit vector with the new direction calculated via the equations 26 | double xValue = xTransform.get(t); 27 | double yValue = yTransform.get(t); 28 | double zValue = zTransform.get(t); 29 | 30 | Vector result = new Vector(xValue, yValue, zValue); 31 | 32 | // Rotates to player's direction 33 | if (orient && source != null) result = VectorUtils.rotateVector(result, source); 34 | 35 | return result; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/math/dQuadraticTransform.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.math; 2 | 3 | import org.bukkit.configuration.ConfigurationSection; 4 | 5 | public class dQuadraticTransform implements Transform { 6 | 7 | private Transform a; 8 | private Transform b; 9 | private Transform c; 10 | 11 | @Override 12 | public void load(ConfigurationSection parameters) { 13 | a = Transforms.loadTransform(parameters, "a"); 14 | b = Transforms.loadTransform(parameters, "b"); 15 | c = Transforms.loadTransform(parameters, "c"); 16 | } 17 | 18 | /** 19 | * This returns the derivative, or velocity, of a quadratic equation at a specific step. 20 | * For a quadratic function: 21 | * f(x) = a(x+b)^2 + c(x+b) + d 22 | * f'(x) = 2a(x+b) + c 23 | * @param input a specific step 24 | * @return the derivative, or velocity, of a quadratic equation 25 | */ 26 | @Override 27 | public double get(double input) { 28 | return 2 * a.get(input) * (input + b.get(input)) + c.get(input); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/math/dSinTransform.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.math; 2 | 3 | import org.bukkit.configuration.ConfigurationSection; 4 | 5 | public class dSinTransform implements Transform { 6 | 7 | private Transform a; 8 | private Transform b; 9 | private Transform c; 10 | 11 | @Override 12 | public void load(ConfigurationSection parameters) { 13 | a = Transforms.loadTransform(parameters, "a"); 14 | b = Transforms.loadTransform(parameters, "b"); 15 | c = Transforms.loadTransform(parameters, "c"); 16 | } 17 | 18 | /** 19 | * This returns the derivative, or velocity, of a sin equation at a specific step. 20 | * For a sin function: 21 | * f(x) = a*sin(b(x+c)) + d 22 | * f'(x) = a*b*cos(b(x+c)) 23 | * @param input a specific step 24 | * @return the derivative, or velocity, of a sin equation 25 | */ 26 | @Override 27 | public double get(double input) { 28 | double bValue = b.get(input); 29 | return a.get(input) * bValue * Math.cos(bValue * (input + c.get(input))); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/util/ConfigUtils.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.util; 2 | 3 | import java.util.Map; 4 | import java.util.List; 5 | import java.util.ArrayList; 6 | import java.util.Collection; 7 | 8 | import org.bukkit.configuration.MemoryConfiguration; 9 | import org.bukkit.configuration.ConfigurationSection; 10 | 11 | public class ConfigUtils { 12 | 13 | public static Collection getNodeList(ConfigurationSection node, String path) { 14 | Collection results = new ArrayList<>(); 15 | List> mapList = node.getMapList(path); 16 | for (Map map : mapList) { 17 | results.add(toConfigurationSection(map)); 18 | } 19 | 20 | return results; 21 | } 22 | 23 | @Deprecated 24 | public static ConfigurationSection toNodeList(Map nodeMap) { 25 | return toConfigurationSection(nodeMap); 26 | } 27 | 28 | public static ConfigurationSection toConfigurationSection(Map nodeMap) { 29 | ConfigurationSection newSection = new MemoryConfiguration(); 30 | for (Map.Entry entry : nodeMap.entrySet()) { 31 | newSection.set(entry.getKey().toString(), entry.getValue()); 32 | } 33 | 34 | return newSection; 35 | } 36 | 37 | public static ConfigurationSection convertConfigurationSection(Map nodeMap) { 38 | ConfigurationSection newSection = new MemoryConfiguration(); 39 | for (Map.Entry entry : nodeMap.entrySet()) { 40 | set(newSection, entry.getKey().toString(), entry.getValue()); 41 | } 42 | 43 | return newSection; 44 | } 45 | 46 | public static ConfigurationSection toStringConfiguration(Map stringMap) { 47 | if (stringMap == null) return null; 48 | 49 | ConfigurationSection configMap = new MemoryConfiguration(); 50 | for (Map.Entry entry : stringMap.entrySet()) { 51 | configMap.set(entry.getKey(), entry.getValue()); 52 | } 53 | 54 | return configMap; 55 | } 56 | 57 | 58 | public static void set(ConfigurationSection node, String path, Object value) { 59 | if (value == null) { 60 | node.set(path, null); 61 | return; 62 | } 63 | 64 | boolean isTrue = value.equals("true"); 65 | boolean isFalse = value.equals("false"); 66 | if (isTrue || isFalse) { 67 | node.set(path, isTrue); 68 | return; 69 | } 70 | try { 71 | Integer i = (value instanceof Integer) ? (Integer) value : Integer.parseInt(value.toString()); 72 | node.set(path, i); 73 | } catch (Exception ex) { 74 | try { 75 | double d; 76 | if (value instanceof Double) d = (Double) value; 77 | else if (value instanceof Float) d = (double) (Float) value; 78 | else d = Double.parseDouble(value.toString()); 79 | node.set(path, d); 80 | } catch (Exception ex2) { 81 | node.set(path, value); 82 | } 83 | } 84 | } 85 | 86 | public static ConfigurationSection getConfigurationSection(ConfigurationSection base, String key) { 87 | ConfigurationSection section = base.getConfigurationSection(key); 88 | if (section != null) return section; 89 | 90 | Object value = base.get(key); 91 | if (value == null) return null; 92 | 93 | if (value instanceof ConfigurationSection) return (ConfigurationSection)value; 94 | 95 | if (value instanceof Map) { 96 | ConfigurationSection newChild = base.createSection(key); 97 | @SuppressWarnings("unchecked") 98 | Map map = (Map)value; 99 | for (Map.Entry entry : map.entrySet()) { 100 | newChild.set(entry.getKey(), entry.getValue()); 101 | } 102 | base.set(key, newChild); 103 | return newChild; 104 | } 105 | 106 | return null; 107 | } 108 | 109 | public static boolean isMaxValue(String stringValue) { 110 | return stringValue.equalsIgnoreCase("infinite") 111 | || stringValue.equalsIgnoreCase("forever") 112 | || stringValue.equalsIgnoreCase("infinity") 113 | || stringValue.equalsIgnoreCase("max"); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/util/Disposable.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.util; 2 | 3 | public interface Disposable { 4 | 5 | public void dispose(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/util/ImageLoadCallback.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.util; 2 | 3 | import java.awt.image.BufferedImage; 4 | 5 | public interface ImageLoadCallback { 6 | 7 | void loaded(final BufferedImage[] images); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/util/ImageLoadTask.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.util; 2 | 3 | import java.net.URL; 4 | import java.io.File; 5 | import java.io.InputStream; 6 | import java.net.URLEncoder; 7 | import java.io.OutputStream; 8 | import javax.imageio.ImageIO; 9 | import java.util.logging.Level; 10 | import java.io.FileOutputStream; 11 | import javax.imageio.ImageReader; 12 | import java.net.HttpURLConnection; 13 | import java.awt.image.BufferedImage; 14 | import javax.imageio.stream.ImageInputStream; 15 | 16 | import de.slikey.effectlib.EffectManager; 17 | 18 | public class ImageLoadTask implements Runnable { 19 | 20 | private static final int REQUEST_TIMEOUT = 30000; 21 | private static final int BUFFER_SIZE = 10 * 1024; 22 | private static boolean dirsMade = false; 23 | private final String fileName; 24 | private final ImageLoadCallback callback; 25 | private final EffectManager effectManager; 26 | 27 | public ImageLoadTask(EffectManager manager, String fileName, ImageLoadCallback callback) { 28 | this.fileName = fileName; 29 | this.callback = callback; 30 | this.effectManager = manager; 31 | } 32 | 33 | @Override 34 | public void run() { 35 | BufferedImage[] images; 36 | File imageFile; 37 | if (fileName.startsWith("http")) { 38 | try { 39 | File cacheFolder = effectManager.getImageCacheFolder(); 40 | if (cacheFolder == null) { 41 | // This should never really happen anymore, but leaving the check here just in case. 42 | effectManager.getLogger().log(Level.WARNING, "Can't load from URL because no cache folder has been set by the owning plugin: " + fileName); 43 | callback.loaded(new BufferedImage[0]); 44 | return; 45 | } 46 | 47 | if (!dirsMade) { 48 | dirsMade = true; 49 | if (!cacheFolder.exists() && !cacheFolder.mkdirs()) { 50 | effectManager.onError("Could not create cache folder: " + cacheFolder.getAbsolutePath()); 51 | } 52 | } 53 | 54 | String cacheFileName = URLEncoder.encode(fileName, "UTF-8"); 55 | imageFile = new File(cacheFolder, cacheFileName); 56 | if (!imageFile.exists()) { 57 | URL imageUrl = new URL(fileName); 58 | HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection(); 59 | conn.setConnectTimeout(REQUEST_TIMEOUT); 60 | conn.setReadTimeout(REQUEST_TIMEOUT); 61 | conn.setInstanceFollowRedirects(true); 62 | InputStream in = conn.getInputStream(); 63 | OutputStream out = new FileOutputStream(imageFile); 64 | byte[] buffer = new byte[BUFFER_SIZE]; 65 | int len; 66 | 67 | while ((len = in.read(buffer)) != -1) { 68 | out.write(buffer, 0, len); 69 | } 70 | out.close(); 71 | } 72 | } catch (Exception ex) { 73 | effectManager.getLogger().log(Level.WARNING, "Failed to load file " + fileName, ex); 74 | callback.loaded(new BufferedImage[0]); 75 | return; 76 | } 77 | } else if (!fileName.startsWith(File.pathSeparator)) { 78 | imageFile = new File(effectManager.getOwningPlugin().getDataFolder(), fileName); 79 | if (!imageFile.exists()) imageFile = new File(fileName); 80 | } else { 81 | imageFile = new File(fileName); 82 | } 83 | if (!imageFile.exists()) { 84 | effectManager.getLogger().log(Level.WARNING, "Failed to find file " + fileName); 85 | images = new BufferedImage[0]; 86 | callback.loaded(images); 87 | return; 88 | } 89 | try { 90 | if (fileName.endsWith(".gif")) { 91 | ImageReader reader = ImageIO.getImageReadersBySuffix("GIF").next(); 92 | ImageInputStream in = ImageIO.createImageInputStream(imageFile); 93 | reader.setInput(in); 94 | int numImages = reader.getNumImages(true); 95 | images = new BufferedImage[numImages]; 96 | for (int i = 0; i < numImages; i++) { 97 | images[i] = reader.read(i); 98 | } 99 | } else { 100 | images = new BufferedImage[1]; 101 | images[0] = ImageIO.read(imageFile); 102 | } 103 | } catch (Exception ex) { 104 | effectManager.getLogger().log(Level.WARNING, "Failed to load file " + fileName, ex); 105 | images = new BufferedImage[0]; 106 | } 107 | 108 | callback.loaded(images); 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/util/RandomUtils.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.util; 2 | 3 | import java.util.Random; 4 | import java.util.concurrent.ThreadLocalRandom; 5 | 6 | import org.bukkit.Material; 7 | import org.bukkit.util.Vector; 8 | 9 | public final class RandomUtils { 10 | 11 | public static final Random random = ThreadLocalRandom.current(); 12 | 13 | private RandomUtils() { 14 | // No instance allowed 15 | } 16 | 17 | public static Vector getRandomVector() { 18 | double u = random.nextDouble(); 19 | double v = random.nextDouble(); 20 | 21 | double theta = u * 2 * Math.PI; 22 | double phi = Math.acos(2 * v - 1); 23 | 24 | double sinTheta = Math.sin(theta); 25 | double cosTheta = Math.cos(theta); 26 | double sinPhi = Math.sin(phi); 27 | double cosPhi = Math.cos(phi); 28 | 29 | double x = sinPhi * cosTheta; 30 | double y = sinPhi * sinTheta; 31 | double z = cosPhi; 32 | 33 | // Going to take it on faith from the math gods that 34 | // this is always a normal vector 35 | return new Vector(x, y, z); 36 | } 37 | 38 | public static Vector getRandomFlatVector() { 39 | double x, z; 40 | x = random.nextDouble() * 2 - 1; 41 | z = random.nextDouble() * 2 - 1; 42 | 43 | return new Vector(x, 0, z); 44 | } 45 | 46 | public static Vector getRandomCircleVector() { 47 | double rnd, x, z; 48 | rnd = random.nextDouble() * 2 * Math.PI; 49 | x = Math.cos(rnd); 50 | z = Math.sin(rnd); 51 | 52 | return new Vector(x, 0, z); 53 | } 54 | 55 | public static Material getRandomMaterial(Material[] materials) { 56 | return materials[random.nextInt(materials.length)]; 57 | } 58 | 59 | public static double getRandomAngle() { 60 | return random.nextDouble() * 2 * Math.PI; 61 | } 62 | 63 | public static boolean checkProbability(double probability) { 64 | return probability >= 1 || random.nextDouble() < probability; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /EffectLib/src/main/java/de/slikey/effectlib/util/StringParser.java: -------------------------------------------------------------------------------- 1 | package de.slikey.effectlib.util; 2 | 3 | import java.awt.Font; 4 | import java.awt.Color; 5 | import java.awt.Graphics; 6 | import java.awt.FontMetrics; 7 | import java.awt.geom.Rectangle2D; 8 | import java.awt.image.BufferedImage; 9 | import java.awt.font.FontRenderContext; 10 | 11 | /** 12 | * Based on answer at StackOverflow 13 | * 14 | * @see ... 15 | * @author Kevin 16 | * 17 | */ 18 | public final class StringParser { 19 | 20 | private StringParser() { 21 | 22 | } 23 | 24 | public static BufferedImage stringToBufferedImage(Font font, String s) { 25 | BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR); 26 | Graphics g = img.getGraphics(); 27 | g.setFont(font); 28 | 29 | FontRenderContext frc = g.getFontMetrics().getFontRenderContext(); 30 | Rectangle2D rect = font.getStringBounds(s, frc); 31 | g.dispose(); 32 | 33 | img = new BufferedImage((int) Math.ceil(rect.getWidth()), (int) Math.ceil(rect.getHeight()), BufferedImage.TYPE_4BYTE_ABGR); 34 | g = img.getGraphics(); 35 | g.setColor(Color.black); 36 | g.setFont(font); 37 | 38 | FontMetrics fm = g.getFontMetrics(); 39 | int x = 0; 40 | int y = fm.getAscent(); 41 | 42 | g.drawString(s, x, y); 43 | g.dispose(); 44 | 45 | return img; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /EffectLib/src/main/resources/migrate.php: -------------------------------------------------------------------------------- 1 | \n"); 12 | } 13 | 14 | $inputFile = $argv[1]; 15 | $outputFile = $argv[2]; 16 | 17 | $effectTranslation = array( 18 | 'huge_explosion' => 'explosion_huge', 19 | 'large_explode' => 'explosion_large', 20 | 'bubble' => 'water_bubble', 21 | 'suspend' => 'suspended', 22 | 'depth_suspend' => 'suspended_depth', 23 | 'magic_crit' => 'crit_magic', 24 | 'smoke' => 'smoke_normal', 25 | 'mob_spell' => 'spell_mob', 26 | 'mob_spell_ambient' => 'spell_mob_ambient', 27 | 'instant_spell' => 'spell_instant', 28 | 'witch_magic' => 'spell_witch', 29 | 'explode' => 'explosion_normal', 30 | 'splash' => 'water_splash', 31 | 'wake' => 'water_wake', 32 | 'large_smoke' => 'smoke_large', 33 | 'red_dust' => 'redstone', 34 | 'snowball_poof' => 'snowball', 35 | 'angry_villager' => 'villager_angry', 36 | 'happy_villager' => 'villager_happy', 37 | 'droplet' => 'water_drop', 38 | 'take' => 'item_take', 39 | 'icon_crack' => 'item_crack', 40 | 'tile_crack' => 'block_dust', 41 | ); 42 | 43 | $contents = file_get_contents($inputFile); 44 | foreach ($effectTranslation as $from => $to) 45 | { 46 | $contents = str_replace($from, $to, $contents); 47 | } 48 | 49 | file_put_contents($outputFile, $contents); -------------------------------------------------------------------------------- /EffectLib/src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: EffectLib 2 | main: de.slikey.effectlib.EffectLib 3 | version: ${project.version} 4 | description: This library supports other plugins to perform cool effects. 5 | author: Slikey 6 | website: http://www.kevin-carstens.de/ 7 | prefix: Effect Library 8 | load: POSTWORLD 9 | database: false 10 | api-version: 1.13 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Slikey 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | EffectLib - Manage your effects the nice way. 2 | ========= 3 | 4 | You have no idea what a vector or matrix is, but you want to give your users some nice effects with particles? No problem. This library comes with a load of effects for you. It handles rotation, text-parsing, and creation of 3D objects with particles in Minecraft. 5 | 6 | - Text-Parsing 7 | - 3D cubes, spheres, stars and others 8 | - 2D arcs, lines and many more! 9 | - Entity effects that enhance every game 10 | 11 | Find more information on [BukkitForums] [forum] or [BukkitDev] [dev]! 12 | 13 | Check out this plugin to demo all the effects: 14 | 15 | https://github.com/u9g/effectlib-visualizer 16 | 17 | Note that **this library** is no standalone plugin! You have to **create yourself a plugin** to run the effects! 18 | 19 | See here: https://github.com/elBukkit/EffectLibDemo 20 | for a full working example. 21 | 22 | # How to Shade 23 | 24 | It is recommended to shade this plugin into yours. This way, users of your plugin do not need to install EffectLib separately. 25 | 26 | This easy to do with Maven. First, add the elMakers repository: 27 | 28 | ``` 29 | 30 | 31 | Maven Central 32 | https://repo1.maven.org/maven2/ 33 | 34 | 35 | 36 | elMakers 37 | http://maven.elmakers.com/repository/ 38 | 39 | 40 | ``` 41 | 42 | Then, add the EffectLib dependency: 43 | 44 | ``` 45 | 46 | com.elmakers.mine.bukkit 47 | EffectLib 48 | 10.2 49 | compile 50 | 51 | 52 | ``` 53 | 54 | Note the "compile" scope! 55 | 56 | Finally, add the Maven shade plugin: 57 | 58 | ``` 59 | 60 | 61 | org.apache.maven.plugins 62 | maven-shade-plugin 63 | 3.8.1 64 | 65 | false 66 | ${project.build.directory}/dependency-reduced-pom.xml 67 | 68 | 69 | 70 | de.slikey 71 | my.own.plugin.namespace.slikey 72 | 73 | 74 | 75 | 76 | com.elmakers.mine.bukkit:EffectLib 77 | 78 | plugin.yml 79 | META-INF/MANIFEST.MF 80 | 81 | 82 | 83 | 84 | 85 | 86 | package 87 | 88 | shade 89 | 90 | 91 | 92 | 93 | 94 | ``` 95 | 96 | Make sure to change the "shadedPattern" to match the base package of your own plugin! 97 | 98 | # Gradle 99 | 100 | To use EffectLib via gradle just add 101 | 102 | ``` 103 | implementation 'com.elmakers.mine.bukkit:EffectLib:10.2' 104 | ``` 105 | 106 | To your build.gradle file, remember to change version to the latest version, you can find the latest version in the maven area above. 107 | 108 | 109 | # Support 110 | 111 | Come visit the Magic Discord if you'd like EffectLib help: https://discord.gg/fWJ3W3kMjG 112 | 113 | # License 114 | 115 | MIT 116 | 117 | **Free Software, Hell Yeah!** 118 | 119 | [dev]:http://dev.bukkit.org/bukkit-plugins/effectlib/ 120 | [forum]:http://forums.bukkit.org/threads/effectlib-manage-your-effects-the-nice-way-text-in-particles.259879/ 121 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # TODO 2 | 3 | * Player exclusion list, or player preference to disable effects 4 | * Async URL/File loading for image effects 5 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 4.0.0 5 | com.elmakers.mine.bukkit 6 | EffectLib-parent 7 | 10.11-SNAPSHOT 8 | 9 | EffectLib-parent 10 | A multi-module container for EffectLib compatibility 11 | 12 | pom 13 | 14 | 15 | Compatibility 16 | EffectLib 17 | 18 | 19 | 20 | UTF-8 21 | 22 | 23 | 24 | 25 | spigot-repo 26 | https://hub.spigotmc.org/nexus/content/repositories/snapshots/ 27 | 28 | 29 | 30 | 31 | --------------------------------------------------------------------------------