Lines 100.00% 21 / 21
Functions and Methods 100.00% 4 / 4
Classes and Traits 100.00% 1 / 1
Name Lines Functions and Methods CRAP Classes and Traits
MovedToMapEvent 100.00% 21 / 21 100.00% 4 / 4 8 100.00% 1 / 1
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 summary 100.00% 1 / 1 100.00% 1 / 1 1
 read 100.00% 14 / 14 100.00% 1 / 1 2
 room 100.00% 5 / 5 100.00% 1 / 1 4
1<?php
2
3declare(strict_types=1);
4
5namespace Lorekeeper\Server\Event\Map;
6
7use Lorekeeper\Core\Asset\Gamefile;
8use Lorekeeper\Core\World\Map\MapName;
9use Lorekeeper\Server\AreaId;
10use Lorekeeper\Server\Exception\MalformedEventException;
11use Lorekeeper\Server\RoomId;
12use Override;
13use Psl\Type;
14use Psl\Type\Exception\CoercionException;
15
16final readonly class MovedToMapEvent extends MapArrivalEvent
17{
18    public function __construct(
19        public AreaId $areaId,
20        public RoomId $roomId,
21        public MapName $map,
22        public Gamefile $file,
23    ) {}
24
25    #[Override]
26    public function summary(): string
27    {
28        return "{$this->map->value} (room {$this->roomId->value})";
29    }
30
31    #[Override]
32    protected static function read(array $data): static
33    {
34        try {
35            $data = Type\shape([
36                'areaId' => Type\positive_int(),
37                'areaName' => Type\non_empty_string(),
38                'strMapName' => Type\non_empty_string(),
39                'strMapFileName' => Type\non_empty_string(),
40            ], allowUnknownFields: true)->coerce($data);
41        } catch (CoercionException $exception) {
42            throw new MalformedEventException(static::class, 'map data is missing or invalid', $exception);
43        }
44
45        return new static(
46            new AreaId($data['areaId']),
47            self::room($data['areaName']),
48            new MapName($data['strMapName']),
49            new Gamefile($data['strMapFileName']),
50        );
51    }
52
53    /** @throws MalformedEventException */
54    private static function room(string $areaName): RoomId
55    {
56        $separator = strrpos($areaName, needle: '-');
57        $room = $separator === false ? '' : substr($areaName, $separator + 1);
58
59        if (!ctype_digit($room) || (int) $room < 1) {
60            throw new MalformedEventException(static::class, "area name '{$areaName}' has no room number");
61        }
62
63        return new RoomId((int) $room);
64    }
65}