mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-16 10:49:10 +00:00
Implemented new Inventory windows on Player, Chest and Furnace
This commit is contained in:
parent
27e82ea60a
commit
53749483c3
@ -28,7 +28,6 @@ use pocketmine\event\player\PlayerAchievementAwardedEvent;
|
|||||||
use pocketmine\event\player\PlayerChatEvent;
|
use pocketmine\event\player\PlayerChatEvent;
|
||||||
use pocketmine\event\player\PlayerCommandPreprocessEvent;
|
use pocketmine\event\player\PlayerCommandPreprocessEvent;
|
||||||
use pocketmine\event\player\PlayerGameModeChangeEvent;
|
use pocketmine\event\player\PlayerGameModeChangeEvent;
|
||||||
use pocketmine\event\player\PlayerItemHeldEvent;
|
|
||||||
use pocketmine\event\player\PlayerJoinEvent;
|
use pocketmine\event\player\PlayerJoinEvent;
|
||||||
use pocketmine\event\player\PlayerKickEvent;
|
use pocketmine\event\player\PlayerKickEvent;
|
||||||
use pocketmine\event\player\PlayerLoginEvent;
|
use pocketmine\event\player\PlayerLoginEvent;
|
||||||
@ -37,7 +36,10 @@ use pocketmine\event\player\PlayerQuitEvent;
|
|||||||
use pocketmine\event\player\PlayerRespawnEvent;
|
use pocketmine\event\player\PlayerRespawnEvent;
|
||||||
use pocketmine\event\server\DataPacketReceiveEvent;
|
use pocketmine\event\server\DataPacketReceiveEvent;
|
||||||
use pocketmine\event\server\DataPacketSendEvent;
|
use pocketmine\event\server\DataPacketSendEvent;
|
||||||
|
use pocketmine\inventory\Inventory;
|
||||||
|
use pocketmine\inventory\InventoryHolder;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\level\format\pmf\LevelFormat;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
use pocketmine\level\Position;
|
use pocketmine\level\Position;
|
||||||
use pocketmine\math\Vector3;
|
use pocketmine\math\Vector3;
|
||||||
@ -48,9 +50,6 @@ use pocketmine\nbt\tag\Compound;
|
|||||||
use pocketmine\nbt\tag\String;
|
use pocketmine\nbt\tag\String;
|
||||||
use pocketmine\network\protocol\AdventureSettingsPacket;
|
use pocketmine\network\protocol\AdventureSettingsPacket;
|
||||||
use pocketmine\network\protocol\ChunkDataPacket;
|
use pocketmine\network\protocol\ChunkDataPacket;
|
||||||
use pocketmine\network\protocol\ContainerClosePacket;
|
|
||||||
use pocketmine\network\protocol\ContainerSetContentPacket;
|
|
||||||
use pocketmine\network\protocol\ContainerSetSlotPacket;
|
|
||||||
use pocketmine\network\protocol\DataPacket;
|
use pocketmine\network\protocol\DataPacket;
|
||||||
use pocketmine\network\protocol\DisconnectPacket;
|
use pocketmine\network\protocol\DisconnectPacket;
|
||||||
use pocketmine\network\protocol\Info as ProtocolInfo;
|
use pocketmine\network\protocol\Info as ProtocolInfo;
|
||||||
@ -61,7 +60,6 @@ use pocketmine\network\protocol\ServerHandshakePacket;
|
|||||||
use pocketmine\network\protocol\SetSpawnPositionPacket;
|
use pocketmine\network\protocol\SetSpawnPositionPacket;
|
||||||
use pocketmine\network\protocol\SetTimePacket;
|
use pocketmine\network\protocol\SetTimePacket;
|
||||||
use pocketmine\network\protocol\StartGamePacket;
|
use pocketmine\network\protocol\StartGamePacket;
|
||||||
use pocketmine\network\protocol\TileEventPacket;
|
|
||||||
use pocketmine\network\protocol\UnknownPacket;
|
use pocketmine\network\protocol\UnknownPacket;
|
||||||
use pocketmine\network\protocol\UpdateBlockPacket;
|
use pocketmine\network\protocol\UpdateBlockPacket;
|
||||||
use pocketmine\network\raknet\Info;
|
use pocketmine\network\raknet\Info;
|
||||||
@ -69,11 +67,8 @@ use pocketmine\network\raknet\Packet;
|
|||||||
use pocketmine\permission\PermissibleBase;
|
use pocketmine\permission\PermissibleBase;
|
||||||
use pocketmine\permission\PermissionAttachment;
|
use pocketmine\permission\PermissionAttachment;
|
||||||
use pocketmine\plugin\Plugin;
|
use pocketmine\plugin\Plugin;
|
||||||
use pocketmine\level\format\pmf\LevelFormat;
|
|
||||||
use pocketmine\recipes\Crafting;
|
use pocketmine\recipes\Crafting;
|
||||||
use pocketmine\scheduler\CallbackTask;
|
use pocketmine\scheduler\CallbackTask;
|
||||||
use pocketmine\tile\Chest;
|
|
||||||
use pocketmine\tile\Furnace;
|
|
||||||
use pocketmine\tile\Sign;
|
use pocketmine\tile\Sign;
|
||||||
use pocketmine\tile\Spawnable;
|
use pocketmine\tile\Spawnable;
|
||||||
use pocketmine\tile\Tile;
|
use pocketmine\tile\Tile;
|
||||||
@ -84,7 +79,7 @@ use pocketmine\utils\TextFormat;
|
|||||||
* Main class that handles networking, recovery, and packet sending to the server part
|
* Main class that handles networking, recovery, and packet sending to the server part
|
||||||
* TODO: Move reliability layer
|
* TODO: Move reliability layer
|
||||||
*/
|
*/
|
||||||
class Player extends Human implements CommandSender, IPlayer{
|
class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||||
|
|
||||||
const SURVIVAL = 0;
|
const SURVIVAL = 0;
|
||||||
const CREATIVE = 1;
|
const CREATIVE = 1;
|
||||||
@ -102,8 +97,13 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
public $loggedIn = false;
|
public $loggedIn = false;
|
||||||
public $gamemode;
|
public $gamemode;
|
||||||
public $lastBreak;
|
public $lastBreak;
|
||||||
public $windowCnt = 2;
|
|
||||||
public $windows = [];
|
protected $windowCnt = 2;
|
||||||
|
/** @var \SplObjectStorage<Inventory> */
|
||||||
|
protected $windows;
|
||||||
|
/** @var Inventory[] */
|
||||||
|
protected $windowIndex = [];
|
||||||
|
|
||||||
public $blocked = true;
|
public $blocked = true;
|
||||||
public $achievements = [];
|
public $achievements = [];
|
||||||
public $chunksLoaded = [];
|
public $chunksLoaded = [];
|
||||||
@ -358,6 +358,7 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
* @param integer $MTU
|
* @param integer $MTU
|
||||||
*/
|
*/
|
||||||
public function __construct($clientID, $ip, $port, $MTU){
|
public function __construct($clientID, $ip, $port, $MTU){
|
||||||
|
$this->windows = new \SplObjectStorage();
|
||||||
$this->perm = new PermissibleBase($this);
|
$this->perm = new PermissibleBase($this);
|
||||||
$this->namedtag = new Compound();
|
$this->namedtag = new Compound();
|
||||||
$this->bigCnt = 0;
|
$this->bigCnt = 0;
|
||||||
@ -1322,6 +1323,7 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
if($p !== $this and strtolower($p->getName()) === strtolower($this->getName())){
|
if($p !== $this and strtolower($p->getName()) === strtolower($this->getName())){
|
||||||
if($p->kick("logged in from another location") === false){
|
if($p->kick("logged in from another location") === false){
|
||||||
$this->close($this->getName() . " has left the game", "already logged in");
|
$this->close($this->getName() . " has left the game", "already logged in");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}else{
|
}else{
|
||||||
break;
|
break;
|
||||||
@ -1432,9 +1434,9 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
$this->spawned = true;
|
$this->spawned = true;
|
||||||
$this->spawnToAll();
|
$this->spawnToAll();
|
||||||
|
|
||||||
$this->sendInventory();
|
|
||||||
$this->sendSettings();
|
$this->sendSettings();
|
||||||
$this->sendArmor();
|
$this->getInventory()->sendContents($this);
|
||||||
|
$this->getInventory()->sendArmorContents($this);
|
||||||
$this->tasks[] = $this->server->getScheduler()->scheduleDelayedTask(new CallbackTask(array($this, "orderChunks")), 30);
|
$this->tasks[] = $this->server->getScheduler()->scheduleDelayedTask(new CallbackTask(array($this, "orderChunks")), 30);
|
||||||
|
|
||||||
$this->blocked = false;
|
$this->blocked = false;
|
||||||
@ -1510,26 +1512,13 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
$item = $this->getSlot($packet->slot);
|
$item = $this->inventory->getItem($packet->slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isset($item) or $packet->slot === false){
|
if(!isset($item) or $packet->slot === false){
|
||||||
$this->sendInventorySlot($packet->slot);
|
$this->inventory->sendSlot($packet->slot, $this);
|
||||||
}else{
|
}else{
|
||||||
$this->server->getPluginManager()->callEvent($ev = new PlayerItemHeldEvent($this, $item, $packet->slot, 0));
|
$this->inventory->setHeldItemSlot($packet->slot);
|
||||||
if($ev->isCancelled()){
|
|
||||||
$this->sendInventorySlot($packet->slot);
|
|
||||||
}elseif($item instanceof Item){
|
|
||||||
$this->setEquipmentSlot(0, $packet->slot);
|
|
||||||
$this->setCurrentEquipmentSlot(0);
|
|
||||||
if(($this->gamemode & 0x01) === 0){
|
|
||||||
if(!in_array($this->slot, $this->hotbar)){
|
|
||||||
array_pop($this->hotbar);
|
|
||||||
array_unshift($this->hotbar, $this->slot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->inAction === true){
|
if($this->inAction === true){
|
||||||
@ -1576,18 +1565,21 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
if($blockVector->distance($this) > 10){
|
if($blockVector->distance($this) > 10){
|
||||||
|
|
||||||
}elseif(($this->gamemode & 0x01) === 1){
|
}elseif(($this->gamemode & 0x01) === 1){
|
||||||
$item = Item::get(Block::$creative[$this->getCurrentEquipment()][0], Block::$creative[$this->getCurrentEquipment()][1], 1);
|
$item = Item::get(
|
||||||
|
Block::$creative[$this->inventory->getHeldItemSlot()][0],
|
||||||
|
Block::$creative[$this->inventory->getHeldItemSlot()][1],
|
||||||
|
1
|
||||||
|
);
|
||||||
if($this->getLevel()->useItemOn($blockVector, $item, $packet->face, $packet->fx, $packet->fy, $packet->fz, $this) === true){
|
if($this->getLevel()->useItemOn($blockVector, $item, $packet->face, $packet->fx, $packet->fy, $packet->fz, $this) === true){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}elseif($this->getSlot($this->getCurrentEquipment())->getID() !== $packet->item or ($this->getSlot($this->getCurrentEquipment())->isTool() === false and $this->getSlot($this->getCurrentEquipment())->getDamage() !== $packet->meta)){
|
}elseif($this->inventory->getItemInHand()->getID() !== $packet->item or ($this->inventory->getItemInHand()->isTool() === false and $this->inventory->getItemInHand()->getDamage() !== $packet->meta)){
|
||||||
$this->sendInventorySlot($this->getCurrentEquipment());
|
$this->inventory->sendHeldItem($this);
|
||||||
}else{
|
}else{
|
||||||
$item = clone $this->getSlot($this->getCurrentEquipment());
|
$item = clone $this->inventory->getItemInHand();
|
||||||
//TODO: Implement adventure mode checks
|
//TODO: Implement adventure mode checks
|
||||||
if($this->getLevel()->useItemOn($blockVector, $item, $packet->face, $packet->fx, $packet->fy, $packet->fz, $this) === true){
|
if($this->getLevel()->useItemOn($blockVector, $item, $packet->face, $packet->fx, $packet->fy, $packet->fz, $this) === true){
|
||||||
$this->setSlot($this->getCurrentEquipment(), $item);
|
$this->inventory->setItemInHand($item);
|
||||||
$this->sendInventorySlot($this->getCurrentEquipment());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1704,15 +1696,19 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
|
|
||||||
|
|
||||||
if(($this->gamemode & 0x01) === 1){
|
if(($this->gamemode & 0x01) === 1){
|
||||||
$item = Item::get(Block::$creative[$this->getCurrentEquipment()][0], Block::$creative[$this->getCurrentEquipment()][1], 1);
|
$item = Item::get(
|
||||||
|
Block::$creative[$this->inventory->getHeldItemSlot()][0],
|
||||||
|
Block::$creative[$this->inventory->getHeldItemSlot()][1],
|
||||||
|
1
|
||||||
|
);
|
||||||
}else{
|
}else{
|
||||||
$item = clone $this->getSlot($this->getCurrentEquipment());
|
$item = clone $this->inventory->getItemInHand();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(($drops = $this->getLevel()->useBreakOn($vector, $item)) !== true){
|
if(($drops = $this->getLevel()->useBreakOn($vector, $item)) !== true){
|
||||||
if(($this->gamemode & 0x01) === 0){
|
if(($this->gamemode & 0x01) === 0){
|
||||||
//TODO: drop items
|
//TODO: drop items
|
||||||
$this->setSlot($this->getCurrentEquipment(), $item);
|
$this->inventory->setItemInHand($item);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1739,33 +1735,22 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
}else{
|
}else{
|
||||||
$s = Item::get($s + 256, 0, 1);
|
$s = Item::get($s + 256, 0, 1);
|
||||||
}
|
}
|
||||||
$slot = $this->getArmorSlot($i);
|
$slot = $this->inventory->getArmorItem($i);
|
||||||
if($slot->getID() !== Item::AIR and $s->getID() === Item::AIR){
|
if($slot->getID() !== Item::AIR and $s->getID() === Item::AIR){
|
||||||
if($this->setArmorSlot($i, Item::get(Item::AIR, 0, 0)) === false){
|
$this->inventory->setArmorItem($i, Item::get(Item::AIR, 0, 0));
|
||||||
$this->sendArmor();
|
}elseif($s->getID() !== Item::AIR and $slot->getID() === Item::AIR and ($sl = $this->inventory->first($s)) !== -1){
|
||||||
$this->sendInventory();
|
if($this->inventory->setArmorItem($i, $this->inventory->getItem($sl)) === false){
|
||||||
|
$this->inventory->sendContents($this);
|
||||||
}else{
|
}else{
|
||||||
$this->addItem($slot);
|
$this->inventory->setItem($sl, Item::get(Item::AIR, 0, 0));
|
||||||
$packet->slots[$i] = 255;
|
|
||||||
}
|
}
|
||||||
}elseif($s->getID() !== Item::AIR and $slot->getID() === Item::AIR and ($sl = $this->hasItem($s, false)) !== false){
|
}elseif($s->getID() !== Item::AIR and $slot->getID() !== Item::AIR and ($slot->getID() !== $s->getID() or $slot->getDamage() !== $s->getDamage()) and ($sl = $this->inventory->first($s)) !== -1){
|
||||||
if($this->setArmorSlot($i, $this->getSlot($sl)) === false){
|
if($this->inventory->setArmorItem($i, $this->inventory->getItem($sl)) === false){
|
||||||
$this->sendArmor();
|
$this->inventory->sendContents($this);
|
||||||
$this->sendInventory();
|
|
||||||
}else{
|
}else{
|
||||||
$this->setSlot($sl, Item::get(Item::AIR, 0, 0));
|
$this->inventory->setItem($sl, $slot);
|
||||||
}
|
}
|
||||||
}elseif($s->getID() !== Item::AIR and $slot->getID() !== Item::AIR and ($slot->getID() !== $s->getID() or $slot->getDamage() !== $s->getDamage()) and ($sl = $this->hasItem($s, false)) !== false){
|
|
||||||
if($this->setArmorSlot($i, $this->getSlot($sl)) === false){
|
|
||||||
$this->sendArmor();
|
|
||||||
$this->sendInventory();
|
|
||||||
}else{
|
|
||||||
$this->setSlot($sl, $slot);
|
|
||||||
}
|
}
|
||||||
}else{
|
|
||||||
$packet->slots[$i] = 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->inAction === true){
|
if($this->inAction === true){
|
||||||
@ -1884,7 +1869,10 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
//$this->entity->setHealth(20, "respawn", true);
|
//$this->entity->setHealth(20, "respawn", true);
|
||||||
//$this->entity->updateMetadata();
|
//$this->entity->updateMetadata();
|
||||||
|
|
||||||
$this->sendInventory();
|
$this->sendSettings();
|
||||||
|
$this->inventory->sendContents($this);
|
||||||
|
$this->inventory->sendArmorContents($this);
|
||||||
|
|
||||||
$this->blocked = false;
|
$this->blocked = false;
|
||||||
break;
|
break;
|
||||||
case ProtocolInfo::SET_HEALTH_PACKET: //Not used
|
case ProtocolInfo::SET_HEALTH_PACKET: //Not used
|
||||||
@ -1989,37 +1977,16 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ProtocolInfo::CONTAINER_CLOSE_PACKET:
|
case ProtocolInfo::CONTAINER_CLOSE_PACKET:
|
||||||
if($this->spawned === false){
|
if($this->spawned === false or $packet->windowid === 0){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$this->craftingItems = [];
|
$this->craftingItems = [];
|
||||||
$this->toCraft = [];
|
$this->toCraft = [];
|
||||||
if(isset($this->windows[$packet->windowid])){
|
if(isset($this->windowIndex[$packet->windowid])){
|
||||||
if(is_array($this->windows[$packet->windowid])){
|
$this->removeWindow($this->windowIndex[$packet->windowid]);
|
||||||
foreach($this->windows[$packet->windowid] as $ob){
|
}else{
|
||||||
$pk = new TileEventPacket;
|
unset($this->windowIndex[$packet->windowid]);
|
||||||
$pk->x = $ob->x;
|
|
||||||
$pk->y = $ob->y;
|
|
||||||
$pk->z = $ob->z;
|
|
||||||
$pk->case1 = 1;
|
|
||||||
$pk->case2 = 0;
|
|
||||||
Player::broadcastPacket($this->getLevel()->players, $pk);
|
|
||||||
}
|
}
|
||||||
}elseif($this->windows[$packet->windowid] instanceof Chest){
|
|
||||||
$pk = new TileEventPacket;
|
|
||||||
$pk->x = $this->windows[$packet->windowid]->x;
|
|
||||||
$pk->y = $this->windows[$packet->windowid]->y;
|
|
||||||
$pk->z = $this->windows[$packet->windowid]->z;
|
|
||||||
$pk->case1 = 1;
|
|
||||||
$pk->case2 = 0;
|
|
||||||
Player::broadcastPacket($this->getLevel()->players, $pk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($this->windows[$packet->windowid]);
|
|
||||||
|
|
||||||
$pk = new ContainerClosePacket;
|
|
||||||
$pk->windowid = $packet->windowid;
|
|
||||||
$this->dataPacket($pk);
|
|
||||||
break;
|
break;
|
||||||
case ProtocolInfo::CONTAINER_SET_SLOT_PACKET:
|
case ProtocolInfo::CONTAINER_SET_SLOT_PACKET:
|
||||||
if($this->spawned === false or $this->blocked === true){
|
if($this->spawned === false or $this->blocked === true){
|
||||||
@ -2035,9 +2002,9 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
$this->craftingItems = [];
|
$this->craftingItems = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if($packet->windowid === 0){
|
if($packet->windowid === 0){ //Crafting!
|
||||||
$craft = false;
|
$craft = false;
|
||||||
$slot = $this->getSlot($packet->slot);
|
$slot = $this->inventory->getItem($packet->slot);
|
||||||
if($slot->getCount() >= $packet->item->getCount() and (($slot->getID() === $packet->item->getID() and $slot->getDamage() === $packet->item->getDamage()) or ($packet->item->getID() === Item::AIR and $packet->item->getCount() === 0)) and !isset($this->craftingItems[$packet->slot])){ //Crafting recipe
|
if($slot->getCount() >= $packet->item->getCount() and (($slot->getID() === $packet->item->getID() and $slot->getDamage() === $packet->item->getDamage()) or ($packet->item->getID() === Item::AIR and $packet->item->getCount() === 0)) and !isset($this->craftingItems[$packet->slot])){ //Crafting recipe
|
||||||
$use = Item::get($slot->getID(), $slot->getDamage(), $slot->getCount() - $packet->item->getCount());
|
$use = Item::get($slot->getID(), $slot->getDamage(), $slot->getCount() - $packet->item->getCount());
|
||||||
$this->craftingItems[$packet->slot] = $use;
|
$this->craftingItems[$packet->slot] = $use;
|
||||||
@ -2066,7 +2033,7 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
|
|
||||||
if($craft === true and count($this->craftingItems) > 0 and count($this->toCraft) > 0 and ($recipe = $this->craftItems($this->toCraft, $this->craftingItems, $this->toCraft[-1])) !== true){
|
if($craft === true and count($this->craftingItems) > 0 and count($this->toCraft) > 0 and ($recipe = $this->craftItems($this->toCraft, $this->craftingItems, $this->toCraft[-1])) !== true){
|
||||||
if($recipe === false){
|
if($recipe === false){
|
||||||
$this->sendInventory();
|
$this->inventory->sendContents($this);
|
||||||
$this->toCraft = [];
|
$this->toCraft = [];
|
||||||
}else{
|
}else{
|
||||||
$this->toCraft = array(-1 => $this->toCraft[-1]);
|
$this->toCraft = array(-1 => $this->toCraft[-1]);
|
||||||
@ -2077,129 +2044,57 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
$this->toCraft = [];
|
$this->toCraft = [];
|
||||||
$this->craftingItems = [];
|
$this->craftingItems = [];
|
||||||
}
|
}
|
||||||
if(!isset($this->windows[$packet->windowid])){
|
if(!isset($this->windowIndex[$packet->windowid])){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(is_array($this->windows[$packet->windowid])){
|
$inv = $this->windowIndex[$packet->windowid];
|
||||||
/** @var \pocketmine\tile\Container[] $tiles */
|
if($packet->slot < 0 or $packet->slot >= $inv->getSize()){
|
||||||
$tiles = $this->windows[$packet->windowid];
|
|
||||||
if($packet->slot >= 0 and $packet->slot < Chest::SLOTS){
|
|
||||||
$tile = $tiles[0];
|
|
||||||
$slotn = $packet->slot;
|
|
||||||
$offset = 0;
|
|
||||||
}elseif($packet->slot >= Chest::SLOTS and $packet->slot <= (Chest::SLOTS << 1)){
|
|
||||||
$tile = $tiles[1];
|
|
||||||
$slotn = $packet->slot - Chest::SLOTS;
|
|
||||||
$offset = Chest::SLOTS;
|
|
||||||
}else{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$item = Item::get($packet->item->getID(), $packet->item->getDamage(), $packet->item->getCount());
|
|
||||||
|
|
||||||
$slot = $tile->getSlot($slotn);
|
/** @var Item $item */
|
||||||
//TODO: container access events?
|
$item = clone $packet->item;
|
||||||
/*if($this->server->api->dhandle("player.container.slot", array(
|
|
||||||
"tile" => $tile,
|
$slot = $inv->getItem($packet->slot);
|
||||||
"slot" => $packet->slot,
|
|
||||||
"offset" => $offset,
|
if($item->getID() !== Item::AIR and $slot->equals($item, true)){
|
||||||
"slotdata" => $slot,
|
|
||||||
"itemdata" => $item,
|
|
||||||
"player" => $this,
|
|
||||||
)) === false
|
|
||||||
){
|
|
||||||
$pk = new ContainerSetSlotPacket;
|
|
||||||
$pk->windowid = $packet->windowid;
|
|
||||||
$pk->slot = $packet->slot;
|
|
||||||
$pk->item = $slot;
|
|
||||||
$this->dataPacket($pk);
|
|
||||||
break;
|
|
||||||
}*/
|
|
||||||
if($item->getID() !== Item::AIR and $slot->getID() == $item->getID()){
|
|
||||||
if($slot->getCount() < $item->getCount()){
|
if($slot->getCount() < $item->getCount()){
|
||||||
$it = clone $item;
|
$it = clone $item;
|
||||||
$it->setCount($item->getCount() - $slot->getCount());
|
$it->setCount($item->getCount() - $slot->getCount());
|
||||||
if($this->removeItem($it) === false){
|
$remaining = $this->inventory->removeItem($it);
|
||||||
$this->sendInventory();
|
if(count($remaining) > 0){
|
||||||
break;
|
/** @var Item $it */
|
||||||
|
$it = array_pop($remaining);
|
||||||
|
$item->setCount($item->getCount() - $it->getCount());
|
||||||
}
|
}
|
||||||
}elseif($slot->getCount() > $item->getCount()){
|
}elseif($slot->getCount() > $item->getCount()){
|
||||||
$it = clone $item;
|
$it = clone $item;
|
||||||
$it->setCount($slot->getCount() - $item->getCount());
|
$it->setCount($slot->count - $item->count);
|
||||||
$this->addItem($it);
|
$remaining = $this->inventory->addItem($it);
|
||||||
|
if(count($remaining) > 0){
|
||||||
|
/** @var Item $it */
|
||||||
|
$it = array_pop($remaining);
|
||||||
|
$item->setCount($item->getCount() + $it->getCount());
|
||||||
}
|
}
|
||||||
}else{
|
|
||||||
if($this->removeItem($item) === false){
|
|
||||||
$this->sendInventory();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
$this->addItem($slot);
|
if($inv->getType()->getDefaultTitle() === "Furnace" and $packet->slot == 2){
|
||||||
}
|
|
||||||
$tile->setSlot($slotn, $item, true, $offset);
|
|
||||||
}else{
|
|
||||||
$tile = $this->windows[$packet->windowid];
|
|
||||||
if(
|
|
||||||
!($tile instanceof Chest or $tile instanceof Furnace)
|
|
||||||
or $packet->slot < 0
|
|
||||||
or (
|
|
||||||
$tile instanceof Chest
|
|
||||||
and $packet->slot >= Chest::SLOTS
|
|
||||||
) or (
|
|
||||||
$tile instanceof Furnace and $packet->slot >= Furnace::SLOTS
|
|
||||||
)
|
|
||||||
){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$item = Item::get($packet->item->getID(), $packet->item->getDamage(), $packet->item->getCount());
|
|
||||||
|
|
||||||
$slot = $tile->getSlot($packet->slot);
|
|
||||||
//TODO: container access events?
|
|
||||||
/*if($this->server->api->dhandle("player.container.slot", array(
|
|
||||||
"tile" => $tile,
|
|
||||||
"slot" => $packet->slot,
|
|
||||||
"slotdata" => $slot,
|
|
||||||
"itemdata" => $item,
|
|
||||||
"player" => $this,
|
|
||||||
)) === false
|
|
||||||
){
|
|
||||||
$pk = new ContainerSetSlotPacket;
|
|
||||||
$pk->windowid = $packet->windowid;
|
|
||||||
$pk->slot = $packet->slot;
|
|
||||||
$pk->item = $slot;
|
|
||||||
$this->dataPacket($pk);
|
|
||||||
break;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if($tile instanceof Furnace and $packet->slot == 2){
|
|
||||||
switch($slot->getID()){
|
switch($slot->getID()){
|
||||||
case Item::IRON_INGOT:
|
case Item::IRON_INGOT:
|
||||||
$this->awardAchievement("acquireIron");
|
$this->awardAchievement("acquireIron");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}else{ //TODO: check this. I don't know what is this for
|
||||||
|
$remaining = $this->inventory->removeItem($item);
|
||||||
|
if(count($remaining) > 0){
|
||||||
|
$this->inventory->removeItem();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$this->inventory->addItem($slot);
|
||||||
|
}
|
||||||
|
$inv->setItem($packet->slot, $item);
|
||||||
|
|
||||||
if($item->getID() !== Item::AIR and $slot->getID() == $item->getID()){
|
|
||||||
if($slot->getCount() < $item->getCount()){
|
|
||||||
$it = clone $item;
|
|
||||||
$it->setCount($item->getCount() - $slot->getCount());
|
|
||||||
if($this->removeItem($it) === false){
|
|
||||||
$this->sendInventory();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}elseif($slot->getCount() > $item->getCount()){
|
|
||||||
$it = clone $item;
|
|
||||||
$it->setCount($slot->count - $item->count);
|
|
||||||
$this->addItem($it);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
if($this->removeItem($item) === false){
|
|
||||||
$this->sendInventory();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$this->addItem($slot);
|
|
||||||
}
|
|
||||||
$tile->setSlot($packet->slot, $item);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case ProtocolInfo::SEND_INVENTORY_PACKET: //TODO, Mojang, enable this ´^_^`
|
case ProtocolInfo::SEND_INVENTORY_PACKET: //TODO, Mojang, enable this ´^_^`
|
||||||
if($this->spawned === false){
|
if($this->spawned === false){
|
||||||
@ -2323,9 +2218,8 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
$this->server->getPluginManager()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this);
|
$this->server->getPluginManager()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this);
|
||||||
$this->spawned = false;
|
$this->spawned = false;
|
||||||
console("[INFO] " . TextFormat::AQUA . $this->username . TextFormat::RESET . "[/" . $this->ip . ":" . $this->port . "] logged out due to " . $reason);
|
console("[INFO] " . TextFormat::AQUA . $this->username . TextFormat::RESET . "[/" . $this->ip . ":" . $this->port . "] logged out due to " . $reason);
|
||||||
$this->windows = [];
|
$this->windows = new \SplObjectStorage();
|
||||||
$this->armor = [];
|
$this->windowIndex = [];
|
||||||
$this->inventory = [];
|
|
||||||
$this->chunksLoaded = [];
|
$this->chunksLoaded = [];
|
||||||
$this->chunksOrder = [];
|
$this->chunksOrder = [];
|
||||||
$this->chunkCount = [];
|
$this->chunkCount = [];
|
||||||
@ -2465,18 +2359,18 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
foreach($recipe as $slot => $item){
|
foreach($recipe as $slot => $item){
|
||||||
$s = $this->getSlot($slot);
|
$s = $this->inventory->getItem($slot);
|
||||||
$s->setCount($s->getCount() - $item->getCount());
|
$s->setCount($s->getCount() - $item->getCount());
|
||||||
if($s->getCount() <= 0){
|
if($s->getCount() <= 0){
|
||||||
$this->setSlot($slot, Item::get(Item::AIR, 0, 0));
|
$this->inventory->setItem($slot, Item::get(Item::AIR, 0, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach($craft as $slot => $item){
|
foreach($craft as $slot => $item){
|
||||||
$s = $this->getSlot($slot);
|
$s = $this->inventory->getItem($slot);
|
||||||
if($s->getCount() <= 0 or $s->getID() === Item::AIR){
|
if($s->getCount() <= 0 or $s->getID() === Item::AIR){
|
||||||
$this->setSlot($slot, Item::get($item->getID(), $item->getDamage(), $item->getCount()));
|
$this->inventory->setItem($slot, Item::get($item->getID(), $item->getDamage(), $item->getCount()));
|
||||||
}else{
|
}else{
|
||||||
$this->setSlot($slot, Item::get($item->getID(), $item->getDamage(), $s->getCount() + $item->getCount()));
|
$this->inventory->setItem($slot, Item::get($item->getID(), $item->getDamage(), $s->getCount() + $item->getCount()));
|
||||||
}
|
}
|
||||||
|
|
||||||
switch($item->getID()){
|
switch($item->getID()){
|
||||||
@ -2497,7 +2391,7 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
break;
|
break;
|
||||||
case Item::CAKE:
|
case Item::CAKE:
|
||||||
$this->awardAchievement("bakeCake");
|
$this->awardAchievement("bakeCake");
|
||||||
$this->addItem(Item::get(Item::BUCKET, 0, 3));
|
$this->inventory->addItem(Item::get(Item::BUCKET, 0, 3));
|
||||||
break;
|
break;
|
||||||
case Item::STONE_PICKAXE:
|
case Item::STONE_PICKAXE:
|
||||||
case Item::GOLD_PICKAXE:
|
case Item::GOLD_PICKAXE:
|
||||||
@ -2519,59 +2413,46 @@ class Player extends Human implements CommandSender, IPlayer{
|
|||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setSlot($slot, Item $item){
|
|
||||||
parent::setSlot($slot, $item);
|
/**
|
||||||
$this->sendInventorySlot($slot);
|
* @param Inventory $inventory
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getWindowId(Inventory $inventory){
|
||||||
|
if($this->windows->contains($inventory)){
|
||||||
|
return $this->windows[$inventory];
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a single slot
|
* Returns the created/existing window id
|
||||||
* TODO: Check if Mojang has implemented this on Minecraft: PE 0.9.0
|
|
||||||
*
|
*
|
||||||
* @param int $s
|
* @param Inventory $inventory
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function sendInventorySlot($s){
|
public function addWindow(Inventory $inventory){
|
||||||
$this->sendInventory();
|
if($this->windows->contains($inventory)){
|
||||||
|
return $this->windows[$inventory];
|
||||||
|
}
|
||||||
|
$this->windowCnt = $cnt = max(2, ++$this->windowCnt % 99);
|
||||||
|
$this->windowIndex[$cnt] = $inventory;
|
||||||
|
$this->windows->attach($inventory, $cnt);
|
||||||
|
$this->inventory->onOpen($this);
|
||||||
|
|
||||||
return; //TODO: Check if Mojang adds this
|
return $cnt;
|
||||||
$s = (int) $s;
|
|
||||||
if(!isset($this->inventory[$s])){
|
|
||||||
$pk = new ContainerSetSlotPacket;
|
|
||||||
$pk->windowid = 0;
|
|
||||||
$pk->slot = (int) $s;
|
|
||||||
$pk->item = Item::get(Item::AIR, 0, 0);
|
|
||||||
$this->dataPacket($pk);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$slot = $this->inventory[$s];
|
public function removeWindow(Inventory $inventory){
|
||||||
$pk = new ContainerSetSlotPacket;
|
$inventory->onClose($this);
|
||||||
$pk->windowid = 0;
|
if($this->windows->contains($inventory)){
|
||||||
$pk->slot = (int) $s;
|
$inventory->onClose($this);
|
||||||
$pk->item = $slot;
|
$id = $this->windows[$inventory];
|
||||||
$this->dataPacket($pk);
|
unset($this->windowIndex[$id]);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends the full inventory
|
|
||||||
*/
|
|
||||||
public function sendInventory(){
|
|
||||||
if(($this->gamemode & 0x01) === 1){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$hotbar = [];
|
|
||||||
foreach($this->hotbar as $slot){
|
|
||||||
$hotbar[] = $slot <= -1 ? -1 : $slot + 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
$pk = new ContainerSetContentPacket;
|
|
||||||
$pk->windowid = 0;
|
|
||||||
$pk->slots = $this->inventory;
|
|
||||||
$pk->hotbar = $hotbar;
|
|
||||||
$this->dataPacket($pk);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setMetadata($metadataKey, MetadataValue $metadataValue){
|
public function setMetadata($metadataKey, MetadataValue $metadataValue){
|
||||||
|
@ -31,7 +31,6 @@ use pocketmine\block\Furnace;
|
|||||||
use pocketmine\command\CommandReader;
|
use pocketmine\command\CommandReader;
|
||||||
use pocketmine\command\CommandSender;
|
use pocketmine\command\CommandSender;
|
||||||
use pocketmine\command\ConsoleCommandSender;
|
use pocketmine\command\ConsoleCommandSender;
|
||||||
use pocketmine\command\PluginCommand;
|
|
||||||
use pocketmine\command\PluginIdentifiableCommand;
|
use pocketmine\command\PluginIdentifiableCommand;
|
||||||
use pocketmine\command\SimpleCommandMap;
|
use pocketmine\command\SimpleCommandMap;
|
||||||
use pocketmine\entity\Entity;
|
use pocketmine\entity\Entity;
|
||||||
@ -41,6 +40,7 @@ use pocketmine\event\server\PacketSendEvent;
|
|||||||
use pocketmine\event\server\ServerCommandEvent;
|
use pocketmine\event\server\ServerCommandEvent;
|
||||||
use pocketmine\inventory\InventoryType;
|
use pocketmine\inventory\InventoryType;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\level\format\pmf\LevelFormat;
|
||||||
use pocketmine\level\generator\Flat;
|
use pocketmine\level\generator\Flat;
|
||||||
use pocketmine\level\generator\Generator;
|
use pocketmine\level\generator\Generator;
|
||||||
use pocketmine\level\generator\Normal;
|
use pocketmine\level\generator\Normal;
|
||||||
@ -73,7 +73,6 @@ use pocketmine\permission\DefaultPermissions;
|
|||||||
use pocketmine\plugin\Plugin;
|
use pocketmine\plugin\Plugin;
|
||||||
use pocketmine\plugin\PluginLoadOrder;
|
use pocketmine\plugin\PluginLoadOrder;
|
||||||
use pocketmine\plugin\PluginManager;
|
use pocketmine\plugin\PluginManager;
|
||||||
use pocketmine\level\format\pmf\LevelFormat;
|
|
||||||
use pocketmine\recipes\Crafting;
|
use pocketmine\recipes\Crafting;
|
||||||
use pocketmine\scheduler\CallbackTask;
|
use pocketmine\scheduler\CallbackTask;
|
||||||
use pocketmine\scheduler\SendUsageTask;
|
use pocketmine\scheduler\SendUsageTask;
|
||||||
@ -795,6 +794,7 @@ class Server{
|
|||||||
return true;
|
return true;
|
||||||
}elseif(!$this->isLevelGenerated($name)){
|
}elseif(!$this->isLevelGenerated($name)){
|
||||||
console("[NOTICE] Level \"" . $name . "\" not found");
|
console("[NOTICE] Level \"" . $name . "\" not found");
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@ namespace pocketmine\block;
|
|||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\network\protocol\ChatPacket;
|
use pocketmine\network\protocol\ChatPacket;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
use pocketmine\Server;
|
|
||||||
|
|
||||||
class Bed extends Transparent{
|
class Bed extends Transparent{
|
||||||
public function __construct($type = 0){
|
public function __construct($type = 0){
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\level\Position;
|
use pocketmine\level\Position;
|
||||||
use pocketmine\metadata\Metadatable;
|
use pocketmine\metadata\Metadatable;
|
||||||
use pocketmine\metadata\MetadataValue;
|
use pocketmine\metadata\MetadataValue;
|
||||||
|
@ -118,8 +118,8 @@ class BurningFurnace extends Solid{
|
|||||||
}
|
}
|
||||||
$t = $this->getLevel()->getTile($this);
|
$t = $this->getLevel()->getTile($this);
|
||||||
if($t instanceof Furnace){
|
if($t instanceof Furnace){
|
||||||
for($s = 0; $s < Furnace::SLOTS; ++$s){
|
for($s = 0; $s < $t->getInventory()->getSize(); ++$s){
|
||||||
$slot = $t->getSlot($s);
|
$slot = $t->getInventory()->getItem($s);
|
||||||
if($slot->getID() > Item::AIR and $slot->getCount() > 0){
|
if($slot->getID() > Item::AIR and $slot->getCount() > 0){
|
||||||
$drops[] = array($slot->getID(), $slot->getDamage(), $slot->getCount());
|
$drops[] = array($slot->getID(), $slot->getDamage(), $slot->getCount());
|
||||||
}
|
}
|
||||||
|
@ -59,8 +59,9 @@ class Chest extends Transparent{
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$c = $this->getSide($side);
|
$c = $this->getSide($side);
|
||||||
if(($c instanceof TileChest) and $c->getDamage() === $this->meta){
|
if($c instanceof Chest and $c->getDamage() === $this->meta){
|
||||||
if((($tile = $this->getLevel()->getTile($c)) instanceof TileChest) and !$tile->isPaired()){
|
$tile = $this->getLevel()->getTile($c);
|
||||||
|
if($tile instanceof TileChest and !$tile->isPaired()){
|
||||||
$chest = $tile;
|
$chest = $tile;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -104,7 +105,7 @@ class Chest extends Transparent{
|
|||||||
}
|
}
|
||||||
|
|
||||||
$t = $this->getLevel()->getTile($this);
|
$t = $this->getLevel()->getTile($this);
|
||||||
$chest = false;
|
$chest = null;
|
||||||
if($t instanceof TileChest){
|
if($t instanceof TileChest){
|
||||||
$chest = $t;
|
$chest = $t;
|
||||||
}else{
|
}else{
|
||||||
@ -123,8 +124,7 @@ class Chest extends Transparent{
|
|||||||
if(($player->gamemode & 0x01) === 0x01){
|
if(($player->gamemode & 0x01) === 0x01){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
$player->addWindow($chest->getInventory());
|
||||||
$chest->openInventory($player);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -135,9 +135,9 @@ class Chest extends Transparent{
|
|||||||
array($this->id, 0, 1),
|
array($this->id, 0, 1),
|
||||||
);
|
);
|
||||||
$t = $this->getLevel()->getTile($this);
|
$t = $this->getLevel()->getTile($this);
|
||||||
if($t instanceof Chest){
|
if($t instanceof TileChest){
|
||||||
for($s = 0; $s < Chest::SLOTS; ++$s){
|
for($s = 0; $s < $t->getInventory()->getSize(); ++$s){
|
||||||
$slot = $t->getSlot($s);
|
$slot = $t->getInventory()->getItem($s);
|
||||||
if($slot->getID() > Item::AIR and $slot->getCount() > 0){
|
if($slot->getID() > Item::AIR and $slot->getCount() > 0){
|
||||||
$drops[] = array($slot->getID(), $slot->getDamage(), $slot->getCount());
|
$drops[] = array($slot->getID(), $slot->getDamage(), $slot->getCount());
|
||||||
}
|
}
|
||||||
|
@ -50,10 +50,10 @@ use pocketmine\command\defaults\StatusCommand;
|
|||||||
use pocketmine\command\defaults\StopCommand;
|
use pocketmine\command\defaults\StopCommand;
|
||||||
use pocketmine\command\defaults\TeleportCommand;
|
use pocketmine\command\defaults\TeleportCommand;
|
||||||
use pocketmine\command\defaults\TellCommand;
|
use pocketmine\command\defaults\TellCommand;
|
||||||
|
use pocketmine\command\defaults\TimeCommand;
|
||||||
use pocketmine\command\defaults\VanillaCommand;
|
use pocketmine\command\defaults\VanillaCommand;
|
||||||
use pocketmine\command\defaults\VersionCommand;
|
use pocketmine\command\defaults\VersionCommand;
|
||||||
use pocketmine\command\defaults\WhitelistCommand;
|
use pocketmine\command\defaults\WhitelistCommand;
|
||||||
use pocketmine\command\defaults\TimeCommand;
|
|
||||||
use pocketmine\Server;
|
use pocketmine\Server;
|
||||||
|
|
||||||
class SimpleCommandMap implements CommandMap{
|
class SimpleCommandMap implements CommandMap{
|
||||||
|
@ -21,10 +21,8 @@
|
|||||||
|
|
||||||
namespace pocketmine\command\defaults;
|
namespace pocketmine\command\defaults;
|
||||||
|
|
||||||
use pocketmine\command\Command;
|
|
||||||
use pocketmine\command\CommandSender;
|
use pocketmine\command\CommandSender;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
use pocketmine\Server;
|
|
||||||
use pocketmine\utils\TextFormat;
|
use pocketmine\utils\TextFormat;
|
||||||
|
|
||||||
class KillCommand extends VanillaCommand{
|
class KillCommand extends VanillaCommand{
|
||||||
|
@ -23,7 +23,6 @@ namespace pocketmine\command\defaults;
|
|||||||
|
|
||||||
use pocketmine\command\Command;
|
use pocketmine\command\Command;
|
||||||
use pocketmine\command\CommandSender;
|
use pocketmine\command\CommandSender;
|
||||||
use pocketmine\event\HandlerList;
|
|
||||||
use pocketmine\Server;
|
use pocketmine\Server;
|
||||||
use pocketmine\utils\TextFormat;
|
use pocketmine\utils\TextFormat;
|
||||||
|
|
||||||
|
@ -23,8 +23,6 @@ namespace pocketmine\command\defaults;
|
|||||||
|
|
||||||
use pocketmine\command\Command;
|
use pocketmine\command\Command;
|
||||||
use pocketmine\command\CommandSender;
|
use pocketmine\command\CommandSender;
|
||||||
use pocketmine\command\ConsoleCommandSender;
|
|
||||||
use pocketmine\level\Position;
|
|
||||||
use pocketmine\math\Vector3;
|
use pocketmine\math\Vector3;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
use pocketmine\Server;
|
use pocketmine\Server;
|
||||||
@ -52,6 +50,7 @@ class SetWorldSpawnCommand extends VanillaCommand{
|
|||||||
$pos = $sender->round();
|
$pos = $sender->round();
|
||||||
}else{
|
}else{
|
||||||
$sender->sendMessage(TextFormat::RED . "You can only perform this command as a player");
|
$sender->sendMessage(TextFormat::RED . "You can only perform this command as a player");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}elseif(count($args) === 3){
|
}elseif(count($args) === 3){
|
||||||
@ -59,12 +58,14 @@ class SetWorldSpawnCommand extends VanillaCommand{
|
|||||||
$pos = new Vector3($this->getInteger($sender, $args[0]), $this->getInteger($sender, $args[1]), $this->getInteger($sender, $args[2]));
|
$pos = new Vector3($this->getInteger($sender, $args[0]), $this->getInteger($sender, $args[1]), $this->getInteger($sender, $args[2]));
|
||||||
}else{
|
}else{
|
||||||
$sender->sendMessage(TextFormat::RED . "Usage: " . $this->usageMessage);
|
$sender->sendMessage(TextFormat::RED . "Usage: " . $this->usageMessage);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$level->setSpawn($pos);
|
$level->setSpawn($pos);
|
||||||
|
|
||||||
Command::broadcastCommandMessage($sender, "Set world " . $level->getName() . "'s spawnpoint to " . $pos->x . ", " . $pos->y . ", " . $pos->z);
|
Command::broadcastCommandMessage($sender, "Set world " . $level->getName() . "'s spawnpoint to " . $pos->x . ", " . $pos->y . ", " . $pos->z);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,12 +51,14 @@ class SpawnpointCommand extends VanillaCommand{
|
|||||||
$target = $sender;
|
$target = $sender;
|
||||||
}else{
|
}else{
|
||||||
$sender->sendMessage(TextFormat::RED . "Please provide a player!");
|
$sender->sendMessage(TextFormat::RED . "Please provide a player!");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
$target = Server::getInstance()->getPlayer($args[0]);
|
$target = Server::getInstance()->getPlayer($args[0]);
|
||||||
if($target === null){
|
if($target === null){
|
||||||
$sender->sendMessage(TextFormat::RED . "Can't find player " . $args[0]);
|
$sender->sendMessage(TextFormat::RED . "Can't find player " . $args[0]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,6 +72,7 @@ class SpawnpointCommand extends VanillaCommand{
|
|||||||
$z = (int) $this->getRelativeDouble($sender->z, $sender, $args[3]);
|
$z = (int) $this->getRelativeDouble($sender->z, $sender, $args[3]);
|
||||||
$target->setSpawn(new Position($x, $y, $z, $level));
|
$target->setSpawn(new Position($x, $y, $z, $level));
|
||||||
Command::broadcastCommandMessage($sender, "Set " . $target->getName() . "'s spawnpoint to " . $x . ", " . $y . ", " . $z);
|
Command::broadcastCommandMessage($sender, "Set " . $target->getName() . "'s spawnpoint to " . $x . ", " . $y . ", " . $z);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}elseif(count($args) <= 1){
|
}elseif(count($args) <= 1){
|
||||||
@ -77,14 +80,17 @@ class SpawnpointCommand extends VanillaCommand{
|
|||||||
$pos = new Position((int) $sender->x, (int) $sender->y, (int) $sender->z, $sender->getLevel());
|
$pos = new Position((int) $sender->x, (int) $sender->y, (int) $sender->z, $sender->getLevel());
|
||||||
$target->setSpawn($pos);
|
$target->setSpawn($pos);
|
||||||
Command::broadcastCommandMessage($sender, "Set " . $target->getName() . "'s spawnpoint to " . $pos->x . ", " . $pos->y . ", " . $pos->z);
|
Command::broadcastCommandMessage($sender, "Set " . $target->getName() . "'s spawnpoint to " . $pos->x . ", " . $pos->y . ", " . $pos->z);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}else{
|
}else{
|
||||||
$sender->sendMessage(TextFormat::RED . "Please provide a player!");
|
$sender->sendMessage(TextFormat::RED . "Please provide a player!");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$sender->sendMessage(TextFormat::RED . "Usage: " . $this->usageMessage);
|
$sender->sendMessage(TextFormat::RED . "Usage: " . $this->usageMessage);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
namespace pocketmine\command\defaults;
|
namespace pocketmine\command\defaults;
|
||||||
|
|
||||||
use pocketmine\command\CommandSender;
|
use pocketmine\command\CommandSender;
|
||||||
use pocketmine\Player;
|
|
||||||
use pocketmine\Server;
|
use pocketmine\Server;
|
||||||
use pocketmine\utils\TextFormat;
|
use pocketmine\utils\TextFormat;
|
||||||
|
|
||||||
@ -48,6 +47,7 @@ class StatusCommand extends VanillaCommand{
|
|||||||
$sender->sendMessage(TextFormat::GOLD . "Upload: " . TextFormat::WHITE . round($server->getNetwork()->getUploadSpeed() / 1024, 2) . " kB/s");
|
$sender->sendMessage(TextFormat::GOLD . "Upload: " . TextFormat::WHITE . round($server->getNetwork()->getUploadSpeed() / 1024, 2) . " kB/s");
|
||||||
$sender->sendMessage(TextFormat::GOLD . "Download: " . TextFormat::WHITE . round($server->getNetwork()->getDownloadSpeed() / 1024, 2) . " kB/s");
|
$sender->sendMessage(TextFormat::GOLD . "Download: " . TextFormat::WHITE . round($server->getNetwork()->getDownloadSpeed() / 1024, 2) . " kB/s");
|
||||||
$sender->sendMessage(TextFormat::GOLD . "Memory: " . TextFormat::WHITE . round((memory_get_usage() / 1024) / 1024, 2) . TextFormat::YELLOW . "/" . TextFormat::WHITE . round((memory_get_usage(true) / 1024) / 1024, 2) . " MB");
|
$sender->sendMessage(TextFormat::GOLD . "Memory: " . TextFormat::WHITE . round((memory_get_usage() / 1024) / 1024, 2) . TextFormat::YELLOW . "/" . TextFormat::WHITE . round((memory_get_usage(true) / 1024) / 1024, 2) . " MB");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -47,6 +47,7 @@ class TeleportCommand extends VanillaCommand{
|
|||||||
|
|
||||||
if(count($args) < 1 or count($args) > 4){
|
if(count($args) < 1 or count($args) > 4){
|
||||||
$sender->sendMessage(TextFormat::RED . "Usage: " . $this->usageMessage);
|
$sender->sendMessage(TextFormat::RED . "Usage: " . $this->usageMessage);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,12 +59,14 @@ class TeleportCommand extends VanillaCommand{
|
|||||||
$target = $sender;
|
$target = $sender;
|
||||||
}else{
|
}else{
|
||||||
$sender->sendMessage(TextFormat::RED . "Please provide a player!");
|
$sender->sendMessage(TextFormat::RED . "Please provide a player!");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
$target = Server::getInstance()->getPlayer($args[0]);
|
$target = Server::getInstance()->getPlayer($args[0]);
|
||||||
if($target === null){
|
if($target === null){
|
||||||
$sender->sendMessage(TextFormat::RED . "Can't find player " . $args[0]);
|
$sender->sendMessage(TextFormat::RED . "Can't find player " . $args[0]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if(count($args) === 2){
|
if(count($args) === 2){
|
||||||
@ -71,6 +74,7 @@ class TeleportCommand extends VanillaCommand{
|
|||||||
$target = Server::getInstance()->getPlayer($args[1]);
|
$target = Server::getInstance()->getPlayer($args[1]);
|
||||||
if($target === null){
|
if($target === null){
|
||||||
$sender->sendMessage(TextFormat::RED . "Can't find player " . $args[1]);
|
$sender->sendMessage(TextFormat::RED . "Can't find player " . $args[1]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,6 +84,7 @@ class TeleportCommand extends VanillaCommand{
|
|||||||
$pos = new Position($target->x, $target->y, $target->z, $target->getLevel());
|
$pos = new Position($target->x, $target->y, $target->z, $target->getLevel());
|
||||||
$origin->teleport($pos);
|
$origin->teleport($pos);
|
||||||
Command::broadcastCommandMessage($sender, "Teleported " . $origin->getName() . " to " . $target->getName());
|
Command::broadcastCommandMessage($sender, "Teleported " . $origin->getName() . " to " . $target->getName());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}elseif($target->getLevel() !== null){
|
}elseif($target->getLevel() !== null){
|
||||||
$pos = count($args) === 4 ? 1 : 0;
|
$pos = count($args) === 4 ? 1 : 0;
|
||||||
@ -88,10 +93,12 @@ class TeleportCommand extends VanillaCommand{
|
|||||||
$z = $this->getRelativeDouble($target->z, $sender, $args[$pos]);
|
$z = $this->getRelativeDouble($target->z, $sender, $args[$pos]);
|
||||||
$target->teleport(new Vector3($x, $y, $z));
|
$target->teleport(new Vector3($x, $y, $z));
|
||||||
Command::broadcastCommandMessage($sender, "Teleported " . $target->getName() . " to " . round($x, 2) . ", " . round($y, 2) . ", " . round($z, 2));
|
Command::broadcastCommandMessage($sender, "Teleported " . $target->getName() . " to " . round($x, 2) . ", " . round($y, 2) . ", " . round($z, 2));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sender->sendMessage(TextFormat::RED . "Usage: " . $this->usageMessage);
|
$sender->sendMessage(TextFormat::RED . "Usage: " . $this->usageMessage);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ use pocketmine\command\Command;
|
|||||||
use pocketmine\command\CommandSender;
|
use pocketmine\command\CommandSender;
|
||||||
use pocketmine\Server;
|
use pocketmine\Server;
|
||||||
use pocketmine\utils\TextFormat;
|
use pocketmine\utils\TextFormat;
|
||||||
use pocketmine\network\protocol\SetTimePacket;
|
|
||||||
|
|
||||||
class TimeCommand extends VanillaCommand{
|
class TimeCommand extends VanillaCommand{
|
||||||
public function __construct($name){
|
public function __construct($name){
|
||||||
@ -21,6 +20,7 @@ class TimeCommand extends VanillaCommand{
|
|||||||
public function execute(CommandSender $sender, $label, array $args){
|
public function execute(CommandSender $sender, $label, array $args){
|
||||||
if(count($args) < 2){
|
if(count($args) < 2){
|
||||||
$sender->sendMessage(TextFormat::RED . "Incorrect usage. Correct usage:\n" . $this->getUsage());
|
$sender->sendMessage(TextFormat::RED . "Incorrect usage. Correct usage:\n" . $this->getUsage());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,6 +28,7 @@ class TimeCommand extends VanillaCommand{
|
|||||||
case "set":
|
case "set":
|
||||||
if(!$sender->hasPermission("pocketmine.command.time.add")){
|
if(!$sender->hasPermission("pocketmine.command.time.add")){
|
||||||
$sender->sendMessage(TextFormat::RED . "You don't have permission to set the time");
|
$sender->sendMessage(TextFormat::RED . "You don't have permission to set the time");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,6 +49,7 @@ class TimeCommand extends VanillaCommand{
|
|||||||
case "add":
|
case "add":
|
||||||
if(!$sender->hasPermission("pocketmine.command.time.add")){
|
if(!$sender->hasPermission("pocketmine.command.time.add")){
|
||||||
$sender->sendMessage(TextFormat::RED . "You don't have permission to set the time");
|
$sender->sendMessage(TextFormat::RED . "You don't have permission to set the time");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ use pocketmine\event\entity\EntityLevelChangeEvent;
|
|||||||
use pocketmine\event\entity\EntityMotionEvent;
|
use pocketmine\event\entity\EntityMotionEvent;
|
||||||
use pocketmine\event\entity\EntityMoveEvent;
|
use pocketmine\event\entity\EntityMoveEvent;
|
||||||
use pocketmine\event\entity\EntitySpawnEvent;
|
use pocketmine\event\entity\EntitySpawnEvent;
|
||||||
|
use pocketmine\level\format\pmf\LevelFormat;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
use pocketmine\level\Position;
|
use pocketmine\level\Position;
|
||||||
use pocketmine\math\AxisAlignedBB;
|
use pocketmine\math\AxisAlignedBB;
|
||||||
@ -36,14 +37,13 @@ use pocketmine\math\Vector3 as Vector3;
|
|||||||
use pocketmine\metadata\Metadatable;
|
use pocketmine\metadata\Metadatable;
|
||||||
use pocketmine\metadata\MetadataValue;
|
use pocketmine\metadata\MetadataValue;
|
||||||
use pocketmine\nbt\tag\Compound;
|
use pocketmine\nbt\tag\Compound;
|
||||||
|
use pocketmine\Network;
|
||||||
use pocketmine\network\protocol\MoveEntityPacket_PosRot;
|
use pocketmine\network\protocol\MoveEntityPacket_PosRot;
|
||||||
use pocketmine\network\protocol\MovePlayerPacket;
|
use pocketmine\network\protocol\MovePlayerPacket;
|
||||||
use pocketmine\network\protocol\RemoveEntityPacket;
|
use pocketmine\network\protocol\RemoveEntityPacket;
|
||||||
use pocketmine\network\protocol\SetEntityMotionPacket;
|
use pocketmine\network\protocol\SetEntityMotionPacket;
|
||||||
use pocketmine\network\protocol\SetTimePacket;
|
use pocketmine\network\protocol\SetTimePacket;
|
||||||
use pocketmine\Network;
|
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
use pocketmine\level\format\pmf\LevelFormat;
|
|
||||||
use pocketmine\plugin\Plugin;
|
use pocketmine\plugin\Plugin;
|
||||||
use pocketmine\Server;
|
use pocketmine\Server;
|
||||||
|
|
||||||
@ -176,6 +176,10 @@ abstract class Entity extends Position implements Metadatable{
|
|||||||
|
|
||||||
protected abstract function initEntity();
|
protected abstract function initEntity();
|
||||||
|
|
||||||
|
public function getViewers(){
|
||||||
|
return $this->hasSpawned;
|
||||||
|
}
|
||||||
|
|
||||||
public function spawnTo(Player $player){
|
public function spawnTo(Player $player){
|
||||||
if(!isset($this->hasSpawned[$player->getID()]) and $player->chunksLoaded[$this->chunkIndex] !== 0xff){
|
if(!isset($this->hasSpawned[$player->getID()]) and $player->chunksLoaded[$this->chunkIndex] !== 0xff){
|
||||||
$this->hasSpawned[$player->getID()] = $player;
|
$this->hasSpawned[$player->getID()] = $player;
|
||||||
|
@ -21,54 +21,46 @@
|
|||||||
|
|
||||||
namespace pocketmine\entity;
|
namespace pocketmine\entity;
|
||||||
|
|
||||||
use pocketmine\event\entity\EntityArmorChangeEvent;
|
use pocketmine\inventory\InventoryHolder;
|
||||||
use pocketmine\event\entity\EntityInventoryChangeEvent;
|
use pocketmine\inventory\PlayerInventory;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\nbt\NBT;
|
use pocketmine\nbt\NBT;
|
||||||
use pocketmine\nbt\tag\Byte;
|
use pocketmine\nbt\tag\Byte;
|
||||||
use pocketmine\nbt\tag\Compound;
|
use pocketmine\nbt\tag\Compound;
|
||||||
use pocketmine\nbt\tag\Enum;
|
use pocketmine\nbt\tag\Enum;
|
||||||
use pocketmine\nbt\tag\Short;
|
use pocketmine\nbt\tag\Short;
|
||||||
|
use pocketmine\Network;
|
||||||
use pocketmine\network\protocol\AddPlayerPacket;
|
use pocketmine\network\protocol\AddPlayerPacket;
|
||||||
use pocketmine\network\protocol\ContainerSetContentPacket;
|
|
||||||
use pocketmine\network\protocol\PlayerArmorEquipmentPacket;
|
|
||||||
use pocketmine\network\protocol\PlayerEquipmentPacket;
|
|
||||||
use pocketmine\network\protocol\RemovePlayerPacket;
|
use pocketmine\network\protocol\RemovePlayerPacket;
|
||||||
use pocketmine\network\protocol\SetEntityMotionPacket;
|
use pocketmine\network\protocol\SetEntityMotionPacket;
|
||||||
use pocketmine\Network;
|
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
use pocketmine\Server;
|
|
||||||
|
|
||||||
class Human extends Creature implements ProjectileSource, InventorySource{
|
class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||||
|
|
||||||
protected $nameTag = "TESTIFICATE";
|
protected $nameTag = "TESTIFICATE";
|
||||||
protected $inventory = [];
|
/** @var PlayerInventory */
|
||||||
public $slot;
|
protected $inventory;
|
||||||
protected $hotbar = [];
|
|
||||||
protected $armor = [];
|
public function getInventory(){
|
||||||
|
return $this->inventory;
|
||||||
|
}
|
||||||
|
|
||||||
protected function initEntity(){
|
protected function initEntity(){
|
||||||
|
$this->inventory = new PlayerInventory($this);
|
||||||
|
|
||||||
if(isset($this->namedtag->NameTag)){
|
if(isset($this->namedtag->NameTag)){
|
||||||
$this->nameTag = $this->namedtag["NameTag"];
|
$this->nameTag = $this->namedtag["NameTag"];
|
||||||
}
|
}
|
||||||
$this->hotbar = array(-1, -1, -1, -1, -1, -1, -1, -1, -1);
|
|
||||||
$this->armor = array(
|
|
||||||
0 => Item::get(Item::AIR, 0, 0),
|
|
||||||
1 => Item::get(Item::AIR, 0, 0),
|
|
||||||
2 => Item::get(Item::AIR, 0, 0),
|
|
||||||
3 => Item::get(Item::AIR, 0, 0)
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach($this->namedtag->Inventory as $item){
|
foreach($this->namedtag->Inventory as $item){
|
||||||
if($item["Slot"] >= 0 and $item["Slot"] < 9){ //Hotbar
|
if($item["Slot"] >= 0 and $item["Slot"] < 9){ //Hotbar
|
||||||
$this->hotbar[$item["Slot"]] = isset($item["TrueSlot"]) ? $item["TrueSlot"] : -1;
|
$this->inventory->setHotbarSlotIndex($item["Slot"], isset($item["TrueSlot"]) ? $item["TrueSlot"] : -1);
|
||||||
}elseif($item["Slot"] >= 100 and $item["Slot"] < 104){ //Armor
|
}elseif($item["Slot"] >= 100 and $item["Slot"] < 104){ //Armor
|
||||||
$this->armor[$item["Slot"] - 100] = Item::get($item["id"], $item["Damage"], $item["Count"]);
|
$this->inventory->setItem($this->inventory->getSize() + $item["Slot"] - 100, Item::get($item["id"], $item["Damage"], $item["Count"]));
|
||||||
}else{
|
}else{
|
||||||
$this->inventory[$item["Slot"] - 9] = Item::get($item["id"], $item["Damage"], $item["Count"]);
|
$this->inventory->setItem($item["Slot"] - 9, Item::get($item["id"], $item["Damage"], $item["Count"]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->slot = $this->hotbar[0];
|
|
||||||
|
|
||||||
$this->height = 1.8; //Or 1.62?
|
$this->height = 1.8; //Or 1.62?
|
||||||
$this->width = 0.6;
|
$this->width = 0.6;
|
||||||
@ -79,14 +71,15 @@ class Human extends Creature implements ProjectileSource, InventorySource{
|
|||||||
$this->namedtag->Inventory = new Enum("Inventory", []);
|
$this->namedtag->Inventory = new Enum("Inventory", []);
|
||||||
$this->namedtag->Inventory->setTagType(NBT::TAG_Compound);
|
$this->namedtag->Inventory->setTagType(NBT::TAG_Compound);
|
||||||
for($slot = 0; $slot < 9; ++$slot){
|
for($slot = 0; $slot < 9; ++$slot){
|
||||||
if(isset($this->hotbar[$slot]) and $this->hotbar[$slot] !== -1){
|
$hotbarSlot = $this->inventory->getHotbarSlotIndex($slot);
|
||||||
$item = $this->getSlot($this->hotbar[$slot]);
|
if($hotbarSlot !== -1){
|
||||||
|
$item = $this->inventory->getItem($hotbarSlot);
|
||||||
if($item->getID() !== 0 and $item->getCount() > 0){
|
if($item->getID() !== 0 and $item->getCount() > 0){
|
||||||
$this->namedtag->Inventory[$slot] = new Compound(false, array(
|
$this->namedtag->Inventory[$slot] = new Compound(false, array(
|
||||||
new Byte("Count", $item->getCount()),
|
new Byte("Count", $item->getCount()),
|
||||||
new Short("Damage", $item->getDamage()),
|
new Short("Damage", $item->getDamage()),
|
||||||
new Byte("Slot", $slot),
|
new Byte("Slot", $slot),
|
||||||
new Byte("TrueSlot", $this->hotbar[$slot]),
|
new Byte("TrueSlot", $hotbarSlot),
|
||||||
new Short("id", $item->getID()),
|
new Short("id", $item->getID()),
|
||||||
));
|
));
|
||||||
continue;
|
continue;
|
||||||
@ -105,7 +98,7 @@ class Human extends Creature implements ProjectileSource, InventorySource{
|
|||||||
$slotCount = Player::SURVIVAL_SLOTS + 9;
|
$slotCount = Player::SURVIVAL_SLOTS + 9;
|
||||||
//$slotCount = (($this instanceof Player and ($this->gamemode & 0x01) === 1) ? Player::CREATIVE_SLOTS : Player::SURVIVAL_SLOTS) + 9;
|
//$slotCount = (($this instanceof Player and ($this->gamemode & 0x01) === 1) ? Player::CREATIVE_SLOTS : Player::SURVIVAL_SLOTS) + 9;
|
||||||
for($slot = 9; $slot < $slotCount; ++$slot){
|
for($slot = 9; $slot < $slotCount; ++$slot){
|
||||||
$item = $this->getSlot($slot - 9);
|
$item = $this->inventory->getItem($slot - 9);
|
||||||
$this->namedtag->Inventory[$slot] = new Compound(false, array(
|
$this->namedtag->Inventory[$slot] = new Compound(false, array(
|
||||||
new Byte("Count", $item->getCount()),
|
new Byte("Count", $item->getCount()),
|
||||||
new Short("Damage", $item->getDamage()),
|
new Short("Damage", $item->getDamage()),
|
||||||
@ -116,8 +109,8 @@ class Human extends Creature implements ProjectileSource, InventorySource{
|
|||||||
|
|
||||||
//Armor
|
//Armor
|
||||||
for($slot = 100; $slot < 104; ++$slot){
|
for($slot = 100; $slot < 104; ++$slot){
|
||||||
$item = $this->armor[$slot - 100];
|
$item = $this->inventory->getItem($this->inventory->getSize() + $slot - 100);
|
||||||
if($item instanceof Item){
|
if($item instanceof Item and $item->getID() !== Item::AIR){
|
||||||
$this->namedtag->Inventory[$slot] = new Compound(false, array(
|
$this->namedtag->Inventory[$slot] = new Compound(false, array(
|
||||||
new Byte("Count", $item->getCount()),
|
new Byte("Count", $item->getCount()),
|
||||||
new Short("Damage", $item->getDamage()),
|
new Short("Damage", $item->getDamage()),
|
||||||
@ -135,7 +128,7 @@ class Human extends Creature implements ProjectileSource, InventorySource{
|
|||||||
$pk = new AddPlayerPacket;
|
$pk = new AddPlayerPacket;
|
||||||
$pk->clientID = 0;
|
$pk->clientID = 0;
|
||||||
$pk->username = $this->nameTag;
|
$pk->username = $this->nameTag;
|
||||||
$pk->eid = $this->id;
|
$pk->eid = $this->getID();
|
||||||
$pk->x = $this->x;
|
$pk->x = $this->x;
|
||||||
$pk->y = $this->y;
|
$pk->y = $this->y;
|
||||||
$pk->z = $this->z;
|
$pk->z = $this->z;
|
||||||
@ -147,15 +140,15 @@ class Human extends Creature implements ProjectileSource, InventorySource{
|
|||||||
$player->dataPacket($pk);
|
$player->dataPacket($pk);
|
||||||
|
|
||||||
$pk = new SetEntityMotionPacket;
|
$pk = new SetEntityMotionPacket;
|
||||||
$pk->eid = $this->id;
|
$pk->eid = $this->getID();
|
||||||
$pk->speedX = $this->motionX;
|
$pk->speedX = $this->motionX;
|
||||||
$pk->speedY = $this->motionY;
|
$pk->speedY = $this->motionY;
|
||||||
$pk->speedZ = $this->motionZ;
|
$pk->speedZ = $this->motionZ;
|
||||||
$player->dataPacket($pk);
|
$player->dataPacket($pk);
|
||||||
|
|
||||||
$this->sendCurrentEquipmentSlot($player);
|
$this->inventory->sendHeldItem($player);
|
||||||
|
|
||||||
$this->sendArmor($player);
|
$this->inventory->sendArmorContents($player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,104 +162,6 @@ class Human extends Creature implements ProjectileSource, InventorySource{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setEquipmentSlot($equipmentSlot, $inventorySlot){
|
|
||||||
$this->hotbar[$equipmentSlot] = $inventorySlot;
|
|
||||||
if($equipmentSlot === $this->slot){
|
|
||||||
foreach($this->hasSpawned as $p){
|
|
||||||
$this->sendCurrentEquipmentSlot($p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getEquipmentSlot($equipmentSlot){
|
|
||||||
if(isset($this->hotbar[$equipmentSlot])){
|
|
||||||
return $this->hotbar[$equipmentSlot];
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setCurrentEquipmentSlot($slot){
|
|
||||||
if(isset($this->hotbar[$slot])){
|
|
||||||
$this->slot = (int) $slot;
|
|
||||||
foreach($this->hasSpawned as $p){
|
|
||||||
$this->sendCurrentEquipmentSlot($p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCurrentEquipmentSlot(){
|
|
||||||
return $this->slot;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCurrentEquipment(){
|
|
||||||
if($this->slot > -1) {
|
|
||||||
return $this->hotbar[$this->slot];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function sendCurrentEquipmentSlot(Player $player){
|
|
||||||
$pk = new PlayerEquipmentPacket;
|
|
||||||
$pk->eid = $this->id;
|
|
||||||
$pk->item = $this->getSlot($this->slot)->getID();
|
|
||||||
$pk->meta = $this->getSlot($this->slot)->getDamage();
|
|
||||||
$pk->slot = 0;
|
|
||||||
$player->dataPacket($pk);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setArmorSlot($slot, Item $item){
|
|
||||||
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityArmorChangeEvent($this, $this->getArmorSlot($slot), $item, $slot));
|
|
||||||
if($ev->isCancelled()){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$this->armor[(int) $slot] = $ev->getNewItem();
|
|
||||||
foreach($this->hasSpawned as $p){
|
|
||||||
$this->sendArmor($p);
|
|
||||||
}
|
|
||||||
if($this instanceof Player){
|
|
||||||
$this->sendArmor();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $slot
|
|
||||||
*
|
|
||||||
* @return Item
|
|
||||||
*/
|
|
||||||
public function getArmorSlot($slot){
|
|
||||||
$slot = (int) $slot;
|
|
||||||
if(!isset($this->armor[$slot])){
|
|
||||||
$this->armor[$slot] = Item::get(Item::AIR, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->armor[$slot];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function sendArmor($player = null){
|
|
||||||
$slots = [];
|
|
||||||
for($i = 0; $i < 4; ++$i){
|
|
||||||
if(isset($this->armor[$i]) and ($this->armor[$i] instanceof Item) and $this->armor[$i]->getID() > Item::AIR){
|
|
||||||
$slots[$i] = $this->armor[$i]->getID() !== Item::AIR ? $this->armor[$i]->getID() - 256 : 0;
|
|
||||||
}else{
|
|
||||||
$this->armor[$i] = Item::get(Item::AIR, 0, 0);
|
|
||||||
$slots[$i] = 255;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if($player instanceof Player){
|
|
||||||
$pk = new PlayerArmorEquipmentPacket();
|
|
||||||
$pk->eid = $this->id;
|
|
||||||
$pk->slots = $slots;
|
|
||||||
$player->dataPacket($pk);
|
|
||||||
}elseif($this instanceof Player){
|
|
||||||
$pk = new ContainerSetContentPacket;
|
|
||||||
$pk->windowid = 0x78; //Armor window id
|
|
||||||
$pk->slots = $this->armor;
|
|
||||||
$this->dataPacket($pk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getData(){ //TODO
|
public function getData(){ //TODO
|
||||||
$flags = 0;
|
$flags = 0;
|
||||||
$flags |= $this->fireTicks > 0 ? 1 : 0;
|
$flags |= $this->fireTicks > 0 ? 1 : 0;
|
||||||
@ -305,132 +200,4 @@ class Human extends Creature implements ProjectileSource, InventorySource{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function hasItem(Item $item, $checkDamage = true){
|
|
||||||
foreach($this->inventory as $s => $i){
|
|
||||||
if($i->equals($item, $checkDamage)){
|
|
||||||
return $i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function canAddItem(Item $item){
|
|
||||||
$inv = $this->inventory;
|
|
||||||
while($item->getCount() > 0){
|
|
||||||
$add = 0;
|
|
||||||
foreach($inv as $s => $i){
|
|
||||||
if($i->getID() === Item::AIR){
|
|
||||||
$add = min($i->getMaxStackSize(), $item->getCount());
|
|
||||||
$inv[$s] = clone $item;
|
|
||||||
$inv[$s]->setCount($add);
|
|
||||||
break;
|
|
||||||
}elseif($i->equals($item)){
|
|
||||||
$add = min($i->getMaxStackSize() - $i->getCount(), $item->getCount());
|
|
||||||
if($add <= 0){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$inv[$s] = clone $item;
|
|
||||||
$inv[$s]->setCount($i->getCount() + $add);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if($add <= 0){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$item->setCount($item->getCount() - $add);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addItem(Item $item){
|
|
||||||
while($item->getCount() > 0){
|
|
||||||
$add = 0;
|
|
||||||
foreach($this->inventory as $s => $i){
|
|
||||||
if($i->getID() === Item::AIR){
|
|
||||||
$add = min($i->getMaxStackSize(), $item->getCount());
|
|
||||||
$i2 = clone $item;
|
|
||||||
$i2->setCount($add);
|
|
||||||
$this->setSlot($s, $i2);
|
|
||||||
break;
|
|
||||||
}elseif($i->equals($item)){
|
|
||||||
$add = min($i->getMaxStackSize() - $i->getCount(), $item->getCount());
|
|
||||||
if($add <= 0){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$i2 = clone $item;
|
|
||||||
$i2->setCount($i->getCount() + $add);
|
|
||||||
$this->setSlot($s, $i2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if($add <= 0){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$item->setCount($item->getCount() - $add);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function canRemoveItem(Item $item, $checkDamage = true){
|
|
||||||
return $this->hasItem($item, $checkDamage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeItem(Item $item, $checkDamage = true){
|
|
||||||
while($item->getCount() > 0){
|
|
||||||
$remove = 0;
|
|
||||||
foreach($this->inventory as $s => $i){
|
|
||||||
if($i->equals($item, $checkDamage)){
|
|
||||||
$remove = min($item->getCount(), $i->getCount());
|
|
||||||
if($item->getCount() < $i->getCount()){
|
|
||||||
$i->setCount($i->getCount() - $item->getCount());
|
|
||||||
$this->setSlot($s, $i);
|
|
||||||
}else{
|
|
||||||
$this->setSlot($s, Item::get(Item::AIR, 0, 0));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if($remove <= 0){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$item->setCount($item->getCount() - $remove);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setSlot($slot, Item $item){
|
|
||||||
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityInventoryChangeEvent($this, $this->getSlot($slot), $item, $slot));
|
|
||||||
if($ev->isCancelled()){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$this->inventory[(int) $slot] = $ev->getNewItem();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $slot
|
|
||||||
*
|
|
||||||
* @return Item
|
|
||||||
*/
|
|
||||||
public function getSlot($slot){
|
|
||||||
$slot = (int) $slot;
|
|
||||||
if(!isset($this->inventory[$slot])){
|
|
||||||
$this->inventory[$slot] = Item::get(Item::AIR, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->inventory[$slot];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAllSlots(){
|
|
||||||
return $this->inventory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSlotCount(){
|
|
||||||
return count($this->inventory);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
|
|
||||||
namespace pocketmine\event\player;
|
namespace pocketmine\event\player;
|
||||||
|
|
||||||
use pocketmine\event\Cancellable;
|
|
||||||
use pocketmine\Event;
|
use pocketmine\Event;
|
||||||
|
use pocketmine\event\Cancellable;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
|
|
||||||
namespace pocketmine\event\server;
|
namespace pocketmine\event\server;
|
||||||
|
|
||||||
use pocketmine\event;
|
|
||||||
use pocketmine\event\Cancellable;
|
use pocketmine\event\Cancellable;
|
||||||
|
use pocketmine\event;
|
||||||
use pocketmine\network\protocol\DataPacket;
|
use pocketmine\network\protocol\DataPacket;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
|
|
||||||
namespace pocketmine\event\server;
|
namespace pocketmine\event\server;
|
||||||
|
|
||||||
use pocketmine\event;
|
|
||||||
use pocketmine\event\Cancellable;
|
use pocketmine\event\Cancellable;
|
||||||
|
use pocketmine\event;
|
||||||
use pocketmine\network\protocol\DataPacket;
|
use pocketmine\network\protocol\DataPacket;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* ____ _ _ __ __ _ __ __ ____
|
|
||||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
|
||||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
|
||||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
|
||||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* @author PocketMine Team
|
|
||||||
* @link http://www.pocketmine.net/
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Events used by Tiles
|
|
||||||
*/
|
|
||||||
namespace pocketmine\event\tile;
|
|
||||||
|
|
||||||
use pocketmine\event\Event;
|
|
||||||
|
|
||||||
abstract class TileEvent extends Event{
|
|
||||||
protected $tile;
|
|
||||||
|
|
||||||
public function getTile(){
|
|
||||||
return $this->tile;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,60 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* ____ _ _ __ __ _ __ __ ____
|
|
||||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
|
||||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
|
||||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
|
||||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* @author PocketMine Team
|
|
||||||
* @link http://www.pocketmine.net/
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace pocketmine\event\tile;
|
|
||||||
|
|
||||||
use pocketmine\Event;
|
|
||||||
use pocketmine\event\Cancellable;
|
|
||||||
use pocketmine\item\Item;
|
|
||||||
use pocketmine\tile\Tile;
|
|
||||||
|
|
||||||
class TileInventoryChangeEvent extends TileEvent implements Cancellable{
|
|
||||||
public static $handlerList = null;
|
|
||||||
|
|
||||||
private $oldItem;
|
|
||||||
private $newItem;
|
|
||||||
private $slot;
|
|
||||||
|
|
||||||
public function __construct(Tile $tile, Item $oldItem, Item $newItem, $slot){
|
|
||||||
$this->tile = $tile;
|
|
||||||
$this->oldItem = $oldItem;
|
|
||||||
$this->newItem = $newItem;
|
|
||||||
$this->slot = (int) $slot;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSlot(){
|
|
||||||
return $this->slot;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getNewItem(){
|
|
||||||
return $this->newItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setNewItem(Item $item){
|
|
||||||
$this->newItem = $item;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getOldItem(){
|
|
||||||
return $this->oldItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -21,9 +21,13 @@
|
|||||||
|
|
||||||
namespace pocketmine\inventory;
|
namespace pocketmine\inventory;
|
||||||
|
|
||||||
|
use pocketmine\entity\Entity;
|
||||||
|
use pocketmine\event\entity\EntityInventoryChangeEvent;
|
||||||
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\network\protocol\ContainerSetContentPacket;
|
||||||
use pocketmine\network\protocol\ContainerSetSlotPacket;
|
use pocketmine\network\protocol\ContainerSetSlotPacket;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\Server;
|
||||||
|
|
||||||
abstract class BaseInventory implements Inventory{
|
abstract class BaseInventory implements Inventory{
|
||||||
|
|
||||||
@ -57,7 +61,7 @@ abstract class BaseInventory implements Inventory{
|
|||||||
|
|
||||||
//A holder can be a plugin, or an entity
|
//A holder can be a plugin, or an entity
|
||||||
if($this->holder instanceof Player){
|
if($this->holder instanceof Player){
|
||||||
$this->viewers->attach($this->holder);
|
$this->holder->addWindow($this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -123,18 +127,34 @@ abstract class BaseInventory implements Inventory{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function setItem($index, Item $item){
|
public function setItem($index, Item $item){
|
||||||
if($index < 0 or $index >= $this->size or $item->getID() === 0){
|
if($index < 0 or $index >= $this->size){
|
||||||
return;
|
return false;
|
||||||
|
}elseif($item->getID() === 0){
|
||||||
|
$this->clear($index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$holder = $this->getHolder();
|
||||||
|
if($holder instanceof Entity){
|
||||||
|
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityInventoryChangeEvent($holder, $this->getItem($index), $item, $index));
|
||||||
|
if($ev->isCancelled()){
|
||||||
|
$this->sendContents($this->getViewers());
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$item = $ev->getNewItem();
|
||||||
|
}
|
||||||
|
|
||||||
$old = $this->slots[$index];
|
$old = $this->slots[$index];
|
||||||
$this->slots[$index] = clone $item;
|
$this->slots[$index] = clone $item;
|
||||||
$this->onSlotChange($index, $old);
|
$this->onSlotChange($index, $old);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function contains(Item $item){
|
public function contains(Item $item){
|
||||||
$count = max(1, $item->getCount());
|
$count = max(1, $item->getCount());
|
||||||
$checkDamage = $item->getDamage() === null ? false : true;
|
$checkDamage = $item->getDamage() === null ? false : true;
|
||||||
foreach($this->slots as $i){
|
foreach($this->getContents() as $i){
|
||||||
if($item->equals($i, $checkDamage)){
|
if($item->equals($i, $checkDamage)){
|
||||||
$count -= $i->getCount();
|
$count -= $i->getCount();
|
||||||
if($count <= 0){
|
if($count <= 0){
|
||||||
@ -149,7 +169,7 @@ abstract class BaseInventory implements Inventory{
|
|||||||
public function all(Item $item){
|
public function all(Item $item){
|
||||||
$slots = [];
|
$slots = [];
|
||||||
$checkDamage = $item->getDamage() === null ? false : true;
|
$checkDamage = $item->getDamage() === null ? false : true;
|
||||||
foreach($this->slots as $index => $i){
|
foreach($this->getContents() as $index => $i){
|
||||||
if($item->equals($i, $checkDamage)){
|
if($item->equals($i, $checkDamage)){
|
||||||
$slots[$index] = $i;
|
$slots[$index] = $i;
|
||||||
}
|
}
|
||||||
@ -160,7 +180,7 @@ abstract class BaseInventory implements Inventory{
|
|||||||
|
|
||||||
public function remove(Item $item){
|
public function remove(Item $item){
|
||||||
$checkDamage = $item->getDamage() === null ? false : true;
|
$checkDamage = $item->getDamage() === null ? false : true;
|
||||||
foreach($this->slots as $index => $i){
|
foreach($this->getContents() as $index => $i){
|
||||||
if($item->equals($i, $checkDamage)){
|
if($item->equals($i, $checkDamage)){
|
||||||
$this->clear($index);
|
$this->clear($index);
|
||||||
}
|
}
|
||||||
@ -170,7 +190,7 @@ abstract class BaseInventory implements Inventory{
|
|||||||
public function first(Item $item){
|
public function first(Item $item){
|
||||||
$count = max(1, $item->getCount());
|
$count = max(1, $item->getCount());
|
||||||
$checkDamage = $item->getDamage() === null ? false : true;
|
$checkDamage = $item->getDamage() === null ? false : true;
|
||||||
foreach($this->slots as $index => $i){
|
foreach($this->getContents() as $index => $i){
|
||||||
if($item->equals($i, $checkDamage) and $i->getCount() >= $count){
|
if($item->equals($i, $checkDamage) and $i->getCount() >= $count){
|
||||||
return $index;
|
return $index;
|
||||||
}
|
}
|
||||||
@ -181,10 +201,7 @@ abstract class BaseInventory implements Inventory{
|
|||||||
|
|
||||||
public function firstEmpty(){
|
public function firstEmpty(){
|
||||||
for($i = 0; $i < $this->size; ++$i){
|
for($i = 0; $i < $this->size; ++$i){
|
||||||
if(!isset($this->slots[$i])){
|
if($this->getItem($i)->getID() === Item::AIR){
|
||||||
return $i;
|
|
||||||
}elseif(!($this->slots[$i] instanceof Item) or $this->slots[$i]->getID() === 0 or $this->slots[$i]->getCount() <= 0){
|
|
||||||
unset($this->slots[$i]);
|
|
||||||
return $i;
|
return $i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -196,11 +213,10 @@ abstract class BaseInventory implements Inventory{
|
|||||||
/** @var Item[] $slots */
|
/** @var Item[] $slots */
|
||||||
$slots = func_get_args();
|
$slots = func_get_args();
|
||||||
for($i = 0; $i < $this->size; ++$i){
|
for($i = 0; $i < $this->size; ++$i){
|
||||||
if(!isset($this->slots[$i])){
|
$item = $this->getItem($i);
|
||||||
$item = $this->slots[$i] = array_shift($slots);
|
if($item->getID() === Item::AIR){
|
||||||
$this->onSlotChange($i, null);
|
$item = array_shift($slots);
|
||||||
}else{
|
$this->setItem($i, $item);
|
||||||
$item = $this->slots[$i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($slots as $index => $slot){
|
foreach($slots as $index => $slot){
|
||||||
@ -230,10 +246,9 @@ abstract class BaseInventory implements Inventory{
|
|||||||
/** @var Item[] $slots */
|
/** @var Item[] $slots */
|
||||||
$slots = func_get_args();
|
$slots = func_get_args();
|
||||||
for($i = 0; $i < $this->size; ++$i){
|
for($i = 0; $i < $this->size; ++$i){
|
||||||
if(!isset($this->slots[$i])){
|
$item = $this->getItem($i);
|
||||||
|
if($item->getID() === Item::AIR){
|
||||||
continue;
|
continue;
|
||||||
}else{
|
|
||||||
$item = $this->slots[$i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($slots as $index => $slot){
|
foreach($slots as $index => $slot){
|
||||||
@ -263,14 +278,32 @@ abstract class BaseInventory implements Inventory{
|
|||||||
|
|
||||||
public function clear($index){
|
public function clear($index){
|
||||||
if(isset($this->slots[$index])){
|
if(isset($this->slots[$index])){
|
||||||
|
$item = Item::get(Item::AIR, null, 0);
|
||||||
$old = $this->slots[$index];
|
$old = $this->slots[$index];
|
||||||
|
$holder = $this->getHolder();
|
||||||
|
if($holder instanceof Entity){
|
||||||
|
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityInventoryChangeEvent($holder, $old, $item, $index));
|
||||||
|
if($ev->isCancelled()){
|
||||||
|
$this->sendContents($this->getViewers());
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$item = $ev->getNewItem();
|
||||||
|
}
|
||||||
|
if($item->getID() !== Item::AIR){
|
||||||
|
$this->slots[$index] = clone $item;
|
||||||
|
}else{
|
||||||
unset($this->slots[$index]);
|
unset($this->slots[$index]);
|
||||||
|
}
|
||||||
|
|
||||||
$this->onSlotChange($index, $old);
|
$this->onSlotChange($index, $old);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function clearAll(){
|
public function clearAll(){
|
||||||
foreach($this->slots as $index => $i){
|
foreach($this->getContents() as $index => $i){
|
||||||
$this->clear($index);
|
$this->clear($index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -280,6 +313,7 @@ abstract class BaseInventory implements Inventory{
|
|||||||
foreach($this->viewers as $viewer){
|
foreach($this->viewers as $viewer){
|
||||||
$viewers[] = $viewer;
|
$viewers[] = $viewer;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $viewers;
|
return $viewers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,12 +334,44 @@ abstract class BaseInventory implements Inventory{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function onSlotChange($index, $before){
|
public function onSlotChange($index, $before){
|
||||||
|
$this->sendSlot($index, $this->getViewers());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Player|Player[] $target
|
||||||
|
*/
|
||||||
|
public function sendContents($target){
|
||||||
|
if($target instanceof Player){
|
||||||
|
$target = [$target];
|
||||||
|
}
|
||||||
|
|
||||||
|
$pk = new ContainerSetContentPacket();
|
||||||
|
$pk->slots = [];
|
||||||
|
for($i = 0; $i < $this->getSize(); ++$i){
|
||||||
|
$pk->slots[$i] = $this->getItem($i);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($target as $player){
|
||||||
|
$pk->windowid = $player->getWindowId($this);
|
||||||
|
$player->dataPacket(clone $pk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $index
|
||||||
|
* @param Player|Player[] $target
|
||||||
|
*/
|
||||||
|
public function sendSlot($index, $target){
|
||||||
|
if($target instanceof Player){
|
||||||
|
$target = [$target];
|
||||||
|
}
|
||||||
|
|
||||||
$pk = new ContainerSetSlotPacket;
|
$pk = new ContainerSetSlotPacket;
|
||||||
$pk->slot = $index;
|
$pk->slot = $index;
|
||||||
$pk->item = clone $this->getItem($index);
|
$pk->item = clone $this->getItem($index);
|
||||||
|
|
||||||
/** @var Player $player */
|
foreach($target as $player){
|
||||||
foreach($this->getViewers() as $player){
|
|
||||||
$pk->windowid = $player->getWindowId($this);
|
$pk->windowid = $player->getWindowId($this);
|
||||||
$player->dataPacket(clone $pk);
|
$player->dataPacket(clone $pk);
|
||||||
}
|
}
|
||||||
|
67
src/pocketmine/inventory/ChestInventory.php
Normal file
67
src/pocketmine/inventory/ChestInventory.php
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* ____ _ _ __ __ _ __ __ ____
|
||||||
|
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||||
|
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||||
|
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||||
|
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* @author PocketMine Team
|
||||||
|
* @link http://www.pocketmine.net/
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace pocketmine\inventory;
|
||||||
|
|
||||||
|
use pocketmine\network\protocol\TileEventPacket;
|
||||||
|
use pocketmine\Player;
|
||||||
|
use pocketmine\tile\Chest;
|
||||||
|
|
||||||
|
class ChestInventory extends ContainerInventory{
|
||||||
|
public function __construct(Chest $tile){
|
||||||
|
parent::__construct($tile, InventoryType::get(InventoryType::CHEST));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Chest
|
||||||
|
*/
|
||||||
|
public function getHolder(){
|
||||||
|
return $this->holder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onOpen(Player $who){
|
||||||
|
parent::onOpen($who);
|
||||||
|
|
||||||
|
if(count($this->getViewers()) === 1){
|
||||||
|
$pk = new TileEventPacket;
|
||||||
|
$pk->x = $this->getHolder()->getX();
|
||||||
|
$pk->y = $this->getHolder()->getY();
|
||||||
|
$pk->z = $this->getHolder()->getZ();
|
||||||
|
$pk->case1 = 1;
|
||||||
|
$pk->case2 = 2;
|
||||||
|
Player::broadcastPacket($this->getHolder()->getLevel()->getPlayers(), $pk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onClose(Player $who){
|
||||||
|
parent::onClose($who);
|
||||||
|
|
||||||
|
if(count($this->getViewers()) === 1){
|
||||||
|
$pk = new TileEventPacket;
|
||||||
|
$pk->x = $this->getHolder()->getX();
|
||||||
|
$pk->y = $this->getHolder()->getY();
|
||||||
|
$pk->z = $this->getHolder()->getZ();
|
||||||
|
$pk->case1 = 1;
|
||||||
|
$pk->case2 = 0;
|
||||||
|
Player::broadcastPacket($this->getHolder()->getLevel()->getPlayers(), $pk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
55
src/pocketmine/inventory/ContainerInventory.php
Normal file
55
src/pocketmine/inventory/ContainerInventory.php
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* ____ _ _ __ __ _ __ __ ____
|
||||||
|
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||||
|
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||||
|
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||||
|
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* @author PocketMine Team
|
||||||
|
* @link http://www.pocketmine.net/
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace pocketmine\inventory;
|
||||||
|
|
||||||
|
use pocketmine\network\protocol\ContainerClosePacket;
|
||||||
|
use pocketmine\network\protocol\ContainerOpenPacket;
|
||||||
|
use pocketmine\Player;
|
||||||
|
use pocketmine\tile\Chest;
|
||||||
|
use pocketmine\tile\Furnace;
|
||||||
|
|
||||||
|
abstract class ContainerInventory extends BaseInventory{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Chest|Furnace
|
||||||
|
*/
|
||||||
|
public function getHolder(){
|
||||||
|
return $this->holder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onOpen(Player $who){
|
||||||
|
$pk = new ContainerOpenPacket;
|
||||||
|
$pk->windowid = $who->getWindowId($this);
|
||||||
|
$pk->type = 0;
|
||||||
|
$pk->slots = $this->getSize();
|
||||||
|
$pk->x = $this->getHolder()->getX();
|
||||||
|
$pk->y = $this->getHolder()->getY();
|
||||||
|
$pk->z = $this->getHolder()->getZ();
|
||||||
|
$who->dataPacket($pk);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onClose(Player $who){
|
||||||
|
$pk = new ContainerClosePacket;
|
||||||
|
$pk->windowid = $who->getWindowId($this);
|
||||||
|
$who->dataPacket($pk);
|
||||||
|
}
|
||||||
|
}
|
101
src/pocketmine/inventory/DoubleChestInventory.php
Normal file
101
src/pocketmine/inventory/DoubleChestInventory.php
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* ____ _ _ __ __ _ __ __ ____
|
||||||
|
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||||
|
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||||
|
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||||
|
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* @author PocketMine Team
|
||||||
|
* @link http://www.pocketmine.net/
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace pocketmine\inventory;
|
||||||
|
|
||||||
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\tile\Chest;
|
||||||
|
|
||||||
|
class DoubleChestInventory extends ChestInventory implements InventoryHolder{
|
||||||
|
/** @var ChestInventory */
|
||||||
|
private $left;
|
||||||
|
/** @var ChestInventory */
|
||||||
|
private $right;
|
||||||
|
|
||||||
|
public function __construct(Chest $left, Chest $right){
|
||||||
|
$this->left = $left->getRealInventory();
|
||||||
|
$this->right = $right->getRealInventory();
|
||||||
|
BaseInventory::__construct($this, InventoryType::get(InventoryType::DOUBLE_CHEST));
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
public function getInventory(){
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
public function getHolder(){
|
||||||
|
return $this->left;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getItem($index){
|
||||||
|
return $index < $this->left->getSize() ? $this->left->getItem($index) : $this->right->getItem($index - $this->right->getSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setItem($index, Item $item){
|
||||||
|
return $index < $this->left->getSize() ? $this->left->setItem($index, $item) : $this->right->setItem($index - $this->right->getSize(), $item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function clear($index){
|
||||||
|
return $index < $this->left->getSize() ? $this->left->clear($index) : $this->right->clear($index - $this->right->getSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getContents(){
|
||||||
|
$contents = [];
|
||||||
|
for($i = 0; $i < $this->getSize(); ++$i){
|
||||||
|
$contents[$i] = $this->getItem($i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Item[] $items
|
||||||
|
*/
|
||||||
|
public function setContents(array $items){
|
||||||
|
if(count($items) > $this->size){
|
||||||
|
$items = array_slice($items, 0, $this->size, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::setContents($items);
|
||||||
|
|
||||||
|
$leftItems = array_slice($items, 0, $this->left->getSize(), true);
|
||||||
|
$this->left->setContents($leftItems);
|
||||||
|
if(count($items) > $this->left->getSize()){
|
||||||
|
$rightItems = array_slice($items, $this->left->getSize() - 1, $this->right->getSize(), true);
|
||||||
|
$this->right->setContents($rightItems);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ChestInventory
|
||||||
|
*/
|
||||||
|
public function getLeftSide(){
|
||||||
|
return $this->left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ChestInventory
|
||||||
|
*/
|
||||||
|
public function getRightSide(){
|
||||||
|
return $this->right;
|
||||||
|
}
|
||||||
|
}
|
92
src/pocketmine/inventory/FurnaceInventory.php
Normal file
92
src/pocketmine/inventory/FurnaceInventory.php
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* ____ _ _ __ __ _ __ __ ____
|
||||||
|
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||||
|
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||||
|
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||||
|
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* @author PocketMine Team
|
||||||
|
* @link http://www.pocketmine.net/
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace pocketmine\inventory;
|
||||||
|
|
||||||
|
|
||||||
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\tile\Furnace;
|
||||||
|
|
||||||
|
class FurnaceInventory extends ContainerInventory{
|
||||||
|
public function __construct(Furnace $tile){
|
||||||
|
parent::__construct($tile, InventoryType::get(InventoryType::FURNACE));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Furnace
|
||||||
|
*/
|
||||||
|
public function getHolder(){
|
||||||
|
return $this->holder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Item
|
||||||
|
*/
|
||||||
|
public function getResult(){
|
||||||
|
return $this->getItem(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Item
|
||||||
|
*/
|
||||||
|
public function getFuel(){
|
||||||
|
return $this->getItem(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Item
|
||||||
|
*/
|
||||||
|
public function getSmelting(){
|
||||||
|
return $this->getItem(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Item $item
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function setResult(Item $item){
|
||||||
|
return $this->setItem(2, $item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Item $item
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function setFuel(Item $item){
|
||||||
|
return $this->setItem(1, $item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Item $item
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function setSmelting(Item $item){
|
||||||
|
return $this->setItem(0, $item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onSlotChange($index, $before){
|
||||||
|
parent::onSlotChange($index, $before);
|
||||||
|
//TODO: implement Furnace scheduled update
|
||||||
|
}
|
||||||
|
}
|
@ -50,6 +50,15 @@ interface Inventory{
|
|||||||
*/
|
*/
|
||||||
public function getItem($index);
|
public function getItem($index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts an Item in a slot.
|
||||||
|
* If a plugin refuses the update or $index is invalid, it'll return false
|
||||||
|
*
|
||||||
|
* @param int $index
|
||||||
|
* @param Item $item
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public function setItem($index, Item $item);
|
public function setItem($index, Item $item);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -127,6 +136,8 @@ interface Inventory{
|
|||||||
* Will clear a specific slot
|
* Will clear a specific slot
|
||||||
*
|
*
|
||||||
* @param int $index
|
* @param int $index
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function clear($index);
|
public function clear($index);
|
||||||
|
|
||||||
|
@ -26,10 +26,11 @@ namespace pocketmine\inventory;
|
|||||||
*/
|
*/
|
||||||
class InventoryType{
|
class InventoryType{
|
||||||
const CHEST = 0;
|
const CHEST = 0;
|
||||||
const PLAYER = 1;
|
const DOUBLE_CHEST = 1;
|
||||||
const FURNACE = 2;
|
const PLAYER = 2;
|
||||||
const CRAFTING = 3;
|
const FURNACE = 3;
|
||||||
const WORKBENCH = 4;
|
const CRAFTING = 4;
|
||||||
|
const WORKBENCH = 5;
|
||||||
|
|
||||||
private static $default = [];
|
private static $default = [];
|
||||||
|
|
||||||
@ -46,6 +47,7 @@ class InventoryType{
|
|||||||
}
|
}
|
||||||
|
|
||||||
static::$default[static::CHEST] = new InventoryType(27, "Chest");
|
static::$default[static::CHEST] = new InventoryType(27, "Chest");
|
||||||
|
static::$default[static::DOUBLE_CHEST] = new InventoryType(27 + 27, "Double Chest");
|
||||||
static::$default[static::PLAYER] = new InventoryType(31, "Player"); //27 CONTAINER, 4 ARMOR (9 reference HOTBAR slots)
|
static::$default[static::PLAYER] = new InventoryType(31, "Player"); //27 CONTAINER, 4 ARMOR (9 reference HOTBAR slots)
|
||||||
static::$default[static::FURNACE] = new InventoryType(3, "Furnace");
|
static::$default[static::FURNACE] = new InventoryType(3, "Furnace");
|
||||||
static::$default[static::CRAFTING] = new InventoryType(5, "Crafting"); //4 CRAFTING slots, 1 RESULT
|
static::$default[static::CRAFTING] = new InventoryType(5, "Crafting"); //4 CRAFTING slots, 1 RESULT
|
||||||
|
@ -22,11 +22,15 @@
|
|||||||
namespace pocketmine\inventory;
|
namespace pocketmine\inventory;
|
||||||
|
|
||||||
use pocketmine\entity\Human;
|
use pocketmine\entity\Human;
|
||||||
|
use pocketmine\event\entity\EntityArmorChangeEvent;
|
||||||
|
use pocketmine\event\player\PlayerItemHeldEvent;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\network\protocol\ContainerSetContentPacket;
|
use pocketmine\network\protocol\ContainerSetContentPacket;
|
||||||
|
use pocketmine\network\protocol\ContainerSetSlotPacket;
|
||||||
use pocketmine\network\protocol\PlayerArmorEquipmentPacket;
|
use pocketmine\network\protocol\PlayerArmorEquipmentPacket;
|
||||||
use pocketmine\network\protocol\PlayerEquipmentPacket;
|
use pocketmine\network\protocol\PlayerEquipmentPacket;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
use pocketmine\Server;
|
||||||
|
|
||||||
class PlayerInventory extends BaseInventory{
|
class PlayerInventory extends BaseInventory{
|
||||||
|
|
||||||
@ -83,8 +87,13 @@ class PlayerInventory extends BaseInventory{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Item $item
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public function setItemInHand(Item $item){
|
public function setItemInHand(Item $item){
|
||||||
$this->setItem($this->getHeldItemSlot(), $item);
|
return $this->setItem($this->getHeldItemSlot(), $item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getHeldItemSlot(){
|
public function getHeldItemSlot(){
|
||||||
@ -93,7 +102,33 @@ class PlayerInventory extends BaseInventory{
|
|||||||
|
|
||||||
public function setHeldItemSlot($slot){
|
public function setHeldItemSlot($slot){
|
||||||
if($slot >= 0 and $slot < $this->getSize()){
|
if($slot >= 0 and $slot < $this->getSize()){
|
||||||
|
$item = $this->getItem($slot);
|
||||||
|
if($this->getHolder() instanceof Player){
|
||||||
|
Server::getInstance()->getPluginManager()->callEvent($ev = new PlayerItemHeldEvent($this->getHolder(), $item, $slot, 0));
|
||||||
|
if($ev->isCancelled()){
|
||||||
|
$this->sendHeldItem($this->getHolder());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$this->setHotbarSlotIndex($this->itemInHandIndex, $slot);
|
$this->setHotbarSlotIndex($this->itemInHandIndex, $slot);
|
||||||
|
$this->sendHeldItem($this->getHolder()->getViewers());
|
||||||
|
|
||||||
|
if($this->getHolder() instanceof Player){
|
||||||
|
$this->sendHeldItem($this->getHolder());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Player|Player[] $target
|
||||||
|
*/
|
||||||
|
public function sendHeldItem($target){
|
||||||
|
if($target instanceof Player){
|
||||||
|
$target = [$target];
|
||||||
|
}
|
||||||
|
|
||||||
$item = $this->getItemInHand();
|
$item = $this->getItemInHand();
|
||||||
|
|
||||||
$pk = new PlayerEquipmentPacket;
|
$pk = new PlayerEquipmentPacket;
|
||||||
@ -102,7 +137,12 @@ class PlayerInventory extends BaseInventory{
|
|||||||
$pk->meta = $item->getDamage();
|
$pk->meta = $item->getDamage();
|
||||||
$pk->slot = 0;
|
$pk->slot = 0;
|
||||||
|
|
||||||
foreach($this->getHolder()->getViewers() as $player){
|
foreach($target as $player){
|
||||||
|
if($player === $this->getHolder()){
|
||||||
|
//TODO: Check if Mojang enabled sending a single slot this
|
||||||
|
//$this->sendSlot($this->getHeldItemSlot());
|
||||||
|
$this->sendContents($this->getHolder());
|
||||||
|
}else{
|
||||||
$player->dataPacket(clone $pk);
|
$player->dataPacket(clone $pk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -112,34 +152,11 @@ class PlayerInventory extends BaseInventory{
|
|||||||
parent::onSlotChange($index, $before);
|
parent::onSlotChange($index, $before);
|
||||||
|
|
||||||
if($index >= $this->getSize()){
|
if($index >= $this->getSize()){
|
||||||
$armor = $this->getArmorContents();
|
$this->sendArmorContents($this->getHolder()->getViewers());
|
||||||
$slots = [];
|
|
||||||
|
|
||||||
foreach($armor as $i => $slot){
|
|
||||||
if($slot->getID() === Item::AIR){
|
|
||||||
$slots[$i] = 255;
|
|
||||||
}else{
|
|
||||||
$slots[$i] = $slot->getID();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$pk = new PlayerArmorEquipmentPacket;
|
if($this->getHolder() instanceof Player){
|
||||||
$pk->eid = $this->getHolder()->getID();
|
$this->sendArmorContents($this->getHolder());
|
||||||
$pk->slots = $slots;
|
|
||||||
|
|
||||||
if($index >= $this->getSize()){ //Armor change
|
|
||||||
foreach($this->getHolder()->getViewers() as $player){
|
|
||||||
if($player === $this->getHolder()){
|
|
||||||
/** @var Player $player */
|
|
||||||
$pk2 = new ContainerSetContentPacket;
|
|
||||||
$pk2->windowid = 0x78; //Armor window id constant
|
|
||||||
$pk2->slots = $armor;
|
|
||||||
$player->dataPacket($pk2);
|
|
||||||
}else{
|
|
||||||
$player->dataPacket(clone $pk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,6 +164,14 @@ class PlayerInventory extends BaseInventory{
|
|||||||
return 9;
|
return 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getArmorItem($index){
|
||||||
|
return $this->getItem($this->getSize() + $index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setArmorItem($index, Item $item){
|
||||||
|
return $this->setItem($this->getSize() + $index, $item);
|
||||||
|
}
|
||||||
|
|
||||||
public function getHelmet(){
|
public function getHelmet(){
|
||||||
return $this->getItem($this->getSize() + 3);
|
return $this->getItem($this->getSize() + 3);
|
||||||
}
|
}
|
||||||
@ -164,19 +189,66 @@ class PlayerInventory extends BaseInventory{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function setHelmet(Item $helmet){
|
public function setHelmet(Item $helmet){
|
||||||
$this->setItem($this->getSize() + 3, $helmet);
|
return $this->setItem($this->getSize() + 3, $helmet);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setChestplate(Item $chestplate){
|
public function setChestplate(Item $chestplate){
|
||||||
$this->setItem($this->getSize() + 2, $chestplate);
|
return $this->setItem($this->getSize() + 2, $chestplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setLeggings(Item $leggings){
|
public function setLeggings(Item $leggings){
|
||||||
$this->setItem($this->getSize() + 1, $leggings);
|
return $this->setItem($this->getSize() + 1, $leggings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setBoots(Item $boots){
|
public function setBoots(Item $boots){
|
||||||
$this->setItem($this->getSize(), $boots);
|
return $this->setItem($this->getSize(), $boots);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setItem($index, Item $item){
|
||||||
|
if($index < 0 or $index >= $this->size){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($index >= $this->getSize()){ //Armor change
|
||||||
|
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityArmorChangeEvent($this->getHolder(), $this->getItem($index), $item, $index));
|
||||||
|
if($ev->isCancelled()){
|
||||||
|
$this->sendArmorContents($this);
|
||||||
|
$this->sendContents($this);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$item = $ev->getNewItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
$old = $this->slots[$index];
|
||||||
|
$this->slots[$index] = clone $item;
|
||||||
|
$this->onSlotChange($index, $old);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function clear($index){
|
||||||
|
if(isset($this->slots[$index])){
|
||||||
|
$item = Item::get(Item::AIR, null, 0);
|
||||||
|
$old = $this->slots[$index];
|
||||||
|
if($index >= $this->getSize() and $index < $this->size){ //Armor change
|
||||||
|
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityArmorChangeEvent($this->getHolder(), $old, $item, $index));
|
||||||
|
if($ev->isCancelled()){
|
||||||
|
$this->sendArmorContents($this);
|
||||||
|
$this->sendContents($this);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$item = $ev->getNewItem();
|
||||||
|
}
|
||||||
|
if($item->getID() !== Item::AIR){
|
||||||
|
$this->slots[$index] = clone $item;
|
||||||
|
}else{
|
||||||
|
unset($this->slots[$index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->onSlotChange($index, $old);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -192,6 +264,41 @@ class PlayerInventory extends BaseInventory{
|
|||||||
return $armor;
|
return $armor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Player|Player[] $target
|
||||||
|
*/
|
||||||
|
public function sendArmorContents($target){
|
||||||
|
if($target instanceof Player){
|
||||||
|
$target = [$target];
|
||||||
|
}
|
||||||
|
$armor = $this->getArmorContents();
|
||||||
|
$slots = [];
|
||||||
|
|
||||||
|
foreach($armor as $i => $slot){
|
||||||
|
if($slot->getID() === Item::AIR){
|
||||||
|
$slots[$i] = 255;
|
||||||
|
}else{
|
||||||
|
$slots[$i] = $slot->getID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$pk = new PlayerArmorEquipmentPacket;
|
||||||
|
$pk->eid = $this->getHolder()->getID();
|
||||||
|
$pk->slots = $slots;
|
||||||
|
|
||||||
|
foreach($target as $player){
|
||||||
|
if($player === $this->getHolder()){
|
||||||
|
/** @var Player $player */
|
||||||
|
$pk2 = new ContainerSetContentPacket;
|
||||||
|
$pk2->windowid = 0x78; //Armor window id constant
|
||||||
|
$pk2->slots = $armor;
|
||||||
|
$player->dataPacket($pk2);
|
||||||
|
}else{
|
||||||
|
$player->dataPacket(clone $pk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Item[] $items
|
* @param Item[] $items
|
||||||
*/
|
*/
|
||||||
@ -209,6 +316,62 @@ class PlayerInventory extends BaseInventory{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Player|Player[] $target
|
||||||
|
*/
|
||||||
|
public function sendContents($target){
|
||||||
|
if($target instanceof Player){
|
||||||
|
$target = [$target];
|
||||||
|
}
|
||||||
|
|
||||||
|
$holder = $this->getHolder();
|
||||||
|
if($holder instanceof Player and ($holder->getGamemode() & 0x01) === 1){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pk = new ContainerSetContentPacket();
|
||||||
|
$pk->slots = [];
|
||||||
|
for($i = 0; $i < $this->getSize(); ++$i){ //Do not send armor by error here
|
||||||
|
$pk->slots[$i] = $this->getItem($i);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($target as $player){
|
||||||
|
$pk->hotbar = [];
|
||||||
|
if($player === $this->getHolder()){
|
||||||
|
for($i = 0; $i < $this->getHotbarSize(); ++$i){
|
||||||
|
$index = $this->getHotbarSlotIndex($i);
|
||||||
|
$pk->hotbar[] = $index <= -1 ? -1 : $index + 9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$pk->windowid = $player->getWindowId($this);
|
||||||
|
$player->dataPacket(clone $pk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $index
|
||||||
|
* @param Player|Player[] $target
|
||||||
|
*/
|
||||||
|
public function sendSlot($index, $target){
|
||||||
|
if($target instanceof Player){
|
||||||
|
$target = [$target];
|
||||||
|
}
|
||||||
|
|
||||||
|
$pk = new ContainerSetSlotPacket;
|
||||||
|
$pk->slot = $index;
|
||||||
|
$pk->item = clone $this->getItem($index);
|
||||||
|
|
||||||
|
foreach($target as $player){
|
||||||
|
if($player === $this->getHolder()){
|
||||||
|
//TODO: Check if Mojang has implemented this (for the player inventory) on Minecraft: PE 0.9.0
|
||||||
|
$this->sendContents($player);
|
||||||
|
}else{
|
||||||
|
$pk->windowid = $player->getWindowId($this);
|
||||||
|
$player->dataPacket(clone $pk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Human
|
* @return Human
|
||||||
*/
|
*/
|
||||||
|
@ -31,6 +31,7 @@ use pocketmine\event\block\BlockBreakEvent;
|
|||||||
use pocketmine\event\block\BlockPlaceEvent;
|
use pocketmine\event\block\BlockPlaceEvent;
|
||||||
use pocketmine\event\player\PlayerInteractEvent;
|
use pocketmine\event\player\PlayerInteractEvent;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\level\format\pmf\LevelFormat;
|
||||||
use pocketmine\level\generator\Generator;
|
use pocketmine\level\generator\Generator;
|
||||||
use pocketmine\math\Vector2;
|
use pocketmine\math\Vector2;
|
||||||
use pocketmine\math\Vector3 as Vector3;
|
use pocketmine\math\Vector3 as Vector3;
|
||||||
@ -42,7 +43,6 @@ use pocketmine\nbt\tag\String;
|
|||||||
use pocketmine\network\protocol\SetTimePacket;
|
use pocketmine\network\protocol\SetTimePacket;
|
||||||
use pocketmine\network\protocol\UpdateBlockPacket;
|
use pocketmine\network\protocol\UpdateBlockPacket;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
use pocketmine\level\format\pmf\LevelFormat;
|
|
||||||
use pocketmine\Server;
|
use pocketmine\Server;
|
||||||
use pocketmine\tile\Chest;
|
use pocketmine\tile\Chest;
|
||||||
use pocketmine\tile\Furnace;
|
use pocketmine\tile\Furnace;
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
|
|
||||||
namespace pocketmine\level;
|
namespace pocketmine\level;
|
||||||
|
|
||||||
|
use pocketmine\level\format\pmf\LevelFormat;
|
||||||
use pocketmine\level\format\PocketChunkParser;
|
use pocketmine\level\format\PocketChunkParser;
|
||||||
use pocketmine\nbt\NBT;
|
use pocketmine\nbt\NBT;
|
||||||
use pocketmine\level\format\pmf\LevelFormat;
|
|
||||||
use pocketmine\utils\Config;
|
use pocketmine\utils\Config;
|
||||||
|
|
||||||
class LevelImport{
|
class LevelImport{
|
||||||
|
@ -106,6 +106,7 @@ class Position extends Vector3{
|
|||||||
if(!$this->isValid()){
|
if(!$this->isValid()){
|
||||||
throw new \RuntimeException("Undefined Level reference");
|
throw new \RuntimeException("Undefined Level reference");
|
||||||
}
|
}
|
||||||
|
|
||||||
return Position::fromObject(parent::getSide($side, $step), $this->getLevel());
|
return Position::fromObject(parent::getSide($side, $step), $this->getLevel());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
|
|
||||||
namespace pocketmine\level;
|
namespace pocketmine\level;
|
||||||
|
|
||||||
use pocketmine\level\generator\Generator;
|
|
||||||
use pocketmine\level\format\pmf\LevelFormat;
|
use pocketmine\level\format\pmf\LevelFormat;
|
||||||
|
use pocketmine\level\generator\Generator;
|
||||||
use pocketmine\Server;
|
use pocketmine\Server;
|
||||||
use pocketmine\utils\Binary;
|
use pocketmine\utils\Binary;
|
||||||
use pocketmine\utils\Random;
|
use pocketmine\utils\Random;
|
||||||
|
@ -20,8 +20,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
namespace pocketmine\level\format;
|
namespace pocketmine\level\format;
|
||||||
use pocketmine\Server;
|
|
||||||
use pocketmine\math\Vector3;
|
use pocketmine\math\Vector3;
|
||||||
|
use pocketmine\Server;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All Level formats must implement this interface
|
* All Level formats must implement this interface
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
namespace pocketmine\level\format;
|
namespace pocketmine\level\format;
|
||||||
|
|
||||||
use pocketmine\utils\Binary;
|
use pocketmine\utils\Binary;
|
||||||
use pocketmine\utils\Utils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WARNING: This code is old, and only supports the file format partially (reverse engineering)
|
* WARNING: This code is old, and only supports the file format partially (reverse engineering)
|
||||||
|
@ -138,6 +138,7 @@ class ChunkSection implements \pocketmine\level\format\ChunkSection{
|
|||||||
for($y = 15; $y >= 0; --$y){
|
for($y = 15; $y >= 0; --$y){
|
||||||
$column{15 - $y} = $this->blocks{($y << 8) + $i};
|
$column{15 - $y} = $this->blocks{($y << 8) + $i};
|
||||||
}
|
}
|
||||||
|
|
||||||
return $column;
|
return $column;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,6 +148,7 @@ class ChunkSection implements \pocketmine\level\format\ChunkSection{
|
|||||||
for($y = 7; $y >= 0; --$y){
|
for($y = 7; $y >= 0; --$y){
|
||||||
$column{7 - $y} = $this->data{($y << 7) + $i};
|
$column{7 - $y} = $this->data{($y << 7) + $i};
|
||||||
}
|
}
|
||||||
|
|
||||||
return $column;
|
return $column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
namespace pocketmine\level\format\anvil;
|
namespace pocketmine\level\format\anvil;
|
||||||
|
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\nbt\NBT;
|
use pocketmine\nbt\NBT;
|
||||||
use pocketmine\nbt\tag\Byte;
|
use pocketmine\nbt\tag\Byte;
|
||||||
use pocketmine\nbt\tag\ByteArray;
|
use pocketmine\nbt\tag\ByteArray;
|
||||||
@ -45,10 +44,12 @@ class RegionLoader{
|
|||||||
protected $lastSector;
|
protected $lastSector;
|
||||||
protected $locationTable = [];
|
protected $locationTable = [];
|
||||||
|
|
||||||
public function __construct($path,/*Level $level, */$regionX, $regionZ){
|
public function __construct($path, /*Level $level, */
|
||||||
|
$regionX, $regionZ){
|
||||||
$this->x = $regionX;
|
$this->x = $regionX;
|
||||||
$this->z = $regionZ;
|
$this->z = $regionZ;
|
||||||
$this->filePath = /*$level->getPath()*/$path . "region/r.$regionX.$regionZ.mca";
|
$this->filePath = /*$level->getPath()*/
|
||||||
|
$path . "region/r.$regionX.$regionZ.mca";
|
||||||
touch($this->filePath);
|
touch($this->filePath);
|
||||||
$this->filePointer = fopen($this->filePath, "r+b");
|
$this->filePointer = fopen($this->filePath, "r+b");
|
||||||
flock($this->filePointer, LOCK_EX);
|
flock($this->filePointer, LOCK_EX);
|
||||||
@ -103,6 +104,7 @@ class RegionLoader{
|
|||||||
$this->writeLocationIndex($index);
|
$this->writeLocationIndex($index);
|
||||||
}elseif($compression !== self::COMPRESSION_ZLIB and $compression !== self::COMPRESSION_GZIP){
|
}elseif($compression !== self::COMPRESSION_ZLIB and $compression !== self::COMPRESSION_GZIP){
|
||||||
trigger_error("Invalid compression type", E_USER_WARNING);
|
trigger_error("Invalid compression type", E_USER_WARNING);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,6 +115,7 @@ class RegionLoader{
|
|||||||
if(!$chunk instanceof Compound){
|
if(!$chunk instanceof Compound){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $chunk;
|
return $chunk;
|
||||||
//$chunk = new Chunk($level, $chunk);
|
//$chunk = new Chunk($level, $chunk);
|
||||||
}
|
}
|
||||||
@ -183,6 +186,7 @@ class RegionLoader{
|
|||||||
$this->writeLocationTable();
|
$this->writeLocationTable();
|
||||||
$n = $this->cleanGarbage();
|
$n = $this->cleanGarbage();
|
||||||
$this->writeLocationTable();
|
$this->writeLocationTable();
|
||||||
|
|
||||||
return $n;
|
return $n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
namespace pocketmine\level\format\generic;
|
namespace pocketmine\level\format\generic;
|
||||||
|
|
||||||
use pocketmine\level\format\Chunk;
|
use pocketmine\level\format\Chunk;
|
||||||
use pocketmine\level\format\ChunkSection;
|
use pocketmine\level\format\ChunkSection;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
@ -48,11 +49,13 @@ abstract class BaseChunk implements Chunk{
|
|||||||
$this->sections[$Y] = $section;
|
$this->sections[$Y] = $section;
|
||||||
}else{
|
}else{
|
||||||
trigger_error("Received invalid ChunkSection instance", E_USER_ERROR);
|
trigger_error("Received invalid ChunkSection instance", E_USER_ERROR);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($section >= self::SECTION_COUNT){
|
if($section >= self::SECTION_COUNT){
|
||||||
trigger_error("Invalid amount of chunks", E_USER_WARNING);
|
trigger_error("Invalid amount of chunks", E_USER_WARNING);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
namespace pocketmine\level\format\generic;
|
namespace pocketmine\level\format\generic;
|
||||||
|
|
||||||
use pocketmine\level\format\ChunkSection;
|
use pocketmine\level\format\ChunkSection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,6 +32,7 @@ class ChunkSection implements \pocketmine\level\format\ChunkSection{
|
|||||||
if($section !== null){
|
if($section !== null){
|
||||||
if(strlen($section) !== 8192){
|
if(strlen($section) !== 8192){
|
||||||
trigger_error("Invalid ChunkSection generated", E_USER_WARNING);
|
trigger_error("Invalid ChunkSection generated", E_USER_WARNING);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$this->section = $section;
|
$this->section = $section;
|
||||||
|
@ -26,7 +26,6 @@ use pocketmine\nbt\NBT;
|
|||||||
use pocketmine\nbt\tag\Compound;
|
use pocketmine\nbt\tag\Compound;
|
||||||
use pocketmine\nbt\tag\Enum;
|
use pocketmine\nbt\tag\Enum;
|
||||||
use pocketmine\utils\Binary;
|
use pocketmine\utils\Binary;
|
||||||
use pocketmine\utils\Utils;
|
|
||||||
|
|
||||||
class LevelFormat extends PMF{
|
class LevelFormat extends PMF{
|
||||||
const VERSION = 2;
|
const VERSION = 2;
|
||||||
|
@ -41,6 +41,7 @@ abstract class MetadataStore{
|
|||||||
$owningPlugin = $newMetadataValue->getOwningPlugin();
|
$owningPlugin = $newMetadataValue->getOwningPlugin();
|
||||||
if($owningPlugin === null){
|
if($owningPlugin === null){
|
||||||
trigger_error("Plugin cannot be null", E_USER_WARNING);
|
trigger_error("Plugin cannot be null", E_USER_WARNING);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,6 @@ use pocketmine\nbt\tag\Short;
|
|||||||
use pocketmine\nbt\tag\String;
|
use pocketmine\nbt\tag\String;
|
||||||
use pocketmine\nbt\tag\Tag;
|
use pocketmine\nbt\tag\Tag;
|
||||||
use pocketmine\utils\Binary;
|
use pocketmine\utils\Binary;
|
||||||
use pocketmine\utils\Utils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Named Binary Tag encoder/decoder
|
* Named Binary Tag encoder/decoder
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
namespace pocketmine\network\protocol;
|
namespace pocketmine\network\protocol;
|
||||||
|
|
||||||
use pocketmine\utils\Binary;
|
use pocketmine\utils\Binary;
|
||||||
use pocketmine\utils\Utils;
|
|
||||||
|
|
||||||
class AddMobPacket extends DataPacket{
|
class AddMobPacket extends DataPacket{
|
||||||
public $eid;
|
public $eid;
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
namespace pocketmine\network\protocol;
|
namespace pocketmine\network\protocol;
|
||||||
|
|
||||||
use pocketmine\utils\Binary;
|
use pocketmine\utils\Binary;
|
||||||
use pocketmine\utils\Utils;
|
|
||||||
|
|
||||||
class AddPlayerPacket extends DataPacket{
|
class AddPlayerPacket extends DataPacket{
|
||||||
public $clientID;
|
public $clientID;
|
||||||
|
@ -23,7 +23,6 @@ namespace pocketmine\network\protocol;
|
|||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\utils\Binary;
|
use pocketmine\utils\Binary;
|
||||||
use pocketmine\utils\Utils;
|
|
||||||
|
|
||||||
abstract class DataPacket extends \stdClass{
|
abstract class DataPacket extends \stdClass{
|
||||||
private $offset = 0;
|
private $offset = 0;
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
namespace pocketmine\network\protocol;
|
namespace pocketmine\network\protocol;
|
||||||
|
|
||||||
use pocketmine\utils\Binary;
|
use pocketmine\utils\Binary;
|
||||||
use pocketmine\utils\Utils;
|
|
||||||
|
|
||||||
class SetEntityDataPacket extends DataPacket{
|
class SetEntityDataPacket extends DataPacket{
|
||||||
public $eid;
|
public $eid;
|
||||||
|
@ -23,7 +23,6 @@ namespace pocketmine\network\query;
|
|||||||
|
|
||||||
use pocketmine\network\Packet;
|
use pocketmine\network\Packet;
|
||||||
use pocketmine\utils\Binary;
|
use pocketmine\utils\Binary;
|
||||||
use pocketmine\utils\Utils;
|
|
||||||
|
|
||||||
class QueryPacket extends Packet{
|
class QueryPacket extends Packet{
|
||||||
const HANDSHAKE = 9;
|
const HANDSHAKE = 9;
|
||||||
|
@ -79,7 +79,6 @@ use pocketmine\network\protocol\UnknownPacket;
|
|||||||
use pocketmine\network\protocol\UpdateBlockPacket;
|
use pocketmine\network\protocol\UpdateBlockPacket;
|
||||||
use pocketmine\network\protocol\UseItemPacket;
|
use pocketmine\network\protocol\UseItemPacket;
|
||||||
use pocketmine\utils\Binary;
|
use pocketmine\utils\Binary;
|
||||||
use pocketmine\utils\Utils;
|
|
||||||
|
|
||||||
class Packet extends NetworkPacket{
|
class Packet extends NetworkPacket{
|
||||||
private $packetID;
|
private $packetID;
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
namespace pocketmine\network\rcon;
|
namespace pocketmine\network\rcon;
|
||||||
|
|
||||||
use pocketmine\utils\Binary;
|
use pocketmine\utils\Binary;
|
||||||
use pocketmine\utils\Utils;
|
|
||||||
|
|
||||||
class RCONInstance extends \Thread{
|
class RCONInstance extends \Thread{
|
||||||
public $stop;
|
public $stop;
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
* Plugin related classes
|
* Plugin related classes
|
||||||
*/
|
*/
|
||||||
namespace pocketmine\plugin;
|
namespace pocketmine\plugin;
|
||||||
|
|
||||||
use pocketmine\command\CommandExecutor;
|
use pocketmine\command\CommandExecutor;
|
||||||
|
|
||||||
|
|
||||||
|
@ -148,6 +148,7 @@ class PluginManager{
|
|||||||
if(count($pluginCommands) > 0){
|
if(count($pluginCommands) > 0){
|
||||||
$this->commandMap->registerAll($plugin->getDescription()->getName(), $pluginCommands);
|
$this->commandMap->registerAll($plugin->getDescription()->getName(), $pluginCommands);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $plugin;
|
return $plugin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,7 @@ abstract class AsyncTask extends \Threaded{
|
|||||||
public function getResult(){
|
public function getResult(){
|
||||||
return $this->synchronized(function (){
|
return $this->synchronized(function (){
|
||||||
$this->finished = true;
|
$this->finished = true;
|
||||||
|
|
||||||
return @unserialize($this->result);
|
return @unserialize($this->result);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ class AsyncWorker extends \Worker{
|
|||||||
|
|
||||||
public function start($options = PTHREADS_INHERIT_CLASSES){
|
public function start($options = PTHREADS_INHERIT_CLASSES){
|
||||||
$this->path = \pocketmine\PATH;
|
$this->path = \pocketmine\PATH;
|
||||||
|
|
||||||
return parent::start($options & ~PTHREADS_INHERIT_CLASSES);
|
return parent::start($options & ~PTHREADS_INHERIT_CLASSES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,8 +208,10 @@ class ServerScheduler{
|
|||||||
$this->asyncPool->collect(function (AsyncTask $task){
|
$this->asyncPool->collect(function (AsyncTask $task){
|
||||||
if($task->isCompleted() or ($task->isFinished() and !$task->hasResult())){
|
if($task->isCompleted() or ($task->isFinished() and !$task->hasResult())){
|
||||||
--$this->asyncTasks;
|
--$this->asyncTasks;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -21,23 +21,134 @@
|
|||||||
|
|
||||||
namespace pocketmine\tile;
|
namespace pocketmine\tile;
|
||||||
|
|
||||||
|
use pocketmine\inventory\ChestInventory;
|
||||||
|
use pocketmine\inventory\DoubleChestInventory;
|
||||||
|
use pocketmine\inventory\InventoryHolder;
|
||||||
|
use pocketmine\item\Item;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
use pocketmine\math\Vector3 as Vector3;
|
use pocketmine\math\Vector3 as Vector3;
|
||||||
use pocketmine\nbt\NBT;
|
use pocketmine\nbt\NBT;
|
||||||
|
use pocketmine\nbt\tag\Byte;
|
||||||
use pocketmine\nbt\tag\Compound;
|
use pocketmine\nbt\tag\Compound;
|
||||||
use pocketmine\nbt\tag\Int;
|
use pocketmine\nbt\tag\Int;
|
||||||
|
use pocketmine\nbt\tag\Short;
|
||||||
use pocketmine\nbt\tag\String;
|
use pocketmine\nbt\tag\String;
|
||||||
use pocketmine\network\protocol\EntityDataPacket;
|
use pocketmine\network\protocol\EntityDataPacket;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
|
||||||
class Chest extends Spawnable{
|
class Chest extends Spawnable implements InventoryHolder, Container{
|
||||||
use Container;
|
|
||||||
|
|
||||||
const SLOTS = 27;
|
/** @var ChestInventory */
|
||||||
|
protected $inventory;
|
||||||
|
/** @var DoubleChestInventory */
|
||||||
|
protected $doubleInventory = null;
|
||||||
|
|
||||||
public function __construct(Level $level, Compound $nbt){
|
public function __construct(Level $level, Compound $nbt){
|
||||||
$nbt["id"] = Tile::CHEST;
|
$nbt["id"] = Tile::CHEST;
|
||||||
parent::__construct($level, $nbt);
|
parent::__construct($level, $nbt);
|
||||||
|
$this->inventory = new ChestInventory($this);
|
||||||
|
for($i = 0; $i < $this->getSize(); ++$i){
|
||||||
|
$this->inventory->setItem($i, $this->getItem($i));
|
||||||
|
}
|
||||||
|
$this->checkPairing();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getSize(){
|
||||||
|
return 27;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $index
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
protected function getSlotIndex($index){
|
||||||
|
foreach($this->namedtag->Items as $i => $slot){
|
||||||
|
if($slot["Slot"] === $s){
|
||||||
|
return $i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method should not be used by plugins, use the Inventory
|
||||||
|
*
|
||||||
|
* @param int $index
|
||||||
|
*
|
||||||
|
* @return Item
|
||||||
|
*/
|
||||||
|
public function getItem($index){
|
||||||
|
$i = $this->getSlotIndex($index);
|
||||||
|
if($i < 0){
|
||||||
|
return Item::get(Item::AIR, 0, 0);
|
||||||
|
}else{
|
||||||
|
return Item::get($this->namedtag->Items[$i]["id"], $this->namedtag->Items[$i]["Damage"], $this->namedtag->Items[$i]["Count"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method should not be used by plugins, use the Inventory
|
||||||
|
*
|
||||||
|
* @param int $index
|
||||||
|
* @param Item $item
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function setItem($index, Item $item){
|
||||||
|
$i = $this->getSlotIndex($index);
|
||||||
|
if($i < 0){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$d = new Compound(false, array(
|
||||||
|
new Byte("Count", $item->getCount()),
|
||||||
|
new Byte("Slot", $index),
|
||||||
|
new Short("id", $item->getID()),
|
||||||
|
new Short("Damage", $item->getDamage()),
|
||||||
|
));
|
||||||
|
|
||||||
|
if($item->getID() === Item::AIR or $item->getCount() <= 0){
|
||||||
|
if($i >= 0){
|
||||||
|
unset($this->namedtag->Items[$i]);
|
||||||
|
}
|
||||||
|
}elseif($i < 0){
|
||||||
|
$this->namedtag->Items[] = $d;
|
||||||
|
}else{
|
||||||
|
$this->namedtag->Items[$i] = $d;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ChestInventory|DoubleChestInventory
|
||||||
|
*/
|
||||||
|
public function getInventory(){
|
||||||
|
return $this->doubleInventory instanceof DoubleChestInventory ? $this->doubleInventory : $this->inventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ChestInventory
|
||||||
|
*/
|
||||||
|
public function getRealInventory(){
|
||||||
|
return $this->inventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function checkPairing(){
|
||||||
|
if(($pair = $this->getPair()) instanceof Chest){
|
||||||
|
if(($pair->x + ($pair->z << 15)) > ($this->x + ($this->z << 15))){ //Order them correctly
|
||||||
|
$this->doubleInventory = new DoubleChestInventory($pair, $this);
|
||||||
|
}else{
|
||||||
|
$this->doubleInventory = new DoubleChestInventory($this, $pair);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$this->doubleInventory = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isPaired(){
|
public function isPaired(){
|
||||||
@ -48,12 +159,18 @@ class Chest extends Spawnable{
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Chest
|
||||||
|
*/
|
||||||
public function getPair(){
|
public function getPair(){
|
||||||
if($this->isPaired()){
|
if($this->isPaired()){
|
||||||
return $this->getLevel()->getTile(new Vector3((int) $this->namedtag->pairx, $this->y, (int) $this->namedtag->pairz));
|
$tile = $this->getLevel()->getTile(new Vector3((int) $this->namedtag->pairx, $this->y, (int) $this->namedtag->pairz));
|
||||||
|
if($tile instanceof Chest){
|
||||||
|
return $tile;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function pairWith(Chest $tile){
|
public function pairWith(Chest $tile){
|
||||||
@ -69,10 +186,11 @@ class Chest extends Spawnable{
|
|||||||
|
|
||||||
$this->spawnToAll();
|
$this->spawnToAll();
|
||||||
$tile->spawnToAll();
|
$tile->spawnToAll();
|
||||||
|
$this->checkPairing();
|
||||||
|
|
||||||
//TODO: Update to new events
|
//TODO: Update to new events
|
||||||
$this->server->handle("tile.update", $this);
|
//$this->server->handle("tile.update", $this);
|
||||||
$this->server->handle("tile.update", $tile);
|
//$this->server->handle("tile.update", $tile);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -86,10 +204,12 @@ class Chest extends Spawnable{
|
|||||||
unset($this->namedtag->pairx, $this->namedtag->pairz, $tile->namedtag->pairx, $tile->namedtag->pairz);
|
unset($this->namedtag->pairx, $this->namedtag->pairz, $tile->namedtag->pairx, $tile->namedtag->pairz);
|
||||||
|
|
||||||
$this->spawnToAll();
|
$this->spawnToAll();
|
||||||
$this->server->handle("tile.update", $this);
|
$this->checkPairing();
|
||||||
|
//TODO: tile update event
|
||||||
|
//$this->server->handle("tile.update", $this);
|
||||||
if($tile instanceof Chest){
|
if($tile instanceof Chest){
|
||||||
$tile->spawnToAll();
|
$tile->spawnToAll();
|
||||||
$this->server->handle("tile.update", $tile);
|
//$this->server->handle("tile.update", $tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -23,178 +23,12 @@ namespace pocketmine\tile;
|
|||||||
|
|
||||||
use pocketmine\event\tile\TileInventoryChangeEvent;
|
use pocketmine\event\tile\TileInventoryChangeEvent;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\nbt\tag\Byte;
|
|
||||||
use pocketmine\nbt\tag\Compound;
|
|
||||||
use pocketmine\nbt\tag\Short;
|
|
||||||
use pocketmine\Network;
|
use pocketmine\Network;
|
||||||
use pocketmine\network\protocol\ContainerOpenPacket;
|
|
||||||
use pocketmine\network\protocol\ContainerSetContentPacket;
|
|
||||||
use pocketmine\network\protocol\TileEventPacket;
|
|
||||||
use pocketmine\Player;
|
|
||||||
use pocketmine\Server;
|
|
||||||
|
|
||||||
trait Container{
|
interface Container{
|
||||||
public function openInventory(Player $player){
|
public function getItem($index);
|
||||||
if($this instanceof 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
$pk = new ContainerOpenPacket();
|
public function setItem($index, Item $item);
|
||||||
$pk->windowid = $id;
|
|
||||||
$pk->type = 0;
|
|
||||||
$pk->slots = is_array($player->windows[$id]) ? Chest::SLOTS << 1 : Chest::SLOTS;
|
|
||||||
$pk->x = $this->x;
|
|
||||||
$pk->y = $this->y;
|
|
||||||
$pk->z = $this->z;
|
|
||||||
$player->dataPacket($pk);
|
|
||||||
$slots = [];
|
|
||||||
|
|
||||||
if(is_array($player->windows[$id])){
|
public function getSize();
|
||||||
$all = $this->getLevel()->getPlayers();
|
|
||||||
foreach($player->windows[$id] as $ob){
|
|
||||||
$pk = new TileEventPacket();
|
|
||||||
$pk->x = $ob->x;
|
|
||||||
$pk->y = $ob->y;
|
|
||||||
$pk->z = $ob->z;
|
|
||||||
$pk->case1 = 1;
|
|
||||||
$pk->case2 = 2;
|
|
||||||
Player::broadcastPacket($all, $pk);
|
|
||||||
for($s = 0; $s < Chest::SLOTS; ++$s){
|
|
||||||
$slot = $ob->getSlot($s);
|
|
||||||
if($slot->getID() > Item::AIR and $slot->getCount() > 0){
|
|
||||||
$slots[] = $slot;
|
|
||||||
}else{
|
|
||||||
$slots[] = Item::get(Item::AIR, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
$pk = new TileEventPacket();
|
|
||||||
$pk->x = $this->x;
|
|
||||||
$pk->y = $this->y;
|
|
||||||
$pk->z = $this->z;
|
|
||||||
$pk->case1 = 1;
|
|
||||||
$pk->case2 = 2;
|
|
||||||
Player::broadcastPacket($this->getLevel()->getPlayers(), $pk);
|
|
||||||
for($s = 0; $s < Chest::SLOTS; ++$s){
|
|
||||||
$slot = $this->getSlot($s);
|
|
||||||
if($slot->getID() > Item::AIR and $slot->getCount() > 0){
|
|
||||||
$slots[] = $slot;
|
|
||||||
}else{
|
|
||||||
$slots[] = Item::get(Item::AIR, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$pk = new ContainerSetContentPacket();
|
|
||||||
$pk->windowid = $id;
|
|
||||||
$pk->slots = $slots;
|
|
||||||
$player->dataPacket($pk);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}elseif($this instanceof Furnace){
|
|
||||||
$player->windowCnt++;
|
|
||||||
$player->windowCnt = $id = max(2, $player->windowCnt % 99);
|
|
||||||
$player->windows[$id] = $this;
|
|
||||||
|
|
||||||
$pk = new ContainerOpenPacket();
|
|
||||||
$pk->windowid = $id;
|
|
||||||
$pk->type = 2;
|
|
||||||
$pk->slots = Furnace::SLOTS;
|
|
||||||
$pk->x = $this->x;
|
|
||||||
$pk->y = $this->y;
|
|
||||||
$pk->z = $this->z;
|
|
||||||
$player->dataPacket($pk);
|
|
||||||
|
|
||||||
$slots = [];
|
|
||||||
for($s = 0; $s < Furnace::SLOTS; ++$s){
|
|
||||||
$slot = $this->getSlot($s);
|
|
||||||
if($slot->getID() > Item::AIR and $slot->getCount() > 0){
|
|
||||||
$slots[] = $slot;
|
|
||||||
}else{
|
|
||||||
$slots[] = Item::get(Item::AIR, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$pk = new ContainerSetContentPacket();
|
|
||||||
$pk->windowid = $id;
|
|
||||||
$pk->slots = $slots;
|
|
||||||
$player->dataPacket($pk);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSlotIndex($s){
|
|
||||||
foreach($this->namedtag->Items as $i => $slot){
|
|
||||||
if($slot["Slot"] === $s){
|
|
||||||
return $i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $s
|
|
||||||
*
|
|
||||||
* @return Item
|
|
||||||
*/
|
|
||||||
public function getSlot($s){
|
|
||||||
$i = $this->getSlotIndex($s);
|
|
||||||
if($i === false or $i < 0){
|
|
||||||
return Item::get(Item::AIR, 0, 0);
|
|
||||||
}else{
|
|
||||||
return Item::get($this->namedtag->Items[$i]["id"], $this->namedtag->Items[$i]["Damage"], $this->namedtag->Items[$i]["Count"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setSlot($s, Item $item, $update = true, $offset = 0){
|
|
||||||
$i = $this->getSlotIndex($s);
|
|
||||||
if($i === false){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Server::getInstance()->getPluginManager()->callEvent($ev = new TileInventoryChangeEvent($this, $this->getSlot($s), $item, $s, $offset));
|
|
||||||
if($ev->isCancelled()){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$item = $ev->getNewItem();
|
|
||||||
$d = new Compound(false, array(
|
|
||||||
new Byte("Count", $item->getCount()),
|
|
||||||
new Byte("Slot", $s),
|
|
||||||
new Short("id", $item->getID()),
|
|
||||||
new Short("Damage", $item->getDamage()),
|
|
||||||
));
|
|
||||||
|
|
||||||
if($item->getID() === Item::AIR or $item->getCount() <= 0){
|
|
||||||
if($i >= 0){
|
|
||||||
unset($this->namedtag->Items[$i]);
|
|
||||||
}
|
|
||||||
}elseif($i < 0){
|
|
||||||
$this->namedtag->Items[] = $d;
|
|
||||||
}else{
|
|
||||||
$this->namedtag->Items[$i] = $d;
|
|
||||||
}
|
|
||||||
|
|
||||||
if($update === true){
|
|
||||||
$this->scheduleUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -22,18 +22,26 @@
|
|||||||
namespace pocketmine\tile;
|
namespace pocketmine\tile;
|
||||||
|
|
||||||
use pocketmine\block\Block;
|
use pocketmine\block\Block;
|
||||||
|
use pocketmine\inventory\FurnaceInventory;
|
||||||
|
use pocketmine\inventory\InventoryHolder;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
|
use pocketmine\nbt\tag\Byte;
|
||||||
use pocketmine\nbt\tag\Compound;
|
use pocketmine\nbt\tag\Compound;
|
||||||
|
use pocketmine\nbt\tag\Short;
|
||||||
|
|
||||||
class Furnace extends Tile{
|
class Furnace extends Tile implements InventoryHolder, Container{
|
||||||
use Container;
|
/** @var FurnaceInventory */
|
||||||
|
protected $inventory;
|
||||||
const SLOTS = 3;
|
|
||||||
|
|
||||||
public function __construct(Level $level, Compound $nbt){
|
public function __construct(Level $level, Compound $nbt){
|
||||||
$nbt["id"] = Tile::FURNACE;
|
$nbt["id"] = Tile::FURNACE;
|
||||||
parent::__construct($level, $nbt);
|
parent::__construct($level, $nbt);
|
||||||
|
$this->inventory = new FurnaceInventory($this);
|
||||||
|
for($i = 0; $i < $this->getSize(); ++$i){
|
||||||
|
$this->inventory->setItem($i, $this->getItem($i));
|
||||||
|
}
|
||||||
|
|
||||||
if(!isset($this->namedtag->BurnTime) or $this->namedtag->BurnTime < 0){
|
if(!isset($this->namedtag->BurnTime) or $this->namedtag->BurnTime < 0){
|
||||||
$this->namedtag->BurnTime = 0;
|
$this->namedtag->BurnTime = 0;
|
||||||
}
|
}
|
||||||
@ -49,6 +57,85 @@ class Furnace extends Tile{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getSize(){
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $index
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
protected function getSlotIndex($index){
|
||||||
|
foreach($this->namedtag->Items as $i => $slot){
|
||||||
|
if($slot["Slot"] === $s){
|
||||||
|
return $i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method should not be used by plugins, use the Inventory
|
||||||
|
*
|
||||||
|
* @param int $index
|
||||||
|
*
|
||||||
|
* @return Item
|
||||||
|
*/
|
||||||
|
public function getItem($index){
|
||||||
|
$i = $this->getSlotIndex($index);
|
||||||
|
if($i < 0){
|
||||||
|
return Item::get(Item::AIR, 0, 0);
|
||||||
|
}else{
|
||||||
|
return Item::get($this->namedtag->Items[$i]["id"], $this->namedtag->Items[$i]["Damage"], $this->namedtag->Items[$i]["Count"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method should not be used by plugins, use the Inventory
|
||||||
|
*
|
||||||
|
* @param int $index
|
||||||
|
* @param Item $item
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function setItem($index, Item $item){
|
||||||
|
$i = $this->getSlotIndex($index);
|
||||||
|
if($i < 0){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$d = new Compound(false, array(
|
||||||
|
new Byte("Count", $item->getCount()),
|
||||||
|
new Byte("Slot", $index),
|
||||||
|
new Short("id", $item->getID()),
|
||||||
|
new Short("Damage", $item->getDamage()),
|
||||||
|
));
|
||||||
|
|
||||||
|
if($item->getID() === Item::AIR or $item->getCount() <= 0){
|
||||||
|
if($i >= 0){
|
||||||
|
unset($this->namedtag->Items[$i]);
|
||||||
|
}
|
||||||
|
}elseif($i < 0){
|
||||||
|
$this->namedtag->Items[] = $d;
|
||||||
|
}else{
|
||||||
|
$this->namedtag->Items[$i] = $d;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return FurnaceInventory
|
||||||
|
*/
|
||||||
|
public function getInventory(){
|
||||||
|
return $this->inventory;
|
||||||
|
}
|
||||||
|
|
||||||
public function onUpdate(){
|
public function onUpdate(){
|
||||||
if($this->closed === true){
|
if($this->closed === true){
|
||||||
return false;
|
return false;
|
||||||
@ -56,9 +143,9 @@ class Furnace extends Tile{
|
|||||||
|
|
||||||
$ret = false;
|
$ret = false;
|
||||||
|
|
||||||
$fuel = $this->getSlot(1);
|
$fuel = $this->inventory->getFuel();
|
||||||
$raw = $this->getSlot(0);
|
$raw = $this->inventory->getSmelting();
|
||||||
$product = $this->getSlot(2);
|
$product = $this->inventory->getResult();
|
||||||
$smelt = $raw->getSmeltItem();
|
$smelt = $raw->getSmeltItem();
|
||||||
$canSmelt = ($smelt !== false and $raw->getCount() > 0 and (($product->getID() === $smelt->getID() and $product->getDamage() === $smelt->getDamage() and $product->getCount() < $product->getMaxStackSize()) or $product->getID() === Item::AIR));
|
$canSmelt = ($smelt !== false and $raw->getCount() > 0 and (($product->getID() === $smelt->getID() and $product->getDamage() === $smelt->getDamage() and $product->getCount() < $product->getMaxStackSize()) or $product->getID() === Item::AIR));
|
||||||
if($this->namedtag->BurnTime <= 0 and $canSmelt and $fuel->getFuelTime() !== false and $fuel->getCount() > 0){
|
if($this->namedtag->BurnTime <= 0 and $canSmelt and $fuel->getFuelTime() !== false and $fuel->getCount() > 0){
|
||||||
@ -69,7 +156,7 @@ class Furnace extends Tile{
|
|||||||
if($fuel->getCount() === 0){
|
if($fuel->getCount() === 0){
|
||||||
$fuel = Item::get(Item::AIR, 0, 0);
|
$fuel = Item::get(Item::AIR, 0, 0);
|
||||||
}
|
}
|
||||||
$this->setSlot(1, $fuel, false);
|
$this->inventory->setFuel($fuel);
|
||||||
$current = $this->getLevel()->getBlock($this);
|
$current = $this->getLevel()->getBlock($this);
|
||||||
if($current->getID() === Item::FURNACE){
|
if($current->getID() === Item::FURNACE){
|
||||||
$this->getLevel()->setBlock($this, Block::get(Item::BURNING_FURNACE, $current->getDamage()), true, false, true);
|
$this->getLevel()->setBlock($this, Block::get(Item::BURNING_FURNACE, $current->getDamage()), true, false, true);
|
||||||
@ -83,12 +170,12 @@ class Furnace extends Tile{
|
|||||||
$this->namedtag->CookTime += $ticks;
|
$this->namedtag->CookTime += $ticks;
|
||||||
if($this->namedtag->CookTime >= 200){ //10 seconds
|
if($this->namedtag->CookTime >= 200){ //10 seconds
|
||||||
$product = Item::get($smelt->getID(), $smelt->getDamage(), $product->getCount() + 1);
|
$product = Item::get($smelt->getID(), $smelt->getDamage(), $product->getCount() + 1);
|
||||||
$this->setSlot(2, $product, false);
|
$this->inventory->setResult($product);
|
||||||
$raw->setCount($raw->getCount() - 1);
|
$raw->setCount($raw->getCount() - 1);
|
||||||
if($raw->getCount() === 0){
|
if($raw->getCount() === 0){
|
||||||
$raw = Item::get(Item::AIR, 0, 0);
|
$raw = Item::get(Item::AIR, 0, 0);
|
||||||
}
|
}
|
||||||
$this->setSlot(0, $raw, false);
|
$this->inventory->setSmelting($raw);
|
||||||
$this->namedtag->CookTime -= 200;
|
$this->namedtag->CookTime -= 200;
|
||||||
}
|
}
|
||||||
}elseif($this->namedtag->BurnTime <= 0){
|
}elseif($this->namedtag->BurnTime <= 0){
|
||||||
@ -109,8 +196,8 @@ class Furnace extends Tile{
|
|||||||
$this->namedtag->BurnTicks = 0;
|
$this->namedtag->BurnTicks = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: tile update event
|
||||||
$this->server->handle("tile.update", $this);
|
//$this->server->handle("tile.update", $this);
|
||||||
$this->lastUpdate = microtime(true);
|
$this->lastUpdate = microtime(true);
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
|
@ -28,7 +28,7 @@ abstract class Spawnable extends Tile{
|
|||||||
|
|
||||||
public function spawnToAll(){
|
public function spawnToAll(){
|
||||||
foreach($this->getLevel()->getPlayers() as $player){
|
foreach($this->getLevel()->getPlayers() as $player){
|
||||||
if($player->eid !== false or $player->spawned !== true){
|
if($player->spawned === true){
|
||||||
$this->spawnTo($player);
|
$this->spawnTo($player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,10 +25,10 @@
|
|||||||
*/
|
*/
|
||||||
namespace pocketmine\tile;
|
namespace pocketmine\tile;
|
||||||
|
|
||||||
|
use pocketmine\level\format\pmf\LevelFormat;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
use pocketmine\level\Position;
|
use pocketmine\level\Position;
|
||||||
use pocketmine\nbt\tag\Compound;
|
use pocketmine\nbt\tag\Compound;
|
||||||
use pocketmine\level\format\pmf\LevelFormat;
|
|
||||||
use pocketmine\Server;
|
use pocketmine\Server;
|
||||||
|
|
||||||
abstract class Tile extends Position{
|
abstract class Tile extends Position{
|
||||||
@ -36,6 +36,8 @@ abstract class Tile extends Position{
|
|||||||
const CHEST = "Chest";
|
const CHEST = "Chest";
|
||||||
const FURNACE = "Furnace";
|
const FURNACE = "Furnace";
|
||||||
|
|
||||||
|
//TODO: pre-close step NBT data saving method
|
||||||
|
|
||||||
public static $tileCount = 1;
|
public static $tileCount = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -89,8 +91,8 @@ abstract class Tile extends Position{
|
|||||||
|
|
||||||
$index = LevelFormat::getIndex($this->x >> 4, $this->z >> 4);
|
$index = LevelFormat::getIndex($this->x >> 4, $this->z >> 4);
|
||||||
$this->chunkIndex = $index;
|
$this->chunkIndex = $index;
|
||||||
$this->level->tiles[$this->id] = $this;
|
$this->getLevel()->tiles[$this->id] = $this;
|
||||||
$this->level->chunkTiles[$this->chunkIndex][$this->id] = $this;
|
$this->getLevel()->chunkTiles[$this->chunkIndex][$this->id] = $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onUpdate(){
|
public function onUpdate(){
|
||||||
@ -105,8 +107,8 @@ abstract class Tile extends Position{
|
|||||||
if($this->closed === false){
|
if($this->closed === false){
|
||||||
$this->closed = true;
|
$this->closed = true;
|
||||||
unset(Tile::$needUpdate[$this->id]);
|
unset(Tile::$needUpdate[$this->id]);
|
||||||
unset($this->level->tiles[$this->id]);
|
unset($this->getLevel()->tiles[$this->id]);
|
||||||
unset($this->level->chunkTiles[$this->chunkIndex][$this->id]);
|
unset($this->getLevel()->chunkTiles[$this->chunkIndex][$this->id]);
|
||||||
unset(Tile::$list[$this->id]);
|
unset(Tile::$list[$this->id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,6 +171,7 @@ class Binary{
|
|||||||
|
|
||||||
return $m;
|
return $m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a byte boolean
|
* Reads a byte boolean
|
||||||
*
|
*
|
||||||
|
@ -262,6 +262,7 @@ class Config{
|
|||||||
$currPath = null;
|
$currPath = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $currPath;
|
return $currPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,6 +69,7 @@ class Random{
|
|||||||
if($t > 2147483647){
|
if($t > 2147483647){
|
||||||
$t -= 4294967296;
|
$t -= 4294967296;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int) $t;
|
return (int) $t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,6 +274,7 @@ class TextFormat{
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $newString;
|
return $newString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,8 +24,6 @@
|
|||||||
*/
|
*/
|
||||||
namespace pocketmine\utils;
|
namespace pocketmine\utils;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Big collection of functions
|
* Big collection of functions
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user