Player actions and bows [WiP]

This commit is contained in:
Shoghi Cervantes 2013-06-03 16:31:33 +02:00
parent d1f2f82c6d
commit f55fb8d490
6 changed files with 196 additions and 58 deletions

View File

@ -174,7 +174,7 @@ class LevelAPI{
$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
}elseif($entity["id"] === OBJECT_PAINTING or $entity["id"] === OBJECT_ARROW){ //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]);
$e->setHealth($entity["Health"]);

View File

@ -42,6 +42,7 @@ class Player{
private $username;
private $iusername;
private $eid = false;
private $startAction = false;
public $data;
public $entity = false;
public $auth = false;
@ -435,6 +436,12 @@ class Player{
}
$this->dataPacket(MC_PLAYER_EQUIPMENT, $data);
break;
case "player.action":
if($data["eid"] === $this->eid or $data["player"]->level !== $this->level){
break;
}
$this->dataPacket(MC_USE_ITEM, $data);
break;
case "entity.move":
if($data->eid === $this->eid or $data->level !== $this->level){
@ -946,6 +953,7 @@ class Player{
$this->evid[] = $this->server->event("entity.metadata", array($this, "eventHandler"));
$this->evid[] = $this->server->event("player.equipment.change", array($this, "eventHandler"));
$this->evid[] = $this->server->event("player.armor", array($this, "eventHandler"));
$this->evid[] = $this->server->event("player.action", array($this, "eventHandler"));
$this->evid[] = $this->server->event("player.pickup", array($this, "eventHandler"));
$this->evid[] = $this->server->event("tile.container.slot", array($this, "eventHandler"));
$this->evid[] = $this->server->event("tile.update", array($this, "eventHandler"));
@ -1015,6 +1023,10 @@ class Player{
}elseif($this->itemEnforcement === true){
$this->sendInventory();
}
if($this->entity->inAction === true){
$this->entity->inAction = false;
$this->entity->updateMetadata();
}
break;
case MC_REQUEST_CHUNK:
if($this->spawned === false){
@ -1026,13 +1038,50 @@ class Player{
break;
}
$data["eid"] = $this->eid;
if($this->blocked === true or Utils::distance($this->entity->position, $data) > 10){
break;
}elseif(!$this->hasItem($data["block"], $data["meta"]) and $this->itemEnforcement === true){
$this->sendInventory();
$data["player"] = $this;
if($data["face"] >= 0 and $data["face"] <= 5){ //Use Block, place
if($this->entity->inAction === true){
$this->entity->inAction = false;
$this->entity->updateMetadata();
}
if($this->blocked === true or Utils::distance($this->entity->position, $data) > 10){
break;
}elseif(!$this->hasItem($data["block"], $data["meta"]) and $this->itemEnforcement === true){
$this->sendInventory();
break;
}
$this->server->api->block->playerBlockAction($this, new Vector3($data["x"], $data["y"], $data["z"]), $data["face"], $data["fx"], $data["fy"], $data["fz"]);
}elseif($data["face"] === 0xFF and $this->server->handle("player.action", $data) !== false){
$this->entity->inAction = true;
$this->startAction = microtime(true);
$this->entity->updateMetadata();
}
break;
case MC_PLAYER_ACTION:
if($this->spawned === false){
break;
}
$this->server->api->block->playerBlockAction($this, new Vector3($data["x"], $data["y"], $data["z"]), $data["face"], $data["fx"], $data["fy"], $data["fz"]);
if($this->entity->inAction === true){
switch($data["action"]){
case 5: //Shot arrow
if($this->equipment->getID() === BOW){
if($this->startAction !== false){
$time = microtime(true) - $this->startAction;
$d = array(
"x" => $this->entity->x,
"y" => $this->entity->y + 1.6,
"z" => $this->entity->z,
);
$e = $this->server->api->entity->add($this->level, ENTITY_OBJECT, OBJECT_ARROW, $d);
$this->server->api->entity->spawnToAll($this->level, $e->eid);
}
}
break;
}
}
$this->startAction = false;
$this->entity->inAction = false;
$this->entity->updateMetadata();
break;
case MC_REMOVE_BLOCK:
if($this->spawned === false){
@ -1050,6 +1099,10 @@ class Player{
$data["eid"] = $this->eid;
$data["player"] = $this;
$this->server->handle("player.armor", $data);
if($this->entity->inAction === true){
$this->entity->inAction = false;
$this->entity->updateMetadata();
}
break;
case MC_INTERACT:
if($this->spawned === false){
@ -1163,6 +1216,10 @@ class Player{
break;
}
$data["eid"] = $this->eid;
if($this->entity->inAction === true){
$this->entity->inAction = false;
$this->entity->updateMetadata();
}
switch($data["event"]){
case 9: //Eating
$items = array(
@ -1205,6 +1262,10 @@ class Player{
$this->server->api->entity->drop(new Position($this->entity->x - 0.5, $this->entity->y, $this->entity->z - 0.5, $this->level), $item);
}
}
if($this->entity->inAction === true){
$this->entity->inAction = false;
$this->entity->updateMetadata();
}
break;
case MC_SIGN_UPDATE:
if($this->spawned === false){

View File

@ -61,6 +61,7 @@ define("ENTITY_MOB", 2);
define("MOB_PIGMAN", 36);
define("ENTITY_OBJECT", 3);
define("OBJECT_ARROW", 80);
define("OBJECT_PAINTING", 83);
define("ENTITY_ITEM", 4);

View File

@ -554,13 +554,34 @@ class CustomPacketHandler{
$this->data["fy"] = Utils::readFloat($this->get(4));
$this->data["fz"] = Utils::readFloat($this->get(4));
}else{
/*$this->raw .= Utils::writeByte($this->data["action"]);
$this->raw .= Utils::writeInt($this->data["x"]);
$this->raw .= Utils::writeInt($this->data["y"]);
$this->raw .= Utils::writeInt($this->data["z"]);
$this->raw .= Utils::writeInt($this->data["face"]);
$this->raw .= Utils::writeShort($this->data["block"]);
$this->raw .= Utils::writeByte($this->data["meta"]);
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= Utils::writeInt($this->data["target"]);*/
$this->raw .= Utils::writeFloat($this->data["fx"]);
$this->raw .= Utils::writeFloat($this->data["fy"]);
$this->raw .= Utils::writeFloat($this->data["fz"]);
}
break;
case MC_PLAYER_ACTION:
//TODO
if($this->c === false){
$this->data["action"] = Utils::readInt($this->get(4));
$this->data["x"] = Utils::readInt($this->get(4));
$this->data["y"] = Utils::readInt($this->get(4));
$this->data["z"] = Utils::readInt($this->get(4));
$this->data["face"] = Utils::readInt($this->get(4));
$this->data["eid"] = Utils::readInt($this->get(4));
}else{
$this->raw .= Utils::writeInt($this->data["action"]);
$this->raw .= Utils::writeInt($this->data["x"]);
$this->raw .= Utils::writeInt($this->data["y"]);
$this->raw .= Utils::writeInt($this->data["z"]);
$this->raw .= Utils::writeInt($this->data["face"]);
$this->raw .= Utils::writeInt($this->data["eid"]);
}
break;
case MC_SET_ENTITY_DATA:
if($this->c === false){

View File

@ -54,10 +54,12 @@ class Entity extends Position{
private $tickCounter;
private $speedMeasure = array(0, 0, 0, 0, 0);
private $server;
private $isStatic;
public $level;
public $lastUpdate;
public $check = true;
public $size = 1;
public $inAction = false;
function __construct(Level $level, $eid, $class, $type = 0, $data = array()){
$this->level = $level;
@ -80,6 +82,7 @@ class Entity extends Position{
$this->lastUpdate = $this->spawntime = microtime(true);
$this->dead = false;
$this->closed = false;
$this->isStatic = false;
$this->name = "";
$this->tickCounter = 0;
$this->server->query("INSERT OR REPLACE INTO entities (EID, level, type, class, health, hasUpdate) VALUES (".$this->eid.", '".$this->level->getName()."', ".$this->type.", ".$this->class.", ".$this->health.", 0);");
@ -130,6 +133,9 @@ class Entity extends Position{
$this->setHealth(1, "generic");
//$this->setName((isset($objects[$this->type]) ? $objects[$this->type]:$this->type));
$this->size = 1;
if($this->type === OBJECT_PAINTING){
$this->isStatic = true;
}
break;
}
$this->updateLast();
@ -346,7 +352,7 @@ class Entity extends Position{
$this->tickCounter = 0;
}
if(($this->class === ENTITY_ITEM or $this->class === ENTITY_MOB or $this->class === ENTITY_PLAYER or $this->class === ENTITY_FALLING)){
if($this->isStatic === false){
$startX = ((int) round($this->x - 0.5)) - 1;
$y = (int) round($this->y - 1);
$startZ = ((int) round($this->z - 0.5)) - 1;
@ -372,56 +378,58 @@ class Entity extends Position{
break;
}
}
if($this->class === ENTITY_ITEM or $this->class === ENTITY_MOB or $this->class === ENTITY_FALLING){
if($this->class !== ENTITY_PLAYER){
$update = false;
$drag = 0.4 * $tdiff;
if($this->speedX != 0){
$this->speedX -= $this->speedX * $drag;
$this->x += $this->speedX * $tdiff;
$update = true;
}
if($this->speedZ != 0){
$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) - 1; $y >= $lim; --$y){
if($this->level->getBlock(new Vector3($x, $y, $z))->isSolid === true){
$ny = $y + 1;
$this->speedY = 0;
$this->support = true;
if($this->class === ENTITY_FALLING){
$this->y = $ny;
$fall = $this->level->getBlock(new Vector3(intval($this->x - 0.5), intval(ceil($this->y)), intval($this->z - 0.5)));
$down = $this->level->getBlock(new Vector3(intval($this->x - 0.5), intval(ceil($this->y) - 1), intval($this->z - 0.5)));
if($fall->isFullBlock === false or $down->isFullBlock === false){
$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"]), true, false, true);
if($this->class !== ENTITY_OBJECT or $support === false){
$drag = 0.4 * $tdiff;
if($this->speedX != 0){
$this->speedX -= $this->speedX * $drag;
$this->x += $this->speedX * $tdiff;
$update = true;
}
if($this->speedZ != 0){
$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) - 1; $y >= $lim; --$y){
if($this->level->getBlock(new Vector3($x, $y, $z))->isSolid === true){
$ny = $y + 1;
$this->speedY = 0;
$this->support = true;
if($this->class === ENTITY_FALLING){
$this->y = $ny;
$fall = $this->level->getBlock(new Vector3(intval($this->x - 0.5), intval(ceil($this->y)), intval($this->z - 0.5)));
$down = $this->level->getBlock(new Vector3(intval($this->x - 0.5), intval(ceil($this->y) - 1), intval($this->z - 0.5)));
if($fall->isFullBlock === false or $down->isFullBlock === false){
$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"]), true, false, true);
}
$this->server->api->handle("entity.motion", $this);
$this->close();
return;
}
$this->server->api->handle("entity.motion", $this);
$this->close();
return;
break;
}
break;
}
}
$this->y = $ny;
$update = true;
}
$this->y = $ny;
$update = true;
}
if($support === false){
$this->speedY -= ($this->class === ENTITY_FALLING ? 18:32) * $tdiff;
$update = true;
}elseif($this->speedY <= 0.1){
}elseif($this->class === ENTITY_OBJECT or $this->speedY <= 0.1){
$this->speedX = 0;
$this->speedY = 0;
$this->speedZ = 0;
@ -435,7 +443,7 @@ class Entity extends Position{
$this->server->api->handle("entity.motion", $this);
}
}elseif($this->class === ENTITY_PLAYER and ($this->player instanceof Player)){
}elseif($this->player instanceof Player){
if($isFlying === true and ($this->player->gamemode & 0x01) === 0x00){
if($this->fallY === false or $this->fallStart === false){
$this->fallY = $y;
@ -468,7 +476,7 @@ class Entity extends Position{
}
}
if($this->class !== ENTITY_OBJECT and ($this->last[0] != $this->x or $this->last[1] != $this->y or $this->last[2] != $this->z or $this->last[3] != $this->yaw or $this->last[4] != $this->pitch)){
if($this->isStatic === false and ($this->last[0] != $this->x or $this->last[1] != $this->y or $this->last[2] != $this->z or $this->last[3] != $this->yaw or $this->last[4] != $this->pitch)){
if($this->class === ENTITY_PLAYER or ($this->last[5] + 8) < $now){
if($this->server->api->handle("entity.move", $this) === false){
if($this->class === ENTITY_PLAYER){
@ -510,7 +518,8 @@ class Entity extends Position{
public function getMetadata(){
$flags = 0;
$flags |= $this->fire > 0 ? 1:0;
$flags |= ($this->crouched === true ? 1:0) << 1;
$flags |= ($this->crouched === true ? 0b10:0) << 1;
$flags |= ($this->inAction === true ? 0b10000:0);
$d = array(
0 => array("type" => 0, "value" => $flags),
1 => array("type" => 1, "value" => $this->air),
@ -600,6 +609,21 @@ class Entity extends Position{
"direction" => $this->getDirection(),
"title" => $this->data["Motive"],
));
}elseif($this->type === OBJECT_ARROW){
$player->dataPacket(MC_ADD_ENTITY, array(
"eid" => $this->eid,
"type" => $this->type,
"x" => $this->x,
"y" => $this->y,
"z" => $this->z,
"did" => 0,
));
$player->dataPacket(MC_SET_ENTITY_MOTION, array(
"eid" => $this->eid,
"speedX" => (int) ($this->speedX * 400),
"speedY" => (int) ($this->speedY * 400),
"speedZ" => (int) ($this->speedZ * 400),
));
}
break;
case ENTITY_FALLING:

View File

@ -144,21 +144,52 @@ class Level{
),
);
}elseif($entity->class === ENTITY_OBJECT){
if($entity->type === OBJECT_PAINTING){
$entities[] = array(
"id" => $entity->type,
"TileX" => $entity->x,
"TileX" => $entity->y,
"TileX" => $entity->z,
"Health" => $entity->health,
"Motive" => $entity->data["Motive"],
"Pos" => array(
0 => $entity->x,
1 => $entity->y,
2 => $entity->z,
),
"Rotation" => array(
0 => $entity->yaw,
1 => $entity->pitch,
),
);
}else{
$entities[] = array(
"id" => $entity->type,
"Health" => $entity->health,
"Pos" => array(
0 => $entity->x,
1 => $entity->y,
2 => $entity->z,
),
"Rotation" => array(
0 => $entity->yaw,
1 => $entity->pitch,
),
);
}
}elseif($entity->class === ENTITY_FALLING){
$entities[] = array(
"id" => $entity->type,
"TileX" => $entity->x,
"TileX" => $entity->y,
"TileX" => $entity->z,
"Health" => $entity->health,
"Motive" => $entity->data["Motive"],
"Tile" => $entity->data["Tile"],
"Pos" => array(
0 => $entity->x,
1 => $entity->y,
2 => $entity->z,
),
"Rotation" => array(
0 => $entity->yaw,
1 => $entity->pitch,
0 => 0,
1 => 0,
),
);
}elseif($entity->class === ENTITY_ITEM){