Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented smithing table functionality #6202

Open
wants to merge 13 commits into
base: minor-next
Choose a base branch
from
5 changes: 1 addition & 4 deletions src/block/SmithingTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,7 @@
final class SmithingTable extends Opaque{

public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
if($player !== null){
$player->setCurrentWindow(new SmithingTableInventory($this->position));
}

HimmelKreis4865 marked this conversation as resolved.
Show resolved Hide resolved
$player?->setCurrentWindow(new SmithingTableInventory($this->position));
HimmelKreis4865 marked this conversation as resolved.
Show resolved Hide resolved
return true;
}

Expand Down
19 changes: 19 additions & 0 deletions src/block/inventory/SmithingTableInventory.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,32 @@

use pocketmine\inventory\SimpleInventory;
use pocketmine\inventory\TemporaryInventory;
use pocketmine\item\Item;
use pocketmine\world\Position;

final class SmithingTableInventory extends SimpleInventory implements BlockInventory, TemporaryInventory{
use BlockInventoryTrait;

public const SLOT_INPUT = 0;

public const SLOT_ADDITION = 1;

public const SLOT_TEMPLATE = 2;

public function __construct(Position $holder){
$this->holder = $holder;
parent::__construct(3);
}

public function getInput() : Item{
return $this->getItem(self::SLOT_INPUT);
}

public function getAddition() : Item{
return $this->getItem(self::SLOT_ADDITION);
}

public function getTemplate() : Item{
return $this->getItem(self::SLOT_TEMPLATE);
}
}
32 changes: 32 additions & 0 deletions src/crafting/CraftingManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
use pocketmine\utils\BinaryStream;
use pocketmine\utils\DestructorCallbackTrait;
use pocketmine\utils\ObjectSet;
use function count;
use function spl_object_id;
use function usort;

Expand Down Expand Up @@ -64,6 +65,12 @@ class CraftingManager{
*/
protected array $potionTypeRecipes = [];

/**
* @var SmithingRecipe[]
* @phpstan-var list<SmithingRecipe>
*/
protected array $smithingRecipes = [];

/**
* @var PotionContainerChangeRecipe[]
* @phpstan-var list<PotionContainerChangeRecipe>
Expand Down Expand Up @@ -197,6 +204,23 @@ public function getPotionContainerChangeRecipes() : array{
return $this->potionContainerChangeRecipes;
}

/**
* @return SmithingRecipe[]
* @phpstan-return list<SmithingRecipe>
*/
public function getSmithingRecipes() : array{
return $this->smithingRecipes;
}

public function getSmithingRecipeFromIndex(int $index) : ?SmithingRecipe{
$craftingOffset = count($this->craftingRecipeIndex) - 1;
HimmelKreis4865 marked this conversation as resolved.
Show resolved Hide resolved

if($index < $craftingOffset || $index > ($craftingOffset + count($this->smithingRecipes))){
return null;
}
return $this->smithingRecipes[$index - $craftingOffset - 1];
}

public function registerShapedRecipe(ShapedRecipe $recipe) : void{
$this->shapedRecipes[self::hashOutputs($recipe->getResults())][] = $recipe;
$this->craftingRecipeIndex[] = $recipe;
Expand Down Expand Up @@ -231,6 +255,14 @@ public function registerPotionContainerChangeRecipe(PotionContainerChangeRecipe
}
}

public function registerSmithingRecipe(SmithingRecipe $recipe) : void{
$this->smithingRecipes[] = $recipe;

foreach($this->recipeRegisteredCallbacks as $callback){
$callback();
}
}

/**
* @param Item[] $outputs
*/
Expand Down
23 changes: 21 additions & 2 deletions src/crafting/CraftingManagerFromDataHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
use pocketmine\crafting\json\RecipeIngredientData;
use pocketmine\crafting\json\ShapedRecipeData;
use pocketmine\crafting\json\ShapelessRecipeData;
use pocketmine\crafting\json\SmithingTransformRecipeData;
use pocketmine\crafting\json\SmithingTrimRecipeData;
use pocketmine\data\bedrock\block\BlockStateData;
use pocketmine\data\bedrock\item\BlockItemIdMap;
use pocketmine\data\bedrock\item\ItemTypeDeserializeException;
Expand Down Expand Up @@ -292,7 +294,6 @@ public static function make(string $directoryPath) : CraftingManager{
$input
));
}

HimmelKreis4865 marked this conversation as resolved.
Show resolved Hide resolved
foreach(self::loadJsonArrayOfObjectsFile(Path::join($directoryPath, 'potion_type.json'), PotionTypeRecipeData::class) as $recipe){
$input = self::deserializeIngredient($recipe->input);
$ingredient = self::deserializeIngredient($recipe->ingredient);
Expand Down Expand Up @@ -329,9 +330,27 @@ public static function make(string $directoryPath) : CraftingManager{
$outputId
));
}
foreach(self::loadJsonArrayOfObjectsFile(Path::join($directoryPath, 'smithing.json'), SmithingTransformRecipeData::class) as $recipe){
$input = self::deserializeIngredient($recipe->input);
$template = self::deserializeIngredient($recipe->template);
$addition = self::deserializeIngredient($recipe->addition);
$output = self::deserializeItemStack($recipe->output);

//TODO: smithing
if($input === null || $template === null || $addition === null || $output === null){
continue;
}
$result->registerSmithingRecipe(new SmithingTransformRecipe($input, $addition, $template, $output));
}
foreach(self::loadJsonArrayOfObjectsFile(Path::join($directoryPath, 'smithing_trim.json'), SmithingTrimRecipeData::class) as $recipe){
$input = self::deserializeIngredient($recipe->input);
$addition = self::deserializeIngredient($recipe->addition);
$template = self::deserializeIngredient($recipe->template);

if($input === null || $template === null || $addition === null){
continue;
}
$result->registerSmithingRecipe(new SmithingTrimRecipe($input, $addition, $template));
}
return $result;
}
}
41 changes: 41 additions & 0 deletions src/crafting/SmithingRecipe.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?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\item\Item;

