Skip to content

Instantly share code, notes, and snippets.

@Kage0x3B
Last active April 18, 2017 17:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kage0x3B/969bef40a3cbe2fecb692deeb157eb89 to your computer and use it in GitHub Desktop.
Save Kage0x3B/969bef40a3cbe2fecb692deeb157eb89 to your computer and use it in GitHub Desktop.
A spigot plugin adding "spells"/projectiles shot from the bow which target the entity you are looking at (almost). Download the plugin at https://syscy.de/downloads/SpellTest.jar
package de.syscy.spelltest;
import java.util.Collection;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityShootBowEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import lombok.RequiredArgsConstructor;
public class SpellTestPlugin extends JavaPlugin implements Listener {
private static final double MAX_TARGET_DISTANCE = 100;
private static final double TARGET_SEARCH_RADIUS = 10;
@Override
public void onEnable() {
getServer().getPluginManager().registerEvents(this, this);
}
@EventHandler
public void onBowShoot(EntityShootBowEvent event) {
if(event.getEntity() instanceof Player) {
Player shooter = (Player) event.getEntity();
event.setCancelled(true);
double targetSearchDistance = MAX_TARGET_DISTANCE * event.getForce();
Vector playerDirection = shooter.getLocation().getDirection();
playerDirection.normalize().multiply(targetSearchDistance);
Location searchLocation = shooter.getLocation().clone().add(playerDirection.normalize().multiply(targetSearchDistance));
Collection<Entity> targets = searchLocation.getWorld().getNearbyEntities(searchLocation, TARGET_SEARCH_RADIUS, TARGET_SEARCH_RADIUS, TARGET_SEARCH_RADIUS);
LivingEntity finalTarget = null;
for(Entity target : targets) {
if(target instanceof LivingEntity) {
finalTarget = (LivingEntity) target;
break;
}
}
getLogger().info("target: " + finalTarget);
if(finalTarget != null) {
SpellRunnable spellRunnable = new SpellRunnable(event.getEntity(), finalTarget, event.getForce());
spellRunnable.runTaskTimer(this, 0, 1);
}
}
}
@RequiredArgsConstructor
private static class SpellRunnable extends BukkitRunnable {
private static final Vector TARGET_LOCATION_OFFSET = new Vector(0.5, 0.5, 0.5);
private final World world;
private final LivingEntity target;
private final double speed;
private final Vector start;
private Vector end;
private double time;
public SpellRunnable(LivingEntity caster, LivingEntity target, float bowForce) {
world = target.getWorld();
this.target = target;
start = caster.getEyeLocation().toVector();
caster.getLocation().distanceSquared(target.getLocation());
speed = 0.02 * Math.min(1.0, 1.0 - bowForce + 0.1);
}
@Override
public void run() {
if(time >= 1) {
// target.damage(2.0, caster);
// target.setFireTicks(200);
end = target.getLocation().toVector().add(TARGET_LOCATION_OFFSET);
world.createExplosion(end.getX(), end.getY(), end.getZ(), 10.0f, true, true);
cancel();
return;
}
end = target.getLocation().toVector().add(TARGET_LOCATION_OFFSET);
Vector currentLocation = findPointOnLineBetweenPoints(start, end, time);
world.spawnParticle(Particle.FLAME, currentLocation.toLocation(world), 100, 0.1, 0.1, 0.1);
time += speed;
}
private Vector findPointOnLineBetweenPoints(Vector p1, Vector p2, double t) {
double x = (1.0 - t) * p1.getX() + t * p2.getX();
double y = (1.0 - t) * p1.getY() + t * p2.getY();
double z = (1.0 - t) * p1.getZ() + t * p2.getZ();
return new Vector(x, y, z);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment