From e0a6d0feabc74fad85bb5a8688334f04cf80d532 Mon Sep 17 00:00:00 2001 From: Shoghi Cervantes Date: Sat, 28 Mar 2015 17:54:10 +0100 Subject: [PATCH] Critical arrows, fixed arrow interception calculation --- src/pocketmine/Player.php | 8 +++++--- src/pocketmine/entity/Arrow.php | 17 +++++++++++++++-- src/pocketmine/entity/Entity.php | 4 ++-- src/pocketmine/entity/Human.php | 1 - src/pocketmine/entity/Projectile.php | 11 +++++++---- .../level/particle/CriticalParticle.php | 4 ++-- src/pocketmine/math/AxisAlignedBB.php | 7 ++++++- src/pocketmine/math/Vector3.php | 6 +++--- 8 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 2a905edf7..fa0b848e0 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1260,7 +1260,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $entity->scheduleUpdate(); } - if($entity instanceof Arrow and $entity->onGround){ + if($entity instanceof Arrow and $entity->hadCollision){ if($entity->dead !== true){ $item = Item::get(Item::ARROW, 0, 1); if($this->isSurvival() and !$this->inventory->canAddItem($item)){ @@ -1775,7 +1775,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ if($this->isSurvival()){ if(!$this->inventory->contains(Item::get(Item::ARROW, 0, 1))){ $this->inventory->sendContents($this); - return; + break; } } @@ -1799,14 +1799,16 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $diff = ($this->server->getTick() - $this->startAction); if($diff < 5){ + $this->inventory->sendContents($this); break; } $p = $diff / 20; $f = min((($p ** 2) + $p * 2) / 3, 1) * 2; if($f < 0.1){ + $this->inventory->sendContents($this); break; } - $ev = new EntityShootBowEvent($this, $bow, Entity::createEntity("Arrow", $this->chunk, $nbt, $this), $f); + $ev = new EntityShootBowEvent($this, $bow, Entity::createEntity("Arrow", $this->chunk, $nbt, $this, $f == 2 ? true : false), $f); $this->server->getPluginManager()->callEvent($ev); diff --git a/src/pocketmine/entity/Arrow.php b/src/pocketmine/entity/Arrow.php index fe91b2828..267312144 100644 --- a/src/pocketmine/entity/Arrow.php +++ b/src/pocketmine/entity/Arrow.php @@ -22,6 +22,7 @@ namespace pocketmine\entity; use pocketmine\level\format\FullChunk; +use pocketmine\level\particle\CriticalParticle; use pocketmine\nbt\tag\Compound; use pocketmine\network\protocol\AddEntityPacket; use pocketmine\Player; @@ -36,10 +37,13 @@ class Arrow extends Projectile{ protected $gravity = 0.05; protected $drag = 0.01; - protected $damage = 6; + protected $damage = 2; - public function __construct(FullChunk $chunk, Compound $nbt, Entity $shootingEntity = null){ + protected $isCritical; + + public function __construct(FullChunk $chunk, Compound $nbt, Entity $shootingEntity = null, $critical = false){ $this->shootingEntity = $shootingEntity; + $this->isCritical = (bool) $critical; parent::__construct($chunk, $nbt); } @@ -52,6 +56,15 @@ class Arrow extends Projectile{ $hasUpdate = parent::onUpdate($currentTick); + if(!$this->hadCollision and $this->isCritical){ + $this->level->addParticle(new CriticalParticle($this->add( + $this->width / 2 + mt_rand(-100, 100) / 500, + $this->height / 2 + mt_rand(-100, 100) / 500, + $this->width / 2 + mt_rand(-100, 100) / 500))); + }elseif($this->onGround){ + $this->isCritical = false; + } + if($this->age > 1200){ $this->kill(); $hasUpdate = true; diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index a9e31d8b9..de93c80a8 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -1009,7 +1009,7 @@ abstract class Entity extends Location implements Metadatable{ $newBB = $this->boundingBox->getOffsetBoundingBox($dx, $dy, $dz); - $list = $this->level->getCollisionCubes($this, $newBB->expand(-0.01, -0.01, -0.01)); + $list = $this->level->getCollisionCubes($this, $newBB->expand(-0.01, -0.01, -0.01), false); if(count($list) === 0){ $this->boundingBox = $newBB; @@ -1106,7 +1106,7 @@ abstract class Entity extends Location implements Metadatable{ //TODO: big messy loop }*/ - $list = $this->level->getCollisionCubes($this, $this->boundingBox->getOffsetBoundingBox($dx, $dy, $dz)); + $list = $this->level->getCollisionCubes($this, $this->boundingBox->getOffsetBoundingBox($dx, $dy, $dz), false); foreach($list as $bb){ diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 1c31f991e..b5eab057a 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -208,4 +208,3 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ } } -a \ No newline at end of file diff --git a/src/pocketmine/entity/Projectile.php b/src/pocketmine/entity/Projectile.php index 8af3e9c34..b6418c20f 100644 --- a/src/pocketmine/entity/Projectile.php +++ b/src/pocketmine/entity/Projectile.php @@ -37,7 +37,7 @@ abstract class Projectile extends Entity{ public $shootingEntity = null; protected $damage = 0; - private $hadCollision = false; + public $hadCollision = false; protected function initEntity(){ parent::initEntity(); @@ -78,8 +78,6 @@ abstract class Projectile extends Entity{ $this->motionY -= $this->gravity; } - $this->keepMovement = $this->checkObstruction($this->x, ($this->boundingBox->minY + $this->boundingBox->maxY) / 2, $this->z); - $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); @@ -121,6 +119,10 @@ abstract class Projectile extends Entity{ $motion = sqrt($this->motionX ** 2 + $this->motionY ** 2 + $this->motionZ ** 2); $damage = ceil($motion * $this->damage); + if($this instanceof Arrow and $this->isCritical){ + $damage += mt_rand(0, (int) ($damage / 2) + 1); + } + if($this->shootingEntity === null){ $ev = new EntityDamageByEntityEvent($this, $movingObjectPosition->entityHit, EntityDamageEvent::CAUSE_PROJECTILE, $damage); }else{ @@ -129,6 +131,7 @@ abstract class Projectile extends Entity{ $movingObjectPosition->entityHit->attack($ev->getFinalDamage(), $ev); + $this->hadCollision = true; if($this->fireTicks > 0){ $ev = new EntityCombustByEntityEvent($this, $movingObjectPosition->entityHit, 5); @@ -153,7 +156,7 @@ abstract class Projectile extends Entity{ $this->motionZ = 0; $this->server->getPluginManager()->callEvent(new ProjectileHitEvent($this)); - }elseif(!$this->isCollided and !$this->hadCollision){ + }elseif(!$this->isCollided and $this->hadCollision){ $this->hadCollision = false; } diff --git a/src/pocketmine/level/particle/CriticalParticle.php b/src/pocketmine/level/particle/CriticalParticle.php index cfe624362..8e43114ac 100644 --- a/src/pocketmine/level/particle/CriticalParticle.php +++ b/src/pocketmine/level/particle/CriticalParticle.php @@ -24,7 +24,7 @@ namespace pocketmine\level\particle; use pocketmine\math\Vector3; class CriticalParticle extends GenericParticle{ - public function __construct(Vector3 $pos){ - parent::__construct($pos, 2); + public function __construct(Vector3 $pos, $scale = 2){ + parent::__construct($pos, 2, $scale); } } diff --git a/src/pocketmine/math/AxisAlignedBB.php b/src/pocketmine/math/AxisAlignedBB.php index 905382aa7..401c1e559 100644 --- a/src/pocketmine/math/AxisAlignedBB.php +++ b/src/pocketmine/math/AxisAlignedBB.php @@ -274,7 +274,12 @@ class AxisAlignedBB{ $v6 = null; } - $vector = $v1; + $vector = null; + + + if($v1 !== null and ($vector === null or $pos1->distanceSquared($v1) < $pos1->distanceSquared($vector))){ + $vector = $v1; + } if($v2 !== null and ($vector === null or $pos1->distanceSquared($v2) < $pos1->distanceSquared($vector))){ $vector = $v2; diff --git a/src/pocketmine/math/Vector3.php b/src/pocketmine/math/Vector3.php index 4395aa4e3..7bc4883c4 100644 --- a/src/pocketmine/math/Vector3.php +++ b/src/pocketmine/math/Vector3.php @@ -246,7 +246,7 @@ class Vector3{ $yDiff = $v->y - $this->y; $zDiff = $v->z - $this->z; - if(($xDiff ** 2) < 1){ + if(($xDiff ** 2) < 0.0000001){ return null; } @@ -273,7 +273,7 @@ class Vector3{ $yDiff = $v->y - $this->y; $zDiff = $v->z - $this->z; - if(($yDiff ** 2) < 1){ + if(($yDiff ** 2) < 0.0000001){ return null; } @@ -300,7 +300,7 @@ class Vector3{ $yDiff = $v->y - $this->y; $zDiff = $v->z - $this->z; - if(($zDiff ** 2) < 1){ + if(($zDiff ** 2) < 0.0000001){ return null; }