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