9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-25 18:09:27 +00:00

重构配方匹配

This commit is contained in:
XiaoMoMi
2025-07-11 04:07:18 +08:00
parent 87f1a53497
commit 18c67d34e0
36 changed files with 231 additions and 256 deletions

View File

@@ -8,8 +8,8 @@ import net.momirealms.craftengine.core.item.modifier.ItemDataModifier;
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
import net.momirealms.craftengine.core.plugin.context.event.EventTrigger;
import net.momirealms.craftengine.core.plugin.context.function.Function;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.UniqueKey;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
@@ -21,7 +21,7 @@ public class BukkitCustomItem extends AbstractCustomItem<ItemStack> {
private final Object item;
private final Object clientItem;
public BukkitCustomItem(Holder<Key> id, Object item, Object clientItem, Key materialKey, Key clientBoundMaterialKey,
public BukkitCustomItem(UniqueKey id, Object item, Object clientItem, Key materialKey, Key clientBoundMaterialKey,
List<ItemBehavior> behaviors,
List<ItemDataModifier<ItemStack>> modifiers, List<ItemDataModifier<ItemStack>> clientBoundModifiers,
ItemSettings settings,
@@ -64,7 +64,7 @@ public class BukkitCustomItem extends AbstractCustomItem<ItemStack> {
}
public static class BuilderImpl implements Builder<ItemStack> {
private Holder<Key> id;
private UniqueKey id;
private Key itemKey;
private final Object item;
private Key clientBoundItemKey;
@@ -81,7 +81,7 @@ public class BukkitCustomItem extends AbstractCustomItem<ItemStack> {
}
@Override
public Builder<ItemStack> id(Holder<Key> id) {
public Builder<ItemStack> id(UniqueKey id) {
this.id = id;
return this;
}

View File

@@ -26,9 +26,6 @@ import net.momirealms.craftengine.core.plugin.config.Config;
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
import net.momirealms.craftengine.core.plugin.logger.Debugger;
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.registry.WritableRegistry;
import net.momirealms.craftengine.core.util.*;
import org.bukkit.Bukkit;
import org.bukkit.Material;
@@ -349,7 +346,7 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
}
@Override
protected CustomItem.Builder<ItemStack> createPlatformItemBuilder(Holder<Key> id, Key materialId, Key clientBoundMaterialId) {
protected CustomItem.Builder<ItemStack> createPlatformItemBuilder(UniqueKey id, Key materialId, Key clientBoundMaterialId) {
Object item = FastNMS.INSTANCE.method$Registry$getValue(MBuiltInRegistries.ITEM, KeyUtils.toResourceLocation(materialId));
Object clientBoundItem = materialId == clientBoundMaterialId ? item : FastNMS.INSTANCE.method$Registry$getValue(MBuiltInRegistries.ITEM, KeyUtils.toResourceLocation(clientBoundMaterialId));
if (item == null) {
@@ -372,14 +369,12 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
Key itemKey = KeyUtils.resourceLocationToKey(resourceLocation);
if (itemKey.namespace().equals("minecraft")) {
VANILLA_ITEMS.add(itemKey);
Holder.Reference<Key> holder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(itemKey)
.orElseGet(() -> ((WritableRegistry<Key>) BuiltInRegistries.OPTIMIZED_ITEM_ID)
.register(ResourceKey.create(BuiltInRegistries.OPTIMIZED_ITEM_ID.key().location(), itemKey), itemKey));
UniqueKey uniqueKey = UniqueKey.create(itemKey);
Object mcHolder = FastNMS.INSTANCE.method$Registry$getHolderByResourceKey(MBuiltInRegistries.ITEM, FastNMS.INSTANCE.method$ResourceKey$create(MRegistries.ITEM, resourceLocation)).get();
Set<Object> tags = (Set<Object>) CoreReflections.field$Holder$Reference$tags.get(mcHolder);
for (Object tag : tags) {
Key tagId = Key.of(CoreReflections.field$TagKey$location.get(tag).toString());
VANILLA_ITEM_TAGS.computeIfAbsent(tagId, (key) -> new ArrayList<>()).add(holder);
VANILLA_ITEM_TAGS.computeIfAbsent(tagId, (key) -> new ArrayList<>()).add(uniqueKey);
}
}
}

View File

@@ -2,29 +2,28 @@ package net.momirealms.craftengine.bukkit.item.recipe;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
import net.momirealms.craftengine.bukkit.item.CloneableConstantItem;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.plugin.reflection.bukkit.CraftBukkitReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MItems;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistries;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistryOps;
import net.momirealms.craftengine.bukkit.util.KeyUtils;
import net.momirealms.craftengine.bukkit.util.MaterialUtils;
import net.momirealms.craftengine.bukkit.util.RecipeUtils;
import net.momirealms.craftengine.core.item.CustomItem;
import net.momirealms.craftengine.core.item.ItemBuildContext;
import net.momirealms.craftengine.core.item.*;
import net.momirealms.craftengine.core.item.recipe.*;
import net.momirealms.craftengine.core.item.recipe.Recipe;
import net.momirealms.craftengine.core.item.recipe.vanilla.*;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.config.Config;
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.HeptaFunction;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.VersionHelper;
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
import net.momirealms.craftengine.core.util.*;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
@@ -135,6 +134,8 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
}
Object finalNmsRecipe = nmsRecipe;
return () -> registerNMSSmithingRecipe(finalNmsRecipe);
} catch (InvalidRecipeIngredientException e) {
throw e;
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to convert smithing transform recipe", e);
return null;
@@ -220,8 +221,8 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
});
MIXED_RECIPE_CONVERTORS.put(RecipeTypes.STONECUTTING, (BukkitRecipeConvertor<CustomStoneCuttingRecipe<ItemStack>>) (id, recipe) -> {
List<ItemStack> itemStacks = new ArrayList<>();
for (Holder<Key> item : recipe.ingredient().items()) {
itemStacks.add(BukkitItemManager.instance().buildItemStack(item.value(), null));
for (UniqueKey item : recipe.ingredient().items()) {
itemStacks.add(BukkitItemManager.instance().buildItemStack(item.key(), null));
}
StonecuttingRecipe stonecuttingRecipe = new StonecuttingRecipe(
new NamespacedKey(id.namespace(), id.value()), recipe.result(ItemBuildContext.EMPTY),
@@ -351,6 +352,8 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
if (converted != null) {
this.delayedTasksOnMainThread.add(converted);
}
} catch (InvalidRecipeIngredientException e) {
throw new LocalizedResourceConfigException("warning.config.recipe.invalid_ingredient", e.ingredient());
} catch (Exception e) {
this.plugin.logger().warn("Failed to convert recipe " + id, e);
}
@@ -502,13 +505,13 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
private void handleDataPackStoneCuttingRecipe(Key id, VanillaStoneCuttingRecipe recipe) {
ItemStack result = createDataPackResultStack(recipe.result());
Set<Holder<Key>> holders = new HashSet<>();
Set<UniqueKey> holders = new HashSet<>();
for (String item : recipe.ingredient()) {
if (item.charAt(0) == '#') {
Key tag = Key.from(item.substring(1));
holders.addAll(this.plugin.itemManager().tagToItems(tag));
} else {
holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.from(item)).orElseThrow());
holders.add(UniqueKey.create(Key.from(item)));
}
}
CustomStoneCuttingRecipe<ItemStack> ceRecipe = new CustomStoneCuttingRecipe<>(
@@ -524,7 +527,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
boolean hasCustomItemInTag = false;
List<Ingredient<ItemStack>> ingredientList = new ArrayList<>();
for (List<String> list : recipe.ingredients()) {
Set<Holder<Key>> holders = new HashSet<>();
Set<UniqueKey> holders = new HashSet<>();
for (String item : list) {
if (item.charAt(0) == '#') {
Key tag = Key.of(item.substring(1));
@@ -535,7 +538,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
}
holders.addAll(plugin.itemManager().tagToItems(tag));
} else {
holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.from(item)).orElseThrow());
holders.add(UniqueKey.create(Key.from(item)));
}
}
ingredientList.add(Ingredient.of(holders));
@@ -560,7 +563,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
boolean hasCustomItemInTag = false;
Map<Character, Ingredient<ItemStack>> ingredients = new HashMap<>();
for (Map.Entry<Character, List<String>> entry : recipe.ingredients().entrySet()) {
Set<Holder<Key>> holders = new HashSet<>();
Set<UniqueKey> holders = new HashSet<>();
for (String item : entry.getValue()) {
if (item.charAt(0) == '#') {
Key tag = Key.from(item.substring(1));
@@ -571,7 +574,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
}
holders.addAll(plugin.itemManager().tagToItems(tag));
} else {
holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.from(item)).orElseThrow());
holders.add(UniqueKey.create(Key.from(item)));
}
}
ingredients.put(entry.getKey(), Ingredient.of(holders));
@@ -597,7 +600,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
Consumer<Runnable> callback) {
NamespacedKey key = new NamespacedKey(id.namespace(), id.value());
ItemStack result = createDataPackResultStack(recipe.result());
Set<Holder<Key>> holders = new HashSet<>();
Set<UniqueKey> holders = new HashSet<>();
boolean hasCustomItemInTag = readVanillaIngredients(false, recipe.ingredient(), holders::add);
CustomCookingRecipe<ItemStack> ceRecipe = constructor2.apply(
id, recipe.category(), recipe.group(),
@@ -620,11 +623,11 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
ItemStack result = createDataPackResultStack(recipe.result());
boolean hasCustomItemInTag;
Set<Holder<Key>> additionHolders = new HashSet<>();
Set<UniqueKey> additionHolders = new HashSet<>();
hasCustomItemInTag = readVanillaIngredients(false, recipe.addition(), additionHolders::add);
Set<Holder<Key>> templateHolders = new HashSet<>();
Set<UniqueKey> templateHolders = new HashSet<>();
hasCustomItemInTag = readVanillaIngredients(hasCustomItemInTag, recipe.template(), templateHolders::add);
Set<Holder<Key>> baseHolders = new HashSet<>();
Set<UniqueKey> baseHolders = new HashSet<>();
hasCustomItemInTag = readVanillaIngredients(hasCustomItemInTag, recipe.base(), baseHolders::add);
CustomSmithingTransformRecipe<ItemStack> ceRecipe = new CustomSmithingTransformRecipe<>(
@@ -647,7 +650,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
this.registerInternalRecipe(id, ceRecipe);
}
private boolean readVanillaIngredients(boolean hasCustomItemInTag, List<String> ingredients, Consumer<Holder<Key>> holderConsumer) {
private boolean readVanillaIngredients(boolean hasCustomItemInTag, List<String> ingredients, Consumer<UniqueKey> holderConsumer) {
for (String item : ingredients) {
if (item.charAt(0) == '#') {
Key tag = Key.from(item.substring(1));
@@ -656,11 +659,11 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
hasCustomItemInTag = true;
}
}
for (Holder<Key> holder : this.plugin.itemManager().tagToItems(tag)) {
for (UniqueKey holder : this.plugin.itemManager().tagToItems(tag)) {
holderConsumer.accept(holder);
}
} else {
holderConsumer.accept(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.from(item)).orElseThrow());
holderConsumer.accept(UniqueKey.create(Key.from(item)));
}
}
return hasCustomItemInTag;
@@ -703,8 +706,8 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
private static RecipeChoice ingredientToBukkitRecipeChoice(Ingredient<ItemStack> ingredient) {
Set<Material> materials = new HashSet<>();
for (Holder<Key> holder : ingredient.items()) {
materials.add(getMaterialById(holder.value()));
for (UniqueKey holder : ingredient.items()) {
materials.add(getMaterialById(holder.key()));
}
return new RecipeChoice.MaterialChoice(new ArrayList<>(materials));
}
@@ -715,15 +718,21 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
return material;
}
Optional<CustomItem<ItemStack>> optionalItem = BukkitItemManager.instance().getCustomItem(key);
return optionalItem.map(itemStackCustomItem -> MaterialUtils.getMaterial(itemStackCustomItem.material())).orElse(null);
return optionalItem.map(itemStackCustomItem -> MaterialUtils.getMaterial(itemStackCustomItem.material())).orElseThrow(() -> new InvalidRecipeIngredientException(key.asString()));
}
private static List<Object> getIngredientLooks(List<Holder<Key>> holders) {
private static List<Object> getIngredientLooks(List<UniqueKey> holders) {
List<Object> itemStacks = new ArrayList<>();
for (Holder<Key> holder : holders) {
ItemStack itemStack = BukkitItemManager.instance().getBuildableItem(holder.value()).get().buildItemStack(ItemBuildContext.EMPTY, 1);
Object nmsStack = FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack);
itemStacks.add(nmsStack);
for (UniqueKey holder : holders) {
Optional<? extends BuildableItem<ItemStack>> buildableItem = BukkitItemManager.instance().getBuildableItem(holder.key());
if (buildableItem.isPresent()) {
ItemStack itemStack = buildableItem.get().buildItemStack(ItemBuildContext.EMPTY, 1);
Object nmsStack = FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack);
itemStacks.add(nmsStack);
} else {
Item<ItemStack> barrier = BukkitItemManager.instance().createWrappedItem(ItemKeys.BARRIER, null);
barrier.customNameJson(AdventureHelper.componentToJson(Component.text(holder.key().asString()).color(NamedTextColor.RED)));
}
}
return itemStacks;
}

View File

@@ -10,9 +10,8 @@ import net.momirealms.craftengine.core.item.recipe.Recipe;
import net.momirealms.craftengine.core.item.recipe.RecipeTypes;
import net.momirealms.craftengine.core.item.recipe.input.CraftingInput;
import net.momirealms.craftengine.core.plugin.config.Config;
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.UniqueKey;
import org.bukkit.block.Crafter;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@@ -23,7 +22,6 @@ import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class CrafterEventListener implements Listener {
private static final OptimizedIDItem<ItemStack> EMPTY = new OptimizedIDItem<>(null, null);
@@ -62,14 +60,8 @@ public class CrafterEventListener implements Listener {
optimizedIDItems.add(EMPTY);
} else {
Item<ItemStack> wrappedItem = this.itemManager.wrap(itemStack);
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
if (idHolder.isEmpty()) {
// an invalid item is used in recipe, we disallow it
event.setCancelled(true);
return;
} else {
optimizedIDItems.add(new OptimizedIDItem<>(idHolder.get(), itemStack));
}
UniqueKey uniqueId = UniqueKey.create(wrappedItem.id());
optimizedIDItems.add(new OptimizedIDItem<>(uniqueId, itemStack));
}
}

View File

@@ -25,12 +25,7 @@ import net.momirealms.craftengine.core.item.setting.AnvilRepairItem;
import net.momirealms.craftengine.core.item.setting.ItemEquipment;
import net.momirealms.craftengine.core.plugin.config.Config;
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.AdventureHelper;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.Pair;
import net.momirealms.craftengine.core.util.VersionHelper;
import net.momirealms.craftengine.core.util.*;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.Campfire;
@@ -42,6 +37,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.*;
import org.bukkit.event.inventory.*;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.*;
import org.bukkit.inventory.view.AnvilView;
@@ -79,10 +75,9 @@ public class RecipeEventListener implements Listener {
if (ItemStackUtils.isEmpty(item)) return;
if (ItemStackUtils.isEmpty(fuelStack)) {
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(item);
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
if (idHolder.isEmpty()) return;
UniqueKey uniqueKey = UniqueKey.create(wrappedItem.id());
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), item));
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(uniqueKey, item));
Key recipeType;
if (furnaceInventory.getType() == InventoryType.FURNACE) {
recipeType = RecipeTypes.SMELTING;
@@ -92,7 +87,7 @@ public class RecipeEventListener implements Listener {
recipeType = RecipeTypes.SMOKING;
}
Recipe<ItemStack> ceRecipe = recipeManager.recipeByInput(recipeType, input);
Recipe<ItemStack> ceRecipe = this.recipeManager.recipeByInput(recipeType, input);
// The item is an ingredient, we should never consider it as fuel firstly
if (ceRecipe != null) return;
@@ -360,11 +355,8 @@ public class RecipeEventListener implements Listener {
return;
}
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
if (idHolder.isEmpty()) {
return;
}
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
UniqueKey uniqueKey = UniqueKey.create(wrappedItem.id());
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(uniqueKey, itemStack));
CustomCampfireRecipe<ItemStack> ceRecipe = (CustomCampfireRecipe<ItemStack>) this.recipeManager.recipeByInput(RecipeTypes.CAMPFIRE_COOKING, input);
if (ceRecipe == null) {
event.setCancelled(true);
@@ -390,13 +382,8 @@ public class RecipeEventListener implements Listener {
ItemStack itemStack = event.getSource();
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
if (idHolder.isEmpty()) {
event.setTotalCookTime(Integer.MAX_VALUE);
return;
}
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
UniqueKey itemId = UniqueKey.create(wrappedItem.id());
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(itemId, itemStack));
CustomCampfireRecipe<ItemStack> ceRecipe = (CustomCampfireRecipe<ItemStack>) this.recipeManager.recipeByInput(RecipeTypes.CAMPFIRE_COOKING, input);
if (ceRecipe == null) {
event.setTotalCookTime(Integer.MAX_VALUE);
@@ -425,13 +412,8 @@ public class RecipeEventListener implements Listener {
ItemStack itemStack = event.getSource();
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
if (idHolder.isEmpty()) {
event.setCancelled(true);
return;
}
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
UniqueKey itemId = UniqueKey.create(wrappedItem.id());
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(itemId, itemStack));
CustomCampfireRecipe<ItemStack> ceRecipe = (CustomCampfireRecipe<ItemStack>) this.recipeManager.recipeByInput(RecipeTypes.CAMPFIRE_COOKING, input);
if (ceRecipe == null) {
event.setCancelled(true);
@@ -893,14 +875,8 @@ public class RecipeEventListener implements Listener {
optimizedIDItems.add(EMPTY);
} else {
Item<ItemStack> wrappedItem = this.itemManager.wrap(itemStack);
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
if (idHolder.isEmpty()) {
// an invalid item is used in recipe, we disallow it
inventory.setResult(null);
return;
} else {
optimizedIDItems.add(new OptimizedIDItem<>(idHolder.get(), itemStack));
}
UniqueKey itemUniqueId = UniqueKey.create(wrappedItem.id());
optimizedIDItems.add(new OptimizedIDItem<>(itemUniqueId, itemStack));
}
}
@@ -1040,8 +1016,7 @@ public class RecipeEventListener implements Listener {
return EMPTY;
} else {
Item<ItemStack> wrappedItem = this.itemManager.wrap(itemStack);
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
return idHolder.map(keyReference -> new OptimizedIDItem<>(keyReference, itemStack)).orElse(EMPTY);
return new OptimizedIDItem<>(UniqueKey.create(wrappedItem.id()), itemStack);
}
}
}

