mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-08-26 13:09:05 +00:00
Merge remote-tracking branch 'origin/minor-next' into major-next
This commit is contained in:
commit
e8eda19ae5
@ -50,6 +50,10 @@ abstract class BaseBanner extends Transparent implements Colored{
|
||||
parent::readStateFromWorld();
|
||||
$tile = $this->position->getWorld()->getTile($this->position);
|
||||
if($tile instanceof TileBanner){
|
||||
if($tile->getType() === TileBanner::TYPE_OMINOUS){
|
||||
//illager banner is implemented as a separate block, as it doesn't support base color or custom patterns
|
||||
return $this->getOminousVersion();
|
||||
}
|
||||
$this->color = $tile->getBaseColor();
|
||||
$this->setPatterns($tile->getPatterns());
|
||||
}
|
||||
@ -57,6 +61,8 @@ abstract class BaseBanner extends Transparent implements Colored{
|
||||
return $this;
|
||||
}
|
||||
|
||||
abstract protected function getOminousVersion() : Block;
|
||||
|
||||
public function writeStateToWorld() : void{
|
||||
parent::writeStateToWorld();
|
||||
$tile = $this->position->getWorld()->getTile($this->position);
|
||||
|
90
src/block/BaseOminousBanner.php
Normal file
90
src/block/BaseOminousBanner.php
Normal file
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\tile\Banner as TileBanner;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
use function assert;
|
||||
|
||||
abstract class BaseOminousBanner extends Transparent{
|
||||
|
||||
public function writeStateToWorld() : void{
|
||||
parent::writeStateToWorld();
|
||||
$tile = $this->position->getWorld()->getTile($this->position);
|
||||
assert($tile instanceof TileBanner);
|
||||
$tile->setBaseColor(DyeColor::WHITE);
|
||||
$tile->setPatterns([]);
|
||||
$tile->setType(TileBanner::TYPE_OMINOUS);
|
||||
}
|
||||
|
||||
public function isSolid() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getMaxStackSize() : int{
|
||||
return 16;
|
||||
}
|
||||
|
||||
public function getFuelTime() : int{
|
||||
return 300;
|
||||
}
|
||||
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
return SupportType::NONE;
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return $block->isSolid();
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(!$this->canBeSupportedBy($blockReplace->getSide($this->getSupportingFace()))){
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
abstract protected function getSupportingFace() : int;
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->canBeSupportedBy($this->getSide($this->getSupportingFace()))){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
public function asItem() : Item{
|
||||
return VanillaItems::OMINOUS_BANNER();
|
||||
}
|
||||
}
|
@ -103,10 +103,27 @@ abstract class BaseSign extends Transparent implements WoodMaterial{
|
||||
return SupportType::NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
abstract protected function getSupportingFace() : int;
|
||||
|
||||
/**
|
||||
* @return int[]
|
||||
*/
|
||||
protected function getSupportingFaceOptions() : array{
|
||||
return [$this->getSupportingFace()];
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide($this->getSupportingFace())->getTypeId() === BlockTypeIds::AIR){
|
||||
$foundSupport = false;
|
||||
foreach($this->getSupportingFaceOptions() as $face){
|
||||
if($this->getSide($face)->getTypeId() !== BlockTypeIds::AIR){
|
||||
$foundSupport = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!$foundSupport){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
@ -787,8 +787,43 @@ final class BlockTypeIds{
|
||||
public const RESIN_CLUMP = 10757;
|
||||
public const CHISELED_RESIN_BRICKS = 10758;
|
||||
public const RESPAWN_ANCHOR = 10759;
|
||||
public const OMINOUS_BANNER = 10760;
|
||||
public const OMINOUS_WALL_BANNER = 10761;
|
||||
public const ACACIA_CEILING_CENTER_HANGING_SIGN = 10762;
|
||||
public const ACACIA_CEILING_EDGES_HANGING_SIGN = 10763;
|
||||
public const ACACIA_WALL_HANGING_SIGN = 10764;
|
||||
public const BIRCH_CEILING_CENTER_HANGING_SIGN = 10765;
|
||||
public const BIRCH_CEILING_EDGES_HANGING_SIGN = 10766;
|
||||
public const BIRCH_WALL_HANGING_SIGN = 10767;
|
||||
public const CHERRY_CEILING_CENTER_HANGING_SIGN = 10768;
|
||||
public const CHERRY_CEILING_EDGES_HANGING_SIGN = 10769;
|
||||
public const CHERRY_WALL_HANGING_SIGN = 10770;
|
||||
public const CRIMSON_CEILING_CENTER_HANGING_SIGN = 10771;
|
||||
public const CRIMSON_CEILING_EDGES_HANGING_SIGN = 10772;
|
||||
public const CRIMSON_WALL_HANGING_SIGN = 10773;
|
||||
public const DARK_OAK_CEILING_CENTER_HANGING_SIGN = 10774;
|
||||
public const DARK_OAK_CEILING_EDGES_HANGING_SIGN = 10775;
|
||||
public const DARK_OAK_WALL_HANGING_SIGN = 10776;
|
||||
public const JUNGLE_CEILING_CENTER_HANGING_SIGN = 10777;
|
||||
public const JUNGLE_CEILING_EDGES_HANGING_SIGN = 10778;
|
||||
public const JUNGLE_WALL_HANGING_SIGN = 10779;
|
||||
public const MANGROVE_CEILING_CENTER_HANGING_SIGN = 10780;
|
||||
public const MANGROVE_CEILING_EDGES_HANGING_SIGN = 10781;
|
||||
public const MANGROVE_WALL_HANGING_SIGN = 10782;
|
||||
public const OAK_CEILING_CENTER_HANGING_SIGN = 10783;
|
||||
public const OAK_CEILING_EDGES_HANGING_SIGN = 10784;
|
||||
public const OAK_WALL_HANGING_SIGN = 10785;
|
||||
public const PALE_OAK_CEILING_CENTER_HANGING_SIGN = 10786;
|
||||
public const PALE_OAK_CEILING_EDGES_HANGING_SIGN = 10787;
|
||||
public const PALE_OAK_WALL_HANGING_SIGN = 10788;
|
||||
public const SPRUCE_CEILING_CENTER_HANGING_SIGN = 10789;
|
||||
public const SPRUCE_CEILING_EDGES_HANGING_SIGN = 10790;
|
||||
public const SPRUCE_WALL_HANGING_SIGN = 10791;
|
||||
public const WARPED_CEILING_CENTER_HANGING_SIGN = 10792;
|
||||
public const WARPED_CEILING_EDGES_HANGING_SIGN = 10793;
|
||||
public const WARPED_WALL_HANGING_SIGN = 10794;
|
||||
|
||||
public const FIRST_UNUSED_BLOCK_ID = 10760;
|
||||
public const FIRST_UNUSED_BLOCK_ID = 10795;
|
||||
|
||||
private static int $nextDynamicId = self::FIRST_UNUSED_BLOCK_ID;
|
||||
|
||||
|
52
src/block/CeilingCenterHangingSign.php
Normal file
52
src/block/CeilingCenterHangingSign.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\SignLikeRotation;
|
||||
use pocketmine\block\utils\SignLikeRotationTrait;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
|
||||
final class CeilingCenterHangingSign extends BaseSign implements SignLikeRotation{
|
||||
use SignLikeRotationTrait;
|
||||
|
||||
protected function getSupportingFace() : int{
|
||||
return Facing::UP;
|
||||
}
|
||||
|
||||
//TODO: duplicated code :(
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($face !== Facing::DOWN){
|
||||
return false;
|
||||
}
|
||||
|
||||
if($player !== null){
|
||||
$this->rotation = self::getRotationFromYaw($player->getLocation()->getYaw());
|
||||
}
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
}
|
51
src/block/CeilingEdgesHangingSign.php
Normal file
51
src/block/CeilingEdgesHangingSign.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\HorizontalFacing;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
|
||||
final class CeilingEdgesHangingSign extends BaseSign implements HorizontalFacing{
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
protected function getSupportingFace() : int{
|
||||
return Facing::UP;
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($face !== Facing::DOWN){
|
||||
return false;
|
||||
}
|
||||
if($player !== null){
|
||||
$this->facing = Facing::opposite($player->getHorizontalFacing());
|
||||
}
|
||||
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
}
|
@ -34,6 +34,10 @@ use pocketmine\world\BlockTransaction;
|
||||
final class FloorBanner extends BaseBanner implements SignLikeRotation{
|
||||
use SignLikeRotationTrait;
|
||||
|
||||
protected function getOminousVersion() : Block{
|
||||
return VanillaBlocks::OMINOUS_BANNER()->setRotation($this->rotation);
|
||||
}
|
||||
|
||||
protected function getSupportingFace() : int{
|
||||
return Facing::DOWN;
|
||||
}
|
||||
|
53
src/block/OminousFloorBanner.php
Normal file
53
src/block/OminousFloorBanner.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\SignLikeRotation;
|
||||
use pocketmine\block\utils\SignLikeRotationTrait;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
|
||||
final class OminousFloorBanner extends BaseOminousBanner implements SignLikeRotation{
|
||||
use SignLikeRotationTrait;
|
||||
|
||||
//TODO: duplicated code :(
|
||||
|
||||
protected function getSupportingFace() : int{
|
||||
return Facing::DOWN;
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($face !== Facing::UP){
|
||||
return false;
|
||||
}
|
||||
|
||||
if($player !== null){
|
||||
$this->rotation = self::getRotationFromYaw($player->getLocation()->getYaw());
|
||||
}
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
}
|
49
src/block/OminousWallBanner.php
Normal file
49
src/block/OminousWallBanner.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\HorizontalFacing;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
|
||||
final class OminousWallBanner extends BaseOminousBanner implements HorizontalFacing{
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
protected function getSupportingFace() : int{
|
||||
return Facing::opposite($this->facing);
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(Facing::axis($face) === Axis::Y){
|
||||
return false;
|
||||
}
|
||||
$this->facing = $face;
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
}
|
@ -45,6 +45,7 @@ use pocketmine\block\tile\EnchantTable as TileEnchantingTable;
|
||||
use pocketmine\block\tile\EnderChest as TileEnderChest;
|
||||
use pocketmine\block\tile\FlowerPot as TileFlowerPot;
|
||||
use pocketmine\block\tile\GlowingItemFrame as TileGlowingItemFrame;
|
||||
use pocketmine\block\tile\HangingSign as TileHangingSign;
|
||||
use pocketmine\block\tile\Hopper as TileHopper;
|
||||
use pocketmine\block\tile\ItemFrame as TileItemFrame;
|
||||
use pocketmine\block\tile\Jukebox as TileJukebox;
|
||||
@ -80,6 +81,8 @@ use function strtolower;
|
||||
* @generate-registry-docblock
|
||||
*
|
||||
* @method static WoodenButton ACACIA_BUTTON()
|
||||
* @method static CeilingCenterHangingSign ACACIA_CEILING_CENTER_HANGING_SIGN()
|
||||
* @method static CeilingEdgesHangingSign ACACIA_CEILING_EDGES_HANGING_SIGN()
|
||||
* @method static WoodenDoor ACACIA_DOOR()
|
||||
* @method static WoodenFence ACACIA_FENCE()
|
||||
* @method static FenceGate ACACIA_FENCE_GATE()
|
||||
@ -92,6 +95,7 @@ use function strtolower;
|
||||
* @method static WoodenSlab ACACIA_SLAB()
|
||||
* @method static WoodenStairs ACACIA_STAIRS()
|
||||
* @method static WoodenTrapdoor ACACIA_TRAPDOOR()
|
||||
* @method static WallHangingSign ACACIA_WALL_HANGING_SIGN()
|
||||
* @method static WallSign ACACIA_WALL_SIGN()
|
||||
* @method static Wood ACACIA_WOOD()
|
||||
* @method static ActivatorRail ACTIVATOR_RAIL()
|
||||
@ -122,6 +126,8 @@ use function strtolower;
|
||||
* @method static BigDripleafHead BIG_DRIPLEAF_HEAD()
|
||||
* @method static BigDripleafStem BIG_DRIPLEAF_STEM()
|
||||
* @method static WoodenButton BIRCH_BUTTON()
|
||||
* @method static CeilingCenterHangingSign BIRCH_CEILING_CENTER_HANGING_SIGN()
|
||||
* @method static CeilingEdgesHangingSign BIRCH_CEILING_EDGES_HANGING_SIGN()
|
||||
* @method static WoodenDoor BIRCH_DOOR()
|
||||
* @method static WoodenFence BIRCH_FENCE()
|
||||
* @method static FenceGate BIRCH_FENCE_GATE()
|
||||
@ -134,6 +140,7 @@ use function strtolower;
|
||||
* @method static WoodenSlab BIRCH_SLAB()
|
||||
* @method static WoodenStairs BIRCH_STAIRS()
|
||||
* @method static WoodenTrapdoor BIRCH_TRAPDOOR()
|
||||
* @method static WallHangingSign BIRCH_WALL_HANGING_SIGN()
|
||||
* @method static WallSign BIRCH_WALL_SIGN()
|
||||
* @method static Wood BIRCH_WOOD()
|
||||
* @method static Opaque BLACKSTONE()
|
||||
@ -170,6 +177,8 @@ use function strtolower;
|
||||
* @method static Chain CHAIN()
|
||||
* @method static ChemicalHeat CHEMICAL_HEAT()
|
||||
* @method static WoodenButton CHERRY_BUTTON()
|
||||
* @method static CeilingCenterHangingSign CHERRY_CEILING_CENTER_HANGING_SIGN()
|
||||
* @method static CeilingEdgesHangingSign CHERRY_CEILING_EDGES_HANGING_SIGN()
|
||||
* @method static WoodenDoor CHERRY_DOOR()
|
||||
* @method static WoodenFence CHERRY_FENCE()
|
||||
* @method static FenceGate CHERRY_FENCE_GATE()
|
||||
@ -181,6 +190,7 @@ use function strtolower;
|
||||
* @method static WoodenSlab CHERRY_SLAB()
|
||||
* @method static WoodenStairs CHERRY_STAIRS()
|
||||
* @method static WoodenTrapdoor CHERRY_TRAPDOOR()
|
||||
* @method static WallHangingSign CHERRY_WALL_HANGING_SIGN()
|
||||
* @method static WallSign CHERRY_WALL_SIGN()
|
||||
* @method static Wood CHERRY_WOOD()
|
||||
* @method static Chest CHEST()
|
||||
@ -231,6 +241,8 @@ use function strtolower;
|
||||
* @method static Opaque CRACKED_STONE_BRICKS()
|
||||
* @method static CraftingTable CRAFTING_TABLE()
|
||||
* @method static WoodenButton CRIMSON_BUTTON()
|
||||
* @method static CeilingCenterHangingSign CRIMSON_CEILING_CENTER_HANGING_SIGN()
|
||||
* @method static CeilingEdgesHangingSign CRIMSON_CEILING_EDGES_HANGING_SIGN()
|
||||
* @method static WoodenDoor CRIMSON_DOOR()
|
||||
* @method static WoodenFence CRIMSON_FENCE()
|
||||
* @method static FenceGate CRIMSON_FENCE_GATE()
|
||||
@ -243,6 +255,7 @@ use function strtolower;
|
||||
* @method static WoodenStairs CRIMSON_STAIRS()
|
||||
* @method static Wood CRIMSON_STEM()
|
||||
* @method static WoodenTrapdoor CRIMSON_TRAPDOOR()
|
||||
* @method static WallHangingSign CRIMSON_WALL_HANGING_SIGN()
|
||||
* @method static WallSign CRIMSON_WALL_SIGN()
|
||||
* @method static Opaque CRYING_OBSIDIAN()
|
||||
* @method static Copper CUT_COPPER()
|
||||
@ -254,6 +267,8 @@ use function strtolower;
|
||||
* @method static Slab CUT_SANDSTONE_SLAB()
|
||||
* @method static Flower DANDELION()
|
||||
* @method static WoodenButton DARK_OAK_BUTTON()
|
||||
* @method static CeilingCenterHangingSign DARK_OAK_CEILING_CENTER_HANGING_SIGN()
|
||||
* @method static CeilingEdgesHangingSign DARK_OAK_CEILING_EDGES_HANGING_SIGN()
|
||||
* @method static WoodenDoor DARK_OAK_DOOR()
|
||||
* @method static WoodenFence DARK_OAK_FENCE()
|
||||
* @method static FenceGate DARK_OAK_FENCE_GATE()
|
||||
@ -266,6 +281,7 @@ use function strtolower;
|
||||
* @method static WoodenSlab DARK_OAK_SLAB()
|
||||
* @method static WoodenStairs DARK_OAK_STAIRS()
|
||||
* @method static WoodenTrapdoor DARK_OAK_TRAPDOOR()
|
||||
* @method static WallHangingSign DARK_OAK_WALL_HANGING_SIGN()
|
||||
* @method static WallSign DARK_OAK_WALL_SIGN()
|
||||
* @method static Wood DARK_OAK_WOOD()
|
||||
* @method static Opaque DARK_PRISMARINE()
|
||||
@ -488,6 +504,8 @@ use function strtolower;
|
||||
* @method static ItemFrame ITEM_FRAME()
|
||||
* @method static Jukebox JUKEBOX()
|
||||
* @method static WoodenButton JUNGLE_BUTTON()
|
||||
* @method static CeilingCenterHangingSign JUNGLE_CEILING_CENTER_HANGING_SIGN()
|
||||
* @method static CeilingEdgesHangingSign JUNGLE_CEILING_EDGES_HANGING_SIGN()
|
||||
* @method static WoodenDoor JUNGLE_DOOR()
|
||||
* @method static WoodenFence JUNGLE_FENCE()
|
||||
* @method static FenceGate JUNGLE_FENCE_GATE()
|
||||
@ -500,6 +518,7 @@ use function strtolower;
|
||||
* @method static WoodenSlab JUNGLE_SLAB()
|
||||
* @method static WoodenStairs JUNGLE_STAIRS()
|
||||
* @method static WoodenTrapdoor JUNGLE_TRAPDOOR()
|
||||
* @method static WallHangingSign JUNGLE_WALL_HANGING_SIGN()
|
||||
* @method static WallSign JUNGLE_WALL_SIGN()
|
||||
* @method static Wood JUNGLE_WOOD()
|
||||
* @method static ChemistryTable LAB_TABLE()
|
||||
@ -522,6 +541,8 @@ use function strtolower;
|
||||
* @method static Loom LOOM()
|
||||
* @method static Magma MAGMA()
|
||||
* @method static WoodenButton MANGROVE_BUTTON()
|
||||
* @method static CeilingCenterHangingSign MANGROVE_CEILING_CENTER_HANGING_SIGN()
|
||||
* @method static CeilingEdgesHangingSign MANGROVE_CEILING_EDGES_HANGING_SIGN()
|
||||
* @method static WoodenDoor MANGROVE_DOOR()
|
||||
* @method static WoodenFence MANGROVE_FENCE()
|
||||
* @method static FenceGate MANGROVE_FENCE_GATE()
|
||||
@ -534,6 +555,7 @@ use function strtolower;
|
||||
* @method static WoodenSlab MANGROVE_SLAB()
|
||||
* @method static WoodenStairs MANGROVE_STAIRS()
|
||||
* @method static WoodenTrapdoor MANGROVE_TRAPDOOR()
|
||||
* @method static WallHangingSign MANGROVE_WALL_HANGING_SIGN()
|
||||
* @method static WallSign MANGROVE_WALL_SIGN()
|
||||
* @method static Wood MANGROVE_WOOD()
|
||||
* @method static ChemistryTable MATERIAL_REDUCER()
|
||||
@ -572,6 +594,8 @@ use function strtolower;
|
||||
* @method static Opaque NETHER_WART_BLOCK()
|
||||
* @method static Note NOTE_BLOCK()
|
||||
* @method static WoodenButton OAK_BUTTON()
|
||||
* @method static CeilingCenterHangingSign OAK_CEILING_CENTER_HANGING_SIGN()
|
||||
* @method static CeilingEdgesHangingSign OAK_CEILING_EDGES_HANGING_SIGN()
|
||||
* @method static WoodenDoor OAK_DOOR()
|
||||
* @method static WoodenFence OAK_FENCE()
|
||||
* @method static FenceGate OAK_FENCE_GATE()
|
||||
@ -584,14 +608,19 @@ use function strtolower;
|
||||
* @method static WoodenSlab OAK_SLAB()
|
||||
* @method static WoodenStairs OAK_STAIRS()
|
||||
* @method static WoodenTrapdoor OAK_TRAPDOOR()
|
||||
* @method static WallHangingSign OAK_WALL_HANGING_SIGN()
|
||||
* @method static WallSign OAK_WALL_SIGN()
|
||||
* @method static Wood OAK_WOOD()
|
||||
* @method static Opaque OBSIDIAN()
|
||||
* @method static OminousFloorBanner OMINOUS_BANNER()
|
||||
* @method static OminousWallBanner OMINOUS_WALL_BANNER()
|
||||
* @method static Flower ORANGE_TULIP()
|
||||
* @method static Flower OXEYE_DAISY()
|
||||
* @method static PackedIce PACKED_ICE()
|
||||
* @method static Opaque PACKED_MUD()
|
||||
* @method static WoodenButton PALE_OAK_BUTTON()
|
||||
* @method static CeilingCenterHangingSign PALE_OAK_CEILING_CENTER_HANGING_SIGN()
|
||||
* @method static CeilingEdgesHangingSign PALE_OAK_CEILING_EDGES_HANGING_SIGN()
|
||||
* @method static WoodenDoor PALE_OAK_DOOR()
|
||||
* @method static WoodenFence PALE_OAK_FENCE()
|
||||
* @method static FenceGate PALE_OAK_FENCE_GATE()
|
||||
@ -603,6 +632,7 @@ use function strtolower;
|
||||
* @method static WoodenSlab PALE_OAK_SLAB()
|
||||
* @method static WoodenStairs PALE_OAK_STAIRS()
|
||||
* @method static WoodenTrapdoor PALE_OAK_TRAPDOOR()
|
||||
* @method static WallHangingSign PALE_OAK_WALL_HANGING_SIGN()
|
||||
* @method static WallSign PALE_OAK_WALL_SIGN()
|
||||
* @method static Wood PALE_OAK_WOOD()
|
||||
* @method static DoublePlant PEONY()
|
||||
@ -733,6 +763,8 @@ use function strtolower;
|
||||
* @method static Sponge SPONGE()
|
||||
* @method static SporeBlossom SPORE_BLOSSOM()
|
||||
* @method static WoodenButton SPRUCE_BUTTON()
|
||||
* @method static CeilingCenterHangingSign SPRUCE_CEILING_CENTER_HANGING_SIGN()
|
||||
* @method static CeilingEdgesHangingSign SPRUCE_CEILING_EDGES_HANGING_SIGN()
|
||||
* @method static WoodenDoor SPRUCE_DOOR()
|
||||
* @method static WoodenFence SPRUCE_FENCE()
|
||||
* @method static FenceGate SPRUCE_FENCE_GATE()
|
||||
@ -745,6 +777,7 @@ use function strtolower;
|
||||
* @method static WoodenSlab SPRUCE_SLAB()
|
||||
* @method static WoodenStairs SPRUCE_STAIRS()
|
||||
* @method static WoodenTrapdoor SPRUCE_TRAPDOOR()
|
||||
* @method static WallHangingSign SPRUCE_WALL_HANGING_SIGN()
|
||||
* @method static WallSign SPRUCE_WALL_SIGN()
|
||||
* @method static Wood SPRUCE_WOOD()
|
||||
* @method static StainedHardenedClay STAINED_CLAY()
|
||||
@ -788,6 +821,8 @@ use function strtolower;
|
||||
* @method static WallBanner WALL_BANNER()
|
||||
* @method static WallCoralFan WALL_CORAL_FAN()
|
||||
* @method static WoodenButton WARPED_BUTTON()
|
||||
* @method static CeilingCenterHangingSign WARPED_CEILING_CENTER_HANGING_SIGN()
|
||||
* @method static CeilingEdgesHangingSign WARPED_CEILING_EDGES_HANGING_SIGN()
|
||||
* @method static WoodenDoor WARPED_DOOR()
|
||||
* @method static WoodenFence WARPED_FENCE()
|
||||
* @method static FenceGate WARPED_FENCE_GATE()
|
||||
@ -800,6 +835,7 @@ use function strtolower;
|
||||
* @method static WoodenStairs WARPED_STAIRS()
|
||||
* @method static Wood WARPED_STEM()
|
||||
* @method static WoodenTrapdoor WARPED_TRAPDOOR()
|
||||
* @method static WallHangingSign WARPED_WALL_HANGING_SIGN()
|
||||
* @method static WallSign WARPED_WALL_SIGN()
|
||||
* @method static Opaque WARPED_WART_BLOCK()
|
||||
* @method static Water WATER()
|
||||
@ -873,6 +909,8 @@ final class VanillaBlocks{
|
||||
$bannerBreakInfo = new Info(BreakInfo::axe(1.0));
|
||||
self::register("banner", fn(BID $id) => new FloorBanner($id, "Banner", $bannerBreakInfo), TileBanner::class);
|
||||
self::register("wall_banner", fn(BID $id) => new WallBanner($id, "Wall Banner", $bannerBreakInfo), TileBanner::class);
|
||||
self::register("ominous_banner", fn(BID $id) => new OminousFloorBanner($id, "Ominous Banner", $bannerBreakInfo), TileBanner::class);
|
||||
self::register("ominous_wall_banner", fn(BID $id) => new OminousWallBanner($id, "Ominous Wall Banner", $bannerBreakInfo), TileBanner::class);
|
||||
self::register("barrel", fn(BID $id) => new Barrel($id, "Barrel", new Info(BreakInfo::axe(2.5))), TileBarrel::class);
|
||||
self::register("barrier", fn(BID $id) => new Transparent($id, "Barrier", new Info(BreakInfo::indestructible())));
|
||||
self::register("beacon", fn(BID $id) => new Beacon($id, "Beacon", new Info(new BreakInfo(3.0))), TileBeacon::class);
|
||||
@ -1392,6 +1430,23 @@ final class VanillaBlocks{
|
||||
};
|
||||
self::register($idName("sign"), fn(BID $id) => new FloorSign($id, $name . " Sign", $signBreakInfo, $woodType, $signAsItem), TileSign::class);
|
||||
self::register($idName("wall_sign"), fn(BID $id) => new WallSign($id, $name . " Wall Sign", $signBreakInfo, $woodType, $signAsItem), TileSign::class);
|
||||
|
||||
$hangingSignAsItem = match($woodType){
|
||||
WoodType::OAK => VanillaItems::OAK_HANGING_SIGN(...),
|
||||
WoodType::SPRUCE => VanillaItems::SPRUCE_HANGING_SIGN(...),
|
||||
WoodType::BIRCH => VanillaItems::BIRCH_HANGING_SIGN(...),
|
||||
WoodType::JUNGLE => VanillaItems::JUNGLE_HANGING_SIGN(...),
|
||||
WoodType::ACACIA => VanillaItems::ACACIA_HANGING_SIGN(...),
|
||||
WoodType::DARK_OAK => VanillaItems::DARK_OAK_HANGING_SIGN(...),
|
||||
WoodType::MANGROVE => VanillaItems::MANGROVE_HANGING_SIGN(...),
|
||||
WoodType::CRIMSON => VanillaItems::CRIMSON_HANGING_SIGN(...),
|
||||
WoodType::WARPED => VanillaItems::WARPED_HANGING_SIGN(...),
|
||||
WoodType::CHERRY => VanillaItems::CHERRY_HANGING_SIGN(...),
|
||||
WoodType::PALE_OAK => VanillaItems::PALE_OAK_HANGING_SIGN(...),
|
||||
};
|
||||
self::register($idName("ceiling_center_hanging_sign"), fn(BID $id) => new CeilingCenterHangingSign($id, $name . "Center Hanging Sign", $signBreakInfo, $woodType, $hangingSignAsItem), TileHangingSign::class);
|
||||
self::register($idName("ceiling_edges_hanging_sign"), fn(BID $id) => new CeilingEdgesHangingSign($id, $name . "Edges Hanging Sign", $signBreakInfo, $woodType, $hangingSignAsItem), TileHangingSign::class);
|
||||
self::register($idName("wall_hanging_sign"), fn(BID $id) => new WallHangingSign($id, $name . " Wall Hanging Sign", $signBreakInfo, $woodType, $hangingSignAsItem), TileHangingSign::class);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,10 @@ use pocketmine\world\BlockTransaction;
|
||||
final class WallBanner extends BaseBanner implements HorizontalFacing{
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
protected function getOminousVersion() : Block{
|
||||
return VanillaBlocks::OMINOUS_WALL_BANNER()->setFacing($this->facing);
|
||||
}
|
||||
|
||||
protected function getSupportingFace() : int{
|
||||
return Facing::opposite($this->facing);
|
||||
}
|
||||
|
63
src/block/WallHangingSign.php
Normal file
63
src/block/WallHangingSign.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\HorizontalFacing;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
|
||||
final class WallHangingSign extends BaseSign implements HorizontalFacing{
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
protected function getSupportingFace() : int{
|
||||
return Facing::rotateY($this->facing, clockwise: true);
|
||||
}
|
||||
|
||||
protected function getSupportingFaceOptions() : array{
|
||||
//wall hanging signs can be supported from either end of the post
|
||||
return [
|
||||
Facing::rotateY($this->facing, clockwise: true),
|
||||
Facing::rotateY($this->facing, clockwise: false)
|
||||
];
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(Facing::axis($face) === Axis::Y){
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->facing = Facing::rotateY($face, clockwise: true);
|
||||
//the front should always face the player if possible
|
||||
if($player !== null && $this->facing === $player->getHorizontalFacing()){
|
||||
$this->facing = Facing::opposite($this->facing);
|
||||
}
|
||||
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
}
|
@ -41,6 +41,10 @@ class Banner extends Spawnable{
|
||||
public const TAG_PATTERNS = "Patterns";
|
||||
public const TAG_PATTERN_COLOR = "Color";
|
||||
public const TAG_PATTERN_NAME = "Pattern";
|
||||
public const TAG_TYPE = "Type";
|
||||
|
||||
public const TYPE_NORMAL = 0;
|
||||
public const TYPE_OMINOUS = 1;
|
||||
|
||||
private DyeColor $baseColor = DyeColor::BLACK;
|
||||
|
||||
@ -50,6 +54,8 @@ class Banner extends Spawnable{
|
||||
*/
|
||||
private array $patterns = [];
|
||||
|
||||
private int $type = self::TYPE_NORMAL;
|
||||
|
||||
public function readSaveData(CompoundTag $nbt) : void{
|
||||
$colorIdMap = DyeColorIdMap::getInstance();
|
||||
if(
|
||||
@ -75,6 +81,8 @@ class Banner extends Spawnable{
|
||||
$this->patterns[] = new BannerPatternLayer($patternType, $patternColor);
|
||||
}
|
||||
}
|
||||
|
||||
$this->type = $nbt->getInt(self::TAG_TYPE);
|
||||
}
|
||||
|
||||
protected function writeSaveData(CompoundTag $nbt) : void{
|
||||
@ -89,6 +97,7 @@ class Banner extends Spawnable{
|
||||
);
|
||||
}
|
||||
$nbt->setTag(self::TAG_PATTERNS, $patterns);
|
||||
$nbt->setInt(self::TAG_TYPE, $this->type);
|
||||
}
|
||||
|
||||
protected function addAdditionalSpawnData(CompoundTag $nbt) : void{
|
||||
@ -103,6 +112,7 @@ class Banner extends Spawnable{
|
||||
);
|
||||
}
|
||||
$nbt->setTag(self::TAG_PATTERNS, $patterns);
|
||||
$nbt->setInt(self::TAG_TYPE, $this->type);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -136,6 +146,10 @@ class Banner extends Spawnable{
|
||||
$this->patterns = $patterns;
|
||||
}
|
||||
|
||||
public function getType() : int{ return $this->type; }
|
||||
|
||||
public function setType(int $type) : void{ $this->type = $type; }
|
||||
|
||||
public function getDefaultName() : string{
|
||||
return "Banner";
|
||||
}
|
||||
|
31
src/block/tile/HangingSign.php
Normal file
31
src/block/tile/HangingSign.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block\tile;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
final class HangingSign extends Sign{
|
||||
|
||||
}
|
@ -79,6 +79,7 @@ final class TileFactory{
|
||||
$this->register(SporeBlossom::class, ["SporeBlossom", "minecraft:spore_blossom"]);
|
||||
$this->register(MobHead::class, ["Skull", "minecraft:skull"]);
|
||||
$this->register(GlowingItemFrame::class, ["GlowItemFrame"]);
|
||||
$this->register(HangingSign::class, ["HangingSign", "minecraft:hanging_sign"]);
|
||||
|
||||
//TODO: ChalkboardBlock
|
||||
//TODO: ChemistryTable
|
||||
|
@ -24,29 +24,21 @@ declare(strict_types=1);
|
||||
namespace pocketmine\data\bedrock;
|
||||
|
||||
use pocketmine\block\utils\MushroomBlockType;
|
||||
use pocketmine\data\bedrock\block\BlockLegacyMetadata as LegacyMeta;
|
||||
use pocketmine\data\bedrock\block\convert\property\ValueMappings;
|
||||
use pocketmine\utils\SingletonTrait;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
final class MushroomBlockTypeIdMap{
|
||||
use SingletonTrait;
|
||||
/** @phpstan-use IntSaveIdMapTrait<MushroomBlockType> */
|
||||
use IntSaveIdMapTrait;
|
||||
|
||||
public function __construct(){
|
||||
$newMapping = ValueMappings::getInstance()->mushroomBlockType;
|
||||
foreach(MushroomBlockType::cases() as $case){
|
||||
$this->register(match($case){
|
||||
MushroomBlockType::PORES => LegacyMeta::MUSHROOM_BLOCK_ALL_PORES,
|
||||
MushroomBlockType::CAP_NORTHWEST => LegacyMeta::MUSHROOM_BLOCK_CAP_NORTHWEST_CORNER,
|
||||
MushroomBlockType::CAP_NORTH => LegacyMeta::MUSHROOM_BLOCK_CAP_NORTH_SIDE,
|
||||
MushroomBlockType::CAP_NORTHEAST => LegacyMeta::MUSHROOM_BLOCK_CAP_NORTHEAST_CORNER,
|
||||
MushroomBlockType::CAP_WEST => LegacyMeta::MUSHROOM_BLOCK_CAP_WEST_SIDE,
|
||||
MushroomBlockType::CAP_MIDDLE => LegacyMeta::MUSHROOM_BLOCK_CAP_TOP_ONLY,
|
||||
MushroomBlockType::CAP_EAST => LegacyMeta::MUSHROOM_BLOCK_CAP_EAST_SIDE,
|
||||
MushroomBlockType::CAP_SOUTHWEST => LegacyMeta::MUSHROOM_BLOCK_CAP_SOUTHWEST_CORNER,
|
||||
MushroomBlockType::CAP_SOUTH => LegacyMeta::MUSHROOM_BLOCK_CAP_SOUTH_SIDE,
|
||||
MushroomBlockType::CAP_SOUTHEAST => LegacyMeta::MUSHROOM_BLOCK_CAP_SOUTHEAST_CORNER,
|
||||
MushroomBlockType::ALL_CAP => LegacyMeta::MUSHROOM_BLOCK_ALL_CAP,
|
||||
}, $case);
|
||||
$this->register($newMapping->valueToRaw($case), $case);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,8 @@ final class BlockLegacyMetadata{
|
||||
public const CORAL_VARIANT_FIRE = 3;
|
||||
public const CORAL_VARIANT_HORN = 4;
|
||||
|
||||
public const LIQUID_FALLING_FLAG = 0x08;
|
||||
|
||||
public const MULTI_FACE_DIRECTION_FLAG_DOWN = 0x01;
|
||||
public const MULTI_FACE_DIRECTION_FLAG_UP = 0x02;
|
||||
public const MULTI_FACE_DIRECTION_FLAG_SOUTH = 0x04;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,237 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\block\convert;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\Slab;
|
||||
use pocketmine\block\Stair;
|
||||
use pocketmine\block\utils\Colored;
|
||||
use pocketmine\data\bedrock\block\BlockStateData;
|
||||
use pocketmine\data\bedrock\block\convert\BlockStateReader as Reader;
|
||||
use pocketmine\data\bedrock\block\convert\BlockStateWriter as Writer;
|
||||
use pocketmine\data\bedrock\block\convert\property\CommonProperties;
|
||||
use pocketmine\data\bedrock\block\convert\property\StringProperty;
|
||||
use function array_map;
|
||||
use function count;
|
||||
use function implode;
|
||||
use function is_string;
|
||||
|
||||
/**
|
||||
* Registers serializers and deserializers for block data in a unified style, to avoid code duplication.
|
||||
* Not all blocks can be registered this way, but we can avoid a lot of repetition for the ones that can.
|
||||
*/
|
||||
final class BlockSerializerDeserializerRegistrar{
|
||||
|
||||
public function __construct(
|
||||
public readonly BlockStateToObjectDeserializer $deserializer,
|
||||
public readonly BlockObjectToStateSerializer $serializer
|
||||
){}
|
||||
|
||||
/**
|
||||
* @param string[]|StringProperty[] $components
|
||||
*
|
||||
* @phpstan-param list<string|StringProperty<*>> $components
|
||||
*
|
||||
* @return string[][]
|
||||
* @phpstan-return list<list<string>>
|
||||
*/
|
||||
private static function compileFlattenedIdPartMatrix(array $components) : array{
|
||||
$result = [];
|
||||
foreach($components as $component){
|
||||
$column = is_string($component) ? [$component] : $component->getPossibleValues();
|
||||
|
||||
if(count($result) === 0){
|
||||
$result = array_map(fn($value) => [$value], $column);
|
||||
}else{
|
||||
$stepResult = [];
|
||||
foreach($result as $parts){
|
||||
foreach($column as $value){
|
||||
$stepPart = $parts;
|
||||
$stepPart[] = $value;
|
||||
$stepResult[] = $stepPart;
|
||||
}
|
||||
}
|
||||
|
||||
$result = $stepResult;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[]|StringProperty[] $idComponents
|
||||
*
|
||||
* @phpstan-template TBlock of Block
|
||||
*
|
||||
* @phpstan-param TBlock $block
|
||||
* @phpstan-param list<string|StringProperty<contravariant TBlock>> $idComponents
|
||||
*/
|
||||
private static function serializeFlattenedId(Block $block, array $idComponents) : string{
|
||||
$id = "";
|
||||
foreach($idComponents as $infix){
|
||||
$id .= is_string($infix) ? $infix : $infix->serializePlain($block);
|
||||
}
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[]|StringProperty[] $idComponents
|
||||
* @param string[] $idPropertyValues
|
||||
*
|
||||
* @phpstan-template TBlock of Block
|
||||
*
|
||||
* @phpstan-param TBlock $baseBlock
|
||||
* @phpstan-param list<string|StringProperty<contravariant TBlock>> $idComponents
|
||||
* @phpstan-param list<string> $idPropertyValues
|
||||
*
|
||||
* @phpstan-return TBlock
|
||||
*/
|
||||
private static function deserializeFlattenedId(Block $baseBlock, array $idComponents, array $idPropertyValues) : Block{
|
||||
$preparedBlock = clone $baseBlock;
|
||||
foreach($idComponents as $k => $component){
|
||||
if($component instanceof StringProperty){
|
||||
$fakeValue = $idPropertyValues[$k];
|
||||
$component->deserializePlain($preparedBlock, $fakeValue);
|
||||
}
|
||||
}
|
||||
|
||||
return $preparedBlock;
|
||||
}
|
||||
|
||||
public function mapSimple(Block $block, string $id) : void{
|
||||
$this->deserializer->mapSimple($id, fn() => clone $block);
|
||||
$this->serializer->mapSimple($block, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-template TBlock of Block
|
||||
* @phpstan-param FlattenedIdModel<TBlock, true> $model
|
||||
*/
|
||||
public function mapFlattenedId(FlattenedIdModel $model) : void{
|
||||
$block = $model->getBlock();
|
||||
|
||||
$idComponents = $model->getIdComponents();
|
||||
if(count($idComponents) === 0){
|
||||
throw new \InvalidArgumentException("No ID components provided");
|
||||
}
|
||||
$properties = $model->getProperties();
|
||||
|
||||
//This is a really cursed hack that lets us essentially write flattened properties as blockstate properties, and
|
||||
//then pull them out to compile an ID :D
|
||||
//This works surprisingly well and is much more elegant than I would've expected
|
||||
|
||||
if(count($properties) > 0){
|
||||
$this->serializer->map($block, function(Block $block) use ($idComponents, $properties) : Writer{
|
||||
$id = self::serializeFlattenedId($block, $idComponents);
|
||||
|
||||
$writer = new Writer($id);
|
||||
foreach($properties as $property){
|
||||
$property->serialize($block, $writer);
|
||||
}
|
||||
|
||||
return $writer;
|
||||
});
|
||||
}else{
|
||||
$this->serializer->map($block, function(Block $block) use ($idComponents) : BlockStateData{
|
||||
//fast path for blocks with no state properties
|
||||
$id = self::serializeFlattenedId($block, $idComponents);
|
||||
return BlockStateData::current($id, []);
|
||||
});
|
||||
}
|
||||
|
||||
$idPermutations = self::compileFlattenedIdPartMatrix($idComponents);
|
||||
foreach($idPermutations as $idParts){
|
||||
//deconstruct the ID into a partial state
|
||||
//we can do this at registration time since there will be multiple deserializers
|
||||
$preparedBlock = self::deserializeFlattenedId($block, $idComponents, $idParts);
|
||||
$id = implode("", $idParts);
|
||||
|
||||
if(count($properties) > 0){
|
||||
$this->deserializer->map($id, function(Reader $reader) use ($preparedBlock, $properties) : Block{
|
||||
$block = clone $preparedBlock;
|
||||
|
||||
foreach($properties as $property){
|
||||
$property->deserialize($block, $reader);
|
||||
}
|
||||
return $block;
|
||||
});
|
||||
}else{
|
||||
//fast path for blocks with no state properties
|
||||
$this->deserializer->map($id, fn() => clone $preparedBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-template TBlock of Block&Colored
|
||||
* @phpstan-param TBlock $block
|
||||
*/
|
||||
public function mapColored(Block $block, string $idPrefix, string $idSuffix) : void{
|
||||
$this->mapFlattenedId(FlattenedIdModel::create($block)
|
||||
->idComponents([
|
||||
$idPrefix,
|
||||
CommonProperties::getInstance()->dyeColorIdInfix,
|
||||
$idSuffix
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
public function mapSlab(Slab $block, string $type) : void{
|
||||
$commonProperties = CommonProperties::getInstance();
|
||||
$this->mapFlattenedId(FlattenedIdModel::create($block)
|
||||
->idComponents(["minecraft:", $type, "_", $commonProperties->slabIdInfix, "slab"])
|
||||
->properties([$commonProperties->slabPositionProperty])
|
||||
);
|
||||
}
|
||||
|
||||
public function mapStairs(Stair $block, string $id) : void{
|
||||
$this->mapModel(Model::create($block, $id)->properties(CommonProperties::getInstance()->stairProperties));
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-template TBlock of Block
|
||||
* @phpstan-param Model<TBlock> $model
|
||||
*/
|
||||
public function mapModel(Model $model) : void{
|
||||
$id = $model->getId();
|
||||
$block = $model->getBlock();
|
||||
$propertyDescriptors = $model->getProperties();
|
||||
|
||||
$this->deserializer->map($id, static function(Reader $in) use ($block, $propertyDescriptors) : Block{
|
||||
$newBlock = clone $block;
|
||||
foreach($propertyDescriptors as $descriptor){
|
||||
$descriptor->deserialize($newBlock, $in);
|
||||
}
|
||||
return $newBlock;
|
||||
});
|
||||
$this->serializer->map($block, static function(Block $block) use ($id, $propertyDescriptors) : Writer{
|
||||
$writer = new Writer($id);
|
||||
foreach($propertyDescriptors as $descriptor){
|
||||
$descriptor->serialize($block, $writer);
|
||||
}
|
||||
return $writer;
|
||||
});
|
||||
}
|
||||
}
|
@ -56,11 +56,13 @@ use pocketmine\data\bedrock\block\BlockLegacyMetadata;
|
||||
use pocketmine\data\bedrock\block\BlockStateDeserializeException;
|
||||
use pocketmine\data\bedrock\block\BlockStateNames;
|
||||
use pocketmine\data\bedrock\block\BlockStateNames as StateNames;
|
||||
use pocketmine\data\bedrock\block\convert\property\ValueMappings;
|
||||
use pocketmine\data\bedrock\MushroomBlockTypeIdMap;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
final class BlockStateDeserializerHelper{
|
||||
|
||||
/** @throws BlockStateDeserializeException */
|
||||
@ -71,6 +73,7 @@ final class BlockStateDeserializerHelper{
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @phpstan-template TCandle of Candle
|
||||
* @phpstan-param TCandle $block
|
||||
* @phpstan-return TCandle
|
||||
@ -103,6 +106,7 @@ final class BlockStateDeserializerHelper{
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @phpstan-template TBlock of CopperMaterial
|
||||
*
|
||||
* @phpstan-param TBlock $block
|
||||
@ -115,6 +119,7 @@ final class BlockStateDeserializerHelper{
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @phpstan-template TBlock of CopperMaterial
|
||||
*
|
||||
* @phpstan-param TBlock $block
|
||||
@ -133,6 +138,7 @@ final class BlockStateDeserializerHelper{
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @phpstan-template TDoor of Door
|
||||
* @phpstan-param TDoor $block
|
||||
* @phpstan-return TDoor
|
||||
@ -155,7 +161,10 @@ final class BlockStateDeserializerHelper{
|
||||
->setTop($in->readBool(BlockStateNames::UPPER_BLOCK_BIT));
|
||||
}
|
||||
|
||||
/** @throws BlockStateDeserializeException */
|
||||
/**
|
||||
* @deprecated
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
public static function decodeFenceGate(FenceGate $block, BlockStateReader $in) : FenceGate{
|
||||
return $block
|
||||
->setFacing($in->readCardinalHorizontalFacing())
|
||||
@ -163,17 +172,19 @@ final class BlockStateDeserializerHelper{
|
||||
->setOpen($in->readBool(BlockStateNames::OPEN_BIT));
|
||||
}
|
||||
|
||||
/** @throws BlockStateDeserializeException */
|
||||
/**
|
||||
* @deprecated
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
public static function decodeFloorCoralFan(FloorCoralFan $block, BlockStateReader $in) : FloorCoralFan{
|
||||
return $block
|
||||
->setAxis(match($in->readBoundedInt(BlockStateNames::CORAL_FAN_DIRECTION, 0, 1)){
|
||||
0 => Axis::X,
|
||||
1 => Axis::Z,
|
||||
default => throw new AssumptionFailedError("readBoundedInt() should have prevented this"),
|
||||
});
|
||||
->setAxis($in->mapIntFromInt(BlockStateNames::CORAL_FAN_DIRECTION, ValueMappings::getInstance()->coralAxis));
|
||||
}
|
||||
|
||||
/** @throws BlockStateDeserializeException */
|
||||
/**
|
||||
* @deprecated
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
public static function decodeFloorSign(FloorSign $block, BlockStateReader $in) : FloorSign{
|
||||
return $block
|
||||
->setRotation($in->readBoundedInt(BlockStateNames::GROUND_SIGN_DIRECTION, 0, 15));
|
||||
@ -186,7 +197,10 @@ final class BlockStateDeserializerHelper{
|
||||
->setHasMap($in->readBool(StateNames::ITEM_FRAME_MAP_BIT));
|
||||
}
|
||||
|
||||
/** @throws BlockStateDeserializeException */
|
||||
/**
|
||||
* @throws BlockStateDeserializeException
|
||||
* @deprecated
|
||||
*/
|
||||
public static function decodeLeaves(Leaves $block, BlockStateReader $in) : Leaves{
|
||||
return $block
|
||||
->setNoDecay($in->readBool(StateNames::PERSISTENT_BIT))
|
||||
@ -236,7 +250,10 @@ final class BlockStateDeserializerHelper{
|
||||
->setDelay($in->readBoundedInt(BlockStateNames::REPEATER_DELAY, 0, 3) + 1);
|
||||
}
|
||||
|
||||
/** @throws BlockStateDeserializeException */
|
||||
/**
|
||||
* @throws BlockStateDeserializeException
|
||||
* @deprecated
|
||||
*/
|
||||
public static function decodeSapling(Sapling $block, BlockStateReader $in) : Sapling{
|
||||
return $block
|
||||
->setReady($in->readBool(BlockStateNames::AGE_BIT));
|
||||
@ -273,6 +290,7 @@ final class BlockStateDeserializerHelper{
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @phpstan-template TStair of Stair
|
||||
* @phpstan-param TStair $block
|
||||
* @phpstan-return TStair
|
||||
@ -296,6 +314,7 @@ final class BlockStateDeserializerHelper{
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @phpstan-template TTrapdoor of Trapdoor
|
||||
* @phpstan-param TTrapdoor $block
|
||||
* @phpstan-return TTrapdoor
|
||||
@ -320,12 +339,19 @@ final class BlockStateDeserializerHelper{
|
||||
return $block;
|
||||
}
|
||||
|
||||
/** @throws BlockStateDeserializeException */
|
||||
/**
|
||||
* @deprecated
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
public static function decodeWallSign(WallSign $block, BlockStateReader $in) : WallSign{
|
||||
return $block
|
||||
->setFacing($in->readHorizontalFacing());
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
public static function decodeWeightedPressurePlate(WeightedPressurePlate $block, BlockStateReader $in) : WeightedPressurePlate{
|
||||
return $block
|
||||
->setOutputSignalStrength($in->readBoundedInt(BlockStateNames::REDSTONE_SIGNAL, 0, 15));
|
||||
|
@ -31,6 +31,9 @@ use pocketmine\data\bedrock\block\BlockStateData;
|
||||
use pocketmine\data\bedrock\block\BlockStateDeserializeException;
|
||||
use pocketmine\data\bedrock\block\BlockStateNames;
|
||||
use pocketmine\data\bedrock\block\BlockStateStringValues as StringValues;
|
||||
use pocketmine\data\bedrock\block\convert\property\EnumFromRawStateMap;
|
||||
use pocketmine\data\bedrock\block\convert\property\IntFromRawStateMap;
|
||||
use pocketmine\data\bedrock\block\convert\property\ValueMappings;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\nbt\tag\ByteTag;
|
||||
@ -112,45 +115,45 @@ final class BlockStateReader{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int[] $mapping
|
||||
* @phpstan-param array<int, int> $mapping
|
||||
* @phpstan-return int
|
||||
* @deprecated
|
||||
* @phpstan-param IntFromRawStateMap<string> $map
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
private function parseFacingValue(int $value, array $mapping) : int{
|
||||
$result = $mapping[$value] ?? null;
|
||||
if($result === null){
|
||||
throw new BlockStateDeserializeException("Unmapped facing value " . $value);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
public function mapIntFromString(string $name, IntFromRawStateMap $map) : int{
|
||||
$raw = $this->readString($name);
|
||||
|
||||
/** @throws BlockStateDeserializeException */
|
||||
public function readFacingDirection() : int{
|
||||
return $this->parseFacingValue($this->readInt(BlockStateNames::FACING_DIRECTION), [
|
||||
0 => Facing::DOWN,
|
||||
1 => Facing::UP,
|
||||
2 => Facing::NORTH,
|
||||
3 => Facing::SOUTH,
|
||||
4 => Facing::WEST,
|
||||
5 => Facing::EAST
|
||||
]);
|
||||
}
|
||||
|
||||
/** @throws BlockStateDeserializeException */
|
||||
public function readBlockFace() : int{
|
||||
return match($raw = $this->readString(BlockStateNames::MC_BLOCK_FACE)){
|
||||
StringValues::MC_BLOCK_FACE_DOWN => Facing::DOWN,
|
||||
StringValues::MC_BLOCK_FACE_UP => Facing::UP,
|
||||
StringValues::MC_BLOCK_FACE_NORTH => Facing::NORTH,
|
||||
StringValues::MC_BLOCK_FACE_SOUTH => Facing::SOUTH,
|
||||
StringValues::MC_BLOCK_FACE_WEST => Facing::WEST,
|
||||
StringValues::MC_BLOCK_FACE_EAST => Facing::EAST,
|
||||
default => throw $this->badValueException(BlockStateNames::MC_BLOCK_FACE, $raw)
|
||||
};
|
||||
return $map->rawToValue($raw) ?? throw $this->badValueException($name, $raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @phpstan-param IntFromRawStateMap<int> $map
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
public function mapIntFromInt(string $name, IntFromRawStateMap $map) : int{
|
||||
$raw = $this->readInt($name);
|
||||
|
||||
return $map->rawToValue($raw) ?? throw $this->badValueException($name, (string) $raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
public function readFacingDirection() : int{
|
||||
return $this->mapIntFromInt(BlockStateNames::FACING_DIRECTION, ValueMappings::getInstance()->facing);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
public function readBlockFace() : int{
|
||||
return $this->mapIntFromString(BlockStateNames::MC_BLOCK_FACE, ValueMappings::getInstance()->blockFace);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @return int[]
|
||||
* @phpstan-return array<int, int>
|
||||
*/
|
||||
@ -173,82 +176,69 @@ final class BlockStateReader{
|
||||
return $result;
|
||||
}
|
||||
|
||||
/** @throws BlockStateDeserializeException */
|
||||
/**
|
||||
* @deprecated
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
public function readEndRodFacingDirection() : int{
|
||||
$result = $this->readFacingDirection();
|
||||
return Facing::axis($result) !== Axis::Y ? Facing::opposite($result) : $result;
|
||||
}
|
||||
|
||||
/** @throws BlockStateDeserializeException */
|
||||
/**
|
||||
* @deprecated
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
public function readHorizontalFacing() : int{
|
||||
return $this->parseFacingValue($this->readInt(BlockStateNames::FACING_DIRECTION), [
|
||||
0 => Facing::NORTH, //should be illegal, but 1.13 allows it
|
||||
1 => Facing::NORTH, //also should be illegal
|
||||
2 => Facing::NORTH,
|
||||
3 => Facing::SOUTH,
|
||||
4 => Facing::WEST,
|
||||
5 => Facing::EAST
|
||||
]);
|
||||
}
|
||||
|
||||
/** @throws BlockStateDeserializeException */
|
||||
public function readWeirdoHorizontalFacing() : int{
|
||||
return $this->parseFacingValue($this->readInt(BlockStateNames::WEIRDO_DIRECTION), [
|
||||
0 => Facing::EAST,
|
||||
1 => Facing::WEST,
|
||||
2 => Facing::SOUTH,
|
||||
3 => Facing::NORTH
|
||||
]);
|
||||
}
|
||||
|
||||
/** @throws BlockStateDeserializeException */
|
||||
public function readLegacyHorizontalFacing() : int{
|
||||
return $this->parseFacingValue($this->readInt(BlockStateNames::DIRECTION), [
|
||||
0 => Facing::SOUTH,
|
||||
1 => Facing::WEST,
|
||||
2 => Facing::NORTH,
|
||||
3 => Facing::EAST
|
||||
]);
|
||||
return $this->mapIntFromInt(BlockStateNames::FACING_DIRECTION, ValueMappings::getInstance()->horizontalFacingClassic);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
public function readWeirdoHorizontalFacing() : int{
|
||||
return $this->mapIntFromInt(BlockStateNames::WEIRDO_DIRECTION, ValueMappings::getInstance()->horizontalFacing5Minus);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
public function readLegacyHorizontalFacing() : int{
|
||||
return $this->mapIntFromInt(BlockStateNames::DIRECTION, ValueMappings::getInstance()->horizontalFacingSWNE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* This is for trapdoors, because Mojang botched the conversion in 1.13
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
public function read5MinusHorizontalFacing() : int{
|
||||
return $this->parseFacingValue($this->readInt(BlockStateNames::DIRECTION), [
|
||||
0 => Facing::EAST,
|
||||
1 => Facing::WEST,
|
||||
2 => Facing::SOUTH,
|
||||
3 => Facing::NORTH
|
||||
]);
|
||||
return $this->mapIntFromInt(BlockStateNames::DIRECTION, ValueMappings::getInstance()->horizontalFacing5Minus);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Used by pumpkins as of 1.20.0.23 beta
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
public function readCardinalHorizontalFacing() : int{
|
||||
return match($raw = $this->readString(BlockStateNames::MC_CARDINAL_DIRECTION)){
|
||||
StringValues::MC_CARDINAL_DIRECTION_NORTH => Facing::NORTH,
|
||||
StringValues::MC_CARDINAL_DIRECTION_SOUTH => Facing::SOUTH,
|
||||
StringValues::MC_CARDINAL_DIRECTION_WEST => Facing::WEST,
|
||||
StringValues::MC_CARDINAL_DIRECTION_EAST => Facing::EAST,
|
||||
default => throw $this->badValueException(BlockStateNames::MC_CARDINAL_DIRECTION, $raw)
|
||||
};
|
||||
return $this->mapIntFromString(BlockStateNames::MC_CARDINAL_DIRECTION, ValueMappings::getInstance()->cardinalDirection);
|
||||
}
|
||||
|
||||
/** @throws BlockStateDeserializeException */
|
||||
/**
|
||||
* @deprecated
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
public function readCoralFacing() : int{
|
||||
return $this->parseFacingValue($this->readInt(BlockStateNames::CORAL_DIRECTION), [
|
||||
0 => Facing::WEST,
|
||||
1 => Facing::EAST,
|
||||
2 => Facing::NORTH,
|
||||
3 => Facing::SOUTH
|
||||
]);
|
||||
return $this->mapIntFromInt(BlockStateNames::CORAL_DIRECTION, ValueMappings::getInstance()->horizontalFacingCoral);
|
||||
}
|
||||
|
||||
/** @throws BlockStateDeserializeException */
|
||||
/**
|
||||
* @deprecated
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
public function readFacingWithoutDown() : int{
|
||||
$result = $this->readFacingDirection();
|
||||
if($result === Facing::DOWN){ //shouldn't be legal, but 1.13 allows it
|
||||
@ -257,6 +247,10 @@ final class BlockStateReader{
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
public function readFacingWithoutUp() : int{
|
||||
$result = $this->readFacingDirection();
|
||||
if($result === Facing::UP){
|
||||
@ -266,23 +260,17 @@ final class BlockStateReader{
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-return Axis::*
|
||||
* @deprecated
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
public function readPillarAxis() : int{
|
||||
$rawValue = $this->readString(BlockStateNames::PILLAR_AXIS);
|
||||
$value = [
|
||||
StringValues::PILLAR_AXIS_X => Axis::X,
|
||||
StringValues::PILLAR_AXIS_Y => Axis::Y,
|
||||
StringValues::PILLAR_AXIS_Z => Axis::Z
|
||||
][$rawValue] ?? null;
|
||||
if($value === null){
|
||||
throw $this->badValueException(BlockStateNames::PILLAR_AXIS, $rawValue, "Invalid axis value");
|
||||
}
|
||||
return $value;
|
||||
return $this->mapIntFromString(BlockStateNames::PILLAR_AXIS, ValueMappings::getInstance()->pillarAxis);
|
||||
}
|
||||
|
||||
/** @throws BlockStateDeserializeException */
|
||||
/**
|
||||
* @deprecated
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
public function readSlabPosition() : SlabType{
|
||||
return match($rawValue = $this->readString(BlockStateNames::MC_VERTICAL_HALF)){
|
||||
StringValues::MC_VERTICAL_HALF_BOTTOM => SlabType::BOTTOM,
|
||||
@ -292,34 +280,25 @@ final class BlockStateReader{
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-return Facing::UP|Facing::NORTH|Facing::SOUTH|Facing::WEST|Facing::EAST
|
||||
* @deprecated
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
public function readTorchFacing() : int{
|
||||
//TODO: horizontal directions are flipped (MCPE bug: https://bugs.mojang.com/browse/MCPE-152036)
|
||||
return match($rawValue = $this->readString(BlockStateNames::TORCH_FACING_DIRECTION)){
|
||||
StringValues::TORCH_FACING_DIRECTION_EAST => Facing::WEST,
|
||||
StringValues::TORCH_FACING_DIRECTION_NORTH => Facing::SOUTH,
|
||||
StringValues::TORCH_FACING_DIRECTION_SOUTH => Facing::NORTH,
|
||||
StringValues::TORCH_FACING_DIRECTION_TOP => Facing::UP,
|
||||
StringValues::TORCH_FACING_DIRECTION_UNKNOWN => Facing::UP, //should be illegal, but 1.13 allows it
|
||||
StringValues::TORCH_FACING_DIRECTION_WEST => Facing::EAST,
|
||||
default => throw $this->badValueException(BlockStateNames::TORCH_FACING_DIRECTION, $rawValue, "Invalid torch facing"),
|
||||
};
|
||||
return $this->mapIntFromString(BlockStateNames::TORCH_FACING_DIRECTION, ValueMappings::getInstance()->torchFacing);
|
||||
}
|
||||
|
||||
/** @throws BlockStateDeserializeException */
|
||||
/**
|
||||
* @deprecated
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
public function readBellAttachmentType() : BellAttachmentType{
|
||||
return match($type = $this->readString(BlockStateNames::ATTACHMENT)){
|
||||
StringValues::ATTACHMENT_HANGING => BellAttachmentType::CEILING,
|
||||
StringValues::ATTACHMENT_STANDING => BellAttachmentType::FLOOR,
|
||||
StringValues::ATTACHMENT_SIDE => BellAttachmentType::ONE_WALL,
|
||||
StringValues::ATTACHMENT_MULTIPLE => BellAttachmentType::TWO_WALLS,
|
||||
default => throw $this->badValueException(BlockStateNames::ATTACHMENT, $type),
|
||||
};
|
||||
return $this->readUnitEnum(BlockStateNames::ATTACHMENT, ValueMappings::getInstance()->bellAttachmentType);
|
||||
}
|
||||
|
||||
/** @throws BlockStateDeserializeException */
|
||||
/**
|
||||
* @deprecated
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
public function readWallConnectionType(string $name) : ?WallConnectionType{
|
||||
return match($type = $this->readString($name)){
|
||||
//TODO: this looks a bit confusing due to use of EAST, but the values are the same for all connections
|
||||
@ -332,6 +311,23 @@ final class BlockStateReader{
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @phpstan-template TEnum of \UnitEnum
|
||||
* @phpstan-param EnumFromRawStateMap<TEnum, string> $map
|
||||
* @phpstan-return TEnum
|
||||
* @throws BlockStateDeserializeException
|
||||
*/
|
||||
public function readUnitEnum(string $name, EnumFromRawStateMap $map) : \UnitEnum{
|
||||
$value = $this->readString($name);
|
||||
|
||||
$mapped = $map->rawToValue($value);
|
||||
if($mapped === null){
|
||||
throw $this->badValueException($name, $value);
|
||||
}
|
||||
return $mapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicitly mark a property as unused, so it doesn't get flagged as an error when debug mode is enabled
|
||||
*/
|
||||
|
@ -55,6 +55,9 @@ use pocketmine\data\bedrock\block\convert\BlockStateWriter as Writer;
|
||||
use pocketmine\data\bedrock\MushroomBlockTypeIdMap;
|
||||
use pocketmine\math\Facing;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
final class BlockStateSerializerHelper{
|
||||
public static function encodeButton(Button $block, Writer $out) : Writer{
|
||||
return $out
|
||||
@ -77,6 +80,9 @@ final class BlockStateSerializerHelper{
|
||||
return $out->writeInt(BlockStateNames::GROWTH, $block->getAge());
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public static function encodeTorch(Torch $block, Writer $out) : Writer{
|
||||
return $out
|
||||
->writeTorchFacing($block->getFacing());
|
||||
@ -97,6 +103,9 @@ final class BlockStateSerializerHelper{
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public static function encodeDoor(Door $block, Writer $out) : Writer{
|
||||
return $out
|
||||
->writeBool(BlockStateNames::UPPER_BLOCK_BIT, $block->isTop())
|
||||
@ -111,6 +120,9 @@ final class BlockStateSerializerHelper{
|
||||
->writeBool(BlockStateNames::UPPER_BLOCK_BIT, $block->isTop());
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public static function encodeFenceGate(FenceGate $block, Writer $out) : Writer{
|
||||
return $out
|
||||
->writeCardinalHorizontalFacing($block->getFacing())
|
||||
@ -118,6 +130,9 @@ final class BlockStateSerializerHelper{
|
||||
->writeBool(BlockStateNames::OPEN_BIT, $block->isOpen());
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public static function encodeFloorSign(FloorSign $block, Writer $out) : Writer{
|
||||
return $out
|
||||
->writeInt(BlockStateNames::GROUND_SIGN_DIRECTION, $block->getRotation());
|
||||
@ -135,6 +150,9 @@ final class BlockStateSerializerHelper{
|
||||
->writeFacingDirection($block->getFacing());
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public static function encodeLeaves(Leaves $block, Writer $out) : Writer{
|
||||
return $out
|
||||
->writeBool(BlockStateNames::PERSISTENT_BIT, $block->isNoDecay())
|
||||
@ -159,11 +177,17 @@ final class BlockStateSerializerHelper{
|
||||
->writeInt(BlockStateNames::HUGE_MUSHROOM_BITS, MushroomBlockTypeIdMap::getInstance()->toId($block->getMushroomBlockType()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public static function encodeQuartz(int $axis, Writer $out) : Writer{
|
||||
return $out
|
||||
->writePillarAxis($axis); //this isn't needed for all types, but we have to write it anyway
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public static function encodeSapling(Sapling $block, Writer $out) : Writer{
|
||||
return $out
|
||||
->writeBool(BlockStateNames::AGE_BIT, $block->isReady());
|
||||
@ -193,6 +217,9 @@ final class BlockStateSerializerHelper{
|
||||
self::encodeSingleSlab($block, $singleId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public static function encodeStairs(Stair $block, Writer $out) : Writer{
|
||||
return $out
|
||||
->writeBool(BlockStateNames::UPSIDE_DOWN_BIT, $block->isUpsideDown())
|
||||
@ -208,6 +235,9 @@ final class BlockStateSerializerHelper{
|
||||
->writeFacingWithoutUp($facing === Facing::UP ? Facing::DOWN : $facing);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public static function encodeTrapdoor(Trapdoor $block, Writer $out) : Writer{
|
||||
return $out
|
||||
->write5MinusHorizontalFacing($block->getFacing())
|
||||
@ -224,6 +254,9 @@ final class BlockStateSerializerHelper{
|
||||
->writeWallConnectionType(BlockStateNames::WALL_CONNECTION_TYPE_WEST, $block->getConnection(Facing::WEST));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public static function encodeWallSign(WallSign $block, Writer $out) : Writer{
|
||||
return $out
|
||||
->writeHorizontalFacing($block->getFacing());
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -31,6 +31,9 @@ use pocketmine\data\bedrock\block\BlockStateData;
|
||||
use pocketmine\data\bedrock\block\BlockStateNames;
|
||||
use pocketmine\data\bedrock\block\BlockStateSerializeException;
|
||||
use pocketmine\data\bedrock\block\BlockStateStringValues as StringValues;
|
||||
use pocketmine\data\bedrock\block\convert\property\EnumFromRawStateMap;
|
||||
use pocketmine\data\bedrock\block\convert\property\IntFromRawStateMap;
|
||||
use pocketmine\data\bedrock\block\convert\property\ValueMappings;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\nbt\tag\ByteTag;
|
||||
@ -73,35 +76,47 @@ final class BlockStateWriter{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return $this */
|
||||
public function writeFacingDirection(int $value) : self{
|
||||
$this->writeInt(BlockStateNames::FACING_DIRECTION, match($value){
|
||||
Facing::DOWN => 0,
|
||||
Facing::UP => 1,
|
||||
Facing::NORTH => 2,
|
||||
Facing::SOUTH => 3,
|
||||
Facing::WEST => 4,
|
||||
Facing::EAST => 5,
|
||||
default => throw new BlockStateSerializeException("Invalid Facing $value")
|
||||
});
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return $this */
|
||||
public function writeBlockFace(int $value) : self{
|
||||
$this->writeString(BlockStateNames::MC_BLOCK_FACE, match($value){
|
||||
Facing::DOWN => StringValues::MC_BLOCK_FACE_DOWN,
|
||||
Facing::UP => StringValues::MC_BLOCK_FACE_UP,
|
||||
Facing::NORTH => StringValues::MC_BLOCK_FACE_NORTH,
|
||||
Facing::SOUTH => StringValues::MC_BLOCK_FACE_SOUTH,
|
||||
Facing::WEST => StringValues::MC_BLOCK_FACE_WEST,
|
||||
Facing::EAST => StringValues::MC_BLOCK_FACE_EAST,
|
||||
default => throw new BlockStateSerializeException("Invalid Facing $value")
|
||||
});
|
||||
/**
|
||||
* @deprecated
|
||||
* @phpstan-param IntFromRawStateMap<string> $map
|
||||
* @return $this
|
||||
*/
|
||||
public function mapIntToString(string $name, IntFromRawStateMap $map, int $value) : self{
|
||||
$raw = $map->valueToRaw($value);
|
||||
$this->writeString($name, $raw);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @phpstan-param IntFromRawStateMap<int> $map
|
||||
* @return $this
|
||||
*/
|
||||
public function mapIntToInt(string $name, IntFromRawStateMap $map, int $value) : self{
|
||||
$raw = $map->valueToRaw($value);
|
||||
$this->writeInt($name, $raw);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @return $this
|
||||
*/
|
||||
public function writeFacingDirection(int $value) : self{
|
||||
return $this->mapIntToInt(BlockStateNames::FACING_DIRECTION, ValueMappings::getInstance()->facing, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @return $this
|
||||
*/
|
||||
public function writeBlockFace(int $value) : self{
|
||||
$this->mapIntToString(BlockStateNames::MC_BLOCK_FACE, ValueMappings::getInstance()->blockFace, $value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @param int[] $faces
|
||||
* @phpstan-param array<int, int> $faces
|
||||
* @return $this
|
||||
@ -123,86 +138,69 @@ final class BlockStateWriter{
|
||||
return $this->writeInt(BlockStateNames::MULTI_FACE_DIRECTION_BITS, $result);
|
||||
}
|
||||
|
||||
/** @return $this */
|
||||
/**
|
||||
* @deprecated
|
||||
* @return $this
|
||||
*/
|
||||
public function writeEndRodFacingDirection(int $value) : self{
|
||||
//end rods are stupid in bedrock and have everything except up/down the wrong way round
|
||||
return $this->writeFacingDirection(Facing::axis($value) !== Axis::Y ? Facing::opposite($value) : $value);
|
||||
}
|
||||
|
||||
/** @return $this */
|
||||
/**
|
||||
* @deprecated
|
||||
* @return $this
|
||||
*/
|
||||
public function writeHorizontalFacing(int $value) : self{
|
||||
if($value === Facing::UP || $value === Facing::DOWN){
|
||||
throw new BlockStateSerializeException("Y-axis facing is not allowed");
|
||||
}
|
||||
|
||||
return $this->writeFacingDirection($value);
|
||||
}
|
||||
|
||||
/** @return $this */
|
||||
public function writeWeirdoHorizontalFacing(int $value) : self{
|
||||
$this->writeInt(BlockStateNames::WEIRDO_DIRECTION, match($value){
|
||||
Facing::EAST => 0,
|
||||
Facing::WEST => 1,
|
||||
Facing::SOUTH => 2,
|
||||
Facing::NORTH => 3,
|
||||
default => throw new BlockStateSerializeException("Invalid horizontal facing $value")
|
||||
});
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return $this */
|
||||
public function writeLegacyHorizontalFacing(int $value) : self{
|
||||
$this->writeInt(BlockStateNames::DIRECTION, match($value){
|
||||
Facing::SOUTH => 0,
|
||||
Facing::WEST => 1,
|
||||
Facing::NORTH => 2,
|
||||
Facing::EAST => 3,
|
||||
default => throw new BlockStateSerializeException("Invalid horizontal facing $value")
|
||||
});
|
||||
return $this;
|
||||
return $this->mapIntToInt(BlockStateNames::FACING_DIRECTION, ValueMappings::getInstance()->horizontalFacingClassic, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @return $this
|
||||
*/
|
||||
public function writeWeirdoHorizontalFacing(int $value) : self{
|
||||
return $this->mapIntToInt(BlockStateNames::WEIRDO_DIRECTION, ValueMappings::getInstance()->horizontalFacing5Minus, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @return $this
|
||||
*/
|
||||
public function writeLegacyHorizontalFacing(int $value) : self{
|
||||
return $this->mapIntToInt(BlockStateNames::DIRECTION, ValueMappings::getInstance()->horizontalFacingSWNE, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* This is for trapdoors, because Mojang botched the conversion in 1.13
|
||||
* @return $this
|
||||
*/
|
||||
public function write5MinusHorizontalFacing(int $value) : self{
|
||||
return $this->writeInt(BlockStateNames::DIRECTION, match($value){
|
||||
Facing::EAST => 0,
|
||||
Facing::WEST => 1,
|
||||
Facing::SOUTH => 2,
|
||||
Facing::NORTH => 3,
|
||||
default => throw new BlockStateSerializeException("Invalid horizontal facing $value")
|
||||
});
|
||||
return $this->mapIntToInt(BlockStateNames::DIRECTION, ValueMappings::getInstance()->horizontalFacing5Minus, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Used by pumpkins as of 1.20.0.23 beta
|
||||
* @return $this
|
||||
*/
|
||||
public function writeCardinalHorizontalFacing(int $value) : self{
|
||||
return $this->writeString(BlockStateNames::MC_CARDINAL_DIRECTION, match($value){
|
||||
Facing::SOUTH => StringValues::MC_CARDINAL_DIRECTION_SOUTH,
|
||||
Facing::WEST => StringValues::MC_CARDINAL_DIRECTION_WEST,
|
||||
Facing::NORTH => StringValues::MC_CARDINAL_DIRECTION_NORTH,
|
||||
Facing::EAST => StringValues::MC_CARDINAL_DIRECTION_EAST,
|
||||
default => throw new BlockStateSerializeException("Invalid horizontal facing $value")
|
||||
});
|
||||
return $this->mapIntToString(BlockStateNames::MC_CARDINAL_DIRECTION, ValueMappings::getInstance()->cardinalDirection, $value);
|
||||
}
|
||||
|
||||
/** @return $this */
|
||||
/**
|
||||
* @deprecated
|
||||
* @return $this
|
||||
*/
|
||||
public function writeCoralFacing(int $value) : self{
|
||||
$this->writeInt(BlockStateNames::CORAL_DIRECTION, match($value){
|
||||
Facing::WEST => 0,
|
||||
Facing::EAST => 1,
|
||||
Facing::NORTH => 2,
|
||||
Facing::SOUTH => 3,
|
||||
default => throw new BlockStateSerializeException("Invalid horizontal facing $value")
|
||||
});
|
||||
return $this;
|
||||
return $this->mapIntToInt(BlockStateNames::CORAL_DIRECTION, ValueMappings::getInstance()->horizontalFacingCoral, $value);
|
||||
}
|
||||
|
||||
/** @return $this */
|
||||
/**
|
||||
* @deprecated
|
||||
* @return $this
|
||||
*/
|
||||
public function writeFacingWithoutDown(int $value) : self{
|
||||
if($value === Facing::DOWN){
|
||||
throw new BlockStateSerializeException("Invalid facing DOWN");
|
||||
@ -211,7 +209,10 @@ final class BlockStateWriter{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return $this */
|
||||
/**
|
||||
* @deprecated
|
||||
* @return $this
|
||||
*/
|
||||
public function writeFacingWithoutUp(int $value) : self{
|
||||
if($value === Facing::UP){
|
||||
throw new BlockStateSerializeException("Invalid facing UP");
|
||||
@ -220,18 +221,19 @@ final class BlockStateWriter{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return $this */
|
||||
/**
|
||||
* @deprecated
|
||||
* @return $this
|
||||
*/
|
||||
public function writePillarAxis(int $axis) : self{
|
||||
$this->writeString(BlockStateNames::PILLAR_AXIS, match($axis){
|
||||
Axis::X => StringValues::PILLAR_AXIS_X,
|
||||
Axis::Y => StringValues::PILLAR_AXIS_Y,
|
||||
Axis::Z => StringValues::PILLAR_AXIS_Z,
|
||||
default => throw new BlockStateSerializeException("Invalid axis $axis")
|
||||
});
|
||||
$this->mapIntToString(BlockStateNames::PILLAR_AXIS, ValueMappings::getInstance()->pillarAxis, $axis);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return $this */
|
||||
/**
|
||||
* @deprecated
|
||||
* @return $this
|
||||
*/
|
||||
public function writeSlabPosition(SlabType $slabType) : self{
|
||||
$this->writeString(BlockStateNames::MC_VERTICAL_HALF, match($slabType){
|
||||
SlabType::TOP => StringValues::MC_VERTICAL_HALF_TOP,
|
||||
@ -241,32 +243,27 @@ final class BlockStateWriter{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return $this */
|
||||
/**
|
||||
* @deprecated
|
||||
* @return $this
|
||||
*/
|
||||
public function writeTorchFacing(int $facing) : self{
|
||||
//TODO: horizontal directions are flipped (MCPE bug: https://bugs.mojang.com/browse/MCPE-152036)
|
||||
$this->writeString(BlockStateNames::TORCH_FACING_DIRECTION, match($facing){
|
||||
Facing::UP => StringValues::TORCH_FACING_DIRECTION_TOP,
|
||||
Facing::SOUTH => StringValues::TORCH_FACING_DIRECTION_NORTH,
|
||||
Facing::NORTH => StringValues::TORCH_FACING_DIRECTION_SOUTH,
|
||||
Facing::EAST => StringValues::TORCH_FACING_DIRECTION_WEST,
|
||||
Facing::WEST => StringValues::TORCH_FACING_DIRECTION_EAST,
|
||||
default => throw new BlockStateSerializeException("Invalid Torch facing $facing")
|
||||
});
|
||||
$this->mapIntToString(BlockStateNames::TORCH_FACING_DIRECTION, ValueMappings::getInstance()->torchFacing, $facing);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return $this */
|
||||
/**
|
||||
* @deprecated
|
||||
* @return $this
|
||||
*/
|
||||
public function writeBellAttachmentType(BellAttachmentType $attachmentType) : self{
|
||||
$this->writeString(BlockStateNames::ATTACHMENT, match($attachmentType){
|
||||
BellAttachmentType::FLOOR => StringValues::ATTACHMENT_STANDING,
|
||||
BellAttachmentType::CEILING => StringValues::ATTACHMENT_HANGING,
|
||||
BellAttachmentType::ONE_WALL => StringValues::ATTACHMENT_SIDE,
|
||||
BellAttachmentType::TWO_WALLS => StringValues::ATTACHMENT_MULTIPLE,
|
||||
});
|
||||
return $this;
|
||||
return $this->writeUnitEnum(BlockStateNames::ATTACHMENT, ValueMappings::getInstance()->bellAttachmentType, $attachmentType);
|
||||
}
|
||||
|
||||
/** @return $this */
|
||||
/**
|
||||
* @deprecated
|
||||
* @return $this
|
||||
*/
|
||||
public function writeWallConnectionType(string $name, ?WallConnectionType $wallConnectionType) : self{
|
||||
$this->writeString($name, match($wallConnectionType){
|
||||
null => StringValues::WALL_CONNECTION_TYPE_EAST_NONE,
|
||||
@ -276,6 +273,21 @@ final class BlockStateWriter{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @phpstan-template TEnum of \UnitEnum
|
||||
* @phpstan-param EnumFromRawStateMap<TEnum, string> $map
|
||||
* @phpstan-param TEnum $case
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function writeUnitEnum(string $name, EnumFromRawStateMap $map, \UnitEnum $case) : self{
|
||||
$value = $map->valueToRaw($case);
|
||||
$this->writeString($name, $value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBlockStateData() : BlockStateData{
|
||||
return BlockStateData::current($this->id, $this->states);
|
||||
}
|
||||
|
107
src/data/bedrock/block/convert/FlattenedIdModel.php
Normal file
107
src/data/bedrock/block/convert/FlattenedIdModel.php
Normal file
@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\block\convert;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\data\bedrock\block\convert\property\Property;
|
||||
use pocketmine\data\bedrock\block\convert\property\StringProperty;
|
||||
|
||||
/**
|
||||
* This class works around a limitation in PHPStan.
|
||||
* Ideally, we'd just have a function that accepted ($block, $id, $properties) all together and just have the template
|
||||
* type inferred from $block alone.
|
||||
* However, there's no way to tell PHPStan to ignore $properties for inference, so we're stuck with this hack.
|
||||
*
|
||||
* @phpstan-template TBlock of Block
|
||||
* @phpstan-template THasIdComponents of bool
|
||||
*/
|
||||
final class FlattenedIdModel{
|
||||
|
||||
/**
|
||||
* @var string[]|StringProperty[]
|
||||
* @phpstan-var list<string|StringProperty<contravariant TBlock>>
|
||||
*/
|
||||
private array $idComponents = [];
|
||||
|
||||
/**
|
||||
* @var Property[]
|
||||
* @phpstan-var list<Property<contravariant TBlock>>
|
||||
*/
|
||||
private array $properties = [];
|
||||
|
||||
/**
|
||||
* @phpstan-param TBlock $block
|
||||
*/
|
||||
private function __construct(
|
||||
private Block $block
|
||||
){}
|
||||
|
||||
/**
|
||||
* @phpstan-template TBlock_ of Block
|
||||
* @phpstan-param TBlock_ $block
|
||||
* @return self<TBlock_, false>
|
||||
*/
|
||||
public static function create(Block $block) : self{
|
||||
/** @phpstan-var self<TBlock_, false> $result */
|
||||
$result = new self($block);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/** @phpstan-return TBlock */
|
||||
public function getBlock() : Block{ return $this->block; }
|
||||
|
||||
/**
|
||||
* @return string[]|StringProperty[]
|
||||
* @phpstan-return list<string|StringProperty<contravariant TBlock>>
|
||||
*/
|
||||
public function getIdComponents() : array{ return $this->idComponents; }
|
||||
|
||||
/**
|
||||
* @return Property[]
|
||||
* @phpstan-return list<Property<contravariant TBlock>>
|
||||
*/
|
||||
public function getProperties() : array{ return $this->properties; }
|
||||
|
||||
/**
|
||||
* @param string[]|StringProperty[] $components
|
||||
* @phpstan-param non-empty-list<string|StringProperty<contravariant TBlock>> $components
|
||||
* @return $this
|
||||
* @phpstan-this-out self<TBlock, true>
|
||||
*/
|
||||
public function idComponents(array $components) : self{
|
||||
$this->idComponents = $components;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Property[] $properties
|
||||
* @phpstan-param non-empty-list<Property<contravariant TBlock>> $properties
|
||||
* @return $this
|
||||
* @phpstan-this-out self<TBlock, THasIdComponents>
|
||||
*/
|
||||
public function properties(array $properties) : self{
|
||||
$this->properties = $properties;
|
||||
return $this;
|
||||
}
|
||||
}
|
82
src/data/bedrock/block/convert/Model.php
Normal file
82
src/data/bedrock/block/convert/Model.php
Normal file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\block\convert;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\data\bedrock\block\convert\property\Property;
|
||||
|
||||
/**
|
||||
* This class works around a limitation in PHPStan.
|
||||
* Ideally, we'd just have a function that accepted ($block, $id, $properties) all together and just have the template
|
||||
* type inferred from $block alone.
|
||||
* However, there's no way to tell PHPStan to ignore $properties for inference, so we're stuck with this hack.
|
||||
*
|
||||
* @phpstan-template TBlock of Block
|
||||
*/
|
||||
final class Model{
|
||||
|
||||
/**
|
||||
* @var Property[]
|
||||
* @phpstan-var list<Property<contravariant TBlock>>
|
||||
*/
|
||||
private array $properties = [];
|
||||
|
||||
/**
|
||||
* @phpstan-param TBlock $block
|
||||
*/
|
||||
private function __construct(
|
||||
private Block $block,
|
||||
private string $id
|
||||
){}
|
||||
|
||||
/** @phpstan-return TBlock */
|
||||
public function getBlock() : Block{ return $this->block; }
|
||||
|
||||
public function getId() : string{ return $this->id; }
|
||||
|
||||
/**
|
||||
* @return Property[]
|
||||
* @phpstan-return list<Property<contravariant TBlock>>
|
||||
*/
|
||||
public function getProperties() : array{ return $this->properties; }
|
||||
|
||||
/**
|
||||
* @phpstan-template TBlock_ of Block
|
||||
* @phpstan-param TBlock_ $block
|
||||
* @phpstan-return self<TBlock_>
|
||||
*/
|
||||
public static function create(Block $block, string $id) : self{
|
||||
return new self($block, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Property[] $properties
|
||||
* @phpstan-param list<Property<contravariant TBlock>> $properties
|
||||
* @phpstan-return $this
|
||||
*/
|
||||
public function properties(array $properties) : self{
|
||||
$this->properties = $properties;
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\block\convert;
|
||||
|
||||
use pocketmine\data\bedrock\block\BlockStateDeserializeException;
|
||||
use function spl_object_id;
|
||||
|
||||
/**
|
||||
* @phpstan-template TEnum of \UnitEnum
|
||||
*/
|
||||
class StringEnumMap{
|
||||
/**
|
||||
* @var string[]
|
||||
* @phpstan-var array<int, string>
|
||||
*/
|
||||
private array $enumToValue = [];
|
||||
|
||||
/**
|
||||
* @var \UnitEnum[]
|
||||
* @phpstan-var array<string, TEnum>
|
||||
*/
|
||||
private array $valueToEnum = [];
|
||||
|
||||
/**
|
||||
* @phpstan-param class-string<TEnum> $class
|
||||
* @phpstan-param \Closure(TEnum) : string $mapper
|
||||
*/
|
||||
public function __construct(
|
||||
private string $class,
|
||||
\Closure $mapper
|
||||
){
|
||||
foreach($class::cases() as $case){
|
||||
$string = $mapper($case);
|
||||
$this->valueToEnum[$string] = $case;
|
||||
$this->enumToValue[spl_object_id($case)] = $string;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param TEnum $enum
|
||||
*/
|
||||
public function enumToValue(\UnitEnum $enum) : string{
|
||||
return $this->enumToValue[spl_object_id($enum)];
|
||||
}
|
||||
|
||||
public function valueToEnum(string $string) : ?\UnitEnum{
|
||||
return $this->valueToEnum[$string] ?? throw new BlockStateDeserializeException("No $this->class enum mapping for \"$string\"");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \UnitEnum[]
|
||||
* @phpstan-return array<string, TEnum>
|
||||
*/
|
||||
public function getValueToEnum() : array{
|
||||
return $this->valueToEnum;
|
||||
}
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\block\convert;
|
||||
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\utils\SingletonTrait;
|
||||
|
||||
final class ValueMappings{
|
||||
use SingletonTrait; //???
|
||||
|
||||
/**
|
||||
* @var StringEnumMap[]
|
||||
* @phpstan-var array<class-string<covariant \UnitEnum>, StringEnumMap<covariant \UnitEnum>>
|
||||
*/
|
||||
private array $enumMappings = [];
|
||||
|
||||
public function __construct(){
|
||||
$this->addEnum(DyeColor::class, fn(DyeColor $case) => match ($case) {
|
||||
DyeColor::BLACK => "black",
|
||||
DyeColor::BLUE => "blue",
|
||||
DyeColor::BROWN => "brown",
|
||||
DyeColor::CYAN => "cyan",
|
||||
DyeColor::GRAY => "gray",
|
||||
DyeColor::GREEN => "green",
|
||||
DyeColor::LIGHT_BLUE => "light_blue",
|
||||
DyeColor::LIGHT_GRAY => "light_gray",
|
||||
DyeColor::LIME => "lime",
|
||||
DyeColor::MAGENTA => "magenta",
|
||||
DyeColor::ORANGE => "orange",
|
||||
DyeColor::PINK => "pink",
|
||||
DyeColor::PURPLE => "purple",
|
||||
DyeColor::RED => "red",
|
||||
DyeColor::WHITE => "white",
|
||||
DyeColor::YELLOW => "yellow"
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-template TEnum of \UnitEnum
|
||||
* @phpstan-param class-string<TEnum> $class
|
||||
* @phpstan-param \Closure(TEnum): string $mapper
|
||||
*/
|
||||
private function addEnum(string $class, \Closure $mapper) : void{
|
||||
$this->enumMappings[$class] = new StringEnumMap($class, $mapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-template TEnum of \UnitEnum
|
||||
* @phpstan-param class-string<TEnum> $class
|
||||
* @phpstan-return StringEnumMap<TEnum>
|
||||
*/
|
||||
public function getEnumMap(string $class) : StringEnumMap{
|
||||
if(!isset($this->enumMappings[$class])){
|
||||
throw new \InvalidArgumentException("No enum mapping found for class: $class");
|
||||
}
|
||||
/**
|
||||
* @phpstan-var StringEnumMap<TEnum> $map
|
||||
*/
|
||||
$map = $this->enumMappings[$class];
|
||||
return $map;
|
||||
}
|
||||
}
|
1646
src/data/bedrock/block/convert/VanillaBlockMappings.php
Normal file
1646
src/data/bedrock/block/convert/VanillaBlockMappings.php
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\block\convert\property;
|
||||
|
||||
use pocketmine\data\bedrock\block\BlockStateSerializeException;
|
||||
use pocketmine\data\bedrock\block\convert\BlockStateReader;
|
||||
use pocketmine\data\bedrock\block\convert\BlockStateWriter;
|
||||
|
||||
/**
|
||||
* @phpstan-template TBlock of object
|
||||
* @phpstan-implements StringProperty<TBlock>
|
||||
*/
|
||||
final class BoolFromStringProperty implements StringProperty{
|
||||
|
||||
/**
|
||||
* @param \Closure(TBlock) : bool $getter
|
||||
* @param \Closure(TBlock, bool) : mixed $setter
|
||||
*/
|
||||
public function __construct(
|
||||
private string $name,
|
||||
private string $falseValue,
|
||||
private string $trueValue,
|
||||
private \Closure $getter,
|
||||
private \Closure $setter
|
||||
){}
|
||||
|
||||
public function getName() : string{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getPossibleValues() : array{
|
||||
return [$this->falseValue, $this->trueValue];
|
||||
}
|
||||
|
||||
public function deserialize(object $block, BlockStateReader $in) : void{
|
||||
$this->deserializePlain($block, $in->readString($this->name));
|
||||
}
|
||||
|
||||
public function deserializePlain(object $block, string $raw) : void{
|
||||
$value = match($raw){
|
||||
$this->falseValue => false,
|
||||
$this->trueValue => true,
|
||||
default => throw new BlockStateSerializeException("Invalid value for {$this->name}: $raw"),
|
||||
};
|
||||
|
||||
($this->setter)($block, $value);
|
||||
}
|
||||
|
||||
public function serialize(object $block, BlockStateWriter $out) : void{
|
||||
$out->writeString($this->name, $this->serializePlain($block));
|
||||
}
|
||||
|
||||
public function serializePlain(object $block) : string{
|
||||
$value = ($this->getter)($block);
|
||||
return $value ? $this->trueValue : $this->falseValue;
|
||||
}
|
||||
}
|
71
src/data/bedrock/block/convert/property/BoolProperty.php
Normal file
71
src/data/bedrock/block/convert/property/BoolProperty.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\block\convert\property;
|
||||
|
||||
use pocketmine\data\bedrock\block\convert\BlockStateReader;
|
||||
use pocketmine\data\bedrock\block\convert\BlockStateWriter;
|
||||
|
||||
/**
|
||||
* @phpstan-template TBlock of object
|
||||
* @phpstan-implements Property<TBlock>
|
||||
*/
|
||||
final class BoolProperty implements Property{
|
||||
/**
|
||||
* @phpstan-param \Closure(TBlock) : bool $getter
|
||||
* @phpstan-param \Closure(TBlock, bool) : mixed $setter
|
||||
*/
|
||||
public function __construct(
|
||||
private string $name,
|
||||
private \Closure $getter,
|
||||
private \Closure $setter,
|
||||
private bool $inverted = false //we don't *need* this, but it avoids accidentally forgetting a ! in the getter/setter closures (and makes it analysable)
|
||||
){}
|
||||
|
||||
/**
|
||||
* @phpstan-return self<object>
|
||||
*/
|
||||
public static function unused(string $name, bool $serializedValue) : self{
|
||||
return new self($name, fn() => $serializedValue, fn() => null);
|
||||
}
|
||||
|
||||
public function getName() : string{ return $this->name; }
|
||||
|
||||
/**
|
||||
* @phpstan-param TBlock $block
|
||||
*/
|
||||
public function deserialize(object $block, BlockStateReader $in) : void{
|
||||
$raw = $in->readBool($this->name);
|
||||
$value = $raw !== $this->inverted;
|
||||
($this->setter)($block, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param TBlock $block
|
||||
*/
|
||||
public function serialize(object $block, BlockStateWriter $out) : void{
|
||||
$value = ($this->getter)($block);
|
||||
$raw = $value !== $this->inverted;
|
||||
$out->writeBool($this->name, $raw);
|
||||
}
|
||||
}
|
428
src/data/bedrock/block/convert/property/CommonProperties.php
Normal file
428
src/data/bedrock/block/convert/property/CommonProperties.php
Normal file
@ -0,0 +1,428 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\block\convert\property;
|
||||
|
||||
use pocketmine\block\Button;
|
||||
use pocketmine\block\Door;
|
||||
use pocketmine\block\DoublePlant;
|
||||
use pocketmine\block\FenceGate;
|
||||
use pocketmine\block\ItemFrame;
|
||||
use pocketmine\block\Liquid;
|
||||
use pocketmine\block\SimplePressurePlate;
|
||||
use pocketmine\block\Slab;
|
||||
use pocketmine\block\Stair;
|
||||
use pocketmine\block\Stem;
|
||||
use pocketmine\block\Torch;
|
||||
use pocketmine\block\Trapdoor;
|
||||
use pocketmine\block\utils\Ageable;
|
||||
use pocketmine\block\utils\AnalogRedstoneSignalEmitter;
|
||||
use pocketmine\block\utils\AnyFacing;
|
||||
use pocketmine\block\utils\Colored;
|
||||
use pocketmine\block\utils\CopperMaterial;
|
||||
use pocketmine\block\utils\CopperOxidation;
|
||||
use pocketmine\block\utils\CoralMaterial;
|
||||
use pocketmine\block\utils\CoralType;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\HorizontalFacing;
|
||||
use pocketmine\block\utils\Lightable;
|
||||
use pocketmine\block\utils\MultiFacing;
|
||||
use pocketmine\block\utils\PillarRotation;
|
||||
use pocketmine\block\utils\SignLikeRotation;
|
||||
use pocketmine\block\utils\SlabType;
|
||||
use pocketmine\block\Wall;
|
||||
use pocketmine\block\Wood;
|
||||
use pocketmine\data\bedrock\block\BlockLegacyMetadata;
|
||||
use pocketmine\data\bedrock\block\BlockStateNames as StateNames;
|
||||
use pocketmine\data\bedrock\block\BlockStateStringValues;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\utils\SingletonTrait;
|
||||
|
||||
final class CommonProperties{
|
||||
use SingletonTrait;
|
||||
|
||||
/** @phpstan-var ValueFromStringProperty<AnyFacing, int> */
|
||||
public readonly ValueFromStringProperty $blockFace;
|
||||
/** @phpstan-var ValueFromStringProperty<PillarRotation, int> */
|
||||
public readonly ValueFromStringProperty $pillarAxis;
|
||||
/** @phpstan-var ValueFromStringProperty<Torch, int> */
|
||||
public readonly ValueFromStringProperty $torchFacing;
|
||||
|
||||
/** @phpstan-var ValueFromStringProperty<HorizontalFacing, int> */
|
||||
public readonly ValueFromStringProperty $horizontalFacingCardinal;
|
||||
/** @phpstan-var ValueFromIntProperty<HorizontalFacing, int> */
|
||||
public readonly ValueFromIntProperty $horizontalFacingSWNE;
|
||||
/** @phpstan-var ValueFromIntProperty<HorizontalFacing, int> */
|
||||
public readonly ValueFromIntProperty $horizontalFacingSWNEInverted;
|
||||
/** @phpstan-var ValueFromIntProperty<HorizontalFacing, int> */
|
||||
public readonly ValueFromIntProperty $horizontalFacingClassic;
|
||||
|
||||
/** @phpstan-var ValueFromIntProperty<AnyFacing, int> */
|
||||
public readonly ValueFromIntProperty $anyFacingClassic;
|
||||
|
||||
/** @phpstan-var OptionSetFromIntProperty<MultiFacing, int> */
|
||||
public readonly OptionSetFromIntProperty $multiFacingFlags;
|
||||
|
||||
/** @phpstan-var IntProperty<SignLikeRotation> */
|
||||
public readonly IntProperty $floorSignLikeRotation;
|
||||
|
||||
/** @phpstan-var IntProperty<AnalogRedstoneSignalEmitter> */
|
||||
public readonly IntProperty $analogRedstoneSignal;
|
||||
|
||||
/** @phpstan-var IntProperty<Ageable> */
|
||||
public readonly IntProperty $cropAgeMax7;
|
||||
/** @phpstan-var BoolProperty<DoublePlant> */
|
||||
public readonly BoolProperty $doublePlantHalf;
|
||||
|
||||
/** @phpstan-var IntProperty<Liquid> */
|
||||
public readonly IntProperty $liquidData;
|
||||
|
||||
/** @phpstan-var BoolProperty<Lightable> */
|
||||
public readonly BoolProperty $lit;
|
||||
|
||||
public readonly DummyProperty $dummyCardinalDirection;
|
||||
public readonly DummyProperty $dummyPillarAxis;
|
||||
|
||||
/** @phpstan-var ValueFromStringProperty<Colored, DyeColor> */
|
||||
public readonly ValueFromStringProperty $dyeColorIdInfix;
|
||||
|
||||
/** @phpstan-var BoolFromStringProperty<Lightable> */
|
||||
public readonly BoolFromStringProperty $litIdInfix;
|
||||
|
||||
/** @phpstan-var BoolFromStringProperty<Slab> */
|
||||
public readonly BoolFromStringProperty $slabIdInfix;
|
||||
/** @phpstan-var BoolFromStringProperty<Slab> */
|
||||
public readonly BoolFromStringProperty $slabPositionProperty;
|
||||
|
||||
/**
|
||||
* @var StringProperty[]
|
||||
* @phpstan-var non-empty-list<string|StringProperty<CoralMaterial>>
|
||||
*/
|
||||
public readonly array $coralIdPrefixes;
|
||||
/**
|
||||
* @var StringProperty[]
|
||||
* @phpstan-var non-empty-list<string|StringProperty<CopperMaterial>>
|
||||
*/
|
||||
public readonly array $copperIdPrefixes;
|
||||
|
||||
/**
|
||||
* @var StringProperty[]
|
||||
* @phpstan-var non-empty-list<string|StringProperty<contravariant Lightable>>
|
||||
*/
|
||||
public readonly array $furnaceIdPrefixes;
|
||||
|
||||
/**
|
||||
* @var StringProperty[]|string[]
|
||||
* @phpstan-var non-empty-list<string|StringProperty<contravariant Liquid>>
|
||||
*/
|
||||
public readonly array $liquidIdPrefixes;
|
||||
|
||||
/**
|
||||
* @var StringProperty[]
|
||||
* @phpstan-var non-empty-list<string|StringProperty<contravariant Wood>>
|
||||
*/
|
||||
public readonly array $woodIdPrefixes;
|
||||
|
||||
/**
|
||||
* @var Property[]
|
||||
* @phpstan-var non-empty-list<Property<contravariant Button>>
|
||||
*/
|
||||
public readonly array $buttonProperties;
|
||||
|
||||
/**
|
||||
* @var Property[]
|
||||
* @phpstan-var non-empty-list<Property<contravariant Lightable & HorizontalFacing>>
|
||||
*/
|
||||
public readonly array $campfireProperties;
|
||||
|
||||
/**
|
||||
* @var Property[]
|
||||
* @phpstan-var non-empty-list<Property<contravariant Door>>
|
||||
*/
|
||||
public readonly array $doorProperties;
|
||||
|
||||
/**
|
||||
* @var Property[]
|
||||
* @phpstan-var non-empty-list<Property<contravariant FenceGate>>
|
||||
*/
|
||||
public readonly array $fenceGateProperties;
|
||||
|
||||
/**
|
||||
* @var Property[]
|
||||
* @phpstan-var non-empty-list<Property<contravariant ItemFrame>>
|
||||
*/
|
||||
public readonly array $itemFrameProperties;
|
||||
|
||||
/**
|
||||
* @var Property[]
|
||||
* @phpstan-var non-empty-list<Property<contravariant SimplePressurePlate>>
|
||||
*/
|
||||
public readonly array $simplePressurePlateProperties;
|
||||
|
||||
/**
|
||||
* @var Property[]
|
||||
* @phpstan-var non-empty-list<Property<contravariant Stair>>
|
||||
*/
|
||||
public readonly array $stairProperties;
|
||||
|
||||
/**
|
||||
* @var Property[]
|
||||
* @phpstan-var non-empty-list<Property<contravariant Stem>>
|
||||
*/
|
||||
public readonly array $stemProperties;
|
||||
|
||||
/**
|
||||
* @var Property[]
|
||||
* @phpstan-var non-empty-list<Property<contravariant Trapdoor>>
|
||||
*/
|
||||
public readonly array $trapdoorProperties;
|
||||
|
||||
/**
|
||||
* @var Property[]
|
||||
* @phpstan-var non-empty-list<Property<contravariant Wall>>
|
||||
*/
|
||||
public readonly array $wallProperties;
|
||||
|
||||
private function __construct(){
|
||||
$vm = ValueMappings::getInstance();
|
||||
|
||||
$hfGet = fn(HorizontalFacing $v) => $v->getFacing();
|
||||
$hfSet = fn(HorizontalFacing $v, int $facing) => $v->setFacing($facing);
|
||||
$this->horizontalFacingCardinal = new ValueFromStringProperty(StateNames::MC_CARDINAL_DIRECTION, $vm->cardinalDirection, $hfGet, $hfSet);
|
||||
|
||||
$this->blockFace = new ValueFromStringProperty(
|
||||
StateNames::MC_BLOCK_FACE,
|
||||
$vm->blockFace,
|
||||
fn(AnyFacing $b) => $b->getFacing(),
|
||||
fn(AnyFacing $b, int $v) => $b->setFacing($v)
|
||||
);
|
||||
|
||||
$this->pillarAxis = new ValueFromStringProperty(
|
||||
StateNames::PILLAR_AXIS,
|
||||
$vm->pillarAxis,
|
||||
fn(PillarRotation $b) => $b->getAxis(),
|
||||
fn(PillarRotation $b, int $v) => $b->setAxis($v)
|
||||
);
|
||||
|
||||
$this->torchFacing = new ValueFromStringProperty(
|
||||
StateNames::TORCH_FACING_DIRECTION,
|
||||
$vm->torchFacing,
|
||||
fn(Torch $b) => $b->getFacing(),
|
||||
fn(Torch $b, int $v) => $b->setFacing($v)
|
||||
);
|
||||
|
||||
$this->horizontalFacingSWNE = new ValueFromIntProperty(StateNames::DIRECTION, $vm->horizontalFacingSWNE, $hfGet, $hfSet);
|
||||
$this->horizontalFacingSWNEInverted = new ValueFromIntProperty(StateNames::DIRECTION, $vm->horizontalFacingSWNEInverted, $hfGet, $hfSet);
|
||||
$this->horizontalFacingClassic = new ValueFromIntProperty(StateNames::FACING_DIRECTION, $vm->horizontalFacingClassic, $hfGet, $hfSet);
|
||||
|
||||
$this->anyFacingClassic = new ValueFromIntProperty(
|
||||
StateNames::FACING_DIRECTION,
|
||||
$vm->facing,
|
||||
fn(AnyFacing $b) => $b->getFacing(),
|
||||
fn(AnyFacing $b, int $v) => $b->setFacing($v)
|
||||
);
|
||||
|
||||
$this->multiFacingFlags = new OptionSetFromIntProperty(
|
||||
StateNames::MULTI_FACE_DIRECTION_BITS,
|
||||
IntFromRawStateMap::int([
|
||||
Facing::DOWN => BlockLegacyMetadata::MULTI_FACE_DIRECTION_FLAG_DOWN,
|
||||
Facing::UP => BlockLegacyMetadata::MULTI_FACE_DIRECTION_FLAG_UP,
|
||||
Facing::NORTH => BlockLegacyMetadata::MULTI_FACE_DIRECTION_FLAG_NORTH,
|
||||
Facing::SOUTH => BlockLegacyMetadata::MULTI_FACE_DIRECTION_FLAG_SOUTH,
|
||||
Facing::WEST => BlockLegacyMetadata::MULTI_FACE_DIRECTION_FLAG_WEST,
|
||||
Facing::EAST => BlockLegacyMetadata::MULTI_FACE_DIRECTION_FLAG_EAST
|
||||
]),
|
||||
fn(MultiFacing $b) => $b->getFaces(),
|
||||
fn(MultiFacing $b, array $v) => $b->setFaces($v)
|
||||
);
|
||||
|
||||
$this->floorSignLikeRotation = new IntProperty(StateNames::GROUND_SIGN_DIRECTION, 0, 15, fn(SignLikeRotation $b) => $b->getRotation(), fn(SignLikeRotation $b, int $v) => $b->setRotation($v));
|
||||
|
||||
$this->analogRedstoneSignal = new IntProperty(StateNames::REDSTONE_SIGNAL, 0, 15, fn(AnalogRedstoneSignalEmitter $b) => $b->getOutputSignalStrength(), fn(AnalogRedstoneSignalEmitter $b, int $v) => $b->setOutputSignalStrength($v));
|
||||
|
||||
$this->cropAgeMax7 = new IntProperty(StateNames::GROWTH, 0, 7, fn(Ageable $b) => $b->getAge(), fn(Ageable $b, int $v) => $b->setAge($v));
|
||||
$this->doublePlantHalf = new BoolProperty(StateNames::UPPER_BLOCK_BIT, fn(DoublePlant $b) => $b->isTop(), fn(DoublePlant $b, bool $v) => $b->setTop($v));
|
||||
|
||||
$fallingFlag = BlockLegacyMetadata::LIQUID_FALLING_FLAG;
|
||||
$this->liquidData = new IntProperty(
|
||||
StateNames::LIQUID_DEPTH,
|
||||
0,
|
||||
15,
|
||||
fn(Liquid $b) => $b->getDecay() | ($b->isFalling() ? $fallingFlag : 0),
|
||||
fn(Liquid $b, int $v) => $b->setDecay($v & ~$fallingFlag)->setFalling(($v & $fallingFlag) !== 0)
|
||||
);
|
||||
|
||||
$this->lit = new BoolProperty(StateNames::LIT, fn(Lightable $b) => $b->isLit(), fn(Lightable $b, bool $v) => $b->setLit($v));
|
||||
|
||||
$this->dummyCardinalDirection = new DummyProperty(StateNames::MC_CARDINAL_DIRECTION, BlockStateStringValues::MC_CARDINAL_DIRECTION_SOUTH);
|
||||
$this->dummyPillarAxis = new DummyProperty(StateNames::PILLAR_AXIS, BlockStateStringValues::PILLAR_AXIS_Y);
|
||||
|
||||
$this->dyeColorIdInfix = new ValueFromStringProperty("color", $vm->dyeColor, fn(Colored $b) => $b->getColor(), fn(Colored $b, DyeColor $v) => $b->setColor($v));
|
||||
$this->litIdInfix = new BoolFromStringProperty("lit", "", "lit_", fn(Lightable $b) => $b->isLit(), fn(Lightable $b, bool $v) => $b->setLit($v));
|
||||
|
||||
$this->slabIdInfix = new BoolFromStringProperty(
|
||||
"double",
|
||||
"",
|
||||
"double_",
|
||||
fn(Slab $b) => $b->getSlabType() === SlabType::DOUBLE,
|
||||
|
||||
//we don't know this is actually a bottom slab yet but we don't have enough information to set the
|
||||
//correct type in this handler
|
||||
//BOTTOM serves as a signal value for the state deserializer to decide whether to ignore the
|
||||
//upper_block_bit property
|
||||
fn(Slab $b, bool $v) => $b->setSlabType($v ? SlabType::DOUBLE : SlabType::BOTTOM)
|
||||
);
|
||||
$this->slabPositionProperty = new BoolFromStringProperty(
|
||||
StateNames::MC_VERTICAL_HALF,
|
||||
BlockStateStringValues::MC_VERTICAL_HALF_BOTTOM,
|
||||
BlockStateStringValues::MC_VERTICAL_HALF_TOP,
|
||||
fn(Slab $b) => $b->getSlabType() === SlabType::TOP,
|
||||
|
||||
//Ignore the value for double slabs (should be set by ID component before this is reached)
|
||||
fn(Slab $b, bool $v) => $b->getSlabType() !== SlabType::DOUBLE ? $b->setSlabType($v ? SlabType::TOP : SlabType::BOTTOM) : null
|
||||
);
|
||||
|
||||
$this->coralIdPrefixes = [
|
||||
"minecraft:",
|
||||
new BoolFromStringProperty("dead", "", "dead_", fn(CoralMaterial $b) => $b->isDead(), fn(CoralMaterial $b, bool $v) => $b->setDead($v)),
|
||||
new ValueFromStringProperty("type", EnumFromRawStateMap::string(CoralType::class, fn(CoralType $case) => match ($case) {
|
||||
CoralType::BRAIN => "brain",
|
||||
CoralType::BUBBLE => "bubble",
|
||||
CoralType::FIRE => "fire",
|
||||
CoralType::HORN => "horn",
|
||||
CoralType::TUBE => "tube"
|
||||
}), fn(CoralMaterial $b) => $b->getCoralType(), fn(CoralMaterial $b, CoralType $v) => $b->setCoralType($v)),
|
||||
];
|
||||
$this->copperIdPrefixes = [
|
||||
"minecraft:",
|
||||
new BoolFromStringProperty("waxed", "", "waxed_", fn(CopperMaterial $b) => $b->isWaxed(), fn(CopperMaterial $b, bool $v) => $b->setWaxed($v)),
|
||||
new ValueFromStringProperty("oxidation", EnumFromRawStateMap::string(CopperOxidation::class, fn(CopperOxidation $case) => match ($case) {
|
||||
CopperOxidation::NONE => "",
|
||||
CopperOxidation::EXPOSED => "exposed_",
|
||||
CopperOxidation::WEATHERED => "weathered_",
|
||||
CopperOxidation::OXIDIZED => "oxidized_",
|
||||
}), fn(CopperMaterial $b) => $b->getOxidation(), fn(CopperMaterial $b, CopperOxidation $v) => $b->setOxidation($v))
|
||||
];
|
||||
|
||||
$this->furnaceIdPrefixes = ["minecraft:", $this->litIdInfix];
|
||||
|
||||
$this->liquidIdPrefixes = [
|
||||
"minecraft:",
|
||||
new BoolFromStringProperty("still", "flowing_", "", fn(Liquid $b) => $b->isStill(), fn(Liquid $b, bool $v) => $b->setStill($v))
|
||||
];
|
||||
|
||||
$this->woodIdPrefixes = [
|
||||
"minecraft:",
|
||||
new BoolFromStringProperty("stripped", "", "stripped_", fn(Wood $b) => $b->isStripped(), fn(Wood $b, bool $v) => $b->setStripped($v)),
|
||||
];
|
||||
|
||||
$this->buttonProperties = [
|
||||
$this->anyFacingClassic,
|
||||
new BoolProperty(StateNames::BUTTON_PRESSED_BIT, fn(Button $b) => $b->isPressed(), fn(Button $b, bool $v) => $b->setPressed($v)),
|
||||
];
|
||||
|
||||
$this->campfireProperties = [
|
||||
$this->horizontalFacingCardinal,
|
||||
new BoolProperty(StateNames::EXTINGUISHED, fn(Lightable $b) => $b->isLit(), fn(Lightable $b, bool $v) => $b->setLit($v), inverted: true),
|
||||
];
|
||||
|
||||
//TODO: check if these need any special treatment to get the appropriate data to both halves of the door
|
||||
$this->doorProperties = [
|
||||
new BoolProperty(StateNames::UPPER_BLOCK_BIT, fn(Door $b) => $b->isTop(), fn(Door $b, bool $v) => $b->setTop($v)),
|
||||
new BoolProperty(StateNames::DOOR_HINGE_BIT, fn(Door $b) => $b->isHingeRight(), fn(Door $b, bool $v) => $b->setHingeRight($v)),
|
||||
new BoolProperty(StateNames::OPEN_BIT, fn(Door $b) => $b->isOpen(), fn(Door $b, bool $v) => $b->setOpen($v)),
|
||||
new ValueFromStringProperty(
|
||||
StateNames::MC_CARDINAL_DIRECTION,
|
||||
IntFromRawStateMap::string([
|
||||
//a door facing "east" is actually facing north - thanks mojang
|
||||
Facing::NORTH => BlockStateStringValues::MC_CARDINAL_DIRECTION_EAST,
|
||||
Facing::EAST => BlockStateStringValues::MC_CARDINAL_DIRECTION_SOUTH,
|
||||
Facing::SOUTH => BlockStateStringValues::MC_CARDINAL_DIRECTION_WEST,
|
||||
Facing::WEST => BlockStateStringValues::MC_CARDINAL_DIRECTION_NORTH
|
||||
]),
|
||||
fn(HorizontalFacing $b) => $b->getFacing(),
|
||||
fn(HorizontalFacing $b, int $v) => $b->setFacing($v)
|
||||
)
|
||||
];
|
||||
|
||||
$this->fenceGateProperties = [
|
||||
new BoolProperty(StateNames::IN_WALL_BIT, fn(FenceGate $b) => $b->isInWall(), fn(FenceGate $b, bool $v) => $b->setInWall($v)),
|
||||
new BoolProperty(StateNames::OPEN_BIT, fn(FenceGate $b) => $b->isOpen(), fn(FenceGate $b, bool $v) => $b->setOpen($v)),
|
||||
$this->horizontalFacingCardinal,
|
||||
];
|
||||
|
||||
$this->itemFrameProperties = [
|
||||
new DummyProperty(StateNames::ITEM_FRAME_PHOTO_BIT, false), //TODO: not sure what the point of this is
|
||||
new BoolProperty(StateNames::ITEM_FRAME_MAP_BIT, fn(ItemFrame $b) => $b->hasMap(), fn(ItemFrame $b, bool $v) => $b->setHasMap($v)),
|
||||
$this->anyFacingClassic
|
||||
];
|
||||
|
||||
$this->simplePressurePlateProperties = [
|
||||
//TODO: not sure what the deal is here ... seems like a mojang bug / artifact of bad implementation?
|
||||
//best to keep this separate from weighted plates anyway...
|
||||
new IntProperty(
|
||||
StateNames::REDSTONE_SIGNAL,
|
||||
0,
|
||||
15,
|
||||
fn(SimplePressurePlate $b) => $b->isPressed() ? 15 : 0,
|
||||
fn(SimplePressurePlate $b, int $v) => $b->setPressed($v !== 0)
|
||||
)
|
||||
];
|
||||
|
||||
$this->stairProperties = [
|
||||
new BoolProperty(StateNames::UPSIDE_DOWN_BIT, fn(Stair $b) => $b->isUpsideDown(), fn(Stair $b, bool $v) => $b->setUpsideDown($v)),
|
||||
new ValueFromIntProperty(StateNames::WEIRDO_DIRECTION, $vm->horizontalFacing5Minus, $hfGet, $hfSet),
|
||||
];
|
||||
|
||||
$this->stemProperties = [
|
||||
new ValueFromIntProperty(StateNames::FACING_DIRECTION, $vm->facingStem, fn(Stem $b) => $b->getFacing(), fn(Stem $b, int $v) => $b->setFacing($v)),
|
||||
$this->cropAgeMax7
|
||||
];
|
||||
|
||||
$this->trapdoorProperties = [
|
||||
//this uses the same values as stairs, but the state is named differently
|
||||
new ValueFromIntProperty(StateNames::DIRECTION, $vm->horizontalFacing5Minus, $hfGet, $hfSet),
|
||||
|
||||
new BoolProperty(StateNames::UPSIDE_DOWN_BIT, fn(Trapdoor $b) => $b->isTop(), fn(Trapdoor $b, bool $v) => $b->setTop($v)),
|
||||
new BoolProperty(StateNames::OPEN_BIT, fn(Trapdoor $b) => $b->isOpen(), fn(Trapdoor $b, bool $v) => $b->setOpen($v)),
|
||||
];
|
||||
|
||||
$wallProperties = [
|
||||
new BoolProperty(StateNames::WALL_POST_BIT, fn(Wall $b) => $b->isPost(), fn(Wall $b, bool $v) => $b->setPost($v)),
|
||||
];
|
||||
foreach([
|
||||
Facing::NORTH => StateNames::WALL_CONNECTION_TYPE_NORTH,
|
||||
Facing::SOUTH => StateNames::WALL_CONNECTION_TYPE_SOUTH,
|
||||
Facing::WEST => StateNames::WALL_CONNECTION_TYPE_WEST,
|
||||
Facing::EAST => StateNames::WALL_CONNECTION_TYPE_EAST
|
||||
] as $facing => $stateName){
|
||||
$wallProperties[] = new ValueFromStringProperty(
|
||||
$stateName,
|
||||
EnumFromRawStateMap::string(WallConnectionTypeShim::class, fn(WallConnectionTypeShim $case) => $case->getValue()),
|
||||
fn(Wall $b) => WallConnectionTypeShim::serialize($b->getConnection($facing)),
|
||||
fn(Wall $b, WallConnectionTypeShim $v) => $b->setConnection($facing, $v->deserialize())
|
||||
);
|
||||
}
|
||||
$this->wallProperties = $wallProperties;
|
||||
}
|
||||
}
|
61
src/data/bedrock/block/convert/property/DummyProperty.php
Normal file
61
src/data/bedrock/block/convert/property/DummyProperty.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\block\convert\property;
|
||||
|
||||
use pocketmine\data\bedrock\block\convert\BlockStateReader;
|
||||
use pocketmine\data\bedrock\block\convert\BlockStateWriter;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use function is_bool;
|
||||
use function is_int;
|
||||
use function is_string;
|
||||
|
||||
/**
|
||||
* @phpstan-implements Property<object>
|
||||
*/
|
||||
final class DummyProperty implements Property{
|
||||
public function __construct(
|
||||
private string $name,
|
||||
private bool|int|string $value
|
||||
){}
|
||||
|
||||
public function getName() : string{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function deserialize(object $block, BlockStateReader $in) : void{
|
||||
$in->ignored($this->name);
|
||||
}
|
||||
|
||||
public function serialize(object $block, BlockStateWriter $out) : void{
|
||||
if(is_bool($this->value)){
|
||||
$out->writeBool($this->name, $this->value);
|
||||
}elseif(is_int($this->value)){
|
||||
$out->writeInt($this->name, $this->value);
|
||||
}elseif(is_string($this->value)){
|
||||
$out->writeString($this->name, $this->value);
|
||||
}else{
|
||||
throw new AssumptionFailedError();
|
||||
}
|
||||
}
|
||||
}
|
109
src/data/bedrock/block/convert/property/EnumFromRawStateMap.php
Normal file
109
src/data/bedrock/block/convert/property/EnumFromRawStateMap.php
Normal file
@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\block\convert\property;
|
||||
|
||||
use function spl_object_id;
|
||||
|
||||
/**
|
||||
* @phpstan-template TEnum of \UnitEnum
|
||||
* @phpstan-template TRaw of int|string
|
||||
* @phpstan-implements StateMap<TEnum, TRaw>
|
||||
*/
|
||||
class EnumFromRawStateMap implements StateMap{
|
||||
/**
|
||||
* @var int[]
|
||||
* @phpstan-var array<int, TRaw>
|
||||
*/
|
||||
private array $enumToValue = [];
|
||||
|
||||
/**
|
||||
* @var \UnitEnum[]
|
||||
* @phpstan-var array<TRaw, TEnum>
|
||||
*/
|
||||
private array $valueToEnum = [];
|
||||
|
||||
/**
|
||||
* @phpstan-param class-string<TEnum> $class
|
||||
* @phpstan-param \Closure(TEnum) : TRaw $mapper
|
||||
* @phpstan-param ?\Closure(TEnum) : list<TRaw> $aliasMapper
|
||||
*/
|
||||
public function __construct(
|
||||
string $class,
|
||||
\Closure $mapper,
|
||||
?\Closure $aliasMapper = null
|
||||
){
|
||||
foreach($class::cases() as $case){
|
||||
$int = $mapper($case);
|
||||
$this->valueToEnum[$int] = $case;
|
||||
$this->enumToValue[spl_object_id($case)] = $int;
|
||||
|
||||
if($aliasMapper !== null){
|
||||
$aliases = $aliasMapper($case);
|
||||
foreach($aliases as $alias){
|
||||
$this->valueToEnum[$alias] = $case;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Workaround PHPStan too-specific literal type inference - if it ever gets fixed we can get rid of these functions
|
||||
*
|
||||
* @phpstan-template TEnum_ of \UnitEnum
|
||||
* @phpstan-param class-string<TEnum_> $class
|
||||
* @param \Closure(TEnum_) : string $mapper
|
||||
* @param ?\Closure(TEnum_) : list<string> $aliasMapper
|
||||
*
|
||||
* @phpstan-return EnumFromRawStateMap<TEnum_, string>
|
||||
*/
|
||||
public static function string(string $class, \Closure $mapper, ?\Closure $aliasMapper = null) : self{ return new self($class, $mapper, $aliasMapper); }
|
||||
|
||||
/**
|
||||
* Workaround PHPStan too-specific literal type inference - if it ever gets fixed we can get rid of these functions
|
||||
*
|
||||
* @phpstan-template TEnum_ of \UnitEnum
|
||||
* @phpstan-param class-string<TEnum_> $class
|
||||
* @param \Closure(TEnum_) : int $mapper
|
||||
* @param ?\Closure(TEnum_) : list<int> $aliasMapper
|
||||
*
|
||||
* @phpstan-return EnumFromRawStateMap<TEnum_, int>
|
||||
*/
|
||||
public static function int(string $class, \Closure $mapper, ?\Closure $aliasMapper = null) : self{ return new self($class, $mapper, $aliasMapper); }
|
||||
|
||||
public function getRawToValueMap() : array{
|
||||
return $this->valueToEnum;
|
||||
}
|
||||
|
||||
public function valueToRaw(mixed $value) : int|string{
|
||||
return $this->enumToValue[spl_object_id($value)];
|
||||
}
|
||||
|
||||
public function rawToValue(int|string $raw) : ?\UnitEnum{
|
||||
return $this->valueToEnum[$raw] ?? null;
|
||||
}
|
||||
|
||||
public function printableValue(mixed $value) : string{
|
||||
return $value::class . "::" . $value->name;
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\block\convert\property;
|
||||
|
||||
/**
|
||||
* In PM we treat head/body as a bool and berries/no berries as a second bool.
|
||||
* However, Bedrock doesn't have IDs to represent a separate head/body without berries, so this enum lets us use an
|
||||
* EnumFromStringProperty to deal with this using special getter/setter logic.
|
||||
*/
|
||||
enum FlattenedCaveVinesVariant : string{
|
||||
case NO_BERRIES = "";
|
||||
case HEAD_WITH_BERRIES = "_head_with_berries";
|
||||
case BODY_WITH_BERRIES = "_body_with_berries";
|
||||
}
|
104
src/data/bedrock/block/convert/property/IntFromRawStateMap.php
Normal file
104
src/data/bedrock/block/convert/property/IntFromRawStateMap.php
Normal file
@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\block\convert\property;
|
||||
|
||||
use function array_flip;
|
||||
use function is_array;
|
||||
|
||||
/**
|
||||
* @phpstan-template TRaw of int|string
|
||||
* @phpstan-implements StateMap<int, TRaw>
|
||||
*/
|
||||
class IntFromRawStateMap implements StateMap{
|
||||
|
||||
/**
|
||||
* @var int[]
|
||||
* @phpstan-var array<TRaw, int>
|
||||
*/
|
||||
private array $deserializeMap;
|
||||
|
||||
/**
|
||||
* Constructs a bidirectional mapping, given a mapping of internal values -> serialized values, and an optional set
|
||||
* of aliases per internal value (used for deserializing invalid serialized values).
|
||||
*
|
||||
* @param (int|string)[] $serializeMap
|
||||
* @param (int|int[])|(string|string[]) $deserializeAliases
|
||||
*
|
||||
* @phpstan-param array<int, TRaw> $serializeMap
|
||||
* @phpstan-param array<int, TRaw|list<TRaw>> $deserializeAliases
|
||||
*/
|
||||
public function __construct(
|
||||
private array $serializeMap,
|
||||
array $deserializeAliases = []
|
||||
){
|
||||
$this->deserializeMap = array_flip($this->serializeMap);
|
||||
foreach($deserializeAliases as $pmValue => $mcValues){
|
||||
if(!is_array($mcValues)){
|
||||
$this->deserializeMap[$mcValues] = $pmValue;
|
||||
}else{
|
||||
foreach($mcValues as $mcValue){
|
||||
$this->deserializeMap[$mcValue] = $pmValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int[] $serializeMap
|
||||
* @param (int|int[]) $deserializeAliases
|
||||
*
|
||||
* @phpstan-param array<int, int> $serializeMap
|
||||
* @phpstan-param array<int, int|list<int>> $deserializeAliases
|
||||
*
|
||||
* @phpstan-return self<int>
|
||||
*/
|
||||
public static function int(array $serializeMap, array $deserializeAliases = []) : self{ return new self($serializeMap, $deserializeAliases); }
|
||||
|
||||
/**
|
||||
* @param string[] $serializeMap
|
||||
* @param (string|string[]) $deserializeAliases
|
||||
*
|
||||
* @phpstan-param array<int, string> $serializeMap
|
||||
* @phpstan-param array<int, string|list<string>> $deserializeAliases
|
||||
*
|
||||
* @phpstan-return self<string>
|
||||
*/
|
||||
public static function string(array $serializeMap, array $deserializeAliases = []) : self{ return new self($serializeMap, $deserializeAliases); }
|
||||
|
||||
public function getRawToValueMap() : array{
|
||||
return $this->deserializeMap;
|
||||
}
|
||||
|
||||
public function valueToRaw(mixed $value) : int|string{
|
||||
return $this->serializeMap[$value];
|
||||
}
|
||||
|
||||
public function rawToValue(int|string $raw) : mixed{
|
||||
return $this->deserializeMap[$raw] ?? null;
|
||||
}
|
||||
|
||||
public function printableValue(mixed $value) : string{
|
||||
return "$value";
|
||||
}
|
||||
}
|
70
src/data/bedrock/block/convert/property/IntProperty.php
Normal file
70
src/data/bedrock/block/convert/property/IntProperty.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\block\convert\property;
|
||||
|
||||
use pocketmine\data\bedrock\block\convert\BlockStateReader;
|
||||
use pocketmine\data\bedrock\block\convert\BlockStateWriter;
|
||||
use pocketmine\utils\Limits;
|
||||
|
||||
/**
|
||||
* @phpstan-template TBlock of object
|
||||
* @phpstan-implements Property<TBlock>
|
||||
*/
|
||||
final class IntProperty implements Property{
|
||||
/**
|
||||
* @phpstan-param \Closure(TBlock) : int $getter
|
||||
* @phpstan-param \Closure(TBlock, int) : mixed $setter
|
||||
*/
|
||||
public function __construct(
|
||||
private string $name,
|
||||
private int $min,
|
||||
private int $max,
|
||||
private \Closure $getter,
|
||||
private \Closure $setter,
|
||||
private int $offset = 0
|
||||
){
|
||||
if($min > $max){
|
||||
throw new \InvalidArgumentException("Min value cannot be greater than max value");
|
||||
}
|
||||
}
|
||||
|
||||
public function getName() : string{ return $this->name; }
|
||||
|
||||
/**
|
||||
* @phpstan-return self<object>
|
||||
*/
|
||||
public static function unused(string $name, int $serializedValue) : self{
|
||||
return new self($name, Limits::INT32_MIN, Limits::INT32_MAX, fn() => $serializedValue, fn() => null);
|
||||
}
|
||||
|
||||
public function deserialize(object $block, BlockStateReader $in) : void{
|
||||
$value = $in->readBoundedInt($this->name, $this->min, $this->max);
|
||||
($this->setter)($block, $value + $this->offset);
|
||||
}
|
||||
|
||||
public function serialize(object $block, BlockStateWriter $out) : void{
|
||||
$value = ($this->getter)($block);
|
||||
$out->writeInt($this->name, $value - $this->offset);
|
||||
}
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\block\convert\property;
|
||||
|
||||
use pocketmine\data\bedrock\block\convert\BlockStateReader;
|
||||
use pocketmine\data\bedrock\block\convert\BlockStateWriter;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
|
||||
/**
|
||||
* @phpstan-template TBlock of object
|
||||
* @phpstan-template TOption of int|\UnitEnum
|
||||
* @phpstan-implements Property<TBlock>
|
||||
*/
|
||||
class OptionSetFromIntProperty implements Property{
|
||||
|
||||
private int $maxValue = 0;
|
||||
|
||||
/**
|
||||
* @phpstan-param StateMap<TOption, int> $map
|
||||
* @phpstan-param \Closure(TBlock) : array<TOption> $getter
|
||||
* @phpstan-param \Closure(TBlock, array<TOption>) : mixed $setter
|
||||
*/
|
||||
public function __construct(
|
||||
private string $name,
|
||||
private StateMap $map,
|
||||
private \Closure $getter,
|
||||
private \Closure $setter
|
||||
){
|
||||
$flagsToCases = $this->map->getRawToValueMap();
|
||||
foreach($flagsToCases as $possibleFlag => $option){
|
||||
if(($this->maxValue & $possibleFlag) !== 0){
|
||||
foreach($flagsToCases as $otherFlag => $otherOption){
|
||||
if(($possibleFlag & $otherFlag) === $otherFlag && $otherOption !== $option){
|
||||
$printableOption = $this->map->printableValue($option);
|
||||
$printableOtherOption = $this->map->printableValue($otherOption);
|
||||
throw new \InvalidArgumentException("Flag for option $printableOption overlaps with flag for option $printableOtherOption in property $this->name");
|
||||
}
|
||||
}
|
||||
|
||||
throw new AssumptionFailedError("Unreachable");
|
||||
}
|
||||
|
||||
$this->maxValue |= $possibleFlag;
|
||||
}
|
||||
}
|
||||
|
||||
public function getName() : string{ return $this->name; }
|
||||
|
||||
public function deserialize(object $block, BlockStateReader $in) : void{
|
||||
$flags = $in->readBoundedInt($this->name, 0, $this->maxValue);
|
||||
|
||||
$value = [];
|
||||
foreach($this->map->getRawToValueMap() as $possibleFlag => $option){
|
||||
if(($flags & $possibleFlag) === $possibleFlag){
|
||||
$value[] = $option;
|
||||
}
|
||||
}
|
||||
|
||||
($this->setter)($block, $value);
|
||||
}
|
||||
|
||||
public function serialize(object $block, BlockStateWriter $out) : void{
|
||||
$flags = 0;
|
||||
|
||||
$value = ($this->getter)($block);
|
||||
foreach($value as $option){
|
||||
$flags |= $this->map->valueToRaw($option);
|
||||
}
|
||||
|
||||
$out->writeInt($this->name, $flags);
|
||||
}
|
||||
}
|
44
src/data/bedrock/block/convert/property/Property.php
Normal file
44
src/data/bedrock/block/convert/property/Property.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\block\convert\property;
|
||||
|
||||
use pocketmine\data\bedrock\block\convert\BlockStateReader;
|
||||
use pocketmine\data\bedrock\block\convert\BlockStateWriter;
|
||||
|
||||
/**
|
||||
* @phpstan-template TBlock of object
|
||||
*/
|
||||
interface Property{
|
||||
public function getName() : string;
|
||||
|
||||
/**
|
||||
* @phpstan-param TBlock $block
|
||||
*/
|
||||
public function deserialize(object $block, BlockStateReader $in) : void;
|
||||
|
||||
/**
|
||||
* @phpstan-param TBlock $block
|
||||
*/
|
||||
public function serialize(object $block, BlockStateWriter $out) : void;
|
||||
}
|
53
src/data/bedrock/block/convert/property/StateMap.php
Normal file
53
src/data/bedrock/block/convert/property/StateMap.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\block\convert\property;
|
||||
|
||||
/**
|
||||
* @phpstan-template TValue
|
||||
* @phpstan-template TRaw of int|string
|
||||
*/
|
||||
interface StateMap{
|
||||
|
||||
/**
|
||||
* @phpstan-return array<TRaw, TValue>
|
||||
*/
|
||||
public function getRawToValueMap() : array;
|
||||
|
||||
/**
|
||||
* @phpstan-param TValue $value
|
||||
* @phpstan-return TRaw
|
||||
*/
|
||||
public function valueToRaw(mixed $value) : int|string;
|
||||
|
||||
/**
|
||||
* @phpstan-param TRaw $raw
|
||||
* @phpstan-return TValue|null
|
||||
*/
|
||||
public function rawToValue(int|string $raw) : mixed;
|
||||
|
||||
/**
|
||||
* @phpstan-param TValue $value
|
||||
*/
|
||||
public function printableValue(mixed $value) : string;
|
||||
}
|
50
src/data/bedrock/block/convert/property/StringProperty.php
Normal file
50
src/data/bedrock/block/convert/property/StringProperty.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\block\convert\property;
|
||||
|
||||
/**
|
||||
* @phpstan-template TBlock of object
|
||||
* @phpstan-extends Property<TBlock>
|
||||
*/
|
||||
interface StringProperty extends Property{
|
||||
/**
|
||||
* @return string[]
|
||||
* @phpstan-return list<string>
|
||||
*/
|
||||
public function getPossibleValues() : array;
|
||||
|
||||
/**
|
||||
* TODO: These are only used for flattened IDs for now, we should expand their use to all properties
|
||||
* in the future and remove the dependencies on BlockStateReader and BlockStateWriter
|
||||
* @phpstan-param TBlock $block
|
||||
*/
|
||||
public function deserializePlain(object $block, string $raw) : void;
|
||||
|
||||
/**
|
||||
* TODO: These are only used for flattened IDs for now, we should expand their use to all properties
|
||||
* in the future and remove the dependencies on BlockStateReader and BlockStateWriter
|
||||
* @phpstan-param TBlock $block
|
||||
*/
|
||||
public function serializePlain(object $block) : string;
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\block\convert\property;
|
||||
|
||||
use pocketmine\data\bedrock\block\convert\BlockStateReader;
|
||||
use pocketmine\data\bedrock\block\convert\BlockStateWriter;
|
||||
use function array_keys;
|
||||
|
||||
/**
|
||||
* @phpstan-template TBlock of object
|
||||
* @phpstan-template TValue of int|\UnitEnum
|
||||
* @phpstan-implements Property<TBlock>
|
||||
*/
|
||||
final class ValueFromIntProperty implements Property{
|
||||
|
||||
/**
|
||||
* @phpstan-param StateMap<TValue, int> $map
|
||||
* @phpstan-param \Closure(TBlock) : TValue $getter
|
||||
* @phpstan-param \Closure(TBlock, TValue) : mixed $setter
|
||||
*/
|
||||
public function __construct(
|
||||
private string $name,
|
||||
private StateMap $map,
|
||||
private \Closure $getter,
|
||||
private \Closure $setter
|
||||
){}
|
||||
|
||||
public function getName() : string{ return $this->name; }
|
||||
|
||||
/**
|
||||
* @return int[]
|
||||
* @phpstan-return list<int>
|
||||
*/
|
||||
public function getPossibleValues() : array{
|
||||
return array_keys($this->map->getRawToValueMap());
|
||||
}
|
||||
|
||||
public function deserialize(object $block, BlockStateReader $in) : void{
|
||||
$raw = $in->readInt($this->name);
|
||||
$value = $this->map->rawToValue($raw);
|
||||
|
||||
if($value === null){
|
||||
throw $in->badValueException($this->name, (string) $raw);
|
||||
}
|
||||
($this->setter)($block, $value);
|
||||
}
|
||||
|
||||
public function serialize(object $block, BlockStateWriter $out) : void{
|
||||
$value = ($this->getter)($block);
|
||||
$raw = $this->map->valueToRaw($value);
|
||||
|
||||
$out->writeInt($this->name, $raw);
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\block\convert\property;
|
||||
|
||||
use pocketmine\data\bedrock\block\BlockStateDeserializeException;
|
||||
use pocketmine\data\bedrock\block\convert\BlockStateReader;
|
||||
use pocketmine\data\bedrock\block\convert\BlockStateWriter;
|
||||
use function array_keys;
|
||||
use function array_map;
|
||||
use function strval;
|
||||
|
||||
/**
|
||||
* @phpstan-template TBlock of object
|
||||
* @phpstan-template TValue of int|\UnitEnum
|
||||
* @phpstan-implements StringProperty<TBlock>
|
||||
*/
|
||||
final class ValueFromStringProperty implements StringProperty{
|
||||
|
||||
/**
|
||||
* @phpstan-param StateMap<TValue, string> $map
|
||||
* @phpstan-param \Closure(TBlock) : TValue $getter
|
||||
* @phpstan-param \Closure(TBlock, TValue) : mixed $setter
|
||||
*/
|
||||
public function __construct(
|
||||
private string $name,
|
||||
private StateMap $map,
|
||||
private \Closure $getter,
|
||||
private \Closure $setter
|
||||
){}
|
||||
|
||||
public function getName() : string{ return $this->name; }
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
* @phpstan-return list<string>
|
||||
*/
|
||||
public function getPossibleValues() : array{
|
||||
//PHP sucks
|
||||
return array_map(strval(...), array_keys($this->map->getRawToValueMap()));
|
||||
}
|
||||
|
||||
public function deserialize(object $block, BlockStateReader $in) : void{
|
||||
$this->deserializePlain($block, $in->readString($this->name));
|
||||
}
|
||||
|
||||
public function deserializePlain(object $block, string $raw) : void{
|
||||
//TODO: duplicated code from BlockStateReader :(
|
||||
$value = $this->map->rawToValue($raw) ?? throw new BlockStateDeserializeException("Property \"$this->name\" has invalid value \"$raw\"");
|
||||
($this->setter)($block, $value);
|
||||
}
|
||||
|
||||
public function serialize(object $block, BlockStateWriter $out) : void{
|
||||
$out->writeString($this->name, $this->serializePlain($block));
|
||||
}
|
||||
|
||||
public function serializePlain(object $block) : string{
|
||||
$value = ($this->getter)($block);
|
||||
return $this->map->valueToRaw($value);
|
||||
}
|
||||
}
|
305
src/data/bedrock/block/convert/property/ValueMappings.php
Normal file
305
src/data/bedrock/block/convert/property/ValueMappings.php
Normal file
@ -0,0 +1,305 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\block\convert\property;
|
||||
|
||||
use pocketmine\block\Bamboo;
|
||||
use pocketmine\block\utils\BellAttachmentType;
|
||||
use pocketmine\block\utils\DirtType;
|
||||
use pocketmine\block\utils\DripleafState;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\FroglightType;
|
||||
use pocketmine\block\utils\LeverFacing;
|
||||
use pocketmine\block\utils\MobHeadType;
|
||||
use pocketmine\block\utils\MushroomBlockType;
|
||||
use pocketmine\data\bedrock\block\BlockLegacyMetadata as LegacyMeta;
|
||||
use pocketmine\data\bedrock\block\BlockStateStringValues as StringValues;
|
||||
use pocketmine\data\bedrock\block\BlockTypeNames as Ids;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\utils\SingletonTrait;
|
||||
|
||||
final class ValueMappings{
|
||||
use SingletonTrait; //???
|
||||
|
||||
/** @phpstan-var EnumFromRawStateMap<DyeColor, string> */
|
||||
public readonly EnumFromRawStateMap $dyeColor;
|
||||
/** @phpstan-var EnumFromRawStateMap<DyeColor, string> */
|
||||
public readonly EnumFromRawStateMap $dyeColorWithSilver;
|
||||
/** @phpstan-var EnumFromRawStateMap<MobHeadType, string> */
|
||||
public readonly EnumFromRawStateMap $mobHeadType;
|
||||
/** @phpstan-var EnumFromRawStateMap<FroglightType, string> */
|
||||
public readonly EnumFromRawStateMap $froglightType;
|
||||
/** @phpstan-var EnumFromRawStateMap<DirtType, string> */
|
||||
public readonly EnumFromRawStateMap $dirtType;
|
||||
|
||||
/** @phpstan-var EnumFromRawStateMap<DripleafState, string> */
|
||||
public readonly EnumFromRawStateMap $dripleafState;
|
||||
/** @phpstan-var EnumFromRawStateMap<BellAttachmentType, string> */
|
||||
public readonly EnumFromRawStateMap $bellAttachmentType;
|
||||
/** @phpstan-var EnumFromRawStateMap<LeverFacing, string> */
|
||||
public readonly EnumFromRawStateMap $leverFacing;
|
||||
|
||||
/** @phpstan-var EnumFromRawStateMap<MushroomBlockType, int> */
|
||||
public readonly EnumFromRawStateMap $mushroomBlockType;
|
||||
|
||||
/** @phpstan-var IntFromRawStateMap<string> */
|
||||
public readonly IntFromRawStateMap $cardinalDirection;
|
||||
/** @phpstan-var IntFromRawStateMap<string> */
|
||||
public readonly IntFromRawStateMap $blockFace;
|
||||
/** @phpstan-var IntFromRawStateMap<string> */
|
||||
public readonly IntFromRawStateMap $pillarAxis;
|
||||
/** @phpstan-var IntFromRawStateMap<string> */
|
||||
public readonly IntFromRawStateMap $torchFacing;
|
||||
/** @phpstan-var IntFromRawStateMap<string> */
|
||||
public readonly IntFromRawStateMap $portalAxis;
|
||||
/** @phpstan-var IntFromRawStateMap<string> */
|
||||
public readonly IntFromRawStateMap $bambooLeafSize;
|
||||
|
||||
/** @phpstan-var IntFromRawStateMap<int> */
|
||||
public readonly IntFromRawStateMap $horizontalFacing5Minus;
|
||||
/** @phpstan-var IntFromRawStateMap<int> */
|
||||
public readonly IntFromRawStateMap $horizontalFacingSWNE;
|
||||
/** @phpstan-var IntFromRawStateMap<int> */
|
||||
public readonly IntFromRawStateMap $horizontalFacingSWNEInverted;
|
||||
/** @phpstan-var IntFromRawStateMap<int> */
|
||||
public readonly IntFromRawStateMap $horizontalFacingCoral;
|
||||
/** @phpstan-var IntFromRawStateMap<int> */
|
||||
public readonly IntFromRawStateMap $horizontalFacingClassic;
|
||||
/** @phpstan-var IntFromRawStateMap<int> */
|
||||
public readonly IntFromRawStateMap $facing;
|
||||
/** @phpstan-var IntFromRawStateMap<int> */
|
||||
public readonly IntFromRawStateMap $facingEndRod;
|
||||
/** @phpstan-var IntFromRawStateMap<int> */
|
||||
public readonly IntFromRawStateMap $coralAxis;
|
||||
|
||||
/** @phpstan-var IntFromRawStateMap<int> */
|
||||
public readonly IntFromRawStateMap $facingExceptDown;
|
||||
/** @phpstan-var IntFromRawStateMap<int> */
|
||||
public readonly IntFromRawStateMap $facingExceptUp;
|
||||
/** @phpstan-var IntFromRawStateMap<int> */
|
||||
public readonly IntFromRawStateMap $facingStem;
|
||||
|
||||
public function __construct(){
|
||||
//flattened ID components - we can't generate constants for these
|
||||
$this->dyeColor = EnumFromRawStateMap::string(DyeColor::class, fn(DyeColor $case) => match ($case) {
|
||||
DyeColor::BLACK => "black",
|
||||
DyeColor::BLUE => "blue",
|
||||
DyeColor::BROWN => "brown",
|
||||
DyeColor::CYAN => "cyan",
|
||||
DyeColor::GRAY => "gray",
|
||||
DyeColor::GREEN => "green",
|
||||
DyeColor::LIGHT_BLUE => "light_blue",
|
||||
DyeColor::LIGHT_GRAY => "light_gray",
|
||||
DyeColor::LIME => "lime",
|
||||
DyeColor::MAGENTA => "magenta",
|
||||
DyeColor::ORANGE => "orange",
|
||||
DyeColor::PINK => "pink",
|
||||
DyeColor::PURPLE => "purple",
|
||||
DyeColor::RED => "red",
|
||||
DyeColor::WHITE => "white",
|
||||
DyeColor::YELLOW => "yellow"
|
||||
});
|
||||
$this->dyeColorWithSilver = EnumFromRawStateMap::string(DyeColor::class, fn(DyeColor $case) => match ($case) {
|
||||
DyeColor::LIGHT_GRAY => "silver",
|
||||
default => $this->dyeColor->valueToRaw($case)
|
||||
});
|
||||
|
||||
$this->mobHeadType = EnumFromRawStateMap::string(MobHeadType::class, fn(MobHeadType $case) => match ($case) {
|
||||
MobHeadType::CREEPER => Ids::CREEPER_HEAD,
|
||||
MobHeadType::DRAGON => Ids::DRAGON_HEAD,
|
||||
MobHeadType::PIGLIN => Ids::PIGLIN_HEAD,
|
||||
MobHeadType::PLAYER => Ids::PLAYER_HEAD,
|
||||
MobHeadType::SKELETON => Ids::SKELETON_SKULL,
|
||||
MobHeadType::WITHER_SKELETON => Ids::WITHER_SKELETON_SKULL,
|
||||
MobHeadType::ZOMBIE => Ids::ZOMBIE_HEAD
|
||||
});
|
||||
$this->froglightType = EnumFromRawStateMap::string(FroglightType::class, fn(FroglightType $case) => match ($case) {
|
||||
FroglightType::OCHRE => Ids::OCHRE_FROGLIGHT,
|
||||
FroglightType::PEARLESCENT => Ids::PEARLESCENT_FROGLIGHT,
|
||||
FroglightType::VERDANT => Ids::VERDANT_FROGLIGHT,
|
||||
});
|
||||
$this->dirtType = EnumFromRawStateMap::string(DirtType::class, fn(DirtType $case) => match ($case) {
|
||||
DirtType::NORMAL => Ids::DIRT,
|
||||
DirtType::COARSE => Ids::COARSE_DIRT,
|
||||
DirtType::ROOTED => Ids::DIRT_WITH_ROOTS,
|
||||
});
|
||||
|
||||
//state value mappings
|
||||
$this->dripleafState = EnumFromRawStateMap::string(DripleafState::class, fn(DripleafState $case) => match ($case) {
|
||||
DripleafState::STABLE => StringValues::BIG_DRIPLEAF_TILT_NONE,
|
||||
DripleafState::UNSTABLE => StringValues::BIG_DRIPLEAF_TILT_UNSTABLE,
|
||||
DripleafState::PARTIAL_TILT => StringValues::BIG_DRIPLEAF_TILT_PARTIAL_TILT,
|
||||
DripleafState::FULL_TILT => StringValues::BIG_DRIPLEAF_TILT_FULL_TILT
|
||||
});
|
||||
$this->bellAttachmentType = EnumFromRawStateMap::string(BellAttachmentType::class, fn(BellAttachmentType $case) => match ($case) {
|
||||
BellAttachmentType::FLOOR => StringValues::ATTACHMENT_STANDING,
|
||||
BellAttachmentType::CEILING => StringValues::ATTACHMENT_HANGING,
|
||||
BellAttachmentType::ONE_WALL => StringValues::ATTACHMENT_SIDE,
|
||||
BellAttachmentType::TWO_WALLS => StringValues::ATTACHMENT_MULTIPLE,
|
||||
});
|
||||
$this->leverFacing = EnumFromRawStateMap::string(LeverFacing::class, fn(LeverFacing $case) => match ($case) {
|
||||
LeverFacing::DOWN_AXIS_Z => StringValues::LEVER_DIRECTION_DOWN_NORTH_SOUTH,
|
||||
LeverFacing::DOWN_AXIS_X => StringValues::LEVER_DIRECTION_DOWN_EAST_WEST,
|
||||
LeverFacing::UP_AXIS_Z => StringValues::LEVER_DIRECTION_UP_NORTH_SOUTH,
|
||||
LeverFacing::UP_AXIS_X => StringValues::LEVER_DIRECTION_UP_EAST_WEST,
|
||||
LeverFacing::NORTH => StringValues::LEVER_DIRECTION_NORTH,
|
||||
LeverFacing::SOUTH => StringValues::LEVER_DIRECTION_SOUTH,
|
||||
LeverFacing::WEST => StringValues::LEVER_DIRECTION_WEST,
|
||||
LeverFacing::EAST => StringValues::LEVER_DIRECTION_EAST
|
||||
});
|
||||
|
||||
$this->mushroomBlockType = EnumFromRawStateMap::int(
|
||||
MushroomBlockType::class,
|
||||
fn(MushroomBlockType $case) => match ($case) {
|
||||
MushroomBlockType::PORES => LegacyMeta::MUSHROOM_BLOCK_ALL_PORES,
|
||||
MushroomBlockType::CAP_NORTHWEST => LegacyMeta::MUSHROOM_BLOCK_CAP_NORTHWEST_CORNER,
|
||||
MushroomBlockType::CAP_NORTH => LegacyMeta::MUSHROOM_BLOCK_CAP_NORTH_SIDE,
|
||||
MushroomBlockType::CAP_NORTHEAST => LegacyMeta::MUSHROOM_BLOCK_CAP_NORTHEAST_CORNER,
|
||||
MushroomBlockType::CAP_WEST => LegacyMeta::MUSHROOM_BLOCK_CAP_WEST_SIDE,
|
||||
MushroomBlockType::CAP_MIDDLE => LegacyMeta::MUSHROOM_BLOCK_CAP_TOP_ONLY,
|
||||
MushroomBlockType::CAP_EAST => LegacyMeta::MUSHROOM_BLOCK_CAP_EAST_SIDE,
|
||||
MushroomBlockType::CAP_SOUTHWEST => LegacyMeta::MUSHROOM_BLOCK_CAP_SOUTHWEST_CORNER,
|
||||
MushroomBlockType::CAP_SOUTH => LegacyMeta::MUSHROOM_BLOCK_CAP_SOUTH_SIDE,
|
||||
MushroomBlockType::CAP_SOUTHEAST => LegacyMeta::MUSHROOM_BLOCK_CAP_SOUTHEAST_CORNER,
|
||||
MushroomBlockType::ALL_CAP => LegacyMeta::MUSHROOM_BLOCK_ALL_CAP,
|
||||
},
|
||||
fn(MushroomBlockType $case) => match ($case) {
|
||||
MushroomBlockType::ALL_CAP => [11, 12, 13],
|
||||
default => []
|
||||
}
|
||||
);
|
||||
|
||||
$this->cardinalDirection = IntFromRawStateMap::string([
|
||||
Facing::NORTH => StringValues::MC_CARDINAL_DIRECTION_NORTH,
|
||||
Facing::SOUTH => StringValues::MC_CARDINAL_DIRECTION_SOUTH,
|
||||
Facing::WEST => StringValues::MC_CARDINAL_DIRECTION_WEST,
|
||||
Facing::EAST => StringValues::MC_CARDINAL_DIRECTION_EAST,
|
||||
]);
|
||||
$this->blockFace = IntFromRawStateMap::string([
|
||||
Facing::DOWN => StringValues::MC_BLOCK_FACE_DOWN,
|
||||
Facing::UP => StringValues::MC_BLOCK_FACE_UP,
|
||||
Facing::NORTH => StringValues::MC_BLOCK_FACE_NORTH,
|
||||
Facing::SOUTH => StringValues::MC_BLOCK_FACE_SOUTH,
|
||||
Facing::WEST => StringValues::MC_BLOCK_FACE_WEST,
|
||||
Facing::EAST => StringValues::MC_BLOCK_FACE_EAST,
|
||||
]);
|
||||
$this->pillarAxis = IntFromRawStateMap::string([
|
||||
Axis::X => StringValues::PILLAR_AXIS_X,
|
||||
Axis::Y => StringValues::PILLAR_AXIS_Y,
|
||||
Axis::Z => StringValues::PILLAR_AXIS_Z
|
||||
]);
|
||||
$this->torchFacing = IntFromRawStateMap::string([
|
||||
//TODO: horizontal directions are flipped (MCPE bug: https://bugs.mojang.com/browse/MCPE-152036)
|
||||
Facing::WEST => StringValues::TORCH_FACING_DIRECTION_EAST,
|
||||
Facing::SOUTH => StringValues::TORCH_FACING_DIRECTION_NORTH,
|
||||
Facing::NORTH => StringValues::TORCH_FACING_DIRECTION_SOUTH,
|
||||
Facing::UP => StringValues::TORCH_FACING_DIRECTION_TOP,
|
||||
Facing::EAST => StringValues::TORCH_FACING_DIRECTION_WEST,
|
||||
], deserializeAliases: [
|
||||
Facing::UP => StringValues::TORCH_FACING_DIRECTION_UNKNOWN //should be illegal, but still supported
|
||||
]);
|
||||
$this->portalAxis = IntFromRawStateMap::string([
|
||||
Axis::X => StringValues::PORTAL_AXIS_X,
|
||||
Axis::Z => StringValues::PORTAL_AXIS_Z,
|
||||
], deserializeAliases: [
|
||||
Axis::X => StringValues::PORTAL_AXIS_UNKNOWN,
|
||||
]);
|
||||
$this->bambooLeafSize = IntFromRawStateMap::string([
|
||||
Bamboo::NO_LEAVES => StringValues::BAMBOO_LEAF_SIZE_NO_LEAVES,
|
||||
Bamboo::SMALL_LEAVES => StringValues::BAMBOO_LEAF_SIZE_SMALL_LEAVES,
|
||||
Bamboo::LARGE_LEAVES => StringValues::BAMBOO_LEAF_SIZE_LARGE_LEAVES,
|
||||
]);
|
||||
|
||||
$this->horizontalFacing5Minus = IntFromRawStateMap::int([
|
||||
Facing::EAST => 0,
|
||||
Facing::WEST => 1,
|
||||
Facing::SOUTH => 2,
|
||||
Facing::NORTH => 3
|
||||
]);
|
||||
$this->horizontalFacingSWNE = IntFromRawStateMap::int([
|
||||
Facing::SOUTH => 0,
|
||||
Facing::WEST => 1,
|
||||
Facing::NORTH => 2,
|
||||
Facing::EAST => 3
|
||||
]);
|
||||
$this->horizontalFacingSWNEInverted = IntFromRawStateMap::int([
|
||||
Facing::NORTH => 0,
|
||||
Facing::EAST => 1,
|
||||
Facing::SOUTH => 2,
|
||||
Facing::WEST => 3,
|
||||
]);
|
||||
$this->horizontalFacingCoral = IntFromRawStateMap::int([
|
||||
Facing::WEST => 0,
|
||||
Facing::EAST => 1,
|
||||
Facing::NORTH => 2,
|
||||
Facing::SOUTH => 3
|
||||
]);
|
||||
$horizontalFacingClassicTable = [
|
||||
Facing::NORTH => 2,
|
||||
Facing::SOUTH => 3,
|
||||
Facing::WEST => 4,
|
||||
Facing::EAST => 5
|
||||
];
|
||||
$this->horizontalFacingClassic = IntFromRawStateMap::int($horizontalFacingClassicTable, deserializeAliases: [
|
||||
Facing::NORTH => [0, 1] //should be illegal but still technically possible
|
||||
]);
|
||||
|
||||
$this->facing = IntFromRawStateMap::int([
|
||||
Facing::DOWN => 0,
|
||||
Facing::UP => 1
|
||||
] + $horizontalFacingClassicTable);
|
||||
|
||||
//end rods have all the horizontal facing values opposite to classic facing
|
||||
$this->facingEndRod = IntFromRawStateMap::int([
|
||||
Facing::DOWN => 0,
|
||||
Facing::UP => 1,
|
||||
Facing::SOUTH => 2,
|
||||
Facing::NORTH => 3,
|
||||
Facing::EAST => 4,
|
||||
Facing::WEST => 5,
|
||||
]);
|
||||
|
||||
$this->coralAxis = IntFromRawStateMap::int([
|
||||
Axis::X => 0,
|
||||
Axis::Z => 1,
|
||||
]);
|
||||
|
||||
//TODO: shitty copy pasta job, we can do this better but this is good enough for now
|
||||
$this->facingExceptDown = IntFromRawStateMap::int(
|
||||
[Facing::UP => 1] + $horizontalFacingClassicTable,
|
||||
deserializeAliases: [Facing::UP => 0]);
|
||||
$this->facingExceptUp = IntFromRawStateMap::int(
|
||||
[Facing::DOWN => 0] + $horizontalFacingClassicTable,
|
||||
deserializeAliases: [Facing::DOWN => 1]
|
||||
);
|
||||
|
||||
//In PM, we use Facing::UP to indicate that the stem is not attached to a pumpkin/melon, since this makes the
|
||||
//most intuitive sense (the stem is pointing at the sky). However, Bedrock uses the DOWN state for this, which
|
||||
//is absurd, and I refuse to make our API similarly absurd.
|
||||
$this->facingStem = IntFromRawStateMap::int(
|
||||
[Facing::UP => 0] + $horizontalFacingClassicTable,
|
||||
deserializeAliases: [Facing::UP => 1]
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\block\convert\property;
|
||||
|
||||
use pocketmine\block\utils\WallConnectionType;
|
||||
use pocketmine\data\bedrock\block\BlockStateStringValues;
|
||||
|
||||
/**
|
||||
* Internally we use null for no connections, but accepting this in the mapping code would require a fair amount of
|
||||
* extra complexity for this one case. This shim allows us to use the regular systems for handling walls.
|
||||
* TODO: get rid of this in PM6 and make the internal enum have a NONE case
|
||||
*/
|
||||
enum WallConnectionTypeShim{
|
||||
case NONE;
|
||||
case SHORT;
|
||||
case TALL;
|
||||
|
||||
/**
|
||||
* TODO: Would've just put this as enum values, but enum backing values can't reference constants in other files in
|
||||
* PHP 8.1 :(
|
||||
*/
|
||||
public function getValue() : string{
|
||||
return match($this){
|
||||
self::NONE => BlockStateStringValues::WALL_CONNECTION_TYPE_EAST_NONE,
|
||||
self::SHORT => BlockStateStringValues::WALL_CONNECTION_TYPE_EAST_SHORT,
|
||||
self::TALL => BlockStateStringValues::WALL_CONNECTION_TYPE_EAST_TALL,
|
||||
};
|
||||
}
|
||||
|
||||
public function deserialize() : ?WallConnectionType{
|
||||
return match($this){
|
||||
self::NONE => null,
|
||||
self::SHORT => WallConnectionType::SHORT,
|
||||
self::TALL => WallConnectionType::TALL,
|
||||
};
|
||||
}
|
||||
|
||||
public static function serialize(?WallConnectionType $value) : self{
|
||||
return match($value){
|
||||
null => self::NONE,
|
||||
WallConnectionType::SHORT => self::SHORT,
|
||||
WallConnectionType::TALL => self::TALL,
|
||||
};
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ namespace pocketmine\data\bedrock\item;
|
||||
use pocketmine\block\Bed;
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\CopperDoor;
|
||||
use pocketmine\block\tile\Banner as TileBanner;
|
||||
use pocketmine\block\utils\CopperOxidation;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\VanillaBlocks as Blocks;
|
||||
@ -46,6 +47,7 @@ use pocketmine\item\Potion;
|
||||
use pocketmine\item\SplashPotion;
|
||||
use pocketmine\item\SuspiciousStew;
|
||||
use pocketmine\item\VanillaItems as Items;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
|
||||
final class ItemSerializerDeserializerRegistrar{
|
||||
|
||||
@ -165,6 +167,7 @@ final class ItemSerializerDeserializerRegistrar{
|
||||
*/
|
||||
private function register1to1ItemMappings() : void{
|
||||
$this->map1to1Item(Ids::ACACIA_BOAT, Items::ACACIA_BOAT());
|
||||
$this->map1to1Item(Ids::ACACIA_HANGING_SIGN, Items::ACACIA_HANGING_SIGN());
|
||||
$this->map1to1Item(Ids::ACACIA_SIGN, Items::ACACIA_SIGN());
|
||||
$this->map1to1Item(Ids::AMETHYST_SHARD, Items::AMETHYST_SHARD());
|
||||
$this->map1to1Item(Ids::APPLE, Items::APPLE());
|
||||
@ -174,6 +177,7 @@ final class ItemSerializerDeserializerRegistrar{
|
||||
$this->map1to1Item(Ids::BEETROOT_SEEDS, Items::BEETROOT_SEEDS());
|
||||
$this->map1to1Item(Ids::BEETROOT_SOUP, Items::BEETROOT_SOUP());
|
||||
$this->map1to1Item(Ids::BIRCH_BOAT, Items::BIRCH_BOAT());
|
||||
$this->map1to1Item(Ids::BIRCH_HANGING_SIGN, Items::BIRCH_HANGING_SIGN());
|
||||
$this->map1to1Item(Ids::BIRCH_SIGN, Items::BIRCH_SIGN());
|
||||
$this->map1to1Item(Ids::BLAZE_POWDER, Items::BLAZE_POWDER());
|
||||
$this->map1to1Item(Ids::BLAZE_ROD, Items::BLAZE_ROD());
|
||||
@ -192,6 +196,7 @@ final class ItemSerializerDeserializerRegistrar{
|
||||
$this->map1to1Item(Ids::CHAINMAIL_HELMET, Items::CHAINMAIL_HELMET());
|
||||
$this->map1to1Item(Ids::CHAINMAIL_LEGGINGS, Items::CHAINMAIL_LEGGINGS());
|
||||
$this->map1to1Item(Ids::CHARCOAL, Items::CHARCOAL());
|
||||
$this->map1to1Item(Ids::CHERRY_HANGING_SIGN, Items::CHERRY_HANGING_SIGN());
|
||||
$this->map1to1Item(Ids::CHERRY_SIGN, Items::CHERRY_SIGN());
|
||||
$this->map1to1Item(Ids::CHICKEN, Items::RAW_CHICKEN());
|
||||
$this->map1to1Item(Ids::CHORUS_FRUIT, Items::CHORUS_FRUIT());
|
||||
@ -211,8 +216,10 @@ final class ItemSerializerDeserializerRegistrar{
|
||||
$this->map1to1Item(Ids::COOKED_SALMON, Items::COOKED_SALMON());
|
||||
$this->map1to1Item(Ids::COOKIE, Items::COOKIE());
|
||||
$this->map1to1Item(Ids::COPPER_INGOT, Items::COPPER_INGOT());
|
||||
$this->map1to1Item(Ids::CRIMSON_HANGING_SIGN, Items::CRIMSON_HANGING_SIGN());
|
||||
$this->map1to1Item(Ids::CRIMSON_SIGN, Items::CRIMSON_SIGN());
|
||||
$this->map1to1Item(Ids::DARK_OAK_BOAT, Items::DARK_OAK_BOAT());
|
||||
$this->map1to1Item(Ids::DARK_OAK_HANGING_SIGN, Items::DARK_OAK_HANGING_SIGN());
|
||||
$this->map1to1Item(Ids::DARK_OAK_SIGN, Items::DARK_OAK_SIGN());
|
||||
$this->map1to1Item(Ids::DIAMOND, Items::DIAMOND());
|
||||
$this->map1to1Item(Ids::DIAMOND_AXE, Items::DIAMOND_AXE());
|
||||
@ -281,6 +288,7 @@ final class ItemSerializerDeserializerRegistrar{
|
||||
$this->map1to1Item(Ids::IRON_SHOVEL, Items::IRON_SHOVEL());
|
||||
$this->map1to1Item(Ids::IRON_SWORD, Items::IRON_SWORD());
|
||||
$this->map1to1Item(Ids::JUNGLE_BOAT, Items::JUNGLE_BOAT());
|
||||
$this->map1to1Item(Ids::JUNGLE_HANGING_SIGN, Items::JUNGLE_HANGING_SIGN());
|
||||
$this->map1to1Item(Ids::JUNGLE_SIGN, Items::JUNGLE_SIGN());
|
||||
$this->map1to1Item(Ids::LAPIS_LAZULI, Items::LAPIS_LAZULI());
|
||||
$this->map1to1Item(Ids::LAVA_BUCKET, Items::LAVA_BUCKET());
|
||||
@ -291,6 +299,7 @@ final class ItemSerializerDeserializerRegistrar{
|
||||
$this->map1to1Item(Ids::LEATHER_LEGGINGS, Items::LEATHER_PANTS());
|
||||
$this->map1to1Item(Ids::MAGMA_CREAM, Items::MAGMA_CREAM());
|
||||
$this->map1to1Item(Ids::MANGROVE_BOAT, Items::MANGROVE_BOAT());
|
||||
$this->map1to1Item(Ids::MANGROVE_HANGING_SIGN, Items::MANGROVE_HANGING_SIGN());
|
||||
$this->map1to1Item(Ids::MANGROVE_SIGN, Items::MANGROVE_SIGN());
|
||||
$this->map1to1Item(Ids::MELON_SEEDS, Items::MELON_SEEDS());
|
||||
$this->map1to1Item(Ids::MELON_SLICE, Items::MELON());
|
||||
@ -334,8 +343,10 @@ final class ItemSerializerDeserializerRegistrar{
|
||||
$this->map1to1Item(Ids::NETHERITE_SWORD, Items::NETHERITE_SWORD());
|
||||
$this->map1to1Item(Ids::NETHERITE_UPGRADE_SMITHING_TEMPLATE, Items::NETHERITE_UPGRADE_SMITHING_TEMPLATE());
|
||||
$this->map1to1Item(Ids::OAK_BOAT, Items::OAK_BOAT());
|
||||
$this->map1to1Item(Ids::OAK_HANGING_SIGN, Items::OAK_HANGING_SIGN());
|
||||
$this->map1to1Item(Ids::OAK_SIGN, Items::OAK_SIGN());
|
||||
$this->map1to1Item(Ids::PAINTING, Items::PAINTING());
|
||||
$this->map1to1Item(Ids::PALE_OAK_HANGING_SIGN, Items::PALE_OAK_HANGING_SIGN());
|
||||
$this->map1to1Item(Ids::PALE_OAK_SIGN, Items::PALE_OAK_SIGN());
|
||||
$this->map1to1Item(Ids::PAPER, Items::PAPER());
|
||||
$this->map1to1Item(Ids::PHANTOM_MEMBRANE, Items::PHANTOM_MEMBRANE());
|
||||
@ -376,6 +387,7 @@ final class ItemSerializerDeserializerRegistrar{
|
||||
$this->map1to1Item(Ids::SPIDER_EYE, Items::SPIDER_EYE());
|
||||
$this->map1to1Item(Ids::SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE, Items::SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE());
|
||||
$this->map1to1Item(Ids::SPRUCE_BOAT, Items::SPRUCE_BOAT());
|
||||
$this->map1to1Item(Ids::SPRUCE_HANGING_SIGN, Items::SPRUCE_HANGING_SIGN());
|
||||
$this->map1to1Item(Ids::SPRUCE_SIGN, Items::SPRUCE_SIGN());
|
||||
$this->map1to1Item(Ids::SPYGLASS, Items::SPYGLASS());
|
||||
$this->map1to1Item(Ids::SQUID_SPAWN_EGG, Items::SQUID_SPAWN_EGG());
|
||||
@ -396,6 +408,7 @@ final class ItemSerializerDeserializerRegistrar{
|
||||
$this->map1to1Item(Ids::VEX_ARMOR_TRIM_SMITHING_TEMPLATE, Items::VEX_ARMOR_TRIM_SMITHING_TEMPLATE());
|
||||
$this->map1to1Item(Ids::VILLAGER_SPAWN_EGG, Items::VILLAGER_SPAWN_EGG());
|
||||
$this->map1to1Item(Ids::WARD_ARMOR_TRIM_SMITHING_TEMPLATE, Items::WARD_ARMOR_TRIM_SMITHING_TEMPLATE());
|
||||
$this->map1to1Item(Ids::WARPED_HANGING_SIGN, Items::WARPED_HANGING_SIGN());
|
||||
$this->map1to1Item(Ids::WARPED_SIGN, Items::WARPED_SIGN());
|
||||
$this->map1to1Item(Ids::WATER_BUCKET, Items::WATER_BUCKET());
|
||||
$this->map1to1Item(Ids::WAYFINDER_ARMOR_TRIM_SMITHING_TEMPLATE, Items::WAYFINDER_ARMOR_TRIM_SMITHING_TEMPLATE());
|
||||
@ -487,14 +500,6 @@ final class ItemSerializerDeserializerRegistrar{
|
||||
* in a unified manner.
|
||||
*/
|
||||
private function register1to1ItemWithMetaMappings() : void{
|
||||
$this->map1to1ItemWithMeta(
|
||||
Ids::BANNER,
|
||||
Items::BANNER(),
|
||||
function(Banner $item, int $meta) : void{
|
||||
$item->setColor(DyeColorIdMap::getInstance()->fromInvertedId($meta) ?? throw new ItemTypeDeserializeException("Unknown banner meta $meta"));
|
||||
},
|
||||
fn(Banner $item) => DyeColorIdMap::getInstance()->toInvertedId($item->getColor())
|
||||
);
|
||||
$this->map1to1ItemWithMeta(
|
||||
Ids::GOAT_HORN,
|
||||
Items::GOAT_HORN(),
|
||||
@ -550,6 +555,21 @@ final class ItemSerializerDeserializerRegistrar{
|
||||
$this->deserializer?->map($id, fn() => Items::DYE()->setColor($color));
|
||||
}
|
||||
$this->serializer?->map(Items::DYE(), fn(Dye $item) => new Data(DyeColorIdMap::getInstance()->toItemId($item->getColor())));
|
||||
|
||||
$this->deserializer?->map(Ids::BANNER, function(Data $data) : Item{
|
||||
$type = $data->getTag()?->getInt(TileBanner::TAG_TYPE, TileBanner::TYPE_NORMAL) ?? TileBanner::TYPE_NORMAL;
|
||||
if($type === TileBanner::TYPE_OMINOUS){
|
||||
return Items::OMINOUS_BANNER();
|
||||
}
|
||||
$color = DyeColorIdMap::getInstance()->fromInvertedId($data->getMeta()) ?? throw new ItemTypeDeserializeException("Unknown banner meta " . $data->getMeta());
|
||||
return Items::BANNER()->setColor($color);
|
||||
});
|
||||
$this->serializer?->map(Items::OMINOUS_BANNER(), fn() => new Data(Ids::BANNER, tag: CompoundTag::create()
|
||||
->setInt(TileBanner::TAG_TYPE, TileBanner::TYPE_OMINOUS))
|
||||
);
|
||||
$this->serializer?->map(Items::BANNER(), function(Banner $item) : Data{
|
||||
return new Data(Ids::BANNER, DyeColorIdMap::getInstance()->toInvertedId($item->getColor()));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
65
src/item/HangingSign.php
Normal file
65
src/item/HangingSign.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
|
||||
final class HangingSign extends Item{
|
||||
|
||||
public function __construct(
|
||||
ItemIdentifier $identifier,
|
||||
string $name,
|
||||
private Block $centerPointCeilingVariant,
|
||||
private Block $edgePointCeilingVariant,
|
||||
private Block $wallVariant
|
||||
){
|
||||
parent::__construct($identifier, $name);
|
||||
}
|
||||
|
||||
public function getPlacementBlock(Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : Block{
|
||||
//we don't verify valid placement conditions here, only decide which block to return
|
||||
$result = $face === Facing::DOWN ?
|
||||
$blockReplace->getSide(Facing::UP)->getSupportType(Facing::DOWN) === SupportType::CENTER ?
|
||||
$this->centerPointCeilingVariant :
|
||||
$this->edgePointCeilingVariant
|
||||
: $this->wallVariant;
|
||||
return clone $result;
|
||||
}
|
||||
|
||||
public function getBlock(?int $clickedFace = null) : Block{
|
||||
//we don't have enough information here to decide which ceiling type to use
|
||||
return $clickedFace === Facing::DOWN ? clone $this->centerPointCeilingVariant : clone $this->wallVariant;
|
||||
}
|
||||
|
||||
public function getMaxStackSize() : int{
|
||||
return 16;
|
||||
}
|
||||
|
||||
public function getFuelTime() : int{
|
||||
return 200;
|
||||
}
|
||||
}
|
@ -488,6 +488,10 @@ class Item implements \JsonSerializable{
|
||||
return $this->getBlock()->canBePlaced();
|
||||
}
|
||||
|
||||
public function getPlacementBlock(Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : Block{
|
||||
return $this->getBlock($face);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the block corresponding to this Item.
|
||||
*/
|
||||
|
@ -334,8 +334,20 @@ final class ItemTypeIds{
|
||||
public const RECORD_CREATOR = 20295;
|
||||
public const RECORD_CREATOR_MUSIC_BOX = 20296;
|
||||
public const RECORD_PRECIPICE = 20297;
|
||||
public const OMINOUS_BANNER = 20298;
|
||||
public const ACACIA_HANGING_SIGN = 20299;
|
||||
public const BIRCH_HANGING_SIGN = 20300;
|
||||
public const CHERRY_HANGING_SIGN = 20301;
|
||||
public const CRIMSON_HANGING_SIGN = 20302;
|
||||
public const DARK_OAK_HANGING_SIGN = 20303;
|
||||
public const JUNGLE_HANGING_SIGN = 20304;
|
||||
public const MANGROVE_HANGING_SIGN = 20305;
|
||||
public const OAK_HANGING_SIGN = 20306;
|
||||
public const PALE_OAK_HANGING_SIGN = 20307;
|
||||
public const SPRUCE_HANGING_SIGN = 20308;
|
||||
public const WARPED_HANGING_SIGN = 20309;
|
||||
|
||||
public const FIRST_UNUSED_ITEM_ID = 20298;
|
||||
public const FIRST_UNUSED_ITEM_ID = 20310;
|
||||
|
||||
private static int $nextDynamicId = self::FIRST_UNUSED_ITEM_ID;
|
||||
|
||||
|
@ -1232,6 +1232,7 @@ final class StringToItemParser extends StringToTParser{
|
||||
private static function registerItems(self $result) : void{
|
||||
|
||||
$result->register("acacia_boat", fn() => Items::ACACIA_BOAT());
|
||||
$result->register("acacia_hanging_sign", fn() => Items::ACACIA_HANGING_SIGN());
|
||||
$result->register("amethyst_shard", fn() => Items::AMETHYST_SHARD());
|
||||
$result->register("antidote", fn() => Items::MEDICINE()->setType(MedicineType::ANTIDOTE));
|
||||
$result->register("apple", fn() => Items::APPLE());
|
||||
@ -1246,6 +1247,7 @@ final class StringToItemParser extends StringToTParser{
|
||||
$result->register("beetroot_seeds", fn() => Items::BEETROOT_SEEDS());
|
||||
$result->register("beetroot_soup", fn() => Items::BEETROOT_SOUP());
|
||||
$result->register("birch_boat", fn() => Items::BIRCH_BOAT());
|
||||
$result->register("birch_hanging_sign", fn() => Items::BIRCH_HANGING_SIGN());
|
||||
$result->register("blaze_powder", fn() => Items::BLAZE_POWDER());
|
||||
$result->register("blaze_rod", fn() => Items::BLAZE_ROD());
|
||||
$result->register("bleach", fn() => Items::BLEACH());
|
||||
@ -1307,6 +1309,7 @@ final class StringToItemParser extends StringToTParser{
|
||||
$result->register("chemical_sulphate", fn() => Items::CHEMICAL_SULPHATE());
|
||||
$result->register("chemical_tungsten_chloride", fn() => Items::CHEMICAL_TUNGSTEN_CHLORIDE());
|
||||
$result->register("chemical_water", fn() => Items::CHEMICAL_WATER());
|
||||
$result->register("cherry_hanging_sign", fn() => Items::CHERRY_HANGING_SIGN());
|
||||
$result->register("chicken", fn() => Items::RAW_CHICKEN());
|
||||
$result->register("chorus_fruit", fn() => Items::CHORUS_FRUIT());
|
||||
$result->register("chorus_fruit_popped", fn() => Items::POPPED_CHORUS_FRUIT());
|
||||
@ -1331,7 +1334,9 @@ final class StringToItemParser extends StringToTParser{
|
||||
$result->register("cooked_salmon", fn() => Items::COOKED_SALMON());
|
||||
$result->register("cookie", fn() => Items::COOKIE());
|
||||
$result->register("copper_ingot", fn() => Items::COPPER_INGOT());
|
||||
$result->register("crimson_hanging_sign", fn() => Items::CRIMSON_HANGING_SIGN());
|
||||
$result->register("dark_oak_boat", fn() => Items::DARK_OAK_BOAT());
|
||||
$result->register("dark_oak_hanging_sign", fn() => Items::DARK_OAK_HANGING_SIGN());
|
||||
$result->register("diamond", fn() => Items::DIAMOND());
|
||||
$result->register("diamond_axe", fn() => Items::DIAMOND_AXE());
|
||||
$result->register("diamond_boots", fn() => Items::DIAMOND_BOOTS());
|
||||
@ -1416,6 +1421,7 @@ final class StringToItemParser extends StringToTParser{
|
||||
$result->register("iron_shovel", fn() => Items::IRON_SHOVEL());
|
||||
$result->register("iron_sword", fn() => Items::IRON_SWORD());
|
||||
$result->register("jungle_boat", fn() => Items::JUNGLE_BOAT());
|
||||
$result->register("jungle_hanging_sign", fn() => Items::JUNGLE_HANGING_SIGN());
|
||||
$result->register("lapis_lazuli", fn() => Items::LAPIS_LAZULI());
|
||||
$result->register("lava_bucket", fn() => Items::LAVA_BUCKET());
|
||||
$result->register("leather", fn() => Items::LEATHER());
|
||||
@ -1427,6 +1433,7 @@ final class StringToItemParser extends StringToTParser{
|
||||
$result->register("leather_pants", fn() => Items::LEATHER_PANTS());
|
||||
$result->register("leather_tunic", fn() => Items::LEATHER_TUNIC());
|
||||
$result->register("magma_cream", fn() => Items::MAGMA_CREAM());
|
||||
$result->register("mangrove_hanging_sign", fn() => Items::MANGROVE_HANGING_SIGN());
|
||||
$result->register("melon", fn() => Items::MELON());
|
||||
$result->register("melon_seeds", fn() => Items::MELON_SEEDS());
|
||||
$result->register("melon_slice", fn() => Items::MELON());
|
||||
@ -1458,7 +1465,9 @@ final class StringToItemParser extends StringToTParser{
|
||||
$result->register("netherstar", fn() => Items::NETHER_STAR());
|
||||
$result->register("netherite_upgrade_smithing_template", fn() => Items::NETHERITE_UPGRADE_SMITHING_TEMPLATE());
|
||||
$result->register("oak_boat", fn() => Items::OAK_BOAT());
|
||||
$result->register("oak_hanging_sign", fn() => Items::OAK_HANGING_SIGN());
|
||||
$result->register("painting", fn() => Items::PAINTING());
|
||||
$result->register("pale_oak_hanging_sign", fn() => Items::PALE_OAK_HANGING_SIGN());
|
||||
$result->register("paper", fn() => Items::PAPER());
|
||||
$result->register("phantom_membrane", fn() => Items::PHANTOM_MEMBRANE());
|
||||
$result->register("pitcher_pod", fn() => Items::PITCHER_POD());
|
||||
@ -1532,6 +1541,7 @@ final class StringToItemParser extends StringToTParser{
|
||||
$result->register("spire_armor_trim_smithing_template", fn() => Items::SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE());
|
||||
$result->register("splash_potion", fn() => Items::SPLASH_POTION());
|
||||
$result->register("spruce_boat", fn() => Items::SPRUCE_BOAT());
|
||||
$result->register("spruce_hanging_sign", fn() => Items::SPRUCE_HANGING_SIGN());
|
||||
$result->register("spyglass", fn() => Items::SPYGLASS());
|
||||
$result->register("squid_spawn_egg", fn() => Items::SQUID_SPAWN_EGG());
|
||||
$result->register("steak", fn() => Items::STEAK());
|
||||
@ -1555,6 +1565,7 @@ final class StringToItemParser extends StringToTParser{
|
||||
$result->register("turtle_shell_piece", fn() => Items::SCUTE());
|
||||
$result->register("villager_spawn_egg", fn() => Items::VILLAGER_SPAWN_EGG());
|
||||
$result->register("ward_armor_trim_smithing_template", fn() => Items::WARD_ARMOR_TRIM_SMITHING_TEMPLATE());
|
||||
$result->register("warped_hanging_sign", fn() => Items::WARPED_HANGING_SIGN());
|
||||
$result->register("water_bucket", fn() => Items::WATER_BUCKET());
|
||||
$result->register("wayfinder_armor_trim_smithing_template", fn() => Items::WAYFINDER_ARMOR_TRIM_SMITHING_TEMPLATE());
|
||||
$result->register("wheat", fn() => Items::WHEAT());
|
||||
|
@ -48,6 +48,7 @@ use function strtolower;
|
||||
* @generate-registry-docblock
|
||||
*
|
||||
* @method static Boat ACACIA_BOAT()
|
||||
* @method static HangingSign ACACIA_HANGING_SIGN()
|
||||
* @method static ItemBlockWallOrFloor ACACIA_SIGN()
|
||||
* @method static ItemBlock AIR()
|
||||
* @method static Item AMETHYST_SHARD()
|
||||
@ -60,6 +61,7 @@ use function strtolower;
|
||||
* @method static BeetrootSeeds BEETROOT_SEEDS()
|
||||
* @method static BeetrootSoup BEETROOT_SOUP()
|
||||
* @method static Boat BIRCH_BOAT()
|
||||
* @method static HangingSign BIRCH_HANGING_SIGN()
|
||||
* @method static ItemBlockWallOrFloor BIRCH_SIGN()
|
||||
* @method static Item BLAZE_POWDER()
|
||||
* @method static BlazeRod BLAZE_ROD()
|
||||
@ -116,6 +118,7 @@ use function strtolower;
|
||||
* @method static Item CHEMICAL_SULPHATE()
|
||||
* @method static Item CHEMICAL_TUNGSTEN_CHLORIDE()
|
||||
* @method static Item CHEMICAL_WATER()
|
||||
* @method static HangingSign CHERRY_HANGING_SIGN()
|
||||
* @method static ItemBlockWallOrFloor CHERRY_SIGN()
|
||||
* @method static ChorusFruit CHORUS_FRUIT()
|
||||
* @method static Item CLAY()
|
||||
@ -134,8 +137,10 @@ use function strtolower;
|
||||
* @method static Cookie COOKIE()
|
||||
* @method static Item COPPER_INGOT()
|
||||
* @method static CoralFan CORAL_FAN()
|
||||
* @method static HangingSign CRIMSON_HANGING_SIGN()
|
||||
* @method static ItemBlockWallOrFloor CRIMSON_SIGN()
|
||||
* @method static Boat DARK_OAK_BOAT()
|
||||
* @method static HangingSign DARK_OAK_HANGING_SIGN()
|
||||
* @method static ItemBlockWallOrFloor DARK_OAK_SIGN()
|
||||
* @method static Item DIAMOND()
|
||||
* @method static Axe DIAMOND_AXE()
|
||||
@ -206,6 +211,7 @@ use function strtolower;
|
||||
* @method static Shovel IRON_SHOVEL()
|
||||
* @method static Sword IRON_SWORD()
|
||||
* @method static Boat JUNGLE_BOAT()
|
||||
* @method static HangingSign JUNGLE_HANGING_SIGN()
|
||||
* @method static ItemBlockWallOrFloor JUNGLE_SIGN()
|
||||
* @method static Item LAPIS_LAZULI()
|
||||
* @method static LiquidBucket LAVA_BUCKET()
|
||||
@ -216,6 +222,7 @@ use function strtolower;
|
||||
* @method static Armor LEATHER_TUNIC()
|
||||
* @method static Item MAGMA_CREAM()
|
||||
* @method static Boat MANGROVE_BOAT()
|
||||
* @method static HangingSign MANGROVE_HANGING_SIGN()
|
||||
* @method static ItemBlockWallOrFloor MANGROVE_SIGN()
|
||||
* @method static Medicine MEDICINE()
|
||||
* @method static Melon MELON()
|
||||
@ -241,8 +248,11 @@ use function strtolower;
|
||||
* @method static Item NETHER_QUARTZ()
|
||||
* @method static Item NETHER_STAR()
|
||||
* @method static Boat OAK_BOAT()
|
||||
* @method static HangingSign OAK_HANGING_SIGN()
|
||||
* @method static ItemBlockWallOrFloor OAK_SIGN()
|
||||
* @method static ItemBlockWallOrFloor OMINOUS_BANNER()
|
||||
* @method static PaintingItem PAINTING()
|
||||
* @method static HangingSign PALE_OAK_HANGING_SIGN()
|
||||
* @method static ItemBlockWallOrFloor PALE_OAK_SIGN()
|
||||
* @method static Item PAPER()
|
||||
* @method static Item PHANTOM_MEMBRANE()
|
||||
@ -307,6 +317,7 @@ use function strtolower;
|
||||
* @method static Item SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE()
|
||||
* @method static SplashPotion SPLASH_POTION()
|
||||
* @method static Boat SPRUCE_BOAT()
|
||||
* @method static HangingSign SPRUCE_HANGING_SIGN()
|
||||
* @method static ItemBlockWallOrFloor SPRUCE_SIGN()
|
||||
* @method static Spyglass SPYGLASS()
|
||||
* @method static SpawnEgg SQUID_SPAWN_EGG()
|
||||
@ -328,6 +339,7 @@ use function strtolower;
|
||||
* @method static Item VEX_ARMOR_TRIM_SMITHING_TEMPLATE()
|
||||
* @method static SpawnEgg VILLAGER_SPAWN_EGG()
|
||||
* @method static Item WARD_ARMOR_TRIM_SMITHING_TEMPLATE()
|
||||
* @method static HangingSign WARPED_HANGING_SIGN()
|
||||
* @method static ItemBlockWallOrFloor WARPED_SIGN()
|
||||
* @method static LiquidBucket WATER_BUCKET()
|
||||
* @method static Item WAYFINDER_ARMOR_TRIM_SMITHING_TEMPLATE()
|
||||
@ -397,6 +409,7 @@ final class VanillaItems{
|
||||
self::_registryRegister("air", Blocks::AIR()->asItem()->setCount(0));
|
||||
|
||||
self::register("acacia_sign", fn(IID $id) => new ItemBlockWallOrFloor($id, Blocks::ACACIA_SIGN(), Blocks::ACACIA_WALL_SIGN()));
|
||||
self::register("acacia_hanging_sign", fn(IID $id) => new HangingSign($id, "Acacia Hanging Sign", Blocks::ACACIA_CEILING_CENTER_HANGING_SIGN(), Blocks::ACACIA_CEILING_EDGES_HANGING_SIGN(), Blocks::ACACIA_WALL_HANGING_SIGN()));
|
||||
self::register("amethyst_shard", fn(IID $id) => new Item($id, "Amethyst Shard"));
|
||||
self::register("apple", fn(IID $id) => new Apple($id, "Apple"));
|
||||
self::register("arrow", fn(IID $id) => new Arrow($id, "Arrow"));
|
||||
@ -407,6 +420,7 @@ final class VanillaItems{
|
||||
self::register("beetroot_seeds", fn(IID $id) => new BeetrootSeeds($id, "Beetroot Seeds"));
|
||||
self::register("beetroot_soup", fn(IID $id) => new BeetrootSoup($id, "Beetroot Soup"));
|
||||
self::register("birch_sign", fn(IID $id) => new ItemBlockWallOrFloor($id, Blocks::BIRCH_SIGN(), Blocks::BIRCH_WALL_SIGN()));
|
||||
self::register("birch_hanging_sign", fn(IID $id) => new HangingSign($id, "Birch Hanging Sign", Blocks::BIRCH_CEILING_CENTER_HANGING_SIGN(), Blocks::BIRCH_CEILING_EDGES_HANGING_SIGN(), Blocks::BIRCH_WALL_HANGING_SIGN()));
|
||||
self::register("blaze_powder", fn(IID $id) => new Item($id, "Blaze Powder"));
|
||||
self::register("blaze_rod", fn(IID $id) => new BlazeRod($id, "Blaze Rod"));
|
||||
self::register("bleach", fn(IID $id) => new Item($id, "Bleach"));
|
||||
@ -421,6 +435,7 @@ final class VanillaItems{
|
||||
self::register("carrot", fn(IID $id) => new Carrot($id, "Carrot"));
|
||||
self::register("charcoal", fn(IID $id) => new Coal($id, "Charcoal"));
|
||||
self::register("cherry_sign", fn(IID $id) => new ItemBlockWallOrFloor($id, Blocks::CHERRY_SIGN(), Blocks::CHERRY_WALL_SIGN()));
|
||||
self::register("cherry_hanging_sign", fn(IID $id) => new HangingSign($id, "Cherry Hanging Sign", Blocks::CHERRY_CEILING_CENTER_HANGING_SIGN(), Blocks::CHERRY_CEILING_EDGES_HANGING_SIGN(), Blocks::CHERRY_WALL_HANGING_SIGN()));
|
||||
self::register("chemical_aluminium_oxide", fn(IID $id) => new Item($id, "Aluminium Oxide"));
|
||||
self::register("chemical_ammonia", fn(IID $id) => new Item($id, "Ammonia"));
|
||||
self::register("chemical_barium_sulphate", fn(IID $id) => new Item($id, "Barium Sulphate"));
|
||||
@ -476,7 +491,9 @@ final class VanillaItems{
|
||||
self::register("copper_ingot", fn(IID $id) => new Item($id, "Copper Ingot"));
|
||||
self::register("coral_fan", fn(IID $id) => new CoralFan($id));
|
||||
self::register("crimson_sign", fn(IID $id) => new ItemBlockWallOrFloor($id, Blocks::CRIMSON_SIGN(), Blocks::CRIMSON_WALL_SIGN()));
|
||||
self::register("crimson_hanging_sign", fn(IID $id) => new HangingSign($id, "Crimson Hanging Sign", Blocks::CRIMSON_CEILING_CENTER_HANGING_SIGN(), Blocks::CRIMSON_CEILING_EDGES_HANGING_SIGN(), Blocks::CRIMSON_WALL_HANGING_SIGN()));
|
||||
self::register("dark_oak_sign", fn(IID $id) => new ItemBlockWallOrFloor($id, Blocks::DARK_OAK_SIGN(), Blocks::DARK_OAK_WALL_SIGN()));
|
||||
self::register("dark_oak_hanging_sign", fn(IID $id) => new HangingSign($id, "Dark Oak Hanging Sign", Blocks::DARK_OAK_CEILING_CENTER_HANGING_SIGN(), Blocks::DARK_OAK_CEILING_EDGES_HANGING_SIGN(), Blocks::DARK_OAK_WALL_HANGING_SIGN()));
|
||||
self::register("diamond", fn(IID $id) => new Item($id, "Diamond"));
|
||||
self::register("disc_fragment_5", fn(IID $id) => new Item($id, "Disc Fragment (5)"));
|
||||
self::register("dragon_breath", fn(IID $id) => new Item($id, "Dragon's Breath"));
|
||||
@ -517,11 +534,13 @@ final class VanillaItems{
|
||||
self::register("iron_ingot", fn(IID $id) => new Item($id, "Iron Ingot"));
|
||||
self::register("iron_nugget", fn(IID $id) => new Item($id, "Iron Nugget"));
|
||||
self::register("jungle_sign", fn(IID $id) => new ItemBlockWallOrFloor($id, Blocks::JUNGLE_SIGN(), Blocks::JUNGLE_WALL_SIGN()));
|
||||
self::register("jungle_hanging_sign", fn(IID $id) => new HangingSign($id, "Jungle Hanging Sign", Blocks::JUNGLE_CEILING_CENTER_HANGING_SIGN(), Blocks::JUNGLE_CEILING_EDGES_HANGING_SIGN(), Blocks::JUNGLE_WALL_HANGING_SIGN()));
|
||||
self::register("lapis_lazuli", fn(IID $id) => new Item($id, "Lapis Lazuli"));
|
||||
self::register("lava_bucket", fn(IID $id) => new LiquidBucket($id, "Lava Bucket", Blocks::LAVA()));
|
||||
self::register("leather", fn(IID $id) => new Item($id, "Leather"));
|
||||
self::register("magma_cream", fn(IID $id) => new Item($id, "Magma Cream"));
|
||||
self::register("mangrove_sign", fn(IID $id) => new ItemBlockWallOrFloor($id, Blocks::MANGROVE_SIGN(), Blocks::MANGROVE_WALL_SIGN()));
|
||||
self::register("mangrove_hanging_sign", fn(IID $id) => new HangingSign($id, "Mangrove Hanging Sign", Blocks::MANGROVE_CEILING_CENTER_HANGING_SIGN(), Blocks::MANGROVE_CEILING_EDGES_HANGING_SIGN(), Blocks::MANGROVE_WALL_HANGING_SIGN()));
|
||||
self::register("medicine", fn(IID $id) => new Medicine($id, "Medicine"));
|
||||
self::register("melon", fn(IID $id) => new Melon($id, "Melon"));
|
||||
self::register("melon_seeds", fn(IID $id) => new MelonSeeds($id, "Melon Seeds"));
|
||||
@ -540,8 +559,11 @@ final class VanillaItems{
|
||||
public function isFireProof() : bool{ return true; }
|
||||
});
|
||||
self::register("oak_sign", fn(IID $id) => new ItemBlockWallOrFloor($id, Blocks::OAK_SIGN(), Blocks::OAK_WALL_SIGN()));
|
||||
self::register("oak_hanging_sign", fn(IID $id) => new HangingSign($id, "Oak Hanging Sign", Blocks::OAK_CEILING_CENTER_HANGING_SIGN(), Blocks::OAK_CEILING_EDGES_HANGING_SIGN(), Blocks::OAK_WALL_HANGING_SIGN()));
|
||||
self::register("ominous_banner", fn(IID $id) => new ItemBlockWallOrFloor($id, Blocks::OMINOUS_BANNER(), Blocks::OMINOUS_WALL_BANNER()));
|
||||
self::register("painting", fn(IID $id) => new PaintingItem($id, "Painting"));
|
||||
self::register("pale_oak_sign", fn(IID $id) => new ItemBlockWallOrFloor($id, Blocks::PALE_OAK_SIGN(), Blocks::PALE_OAK_WALL_SIGN()));
|
||||
self::register("pale_oak_hanging_sign", fn(IID $id) => new HangingSign($id, "Pale Oak Hanging Sign", Blocks::PALE_OAK_CEILING_CENTER_HANGING_SIGN(), Blocks::PALE_OAK_CEILING_EDGES_HANGING_SIGN(), Blocks::PALE_OAK_WALL_HANGING_SIGN()));
|
||||
self::register("paper", fn(IID $id) => new Item($id, "Paper"));
|
||||
self::register("phantom_membrane", fn(IID $id) => new Item($id, "Phantom Membrane"));
|
||||
self::register("pitcher_pod", fn(IID $id) => new PitcherPod($id, "Pitcher Pod"));
|
||||
@ -598,6 +620,7 @@ final class VanillaItems{
|
||||
self::register("spider_eye", fn(IID $id) => new SpiderEye($id, "Spider Eye"));
|
||||
self::register("splash_potion", fn(IID $id) => new SplashPotion($id, "Splash Potion"));
|
||||
self::register("spruce_sign", fn(IID $id) => new ItemBlockWallOrFloor($id, Blocks::SPRUCE_SIGN(), Blocks::SPRUCE_WALL_SIGN()));
|
||||
self::register("spruce_hanging_sign", fn(IID $id) => new HangingSign($id, "Spruce Hanging Sign", Blocks::SPRUCE_CEILING_CENTER_HANGING_SIGN(), Blocks::SPRUCE_CEILING_EDGES_HANGING_SIGN(), Blocks::SPRUCE_WALL_HANGING_SIGN()));
|
||||
self::register("spyglass", fn(IID $id) => new Spyglass($id, "Spyglass"));
|
||||
self::register("steak", fn(IID $id) => new Steak($id, "Steak"));
|
||||
self::register("stick", fn(IID $id) => new Stick($id, "Stick"));
|
||||
@ -608,6 +631,7 @@ final class VanillaItems{
|
||||
self::register("torchflower_seeds", fn(IID $id) => new TorchflowerSeeds($id, "Torchflower Seeds"));
|
||||
self::register("totem", fn(IID $id) => new Totem($id, "Totem of Undying"));
|
||||
self::register("warped_sign", fn(IID $id) => new ItemBlockWallOrFloor($id, Blocks::WARPED_SIGN(), Blocks::WARPED_WALL_SIGN()));
|
||||
self::register("warped_hanging_sign", fn(IID $id) => new HangingSign($id, "Warped Hanging Sign", Blocks::WARPED_CEILING_CENTER_HANGING_SIGN(), Blocks::WARPED_CEILING_EDGES_HANGING_SIGN(), Blocks::WARPED_WALL_HANGING_SIGN()));
|
||||
self::register("water_bucket", fn(IID $id) => new LiquidBucket($id, "Water Bucket", Blocks::WATER()));
|
||||
self::register("wheat", fn(IID $id) => new Item($id, "Wheat"));
|
||||
self::register("wheat_seeds", fn(IID $id) => new WheatSeeds($id, "Wheat Seeds"));
|
||||
|
@ -2279,7 +2279,7 @@ class World implements ChunkManager{
|
||||
if($item->isNull() || !$item->canBePlaced()){
|
||||
return false;
|
||||
}
|
||||
$hand = $item->getBlock($face);
|
||||
$hand = $item->getPlacementBlock($blockReplace, $blockClicked, $face, $clickVector);
|
||||
$hand->position($this, $blockReplace->getPosition()->x, $blockReplace->getPosition()->y, $blockReplace->getPosition()->z);
|
||||
|
||||
if($hand->canBePlacedAt($blockClicked, $clickVector, $face, true)){
|
||||
@ -2959,7 +2959,7 @@ class World implements ChunkManager{
|
||||
unset($this->blockCache[$chunkHash]);
|
||||
unset($this->blockCollisionBoxCache[$chunkHash]);
|
||||
|
||||
$this->initChunk($x, $z, $chunkData);
|
||||
$this->initChunk($x, $z, $chunkData, $chunk);
|
||||
|
||||
if(ChunkLoadEvent::hasHandlers()){
|
||||
(new ChunkLoadEvent($this, $x, $z, $this->chunks[$chunkHash], false))->call();
|
||||
@ -2979,7 +2979,7 @@ class World implements ChunkManager{
|
||||
return $this->chunks[$chunkHash];
|
||||
}
|
||||
|
||||
private function initChunk(int $chunkX, int $chunkZ, ChunkData $chunkData) : void{
|
||||
private function initChunk(int $chunkX, int $chunkZ, ChunkData $chunkData, Chunk $chunk) : void{
|
||||
$logger = new \PrefixedLogger($this->logger, "Loading chunk $chunkX $chunkZ");
|
||||
|
||||
if(count($chunkData->getEntityNBT()) !== 0){
|
||||
@ -3044,6 +3044,16 @@ class World implements ChunkManager{
|
||||
}else{
|
||||
$this->addTile($tile);
|
||||
}
|
||||
$expectedStateId = $chunk->getBlockStateId($tilePosition->getFloorX() & Chunk::COORD_MASK, $tilePosition->getFloorY(), $tilePosition->getFloorZ() & Chunk::COORD_MASK);
|
||||
$actualStateId = $this->getBlock($tilePosition)->getStateId();
|
||||
if($expectedStateId !== $actualStateId){
|
||||
//state ID was updated by readStateFromWorld - typically because the block pulled some data from the tile
|
||||
//make sure this is synced to the chunk
|
||||
//TODO: in the future we should pull tile reading logic out of readStateFromWorld() and do it only
|
||||
//when the tile is loaded - this would be cleaner and faster
|
||||
$chunk->setBlockStateId($tilePosition->getFloorX() & Chunk::COORD_MASK, $tilePosition->getFloorY(), $tilePosition->getFloorZ() & Chunk::COORD_MASK, $actualStateId);
|
||||
$this->logger->debug("Tile " . $tile::class . " at x=$tilePosition->x,y=$tilePosition->y,z=$tilePosition->z updated block state ID from $expectedStateId to $actualStateId");
|
||||
}
|
||||
}
|
||||
|
||||
foreach(Utils::promoteKeys($deletedTiles) as $saveId => $count){
|
||||
|
@ -26,7 +26,9 @@ namespace pocketmine\world\format\io;
|
||||
use pocketmine\data\bedrock\block\BlockStateData;
|
||||
use pocketmine\data\bedrock\block\BlockTypeNames;
|
||||
use pocketmine\data\bedrock\block\convert\BlockObjectToStateSerializer;
|
||||
use pocketmine\data\bedrock\block\convert\BlockSerializerDeserializerRegistrar;
|
||||
use pocketmine\data\bedrock\block\convert\BlockStateToObjectDeserializer;
|
||||
use pocketmine\data\bedrock\block\convert\VanillaBlockMappings;
|
||||
use pocketmine\data\bedrock\block\upgrade\BlockDataUpgrader;
|
||||
use pocketmine\data\bedrock\block\upgrade\BlockIdMetaUpgrader;
|
||||
use pocketmine\data\bedrock\block\upgrade\BlockStateUpgrader;
|
||||
@ -44,20 +46,28 @@ use const pocketmine\BEDROCK_BLOCK_UPGRADE_SCHEMA_PATH;
|
||||
* benefits for now.
|
||||
*/
|
||||
final class GlobalBlockStateHandlers{
|
||||
private static ?BlockObjectToStateSerializer $blockStateSerializer = null;
|
||||
|
||||
private static ?BlockStateToObjectDeserializer $blockStateDeserializer = null;
|
||||
|
||||
private static ?BlockDataUpgrader $blockDataUpgrader = null;
|
||||
|
||||
private static ?BlockStateData $unknownBlockStateData = null;
|
||||
|
||||
private static ?BlockSerializerDeserializerRegistrar $registrar = null;
|
||||
|
||||
public static function getRegistrar() : BlockSerializerDeserializerRegistrar{
|
||||
if(self::$registrar === null){
|
||||
$deserializer = new BlockStateToObjectDeserializer();
|
||||
$serializer = new BlockObjectToStateSerializer();
|
||||
self::$registrar = new BlockSerializerDeserializerRegistrar($deserializer, $serializer);
|
||||
VanillaBlockMappings::init(self::$registrar);
|
||||
}
|
||||
return self::$registrar;
|
||||
}
|
||||
|
||||
public static function getDeserializer() : BlockStateToObjectDeserializer{
|
||||
return self::$blockStateDeserializer ??= new BlockStateToObjectDeserializer();
|
||||
return self::getRegistrar()->deserializer;
|
||||
}
|
||||
|
||||
public static function getSerializer() : BlockObjectToStateSerializer{
|
||||
return self::$blockStateSerializer ??= new BlockObjectToStateSerializer();
|
||||
return self::getRegistrar()->serializer;
|
||||
}
|
||||
|
||||
public static function getUpgrader() : BlockDataUpgrader{
|
||||
|
@ -600,6 +600,12 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../src/crash/CrashDumpRenderer.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$faces of method pocketmine\\block\\Vine\:\:setFaces\(\) expects list\<2\|3\|4\|5\>, array\<int\> given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: ../../../src/data/bedrock/block/convert/VanillaBlockMappings.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$blockToItemId of class pocketmine\\data\\bedrock\\item\\BlockItemIdMap constructor expects array\<string, string\>, array\<mixed, mixed\> given\.$#'
|
||||
identifier: argument.type
|
||||
|
@ -18,78 +18,138 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../src/Server.php
|
||||
|
||||
-
|
||||
message: '#^Method pocketmine\\block\\Block\:\:readStateFromWorld\(\) is marked as impure but does not have any side effects\.$#'
|
||||
identifier: impureMethod.pure
|
||||
count: 1
|
||||
path: ../../../src/block/Block.php
|
||||
|
||||
-
|
||||
message: '#^Method pocketmine\\block\\DoubleTallGrass\:\:traitGetDropsForIncompatibleTool\(\) return type has no value type specified in iterable type array\.$#'
|
||||
identifier: missingType.iterableValue
|
||||
count: 1
|
||||
path: ../../../src/block/DoubleTallGrass.php
|
||||
|
||||
-
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:ACACIA_HANGING_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:ACACIA_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:BIRCH_HANGING_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:BIRCH_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:CHERRY_HANGING_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:CHERRY_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:CRIMSON_HANGING_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:CRIMSON_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:DARK_OAK_HANGING_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:DARK_OAK_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:JUNGLE_HANGING_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:JUNGLE_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:MANGROVE_HANGING_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:MANGROVE_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:OAK_HANGING_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:OAK_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:PALE_OAK_HANGING_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:PALE_OAK_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:SPRUCE_HANGING_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:SPRUCE_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:WARPED_HANGING_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:WARPED_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
@ -252,9 +312,3 @@ parameters:
|
||||
count: 2
|
||||
path: ../../phpunit/promise/PromiseTest.php
|
||||
|
||||
-
|
||||
message: '#^Strict comparison using \=\=\= between 0 and 0 will always evaluate to true\.$#'
|
||||
identifier: identical.alwaysTrue
|
||||
count: 1
|
||||
path: ../rules/UnsafeForeachArrayWithStringKeysRule.php
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
{
|
||||
"stateCounts": {
|
||||
"ACACIA_BUTTON": 12,
|
||||
"ACACIA_CEILING_CENTER_HANGING_SIGN": 16,
|
||||
"ACACIA_CEILING_EDGES_HANGING_SIGN": 4,
|
||||
"ACACIA_DOOR": 32,
|
||||
"ACACIA_FENCE": 1,
|
||||
"ACACIA_FENCE_GATE": 16,
|
||||
@ -13,6 +15,7 @@
|
||||
"ACACIA_SLAB": 3,
|
||||
"ACACIA_STAIRS": 8,
|
||||
"ACACIA_TRAPDOOR": 16,
|
||||
"ACACIA_WALL_HANGING_SIGN": 4,
|
||||
"ACACIA_WALL_SIGN": 4,
|
||||
"ACACIA_WOOD": 6,
|
||||
"ACTIVATOR_RAIL": 12,
|
||||
@ -43,6 +46,8 @@
|
||||
"BIG_DRIPLEAF_HEAD": 16,
|
||||
"BIG_DRIPLEAF_STEM": 4,
|
||||
"BIRCH_BUTTON": 12,
|
||||
"BIRCH_CEILING_CENTER_HANGING_SIGN": 16,
|
||||
"BIRCH_CEILING_EDGES_HANGING_SIGN": 4,
|
||||
"BIRCH_DOOR": 32,
|
||||
"BIRCH_FENCE": 1,
|
||||
"BIRCH_FENCE_GATE": 16,
|
||||
@ -55,6 +60,7 @@
|
||||
"BIRCH_SLAB": 3,
|
||||
"BIRCH_STAIRS": 8,
|
||||
"BIRCH_TRAPDOOR": 16,
|
||||
"BIRCH_WALL_HANGING_SIGN": 4,
|
||||
"BIRCH_WALL_SIGN": 4,
|
||||
"BIRCH_WOOD": 6,
|
||||
"BLACKSTONE": 1,
|
||||
@ -91,6 +97,8 @@
|
||||
"CHAIN": 3,
|
||||
"CHEMICAL_HEAT": 1,
|
||||
"CHERRY_BUTTON": 12,
|
||||
"CHERRY_CEILING_CENTER_HANGING_SIGN": 16,
|
||||
"CHERRY_CEILING_EDGES_HANGING_SIGN": 4,
|
||||
"CHERRY_DOOR": 32,
|
||||
"CHERRY_FENCE": 1,
|
||||
"CHERRY_FENCE_GATE": 16,
|
||||
@ -102,6 +110,7 @@
|
||||
"CHERRY_SLAB": 3,
|
||||
"CHERRY_STAIRS": 8,
|
||||
"CHERRY_TRAPDOOR": 16,
|
||||
"CHERRY_WALL_HANGING_SIGN": 4,
|
||||
"CHERRY_WALL_SIGN": 4,
|
||||
"CHERRY_WOOD": 6,
|
||||
"CHEST": 4,
|
||||
@ -152,6 +161,8 @@
|
||||
"CRACKED_STONE_BRICKS": 1,
|
||||
"CRAFTING_TABLE": 1,
|
||||
"CRIMSON_BUTTON": 12,
|
||||
"CRIMSON_CEILING_CENTER_HANGING_SIGN": 16,
|
||||
"CRIMSON_CEILING_EDGES_HANGING_SIGN": 4,
|
||||
"CRIMSON_DOOR": 32,
|
||||
"CRIMSON_FENCE": 1,
|
||||
"CRIMSON_FENCE_GATE": 16,
|
||||
@ -164,6 +175,7 @@
|
||||
"CRIMSON_STAIRS": 8,
|
||||
"CRIMSON_STEM": 6,
|
||||
"CRIMSON_TRAPDOOR": 16,
|
||||
"CRIMSON_WALL_HANGING_SIGN": 4,
|
||||
"CRIMSON_WALL_SIGN": 4,
|
||||
"CRYING_OBSIDIAN": 1,
|
||||
"CUT_COPPER": 8,
|
||||
@ -175,6 +187,8 @@
|
||||
"CUT_SANDSTONE_SLAB": 3,
|
||||
"DANDELION": 1,
|
||||
"DARK_OAK_BUTTON": 12,
|
||||
"DARK_OAK_CEILING_CENTER_HANGING_SIGN": 16,
|
||||
"DARK_OAK_CEILING_EDGES_HANGING_SIGN": 4,
|
||||
"DARK_OAK_DOOR": 32,
|
||||
"DARK_OAK_FENCE": 1,
|
||||
"DARK_OAK_FENCE_GATE": 16,
|
||||
@ -187,6 +201,7 @@
|
||||
"DARK_OAK_SLAB": 3,
|
||||
"DARK_OAK_STAIRS": 8,
|
||||
"DARK_OAK_TRAPDOOR": 16,
|
||||
"DARK_OAK_WALL_HANGING_SIGN": 4,
|
||||
"DARK_OAK_WALL_SIGN": 4,
|
||||
"DARK_OAK_WOOD": 6,
|
||||
"DARK_PRISMARINE": 1,
|
||||
@ -409,6 +424,8 @@
|
||||
"ITEM_FRAME": 12,
|
||||
"JUKEBOX": 1,
|
||||
"JUNGLE_BUTTON": 12,
|
||||
"JUNGLE_CEILING_CENTER_HANGING_SIGN": 16,
|
||||
"JUNGLE_CEILING_EDGES_HANGING_SIGN": 4,
|
||||
"JUNGLE_DOOR": 32,
|
||||
"JUNGLE_FENCE": 1,
|
||||
"JUNGLE_FENCE_GATE": 16,
|
||||
@ -421,6 +438,7 @@
|
||||
"JUNGLE_SLAB": 3,
|
||||
"JUNGLE_STAIRS": 8,
|
||||
"JUNGLE_TRAPDOOR": 16,
|
||||
"JUNGLE_WALL_HANGING_SIGN": 4,
|
||||
"JUNGLE_WALL_SIGN": 4,
|
||||
"JUNGLE_WOOD": 6,
|
||||
"LAB_TABLE": 4,
|
||||
@ -443,6 +461,8 @@
|
||||
"LOOM": 4,
|
||||
"MAGMA": 1,
|
||||
"MANGROVE_BUTTON": 12,
|
||||
"MANGROVE_CEILING_CENTER_HANGING_SIGN": 16,
|
||||
"MANGROVE_CEILING_EDGES_HANGING_SIGN": 4,
|
||||
"MANGROVE_DOOR": 32,
|
||||
"MANGROVE_FENCE": 1,
|
||||
"MANGROVE_FENCE_GATE": 16,
|
||||
@ -455,6 +475,7 @@
|
||||
"MANGROVE_SLAB": 3,
|
||||
"MANGROVE_STAIRS": 8,
|
||||
"MANGROVE_TRAPDOOR": 16,
|
||||
"MANGROVE_WALL_HANGING_SIGN": 4,
|
||||
"MANGROVE_WALL_SIGN": 4,
|
||||
"MANGROVE_WOOD": 6,
|
||||
"MATERIAL_REDUCER": 4,
|
||||
@ -493,6 +514,8 @@
|
||||
"NETHER_WART_BLOCK": 1,
|
||||
"NOTE_BLOCK": 1,
|
||||
"OAK_BUTTON": 12,
|
||||
"OAK_CEILING_CENTER_HANGING_SIGN": 16,
|
||||
"OAK_CEILING_EDGES_HANGING_SIGN": 4,
|
||||
"OAK_DOOR": 32,
|
||||
"OAK_FENCE": 1,
|
||||
"OAK_FENCE_GATE": 16,
|
||||
@ -505,14 +528,19 @@
|
||||
"OAK_SLAB": 3,
|
||||
"OAK_STAIRS": 8,
|
||||
"OAK_TRAPDOOR": 16,
|
||||
"OAK_WALL_HANGING_SIGN": 4,
|
||||
"OAK_WALL_SIGN": 4,
|
||||
"OAK_WOOD": 6,
|
||||
"OBSIDIAN": 1,
|
||||
"OMINOUS_BANNER": 16,
|
||||
"OMINOUS_WALL_BANNER": 4,
|
||||
"ORANGE_TULIP": 1,
|
||||
"OXEYE_DAISY": 1,
|
||||
"PACKED_ICE": 1,
|
||||
"PACKED_MUD": 1,
|
||||
"PALE_OAK_BUTTON": 12,
|
||||
"PALE_OAK_CEILING_CENTER_HANGING_SIGN": 16,
|
||||
"PALE_OAK_CEILING_EDGES_HANGING_SIGN": 4,
|
||||
"PALE_OAK_DOOR": 32,
|
||||
"PALE_OAK_FENCE": 1,
|
||||
"PALE_OAK_FENCE_GATE": 16,
|
||||
@ -524,6 +552,7 @@
|
||||
"PALE_OAK_SLAB": 3,
|
||||
"PALE_OAK_STAIRS": 8,
|
||||
"PALE_OAK_TRAPDOOR": 16,
|
||||
"PALE_OAK_WALL_HANGING_SIGN": 4,
|
||||
"PALE_OAK_WALL_SIGN": 4,
|
||||
"PALE_OAK_WOOD": 6,
|
||||
"PEONY": 2,
|
||||
@ -654,6 +683,8 @@
|
||||
"SPONGE": 2,
|
||||
"SPORE_BLOSSOM": 1,
|
||||
"SPRUCE_BUTTON": 12,
|
||||
"SPRUCE_CEILING_CENTER_HANGING_SIGN": 16,
|
||||
"SPRUCE_CEILING_EDGES_HANGING_SIGN": 4,
|
||||
"SPRUCE_DOOR": 32,
|
||||
"SPRUCE_FENCE": 1,
|
||||
"SPRUCE_FENCE_GATE": 16,
|
||||
@ -666,6 +697,7 @@
|
||||
"SPRUCE_SLAB": 3,
|
||||
"SPRUCE_STAIRS": 8,
|
||||
"SPRUCE_TRAPDOOR": 16,
|
||||
"SPRUCE_WALL_HANGING_SIGN": 4,
|
||||
"SPRUCE_WALL_SIGN": 4,
|
||||
"SPRUCE_WOOD": 6,
|
||||
"STAINED_CLAY": 16,
|
||||
@ -709,6 +741,8 @@
|
||||
"WALL_BANNER": 64,
|
||||
"WALL_CORAL_FAN": 40,
|
||||
"WARPED_BUTTON": 12,
|
||||
"WARPED_CEILING_CENTER_HANGING_SIGN": 16,
|
||||
"WARPED_CEILING_EDGES_HANGING_SIGN": 4,
|
||||
"WARPED_DOOR": 32,
|
||||
"WARPED_FENCE": 1,
|
||||
"WARPED_FENCE_GATE": 16,
|
||||
@ -721,6 +755,7 @@
|
||||
"WARPED_STAIRS": 8,
|
||||
"WARPED_STEM": 6,
|
||||
"WARPED_TRAPDOOR": 16,
|
||||
"WARPED_WALL_HANGING_SIGN": 4,
|
||||
"WARPED_WALL_SIGN": 4,
|
||||
"WARPED_WART_BLOCK": 1,
|
||||
"WATER": 32,
|
||||
@ -734,26 +769,41 @@
|
||||
"WOOL": 16
|
||||
},
|
||||
"tiles": {
|
||||
"ACACIA_CEILING_CENTER_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"ACACIA_CEILING_EDGES_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"ACACIA_SIGN": "pocketmine\\block\\tile\\Sign",
|
||||
"ACACIA_WALL_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"ACACIA_WALL_SIGN": "pocketmine\\block\\tile\\Sign",
|
||||
"BANNER": "pocketmine\\block\\tile\\Banner",
|
||||
"BARREL": "pocketmine\\block\\tile\\Barrel",
|
||||
"BEACON": "pocketmine\\block\\tile\\Beacon",
|
||||
"BED": "pocketmine\\block\\tile\\Bed",
|
||||
"BELL": "pocketmine\\block\\tile\\Bell",
|
||||
"BIRCH_CEILING_CENTER_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"BIRCH_CEILING_EDGES_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"BIRCH_SIGN": "pocketmine\\block\\tile\\Sign",
|
||||
"BIRCH_WALL_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"BIRCH_WALL_SIGN": "pocketmine\\block\\tile\\Sign",
|
||||
"BLAST_FURNACE": "pocketmine\\block\\tile\\BlastFurnace",
|
||||
"BREWING_STAND": "pocketmine\\block\\tile\\BrewingStand",
|
||||
"CAMPFIRE": "pocketmine\\block\\tile\\Campfire",
|
||||
"CAULDRON": "pocketmine\\block\\tile\\Cauldron",
|
||||
"CHERRY_CEILING_CENTER_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"CHERRY_CEILING_EDGES_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"CHERRY_SIGN": "pocketmine\\block\\tile\\Sign",
|
||||
"CHERRY_WALL_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"CHERRY_WALL_SIGN": "pocketmine\\block\\tile\\Sign",
|
||||
"CHEST": "pocketmine\\block\\tile\\Chest",
|
||||
"CHISELED_BOOKSHELF": "pocketmine\\block\\tile\\ChiseledBookshelf",
|
||||
"CRIMSON_CEILING_CENTER_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"CRIMSON_CEILING_EDGES_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"CRIMSON_SIGN": "pocketmine\\block\\tile\\Sign",
|
||||
"CRIMSON_WALL_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"CRIMSON_WALL_SIGN": "pocketmine\\block\\tile\\Sign",
|
||||
"DARK_OAK_CEILING_CENTER_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"DARK_OAK_CEILING_EDGES_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"DARK_OAK_SIGN": "pocketmine\\block\\tile\\Sign",
|
||||
"DARK_OAK_WALL_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"DARK_OAK_WALL_SIGN": "pocketmine\\block\\tile\\Sign",
|
||||
"DAYLIGHT_SENSOR": "pocketmine\\block\\tile\\DaylightSensor",
|
||||
"DYED_SHULKER_BOX": "pocketmine\\block\\tile\\ShulkerBox",
|
||||
@ -765,29 +815,49 @@
|
||||
"HOPPER": "pocketmine\\block\\tile\\Hopper",
|
||||
"ITEM_FRAME": "pocketmine\\block\\tile\\ItemFrame",
|
||||
"JUKEBOX": "pocketmine\\block\\tile\\Jukebox",
|
||||
"JUNGLE_CEILING_CENTER_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"JUNGLE_CEILING_EDGES_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"JUNGLE_SIGN": "pocketmine\\block\\tile\\Sign",
|
||||
"JUNGLE_WALL_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"JUNGLE_WALL_SIGN": "pocketmine\\block\\tile\\Sign",
|
||||
"LAVA_CAULDRON": "pocketmine\\block\\tile\\Cauldron",
|
||||
"LECTERN": "pocketmine\\block\\tile\\Lectern",
|
||||
"MANGROVE_CEILING_CENTER_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"MANGROVE_CEILING_EDGES_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"MANGROVE_SIGN": "pocketmine\\block\\tile\\Sign",
|
||||
"MANGROVE_WALL_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"MANGROVE_WALL_SIGN": "pocketmine\\block\\tile\\Sign",
|
||||
"MOB_HEAD": "pocketmine\\block\\tile\\MobHead",
|
||||
"MONSTER_SPAWNER": "pocketmine\\block\\tile\\MonsterSpawner",
|
||||
"NOTE_BLOCK": "pocketmine\\block\\tile\\Note",
|
||||
"OAK_CEILING_CENTER_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"OAK_CEILING_EDGES_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"OAK_SIGN": "pocketmine\\block\\tile\\Sign",
|
||||
"OAK_WALL_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"OAK_WALL_SIGN": "pocketmine\\block\\tile\\Sign",
|
||||
"OMINOUS_BANNER": "pocketmine\\block\\tile\\Banner",
|
||||
"OMINOUS_WALL_BANNER": "pocketmine\\block\\tile\\Banner",
|
||||
"PALE_OAK_CEILING_CENTER_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"PALE_OAK_CEILING_EDGES_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"PALE_OAK_SIGN": "pocketmine\\block\\tile\\Sign",
|
||||
"PALE_OAK_WALL_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"PALE_OAK_WALL_SIGN": "pocketmine\\block\\tile\\Sign",
|
||||
"POTION_CAULDRON": "pocketmine\\block\\tile\\Cauldron",
|
||||
"REDSTONE_COMPARATOR": "pocketmine\\block\\tile\\Comparator",
|
||||
"SHULKER_BOX": "pocketmine\\block\\tile\\ShulkerBox",
|
||||
"SMOKER": "pocketmine\\block\\tile\\Smoker",
|
||||
"SOUL_CAMPFIRE": "pocketmine\\block\\tile\\Campfire",
|
||||
"SPRUCE_CEILING_CENTER_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"SPRUCE_CEILING_EDGES_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"SPRUCE_SIGN": "pocketmine\\block\\tile\\Sign",
|
||||
"SPRUCE_WALL_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"SPRUCE_WALL_SIGN": "pocketmine\\block\\tile\\Sign",
|
||||
"TRAPPED_CHEST": "pocketmine\\block\\tile\\Chest",
|
||||
"WALL_BANNER": "pocketmine\\block\\tile\\Banner",
|
||||
"WARPED_CEILING_CENTER_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"WARPED_CEILING_EDGES_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"WARPED_SIGN": "pocketmine\\block\\tile\\Sign",
|
||||
"WARPED_WALL_HANGING_SIGN": "pocketmine\\block\\tile\\HangingSign",
|
||||
"WARPED_WALL_SIGN": "pocketmine\\block\\tile\\Sign",
|
||||
"WATER_CAULDRON": "pocketmine\\block\\tile\\Cauldron"
|
||||
}
|
||||
|
@ -42,6 +42,8 @@ final class BlockSerializerDeserializerTest extends TestCase{
|
||||
public function setUp() : void{
|
||||
$this->deserializer = new BlockStateToObjectDeserializer();
|
||||
$this->serializer = new BlockObjectToStateSerializer();
|
||||
$registrar = new BlockSerializerDeserializerRegistrar($this->deserializer, $this->serializer);
|
||||
VanillaBlockMappings::init($registrar);
|
||||
}
|
||||
|
||||
public function testAllKnownBlockStatesSerializableAndDeserializable() : void{
|
||||
@ -49,16 +51,21 @@ final class BlockSerializerDeserializerTest extends TestCase{
|
||||
try{
|
||||
$blockStateData = $this->serializer->serializeBlock($block);
|
||||
}catch(BlockStateSerializeException $e){
|
||||
self::fail($e->getMessage());
|
||||
self::fail("Failed to serialize " . $block->getName() . ": " . $e->getMessage());
|
||||
}
|
||||
try{
|
||||
$newBlock = $this->deserializer->deserializeBlock($blockStateData);
|
||||
}catch(BlockStateDeserializeException $e){
|
||||
self::fail($e->getMessage());
|
||||
self::fail("Failed to deserialize " . $blockStateData->getName() . ": " . $e->getMessage() . " with data " . $blockStateData->toNbt());
|
||||
}
|
||||
|
||||
if($block->getTypeId() === BlockTypeIds::POTION_CAULDRON){
|
||||
//this pretends to be a water cauldron in the blockstate, and stores its actual data in the blockentity
|
||||
if(match ($block->getTypeId()) {
|
||||
BlockTypeIds::POTION_CAULDRON,
|
||||
BlockTypeIds::OMINOUS_BANNER,
|
||||
BlockTypeIds::OMINOUS_WALL_BANNER => true,
|
||||
default => false
|
||||
}){
|
||||
//these pretend to be something else in the blockstate, and the variant switching is done via block entity data
|
||||
continue;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user