LoginSignup
2
0

More than 1 year has passed since last update.

クリスマスに向けてリア充を逃がさず爆破する弓を作る

Posted at

もうすぐクリスマスな時期になりましたね!リア充がわきますね!目障りなリア充は爆破してしまいましょう。逃げられても大丈夫なように矢を追尾させ、確実に〇れるようにしてしまいましょう。

動作環境

php 8.0以降
PMMP4.0.0

仕様

弓を放った際に一番近いエンティティを取得し、それに向けて弓の進行方向を変えます。
また、着弾時に爆発するようにします。
実装方法は矢のクラスをオーバーライドする方法で行きます。

ソースコード

<?php
namespace riajyu;
use pocketmine\entity\projectile\Arrow;
use pocketmine\entity\{
    Entity,
    Living,
    Location
};
use pocketmine\world\World;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\world\Explosion;
use pocketmine\event\entity\ProjectileHitEvent;
use pocketmine\world\sound\ArrowHitSound;

final class HomingMissileArrow extends Arrow{
    protected $gravity = 0;
    protected $damage = 3.0;
    protected $punchKnockback = 2.0;
    private $shooter;
    private $level;


    public function __construct(Location $location, ?CompoundTag $nbt = null, ?Entity $entity = null, bool $critical = false , ?World $level = null){
        parent::__construct(
            $location,
            $entity,
            $critical,
            $nbt
        );
        if($entity === null) return;
        //$this->setMotion($entity->getDirectionVector()->normalize()->multiply(0.2));
        $this->shooter = $entity;
        $this->level = $level;
    }

    public function entityBaseTick(int $tick = 1):bool{
      $newTarget = $this->level->getNearestEntity($this->getLocation(), 50.0, Living::class);
          if($newTarget instanceof Living){
            if($this->shooter === null){
          $currentTarget = null;
        }else{
              if($this->shooter->getId() !== $newTarget->getId()){
            $currentTarget = $newTarget;
          }else{
            $currentTarget = null;
          }
        }
      }else{
            $currentTarget = null;
          }

      if($currentTarget !== null){
        $vector = $currentTarget->getPosition()->add(0, $currentTarget->getEyeHeight() / 2, 0)->subtract($this->getLocation()->getX(),$this->getLocation()->getY(),$this->getLocation()->getZ())->divide(75.0);

        $distance = $vector->lengthSquared();
        if($distance < 1){
          $diff = $vector->normalize()->multiply(5 * (1 - sqrt($distance)) ** 2);
          $this->motion->x += $diff->x;
          $this->motion->y += $diff->y;
          $this->motion->z += $diff->z;
        }
      }
        if($this->closed){
            return false;
        }

        $hasUpdate = parent::entityBaseTick($tick);

        if($this->blockHit !== null){
            $this->collideTicks += $tick;
            if($this->collideTicks > 1200){
                $this->flagForDespawn();
                $hasUpdate = true;
            }
        }else{
            $this->collideTicks = 0;
        }

        return $hasUpdate;
    }

    protected function onHit(ProjectileHitEvent $event) : void{
        $this->setCritical(false);
        $this->broadcastSound(new ArrowHitSound());
        $explosion = new Explosion($event->getEntity()->location->asLocation(), 3);
        $explosion->explodeB();
    }
}

以上です。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0