PocketMine-MP 5.27.1 git-9af3cde03fabbe4129c79e46dc87ffa0fff446e6
Loading...
Searching...
No Matches
BlockStateToObjectDeserializer.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\data\bedrock\block\convert;
25
40use pocketmine\block\utils\BrewingStandSlot;
41use pocketmine\block\utils\ChiseledBookshelfSlot;
43use pocketmine\block\utils\CopperOxidation;
44use pocketmine\block\utils\CoralType;
45use pocketmine\block\utils\DirtType;
46use pocketmine\block\utils\DripleafState;
47use pocketmine\block\utils\DyeColor;
48use pocketmine\block\utils\FroglightType;
49use pocketmine\block\utils\LeverFacing;
50use pocketmine\block\utils\MobHeadType;
65use function array_key_exists;
66use function count;
67use function min;
68
70
75 private array $deserializeFuncs = [];
76
81 private array $simpleCache = [];
82
83 public function __construct(){
84 $this->registerCandleDeserializers();
85 $this->registerFlatColorBlockDeserializers();
86 $this->registerFlatCoralDeserializers();
87 $this->registerCauldronDeserializers();
88 $this->registerFlatWoodBlockDeserializers();
89 $this->registerLeavesDeserializers();
90 $this->registerSaplingDeserializers();
91 $this->registerLightDeserializers();
92 $this->registerMobHeadDeserializers();
93 $this->registerCopperDeserializers();
94 $this->registerSimpleDeserializers();
95 $this->registerDeserializers();
96 }
97
98 public function deserialize(BlockStateData $stateData) : int{
99 if(count($stateData->getStates()) === 0){
100 //if a block has zero properties, we can keep a map of string ID -> internal blockstate ID
101 return $this->simpleCache[$stateData->getName()] ??= $this->deserializeToStateId($stateData);
102 }
103
104 //we can't cache blocks that have properties - go ahead and deserialize the slow way
105 return $this->deserializeToStateId($stateData);
106 }
107
108 private function deserializeToStateId(BlockStateData $stateData) : int{
109 $stateId = $this->deserializeBlock($stateData)->getStateId();
110 //plugin devs seem to keep missing this and causing core crashes, so we need to verify this at the earliest
111 //available opportunity
112 if(!RuntimeBlockStateRegistry::getInstance()->hasStateId($stateId)){
113 throw new \LogicException("State ID $stateId returned by deserializer for " . $stateData->getName() . " is not registered in RuntimeBlockStateRegistry");
114 }
115 return $stateId;
116 }
117
119 public function map(string $id, \Closure $c) : void{
120 $this->deserializeFuncs[$id] = $c;
121 $this->simpleCache = [];
122 }
123
130 public function getDeserializerForId(string $id) : ?\Closure{
131 return $this->deserializeFuncs[$id] ?? null;
132 }
133
135 public function mapSimple(string $id, \Closure $getBlock) : void{
136 $this->map($id, $getBlock);
137 }
138
142 public function mapSlab(string $singleId, string $doubleId, \Closure $getBlock) : void{
143 $this->map($singleId, fn(Reader $in) => Helper::decodeSingleSlab($getBlock($in), $in));
144 $this->map($doubleId, fn(Reader $in) => Helper::decodeDoubleSlab($getBlock($in), $in));
145 }
146
150 public function mapStairs(string $id, \Closure $getBlock) : void{
151 $this->map($id, fn(Reader $in) : Stair => Helper::decodeStairs($getBlock(), $in));
152 }
153
155 public function mapLog(string $unstrippedId, string $strippedId, \Closure $getBlock) : void{
156 $this->map($unstrippedId, fn(Reader $in) => Helper::decodeLog($getBlock(), false, $in));
157 $this->map($strippedId, fn(Reader $in) => Helper::decodeLog($getBlock(), true, $in));
158 }
159
160 private function registerCandleDeserializers() : void{
161 $this->map(Ids::CANDLE, fn(Reader $in) => Helper::decodeCandle(Blocks::CANDLE(), $in));
162 foreach([
163 Ids::BLACK_CANDLE => DyeColor::BLACK,
164 Ids::BLUE_CANDLE => DyeColor::BLUE,
165 Ids::BROWN_CANDLE => DyeColor::BROWN,
166 Ids::CYAN_CANDLE => DyeColor::CYAN,
167 Ids::GRAY_CANDLE => DyeColor::GRAY,
168 Ids::GREEN_CANDLE => DyeColor::GREEN,
169 Ids::LIGHT_BLUE_CANDLE => DyeColor::LIGHT_BLUE,
170 Ids::LIGHT_GRAY_CANDLE => DyeColor::LIGHT_GRAY,
171 Ids::LIME_CANDLE => DyeColor::LIME,
172 Ids::MAGENTA_CANDLE => DyeColor::MAGENTA,
173 Ids::ORANGE_CANDLE => DyeColor::ORANGE,
174 Ids::PINK_CANDLE => DyeColor::PINK,
175 Ids::PURPLE_CANDLE => DyeColor::PURPLE,
176 Ids::RED_CANDLE => DyeColor::RED,
177 Ids::WHITE_CANDLE => DyeColor::WHITE,
178 Ids::YELLOW_CANDLE => DyeColor::YELLOW,
179 ] as $id => $color){
180 $this->map($id, fn(Reader $in) => Helper::decodeCandle(Blocks::DYED_CANDLE()->setColor($color), $in));
181 }
182
183 $this->map(Ids::CANDLE_CAKE, fn(Reader $in) => Blocks::CAKE_WITH_CANDLE()->setLit($in->readBool(StateNames::LIT)));
184 foreach([
185 Ids::BLACK_CANDLE_CAKE => DyeColor::BLACK,
186 Ids::BLUE_CANDLE_CAKE => DyeColor::BLUE,
187 Ids::BROWN_CANDLE_CAKE => DyeColor::BROWN,
188 Ids::CYAN_CANDLE_CAKE => DyeColor::CYAN,
189 Ids::GRAY_CANDLE_CAKE => DyeColor::GRAY,
190 Ids::GREEN_CANDLE_CAKE => DyeColor::GREEN,
191 Ids::LIGHT_BLUE_CANDLE_CAKE => DyeColor::LIGHT_BLUE,
192 Ids::LIGHT_GRAY_CANDLE_CAKE => DyeColor::LIGHT_GRAY,
193 Ids::LIME_CANDLE_CAKE => DyeColor::LIME,
194 Ids::MAGENTA_CANDLE_CAKE => DyeColor::MAGENTA,
195 Ids::ORANGE_CANDLE_CAKE => DyeColor::ORANGE,
196 Ids::PINK_CANDLE_CAKE => DyeColor::PINK,
197 Ids::PURPLE_CANDLE_CAKE => DyeColor::PURPLE,
198 Ids::RED_CANDLE_CAKE => DyeColor::RED,
199 Ids::WHITE_CANDLE_CAKE => DyeColor::WHITE,
200 Ids::YELLOW_CANDLE_CAKE => DyeColor::YELLOW,
201 ] as $id => $color){
202 $this->map($id, fn(Reader $in) => Blocks::CAKE_WITH_DYED_CANDLE()
203 ->setColor($color)
204 ->setLit($in->readBool(StateNames::LIT))
205 );
206 }
207 }
208
209 private function registerFlatColorBlockDeserializers() : void{
210 foreach([
211 Ids::HARD_BLACK_STAINED_GLASS => DyeColor::BLACK,
212 Ids::HARD_BLUE_STAINED_GLASS => DyeColor::BLUE,
213 Ids::HARD_BROWN_STAINED_GLASS => DyeColor::BROWN,
214 Ids::HARD_CYAN_STAINED_GLASS => DyeColor::CYAN,
215 Ids::HARD_GRAY_STAINED_GLASS => DyeColor::GRAY,
216 Ids::HARD_GREEN_STAINED_GLASS => DyeColor::GREEN,
217 Ids::HARD_LIGHT_BLUE_STAINED_GLASS => DyeColor::LIGHT_BLUE,
218 Ids::HARD_LIGHT_GRAY_STAINED_GLASS => DyeColor::LIGHT_GRAY,
219 Ids::HARD_LIME_STAINED_GLASS => DyeColor::LIME,
220 Ids::HARD_MAGENTA_STAINED_GLASS => DyeColor::MAGENTA,
221 Ids::HARD_ORANGE_STAINED_GLASS => DyeColor::ORANGE,
222 Ids::HARD_PINK_STAINED_GLASS => DyeColor::PINK,
223 Ids::HARD_PURPLE_STAINED_GLASS => DyeColor::PURPLE,
224 Ids::HARD_RED_STAINED_GLASS => DyeColor::RED,
225 Ids::HARD_WHITE_STAINED_GLASS => DyeColor::WHITE,
226 Ids::HARD_YELLOW_STAINED_GLASS => DyeColor::YELLOW,
227 ] as $id => $color){
228 $this->map($id, fn(Reader $in) => Blocks::STAINED_HARDENED_GLASS()->setColor($color));
229 }
230
231 foreach([
232 Ids::HARD_BLACK_STAINED_GLASS_PANE => DyeColor::BLACK,
233 Ids::HARD_BLUE_STAINED_GLASS_PANE => DyeColor::BLUE,
234 Ids::HARD_BROWN_STAINED_GLASS_PANE => DyeColor::BROWN,
235 Ids::HARD_CYAN_STAINED_GLASS_PANE => DyeColor::CYAN,
236 Ids::HARD_GRAY_STAINED_GLASS_PANE => DyeColor::GRAY,
237 Ids::HARD_GREEN_STAINED_GLASS_PANE => DyeColor::GREEN,
238 Ids::HARD_LIGHT_BLUE_STAINED_GLASS_PANE => DyeColor::LIGHT_BLUE,
239 Ids::HARD_LIGHT_GRAY_STAINED_GLASS_PANE => DyeColor::LIGHT_GRAY,
240 Ids::HARD_LIME_STAINED_GLASS_PANE => DyeColor::LIME,
241 Ids::HARD_MAGENTA_STAINED_GLASS_PANE => DyeColor::MAGENTA,
242 Ids::HARD_ORANGE_STAINED_GLASS_PANE => DyeColor::ORANGE,
243 Ids::HARD_PINK_STAINED_GLASS_PANE => DyeColor::PINK,
244 Ids::HARD_PURPLE_STAINED_GLASS_PANE => DyeColor::PURPLE,
245 Ids::HARD_RED_STAINED_GLASS_PANE => DyeColor::RED,
246 Ids::HARD_WHITE_STAINED_GLASS_PANE => DyeColor::WHITE,
247 Ids::HARD_YELLOW_STAINED_GLASS_PANE => DyeColor::YELLOW,
248 ] as $id => $color){
249 $this->map($id, fn(Reader $in) => Blocks::STAINED_HARDENED_GLASS_PANE()->setColor($color));
250 }
251
252 foreach([
253 Ids::BLACK_GLAZED_TERRACOTTA => DyeColor::BLACK,
254 Ids::BLUE_GLAZED_TERRACOTTA => DyeColor::BLUE,
255 Ids::BROWN_GLAZED_TERRACOTTA => DyeColor::BROWN,
256 Ids::CYAN_GLAZED_TERRACOTTA => DyeColor::CYAN,
257 Ids::GRAY_GLAZED_TERRACOTTA => DyeColor::GRAY,
258 Ids::GREEN_GLAZED_TERRACOTTA => DyeColor::GREEN,
259 Ids::LIGHT_BLUE_GLAZED_TERRACOTTA => DyeColor::LIGHT_BLUE,
260 Ids::SILVER_GLAZED_TERRACOTTA => DyeColor::LIGHT_GRAY,
261 Ids::LIME_GLAZED_TERRACOTTA => DyeColor::LIME,
262 Ids::MAGENTA_GLAZED_TERRACOTTA => DyeColor::MAGENTA,
263 Ids::ORANGE_GLAZED_TERRACOTTA => DyeColor::ORANGE,
264 Ids::PINK_GLAZED_TERRACOTTA => DyeColor::PINK,
265 Ids::PURPLE_GLAZED_TERRACOTTA => DyeColor::PURPLE,
266 Ids::RED_GLAZED_TERRACOTTA => DyeColor::RED,
267 Ids::WHITE_GLAZED_TERRACOTTA => DyeColor::WHITE,
268 Ids::YELLOW_GLAZED_TERRACOTTA => DyeColor::YELLOW,
269 ] as $id => $color){
270 $this->map($id, fn(Reader $in) => Blocks::GLAZED_TERRACOTTA()
271 ->setColor($color)
272 ->setFacing($in->readHorizontalFacing())
273 );
274 }
275
276 foreach([
277 Ids::BLACK_WOOL => DyeColor::BLACK,
278 Ids::BLUE_WOOL => DyeColor::BLUE,
279 Ids::BROWN_WOOL => DyeColor::BROWN,
280 Ids::CYAN_WOOL => DyeColor::CYAN,
281 Ids::GRAY_WOOL => DyeColor::GRAY,
282 Ids::GREEN_WOOL => DyeColor::GREEN,
283 Ids::LIGHT_BLUE_WOOL => DyeColor::LIGHT_BLUE,
284 Ids::LIGHT_GRAY_WOOL => DyeColor::LIGHT_GRAY,
285 Ids::LIME_WOOL => DyeColor::LIME,
286 Ids::MAGENTA_WOOL => DyeColor::MAGENTA,
287 Ids::ORANGE_WOOL => DyeColor::ORANGE,
288 Ids::PINK_WOOL => DyeColor::PINK,
289 Ids::PURPLE_WOOL => DyeColor::PURPLE,
290 Ids::RED_WOOL => DyeColor::RED,
291 Ids::WHITE_WOOL => DyeColor::WHITE,
292 Ids::YELLOW_WOOL => DyeColor::YELLOW,
293 ] as $id => $color){
294 $this->mapSimple($id, fn() => Blocks::WOOL()->setColor($color));
295 }
296
297 foreach([
298 Ids::BLACK_CARPET => DyeColor::BLACK,
299 Ids::BLUE_CARPET => DyeColor::BLUE,
300 Ids::BROWN_CARPET => DyeColor::BROWN,
301 Ids::CYAN_CARPET => DyeColor::CYAN,
302 Ids::GRAY_CARPET => DyeColor::GRAY,
303 Ids::GREEN_CARPET => DyeColor::GREEN,
304 Ids::LIGHT_BLUE_CARPET => DyeColor::LIGHT_BLUE,
305 Ids::LIGHT_GRAY_CARPET => DyeColor::LIGHT_GRAY,
306 Ids::LIME_CARPET => DyeColor::LIME,
307 Ids::MAGENTA_CARPET => DyeColor::MAGENTA,
308 Ids::ORANGE_CARPET => DyeColor::ORANGE,
309 Ids::PINK_CARPET => DyeColor::PINK,
310 Ids::PURPLE_CARPET => DyeColor::PURPLE,
311 Ids::RED_CARPET => DyeColor::RED,
312 Ids::WHITE_CARPET => DyeColor::WHITE,
313 Ids::YELLOW_CARPET => DyeColor::YELLOW,
314 ] as $id => $color){
315 $this->mapSimple($id, fn() => Blocks::CARPET()->setColor($color));
316 }
317
318 foreach([
319 Ids::BLACK_SHULKER_BOX => DyeColor::BLACK,
320 Ids::BLUE_SHULKER_BOX => DyeColor::BLUE,
321 Ids::BROWN_SHULKER_BOX => DyeColor::BROWN,
322 Ids::CYAN_SHULKER_BOX => DyeColor::CYAN,
323 Ids::GRAY_SHULKER_BOX => DyeColor::GRAY,
324 Ids::GREEN_SHULKER_BOX => DyeColor::GREEN,
325 Ids::LIGHT_BLUE_SHULKER_BOX => DyeColor::LIGHT_BLUE,
326 Ids::LIGHT_GRAY_SHULKER_BOX => DyeColor::LIGHT_GRAY,
327 Ids::LIME_SHULKER_BOX => DyeColor::LIME,
328 Ids::MAGENTA_SHULKER_BOX => DyeColor::MAGENTA,
329 Ids::ORANGE_SHULKER_BOX => DyeColor::ORANGE,
330 Ids::PINK_SHULKER_BOX => DyeColor::PINK,
331 Ids::PURPLE_SHULKER_BOX => DyeColor::PURPLE,
332 Ids::RED_SHULKER_BOX => DyeColor::RED,
333 Ids::WHITE_SHULKER_BOX => DyeColor::WHITE,
334 Ids::YELLOW_SHULKER_BOX => DyeColor::YELLOW,
335 ] as $id => $color){
336 $this->mapSimple($id, fn() => Blocks::DYED_SHULKER_BOX()->setColor($color));
337 }
338
339 foreach([
340 Ids::BLACK_CONCRETE => DyeColor::BLACK,
341 Ids::BLUE_CONCRETE => DyeColor::BLUE,
342 Ids::BROWN_CONCRETE => DyeColor::BROWN,
343 Ids::CYAN_CONCRETE => DyeColor::CYAN,
344 Ids::GRAY_CONCRETE => DyeColor::GRAY,
345 Ids::GREEN_CONCRETE => DyeColor::GREEN,
346 Ids::LIGHT_BLUE_CONCRETE => DyeColor::LIGHT_BLUE,
347 Ids::LIGHT_GRAY_CONCRETE => DyeColor::LIGHT_GRAY,
348 Ids::LIME_CONCRETE => DyeColor::LIME,
349 Ids::MAGENTA_CONCRETE => DyeColor::MAGENTA,
350 Ids::ORANGE_CONCRETE => DyeColor::ORANGE,
351 Ids::PINK_CONCRETE => DyeColor::PINK,
352 Ids::PURPLE_CONCRETE => DyeColor::PURPLE,
353 Ids::RED_CONCRETE => DyeColor::RED,
354 Ids::WHITE_CONCRETE => DyeColor::WHITE,
355 Ids::YELLOW_CONCRETE => DyeColor::YELLOW,
356 ] as $id => $color){
357 $this->mapSimple($id, fn() => Blocks::CONCRETE()->setColor($color));
358 }
359
360 foreach([
361 Ids::BLACK_CONCRETE_POWDER => DyeColor::BLACK,
362 Ids::BLUE_CONCRETE_POWDER => DyeColor::BLUE,
363 Ids::BROWN_CONCRETE_POWDER => DyeColor::BROWN,
364 Ids::CYAN_CONCRETE_POWDER => DyeColor::CYAN,
365 Ids::GRAY_CONCRETE_POWDER => DyeColor::GRAY,
366 Ids::GREEN_CONCRETE_POWDER => DyeColor::GREEN,
367 Ids::LIGHT_BLUE_CONCRETE_POWDER => DyeColor::LIGHT_BLUE,
368 Ids::LIGHT_GRAY_CONCRETE_POWDER => DyeColor::LIGHT_GRAY,
369 Ids::LIME_CONCRETE_POWDER => DyeColor::LIME,
370 Ids::MAGENTA_CONCRETE_POWDER => DyeColor::MAGENTA,
371 Ids::ORANGE_CONCRETE_POWDER => DyeColor::ORANGE,
372 Ids::PINK_CONCRETE_POWDER => DyeColor::PINK,
373 Ids::PURPLE_CONCRETE_POWDER => DyeColor::PURPLE,
374 Ids::RED_CONCRETE_POWDER => DyeColor::RED,
375 Ids::WHITE_CONCRETE_POWDER => DyeColor::WHITE,
376 Ids::YELLOW_CONCRETE_POWDER => DyeColor::YELLOW,
377 ] as $id => $color){
378 $this->mapSimple($id, fn() => Blocks::CONCRETE_POWDER()->setColor($color));
379 }
380
381 foreach([
382 Ids::BLACK_TERRACOTTA => DyeColor::BLACK,
383 Ids::BLUE_TERRACOTTA => DyeColor::BLUE,
384 Ids::BROWN_TERRACOTTA => DyeColor::BROWN,
385 Ids::CYAN_TERRACOTTA => DyeColor::CYAN,
386 Ids::GRAY_TERRACOTTA => DyeColor::GRAY,
387 Ids::GREEN_TERRACOTTA => DyeColor::GREEN,
388 Ids::LIGHT_BLUE_TERRACOTTA => DyeColor::LIGHT_BLUE,
389 Ids::LIGHT_GRAY_TERRACOTTA => DyeColor::LIGHT_GRAY,
390 Ids::LIME_TERRACOTTA => DyeColor::LIME,
391 Ids::MAGENTA_TERRACOTTA => DyeColor::MAGENTA,
392 Ids::ORANGE_TERRACOTTA => DyeColor::ORANGE,
393 Ids::PINK_TERRACOTTA => DyeColor::PINK,
394 Ids::PURPLE_TERRACOTTA => DyeColor::PURPLE,
395 Ids::RED_TERRACOTTA => DyeColor::RED,
396 Ids::WHITE_TERRACOTTA => DyeColor::WHITE,
397 Ids::YELLOW_TERRACOTTA => DyeColor::YELLOW,
398 ] as $id => $color){
399 $this->mapSimple($id, fn() => Blocks::STAINED_CLAY()->setColor($color));
400 }
401
402 foreach([
403 Ids::BLACK_STAINED_GLASS => DyeColor::BLACK,
404 Ids::BLUE_STAINED_GLASS => DyeColor::BLUE,
405 Ids::BROWN_STAINED_GLASS => DyeColor::BROWN,
406 Ids::CYAN_STAINED_GLASS => DyeColor::CYAN,
407 Ids::GRAY_STAINED_GLASS => DyeColor::GRAY,
408 Ids::GREEN_STAINED_GLASS => DyeColor::GREEN,
409 Ids::LIGHT_BLUE_STAINED_GLASS => DyeColor::LIGHT_BLUE,
410 Ids::LIGHT_GRAY_STAINED_GLASS => DyeColor::LIGHT_GRAY,
411 Ids::LIME_STAINED_GLASS => DyeColor::LIME,
412 Ids::MAGENTA_STAINED_GLASS => DyeColor::MAGENTA,
413 Ids::ORANGE_STAINED_GLASS => DyeColor::ORANGE,
414 Ids::PINK_STAINED_GLASS => DyeColor::PINK,
415 Ids::PURPLE_STAINED_GLASS => DyeColor::PURPLE,
416 Ids::RED_STAINED_GLASS => DyeColor::RED,
417 Ids::WHITE_STAINED_GLASS => DyeColor::WHITE,
418 Ids::YELLOW_STAINED_GLASS => DyeColor::YELLOW,
419 ] as $id => $color){
420 $this->mapSimple($id, fn() => Blocks::STAINED_GLASS()->setColor($color));
421 }
422
423 foreach([
424 Ids::BLACK_STAINED_GLASS_PANE => DyeColor::BLACK,
425 Ids::BLUE_STAINED_GLASS_PANE => DyeColor::BLUE,
426 Ids::BROWN_STAINED_GLASS_PANE => DyeColor::BROWN,
427 Ids::CYAN_STAINED_GLASS_PANE => DyeColor::CYAN,
428 Ids::GRAY_STAINED_GLASS_PANE => DyeColor::GRAY,
429 Ids::GREEN_STAINED_GLASS_PANE => DyeColor::GREEN,
430 Ids::LIGHT_BLUE_STAINED_GLASS_PANE => DyeColor::LIGHT_BLUE,
431 Ids::LIGHT_GRAY_STAINED_GLASS_PANE => DyeColor::LIGHT_GRAY,
432 Ids::LIME_STAINED_GLASS_PANE => DyeColor::LIME,
433 Ids::MAGENTA_STAINED_GLASS_PANE => DyeColor::MAGENTA,
434 Ids::ORANGE_STAINED_GLASS_PANE => DyeColor::ORANGE,
435 Ids::PINK_STAINED_GLASS_PANE => DyeColor::PINK,
436 Ids::PURPLE_STAINED_GLASS_PANE => DyeColor::PURPLE,
437 Ids::RED_STAINED_GLASS_PANE => DyeColor::RED,
438 Ids::WHITE_STAINED_GLASS_PANE => DyeColor::WHITE,
439 Ids::YELLOW_STAINED_GLASS_PANE => DyeColor::YELLOW,
440 ] as $id => $color){
441 $this->mapSimple($id, fn() => Blocks::STAINED_GLASS_PANE()->setColor($color));
442 }
443 }
444
445 private function registerFlatCoralDeserializers() : void{
446 foreach([
447 Ids::BRAIN_CORAL => CoralType::BRAIN,
448 Ids::BUBBLE_CORAL => CoralType::BUBBLE,
449 Ids::FIRE_CORAL => CoralType::FIRE,
450 Ids::HORN_CORAL => CoralType::HORN,
451 Ids::TUBE_CORAL => CoralType::TUBE,
452 ] as $id => $coralType){
453 $this->mapSimple($id, fn() => Blocks::CORAL()->setCoralType($coralType)->setDead(false));
454 }
455 foreach([
456 Ids::DEAD_BRAIN_CORAL => CoralType::BRAIN,
457 Ids::DEAD_BUBBLE_CORAL => CoralType::BUBBLE,
458 Ids::DEAD_FIRE_CORAL => CoralType::FIRE,
459 Ids::DEAD_HORN_CORAL => CoralType::HORN,
460 Ids::DEAD_TUBE_CORAL => CoralType::TUBE,
461 ] as $id => $coralType){
462 $this->mapSimple($id, fn() => Blocks::CORAL()->setCoralType($coralType)->setDead(true));
463 }
464
465 foreach([
466 [CoralType::BRAIN, Ids::BRAIN_CORAL_FAN, Ids::DEAD_BRAIN_CORAL_FAN],
467 [CoralType::BUBBLE, Ids::BUBBLE_CORAL_FAN, Ids::DEAD_BUBBLE_CORAL_FAN],
468 [CoralType::FIRE, Ids::FIRE_CORAL_FAN, Ids::DEAD_FIRE_CORAL_FAN],
469 [CoralType::HORN, Ids::HORN_CORAL_FAN, Ids::DEAD_HORN_CORAL_FAN],
470 [CoralType::TUBE, Ids::TUBE_CORAL_FAN, Ids::DEAD_TUBE_CORAL_FAN],
471 ] as [$coralType, $aliveId, $deadId]){
472 $this->map($aliveId, fn(Reader $in) => Helper::decodeFloorCoralFan(Blocks::CORAL_FAN()->setCoralType($coralType)->setDead(false), $in));
473 $this->map($deadId, fn(Reader $in) => Helper::decodeFloorCoralFan(Blocks::CORAL_FAN()->setCoralType($coralType)->setDead(true), $in));
474 }
475
476 foreach([
477 [CoralType::BRAIN, Ids::BRAIN_CORAL_BLOCK, Ids::DEAD_BRAIN_CORAL_BLOCK],
478 [CoralType::BUBBLE, Ids::BUBBLE_CORAL_BLOCK, Ids::DEAD_BUBBLE_CORAL_BLOCK],
479 [CoralType::FIRE, Ids::FIRE_CORAL_BLOCK, Ids::DEAD_FIRE_CORAL_BLOCK],
480 [CoralType::HORN, Ids::HORN_CORAL_BLOCK, Ids::DEAD_HORN_CORAL_BLOCK],
481 [CoralType::TUBE, Ids::TUBE_CORAL_BLOCK, Ids::DEAD_TUBE_CORAL_BLOCK],
482 ] as [$coralType, $aliveId, $deadId]){
483 $this->map($aliveId, fn(Reader $in) => Blocks::CORAL_BLOCK()->setCoralType($coralType)->setDead(false));
484 $this->map($deadId, fn(Reader $in) => Blocks::CORAL_BLOCK()->setCoralType($coralType)->setDead(true));
485 }
486
487 foreach([
488 [CoralType::BRAIN, Ids::BRAIN_CORAL_WALL_FAN, Ids::DEAD_BRAIN_CORAL_WALL_FAN],
489 [CoralType::BUBBLE, Ids::BUBBLE_CORAL_WALL_FAN, Ids::DEAD_BUBBLE_CORAL_WALL_FAN],
490 [CoralType::FIRE, Ids::FIRE_CORAL_WALL_FAN, Ids::DEAD_FIRE_CORAL_WALL_FAN],
491 [CoralType::HORN, Ids::HORN_CORAL_WALL_FAN, Ids::DEAD_HORN_CORAL_WALL_FAN],
492 [CoralType::TUBE, Ids::TUBE_CORAL_WALL_FAN, Ids::DEAD_TUBE_CORAL_WALL_FAN],
493 ] as [$coralType, $aliveId, $deadId]){
494 $this->map($aliveId, fn(Reader $in) => Blocks::WALL_CORAL_FAN()->setFacing($in->readCoralFacing())->setCoralType($coralType)->setDead(false));
495 $this->map($deadId, fn(Reader $in) => Blocks::WALL_CORAL_FAN()->setFacing($in->readCoralFacing())->setCoralType($coralType)->setDead(true));
496 }
497 }
498
499 private function registerCauldronDeserializers() : void{
500 $deserializer = function(Reader $in) : Block{
501 $level = $in->readBoundedInt(StateNames::FILL_LEVEL, 0, 6);
502 if($level === 0){
503 $in->ignored(StateNames::CAULDRON_LIQUID);
504 return Blocks::CAULDRON();
505 }
506
507 return (match($liquid = $in->readString(StateNames::CAULDRON_LIQUID)){
508 StringValues::CAULDRON_LIQUID_WATER => Blocks::WATER_CAULDRON(),
509 StringValues::CAULDRON_LIQUID_LAVA => Blocks::LAVA_CAULDRON(),
510 StringValues::CAULDRON_LIQUID_POWDER_SNOW => throw new UnsupportedBlockStateException("Powder snow is not supported yet"),
511 default => throw $in->badValueException(StateNames::CAULDRON_LIQUID, $liquid)
512 })->setFillLevel($level);
513 };
514 $this->map(Ids::CAULDRON, $deserializer);
515 }
516
517 private function registerFlatWoodBlockDeserializers() : void{
518 $this->map(Ids::ACACIA_BUTTON, fn(Reader $in) => Helper::decodeButton(Blocks::ACACIA_BUTTON(), $in));
519 $this->map(Ids::ACACIA_DOOR, fn(Reader $in) => Helper::decodeDoor(Blocks::ACACIA_DOOR(), $in));
520 $this->map(Ids::ACACIA_FENCE_GATE, fn(Reader $in) => Helper::decodeFenceGate(Blocks::ACACIA_FENCE_GATE(), $in));
521 $this->map(Ids::ACACIA_PRESSURE_PLATE, fn(Reader $in) => Helper::decodeSimplePressurePlate(Blocks::ACACIA_PRESSURE_PLATE(), $in));
522 $this->map(Ids::ACACIA_STANDING_SIGN, fn(Reader $in) => Helper::decodeFloorSign(Blocks::ACACIA_SIGN(), $in));
523 $this->map(Ids::ACACIA_TRAPDOOR, fn(Reader $in) => Helper::decodeTrapdoor(Blocks::ACACIA_TRAPDOOR(), $in));
524 $this->map(Ids::ACACIA_WALL_SIGN, fn(Reader $in) => Helper::decodeWallSign(Blocks::ACACIA_WALL_SIGN(), $in));
525 $this->mapLog(Ids::ACACIA_LOG, Ids::STRIPPED_ACACIA_LOG, fn() => Blocks::ACACIA_LOG());
526 $this->mapLog(Ids::ACACIA_WOOD, Ids::STRIPPED_ACACIA_WOOD, fn() => Blocks::ACACIA_WOOD());
527 $this->mapSimple(Ids::ACACIA_FENCE, fn() => Blocks::ACACIA_FENCE());
528 $this->mapSimple(Ids::ACACIA_PLANKS, fn() => Blocks::ACACIA_PLANKS());
529 $this->mapSlab(Ids::ACACIA_SLAB, Ids::ACACIA_DOUBLE_SLAB, fn() => Blocks::ACACIA_SLAB());
530 $this->mapStairs(Ids::ACACIA_STAIRS, fn() => Blocks::ACACIA_STAIRS());
531
532 $this->map(Ids::BIRCH_BUTTON, fn(Reader $in) => Helper::decodeButton(Blocks::BIRCH_BUTTON(), $in));
533 $this->map(Ids::BIRCH_DOOR, fn(Reader $in) => Helper::decodeDoor(Blocks::BIRCH_DOOR(), $in));
534 $this->map(Ids::BIRCH_FENCE_GATE, fn(Reader $in) => Helper::decodeFenceGate(Blocks::BIRCH_FENCE_GATE(), $in));
535 $this->map(Ids::BIRCH_PRESSURE_PLATE, fn(Reader $in) => Helper::decodeSimplePressurePlate(Blocks::BIRCH_PRESSURE_PLATE(), $in));
536 $this->map(Ids::BIRCH_STANDING_SIGN, fn(Reader $in) => Helper::decodeFloorSign(Blocks::BIRCH_SIGN(), $in));
537 $this->map(Ids::BIRCH_TRAPDOOR, fn(Reader $in) => Helper::decodeTrapdoor(Blocks::BIRCH_TRAPDOOR(), $in));
538 $this->map(Ids::BIRCH_WALL_SIGN, fn(Reader $in) => Helper::decodeWallSign(Blocks::BIRCH_WALL_SIGN(), $in));
539 $this->mapLog(Ids::BIRCH_LOG, Ids::STRIPPED_BIRCH_LOG, fn() => Blocks::BIRCH_LOG());
540 $this->mapLog(Ids::BIRCH_WOOD, Ids::STRIPPED_BIRCH_WOOD, fn() => Blocks::BIRCH_WOOD());
541 $this->mapSimple(Ids::BIRCH_FENCE, fn() => Blocks::BIRCH_FENCE());
542 $this->mapSimple(Ids::BIRCH_PLANKS, fn() => Blocks::BIRCH_PLANKS());
543 $this->mapSlab(Ids::BIRCH_SLAB, Ids::BIRCH_DOUBLE_SLAB, fn() => Blocks::BIRCH_SLAB());
544 $this->mapStairs(Ids::BIRCH_STAIRS, fn() => Blocks::BIRCH_STAIRS());
545
546 $this->map(Ids::CHERRY_BUTTON, fn(Reader $in) => Helper::decodeButton(Blocks::CHERRY_BUTTON(), $in));
547 $this->map(Ids::CHERRY_DOOR, fn(Reader $in) => Helper::decodeDoor(Blocks::CHERRY_DOOR(), $in));
548 $this->map(Ids::CHERRY_FENCE_GATE, fn(Reader $in) => Helper::decodeFenceGate(Blocks::CHERRY_FENCE_GATE(), $in));
549 $this->map(Ids::CHERRY_PRESSURE_PLATE, fn(Reader $in) => Helper::decodeSimplePressurePlate(Blocks::CHERRY_PRESSURE_PLATE(), $in));
550 $this->map(Ids::CHERRY_STANDING_SIGN, fn(Reader $in) => Helper::decodeFloorSign(Blocks::CHERRY_SIGN(), $in));
551 $this->map(Ids::CHERRY_TRAPDOOR, fn(Reader $in) => Helper::decodeTrapdoor(Blocks::CHERRY_TRAPDOOR(), $in));
552 $this->map(Ids::CHERRY_WALL_SIGN, fn(Reader $in) => Helper::decodeWallSign(Blocks::CHERRY_WALL_SIGN(), $in));
553 $this->mapLog(Ids::CHERRY_LOG, Ids::STRIPPED_CHERRY_LOG, fn() => Blocks::CHERRY_LOG());
554 $this->mapSimple(Ids::CHERRY_FENCE, fn() => Blocks::CHERRY_FENCE());
555 $this->mapSimple(Ids::CHERRY_PLANKS, fn() => Blocks::CHERRY_PLANKS());
556 $this->mapSlab(Ids::CHERRY_SLAB, Ids::CHERRY_DOUBLE_SLAB, fn() => Blocks::CHERRY_SLAB());
557 $this->mapStairs(Ids::CHERRY_STAIRS, fn() => Blocks::CHERRY_STAIRS());
558 $this->map(Ids::CHERRY_WOOD, fn(Reader $in) => Helper::decodeLog(Blocks::CHERRY_WOOD(), false, $in));
559 $this->map(Ids::STRIPPED_CHERRY_WOOD, fn(Reader $in) => Helper::decodeLog(Blocks::CHERRY_WOOD(), true, $in));
560
561 $this->map(Ids::CRIMSON_BUTTON, fn(Reader $in) => Helper::decodeButton(Blocks::CRIMSON_BUTTON(), $in));
562 $this->map(Ids::CRIMSON_DOOR, fn(Reader $in) => Helper::decodeDoor(Blocks::CRIMSON_DOOR(), $in));
563 $this->map(Ids::CRIMSON_FENCE_GATE, fn(Reader $in) => Helper::decodeFenceGate(Blocks::CRIMSON_FENCE_GATE(), $in));
564 $this->map(Ids::CRIMSON_PRESSURE_PLATE, fn(Reader $in) => Helper::decodeSimplePressurePlate(Blocks::CRIMSON_PRESSURE_PLATE(), $in));
565 $this->map(Ids::CRIMSON_STANDING_SIGN, fn(Reader $in) => Helper::decodeFloorSign(Blocks::CRIMSON_SIGN(), $in));
566 $this->map(Ids::CRIMSON_TRAPDOOR, fn(Reader $in) => Helper::decodeTrapdoor(Blocks::CRIMSON_TRAPDOOR(), $in));
567 $this->map(Ids::CRIMSON_WALL_SIGN, fn(Reader $in) => Helper::decodeWallSign(Blocks::CRIMSON_WALL_SIGN(), $in));
568 $this->mapLog(Ids::CRIMSON_HYPHAE, Ids::STRIPPED_CRIMSON_HYPHAE, fn() => Blocks::CRIMSON_HYPHAE());
569 $this->mapLog(Ids::CRIMSON_STEM, Ids::STRIPPED_CRIMSON_STEM, fn() => Blocks::CRIMSON_STEM());
570 $this->mapSimple(Ids::CRIMSON_FENCE, fn() => Blocks::CRIMSON_FENCE());
571 $this->mapSimple(Ids::CRIMSON_PLANKS, fn() => Blocks::CRIMSON_PLANKS());
572 $this->mapSlab(Ids::CRIMSON_SLAB, Ids::CRIMSON_DOUBLE_SLAB, fn() => Blocks::CRIMSON_SLAB());
573 $this->mapStairs(Ids::CRIMSON_STAIRS, fn() => Blocks::CRIMSON_STAIRS());
574
575 $this->map(Ids::DARKOAK_STANDING_SIGN, fn(Reader $in) => Helper::decodeFloorSign(Blocks::DARK_OAK_SIGN(), $in));
576 $this->map(Ids::DARKOAK_WALL_SIGN, fn(Reader $in) => Helper::decodeWallSign(Blocks::DARK_OAK_WALL_SIGN(), $in));
577 $this->map(Ids::DARK_OAK_BUTTON, fn(Reader $in) => Helper::decodeButton(Blocks::DARK_OAK_BUTTON(), $in));
578 $this->map(Ids::DARK_OAK_DOOR, fn(Reader $in) => Helper::decodeDoor(Blocks::DARK_OAK_DOOR(), $in));
579 $this->map(Ids::DARK_OAK_FENCE_GATE, fn(Reader $in) => Helper::decodeFenceGate(Blocks::DARK_OAK_FENCE_GATE(), $in));
580 $this->map(Ids::DARK_OAK_PRESSURE_PLATE, fn(Reader $in) => Helper::decodeSimplePressurePlate(Blocks::DARK_OAK_PRESSURE_PLATE(), $in));
581 $this->map(Ids::DARK_OAK_TRAPDOOR, fn(Reader $in) => Helper::decodeTrapdoor(Blocks::DARK_OAK_TRAPDOOR(), $in));
582 $this->mapLog(Ids::DARK_OAK_LOG, Ids::STRIPPED_DARK_OAK_LOG, fn() => Blocks::DARK_OAK_LOG());
583 $this->mapLog(Ids::DARK_OAK_WOOD, Ids::STRIPPED_DARK_OAK_WOOD, fn() => Blocks::DARK_OAK_WOOD());
584 $this->mapSimple(Ids::DARK_OAK_FENCE, fn() => Blocks::DARK_OAK_FENCE());
585 $this->mapSimple(Ids::DARK_OAK_PLANKS, fn() => Blocks::DARK_OAK_PLANKS());
586 $this->mapSlab(Ids::DARK_OAK_SLAB, Ids::DARK_OAK_DOUBLE_SLAB, fn() => Blocks::DARK_OAK_SLAB());
587 $this->mapStairs(Ids::DARK_OAK_STAIRS, fn() => Blocks::DARK_OAK_STAIRS());
588
589 $this->map(Ids::JUNGLE_BUTTON, fn(Reader $in) => Helper::decodeButton(Blocks::JUNGLE_BUTTON(), $in));
590 $this->map(Ids::JUNGLE_DOOR, fn(Reader $in) => Helper::decodeDoor(Blocks::JUNGLE_DOOR(), $in));
591 $this->map(Ids::JUNGLE_FENCE_GATE, fn(Reader $in) => Helper::decodeFenceGate(Blocks::JUNGLE_FENCE_GATE(), $in));
592 $this->map(Ids::JUNGLE_PRESSURE_PLATE, fn(Reader $in) => Helper::decodeSimplePressurePlate(Blocks::JUNGLE_PRESSURE_PLATE(), $in));
593 $this->map(Ids::JUNGLE_STANDING_SIGN, fn(Reader $in) => Helper::decodeFloorSign(Blocks::JUNGLE_SIGN(), $in));
594 $this->map(Ids::JUNGLE_TRAPDOOR, fn(Reader $in) => Helper::decodeTrapdoor(Blocks::JUNGLE_TRAPDOOR(), $in));
595 $this->map(Ids::JUNGLE_WALL_SIGN, fn(Reader $in) => Helper::decodeWallSign(Blocks::JUNGLE_WALL_SIGN(), $in));
596 $this->mapLog(Ids::JUNGLE_LOG, Ids::STRIPPED_JUNGLE_LOG, fn() => Blocks::JUNGLE_LOG());
597 $this->mapLog(Ids::JUNGLE_WOOD, Ids::STRIPPED_JUNGLE_WOOD, fn() => Blocks::JUNGLE_WOOD());
598 $this->mapSimple(Ids::JUNGLE_FENCE, fn() => Blocks::JUNGLE_FENCE());
599 $this->mapSimple(Ids::JUNGLE_PLANKS, fn() => Blocks::JUNGLE_PLANKS());
600 $this->mapSlab(Ids::JUNGLE_SLAB, Ids::JUNGLE_DOUBLE_SLAB, fn() => Blocks::JUNGLE_SLAB());
601 $this->mapStairs(Ids::JUNGLE_STAIRS, fn() => Blocks::JUNGLE_STAIRS());
602
603 $this->map(Ids::MANGROVE_BUTTON, fn(Reader $in) => Helper::decodeButton(Blocks::MANGROVE_BUTTON(), $in));
604 $this->map(Ids::MANGROVE_DOOR, fn(Reader $in) => Helper::decodeDoor(Blocks::MANGROVE_DOOR(), $in));
605 $this->map(Ids::MANGROVE_FENCE_GATE, fn(Reader $in) => Helper::decodeFenceGate(Blocks::MANGROVE_FENCE_GATE(), $in));
606 $this->map(Ids::MANGROVE_PRESSURE_PLATE, fn(Reader $in) => Helper::decodeSimplePressurePlate(Blocks::MANGROVE_PRESSURE_PLATE(), $in));
607 $this->map(Ids::MANGROVE_STANDING_SIGN, fn(Reader $in) => Helper::decodeFloorSign(Blocks::MANGROVE_SIGN(), $in));
608 $this->map(Ids::MANGROVE_TRAPDOOR, fn(Reader $in) => Helper::decodeTrapdoor(Blocks::MANGROVE_TRAPDOOR(), $in));
609 $this->map(Ids::MANGROVE_WALL_SIGN, fn(Reader $in) => Helper::decodeWallSign(Blocks::MANGROVE_WALL_SIGN(), $in));
610 $this->mapLog(Ids::MANGROVE_LOG, Ids::STRIPPED_MANGROVE_LOG, fn() => Blocks::MANGROVE_LOG());
611 $this->mapSimple(Ids::MANGROVE_FENCE, fn() => Blocks::MANGROVE_FENCE());
612 $this->mapSimple(Ids::MANGROVE_PLANKS, fn() => Blocks::MANGROVE_PLANKS());
613 $this->mapSlab(Ids::MANGROVE_SLAB, Ids::MANGROVE_DOUBLE_SLAB, fn() => Blocks::MANGROVE_SLAB());
614 $this->mapStairs(Ids::MANGROVE_STAIRS, fn() => Blocks::MANGROVE_STAIRS());
615 $this->map(Ids::MANGROVE_WOOD, fn(Reader $in) => Helper::decodeLog(Blocks::MANGROVE_WOOD(), false, $in));
616 $this->map(Ids::STRIPPED_MANGROVE_WOOD, fn(Reader $in) => Helper::decodeLog(Blocks::MANGROVE_WOOD(), true, $in));
617
618 //oak - due to age, many of these don't specify "oak", making for confusing reading
619 $this->map(Ids::WOODEN_BUTTON, fn(Reader $in) => Helper::decodeButton(Blocks::OAK_BUTTON(), $in));
620 $this->map(Ids::WOODEN_DOOR, fn(Reader $in) => Helper::decodeDoor(Blocks::OAK_DOOR(), $in));
621 $this->map(Ids::FENCE_GATE, fn(Reader $in) => Helper::decodeFenceGate(Blocks::OAK_FENCE_GATE(), $in));
622 $this->map(Ids::WOODEN_PRESSURE_PLATE, fn(Reader $in) => Helper::decodeSimplePressurePlate(Blocks::OAK_PRESSURE_PLATE(), $in));
623 $this->map(Ids::STANDING_SIGN, fn(Reader $in) => Helper::decodeFloorSign(Blocks::OAK_SIGN(), $in));
624 $this->map(Ids::TRAPDOOR, fn(Reader $in) => Helper::decodeTrapdoor(Blocks::OAK_TRAPDOOR(), $in));
625 $this->map(Ids::WALL_SIGN, fn(Reader $in) => Helper::decodeWallSign(Blocks::OAK_WALL_SIGN(), $in));
626 $this->mapLog(Ids::OAK_LOG, Ids::STRIPPED_OAK_LOG, fn() => Blocks::OAK_LOG());
627 $this->mapLog(Ids::OAK_WOOD, Ids::STRIPPED_OAK_WOOD, fn() => Blocks::OAK_WOOD());
628 $this->mapSimple(Ids::OAK_FENCE, fn() => Blocks::OAK_FENCE());
629 $this->mapSimple(Ids::OAK_PLANKS, fn() => Blocks::OAK_PLANKS());
630 $this->mapSlab(Ids::OAK_SLAB, Ids::OAK_DOUBLE_SLAB, fn() => Blocks::OAK_SLAB());
631 $this->mapStairs(Ids::OAK_STAIRS, fn() => Blocks::OAK_STAIRS());
632
633 $this->map(Ids::PALE_OAK_BUTTON, fn(Reader $in) => Helper::decodeButton(Blocks::PALE_OAK_BUTTON(), $in));
634 $this->map(Ids::PALE_OAK_DOOR, fn(Reader $in) => Helper::decodeDoor(Blocks::PALE_OAK_DOOR(), $in));
635 $this->map(Ids::PALE_OAK_FENCE_GATE, fn(Reader $in) => Helper::decodeFenceGate(Blocks::PALE_OAK_FENCE_GATE(), $in));
636 $this->map(Ids::PALE_OAK_PRESSURE_PLATE, fn(Reader $in) => Helper::decodeSimplePressurePlate(Blocks::PALE_OAK_PRESSURE_PLATE(), $in));
637 $this->map(Ids::PALE_OAK_STANDING_SIGN, fn(Reader $in) => Helper::decodeFloorSign(Blocks::PALE_OAK_SIGN(), $in));
638 $this->map(Ids::PALE_OAK_TRAPDOOR, fn(Reader $in) => Helper::decodeTrapdoor(Blocks::PALE_OAK_TRAPDOOR(), $in));
639 $this->map(Ids::PALE_OAK_WALL_SIGN, fn(Reader $in) => Helper::decodeWallSign(Blocks::PALE_OAK_WALL_SIGN(), $in));
640 $this->mapLog(Ids::PALE_OAK_LOG, Ids::STRIPPED_PALE_OAK_LOG, fn() => Blocks::PALE_OAK_LOG());
641 $this->mapLog(Ids::PALE_OAK_WOOD, Ids::STRIPPED_PALE_OAK_WOOD, fn() => Blocks::PALE_OAK_WOOD());
642 $this->mapSimple(Ids::PALE_OAK_FENCE, fn() => Blocks::PALE_OAK_FENCE());
643 $this->mapSimple(Ids::PALE_OAK_PLANKS, fn() => Blocks::PALE_OAK_PLANKS());
644 $this->mapSlab(Ids::PALE_OAK_SLAB, Ids::PALE_OAK_DOUBLE_SLAB, fn() => Blocks::PALE_OAK_SLAB());
645 $this->mapStairs(Ids::PALE_OAK_STAIRS, fn() => Blocks::PALE_OAK_STAIRS());
646
647 $this->map(Ids::SPRUCE_BUTTON, fn(Reader $in) => Helper::decodeButton(Blocks::SPRUCE_BUTTON(), $in));
648 $this->map(Ids::SPRUCE_DOOR, fn(Reader $in) => Helper::decodeDoor(Blocks::SPRUCE_DOOR(), $in));
649 $this->map(Ids::SPRUCE_FENCE_GATE, fn(Reader $in) => Helper::decodeFenceGate(Blocks::SPRUCE_FENCE_GATE(), $in));
650 $this->map(Ids::SPRUCE_PRESSURE_PLATE, fn(Reader $in) => Helper::decodeSimplePressurePlate(Blocks::SPRUCE_PRESSURE_PLATE(), $in));
651 $this->map(Ids::SPRUCE_STANDING_SIGN, fn(Reader $in) => Helper::decodeFloorSign(Blocks::SPRUCE_SIGN(), $in));
652 $this->map(Ids::SPRUCE_TRAPDOOR, fn(Reader $in) => Helper::decodeTrapdoor(Blocks::SPRUCE_TRAPDOOR(), $in));
653 $this->map(Ids::SPRUCE_WALL_SIGN, fn(Reader $in) => Helper::decodeWallSign(Blocks::SPRUCE_WALL_SIGN(), $in));
654 $this->mapLog(Ids::SPRUCE_LOG, Ids::STRIPPED_SPRUCE_LOG, fn() => Blocks::SPRUCE_LOG());
655 $this->mapLog(Ids::SPRUCE_WOOD, Ids::STRIPPED_SPRUCE_WOOD, fn() => Blocks::SPRUCE_WOOD());
656 $this->mapSimple(Ids::SPRUCE_FENCE, fn() => Blocks::SPRUCE_FENCE());
657 $this->mapSimple(Ids::SPRUCE_PLANKS, fn() => Blocks::SPRUCE_PLANKS());
658 $this->mapSlab(Ids::SPRUCE_SLAB, Ids::SPRUCE_DOUBLE_SLAB, fn() => Blocks::SPRUCE_SLAB());
659 $this->mapStairs(Ids::SPRUCE_STAIRS, fn() => Blocks::SPRUCE_STAIRS());
660
661 $this->map(Ids::WARPED_BUTTON, fn(Reader $in) => Helper::decodeButton(Blocks::WARPED_BUTTON(), $in));
662 $this->map(Ids::WARPED_DOOR, fn(Reader $in) => Helper::decodeDoor(Blocks::WARPED_DOOR(), $in));
663 $this->map(Ids::WARPED_FENCE_GATE, fn(Reader $in) => Helper::decodeFenceGate(Blocks::WARPED_FENCE_GATE(), $in));
664 $this->map(Ids::WARPED_PRESSURE_PLATE, fn(Reader $in) => Helper::decodeSimplePressurePlate(Blocks::WARPED_PRESSURE_PLATE(), $in));
665 $this->map(Ids::WARPED_STANDING_SIGN, fn(Reader $in) => Helper::decodeFloorSign(Blocks::WARPED_SIGN(), $in));
666 $this->map(Ids::WARPED_TRAPDOOR, fn(Reader $in) => Helper::decodeTrapdoor(Blocks::WARPED_TRAPDOOR(), $in));
667 $this->map(Ids::WARPED_WALL_SIGN, fn(Reader $in) => Helper::decodeWallSign(Blocks::WARPED_WALL_SIGN(), $in));
668 $this->mapLog(Ids::WARPED_HYPHAE, Ids::STRIPPED_WARPED_HYPHAE, fn() => Blocks::WARPED_HYPHAE());
669 $this->mapLog(Ids::WARPED_STEM, Ids::STRIPPED_WARPED_STEM, fn() => Blocks::WARPED_STEM());
670 $this->mapSimple(Ids::WARPED_FENCE, fn() => Blocks::WARPED_FENCE());
671 $this->mapSimple(Ids::WARPED_PLANKS, fn() => Blocks::WARPED_PLANKS());
672 $this->mapSlab(Ids::WARPED_SLAB, Ids::WARPED_DOUBLE_SLAB, fn() => Blocks::WARPED_SLAB());
673 $this->mapStairs(Ids::WARPED_STAIRS, fn() => Blocks::WARPED_STAIRS());
674 }
675
676 private function registerLeavesDeserializers() : void{
677 $this->map(Ids::ACACIA_LEAVES, fn(Reader $in) => Helper::decodeLeaves(Blocks::ACACIA_LEAVES(), $in));
678 $this->map(Ids::AZALEA_LEAVES, fn(Reader $in) => Helper::decodeLeaves(Blocks::AZALEA_LEAVES(), $in));
679 $this->map(Ids::AZALEA_LEAVES_FLOWERED, fn(Reader $in) => Helper::decodeLeaves(Blocks::FLOWERING_AZALEA_LEAVES(), $in));
680 $this->map(Ids::BIRCH_LEAVES, fn(Reader $in) => Helper::decodeLeaves(Blocks::BIRCH_LEAVES(), $in));
681 $this->map(Ids::CHERRY_LEAVES, fn(Reader $in) => Helper::decodeLeaves(Blocks::CHERRY_LEAVES(), $in));
682 $this->map(Ids::DARK_OAK_LEAVES, fn(Reader $in) => Helper::decodeLeaves(Blocks::DARK_OAK_LEAVES(), $in));
683 $this->map(Ids::JUNGLE_LEAVES, fn(Reader $in) => Helper::decodeLeaves(Blocks::JUNGLE_LEAVES(), $in));
684 $this->map(Ids::MANGROVE_LEAVES, fn(Reader $in) => Helper::decodeLeaves(Blocks::MANGROVE_LEAVES(), $in));
685 $this->map(Ids::OAK_LEAVES, fn(Reader $in) => Helper::decodeLeaves(Blocks::OAK_LEAVES(), $in));
686 $this->map(Ids::PALE_OAK_LEAVES, fn(Reader $in) => Helper::decodeLeaves(Blocks::PALE_OAK_LEAVES(), $in));
687 $this->map(Ids::SPRUCE_LEAVES, fn(Reader $in) => Helper::decodeLeaves(Blocks::SPRUCE_LEAVES(), $in));
688 }
689
690 private function registerSaplingDeserializers() : void{
691 foreach([
692 Ids::ACACIA_SAPLING => fn() => Blocks::ACACIA_SAPLING(),
693 Ids::BIRCH_SAPLING => fn() => Blocks::BIRCH_SAPLING(),
694 Ids::DARK_OAK_SAPLING => fn() => Blocks::DARK_OAK_SAPLING(),
695 Ids::JUNGLE_SAPLING => fn() => Blocks::JUNGLE_SAPLING(),
696 Ids::OAK_SAPLING => fn() => Blocks::OAK_SAPLING(),
697 Ids::SPRUCE_SAPLING => fn() => Blocks::SPRUCE_SAPLING(),
698 ] as $id => $getBlock){
699 $this->map($id, fn(Reader $in) => Helper::decodeSapling($getBlock(), $in));
700 }
701 }
702
703 private function registerLightDeserializers() : void{
704 foreach([
705 Ids::LIGHT_BLOCK_0 => 0,
706 Ids::LIGHT_BLOCK_1 => 1,
707 Ids::LIGHT_BLOCK_2 => 2,
708 Ids::LIGHT_BLOCK_3 => 3,
709 Ids::LIGHT_BLOCK_4 => 4,
710 Ids::LIGHT_BLOCK_5 => 5,
711 Ids::LIGHT_BLOCK_6 => 6,
712 Ids::LIGHT_BLOCK_7 => 7,
713 Ids::LIGHT_BLOCK_8 => 8,
714 Ids::LIGHT_BLOCK_9 => 9,
715 Ids::LIGHT_BLOCK_10 => 10,
716 Ids::LIGHT_BLOCK_11 => 11,
717 Ids::LIGHT_BLOCK_12 => 12,
718 Ids::LIGHT_BLOCK_13 => 13,
719 Ids::LIGHT_BLOCK_14 => 14,
720 Ids::LIGHT_BLOCK_15 => 15,
721 ] as $id => $level){
722 $this->mapSimple($id, fn() => Blocks::LIGHT()->setLightLevel($level));
723 }
724 }
725
726 private function registerMobHeadDeserializers() : void{
727 foreach([
728 Ids::CREEPER_HEAD => MobHeadType::CREEPER,
729 Ids::DRAGON_HEAD => MobHeadType::DRAGON,
730 Ids::PIGLIN_HEAD => MobHeadType::PIGLIN,
731 Ids::PLAYER_HEAD => MobHeadType::PLAYER,
732 Ids::SKELETON_SKULL => MobHeadType::SKELETON,
733 Ids::WITHER_SKELETON_SKULL => MobHeadType::WITHER_SKELETON,
734 Ids::ZOMBIE_HEAD => MobHeadType::ZOMBIE
735 ] as $id => $mobHeadType){
736 $this->map($id, fn(Reader $in) => Blocks::MOB_HEAD()->setMobHeadType($mobHeadType)->setFacing($in->readFacingWithoutDown()));
737 }
738 }
739
743 private function mapCopper(
744 string $normalId,
745 string $waxedNormalId,
746 string $exposedId,
747 string $waxedExposedId,
748 string $weatheredId,
749 string $waxedWeatheredId,
750 string $oxidizedId,
751 string $waxedOxidizedId,
752 \Closure $deserializer
753 ) : void{
754 foreach(Utils::stringifyKeys([
755 $normalId => [CopperOxidation::NONE, false],
756 $waxedNormalId => [CopperOxidation::NONE, true],
757 $exposedId => [CopperOxidation::EXPOSED, false],
758 $waxedExposedId => [CopperOxidation::EXPOSED, true],
759 $weatheredId => [CopperOxidation::WEATHERED, false],
760 $waxedWeatheredId => [CopperOxidation::WEATHERED, true],
761 $oxidizedId => [CopperOxidation::OXIDIZED, false],
762 $waxedOxidizedId => [CopperOxidation::OXIDIZED, true],
763 ]) as $id => [$oxidation, $waxed]){
764 $this->map($id, fn(Reader $in) => $deserializer($in)->setOxidation($oxidation)->setWaxed($waxed));
765 }
766 }
767
768 private function registerCopperDeserializers() : void{
769 $this->mapCopper(
770 Ids::CUT_COPPER_SLAB,
771 Ids::WAXED_CUT_COPPER_SLAB,
772 Ids::EXPOSED_CUT_COPPER_SLAB,
773 Ids::WAXED_EXPOSED_CUT_COPPER_SLAB,
774 Ids::WEATHERED_CUT_COPPER_SLAB,
775 Ids::WAXED_WEATHERED_CUT_COPPER_SLAB,
776 Ids::OXIDIZED_CUT_COPPER_SLAB,
777 Ids::WAXED_OXIDIZED_CUT_COPPER_SLAB,
778 fn(Reader $in) => Helper::decodeSingleSlab(Blocks::CUT_COPPER_SLAB(), $in)
779 );
780 $this->mapCopper(
781 Ids::DOUBLE_CUT_COPPER_SLAB,
782 Ids::WAXED_DOUBLE_CUT_COPPER_SLAB,
783 Ids::EXPOSED_DOUBLE_CUT_COPPER_SLAB,
784 Ids::WAXED_EXPOSED_DOUBLE_CUT_COPPER_SLAB,
785 Ids::WEATHERED_DOUBLE_CUT_COPPER_SLAB,
786 Ids::WAXED_WEATHERED_DOUBLE_CUT_COPPER_SLAB,
787 Ids::OXIDIZED_DOUBLE_CUT_COPPER_SLAB,
788 Ids::WAXED_OXIDIZED_DOUBLE_CUT_COPPER_SLAB,
789 fn(Reader $in) => Helper::decodeDoubleSlab(Blocks::CUT_COPPER_SLAB(), $in)
790 );
791
792 $this->mapCopper(
793 Ids::COPPER_BULB,
794 Ids::WAXED_COPPER_BULB,
795 Ids::EXPOSED_COPPER_BULB,
796 Ids::WAXED_EXPOSED_COPPER_BULB,
797 Ids::WEATHERED_COPPER_BULB,
798 Ids::WAXED_WEATHERED_COPPER_BULB,
799 Ids::OXIDIZED_COPPER_BULB,
800 Ids::WAXED_OXIDIZED_COPPER_BULB,
801 fn(Reader $in) => Blocks::COPPER_BULB()
802 ->setLit($in->readBool(StateNames::LIT))
803 ->setPowered($in->readBool(StateNames::POWERED_BIT))
804 );
805 $this->mapCopper(
806 Ids::COPPER_DOOR,
807 Ids::WAXED_COPPER_DOOR,
808 Ids::EXPOSED_COPPER_DOOR,
809 Ids::WAXED_EXPOSED_COPPER_DOOR,
810 Ids::WEATHERED_COPPER_DOOR,
811 Ids::WAXED_WEATHERED_COPPER_DOOR,
812 Ids::OXIDIZED_COPPER_DOOR,
813 Ids::WAXED_OXIDIZED_COPPER_DOOR,
814 fn(Reader $in) => Helper::decodeDoor(Blocks::COPPER_DOOR(), $in)
815 );
816 $this->mapCopper(
817 Ids::COPPER_TRAPDOOR,
818 Ids::WAXED_COPPER_TRAPDOOR,
819 Ids::EXPOSED_COPPER_TRAPDOOR,
820 Ids::WAXED_EXPOSED_COPPER_TRAPDOOR,
821 Ids::WEATHERED_COPPER_TRAPDOOR,
822 Ids::WAXED_WEATHERED_COPPER_TRAPDOOR,
823 Ids::OXIDIZED_COPPER_TRAPDOOR,
824 Ids::WAXED_OXIDIZED_COPPER_TRAPDOOR,
825 fn(Reader $in) => Helper::decodeTrapdoor(Blocks::COPPER_TRAPDOOR(), $in)
826 );
827 $this->mapCopper(
828 Ids::COPPER_BLOCK,
829 Ids::WAXED_COPPER,
830 Ids::EXPOSED_COPPER,
831 Ids::WAXED_EXPOSED_COPPER,
832 Ids::WEATHERED_COPPER,
833 Ids::WAXED_WEATHERED_COPPER,
834 Ids::OXIDIZED_COPPER,
835 Ids::WAXED_OXIDIZED_COPPER,
836 fn(Reader $in) => Blocks::COPPER()
837 );
838 $this->mapCopper(
839 Ids::CHISELED_COPPER,
840 Ids::WAXED_CHISELED_COPPER,
841 Ids::EXPOSED_CHISELED_COPPER,
842 Ids::WAXED_EXPOSED_CHISELED_COPPER,
843 Ids::WEATHERED_CHISELED_COPPER,
844 Ids::WAXED_WEATHERED_CHISELED_COPPER,
845 Ids::OXIDIZED_CHISELED_COPPER,
846 Ids::WAXED_OXIDIZED_CHISELED_COPPER,
847 fn(Reader $in) => Blocks::CHISELED_COPPER()
848 );
849 $this->mapCopper(
850 Ids::COPPER_GRATE,
851 Ids::WAXED_COPPER_GRATE,
852 Ids::EXPOSED_COPPER_GRATE,
853 Ids::WAXED_EXPOSED_COPPER_GRATE,
854 Ids::WEATHERED_COPPER_GRATE,
855 Ids::WAXED_WEATHERED_COPPER_GRATE,
856 Ids::OXIDIZED_COPPER_GRATE,
857 Ids::WAXED_OXIDIZED_COPPER_GRATE,
858 fn(Reader $in) => Blocks::COPPER_GRATE()
859 );
860 $this->mapCopper(
861 Ids::CUT_COPPER,
862 Ids::WAXED_CUT_COPPER,
863 Ids::EXPOSED_CUT_COPPER,
864 Ids::WAXED_EXPOSED_CUT_COPPER,
865 Ids::WEATHERED_CUT_COPPER,
866 Ids::WAXED_WEATHERED_CUT_COPPER,
867 Ids::OXIDIZED_CUT_COPPER,
868 Ids::WAXED_OXIDIZED_CUT_COPPER,
869 fn(Reader $in) => Blocks::CUT_COPPER()
870 );
871 $this->mapCopper(
872 Ids::CUT_COPPER_STAIRS,
873 Ids::WAXED_CUT_COPPER_STAIRS,
874 Ids::EXPOSED_CUT_COPPER_STAIRS,
875 Ids::WAXED_EXPOSED_CUT_COPPER_STAIRS,
876 Ids::WEATHERED_CUT_COPPER_STAIRS,
877 Ids::WAXED_WEATHERED_CUT_COPPER_STAIRS,
878 Ids::OXIDIZED_CUT_COPPER_STAIRS,
879 Ids::WAXED_OXIDIZED_CUT_COPPER_STAIRS,
880 fn(Reader $in) => Helper::decodeStairs(Blocks::CUT_COPPER_STAIRS(), $in)
881 );
882 }
883
884 private function registerSimpleDeserializers() : void{
885 $this->mapSimple(Ids::AIR, fn() => Blocks::AIR());
886 $this->mapSimple(Ids::AMETHYST_BLOCK, fn() => Blocks::AMETHYST());
887 $this->mapSimple(Ids::ANCIENT_DEBRIS, fn() => Blocks::ANCIENT_DEBRIS());
888 $this->mapSimple(Ids::ANDESITE, fn() => Blocks::ANDESITE());
889 $this->mapSimple(Ids::BARRIER, fn() => Blocks::BARRIER());
890 $this->mapSimple(Ids::BEACON, fn() => Blocks::BEACON());
891 $this->mapSimple(Ids::BLACKSTONE, fn() => Blocks::BLACKSTONE());
892 $this->mapSimple(Ids::BLUE_ICE, fn() => Blocks::BLUE_ICE());
893 $this->mapSimple(Ids::BOOKSHELF, fn() => Blocks::BOOKSHELF());
894 $this->mapSimple(Ids::BRICK_BLOCK, fn() => Blocks::BRICKS());
895 $this->mapSimple(Ids::BROWN_MUSHROOM, fn() => Blocks::BROWN_MUSHROOM());
896 $this->mapSimple(Ids::BUDDING_AMETHYST, fn() => Blocks::BUDDING_AMETHYST());
897 $this->mapSimple(Ids::CALCITE, fn() => Blocks::CALCITE());
898 $this->mapSimple(Ids::CARTOGRAPHY_TABLE, fn() => Blocks::CARTOGRAPHY_TABLE());
899 $this->mapSimple(Ids::CHEMICAL_HEAT, fn() => Blocks::CHEMICAL_HEAT());
900 $this->mapSimple(Ids::CHISELED_DEEPSLATE, fn() => Blocks::CHISELED_DEEPSLATE());
901 $this->mapSimple(Ids::CHISELED_NETHER_BRICKS, fn() => Blocks::CHISELED_NETHER_BRICKS());
902 $this->mapSimple(Ids::CHISELED_POLISHED_BLACKSTONE, fn() => Blocks::CHISELED_POLISHED_BLACKSTONE());
903 $this->mapSimple(Ids::CHISELED_RED_SANDSTONE, fn() => Blocks::CHISELED_RED_SANDSTONE());
904 $this->mapSimple(Ids::CHISELED_RESIN_BRICKS, fn() => Blocks::CHISELED_RESIN_BRICKS());
905 $this->mapSimple(Ids::CHISELED_SANDSTONE, fn() => Blocks::CHISELED_SANDSTONE());
906 $this->mapSimple(Ids::CHISELED_STONE_BRICKS, fn() => Blocks::CHISELED_STONE_BRICKS());
907 $this->mapSimple(Ids::CHISELED_TUFF, fn() => Blocks::CHISELED_TUFF());
908 $this->mapSimple(Ids::CHISELED_TUFF_BRICKS, fn() => Blocks::CHISELED_TUFF_BRICKS());
909 $this->mapSimple(Ids::CHORUS_PLANT, fn() => Blocks::CHORUS_PLANT());
910 $this->mapSimple(Ids::CLAY, fn() => Blocks::CLAY());
911 $this->mapSimple(Ids::COAL_BLOCK, fn() => Blocks::COAL());
912 $this->mapSimple(Ids::COAL_ORE, fn() => Blocks::COAL_ORE());
913 $this->mapSimple(Ids::COBBLED_DEEPSLATE, fn() => Blocks::COBBLED_DEEPSLATE());
914 $this->mapSimple(Ids::COBBLESTONE, fn() => Blocks::COBBLESTONE());
915 $this->mapSimple(Ids::COPPER_ORE, fn() => Blocks::COPPER_ORE());
916 $this->mapSimple(Ids::CRACKED_DEEPSLATE_BRICKS, fn() => Blocks::CRACKED_DEEPSLATE_BRICKS());
917 $this->mapSimple(Ids::CRACKED_DEEPSLATE_TILES, fn() => Blocks::CRACKED_DEEPSLATE_TILES());
918 $this->mapSimple(Ids::CRACKED_NETHER_BRICKS, fn() => Blocks::CRACKED_NETHER_BRICKS());
919 $this->mapSimple(Ids::CRACKED_POLISHED_BLACKSTONE_BRICKS, fn() => Blocks::CRACKED_POLISHED_BLACKSTONE_BRICKS());
920 $this->mapSimple(Ids::CRACKED_STONE_BRICKS, fn() => Blocks::CRACKED_STONE_BRICKS());
921 $this->mapSimple(Ids::CRAFTING_TABLE, fn() => Blocks::CRAFTING_TABLE());
922 $this->mapSimple(Ids::CRIMSON_ROOTS, fn() => Blocks::CRIMSON_ROOTS());
923 $this->mapSimple(Ids::CRYING_OBSIDIAN, fn() => Blocks::CRYING_OBSIDIAN());
924 $this->mapSimple(Ids::CUT_RED_SANDSTONE, fn() => Blocks::CUT_RED_SANDSTONE());
925 $this->mapSimple(Ids::CUT_SANDSTONE, fn() => Blocks::CUT_SANDSTONE());
926 $this->mapSimple(Ids::DARK_PRISMARINE, fn() => Blocks::DARK_PRISMARINE());
927 $this->mapSimple(Ids::DEADBUSH, fn() => Blocks::DEAD_BUSH());
928 $this->mapSimple(Ids::DEEPSLATE_BRICKS, fn() => Blocks::DEEPSLATE_BRICKS());
929 $this->mapSimple(Ids::DEEPSLATE_COAL_ORE, fn() => Blocks::DEEPSLATE_COAL_ORE());
930 $this->mapSimple(Ids::DEEPSLATE_COPPER_ORE, fn() => Blocks::DEEPSLATE_COPPER_ORE());
931 $this->mapSimple(Ids::DEEPSLATE_DIAMOND_ORE, fn() => Blocks::DEEPSLATE_DIAMOND_ORE());
932 $this->mapSimple(Ids::DEEPSLATE_EMERALD_ORE, fn() => Blocks::DEEPSLATE_EMERALD_ORE());
933 $this->mapSimple(Ids::DEEPSLATE_GOLD_ORE, fn() => Blocks::DEEPSLATE_GOLD_ORE());
934 $this->mapSimple(Ids::DEEPSLATE_IRON_ORE, fn() => Blocks::DEEPSLATE_IRON_ORE());
935 $this->mapSimple(Ids::DEEPSLATE_LAPIS_ORE, fn() => Blocks::DEEPSLATE_LAPIS_LAZULI_ORE());
936 $this->mapSimple(Ids::DEEPSLATE_TILES, fn() => Blocks::DEEPSLATE_TILES());
937 $this->mapSimple(Ids::DIAMOND_BLOCK, fn() => Blocks::DIAMOND());
938 $this->mapSimple(Ids::DIAMOND_ORE, fn() => Blocks::DIAMOND_ORE());
939 $this->mapSimple(Ids::DIORITE, fn() => Blocks::DIORITE());
940 $this->mapSimple(Ids::DRAGON_EGG, fn() => Blocks::DRAGON_EGG());
941 $this->mapSimple(Ids::DRIED_KELP_BLOCK, fn() => Blocks::DRIED_KELP());
942 $this->mapSimple(Ids::ELEMENT_0, fn() => Blocks::ELEMENT_ZERO());
943 $this->mapSimple(Ids::ELEMENT_1, fn() => Blocks::ELEMENT_HYDROGEN());
944 $this->mapSimple(Ids::ELEMENT_10, fn() => Blocks::ELEMENT_NEON());
945 $this->mapSimple(Ids::ELEMENT_100, fn() => Blocks::ELEMENT_FERMIUM());
946 $this->mapSimple(Ids::ELEMENT_101, fn() => Blocks::ELEMENT_MENDELEVIUM());
947 $this->mapSimple(Ids::ELEMENT_102, fn() => Blocks::ELEMENT_NOBELIUM());
948 $this->mapSimple(Ids::ELEMENT_103, fn() => Blocks::ELEMENT_LAWRENCIUM());
949 $this->mapSimple(Ids::ELEMENT_104, fn() => Blocks::ELEMENT_RUTHERFORDIUM());
950 $this->mapSimple(Ids::ELEMENT_105, fn() => Blocks::ELEMENT_DUBNIUM());
951 $this->mapSimple(Ids::ELEMENT_106, fn() => Blocks::ELEMENT_SEABORGIUM());
952 $this->mapSimple(Ids::ELEMENT_107, fn() => Blocks::ELEMENT_BOHRIUM());
953 $this->mapSimple(Ids::ELEMENT_108, fn() => Blocks::ELEMENT_HASSIUM());
954 $this->mapSimple(Ids::ELEMENT_109, fn() => Blocks::ELEMENT_MEITNERIUM());
955 $this->mapSimple(Ids::ELEMENT_11, fn() => Blocks::ELEMENT_SODIUM());
956 $this->mapSimple(Ids::ELEMENT_110, fn() => Blocks::ELEMENT_DARMSTADTIUM());
957 $this->mapSimple(Ids::ELEMENT_111, fn() => Blocks::ELEMENT_ROENTGENIUM());
958 $this->mapSimple(Ids::ELEMENT_112, fn() => Blocks::ELEMENT_COPERNICIUM());
959 $this->mapSimple(Ids::ELEMENT_113, fn() => Blocks::ELEMENT_NIHONIUM());
960 $this->mapSimple(Ids::ELEMENT_114, fn() => Blocks::ELEMENT_FLEROVIUM());
961 $this->mapSimple(Ids::ELEMENT_115, fn() => Blocks::ELEMENT_MOSCOVIUM());
962 $this->mapSimple(Ids::ELEMENT_116, fn() => Blocks::ELEMENT_LIVERMORIUM());
963 $this->mapSimple(Ids::ELEMENT_117, fn() => Blocks::ELEMENT_TENNESSINE());
964 $this->mapSimple(Ids::ELEMENT_118, fn() => Blocks::ELEMENT_OGANESSON());
965 $this->mapSimple(Ids::ELEMENT_12, fn() => Blocks::ELEMENT_MAGNESIUM());
966 $this->mapSimple(Ids::ELEMENT_13, fn() => Blocks::ELEMENT_ALUMINUM());
967 $this->mapSimple(Ids::ELEMENT_14, fn() => Blocks::ELEMENT_SILICON());
968 $this->mapSimple(Ids::ELEMENT_15, fn() => Blocks::ELEMENT_PHOSPHORUS());
969 $this->mapSimple(Ids::ELEMENT_16, fn() => Blocks::ELEMENT_SULFUR());
970 $this->mapSimple(Ids::ELEMENT_17, fn() => Blocks::ELEMENT_CHLORINE());
971 $this->mapSimple(Ids::ELEMENT_18, fn() => Blocks::ELEMENT_ARGON());
972 $this->mapSimple(Ids::ELEMENT_19, fn() => Blocks::ELEMENT_POTASSIUM());
973 $this->mapSimple(Ids::ELEMENT_2, fn() => Blocks::ELEMENT_HELIUM());
974 $this->mapSimple(Ids::ELEMENT_20, fn() => Blocks::ELEMENT_CALCIUM());
975 $this->mapSimple(Ids::ELEMENT_21, fn() => Blocks::ELEMENT_SCANDIUM());
976 $this->mapSimple(Ids::ELEMENT_22, fn() => Blocks::ELEMENT_TITANIUM());
977 $this->mapSimple(Ids::ELEMENT_23, fn() => Blocks::ELEMENT_VANADIUM());
978 $this->mapSimple(Ids::ELEMENT_24, fn() => Blocks::ELEMENT_CHROMIUM());
979 $this->mapSimple(Ids::ELEMENT_25, fn() => Blocks::ELEMENT_MANGANESE());
980 $this->mapSimple(Ids::ELEMENT_26, fn() => Blocks::ELEMENT_IRON());
981 $this->mapSimple(Ids::ELEMENT_27, fn() => Blocks::ELEMENT_COBALT());
982 $this->mapSimple(Ids::ELEMENT_28, fn() => Blocks::ELEMENT_NICKEL());
983 $this->mapSimple(Ids::ELEMENT_29, fn() => Blocks::ELEMENT_COPPER());
984 $this->mapSimple(Ids::ELEMENT_3, fn() => Blocks::ELEMENT_LITHIUM());
985 $this->mapSimple(Ids::ELEMENT_30, fn() => Blocks::ELEMENT_ZINC());
986 $this->mapSimple(Ids::ELEMENT_31, fn() => Blocks::ELEMENT_GALLIUM());
987 $this->mapSimple(Ids::ELEMENT_32, fn() => Blocks::ELEMENT_GERMANIUM());
988 $this->mapSimple(Ids::ELEMENT_33, fn() => Blocks::ELEMENT_ARSENIC());
989 $this->mapSimple(Ids::ELEMENT_34, fn() => Blocks::ELEMENT_SELENIUM());
990 $this->mapSimple(Ids::ELEMENT_35, fn() => Blocks::ELEMENT_BROMINE());
991 $this->mapSimple(Ids::ELEMENT_36, fn() => Blocks::ELEMENT_KRYPTON());
992 $this->mapSimple(Ids::ELEMENT_37, fn() => Blocks::ELEMENT_RUBIDIUM());
993 $this->mapSimple(Ids::ELEMENT_38, fn() => Blocks::ELEMENT_STRONTIUM());
994 $this->mapSimple(Ids::ELEMENT_39, fn() => Blocks::ELEMENT_YTTRIUM());
995 $this->mapSimple(Ids::ELEMENT_4, fn() => Blocks::ELEMENT_BERYLLIUM());
996 $this->mapSimple(Ids::ELEMENT_40, fn() => Blocks::ELEMENT_ZIRCONIUM());
997 $this->mapSimple(Ids::ELEMENT_41, fn() => Blocks::ELEMENT_NIOBIUM());
998 $this->mapSimple(Ids::ELEMENT_42, fn() => Blocks::ELEMENT_MOLYBDENUM());
999 $this->mapSimple(Ids::ELEMENT_43, fn() => Blocks::ELEMENT_TECHNETIUM());
1000 $this->mapSimple(Ids::ELEMENT_44, fn() => Blocks::ELEMENT_RUTHENIUM());
1001 $this->mapSimple(Ids::ELEMENT_45, fn() => Blocks::ELEMENT_RHODIUM());
1002 $this->mapSimple(Ids::ELEMENT_46, fn() => Blocks::ELEMENT_PALLADIUM());
1003 $this->mapSimple(Ids::ELEMENT_47, fn() => Blocks::ELEMENT_SILVER());
1004 $this->mapSimple(Ids::ELEMENT_48, fn() => Blocks::ELEMENT_CADMIUM());
1005 $this->mapSimple(Ids::ELEMENT_49, fn() => Blocks::ELEMENT_INDIUM());
1006 $this->mapSimple(Ids::ELEMENT_5, fn() => Blocks::ELEMENT_BORON());
1007 $this->mapSimple(Ids::ELEMENT_50, fn() => Blocks::ELEMENT_TIN());
1008 $this->mapSimple(Ids::ELEMENT_51, fn() => Blocks::ELEMENT_ANTIMONY());
1009 $this->mapSimple(Ids::ELEMENT_52, fn() => Blocks::ELEMENT_TELLURIUM());
1010 $this->mapSimple(Ids::ELEMENT_53, fn() => Blocks::ELEMENT_IODINE());
1011 $this->mapSimple(Ids::ELEMENT_54, fn() => Blocks::ELEMENT_XENON());
1012 $this->mapSimple(Ids::ELEMENT_55, fn() => Blocks::ELEMENT_CESIUM());
1013 $this->mapSimple(Ids::ELEMENT_56, fn() => Blocks::ELEMENT_BARIUM());
1014 $this->mapSimple(Ids::ELEMENT_57, fn() => Blocks::ELEMENT_LANTHANUM());
1015 $this->mapSimple(Ids::ELEMENT_58, fn() => Blocks::ELEMENT_CERIUM());
1016 $this->mapSimple(Ids::ELEMENT_59, fn() => Blocks::ELEMENT_PRASEODYMIUM());
1017 $this->mapSimple(Ids::ELEMENT_6, fn() => Blocks::ELEMENT_CARBON());
1018 $this->mapSimple(Ids::ELEMENT_60, fn() => Blocks::ELEMENT_NEODYMIUM());
1019 $this->mapSimple(Ids::ELEMENT_61, fn() => Blocks::ELEMENT_PROMETHIUM());
1020 $this->mapSimple(Ids::ELEMENT_62, fn() => Blocks::ELEMENT_SAMARIUM());
1021 $this->mapSimple(Ids::ELEMENT_63, fn() => Blocks::ELEMENT_EUROPIUM());
1022 $this->mapSimple(Ids::ELEMENT_64, fn() => Blocks::ELEMENT_GADOLINIUM());
1023 $this->mapSimple(Ids::ELEMENT_65, fn() => Blocks::ELEMENT_TERBIUM());
1024 $this->mapSimple(Ids::ELEMENT_66, fn() => Blocks::ELEMENT_DYSPROSIUM());
1025 $this->mapSimple(Ids::ELEMENT_67, fn() => Blocks::ELEMENT_HOLMIUM());
1026 $this->mapSimple(Ids::ELEMENT_68, fn() => Blocks::ELEMENT_ERBIUM());
1027 $this->mapSimple(Ids::ELEMENT_69, fn() => Blocks::ELEMENT_THULIUM());
1028 $this->mapSimple(Ids::ELEMENT_7, fn() => Blocks::ELEMENT_NITROGEN());
1029 $this->mapSimple(Ids::ELEMENT_70, fn() => Blocks::ELEMENT_YTTERBIUM());
1030 $this->mapSimple(Ids::ELEMENT_71, fn() => Blocks::ELEMENT_LUTETIUM());
1031 $this->mapSimple(Ids::ELEMENT_72, fn() => Blocks::ELEMENT_HAFNIUM());
1032 $this->mapSimple(Ids::ELEMENT_73, fn() => Blocks::ELEMENT_TANTALUM());
1033 $this->mapSimple(Ids::ELEMENT_74, fn() => Blocks::ELEMENT_TUNGSTEN());
1034 $this->mapSimple(Ids::ELEMENT_75, fn() => Blocks::ELEMENT_RHENIUM());
1035 $this->mapSimple(Ids::ELEMENT_76, fn() => Blocks::ELEMENT_OSMIUM());
1036 $this->mapSimple(Ids::ELEMENT_77, fn() => Blocks::ELEMENT_IRIDIUM());
1037 $this->mapSimple(Ids::ELEMENT_78, fn() => Blocks::ELEMENT_PLATINUM());
1038 $this->mapSimple(Ids::ELEMENT_79, fn() => Blocks::ELEMENT_GOLD());
1039 $this->mapSimple(Ids::ELEMENT_8, fn() => Blocks::ELEMENT_OXYGEN());
1040 $this->mapSimple(Ids::ELEMENT_80, fn() => Blocks::ELEMENT_MERCURY());
1041 $this->mapSimple(Ids::ELEMENT_81, fn() => Blocks::ELEMENT_THALLIUM());
1042 $this->mapSimple(Ids::ELEMENT_82, fn() => Blocks::ELEMENT_LEAD());
1043 $this->mapSimple(Ids::ELEMENT_83, fn() => Blocks::ELEMENT_BISMUTH());
1044 $this->mapSimple(Ids::ELEMENT_84, fn() => Blocks::ELEMENT_POLONIUM());
1045 $this->mapSimple(Ids::ELEMENT_85, fn() => Blocks::ELEMENT_ASTATINE());
1046 $this->mapSimple(Ids::ELEMENT_86, fn() => Blocks::ELEMENT_RADON());
1047 $this->mapSimple(Ids::ELEMENT_87, fn() => Blocks::ELEMENT_FRANCIUM());
1048 $this->mapSimple(Ids::ELEMENT_88, fn() => Blocks::ELEMENT_RADIUM());
1049 $this->mapSimple(Ids::ELEMENT_89, fn() => Blocks::ELEMENT_ACTINIUM());
1050 $this->mapSimple(Ids::ELEMENT_9, fn() => Blocks::ELEMENT_FLUORINE());
1051 $this->mapSimple(Ids::ELEMENT_90, fn() => Blocks::ELEMENT_THORIUM());
1052 $this->mapSimple(Ids::ELEMENT_91, fn() => Blocks::ELEMENT_PROTACTINIUM());
1053 $this->mapSimple(Ids::ELEMENT_92, fn() => Blocks::ELEMENT_URANIUM());
1054 $this->mapSimple(Ids::ELEMENT_93, fn() => Blocks::ELEMENT_NEPTUNIUM());
1055 $this->mapSimple(Ids::ELEMENT_94, fn() => Blocks::ELEMENT_PLUTONIUM());
1056 $this->mapSimple(Ids::ELEMENT_95, fn() => Blocks::ELEMENT_AMERICIUM());
1057 $this->mapSimple(Ids::ELEMENT_96, fn() => Blocks::ELEMENT_CURIUM());
1058 $this->mapSimple(Ids::ELEMENT_97, fn() => Blocks::ELEMENT_BERKELIUM());
1059 $this->mapSimple(Ids::ELEMENT_98, fn() => Blocks::ELEMENT_CALIFORNIUM());
1060 $this->mapSimple(Ids::ELEMENT_99, fn() => Blocks::ELEMENT_EINSTEINIUM());
1061 $this->mapSimple(Ids::EMERALD_BLOCK, fn() => Blocks::EMERALD());
1062 $this->mapSimple(Ids::EMERALD_ORE, fn() => Blocks::EMERALD_ORE());
1063 $this->mapSimple(Ids::ENCHANTING_TABLE, fn() => Blocks::ENCHANTING_TABLE());
1064 $this->mapSimple(Ids::END_BRICKS, fn() => Blocks::END_STONE_BRICKS());
1065 $this->mapSimple(Ids::END_STONE, fn() => Blocks::END_STONE());
1066 $this->mapSimple(Ids::FERN, fn() => Blocks::FERN());
1067 $this->mapSimple(Ids::FLETCHING_TABLE, fn() => Blocks::FLETCHING_TABLE());
1068 $this->mapSimple(Ids::GILDED_BLACKSTONE, fn() => Blocks::GILDED_BLACKSTONE());
1069 $this->mapSimple(Ids::GLASS, fn() => Blocks::GLASS());
1070 $this->mapSimple(Ids::GLASS_PANE, fn() => Blocks::GLASS_PANE());
1071 $this->mapSimple(Ids::GLOWINGOBSIDIAN, fn() => Blocks::GLOWING_OBSIDIAN());
1072 $this->mapSimple(Ids::GLOWSTONE, fn() => Blocks::GLOWSTONE());
1073 $this->mapSimple(Ids::GOLD_BLOCK, fn() => Blocks::GOLD());
1074 $this->mapSimple(Ids::GOLD_ORE, fn() => Blocks::GOLD_ORE());
1075 $this->mapSimple(Ids::GRANITE, fn() => Blocks::GRANITE());
1076 $this->mapSimple(Ids::GRASS_BLOCK, fn() => Blocks::GRASS());
1077 $this->mapSimple(Ids::GRASS_PATH, fn() => Blocks::GRASS_PATH());
1078 $this->mapSimple(Ids::GRAVEL, fn() => Blocks::GRAVEL());
1079 $this->mapSimple(Ids::HANGING_ROOTS, fn() => Blocks::HANGING_ROOTS());
1080 $this->mapSimple(Ids::HARD_GLASS, fn() => Blocks::HARDENED_GLASS());
1081 $this->mapSimple(Ids::HARD_GLASS_PANE, fn() => Blocks::HARDENED_GLASS_PANE());
1082 $this->mapSimple(Ids::HARDENED_CLAY, fn() => Blocks::HARDENED_CLAY());
1083 $this->mapSimple(Ids::HONEYCOMB_BLOCK, fn() => Blocks::HONEYCOMB());
1084 $this->mapSimple(Ids::ICE, fn() => Blocks::ICE());
1085 $this->mapSimple(Ids::INFESTED_CHISELED_STONE_BRICKS, fn() => Blocks::INFESTED_CHISELED_STONE_BRICK());
1086 $this->mapSimple(Ids::INFESTED_COBBLESTONE, fn() => Blocks::INFESTED_COBBLESTONE());
1087 $this->mapSimple(Ids::INFESTED_CRACKED_STONE_BRICKS, fn() => Blocks::INFESTED_CRACKED_STONE_BRICK());
1088 $this->mapSimple(Ids::INFESTED_MOSSY_STONE_BRICKS, fn() => Blocks::INFESTED_MOSSY_STONE_BRICK());
1089 $this->mapSimple(Ids::INFESTED_STONE, fn() => Blocks::INFESTED_STONE());
1090 $this->mapSimple(Ids::INFESTED_STONE_BRICKS, fn() => Blocks::INFESTED_STONE_BRICK());
1091 $this->mapSimple(Ids::INFO_UPDATE, fn() => Blocks::INFO_UPDATE());
1092 $this->mapSimple(Ids::INFO_UPDATE2, fn() => Blocks::INFO_UPDATE2());
1093 $this->mapSimple(Ids::INVISIBLE_BEDROCK, fn() => Blocks::INVISIBLE_BEDROCK());
1094 $this->mapSimple(Ids::IRON_BARS, fn() => Blocks::IRON_BARS());
1095 $this->mapSimple(Ids::IRON_BLOCK, fn() => Blocks::IRON());
1096 $this->mapSimple(Ids::IRON_ORE, fn() => Blocks::IRON_ORE());
1097 $this->mapSimple(Ids::JUKEBOX, fn() => Blocks::JUKEBOX());
1098 $this->mapSimple(Ids::LAPIS_BLOCK, fn() => Blocks::LAPIS_LAZULI());
1099 $this->mapSimple(Ids::LAPIS_ORE, fn() => Blocks::LAPIS_LAZULI_ORE());
1100 $this->mapSimple(Ids::MAGMA, fn() => Blocks::MAGMA());
1101 $this->mapSimple(Ids::MANGROVE_ROOTS, fn() => Blocks::MANGROVE_ROOTS());
1102 $this->mapSimple(Ids::MELON_BLOCK, fn() => Blocks::MELON());
1103 $this->mapSimple(Ids::MOB_SPAWNER, fn() => Blocks::MONSTER_SPAWNER());
1104 $this->mapSimple(Ids::MOSSY_COBBLESTONE, fn() => Blocks::MOSSY_COBBLESTONE());
1105 $this->mapSimple(Ids::MOSSY_STONE_BRICKS, fn() => Blocks::MOSSY_STONE_BRICKS());
1106 $this->mapSimple(Ids::MUD, fn() => Blocks::MUD());
1107 $this->mapSimple(Ids::MUD_BRICKS, fn() => Blocks::MUD_BRICKS());
1108 $this->mapSimple(Ids::MYCELIUM, fn() => Blocks::MYCELIUM());
1109 $this->mapSimple(Ids::NETHER_BRICK, fn() => Blocks::NETHER_BRICKS());
1110 $this->mapSimple(Ids::NETHER_BRICK_FENCE, fn() => Blocks::NETHER_BRICK_FENCE());
1111 $this->mapSimple(Ids::NETHER_GOLD_ORE, fn() => Blocks::NETHER_GOLD_ORE());
1112 $this->mapSimple(Ids::NETHER_WART_BLOCK, fn() => Blocks::NETHER_WART_BLOCK());
1113 $this->mapSimple(Ids::NETHERITE_BLOCK, fn() => Blocks::NETHERITE());
1114 $this->mapSimple(Ids::NETHERRACK, fn() => Blocks::NETHERRACK());
1115 $this->mapSimple(Ids::NETHERREACTOR, fn() => Blocks::NETHER_REACTOR_CORE());
1116 $this->mapSimple(Ids::NOTEBLOCK, fn() => Blocks::NOTE_BLOCK());
1117 $this->mapSimple(Ids::OBSIDIAN, fn() => Blocks::OBSIDIAN());
1118 $this->mapSimple(Ids::PACKED_ICE, fn() => Blocks::PACKED_ICE());
1119 $this->mapSimple(Ids::PACKED_MUD, fn() => Blocks::PACKED_MUD());
1120 $this->mapSimple(Ids::PODZOL, fn() => Blocks::PODZOL());
1121 $this->mapSimple(Ids::POLISHED_ANDESITE, fn() => Blocks::POLISHED_ANDESITE());
1122 $this->mapSimple(Ids::POLISHED_BLACKSTONE, fn() => Blocks::POLISHED_BLACKSTONE());
1123 $this->mapSimple(Ids::POLISHED_BLACKSTONE_BRICKS, fn() => Blocks::POLISHED_BLACKSTONE_BRICKS());
1124 $this->mapSimple(Ids::POLISHED_DEEPSLATE, fn() => Blocks::POLISHED_DEEPSLATE());
1125 $this->mapSimple(Ids::POLISHED_DIORITE, fn() => Blocks::POLISHED_DIORITE());
1126 $this->mapSimple(Ids::POLISHED_GRANITE, fn() => Blocks::POLISHED_GRANITE());
1127 $this->mapSimple(Ids::POLISHED_TUFF, fn() => Blocks::POLISHED_TUFF());
1128 $this->mapSimple(Ids::PRISMARINE, fn() => Blocks::PRISMARINE());
1129 $this->mapSimple(Ids::PRISMARINE_BRICKS, fn() => Blocks::PRISMARINE_BRICKS());
1130 $this->mapSimple(Ids::QUARTZ_BRICKS, fn() => Blocks::QUARTZ_BRICKS());
1131 $this->mapSimple(Ids::QUARTZ_ORE, fn() => Blocks::NETHER_QUARTZ_ORE());
1132 $this->mapSimple(Ids::RAW_COPPER_BLOCK, fn() => Blocks::RAW_COPPER());
1133 $this->mapSimple(Ids::RAW_GOLD_BLOCK, fn() => Blocks::RAW_GOLD());
1134 $this->mapSimple(Ids::RAW_IRON_BLOCK, fn() => Blocks::RAW_IRON());
1135 $this->mapSimple(Ids::RED_MUSHROOM, fn() => Blocks::RED_MUSHROOM());
1136 $this->mapSimple(Ids::RED_NETHER_BRICK, fn() => Blocks::RED_NETHER_BRICKS());
1137 $this->mapSimple(Ids::RED_SAND, fn() => Blocks::RED_SAND());
1138 $this->mapSimple(Ids::RED_SANDSTONE, fn() => Blocks::RED_SANDSTONE());
1139 $this->mapSimple(Ids::REDSTONE_BLOCK, fn() => Blocks::REDSTONE());
1140 $this->mapSimple(Ids::REINFORCED_DEEPSLATE, fn() => Blocks::REINFORCED_DEEPSLATE());
1141 $this->mapSimple(Ids::RESERVED6, fn() => Blocks::RESERVED6());
1142 $this->mapSimple(Ids::RESIN_BLOCK, fn() => Blocks::RESIN());
1143 $this->mapSimple(Ids::RESIN_BRICKS, fn() => Blocks::RESIN_BRICKS());
1144 $this->mapSimple(Ids::SAND, fn() => Blocks::SAND());
1145 $this->mapSimple(Ids::SANDSTONE, fn() => Blocks::SANDSTONE());
1146 $this->mapSimple(Ids::SCULK, fn() => Blocks::SCULK());
1147 $this->mapSimple(Ids::SEA_LANTERN, fn() => Blocks::SEA_LANTERN());
1148 $this->mapSimple(Ids::SHORT_GRASS, fn() => Blocks::TALL_GRASS()); //no, this is not a typo - tall_grass is now the double block, just to be confusing :(
1149 $this->mapSimple(Ids::SHROOMLIGHT, fn() => Blocks::SHROOMLIGHT());
1150 $this->mapSimple(Ids::SLIME, fn() => Blocks::SLIME());
1151 $this->mapSimple(Ids::SMITHING_TABLE, fn() => Blocks::SMITHING_TABLE());
1152 $this->mapSimple(Ids::SMOOTH_BASALT, fn() => Blocks::SMOOTH_BASALT());
1153 $this->mapSimple(Ids::SMOOTH_RED_SANDSTONE, fn() => Blocks::SMOOTH_RED_SANDSTONE());
1154 $this->mapSimple(Ids::SMOOTH_SANDSTONE, fn() => Blocks::SMOOTH_SANDSTONE());
1155 $this->mapSimple(Ids::SMOOTH_STONE, fn() => Blocks::SMOOTH_STONE());
1156 $this->mapSimple(Ids::SNOW, fn() => Blocks::SNOW());
1157 $this->mapSimple(Ids::SOUL_SAND, fn() => Blocks::SOUL_SAND());
1158 $this->mapSimple(Ids::SOUL_SOIL, fn() => Blocks::SOUL_SOIL());
1159 $this->mapSimple(Ids::SPORE_BLOSSOM, fn() => Blocks::SPORE_BLOSSOM());
1160 $this->mapSimple(Ids::SPONGE, fn() => Blocks::SPONGE());
1161 $this->mapSimple(Ids::STONE, fn() => Blocks::STONE());
1162 $this->mapSimple(Ids::STONECUTTER, fn() => Blocks::LEGACY_STONECUTTER());
1163 $this->mapSimple(Ids::STONE_BRICKS, fn() => Blocks::STONE_BRICKS());
1164 $this->mapSimple(Ids::TINTED_GLASS, fn() => Blocks::TINTED_GLASS());
1165 $this->mapSimple(Ids::TORCHFLOWER, fn() => Blocks::TORCHFLOWER());
1166 $this->mapSimple(Ids::TUFF, fn() => Blocks::TUFF());
1167 $this->mapSimple(Ids::TUFF_BRICKS, fn() => Blocks::TUFF_BRICKS());
1168 $this->mapSimple(Ids::UNDYED_SHULKER_BOX, fn() => Blocks::SHULKER_BOX());
1169 $this->mapSimple(Ids::WARPED_WART_BLOCK, fn() => Blocks::WARPED_WART_BLOCK());
1170 $this->mapSimple(Ids::WARPED_ROOTS, fn() => Blocks::WARPED_ROOTS());
1171 $this->mapSimple(Ids::WATERLILY, fn() => Blocks::LILY_PAD());
1172 $this->mapSimple(Ids::WEB, fn() => Blocks::COBWEB());
1173 $this->mapSimple(Ids::WET_SPONGE, fn() => Blocks::SPONGE()->setWet(true));
1174 $this->mapSimple(Ids::WITHER_ROSE, fn() => Blocks::WITHER_ROSE());
1175 $this->mapSimple(Ids::DANDELION, fn() => Blocks::DANDELION());
1176
1177 $this->mapSimple(Ids::ALLIUM, fn() => Blocks::ALLIUM());
1178 $this->mapSimple(Ids::CORNFLOWER, fn() => Blocks::CORNFLOWER());
1179 $this->mapSimple(Ids::AZURE_BLUET, fn() => Blocks::AZURE_BLUET());
1180 $this->mapSimple(Ids::LILY_OF_THE_VALLEY, fn() => Blocks::LILY_OF_THE_VALLEY());
1181 $this->mapSimple(Ids::BLUE_ORCHID, fn() => Blocks::BLUE_ORCHID());
1182 $this->mapSimple(Ids::OXEYE_DAISY, fn() => Blocks::OXEYE_DAISY());
1183 $this->mapSimple(Ids::POPPY, fn() => Blocks::POPPY());
1184 $this->mapSimple(Ids::ORANGE_TULIP, fn() => Blocks::ORANGE_TULIP());
1185 $this->mapSimple(Ids::PINK_TULIP, fn() => Blocks::PINK_TULIP());
1186 $this->mapSimple(Ids::RED_TULIP, fn() => Blocks::RED_TULIP());
1187 $this->mapSimple(Ids::WHITE_TULIP, fn() => Blocks::WHITE_TULIP());
1188 }
1189
1190 private function registerDeserializers() : void{
1191 $this->map(Ids::ACTIVATOR_RAIL, function(Reader $in) : Block{
1192 return Blocks::ACTIVATOR_RAIL()
1193 ->setPowered($in->readBool(StateNames::RAIL_DATA_BIT))
1194 ->setShape($in->readBoundedInt(StateNames::RAIL_DIRECTION, 0, 5));
1195 });
1196 $this->map(Ids::AMETHYST_CLUSTER, function(Reader $in) : Block{
1197 return Blocks::AMETHYST_CLUSTER()
1198 ->setStage(AmethystCluster::STAGE_CLUSTER)
1199 ->setFacing($in->readBlockFace());
1200 });
1201 $this->mapSlab(Ids::ANDESITE_SLAB, Ids::ANDESITE_DOUBLE_SLAB, fn() => Blocks::ANDESITE_SLAB());
1202 $this->mapStairs(Ids::ANDESITE_STAIRS, fn() => Blocks::ANDESITE_STAIRS());
1203 $this->map(Ids::ANDESITE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::ANDESITE_WALL(), $in));
1204 $this->map(Ids::ANVIL, function(Reader $in) : Block{
1205 return Blocks::ANVIL()
1206 ->setDamage(Anvil::UNDAMAGED)
1207 ->setFacing($in->readCardinalHorizontalFacing());
1208 });
1209 $this->map(Ids::CHIPPED_ANVIL, function(Reader $in) : Block{
1210 return Blocks::ANVIL()
1211 ->setDamage(Anvil::SLIGHTLY_DAMAGED)
1212 ->setFacing($in->readCardinalHorizontalFacing());
1213 });
1214 $this->map(Ids::DAMAGED_ANVIL, function(Reader $in) : Block{
1215 return Blocks::ANVIL()
1216 ->setDamage(Anvil::VERY_DAMAGED)
1217 ->setFacing($in->readCardinalHorizontalFacing());
1218 });
1219 $this->map(Ids::BAMBOO, function(Reader $in) : Block{
1220 return Blocks::BAMBOO()
1221 ->setLeafSize(match($value = $in->readString(StateNames::BAMBOO_LEAF_SIZE)){
1222 StringValues::BAMBOO_LEAF_SIZE_NO_LEAVES => Bamboo::NO_LEAVES,
1223 StringValues::BAMBOO_LEAF_SIZE_SMALL_LEAVES => Bamboo::SMALL_LEAVES,
1224 StringValues::BAMBOO_LEAF_SIZE_LARGE_LEAVES => Bamboo::LARGE_LEAVES,
1225 default => throw $in->badValueException(StateNames::BAMBOO_LEAF_SIZE, $value),
1226 })
1227 ->setReady($in->readBool(StateNames::AGE_BIT))
1228 ->setThick(match($value = $in->readString(StateNames::BAMBOO_STALK_THICKNESS)){
1229 StringValues::BAMBOO_STALK_THICKNESS_THIN => false,
1230 StringValues::BAMBOO_STALK_THICKNESS_THICK => true,
1231 default => throw $in->badValueException(StateNames::BAMBOO_STALK_THICKNESS, $value),
1232 });
1233 });
1234 $this->map(Ids::BAMBOO_SAPLING, function(Reader $in) : Block{
1235 return Blocks::BAMBOO_SAPLING()->setReady($in->readBool(StateNames::AGE_BIT));
1236 });
1237 $this->map(Ids::BARREL, function(Reader $in) : Block{
1238 return Blocks::BARREL()
1239 ->setFacing($in->readFacingDirection())
1240 ->setOpen($in->readBool(StateNames::OPEN_BIT));
1241 });
1242 $this->map(Ids::BASALT, function(Reader $in){
1243 return Blocks::BASALT()
1244 ->setAxis($in->readPillarAxis());
1245 });
1246 $this->map(Ids::BED, function(Reader $in) : Block{
1247 return Blocks::BED()
1248 ->setFacing($in->readLegacyHorizontalFacing())
1249 ->setHead($in->readBool(StateNames::HEAD_PIECE_BIT))
1250 ->setOccupied($in->readBool(StateNames::OCCUPIED_BIT));
1251 });
1252 $this->map(Ids::BEDROCK, function(Reader $in) : Block{
1253 return Blocks::BEDROCK()
1254 ->setBurnsForever($in->readBool(StateNames::INFINIBURN_BIT));
1255 });
1256 $this->map(Ids::BEETROOT, fn(Reader $in) => Helper::decodeCrops(Blocks::BEETROOTS(), $in));
1257 $this->map(Ids::BELL, function(Reader $in) : Block{
1258 $in->ignored(StateNames::TOGGLE_BIT); //only useful at runtime
1259 return Blocks::BELL()
1260 ->setFacing($in->readLegacyHorizontalFacing())
1261 ->setAttachmentType($in->readBellAttachmentType());
1262 });
1263 $this->map(Ids::BIG_DRIPLEAF, function(Reader $in) : Block{
1264 if($in->readBool(StateNames::BIG_DRIPLEAF_HEAD)){
1265 return Blocks::BIG_DRIPLEAF_HEAD()
1266 ->setFacing($in->readCardinalHorizontalFacing())
1267 ->setLeafState(match($type = $in->readString(StateNames::BIG_DRIPLEAF_TILT)){
1268 StringValues::BIG_DRIPLEAF_TILT_NONE => DripleafState::STABLE,
1269 StringValues::BIG_DRIPLEAF_TILT_UNSTABLE => DripleafState::UNSTABLE,
1270 StringValues::BIG_DRIPLEAF_TILT_PARTIAL_TILT => DripleafState::PARTIAL_TILT,
1271 StringValues::BIG_DRIPLEAF_TILT_FULL_TILT => DripleafState::FULL_TILT,
1272 default => throw $in->badValueException(StateNames::BIG_DRIPLEAF_TILT, $type),
1273 });
1274 }else{
1275 $in->ignored(StateNames::BIG_DRIPLEAF_TILT);
1276 return Blocks::BIG_DRIPLEAF_STEM()->setFacing($in->readCardinalHorizontalFacing());
1277 }
1278 });
1279 $this->mapSlab(Ids::BLACKSTONE_SLAB, Ids::BLACKSTONE_DOUBLE_SLAB, fn() => Blocks::BLACKSTONE_SLAB());
1280 $this->mapStairs(Ids::BLACKSTONE_STAIRS, fn() => Blocks::BLACKSTONE_STAIRS());
1281 $this->map(Ids::BLACKSTONE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::BLACKSTONE_WALL(), $in));
1282 $this->map(Ids::BLAST_FURNACE, function(Reader $in) : Block{
1283 return Blocks::BLAST_FURNACE()
1284 ->setFacing($in->readCardinalHorizontalFacing())
1285 ->setLit(false);
1286 });
1287 $this->map(Ids::BONE_BLOCK, function(Reader $in) : Block{
1288 $in->ignored(StateNames::DEPRECATED);
1289 return Blocks::BONE_BLOCK()->setAxis($in->readPillarAxis());
1290 });
1291 $this->map(Ids::BREWING_STAND, function(Reader $in) : Block{
1292 return Blocks::BREWING_STAND()
1293 ->setSlot(BrewingStandSlot::EAST, $in->readBool(StateNames::BREWING_STAND_SLOT_A_BIT))
1294 ->setSlot(BrewingStandSlot::SOUTHWEST, $in->readBool(StateNames::BREWING_STAND_SLOT_B_BIT))
1295 ->setSlot(BrewingStandSlot::NORTHWEST, $in->readBool(StateNames::BREWING_STAND_SLOT_C_BIT));
1296 });
1297 $this->mapSlab(Ids::BRICK_SLAB, Ids::BRICK_DOUBLE_SLAB, fn() => Blocks::BRICK_SLAB());
1298 $this->mapStairs(Ids::BRICK_STAIRS, fn() => Blocks::BRICK_STAIRS());
1299 $this->map(Ids::BRICK_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::BRICK_WALL(), $in));
1300 $this->map(Ids::MUSHROOM_STEM, fn(Reader $in) => match($in->readBoundedInt(StateNames::HUGE_MUSHROOM_BITS, 0, 15)){
1301 BlockLegacyMetadata::MUSHROOM_BLOCK_ALL_STEM => Blocks::ALL_SIDED_MUSHROOM_STEM(),
1302 BlockLegacyMetadata::MUSHROOM_BLOCK_STEM => Blocks::MUSHROOM_STEM(),
1303 default => throw new BlockStateDeserializeException("This state does not exist"),
1304 });
1305 $this->map(Ids::BROWN_MUSHROOM_BLOCK, fn(Reader $in) => Helper::decodeMushroomBlock(Blocks::BROWN_MUSHROOM_BLOCK(), $in));
1306 $this->map(Ids::CACTUS, function(Reader $in) : Block{
1307 return Blocks::CACTUS()
1308 ->setAge($in->readBoundedInt(StateNames::AGE, 0, 15));
1309 });
1310 $this->map(Ids::CAKE, function(Reader $in) : Block{
1311 return Blocks::CAKE()
1312 ->setBites($in->readBoundedInt(StateNames::BITE_COUNTER, 0, 6));
1313 });
1314 $this->map(Ids::CAMPFIRE, function(Reader $in) : Block{
1315 return Blocks::CAMPFIRE()
1316 ->setFacing($in->readCardinalHorizontalFacing())
1317 ->setLit(!$in->readBool(StateNames::EXTINGUISHED));
1318 });
1319 $this->map(Ids::CARROTS, fn(Reader $in) => Helper::decodeCrops(Blocks::CARROTS(), $in));
1320 $this->map(Ids::CARVED_PUMPKIN, function(Reader $in) : Block{
1321 return Blocks::CARVED_PUMPKIN()
1322 ->setFacing($in->readCardinalHorizontalFacing());
1323 });
1324 $this->map(Ids::CAVE_VINES, function(Reader $in) : CaveVines{
1325 return Blocks::CAVE_VINES()
1326 ->setBerries(false)
1327 ->setHead(false)
1328 ->setAge($in->readBoundedInt(StateNames::GROWING_PLANT_AGE, 0, 25));
1329 });
1330 $this->map(Ids::CAVE_VINES_BODY_WITH_BERRIES, function(Reader $in) : CaveVines{
1331 return Blocks::CAVE_VINES()
1332 ->setBerries(true)
1333 ->setHead(false)
1334 ->setAge($in->readBoundedInt(StateNames::GROWING_PLANT_AGE, 0, 25));
1335 });
1336 $this->map(Ids::CAVE_VINES_HEAD_WITH_BERRIES, function(Reader $in) : CaveVines{
1337 return Blocks::CAVE_VINES()
1338 ->setBerries(true)
1339 ->setHead(true)
1340 ->setAge($in->readBoundedInt(StateNames::GROWING_PLANT_AGE, 0, 25));
1341 });
1342 $this->map(Ids::CHAIN, function(Reader $in) : Block{
1343 return Blocks::CHAIN()
1344 ->setAxis($in->readPillarAxis());
1345 });
1346 $this->map(Ids::CHISELED_BOOKSHELF, function(Reader $in) : Block{
1347 $block = Blocks::CHISELED_BOOKSHELF()
1348 ->setFacing($in->readLegacyHorizontalFacing());
1349
1350 //we don't use API constant for bounds here as the data bounds might be different to what we support internally
1351 $flags = $in->readBoundedInt(StateNames::BOOKS_STORED, 0, (1 << 6) - 1);
1352 foreach(ChiseledBookshelfSlot::cases() as $slot){
1353 $block->setSlot($slot, ($flags & (1 << $slot->value)) !== 0);
1354 }
1355
1356 return $block;
1357 });
1358 $this->map(Ids::CHISELED_COPPER, fn() => Helper::decodeCopper(Blocks::CHISELED_COPPER(), CopperOxidation::NONE));
1359 $this->map(Ids::CHISELED_QUARTZ_BLOCK, function(Reader $in) : Block{
1360 return Blocks::CHISELED_QUARTZ()
1361 ->setAxis($in->readPillarAxis());
1362 });
1363 $this->map(Ids::CHEST, function(Reader $in) : Block{
1364 return Blocks::CHEST()
1365 ->setFacing($in->readCardinalHorizontalFacing());
1366 });
1367 $this->map(Ids::CHORUS_FLOWER, function(Reader $in) : Block{
1368 return Blocks::CHORUS_FLOWER()
1369 ->setAge($in->readBoundedInt(StateNames::AGE, ChorusFlower::MIN_AGE, ChorusFlower::MAX_AGE));
1370 });
1371 $this->map(Ids::COARSE_DIRT, fn() => Blocks::DIRT()->setDirtType(DirtType::COARSE));
1372 $this->mapSlab(Ids::COBBLED_DEEPSLATE_SLAB, Ids::COBBLED_DEEPSLATE_DOUBLE_SLAB, fn() => Blocks::COBBLED_DEEPSLATE_SLAB());
1373 $this->mapStairs(Ids::COBBLED_DEEPSLATE_STAIRS, fn() => Blocks::COBBLED_DEEPSLATE_STAIRS());
1374 $this->map(Ids::COBBLED_DEEPSLATE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::COBBLED_DEEPSLATE_WALL(), $in));
1375 $this->mapSlab(Ids::COBBLESTONE_SLAB, Ids::COBBLESTONE_DOUBLE_SLAB, fn() => Blocks::COBBLESTONE_SLAB());
1376 $this->map(Ids::COBBLESTONE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::COBBLESTONE_WALL(), $in));
1377 $this->map(Ids::COCOA, function(Reader $in) : Block{
1378 return Blocks::COCOA_POD()
1379 ->setAge($in->readBoundedInt(StateNames::AGE, 0, 2))
1380 ->setFacing(Facing::opposite($in->readLegacyHorizontalFacing()));
1381 });
1382 $this->map(Ids::COLORED_TORCH_BLUE, fn(Reader $in) => Blocks::BLUE_TORCH()->setFacing($in->readTorchFacing()));
1383 $this->map(Ids::COLORED_TORCH_GREEN, fn(Reader $in) => Blocks::GREEN_TORCH()->setFacing($in->readTorchFacing()));
1384 $this->map(Ids::COLORED_TORCH_PURPLE, fn(Reader $in) => Blocks::PURPLE_TORCH()->setFacing($in->readTorchFacing()));
1385 $this->map(Ids::COLORED_TORCH_RED, fn(Reader $in) => Blocks::RED_TORCH()->setFacing($in->readTorchFacing()));
1386 $this->map(Ids::COMPOUND_CREATOR, fn(Reader $in) => Blocks::COMPOUND_CREATOR()
1387 ->setFacing(Facing::opposite($in->readLegacyHorizontalFacing()))
1388 );
1389 $this->mapSlab(Ids::CUT_RED_SANDSTONE_SLAB, Ids::CUT_RED_SANDSTONE_DOUBLE_SLAB, fn() => Blocks::CUT_RED_SANDSTONE_SLAB());
1390 $this->mapSlab(Ids::CUT_SANDSTONE_SLAB, Ids::CUT_SANDSTONE_DOUBLE_SLAB, fn() => Blocks::CUT_SANDSTONE_SLAB());
1391 $this->mapSlab(Ids::DARK_PRISMARINE_SLAB, Ids::DARK_PRISMARINE_DOUBLE_SLAB, fn() => Blocks::DARK_PRISMARINE_SLAB());
1392 $this->mapStairs(Ids::DARK_PRISMARINE_STAIRS, fn() => Blocks::DARK_PRISMARINE_STAIRS());
1393 $this->map(Ids::DAYLIGHT_DETECTOR, fn(Reader $in) => Helper::decodeDaylightSensor(Blocks::DAYLIGHT_SENSOR(), $in)
1394 ->setInverted(false));
1395 $this->map(Ids::DAYLIGHT_DETECTOR_INVERTED, fn(Reader $in) => Helper::decodeDaylightSensor(Blocks::DAYLIGHT_SENSOR(), $in)
1396 ->setInverted(true));
1397 $this->map(Ids::DEEPSLATE, function(Reader $in) : Block{
1398 return Blocks::DEEPSLATE()
1399 ->setAxis($in->readPillarAxis());
1400 });
1401 $this->mapSlab(Ids::DEEPSLATE_BRICK_SLAB, Ids::DEEPSLATE_BRICK_DOUBLE_SLAB, fn() => Blocks::DEEPSLATE_BRICK_SLAB());
1402 $this->mapStairs(Ids::DEEPSLATE_BRICK_STAIRS, fn() => Blocks::DEEPSLATE_BRICK_STAIRS());
1403 $this->map(Ids::DEEPSLATE_BRICK_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::DEEPSLATE_BRICK_WALL(), $in));
1404 $this->map(Ids::DEEPSLATE_REDSTONE_ORE, fn() => Blocks::DEEPSLATE_REDSTONE_ORE()->setLit(false));
1405 $this->mapSlab(Ids::DEEPSLATE_TILE_SLAB, Ids::DEEPSLATE_TILE_DOUBLE_SLAB, fn() => Blocks::DEEPSLATE_TILE_SLAB());
1406 $this->mapStairs(Ids::DEEPSLATE_TILE_STAIRS, fn() => Blocks::DEEPSLATE_TILE_STAIRS());
1407 $this->map(Ids::DEEPSLATE_TILE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::DEEPSLATE_TILE_WALL(), $in));
1408 $this->map(Ids::DETECTOR_RAIL, function(Reader $in) : Block{
1409 return Blocks::DETECTOR_RAIL()
1410 ->setActivated($in->readBool(StateNames::RAIL_DATA_BIT))
1411 ->setShape($in->readBoundedInt(StateNames::RAIL_DIRECTION, 0, 5));
1412 });
1413 $this->mapSlab(Ids::DIORITE_SLAB, Ids::DIORITE_DOUBLE_SLAB, fn() => Blocks::DIORITE_SLAB());
1414 $this->mapStairs(Ids::DIORITE_STAIRS, fn() => Blocks::DIORITE_STAIRS());
1415 $this->map(Ids::DIORITE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::DIORITE_WALL(), $in));
1416 $this->map(Ids::DIRT, fn() => Blocks::DIRT()->setDirtType(DirtType::NORMAL));
1417 $this->map(Ids::DIRT_WITH_ROOTS, fn() => Blocks::DIRT()->setDirtType(DirtType::ROOTED));
1418 $this->map(Ids::LARGE_FERN, fn(Reader $in) => Helper::decodeDoublePlant(Blocks::LARGE_FERN(), $in));
1419 $this->map(Ids::TALL_GRASS, fn(Reader $in) => Helper::decodeDoublePlant(Blocks::DOUBLE_TALLGRASS(), $in));
1420 $this->map(Ids::PEONY, fn(Reader $in) => Helper::decodeDoublePlant(Blocks::PEONY(), $in));
1421 $this->map(Ids::ROSE_BUSH, fn(Reader $in) => Helper::decodeDoublePlant(Blocks::ROSE_BUSH(), $in));
1422 $this->map(Ids::SUNFLOWER, fn(Reader $in) => Helper::decodeDoublePlant(Blocks::SUNFLOWER(), $in));
1423 $this->map(Ids::LILAC, fn(Reader $in) => Helper::decodeDoublePlant(Blocks::LILAC(), $in));
1424 $this->map(Ids::ELEMENT_CONSTRUCTOR, fn(Reader $in) => Blocks::ELEMENT_CONSTRUCTOR()
1425 ->setFacing(Facing::opposite($in->readLegacyHorizontalFacing()))
1426 );
1427 $this->mapStairs(Ids::END_BRICK_STAIRS, fn() => Blocks::END_STONE_BRICK_STAIRS());
1428 $this->map(Ids::END_STONE_BRICK_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::END_STONE_BRICK_WALL(), $in));
1429 $this->map(Ids::END_PORTAL_FRAME, function(Reader $in) : Block{
1430 return Blocks::END_PORTAL_FRAME()
1431 ->setEye($in->readBool(StateNames::END_PORTAL_EYE_BIT))
1432 ->setFacing($in->readCardinalHorizontalFacing());
1433 });
1434 $this->map(Ids::END_ROD, function(Reader $in) : Block{
1435 return Blocks::END_ROD()
1436 ->setFacing($in->readEndRodFacingDirection());
1437 });
1438 $this->mapSlab(Ids::END_STONE_BRICK_SLAB, Ids::END_STONE_BRICK_DOUBLE_SLAB, fn() => Blocks::END_STONE_BRICK_SLAB());
1439 $this->map(Ids::ENDER_CHEST, function(Reader $in) : Block{
1440 return Blocks::ENDER_CHEST()
1441 ->setFacing($in->readCardinalHorizontalFacing());
1442 });
1443 $this->map(Ids::FARMLAND, function(Reader $in) : Block{
1444 return Blocks::FARMLAND()
1445 ->setWetness($in->readBoundedInt(StateNames::MOISTURIZED_AMOUNT, 0, 7));
1446 });
1447 $this->map(Ids::FIRE, function(Reader $in) : Block{
1448 return Blocks::FIRE()
1449 ->setAge($in->readBoundedInt(StateNames::AGE, 0, 15));
1450 });
1451 $this->map(Ids::FLOWER_POT, function(Reader $in) : Block{
1452 $in->ignored(StateNames::UPDATE_BIT);
1453 return Blocks::FLOWER_POT();
1454 });
1455 $this->map(Ids::FLOWING_LAVA, fn(Reader $in) => Helper::decodeFlowingLiquid(Blocks::LAVA(), $in));
1456 $this->map(Ids::FLOWING_WATER, fn(Reader $in) => Helper::decodeFlowingLiquid(Blocks::WATER(), $in));
1457 $this->map(Ids::FRAME, fn(Reader $in) => Helper::decodeItemFrame(Blocks::ITEM_FRAME(), $in));
1458 $this->map(Ids::FROSTED_ICE, function(Reader $in) : Block{
1459 return Blocks::FROSTED_ICE()
1460 ->setAge($in->readBoundedInt(StateNames::AGE, 0, 3));
1461 });
1462 $this->map(Ids::FURNACE, function(Reader $in) : Block{
1463 return Blocks::FURNACE()
1464 ->setFacing($in->readCardinalHorizontalFacing())
1465 ->setLit(false);
1466 });
1467 $this->map(Ids::GLOW_LICHEN, fn(Reader $in) => Blocks::GLOW_LICHEN()->setFaces($in->readFacingFlags()));
1468 $this->map(Ids::GLOW_FRAME, fn(Reader $in) => Helper::decodeItemFrame(Blocks::GLOWING_ITEM_FRAME(), $in));
1469 $this->map(Ids::GOLDEN_RAIL, function(Reader $in) : Block{
1470 return Blocks::POWERED_RAIL()
1471 ->setPowered($in->readBool(StateNames::RAIL_DATA_BIT))
1472 ->setShape($in->readBoundedInt(StateNames::RAIL_DIRECTION, 0, 5));
1473 });
1474 $this->mapSlab(Ids::GRANITE_SLAB, Ids::GRANITE_DOUBLE_SLAB, fn() => Blocks::GRANITE_SLAB());
1475 $this->mapStairs(Ids::GRANITE_STAIRS, fn() => Blocks::GRANITE_STAIRS());
1476 $this->map(Ids::GRANITE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::GRANITE_WALL(), $in));
1477 $this->map(Ids::HAY_BLOCK, function(Reader $in) : Block{
1478 $in->ignored(StateNames::DEPRECATED);
1479 return Blocks::HAY_BALE()->setAxis($in->readPillarAxis());
1480 });
1481 $this->map(Ids::HEAVY_WEIGHTED_PRESSURE_PLATE, fn(Reader $in) => Helper::decodeWeightedPressurePlate(Blocks::WEIGHTED_PRESSURE_PLATE_HEAVY(), $in));
1482 $this->map(Ids::HOPPER, function(Reader $in) : Block{
1483 return Blocks::HOPPER()
1484 ->setFacing($in->readFacingWithoutUp())
1485 ->setPowered($in->readBool(StateNames::TOGGLE_BIT));
1486 });
1487 $this->map(Ids::IRON_DOOR, fn(Reader $in) => Helper::decodeDoor(Blocks::IRON_DOOR(), $in));
1488 $this->map(Ids::IRON_TRAPDOOR, fn(Reader $in) => Helper::decodeTrapdoor(Blocks::IRON_TRAPDOOR(), $in));
1489 $this->map(Ids::LAB_TABLE, fn(Reader $in) => Blocks::LAB_TABLE()
1490 ->setFacing(Facing::opposite($in->readLegacyHorizontalFacing()))
1491 );
1492 $this->map(Ids::LADDER, function(Reader $in) : Block{
1493 return Blocks::LADDER()
1494 ->setFacing($in->readHorizontalFacing());
1495 });
1496 $this->map(Ids::LANTERN, function(Reader $in) : Block{
1497 return Blocks::LANTERN()
1498 ->setHanging($in->readBool(StateNames::HANGING));
1499 });
1500 $this->map(Ids::LARGE_AMETHYST_BUD, function(Reader $in) : Block{
1501 return Blocks::AMETHYST_CLUSTER()
1502 ->setStage(AmethystCluster::STAGE_LARGE_BUD)
1503 ->setFacing($in->readBlockFace());
1504 });
1505 $this->map(Ids::LAVA, fn(Reader $in) => Helper::decodeStillLiquid(Blocks::LAVA(), $in));
1506 $this->map(Ids::LECTERN, function(Reader $in) : Block{
1507 return Blocks::LECTERN()
1508 ->setFacing($in->readCardinalHorizontalFacing())
1509 ->setProducingSignal($in->readBool(StateNames::POWERED_BIT));
1510 });
1511 $this->map(Ids::LEVER, function(Reader $in) : Block{
1512 return Blocks::LEVER()
1513 ->setActivated($in->readBool(StateNames::OPEN_BIT))
1514 ->setFacing(match($value = $in->readString(StateNames::LEVER_DIRECTION)){
1515 StringValues::LEVER_DIRECTION_DOWN_NORTH_SOUTH => LeverFacing::DOWN_AXIS_Z,
1516 StringValues::LEVER_DIRECTION_DOWN_EAST_WEST => LeverFacing::DOWN_AXIS_X,
1517 StringValues::LEVER_DIRECTION_UP_NORTH_SOUTH => LeverFacing::UP_AXIS_Z,
1518 StringValues::LEVER_DIRECTION_UP_EAST_WEST => LeverFacing::UP_AXIS_X,
1519 StringValues::LEVER_DIRECTION_NORTH => LeverFacing::NORTH,
1520 StringValues::LEVER_DIRECTION_SOUTH => LeverFacing::SOUTH,
1521 StringValues::LEVER_DIRECTION_WEST => LeverFacing::WEST,
1522 StringValues::LEVER_DIRECTION_EAST => LeverFacing::EAST,
1523 default => throw $in->badValueException(StateNames::LEVER_DIRECTION, $value),
1524 });
1525 });
1526 $this->map(Ids::LIGHTNING_ROD, function(Reader $in) : Block{
1527 return Blocks::LIGHTNING_ROD()
1528 ->setFacing($in->readFacingDirection());
1529 });
1530 $this->map(Ids::LIGHT_WEIGHTED_PRESSURE_PLATE, fn(Reader $in) => Helper::decodeWeightedPressurePlate(Blocks::WEIGHTED_PRESSURE_PLATE_LIGHT(), $in));
1531 $this->map(Ids::LIT_BLAST_FURNACE, function(Reader $in) : Block{
1532 return Blocks::BLAST_FURNACE()
1533 ->setFacing($in->readCardinalHorizontalFacing())
1534 ->setLit(true);
1535 });
1536 $this->map(Ids::LIT_DEEPSLATE_REDSTONE_ORE, fn() => Blocks::DEEPSLATE_REDSTONE_ORE()->setLit(true));
1537 $this->map(Ids::LIT_FURNACE, function(Reader $in) : Block{
1538 return Blocks::FURNACE()
1539 ->setFacing($in->readCardinalHorizontalFacing())
1540 ->setLit(true);
1541 });
1542 $this->map(Ids::LIT_PUMPKIN, function(Reader $in) : Block{
1543 return Blocks::LIT_PUMPKIN()
1544 ->setFacing($in->readCardinalHorizontalFacing());
1545 });
1546 $this->map(Ids::LIT_REDSTONE_LAMP, function() : Block{
1547 return Blocks::REDSTONE_LAMP()
1548 ->setPowered(true);
1549 });
1550 $this->map(Ids::LIT_REDSTONE_ORE, function() : Block{
1551 return Blocks::REDSTONE_ORE()
1552 ->setLit(true);
1553 });
1554 $this->map(Ids::LIT_SMOKER, function(Reader $in) : Block{
1555 return Blocks::SMOKER()
1556 ->setFacing($in->readCardinalHorizontalFacing())
1557 ->setLit(true);
1558 });
1559 $this->map(Ids::LOOM, function(Reader $in) : Block{
1560 return Blocks::LOOM()
1561 ->setFacing($in->readLegacyHorizontalFacing());
1562 });
1563 $this->map(Ids::MATERIAL_REDUCER, fn(Reader $in) => Blocks::MATERIAL_REDUCER()
1564 ->setFacing(Facing::opposite($in->readLegacyHorizontalFacing()))
1565 );
1566 $this->map(Ids::MEDIUM_AMETHYST_BUD, function(Reader $in) : Block{
1567 return Blocks::AMETHYST_CLUSTER()
1568 ->setStage(AmethystCluster::STAGE_MEDIUM_BUD)
1569 ->setFacing($in->readBlockFace());
1570 });
1571 $this->map(Ids::MELON_STEM, fn(Reader $in) => Helper::decodeStem(Blocks::MELON_STEM(), $in));
1572 $this->mapSlab(Ids::MOSSY_COBBLESTONE_SLAB, Ids::MOSSY_COBBLESTONE_DOUBLE_SLAB, fn() => Blocks::MOSSY_COBBLESTONE_SLAB());
1573 $this->mapStairs(Ids::MOSSY_COBBLESTONE_STAIRS, fn() => Blocks::MOSSY_COBBLESTONE_STAIRS());
1574 $this->map(Ids::MOSSY_COBBLESTONE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::MOSSY_COBBLESTONE_WALL(), $in));
1575 $this->mapSlab(Ids::MOSSY_STONE_BRICK_SLAB, Ids::MOSSY_STONE_BRICK_DOUBLE_SLAB, fn() => Blocks::MOSSY_STONE_BRICK_SLAB());
1576 $this->mapStairs(Ids::MOSSY_STONE_BRICK_STAIRS, fn() => Blocks::MOSSY_STONE_BRICK_STAIRS());
1577 $this->map(Ids::MOSSY_STONE_BRICK_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::MOSSY_STONE_BRICK_WALL(), $in));
1578 $this->mapSlab(Ids::MUD_BRICK_SLAB, Ids::MUD_BRICK_DOUBLE_SLAB, fn() => Blocks::MUD_BRICK_SLAB());
1579 $this->mapStairs(Ids::MUD_BRICK_STAIRS, fn() => Blocks::MUD_BRICK_STAIRS());
1580 $this->map(Ids::MUD_BRICK_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::MUD_BRICK_WALL(), $in));
1581 $this->map(Ids::MUDDY_MANGROVE_ROOTS, function(Reader $in) : Block{
1582 return Blocks::MUDDY_MANGROVE_ROOTS()
1583 ->setAxis($in->readPillarAxis());
1584 });
1585 $this->mapSlab(Ids::NETHER_BRICK_SLAB, Ids::NETHER_BRICK_DOUBLE_SLAB, fn() => Blocks::NETHER_BRICK_SLAB());
1586 $this->mapStairs(Ids::NETHER_BRICK_STAIRS, fn() => Blocks::NETHER_BRICK_STAIRS());
1587 $this->map(Ids::NETHER_BRICK_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::NETHER_BRICK_WALL(), $in));
1588 $this->map(Ids::NETHER_WART, function(Reader $in) : Block{
1589 return Blocks::NETHER_WART()
1590 ->setAge($in->readBoundedInt(StateNames::AGE, 0, 3));
1591 });
1592 $this->mapSlab(Ids::NORMAL_STONE_SLAB, Ids::NORMAL_STONE_DOUBLE_SLAB, fn() => Blocks::STONE_SLAB());
1593 $this->mapStairs(Ids::NORMAL_STONE_STAIRS, fn() => Blocks::STONE_STAIRS());
1594 $this->map(Ids::OCHRE_FROGLIGHT, fn(Reader $in) => Blocks::FROGLIGHT()->setFroglightType(FroglightType::OCHRE)->setAxis($in->readPillarAxis()));
1595 $this->map(Ids::PEARLESCENT_FROGLIGHT, fn(Reader $in) => Blocks::FROGLIGHT()->setFroglightType(FroglightType::PEARLESCENT)->setAxis($in->readPillarAxis()));
1596 $this->mapSlab(Ids::PETRIFIED_OAK_SLAB, Ids::PETRIFIED_OAK_DOUBLE_SLAB, fn() => Blocks::FAKE_WOODEN_SLAB());
1597 $this->map(Ids::PINK_PETALS, function(Reader $in) : Block{
1598 //Pink petals only uses 0-3, but GROWTH state can go up to 7
1599 $growth = $in->readBoundedInt(StateNames::GROWTH, 0, 7);
1600 return Blocks::PINK_PETALS()
1601 ->setFacing($in->readCardinalHorizontalFacing())
1602 ->setCount(min($growth + 1, PinkPetals::MAX_COUNT));
1603 });
1604 $this->map(Ids::PITCHER_CROP, function(Reader $in) : Block{
1605 $growth = $in->readBoundedInt(StateNames::GROWTH, 0, 7);
1606 $top = $in->readBool(StateNames::UPPER_BLOCK_BIT);
1607 if($growth <= PitcherCrop::MAX_AGE){
1608 //top pitcher crop with age 0-2 is an invalid state
1609 //only the bottom half should exist in this case
1610 return $top ? Blocks::AIR() : Blocks::PITCHER_CROP()->setAge($growth);
1611 }
1612 return Blocks::DOUBLE_PITCHER_CROP()
1613 ->setAge(min($growth - PitcherCrop::MAX_AGE - 1, DoublePitcherCrop::MAX_AGE))
1614 ->setTop($top);
1615 });
1616 $this->map(Ids::PITCHER_PLANT, function(Reader $in) : Block{
1617 return Blocks::PITCHER_PLANT()
1618 ->setTop($in->readBool(StateNames::UPPER_BLOCK_BIT));
1619 });
1620 $this->mapSlab(Ids::POLISHED_ANDESITE_SLAB, Ids::POLISHED_ANDESITE_DOUBLE_SLAB, fn() => Blocks::POLISHED_ANDESITE_SLAB());
1621 $this->mapStairs(Ids::POLISHED_ANDESITE_STAIRS, fn() => Blocks::POLISHED_ANDESITE_STAIRS());
1622 $this->map(Ids::POLISHED_BASALT, function(Reader $in) : Block{
1623 return Blocks::POLISHED_BASALT()
1624 ->setAxis($in->readPillarAxis());
1625 });
1626 $this->map(Ids::POLISHED_BLACKSTONE_BUTTON, fn(Reader $in) => Helper::decodeButton(Blocks::POLISHED_BLACKSTONE_BUTTON(), $in));
1627 $this->mapSlab(Ids::POLISHED_BLACKSTONE_SLAB, Ids::POLISHED_BLACKSTONE_DOUBLE_SLAB, fn() => Blocks::POLISHED_BLACKSTONE_SLAB());
1628 $this->map(Ids::POLISHED_BLACKSTONE_PRESSURE_PLATE, fn(Reader $in) => Helper::decodeSimplePressurePlate(Blocks::POLISHED_BLACKSTONE_PRESSURE_PLATE(), $in));
1629 $this->mapStairs(Ids::POLISHED_BLACKSTONE_STAIRS, fn() => Blocks::POLISHED_BLACKSTONE_STAIRS());
1630 $this->map(Ids::POLISHED_BLACKSTONE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::POLISHED_BLACKSTONE_WALL(), $in));
1631 $this->mapSlab(Ids::POLISHED_BLACKSTONE_BRICK_SLAB, Ids::POLISHED_BLACKSTONE_BRICK_DOUBLE_SLAB, fn() => Blocks::POLISHED_BLACKSTONE_BRICK_SLAB());
1632 $this->mapStairs(Ids::POLISHED_BLACKSTONE_BRICK_STAIRS, fn() => Blocks::POLISHED_BLACKSTONE_BRICK_STAIRS());
1633 $this->map(Ids::POLISHED_BLACKSTONE_BRICK_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::POLISHED_BLACKSTONE_BRICK_WALL(), $in));
1634 $this->mapSlab(Ids::POLISHED_DEEPSLATE_SLAB, Ids::POLISHED_DEEPSLATE_DOUBLE_SLAB, fn() => Blocks::POLISHED_DEEPSLATE_SLAB());
1635 $this->mapStairs(Ids::POLISHED_DEEPSLATE_STAIRS, fn() => Blocks::POLISHED_DEEPSLATE_STAIRS());
1636 $this->map(Ids::POLISHED_DEEPSLATE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::POLISHED_DEEPSLATE_WALL(), $in));
1637 $this->mapSlab(Ids::POLISHED_DIORITE_SLAB, Ids::POLISHED_DIORITE_DOUBLE_SLAB, fn() => Blocks::POLISHED_DIORITE_SLAB());
1638 $this->mapStairs(Ids::POLISHED_DIORITE_STAIRS, fn() => Blocks::POLISHED_DIORITE_STAIRS());
1639 $this->mapSlab(Ids::POLISHED_GRANITE_SLAB, Ids::POLISHED_GRANITE_DOUBLE_SLAB, fn() => Blocks::POLISHED_GRANITE_SLAB());
1640 $this->mapStairs(Ids::POLISHED_GRANITE_STAIRS, fn() => Blocks::POLISHED_GRANITE_STAIRS());
1641 $this->mapSlab(Ids::POLISHED_TUFF_SLAB, Ids::POLISHED_TUFF_DOUBLE_SLAB, fn() => Blocks::POLISHED_TUFF_SLAB());
1642 $this->mapStairs(Ids::POLISHED_TUFF_STAIRS, fn() => Blocks::POLISHED_TUFF_STAIRS());
1643 $this->map(Ids::POLISHED_TUFF_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::POLISHED_TUFF_WALL(), $in));
1644 $this->map(Ids::PORTAL, function(Reader $in) : Block{
1645 return Blocks::NETHER_PORTAL()
1646 ->setAxis(match($value = $in->readString(StateNames::PORTAL_AXIS)){
1647 StringValues::PORTAL_AXIS_UNKNOWN => Axis::X,
1648 StringValues::PORTAL_AXIS_X => Axis::X,
1649 StringValues::PORTAL_AXIS_Z => Axis::Z,
1650 default => throw $in->badValueException(StateNames::PORTAL_AXIS, $value),
1651 });
1652 });
1653 $this->map(Ids::POTATOES, fn(Reader $in) => Helper::decodeCrops(Blocks::POTATOES(), $in));
1654 $this->map(Ids::POWERED_COMPARATOR, fn(Reader $in) => Helper::decodeComparator(Blocks::REDSTONE_COMPARATOR(), $in));
1655 $this->map(Ids::POWERED_REPEATER, fn(Reader $in) => Helper::decodeRepeater(Blocks::REDSTONE_REPEATER(), $in)
1656 ->setPowered(true));
1657 $this->mapSlab(Ids::PRISMARINE_BRICK_SLAB, Ids::PRISMARINE_BRICK_DOUBLE_SLAB, fn() => Blocks::PRISMARINE_BRICKS_SLAB());
1658 $this->mapStairs(Ids::PRISMARINE_BRICKS_STAIRS, fn() => Blocks::PRISMARINE_BRICKS_STAIRS());
1659 $this->map(Ids::PRISMARINE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::PRISMARINE_WALL(), $in));
1660 $this->mapSlab(Ids::PRISMARINE_SLAB, Ids::PRISMARINE_DOUBLE_SLAB, fn() => Blocks::PRISMARINE_SLAB());
1661 $this->mapStairs(Ids::PRISMARINE_STAIRS, fn() => Blocks::PRISMARINE_STAIRS());
1662 $this->map(Ids::PUMPKIN, function(Reader $in) : Block{
1663 $in->ignored(StateNames::MC_CARDINAL_DIRECTION); //obsolete
1664 return Blocks::PUMPKIN();
1665 });
1666 $this->map(Ids::PUMPKIN_STEM, fn(Reader $in) => Helper::decodeStem(Blocks::PUMPKIN_STEM(), $in));
1667 $this->map(Ids::PURPUR_BLOCK, function(Reader $in) : Block{
1668 $in->ignored(StateNames::PILLAR_AXIS); //???
1669 return Blocks::PURPUR();
1670 });
1671 $this->map(Ids::PURPUR_PILLAR, fn(Reader $in) => Blocks::PURPUR_PILLAR()->setAxis($in->readPillarAxis()));
1672 $this->mapSlab(Ids::PURPUR_SLAB, Ids::PURPUR_DOUBLE_SLAB, fn() => Blocks::PURPUR_SLAB());
1673 $this->mapStairs(Ids::PURPUR_STAIRS, fn() => Blocks::PURPUR_STAIRS());
1674 $this->map(Ids::QUARTZ_BLOCK, function(Reader $in) : Opaque{
1675 $in->ignored(StateNames::PILLAR_AXIS);
1676 return Blocks::QUARTZ();
1677 });
1678 $this->map(Ids::QUARTZ_PILLAR, function(Reader $in) : Block{
1679 return Blocks::QUARTZ_PILLAR()
1680 ->setAxis($in->readPillarAxis());
1681 });
1682 $this->mapSlab(Ids::QUARTZ_SLAB, Ids::QUARTZ_DOUBLE_SLAB, fn() => Blocks::QUARTZ_SLAB());
1683 $this->mapStairs(Ids::QUARTZ_STAIRS, fn() => Blocks::QUARTZ_STAIRS());
1684 $this->map(Ids::RAIL, function(Reader $in) : Block{
1685 return Blocks::RAIL()
1686 ->setShape($in->readBoundedInt(StateNames::RAIL_DIRECTION, 0, 9));
1687 });
1688 $this->map(Ids::RED_MUSHROOM_BLOCK, fn(Reader $in) => Helper::decodeMushroomBlock(Blocks::RED_MUSHROOM_BLOCK(), $in));
1689 $this->mapSlab(Ids::RED_NETHER_BRICK_SLAB, Ids::RED_NETHER_BRICK_DOUBLE_SLAB, fn() => Blocks::RED_NETHER_BRICK_SLAB());
1690 $this->mapStairs(Ids::RED_NETHER_BRICK_STAIRS, fn() => Blocks::RED_NETHER_BRICK_STAIRS());
1691 $this->map(Ids::RED_NETHER_BRICK_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::RED_NETHER_BRICK_WALL(), $in));
1692 $this->mapSlab(Ids::RED_SANDSTONE_SLAB, Ids::RED_SANDSTONE_DOUBLE_SLAB, fn() => Blocks::RED_SANDSTONE_SLAB());
1693 $this->mapStairs(Ids::RED_SANDSTONE_STAIRS, fn() => Blocks::RED_SANDSTONE_STAIRS());
1694 $this->map(Ids::RED_SANDSTONE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::RED_SANDSTONE_WALL(), $in));
1695 $this->map(Ids::REDSTONE_LAMP, function() : Block{
1696 return Blocks::REDSTONE_LAMP()
1697 ->setPowered(false);
1698 });
1699 $this->map(Ids::REDSTONE_ORE, function() : Block{
1700 return Blocks::REDSTONE_ORE()
1701 ->setLit(false);
1702 });
1703 $this->map(Ids::REDSTONE_TORCH, function(Reader $in) : Block{
1704 return Blocks::REDSTONE_TORCH()
1705 ->setFacing($in->readTorchFacing())
1706 ->setLit(true);
1707 });
1708 $this->map(Ids::REDSTONE_WIRE, function(Reader $in) : Block{
1709 return Blocks::REDSTONE_WIRE()
1710 ->setOutputSignalStrength($in->readBoundedInt(StateNames::REDSTONE_SIGNAL, 0, 15));
1711 });
1712 $this->map(Ids::REEDS, function(Reader $in) : Block{
1713 return Blocks::SUGARCANE()
1714 ->setAge($in->readBoundedInt(StateNames::AGE, 0, 15));
1715 });
1716 $this->mapSlab(Ids::RESIN_BRICK_SLAB, Ids::RESIN_BRICK_DOUBLE_SLAB, fn() => Blocks::RESIN_BRICK_SLAB());
1717 $this->mapStairs(Ids::RESIN_BRICK_STAIRS, fn() => Blocks::RESIN_BRICK_STAIRS());
1718 $this->map(Ids::RESIN_BRICK_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::RESIN_BRICK_WALL(), $in));
1719 $this->map(Ids::RESIN_CLUMP, fn(Reader $in) => Blocks::RESIN_CLUMP()->setFaces($in->readFacingFlags()));
1720 $this->mapSlab(Ids::SANDSTONE_SLAB, Ids::SANDSTONE_DOUBLE_SLAB, fn() => Blocks::SANDSTONE_SLAB());
1721 $this->mapStairs(Ids::SANDSTONE_STAIRS, fn() => Blocks::SANDSTONE_STAIRS());
1722 $this->map(Ids::SANDSTONE_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::SANDSTONE_WALL(), $in));
1723 $this->map(Ids::SEA_PICKLE, function(Reader $in) : Block{
1724 return Blocks::SEA_PICKLE()
1725 ->setCount($in->readBoundedInt(StateNames::CLUSTER_COUNT, 0, 3) + 1)
1726 ->setUnderwater(!$in->readBool(StateNames::DEAD_BIT));
1727 });
1728 $this->map(Ids::SMOKER, function(Reader $in) : Block{
1729 return Blocks::SMOKER()
1730 ->setFacing($in->readCardinalHorizontalFacing())
1731 ->setLit(false);
1732 });
1733 $this->map(Ids::SMALL_AMETHYST_BUD, function(Reader $in) : Block{
1734 return Blocks::AMETHYST_CLUSTER()
1735 ->setStage(AmethystCluster::STAGE_SMALL_BUD)
1736 ->setFacing($in->readBlockFace());
1737 });
1738 $this->map(Ids::SMALL_DRIPLEAF_BLOCK, function(Reader $in) : Block{
1739 return Blocks::SMALL_DRIPLEAF()
1740 ->setFacing($in->readCardinalHorizontalFacing())
1741 ->setTop($in->readBool(StateNames::UPPER_BLOCK_BIT));
1742 });
1743 $this->map(Ids::SMOOTH_QUARTZ, function(Reader $in) : Block{
1744 $in->ignored(StateNames::PILLAR_AXIS);
1745 return Blocks::SMOOTH_QUARTZ();
1746 });
1747 $this->mapSlab(Ids::SMOOTH_QUARTZ_SLAB, Ids::SMOOTH_QUARTZ_DOUBLE_SLAB, fn() => Blocks::SMOOTH_QUARTZ_SLAB());
1748 $this->mapStairs(Ids::SMOOTH_QUARTZ_STAIRS, fn() => Blocks::SMOOTH_QUARTZ_STAIRS());
1749 $this->mapSlab(Ids::SMOOTH_RED_SANDSTONE_SLAB, Ids::SMOOTH_RED_SANDSTONE_DOUBLE_SLAB, fn() => Blocks::SMOOTH_RED_SANDSTONE_SLAB());
1750 $this->mapStairs(Ids::SMOOTH_RED_SANDSTONE_STAIRS, fn() => Blocks::SMOOTH_RED_SANDSTONE_STAIRS());
1751 $this->mapSlab(Ids::SMOOTH_SANDSTONE_SLAB, Ids::SMOOTH_SANDSTONE_DOUBLE_SLAB, fn() => Blocks::SMOOTH_SANDSTONE_SLAB());
1752 $this->mapStairs(Ids::SMOOTH_SANDSTONE_STAIRS, fn() => Blocks::SMOOTH_SANDSTONE_STAIRS());
1753 $this->mapSlab(Ids::SMOOTH_STONE_SLAB, Ids::SMOOTH_STONE_DOUBLE_SLAB, fn() => Blocks::SMOOTH_STONE_SLAB());
1754 $this->map(Ids::SNOW_LAYER, function(Reader $in) : Block{
1755 $in->ignored(StateNames::COVERED_BIT); //seems to be useless
1756 return Blocks::SNOW_LAYER()->setLayers($in->readBoundedInt(StateNames::HEIGHT, 0, 7) + 1);
1757 });
1758 $this->map(Ids::SOUL_CAMPFIRE, function(Reader $in) : Block{
1759 return Blocks::SOUL_CAMPFIRE()
1760 ->setFacing($in->readCardinalHorizontalFacing())
1761 ->setLit(!$in->readBool(StateNames::EXTINGUISHED));
1762 });
1763 $this->map(Ids::SOUL_FIRE, function(Reader $in) : Block{
1764 $in->ignored(StateNames::AGE); //this is useless for soul fire, since it doesn't have the logic associated
1765 return Blocks::SOUL_FIRE();
1766 });
1767 $this->map(Ids::SOUL_LANTERN, function(Reader $in) : Block{
1768 return Blocks::SOUL_LANTERN()
1769 ->setHanging($in->readBool(StateNames::HANGING));
1770 });
1771 $this->map(Ids::SOUL_TORCH, function(Reader $in) : Block{
1772 return Blocks::SOUL_TORCH()
1773 ->setFacing($in->readTorchFacing());
1774 });
1775 $this->map(Ids::STANDING_BANNER, function(Reader $in) : Block{
1776 return Blocks::BANNER()
1777 ->setRotation($in->readBoundedInt(StateNames::GROUND_SIGN_DIRECTION, 0, 15));
1778 });
1779 $this->mapSlab(Ids::STONE_BRICK_SLAB, Ids::STONE_BRICK_DOUBLE_SLAB, fn() => Blocks::STONE_BRICK_SLAB());
1780 $this->mapStairs(Ids::STONE_BRICK_STAIRS, fn() => Blocks::STONE_BRICK_STAIRS());
1781 $this->map(Ids::STONE_BRICK_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::STONE_BRICK_WALL(), $in));
1782 $this->map(Ids::STONE_BUTTON, fn(Reader $in) => Helper::decodeButton(Blocks::STONE_BUTTON(), $in));
1783 $this->map(Ids::STONE_PRESSURE_PLATE, fn(Reader $in) => Helper::decodeSimplePressurePlate(Blocks::STONE_PRESSURE_PLATE(), $in));
1784 $this->mapStairs(Ids::STONE_STAIRS, fn() => Blocks::COBBLESTONE_STAIRS());
1785 $this->map(Ids::STONECUTTER_BLOCK, function(Reader $in) : Block{
1786 return Blocks::STONECUTTER()
1787 ->setFacing($in->readCardinalHorizontalFacing());
1788 });
1789 $this->map(Ids::SWEET_BERRY_BUSH, function(Reader $in) : Block{
1790 //berry bush only wants 0-3, but it can be bigger in MCPE due to misuse of GROWTH state which goes up to 7
1791 $growth = $in->readBoundedInt(StateNames::GROWTH, 0, 7);
1792 return Blocks::SWEET_BERRY_BUSH()
1793 ->setAge(min($growth, SweetBerryBush::STAGE_MATURE));
1794 });
1795 $this->map(Ids::TNT, function(Reader $in) : Block{
1796 return Blocks::TNT()
1797 ->setUnstable($in->readBool(StateNames::EXPLODE_BIT))
1798 ->setWorksUnderwater(false);
1799 });
1800 $this->map(Ids::TORCH, function(Reader $in) : Block{
1801 return Blocks::TORCH()
1802 ->setFacing($in->readTorchFacing());
1803 });
1804 $this->map(Ids::TORCHFLOWER_CROP, function(Reader $in) : Block{
1805 return Blocks::TORCHFLOWER_CROP()
1806 //this property can have values 0-7, but only 0-1 are valid
1807 ->setReady($in->readBoundedInt(StateNames::GROWTH, 0, 7) !== 0);
1808 });
1809 $this->map(Ids::TRAPPED_CHEST, function(Reader $in) : Block{
1810 return Blocks::TRAPPED_CHEST()
1811 ->setFacing($in->readCardinalHorizontalFacing());
1812 });
1813 $this->map(Ids::TRIP_WIRE, function(Reader $in) : Block{
1814 return Blocks::TRIPWIRE()
1815 ->setConnected($in->readBool(StateNames::ATTACHED_BIT))
1816 ->setDisarmed($in->readBool(StateNames::DISARMED_BIT))
1817 ->setSuspended($in->readBool(StateNames::SUSPENDED_BIT))
1818 ->setTriggered($in->readBool(StateNames::POWERED_BIT));
1819 });
1820 $this->map(Ids::TRIPWIRE_HOOK, function(Reader $in) : Block{
1821 return Blocks::TRIPWIRE_HOOK()
1822 ->setConnected($in->readBool(StateNames::ATTACHED_BIT))
1823 ->setFacing($in->readLegacyHorizontalFacing())
1824 ->setPowered($in->readBool(StateNames::POWERED_BIT));
1825 });
1826 $this->mapSlab(Ids::TUFF_BRICK_SLAB, Ids::TUFF_BRICK_DOUBLE_SLAB, fn() => Blocks::TUFF_BRICK_SLAB());
1827 $this->mapStairs(Ids::TUFF_BRICK_STAIRS, fn() => Blocks::TUFF_BRICK_STAIRS());
1828 $this->map(Ids::TUFF_BRICK_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::TUFF_BRICK_WALL(), $in));
1829 $this->mapSlab(Ids::TUFF_SLAB, Ids::TUFF_DOUBLE_SLAB, fn() => Blocks::TUFF_SLAB());
1830 $this->mapStairs(Ids::TUFF_STAIRS, fn() => Blocks::TUFF_STAIRS());
1831 $this->map(Ids::TUFF_WALL, fn(Reader $in) => Helper::decodeWall(Blocks::TUFF_WALL(), $in));
1832 $this->map(Ids::TWISTING_VINES, function(Reader $in) : Block{
1833 return Blocks::TWISTING_VINES()
1834 ->setAge($in->readBoundedInt(StateNames::TWISTING_VINES_AGE, 0, 25));
1835 });
1836 $this->map(Ids::UNDERWATER_TNT, function(Reader $in) : Block{
1837 return Blocks::TNT()
1838 ->setUnstable($in->readBool(StateNames::EXPLODE_BIT))
1839 ->setWorksUnderwater(true);
1840 });
1841 $this->map(Ids::UNDERWATER_TORCH, function(Reader $in) : Block{
1842 return Blocks::UNDERWATER_TORCH()
1843 ->setFacing($in->readTorchFacing());
1844 });
1845 $this->map(Ids::UNLIT_REDSTONE_TORCH, function(Reader $in) : Block{
1846 return Blocks::REDSTONE_TORCH()
1847 ->setFacing($in->readTorchFacing())
1848 ->setLit(false);
1849 });
1850 $this->map(Ids::UNPOWERED_COMPARATOR, fn(Reader $in) => Helper::decodeComparator(Blocks::REDSTONE_COMPARATOR(), $in));
1851 $this->map(Ids::UNPOWERED_REPEATER, fn(Reader $in) => Helper::decodeRepeater(Blocks::REDSTONE_REPEATER(), $in)
1852 ->setPowered(false));
1853 $this->map(Ids::VERDANT_FROGLIGHT, fn(Reader $in) => Blocks::FROGLIGHT()->setFroglightType(FroglightType::VERDANT)->setAxis($in->readPillarAxis()));
1854 $this->map(Ids::VINE, function(Reader $in) : Block{
1855 $vineDirectionFlags = $in->readBoundedInt(StateNames::VINE_DIRECTION_BITS, 0, 15);
1856 return Blocks::VINES()
1857 ->setFace(Facing::NORTH, ($vineDirectionFlags & BlockLegacyMetadata::VINE_FLAG_NORTH) !== 0)
1858 ->setFace(Facing::SOUTH, ($vineDirectionFlags & BlockLegacyMetadata::VINE_FLAG_SOUTH) !== 0)
1859 ->setFace(Facing::WEST, ($vineDirectionFlags & BlockLegacyMetadata::VINE_FLAG_WEST) !== 0)
1860 ->setFace(Facing::EAST, ($vineDirectionFlags & BlockLegacyMetadata::VINE_FLAG_EAST) !== 0);
1861 });
1862 $this->map(Ids::WALL_BANNER, function(Reader $in) : Block{
1863 return Blocks::WALL_BANNER()
1864 ->setFacing($in->readHorizontalFacing());
1865 });
1866 $this->map(Ids::WATER, fn(Reader $in) => Helper::decodeStillLiquid(Blocks::WATER(), $in));
1867
1868 $this->map(Ids::WEEPING_VINES, function(Reader $in) : Block{
1869 return Blocks::WEEPING_VINES()
1870 ->setAge($in->readBoundedInt(StateNames::WEEPING_VINES_AGE, 0, 25));
1871 });
1872 $this->map(Ids::WHEAT, fn(Reader $in) => Helper::decodeCrops(Blocks::WHEAT(), $in));
1873 }
1874
1876 public function deserializeBlock(BlockStateData $blockStateData) : Block{
1877 $id = $blockStateData->getName();
1878 if(!array_key_exists($id, $this->deserializeFuncs)){
1879 throw new UnsupportedBlockStateException("Unknown block ID \"$id\"");
1880 }
1881 $reader = new Reader($blockStateData);
1882 $block = $this->deserializeFuncs[$id]($reader);
1883 $reader->checkUnreadProperties();
1884 return $block;
1885 }
1886}
mapLog(string $unstrippedId, string $strippedId, \Closure $getBlock)