Implemented Stonecutter (#4732)

This commit is contained in:
ipad54 2022-05-17 18:01:03 +03:00 committed by GitHub
parent 8b8560a701
commit 1e59679ec2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 182 additions and 8 deletions

View File

@ -394,6 +394,7 @@ class BlockFactory{
$this->registerAllMeta(new Stair(new BID(Ids::STONE_BRICK_STAIRS, 0), "Stone Brick Stairs", $stoneBreakInfo));
$this->registerAllMeta(new Stair(new BID(Ids::MOSSY_STONE_BRICK_STAIRS, 0), "Mossy Stone Brick Stairs", $stoneBreakInfo));
$this->registerAllMeta(new StoneButton(new BID(Ids::STONE_BUTTON, 0), "Stone Button", new BlockBreakInfo(0.5, BlockToolType::PICKAXE)));
$this->registerAllMeta(new Stonecutter(new BID(Ids::STONECUTTER_BLOCK, 0, ItemIds::STONECUTTER_BLOCK), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE)));
$this->registerAllMeta(new StonePressurePlate(new BID(Ids::STONE_PRESSURE_PLATE, 0), "Stone Pressure Plate", new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
//TODO: in the future this won't be the same for all the types
@ -434,7 +435,7 @@ class BlockFactory{
$this->registerSlabWithDoubleHighBitsRemapping($slabType);
}
$this->registerAllMeta(new Opaque(new BID(Ids::STONECUTTER, 0), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
$this->registerAllMeta(new Opaque(new BID(Ids::STONECUTTER, 0), "Legacy Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
$this->registerAllMeta(new Sugarcane(new BID(Ids::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane", BlockBreakInfo::instant()));
$this->registerAllMeta(new SweetBerryBush(new BID(Ids::SWEET_BERRY_BUSH, 0, ItemIds::SWEET_BERRIES), "Sweet Berry Bush", BlockBreakInfo::instant()));
$this->registerAllMeta(new TNT(new BID(Ids::TNT, 0), "TNT", BlockBreakInfo::instant()));
@ -644,7 +645,6 @@ class BlockFactory{
//TODO: minecraft:seagrass
//TODO: minecraft:smithing_table
//TODO: minecraft:sticky_piston
//TODO: minecraft:stonecutter_block
//TODO: minecraft:structure_block
//TODO: minecraft:turtle_egg
//endregion

62
src/block/Stonecutter.php Normal file
View File

@ -0,0 +1,62 @@
<?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/
*
*
*/
declare(strict_types=1);
namespace pocketmine\block;
use pocketmine\block\inventory\StonecutterInventory;
use pocketmine\block\utils\BlockDataSerializer;
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
use pocketmine\block\utils\HorizontalFacingTrait;
use pocketmine\item\Item;
use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Facing;
use pocketmine\math\Vector3;
use pocketmine\player\Player;
class Stonecutter extends Transparent{
use FacesOppositePlacingPlayerTrait;
use HorizontalFacingTrait;
public function writeStateToMeta() : int{
return BlockDataSerializer::writeHorizontalFacing($this->facing);
}
public function readStateFromData(int $id, int $stateMeta) : void{
$this->facing = BlockDataSerializer::readHorizontalFacing($stateMeta);
}
public function getStateBitmask() : int{
return 0b111;
}
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
if($player !== null){
$player->setCurrentWindow(new StonecutterInventory($this->position));
}
return true;
}
protected function recalculateCollisionBoxes() : array{
return [AxisAlignedBB::one()->trim(Facing::UP, 7 / 16)];
}
}

View File

@ -529,6 +529,7 @@ use pocketmine\utils\CloningRegistryTrait;
* @method static StainedHardenedGlass STAINED_HARDENED_GLASS()
* @method static StainedHardenedGlassPane STAINED_HARDENED_GLASS_PANE()
* @method static Opaque STONE()
* @method static Stonecutter STONECUTTER()
* @method static Opaque STONE_BRICKS()
* @method static Slab STONE_BRICK_SLAB()
* @method static Stair STONE_BRICK_STAIRS()
@ -1099,6 +1100,7 @@ final class VanillaBlocks{
self::register("stone_pressure_plate", $factory->get(Ids::STONE_PRESSURE_PLATE, 0));
self::register("stone_slab", $factory->get(Ids::STONE_SLAB4, 2));
self::register("stone_stairs", $factory->get(Ids::NORMAL_STONE_STAIRS, 0));
self::register("stonecutter", $factory->get(Ids::STONECUTTER_BLOCK, 2));
self::register("stripped_acacia_log", $factory->get(Ids::STRIPPED_ACACIA_LOG, 0));
self::register("stripped_acacia_wood", $factory->get(Ids::WOOD, 12));
self::register("stripped_birch_log", $factory->get(Ids::STRIPPED_BIRCH_LOG, 0));

View File

@ -0,0 +1,39 @@
<?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/
*
*
*/
declare(strict_types=1);
namespace pocketmine\block\inventory;
use pocketmine\inventory\SimpleInventory;
use pocketmine\inventory\TemporaryInventory;
use pocketmine\world\Position;
class StonecutterInventory extends SimpleInventory implements BlockInventory, TemporaryInventory{
use BlockInventoryTrait;
public const SLOT_INPUT = 0;
public function __construct(Position $holder){
$this->holder = $holder;
parent::__construct(1);
}
}

View File

@ -43,12 +43,19 @@ final class CraftingManagerFromDataHelper{
$itemDeserializerFunc = \Closure::fromCallable([Item::class, 'jsonDeserialize']);
foreach($recipes["shapeless"] as $recipe){
if($recipe["block"] !== "crafting_table"){ //TODO: filter others out for now to avoid breaking economics
$recipeType = match($recipe["block"]){
"crafting_table" => ShapelessRecipeType::CRAFTING(),
"stonecutter" => ShapelessRecipeType::STONECUTTER(),
//TODO: Cartography Table
default => null
};
if($recipeType === null){
continue;
}
$result->registerShapelessRecipe(new ShapelessRecipe(
array_map($itemDeserializerFunc, $recipe["input"]),
array_map($itemDeserializerFunc, $recipe["output"])
array_map($itemDeserializerFunc, $recipe["output"]),
$recipeType
));
}
foreach($recipes["shaped"] as $recipe){

View File

@ -32,12 +32,15 @@ class ShapelessRecipe implements CraftingRecipe{
private array $ingredients = [];
/** @var Item[] */
private array $results;
private ShapelessRecipeType $type;
/**
* @param Item[] $ingredients No more than 9 total. This applies to sum of item stack counts, not count of array.
* @param Item[] $results List of result items created by this recipe.
* TODO: we'll want to make the type parameter mandatory in PM5
*/
public function __construct(array $ingredients, array $results){
public function __construct(array $ingredients, array $results, ?ShapelessRecipeType $type = null){
$this->type = $type ?? ShapelessRecipeType::CRAFTING();
foreach($ingredients as $item){
//Ensure they get split up properly
if(count($this->ingredients) + $item->getCount() > 9){
@ -63,6 +66,10 @@ class ShapelessRecipe implements CraftingRecipe{
return $this->getResults();
}
public function getType() : ShapelessRecipeType{
return $this->type;
}
/**
* @return Item[]
*/

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/
*
*
*/
declare(strict_types=1);
namespace pocketmine\crafting;
use pocketmine\utils\EnumTrait;
/**
* This doc-block is generated automatically, do not modify it manually.
* This must be regenerated whenever registry members are added, removed or changed.
* @see build/generate-registry-annotations.php
* @generate-registry-docblock
*
* @method static ShapelessRecipeType CRAFTING()
* @method static ShapelessRecipeType STONECUTTER()
*/
final class ShapelessRecipeType{
use EnumTrait;
protected static function setup() : void{
self::registerAll(
new self("crafting"),
new self("stonecutter")
);
}
}

View File

@ -869,7 +869,8 @@ final class StringToItemParser extends StringToTParser{
$result->registerBlock("stone_stairs", fn() => VanillaBlocks::STONE_STAIRS());
$result->registerBlock("stone_wall", fn() => VanillaBlocks::COBBLESTONE_WALL());
$result->registerBlock("stonebrick", fn() => VanillaBlocks::STONE_BRICKS());
$result->registerBlock("stonecutter", fn() => VanillaBlocks::LEGACY_STONECUTTER());
$result->registerBlock("stonecutter", fn() => VanillaBlocks::STONECUTTER());
$result->registerBlock("stonecutter_block", fn() => VanillaBlocks::STONECUTTER());
$result->registerBlock("stripped_acacia_log", fn() => VanillaBlocks::STRIPPED_ACACIA_LOG());
$result->registerBlock("stripped_acacia_wood", fn() => VanillaBlocks::STRIPPED_ACACIA_WOOD());
$result->registerBlock("stripped_birch_log", fn() => VanillaBlocks::STRIPPED_BIRCH_LOG());

View File

@ -31,6 +31,7 @@ use pocketmine\block\inventory\EnchantInventory;
use pocketmine\block\inventory\FurnaceInventory;
use pocketmine\block\inventory\HopperInventory;
use pocketmine\block\inventory\LoomInventory;
use pocketmine\block\inventory\StonecutterInventory;
use pocketmine\crafting\FurnaceType;
use pocketmine\inventory\CreativeInventory;
use pocketmine\inventory\Inventory;
@ -210,6 +211,7 @@ class InventoryManager{
$inv instanceof AnvilInventory => WindowTypes::ANVIL,
$inv instanceof HopperInventory => WindowTypes::HOPPER,
$inv instanceof CraftingTableInventory => WindowTypes::WORKBENCH,
$inv instanceof StonecutterInventory => WindowTypes::STONECUTTER,
default => WindowTypes::CONTAINER
};
return [ContainerOpenPacket::blockInv($id, $windowType, $blockPosition)];

View File

@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe\cache;
use pocketmine\crafting\CraftingManager;
use pocketmine\crafting\FurnaceType;
use pocketmine\crafting\ShapelessRecipeType;
use pocketmine\item\Item;
use pocketmine\network\mcpe\convert\ItemTranslator;
use pocketmine\network\mcpe\convert\TypeConverter;
@ -81,6 +82,11 @@ final class CraftingDataCache{
$recipesWithTypeIds = [];
foreach($manager->getShapelessRecipes() as $list){
foreach($list as $recipe){
$typeTag = match($recipe->getType()->id()){
ShapelessRecipeType::CRAFTING()->id() => CraftingRecipeBlockName::CRAFTING_TABLE,
ShapelessRecipeType::STONECUTTER()->id() => CraftingRecipeBlockName::STONECUTTER,
default => throw new AssumptionFailedError("Unreachable"),
};
$recipesWithTypeIds[] = new ProtocolShapelessRecipe(
CraftingDataPacket::ENTRY_SHAPELESS,
Binary::writeInt(++$counter),
@ -91,7 +97,7 @@ final class CraftingDataCache{
return $converter->coreItemStackToNet($item);
}, $recipe->getResults()),
$nullUUID,
CraftingRecipeBlockName::CRAFTING_TABLE,
$typeTag,
50,
$counter
);

View File

@ -27,6 +27,7 @@ use pocketmine\block\inventory\AnvilInventory;
use pocketmine\block\inventory\CraftingTableInventory;
use pocketmine\block\inventory\EnchantInventory;
use pocketmine\block\inventory\LoomInventory;
use pocketmine\block\inventory\StonecutterInventory;
use pocketmine\inventory\transaction\action\CreateItemAction;
use pocketmine\inventory\transaction\action\DestroyItemAction;
use pocketmine\inventory\transaction\action\DropItemAction;
@ -283,6 +284,7 @@ class TypeConverter{
$current instanceof AnvilInventory => UIInventorySlotOffset::ANVIL,
$current instanceof EnchantInventory => UIInventorySlotOffset::ENCHANTING_TABLE,
$current instanceof LoomInventory => UIInventorySlotOffset::LOOM,
$current instanceof StonecutterInventory => [UIInventorySlotOffset::STONE_CUTTER_INPUT => StonecutterInventory::SLOT_INPUT],
$current instanceof CraftingTableInventory => UIInventorySlotOffset::CRAFTING3X3_INPUT,
default => null
};

File diff suppressed because one or more lines are too long