mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-11 16:29:40 +00:00
Block: Replace Color and WoodType magic numbers with type-safe objects
this provides automatic type safety without the need for magic number value checking everywhere.
This commit is contained in:
parent
18440f612f
commit
7b3993730a
@ -24,7 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataValidator;
|
||||
use pocketmine\block\utils\Color;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\lang\TranslationContainer;
|
||||
@ -52,11 +52,11 @@ class Bed extends Transparent{
|
||||
protected $occupied = false;
|
||||
/** @var bool */
|
||||
protected $head = false;
|
||||
/** @var int */
|
||||
protected $color = Color::RED;
|
||||
/** @var DyeColor */
|
||||
protected $color;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
$this->color = DyeColor::$RED;
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
@ -183,7 +183,7 @@ class Bed extends Transparent{
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$this->color = $item->getDamage(); //TODO: replace this with a proper colour getter
|
||||
$this->color = DyeColor::fromMagicNumber($item->getDamage()); //TODO: replace this with a proper colour getter
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if(!$down->isTransparent()){
|
||||
$this->facing = $player !== null ? $player->getHorizontalFacing() : Facing::NORTH;
|
||||
@ -211,7 +211,7 @@ class Bed extends Transparent{
|
||||
}
|
||||
|
||||
public function getItem() : Item{
|
||||
return ItemFactory::get($this->getItemId(), $this->color);
|
||||
return ItemFactory::get($this->getItemId(), $this->color->getMagicNumber());
|
||||
}
|
||||
|
||||
public function isAffectedBySilkTouch() : bool{
|
||||
|
@ -23,10 +23,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\Color;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\InvalidBlockStateException;
|
||||
use pocketmine\block\utils\PillarRotationTrait;
|
||||
use pocketmine\block\utils\WoodType;
|
||||
use pocketmine\block\utils\TreeType;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Position;
|
||||
use function array_fill;
|
||||
@ -93,17 +93,17 @@ class BlockFactory{
|
||||
|
||||
self::registerBlock(new Cobblestone());
|
||||
|
||||
foreach(WoodType::ALL as $type){
|
||||
self::registerBlock(new Planks(Block::PLANKS, $type, WoodType::NAMES[$type] . " Planks"));
|
||||
self::registerBlock(new Sapling(Block::SAPLING, $type, WoodType::NAMES[$type] . " Sapling"));
|
||||
self::registerBlock(new WoodenFence(Block::FENCE, $type, WoodType::NAMES[$type] . " Fence"));
|
||||
}
|
||||
foreach(TreeType::getAll() as $treeType){
|
||||
$magicNumber = $treeType->getMagicNumber();
|
||||
$name = $treeType->getDisplayName();
|
||||
self::registerBlock(new Planks(Block::PLANKS, $magicNumber, $name . " Planks"));
|
||||
self::registerBlock(new Sapling(Block::SAPLING, $magicNumber, $treeType, $name . " Sapling"));
|
||||
self::registerBlock(new WoodenFence(Block::FENCE, $magicNumber, $name . " Fence"));
|
||||
|
||||
foreach(WoodType::ALL as $type){
|
||||
//TODO: find a better way to deal with this split
|
||||
self::registerBlock(new Log($type >= 4 ? Block::WOOD2 : Block::WOOD, $type & 0x03, WoodType::NAMES[$type] . " Log"));
|
||||
self::registerBlock(new Wood($type >= 4 ? Block::WOOD2 : Block::WOOD, ($type & 0x03) | 0b1100, WoodType::NAMES[$type] . " Wood"));
|
||||
self::registerBlock(new Leaves($type >= 4 ? Block::LEAVES2 : Block::LEAVES, $type & 0x03, $type, WoodType::NAMES[$type] . " Leaves"));
|
||||
self::registerBlock(new Log($magicNumber >= 4 ? Block::WOOD2 : Block::WOOD, $magicNumber & 0x03, $treeType, $name . " Log"));
|
||||
self::registerBlock(new Wood($magicNumber >= 4 ? Block::WOOD2 : Block::WOOD, ($magicNumber & 0x03) | 0b1100, $treeType, $name . " Wood"));
|
||||
self::registerBlock(new Leaves($magicNumber >= 4 ? Block::LEAVES2 : Block::LEAVES, $magicNumber & 0x03, $treeType, $name . " Leaves"));
|
||||
}
|
||||
|
||||
self::registerBlock(new Bedrock());
|
||||
@ -151,14 +151,14 @@ class BlockFactory{
|
||||
//TODO: PISTON
|
||||
//TODO: PISTONARMCOLLISION
|
||||
|
||||
foreach(Color::ALL as $color){
|
||||
self::registerBlock(new Wool(Block::WOOL, $color, Color::NAMES[$color] . " Wool"));
|
||||
self::registerBlock(new HardenedClay(Block::STAINED_CLAY, $color, Color::NAMES[$color] . " Stained Clay"));
|
||||
self::registerBlock(new Glass(Block::STAINED_GLASS, $color, Color::NAMES[$color] . " Stained Glass"));
|
||||
self::registerBlock(new GlassPane(Block::STAINED_GLASS_PANE, $color, Color::NAMES[$color] . " Stained Glass Pane"));
|
||||
self::registerBlock(new Carpet(Block::CARPET, $color, Color::NAMES[$color] . " Carpet"));
|
||||
self::registerBlock(new Concrete(Block::CONCRETE, $color, Color::NAMES[$color] . " Concrete"));
|
||||
self::registerBlock(new ConcretePowder(Block::CONCRETE_POWDER, $color, Color::NAMES[$color] . " Concrete Powder"));
|
||||
foreach(DyeColor::getAll() as $color){
|
||||
self::registerBlock(new Wool(Block::WOOL, $color->getMagicNumber(), $color->getDisplayName() . " Wool"));
|
||||
self::registerBlock(new HardenedClay(Block::STAINED_CLAY, $color->getMagicNumber(), $color->getDisplayName() . " Stained Clay"));
|
||||
self::registerBlock(new Glass(Block::STAINED_GLASS, $color->getMagicNumber(), $color->getDisplayName() . " Stained Glass"));
|
||||
self::registerBlock(new GlassPane(Block::STAINED_GLASS_PANE, $color->getMagicNumber(), $color->getDisplayName() . " Stained Glass Pane"));
|
||||
self::registerBlock(new Carpet(Block::CARPET, $color->getMagicNumber(), $color->getDisplayName() . " Carpet"));
|
||||
self::registerBlock(new Concrete(Block::CONCRETE, $color->getMagicNumber(), $color->getDisplayName() . " Concrete"));
|
||||
self::registerBlock(new ConcretePowder(Block::CONCRETE_POWDER, $color->getMagicNumber(), $color->getDisplayName() . " Concrete Powder"));
|
||||
}
|
||||
|
||||
self::registerBlock(new Dandelion());
|
||||
@ -197,8 +197,8 @@ class BlockFactory{
|
||||
new StoneSlab(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 6, "Smooth Sandstone"),
|
||||
new StoneSlab(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 7, "Red Nether Brick")
|
||||
];
|
||||
foreach(WoodType::ALL as $woodType){
|
||||
$slabTypes[] = new WoodenSlab($woodType);
|
||||
foreach(TreeType::getAll() as $woodType){
|
||||
$slabTypes[] = new WoodenSlab(Block::WOODEN_SLAB, Block::DOUBLE_WOODEN_SLAB, $woodType->getMagicNumber(), $woodType->getDisplayName());
|
||||
}
|
||||
foreach($slabTypes as $type){
|
||||
self::registerBlock($type);
|
||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataValidator;
|
||||
use pocketmine\block\utils\TreeType;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
@ -85,7 +86,7 @@ class CocoaBlock extends Transparent{
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
if(Facing::axis($face) !== Facing::AXIS_Y and $blockClicked->getId() === Block::LOG and $blockClicked->getVariant() === Wood::JUNGLE){
|
||||
if(Facing::axis($face) !== Facing::AXIS_Y and $blockClicked instanceof Wood and $blockClicked->getTreeType() === TreeType::$JUNGLE){
|
||||
$this->facing = $face;
|
||||
return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
@ -103,7 +104,7 @@ class CocoaBlock extends Transparent{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$side = $this->getSide(Facing::opposite($this->facing));
|
||||
if($side->getId() !== Block::LOG or $side->getVariant() !== Wood::JUNGLE){
|
||||
if(!($side instanceof Wood) or $side->getTreeType() !== TreeType::$JUNGLE){
|
||||
$this->level->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\WoodType;
|
||||
use pocketmine\block\utils\TreeType;
|
||||
use pocketmine\event\block\LeavesDecayEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
@ -34,17 +34,17 @@ use pocketmine\Player;
|
||||
use function mt_rand;
|
||||
|
||||
class Leaves extends Transparent{
|
||||
/** @var int */
|
||||
protected $woodType;
|
||||
/** @var TreeType */
|
||||
protected $treeType;
|
||||
|
||||
/** @var bool */
|
||||
protected $noDecay = false;
|
||||
/** @var bool */
|
||||
protected $checkDecay = false;
|
||||
|
||||
public function __construct(int $id, int $variant, int $woodType, ?string $name = null){
|
||||
public function __construct(int $id, int $variant, TreeType $treeType, ?string $name = null){
|
||||
parent::__construct($id, $variant, $name);
|
||||
$this->woodType = $woodType;
|
||||
$this->treeType = $treeType;
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
@ -132,9 +132,9 @@ class Leaves extends Transparent{
|
||||
|
||||
$drops = [];
|
||||
if(mt_rand(1, 20) === 1){ //Saplings
|
||||
$drops[] = ItemFactory::get(Item::SAPLING, $this->woodType);
|
||||
$drops[] = ItemFactory::get(Item::SAPLING, $this->treeType->getMagicNumber());
|
||||
}
|
||||
if(($this->woodType === WoodType::OAK or $this->woodType === WoodType::DARK_OAK) and mt_rand(1, 200) === 1){ //Apples
|
||||
if(($this->treeType === TreeType::$OAK or $this->treeType === TreeType::$DARK_OAK) and mt_rand(1, 200) === 1){ //Apples
|
||||
$drops[] = ItemFactory::get(Item::APPLE);
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\TreeType;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\generator\object\Tree;
|
||||
use pocketmine\math\Facing;
|
||||
@ -35,6 +36,13 @@ class Sapling extends Flowable{
|
||||
|
||||
/** @var bool */
|
||||
protected $ready = false;
|
||||
/** @var TreeType */
|
||||
private $treeType;
|
||||
|
||||
public function __construct(int $id, int $variant, TreeType $treeType, ?string $name = null, int $itemId = null){
|
||||
parent::__construct($id, $variant, $name, $itemId);
|
||||
$this->treeType = $treeType;
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return ($this->ready ? 0x08 : 0);
|
||||
@ -60,7 +68,7 @@ class Sapling extends Flowable{
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal
|
||||
//TODO: change log type
|
||||
Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->getVariant());
|
||||
Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->treeType);
|
||||
|
||||
$item->pop();
|
||||
|
||||
@ -83,7 +91,7 @@ class Sapling extends Flowable{
|
||||
public function onRandomTick() : void{
|
||||
if($this->level->getFullLightAt($this->x, $this->y, $this->z) >= 8 and mt_rand(1, 7) === 1){
|
||||
if($this->ready){
|
||||
Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->getVariant());
|
||||
Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->treeType);
|
||||
}else{
|
||||
$this->ready = true;
|
||||
$this->getLevel()->setBlock($this, $this);
|
||||
|
@ -23,11 +23,25 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\TreeType;
|
||||
|
||||
class Wood extends Solid{
|
||||
public const OAK = 0;
|
||||
public const SPRUCE = 1;
|
||||
public const BIRCH = 2;
|
||||
public const JUNGLE = 3;
|
||||
|
||||
/** @var TreeType */
|
||||
private $treeType;
|
||||
|
||||
public function __construct(int $id, int $variant, TreeType $treeType, ?string $name = null, int $itemId = null){
|
||||
parent::__construct($id, $variant, $name, $itemId);
|
||||
$this->treeType = $treeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: this is ad hoc, but add an interface for this to all tree-related blocks
|
||||
* @return TreeType
|
||||
*/
|
||||
public function getTreeType() : TreeType{
|
||||
return $this->treeType;
|
||||
}
|
||||
|
||||
public function getHardness() : float{
|
||||
return 2;
|
||||
|
@ -23,16 +23,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\WoodType;
|
||||
|
||||
class WoodenSlab extends Slab{
|
||||
|
||||
protected $id = self::WOODEN_SLAB;
|
||||
|
||||
public function __construct(int $variant = 0){
|
||||
parent::__construct(self::WOODEN_SLAB, self::DOUBLE_WOODEN_SLAB, $variant, WoodType::NAMES[$variant]);
|
||||
}
|
||||
|
||||
public function getHardness() : float{
|
||||
return 2;
|
||||
}
|
||||
|
@ -1,81 +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\block\utils;
|
||||
|
||||
class Color{
|
||||
public const WHITE = 0;
|
||||
public const ORANGE = 1;
|
||||
public const MAGENTA = 2;
|
||||
public const LIGHT_BLUE = 3;
|
||||
public const YELLOW = 4;
|
||||
public const LIME = 5;
|
||||
public const PINK = 6;
|
||||
public const GRAY = 7;
|
||||
public const LIGHT_GRAY = 8;
|
||||
public const CYAN = 9;
|
||||
public const PURPLE = 10;
|
||||
public const BLUE = 11;
|
||||
public const BROWN = 12;
|
||||
public const GREEN = 13;
|
||||
public const RED = 14;
|
||||
public const BLACK = 15;
|
||||
|
||||
public const ALL = [
|
||||
self::WHITE,
|
||||
self::ORANGE,
|
||||
self::MAGENTA,
|
||||
self::LIGHT_BLUE,
|
||||
self::YELLOW,
|
||||
self::LIME,
|
||||
self::PINK,
|
||||
self::GRAY,
|
||||
self::LIGHT_GRAY,
|
||||
self::CYAN,
|
||||
self::PURPLE,
|
||||
self::BLUE,
|
||||
self::BROWN,
|
||||
self::GREEN,
|
||||
self::RED,
|
||||
self::BLACK
|
||||
];
|
||||
|
||||
public const NAMES = [
|
||||
self::WHITE => "White",
|
||||
self::ORANGE => "Orange",
|
||||
self::MAGENTA => "Magenta",
|
||||
self::LIGHT_BLUE => "Light Blue",
|
||||
self::YELLOW => "Yellow",
|
||||
self::LIME => "Lime",
|
||||
self::PINK => "Pink",
|
||||
self::GRAY => "Gray",
|
||||
self::LIGHT_GRAY => "Light Gray",
|
||||
self::CYAN => "Cyan",
|
||||
self::PURPLE => "Purple",
|
||||
self::BLUE => "Blue",
|
||||
self::BROWN => "Brown",
|
||||
self::GREEN => "Green",
|
||||
self::RED => "Red",
|
||||
self::BLACK => "Black"
|
||||
];
|
||||
}
|
151
src/pocketmine/block/utils/DyeColor.php
Normal file
151
src/pocketmine/block/utils/DyeColor.php
Normal file
@ -0,0 +1,151 @@
|
||||
<?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 DyeColor{
|
||||
|
||||
/** @var DyeColor */
|
||||
public static $WHITE;
|
||||
/** @var DyeColor */
|
||||
public static $ORANGE;
|
||||
/** @var DyeColor */
|
||||
public static $MAGENTA;
|
||||
/** @var DyeColor */
|
||||
public static $LIGHT_BLUE;
|
||||
/** @var DyeColor */
|
||||
public static $YELLOW;
|
||||
/** @var DyeColor */
|
||||
public static $LIME;
|
||||
/** @var DyeColor */
|
||||
public static $PINK;
|
||||
/** @var DyeColor */
|
||||
public static $GRAY;
|
||||
/** @var DyeColor */
|
||||
public static $LIGHT_GRAY;
|
||||
/** @var DyeColor */
|
||||
public static $CYAN;
|
||||
/** @var DyeColor */
|
||||
public static $PURPLE;
|
||||
/** @var DyeColor */
|
||||
public static $BLUE;
|
||||
/** @var DyeColor */
|
||||
public static $BROWN;
|
||||
/** @var DyeColor */
|
||||
public static $GREEN;
|
||||
/** @var DyeColor */
|
||||
public static $RED;
|
||||
/** @var DyeColor */
|
||||
public static $BLACK;
|
||||
|
||||
/** @var DyeColor[] */
|
||||
private static $numericIdMap = [];
|
||||
/** @var DyeColor[] separate mapping that doesn't depend on magic numbers */
|
||||
private static $all = [];
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function _init() : void{
|
||||
self::register(self::$WHITE = new DyeColor("White", 0));
|
||||
self::register(self::$ORANGE = new DyeColor("Orange", 1));
|
||||
self::register(self::$MAGENTA = new DyeColor("Magenta", 2));
|
||||
self::register(self::$LIGHT_BLUE = new DyeColor("Light Blue", 3));
|
||||
self::register(self::$YELLOW = new DyeColor("Yellow", 4));
|
||||
self::register(self::$LIME = new DyeColor("Lime", 5));
|
||||
self::register(self::$PINK = new DyeColor("Pink", 6));
|
||||
self::register(self::$GRAY = new DyeColor("Gray", 7));
|
||||
self::register(self::$LIGHT_GRAY = new DyeColor("Light Gray", 8));
|
||||
self::register(self::$CYAN = new DyeColor("Cyan", 9));
|
||||
self::register(self::$PURPLE = new DyeColor("Purple", 10));
|
||||
self::register(self::$BLUE = new DyeColor("Blue", 11));
|
||||
self::register(self::$BROWN = new DyeColor("Brown", 12));
|
||||
self::register(self::$GREEN = new DyeColor("Green", 13));
|
||||
self::register(self::$RED = new DyeColor("Red", 14));
|
||||
self::register(self::$BLACK = new DyeColor("Black", 15));
|
||||
}
|
||||
|
||||
private static function register(DyeColor $color) : void{
|
||||
self::$numericIdMap[$color->getMagicNumber()] = $color;
|
||||
self::$all[] = $color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a set of all known dye colours.
|
||||
*
|
||||
* @return DyeColor[]
|
||||
*/
|
||||
public static function getAll() : array{
|
||||
return self::$all;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a DyeColor object matching the given magic number
|
||||
* @internal
|
||||
*
|
||||
* @param int $magicNumber
|
||||
* @param bool $inverted Invert the ID before using it (useful for actual dye magic IDs)
|
||||
*
|
||||
* @return DyeColor
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public static function fromMagicNumber(int $magicNumber, bool $inverted = false) : DyeColor{
|
||||
$real = $inverted ? ~$magicNumber & 0xf : $magicNumber;
|
||||
if(!isset(self::$numericIdMap[$real])){
|
||||
throw new \InvalidArgumentException("Unknown dye colour magic number $magicNumber");
|
||||
}
|
||||
return self::$numericIdMap[$real];
|
||||
}
|
||||
|
||||
/** @var string */
|
||||
private $displayName;
|
||||
/** @var int */
|
||||
private $magicNumber;
|
||||
|
||||
private 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getInvertedMagicNumber() : int{
|
||||
return ~$this->magicNumber & 0xf;
|
||||
}
|
||||
}
|
||||
DyeColor::_init();
|
112
src/pocketmine/block/utils/TreeType.php
Normal file
112
src/pocketmine/block/utils/TreeType.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?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 TreeType{
|
||||
|
||||
/** @var TreeType */
|
||||
public static $OAK;
|
||||
/** @var TreeType */
|
||||
public static $SPRUCE;
|
||||
/** @var TreeType */
|
||||
public static $BIRCH;
|
||||
/** @var TreeType */
|
||||
public static $JUNGLE;
|
||||
/** @var TreeType */
|
||||
public static $ACACIA;
|
||||
/** @var TreeType */
|
||||
public static $DARK_OAK;
|
||||
|
||||
/** @var TreeType[] */
|
||||
private static $numericIdMap = [];
|
||||
/** @var TreeType[] */
|
||||
private static $all = [];
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function _init() : void{
|
||||
self::register(self::$OAK = new TreeType("Oak", 0));
|
||||
self::register(self::$SPRUCE = new TreeType("Spruce", 1));
|
||||
self::register(self::$BIRCH = new TreeType("Birch", 2));
|
||||
self::register(self::$JUNGLE = new TreeType("Jungle", 3));
|
||||
self::register(self::$ACACIA = new TreeType("Acacia", 4));
|
||||
self::register(self::$DARK_OAK = new TreeType("Dark Oak", 5));
|
||||
}
|
||||
|
||||
private static function register(TreeType $type) : void{
|
||||
self::$numericIdMap[$type->getMagicNumber()] = $type;
|
||||
self::$all[] = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TreeType[]
|
||||
*/
|
||||
public static function getAll() : array{
|
||||
return self::$all;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @param int $magicNumber
|
||||
*
|
||||
* @return TreeType
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public static function fromMagicNumber(int $magicNumber) : TreeType{
|
||||
if(!isset(self::$numericIdMap[$magicNumber])){
|
||||
throw new \InvalidArgumentException("Unknown tree type magic number $magicNumber");
|
||||
}
|
||||
return self::$numericIdMap[$magicNumber];
|
||||
}
|
||||
|
||||
/** @var string */
|
||||
private $displayName;
|
||||
/** @var int */
|
||||
private $magicNumber;
|
||||
|
||||
/**
|
||||
* @param string $displayName
|
||||
* @param int $magicNumber
|
||||
*/
|
||||
private 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;
|
||||
}
|
||||
}
|
||||
TreeType::_init();
|
@ -1,51 +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\block\utils;
|
||||
|
||||
class WoodType{
|
||||
public const OAK = 0;
|
||||
public const SPRUCE = 1;
|
||||
public const BIRCH = 2;
|
||||
public const JUNGLE = 3;
|
||||
public const ACACIA = 4;
|
||||
public const DARK_OAK = 5;
|
||||
|
||||
public const ALL = [
|
||||
self::OAK,
|
||||
self::SPRUCE,
|
||||
self::BIRCH,
|
||||
self::JUNGLE,
|
||||
self::ACACIA,
|
||||
self::DARK_OAK
|
||||
];
|
||||
|
||||
public const NAMES = [
|
||||
self::OAK => "Oak",
|
||||
self::SPRUCE => "Spruce",
|
||||
self::BIRCH => "Birch",
|
||||
self::JUNGLE => "Jungle",
|
||||
self::ACACIA => "Acacia",
|
||||
self::DARK_OAK => "Dark Oak"
|
||||
];
|
||||
}
|
@ -38,8 +38,8 @@ class Banner extends Item{
|
||||
public const TAG_PATTERN_COLOR = TileBanner::TAG_PATTERN_COLOR;
|
||||
public const TAG_PATTERN_NAME = TileBanner::TAG_PATTERN_NAME;
|
||||
|
||||
public function __construct(int $variant){
|
||||
parent::__construct(self::BANNER, $variant, "Banner");
|
||||
public function __construct(int $variant, string $name){
|
||||
parent::__construct(self::BANNER, $variant, $name);
|
||||
}
|
||||
|
||||
public function getBlock() : Block{
|
||||
|
@ -27,8 +27,9 @@ use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
|
||||
class Bed extends Item{
|
||||
public function __construct(int $variant){
|
||||
parent::__construct(self::BED, $variant, "Bed");
|
||||
|
||||
public function __construct(int $variant, string $name){
|
||||
parent::__construct(self::BED, $variant, $name);
|
||||
}
|
||||
|
||||
public function getBlock() : Block{
|
||||
|
@ -27,8 +27,8 @@ use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
|
||||
class Dye extends Item{
|
||||
public function __construct(int $variant){
|
||||
parent::__construct(self::DYE, $variant, "Dye");
|
||||
public function __construct(int $variant, string $name){
|
||||
parent::__construct(self::DYE, $variant, $name);
|
||||
}
|
||||
|
||||
public function getBlock() : Block{
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\entity\EntityFactory;
|
||||
use pocketmine\entity\Living;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
@ -151,11 +152,13 @@ class ItemFactory{
|
||||
self::registerItem(new Item(Item::GLOWSTONE_DUST, 0, "Glowstone Dust"));
|
||||
self::registerItem(new RawFish());
|
||||
self::registerItem(new CookedFish());
|
||||
for($i = 0; $i < 16; ++$i){
|
||||
//TODO: add colour constants (this is messy)
|
||||
self::registerItem(new Dye($i));
|
||||
self::registerItem(new Bed($i));
|
||||
self::registerItem(new Banner($i));
|
||||
foreach(DyeColor::getAll() as $color){
|
||||
//TODO: use colour object directly
|
||||
//TODO: add interface to dye-colour objects
|
||||
//TODO: new dedicated dyes
|
||||
self::registerItem(new Dye($color->getInvertedMagicNumber(), $color->getDisplayName() . " Dye"));
|
||||
self::registerItem(new Bed($color->getMagicNumber(), $color->getDisplayName() . " Bed"));
|
||||
self::registerItem(new Banner($color->getInvertedMagicNumber(), $color->getDisplayName() . " Banner"));
|
||||
}
|
||||
self::registerItem(new Item(Item::BONE, 0, "Bone"));
|
||||
self::registerItem(new Item(Item::SUGAR, 0, "Sugar"));
|
||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\level\biome;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\utils\TreeType;
|
||||
use pocketmine\level\ChunkManager;
|
||||
use pocketmine\level\generator\populator\Populator;
|
||||
use pocketmine\utils\Random;
|
||||
@ -98,7 +99,7 @@ abstract class Biome{
|
||||
|
||||
self::register(self::SMALL_MOUNTAINS, new SmallMountainsBiome());
|
||||
|
||||
self::register(self::BIRCH_FOREST, new ForestBiome(ForestBiome::TYPE_BIRCH));
|
||||
self::register(self::BIRCH_FOREST, new ForestBiome(TreeType::$BIRCH));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -23,23 +23,21 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\level\biome;
|
||||
|
||||
use pocketmine\block\utils\WoodType;
|
||||
use pocketmine\block\utils\TreeType;
|
||||
use pocketmine\level\generator\populator\TallGrass;
|
||||
use pocketmine\level\generator\populator\Tree;
|
||||
|
||||
class ForestBiome extends GrassyBiome{
|
||||
|
||||
public const TYPE_NORMAL = 0;
|
||||
public const TYPE_BIRCH = 1;
|
||||
/** @var TreeType */
|
||||
private $type;
|
||||
|
||||
public $type;
|
||||
|
||||
public function __construct(int $type = self::TYPE_NORMAL){
|
||||
public function __construct(?TreeType $type = null){
|
||||
parent::__construct();
|
||||
|
||||
$this->type = $type;
|
||||
$this->type = $type ?? TreeType::$OAK;
|
||||
|
||||
$trees = new Tree($type === self::TYPE_BIRCH ? WoodType::BIRCH : WoodType::OAK);
|
||||
$trees = new Tree($type);
|
||||
$trees->setBaseAmount(5);
|
||||
$this->addPopulator($trees);
|
||||
|
||||
@ -50,7 +48,7 @@ class ForestBiome extends GrassyBiome{
|
||||
|
||||
$this->setElevation(63, 81);
|
||||
|
||||
if($type === self::TYPE_BIRCH){
|
||||
if($type === TreeType::$BIRCH){
|
||||
$this->temperature = 0.6;
|
||||
$this->rainfall = 0.5;
|
||||
}else{
|
||||
@ -60,6 +58,6 @@ class ForestBiome extends GrassyBiome{
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
return $this->type === self::TYPE_BIRCH ? "Birch Forest" : "Forest";
|
||||
return $this->type->getDisplayName() . " Forest";
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\level\biome;
|
||||
|
||||
use pocketmine\block\utils\WoodType;
|
||||
use pocketmine\block\utils\TreeType;
|
||||
use pocketmine\level\generator\populator\TallGrass;
|
||||
use pocketmine\level\generator\populator\Tree;
|
||||
|
||||
@ -32,7 +32,7 @@ class TaigaBiome extends SnowyBiome{
|
||||
public function __construct(){
|
||||
parent::__construct();
|
||||
|
||||
$trees = new Tree(WoodType::SPRUCE);
|
||||
$trees = new Tree(TreeType::$SPRUCE);
|
||||
$trees->setBaseAmount(10);
|
||||
$this->addPopulator($trees);
|
||||
|
||||
|
@ -25,7 +25,7 @@ namespace pocketmine\level\generator\object;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\block\Wood;
|
||||
use pocketmine\block\utils\TreeType;
|
||||
use pocketmine\level\ChunkManager;
|
||||
use pocketmine\utils\Random;
|
||||
|
||||
@ -34,7 +34,7 @@ class BirchTree extends Tree{
|
||||
protected $superBirch = false;
|
||||
|
||||
public function __construct(bool $superBirch = false){
|
||||
parent::__construct(BlockFactory::get(Block::LOG, Wood::BIRCH), BlockFactory::get(Block::LEAVES, Wood::BIRCH));
|
||||
parent::__construct(BlockFactory::get(Block::LOG, TreeType::$BIRCH->getMagicNumber()), BlockFactory::get(Block::LEAVES, TreeType::$BIRCH->getMagicNumber()));
|
||||
$this->superBirch = $superBirch;
|
||||
}
|
||||
|
||||
|
@ -25,11 +25,11 @@ namespace pocketmine\level\generator\object;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\block\Wood;
|
||||
use pocketmine\block\utils\TreeType;
|
||||
|
||||
class JungleTree extends Tree{
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(BlockFactory::get(Block::LOG, Wood::JUNGLE), BlockFactory::get(Block::LEAVES, Wood::JUNGLE), 8);
|
||||
parent::__construct(BlockFactory::get(Block::LOG, TreeType::$JUNGLE->getMagicNumber()), BlockFactory::get(Block::LEAVES, TreeType::$JUNGLE->getMagicNumber()), 8);
|
||||
}
|
||||
}
|
||||
|
@ -25,14 +25,14 @@ namespace pocketmine\level\generator\object;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\block\Wood;
|
||||
use pocketmine\block\utils\TreeType;
|
||||
use pocketmine\level\ChunkManager;
|
||||
use pocketmine\utils\Random;
|
||||
|
||||
class OakTree extends Tree{
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(BlockFactory::get(Block::LOG, Wood::OAK), BlockFactory::get(Block::LEAVES, Wood::OAK));
|
||||
parent::__construct(BlockFactory::get(Block::LOG, TreeType::$OAK->getMagicNumber()), BlockFactory::get(Block::LEAVES, TreeType::$OAK->getMagicNumber()));
|
||||
}
|
||||
|
||||
public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{
|
||||
|
@ -25,7 +25,7 @@ namespace pocketmine\level\generator\object;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\block\Wood;
|
||||
use pocketmine\block\utils\TreeType;
|
||||
use pocketmine\level\BlockWriteBatch;
|
||||
use pocketmine\level\ChunkManager;
|
||||
use pocketmine\utils\Random;
|
||||
@ -34,7 +34,7 @@ use function abs;
|
||||
class SpruceTree extends Tree{
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(BlockFactory::get(Block::LOG, Wood::SPRUCE), BlockFactory::get(Block::LEAVES, Wood::SPRUCE), 10);
|
||||
parent::__construct(BlockFactory::get(Block::LOG, TreeType::$SPRUCE->getMagicNumber()), BlockFactory::get(Block::LEAVES, TreeType::$SPRUCE->getMagicNumber()), 10);
|
||||
}
|
||||
|
||||
protected function generateChunkHeight(Random $random) : int{
|
||||
|
@ -27,7 +27,7 @@ use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\block\Leaves;
|
||||
use pocketmine\block\Sapling;
|
||||
use pocketmine\block\utils\WoodType;
|
||||
use pocketmine\block\utils\TreeType;
|
||||
use pocketmine\level\BlockWriteBatch;
|
||||
use pocketmine\level\ChunkManager;
|
||||
use pocketmine\utils\Random;
|
||||
@ -49,34 +49,40 @@ abstract class Tree{
|
||||
$this->treeHeight = $treeHeight;
|
||||
}
|
||||
|
||||
public static function growTree(ChunkManager $level, int $x, int $y, int $z, Random $random, int $type = WoodType::OAK) : void{
|
||||
switch($type){
|
||||
case WoodType::SPRUCE:
|
||||
/**
|
||||
* @param ChunkManager $level
|
||||
* @param int $x
|
||||
* @param int $y
|
||||
* @param int $z
|
||||
* @param Random $random
|
||||
* @param TreeType|null $type default oak
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public static function growTree(ChunkManager $level, int $x, int $y, int $z, Random $random, ?TreeType $type = null) : void{
|
||||
/** @var null|Tree $tree */
|
||||
$tree = null;
|
||||
$type = $type ?? TreeType::$OAK;
|
||||
if($type === TreeType::$SPRUCE){
|
||||
$tree = new SpruceTree();
|
||||
break;
|
||||
case WoodType::BIRCH:
|
||||
}elseif($type === TreeType::$BIRCH){
|
||||
if($random->nextBoundedInt(39) === 0){
|
||||
$tree = new BirchTree(true);
|
||||
}else{
|
||||
$tree = new BirchTree();
|
||||
}
|
||||
break;
|
||||
case WoodType::JUNGLE:
|
||||
}elseif($type === TreeType::$JUNGLE){
|
||||
$tree = new JungleTree();
|
||||
break;
|
||||
case WoodType::ACACIA:
|
||||
case WoodType::DARK_OAK:
|
||||
return; //TODO
|
||||
default:
|
||||
}elseif($type === TreeType::$OAK){ //default
|
||||
$tree = new OakTree();
|
||||
/*if($random->nextRange(0, 9) === 0){
|
||||
$tree = new BigTree();
|
||||
}else{*/
|
||||
|
||||
//}
|
||||
break;
|
||||
}
|
||||
if($tree->canPlaceObject($level, $x, $y, $z, $random)){
|
||||
|
||||
if($tree !== null and $tree->canPlaceObject($level, $x, $y, $z, $random)){
|
||||
$tree->placeObject($level, $x, $y, $z, $random);
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\level\generator\populator;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\utils\WoodType;
|
||||
use pocketmine\block\utils\TreeType;
|
||||
use pocketmine\level\ChunkManager;
|
||||
use pocketmine\level\generator\object\Tree as ObjectTree;
|
||||
use pocketmine\utils\Random;
|
||||
@ -35,10 +35,14 @@ class Tree extends Populator{
|
||||
private $randomAmount;
|
||||
private $baseAmount;
|
||||
|
||||
/** @var TreeType */
|
||||
private $type;
|
||||
|
||||
public function __construct(int $type = WoodType::OAK){
|
||||
$this->type = $type;
|
||||
/**
|
||||
* @param TreeType|null $type default oak
|
||||
*/
|
||||
public function __construct(?TreeType $type = null){
|
||||
$this->type = $type ?? TreeType::$OAK;
|
||||
}
|
||||
|
||||
public function setRandomAmount(int $amount) : void{
|
||||
|
@ -23,31 +23,42 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\tile;
|
||||
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\ByteTag;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
|
||||
class Bed extends Spawnable{
|
||||
public const TAG_COLOR = "color";
|
||||
/** @var int */
|
||||
private $color = 14; //default to old red
|
||||
/** @var DyeColor */
|
||||
private $color;
|
||||
|
||||
public function getColor() : int{
|
||||
public function __construct(Level $level, Vector3 $pos){
|
||||
$this->color = DyeColor::$RED;
|
||||
parent::__construct($level, $pos);
|
||||
}
|
||||
|
||||
public function getColor() : DyeColor{
|
||||
return $this->color;
|
||||
}
|
||||
|
||||
public function setColor(int $color){
|
||||
$this->color = $color & 0xf;
|
||||
public function setColor(DyeColor $color){
|
||||
$this->color = $color;
|
||||
$this->onChanged();
|
||||
}
|
||||
|
||||
public function readSaveData(CompoundTag $nbt) : void{
|
||||
$this->color = $nbt->getByte(self::TAG_COLOR, 14, true);
|
||||
if($nbt->hasTag(self::TAG_COLOR, ByteTag::class)){
|
||||
$this->color = DyeColor::fromMagicNumber($nbt->getByte(self::TAG_COLOR));
|
||||
}
|
||||
}
|
||||
|
||||
protected function writeSaveData(CompoundTag $nbt) : void{
|
||||
$nbt->setByte(self::TAG_COLOR, $this->color);
|
||||
$nbt->setByte(self::TAG_COLOR, $this->color->getMagicNumber());
|
||||
}
|
||||
|
||||
protected function addAdditionalSpawnData(CompoundTag $nbt) : void{
|
||||
$nbt->setByte(self::TAG_COLOR, $this->color);
|
||||
$nbt->setByte(self::TAG_COLOR, $this->color->getMagicNumber());
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user