Skip to content

Commit b4cb09f

Browse files
continue refactoring, not finished, not tested
This is a bump from my workspace
1 parent a1695a5 commit b4cb09f

10 files changed

+67
-56
lines changed

src/block/utils/AnvilHelper.php

+6-3
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,23 @@ final class AnvilHelper{
3939
public static function calculateResult(Player $player, Item $base, Item $material, ?string $customName = null) : ?AnvilCraftResult {
4040

4141
$recipe = Server::getInstance()->getCraftingManager()->matchAnvilRecipe($base, $material);
42+
if($recipe === null){
43+
return null;
44+
}
4245
$result = $recipe->getResultFor($base, $material);
4346

4447
if($result !== null){
45-
$resultItem = $result->getResult();
48+
$resultItem = $result->getOutput();
4649
$xpCost = $result->getXpCost();
4750
if(($customName === null || $customName === "") && $resultItem->hasCustomName()){
4851
$xpCost++;
4952
$resultItem->clearCustomName();
50-
}elseif($resultItem->getCustomName() !== $customName){
53+
}elseif($customName !== null && $resultItem->getCustomName() !== $customName){
5154
$xpCost++;
5255
$resultItem->setCustomName($customName);
5356
}
5457

55-
$result = new AnvilCraftResult($xpCost, $resultItem);
58+
$result = new AnvilCraftResult($xpCost, $resultItem, $result->getSacrificeResult());
5659
}
5760

5861
if($result === null || $result->getXpCost() <= 0 || ($result->getXpCost() > self::COST_LIMIT && !$player->isCreative())){

src/crafting/AnvilCraftResult.php

+31-4
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,44 @@
2525

2626
use pocketmine\item\Item;
2727

28+
/**
29+
* This class is here to hold the result of an anvil crafting process.
30+
*/
2831
class AnvilCraftResult{
32+
/**
33+
* @param int $xpCost
34+
* @param Item $output
35+
* @param Item|null $sacrificeResult If the given item is considered as null (count <= 0), the value will be set to null.
36+
*/
2937
public function __construct(
3038
private int $xpCost,
31-
private Item $result,
32-
){}
39+
private Item $output,
40+
private ?Item $sacrificeResult
41+
){
42+
if($this->sacrificeResult !== null && $this->sacrificeResult->isNull()){
43+
$this->sacrificeResult = null;
44+
}
45+
}
3346

47+
/**
48+
* Represent the amount of experience points required to craft the output item.
49+
*/
3450
public function getXpCost() : int{
3551
return $this->xpCost;
3652
}
3753

38-
public function getResult() : Item{
39-
return $this->result;
54+
/**
55+
* Represent the item given as output of the crafting process.
56+
*/
57+
public function getOutput() : Item{
58+
return $this->output;
59+
}
60+
61+
/**
62+
* This result has to be null if the sacrifice slot need to be emptied.
63+
* If not null, it represent the item that will be left in the sacrifice slot after the crafting process.
64+
*/
65+
public function getSacrificeResult() : ?Item{
66+
return $this->sacrificeResult;
4067
}
4168
}

src/crafting/AnvilRecipe.php

-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,5 @@
2626
use pocketmine\item\Item;
2727

2828
interface AnvilRecipe{
29-
public function getXpCost() : int;
30-
3129
public function getResultFor(Item $input, Item $material) : ?AnvilCraftResult;
3230
}

src/crafting/CraftingManager.php

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
use function implode;
3535
use function ksort;
3636
use function spl_object_id;
37+
use function var_dump;
3738
use const SORT_STRING;
3839

3940
class CraftingManager{

src/crafting/CraftingManagerFromDataHelper.php

+6-6
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@
3131
use pocketmine\crafting\json\ShapedRecipeData;
3232
use pocketmine\crafting\json\ShapelessRecipeData;
3333
use pocketmine\data\bedrock\block\BlockStateData;
34+
use pocketmine\data\bedrock\block\BlockTypeNames;
3435
use pocketmine\data\bedrock\item\BlockItemIdMap;
3536
use pocketmine\data\bedrock\item\ItemTypeDeserializeException;
37+
use pocketmine\data\bedrock\item\ItemTypeNames;
3638
use pocketmine\data\bedrock\item\SavedItemData;
3739
use pocketmine\data\bedrock\item\SavedItemStackData;
3840
use pocketmine\data\SavedDataLoadingException;
@@ -335,15 +337,13 @@ public static function make(string $directoryPath) : CraftingManager{
335337
}
336338

337339
$result->registerAnvilRecipe(new MaterialRepairRecipe(
338-
new ExactRecipeIngredient(VanillaItems::DIAMOND_PICKAXE()),
339-
new ExactRecipeIngredient(VanillaItems::DIAMOND()),
340-
VanillaItems::DIAMOND_PICKAXE()
340+
new MetaWildcardRecipeIngredient(ItemTypeNames::DIAMOND_PICKAXE),
341+
new ExactRecipeIngredient(VanillaItems::DIAMOND())
341342
));
342343

343344
$result->registerAnvilRecipe(new ItemCombineRecipe(
344-
new ExactRecipeIngredient(VanillaItems::DIAMOND_PICKAXE()),
345-
new ExactRecipeIngredient(VanillaItems::DIAMOND_PICKAXE()),
346-
VanillaItems::DIAMOND_PICKAXE()
345+
new MetaWildcardRecipeIngredient(ItemTypeNames::DIAMOND_PICKAXE),
346+
new MetaWildcardRecipeIngredient(ItemTypeNames::DIAMOND_PICKAXE)
347347
));
348348

349349
//TODO: smithing

src/crafting/ItemCombineRecipe.php

+7-21
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@
4040
class ItemCombineRecipe implements AnvilRecipe{
4141
public function __construct(
4242
private RecipeIngredient $input,
43-
private RecipeIngredient $material,
44-
private Item $result
43+
private RecipeIngredient $material
4544
){ }
4645

4746
public function getInput() : RecipeIngredient{
@@ -52,22 +51,14 @@ public function getMaterial() : RecipeIngredient{
5251
return $this->material;
5352
}
5453

55-
public function getResult() : Item{
56-
return clone $this->result;
57-
}
58-
59-
public function getXpCost() : int{
60-
return 2;
61-
}
62-
6354
public function getResultFor(Item $input, Item $material) : ?AnvilCraftResult{
64-
if($input->equals($this->input->getItem()) && $material->equals($this->material->getItem())){
65-
$result = $this->getResult();
55+
if($this->input->accepts($input) && $this->material->accepts($material)){
56+
$result = (clone $input);
6657
$xpCost = 0;
67-
if($input instanceof Durable && $material instanceof Durable){
68-
$damage = $input->getDamage();
58+
if($result instanceof Durable && $material instanceof Durable){
59+
$damage = $result->getDamage();
6960
if($damage !== 0){
70-
$baseMaxDurability = $input->getMaxDurability();
61+
$baseMaxDurability = $result->getMaxDurability();
7162
$baseDurability = $baseMaxDurability - $damage;
7263
$materialDurability = $material->getMaxDurability() - $material->getDamage();
7364
$addDurability = (int) ($baseMaxDurability * 12 / 100);
@@ -78,11 +69,6 @@ public function getResultFor(Item $input, Item $material) : ?AnvilCraftResult{
7869
$xpCost = 2;
7970
}
8071

81-
// setting base enchantments to result
82-
foreach($input->getEnchantments() as $enchantment){
83-
$result->addEnchantment($enchantment);
84-
}
85-
8672
// combining enchantments
8773
foreach($material->getEnchantments() as $instance){
8874
$enchantment = $instance->getType();
@@ -131,7 +117,7 @@ public function getResultFor(Item $input, Item $material) : ?AnvilCraftResult{
131117
);
132118
}
133119

134-
return new AnvilCraftResult($xpCost, $result);
120+
return new AnvilCraftResult($xpCost, $result, null);
135121
}
136122

137123
return null;

src/crafting/MaterialRepairRecipe.php

+11-13
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,22 @@
2323

2424
namespace pocketmine\crafting;
2525

26+
use pocketmine\item\Durable;
2627
use pocketmine\item\Item;
28+
use pocketmine\item\Tool;
2729
use function ceil;
2830
use function floor;
2931
use function max;
3032
use function min;
33+
use function var_dump;
3134

3235
/**
3336
* Represent a recipe that repair an item with a material in an anvil.
3437
*/
3538
class MaterialRepairRecipe implements AnvilRecipe{
3639
public function __construct(
3740
private RecipeIngredient $input,
38-
private RecipeIngredient $material,
39-
private Item $result
41+
private RecipeIngredient $material
4042
){ }
4143

4244
public function getInput() : RecipeIngredient{
@@ -47,16 +49,8 @@ public function getMaterial() : RecipeIngredient{
4749
return $this->material;
4850
}
4951

50-
public function getResult() : Item{
51-
return clone $this->result;
52-
}
53-
54-
public function getXpCost() : int{
55-
return 1;
56-
}
57-
58-
public function getResultFor(Item $input, Item $material) : ?Item{
59-
if($this->input->accepts($input) && $this->material->accepts($material)){
52+
public function getResultFor(Item $input, Item $material) : ?AnvilCraftResult{
53+
if($this->input->accepts($input) && $this->material->accepts($material) && $input instanceof Durable){
6054
$damage = $input->getDamage();
6155
if($damage !== 0){
6256
$quarter = min($damage, (int) floor($input->getMaxDurability() / 4));
@@ -65,7 +59,11 @@ public function getResultFor(Item $input, Item $material) : ?Item{
6559
// TODO: remove the material
6660
$damage -= $quarter * $numberRepair;
6761
}
68-
return $this->getResult()->setDamage(max(0, $damage));
62+
return new AnvilCraftResult(
63+
$numberRepair,
64+
(clone $input)->setDamage(max(0, $damage)),
65+
$material->pop($numberRepair)
66+
);
6967
}
7068
}
7169

src/inventory/transaction/AnvilTransaction.php

+3-5
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ private function validateInputs(Item $base, Item $material, Item $expectedOutput
6767
if($calculAttempt === null){
6868
return null;
6969
}
70-
$result = $calculAttempt->getResult();
70+
$result = $calculAttempt->getOutput();
7171
if(!$result->equalsExact($expectedOutput)){
7272
return null;
7373
}
@@ -119,7 +119,7 @@ public function execute() : void{
119119
parent::execute();
120120

121121
if($this->source->hasFiniteResources()){
122-
$this->source->getXpManager()->subtractXpLevels($this->expectedResult->getRepairCost());
122+
$this->source->getXpManager()->subtractXpLevels($this->expectedResult->getXpCost());
123123
}
124124

125125
$inventory = $this->source->getCurrentWindow();
@@ -148,9 +148,7 @@ protected function callExecuteEvent() : bool{
148148
throw new AssumptionFailedError("Expected that baseItem are not null before executing the event");
149149
}
150150

151-
$ev = new PlayerUseAnvilEvent($this->source, $this->baseItem, $this->materialItem, $this->expectedResult->getResult() ?? throw new \AssertionError(
152-
"Expected that the expected result is not null"
153-
), $this->customName, $this->expectedResult->getXpCost());
151+
$ev = new PlayerUseAnvilEvent($this->source, $this->baseItem, $this->materialItem, $this->expectedResult->getOutput(), $this->customName, $this->expectedResult->getXpCost());
154152
$ev->call();
155153
return !$ev->isCancelled();
156154
}

src/item/ToolTier.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
* @method static ToolTier STONE()
3737
* @method static ToolTier WOOD()
3838
*
39-
* @phpstan-type TMetadata array{0: int, 1: int, 2: int, 3: int, 4: int, 5: int[]}
39+
* @phpstan-type TMetadata array{0: int, 1: int, 2: int, 3: int, 4: int}
4040
*/
4141
enum ToolTier{
4242
use LegacyEnumShimTrait;

src/network/mcpe/handler/ItemStackRequestExecutor.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ protected function processItemStackRequestAction(ItemStackRequestAction $action)
358358
$result = AnvilHelper::calculateResult($this->player, $window->getInput(), $window->getMaterial(), $this->request->getFilterStrings()[0] ?? null);
359359
if($result !== null){
360360
$this->specialTransaction = new AnvilTransaction($this->player, $result, $this->request->getFilterStrings()[0] ?? null);
361-
$this->setNextCreatedItem($result->getResult());
361+
$this->setNextCreatedItem($result->getOutput());
362362
}
363363
}
364364
}elseif($action instanceof CraftingConsumeInputStackRequestAction){

0 commit comments

Comments
 (0)