Critical arrows, fixed arrow interception calculation

This commit is contained in:
Shoghi Cervantes 2015-03-28 17:54:10 +01:00
parent 0a85ad0d1f
commit e0a6d0feab
No known key found for this signature in database
GPG Key ID: 78464DB0A7837F89
8 changed files with 40 additions and 18 deletions

View File

@ -1260,7 +1260,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$entity->scheduleUpdate(); $entity->scheduleUpdate();
} }
if($entity instanceof Arrow and $entity->onGround){ if($entity instanceof Arrow and $entity->hadCollision){
if($entity->dead !== true){ if($entity->dead !== true){
$item = Item::get(Item::ARROW, 0, 1); $item = Item::get(Item::ARROW, 0, 1);
if($this->isSurvival() and !$this->inventory->canAddItem($item)){ 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->isSurvival()){
if(!$this->inventory->contains(Item::get(Item::ARROW, 0, 1))){ if(!$this->inventory->contains(Item::get(Item::ARROW, 0, 1))){
$this->inventory->sendContents($this); $this->inventory->sendContents($this);
return; break;
} }
} }
@ -1799,14 +1799,16 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$diff = ($this->server->getTick() - $this->startAction); $diff = ($this->server->getTick() - $this->startAction);
if($diff < 5){ if($diff < 5){
$this->inventory->sendContents($this);
break; break;
} }
$p = $diff / 20; $p = $diff / 20;
$f = min((($p ** 2) + $p * 2) / 3, 1) * 2; $f = min((($p ** 2) + $p * 2) / 3, 1) * 2;
if($f < 0.1){ if($f < 0.1){
$this->inventory->sendContents($this);
break; 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); $this->server->getPluginManager()->callEvent($ev);

View File

@ -22,6 +22,7 @@
namespace pocketmine\entity; namespace pocketmine\entity;
use pocketmine\level\format\FullChunk; use pocketmine\level\format\FullChunk;
use pocketmine\level\particle\CriticalParticle;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\Compound;
use pocketmine\network\protocol\AddEntityPacket; use pocketmine\network\protocol\AddEntityPacket;
use pocketmine\Player; use pocketmine\Player;
@ -36,10 +37,13 @@ class Arrow extends Projectile{
protected $gravity = 0.05; protected $gravity = 0.05;
protected $drag = 0.01; 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->shootingEntity = $shootingEntity;
$this->isCritical = (bool) $critical;
parent::__construct($chunk, $nbt); parent::__construct($chunk, $nbt);
} }
@ -52,6 +56,15 @@ class Arrow extends Projectile{
$hasUpdate = parent::onUpdate($currentTick); $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){ if($this->age > 1200){
$this->kill(); $this->kill();
$hasUpdate = true; $hasUpdate = true;

View File

@ -1009,7 +1009,7 @@ abstract class Entity extends Location implements Metadatable{
$newBB = $this->boundingBox->getOffsetBoundingBox($dx, $dy, $dz); $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){ if(count($list) === 0){
$this->boundingBox = $newBB; $this->boundingBox = $newBB;
@ -1106,7 +1106,7 @@ abstract class Entity extends Location implements Metadatable{
//TODO: big messy loop //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){ foreach($list as $bb){

View File

@ -208,4 +208,3 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
} }
} }
a

View File

@ -37,7 +37,7 @@ abstract class Projectile extends Entity{
public $shootingEntity = null; public $shootingEntity = null;
protected $damage = 0; protected $damage = 0;
private $hadCollision = false; public $hadCollision = false;
protected function initEntity(){ protected function initEntity(){
parent::initEntity(); parent::initEntity();
@ -78,8 +78,6 @@ abstract class Projectile extends Entity{
$this->motionY -= $this->gravity; $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); $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); $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); $motion = sqrt($this->motionX ** 2 + $this->motionY ** 2 + $this->motionZ ** 2);
$damage = ceil($motion * $this->damage); $damage = ceil($motion * $this->damage);
if($this instanceof Arrow and $this->isCritical){
$damage += mt_rand(0, (int) ($damage / 2) + 1);
}
if($this->shootingEntity === null){ if($this->shootingEntity === null){
$ev = new EntityDamageByEntityEvent($this, $movingObjectPosition->entityHit, EntityDamageEvent::CAUSE_PROJECTILE, $damage); $ev = new EntityDamageByEntityEvent($this, $movingObjectPosition->entityHit, EntityDamageEvent::CAUSE_PROJECTILE, $damage);
}else{ }else{
@ -129,6 +131,7 @@ abstract class Projectile extends Entity{
$movingObjectPosition->entityHit->attack($ev->getFinalDamage(), $ev); $movingObjectPosition->entityHit->attack($ev->getFinalDamage(), $ev);
$this->hadCollision = true;
if($this->fireTicks > 0){ if($this->fireTicks > 0){
$ev = new EntityCombustByEntityEvent($this, $movingObjectPosition->entityHit, 5); $ev = new EntityCombustByEntityEvent($this, $movingObjectPosition->entityHit, 5);
@ -153,7 +156,7 @@ abstract class Projectile extends Entity{
$this->motionZ = 0; $this->motionZ = 0;
$this->server->getPluginManager()->callEvent(new ProjectileHitEvent($this)); $this->server->getPluginManager()->callEvent(new ProjectileHitEvent($this));
}elseif(!$this->isCollided and !$this->hadCollision){ }elseif(!$this->isCollided and $this->hadCollision){
$this->hadCollision = false; $this->hadCollision = false;
} }

View File

@ -24,7 +24,7 @@ namespace pocketmine\level\particle;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
class CriticalParticle extends GenericParticle{ class CriticalParticle extends GenericParticle{
public function __construct(Vector3 $pos){ public function __construct(Vector3 $pos, $scale = 2){
parent::__construct($pos, 2); parent::__construct($pos, 2, $scale);
} }
} }

View File

@ -274,7 +274,12 @@ class AxisAlignedBB{
$v6 = null; $v6 = null;
} }
$vector = null;
if($v1 !== null and ($vector === null or $pos1->distanceSquared($v1) < $pos1->distanceSquared($vector))){
$vector = $v1; $vector = $v1;
}
if($v2 !== null and ($vector === null or $pos1->distanceSquared($v2) < $pos1->distanceSquared($vector))){ if($v2 !== null and ($vector === null or $pos1->distanceSquared($v2) < $pos1->distanceSquared($vector))){
$vector = $v2; $vector = $v2;

View File

@ -246,7 +246,7 @@ class Vector3{
$yDiff = $v->y - $this->y; $yDiff = $v->y - $this->y;
$zDiff = $v->z - $this->z; $zDiff = $v->z - $this->z;
if(($xDiff ** 2) < 1){ if(($xDiff ** 2) < 0.0000001){
return null; return null;
} }
@ -273,7 +273,7 @@ class Vector3{
$yDiff = $v->y - $this->y; $yDiff = $v->y - $this->y;
$zDiff = $v->z - $this->z; $zDiff = $v->z - $this->z;
if(($yDiff ** 2) < 1){ if(($yDiff ** 2) < 0.0000001){
return null; return null;
} }
@ -300,7 +300,7 @@ class Vector3{
$yDiff = $v->y - $this->y; $yDiff = $v->y - $this->y;
$zDiff = $v->z - $this->z; $zDiff = $v->z - $this->z;
if(($zDiff ** 2) < 1){ if(($zDiff ** 2) < 0.0000001){
return null; return null;
} }