mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-12 22:45:28 +00:00
Entity: replace separate height/width/eyeHeight fields with an EntitySizeInfo structure
this will make it easier to implement stuff like sleeping (properly), swimming and gliding without needing to duplicate all the fields.
This commit is contained in:
parent
574b615b4c
commit
e53b57732b
@ -118,13 +118,8 @@ abstract class Entity{
|
||||
/** @var bool */
|
||||
public $onGround = false;
|
||||
|
||||
/** @var float */
|
||||
public $eyeHeight = null;
|
||||
|
||||
/** @var float */
|
||||
public $height;
|
||||
/** @var float */
|
||||
public $width;
|
||||
/** @var EntitySizeInfo */
|
||||
public $size;
|
||||
|
||||
/** @var float */
|
||||
private $health = 20.0;
|
||||
@ -218,9 +213,7 @@ abstract class Entity{
|
||||
public function __construct(Location $location, ?CompoundTag $nbt = null){
|
||||
$this->timings = Timings::getEntityTimings($this);
|
||||
|
||||
if($this->eyeHeight === null){
|
||||
$this->eyeHeight = $this->height / 2 + 0.1;
|
||||
}
|
||||
$this->size = $this->getInitialSizeInfo();
|
||||
|
||||
$this->id = self::nextRuntimeId();
|
||||
$this->server = $location->getWorld()->getServer();
|
||||
@ -259,6 +252,8 @@ abstract class Entity{
|
||||
|
||||
}
|
||||
|
||||
abstract protected function getInitialSizeInfo() : EntitySizeInfo;
|
||||
|
||||
public function getNameTag() : string{
|
||||
return $this->nameTag;
|
||||
}
|
||||
@ -299,11 +294,7 @@ abstract class Entity{
|
||||
if($value <= 0){
|
||||
throw new \InvalidArgumentException("Scale must be greater than 0");
|
||||
}
|
||||
$multiplier = $value / $this->getScale();
|
||||
|
||||
$this->width *= $multiplier;
|
||||
$this->height *= $multiplier;
|
||||
$this->eyeHeight *= $multiplier;
|
||||
$this->size = $this->getInitialSizeInfo()->scale($value);
|
||||
|
||||
$this->scale = $value;
|
||||
|
||||
@ -315,14 +306,14 @@ abstract class Entity{
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox() : void{
|
||||
$halfWidth = $this->width / 2;
|
||||
$halfWidth = $this->size->getWidth() / 2;
|
||||
|
||||
$this->boundingBox = new AxisAlignedBB(
|
||||
$this->location->x - $halfWidth,
|
||||
$this->location->y + $this->ySize,
|
||||
$this->location->z - $halfWidth,
|
||||
$this->location->x + $halfWidth,
|
||||
$this->location->y + $this->height + $this->ySize,
|
||||
$this->location->y + $this->size->getHeight() + $this->ySize,
|
||||
$this->location->z + $halfWidth
|
||||
);
|
||||
}
|
||||
@ -1042,7 +1033,7 @@ abstract class Entity{
|
||||
}
|
||||
|
||||
public function getEyeHeight() : float{
|
||||
return $this->eyeHeight;
|
||||
return $this->size->getEyeHeight();
|
||||
}
|
||||
|
||||
public function getEyePos() : Vector3{
|
||||
@ -1585,8 +1576,8 @@ abstract class Entity{
|
||||
|
||||
protected function syncNetworkData(EntityMetadataCollection $properties) : void{
|
||||
$properties->setByte(EntityMetadataProperties::ALWAYS_SHOW_NAMETAG, $this->alwaysShowNameTag ? 1 : 0);
|
||||
$properties->setFloat(EntityMetadataProperties::BOUNDING_BOX_HEIGHT, $this->height);
|
||||
$properties->setFloat(EntityMetadataProperties::BOUNDING_BOX_WIDTH, $this->width);
|
||||
$properties->setFloat(EntityMetadataProperties::BOUNDING_BOX_HEIGHT, $this->size->getHeight());
|
||||
$properties->setFloat(EntityMetadataProperties::BOUNDING_BOX_WIDTH, $this->size->getWidth());
|
||||
$properties->setFloat(EntityMetadataProperties::SCALE, $this->scale);
|
||||
$properties->setLong(EntityMetadataProperties::LEAD_HOLDER_EID, -1);
|
||||
$properties->setLong(EntityMetadataProperties::OWNER_EID, $this->ownerId ?? -1);
|
||||
|
53
src/entity/EntitySizeInfo.php
Normal file
53
src/entity/EntitySizeInfo.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?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\entity;
|
||||
|
||||
final class EntitySizeInfo{
|
||||
/** @var float */
|
||||
private $height;
|
||||
/** @var float */
|
||||
private $width;
|
||||
/** @var float */
|
||||
private $eyeHeight;
|
||||
|
||||
public function __construct(float $height, float $width, ?float $eyeHeight = null){
|
||||
$this->height = $height;
|
||||
$this->width = $width;
|
||||
$this->eyeHeight = $eyeHeight ?? min($this->height / 2 + 0.1, $this->height);
|
||||
}
|
||||
|
||||
public function getHeight() : float{ return $this->height; }
|
||||
|
||||
public function getWidth() : float{ return $this->width; }
|
||||
|
||||
public function getEyeHeight() : float{ return $this->eyeHeight; }
|
||||
|
||||
public function scale(float $newScale) : self{
|
||||
return new self(
|
||||
$this->height * $newScale,
|
||||
$this->width * $newScale,
|
||||
$this->eyeHeight * $newScale
|
||||
);
|
||||
}
|
||||
}
|
@ -74,10 +74,6 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
|
||||
/** @var UUID */
|
||||
protected $uuid;
|
||||
|
||||
public $width = 0.6;
|
||||
public $height = 1.8;
|
||||
public $eyeHeight = 1.62;
|
||||
|
||||
/** @var Skin */
|
||||
protected $skin;
|
||||
|
||||
@ -94,6 +90,8 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
|
||||
parent::__construct($location, $nbt);
|
||||
}
|
||||
|
||||
protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(1.8, 0.6, 1.62); }
|
||||
|
||||
/**
|
||||
* @throws InvalidSkinException
|
||||
* @throws \UnexpectedValueException
|
||||
|
@ -715,7 +715,7 @@ abstract class Living extends Entity{
|
||||
$blocks = [];
|
||||
$nextIndex = 0;
|
||||
|
||||
foreach(VoxelRayTrace::inDirection($this->location->add(0, $this->eyeHeight, 0), $this->getDirectionVector(), $maxDistance) as $vector3){
|
||||
foreach(VoxelRayTrace::inDirection($this->location->add(0, $this->size->getEyeHeight(), 0), $this->getDirectionVector(), $maxDistance) as $vector3){
|
||||
$block = $this->getWorld()->getBlockAt($vector3->x, $vector3->y, $vector3->z);
|
||||
$blocks[$nextIndex++] = $block;
|
||||
|
||||
|
@ -39,9 +39,6 @@ class Squid extends WaterAnimal{
|
||||
|
||||
public static function getNetworkTypeId() : string{ return EntityIds::SQUID; }
|
||||
|
||||
public $width = 0.95;
|
||||
public $height = 0.95;
|
||||
|
||||
/** @var Vector3|null */
|
||||
public $swimDirection = null;
|
||||
/** @var float */
|
||||
@ -50,6 +47,8 @@ class Squid extends WaterAnimal{
|
||||
/** @var int */
|
||||
private $switchDirectionTicker = 0;
|
||||
|
||||
protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.95, 0.95); }
|
||||
|
||||
public function initEntity(CompoundTag $nbt) : void{
|
||||
$this->setMaxHealth(10);
|
||||
parent::initEntity($nbt);
|
||||
|
@ -38,14 +38,15 @@ class Villager extends Living implements Ageable{
|
||||
|
||||
public static function getNetworkTypeId() : string{ return EntityIds::VILLAGER; }
|
||||
|
||||
public $width = 0.6;
|
||||
public $height = 1.8;
|
||||
|
||||
/** @var bool */
|
||||
private $baby = false;
|
||||
/** @var int */
|
||||
private $profession = self::PROFESSION_FARMER;
|
||||
|
||||
protected function getInitialSizeInfo() : EntitySizeInfo{
|
||||
return new EntitySizeInfo(1.8, 0.6); //TODO: eye height??
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
return "Villager";
|
||||
}
|
||||
|
@ -31,8 +31,9 @@ class Zombie extends Living{
|
||||
|
||||
public static function getNetworkTypeId() : string{ return EntityIds::ZOMBIE; }
|
||||
|
||||
public $width = 0.6;
|
||||
public $height = 1.8;
|
||||
protected function getInitialSizeInfo() : EntitySizeInfo{
|
||||
return new EntitySizeInfo(1.8, 0.6); //TODO: eye height ??
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
return "Zombie";
|
||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\entity\object;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\EntitySizeInfo;
|
||||
use pocketmine\entity\Human;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\IntTag;
|
||||
@ -78,9 +79,6 @@ class ExperienceOrb extends Entity{
|
||||
return $result;
|
||||
}
|
||||
|
||||
public $height = 0.25;
|
||||
public $width = 0.25;
|
||||
|
||||
public $gravity = 0.04;
|
||||
public $drag = 0.02;
|
||||
|
||||
@ -102,6 +100,8 @@ class ExperienceOrb extends Entity{
|
||||
/** @var int */
|
||||
protected $xpValue = 1;
|
||||
|
||||
protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.25, 0.25); }
|
||||
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
parent::initEntity($nbt);
|
||||
|
||||
|
@ -27,6 +27,7 @@ use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\block\utils\Fallable;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\EntitySizeInfo;
|
||||
use pocketmine\entity\Location;
|
||||
use pocketmine\event\entity\EntityBlockChangeEvent;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
@ -44,9 +45,6 @@ class FallingBlock extends Entity{
|
||||
|
||||
public static function getNetworkTypeId() : string{ return EntityIds::FALLING_BLOCK; }
|
||||
|
||||
public $width = 0.98;
|
||||
public $height = 0.98;
|
||||
|
||||
protected $gravity = 0.04;
|
||||
protected $drag = 0.02;
|
||||
|
||||
@ -60,6 +58,8 @@ class FallingBlock extends Entity{
|
||||
parent::__construct($location, $nbt);
|
||||
}
|
||||
|
||||
protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.98, 0.98); }
|
||||
|
||||
public static function parseBlockNBT(BlockFactory $factory, CompoundTag $nbt) : Block{
|
||||
$blockId = 0;
|
||||
|
||||
@ -102,7 +102,7 @@ class FallingBlock extends Entity{
|
||||
|
||||
if(!$this->isFlaggedForDespawn()){
|
||||
$world = $this->getWorld();
|
||||
$pos = $this->location->add(-$this->width / 2, $this->height, -$this->width / 2)->floor();
|
||||
$pos = $this->location->add(-$this->size->getWidth() / 2, $this->size->getHeight(), -$this->size->getWidth() / 2)->floor();
|
||||
|
||||
$this->block->position($world, $pos->x, $pos->y, $pos->z);
|
||||
|
||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\entity\object;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\EntitySizeInfo;
|
||||
use pocketmine\entity\Location;
|
||||
use pocketmine\event\entity\ItemDespawnEvent;
|
||||
use pocketmine\event\entity\ItemSpawnEvent;
|
||||
@ -54,9 +55,6 @@ class ItemEntity extends Entity{
|
||||
/** @var Item */
|
||||
protected $item;
|
||||
|
||||
public $width = 0.25;
|
||||
public $height = 0.25;
|
||||
|
||||
protected $gravity = 0.04;
|
||||
protected $drag = 0.02;
|
||||
|
||||
@ -73,6 +71,8 @@ class ItemEntity extends Entity{
|
||||
parent::__construct($location, $nbt);
|
||||
}
|
||||
|
||||
protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.25, 0.25); }
|
||||
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
parent::initEntity($nbt);
|
||||
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\entity\object;
|
||||
|
||||
use pocketmine\block\VanillaBlocks;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\EntitySizeInfo;
|
||||
use pocketmine\entity\Location;
|
||||
use pocketmine\event\entity\EntityDamageByEntityEvent;
|
||||
use pocketmine\item\VanillaItems;
|
||||
@ -60,12 +61,6 @@ class Painting extends Entity{
|
||||
/** @var float */
|
||||
protected $drag = 1.0;
|
||||
|
||||
//these aren't accurate, but it doesn't matter since they aren't used (vanilla PC does something similar)
|
||||
/** @var float */
|
||||
public $height = 0.5;
|
||||
/** @var float */
|
||||
public $width = 0.5;
|
||||
|
||||
/** @var Vector3 */
|
||||
protected $blockIn;
|
||||
/** @var int */
|
||||
@ -80,6 +75,11 @@ class Painting extends Entity{
|
||||
parent::__construct($location, $nbt);
|
||||
}
|
||||
|
||||
protected function getInitialSizeInfo() : EntitySizeInfo{
|
||||
//these aren't accurate, but it doesn't matter since they aren't used (vanilla PC does something similar)
|
||||
return new EntitySizeInfo(0.5, 0.5);
|
||||
}
|
||||
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
$this->setMaxHealth(1);
|
||||
$this->setHealth(1);
|
||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\entity\object;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\EntitySizeInfo;
|
||||
use pocketmine\entity\Explosive;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\event\entity\ExplosionPrimeEvent;
|
||||
@ -40,9 +41,6 @@ class PrimedTNT extends Entity implements Explosive{
|
||||
|
||||
public static function getNetworkTypeId() : string{ return EntityIds::TNT; }
|
||||
|
||||
public $width = 0.98;
|
||||
public $height = 0.98;
|
||||
|
||||
protected $gravity = 0.04;
|
||||
protected $drag = 0.02;
|
||||
|
||||
@ -51,6 +49,8 @@ class PrimedTNT extends Entity implements Explosive{
|
||||
|
||||
public $canCollide = false;
|
||||
|
||||
protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.98, 0.98); }
|
||||
|
||||
public function getFuse() : int{
|
||||
return $this->fuse;
|
||||
}
|
||||
@ -108,7 +108,7 @@ class PrimedTNT extends Entity implements Explosive{
|
||||
$ev = new ExplosionPrimeEvent($this, 4);
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$explosion = new Explosion(Position::fromObject($this->location->add(0, $this->height / 2, 0), $this->getWorld()), $ev->getForce(), $this);
|
||||
$explosion = new Explosion(Position::fromObject($this->location->add(0, $this->size->getHeight() / 2, 0), $this->getWorld()), $ev->getForce(), $this);
|
||||
if($ev->isBlockBreaking()){
|
||||
$explosion->explodeA();
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ namespace pocketmine\entity\projectile;
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\entity\animation\ArrowShakeAnimation;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\EntitySizeInfo;
|
||||
use pocketmine\entity\Location;
|
||||
use pocketmine\event\entity\ProjectileHitEvent;
|
||||
use pocketmine\event\inventory\InventoryPickupArrowEvent;
|
||||
@ -50,9 +51,6 @@ class Arrow extends Projectile{
|
||||
|
||||
private const TAG_PICKUP = "pickup"; //TAG_Byte
|
||||
|
||||
public $width = 0.25;
|
||||
public $height = 0.25;
|
||||
|
||||
protected $gravity = 0.05;
|
||||
protected $drag = 0.01;
|
||||
|
||||
@ -76,6 +74,8 @@ class Arrow extends Projectile{
|
||||
$this->setCritical($critical);
|
||||
}
|
||||
|
||||
protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.25, 0.25); }
|
||||
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
parent::initEntity($nbt);
|
||||
|
||||
|
@ -24,16 +24,16 @@ declare(strict_types=1);
|
||||
namespace pocketmine\entity\projectile;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\entity\EntitySizeInfo;
|
||||
use pocketmine\math\RayTraceResult;
|
||||
|
||||
abstract class Throwable extends Projectile{
|
||||
|
||||
public $width = 0.25;
|
||||
public $height = 0.25;
|
||||
|
||||
protected $gravity = 0.03;
|
||||
protected $drag = 0.01;
|
||||
|
||||
protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.25, 0.25); }
|
||||
|
||||
protected function onHitBlock(Block $blockHit, RayTraceResult $hitResult) : void{
|
||||
parent::onHitBlock($blockHit, $hitResult);
|
||||
$this->flagForDespawn();
|
||||
|
@ -1657,7 +1657,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
|
||||
|
||||
$entity->attack($ev);
|
||||
|
||||
$soundPos = $entity->getPosition()->add(0, $entity->height / 2, 0);
|
||||
$soundPos = $entity->getPosition()->add(0, $entity->size->getHeight() / 2, 0);
|
||||
if($ev->isCancelled()){
|
||||
$this->getWorld()->addSound($soundPos, new EntityAttackNoDamageSound());
|
||||
return false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user