9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-27 10:59:07 +00:00

Optimize Recipes

This commit is contained in:
XiaoMoMi
2025-02-15 04:35:02 +08:00
parent a20a008f65
commit d657a481f5
19 changed files with 108 additions and 83 deletions

View File

@@ -88,7 +88,7 @@ recipes:
default:topaz_from_smelting_topaz_ore:
type: smelting
experience: 1.0
categroy: MISC
category: misc
group: topaz
time: 200
ingredient: "default:topaz_ore"
@@ -98,7 +98,7 @@ recipes:
default:topaz_from_smelting_deepslate_topaz_ore:
type: smelting
experience: 1.0
categroy: MISC
category: misc
group: topaz
time: 200
ingredient: "default:deepslate_topaz_ore"
@@ -108,7 +108,7 @@ recipes:
default:topaz_from_blasting_topaz_ore:
type: blasting
experience: 1.0
categroy: MISC
category: misc
group: topaz
time: 100
ingredient: "default:topaz_ore"
@@ -118,7 +118,7 @@ recipes:
default:topaz_from_blasting_deepslate_topaz_ore:
type: blasting
experience: 1.0
categroy: MISC
category: misc
group: topaz
time: 100
ingredient: "default:deepslate_topaz_ore"

View File

@@ -262,6 +262,8 @@ items:
recipes:
default:palm_planks:
type: shapeless
category: building
group: planks
ingredients:
A: "#default:palm_logs"
result:
@@ -269,6 +271,8 @@ recipes:
count: 4
default:palm_wood:
type: shaped
category: building
group: bark
pattern:
- "AA"
- "AA"
@@ -279,6 +283,8 @@ recipes:
count: 3
default:stripped_palm_wood:
type: shaped
category: building
group: bark
pattern:
- "AA"
- "AA"

View File

