177 lines
6.3 KiB
Java
177 lines
6.3 KiB
Java
package com.hypixel.hytale.builtin.crafting;
|
|
|
|
import com.hypixel.hytale.protocol.BenchRequirement;
|
|
import com.hypixel.hytale.protocol.ItemResourceType;
|
|
import com.hypixel.hytale.server.core.asset.type.item.config.CraftingRecipe;
|
|
import com.hypixel.hytale.server.core.inventory.ItemStack;
|
|
import com.hypixel.hytale.server.core.inventory.MaterialQuantity;
|
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
|
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Objects;
|
|
import java.util.Set;
|
|
import java.util.Map.Entry;
|
|
import javax.annotation.Nonnull;
|
|
import javax.annotation.Nullable;
|
|
|
|
public class BenchRecipeRegistry {
|
|
private final String benchId;
|
|
private final Map<String, Set<String>> categoryMap = new Object2ObjectOpenHashMap();
|
|
private final Map<String, Set<String>> itemToIncomingRecipe = new Object2ObjectOpenHashMap();
|
|
private final Set<String> uncategorizedRecipes = new ObjectOpenHashSet();
|
|
private final Set<String> allMaterialIds = new ObjectOpenHashSet();
|
|
private final Set<String> allMaterialResourceType = new ObjectOpenHashSet();
|
|
|
|
public BenchRecipeRegistry(String benchId) {
|
|
this.benchId = benchId;
|
|
}
|
|
|
|
public Iterable<String> getIncomingRecipesForItem(@Nonnull String itemId) {
|
|
Set<String> recipes = this.itemToIncomingRecipe.get(itemId);
|
|
return recipes == null ? Collections.emptySet() : recipes;
|
|
}
|
|
|
|
public void removeRecipe(@Nonnull String id) {
|
|
this.uncategorizedRecipes.remove(id);
|
|
|
|
for (Entry<String, Set<String>> entry : this.categoryMap.entrySet()) {
|
|
entry.getValue().remove(id);
|
|
}
|
|
}
|
|
|
|
public void addRecipe(@Nonnull BenchRequirement benchRequirement, @Nonnull CraftingRecipe recipe) {
|
|
if (benchRequirement.categories != null && benchRequirement.categories.length != 0) {
|
|
for (String category : benchRequirement.categories) {
|
|
this.categoryMap.computeIfAbsent(category, k -> new ObjectOpenHashSet()).add(recipe.getId());
|
|
}
|
|
} else {
|
|
this.uncategorizedRecipes.add(recipe.getId());
|
|
}
|
|
}
|
|
|
|
public CraftingRecipe[] getAllRecipes() {
|
|
Set<String> allRecipeIds = new ObjectOpenHashSet(this.uncategorizedRecipes);
|
|
|
|
for (Set<String> recipes : this.categoryMap.values()) {
|
|
allRecipeIds.addAll(recipes);
|
|
}
|
|
|
|
List<CraftingRecipe> allRecipes = new ObjectArrayList(allRecipeIds.size());
|
|
|
|
for (String recipeId : allRecipeIds) {
|
|
CraftingRecipe recipe = CraftingRecipe.getAssetMap().getAsset(recipeId);
|
|
if (recipe != null) {
|
|
allRecipes.add(recipe);
|
|
}
|
|
}
|
|
|
|
return allRecipes.toArray(CraftingRecipe[]::new);
|
|
}
|
|
|
|
@Nullable
|
|
public Set<String> getRecipesForCategory(@Nonnull String benchCategoryId) {
|
|
return this.categoryMap.get(benchCategoryId);
|
|
}
|
|
|
|
public void recompute() {
|
|
this.allMaterialIds.clear();
|
|
this.allMaterialResourceType.clear();
|
|
this.itemToIncomingRecipe.clear();
|
|
|
|
for (Set<String> recipes : this.categoryMap.values()) {
|
|
this.extractMaterialFromRecipes(recipes);
|
|
}
|
|
|
|
this.extractMaterialFromRecipes(this.uncategorizedRecipes);
|
|
}
|
|
|
|
private void extractMaterialFromRecipes(Set<String> recipes) {
|
|
for (String recipeId : recipes) {
|
|
CraftingRecipe recipe = CraftingRecipe.getAssetMap().getAsset(recipeId);
|
|
if (recipe != null) {
|
|
BenchRequirement[] benchRequirements = recipe.getBenchRequirement();
|
|
if (benchRequirements != null) {
|
|
boolean matchesRegistry = false;
|
|
|
|
for (BenchRequirement requirement : benchRequirements) {
|
|
if (requirement.id.equals(this.benchId)) {
|
|
matchesRegistry = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (matchesRegistry) {
|
|
for (MaterialQuantity material : recipe.getInput()) {
|
|
if (material.getItemId() != null) {
|
|
this.allMaterialIds.add(material.getItemId());
|
|
}
|
|
|
|
if (material.getResourceTypeId() != null) {
|
|
this.allMaterialResourceType.add(material.getResourceTypeId());
|
|
}
|
|
}
|
|
|
|
for (MaterialQuantity output : recipe.getOutputs()) {
|
|
this.itemToIncomingRecipe.computeIfAbsent(output.getItemId(), k -> new ObjectOpenHashSet()).add(recipeId);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public boolean isValidCraftingMaterial(@Nonnull ItemStack itemStack) {
|
|
if (this.allMaterialIds.contains(itemStack.getItemId())) {
|
|
return true;
|
|
} else {
|
|
ItemResourceType[] resourceTypeId = itemStack.getItem().getResourceTypes();
|
|
if (resourceTypeId != null) {
|
|
for (ItemResourceType resTypeId : resourceTypeId) {
|
|
if (this.allMaterialResourceType.contains(resTypeId.id)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object o) {
|
|
if (o != null && this.getClass() == o.getClass()) {
|
|
BenchRecipeRegistry that = (BenchRecipeRegistry)o;
|
|
return Objects.equals(this.benchId, that.benchId)
|
|
&& Objects.equals(this.categoryMap, that.categoryMap)
|
|
&& Objects.equals(this.uncategorizedRecipes, that.uncategorizedRecipes)
|
|
&& Objects.equals(this.allMaterialIds, that.allMaterialIds)
|
|
&& Objects.equals(this.allMaterialResourceType, that.allMaterialResourceType);
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return Objects.hash(this.benchId, this.categoryMap, this.uncategorizedRecipes, this.allMaterialIds, this.allMaterialResourceType);
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "BenchRecipeRegistry{benchId='"
|
|
+ this.benchId
|
|
+ "', categoryMap="
|
|
+ this.categoryMap
|
|
+ ", uncategorizedRecipes="
|
|
+ this.uncategorizedRecipes
|
|
+ ", allMaterialIds="
|
|
+ this.allMaterialIds
|
|
+ ", allMaterialResourceType="
|
|
+ this.allMaterialResourceType
|
|
+ "}";
|
|
}
|
|
}
|