interface SmithingRecipe{

public function getInput() : RecipeIngredient;

public function getAddition() : RecipeIngredient;

public function getTemplate() : RecipeIngredient;

/**
* @param Item[] $inputs
* @phpstan-param list<Item> $inputs
*/
public function getResultFor(array $inputs) : ?Item;
}
73 changes: 73 additions & 0 deletions src/crafting/SmithingTransformRecipe.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?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\item\Armor;
use pocketmine\item\Item;
use pocketmine\item\TieredTool;

class SmithingTransformRecipe implements SmithingRecipe{

public function __construct(
private readonly RecipeIngredient $input,
private readonly RecipeIngredient $addition,
private readonly RecipeIngredient $template,
private Item $result
){
$this->result = clone $this->result;
}

public function getInput() : RecipeIngredient{
return $this->input;
}

public function getAddition() : RecipeIngredient{
return $this->addition;
}

public function getTemplate() : RecipeIngredient{
return $this->template;
}

public function getResult() : Item{
return clone $this->result;
}

/**
* @param Item[] $inputs
* @phpstan-param list<Item> $inputs
*/
public function getResultFor(array $inputs) : ?Item{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sceptical about the fact that it's up to the recipe to find out what the input is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tbh I don't see a problem here, it also has 2 usages so I don't know how I'd change it smoothly..

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this relevant now? If so, please give me some more information on where to move the methods

$input = null;
foreach($inputs as $item){
if ($item instanceof Armor || $item instanceof TieredTool){
$input = $item;
}
}
if($input === null){
return null;
}
return $this->getResult()->setNamedTag($input->getNamedTag());
ShockedPlot7560 marked this conversation as resolved.
Show resolved Hide resolved
}
}
77 changes: 77 additions & 0 deletions src/crafting/SmithingTrimRecipe.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?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\item\Armor;
use pocketmine\item\ArmorTrim;
use pocketmine\item\ArmorTrimMaterial;
use pocketmine\item\ArmorTrimPattern;
use pocketmine\item\Item;
use pocketmine\item\SmithingTemplate;

class SmithingTrimRecipe implements SmithingRecipe{

public function __construct(
private readonly RecipeIngredient $input,
private readonly RecipeIngredient $addition,
private readonly RecipeIngredient $template){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because these are readonly values the getter functions are redundant and these variables can be made public

}

public function getInput() : RecipeIngredient{
return $this->input;
}

public function getAddition() : RecipeIngredient{
return $this->addition;
}

public function getTemplate() : RecipeIngredient{
return $this->template;
}

/**
* @param Item[] $inputs
* @phpstan-param list<Item> $inputs
*/
public function getResultFor(array $inputs) : ?Item{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

$input = $template = $addition = null;
foreach($inputs as $item){
if($item instanceof Armor){
$input = $item;
}elseif($item instanceof SmithingTemplate){
$template = $item;
}else{
$addition = $item;
}
}

if($input === null || $addition === null || $template === null){
return null;
}
if(($material = ArmorTrimMaterial::fromItem($addition)) === null || ($pattern = ArmorTrimPattern::fromItem($template)) === null){
return null;
}
return $input->setTrim(new ArmorTrim($material, $pattern));
HimmelKreis4865 marked this conversation as resolved.
Show resolved Hide resolved
}
}
46 changes: 46 additions & 0 deletions src/data/bedrock/TrimMaterialTypeIdMap.php
Original file line number Diff line number Diff line change
@@ -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\data\bedrock;

use pocketmine\item\ArmorTrimMaterial;
use pocketmine\utils\SingletonTrait;

final class TrimMaterialTypeIdMap{
use SingletonTrait;
/** @phpstan-use IntSaveIdMapTrait<ArmorTrimMaterial> */
use IntSaveIdMapTrait;

private function __construct(){
$this->register(TrimMaterialTypeIds::AMETHYST, ArmorTrimMaterial::AMETHYST);
$this->register(TrimMaterialTypeIds::COPPER, ArmorTrimMaterial::COPPER);
$this->register(TrimMaterialTypeIds::DIAMOND, ArmorTrimMaterial::DIAMOND);
$this->register(TrimMaterialTypeIds::EMERALD, ArmorTrimMaterial::EMERALD);
$this->register(TrimMaterialTypeIds::GOLD, ArmorTrimMaterial::GOLD);
$this->register(TrimMaterialTypeIds::IRON, ArmorTrimMaterial::IRON);
$this->register(TrimMaterialTypeIds::LAPIS, ArmorTrimMaterial::LAPIS);
$this->register(TrimMaterialTypeIds::NETHERITE, ArmorTrimMaterial::NETHERITE);
$this->register(TrimMaterialTypeIds::QUARTZ, ArmorTrimMaterial::QUARTZ);
$this->register(TrimMaterialTypeIds::REDSTONE, ArmorTrimMaterial::REDSTONE);
}
}
Loading