mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-21 00:07:30 +00:00
Merge branch 'next-major' into modern-world-support
This commit is contained in:
commit
01af70f671
77
changelogs/4.4.md
Normal file
77
changelogs/4.4.md
Normal file
@ -0,0 +1,77 @@
|
||||
**For Minecraft: Bedrock Edition 1.18.30**
|
||||
|
||||
### Note about API versions
|
||||
Plugins which don't touch the protocol and compatible with any previous 4.x.y version will also run on these releases and do not need API bumps.
|
||||
Plugin developers should **only** update their required API to this version if you need the changes in this build.
|
||||
|
||||
**WARNING: If your plugin uses the protocol, you're not shielded by API change constraints.** You should consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you do.
|
||||
|
||||
# 4.4.0
|
||||
Released 1st June 2022.
|
||||
|
||||
## General
|
||||
- The server will now shut itself down if any of the following errors occur during startup:
|
||||
- Any plugin fails to load or enable (plugins loaded by other plugins post-startup are **not** affected by this change) (**PR [#4951](https://github.com/pmmp/PocketMine-MP/pull/4951)**)
|
||||
- The motivation for this change is to prevent situations where plugins failing to load could result in adverse outcomes, such as a world protection plugin leaving a lobby unprotected from griefing.
|
||||
- If you encounter this problem, remove the offending plugin(s) or prevent it from loading using `plugin_list.yml`.
|
||||
- See **PR [#4951](https://github.com/pmmp/PocketMine-MP/pull/4951)** for more detail on this change.
|
||||
- Any world mentioned in `server.properties` or `pocketmine.yml` fails to load (worlds loaded by plugins are **not** affected by this change)
|
||||
- Any world mentioned in `server.properties` or `pocketmine.yml` fails to generate (e.g. due to invalid generator settings)
|
||||
- Enabling the server whitelist while the server is running (e.g. using `/whitelist on`) will now kick any non-whitelisted players currently on the server (**PR [#4774](https://github.com/pmmp/PocketMine-MP/pull/4774)**).
|
||||
- Help for commands (`/help <name of command>`) now displays a list of aliases of that command.
|
||||
- A CRITICAL log message is now generated if a plugin disables itself when enabling, in case the plugin doesn't emit any error of its own.
|
||||
- The `/give` command now shows the alias used to find the given item in the success message, instead of the item ID/meta.
|
||||
|
||||
## Fixes
|
||||
- Block placement has been fixed in many places where it previously didn't work correctly (**PR [#4886](https://github.com/pmmp/PocketMine-MP/pull/4886)**):
|
||||
- torches on top of slabs, upside-down stairs
|
||||
- torches on the back face of stairs
|
||||
- flower pots on top of fences
|
||||
- the list goes on and on ...
|
||||
- Fixed backslash escapes not getting properly removed from commands in some cases.
|
||||
- Fixed aliases defined in the `aliases` section of `pocketmine.yml` not being treated as quote-aware.
|
||||
|
||||
## Gameplay
|
||||
- Plants in flower pots can now be removed by right-clicking on the flower pot.
|
||||
- Leaves now have a 2% chance of dropping sticks when destroyed by hand (**PR [#5019](https://github.com/pmmp/PocketMine-MP/pull/5019)**).
|
||||
- Food exhaustion now matches Bedrock 1.18.30 (**PR [#5034](https://github.com/pmmp/PocketMine-MP/pull/5034)**).
|
||||
- Implemented Stonecutter block (**PR [#4732](https://github.com/pmmp/PocketMine-MP/pull/4732)**).
|
||||
|
||||
## API
|
||||
### Block
|
||||
- Added `Block->getSupportType(Facing) : SupportType` (**PR [#4886](https://github.com/pmmp/PocketMine-MP/pull/4886)**).
|
||||
- This is used to determine the kind of support a block face can provide to a block (e.g. a torch) placed on it.
|
||||
- Added `utils\SupportType` enum (**PR [#4886](https://github.com/pmmp/PocketMine-MP/pull/4886)**).
|
||||
- `tile\Spawnable->isDirty()` and `tile\Spawnable->setDirty()` are now `@deprecated`.
|
||||
|
||||
### Command
|
||||
- Added `CommandStringHelper::parseQuoteAware()`. This static method contains the code used by `SimpleCommandMap` used to parse quoted command arguments.
|
||||
|
||||
### Entity
|
||||
- Added `Human::emote()` (**PR [#4610](https://github.com/pmmp/PocketMine-MP/pull/4610)**)
|
||||
|
||||
### Event
|
||||
- `PlayerCommandPreprocessEvent` is now `@deprecated`, since its functionality is entirely replaced by other, general-purpose events.
|
||||
- Use `CommandEvent` to intercept commands.
|
||||
- Use `PlayerChatEvent` to intercept chat messages.
|
||||
- To convert a chat message into a command, pass it directly to `Server->dispatchCommand()` with the player as sender.
|
||||
- Added `PlayerPostChunkSendEvent` (**PR [#4937](https://github.com/pmmp/PocketMine-MP/pull/4937)**).
|
||||
- Added `PlayerDeathEvent->setKeepXp()` (**PR [#4015](https://github.com/pmmp/PocketMine-MP/pull/4015)**).
|
||||
- `InventoryCloseEvent` is now called **after** the target window has been removed. This fixes various feedback loops caused by trying to open new windows to a player while there was one still active.
|
||||
- As a side effect, this now means that `Player->getCurrentWindow()` will return `null` during `InventoryCloseEvent`. Use `InventoryCloseEvent->getInventory()` instead.
|
||||
|
||||
### Item
|
||||
- `StringToItemParser` now recognizes `cod`, `raw_cod` and `cooked_cod` aliases.
|
||||
|
||||
### Plugin
|
||||
- `DisablePluginException` may now be thrown from `Plugin::onEnable()` to make the server gracefully disable the plugin (without crashing) (**PR [#4780](https://github.com/pmmp/PocketMine-MP/pull/4780)**).
|
||||
- `PluginManager->registerEvent()` now returns the `RegisteredListener` created for the handler, to permit unregistering it later.
|
||||
|
||||
## Internals
|
||||
- Private property declarations now use typed properties (PHP 7.4) and promoted constructor properties (PHP 8.0) wherever possible.
|
||||
- Protected and public properties remain unchanged, since they can't be changed without breaking subclasses.
|
||||
- Promoted constructor properties are only used when it's consistently possible to promote most or all properties in a class.
|
||||
- Simplified and improved legibility of `FormattedCommandAlias`.
|
||||
- Added unit tests for the quote-aware command parser used by `SimpleCommandMap`.
|
||||
- Various hardcoded values in `block` package classes have been moved to private constants to improve readability.
|
||||
- Added various constants used in the `LevelDB` world provider.
|
@ -31,9 +31,9 @@ use function str_repeat;
|
||||
|
||||
final class VersionInfo{
|
||||
public const NAME = "PocketMine-MP";
|
||||
public const BASE_VERSION = "4.4.0-BETA2";
|
||||
public const BASE_VERSION = "5.0.0";
|
||||
public const IS_DEVELOPMENT_BUILD = true;
|
||||
public const BUILD_CHANNEL = "beta";
|
||||
public const BUILD_CHANNEL = "alpha";
|
||||
|
||||
private function __construct(){
|
||||
//NOOP
|
||||
|
@ -90,125 +90,79 @@ abstract class Entity{
|
||||
}
|
||||
|
||||
/** @var Player[] */
|
||||
protected $hasSpawned = [];
|
||||
protected array $hasSpawned = [];
|
||||
|
||||
/** @var int */
|
||||
protected $id;
|
||||
protected int $id;
|
||||
|
||||
private EntityMetadataCollection $networkProperties;
|
||||
|
||||
/** @var EntityDamageEvent|null */
|
||||
protected $lastDamageCause = null;
|
||||
protected ?EntityDamageEvent $lastDamageCause = null;
|
||||
|
||||
/** @var Block[]|null */
|
||||
protected $blocksAround;
|
||||
protected ?array $blocksAround = null;
|
||||
|
||||
/** @var Location */
|
||||
protected $location;
|
||||
/** @var Location */
|
||||
protected $lastLocation;
|
||||
/** @var Vector3 */
|
||||
protected $motion;
|
||||
/** @var Vector3 */
|
||||
protected $lastMotion;
|
||||
/** @var bool */
|
||||
protected $forceMovementUpdate = false;
|
||||
protected Location $location;
|
||||
protected Location $lastLocation;
|
||||
protected Vector3 $motion;
|
||||
protected Vector3 $lastMotion;
|
||||
protected bool $forceMovementUpdate = false;
|
||||
|
||||
/** @var AxisAlignedBB */
|
||||
public $boundingBox;
|
||||
/** @var bool */
|
||||
public $onGround = false;
|
||||
public AxisAlignedBB $boundingBox;
|
||||
public bool $onGround = false;
|
||||
|
||||
/** @var EntitySizeInfo */
|
||||
public $size;
|
||||
public EntitySizeInfo $size;
|
||||
|
||||
private float $health = 20.0;
|
||||
private int $maxHealth = 20;
|
||||
|
||||
/** @var float */
|
||||
protected $ySize = 0.0;
|
||||
/** @var float */
|
||||
protected $stepHeight = 0.0;
|
||||
/** @var bool */
|
||||
public $keepMovement = false;
|
||||
protected float $ySize = 0.0;
|
||||
protected float $stepHeight = 0.0;
|
||||
public bool $keepMovement = false;
|
||||
|
||||
/** @var float */
|
||||
public $fallDistance = 0.0;
|
||||
/** @var int */
|
||||
public $ticksLived = 0;
|
||||
/** @var int */
|
||||
public $lastUpdate;
|
||||
/** @var int */
|
||||
protected $fireTicks = 0;
|
||||
/** @var bool */
|
||||
public $canCollide = true;
|
||||
|
||||
/** @var bool */
|
||||
protected $isStatic = false;
|
||||
public float $fallDistance = 0.0;
|
||||
public int $ticksLived = 0;
|
||||
public int $lastUpdate;
|
||||
protected int $fireTicks = 0;
|
||||
|
||||
private bool $savedWithChunk = true;
|
||||
|
||||
/** @var bool */
|
||||
public $isCollided = false;
|
||||
/** @var bool */
|
||||
public $isCollidedHorizontally = false;
|
||||
/** @var bool */
|
||||
public $isCollidedVertically = false;
|
||||
public bool $isCollided = false;
|
||||
public bool $isCollidedHorizontally = false;
|
||||
public bool $isCollidedVertically = false;
|
||||
|
||||
/** @var int */
|
||||
public $noDamageTicks = 0;
|
||||
/** @var bool */
|
||||
protected $justCreated = true;
|
||||
public int $noDamageTicks = 0;
|
||||
protected bool $justCreated = true;
|
||||
|
||||
/** @var AttributeMap */
|
||||
protected $attributeMap;
|
||||
protected AttributeMap $attributeMap;
|
||||
|
||||
/** @var float */
|
||||
protected $gravity;
|
||||
/** @var float */
|
||||
protected $drag;
|
||||
/** @var bool */
|
||||
protected $gravityEnabled = true;
|
||||
protected float $gravity;
|
||||
protected float $drag;
|
||||
protected bool $gravityEnabled = true;
|
||||
|
||||
/** @var Server */
|
||||
protected $server;
|
||||
protected Server $server;
|
||||
|
||||
/** @var bool */
|
||||
protected $closed = false;
|
||||
protected bool $closed = false;
|
||||
private bool $closeInFlight = false;
|
||||
private bool $needsDespawn = false;
|
||||
|
||||
/** @var TimingsHandler */
|
||||
protected $timings;
|
||||
protected TimingsHandler $timings;
|
||||
|
||||
protected bool $networkPropertiesDirty = false;
|
||||
|
||||
/** @var string */
|
||||
protected $nameTag = "";
|
||||
/** @var bool */
|
||||
protected $nameTagVisible = true;
|
||||
/** @var bool */
|
||||
protected $alwaysShowNameTag = false;
|
||||
/** @var string */
|
||||
protected $scoreTag = "";
|
||||
/** @var float */
|
||||
protected $scale = 1.0;
|
||||
protected string $nameTag = "";
|
||||
protected bool $nameTagVisible = true;
|
||||
protected bool $alwaysShowNameTag = false;
|
||||
protected string $scoreTag = "";
|
||||
protected float $scale = 1.0;
|
||||
|
||||
/** @var bool */
|
||||
protected $canClimb = false;
|
||||
/** @var bool */
|
||||
protected $canClimbWalls = false;
|
||||
/** @var bool */
|
||||
protected $immobile = false;
|
||||
/** @var bool */
|
||||
protected $invisible = false;
|
||||
/** @var bool */
|
||||
protected $silent = false;
|
||||
protected bool $canClimb = false;
|
||||
protected bool $canClimbWalls = false;
|
||||
protected bool $immobile = false;
|
||||
protected bool $invisible = false;
|
||||
protected bool $silent = false;
|
||||
|
||||
/** @var int|null */
|
||||
protected $ownerId = null;
|
||||
/** @var int|null */
|
||||
protected $targetId = null;
|
||||
protected ?int $ownerId = null;
|
||||
protected ?int $targetId = null;
|
||||
|
||||
private bool $constructorCalled = false;
|
||||
|
||||
@ -222,6 +176,8 @@ abstract class Entity{
|
||||
$this->timings = Timings::getEntityTimings($this);
|
||||
|
||||
$this->size = $this->getInitialSizeInfo();
|
||||
$this->drag = $this->getInitialDragMultiplier();
|
||||
$this->gravity = $this->getInitialGravity();
|
||||
|
||||
$this->id = self::nextRuntimeId();
|
||||
$this->server = $location->getWorld()->getServer();
|
||||
@ -257,6 +213,21 @@ abstract class Entity{
|
||||
|
||||
abstract protected function getInitialSizeInfo() : EntitySizeInfo;
|
||||
|
||||
/**
|
||||
* Returns the percentage by which the entity's velocity is reduced per tick when moving through air.
|
||||
* The entity's velocity is multiplied by 1 minus this value.
|
||||
*
|
||||
* @return float 0-1
|
||||
*/
|
||||
abstract protected function getInitialDragMultiplier() : float;
|
||||
|
||||
/**
|
||||
* Returns the downwards acceleration of the entity when falling, in blocks/tick².
|
||||
*
|
||||
* @return float minimum 0
|
||||
*/
|
||||
abstract protected function getInitialGravity() : float;
|
||||
|
||||
public function getNameTag() : string{
|
||||
return $this->nameTag;
|
||||
}
|
||||
@ -984,9 +955,7 @@ abstract class Entity{
|
||||
|
||||
$this->timings->stopTiming();
|
||||
|
||||
//if($this->isStatic())
|
||||
return ($hasUpdate || $this->hasMovementUpdate());
|
||||
//return !($this instanceof Player);
|
||||
}
|
||||
|
||||
final public function scheduleUpdate() : void{
|
||||
|
@ -74,28 +74,18 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
|
||||
|
||||
public static function getNetworkTypeId() : string{ return EntityIds::PLAYER; }
|
||||
|
||||
/** @var PlayerInventory */
|
||||
protected $inventory;
|
||||
protected PlayerInventory $inventory;
|
||||
protected PlayerOffHandInventory $offHandInventory;
|
||||
protected PlayerEnderInventory $enderInventory;
|
||||
|
||||
/** @var PlayerOffHandInventory */
|
||||
protected $offHandInventory;
|
||||
protected UuidInterface $uuid;
|
||||
|
||||
/** @var PlayerEnderInventory */
|
||||
protected $enderInventory;
|
||||
protected Skin $skin;
|
||||
|
||||
/** @var UuidInterface */
|
||||
protected $uuid;
|
||||
protected HungerManager $hungerManager;
|
||||
protected ExperienceManager $xpManager;
|
||||
|
||||
/** @var Skin */
|
||||
protected $skin;
|
||||
|
||||
/** @var HungerManager */
|
||||
protected $hungerManager;
|
||||
/** @var ExperienceManager */
|
||||
protected $xpManager;
|
||||
|
||||
/** @var int */
|
||||
protected $xpSeed;
|
||||
protected int $xpSeed;
|
||||
|
||||
public function __construct(Location $location, Skin $skin, ?CompoundTag $nbt = null){
|
||||
$this->skin = $skin;
|
||||
@ -383,9 +373,9 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
|
||||
|
||||
public function getDrops() : array{
|
||||
return array_filter(array_merge(
|
||||
$this->inventory !== null ? array_values($this->inventory->getContents()) : [],
|
||||
$this->armorInventory !== null ? array_values($this->armorInventory->getContents()) : [],
|
||||
$this->offHandInventory !== null ? array_values($this->offHandInventory->getContents()) : [],
|
||||
array_values($this->inventory->getContents()),
|
||||
array_values($this->armorInventory->getContents()),
|
||||
array_values($this->offHandInventory->getContents()),
|
||||
), function(Item $item) : bool{ return !$item->hasEnchantment(VanillaEnchantments::VANISHING()); });
|
||||
}
|
||||
|
||||
@ -404,55 +394,51 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
|
||||
|
||||
$inventoryTag = new ListTag([], NBT::TAG_Compound);
|
||||
$nbt->setTag("Inventory", $inventoryTag);
|
||||
if($this->inventory !== null){
|
||||
//Normal inventory
|
||||
$slotCount = $this->inventory->getSize() + $this->inventory->getHotbarSize();
|
||||
for($slot = $this->inventory->getHotbarSize(); $slot < $slotCount; ++$slot){
|
||||
$item = $this->inventory->getItem($slot - 9);
|
||||
if(!$item->isNull()){
|
||||
$inventoryTag->push($item->nbtSerialize($slot));
|
||||
}
|
||||
}
|
||||
|
||||
//Armor
|
||||
for($slot = 100; $slot < 104; ++$slot){
|
||||
$item = $this->armorInventory->getItem($slot - 100);
|
||||
if(!$item->isNull()){
|
||||
$inventoryTag->push($item->nbtSerialize($slot));
|
||||
}
|
||||
//Normal inventory
|
||||
$slotCount = $this->inventory->getSize() + $this->inventory->getHotbarSize();
|
||||
for($slot = $this->inventory->getHotbarSize(); $slot < $slotCount; ++$slot){
|
||||
$item = $this->inventory->getItem($slot - 9);
|
||||
if(!$item->isNull()){
|
||||
$inventoryTag->push($item->nbtSerialize($slot));
|
||||
}
|
||||
|
||||
$nbt->setInt("SelectedInventorySlot", $this->inventory->getHeldItemIndex());
|
||||
}
|
||||
|
||||
//Armor
|
||||
for($slot = 100; $slot < 104; ++$slot){
|
||||
$item = $this->armorInventory->getItem($slot - 100);
|
||||
if(!$item->isNull()){
|
||||
$inventoryTag->push($item->nbtSerialize($slot));
|
||||
}
|
||||
}
|
||||
|
||||
$nbt->setInt("SelectedInventorySlot", $this->inventory->getHeldItemIndex());
|
||||
|
||||
$offHandItem = $this->offHandInventory->getItem(0);
|
||||
if(!$offHandItem->isNull()){
|
||||
$nbt->setTag("OffHandItem", $offHandItem->nbtSerialize());
|
||||
}
|
||||
|
||||
if($this->enderInventory !== null){
|
||||
/** @var CompoundTag[] $items */
|
||||
$items = [];
|
||||
/** @var CompoundTag[] $items */
|
||||
$items = [];
|
||||
|
||||
$slotCount = $this->enderInventory->getSize();
|
||||
for($slot = 0; $slot < $slotCount; ++$slot){
|
||||
$item = $this->enderInventory->getItem($slot);
|
||||
if(!$item->isNull()){
|
||||
$items[] = $item->nbtSerialize($slot);
|
||||
}
|
||||
$slotCount = $this->enderInventory->getSize();
|
||||
for($slot = 0; $slot < $slotCount; ++$slot){
|
||||
$item = $this->enderInventory->getItem($slot);
|
||||
if(!$item->isNull()){
|
||||
$items[] = $item->nbtSerialize($slot);
|
||||
}
|
||||
|
||||
$nbt->setTag("EnderChestInventory", new ListTag($items, NBT::TAG_Compound));
|
||||
}
|
||||
|
||||
if($this->skin !== null){
|
||||
$nbt->setTag("Skin", CompoundTag::create()
|
||||
->setString("Name", $this->skin->getSkinId())
|
||||
->setByteArray("Data", $this->skin->getSkinData())
|
||||
->setByteArray("CapeData", $this->skin->getCapeData())
|
||||
->setString("GeometryName", $this->skin->getGeometryName())
|
||||
->setByteArray("GeometryData", $this->skin->getGeometryData())
|
||||
);
|
||||
}
|
||||
$nbt->setTag("EnderChestInventory", new ListTag($items, NBT::TAG_Compound));
|
||||
|
||||
$nbt->setTag("Skin", CompoundTag::create()
|
||||
->setString("Name", $this->skin->getSkinId())
|
||||
->setByteArray("Data", $this->skin->getSkinData())
|
||||
->setByteArray("CapeData", $this->skin->getCapeData())
|
||||
->setString("GeometryName", $this->skin->getGeometryName())
|
||||
->setByteArray("GeometryData", $this->skin->getGeometryData())
|
||||
);
|
||||
|
||||
return $nbt;
|
||||
}
|
||||
@ -512,11 +498,13 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
|
||||
}
|
||||
|
||||
protected function destroyCycles() : void{
|
||||
$this->inventory = null;
|
||||
$this->offHandInventory = null;
|
||||
$this->enderInventory = null;
|
||||
$this->hungerManager = null;
|
||||
$this->xpManager = null;
|
||||
unset(
|
||||
$this->inventory,
|
||||
$this->offHandInventory,
|
||||
$this->enderInventory,
|
||||
$this->hungerManager,
|
||||
$this->xpManager
|
||||
);
|
||||
parent::destroyCycles();
|
||||
}
|
||||
}
|
||||
|
@ -76,50 +76,34 @@ use const M_PI;
|
||||
abstract class Living extends Entity{
|
||||
protected const DEFAULT_BREATH_TICKS = 300;
|
||||
|
||||
protected $gravity = 0.08;
|
||||
protected $drag = 0.02;
|
||||
protected int $attackTime = 0;
|
||||
|
||||
/** @var int */
|
||||
protected $attackTime = 0;
|
||||
public int $deadTicks = 0;
|
||||
protected int $maxDeadTicks = 25;
|
||||
|
||||
/** @var int */
|
||||
public $deadTicks = 0;
|
||||
/** @var int */
|
||||
protected $maxDeadTicks = 25;
|
||||
protected float $jumpVelocity = 0.42;
|
||||
|
||||
/** @var float */
|
||||
protected $jumpVelocity = 0.42;
|
||||
protected EffectManager $effectManager;
|
||||
|
||||
/** @var EffectManager */
|
||||
protected $effectManager;
|
||||
protected ArmorInventory $armorInventory;
|
||||
|
||||
/** @var ArmorInventory */
|
||||
protected $armorInventory;
|
||||
protected bool $breathing = true;
|
||||
protected int $breathTicks = self::DEFAULT_BREATH_TICKS;
|
||||
protected int $maxBreathTicks = self::DEFAULT_BREATH_TICKS;
|
||||
|
||||
/** @var bool */
|
||||
protected $breathing = true;
|
||||
/** @var int */
|
||||
protected $breathTicks = self::DEFAULT_BREATH_TICKS;
|
||||
/** @var int */
|
||||
protected $maxBreathTicks = self::DEFAULT_BREATH_TICKS;
|
||||
protected Attribute $healthAttr;
|
||||
protected Attribute $absorptionAttr;
|
||||
protected Attribute $knockbackResistanceAttr;
|
||||
protected Attribute $moveSpeedAttr;
|
||||
|
||||
/** @var Attribute */
|
||||
protected $healthAttr;
|
||||
/** @var Attribute */
|
||||
protected $absorptionAttr;
|
||||
/** @var Attribute */
|
||||
protected $knockbackResistanceAttr;
|
||||
/** @var Attribute */
|
||||
protected $moveSpeedAttr;
|
||||
protected bool $sprinting = false;
|
||||
protected bool $sneaking = false;
|
||||
protected bool $gliding = false;
|
||||
protected bool $swimming = false;
|
||||
|
||||
/** @var bool */
|
||||
protected $sprinting = false;
|
||||
/** @var bool */
|
||||
protected $sneaking = false;
|
||||
/** @var bool */
|
||||
protected $gliding = false;
|
||||
/** @var bool */
|
||||
protected $swimming = false;
|
||||
protected function getInitialDragMultiplier() : float{ return 0.02; }
|
||||
|
||||
protected function getInitialGravity() : float{ return 0.08; }
|
||||
|
||||
abstract public function getName() : string;
|
||||
|
||||
@ -850,8 +834,10 @@ abstract class Living extends Entity{
|
||||
}
|
||||
|
||||
protected function destroyCycles() : void{
|
||||
$this->armorInventory = null;
|
||||
$this->effectManager = null;
|
||||
unset(
|
||||
$this->armorInventory,
|
||||
$this->effectManager
|
||||
);
|
||||
parent::destroyCycles();
|
||||
}
|
||||
}
|
||||
|
@ -29,10 +29,8 @@ use pocketmine\world\World;
|
||||
|
||||
class Location extends Position{
|
||||
|
||||
/** @var float */
|
||||
public $yaw;
|
||||
/** @var float */
|
||||
public $pitch;
|
||||
public float $yaw;
|
||||
public float $pitch;
|
||||
|
||||
public function __construct(float $x, float $y, float $z, ?World $world, float $yaw, float $pitch){
|
||||
$this->yaw = $yaw;
|
||||
|
@ -39,10 +39,8 @@ class Squid extends WaterAnimal{
|
||||
|
||||
public static function getNetworkTypeId() : string{ return EntityIds::SQUID; }
|
||||
|
||||
/** @var Vector3|null */
|
||||
public $swimDirection = null;
|
||||
/** @var float */
|
||||
public $swimSpeed = 0.1;
|
||||
public ?Vector3 $swimDirection = null;
|
||||
public float $swimSpeed = 0.1;
|
||||
|
||||
private int $switchDirectionTicker = 0;
|
||||
|
||||
|
@ -28,8 +28,7 @@ use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection;
|
||||
use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags;
|
||||
|
||||
abstract class WaterAnimal extends Living implements Ageable{
|
||||
/** @var bool */
|
||||
protected $baby = false;
|
||||
protected bool $baby = false;
|
||||
|
||||
public function isBaby() : bool{
|
||||
return $this->baby;
|
||||
|
@ -33,25 +33,22 @@ use function count;
|
||||
use function spl_object_id;
|
||||
|
||||
class EffectManager{
|
||||
|
||||
/** @var EffectInstance[] */
|
||||
protected $effects = [];
|
||||
protected array $effects = [];
|
||||
|
||||
/** @var Color */
|
||||
protected $bubbleColor;
|
||||
/** @var bool */
|
||||
protected $onlyAmbientEffects = false;
|
||||
protected Color $bubbleColor;
|
||||
protected bool $onlyAmbientEffects = false;
|
||||
|
||||
/**
|
||||
* @var \Closure[]|ObjectSet
|
||||
* @phpstan-var ObjectSet<\Closure(EffectInstance, bool $replacesOldEffect) : void>
|
||||
*/
|
||||
protected $effectAddHooks;
|
||||
protected ObjectSet $effectAddHooks;
|
||||
/**
|
||||
* @var \Closure[]|ObjectSet
|
||||
* @phpstan-var ObjectSet<\Closure(EffectInstance) : void>
|
||||
*/
|
||||
protected $effectRemoveHooks;
|
||||
protected ObjectSet $effectRemoveHooks;
|
||||
|
||||
public function __construct(
|
||||
private Living $entity
|
||||
|
@ -78,26 +78,15 @@ class ExperienceOrb extends Entity{
|
||||
return $result;
|
||||
}
|
||||
|
||||
public $gravity = 0.04;
|
||||
public $drag = 0.02;
|
||||
protected int $age = 0;
|
||||
|
||||
/** @var int */
|
||||
protected $age = 0;
|
||||
/** Ticker used for determining interval in which to look for new target players. */
|
||||
protected int $lookForTargetTime = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* Ticker used for determining interval in which to look for new target players.
|
||||
*/
|
||||
protected $lookForTargetTime = 0;
|
||||
/** Runtime entity ID of the player this XP orb is targeting. */
|
||||
protected ?int $targetPlayerRuntimeId = null;
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
* Runtime entity ID of the player this XP orb is targeting.
|
||||
*/
|
||||
protected $targetPlayerRuntimeId = null;
|
||||
|
||||
/** @var int */
|
||||
protected $xpValue;
|
||||
protected int $xpValue;
|
||||
|
||||
public function __construct(Location $location, int $xpValue, ?CompoundTag $nbt = null){
|
||||
$this->xpValue = $xpValue;
|
||||
@ -106,6 +95,10 @@ class ExperienceOrb extends Entity{
|
||||
|
||||
protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.25, 0.25); }
|
||||
|
||||
protected function getInitialDragMultiplier() : float{ return 0.02; }
|
||||
|
||||
protected function getInitialGravity() : float{ return 0.04; }
|
||||
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
parent::initEntity($nbt);
|
||||
|
||||
|
@ -46,13 +46,7 @@ class FallingBlock extends Entity{
|
||||
|
||||
public static function getNetworkTypeId() : string{ return EntityIds::FALLING_BLOCK; }
|
||||
|
||||
protected $gravity = 0.04;
|
||||
protected $drag = 0.02;
|
||||
|
||||
/** @var Block */
|
||||
protected $block;
|
||||
|
||||
public $canCollide = false;
|
||||
protected Block $block;
|
||||
|
||||
public function __construct(Location $location, Block $block, ?CompoundTag $nbt = null){
|
||||
$this->block = $block;
|
||||
@ -61,6 +55,10 @@ class FallingBlock extends Entity{
|
||||
|
||||
protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.98, 0.98); }
|
||||
|
||||
protected function getInitialDragMultiplier() : float{ return 0.02; }
|
||||
|
||||
protected function getInitialGravity() : float{ return 0.04; }
|
||||
|
||||
public static function parseBlockNBT(BlockFactory $factory, CompoundTag $nbt) : Block{
|
||||
$blockId = 0;
|
||||
|
||||
|
@ -50,22 +50,11 @@ class ItemEntity extends Entity{
|
||||
public const NEVER_DESPAWN = -1;
|
||||
public const MAX_DESPAWN_DELAY = 32767 + self::DEFAULT_DESPAWN_DELAY; //max value storable by mojang NBT :(
|
||||
|
||||
/** @var string */
|
||||
protected $owner = "";
|
||||
/** @var string */
|
||||
protected $thrower = "";
|
||||
/** @var int */
|
||||
protected $pickupDelay = 0;
|
||||
/** @var Item */
|
||||
protected $item;
|
||||
|
||||
protected $gravity = 0.04;
|
||||
protected $drag = 0.02;
|
||||
|
||||
public $canCollide = false;
|
||||
|
||||
/** @var int */
|
||||
protected $despawnDelay = self::DEFAULT_DESPAWN_DELAY;
|
||||
protected string $owner = "";
|
||||
protected string $thrower = "";
|
||||
protected int $pickupDelay = 0;
|
||||
protected int $despawnDelay = self::DEFAULT_DESPAWN_DELAY;
|
||||
protected Item $item;
|
||||
|
||||
public function __construct(Location $location, Item $item, ?CompoundTag $nbt = null){
|
||||
if($item->isNull()){
|
||||
@ -77,6 +66,10 @@ class ItemEntity extends Entity{
|
||||
|
||||
protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.25, 0.25); }
|
||||
|
||||
protected function getInitialDragMultiplier() : float{ return 0.02; }
|
||||
|
||||
protected function getInitialGravity() : float{ return 0.04; }
|
||||
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
parent::initEntity($nbt);
|
||||
|
||||
@ -197,12 +190,8 @@ class ItemEntity extends Entity{
|
||||
}
|
||||
$nbt->setShort("Age", $age);
|
||||
$nbt->setShort("PickupDelay", $this->pickupDelay);
|
||||
if($this->owner !== null){
|
||||
$nbt->setString("Owner", $this->owner);
|
||||
}
|
||||
if($this->thrower !== null){
|
||||
$nbt->setString("Thrower", $this->thrower);
|
||||
}
|
||||
$nbt->setString("Owner", $this->owner);
|
||||
$nbt->setString("Thrower", $this->thrower);
|
||||
|
||||
return $nbt;
|
||||
}
|
||||
|
@ -56,17 +56,9 @@ class Painting extends Entity{
|
||||
Facing::EAST => 3
|
||||
];
|
||||
|
||||
/** @var float */
|
||||
protected $gravity = 0.0;
|
||||
/** @var float */
|
||||
protected $drag = 1.0;
|
||||
|
||||
/** @var Vector3 */
|
||||
protected $blockIn;
|
||||
/** @var int */
|
||||
protected $facing = Facing::NORTH;
|
||||
/** @var PaintingMotive */
|
||||
protected $motive;
|
||||
protected Vector3 $blockIn;
|
||||
protected int $facing;
|
||||
protected PaintingMotive $motive;
|
||||
|
||||
public function __construct(Location $location, Vector3 $blockIn, int $facing, PaintingMotive $motive, ?CompoundTag $nbt = null){
|
||||
$this->motive = $motive;
|
||||
@ -80,6 +72,10 @@ class Painting extends Entity{
|
||||
return new EntitySizeInfo(0.5, 0.5);
|
||||
}
|
||||
|
||||
protected function getInitialDragMultiplier() : float{ return 1.0; }
|
||||
|
||||
protected function getInitialGravity() : float{ return 0.0; }
|
||||
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
$this->setMaxHealth(1);
|
||||
$this->setHealth(1);
|
||||
|
@ -84,18 +84,11 @@ class PaintingMotive{
|
||||
return self::$motives;
|
||||
}
|
||||
|
||||
/** @var string */
|
||||
protected $name;
|
||||
/** @var int */
|
||||
protected $width;
|
||||
/** @var int */
|
||||
protected $height;
|
||||
|
||||
public function __construct(int $width, int $height, string $name){
|
||||
$this->name = $name;
|
||||
$this->width = $width;
|
||||
$this->height = $height;
|
||||
}
|
||||
public function __construct(
|
||||
protected int $width,
|
||||
protected int $height,
|
||||
protected string $name
|
||||
){}
|
||||
|
||||
public function getName() : string{
|
||||
return $this->name;
|
||||
|
@ -41,18 +41,15 @@ class PrimedTNT extends Entity implements Explosive{
|
||||
|
||||
public static function getNetworkTypeId() : string{ return EntityIds::TNT; }
|
||||
|
||||
protected $gravity = 0.04;
|
||||
protected $drag = 0.02;
|
||||
|
||||
/** @var int */
|
||||
protected $fuse;
|
||||
|
||||
protected int $fuse;
|
||||
protected bool $worksUnderwater = false;
|
||||
|
||||
public $canCollide = false;
|
||||
|
||||
protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.98, 0.98); }
|
||||
|
||||
protected function getInitialDragMultiplier() : float{ return 0.02; }
|
||||
|
||||
protected function getInitialGravity() : float{ return 0.04; }
|
||||
|
||||
public function getFuse() : int{
|
||||
return $this->fuse;
|
||||
}
|
||||
|
@ -52,23 +52,11 @@ class Arrow extends Projectile{
|
||||
private const TAG_PICKUP = "pickup"; //TAG_Byte
|
||||
public const TAG_CRIT = "crit"; //TAG_Byte
|
||||
|
||||
protected $gravity = 0.05;
|
||||
protected $drag = 0.01;
|
||||
|
||||
/** @var float */
|
||||
protected $damage = 2.0;
|
||||
|
||||
/** @var int */
|
||||
protected $pickupMode = self::PICKUP_ANY;
|
||||
|
||||
/** @var float */
|
||||
protected $punchKnockback = 0.0;
|
||||
|
||||
/** @var int */
|
||||
protected $collideTicks = 0;
|
||||
|
||||
/** @var bool */
|
||||
protected $critical = false;
|
||||
protected float $damage = 2.0;
|
||||
protected int $pickupMode = self::PICKUP_ANY;
|
||||
protected float $punchKnockback = 0.0;
|
||||
protected int $collideTicks = 0;
|
||||
protected bool $critical = false;
|
||||
|
||||
public function __construct(Location $location, ?Entity $shootingEntity, bool $critical, ?CompoundTag $nbt = null){
|
||||
parent::__construct($location, $shootingEntity, $nbt);
|
||||
@ -77,6 +65,10 @@ class Arrow extends Projectile{
|
||||
|
||||
protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.25, 0.25); }
|
||||
|
||||
protected function getInitialDragMultiplier() : float{ return 0.01; }
|
||||
|
||||
protected function getInitialGravity() : float{ return 0.05; }
|
||||
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
parent::initEntity($nbt);
|
||||
|
||||
|
@ -32,7 +32,7 @@ use function mt_rand;
|
||||
class ExperienceBottle extends Throwable{
|
||||
public static function getNetworkTypeId() : string{ return EntityIds::XP_BOTTLE; }
|
||||
|
||||
protected $gravity = 0.07;
|
||||
protected function getInitialGravity() : float{ return 0.07; }
|
||||
|
||||
public function getResultDamage() : int{
|
||||
return -1;
|
||||
|
@ -51,11 +51,8 @@ use const PHP_INT_MAX;
|
||||
|
||||
abstract class Projectile extends Entity{
|
||||
|
||||
/** @var float */
|
||||
protected $damage = 0.0;
|
||||
|
||||
/** @var Block|null */
|
||||
protected $blockHit;
|
||||
protected float $damage = 0.0;
|
||||
protected ?Block $blockHit = null;
|
||||
|
||||
public function __construct(Location $location, ?Entity $shootingEntity, ?CompoundTag $nbt = null){
|
||||
parent::__construct($location, $nbt);
|
||||
|
@ -52,11 +52,7 @@ class SplashPotion extends Throwable{
|
||||
|
||||
public static function getNetworkTypeId() : string{ return EntityIds::SPLASH_POTION; }
|
||||
|
||||
protected $gravity = 0.05;
|
||||
protected $drag = 0.01;
|
||||
|
||||
/** @var bool */
|
||||
protected $linger = false;
|
||||
protected bool $linger = false;
|
||||
protected PotionType $potionType;
|
||||
|
||||
public function __construct(Location $location, ?Entity $shootingEntity, PotionType $potionType, ?CompoundTag $nbt = null){
|
||||
@ -64,6 +60,8 @@ class SplashPotion extends Throwable{
|
||||
parent::__construct($location, $shootingEntity, $nbt);
|
||||
}
|
||||
|
||||
protected function getInitialGravity() : float{ return 0.05; }
|
||||
|
||||
public function saveNBT() : CompoundTag{
|
||||
$nbt = parent::saveNBT();
|
||||
$nbt->setShort("PotionId", PotionTypeIdMap::getInstance()->toId($this->getPotionType()));
|
||||
|
@ -29,11 +29,12 @@ use pocketmine\math\RayTraceResult;
|
||||
|
||||
abstract class Throwable extends Projectile{
|
||||
|
||||
protected $gravity = 0.03;
|
||||
protected $drag = 0.01;
|
||||
|
||||
protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.25, 0.25); }
|
||||
|
||||
protected function getInitialDragMultiplier() : float{ return 0.01; }
|
||||
|
||||
protected function getInitialGravity() : float{ return 0.03; }
|
||||
|
||||
protected function onHitBlock(Block $blockHit, RayTraceResult $hitResult) : void{
|
||||
parent::onHitBlock($blockHit, $hitResult);
|
||||
$this->flagForDespawn();
|
||||
|
@ -241,8 +241,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
|
||||
protected ?float $lastMovementProcess = null;
|
||||
|
||||
protected int $inAirTicks = 0;
|
||||
/** @var float */
|
||||
protected $stepHeight = 0.6;
|
||||
|
||||
protected float $stepHeight = 0.6;
|
||||
|
||||
protected ?Vector3 $sleeping = null;
|
||||
private ?Position $spawnPosition = null;
|
||||
@ -2217,16 +2217,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
|
||||
$this->getWorld()->dropItem($this->location, $item);
|
||||
}
|
||||
|
||||
if($this->inventory !== null){
|
||||
$this->inventory->setHeldItemIndex(0);
|
||||
$this->inventory->clearAll();
|
||||
}
|
||||
if($this->armorInventory !== null){
|
||||
$this->armorInventory->clearAll();
|
||||
}
|
||||
if($this->offHandInventory !== null){
|
||||
$this->offHandInventory->clearAll();
|
||||
}
|
||||
$this->inventory->setHeldItemIndex(0);
|
||||
$this->inventory->clearAll();
|
||||
$this->armorInventory->clearAll();
|
||||
$this->offHandInventory->clearAll();
|
||||
}
|
||||
|
||||
if(!$ev->getKeepXp()){
|
||||
|
@ -28,16 +28,9 @@ use pocketmine\utils\AssumptionFailedError;
|
||||
use function assert;
|
||||
|
||||
class Position extends Vector3{
|
||||
public ?World $world = null;
|
||||
|
||||
/** @var World|null */
|
||||
public $world = null;
|
||||
|
||||
/**
|
||||
* @param float|int $x
|
||||
* @param float|int $y
|
||||
* @param float|int $z
|
||||
*/
|
||||
public function __construct($x, $y, $z, ?World $world){
|
||||
public function __construct(float|int $x, float|int $y, float|int $z, ?World $world){
|
||||
parent::__construct($x, $y, $z);
|
||||
if($world !== null && !$world->isLoaded()){
|
||||
throw new \InvalidArgumentException("Specified world has been unloaded and cannot be used");
|
||||
|
@ -1904,11 +1904,9 @@ class World implements ChunkManager{
|
||||
public function getCollidingEntities(AxisAlignedBB $bb, ?Entity $entity = null) : array{
|
||||
$nearby = [];
|
||||
|
||||
if($entity === null || $entity->canCollide){
|
||||
foreach($this->getNearbyEntities($bb, $entity) as $ent){
|
||||
if($ent->canBeCollidedWith() && ($entity === null || $entity->canCollideWith($ent))){
|
||||
$nearby[] = $ent;
|
||||
}
|
||||
foreach($this->getNearbyEntities($bb, $entity) as $ent){
|
||||
if($ent->canBeCollidedWith() && ($entity === null || $entity->canCollideWith($ent))){
|
||||
$nearby[] = $ent;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,9 +64,6 @@ class RegionLoader{
|
||||
|
||||
public const FIRST_SECTOR = 2; //location table occupies 0 and 1
|
||||
|
||||
/** @var int */
|
||||
public static $COMPRESSION_LEVEL = 7;
|
||||
|
||||
/** @var string */
|
||||
protected $filePath;
|
||||
/** @var resource */
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit e884a4c234629126203e769df7c4dbbbc0dc2d49
|
||||
Subproject commit 1b264da3d244cd9b0030cbc3d584d2f685648bfe
|
@ -2,7 +2,7 @@ name: TesterPlugin
|
||||
main: pmmp\TesterPlugin\Main
|
||||
src-namespace-prefix: pmmp\TesterPlugin
|
||||
version: 0.1.0
|
||||
api: [3.2.0, 4.0.0]
|
||||
api: [5.0.0]
|
||||
load: POSTWORLD
|
||||
author: pmmp
|
||||
description: Plugin used to run tests on PocketMine-MP
|
||||
|
Loading…
x
Reference in New Issue
Block a user