PocketMine-MP 5.41.1 git-dec84fe67dc3319e33f5066e5d03b16f00f2ff4c
Loading...
Searching...
No Matches
ItemEnchantmentTagRegistry.php
1<?php
2
3/*
4 *
5 * ____ _ _ __ __ _ __ __ ____
6 * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
7 * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
8 * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
9 * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
10 *
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * @author PocketMine Team
17 * @link http://www.pocketmine.net/
18 *
19 *
20 */
21
22declare(strict_types=1);
23
24namespace pocketmine\item\enchantment;
25
27use pocketmine\utils\SingletonTrait;
29use function array_diff;
30use function array_intersect;
31use function array_merge;
32use function array_search;
33use function array_shift;
34use function array_unique;
35use function array_values;
36use function count;
37
43 use SingletonTrait;
44
49 private array $tagMap = [];
50
51 private function __construct(){
52 $this->register(Tags::ARMOR, [Tags::HELMET, Tags::CHESTPLATE, Tags::LEGGINGS, Tags::BOOTS]);
53 $this->register(Tags::SHIELD);
54 $this->register(Tags::SWORD);
55 $this->register(Tags::TRIDENT);
56 $this->register(Tags::BOW);
57 $this->register(Tags::CROSSBOW);
58 $this->register(Tags::SHEARS);
59 $this->register(Tags::FLINT_AND_STEEL);
60 $this->register(Tags::BLOCK_TOOLS, [Tags::AXE, Tags::PICKAXE, Tags::SHOVEL, Tags::HOE]);
61 $this->register(Tags::FISHING_ROD);
62 $this->register(Tags::CARROT_ON_STICK);
63 $this->register(Tags::COMPASS);
64 $this->register(Tags::MASK);
65 $this->register(Tags::ELYTRA);
66 $this->register(Tags::BRUSH);
67 $this->register(Tags::WEAPONS, [
68 Tags::SWORD,
69 Tags::TRIDENT,
70 Tags::BOW,
71 Tags::CROSSBOW,
72 Tags::BLOCK_TOOLS,
73 ]);
74 }
75
81 public function register(string $tag, array $nestedTags = []) : void{
82 $this->assertNotInternalTag($tag);
83
84 foreach($nestedTags as $nestedTag){
85 if(!isset($this->tagMap[$nestedTag])){
86 $this->register($nestedTag);
87 }
88 $this->tagMap[$tag][] = $nestedTag;
89 }
90
91 if(!isset($this->tagMap[$tag])){
92 $this->tagMap[$tag] = [];
93 $this->tagMap[Tags::ALL][] = $tag;
94 }
95 }
96
97 public function unregister(string $tag) : void{
98 if(!isset($this->tagMap[$tag])){
99 return;
100 }
101 $this->assertNotInternalTag($tag);
102
103 unset($this->tagMap[$tag]);
104
105 foreach(Utils::stringifyKeys($this->tagMap) as $key => $nestedTags){
106 if(($nestedKey = array_search($tag, $nestedTags, true)) !== false){
107 unset($nestedTags[$nestedKey]);
108 $this->tagMap[$key] = array_values($nestedTags);
109 }
110 }
111 }
112
118 public function removeNested(string $tag, array $nestedTags) : void{
119 $this->assertNotInternalTag($tag);
120 $this->tagMap[$tag] = array_values(array_diff($this->tagMap[$tag], $nestedTags));
121 }
122
128 public function getNested(string $tag) : array{
129 return $this->tagMap[$tag] ?? [];
130 }
131
136 public function isTagArrayIntersection(array $firstTags, array $secondTags) : bool{
137 if(count($firstTags) === 0 || count($secondTags) === 0){
138 return false;
139 }
140
141 $firstLeafTags = $this->getLeafTagsForArray($firstTags);
142 $secondLeafTags = $this->getLeafTagsForArray($secondTags);
143
144 return count(array_intersect($firstLeafTags, $secondLeafTags)) !== 0;
145 }
146
154 private function getLeafTagsForArray(array $tags) : array{
155 $leafTagArrays = [];
156 foreach($tags as $tag){
157 $leafTagArrays[] = $this->getLeafTags($tag);
158 }
159 return array_unique(array_merge(...$leafTagArrays));
160 }
161
167 private function getLeafTags(string $tag) : array{
168 $result = [];
169 $tagsToHandle = [$tag];
170
171 while(count($tagsToHandle) !== 0){
172 $currentTag = array_shift($tagsToHandle);
173 $nestedTags = $this->getNested($currentTag);
174
175 if(count($nestedTags) === 0){
176 $result[] = $currentTag;
177 }else{
178 $tagsToHandle = array_merge($tagsToHandle, $nestedTags);
179 }
180 }
181
182 return $result;
183 }
184
185 private function assertNotInternalTag(string $tag) : void{
186 if($tag === Tags::ALL){
187 throw new \InvalidArgumentException(
188 "Cannot perform any operations on the internal item enchantment tag '$tag'"
189 );
190 }
191 }
192}