mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-28 14:19:53 +00:00
Fixed possible memory leak with projectiles, use owner/target metadata
This commit is contained in:
parent
c383c7b0dd
commit
4ccd955647
@ -37,14 +37,9 @@ class Arrow extends Projectile{
|
|||||||
protected $gravity = 0.05;
|
protected $gravity = 0.05;
|
||||||
protected $drag = 0.01;
|
protected $drag = 0.01;
|
||||||
|
|
||||||
protected $damage = 2;
|
public function __construct(Level $level, CompoundTag $nbt, Entity $shootingEntity = null, bool $critical = false){
|
||||||
|
|
||||||
protected $isCritical;
|
|
||||||
|
|
||||||
public function __construct(Level $level, CompoundTag $nbt, Entity $shootingEntity = null, $critical = false){
|
|
||||||
$this->isCritical = (bool) $critical;
|
|
||||||
parent::__construct($level, $nbt, $shootingEntity);
|
parent::__construct($level, $nbt, $shootingEntity);
|
||||||
$this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_CRITICAL, $critical);
|
$this->setCritical($critical);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isCritical() : bool{
|
public function isCritical() : bool{
|
||||||
|
@ -533,6 +533,80 @@ abstract class Entity extends Location implements Metadatable{
|
|||||||
$this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_WALLCLIMBING, $value);
|
$this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_WALLCLIMBING, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the entity ID of the owning entity, or null if the entity doesn't have an owner.
|
||||||
|
* @return int|string|null
|
||||||
|
*/
|
||||||
|
public function getOwningEntityId(){
|
||||||
|
return $this->getDataProperty(self::DATA_OWNER_EID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the owning entity, or null if the entity was not found.
|
||||||
|
* @return Entity|null
|
||||||
|
*/
|
||||||
|
public function getOwningEntity(){
|
||||||
|
$eid = $this->getOwningEntityId();
|
||||||
|
if($eid !== null){
|
||||||
|
return $this->server->findEntity($eid, $this->level);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the owner of the entity.
|
||||||
|
*
|
||||||
|
* @param Entity $owner
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException if the supplied entity is not valid
|
||||||
|
*/
|
||||||
|
public function setOwningEntity(Entity $owner){
|
||||||
|
if($owner->closed){
|
||||||
|
throw new \InvalidArgumentException("Supplied owning entity is garbage and cannot be used");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->setDataProperty(self::DATA_OWNER_EID, self::DATA_TYPE_LONG, $owner->getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the entity ID of the entity's target, or null if it doesn't have a target.
|
||||||
|
* @return int|string|null
|
||||||
|
*/
|
||||||
|
public function getTargetEntityId(){
|
||||||
|
return $this->getDataProperty(self::DATA_TARGET_EID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the entity's target entity, or null if not found.
|
||||||
|
* This is used for things like hostile mobs attacking entities, and for fishing rods reeling hit entities in.
|
||||||
|
*
|
||||||
|
* @return Entity|null
|
||||||
|
*/
|
||||||
|
public function getTargetEntity(){
|
||||||
|
$eid = $this->getTargetEntityId();
|
||||||
|
if($eid !== null){
|
||||||
|
return $this->server->findEntity($eid, $this->level);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the entity's target entity.
|
||||||
|
*
|
||||||
|
* @param Entity $target
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException if the target entity is not valid
|
||||||
|
*/
|
||||||
|
public function setTargetEntity(Entity $target){
|
||||||
|
if($target->closed){
|
||||||
|
throw new \InvalidArgumentException("Supplied target entity is garbage and cannot be used");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->setDataProperty(self::DATA_TARGET_EID, self::DATA_TYPE_LONG, $target->getId());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Effect[]
|
* @return Effect[]
|
||||||
*/
|
*/
|
||||||
|
@ -36,16 +36,13 @@ abstract class Projectile extends Entity{
|
|||||||
|
|
||||||
const DATA_SHOOTER_ID = 17;
|
const DATA_SHOOTER_ID = 17;
|
||||||
|
|
||||||
/** @var Entity */
|
|
||||||
public $shootingEntity = null;
|
|
||||||
protected $damage = 0;
|
protected $damage = 0;
|
||||||
|
|
||||||
public $hadCollision = false;
|
public $hadCollision = false;
|
||||||
|
|
||||||
public function __construct(Level $level, CompoundTag $nbt, Entity $shootingEntity = null){
|
public function __construct(Level $level, CompoundTag $nbt, Entity $shootingEntity = null){
|
||||||
$this->shootingEntity = $shootingEntity;
|
|
||||||
if($shootingEntity !== null){
|
if($shootingEntity !== null){
|
||||||
$this->setDataProperty(self::DATA_SHOOTER_ID, self::DATA_TYPE_LONG, $shootingEntity->getId());
|
$this->setOwningEntity($shootingEntity);
|
||||||
}
|
}
|
||||||
parent::__construct($level, $nbt);
|
parent::__construct($level, $nbt);
|
||||||
}
|
}
|
||||||
@ -83,10 +80,10 @@ abstract class Projectile extends Entity{
|
|||||||
|
|
||||||
$damage = $this->getResultDamage();
|
$damage = $this->getResultDamage();
|
||||||
|
|
||||||
if($this->shootingEntity === null){
|
if($this->getOwningEntity() === null){
|
||||||
$ev = new EntityDamageByEntityEvent($this, $entity, EntityDamageEvent::CAUSE_PROJECTILE, $damage);
|
$ev = new EntityDamageByEntityEvent($this, $entity, EntityDamageEvent::CAUSE_PROJECTILE, $damage);
|
||||||
}else{
|
}else{
|
||||||
$ev = new EntityDamageByChildEntityEvent($this->shootingEntity, $this, $entity, EntityDamageEvent::CAUSE_PROJECTILE, $damage);
|
$ev = new EntityDamageByChildEntityEvent($this->getOwningEntity(), $this, $entity, EntityDamageEvent::CAUSE_PROJECTILE, $damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
$entity->attack($ev->getFinalDamage(), $ev);
|
$entity->attack($ev->getFinalDamage(), $ev);
|
||||||
@ -140,7 +137,7 @@ abstract class Projectile extends Entity{
|
|||||||
|
|
||||||
foreach($list as $entity){
|
foreach($list as $entity){
|
||||||
if(/*!$entity->canCollideWith($this) or */
|
if(/*!$entity->canCollideWith($this) or */
|
||||||
($entity === $this->shootingEntity and $this->ticksLived < 5)
|
($entity->getId() === $this->getOwningEntityId() and $this->ticksLived < 5)
|
||||||
){
|
){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user