Fixed climbing blocks such as ladders and vines

Seems we can now climb ANY block if the climbing flag is true, and nothing if false. This commit adds local block checks to see if a climbable block exists at the entity's feet and if so, sets the flag.
This commit is contained in:
Dylan K. Taylor 2017-04-14 19:02:53 +01:00
parent f12a6eed29
commit 66924729ff
4 changed files with 66 additions and 5 deletions

View File

@ -472,6 +472,14 @@ class Block extends Position implements BlockIds, Metadatable{
return false;
}
/**
* Returns whether entities can climb up this block.
* @return bool
*/
public function canClimb() : bool{
return false;
}
/**
* @return string
*/

View File

@ -52,6 +52,10 @@ class Ladder extends Transparent{
return 0.4;
}
public function canClimb() : bool{
return true;
}
public function onEntityCollide(Entity $entity){
$entity->resetFallDistance();
$entity->onGround = true;

View File

@ -56,6 +56,10 @@ class Vine extends Transparent{
return true;
}
public function canClimb() : bool{
return true;
}
public function onEntityCollide(Entity $entity){
$entity->resetFallDistance();
}
@ -122,7 +126,7 @@ class Vine extends Transparent{
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
if(!$target->isTransparent() and $target->isSolid()){
if($target->isSolid()){
$faces = [
2 => 1,
3 => 4,
@ -142,11 +146,16 @@ class Vine extends Transparent{
public function onUpdate($type){
if($type === Level::BLOCK_UPDATE_NORMAL){
/*if($this->getSide(0)->getId() === self::AIR){ //Replace with common break method
Server::getInstance()->api->entity->drop($this, Item::get(LADDER, 0, 1));
$this->getLevel()->setBlock($this, new Air(), true, true);
$sides = [
2 => 4,
3 => 1,
4 => 2,
5 => 8
];
if(!$this->getSide($sides[$this->meta])->isSolid()){ //Replace with common break method
$this->level->useBreakOn($this);
return Level::BLOCK_UPDATE_NORMAL;
}*/
}
}
return false;

View File

@ -454,6 +454,45 @@ abstract class Entity extends Location implements Metadatable{
$this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_IMMOBILE, $value);
}
/**
* Sets whether this entity is currently able to climb blocks. By default this is only true if the entity is climbing a ladder or vine or similar block.
*
* @return bool
*/
public function isClimbing() : bool{
return $this->getDataFlag(self::DATA_FLAGS, self::DATA_FLAG_WALLCLIMBING);
}
/**
* Sets whether the entity can climb blocks. If true, the entity can climb anything, if false, they cannot climb anything (this includes ladders and vines).
*
* @param bool $value
*/
public function setClimbing(bool $value = true){
$this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_WALLCLIMBING, $value);
}
/**
* Checks blocks adjacent to the entity's feet to check if it is currently colliding with a climbable block.
*/
protected function checkClimbing(){
$climbing = false;
$block = $this->level->getBlock($this);
if($block->canClimb()){
$climbing = true;
}else{
for($i = 0; $i <= 5; ++$i){
if($block->getSide($i)->canClimb()){
$climbing = true;
break;
}
}
}
$this->setClimbing($climbing);
}
/**
* @return Effect[]
*/
@ -1434,6 +1473,7 @@ abstract class Entity extends Location implements Metadatable{
$this->checkChunks();
$this->checkGroundState($movX, $movY, $movZ, $dx, $dy, $dz);
$this->checkClimbing();
$this->updateFallState($dy, $this->onGround);
if($movX != $dx){