Merge branch 'mcpe-0.13'

This commit is contained in:
Intyre 2015-12-19 11:38:05 +01:00
commit 261ce1ba8b
No known key found for this signature in database
GPG Key ID: B06D41D26935005A
274 changed files with 7872 additions and 1668 deletions

View File

@ -26,6 +26,7 @@ use pocketmine\event\Timings;
use pocketmine\scheduler\GarbageCollectionTask; use pocketmine\scheduler\GarbageCollectionTask;
use pocketmine\utils\Utils; use pocketmine\utils\Utils;
class MemoryManager{ class MemoryManager{
/** @var Server */ /** @var Server */
@ -231,7 +232,7 @@ class MemoryManager{
} }
$this->leakInfo[$identifier] = [ $this->leakInfo[$identifier] = [
"id" => $id = Utils::dataToUUID($identifier . ":" . $this->leakSeed++), "id" => $id = md5($identifier . ":" . $this->leakSeed++),
"class" => get_class($object), "class" => get_class($object),
"hash" => $identifier "hash" => $identifier
]; ];

File diff suppressed because it is too large Load Diff

View File

@ -72,11 +72,11 @@ namespace pocketmine {
use pocketmine\utils\Utils; use pocketmine\utils\Utils;
use pocketmine\wizard\Installer; use pocketmine\wizard\Installer;
const VERSION = "1.5dev"; const VERSION = "1.6dev";
const API_VERSION = "1.12.0"; const API_VERSION = "1.13.1";
const CODENAME = "活発(Kappatsu)フグ(Fugu)"; const CODENAME = "[REDACTED]";
const MINECRAFT_VERSION = "v0.11.0 alpha"; const MINECRAFT_VERSION = "v0.13.1 alpha";
const MINECRAFT_VERSION_NETWORK = "0.11.0"; const MINECRAFT_VERSION_NETWORK = "0.13.1";
/* /*
* Startup code. Do not look at it, it may harm you. * Startup code. Do not look at it, it may harm you.
@ -355,10 +355,10 @@ namespace pocketmine {
$args = $trace[$i]["params"]; $args = $trace[$i]["params"];
} }
foreach($args as $name => $value){ foreach($args as $name => $value){
$params .= (is_object($value) ? get_class($value) . " " . (method_exists($value, "__toString") ? $value->__toString() : "object") : gettype($value) . " " . (is_array($value) ? "Array()" : @strval($value))) . ", "; $params .= (is_object($value) ? get_class($value) . " " . (method_exists($value, "__toString") ? $value->__toString() : "object") : gettype($value) . " " . (is_array($value) ? "Array()" : Utils::printable(@strval($value)))) . ", ";
} }
} }
$messages[] = "#$j " . (isset($trace[$i]["file"]) ? cleanPath($trace[$i]["file"]) : "") . "(" . (isset($trace[$i]["line"]) ? $trace[$i]["line"] : "") . "): " . (isset($trace[$i]["class"]) ? $trace[$i]["class"] . (($trace[$i]["type"] === "dynamic" or $trace[$i]["type"] === "->") ? "->" : "::") : "") . $trace[$i]["function"] . "(" . substr($params, 0, -2) . ")"; $messages[] = "#$j " . (isset($trace[$i]["file"]) ? cleanPath($trace[$i]["file"]) : "") . "(" . (isset($trace[$i]["line"]) ? $trace[$i]["line"] : "") . "): " . (isset($trace[$i]["class"]) ? $trace[$i]["class"] . (($trace[$i]["type"] === "dynamic" or $trace[$i]["type"] === "->") ? "->" : "::") : "") . $trace[$i]["function"] . "(" . Utils::printable(substr($params, 0, -2)) . ")";
} }
return $messages; return $messages;

View File

@ -32,6 +32,7 @@ use pocketmine\command\ConsoleCommandSender;
use pocketmine\command\PluginIdentifiableCommand; use pocketmine\command\PluginIdentifiableCommand;
use pocketmine\command\SimpleCommandMap; use pocketmine\command\SimpleCommandMap;
use pocketmine\entity\Arrow; use pocketmine\entity\Arrow;
use pocketmine\entity\Attribute;
use pocketmine\entity\Effect; use pocketmine\entity\Effect;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
use pocketmine\entity\FallingSand; use pocketmine\entity\FallingSand;
@ -53,6 +54,9 @@ use pocketmine\event\TranslationContainer;
use pocketmine\inventory\CraftingManager; use pocketmine\inventory\CraftingManager;
use pocketmine\inventory\InventoryType; use pocketmine\inventory\InventoryType;
use pocketmine\inventory\Recipe; use pocketmine\inventory\Recipe;
use pocketmine\inventory\ShapedRecipe;
use pocketmine\inventory\ShapelessRecipe;
use pocketmine\item\enchantment\Enchantment;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\lang\BaseLang; use pocketmine\lang\BaseLang;
use pocketmine\level\format\anvil\Anvil; use pocketmine\level\format\anvil\Anvil;
@ -62,6 +66,7 @@ use pocketmine\level\format\mcregion\McRegion;
use pocketmine\level\generator\biome\Biome; use pocketmine\level\generator\biome\Biome;
use pocketmine\level\generator\Flat; use pocketmine\level\generator\Flat;
use pocketmine\level\generator\Generator; use pocketmine\level\generator\Generator;
use pocketmine\level\generator\hell\Nether;
use pocketmine\level\generator\normal\Normal; use pocketmine\level\generator\normal\Normal;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\metadata\EntityMetadataStore; use pocketmine\metadata\EntityMetadataStore;
@ -80,7 +85,9 @@ use pocketmine\nbt\tag\String;
use pocketmine\network\CompressBatchedTask; use pocketmine\network\CompressBatchedTask;
use pocketmine\network\Network; use pocketmine\network\Network;
use pocketmine\network\protocol\BatchPacket; use pocketmine\network\protocol\BatchPacket;
use pocketmine\network\protocol\CraftingDataPacket;
use pocketmine\network\protocol\DataPacket; use pocketmine\network\protocol\DataPacket;
use pocketmine\network\protocol\PlayerListPacket;
use pocketmine\network\query\QueryHandler; use pocketmine\network\query\QueryHandler;
use pocketmine\network\RakLibInterface; use pocketmine\network\RakLibInterface;
use pocketmine\network\rcon\RCON; use pocketmine\network\rcon\RCON;
@ -97,6 +104,7 @@ use pocketmine\scheduler\FileWriteTask;
use pocketmine\scheduler\SendUsageTask; use pocketmine\scheduler\SendUsageTask;
use pocketmine\scheduler\ServerScheduler; use pocketmine\scheduler\ServerScheduler;
use pocketmine\tile\Chest; use pocketmine\tile\Chest;
use pocketmine\tile\EnchantTable;
use pocketmine\tile\Furnace; use pocketmine\tile\Furnace;
use pocketmine\tile\Sign; use pocketmine\tile\Sign;
use pocketmine\tile\Tile; use pocketmine\tile\Tile;
@ -111,6 +119,7 @@ use pocketmine\utils\Terminal;
use pocketmine\utils\TextFormat; use pocketmine\utils\TextFormat;
use pocketmine\utils\TextWrapper; use pocketmine\utils\TextWrapper;
use pocketmine\utils\Utils; use pocketmine\utils\Utils;
use pocketmine\utils\UUID;
use pocketmine\utils\VersionString; use pocketmine\utils\VersionString;
/** /**
@ -249,6 +258,9 @@ class Server{
/** @var Player[] */ /** @var Player[] */
private $players = []; private $players = [];
/** @var Player[] */
private $playerList = [];
private $identifiers = []; private $identifiers = [];
/** @var Level[] */ /** @var Level[] */
@ -705,7 +717,7 @@ class Server{
* @return Player[] * @return Player[]
*/ */
public function getOnlinePlayers(){ public function getOnlinePlayers(){
return $this->players; return $this->playerList;
} }
public function addRecipe(Recipe $recipe){ public function addRecipe(Recipe $recipe){
@ -1085,99 +1097,6 @@ class Server{
$level->setTickRate($this->baseTickRate); $level->setTickRate($this->baseTickRate);
/*foreach($entities->getAll() as $entity){
if(!isset($entity["id"])){
break;
}
if($entity["id"] === 64){ //Item Drop
$e = $this->server->api->entity->add($this->levels[$name], ENTITY_ITEM, $entity["Item"]["id"], array(
"meta" => $entity["Item"]["Damage"],
"stack" => $entity["Item"]["Count"],
"x" => $entity["Pos"][0],
"y" => $entity["Pos"][1],
"z" => $entity["Pos"][2],
"yaw" => $entity["Rotation"][0],
"pitch" => $entity["Rotation"][1],
));
}elseif($entity["id"] === FALLING_SAND){
$e = $this->server->api->entity->add($this->levels[$name], ENTITY_FALLING, $entity["id"], $entity);
$e->setPosition(new Vector3($entity["Pos"][0], $entity["Pos"][1], $entity["Pos"][2]), $entity["Rotation"][0], $entity["Rotation"][1]);
$e->setHealth($entity["Health"]);
}elseif($entity["id"] === OBJECT_PAINTING or $entity["id"] === OBJECT_ARROW){ //Painting
$e = $this->server->api->entity->add($this->levels[$name], ENTITY_OBJECT, $entity["id"], $entity);
$e->setPosition(new Vector3($entity["Pos"][0], $entity["Pos"][1], $entity["Pos"][2]), $entity["Rotation"][0], $entity["Rotation"][1]);
$e->setHealth(1);
}else{
$e = $this->server->api->entity->add($this->levels[$name], ENTITY_MOB, $entity["id"], $entity);
$e->setPosition(new Vector3($entity["Pos"][0], $entity["Pos"][1], $entity["Pos"][2]), $entity["Rotation"][0], $entity["Rotation"][1]);
$e->setHealth($entity["Health"]);
}
}*/
/*if(file_exists($path . "tiles.yml")){
$tiles = new Config($path . "tiles.yml", Config::YAML);
foreach($tiles->getAll() as $tile){
if(!isset($tile["id"])){
continue;
}
$level->loadChunk($tile["x"] >> 4, $tile["z"] >> 4);
$nbt = new Compound(false, []);
foreach($tile as $index => $data){
switch($index){
case "Items":
$tag = new Enum("Items", []);
$tag->setTagType(NBT::TAG_Compound);
foreach($data as $slot => $fields){
$tag[(int) $slot] = new Compound(false, array(
"Count" => new Byte("Count", $fields["Count"]),
"Slot" => new Short("Slot", $fields["Slot"]),
"Damage" => new Short("Damage", $fields["Damage"]),
"id" => new String("id", $fields["id"])
));
}
$nbt["Items"] = $tag;
break;
case "id":
case "Text1":
case "Text2":
case "Text3":
case "Text4":
$nbt[$index] = new String($index, $data);
break;
case "x":
case "y":
case "z":
case "pairx":
case "pairz":
$nbt[$index] = new Int($index, $data);
break;
case "BurnTime":
case "CookTime":
case "MaxTime":
$nbt[$index] = new Short($index, $data);
break;
}
}
switch($tile["id"]){
case Tile::FURNACE:
new Furnace($level, $nbt);
break;
case Tile::CHEST:
new Chest($level, $nbt);
break;
case Tile::SIGN:
new Sign($level, $nbt);
break;
}
}
unlink($path . "tiles.yml");
$level->save(true, true);
}*/
return true; return true;
} }
@ -1691,6 +1610,8 @@ class Server{
Item::init(); Item::init();
Biome::init(); Biome::init();
Effect::init(); Effect::init();
Enchantment::init();
Attribute::init();
/** TODO: @deprecated */ /** TODO: @deprecated */
TextWrapper::init(); TextWrapper::init();
$this->craftingManager = new CraftingManager(); $this->craftingManager = new CraftingManager();
@ -1726,6 +1647,8 @@ class Server{
Generator::addGenerator(Flat::class, "flat"); Generator::addGenerator(Flat::class, "flat");
Generator::addGenerator(Normal::class, "normal"); Generator::addGenerator(Normal::class, "normal");
Generator::addGenerator(Normal::class, "default"); Generator::addGenerator(Normal::class, "default");
Generator::addGenerator(Nether::class, "hell");
Generator::addGenerator(Nether::class, "nether");
foreach((array) $this->getProperty("worlds", []) as $name => $worldSetting){ foreach((array) $this->getProperty("worlds", []) as $name => $worldSetting){
if($this->loadLevel($name) === false){ if($this->loadLevel($name) === false){
@ -1912,9 +1835,9 @@ class Server{
if(!$p->isEncoded){ if(!$p->isEncoded){
$p->encode(); $p->encode();
} }
$str .= $p->buffer; $str .= Binary::writeInt(strlen($p->buffer)) . $p->buffer;
}else{ }else{
$str .= $p; $str .= Binary::writeInt(strlen($p)) . $p;
} }
} }
@ -1929,15 +1852,14 @@ class Server{
$task = new CompressBatchedTask($str, $targets, $this->networkCompressionLevel, $channel); $task = new CompressBatchedTask($str, $targets, $this->networkCompressionLevel, $channel);
$this->getScheduler()->scheduleAsyncTask($task); $this->getScheduler()->scheduleAsyncTask($task);
}else{ }else{
$this->broadcastPacketsCallback(zlib_encode($str, ZLIB_ENCODING_DEFLATE, $this->networkCompressionLevel), $targets, $channel); $this->broadcastPacketsCallback(zlib_encode($str, ZLIB_ENCODING_DEFLATE, $this->networkCompressionLevel), $targets);
} }
Timings::$playerNetworkTimer->stopTiming(); Timings::$playerNetworkTimer->stopTiming();
} }
public function broadcastPacketsCallback($data, array $identifiers, $channel = 0){ public function broadcastPacketsCallback($data, array $identifiers){
$pk = new BatchPacket(); $pk = new BatchPacket();
$pk->setChannel($channel);
$pk->payload = $data; $pk->payload = $data;
$pk->encode(); $pk->encode();
$pk->isEncoded = true; $pk->isEncoded = true;
@ -2311,8 +2233,11 @@ class Server{
public function onPlayerLogin(Player $player){ public function onPlayerLogin(Player $player){
if($this->sendUsageTicker > 0){ if($this->sendUsageTicker > 0){
$this->uniquePlayers[$player->getUniqueId()] = $player->getUniqueId(); $this->uniquePlayers[$player->getRawUniqueId()] = $player->getRawUniqueId();
} }
$this->sendFullPlayerListData($player);
$this->sendRecipeList($player);
} }
public function addPlayer($identifier, Player $player){ public function addPlayer($identifier, Player $player){
@ -2320,6 +2245,66 @@ class Server{
$this->identifiers[spl_object_hash($player)] = $identifier; $this->identifiers[spl_object_hash($player)] = $identifier;
} }
public function addOnlinePlayer(Player $player){
$this->playerList[$player->getRawUniqueId()] = $player;
$this->updatePlayerListData($player->getUniqueId(), $player->getId(), $player->getDisplayName(), $player->getSkinName(), $player->getSkinData());
}
public function removeOnlinePlayer(Player $player){
if(isset($this->playerList[$player->getRawUniqueId()])){
unset($this->playerList[$player->getRawUniqueId()]);
$pk = new PlayerListPacket();
$pk->type = PlayerListPacket::TYPE_REMOVE;
$pk->entries[] = [$player->getUniqueId()];
Server::broadcastPacket($this->playerList, $pk);
}
}
public function updatePlayerListData(UUID $uuid, $entityId, $name, $skinName, $skinData, array $players = null){
$pk = new PlayerListPacket();
$pk->type = PlayerListPacket::TYPE_ADD;
$pk->entries[] = [$uuid, $entityId, $name, $skinName, $skinData];
Server::broadcastPacket($players === null ? $this->playerList : $players, $pk);
}
public function removePlayerListData(UUID $uuid, array $players = null){
$pk = new PlayerListPacket();
$pk->type = PlayerListPacket::TYPE_REMOVE;
$pk->entries[] = [$uuid];
Server::broadcastPacket($players === null ? $this->playerList : $players, $pk);
}
public function sendFullPlayerListData(Player $p){
$pk = new PlayerListPacket();
$pk->type = PlayerListPacket::TYPE_ADD;
foreach($this->playerList as $player){
$pk->entries[] = [$player->getUniqueId(), $player->getId(), $player->getDisplayName(), $player->getSkinName(), $player->getSkinData()];
}
$p->dataPacket($pk);
}
public function sendRecipeList(Player $p){
$pk = new CraftingDataPacket();
$pk->cleanRecipes = true;
foreach($this->getCraftingManager()->getRecipes() as $recipe){
if($recipe instanceof ShapedRecipe){
$pk->addShapedRecipe($recipe);
}elseif($recipe instanceof ShapelessRecipe){
$pk->addShapelessRecipe($recipe);
}
}
foreach($this->getCraftingManager()->getFurnaceRecipes() as $recipe){
$pk->addFurnaceRecipe($recipe);
}
$p->dataPacket($pk);
}
private function checkTickUpdates($currentTick, $tickTime){ private function checkTickUpdates($currentTick, $tickTime){
foreach($this->players as $p){ foreach($this->players as $p){
if(!$p->loggedIn and ($tickTime - $p->creationTime) >= 10){ if(!$p->loggedIn and ($tickTime - $p->creationTime) >= 10){
@ -2370,7 +2355,7 @@ class Server{
public function doAutoSave(){ public function doAutoSave(){
if($this->getAutoSave()){ if($this->getAutoSave()){
Timings::$worldSaveTimer->startTiming(); Timings::$worldSaveTimer->startTiming();
foreach($this->getOnlinePlayers() as $index => $player){ foreach($this->players as $index => $player){
if($player->isOnline()){ if($player->isOnline()){
$player->save(true); $player->save(true);
}elseif(!$player->isConnected()){ }elseif(!$player->isConnected()){
@ -2594,6 +2579,7 @@ class Server{
Tile::registerTile(Chest::class); Tile::registerTile(Chest::class);
Tile::registerTile(Furnace::class); Tile::registerTile(Furnace::class);
Tile::registerTile(Sign::class); Tile::registerTile(Sign::class);
Tile::registerTile(EnchantTable::class);
} }
} }

View File

@ -0,0 +1,82 @@
<?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\block;
use pocketmine\inventory\AnvilInventory;
use pocketmine\item\Item;
use pocketmine\item\Tool;
use pocketmine\Player;
class Anvil extends Fallable{
protected $id = self::ANVIL;
public function isSolid(){
return false;
}
public function __construct($meta = 0){
$this->meta = $meta;
}
public function canBeActivated(){
return true;
}
public function getHardness(){
return 5;
}
public function getResistance(){
return 6000;
}
public function getName(){
return "Anvil";
}
public function getToolType(){
return Tool::TYPE_PICKAXE;
}
public function onActivate(Item $item, Player $player = null){
if($player instanceof Player){
if($player->isCreative()){
return true;
}
$player->addWindow(new AnvilInventory($this));
}
return true;
}
public function getDrops(Item $item){
if($item->isPickaxe() >= Tool::TIER_WOODEN){
return [
[$this->id, 0, 1], //TODO break level
];
}else{
return [];
}
}
}

View File

@ -25,9 +25,8 @@
namespace pocketmine\block; namespace pocketmine\block;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
use pocketmine\entity\Squid;
use pocketmine\entity\Villager;
use pocketmine\entity\Zombie;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\item\Tool; use pocketmine\item\Tool;
use pocketmine\level\Level; use pocketmine\level\Level;
@ -182,9 +181,13 @@ class Block extends Position implements Metadatable{
const LILY_PAD = 111; const LILY_PAD = 111;
const NETHER_BRICKS = 112; const NETHER_BRICKS = 112;
const NETHER_BRICK_BLOCK = 112; const NETHER_BRICK_BLOCK = 112;
const NETHER_BRICK_FENCE = 113;
const NETHER_BRICKS_STAIRS = 114; const NETHER_BRICKS_STAIRS = 114;
const ENCHANTING_TABLE = 116;
const ENCHANT_TABLE = 116;
const ENCHANTMENT_TABLE = 116;
const BREWING_STAND = 117;
const END_PORTAL_FRAME = 120; const END_PORTAL_FRAME = 120;
const END_STONE = 121; const END_STONE = 121;
@ -202,10 +205,13 @@ class Block extends Position implements Metadatable{
const COBBLE_WALL = 139; const COBBLE_WALL = 139;
const STONE_WALL = 139; const STONE_WALL = 139;
const COBBLESTONE_WALL = 139; const COBBLESTONE_WALL = 139;
const FLOWER_POT_BLOCK = 140;
const CARROT_BLOCK = 141; const CARROT_BLOCK = 141;
const POTATO_BLOCK = 142; const POTATO_BLOCK = 142;
const ANVIL = 145;
const TRAPPED_CHEST = 146;
const REDSTONE_BLOCK = 152; const REDSTONE_BLOCK = 152;
const QUARTZ_BLOCK = 155; const QUARTZ_BLOCK = 155;
@ -231,11 +237,12 @@ class Block extends Position implements Metadatable{
const DARK_OAK_WOOD_STAIRS = 164; const DARK_OAK_WOOD_STAIRS = 164;
const DARK_OAK_WOODEN_STAIRS = 164; const DARK_OAK_WOODEN_STAIRS = 164;
const IRON_TRAPDOOR = 167;
const HAY_BALE = 170; const HAY_BALE = 170;
const CARPET = 171; const CARPET = 171;
const HARDENED_CLAY = 172; const HARDENED_CLAY = 172;
const COAL_BLOCK = 173; const COAL_BLOCK = 173;
const PACKED_ICE = 174;
const DOUBLE_PLANT = 175; const DOUBLE_PLANT = 175;
const FENCE_GATE_SPRUCE = 183; const FENCE_GATE_SPRUCE = 183;
@ -250,7 +257,6 @@ class Block extends Position implements Metadatable{
const BEETROOT_BLOCK = 244; const BEETROOT_BLOCK = 244;
const STONECUTTER = 245; const STONECUTTER = 245;
const GLOWING_OBSIDIAN = 246; const GLOWING_OBSIDIAN = 246;
const NETHER_REACTOR = 247;
/** @var \SplFixedArray */ /** @var \SplFixedArray */
public static $list = null; public static $list = null;
@ -408,9 +414,11 @@ class Block extends Position implements Metadatable{
self::$list[self::MYCELIUM] = Mycelium::class; self::$list[self::MYCELIUM] = Mycelium::class;
self::$list[self::WATER_LILY] = WaterLily::class; self::$list[self::WATER_LILY] = WaterLily::class;
self::$list[self::NETHER_BRICKS] = NetherBrick::class; self::$list[self::NETHER_BRICKS] = NetherBrick::class;
self::$list[self::NETHER_BRICK_FENCE] = NetherBrickFence::class;
self::$list[self::NETHER_BRICKS_STAIRS] = NetherBrickStairs::class; self::$list[self::NETHER_BRICKS_STAIRS] = NetherBrickStairs::class;
self::$list[self::ENCHANTING_TABLE] = EnchantingTable::class;
self::$list[self::BREWING_STAND] = BrewingStand::class;
self::$list[self::END_PORTAL_FRAME] = EndPortalFrame::class; self::$list[self::END_PORTAL_FRAME] = EndPortalFrame::class;
self::$list[self::END_STONE] = EndStone::class; self::$list[self::END_STONE] = EndStone::class;
self::$list[self::SANDSTONE_STAIRS] = SandstoneStairs::class; self::$list[self::SANDSTONE_STAIRS] = SandstoneStairs::class;
@ -421,10 +429,11 @@ class Block extends Position implements Metadatable{
self::$list[self::BIRCH_WOOD_STAIRS] = BirchWoodStairs::class; self::$list[self::BIRCH_WOOD_STAIRS] = BirchWoodStairs::class;
self::$list[self::JUNGLE_WOOD_STAIRS] = JungleWoodStairs::class; self::$list[self::JUNGLE_WOOD_STAIRS] = JungleWoodStairs::class;
self::$list[self::STONE_WALL] = StoneWall::class; self::$list[self::STONE_WALL] = StoneWall::class;
self::$list[self::FLOWER_POT_BLOCK] = FlowerPot::class;
self::$list[self::CARROT_BLOCK] = Carrot::class; self::$list[self::CARROT_BLOCK] = Carrot::class;
self::$list[self::POTATO_BLOCK] = Potato::class; self::$list[self::POTATO_BLOCK] = Potato::class;
self::$list[self::ANVIL] = Anvil::class;
self::$list[self::TRAPPED_CHEST] = TrappedChest::class;
self::$list[self::REDSTONE_BLOCK] = Redstone::class; self::$list[self::REDSTONE_BLOCK] = Redstone::class;
self::$list[self::QUARTZ_BLOCK] = Quartz::class; self::$list[self::QUARTZ_BLOCK] = Quartz::class;
@ -438,11 +447,12 @@ class Block extends Position implements Metadatable{
self::$list[self::ACACIA_WOOD_STAIRS] = AcaciaWoodStairs::class; self::$list[self::ACACIA_WOOD_STAIRS] = AcaciaWoodStairs::class;
self::$list[self::DARK_OAK_WOOD_STAIRS] = DarkOakWoodStairs::class; self::$list[self::DARK_OAK_WOOD_STAIRS] = DarkOakWoodStairs::class;
self::$list[self::IRON_TRAPDOOR] = IronTrapdoor::class;
self::$list[self::HAY_BALE] = HayBale::class; self::$list[self::HAY_BALE] = HayBale::class;
self::$list[self::CARPET] = Carpet::class; self::$list[self::CARPET] = Carpet::class;
self::$list[self::HARDENED_CLAY] = HardenedClay::class; self::$list[self::HARDENED_CLAY] = HardenedClay::class;
self::$list[self::COAL_BLOCK] = Coal::class; self::$list[self::COAL_BLOCK] = Coal::class;
self::$list[self::PACKED_ICE] = PackedIce::class;
self::$list[self::DOUBLE_PLANT] = DoublePlant::class; self::$list[self::DOUBLE_PLANT] = DoublePlant::class;
self::$list[self::FENCE_GATE_SPRUCE] = FenceGateSpruce::class; self::$list[self::FENCE_GATE_SPRUCE] = FenceGateSpruce::class;
@ -457,7 +467,6 @@ class Block extends Position implements Metadatable{
self::$list[self::BEETROOT_BLOCK] = Beetroot::class; self::$list[self::BEETROOT_BLOCK] = Beetroot::class;
self::$list[self::STONECUTTER] = Stonecutter::class; self::$list[self::STONECUTTER] = Stonecutter::class;
self::$list[self::GLOWING_OBSIDIAN] = GlowingObsidian::class; self::$list[self::GLOWING_OBSIDIAN] = GlowingObsidian::class;
self::$list[self::NETHER_REACTOR] = NetherReactor::class;
foreach(self::$list as $id => $class){ foreach(self::$list as $id => $class){
if($class !== null){ if($class !== null){
@ -788,6 +797,10 @@ class Block extends Position implements Metadatable{
$base *= 3.33; $base *= 3.33;
} }
if($item->isSword()){
$base *= 0.5;
}
return $base; return $base;
} }

View File

@ -0,0 +1,46 @@
<?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\block;
use pocketmine\item\Item;
use pocketmine\item\Tool;
class BrewingStand extends Transparent{
protected $id = self::BREWING_STAND;
public function __construct(){
}
public function getName(){
return "Brewing Stand";
}
public function getHardness(){
return 0.5;
}
public function getToolType(){
return Tool::TYPE_PICKAXE;
}
}

View File

@ -49,7 +49,7 @@ class Bricks extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 1){ if($item->isPickaxe() >= Tool::TIER_WOODEN){
return [ return [
[Item::BRICKS_BLOCK, 0, 1], [Item::BRICKS_BLOCK, 0, 1],
]; ];

View File

@ -77,6 +77,17 @@ class BurningFurnace extends Solid{
new Int("z", $this->z) new Int("z", $this->z)
]); ]);
$nbt->Items->setTagType(NBT::TAG_Compound); $nbt->Items->setTagType(NBT::TAG_Compound);
if($item->hasCustomName()){
$nbt->CustomName = new String("CustomName", $item->getCustomName());
}
if($item->hasCustomBlockData()){
foreach($item->getCustomBlockData() as $key => $v){
$nbt->{$key} = $v;
}
}
Tile::createTile("Furnace", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt); Tile::createTile("Furnace", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
return true; return true;
@ -106,6 +117,12 @@ class BurningFurnace extends Solid{
$furnace = Tile::createTile("Furnace", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt); $furnace = Tile::createTile("Furnace", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
} }
if(isset($furnace->namedtag->Lock) and $furnace->namedtag->Lock instanceof String){
if($furnace->namedtag->Lock->getValue() !== $item->getCustomName()){
return true;
}
}
if($player->isCreative()){ if($player->isCreative()){
return true; return true;
} }
@ -118,7 +135,7 @@ class BurningFurnace extends Solid{
public function getDrops(Item $item){ public function getDrops(Item $item){
$drops = []; $drops = [];
if($item->isPickaxe() >= 1){ if($item->isPickaxe() >= Tool::TIER_WOODEN){
$drops[] = [Item::FURNACE, 0, 1]; $drops[] = [Item::FURNACE, 0, 1];
} }

View File

@ -26,7 +26,7 @@ use pocketmine\item\Item;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\math\AxisAlignedBB; use pocketmine\math\AxisAlignedBB;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\Server;
class Cake extends Transparent{ class Cake extends Transparent{

View File

@ -104,6 +104,17 @@ class Chest extends Transparent{
new Int("z", $this->z) new Int("z", $this->z)
]); ]);
$nbt->Items->setTagType(NBT::TAG_Compound); $nbt->Items->setTagType(NBT::TAG_Compound);
if($item->hasCustomName()){
$nbt->CustomName = new String("CustomName", $item->getCustomName());
}
if($item->hasCustomBlockData()){
foreach($item->getCustomBlockData() as $key => $v){
$nbt->{$key} = $v;
}
}
$tile = Tile::createTile("Chest", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt); $tile = Tile::createTile("Chest", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
if($chest instanceof TileChest and $tile instanceof TileChest){ if($chest instanceof TileChest and $tile instanceof TileChest){
@ -147,6 +158,11 @@ class Chest extends Transparent{
$chest = Tile::createTile("Chest", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt); $chest = Tile::createTile("Chest", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
} }
if(isset($chest->namedtag->Lock) and $chest->namedtag->Lock instanceof String){
if($chest->namedtag->Lock->getValue() !== $item->getCustomName()){
return true;
}
}
if($player->isCreative()){ if($player->isCreative()){
return true; return true;

View File

@ -45,7 +45,7 @@ class Coal extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 1){ if($item->isPickaxe() >= Tool::TIER_WOODEN){
return [ return [
[Item::COAL_BLOCK, 0, 1], [Item::COAL_BLOCK, 0, 1],
]; ];

View File

@ -45,7 +45,7 @@ class CoalOre extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 1){ if($item->isPickaxe() >= Tool::TIER_WOODEN){
return [ return [
[Item::COAL, 0, 1], [Item::COAL, 0, 1],
]; ];

View File

@ -45,7 +45,7 @@ class Cobblestone extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 1){ if($item->isPickaxe() >= Tool::TIER_WOODEN){
return [ return [
[Item::COBBLESTONE, 0, 1], [Item::COBBLESTONE, 0, 1],
]; ];

View File

@ -45,7 +45,7 @@ class Diamond extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 4){ if($item->isPickaxe() >= Tool::TIER_IRON){
return [ return [
[Item::DIAMOND_BLOCK, 0, 1], [Item::DIAMOND_BLOCK, 0, 1],
]; ];

View File

@ -45,7 +45,7 @@ class DiamondOre extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 4){ if($item->isPickaxe() >= Tool::TIER_IRON){
return [ return [
[Item::DIAMOND, 0, 1], [Item::DIAMOND, 0, 1],
]; ];

View File

@ -26,9 +26,7 @@ use pocketmine\level\Level;
use pocketmine\level\sound\DoorSound; use pocketmine\level\sound\DoorSound;
use pocketmine\math\AxisAlignedBB; use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\network\protocol\LevelEventPacket;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\Server;
abstract class Door extends Transparent{ abstract class Door extends Transparent{

View File

@ -49,13 +49,13 @@ class DoubleSlab extends Solid{
4 => "Brick", 4 => "Brick",
5 => "Stone Brick", 5 => "Stone Brick",
6 => "Quartz", 6 => "Quartz",
7 => "", 7 => "Nether Brick",
]; ];
return "Double " . $names[$this->meta & 0x07] . " Slab"; return "Double " . $names[$this->meta & 0x07] . " Slab";
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 1){ if($item->isPickaxe() >= Tool::TIER_WOODEN){
return [ return [
[Item::SLAB, $this->meta & 0x07, 2], [Item::SLAB, $this->meta & 0x07, 2],
]; ];

View File

@ -45,7 +45,7 @@ class Emerald extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 4){ if($item->isPickaxe() >= Tool::TIER_IRON){
return [ return [
[Item::EMERALD_BLOCK, 0, 1], [Item::EMERALD_BLOCK, 0, 1],
]; ];

View File

@ -45,7 +45,7 @@ class EmeraldOre extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 4){ if($item->isPickaxe() >= Tool::TIER_IRON){
return [ return [
[Item::EMERALD, 0, 1], [Item::EMERALD, 0, 1],
]; ];

View File

@ -0,0 +1,108 @@
<?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\block;
use pocketmine\inventory\EnchantInventory;
use pocketmine\item\Item;
use pocketmine\item\Tool;
use pocketmine\nbt\tag\Compound;
use pocketmine\nbt\tag\Int;
use pocketmine\nbt\tag\String;
use pocketmine\Player;
use pocketmine\tile\Tile;
class EnchantingTable extends Transparent{
protected $id = self::ENCHANTING_TABLE;
public function __construct(){
}
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
$this->getLevel()->setBlock($block, $this, true, true);
$nbt = new Compound("", [
new String("id", Tile::ENCHANT_TABLE),
new Int("x", $this->x),
new Int("y", $this->y),
new Int("z", $this->z)
]);
if($item->hasCustomName()){
$nbt->CustomName = new String("CustomName", $item->getCustomName());
}
if($item->hasCustomBlockData()){
foreach($item->getCustomBlockData() as $key => $v){
$nbt->{$key} = $v;
}
}
Tile::createTile(Tile::ENCHANT_TABLE, $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
return true;
}
public function canBeActivated(){
return true;
}
public function getHardness(){
return 5;
}
public function getResistance(){
return 6000;
}
public function getName(){
return "Enchanting Table";
}
public function getToolType(){
return Tool::TYPE_PICKAXE;
}
public function onActivate(Item $item, Player $player = null){
if($player instanceof Player){
//TODO lock
if($player->isCreative()){
return true;
}
$player->addWindow(new EnchantInventory($this));
}
return true;
}
public function getDrops(Item $item){
if($item->isPickaxe() >= Tool::TIER_WOODEN){
return [
[$this->id, 0, 1],
];
}else{
return [];
}
}
}

View File

@ -21,7 +21,7 @@
namespace pocketmine\block; namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\item\Tool; use pocketmine\item\Tool;
class EndStone extends Solid{ class EndStone extends Solid{

View File

@ -26,6 +26,12 @@ use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
class Fence extends Transparent{ class Fence extends Transparent{
const FENCE_OAK = 0;
const FENCE_SPRUCE = 1;
const FENCE_BIRCH = 2;
const FENCE_JUNGLE = 3;
const FENCE_ACACIA = 4;
const FENCE_DARKOAK = 5;
protected $id = self::FENCE; protected $id = self::FENCE;
@ -38,18 +44,18 @@ class Fence extends Transparent{
} }
public function getToolType(){ public function getToolType(){
return Tool::TYPE_PICKAXE; return Tool::TYPE_AXE;
} }
public function getName(){ public function getName(){
static $names = [ static $names = [
0 => "Oak Fence", self::FENCE_OAK => "Oak Fence",
1 => "Spruce Fence", self::FENCE_SPRUCE => "Spruce Fence",
2 => "Birch Fence", self::FENCE_BIRCH => "Birch Fence",
3 => "Jungle Fence", self::FENCE_JUNGLE => "Jungle Fence",
4 => "Acacia Fence", self::FENCE_ACACIA => "Acacia Fence",
5 => "Dark Oak Fence", self::FENCE_DARKOAK => "Dark Oak Fence",
"", "",
"" ""
]; ];

View File

@ -22,7 +22,7 @@
namespace pocketmine\block; namespace pocketmine\block;
use pocketmine\item\Item;
abstract class Flowable extends Transparent{ abstract class Flowable extends Transparent{

View File

@ -21,21 +21,18 @@
namespace pocketmine\block; namespace pocketmine\block;
use pocketmine\item\Item;
class NetherReactor extends Solid{ class FlowerPot extends Transparent{
protected $id = self::NETHER_REACTOR; protected $id = self::FLOWER_POT_BLOCK;
public function __construct($meta = 0){ public function __construct($meta = 0){
$this->meta = $meta; $this->meta = $meta;
} }
public function getName(){ public function getName(){
return "Nether Reactor"; return "Flower Pot Block";
}
public function canBeActivated(){
return true;
} }
} }

View File

@ -60,7 +60,7 @@ class GlowingRedstoneOre extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 4){ if($item->isPickaxe() >= Tool::TIER_IRON){
return [ return [
[Item::REDSTONE_DUST, 0, mt_rand(4, 5)], [Item::REDSTONE_DUST, 0, mt_rand(4, 5)],
]; ];

View File

@ -45,7 +45,7 @@ class Gold extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 4){ if($item->isPickaxe() >= Tool::TIER_IRON){
return [ return [
[Item::GOLD_BLOCK, 0, 1], [Item::GOLD_BLOCK, 0, 1],
]; ];

View File

@ -45,7 +45,7 @@ class GoldOre extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 4){ if($item->isPickaxe() >= Tool::TIER_IRON){
return [ return [
[Item::GOLD_ORE, 0, 1], [Item::GOLD_ORE, 0, 1],
]; ];

View File

@ -21,16 +21,13 @@
namespace pocketmine\block; namespace pocketmine\block;
use pocketmine\event\block\BlockSpreadEvent;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\item\Tool; use pocketmine\item\Tool;
use pocketmine\level\generator\object\TallGrass as TallGrassObject;
use pocketmine\level\Level;
use pocketmine\math\AxisAlignedBB; use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Vector3;
use pocketmine\Player;
use pocketmine\Server;
use pocketmine\utils\Random;
class GrassPath extends Transparent{ class GrassPath extends Transparent{

View File

@ -21,7 +21,7 @@
namespace pocketmine\block; namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\item\Tool; use pocketmine\item\Tool;
class HardenedClay extends Solid{ class HardenedClay extends Solid{

View File

@ -45,7 +45,7 @@ class Iron extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 3){ if($item->isPickaxe() >= Tool::TIER_STONE){
return [ return [
[Item::IRON_BLOCK, 0, 1], [Item::IRON_BLOCK, 0, 1],
]; ];

View File

@ -45,7 +45,7 @@ class IronBars extends Thin{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 1){ if($item->isPickaxe() >= Tool::TIER_WOODEN){
return [ return [
[Item::IRON_BARS, 0, 1], [Item::IRON_BARS, 0, 1],
]; ];

View File

@ -45,7 +45,7 @@ class IronDoor extends Door{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 1){ if($item->isPickaxe() >= Tool::TIER_WOODEN){
return [ return [
[Item::IRON_DOOR, 0, 1], [Item::IRON_DOOR, 0, 1],
]; ];

View File

@ -45,7 +45,7 @@ class IronOre extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 3){ if($item->isPickaxe() >= Tool::TIER_STONE){
return [ return [
[Item::IRON_ORE, 0, 1], [Item::IRON_ORE, 0, 1],
]; ];

View File

@ -0,0 +1,156 @@
<?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\block;
use pocketmine\item\Item;
use pocketmine\item\Tool;
use pocketmine\math\AxisAlignedBB;
use pocketmine\Player;
class IronTrapdoor extends Transparent{
protected $id = self::IRON_TRAPDOOR;
public function __construct($meta = 0){
$this->meta = $meta;
}
public function getName(){
return "Iron Trapdoor";
}
public function getHardness(){
return 5;
}
public function canBeActivated(){
return true;
}
protected function recalculateBoundingBox(){
$damage = $this->getDamage();
$f = 0.1875;
if(($damage & 0x08) > 0){
$bb = new AxisAlignedBB(
$this->x,
$this->y + 1 - $f,
$this->z,
$this->x + 1,
$this->y + 1,
$this->z + 1
);
}else{
$bb = new AxisAlignedBB(
$this->x,
$this->y,
$this->z,
$this->x + 1,
$this->y + $f,
$this->z + 1
);
}
if(($damage & 0x04) > 0){
if(($damage & 0x03) === 0){
$bb->setBounds(
$this->x,
$this->y,
$this->z + 1 - $f,
$this->x + 1,
$this->y + 1,
$this->z + 1
);
}elseif(($damage & 0x03) === 1){
$bb->setBounds(
$this->x,
$this->y,
$this->z,
$this->x + 1,
$this->y + 1,
$this->z + $f
);
}
if(($damage & 0x03) === 2){
$bb->setBounds(
$this->x + 1 - $f,
$this->y,
$this->z,
$this->x + 1,
$this->y + 1,
$this->z + 1
);
}
if(($damage & 0x03) === 3){
$bb->setBounds(
$this->x,
$this->y,
$this->z,
$this->x + $f,
$this->y + 1,
$this->z + 1
);
}
}
return $bb;
}
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
if(($target->isTransparent() === false or $target->getId() === self::SLAB) and $face !== 0 and $face !== 1){
$faces = [
2 => 0,
3 => 1,
4 => 2,
5 => 3,
];
$this->meta = $faces[$face] & 0x03;
if($fy > 0.5){
$this->meta |= 0x08;
}
$this->getLevel()->setBlock($block, $this, true, true);
return true;
}
return false;
}
public function getDrops(Item $item){
return [
[$this->id, 0, 1],
];
}
public function onActivate(Item $item, Player $player = null){
$this->meta ^= 0x04;
$this->getLevel()->setBlock($this, $this, true);
$this->level->addSound(new DoorSound($this));
return true;
}
public function getToolType(){
return Tool::TYPE_PICKAXE;
}
}

View File

@ -45,7 +45,7 @@ class Lapis extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 3){ if($item->isPickaxe() >= Tool::TIER_STONE){
return [ return [
[Item::LAPIS_BLOCK, 0, 1], [Item::LAPIS_BLOCK, 0, 1],
]; ];

View File

@ -45,7 +45,7 @@ class LapisOre extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 3){ if($item->isPickaxe() >= Tool::TIER_STONE){
return [ return [
[Item::DYE, 4, mt_rand(4, 8)], [Item::DYE, 4, mt_rand(4, 8)],
]; ];

View File

@ -45,7 +45,7 @@ class MossStone extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 1){ if($item->isPickaxe() >= Tool::TIER_WOODEN){
return [ return [
[Item::MOSS_STONE, $this->meta, 1], [Item::MOSS_STONE, $this->meta, 1],
]; ];

View File

@ -45,7 +45,7 @@ class NetherBrick extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 1){ if($item->isPickaxe() >= Tool::TIER_WOODEN){
return [ return [
[Item::NETHER_BRICKS, 0, 1], [Item::NETHER_BRICKS, 0, 1],
]; ];

View File

@ -0,0 +1,71 @@
<?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\block;
use pocketmine\item\Item;
use pocketmine\item\Tool;
class NetherBrickFence extends Transparent {
protected $id = self::NETHER_BRICK_FENCE;
public function __construct($meta = 0){
$this->meta = $meta;
}
public function getBreakTime(Item $item){
if ($item instanceof Air){
//Breaking by hand
return 10;
}
else{
// Other breaktimes are equal to woodfences.
return parent::getBreakTime($item);
}
}
public function getHardness(){
return 2;
}
public function getToolType(){
return Tool::TYPE_PICKAXE;
}
public function getName(){
return "Nether Brick Fence";
}
public function canConnect(Block $block){
//TODO: activate comments when the NetherBrickFenceGate class has been created.
return ($block instanceof NetherBrickFence /* or $block instanceof NetherBrickFenceGate */) ? true : $block->isSolid() and !$block->isTransparent();
}
public function getDrops(Item $item){
if($item->isPickaxe() >= Tool::TIER_WOODEN){
return [
[$this->id, $this->meta, 1],
];
}else{
return [];
}
}
}

View File

@ -45,7 +45,7 @@ class Netherrack extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 1){ if($item->isPickaxe() >= Tool::TIER_WOODEN){
return [ return [
[Item::NETHERRACK, 0, 1], [Item::NETHERRACK, 0, 1],
]; ];

View File

@ -45,7 +45,7 @@ class Obsidian extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 5){ if($item->isPickaxe() >= Tool::TIER_DIAMOND){
return [ return [
[Item::OBSIDIAN, 0, 1], [Item::OBSIDIAN, 0, 1],
]; ];

View File

@ -0,0 +1,47 @@
<?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\block;
use pocketmine\item\Item;
use pocketmine\item\Tool;
class PackedIce extends Solid{
protected $id = self::PACKED_ICE;
public function __construct(){
}
public function getName(){
return "Packed Ice";
}
public function getHardness(){
return 0.5;
}
public function getToolType(){
return Tool::TYPE_PICKAXE;
}
}

View File

@ -26,6 +26,11 @@ use pocketmine\item\Tool;
class Quartz extends Solid{ class Quartz extends Solid{
const QUARTZ_NORMAL = 0;
const QUARTZ_CHISELED = 1;
const QUARTZ_PILLAR = 2;
const QUARTZ_PILLAR2 = 3;
protected $id = self::QUARTZ_BLOCK; protected $id = self::QUARTZ_BLOCK;
public function __construct($meta = 0){ public function __construct($meta = 0){
@ -38,10 +43,10 @@ class Quartz extends Solid{
public function getName(){ public function getName(){
static $names = [ static $names = [
0 => "Quartz Block", self::QUARTZ_NORMAL => "Quartz Block",
1 => "Chiseled Quartz Block", self::QUARTZ_CHISELED => "Chiseled Quartz Block",
2 => "Quartz Pillar", self::QUARTZ_PILLAR => "Quartz Pillar",
3 => "Quartz Pillar", self::QUARTZ_PILLAR2 => "Quartz Pillar",
]; ];
return $names[$this->meta & 0x03]; return $names[$this->meta & 0x03];
} }
@ -51,7 +56,7 @@ class Quartz extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 1){ if($item->isPickaxe() >= Tool::TIER_WOODEN){
return [ return [
[Item::QUARTZ_BLOCK, $this->meta & 0x03, 1], [Item::QUARTZ_BLOCK, $this->meta & 0x03, 1],
]; ];

View File

@ -45,7 +45,7 @@ class Redstone extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 1){ if($item->isPickaxe() >= Tool::TIER_WOODEN){
return [ return [
[Item::REDSTONE_BLOCK, 0, 1], [Item::REDSTONE_BLOCK, 0, 1],
]; ];

View File

@ -58,7 +58,7 @@ class RedstoneOre extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 2){ if($item->isPickaxe() >= Tool::TIER_GOLD){
return [ return [
[Item::REDSTONE_DUST, 0, mt_rand(4, 5)], [Item::REDSTONE_DUST, 0, mt_rand(4, 5)],
]; ];

View File

@ -26,6 +26,10 @@ use pocketmine\item\Tool;
class Sandstone extends Solid{ class Sandstone extends Solid{
const NORMAL = 0;
const CHISELED = 1;
const SMOOTH = 2;
protected $id = self::SANDSTONE; protected $id = self::SANDSTONE;
public function __construct($meta = 0){ public function __construct($meta = 0){
@ -38,9 +42,9 @@ class Sandstone extends Solid{
public function getName(){ public function getName(){
static $names = [ static $names = [
0 => "Sandstone", self::NORMAL => "Sandstone",
1 => "Chiseled Sandstone", self::CHISELED => "Chiseled Sandstone",
2 => "Smooth Sandstone", self::SMOOTH => "Smooth Sandstone",
3 => "", 3 => "",
]; ];
return $names[$this->meta & 0x03]; return $names[$this->meta & 0x03];
@ -51,7 +55,7 @@ class Sandstone extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 1){ if($item->isPickaxe() >= Tool::TIER_WOODEN){
return [ return [
[Item::SANDSTONE, $this->meta & 0x03, 1], [Item::SANDSTONE, $this->meta & 0x03, 1],
]; ];

View File

@ -88,7 +88,7 @@ class SignPost extends Transparent{
} }
public function onBreak(Item $item){ public function onBreak(Item $item){
$this->getLevel()->setBlock($this, new Air(), true, true, true); $this->getLevel()->setBlock($this, new Air(), true, true);
return true; return true;
} }

View File

@ -27,6 +27,14 @@ use pocketmine\math\AxisAlignedBB;
use pocketmine\Player; use pocketmine\Player;
class Slab extends Transparent{ class Slab extends Transparent{
const STONE = 0;
const SANDSTONE = 1;
const WOODEN = 2;
const COBBLESTONE = 3;
const BRICK = 4;
const STONE_BRICK = 5;
const QUARTZ = 6;
const NETHER_BRICK = 7;
protected $id = self::SLAB; protected $id = self::SLAB;
@ -40,14 +48,14 @@ class Slab extends Transparent{
public function getName(){ public function getName(){
static $names = [ static $names = [
0 => "Stone", self::STONE => "Stone",
1 => "Sandstone", self::SANDSTONE => "Sandstone",
2 => "Wooden", self::WOODEN => "Wooden",
3 => "Cobblestone", self::COBBLESTONE => "Cobblestone",
4 => "Brick", self::BRICK => "Brick",
5 => "Stone Brick", self::STONE_BRICK => "Stone Brick",
6 => "Quartz", self::QUARTZ => "Quartz",
7 => "", self::NETHER_BRICK => "Nether Brick",
]; ];
return (($this->meta & 0x08) > 0 ? "Upper " : "") . $names[$this->meta & 0x07] . " Slab"; return (($this->meta & 0x08) > 0 ? "Upper " : "") . $names[$this->meta & 0x07] . " Slab";
} }
@ -125,7 +133,7 @@ class Slab extends Transparent{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 1){ if($item->isPickaxe() >= Tool::TIER_WOODEN){
return [ return [
[$this->id, $this->meta & 0x07, 1], [$this->id, $this->meta & 0x07, 1],
]; ];

View File

@ -21,7 +21,7 @@
namespace pocketmine\block; namespace pocketmine\block;
use pocketmine\item\Item;
use pocketmine\item\Tool; use pocketmine\item\Tool;
class StainedClay extends Solid{ class StainedClay extends Solid{

View File

@ -143,7 +143,7 @@ abstract class Stair extends Transparent{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 1){ if($item->isPickaxe() >= Tool::TIER_WOODEN){
return [ return [
[$this->getId(), 0, 1], [$this->getId(), 0, 1],
]; ];

View File

@ -37,7 +37,6 @@ class Stone extends Solid{
public function __construct($meta = 0){ public function __construct($meta = 0){
$this->meta = $meta; $this->meta = $meta;
} }
public function getHardness(){ public function getHardness(){

View File

@ -25,6 +25,10 @@ use pocketmine\item\Item;
use pocketmine\item\Tool; use pocketmine\item\Tool;
class StoneBricks extends Solid{ class StoneBricks extends Solid{
const NORMAL = 0;
const MOSSY = 1;
const CRACKED = 2;
const CHISELED = 3;
protected $id = self::STONE_BRICKS; protected $id = self::STONE_BRICKS;
@ -42,16 +46,16 @@ class StoneBricks extends Solid{
public function getName(){ public function getName(){
static $names = [ static $names = [
0 => "Stone Bricks", self::NORMAL => "Stone Bricks",
1 => "Mossy Stone Bricks", self::MOSSY => "Mossy Stone Bricks",
2 => "Cracked Stone Bricks", self::CRACKED => "Cracked Stone Bricks",
3 => "Chiseled Stone Bricks", self::CHISELED => "Chiseled Stone Bricks",
]; ];
return $names[$this->meta & 0x03]; return $names[$this->meta & 0x03];
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 1){ if($item->isPickaxe() >= Tool::TIER_WOODEN){
return [ return [
[Item::STONE_BRICKS, $this->meta & 0x03, 1], [Item::STONE_BRICKS, $this->meta & 0x03, 1],
]; ];

View File

@ -27,6 +27,8 @@ use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
class StoneWall extends Transparent{ class StoneWall extends Transparent{
const NONE_MOSSY_WALL = 0;
const MOSSY_WALL = 1;
protected $id = self::STONE_WALL; protected $id = self::STONE_WALL;

View File

@ -55,7 +55,7 @@ class Stonecutter extends Solid{
} }
public function getDrops(Item $item){ public function getDrops(Item $item){
if($item->isPickaxe() >= 1){ if($item->isPickaxe() >= Tool::TIER_WOODEN){
return [ return [
[Item::STONECUTTER, 0, 1], [Item::STONECUTTER, 0, 1],
]; ];

View File

@ -0,0 +1,181 @@
<?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\block;
use pocketmine\item\Item;
use pocketmine\item\Tool;
use pocketmine\math\AxisAlignedBB;
use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Compound;
use pocketmine\nbt\tag\Enum;
use pocketmine\nbt\tag\Int;
use pocketmine\nbt\tag\String;
use pocketmine\Player;
use pocketmine\tile\Chest as TileChest;
use pocketmine\tile\Tile;
class TrappedChest extends Transparent{
protected $id = self::CHEST;
public function __construct($meta = 0){
$this->meta = $meta;
}
public function canBeActivated(){
return true;
}
public function getHardness(){
return 2.5;
}
public function getName(){
return "Trapped Chest";
}
public function getToolType(){
return Tool::TYPE_AXE;
}
protected function recalculateBoundingBox(){
return new AxisAlignedBB(
$this->x + 0.0625,
$this->y,
$this->z + 0.0625,
$this->x + 0.9375,
$this->y + 0.9475,
$this->z + 0.9375
);
}
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
$faces = [
0 => 4,
1 => 2,
2 => 5,
3 => 3,
];
$chest = null;
$this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0];
for($side = 2; $side <= 5; ++$side){
if(($this->meta === 4 or $this->meta === 5) and ($side === 4 or $side === 5)){
continue;
}elseif(($this->meta === 3 or $this->meta === 2) and ($side === 2 or $side === 3)){
continue;
}
$c = $this->getSide($side);
if($c instanceof Chest and $c->getDamage() === $this->meta){
$tile = $this->getLevel()->getTile($c);
if($tile instanceof TileChest and !$tile->isPaired()){
$chest = $tile;
break;
}
}
}
$this->getLevel()->setBlock($block, $this, true, true);
$nbt = new Compound("", [
new Enum("Items", []),
new String("id", Tile::CHEST),
new Int("x", $this->x),
new Int("y", $this->y),
new Int("z", $this->z)
]);
$nbt->Items->setTagType(NBT::TAG_Compound);
if($item->hasCustomName()){
$nbt->CustomName = new String("CustomName", $item->getCustomName());
}
if($item->hasCustomBlockData()){
foreach($item->getCustomBlockData() as $key => $v){
$nbt->{$key} = $v;
}
}
$tile = Tile::createTile("Chest", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
if($chest instanceof TileChest and $tile instanceof TileChest){
$chest->pairWith($tile);
$tile->pairWith($chest);
}
return true;
}
public function onBreak(Item $item){
$t = $this->getLevel()->getTile($this);
if($t instanceof TileChest){
$t->unpair();
}
$this->getLevel()->setBlock($this, new Air(), true, true);
return true;
}
public function onActivate(Item $item, Player $player = null){
if($player instanceof Player){
$top = $this->getSide(1);
if($top->isTransparent() !== true){
return true;
}
$t = $this->getLevel()->getTile($this);
$chest = null;
if($t instanceof TileChest){
$chest = $t;
}else{
$nbt = new Compound("", [
new Enum("Items", []),
new String("id", Tile::CHEST),
new Int("x", $this->x),
new Int("y", $this->y),
new Int("z", $this->z)
]);
$nbt->Items->setTagType(NBT::TAG_Compound);
$chest = Tile::createTile("Chest", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
}
if(isset($chest->namedtag->Lock) and $chest->namedtag->Lock instanceof String){
if($chest->namedtag->Lock->getValue() !== $item->getCustomName()){
return true;
}
}
if($player->isCreative()){
return true;
}
$player->addWindow($chest->getInventory());
}
return true;
}
public function getDrops(Item $item){
return [
[$this->id, 0, 1],
];
}
}

View File

@ -22,6 +22,8 @@
namespace pocketmine\block; namespace pocketmine\block;
use pocketmine\level\Level;
class WallSign extends SignPost{ class WallSign extends SignPost{
protected $id = self::WALL_SIGN; protected $id = self::WALL_SIGN;
@ -31,6 +33,20 @@ class WallSign extends SignPost{
} }
public function onUpdate($type){ public function onUpdate($type){
$faces = [
2 => 3,
3 => 2,
4 => 5,
5 => 4,
];
if($type === Level::BLOCK_UPDATE_NORMAL){
if(isset($faces[$this->meta])) {
if ($this->getSide($faces[$this->meta])->getId() === self::AIR) {
$this->getLevel()->useBreakOn($this);
}
return Level::BLOCK_UPDATE_NORMAL;
}
}
return false; return false;
} }
} }

View File

@ -21,9 +21,9 @@
namespace pocketmine\block; namespace pocketmine\block;
use pocketmine\entity\Entity;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\item\Tool;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\math\AxisAlignedBB; use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;

View File

@ -23,7 +23,7 @@ namespace pocketmine\command;
use pocketmine\event\TranslationContainer; use pocketmine\event\TranslationContainer;
use pocketmine\plugin\Plugin; use pocketmine\plugin\Plugin;
use pocketmine\utils\TextFormat;
class PluginCommand extends Command implements PluginIdentifiableCommand{ class PluginCommand extends Command implements PluginIdentifiableCommand{

View File

@ -29,6 +29,7 @@ use pocketmine\command\defaults\DeopCommand;
use pocketmine\command\defaults\DifficultyCommand; use pocketmine\command\defaults\DifficultyCommand;
use pocketmine\command\defaults\DumpMemoryCommand; use pocketmine\command\defaults\DumpMemoryCommand;
use pocketmine\command\defaults\EffectCommand; use pocketmine\command\defaults\EffectCommand;
use pocketmine\command\defaults\EnchantCommand;
use pocketmine\command\defaults\GamemodeCommand; use pocketmine\command\defaults\GamemodeCommand;
use pocketmine\command\defaults\GarbageCollectorCommand; use pocketmine\command\defaults\GarbageCollectorCommand;
use pocketmine\command\defaults\GiveCommand; use pocketmine\command\defaults\GiveCommand;
@ -105,6 +106,7 @@ class SimpleCommandMap implements CommandMap{
$this->register("pocketmine", new SaveCommand("save-all")); $this->register("pocketmine", new SaveCommand("save-all"));
$this->register("pocketmine", new GiveCommand("give")); $this->register("pocketmine", new GiveCommand("give"));
$this->register("pocketmine", new EffectCommand("effect")); $this->register("pocketmine", new EffectCommand("effect"));
$this->register("pocketmine", new EnchantCommand("enchant"));
$this->register("pocketmine", new ParticleCommand("particle")); $this->register("pocketmine", new ParticleCommand("particle"));
$this->register("pocketmine", new GamemodeCommand("gamemode")); $this->register("pocketmine", new GamemodeCommand("gamemode"));
$this->register("pocketmine", new KillCommand("kill")); $this->register("pocketmine", new KillCommand("kill"));

View File

@ -25,7 +25,7 @@ use pocketmine\command\Command;
use pocketmine\command\CommandSender; use pocketmine\command\CommandSender;
use pocketmine\event\TranslationContainer; use pocketmine\event\TranslationContainer;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\utils\TextFormat;
class BanCommand extends VanillaCommand{ class BanCommand extends VanillaCommand{

View File

@ -25,7 +25,7 @@ use pocketmine\command\Command;
use pocketmine\command\CommandSender; use pocketmine\command\CommandSender;
use pocketmine\event\TranslationContainer; use pocketmine\event\TranslationContainer;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\utils\TextFormat;
class BanIpCommand extends VanillaCommand{ class BanIpCommand extends VanillaCommand{

View File

@ -64,9 +64,9 @@ class BanListCommand extends VanillaCommand{
} }
if($args[0] === "ips"){ if($args[0] === "ips"){
$sender->sendMessage("commands.banlist.ips", [count($list)]); $sender->sendMessage(new TranslationContainer("commands.banlist.ips", [count($list)]));
}else{ }else{
$sender->sendMessage("commands.banlist.players", [count($list)]); $sender->sendMessage(new TranslationContainer("commands.banlist.players", [count($list)]));
} }
$sender->sendMessage(substr($message, 0, -2)); $sender->sendMessage(substr($message, 0, -2));

View File

@ -24,7 +24,7 @@ namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender; use pocketmine\command\CommandSender;
use pocketmine\event\TranslationContainer; use pocketmine\event\TranslationContainer;
use pocketmine\Server; use pocketmine\Server;
use pocketmine\utils\TextFormat;
class DefaultGamemodeCommand extends VanillaCommand{ class DefaultGamemodeCommand extends VanillaCommand{

View File

@ -27,7 +27,7 @@ use pocketmine\event\TranslationContainer;
use pocketmine\network\Network; use pocketmine\network\Network;
use pocketmine\network\protocol\SetDifficultyPacket; use pocketmine\network\protocol\SetDifficultyPacket;
use pocketmine\Server; use pocketmine\Server;
use pocketmine\utils\TextFormat;
class DifficultyCommand extends VanillaCommand{ class DifficultyCommand extends VanillaCommand{
@ -62,7 +62,7 @@ class DifficultyCommand extends VanillaCommand{
$pk = new SetDifficultyPacket(); $pk = new SetDifficultyPacket();
$pk->difficulty = $sender->getServer()->getDifficulty(); $pk->difficulty = $sender->getServer()->getDifficulty();
Server::broadcastPacket($sender->getServer()->getOnlinePlayers(), $pk->setChannel(Network::CHANNEL_WORLD_EVENTS)); Server::broadcastPacket($sender->getServer()->getOnlinePlayers(), $pk);
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.difficulty.success", [$difficulty])); Command::broadcastCommandMessage($sender, new TranslationContainer("commands.difficulty.success", [$difficulty]));
}else{ }else{

View File

@ -22,8 +22,7 @@
namespace pocketmine\command\defaults; namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender; use pocketmine\command\CommandSender;
use pocketmine\utils\TextFormat;
use pocketmine\utils\Utils;
class DumpMemoryCommand extends VanillaCommand{ class DumpMemoryCommand extends VanillaCommand{

View File

@ -21,7 +21,7 @@
namespace pocketmine\command\defaults; namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender; use pocketmine\command\CommandSender;
use pocketmine\entity\Effect; use pocketmine\entity\Effect;
use pocketmine\entity\InstantEffect; use pocketmine\entity\InstantEffect;

View File

@ -0,0 +1,86 @@
<?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\command\defaults;
use pocketmine\command\CommandSender;
use pocketmine\entity\Effect;
use pocketmine\entity\InstantEffect;
use pocketmine\event\TranslationContainer;
use pocketmine\item\enchantment\Enchantment;
use pocketmine\utils\TextFormat;
class EnchantCommand extends VanillaCommand{
public function __construct($name){
parent::__construct(
$name,
"%pocketmine.command.enchant.description",
"%commands.enchant.usage"
);
$this->setPermission("pocketmine.command.enchant");
}
public function execute(CommandSender $sender, $currentAlias, array $args){
if(!$this->testPermission($sender)){
return true;
}
if(count($args) < 2){
$sender->sendMessage(new TranslationContainer("commands.generic.usage", [$this->usageMessage]));
return true;
}
$player = $sender->getServer()->getPlayer($args[0]);
if($player === null){
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound"));
return true;
}
$enchantId = (int) $args[1];
$enchantLevel = isset($args[2]) ? (int) $args[2] : 1;
$enchantment = Enchantment::getEnchantment($enchantId);
if($enchantment->getId() === Enchantment::TYPE_INVALID){
$sender->sendMessage(new TranslationContainer("commands.enchant.notFound", [$enchantId]));
return true;
}
$enchantment->setLevel($enchantLevel);
$item = $player->getInventory()->getItemInHand();
if($item->getId() <= 0){
$sender->sendMessage(new TranslationContainer("commands.enchant.noItem"));
return true;
}
$item->addEnchantment($enchantment);
$player->getInventory()->setItemInHand($item);
self::broadcastCommandMessage($sender, new TranslationContainer("%commands.enchant.success"));
return true;
}
}

View File

@ -23,7 +23,7 @@ namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender; use pocketmine\command\CommandSender;
use pocketmine\utils\TextFormat; use pocketmine\utils\TextFormat;
use pocketmine\utils\Utils;
class GarbageCollectorCommand extends VanillaCommand{ class GarbageCollectorCommand extends VanillaCommand{

View File

@ -25,6 +25,8 @@ use pocketmine\command\Command;
use pocketmine\command\CommandSender; use pocketmine\command\CommandSender;
use pocketmine\event\TranslationContainer; use pocketmine\event\TranslationContainer;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Compound;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\utils\TextFormat; use pocketmine\utils\TextFormat;
@ -59,6 +61,23 @@ class GiveCommand extends VanillaCommand{
$item->setCount((int) $args[2]); $item->setCount((int) $args[2]);
} }
if(isset($args[3])){
$tags = $exception = null;
$data = implode(" ", array_slice($args, 3));
try{
$tags = NBT::parseJSON($data);
}catch (\Exception $ex){
$exception = $ex;
}
if(!($tags instanceof Compound) or $exception !== null){
$sender->sendMessage(new TranslationContainer("commands.give.tagError", [$exception !== null ? $exception->getMessage() : "Invalid tag conversion"]));
return true;
}
$item->setNamedTag($tags);
}
if($player instanceof Player){ if($player instanceof Player){
if($item->getId() === 0){ if($item->getId() === 0){
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.give.item.notFound", [$args[1]])); $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.give.item.notFound", [$args[1]]));

View File

@ -24,7 +24,7 @@ namespace pocketmine\command\defaults;
use pocketmine\command\Command; use pocketmine\command\Command;
use pocketmine\command\CommandSender; use pocketmine\command\CommandSender;
use pocketmine\event\TranslationContainer; use pocketmine\event\TranslationContainer;
use pocketmine\utils\TextFormat;
class PardonCommand extends VanillaCommand{ class PardonCommand extends VanillaCommand{

View File

@ -24,7 +24,7 @@ namespace pocketmine\command\defaults;
use pocketmine\command\Command; use pocketmine\command\Command;
use pocketmine\command\CommandSender; use pocketmine\command\CommandSender;
use pocketmine\event\TranslationContainer; use pocketmine\event\TranslationContainer;
use pocketmine\utils\TextFormat;
class PardonIpCommand extends VanillaCommand{ class PardonIpCommand extends VanillaCommand{

View File

@ -25,19 +25,26 @@ use pocketmine\block\Block;
use pocketmine\command\CommandSender; use pocketmine\command\CommandSender;
use pocketmine\event\TranslationContainer; use pocketmine\event\TranslationContainer;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\level\particle\AngryVillagerParticle;
use pocketmine\level\particle\BubbleParticle; use pocketmine\level\particle\BubbleParticle;
use pocketmine\level\particle\CriticalParticle; use pocketmine\level\particle\CriticalParticle;
use pocketmine\level\particle\DustParticle; use pocketmine\level\particle\DustParticle;
use pocketmine\level\particle\EnchantmentTableParticle;
use pocketmine\level\particle\EnchantParticle; use pocketmine\level\particle\EnchantParticle;
use pocketmine\level\particle\ExplodeParticle; use pocketmine\level\particle\ExplodeParticle;
use pocketmine\level\particle\FlameParticle; use pocketmine\level\particle\FlameParticle;
use pocketmine\level\particle\HappyVillagerParticle;
use pocketmine\level\particle\HeartParticle; use pocketmine\level\particle\HeartParticle;
use pocketmine\level\particle\HugeExplodeParticle;
use pocketmine\level\particle\InkParticle; use pocketmine\level\particle\InkParticle;
use pocketmine\level\particle\InstantEnchantParticle;
use pocketmine\level\particle\ItemBreakParticle; use pocketmine\level\particle\ItemBreakParticle;
use pocketmine\level\particle\LargeExplodeParticle;
use pocketmine\level\particle\LavaDripParticle; use pocketmine\level\particle\LavaDripParticle;
use pocketmine\level\particle\LavaParticle; use pocketmine\level\particle\LavaParticle;
use pocketmine\level\particle\Particle; use pocketmine\level\particle\Particle;
use pocketmine\level\particle\PortalParticle; use pocketmine\level\particle\PortalParticle;
use pocketmine\level\particle\RainSplashParticle;
use pocketmine\level\particle\RedstoneParticle; use pocketmine\level\particle\RedstoneParticle;
use pocketmine\level\particle\SmokeParticle; use pocketmine\level\particle\SmokeParticle;
use pocketmine\level\particle\SplashParticle; use pocketmine\level\particle\SplashParticle;
@ -123,6 +130,10 @@ class ParticleCommand extends VanillaCommand{
switch($name){ switch($name){
case "explode": case "explode":
return new ExplodeParticle($pos); return new ExplodeParticle($pos);
case "largeexplode":
return new LargeExplodeParticle($pos);
case "hugeexplosion":
return new HugeExplodeParticle($pos);
case "bubble": case "bubble":
return new BubbleParticle($pos); return new BubbleParticle($pos);
case "splash": case "splash":
@ -136,6 +147,8 @@ class ParticleCommand extends VanillaCommand{
return new SmokeParticle($pos, $data !== null ? $data : 0); return new SmokeParticle($pos, $data !== null ? $data : 0);
case "spell": case "spell":
return new EnchantParticle($pos); return new EnchantParticle($pos);
case "instantspell":
return new InstantEnchantParticle($pos);
case "dripwater": case "dripwater":
return new WaterDripParticle($pos); return new WaterDripParticle($pos);
case "driplava": case "driplava":
@ -153,6 +166,8 @@ class ParticleCommand extends VanillaCommand{
return new RedstoneParticle($pos, $data !== null ? $data : 1); return new RedstoneParticle($pos, $data !== null ? $data : 1);
case "snowballpoof": case "snowballpoof":
return new ItemBreakParticle($pos, Item::get(Item::SNOWBALL)); return new ItemBreakParticle($pos, Item::get(Item::SNOWBALL));
case "slime":
return new ItemBreakParticle($pos, Item::get(Item::SLIMEBALL));
case "itembreak": case "itembreak":
if($data !== null and $data !== 0){ if($data !== null and $data !== 0){
return new ItemBreakParticle($pos, $data); return new ItemBreakParticle($pos, $data);
@ -167,6 +182,14 @@ class ParticleCommand extends VanillaCommand{
return new HeartParticle($pos, $data !== null ? $data : 0); return new HeartParticle($pos, $data !== null ? $data : 0);
case "ink": case "ink":
return new InkParticle($pos, $data !== null ? $data : 0); return new InkParticle($pos, $data !== null ? $data : 0);
case "droplet":
return new RainSplashParticle($pos);
case "enchantmenttable":
return new EnchantmentTableParticle($pos);
case "happyvillager":
return new HappyVillagerParticle($pos);
case "angryvillager":
return new AngryVillagerParticle($pos);
} }

View File

@ -24,7 +24,7 @@ namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender; use pocketmine\command\CommandSender;
use pocketmine\event\TimingsHandler; use pocketmine\event\TimingsHandler;
use pocketmine\event\TranslationContainer; use pocketmine\event\TranslationContainer;
use pocketmine\utils\TextFormat;
class TimingsCommand extends VanillaCommand{ class TimingsCommand extends VanillaCommand{

View File

@ -86,7 +86,7 @@ class Arrow extends Projectile{
$pk->speedY = $this->motionY; $pk->speedY = $this->motionY;
$pk->speedZ = $this->motionZ; $pk->speedZ = $this->motionZ;
$pk->metadata = $this->dataProperties; $pk->metadata = $this->dataProperties;
$player->dataPacket($pk->setChannel(Network::CHANNEL_ENTITY_SPAWNING)); $player->dataPacket($pk);
parent::spawnTo($player); parent::spawnTo($player);
} }

View File

@ -0,0 +1,171 @@
<?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\entity;
use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\event\entity\EntityRegainHealthEvent;
use pocketmine\network\Network;
use pocketmine\network\protocol\MobEffectPacket;
use pocketmine\Player;
class Attribute{
const MAX_HEALTH = 0;
const EXPERIENCE = 1;
const EXPERIENCE_LEVEL = 2;
private $id;
protected $minValue;
protected $maxValue;
protected $defaultValue;
protected $currentValue;
protected $name;
protected $shouldSend;
/** @var Attribute[] */
protected static $attributes = [];
public static function init(){
self::addAttribute(self::MAX_HEALTH, "generic.health", 0, 0x7fffffff, 20, true);
self::addAttribute(self::EXPERIENCE, "player.experience", 0, 1, 0, true);
self::addAttribute(self::EXPERIENCE_LEVEL, "player.level", 0, 24791, 0, true);
}
/**
* @param int $id
* @param string $name
* @param float $minValue
* @param float $maxValue
* @param float $defaultValue
* @param bool $shouldSend
* @return Attribute
*/
public static function addAttribute($id, $name, $minValue, $maxValue, $defaultValue, $shouldSend = false){
if($minValue > $maxValue or $defaultValue > $maxValue or $defaultValue < $minValue){
throw new \InvalidArgumentException("Invalid ranges: min value: $minValue, max value: $maxValue, $defaultValue: $defaultValue");
}
return self::$attributes[(int) $id] = new Attribute($id, $name, $minValue, $maxValue, $defaultValue, $shouldSend);
}
/**
* @param $id
* @return null|Attribute
*/
public static function getAttribute($id){
return isset(self::$attributes[$id]) ? clone self::$attributes[$id] : null;
}
/**
* @param $name
* @return null|Attribute
*/
public static function getAttributeByName($name){
foreach(self::$attributes as $a){
if($a->getName() === $name){
return clone $a;
}
}
return null;
}
private function __construct($id, $name, $minValue, $maxValue, $defaultValue, $shouldSend = false){
$this->id = (int) $id;
$this->name = (string) $name;
$this->minValue = (float) $minValue;
$this->maxValue = (float) $maxValue;
$this->defaultValue = (float) $defaultValue;
$this->shouldSend = (float) $shouldSend;
$this->currentValue = $this->defaultValue;
}
public function getMinValue(){
return $this->minValue;
}
public function setMinValue($minValue){
if($minValue > $this->getMaxValue()){
throw new \InvalidArgumentException("Value $minValue is bigger than the maxValue!");
}
$this->minValue = $minValue;
return $this;
}
public function getMaxValue(){
return $this->maxValue;
}
public function setMaxValue($maxValue){
if($maxValue < $this->getMinValue()){
throw new \InvalidArgumentException("Value $maxValue is bigger than the minValue!");
}
$this->maxValue = $maxValue;
return $this;
}
public function getDefaultValue(){
return $this->defaultValue;
}
public function setDefaultValue($defaultValue){
if($defaultValue > $this->getMaxValue() or $defaultValue < $this->getMinValue()){
throw new \InvalidArgumentException("Value $defaultValue exceeds the range!");
}
$this->defaultValue = $defaultValue;
return $this;
}
public function getValue(){
return $this->currentValue;
}
public function setValue($value){
if($value > $this->getMaxValue() or $value < $this->getMinValue()){
throw new \InvalidArgumentException("Value $value exceeds the range!");
}
$this->currentValue = $value;
return $this;
}
public function getName(){
return $this->name;
}
public function getId(){
return $this->id;
}
public function isSyncable(){
return $this->shouldSend;
}
}

View File

@ -26,7 +26,7 @@ use pocketmine\event\entity\EntityRegainHealthEvent;
use pocketmine\network\Network; use pocketmine\network\Network;
use pocketmine\network\protocol\MobEffectPacket; use pocketmine\network\protocol\MobEffectPacket;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\Server;
class Effect{ class Effect{
const SPEED = 1; const SPEED = 1;
@ -249,7 +249,7 @@ class Effect{
$pk->eventId = MobEffectPacket::EVENT_ADD; $pk->eventId = MobEffectPacket::EVENT_ADD;
} }
$entity->dataPacket($pk->setChannel(Network::CHANNEL_WORLD_EVENTS)); $entity->dataPacket($pk);
} }
if($this->id === Effect::INVISIBILITY){ if($this->id === Effect::INVISIBILITY){
@ -265,7 +265,7 @@ class Effect{
$pk->eventId = MobEffectPacket::EVENT_REMOVE; $pk->eventId = MobEffectPacket::EVENT_REMOVE;
$pk->effectId = $this->getId(); $pk->effectId = $this->getId();
$entity->dataPacket($pk->setChannel(Network::CHANNEL_WORLD_EVENTS)); $entity->dataPacket($pk);
} }
if($this->id === Effect::INVISIBILITY){ if($this->id === Effect::INVISIBILITY){

View File

@ -57,7 +57,7 @@ use pocketmine\network\Network;
use pocketmine\network\protocol\MobEffectPacket; use pocketmine\network\protocol\MobEffectPacket;
use pocketmine\network\protocol\RemoveEntityPacket; use pocketmine\network\protocol\RemoveEntityPacket;
use pocketmine\network\protocol\SetEntityDataPacket; use pocketmine\network\protocol\SetEntityDataPacket;
use pocketmine\network\protocol\SetTimePacket;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\plugin\Plugin; use pocketmine\plugin\Plugin;
use pocketmine\Server; use pocketmine\Server;
@ -92,6 +92,7 @@ abstract class Entity extends Location implements Metadatable{
const DATA_FLAG_ONFIRE = 0; const DATA_FLAG_ONFIRE = 0;
const DATA_FLAG_SNEAKING = 1; const DATA_FLAG_SNEAKING = 1;
const DATA_FLAG_RIDING = 2; const DATA_FLAG_RIDING = 2;
const DATA_FLAG_SPRINTING = 3;
const DATA_FLAG_ACTION = 4; const DATA_FLAG_ACTION = 4;
const DATA_FLAG_INVISIBLE = 5; const DATA_FLAG_INVISIBLE = 5;
@ -302,6 +303,22 @@ abstract class Entity extends Location implements Metadatable{
$this->setDataProperty(self::DATA_SHOW_NAMETAG, self::DATA_TYPE_BYTE, $value ? 1 : 0); $this->setDataProperty(self::DATA_SHOW_NAMETAG, self::DATA_TYPE_BYTE, $value ? 1 : 0);
} }
public function isSneaking(){
return $this->getDataFlag(self::DATA_FLAGS, self::DATA_FLAG_SNEAKING);
}
public function setSneaking($value = true){
$this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_SNEAKING, (bool) $value);
}
public function isSprinting(){
return $this->getDataFlag(self::DATA_FLAGS, self::DATA_FLAG_SPRINTING);
}
public function setSprinting($value = true){
$this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_SPRINTING, (bool) $value);
}
/** /**
* @return Effect[] * @return Effect[]
*/ */
@ -433,8 +450,13 @@ abstract class Entity extends Location implements Metadatable{
public function saveNBT(){ public function saveNBT(){
if(!($this instanceof Player)){ if(!($this instanceof Player)){
$this->namedtag->id = new String("id", $this->getSaveId()); $this->namedtag->id = new String("id", $this->getSaveId());
$this->namedtag->CustomName = new String("CustomName", $this->getNameTag()); if($this->getNameTag() !== ""){
$this->namedtag->CustomNameVisible = new String("CustomNameVisible", $this->isNameTagVisible()); $this->namedtag->CustomName = new String("CustomName", $this->getNameTag());
$this->namedtag->CustomNameVisible = new String("CustomNameVisible", $this->isNameTagVisible());
}else{
unset($this->namedtag->CustomName);
unset($this->namedtag->CustomNameVisible);
}
} }
$this->namedtag->Pos = new Enum("Pos", [ $this->namedtag->Pos = new Enum("Pos", [
@ -495,7 +517,9 @@ abstract class Entity extends Location implements Metadatable{
if(isset($this->namedtag->CustomName)){ if(isset($this->namedtag->CustomName)){
$this->setNameTag($this->namedtag["CustomName"]); $this->setNameTag($this->namedtag["CustomName"]);
$this->setNameTagVisible($this->namedtag["CustomNameVisible"] > 0); if(isset($this->namedtag->CustomNameVisible)){
$this->setNameTagVisible($this->namedtag["CustomNameVisible"] > 0);
}
} }
$this->scheduleUpdate(); $this->scheduleUpdate();
@ -527,7 +551,7 @@ abstract class Entity extends Location implements Metadatable{
$pk->duration = $effect->getDuration(); $pk->duration = $effect->getDuration();
$pk->eventId = MobEffectPacket::EVENT_ADD; $pk->eventId = MobEffectPacket::EVENT_ADD;
$player->dataPacket($pk->setChannel(Network::CHANNEL_WORLD_EVENTS)); $player->dataPacket($pk);
} }
} }
@ -548,9 +572,9 @@ abstract class Entity extends Location implements Metadatable{
$pk->metadata = $data === null ? $this->dataProperties : $data; $pk->metadata = $data === null ? $this->dataProperties : $data;
if(!is_array($player)){ if(!is_array($player)){
$player->dataPacket($pk->setChannel(Network::CHANNEL_WORLD_EVENTS)); $player->dataPacket($pk);
}else{ }else{
Server::broadcastPacket($player, $pk->setChannel(Network::CHANNEL_WORLD_EVENTS)); Server::broadcastPacket($player, $pk);
} }
} }
@ -561,7 +585,7 @@ abstract class Entity extends Location implements Metadatable{
if(isset($this->hasSpawned[$player->getLoaderId()])){ if(isset($this->hasSpawned[$player->getLoaderId()])){
$pk = new RemoveEntityPacket(); $pk = new RemoveEntityPacket();
$pk->eid = $this->getId(); $pk->eid = $this->getId();
$player->dataPacket($pk->setChannel(Network::CHANNEL_ENTITY_SPAWNING)); $player->dataPacket($pk);
unset($this->hasSpawned[$player->getLoaderId()]); unset($this->hasSpawned[$player->getLoaderId()]);
} }
} }
@ -1456,7 +1480,7 @@ abstract class Entity extends Location implements Metadatable{
} }
public function spawnToAll(){ public function spawnToAll(){
if($this->chunk === null){ if($this->chunk === null or $this->closed){
return; return;
} }
foreach($this->level->getChunkPlayers($this->chunk->getX(), $this->chunk->getZ()) as $player){ foreach($this->level->getChunkPlayers($this->chunk->getX(), $this->chunk->getZ()) as $player){

View File

@ -23,11 +23,11 @@ namespace pocketmine\entity;
use pocketmine\block\Block; use pocketmine\block\Block;
use pocketmine\block\Flowable;
use pocketmine\block\Liquid; use pocketmine\block\Liquid;
use pocketmine\event\entity\EntityBlockChangeEvent; use pocketmine\event\entity\EntityBlockChangeEvent;
use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\event\entity\EntityRegainHealthEvent;
use pocketmine\item\Item as ItemItem; use pocketmine\item\Item as ItemItem;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\Byte;
@ -170,7 +170,7 @@ class FallingSand extends Entity{
$pk->yaw = $this->yaw; $pk->yaw = $this->yaw;
$pk->pitch = $this->pitch; $pk->pitch = $this->pitch;
$pk->metadata = $this->dataProperties; $pk->metadata = $this->dataProperties;
$player->dataPacket($pk->setChannel(Network::CHANNEL_ENTITY_SPAWNING)); $player->dataPacket($pk);
parent::spawnTo($player); parent::spawnTo($player);
} }

View File

@ -24,6 +24,7 @@ namespace pocketmine\entity;
use pocketmine\inventory\InventoryHolder; use pocketmine\inventory\InventoryHolder;
use pocketmine\inventory\PlayerInventory; use pocketmine\inventory\PlayerInventory;
use pocketmine\item\Item as ItemItem; use pocketmine\item\Item as ItemItem;
use pocketmine\utils\UUID;
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;
@ -46,29 +47,48 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
/** @var PlayerInventory */ /** @var PlayerInventory */
protected $inventory; protected $inventory;
/** @var UUID */
protected $uuid;
protected $rawUUID;
public $width = 0.6; public $width = 0.6;
public $length = 0.6; public $length = 0.6;
public $height = 1.8; public $height = 1.8;
public $eyeHeight = 1.62; public $eyeHeight = 1.62;
protected $skinName;
protected $skin; protected $skin;
protected $isSlim = false;
public function getSkinData(){ public function getSkinData(){
return $this->skin; return $this->skin;
} }
public function isSkinSlim(){ public function getSkinName(){
return $this->isSlim; return $this->skinName;
}
/**
* @return UUID|null
*/
public function getUniqueId(){
return $this->uuid;
}
/**
* @return string
*/
public function getRawUniqueId(){
return $this->rawUUID;
} }
/** /**
* @param string $str * @param string $str
* @param bool $isSlim * @param string $skinName
*/ */
public function setSkin($str, $isSlim = false){ public function setSkin($str, $skinName){
$this->skin = $str; $this->skin = $str;
$this->isSlim = (bool) $isSlim; $this->skinName = $skinName;
} }
public function getInventory(){ public function getInventory(){
@ -92,8 +112,10 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
} }
if(isset($this->namedtag->Skin) and $this->namedtag->Skin instanceof Compound){ if(isset($this->namedtag->Skin) and $this->namedtag->Skin instanceof Compound){
$this->setSkin($this->namedtag->Skin["Data"], $this->namedtag->Skin["Slim"] > 0); $this->setSkin($this->namedtag->Skin["Data"], $this->namedtag->Skin["Name"]);
} }
$this->uuid = UUID::fromData($this->getId(), $this->getSkinData(), $this->getNameTag());
} }
if(isset($this->namedtag->Inventory) and $this->namedtag->Inventory instanceof Enum){ if(isset($this->namedtag->Inventory) and $this->namedtag->Inventory instanceof Enum){
@ -101,9 +123,9 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
if($item["Slot"] >= 0 and $item["Slot"] < 9){ //Hotbar if($item["Slot"] >= 0 and $item["Slot"] < 9){ //Hotbar
$this->inventory->setHotbarSlotIndex($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->inventory->setItem($this->inventory->getSize() + $item["Slot"] - 100, ItemItem::get($item["id"], $item["Damage"], $item["Count"])); $this->inventory->setItem($this->inventory->getSize() + $item["Slot"] - 100, NBT::getItemHelper($item));
}else{ }else{
$this->inventory->setItem($item["Slot"] - 9, ItemItem::get($item["id"], $item["Damage"], $item["Count"])); $this->inventory->setItem($item["Slot"] - 9, NBT::getItemHelper($item));
} }
} }
} }
@ -136,16 +158,14 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
if($hotbarSlot !== -1){ if($hotbarSlot !== -1){
$item = $this->inventory->getItem($hotbarSlot); $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("", [ $tag = NBT::putItemHelper($item, $slot);
new Byte("Count", $item->getCount()), $tag->TrueSlot = new Byte("TrueSlot", $hotbarSlot);
new Short("Damage", $item->getDamage()), $this->namedtag->Inventory[$slot] = $tag;
new Byte("Slot", $slot),
new Byte("TrueSlot", $hotbarSlot),
new Short("id", $item->getId()),
]);
continue; continue;
} }
} }
$this->namedtag->Inventory[$slot] = new Compound("", [ $this->namedtag->Inventory[$slot] = new Compound("", [
new Byte("Count", 0), new Byte("Count", 0),
new Short("Damage", 0), new Short("Damage", 0),
@ -160,24 +180,14 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
//$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->inventory->getItem($slot - 9); $item = $this->inventory->getItem($slot - 9);
$this->namedtag->Inventory[$slot] = new Compound("", [ $this->namedtag->Inventory[$slot] = NBT::putItemHelper($item, $slot);
new Byte("Count", $item->getCount()),
new Short("Damage", $item->getDamage()),
new Byte("Slot", $slot),
new Short("id", $item->getId()),
]);
} }
//Armor //Armor
for($slot = 100; $slot < 104; ++$slot){ for($slot = 100; $slot < 104; ++$slot){
$item = $this->inventory->getItem($this->inventory->getSize() + $slot - 100); $item = $this->inventory->getItem($this->inventory->getSize() + $slot - 100);
if($item instanceof ItemItem and $item->getId() !== ItemItem::AIR){ if($item instanceof ItemItem and $item->getId() !== ItemItem::AIR){
$this->namedtag->Inventory[$slot] = new Compound("", [ $this->namedtag->Inventory[$slot] = NBT::putItemHelper($item, $slot);
new Byte("Count", $item->getCount()),
new Short("Damage", $item->getDamage()),
new Byte("Slot", $slot),
new Short("id", $item->getId()),
]);
} }
} }
} }
@ -185,7 +195,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
if(strlen($this->getSkinData()) > 0){ if(strlen($this->getSkinData()) > 0){
$this->namedtag->Skin = new Compound("Skin", [ $this->namedtag->Skin = new Compound("Skin", [
"Data" => new String("Data", $this->getSkinData()), "Data" => new String("Data", $this->getSkinData()),
"Slim" => new Byte("Slim", $this->isSkinSlim() ? 1 : 0) "Name" => new String("Name", $this->getSkinName())
]); ]);
} }
} }
@ -198,8 +208,13 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
throw new \InvalidStateException((new \ReflectionClass($this))->getShortName() . " must have a valid skin set"); throw new \InvalidStateException((new \ReflectionClass($this))->getShortName() . " must have a valid skin set");
} }
if(!($this instanceof Player)){
$this->server->updatePlayerListData($this->getUniqueId(), $this->getId(), $this->getName(), $this->skinName, $this->skin, [$player]);
}
$pk = new AddPlayerPacket(); $pk = new AddPlayerPacket();
$pk->clientID = $this->getId(); $pk->uuid = $this->getUniqueId();
$pk->username = $this->getName(); $pk->username = $this->getName();
$pk->eid = $this->getId(); $pk->eid = $this->getId();
$pk->x = $this->x; $pk->x = $this->x;
@ -210,24 +225,25 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
$pk->speedZ = $this->motionZ; $pk->speedZ = $this->motionZ;
$pk->yaw = $this->yaw; $pk->yaw = $this->yaw;
$pk->pitch = $this->pitch; $pk->pitch = $this->pitch;
$item = $this->getInventory()->getItemInHand(); $pk->item = $this->getInventory()->getItemInHand();
$pk->item = $item->getId();
$pk->meta = $item->getDamage();
$pk->skin = $this->skin;
$pk->slim = $this->isSlim;
$pk->metadata = $this->dataProperties; $pk->metadata = $this->dataProperties;
$player->dataPacket($pk->setChannel(Network::CHANNEL_ENTITY_SPAWNING)); $player->dataPacket($pk);
$this->inventory->sendArmorContents($player); $this->inventory->sendArmorContents($player);
if(!($this instanceof Player)){
$this->server->removePlayerListData($this->getUniqueId(), [$player]);
}
} }
} }
public function despawnFrom(Player $player){ public function despawnFrom(Player $player){
if(isset($this->hasSpawned[$player->getLoaderId()])){ if(isset($this->hasSpawned[$player->getLoaderId()])){
$pk = new RemovePlayerPacket(); $pk = new RemovePlayerPacket();
$pk->eid = $this->getId(); $pk->eid = $this->getId();
$pk->clientID = $this->getId(); $pk->clientId = $this->getUniqueId();
$player->dataPacket($pk->setChannel(Network::CHANNEL_ENTITY_SPAWNING)); $player->dataPacket($pk);
unset($this->hasSpawned[$player->getLoaderId()]); unset($this->hasSpawned[$player->getLoaderId()]);
} }
} }

View File

@ -22,13 +22,14 @@
namespace pocketmine\entity; namespace pocketmine\entity;
use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\event\entity\EntityRegainHealthEvent;
use pocketmine\event\entity\ItemDespawnEvent; use pocketmine\event\entity\ItemDespawnEvent;
use pocketmine\event\entity\ItemSpawnEvent; use pocketmine\event\entity\ItemSpawnEvent;
use pocketmine\item\Item as ItemItem; use pocketmine\item\Item as ItemItem;
use pocketmine\math\Vector3;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Compound;
use pocketmine\nbt\tag\Short; use pocketmine\nbt\tag\Short;
use pocketmine\nbt\tag\String; use pocketmine\nbt\tag\String;
use pocketmine\network\Network; use pocketmine\network\Network;
@ -69,7 +70,11 @@ class Item extends Entity{
if(isset($this->namedtag->Thrower)){ if(isset($this->namedtag->Thrower)){
$this->thrower = $this->namedtag["Thrower"]; $this->thrower = $this->namedtag["Thrower"];
} }
$this->item = ItemItem::get($this->namedtag->Item["id"], $this->namedtag->Item["Damage"], $this->namedtag->Item["Count"]); if(!isset($this->namedtag->Item)){
$this->close();
return;
}
$this->item = NBT::getItemHelper($this->namedtag->Item);
$this->server->getPluginManager()->callEvent(new ItemSpawnEvent($this)); $this->server->getPluginManager()->callEvent(new ItemSpawnEvent($this));
@ -154,11 +159,7 @@ class Item extends Entity{
public function saveNBT(){ public function saveNBT(){
parent::saveNBT(); parent::saveNBT();
$this->namedtag->Item = new Compound("Item", [ $this->namedtag->Item = NBT::putItemHelper($this->item);
"id" => new Short("id", $this->item->getId()),
"Damage" => new Short("Damage", $this->item->getDamage()),
"Count" => new Byte("Count", $this->item->getCount())
]);
$this->namedtag->Health = new Short("Health", $this->getHealth()); $this->namedtag->Health = new Short("Health", $this->getHealth());
$this->namedtag->Age = new Short("Age", $this->age); $this->namedtag->Age = new Short("Age", $this->age);
$this->namedtag->PickupDelay = new Short("PickupDelay", $this->pickupDelay); $this->namedtag->PickupDelay = new Short("PickupDelay", $this->pickupDelay);
@ -233,7 +234,7 @@ class Item extends Entity{
$pk->speedY = $this->motionY; $pk->speedY = $this->motionY;
$pk->speedZ = $this->motionZ; $pk->speedZ = $this->motionZ;
$pk->item = $this->getItem(); $pk->item = $this->getItem();
$player->dataPacket($pk->setChannel(Network::CHANNEL_ENTITY_SPAWNING)); $player->dataPacket($pk);
$this->sendData($player); $this->sendData($player);

View File

@ -34,7 +34,7 @@ use pocketmine\math\Vector3;
use pocketmine\nbt\tag\Short; use pocketmine\nbt\tag\Short;
use pocketmine\network\Network; use pocketmine\network\Network;
use pocketmine\network\protocol\EntityEventPacket; use pocketmine\network\protocol\EntityEventPacket;
use pocketmine\Player;
use pocketmine\Server; use pocketmine\Server;
use pocketmine\utils\BlockIterator; use pocketmine\utils\BlockIterator;
@ -69,7 +69,7 @@ abstract class Living extends Entity implements Damageable{
$pk = new EntityEventPacket(); $pk = new EntityEventPacket();
$pk->eid = $this->getId(); $pk->eid = $this->getId();
$pk->event = EntityEventPacket::RESPAWN; $pk->event = EntityEventPacket::RESPAWN;
Server::broadcastPacket($this->hasSpawned, $pk->setChannel(Network::CHANNEL_WORLD_EVENTS)); Server::broadcastPacket($this->hasSpawned, $pk);
} }
} }
@ -127,7 +127,7 @@ abstract class Living extends Entity implements Damageable{
$pk = new EntityEventPacket(); $pk = new EntityEventPacket();
$pk->eid = $this->getId(); $pk->eid = $this->getId();
$pk->event = $this->getHealth() <= 0 ? EntityEventPacket::DEATH_ANIMATION : EntityEventPacket::HURT_ANIMATION; //Ouch! $pk->event = $this->getHealth() <= 0 ? EntityEventPacket::DEATH_ANIMATION : EntityEventPacket::HURT_ANIMATION; //Ouch!
Server::broadcastPacket($this->hasSpawned, $pk->setChannel(Network::CHANNEL_WORLD_EVENTS)); Server::broadcastPacket($this->hasSpawned, $pk);
$this->attackTime = 10; //0.5 seconds cooldown $this->attackTime = 10; //0.5 seconds cooldown
} }

View File

@ -23,7 +23,7 @@ namespace pocketmine\entity;
use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\event\entity\EntityRegainHealthEvent;
use pocketmine\event\entity\ExplosionPrimeEvent; use pocketmine\event\entity\ExplosionPrimeEvent;
use pocketmine\level\Explosion; use pocketmine\level\Explosion;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\Byte;
@ -144,7 +144,7 @@ class PrimedTNT extends Entity implements Explosive{
$pk->speedY = $this->motionY; $pk->speedY = $this->motionY;
$pk->speedZ = $this->motionZ; $pk->speedZ = $this->motionZ;
$pk->metadata = $this->dataProperties; $pk->metadata = $this->dataProperties;
$player->dataPacket($pk->setChannel(Network::CHANNEL_ENTITY_SPAWNING)); $player->dataPacket($pk);
parent::spawnTo($player); parent::spawnTo($player);
} }

View File

@ -26,7 +26,7 @@ use pocketmine\event\entity\EntityCombustByEntityEvent;
use pocketmine\event\entity\EntityDamageByChildEntityEvent; use pocketmine\event\entity\EntityDamageByChildEntityEvent;
use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageByEntityEvent;
use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\event\entity\EntityRegainHealthEvent;
use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\event\entity\ProjectileHitEvent;
use pocketmine\level\format\FullChunk; use pocketmine\level\format\FullChunk;
use pocketmine\level\MovingObjectPosition; use pocketmine\level\MovingObjectPosition;

View File

@ -72,7 +72,7 @@ class Snowball extends Projectile{
$pk->speedY = $this->motionY; $pk->speedY = $this->motionY;
$pk->speedZ = $this->motionZ; $pk->speedZ = $this->motionZ;
$pk->metadata = $this->dataProperties; $pk->metadata = $this->dataProperties;
$player->dataPacket($pk->setChannel(Network::CHANNEL_ENTITY_SPAWNING)); $player->dataPacket($pk);
parent::spawnTo($player); parent::spawnTo($player);
} }

View File

@ -68,7 +68,7 @@ class Squid extends WaterAnimal implements Ageable{
$pk = new EntityEventPacket(); $pk = new EntityEventPacket();
$pk->eid = $this->getId(); $pk->eid = $this->getId();
$pk->event = EntityEventPacket::SQUID_INK_CLOUD; $pk->event = EntityEventPacket::SQUID_INK_CLOUD;
Server::broadcastPacket($this->hasSpawned, $pk->setChannel(Network::CHANNEL_WORLD_EVENTS)); Server::broadcastPacket($this->hasSpawned, $pk);
} }
} }
@ -160,7 +160,7 @@ class Squid extends WaterAnimal implements Ageable{
$pk->yaw = $this->yaw; $pk->yaw = $this->yaw;
$pk->pitch = $this->pitch; $pk->pitch = $this->pitch;
$pk->metadata = $this->dataProperties; $pk->metadata = $this->dataProperties;
$player->dataPacket($pk->setChannel(Network::CHANNEL_ENTITY_SPAWNING)); $player->dataPacket($pk);
parent::spawnTo($player); parent::spawnTo($player);
} }

View File

@ -65,7 +65,7 @@ class Villager extends Creature implements NPC, Ageable{
$pk->yaw = $this->yaw; $pk->yaw = $this->yaw;
$pk->pitch = $this->pitch; $pk->pitch = $this->pitch;
$pk->metadata = $this->dataProperties; $pk->metadata = $this->dataProperties;
$player->dataPacket($pk->setChannel(Network::CHANNEL_ENTITY_SPAWNING)); $player->dataPacket($pk);
parent::spawnTo($player); parent::spawnTo($player);
} }

View File

@ -52,7 +52,7 @@ class Zombie extends Monster{
$pk->yaw = $this->yaw; $pk->yaw = $this->yaw;
$pk->pitch = $this->pitch; $pk->pitch = $this->pitch;
$pk->metadata = $this->dataProperties; $pk->metadata = $this->dataProperties;
$player->dataPacket($pk->setChannel(Network::CHANNEL_ENTITY_SPAWNING)); $player->dataPacket($pk);
parent::spawnTo($player); parent::spawnTo($player);
} }

View File

@ -23,31 +23,42 @@ namespace pocketmine\event\inventory;
use pocketmine\event\Cancellable; use pocketmine\event\Cancellable;
use pocketmine\event\Event; use pocketmine\event\Event;
use pocketmine\inventory\CraftingTransactionGroup;
use pocketmine\inventory\Recipe; use pocketmine\inventory\Recipe;
use pocketmine\item\Item;
use pocketmine\Player;
class CraftItemEvent extends Event implements Cancellable{ class CraftItemEvent extends Event implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
/** @var CraftingTransactionGroup */ /** @var Item[] */
private $ts; private $input = [];
/** @var Recipe */ /** @var Recipe */
private $recipe; private $recipe;
/** @var \pocketmine\Player */
private $player;
/** /**
* @param CraftingTransactionGroup $ts * @param \pocketmine\Player $player
* @param Recipe $recipe * @param Item[] $input
* @param Recipe $recipe
*/ */
public function __construct(CraftingTransactionGroup $ts, Recipe $recipe){ public function __construct(Player $player, array $input, Recipe $recipe){
$this->ts = $ts; $this->player = $player;
$this->input = $input;
$this->recipe = $recipe; $this->recipe = $recipe;
} }
/** /**
* @return CraftingTransactionGroup * @return Item[]
*/ */
public function getTransaction(){ public function getInput(){
return $this->ts; $items = [];
foreach($items as $i => $item){
$items[$i] = clone $item;
}
return $items;
} }
/** /**
@ -57,4 +68,10 @@ class CraftItemEvent extends Event implements Cancellable{
return $this->recipe; return $this->recipe;
} }
/**
* @return \pocktemine\Player
*/
public function getPlayer(){
return $this->player;
}
} }

View File

@ -0,0 +1,42 @@
<?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\player;
use pocketmine\event\Cancellable;
use pocketmine\Player;
class PlayerToggleSneakEvent extends PlayerEvent implements Cancellable{
public static $handlerList = null;
/** @var bool */
protected $isSneaking;
public function __construct(Player $player, $isSneaking){
$this->player = $player;
$this->isSneaking = (bool) $isSneaking;
}
public function isSneaking(){
return $this->isSneaking;
}
}

View File

@ -0,0 +1,42 @@
<?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\player;
use pocketmine\event\Cancellable;
use pocketmine\Player;
class PlayerToggleSprintEvent extends PlayerEvent implements Cancellable{
public static $handlerList = null;
/** @var bool */
protected $isSprinting;
public function __construct(Player $player, $isSprinting){
$this->player = $player;
$this->isSprinting = (bool) $isSprinting;
}
public function isSprinting(){
return $this->isSprinting;
}
}

View File

@ -0,0 +1,47 @@
<?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\level\Position;
use pocketmine\Player;
class AnvilInventory extends ContainerInventory{
public function __construct(Position $pos){
parent::__construct(new FakeBlockMenu($this, $pos), InventoryType::get(InventoryType::ANVIL));
}
/**
* @return FakeBlockMenu
*/
public function getHolder(){
return $this->holder;
}
public function onClose(Player $who){
parent::onClose($who);
for($i = 0; $i < 2; ++$i){
$this->getHolder()->getLevel()->dropItem($this->getHolder()->add(0.5, 0.5, 0.5), $this->getItem($i));
$this->clear($i);
}
}
}

View File

@ -160,8 +160,9 @@ abstract class BaseInventory implements Inventory{
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;
$checkTags = $item->getCompoundTag() === null ? false : true;
foreach($this->getContents() as $i){ foreach($this->getContents() as $i){
if($item->equals($i, $checkDamage)){ if($item->equals($i, $checkDamage, $checkTags)){
$count -= $i->getCount(); $count -= $i->getCount();
if($count <= 0){ if($count <= 0){
return true; return true;
@ -175,8 +176,9 @@ 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;
$checkTags = $item->getCompoundTag() === null ? false : true;
foreach($this->getContents() as $index => $i){ foreach($this->getContents() as $index => $i){
if($item->equals($i, $checkDamage)){ if($item->equals($i, $checkDamage, $checkTags)){
$slots[$index] = $i; $slots[$index] = $i;
} }
} }
@ -186,8 +188,10 @@ 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;
$checkTags = $item->getCompoundTag() === null ? false : true;
foreach($this->getContents() as $index => $i){ foreach($this->getContents() as $index => $i){
if($item->equals($i, $checkDamage)){ if($item->equals($i, $checkDamage, $checkTags)){
$this->clear($index); $this->clear($index);
} }
} }
@ -196,8 +200,10 @@ 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;
$checkTags = $item->getCompoundTag() === null ? false : true;
foreach($this->getContents() as $index => $i){ foreach($this->getContents() as $index => $i){
if($item->equals($i, $checkDamage) and $i->getCount() >= $count){ if($item->equals($i, $checkDamage, $checkTags) and $i->getCount() >= $count){
return $index; return $index;
} }
} }
@ -218,9 +224,10 @@ abstract class BaseInventory implements Inventory{
public function canAddItem(Item $item){ public function canAddItem(Item $item){
$item = clone $item; $item = clone $item;
$checkDamage = $item->getDamage() === null ? false : true; $checkDamage = $item->getDamage() === null ? false : true;
$checkTags = $item->getCompoundTag() === null ? false : true;
for($i = 0; $i < $this->getSize(); ++$i){ for($i = 0; $i < $this->getSize(); ++$i){
$slot = $this->getItem($i); $slot = $this->getItem($i);
if($item->equals($slot, $checkDamage)){ if($item->equals($slot, $checkDamage, $checkTags)){
if(($diff = $slot->getMaxStackSize() - $slot->getCount()) > 0){ if(($diff = $slot->getMaxStackSize() - $slot->getCount()) > 0){
$item->setCount($item->getCount() - $diff); $item->setCount($item->getCount() - $diff);
} }
@ -258,7 +265,7 @@ abstract class BaseInventory implements Inventory{
} }
foreach($itemSlots as $index => $slot){ foreach($itemSlots as $index => $slot){
if($slot->equals($item, true) and $item->getCount() < $item->getMaxStackSize()){ if($slot->equals($item) and $item->getCount() < $item->getMaxStackSize()){
$amount = min($item->getMaxStackSize() - $item->getCount(), $slot->getCount(), $this->getMaxStackSize()); $amount = min($item->getMaxStackSize() - $item->getCount(), $slot->getCount(), $this->getMaxStackSize());
if($amount > 0){ if($amount > 0){
$slot->setCount($slot->getCount() - $amount); $slot->setCount($slot->getCount() - $amount);
@ -316,7 +323,7 @@ abstract class BaseInventory implements Inventory{
} }
foreach($itemSlots as $index => $slot){ foreach($itemSlots as $index => $slot){
if($slot->equals($item, $slot->getDamage() === null ? false : true)){ if($slot->equals($item, $slot->getDamage() === null ? false : true, $slot->getCompoundTag() === null ? false : true)){
$amount = min($item->getCount(), $slot->getCount()); $amount = min($item->getCount(), $slot->getCount());
$slot->setCount($slot->getCount() - $amount); $slot->setCount($slot->getCount() - $amount);
$item->setCount($item->getCount() - $amount); $item->setCount($item->getCount() - $amount);
@ -428,7 +435,7 @@ abstract class BaseInventory implements Inventory{
continue; continue;
} }
$pk->windowid = $id; $pk->windowid = $id;
$player->dataPacket($pk->setChannel(Network::CHANNEL_WORLD_EVENTS)); $player->dataPacket($pk);
} }
} }
@ -451,7 +458,7 @@ abstract class BaseInventory implements Inventory{
continue; continue;
} }
$pk->windowid = $id; $pk->windowid = $id;
$player->dataPacket($pk->setChannel(Network::CHANNEL_WORLD_EVENTS)); $player->dataPacket($pk);
} }
} }

View File

@ -21,6 +21,6 @@
namespace pocketmine\inventory; namespace pocketmine\inventory;
class StonecutterShapelessRecipe extends ShapelessRecipe{ class BigShapedRecipe extends ShapedRecipe{
} }

View File

@ -23,9 +23,9 @@ namespace pocketmine\inventory;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\network\Network; use pocketmine\network\Network;
use pocketmine\network\protocol\TileEventPacket; use pocketmine\network\protocol\BlockEventPacket;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\Server;
use pocketmine\tile\Chest; use pocketmine\tile\Chest;
class ChestInventory extends ContainerInventory{ class ChestInventory extends ContainerInventory{
@ -44,28 +44,28 @@ class ChestInventory extends ContainerInventory{
parent::onOpen($who); parent::onOpen($who);
if(count($this->getViewers()) === 1){ if(count($this->getViewers()) === 1){
$pk = new TileEventPacket(); $pk = new BlockEventPacket();
$pk->x = $this->getHolder()->getX(); $pk->x = $this->getHolder()->getX();
$pk->y = $this->getHolder()->getY(); $pk->y = $this->getHolder()->getY();
$pk->z = $this->getHolder()->getZ(); $pk->z = $this->getHolder()->getZ();
$pk->case1 = 1; $pk->case1 = 1;
$pk->case2 = 2; $pk->case2 = 2;
if(($level = $this->getHolder()->getLevel()) instanceof Level){ if(($level = $this->getHolder()->getLevel()) instanceof Level){
$level->addChunkPacket($this->getHolder()->getX() >> 4, $this->getHolder()->getZ() >> 4, $pk->setChannel(Network::CHANNEL_WORLD_EVENTS)); $level->addChunkPacket($this->getHolder()->getX() >> 4, $this->getHolder()->getZ() >> 4, $pk);
} }
} }
} }
public function onClose(Player $who){ public function onClose(Player $who){
if(count($this->getViewers()) === 1){ if(count($this->getViewers()) === 1){
$pk = new TileEventPacket(); $pk = new BlockEventPacket();
$pk->x = $this->getHolder()->getX(); $pk->x = $this->getHolder()->getX();
$pk->y = $this->getHolder()->getY(); $pk->y = $this->getHolder()->getY();
$pk->z = $this->getHolder()->getZ(); $pk->z = $this->getHolder()->getZ();
$pk->case1 = 1; $pk->case1 = 1;
$pk->case2 = 0; $pk->case2 = 0;
if(($level = $this->getHolder()->getLevel()) instanceof Level){ if(($level = $this->getHolder()->getLevel()) instanceof Level){
$level->addChunkPacket($this->getHolder()->getX() >> 4, $this->getHolder()->getZ() >> 4, $pk->setChannel(Network::CHANNEL_WORLD_EVENTS)); $level->addChunkPacket($this->getHolder()->getX() >> 4, $this->getHolder()->getZ() >> 4, $pk);
} }
} }
parent::onClose($who); parent::onClose($who);

View File

@ -43,7 +43,7 @@ abstract class ContainerInventory extends BaseInventory{
$pk->x = $pk->y = $pk->z = 0; $pk->x = $pk->y = $pk->z = 0;
} }
$who->dataPacket($pk->setChannel(Network::CHANNEL_WORLD_EVENTS)); $who->dataPacket($pk);
$this->sendContents($who); $this->sendContents($who);
} }
@ -51,7 +51,7 @@ abstract class ContainerInventory extends BaseInventory{
public function onClose(Player $who){ public function onClose(Player $who){
$pk = new ContainerClosePacket(); $pk = new ContainerClosePacket();
$pk->windowid = $who->getWindowId($this); $pk->windowid = $who->getWindowId($this);
$who->dataPacket($pk->setChannel(Network::CHANNEL_WORLD_EVENTS)); $who->dataPacket($pk);
parent::onClose($who); parent::onClose($who);
} }
} }

View File

@ -21,11 +21,19 @@
namespace pocketmine\inventory; namespace pocketmine\inventory;
use pocketmine\block\Planks; use pocketmine\block\Planks;
use pocketmine\block\Quartz;
use pocketmine\block\Sandstone;
use pocketmine\block\Slab;
use pocketmine\block\Fence;
use pocketmine\block\Stone; use pocketmine\block\Stone;
use pocketmine\block\StoneBricks;
use pocketmine\block\StoneWall;
use pocketmine\block\Wood; use pocketmine\block\Wood;
use pocketmine\block\Wood2; use pocketmine\block\Wood2;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\utils\UUID;
class CraftingManager{ class CraftingManager{
@ -38,6 +46,8 @@ class CraftingManager{
/** @var FurnaceRecipe[] */ /** @var FurnaceRecipe[] */
public $furnaceRecipes = []; public $furnaceRecipes = [];
private static $RECIPE_COUNT = 0;
public function __construct(){ public function __construct(){
$this->registerStonecutter(); $this->registerStonecutter();
@ -52,70 +62,300 @@ class CraftingManager{
$this->registerFood(); $this->registerFood();
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::CLAY_BLOCK, 0, 1)))->addIngredient(Item::get(Item::CLAY, 0, 4))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::CLAY_BLOCK, 0, 1)))->addIngredient(Item::get(Item::CLAY, 0, 4)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WORKBENCH, 0, 1)))->addIngredient(Item::get(Item::WOODEN_PLANK, null, 4)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::WORKBENCH, 0, 1),
"XX",
"XX"
))->setIngredient("X", Item::get(Item::WOODEN_PLANK, null)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::GLOWSTONE_BLOCK, 0, 1)))->addIngredient(Item::get(Item::GLOWSTONE_DUST, 0, 4))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::GLOWSTONE_BLOCK, 0, 1)))->addIngredient(Item::get(Item::GLOWSTONE_DUST, 0, 4)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::LIT_PUMPKIN, 0, 1)))->addIngredient(Item::get(Item::PUMPKIN, 0, 1))->addIngredient(Item::get(Item::TORCH, 0, 1))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::LIT_PUMPKIN, 0, 1)))->addIngredient(Item::get(Item::PUMPKIN, 0, 1))->addIngredient(Item::get(Item::TORCH, 0, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::SNOW_BLOCK, 0, 1)))->addIngredient(Item::get(Item::SNOWBALL, 0, 4)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::SNOW_BLOCK, 0, 1),
"XX",
"XX"
))->setIngredient("X", Item::get(Item::SNOWBALL)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::SNOW_LAYER, 0, 6)))->addIngredient(Item::get(Item::SNOW_BLOCK, 0, 3))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::SNOW_LAYER, 0, 6)))->addIngredient(Item::get(Item::SNOW_BLOCK, 0, 3)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::STICK, 0, 4)))->addIngredient(Item::get(Item::WOODEN_PLANK, null, 2)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::STONECUTTER, 0, 1)))->addIngredient(Item::get(Item::COBBLESTONE, 0, 4)));
$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)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOOL, 0, 1)))->addIngredient(Item::get(Item::STRING, 0, 4)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::TORCH, 0, 4)))->addIngredient(Item::get(Item::COAL, 0, 1))->addIngredient(Item::get(Item::STICK, 0, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::TORCH, 0, 4)))->addIngredient(Item::get(Item::COAL, 1, 1))->addIngredient(Item::get(Item::STICK, 0, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::SUGAR, 0, 1)))->addIngredient(Item::get(Item::SUGARCANE, 0, 1)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::STICK, 0, 4),
"X ",
"X "
))->setIngredient("X", Item::get(Item::WOODEN_PLANK, null)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::BED, 0, 1)))->addIngredient(Item::get(Item::WOOL, null, 3))->addIngredient(Item::get(Item::WOODEN_PLANK, null, 3))); $this->registerRecipe((new ShapedRecipe(Item::get(Item::STONECUTTER, 0, 1),
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::CHEST, 0, 1)))->addIngredient(Item::get(Item::WOODEN_PLANK, null, 8))); "XX",
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::FENCE, 0, 3)))->addIngredient(Item::get(Item::STICK, 0, 2))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::OAK, 4))); "XX"
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::FENCE, Planks::SPRUCE, 3)))->addIngredient(Item::get(Item::STICK, 0, 2))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::SPRUCE, 4))); ))->setIngredient("X", Item::get(Item::COBBLESTONE)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::FENCE, Planks::BIRCH, 3)))->addIngredient(Item::get(Item::STICK, 0, 2))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::BIRCH, 4)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::FENCE, Planks::JUNGLE, 3)))->addIngredient(Item::get(Item::STICK, 0, 2))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::JUNGLE, 4)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::FENCE, Planks::ACACIA, 3)))->addIngredient(Item::get(Item::STICK, 0, 2))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::ACACIA, 4)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::FENCE, Planks::DARK_OAK, 3)))->addIngredient(Item::get(Item::STICK, 0, 2))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::DARK_OAK, 4)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::FENCE_GATE, 0, 1)))->addIngredient(Item::get(Item::STICK, 0, 4))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::OAK, 2)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::FENCE_GATE_SPRUCE, 0, 1)))->addIngredient(Item::get(Item::STICK, 0, 4))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::SPRUCE, 2)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::FENCE_GATE_BIRCH, 0, 1)))->addIngredient(Item::get(Item::STICK, 0, 4))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::BIRCH, 2)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::FENCE_GATE_JUNGLE, 0, 1)))->addIngredient(Item::get(Item::STICK, 0, 4))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::JUNGLE, 2)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::FENCE_GATE_DARK_OAK, 0, 1)))->addIngredient(Item::get(Item::STICK, 0, 4))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::DARK_OAK, 2)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::FENCE_GATE_ACACIA, 0, 1)))->addIngredient(Item::get(Item::STICK, 0, 4))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::ACACIA, 2)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::FURNACE, 0, 1)))->addIngredient(Item::get(Item::COBBLESTONE, 0, 8)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::GLASS_PANE, 0, 16)))->addIngredient(Item::get(Item::GLASS, 0, 6)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::LADDER, 0, 2)))->addIngredient(Item::get(Item::STICK, 0, 7)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::NETHER_REACTOR, 0, 1)))->addIngredient(Item::get(Item::DIAMOND, 0, 3))->addIngredient(Item::get(Item::IRON_INGOT, 0, 6)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::TRAPDOOR, 0, 2)))->addIngredient(Item::get(Item::WOODEN_PLANK, null, 6)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::WOODEN_DOOR, 0, 1)))->addIngredient(Item::get(Item::WOODEN_PLANK, null, 6)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::WOODEN_STAIRS, 0, 4)))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::OAK, 6)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::WOOD_SLAB, Planks::OAK, 6)))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::OAK, 3)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::SPRUCE_WOOD_STAIRS, 0, 4)))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::SPRUCE, 6)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::WOOD_SLAB, Planks::SPRUCE, 6)))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::SPRUCE, 3)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::BIRCH_WOOD_STAIRS, 0, 4)))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::BIRCH, 6)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::WOOD_SLAB, Planks::BIRCH, 6)))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::BIRCH, 3)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::JUNGLE_WOOD_STAIRS, 0, 4)))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::JUNGLE, 6)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::WOOD_SLAB, Planks::JUNGLE, 6)))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::JUNGLE, 3)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::ACACIA_WOOD_STAIRS, 0, 4)))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::ACACIA, 6)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::WOOD_SLAB, Planks::ACACIA, 6)))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::ACACIA, 3)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::DARK_OAK_WOOD_STAIRS, 0, 4)))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::DARK_OAK, 6)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::WOOD_SLAB, Planks::DARK_OAK, 6)))->addIngredient(Item::get(Item::WOODEN_PLANK, Planks::DARK_OAK, 3)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::BUCKET, 0, 1)))->addIngredient(Item::get(Item::IRON_INGOT, 0, 3))); $this->registerRecipe((new ShapedRecipe(Item::get(Item::WOODEN_PLANK, Planks::OAK, 4),
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::CLOCK, 0, 1)))->addIngredient(Item::get(Item::GOLD_INGOT, 0, 4))->addIngredient(Item::get(Item::REDSTONE_DUST, 0, 1))); "X"
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::COMPASS, 0, 1)))->addIngredient(Item::get(Item::IRON_INGOT, 0, 4))->addIngredient(Item::get(Item::REDSTONE_DUST, 0, 1))); ))->setIngredient("X", Item::get(Item::WOOD, Wood::OAK, 1)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::TNT, 0, 1)))->addIngredient(Item::get(Item::GUNPOWDER, 0, 5))->addIngredient(Item::get(Item::SAND, null, 4)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::BOWL, 0, 4)))->addIngredient(Item::get(Item::WOODEN_PLANKS, null, 3))); $this->registerRecipe((new ShapedRecipe(Item::get(Item::WOODEN_PLANK, Planks::SPRUCE, 4),
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::MINECART, 0, 1)))->addIngredient(Item::get(Item::IRON_INGOT, 0, 5))); "X"
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::BOOK, 0, 1)))->addIngredient(Item::get(Item::PAPER, 0, 3))); ))->setIngredient("X", Item::get(Item::WOOD, Wood::SPRUCE, 1)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::BOOKSHELF, 0, 1)))->addIngredient(Item::get(Item::WOODEN_PLANK, null, 6))->addIngredient(Item::get(Item::BOOK, 0, 3)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::PAINTING, 0, 1)))->addIngredient(Item::get(Item::STICK, 0, 8))->addIngredient(Item::get(Item::WOOL, null, 1))); $this->registerRecipe((new ShapedRecipe(Item::get(Item::WOODEN_PLANK, Planks::BIRCH, 4),
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::PAPER, 0, 1)))->addIngredient(Item::get(Item::SUGARCANE, 0, 3))); "X"
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::SIGN, 0, 3)))->addIngredient(Item::get(Item::STICK, 0, 1))->addIngredient(Item::get(Item::WOODEN_PLANKS, null, 6))); //TODO: check if it gives one sign or three ))->setIngredient("X", Item::get(Item::WOOD, Wood::BIRCH, 1)));
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::IRON_BARS, 0, 16)))->addIngredient(Item::get(Item::IRON_INGOT, 0, 6)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::WOODEN_PLANK, Planks::JUNGLE, 4),
"X"
))->setIngredient("X", Item::get(Item::WOOD, Wood::JUNGLE, 1)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::WOODEN_PLANK, Planks::ACACIA, 4),
"X"
))->setIngredient("X", Item::get(Item::WOOD2, Wood2::ACACIA, 1)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::WOODEN_PLANK, Planks::DARK_OAK, 4),
"X"
))->setIngredient("X", Item::get(Item::WOOD2, Wood2::DARK_OAK, 1)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::WOOL, 0, 1),
"XX",
"XX"
))->setIngredient("X", Item::get(Item::STRING, 0, 4)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::TORCH, 0, 4),
"C ",
"S"
))->setIngredient("C", Item::get(Item::COAL,0,1))->setIngredient("S", Item::get(Item::STICK,0,1)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::TORCH, 0, 4),
"C ",
"S"
))->setIngredient("C", Item::get(Item::COAL, 1, 1))->setIngredient("S", Item::get(Item::STICK, 0, 1)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::SUGAR, 0, 1),
"S"
))->setIngredient("S", Item::get(Item::SUGARCANE, 0, 1)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::BED, 0, 1),
"WWW",
"PPP"
))->setIngredient("W", Item::get(Item::WOOL, null, 3))->setIngredient("P", Item::get(Item::WOODEN_PLANK, null, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::CHEST, 0, 1),
"PPP",
"P P",
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, null, 8)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE, 0, 3),
"PSP",
"PSP"
))->setIngredient("S", Item::get(Item::STICK, 0, 2))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::OAK, 4)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE, Planks::SPRUCE, 3),
"PSP",
"PSP"
))->setIngredient("S", Item::get(Item::STICK, 0, 2))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::SPRUCE, 4)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE, Planks::BIRCH, 3),
"PSP",
"PSP"
))->setIngredient("S", Item::get(Item::STICK, 0, 2))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::BIRCH, 4)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE, Planks::JUNGLE, 3),
"PSP",
"PSP"
))->setIngredient("S", Item::get(Item::STICK, 0, 2))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::JUNGLE, 4)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE, Planks::ACACIA, 3),
"PSP",
"PSP"
))->setIngredient("S", Item::get(Item::STICK, 0, 2))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::ACACIA, 4)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE, Planks::DARK_OAK, 3),
"PSP",
"PSP"
))->setIngredient("S", Item::get(Item::STICK, 0, 2))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::DARK_OAK, 4)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE_GATE, 0, 1),
"SPS",
"SPS"
))->setIngredient("S", Item::get(Item::STICK, 0, 4))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::OAK, 2)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE_GATE_SPRUCE, 0, 1),
"SPS",
"SPS"
))->setIngredient("S", Item::get(Item::STICK, 0, 4))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::SPRUCE, 2)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE_GATE_BIRCH, 0, 1),
"SPS",
"SPS"
))->setIngredient("S", Item::get(Item::STICK, 0, 4))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::BIRCH, 2)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE_GATE_JUNGLE, 0, 1),
"SPS",
"SPS"
))->setIngredient("S", Item::get(Item::STICK, 0, 4))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::JUNGLE, 2)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE_GATE_DARK_OAK, 0, 1),
"SPS",
"SPS"
))->setIngredient("S", Item::get(Item::STICK, 0, 4))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::DARK_OAK, 2)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FENCE_GATE_ACACIA, 0, 1),
"SPS",
"SPS"
))->setIngredient("S", Item::get(Item::STICK, 0, 4))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::ACACIA, 2)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FURNACE, 0, 1),
"CCC",
"C C",
"CCC"
))->setIngredient("C", Item::get(Item::COBBLESTONE, 0, 8)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::GLASS_PANE, 0, 16),
"GGG",
"GGG"
))->setIngredient("G", Item::get(Item::GLASS, 0, 6)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::LADDER, 0, 2),
"S S",
"SSS",
"S S"
))->setIngredient("S", Item::get(Item::STICK, 0, 7)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::TRAPDOOR, 0, 2),
"PPP",
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, null, 6)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::WOODEN_DOOR, 0, 1),
"PP",
"PP",
"PP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, null, 6)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::WOODEN_STAIRS, 0, 4),
" P",
" PP",
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::OAK, 6)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::WOOD_SLAB, Planks::OAK, 6),
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::OAK, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::SPRUCE_WOOD_STAIRS, 0, 4),
" P",
" PP",
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::SPRUCE, 6)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::WOOD_SLAB, Planks::SPRUCE, 6),
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::SPRUCE, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::BIRCH_WOOD_STAIRS, 0, 4),
" P",
" PP",
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::BIRCH, 6)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::WOOD_SLAB, Planks::BIRCH, 6),
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::BIRCH, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::JUNGLE_WOOD_STAIRS, 0, 4),
"P",
"PP",
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::JUNGLE, 6)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::WOOD_SLAB, Planks::JUNGLE, 6),
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::JUNGLE, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::ACACIA_WOOD_STAIRS, 0, 4),
" P",
" PP",
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::ACACIA, 6)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::WOOD_SLAB, Planks::ACACIA, 6),
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::ACACIA, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::DARK_OAK_WOOD_STAIRS, 0, 4),
" P",
" PP",
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::DARK_OAK, 6)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::WOOD_SLAB, Planks::DARK_OAK, 6),
"PPP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, Planks::DARK_OAK, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::BUCKET, 0, 1),
"I I",
" I"
))->setIngredient("I", Item::get(Item::IRON_INGOT, 0, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::CLOCK, 0, 1),
" G",
"GR",
" G"
))->setIngredient("G", Item::get(Item::GOLD_INGOT, 0, 4))->setIngredient("R", Item::get(Item::REDSTONE_DUST, 0, 1)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::COMPASS, 0, 1),
" I ",
"IRI",
" I"
))->setIngredient("I", Item::get(Item::IRON_INGOT, 0, 4))->setIngredient("R", Item::get(Item::REDSTONE_DUST, 0, 1)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::TNT, 0, 1),
"GSG",
"SGS",
"GSG"
))->setIngredient("G", Item::get(Item::GUNPOWDER, 0, 5))->setIngredient("S", Item::get(Item::SAND, null, 4)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::BOWL, 0, 4),
"P P",
" P"
))->setIngredient("P", Item::get(Item::WOODEN_PLANKS, null, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::MINECART, 0, 1),
"I I",
"III"
))->setIngredient("I", Item::get(Item::IRON_INGOT, 0, 5)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::BOOK, 0, 1),
"P P",
" P "
))->setIngredient("P", Item::get(Item::PAPER, 0, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::BOOKSHELF, 0, 1),
"PBP",
"PBP",
"PBP"
))->setIngredient("P", Item::get(Item::WOODEN_PLANK, null, 6))->setIngredient("B", Item::get(Item::BOOK, 0, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::PAINTING, 0, 1),
"SSS",
"SWS",
"SSS"
))->setIngredient("S", Item::get(Item::STICK, 0, 8))->setIngredient("W", Item::get(Item::WOOL, null, 1)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::PAPER, 0, 3),
"SS",
"S"
))->setIngredient("S", Item::get(Item::SUGARCANE, 0, 3)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::SIGN, 0, 3),
"PPP",
"PPP",
" S"
))->setIngredient("S", Item::get(Item::STICK, 0, 1))->setIngredient("P", Item::get(Item::WOODEN_PLANKS, null, 6))); //TODO: check if it gives one sign or three
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::IRON_BARS, 0, 16),
"III",
"III",
"III"
))->setIngredient("I", Item::get(Item::IRON_INGOT, 0, 9)));
} }
protected function registerFurnace(){ protected function registerFurnace(){
@ -142,37 +382,141 @@ class CraftingManager{
} }
protected function registerStonecutter(){ protected function registerStonecutter(){
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::QUARTZ_BLOCK, 0, 1)))->addIngredient(Item::get(Item::QUARTZ, 0, 4))); $shapes = [
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::BRICK_STAIRS, 0, 4)))->addIngredient(Item::get(Item::BRICKS_BLOCK, 0, 6))); "slab" => [
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::BRICKS_BLOCK, 0, 1)))->addIngredient(Item::get(Item::BRICK, 0, 4))); " ",
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::SLAB, 4, 6)))->addIngredient(Item::get(Item::BRICKS_BLOCK, 0, 3))); "XXX",
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::QUARTZ_BLOCK, 1, 1)))->addIngredient(Item::get(Item::SLAB, 6, 2))); " "
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::SLAB, 3, 6)))->addIngredient(Item::get(Item::COBBLESTONE, 0, 3))); ],
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::COBBLESTONE_WALL, 0, 6)))->addIngredient(Item::get(Item::COBBLESTONE, 0, 6))); "stairs" => [
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::COBBLESTONE_WALL, 1, 6)))->addIngredient(Item::get(Item::MOSS_STONE, 0, 6))); "X ",
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::NETHER_BRICKS, 0, 1)))->addIngredient(Item::get(Item::NETHER_BRICK, 0, 4))); "XX ",
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::NETHER_BRICKS_STAIRS, 0, 4)))->addIngredient(Item::get(Item::NETHER_BRICKS, 0, 6))); "XXX"
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::QUARTZ_BLOCK, 2, 2)))->addIngredient(Item::get(Item::QUARTZ_BLOCK, 0, 2))); ],
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::SLAB, 6, 6)))->addIngredient(Item::get(Item::QUARTZ_BLOCK, 0, 3))); "wall/fence" => [
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::SANDSTONE_STAIRS, 0, 4)))->addIngredient(Item::get(Item::SANDSTONE, 0, 6))); "XXX",
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::SANDSTONE, 0, 1)))->addIngredient(Item::get(Item::SAND, 0, 4))); "XXX",
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::SANDSTONE, 2, 4)))->addIngredient(Item::get(Item::SANDSTONE, 0, 4))); " "
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::SANDSTONE, 1, 1)))->addIngredient(Item::get(Item::SLAB, 1, 2))); ],
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::SLAB, 1, 6)))->addIngredient(Item::get(Item::SANDSTONE, 0, 3))); "blockrecipe1" => [
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::STONE_BRICK_STAIRS, 0, 4)))->addIngredient(Item::get(Item::STONE_BRICK, null, 6))); "XX",
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::STONE_BRICK, 0, 4)))->addIngredient(Item::get(Item::STONE, null, 4))); "XX"
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::STONE_BRICK, 3, 1)))->addIngredient(Item::get(Item::SLAB, 5, 2))); ],
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::STONE_BRICK, 1, 1)))->addIngredient(Item::get(Item::STONE_BRICK, 0, 1))->addIngredient(Item::get(Item::VINES, 0, 1))); "blockrecipe2X1" => [
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::SLAB, 5, 6)))->addIngredient(Item::get(Item::STONE_BRICK, null, 3))); " ",
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::SLAB, 0, 6)))->addIngredient(Item::get(Item::STONE, null, 3))); " X ",
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::COBBLESTONE_STAIRS, 0, 4)))->addIngredient(Item::get(Item::COBBLESTONE, 0, 6))); " X "
],
"blockrecipe2X2" => [
"AB",
"BA"
],
"blockrecipe1X2" => [
" ",
"AB"
]
];
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::STONE, Stone::POLISHED_GRANITE, 4)))->addIngredient(Item::get(Item::STONE, Stone::GRANITE, 4))); $buildRecipes = [];
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::STONE, Stone::POLISHED_DIORITE, 4)))->addIngredient(Item::get(Item::STONE, Stone::DIORITE, 4)));
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::STONE, Stone::POLISHED_ANDESITE, 4)))->addIngredient(Item::get(Item::STONE, Stone::ANDESITE, 4))); // Single ingedient stone cutter recipes:
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::STONE, Stone::GRANITE, 1)))->addIngredient(Item::get(Item::STONE, Stone::DIORITE, 1))->addIngredient(Item::get(Item::QUARTZ, 0, 1))); $RESULT_ITEMID = 0; $RESULT_META = 1; $INGREDIENT_ITEMID = 2; $INGREDIENT_META = 3; $RECIPE_SHAPE = 4;$RESULT_AMOUNT = 5;
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::STONE, Stone::DIORITE, 2)))->addIngredient(Item::get(Item::COBBLESTONE, 0, 2))->addIngredient(Item::get(Item::QUARTZ, 0, 2))); $recipes = [
$this->registerRecipe((new StonecutterShapelessRecipe(Item::get(Item::STONE, Stone::ANDESITE, 2)))->addIngredient(Item::get(Item::COBBLESTONE, 0, 1))->addIngredient(Item::get(Item::STONE, Stone::DIORITE, 1))); //RESULT_ITEM_ID RESULT_META INGREDIENT_ITEMID INGREDIENT_META RECIPE_SHAPE RESULT_AMOUNT
[Item::SLAB, Slab::STONE, Item::STONE, Stone::NORMAL, "slab", 6],
[Item::SLAB, Slab::COBBLESTONE, Item::COBBLESTONE, 0, "slab", 6],
[Item::SLAB, Slab::SANDSTONE, Item::SANDSTONE, 0, "slab", 6],
[Item::SLAB, Slab::BRICK, Item::BRICK, 0, "slab", 6],
[Item::SLAB, Slab::STONE_BRICK, Item::STONE_BRICK, StoneBricks::NORMAL,"slab", 6],
[Item::SLAB, Slab::NETHER_BRICK, Item::NETHER_BRICK_BLOCK, 0, "slab", 6],
[Item::SLAB, Slab::QUARTZ, Item::QUARTZ_BLOCK, 0, "slab", 6],
[Item::COBBLESTONE_STAIRS, 0, Item::COBBLESTONE, 0, "stairs", 4],
[Item::SANDSTONE_STAIRS, 0, Item::SANDSTONE, 0, "stairs", 4],
[Item::STONE_BRICK_STAIRS, 0, Item::STONE_BRICK, StoneBricks::NORMAL,"stairs", 4],
[Item::BRICK_STAIRS, 0, Item::BRICKS_BLOCK, 0, "stairs", 4],
[Item::NETHER_BRICKS_STAIRS,0, Item::NETHER_BRICK_BLOCK, 0, "stairs", 4],
[Item::COBBLESTONE_WALL, StoneWall::NONE_MOSSY_WALL, Item::COBBLESTONE, 0, "wall/fence", 6],
[Item::COBBLESTONE_WALL, StoneWall::MOSSY_WALL, Item::MOSSY_STONE, 0, "wall/fence", 6],
[Item::NETHER_BRICK_FENCE, 0, Item::NETHER_BRICK_BLOCK, 0, "wall/fence", 6],
[Item::NETHER_BRICKS, 0, Item::NETHER_BRICK, 0, "blockrecipe1", 1],
[Item::SANDSTONE, SandStone::NORMAL, Item::SAND, 0, "blockrecipe1", 1],
[Item::SANDSTONE, Sandstone::CHISELED, Item::SANDSTONE, SandStone::NORMAL, "blockrecipe1", 4],
[Item::STONE_BRICK, StoneBricks::NORMAL, Item::STONE, Stone::NORMAL, "blockrecipe1", 4],
[Item::STONE_BRICK, StoneBricks::NORMAL, Item::STONE, Stone::POLISHED_GRANITE,"blockrecipe1", 4],
[Item::STONE_BRICK, StoneBricks::NORMAL, Item::STONE, Stone::POLISHED_DIORITE,"blockrecipe1", 4],
[Item::STONE_BRICK, StoneBricks::NORMAL, Item::STONE, Stone::POLISHED_ANDESITE,"blockrecipe1",4],
[Item::STONE, Stone::POLISHED_GRANITE, Item::STONE, Stone::GRANITE, "blockrecipe1", 4],
[Item::STONE, Stone::POLISHED_DIORITE, Item::STONE, Stone::DIORITE, "blockrecipe1", 4],
[Item::STONE, Stone::POLISHED_ANDESITE, Item::STONE, Stone::ANDESITE, "blockrecipe1", 4],
[Item::QUARTZ_BLOCK, Quartz::QUARTZ_NORMAL, Item::QUARTZ, Stone::ANDESITE, "blockrecipe1", 4],
[Item::QUARTZ_BLOCK, Quartz::QUARTZ_CHISELED, Item::SLAB, Slab::QUARTZ, "blockrecipe2X1", 1],
[Item::SANDSTONE, SandStone::CHISELED, Item::SLAB, Slab::SANDSTONE, "blockrecipe2X1", 1],
[Item::STONE_BRICK, StoneBricks::CHISELED, Item::SLAB, Slab::STONE_BRICK, "blockrecipe2X1", 1],
];
foreach ($recipes as $recipe){
$buildRecipes[] = $this->createOneIngedientRecipe($shapes[$recipe[$RECIPE_SHAPE]], $recipe[$RESULT_ITEMID], $recipe[$RESULT_META], $recipe[$RESULT_AMOUNT], $recipe[$INGREDIENT_ITEMID], $recipe[$INGREDIENT_META], "X", "Stonecutter");
}
// Multi-ingredient stone recipes:
$buildRecipes[] = ((new StonecutterShapedRecipe(Item::get(Item::STONE, Stone::GRANITE, 1),
...$shapes["blockrecipe1X2"]
))->setIngredient("A", Item::get(Item::STONE, Stone::DIORITE, 1))->setIngredient("B", Item::get(Item::QUARTZ, Quartz::QUARTZ_NORMAL, 1)));
$buildRecipes[] = ((new StonecutterShapedRecipe(Item::get(Item::STONE, Stone::DIORITE, 2),
...$shapes["blockrecipe2X2"]
))->setIngredient("A", Item::get(Item::COBBLESTONE, 0, 2))->setIngredient("B", Item::get(Item::QUARTZ, 0, 2)));
$buildRecipes[] = ((new StonecutterShapedRecipe(Item::get(Item::STONE, Stone::ANDESITE, 2),
...$shapes["blockrecipe1X2"]
))->setIngredient("A", Item::get(Item::COBBLESTONE, 0, 1))->setIngredient("B", Item::get(Item::STONE, Stone::DIORITE, 1)));
$buildRecipes[] = ((new StonecutterShapedRecipe(Item::get(Item::STONE_BRICK, StoneBricks::MOSSY, 1),
...$shapes["blockrecipe1X2"]
))->setIngredient("A", Item::get(Item::STONE_BRICK, StoneBricks::NORMAL, 1))->setIngredient("B", Item::get(Item::VINES, 0, 1)));
$this->sortAndAddRecipesArray($buildRecipes);
}
private function sortAndAddRecipesArray(&$recipes){
// Sort the recipes based on the result item name with the bubblesort algoritm.
for ($i = 0; $i < count($recipes); ++$i){
$current = $recipes[$i];
$result = $current->getResult();
for ($j = count($recipes)-1; $j > $i; --$j)
{
if ($this->sort($result, $recipes[$j]->getResult())>0){
$swap = $current;
$current = $recipes[$j];
$recipes[$j] = $swap;
$result = $current->getResult();
}
}
$this->registerRecipe($current);
}
}
private function createOneIngedientRecipe($recipeshape, $resultitem, $resultitemmeta, $resultitemamound, $ingedienttype, $ingredientmeta, $ingredientname, $inventoryType = ""){
$ingredientamount = 0;
$height = 0;
// count how many of the ingredient are in the recipe and check height for big or small recipe.
foreach ($recipeshape as $line){
$height += 1;
$width = strlen($line);
$ingredientamount += substr_count($line, $ingredientname);
}
$recipe = null;
if ($height < 3){
// Process small recipe
$fullClassName = "pocketmine\\inventory\\".$inventoryType."ShapedRecipe";// $ShapeClass."ShapedRecipe";
$recipe = ((new $fullClassName(Item::get($resultitem, $resultitemmeta, $resultitemamound),
...$recipeshape
))->setIngredient($ingredientname, Item::get($ingedienttype, $ingredientmeta, $ingredientamount)));
}
else{
// Process big recipe
$fullClassName = "pocketmine\\inventory\\".$inventoryType."BigShapedRecipe";
$recipe = ((new $fullClassName(Item::get($resultitem, $resultitemmeta, $resultitemamound),
...$recipeshape
))->setIngredient($ingredientname, Item::get($ingedienttype, $ingredientmeta, $ingredientamount)));
}
return $recipe;
} }
protected function registerFood(){ protected function registerFood(){
@ -188,7 +532,6 @@ class CraftingManager{
} }
protected function registerArmor(){ protected function registerArmor(){
$cost = [5, 8, 7, 4];
$types = [ $types = [
[Item::LEATHER, Item::FIRE, Item::IRON_INGOT, Item::DIAMOND, Item::GOLD_INGOT], [Item::LEATHER, Item::FIRE, Item::IRON_INGOT, Item::DIAMOND, Item::GOLD_INGOT],
[Item::LEATHER_CAP, Item::CHAIN_HELMET, Item::IRON_HELMET, Item::DIAMOND_HELMET, Item::GOLD_HELMET], [Item::LEATHER_CAP, Item::CHAIN_HELMET, Item::IRON_HELMET, Item::DIAMOND_HELMET, Item::GOLD_HELMET],
@ -196,31 +539,68 @@ class CraftingManager{
[Item::LEATHER_PANTS, Item::CHAIN_LEGGINGS, Item::IRON_LEGGINGS, Item::DIAMOND_LEGGINGS, Item::GOLD_LEGGINGS], [Item::LEATHER_PANTS, Item::CHAIN_LEGGINGS, Item::IRON_LEGGINGS, Item::DIAMOND_LEGGINGS, Item::GOLD_LEGGINGS],
[Item::LEATHER_BOOTS, Item::CHAIN_BOOTS, Item::IRON_BOOTS, Item::DIAMOND_BOOTS, Item::GOLD_BOOTS], [Item::LEATHER_BOOTS, Item::CHAIN_BOOTS, Item::IRON_BOOTS, Item::DIAMOND_BOOTS, Item::GOLD_BOOTS],
]; ];
$shapes = [
[
"XXX",
"X X",
" "
],
[
"X X",
"XXX",
"XXX"
],
[
"XXX",
"X X",
"X X"
],
[
" ",
"X X",
"X X"
]
];
for($i = 1; $i < 5; ++$i){ for($i = 1; $i < 5; ++$i){
foreach($types[$i] as $j => $type){ foreach($types[$i] as $j => $type){
$this->registerRecipe((new BigShapelessRecipe(Item::get($type, 0, 1)))->addIngredient(Item::get($types[0][$j], 0, $cost[$i - 1]))); $this->registerRecipe((new BigShapedRecipe(Item::get($type, 0, 1), ...$shapes[$i - 1]))->setIngredient("X", Item::get($types[0][$j], 0, 1)));
} }
} }
} }
protected function registerWeapons(){ protected function registerWeapons(){
$cost = [2];
$types = [ $types = [
[Item::WOODEN_PLANK, Item::COBBLESTONE, Item::IRON_INGOT, Item::DIAMOND, Item::GOLD_INGOT], [Item::WOODEN_PLANK, Item::COBBLESTONE, Item::IRON_INGOT, Item::DIAMOND, Item::GOLD_INGOT],
[Item::WOODEN_SWORD, Item::STONE_SWORD, Item::IRON_SWORD, Item::DIAMOND_SWORD, Item::GOLD_SWORD], [Item::WOODEN_SWORD, Item::STONE_SWORD, Item::IRON_SWORD, Item::DIAMOND_SWORD, Item::GOLD_SWORD],
]; ];
for($i = 1; $i < 2; ++$i){ for($i = 1; $i < 2; ++$i){
foreach($types[$i] as $j => $type){ foreach($types[$i] as $j => $type){
$this->registerRecipe((new BigShapelessRecipe(Item::get($type, 0, 1)))->addIngredient(Item::get($types[0][$j], null, $cost[$i - 1]))->addIngredient(Item::get(Item::STICK, 0, 1))); $this->registerRecipe((new BigShapedRecipe(Item::get($type, 0, 1),
" X ",
" X ",
" I "
))->setIngredient("X", Item::get($types[0][$j], null))->setIngredient("I", Item::get(Item::STICK)));
} }
} }
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::ARROW, 0, 1)))->addIngredient(Item::get(Item::STICK, 0, 1))->addIngredient(Item::get(Item::FLINT, 0, 1))->addIngredient(Item::get(Item::FEATHER, 0, 1))); $this->registerRecipe((new BigShapedRecipe(Item::get(Item::ARROW, 0, 1),
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::BOW, 0, 1)))->addIngredient(Item::get(Item::STRING, 0, 3))->addIngredient(Item::get(Item::STICK, 0, 3))); " F ",
" S ",
" P "
))->setIngredient("S", Item::get(Item::STICK))->setIngredient("F", Item::get(Item::FLINT))->setIngredient("P", Item::get(Item::FEATHER)));
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::BOW, 0, 1),
" X~",
"X ~",
" X~"
))->setIngredient("~", Item::get(Item::STRING))->setIngredient("X", Item::get(Item::STICK)));
} }
protected function registerTools(){ protected function registerTools(){
$cost = [3, 1, 3, 2];
$types = [ $types = [
[Item::WOODEN_PLANK, Item::COBBLESTONE, Item::IRON_INGOT, Item::DIAMOND, Item::GOLD_INGOT], [Item::WOODEN_PLANK, Item::COBBLESTONE, Item::IRON_INGOT, Item::DIAMOND, Item::GOLD_INGOT],
[Item::WOODEN_PICKAXE, Item::STONE_PICKAXE, Item::IRON_PICKAXE, Item::DIAMOND_PICKAXE, Item::GOLD_PICKAXE], [Item::WOODEN_PICKAXE, Item::STONE_PICKAXE, Item::IRON_PICKAXE, Item::DIAMOND_PICKAXE, Item::GOLD_PICKAXE],
@ -228,14 +608,44 @@ class CraftingManager{
[Item::WOODEN_AXE, Item::STONE_AXE, Item::IRON_AXE, Item::DIAMOND_AXE, Item::GOLD_AXE], [Item::WOODEN_AXE, Item::STONE_AXE, Item::IRON_AXE, Item::DIAMOND_AXE, Item::GOLD_AXE],
[Item::WOODEN_HOE, Item::STONE_HOE, Item::IRON_HOE, Item::DIAMOND_HOE, Item::GOLD_HOE], [Item::WOODEN_HOE, Item::STONE_HOE, Item::IRON_HOE, Item::DIAMOND_HOE, Item::GOLD_HOE],
]; ];
$shapes = [
[
"XXX",
" I ",
" I "
],
[
" X ",
" I ",
" I "
],
[
"XX ",
"XI ",
" I "
],
[
"XX ",
" I ",
" I "
]
];
for($i = 1; $i < 5; ++$i){ for($i = 1; $i < 5; ++$i){
foreach($types[$i] as $j => $type){ foreach($types[$i] as $j => $type){
$this->registerRecipe((new BigShapelessRecipe(Item::get($type, 0, 1)))->addIngredient(Item::get($types[0][$j], null, $cost[$i - 1]))->addIngredient(Item::get(Item::STICK, 0, 2))); $this->registerRecipe((new BigShapedRecipe(Item::get($type, 0, 1), ...$shapes[$i - 1]))->setIngredient("X", Item::get($types[0][$j], null))->setIngredient("I", Item::get(Item::STICK)));
} }
} }
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::FLINT_AND_STEEL, 0, 1)))->addIngredient(Item::get(Item::IRON_INGOT, 0, 1))->addIngredient(Item::get(Item::FLINT, 0, 1))); $this->registerRecipe((new ShapedRecipe(Item::get(Item::FLINT_AND_STEEL, 0, 1),
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::SHEARS, 0, 1)))->addIngredient(Item::get(Item::IRON_INGOT, 0, 2))); " S",
"F "
))->setIngredient("F", Item::get(Item::FLINT))->setIngredient("S", Item::get(Item::IRON_INGOT)));
$this->registerRecipe((new ShapedRecipe(Item::get(Item::SHEARS, 0, 1),
" X",
"X "
))->setIngredient("X", Item::get(Item::IRON_INGOT)));
} }
protected function registerDyes(){ protected function registerDyes(){
@ -243,9 +653,9 @@ class CraftingManager{
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOOL, 15 - $i, 1)))->addIngredient(Item::get(Item::DYE, $i, 1))->addIngredient(Item::get(Item::WOOL, 0, 1))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOOL, 15 - $i, 1)))->addIngredient(Item::get(Item::DYE, $i, 1))->addIngredient(Item::get(Item::WOOL, 0, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::STAINED_CLAY, 15 - $i, 8)))->addIngredient(Item::get(Item::DYE, $i, 1))->addIngredient(Item::get(Item::HARDENED_CLAY, 0, 8))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::STAINED_CLAY, 15 - $i, 8)))->addIngredient(Item::get(Item::DYE, $i, 1))->addIngredient(Item::get(Item::HARDENED_CLAY, 0, 8)));
//TODO: add glass things? //TODO: add glass things?
//$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOOL, 15 - $i, 1)))->addIngredient(Item::get(Item::DYE, $i, 1))->addIngredient(Item::get(Item::WOOL, 0, 1))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOOL, 15 - $i, 1)))->addIngredient(Item::get(Item::DYE, $i, 1))->addIngredient(Item::get(Item::WOOL, 0, 1)));
//$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOOL, 15 - $i, 1)))->addIngredient(Item::get(Item::DYE, $i, 1))->addIngredient(Item::get(Item::WOOL, 0, 1))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOOL, 15 - $i, 1)))->addIngredient(Item::get(Item::DYE, $i, 1))->addIngredient(Item::get(Item::WOOL, 0, 1)));
//$this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOOL, 15 - $i, 1)))->addIngredient(Item::get(Item::DYE, $i, 1))->addIngredient(Item::get(Item::WOOL, 0, 1))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::WOOL, 15 - $i, 1)))->addIngredient(Item::get(Item::DYE, $i, 1))->addIngredient(Item::get(Item::WOOL, 0, 1)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::CARPET, $i, 3)))->addIngredient(Item::get(Item::WOOL, $i, 2))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::CARPET, $i, 3)))->addIngredient(Item::get(Item::WOOL, $i, 2)));
} }
@ -291,8 +701,8 @@ class CraftingManager{
$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::LAPIS_BLOCK, 0, 1)))->addIngredient(Item::get(Item::DYE, 4, 9))); $this->registerRecipe((new BigShapelessRecipe(Item::get(Item::LAPIS_BLOCK, 0, 1)))->addIngredient(Item::get(Item::DYE, 4, 9)));
$this->registerRecipe((new ShapelessRecipe(Item::get(Item::DYE, 4, 9)))->addIngredient(Item::get(Item::LAPIS_BLOCK, 0, 1))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::DYE, 4, 9)))->addIngredient(Item::get(Item::LAPIS_BLOCK, 0, 1)));
//$this->registerRecipe((new BigShapelessRecipe(Item::get(Item::GOLD_INGOT, 0, 1)))->addIngredient(Item::get(Item::GOLD_NUGGET, 0, 9))); $this->registerRecipe((new BigShapelessRecipe(Item::get(Item::GOLD_INGOT, 0, 1)))->addIngredient(Item::get(Item::GOLD_NUGGET, 0, 9)));
//$this->registerRecipe((new ShapelessRecipe(Item::get(Item::GOLD_NUGGET, 0, 9)))->addIngredient(Item::get(Item::GOLD_INGOT, 0, 1))); $this->registerRecipe((new ShapelessRecipe(Item::get(Item::GOLD_NUGGET, 0, 9)))->addIngredient(Item::get(Item::GOLD_INGOT, 0, 1)));
} }
@ -314,6 +724,14 @@ class CraftingManager{
} }
} }
/**
* @param UUID $id
* @return Recipe
*/
public function getRecipe(UUID $id){
$index = $id->toBinary();
return isset($this->recipes[$index]) ? $this->recipes[$index] : null;
}
/** /**
* @return Recipe[] * @return Recipe[]
@ -348,7 +766,22 @@ class CraftingManager{
* @param ShapedRecipe $recipe * @param ShapedRecipe $recipe
*/ */
public function registerShapedRecipe(ShapedRecipe $recipe){ public function registerShapedRecipe(ShapedRecipe $recipe){
$result = $recipe->getResult();
$this->recipes[$recipe->getId()->toBinary()] = $recipe;
$ingredients = $recipe->getIngredientMap();
$hash = "";
foreach($ingredients as $v){
foreach($v as $item){
if($item !== null){
/** @var Item $item */
$hash .= $item->getId() . ":" . ($item->getDamage() === null ? "?" : $item->getDamage()) . "x" . $item->getCount() . ",";
}
}
$hash .= ";";
}
$this->recipeLookup[$result->getId() . ":" . $result->getDamage()][$hash] = $recipe;
} }
/** /**
@ -356,7 +789,7 @@ class CraftingManager{
*/ */
public function registerShapelessRecipe(ShapelessRecipe $recipe){ public function registerShapelessRecipe(ShapelessRecipe $recipe){
$result = $recipe->getResult(); $result = $recipe->getResult();
$this->recipes[spl_object_hash($recipe)] = $recipe; $this->recipes[$recipe->getId()->toBinary()] = $recipe;
$hash = ""; $hash = "";
$ingredients = $recipe->getIngredientList(); $ingredients = $recipe->getIngredientList();
usort($ingredients, [$this, "sort"]); usort($ingredients, [$this, "sort"]);
@ -404,7 +837,7 @@ class CraftingManager{
foreach($ingredients as $item){ foreach($ingredients as $item){
$amount = $item->getCount(); $amount = $item->getCount();
foreach($checkInput as $k => $checkItem){ foreach($checkInput as $k => $checkItem){
if($checkItem->equals($item, $checkItem->getDamage() === null ? false : true)){ if($checkItem->equals($item, $checkItem->getDamage() === null ? false : true, $checkItem->getCompoundTag() === null ? false : true)){
$remove = min($checkItem->getCount(), $amount); $remove = min($checkItem->getCount(), $amount);
$checkItem->setCount($checkItem->getCount() - $remove); $checkItem->setCount($checkItem->getCount() - $remove);
if($checkItem->getCount() === 0){ if($checkItem->getCount() === 0){
@ -432,86 +865,12 @@ 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, [$this, "sort"]);
$inputCount = 0;
foreach($input as $item){
$inputCount += $item->getCount();
$hash .= $item->getId() . ":" . ($item->getDamage() === null ? "?" : $item->getDamage()) . "x" . $item->getCount() . ",";
}
if(!isset($this->recipeLookup[$k][$hash])){
$hasRecipe = null;
foreach($this->recipeLookup[$k] as $recipe){
if($recipe instanceof ShapelessRecipe){
if($recipe->getIngredientCount() !== $inputCount){
continue;
}
$checkInput = $recipe->getIngredientList();
foreach($input as $item){
$amount = $item->getCount();
foreach($checkInput as $k => $checkItem){
if($checkItem->equals($item, $checkItem->getDamage() === null ? false : true)){
$remove = min($checkItem->getCount(), $amount);
$checkItem->setCount($checkItem->getCount() - $remove);
if($checkItem->getCount() === 0){
unset($checkInput[$k]);
}
$amount -= $remove;
if($amount === 0){
break;
}
}
}
}
if(count($checkInput) === 0){
$hasRecipe = $recipe;
break;
}
}
if($hasRecipe instanceof Recipe){
break;
}
}
if($hasRecipe === null){
return false;
}
$recipe = $hasRecipe;
}else{
$recipe = $this->recipeLookup[$k][$hash];
}
$checkResult = $recipe->getResult();
if($checkResult->equals($result, true) and $checkResult->getCount() === $result->getCount()){
return $recipe;
}
return null;
}
/** /**
* @param Recipe $recipe * @param Recipe $recipe
*/ */
public function registerRecipe(Recipe $recipe){ public function registerRecipe(Recipe $recipe){
$recipe->setId(UUID::fromData(++self::$RECIPE_COUNT, $recipe->getResult()->getId(), $recipe->getResult()->getDamage(), $recipe->getResult()->getCount(), $recipe->getResult()->getCompoundTag()));
if($recipe instanceof ShapedRecipe){ if($recipe instanceof ShapedRecipe){
$this->registerShapedRecipe($recipe); $this->registerShapedRecipe($recipe);
}elseif($recipe instanceof ShapelessRecipe){ }elseif($recipe instanceof ShapelessRecipe){

View File

@ -1,111 +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\inventory;
use pocketmine\event\inventory\CraftItemEvent;
use pocketmine\item\Item;
use pocketmine\Server;
class CraftingTransactionGroup extends SimpleTransactionGroup{
/** @var Item[] */
protected $input = [];
/** @var Item[] */
protected $output = [];
/** @var Recipe */
protected $recipe = null;
public function __construct(SimpleTransactionGroup $group){
parent::__construct();
$this->transactions = $group->getTransactions();
$this->inventories = $group->getInventories();
$this->source = $group->getSource();
$this->matchItems($this->output, $this->input);
}
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(){
if(count($this->output) !== 1 or count($this->input) === 0){
return false;
}
return $this->getMatchingRecipe() instanceof Recipe;
}
/**
* @return Recipe
*/
public function getMatchingRecipe(){
if($this->recipe === null){
$this->recipe = Server::getInstance()->getCraftingManager()->matchTransaction($this);
}
return $this->recipe;
}
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->getSource());
}
$this->hasExecuted = true;
return true;
}
}

View File

@ -24,9 +24,9 @@ namespace pocketmine\inventory;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\network\Network; use pocketmine\network\Network;
use pocketmine\network\protocol\TileEventPacket; use pocketmine\network\protocol\BlockEventPacket;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\Server;
use pocketmine\tile\Chest; use pocketmine\tile\Chest;
class DoubleChestInventory extends ChestInventory implements InventoryHolder{ class DoubleChestInventory extends ChestInventory implements InventoryHolder{
@ -99,28 +99,28 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{
parent::onOpen($who); parent::onOpen($who);
if(count($this->getViewers()) === 1){ if(count($this->getViewers()) === 1){
$pk = new TileEventPacket(); $pk = new BlockEventPacket();
$pk->x = $this->right->getHolder()->getX(); $pk->x = $this->right->getHolder()->getX();
$pk->y = $this->right->getHolder()->getY(); $pk->y = $this->right->getHolder()->getY();
$pk->z = $this->right->getHolder()->getZ(); $pk->z = $this->right->getHolder()->getZ();
$pk->case1 = 1; $pk->case1 = 1;
$pk->case2 = 2; $pk->case2 = 2;
if(($level = $this->right->getHolder()->getLevel()) instanceof Level){ if(($level = $this->right->getHolder()->getLevel()) instanceof Level){
$level->addChunkPacket($this->right->getHolder()->getX() >> 4, $this->right->getHolder()->getZ() >> 4, $pk->setChannel(Network::CHANNEL_WORLD_EVENTS)); $level->addChunkPacket($this->right->getHolder()->getX() >> 4, $this->right->getHolder()->getZ() >> 4, $pk);
} }
} }
} }
public function onClose(Player $who){ public function onClose(Player $who){
if(count($this->getViewers()) === 1){ if(count($this->getViewers()) === 1){
$pk = new TileEventPacket(); $pk = new BlockEventPacket();
$pk->x = $this->right->getHolder()->getX(); $pk->x = $this->right->getHolder()->getX();
$pk->y = $this->right->getHolder()->getY(); $pk->y = $this->right->getHolder()->getY();
$pk->z = $this->right->getHolder()->getZ(); $pk->z = $this->right->getHolder()->getZ();
$pk->case1 = 1; $pk->case1 = 1;
$pk->case2 = 0; $pk->case2 = 0;
if(($level = $this->right->getHolder()->getLevel()) instanceof Level){ if(($level = $this->right->getHolder()->getLevel()) instanceof Level){
$level->addChunkPacket($this->right->getHolder()->getX() >> 4, $this->right->getHolder()->getZ() >> 4, $pk->setChannel(Network::CHANNEL_WORLD_EVENTS)); $level->addChunkPacket($this->right->getHolder()->getX() >> 4, $this->right->getHolder()->getZ() >> 4, $pk);
} }
} }
parent::onClose($who); parent::onClose($who);

View File

@ -0,0 +1,47 @@
<?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\level\Position;
use pocketmine\Player;
class EnchantInventory extends ContainerInventory{
public function __construct(Position $pos){
parent::__construct(new FakeBlockMenu($this, $pos), InventoryType::get(InventoryType::ENCHANT_TABLE));
}
/**
* @return FakeBlockMenu
*/
public function getHolder(){
return $this->holder;
}
public function onClose(Player $who){
parent::onClose($who);
for($i = 0; $i < 2; ++$i){
$this->getHolder()->getLevel()->dropItem($this->getHolder()->add(0.5, 0.5, 0.5), $this->getItem($i));
$this->clear($i);
}
}
}

Some files were not shown because too many files have changed in this diff Show More