Implemented bed bouncing

This commit is contained in:
Dylan K. Taylor 2021-09-05 20:11:49 +01:00
parent 92f3a7d206
commit ded778f422
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
4 changed files with 34 additions and 17 deletions

View File

@ -29,6 +29,7 @@ use pocketmine\block\utils\ColoredTrait;
use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\DyeColor;
use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\block\utils\HorizontalFacingTrait;
use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\data\bedrock\DyeColorIdMap;
use pocketmine\entity\Entity;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationFactory;
use pocketmine\math\AxisAlignedBB; use pocketmine\math\AxisAlignedBB;
@ -170,6 +171,11 @@ class Bed extends Transparent{
} }
} }
public function onEntityLand(Entity $entity) : ?float{
$entity->fallDistance *= 0.5;
return $entity->getMotion()->y * -3 / 4; // 2/3 in Java, according to the wiki
}
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
$down = $this->getSide(Facing::DOWN); $down = $this->getSide(Facing::DOWN);
if(!$down->isTransparent()){ if(!$down->isTransparent()){

View File

@ -562,6 +562,14 @@ class Block{
return true; return true;
} }
/**
* Called when an entity lands on this block (usually due to falling).
* @return float|null The new vertical velocity of the entity, or null if unchanged.
*/
public function onEntityLand(Entity $entity) : ?float{
return null;
}
/** /**
* @return AxisAlignedBB[] * @return AxisAlignedBB[]
*/ */

View File

@ -1022,11 +1022,12 @@ abstract class Entity{
$this->fallDistance = 0.0; $this->fallDistance = 0.0;
} }
protected function updateFallState(float $distanceThisTick, bool $onGround) : void{ protected function updateFallState(float $distanceThisTick, bool $onGround) : ?float{
if($onGround){ if($onGround){
if($this->fallDistance > 0){ if($this->fallDistance > 0){
$this->onHitGround(); $newVerticalVelocity = $this->onHitGround();
$this->resetFallDistance(); $this->resetFallDistance();
return $newVerticalVelocity;
} }
}elseif($distanceThisTick < $this->fallDistance){ }elseif($distanceThisTick < $this->fallDistance){
//we've fallen some distance (distanceThisTick is negative) //we've fallen some distance (distanceThisTick is negative)
@ -1037,13 +1038,14 @@ abstract class Entity{
//reset it so it will be measured starting from the new, higher position //reset it so it will be measured starting from the new, higher position
$this->fallDistance = 0; $this->fallDistance = 0;
} }
return null;
} }
/** /**
* Called when a falling entity hits the ground. * Called when a falling entity hits the ground.
*/ */
protected function onHitGround() : void{ protected function onHitGround() : ?float{
return null;
} }
public function getEyeHeight() : float{ public function getEyeHeight() : float{
@ -1183,11 +1185,11 @@ abstract class Entity{
$this->getWorld()->onEntityMoved($this); $this->getWorld()->onEntityMoved($this);
$this->checkBlockIntersections(); $this->checkBlockIntersections();
$this->checkGroundState($wantedX, $wantedY, $wantedZ, $dx, $dy, $dz); $this->checkGroundState($wantedX, $wantedY, $wantedZ, $dx, $dy, $dz);
$this->updateFallState($dy, $this->onGround); $postFallVerticalVelocity = $this->updateFallState($dy, $this->onGround);
$this->motion = $this->motion->withComponents( $this->motion = $this->motion->withComponents(
$wantedX != $dx ? 0 : null, $wantedX != $dx ? 0 : null,
$wantedY != $dy ? 0 : null, $postFallVerticalVelocity ?? ($wantedY != $dy ? 0 : null),
$wantedZ != $dz ? 0 : null $wantedZ != $dz ? 0 : null
); );

View File

@ -309,7 +309,15 @@ abstract class Living extends Entity{
return ceil($fallDistance - 3 - (($jumpBoost = $this->effectManager->get(VanillaEffects::JUMP_BOOST())) !== null ? $jumpBoost->getEffectLevel() : 0)); return ceil($fallDistance - 3 - (($jumpBoost = $this->effectManager->get(VanillaEffects::JUMP_BOOST())) !== null ? $jumpBoost->getEffectLevel() : 0));
} }
protected function onHitGround() : void{ protected function onHitGround() : ?float{
$fallBlockPos = $this->location->floor();
$fallBlock = $this->getWorld()->getBlock($fallBlockPos);
if(count($fallBlock->getCollisionBoxes()) === 0){
$fallBlockPos = $fallBlockPos->down();
$fallBlock = $this->getWorld()->getBlock($fallBlockPos);
}
$newVerticalVelocity = $fallBlock->onEntityLand($this);
$damage = $this->calculateFallDamage($this->fallDistance); $damage = $this->calculateFallDamage($this->fallDistance);
if($damage > 0){ if($damage > 0){
$ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_FALL, $damage); $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_FALL, $damage);
@ -319,17 +327,10 @@ abstract class Living extends Entity{
new EntityLongFallSound($this) : new EntityLongFallSound($this) :
new EntityShortFallSound($this) new EntityShortFallSound($this)
); );
}else{ }elseif($fallBlock->getId() !== BlockLegacyIds::AIR){
$fallBlockPos = $this->location->floor(); $this->broadcastSound(new EntityLandSound($this, $fallBlock));
$fallBlock = $this->getWorld()->getBlock($fallBlockPos);
if(count($fallBlock->getCollisionBoxes()) === 0){
$fallBlockPos = $fallBlockPos->down();
$fallBlock = $this->getWorld()->getBlock($fallBlockPos);
}
if($fallBlock->getId() !== BlockLegacyIds::AIR){
$this->broadcastSound(new EntityLandSound($this, $fallBlock));
}
} }
return $newVerticalVelocity;
} }
/** /**