Lines 100.00% 31 / 31
Functions and Methods 100.00% 3 / 3
Classes and Traits 100.00% 1 / 1
Name Lines Functions and Methods CRAP Classes and Traits
TemporaryItemsAddedEvent 100.00% 31 / 31 100.00% 3 / 3 10 100.00% 1 / 1
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 from 100.00% 25 / 25 100.00% 1 / 1 8
 summary 100.00% 5 / 5 100.00% 1 / 1 1
1<?php
2
3declare(strict_types=1);
4
5namespace Lorekeeper\Server\Event\Inventory;
6
7use Lorekeeper\Core\Item\ItemId;
8use Lorekeeper\Core\Item\ItemName;
9use Lorekeeper\Core\Player\PlayerItem;
10use Lorekeeper\Core\Support\Quantity;
11use Lorekeeper\Server\Event\Event;
12use Lorekeeper\Server\Event\Item\Helper\ItemKinds;
13use Lorekeeper\Server\Event\NamedAfterClass;
14use Lorekeeper\Server\Exception\MalformedEventException;
15use Lorekeeper\Server\Message\JsonMessage;
16use Lorekeeper\Server\Message\Message;
17use Override;
18use Psl\Option;
19use Psl\Type;
20use Psl\Type\Exception\CoercionException;
21
22final readonly class TemporaryItemsAddedEvent implements Event
23{
24    use NamedAfterClass;
25
26    /** @param non-empty-list<PlayerItem> $items */
27    public function __construct(
28        public array $items,
29    ) {}
30
31    /** @return Option\Option<static> */
32    #[Override]
33    public static function from(Message $message): Option\Option
34    {
35        if (!$message instanceof JsonMessage || ($message->data['cmd'] ?? null) !== 'addItems') {
36            return Option\none();
37        }
38
39        try {
40            $items = Type\dict(Type\string(), Type\shape([
41                'ItemID' => Type\positive_int(),
42                'sName' => Type\optional(Type\non_empty_string()),
43                'sType' => Type\optional(Type\string()),
44                'bTemp' => Type\optional(Type\bool()),
45                'iQty' => Type\positive_int(),
46            ], allowUnknownFields: true))->coerce($message->data['items'] ?? null);
47        } catch (CoercionException $exception) {
48            throw new MalformedEventException(static::class, 'items are missing or invalid', $exception);
49        }
50
51        $added = [];
52        foreach ($items as $entry) {
53            if (!($entry['bTemp'] ?? false) || !array_key_exists('sName', $entry)) {
54                continue;
55            }
56
57            $added[] = new PlayerItem(
58                ItemKinds::read(
59                    new ItemId($entry['ItemID']),
60                    new ItemName($entry['sName']),
61                    $entry['sType'] ?? '',
62                    static::class,
63                ),
64                new Quantity($entry['iQty']),
65            );
66        }
67
68        return $added === [] ? Option\none() : Option\some(new static($added));
69    }
70
71    #[Override]
72    public function summary(): string
73    {
74        return 'Got for now '
75        . implode(', ', array_map(
76            static fn(PlayerItem $held): string => "{$held->quantity->value} {$held->item->name->value}",
77            $this->items,
78        ));
79    }
80}