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