continue refactoring, not finished, not tested

This is a bump from my workspace
This commit is contained in:
ShockedPlot7560 2025-03-22 20:21:56 +01:00
parent a1695a52d5
commit b4cb09fe5e
No known key found for this signature in database
GPG Key ID: D7539B420F1FA86E
10 changed files with 67 additions and 56 deletions

View File

@ -39,20 +39,23 @@ final class AnvilHelper{
public static function calculateResult(Player $player, Item $base, Item $material, ?string $customName = null) : ?AnvilCraftResult {
$recipe = Server::getInstance()->getCraftingManager()->matchAnvilRecipe($base, $material);
if($recipe === null){
return null;
}
$result = $recipe->getResultFor($base, $material);
if($result !== null){
$resultItem = $result->getResult();
$resultItem = $result->getOutput();
$xpCost = $result->getXpCost();
if(($customName === null || $customName === "") && $resultItem->hasCustomName()){
$xpCost++;
$resultItem->clearCustomName();
}elseif($resultItem->getCustomName() !== $customName){
}elseif($customName !== null && $resultItem->getCustomName() !== $customName){
$xpCost++;
$resultItem->setCustomName($customName);
}
$result = new AnvilCraftResult($xpCost, $resultItem);
$result = new AnvilCraftResult($xpCost, $resultItem, $result->getSacrificeResult());
}
if($result === null || $result->getXpCost() <= 0 || ($result->getXpCost() > self::COST_LIMIT && !$player->isCreative())){

View File

@ -25,17 +25,44 @@ namespace pocketmine\crafting;
use pocketmine\item\Item;
/**
* This class is here to hold the result of an anvil crafting process.
*/
class AnvilCraftResult{
/**
* @param int $xpCost
* @param Item $output
* @param Item|null $sacrificeResult If the given item is considered as null (count <= 0), the value will be set to null.
*/
public function __construct(
private int $xpCost,
private Item $result,
){}
private Item $output,
private ?Item $sacrificeResult
){
if($this->sacrificeResult !== null && $this->sacrificeResult->isNull()){
$this->sacrificeResult = null;
}
}
/**
* Represent the amount of experience points required to craft the output item.
*/
public function getXpCost() : int{
return $this->xpCost;
}
public function getResult() : Item{
return $this->result;
/**
* Represent the item given as output of the crafting process.
*/
public function getOutput() : Item{
return $this->output;
}
/**
* This result has to be null if the sacrifice slot need to be emptied.
* If not null, it represent the item that will be left in the sacrifice slot after the crafting process.
*/
public function getSacrificeResult() : ?Item{
return $this->sacrificeResult;
}
}

View File

@ -26,7 +26,5 @@ namespace pocketmine\crafting;
use pocketmine\item\Item;
interface AnvilRecipe{
public function getXpCost() : int;
public function getResultFor(Item $input, Item $material) : ?AnvilCraftResult;
}

View File

@ -34,6 +34,7 @@ use function count;
use function implode;
use function ksort;
use function spl_object_id;
use function var_dump;
use const SORT_STRING;
class CraftingManager{

View File

@ -31,8 +31,10 @@ use pocketmine\crafting\json\RecipeIngredientData;
use pocketmine\crafting\json\ShapedRecipeData;
use pocketmine\crafting\json\ShapelessRecipeData;
use pocketmine\data\bedrock\block\BlockStateData;
use pocketmine\data\bedrock\block\BlockTypeNames;
use pocketmine\data\bedrock\item\BlockItemIdMap;
use pocketmine\data\bedrock\item\ItemTypeDeserializeException;
use pocketmine\data\bedrock\item\ItemTypeNames;
use pocketmine\data\bedrock\item\SavedItemData;
use pocketmine\data\bedrock\item\SavedItemStackData;
use pocketmine\data\SavedDataLoadingException;
@ -335,15 +337,13 @@ final class CraftingManagerFromDataHelper{
}
$result->registerAnvilRecipe(new MaterialRepairRecipe(
new ExactRecipeIngredient(VanillaItems::DIAMOND_PICKAXE()),
new ExactRecipeIngredient(VanillaItems::DIAMOND()),
VanillaItems::DIAMOND_PICKAXE()
new MetaWildcardRecipeIngredient(ItemTypeNames::DIAMOND_PICKAXE),
new ExactRecipeIngredient(VanillaItems::DIAMOND())
));
$result->registerAnvilRecipe(new ItemCombineRecipe(
new ExactRecipeIngredient(VanillaItems::DIAMOND_PICKAXE()),
new ExactRecipeIngredient(VanillaItems::DIAMOND_PICKAXE()),
VanillaItems::DIAMOND_PICKAXE()
new MetaWildcardRecipeIngredient(ItemTypeNames::DIAMOND_PICKAXE),
new MetaWildcardRecipeIngredient(ItemTypeNames::DIAMOND_PICKAXE)
));
//TODO: smithing

View File

@ -40,8 +40,7 @@ use function min;
class ItemCombineRecipe implements AnvilRecipe{
public function __construct(
private RecipeIngredient $input,
private RecipeIngredient $material,
private Item $result
private RecipeIngredient $material
){ }
public function getInput() : RecipeIngredient{
@ -52,22 +51,14 @@ class ItemCombineRecipe implements AnvilRecipe{
return $this->material;
}
public function getResult() : Item{
return clone $this->result;
}
public function getXpCost() : int{
return 2;
}
public function getResultFor(Item $input, Item $material) : ?AnvilCraftResult{
if($input->equals($this->input->getItem()) && $material->equals($this->material->getItem())){
$result = $this->getResult();
if($this->input->accepts($input) && $this->material->accepts($material)){
$result = (clone $input);
$xpCost = 0;
if($input instanceof Durable && $material instanceof Durable){
$damage = $input->getDamage();
if($result instanceof Durable && $material instanceof Durable){
$damage = $result->getDamage();
if($damage !== 0){
$baseMaxDurability = $input->getMaxDurability();
$baseMaxDurability = $result->getMaxDurability();
$baseDurability = $baseMaxDurability - $damage;
$materialDurability = $material->getMaxDurability() - $material->getDamage();
$addDurability = (int) ($baseMaxDurability * 12 / 100);
@ -78,11 +69,6 @@ class ItemCombineRecipe implements AnvilRecipe{
$xpCost = 2;
}
// setting base enchantments to result
foreach($input->getEnchantments() as $enchantment){
$result->addEnchantment($enchantment);
}
// combining enchantments
foreach($material->getEnchantments() as $instance){
$enchantment = $instance->getType();
@ -131,7 +117,7 @@ class ItemCombineRecipe implements AnvilRecipe{
);
}
return new AnvilCraftResult($xpCost, $result);
return new AnvilCraftResult($xpCost, $result, null);
}
return null;

View File

@ -23,11 +23,14 @@ declare(strict_types=1);
namespace pocketmine\crafting;
use pocketmine\item\Durable;
use pocketmine\item\Item;
use pocketmine\item\Tool;
use function ceil;
use function floor;
use function max;
use function min;
use function var_dump;
/**
* Represent a recipe that repair an item with a material in an anvil.
@ -35,8 +38,7 @@ use function min;
class MaterialRepairRecipe implements AnvilRecipe{
public function __construct(
private RecipeIngredient $input,
private RecipeIngredient $material,
private Item $result
private RecipeIngredient $material
){ }
public function getInput() : RecipeIngredient{
@ -47,16 +49,8 @@ class MaterialRepairRecipe implements AnvilRecipe{
return $this->material;
}
public function getResult() : Item{
return clone $this->result;
}
public function getXpCost() : int{
return 1;
}
public function getResultFor(Item $input, Item $material) : ?Item{
if($this->input->accepts($input) && $this->material->accepts($material)){
public function getResultFor(Item $input, Item $material) : ?AnvilCraftResult{
if($this->input->accepts($input) && $this->material->accepts($material) && $input instanceof Durable){
$damage = $input->getDamage();
if($damage !== 0){
$quarter = min($damage, (int) floor($input->getMaxDurability() / 4));
@ -65,7 +59,11 @@ class MaterialRepairRecipe implements AnvilRecipe{
// TODO: remove the material
$damage -= $quarter * $numberRepair;
}
return $this->getResult()->setDamage(max(0, $damage));
return new AnvilCraftResult(
$numberRepair,
(clone $input)->setDamage(max(0, $damage)),
$material->pop($numberRepair)
);
}
}

View File

@ -67,7 +67,7 @@ class AnvilTransaction extends InventoryTransaction{
if($calculAttempt === null){
return null;
}
$result = $calculAttempt->getResult();
$result = $calculAttempt->getOutput();
if(!$result->equalsExact($expectedOutput)){
return null;
}
@ -119,7 +119,7 @@ class AnvilTransaction extends InventoryTransaction{
parent::execute();
if($this->source->hasFiniteResources()){
$this->source->getXpManager()->subtractXpLevels($this->expectedResult->getRepairCost());
$this->source->getXpManager()->subtractXpLevels($this->expectedResult->getXpCost());
}
$inventory = $this->source->getCurrentWindow();
@ -148,9 +148,7 @@ class AnvilTransaction extends InventoryTransaction{
throw new AssumptionFailedError("Expected that baseItem are not null before executing the event");
}
$ev = new PlayerUseAnvilEvent($this->source, $this->baseItem, $this->materialItem, $this->expectedResult->getResult() ?? throw new \AssertionError(
"Expected that the expected result is not null"
), $this->customName, $this->expectedResult->getXpCost());
$ev = new PlayerUseAnvilEvent($this->source, $this->baseItem, $this->materialItem, $this->expectedResult->getOutput(), $this->customName, $this->expectedResult->getXpCost());
$ev->call();
return !$ev->isCancelled();
}

View File

@ -36,7 +36,7 @@ use pocketmine\utils\LegacyEnumShimTrait;
* @method static ToolTier STONE()
* @method static ToolTier WOOD()
*
* @phpstan-type TMetadata array{0: int, 1: int, 2: int, 3: int, 4: int, 5: int[]}
* @phpstan-type TMetadata array{0: int, 1: int, 2: int, 3: int, 4: int}
*/
enum ToolTier{
use LegacyEnumShimTrait;

View File

@ -358,7 +358,7 @@ class ItemStackRequestExecutor{
$result = AnvilHelper::calculateResult($this->player, $window->getInput(), $window->getMaterial(), $this->request->getFilterStrings()[0] ?? null);
if($result !== null){
$this->specialTransaction = new AnvilTransaction($this->player, $result, $this->request->getFilterStrings()[0] ?? null);
$this->setNextCreatedItem($result->getResult());
$this->setNextCreatedItem($result->getOutput());
}
}
}elseif($action instanceof CraftingConsumeInputStackRequestAction){