diff --git a/src/main/java/me/xemor/skillslibrary2/effects/ArrowEffect.java b/src/main/java/me/xemor/skillslibrary2/effects/ArrowEffect.java index 4203fa0..983e4e2 100644 --- a/src/main/java/me/xemor/skillslibrary2/effects/ArrowEffect.java +++ b/src/main/java/me/xemor/skillslibrary2/effects/ArrowEffect.java @@ -11,7 +11,7 @@ public class ArrowEffect extends Effect implements TargetEffect { private final double velocity; private final int damage; - private final EntityType entityType; + private final EntityData entityData; private final int fireTicks; private static final double log099 = Math.log(0.99); @@ -19,7 +19,9 @@ public ArrowEffect(int effect, ConfigurationSection configurationSection) { super(effect, configurationSection); velocity = configurationSection.getDouble("velocity", 1.0); damage = configurationSection.getInt("damage", 4); - entityType = EntityType.valueOf(configurationSection.getString("entity", "arrow").toUpperCase()); + + ConfigurationSection entitySection = configurationSection.getConfigurationSection("entity"); + this.entityData = entitySection != null ? new EntityData(entitySection) : new EntityData(); fireTicks = configurationSection.getInt("fireTicks", 0); } @@ -40,7 +42,7 @@ public boolean useEffect(Entity entity, Entity target) { double initialXVelocity = solveForInitialHorizontalVelocity(xDifference, time); double initialZVelocity = solveForInitialHorizontalVelocity(zDifference, time); Vector vector = new Vector(initialXVelocity, initialYVelocity, initialZVelocity); - Entity spawnedEntity = world.spawnEntity(startPoint, entityType); + Entity spawnedEntity = entityData.createEntity(world, startPoint); if (spawnedEntity instanceof Arrow arrow) { arrow.setPickupStatus(AbstractArrow.PickupStatus.DISALLOWED); arrow.setDamage(damage); diff --git a/src/main/java/me/xemor/skillslibrary2/effects/Effects.java b/src/main/java/me/xemor/skillslibrary2/effects/Effects.java index c07d275..2d4ddf1 100644 --- a/src/main/java/me/xemor/skillslibrary2/effects/Effects.java +++ b/src/main/java/me/xemor/skillslibrary2/effects/Effects.java @@ -70,6 +70,7 @@ public class Effects { registerEffect("FLY", FlyEffect.class); registerEffect("FLYING", FlyEffect.class); registerEffect("FURNACEBURNTIME", FurnaceBurnTimeEffect.class); + registerEffect("PARTICLE", ParticleEffect.class); } public static void registerEffect(String name, Class effectDataClass) { diff --git a/src/main/java/me/xemor/skillslibrary2/effects/LaunchEffect.java b/src/main/java/me/xemor/skillslibrary2/effects/LaunchEffect.java index 9faaf0e..dd9dc6b 100644 --- a/src/main/java/me/xemor/skillslibrary2/effects/LaunchEffect.java +++ b/src/main/java/me/xemor/skillslibrary2/effects/LaunchEffect.java @@ -1,21 +1,23 @@ package me.xemor.skillslibrary2.effects; +import me.xemor.configurationdata.entity.EntityData; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.util.Vector; public class LaunchEffect extends Effect implements EntityEffect, TargetEffect { - private final EntityType entityType; + private final EntityData entityData; private final double velocity; public LaunchEffect(int effect, ConfigurationSection configurationSection) { super(effect, configurationSection); - this.entityType = EntityType.valueOf(configurationSection.getString("entity", "FIREBALL")); + + ConfigurationSection entitySection = configurationSection.getConfigurationSection("entity"); + this.entityData = entitySection != null ? new EntityData(entitySection) : new EntityData(); this.velocity = configurationSection.getDouble("velocity", 1.0); } @@ -30,7 +32,7 @@ public boolean useEffect(Entity entity, Entity target) { } Vector direction = target.getLocation().subtract(entityLocation).toVector().normalize(); Location spawnLocation = entityLocation.clone().add(direction); - Entity projectile = world.spawnEntity(spawnLocation, entityType); + Entity projectile = entityData.createEntity(world, spawnLocation); projectile.setVelocity(direction.multiply(velocity)); return false; } @@ -47,7 +49,7 @@ public boolean useEffect(Entity entity) { direction = entity.getLocation().getDirection(); spawnLocation = entity.getLocation().clone().add(direction); } - Entity projectile = world.spawnEntity(spawnLocation, entityType); + Entity projectile = entityData.createEntity(world, spawnLocation); projectile.setVelocity(direction.multiply(velocity)); return false; } diff --git a/src/main/java/me/xemor/skillslibrary2/effects/ParticleEffect.java b/src/main/java/me/xemor/skillslibrary2/effects/ParticleEffect.java new file mode 100644 index 0000000..81c4424 --- /dev/null +++ b/src/main/java/me/xemor/skillslibrary2/effects/ParticleEffect.java @@ -0,0 +1,116 @@ +package me.xemor.skillslibrary2.effects; + +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.World; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Entity; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; + +public class ParticleEffect extends Effect implements EntityEffect, LocationEffect, TargetEffect { + + private final Particle particle; + private final ParticleShape shape; + private final int count; + private final double offsetX; + private final double offsetY; + private final double offsetZ; + private final double extra; + private final boolean force; + + public ParticleEffect(int effect, ConfigurationSection configurationSection) { + super(effect, configurationSection); + particle = Particle.valueOf(configurationSection.getString("particle", "END_ROD").toUpperCase()); + shape = ParticleShape.valueOf(configurationSection.getString("shape", "SINGLE").toUpperCase()); + count = configurationSection.getInt("count", 1); + offsetX = configurationSection.getDouble("offsetX", 0.0); + offsetY = configurationSection.getDouble("offsetY", 0.0); + offsetZ = configurationSection.getDouble("offsetZ", 0.0); + extra = configurationSection.getDouble("extra", 0.0); + force = configurationSection.getBoolean("force"); + } + + @Override + public boolean useEffect(Entity entity) { + spawnParticle(entity.getWorld(), entity.getLocation()); + return true; + } + + @Override + public boolean useEffect(Entity entity, Location location) { + spawnParticle(entity.getWorld(), location, entity.getLocation()); + return false; + } + + @Override + public boolean useEffect(Entity entity, Entity target) { + spawnParticle(entity.getWorld(), target.getLocation(), entity.getLocation()); + return false; + } + + public void spawnParticle(@NotNull World world, @NotNull Location location, Location... locations) { + switch(shape) { + case SINGLE -> { + world.spawnParticle(particle, location, count, offsetX, offsetY, offsetZ, extra, null, force); + } + case LINE -> { + Location fromLocation = location.clone(); + Location toLocation = locations.length > 0 ? locations[locations.length - 1] : location; + Vector vector = toLocation.toVector().subtract(location.toVector()); + + for (double i = 1; i <= fromLocation.distance(toLocation); i += 0.5) { + vector.multiply(i); + fromLocation.add(vector); + world.spawnParticle(particle, fromLocation, count, offsetX, offsetY, offsetZ, extra, null, force); + fromLocation.subtract(vector); + vector.normalize(); + } + } + case BLOCK_FACE -> { + double minX = location.getBlockX(); + double minZ = location.getBlockZ(); + double maxX = location.getBlockX() + 1; + double maxZ = location.getBlockZ() + 1; + + for (double x = minX; x <= maxX; x += 0.05) { + for (double z = minZ; z <= maxZ; z += 0.05) { + if (x == minX || x >= maxX - 0.05 || z == minZ || z >= maxZ - 0.05) { + world.spawnParticle(particle, new Location(world, x, location.getBlockY(), z), count, offsetX, offsetY, offsetZ, extra, null, force); + } + } + } + } + case BLOCK -> { + double minX = location.getBlockX(); + double minY = location.getBlockY(); + double minZ = location.getBlockZ(); + double maxX = location.getBlockX() + 1; + double maxY = location.getBlockY() + 1; + double maxZ = location.getBlockZ() + 1; + + for (double x = minX; x <= maxX; x += 0.05) { + for (double y = minY; y <= maxY; y += 0.05) { + for (double z = minZ; z <= maxZ; z += 0.05) { + int successes = 0; + if (x == minX || x >= maxX - 0.05) successes++; + if (y == minY || y >= maxY - 0.05) successes++; + if (z == minZ || z >= maxZ - 0.05) successes++; + + if (successes >= 2) { + world.spawnParticle(particle, new Location(world, x, y, z), count, offsetX, offsetY, offsetZ, extra, null, force); + } + } + } + } + } + } + } + + public enum ParticleShape { + SINGLE, + LINE, + BLOCK_FACE, + BLOCK + } +}