mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-08-26 05:04:57 +00:00
parent
7c521b456e
commit
8f9478e82f
@ -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);
|
||||
|
85
src/block/BaseOminousBanner.php
Normal file
85
src/block/BaseOminousBanner.php
Normal file
@ -0,0 +1,85 @@
|
||||
<?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\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);
|
||||
}
|
||||
}
|
||||
}
|
@ -787,8 +787,10 @@ 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 FIRST_UNUSED_BLOCK_ID = 10760;
|
||||
public const FIRST_UNUSED_BLOCK_ID = 10762;
|
||||
|
||||
private static int $nextDynamicId = self::FIRST_UNUSED_BLOCK_ID;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -587,6 +587,8 @@ use function strtolower;
|
||||
* @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()
|
||||
@ -873,6 +875,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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ use pocketmine\block\Farmland;
|
||||
use pocketmine\block\FillableCauldron;
|
||||
use pocketmine\block\Fire;
|
||||
use pocketmine\block\FloorCoralFan;
|
||||
use pocketmine\block\OminousFloorBanner;
|
||||
use pocketmine\block\Froglight;
|
||||
use pocketmine\block\FrostedIce;
|
||||
use pocketmine\block\GlazedTerracotta;
|
||||
@ -103,6 +104,7 @@ use pocketmine\block\utils\MushroomBlockType;
|
||||
use pocketmine\block\utils\PoweredByRedstone;
|
||||
use pocketmine\block\VanillaBlocks as Blocks;
|
||||
use pocketmine\block\Vine;
|
||||
use pocketmine\block\OminousWallBanner;
|
||||
use pocketmine\data\bedrock\block\BlockLegacyMetadata;
|
||||
use pocketmine\data\bedrock\block\BlockStateDeserializeException;
|
||||
use pocketmine\data\bedrock\block\BlockStateNames as StateNames;
|
||||
@ -154,7 +156,7 @@ final class VanillaBlockMappings{
|
||||
self::registerChemistryMappings($reg, $commonProperties);
|
||||
self::register1to1CustomMappings($reg, $commonProperties);
|
||||
|
||||
self::registerSplitMappings($reg);
|
||||
self::registerSplitMappings($reg, $commonProperties);
|
||||
}
|
||||
|
||||
private static function registerSimpleIdOnlyMappings(BlockSerializerDeserializerRegistrar $reg) : void{
|
||||
@ -1476,7 +1478,7 @@ final class VanillaBlockMappings{
|
||||
* These currently can't be registered in a unified way, and due to their small number it may not be worth the
|
||||
* effort to implement a unified way to deal with them
|
||||
*/
|
||||
private static function registerSplitMappings(BlockSerializerDeserializerRegistrar $reg) : void{
|
||||
private static function registerSplitMappings(BlockSerializerDeserializerRegistrar $reg, CommonProperties $commonProperties) : void{
|
||||
//big dripleaf - split into head / stem variants, as stems don't have tilt or leaf state
|
||||
$reg->serializer->map(Blocks::BIG_DRIPLEAF_HEAD(), function(BigDripleafHead $block) : Writer{
|
||||
return Writer::create(Ids::BIG_DRIPLEAF)
|
||||
@ -1557,5 +1559,18 @@ final class VanillaBlockMappings{
|
||||
->setAge(min($growth - PitcherCrop::MAX_AGE - 1, DoublePitcherCrop::MAX_AGE))
|
||||
->setTop($top);
|
||||
});
|
||||
|
||||
//these only exist within PM (mapped from tile properties) as they don't support the same properties as a
|
||||
//normal banner
|
||||
$reg->serializer->map(Blocks::OMINOUS_BANNER(), function(OminousFloorBanner $block) use ($commonProperties) : Writer{
|
||||
$writer = Writer::create(Ids::STANDING_BANNER);
|
||||
$commonProperties->floorSignLikeRotation->serialize($block, $writer);
|
||||
return $writer;
|
||||
});
|
||||
$reg->serializer->map(Blocks::OMINOUS_WALL_BANNER(), function(OminousWallBanner $block) use ($commonProperties) : Writer{
|
||||
$writer = Writer::create(Ids::WALL_BANNER);
|
||||
$commonProperties->horizontalFacingClassic->serialize($block, $writer);
|
||||
return $writer;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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{
|
||||
|
||||
@ -487,14 +489,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 +544,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;
|
||||
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()));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -334,8 +334,9 @@ 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 FIRST_UNUSED_ITEM_ID = 20298;
|
||||
public const FIRST_UNUSED_ITEM_ID = 20299;
|
||||
|
||||
private static int $nextDynamicId = self::FIRST_UNUSED_ITEM_ID;
|
||||
|
||||
|
@ -242,6 +242,7 @@ use function strtolower;
|
||||
* @method static Item NETHER_STAR()
|
||||
* @method static Boat OAK_BOAT()
|
||||
* @method static ItemBlockWallOrFloor OAK_SIGN()
|
||||
* @method static ItemBlockWallOrFloor OMINOUS_BANNER()
|
||||
* @method static PaintingItem PAINTING()
|
||||
* @method static ItemBlockWallOrFloor PALE_OAK_SIGN()
|
||||
* @method static Item PAPER()
|
||||
@ -540,6 +541,7 @@ 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("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("paper", fn(IID $id) => new Item($id, "Paper"));
|
||||
|
Loading…
x
Reference in New Issue
Block a user