mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-10-18 04:00:29 +00:00
Extract mandatory parameters into constructor parameters
the goal is obviously to ditch NBT entirely here, but there's more work to be done before that becomes possible.
This commit is contained in:
@@ -213,7 +213,7 @@ abstract class Entity{
|
||||
/** @var int|null */
|
||||
protected $targetId = null;
|
||||
|
||||
public function __construct(World $world, CompoundTag $nbt){
|
||||
public function __construct(Location $location, CompoundTag $nbt){
|
||||
$this->timings = Timings::getEntityTimings($this);
|
||||
|
||||
$this->temporalVector = new Vector3();
|
||||
@@ -223,14 +223,9 @@ abstract class Entity{
|
||||
}
|
||||
|
||||
$this->id = EntityFactory::nextRuntimeId();
|
||||
$this->server = $world->getServer();
|
||||
$this->server = $location->getWorldNonNull()->getServer();
|
||||
|
||||
/** @var float[] $pos */
|
||||
$pos = $nbt->getListTag("Pos")->getAllValues();
|
||||
/** @var float[] $rotation */
|
||||
$rotation = $nbt->getListTag("Rotation")->getAllValues();
|
||||
|
||||
$this->location = new Location($pos[0], $pos[1], $pos[2], $rotation[0], $rotation[1], $world);
|
||||
$this->location = $location->asLocation();
|
||||
assert(
|
||||
!is_nan($this->location->x) and !is_infinite($this->location->x) and
|
||||
!is_nan($this->location->y) and !is_infinite($this->location->y) and
|
||||
|
@@ -26,6 +26,7 @@ namespace pocketmine\entity;
|
||||
use DaveRandom\CallbackValidator\CallbackType;
|
||||
use DaveRandom\CallbackValidator\ParameterType;
|
||||
use DaveRandom\CallbackValidator\ReturnType;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\entity\object\ExperienceOrb;
|
||||
use pocketmine\entity\object\FallingBlock;
|
||||
use pocketmine\entity\object\ItemEntity;
|
||||
@@ -38,7 +39,11 @@ use pocketmine\entity\projectile\EnderPearl;
|
||||
use pocketmine\entity\projectile\ExperienceBottle;
|
||||
use pocketmine\entity\projectile\Snowball;
|
||||
use pocketmine\entity\projectile\SplashPotion;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\NBT;
|
||||
use pocketmine\nbt\tag\ByteTag;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\DoubleTag;
|
||||
use pocketmine\nbt\tag\FloatTag;
|
||||
@@ -50,6 +55,7 @@ use pocketmine\utils\SingletonTrait;
|
||||
use pocketmine\utils\Utils;
|
||||
use pocketmine\world\World;
|
||||
use function array_keys;
|
||||
use function count;
|
||||
use function in_array;
|
||||
use function reset;
|
||||
|
||||
@@ -84,63 +90,85 @@ final class EntityFactory{
|
||||
//TODO: index them by version to allow proper multi-save compatibility
|
||||
|
||||
$this->register(Arrow::class, function(World $world, CompoundTag $nbt) : Arrow{
|
||||
return new Arrow($world, $nbt);
|
||||
return new Arrow(self::parseLocation($nbt, $world), null, false, $nbt); //TODO: missing critical flag
|
||||
}, ['Arrow', 'minecraft:arrow'], EntityLegacyIds::ARROW);
|
||||
|
||||
$this->register(Egg::class, function(World $world, CompoundTag $nbt) : Egg{
|
||||
return new Egg($world, $nbt);
|
||||
return new Egg(self::parseLocation($nbt, $world), null, $nbt);
|
||||
}, ['Egg', 'minecraft:egg'], EntityLegacyIds::EGG);
|
||||
|
||||
$this->register(EnderPearl::class, function(World $world, CompoundTag $nbt) : EnderPearl{
|
||||
return new EnderPearl($world, $nbt);
|
||||
return new EnderPearl(self::parseLocation($nbt, $world), null, $nbt);
|
||||
}, ['ThrownEnderpearl', 'minecraft:ender_pearl'], EntityLegacyIds::ENDER_PEARL);
|
||||
|
||||
$this->register(ExperienceBottle::class, function(World $world, CompoundTag $nbt) : ExperienceBottle{
|
||||
return new ExperienceBottle($world, $nbt);
|
||||
return new ExperienceBottle(self::parseLocation($nbt, $world), null, $nbt);
|
||||
}, ['ThrownExpBottle', 'minecraft:xp_bottle'], EntityLegacyIds::XP_BOTTLE);
|
||||
|
||||
$this->register(ExperienceOrb::class, function(World $world, CompoundTag $nbt) : ExperienceOrb{
|
||||
return new ExperienceOrb($world, $nbt);
|
||||
return new ExperienceOrb(self::parseLocation($nbt, $world), $nbt);
|
||||
}, ['XPOrb', 'minecraft:xp_orb'], EntityLegacyIds::XP_ORB);
|
||||
|
||||
$this->register(FallingBlock::class, function(World $world, CompoundTag $nbt) : FallingBlock{
|
||||
return new FallingBlock($world, $nbt);
|
||||
return new FallingBlock(self::parseLocation($nbt, $world), FallingBlock::parseBlockNBT(BlockFactory::getInstance(), $nbt), $nbt);
|
||||
}, ['FallingSand', 'minecraft:falling_block'], EntityLegacyIds::FALLING_BLOCK);
|
||||
|
||||
$this->register(ItemEntity::class, function(World $world, CompoundTag $nbt) : ItemEntity{
|
||||
return new ItemEntity($world, $nbt);
|
||||
$itemTag = $nbt->getCompoundTag("Item");
|
||||
if($itemTag === null){
|
||||
throw new \UnexpectedValueException("Expected \"Item\" NBT tag not found");
|
||||
}
|
||||
|
||||
$item = Item::nbtDeserialize($itemTag);
|
||||
if($item->isNull()){
|
||||
throw new \UnexpectedValueException("Item is invalid");
|
||||
}
|
||||
return new ItemEntity(self::parseLocation($nbt, $world), $item, $nbt);
|
||||
}, ['Item', 'minecraft:item'], EntityLegacyIds::ITEM);
|
||||
|
||||
$this->register(Painting::class, function(World $world, CompoundTag $nbt) : Painting{
|
||||
return new Painting($world, $nbt);
|
||||
$motive = PaintingMotive::getMotiveByName($nbt->getString("Motive"));
|
||||
if($motive === null){
|
||||
throw new \UnexpectedValueException("Unknown painting motive");
|
||||
}
|
||||
$blockIn = new Vector3($nbt->getInt("TileX"), $nbt->getInt("TileY"), $nbt->getInt("TileZ"));
|
||||
if($nbt->hasTag("Direction", ByteTag::class)){
|
||||
$facing = Painting::DATA_TO_FACING[$nbt->getByte("Direction")] ?? Facing::NORTH;
|
||||
}elseif($nbt->hasTag("Facing", ByteTag::class)){
|
||||
$facing = Painting::DATA_TO_FACING[$nbt->getByte("Facing")] ?? Facing::NORTH;
|
||||
}else{
|
||||
throw new \UnexpectedValueException("Missing facing info");
|
||||
}
|
||||
|
||||
return new Painting(self::parseLocation($nbt, $world), $blockIn, $facing, $motive, $nbt);
|
||||
}, ['Painting', 'minecraft:painting'], EntityLegacyIds::PAINTING);
|
||||
|
||||
$this->register(PrimedTNT::class, function(World $world, CompoundTag $nbt) : PrimedTNT{
|
||||
return new PrimedTNT($world, $nbt);
|
||||
return new PrimedTNT(self::parseLocation($nbt, $world), $nbt);
|
||||
}, ['PrimedTnt', 'PrimedTNT', 'minecraft:tnt'], EntityLegacyIds::TNT);
|
||||
|
||||
$this->register(Snowball::class, function(World $world, CompoundTag $nbt) : Snowball{
|
||||
return new Snowball($world, $nbt);
|
||||
return new Snowball(self::parseLocation($nbt, $world), null, $nbt);
|
||||
}, ['Snowball', 'minecraft:snowball'], EntityLegacyIds::SNOWBALL);
|
||||
|
||||
$this->register(SplashPotion::class, function(World $world, CompoundTag $nbt) : SplashPotion{
|
||||
return new SplashPotion($world, $nbt);
|
||||
return new SplashPotion(self::parseLocation($nbt, $world), null, $nbt);
|
||||
}, ['ThrownPotion', 'minecraft:potion', 'thrownpotion'], EntityLegacyIds::SPLASH_POTION);
|
||||
|
||||
$this->register(Squid::class, function(World $world, CompoundTag $nbt) : Squid{
|
||||
return new Squid($world, $nbt);
|
||||
return new Squid(self::parseLocation($nbt, $world), $nbt);
|
||||
}, ['Squid', 'minecraft:squid'], EntityLegacyIds::SQUID);
|
||||
|
||||
$this->register(Villager::class, function(World $world, CompoundTag $nbt) : Villager{
|
||||
return new Villager($world, $nbt);
|
||||
return new Villager(self::parseLocation($nbt, $world), $nbt);
|
||||
}, ['Villager', 'minecraft:villager'], EntityLegacyIds::VILLAGER);
|
||||
|
||||
$this->register(Zombie::class, function(World $world, CompoundTag $nbt) : Zombie{
|
||||
return new Zombie($world, $nbt);
|
||||
return new Zombie(self::parseLocation($nbt, $world), $nbt);
|
||||
}, ['Zombie', 'minecraft:zombie'], EntityLegacyIds::ZOMBIE);
|
||||
|
||||
$this->register(Human::class, function(World $world, CompoundTag $nbt) : Human{
|
||||
return new Human($world, $nbt);
|
||||
return new Human(self::parseLocation($nbt, $world), Human::parseSkinNBT($nbt), $nbt);
|
||||
}, ['Human']);
|
||||
|
||||
PaintingMotive::init();
|
||||
@@ -247,6 +275,37 @@ final class EntityFactory{
|
||||
throw new \InvalidArgumentException("Entity $class is not registered");
|
||||
}
|
||||
|
||||
public static function parseLocation(CompoundTag $nbt, World $world) : Location{
|
||||
$pos = self::parseVec3($nbt, "Pos", false);
|
||||
|
||||
$yawPitch = $nbt->getTag("Rotation");
|
||||
if(!($yawPitch instanceof ListTag) or $yawPitch->getTagType() !== NBT::TAG_Float){
|
||||
throw new \UnexpectedValueException("'Rotation' should be a List<Float>");
|
||||
}
|
||||
$values = $yawPitch->getValue();
|
||||
if(count($values) !== 2){
|
||||
throw new \UnexpectedValueException("Expected exactly 2 entries for 'Rotation'");
|
||||
}
|
||||
|
||||
return Location::fromObject($pos, $world, $values[0]->getValue(), $values[1]->getValue());
|
||||
}
|
||||
|
||||
private static function parseVec3(CompoundTag $nbt, string $tagName, bool $optional) : Vector3{
|
||||
$pos = $nbt->getTag($tagName);
|
||||
if($pos === null and $optional){
|
||||
return new Vector3(0, 0, 0);
|
||||
}
|
||||
if(!($pos instanceof ListTag) or $pos->getTagType() !== NBT::TAG_Double){
|
||||
throw new \UnexpectedValueException("'$tagName' should be a List<Double>");
|
||||
}
|
||||
/** @var DoubleTag[] $values */
|
||||
$values = $pos->getValue();
|
||||
if(count($values) !== 3){
|
||||
throw new \UnexpectedValueException("Expected exactly 3 entries in '$tagName' tag");
|
||||
}
|
||||
return new Vector3($values[0]->getValue(), $values[1]->getValue(), $values[2]->getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function which creates minimal NBT needed to spawn an entity.
|
||||
*/
|
||||
|
@@ -55,7 +55,6 @@ use pocketmine\player\Player;
|
||||
use pocketmine\utils\Limits;
|
||||
use pocketmine\uuid\UUID;
|
||||
use pocketmine\world\sound\TotemUseSound;
|
||||
use pocketmine\world\World;
|
||||
use function array_filter;
|
||||
use function array_merge;
|
||||
use function array_values;
|
||||
@@ -94,22 +93,27 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
|
||||
|
||||
protected $baseOffset = 1.62;
|
||||
|
||||
public function __construct(World $world, CompoundTag $nbt){
|
||||
if($this->skin === null){
|
||||
$skinTag = $nbt->getCompoundTag("Skin");
|
||||
if($skinTag === null){
|
||||
throw new \InvalidStateException((new \ReflectionClass($this))->getShortName() . " must have a valid skin set");
|
||||
}
|
||||
$this->skin = new Skin( //this throws if the skin is invalid
|
||||
$skinTag->getString("Name"),
|
||||
$skinTag->hasTag("Data", StringTag::class) ? $skinTag->getString("Data") : $skinTag->getByteArray("Data"), //old data (this used to be saved as a StringTag in older versions of PM)
|
||||
$skinTag->getByteArray("CapeData", ""),
|
||||
$skinTag->getString("GeometryName", ""),
|
||||
$skinTag->getByteArray("GeometryData", "")
|
||||
);
|
||||
}
|
||||
public function __construct(Location $location, Skin $skin, CompoundTag $nbt){
|
||||
$this->skin = $skin;
|
||||
parent::__construct($location, $nbt);
|
||||
}
|
||||
|
||||
parent::__construct($world, $nbt);
|
||||
/**
|
||||
* @throws InvalidSkinException
|
||||
* @throws \UnexpectedValueException
|
||||
*/
|
||||
public static function parseSkinNBT(CompoundTag $nbt) : Skin{
|
||||
$skinTag = $nbt->getCompoundTag("Skin");
|
||||
if($skinTag === null){
|
||||
throw new \UnexpectedValueException("Missing skin data");
|
||||
}
|
||||
return new Skin( //this throws if the skin is invalid
|
||||
$skinTag->getString("Name"),
|
||||
$skinTag->hasTag("Data", StringTag::class) ? $skinTag->getString("Data") : $skinTag->getByteArray("Data"), //old data (this used to be saved as a StringTag in older versions of PM)
|
||||
$skinTag->getByteArray("CapeData", ""),
|
||||
$skinTag->getString("GeometryName", ""),
|
||||
$skinTag->getByteArray("GeometryData", "")
|
||||
);
|
||||
}
|
||||
|
||||
public function getUniqueId() : UUID{
|
||||
|
@@ -27,6 +27,7 @@ use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\block\utils\Fallable;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Location;
|
||||
use pocketmine\event\entity\EntityBlockChangeEvent;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\nbt\tag\ByteTag;
|
||||
@@ -36,7 +37,6 @@ use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds;
|
||||
use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection;
|
||||
use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties;
|
||||
use function abs;
|
||||
use function get_class;
|
||||
|
||||
class FallingBlock extends Entity{
|
||||
|
||||
@@ -55,9 +55,12 @@ class FallingBlock extends Entity{
|
||||
|
||||
public $canCollide = false;
|
||||
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
parent::initEntity($nbt);
|
||||
public function __construct(Location $location, Block $block, CompoundTag $nbt){
|
||||
$this->block = $block;
|
||||
parent::__construct($location, $nbt);
|
||||
}
|
||||
|
||||
public static function parseBlockNBT(BlockFactory $factory, CompoundTag $nbt) : Block{
|
||||
$blockId = 0;
|
||||
|
||||
//TODO: 1.8+ save format
|
||||
@@ -68,12 +71,12 @@ class FallingBlock extends Entity{
|
||||
}
|
||||
|
||||
if($blockId === 0){
|
||||
throw new \UnexpectedValueException("Invalid " . get_class($this) . " entity: block ID is 0 or missing");
|
||||
throw new \UnexpectedValueException("Missing block info from NBT");
|
||||
}
|
||||
|
||||
$damage = $nbt->getByte("Data", 0);
|
||||
|
||||
$this->block = BlockFactory::getInstance()->get($blockId, $damage);
|
||||
return $factory->get($blockId, $damage);
|
||||
}
|
||||
|
||||
public function canCollideWith(Entity $entity) : bool{
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\entity\object;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Location;
|
||||
use pocketmine\event\entity\ItemDespawnEvent;
|
||||
use pocketmine\event\entity\ItemSpawnEvent;
|
||||
use pocketmine\event\inventory\InventoryPickupItemEvent;
|
||||
@@ -33,7 +34,6 @@ use pocketmine\network\mcpe\convert\TypeConverter;
|
||||
use pocketmine\network\mcpe\protocol\AddItemActorPacket;
|
||||
use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds;
|
||||
use pocketmine\player\Player;
|
||||
use function get_class;
|
||||
use function max;
|
||||
|
||||
class ItemEntity extends Entity{
|
||||
@@ -65,6 +65,14 @@ class ItemEntity extends Entity{
|
||||
/** @var int */
|
||||
protected $despawnDelay = self::DEFAULT_DESPAWN_DELAY;
|
||||
|
||||
public function __construct(Location $location, Item $item, CompoundTag $nbt){
|
||||
if($item->isNull()){
|
||||
throw new \InvalidArgumentException("Item entity must have a non-air item with a count of at least 1");
|
||||
}
|
||||
$this->item = $item;
|
||||
parent::__construct($location, $nbt);
|
||||
}
|
||||
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
parent::initEntity($nbt);
|
||||
|
||||
@@ -81,16 +89,6 @@ class ItemEntity extends Entity{
|
||||
$this->owner = $nbt->getString("Owner", $this->owner);
|
||||
$this->thrower = $nbt->getString("Thrower", $this->thrower);
|
||||
|
||||
$itemTag = $nbt->getCompoundTag("Item");
|
||||
if($itemTag === null){
|
||||
throw new \UnexpectedValueException("Invalid " . get_class($this) . " entity: expected \"Item\" NBT tag not found");
|
||||
}
|
||||
|
||||
$this->item = Item::nbtDeserialize($itemTag);
|
||||
if($this->item->isNull()){
|
||||
throw new \UnexpectedValueException("Item for " . get_class($this) . " is invalid");
|
||||
}
|
||||
|
||||
(new ItemSpawnEvent($this))->call();
|
||||
}
|
||||
|
||||
|
@@ -25,12 +25,12 @@ namespace pocketmine\entity\object;
|
||||
|
||||
use pocketmine\block\VanillaBlocks;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Location;
|
||||
use pocketmine\event\entity\EntityDamageByEntityEvent;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\ByteTag;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\network\mcpe\protocol\AddPaintingPacket;
|
||||
use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds;
|
||||
@@ -42,7 +42,7 @@ use function ceil;
|
||||
class Painting extends Entity{
|
||||
public static function getNetworkTypeId() : int{ return EntityLegacyIds::PAINTING; }
|
||||
|
||||
private const DATA_TO_FACING = [
|
||||
public const DATA_TO_FACING = [
|
||||
0 => Facing::SOUTH,
|
||||
1 => Facing::WEST,
|
||||
2 => Facing::NORTH,
|
||||
@@ -73,15 +73,11 @@ class Painting extends Entity{
|
||||
/** @var string */
|
||||
protected $motive;
|
||||
|
||||
public function __construct(World $world, CompoundTag $nbt){
|
||||
$this->motive = $nbt->getString("Motive");
|
||||
$this->blockIn = new Vector3($nbt->getInt("TileX"), $nbt->getInt("TileY"), $nbt->getInt("TileZ"));
|
||||
if($nbt->hasTag("Direction", ByteTag::class)){
|
||||
$this->facing = self::DATA_TO_FACING[$nbt->getByte("Direction")] ?? Facing::NORTH;
|
||||
}elseif($nbt->hasTag("Facing", ByteTag::class)){
|
||||
$this->facing = self::DATA_TO_FACING[$nbt->getByte("Facing")] ?? Facing::NORTH;
|
||||
}
|
||||
parent::__construct($world, $nbt);
|
||||
public function __construct(Location $location, Vector3 $blockIn, int $facing, PaintingMotive $motive, CompoundTag $nbt){
|
||||
$this->motive = $motive->getName(); //TODO: use motive directly
|
||||
$this->blockIn = $blockIn->asVector3();
|
||||
$this->facing = $facing;
|
||||
parent::__construct($location, $nbt);
|
||||
}
|
||||
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
|
@@ -53,6 +53,17 @@ class PrimedTNT extends Entity implements Explosive{
|
||||
|
||||
public $canCollide = false;
|
||||
|
||||
public function getFuse() : int{
|
||||
return $this->fuse;
|
||||
}
|
||||
|
||||
public function setFuse(int $fuse) : void{
|
||||
if($fuse < 0 or $fuse > 32767){
|
||||
throw new \InvalidArgumentException("Fuse must be in the range 0-32767");
|
||||
}
|
||||
$this->fuse = $fuse;
|
||||
}
|
||||
|
||||
public function attack(EntityDamageEvent $source) : void{
|
||||
if($source->getCause() === EntityDamageEvent::CAUSE_VOID){
|
||||
parent::attack($source);
|
||||
|
@@ -26,6 +26,7 @@ namespace pocketmine\entity\projectile;
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\entity\animation\ArrowShakeAnimation;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Location;
|
||||
use pocketmine\event\entity\ProjectileHitEvent;
|
||||
use pocketmine\event\inventory\InventoryPickupArrowEvent;
|
||||
use pocketmine\item\VanillaItems;
|
||||
@@ -36,7 +37,6 @@ use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection;
|
||||
use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\sound\ArrowHitSound;
|
||||
use pocketmine\world\World;
|
||||
use function mt_rand;
|
||||
use function sqrt;
|
||||
|
||||
@@ -71,8 +71,8 @@ class Arrow extends Projectile{
|
||||
/** @var bool */
|
||||
protected $critical = false;
|
||||
|
||||
public function __construct(World $world, CompoundTag $nbt, ?Entity $shootingEntity = null, bool $critical = false){
|
||||
parent::__construct($world, $nbt, $shootingEntity);
|
||||
public function __construct(Location $location, ?Entity $shootingEntity, bool $critical, CompoundTag $nbt){
|
||||
parent::__construct($location, $shootingEntity, $nbt);
|
||||
$this->setCritical($critical);
|
||||
}
|
||||
|
||||
|
@@ -27,6 +27,7 @@ use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Living;
|
||||
use pocketmine\entity\Location;
|
||||
use pocketmine\event\entity\EntityCombustByEntityEvent;
|
||||
use pocketmine\event\entity\EntityDamageByChildEntityEvent;
|
||||
use pocketmine\event\entity\EntityDamageByEntityEvent;
|
||||
@@ -41,7 +42,6 @@ use pocketmine\nbt\tag\ByteTag;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\IntTag;
|
||||
use pocketmine\timings\Timings;
|
||||
use pocketmine\world\World;
|
||||
use function assert;
|
||||
use function atan2;
|
||||
use function ceil;
|
||||
@@ -57,8 +57,8 @@ abstract class Projectile extends Entity{
|
||||
/** @var Block|null */
|
||||
protected $blockHit;
|
||||
|
||||
public function __construct(World $world, CompoundTag $nbt, ?Entity $shootingEntity = null){
|
||||
parent::__construct($world, $nbt);
|
||||
public function __construct(Location $location, ?Entity $shootingEntity, CompoundTag $nbt){
|
||||
parent::__construct($location, $nbt);
|
||||
if($shootingEntity !== null){
|
||||
$this->setOwningEntity($shootingEntity);
|
||||
}
|
||||
|
Reference in New Issue
Block a user