mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-18 19:55:33 +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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->currentTransaction === null or $this->currentTransaction->getCreationTime() > (microtime(true) - 1)){
|
|
||||||
$this->currentTransaction = new SimpleTransactionGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
if($packet->slot < 0){
|
if($packet->slot < 0){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2029,9 +2025,28 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
|||||||
break;
|
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);
|
$this->currentTransaction->addTransaction($transaction);
|
||||||
|
|
||||||
if($this->currentTransaction->canExecute()){
|
if($this->currentTransaction->canExecute()){
|
||||||
|
if(!$this->currentTransaction->execute()){
|
||||||
|
$this->currentTransaction = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
foreach($this->currentTransaction->getTransactions() as $ts){
|
foreach($this->currentTransaction->getTransactions() as $ts){
|
||||||
$inv = $ts->getInventory();
|
$inv = $ts->getInventory();
|
||||||
if($inv instanceof FurnaceInventory){
|
if($inv instanceof FurnaceInventory){
|
||||||
@ -2043,19 +2058,13 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$this->currentTransaction = null;
|
$this->currentTransaction = null;
|
||||||
}
|
|
||||||
}elseif($packet->windowid == 0){ //Try crafting
|
}elseif($packet->windowid == 0){ //Try crafting
|
||||||
$craftingGroup = new CraftingTransactionGroup($this->currentTransaction);
|
$craftingGroup = new CraftingTransactionGroup($this->currentTransaction);
|
||||||
if($craftingGroup->canExecute()){ //We can craft!
|
if($craftingGroup->canExecute() and $craftingGroup->execute()){ //We can craft!
|
||||||
//TODO: CraftItemEvent
|
switch($craftingGroup->getResult()->getID()){
|
||||||
//$this->server->getPluginManager($ev = new CraftItemEvent($this, $recipe, $craft, $type));
|
|
||||||
//if($ev->isCancelled()){
|
|
||||||
// return false;
|
|
||||||
//}
|
|
||||||
|
|
||||||
/*switch($item->getID()){
|
|
||||||
case Item::WORKBENCH:
|
case Item::WORKBENCH:
|
||||||
$this->awardAchievement("buildWorkBench");
|
$this->awardAchievement("buildWorkBench");
|
||||||
break;
|
break;
|
||||||
@ -2072,6 +2081,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
|||||||
$this->awardAchievement("makeBread");
|
$this->awardAchievement("makeBread");
|
||||||
break;
|
break;
|
||||||
case Item::CAKE:
|
case Item::CAKE:
|
||||||
|
//TODO: detect complex recipes like cake that leave remainings
|
||||||
$this->awardAchievement("bakeCake");
|
$this->awardAchievement("bakeCake");
|
||||||
$this->inventory->addItem(Item::get(Item::BUCKET, 0, 3));
|
$this->inventory->addItem(Item::get(Item::BUCKET, 0, 3));
|
||||||
break;
|
break;
|
||||||
@ -2087,15 +2097,17 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
|||||||
case Item::DIAMOND:
|
case Item::DIAMOND:
|
||||||
$this->awardAchievement("diamond");
|
$this->awardAchievement("diamond");
|
||||||
break;
|
break;
|
||||||
}*/
|
|
||||||
|
|
||||||
$craftingGroup->execute();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$this->currentTransaction = null;
|
$this->currentTransaction = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case ProtocolInfo::SEND_INVENTORY_PACKET: //TODO, Mojang, enable this ´^_^`
|
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];
|
return $this->windows[$inventory];
|
||||||
}
|
}
|
||||||
|
|
||||||
if($forceId === 0 or $inventory->open($this)){
|
|
||||||
if($forceId === null){
|
if($forceId === null){
|
||||||
$this->windowCnt = $cnt = max(2, ++$this->windowCnt % 99);
|
$this->windowCnt = $cnt = max(2, ++$this->windowCnt % 99);
|
||||||
}else{
|
}else{
|
||||||
@ -2330,20 +2341,20 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
|||||||
}
|
}
|
||||||
$this->windowIndex[$cnt] = $inventory;
|
$this->windowIndex[$cnt] = $inventory;
|
||||||
$this->windows->attach($inventory, $cnt);
|
$this->windows->attach($inventory, $cnt);
|
||||||
|
if($inventory->open($this)){
|
||||||
return $cnt;
|
return $cnt;
|
||||||
}else{
|
}else{
|
||||||
|
$this->removeWindow($inventory);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function removeWindow(Inventory $inventory){
|
public function removeWindow(Inventory $inventory){
|
||||||
$inventory->close($this);
|
$inventory->close($this);
|
||||||
if($this->windows->contains($inventory)){
|
if($this->windows->contains($inventory)){
|
||||||
$id = $this->windows[$inventory];
|
$id = $this->windows[$inventory];
|
||||||
|
$this->windows->detach($this->windowIndex[$id]);
|
||||||
unset($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\PacketReceiveEvent;
|
||||||
use pocketmine\event\server\PacketSendEvent;
|
use pocketmine\event\server\PacketSendEvent;
|
||||||
use pocketmine\event\server\ServerCommandEvent;
|
use pocketmine\event\server\ServerCommandEvent;
|
||||||
|
use pocketmine\inventory\CraftingManager;
|
||||||
use pocketmine\inventory\InventoryType;
|
use pocketmine\inventory\InventoryType;
|
||||||
|
use pocketmine\inventory\Recipe;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\level\format\pmf\LevelFormat;
|
use pocketmine\level\format\pmf\LevelFormat;
|
||||||
use pocketmine\level\generator\Flat;
|
use pocketmine\level\generator\Flat;
|
||||||
@ -127,6 +129,9 @@ class Server{
|
|||||||
/** @var SimpleCommandMap */
|
/** @var SimpleCommandMap */
|
||||||
private $commandMap = null;
|
private $commandMap = null;
|
||||||
|
|
||||||
|
/** @var CraftingManager */
|
||||||
|
private $craftingManager;
|
||||||
|
|
||||||
/** @var ConsoleCommandSender */
|
/** @var ConsoleCommandSender */
|
||||||
private $consoleSender;
|
private $consoleSender;
|
||||||
|
|
||||||
@ -468,6 +473,13 @@ class Server{
|
|||||||
return $this->pluginManager;
|
return $this->pluginManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return CraftingManager
|
||||||
|
*/
|
||||||
|
public function getCraftingManager(){
|
||||||
|
return $this->craftingManager;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return ServerScheduler
|
* @return ServerScheduler
|
||||||
*/
|
*/
|
||||||
@ -512,6 +524,10 @@ class Server{
|
|||||||
return $this->players;
|
return $this->players;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function addRecipe(Recipe $recipe){
|
||||||
|
$this->craftingManager->registerRecipe($recipe);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $name
|
* @param string $name
|
||||||
*
|
*
|
||||||
@ -1267,6 +1283,13 @@ class Server{
|
|||||||
|
|
||||||
$this->consoleSender = new ConsoleCommandSender();
|
$this->consoleSender = new ConsoleCommandSender();
|
||||||
$this->commandMap = new SimpleCommandMap($this);
|
$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 = new PluginManager($this, $this->commandMap);
|
||||||
$this->pluginManager->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this->consoleSender);
|
$this->pluginManager->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this->consoleSender);
|
||||||
$this->pluginManager->registerInterface("pocketmine\\plugin\\PharPluginLoader");
|
$this->pluginManager->registerInterface("pocketmine\\plugin\\PharPluginLoader");
|
||||||
@ -1276,10 +1299,7 @@ class Server{
|
|||||||
|
|
||||||
$this->enablePlugins(PluginLoadOrder::STARTUP);
|
$this->enablePlugins(PluginLoadOrder::STARTUP);
|
||||||
|
|
||||||
InventoryType::init();
|
|
||||||
Block::init();
|
|
||||||
Item::init();
|
|
||||||
Crafting::init();
|
|
||||||
|
|
||||||
Generator::addGenerator("pocketmine\\level\\generator\\Flat", "flat");
|
Generator::addGenerator("pocketmine\\level\\generator\\Flat", "flat");
|
||||||
Generator::addGenerator("pocketmine\\level\\generator\\Normal", "normal");
|
Generator::addGenerator("pocketmine\\level\\generator\\Normal", "normal");
|
||||||
|
@ -23,15 +23,24 @@ namespace pocketmine\block;
|
|||||||
|
|
||||||
|
|
||||||
class Planks extends Solid{
|
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){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::PLANKS, $meta, "Wooden Planks");
|
parent::__construct(self::PLANKS, $meta, "Wood Planks");
|
||||||
$names = array(
|
$names = array(
|
||||||
Wood::OAK => "Oak Wooden Planks",
|
self::OAK => "Oak Wood Planks",
|
||||||
Wood::SPRUCE => "Spruce Wooden Planks",
|
self::SPRUCE => "Spruce Wood Planks",
|
||||||
Wood::BIRCH => "Birch Wooden Planks",
|
self::BIRCH => "Birch Wood Planks",
|
||||||
Wood::JUNGLE => "Jungle Wooden 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;
|
$this->hardness = 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,8 @@ class Wood extends Solid{
|
|||||||
const SPRUCE = 1;
|
const SPRUCE = 1;
|
||||||
const BIRCH = 2;
|
const BIRCH = 2;
|
||||||
const JUNGLE = 3;
|
const JUNGLE = 3;
|
||||||
|
const ACACIA = 4;
|
||||||
|
const DARK_OAK = 5;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::WOOD, $meta, "Wood");
|
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){
|
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);
|
$player->dataPacket(clone $pk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -409,7 +413,11 @@ abstract class BaseInventory implements Inventory{
|
|||||||
$pk->item = clone $this->getItem($index);
|
$pk->item = clone $this->getItem($index);
|
||||||
|
|
||||||
foreach($target as $player){
|
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);
|
$player->dataPacket(clone $pk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,8 @@ abstract class ContainerInventory extends BaseInventory{
|
|||||||
}
|
}
|
||||||
|
|
||||||
$who->dataPacket($pk);
|
$who->dataPacket($pk);
|
||||||
|
|
||||||
|
$this->sendContents($who);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onClose(Player $who){
|
public function onClose(Player $who){
|
||||||
|
@ -21,19 +21,55 @@
|
|||||||
|
|
||||||
namespace pocketmine\inventory;
|
namespace pocketmine\inventory;
|
||||||
|
|
||||||
|
use pocketmine\block\Planks;
|
||||||
|
use pocketmine\block\Wood;
|
||||||
|
use pocketmine\item\Item;
|
||||||
|
|
||||||
class CraftingManager{
|
class CraftingManager{
|
||||||
|
|
||||||
/** @var Recipe[] */
|
/** @var Recipe[] */
|
||||||
public $recipes = [];
|
public $recipes = [];
|
||||||
|
|
||||||
|
/** @var Recipe[][] */
|
||||||
|
protected $recipeLookup = [];
|
||||||
|
|
||||||
/** @var FurnaceRecipe[] */
|
/** @var FurnaceRecipe[] */
|
||||||
public $furnaceRecipes = [];
|
public $furnaceRecipes = [];
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
//TODO: add crafting recipes
|
//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(){
|
public function sort(Item $i1, Item $i2){
|
||||||
//TODO: recipe sort
|
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
|
* @param ShapelessRecipe $recipe
|
||||||
*/
|
*/
|
||||||
public function registerShapelessRecipe(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
|
* @param Recipe $recipe
|
||||||
*/
|
*/
|
||||||
|
@ -21,16 +21,88 @@
|
|||||||
|
|
||||||
namespace pocketmine\inventory;
|
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){
|
public function __construct(TransactionGroup $group){
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->transactions = $group->getTransactions();
|
$this->transactions = $group->getTransactions();
|
||||||
$this->inventories = $group->getInventories();
|
$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(){
|
public function canExecute(){
|
||||||
//TODO: search in crafting recipes
|
if(count($this->output) !== 1 or count($this->input) === 0){
|
||||||
return false;
|
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;
|
namespace pocketmine\inventory;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\Server;
|
||||||
|
|
||||||
class FurnaceRecipe implements Recipe{
|
class FurnaceRecipe implements Recipe{
|
||||||
/** @var Item */
|
/** @var Item */
|
||||||
@ -60,55 +61,7 @@ class FurnaceRecipe implements Recipe{
|
|||||||
return clone $this->output;
|
return clone $this->output;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function registerToCraftingManager(){
|
||||||
* @param Item $item
|
Server::getInstance()->getCraftingManager()->registerFurnaceRecipe($this);
|
||||||
*
|
|
||||||
* @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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -335,7 +335,11 @@ class PlayerInventory extends BaseInventory{
|
|||||||
$pk->hotbar[] = $index <= -1 ? -1 : $index + 9;
|
$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);
|
$player->dataPacket(clone $pk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -355,10 +359,15 @@ class PlayerInventory extends BaseInventory{
|
|||||||
|
|
||||||
foreach($target as $player){
|
foreach($target as $player){
|
||||||
if($player === $this->getHolder()){
|
if($player === $this->getHolder()){
|
||||||
|
/** @var Player $player */
|
||||||
//TODO: Check if Mojang has implemented this (for the player inventory) on Minecraft: PE 0.9.0
|
//TODO: Check if Mojang has implemented this (for the player inventory) on Minecraft: PE 0.9.0
|
||||||
$this->sendContents($player);
|
$this->sendContents($player);
|
||||||
}else{
|
}else{
|
||||||
$pk->windowid = $player->getWindowId($this);
|
if(($id = $player->getWindowId($this)) === -1){
|
||||||
|
$this->close($player);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$pk->windowid = $id;
|
||||||
$player->dataPacket(clone $pk);
|
$player->dataPacket(clone $pk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
namespace pocketmine\inventory;
|
namespace pocketmine\inventory;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\Server;
|
||||||
|
|
||||||
class ShapedRecipe implements Recipe{
|
class ShapedRecipe implements Recipe{
|
||||||
/** @var Item */
|
/** @var Item */
|
||||||
@ -98,4 +99,8 @@ class ShapedRecipe implements Recipe{
|
|||||||
public function getShape(){
|
public function getShape(){
|
||||||
return $this->rows;
|
return $this->rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function registerToCraftingManager(){
|
||||||
|
Server::getInstance()->getCraftingManager()->registerShapedRecipe($this);
|
||||||
|
}
|
||||||
}
|
}
|
@ -22,6 +22,7 @@
|
|||||||
namespace pocketmine\inventory;
|
namespace pocketmine\inventory;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\Server;
|
||||||
|
|
||||||
class ShapelessRecipe implements Recipe{
|
class ShapelessRecipe implements Recipe{
|
||||||
/** @var Item */
|
/** @var Item */
|
||||||
@ -89,4 +90,8 @@ class ShapelessRecipe implements Recipe{
|
|||||||
}
|
}
|
||||||
return $ingredients;
|
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();
|
$this->inventories[spl_object_hash($transaction->getInventory())] = $transaction->getInventory();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function canExecute(){
|
/**
|
||||||
/** @var Item[] $needItems */
|
* @param Item[] $needItems
|
||||||
$needItems = [];
|
* @param Item[] $haveItems
|
||||||
/** @var Item[] $haveItems */
|
*/
|
||||||
$haveItems = [];
|
protected function matchItems(array &$needItems, array &$haveItems){
|
||||||
foreach($this->transactions as $key => $ts){
|
foreach($this->transactions as $key => $ts){
|
||||||
|
if($ts->getTargetItem()->getID() !== Item::AIR){
|
||||||
$needItems[] = $ts->getTargetItem();
|
$needItems[] = $ts->getTargetItem();
|
||||||
|
}
|
||||||
$checkSourceItem = $ts->getInventory()->getItem($ts->getSlot());
|
$checkSourceItem = $ts->getInventory()->getItem($ts->getSlot());
|
||||||
$sourceItem = $ts->getSourceItem();
|
$sourceItem = $ts->getSourceItem();
|
||||||
if(!$checkSourceItem->equals($sourceItem, true) or $sourceItem->getCount() !== $checkSourceItem->getCount()){
|
if(!$checkSourceItem->equals($sourceItem, true) or $sourceItem->getCount() !== $checkSourceItem->getCount()){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if($sourceItem->getID() !== Item::AIR){
|
||||||
$haveItems[] = $sourceItem;
|
$haveItems[] = $sourceItem;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach($needItems as $i => $needItem){
|
foreach($needItems as $i => $needItem){
|
||||||
foreach($haveItems as $j => $haveItem){
|
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;
|
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());
|
$transaction->getInventory()->setItem($transaction->getSlot(), $transaction->getTargetItem());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->hasExecuted = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user