PocketMine-MP  1.4 - API 1.10.0
 All Classes Namespaces Functions Variables Pages
tile/Chest.php
1 <?php
2 
3 /*
4  *
5  * ____ _ _ __ __ _ __ __ ____
6  * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
7  * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
8  * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
9  * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
10  *
11  * This program is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * @author PocketMine Team
17  * @link http://www.pocketmine.net/
18  *
19  *
20 */
21 
22 namespace pocketmine\tile;
23 
37 
38 class Chest extends Spawnable implements InventoryHolder, Container{
39 
41  protected $inventory;
43  protected $doubleInventory = null;
44 
45  public function __construct(FullChunk $chunk, Compound $nbt){
46  parent::__construct($chunk, $nbt);
47  $this->inventory = new ChestInventory($this);
48 
49  if(!isset($this->namedtag->Items) or !($this->namedtag->Items instanceof Enum)){
50  $this->namedtag->Items = new Enum("Inventory", []);
51  $this->namedtag->Items->setTagType(NBT::TAG_Compound);
52  }
53 
54  for($i = 0; $i < $this->getSize(); ++$i){
55  $this->inventory->setItem($i, $this->getItem($i));
56  }
57  }
58 
59  public function close(){
60  if($this->closed === false){
61  foreach($this->getInventory()->getViewers() as $player){
62  $player->removeWindow($this->getInventory());
63  }
64 
65  foreach($this->getInventory()->getViewers() as $player){
66  $player->removeWindow($this->getRealInventory());
67  }
68  parent::close();
69  }
70  }
71 
72  public function saveNBT(){
73  $this->namedtag->Items = new Enum("Items", []);
74  $this->namedtag->Items->setTagType(NBT::TAG_Compound);
75  for($index = 0; $index < $this->getSize(); ++$index){
76  $this->setItem($index, $this->inventory->getItem($index));
77  }
78  }
79 
83  public function getSize(){
84  return 27;
85  }
86 
92  protected function getSlotIndex($index){
93  foreach($this->namedtag->Items as $i => $slot){
94  if($slot["Slot"] === $index){
95  return $i;
96  }
97  }
98 
99  return -1;
100  }
101 
109  public function getItem($index){
110  $i = $this->getSlotIndex($index);
111  if($i < 0){
112  return Item::get(Item::AIR, 0, 0);
113  }else{
114  return Item::get($this->namedtag->Items[$i]["id"], $this->namedtag->Items[$i]["Damage"], $this->namedtag->Items[$i]["Count"]);
115  }
116  }
117 
126  public function setItem($index, Item $item){
127  $i = $this->getSlotIndex($index);
128 
129  $d = new Compound(false, [
130  new Byte("Count", $item->getCount()),
131  new Byte("Slot", $index),
132  new Short("id", $item->getId()),
133  new Short("Damage", $item->getDamage()),
134  ]);
135 
136  if($item->getId() === Item::AIR or $item->getCount() <= 0){
137  if($i >= 0){
138  unset($this->namedtag->Items[$i]);
139  }
140  }elseif($i < 0){
141  for($i = 0; $i <= $this->getSize(); ++$i){
142  if(!isset($this->namedtag->Items[$i])){
143  break;
144  }
145  }
146  $this->namedtag->Items[$i] = $d;
147  }else{
148  $this->namedtag->Items[$i] = $d;
149  }
150 
151  return true;
152  }
153 
157  public function getInventory(){
158  if($this->isPaired() and $this->doubleInventory === null){
159  $this->checkPairing();
160  }
161  return $this->doubleInventory instanceof DoubleChestInventory ? $this->doubleInventory : $this->inventory;
162  }
163 
167  public function getRealInventory(){
168  return $this->inventory;
169  }
170 
171  protected function checkPairing(){
172  if(($pair = $this->getPair()) instanceof Chest){
173  if(!$pair->isPaired()){
174  $pair->createPair($this);
175  $pair->checkPairing();
176  }
177  if($this->doubleInventory === null){
178  if(($pair->x + ($pair->z << 15)) > ($this->x + ($this->z << 15))){ //Order them correctly
179  $this->doubleInventory = new DoubleChestInventory($pair, $this);
180  }else{
181  $this->doubleInventory = new DoubleChestInventory($this, $pair);
182  }
183  }
184  }else{
185  $this->doubleInventory = null;
186  unset($this->namedtag->pairx, $this->namedtag->pairz);
187  }
188  }
189 
190  public function isPaired(){
191  if(!isset($this->namedtag->pairx) or !isset($this->namedtag->pairz)){
192  return false;
193  }
194 
195  return true;
196  }
197 
201  public function getPair(){
202  if($this->isPaired()){
203  $tile = $this->getLevel()->getTile(new Vector3((int) $this->namedtag["pairx"], $this->y, (int) $this->namedtag["pairz"]));
204  if($tile instanceof Chest){
205  return $tile;
206  }
207  }
208 
209  return null;
210  }
211 
212  public function pairWith(Chest $tile){
213  if($this->isPaired() or $tile->isPaired()){
214  return false;
215  }
216 
217  $this->createPair($tile);
218 
219  $this->spawnToAll();
220  $tile->spawnToAll();
221  $this->checkPairing();
222 
223  return true;
224  }
225 
226  private function createPair(Chest $tile){
227  $this->namedtag->pairx = new Int("pairx", $tile->x);
228  $this->namedtag->pairz = new Int("pairz", $tile->z);
229 
230  $tile->namedtag->pairx = new Int("pairx", $this->x);
231  $tile->namedtag->pairz = new Int("pairz", $this->z);
232  }
233 
234  public function unpair(){
235  if(!$this->isPaired()){
236  return false;
237  }
238 
239  $tile = $this->getPair();
240  unset($this->namedtag->pairx, $this->namedtag->pairz);
241 
242  $this->spawnToAll();
243 
244  if($tile instanceof Chest){
245  unset($tile->namedtag->pairx, $tile->namedtag->pairz);
246  $tile->checkPairing();
247  $tile->spawnToAll();
248  }
249  $this->checkPairing();
250 
251  return true;
252  }
253 
254  public function getSpawnCompound(){
255  if($this->isPaired()){
256  return new Compound("", [
257  new String("id", Tile::CHEST),
258  new Int("x", (int) $this->x),
259  new Int("y", (int) $this->y),
260  new Int("z", (int) $this->z),
261  new Int("pairx", (int) $this->namedtag["pairx"]),
262  new Int("pairz", (int) $this->namedtag["pairz"])
263  ]);
264  }else{
265  return new Compound("", [
266  new String("id", Tile::CHEST),
267  new Int("x", (int) $this->x),
268  new Int("y", (int) $this->y),
269  new Int("z", (int) $this->z)
270  ]);
271  }
272  }
273 }
setItem($index, Item $item)
Definition: tile/Chest.php:126