Lines 97.14% 34 / 35
Methods 75.00% 3 / 4
Classes 0.00% 0 / 1
Name Lines Methods CRAP
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 from 95.65% 22 / 23 0.00% 0 / 1 6
 summary 100.00% 5 / 5 100.00% 1 / 1 1
 [Lorekeeper\Server\Event\NamedAfterClass] name 100.00% 6 / 6 100.00% 1 / 1 1
23final readonly class ItemDroppedEvent implements Event
24{
25    use NamedAfterClass;
26
27    /** @param non-empty-list<PlayerItem> $items */
28    public function __construct(
29        public array $items,
30    ) {}
31
32    /** @return Option\Option<static> */
33    #[Override]
34    public static function from(Message $message): Option\Option
35    {
36        if (!$message instanceof JsonMessage || ($message->data['cmd'] ?? null) !== 'dropItem') {
37            return Option\none();
38        }
39
40        try {
41            $items = Type\non_empty_dict(Type\string(), Type\shape([
42                'ItemID' => Type\positive_int(),
43                'sName' => Type\non_empty_string(),
44                'sType' => Type\string(),
45                'iQty' => Type\positive_int(),
46                'bUpg' => Type\optional(Type\bool()),
47            ], allowUnknownFields: true))->coerce($message->data['items'] ?? null);
48        } catch (CoercionException $exception) {
49            throw new MalformedEventException(static::class, 'dropped items are missing or invalid', $exception);
50        }
51
52        $dropped = [];
53        foreach ($items as $entry) {
54            $item = ItemKinds::read(
55                new ItemId($entry['ItemID']),
56                new ItemName($entry['sName']),
57                $entry['sType'],
58                static::class,
59            );
60            if ($entry['bUpg'] ?? false) {
61                $item->tags->add(ItemTag::MemberOnly);
62            }
63
64            $dropped[] = new PlayerItem($item, new Quantity($entry['iQty']));
65        }
66
67        return Option\some(new static($dropped));
68    }
69
70    #[Override]
71    public function summary(): string
72    {
73        return 'Dropped '
74        . implode(', ', array_map(
75            static fn(PlayerItem $held): string => "{$held->quantity->value} {$held->item->name->value}",
76            $this->items,
77        ));
78    }
79}

From Lorekeeper\Server\Event\NamedAfterClass

7trait NamedAfterClass
8{
9    public function name(): string
10    {
11        $class = static::class;
12
13        return (string) preg_replace(
14            '/Event$/',
15            replacement: '',
16            subject: substr($class, (int) strrpos($class, needle: '\\') + 1),
17        );
18    }
19}