2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Minecraftサーバ開発・運営Advent Calendar 2021

Day 23

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

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?