Homingarrow作成のヒントを募集してます

Modding・サーバPlugin制作・ツール制作など、開発関連の質問があればこちらにお願い致します。
フォーラムルール
質問関連フォーラムで質問する時は、必ず次のトピックを一読/厳守お願い致します。
viewtopic.php?f=5&t=999
  • (PostNo.287885)

Homingarrow作成のヒントを募集してます

投稿記事by ONP » 2016年11月16日(水) 05:06

spigot-1.8.8.jar
他導入plugins
Mutiverse
WorldEdit



現在指定したtargetを自動で追尾するような弓を作ろうとしており
公開されているソースなどから次のように組むことが出来
無事曲がることに成功したのですが現在の仕様として
矢の半径10マスに存在するEntitymobをTargetとする仕様なのですが
矢を発射した段階での判断なので実質的に自分の半径10マスにいるmobをtargetとしているのです
理想としては途中までは通常通り矢の軌道を描き、その軌道上の半径10マス以内のmobをtargetしたいのです。

なんだかまどろっころしくなりましたが簡潔に言えば飛んでる途中でTargetを決めたいということです
どなたか案などありますかね?


コード: 全て選択
package com.homing;

import org.bukkit.entity.Arrow;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
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.util.Vector;

public class Homingarrow
  extends JavaPlugin
  implements Listener
{
  public void onEnable()
  {
    getLogger().info("BlingGravity has been loaded.");
    getServer().getPluginManager().registerEvents(this, this);
  }

  public void onDisable()
  {
    getLogger().info("BlingGravity has been unloaded.");
  }

  @EventHandler
  public void eventArrowFired(EntityShootBowEvent e)
  {
    if (((e.getEntity() instanceof LivingEntity)) && ((e.getProjectile() instanceof Arrow)))
    {
      LivingEntity player = e.getEntity();

      double minAngle = 12.0D;
      Entity minEntity = null;
      for (Entity entity :  e.getProjectile().getNearbyEntities(10.0D, 10.0D, 10.0D)) {
        if ((entity instanceof LivingEntity) && (!entity.isDead()))
        {
          Vector toTarget = entity.getLocation().toVector().clone().subtract(player.getLocation().toVector());
          double angle = e.getProjectile().getVelocity().angle(toTarget);
          if (angle < minAngle)
          {
            minAngle = angle;
            minEntity = entity;
          }
        }
      }
      if (minEntity != null) {
        new HomingTask((Arrow)e.getProjectile(), (LivingEntity)minEntity, this);
      }
    }
  }
}

コード: 全て選択
package com.homing;

import org.bukkit.Effect;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;

public class HomingTask
  extends BukkitRunnable
{
  private static final double MaxRotationAngle = 0.12D;
  private static final double TargetSpeed = 1.4D;
  Arrow arrow;
  LivingEntity target;

  public HomingTask(Arrow arrow, LivingEntity target, Plugin plugin)
  {
    this.arrow = arrow;
    this.target = target;
    runTaskTimer(plugin, 1L, 1L);
  }

  public void run()
  {
    double speed = this.arrow.getVelocity().length();
    if ((this.arrow.isOnGround()) || (this.arrow.isDead()) || (this.target.isDead()))
    {
      cancel();
      return;
    }
    Vector toTarget = this.target.getLocation().clone().add(new Vector(0.0D, 0.5D, 0.0D)).subtract(this.arrow.getLocation()).toVector();

    Vector dirVelocity = this.arrow.getVelocity().clone().normalize();
    Vector dirToTarget = toTarget.clone().normalize();
    double angle = dirVelocity.angle(dirToTarget);

    double newSpeed = 0.9D * speed + 0.13999999999999999D;
    if (((this.target instanceof Player)) && (this.arrow.getLocation().distance(this.target.getLocation()) < 8.0D))
    {
      Player player = (Player)this.target;
      if (player.isBlocking()) {
        newSpeed = speed * 0.6D;
      }
    }
    Vector newVelocity;
    if (angle < 0.12D)
    {
      newVelocity = dirVelocity.clone().multiply(newSpeed);
    }
    else
    {
      Vector newDir = dirVelocity.clone().multiply((angle - 0.12D) / angle).add(dirToTarget.clone().multiply(0.12D / angle));
      newDir.normalize();
      newVelocity = newDir.clone().multiply(newSpeed);
    }
    this.arrow.setVelocity(newVelocity.add(new Vector(0.0D, 0.03D, 0.0D)));
    this.arrow.getWorld().playEffect(this.arrow.getLocation(), Effect.SMOKE, 0);
  }
}
ONP
ID:afe9835b
石掘り
 
記事: 131
登録日時: 2015年8月12日(水) 22:45

  • (PostNo.287886)

Re: Homingarrow作成のヒントを募集してます

投稿記事by ONP » 2016年11月16日(水) 05:13

わかりにくいですが図を作りました

矢印が矢の軌道
丸数字がTargetにしたいEntityです

1のように手前にTargetがいる場合は1の半径10マス以内に近づいたら軌道修正を始める

3のように奥にしかTargetがいない場合は3の半径10マス以内に近づいたら軌道修正を始める


このようなイメージでお願いします

矢の軌道の半径10マスに最初に入ったEntityにTargetをするということです
添付ファイル
hominh.png
ONP
ID:afe9835b
石掘り
 
記事: 131
登録日時: 2015年8月12日(水) 22:45

  • (PostNo.287909)

Re: Homingarrow作成のヒントを募集してます

投稿記事by Lemon18 » 2016年11月16日(水) 16:16

EntityShootBowEventからBukkitRunnableで、毎tickごとに、イベントから取得した矢からEntity#getNearbyEntities(double, double, double)で矢の半径nメートルからEntityを取得し、そのEntityの場所にVelocityを設定してあげれば良いのではないでしょうか。そうすれば、対象が見つからない場合は、自然に矢が飛んでいきます。
Bukkitプラグインとか作ったり作らなかったり。
「どのOSでも使える」を目標に日本語入力ツールを作っています。良ければ見てください。
http://forum.minecraftuser.jp/viewtopic.php?f=36&t=31671


Twitter: https://twitter.com/Lemon1806
Minecraft: Applemon
Lemon18
ID:b66be5f3
石掘り
 
記事: 80
登録日時: 2015年6月05日(金) 22:42


Return to 質問:開発・制作関連

x