40 use DestructorCallbackTrait;
46 protected array $shapedRecipes = [];
51 protected array $shapelessRecipes = [];
57 private array $craftingRecipeIndex = [];
63 protected array $furnaceRecipeManagers = [];
69 protected array $potionTypeRecipes = [];
75 protected array $potionContainerChangeRecipes = [];
81 private array $brewingRecipeCache = [];
84 private ObjectSet $recipeRegisteredCallbacks;
86 public function __construct(){
87 $this->recipeRegisteredCallbacks =
new ObjectSet();
88 foreach(FurnaceType::cases() as $furnaceType){
92 $recipeRegisteredCallbacks = $this->recipeRegisteredCallbacks;
93 foreach($this->furnaceRecipeManagers as $furnaceRecipeManager){
94 $furnaceRecipeManager->getRecipeRegisteredCallbacks()->add(
static function(
FurnaceRecipe $recipe) use ($recipeRegisteredCallbacks) :
void{
95 foreach($recipeRegisteredCallbacks as $callback){
111 ($retval = $i1->getStateId() <=> $i2->getStateId()) === 0 && ($retval = $i1->getCount() <=> $i2->getCount()) === 0;
116 private static function hashOutput(
Item $output) : string{
118 $write->
putVarInt($output->getStateId());
121 return $write->getBuffer();
127 private static function hashOutputs(array $outputs) : string{
128 if(count($outputs) === 1){
129 return self::hashOutput(array_shift($outputs));
132 foreach($outputs as $o){
135 $hash = self::hashOutput($o);
136 $unique[$hash] = $hash;
138 ksort($unique, SORT_STRING);
139 return implode(
"", $unique);
147 return $this->shapelessRecipes;
155 return $this->shapedRecipes;
163 return $this->craftingRecipeIndex;
166 public function getCraftingRecipeFromIndex(
int $index) : ?
CraftingRecipe{
167 return $this->craftingRecipeIndex[$index] ?? null;
170 public function getFurnaceRecipeManager(FurnaceType $furnaceType) : FurnaceRecipeManager{
171 return $this->furnaceRecipeManagers[spl_object_id($furnaceType)];
179 return $this->potionTypeRecipes;
187 return $this->potionContainerChangeRecipes;
190 public function registerShapedRecipe(
ShapedRecipe $recipe) : void{
191 $this->shapedRecipes[self::hashOutputs($recipe->getResults())][] = $recipe;
192 $this->craftingRecipeIndex[] = $recipe;
194 foreach($this->recipeRegisteredCallbacks as $callback){
199 public function registerShapelessRecipe(ShapelessRecipe $recipe) : void{
200 $this->shapelessRecipes[self::hashOutputs($recipe->getResults())][] = $recipe;
201 $this->craftingRecipeIndex[] = $recipe;
203 foreach($this->recipeRegisteredCallbacks as $callback){
208 public function registerPotionTypeRecipe(PotionTypeRecipe $recipe) : void{
209 $this->potionTypeRecipes[] = $recipe;
211 foreach($this->recipeRegisteredCallbacks as $callback){
216 public function registerPotionContainerChangeRecipe(PotionContainerChangeRecipe $recipe) : void{
217 $this->potionContainerChangeRecipes[] = $recipe;
219 foreach($this->recipeRegisteredCallbacks as $callback){
230 $outputHash = self::hashOutputs($outputs);
232 if(isset($this->shapedRecipes[$outputHash])){
233 foreach($this->shapedRecipes[$outputHash] as $recipe){
234 if($recipe->matchesCraftingGrid($grid)){
240 if(isset($this->shapelessRecipes[$outputHash])){
241 foreach($this->shapelessRecipes[$outputHash] as $recipe){
242 if($recipe->matchesCraftingGrid($grid)){
260 $outputHash = self::hashOutputs($outputs);
262 if(isset($this->shapedRecipes[$outputHash])){
263 foreach($this->shapedRecipes[$outputHash] as $recipe){
268 if(isset($this->shapelessRecipes[$outputHash])){
269 foreach($this->shapelessRecipes[$outputHash] as $recipe){
275 public function matchBrewingRecipe(Item $input, Item $ingredient) : ?BrewingRecipe{
276 $inputHash = $input->getStateId();
277 $ingredientHash = $ingredient->getStateId();
278 $cached = $this->brewingRecipeCache[$inputHash][$ingredientHash] ??
null;
279 if($cached !==
null){
283 foreach($this->potionContainerChangeRecipes as $recipe){
284 if($recipe->getIngredient()->accepts($ingredient) && $recipe->getResultFor($input) !==
null){
285 return $this->brewingRecipeCache[$inputHash][$ingredientHash] = $recipe;
289 foreach($this->potionTypeRecipes as $recipe){
290 if($recipe->getIngredient()->accepts($ingredient) && $recipe->getResultFor($input) !==
null){
291 return $this->brewingRecipeCache[$inputHash][$ingredientHash] = $recipe;