mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-21 16:24:05 +00:00
First look at using (very) basic tags for dynamic block properties
this allows plugins to, for example, add their own custom dirt-like blocks which support having flowers placed on them.
This commit is contained in:
parent
817591910b
commit
d9b050fb68
@ -124,14 +124,7 @@ class Bamboo extends Transparent{
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
//TODO: tags would be better for this
|
||||
return
|
||||
$block instanceof Dirt ||
|
||||
$block instanceof Grass ||
|
||||
$block instanceof Gravel ||
|
||||
$block instanceof Sand ||
|
||||
$block instanceof Mycelium ||
|
||||
$block instanceof Podzol;
|
||||
return $block->hasTypeTag(BlockTypeTags::DIRT) || $block->hasTypeTag(BlockTypeTags::MUD);
|
||||
}
|
||||
|
||||
private function seekToTop() : Bamboo{
|
||||
|
@ -52,14 +52,7 @@ final class BambooSapling extends Flowable{
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
//TODO: tags would be better for this
|
||||
return
|
||||
$block instanceof Dirt ||
|
||||
$block instanceof Grass ||
|
||||
$block instanceof Gravel ||
|
||||
$block instanceof Sand ||
|
||||
$block instanceof Mycelium ||
|
||||
$block instanceof Podzol;
|
||||
return $block->hasTypeTag(BlockTypeTags::DIRT) || $block->hasTypeTag(BlockTypeTags::MUD);
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
|
@ -56,7 +56,7 @@ class Block{
|
||||
|
||||
protected BlockIdentifier $idInfo;
|
||||
protected string $fallbackName;
|
||||
protected BlockBreakInfo $breakInfo;
|
||||
protected BlockTypeInfo $typeInfo;
|
||||
protected Position $position;
|
||||
|
||||
/** @var AxisAlignedBB[]|null */
|
||||
@ -68,7 +68,7 @@ class Block{
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
$this->idInfo = $idInfo;
|
||||
$this->fallbackName = $name;
|
||||
$this->breakInfo = $typeInfo->getBreakInfo();
|
||||
$this->typeInfo = $typeInfo;
|
||||
$this->position = new Position(0, 0, 0, null);
|
||||
}
|
||||
|
||||
@ -237,6 +237,25 @@ class Block{
|
||||
return $this->getStateId() === $other->getStateId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getTypeTags() : array{
|
||||
return $this->typeInfo->getTypeTags();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this block type has the given type tag. Type tags are used as a dynamic way to tag blocks as
|
||||
* having certain properties, allowing type checks which are more dynamic than hardcoding a bunch of IDs or a bunch
|
||||
* of instanceof checks.
|
||||
*
|
||||
* For example, grass blocks, dirt, farmland, podzol and mycelium are all dirt-like blocks, and support the
|
||||
* placement of blocks like flowers, so they have a common tag which allows them to be identified as such.
|
||||
*/
|
||||
public function hasTypeTag(string $tag) : bool{
|
||||
return $this->typeInfo->hasTypeTag($tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* AKA: Block->isPlaceable
|
||||
*/
|
||||
@ -268,7 +287,7 @@ class Block{
|
||||
* Returns an object containing information about the destruction requirements of this block.
|
||||
*/
|
||||
public function getBreakInfo() : BlockBreakInfo{
|
||||
return $this->breakInfo;
|
||||
return $this->typeInfo->getBreakInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -412,7 +431,7 @@ class Block{
|
||||
* @return Item[]
|
||||
*/
|
||||
public function getDrops(Item $item) : array{
|
||||
if($this->breakInfo->isToolCompatible($item)){
|
||||
if($this->getBreakInfo()->isToolCompatible($item)){
|
||||
if($this->isAffectedBySilkTouch() && $item->hasEnchantment(VanillaEnchantments::SILK_TOUCH())){
|
||||
return $this->getSilkTouchDrops($item);
|
||||
}
|
||||
@ -454,7 +473,7 @@ class Block{
|
||||
* Returns how much XP will be dropped by breaking this block with the given item.
|
||||
*/
|
||||
public function getXpDropForTool(Item $item) : int{
|
||||
if($item->hasEnchantment(VanillaEnchantments::SILK_TOUCH()) || !$this->breakInfo->isToolCompatible($item)){
|
||||
if($item->hasEnchantment(VanillaEnchantments::SILK_TOUCH()) || !$this->getBreakInfo()->isToolCompatible($item)){
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -23,11 +23,27 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use function array_fill_keys;
|
||||
use function array_keys;
|
||||
|
||||
final class BlockTypeInfo{
|
||||
/**
|
||||
* @var true[]
|
||||
* @phpstan-var array<string, true>
|
||||
*/
|
||||
private array $typeTags;
|
||||
|
||||
public function __construct(
|
||||
private BlockBreakInfo $breakInfo,
|
||||
){}
|
||||
array $typeTags = []
|
||||
){
|
||||
$this->typeTags = array_fill_keys($typeTags, true);
|
||||
}
|
||||
|
||||
public function getBreakInfo() : BlockBreakInfo{ return $this->breakInfo; }
|
||||
|
||||
/** @return string[] */
|
||||
public function getTypeTags() : array{ return array_keys($this->typeTags); }
|
||||
|
||||
public function hasTypeTag(string $tag) : bool{ return isset($this->typeTags[$tag]); }
|
||||
}
|
||||
|
32
src/block/BlockTypeTags.php
Normal file
32
src/block/BlockTypeTags.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?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;
|
||||
|
||||
final class BlockTypeTags{
|
||||
|
||||
public const DIRT = "dirt";
|
||||
public const MUD = "mud";
|
||||
public const SAND = "sand";
|
||||
public const POTTABLE_PLANTS = "pottable";
|
||||
}
|
@ -81,10 +81,13 @@ class Cactus extends Transparent{
|
||||
return true;
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return $block->isSameType($this) || $block->hasTypeTag(BlockTypeTags::SAND);
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
$world = $this->position->getWorld();
|
||||
if($down->getTypeId() !== BlockTypeIds::SAND && $down->getTypeId() !== BlockTypeIds::RED_SAND && !$down->isSameType($this)){
|
||||
if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){
|
||||
$world->useBreakOn($this->position);
|
||||
}else{
|
||||
foreach(Facing::HORIZONTAL as $side){
|
||||
@ -131,8 +134,7 @@ class Cactus extends Transparent{
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if($down->getTypeId() === BlockTypeIds::SAND || $down->getTypeId() === BlockTypeIds::RED_SAND || $down->isSameType($this)){
|
||||
if($this->canBeSupportedBy($this->getSide(Facing::DOWN))){
|
||||
foreach(Facing::HORIZONTAL as $side){
|
||||
if($this->getSide($side)->isSolid()){
|
||||
return false;
|
||||
|
@ -49,8 +49,8 @@ class DoublePlant extends Flowable{
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$id = $blockReplace->getSide(Facing::DOWN)->getTypeId();
|
||||
if(($id === BlockTypeIds::GRASS || $id === BlockTypeIds::DIRT) && $blockReplace->getSide(Facing::UP)->canBeReplaced()){
|
||||
$down = $blockReplace->getSide(Facing::DOWN);
|
||||
if($down->hasTypeTag(BlockTypeTags::DIRT) && $blockReplace->getSide(Facing::UP)->canBeReplaced()){
|
||||
$top = clone $this;
|
||||
$top->top = true;
|
||||
$tx->addBlock($blockReplace->position, $this)->addBlock($blockReplace->position->getSide(Facing::UP), $top);
|
||||
@ -74,7 +74,8 @@ class DoublePlant extends Flowable{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->isValidHalfPlant() || (!$this->top && $this->getSide(Facing::DOWN)->isTransparent())){
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if(!$this->isValidHalfPlant() || (!$this->top && !$down->hasTypeTag(BlockTypeTags::DIRT) && !$down->hasTypeTag(BlockTypeTags::MUD))){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ class Flower extends Flowable{
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if($down->getTypeId() === BlockTypeIds::GRASS || $down->getTypeId() === BlockTypeIds::DIRT || $down->getTypeId() === BlockTypeIds::FARMLAND){
|
||||
if($down->hasTypeTag(BlockTypeTags::DIRT) || $down->hasTypeTag(BlockTypeTags::MUD)){
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
@ -41,7 +41,8 @@ class Flower extends Flowable{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Facing::DOWN)->isTransparent()){
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if(!$down->hasTypeTag(BlockTypeTags::DIRT) && !$down->hasTypeTag(BlockTypeTags::MUD)){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
@ -79,14 +79,7 @@ class FlowerPot extends Flowable{
|
||||
}
|
||||
|
||||
private function isValidPlant(Block $block) : bool{
|
||||
return
|
||||
$block instanceof Cactus ||
|
||||
$block instanceof DeadBush ||
|
||||
$block instanceof Flower ||
|
||||
$block instanceof RedMushroom ||
|
||||
$block instanceof Sapling ||
|
||||
($block instanceof TallGrass && $block->getTypeId() === BlockTypeIds::LARGE_FERN);
|
||||
//TODO: bamboo
|
||||
return $block->hasTypeTag(BlockTypeTags::POTTABLE_PLANTS);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -63,7 +63,7 @@ class Sapling extends Flowable{
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if($down->getTypeId() === BlockTypeIds::GRASS || $down->getTypeId() === BlockTypeIds::DIRT || $down->getTypeId() === BlockTypeIds::FARMLAND){
|
||||
if($down->hasTypeTag(BlockTypeTags::DIRT) || $down->hasTypeTag(BlockTypeTags::MUD)){
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
@ -81,7 +81,8 @@ class Sapling extends Flowable{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Facing::DOWN)->isTransparent()){
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if(!$down->hasTypeTag(BlockTypeTags::DIRT) && !$down->hasTypeTag(BlockTypeTags::MUD)){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
@ -53,8 +53,7 @@ abstract class Stem extends Crops{
|
||||
}
|
||||
|
||||
$side = $this->getSide(Facing::HORIZONTAL[array_rand(Facing::HORIZONTAL)]);
|
||||
$d = $side->getSide(Facing::DOWN);
|
||||
if($side->getTypeId() === BlockTypeIds::AIR && ($d->getTypeId() === BlockTypeIds::FARMLAND || $d->getTypeId() === BlockTypeIds::GRASS || $d->getTypeId() === BlockTypeIds::DIRT)){
|
||||
if($side->getTypeId() === BlockTypeIds::AIR && $side->getSide(Facing::DOWN)->hasTypeTag(BlockTypeTags::DIRT)){
|
||||
$ev = new BlockGrowEvent($side, $grow);
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
|
@ -92,9 +92,16 @@ class Sugarcane extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return
|
||||
$block->hasTypeTag(BlockTypeTags::MUD) ||
|
||||
$block->hasTypeTag(BlockTypeTags::DIRT) ||
|
||||
$block->hasTypeTag(BlockTypeTags::SAND);
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if($down->isTransparent() && !$down->isSameType($this)){
|
||||
if(!$down->isSameType($this) && !$this->canBeSupportedBy($down)){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
@ -118,7 +125,7 @@ class Sugarcane extends Flowable{
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if($down->isSameType($this)){
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}elseif($down->getTypeId() === BlockTypeIds::GRASS || $down->getTypeId() === BlockTypeIds::DIRT || $down->getTypeId() === BlockTypeIds::SAND || $down->getTypeId() === BlockTypeIds::RED_SAND || $down->getTypeId() === BlockTypeIds::PODZOL){
|
||||
}elseif($this->canBeSupportedBy($down)){
|
||||
foreach(Facing::HORIZONTAL as $side){
|
||||
if($down->getSide($side) instanceof Water){
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
|
@ -73,8 +73,8 @@ class SweetBerryBush extends Flowable{
|
||||
}
|
||||
|
||||
protected function canBeSupportedBy(Block $block) : bool{
|
||||
$id = $block->getTypeId();
|
||||
return $id === BlockTypeIds::GRASS || $id === BlockTypeIds::DIRT || $id === BlockTypeIds::PODZOL;
|
||||
return $block->getTypeId() !== BlockTypeIds::FARMLAND && //bedrock-specific thing (bug?)
|
||||
($block->hasTypeTag(BlockTypeTags::DIRT) || $block->hasTypeTag(BlockTypeTags::MUD));
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
|
@ -38,8 +38,8 @@ class TallGrass extends Flowable{
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$down = $this->getSide(Facing::DOWN)->getTypeId();
|
||||
if($down === BlockTypeIds::GRASS || $down === BlockTypeIds::DIRT){
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if($down->hasTypeTag(BlockTypeTags::DIRT) || $down->hasTypeTag(BlockTypeTags::MUD)){
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
@ -47,7 +47,8 @@ class TallGrass extends Flowable{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Facing::DOWN)->isTransparent()){ //Replace with common break method
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if($down->hasTypeTag(BlockTypeTags::DIRT) || $down->hasTypeTag(BlockTypeTags::MUD)){ //Replace with common break method
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ use pocketmine\block\BlockIdentifier as BID;
|
||||
use pocketmine\block\BlockToolType as ToolType;
|
||||
use pocketmine\block\BlockTypeIds as Ids;
|
||||
use pocketmine\block\BlockTypeInfo as Info;
|
||||
use pocketmine\block\BlockTypeTags as Tags;
|
||||
use pocketmine\block\tile\Banner as TileBanner;
|
||||
use pocketmine\block\tile\Barrel as TileBarrel;
|
||||
use pocketmine\block\tile\Beacon as TileBeacon;
|
||||
@ -750,7 +751,7 @@ final class VanillaBlocks{
|
||||
}
|
||||
return parent::getBreakTime($item);
|
||||
}
|
||||
})));
|
||||
}, [Tags::POTTABLE_PLANTS])));
|
||||
self::register("bamboo_sapling", new BambooSapling(new BID(Ids::BAMBOO_SAPLING), "Bamboo Sapling", new Info(BreakInfo::instant())));
|
||||
|
||||
$bannerBreakInfo = new Info(BreakInfo::axe(1.0));
|
||||
@ -773,8 +774,8 @@ final class VanillaBlocks{
|
||||
self::register("brick_stairs", new Stair(new BID(Ids::BRICK_STAIRS), "Brick Stairs", $bricksBreakInfo));
|
||||
self::register("bricks", new Opaque(new BID(Ids::BRICKS), "Bricks", $bricksBreakInfo));
|
||||
|
||||
self::register("brown_mushroom", new BrownMushroom(new BID(Ids::BROWN_MUSHROOM), "Brown Mushroom", new Info(BreakInfo::instant())));
|
||||
self::register("cactus", new Cactus(new BID(Ids::CACTUS), "Cactus", new Info(new BreakInfo(0.4))));
|
||||
self::register("brown_mushroom", new BrownMushroom(new BID(Ids::BROWN_MUSHROOM), "Brown Mushroom", new Info(BreakInfo::instant(), [Tags::POTTABLE_PLANTS])));
|
||||
self::register("cactus", new Cactus(new BID(Ids::CACTUS), "Cactus", new Info(new BreakInfo(0.4), [Tags::POTTABLE_PLANTS])));
|
||||
self::register("cake", new Cake(new BID(Ids::CAKE), "Cake", new Info(new BreakInfo(0.5))));
|
||||
self::register("carrots", new Carrot(new BID(Ids::CARROTS), "Carrot Block", new Info(BreakInfo::instant())));
|
||||
|
||||
@ -794,11 +795,11 @@ final class VanillaBlocks{
|
||||
self::register("coral_block", new CoralBlock(new BID(Ids::CORAL_BLOCK), "Coral Block", new Info(BreakInfo::pickaxe(7.0, ToolTier::WOOD()))));
|
||||
self::register("crafting_table", new CraftingTable(new BID(Ids::CRAFTING_TABLE), "Crafting Table", new Info(BreakInfo::axe(2.5))));
|
||||
self::register("daylight_sensor", new DaylightSensor(new BID(Ids::DAYLIGHT_SENSOR, TileDaylightSensor::class), "Daylight Sensor", new Info(BreakInfo::axe(0.2))));
|
||||
self::register("dead_bush", new DeadBush(new BID(Ids::DEAD_BUSH), "Dead Bush", new Info(BreakInfo::instant(ToolType::SHEARS, 1))));
|
||||
self::register("dead_bush", new DeadBush(new BID(Ids::DEAD_BUSH), "Dead Bush", new Info(BreakInfo::instant(ToolType::SHEARS, 1), [Tags::POTTABLE_PLANTS])));
|
||||
self::register("detector_rail", new DetectorRail(new BID(Ids::DETECTOR_RAIL), "Detector Rail", $railBreakInfo));
|
||||
|
||||
self::register("diamond", new Opaque(new BID(Ids::DIAMOND), "Diamond Block", new Info(BreakInfo::pickaxe(5.0, ToolTier::IRON(), 30.0))));
|
||||
self::register("dirt", new Dirt(new BID(Ids::DIRT), "Dirt", new Info(BreakInfo::shovel(0.5))));
|
||||
self::register("dirt", new Dirt(new BID(Ids::DIRT), "Dirt", new Info(BreakInfo::shovel(0.5), [Tags::DIRT])));
|
||||
self::register("sunflower", new DoublePlant(new BID(Ids::SUNFLOWER), "Sunflower", new Info(BreakInfo::instant())));
|
||||
self::register("lilac", new DoublePlant(new BID(Ids::LILAC), "Lilac", new Info(BreakInfo::instant())));
|
||||
self::register("rose_bush", new DoublePlant(new BID(Ids::ROSE_BUSH), "Rose Bush", new Info(BreakInfo::instant())));
|
||||
@ -818,22 +819,24 @@ final class VanillaBlocks{
|
||||
self::register("end_stone_brick_stairs", new Stair(new BID(Ids::END_STONE_BRICK_STAIRS), "End Stone Brick Stairs", $endBrickBreakInfo));
|
||||
|
||||
self::register("ender_chest", new EnderChest(new BID(Ids::ENDER_CHEST, TileEnderChest::class), "Ender Chest", new Info(BreakInfo::pickaxe(22.5, ToolTier::WOOD(), 3000.0))));
|
||||
self::register("farmland", new Farmland(new BID(Ids::FARMLAND), "Farmland", new Info(BreakInfo::shovel(0.6))));
|
||||
self::register("farmland", new Farmland(new BID(Ids::FARMLAND), "Farmland", new Info(BreakInfo::shovel(0.6), [Tags::DIRT])));
|
||||
self::register("fire", new Fire(new BID(Ids::FIRE), "Fire Block", new Info(BreakInfo::instant())));
|
||||
self::register("fletching_table", new FletchingTable(new BID(Ids::FLETCHING_TABLE), "Fletching Table", new Info(BreakInfo::axe(2.5, null, 2.5))));
|
||||
self::register("dandelion", new Flower(new BID(Ids::DANDELION), "Dandelion", new Info(BreakInfo::instant())));
|
||||
self::register("poppy", new Flower(new BID(Ids::POPPY), "Poppy", new Info(BreakInfo::instant())));
|
||||
self::register("allium", new Flower(new BID(Ids::ALLIUM), "Allium", new Info(BreakInfo::instant())));
|
||||
self::register("azure_bluet", new Flower(new BID(Ids::AZURE_BLUET), "Azure Bluet", new Info(BreakInfo::instant())));
|
||||
self::register("blue_orchid", new Flower(new BID(Ids::BLUE_ORCHID), "Blue Orchid", new Info(BreakInfo::instant())));
|
||||
self::register("cornflower", new Flower(new BID(Ids::CORNFLOWER), "Cornflower", new Info(BreakInfo::instant())));
|
||||
self::register("lily_of_the_valley", new Flower(new BID(Ids::LILY_OF_THE_VALLEY), "Lily of the Valley", new Info(BreakInfo::instant())));
|
||||
self::register("orange_tulip", new Flower(new BID(Ids::ORANGE_TULIP), "Orange Tulip", new Info(BreakInfo::instant())));
|
||||
self::register("oxeye_daisy", new Flower(new BID(Ids::OXEYE_DAISY), "Oxeye Daisy", new Info(BreakInfo::instant())));
|
||||
self::register("pink_tulip", new Flower(new BID(Ids::PINK_TULIP), "Pink Tulip", new Info(BreakInfo::instant())));
|
||||
self::register("red_tulip", new Flower(new BID(Ids::RED_TULIP), "Red Tulip", new Info(BreakInfo::instant())));
|
||||
self::register("white_tulip", new Flower(new BID(Ids::WHITE_TULIP), "White Tulip", new Info(BreakInfo::instant())));
|
||||
self::register("flower_pot", new FlowerPot(new BID(Ids::FLOWER_POT, TileFlowerPot::class), "Flower Pot", new Info(BreakInfo::instant())));
|
||||
|
||||
$flowerTypeInfo = new Info(BreakInfo::instant(), [Tags::POTTABLE_PLANTS]);
|
||||
self::register("dandelion", new Flower(new BID(Ids::DANDELION), "Dandelion", $flowerTypeInfo));
|
||||
self::register("poppy", new Flower(new BID(Ids::POPPY), "Poppy", $flowerTypeInfo));
|
||||
self::register("allium", new Flower(new BID(Ids::ALLIUM), "Allium", $flowerTypeInfo));
|
||||
self::register("azure_bluet", new Flower(new BID(Ids::AZURE_BLUET), "Azure Bluet", $flowerTypeInfo));
|
||||
self::register("blue_orchid", new Flower(new BID(Ids::BLUE_ORCHID), "Blue Orchid", $flowerTypeInfo));
|
||||
self::register("cornflower", new Flower(new BID(Ids::CORNFLOWER), "Cornflower", $flowerTypeInfo));
|
||||
self::register("lily_of_the_valley", new Flower(new BID(Ids::LILY_OF_THE_VALLEY), "Lily of the Valley", $flowerTypeInfo));
|
||||
self::register("orange_tulip", new Flower(new BID(Ids::ORANGE_TULIP), "Orange Tulip", $flowerTypeInfo));
|
||||
self::register("oxeye_daisy", new Flower(new BID(Ids::OXEYE_DAISY), "Oxeye Daisy", $flowerTypeInfo));
|
||||
self::register("pink_tulip", new Flower(new BID(Ids::PINK_TULIP), "Pink Tulip", $flowerTypeInfo));
|
||||
self::register("red_tulip", new Flower(new BID(Ids::RED_TULIP), "Red Tulip", $flowerTypeInfo));
|
||||
self::register("white_tulip", new Flower(new BID(Ids::WHITE_TULIP), "White Tulip", $flowerTypeInfo));
|
||||
self::register("flower_pot", new FlowerPot(new BID(Ids::FLOWER_POT, TileFlowerPot::class), "Flower Pot", $flowerTypeInfo));
|
||||
self::register("frosted_ice", new FrostedIce(new BID(Ids::FROSTED_ICE), "Frosted Ice", new Info(BreakInfo::pickaxe(2.5))));
|
||||
self::register("furnace", new Furnace(new BID(Ids::FURNACE, TileNormalFurnace::class), "Furnace", new Info(BreakInfo::pickaxe(3.5, ToolTier::WOOD()))));
|
||||
self::register("blast_furnace", new Furnace(new BID(Ids::BLAST_FURNACE, TileBlastFurnace::class), "Blast Furnace", new Info(BreakInfo::pickaxe(3.5, ToolTier::WOOD()))));
|
||||
@ -846,9 +849,9 @@ final class VanillaBlocks{
|
||||
self::register("glowstone", new Glowstone(new BID(Ids::GLOWSTONE), "Glowstone", new Info(BreakInfo::pickaxe(0.3))));
|
||||
self::register("gold", new Opaque(new BID(Ids::GOLD), "Gold Block", new Info(BreakInfo::pickaxe(3.0, ToolTier::IRON(), 30.0))));
|
||||
|
||||
$grassBreakInfo = new Info(BreakInfo::shovel(0.6));
|
||||
self::register("grass", new Grass(new BID(Ids::GRASS), "Grass", $grassBreakInfo));
|
||||
self::register("grass_path", new GrassPath(new BID(Ids::GRASS_PATH), "Grass Path", $grassBreakInfo));
|
||||
$grassBreakInfo = BreakInfo::shovel(0.6);
|
||||
self::register("grass", new Grass(new BID(Ids::GRASS), "Grass", new Info($grassBreakInfo, [Tags::DIRT])));
|
||||
self::register("grass_path", new GrassPath(new BID(Ids::GRASS_PATH), "Grass Path", new Info($grassBreakInfo)));
|
||||
self::register("gravel", new Gravel(new BID(Ids::GRAVEL), "Gravel", new Info(BreakInfo::shovel(0.6))));
|
||||
|
||||
$hardenedClayBreakInfo = new Info(BreakInfo::pickaxe(1.25, ToolTier::WOOD(), 21.0));
|
||||
@ -889,7 +892,7 @@ final class VanillaBlocks{
|
||||
self::register("melon", new Melon(new BID(Ids::MELON), "Melon Block", new Info(BreakInfo::axe(1.0))));
|
||||
self::register("melon_stem", new MelonStem(new BID(Ids::MELON_STEM), "Melon Stem", new Info(BreakInfo::instant())));
|
||||
self::register("monster_spawner", new MonsterSpawner(new BID(Ids::MONSTER_SPAWNER, TileMonsterSpawner::class), "Monster Spawner", new Info(BreakInfo::pickaxe(5.0, ToolTier::WOOD()))));
|
||||
self::register("mycelium", new Mycelium(new BID(Ids::MYCELIUM), "Mycelium", new Info(BreakInfo::shovel(0.6))));
|
||||
self::register("mycelium", new Mycelium(new BID(Ids::MYCELIUM), "Mycelium", new Info(BreakInfo::shovel(0.6), [Tags::DIRT])));
|
||||
|
||||
$netherBrickBreakInfo = new Info(BreakInfo::pickaxe(2.0, ToolTier::WOOD(), 30.0));
|
||||
self::register("nether_bricks", new Opaque(new BID(Ids::NETHER_BRICKS), "Nether Bricks", $netherBrickBreakInfo));
|
||||
@ -908,7 +911,7 @@ final class VanillaBlocks{
|
||||
self::register("note_block", new Note(new BID(Ids::NOTE_BLOCK, TileNote::class), "Note Block", new Info(BreakInfo::axe(0.8))));
|
||||
self::register("obsidian", new Opaque(new BID(Ids::OBSIDIAN), "Obsidian", new Info(BreakInfo::pickaxe(35.0 /* 50 in PC */, ToolTier::DIAMOND(), 6000.0))));
|
||||
self::register("packed_ice", new PackedIce(new BID(Ids::PACKED_ICE), "Packed Ice", new Info(BreakInfo::pickaxe(0.5))));
|
||||
self::register("podzol", new Podzol(new BID(Ids::PODZOL), "Podzol", new Info(BreakInfo::shovel(0.5))));
|
||||
self::register("podzol", new Podzol(new BID(Ids::PODZOL), "Podzol", new Info(BreakInfo::shovel(0.5), [Tags::DIRT])));
|
||||
self::register("potatoes", new Potato(new BID(Ids::POTATOES), "Potato Block", new Info(BreakInfo::instant())));
|
||||
self::register("powered_rail", new PoweredRail(new BID(Ids::POWERED_RAIL), "Powered Rail", $railBreakInfo));
|
||||
|
||||
@ -943,7 +946,7 @@ final class VanillaBlocks{
|
||||
self::register("smooth_quartz_stairs", new Stair(new BID(Ids::SMOOTH_QUARTZ_STAIRS), "Smooth Quartz Stairs", $quartzBreakInfo));
|
||||
|
||||
self::register("rail", new Rail(new BID(Ids::RAIL), "Rail", $railBreakInfo));
|
||||
self::register("red_mushroom", new RedMushroom(new BID(Ids::RED_MUSHROOM), "Red Mushroom", new Info(BreakInfo::instant())));
|
||||
self::register("red_mushroom", new RedMushroom(new BID(Ids::RED_MUSHROOM), "Red Mushroom", new Info(BreakInfo::instant(), [Tags::POTTABLE_PLANTS])));
|
||||
self::register("redstone", new Redstone(new BID(Ids::REDSTONE), "Redstone Block", new Info(BreakInfo::pickaxe(5.0, ToolTier::WOOD(), 30.0))));
|
||||
self::register("redstone_comparator", new RedstoneComparator(new BID(Ids::REDSTONE_COMPARATOR, TileComparator::class), "Redstone Comparator", new Info(BreakInfo::instant())));
|
||||
self::register("redstone_lamp", new RedstoneLamp(new BID(Ids::REDSTONE_LAMP), "Redstone Lamp", new Info(new BreakInfo(0.3))));
|
||||
@ -952,9 +955,9 @@ final class VanillaBlocks{
|
||||
self::register("redstone_wire", new RedstoneWire(new BID(Ids::REDSTONE_WIRE), "Redstone", new Info(BreakInfo::instant())));
|
||||
self::register("reserved6", new Reserved6(new BID(Ids::RESERVED6), "reserved6", new Info(BreakInfo::instant())));
|
||||
|
||||
$sandBreakInfo = new Info(BreakInfo::shovel(0.5));
|
||||
self::register("sand", new Sand(new BID(Ids::SAND), "Sand", $sandBreakInfo));
|
||||
self::register("red_sand", new Sand(new BID(Ids::RED_SAND), "Red Sand", $sandBreakInfo));
|
||||
$sandTypeInfo = new Info(BreakInfo::shovel(0.5), [Tags::SAND]);
|
||||
self::register("sand", new Sand(new BID(Ids::SAND), "Sand", $sandTypeInfo));
|
||||
self::register("red_sand", new Sand(new BID(Ids::RED_SAND), "Red Sand", $sandTypeInfo));
|
||||
|
||||
self::register("sea_lantern", new SeaLantern(new BID(Ids::SEA_LANTERN), "Sea Lantern", new Info(new BreakInfo(0.3))));
|
||||
self::register("sea_pickle", new SeaPickle(new BID(Ids::SEA_PICKLE), "Sea Pickle", new Info(BreakInfo::instant())));
|
||||
@ -1051,7 +1054,7 @@ final class VanillaBlocks{
|
||||
self::register("sugarcane", new Sugarcane(new BID(Ids::SUGARCANE), "Sugarcane", new Info(BreakInfo::instant())));
|
||||
self::register("sweet_berry_bush", new SweetBerryBush(new BID(Ids::SWEET_BERRY_BUSH), "Sweet Berry Bush", new Info(BreakInfo::instant())));
|
||||
self::register("tnt", new TNT(new BID(Ids::TNT), "TNT", new Info(BreakInfo::instant())));
|
||||
self::register("fern", new TallGrass(new BID(Ids::FERN), "Fern", new Info(BreakInfo::instant(ToolType::SHEARS, 1))));
|
||||
self::register("fern", new TallGrass(new BID(Ids::FERN), "Fern", new Info(BreakInfo::instant(ToolType::SHEARS, 1), [Tags::POTTABLE_PLANTS])));
|
||||
self::register("tall_grass", new TallGrass(new BID(Ids::TALL_GRASS), "Tall Grass", new Info(BreakInfo::instant(ToolType::SHEARS, 1))));
|
||||
|
||||
self::register("blue_torch", new Torch(new BID(Ids::BLUE_TORCH), "Blue Torch", new Info(BreakInfo::instant())));
|
||||
@ -1081,10 +1084,11 @@ final class VanillaBlocks{
|
||||
return parent::getBreakTime($item);
|
||||
}
|
||||
});
|
||||
$saplingTypeInfo = new Info(BreakInfo::instant(), [Tags::POTTABLE_PLANTS]);
|
||||
|
||||
foreach(TreeType::getAll() as $treeType){
|
||||
$name = $treeType->getDisplayName();
|
||||
self::register($treeType->name() . "_sapling", new Sapling(BlockLegacyIdHelper::getSaplingIdentifier($treeType), $name . " Sapling", new Info(BreakInfo::instant()), $treeType));
|
||||
self::register($treeType->name() . "_sapling", new Sapling(BlockLegacyIdHelper::getSaplingIdentifier($treeType), $name . " Sapling", $saplingTypeInfo, $treeType));
|
||||
self::register($treeType->name() . "_leaves", new Leaves(BlockLegacyIdHelper::getLeavesIdentifier($treeType), $name . " Leaves", $leavesBreakInfo, $treeType));
|
||||
}
|
||||
|
||||
@ -1171,7 +1175,7 @@ final class VanillaBlocks{
|
||||
|
||||
self::register("mangrove_roots", new MangroveRoots(new BID(Ids::MANGROVE_ROOTS), "Mangrove Roots", new Info(BreakInfo::axe(0.7))));
|
||||
//TODO: muddy mangrove roots are supposed to be axis-rotatable (Bedrock parity issue https://bugs.mojang.com/browse/MCPE-153721)
|
||||
self::register("muddy_mangrove_roots", new Transparent(new BID(Ids::MUDDY_MANGROVE_ROOTS), "Muddy Mangrove Roots", new Info(BreakInfo::shovel(0.7))));
|
||||
self::register("muddy_mangrove_roots", new Transparent(new BID(Ids::MUDDY_MANGROVE_ROOTS), "Muddy Mangrove Roots", new Info(BreakInfo::shovel(0.7), [Tags::MUD])));
|
||||
self::register("froglight", new Froglight(new BID(Ids::FROGLIGHT), "Froglight", new Info(new BreakInfo(0.3))));
|
||||
|
||||
self::registerBlocksR13();
|
||||
@ -1397,7 +1401,7 @@ final class VanillaBlocks{
|
||||
|
||||
private static function registerBlocksR13() : void{
|
||||
self::register("light", new Light(new BID(Ids::LIGHT), "Light Block", new Info(BreakInfo::indestructible())));
|
||||
self::register("wither_rose", new WitherRose(new BID(Ids::WITHER_ROSE), "Wither Rose", new Info(BreakInfo::instant())));
|
||||
self::register("wither_rose", new WitherRose(new BID(Ids::WITHER_ROSE), "Wither Rose", new Info(BreakInfo::instant(), [Tags::POTTABLE_PLANTS])));
|
||||
}
|
||||
|
||||
private static function registerBlocksR14() : void{
|
||||
@ -1531,7 +1535,7 @@ final class VanillaBlocks{
|
||||
}
|
||||
|
||||
private static function registerMudBlocks() : void{
|
||||
self::register("mud", new Opaque(new BID(Ids::MUD), "Mud", new Info(BreakInfo::shovel(0.5))));
|
||||
self::register("mud", new Opaque(new BID(Ids::MUD), "Mud", new Info(BreakInfo::shovel(0.5), [Tags::MUD])));
|
||||
self::register("packed_mud", new Opaque(new BID(Ids::PACKED_MUD), "Packed Mud", new Info(BreakInfo::pickaxe(1.0, null, 15.0))));
|
||||
|
||||
$mudBricksBreakInfo = new Info(BreakInfo::pickaxe(2.0, ToolTier::WOOD(), 30.0));
|
||||
|
@ -36,18 +36,15 @@ use pocketmine\world\BlockTransaction;
|
||||
class WitherRose extends Flowable{
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return match($block->getTypeId()){
|
||||
BlockTypeIds::GRASS,
|
||||
BlockTypeIds::DIRT,
|
||||
BlockTypeIds::FARMLAND,
|
||||
BlockTypeIds::MYCELIUM,
|
||||
BlockTypeIds::PODZOL,
|
||||
BlockTypeIds::NETHERRACK,
|
||||
BlockTypeIds::SOUL_SAND,
|
||||
BlockTypeIds::SOUL_SOIL => true,
|
||||
//TODO: moss, mud, rooted dirt
|
||||
default => false
|
||||
};
|
||||
return
|
||||
$block->hasTypeTag(BlockTypeTags::DIRT) ||
|
||||
$block->hasTypeTag(BlockTypeTags::MUD) ||
|
||||
match($block->getTypeId()){
|
||||
BlockTypeIds::NETHERRACK,
|
||||
BlockTypeIds::SOUL_SAND,
|
||||
BlockTypeIds::SOUL_SOIL => true,
|
||||
default => false
|
||||
};
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\world\generator\populator;
|
||||
|
||||
use pocketmine\block\BlockTypeIds;
|
||||
use pocketmine\block\BlockTypeTags;
|
||||
use pocketmine\block\utils\TreeType;
|
||||
use pocketmine\utils\Random;
|
||||
use pocketmine\world\ChunkManager;
|
||||
@ -67,10 +68,10 @@ class Tree implements Populator{
|
||||
|
||||
private function getHighestWorkableBlock(ChunkManager $world, int $x, int $z) : int{
|
||||
for($y = 127; $y >= 0; --$y){
|
||||
$b = $world->getBlockAt($x, $y, $z)->getTypeId();
|
||||
if($b === BlockTypeIds::DIRT || $b === BlockTypeIds::GRASS){
|
||||
$b = $world->getBlockAt($x, $y, $z);
|
||||
if($b->hasTypeTag(BlockTypeTags::DIRT) || $b->hasTypeTag(BlockTypeTags::MUD)){
|
||||
return $y + 1;
|
||||
}elseif($b !== BlockTypeIds::AIR && $b !== BlockTypeIds::SNOW_LAYER){
|
||||
}elseif($b->getTypeId() !== BlockTypeIds::AIR && $b->getTypeId() !== BlockTypeIds::SNOW_LAYER){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user