Lines 81.25% 13 / 16
Functions and Methods 66.66% 2 / 3
Classes and Traits 0.00% 0 / 1
Name Lines Functions and Methods CRAP Classes and Traits
QuestMarkedEvent 81.25% 13 / 16 66.66% 2 / 3 7.32 0.00% 0 / 1
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 from 78.57% 11 / 14 0.00% 0 / 1 5.25
 summary 100.00% 1 / 1 100.00% 1 / 1 1
1<?php
2
3declare(strict_types=1);
4
5namespace Lorekeeper\Server\Event\Quest;
6
7use Lorekeeper\Core\World\Quest\QuestMark;
8use Lorekeeper\Server\Event\Event;
9use Lorekeeper\Server\Event\NamedAfterClass;
10use Lorekeeper\Server\Event\Quest\Helper\QuestMarks;
11use Lorekeeper\Server\Exception\MalformedEventException;
12use Lorekeeper\Server\Message\JsonMessage;
13use Lorekeeper\Server\Message\Message;
14use Override;
15use Psl\Option;
16use Psl\Type;
17use Psl\Type\Exception\CoercionException;
18
19final readonly class QuestMarkedEvent implements Event
20{
21    use NamedAfterClass;
22
23    public function __construct(
24        public QuestMark $mark,
25    ) {}
26
27    /** @return Option\Option<static> */
28    #[Override]
29    public static function from(Message $message): Option\Option
30    {
31        if (!$message instanceof JsonMessage || ($message->data['cmd'] ?? null) !== 'setAchievement') {
32            return Option\none();
33        }
34
35        try {
36            $achievement = Type\shape([
37                'field' => Type\string(),
38                'index' => Type\uint(),
39                'value' => Type\int(),
40            ], allowUnknownFields: true)->coerce($message->data);
41        } catch (CoercionException $exception) {
42            throw new MalformedEventException(static::class, 'achievement is invalid', $exception);
43        }
44
45        if ($achievement['value'] !== 1) {
46            return Option\none();
47        }
48
49        return QuestMarks::of($achievement['field'], $achievement['index'])->map(
50            static fn(QuestMark $mark): static => new static($mark),
51        );
52    }
53
54    #[Override]
55    public function summary(): string
56    {
57        return "Marked {$this->mark->period->name} quest {$this->mark->group}:{$this->mark->index}";
58    }
59}