From 4e6b34f57377e7e92892ed88d5ed3744642fcb1f Mon Sep 17 00:00:00 2001 From: IvanCraft623 <57236932+IvanCraft623@users.noreply.github.com> Date: Tue, 24 Sep 2024 21:25:10 -0500 Subject: [PATCH] Implement new 1.21 copper blocks (#6366) Added the following new blocks: - All types of Copper Bulb - All types of Copper Door - All types of Copper Trapdoor - All types of Chiseled Copper - All types of Copper Grate --- src/block/BlockTypeIds.php | 7 +- src/block/CopperBulb.php | 69 +++++++++++++ src/block/CopperDoor.php | 53 ++++++++++ src/block/CopperGrate.php | 33 +++++++ src/block/CopperTrapdoor.php | 44 +++++++++ src/block/VanillaBlocks.php | 12 +++ .../convert/BlockObjectToStateSerializer.php | 99 +++++++++++++++++++ .../BlockStateToObjectDeserializer.php | 72 ++++++++++++++ .../ItemSerializerDeserializerRegistrar.php | 28 ++++++ src/item/StringToItemParser.php | 5 + tests/phpstan/configs/phpstan-bugs.neon | 10 ++ .../block_factory_consistency_check.json | 5 + 12 files changed, 436 insertions(+), 1 deletion(-) create mode 100644 src/block/CopperBulb.php create mode 100644 src/block/CopperDoor.php create mode 100644 src/block/CopperGrate.php create mode 100644 src/block/CopperTrapdoor.php diff --git a/src/block/BlockTypeIds.php b/src/block/BlockTypeIds.php index 29f4e650d..3914a4b74 100644 --- a/src/block/BlockTypeIds.php +++ b/src/block/BlockTypeIds.php @@ -760,8 +760,13 @@ final class BlockTypeIds{ public const POLISHED_TUFF_SLAB = 10730; public const POLISHED_TUFF_STAIRS = 10731; public const POLISHED_TUFF_WALL = 10732; + public const COPPER_BULB = 10733; + public const COPPER_DOOR = 10734; + public const COPPER_TRAPDOOR = 10735; + public const CHISELED_COPPER = 10736; + public const COPPER_GRATE = 10737; - public const FIRST_UNUSED_BLOCK_ID = 10733; + public const FIRST_UNUSED_BLOCK_ID = 10738; private static int $nextDynamicId = self::FIRST_UNUSED_BLOCK_ID; diff --git a/src/block/CopperBulb.php b/src/block/CopperBulb.php new file mode 100644 index 000000000..223c63527 --- /dev/null +++ b/src/block/CopperBulb.php @@ -0,0 +1,69 @@ +encodeLitState($w); + $w->bool($this->powered); + } + + /** @return $this */ + public function togglePowered(bool $powered) : self{ + if($powered === $this->powered){ + return $this; + } + if ($powered) { + $this->setLit(!$this->lit); + } + $this->setPowered($powered); + return $this; + } + + public function getLightLevel() : int{ + if ($this->lit) { + return match($this->oxidation){ + CopperOxidation::NONE => 15, + CopperOxidation::EXPOSED => 12, + CopperOxidation::WEATHERED => 8, + CopperOxidation::OXIDIZED => 4, + }; + } + + return 0; + } +} diff --git a/src/block/CopperDoor.php b/src/block/CopperDoor.php new file mode 100644 index 000000000..d53be2323 --- /dev/null +++ b/src/block/CopperDoor.php @@ -0,0 +1,53 @@ +isSneaking() && $this->onInteractCopper($item, $face, $clickVector, $player, $returnedItems)) { + //copy copper properties to other half + $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); + $world = $this->position->getWorld(); + if ($other instanceof CopperDoor) { + $other->setOxidation($this->oxidation); + $other->setWaxed($this->waxed); + $world->setBlock($other->position, $other); + } + return true; + } + + return parent::onInteract($item, $face, $clickVector, $player, $returnedItems); + } +} diff --git a/src/block/CopperGrate.php b/src/block/CopperGrate.php new file mode 100644 index 000000000..fb59d846e --- /dev/null +++ b/src/block/CopperGrate.php @@ -0,0 +1,33 @@ +isSneaking() && $this->onInteractCopper($item, $face, $clickVector, $player, $returnedItems)) { + return true; + } + + return parent::onInteract($item, $face, $clickVector, $player, $returnedItems); + } +} diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 13c7e869a..60540dfb8 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -181,6 +181,7 @@ use function strtolower; * @method static Wood CHERRY_WOOD() * @method static Chest CHEST() * @method static ChiseledBookshelf CHISELED_BOOKSHELF() + * @method static Copper CHISELED_COPPER() * @method static Opaque CHISELED_DEEPSLATE() * @method static Opaque CHISELED_NETHER_BRICKS() * @method static Opaque CHISELED_POLISHED_BLACKSTONE() @@ -209,7 +210,11 @@ use function strtolower; * @method static Concrete CONCRETE() * @method static ConcretePowder CONCRETE_POWDER() * @method static Copper COPPER() + * @method static CopperBulb COPPER_BULB() + * @method static CopperDoor COPPER_DOOR() + * @method static CopperGrate COPPER_GRATE() * @method static CopperOre COPPER_ORE() + * @method static CopperTrapdoor COPPER_TRAPDOOR() * @method static Coral CORAL() * @method static CoralBlock CORAL_BLOCK() * @method static FloorCoralFan CORAL_FAN() @@ -1642,9 +1647,16 @@ final class VanillaBlocks{ self::register("lightning_rod", new LightningRod(new BID(Ids::LIGHTNING_ROD), "Lightning Rod", $copperBreakInfo)); self::register("copper", new Copper(new BID(Ids::COPPER), "Copper Block", $copperBreakInfo)); + self::register("chiseled_copper", new Copper(new BID(Ids::CHISELED_COPPER), "Chiseled Copper", $copperBreakInfo)); + self::register("copper_grate", new CopperGrate(new BID(Ids::COPPER_GRATE), "Copper Grate", $copperBreakInfo)); self::register("cut_copper", new Copper(new BID(Ids::CUT_COPPER), "Cut Copper Block", $copperBreakInfo)); self::register("cut_copper_slab", new CopperSlab(new BID(Ids::CUT_COPPER_SLAB), "Cut Copper Slab", $copperBreakInfo)); self::register("cut_copper_stairs", new CopperStairs(new BID(Ids::CUT_COPPER_STAIRS), "Cut Copper Stairs", $copperBreakInfo)); + self::register("copper_bulb", new CopperBulb(new BID(Ids::COPPER_BULB), "Copper Bulb", $copperBreakInfo)); + + $copperDoorBreakInfo = new Info(BreakInfo::pickaxe(3.0, ToolTier::STONE, 30.0)); + self::register("copper_door", new CopperDoor(new BID(Ids::COPPER_DOOR), "Copper Door", $copperDoorBreakInfo)); + self::register("copper_trapdoor", new CopperTrapdoor(new BID(Ids::COPPER_TRAPDOOR), "Copper Trapdoor", $copperDoorBreakInfo)); $candleBreakInfo = new Info(new BreakInfo(0.1)); self::register("candle", new Candle(new BID(Ids::CANDLE), "Candle", $candleBreakInfo)); diff --git a/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php b/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php index 0768d21c3..f85e84551 100644 --- a/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php +++ b/src/data/bedrock/block/convert/BlockObjectToStateSerializer.php @@ -58,8 +58,12 @@ use pocketmine\block\CocoaBlock; use pocketmine\block\Concrete; use pocketmine\block\ConcretePowder; use pocketmine\block\Copper; +use pocketmine\block\CopperBulb; +use pocketmine\block\CopperDoor; +use pocketmine\block\CopperGrate; use pocketmine\block\CopperSlab; use pocketmine\block\CopperStairs; +use pocketmine\block\CopperTrapdoor; use pocketmine\block\Coral; use pocketmine\block\CoralBlock; use pocketmine\block\DaylightSensor; @@ -1255,6 +1259,40 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ Helper::selectCopperId($oxidation, Ids::COPPER_BLOCK, Ids::EXPOSED_COPPER, Ids::WEATHERED_COPPER, Ids::OXIDIZED_COPPER) ); }); + $this->map(Blocks::CHISELED_COPPER(), function(Copper $block) : Writer{ + $oxidation = $block->getOxidation(); + return new Writer($block->isWaxed() ? + Helper::selectCopperId($oxidation, + Ids::WAXED_CHISELED_COPPER, + Ids::WAXED_EXPOSED_CHISELED_COPPER, + Ids::WAXED_WEATHERED_CHISELED_COPPER, + Ids::WAXED_OXIDIZED_CHISELED_COPPER + ) : + Helper::selectCopperId($oxidation, + Ids::CHISELED_COPPER, + Ids::EXPOSED_CHISELED_COPPER, + Ids::WEATHERED_CHISELED_COPPER, + Ids::OXIDIZED_CHISELED_COPPER + ) + ); + }); + $this->map(Blocks::COPPER_GRATE(), function(CopperGrate $block) : Writer{ + $oxidation = $block->getOxidation(); + return new Writer($block->isWaxed() ? + Helper::selectCopperId($oxidation, + Ids::WAXED_COPPER_GRATE, + Ids::WAXED_EXPOSED_COPPER_GRATE, + Ids::WAXED_WEATHERED_COPPER_GRATE, + Ids::WAXED_OXIDIZED_COPPER_GRATE + ) : + Helper::selectCopperId($oxidation, + Ids::COPPER_GRATE, + Ids::EXPOSED_COPPER_GRATE, + Ids::WEATHERED_COPPER_GRATE, + Ids::OXIDIZED_COPPER_GRATE + ) + ); + }); $this->map(Blocks::CUT_COPPER(), function(Copper $block) : Writer{ $oxidation = $block->getOxidation(); return new Writer($block->isWaxed() ? @@ -1322,6 +1360,67 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{ ) ); }); + $this->map(Blocks::COPPER_BULB(), function(CopperBulb $block) : Writer{ + $oxidation = $block->getOxidation(); + return Writer::create($block->isWaxed() ? + Helper::selectCopperId($oxidation, + Ids::WAXED_COPPER_BULB, + Ids::WAXED_EXPOSED_COPPER_BULB, + Ids::WAXED_WEATHERED_COPPER_BULB, + Ids::WAXED_OXIDIZED_COPPER_BULB) : + Helper::selectCopperId($oxidation, + Ids::COPPER_BULB, + Ids::EXPOSED_COPPER_BULB, + Ids::WEATHERED_COPPER_BULB, + Ids::OXIDIZED_COPPER_BULB + )) + ->writeBool(StateNames::LIT, $block->isLit()) + ->writeBool(StateNames::POWERED_BIT, $block->isPowered()); + }); + $this->map(Blocks::COPPER_DOOR(), function(CopperDoor $block) : Writer{ + $oxidation = $block->getOxidation(); + return Helper::encodeDoor( + $block, + new Writer($block->isWaxed() ? + Helper::selectCopperId( + $oxidation, + Ids::WAXED_COPPER_DOOR, + Ids::WAXED_EXPOSED_COPPER_DOOR, + Ids::WAXED_WEATHERED_COPPER_DOOR, + Ids::WAXED_OXIDIZED_COPPER_DOOR + ) : + Helper::selectCopperId( + $oxidation, + Ids::COPPER_DOOR, + Ids::EXPOSED_COPPER_DOOR, + Ids::WEATHERED_COPPER_DOOR, + Ids::OXIDIZED_COPPER_DOOR + ) + ) + ); + }); + $this->map(Blocks::COPPER_TRAPDOOR(), function(CopperTrapdoor $block) : Writer{ + $oxidation = $block->getOxidation(); + return Helper::encodeTrapdoor( + $block, + new Writer($block->isWaxed() ? + Helper::selectCopperId( + $oxidation, + Ids::WAXED_COPPER_TRAPDOOR, + Ids::WAXED_EXPOSED_COPPER_TRAPDOOR, + Ids::WAXED_WEATHERED_COPPER_TRAPDOOR, + Ids::WAXED_OXIDIZED_COPPER_TRAPDOOR + ) : + Helper::selectCopperId( + $oxidation, + Ids::COPPER_TRAPDOOR, + Ids::EXPOSED_COPPER_TRAPDOOR, + Ids::WEATHERED_COPPER_TRAPDOOR, + Ids::OXIDIZED_COPPER_TRAPDOOR + ) + ) + ); + }); $this->map(Blocks::COCOA_POD(), function(CocoaBlock $block) : Writer{ return Writer::create(Ids::COCOA) ->writeInt(StateNames::AGE, $block->getAge()) diff --git a/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php b/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php index 49365799c..19b5372a0 100644 --- a/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php +++ b/src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php @@ -1156,6 +1156,7 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ return $block; }); + $this->map(Ids::CHISELED_COPPER, fn() => Helper::decodeCopper(Blocks::CHISELED_COPPER(), CopperOxidation::NONE)); $this->map(Ids::CHISELED_QUARTZ_BLOCK, function(Reader $in) : Block{ return Blocks::CHISELED_QUARTZ() ->setAxis($in->readPillarAxis()); @@ -1187,6 +1188,14 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ ->setFacing(Facing::opposite($in->readLegacyHorizontalFacing())) ); $this->map(Ids::COPPER_BLOCK, fn() => Helper::decodeCopper(Blocks::COPPER(), CopperOxidation::NONE)); + $this->map(Ids::COPPER_BULB, function(Reader $in) : Block{ + return Helper::decodeCopper(Blocks::COPPER_BULB(), CopperOxidation::NONE) + ->setLit($in->readBool(StateNames::LIT)) + ->setPowered($in->readBool(StateNames::POWERED_BIT)); + }); + $this->map(Ids::COPPER_DOOR, fn(Reader $in) => Helper::decodeDoor(Helper::decodeCopper(Blocks::COPPER_DOOR(), CopperOxidation::NONE), $in)); + $this->map(Ids::COPPER_GRATE, fn() => Helper::decodeCopper(Blocks::COPPER_GRATE(), CopperOxidation::NONE)); + $this->map(Ids::COPPER_TRAPDOOR, fn(Reader $in) => Helper::decodeTrapdoor(Helper::decodeCopper(Blocks::COPPER_TRAPDOOR(), CopperOxidation::NONE), $in)); $this->map(Ids::CUT_COPPER, fn() => Helper::decodeCopper(Blocks::CUT_COPPER(), CopperOxidation::NONE)); $this->mapSlab(Ids::CUT_COPPER_SLAB, Ids::DOUBLE_CUT_COPPER_SLAB, fn() => Helper::decodeCopper(Blocks::CUT_COPPER_SLAB(), CopperOxidation::NONE)); $this->mapStairs(Ids::CUT_COPPER_STAIRS, fn() => Helper::decodeCopper(Blocks::CUT_COPPER_STAIRS(), CopperOxidation::NONE)); @@ -1245,9 +1254,18 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ ->setFacing($in->readCardinalHorizontalFacing()); }); $this->map(Ids::EXPOSED_COPPER, fn() => Helper::decodeCopper(Blocks::COPPER(), CopperOxidation::EXPOSED)); + $this->map(Ids::EXPOSED_CHISELED_COPPER, fn() => Helper::decodeCopper(Blocks::CHISELED_COPPER(), CopperOxidation::EXPOSED)); + $this->map(Ids::EXPOSED_COPPER_GRATE, fn() => Helper::decodeCopper(Blocks::COPPER_GRATE(), CopperOxidation::EXPOSED)); $this->map(Ids::EXPOSED_CUT_COPPER, fn() => Helper::decodeCopper(Blocks::CUT_COPPER(), CopperOxidation::EXPOSED)); $this->mapSlab(Ids::EXPOSED_CUT_COPPER_SLAB, Ids::EXPOSED_DOUBLE_CUT_COPPER_SLAB, fn() => Helper::decodeCopper(Blocks::CUT_COPPER_SLAB(), CopperOxidation::EXPOSED)); $this->mapStairs(Ids::EXPOSED_CUT_COPPER_STAIRS, fn() => Helper::decodeCopper(Blocks::CUT_COPPER_STAIRS(), CopperOxidation::EXPOSED)); + $this->map(Ids::EXPOSED_COPPER_BULB, function(Reader $in) : Block{ + return Helper::decodeCopper(Blocks::COPPER_BULB(), CopperOxidation::EXPOSED) + ->setLit($in->readBool(StateNames::LIT)) + ->setPowered($in->readBool(StateNames::POWERED_BIT)); + }); + $this->map(Ids::EXPOSED_COPPER_DOOR, fn(Reader $in) => Helper::decodeDoor(Helper::decodeCopper(Blocks::COPPER_DOOR(), CopperOxidation::EXPOSED), $in)); + $this->map(Ids::EXPOSED_COPPER_TRAPDOOR, fn(Reader $in) => Helper::decodeTrapdoor(Helper::decodeCopper(Blocks::COPPER_TRAPDOOR(), CopperOxidation::EXPOSED), $in)); $this->map(Ids::FARMLAND, function(Reader $in) : Block{ return Blocks::FARMLAND() ->setWetness($in->readBoundedInt(StateNames::MOISTURIZED_AMOUNT, 0, 7)); @@ -1401,9 +1419,18 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ $this->mapStairs(Ids::NORMAL_STONE_STAIRS, fn() => Blocks::STONE_STAIRS()); $this->map(Ids::OCHRE_FROGLIGHT, fn(Reader $in) => Blocks::FROGLIGHT()->setFroglightType(FroglightType::OCHRE)->setAxis($in->readPillarAxis())); $this->map(Ids::OXIDIZED_COPPER, fn() => Helper::decodeCopper(Blocks::COPPER(), CopperOxidation::OXIDIZED)); + $this->map(Ids::OXIDIZED_CHISELED_COPPER, fn() => Helper::decodeCopper(Blocks::CHISELED_COPPER(), CopperOxidation::OXIDIZED)); + $this->map(Ids::OXIDIZED_COPPER_GRATE, fn() => Helper::decodeCopper(Blocks::COPPER_GRATE(), CopperOxidation::OXIDIZED)); $this->map(Ids::OXIDIZED_CUT_COPPER, fn() => Helper::decodeCopper(Blocks::CUT_COPPER(), CopperOxidation::OXIDIZED)); $this->mapSlab(Ids::OXIDIZED_CUT_COPPER_SLAB, Ids::OXIDIZED_DOUBLE_CUT_COPPER_SLAB, fn() => Helper::decodeCopper(Blocks::CUT_COPPER_SLAB(), CopperOxidation::OXIDIZED)); $this->mapStairs(Ids::OXIDIZED_CUT_COPPER_STAIRS, fn() => Helper::decodeCopper(Blocks::CUT_COPPER_STAIRS(), CopperOxidation::OXIDIZED)); + $this->map(Ids::OXIDIZED_COPPER_BULB, function(Reader $in) : Block{ + return Helper::decodeCopper(Blocks::COPPER_BULB(), CopperOxidation::OXIDIZED) + ->setLit($in->readBool(StateNames::LIT)) + ->setPowered($in->readBool(StateNames::POWERED_BIT)); + }); + $this->map(Ids::OXIDIZED_COPPER_DOOR, fn(Reader $in) => Helper::decodeDoor(Helper::decodeCopper(Blocks::COPPER_DOOR(), CopperOxidation::OXIDIZED), $in)); + $this->map(Ids::OXIDIZED_COPPER_TRAPDOOR, fn(Reader $in) => Helper::decodeTrapdoor(Helper::decodeCopper(Blocks::COPPER_TRAPDOOR(), CopperOxidation::OXIDIZED), $in)); $this->map(Ids::PEARLESCENT_FROGLIGHT, fn(Reader $in) => Blocks::FROGLIGHT()->setFroglightType(FroglightType::PEARLESCENT)->setAxis($in->readPillarAxis())); $this->mapSlab(Ids::PETRIFIED_OAK_SLAB, Ids::PETRIFIED_OAK_DOUBLE_SLAB, fn() => Blocks::FAKE_WOODEN_SLAB()); $this->map(Ids::PINK_PETALS, function(Reader $in) : Block{ @@ -1677,25 +1704,70 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{ }); $this->map(Ids::WATER, fn(Reader $in) => Helper::decodeStillLiquid(Blocks::WATER(), $in)); $this->map(Ids::WAXED_COPPER, fn() => Helper::decodeWaxedCopper(Blocks::COPPER(), CopperOxidation::NONE)); + $this->map(Ids::WAXED_CHISELED_COPPER, fn() => Helper::decodeWaxedCopper(Blocks::CHISELED_COPPER(), CopperOxidation::NONE)); + $this->map(Ids::WAXED_COPPER_GRATE, fn() => Helper::decodeWaxedCopper(Blocks::COPPER_GRATE(), CopperOxidation::NONE)); $this->map(Ids::WAXED_CUT_COPPER, fn() => Helper::decodeWaxedCopper(Blocks::CUT_COPPER(), CopperOxidation::NONE)); $this->mapSlab(Ids::WAXED_CUT_COPPER_SLAB, Ids::WAXED_DOUBLE_CUT_COPPER_SLAB, fn() => Helper::decodeWaxedCopper(Blocks::CUT_COPPER_SLAB(), CopperOxidation::NONE)); $this->mapStairs(Ids::WAXED_CUT_COPPER_STAIRS, fn() => Helper::decodeWaxedCopper(Blocks::CUT_COPPER_STAIRS(), CopperOxidation::NONE)); + $this->map(Ids::WAXED_COPPER_BULB, function(Reader $in) : Block{ + return Helper::decodeWaxedCopper(Blocks::COPPER_BULB(), CopperOxidation::NONE) + ->setLit($in->readBool(StateNames::LIT)) + ->setPowered($in->readBool(StateNames::POWERED_BIT)); + }); + $this->map(Ids::WAXED_COPPER_DOOR, fn(Reader $in) => Helper::decodeDoor(Helper::decodeWaxedCopper(Blocks::COPPER_DOOR(), CopperOxidation::NONE), $in)); + $this->map(Ids::WAXED_COPPER_TRAPDOOR, fn(Reader $in) => Helper::decodeTrapdoor(Helper::decodeWaxedCopper(Blocks::COPPER_TRAPDOOR(), CopperOxidation::NONE), $in)); $this->map(Ids::WAXED_EXPOSED_COPPER, fn() => Helper::decodeWaxedCopper(Blocks::COPPER(), CopperOxidation::EXPOSED)); + $this->map(Ids::WAXED_EXPOSED_CHISELED_COPPER, fn() => Helper::decodeWaxedCopper(Blocks::CHISELED_COPPER(), CopperOxidation::EXPOSED)); + $this->map(Ids::WAXED_EXPOSED_COPPER_GRATE, fn() => Helper::decodeWaxedCopper(Blocks::COPPER_GRATE(), CopperOxidation::EXPOSED)); $this->map(Ids::WAXED_EXPOSED_CUT_COPPER, fn() => Helper::decodeWaxedCopper(Blocks::CUT_COPPER(), CopperOxidation::EXPOSED)); $this->mapSlab(Ids::WAXED_EXPOSED_CUT_COPPER_SLAB, Ids::WAXED_EXPOSED_DOUBLE_CUT_COPPER_SLAB, fn() => Helper::decodeWaxedCopper(Blocks::CUT_COPPER_SLAB(), CopperOxidation::EXPOSED)); $this->mapStairs(Ids::WAXED_EXPOSED_CUT_COPPER_STAIRS, fn() => Helper::decodeWaxedCopper(Blocks::CUT_COPPER_STAIRS(), CopperOxidation::EXPOSED)); + $this->map(Ids::WAXED_EXPOSED_COPPER_BULB, function(Reader $in) : Block{ + return Helper::decodeWaxedCopper(Blocks::COPPER_BULB(), CopperOxidation::EXPOSED) + ->setLit($in->readBool(StateNames::LIT)) + ->setPowered($in->readBool(StateNames::POWERED_BIT)); + }); + $this->map(Ids::WAXED_EXPOSED_COPPER_DOOR, fn(Reader $in) => Helper::decodeDoor(Helper::decodeWaxedCopper(Blocks::COPPER_DOOR(), CopperOxidation::EXPOSED), $in)); + $this->map(Ids::WAXED_EXPOSED_COPPER_TRAPDOOR, fn(Reader $in) => Helper::decodeTrapdoor(Helper::decodeWaxedCopper(Blocks::COPPER_TRAPDOOR(), CopperOxidation::EXPOSED), $in)); $this->map(Ids::WAXED_OXIDIZED_COPPER, fn() => Helper::decodeWaxedCopper(Blocks::COPPER(), CopperOxidation::OXIDIZED)); + $this->map(Ids::WAXED_OXIDIZED_CHISELED_COPPER, fn() => Helper::decodeWaxedCopper(Blocks::CHISELED_COPPER(), CopperOxidation::OXIDIZED)); + $this->map(Ids::WAXED_OXIDIZED_COPPER_GRATE, fn() => Helper::decodeWaxedCopper(Blocks::COPPER_GRATE(), CopperOxidation::OXIDIZED)); $this->map(Ids::WAXED_OXIDIZED_CUT_COPPER, fn() => Helper::decodeWaxedCopper(Blocks::CUT_COPPER(), CopperOxidation::OXIDIZED)); $this->mapSlab(Ids::WAXED_OXIDIZED_CUT_COPPER_SLAB, Ids::WAXED_OXIDIZED_DOUBLE_CUT_COPPER_SLAB, fn() => Helper::decodeWaxedCopper(Blocks::CUT_COPPER_SLAB(), CopperOxidation::OXIDIZED)); $this->mapStairs(Ids::WAXED_OXIDIZED_CUT_COPPER_STAIRS, fn() => Helper::decodeWaxedCopper(Blocks::CUT_COPPER_STAIRS(), CopperOxidation::OXIDIZED)); + $this->map(Ids::WAXED_OXIDIZED_COPPER_BULB, function(Reader $in) : Block{ + return Helper::decodeWaxedCopper(Blocks::COPPER_BULB(), CopperOxidation::OXIDIZED) + ->setLit($in->readBool(StateNames::LIT)) + ->setPowered($in->readBool(StateNames::POWERED_BIT)); + }); + $this->map(Ids::WAXED_OXIDIZED_COPPER_DOOR, fn(Reader $in) => Helper::decodeDoor(Helper::decodeWaxedCopper(Blocks::COPPER_DOOR(), CopperOxidation::OXIDIZED), $in)); + $this->map(Ids::WAXED_OXIDIZED_COPPER_TRAPDOOR, fn(Reader $in) => Helper::decodeTrapdoor(Helper::decodeWaxedCopper(Blocks::COPPER_TRAPDOOR(), CopperOxidation::OXIDIZED), $in)); $this->map(Ids::WAXED_WEATHERED_COPPER, fn() => Helper::decodeWaxedCopper(Blocks::COPPER(), CopperOxidation::WEATHERED)); + $this->map(Ids::WAXED_WEATHERED_CHISELED_COPPER, fn() => Helper::decodeWaxedCopper(Blocks::CHISELED_COPPER(), CopperOxidation::WEATHERED)); + $this->map(Ids::WAXED_WEATHERED_COPPER_GRATE, fn() => Helper::decodeWaxedCopper(Blocks::COPPER_GRATE(), CopperOxidation::WEATHERED)); $this->map(Ids::WAXED_WEATHERED_CUT_COPPER, fn() => Helper::decodeWaxedCopper(Blocks::CUT_COPPER(), CopperOxidation::WEATHERED)); $this->mapSlab(Ids::WAXED_WEATHERED_CUT_COPPER_SLAB, Ids::WAXED_WEATHERED_DOUBLE_CUT_COPPER_SLAB, fn() => Helper::decodeWaxedCopper(Blocks::CUT_COPPER_SLAB(), CopperOxidation::WEATHERED)); $this->mapStairs(Ids::WAXED_WEATHERED_CUT_COPPER_STAIRS, fn() => Helper::decodeWaxedCopper(Blocks::CUT_COPPER_STAIRS(), CopperOxidation::WEATHERED)); + $this->map(Ids::WAXED_WEATHERED_COPPER_BULB, function(Reader $in) : Block{ + return Helper::decodeWaxedCopper(Blocks::COPPER_BULB(), CopperOxidation::WEATHERED) + ->setLit($in->readBool(StateNames::LIT)) + ->setPowered($in->readBool(StateNames::POWERED_BIT)); + }); + $this->map(Ids::WAXED_WEATHERED_COPPER_DOOR, fn(Reader $in) => Helper::decodeDoor(Helper::decodeWaxedCopper(Blocks::COPPER_DOOR(), CopperOxidation::WEATHERED), $in)); + $this->map(Ids::WAXED_WEATHERED_COPPER_TRAPDOOR, fn(Reader $in) => Helper::decodeTrapdoor(Helper::decodeWaxedCopper(Blocks::COPPER_TRAPDOOR(), CopperOxidation::WEATHERED), $in)); $this->map(Ids::WEATHERED_COPPER, fn() => Helper::decodeCopper(Blocks::COPPER(), CopperOxidation::WEATHERED)); + $this->map(Ids::WEATHERED_CHISELED_COPPER, fn() => Helper::decodeCopper(Blocks::CHISELED_COPPER(), CopperOxidation::WEATHERED)); + $this->map(Ids::WEATHERED_COPPER_GRATE, fn() => Helper::decodeCopper(Blocks::COPPER_GRATE(), CopperOxidation::WEATHERED)); $this->map(Ids::WEATHERED_CUT_COPPER, fn() => Helper::decodeCopper(Blocks::CUT_COPPER(), CopperOxidation::WEATHERED)); $this->mapSlab(Ids::WEATHERED_CUT_COPPER_SLAB, Ids::WEATHERED_DOUBLE_CUT_COPPER_SLAB, fn() => Helper::decodeCopper(Blocks::CUT_COPPER_SLAB(), CopperOxidation::WEATHERED)); $this->mapStairs(Ids::WEATHERED_CUT_COPPER_STAIRS, fn() => Helper::decodeCopper(Blocks::CUT_COPPER_STAIRS(), CopperOxidation::WEATHERED)); + $this->map(Ids::WEATHERED_COPPER_BULB, function(Reader $in) : Block{ + return Helper::decodeCopper(Blocks::COPPER_BULB(), CopperOxidation::WEATHERED) + ->setLit($in->readBool(StateNames::LIT)) + ->setPowered($in->readBool(StateNames::POWERED_BIT)); + }); + $this->map(Ids::WEATHERED_COPPER_DOOR, fn(Reader $in) => Helper::decodeDoor(Helper::decodeCopper(Blocks::COPPER_DOOR(), CopperOxidation::WEATHERED), $in)); + $this->map(Ids::WEATHERED_COPPER_TRAPDOOR, fn(Reader $in) => Helper::decodeTrapdoor(Helper::decodeCopper(Blocks::COPPER_TRAPDOOR(), CopperOxidation::WEATHERED), $in)); $this->map(Ids::WEEPING_VINES, function(Reader $in) : Block{ return Blocks::WEEPING_VINES() ->setAge($in->readBoundedInt(StateNames::WEEPING_VINES_AGE, 0, 25)); diff --git a/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php b/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php index de9b5ae5e..d06b41626 100644 --- a/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php +++ b/src/data/bedrock/item/ItemSerializerDeserializerRegistrar.php @@ -25,7 +25,9 @@ namespace pocketmine\data\bedrock\item; use pocketmine\block\Bed; use pocketmine\block\Block; +use pocketmine\block\CopperDoor; use pocketmine\block\MobHead; +use pocketmine\block\utils\CopperOxidation; use pocketmine\block\utils\DyeColor; use pocketmine\block\VanillaBlocks as Blocks; use pocketmine\data\bedrock\CompoundTypeIds; @@ -56,6 +58,7 @@ final class ItemSerializerDeserializerRegistrar{ $this->register1to1BlockWithMetaMappings(); $this->register1to1ItemWithMetaMappings(); $this->register1ToNItemMappings(); + $this->registerMiscBlockMappings(); $this->registerMiscItemMappings(); } @@ -538,4 +541,29 @@ final class ItemSerializerDeserializerRegistrar{ } $this->serializer?->map(Items::DYE(), fn(Dye $item) => new Data(DyeColorIdMap::getInstance()->toItemId($item->getColor()))); } + + /** + * Registers serializers and deserializers for PocketMine-MP blockitems that don't fit any other pattern. + * Ideally we want to get rid of this completely, if possible. + * + * Most of these are single PocketMine-MP blocks which map to multiple IDs depending on their properties, which is + * complex to implement in a generic way. + */ + private function registerMiscBlockMappings() : void{ + $copperDoorStateIdMap = []; + foreach ([ + [Ids::COPPER_DOOR, CopperOxidation::NONE, false], + [Ids::EXPOSED_COPPER_DOOR, CopperOxidation::EXPOSED, false], + [Ids::WEATHERED_COPPER_DOOR, CopperOxidation::WEATHERED, false], + [Ids::OXIDIZED_COPPER_DOOR, CopperOxidation::OXIDIZED, false], + [Ids::WAXED_COPPER_DOOR, CopperOxidation::NONE, true], + [Ids::WAXED_EXPOSED_COPPER_DOOR, CopperOxidation::EXPOSED, true], + [Ids::WAXED_WEATHERED_COPPER_DOOR, CopperOxidation::WEATHERED, true], + [Ids::WAXED_OXIDIZED_COPPER_DOOR, CopperOxidation::OXIDIZED, true] + ] as [$id, $oxidation, $waxed]) { + $copperDoorStateIdMap[$oxidation->value][$waxed ? 1 : 0] = $id; + $this->deserializer?->mapBlock($id, fn() => Blocks::COPPER_DOOR()->setOxidation($oxidation)->setWaxed($waxed)); + } + $this->serializer?->mapBlock(Blocks::COPPER_DOOR(), fn(CopperDoor $block) => new Data($copperDoorStateIdMap[$block->getOxidation()->value][$block->isWaxed() ? 1 : 0])); + } } diff --git a/src/item/StringToItemParser.php b/src/item/StringToItemParser.php index 9f5db6950..ee0f1f5c5 100644 --- a/src/item/StringToItemParser.php +++ b/src/item/StringToItemParser.php @@ -98,9 +98,14 @@ final class StringToItemParser extends StringToTParser{ foreach(["" => false, "waxed_" => true] as $waxedPrefix => $waxed){ $register = fn(string $name, \Closure $callback) => $result->registerBlock($waxedPrefix . $oxPrefix . $name, $callback); $register("copper_block", fn() => Blocks::COPPER()->setOxidation($oxidation)->setWaxed($waxed)); + $register("chiseled_copper", fn() => Blocks::CHISELED_COPPER()->setOxidation($oxidation)->setWaxed($waxed)); + $register("copper_grate", fn() => Blocks::COPPER_GRATE()->setOxidation($oxidation)->setWaxed($waxed)); $register("cut_copper_block", fn() => Blocks::CUT_COPPER()->setOxidation($oxidation)->setWaxed($waxed)); $register("cut_copper_stairs", fn() => Blocks::CUT_COPPER_STAIRS()->setOxidation($oxidation)->setWaxed($waxed)); $register("cut_copper_slab", fn() => Blocks::CUT_COPPER_SLAB()->setOxidation($oxidation)->setWaxed($waxed)); + $register("copper_bulb", fn() => Blocks::COPPER_BULB()->setOxidation($oxidation)->setWaxed($waxed)); + $register("copper_door", fn() => Blocks::COPPER_DOOR()->setOxidation($oxidation)->setWaxed($waxed)); + $register("copper_trapdoor", fn() => Blocks::COPPER_TRAPDOOR()->setOxidation($oxidation)->setWaxed($waxed)); } } diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index de38903bd..0ead377ba 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -10,6 +10,16 @@ parameters: count: 1 path: ../../../src/block/DoubleTallGrass.php + - + message: "#^Method pocketmine\\\\block\\\\CopperDoor\\:\\:onInteractCopper\\(\\) has parameter \\$returnedItems with no value type specified in iterable type array\\.$#" + count: 1 + path: ../../../src/block/utils/CopperTrait.php + + - + message: "#^Method pocketmine\\\\block\\\\CopperTrapdoor\\:\\:onInteractCopper\\(\\) has parameter \\$returnedItems with no value type specified in iterable type array\\.$#" + count: 1 + path: ../../../src/block/utils/CopperTrait.php + - message: "#^Call to function assert\\(\\) with false and 'unknown hit type' will always evaluate to false\\.$#" count: 1 diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 97c24b52e..79804d8cb 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -105,6 +105,7 @@ "CHERRY_WOOD": 6, "CHEST": 4, "CHISELED_BOOKSHELF": 256, + "CHISELED_COPPER": 8, "CHISELED_DEEPSLATE": 1, "CHISELED_NETHER_BRICKS": 1, "CHISELED_POLISHED_BLACKSTONE": 1, @@ -133,7 +134,11 @@ "CONCRETE": 16, "CONCRETE_POWDER": 16, "COPPER": 8, + "COPPER_BULB": 32, + "COPPER_DOOR": 256, + "COPPER_GRATE": 8, "COPPER_ORE": 1, + "COPPER_TRAPDOOR": 128, "CORAL": 10, "CORAL_BLOCK": 10, "CORAL_FAN": 20,