PocketMine-MP 5.39.3 git-21ae710729750cd637333d673bbbbbc598fc659e
Loading...
Searching...
No Matches
VanillaBlockMappings.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
91use pocketmine\block\utils\BellAttachmentType;
92use pocketmine\block\utils\BrewingStandSlot;
93use pocketmine\block\utils\ChiseledBookshelfSlot;
94use pocketmine\block\utils\CopperOxidation;
95use pocketmine\block\utils\DirtType;
96use pocketmine\block\utils\DripleafState;
97use pocketmine\block\utils\DyeColor;
98use pocketmine\block\utils\FroglightType;
100use pocketmine\block\utils\HorizontalFacingOption;
101use pocketmine\block\utils\LeverFacing;
102use pocketmine\block\utils\MobHeadType;
103use pocketmine\block\utils\MushroomBlockType;
105use pocketmine\block\utils\RailShape;
120use pocketmine\data\bedrock\block\convert\property\FlattenedCaveVinesVariant;
129use function array_map;
130use function min;
131use function range;
132
137
138 public static function init(BlockSerializerDeserializerRegistrar $reg) : void{
139 $commonProperties = CommonProperties::getInstance();
140 self::registerSimpleIdOnlyMappings($reg);
141 self::registerColoredMappings($reg, $commonProperties);
142 self::registerCandleMappings($reg, $commonProperties);
143 self::registerLeavesMappings($reg);
144 self::registerSaplingMappings($reg);
145 self::registerPlantMappings($reg, $commonProperties);
146 self::registerCoralMappings($reg, $commonProperties);
147 self::registerCopperMappings($reg, $commonProperties);
148 self::registerFlattenedEnumMappings($reg, $commonProperties);
149 self::registerFlattenedBoolMappings($reg, $commonProperties);
150 self::registerStoneLikeSlabMappings($reg);
151 self::registerStoneLikeStairMappings($reg);
152 self::registerStoneLikeWallMappings($reg, $commonProperties);
153
154 self::registerWoodMappings($reg, $commonProperties);
155 self::registerTorchMappings($reg, $commonProperties);
156 self::registerChemistryMappings($reg, $commonProperties);
157 self::register1to1CustomMappings($reg, $commonProperties);
158
159 self::registerSplitMappings($reg, $commonProperties);
160 }
161
162 private static function registerSimpleIdOnlyMappings(BlockSerializerDeserializerRegistrar $reg) : void{
163 $reg->mapSimple(Blocks::AIR(), Ids::AIR);
164 $reg->mapSimple(Blocks::AMETHYST(), Ids::AMETHYST_BLOCK);
165 $reg->mapSimple(Blocks::ANCIENT_DEBRIS(), Ids::ANCIENT_DEBRIS);
166 $reg->mapSimple(Blocks::ANDESITE(), Ids::ANDESITE);
167 $reg->mapSimple(Blocks::AZALEA(), Ids::AZALEA);
168 $reg->mapSimple(Blocks::BARRIER(), Ids::BARRIER);
169 $reg->mapSimple(Blocks::BEACON(), Ids::BEACON);
170 $reg->mapSimple(Blocks::BLACKSTONE(), Ids::BLACKSTONE);
171 $reg->mapSimple(Blocks::BLUE_ICE(), Ids::BLUE_ICE);
172 $reg->mapSimple(Blocks::BOOKSHELF(), Ids::BOOKSHELF);
173 $reg->mapSimple(Blocks::BRICKS(), Ids::BRICK_BLOCK);
174 $reg->mapSimple(Blocks::BROWN_MUSHROOM(), Ids::BROWN_MUSHROOM);
175 $reg->mapSimple(Blocks::BUDDING_AMETHYST(), Ids::BUDDING_AMETHYST);
176 $reg->mapSimple(Blocks::CALCITE(), Ids::CALCITE);
177 $reg->mapSimple(Blocks::CARTOGRAPHY_TABLE(), Ids::CARTOGRAPHY_TABLE);
178 $reg->mapSimple(Blocks::CHEMICAL_HEAT(), Ids::CHEMICAL_HEAT);
179 $reg->mapSimple(Blocks::CHISELED_DEEPSLATE(), Ids::CHISELED_DEEPSLATE);
180 $reg->mapSimple(Blocks::CHISELED_NETHER_BRICKS(), Ids::CHISELED_NETHER_BRICKS);
181 $reg->mapSimple(Blocks::CHISELED_POLISHED_BLACKSTONE(), Ids::CHISELED_POLISHED_BLACKSTONE);
182 $reg->mapSimple(Blocks::CHISELED_RED_SANDSTONE(), Ids::CHISELED_RED_SANDSTONE);
183 $reg->mapSimple(Blocks::CHISELED_RESIN_BRICKS(), Ids::CHISELED_RESIN_BRICKS);
184 $reg->mapSimple(Blocks::CHISELED_SANDSTONE(), Ids::CHISELED_SANDSTONE);
185 $reg->mapSimple(Blocks::CHISELED_STONE_BRICKS(), Ids::CHISELED_STONE_BRICKS);
186 $reg->mapSimple(Blocks::CHISELED_TUFF(), Ids::CHISELED_TUFF);
187 $reg->mapSimple(Blocks::CHISELED_TUFF_BRICKS(), Ids::CHISELED_TUFF_BRICKS);
188 $reg->mapSimple(Blocks::CHORUS_PLANT(), Ids::CHORUS_PLANT);
189 $reg->mapSimple(Blocks::CLAY(), Ids::CLAY);
190 $reg->mapSimple(Blocks::COAL(), Ids::COAL_BLOCK);
191 $reg->mapSimple(Blocks::COAL_ORE(), Ids::COAL_ORE);
192 $reg->mapSimple(Blocks::COBBLED_DEEPSLATE(), Ids::COBBLED_DEEPSLATE);
193 $reg->mapSimple(Blocks::COBBLESTONE(), Ids::COBBLESTONE);
194 $reg->mapSimple(Blocks::COBWEB(), Ids::WEB);
195 $reg->mapSimple(Blocks::COPPER_ORE(), Ids::COPPER_ORE);
196 $reg->mapSimple(Blocks::CRACKED_DEEPSLATE_BRICKS(), Ids::CRACKED_DEEPSLATE_BRICKS);
197 $reg->mapSimple(Blocks::CRACKED_DEEPSLATE_TILES(), Ids::CRACKED_DEEPSLATE_TILES);
198 $reg->mapSimple(Blocks::CRACKED_NETHER_BRICKS(), Ids::CRACKED_NETHER_BRICKS);
199 $reg->mapSimple(Blocks::CRACKED_POLISHED_BLACKSTONE_BRICKS(), Ids::CRACKED_POLISHED_BLACKSTONE_BRICKS);
200 $reg->mapSimple(Blocks::CRACKED_STONE_BRICKS(), Ids::CRACKED_STONE_BRICKS);
201 $reg->mapSimple(Blocks::CRAFTING_TABLE(), Ids::CRAFTING_TABLE);
202 $reg->mapSimple(Blocks::CRIMSON_ROOTS(), Ids::CRIMSON_ROOTS);
203 $reg->mapSimple(Blocks::CRYING_OBSIDIAN(), Ids::CRYING_OBSIDIAN);
204 $reg->mapSimple(Blocks::DANDELION(), Ids::DANDELION);
205 $reg->mapSimple(Blocks::CUT_RED_SANDSTONE(), Ids::CUT_RED_SANDSTONE);
206 $reg->mapSimple(Blocks::CUT_SANDSTONE(), Ids::CUT_SANDSTONE);
207 $reg->mapSimple(Blocks::DARK_PRISMARINE(), Ids::DARK_PRISMARINE);
208 $reg->mapSimple(Blocks::DEAD_BUSH(), Ids::DEADBUSH);
209 $reg->mapSimple(Blocks::DEEPSLATE_BRICKS(), Ids::DEEPSLATE_BRICKS);
210 $reg->mapSimple(Blocks::DEEPSLATE_COAL_ORE(), Ids::DEEPSLATE_COAL_ORE);
211 $reg->mapSimple(Blocks::DEEPSLATE_COPPER_ORE(), Ids::DEEPSLATE_COPPER_ORE);
212 $reg->mapSimple(Blocks::DEEPSLATE_DIAMOND_ORE(), Ids::DEEPSLATE_DIAMOND_ORE);
213 $reg->mapSimple(Blocks::DEEPSLATE_EMERALD_ORE(), Ids::DEEPSLATE_EMERALD_ORE);
214 $reg->mapSimple(Blocks::DEEPSLATE_GOLD_ORE(), Ids::DEEPSLATE_GOLD_ORE);
215 $reg->mapSimple(Blocks::DEEPSLATE_IRON_ORE(), Ids::DEEPSLATE_IRON_ORE);
216 $reg->mapSimple(Blocks::DEEPSLATE_LAPIS_LAZULI_ORE(), Ids::DEEPSLATE_LAPIS_ORE);
217 $reg->mapSimple(Blocks::DEEPSLATE_TILES(), Ids::DEEPSLATE_TILES);
218 $reg->mapSimple(Blocks::DIAMOND(), Ids::DIAMOND_BLOCK);
219 $reg->mapSimple(Blocks::DIAMOND_ORE(), Ids::DIAMOND_ORE);
220 $reg->mapSimple(Blocks::DIORITE(), Ids::DIORITE);
221 $reg->mapSimple(Blocks::DRAGON_EGG(), Ids::DRAGON_EGG);
222 $reg->mapSimple(Blocks::DRIED_KELP(), Ids::DRIED_KELP_BLOCK);
223 $reg->mapSimple(Blocks::ELEMENT_ACTINIUM(), Ids::ELEMENT_89);
224 $reg->mapSimple(Blocks::ELEMENT_ALUMINUM(), Ids::ELEMENT_13);
225 $reg->mapSimple(Blocks::ELEMENT_AMERICIUM(), Ids::ELEMENT_95);
226 $reg->mapSimple(Blocks::ELEMENT_ANTIMONY(), Ids::ELEMENT_51);
227 $reg->mapSimple(Blocks::ELEMENT_ARGON(), Ids::ELEMENT_18);
228 $reg->mapSimple(Blocks::ELEMENT_ARSENIC(), Ids::ELEMENT_33);
229 $reg->mapSimple(Blocks::ELEMENT_ASTATINE(), Ids::ELEMENT_85);
230 $reg->mapSimple(Blocks::ELEMENT_BARIUM(), Ids::ELEMENT_56);
231 $reg->mapSimple(Blocks::ELEMENT_BERKELIUM(), Ids::ELEMENT_97);
232 $reg->mapSimple(Blocks::ELEMENT_BERYLLIUM(), Ids::ELEMENT_4);
233 $reg->mapSimple(Blocks::ELEMENT_BISMUTH(), Ids::ELEMENT_83);
234 $reg->mapSimple(Blocks::ELEMENT_BOHRIUM(), Ids::ELEMENT_107);
235 $reg->mapSimple(Blocks::ELEMENT_BORON(), Ids::ELEMENT_5);
236 $reg->mapSimple(Blocks::ELEMENT_BROMINE(), Ids::ELEMENT_35);
237 $reg->mapSimple(Blocks::ELEMENT_CADMIUM(), Ids::ELEMENT_48);
238 $reg->mapSimple(Blocks::ELEMENT_CALCIUM(), Ids::ELEMENT_20);
239 $reg->mapSimple(Blocks::ELEMENT_CALIFORNIUM(), Ids::ELEMENT_98);
240 $reg->mapSimple(Blocks::ELEMENT_CARBON(), Ids::ELEMENT_6);
241 $reg->mapSimple(Blocks::ELEMENT_CERIUM(), Ids::ELEMENT_58);
242 $reg->mapSimple(Blocks::ELEMENT_CESIUM(), Ids::ELEMENT_55);
243 $reg->mapSimple(Blocks::ELEMENT_CHLORINE(), Ids::ELEMENT_17);
244 $reg->mapSimple(Blocks::ELEMENT_CHROMIUM(), Ids::ELEMENT_24);
245 $reg->mapSimple(Blocks::ELEMENT_COBALT(), Ids::ELEMENT_27);
246 $reg->mapSimple(Blocks::ELEMENT_COPERNICIUM(), Ids::ELEMENT_112);
247 $reg->mapSimple(Blocks::ELEMENT_COPPER(), Ids::ELEMENT_29);
248 $reg->mapSimple(Blocks::ELEMENT_CURIUM(), Ids::ELEMENT_96);
249 $reg->mapSimple(Blocks::ELEMENT_DARMSTADTIUM(), Ids::ELEMENT_110);
250 $reg->mapSimple(Blocks::ELEMENT_DUBNIUM(), Ids::ELEMENT_105);
251 $reg->mapSimple(Blocks::ELEMENT_DYSPROSIUM(), Ids::ELEMENT_66);
252 $reg->mapSimple(Blocks::ELEMENT_EINSTEINIUM(), Ids::ELEMENT_99);
253 $reg->mapSimple(Blocks::ELEMENT_ERBIUM(), Ids::ELEMENT_68);
254 $reg->mapSimple(Blocks::ELEMENT_EUROPIUM(), Ids::ELEMENT_63);
255 $reg->mapSimple(Blocks::ELEMENT_FERMIUM(), Ids::ELEMENT_100);
256 $reg->mapSimple(Blocks::ELEMENT_FLEROVIUM(), Ids::ELEMENT_114);
257 $reg->mapSimple(Blocks::ELEMENT_FLUORINE(), Ids::ELEMENT_9);
258 $reg->mapSimple(Blocks::ELEMENT_FRANCIUM(), Ids::ELEMENT_87);
259 $reg->mapSimple(Blocks::ELEMENT_GADOLINIUM(), Ids::ELEMENT_64);
260 $reg->mapSimple(Blocks::ELEMENT_GALLIUM(), Ids::ELEMENT_31);
261 $reg->mapSimple(Blocks::ELEMENT_GERMANIUM(), Ids::ELEMENT_32);
262 $reg->mapSimple(Blocks::ELEMENT_GOLD(), Ids::ELEMENT_79);
263 $reg->mapSimple(Blocks::ELEMENT_HAFNIUM(), Ids::ELEMENT_72);
264 $reg->mapSimple(Blocks::ELEMENT_HASSIUM(), Ids::ELEMENT_108);
265 $reg->mapSimple(Blocks::ELEMENT_HELIUM(), Ids::ELEMENT_2);
266 $reg->mapSimple(Blocks::ELEMENT_HOLMIUM(), Ids::ELEMENT_67);
267 $reg->mapSimple(Blocks::ELEMENT_HYDROGEN(), Ids::ELEMENT_1);
268 $reg->mapSimple(Blocks::ELEMENT_INDIUM(), Ids::ELEMENT_49);
269 $reg->mapSimple(Blocks::ELEMENT_IODINE(), Ids::ELEMENT_53);
270 $reg->mapSimple(Blocks::ELEMENT_IRIDIUM(), Ids::ELEMENT_77);
271 $reg->mapSimple(Blocks::ELEMENT_IRON(), Ids::ELEMENT_26);
272 $reg->mapSimple(Blocks::ELEMENT_KRYPTON(), Ids::ELEMENT_36);
273 $reg->mapSimple(Blocks::ELEMENT_LANTHANUM(), Ids::ELEMENT_57);
274 $reg->mapSimple(Blocks::ELEMENT_LAWRENCIUM(), Ids::ELEMENT_103);
275 $reg->mapSimple(Blocks::ELEMENT_LEAD(), Ids::ELEMENT_82);
276 $reg->mapSimple(Blocks::ELEMENT_LITHIUM(), Ids::ELEMENT_3);
277 $reg->mapSimple(Blocks::ELEMENT_LIVERMORIUM(), Ids::ELEMENT_116);
278 $reg->mapSimple(Blocks::ELEMENT_LUTETIUM(), Ids::ELEMENT_71);
279 $reg->mapSimple(Blocks::ELEMENT_MAGNESIUM(), Ids::ELEMENT_12);
280 $reg->mapSimple(Blocks::ELEMENT_MANGANESE(), Ids::ELEMENT_25);
281 $reg->mapSimple(Blocks::ELEMENT_MEITNERIUM(), Ids::ELEMENT_109);
282 $reg->mapSimple(Blocks::ELEMENT_MENDELEVIUM(), Ids::ELEMENT_101);
283 $reg->mapSimple(Blocks::ELEMENT_MERCURY(), Ids::ELEMENT_80);
284 $reg->mapSimple(Blocks::ELEMENT_MOLYBDENUM(), Ids::ELEMENT_42);
285 $reg->mapSimple(Blocks::ELEMENT_MOSCOVIUM(), Ids::ELEMENT_115);
286 $reg->mapSimple(Blocks::ELEMENT_NEODYMIUM(), Ids::ELEMENT_60);
287 $reg->mapSimple(Blocks::ELEMENT_NEON(), Ids::ELEMENT_10);
288 $reg->mapSimple(Blocks::ELEMENT_NEPTUNIUM(), Ids::ELEMENT_93);
289 $reg->mapSimple(Blocks::ELEMENT_NICKEL(), Ids::ELEMENT_28);
290 $reg->mapSimple(Blocks::ELEMENT_NIHONIUM(), Ids::ELEMENT_113);
291 $reg->mapSimple(Blocks::ELEMENT_NIOBIUM(), Ids::ELEMENT_41);
292 $reg->mapSimple(Blocks::ELEMENT_NITROGEN(), Ids::ELEMENT_7);
293 $reg->mapSimple(Blocks::ELEMENT_NOBELIUM(), Ids::ELEMENT_102);
294 $reg->mapSimple(Blocks::ELEMENT_OGANESSON(), Ids::ELEMENT_118);
295 $reg->mapSimple(Blocks::ELEMENT_OSMIUM(), Ids::ELEMENT_76);
296 $reg->mapSimple(Blocks::ELEMENT_OXYGEN(), Ids::ELEMENT_8);
297 $reg->mapSimple(Blocks::ELEMENT_PALLADIUM(), Ids::ELEMENT_46);
298 $reg->mapSimple(Blocks::ELEMENT_PHOSPHORUS(), Ids::ELEMENT_15);
299 $reg->mapSimple(Blocks::ELEMENT_PLATINUM(), Ids::ELEMENT_78);
300 $reg->mapSimple(Blocks::ELEMENT_PLUTONIUM(), Ids::ELEMENT_94);
301 $reg->mapSimple(Blocks::ELEMENT_POLONIUM(), Ids::ELEMENT_84);
302 $reg->mapSimple(Blocks::ELEMENT_POTASSIUM(), Ids::ELEMENT_19);
303 $reg->mapSimple(Blocks::ELEMENT_PRASEODYMIUM(), Ids::ELEMENT_59);
304 $reg->mapSimple(Blocks::ELEMENT_PROMETHIUM(), Ids::ELEMENT_61);
305 $reg->mapSimple(Blocks::ELEMENT_PROTACTINIUM(), Ids::ELEMENT_91);
306 $reg->mapSimple(Blocks::ELEMENT_RADIUM(), Ids::ELEMENT_88);
307 $reg->mapSimple(Blocks::ELEMENT_RADON(), Ids::ELEMENT_86);
308 $reg->mapSimple(Blocks::ELEMENT_RHENIUM(), Ids::ELEMENT_75);
309 $reg->mapSimple(Blocks::ELEMENT_RHODIUM(), Ids::ELEMENT_45);
310 $reg->mapSimple(Blocks::ELEMENT_ROENTGENIUM(), Ids::ELEMENT_111);
311 $reg->mapSimple(Blocks::ELEMENT_RUBIDIUM(), Ids::ELEMENT_37);
312 $reg->mapSimple(Blocks::ELEMENT_RUTHENIUM(), Ids::ELEMENT_44);
313 $reg->mapSimple(Blocks::ELEMENT_RUTHERFORDIUM(), Ids::ELEMENT_104);
314 $reg->mapSimple(Blocks::ELEMENT_SAMARIUM(), Ids::ELEMENT_62);
315 $reg->mapSimple(Blocks::ELEMENT_SCANDIUM(), Ids::ELEMENT_21);
316 $reg->mapSimple(Blocks::ELEMENT_SEABORGIUM(), Ids::ELEMENT_106);
317 $reg->mapSimple(Blocks::ELEMENT_SELENIUM(), Ids::ELEMENT_34);
318 $reg->mapSimple(Blocks::ELEMENT_SILICON(), Ids::ELEMENT_14);
319 $reg->mapSimple(Blocks::ELEMENT_SILVER(), Ids::ELEMENT_47);
320 $reg->mapSimple(Blocks::ELEMENT_SODIUM(), Ids::ELEMENT_11);
321 $reg->mapSimple(Blocks::ELEMENT_STRONTIUM(), Ids::ELEMENT_38);
322 $reg->mapSimple(Blocks::ELEMENT_SULFUR(), Ids::ELEMENT_16);
323 $reg->mapSimple(Blocks::ELEMENT_TANTALUM(), Ids::ELEMENT_73);
324 $reg->mapSimple(Blocks::ELEMENT_TECHNETIUM(), Ids::ELEMENT_43);
325 $reg->mapSimple(Blocks::ELEMENT_TELLURIUM(), Ids::ELEMENT_52);
326 $reg->mapSimple(Blocks::ELEMENT_TENNESSINE(), Ids::ELEMENT_117);
327 $reg->mapSimple(Blocks::ELEMENT_TERBIUM(), Ids::ELEMENT_65);
328 $reg->mapSimple(Blocks::ELEMENT_THALLIUM(), Ids::ELEMENT_81);
329 $reg->mapSimple(Blocks::ELEMENT_THORIUM(), Ids::ELEMENT_90);
330 $reg->mapSimple(Blocks::ELEMENT_THULIUM(), Ids::ELEMENT_69);
331 $reg->mapSimple(Blocks::ELEMENT_TIN(), Ids::ELEMENT_50);
332 $reg->mapSimple(Blocks::ELEMENT_TITANIUM(), Ids::ELEMENT_22);
333 $reg->mapSimple(Blocks::ELEMENT_TUNGSTEN(), Ids::ELEMENT_74);
334 $reg->mapSimple(Blocks::ELEMENT_URANIUM(), Ids::ELEMENT_92);
335 $reg->mapSimple(Blocks::ELEMENT_VANADIUM(), Ids::ELEMENT_23);
336 $reg->mapSimple(Blocks::ELEMENT_XENON(), Ids::ELEMENT_54);
337 $reg->mapSimple(Blocks::ELEMENT_YTTERBIUM(), Ids::ELEMENT_70);
338 $reg->mapSimple(Blocks::ELEMENT_YTTRIUM(), Ids::ELEMENT_39);
339 $reg->mapSimple(Blocks::ELEMENT_ZERO(), Ids::ELEMENT_0);
340 $reg->mapSimple(Blocks::ELEMENT_ZINC(), Ids::ELEMENT_30);
341 $reg->mapSimple(Blocks::ELEMENT_ZIRCONIUM(), Ids::ELEMENT_40);
342 $reg->mapSimple(Blocks::EMERALD(), Ids::EMERALD_BLOCK);
343 $reg->mapSimple(Blocks::EMERALD_ORE(), Ids::EMERALD_ORE);
344 $reg->mapSimple(Blocks::ENCHANTING_TABLE(), Ids::ENCHANTING_TABLE);
345 $reg->mapSimple(Blocks::END_STONE(), Ids::END_STONE);
346 $reg->mapSimple(Blocks::END_STONE_BRICKS(), Ids::END_BRICKS);
347 $reg->mapSimple(Blocks::FERN(), Ids::FERN);
348 $reg->mapSimple(Blocks::FLETCHING_TABLE(), Ids::FLETCHING_TABLE);
349 $reg->mapSimple(Blocks::FLOWERING_AZALEA(), Ids::FLOWERING_AZALEA);
350 $reg->mapSimple(Blocks::GILDED_BLACKSTONE(), Ids::GILDED_BLACKSTONE);
351 $reg->mapSimple(Blocks::GLASS(), Ids::GLASS);
352 $reg->mapSimple(Blocks::GLASS_PANE(), Ids::GLASS_PANE);
353 $reg->mapSimple(Blocks::GLOWING_OBSIDIAN(), Ids::GLOWINGOBSIDIAN);
354 $reg->mapSimple(Blocks::GLOWSTONE(), Ids::GLOWSTONE);
355 $reg->mapSimple(Blocks::GOLD(), Ids::GOLD_BLOCK);
356 $reg->mapSimple(Blocks::GOLD_ORE(), Ids::GOLD_ORE);
357 $reg->mapSimple(Blocks::GRANITE(), Ids::GRANITE);
358 $reg->mapSimple(Blocks::GRASS(), Ids::GRASS_BLOCK);
359 $reg->mapSimple(Blocks::GRASS_PATH(), Ids::GRASS_PATH);
360 $reg->mapSimple(Blocks::GRAVEL(), Ids::GRAVEL);
361 $reg->mapSimple(Blocks::HANGING_ROOTS(), Ids::HANGING_ROOTS);
362 $reg->mapSimple(Blocks::HARDENED_CLAY(), Ids::HARDENED_CLAY);
363 $reg->mapSimple(Blocks::HARDENED_GLASS(), Ids::HARD_GLASS);
364 $reg->mapSimple(Blocks::HARDENED_GLASS_PANE(), Ids::HARD_GLASS_PANE);
365 $reg->mapSimple(Blocks::HONEYCOMB(), Ids::HONEYCOMB_BLOCK);
366 $reg->mapSimple(Blocks::ICE(), Ids::ICE);
367 $reg->mapSimple(Blocks::INFESTED_CHISELED_STONE_BRICK(), Ids::INFESTED_CHISELED_STONE_BRICKS);
368 $reg->mapSimple(Blocks::INFESTED_COBBLESTONE(), Ids::INFESTED_COBBLESTONE);
369 $reg->mapSimple(Blocks::INFESTED_CRACKED_STONE_BRICK(), Ids::INFESTED_CRACKED_STONE_BRICKS);
370 $reg->mapSimple(Blocks::INFESTED_MOSSY_STONE_BRICK(), Ids::INFESTED_MOSSY_STONE_BRICKS);
371 $reg->mapSimple(Blocks::INFESTED_STONE(), Ids::INFESTED_STONE);
372 $reg->mapSimple(Blocks::INFESTED_STONE_BRICK(), Ids::INFESTED_STONE_BRICKS);
373 $reg->mapSimple(Blocks::INFO_UPDATE(), Ids::INFO_UPDATE);
374 $reg->mapSimple(Blocks::INFO_UPDATE2(), Ids::INFO_UPDATE2);
375 $reg->mapSimple(Blocks::INVISIBLE_BEDROCK(), Ids::INVISIBLE_BEDROCK);
376 $reg->mapSimple(Blocks::IRON(), Ids::IRON_BLOCK);
377 $reg->mapSimple(Blocks::IRON_BARS(), Ids::IRON_BARS);
378 $reg->mapSimple(Blocks::IRON_ORE(), Ids::IRON_ORE);
379 $reg->mapSimple(Blocks::JUKEBOX(), Ids::JUKEBOX);
380 $reg->mapSimple(Blocks::LAPIS_LAZULI(), Ids::LAPIS_BLOCK);
381 $reg->mapSimple(Blocks::LAPIS_LAZULI_ORE(), Ids::LAPIS_ORE);
382 $reg->mapSimple(Blocks::LEGACY_STONECUTTER(), Ids::STONECUTTER);
383 $reg->mapSimple(Blocks::LILY_PAD(), Ids::WATERLILY);
384 $reg->mapSimple(Blocks::MAGMA(), Ids::MAGMA);
385 $reg->mapSimple(Blocks::MANGROVE_ROOTS(), Ids::MANGROVE_ROOTS);
386 $reg->mapSimple(Blocks::MELON(), Ids::MELON_BLOCK);
387 $reg->mapSimple(Blocks::MONSTER_SPAWNER(), Ids::MOB_SPAWNER);
388 $reg->mapSimple(Blocks::MOSSY_COBBLESTONE(), Ids::MOSSY_COBBLESTONE);
389 $reg->mapSimple(Blocks::MOSSY_STONE_BRICKS(), Ids::MOSSY_STONE_BRICKS);
390 $reg->mapSimple(Blocks::MUD(), Ids::MUD);
391 $reg->mapSimple(Blocks::MUD_BRICKS(), Ids::MUD_BRICKS);
392 $reg->mapSimple(Blocks::MYCELIUM(), Ids::MYCELIUM);
393 $reg->mapSimple(Blocks::NETHERITE(), Ids::NETHERITE_BLOCK);
394 $reg->mapSimple(Blocks::NETHERRACK(), Ids::NETHERRACK);
395 $reg->mapSimple(Blocks::NETHER_BRICKS(), Ids::NETHER_BRICK);
396 $reg->mapSimple(Blocks::NETHER_BRICK_FENCE(), Ids::NETHER_BRICK_FENCE);
397 $reg->mapSimple(Blocks::NETHER_GOLD_ORE(), Ids::NETHER_GOLD_ORE);
398 $reg->mapSimple(Blocks::NETHER_QUARTZ_ORE(), Ids::QUARTZ_ORE);
399 $reg->mapSimple(Blocks::NETHER_REACTOR_CORE(), Ids::NETHERREACTOR);
400 $reg->mapSimple(Blocks::NETHER_WART_BLOCK(), Ids::NETHER_WART_BLOCK);
401 $reg->mapSimple(Blocks::NOTE_BLOCK(), Ids::NOTEBLOCK);
402 $reg->mapSimple(Blocks::OBSIDIAN(), Ids::OBSIDIAN);
403 $reg->mapSimple(Blocks::PACKED_ICE(), Ids::PACKED_ICE);
404 $reg->mapSimple(Blocks::PACKED_MUD(), Ids::PACKED_MUD);
405 $reg->mapSimple(Blocks::PODZOL(), Ids::PODZOL);
406 $reg->mapSimple(Blocks::POLISHED_ANDESITE(), Ids::POLISHED_ANDESITE);
407 $reg->mapSimple(Blocks::POLISHED_BLACKSTONE(), Ids::POLISHED_BLACKSTONE);
408 $reg->mapSimple(Blocks::POLISHED_BLACKSTONE_BRICKS(), Ids::POLISHED_BLACKSTONE_BRICKS);
409 $reg->mapSimple(Blocks::POLISHED_DEEPSLATE(), Ids::POLISHED_DEEPSLATE);
410 $reg->mapSimple(Blocks::POLISHED_DIORITE(), Ids::POLISHED_DIORITE);
411 $reg->mapSimple(Blocks::POLISHED_GRANITE(), Ids::POLISHED_GRANITE);
412 $reg->mapSimple(Blocks::POLISHED_TUFF(), Ids::POLISHED_TUFF);
413 $reg->mapSimple(Blocks::PRISMARINE(), Ids::PRISMARINE);
414 $reg->mapSimple(Blocks::PRISMARINE_BRICKS(), Ids::PRISMARINE_BRICKS);
415 $reg->mapSimple(Blocks::QUARTZ_BRICKS(), Ids::QUARTZ_BRICKS);
416 $reg->mapSimple(Blocks::RAW_COPPER(), Ids::RAW_COPPER_BLOCK);
417 $reg->mapSimple(Blocks::RAW_GOLD(), Ids::RAW_GOLD_BLOCK);
418 $reg->mapSimple(Blocks::RAW_IRON(), Ids::RAW_IRON_BLOCK);
419 $reg->mapSimple(Blocks::REDSTONE(), Ids::REDSTONE_BLOCK);
420 $reg->mapSimple(Blocks::RED_MUSHROOM(), Ids::RED_MUSHROOM);
421 $reg->mapSimple(Blocks::RED_NETHER_BRICKS(), Ids::RED_NETHER_BRICK);
422 $reg->mapSimple(Blocks::RED_SAND(), Ids::RED_SAND);
423 $reg->mapSimple(Blocks::RED_SANDSTONE(), Ids::RED_SANDSTONE);
424 $reg->mapSimple(Blocks::REINFORCED_DEEPSLATE(), Ids::REINFORCED_DEEPSLATE);
425 $reg->mapSimple(Blocks::RESERVED6(), Ids::RESERVED6);
426 $reg->mapSimple(Blocks::RESIN(), Ids::RESIN_BLOCK);
427 $reg->mapSimple(Blocks::RESIN_BRICKS(), Ids::RESIN_BRICKS);
428 $reg->mapSimple(Blocks::SAND(), Ids::SAND);
429 $reg->mapSimple(Blocks::SANDSTONE(), Ids::SANDSTONE);
430 $reg->mapSimple(Blocks::SCULK(), Ids::SCULK);
431 $reg->mapSimple(Blocks::SEA_LANTERN(), Ids::SEA_LANTERN);
432 $reg->mapSimple(Blocks::SHROOMLIGHT(), Ids::SHROOMLIGHT);
433 $reg->mapSimple(Blocks::SHULKER_BOX(), Ids::UNDYED_SHULKER_BOX);
434 $reg->mapSimple(Blocks::SLIME(), Ids::SLIME);
435 $reg->mapSimple(Blocks::SMITHING_TABLE(), Ids::SMITHING_TABLE);
436 $reg->mapSimple(Blocks::SMOOTH_BASALT(), Ids::SMOOTH_BASALT);
437 $reg->mapSimple(Blocks::SMOOTH_RED_SANDSTONE(), Ids::SMOOTH_RED_SANDSTONE);
438 $reg->mapSimple(Blocks::SMOOTH_SANDSTONE(), Ids::SMOOTH_SANDSTONE);
439 $reg->mapSimple(Blocks::SMOOTH_STONE(), Ids::SMOOTH_STONE);
440 $reg->mapSimple(Blocks::SNOW(), Ids::SNOW);
441 $reg->mapSimple(Blocks::SOUL_SAND(), Ids::SOUL_SAND);
442 $reg->mapSimple(Blocks::SOUL_SOIL(), Ids::SOUL_SOIL);
443 $reg->mapSimple(Blocks::SPORE_BLOSSOM(), Ids::SPORE_BLOSSOM);
444 $reg->mapSimple(Blocks::STONE(), Ids::STONE);
445 $reg->mapSimple(Blocks::STONE_BRICKS(), Ids::STONE_BRICKS);
446 $reg->mapSimple(Blocks::STRUCTURE_VOID(), Ids::STRUCTURE_VOID);
447 $reg->mapSimple(Blocks::TALL_GRASS(), Ids::SHORT_GRASS); //no, this is not a typo - tall_grass is now the double block, just to be confusing :(
448 $reg->mapSimple(Blocks::TINTED_GLASS(), Ids::TINTED_GLASS);
449 $reg->mapSimple(Blocks::TORCHFLOWER(), Ids::TORCHFLOWER);
450 $reg->mapSimple(Blocks::TUFF(), Ids::TUFF);
451 $reg->mapSimple(Blocks::TUFF_BRICKS(), Ids::TUFF_BRICKS);
452 $reg->mapSimple(Blocks::WARPED_WART_BLOCK(), Ids::WARPED_WART_BLOCK);
453 $reg->mapSimple(Blocks::WARPED_ROOTS(), Ids::WARPED_ROOTS);
454 $reg->mapSimple(Blocks::WITHER_ROSE(), Ids::WITHER_ROSE);
455
456 $reg->mapSimple(Blocks::ALLIUM(), Ids::ALLIUM);
457 $reg->mapSimple(Blocks::CORNFLOWER(), Ids::CORNFLOWER);
458 $reg->mapSimple(Blocks::AZURE_BLUET(), Ids::AZURE_BLUET);
459 $reg->mapSimple(Blocks::LILY_OF_THE_VALLEY(), Ids::LILY_OF_THE_VALLEY);
460 $reg->mapSimple(Blocks::BLUE_ORCHID(), Ids::BLUE_ORCHID);
461 $reg->mapSimple(Blocks::OXEYE_DAISY(), Ids::OXEYE_DAISY);
462 $reg->mapSimple(Blocks::POPPY(), Ids::POPPY);
463 $reg->mapSimple(Blocks::ORANGE_TULIP(), Ids::ORANGE_TULIP);
464 $reg->mapSimple(Blocks::PINK_TULIP(), Ids::PINK_TULIP);
465 $reg->mapSimple(Blocks::RED_TULIP(), Ids::RED_TULIP);
466 $reg->mapSimple(Blocks::WHITE_TULIP(), Ids::WHITE_TULIP);
467
468 $reg->mapSimple(Blocks::CACTUS_FLOWER(), Ids::CACTUS_FLOWER);
469 $reg->mapSimple(Blocks::CRIMSON_FUNGUS(), Ids::CRIMSON_FUNGUS);
470 $reg->mapSimple(Blocks::WARPED_FUNGUS(), Ids::WARPED_FUNGUS);
471 $reg->mapSimple(Blocks::NETHER_SPROUTS(), Ids::NETHER_SPROUTS);
472 $reg->mapSimple(Blocks::CRIMSON_NYLIUM(), Ids::CRIMSON_NYLIUM);
473 $reg->mapSimple(Blocks::WARPED_NYLIUM(), Ids::WARPED_NYLIUM);
474 }
475
476 private static function registerColoredMappings(BlockSerializerDeserializerRegistrar $reg, CommonProperties $commonProperties) : void{
477 $reg->mapColored(Blocks::STAINED_HARDENED_GLASS(), "minecraft:hard_", "_stained_glass");
478 $reg->mapColored(Blocks::STAINED_HARDENED_GLASS_PANE(), "minecraft:hard_", "_stained_glass_pane");
479
480 $reg->mapColored(Blocks::CARPET(), "minecraft:", "_carpet");
481 $reg->mapColored(Blocks::CONCRETE(), "minecraft:", "_concrete");
482 $reg->mapColored(Blocks::CONCRETE_POWDER(), "minecraft:", "_concrete_powder");
483 $reg->mapColored(Blocks::DYED_SHULKER_BOX(), "minecraft:", "_shulker_box");
484 $reg->mapColored(Blocks::STAINED_CLAY(), "minecraft:", "_terracotta");
485 $reg->mapColored(Blocks::STAINED_GLASS(), "minecraft:", "_stained_glass");
486 $reg->mapColored(Blocks::STAINED_GLASS_PANE(), "minecraft:", "_stained_glass_pane");
487 $reg->mapColored(Blocks::WOOL(), "minecraft:", "_wool");
488
489 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::GLAZED_TERRACOTTA())
490 ->idComponents([
491 "minecraft:",
492 new ValueFromStringProperty("color", ValueMappings::getInstance()->dyeColorWithSilver, fn(GlazedTerracotta $b) => $b->getColor(), fn(GlazedTerracotta $b, DyeColor $v) => $b->setColor($v)),
493 "_glazed_terracotta"
494 ])
495 ->properties([$commonProperties->horizontalFacingClassic])
496 );
497 }
498
499 private static function registerCandleMappings(BlockSerializerDeserializerRegistrar $reg, CommonProperties $commonProperties) : void{
500 $candleProperties = [
501 $commonProperties->lit,
502 new IntProperty(StateNames::CANDLES, 0, 3, fn(Candle $b) => $b->getCount(), fn(Candle $b, int $v) => $b->setCount($v), offset: 1),
503 ];
504 $cakeWithCandleProperties = [$commonProperties->lit];
505 $reg->mapModel(Model::create(Blocks::CANDLE(), Ids::CANDLE)->properties($candleProperties));
506 $reg->mapModel(Model::create(Blocks::CAKE_WITH_CANDLE(), Ids::CANDLE_CAKE)->properties($cakeWithCandleProperties));
507
508 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::DYED_CANDLE())
509 ->idComponents([
510 "minecraft:",
511 $commonProperties->dyeColorIdInfix,
512 "_candle"
513 ])
514 ->properties($candleProperties)
515 );
516 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::CAKE_WITH_DYED_CANDLE())
517 ->idComponents([
518 "minecraft:",
519 $commonProperties->dyeColorIdInfix,
520 "_candle_cake"
521 ])
522 ->properties($cakeWithCandleProperties)
523 );
524 }
525
526 private static function registerLeavesMappings(BlockSerializerDeserializerRegistrar $reg) : void{
527 $properties = [
528 new BoolProperty(StateNames::PERSISTENT_BIT, fn(Leaves $b) => $b->isNoDecay(), fn(Leaves $b, bool $v) => $b->setNoDecay($v)),
529 new BoolProperty(StateNames::UPDATE_BIT, fn(Leaves $b) => $b->isCheckDecay(), fn(Leaves $b, bool $v) => $b->setCheckDecay($v)),
530 ];
531 foreach([
532 Ids::ACACIA_LEAVES => Blocks::ACACIA_LEAVES(),
533 Ids::AZALEA_LEAVES => Blocks::AZALEA_LEAVES(),
534 Ids::AZALEA_LEAVES_FLOWERED => Blocks::FLOWERING_AZALEA_LEAVES(),
535 Ids::BIRCH_LEAVES => Blocks::BIRCH_LEAVES(),
536 Ids::CHERRY_LEAVES => Blocks::CHERRY_LEAVES(),
537 Ids::DARK_OAK_LEAVES => Blocks::DARK_OAK_LEAVES(),
538 Ids::JUNGLE_LEAVES => Blocks::JUNGLE_LEAVES(),
539 Ids::MANGROVE_LEAVES => Blocks::MANGROVE_LEAVES(),
540 Ids::OAK_LEAVES => Blocks::OAK_LEAVES(),
541 Ids::PALE_OAK_LEAVES => Blocks::PALE_OAK_LEAVES(),
542 Ids::SPRUCE_LEAVES => Blocks::SPRUCE_LEAVES()
543 ] as $id => $block){
544 $reg->mapModel(Model::create($block, $id)->properties($properties));
545 }
546 }
547
548 private static function registerSaplingMappings(BlockSerializerDeserializerRegistrar $reg) : void{
549 $properties = [
550 new BoolProperty(StateNames::AGE_BIT, fn(Sapling $b) => $b->isReady(), fn(Sapling $b, bool $v) => $b->setReady($v)),
551 ];
552 foreach([
553 Ids::ACACIA_SAPLING => Blocks::ACACIA_SAPLING(),
554 Ids::BIRCH_SAPLING => Blocks::BIRCH_SAPLING(),
555 Ids::DARK_OAK_SAPLING => Blocks::DARK_OAK_SAPLING(),
556 Ids::JUNGLE_SAPLING => Blocks::JUNGLE_SAPLING(),
557 Ids::OAK_SAPLING => Blocks::OAK_SAPLING(),
558 Ids::SPRUCE_SAPLING => Blocks::SPRUCE_SAPLING(),
559 ] as $id => $block){
560 $reg->mapModel(Model::create($block, $id)->properties($properties));
561 }
562 }
563
564 private static function registerPlantMappings(BlockSerializerDeserializerRegistrar $reg, CommonProperties $commonProperties) : void{
565 $reg->mapModel(Model::create(Blocks::BEETROOTS(), Ids::BEETROOT)->properties([$commonProperties->cropAgeMax7]));
566 $reg->mapModel(Model::create(Blocks::CARROTS(), Ids::CARROTS)->properties([$commonProperties->cropAgeMax7]));
567 $reg->mapModel(Model::create(Blocks::POTATOES(), Ids::POTATOES)->properties([$commonProperties->cropAgeMax7]));
568 $reg->mapModel(Model::create(Blocks::WHEAT(), Ids::WHEAT)->properties([$commonProperties->cropAgeMax7]));
569
570 $reg->mapModel(Model::create(Blocks::MELON_STEM(), Ids::MELON_STEM)->properties($commonProperties->stemProperties));
571 $reg->mapModel(Model::create(Blocks::PUMPKIN_STEM(), Ids::PUMPKIN_STEM)->properties($commonProperties->stemProperties));
572
573 foreach([
574 [Blocks::DOUBLE_TALLGRASS(), Ids::TALL_GRASS],
575 [Blocks::LARGE_FERN(), Ids::LARGE_FERN],
576 [Blocks::LILAC(), Ids::LILAC],
577 [Blocks::PEONY(), Ids::PEONY],
578 [Blocks::ROSE_BUSH(), Ids::ROSE_BUSH],
579 [Blocks::SUNFLOWER(), Ids::SUNFLOWER],
580 ] as [$block, $id]){
581 $reg->mapModel(Model::create($block, $id)->properties([$commonProperties->doublePlantHalf]));
582 }
583
584 foreach([
585 [Blocks::BROWN_MUSHROOM_BLOCK(), Ids::BROWN_MUSHROOM_BLOCK],
586 [Blocks::RED_MUSHROOM_BLOCK(), Ids::RED_MUSHROOM_BLOCK]
587 ] as [$block, $id]){
588 $reg->mapModel(Model::create($block, $id)->properties([
589 new ValueFromIntProperty(StateNames::HUGE_MUSHROOM_BITS, ValueMappings::getInstance()->mushroomBlockType, fn(RedMushroomBlock $b) => $b->getMushroomBlockType(), fn(RedMushroomBlock $b, MushroomBlockType $v) => $b->setMushroomBlockType($v)),
590 ]));
591 }
592
593 $reg->mapModel(Model::create(Blocks::GLOW_LICHEN(), Ids::GLOW_LICHEN)->properties([$commonProperties->multiFacingFlags]));
594 $reg->mapModel(Model::create(Blocks::RESIN_CLUMP(), Ids::RESIN_CLUMP)->properties([$commonProperties->multiFacingFlags]));
595
596 $reg->mapModel(Model::create(Blocks::VINES(), Ids::VINE)->properties([
598 StateNames::VINE_DIRECTION_BITS,
599 EnumFromRawStateMap::int(HorizontalFacingOption::class, fn(HorizontalFacingOption $case) => match($case) {
600 HorizontalFacingOption::NORTH => BlockLegacyMetadata::VINE_FLAG_NORTH,
601 HorizontalFacingOption::SOUTH => BlockLegacyMetadata::VINE_FLAG_SOUTH,
602 HorizontalFacingOption::WEST => BlockLegacyMetadata::VINE_FLAG_WEST,
603 HorizontalFacingOption::EAST => BlockLegacyMetadata::VINE_FLAG_EAST,
604 }),
605 //TODO: hack for lack of HorizontalFacing enum :(
606 fn(Vine $b) => $b->getFaces(),
607 fn(Vine $b, array $v) => $b->setFaces($v)
608 )
609 ]));
610
611 $reg->mapModel(Model::create(Blocks::SWEET_BERRY_BUSH(), Ids::SWEET_BERRY_BUSH)->properties([
612 //TODO: berry bush only wants 0-3, but it can be bigger in MCPE due to misuse of GROWTH state which goes up to 7
613 new IntProperty(StateNames::GROWTH, 0, 7, fn(SweetBerryBush $b) => $b->getAge(), fn(SweetBerryBush $b, int $v) => $b->setAge(min($v, SweetBerryBush::STAGE_MATURE)))
614 ]));
615 $reg->mapModel(Model::create(Blocks::TORCHFLOWER_CROP(), Ids::TORCHFLOWER_CROP)->properties([
616 //TODO: this property can have values 0-7, but only 0-1 are valid
617 new IntProperty(StateNames::GROWTH, 0, 7, fn(TorchflowerCrop $b) => $b->isReady() ? 1 : 0, fn(TorchflowerCrop $b, int $v) => $b->setReady($v !== 0))
618 ]));
619 }
620
621 private static function registerCoralMappings(BlockSerializerDeserializerRegistrar $reg, CommonProperties $commonProperties) : void{
622 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::CORAL())->idComponents([...$commonProperties->coralIdPrefixes, "_coral"]));
623 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::CORAL_BLOCK())->idComponents([...$commonProperties->coralIdPrefixes, "_coral_block"]));
624 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::CORAL_FAN())
625 ->idComponents([...$commonProperties->coralIdPrefixes, "_coral_fan"])
626 ->properties([
627 //TODO: hack for lack of horizontal axis enum :(
628 new ValueFromIntProperty(StateNames::CORAL_FAN_DIRECTION, ValueMappings::getInstance()->coralAxis, fn(FloorCoralFan $b) => $b->getAxis()->value, fn(FloorCoralFan $b, int $v) => $b->setAxis(Axis::from($v)))
629 ])
630 );
631 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::WALL_CORAL_FAN())
632 ->idComponents([...$commonProperties->coralIdPrefixes, "_coral_wall_fan"])
633 ->properties([
634 new ValueFromIntProperty(StateNames::CORAL_DIRECTION, ValueMappings::getInstance()->horizontalFacingCoral, fn(HorizontalFacing $b) => $b->getFacing(), fn(HorizontalFacing $b, HorizontalFacingOption $v) => $b->setFacing($v)),
635 ])
636 );
637 }
638
639 private static function registerCopperMappings(BlockSerializerDeserializerRegistrar $reg, CommonProperties $commonProperties) : void{
640 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::COPPER_BULB())
641 ->idComponents([...$commonProperties->copperIdPrefixes, "copper_bulb"])
642 ->properties([
643 $commonProperties->lit,
644 new BoolProperty(StateNames::POWERED_BIT, fn(PoweredByRedstone $b) => $b->isPowered(), fn(PoweredByRedstone $b, bool $v) => $b->setPowered($v)),
645 ])
646 );
647 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::COPPER())
648 ->idComponents([
649 ...$commonProperties->copperIdPrefixes,
650 "copper",
651 //HACK: the non-waxed, non-oxidised variant has a _block suffix, but none of the others do
652 new BoolFromStringProperty("bruhhhh", "", "_block", fn(Copper $b) => !$b->isWaxed() && $b->getOxidation() === CopperOxidation::NONE, fn() => null)
653 ])
654 );
655 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::CHISELED_COPPER())->idComponents([...$commonProperties->copperIdPrefixes, "chiseled_copper"]));
656 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::COPPER_GRATE())->idComponents([...$commonProperties->copperIdPrefixes, "copper_grate"]));
657 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::CUT_COPPER())->idComponents([...$commonProperties->copperIdPrefixes, "cut_copper"]));
658 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::CUT_COPPER_STAIRS())
659 ->idComponents([...$commonProperties->copperIdPrefixes, "cut_copper_stairs"])
660 ->properties($commonProperties->stairProperties)
661 );
662 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::COPPER_TRAPDOOR())
663 ->idComponents([...$commonProperties->copperIdPrefixes, "copper_trapdoor"])
664 ->properties($commonProperties->trapdoorProperties)
665 );
666 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::COPPER_DOOR())
667 ->idComponents([...$commonProperties->copperIdPrefixes, "copper_door"])
668 ->properties($commonProperties->doorProperties)
669 );
670
671 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::CUT_COPPER_SLAB())
672 ->idComponents([
673 ...$commonProperties->copperIdPrefixes,
674 $commonProperties->slabIdInfix,
675 "cut_copper_slab"
676 ])
677 ->properties([$commonProperties->slabPositionProperty])
678 );
679
680 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::COPPER_BARS())->idComponents([...$commonProperties->copperIdPrefixes, "copper_bars"]));
681 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::COPPER_CHAIN())
682 ->idComponents([...$commonProperties->copperIdPrefixes, "copper_chain"])
683 ->properties([$commonProperties->pillarAxis])
684 );
685 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::COPPER_LANTERN())
686 ->idComponents([...$commonProperties->copperIdPrefixes, "copper_lantern"])
687 ->properties([
688 new BoolProperty(StateNames::HANGING, fn(CopperLantern $b) => $b->isHanging(), fn(CopperLantern $b, bool $v) => $b->setHanging($v))
689 ])
690 );
691 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::LIGHTNING_ROD())
692 ->idComponents([...$commonProperties->copperIdPrefixes, "lightning_rod"])
693 ->properties([
694 $commonProperties->anyFacingClassic,
695 new DummyProperty(StateNames::POWERED_BIT, false) //TODO
696 ])
697 );
698 }
699
700 private static function registerFlattenedEnumMappings(BlockSerializerDeserializerRegistrar $reg, CommonProperties $commonProperties) : void{
701 //A
702 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::ANVIL())
703 ->idComponents([
705 0 => Ids::ANVIL,
706 1 => Ids::CHIPPED_ANVIL,
707 2 => Ids::DAMAGED_ANVIL,
708 ]), fn(Anvil $b) => $b->getDamage(), fn(Anvil $b, int $v) => $b->setDamage($v))
709 ])
710 ->properties([$commonProperties->horizontalFacingCardinal])
711 );
712 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::AMETHYST_CLUSTER())
713 ->idComponents([
715 AmethystCluster::STAGE_SMALL_BUD => Ids::SMALL_AMETHYST_BUD,
716 AmethystCluster::STAGE_MEDIUM_BUD => Ids::MEDIUM_AMETHYST_BUD,
717 AmethystCluster::STAGE_LARGE_BUD => Ids::LARGE_AMETHYST_BUD,
718 AmethystCluster::STAGE_CLUSTER => Ids::AMETHYST_CLUSTER
719 ]), fn(AmethystCluster $b) => $b->getStage(), fn(AmethystCluster $b, int $v) => $b->setStage($v))
720 ])
721 ->properties([$commonProperties->blockFace])
722 );
723
724 //C
725 //This one is a special offender :<
726 //I have no idea why this only has 3 IDs - there are 4 in Java and 4 visually distinct states in Bedrock
727 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::CAVE_VINES())
728 ->idComponents([
729 "minecraft:cave_vines",
731 "variant",
732 EnumFromRawStateMap::string(FlattenedCaveVinesVariant::class, fn(FlattenedCaveVinesVariant $case) => $case->value),
733 fn(CaveVines $b) => $b->hasBerries() ?
734 ($b->isHead() ?
735 FlattenedCaveVinesVariant::HEAD_WITH_BERRIES :
736 FlattenedCaveVinesVariant::BODY_WITH_BERRIES) :
737 FlattenedCaveVinesVariant::NO_BERRIES,
738 fn(CaveVines $b, FlattenedCaveVinesVariant $v) => match($v){
739 FlattenedCaveVinesVariant::HEAD_WITH_BERRIES => $b->setBerries(true)->setHead(true),
740 FlattenedCaveVinesVariant::BODY_WITH_BERRIES => $b->setBerries(true)->setHead(false),
741 FlattenedCaveVinesVariant::NO_BERRIES => $b->setBerries(false)->setHead(false), //assume this isn't a head, since we don't have enough information
742 }
743 )
744 ])
745 ->properties([
746 new IntProperty(StateNames::GROWING_PLANT_AGE, 0, 25, fn(CaveVines $b) => $b->getAge(), fn(CaveVines $b, int $v) => $b->setAge($v)),
747 ])
748 );
749
750 //D
751 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::DIRT())
752 ->idComponents([
753 new ValueFromStringProperty("id", EnumFromRawStateMap::string(DirtType::class, fn(DirtType $case) => match ($case) {
754 DirtType::NORMAL => Ids::DIRT,
755 DirtType::COARSE => Ids::COARSE_DIRT,
756 DirtType::ROOTED => Ids::DIRT_WITH_ROOTS,
757 }), fn(Dirt $b) => $b->getDirtType(), fn(Dirt $b, DirtType $v) => $b->setDirtType($v))
758 ])
759 );
760
761 //F
762 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::FROGLIGHT())
763 ->idComponents([
764 new ValueFromStringProperty("id", ValueMappings::getInstance()->froglightType, fn(Froglight $b) => $b->getFroglightType(), fn(Froglight $b, FroglightType $v) => $b->setFroglightType($v)),
765 ])
766 ->properties([$commonProperties->pillarAxis])
767 );
768
769 //L
770 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::LIGHT())
771 ->idComponents([
772 "minecraft:light_block_",
773 //this is a bit shit but it's easier than adapting IntProperty to support flattening :D
775 "light_level",
776 IntFromRawStateMap::string(array_map(strval(...), range(0, 15))),
777 fn(Light $b) => $b->getLightLevel(),
778 fn(Light $b, int $v) => $b->setLightLevel($v)
779 )
780 ])
781 );
782
783 //M
784 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::MOB_HEAD())
785 ->idComponents([
786 new ValueFromStringProperty("id", ValueMappings::getInstance()->mobHeadType, fn(MobHead $b) => $b->getMobHeadType(), fn(MobHead $b, MobHeadType $v) => $b->setMobHeadType($v)),
787 ])
788 ->properties([
789 new ValueFromIntProperty(StateNames::FACING_DIRECTION, ValueMappings::getInstance()->facingExceptDown, fn(MobHead $b) => $b->getFacing()->value, fn(MobHead $b, int $v) => $b->setFacing(Facing::from($v)))
790 ])
791 );
792
793 foreach([
794 [Blocks::LAVA(), "lava"],
795 [Blocks::WATER(), "water"]
796 ] as [$block, $idSuffix]){
798 ->idComponents([...$commonProperties->liquidIdPrefixes, $idSuffix])
799 ->properties([$commonProperties->liquidData])
800 );
801 }
802 }
803
804 private static function registerFlattenedBoolMappings(BlockSerializerDeserializerRegistrar $reg, CommonProperties $commonProperties) : void{
805 foreach([
806 [Blocks::BLAST_FURNACE(), "blast_furnace"],
807 [Blocks::FURNACE(), "furnace"],
808 [Blocks::SMOKER(), "smoker"]
809 ] as [$block, $idSuffix]){
811 ->idComponents([...$commonProperties->furnaceIdPrefixes, $idSuffix])
812 ->properties([$commonProperties->horizontalFacingCardinal])
813 );
814 }
815
816 foreach([
817 [Blocks::REDSTONE_LAMP(), "redstone_lamp"],
818 [Blocks::REDSTONE_ORE(), "redstone_ore"],
819 [Blocks::DEEPSLATE_REDSTONE_ORE(), "deepslate_redstone_ore"]
820 ] as [$block, $idSuffix]){
821 $reg->mapFlattenedId(FlattenedIdModel::create($block)->idComponents(["minecraft:", $commonProperties->litIdInfix, $idSuffix]));
822 }
823
824 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::DAYLIGHT_SENSOR())
825 ->idComponents([
826 "minecraft:daylight_detector",
827 new BoolFromStringProperty("inverted", "", "_inverted", fn(DaylightSensor $b) => $b->isInverted(), fn(DaylightSensor $b, bool $v) => $b->setInverted($v))
828 ])
829 ->properties([$commonProperties->analogRedstoneSignal])
830 );
831 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::REDSTONE_REPEATER())
832 ->idComponents([
833 "minecraft:",
834 new BoolFromStringProperty("powered", "un", "", fn(RedstoneRepeater $b) => $b->isPowered(), fn(RedstoneRepeater $b, bool $v) => $b->setPowered($v)),
835 "powered_repeater"
836 ])
837 ->properties([
838 $commonProperties->horizontalFacingCardinal,
839 new IntProperty(StateNames::REPEATER_DELAY, 0, 3, fn(RedstoneRepeater $b) => $b->getDelay(), fn(RedstoneRepeater $b, int $v) => $b->setDelay($v), offset: 1),
840 ])
841 );
842 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::REDSTONE_COMPARATOR())
843 ->idComponents([
844 "minecraft:",
845 //this property also appears in the state, so we ignore it in the ID
846 //this is baked here purely to keep minecraft happy
847 new BoolFromStringProperty("dummy_powered", "un", "", fn(RedstoneComparator $b) => $b->isPowered(), fn() => null),
848 "powered_comparator"
849 ])
850 ->properties([
851 $commonProperties->horizontalFacingCardinal,
852 new BoolProperty(StateNames::OUTPUT_LIT_BIT, fn(RedstoneComparator $b) => $b->isPowered(), fn(RedstoneComparator $b, bool $v) => $b->setPowered($v)),
853 new BoolProperty(StateNames::OUTPUT_SUBTRACT_BIT, fn(RedstoneComparator $b) => $b->isSubtractMode(), fn(RedstoneComparator $b, bool $v) => $b->setSubtractMode($v)),
854 ])
855 );
856 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::REDSTONE_TORCH())
857 ->idComponents([
858 "minecraft:",
859 new BoolFromStringProperty("lit", "unlit_", "", fn(RedstoneTorch $b) => $b->isLit(), fn(RedstoneTorch $b, bool $v) => $b->setLit($v)),
860 "redstone_torch"
861 ])
862 ->properties([$commonProperties->torchFacing])
863 );
864 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::SPONGE())->idComponents([
865 "minecraft:",
866 new BoolFromStringProperty("wet", "", "wet_", fn(Sponge $b) => $b->isWet(), fn(Sponge $b, bool $v) => $b->setWet($v)),
867 "sponge"
868 ]));
869 $reg->mapFlattenedId(FlattenedIdModel::create(Blocks::TNT())
870 ->idComponents([
871 "minecraft:",
872 new BoolFromStringProperty("underwater", "", "underwater_", fn(TNT $b) => $b->worksUnderwater(), fn(TNT $b, bool $v) => $b->setWorksUnderwater($v)),
873 "tnt"
874 ])
875 ->properties([
876 new BoolProperty(StateNames::EXPLODE_BIT, fn(TNT $b) => $b->isUnstable(), fn(TNT $b, bool $v) => $b->setUnstable($v)),
877 ])
878 );
879 }
880
881 private static function registerStoneLikeSlabMappings(BlockSerializerDeserializerRegistrar $reg) : void{
882 $reg->mapSlab(Blocks::ANDESITE_SLAB(), "andesite");
883 $reg->mapSlab(Blocks::BLACKSTONE_SLAB(), "blackstone");
884 $reg->mapSlab(Blocks::BRICK_SLAB(), "brick");
885 $reg->mapSlab(Blocks::COBBLED_DEEPSLATE_SLAB(), "cobbled_deepslate");
886 $reg->mapSlab(Blocks::COBBLESTONE_SLAB(), "cobblestone");
887 $reg->mapSlab(Blocks::CUT_RED_SANDSTONE_SLAB(), "cut_red_sandstone");
888 $reg->mapSlab(Blocks::CUT_SANDSTONE_SLAB(), "cut_sandstone");
889 $reg->mapSlab(Blocks::DARK_PRISMARINE_SLAB(), "dark_prismarine");
890 $reg->mapSlab(Blocks::DEEPSLATE_BRICK_SLAB(), "deepslate_brick");
891 $reg->mapSlab(Blocks::DEEPSLATE_TILE_SLAB(), "deepslate_tile");
892 $reg->mapSlab(Blocks::DIORITE_SLAB(), "diorite");
893 $reg->mapSlab(Blocks::END_STONE_BRICK_SLAB(), "end_stone_brick");
894 $reg->mapSlab(Blocks::FAKE_WOODEN_SLAB(), "petrified_oak");
895 $reg->mapSlab(Blocks::GRANITE_SLAB(), "granite");
896 $reg->mapSlab(Blocks::MOSSY_COBBLESTONE_SLAB(), "mossy_cobblestone");
897 $reg->mapSlab(Blocks::MOSSY_STONE_BRICK_SLAB(), "mossy_stone_brick");
898 $reg->mapSlab(Blocks::MUD_BRICK_SLAB(), "mud_brick");
899 $reg->mapSlab(Blocks::NETHER_BRICK_SLAB(), "nether_brick");
900 $reg->mapSlab(Blocks::POLISHED_ANDESITE_SLAB(), "polished_andesite");
901 $reg->mapSlab(Blocks::POLISHED_BLACKSTONE_BRICK_SLAB(), "polished_blackstone_brick");
902 $reg->mapSlab(Blocks::POLISHED_BLACKSTONE_SLAB(), "polished_blackstone");
903 $reg->mapSlab(Blocks::POLISHED_DEEPSLATE_SLAB(), "polished_deepslate");
904 $reg->mapSlab(Blocks::POLISHED_DIORITE_SLAB(), "polished_diorite");
905 $reg->mapSlab(Blocks::POLISHED_GRANITE_SLAB(), "polished_granite");
906 $reg->mapSlab(Blocks::POLISHED_TUFF_SLAB(), "polished_tuff");
907 $reg->mapSlab(Blocks::PRISMARINE_BRICKS_SLAB(), "prismarine_brick");
908 $reg->mapSlab(Blocks::PRISMARINE_SLAB(), "prismarine");
909 $reg->mapSlab(Blocks::PURPUR_SLAB(), "purpur");
910 $reg->mapSlab(Blocks::QUARTZ_SLAB(), "quartz");
911 $reg->mapSlab(Blocks::RED_NETHER_BRICK_SLAB(), "red_nether_brick");
912 $reg->mapSlab(Blocks::RED_SANDSTONE_SLAB(), "red_sandstone");
913 $reg->mapSlab(Blocks::RESIN_BRICK_SLAB(), "resin_brick");
914 $reg->mapSlab(Blocks::SANDSTONE_SLAB(), "sandstone");
915 $reg->mapSlab(Blocks::SMOOTH_QUARTZ_SLAB(), "smooth_quartz");
916 $reg->mapSlab(Blocks::SMOOTH_RED_SANDSTONE_SLAB(), "smooth_red_sandstone");
917 $reg->mapSlab(Blocks::SMOOTH_SANDSTONE_SLAB(), "smooth_sandstone");
918 $reg->mapSlab(Blocks::SMOOTH_STONE_SLAB(), "smooth_stone");
919 $reg->mapSlab(Blocks::STONE_BRICK_SLAB(), "stone_brick");
920 $reg->mapSlab(Blocks::STONE_SLAB(), "normal_stone");
921 $reg->mapSlab(Blocks::TUFF_BRICK_SLAB(), "tuff_brick");
922 $reg->mapSlab(Blocks::TUFF_SLAB(), "tuff");
923 }
924
925 private static function registerStoneLikeStairMappings(BlockSerializerDeserializerRegistrar $reg) : void{
926 $reg->mapStairs(Blocks::ANDESITE_STAIRS(), Ids::ANDESITE_STAIRS);
927 $reg->mapStairs(Blocks::BLACKSTONE_STAIRS(), Ids::BLACKSTONE_STAIRS);
928 $reg->mapStairs(Blocks::BRICK_STAIRS(), Ids::BRICK_STAIRS);
929 $reg->mapStairs(Blocks::COBBLED_DEEPSLATE_STAIRS(), Ids::COBBLED_DEEPSLATE_STAIRS);
930 $reg->mapStairs(Blocks::COBBLESTONE_STAIRS(), Ids::STONE_STAIRS);
931 $reg->mapStairs(Blocks::DARK_PRISMARINE_STAIRS(), Ids::DARK_PRISMARINE_STAIRS);
932 $reg->mapStairs(Blocks::DEEPSLATE_BRICK_STAIRS(), Ids::DEEPSLATE_BRICK_STAIRS);
933 $reg->mapStairs(Blocks::DEEPSLATE_TILE_STAIRS(), Ids::DEEPSLATE_TILE_STAIRS);
934 $reg->mapStairs(Blocks::DIORITE_STAIRS(), Ids::DIORITE_STAIRS);
935 $reg->mapStairs(Blocks::END_STONE_BRICK_STAIRS(), Ids::END_BRICK_STAIRS);
936 $reg->mapStairs(Blocks::GRANITE_STAIRS(), Ids::GRANITE_STAIRS);
937 $reg->mapStairs(Blocks::MOSSY_COBBLESTONE_STAIRS(), Ids::MOSSY_COBBLESTONE_STAIRS);
938 $reg->mapStairs(Blocks::MOSSY_STONE_BRICK_STAIRS(), Ids::MOSSY_STONE_BRICK_STAIRS);
939 $reg->mapStairs(Blocks::MUD_BRICK_STAIRS(), Ids::MUD_BRICK_STAIRS);
940 $reg->mapStairs(Blocks::NETHER_BRICK_STAIRS(), Ids::NETHER_BRICK_STAIRS);
941 $reg->mapStairs(Blocks::POLISHED_ANDESITE_STAIRS(), Ids::POLISHED_ANDESITE_STAIRS);
942 $reg->mapStairs(Blocks::POLISHED_BLACKSTONE_BRICK_STAIRS(), Ids::POLISHED_BLACKSTONE_BRICK_STAIRS);
943 $reg->mapStairs(Blocks::POLISHED_BLACKSTONE_STAIRS(), Ids::POLISHED_BLACKSTONE_STAIRS);
944 $reg->mapStairs(Blocks::POLISHED_DEEPSLATE_STAIRS(), Ids::POLISHED_DEEPSLATE_STAIRS);
945 $reg->mapStairs(Blocks::POLISHED_DIORITE_STAIRS(), Ids::POLISHED_DIORITE_STAIRS);
946 $reg->mapStairs(Blocks::POLISHED_GRANITE_STAIRS(), Ids::POLISHED_GRANITE_STAIRS);
947 $reg->mapStairs(Blocks::POLISHED_TUFF_STAIRS(), Ids::POLISHED_TUFF_STAIRS);
948 $reg->mapStairs(Blocks::PRISMARINE_BRICKS_STAIRS(), Ids::PRISMARINE_BRICKS_STAIRS);
949 $reg->mapStairs(Blocks::PRISMARINE_STAIRS(), Ids::PRISMARINE_STAIRS);
950 $reg->mapStairs(Blocks::PURPUR_STAIRS(), Ids::PURPUR_STAIRS);
951 $reg->mapStairs(Blocks::QUARTZ_STAIRS(), Ids::QUARTZ_STAIRS);
952 $reg->mapStairs(Blocks::RED_NETHER_BRICK_STAIRS(), Ids::RED_NETHER_BRICK_STAIRS);
953 $reg->mapStairs(Blocks::RED_SANDSTONE_STAIRS(), Ids::RED_SANDSTONE_STAIRS);
954 $reg->mapStairs(Blocks::RESIN_BRICK_STAIRS(), Ids::RESIN_BRICK_STAIRS);
955 $reg->mapStairs(Blocks::SANDSTONE_STAIRS(), Ids::SANDSTONE_STAIRS);
956 $reg->mapStairs(Blocks::SMOOTH_QUARTZ_STAIRS(), Ids::SMOOTH_QUARTZ_STAIRS);
957 $reg->mapStairs(Blocks::SMOOTH_RED_SANDSTONE_STAIRS(), Ids::SMOOTH_RED_SANDSTONE_STAIRS);
958 $reg->mapStairs(Blocks::SMOOTH_SANDSTONE_STAIRS(), Ids::SMOOTH_SANDSTONE_STAIRS);
959 $reg->mapStairs(Blocks::STONE_BRICK_STAIRS(), Ids::STONE_BRICK_STAIRS);
960 $reg->mapStairs(Blocks::STONE_STAIRS(), Ids::NORMAL_STONE_STAIRS);
961 $reg->mapStairs(Blocks::TUFF_BRICK_STAIRS(), Ids::TUFF_BRICK_STAIRS);
962 $reg->mapStairs(Blocks::TUFF_STAIRS(), Ids::TUFF_STAIRS);
963 }
964
965 private static function registerStoneLikeWallMappings(BlockSerializerDeserializerRegistrar $reg, CommonProperties $commonProperties) : void{
966 foreach([
967 Ids::ANDESITE_WALL => Blocks::ANDESITE_WALL(),
968 Ids::BLACKSTONE_WALL => Blocks::BLACKSTONE_WALL(),
969 Ids::BRICK_WALL => Blocks::BRICK_WALL(),
970 Ids::COBBLED_DEEPSLATE_WALL => Blocks::COBBLED_DEEPSLATE_WALL(),
971 Ids::COBBLESTONE_WALL => Blocks::COBBLESTONE_WALL(),
972 Ids::DEEPSLATE_BRICK_WALL => Blocks::DEEPSLATE_BRICK_WALL(),
973 Ids::DEEPSLATE_TILE_WALL => Blocks::DEEPSLATE_TILE_WALL(),
974 Ids::DIORITE_WALL => Blocks::DIORITE_WALL(),
975 Ids::END_STONE_BRICK_WALL => Blocks::END_STONE_BRICK_WALL(),
976 Ids::GRANITE_WALL => Blocks::GRANITE_WALL(),
977 Ids::MOSSY_COBBLESTONE_WALL => Blocks::MOSSY_COBBLESTONE_WALL(),
978 Ids::MOSSY_STONE_BRICK_WALL => Blocks::MOSSY_STONE_BRICK_WALL(),
979 Ids::MUD_BRICK_WALL => Blocks::MUD_BRICK_WALL(),
980 Ids::NETHER_BRICK_WALL => Blocks::NETHER_BRICK_WALL(),
981 Ids::POLISHED_BLACKSTONE_BRICK_WALL => Blocks::POLISHED_BLACKSTONE_BRICK_WALL(),
982 Ids::POLISHED_BLACKSTONE_WALL => Blocks::POLISHED_BLACKSTONE_WALL(),
983 Ids::POLISHED_DEEPSLATE_WALL => Blocks::POLISHED_DEEPSLATE_WALL(),
984 Ids::POLISHED_TUFF_WALL => Blocks::POLISHED_TUFF_WALL(),
985 Ids::PRISMARINE_WALL => Blocks::PRISMARINE_WALL(),
986 Ids::RED_NETHER_BRICK_WALL => Blocks::RED_NETHER_BRICK_WALL(),
987 Ids::RED_SANDSTONE_WALL => Blocks::RED_SANDSTONE_WALL(),
988 Ids::RESIN_BRICK_WALL => Blocks::RESIN_BRICK_WALL(),
989 Ids::SANDSTONE_WALL => Blocks::SANDSTONE_WALL(),
990 Ids::STONE_BRICK_WALL => Blocks::STONE_BRICK_WALL(),
991 Ids::TUFF_BRICK_WALL => Blocks::TUFF_BRICK_WALL(),
992 Ids::TUFF_WALL => Blocks::TUFF_WALL()
993 ] as $id => $block){
994 $reg->mapModel(Model::create($block, $id)->properties($commonProperties->wallProperties));
995 }
996 }
997
998 private static function registerWoodMappings(BlockSerializerDeserializerRegistrar $reg, CommonProperties $commonProperties) : void{
999 //buttons
1000 foreach([
1001 [Blocks::ACACIA_BUTTON(), Ids::ACACIA_BUTTON],
1002 [Blocks::BAMBOO_BUTTON(), Ids::BAMBOO_BUTTON],
1003 [Blocks::BIRCH_BUTTON(), Ids::BIRCH_BUTTON],
1004 [Blocks::CHERRY_BUTTON(), Ids::CHERRY_BUTTON],
1005 [Blocks::CRIMSON_BUTTON(), Ids::CRIMSON_BUTTON],
1006 [Blocks::DARK_OAK_BUTTON(), Ids::DARK_OAK_BUTTON],
1007 [Blocks::JUNGLE_BUTTON(), Ids::JUNGLE_BUTTON],
1008 [Blocks::MANGROVE_BUTTON(), Ids::MANGROVE_BUTTON],
1009 [Blocks::OAK_BUTTON(), Ids::WOODEN_BUTTON],
1010 [Blocks::PALE_OAK_BUTTON(), Ids::PALE_OAK_BUTTON],
1011 [Blocks::SPRUCE_BUTTON(), Ids::SPRUCE_BUTTON],
1012 [Blocks::WARPED_BUTTON(), Ids::WARPED_BUTTON]
1013 ] as [$block, $id]){
1014 $reg->mapModel(Model::create($block, $id)->properties($commonProperties->buttonProperties));
1015 }
1016
1017 //doors
1018 foreach([
1019 [Blocks::ACACIA_DOOR(), Ids::ACACIA_DOOR],
1020 [Blocks::BAMBOO_DOOR(), Ids::BAMBOO_DOOR],
1021 [Blocks::BIRCH_DOOR(), Ids::BIRCH_DOOR],
1022 [Blocks::CHERRY_DOOR(), Ids::CHERRY_DOOR],
1023 [Blocks::CRIMSON_DOOR(), Ids::CRIMSON_DOOR],
1024 [Blocks::DARK_OAK_DOOR(), Ids::DARK_OAK_DOOR],
1025 [Blocks::JUNGLE_DOOR(), Ids::JUNGLE_DOOR],
1026 [Blocks::MANGROVE_DOOR(), Ids::MANGROVE_DOOR],
1027 [Blocks::OAK_DOOR(), Ids::WOODEN_DOOR],
1028 [Blocks::PALE_OAK_DOOR(), Ids::PALE_OAK_DOOR],
1029 [Blocks::SPRUCE_DOOR(), Ids::SPRUCE_DOOR],
1030 [Blocks::WARPED_DOOR(), Ids::WARPED_DOOR]
1031 ] as [$block, $id]){
1032 $reg->mapModel(Model::create($block, $id)->properties($commonProperties->doorProperties));
1033 }
1034
1035 //fences
1036 foreach([
1037 [Blocks::ACACIA_FENCE(), Ids::ACACIA_FENCE],
1038 [Blocks::BAMBOO_FENCE(), Ids::BAMBOO_FENCE],
1039 [Blocks::BIRCH_FENCE(), Ids::BIRCH_FENCE],
1040 [Blocks::CHERRY_FENCE(), Ids::CHERRY_FENCE],
1041 [Blocks::DARK_OAK_FENCE(), Ids::DARK_OAK_FENCE],
1042 [Blocks::JUNGLE_FENCE(), Ids::JUNGLE_FENCE],
1043 [Blocks::MANGROVE_FENCE(), Ids::MANGROVE_FENCE],
1044 [Blocks::OAK_FENCE(), Ids::OAK_FENCE],
1045 [Blocks::PALE_OAK_FENCE(), Ids::PALE_OAK_FENCE],
1046 [Blocks::SPRUCE_FENCE(), Ids::SPRUCE_FENCE],
1047 [Blocks::CRIMSON_FENCE(), Ids::CRIMSON_FENCE],
1048 [Blocks::WARPED_FENCE(), Ids::WARPED_FENCE]
1049 ] as [$block, $id]){
1050 $reg->mapSimple($block, $id);
1051 }
1052
1053 foreach([
1054 [Blocks::ACACIA_FENCE_GATE(), Ids::ACACIA_FENCE_GATE],
1055 [Blocks::BAMBOO_FENCE_GATE(), Ids::BAMBOO_FENCE_GATE],
1056 [Blocks::BIRCH_FENCE_GATE(), Ids::BIRCH_FENCE_GATE],
1057 [Blocks::CHERRY_FENCE_GATE(), Ids::CHERRY_FENCE_GATE],
1058 [Blocks::DARK_OAK_FENCE_GATE(), Ids::DARK_OAK_FENCE_GATE],
1059 [Blocks::JUNGLE_FENCE_GATE(), Ids::JUNGLE_FENCE_GATE],
1060 [Blocks::MANGROVE_FENCE_GATE(), Ids::MANGROVE_FENCE_GATE],
1061 [Blocks::OAK_FENCE_GATE(), Ids::FENCE_GATE],
1062 [Blocks::PALE_OAK_FENCE_GATE(), Ids::PALE_OAK_FENCE_GATE],
1063 [Blocks::SPRUCE_FENCE_GATE(), Ids::SPRUCE_FENCE_GATE],
1064 [Blocks::CRIMSON_FENCE_GATE(), Ids::CRIMSON_FENCE_GATE],
1065 [Blocks::WARPED_FENCE_GATE(), Ids::WARPED_FENCE_GATE]
1066 ] as [$block, $id]){
1067 $reg->mapModel(Model::create($block, $id)->properties($commonProperties->fenceGateProperties));
1068 }
1069
1070 foreach([
1071 [Blocks::ACACIA_SIGN(), Ids::ACACIA_STANDING_SIGN],
1072 [Blocks::BAMBOO_SIGN(), Ids::BAMBOO_STANDING_SIGN],
1073 [Blocks::BIRCH_SIGN(), Ids::BIRCH_STANDING_SIGN],
1074 [Blocks::CHERRY_SIGN(), Ids::CHERRY_STANDING_SIGN],
1075 [Blocks::DARK_OAK_SIGN(), Ids::DARKOAK_STANDING_SIGN],
1076 [Blocks::JUNGLE_SIGN(), Ids::JUNGLE_STANDING_SIGN],
1077 [Blocks::MANGROVE_SIGN(), Ids::MANGROVE_STANDING_SIGN],
1078 [Blocks::OAK_SIGN(), Ids::STANDING_SIGN],
1079 [Blocks::PALE_OAK_SIGN(), Ids::PALE_OAK_STANDING_SIGN],
1080 [Blocks::SPRUCE_SIGN(), Ids::SPRUCE_STANDING_SIGN],
1081 [Blocks::CRIMSON_SIGN(), Ids::CRIMSON_STANDING_SIGN],
1082 [Blocks::WARPED_SIGN(), Ids::WARPED_STANDING_SIGN]
1083 ] as [$block, $id]){
1084 $reg->mapModel(Model::create($block, $id)->properties([$commonProperties->floorSignLikeRotation]));
1085 }
1086
1087 //logs
1088 foreach([
1089 [Blocks::ACACIA_LOG(), "acacia_log"],
1090 [Blocks::BIRCH_LOG(), "birch_log"],
1091 [Blocks::CHERRY_LOG(), "cherry_log"],
1092 [Blocks::DARK_OAK_LOG(), "dark_oak_log"],
1093 [Blocks::JUNGLE_LOG(), "jungle_log"],
1094 [Blocks::MANGROVE_LOG(), "mangrove_log"],
1095 [Blocks::OAK_LOG(), "oak_log"],
1096 [Blocks::PALE_OAK_LOG(), "pale_oak_log"],
1097 [Blocks::SPRUCE_LOG(), "spruce_log"],
1098 [Blocks::CRIMSON_STEM(), "crimson_stem"],
1099 [Blocks::WARPED_STEM(), "warped_stem"],
1100
1101 //all-sided logs
1102 [Blocks::ACACIA_WOOD(), "acacia_wood"],
1103 [Blocks::BIRCH_WOOD(), "birch_wood"],
1104 [Blocks::CHERRY_WOOD(), "cherry_wood"],
1105 [Blocks::DARK_OAK_WOOD(), "dark_oak_wood"],
1106 [Blocks::JUNGLE_WOOD(), "jungle_wood"],
1107 [Blocks::MANGROVE_WOOD(), "mangrove_wood"],
1108 [Blocks::OAK_WOOD(), "oak_wood"],
1109 [Blocks::PALE_OAK_WOOD(), "pale_oak_wood"],
1110 [Blocks::SPRUCE_WOOD(), "spruce_wood"],
1111 [Blocks::CRIMSON_HYPHAE(), "crimson_hyphae"],
1112 [Blocks::WARPED_HYPHAE(), "warped_hyphae"],
1113
1114 //bamboo is a special cookie - its name differs and there's no all-sided variant
1115 [Blocks::BAMBOO_BLOCK(), "bamboo_block"],
1116 ] as [$block, $idSuffix]){
1118 ->idComponents([...$commonProperties->woodIdPrefixes, $idSuffix])
1119 ->properties([$commonProperties->pillarAxis])
1120 );
1121 }
1122
1123 //planks
1124 foreach([
1125 [Blocks::ACACIA_PLANKS(), Ids::ACACIA_PLANKS],
1126 [Blocks::BAMBOO_PLANKS(), Ids::BAMBOO_PLANKS],
1127 [Blocks::BAMBOO_MOSAIC(), Ids::BAMBOO_MOSAIC], //special bamboo variant block
1128 [Blocks::BIRCH_PLANKS(), Ids::BIRCH_PLANKS],
1129 [Blocks::CHERRY_PLANKS(), Ids::CHERRY_PLANKS],
1130 [Blocks::DARK_OAK_PLANKS(), Ids::DARK_OAK_PLANKS],
1131 [Blocks::JUNGLE_PLANKS(), Ids::JUNGLE_PLANKS],
1132 [Blocks::MANGROVE_PLANKS(), Ids::MANGROVE_PLANKS],
1133 [Blocks::OAK_PLANKS(), Ids::OAK_PLANKS],
1134 [Blocks::PALE_OAK_PLANKS(), Ids::PALE_OAK_PLANKS],
1135 [Blocks::SPRUCE_PLANKS(), Ids::SPRUCE_PLANKS],
1136 [Blocks::CRIMSON_PLANKS(), Ids::CRIMSON_PLANKS],
1137 [Blocks::WARPED_PLANKS(), Ids::WARPED_PLANKS]
1138 ] as [$block, $id]){
1139 $reg->mapSimple($block, $id);
1140 }
1141
1142 //pressure plates
1143 foreach([
1144 [Blocks::ACACIA_PRESSURE_PLATE(), Ids::ACACIA_PRESSURE_PLATE],
1145 [Blocks::BAMBOO_PRESSURE_PLATE(), Ids::BAMBOO_PRESSURE_PLATE],
1146 [Blocks::BIRCH_PRESSURE_PLATE(), Ids::BIRCH_PRESSURE_PLATE],
1147 [Blocks::CHERRY_PRESSURE_PLATE(), Ids::CHERRY_PRESSURE_PLATE],
1148 [Blocks::DARK_OAK_PRESSURE_PLATE(), Ids::DARK_OAK_PRESSURE_PLATE],
1149 [Blocks::JUNGLE_PRESSURE_PLATE(), Ids::JUNGLE_PRESSURE_PLATE],
1150 [Blocks::MANGROVE_PRESSURE_PLATE(), Ids::MANGROVE_PRESSURE_PLATE],
1151 [Blocks::OAK_PRESSURE_PLATE(), Ids::WOODEN_PRESSURE_PLATE],
1152 [Blocks::PALE_OAK_PRESSURE_PLATE(), Ids::PALE_OAK_PRESSURE_PLATE],
1153 [Blocks::SPRUCE_PRESSURE_PLATE(), Ids::SPRUCE_PRESSURE_PLATE],
1154 [Blocks::CRIMSON_PRESSURE_PLATE(), Ids::CRIMSON_PRESSURE_PLATE],
1155 [Blocks::WARPED_PRESSURE_PLATE(), Ids::WARPED_PRESSURE_PLATE]
1156 ] as [$block, $id]){
1157 $reg->mapModel(Model::create($block, $id)->properties($commonProperties->simplePressurePlateProperties));
1158 }
1159
1160 //slabs
1161 foreach([
1162 [Blocks::ACACIA_SLAB(), "acacia"],
1163 [Blocks::BAMBOO_SLAB(), "bamboo"],
1164 [Blocks::BAMBOO_MOSAIC_SLAB(), "bamboo_mosaic"], //special bamboo variant block
1165 [Blocks::BIRCH_SLAB(), "birch"],
1166 [Blocks::CHERRY_SLAB(), "cherry"],
1167 [Blocks::DARK_OAK_SLAB(), "dark_oak"],
1168 [Blocks::JUNGLE_SLAB(), "jungle"],
1169 [Blocks::MANGROVE_SLAB(), "mangrove"],
1170 [Blocks::OAK_SLAB(), "oak"],
1171 [Blocks::PALE_OAK_SLAB(), "pale_oak"],
1172 [Blocks::SPRUCE_SLAB(), "spruce"],
1173 [Blocks::CRIMSON_SLAB(), "crimson"],
1174 [Blocks::WARPED_SLAB(), "warped"]
1175 ] as [$block, $type]){
1176 $reg->mapSlab($block, $type);
1177 }
1178
1179 //stairs
1180 foreach([
1181 [Blocks::ACACIA_STAIRS(), Ids::ACACIA_STAIRS],
1182 [Blocks::BAMBOO_STAIRS(), Ids::BAMBOO_STAIRS],
1183 [Blocks::BAMBOO_MOSAIC_STAIRS(), Ids::BAMBOO_MOSAIC_STAIRS], //special bamboo variant block
1184 [Blocks::BIRCH_STAIRS(), Ids::BIRCH_STAIRS],
1185 [Blocks::CHERRY_STAIRS(), Ids::CHERRY_STAIRS],
1186 [Blocks::DARK_OAK_STAIRS(), Ids::DARK_OAK_STAIRS],
1187 [Blocks::JUNGLE_STAIRS(), Ids::JUNGLE_STAIRS],
1188 [Blocks::MANGROVE_STAIRS(), Ids::MANGROVE_STAIRS],
1189 [Blocks::OAK_STAIRS(), Ids::OAK_STAIRS],
1190 [Blocks::PALE_OAK_STAIRS(), Ids::PALE_OAK_STAIRS],
1191 [Blocks::SPRUCE_STAIRS(), Ids::SPRUCE_STAIRS],
1192 [Blocks::CRIMSON_STAIRS(), Ids::CRIMSON_STAIRS],
1193 [Blocks::WARPED_STAIRS(), Ids::WARPED_STAIRS]
1194 ] as [$block, $id]){
1195 $reg->mapStairs($block, $id);
1196 }
1197
1198 //trapdoors
1199 foreach([
1200 [Blocks::ACACIA_TRAPDOOR(), Ids::ACACIA_TRAPDOOR],
1201 [Blocks::BAMBOO_TRAPDOOR(), Ids::BAMBOO_TRAPDOOR],
1202 [Blocks::BIRCH_TRAPDOOR(), Ids::BIRCH_TRAPDOOR],
1203 [Blocks::CHERRY_TRAPDOOR(), Ids::CHERRY_TRAPDOOR],
1204 [Blocks::DARK_OAK_TRAPDOOR(), Ids::DARK_OAK_TRAPDOOR],
1205 [Blocks::JUNGLE_TRAPDOOR(), Ids::JUNGLE_TRAPDOOR],
1206 [Blocks::MANGROVE_TRAPDOOR(), Ids::MANGROVE_TRAPDOOR],
1207 [Blocks::OAK_TRAPDOOR(), Ids::TRAPDOOR],
1208 [Blocks::PALE_OAK_TRAPDOOR(), Ids::PALE_OAK_TRAPDOOR],
1209 [Blocks::SPRUCE_TRAPDOOR(), Ids::SPRUCE_TRAPDOOR],
1210 [Blocks::CRIMSON_TRAPDOOR(), Ids::CRIMSON_TRAPDOOR],
1211 [Blocks::WARPED_TRAPDOOR(), Ids::WARPED_TRAPDOOR]
1212 ] as [$block, $id]){
1213 $reg->mapModel(Model::create($block, $id)->properties($commonProperties->trapdoorProperties));
1214 }
1215
1216 //wall signs
1217 foreach([
1218 [Blocks::ACACIA_WALL_SIGN(), Ids::ACACIA_WALL_SIGN],
1219 [Blocks::BAMBOO_WALL_SIGN(), Ids::BAMBOO_WALL_SIGN],
1220 [Blocks::BIRCH_WALL_SIGN(), Ids::BIRCH_WALL_SIGN],
1221 [Blocks::CHERRY_WALL_SIGN(), Ids::CHERRY_WALL_SIGN],
1222 [Blocks::DARK_OAK_WALL_SIGN(), Ids::DARKOAK_WALL_SIGN],
1223 [Blocks::JUNGLE_WALL_SIGN(), Ids::JUNGLE_WALL_SIGN],
1224 [Blocks::MANGROVE_WALL_SIGN(), Ids::MANGROVE_WALL_SIGN],
1225 [Blocks::OAK_WALL_SIGN(), Ids::WALL_SIGN],
1226 [Blocks::PALE_OAK_WALL_SIGN(), Ids::PALE_OAK_WALL_SIGN],
1227 [Blocks::SPRUCE_WALL_SIGN(), Ids::SPRUCE_WALL_SIGN],
1228 [Blocks::CRIMSON_WALL_SIGN(), Ids::CRIMSON_WALL_SIGN],
1229 [Blocks::WARPED_WALL_SIGN(), Ids::WARPED_WALL_SIGN]
1230 ] as [$block, $id]){
1231 $reg->mapModel(Model::create($block, $id)->properties([$commonProperties->horizontalFacingClassic]));
1232 }
1233 }
1234
1235 private static function registerTorchMappings(BlockSerializerDeserializerRegistrar $reg, CommonProperties $commonProperties) : void{
1236 foreach([
1237 [Blocks::BLUE_TORCH(), Ids::COLORED_TORCH_BLUE],
1238 [Blocks::COPPER_TORCH(), Ids::COPPER_TORCH],
1239 [Blocks::GREEN_TORCH(), Ids::COLORED_TORCH_GREEN],
1240 [Blocks::PURPLE_TORCH(), Ids::COLORED_TORCH_PURPLE],
1241 [Blocks::RED_TORCH(), Ids::COLORED_TORCH_RED],
1242 [Blocks::SOUL_TORCH(), Ids::SOUL_TORCH],
1243 [Blocks::TORCH(), Ids::TORCH],
1244 [Blocks::UNDERWATER_TORCH(), Ids::UNDERWATER_TORCH]
1245 ] as [$block, $id]){
1246 $reg->mapModel(Model::create($block, $id)->properties([$commonProperties->torchFacing]));
1247 }
1248 }
1249
1250 private static function registerChemistryMappings(BlockSerializerDeserializerRegistrar $reg, CommonProperties $commonProperties) : void{
1251 foreach([
1252 [Blocks::COMPOUND_CREATOR(), Ids::COMPOUND_CREATOR],
1253 [Blocks::ELEMENT_CONSTRUCTOR(), Ids::ELEMENT_CONSTRUCTOR],
1254 [Blocks::LAB_TABLE(), Ids::LAB_TABLE],
1255 [Blocks::MATERIAL_REDUCER(), Ids::MATERIAL_REDUCER],
1256 ] as [$block, $id]){
1257 $reg->mapModel(Model::create($block, $id)->properties([$commonProperties->horizontalFacingSWNEInverted]));
1258 }
1259 }
1260
1261 private static function register1to1CustomMappings(BlockSerializerDeserializerRegistrar $reg, CommonProperties $commonProperties) : void{
1262 //TODO: some of these have repeated accessor refs, we might be able to deduplicate them
1263 //A
1264 $reg->mapModel(Model::create(Blocks::ACTIVATOR_RAIL(), Ids::ACTIVATOR_RAIL)->properties([
1265 new BoolProperty(StateNames::RAIL_DATA_BIT, fn(ActivatorRail $b) => $b->isPowered(), fn(ActivatorRail $b, bool $v) => $b->setPowered($v)),
1266 $commonProperties->straightOnlyRailShape
1267 ]));
1268
1269 //B
1270 $reg->mapModel(Model::create(Blocks::BAMBOO(), Ids::BAMBOO)->properties([
1271 new ValueFromStringProperty(StateNames::BAMBOO_LEAF_SIZE, ValueMappings::getInstance()->bambooLeafSize, fn(Bamboo $b) => $b->getLeafSize(), fn(Bamboo $b, int $v) => $b->setLeafSize($v)),
1272 new BoolProperty(StateNames::AGE_BIT, fn(Bamboo $b) => $b->isReady(), fn(Bamboo $b, bool $v) => $b->setReady($v)),
1273 new BoolFromStringProperty(StateNames::BAMBOO_STALK_THICKNESS, StringValues::BAMBOO_STALK_THICKNESS_THIN, StringValues::BAMBOO_STALK_THICKNESS_THICK, fn(Bamboo $b) => $b->isThick(), fn(Bamboo $b, bool $v) => $b->setThick($v))
1274 ]));
1275 $reg->mapModel(Model::create(Blocks::BAMBOO_SAPLING(), Ids::BAMBOO_SAPLING)->properties([
1276 new BoolProperty(StateNames::AGE_BIT, fn(BambooSapling $b) => $b->isReady(), fn(BambooSapling $b, bool $v) => $b->setReady($v))
1277 ]));
1278 $reg->mapModel(Model::create(Blocks::BANNER(), Ids::STANDING_BANNER)->properties([$commonProperties->floorSignLikeRotation]));
1279 $reg->mapModel(Model::create(Blocks::BARREL(), Ids::BARREL)->properties([
1280 $commonProperties->anyFacingClassic,
1281 new BoolProperty(StateNames::OPEN_BIT, fn(Barrel $b) => $b->isOpen(), fn(Barrel $b, bool $v) => $b->setOpen($v))
1282 ]));
1283 $reg->mapModel(Model::create(Blocks::BASALT(), Ids::BASALT)->properties([$commonProperties->pillarAxis]));
1284 $reg->mapModel(Model::create(Blocks::BED(), Ids::BED)->properties([
1285 new BoolProperty(StateNames::HEAD_PIECE_BIT, fn(Bed $b) => $b->isHeadPart(), fn(Bed $b, bool $v) => $b->setHead($v)),
1286 new BoolProperty(StateNames::OCCUPIED_BIT, fn(Bed $b) => $b->isOccupied(), fn(Bed $b, bool $v) => $b->setOccupied($v)),
1287 $commonProperties->horizontalFacingSWNE
1288 ]));
1289 $reg->mapModel(Model::create(Blocks::BEDROCK(), Ids::BEDROCK)->properties([
1290 new BoolProperty(StateNames::INFINIBURN_BIT, fn(Bedrock $b) => $b->burnsForever(), fn(Bedrock $b, bool $v) => $b->setBurnsForever($v))
1291 ]));
1292 $reg->mapModel(Model::create(Blocks::BELL(), Ids::BELL)->properties([
1293 BoolProperty::unused(StateNames::TOGGLE_BIT, false),
1294 new ValueFromStringProperty(StateNames::ATTACHMENT, ValueMappings::getInstance()->bellAttachmentType, fn(Bell $b) => $b->getAttachmentType(), fn(Bell $b, BellAttachmentType $v) => $b->setAttachmentType($v)),
1295 $commonProperties->horizontalFacingSWNE
1296 ]));
1297 $reg->mapModel(Model::create(Blocks::BONE_BLOCK(), Ids::BONE_BLOCK)->properties([
1298 IntProperty::unused(StateNames::DEPRECATED, 0),
1299 $commonProperties->pillarAxis
1300 ]));
1301
1302 $reg->mapModel(Model::create(Blocks::BREWING_STAND(), Ids::BREWING_STAND)->properties(array_map(fn(BrewingStandSlot $slot) => new BoolProperty(match ($slot) {
1303 BrewingStandSlot::EAST => StateNames::BREWING_STAND_SLOT_A_BIT,
1304 BrewingStandSlot::SOUTHWEST => StateNames::BREWING_STAND_SLOT_B_BIT,
1305 BrewingStandSlot::NORTHWEST => StateNames::BREWING_STAND_SLOT_C_BIT
1306 }, fn(BrewingStand $b) => $b->hasSlot($slot), fn(BrewingStand $b, bool $v) => $b->setSlot($slot, $v)), BrewingStandSlot::cases())));
1307
1308 //C
1309 $reg->mapModel(Model::create(Blocks::CACTUS(), Ids::CACTUS)->properties([
1310 new IntProperty(StateNames::AGE, 0, 15, fn(Cactus $b) => $b->getAge(), fn(Cactus $b, int $v) => $b->setAge($v))
1311 ]));
1312 $reg->mapModel(Model::create(Blocks::CAKE(), Ids::CAKE)->properties([
1313 new IntProperty(StateNames::BITE_COUNTER, 0, 6, fn(Cake $b) => $b->getBites(), fn(Cake $b, int $v) => $b->setBites($v))
1314 ]));
1315 $reg->mapModel(Model::create(Blocks::CAMPFIRE(), Ids::CAMPFIRE)->properties($commonProperties->campfireProperties));
1316 $reg->mapModel(Model::create(Blocks::CARVED_PUMPKIN(), Ids::CARVED_PUMPKIN)->properties([
1317 $commonProperties->horizontalFacingCardinal
1318 ]));
1319 $reg->mapModel(Model::create(Blocks::CHAIN(), Ids::IRON_CHAIN)->properties([$commonProperties->pillarAxis]));
1320 $reg->mapModel(Model::create(Blocks::CHISELED_BOOKSHELF(), Ids::CHISELED_BOOKSHELF)->properties([
1321 $commonProperties->horizontalFacingSWNE,
1323 StateNames::BOOKS_STORED,
1324 EnumFromRawStateMap::int(ChiseledBookshelfSlot::class, fn(ChiseledBookshelfSlot $case) => match($case){
1325 //these are (currently) the same as the internal values, but it's best not to rely on those in case Mojang mess with the flags
1326 ChiseledBookshelfSlot::TOP_LEFT => 1 << 0,
1327 ChiseledBookshelfSlot::TOP_MIDDLE => 1 << 1,
1328 ChiseledBookshelfSlot::TOP_RIGHT => 1 << 2,
1329 ChiseledBookshelfSlot::BOTTOM_LEFT => 1 << 3,
1330 ChiseledBookshelfSlot::BOTTOM_MIDDLE => 1 << 4,
1331 ChiseledBookshelfSlot::BOTTOM_RIGHT => 1 << 5
1332 }),
1333 fn(ChiseledBookshelf $b) => $b->getSlots(),
1334 fn(ChiseledBookshelf $b, array $v) => $b->setSlots($v)
1335 )
1336 ]));
1337 $reg->mapModel(Model::create(Blocks::CHISELED_QUARTZ(), Ids::CHISELED_QUARTZ_BLOCK)->properties([$commonProperties->pillarAxis]));
1338 $reg->mapModel(Model::create(Blocks::CHEST(), Ids::CHEST)->properties([$commonProperties->horizontalFacingCardinal]));
1339 $reg->mapModel(Model::create(Blocks::CHORUS_FLOWER(), Ids::CHORUS_FLOWER)->properties([
1340 new IntProperty(StateNames::AGE, ChorusFlower::MIN_AGE, ChorusFlower::MAX_AGE, fn(ChorusFlower $b) => $b->getAge(), fn(ChorusFlower $b, int $v) => $b->setAge($v))
1341 ]));
1342 $reg->mapModel(Model::create(Blocks::COCOA_POD(), Ids::COCOA)->properties([
1343 new IntProperty(StateNames::AGE, 0, 2, fn(CocoaBlock $b) => $b->getAge(), fn(CocoaBlock $b, int $v) => $b->setAge($v)),
1344 $commonProperties->horizontalFacingSWNEInverted
1345 ]));
1346
1347 //D
1348 $reg->mapModel(Model::create(Blocks::DEEPSLATE(), Ids::DEEPSLATE)->properties([$commonProperties->pillarAxis]));
1349 $reg->mapModel(Model::create(Blocks::DETECTOR_RAIL(), Ids::DETECTOR_RAIL)->properties([
1350 new BoolProperty(StateNames::RAIL_DATA_BIT, fn(DetectorRail $b) => $b->isActivated(), fn(DetectorRail $b, bool $v) => $b->setActivated($v)),
1351 $commonProperties->straightOnlyRailShape
1352 ]));
1353
1354 //E
1355 $reg->mapModel(Model::create(Blocks::ENDER_CHEST(), Ids::ENDER_CHEST)->properties([$commonProperties->horizontalFacingCardinal]));
1356 $reg->mapModel(Model::create(Blocks::END_PORTAL_FRAME(), Ids::END_PORTAL_FRAME)->properties([
1357 new BoolProperty(StateNames::END_PORTAL_EYE_BIT, fn(EndPortalFrame $b) => $b->hasEye(), fn(EndPortalFrame $b, bool $v) => $b->setEye($v)),
1358 $commonProperties->horizontalFacingCardinal
1359 ]));
1360 $reg->mapModel(Model::create(Blocks::END_ROD(), Ids::END_ROD)->properties([
1361 new ValueFromIntProperty(StateNames::FACING_DIRECTION, ValueMappings::getInstance()->facingEndRod, fn(EndRod $b) => $b->getFacing(), fn(EndRod $b, Facing $v) => $b->setFacing($v)),
1362 ]));
1363
1364 //F
1365 $reg->mapModel(Model::create(Blocks::FARMLAND(), Ids::FARMLAND)->properties([
1366 new IntProperty(StateNames::MOISTURIZED_AMOUNT, 0, 7, fn(Farmland $b) => $b->getWetness(), fn(Farmland $b, int $v) => $b->setWetness($v))
1367 ]));
1368 $reg->mapModel(Model::create(Blocks::FIRE(), Ids::FIRE)->properties([
1369 new IntProperty(StateNames::AGE, 0, 15, fn(Fire $b) => $b->getAge(), fn(Fire $b, int $v) => $b->setAge($v))
1370 ]));
1371 $reg->mapModel(Model::create(Blocks::FLOWER_POT(), Ids::FLOWER_POT)->properties([
1372 BoolProperty::unused(StateNames::UPDATE_BIT, false)
1373 ]));
1374 $reg->mapModel(Model::create(Blocks::FROSTED_ICE(), Ids::FROSTED_ICE)->properties([
1375 new IntProperty(StateNames::AGE, 0, 3, fn(FrostedIce $b) => $b->getAge(), fn(FrostedIce $b, int $v) => $b->setAge($v))
1376 ]));
1377
1378 //G
1379 $reg->mapModel(Model::create(Blocks::GLOWING_ITEM_FRAME(), Ids::GLOW_FRAME)->properties($commonProperties->itemFrameProperties));
1380
1381 //H
1382 $reg->mapModel(Model::create(Blocks::HAY_BALE(), Ids::HAY_BLOCK)->properties([
1383 IntProperty::unused(StateNames::DEPRECATED, 0),
1384 $commonProperties->pillarAxis
1385 ]));
1386 $reg->mapModel(Model::create(Blocks::HOPPER(), Ids::HOPPER)->properties([
1387 //kinda weird this doesn't use powered_bit?
1388 new BoolProperty(StateNames::TOGGLE_BIT, fn(PoweredByRedstone $b) => $b->isPowered(), fn(PoweredByRedstone $b, bool $v) => $b->setPowered($v)),
1389 new ValueFromIntProperty(StateNames::FACING_DIRECTION, ValueMappings::getInstance()->facingExceptUp, fn(Hopper $b) => $b->getFacing()->value, fn(Hopper $b, int $v) => $b->setFacing(Facing::from($v))),
1390 ]));
1391
1392 //I
1393 $reg->mapModel(Model::create(Blocks::INFESTED_DEEPSLATE(), Ids::INFESTED_DEEPSLATE)->properties([$commonProperties->pillarAxis]));
1394 $reg->mapModel(Model::create(Blocks::IRON_DOOR(), Ids::IRON_DOOR)->properties($commonProperties->doorProperties));
1395 $reg->mapModel(Model::create(Blocks::IRON_TRAPDOOR(), Ids::IRON_TRAPDOOR)->properties($commonProperties->trapdoorProperties));
1396 $reg->mapModel(Model::create(Blocks::ITEM_FRAME(), Ids::FRAME)->properties($commonProperties->itemFrameProperties));
1397
1398 //L
1399 $reg->mapModel(Model::create(Blocks::LADDER(), Ids::LADDER)->properties([$commonProperties->horizontalFacingClassic]));
1400 $reg->mapModel(Model::create(Blocks::LANTERN(), Ids::LANTERN)->properties([
1401 new BoolProperty(StateNames::HANGING, fn(Lantern $b) => $b->isHanging(), fn(Lantern $b, bool $v) => $b->setHanging($v))
1402 ]));
1403 $reg->mapModel(Model::create(Blocks::LECTERN(), Ids::LECTERN)->properties([
1404 new BoolProperty(StateNames::POWERED_BIT, fn(Lectern $b) => $b->isProducingSignal(), fn(Lectern $b, bool $v) => $b->setProducingSignal($v)),
1405 $commonProperties->horizontalFacingCardinal,
1406 ]));
1407 $reg->mapModel(Model::create(Blocks::LEVER(), Ids::LEVER)->properties([
1408 new ValueFromStringProperty(StateNames::LEVER_DIRECTION, ValueMappings::getInstance()->leverFacing, fn(Lever $b) => $b->getFacing(), fn(Lever $b, LeverFacing $v) => $b->setFacing($v)),
1409 new BoolProperty(StateNames::OPEN_BIT, fn(Lever $b) => $b->isActivated(), fn(Lever $b, bool $v) => $b->setActivated($v)),
1410 ]));
1411 $reg->mapModel(Model::create(Blocks::LIT_PUMPKIN(), Ids::LIT_PUMPKIN)->properties([$commonProperties->horizontalFacingCardinal]));
1412 $reg->mapModel(Model::create(Blocks::LOOM(), Ids::LOOM)->properties([$commonProperties->horizontalFacingSWNE]));
1413
1414 //M
1415 $reg->mapModel(Model::create(Blocks::MUDDY_MANGROVE_ROOTS(), Ids::MUDDY_MANGROVE_ROOTS)->properties([$commonProperties->pillarAxis]));
1416 $reg->mapModel(Model::create(Blocks::NETHER_WART(), Ids::NETHER_WART)->properties([
1417 new IntProperty(StateNames::AGE, 0, 3, fn(NetherWartPlant $b) => $b->getAge(), fn(NetherWartPlant $b, int $v) => $b->setAge($v))
1418 ]));
1419 $reg->mapModel(Model::create(Blocks::NETHER_PORTAL(), Ids::PORTAL)->properties([
1420 //TODO: hack for lack of horizontal axis enum :(
1421 new ValueFromStringProperty(StateNames::PORTAL_AXIS, ValueMappings::getInstance()->portalAxis, fn(NetherPortal $b) => $b->getAxis()->value, fn(NetherPortal $b, int $v) => $b->setAxis(Axis::from($v)))
1422 ]));
1423
1424 //P
1425 $reg->mapModel(Model::create(Blocks::PINK_PETALS(), Ids::PINK_PETALS)->properties([
1426 //Pink petals only uses 0-3, but GROWTH state can go up to 7
1427 new IntProperty(StateNames::GROWTH, 0, 7, fn(PinkPetals $b) => $b->getCount(), fn(PinkPetals $b, int $v) => $b->setCount(min($v, PinkPetals::MAX_COUNT)), offset: 1),
1428 $commonProperties->horizontalFacingCardinal
1429 ]));
1430 $reg->mapModel(Model::create(Blocks::POWERED_RAIL(), Ids::GOLDEN_RAIL)->properties([
1431 new BoolProperty(StateNames::RAIL_DATA_BIT, fn(PoweredRail $b) => $b->isPowered(), fn(PoweredRail $b, bool $v) => $b->setPowered($v)), //TODO: shared with ActivatorRail
1432 $commonProperties->straightOnlyRailShape
1433 ]));
1434 $reg->mapModel(Model::create(Blocks::PITCHER_PLANT(), Ids::PITCHER_PLANT)->properties([
1435 new BoolProperty(StateNames::UPPER_BLOCK_BIT, fn(DoublePlant $b) => $b->isTop(), fn(DoublePlant $b, bool $v) => $b->setTop($v)), //TODO: don't we have helpers for this?
1436 ]));
1437 $reg->mapModel(Model::create(Blocks::POLISHED_BASALT(), Ids::POLISHED_BASALT)->properties([$commonProperties->pillarAxis]));
1438 $reg->mapModel(Model::create(Blocks::POLISHED_BLACKSTONE_BUTTON(), Ids::POLISHED_BLACKSTONE_BUTTON)->properties($commonProperties->buttonProperties));
1439 $reg->mapModel(Model::create(Blocks::POLISHED_BLACKSTONE_PRESSURE_PLATE(), Ids::POLISHED_BLACKSTONE_PRESSURE_PLATE)->properties($commonProperties->simplePressurePlateProperties));
1440 $reg->mapModel(Model::create(Blocks::PUMPKIN(), Ids::PUMPKIN)->properties([
1441 //not used, has no visible effect
1442 $commonProperties->dummyCardinalDirection
1443 ]));
1444 $reg->mapModel(Model::create(Blocks::PURPUR(), Ids::PURPUR_BLOCK)->properties([
1445 $commonProperties->dummyPillarAxis
1446 ]));
1447 $reg->mapModel(Model::create(Blocks::PURPUR_PILLAR(), Ids::PURPUR_PILLAR)->properties([$commonProperties->pillarAxis]));
1448
1449 //Q
1450 $reg->mapModel(Model::create(Blocks::QUARTZ(), Ids::QUARTZ_BLOCK)->properties([
1451 $commonProperties->dummyPillarAxis
1452 ]));
1453 $reg->mapModel(Model::create(Blocks::QUARTZ_PILLAR(), Ids::QUARTZ_PILLAR)->properties([$commonProperties->pillarAxis]));
1454
1455 //R
1456 $reg->mapModel(Model::create(Blocks::RAIL(), Ids::RAIL)->properties([
1457 new ValueFromIntProperty(StateNames::RAIL_DIRECTION, EnumFromRawStateMap::int(RailShape::class, fn(RailShape $case) => match($case){
1458 RailShape::FLAT_AXIS_Z => BlockLegacyMetadata::RAIL_STRAIGHT_NORTH_SOUTH,
1459 RailShape::FLAT_AXIS_X => BlockLegacyMetadata::RAIL_STRAIGHT_EAST_WEST,
1460 RailShape::ASCENDING_EAST => BlockLegacyMetadata::RAIL_ASCENDING_EAST,
1461 RailShape::ASCENDING_WEST => BlockLegacyMetadata::RAIL_ASCENDING_WEST,
1462 RailShape::ASCENDING_NORTH => BlockLegacyMetadata::RAIL_ASCENDING_NORTH,
1463 RailShape::ASCENDING_SOUTH => BlockLegacyMetadata::RAIL_ASCENDING_SOUTH,
1464 RailShape::CURVED_NORTHEAST => BlockLegacyMetadata::RAIL_CURVE_NORTHEAST,
1465 RailShape::CURVED_NORTHWEST => BlockLegacyMetadata::RAIL_CURVE_NORTHWEST,
1466 RailShape::CURVED_SOUTHEAST => BlockLegacyMetadata::RAIL_CURVE_SOUTHEAST,
1467 RailShape::CURVED_SOUTHWEST => BlockLegacyMetadata::RAIL_CURVE_SOUTHWEST,
1468 }), fn(Rail $b) => $b->getShape(), fn(Rail $b, RailShape $v) => $b->setShape($v))
1469 ]));
1470 $reg->mapModel(Model::create(Blocks::REDSTONE_WIRE(), Ids::REDSTONE_WIRE)->properties([$commonProperties->analogRedstoneSignal]));
1471 $reg->mapModel(Model::create(Blocks::RESPAWN_ANCHOR(), Ids::RESPAWN_ANCHOR)->properties([
1472 new IntProperty(StateNames::RESPAWN_ANCHOR_CHARGE, 0, 4, fn(RespawnAnchor $b) => $b->getCharges(), fn(RespawnAnchor $b, int $v) => $b->setCharges($v))
1473 ]));
1474
1475 //S
1476 $reg->mapModel(Model::create(Blocks::SEA_PICKLE(), Ids::SEA_PICKLE)->properties([
1477 new IntProperty(StateNames::CLUSTER_COUNT, 0, 3, fn(SeaPickle $b) => $b->getCount(), fn(SeaPickle $b, int $v) => $b->setCount($v), offset: 1),
1478 new BoolProperty(StateNames::DEAD_BIT, fn(SeaPickle $b) => $b->isUnderwater(), fn(SeaPickle $b, bool $v) => $b->setUnderwater($v), inverted: true)
1479 ]));
1480 $reg->mapModel(Model::create(Blocks::SMALL_DRIPLEAF(), Ids::SMALL_DRIPLEAF_BLOCK)->properties([
1481 new BoolProperty(StateNames::UPPER_BLOCK_BIT, fn(SmallDripleaf $b) => $b->isTop(), fn(SmallDripleaf $b, bool $v) => $b->setTop($v)),
1482 $commonProperties->horizontalFacingCardinal
1483 ]));
1484 $reg->mapModel(Model::create(Blocks::SMOOTH_QUARTZ(), Ids::SMOOTH_QUARTZ)->properties([
1485 $commonProperties->dummyPillarAxis
1486 ]));
1487 $reg->mapModel(Model::create(Blocks::SNOW_LAYER(), Ids::SNOW_LAYER)->properties([
1488 new DummyProperty(StateNames::COVERED_BIT, false),
1489 new IntProperty(StateNames::HEIGHT, 0, 7, fn(SnowLayer $b) => $b->getLayers(), fn(SnowLayer $b, int $v) => $b->setLayers($v), offset: 1)
1490 ]));
1491 $reg->mapModel(Model::create(Blocks::SOUL_CAMPFIRE(), Ids::SOUL_CAMPFIRE)->properties($commonProperties->campfireProperties));
1492 $reg->mapModel(Model::create(Blocks::SOUL_FIRE(), Ids::SOUL_FIRE)->properties([
1493 new DummyProperty(StateNames::AGE, 0) //this is useless for soul fire, since it doesn't have the logic associated
1494 ]));
1495 $reg->mapModel(Model::create(Blocks::SOUL_LANTERN(), Ids::SOUL_LANTERN)->properties([
1496 new BoolProperty(StateNames::HANGING, fn(Lantern $b) => $b->isHanging(), fn(Lantern $b, bool $v) => $b->setHanging($v)) //TODO: repeated
1497 ]));
1498 $reg->mapModel(Model::create(Blocks::STONE_BUTTON(), Ids::STONE_BUTTON)->properties($commonProperties->buttonProperties));
1499 $reg->mapModel(Model::create(Blocks::STONE_PRESSURE_PLATE(), Ids::STONE_PRESSURE_PLATE)->properties($commonProperties->simplePressurePlateProperties));
1500 $reg->mapModel(Model::create(Blocks::STONECUTTER(), Ids::STONECUTTER_BLOCK)->properties([
1501 $commonProperties->horizontalFacingCardinal
1502 ]));
1503 $reg->mapModel(Model::create(Blocks::SUGARCANE(), Ids::REEDS)->properties([
1504 new IntProperty(StateNames::AGE, 0, 15, fn(Sugarcane $b) => $b->getAge(), fn(Sugarcane $b, int $v) => $b->setAge($v))
1505 ]));
1506
1507 //T
1508 $reg->mapModel(Model::create(Blocks::TRAPPED_CHEST(), Ids::TRAPPED_CHEST)->properties([
1509 $commonProperties->horizontalFacingCardinal
1510 ]));
1511 $reg->mapModel(Model::create(Blocks::TRIPWIRE(), Ids::TRIP_WIRE)->properties([
1512 new BoolProperty(StateNames::ATTACHED_BIT, fn(Tripwire $b) => $b->isConnected(), fn(Tripwire $b, bool $v) => $b->setConnected($v)),
1513 new BoolProperty(StateNames::DISARMED_BIT, fn(Tripwire $b) => $b->isDisarmed(), fn(Tripwire $b, bool $v) => $b->setDisarmed($v)),
1514 new BoolProperty(StateNames::SUSPENDED_BIT, fn(Tripwire $b) => $b->isSuspended(), fn(Tripwire $b, bool $v) => $b->setSuspended($v)),
1515 new BoolProperty(StateNames::POWERED_BIT, fn(Tripwire $b) => $b->isTriggered(), fn(Tripwire $b, bool $v) => $b->setTriggered($v)),
1516 ]));
1517 $reg->mapModel(Model::create(Blocks::TRIPWIRE_HOOK(), Ids::TRIPWIRE_HOOK)->properties([
1518 new BoolProperty(StateNames::ATTACHED_BIT, fn(TripwireHook $b) => $b->isConnected(), fn(TripwireHook $b, bool $v) => $b->setConnected($v)),
1519 new BoolProperty(StateNames::POWERED_BIT, fn(TripwireHook $b) => $b->isPowered(), fn(TripwireHook $b, bool $v) => $b->setPowered($v)),
1520 $commonProperties->horizontalFacingSWNE
1521 ]));
1522
1523 $reg->mapModel(Model::create(Blocks::TWISTING_VINES(), Ids::TWISTING_VINES)->properties([
1524 new IntProperty(StateNames::TWISTING_VINES_AGE, 0, 25, fn(NetherVines $b) => $b->getAge(), fn(NetherVines $b, int $v) => $b->setAge($v))
1525 ]));
1526
1527 //W
1528 $reg->mapModel(Model::create(Blocks::WALL_BANNER(), Ids::WALL_BANNER)->properties([$commonProperties->horizontalFacingClassic]));
1529 $reg->mapModel(Model::create(Blocks::WEEPING_VINES(), Ids::WEEPING_VINES)->properties([
1530 new IntProperty(StateNames::WEEPING_VINES_AGE, 0, 25, fn(NetherVines $b) => $b->getAge(), fn(NetherVines $b, int $v) => $b->setAge($v))
1531 ]));
1532 $reg->mapModel(Model::create(Blocks::WEIGHTED_PRESSURE_PLATE_HEAVY(), Ids::HEAVY_WEIGHTED_PRESSURE_PLATE)->properties([$commonProperties->analogRedstoneSignal]));
1533 $reg->mapModel(Model::create(Blocks::WEIGHTED_PRESSURE_PLATE_LIGHT(), Ids::LIGHT_WEIGHTED_PRESSURE_PLATE)->properties([$commonProperties->analogRedstoneSignal]));
1534 }
1535
1540 private static function mapAsymmetricSerializer(BlockSerializerDeserializerRegistrar $reg, Model $model) : void{
1541 $id = $model->getId();
1542 $properties = $model->getProperties();
1543 $reg->serializer->map($model->getBlock(), function(Block $block) use ($id, $properties) : Writer{
1544 $writer = new Writer($id);
1545 foreach($properties as $property){
1546 $property->serialize($block, $writer);
1547 }
1548 return $writer;
1549 });
1550 }
1551
1557 private static function deserializeAsymmetric(Model $model, Reader $in) : Block{
1558 $block = clone $model->getBlock();
1559 foreach($model->getProperties() as $property){
1560 $property->deserialize($block, $in);
1561 }
1562 return $block;
1563 }
1564
1571 private static function registerSplitMappings(BlockSerializerDeserializerRegistrar $reg, CommonProperties $commonProperties) : void{
1572 //big dripleaf - split into head / stem variants, as stems don't have tilt or leaf state
1573 $bigDripleafHeadModel = Model::create(Blocks::BIG_DRIPLEAF_HEAD(), Ids::BIG_DRIPLEAF)->properties([
1574 $commonProperties->horizontalFacingCardinal,
1575 new ValueFromStringProperty(StateNames::BIG_DRIPLEAF_TILT, ValueMappings::getInstance()->dripleafState, fn(BigDripleafHead $b) => $b->getLeafState(), fn(BigDripleafHead $b, DripleafState $v) => $b->setLeafState($v)),
1576 new DummyProperty(StateNames::BIG_DRIPLEAF_HEAD, true)
1577 ]);
1578 $bigDripleafStemModel = Model::create(Blocks::BIG_DRIPLEAF_STEM(), Ids::BIG_DRIPLEAF)->properties([
1579 $commonProperties->horizontalFacingCardinal,
1580 new DummyProperty(StateNames::BIG_DRIPLEAF_TILT, StringValues::BIG_DRIPLEAF_TILT_NONE),
1581 new DummyProperty(StateNames::BIG_DRIPLEAF_HEAD, false)
1582 ]);
1583 self::mapAsymmetricSerializer($reg, $bigDripleafHeadModel);
1584 self::mapAsymmetricSerializer($reg, $bigDripleafStemModel);
1585 $reg->deserializer->map(Ids::BIG_DRIPLEAF, fn(Reader $in) => $in->readBool(StateNames::BIG_DRIPLEAF_HEAD) ?
1586 self::deserializeAsymmetric($bigDripleafHeadModel, $in) :
1587 self::deserializeAsymmetric($bigDripleafStemModel, $in)
1588 );
1589
1590 $fillLevelProperty = new IntProperty(StateNames::FILL_LEVEL, 1, 6, fn(FillableCauldron $b) => $b->getFillLevel(), fn(FillableCauldron $b, int $v) => $b->setFillLevel($v));
1591
1592 //this pretends to be a water cauldron on disk and stores its real information in the block actor data, therefore only a serializer is needed
1593 self::mapAsymmetricSerializer($reg, Model::create(Blocks::POTION_CAULDRON(), Ids::CAULDRON)->properties([$fillLevelProperty, new DummyProperty(StateNames::CAULDRON_LIQUID, StringValues::CAULDRON_LIQUID_WATER)]));
1594
1595 $lavaCauldronModel = Model::create(Blocks::LAVA_CAULDRON(), Ids::CAULDRON)->properties([
1596 $fillLevelProperty,
1597 new DummyProperty(StateNames::CAULDRON_LIQUID, StringValues::CAULDRON_LIQUID_LAVA)
1598 ]);
1599 $waterCauldronModel = Model::create(Blocks::WATER_CAULDRON(), Ids::CAULDRON)->properties([
1600 $fillLevelProperty,
1601 new DummyProperty(StateNames::CAULDRON_LIQUID, StringValues::CAULDRON_LIQUID_WATER)
1602 ]);
1603 $emptyCauldronModel = Model::create(Blocks::CAULDRON(), Ids::CAULDRON)->properties([
1604 new DummyProperty(StateNames::FILL_LEVEL, 0),
1605 new DummyProperty(StateNames::CAULDRON_LIQUID, StringValues::CAULDRON_LIQUID_WATER)
1606 ]);
1607 self::mapAsymmetricSerializer($reg, $lavaCauldronModel);
1608 self::mapAsymmetricSerializer($reg, $waterCauldronModel);
1609 self::mapAsymmetricSerializer($reg, $emptyCauldronModel);
1610 $reg->deserializer->map(Ids::CAULDRON, fn(Reader $in) => $in->readInt(StateNames::FILL_LEVEL) === 0 ?
1611 self::deserializeAsymmetric($emptyCauldronModel, $in) :
1612 match ($liquid = $in->readString(StateNames::CAULDRON_LIQUID)) {
1613 StringValues::CAULDRON_LIQUID_WATER => self::deserializeAsymmetric($waterCauldronModel, $in),
1614 StringValues::CAULDRON_LIQUID_LAVA => self::deserializeAsymmetric($lavaCauldronModel, $in),
1615 StringValues::CAULDRON_LIQUID_POWDER_SNOW => throw new UnsupportedBlockStateException("Powder snow is not supported yet"),
1616 default => throw $in->badValueException(StateNames::CAULDRON_LIQUID, $liquid)
1617 }
1618 );
1619
1620 //mushroom stems, split for consistency with all-sided logs vs normal logs
1621 $allSidedMushroomStemModel = Model::create(Blocks::ALL_SIDED_MUSHROOM_STEM(), Ids::MUSHROOM_STEM)->properties([new DummyProperty(StateNames::HUGE_MUSHROOM_BITS, BlockLegacyMetadata::MUSHROOM_BLOCK_ALL_STEM)]);
1622 $mushroomStemModel = Model::create(Blocks::MUSHROOM_STEM(), Ids::MUSHROOM_STEM)->properties([new DummyProperty(StateNames::HUGE_MUSHROOM_BITS, BlockLegacyMetadata::MUSHROOM_BLOCK_STEM)]);
1623 self::mapAsymmetricSerializer($reg, $allSidedMushroomStemModel);
1624 self::mapAsymmetricSerializer($reg, $mushroomStemModel);
1625 $reg->deserializer->map(Ids::MUSHROOM_STEM, fn(Reader $in) : Block => match ($in->readInt(StateNames::HUGE_MUSHROOM_BITS)) {
1626 BlockLegacyMetadata::MUSHROOM_BLOCK_ALL_STEM => self::deserializeAsymmetric($allSidedMushroomStemModel, $in),
1627 BlockLegacyMetadata::MUSHROOM_BLOCK_STEM => self::deserializeAsymmetric($mushroomStemModel, $in),
1628 default => throw new BlockStateDeserializeException("This state does not exist"),
1629 });
1630
1631 //pitcher crop, split into single and double variants as double has different properties and behaviour
1632 //this will probably be the most annoying to unify
1633 $pitcherCropModel = Model::create(Blocks::PITCHER_CROP(), Ids::PITCHER_CROP)->properties([
1634 new IntProperty(StateNames::GROWTH, 0, PitcherCrop::MAX_AGE, fn(PitcherCrop $b) => $b->getAge(), fn(PitcherCrop $b, int $v) => $b->setAge($v)),
1635 new DummyProperty(StateNames::UPPER_BLOCK_BIT, false)
1636 ]);
1637 $doublePitcherCropAgeOffset = PitcherCrop::MAX_AGE + 1;
1638 $doublePitcherCropModel = Model::create(Blocks::DOUBLE_PITCHER_CROP(), Ids::PITCHER_CROP)->properties([
1639 new IntProperty(
1640 StateNames::GROWTH,
1641 $doublePitcherCropAgeOffset, //TODO: it would be a bit less awkward if the bounds applied _after_ applying the offset, instead of before
1642 7,
1643 fn(DoublePitcherCrop $b) => $b->getAge(),
1644 fn(DoublePitcherCrop $b, int $v) => $b->setAge(min($v, DoublePitcherCrop::MAX_AGE)), //state may give up to 7, but only up to 4 is valid
1645 offset: -$doublePitcherCropAgeOffset
1646 ),
1647 new BoolProperty(StateNames::UPPER_BLOCK_BIT, fn(DoublePitcherCrop $b) => $b->isTop(), fn(DoublePitcherCrop $b, bool $v) => $b->setTop($v))
1648 ]);
1649 self::mapAsymmetricSerializer($reg, $pitcherCropModel);
1650 self::mapAsymmetricSerializer($reg, $doublePitcherCropModel);
1651 $reg->deserializer->map(Ids::PITCHER_CROP, fn(Reader $in) => $in->readInt(StateNames::GROWTH) <= PitcherCrop::MAX_AGE ?
1652 ($in->readBool(StateNames::UPPER_BLOCK_BIT) ?
1653 //top pitcher crop with age 0-2 is an invalid state, only the bottom half should exist in this case
1654 Blocks::AIR() :
1655 self::deserializeAsymmetric($pitcherCropModel, $in)
1656 ) : self::deserializeAsymmetric($doublePitcherCropModel, $in)
1657 );
1658
1659 //these only exist within PM (mapped from tile properties) as they don't support the same properties as a
1660 //normal banner, therefore no deserializer is needed
1661 self::mapAsymmetricSerializer($reg, Model::create(Blocks::OMINOUS_BANNER(), Ids::STANDING_BANNER)->properties([$commonProperties->floorSignLikeRotation]));
1662 self::mapAsymmetricSerializer($reg, Model::create(Blocks::OMINOUS_WALL_BANNER(), Ids::WALL_BANNER)->properties([$commonProperties->horizontalFacingClassic]));
1663
1664 foreach([
1665 Ids::ACACIA_HANGING_SIGN => [Blocks::ACACIA_CEILING_CENTER_HANGING_SIGN(), Blocks::ACACIA_CEILING_EDGES_HANGING_SIGN(), Blocks::ACACIA_WALL_HANGING_SIGN()],
1666 Ids::BAMBOO_HANGING_SIGN => [Blocks::BAMBOO_CEILING_CENTER_HANGING_SIGN(), Blocks::BAMBOO_CEILING_EDGES_HANGING_SIGN(), Blocks::BAMBOO_WALL_HANGING_SIGN()],
1667 Ids::BIRCH_HANGING_SIGN => [Blocks::BIRCH_CEILING_CENTER_HANGING_SIGN(), Blocks::BIRCH_CEILING_EDGES_HANGING_SIGN(), Blocks::BIRCH_WALL_HANGING_SIGN()],
1668 Ids::CHERRY_HANGING_SIGN => [Blocks::CHERRY_CEILING_CENTER_HANGING_SIGN(), Blocks::CHERRY_CEILING_EDGES_HANGING_SIGN(), Blocks::CHERRY_WALL_HANGING_SIGN()],
1669 Ids::CRIMSON_HANGING_SIGN => [Blocks::CRIMSON_CEILING_CENTER_HANGING_SIGN(), Blocks::CRIMSON_CEILING_EDGES_HANGING_SIGN(), Blocks::CRIMSON_WALL_HANGING_SIGN()],
1670 Ids::DARK_OAK_HANGING_SIGN => [Blocks::DARK_OAK_CEILING_CENTER_HANGING_SIGN(), Blocks::DARK_OAK_CEILING_EDGES_HANGING_SIGN(), Blocks::DARK_OAK_WALL_HANGING_SIGN()],
1671 Ids::JUNGLE_HANGING_SIGN => [Blocks::JUNGLE_CEILING_CENTER_HANGING_SIGN(), Blocks::JUNGLE_CEILING_EDGES_HANGING_SIGN(), Blocks::JUNGLE_WALL_HANGING_SIGN()],
1672 Ids::MANGROVE_HANGING_SIGN => [Blocks::MANGROVE_CEILING_CENTER_HANGING_SIGN(), Blocks::MANGROVE_CEILING_EDGES_HANGING_SIGN(), Blocks::MANGROVE_WALL_HANGING_SIGN()],
1673 Ids::OAK_HANGING_SIGN => [Blocks::OAK_CEILING_CENTER_HANGING_SIGN(), Blocks::OAK_CEILING_EDGES_HANGING_SIGN(), Blocks::OAK_WALL_HANGING_SIGN()],
1674 Ids::PALE_OAK_HANGING_SIGN => [Blocks::PALE_OAK_CEILING_CENTER_HANGING_SIGN(), Blocks::PALE_OAK_CEILING_EDGES_HANGING_SIGN(), Blocks::PALE_OAK_WALL_HANGING_SIGN()],
1675 Ids::SPRUCE_HANGING_SIGN => [Blocks::SPRUCE_CEILING_CENTER_HANGING_SIGN(), Blocks::SPRUCE_CEILING_EDGES_HANGING_SIGN(), Blocks::SPRUCE_WALL_HANGING_SIGN()],
1676 Ids::WARPED_HANGING_SIGN => [Blocks::WARPED_CEILING_CENTER_HANGING_SIGN(), Blocks::WARPED_CEILING_EDGES_HANGING_SIGN(), Blocks::WARPED_WALL_HANGING_SIGN()],
1677 ] as $id => [$center, $edges, $wall]){
1678 //attached_bit - true for ceiling center signs, false for ceiling edges signs and wall signs
1679 //hanging - true for all ceiling signs, false for wall signs
1680 //facing_direction - used for ceiling edges signs and wall signs
1681 //ground_sign_direction - used by ceiling center signs only
1682 $centerModel = Model::create($center, $id)->properties([
1683 $commonProperties->floorSignLikeRotation,
1684 new DummyProperty(StateNames::ATTACHED_BIT, true),
1685 new DummyProperty(StateNames::HANGING, true),
1686 new DummyProperty(StateNames::FACING_DIRECTION, 2)
1687 ]);
1688 $edgesModel = Model::create($edges, $id)->properties([
1689 new DummyProperty(StateNames::GROUND_SIGN_DIRECTION, 0),
1690 new DummyProperty(StateNames::ATTACHED_BIT, false),
1691 new DummyProperty(StateNames::HANGING, true),
1692 $commonProperties->horizontalFacingClassic,
1693 ]);
1694 $wallModel = Model::create($wall, $id)->properties([
1695 new DummyProperty(StateNames::GROUND_SIGN_DIRECTION, 0),
1696 new DummyProperty(StateNames::ATTACHED_BIT, false),
1697 new DummyProperty(StateNames::HANGING, false),
1698 $commonProperties->horizontalFacingClassic
1699 ]);
1700 self::mapAsymmetricSerializer($reg, $centerModel);
1701 self::mapAsymmetricSerializer($reg, $edgesModel);
1702 self::mapAsymmetricSerializer($reg, $wallModel);
1703 $reg->deserializer->map($id, fn(Reader $in) => $in->readBool(StateNames::HANGING) ?
1704 ($in->readBool(StateNames::ATTACHED_BIT) ?
1705 self::deserializeAsymmetric($centerModel, $in) :
1706 self::deserializeAsymmetric($edgesModel, $in)
1707 ) :
1708 self::deserializeAsymmetric($wallModel, $in));
1709 }
1710 }
1711}
setLeafState(DripleafState $leafState)
setCount(int $count)
Definition Candle.php:58
setInverted(bool $inverted=true)
setNoDecay(bool $noDecay)
Definition Leaves.php:62
setCheckDecay(bool $checkDecay)
Definition Leaves.php:70
setMushroomBlockType(MushroomBlockType $mushroomBlockType)
setReady(bool $ready)
Definition Sapling.php:58
setShape(StraightOnlyRailShape $shape)
setFaces(array $faces)
Definition Vine.php:58
static create(Block $block, string $id)
Definition Model.php:69
static unused(string $name, bool $serializedValue)
static string(string $class, \Closure $mapper, ?\Closure $aliasMapper=null)
static int(string $class, \Closure $mapper, ?\Closure $aliasMapper=null)
static string(array $serializeMap, array $deserializeAliases=[])
static unused(string $name, int $serializedValue)
setFacing(HorizontalFacingOption $facing)