View File

@@ -23,10 +23,9 @@ import net.momirealms.craftengine.core.item.recipe.CustomCookingRecipe;
import net.momirealms.craftengine.core.item.recipe.OptimizedIDItem;
import net.momirealms.craftengine.core.item.recipe.RecipeTypes;
import net.momirealms.craftengine.core.item.recipe.input.SingleItemInput;
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.ReflectionUtils;
import net.momirealms.craftengine.core.util.UniqueKey;
import net.momirealms.craftengine.core.util.VersionHelper;
import org.bukkit.inventory.ItemStack;
@@ -135,12 +134,9 @@ public class RecipeInjector {
);
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
if (idHolder.isEmpty()) {
return Optional.empty();
}
UniqueKey uniqueKey = UniqueKey.create(wrappedItem.id());
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(uniqueKey, itemStack));
CustomCookingRecipe<ItemStack> ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(injectedCacheCheck.customRecipeType(), input, injectedCacheCheck.lastCustomRecipe());
if (ceRecipe == null) {
return Optional.empty();
@@ -186,12 +182,9 @@ public class RecipeInjector {
}
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
if (idHolder.isEmpty()) {
return Optional.empty();
}
UniqueKey uniqueKey = UniqueKey.create(wrappedItem.id());
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(uniqueKey, itemStack));
CustomCookingRecipe<ItemStack> ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(injectedCacheCheck.customRecipeType(), input, injectedCacheCheck.lastCustomRecipe());
if (ceRecipe == null) {
return Optional.empty();
@@ -232,12 +225,9 @@ public class RecipeInjector {
ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(FastNMS.INSTANCE.field$SingleRecipeInput$item(args[0]));
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
if (idHolder.isEmpty()) {
return Optional.empty();
}
UniqueKey uniqueKey = UniqueKey.create(wrappedItem.id());
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(uniqueKey, itemStack));
CustomCookingRecipe<ItemStack> ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(injectedCacheCheck.customRecipeType(), input, injectedCacheCheck.lastCustomRecipe());
if (ceRecipe == null) {
return Optional.empty();
@@ -282,12 +272,9 @@ public class RecipeInjector {
// 获取唯一内存地址id
ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(FastNMS.INSTANCE.field$SingleRecipeInput$item(args[0]));
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
if (idHolder.isEmpty()) {
return Optional.empty();
}
UniqueKey uniqueKey = UniqueKey.create(wrappedItem.id());
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(uniqueKey, itemStack));
CustomCookingRecipe<ItemStack> ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(injectedCacheCheck.customRecipeType(), input, injectedCacheCheck.lastCustomRecipe());
// 这个ce配方并不存在那么应该返回空
if (ceRecipe == null) {

View File

@@ -7,6 +7,7 @@ public final class MItems {
public static final Object AIR;
public static final Object WATER_BUCKET;
public static final Object BARRIER;
private static Object getById(String id) {
Object rl = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", id);
@@ -16,5 +17,6 @@ public final class MItems {
static {
AIR = getById("air");
WATER_BUCKET = getById("water_bucket");
BARRIER = getById("barrier");
}
}

View File

@@ -9,11 +9,10 @@ import net.momirealms.craftengine.core.item.recipe.RecipeTypes;
import net.momirealms.craftengine.core.item.recipe.input.SingleItemInput;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.config.Config;
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.Direction;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.QuadFunction;
import net.momirealms.craftengine.core.util.UniqueKey;
import net.momirealms.craftengine.core.world.BlockHitResult;
import net.momirealms.craftengine.core.world.BlockPos;
import org.bukkit.block.data.BlockData;
@@ -24,7 +23,6 @@ import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
public class InteractUtils {
private static final Map<Key, QuadFunction<Player, Item<ItemStack>, BlockData, BlockHitResult, Boolean>> INTERACTIONS = new HashMap<>();
@@ -81,17 +79,17 @@ public class InteractUtils {
});
registerInteraction(BlockKeys.SOUL_CAMPFIRE, (player, item, blockState, result) -> {
if (!Config.enableRecipeSystem()) return false;
Optional<Holder.Reference<Key>> optional = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(item.id());
return optional.filter(keyReference -> BukkitRecipeManager.instance().recipeByInput(RecipeTypes.CAMPFIRE_COOKING, new SingleItemInput<>(new OptimizedIDItem<>(
keyReference, item.getItem()
))) != null).isPresent();
UniqueKey uniqueKey = UniqueKey.create(item.id());
return BukkitRecipeManager.instance().recipeByInput(RecipeTypes.CAMPFIRE_COOKING, new SingleItemInput<>(new OptimizedIDItem<>(
uniqueKey, item.getItem()
))) != null;
});
registerInteraction(BlockKeys.CAMPFIRE, (player, item, blockState, result) -> {
if (!Config.enableRecipeSystem()) return false;
Optional<Holder.Reference<Key>> optional = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(item.id());
return optional.filter(keyReference -> BukkitRecipeManager.instance().recipeByInput(RecipeTypes.CAMPFIRE_COOKING, new SingleItemInput<>(new OptimizedIDItem<>(
keyReference, item.getItem()
))) != null).isPresent();
UniqueKey uniqueKey = UniqueKey.create(item.id());
return BukkitRecipeManager.instance().recipeByInput(RecipeTypes.CAMPFIRE_COOKING, new SingleItemInput<>(new OptimizedIDItem<>(
uniqueKey, item.getItem()
))) != null;
});
registerInteraction(BlockKeys.DECORATED_POT, (player, item, blockState, result) -> true);
registerInteraction(BlockKeys.HOPPER, (player, item, blockState, result) -> true);

View File

@@ -120,7 +120,8 @@ warning.config.image.invalid_hex_value: "<yellow>Problem in Datei <arg:0> gefund
warning.config.recipe.duplicate: "<yellow>Problem in Datei <arg:0> gefunden - Dupliziertes Rezept '<arg:1>'. Bitte überprüfen Sie, ob dieselbe Konfiguration in anderen Dateien vorhanden ist.</yellow>"
warning.config.recipe.missing_type: "<yellow>Problem in Datei <arg:0> gefunden - Dem Rezept '<arg:1>' fehlt das erforderliche 'type'-Argument.</yellow>"
warning.config.recipe.invalid_type: "<yellow>Problem in Datei <arg:0> gefunden - Das Rezept '<arg:1>' verwendet einen ungültigen Rezepttyp '<arg:2>'.</yellow>"
warning.config.recipe.invalid_item: "<yellow>Problem in Datei <arg:0> gefunden - Das Rezept '<arg:1>' verwendet einen ungültigen Gegenstand '<arg:2>'.</yellow>"
warning.config.recipe.invalid_ingredient: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid ingredient '<arg:2>'.</yellow>"
warning.config.recipe.invalid_result: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid result '<arg:2>'.</yellow>"
warning.config.recipe.missing_ingredient: "<yellow>Problem in Datei <arg:0> gefunden - Dem Kochrezept '<arg:1>' fehlt das erforderliche 'ingredient'-Argument.</yellow>"
warning.config.recipe.missing_result: "<yellow>Problem in Datei <arg:0> gefunden - Dem Rezept '<arg:1>' fehlt das erforderliche 'result'-Argument.</yellow>"
warning.config.recipe.result.missing_id: "<yellow>Problem in Datei <arg:0> gefunden - Dem Rezept '<arg:1>' fehlt das erforderliche Argument 'id' für das Rezeptresultat.</yellow>"

View File

@@ -121,7 +121,8 @@ warning.config.image.invalid_hex_value: "<yellow>Issue found in file <arg:0> - T
warning.config.recipe.duplicate: "<yellow>Issue found in file <arg:0> - Duplicated recipe '<arg:1>'. Please check if there is the same configuration in other files.</yellow>"
warning.config.recipe.missing_type: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is missing the required 'type' argument.</yellow>"
warning.config.recipe.invalid_type: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid recipe type '<arg:2>'.</yellow>"
warning.config.recipe.invalid_item: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid item '<arg:2>'.</yellow>"
warning.config.recipe.invalid_ingredient: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid ingredient '<arg:2>'.</yellow>"
warning.config.recipe.invalid_result: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid result '<arg:2>'.</yellow>"
warning.config.recipe.missing_ingredient: "<yellow>Issue found in file <arg:0> - The cooking recipe '<arg:1>' is missing the required 'ingredient' argument.</yellow>"
warning.config.recipe.missing_result: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is missing the required 'result' argument.</yellow>"
warning.config.recipe.result.missing_id: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is missing the required argument 'id' for recipe result.</yellow>"

View File

@@ -84,7 +84,8 @@ warning.config.image.invalid_hex_value: "<yellow>Problema encontrado en el archi
warning.config.recipe.duplicate: "<yellow>Problema encontrado en el archivo <arg:0> - Receta duplicada '<arg:1>'. Verifica si hay la misma configuración en otros archivos.</yellow>"
warning.config.recipe.missing_type: "<yellow>Problema encontrado en el archivo <arg:0> - La receta '<arg:1>' carece del argumento requerido 'type'.</yellow>"
warning.config.recipe.invalid_type: "<yellow>Problema encontrado en el archivo <arg:0> - La receta '<arg:1>' está usando un tipo de receta inválido '<arg:2>'.</yellow>"
warning.config.recipe.invalid_item: "<yellow>Problema encontrado en el archivo <arg:0> - La receta '<arg:1>' está usando un objeto inválido '<arg:2>'.</yellow>"
warning.config.recipe.invalid_ingredient: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid ingredient '<arg:2>'.</yellow>"
warning.config.recipe.invalid_result: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid result '<arg:2>'.</yellow>"
warning.config.recipe.missing_ingredient: "<yellow>Problema encontrado en el archivo <arg:0> - La receta de cocción '<arg:1>' carece del argumento requerido 'ingredient'.</yellow>"
warning.config.recipe.missing_result: "<yellow>Problema encontrado en el archivo <arg:0> - La receta '<arg:1>' carece del argumento requerido 'result'.</yellow>"
warning.config.recipe.result.missing_id: "<yellow>Problema encontrado en el archivo <arg:0> - La receta '<arg:1>' carece del argumento requerido 'id' para el resultado de la receta.</yellow>"

View File

@@ -120,7 +120,8 @@ warning.config.image.invalid_hex_value: "<yellow>Проблема найдена
warning.config.recipe.duplicate: "<yellow>Проблема найдена в файле <arg:0> - Дублированный рецепт '<arg:1>'. Проверьте, есть ли такая же конфигурация в других файлах.</yellow>"
warning.config.recipe.missing_type: "<yellow>Проблема найдена в файле <arg:0> - В рецепте '<arg:1>' отсутствует необходимый 'type' аргумент.</yellow>"
warning.config.recipe.invalid_type: "<yellow>Проблема найдена в файле <arg:0> - Рецепт '<arg:1>' использует недопустимый тип рецепта '<arg:2>'.</yellow>"
warning.config.recipe.invalid_item: "<yellow>Проблема найдена в файле <arg:0> - Рецепт '<arg:1>' использует недопустимый предмет '<arg:2>'.</yellow>"
warning.config.recipe.invalid_ingredient: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid ingredient '<arg:2>'.</yellow>"
warning.config.recipe.invalid_result: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid result '<arg:2>'.</yellow>"
warning.config.recipe.missing_ingredient: "<yellow>Проблема найдена в файле <arg:0> - В рецепт приготовления '<arg:1>' отсутствует необходимый 'ingredient' аргумент.</yellow>"
warning.config.recipe.missing_result: "<yellow>Проблема найдена в файле <arg:0> - В рецепте '<arg:1>' отсутствует необходимый 'result' аргумент.</yellow>"
warning.config.recipe.result.missing_id: "<yellow>Проблема найдена в файле <arg:0> - В рецепте '<arg:1>' отсутствует необходимый аргумент 'id' для результата рецепта.</yellow>"

View File

@@ -83,7 +83,8 @@ warning.config.image.invalid_hex_value: "<yellow><arg:0> dosyasında sorun bulun
warning.config.recipe.duplicate: "<yellow><arg:0> dosyasında sorun bulundu - Yinelenen tarif '<arg:1>'. Diğer dosyalarda aynı yapılandırmanın olup olmadığını kontrol edin.</yellow>"
warning.config.recipe.missing_type: "<yellow><arg:0> dosyasında sorun bulundu - '<arg:1>' tarifi gerekli 'type' argümanı eksik.</yellow>"
warning.config.recipe.invalid_type: "<yellow><arg:0> dosyasında sorun bulundu - '<arg:1>' tarifi geçersiz bir tarif türü '<arg:2>' kullanıyor.</yellow>"
warning.config.recipe.invalid_item: "<yellow><arg:0> dosyasında sorun bulundu - '<arg:1>' tarifi geçersiz bir eşya '<arg:2>' kullanıyor.</yellow>"
warning.config.recipe.invalid_ingredient: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid ingredient '<arg:2>'.</yellow>"
warning.config.recipe.invalid_result: "<yellow>Issue found in file <arg:0> - The recipe '<arg:1>' is using an invalid result '<arg:2>'.</yellow>"
warning.config.recipe.missing_ingredient: "<yellow><arg:0> dosyasında sorun bulundu - '<arg:1>' pişirme tarifi gerekli 'ingredient' argümanı eksik.</yellow>"
warning.config.recipe.missing_result: "<yellow><arg:0> dosyasında sorun bulundu - '<arg:1>' tarifi gerekli 'result' argümanı eksik.</yellow>"
warning.config.recipe.result.missing_id: "<yellow><arg:0> dosyasında sorun bulundu - '<arg:1>' tarifi, tarif sonucu için gerekli 'id' argümanı eksik.</yellow>"

View File

@@ -121,7 +121,8 @@ warning.config.image.invalid_hex_value: "<yellow>在文件 <arg:0> 发现问题
warning.config.recipe.duplicate: "<yellow>在文件 <arg:0> 发现问题 - 重复的配方 '<arg:1>' 请检查其他文件中是否存在相同配置</yellow>"
warning.config.recipe.missing_type: "<yellow>在文件 <arg:0> 发现问题 - 配方 '<arg:1>' 缺少必需的 'type' 参数</yellow>"
warning.config.recipe.invalid_type: "<yellow>在文件 <arg:0> 发现问题 - 配方 '<arg:1>' 使用了无效的配方类型 '<arg:2>'</yellow>"
warning.config.recipe.invalid_item: "<yellow>在文件 <arg:0> 发现问题 - 配方 '<arg:1>' 使用了无效的物品 '<arg:2>'</yellow>"
warning.config.recipe.invalid_ingredient: "<yellow>在文件 <arg:0> 发现问题 - 配方 '<arg:1>' 使用了无效的原料 '<arg:2>'</yellow>"
warning.config.recipe.invalid_result: "<yellow>在文件 <arg:0> 发现问题 - 配方 '<arg:1>' 使用了无效的结果 '<arg:2>'</yellow>"
warning.config.recipe.missing_ingredient: "<yellow>在文件 <arg:0> 发现问题 - 烧炼配方 '<arg:1>' 缺少必需的 'ingredient' 参数</yellow>"
warning.config.recipe.missing_result: "<yellow>在文件 <arg:0> 发现问题 - 配方 '<arg:1>' 缺少必需的 'result' 参数</yellow>"
warning.config.recipe.result.missing_id: "<yellow>在文件 <arg:0> 发现问题 - 配方 '<arg:1>' 的结果缺少必需的 'id' 参数</yellow>"

View File

@@ -5,8 +5,8 @@ import net.momirealms.craftengine.core.item.modifier.ItemDataModifier;
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
import net.momirealms.craftengine.core.plugin.context.event.EventTrigger;
import net.momirealms.craftengine.core.plugin.context.function.Function;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.UniqueKey;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
@@ -15,7 +15,7 @@ import java.util.Map;
import java.util.Optional;
public abstract class AbstractCustomItem<I> implements CustomItem<I> {
protected final Holder<Key> id;
protected final UniqueKey id;
protected final Key material;
protected final Key clientBoundMaterial;
protected final ItemDataModifier<I>[] modifiers;
@@ -25,7 +25,7 @@ public abstract class AbstractCustomItem<I> implements CustomItem<I> {
protected final Map<EventTrigger, List<Function<PlayerOptionalContext>>> events;
@SuppressWarnings("unchecked")
public AbstractCustomItem(Holder<Key> id, Key material, Key clientBoundMaterial,
public AbstractCustomItem(UniqueKey id, Key material, Key clientBoundMaterial,
List<ItemBehavior> behaviors,
List<ItemDataModifier<I>> modifiers,
List<ItemDataModifier<I>> clientBoundModifiers,
@@ -52,11 +52,11 @@ public abstract class AbstractCustomItem<I> implements CustomItem<I> {
@Override
public Key id() {
return this.id.value();
return this.id.key();
}
@Override
public Holder<Key> idHolder() {
public UniqueKey uniqueId() {
return this.id;
}

View File

@@ -25,9 +25,6 @@ import net.momirealms.craftengine.core.plugin.context.text.TextProvider;
import net.momirealms.craftengine.core.plugin.context.text.TextProviders;
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
import net.momirealms.craftengine.core.plugin.locale.TranslationManager;
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.registry.WritableRegistry;
import net.momirealms.craftengine.core.util.*;
import org.incendo.cloud.suggestion.Suggestion;
import org.incendo.cloud.type.Either;
@@ -42,14 +39,14 @@ import java.util.stream.Stream;
public abstract class AbstractItemManager<I> extends AbstractModelGenerator implements ItemManager<I> {
protected static final Map<Key, List<ItemBehavior>> VANILLA_ITEM_EXTRA_BEHAVIORS = new HashMap<>();
protected static final Set<Key> VANILLA_ITEMS = new HashSet<>(1024);
protected static final Map<Key, List<Holder<Key>>> VANILLA_ITEM_TAGS = new HashMap<>();
protected static final Map<Key, List<UniqueKey>> VANILLA_ITEM_TAGS = new HashMap<>();
private final ItemParser itemParser;
private final EquipmentParser equipmentParser;
protected final Map<String, ExternalItemProvider<I>> externalItemProviders = new HashMap<>();
protected final Map<String, Function<Object, ItemDataModifier<I>>> dataFunctions = new HashMap<>();
protected final Map<Key, CustomItem<I>> customItems = new HashMap<>();
protected final Map<Key, List<Holder<Key>>> customItemTags = new HashMap<>();
protected final Map<Key, List<UniqueKey>> customItemTags = new HashMap<>();
protected final Map<Key, Map<Integer, Key>> cmdConflictChecker = new HashMap<>();
protected final Map<Key, ModernItemModel> modernItemModels1_21_4 = new HashMap<>();
protected final Map<Key, TreeSet<LegacyOverridesModel>> modernItemModels1_21_2 = new HashMap<>();
@@ -157,19 +154,19 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
// tags
Set<Key> tags = customItem.settings().tags();
for (Key tag : tags) {
this.customItemTags.computeIfAbsent(tag, k -> new ArrayList<>()).add(customItem.idHolder());
this.customItemTags.computeIfAbsent(tag, k -> new ArrayList<>()).add(customItem.uniqueId());
}
return true;
}
@Override
public List<Holder<Key>> tagToItems(Key tag) {
List<Holder<Key>> items = new ArrayList<>();
List<Holder<Key>> holders = VANILLA_ITEM_TAGS.get(tag);
public List<UniqueKey> tagToItems(Key tag) {
List<UniqueKey> items = new ArrayList<>();
List<UniqueKey> holders = VANILLA_ITEM_TAGS.get(tag);
if (holders != null) {
items.addAll(holders);
}
List<Holder<Key>> customItems = this.customItemTags.get(tag);
List<UniqueKey> customItems = this.customItemTags.get(tag);
if (customItems != null) {
items.addAll(customItems);
}
@@ -177,12 +174,12 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
}
@Override
public List<Holder<Key>> tagToVanillaItems(Key tag) {
public List<UniqueKey> tagToVanillaItems(Key tag) {
return Collections.unmodifiableList(VANILLA_ITEM_TAGS.getOrDefault(tag, List.of()));
}
@Override
public List<Holder<Key>> tagToCustomItems(Key tag) {
public List<UniqueKey> tagToCustomItems(Key tag) {
return Collections.unmodifiableList(this.customItemTags.getOrDefault(tag, List.of()));
}
@@ -253,7 +250,7 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
return VANILLA_ITEMS.contains(item);
}
protected abstract CustomItem.Builder<I> createPlatformItemBuilder(Holder<Key> id, Key material, Key clientBoundMaterial);
protected abstract CustomItem.Builder<I> createPlatformItemBuilder(UniqueKey id, Key material, Key clientBoundMaterial);
protected abstract void registerArmorTrimPattern(Collection<Key> equipments);
@@ -327,11 +324,9 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
throw new LocalizedResourceConfigException("warning.config.item.duplicate");
}
// register for recipes
Holder.Reference<Key> holder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(id)
.orElseGet(() -> ((WritableRegistry<Key>) BuiltInRegistries.OPTIMIZED_ITEM_ID)
.register(ResourceKey.create(BuiltInRegistries.OPTIMIZED_ITEM_ID.key().location(), id), id));
UniqueKey uniqueId = UniqueKey.create(id);
// register for recipes
boolean isVanillaItem = isVanillaItem(id);
Key material = Key.from(isVanillaItem ? id.value() : ResourceConfigUtils.requireNonEmptyStringOrThrow(section.get("material"), "warning.config.item.missing_material").toLowerCase(Locale.ENGLISH));
Key clientBoundMaterial = section.containsKey("client-bound-material") ? Key.from(section.get("client-bound-material").toString().toLowerCase(Locale.ENGLISH)) : material;
@@ -346,7 +341,7 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
Key itemModelKey = null;
CustomItem.Builder<I> itemBuilder = createPlatformItemBuilder(holder, material, clientBoundMaterial);
CustomItem.Builder<I> itemBuilder = createPlatformItemBuilder(uniqueId, material, clientBoundMaterial);
boolean hasItemModelSection = section.containsKey("item-model");
// To get at least one model provider

View File

@@ -6,8 +6,8 @@ import net.momirealms.craftengine.core.item.modifier.ItemDataModifier;
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
import net.momirealms.craftengine.core.plugin.context.event.EventTrigger;
import net.momirealms.craftengine.core.plugin.context.function.Function;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.UniqueKey;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -17,7 +17,7 @@ public interface CustomItem<I> extends BuildableItem<I> {
Key id();
Holder<Key> idHolder();
UniqueKey uniqueId();
Key material();
@@ -47,7 +47,7 @@ public interface CustomItem<I> extends BuildableItem<I> {
List<ItemBehavior> behaviors();
interface Builder<I> {
Builder<I> id(Holder<Key> id);
Builder<I> id(UniqueKey id);
Builder<I> clientBoundMaterial(Key clientBoundMaterialKey);

View File

@@ -9,9 +9,9 @@ import net.momirealms.craftengine.core.pack.model.ModernItemModel;
import net.momirealms.craftengine.core.pack.model.generation.ModelGenerator;
import net.momirealms.craftengine.core.plugin.Manageable;
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.FriendlyByteBuf;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.UniqueKey;
import org.incendo.cloud.suggestion.Suggestion;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -82,11 +82,11 @@ public interface ItemManager<T> extends Manageable, ModelGenerator {
boolean addCustomItem(CustomItem<T> customItem);
List<Holder<Key>> tagToItems(Key tag);
List<UniqueKey> tagToItems(Key tag);
List<Holder<Key>> tagToVanillaItems(Key tag);
List<UniqueKey> tagToVanillaItems(Key tag);
List<Holder<Key>> tagToCustomItems(Key tag);
List<UniqueKey> tagToCustomItems(Key tag);
int fuelTime(T itemStack);

View File

@@ -2,12 +2,7 @@ package net.momirealms.craftengine.core.item.recipe;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.EnumUtils;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.MiscUtils;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import net.momirealms.craftengine.core.util.*;
import java.util.*;
@@ -21,14 +16,13 @@ public abstract class AbstractRecipeFactory<T> implements RecipeFactory<T> {
return MiscUtils.castToMap(getIngredientOrThrow(arguments), true);
}
protected Set<Holder<Key>> ingredientHolders(Map<String, Object> arguments) {
Set<Holder<Key>> holders = new HashSet<>();
protected Set<UniqueKey> ingredientHolders(Map<String, Object> arguments) {
Set<UniqueKey> holders = new HashSet<>();
for (String item : ingredients(arguments)) {
if (item.charAt(0) == '#') {
holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1))));
} else {
holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow(
() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", item)));
holders.add(UniqueKey.create(Key.of(item)));
}
}
return holders;

View File

@@ -11,8 +11,8 @@ import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.config.Config;
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.UniqueKey;
import net.momirealms.craftengine.core.util.VersionHelper;
import org.jetbrains.annotations.Nullable;
@@ -140,8 +140,8 @@ public abstract class AbstractRecipeManager<T> implements RecipeManager<T> {
this.byResult.computeIfAbsent(recipe.result().item().id(), k -> new ArrayList<>()).add(recipe);
HashSet<Key> usedKeys = new HashSet<>();
for (Ingredient<T> ingredient : recipe.ingredientsInUse()) {
for (Holder<Key> holder : ingredient.items()) {
Key key = holder.value();
for (UniqueKey holder : ingredient.items()) {
Key key = holder.key();
if (usedKeys.add(key)) {
this.byIngredient.computeIfAbsent(key, k -> new ArrayList<>()).add(recipe);
}

View File

@@ -1,8 +1,8 @@
package net.momirealms.craftengine.core.item.recipe;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import net.momirealms.craftengine.core.util.UniqueKey;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
@@ -28,7 +28,7 @@ public class CustomBlastingRecipe<T> extends CustomCookingRecipe<T> {
String group = arguments.containsKey("group") ? arguments.get("group").toString() : null;
int cookingTime = ResourceConfigUtils.getAsInt(arguments.getOrDefault("time", 80), "time");
float experience = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("experience", 0.0f), "experience");
Set<Holder<Key>> holders = ingredientHolders(arguments);
Set<UniqueKey> holders = ingredientHolders(arguments);
return new CustomBlastingRecipe(id, cookingRecipeCategory(arguments), group, Ingredient.of(holders), cookingTime, experience, parseResult(arguments));
}
}

View File

@@ -1,8 +1,8 @@
package net.momirealms.craftengine.core.item.recipe;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import net.momirealms.craftengine.core.util.UniqueKey;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
@@ -28,7 +28,7 @@ public class CustomCampfireRecipe<T> extends CustomCookingRecipe<T> {
String group = arguments.containsKey("group") ? arguments.get("group").toString() : null;
int cookingTime = ResourceConfigUtils.getAsInt(arguments.getOrDefault("time", 80), "time");
float experience = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("experience", 0.0f), "experience");
Set<Holder<Key>> holders = ingredientHolders(arguments);
Set<UniqueKey> holders = ingredientHolders(arguments);
return new CustomCampfireRecipe(id, cookingRecipeCategory(arguments), group, Ingredient.of(holders), cookingTime, experience, parseResult(arguments));
}
}

View File

@@ -4,10 +4,9 @@ import net.momirealms.craftengine.core.item.recipe.input.CraftingInput;
import net.momirealms.craftengine.core.item.recipe.input.RecipeInput;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.MiscUtils;
import net.momirealms.craftengine.core.util.UniqueKey;
import org.jetbrains.annotations.NotNull;
import java.util.*;
@@ -156,13 +155,12 @@ public class CustomShapedRecipe<T> extends CustomCraftingTableRecipe<T> {
}
char ch = key.charAt(0);
List<String> items = MiscUtils.getAsStringList(entry.getValue());
Set<Holder<Key>> holders = new HashSet<>();
Set<UniqueKey> holders = new HashSet<>();
for (String item : items) {
if (item.charAt(0) == '#') {
holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1))));
} else {
holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow(
() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", item)));
holders.add(UniqueKey.create(Key.of(item)));
}
}
ingredients.put(ch, Ingredient.of(holders));

View File

@@ -3,11 +3,9 @@ package net.momirealms.craftengine.core.item.recipe;
import net.momirealms.craftengine.core.item.recipe.input.CraftingInput;
import net.momirealms.craftengine.core.item.recipe.input.RecipeInput;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.MiscUtils;
import net.momirealms.craftengine.core.util.UniqueKey;
import org.jetbrains.annotations.NotNull;
import java.util.*;
@@ -64,13 +62,12 @@ public class CustomShapelessRecipe<T> extends CustomCraftingTableRecipe<T> {
if (ingredientsObject instanceof Map<?,?> map) {
for (Map.Entry<String, Object> entry : (MiscUtils.castToMap(map, false)).entrySet()) {
List<String> items = MiscUtils.getAsStringList(entry.getValue());
Set<Holder<Key>> holders = new HashSet<>();
Set<UniqueKey> holders = new HashSet<>();
for (String item : items) {
if (item.charAt(0) == '#') {
holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1))));
} else {
holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow(
() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", item)));
holders.add(UniqueKey.create(Key.of(item)));
}
}
ingredients.add(Ingredient.of(holders));
@@ -78,36 +75,33 @@ public class CustomShapelessRecipe<T> extends CustomCraftingTableRecipe<T> {
} else if (ingredientsObject instanceof List<?> list) {
for (Object obj : list) {
if (obj instanceof List<?> inner) {
Set<Holder<Key>> holders = new HashSet<>();
Set<UniqueKey> holders = new HashSet<>();
for (String item : MiscUtils.getAsStringList(inner)) {
if (item.charAt(0) == '#') {
holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1))));
} else {
holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow(
() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", item)));
holders.add(UniqueKey.create(Key.of(item)));
}
}
ingredients.add(Ingredient.of(holders));
} else {
String item = obj.toString();
Set<Holder<Key>> holders = new HashSet<>();
Set<UniqueKey> holders = new HashSet<>();
if (item.charAt(0) == '#') {
holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1))));
} else {
holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow(
() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", item)));
holders.add(UniqueKey.create(Key.of(item)));
}
ingredients.add(Ingredient.of(holders));
}
}
} else {
String item = ingredientsObject.toString();
Set<Holder<Key>> holders = new HashSet<>();
Set<UniqueKey> holders = new HashSet<>();
if (item.charAt(0) == '#') {
holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1))));
} else {
holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow(
() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", item)));
holders.add(UniqueKey.create(Key.of(item)));
}
ingredients.add(Ingredient.of(holders));
}

View File

@@ -1,8 +1,8 @@
package net.momirealms.craftengine.core.item.recipe;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import net.momirealms.craftengine.core.util.UniqueKey;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
@@ -28,7 +28,7 @@ public class CustomSmeltingRecipe<T> extends CustomCookingRecipe<T> {
String group = arguments.containsKey("group") ? arguments.get("group").toString() : null;
int cookingTime = ResourceConfigUtils.getAsInt(arguments.getOrDefault("time", 80), "time");
float experience = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("experience", 0.0f), "experience");
Set<Holder<Key>> holders = ingredientHolders(arguments);
Set<UniqueKey> holders = ingredientHolders(arguments);
return new CustomSmeltingRecipe(id, cookingRecipeCategory(arguments), group, Ingredient.of(holders), cookingTime, experience, parseResult(arguments));
}
}

View File

@@ -7,7 +7,6 @@ import net.momirealms.craftengine.core.item.recipe.input.SmithingInput;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.registry.Registries;
import net.momirealms.craftengine.core.registry.WritableRegistry;
import net.momirealms.craftengine.core.util.*;
@@ -145,13 +144,12 @@ public class CustomSmithingTransformRecipe<T> implements Recipe<T> {
}
private Ingredient<A> toIngredient(List<String> items) {
Set<Holder<Key>> holders = new HashSet<>();
Set<UniqueKey> holders = new HashSet<>();
for (String item : items) {
if (item.charAt(0) == '#') {
holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1))));
} else {
holders.add(BuiltInRegistries.OPTIMIZED_ITEM_ID.get(Key.of(item)).orElseThrow(
() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", item)));
holders.add(UniqueKey.create(Key.of(item)));
}
}
return holders.isEmpty() ? null : Ingredient.of(holders);

View File

@@ -1,8 +1,8 @@
package net.momirealms.craftengine.core.item.recipe;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import net.momirealms.craftengine.core.util.UniqueKey;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
@@ -28,7 +28,7 @@ public class CustomSmokingRecipe<T> extends CustomCookingRecipe<T> {
String group = arguments.containsKey("group") ? arguments.get("group").toString() : null;
int cookingTime = ResourceConfigUtils.getAsInt(arguments.getOrDefault("time", 80), "time");
float experience = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("experience", 0.0f), "experience");
Set<Holder<Key>> holders = ingredientHolders(arguments);
Set<UniqueKey> holders = ingredientHolders(arguments);
return new CustomSmokingRecipe(id, cookingRecipeCategory(arguments), group, Ingredient.of(holders), cookingTime, experience, parseResult(arguments));
}
}

