mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-18 11:45:30 +00:00
Added CraftItemEvent, Crafting system now uses Transactions
This commit is contained in:
parent
3fc1be1262
commit
6746987ce5
@ -2009,10 +2009,6 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
break;
|
||||
}
|
||||
|
||||
if($this->currentTransaction === null or $this->currentTransaction->getCreationTime() > (microtime(true) - 1)){
|
||||
$this->currentTransaction = new SimpleTransactionGroup();
|
||||
}
|
||||
|
||||
if($packet->slot < 0){
|
||||
break;
|
||||
}
|
||||
@ -2029,9 +2025,28 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
break;
|
||||
}
|
||||
|
||||
if($transaction->getSourceItem()->equals($transaction->getTargetItem(), true) and $transaction->getTargetItem()->getCount() === $transaction->getSourceItem()->getCount()){ //No changes!
|
||||
//No changes, just a local inventory update sent by the server
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if($this->currentTransaction === null or $this->currentTransaction->getCreationTime() < (microtime(true) - 0.5)){
|
||||
if($this->currentTransaction instanceof SimpleTransactionGroup){
|
||||
foreach($this->currentTransaction->getInventories() as $inventory){
|
||||
$inventory->sendContents($inventory->getViewers());
|
||||
}
|
||||
}
|
||||
$this->currentTransaction = new SimpleTransactionGroup();
|
||||
}
|
||||
|
||||
$this->currentTransaction->addTransaction($transaction);
|
||||
|
||||
if($this->currentTransaction->canExecute()){
|
||||
if(!$this->currentTransaction->execute()){
|
||||
$this->currentTransaction = null;
|
||||
break;
|
||||
}
|
||||
foreach($this->currentTransaction->getTransactions() as $ts){
|
||||
$inv = $ts->getInventory();
|
||||
if($inv instanceof FurnaceInventory){
|
||||
@ -2043,19 +2058,13 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->currentTransaction = null;
|
||||
}
|
||||
}elseif($packet->windowid == 0){ //Try crafting
|
||||
$craftingGroup = new CraftingTransactionGroup($this->currentTransaction);
|
||||
if($craftingGroup->canExecute()){ //We can craft!
|
||||
//TODO: CraftItemEvent
|
||||
//$this->server->getPluginManager($ev = new CraftItemEvent($this, $recipe, $craft, $type));
|
||||
//if($ev->isCancelled()){
|
||||
// return false;
|
||||
//}
|
||||
|
||||
/*switch($item->getID()){
|
||||
if($craftingGroup->canExecute() and $craftingGroup->execute()){ //We can craft!
|
||||
switch($craftingGroup->getResult()->getID()){
|
||||
case Item::WORKBENCH:
|
||||
$this->awardAchievement("buildWorkBench");
|
||||
break;
|
||||
@ -2072,6 +2081,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$this->awardAchievement("makeBread");
|
||||
break;
|
||||
case Item::CAKE:
|
||||
//TODO: detect complex recipes like cake that leave remainings
|
||||
$this->awardAchievement("bakeCake");
|
||||
$this->inventory->addItem(Item::get(Item::BUCKET, 0, 3));
|
||||
break;
|
||||
@ -2087,15 +2097,17 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
case Item::DIAMOND:
|
||||
$this->awardAchievement("diamond");
|
||||
break;
|
||||
}*/
|
||||
|
||||
$craftingGroup->execute();
|
||||
}
|
||||
|
||||
|
||||
|
||||
$this->currentTransaction = null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
break;
|
||||
case ProtocolInfo::SEND_INVENTORY_PACKET: //TODO, Mojang, enable this ´^_^`
|
||||
@ -2322,7 +2334,6 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
return $this->windows[$inventory];
|
||||
}
|
||||
|
||||
if($forceId === 0 or $inventory->open($this)){
|
||||
if($forceId === null){
|
||||
$this->windowCnt = $cnt = max(2, ++$this->windowCnt % 99);
|
||||
}else{
|
||||
@ -2330,20 +2341,20 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
}
|
||||
$this->windowIndex[$cnt] = $inventory;
|
||||
$this->windows->attach($inventory, $cnt);
|
||||
if($inventory->open($this)){
|
||||
return $cnt;
|
||||
}else{
|
||||
$this->removeWindow($inventory);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function removeWindow(Inventory $inventory){
|
||||
$inventory->close($this);
|
||||
if($this->windows->contains($inventory)){
|
||||
$id = $this->windows[$inventory];
|
||||
$this->windows->detach($this->windowIndex[$id]);
|
||||
unset($this->windowIndex[$id]);
|
||||
$this->windows->detach($this->windows[$inventory]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,9 @@ use pocketmine\event\HandlerList;
|
||||
use pocketmine\event\server\PacketReceiveEvent;
|
||||
use pocketmine\event\server\PacketSendEvent;
|
||||
use pocketmine\event\server\ServerCommandEvent;
|
||||
use pocketmine\inventory\CraftingManager;
|
||||
use pocketmine\inventory\InventoryType;
|
||||
use pocketmine\inventory\Recipe;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\format\pmf\LevelFormat;
|
||||
use pocketmine\level\generator\Flat;
|
||||
@ -127,6 +129,9 @@ class Server{
|
||||
/** @var SimpleCommandMap */
|
||||
private $commandMap = null;
|
||||
|
||||
/** @var CraftingManager */
|
||||
private $craftingManager;
|
||||
|
||||
/** @var ConsoleCommandSender */
|
||||
private $consoleSender;
|
||||
|
||||
@ -468,6 +473,13 @@ class Server{
|
||||
return $this->pluginManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CraftingManager
|
||||
*/
|
||||
public function getCraftingManager(){
|
||||
return $this->craftingManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ServerScheduler
|
||||
*/
|
||||
@ -512,6 +524,10 @@ class Server{
|
||||
return $this->players;
|
||||
}
|
||||
|
||||
public function addRecipe(Recipe $recipe){
|
||||
$this->craftingManager->registerRecipe($recipe);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
@ -1267,6 +1283,13 @@ class Server{
|
||||
|
||||
$this->consoleSender = new ConsoleCommandSender();
|
||||
$this->commandMap = new SimpleCommandMap($this);
|
||||
|
||||
InventoryType::init();
|
||||
Block::init();
|
||||
Item::init();
|
||||
Crafting::init();
|
||||
$this->craftingManager = new CraftingManager();
|
||||
|
||||
$this->pluginManager = new PluginManager($this, $this->commandMap);
|
||||
$this->pluginManager->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this->consoleSender);
|
||||
$this->pluginManager->registerInterface("pocketmine\\plugin\\PharPluginLoader");
|
||||
@ -1276,10 +1299,7 @@ class Server{
|
||||
|
||||
$this->enablePlugins(PluginLoadOrder::STARTUP);
|
||||
|
||||
InventoryType::init();
|
||||
Block::init();
|
||||
Item::init();
|
||||
Crafting::init();
|
||||
|
||||
|
||||
Generator::addGenerator("pocketmine\\level\\generator\\Flat", "flat");
|
||||
Generator::addGenerator("pocketmine\\level\\generator\\Normal", "normal");
|
||||
|
@ -23,15 +23,24 @@ namespace pocketmine\block;
|
||||
|
||||
|
||||
class Planks extends Solid{
|
||||
const OAK = 0;
|
||||
const SPRUCE = 1;
|
||||
const BIRCH = 2;
|
||||
const JUNGLE = 3;
|
||||
const ACACIA = 4;
|
||||
const DARK_OAK = 5;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::PLANKS, $meta, "Wooden Planks");
|
||||
parent::__construct(self::PLANKS, $meta, "Wood Planks");
|
||||
$names = array(
|
||||
Wood::OAK => "Oak Wooden Planks",
|
||||
Wood::SPRUCE => "Spruce Wooden Planks",
|
||||
Wood::BIRCH => "Birch Wooden Planks",
|
||||
Wood::JUNGLE => "Jungle Wooden Planks",
|
||||
self::OAK => "Oak Wood Planks",
|
||||
self::SPRUCE => "Spruce Wood Planks",
|
||||
self::BIRCH => "Birch Wood Planks",
|
||||
self::JUNGLE => "Jungle Wood Planks",
|
||||
self::ACACIA => "Acacia Wood Planks",
|
||||
self::DARK_OAK => "Jungle Wood Planks",
|
||||
);
|
||||
$this->name = $names[$this->meta & 0x03];
|
||||
$this->name = $names[$this->meta & 0x07];
|
||||
$this->hardness = 15;
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,8 @@ class Wood extends Solid{
|
||||
const SPRUCE = 1;
|
||||
const BIRCH = 2;
|
||||
const JUNGLE = 3;
|
||||
const ACACIA = 4;
|
||||
const DARK_OAK = 5;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::WOOD, $meta, "Wood");
|
||||
|
60
src/pocketmine/event/inventory/CraftItemEvent.php
Normal file
60
src/pocketmine/event/inventory/CraftItemEvent.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?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\inventory;
|
||||
use pocketmine\event\Cancellable;
|
||||
use pocketmine\event\Event;
|
||||
use pocketmine\inventory\Inventory;
|
||||
use pocketmine\inventory\CraftingTransactionGroup;
|
||||
use pocketmine\inventory\Recipe;
|
||||
use pocketmine\Player;
|
||||
|
||||
class CraftItemEvent extends Event implements Cancellable{
|
||||
public static $handlerList = null;
|
||||
|
||||
/** @var CraftingTransactionGroup */
|
||||
private $ts;
|
||||
/** @var Recipe */
|
||||
private $recipe;
|
||||
|
||||
/**
|
||||
* @param CraftingTransactionGroup $ts
|
||||
*/
|
||||
public function __construct(CraftingTransactionGroup $ts, Recipe $recipe){
|
||||
$this->ts = $ts;
|
||||
$this->recipe = $recipe;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CraftingTransactionGroup
|
||||
*/
|
||||
public function getTransaction(){
|
||||
return $this->ts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Recipe
|
||||
*/
|
||||
public function getRecipe(){
|
||||
return $this->recipe;
|
||||
}
|
||||
|
||||
}
|
@ -390,7 +390,11 @@ abstract class BaseInventory implements Inventory{
|
||||
}
|
||||
|
||||
foreach($target as $player){
|
||||
$pk->windowid = $player->getWindowId($this);
|
||||
if(($id = $player->getWindowId($this)) === -1){
|
||||
$this->close($player);
|
||||
continue;
|
||||
}
|
||||
$pk->windowid = $id;
|
||||
$player->dataPacket(clone $pk);
|
||||
}
|
||||
}
|
||||
@ -409,7 +413,11 @@ abstract class BaseInventory implements Inventory{
|
||||
$pk->item = clone $this->getItem($index);
|
||||
|
||||
foreach($target as $player){
|
||||
$pk->windowid = $player->getWindowId($this);
|
||||
if(($id = $player->getWindowId($this)) === -1){
|
||||
$this->close($player);
|
||||
continue;
|
||||
}
|
||||
$pk->windowid = $id;
|
||||
$player->dataPacket(clone $pk);
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ abstract class ContainerInventory extends BaseInventory{
|
||||
}
|
||||
|
||||
$who->dataPacket($pk);
|
||||
|
||||
$this->sendContents($who);
|
||||
}
|
||||
|
||||
public function onClose(Player $who){
|
||||
|
@ -21,19 +21,55 @@
|
||||
|
||||
namespace pocketmine\inventory;
|
||||
|
||||
use pocketmine\block\Planks;
|
||||
use pocketmine\block\Wood;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class CraftingManager{
|
||||
|
||||
/** @var Recipe[] */
|
||||
public $recipes = [];
|
||||
|
||||
/** @var Recipe[][] */
|
||||
protected $recipeLookup = [];
|
||||
|
||||
/** @var FurnaceRecipe[] */
|
||||
public $furnaceRecipes = [];
|
||||
|
||||
public function __construct(){
|
||||
//TODO: add crafting recipes
|
||||
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOODEN_PLANK, Planks::OAK, 4)))->addIngredient(Item::get(Item::WOOD, Wood::OAK, 1)));
|
||||
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOODEN_PLANK, Planks::SPRUCE, 4)))->addIngredient(Item::get(Item::WOOD, Wood::SPRUCE, 1)));
|
||||
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOODEN_PLANK, Planks::BIRCH, 4)))->addIngredient(Item::get(Item::WOOD, Wood::BIRCH, 1)));
|
||||
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOODEN_PLANK, Planks::JUNGLE, 4)))->addIngredient(Item::get(Item::WOOD, Wood::JUNGLE, 1)));
|
||||
//$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOODEN_PLANK, Planks::ACACIA, 4)))->addIngredient(Item::get(Item::WOOD2, Wood2::ACACIA, 1)));
|
||||
//$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOODEN_PLANK, Planks::DARK_OAK, 4)))->addIngredient(Item::get(Item::WOOD2, Wood2::DARK_OAK, 1)));
|
||||
}
|
||||
|
||||
public function sort(){
|
||||
//TODO: recipe sort
|
||||
public function sort(Item $i1, Item $i2){
|
||||
if($i1->getID() > $i2->getID()){
|
||||
return 1;
|
||||
}elseif($i1->getID() < $i2->getID()){
|
||||
return -1;
|
||||
}elseif($i1->getDamage() > $i2->getDamage()){
|
||||
return 1;
|
||||
}elseif($i1->getDamage() < $i2->getDamage()){
|
||||
return -1;
|
||||
}elseif($i1->getCount() > $i2->getCount()){
|
||||
return 1;
|
||||
}elseif($i1->getCount() < $i2->getCount()){
|
||||
return -1;
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Recipe[]
|
||||
*/
|
||||
public function getRecipes(){
|
||||
return $this->recipes;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,7 +83,15 @@ class CraftingManager{
|
||||
* @param ShapelessRecipe $recipe
|
||||
*/
|
||||
public function registerShapelessRecipe(ShapelessRecipe $recipe){
|
||||
|
||||
$result = $recipe->getResult();
|
||||
$this->recipes[spl_object_hash($recipe)] = $recipe;
|
||||
$hash = "";
|
||||
$ingredients = $recipe->getIngredientList();
|
||||
usort($ingredients, array($this, "sort"));
|
||||
foreach($ingredients as $item){
|
||||
$hash .= $item->getID().":".($item->getDamage() === null ? "?":$item->getDamage())."x".$item->getCount().",";
|
||||
}
|
||||
$this->recipeLookup[$result->getID().":".$result->getDamage()][$hash] = $recipe;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,6 +101,38 @@ class CraftingManager{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CraftingTransactionGroup $ts
|
||||
*
|
||||
* @return Recipe
|
||||
*/
|
||||
public function matchTransaction(CraftingTransactionGroup $ts){
|
||||
$result = $ts->getResult();
|
||||
|
||||
if(!($result instanceof Item)){
|
||||
return false;
|
||||
}
|
||||
$k = $result->getID().":".$result->getDamage();
|
||||
|
||||
if(!isset($this->recipeLookup[$k])){
|
||||
return false;
|
||||
}
|
||||
$hash = "";
|
||||
$input = $ts->getRecipe();
|
||||
usort($input, array($this, "sort"));
|
||||
foreach($input as $item){
|
||||
$hash .= $item->getID().":".($item->getDamage() === null ? "?":$item->getDamage())."x".$item->getCount().",";
|
||||
}
|
||||
if(!isset($this->recipeLookup[$k][$hash])){
|
||||
return false;
|
||||
}
|
||||
$checkResult = $this->recipeLookup[$k][$hash]->getResult();
|
||||
if($checkResult->equals($result, true) and $checkResult->getCount() === $result->getCount()){
|
||||
return $this->recipeLookup[$k][$hash];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Recipe $recipe
|
||||
*/
|
||||
|
@ -21,16 +21,88 @@
|
||||
|
||||
namespace pocketmine\inventory;
|
||||
|
||||
class CraftingTransactionGroup extends SimpleTransactionGroup{
|
||||
use pocketmine\event\inventory\CraftItemEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\Server;
|
||||
|
||||
class CraftingTransactionGroup extends SimpleTransactionGroup{
|
||||
/** @var Item[] */
|
||||
protected $input = [];
|
||||
/** @var Item[] */
|
||||
protected $output = [];
|
||||
public function __construct(TransactionGroup $group){
|
||||
parent::__construct();
|
||||
$this->transactions = $group->getTransactions();
|
||||
$this->inventories = $group->getInventories();
|
||||
|
||||
$this->matchItems($this->output, $this->input);
|
||||
/*$input = "";
|
||||
$output = "";
|
||||
foreach($this->input as $item){
|
||||
$input .= $item->getID().":".$item->getDamage()."(".$item->getCount()."), ";
|
||||
}
|
||||
foreach($this->output as $item){
|
||||
$output .= $item->getID().":".$item->getDamage()."(".$item->getCount()."), ";
|
||||
}
|
||||
console("craft_tx#".spl_object_hash($this).": ".substr($input, 0, -2)." => ".substr($output, 0, -2));*/
|
||||
}
|
||||
|
||||
public function addTransaction(Transaction $transaction){
|
||||
parent::addTransaction($transaction);
|
||||
$this->input = [];
|
||||
$this->output = [];
|
||||
$this->matchItems($this->output, $this->input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Items that have been used
|
||||
*
|
||||
* @return Item[]
|
||||
*/
|
||||
public function getRecipe(){
|
||||
return $this->input;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Item
|
||||
*/
|
||||
public function getResult(){
|
||||
reset($this->output);
|
||||
return current($this->output);
|
||||
}
|
||||
|
||||
public function canExecute(){
|
||||
//TODO: search in crafting recipes
|
||||
if(count($this->output) !== 1 or count($this->input) === 0){
|
||||
return false;
|
||||
}
|
||||
return $this->getMatchingRecipe() instanceof Recipe;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Recipe
|
||||
*/
|
||||
public function getMatchingRecipe(){
|
||||
return Server::getInstance()->getCraftingManager()->matchTransaction($this);
|
||||
}
|
||||
|
||||
public function execute(){
|
||||
if($this->hasExecuted() or !$this->canExecute()){
|
||||
return false;
|
||||
}
|
||||
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new CraftItemEvent($this, $this->getMatchingRecipe()));
|
||||
if($ev->isCancelled()){
|
||||
foreach($this->inventories as $inventory){
|
||||
$inventory->sendContents($inventory->getViewers());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach($this->transactions as $transaction){
|
||||
$transaction->getInventory()->setItem($transaction->getSlot(), $transaction->getTargetItem());
|
||||
}
|
||||
$this->hasExecuted = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
namespace pocketmine\inventory;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\Server;
|
||||
|
||||
class FurnaceRecipe implements Recipe{
|
||||
/** @var Item */
|
||||
@ -60,55 +61,7 @@ class FurnaceRecipe implements Recipe{
|
||||
return clone $this->output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Item $item
|
||||
*
|
||||
* @returns ShapelessRecipe
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function addIngredient(Item $item){
|
||||
if(count($this->ingredients) >= 9){
|
||||
throw new \Exception("Shapeless recipes cannot have more than 9 ingredients");
|
||||
}
|
||||
|
||||
$it = clone $item;
|
||||
$it->setCount(1);
|
||||
|
||||
while($item->getCount() > 0){
|
||||
$this->ingredients[] = clone $it;
|
||||
$item->setCount($item->getCount() - 1);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Item $item
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function removeIngredient(Item $item){
|
||||
foreach($this->ingredients as $index => $ingredient){
|
||||
if($item->getCount() <= 0){
|
||||
break;
|
||||
}
|
||||
if($ingredient->equals($item, $item->getDamage() === null ? false : true)){
|
||||
unset($this->ingredients[$index]);
|
||||
$item->setCount($item->getCount() - 1);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Item[]
|
||||
*/
|
||||
public function getIngredientList(){
|
||||
$ingredients = [];
|
||||
foreach($this->ingredients as $ingredient){
|
||||
$ingredients[] = clone $ingredient;
|
||||
}
|
||||
return $ingredients;
|
||||
public function registerToCraftingManager(){
|
||||
Server::getInstance()->getCraftingManager()->registerFurnaceRecipe($this);
|
||||
}
|
||||
}
|
@ -335,7 +335,11 @@ class PlayerInventory extends BaseInventory{
|
||||
$pk->hotbar[] = $index <= -1 ? -1 : $index + 9;
|
||||
}
|
||||
}
|
||||
$pk->windowid = $player->getWindowId($this);
|
||||
if(($id = $player->getWindowId($this)) === -1){
|
||||
$this->close($player);
|
||||
continue;
|
||||
}
|
||||
$pk->windowid = $id;
|
||||
$player->dataPacket(clone $pk);
|
||||
}
|
||||
}
|
||||
@ -355,10 +359,15 @@ class PlayerInventory extends BaseInventory{
|
||||
|
||||
foreach($target as $player){
|
||||
if($player === $this->getHolder()){
|
||||
/** @var Player $player */
|
||||
//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);
|
||||
if(($id = $player->getWindowId($this)) === -1){
|
||||
$this->close($player);
|
||||
continue;
|
||||
}
|
||||
$pk->windowid = $id;
|
||||
$player->dataPacket(clone $pk);
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
namespace pocketmine\inventory;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\Server;
|
||||
|
||||
class ShapedRecipe implements Recipe{
|
||||
/** @var Item */
|
||||
@ -98,4 +99,8 @@ class ShapedRecipe implements Recipe{
|
||||
public function getShape(){
|
||||
return $this->rows;
|
||||
}
|
||||
|
||||
public function registerToCraftingManager(){
|
||||
Server::getInstance()->getCraftingManager()->registerShapedRecipe($this);
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
namespace pocketmine\inventory;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\Server;
|
||||
|
||||
class ShapelessRecipe implements Recipe{
|
||||
/** @var Item */
|
||||
@ -89,4 +90,8 @@ class ShapelessRecipe implements Recipe{
|
||||
}
|
||||
return $ingredients;
|
||||
}
|
||||
|
||||
public function registerToCraftingManager(){
|
||||
Server::getInstance()->getCraftingManager()->registerShapelessRecipe($this);
|
||||
}
|
||||
}
|
@ -59,20 +59,24 @@ class SimpleTransactionGroup implements TransactionGroup{
|
||||
$this->inventories[spl_object_hash($transaction->getInventory())] = $transaction->getInventory();
|
||||
}
|
||||
|
||||
public function canExecute(){
|
||||
/** @var Item[] $needItems */
|
||||
$needItems = [];
|
||||
/** @var Item[] $haveItems */
|
||||
$haveItems = [];
|
||||
/**
|
||||
* @param Item[] $needItems
|
||||
* @param Item[] $haveItems
|
||||
*/
|
||||
protected function matchItems(array &$needItems, array &$haveItems){
|
||||
foreach($this->transactions as $key => $ts){
|
||||
if($ts->getTargetItem()->getID() !== Item::AIR){
|
||||
$needItems[] = $ts->getTargetItem();
|
||||
}
|
||||
$checkSourceItem = $ts->getInventory()->getItem($ts->getSlot());
|
||||
$sourceItem = $ts->getSourceItem();
|
||||
if(!$checkSourceItem->equals($sourceItem, true) or $sourceItem->getCount() !== $checkSourceItem->getCount()){
|
||||
return false;
|
||||
}
|
||||
if($sourceItem->getID() !== Item::AIR){
|
||||
$haveItems[] = $sourceItem;
|
||||
}
|
||||
}
|
||||
|
||||
foreach($needItems as $i => $needItem){
|
||||
foreach($haveItems as $j => $haveItem){
|
||||
@ -90,7 +94,12 @@ class SimpleTransactionGroup implements TransactionGroup{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function canExecute(){
|
||||
$haveItems = [];
|
||||
$needItems = [];
|
||||
$this->matchItems($haveItems, $needItems);
|
||||
return count($haveItems) === 0 and count($needItems) === 0 and count($this->transactions) > 0;
|
||||
}
|
||||
|
||||
@ -111,6 +120,8 @@ class SimpleTransactionGroup implements TransactionGroup{
|
||||
$transaction->getInventory()->setItem($transaction->getSlot(), $transaction->getTargetItem());
|
||||
}
|
||||
|
||||
$this->hasExecuted = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user