Homing Projectiles

Discussion in 'Plugin Development' started by Gosintary, Apr 1, 2020.

Thread Status:
Not open for further replies.
  1. Offline

    Gosintary

    Hello!

    I'm working on a plugin for a friend's server, and I was wondering what you guys think the most effective way to create a homing projectile is.

    So far I have a plugin the shoots a fire charge when the player right-clicks with a firework in hand. I have a cool-down set up for it, and custom damage for the fire-charge.

    I'm looking for the best way to locate and track the nearest player for 5 seconds.
    When the player shoots this missile, it should find the closest player, move towards the player, following his movements, and hit the player OR explode after 5 seconds. What would yall recommend?
     
  2. Offline

    NukerFall

    i got my own homing proj plugin, you can edit it and use for yourself


    Code:
    public void onBowShoot(EntitySpawnEvent event) {
            if (event.getEntityType().equals(EntityType.ARROW)) {
                Arrow arrow = (Arrow) event.getEntity();
                if (arrow.getShooter() instanceof Player) {
                    Player shooter = (Player) arrow.getShooter();
                    entities = (List<Entity>) shooter.getWorld().getNearbyEntities(shooter.getLocation(), 32, 32, 32);
                    if (ArrowPhysics.getTarget(shooter, entities) != null) {
                        Entity target = ArrowPhysics.getTarget(shooter, entities);
                        Arrows.addArrow(arrow);
                        BukkitRunnable r = new BukkitRunnable() {
                            public void run() {
                                if (Arrows.getArrows().contains(arrow)) {
                                    ArrowPhysics.addForce(arrow, target);
                                } else {
                                    if (!this.isCancelled()) {
                                        this.cancel();
                                    }
                                }
                            }
                        };
                        r.runTaskTimerAsynchronously(main, 0L, main.getConfig().getInt("Mechanics.arrow-calc-time")*1L);
                    }
                }
            }
        }
    

    Code:
    public void onArrowHit(ProjectileHitEvent event) {
            if (event.getEntityType().equals(EntityType.ARROW)) {
                Arrow arrow = (Arrow) event.getEntity();
                if (arrow.getShooter() instanceof Player) {
                    Arrows.removeArrow(arrow);
                }
            }
        }


    ArrowPhysics class
    Code:
    public static Entity getTarget(Player shooter, List<Entity> entities) {
            Entity target = null;
            for (Entity e : entities) {
                Vector n = e.getLocation().toVector().subtract(shooter.getLocation().toVector());
                if (shooter.getLocation().getDirection().normalize().crossProduct(n).lengthSquared() < 1.0 && n.normalize().dot(shooter.getLocation().getDirection().normalize()) >= 0) {
                    if (target == null || target.getLocation().distanceSquared(shooter.getLocation()) > e.getLocation().distanceSquared(shooter.getLocation())) {
                        target = e;
                        break;
                    }
                }
            }
            return target;
        }
    
        public static void addForce(Arrow arrow, Entity target) {
                Vector v = target.getLocation().add(0.0, target.getHeight()/2, 0.0).toVector().subtract(arrow.getLocation().toVector()).normalize();
                arrow.setVelocity(v.multiply(main.getConfig().getDouble(("Mechanics.arrow-multiplier"))));
                arrow.getLocation().setDirection(v);
        }
    }
     
Thread Status:
Not open for further replies.

Share This Page