Merge branch 'release/3.1'

This commit is contained in:
Dylan K. Taylor 2018-06-24 12:07:57 +01:00
commit cfee9aa117
5 changed files with 78 additions and 13 deletions

View File

@ -34,6 +34,7 @@ use pocketmine\inventory\ArmorInventory;
use pocketmine\inventory\ArmorInventoryEventProcessor; use pocketmine\inventory\ArmorInventoryEventProcessor;
use pocketmine\item\Armor; use pocketmine\item\Armor;
use pocketmine\item\Consumable; use pocketmine\item\Consumable;
use pocketmine\item\Durable;
use pocketmine\item\enchantment\Enchantment; use pocketmine\item\enchantment\Enchantment;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
@ -476,6 +477,26 @@ abstract class Living extends Entity implements Damageable{
protected function applyPostDamageEffects(EntityDamageEvent $source) : void{ protected function applyPostDamageEffects(EntityDamageEvent $source) : void{
$this->setAbsorption(max(0, $this->getAbsorption() + $source->getModifier(EntityDamageEvent::MODIFIER_ABSORPTION))); $this->setAbsorption(max(0, $this->getAbsorption() + $source->getModifier(EntityDamageEvent::MODIFIER_ABSORPTION)));
$this->damageArmor($source->getBaseDamage()); $this->damageArmor($source->getBaseDamage());
if($source instanceof EntityDamageByEntityEvent){
$damage = 0;
foreach($this->armorInventory->getContents() as $k => $item){
if($item instanceof Armor and ($thornsLevel = $item->getEnchantmentLevel(Enchantment::THORNS)) > 0){
if(mt_rand(0, 99) < $thornsLevel * 15){
$this->damageItem($item, 3);
$damage += ($thornsLevel > 10 ? $thornsLevel - 10 : 1 + mt_rand(0, 3));
}else{
$this->damageItem($item, 1); //thorns causes an extra +1 durability loss even if it didn't activate
}
$this->armorInventory->setItem($k, $item);
}
}
if($damage > 0){
$source->getDamager()->attack(new EntityDamageByEntityEvent($this, $source->getDamager(), EntityDamageEvent::CAUSE_MAGIC, $damage));
}
}
} }
/** /**
@ -490,16 +511,20 @@ abstract class Living extends Entity implements Damageable{
$armor = $this->armorInventory->getContents(true); $armor = $this->armorInventory->getContents(true);
foreach($armor as $item){ foreach($armor as $item){
if($item instanceof Armor){ if($item instanceof Armor){
$item->applyDamage($durabilityRemoved); $this->damageItem($item, $durabilityRemoved);
if($item->isBroken()){
$this->level->broadcastLevelSoundEvent($this, LevelSoundEventPacket::SOUND_BREAK);
}
} }
} }
$this->armorInventory->setContents($armor); $this->armorInventory->setContents($armor);
} }
private function damageItem(Durable $item, int $durabilityRemoved) : void{
$item->applyDamage($durabilityRemoved);
if($item->isBroken()){
$this->level->broadcastLevelSoundEvent($this, LevelSoundEventPacket::SOUND_BREAK);
}
}
public function attack(EntityDamageEvent $source) : void{ public function attack(EntityDamageEvent $source) : void{
if($this->attackTime > 0 or $this->noDamageTicks > 0){ if($this->attackTime > 0 or $this->noDamageTicks > 0){
$lastCause = $this->getLastDamageCause(); $lastCause = $this->getLastDamageCause();
@ -577,14 +602,17 @@ abstract class Living extends Entity implements Damageable{
$motion = clone $this->motion; $motion = clone $this->motion;
$motion->x /= 2; $motion->x /= 2;
$motion->y /= 2;
$motion->z /= 2; $motion->z /= 2;
$motion->x += $x * $f * $base; $motion->x += $x * $f * $base;
$motion->y += $base;
$motion->z += $z * $f * $base; $motion->z += $z * $f * $base;
if($motion->y > $base){ if($this->onGround){
$motion->y = $base; $motion->y /= 2;
$motion->y += $base;
if($motion->y > 0.4){ //this is hardcoded in vanilla
$motion->y = 0.4;
}
} }
$this->setMotion($motion); $this->setMotion($motion);

View File

@ -165,7 +165,7 @@ class ExperienceOrb extends Entity{
} }
$currentTarget = $this->getTargetPlayer(); $currentTarget = $this->getTargetPlayer();
if($currentTarget !== null and $currentTarget->distanceSquared($this) > self::MAX_TARGET_DISTANCE ** 2){ if($currentTarget !== null and (!$currentTarget->isAlive() or $currentTarget->distanceSquared($this) > self::MAX_TARGET_DISTANCE ** 2)){
$currentTarget = null; $currentTarget = null;
} }

View File

@ -31,6 +31,7 @@ use pocketmine\item\Item;
use pocketmine\item\ItemFactory; use pocketmine\item\ItemFactory;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\math\RayTraceResult; use pocketmine\math\RayTraceResult;
use pocketmine\math\Vector3;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\EntityEventPacket;
use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket;
@ -58,6 +59,9 @@ class Arrow extends Projectile{
/** @var int */ /** @var int */
protected $pickupMode = self::PICKUP_ANY; protected $pickupMode = self::PICKUP_ANY;
/** @var float */
protected $punchKnockback = 0.0;
public function __construct(Level $level, CompoundTag $nbt, ?Entity $shootingEntity = null, bool $critical = false){ public function __construct(Level $level, CompoundTag $nbt, ?Entity $shootingEntity = null, bool $critical = false){
parent::__construct($level, $nbt, $shootingEntity); parent::__construct($level, $nbt, $shootingEntity);
$this->setCritical($critical); $this->setCritical($critical);
@ -92,6 +96,20 @@ class Arrow extends Projectile{
} }
} }
/**
* @return float
*/
public function getPunchKnockback() : float{
return $this->punchKnockback;
}
/**
* @param float $punchKnockback
*/
public function setPunchKnockback(float $punchKnockback) : void{
$this->punchKnockback = $punchKnockback;
}
public function entityBaseTick(int $tickDiff = 1) : bool{ public function entityBaseTick(int $tickDiff = 1) : bool{
if($this->closed){ if($this->closed){
return false; return false;
@ -117,6 +135,16 @@ class Arrow extends Projectile{
$this->broadcastEntityEvent(EntityEventPacket::ARROW_SHAKE, 7); //7 ticks $this->broadcastEntityEvent(EntityEventPacket::ARROW_SHAKE, 7); //7 ticks
} }
protected function onHitEntity(Entity $entityHit, RayTraceResult $hitResult) : void{
parent::onHitEntity($entityHit, $hitResult);
if($this->punchKnockback > 0){
$mot = $entityHit->getMotion();
$multiplier = $this->punchKnockback * 0.6 / $mot->length();
$entityHit->setMotion($mot->add($mot->x * $multiplier, 0.1, $mot->z * $multiplier));
}
}
/** /**
* @return int * @return int
*/ */

View File

@ -67,12 +67,20 @@ class Bow extends Tool{
$entity = Entity::createEntity("Arrow", $player->getLevel(), $nbt, $player, $force == 2); $entity = Entity::createEntity("Arrow", $player->getLevel(), $nbt, $player, $force == 2);
if($entity instanceof Projectile){ if($entity instanceof Projectile){
$infinity = $this->hasEnchantment(Enchantment::INFINITY); $infinity = $this->hasEnchantment(Enchantment::INFINITY);
if($infinity and $entity instanceof ArrowEntity){ if($entity instanceof ArrowEntity){
if($infinity){
$entity->setPickupMode(ArrowEntity::PICKUP_CREATIVE); $entity->setPickupMode(ArrowEntity::PICKUP_CREATIVE);
} }
if(($punchLevel = $this->getEnchantmentLevel(Enchantment::PUNCH)) > 0){
$entity->setPunchKnockback($punchLevel);
}
}
if(($powerLevel = $this->getEnchantmentLevel(Enchantment::POWER)) > 0){ if(($powerLevel = $this->getEnchantmentLevel(Enchantment::POWER)) > 0){
$entity->setBaseDamage($entity->getBaseDamage() + (($powerLevel + 1) / 2)); $entity->setBaseDamage($entity->getBaseDamage() + (($powerLevel + 1) / 2));
} }
if($this->hasEnchantment(Enchantment::FLAME)){
$entity->setOnFire($entity->getFireTicks() * 20 + 100);
}
$ev = new EntityShootBowEvent($player, $this, $entity, $force); $ev = new EntityShootBowEvent($player, $this, $entity, $force);
if($force < 0.1 or $diff < 5){ if($force < 0.1 or $diff < 5){

View File

@ -114,7 +114,7 @@ class Enchantment{
self::registerEnchantment(new ProtectionEnchantment(self::PROJECTILE_PROTECTION, "%enchantment.protect.projectile", self::RARITY_UNCOMMON, self::SLOT_ARMOR, self::SLOT_NONE, 4, 1.5, [ self::registerEnchantment(new ProtectionEnchantment(self::PROJECTILE_PROTECTION, "%enchantment.protect.projectile", self::RARITY_UNCOMMON, self::SLOT_ARMOR, self::SLOT_NONE, 4, 1.5, [
EntityDamageEvent::CAUSE_PROJECTILE EntityDamageEvent::CAUSE_PROJECTILE
])); ]));
self::registerEnchantment(new Enchantment(self::THORNS, "%enchantment.thorns", self::RARITY_MYTHIC, self::SLOT_TORSO, self::SLOT_HEAD | self::SLOT_LEGS | self::SLOT_FEET, 3));
self::registerEnchantment(new Enchantment(self::RESPIRATION, "%enchantment.oxygen", self::RARITY_RARE, self::SLOT_HEAD, self::SLOT_NONE, 3)); self::registerEnchantment(new Enchantment(self::RESPIRATION, "%enchantment.oxygen", self::RARITY_RARE, self::SLOT_HEAD, self::SLOT_NONE, 3));
self::registerEnchantment(new Enchantment(self::EFFICIENCY, "%enchantment.digging", self::RARITY_COMMON, self::SLOT_DIG, self::SLOT_SHEARS, 5)); self::registerEnchantment(new Enchantment(self::EFFICIENCY, "%enchantment.digging", self::RARITY_COMMON, self::SLOT_DIG, self::SLOT_SHEARS, 5));
@ -122,7 +122,8 @@ class Enchantment{
self::registerEnchantment(new Enchantment(self::UNBREAKING, "%enchantment.durability", self::RARITY_UNCOMMON, self::SLOT_DIG | self::SLOT_ARMOR | self::SLOT_FISHING_ROD | self::SLOT_BOW, self::SLOT_TOOL | self::SLOT_CARROT_STICK | self::SLOT_ELYTRA, 3)); self::registerEnchantment(new Enchantment(self::UNBREAKING, "%enchantment.durability", self::RARITY_UNCOMMON, self::SLOT_DIG | self::SLOT_ARMOR | self::SLOT_FISHING_ROD | self::SLOT_BOW, self::SLOT_TOOL | self::SLOT_CARROT_STICK | self::SLOT_ELYTRA, 3));
self::registerEnchantment(new Enchantment(self::POWER, "%enchantment.arrowDamage", self::RARITY_COMMON, self::SLOT_BOW, self::SLOT_NONE, 5)); self::registerEnchantment(new Enchantment(self::POWER, "%enchantment.arrowDamage", self::RARITY_COMMON, self::SLOT_BOW, self::SLOT_NONE, 5));
self::registerEnchantment(new Enchantment(self::PUNCH, "%enchantment.arrowKnockback", self::RARITY_RARE, self::SLOT_BOW, self::SLOT_NONE, 2));
self::registerEnchantment(new Enchantment(self::FLAME, "%enchantment.arrowFire", self::RARITY_RARE, self::SLOT_BOW, self::SLOT_NONE, 1));
self::registerEnchantment(new Enchantment(self::INFINITY, "%enchantment.arrowInfinite", self::RARITY_MYTHIC, self::SLOT_BOW, self::SLOT_NONE, 1)); self::registerEnchantment(new Enchantment(self::INFINITY, "%enchantment.arrowInfinite", self::RARITY_MYTHIC, self::SLOT_BOW, self::SLOT_NONE, 1));
self::registerEnchantment(new Enchantment(self::VANISHING, "%enchantment.curse.vanishing", self::RARITY_MYTHIC, self::SLOT_NONE, self::SLOT_ALL, 1)); self::registerEnchantment(new Enchantment(self::VANISHING, "%enchantment.curse.vanishing", self::RARITY_MYTHIC, self::SLOT_NONE, self::SLOT_ALL, 1));