View File

@@ -2,8 +2,8 @@ package net.momirealms.craftengine.core.item.recipe;
import net.momirealms.craftengine.core.item.recipe.input.RecipeInput;
import net.momirealms.craftengine.core.item.recipe.input.SingleItemInput;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.UniqueKey;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -45,7 +45,7 @@ public class CustomStoneCuttingRecipe<T> extends AbstractGroupedRecipe<T> {
@Override
public Recipe<A> create(Key id, Map<String, Object> arguments) {
String group = arguments.containsKey("group") ? arguments.get("group").toString() : null;
Set<Holder<Key>> holders = ingredientHolders(arguments);
Set<UniqueKey> holders = ingredientHolders(arguments);
return new CustomStoneCuttingRecipe<>(id, group, Ingredient.of(holders), parseResult(arguments));
}
}

View File

@@ -1,15 +1,14 @@
package net.momirealms.craftengine.core.item.recipe;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.UniqueKey;
import java.util.*;
import java.util.function.Predicate;
public class Ingredient<T> implements Predicate<OptimizedIDItem<T>>, StackedContents.IngredientInfo<Holder<Key>> {
private final List<Holder<Key>> items;
public class Ingredient<T> implements Predicate<OptimizedIDItem<T>>, StackedContents.IngredientInfo<UniqueKey> {
private final List<UniqueKey> items;
public Ingredient(List<Holder<Key>> items) {
public Ingredient(List<UniqueKey> items) {
this.items = items;
}
@@ -18,17 +17,17 @@ public class Ingredient<T> implements Predicate<OptimizedIDItem<T>>, StackedCont
.orElseGet(stack::isEmpty);
}
public static <T> Ingredient<T> of(List<Holder<Key>> items) {
public static <T> Ingredient<T> of(List<UniqueKey> items) {
return new Ingredient<>(items);
}
public static <T> Ingredient<T> of(Set<Holder<Key>> items) {
public static <T> Ingredient<T> of(Set<UniqueKey> items) {
return new Ingredient<>(new ArrayList<>(items));
}
@Override
public boolean test(OptimizedIDItem<T> optimizedIDItem) {
for (Holder<Key> item : this.items()) {
for (UniqueKey item : this.items()) {
if (optimizedIDItem.is(item)) {
return true;
}
@@ -36,14 +35,14 @@ public class Ingredient<T> implements Predicate<OptimizedIDItem<T>>, StackedCont
return false;
}
public List<Holder<Key>> items() {
public List<UniqueKey> items() {
return this.items;
}
@Override
public String toString() {
StringJoiner joiner = new StringJoiner(", ");
for (Holder<Key> item : this.items()) {
for (UniqueKey item : this.items()) {
joiner.add(item.toString());
}
return "Ingredient: [" + joiner + "]";
@@ -54,7 +53,7 @@ public class Ingredient<T> implements Predicate<OptimizedIDItem<T>>, StackedCont
}
@Override
public boolean acceptsItem(Holder<Key> entry) {
public boolean acceptsItem(UniqueKey entry) {
return this.items.contains(entry);
}
}

View File

@@ -0,0 +1,13 @@
package net.momirealms.craftengine.core.item.recipe;
public class InvalidRecipeIngredientException extends RuntimeException {
private final String ingredient;
public InvalidRecipeIngredientException(String ingredient) {
this.ingredient = ingredient;
}
public String ingredient() {
return ingredient;
}
}

View File

@@ -1,37 +1,36 @@
package net.momirealms.craftengine.core.item.recipe;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.UniqueKey;
public class OptimizedIDItem<T> {
private final T rawItem;
private final Holder<Key> idHolder;
private final UniqueKey uniqueId;
public OptimizedIDItem(Holder<Key> idHolder, T rawItem) {
this.idHolder = idHolder;
public OptimizedIDItem(UniqueKey uniqueId, T rawItem) {
this.uniqueId = uniqueId;
this.rawItem = rawItem;
}
public Holder<Key> id() {
return idHolder;
public UniqueKey id() {
return uniqueId;
}
public T rawItem() {
return rawItem;
}
public boolean is(Holder<Key> id) {
return idHolder == id;
public boolean is(UniqueKey id) {
return uniqueId == id;
}
public boolean isEmpty() {
return idHolder == null;
return uniqueId == null;
}
@Override
public String toString() {
return "OptimizedIDItem{" +
"idHolder=" + idHolder +
"uniqueId=" + uniqueId +
'}';
}
}

View File

@@ -22,7 +22,7 @@ public interface RecipeFactory<T> {
int count = ResourceConfigUtils.getAsInt(resultMap.getOrDefault("count", 1), "count");
return new CustomRecipeResult(
CraftEngine.instance().itemManager().getBuildableItem(Key.of(id)).orElseThrow(
() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_item", id)),
() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_result", id)),
count
);
}

View File

@@ -1,12 +1,11 @@
package net.momirealms.craftengine.core.item.recipe;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.UniqueKey;
import java.util.List;
public class RecipeFinder {
private final StackedContents<Holder<Key>> stackedContents = new StackedContents<>();
private final StackedContents<UniqueKey> stackedContents = new StackedContents<>();
public <T> void addInput(OptimizedIDItem<T> item) {
if (!item.isEmpty()) {
@@ -19,7 +18,7 @@ public class RecipeFinder {
return !placementInfo.isImpossibleToPlace() && canCraft(placementInfo.ingredients());
}
private boolean canCraft(List<? extends StackedContents.IngredientInfo<Holder<Key>>> rawIngredients) {
private boolean canCraft(List<? extends StackedContents.IngredientInfo<UniqueKey>> rawIngredients) {
return this.stackedContents.tryPick(rawIngredients);
}
}

View File

@@ -16,11 +16,7 @@ import net.momirealms.craftengine.core.plugin.context.ContextHolder;
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
import net.momirealms.craftengine.core.plugin.gui.*;
import net.momirealms.craftengine.core.plugin.gui.Ingredient;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.AdventureHelper;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.MiscUtils;
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import net.momirealms.craftengine.core.util.*;
import java.nio.file.Path;
import java.util.*;
@@ -506,8 +502,8 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager {
List<Item<?>> templates = new ArrayList<>();
Optional.ofNullable(recipe.template()).ifPresent(it -> {
for (Holder<Key> in : it.items()) {
templates.add(this.plugin.itemManager().createWrappedItem(in.value(), player));
for (UniqueKey in : it.items()) {
templates.add(this.plugin.itemManager().createWrappedItem(in.key(), player));
}
});
layout.addIngredient('A', templates.isEmpty() ? GuiElement.EMPTY : GuiElement.recipeIngredient(templates, (e, c) -> {
@@ -539,8 +535,8 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager {
List<Item<?>> bases = new ArrayList<>();
Optional.ofNullable(recipe.base()).ifPresent(it -> {
for (Holder<Key> in : it.items()) {
bases.add(this.plugin.itemManager().createWrappedItem(in.value(), player));
for (UniqueKey in : it.items()) {
bases.add(this.plugin.itemManager().createWrappedItem(in.key(), player));
}
});
layout.addIngredient('B', bases.isEmpty() ? GuiElement.EMPTY : GuiElement.recipeIngredient(bases, (e, c) -> {
@@ -572,8 +568,8 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager {
List<Item<?>> additions = new ArrayList<>();
Optional.ofNullable(recipe.addition()).ifPresent(it -> {
for (Holder<Key> in : it.items()) {
additions.add(this.plugin.itemManager().createWrappedItem(in.value(), player));
for (UniqueKey in : it.items()) {
additions.add(this.plugin.itemManager().createWrappedItem(in.key(), player));
}
});
layout.addIngredient('C', additions.isEmpty() ? GuiElement.EMPTY : GuiElement.recipeIngredient(additions, (e, c) -> {
@@ -623,8 +619,8 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager {
List<Item<?>> ingredients = new ArrayList<>();
net.momirealms.craftengine.core.item.recipe.Ingredient<Object> ingredient = recipe.ingredient();
for (Holder<Key> in : ingredient.items()) {
ingredients.add(this.plugin.itemManager().createWrappedItem(in.value(), player));
for (UniqueKey in : ingredient.items()) {
ingredients.add(this.plugin.itemManager().createWrappedItem(in.key(), player));
}
GuiLayout layout = new GuiLayout(
" ",
@@ -756,8 +752,8 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager {
List<Item<?>> ingredients = new ArrayList<>();
net.momirealms.craftengine.core.item.recipe.Ingredient<Object> ingredient = recipe.ingredient();
for (Holder<Key> in : ingredient.items()) {
ingredients.add(this.plugin.itemManager().createWrappedItem(in.value(), player));
for (UniqueKey in : ingredient.items()) {
ingredients.add(this.plugin.itemManager().createWrappedItem(in.key(), player));
}
GuiLayout layout = new GuiLayout(
" ",
@@ -1001,8 +997,8 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager {
layout.addIngredient(currentChar, Ingredient.EMPTY);
} else {
List<Item<?>> ingredients = new ArrayList<>();
for (Holder<Key> in : ingredient.items()) {
ingredients.add(this.plugin.itemManager().createWrappedItem(in.value(), player));
for (UniqueKey in : ingredient.items()) {
ingredients.add(this.plugin.itemManager().createWrappedItem(in.key(), player));
}
layout.addIngredient(currentChar, GuiElement.recipeIngredient(ingredients, (e, c) -> {
c.cancel();
@@ -1044,8 +1040,8 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager {
char currentChar = (char) (start + x + y * 3);
if (i < ingredients.size()) {
List<Item<?>> ingredientItems = new ArrayList<>();
for (Holder<Key> in : ingredients.get(i).items()) {
ingredientItems.add(this.plugin.itemManager().createWrappedItem(in.value(), player));
for (UniqueKey in : ingredients.get(i).items()) {
ingredientItems.add(this.plugin.itemManager().createWrappedItem(in.key(), player));
}
layout.addIngredient(currentChar, GuiElement.recipeIngredient(ingredientItems, (e, c) -> {
c.cancel();

View File

@@ -36,12 +36,10 @@ import net.momirealms.craftengine.core.plugin.context.condition.ConditionFactory
import net.momirealms.craftengine.core.plugin.context.function.FunctionFactory;
import net.momirealms.craftengine.core.plugin.context.number.NumberProviderFactory;
import net.momirealms.craftengine.core.plugin.context.selector.PlayerSelectorFactory;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.ResourceKey;
public class BuiltInRegistries {
public static final Registry<CustomBlock> BLOCK = createDynamicBoundRegistry(Registries.BLOCK);
public static final Registry<Key> OPTIMIZED_ITEM_ID = createConstantBoundRegistry(Registries.OPTIMIZED_ITEM_ID);
public static final Registry<BlockBehaviorFactory> BLOCK_BEHAVIOR_FACTORY = createConstantBoundRegistry(Registries.BLOCK_BEHAVIOR_FACTORY);
public static final Registry<ItemBehaviorFactory> ITEM_BEHAVIOR_FACTORY = createConstantBoundRegistry(Registries.ITEM_BEHAVIOR_FACTORY);
public static final Registry<PropertyFactory> PROPERTY_FACTORY = createConstantBoundRegistry(Registries.PROPERTY_FACTORY);

View File

@@ -0,0 +1,28 @@
package net.momirealms.craftengine.core.util;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
public final class UniqueKey {
private static final Map<Key, UniqueKey> CACHE = new HashMap<>(4096, 0.5f);
private final Key key;
private UniqueKey(Key key) {
this.key = key;
}
public static UniqueKey create(Key key) {
return CACHE.computeIfAbsent(key, UniqueKey::new);
}
@Nullable
public static UniqueKey getCached(Key key) {
return CACHE.get(key);
}
public Key key() {
return key;
}
}