Lines 85.71% 12 / 14
Functions and Methods 0.00% 0 / 1
Classes and Traits 0.00% 0 / 1
Name Lines Functions and Methods CRAP Classes and Traits
CombatRoundEvent 85.71% 12 / 14 0.00% 0 / 1 4.05 0.00% 0 / 1
 read n/a 0 / 0 n/a 0 / 0 0
 from 85.71% 12 / 14 0.00% 0 / 1 4.05
1<?php
2
3declare(strict_types=1);
4
5namespace Lorekeeper\Server\Event\Combat;
6
7use Lorekeeper\Server\Event\Event;
8use Lorekeeper\Server\Event\NamedAfterClass;
9use Lorekeeper\Server\Exception\MalformedEventException;
10use Lorekeeper\Server\Message\JsonMessage;
11use Lorekeeper\Server\Message\Message;
12use Override;
13use Psl\Option;
14use Psl\Type;
15use Psl\Type\Exception\CoercionException;
16
17abstract readonly class CombatRoundEvent implements Event
18{
19    use NamedAfterClass;
20
21    /**
22     * @param array<positive-int, array{intHP?: non-negative-int, intMP?: non-negative-int, intState?: int<0, 2>}> $monsters
23     * @param array<non-empty-string, array{intHP?: non-negative-int, intMP?: non-negative-int, intState?: int<0, 2>}> $players
24     *
25     * @return Option\Option<static>
26     */
27    abstract protected static function read(array $monsters, array $players): Option\Option;
28
29    /** @return Option\Option<static> */
30    #[Override]
31    final public static function from(Message $message): Option\Option
32    {
33        if (!$message instanceof JsonMessage || ($message->data['cmd'] ?? null) !== 'ct') {
34            return Option\none();
35        }
36
37        $status = Type\shape([
38            'intHP' => Type\optional(Type\uint()),
39            'intMP' => Type\optional(Type\uint()),
40            'intState' => Type\optional(Type\int_range(min: 0, max: 2)),
41        ], allowUnknownFields: true);
42
43        try {
44            $round = Type\shape([
45                'm' => Type\optional(Type\dict(Type\positive_int(), $status)),
46                'p' => Type\optional(Type\dict(Type\non_empty_string(), $status)),
47            ], allowUnknownFields: true)->coerce($message->data);
48        } catch (CoercionException $exception) {
49            throw new MalformedEventException(static::class, 'combat round is invalid', $exception);
50        }
51
52        return static::read($round['m'] ?? [], $round['p'] ?? []);
53    }
54}