@@ -24,7 +24,7 @@ import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.config.ConfigManager;
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.HexaFunction;
import net.momirealms.craftengine.core.util.HeptaFunction;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.PentaFunction;
import net.momirealms.craftengine.core.util.VersionHelper;
@@ -190,9 +190,6 @@ public class BukkitRecipeManager implements RecipeManager<ItemStack> {
private final VanillaRecipeReader recipeReader;
private final List<NamespacedKey> injectedDataPackRecipes;
private final List<NamespacedKey> registeredCustomRecipes;
// [internal:xxx] + [custom:custom]
// includes injected vanilla recipes and custom recipes
private final Set<Key> customRecipes;
// data pack recipe resource locations [minecraft:xxx]
private final Set<Key> dataPackRecipes;
@@ -206,7 +203,6 @@ public class BukkitRecipeManager implements RecipeManager<ItemStack> {
this.injectedDataPackRecipes = new ArrayList<>();
this.registeredCustomRecipes = new ArrayList<>();
this.dataPackRecipes = new HashSet<>();
this.customRecipes = new HashSet<>();
this.recipeEventListener = new RecipeEventListener(plugin, this, plugin.itemManager());
if (VersionHelper.isVersionNewerThan1_21()) {
this.crafterEventListener = new CrafterEventListener(plugin, this, plugin.itemManager());
@@ -239,7 +235,7 @@ public class BukkitRecipeManager implements RecipeManager<ItemStack> {
@Override
public boolean isCustomRecipe(Key key) {
return this.customRecipes.contains(key);
return this.byId.containsKey(key);
}
@Override
@@ -279,7 +275,6 @@ public class BukkitRecipeManager implements RecipeManager<ItemStack> {
this.recipes.clear();
this.byId.clear();
this.dataPackRecipes.clear();
this.customRecipes.clear();
try {
// do not unregister them
@@ -314,17 +309,17 @@ public class BukkitRecipeManager implements RecipeManager<ItemStack> {
@Override
public void parseSection(Pack pack, Path path, Key id, Map<String, Object> section) {
if (!ConfigManager.enableRecipeSystem()) return;
if (this.customRecipes.contains(id)) {
if (this.byId.containsKey(id)) {
this.plugin.logger().warn(path, "Duplicated recipe " + id);
return;
}
Recipe<ItemStack> recipe = RecipeTypes.fromMap(section);
Recipe<ItemStack> recipe = RecipeTypes.fromMap(id, section);
NamespacedKey key = NamespacedKey.fromString(id.toString());
BUKKIT_RECIPE_REGISTER.get(recipe.type()).accept(key, recipe);
try {
this.registeredCustomRecipes.add(key);
this.customRecipes.add(id);
this.recipes.computeIfAbsent(recipe.type(), k -> new ArrayList<>()).add(recipe);
this.byId.put(id, recipe);
} catch (Exception e) {
plugin.logger().warn("Failed to add custom recipe " + id, e);
}
@@ -337,8 +332,8 @@ public class BukkitRecipeManager implements RecipeManager<ItemStack> {
// example: stone button
public void addVanillaInternalRecipe(Key id, Recipe<ItemStack> recipe) {
this.customRecipes.add(id);
this.recipes.computeIfAbsent(recipe.type(), k -> new ArrayList<>()).add(recipe);
this.byId.put(id, recipe);
}
@Nullable
@@ -357,20 +352,13 @@ public class BukkitRecipeManager implements RecipeManager<ItemStack> {
@Nullable
@Override
public Recipe<ItemStack> getRecipe(Key type, RecipeInput input, Key lastRecipe) {
List<Recipe<ItemStack>> recipes = this.recipes.get(type);
if (recipes == null) return null;
if (lastRecipe != null) {
Recipe<ItemStack> last = byId.get(lastRecipe);
if (last != null && last.matches(input)) {
return last;
}
for (Recipe<ItemStack> recipe : recipes) {
if (recipe.matches(input)) {
return recipe;
}
}
}
return null;
return getRecipe(type, input);
}
@Override
@@ -524,6 +512,7 @@ public class BukkitRecipeManager implements RecipeManager<ItemStack> {
}
CustomShapelessRecipe<ItemStack> ceRecipe = new CustomShapelessRecipe<>(
id,
recipe.category(),
recipe.group(),
ingredientList,
@@ -581,6 +570,7 @@ public class BukkitRecipeManager implements RecipeManager<ItemStack> {
}
CustomShapedRecipe<ItemStack> ceRecipe = new CustomShapedRecipe<>(
id,
recipe.category(),
recipe.group(),
new CustomShapedRecipe.Pattern<>(recipe.pattern(), ingredients),
@@ -604,7 +594,7 @@ public class BukkitRecipeManager implements RecipeManager<ItemStack> {
private void handleDataPackCookingRecipe(Key id,
VanillaCookingRecipe recipe,
PentaFunction<NamespacedKey, ItemStack, RecipeChoice, Float, Integer, org.bukkit.inventory.CookingRecipe<?>> constructor1,
HexaFunction<CookingRecipeCategory, String, Ingredient<ItemStack>, Integer, Float, CustomRecipeResult<ItemStack>, CookingRecipe<ItemStack>> constructor2,
HeptaFunction<Key, CookingRecipeCategory, String, Ingredient<ItemStack>, Integer, Float, CustomRecipeResult<ItemStack>, CookingRecipe<ItemStack>> constructor2,
Method fromBukkitRecipeMethod,
Consumer<Runnable> callback) {
NamespacedKey key = new NamespacedKey(id.namespace(), id.value());
@@ -638,6 +628,7 @@ public class BukkitRecipeManager implements RecipeManager<ItemStack> {
}
CookingRecipe<ItemStack> ceRecipe = constructor2.apply(
id,
recipe.category(),
recipe.group(),
Ingredient.of(holders),

View File

@@ -158,27 +158,19 @@ public class RecipeEventListener implements Listener {
}
BukkitServerPlayer serverPlayer = this.plugin.adapt(player);
// though it might be inaccurate after reloading
// but it's worthy to cache
Recipe<ItemStack> lastRecipe = serverPlayer.lastUsedRecipe();
if (lastRecipe != null && (lastRecipe.type() == RecipeTypes.SHAPELESS || lastRecipe.type() == RecipeTypes.SHAPED )) {
if (lastRecipe.matches(input)) {
inventory.setResult(lastRecipe.getResult(serverPlayer));
return;
}
}
Key lastRecipe = serverPlayer.lastUsedRecipe();
Recipe<ItemStack> ceRecipe = this.recipeManager.getRecipe(RecipeTypes.SHAPELESS, input);
Recipe<ItemStack> ceRecipe = this.recipeManager.getRecipe(RecipeTypes.SHAPELESS, input, lastRecipe);
if (ceRecipe != null) {
inventory.setResult(ceRecipe.getResult(serverPlayer));
serverPlayer.setLastUsedRecipe(ceRecipe);
serverPlayer.setLastUsedRecipe(ceRecipe.id());
correctCraftingRecipeUsed(inventory, ceRecipe);
return;
}
ceRecipe = this.recipeManager.getRecipe(RecipeTypes.SHAPED, input);
ceRecipe = this.recipeManager.getRecipe(RecipeTypes.SHAPED, input, lastRecipe);
if (ceRecipe != null) {
inventory.setResult(ceRecipe.getResult(serverPlayer));
serverPlayer.setLastUsedRecipe(ceRecipe);
serverPlayer.setLastUsedRecipe(ceRecipe.id());
correctCraftingRecipeUsed(inventory, ceRecipe);
return;
}

View File

@@ -79,6 +79,7 @@ public class BukkitInjector {
private static Class<?> clazz$InjectedCacheChecker;
private static Field field$InjectedCacheChecker$recipeType;
private static Field field$InjectedCacheChecker$lastRecipe;
private static Field field$InjectedCacheChecker$lastCustomRecipe;
public static void init() {
try {
@@ -87,6 +88,7 @@ public class BukkitInjector {
.implement(Reflections.clazz$RecipeManager$CachedCheck)
.defineField("recipeType", Reflections.clazz$RecipeType, Visibility.PUBLIC)
.defineField("lastRecipe", Object.class, Visibility.PUBLIC)
.defineField("lastCustomRecipe", Key.class, Visibility.PUBLIC)
.method(ElementMatchers.named("getRecipeFor").or(ElementMatchers.named("a")))
.intercept(MethodDelegation.to(
VersionHelper.isVersionNewerThan1_21_2() ?
@@ -102,6 +104,7 @@ public class BukkitInjector {
.getLoaded();
field$InjectedCacheChecker$recipeType = clazz$InjectedCacheChecker.getDeclaredField("recipeType");
field$InjectedCacheChecker$lastRecipe = clazz$InjectedCacheChecker.getDeclaredField("lastRecipe");
field$InjectedCacheChecker$lastCustomRecipe = clazz$InjectedCacheChecker.getDeclaredField("lastCustomRecipe");
// Paletted Container
clazz$InjectedPalettedContainer = byteBuddy
@@ -336,20 +339,22 @@ public class BukkitInjector {
CookingInput<ItemStack> input = new CookingInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack> ceRecipe;
Key lastCustomRecipe = (Key) field$InjectedCacheChecker$lastCustomRecipe.get(thisObj);
if (type == Reflections.instance$RecipeType$SMELTING) {
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.SMELTING, input);
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.SMELTING, input, lastCustomRecipe);
} else if (type == Reflections.instance$RecipeType$BLASTING) {
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.BLASTING, input);
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.BLASTING, input, lastCustomRecipe);
} else if (type == Reflections.instance$RecipeType$SMOKING) {
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.SMOKING, input);
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.SMOKING, input, lastCustomRecipe);
} else {
return Optional.empty();
}
if (ceRecipe == null) {
return Optional.empty();
}
// Cache recipes, it might be incorrect on reloading
field$InjectedCacheChecker$lastCustomRecipe.set(thisObj, ceRecipe.id());
// It doesn't matter at all
field$InjectedCacheChecker$lastRecipe.set(thisObj, resourceLocation);
return Optional.of(Optional.ofNullable(recipeManager.getRecipeHolderByRecipe(ceRecipe)).orElse(pair.getSecond()));
@@ -392,20 +397,22 @@ public class BukkitInjector {
CookingInput<ItemStack> input = new CookingInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack> ceRecipe;
Key lastCustomRecipe = (Key) field$InjectedCacheChecker$lastCustomRecipe.get(thisObj);
if (type == Reflections.instance$RecipeType$SMELTING) {
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.SMELTING, input);
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.SMELTING, input, lastCustomRecipe);
} else if (type == Reflections.instance$RecipeType$BLASTING) {
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.BLASTING, input);
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.BLASTING, input, lastCustomRecipe);
} else if (type == Reflections.instance$RecipeType$SMOKING) {
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.SMOKING, input);
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.SMOKING, input, lastCustomRecipe);
} else {
return Optional.empty();
}
if (ceRecipe == null) {
return Optional.empty();
}
// Cache recipes, it might be incorrect on reloading
field$InjectedCacheChecker$lastCustomRecipe.set(thisObj, ceRecipe.id());
// It doesn't matter at all
field$InjectedCacheChecker$lastRecipe.set(thisObj, id);
return Optional.of(Optional.ofNullable(recipeManager.getRecipeHolderByRecipe(ceRecipe)).orElse(holder));
@@ -447,20 +454,22 @@ public class BukkitInjector {
CookingInput<ItemStack> input = new CookingInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack> ceRecipe;
Key lastCustomRecipe = (Key) field$InjectedCacheChecker$lastCustomRecipe.get(thisObj);
if (type == Reflections.instance$RecipeType$SMELTING) {
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.SMELTING, input);
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.SMELTING, input, lastCustomRecipe);
} else if (type == Reflections.instance$RecipeType$BLASTING) {
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.BLASTING, input);
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.BLASTING, input, lastCustomRecipe);
} else if (type == Reflections.instance$RecipeType$SMOKING) {
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.SMOKING, input);
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.SMOKING, input, lastCustomRecipe);
} else {
return Optional.empty();
}
if (ceRecipe == null) {
return Optional.empty();
}
// Cache recipes, it might be incorrect on reloading
field$InjectedCacheChecker$lastCustomRecipe.set(thisObj, ceRecipe.id());
// It doesn't matter at all
field$InjectedCacheChecker$lastRecipe.set(thisObj, id);
return Optional.of(Optional.ofNullable(recipeManager.getRecipeHolderByRecipe(ceRecipe)).orElse(holder));
@@ -503,20 +512,22 @@ public class BukkitInjector {
CookingInput<ItemStack> input = new CookingInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack> ceRecipe;
Key lastCustomRecipe = (Key) field$InjectedCacheChecker$lastCustomRecipe.get(thisObj);
if (type == Reflections.instance$RecipeType$SMELTING) {
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.SMELTING, input);
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.SMELTING, input, lastCustomRecipe);
} else if (type == Reflections.instance$RecipeType$BLASTING) {
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.BLASTING, input);
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.BLASTING, input, lastCustomRecipe);
} else if (type == Reflections.instance$RecipeType$SMOKING) {
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.SMOKING, input);
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.SMOKING, input, lastCustomRecipe);
} else {
return Optional.empty();
}
if (ceRecipe == null) {
return Optional.empty();
}
// Cache recipes, it might be incorrect on reloading
field$InjectedCacheChecker$lastCustomRecipe.set(thisObj, ceRecipe.id());
// It doesn't matter at all
field$InjectedCacheChecker$lastRecipe.set(thisObj, id);
return Optional.of(Optional.ofNullable(recipeManager.getRecipeHolderByRecipe(ceRecipe)).orElse(holder));

View File

@@ -10,7 +10,6 @@ import net.momirealms.craftengine.bukkit.world.BukkitWorld;
import net.momirealms.craftengine.core.entity.player.InteractionHand;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.item.recipe.Recipe;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.network.ConnectionState;
import net.momirealms.craftengine.core.util.Direction;
@@ -61,7 +60,7 @@ public class BukkitServerPlayer extends Player {
private int resentSoundTick;
private int resentSwingTick;
private Recipe<ItemStack> lastUsedRecipe = null;
private Key lastUsedRecipe = null;
public BukkitServerPlayer(BukkitCraftEngine plugin, Channel channel) {
this.channel = channel;
@@ -536,11 +535,11 @@ public class BukkitServerPlayer extends Player {
return resentSwingTick == gameTicks();
}
public Recipe<ItemStack> lastUsedRecipe() {
public Key lastUsedRecipe() {
return lastUsedRecipe;
}
public void setLastUsedRecipe(Recipe<ItemStack> lastUsedRecipe) {
public void setLastUsedRecipe(Key lastUsedRecipe) {
this.lastUsedRecipe = lastUsedRecipe;
}
}

View File

@@ -1,12 +1,15 @@
package net.momirealms.craftengine.core.item.recipe;
import net.momirealms.craftengine.core.util.Key;
import org.jetbrains.annotations.Nullable;
public abstract class AbstractRecipe<T> implements Recipe<T> {
protected String group;
protected Key id;
protected AbstractRecipe(String group) {
protected AbstractRecipe(Key id, String group) {
this.group = group;
this.id = id;
}
@Override
@@ -14,4 +17,9 @@ public abstract class AbstractRecipe<T> implements Recipe<T> {
public String group() {
return group;
}
@Override
public Key id() {
return id;
}
}

View File

@@ -2,6 +2,7 @@ package net.momirealms.craftengine.core.item.recipe;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.item.recipe.input.RecipeInput;
import net.momirealms.craftengine.core.util.Key;
public abstract class CookingRecipe<T> extends AbstractRecipe<T> {
protected final CookingRecipeCategory category;
@@ -10,13 +11,14 @@ public abstract class CookingRecipe<T> extends AbstractRecipe<T> {
protected final float experience;
protected final int cookingTime;
protected CookingRecipe(CookingRecipeCategory category,
protected CookingRecipe(Key id,
CookingRecipeCategory category,
String group,
Ingredient<T> ingredient,
int cookingTime,
float experience,
CustomRecipeResult<T> result) {
super(group);
super(id, group);
this.category = category;
this.ingredient = ingredient;
this.result = result;

View File

@@ -1,10 +1,12 @@
package net.momirealms.craftengine.core.item.recipe;
import net.momirealms.craftengine.core.util.Key;
public abstract class CraftingTableRecipe<T> extends AbstractRecipe<T> {
protected final CraftingRecipeCategory category;
protected CraftingTableRecipe(CraftingRecipeCategory category, String group) {
super(group);
protected CraftingTableRecipe(Key id, CraftingRecipeCategory category, String group) {
super(id, group);
this.category = category;
}

View File

@@ -12,8 +12,8 @@ import java.util.*;
public class CustomBlastingRecipe<T> extends CookingRecipe<T> {
public static final Factory<?> FACTORY = new Factory<>();
public CustomBlastingRecipe(CookingRecipeCategory category, String group, Ingredient<T> ingredient, int cookingTime, float experience, CustomRecipeResult<T> result) {
super(category, group, ingredient, cookingTime, experience, result);
public CustomBlastingRecipe(Key id, CookingRecipeCategory category, String group, Ingredient<T> ingredient, int cookingTime, float experience, CustomRecipeResult<T> result) {
super(id, category, group, ingredient, cookingTime, experience, result);
}
@Override
@@ -25,7 +25,7 @@ public class CustomBlastingRecipe<T> extends CookingRecipe<T> {
@SuppressWarnings({"unchecked", "rawtypes", "DuplicatedCode"})
@Override
public Recipe<CustomBlastingRecipe<A>> create(Map<String, Object> arguments) {
public Recipe<CustomBlastingRecipe<A>> create(Key id, Map<String, Object> arguments) {
CookingRecipeCategory recipeCategory = arguments.containsKey("category") ? CookingRecipeCategory.valueOf(arguments.get("category").toString().toUpperCase(Locale.ENGLISH)) : null;
String group = arguments.containsKey("group") ? arguments.get("group").toString() : null;
int cookingTime = MiscUtils.getAsInt(arguments.getOrDefault("time", 80));
@@ -40,6 +40,7 @@ public class CustomBlastingRecipe<T> extends CookingRecipe<T> {
}
}
return new CustomBlastingRecipe(
id,
recipeCategory,
group,
Ingredient.of(holders),

View File

@@ -12,8 +12,8 @@ import java.util.*;
public class CustomCampfireRecipe<T> extends CookingRecipe<T> {
public static final Factory<?> FACTORY = new Factory<>();
public CustomCampfireRecipe(CookingRecipeCategory category, String group, Ingredient<T> ingredient, int cookingTime, float experience, CustomRecipeResult<T> result) {
super(category, group, ingredient, cookingTime, experience, result);
public CustomCampfireRecipe(Key id, CookingRecipeCategory category, String group, Ingredient<T> ingredient, int cookingTime, float experience, CustomRecipeResult<T> result) {
super(id, category, group, ingredient, cookingTime, experience, result);
}
@Override
@@ -25,7 +25,7 @@ public class CustomCampfireRecipe<T> extends CookingRecipe<T> {
@SuppressWarnings({"unchecked", "rawtypes", "DuplicatedCode"})
@Override
public Recipe<CustomCampfireRecipe<A>> create(Map<String, Object> arguments) {
public Recipe<CustomCampfireRecipe<A>> create(Key id, Map<String, Object> arguments) {
CookingRecipeCategory recipeCategory = arguments.containsKey("category") ? CookingRecipeCategory.valueOf(arguments.get("category").toString().toUpperCase(Locale.ENGLISH)) : null;
String group = arguments.containsKey("group") ? arguments.get("group").toString() : null;
int cookingTime = MiscUtils.getAsInt(arguments.getOrDefault("time", 80));
@@ -40,6 +40,7 @@ public class CustomCampfireRecipe<T> extends CookingRecipe<T> {
}
}
return new CustomCampfireRecipe(
id,
recipeCategory,
group,
Ingredient.of(holders),

View File

@@ -18,8 +18,8 @@ public class CustomShapedRecipe<T> extends CraftingTableRecipe<T> {
private final Pattern<T> pattern;
private final CustomRecipeResult<T> result;
public CustomShapedRecipe(CraftingRecipeCategory category, String group, Pattern<T> pattern, CustomRecipeResult<T> result) {
super(category, group);
public CustomShapedRecipe(Key id, CraftingRecipeCategory category, String group, Pattern<T> pattern, CustomRecipeResult<T> result) {
super(id, category, group);
this.pattern = pattern;
this.parsedPattern = pattern.parse();
this.result = result;
@@ -140,7 +140,7 @@ public class CustomShapedRecipe<T> extends CraftingTableRecipe<T> {
@SuppressWarnings({"unchecked", "rawtypes", "DuplicatedCode"})
@Override
public Recipe<A> create(Map<String, Object> arguments) {
public Recipe<A> create(Key id, Map<String, Object> arguments) {
List<String> pattern = MiscUtils.getAsStringList(arguments.get("pattern"));
if (pattern.isEmpty()) {
throw new IllegalArgumentException("pattern cannot be empty");
@@ -173,6 +173,7 @@ public class CustomShapedRecipe<T> extends CraftingTableRecipe<T> {
ingredients.put(ch, Ingredient.of(holders));
}
return new CustomShapedRecipe(
id,
recipeCategory,
group,
new Pattern<>(pattern.toArray(new String[0]), ingredients),

View File

@@ -18,8 +18,8 @@ public class CustomShapelessRecipe<T> extends CraftingTableRecipe<T> {
private final PlacementInfo<T> placementInfo;
private final CustomRecipeResult<T> result;
public CustomShapelessRecipe(CraftingRecipeCategory category, String group, List<Ingredient<T>> ingredients, CustomRecipeResult<T> result) {
super(category, group);
public CustomShapelessRecipe(Key id, CraftingRecipeCategory category, String group, List<Ingredient<T>> ingredients, CustomRecipeResult<T> result) {
super(id, category, group);
this.ingredients = ingredients;
this.result = result;
this.placementInfo = PlacementInfo.create(ingredients);
@@ -63,7 +63,7 @@ public class CustomShapelessRecipe<T> extends CraftingTableRecipe<T> {
@SuppressWarnings({"unchecked", "rawtypes", "DuplicatedCode"})
@Override
public Recipe<A> create(Map<String, Object> arguments) {
public Recipe<A> create(Key id, Map<String, Object> arguments) {
Map<String, Object> ingredientMap = MiscUtils.castToMap(arguments.get("ingredients"), true);
if (ingredientMap == null) {
throw new IllegalArgumentException("ingredients cannot be empty");
@@ -84,6 +84,7 @@ public class CustomShapelessRecipe<T> extends CraftingTableRecipe<T> {
ingredients.add(Ingredient.of(holders));
}
return new CustomShapelessRecipe(
id,
recipeCategory,
group,
ingredients,

View File

@@ -12,8 +12,8 @@ import java.util.*;
public class CustomSmeltingRecipe<T> extends CookingRecipe<T> {
public static final Factory<?> FACTORY = new Factory<>();
public CustomSmeltingRecipe(CookingRecipeCategory category, String group, Ingredient<T> ingredient, int cookingTime, float experience, CustomRecipeResult<T> result) {
super(category, group, ingredient, cookingTime, experience, result);
public CustomSmeltingRecipe(Key id, CookingRecipeCategory category, String group, Ingredient<T> ingredient, int cookingTime, float experience, CustomRecipeResult<T> result) {
super(id, category, group, ingredient, cookingTime, experience, result);
}
@Override
@@ -25,7 +25,7 @@ public class CustomSmeltingRecipe<T> extends CookingRecipe<T> {
@SuppressWarnings({"unchecked", "rawtypes", "DuplicatedCode"})
@Override
public Recipe<CustomSmeltingRecipe<A>> create(Map<String, Object> arguments) {
public Recipe<CustomSmeltingRecipe<A>> create(Key id, Map<String, Object> arguments) {
CookingRecipeCategory recipeCategory = arguments.containsKey("category") ? CookingRecipeCategory.valueOf(arguments.get("category").toString().toUpperCase(Locale.ENGLISH)) : null;
String group = arguments.containsKey("group") ? arguments.get("group").toString() : null;
int cookingTime = MiscUtils.getAsInt(arguments.getOrDefault("time", 80));
@@ -40,6 +40,7 @@ public class CustomSmeltingRecipe<T> extends CookingRecipe<T> {
}
}
return new CustomSmeltingRecipe(
id,
recipeCategory,
group,
Ingredient.of(holders),

View File

@@ -12,8 +12,8 @@ import java.util.*;
public class CustomSmokingRecipe<T> extends CookingRecipe<T> {
public static final Factory<?> FACTORY = new Factory<>();
public CustomSmokingRecipe(CookingRecipeCategory category, String group, Ingredient<T> ingredient, int cookingTime, float experience, CustomRecipeResult<T> result) {
super(category, group, ingredient, cookingTime, experience, result);
public CustomSmokingRecipe(Key id, CookingRecipeCategory category, String group, Ingredient<T> ingredient, int cookingTime, float experience, CustomRecipeResult<T> result) {
super(id, category, group, ingredient, cookingTime, experience, result);
}
@Override
@@ -25,7 +25,7 @@ public class CustomSmokingRecipe<T> extends CookingRecipe<T> {
@SuppressWarnings({"unchecked", "rawtypes", "DuplicatedCode"})
@Override
public Recipe<CustomSmokingRecipe<A>> create(Map<String, Object> arguments) {
public Recipe<CustomSmokingRecipe<A>> create(Key id, Map<String, Object> arguments) {
CookingRecipeCategory recipeCategory = arguments.containsKey("category") ? CookingRecipeCategory.valueOf(arguments.get("category").toString().toUpperCase(Locale.ENGLISH)) : null;
String group = arguments.containsKey("group") ? arguments.get("group").toString() : null;
int cookingTime = MiscUtils.getAsInt(arguments.getOrDefault("time", 80));
@@ -40,6 +40,7 @@ public class CustomSmokingRecipe<T> extends CookingRecipe<T> {
}
}
return new CustomSmokingRecipe(
id,
recipeCategory,
group,
Ingredient.of(holders),

View File

@@ -15,6 +15,8 @@ public interface Recipe<T> {
@NotNull
Key type();
Key id();
@Nullable
String group();
}

View File

@@ -8,7 +8,7 @@ import java.util.Map;
public interface RecipeFactory<T> {
Recipe<T> create(Map<String, Object> arguments);
Recipe<T> create(Key id, Map<String, Object> arguments);
@SuppressWarnings({"unchecked", "rawtypes"})
default CustomRecipeResult<T> parseResult(Map<String, Object> arguments) {

View File

@@ -33,7 +33,7 @@ public class RecipeTypes {
}
@SuppressWarnings("unchecked")
public static <T> Recipe<T> fromMap(Map<String, Object> map) {
public static <T> Recipe<T> fromMap(Key id, Map<String, Object> map) {
String type = (String) map.get("type");
if (type == null) {
throw new NullPointerException("recipe type cannot be null");
@@ -43,6 +43,6 @@ public class RecipeTypes {
if (factory == null) {
throw new IllegalArgumentException("Unknown recipe type: " + type);
}
return factory.create(map);
return factory.create(id, map);
}
}

View File

@@ -0,0 +1,6 @@
package net.momirealms.craftengine.core.util;
@FunctionalInterface
public interface HeptaFunction<T, U, V, W, X, Y, O, R> {
R apply(T t, U u, V v, W w, X x, Y y, O o);
}