mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-19 04:05:31 +00:00
Added chest pairing
This commit is contained in:
parent
e8c273fc10
commit
176c371330
153
src/Player.php
153
src/Player.php
@ -1184,7 +1184,7 @@ class Player{
|
||||
"x" => $this->data->get("position")["x"],
|
||||
"y" => $this->data->get("position")["y"],
|
||||
"z" => $this->data->get("position")["z"],
|
||||
"unknown1" => 0,
|
||||
"generator" => 0,
|
||||
"gamemode" => ($this->gamemode & 0x01),
|
||||
"eid" => 0,
|
||||
));
|
||||
@ -1651,14 +1651,27 @@ class Player{
|
||||
}
|
||||
$this->craftingItems = array();
|
||||
$this->toCraft = array();
|
||||
if(isset($this->windows[$data["windowid"]]) and $this->windows[$data["windowid"]]->class === TILE_CHEST){
|
||||
$this->server->api->player->broadcastPacket($this->server->api->player->getAll($this->level), MC_TILE_EVENT, array(
|
||||
"x" => $this->windows[$data["windowid"]]->x,
|
||||
"y" => $this->windows[$data["windowid"]]->y,
|
||||
"z" => $this->windows[$data["windowid"]]->z,
|
||||
"case1" => 1,
|
||||
"case2" => 0,
|
||||
));
|
||||
if(isset($this->windows[$data["windowid"]])){
|
||||
if(is_array($this->windows[$data["windowid"]])){
|
||||
$all = $this->server->api->player->getAll($this->level);
|
||||
foreach($this->windows[$data["windowid"]] as $ob){
|
||||
$this->server->api->player->broadcastPacket($all, MC_TILE_EVENT, array(
|
||||
"x" => $ob->x,
|
||||
"y" => $ob->y,
|
||||
"z" => $ob->z,
|
||||
"case1" => 1,
|
||||
"case2" => 0,
|
||||
));
|
||||
}
|
||||
}elseif($this->windows[$data["windowid"]]->class === TILE_CHEST){
|
||||
$this->server->api->player->broadcastPacket($this->server->api->player->getAll($this->level), MC_TILE_EVENT, array(
|
||||
"x" => $this->windows[$data["windowid"]]->x,
|
||||
"y" => $this->windows[$data["windowid"]]->y,
|
||||
"z" => $this->windows[$data["windowid"]]->z,
|
||||
"case1" => 1,
|
||||
"case2" => 0,
|
||||
));
|
||||
}
|
||||
}
|
||||
unset($this->windows[$data["windowid"]]);
|
||||
|
||||
@ -1725,46 +1738,94 @@ class Player{
|
||||
if(!isset($this->windows[$data["windowid"]])){
|
||||
break;
|
||||
}
|
||||
$tile = $this->windows[$data["windowid"]];
|
||||
if(($tile->class !== TILE_CHEST and $tile->class !== TILE_FURNACE) or $data["slot"] < 0 or ($tile->class === TILE_CHEST and $data["slot"] >= CHEST_SLOTS) or ($tile->class === TILE_FURNACE and $data["slot"] >= FURNACE_SLOTS)){
|
||||
break;
|
||||
}
|
||||
$done = false;
|
||||
$item = BlockAPI::getItem($data["block"], $data["meta"], $data["stack"]);
|
||||
|
||||
$slot = $tile->getSlot($data["slot"]);
|
||||
$done = true;
|
||||
if($this->server->api->dhandle("player.container.slot", array(
|
||||
"tile" => $tile,
|
||||
"slot" => $data["slot"],
|
||||
"slotdata" => $slot,
|
||||
"itemdata" => $item,
|
||||
"player" => $this,
|
||||
)) === false){
|
||||
$this->dataPacket(MC_CONTAINER_SET_SLOT, array(
|
||||
"windowid" => $data["windowid"],
|
||||
"slot" => $data["slot"],
|
||||
"block" => $slot->getID(),
|
||||
"stack" => $slot->count,
|
||||
"meta" => $slot->getMetadata(),
|
||||
));
|
||||
break;
|
||||
}
|
||||
if($item->getID() !== AIR and $slot->getID() == $item->getID()){
|
||||
if($slot->count < $item->count){
|
||||
if($this->removeItem($item->getID(), $item->getMetadata(), $item->count - $slot->count, false) === false){
|
||||
break;
|
||||
}
|
||||
}elseif($slot->count > $item->count){
|
||||
$this->addItem($item->getID(), $item->getMetadata(), $slot->count - $item->count, false);
|
||||
}
|
||||
}else{
|
||||
if($this->removeItem($item->getID(), $item->getMetadata(), $item->count, false) === false){
|
||||
if(is_array($this->windows[$data["windowid"]])){
|
||||
$tiles = $this->windows[$data["windowid"]];
|
||||
if($data["slot"] > 0 and $data["slot"] < CHEST_SLOTS){
|
||||
$tile = $tiles[0];
|
||||
$slotn = $data["slot"];
|
||||
$offset = 0;
|
||||
}elseif($data["slot"] >= CHEST_SLOTS and $data["slot"] <= (CHEST_SLOTS << 1)){
|
||||
$tile = $tiles[1];
|
||||
$slotn = $data["slot"] - CHEST_SLOTS;
|
||||
$offset = CHEST_SLOTS;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
$this->addItem($slot->getID(), $slot->getMetadata(), $slot->count, false);
|
||||
|
||||
$item = BlockAPI::getItem($data["block"], $data["meta"], $data["stack"]);
|
||||
|
||||
$slot = $tile->getSlot($slotn);
|
||||
if($this->server->api->dhandle("player.container.slot", array(
|
||||
"tile" => $tile,
|
||||
"slot" => $data["slot"],
|
||||
"slotdata" => $slot,
|
||||
"itemdata" => $item,
|
||||
"player" => $this,
|
||||
)) === false){
|
||||
$this->dataPacket(MC_CONTAINER_SET_SLOT, array(
|
||||
"windowid" => $data["windowid"],
|
||||
"slot" => $data["slot"],
|
||||
"block" => $slot->getID(),
|
||||
"stack" => $slot->count,
|
||||
"meta" => $slot->getMetadata(),
|
||||
));
|
||||
break;
|
||||
}
|
||||
if($item->getID() !== AIR and $slot->getID() == $item->getID()){
|
||||
if($slot->count < $item->count){
|
||||
if($this->removeItem($item->getID(), $item->getMetadata(), $item->count - $slot->count, false) === false){
|
||||
break;
|
||||
}
|
||||
}elseif($slot->count > $item->count){
|
||||
$this->addItem($item->getID(), $item->getMetadata(), $slot->count - $item->count, false);
|
||||
}
|
||||
}else{
|
||||
if($this->removeItem($item->getID(), $item->getMetadata(), $item->count, false) === false){
|
||||
break;
|
||||
}
|
||||
$this->addItem($slot->getID(), $slot->getMetadata(), $slot->count, false);
|
||||
}
|
||||
$tile->setSlot($slotn, $item, true, $offset);
|
||||
}else{
|
||||
$tile = $this->windows[$data["windowid"]];
|
||||
if(($tile->class !== TILE_CHEST and $tile->class !== TILE_FURNACE) or $data["slot"] < 0 or ($tile->class === TILE_CHEST and $data["slot"] >= CHEST_SLOTS) or ($tile->class === TILE_FURNACE and $data["slot"] >= FURNACE_SLOTS)){
|
||||
break;
|
||||
}
|
||||
$item = BlockAPI::getItem($data["block"], $data["meta"], $data["stack"]);
|
||||
|
||||
$slot = $tile->getSlot($data["slot"]);
|
||||
if($this->server->api->dhandle("player.container.slot", array(
|
||||
"tile" => $tile,
|
||||
"slot" => $data["slot"],
|
||||
"slotdata" => $slot,
|
||||
"itemdata" => $item,
|
||||
"player" => $this,
|
||||
)) === false){
|
||||
$this->dataPacket(MC_CONTAINER_SET_SLOT, array(
|
||||
"windowid" => $data["windowid"],
|
||||
"slot" => $data["slot"],
|
||||
"block" => $slot->getID(),
|
||||
"stack" => $slot->count,
|
||||
"meta" => $slot->getMetadata(),
|
||||
));
|
||||
break;
|
||||
}
|
||||
if($item->getID() !== AIR and $slot->getID() == $item->getID()){
|
||||
if($slot->count < $item->count){
|
||||
if($this->removeItem($item->getID(), $item->getMetadata(), $item->count - $slot->count, false) === false){
|
||||
break;
|
||||
}
|
||||
}elseif($slot->count > $item->count){
|
||||
$this->addItem($item->getID(), $item->getMetadata(), $slot->count - $item->count, false);
|
||||
}
|
||||
}else{
|
||||
if($this->removeItem($item->getID(), $item->getMetadata(), $item->count, false) === false){
|
||||
break;
|
||||
}
|
||||
$this->addItem($slot->getID(), $slot->getMetadata(), $slot->count, false);
|
||||
}
|
||||
$tile->setSlot($data["slot"], $item);
|
||||
}
|
||||
$tile->setSlot($data["slot"], $item);
|
||||
break;
|
||||
case MC_SEND_INVENTORY: //TODO, Mojang, enable this ´^_^`
|
||||
if($this->spawned === false){
|
||||
|
@ -65,32 +65,11 @@ class BurningFurnaceBlock extends SolidBlock{
|
||||
));
|
||||
}
|
||||
|
||||
if($furnace->class !== TILE_FURNACE or ($player->gamemode & 0x01) === 0x01){
|
||||
if(($player->gamemode & 0x01) === 0x01){
|
||||
return true;
|
||||
}
|
||||
$player->windowCnt++;
|
||||
$player->windowCnt = $id = max(2, $player->windowCnt % 99);
|
||||
$player->windows[$id] = $furnace;
|
||||
$player->dataPacket(MC_CONTAINER_OPEN, array(
|
||||
"windowid" => $id,
|
||||
"type" => WINDOW_FURNACE,
|
||||
"slots" => FURNACE_SLOTS,
|
||||
"title" => "Furnace",
|
||||
));
|
||||
$slots = array();
|
||||
for($s = 0; $s < FURNACE_SLOTS; ++$s){
|
||||
$slot = $furnace->getSlot($s);
|
||||
if($slot->getID() > 0 and $slot->count > 0){
|
||||
$slots[] = $slot;
|
||||
}else{
|
||||
$slots[] = BlockAPI::getItem(AIR, 0, 0);
|
||||
}
|
||||
}
|
||||
$player->dataPacket(MC_CONTAINER_SET_CONTENT, array(
|
||||
"windowid" => $id,
|
||||
"count" => count($slots),
|
||||
"slots" => $slots
|
||||
));
|
||||
|
||||
$furnace->openInventory($player);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -31,50 +31,44 @@ class ChestBlock extends TransparentBlock{
|
||||
$this->isActivable = true;
|
||||
}
|
||||
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
|
||||
$server = ServerAPI::request();
|
||||
$faces = array(
|
||||
0 => 4,
|
||||
1 => 2,
|
||||
2 => 5,
|
||||
3 => 3,
|
||||
);
|
||||
$facesc = array(
|
||||
2 => 4,
|
||||
3 => 2,
|
||||
4 => 5,
|
||||
5 => 3,
|
||||
);
|
||||
|
||||
$chest = false;
|
||||
$this->meta = $faces[$player->entity->getDirection()];
|
||||
|
||||
for($side = 2; $side <= 5; ++$side){
|
||||
if(($this->meta === 4 or $this->meta === 5) and ($side === 4 or $side === 5)){
|
||||
continue;
|
||||
}elseif(($this->meta === 3 or $this->meta === 2) and ($side === 2 or $side === 3)){
|
||||
continue;
|
||||
}
|
||||
$c = $this->getSide($side);
|
||||
if($c instanceof ChestBlock){
|
||||
/*if($chest !== false){ //No chests in the middle
|
||||
return false;
|
||||
}*/
|
||||
$chest = array($side, $c);
|
||||
break;
|
||||
if(($c instanceof ChestBlock) and $c->getMetadata() === $this->meta){
|
||||
if((($tile = $server->api->tile->get($c)) instanceof Tile) and !$tile->isPaired()){
|
||||
$chest = $tile;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($chest !== false and ($chest[1]->getSide($chest[0]) instanceof ChestBlock)){ //Already double chest
|
||||
return false;
|
||||
}
|
||||
|
||||
if($chest !== false){
|
||||
$this->meta = $facesc[$chest[0]];
|
||||
$this->level->setBlock($chest[1], new ChestBlock($this->meta));
|
||||
}else{
|
||||
$this->meta = $faces[$player->entity->getDirection()];
|
||||
}
|
||||
$this->level->setBlock($block, $this);
|
||||
$server = ServerAPI::request();
|
||||
$server->api->tile->add($this->level, TILE_CHEST, $this->x, $this->y, $this->z, array(
|
||||
$tile = $server->api->tile->add($this->level, TILE_CHEST, $this->x, $this->y, $this->z, array(
|
||||
"Items" => array(),
|
||||
"id" => TILE_CHEST,
|
||||
"x" => $this->x,
|
||||
"y" => $this->y,
|
||||
"z" => $this->z
|
||||
));
|
||||
if($chest instanceof Tile){
|
||||
$chest->pairWith($tile);
|
||||
$tile->pairWith($chest);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -104,40 +98,13 @@ class ChestBlock extends TransparentBlock{
|
||||
));
|
||||
}
|
||||
|
||||
if($chest->class !== TILE_CHEST or ($player->gamemode & 0x01) === 0x01){
|
||||
|
||||
|
||||
if(($player->gamemode & 0x01) === 0x01){
|
||||
return true;
|
||||
}
|
||||
$player->windowCnt++;
|
||||
$player->windowCnt = $id = max(2, $player->windowCnt % 99);
|
||||
$player->windows[$id] = $chest;
|
||||
$player->dataPacket(MC_CONTAINER_OPEN, array(
|
||||
"windowid" => $id,
|
||||
"type" => WINDOW_CHEST,
|
||||
"slots" => CHEST_SLOTS,
|
||||
"title" => "Chest",
|
||||
));
|
||||
$server->api->player->broadcastPacket($server->api->player->getAll($this->level), MC_TILE_EVENT, array(
|
||||
"x" => $this->x,
|
||||
"y" => $this->y,
|
||||
"z" => $this->z,
|
||||
"case1" => 1,
|
||||
"case2" => 2,
|
||||
));
|
||||
$slots = array();
|
||||
for($s = 0; $s < CHEST_SLOTS; ++$s){
|
||||
$slot = $chest->getSlot($s);
|
||||
if($slot->getID() > AIR and $slot->count > 0){
|
||||
$slots[] = $slot;
|
||||
}else{
|
||||
$slots[] = BlockAPI::getItem(AIR, 0, 0);
|
||||
}
|
||||
}
|
||||
$player->dataPacket(MC_CONTAINER_SET_CONTENT, array(
|
||||
"windowid" => $id,
|
||||
"count" => count($slots),
|
||||
"slots" => $slots
|
||||
));
|
||||
|
||||
$chest->openInventory($player);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -202,7 +202,7 @@ class CustomPacketHandler{
|
||||
case MC_START_GAME:
|
||||
if($this->c === false){
|
||||
$this->data["seed"] = Utils::readInt($this->get(4));
|
||||
$this->data["unknown1"] = Utils::readInt($this->get(4));
|
||||
$this->data["generator"] = Utils::readInt($this->get(4));
|
||||
$this->data["gamemode"] = Utils::readInt($this->get(4));
|
||||
$this->data["eid"] = Utils::readInt($this->get(4));
|
||||
$this->data["x"] = Utils::readFloat($this->get(4));
|
||||
@ -210,7 +210,7 @@ class CustomPacketHandler{
|
||||
$this->data["z"] = Utils::readFloat($this->get(4));
|
||||
}else{
|
||||
$this->raw .= Utils::writeInt($this->data["seed"]);
|
||||
$this->raw .= Utils::writeInt($this->data["unknown1"]);
|
||||
$this->raw .= Utils::writeInt($this->data["generator"]);
|
||||
$this->raw .= Utils::writeInt($this->data["gamemode"]);
|
||||
$this->raw .= Utils::writeInt($this->data["eid"]);
|
||||
$this->raw .= Utils::writeFloat($this->data["x"]);
|
||||
|
@ -106,6 +106,120 @@ class Tile extends Position{
|
||||
|
||||
$tile->data["pairx"] = $this->x;
|
||||
$tile->data["pairz"] = $this->z;
|
||||
|
||||
$this->server->api->tile->spawnToAll($this);
|
||||
$this->server->api->tile->spawnToAll($tile);
|
||||
}
|
||||
|
||||
public function unpair(){
|
||||
if(!$this->isPaired()){
|
||||
return false;
|
||||
}
|
||||
|
||||
$tile = $this->getPair();
|
||||
unset($this->data["pairx"], $this->data["pairz"], $ile->data["pairx"], $tile->data["pairz"]);
|
||||
|
||||
$this->server->api->tile->spawnToAll($this);
|
||||
if($tile instanceof Tile){
|
||||
$this->server->api->tile->spawnToAll($tile);
|
||||
}
|
||||
}
|
||||
|
||||
public function openInventory(Player $player){
|
||||
if($this->class === TILE_CHEST){
|
||||
$player->windowCnt++;
|
||||
$player->windowCnt = $id = max(2, $player->windowCnt % 99);
|
||||
if(($pair = $this->getPair()) !== false){
|
||||
if(($pair->x + ($pair->z << 13)) > ($this->x + ($this->z << 13))){ //Order them correctly
|
||||
$player->windows[$id] = array(
|
||||
$pair,
|
||||
$this
|
||||
);
|
||||
}else{
|
||||
$player->windows[$id] = array(
|
||||
$this,
|
||||
$pair
|
||||
);
|
||||
}
|
||||
}else{
|
||||
$player->windows[$id] = $this;
|
||||
}
|
||||
$player->dataPacket(MC_CONTAINER_OPEN, array(
|
||||
"windowid" => $id,
|
||||
"type" => WINDOW_CHEST,
|
||||
"slots" => is_array($player->windows[$id]) ? CHEST_SLOTS << 1:CHEST_SLOTS,
|
||||
"title" => "Chest",
|
||||
));
|
||||
$slots = array();
|
||||
|
||||
if(is_array($player->windows[$id])){
|
||||
$all = $this->server->api->player->getAll($this->level);
|
||||
foreach($player->windows[$id] as $ob){
|
||||
$this->server->api->player->broadcastPacket($all, MC_TILE_EVENT, array(
|
||||
"x" => $ob->x,
|
||||
"y" => $ob->y,
|
||||
"z" => $ob->z,
|
||||
"case1" => 1,
|
||||
"case2" => 2,
|
||||
));
|
||||
for($s = 0; $s < CHEST_SLOTS; ++$s){
|
||||
$slot = $ob->getSlot($s);
|
||||
if($slot->getID() > AIR and $slot->count > 0){
|
||||
$slots[] = $slot;
|
||||
}else{
|
||||
$slots[] = BlockAPI::getItem(AIR, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
$this->server->api->player->broadcastPacket($this->server->api->player->getAll($this->level), MC_TILE_EVENT, array(
|
||||
"x" => $this->x,
|
||||
"y" => $this->y,
|
||||
"z" => $this->z,
|
||||
"case1" => 1,
|
||||
"case2" => 2,
|
||||
));
|
||||
for($s = 0; $s < CHEST_SLOTS; ++$s){
|
||||
$slot = $this->getSlot($s);
|
||||
if($slot->getID() > AIR and $slot->count > 0){
|
||||
$slots[] = $slot;
|
||||
}else{
|
||||
$slots[] = BlockAPI::getItem(AIR, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
$player->dataPacket(MC_CONTAINER_SET_CONTENT, array(
|
||||
"windowid" => $id,
|
||||
"count" => count($slots),
|
||||
"slots" => $slots
|
||||
));
|
||||
return true;
|
||||
}elseif($this->class === TILE_FURNACE){
|
||||
$player->windowCnt++;
|
||||
$player->windowCnt = $id = max(2, $player->windowCnt % 99);
|
||||
$player->windows[$id] = $this;
|
||||
$player->dataPacket(MC_CONTAINER_OPEN, array(
|
||||
"windowid" => $id,
|
||||
"type" => WINDOW_FURNACE,
|
||||
"slots" => FURNACE_SLOTS,
|
||||
"title" => "Furnace",
|
||||
));
|
||||
$slots = array();
|
||||
for($s = 0; $s < FURNACE_SLOTS; ++$s){
|
||||
$slot = $this->getSlot($s);
|
||||
if($slot->getID() > AIR and $slot->count > 0){
|
||||
$slots[] = $slot;
|
||||
}else{
|
||||
$slots[] = BlockAPI::getItem(AIR, 0, 0);
|
||||
}
|
||||
}
|
||||
$player->dataPacket(MC_CONTAINER_SET_CONTENT, array(
|
||||
"windowid" => $id,
|
||||
"count" => count($slots),
|
||||
"slots" => $slots
|
||||
));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public function update(){
|
||||
@ -195,7 +309,7 @@ class Tile extends Position{
|
||||
}
|
||||
}
|
||||
|
||||
public function setSlot($s, Item $item, $update = true){
|
||||
public function setSlot($s, Item $item, $update = true, $offset = 0){
|
||||
$i = $this->getSlotIndex($s);
|
||||
$d = array(
|
||||
"Count" => $item->count,
|
||||
@ -216,7 +330,7 @@ class Tile extends Position{
|
||||
}
|
||||
$this->server->api->dhandle("tile.container.slot", array(
|
||||
"tile" => $this,
|
||||
"slot" => $s,
|
||||
"slot" => $s + $offset,
|
||||
"slotdata" => $item,
|
||||
));
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user