*/ public array $projectileColor; protected float $fireTimer = 0.0; public function __construct( float $x, float $y, EntityList $container, Room $room, ?Player $initialTarget, array $config = [], ?callable $onDeath = null, ) { parent::__construct($x, $y, $container, $room, $config, $onDeath); if ($initialTarget !== null) { $this->target = $initialTarget; } $this->preferredDistance = $config['preferredDistance'] ?? 220.0; $this->fireInterval = $config['fireInterval'] ?? 2.2; $this->projectileSpeed = $config['projectileSpeed'] ?? 220.0; $this->projectileCount = $config['projectileCount'] ?? 1; $this->projectileSpread = $config['projectileSpread'] ?? 0.08; $this->projectileColor = $config['projectileColor'] ?? [0.7, 0.2, 1.0, 1.0]; } public function kind(): string { return 'witch'; } public function update(float $dt): void { $this->time += $dt; if ($this->updateEmerge($dt)) { return; } $this->fireTimer -= $dt; $target = $this->target; if ($target === null) { return; } $delta = $target->pos->subV($this->pos); $distance = $delta->length(); $move = Vector2::zero(); if ($distance > 1.0) { $dir = $delta->divS($distance); if ($distance < $this->preferredDistance) { $move = $dir->mulS(-$this->speed); } elseif ($distance > $this->preferredDistance + 40.0) { $move = $dir->mulS($this->speed); } } $this->velocity = $move->addV($this->hitKnockback); $this->move($dt); $this->hitKnockback = $this->hitKnockback->mulS(max(0.0, 1 - $dt * $this->knockbackDamping)); $this->flash = max(0.0, $this->flash - $dt); if ($this->fireTimer <= 0.0 && ! $target->dead && $distance < 480.0) { $this->fireTimer = $this->fireInterval * (0.8 + $this->rand01() * 0.4); $this->fire(); } } protected function onEmergeComplete(): void { $this->fireTimer = $this->fireInterval * (0.4 + $this->rand01() * 0.4); } public function fire(): void { $target = $this->target; if ($target === null) { return; } $aim = $target->pos->subV($this->pos); $aimAngle = $aim->lengthSquared() > 1.0 ? atan2($aim->y, $aim->x) : $this->time; $offset = (($this->projectileCount - 1) / 2.0) * $this->projectileSpread; for ($i = 0; $i < $this->projectileCount; $i++) { $angle = $aimAngle - $offset + $i * $this->projectileSpread; $direction = new Vector2(cos($angle), sin($angle)); $this->container->append(new WitchProjectile( $this->pos->x, $this->pos->y, $direction, $this->container, $this->room, $this->projectileSpeed, $this->size * 0.4, $this->projectileColor, )); } } }