PageRenderTime 50ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/src/pocketmine/tile/Furnace.php

https://gitlab.com/Skull3x/ClearSky
PHP | 287 lines | 216 code | 44 blank | 27 comment | 29 complexity | db006902a37bfaa774665880b79d0578 MD5 | raw file
  1. <?php
  2. namespace pocketmine\tile;
  3. use pocketmine\block\Block;
  4. use pocketmine\event\inventory\FurnaceBurnEvent;
  5. use pocketmine\event\inventory\FurnaceSmeltEvent;
  6. use pocketmine\inventory\FurnaceInventory;
  7. use pocketmine\inventory\FurnaceRecipe;
  8. use pocketmine\inventory\InventoryHolder;
  9. use pocketmine\item\Item;
  10. use pocketmine\level\format\FullChunk;
  11. use pocketmine\nbt\NBT;
  12. use pocketmine\nbt\tag\Compound;
  13. use pocketmine\nbt\tag\Enum;
  14. use pocketmine\nbt\tag\Short;
  15. use pocketmine\nbt\tag\String;
  16. use pocketmine\nbt\tag\Int;
  17. use pocketmine\network\Network;
  18. use pocketmine\network\protocol\ContainerSetDataPacket;
  19. class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{
  20. /** @var FurnaceInventory */
  21. protected $inventory;
  22. public function __construct(FullChunk $chunk, Compound $nbt){
  23. parent::__construct($chunk, $nbt);
  24. $this->inventory = new FurnaceInventory($this);
  25. if(!isset($this->namedtag->Items) or !($this->namedtag->Items instanceof Enum)){
  26. $this->namedtag->Items = new Enum("Items", []);
  27. $this->namedtag->Items->setTagType(NBT::TAG_Compound);
  28. }
  29. for($i = 0; $i < $this->getSize(); ++$i){
  30. $this->inventory->setItem($i, $this->getItem($i));
  31. }
  32. if(!isset($this->namedtag->BurnTime) or $this->namedtag["BurnTime"] < 0){
  33. $this->namedtag->BurnTime = new Short("BurnTime", 0);
  34. }
  35. if(!isset($this->namedtag->CookTime) or $this->namedtag["CookTime"] < 0 or ($this->namedtag["BurnTime"] === 0 and $this->namedtag["CookTime"] > 0)){
  36. $this->namedtag->CookTime = new Short("CookTime", 0);
  37. }
  38. if(!isset($this->namedtag->MaxTime)){
  39. $this->namedtag->MaxTime = new Short("BurnTime", $this->namedtag["BurnTime"]);
  40. $this->namedtag->BurnTicks = new Short("BurnTicks", 0);
  41. }
  42. if($this->namedtag["BurnTime"] > 0){
  43. $this->scheduleUpdate();
  44. }
  45. }
  46. public function getName(){
  47. return isset($this->namedtag->CustomName) ? $this->namedtag->CustomName->getValue() : "Furnace";
  48. }
  49. public function hasName(){
  50. return isset($this->namedtag->CustomName);
  51. }
  52. public function setName($str){
  53. if($str === ""){
  54. unset($this->namedtag->CustomName);
  55. return;
  56. }
  57. $this->namedtag->CustomName = new String("CustomName", $str);
  58. }
  59. public function close(){
  60. if($this->closed === false){
  61. foreach($this->getInventory()->getViewers() as $player){
  62. $player->removeWindow($this->getInventory());
  63. }
  64. parent::close();
  65. }
  66. }
  67. public function saveNBT(){
  68. $this->namedtag->Items = new Enum("Items", []);
  69. $this->namedtag->Items->setTagType(NBT::TAG_Compound);
  70. for($index = 0; $index < $this->getSize(); ++$index){
  71. $this->setItem($index, $this->inventory->getItem($index));
  72. }
  73. }
  74. /**
  75. * @return int
  76. */
  77. public function getSize(){
  78. return 3;
  79. }
  80. /**
  81. * @param $index
  82. *
  83. * @return int
  84. */
  85. protected function getSlotIndex($index){
  86. foreach($this->namedtag->Items as $i => $slot){
  87. if($slot["Slot"] === $index){
  88. return $i;
  89. }
  90. }
  91. return -1;
  92. }
  93. /**
  94. * This method should not be used by plugins, use the Inventory
  95. *
  96. * @param int $index
  97. *
  98. * @return Item
  99. */
  100. public function getItem($index){
  101. $i = $this->getSlotIndex($index);
  102. if($i < 0){
  103. return Item::get(Item::AIR, 0, 0);
  104. }else{
  105. return NBT::getItemHelper($this->namedtag->Items[$i]);
  106. }
  107. }
  108. /**
  109. * This method should not be used by plugins, use the Inventory
  110. *
  111. * @param int $index
  112. * @param Item $item
  113. *
  114. * @return bool
  115. */
  116. public function setItem($index, Item $item){
  117. $i = $this->getSlotIndex($index);
  118. $d = NBT::putItemHelper($item, $index);
  119. if($item->getId() === Item::AIR or $item->getCount() <= 0){
  120. if($i >= 0){
  121. unset($this->namedtag->Items[$i]);
  122. }
  123. }elseif($i < 0){
  124. for($i = 0; $i <= $this->getSize(); ++$i){
  125. if(!isset($this->namedtag->Items[$i])){
  126. break;
  127. }
  128. }
  129. $this->namedtag->Items[$i] = $d;
  130. }else{
  131. $this->namedtag->Items[$i] = $d;
  132. }
  133. return true;
  134. }
  135. /**
  136. * @return FurnaceInventory
  137. */
  138. public function getInventory(){
  139. return $this->inventory;
  140. }
  141. protected function checkFuel(Item $fuel){
  142. $this->server->getPluginManager()->callEvent($ev = new FurnaceBurnEvent($this, $fuel, $fuel->getFuelTime()));
  143. if($ev->isCancelled()){
  144. return;
  145. }
  146. $this->namedtag->MaxTime = new Short("MaxTime", $ev->getBurnTime());
  147. $this->namedtag->BurnTime = new Short("BurnTime", $ev->getBurnTime());
  148. $this->namedtag->BurnTicks = new Short("BurnTicks", 0);
  149. if($this->getBlock()->getId() === Item::FURNACE){
  150. $this->getLevel()->setBlock($this, Block::get(Item::BURNING_FURNACE, $this->getBlock()->getDamage()), true);
  151. }
  152. if($this->namedtag["BurnTime"] > 0 and $ev->isBurning()){
  153. $fuel->setCount($fuel->getCount() - 1);
  154. if($fuel->getCount() === 0){
  155. $fuel = Item::get(Item::AIR, 0, 0);
  156. }
  157. $this->inventory->setFuel($fuel);
  158. }
  159. }
  160. public function onUpdate(){
  161. if($this->closed === true){
  162. return false;
  163. }
  164. $this->timings->startTiming();
  165. $ret = false;
  166. $fuel = $this->inventory->getFuel();
  167. $raw = $this->inventory->getSmelting();
  168. $product = $this->inventory->getResult();
  169. $smelt = $this->server->getCraftingManager()->matchFurnaceRecipe($raw);
  170. $canSmelt = ($smelt instanceof FurnaceRecipe and $raw->getCount() > 0 and (($smelt->getResult()->equals($product) and $product->getCount() < $product->getMaxStackSize()) or $product->getId() === Item::AIR));
  171. if($this->namedtag["BurnTime"] <= 0 and $canSmelt and $fuel->getFuelTime() !== null and $fuel->getCount() > 0){
  172. $this->checkFuel($fuel);
  173. }
  174. if($this->namedtag["BurnTime"] > 0){
  175. $this->namedtag->BurnTime = new Short("BurnTime", $this->namedtag["BurnTime"] - 1);
  176. $this->namedtag->BurnTicks = new Short("BurnTicks", ceil(($this->namedtag["BurnTime"] / $this->namedtag["MaxTime"] * 200)));
  177. if($smelt instanceof FurnaceRecipe and $canSmelt){
  178. $this->namedtag->CookTime = new Short("CookTime", $this->namedtag["CookTime"] + 1);
  179. if($this->namedtag["CookTime"] >= 200){ //10 seconds
  180. $product = Item::get($smelt->getResult()->getId(), $smelt->getResult()->getDamage(), $product->getCount() + 1);
  181. $this->server->getPluginManager()->callEvent($ev = new FurnaceSmeltEvent($this, $raw, $product));
  182. if(!$ev->isCancelled()){
  183. $this->inventory->setResult($ev->getResult());
  184. $raw->setCount($raw->getCount() - 1);
  185. if($raw->getCount() === 0){
  186. $raw = Item::get(Item::AIR, 0, 0);
  187. }
  188. $this->inventory->setSmelting($raw);
  189. }
  190. $this->namedtag->CookTime = new Short("CookTime", $this->namedtag["CookTime"] - 200);
  191. }
  192. }elseif($this->namedtag["BurnTime"] <= 0){
  193. $this->namedtag->BurnTime = new Short("BurnTime", 0);
  194. $this->namedtag->CookTime = new Short("CookTime", 0);
  195. $this->namedtag->BurnTicks = new Short("BurnTicks", 0);
  196. }else{
  197. $this->namedtag->CookTime = new Short("CookTime", 0);
  198. }
  199. $ret = true;
  200. }else{
  201. ;
  202. if($this->getBlock()->getId() === Item::BURNING_FURNACE){
  203. $this->getLevel()->setBlock($this, Block::get(Item::FURNACE, $this->getBlock()->getDamage()), true);
  204. }
  205. $this->namedtag->BurnTime = new Short("BurnTime", 0);
  206. $this->namedtag->CookTime = new Short("CookTime", 0);
  207. $this->namedtag->BurnTicks = new Short("BurnTicks", 0);
  208. }
  209. foreach($this->getInventory()->getViewers() as $player){
  210. $windowId = $player->getWindowId($this->getInventory());
  211. if($windowId > 0){
  212. $pk = new ContainerSetDataPacket();
  213. $pk->windowid = $windowId;
  214. $pk->property = 0; //Smelting
  215. $pk->value = floor($this->namedtag["CookTime"]);
  216. $player->dataPacket($pk);
  217. $pk = new ContainerSetDataPacket();
  218. $pk->windowid = $windowId;
  219. $pk->property = 1; //Fire icon
  220. $pk->value = $this->namedtag["BurnTicks"];
  221. $player->dataPacket($pk);
  222. }
  223. }
  224. $this->lastUpdate = microtime(true);
  225. $this->timings->stopTiming();
  226. return $ret;
  227. }
  228. public function getSpawnCompound(){
  229. $nbt = new Compound("", [
  230. new String("id", Tile::FURNACE),
  231. new Int("x", (int) $this->x),
  232. new Int("y", (int) $this->y),
  233. new Int("z", (int) $this->z),
  234. new Short("BurnTime", $this->namedtag["BurnTime"]),
  235. new Short("CookTime", $this->namedtag["CookTime"]),
  236. new Short("BurnDuration", $this->namedtag["BurnTicks"])
  237. ]);
  238. if($this->hasName()){
  239. $nbt->CustomName = $this->namedtag->CustomName;
  240. }
  241. return $nbt;
  242. }
  243. }