Lines 93.33% 14 / 15
Methods 80.00% 4 / 5
Classes 0.00% 0 / 1
Name Lines Methods CRAP
 __construct 100.00% 2 / 2 100.00% 1 / 1 2
 target 100.00% 1 / 1 100.00% 1 / 1 1
 with 100.00% 1 / 1 100.00% 1 / 1 1
 at 100.00% 3 / 3 100.00% 1 / 1 2
 toMessage 87.50% 7 / 8 0.00% 0 / 1 7.10
14final readonly class AttackMonsterCommand implements Attack
15{
16    /** @throws InvalidArgumentException */
17    public function __construct(
18        private AreaId $area,
19        private SkillSlot $skill,
20        private MonsterSpawnId $monster,
21    ) {
22        if ($skill === SkillSlot::Potion) {
23            throw new InvalidArgumentException('A potion is not an attack.');
24        }
25    }
26
27    #[Override]
28    public function target(): MonsterSpawnId
29    {
30        return $this->monster;
31    }
32
33    #[Override]
34    public function with(SkillSlot $skill): static
35    {
36        return new static($this->area, $skill, $this->monster);
37    }
38
39    #[Override]
40    public function at(Targetable $target): static
41    {
42        if (!$target instanceof MonsterSpawnId) {
43            throw new InvalidArgumentException('A monster attack can only aim at a monster.');
44        }
45
46        return new static($this->area, $this->skill, $target);
47    }
48
49    #[Override]
50    public function toMessage(): string
51    {
52        $skill = match ($this->skill) {
53            SkillSlot::AutoAttack => 'aa',
54            SkillSlot::First => 'a1',
55            SkillSlot::Second => 'a2',
56            SkillSlot::Third => 'a3',
57            SkillSlot::Fourth => 'a4',
58            SkillSlot::Potion => 'i1',
59        };
60
61        return "%xt%zm%gar%{$this->area}%0%{$skill}>m:{$this->monster}%wvz%";
62    }
63}