mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-12 14:35:35 +00:00
Branch merge
This commit is contained in:
commit
1f70a7830e
@ -26,6 +26,7 @@ namespace pocketmine;
|
||||
use pocketmine\block\Air;
|
||||
use pocketmine\block\Bed;
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\command\Command;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\entity\Arrow;
|
||||
@ -1626,6 +1627,10 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
|
||||
}
|
||||
|
||||
protected function tryChangeMovement(){
|
||||
|
||||
}
|
||||
|
||||
public function sendAttributes(bool $sendAll = false){
|
||||
$entries = $sendAll ? $this->attributeMap->getAll() : $this->attributeMap->needSend();
|
||||
if(count($entries) > 0){
|
||||
@ -1670,7 +1675,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
$this->processMovement($tickDiff);
|
||||
$this->entityBaseTick($tickDiff);
|
||||
|
||||
if(!$this->isSpectator()){
|
||||
if(!$this->isSpectator() and $this->isAlive()){
|
||||
$this->checkNearEntities($tickDiff);
|
||||
|
||||
if($this->speed !== null){
|
||||
@ -2215,7 +2220,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
if(!$this->canInteract($blockVector->add(0.5, 0.5, 0.5), 13) or $this->isSpectator()){
|
||||
}elseif($this->isCreative()){
|
||||
$item = $this->inventory->getItemInHand();
|
||||
if($this->level->useItemOn($blockVector, $item, $face, $packet->transactionData->clickPos->x, $packet->transactionData->clickPos->y, $packet->transactionData->clickPos->z, $this, true) === true){
|
||||
if($this->level->useItemOn($blockVector, $item, $face, $packet->transactionData->clickPos, $this, true) === true){
|
||||
return true;
|
||||
}
|
||||
}elseif(!$this->inventory->getItemInHand()->equals($packet->transactionData->itemInHand)){
|
||||
@ -2223,7 +2228,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
}else{
|
||||
$item = $this->inventory->getItemInHand();
|
||||
$oldItem = clone $item;
|
||||
if($this->level->useItemOn($blockVector, $item, $face, $packet->transactionData->clickPos->x, $packet->transactionData->clickPos->y, $packet->transactionData->clickPos->z, $this, true)){
|
||||
if($this->level->useItemOn($blockVector, $item, $face, $packet->transactionData->clickPos, $this, true)){
|
||||
if(!$item->equals($oldItem) or $item->getCount() !== $oldItem->getCount()){
|
||||
$this->inventory->setItemInHand($item);
|
||||
$this->inventory->sendHeldItem($this->hasSpawned);
|
||||
@ -2587,7 +2592,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
}
|
||||
$block = $target->getSide($packet->face);
|
||||
if($block->getId() === Block::FIRE){
|
||||
$this->level->setBlock($block, Block::get(Block::AIR));
|
||||
$this->level->setBlock($block, BlockFactory::get(Block::AIR));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ declare(strict_types=1);
|
||||
*/
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\command\CommandReader;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\ConsoleCommandSender;
|
||||
@ -80,8 +80,8 @@ use pocketmine\nbt\tag\StringTag;
|
||||
use pocketmine\network\CompressBatchedTask;
|
||||
use pocketmine\network\mcpe\protocol\BatchPacket;
|
||||
use pocketmine\network\mcpe\protocol\DataPacket;
|
||||
use pocketmine\network\mcpe\protocol\ProtocolInfo;
|
||||
use pocketmine\network\mcpe\protocol\PlayerListPacket;
|
||||
use pocketmine\network\mcpe\protocol\ProtocolInfo;
|
||||
use pocketmine\network\mcpe\protocol\types\PlayerListEntry;
|
||||
use pocketmine\network\mcpe\RakLibInterface;
|
||||
use pocketmine\network\Network;
|
||||
@ -1439,6 +1439,18 @@ class Server{
|
||||
}
|
||||
$this->config = new Config($this->dataPath . "pocketmine.yml", Config::YAML, []);
|
||||
|
||||
define('pocketmine\DEBUG', (int) $this->getProperty("debug.level", 1));
|
||||
|
||||
if(((int) ini_get('zend.assertions')) > 0 and ((bool) $this->getProperty("debug.assertions.warn-if-enabled", true)) !== false){
|
||||
$this->logger->warning("Debugging assertions are enabled, this may impact on performance. To disable them, set `zend.assertions = -1` in php.ini.");
|
||||
}
|
||||
|
||||
ini_set('assert.exception', '1');
|
||||
|
||||
if($this->logger instanceof MainLogger){
|
||||
$this->logger->setLogDebug(\pocketmine\DEBUG > 1);
|
||||
}
|
||||
|
||||
$this->logger->info("Loading server properties...");
|
||||
$this->properties = new Config($this->dataPath . "server.properties", Config::PROPERTIES, [
|
||||
"motd" => "Minecraft: PE Server",
|
||||
@ -1540,18 +1552,6 @@ class Server{
|
||||
$this->setConfigInt("difficulty", 3);
|
||||
}
|
||||
|
||||
define('pocketmine\DEBUG', (int) $this->getProperty("debug.level", 1));
|
||||
|
||||
if(((int) ini_get('zend.assertions')) > 0 and ((bool) $this->getProperty("debug.assertions.warn-if-enabled", true)) !== false){
|
||||
$this->logger->warning("Debugging assertions are enabled, this may impact on performance. To disable them, set `zend.assertions = -1` in php.ini.");
|
||||
}
|
||||
|
||||
ini_set('assert.exception', '1');
|
||||
|
||||
if($this->logger instanceof MainLogger){
|
||||
$this->logger->setLogDebug(\pocketmine\DEBUG > 1);
|
||||
}
|
||||
|
||||
if(\pocketmine\DEBUG >= 0){
|
||||
@cli_set_process_title($this->getName() . " " . $this->getPocketMineVersion());
|
||||
}
|
||||
@ -1582,7 +1582,7 @@ class Server{
|
||||
|
||||
Entity::init();
|
||||
Tile::init();
|
||||
Block::init();
|
||||
BlockFactory::init();
|
||||
Enchantment::init();
|
||||
Item::init();
|
||||
Biome::init();
|
||||
|
@ -54,7 +54,7 @@ class Air extends Transparent{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canBeReplaced() : bool{
|
||||
public function canBeReplaced(Block $with = null) : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -74,7 +74,7 @@ class Air extends Transparent{
|
||||
return -1;
|
||||
}
|
||||
|
||||
public function getResistance() : float{
|
||||
public function getBlastResistance() : float{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ namespace pocketmine\block;
|
||||
use pocketmine\inventory\AnvilInventory;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Anvil extends Fallable{
|
||||
@ -48,7 +49,7 @@ class Anvil extends Fallable{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getResistance() : float{
|
||||
public function getBlastResistance() : float{
|
||||
return 6000;
|
||||
}
|
||||
|
||||
@ -73,7 +74,7 @@ class Anvil extends Fallable{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$direction = ($player !== null ? $player->getDirection() : 0) & 0x03;
|
||||
$this->meta = ($this->meta & 0x0c) | $direction;
|
||||
return $this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
@ -174,14 +174,14 @@ class Bed extends Transparent{
|
||||
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if(!$down->isTransparent()){
|
||||
$meta = (($player instanceof Player ? $player->getDirection() : 0) - 1) & 0x03;
|
||||
$next = $this->getSide(self::getOtherHalfSide($meta));
|
||||
if($next->canBeReplaced() === true and !$next->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
$this->getLevel()->setBlock($block, Block::get($this->id, $meta), true, true);
|
||||
$this->getLevel()->setBlock($next, Block::get($this->id, $meta | self::BITFLAG_HEAD), true, true);
|
||||
$this->getLevel()->setBlock($block, BlockFactory::get($this->id, $meta), true, true);
|
||||
$this->getLevel()->setBlock($next, BlockFactory::get($this->id, $meta | self::BITFLAG_HEAD), true, true);
|
||||
|
||||
$nbt = new CompoundTag("", [
|
||||
new StringTag("id", Tile::BED),
|
||||
@ -206,7 +206,7 @@ class Bed extends Transparent{
|
||||
}
|
||||
|
||||
public function onBreak(Item $item) : bool{
|
||||
$this->getLevel()->setBlock($this, Block::get(Block::AIR), true, true);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true, true);
|
||||
if(($other = $this->getOtherHalf()) !== null){
|
||||
$this->getLevel()->useBreakOn($other); //make sure tiles get removed
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ class Bedrock extends Solid{
|
||||
return -1;
|
||||
}
|
||||
|
||||
public function getResistance() : float{
|
||||
public function getBlastResistance() : float{
|
||||
return 18000000;
|
||||
}
|
||||
|
||||
|
@ -41,356 +41,17 @@ use pocketmine\plugin\Plugin;
|
||||
|
||||
class Block extends Position implements BlockIds, Metadatable{
|
||||
|
||||
/** @var \SplFixedArray<Block> */
|
||||
public static $list = null;
|
||||
/** @var \SplFixedArray<Block> */
|
||||
public static $fullList = null;
|
||||
|
||||
/** @var \SplFixedArray<int> */
|
||||
public static $light = null;
|
||||
/** @var \SplFixedArray<int> */
|
||||
public static $lightFilter = null;
|
||||
/** @var \SplFixedArray<bool> */
|
||||
public static $solid = null;
|
||||
/** @var \SplFixedArray<float> */
|
||||
public static $hardness = null;
|
||||
/** @var \SplFixedArray<bool> */
|
||||
public static $transparent = null;
|
||||
/** @var \SplFixedArray<bool> */
|
||||
public static $diffusesSkyLight = null;
|
||||
|
||||
/**
|
||||
* Initializes the block factory. By default this is called only once on server start, however you may wish to use
|
||||
* this if you need to reset the block factory back to its original defaults for whatever reason.
|
||||
* @deprecated This functionality has moved to {@link BlockFactory#get}
|
||||
*
|
||||
* @param bool $force
|
||||
*/
|
||||
public static function init(bool $force = false){
|
||||
if(self::$list === null or $force){
|
||||
self::$list = new \SplFixedArray(256);
|
||||
self::$fullList = new \SplFixedArray(4096);
|
||||
self::$light = new \SplFixedArray(256);
|
||||
self::$lightFilter = new \SplFixedArray(256);
|
||||
self::$solid = new \SplFixedArray(256);
|
||||
self::$hardness = new \SplFixedArray(256);
|
||||
self::$transparent = new \SplFixedArray(256);
|
||||
self::$diffusesSkyLight = new \SplFixedArray(256);
|
||||
|
||||
self::registerBlock(new Air());
|
||||
self::registerBlock(new Stone());
|
||||
self::registerBlock(new Grass());
|
||||
self::registerBlock(new Dirt());
|
||||
self::registerBlock(new Cobblestone());
|
||||
self::registerBlock(new Planks());
|
||||
self::registerBlock(new Sapling());
|
||||
self::registerBlock(new Bedrock());
|
||||
self::registerBlock(new Water());
|
||||
self::registerBlock(new StillWater());
|
||||
self::registerBlock(new Lava());
|
||||
self::registerBlock(new StillLava());
|
||||
self::registerBlock(new Sand());
|
||||
self::registerBlock(new Gravel());
|
||||
self::registerBlock(new GoldOre());
|
||||
self::registerBlock(new IronOre());
|
||||
self::registerBlock(new CoalOre());
|
||||
self::registerBlock(new Wood());
|
||||
self::registerBlock(new Leaves());
|
||||
self::registerBlock(new Sponge());
|
||||
self::registerBlock(new Glass());
|
||||
self::registerBlock(new LapisOre());
|
||||
self::registerBlock(new Lapis());
|
||||
//TODO: DISPENSER
|
||||
self::registerBlock(new Sandstone());
|
||||
self::registerBlock(new NoteBlock());
|
||||
self::registerBlock(new Bed());
|
||||
self::registerBlock(new PoweredRail());
|
||||
self::registerBlock(new DetectorRail());
|
||||
//TODO: STICKY_PISTON
|
||||
self::registerBlock(new Cobweb());
|
||||
self::registerBlock(new TallGrass());
|
||||
self::registerBlock(new DeadBush());
|
||||
//TODO: PISTON
|
||||
//TODO: PISTONARMCOLLISION
|
||||
self::registerBlock(new Wool());
|
||||
|
||||
self::registerBlock(new Dandelion());
|
||||
self::registerBlock(new Flower());
|
||||
self::registerBlock(new BrownMushroom());
|
||||
self::registerBlock(new RedMushroom());
|
||||
self::registerBlock(new Gold());
|
||||
self::registerBlock(new Iron());
|
||||
self::registerBlock(new DoubleStoneSlab());
|
||||
self::registerBlock(new StoneSlab());
|
||||
self::registerBlock(new Bricks());
|
||||
self::registerBlock(new TNT());
|
||||
self::registerBlock(new Bookshelf());
|
||||
self::registerBlock(new MossyCobblestone());
|
||||
self::registerBlock(new Obsidian());
|
||||
self::registerBlock(new Torch());
|
||||
self::registerBlock(new Fire());
|
||||
self::registerBlock(new MonsterSpawner());
|
||||
self::registerBlock(new WoodenStairs(Block::OAK_STAIRS, 0, "Oak Stairs"));
|
||||
self::registerBlock(new Chest());
|
||||
//TODO: REDSTONE_WIRE
|
||||
self::registerBlock(new DiamondOre());
|
||||
self::registerBlock(new Diamond());
|
||||
self::registerBlock(new CraftingTable());
|
||||
self::registerBlock(new Wheat());
|
||||
self::registerBlock(new Farmland());
|
||||
self::registerBlock(new Furnace());
|
||||
self::registerBlock(new BurningFurnace());
|
||||
self::registerBlock(new SignPost());
|
||||
self::registerBlock(new WoodenDoor(Block::OAK_DOOR_BLOCK, 0, "Oak Door Block", Item::OAK_DOOR));
|
||||
self::registerBlock(new Ladder());
|
||||
self::registerBlock(new Rail());
|
||||
self::registerBlock(new CobblestoneStairs());
|
||||
self::registerBlock(new WallSign());
|
||||
self::registerBlock(new Lever());
|
||||
self::registerBlock(new StonePressurePlate());
|
||||
self::registerBlock(new IronDoor());
|
||||
self::registerBlock(new WoodenPressurePlate());
|
||||
self::registerBlock(new RedstoneOre());
|
||||
self::registerBlock(new GlowingRedstoneOre());
|
||||
self::registerBlock(new RedstoneTorchUnlit());
|
||||
self::registerBlock(new RedstoneTorch());
|
||||
self::registerBlock(new StoneButton());
|
||||
self::registerBlock(new SnowLayer());
|
||||
self::registerBlock(new Ice());
|
||||
self::registerBlock(new Snow());
|
||||
self::registerBlock(new Cactus());
|
||||
self::registerBlock(new Clay());
|
||||
self::registerBlock(new Sugarcane());
|
||||
|
||||
self::registerBlock(new Fence());
|
||||
self::registerBlock(new Pumpkin());
|
||||
self::registerBlock(new Netherrack());
|
||||
self::registerBlock(new SoulSand());
|
||||
self::registerBlock(new Glowstone());
|
||||
//TODO: PORTAL
|
||||
self::registerBlock(new LitPumpkin());
|
||||
self::registerBlock(new Cake());
|
||||
//TODO: REPEATER_BLOCK
|
||||
//TODO: POWERED_REPEATER
|
||||
//TODO: INVISIBLEBEDROCK
|
||||
self::registerBlock(new Trapdoor());
|
||||
//TODO: MONSTER_EGG
|
||||
self::registerBlock(new StoneBricks());
|
||||
//TODO: BROWN_MUSHROOM_BLOCK
|
||||
//TODO: RED_MUSHROOM_BLOCK
|
||||
self::registerBlock(new IronBars());
|
||||
self::registerBlock(new GlassPane());
|
||||
self::registerBlock(new Melon());
|
||||
self::registerBlock(new PumpkinStem());
|
||||
self::registerBlock(new MelonStem());
|
||||
self::registerBlock(new Vine());
|
||||
self::registerBlock(new FenceGate(Block::OAK_FENCE_GATE, 0, "Oak Fence Gate"));
|
||||
self::registerBlock(new BrickStairs());
|
||||
self::registerBlock(new StoneBrickStairs());
|
||||
self::registerBlock(new Mycelium());
|
||||
self::registerBlock(new WaterLily());
|
||||
self::registerBlock(new NetherBrick(Block::NETHER_BRICK_BLOCK, 0, "Nether Bricks"));
|
||||
self::registerBlock(new NetherBrickFence());
|
||||
self::registerBlock(new NetherBrickStairs());
|
||||
self::registerBlock(new NetherWartPlant());
|
||||
self::registerBlock(new EnchantingTable());
|
||||
self::registerBlock(new BrewingStand());
|
||||
//TODO: CAULDRON_BLOCK
|
||||
//TODO: END_PORTAL
|
||||
self::registerBlock(new EndPortalFrame());
|
||||
self::registerBlock(new EndStone());
|
||||
//TODO: DRAGON_EGG
|
||||
self::registerBlock(new RedstoneLamp());
|
||||
self::registerBlock(new LitRedstoneLamp());
|
||||
//TODO: DROPPER
|
||||
self::registerBlock(new ActivatorRail());
|
||||
self::registerBlock(new CocoaBlock());
|
||||
self::registerBlock(new SandstoneStairs());
|
||||
self::registerBlock(new EmeraldOre());
|
||||
//TODO: ENDER_CHEST
|
||||
self::registerBlock(new TripwireHook());
|
||||
self::registerBlock(new Tripwire());
|
||||
self::registerBlock(new Emerald());
|
||||
self::registerBlock(new WoodenStairs(Block::SPRUCE_STAIRS, 0, "Spruce Stairs"));
|
||||
self::registerBlock(new WoodenStairs(Block::BIRCH_STAIRS, 0, "Birch Stairs"));
|
||||
self::registerBlock(new WoodenStairs(Block::JUNGLE_STAIRS, 0, "Jungle Stairs"));
|
||||
//TODO: COMMAND_BLOCK
|
||||
//TODO: BEACON
|
||||
self::registerBlock(new CobblestoneWall());
|
||||
self::registerBlock(new FlowerPot());
|
||||
self::registerBlock(new Carrot());
|
||||
self::registerBlock(new Potato());
|
||||
self::registerBlock(new WoodenButton());
|
||||
self::registerBlock(new Skull());
|
||||
self::registerBlock(new Anvil());
|
||||
self::registerBlock(new TrappedChest());
|
||||
self::registerBlock(new WeightedPressurePlateLight());
|
||||
self::registerBlock(new WeightedPressurePlateHeavy());
|
||||
//TODO: COMPARATOR_BLOCK
|
||||
//TODO: POWERED_COMPARATOR
|
||||
self::registerBlock(new DaylightSensor());
|
||||
self::registerBlock(new Redstone());
|
||||
self::registerBlock(new NetherQuartzOre());
|
||||
//TODO: HOPPER_BLOCK
|
||||
self::registerBlock(new Quartz());
|
||||
self::registerBlock(new QuartzStairs());
|
||||
self::registerBlock(new DoubleWoodenSlab());
|
||||
self::registerBlock(new WoodenSlab());
|
||||
self::registerBlock(new StainedClay());
|
||||
self::registerBlock(new StainedGlassPane());
|
||||
self::registerBlock(new Leaves2());
|
||||
self::registerBlock(new Wood2());
|
||||
self::registerBlock(new WoodenStairs(Block::ACACIA_STAIRS, 0, "Acacia Stairs"));
|
||||
self::registerBlock(new WoodenStairs(Block::DARK_OAK_STAIRS, 0, "Dark Oak Stairs"));
|
||||
//TODO: SLIME
|
||||
|
||||
self::registerBlock(new IronTrapdoor());
|
||||
self::registerBlock(new Prismarine());
|
||||
self::registerBlock(new SeaLantern());
|
||||
self::registerBlock(new HayBale());
|
||||
self::registerBlock(new Carpet());
|
||||
self::registerBlock(new HardenedClay());
|
||||
self::registerBlock(new Coal());
|
||||
self::registerBlock(new PackedIce());
|
||||
self::registerBlock(new DoublePlant());
|
||||
|
||||
//TODO: DAYLIGHT_DETECTOR_INVERTED
|
||||
//TODO: RED_SANDSTONE
|
||||
//TODO: RED_SANDSTONE_STAIRS
|
||||
//TODO: DOUBLE_STONE_SLAB2
|
||||
//TODO: STONE_SLAB2
|
||||
self::registerBlock(new FenceGate(Block::SPRUCE_FENCE_GATE, 0, "Spruce Fence Gate"));
|
||||
self::registerBlock(new FenceGate(Block::BIRCH_FENCE_GATE, 0, "Birch Fence Gate"));
|
||||
self::registerBlock(new FenceGate(Block::JUNGLE_FENCE_GATE, 0, "Jungle Fence Gate"));
|
||||
self::registerBlock(new FenceGate(Block::DARK_OAK_FENCE_GATE, 0, "Dark Oak Fence Gate"));
|
||||
self::registerBlock(new FenceGate(Block::ACACIA_FENCE_GATE, 0, "Acacia Fence Gate"));
|
||||
//TODO: REPEATING_COMMAND_BLOCK
|
||||
//TODO: CHAIN_COMMAND_BLOCK
|
||||
|
||||
self::registerBlock(new WoodenDoor(Block::SPRUCE_DOOR_BLOCK, 0, "Spruce Door Block", Item::SPRUCE_DOOR));
|
||||
self::registerBlock(new WoodenDoor(Block::BIRCH_DOOR_BLOCK, 0, "Birch Door Block", Item::BIRCH_DOOR));
|
||||
self::registerBlock(new WoodenDoor(Block::JUNGLE_DOOR_BLOCK, 0, "Jungle Door Block", Item::JUNGLE_DOOR));
|
||||
self::registerBlock(new WoodenDoor(Block::ACACIA_DOOR_BLOCK, 0, "Acacia Door Block", Item::ACACIA_DOOR));
|
||||
self::registerBlock(new WoodenDoor(Block::DARK_OAK_DOOR_BLOCK, 0, "Dark Oak Door Block", Item::DARK_OAK_DOOR));
|
||||
self::registerBlock(new GrassPath());
|
||||
self::registerBlock(new ItemFrame());
|
||||
//TODO: CHORUS_FLOWER
|
||||
//TODO: PURPUR_BLOCK
|
||||
|
||||
//TODO: PURPUR_STAIRS
|
||||
|
||||
//TODO: END_BRICKS
|
||||
//TODO: FROSTED_ICE
|
||||
self::registerBlock(new EndRod());
|
||||
//TODO: END_GATEWAY
|
||||
|
||||
self::registerBlock(new Magma());
|
||||
self::registerBlock(new NetherWartBlock());
|
||||
self::registerBlock(new NetherBrick(Block::RED_NETHER_BRICK, 0, "Red Nether Bricks"));
|
||||
//TODO: BONE_BLOCK
|
||||
|
||||
//TODO: SHULKER_BOX
|
||||
self::registerBlock(new GlazedTerracotta(Block::PURPLE_GLAZED_TERRACOTTA, 0, "Purple Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::WHITE_GLAZED_TERRACOTTA, 0, "White Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::ORANGE_GLAZED_TERRACOTTA, 0, "Orange Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::MAGENTA_GLAZED_TERRACOTTA, 0, "Magenta Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::LIGHT_BLUE_GLAZED_TERRACOTTA, 0, "Light Blue Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::YELLOW_GLAZED_TERRACOTTA, 0, "Yellow Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::LIME_GLAZED_TERRACOTTA, 0, "Lime Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::PINK_GLAZED_TERRACOTTA, 0, "Pink Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::GRAY_GLAZED_TERRACOTTA, 0, "Grey Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::SILVER_GLAZED_TERRACOTTA, 0, "Light Grey Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::CYAN_GLAZED_TERRACOTTA, 0, "Cyan Glazed Terracotta"));
|
||||
|
||||
self::registerBlock(new GlazedTerracotta(Block::BLUE_GLAZED_TERRACOTTA, 0, "Blue Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::BROWN_GLAZED_TERRACOTTA, 0, "Brown Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::GREEN_GLAZED_TERRACOTTA, 0, "Green Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::RED_GLAZED_TERRACOTTA, 0, "Red Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::BLACK_GLAZED_TERRACOTTA, 0, "Black Glazed Terracotta"));
|
||||
//TODO: CONCRETE
|
||||
//TODO: CONCRETEPOWDER
|
||||
|
||||
//TODO: CHORUS_PLANT
|
||||
self::registerBlock(new StainedGlass());
|
||||
|
||||
self::registerBlock(new Podzol());
|
||||
self::registerBlock(new Beetroot());
|
||||
self::registerBlock(new Stonecutter());
|
||||
self::registerBlock(new GlowingObsidian());
|
||||
self::registerBlock(new NetherReactor());
|
||||
//TODO: INFO_UPDATE
|
||||
//TODO: INFO_UPDATE2
|
||||
//TODO: MOVINGBLOCK
|
||||
//TODO: OBSERVER
|
||||
|
||||
//TODO: RESERVED6
|
||||
|
||||
foreach(self::$list as $id => $block){
|
||||
if($block === null){
|
||||
self::registerBlock(new UnknownBlock($id));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a block type into the index. Plugins may use this method to register new block types or override
|
||||
* existing ones.
|
||||
*
|
||||
* NOTE: If you are registering a new block type, you will need to add it to the creative inventory yourself - it
|
||||
* will not automatically appear there.
|
||||
*
|
||||
* @param Block $block
|
||||
* @param bool $override Whether to override existing registrations
|
||||
*
|
||||
* @throws \RuntimeException if something attempted to override an already-registered block without specifying the
|
||||
* $override parameter.
|
||||
*/
|
||||
public static function registerBlock(Block $block, bool $override = false){
|
||||
$id = $block->getId();
|
||||
|
||||
if(self::$list[$id] !== null and !(self::$list[$id] instanceof UnknownBlock) and !$override){
|
||||
throw new \RuntimeException("Trying to overwrite an already registered block");
|
||||
}
|
||||
|
||||
self::$list[$id] = clone $block;
|
||||
|
||||
for($meta = 0; $meta < 16; ++$meta){
|
||||
$variant = clone $block;
|
||||
$variant->setDamage($meta);
|
||||
self::$fullList[($id << 4) | $meta] = $variant;
|
||||
}
|
||||
|
||||
self::$solid[$id] = $block->isSolid();
|
||||
self::$transparent[$id] = $block->isTransparent();
|
||||
self::$hardness[$id] = $block->getHardness();
|
||||
self::$light[$id] = $block->getLightLevel();
|
||||
self::$lightFilter[$id] = $block->getLightFilter() + 1; //opacity plus 1 standard light filter
|
||||
self::$diffusesSkyLight[$id] = $block->diffusesSkyLight();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param int $meta
|
||||
* @param Position $pos
|
||||
* @param int $id
|
||||
* @param int $meta
|
||||
* @param Position|null $pos
|
||||
*
|
||||
* @return Block
|
||||
*/
|
||||
public static function get(int $id, int $meta = 0, Position $pos = null) : Block{
|
||||
try{
|
||||
$block = clone self::$fullList[($id << 4) | $meta];
|
||||
}catch(\RuntimeException $e){
|
||||
//TODO: this probably should return null (out of bounds IDs may cause unexpected behaviour)
|
||||
$block = new UnknownBlock($id, $meta);
|
||||
}
|
||||
|
||||
if($pos !== null){
|
||||
$block->x = $pos->x;
|
||||
$block->y = $pos->y;
|
||||
$block->z = $pos->z;
|
||||
$block->level = $pos->level;
|
||||
}
|
||||
|
||||
return $block;
|
||||
return BlockFactory::get($id, $meta, $pos);
|
||||
}
|
||||
|
||||
/** @var int */
|
||||
@ -476,14 +137,12 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
* @param Block $block
|
||||
* @param Block $target
|
||||
* @param int $face
|
||||
* @param float $fx
|
||||
* @param float $fy
|
||||
* @param float $fz
|
||||
* @param Vector3 $facePos
|
||||
* @param Player|null $player
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
return $this->getLevel()->setBlock($this, $this, true, true);
|
||||
}
|
||||
|
||||
@ -506,7 +165,7 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
* @return bool
|
||||
*/
|
||||
public function onBreak(Item $item) : bool{
|
||||
return $this->getLevel()->setBlock($this, Block::get(Block::AIR), true, true);
|
||||
return $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -533,6 +192,7 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a base value used to compute block break times.
|
||||
* @return float
|
||||
*/
|
||||
public function getHardness() : float{
|
||||
@ -540,9 +200,18 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @return float
|
||||
*/
|
||||
public function getResistance() : float{
|
||||
return $this->getBlastResistance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the block's resistance to explosions. Usually 5x hardness.
|
||||
* @return float
|
||||
*/
|
||||
public function getBlastResistance() : float{
|
||||
return $this->getHardness() * 5;
|
||||
}
|
||||
|
||||
@ -599,9 +268,11 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Block|null $with
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canBeReplaced() : bool{
|
||||
public function canBeReplaced(Block $with = null) : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -742,7 +413,7 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
return $this->getLevel()->getBlock(Vector3::getSide($side, $step));
|
||||
}
|
||||
|
||||
return Block::get(Block::AIR, 0, Position::fromObject(Vector3::getSide($side, $step)));
|
||||
return BlockFactory::get(Block::AIR, 0, Position::fromObject(Vector3::getSide($side, $step)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
391
src/pocketmine/block/BlockFactory.php
Normal file
391
src/pocketmine/block/BlockFactory.php
Normal file
@ -0,0 +1,391 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Position;
|
||||
|
||||
/**
|
||||
* Manages block registration and instance creation
|
||||
*/
|
||||
class BlockFactory{
|
||||
/** @var \SplFixedArray<Block> */
|
||||
public static $list = null;
|
||||
/** @var \SplFixedArray<Block> */
|
||||
public static $fullList = null;
|
||||
/** @var \SplFixedArray<bool> */
|
||||
public static $solid = null;
|
||||
/** @var \SplFixedArray<bool> */
|
||||
public static $transparent = null;
|
||||
/** @var \SplFixedArray<float> */
|
||||
public static $hardness = null;
|
||||
/** @var \SplFixedArray<int> */
|
||||
public static $light = null;
|
||||
/** @var \SplFixedArray<int> */
|
||||
public static $lightFilter = null;
|
||||
/** @var \SplFixedArray<bool> */
|
||||
public static $diffusesSkyLight = null;
|
||||
/** @var \SplFixedArray<float> */
|
||||
public static $blastResistance = null;
|
||||
|
||||
/**
|
||||
* Initializes the block factory. By default this is called only once on server start, however you may wish to use
|
||||
* this if you need to reset the block factory back to its original defaults for whatever reason.
|
||||
*
|
||||
* @param bool $force
|
||||
*/
|
||||
public static function init(bool $force = false){
|
||||
if(self::$list === null or $force){
|
||||
self::$list = new \SplFixedArray(256);
|
||||
self::$fullList = new \SplFixedArray(4096);
|
||||
self::$light = new \SplFixedArray(256);
|
||||
self::$lightFilter = new \SplFixedArray(256);
|
||||
self::$solid = new \SplFixedArray(256);
|
||||
self::$hardness = new \SplFixedArray(256);
|
||||
self::$transparent = new \SplFixedArray(256);
|
||||
self::$diffusesSkyLight = new \SplFixedArray(256);
|
||||
|
||||
self::registerBlock(new Air());
|
||||
self::registerBlock(new Stone());
|
||||
self::registerBlock(new Grass());
|
||||
self::registerBlock(new Dirt());
|
||||
self::registerBlock(new Cobblestone());
|
||||
self::registerBlock(new Planks());
|
||||
self::registerBlock(new Sapling());
|
||||
self::registerBlock(new Bedrock());
|
||||
self::registerBlock(new Water());
|
||||
self::registerBlock(new StillWater());
|
||||
self::registerBlock(new Lava());
|
||||
self::registerBlock(new StillLava());
|
||||
self::registerBlock(new Sand());
|
||||
self::registerBlock(new Gravel());
|
||||
self::registerBlock(new GoldOre());
|
||||
self::registerBlock(new IronOre());
|
||||
self::registerBlock(new CoalOre());
|
||||
self::registerBlock(new Wood());
|
||||
self::registerBlock(new Leaves());
|
||||
self::registerBlock(new Sponge());
|
||||
self::registerBlock(new Glass());
|
||||
self::registerBlock(new LapisOre());
|
||||
self::registerBlock(new Lapis());
|
||||
//TODO: DISPENSER
|
||||
self::registerBlock(new Sandstone());
|
||||
self::registerBlock(new NoteBlock());
|
||||
self::registerBlock(new Bed());
|
||||
self::registerBlock(new PoweredRail());
|
||||
self::registerBlock(new DetectorRail());
|
||||
//TODO: STICKY_PISTON
|
||||
self::registerBlock(new Cobweb());
|
||||
self::registerBlock(new TallGrass());
|
||||
self::registerBlock(new DeadBush());
|
||||
//TODO: PISTON
|
||||
//TODO: PISTONARMCOLLISION
|
||||
self::registerBlock(new Wool());
|
||||
|
||||
self::registerBlock(new Dandelion());
|
||||
self::registerBlock(new Flower());
|
||||
self::registerBlock(new BrownMushroom());
|
||||
self::registerBlock(new RedMushroom());
|
||||
self::registerBlock(new Gold());
|
||||
self::registerBlock(new Iron());
|
||||
self::registerBlock(new DoubleStoneSlab());
|
||||
self::registerBlock(new StoneSlab());
|
||||
self::registerBlock(new Bricks());
|
||||
self::registerBlock(new TNT());
|
||||
self::registerBlock(new Bookshelf());
|
||||
self::registerBlock(new MossyCobblestone());
|
||||
self::registerBlock(new Obsidian());
|
||||
self::registerBlock(new Torch());
|
||||
self::registerBlock(new Fire());
|
||||
self::registerBlock(new MonsterSpawner());
|
||||
self::registerBlock(new WoodenStairs(Block::OAK_STAIRS, 0, "Oak Stairs"));
|
||||
self::registerBlock(new Chest());
|
||||
//TODO: REDSTONE_WIRE
|
||||
self::registerBlock(new DiamondOre());
|
||||
self::registerBlock(new Diamond());
|
||||
self::registerBlock(new CraftingTable());
|
||||
self::registerBlock(new Wheat());
|
||||
self::registerBlock(new Farmland());
|
||||
self::registerBlock(new Furnace());
|
||||
self::registerBlock(new BurningFurnace());
|
||||
self::registerBlock(new SignPost());
|
||||
self::registerBlock(new WoodenDoor(Block::OAK_DOOR_BLOCK, 0, "Oak Door Block", Item::OAK_DOOR));
|
||||
self::registerBlock(new Ladder());
|
||||
self::registerBlock(new Rail());
|
||||
self::registerBlock(new CobblestoneStairs());
|
||||
self::registerBlock(new WallSign());
|
||||
self::registerBlock(new Lever());
|
||||
self::registerBlock(new StonePressurePlate());
|
||||
self::registerBlock(new IronDoor());
|
||||
self::registerBlock(new WoodenPressurePlate());
|
||||
self::registerBlock(new RedstoneOre());
|
||||
self::registerBlock(new GlowingRedstoneOre());
|
||||
self::registerBlock(new RedstoneTorchUnlit());
|
||||
self::registerBlock(new RedstoneTorch());
|
||||
self::registerBlock(new StoneButton());
|
||||
self::registerBlock(new SnowLayer());
|
||||
self::registerBlock(new Ice());
|
||||
self::registerBlock(new Snow());
|
||||
self::registerBlock(new Cactus());
|
||||
self::registerBlock(new Clay());
|
||||
self::registerBlock(new Sugarcane());
|
||||
|
||||
self::registerBlock(new Fence());
|
||||
self::registerBlock(new Pumpkin());
|
||||
self::registerBlock(new Netherrack());
|
||||
self::registerBlock(new SoulSand());
|
||||
self::registerBlock(new Glowstone());
|
||||
//TODO: PORTAL
|
||||
self::registerBlock(new LitPumpkin());
|
||||
self::registerBlock(new Cake());
|
||||
//TODO: REPEATER_BLOCK
|
||||
//TODO: POWERED_REPEATER
|
||||
//TODO: INVISIBLEBEDROCK
|
||||
self::registerBlock(new Trapdoor());
|
||||
//TODO: MONSTER_EGG
|
||||
self::registerBlock(new StoneBricks());
|
||||
//TODO: BROWN_MUSHROOM_BLOCK
|
||||
//TODO: RED_MUSHROOM_BLOCK
|
||||
self::registerBlock(new IronBars());
|
||||
self::registerBlock(new GlassPane());
|
||||
self::registerBlock(new Melon());
|
||||
self::registerBlock(new PumpkinStem());
|
||||
self::registerBlock(new MelonStem());
|
||||
self::registerBlock(new Vine());
|
||||
self::registerBlock(new FenceGate(Block::OAK_FENCE_GATE, 0, "Oak Fence Gate"));
|
||||
self::registerBlock(new BrickStairs());
|
||||
self::registerBlock(new StoneBrickStairs());
|
||||
self::registerBlock(new Mycelium());
|
||||
self::registerBlock(new WaterLily());
|
||||
self::registerBlock(new NetherBrick(Block::NETHER_BRICK_BLOCK, 0, "Nether Bricks"));
|
||||
self::registerBlock(new NetherBrickFence());
|
||||
self::registerBlock(new NetherBrickStairs());
|
||||
self::registerBlock(new NetherWartPlant());
|
||||
self::registerBlock(new EnchantingTable());
|
||||
self::registerBlock(new BrewingStand());
|
||||
//TODO: CAULDRON_BLOCK
|
||||
//TODO: END_PORTAL
|
||||
self::registerBlock(new EndPortalFrame());
|
||||
self::registerBlock(new EndStone());
|
||||
//TODO: DRAGON_EGG
|
||||
self::registerBlock(new RedstoneLamp());
|
||||
self::registerBlock(new LitRedstoneLamp());
|
||||
//TODO: DROPPER
|
||||
self::registerBlock(new ActivatorRail());
|
||||
self::registerBlock(new CocoaBlock());
|
||||
self::registerBlock(new SandstoneStairs());
|
||||
self::registerBlock(new EmeraldOre());
|
||||
//TODO: ENDER_CHEST
|
||||
self::registerBlock(new TripwireHook());
|
||||
self::registerBlock(new Tripwire());
|
||||
self::registerBlock(new Emerald());
|
||||
self::registerBlock(new WoodenStairs(Block::SPRUCE_STAIRS, 0, "Spruce Stairs"));
|
||||
self::registerBlock(new WoodenStairs(Block::BIRCH_STAIRS, 0, "Birch Stairs"));
|
||||
self::registerBlock(new WoodenStairs(Block::JUNGLE_STAIRS, 0, "Jungle Stairs"));
|
||||
//TODO: COMMAND_BLOCK
|
||||
//TODO: BEACON
|
||||
self::registerBlock(new CobblestoneWall());
|
||||
self::registerBlock(new FlowerPot());
|
||||
self::registerBlock(new Carrot());
|
||||
self::registerBlock(new Potato());
|
||||
self::registerBlock(new WoodenButton());
|
||||
self::registerBlock(new Skull());
|
||||
self::registerBlock(new Anvil());
|
||||
self::registerBlock(new TrappedChest());
|
||||
self::registerBlock(new WeightedPressurePlateLight());
|
||||
self::registerBlock(new WeightedPressurePlateHeavy());
|
||||
//TODO: COMPARATOR_BLOCK
|
||||
//TODO: POWERED_COMPARATOR
|
||||
self::registerBlock(new DaylightSensor());
|
||||
self::registerBlock(new Redstone());
|
||||
self::registerBlock(new NetherQuartzOre());
|
||||
//TODO: HOPPER_BLOCK
|
||||
self::registerBlock(new Quartz());
|
||||
self::registerBlock(new QuartzStairs());
|
||||
self::registerBlock(new DoubleWoodenSlab());
|
||||
self::registerBlock(new WoodenSlab());
|
||||
self::registerBlock(new StainedClay());
|
||||
self::registerBlock(new StainedGlassPane());
|
||||
self::registerBlock(new Leaves2());
|
||||
self::registerBlock(new Wood2());
|
||||
self::registerBlock(new WoodenStairs(Block::ACACIA_STAIRS, 0, "Acacia Stairs"));
|
||||
self::registerBlock(new WoodenStairs(Block::DARK_OAK_STAIRS, 0, "Dark Oak Stairs"));
|
||||
//TODO: SLIME
|
||||
|
||||
self::registerBlock(new IronTrapdoor());
|
||||
self::registerBlock(new Prismarine());
|
||||
self::registerBlock(new SeaLantern());
|
||||
self::registerBlock(new HayBale());
|
||||
self::registerBlock(new Carpet());
|
||||
self::registerBlock(new HardenedClay());
|
||||
self::registerBlock(new Coal());
|
||||
self::registerBlock(new PackedIce());
|
||||
self::registerBlock(new DoublePlant());
|
||||
|
||||
//TODO: DAYLIGHT_DETECTOR_INVERTED
|
||||
//TODO: RED_SANDSTONE
|
||||
//TODO: RED_SANDSTONE_STAIRS
|
||||
//TODO: DOUBLE_STONE_SLAB2
|
||||
//TODO: STONE_SLAB2
|
||||
self::registerBlock(new FenceGate(Block::SPRUCE_FENCE_GATE, 0, "Spruce Fence Gate"));
|
||||
self::registerBlock(new FenceGate(Block::BIRCH_FENCE_GATE, 0, "Birch Fence Gate"));
|
||||
self::registerBlock(new FenceGate(Block::JUNGLE_FENCE_GATE, 0, "Jungle Fence Gate"));
|
||||
self::registerBlock(new FenceGate(Block::DARK_OAK_FENCE_GATE, 0, "Dark Oak Fence Gate"));
|
||||
self::registerBlock(new FenceGate(Block::ACACIA_FENCE_GATE, 0, "Acacia Fence Gate"));
|
||||
//TODO: REPEATING_COMMAND_BLOCK
|
||||
//TODO: CHAIN_COMMAND_BLOCK
|
||||
|
||||
self::registerBlock(new WoodenDoor(Block::SPRUCE_DOOR_BLOCK, 0, "Spruce Door Block", Item::SPRUCE_DOOR));
|
||||
self::registerBlock(new WoodenDoor(Block::BIRCH_DOOR_BLOCK, 0, "Birch Door Block", Item::BIRCH_DOOR));
|
||||
self::registerBlock(new WoodenDoor(Block::JUNGLE_DOOR_BLOCK, 0, "Jungle Door Block", Item::JUNGLE_DOOR));
|
||||
self::registerBlock(new WoodenDoor(Block::ACACIA_DOOR_BLOCK, 0, "Acacia Door Block", Item::ACACIA_DOOR));
|
||||
self::registerBlock(new WoodenDoor(Block::DARK_OAK_DOOR_BLOCK, 0, "Dark Oak Door Block", Item::DARK_OAK_DOOR));
|
||||
self::registerBlock(new GrassPath());
|
||||
self::registerBlock(new ItemFrame());
|
||||
//TODO: CHORUS_FLOWER
|
||||
//TODO: PURPUR_BLOCK
|
||||
|
||||
//TODO: PURPUR_STAIRS
|
||||
|
||||
//TODO: END_BRICKS
|
||||
//TODO: FROSTED_ICE
|
||||
self::registerBlock(new EndRod());
|
||||
//TODO: END_GATEWAY
|
||||
|
||||
self::registerBlock(new Magma());
|
||||
self::registerBlock(new NetherWartBlock());
|
||||
self::registerBlock(new NetherBrick(Block::RED_NETHER_BRICK, 0, "Red Nether Bricks"));
|
||||
//TODO: BONE_BLOCK
|
||||
|
||||
//TODO: SHULKER_BOX
|
||||
self::registerBlock(new GlazedTerracotta(Block::PURPLE_GLAZED_TERRACOTTA, 0, "Purple Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::WHITE_GLAZED_TERRACOTTA, 0, "White Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::ORANGE_GLAZED_TERRACOTTA, 0, "Orange Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::MAGENTA_GLAZED_TERRACOTTA, 0, "Magenta Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::LIGHT_BLUE_GLAZED_TERRACOTTA, 0, "Light Blue Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::YELLOW_GLAZED_TERRACOTTA, 0, "Yellow Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::LIME_GLAZED_TERRACOTTA, 0, "Lime Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::PINK_GLAZED_TERRACOTTA, 0, "Pink Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::GRAY_GLAZED_TERRACOTTA, 0, "Grey Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::SILVER_GLAZED_TERRACOTTA, 0, "Light Grey Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::CYAN_GLAZED_TERRACOTTA, 0, "Cyan Glazed Terracotta"));
|
||||
|
||||
self::registerBlock(new GlazedTerracotta(Block::BLUE_GLAZED_TERRACOTTA, 0, "Blue Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::BROWN_GLAZED_TERRACOTTA, 0, "Brown Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::GREEN_GLAZED_TERRACOTTA, 0, "Green Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::RED_GLAZED_TERRACOTTA, 0, "Red Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::BLACK_GLAZED_TERRACOTTA, 0, "Black Glazed Terracotta"));
|
||||
//TODO: CONCRETE
|
||||
//TODO: CONCRETEPOWDER
|
||||
|
||||
//TODO: CHORUS_PLANT
|
||||
self::registerBlock(new StainedGlass());
|
||||
|
||||
self::registerBlock(new Podzol());
|
||||
self::registerBlock(new Beetroot());
|
||||
self::registerBlock(new Stonecutter());
|
||||
self::registerBlock(new GlowingObsidian());
|
||||
self::registerBlock(new NetherReactor());
|
||||
//TODO: INFO_UPDATE
|
||||
//TODO: INFO_UPDATE2
|
||||
//TODO: MOVINGBLOCK
|
||||
//TODO: OBSERVER
|
||||
|
||||
//TODO: RESERVED6
|
||||
|
||||
foreach(self::$list as $id => $block){
|
||||
if($block === null){
|
||||
self::registerBlock(new UnknownBlock($id));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a block type into the index. Plugins may use this method to register new block types or override
|
||||
* existing ones.
|
||||
*
|
||||
* NOTE: If you are registering a new block type, you will need to add it to the creative inventory yourself - it
|
||||
* will not automatically appear there.
|
||||
*
|
||||
* @param Block $block
|
||||
* @param bool $override Whether to override existing registrations
|
||||
*
|
||||
* @throws \RuntimeException if something attempted to override an already-registered block without specifying the
|
||||
* $override parameter.
|
||||
*/
|
||||
public static function registerBlock(Block $block, bool $override = false){
|
||||
$id = $block->getId();
|
||||
|
||||
if(self::$list[$id] !== null and !(self::$list[$id] instanceof UnknownBlock) and !$override){
|
||||
throw new \RuntimeException("Trying to overwrite an already registered block");
|
||||
}
|
||||
|
||||
self::$list[$id] = clone $block;
|
||||
|
||||
for($meta = 0; $meta < 16; ++$meta){
|
||||
$variant = clone $block;
|
||||
$variant->setDamage($meta);
|
||||
self::$fullList[($id << 4) | $meta] = $variant;
|
||||
}
|
||||
|
||||
self::$solid[$id] = $block->isSolid();
|
||||
self::$transparent[$id] = $block->isTransparent();
|
||||
self::$hardness[$id] = $block->getHardness();
|
||||
self::$light[$id] = $block->getLightLevel();
|
||||
self::$lightFilter[$id] = $block->getLightFilter() + 1; //opacity plus 1 standard light filter
|
||||
self::$diffusesSkyLight[$id] = $block->diffusesSkyLight();
|
||||
self::$blastResistance[$id] = $block->getBlastResistance();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param int $meta
|
||||
* @param Position $pos
|
||||
*
|
||||
* @return Block
|
||||
*/
|
||||
public static function get(int $id, int $meta = 0, Position $pos = null) : Block{
|
||||
try{
|
||||
$block = self::$fullList[($id << 4) | $meta];
|
||||
if($block !== null){
|
||||
$block = clone $block;
|
||||
}else{
|
||||
$block = new UnknownBlock($id, $meta);
|
||||
}
|
||||
}catch(\RuntimeException $e){
|
||||
//TODO: this probably should return null (out of bounds IDs may cause unexpected behaviour)
|
||||
$block = new UnknownBlock($id, $meta);
|
||||
}
|
||||
|
||||
if($pos !== null){
|
||||
$block->x = $pos->x;
|
||||
$block->y = $pos->y;
|
||||
$block->z = $pos->z;
|
||||
$block->level = $pos->level;
|
||||
}
|
||||
|
||||
return $block;
|
||||
}
|
||||
}
|
@ -37,7 +37,7 @@ class BrickStairs extends Stair{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getResistance() : float{
|
||||
public function getBlastResistance() : float{
|
||||
return 30;
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ class Bricks extends Solid{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getResistance() : float{
|
||||
public function getBlastResistance() : float{
|
||||
return 30;
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ class BrownMushroom extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->isTransparent() === false){
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\NBT;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\IntTag;
|
||||
@ -58,7 +59,7 @@ class BurningFurnace extends Solid{
|
||||
return 13;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$faces = [
|
||||
0 => 4,
|
||||
1 => 2,
|
||||
|
@ -90,7 +90,7 @@ class Cactus extends Transparent{
|
||||
for($y = 1; $y < 3; ++$y){
|
||||
$b = $this->getLevel()->getBlock(new Vector3($this->x, $this->y + $y, $this->z));
|
||||
if($b->getId() === self::AIR){
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($b, Block::get(Block::CACTUS)));
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($b, BlockFactory::get(Block::CACTUS)));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($b, $ev->getNewState(), true);
|
||||
}
|
||||
@ -108,7 +108,7 @@ class Cactus extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === self::SAND or $down->getId() === self::CACTUS){
|
||||
$block0 = $this->getSide(Vector3::SIDE_NORTH);
|
||||
|
@ -62,7 +62,7 @@ class Cake extends Transparent implements FoodSource{
|
||||
);
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() !== self::AIR){
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
@ -76,7 +76,7 @@ class Cake extends Transparent implements FoodSource{
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() === self::AIR){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, Block::get(Block::AIR), true);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
@ -114,7 +114,7 @@ class Cake extends Transparent implements FoodSource{
|
||||
$clone = clone $this;
|
||||
$clone->meta++;
|
||||
if($clone->meta >= 0x06){
|
||||
$clone = Block::get(Block::AIR);
|
||||
$clone = BlockFactory::get(Block::AIR);
|
||||
}
|
||||
return $clone;
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ class Carpet extends Flowable{
|
||||
);
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() !== self::AIR){
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
@ -67,7 +67,7 @@ class Chest extends Transparent{
|
||||
);
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$faces = [
|
||||
0 => 4,
|
||||
1 => 2,
|
||||
@ -129,7 +129,7 @@ class Chest extends Transparent{
|
||||
if($t instanceof TileChest){
|
||||
$t->unpair();
|
||||
}
|
||||
$this->getLevel()->setBlock($this, Block::get(Block::AIR), true, true);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ use pocketmine\Server;
|
||||
|
||||
abstract class Crops extends Flowable{
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($block->getSide(Vector3::SIDE_DOWN)->getId() === Block::FARMLAND){
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
||||
|
@ -41,7 +41,7 @@ class Dandelion extends Flowable{
|
||||
}
|
||||
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === 2 or $down->getId() === 3 or $down->getId() === 60){
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
@ -50,7 +50,7 @@ class Dirt extends Solid{
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($item->isHoe()){
|
||||
$item->useOn($this);
|
||||
$this->getLevel()->setBlock($this, Block::get(Block::FARMLAND, 0), true);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::FARMLAND, 0), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -204,9 +204,9 @@ abstract class Door extends Transparent{
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() === self::AIR){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, Block::get(Block::AIR), false);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), false);
|
||||
if($this->getSide(Vector3::SIDE_UP) instanceof Door){
|
||||
$this->getLevel()->setBlock($this->getSide(Vector3::SIDE_UP), Block::get(Block::AIR), false);
|
||||
$this->getLevel()->setBlock($this->getSide(Vector3::SIDE_UP), BlockFactory::get(Block::AIR), false);
|
||||
}
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
@ -216,22 +216,22 @@ abstract class Door extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
if($face === 1){
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($face === Vector3::SIDE_UP){
|
||||
$blockUp = $this->getSide(Vector3::SIDE_UP);
|
||||
$blockDown = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($blockUp->canBeReplaced() === false or $blockDown->isTransparent() === true){
|
||||
return false;
|
||||
}
|
||||
$direction = $player instanceof Player ? $player->getDirection() : 0;
|
||||
$face = [
|
||||
$faces = [
|
||||
0 => 3,
|
||||
1 => 4,
|
||||
2 => 2,
|
||||
3 => 5,
|
||||
];
|
||||
$next = $this->getSide($face[($direction + 2) % 4]);
|
||||
$next2 = $this->getSide($face[$direction]);
|
||||
$next = $this->getSide($faces[($direction + 2) % 4]);
|
||||
$next2 = $this->getSide($faces[$direction]);
|
||||
$metaUp = 0x08;
|
||||
if($next->getId() === $this->getId() or ($next2->isTransparent() === false and $next->isTransparent() === true)){ //Door hinge
|
||||
$metaUp |= 0x01;
|
||||
@ -239,7 +239,7 @@ abstract class Door extends Transparent{
|
||||
|
||||
$this->setDamage($player->getDirection() & 0x03);
|
||||
$this->getLevel()->setBlock($block, $this, true, true); //Bottom
|
||||
$this->getLevel()->setBlock($blockUp, $b = Block::get($this->getId(), $metaUp), true); //Top
|
||||
$this->getLevel()->setBlock($blockUp, $b = BlockFactory::get($this->getId(), $metaUp), true); //Top
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -250,15 +250,15 @@ abstract class Door extends Transparent{
|
||||
if(($this->getDamage() & 0x08) === 0x08){
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === $this->getId()){
|
||||
$this->getLevel()->setBlock($down, Block::get(Block::AIR), true);
|
||||
$this->getLevel()->setBlock($down, BlockFactory::get(Block::AIR), true);
|
||||
}
|
||||
}else{
|
||||
$up = $this->getSide(Vector3::SIDE_UP);
|
||||
if($up->getId() === $this->getId()){
|
||||
$this->getLevel()->setBlock($up, Block::get(Block::AIR), true);
|
||||
$this->getLevel()->setBlock($up, BlockFactory::get(Block::AIR), true);
|
||||
}
|
||||
}
|
||||
$this->getLevel()->setBlock($this, Block::get(Block::AIR), true);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -268,7 +268,7 @@ abstract class Door extends Transparent{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === $this->getId()){
|
||||
$meta = $down->getDamage() ^ 0x04;
|
||||
$this->level->setBlock($down, Block::get($this->getId(), $meta), true);
|
||||
$this->level->setBlock($down, BlockFactory::get($this->getId(), $meta), true);
|
||||
$this->level->addSound(new DoorSound($this));
|
||||
return true;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ class DoublePlant extends Flowable{
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function canBeReplaced() : bool{
|
||||
public function canBeReplaced(Block $with = null) : bool{
|
||||
return $this->meta === 2 or $this->meta === 3; //grass or fern
|
||||
}
|
||||
|
||||
@ -53,11 +53,11 @@ class DoublePlant extends Flowable{
|
||||
return $names[$this->meta & 0x07] ?? "";
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$id = $block->getSide(Vector3::SIDE_DOWN)->getId();
|
||||
if(($id === Block::GRASS or $id === Block::DIRT) and $block->getSide(Vector3::SIDE_UP)->canBeReplaced()){
|
||||
$this->getLevel()->setBlock($block, $this, false, false);
|
||||
$this->getLevel()->setBlock($block->getSide(Vector3::SIDE_UP), Block::get($this->id, $this->meta | self::BITFLAG_TOP), false, false);
|
||||
$this->getLevel()->setBlock($block->getSide(Vector3::SIDE_UP), BlockFactory::get($this->id, $this->meta | self::BITFLAG_TOP), false, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -98,7 +98,7 @@ class DoublePlant extends Flowable{
|
||||
|
||||
public function onBreak(Item $item) : bool{
|
||||
if(parent::onBreak($item) and $this->isValidHalfPlant()){
|
||||
return $this->getLevel()->setBlock($this->getSide(($this->meta & self::BITFLAG_TOP) !== 0 ? Vector3::SIDE_DOWN : Vector3::SIDE_UP), Block::get(Block::AIR));
|
||||
return $this->getLevel()->setBlock($this->getSide(($this->meta & self::BITFLAG_TOP) !== 0 ? Vector3::SIDE_DOWN : Vector3::SIDE_UP), BlockFactory::get(Block::AIR));
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -26,6 +26,7 @@ namespace pocketmine\block;
|
||||
use pocketmine\inventory\EnchantInventory;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\IntTag;
|
||||
use pocketmine\nbt\tag\StringTag;
|
||||
@ -40,7 +41,7 @@ class EnchantingTable extends Transparent{
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
$nbt = new CompoundTag("", [
|
||||
new StringTag("id", Tile::ENCHANT_TABLE),
|
||||
@ -68,7 +69,7 @@ class EnchantingTable extends Transparent{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getResistance() : float{
|
||||
public function getBlastResistance() : float{
|
||||
return 6000;
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ class EndPortalFrame extends Solid{
|
||||
return -1;
|
||||
}
|
||||
|
||||
public function getResistance() : float{
|
||||
public function getBlastResistance() : float{
|
||||
return 18000000;
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ class EndRod extends Flowable{
|
||||
return "End Rod";
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($face === Vector3::SIDE_UP or $face === Vector3::SIDE_DOWN){
|
||||
$this->meta = $face;
|
||||
}else{
|
||||
|
@ -39,7 +39,7 @@ abstract class Fallable extends Solid{
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === self::AIR or ($down instanceof Liquid)){
|
||||
$this->level->setBlock($this, Block::get(Block::AIR), true, true);
|
||||
$this->level->setBlock($this, BlockFactory::get(Block::AIR), true, true);
|
||||
$fall = Entity::createEntity("FallingSand", $this->getLevel(), new CompoundTag("", [
|
||||
new ListTag("Pos", [
|
||||
new DoubleTag("", $this->x + 0.5),
|
||||
|
@ -27,6 +27,7 @@ use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\level\sound\DoorSound;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class FenceGate extends Transparent{
|
||||
@ -68,7 +69,7 @@ class FenceGate extends Transparent{
|
||||
}
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$this->meta = ($player instanceof Player ? ($player->getDirection() - 1) & 0x03 : 0);
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
||||
|
@ -57,7 +57,7 @@ class Fire extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function canBeReplaced() : bool{
|
||||
public function canBeReplaced(Block $with = null) : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -87,14 +87,14 @@ class Fire extends Flowable{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$this->getLevel()->setBlock($this, Block::get(Block::AIR), true);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== self::NETHERRACK){
|
||||
if(mt_rand(0, 2) === 0){
|
||||
if($this->meta === 0x0F){
|
||||
$this->level->setBlock($this, Block::get(Block::AIR));
|
||||
$this->level->setBlock($this, BlockFactory::get(Block::AIR));
|
||||
}else{
|
||||
$this->meta++;
|
||||
$this->level->setBlock($this, $this);
|
||||
|
@ -33,7 +33,7 @@ abstract class Flowable extends Transparent{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getResistance() : float{
|
||||
public function getBlastResistance() : float{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ class Flower extends Flowable{
|
||||
return $names[$this->meta] ?? "Unknown";
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === Block::GRASS or $down->getId() === Block::DIRT or $down->getId() === Block::FARMLAND){
|
||||
$this->getLevel()->setBlock($block, $this, true);
|
||||
|
@ -62,7 +62,7 @@ class FlowerPot extends Flowable{
|
||||
);
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
return false;
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class GlazedTerracotta extends Solid{
|
||||
@ -38,7 +39,7 @@ class GlazedTerracotta extends Solid{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($player !== null){
|
||||
$faces = [
|
||||
0 => 4,
|
||||
|
@ -39,7 +39,7 @@ class GlowingRedstoneOre extends RedstoneOre{
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_SCHEDULED or $type === Level::BLOCK_UPDATE_RANDOM){
|
||||
$this->getLevel()->setBlock($this, Block::get(Block::REDSTONE_ORE, $this->meta), false, false);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::REDSTONE_ORE, $this->meta), false, false);
|
||||
|
||||
return Level::BLOCK_UPDATE_WEAK;
|
||||
}
|
||||
|
@ -61,9 +61,9 @@ class Grass extends Solid{
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
$lightAbove = $this->level->getFullLightAt($this->x, $this->y + 1, $this->z);
|
||||
if($lightAbove < 4 and Block::$lightFilter[$this->level->getBlockIdAt($this->x, $this->y + 1, $this->z)] >= 3){ //2 plus 1 standard filter amount
|
||||
if($lightAbove < 4 and BlockFactory::$lightFilter[$this->level->getBlockIdAt($this->x, $this->y + 1, $this->z)] >= 3){ //2 plus 1 standard filter amount
|
||||
//grass dies
|
||||
$this->level->getServer()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($this, $this, Block::get(Block::DIRT)));
|
||||
$this->level->getServer()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($this, $this, BlockFactory::get(Block::DIRT)));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->level->setBlock($this, $ev->getNewState(), false, false);
|
||||
}
|
||||
@ -79,12 +79,12 @@ class Grass extends Solid{
|
||||
if(
|
||||
$this->level->getBlockIdAt($vector->x, $vector->y, $vector->z) !== Block::DIRT or
|
||||
$this->level->getFullLightAt($vector->x, $vector->y + 1, $vector->z) < 4 or
|
||||
Block::$lightFilter[$this->level->getBlockIdAt($vector->x, $vector->y + 1, $vector->z)] >= 3
|
||||
BlockFactory::$lightFilter[$this->level->getBlockIdAt($vector->x, $vector->y + 1, $vector->z)] >= 3
|
||||
){
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->level->getServer()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($this->level->getBlock($vector), $this, Block::get(Block::GRASS)));
|
||||
$this->level->getServer()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($this->level->getBlock($vector), $this, BlockFactory::get(Block::GRASS)));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->level->setBlock($vector, $ev->getNewState(), false, false);
|
||||
}
|
||||
@ -105,12 +105,12 @@ class Grass extends Solid{
|
||||
return true;
|
||||
}elseif($item->isHoe()){
|
||||
$item->useOn($this);
|
||||
$this->getLevel()->setBlock($this, Block::get(Block::FARMLAND));
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::FARMLAND));
|
||||
|
||||
return true;
|
||||
}elseif($item->isShovel() and $this->getSide(Vector3::SIDE_UP)->getId() === Block::AIR){
|
||||
$item->useOn($this);
|
||||
$this->getLevel()->setBlock($this, Block::get(Block::GRASS_PATH));
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::GRASS_PATH));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class HayBale extends Solid{
|
||||
@ -42,7 +43,7 @@ class HayBale extends Solid{
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$faces = [
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
|
@ -52,7 +52,7 @@ class Ice extends Transparent{
|
||||
}
|
||||
|
||||
public function onBreak(Item $item) : bool{
|
||||
$this->getLevel()->setBlock($this, Block::get(Block::WATER), true);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::WATER), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\{
|
||||
ByteTag, CompoundTag, FloatTag, IntTag, StringTag
|
||||
};
|
||||
@ -103,16 +104,16 @@ class ItemFrame extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
if($face === 0 or $face === 1){
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($face === Vector3::SIDE_DOWN or $face === Vector3::SIDE_UP){
|
||||
return false;
|
||||
}
|
||||
|
||||
$faces = [
|
||||
2 => 3,
|
||||
3 => 2,
|
||||
4 => 1,
|
||||
5 => 0
|
||||
Vector3::SIDE_NORTH => 3,
|
||||
Vector3::SIDE_SOUTH => 2,
|
||||
Vector3::SIDE_WEST => 1,
|
||||
Vector3::SIDE_EAST => 0
|
||||
];
|
||||
|
||||
$this->meta = $faces[$face];
|
||||
|
@ -28,6 +28,7 @@ use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Ladder extends Transparent{
|
||||
@ -109,7 +110,7 @@ class Ladder extends Transparent{
|
||||
}
|
||||
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($target->isTransparent() === false){
|
||||
$faces = [
|
||||
2 => 2,
|
||||
|
@ -28,6 +28,7 @@ use pocketmine\event\entity\EntityCombustByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
|
||||
@ -62,7 +63,7 @@ class Lava extends Liquid{
|
||||
$entity->resetFallDistance();
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$ret = $this->getLevel()->setBlock($this, $this, true, false);
|
||||
$this->getLevel()->scheduleDelayedBlockUpdate($this, $this->tickRate());
|
||||
|
||||
|
@ -159,7 +159,7 @@ class Leaves extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$this->meta |= 0x04;
|
||||
return $this->getLevel()->setBlock($this, $this, true);
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ abstract class Liquid extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function canBeReplaced() : bool{
|
||||
public function canBeReplaced(Block $with = null) : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -241,9 +241,9 @@ abstract class Liquid extends Transparent{
|
||||
if($k !== $decay){
|
||||
$decay = $k;
|
||||
if($decay < 0){
|
||||
$this->getLevel()->setBlock($this, Block::get(Block::AIR), true, true);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true, true);
|
||||
}else{
|
||||
$this->getLevel()->setBlock($this, Block::get($this->id, $decay), true, true);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get($this->id, $decay), true, true);
|
||||
$this->getLevel()->scheduleDelayedBlockUpdate($this, $this->tickRate());
|
||||
}
|
||||
}elseif($flag){
|
||||
@ -257,10 +257,10 @@ abstract class Liquid extends Transparent{
|
||||
$bottomBlock = $this->level->getBlock($this->temporalVector->setComponents($this->x, $this->y - 1, $this->z));
|
||||
|
||||
if($this instanceof Lava and $bottomBlock instanceof Water){
|
||||
$this->getLevel()->setBlock($bottomBlock, Block::get(Block::STONE), true, true);
|
||||
$this->getLevel()->setBlock($bottomBlock, BlockFactory::get(Block::STONE), true, true);
|
||||
|
||||
}elseif($bottomBlock->canBeFlowedInto() or ($bottomBlock instanceof Liquid and ($bottomBlock->getDamage() & 0x07) !== 0)){
|
||||
$this->getLevel()->setBlock($bottomBlock, Block::get($this->id, $decay | 0x08), true, false);
|
||||
$this->getLevel()->setBlock($bottomBlock, BlockFactory::get($this->id, $decay | 0x08), true, false);
|
||||
$this->getLevel()->scheduleDelayedBlockUpdate($bottomBlock, $this->tickRate());
|
||||
|
||||
}elseif($decay >= 0 and ($decay === 0 or !$bottomBlock->canBeFlowedInto())){
|
||||
@ -305,7 +305,7 @@ abstract class Liquid extends Transparent{
|
||||
$this->getLevel()->useBreakOn($block);
|
||||
}
|
||||
|
||||
$this->getLevel()->setBlock($block, Block::get($this->getId(), $newFlowDecay), true, false);
|
||||
$this->getLevel()->setBlock($block, BlockFactory::get($this->getId(), $newFlowDecay), true, false);
|
||||
$this->getLevel()->scheduleDelayedBlockUpdate($block, $this->tickRate());
|
||||
}
|
||||
}
|
||||
@ -434,9 +434,9 @@ abstract class Liquid extends Transparent{
|
||||
|
||||
if($colliding){
|
||||
if($this->getDamage() === 0){
|
||||
$this->getLevel()->setBlock($this, Block::get(Block::OBSIDIAN), true, true);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::OBSIDIAN), true, true);
|
||||
}elseif($this->getDamage() <= 4){
|
||||
$this->getLevel()->setBlock($this, Block::get(Block::COBBLESTONE), true, true);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::COBBLESTONE), true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ class MelonStem extends Crops{
|
||||
$side = $this->getSide(mt_rand(2, 5));
|
||||
$d = $side->getSide(Vector3::SIDE_DOWN);
|
||||
if($side->getId() === self::AIR and ($d->getId() === self::FARMLAND or $d->getId() === self::GRASS or $d->getId() === self::DIRT)){
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($side, Block::get(Block::MELON_BLOCK)));
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($side, BlockFactory::get(Block::MELON_BLOCK)));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($side, $ev->getNewState(), true);
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ class Mycelium extends Solid{
|
||||
$block = $this->getLevel()->getBlock(new Vector3($x, $y, $z));
|
||||
if($block->getId() === Block::DIRT){
|
||||
if($block->getSide(Vector3::SIDE_UP) instanceof Transparent){
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($block, $this, Block::get(Block::MYCELIUM)));
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($block, $this, BlockFactory::get(Block::MYCELIUM)));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($block, $ev->getNewState());
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ class NetherWartPlant extends Flowable{
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === Block::SOUL_SAND){
|
||||
$this->getLevel()->setBlock($block, $this, false, true);
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Pumpkin extends Solid{
|
||||
@ -47,7 +48,7 @@ class Pumpkin extends Solid{
|
||||
return "Pumpkin";
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
$this->meta = ((int) $player->getDirection() + 1) % 4;
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ class PumpkinStem extends Crops{
|
||||
$side = $this->getSide(mt_rand(2, 5));
|
||||
$d = $side->getSide(Vector3::SIDE_DOWN);
|
||||
if($side->getId() === self::AIR and ($d->getId() === self::FARMLAND or $d->getId() === self::GRASS or $d->getId() === self::DIRT)){
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($side, Block::get(Block::PUMPKIN)));
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($side, BlockFactory::get(Block::PUMPKIN)));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($side, $ev->getNewState(), true);
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ class Rail extends Flowable{
|
||||
return 0.7;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if(!$block->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
return $this->getLevel()->setBlock($block, $this, true, true);
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ class RedMushroom extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->isTransparent() === false){
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
@ -26,6 +26,7 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class RedstoneOre extends Solid{
|
||||
@ -44,13 +45,13 @@ class RedstoneOre extends Solid{
|
||||
return 3;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
return $this->getLevel()->setBlock($this, $this, true, false);
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL or $type === Level::BLOCK_UPDATE_TOUCH){
|
||||
$this->getLevel()->setBlock($this, Block::get(Block::GLOWING_REDSTONE_ORE, $this->meta));
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::GLOWING_REDSTONE_ORE, $this->meta));
|
||||
|
||||
return Level::BLOCK_UPDATE_WEAK;
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ class Sapling extends Flowable{
|
||||
}
|
||||
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === self::GRASS or $down->getId() === self::DIRT or $down->getId() === self::FARMLAND){
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
@ -60,8 +60,8 @@ class SignPost extends Transparent{
|
||||
}
|
||||
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
if($face !== 0){
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($face !== Vector3::SIDE_DOWN){
|
||||
$nbt = new CompoundTag("", [
|
||||
new StringTag("id", Tile::SIGN),
|
||||
new IntTag("x", $block->x),
|
||||
@ -83,7 +83,7 @@ class SignPost extends Transparent{
|
||||
}
|
||||
}
|
||||
|
||||
if($face === 1){
|
||||
if($face === Vector3::SIDE_UP){
|
||||
$this->meta = floor((($player->yaw + 180) * 16 / 360) + 0.5) & 0x0f;
|
||||
$this->getLevel()->setBlock($block, $this, true);
|
||||
}else{
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\ByteTag;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\IntTag;
|
||||
@ -62,10 +63,10 @@ class Skull extends Flowable{
|
||||
);
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
if($face !== 0){
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($face !== Vector3::SIDE_DOWN){
|
||||
$this->meta = $face;
|
||||
if($face === 1){
|
||||
if($face === Vector3::SIDE_UP){
|
||||
$rot = floor(($player->yaw * 16 / 360) + 0.5) & 0x0F;
|
||||
}else{
|
||||
$rot = $face;
|
||||
|
@ -41,7 +41,7 @@ class SnowLayer extends Flowable{
|
||||
return "Snow Layer";
|
||||
}
|
||||
|
||||
public function canBeReplaced() : bool{
|
||||
public function canBeReplaced(Block $with = null) : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ class SnowLayer extends Flowable{
|
||||
}
|
||||
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($block->getSide(Vector3::SIDE_DOWN)->isSolid()){
|
||||
//TODO: fix placement
|
||||
$this->getLevel()->setBlock($block, $this, true);
|
||||
@ -68,13 +68,13 @@ class SnowLayer extends Flowable{
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if(!$this->getSide(Vector3::SIDE_DOWN)->isSolid()){
|
||||
$this->getLevel()->setBlock($this, Block::get(Block::AIR), false, false);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), false, false);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
if($this->level->getBlockLightAt($this->x, $this->y, $this->z) >= 12){
|
||||
$this->getLevel()->setBlock($this, Block::get(Block::AIR), false, false);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), false, false);
|
||||
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
abstract class Stair extends Transparent{
|
||||
@ -129,7 +130,7 @@ abstract class Stair extends Transparent{
|
||||
}
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$faces = [
|
||||
0 => 0,
|
||||
1 => 2,
|
||||
@ -137,7 +138,7 @@ abstract class Stair extends Transparent{
|
||||
3 => 3,
|
||||
];
|
||||
$this->meta = $faces[$player->getDirection()] & 0x03;
|
||||
if(($fy > 0.5 and $face !== 1) or $face === 0){
|
||||
if(($facePos->y > 0.5 and $face !== Vector3::SIDE_UP) or $face === Vector3::SIDE_DOWN){
|
||||
$this->meta |= 0x04; //Upside-down stairs
|
||||
}
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
@ -50,7 +50,7 @@ class Sugarcane extends Flowable{
|
||||
for($y = 1; $y < 3; ++$y){
|
||||
$b = $this->getLevel()->getBlock(new Vector3($this->x, $this->y + $y, $this->z));
|
||||
if($b->getId() === self::AIR){
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($b, Block::get(Block::SUGARCANE_BLOCK)));
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($b, BlockFactory::get(Block::SUGARCANE_BLOCK)));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($b, $ev->getNewState(), true);
|
||||
}
|
||||
@ -84,7 +84,7 @@ class Sugarcane extends Flowable{
|
||||
for($y = 1; $y < 3; ++$y){
|
||||
$b = $this->getLevel()->getBlock(new Vector3($this->x, $this->y + $y, $this->z));
|
||||
if($b->getId() === self::AIR){
|
||||
$this->getLevel()->setBlock($b, Block::get(Block::SUGARCANE_BLOCK), true);
|
||||
$this->getLevel()->setBlock($b, BlockFactory::get(Block::SUGARCANE_BLOCK), true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -102,10 +102,10 @@ class Sugarcane extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === self::SUGARCANE_BLOCK){
|
||||
$this->getLevel()->setBlock($block, Block::get(Block::SUGARCANE_BLOCK), true);
|
||||
$this->getLevel()->setBlock($block, BlockFactory::get(Block::SUGARCANE_BLOCK), true);
|
||||
|
||||
return true;
|
||||
}elseif($down->getId() === self::GRASS or $down->getId() === self::DIRT or $down->getId() === self::SAND){
|
||||
@ -114,7 +114,7 @@ class Sugarcane extends Flowable{
|
||||
$block2 = $down->getSide(Vector3::SIDE_WEST);
|
||||
$block3 = $down->getSide(Vector3::SIDE_EAST);
|
||||
if(($block0 instanceof Water) or ($block1 instanceof Water) or ($block2 instanceof Water) or ($block3 instanceof Water)){
|
||||
$this->getLevel()->setBlock($block, Block::get(Block::SUGARCANE_BLOCK), true);
|
||||
$this->getLevel()->setBlock($block, BlockFactory::get(Block::SUGARCANE_BLOCK), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ class TNT extends Solid{
|
||||
}
|
||||
|
||||
public function ignite(int $fuse = 80){
|
||||
$this->getLevel()->setBlock($this, Block::get(Block::AIR), true);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true);
|
||||
|
||||
$mot = (new Random())->nextSignedFloat() * M_PI * 2;
|
||||
$tnt = Entity::createEntity("PrimedTNT", $this->getLevel(), new CompoundTag("", [
|
||||
|
@ -36,7 +36,7 @@ class TallGrass extends Flowable{
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function canBeReplaced() : bool{
|
||||
public function canBeReplaced(Block $with = null) : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ class TallGrass extends Flowable{
|
||||
return $names[$this->meta & 0x03] ?? "Unknown";
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === self::GRASS){
|
||||
$this->getLevel()->setBlock($block, $this, true);
|
||||
@ -64,7 +64,7 @@ class TallGrass extends Flowable{
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent() === true){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, Block::get(Block::AIR), true, true);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true, true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
|
@ -68,16 +68,16 @@ class Torch extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$below = $this->getSide(Vector3::SIDE_DOWN);
|
||||
|
||||
if($target->isTransparent() === false and $face !== 0){
|
||||
if($target->isTransparent() === false and $face !== Vector3::SIDE_DOWN){
|
||||
$faces = [
|
||||
1 => 5,
|
||||
2 => 4,
|
||||
3 => 3,
|
||||
4 => 2,
|
||||
5 => 1,
|
||||
Vector3::SIDE_UP => 5,
|
||||
Vector3::SIDE_NORTH => 4,
|
||||
Vector3::SIDE_SOUTH => 3,
|
||||
Vector3::SIDE_WEST => 2,
|
||||
Vector3::SIDE_EAST => 1,
|
||||
];
|
||||
$this->meta = $faces[$face];
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
@ -27,6 +27,7 @@ use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\level\sound\DoorSound;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Trapdoor extends Transparent{
|
||||
@ -123,7 +124,7 @@ class Trapdoor extends Transparent{
|
||||
return $bb;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$directions = [
|
||||
0 => 1,
|
||||
1 => 3,
|
||||
@ -133,7 +134,7 @@ class Trapdoor extends Transparent{
|
||||
if($player !== null){
|
||||
$this->meta = $directions[$player->getDirection() & 0x03];
|
||||
}
|
||||
if(($fy > 0.5 and $face !== self::SIDE_UP) or $face === self::SIDE_DOWN){
|
||||
if(($facePos->y > 0.5 and $face !== self::SIDE_UP) or $face === self::SIDE_DOWN){
|
||||
$this->meta |= self::MASK_UPPER; //top half of block
|
||||
}
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
@ -132,7 +132,7 @@ class Vine extends Transparent{
|
||||
}
|
||||
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
//TODO: multiple sides
|
||||
if($target->isSolid()){
|
||||
$faces = [
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Water extends Liquid{
|
||||
@ -52,7 +53,7 @@ class Water extends Liquid{
|
||||
$entity->resetFallDistance();
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$ret = $this->getLevel()->setBlock($this, $this, true, false);
|
||||
$this->getLevel()->scheduleDelayedBlockUpdate($this, $this->tickRate());
|
||||
|
||||
|
@ -57,7 +57,7 @@ class WaterLily extends Flowable{
|
||||
}
|
||||
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($target instanceof Water){
|
||||
$up = $target->getSide(Vector3::SIDE_UP);
|
||||
if($up->getId() === Block::AIR){
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Wood extends Solid{
|
||||
@ -53,14 +54,14 @@ class Wood extends Solid{
|
||||
return $names[$this->meta & 0x03];
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$faces = [
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 0b1000,
|
||||
3 => 0b1000,
|
||||
4 => 0b0100,
|
||||
5 => 0b0100,
|
||||
Vector3::SIDE_DOWN => 0,
|
||||
Vector3::SIDE_UP => 0,
|
||||
Vector3::SIDE_NORTH => 0b1000,
|
||||
Vector3::SIDE_SOUTH => 0b1000,
|
||||
Vector3::SIDE_WEST => 0b0100,
|
||||
Vector3::SIDE_EAST => 0b0100,
|
||||
];
|
||||
|
||||
$this->meta = ($this->meta & 0x03) | $faces[$face];
|
||||
|
@ -26,6 +26,7 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class WoodenSlab extends Transparent{
|
||||
@ -77,41 +78,45 @@ class WoodenSlab extends Transparent{
|
||||
}
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, float $fx, float $fy, float $fz, Player $player = null) : bool{
|
||||
public function canBeReplaced(Block $with = null) : bool{
|
||||
return $with !== null and $with->getId() === $this->getId() and ($with->getDamage() & 0x07) === ($this->getDamage() & 0x07);
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$this->meta &= 0x07;
|
||||
if($face === 0){
|
||||
if($target->getId() === $this->id and ($target->getDamage() & 0x08) === 0x08 and ($target->getDamage() & 0x07) === ($this->meta)){
|
||||
$this->getLevel()->setBlock($target, Block::get($this->doubleId, $this->meta), true);
|
||||
if($face === Vector3::SIDE_DOWN){
|
||||
if($target->getId() === $this->id and ($target->getDamage() & 0x08) === 0x08 and ($target->getDamage() & 0x07) === $this->meta){
|
||||
$this->getLevel()->setBlock($target, BlockFactory::get($this->doubleId, $this->meta), true);
|
||||
|
||||
return true;
|
||||
}elseif($block->getId() === $this->id and ($block->getDamage() & 0x07) === ($this->meta)){
|
||||
$this->getLevel()->setBlock($block, Block::get($this->doubleId, $this->meta), true);
|
||||
}elseif($block->getId() === $this->id and ($block->getDamage() & 0x07) === $this->meta){
|
||||
$this->getLevel()->setBlock($block, BlockFactory::get($this->doubleId, $this->meta), true);
|
||||
|
||||
return true;
|
||||
}else{
|
||||
$this->meta |= 0x08;
|
||||
}
|
||||
}elseif($face === 1){
|
||||
}elseif($face === Vector3::SIDE_UP){
|
||||
if($target->getId() === $this->id and ($target->getDamage() & 0x08) === 0 and ($target->getDamage() & 0x07) === $this->meta){
|
||||
$this->getLevel()->setBlock($target, Block::get($this->doubleId, $this->meta), true);
|
||||
$this->getLevel()->setBlock($target, BlockFactory::get($this->doubleId, $this->meta), true);
|
||||
|
||||
return true;
|
||||
}elseif($block->getId() === $this->id and ($block->getDamage() & 0x07) === $this->meta){
|
||||
$this->getLevel()->setBlock($block, Block::get($this->doubleId, $this->meta), true);
|
||||
$this->getLevel()->setBlock($block, BlockFactory::get($this->doubleId, $this->meta), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
}else{ //TODO: collision
|
||||
if($block->getId() === $this->id){
|
||||
if(($block->getDamage() & 0x07) === $this->meta){
|
||||
$this->getLevel()->setBlock($block, Block::get($this->doubleId, $this->meta), true);
|
||||
$this->getLevel()->setBlock($block, BlockFactory::get($this->doubleId, $this->meta), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}else{
|
||||
if($fy > 0.5){
|
||||
if($facePos->y > 0.5){
|
||||
$this->meta |= 0x08;
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ class WoodenStairs extends Stair{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getResistance() : float{
|
||||
public function getBlastResistance() : float{
|
||||
return 15;
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\command\defaults;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\utils\InvalidCommandSyntaxException;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
@ -183,7 +183,7 @@ class ParticleCommand extends VanillaCommand{
|
||||
break;
|
||||
case "terrain":
|
||||
if($data !== null and $data !== 0){
|
||||
return new TerrainParticle($pos, Block::get($data));
|
||||
return new TerrainParticle($pos, BlockFactory::get($data));
|
||||
}
|
||||
break;
|
||||
case "heart":
|
||||
@ -211,7 +211,7 @@ class ParticleCommand extends VanillaCommand{
|
||||
}elseif(strpos($name, "blockcrack_") === 0){
|
||||
$d = explode("_", $name);
|
||||
if(count($d) === 2){
|
||||
return new TerrainParticle($pos, Block::get($d[1] & 0xff, $d[1] >> 12));
|
||||
return new TerrainParticle($pos, BlockFactory::get($d[1] & 0xff, $d[1] >> 12));
|
||||
}
|
||||
}elseif(strpos($name, "blockdust_") === 0){
|
||||
$d = explode("_", $name);
|
||||
|
@ -62,14 +62,12 @@ class Arrow extends Projectile{
|
||||
}
|
||||
}
|
||||
|
||||
public function onUpdate(int $currentTick) : bool{
|
||||
public function entityBaseTick(int $tickDiff = 1) : bool{
|
||||
if($this->closed){
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->timings->startTiming();
|
||||
|
||||
$hasUpdate = parent::onUpdate($currentTick);
|
||||
$hasUpdate = parent::entityBaseTick($tickDiff);
|
||||
|
||||
if($this->onGround or $this->hadCollision){
|
||||
$this->setCritical(false);
|
||||
@ -80,8 +78,6 @@ class Arrow extends Projectile{
|
||||
$hasUpdate = true;
|
||||
}
|
||||
|
||||
$this->timings->stopTiming();
|
||||
|
||||
return $hasUpdate;
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\entity;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\block\Water;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\event\entity\EntityDespawnEvent;
|
||||
@ -64,6 +65,8 @@ use pocketmine\Server;
|
||||
|
||||
abstract class Entity extends Location implements Metadatable{
|
||||
|
||||
const MOTION_THRESHOLD = 0.00001;
|
||||
|
||||
const NETWORK_ID = -1;
|
||||
|
||||
const DATA_TYPE_BYTE = 0;
|
||||
@ -273,6 +276,8 @@ abstract class Entity extends Location implements Metadatable{
|
||||
public $lastMotionY;
|
||||
/** @var float */
|
||||
public $lastMotionZ;
|
||||
/** @var bool */
|
||||
protected $forceMovementUpdate = false;
|
||||
|
||||
/** @var float */
|
||||
public $lastYaw;
|
||||
@ -1018,13 +1023,13 @@ abstract class Entity extends Location implements Metadatable{
|
||||
$diffY = $y - $j;
|
||||
$diffZ = $z - $k;
|
||||
|
||||
if(Block::$solid[$this->level->getBlockIdAt($i, $j, $k)]){
|
||||
$flag = !Block::$solid[$this->level->getBlockIdAt($i - 1, $j, $k)];
|
||||
$flag1 = !Block::$solid[$this->level->getBlockIdAt($i + 1, $j, $k)];
|
||||
$flag2 = !Block::$solid[$this->level->getBlockIdAt($i, $j - 1, $k)];
|
||||
$flag3 = !Block::$solid[$this->level->getBlockIdAt($i, $j + 1, $k)];
|
||||
$flag4 = !Block::$solid[$this->level->getBlockIdAt($i, $j, $k - 1)];
|
||||
$flag5 = !Block::$solid[$this->level->getBlockIdAt($i, $j, $k + 1)];
|
||||
if(BlockFactory::$solid[$this->level->getBlockIdAt($i, $j, $k)]){
|
||||
$flag = !BlockFactory::$solid[$this->level->getBlockIdAt($i - 1, $j, $k)];
|
||||
$flag1 = !BlockFactory::$solid[$this->level->getBlockIdAt($i + 1, $j, $k)];
|
||||
$flag2 = !BlockFactory::$solid[$this->level->getBlockIdAt($i, $j - 1, $k)];
|
||||
$flag3 = !BlockFactory::$solid[$this->level->getBlockIdAt($i, $j + 1, $k)];
|
||||
$flag4 = !BlockFactory::$solid[$this->level->getBlockIdAt($i, $j, $k - 1)];
|
||||
$flag5 = !BlockFactory::$solid[$this->level->getBlockIdAt($i, $j, $k + 1)];
|
||||
|
||||
$direction = -1;
|
||||
$limit = 9999;
|
||||
@ -1227,6 +1232,35 @@ abstract class Entity extends Location implements Metadatable{
|
||||
$this->level->addChunkPacket($this->chunk->getX(), $this->chunk->getZ(), $pk);
|
||||
}
|
||||
|
||||
protected function applyDragBeforeGravity() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function applyGravity(){
|
||||
$this->motionY -= $this->gravity;
|
||||
}
|
||||
|
||||
protected function tryChangeMovement(){
|
||||
$friction = 1 - $this->drag;
|
||||
|
||||
if(!$this->onGround){
|
||||
if($this->applyDragBeforeGravity()){
|
||||
$this->motionY *= $friction;
|
||||
}
|
||||
|
||||
$this->applyGravity();
|
||||
|
||||
if(!$this->applyDragBeforeGravity()){
|
||||
$this->motionY *= $friction;
|
||||
}
|
||||
}else{
|
||||
$friction = $this->level->getBlock($this->floor()->subtract(0, 1, 0))->getFrictionFactor();
|
||||
}
|
||||
|
||||
$this->motionX *= $friction;
|
||||
$this->motionZ *= $friction;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Vector3
|
||||
*/
|
||||
@ -1269,16 +1303,34 @@ abstract class Entity extends Location implements Metadatable{
|
||||
|
||||
$this->timings->startTiming();
|
||||
|
||||
if($this->hasMovementUpdate()){
|
||||
$this->tryChangeMovement();
|
||||
$this->move($this->motionX, $this->motionY, $this->motionZ);
|
||||
|
||||
if(abs($this->motionX) <= self::MOTION_THRESHOLD){
|
||||
$this->motionX = 0;
|
||||
}
|
||||
if(abs($this->motionY) <= self::MOTION_THRESHOLD){
|
||||
$this->motionY = 0;
|
||||
}
|
||||
if(abs($this->motionZ) <= self::MOTION_THRESHOLD){
|
||||
$this->motionZ = 0;
|
||||
}
|
||||
|
||||
$this->updateMovement();
|
||||
$this->forceMovementUpdate = false;
|
||||
}
|
||||
|
||||
Timings::$timerEntityBaseTick->startTiming();
|
||||
$hasUpdate = $this->entityBaseTick($tickDiff);
|
||||
Timings::$timerEntityBaseTick->stopTiming();
|
||||
|
||||
$this->updateMovement();
|
||||
|
||||
|
||||
$this->timings->stopTiming();
|
||||
|
||||
//if($this->isStatic())
|
||||
return $hasUpdate;
|
||||
return ($hasUpdate or $this->hasMovementUpdate());
|
||||
//return !($this instanceof Player);
|
||||
}
|
||||
|
||||
@ -1286,6 +1338,31 @@ abstract class Entity extends Location implements Metadatable{
|
||||
$this->level->updateEntities[$this->id] = $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flags the entity as needing a movement update on the next tick. Setting this forces a movement update even if the
|
||||
* entity's motion is zero. Used to trigger movement updates when blocks change near entities.
|
||||
*
|
||||
* @param bool $value
|
||||
*/
|
||||
final public function setForceMovementUpdate(bool $value = true){
|
||||
$this->forceMovementUpdate = $value;
|
||||
$this->onGround = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the entity needs a movement update on the next tick.
|
||||
* @return bool
|
||||
*/
|
||||
final public function hasMovementUpdate() : bool{
|
||||
return (
|
||||
$this->forceMovementUpdate or
|
||||
abs($this->motionX) > self::MOTION_THRESHOLD or
|
||||
abs($this->motionY) > self::MOTION_THRESHOLD or
|
||||
abs($this->motionZ) > self::MOTION_THRESHOLD or
|
||||
!$this->onGround
|
||||
);
|
||||
}
|
||||
|
||||
public function isOnFire() : bool{
|
||||
return $this->fireTicks > 0;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\entity;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\event\entity\EntityBlockChangeEvent;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\item\Item as ItemItem;
|
||||
@ -80,34 +80,14 @@ class FallingSand extends Entity{
|
||||
}
|
||||
}
|
||||
|
||||
public function onUpdate(int $currentTick) : bool{
|
||||
|
||||
public function entityBaseTick(int $tickDiff = 1) : bool{
|
||||
if($this->closed){
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->timings->startTiming();
|
||||
|
||||
$tickDiff = $currentTick - $this->lastUpdate;
|
||||
if($tickDiff <= 0 and !$this->justCreated){
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->lastUpdate = $currentTick;
|
||||
|
||||
$hasUpdate = $this->entityBaseTick($tickDiff);
|
||||
$hasUpdate = parent::entityBaseTick($tickDiff);
|
||||
|
||||
if($this->isAlive()){
|
||||
$this->motionY -= $this->gravity;
|
||||
|
||||
$this->move($this->motionX, $this->motionY, $this->motionZ);
|
||||
|
||||
$friction = 1 - $this->drag;
|
||||
|
||||
$this->motionX *= $friction;
|
||||
$this->motionY *= 1 - $this->drag;
|
||||
$this->motionZ *= $friction;
|
||||
|
||||
$pos = (new Vector3($this->x - 0.5, $this->y, $this->z - 0.5))->floor();
|
||||
|
||||
if($this->onGround){
|
||||
@ -117,18 +97,16 @@ class FallingSand extends Entity{
|
||||
//FIXME: anvils are supposed to destroy torches
|
||||
$this->getLevel()->dropItem($this, ItemItem::get($this->getBlock(), $this->getDamage(), 1));
|
||||
}else{
|
||||
$this->server->getPluginManager()->callEvent($ev = new EntityBlockChangeEvent($this, $block, Block::get($this->getBlock(), $this->getDamage())));
|
||||
$this->server->getPluginManager()->callEvent($ev = new EntityBlockChangeEvent($this, $block, BlockFactory::get($this->getBlock(), $this->getDamage())));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($pos, $ev->getTo(), true);
|
||||
}
|
||||
}
|
||||
$hasUpdate = true;
|
||||
}
|
||||
|
||||
$this->updateMovement();
|
||||
}
|
||||
|
||||
return $hasUpdate or !$this->onGround or abs($this->motionX) > 0.00001 or abs($this->motionY) > 0.00001 or abs($this->motionZ) > 0.00001;
|
||||
return $hasUpdate;
|
||||
}
|
||||
|
||||
public function getBlock(){
|
||||
|
@ -98,24 +98,14 @@ class Item extends Entity{
|
||||
}
|
||||
}
|
||||
|
||||
public function onUpdate(int $currentTick) : bool{
|
||||
public function entityBaseTick(int $tickDiff = 1) : bool{
|
||||
if($this->closed){
|
||||
return false;
|
||||
}
|
||||
|
||||
$tickDiff = $currentTick - $this->lastUpdate;
|
||||
if($tickDiff <= 0 and !$this->justCreated){
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->lastUpdate = $currentTick;
|
||||
|
||||
$this->timings->startTiming();
|
||||
|
||||
$hasUpdate = $this->entityBaseTick($tickDiff);
|
||||
$hasUpdate = parent::entityBaseTick($tickDiff);
|
||||
|
||||
if($this->isAlive()){
|
||||
|
||||
if($this->pickupDelay > 0 and $this->pickupDelay < 32767){ //Infinite delay
|
||||
$this->pickupDelay -= $tickDiff;
|
||||
if($this->pickupDelay < 0){
|
||||
@ -123,30 +113,6 @@ class Item extends Entity{
|
||||
}
|
||||
}
|
||||
|
||||
$this->motionY -= $this->gravity;
|
||||
|
||||
if($this->checkObstruction($this->x, $this->y, $this->z)){
|
||||
$hasUpdate = true;
|
||||
}
|
||||
|
||||
$this->move($this->motionX, $this->motionY, $this->motionZ);
|
||||
|
||||
$friction = 1 - $this->drag;
|
||||
|
||||
if($this->onGround and (abs($this->motionX) > 0.00001 or abs($this->motionZ) > 0.00001)){
|
||||
$friction = $this->getLevel()->getBlock($this->temporalVector->setComponents((int) floor($this->x), (int) floor($this->y - 1), (int) floor($this->z) - 1))->getFrictionFactor() * $friction;
|
||||
}
|
||||
|
||||
$this->motionX *= $friction;
|
||||
$this->motionY *= 1 - $this->drag;
|
||||
$this->motionZ *= $friction;
|
||||
|
||||
if($this->onGround){
|
||||
$this->motionY *= -0.5;
|
||||
}
|
||||
|
||||
$this->updateMovement();
|
||||
|
||||
if($this->age > 6000){
|
||||
$this->server->getPluginManager()->callEvent($ev = new ItemDespawnEvent($this));
|
||||
if($ev->isCancelled()){
|
||||
@ -159,9 +125,16 @@ class Item extends Entity{
|
||||
|
||||
}
|
||||
|
||||
$this->timings->stopTiming();
|
||||
return $hasUpdate;
|
||||
}
|
||||
|
||||
return $hasUpdate or !$this->onGround or abs($this->motionX) > 0.00001 or abs($this->motionY) > 0.00001 or abs($this->motionZ) > 0.00001;
|
||||
protected function tryChangeMovement(){
|
||||
$this->checkObstruction($this->x, $this->y, $this->z);
|
||||
parent::tryChangeMovement();
|
||||
}
|
||||
|
||||
protected function applyDragBeforeGravity() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function saveNBT(){
|
||||
|
@ -79,58 +79,27 @@ class PrimedTNT extends Entity implements Explosive{
|
||||
$this->namedtag->Fuse = new ByteTag("Fuse", $this->fuse);
|
||||
}
|
||||
|
||||
public function onUpdate(int $currentTick) : bool{
|
||||
|
||||
public function entityBaseTick(int $tickDiff = 1) : bool{
|
||||
if($this->closed){
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->timings->startTiming();
|
||||
|
||||
$tickDiff = $currentTick - $this->lastUpdate;
|
||||
if($tickDiff <= 0 and !$this->justCreated){
|
||||
return true;
|
||||
}
|
||||
$hasUpdate = parent::entityBaseTick($tickDiff);
|
||||
|
||||
if($this->fuse % 5 === 0){ //don't spam it every tick, it's not necessary
|
||||
$this->setDataProperty(self::DATA_FUSE_LENGTH, self::DATA_TYPE_INT, $this->fuse);
|
||||
}
|
||||
|
||||
$this->lastUpdate = $currentTick;
|
||||
|
||||
$hasUpdate = $this->entityBaseTick($tickDiff);
|
||||
|
||||
if($this->isAlive()){
|
||||
|
||||
$this->motionY -= $this->gravity;
|
||||
|
||||
$this->move($this->motionX, $this->motionY, $this->motionZ);
|
||||
|
||||
$friction = 1 - $this->drag;
|
||||
|
||||
$this->motionX *= $friction;
|
||||
$this->motionY *= $friction;
|
||||
$this->motionZ *= $friction;
|
||||
|
||||
$this->updateMovement();
|
||||
|
||||
if($this->onGround){
|
||||
$this->motionY *= -0.5;
|
||||
$this->motionX *= 0.7;
|
||||
$this->motionZ *= 0.7;
|
||||
}
|
||||
|
||||
$this->fuse -= $tickDiff;
|
||||
|
||||
if($this->fuse <= 0){
|
||||
$this->kill();
|
||||
$this->explode();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return $hasUpdate or $this->fuse >= 0 or abs($this->motionX) > 0.00001 or abs($this->motionY) > 0.00001 or abs($this->motionZ) > 0.00001;
|
||||
return $hasUpdate or $this->fuse >= 0;
|
||||
}
|
||||
|
||||
public function explode(){
|
||||
|
@ -108,28 +108,20 @@ abstract class Projectile extends Entity{
|
||||
$this->namedtag->Age = new ShortTag("Age", $this->age);
|
||||
}
|
||||
|
||||
public function onUpdate(int $currentTick) : bool{
|
||||
protected function applyDragBeforeGravity() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function entityBaseTick(int $tickDiff = 1) : bool{
|
||||
if($this->closed){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$tickDiff = $currentTick - $this->lastUpdate;
|
||||
if($tickDiff <= 0 and !$this->justCreated){
|
||||
return true;
|
||||
}
|
||||
$this->lastUpdate = $currentTick;
|
||||
|
||||
$hasUpdate = $this->entityBaseTick($tickDiff);
|
||||
$hasUpdate = parent::entityBaseTick($tickDiff);
|
||||
|
||||
if($this->isAlive()){
|
||||
|
||||
$movingObjectPosition = null;
|
||||
|
||||
if(!$this->isCollided){
|
||||
$this->motionY -= $this->gravity;
|
||||
}
|
||||
|
||||
$moveVector = new Vector3($this->x + $this->motionX, $this->y + $this->motionY, $this->z + $this->motionZ);
|
||||
|
||||
$list = $this->getLevel()->getCollidingEntities($this->boundingBox->addCoord($this->motionX, $this->motionY, $this->motionZ)->expand(1, 1, 1), $this);
|
||||
@ -170,8 +162,6 @@ abstract class Projectile extends Entity{
|
||||
}
|
||||
}
|
||||
|
||||
$this->move($this->motionX, $this->motionY, $this->motionZ);
|
||||
|
||||
if($this->isCollided and !$this->hadCollision){ //Collided with a block
|
||||
$this->hadCollision = true;
|
||||
|
||||
@ -181,20 +171,16 @@ abstract class Projectile extends Entity{
|
||||
|
||||
$this->server->getPluginManager()->callEvent(new ProjectileHitEvent($this));
|
||||
return false;
|
||||
}elseif(!$this->isCollided and $this->hadCollision){ //Collided with block, but block later removed
|
||||
//This currently doesn't work because the arrow's motion is all zeros when it's hit a block, so move() doesn't do any collision checks.
|
||||
//TODO: fix this
|
||||
}elseif(!$this->isCollided and $this->hadCollision){ //Previously collided with block, but block later removed
|
||||
$this->hadCollision = false;
|
||||
}
|
||||
|
||||
if(!$this->hadCollision or abs($this->motionX) > 0.00001 or abs($this->motionY) > 0.00001 or abs($this->motionZ) > 0.00001){
|
||||
if(!$this->hadCollision or abs($this->motionX) > self::MOTION_THRESHOLD or abs($this->motionY) > self::MOTION_THRESHOLD or abs($this->motionZ) > self::MOTION_THRESHOLD){
|
||||
$f = sqrt(($this->motionX ** 2) + ($this->motionZ ** 2));
|
||||
$this->yaw = (atan2($this->motionX, $this->motionZ) * 180 / M_PI);
|
||||
$this->pitch = (atan2($this->motionY, $f) * 180 / M_PI);
|
||||
$hasUpdate = true;
|
||||
}
|
||||
|
||||
$this->updateMovement();
|
||||
}
|
||||
|
||||
return $hasUpdate;
|
||||
|
@ -42,22 +42,18 @@ class Snowball extends Projectile{
|
||||
parent::__construct($level, $nbt, $shootingEntity);
|
||||
}
|
||||
|
||||
public function onUpdate(int $currentTick) : bool{
|
||||
public function entityBaseTick(int $tickDiff = 1) : bool{
|
||||
if($this->closed){
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->timings->startTiming();
|
||||
|
||||
$hasUpdate = parent::onUpdate($currentTick);
|
||||
$hasUpdate = parent::entityBaseTick($tickDiff);
|
||||
|
||||
if($this->age > 1200 or $this->isCollided){
|
||||
$this->kill();
|
||||
$hasUpdate = true;
|
||||
}
|
||||
|
||||
$this->timings->stopTiming();
|
||||
|
||||
return $hasUpdate;
|
||||
}
|
||||
|
||||
|
@ -78,21 +78,19 @@ class Squid extends WaterAnimal{
|
||||
}
|
||||
|
||||
|
||||
public function onUpdate(int $currentTick) : bool{
|
||||
public function entityBaseTick(int $tickDiff = 1) : bool{
|
||||
if($this->closed !== false){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(++$this->switchDirectionTicker === 100){
|
||||
if(++$this->switchDirectionTicker === 100 or $this->isCollided){
|
||||
$this->switchDirectionTicker = 0;
|
||||
if(mt_rand(0, 100) < 50){
|
||||
$this->swimDirection = null;
|
||||
}
|
||||
}
|
||||
|
||||
$this->timings->startTiming();
|
||||
|
||||
$hasUpdate = parent::onUpdate($currentTick);
|
||||
$hasUpdate = parent::entityBaseTick($tickDiff);
|
||||
|
||||
if($this->isAlive()){
|
||||
|
||||
@ -102,7 +100,6 @@ class Squid extends WaterAnimal{
|
||||
|
||||
$inWater = $this->isInsideOfWater();
|
||||
if(!$inWater){
|
||||
$this->motionY -= $this->gravity;
|
||||
$this->swimDirection = null;
|
||||
}elseif($this->swimDirection !== null){
|
||||
if($this->motionX ** 2 + $this->motionY ** 2 + $this->motionZ ** 2 <= $this->swimDirection->lengthSquared()){
|
||||
@ -115,34 +112,18 @@ class Squid extends WaterAnimal{
|
||||
$this->swimSpeed = mt_rand(50, 100) / 2000;
|
||||
}
|
||||
|
||||
$expectedPos = new Vector3($this->x + $this->motionX, $this->y + $this->motionY, $this->z + $this->motionZ);
|
||||
|
||||
$this->move($this->motionX, $this->motionY, $this->motionZ);
|
||||
|
||||
if($expectedPos->distanceSquared($this) > 0){
|
||||
$this->swimDirection = $this->generateRandomDirection();
|
||||
$this->swimSpeed = mt_rand(50, 100) / 2000;
|
||||
}
|
||||
|
||||
$friction = 1 - $this->drag;
|
||||
|
||||
$this->motionX *= $friction;
|
||||
$this->motionY *= 1 - $this->drag;
|
||||
$this->motionZ *= $friction;
|
||||
|
||||
$f = sqrt(($this->motionX ** 2) + ($this->motionZ ** 2));
|
||||
$this->yaw = (-atan2($this->motionX, $this->motionZ) * 180 / M_PI);
|
||||
$this->pitch = (-atan2($f, $this->motionY) * 180 / M_PI);
|
||||
|
||||
if($this->onGround){
|
||||
$this->motionY *= -0.5;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$this->timings->stopTiming();
|
||||
return $hasUpdate;
|
||||
}
|
||||
|
||||
return $hasUpdate or !$this->onGround or abs($this->motionX) > 0.00001 or abs($this->motionY) > 0.00001 or abs($this->motionZ) > 0.00001;
|
||||
protected function applyGravity(){
|
||||
if(!$this->isInsideOfWater()){
|
||||
parent::applyGravity();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\event\player;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\event\Cancellable;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Position;
|
||||
@ -63,7 +64,7 @@ class PlayerInteractEvent extends PlayerEvent implements Cancellable{
|
||||
$this->touchVector = new Vector3(0, 0, 0);
|
||||
}else{
|
||||
$this->touchVector = $block;
|
||||
$this->blockTouched = Block::get(0, 0, new Position(0, 0, 0, $player->level));
|
||||
$this->blockTouched = BlockFactory::get(0, 0, new Position(0, 0, 0, $player->level));
|
||||
}
|
||||
$this->player = $player;
|
||||
$this->item = $item;
|
||||
|
@ -24,10 +24,11 @@ declare(strict_types=1);
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
|
||||
class Bed extends Item{
|
||||
public function __construct($meta = 0, $count = 1){
|
||||
$this->block = Block::get(Block::BED_BLOCK);
|
||||
$this->block = BlockFactory::get(Block::BED_BLOCK);
|
||||
parent::__construct(self::BED, $meta, $count, "Bed");
|
||||
}
|
||||
|
||||
|
@ -24,10 +24,11 @@ declare(strict_types=1);
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
|
||||
class BeetrootSeeds extends Item{
|
||||
public function __construct($meta = 0, $count = 1){
|
||||
$this->block = Block::get(Block::BEETROOT_BLOCK);
|
||||
$this->block = BlockFactory::get(Block::BEETROOT_BLOCK);
|
||||
parent::__construct(self::BEETROOT_SEEDS, $meta, $count, "Beetroot Seeds");
|
||||
}
|
||||
}
|
@ -25,9 +25,11 @@ namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Air;
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\block\Liquid;
|
||||
use pocketmine\event\player\PlayerBucketFillEvent;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Bucket extends Item{
|
||||
@ -47,8 +49,8 @@ class Bucket extends Item{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function onActivate(Level $level, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
$targetBlock = Block::get($this->meta);
|
||||
public function onActivate(Level $level, Player $player, Block $block, Block $target, int $face, Vector3 $facePos) : bool{
|
||||
$targetBlock = BlockFactory::get($this->meta);
|
||||
|
||||
if($targetBlock instanceof Air){
|
||||
if($target instanceof Liquid and $target->getDamage() === 0){
|
||||
@ -56,7 +58,7 @@ class Bucket extends Item{
|
||||
$result->setDamage($target->getId());
|
||||
$player->getServer()->getPluginManager()->callEvent($ev = new PlayerBucketFillEvent($player, $block, $face, $this, $result));
|
||||
if(!$ev->isCancelled()){
|
||||
$player->getLevel()->setBlock($target, Block::get(Block::AIR), true, true);
|
||||
$player->getLevel()->setBlock($target, BlockFactory::get(Block::AIR), true, true);
|
||||
if($player->isSurvival()){
|
||||
$player->getInventory()->setItemInHand($ev->getItem());
|
||||
}
|
||||
|
@ -24,10 +24,11 @@ declare(strict_types=1);
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
|
||||
class Cake extends Item{
|
||||
public function __construct($meta = 0, $count = 1){
|
||||
$this->block = Block::get(Block::CAKE_BLOCK);
|
||||
$this->block = BlockFactory::get(Block::CAKE_BLOCK);
|
||||
parent::__construct(self::CAKE, $meta, $count, "Cake");
|
||||
}
|
||||
|
||||
|
@ -24,10 +24,11 @@ declare(strict_types=1);
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
|
||||
class Carrot extends Food{
|
||||
public function __construct($meta = 0, $count = 1){
|
||||
$this->block = Block::get(Block::CARROT_BLOCK);
|
||||
$this->block = BlockFactory::get(Block::CARROT_BLOCK);
|
||||
parent::__construct(self::CARROT, $meta, $count, "Carrot");
|
||||
}
|
||||
|
||||
|
@ -24,9 +24,11 @@ declare(strict_types=1);
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\block\Fire;
|
||||
use pocketmine\block\Solid;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class FlintSteel extends Tool{
|
||||
@ -34,9 +36,9 @@ class FlintSteel extends Tool{
|
||||
parent::__construct(self::FLINT_STEEL, $meta, $count, "Flint and Steel");
|
||||
}
|
||||
|
||||
public function onActivate(Level $level, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
public function onActivate(Level $level, Player $player, Block $block, Block $target, int $face, Vector3 $facePos) : bool{
|
||||
if($block->getId() === self::AIR and ($target instanceof Solid)){
|
||||
$level->setBlock($block, Block::get(Block::FIRE), true);
|
||||
$level->setBlock($block, BlockFactory::get(Block::FIRE), true);
|
||||
if(($player->gamemode & 0x01) === 0 and $this->useOn($block)){
|
||||
if($this->getDamage() >= $this->getMaxDurability()){
|
||||
$player->getInventory()->setItemInHand(new Item(Item::AIR, 0, 0));
|
||||
|
@ -24,10 +24,11 @@ declare(strict_types=1);
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
|
||||
class FlowerPot extends Item{
|
||||
public function __construct($meta = 0, $count = 1){
|
||||
$this->block = Block::get(Block::FLOWER_POT_BLOCK);
|
||||
$this->block = BlockFactory::get(Block::FLOWER_POT_BLOCK);
|
||||
parent::__construct(self::FLOWER_POT, $meta, $count, "Flower Pot");
|
||||
}
|
||||
}
|
@ -24,10 +24,11 @@ declare(strict_types=1);
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
|
||||
class IronDoor extends Item{
|
||||
public function __construct($meta = 0, $count = 1){
|
||||
$this->block = Block::get(Block::IRON_DOOR_BLOCK);
|
||||
$this->block = BlockFactory::get(Block::IRON_DOOR_BLOCK);
|
||||
parent::__construct(self::IRON_DOOR, $meta, $count, "Iron Door");
|
||||
}
|
||||
|
||||
|
@ -27,9 +27,11 @@ declare(strict_types=1);
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\item\enchantment\Enchantment;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\NBT;
|
||||
use pocketmine\nbt\tag\ByteTag;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
@ -327,7 +329,7 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
public static function get(int $id, int $meta = 0, int $count = 1, $tags = "") : Item{
|
||||
try{
|
||||
if($id < 256){
|
||||
return (new ItemBlock(Block::get($id, $meta), $meta, $count))->setCompoundTag($tags);
|
||||
return (new ItemBlock(BlockFactory::get($id, $meta), $meta, $count))->setCompoundTag($tags);
|
||||
}else{
|
||||
$class = self::$list[$id];
|
||||
if($class === null){
|
||||
@ -387,8 +389,8 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
$this->meta = $meta !== -1 ? $meta & 0xffff : -1;
|
||||
$this->count = $count;
|
||||
$this->name = $name;
|
||||
if(!isset($this->block) and $this->id <= 0xff and isset(Block::$list[$this->id])){
|
||||
$this->block = Block::get($this->id, $this->meta);
|
||||
if(!isset($this->block) and $this->id <= 0xff and isset(BlockFactory::$list[$this->id])){
|
||||
$this->block = BlockFactory::get($this->id, $this->meta);
|
||||
$this->name = $this->block->getName();
|
||||
}
|
||||
}
|
||||
@ -877,7 +879,7 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
if($this->block instanceof Block){
|
||||
return clone $this->block;
|
||||
}else{
|
||||
return Block::get(self::AIR);
|
||||
return BlockFactory::get(self::AIR);
|
||||
}
|
||||
}
|
||||
|
||||
@ -982,18 +984,16 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
/**
|
||||
* Called when a player uses this item on a block.
|
||||
*
|
||||
* @param Level $level
|
||||
* @param Player $player
|
||||
* @param Block $block
|
||||
* @param Block $target
|
||||
* @param int $face
|
||||
* @param float $fx
|
||||
* @param float $fy
|
||||
* @param float $fz
|
||||
* @param Level $level
|
||||
* @param Player $player
|
||||
* @param Block $block
|
||||
* @param Block $target
|
||||
* @param int $face
|
||||
* @param Vector3 $facePos
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function onActivate(Level $level, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
public function onActivate(Level $level, Player $player, Block $block, Block $target, int $face, Vector3 $facePos) : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -24,10 +24,11 @@ declare(strict_types=1);
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
|
||||
class ItemFrame extends Item{
|
||||
public function __construct($meta = 0, $count = 1){
|
||||
$this->block = Block::get(Block::ITEM_FRAME_BLOCK);
|
||||
$this->block = BlockFactory::get(Block::ITEM_FRAME_BLOCK);
|
||||
parent::__construct(self::ITEM_FRAME, $meta, $count, "Item Frame");
|
||||
}
|
||||
}
|
@ -24,10 +24,11 @@ declare(strict_types=1);
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
|
||||
class MelonSeeds extends Item{
|
||||
public function __construct($meta = 0, $count = 1){
|
||||
$this->block = Block::get(Block::MELON_STEM);
|
||||
$this->block = BlockFactory::get(Block::MELON_STEM);
|
||||
parent::__construct(self::MELON_SEEDS, $meta, $count, "Melon Seeds");
|
||||
}
|
||||
}
|
@ -24,10 +24,11 @@ declare(strict_types=1);
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
|
||||
class NetherWart extends Item{
|
||||
public function __construct($meta = 0, $count = 1){
|
||||
$this->block = Block::get(Block::NETHER_WART_PLANT);
|
||||
$this->block = BlockFactory::get(Block::NETHER_WART_PLANT);
|
||||
parent::__construct(self::NETHER_WART, $meta, $count, "Nether Wart");
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Painting extends Item{
|
||||
@ -32,7 +33,7 @@ class Painting extends Item{
|
||||
parent::__construct(self::PAINTING, $meta, $count, "Painting");
|
||||
}
|
||||
|
||||
public function onActivate(Level $level, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
public function onActivate(Level $level, Player $player, Block $block, Block $target, int $face, Vector3 $facePos) : bool{
|
||||
if($target->isTransparent() === false and $face > 1 and $block->isSolid() === false){
|
||||
$faces = [
|
||||
2 => 1,
|
||||
|
@ -24,10 +24,11 @@ declare(strict_types=1);
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
|
||||
class Potato extends Food{
|
||||
public function __construct($meta = 0, $count = 1){
|
||||
$this->block = Block::get(Block::POTATO_BLOCK);
|
||||
$this->block = BlockFactory::get(Block::POTATO_BLOCK);
|
||||
parent::__construct(self::POTATO, $meta, $count, "Potato");
|
||||
}
|
||||
|
||||
|
@ -24,10 +24,11 @@ declare(strict_types=1);
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
|
||||
class PumpkinSeeds extends Item{
|
||||
public function __construct($meta = 0, $count = 1){
|
||||
$this->block = Block::get(Block::PUMPKIN_STEM);
|
||||
$this->block = BlockFactory::get(Block::PUMPKIN_STEM);
|
||||
parent::__construct(self::PUMPKIN_SEEDS, $meta, $count, "Pumpkin Seeds");
|
||||
}
|
||||
}
|
@ -24,10 +24,11 @@ declare(strict_types=1);
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
|
||||
class Sign extends Item{
|
||||
public function __construct($meta = 0, $count = 1){
|
||||
$this->block = Block::get(Block::SIGN_POST);
|
||||
$this->block = BlockFactory::get(Block::SIGN_POST);
|
||||
parent::__construct(self::SIGN, $meta, $count, "Sign");
|
||||
}
|
||||
|
||||
|
@ -24,10 +24,11 @@ declare(strict_types=1);
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
|
||||
class Skull extends Item{
|
||||
public function __construct($meta = 0, $count = 1){
|
||||
$this->block = Block::get(Block::SKULL_BLOCK);
|
||||
$this->block = BlockFactory::get(Block::SKULL_BLOCK);
|
||||
parent::__construct(self::SKULL, $meta, $count, "Mob Head");
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ namespace pocketmine\item;
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\DoubleTag;
|
||||
use pocketmine\nbt\tag\FloatTag;
|
||||
@ -38,7 +39,7 @@ class SpawnEgg extends Item{
|
||||
parent::__construct(self::SPAWN_EGG, $meta, $count, "Spawn Egg");
|
||||
}
|
||||
|
||||
public function onActivate(Level $level, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
public function onActivate(Level $level, Player $player, Block $block, Block $target, int $face, Vector3 $facePos) : bool{
|
||||
$nbt = new CompoundTag("", [
|
||||
new ListTag("Pos", [
|
||||
new DoubleTag("", $block->getX() + 0.5),
|
||||
|
@ -24,10 +24,11 @@ declare(strict_types=1);
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
|
||||
class Sugarcane extends Item{
|
||||
public function __construct($meta = 0, $count = 1){
|
||||
$this->block = Block::get(Block::SUGARCANE_BLOCK);
|
||||
$this->block = BlockFactory::get(Block::SUGARCANE_BLOCK);
|
||||
parent::__construct(self::SUGARCANE, $meta, $count, "Sugar Cane");
|
||||
}
|
||||
}
|
@ -24,10 +24,11 @@ declare(strict_types=1);
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
|
||||
class WheatSeeds extends Item{
|
||||
public function __construct($meta = 0, $count = 1){
|
||||
$this->block = Block::get(Block::WHEAT_BLOCK);
|
||||
$this->block = BlockFactory::get(Block::WHEAT_BLOCK);
|
||||
parent::__construct(self::WHEAT_SEEDS, $meta, $count, "Wheat Seeds");
|
||||
}
|
||||
}
|
@ -24,10 +24,11 @@ declare(strict_types=1);
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
|
||||
class WoodenDoor extends Item{
|
||||
public function __construct($meta = 0, $count = 1){
|
||||
$this->block = Block::get(Block::WOODEN_DOOR_BLOCK);
|
||||
$this->block = BlockFactory::get(Block::WOODEN_DOOR_BLOCK);
|
||||
parent::__construct(self::WOODEN_DOOR, $meta, $count, "Wooden Door");
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\level;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\block\TNT;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\event\block\BlockUpdateEvent;
|
||||
@ -32,6 +33,7 @@ use pocketmine\event\entity\EntityDamageByEntityEvent;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\event\entity\EntityExplodeEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\format\SubChunkInterface;
|
||||
use pocketmine\level\particle\HugeExplodeSeedParticle;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Math;
|
||||
@ -69,7 +71,14 @@ class Explosion{
|
||||
}
|
||||
|
||||
$vector = new Vector3(0, 0, 0);
|
||||
$vBlock = new Vector3(0, 0, 0);
|
||||
$vBlock = new Position(0, 0, 0, $this->level);
|
||||
|
||||
$currentX = ((int) $this->source->x) >> 4;
|
||||
$currentZ = ((int) $this->source->z) >> 4;
|
||||
$currentChunk = $this->level->getChunk($currentX, $currentZ, true);
|
||||
|
||||
$currentSubY = ((int) $this->source->y) >> 4;
|
||||
$currentSubChunk = $currentChunk->getSubChunk($currentSubY);
|
||||
|
||||
$mRays = (int) ($this->rays - 1);
|
||||
for($i = 0; $i < $this->rays; ++$i){
|
||||
@ -89,19 +98,37 @@ class Explosion{
|
||||
$vBlock->x = $pointerX >= $x ? $x : $x - 1;
|
||||
$vBlock->y = $pointerY >= $y ? $y : $y - 1;
|
||||
$vBlock->z = $pointerZ >= $z ? $z : $z - 1;
|
||||
if(!$this->level->isInWorld($vBlock->x, $vBlock->y, $vBlock->z)){
|
||||
break;
|
||||
}
|
||||
$block = $this->level->getBlock($vBlock);
|
||||
|
||||
if($block->getId() !== 0){
|
||||
$blastForce -= ($block->getResistance() / 5 + 0.3) * $this->stepLen;
|
||||
|
||||
if(($vBlock->x >> 4) !== $currentX or ($vBlock->z >> 4) !== $currentZ){
|
||||
$currentX = $vBlock->x >> 4;
|
||||
$currentZ = $vBlock->z >> 4;
|
||||
|
||||
$currentChunk = $this->level->getChunk($currentX, $currentZ);
|
||||
if($currentChunk === null){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(($vBlock->y >> 4) !== $currentSubY){
|
||||
$currentSubY = $vBlock->y >> 4;
|
||||
$currentSubChunk = $currentChunk->getSubChunk($currentSubY);
|
||||
if($currentSubChunk === null){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$blockId = $currentSubChunk->getBlockId($vBlock->x & 0x0f, $vBlock->y & 0x0f, $vBlock->z & 0x0f);
|
||||
|
||||
if($blockId !== 0){
|
||||
$blastForce -= (BlockFactory::$blastResistance[$blockId] / 5 + 0.3) * $this->stepLen;
|
||||
if($blastForce > 0){
|
||||
if(!isset($this->affectedBlocks[$index = Level::blockHash($block->x, $block->y, $block->z)])){
|
||||
$this->affectedBlocks[$index] = $block;
|
||||
if(!isset($this->affectedBlocks[$index = Level::blockHash($vBlock->x, $vBlock->y, $vBlock->z)])){
|
||||
$this->affectedBlocks[$index] = BlockFactory::get($blockId, $currentSubChunk->getBlockData($vBlock->x & 0x0f, $vBlock->y & 0x0f, $vBlock->z & 0x0f), $vBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$pointerX += $vector->x;
|
||||
$pointerY += $vector->y;
|
||||
$pointerZ += $vector->z;
|
||||
@ -183,6 +210,9 @@ class Explosion{
|
||||
|
||||
for($side = 0; $side <= 5; $side++){
|
||||
$sideBlock = $pos->getSide($side);
|
||||
if(!$this->level->isInWorld($sideBlock->x, $sideBlock->y, $sideBlock->z)){
|
||||
continue;
|
||||
}
|
||||
if(!isset($this->affectedBlocks[$index = Level::blockHash($sideBlock->x, $sideBlock->y, $sideBlock->z)]) and !isset($updateBlocks[$index])){
|
||||
$this->level->getServer()->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->level->getBlock($sideBlock)));
|
||||
if(!$ev->isCancelled()){
|
||||
|
@ -29,6 +29,7 @@ namespace pocketmine\level;
|
||||
use pocketmine\block\Air;
|
||||
use pocketmine\block\Beetroot;
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\block\BrownMushroom;
|
||||
use pocketmine\block\Cactus;
|
||||
use pocketmine\block\Carrot;
|
||||
@ -311,7 +312,7 @@ class Level implements ChunkManager, Metadatable{
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __construct(Server $server, string $name, string $path, string $provider){
|
||||
$this->blockStates = Block::$fullList;
|
||||
$this->blockStates = BlockFactory::$fullList;
|
||||
$this->levelId = static::$levelIdCounter++;
|
||||
$this->blockMetadata = new BlockMetadataStore($this);
|
||||
$this->server = $server;
|
||||
@ -911,7 +912,7 @@ class Level implements ChunkManager, Metadatable{
|
||||
}
|
||||
|
||||
public function addRandomTickedBlock(int $id){
|
||||
$this->randomTickBlocks[$id] = get_class(Block::$list[$id]);
|
||||
$this->randomTickBlocks[$id] = get_class(BlockFactory::$list[$id]);
|
||||
}
|
||||
|
||||
public function removeRandomTickedBlock(int $id){
|
||||
@ -1388,7 +1389,7 @@ class Level implements ChunkManager, Metadatable{
|
||||
if($yPlusOne === $oldHeightMap){ //Block changed directly beneath the heightmap. Check if a block was removed or changed to a different light-filter.
|
||||
$newHeightMap = $this->getChunk($x >> 4, $z >> 4)->recalculateHeightMapColumn($x & 0x0f, $z & 0x0f);
|
||||
}elseif($yPlusOne > $oldHeightMap){ //Block changed above the heightmap.
|
||||
if(Block::$lightFilter[$sourceId] > 1 or Block::$diffusesSkyLight[$sourceId]){
|
||||
if(BlockFactory::$lightFilter[$sourceId] > 1 or BlockFactory::$diffusesSkyLight[$sourceId]){
|
||||
$this->setHeightMap($x, $z, $yPlusOne);
|
||||
$newHeightMap = $yPlusOne;
|
||||
}else{ //Block changed which has no effect on direct sky light, for example placing or removing glass.
|
||||
@ -1410,7 +1411,7 @@ class Level implements ChunkManager, Metadatable{
|
||||
$update->setAndUpdateLight($x, $i, $z, 15);
|
||||
}
|
||||
}else{ //No heightmap change, block changed "underground"
|
||||
$update->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentBlockSkyLight($x, $y, $z) - Block::$lightFilter[$sourceId]));
|
||||
$update->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentBlockSkyLight($x, $y, $z) - BlockFactory::$lightFilter[$sourceId]));
|
||||
}
|
||||
|
||||
$update->execute();
|
||||
@ -1442,7 +1443,7 @@ class Level implements ChunkManager, Metadatable{
|
||||
$this->timings->doBlockLightUpdates->startTiming();
|
||||
|
||||
$id = $this->getBlockIdAt($x, $y, $z);
|
||||
$newLevel = max(Block::$light[$id], $this->getHighestAdjacentBlockLight($x, $y, $z) - Block::$lightFilter[$id]);
|
||||
$newLevel = max(BlockFactory::$light[$id], $this->getHighestAdjacentBlockLight($x, $y, $z) - BlockFactory::$lightFilter[$id]);
|
||||
|
||||
$update = new BlockLightUpdate($this);
|
||||
$update->setAndUpdateLight($x, $y, $z, $newLevel);
|
||||
@ -1507,7 +1508,8 @@ class Level implements ChunkManager, Metadatable{
|
||||
|
||||
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($block));
|
||||
if(!$ev->isCancelled()){
|
||||
foreach($this->getNearbyEntities(new AxisAlignedBB($block->x - 1, $block->y - 1, $block->z - 1, $block->x + 1, $block->y + 1, $block->z + 1)) as $entity){
|
||||
foreach($this->getNearbyEntities(new AxisAlignedBB($block->x - 1, $block->y - 1, $block->z - 1, $block->x + 2, $block->y + 2, $block->z + 2)) as $entity){
|
||||
$entity->setForceMovementUpdate();
|
||||
$entity->scheduleUpdate();
|
||||
}
|
||||
$ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL);
|
||||
@ -1652,7 +1654,7 @@ class Level implements ChunkManager, Metadatable{
|
||||
$above = $this->getBlock(new Vector3($target->x, $target->y + 1, $target->z));
|
||||
if($above !== null){
|
||||
if($above->getId() === Item::FIRE){
|
||||
$this->setBlock($above, Block::get(Block::AIR), true);
|
||||
$this->setBlock($above, BlockFactory::get(Block::AIR), true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1698,21 +1700,23 @@ class Level implements ChunkManager, Metadatable{
|
||||
/**
|
||||
* Uses a item on a position and face, placing it or activating the block
|
||||
*
|
||||
* @param Vector3 $vector
|
||||
* @param Item $item
|
||||
* @param int $face
|
||||
* @param float $fx default 0.0
|
||||
* @param float $fy default 0.0
|
||||
* @param float $fz default 0.0
|
||||
* @param Player $player default null
|
||||
* @param bool $playSound Whether to play a block-place sound if the block was placed successfully.
|
||||
* @param Vector3 $vector
|
||||
* @param Item $item
|
||||
* @param int $face
|
||||
* @param Vector3|null $facePos
|
||||
* @param Player|null $player default null
|
||||
* @param bool $playSound Whether to play a block-place sound if the block was placed successfully.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function useItemOn(Vector3 $vector, Item &$item, int $face, float $fx = 0.0, float $fy = 0.0, float $fz = 0.0, Player $player = null, bool $playSound = false) : bool{
|
||||
public function useItemOn(Vector3 $vector, Item &$item, int $face, Vector3 $facePos = null, Player $player = null, bool $playSound = false) : bool{
|
||||
$target = $this->getBlock($vector);
|
||||
$block = $target->getSide($face);
|
||||
|
||||
if($facePos === null){
|
||||
$facePos = new Vector3(0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
if($block->y >= $this->provider->getWorldHeight() or $block->y < 0){
|
||||
//TODO: build height limit messages for custom world heights and mcregion cap
|
||||
return false;
|
||||
@ -1757,7 +1761,7 @@ class Level implements ChunkManager, Metadatable{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!$player->isSneaking() and $item->onActivate($this, $player, $block, $target, $face, $fx, $fy, $fz)){
|
||||
if(!$player->isSneaking() and $item->onActivate($this, $player, $block, $target, $face, $facePos)){
|
||||
if($item->getCount() <= 0){
|
||||
$item = Item::get(Item::AIR, 0, 0);
|
||||
|
||||
@ -1771,23 +1775,20 @@ class Level implements ChunkManager, Metadatable{
|
||||
return true;
|
||||
}
|
||||
|
||||
if($item->canBePlaced()){
|
||||
$hand = $item->getBlock();
|
||||
$hand->position($block);
|
||||
}else{
|
||||
if(!$item->canBePlaced()){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!($block->canBeReplaced() === true or ($hand->getId() === Item::WOODEN_SLAB and $block->getId() === Item::WOODEN_SLAB) or ($hand->getId() === Item::STONE_SLAB and $block->getId() === Item::STONE_SLAB))){
|
||||
return false;
|
||||
}
|
||||
$hand = $item->getBlock();
|
||||
|
||||
if($target->canBeReplaced() === true){
|
||||
if($target->canBeReplaced($hand)){
|
||||
$block = $target;
|
||||
$hand->position($block);
|
||||
//$face = -1;
|
||||
}elseif(!$block->canBeReplaced($hand)){
|
||||
return false;
|
||||
}
|
||||
|
||||
$hand->position($block);
|
||||
|
||||
if($hand->isSolid() === true and $hand->getBoundingBox() !== null){
|
||||
$entities = $this->getCollidingEntities($hand->getBoundingBox());
|
||||
$realCount = 0;
|
||||
@ -1828,7 +1829,7 @@ class Level implements ChunkManager, Metadatable{
|
||||
}
|
||||
}
|
||||
|
||||
if($hand->place($item, $block, $target, $face, $fx, $fy, $fz, $player) === false){
|
||||
if(!$hand->place($item, $block, $target, $face, $facePos, $player)){
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2683,7 +2684,7 @@ class Level implements ChunkManager, Metadatable{
|
||||
$wasAir = ($chunk->getBlockId($x, $y - 1, $z) === 0);
|
||||
for(; $y > 0; --$y){
|
||||
$b = $chunk->getFullBlock($x, $y, $z);
|
||||
$block = Block::get($b >> 4, $b & 0x0f);
|
||||
$block = BlockFactory::get($b >> 4, $b & 0x0f);
|
||||
if($this->isFullBlock($block)){
|
||||
if($wasAir){
|
||||
$y++;
|
||||
@ -2696,10 +2697,10 @@ class Level implements ChunkManager, Metadatable{
|
||||
|
||||
for(; $y >= 0 and $y < $max; ++$y){
|
||||
$b = $chunk->getFullBlock($x, $y + 1, $z);
|
||||
$block = Block::get($b >> 4, $b & 0x0f);
|
||||
$block = BlockFactory::get($b >> 4, $b & 0x0f);
|
||||
if(!$this->isFullBlock($block)){
|
||||
$b = $chunk->getFullBlock($x, $y, $z);
|
||||
$block = Block::get($b >> 4, $b & 0x0f);
|
||||
$block = BlockFactory::get($b >> 4, $b & 0x0f);
|
||||
if(!$this->isFullBlock($block)){
|
||||
return new Position($spawn->x, $y === (int) $spawn->y ? $spawn->y : $y, $spawn->z, $this);
|
||||
}
|
||||
|
@ -27,24 +27,30 @@ use pocketmine\entity\Entity;
|
||||
use pocketmine\math\Vector3;
|
||||
|
||||
class MovingObjectPosition{
|
||||
const TYPE_BLOCK_COLLISION = 0;
|
||||
const TYPE_ENTITY_COLLISION = 1;
|
||||
|
||||
/** 0 = block, 1 = entity */
|
||||
/** @var int */
|
||||
public $typeOfHit;
|
||||
|
||||
/** @var int|null */
|
||||
public $blockX;
|
||||
/** @var int|null */
|
||||
public $blockY;
|
||||
/** @var int|null */
|
||||
public $blockZ;
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
* Which side was hit. If its -1 then it went the full length of the ray trace.
|
||||
* Bottom = 0, Top = 1, East = 2, West = 3, North = 4, South = 5.
|
||||
* -1 or one of the Vector3::SIDE_* constants
|
||||
*/
|
||||
public $sideHit;
|
||||
|
||||
/** @var Vector3 */
|
||||
public $hitVector;
|
||||
|
||||
/** @var Entity */
|
||||
/** @var Entity|null */
|
||||
public $entityHit = null;
|
||||
|
||||
protected function __construct(){
|
||||
@ -62,10 +68,11 @@ class MovingObjectPosition{
|
||||
*/
|
||||
public static function fromBlock(int $x, int $y, int $z, int $side, Vector3 $hitVector) : MovingObjectPosition{
|
||||
$ob = new MovingObjectPosition;
|
||||
$ob->typeOfHit = 0;
|
||||
$ob->typeOfHit = self::TYPE_BLOCK_COLLISION;
|
||||
$ob->blockX = $x;
|
||||
$ob->blockY = $y;
|
||||
$ob->blockZ = $z;
|
||||
$ob->sideHit = $side;
|
||||
$ob->hitVector = new Vector3($hitVector->x, $hitVector->y, $hitVector->z);
|
||||
return $ob;
|
||||
}
|
||||
@ -77,7 +84,7 @@ class MovingObjectPosition{
|
||||
*/
|
||||
public static function fromEntity(Entity $entity) : MovingObjectPosition{
|
||||
$ob = new MovingObjectPosition;
|
||||
$ob->typeOfHit = 1;
|
||||
$ob->typeOfHit = self::TYPE_ENTITY_COLLISION;
|
||||
$ob->entityHit = $entity;
|
||||
$ob->hitVector = new Vector3($entity->x, $entity->y, $entity->z);
|
||||
return $ob;
|
||||
|
@ -26,7 +26,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\level\format;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\nbt\NBT;
|
||||
@ -438,7 +438,7 @@ class Chunk{
|
||||
public function recalculateHeightMapColumn(int $x, int $z) : int{
|
||||
$max = $this->getHighestBlockAt($x, $z);
|
||||
for($y = $max; $y >= 0; --$y){
|
||||
if(Block::$lightFilter[$id = $this->getBlockId($x, $y, $z)] > 1 or Block::$diffusesSkyLight[$id]){
|
||||
if(BlockFactory::$lightFilter[$id = $this->getBlockId($x, $y, $z)] > 1 or BlockFactory::$diffusesSkyLight[$id]){
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -470,7 +470,7 @@ class Chunk{
|
||||
$light = 15;
|
||||
for(; $y >= 0; --$y){
|
||||
if($light > 0){
|
||||
$light -= Block::$lightFilter[$this->getBlockId($x, $y, $z)];
|
||||
$light -= BlockFactory::$lightFilter[$this->getBlockId($x, $y, $z)];
|
||||
if($light <= 0){
|
||||
break;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\level\generator;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\level\generator\biome\Biome;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\level\SimpleChunkManager;
|
||||
@ -47,7 +47,7 @@ class GeneratorRegisterTask extends AsyncTask{
|
||||
}
|
||||
|
||||
public function onRun(){
|
||||
Block::init();
|
||||
BlockFactory::init();
|
||||
Biome::init();
|
||||
$manager = new SimpleChunkManager($this->seed, $this->worldHeight);
|
||||
$this->saveToThreadStore("generation.level{$this->levelId}.manager", $manager);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user