Additional specialisation for colored blocks

this reduces boilerplate even further
This commit is contained in:
Dylan K. Taylor
2025-08-15 22:24:27 +01:00
parent c0fad353a2
commit 431790a319
3 changed files with 76 additions and 168 deletions

View File

@ -45,7 +45,6 @@ use pocketmine\block\CakeWithCandle;
use pocketmine\block\CakeWithDyedCandle; use pocketmine\block\CakeWithDyedCandle;
use pocketmine\block\Campfire; use pocketmine\block\Campfire;
use pocketmine\block\Candle; use pocketmine\block\Candle;
use pocketmine\block\Carpet;
use pocketmine\block\Carrot; use pocketmine\block\Carrot;
use pocketmine\block\CarvedPumpkin; use pocketmine\block\CarvedPumpkin;
use pocketmine\block\CaveVines; use pocketmine\block\CaveVines;
@ -55,8 +54,6 @@ use pocketmine\block\Chest;
use pocketmine\block\ChiseledBookshelf; use pocketmine\block\ChiseledBookshelf;
use pocketmine\block\ChorusFlower; use pocketmine\block\ChorusFlower;
use pocketmine\block\CocoaBlock; use pocketmine\block\CocoaBlock;
use pocketmine\block\Concrete;
use pocketmine\block\ConcretePowder;
use pocketmine\block\Copper; use pocketmine\block\Copper;
use pocketmine\block\CopperBulb; use pocketmine\block\CopperBulb;
use pocketmine\block\CopperDoor; use pocketmine\block\CopperDoor;
@ -73,8 +70,6 @@ use pocketmine\block\Door;
use pocketmine\block\DoublePitcherCrop; use pocketmine\block\DoublePitcherCrop;
use pocketmine\block\DoublePlant; use pocketmine\block\DoublePlant;
use pocketmine\block\DoubleTallGrass; use pocketmine\block\DoubleTallGrass;
use pocketmine\block\DyedCandle;
use pocketmine\block\DyedShulkerBox;
use pocketmine\block\EnderChest; use pocketmine\block\EnderChest;
use pocketmine\block\EndPortalFrame; use pocketmine\block\EndPortalFrame;
use pocketmine\block\EndRod; use pocketmine\block\EndRod;
@ -133,11 +128,6 @@ use pocketmine\block\SmallDripleaf;
use pocketmine\block\SnowLayer; use pocketmine\block\SnowLayer;
use pocketmine\block\SoulCampfire; use pocketmine\block\SoulCampfire;
use pocketmine\block\Sponge; use pocketmine\block\Sponge;
use pocketmine\block\StainedGlass;
use pocketmine\block\StainedGlassPane;
use pocketmine\block\StainedHardenedClay;
use pocketmine\block\StainedHardenedGlass;
use pocketmine\block\StainedHardenedGlassPane;
use pocketmine\block\Stair; use pocketmine\block\Stair;
use pocketmine\block\StoneButton; use pocketmine\block\StoneButton;
use pocketmine\block\Stonecutter; use pocketmine\block\Stonecutter;
@ -153,6 +143,7 @@ use pocketmine\block\Tripwire;
use pocketmine\block\TripwireHook; use pocketmine\block\TripwireHook;
use pocketmine\block\UnderwaterTorch; use pocketmine\block\UnderwaterTorch;
use pocketmine\block\utils\BrewingStandSlot; use pocketmine\block\utils\BrewingStandSlot;
use pocketmine\block\utils\Colored;
use pocketmine\block\utils\CoralType; use pocketmine\block\utils\CoralType;
use pocketmine\block\utils\DirtType; use pocketmine\block\utils\DirtType;
use pocketmine\block\utils\DripleafState; use pocketmine\block\utils\DripleafState;
@ -176,7 +167,6 @@ use pocketmine\block\WoodenDoor;
use pocketmine\block\WoodenPressurePlate; use pocketmine\block\WoodenPressurePlate;
use pocketmine\block\WoodenStairs; use pocketmine\block\WoodenStairs;
use pocketmine\block\WoodenTrapdoor; use pocketmine\block\WoodenTrapdoor;
use pocketmine\block\Wool;
use pocketmine\data\bedrock\block\BlockLegacyMetadata; use pocketmine\data\bedrock\block\BlockLegacyMetadata;
use pocketmine\data\bedrock\block\BlockStateData; use pocketmine\data\bedrock\block\BlockStateData;
use pocketmine\data\bedrock\block\BlockStateNames as StateNames; use pocketmine\data\bedrock\block\BlockStateNames as StateNames;
@ -319,43 +309,57 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{
}); });
} }
/**
* @phpstan-template TBlock of Block&Colored
* @phpstan-param TBlock $block
* @phpstan-param ?\Closure(TBlock, Writer) : Writer $extra
*/
public function mapColored(
Block $block,
string $prefix,
string $suffix,
?\Closure $extra = null
) : void{
$this->mapFlattenedEnum(
$block,
ValueMappings::getInstance()->getEnumMap(DyeColor::class),
$prefix,
$suffix,
fn(Colored $block) => $block->getColor(),
$extra
);
}
private function registerCandleSerializers() : void{ private function registerCandleSerializers() : void{
$this->map(Blocks::CANDLE(), fn(Candle $block) => Helper::encodeCandle($block, new Writer(Ids::CANDLE))); $this->map(Blocks::CANDLE(), fn(Candle $block) => Helper::encodeCandle($block, new Writer(Ids::CANDLE)));
$this->mapFlattenedEnum( $this->mapColored(
Blocks::DYED_CANDLE(), Blocks::DYED_CANDLE(),
ValueMappings::getInstance()->getEnumMap(DyeColor::class),
"minecraft:", "minecraft:",
"_candle", "_candle",
fn(DyedCandle $block) => $block->getColor(),
Helper::encodeCandle(...) Helper::encodeCandle(...)
); );
$this->map(Blocks::CAKE_WITH_CANDLE(), fn(CakeWithCandle $block) => Writer::create(Ids::CANDLE_CAKE) $this->map(Blocks::CAKE_WITH_CANDLE(), fn(CakeWithCandle $block) => Writer::create(Ids::CANDLE_CAKE)
->writeBool(StateNames::LIT, $block->isLit())); ->writeBool(StateNames::LIT, $block->isLit()));
$this->mapFlattenedEnum( $this->mapColored(
Blocks::CAKE_WITH_DYED_CANDLE(), Blocks::CAKE_WITH_DYED_CANDLE(),
ValueMappings::getInstance()->getEnumMap(DyeColor::class),
"minecraft:", "minecraft:",
"_candle_cake", "_candle_cake",
fn(CakeWithDyedCandle $block) => $block->getColor(),
fn(CakeWithDyedCandle $block, Writer $writer) => $writer->writeBool(StateNames::LIT, $block->isLit()) fn(CakeWithDyedCandle $block, Writer $writer) => $writer->writeBool(StateNames::LIT, $block->isLit())
); );
} }
public function registerFlatColorBlockSerializers() : void{ public function registerFlatColorBlockSerializers() : void{
$this->mapFlattenedEnum( $this->mapColored(Blocks::STAINED_HARDENED_GLASS(), "minecraft:hard_", "_stained_glass");
Blocks::STAINED_HARDENED_GLASS(), $this->mapColored(Blocks::STAINED_HARDENED_GLASS_PANE(), "minecraft:hard_", "_stained_glass_pane");
ValueMappings::getInstance()->getEnumMap(DyeColor::class),
"minecraft:hard_", $this->mapColored(Blocks::CARPET(), "minecraft:", "_carpet");
"_stained_glass", $this->mapColored(Blocks::CONCRETE(), "minecraft:", "_concrete");
fn(StainedHardenedGlass $block) => $block->getColor() $this->mapColored(Blocks::CONCRETE_POWDER(), "minecraft:", "_concrete_powder");
); $this->mapColored(Blocks::DYED_SHULKER_BOX(), "minecraft:", "_shulker_box");
$this->mapFlattenedEnum( $this->mapColored(Blocks::STAINED_CLAY(), "minecraft:", "_terracotta");
Blocks::STAINED_HARDENED_GLASS_PANE(), $this->mapColored(Blocks::STAINED_GLASS(), "minecraft:", "_stained_glass");
ValueMappings::getInstance()->getEnumMap(DyeColor::class), $this->mapColored(Blocks::STAINED_GLASS_PANE(), "minecraft:", "_stained_glass_pane");
"minecraft:hard_", $this->mapColored(Blocks::WOOL(), "minecraft:", "_wool");
"_stained_glass_pane",
fn(StainedHardenedGlassPane $block) => $block->getColor(),
);
$this->map(Blocks::GLAZED_TERRACOTTA(), function(GlazedTerracotta $block) : Writer{ $this->map(Blocks::GLAZED_TERRACOTTA(), function(GlazedTerracotta $block) : Writer{
return Writer::create(match($block->getColor()){ return Writer::create(match($block->getColor()){
@ -366,7 +370,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{
DyeColor::GRAY => Ids::GRAY_GLAZED_TERRACOTTA, DyeColor::GRAY => Ids::GRAY_GLAZED_TERRACOTTA,
DyeColor::GREEN => Ids::GREEN_GLAZED_TERRACOTTA, DyeColor::GREEN => Ids::GREEN_GLAZED_TERRACOTTA,
DyeColor::LIGHT_BLUE => Ids::LIGHT_BLUE_GLAZED_TERRACOTTA, DyeColor::LIGHT_BLUE => Ids::LIGHT_BLUE_GLAZED_TERRACOTTA,
DyeColor::LIGHT_GRAY => Ids::SILVER_GLAZED_TERRACOTTA, DyeColor::LIGHT_GRAY => Ids::SILVER_GLAZED_TERRACOTTA, //minecraft sadness
DyeColor::LIME => Ids::LIME_GLAZED_TERRACOTTA, DyeColor::LIME => Ids::LIME_GLAZED_TERRACOTTA,
DyeColor::MAGENTA => Ids::MAGENTA_GLAZED_TERRACOTTA, DyeColor::MAGENTA => Ids::MAGENTA_GLAZED_TERRACOTTA,
DyeColor::ORANGE => Ids::ORANGE_GLAZED_TERRACOTTA, DyeColor::ORANGE => Ids::ORANGE_GLAZED_TERRACOTTA,
@ -378,68 +382,6 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{
}) })
->writeHorizontalFacing($block->getFacing()); ->writeHorizontalFacing($block->getFacing());
}); });
$this->mapFlattenedEnum(
Blocks::WOOL(),
ValueMappings::getInstance()->getEnumMap(DyeColor::class),
"minecraft:",
"_wool",
fn(Wool $block) => $block->getColor()
);
$this->mapFlattenedEnum(
Blocks::CARPET(),
ValueMappings::getInstance()->getEnumMap(DyeColor::class),
"minecraft:",
"_carpet",
fn(Carpet $block) => $block->getColor()
);
$this->mapFlattenedEnum(
Blocks::DYED_SHULKER_BOX(),
ValueMappings::getInstance()->getEnumMap(DyeColor::class),
"minecraft:",
"_shulker_box",
fn(DyedShulkerBox $block) => $block->getColor()
);
$this->mapFlattenedEnum(
Blocks::CONCRETE(),
ValueMappings::getInstance()->getEnumMap(DyeColor::class),
"minecraft:",
"_concrete",
fn(Concrete $block) => $block->getColor()
);
$this->mapFlattenedEnum(
Blocks::CONCRETE_POWDER(),
ValueMappings::getInstance()->getEnumMap(DyeColor::class),
"minecraft:",
"_concrete_powder",
fn(ConcretePowder $block) => $block->getColor()
);
$this->mapFlattenedEnum(
Blocks::STAINED_CLAY(),
ValueMappings::getInstance()->getEnumMap(DyeColor::class),
"minecraft:",
"_terracotta",
fn(StainedHardenedClay $block) => $block->getColor()
);
$this->mapFlattenedEnum(
Blocks::STAINED_GLASS(),
ValueMappings::getInstance()->getEnumMap(DyeColor::class),
"minecraft:",
"_stained_glass",
fn(StainedGlass $block) => $block->getColor()
);
$this->mapFlattenedEnum(
Blocks::STAINED_GLASS_PANE(),
ValueMappings::getInstance()->getEnumMap(DyeColor::class),
"minecraft:",
"_stained_glass_pane",
fn(StainedGlassPane $block) => $block->getColor()
);
} }
private function registerFlatCoralSerializers() : void{ private function registerFlatCoralSerializers() : void{

View File

@ -70,7 +70,13 @@ final class BlockStateDeserializerHelper{
->setPressed($in->readBool(BlockStateNames::BUTTON_PRESSED_BIT)); ->setPressed($in->readBool(BlockStateNames::BUTTON_PRESSED_BIT));
} }
/** @throws BlockStateDeserializeException */ /**
* @phpstan-template TCandle of Candle
* @phpstan-param TCandle $block
* @phpstan-return TCandle
*
* @throws BlockStateDeserializeException
*/
public static function decodeCandle(Candle $block, BlockStateReader $in) : Candle{ public static function decodeCandle(Candle $block, BlockStateReader $in) : Candle{
return $block return $block
->setCount($in->readBoundedInt(StateNames::CANDLES, 0, 3) + 1) ->setCount($in->readBoundedInt(StateNames::CANDLES, 0, 3) + 1)

View File

@ -40,6 +40,7 @@ use pocketmine\block\Stair;
use pocketmine\block\SweetBerryBush; use pocketmine\block\SweetBerryBush;
use pocketmine\block\utils\BrewingStandSlot; use pocketmine\block\utils\BrewingStandSlot;
use pocketmine\block\utils\ChiseledBookshelfSlot; use pocketmine\block\utils\ChiseledBookshelfSlot;
use pocketmine\block\utils\Colored;
use pocketmine\block\utils\CopperMaterial; use pocketmine\block\utils\CopperMaterial;
use pocketmine\block\utils\CopperOxidation; use pocketmine\block\utils\CopperOxidation;
use pocketmine\block\utils\CoralType; use pocketmine\block\utils\CoralType;
@ -187,39 +188,52 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{
} }
} }
private function registerCandleDeserializers() : void{ /**
$this->map(Ids::CANDLE, fn(Reader $in) => Helper::decodeCandle(Blocks::CANDLE(), $in)); * @phpstan-template TBlock of Block&Colored
* @phpstan-param \Closure() : TBlock $getBlock
* @phpstan-param ?\Closure(TBlock, Reader) : TBlock $extra
*/
public function mapColored(string $prefix, string $suffix, \Closure $getBlock, ?\Closure $extra = null) : void{
$this->mapFlattenedEnum( $this->mapFlattenedEnum(
ValueMappings::getInstance()->getEnumMap(DyeColor::class), ValueMappings::getInstance()->getEnumMap(DyeColor::class),
$prefix,
$suffix,
fn(DyeColor $color) => $getBlock()->setColor($color),
$extra
);
}
private function registerCandleDeserializers() : void{
$this->map(Ids::CANDLE, fn(Reader $in) => Helper::decodeCandle(Blocks::CANDLE(), $in));
$this->mapColored(
"minecraft:", "minecraft:",
"_candle", "_candle",
fn(DyeColor $color) => Blocks::DYED_CANDLE()->setColor($color), fn() => Blocks::DYED_CANDLE(),
Helper::decodeCandle(...) Helper::decodeCandle(...)
); );
$this->map(Ids::CANDLE_CAKE, fn(Reader $in) => Blocks::CAKE_WITH_CANDLE()->setLit($in->readBool(StateNames::LIT))); $this->map(Ids::CANDLE_CAKE, fn(Reader $in) => Blocks::CAKE_WITH_CANDLE()->setLit($in->readBool(StateNames::LIT)));
$this->mapFlattenedEnum(
ValueMappings::getInstance()->getEnumMap(DyeColor::class), $this->mapColored(
"minecraft:", "minecraft:",
"_candle_cake", "_candle_cake",
fn(DyeColor $color) => Blocks::CAKE_WITH_DYED_CANDLE()->setColor($color), fn() => Blocks::CAKE_WITH_DYED_CANDLE(),
fn(CakeWithDyedCandle $block, Reader $in) => $block->setLit($in->readBool(StateNames::LIT)) fn(CakeWithDyedCandle $block, Reader $in) => $block->setLit($in->readBool(StateNames::LIT))
); );
} }
private function registerFlatColorBlockDeserializers() : void{ private function registerFlatColorBlockDeserializers() : void{
$this->mapFlattenedEnum( $this->mapColored("minecraft:hard_", "_stained_glass", fn() => Blocks::STAINED_HARDENED_GLASS());
ValueMappings::getInstance()->getEnumMap(DyeColor::class), $this->mapColored("minecraft:hard_", "_stained_glass_pane", fn() => Blocks::STAINED_HARDENED_GLASS_PANE());
"minecraft:hard_",
"_stained_glass", $this->mapColored("minecraft:", "_carpet", fn() => Blocks::CARPET());
fn(DyeColor $color) => Blocks::STAINED_HARDENED_GLASS()->setColor($color) $this->mapColored("minecraft:", "_concrete", fn() => Blocks::CONCRETE());
); $this->mapColored("minecraft:", "_concrete_powder", fn() => Blocks::CONCRETE_POWDER());
$this->mapFlattenedEnum( $this->mapColored("minecraft:", "_shulker_box", fn() => Blocks::DYED_SHULKER_BOX());
ValueMappings::getInstance()->getEnumMap(DyeColor::class), $this->mapColored("minecraft:", "_stained_glass", fn() => Blocks::STAINED_GLASS());
"minecraft:hard_", $this->mapColored("minecraft:", "_stained_glass_pane", fn() => Blocks::STAINED_GLASS_PANE());
"_stained_glass_pane", $this->mapColored("minecraft:", "_terracotta", fn() => Blocks::STAINED_CLAY());
fn(DyeColor $color) => Blocks::STAINED_HARDENED_GLASS_PANE()->setColor($color) $this->mapColored("minecraft:", "_wool", fn() => Blocks::WOOL());
);
foreach([ foreach([
Ids::BLACK_GLAZED_TERRACOTTA => DyeColor::BLACK, Ids::BLACK_GLAZED_TERRACOTTA => DyeColor::BLACK,
@ -229,7 +243,7 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{
Ids::GRAY_GLAZED_TERRACOTTA => DyeColor::GRAY, Ids::GRAY_GLAZED_TERRACOTTA => DyeColor::GRAY,
Ids::GREEN_GLAZED_TERRACOTTA => DyeColor::GREEN, Ids::GREEN_GLAZED_TERRACOTTA => DyeColor::GREEN,
Ids::LIGHT_BLUE_GLAZED_TERRACOTTA => DyeColor::LIGHT_BLUE, Ids::LIGHT_BLUE_GLAZED_TERRACOTTA => DyeColor::LIGHT_BLUE,
Ids::SILVER_GLAZED_TERRACOTTA => DyeColor::LIGHT_GRAY, Ids::SILVER_GLAZED_TERRACOTTA => DyeColor::LIGHT_GRAY, //minecraft sadness
Ids::LIME_GLAZED_TERRACOTTA => DyeColor::LIME, Ids::LIME_GLAZED_TERRACOTTA => DyeColor::LIME,
Ids::MAGENTA_GLAZED_TERRACOTTA => DyeColor::MAGENTA, Ids::MAGENTA_GLAZED_TERRACOTTA => DyeColor::MAGENTA,
Ids::ORANGE_GLAZED_TERRACOTTA => DyeColor::ORANGE, Ids::ORANGE_GLAZED_TERRACOTTA => DyeColor::ORANGE,
@ -244,60 +258,6 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{
->setFacing($in->readHorizontalFacing()) ->setFacing($in->readHorizontalFacing())
); );
} }
$this->mapFlattenedEnum(
ValueMappings::getInstance()->getEnumMap(DyeColor::class),
"minecraft:",
"_wool",
fn(DyeColor $color) => Blocks::WOOL()->setColor($color)
);
$this->mapFlattenedEnum(
ValueMappings::getInstance()->getEnumMap(DyeColor::class),
"minecraft:",
"_carpet",
fn(DyeColor $color) => Blocks::CARPET()->setColor($color)
);
$this->mapFlattenedEnum(
ValueMappings::getInstance()->getEnumMap(DyeColor::class),
"minecraft:",
"_shulker_box",
fn(DyeColor $color) => Blocks::DYED_SHULKER_BOX()->setColor($color)
);
$this->mapFlattenedEnum(
ValueMappings::getInstance()->getEnumMap(DyeColor::class),
"minecraft:",
"_concrete",
fn(DyeColor $color) => Blocks::CONCRETE()->setColor($color)
);
$this->mapFlattenedEnum(
ValueMappings::getInstance()->getEnumMap(DyeColor::class),
"minecraft:",
"_concrete_powder",
fn(DyeColor $color) => Blocks::CONCRETE_POWDER()->setColor($color)
);
$this->mapFlattenedEnum(
ValueMappings::getInstance()->getEnumMap(DyeColor::class),
"minecraft:",
"_terracotta",
fn(DyeColor $color) => Blocks::STAINED_CLAY()->setColor($color)
);
$this->mapFlattenedEnum(
ValueMappings::getInstance()->getEnumMap(DyeColor::class),
"minecraft:",
"_stained_glass",
fn(DyeColor $color) => Blocks::STAINED_GLASS()->setColor($color)
);
$this->mapFlattenedEnum(
ValueMappings::getInstance()->getEnumMap(DyeColor::class),
"minecraft:",
"_stained_glass_pane",
fn(DyeColor $color) => Blocks::STAINED_GLASS_PANE()->setColor($color)
);
} }
private function registerFlatCoralDeserializers() : void{ private function registerFlatCoralDeserializers() : void{