mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-10 07:49:42 +00:00
Added SkullType enum, some cleanup to skull handling
this is still more ugly than I'd like it to be because of the way the blockfactory currently works.
This commit is contained in:
parent
edf4a719d5
commit
cb91afcc00
@ -24,24 +24,33 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataValidator;
|
||||
use pocketmine\block\utils\SkullType;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Skull as ItemSkull;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\tile\Skull as TileSkull;
|
||||
use function assert;
|
||||
use function floor;
|
||||
|
||||
class Skull extends Flowable{
|
||||
/** @var SkullType */
|
||||
protected $skullType;
|
||||
|
||||
/** @var int */
|
||||
protected $facing = Facing::NORTH;
|
||||
|
||||
protected $type = TileSkull::TYPE_SKELETON;
|
||||
/** @var int */
|
||||
protected $rotation = 0; //TODO: split this into floor skull and wall skull handling
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name){
|
||||
$this->skullType = SkullType::SKELETON(); //TODO: this should be a parameter
|
||||
parent::__construct($idInfo, $name);
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return $this->facing;
|
||||
}
|
||||
@ -58,7 +67,7 @@ class Skull extends Flowable{
|
||||
parent::readStateFromWorld();
|
||||
$tile = $this->level->getTile($this);
|
||||
if($tile instanceof TileSkull){
|
||||
$this->type = $tile->getType();
|
||||
$this->skullType = $tile->getSkullType();
|
||||
$this->rotation = $tile->getRotation();
|
||||
}
|
||||
}
|
||||
@ -67,16 +76,22 @@ class Skull extends Flowable{
|
||||
parent::writeStateToWorld();
|
||||
//extra block properties storage hack
|
||||
$tile = $this->level->getTile($this);
|
||||
if($tile instanceof TileSkull){
|
||||
$tile->setRotation($this->rotation);
|
||||
$tile->setType($this->type);
|
||||
}
|
||||
assert($tile instanceof TileSkull);
|
||||
$tile->setRotation($this->rotation);
|
||||
$tile->setSkullType($this->skullType);
|
||||
}
|
||||
|
||||
public function getHardness() : float{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SkullType
|
||||
*/
|
||||
public function getSkullType() : SkullType{
|
||||
return $this->skullType;
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox() : ?AxisAlignedBB{
|
||||
//TODO: different bounds depending on attached face
|
||||
return AxisAlignedBB::one()->contract(0.25, 0, 0.25)->trim(Facing::UP, 0.5);
|
||||
@ -88,7 +103,9 @@ class Skull extends Flowable{
|
||||
}
|
||||
|
||||
$this->facing = $face;
|
||||
$this->type = $item->getDamage(); //TODO: replace this with a proper variant getter
|
||||
if($item instanceof ItemSkull){
|
||||
$this->skullType = $item->getSkullType(); //TODO: the item should handle this, but this hack is currently needed because of tile mess
|
||||
}
|
||||
if($player !== null and $face === Facing::UP){
|
||||
$this->rotation = ((int) floor(($player->yaw * 16 / 360) + 0.5)) & 0xf;
|
||||
}
|
||||
@ -96,7 +113,7 @@ class Skull extends Flowable{
|
||||
}
|
||||
|
||||
public function asItem() : Item{
|
||||
return ItemFactory::get(Item::SKULL, $this->type);
|
||||
return ItemFactory::get(Item::SKULL, $this->skullType->getMagicNumber());
|
||||
}
|
||||
|
||||
public function isAffectedBySilkTouch() : bool{
|
||||
|
131
src/pocketmine/block/utils/SkullType.php
Normal file
131
src/pocketmine/block/utils/SkullType.php
Normal file
@ -0,0 +1,131 @@
|
||||
<?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\utils;
|
||||
|
||||
final class SkullType{
|
||||
|
||||
/** @var SkullType */
|
||||
private static $SKELETON;
|
||||
/** @var SkullType */
|
||||
private static $WITHER_SKELETON;
|
||||
/** @var SkullType */
|
||||
private static $ZOMBIE;
|
||||
/** @var SkullType */
|
||||
private static $HUMAN;
|
||||
/** @var SkullType */
|
||||
private static $CREEPER;
|
||||
/** @var SkullType */
|
||||
private static $DRAGON;
|
||||
|
||||
/* auto-generated code */
|
||||
|
||||
public static function SKELETON() : SkullType{
|
||||
return self::$SKELETON;
|
||||
}
|
||||
|
||||
public static function WITHER_SKELETON() : SkullType{
|
||||
return self::$WITHER_SKELETON;
|
||||
}
|
||||
|
||||
public static function ZOMBIE() : SkullType{
|
||||
return self::$ZOMBIE;
|
||||
}
|
||||
|
||||
public static function HUMAN() : SkullType{
|
||||
return self::$HUMAN;
|
||||
}
|
||||
|
||||
public static function CREEPER() : SkullType{
|
||||
return self::$CREEPER;
|
||||
}
|
||||
|
||||
public static function DRAGON() : SkullType{
|
||||
return self::$DRAGON;
|
||||
}
|
||||
|
||||
/** @var SkullType[] */
|
||||
private static $all = [];
|
||||
/** @var SkullType[] */
|
||||
private static $numericIdMap = [];
|
||||
|
||||
public static function _init() : void{
|
||||
self::register(self::$SKELETON = new SkullType("Skeleton Skull", 0));
|
||||
self::register(self::$WITHER_SKELETON = new SkullType("Wither Skeleton Skull", 1));
|
||||
self::register(self::$ZOMBIE = new SkullType("Zombie Head", 2));
|
||||
self::register(self::$HUMAN = new SkullType("Player Head", 3));
|
||||
self::register(self::$CREEPER = new SkullType("Creeper Head", 4));
|
||||
self::register(self::$DRAGON = new SkullType("Dragon Head", 5));
|
||||
}
|
||||
|
||||
private static function register(SkullType $type) : void{
|
||||
self::$numericIdMap[$type->getMagicNumber()] = $type;
|
||||
self::$all[] = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SkullType[]
|
||||
*/
|
||||
public static function getAll() : array{
|
||||
return self::$all;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @param int $magicNumber
|
||||
*
|
||||
* @return SkullType
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public static function fromMagicNumber(int $magicNumber) : SkullType{
|
||||
if(!isset(self::$numericIdMap[$magicNumber])){
|
||||
throw new \InvalidArgumentException("Unknown skull type magic number $magicNumber");
|
||||
}
|
||||
return self::$numericIdMap[$magicNumber];
|
||||
}
|
||||
|
||||
/** @var string */
|
||||
private $displayName;
|
||||
/** @var int */
|
||||
private $magicNumber;
|
||||
|
||||
public function __construct(string $displayName, int $magicNumber){
|
||||
$this->displayName = $displayName;
|
||||
$this->magicNumber = $magicNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDisplayName() : string{
|
||||
return $this->displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getMagicNumber() : int{
|
||||
return $this->magicNumber;
|
||||
}
|
||||
}
|
||||
SkullType::_init();
|
@ -26,10 +26,10 @@ namespace pocketmine\item;
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\SkullType;
|
||||
use pocketmine\entity\EntityFactory;
|
||||
use pocketmine\entity\Living;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\tile\Skull;
|
||||
use function constant;
|
||||
use function defined;
|
||||
use function explode;
|
||||
@ -172,12 +172,6 @@ class ItemFactory{
|
||||
self::register(new ItemBlock(Block::NETHER_WART_PLANT, 0, Item::NETHER_WART));
|
||||
self::register(new ItemBlock(Block::OAK_DOOR_BLOCK, 0, Item::OAK_DOOR));
|
||||
self::register(new ItemBlock(Block::REPEATER_BLOCK, 0, Item::REPEATER));
|
||||
self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_CREEPER, Item::SKULL));
|
||||
self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_DRAGON, Item::SKULL));
|
||||
self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_HUMAN, Item::SKULL));
|
||||
self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_SKELETON, Item::SKULL));
|
||||
self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_WITHER, Item::SKULL));
|
||||
self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_ZOMBIE, Item::SKULL));
|
||||
self::register(new ItemBlock(Block::SPRUCE_DOOR_BLOCK, 0, Item::SPRUCE_DOOR));
|
||||
self::register(new ItemBlock(Block::SUGARCANE_BLOCK, 0, Item::SUGARCANE));
|
||||
self::register(new LeatherBoots());
|
||||
@ -236,6 +230,10 @@ class ItemFactory{
|
||||
self::register(new WritableBook());
|
||||
self::register(new WrittenBook());
|
||||
|
||||
foreach(SkullType::getAll() as $skullType){
|
||||
self::register(new Skull(Item::SKULL, $skullType->getMagicNumber(), $skullType->getDisplayName(), $skullType));
|
||||
}
|
||||
|
||||
/** @var int[]|\SplObjectStorage $dyeMap */
|
||||
$dyeMap = new \SplObjectStorage();
|
||||
$dyeMap[DyeColor::BLACK()] = 16;
|
||||
|
47
src/pocketmine/item/Skull.php
Normal file
47
src/pocketmine/item/Skull.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?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\BlockFactory;
|
||||
use pocketmine\block\utils\SkullType;
|
||||
|
||||
class Skull extends Item{
|
||||
|
||||
/** @var SkullType */
|
||||
private $skullType;
|
||||
|
||||
public function __construct(int $id, int $variant, string $name, SkullType $skullType){
|
||||
parent::__construct($id, $variant, $name);
|
||||
$this->skullType = $skullType;
|
||||
}
|
||||
|
||||
public function getBlock() : Block{
|
||||
return BlockFactory::get(Block::SKULL_BLOCK);
|
||||
}
|
||||
|
||||
public function getSkullType() : SkullType{
|
||||
return $this->skullType;
|
||||
}
|
||||
}
|
@ -23,42 +23,58 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\tile;
|
||||
|
||||
use pocketmine\block\utils\SkullType;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\ByteTag;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @see \pocketmine\block\Skull
|
||||
*/
|
||||
class Skull extends Spawnable{
|
||||
public const TYPE_SKELETON = 0;
|
||||
public const TYPE_WITHER = 1;
|
||||
public const TYPE_ZOMBIE = 2;
|
||||
public const TYPE_HUMAN = 3;
|
||||
public const TYPE_CREEPER = 4;
|
||||
public const TYPE_DRAGON = 5;
|
||||
|
||||
public const TAG_SKULL_TYPE = "SkullType"; //TAG_Byte
|
||||
public const TAG_ROT = "Rot"; //TAG_Byte
|
||||
public const TAG_MOUTH_MOVING = "MouthMoving"; //TAG_Byte
|
||||
public const TAG_MOUTH_TICK_COUNT = "MouthTickCount"; //TAG_Int
|
||||
private const TAG_SKULL_TYPE = "SkullType"; //TAG_Byte
|
||||
private const TAG_ROT = "Rot"; //TAG_Byte
|
||||
private const TAG_MOUTH_MOVING = "MouthMoving"; //TAG_Byte
|
||||
private const TAG_MOUTH_TICK_COUNT = "MouthTickCount"; //TAG_Int
|
||||
|
||||
/** @var int */
|
||||
private $skullType = self::TYPE_SKELETON;
|
||||
/** @var SkullType */
|
||||
private $skullType;
|
||||
/** @var int */
|
||||
private $skullRotation = 0;
|
||||
|
||||
public function __construct(Level $level, Vector3 $pos){
|
||||
$this->skullType = SkullType::SKELETON();
|
||||
parent::__construct($level, $pos);
|
||||
}
|
||||
|
||||
public function readSaveData(CompoundTag $nbt) : void{
|
||||
$this->skullType = $nbt->getByte(self::TAG_SKULL_TYPE, $this->skullType, true);
|
||||
$this->skullRotation = $nbt->getByte(self::TAG_ROT, $this->skullRotation, true);
|
||||
if($nbt->hasTag(self::TAG_SKULL_TYPE, ByteTag::class)){
|
||||
try{
|
||||
$this->skullType = SkullType::fromMagicNumber($nbt->getByte(self::TAG_SKULL_TYPE));
|
||||
}catch(\InvalidArgumentException $e){
|
||||
//bad data, drop it
|
||||
}
|
||||
}
|
||||
$rotation = $nbt->getByte(self::TAG_ROT, 0, true);
|
||||
if($rotation >= 0 and $rotation <= 15){
|
||||
$this->skullRotation = $rotation;
|
||||
}
|
||||
}
|
||||
|
||||
protected function writeSaveData(CompoundTag $nbt) : void{
|
||||
$nbt->setByte(self::TAG_SKULL_TYPE, $this->skullType);
|
||||
$nbt->setByte(self::TAG_SKULL_TYPE, $this->skullType->getMagicNumber());
|
||||
$nbt->setByte(self::TAG_ROT, $this->skullRotation);
|
||||
}
|
||||
|
||||
public function setType(int $type){
|
||||
public function setSkullType(SkullType $type){
|
||||
$this->skullType = $type;
|
||||
$this->onChanged();
|
||||
}
|
||||
|
||||
public function getType() : int{
|
||||
public function getSkullType() : SkullType{
|
||||
return $this->skullType;
|
||||
}
|
||||
|
||||
@ -72,7 +88,7 @@ class Skull extends Spawnable{
|
||||
}
|
||||
|
||||
protected function addAdditionalSpawnData(CompoundTag $nbt) : void{
|
||||
$nbt->setByte(self::TAG_SKULL_TYPE, $this->skullType);
|
||||
$nbt->setByte(self::TAG_SKULL_TYPE, $this->skullType->getMagicNumber());
|
||||
$nbt->setByte(self::TAG_ROT, $this->skullRotation);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user