mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-20 16:00:20 +00:00
Move mob head and note instrument save IDs into pocketmine\data\bedrock
to be consistent, these shouldn't be exposed in the API like this... I'm not very happy with the whole 'type ID map' paradigm (particularly its lack of static analysis guarantees), but the most important thing right now is to get this stuff out of the API so that plugin devs don't try and abuse it. We're not going to change the whole system days before PM5 release.
This commit is contained in:
parent
bdb0ed0701
commit
fddab29e87
@ -24,6 +24,8 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block\tile;
|
||||
|
||||
use pocketmine\block\utils\MobHeadType;
|
||||
use pocketmine\data\bedrock\MobHeadTypeIdMap;
|
||||
use pocketmine\data\SavedDataLoadingException;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\ByteTag;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
@ -50,11 +52,11 @@ class MobHead extends Spawnable{
|
||||
|
||||
public function readSaveData(CompoundTag $nbt) : void{
|
||||
if(($skullTypeTag = $nbt->getTag(self::TAG_SKULL_TYPE)) instanceof ByteTag){
|
||||
try{
|
||||
$this->mobHeadType = MobHeadType::fromMagicNumber($skullTypeTag->getValue());
|
||||
}catch(\InvalidArgumentException $e){
|
||||
//bad data, drop it
|
||||
$mobHeadType = MobHeadTypeIdMap::getInstance()->fromId($skullTypeTag->getValue());
|
||||
if($mobHeadType === null){
|
||||
throw new SavedDataLoadingException("Invalid skull type tag value " . $skullTypeTag->getValue());
|
||||
}
|
||||
$this->mobHeadType = $mobHeadType;
|
||||
}
|
||||
$rotation = $nbt->getByte(self::TAG_ROT, 0);
|
||||
if($rotation >= 0 && $rotation <= 15){
|
||||
@ -63,7 +65,7 @@ class MobHead extends Spawnable{
|
||||
}
|
||||
|
||||
protected function writeSaveData(CompoundTag $nbt) : void{
|
||||
$nbt->setByte(self::TAG_SKULL_TYPE, $this->mobHeadType->getMagicNumber());
|
||||
$nbt->setByte(self::TAG_SKULL_TYPE, MobHeadTypeIdMap::getInstance()->toId($this->mobHeadType));
|
||||
$nbt->setByte(self::TAG_ROT, $this->rotation);
|
||||
}
|
||||
|
||||
@ -84,7 +86,7 @@ class MobHead extends Spawnable{
|
||||
}
|
||||
|
||||
protected function addAdditionalSpawnData(CompoundTag $nbt) : void{
|
||||
$nbt->setByte(self::TAG_SKULL_TYPE, $this->mobHeadType->getMagicNumber());
|
||||
$nbt->setByte(self::TAG_SKULL_TYPE, MobHeadTypeIdMap::getInstance()->toId($this->mobHeadType));
|
||||
$nbt->setByte(self::TAG_ROT, $this->rotation);
|
||||
}
|
||||
}
|
||||
|
@ -40,45 +40,23 @@ use pocketmine\utils\EnumTrait;
|
||||
*/
|
||||
final class MobHeadType{
|
||||
use EnumTrait {
|
||||
register as Enum_register;
|
||||
__construct as Enum___construct;
|
||||
}
|
||||
|
||||
/** @var MobHeadType[] */
|
||||
private static array $numericIdMap = [];
|
||||
|
||||
protected static function setup() : void{
|
||||
self::registerAll(
|
||||
new MobHeadType("skeleton", "Skeleton Skull", 0),
|
||||
new MobHeadType("wither_skeleton", "Wither Skeleton Skull", 1),
|
||||
new MobHeadType("zombie", "Zombie Head", 2),
|
||||
new MobHeadType("player", "Player Head", 3),
|
||||
new MobHeadType("creeper", "Creeper Head", 4),
|
||||
new MobHeadType("dragon", "Dragon Head", 5)
|
||||
new MobHeadType("skeleton", "Skeleton Skull"),
|
||||
new MobHeadType("wither_skeleton", "Wither Skeleton Skull"),
|
||||
new MobHeadType("zombie", "Zombie Head"),
|
||||
new MobHeadType("player", "Player Head"),
|
||||
new MobHeadType("creeper", "Creeper Head"),
|
||||
new MobHeadType("dragon", "Dragon Head")
|
||||
);
|
||||
}
|
||||
|
||||
protected static function register(MobHeadType $type) : void{
|
||||
self::Enum_register($type);
|
||||
self::$numericIdMap[$type->getMagicNumber()] = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public static function fromMagicNumber(int $magicNumber) : MobHeadType{
|
||||
if(!isset(self::$numericIdMap[$magicNumber])){
|
||||
throw new \InvalidArgumentException("Unknown skull type magic number $magicNumber");
|
||||
}
|
||||
return self::$numericIdMap[$magicNumber];
|
||||
}
|
||||
|
||||
private function __construct(
|
||||
string $enumName,
|
||||
private string $displayName,
|
||||
private int $magicNumber
|
||||
private string $displayName
|
||||
){
|
||||
$this->Enum___construct($enumName);
|
||||
}
|
||||
@ -86,8 +64,4 @@ final class MobHeadType{
|
||||
public function getDisplayName() : string{
|
||||
return $this->displayName;
|
||||
}
|
||||
|
||||
public function getMagicNumber() : int{
|
||||
return $this->magicNumber;
|
||||
}
|
||||
}
|
||||
|
68
src/data/bedrock/MobHeadTypeIdMap.php
Normal file
68
src/data/bedrock/MobHeadTypeIdMap.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?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;
|
||||
|
||||
use pocketmine\block\utils\MobHeadType;
|
||||
use pocketmine\utils\SingletonTrait;
|
||||
|
||||
final class MobHeadTypeIdMap{
|
||||
use SingletonTrait;
|
||||
|
||||
/**
|
||||
* @var MobHeadType[]
|
||||
* @phpstan-var array<int, MobHeadType>
|
||||
*/
|
||||
private array $idToEnum = [];
|
||||
|
||||
/**
|
||||
* @var int[]
|
||||
* @phpstan-var array<int, int>
|
||||
*/
|
||||
private array $enumToId = [];
|
||||
|
||||
private function __construct(){
|
||||
$this->register(0, MobHeadType::SKELETON());
|
||||
$this->register(1, MobHeadType::WITHER_SKELETON());
|
||||
$this->register(2, MobHeadType::ZOMBIE());
|
||||
$this->register(3, MobHeadType::PLAYER());
|
||||
$this->register(4, MobHeadType::CREEPER());
|
||||
$this->register(5, MobHeadType::DRAGON());
|
||||
}
|
||||
|
||||
private function register(int $id, MobHeadType $type) : void{
|
||||
$this->idToEnum[$id] = $type;
|
||||
$this->enumToId[$type->id()] = $id;
|
||||
}
|
||||
|
||||
public function fromId(int $id) : ?MobHeadType{
|
||||
return $this->idToEnum[$id] ?? null;
|
||||
}
|
||||
|
||||
public function toId(MobHeadType $type) : int{
|
||||
if(!isset($this->enumToId[$type->id()])){
|
||||
throw new \InvalidArgumentException("Type does not have a mapped ID");
|
||||
}
|
||||
return $this->enumToId[$type->id()];
|
||||
}
|
||||
}
|
67
src/data/bedrock/NoteInstrumentIdMap.php
Normal file
67
src/data/bedrock/NoteInstrumentIdMap.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?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;
|
||||
|
||||
use pocketmine\utils\SingletonTrait;
|
||||
use pocketmine\world\sound\NoteInstrument;
|
||||
|
||||
final class NoteInstrumentIdMap{
|
||||
use SingletonTrait;
|
||||
|
||||
/**
|
||||
* @var NoteInstrument[]
|
||||
* @phpstan-var array<int, NoteInstrument>
|
||||
*/
|
||||
private array $idToEnum = [];
|
||||
|
||||
/**
|
||||
* @var int[]
|
||||
* @phpstan-var array<int, int>
|
||||
*/
|
||||
private array $enumToId = [];
|
||||
|
||||
private function __construct(){
|
||||
$this->register(0, NoteInstrument::PIANO());
|
||||
$this->register(1, NoteInstrument::BASS_DRUM());
|
||||
$this->register(2, NoteInstrument::SNARE());
|
||||
$this->register(3, NoteInstrument::CLICKS_AND_STICKS());
|
||||
$this->register(4, NoteInstrument::DOUBLE_BASS());
|
||||
}
|
||||
|
||||
private function register(int $id, NoteInstrument $instrument) : void{
|
||||
$this->idToEnum[$id] = $instrument;
|
||||
$this->enumToId[$instrument->id()] = $id;
|
||||
}
|
||||
|
||||
public function fromId(int $id) : ?NoteInstrument{
|
||||
return $this->idToEnum[$id] ?? null;
|
||||
}
|
||||
|
||||
public function toId(NoteInstrument $instrument) : int{
|
||||
if(!isset($this->enumToId[$instrument->id()])){
|
||||
throw new \InvalidArgumentException("Type does not have a mapped ID");
|
||||
}
|
||||
return $this->enumToId[$instrument->id()];
|
||||
}
|
||||
}
|
@ -27,13 +27,13 @@ use pocketmine\block\Bed;
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\MobHead;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\MobHeadType;
|
||||
use pocketmine\block\VanillaBlocks as Blocks;
|
||||
use pocketmine\data\bedrock\CompoundTypeIds;
|
||||
use pocketmine\data\bedrock\DyeColorIdMap;
|
||||
use pocketmine\data\bedrock\item\ItemTypeNames as Ids;
|
||||
use pocketmine\data\bedrock\item\SavedItemData as Data;
|
||||
use pocketmine\data\bedrock\MedicineTypeIdMap;
|
||||
use pocketmine\data\bedrock\MobHeadTypeIdMap;
|
||||
use pocketmine\data\bedrock\PotionTypeIdMap;
|
||||
use pocketmine\data\bedrock\SuspiciousStewTypeIdMap;
|
||||
use pocketmine\item\Banner;
|
||||
@ -445,14 +445,9 @@ final class ItemSerializerDeserializerRegistrar{
|
||||
Ids::SKULL,
|
||||
Blocks::MOB_HEAD(),
|
||||
function(MobHead $block, int $meta) : void{
|
||||
try{
|
||||
$skullType = MobHeadType::fromMagicNumber($meta);
|
||||
}catch(\InvalidArgumentException $e){
|
||||
throw new ItemTypeDeserializeException($e->getMessage(), 0, $e);
|
||||
}
|
||||
$block->setMobHeadType($skullType);
|
||||
$block->setMobHeadType(MobHeadTypeIdMap::getInstance()->fromId($meta) ?? throw new ItemTypeDeserializeException("Unknown mob head type ID $meta"));
|
||||
},
|
||||
fn(MobHead $block) => $block->getMobHeadType()->getMagicNumber()
|
||||
fn(MobHead $block) => MobHeadTypeIdMap::getInstance()->toId($block->getMobHeadType())
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -38,28 +38,15 @@ use pocketmine\utils\EnumTrait;
|
||||
* @method static NoteInstrument SNARE()
|
||||
*/
|
||||
final class NoteInstrument{
|
||||
use EnumTrait {
|
||||
__construct as Enum___construct;
|
||||
}
|
||||
use EnumTrait;
|
||||
|
||||
protected static function setup() : void{
|
||||
self::registerAll(
|
||||
new self("piano", 0),
|
||||
new self("bass_drum", 1),
|
||||
new self("snare", 2),
|
||||
new self("clicks_and_sticks", 3),
|
||||
new self("double_bass", 4)
|
||||
new self("piano"),
|
||||
new self("bass_drum"),
|
||||
new self("snare"),
|
||||
new self("clicks_and_sticks"),
|
||||
new self("double_bass")
|
||||
);
|
||||
}
|
||||
|
||||
private function __construct(
|
||||
string $name,
|
||||
private int $magicNumber
|
||||
){
|
||||
$this->Enum___construct($name);
|
||||
}
|
||||
|
||||
public function getMagicNumber() : int{
|
||||
return $this->magicNumber;
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\world\sound;
|
||||
|
||||
use pocketmine\data\bedrock\NoteInstrumentIdMap;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\mcpe\protocol\LevelSoundEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\types\LevelSoundEvent;
|
||||
@ -38,6 +39,7 @@ class NoteSound implements Sound{
|
||||
}
|
||||
|
||||
public function encode(Vector3 $pos) : array{
|
||||
return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::NOTE, $pos, false, ($this->instrument->getMagicNumber() << 8) | $this->note)];
|
||||
$instrumentId = NoteInstrumentIdMap::getInstance()->toId($this->instrument);
|
||||
return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::NOTE, $pos, false, ($instrumentId << 8) | $this->note)];
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user