Falling Entities, better Physics [not final]

This commit is contained in:
Shoghi Cervantes 2013-05-28 22:03:58 +02:00
parent cb03daf28a
commit 58fd67d2ed
8 changed files with 125 additions and 32 deletions

View File

@ -715,18 +715,28 @@ class BlockAPI{
}
}*/
public function blockUpdateAround(Position $pos, $type = BLOCK_UPDATE_NORMAL){
public function blockUpdateAround(Position $pos, $type = BLOCK_UPDATE_NORMAL, $delay = false){
if(!($pos instanceof Block)){
$block = $pos->level->getBlock($pos);
}else{
$block = $pos;
}
$this->blockUpdate($block->getSide(0), $type);
$this->blockUpdate($block->getSide(1), $type);
$this->blockUpdate($block->getSide(2), $type);
$this->blockUpdate($block->getSide(3), $type);
$this->blockUpdate($block->getSide(4), $type);
$this->blockUpdate($block->getSide(5), $type);
if($delay !== false){
$this->scheduleBlockUpdate($block->getSide(0), $delay, $type);
$this->scheduleBlockUpdate($block->getSide(1), $delay, $type);
$this->scheduleBlockUpdate($block->getSide(2), $delay, $type);
$this->scheduleBlockUpdate($block->getSide(3), $delay, $type);
$this->scheduleBlockUpdate($block->getSide(4), $delay, $type);
$this->scheduleBlockUpdate($block->getSide(5), $delay, $type);
}else{
$this->blockUpdate($block->getSide(0), $type);
$this->blockUpdate($block->getSide(1), $type);
$this->blockUpdate($block->getSide(2), $type);
$this->blockUpdate($block->getSide(3), $type);
$this->blockUpdate($block->getSide(4), $type);
$this->blockUpdate($block->getSide(5), $type);
}
}
public function blockUpdate(Position $pos, $type = BLOCK_UPDATE_NORMAL){

View File

@ -170,6 +170,10 @@ class LevelAPI{
"yaw" => $entity["Rotation"][0],
"pitch" => $entity["Rotation"][1],
));
}elseif($entity["id"] === FALLING_SAND){
$e = $this->server->api->entity->add($this->levels[$name], ENTITY_FALLING, $entity["id"], $entity);
$e->setPosition(new Vector3($entity["Pos"][0], $entity["Pos"][1], $entity["Pos"][2]), $entity["Rotation"][0], $entity["Rotation"][1]);
$e->setHealth($entity["Health"]);
}elseif($entity["id"] === OBJECT_PAINTING){ //Painting
$e = $this->server->api->entity->add($this->levels[$name], ENTITY_OBJECT, $entity["id"], $entity);
$e->setPosition(new Vector3($entity["Pos"][0], $entity["Pos"][1], $entity["Pos"][2]), $entity["Rotation"][0], $entity["Rotation"][1]);

View File

@ -6,7 +6,7 @@ ZEND_VM="GOTO"
LIBEDIT_VERSION="0.3"
ZLIB_VERSION="1.2.8"
PTHREADS_VERSION="e5d95dfb847c8963c100bd4fb601dde41e0b75d1"
PTHREADS_VERSION="0b863ea34e1f5c0a0eef6d50a7cbca58d39435cc"
CURL_VERSION="curl-7_30_0"
echo "[PocketMine] PHP installer and compiler for Linux & Mac - v$COMPILER_VERSION"

View File

@ -57,6 +57,9 @@ define("ENTITY_OBJECT", 2);
define("ENTITY_ITEM", 3);
define("ENTITY_FALLING", 4);
define("FALLING_SAND", 66);
//TileEntities
define("TILE_SIGN", "Sign");

View File

@ -25,9 +25,24 @@ the Free Software Foundation, either version 3 of the License, or
*/
class FallableBlock extends GenericBlock{
class FallableBlock extends SolidBlock{
public function __construct($id, $meta = 0, $name = "Unknown"){
parent::__construct($id, $meta, $name);
$this->hasPhysics = true;
}
public function onUpdate($type){
if($this->getSide(0)->getID() === AIR){
$data = array(
"x" => $this->x + 0.5,
"y" => $this->y + 0.5,
"z" => $this->z + 0.5,
"Tile" => $this->id,
);
$server = ServerAPI::request();
$e = $server->api->entity->add($this->level, ENTITY_FALLING, FALLING_SAND, $data);
$server->api->entity->spawnToAll($this->level, $e->eid);
$this->level->setBlock($this, new AirBlock());
}
}
}

View File

@ -256,20 +256,31 @@ class CustomPacketHandler{
$this->raw .= Utils::writeInt($this->data["eid"]);
}
break;
case MC_ADD_ENTITY: //Not used?
case MC_ADD_ENTITY:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["type"] = ord($this->get(1));
$this->data["x"] = Utils::readFloat($this->get(4));
$this->data["y"] = Utils::readFloat($this->get(4));
$this->data["z"] = Utils::readFloat($this->get(4));
$this->data["did"] = Utils::readInt($this->get(4));
if($this->data["did"] > 0){
$this->data["speedX"] = Utils::readShort($this->get(2));
$this->data["speedY"] = Utils::readShort($this->get(2));
$this->data["speedZ"] = Utils::readShort($this->get(2));
}
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= chr($this->data["type"]);
$this->raw .= Utils::writeFloat($this->data["x"]);
$this->raw .= Utils::writeFloat($this->data["y"]);
$this->raw .= Utils::writeFloat($this->data["z"]);
$this->raw .= Utils::hexToStr("000000020000ffd30000");//Utils::writeInt(0);
$this->raw .= Utils::writeInt($this->data["did"]);
if($this->data["did"] > 0){
$this->raw .= Utils::writeShort($this->data["speedX"]);
$this->raw .= Utils::writeShort($this->data["speedY"]);
$this->raw .= Utils::writeShort($this->data["speedZ"]);
}
}
break;
case MC_REMOVE_ENTITY:
@ -379,7 +390,7 @@ class CustomPacketHandler{
$this->raw .= chr($this->data["face"]);
}
break;
case MC_REMOVE_BLOCK:
case MC_REMOVE_BLOCK: //Sent when a player removes a block, not used
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["x"] = Utils::readInt($this->get(4));

View File

@ -55,6 +55,7 @@ class Entity extends Position{
private $speedMeasure = array(0, 0, 0, 0, 0);
private $server;
public $level;
public $lastUpdate;
public $check = true;
public $size = 1;
@ -76,7 +77,7 @@ class Entity extends Position{
$this->fire = 0;
$this->crouched = false;
$this->invincible = false;
$this->spawntime = microtime(true);
$this->lastUpdate = $this->spawntime = microtime(true);
$this->dead = false;
$this->closed = false;
$this->name = "";
@ -116,6 +117,11 @@ class Entity extends Position{
//$this->setName((isset($mobs[$this->type]) ? $mobs[$this->type]:$this->type));
$this->size = 1;
break;
case ENTITY_FALLING:
$this->setHealth(PHP_INT_MAX, "generic");
$this->server->schedule(5, array($this, "update"), array(), true);
$this->size = 0.98;
break;
case ENTITY_OBJECT:
$this->x = isset($this->data["TileX"]) ? $this->data["TileX"]:$this->x;
$this->y = isset($this->data["TileY"]) ? $this->data["TileY"]:$this->y;
@ -320,9 +326,12 @@ class Entity extends Position{
return false;
}
$now = microtime(true);
if($this->check === false){
$this->lastUpdate = $now;
return;
}
$tdiff = $now - $this->lastUpdate;
if($this->tickCounter === 0){
$this->tickCounter = 1;
@ -331,7 +340,7 @@ class Entity extends Position{
$this->tickCounter = 0;
}
if(($this->class === ENTITY_ITEM or $this->class === ENTITY_MOB or $this->class === ENTITY_PLAYER)){
if(($this->class === ENTITY_ITEM or $this->class === ENTITY_MOB or $this->class === ENTITY_PLAYER or $this->class === ENTITY_FALLING)){
$startX = ((int) round($this->x - 0.5)) - 1;
$y = (int) round($this->y - 1);
$startZ = ((int) round($this->z - 0.5)) - 1;
@ -353,30 +362,60 @@ class Entity extends Position{
break;
}
}
if($this->class === ENTITY_ITEM or $this->class === ENTITY_MOB){
if($this->class === ENTITY_ITEM or $this->class === ENTITY_MOB or $this->class === ENTITY_FALLING){
$update = false;
$drag = 0.4 * $tdiff;
if($this->speedX != 0){
$this->x += $this->speedX * 5;
$update = true;
}
if($this->speedY != 0){
$this->y += $this->speedY * 5;
$this->speedX -= $this->speedX * $drag;
$this->x += $this->speedX * $tdiff;
$update = true;
}
if($this->speedZ != 0){
$this->z += $this->speedZ * 5;
$this->speedZ -= $this->speedZ * $drag;
$this->z += $this->speedZ * $tdiff;
$update = true;
}
if($this->speedY != 0){
$this->speedY -= $this->speedY * $drag;
$ny = $this->y + $this->speedY * $tdiff;
if($ny < $this->y){
$x = (int) ($this->x - 0.5);
$z = (int) ($this->z - 0.5);
$lim = (int) floor($ny);
for($y = (int) ceil($this->y); $y >= $lim; --$y){
if($this->level->getBlock(new Vector3($x, $y, $z))->isFlowable !== true){
$ny = $y + 1;
$this->speedY = 0;
$this->support = true;
break;
}
}
}
$this->y = $ny;
$update = true;
}
if($support === false){
$this->speedY -= 0.04 * 5;
$update = true;
}elseif($this->speedY < 0){
$this->y = $y + 1;
$this->speedX = 0;
$this->speedY = 0;
$this->speedZ = 0;
$this->speedY -= ($this->class === ENTITY_FALLING ? 16:32) * $tdiff;
$update = true;
}else{
if($this->speedY < 0){
$this->speedX = 0;
$this->speedY = 0;
$this->speedZ = 0;
$update = true;
}
if($this->class === ENTITY_FALLING){
$fall = $this->level->getBlock(new Vector3(intval($this->x - 0.5), intval(ceil($this->y)), intval($this->z - 0.5)));
if($fall->getID() !== AIR and $fall->isFlowable){
$this->server->api->entity->drop($this, BlockAPI::getItem($this->data["Tile"] & 0xFFFF, 0, 1), true);
}else{
$this->level->setBlock($fall, BlockAPI::get($this->data["Tile"]));
}
$this->server->api->handle("entity.motion", $this);
$this->close();
}
}
if($update === true){
$this->server->api->handle("entity.motion", $this);
}
@ -421,10 +460,11 @@ class Entity extends Position{
}else{
$this->setPosition($this->last[0], $this->last[1], $this->last[2], $this->last[3], $this->last[4]);
}
return;
}else{
$this->updateLast();
}
$this->updateLast();
}
$this->lastUpdate = $now;
}
public function getDirection(){
@ -528,6 +568,16 @@ class Entity extends Position{
));
}
break;
case ENTITY_FALLING:
$player->dataPacket(MC_ADD_ENTITY, array(
"eid" => $this->eid,
"type" => $this->type,
"x" => $this->x,
"y" => $this->y,
"z" => $this->z,
"did" => -$this->data["Tile"],
));
break;
}
}

View File

@ -242,8 +242,8 @@ class Level{
"block" => $block,
));*/
if($update === true){
$this->server->api->block->blockUpdate($block, BLOCK_UPDATE_NORMAL); //????? water?
$this->server->api->block->blockUpdateAround($pos, BLOCK_UPDATE_NORMAL);
$this->server->api->block->scheduleBlockUpdate($block, 1, BLOCK_UPDATE_NORMAL); //????? water?
$this->server->api->block->blockUpdateAround($pos, BLOCK_UPDATE_NORMAL, 1);
}
if($tiles === true){
if(($t = $this->server->api->tileentity->get($pos)) !== false){