mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-27 02:49:15 +00:00
trim配方(未测试)
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package net.momirealms.craftengine.bukkit.util;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryEvent;
|
||||
import org.bukkit.event.inventory.PrepareAnvilEvent;
|
||||
import org.bukkit.inventory.AnvilInventory;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
@@ -65,4 +66,8 @@ public class LegacyInventoryUtils {
|
||||
public static void openWorkbench(Player player) {
|
||||
player.openWorkbench(null, true);
|
||||
}
|
||||
|
||||
public static Player getPlayerFromInventoryEvent(InventoryEvent event) {
|
||||
return (Player) event.getView().getPlayer();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@ import io.papermc.paper.event.player.AsyncChatCommandDecorateEvent;
|
||||
import io.papermc.paper.event.player.AsyncChatDecorateEvent;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.bukkit.CraftBukkitReflections;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.paper.PaperReflections;
|
||||
import net.momirealms.craftengine.bukkit.util.ComponentUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.InventoryUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.ItemStackUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.LegacyInventoryUtils;
|
||||
import net.momirealms.craftengine.core.font.*;
|
||||
@@ -132,14 +132,7 @@ public class BukkitFontManager extends AbstractFontManager implements Listener {
|
||||
}
|
||||
ItemStack result = event.getResult();
|
||||
if (ItemStackUtils.isEmpty(result)) return;
|
||||
Player player;
|
||||
try {
|
||||
player = (Player) CraftBukkitReflections.method$InventoryView$getPlayer.invoke(VersionHelper.isOrAbove1_21() ? event.getView() : LegacyInventoryUtils.getView(event));
|
||||
} catch (ReflectiveOperationException e) {
|
||||
this.plugin.logger().warn("Failed to get inventory viewer", e);
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = InventoryUtils.getPlayerFromInventoryEvent(event);
|
||||
String renameText;
|
||||
if (VersionHelper.isOrAbove1_21_2()) {
|
||||
AnvilView anvilView = event.getView();
|
||||
|
||||
@@ -14,13 +14,13 @@ import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBuiltInRegistries;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MItems;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistries;
|
||||
import net.momirealms.craftengine.bukkit.util.ItemStackUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.KeyUtils;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
import net.momirealms.craftengine.core.item.*;
|
||||
import net.momirealms.craftengine.core.item.modifier.IdModifier;
|
||||
import net.momirealms.craftengine.core.item.recipe.UniqueIdItem;
|
||||
import net.momirealms.craftengine.core.pack.AbstractPackManager;
|
||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
|
||||
@@ -54,8 +54,8 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
||||
private final ArmorEventListener armorEventListener;
|
||||
private final NetworkItemHandler<ItemStack> networkItemHandler;
|
||||
private final Object bedrockItemHolder;
|
||||
private final Item<ItemStack> empty;
|
||||
private final ItemStack emptyStack;
|
||||
private final Item<ItemStack> emptyItem;
|
||||
private final UniqueIdItem<ItemStack> emptyUniqueItem;
|
||||
private Set<Key> lastRegisteredPatterns = Set.of();
|
||||
|
||||
public BukkitItemManager(BukkitCraftEngine plugin) {
|
||||
@@ -71,8 +71,15 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
||||
this.bedrockItemHolder = FastNMS.INSTANCE.method$Registry$getHolderByResourceKey(MBuiltInRegistries.ITEM, FastNMS.INSTANCE.method$ResourceKey$create(MRegistries.ITEM, KeyUtils.toResourceLocation(Key.of("minecraft:bedrock")))).get();;
|
||||
this.registerCustomTrimMaterial();
|
||||
this.loadLastRegisteredPatterns();
|
||||
this.empty = this.wrap(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(CoreReflections.instance$ItemStack$EMPTY));
|
||||
this.emptyStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(FastNMS.INSTANCE.constructor$ItemStack(MItems.AIR, 1));
|
||||
|
||||
ItemStack emptyStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(CoreReflections.instance$ItemStack$EMPTY);
|
||||
this.emptyItem = this.wrap(emptyStack);
|
||||
this.emptyUniqueItem = new UniqueIdItem<>(UniqueKey.AIR, this.emptyItem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UniqueIdItem<ItemStack> uniqueEmptyItem() {
|
||||
return this.emptyUniqueItem;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -104,18 +111,20 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
||||
|
||||
@Override
|
||||
public Item<ItemStack> s2c(Item<ItemStack> item, Player player) {
|
||||
if (item.isEmpty()) return item;
|
||||
return this.networkItemHandler.s2c(item, player).orElse(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<ItemStack> c2s(Item<ItemStack> item) {
|
||||
if (item.isEmpty()) return item;
|
||||
return this.networkItemHandler.c2s(item).orElse(item);
|
||||
}
|
||||
|
||||
public Optional<ItemStack> s2c(ItemStack itemStack, Player player) {
|
||||
try {
|
||||
Item<ItemStack> wrapped = wrap(itemStack);
|
||||
if (wrapped == null) return Optional.empty();
|
||||
if (wrapped.isEmpty()) return Optional.empty();
|
||||
return this.networkItemHandler.s2c(wrapped, player).map(Item::getItem);
|
||||
} catch (Throwable e) {
|
||||
Debugger.ITEM.warn(() -> "Failed to handle s2c items.", e);
|
||||
@@ -126,7 +135,7 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
||||
public Optional<ItemStack> c2s(ItemStack itemStack) {
|
||||
try {
|
||||
Item<ItemStack> wrapped = wrap(itemStack);
|
||||
if (wrapped == null) return Optional.empty();
|
||||
if (wrapped.isEmpty()) return Optional.empty();
|
||||
return this.networkItemHandler.c2s(wrapped).map(Item::getItem);
|
||||
} catch (Throwable e) {
|
||||
Debugger.COMMON.warn(() -> "Failed to handle c2s items.", e);
|
||||
@@ -332,7 +341,7 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
||||
|
||||
@Override
|
||||
public @NotNull Item<ItemStack> wrap(ItemStack itemStack) {
|
||||
if (itemStack == null) return this.empty;
|
||||
if (itemStack == null) return this.emptyItem;
|
||||
return this.factory.wrap(itemStack);
|
||||
}
|
||||
|
||||
@@ -386,4 +395,45 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
||||
plugin.logger().warn("Failed to init vanilla items", e);
|
||||
}
|
||||
}
|
||||
|
||||
// 1.20-1.21.4 template 不为空
|
||||
// 1.21.5+ pattern 不为空
|
||||
@Override
|
||||
public Item<ItemStack> applyTrim(Item<ItemStack> base, Item<ItemStack> addition, Item<ItemStack> template, Key pattern) {
|
||||
Optional<?> optionalMaterial = FastNMS.INSTANCE.method$TrimMaterials$getFromIngredient(addition.getLiteralObject());
|
||||
Optional<?> optionalPattern = VersionHelper.isOrAbove1_21_5() ?
|
||||
FastNMS.INSTANCE.method$Registry$getHolderByResourceLocation(FastNMS.INSTANCE.method$RegistryAccess$lookupOrThrow(FastNMS.INSTANCE.registryAccess(), MRegistries.TRIM_MATERIAL), KeyUtils.toResourceLocation(pattern)) :
|
||||
FastNMS.INSTANCE.method$TrimPatterns$getFromTemplate(template.getLiteralObject());
|
||||
if (optionalMaterial.isPresent() && optionalPattern.isPresent()) {
|
||||
Object armorTrim = FastNMS.INSTANCE.constructor$ArmorTrim(optionalMaterial.get(), optionalPattern.get());
|
||||
Object previousTrim;
|
||||
if (VersionHelper.isOrAbove1_20_5()) {
|
||||
previousTrim = base.getExactComponent(ComponentKeys.TRIM);
|
||||
} else {
|
||||
try {
|
||||
previousTrim = VersionHelper.isOrAbove1_20_2() ?
|
||||
((Optional<?>) CoreReflections.method$ArmorTrim$getTrim.invoke(null, FastNMS.INSTANCE.registryAccess(), base.getLiteralObject(), true)).orElse(null) :
|
||||
((Optional<?>) CoreReflections.method$ArmorTrim$getTrim.invoke(null, FastNMS.INSTANCE.registryAccess(), base.getLiteralObject())).orElse(null);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
this.plugin.logger().warn("Failed to get armor trim", e);
|
||||
return this.emptyItem;
|
||||
}
|
||||
}
|
||||
if (armorTrim.equals(previousTrim)) {
|
||||
return this.emptyItem;
|
||||
}
|
||||
Item<ItemStack> newItem = base.copyWithCount(1);
|
||||
if (VersionHelper.isOrAbove1_20_5()) {
|
||||
newItem.setExactComponent(ComponentKeys.TRIM, armorTrim);
|
||||
} else {
|
||||
try {
|
||||
CoreReflections.method$ArmorTrim$setTrim.invoke(null, FastNMS.INSTANCE.registryAccess(), base.getLiteralObject(), armorTrim);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
this.plugin.logger().warn("Failed to set armor trim", e);
|
||||
return this.emptyItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.emptyItem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ public class LegacyItemWrapper implements ItemWrapper<ItemStack> {
|
||||
getItem().setAmount(amount);
|
||||
}
|
||||
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
public Object getExactTag(Object... path) {
|
||||
Object compoundTag = FastNMS.INSTANCE.method$ItemStack$getTag(this.nmsStack);
|
||||
if (compoundTag == null) return null;
|
||||
|
||||
@@ -45,7 +45,7 @@ public final class LegacyNetworkItemHandler implements NetworkItemHandler<ItemSt
|
||||
return Optional.of(wrapped);
|
||||
}
|
||||
}
|
||||
CompoundTag networkData = (CompoundTag) wrapped.getNBTTag(NETWORK_ITEM_TAG);
|
||||
CompoundTag networkData = (CompoundTag) wrapped.getTag(NETWORK_ITEM_TAG);
|
||||
if (networkData == null) return Optional.empty();
|
||||
wrapped.removeTag(NETWORK_ITEM_TAG);
|
||||
for (Map.Entry<String, Tag> entry : networkData.entrySet()) {
|
||||
@@ -74,7 +74,7 @@ public final class LegacyNetworkItemHandler implements NetworkItemHandler<ItemSt
|
||||
return new OtherItem(wrapped, hasDifferentMaterial).process();
|
||||
} else {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
Tag argumentTag = wrapped.getNBTTag(ArgumentModifier.ARGUMENTS_TAG);
|
||||
Tag argumentTag = wrapped.getTag(ArgumentModifier.ARGUMENTS_TAG);
|
||||
ItemBuildContext context;
|
||||
if (argumentTag instanceof CompoundTag arguments) {
|
||||
ContextHolder.Builder builder = ContextHolder.builder();
|
||||
|
||||
@@ -146,6 +146,11 @@ public abstract class BukkitItemFactory<W extends ItemWrapper<ItemStack>> extend
|
||||
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setExactComponent(W item, Object type, Object value) {
|
||||
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasComponent(W item, Object type) {
|
||||
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
|
||||
|
||||
@@ -72,8 +72,29 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
|
||||
return currentObj;
|
||||
}
|
||||
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
@Override
|
||||
protected Tag getNBTTag(ComponentItemWrapper item, Object... path) {
|
||||
protected Object getExactTag(ComponentItemWrapper item, Object... path) {
|
||||
Object customData = getExactComponent(item, ComponentTypes.CUSTOM_DATA);
|
||||
if (customData == null) return null;
|
||||
Object currentTag = FastNMS.INSTANCE.method$CustomData$getUnsafe(customData);
|
||||
for (int i = 0; i < path.length; i++) {
|
||||
Object pathSegment = path[i];
|
||||
if (pathSegment == null) return null;
|
||||
currentTag = FastNMS.INSTANCE.method$CompoundTag$get(currentTag, path[i].toString());
|
||||
if (currentTag == null) return null;
|
||||
if (i == path.length - 1) {
|
||||
return currentTag;
|
||||
}
|
||||
if (!CoreReflections.clazz$CompoundTag.isInstance(currentTag)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Tag getTag(ComponentItemWrapper item, Object... path) {
|
||||
CompoundTag rootTag = (CompoundTag) item.getSparrowNBTComponent(ComponentTypes.CUSTOM_DATA).orElse(null);
|
||||
if (rootTag == null) return null;
|
||||
Tag currentTag = rootTag;
|
||||
@@ -140,7 +161,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
|
||||
|
||||
@Override
|
||||
protected boolean hasTag(ComponentItemWrapper item, Object... path) {
|
||||
return getNBTTag(item, path) != null;
|
||||
return getTag(item, path) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -221,6 +242,11 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
|
||||
return item.getComponentExact(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setExactComponent(ComponentItemWrapper item, Object type, Object value) {
|
||||
item.setComponentExact(type, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getJavaComponent(ComponentItemWrapper item, Object type) {
|
||||
return item.getJavaComponent(type).orElse(null);
|
||||
@@ -475,8 +501,8 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
|
||||
item.resetComponent(ComponentTypes.TRIM);
|
||||
} else {
|
||||
item.setJavaComponent(ComponentTypes.TRIM, Map.of(
|
||||
"pattern", trim.pattern(),
|
||||
"material", trim.material()
|
||||
"pattern", trim.pattern().asString(),
|
||||
"material", trim.material().asString()
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -489,7 +515,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> trimMap = (Map<String, String>) trim.get();
|
||||
return Optional.of(new Trim(trimMap.get("pattern"), trimMap.get("material")));
|
||||
return Optional.of(new Trim(Key.of(trimMap.get("pattern")), Key.of(trimMap.get("material"))));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@@ -43,10 +43,15 @@ public class UniversalItemFactory extends BukkitItemFactory<LegacyItemWrapper> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Tag getNBTTag(LegacyItemWrapper item, Object... path) {
|
||||
protected Tag getTag(LegacyItemWrapper item, Object... path) {
|
||||
return item.getNBTTag(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getExactTag(LegacyItemWrapper item, Object... path) {
|
||||
return item.getExactTag(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasTag(LegacyItemWrapper item, Object... path) {
|
||||
return item.hasTag(path);
|
||||
@@ -263,8 +268,8 @@ public class UniversalItemFactory extends BukkitItemFactory<LegacyItemWrapper> {
|
||||
item.remove("Trim");
|
||||
return;
|
||||
}
|
||||
item.setTag(trim.material(), "Trim", "material");
|
||||
item.setTag(trim.pattern(), "Trim", "pattern");
|
||||
item.setTag(trim.material().asString(), "Trim", "material");
|
||||
item.setTag(trim.pattern().asString(), "Trim", "pattern");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -304,7 +309,7 @@ public class UniversalItemFactory extends BukkitItemFactory<LegacyItemWrapper> {
|
||||
String material = item.getJavaTag("Trim", "material");
|
||||
String pattern = item.getJavaTag("Trim", "pattern");
|
||||
if (material == null || pattern == null) return Optional.empty();
|
||||
return Optional.of(new Trim(material, pattern));
|
||||
return Optional.of(new Trim(Key.of(material), Key.of(pattern)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -140,6 +140,27 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
MIXED_RECIPE_CONVERTORS.put(RecipeTypes.SMITHING_TRIM, (BukkitRecipeConvertor<CustomSmithingTrimRecipe<ItemStack>>) (id, recipe) -> {
|
||||
try {
|
||||
Object nmsRecipe = createMinecraftSmithingTrimRecipe(recipe);
|
||||
if (VersionHelper.isOrAbove1_21_2()) {
|
||||
nmsRecipe = CoreReflections.constructor$RecipeHolder.newInstance(
|
||||
CraftBukkitReflections.method$CraftRecipe$toMinecraft.invoke(null, new NamespacedKey(id.namespace(), id.value())), nmsRecipe);
|
||||
} else if (VersionHelper.isOrAbove1_20_2()) {
|
||||
nmsRecipe = CoreReflections.constructor$RecipeHolder.newInstance(KeyUtils.toResourceLocation(id), nmsRecipe);
|
||||
} else {
|
||||
Object finalNmsRecipe0 = nmsRecipe;
|
||||
return () -> registerNMSSmithingRecipe(finalNmsRecipe0);
|
||||
}
|
||||
Object finalNmsRecipe = nmsRecipe;
|
||||
return () -> registerNMSSmithingRecipe(finalNmsRecipe);
|
||||
} catch (InvalidRecipeIngredientException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().warn("Failed to convert smithing trim recipe", e);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
// TODO DO NOT USE BUKKIT RECIPE AS BRIDGE IN FUTURE VERSIONS, WE SHOULD DIRECTLY CONSTRUCT THOSE NMS RECIPES
|
||||
MIXED_RECIPE_CONVERTORS.put(RecipeTypes.SHAPED, (BukkitRecipeConvertor<CustomShapedRecipe<ItemStack>>) (id, recipe) -> {
|
||||
ShapedRecipe shapedRecipe = new ShapedRecipe(new NamespacedKey(id.namespace(), id.value()), recipe.result(ItemBuildContext.EMPTY));
|
||||
@@ -439,6 +460,10 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
VanillaSmithingTransformRecipe recipe = this.recipeReader.readSmithingTransform(jsonObject);
|
||||
handleDataPackSmithingTransform(id, recipe, (this.delayedTasksOnMainThread::add));
|
||||
}
|
||||
case "minecraft:smithing_trim" -> {
|
||||
VanillaSmithingTrimRecipe recipe = this.recipeReader.readSmithingTrim(jsonObject);
|
||||
handleDataPackSmithingTrim(id, recipe, (this.delayedTasksOnMainThread::add));
|
||||
}
|
||||
case "minecraft:stonecutting" -> {
|
||||
VanillaStoneCuttingRecipe recipe = this.recipeReader.readStoneCutting(jsonObject);
|
||||
handleDataPackStoneCuttingRecipe(id, recipe);
|
||||
@@ -649,6 +674,35 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
this.registerInternalRecipe(id, ceRecipe);
|
||||
}
|
||||
|
||||
private void handleDataPackSmithingTrim(Key id, VanillaSmithingTrimRecipe recipe, Consumer<Runnable> callback) {
|
||||
NamespacedKey key = new NamespacedKey(id.namespace(), id.value());
|
||||
|
||||
boolean hasCustomItemInTag;
|
||||
Set<UniqueKey> additionHolders = new HashSet<>();
|
||||
hasCustomItemInTag = readVanillaIngredients(false, recipe.addition(), additionHolders::add);
|
||||
Set<UniqueKey> templateHolders = new HashSet<>();
|
||||
hasCustomItemInTag = readVanillaIngredients(hasCustomItemInTag, recipe.template(), templateHolders::add);
|
||||
Set<UniqueKey> baseHolders = new HashSet<>();
|
||||
hasCustomItemInTag = readVanillaIngredients(hasCustomItemInTag, recipe.base(), baseHolders::add);
|
||||
|
||||
CustomSmithingTrimRecipe<ItemStack> ceRecipe = new CustomSmithingTrimRecipe<>(
|
||||
id,
|
||||
Ingredient.of(baseHolders),
|
||||
Ingredient.of(templateHolders),
|
||||
Ingredient.of(additionHolders),
|
||||
Optional.ofNullable(recipe.pattern()).map(Key::of).orElse(null)
|
||||
);
|
||||
|
||||
if (hasCustomItemInTag) {
|
||||
Runnable converted = findNMSRecipeConvertor(ceRecipe).convert(id, ceRecipe);
|
||||
callback.accept(() -> {
|
||||
unregisterNMSRecipe(key);
|
||||
converted.run();
|
||||
});
|
||||
}
|
||||
this.registerInternalRecipe(id, ceRecipe);
|
||||
}
|
||||
|
||||
private boolean readVanillaIngredients(boolean hasCustomItemInTag, List<String> ingredients, Consumer<UniqueKey> holderConsumer) {
|
||||
for (String item : ingredients) {
|
||||
if (item.charAt(0) == '#') {
|
||||
@@ -903,4 +957,35 @@ public class BukkitRecipeManager extends AbstractRecipeManager<ItemStack> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static Object createMinecraftSmithingTrimRecipe(CustomSmithingTrimRecipe<ItemStack> recipe) throws ReflectiveOperationException {
|
||||
if (VersionHelper.isOrAbove1_21_5()) {
|
||||
Object registry = FastNMS.INSTANCE.method$RegistryAccess$lookupOrThrow(FastNMS.INSTANCE.registryAccess(), MRegistries.TRIM_PATTERN);
|
||||
return CoreReflections.constructor$SmithingTrimRecipe.newInstance(
|
||||
toMinecraftIngredient(recipe.template()),
|
||||
toMinecraftIngredient(recipe.base()),
|
||||
toMinecraftIngredient(recipe.addition()),
|
||||
FastNMS.INSTANCE.method$Registry$getHolderByResourceLocation(registry, KeyUtils.toResourceLocation(recipe.pattern()))
|
||||
);
|
||||
} else if (VersionHelper.isOrAbove1_21_2()) {
|
||||
return CoreReflections.constructor$SmithingTrimRecipe.newInstance(
|
||||
toOptionalMinecraftIngredient(recipe.template()),
|
||||
toOptionalMinecraftIngredient(recipe.base()),
|
||||
toOptionalMinecraftIngredient(recipe.addition())
|
||||
);
|
||||
} else if (VersionHelper.isOrAbove1_20_2()) {
|
||||
return CoreReflections.constructor$SmithingTrimRecipe.newInstance(
|
||||
toMinecraftIngredient(recipe.template()),
|
||||
toMinecraftIngredient(recipe.base()),
|
||||
toMinecraftIngredient(recipe.addition())
|
||||
);
|
||||
} else {
|
||||
return CoreReflections.constructor$SmithingTrimRecipe.newInstance(
|
||||
KeyUtils.toResourceLocation(recipe.id()),
|
||||
toMinecraftIngredient(recipe.template()),
|
||||
toMinecraftIngredient(recipe.base()),
|
||||
toMinecraftIngredient(recipe.addition())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ import net.momirealms.craftengine.bukkit.util.ItemStackUtils;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.ItemManager;
|
||||
import net.momirealms.craftengine.core.item.recipe.OptimizedIDItem;
|
||||
import net.momirealms.craftengine.core.item.recipe.Recipe;
|
||||
import net.momirealms.craftengine.core.item.recipe.RecipeTypes;
|
||||
import net.momirealms.craftengine.core.item.recipe.UniqueIdItem;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.CraftingInput;
|
||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
@@ -52,33 +52,33 @@ public class CrafterEventListener implements Listener {
|
||||
Inventory inventory = crafter.getInventory();
|
||||
ItemStack[] ingredients = inventory.getStorageContents();
|
||||
|
||||
List<OptimizedIDItem<ItemStack>> optimizedIDItems = new ArrayList<>();
|
||||
List<UniqueIdItem<ItemStack>> uniqueIdItems = new ArrayList<>();
|
||||
for (ItemStack itemStack : ingredients) {
|
||||
if (ItemStackUtils.isEmpty(itemStack)) {
|
||||
optimizedIDItems.add(RecipeEventListener.EMPTY);
|
||||
uniqueIdItems.add(this.itemManager.uniqueEmptyItem());
|
||||
} else {
|
||||
Item<ItemStack> wrappedItem = this.itemManager.wrap(itemStack);
|
||||
optimizedIDItems.add(new OptimizedIDItem<>(wrappedItem.recipeIngredientId(), itemStack));
|
||||
uniqueIdItems.add(new UniqueIdItem<>(wrappedItem.recipeIngredientId(), wrappedItem));
|
||||
}
|
||||
}
|
||||
|
||||
CraftingInput<ItemStack> input;
|
||||
if (ingredients.length == 9) {
|
||||
input = CraftingInput.of(3, 3, optimizedIDItems);
|
||||
input = CraftingInput.of(3, 3, uniqueIdItems);
|
||||
} else if (ingredients.length == 4) {
|
||||
input = CraftingInput.of(2, 2, optimizedIDItems);
|
||||
input = CraftingInput.of(2, 2, uniqueIdItems);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
Recipe<ItemStack> ceRecipe = this.recipeManager.recipeByInput(RecipeTypes.SHAPELESS, input);
|
||||
if (ceRecipe != null) {
|
||||
event.setResult(ceRecipe.result(ItemBuildContext.EMPTY));
|
||||
event.setResult(ceRecipe.assemble(input, ItemBuildContext.EMPTY));
|
||||
return;
|
||||
}
|
||||
ceRecipe = this.recipeManager.recipeByInput(RecipeTypes.SHAPED, input);
|
||||
if (ceRecipe != null) {
|
||||
event.setResult(ceRecipe.result(ItemBuildContext.EMPTY));
|
||||
event.setResult(ceRecipe.assemble(input, ItemBuildContext.EMPTY));
|
||||
return;
|
||||
}
|
||||
// clear result if not met
|
||||
|
||||
@@ -12,6 +12,7 @@ import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflect
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRecipeTypes;
|
||||
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
|
||||
import net.momirealms.craftengine.bukkit.util.ComponentUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.InventoryUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.ItemStackUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.LegacyInventoryUtils;
|
||||
import net.momirealms.craftengine.core.item.*;
|
||||
@@ -49,7 +50,6 @@ import java.util.Optional;
|
||||
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
public class RecipeEventListener implements Listener {
|
||||
public static final OptimizedIDItem<ItemStack> EMPTY = new OptimizedIDItem<>(null, null);
|
||||
private final ItemManager<ItemStack> itemManager;
|
||||
private final BukkitRecipeManager recipeManager;
|
||||
private final BukkitCraftEngine plugin;
|
||||
@@ -74,7 +74,7 @@ public class RecipeEventListener implements Listener {
|
||||
ItemStack item = event.getCurrentItem();
|
||||
if (ItemStackUtils.isEmpty(item)) return;
|
||||
if (ItemStackUtils.isEmpty(fuelStack)) {
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(getOptimizedIDItem(item));
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(getUniqueIdItem(item));
|
||||
Key recipeType;
|
||||
if (furnaceInventory.getType() == InventoryType.FURNACE) {
|
||||
recipeType = RecipeTypes.SMELTING;
|
||||
@@ -351,7 +351,7 @@ public class RecipeEventListener implements Listener {
|
||||
if (optionalMCRecipe.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(getOptimizedIDItem(itemStack));
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(getUniqueIdItem(itemStack));
|
||||
CustomCampfireRecipe<ItemStack> ceRecipe = (CustomCampfireRecipe<ItemStack>) this.recipeManager.recipeByInput(RecipeTypes.CAMPFIRE_COOKING, input);
|
||||
if (ceRecipe == null) {
|
||||
event.setCancelled(true);
|
||||
@@ -376,7 +376,7 @@ public class RecipeEventListener implements Listener {
|
||||
}
|
||||
|
||||
ItemStack itemStack = event.getSource();
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(getOptimizedIDItem(itemStack));
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(getUniqueIdItem(itemStack));
|
||||
CustomCampfireRecipe<ItemStack> ceRecipe = (CustomCampfireRecipe<ItemStack>) this.recipeManager.recipeByInput(RecipeTypes.CAMPFIRE_COOKING, input);
|
||||
if (ceRecipe == null) {
|
||||
event.setTotalCookTime(Integer.MAX_VALUE);
|
||||
@@ -404,7 +404,7 @@ public class RecipeEventListener implements Listener {
|
||||
}
|
||||
|
||||
ItemStack itemStack = event.getSource();
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(getOptimizedIDItem(itemStack));
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(getUniqueIdItem(itemStack));
|
||||
CustomCampfireRecipe<ItemStack> ceRecipe = (CustomCampfireRecipe<ItemStack>) this.recipeManager.recipeByInput(RecipeTypes.CAMPFIRE_COOKING, input);
|
||||
if (ceRecipe == null) {
|
||||
event.setCancelled(true);
|
||||
@@ -620,13 +620,7 @@ public class RecipeEventListener implements Listener {
|
||||
LegacyInventoryUtils.setRepairCostAmount(inventory, actualConsumedAmount);
|
||||
}
|
||||
|
||||
Player player;
|
||||
try {
|
||||
player = (Player) CraftBukkitReflections.method$InventoryView$getPlayer.invoke(VersionHelper.isOrAbove1_21() ? event.getView() : LegacyInventoryUtils.getView(event));
|
||||
} catch (ReflectiveOperationException e) {
|
||||
plugin.logger().warn("Failed to get inventory viewer", e);
|
||||
return;
|
||||
}
|
||||
Player player = InventoryUtils.getPlayerFromInventoryEvent(event);
|
||||
|
||||
if (finalCost >= maxRepairCost && !plugin.adapt(player).canInstabuild()) {
|
||||
hasResult = false;
|
||||
@@ -732,13 +726,7 @@ public class RecipeEventListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player;
|
||||
try {
|
||||
player = (Player) CraftBukkitReflections.method$InventoryView$getPlayer.invoke(event.getView());
|
||||
} catch (ReflectiveOperationException e) {
|
||||
plugin.logger().warn("Failed to get inventory viewer", e);
|
||||
return;
|
||||
}
|
||||
Player player = InventoryUtils.getPlayerFromInventoryEvent(event);
|
||||
|
||||
Optional<CustomItem<ItemStack>> customItemOptional = plugin.itemManager().getCustomItem(left.id());
|
||||
if (customItemOptional.isEmpty()) {
|
||||
@@ -860,34 +848,28 @@ public class RecipeEventListener implements Listener {
|
||||
CraftingInventory inventory = event.getInventory();
|
||||
ItemStack[] ingredients = inventory.getMatrix();
|
||||
|
||||
List<OptimizedIDItem<ItemStack>> optimizedIDItems = new ArrayList<>();
|
||||
List<UniqueIdItem<ItemStack>> uniqueIdItems = new ArrayList<>();
|
||||
for (ItemStack itemStack : ingredients) {
|
||||
optimizedIDItems.add(getOptimizedIDItem(itemStack));
|
||||
uniqueIdItems.add(getUniqueIdItem(itemStack));
|
||||
}
|
||||
|
||||
CraftingInput<ItemStack> input;
|
||||
if (ingredients.length == 9) {
|
||||
input = CraftingInput.of(3, 3, optimizedIDItems);
|
||||
input = CraftingInput.of(3, 3, uniqueIdItems);
|
||||
} else if (ingredients.length == 4) {
|
||||
input = CraftingInput.of(2, 2, optimizedIDItems);
|
||||
input = CraftingInput.of(2, 2, uniqueIdItems);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player;
|
||||
try {
|
||||
player = (Player) CraftBukkitReflections.method$InventoryView$getPlayer.invoke(event.getView());
|
||||
} catch (ReflectiveOperationException e) {
|
||||
this.plugin.logger().warn("Failed to get inventory viewer", e);
|
||||
return;
|
||||
}
|
||||
Player player = InventoryUtils.getPlayerFromInventoryEvent(event);
|
||||
|
||||
BukkitServerPlayer serverPlayer = this.plugin.adapt(player);
|
||||
Key lastRecipe = serverPlayer.lastUsedRecipe();
|
||||
|
||||
Recipe<ItemStack> ceRecipe = this.recipeManager.recipeByInput(RecipeTypes.SHAPELESS, input, lastRecipe);
|
||||
if (ceRecipe != null) {
|
||||
inventory.setResult(ceRecipe.result(new ItemBuildContext(serverPlayer, ContextHolder.EMPTY)));
|
||||
inventory.setResult(ceRecipe.assemble(input, new ItemBuildContext(serverPlayer, ContextHolder.EMPTY)));
|
||||
serverPlayer.setLastUsedRecipe(ceRecipe.id());
|
||||
if (!ceRecipe.id().equals(recipeId)) {
|
||||
correctCraftingRecipeUsed(inventory, ceRecipe);
|
||||
@@ -896,7 +878,7 @@ public class RecipeEventListener implements Listener {
|
||||
}
|
||||
ceRecipe = this.recipeManager.recipeByInput(RecipeTypes.SHAPED, input, lastRecipe);
|
||||
if (ceRecipe != null) {
|
||||
inventory.setResult(ceRecipe.result(new ItemBuildContext(serverPlayer, ContextHolder.EMPTY)));
|
||||
inventory.setResult(ceRecipe.assemble(input, new ItemBuildContext(serverPlayer, ContextHolder.EMPTY)));
|
||||
serverPlayer.setLastUsedRecipe(ceRecipe.id());
|
||||
if (!ceRecipe.id().equals(recipeId)) {
|
||||
correctCraftingRecipeUsed(inventory, ceRecipe);
|
||||
@@ -923,18 +905,48 @@ public class RecipeEventListener implements Listener {
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onSmithingTrim(PrepareSmithingEvent event) {
|
||||
SmithingInventory inventory = event.getInventory();
|
||||
if (!(inventory.getRecipe() instanceof SmithingTrimRecipe)) return;
|
||||
if (!(inventory.getRecipe() instanceof SmithingTrimRecipe recipe)) return;
|
||||
|
||||
ItemStack equipment = inventory.getInputEquipment();
|
||||
if (ItemStackUtils.isEmpty(equipment)) return;
|
||||
Item<ItemStack> wrappedEquipment = this.itemManager.wrap(equipment);
|
||||
Optional<CustomItem<ItemStack>> optionalCustomItem = wrappedEquipment.getCustomItem();
|
||||
if (optionalCustomItem.isEmpty()) return;
|
||||
CustomItem<ItemStack> customItem = optionalCustomItem.get();
|
||||
ItemEquipment itemEquipmentSettings = customItem.settings().equipment();
|
||||
if (itemEquipmentSettings == null) return;
|
||||
// 不允许trim类型的盔甲再次被使用trim
|
||||
if (itemEquipmentSettings.equipment() instanceof TrimBasedEquipment) {
|
||||
if (!ItemStackUtils.isEmpty(equipment)) {
|
||||
Item<ItemStack> wrappedEquipment = this.itemManager.wrap(equipment);
|
||||
Optional<CustomItem<ItemStack>> optionalCustomItem = wrappedEquipment.getCustomItem();
|
||||
if (optionalCustomItem.isPresent()) {
|
||||
CustomItem<ItemStack> customItem = optionalCustomItem.get();
|
||||
ItemEquipment itemEquipmentSettings = customItem.settings().equipment();
|
||||
if (itemEquipmentSettings != null && itemEquipmentSettings.equipment() instanceof TrimBasedEquipment) {
|
||||
// 不允许trim类型的盔甲再次被使用trim
|
||||
event.setResult(null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Key recipeId = Key.of(recipe.getKey().namespace(), recipe.getKey().value());
|
||||
boolean isCustom = this.recipeManager.isCustomRecipe(recipeId);
|
||||
// Maybe it's recipe from other plugins, then we ignore it
|
||||
if (!isCustom) {
|
||||
return;
|
||||
}
|
||||
|
||||
SmithingInput<ItemStack> input = new SmithingInput<>(
|
||||
getUniqueIdItem(inventory.getInputEquipment()),
|
||||
getUniqueIdItem(inventory.getInputTemplate()),
|
||||
getUniqueIdItem(inventory.getInputMineral())
|
||||
);
|
||||
|
||||
Recipe<ItemStack> ceRecipe = this.recipeManager.recipeByInput(RecipeTypes.SMITHING_TRIM, input);
|
||||
if (ceRecipe == null) {
|
||||
event.setResult(null);
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = InventoryUtils.getPlayerFromInventoryEvent(event);
|
||||
CustomSmithingTrimRecipe<ItemStack> trimRecipe = (CustomSmithingTrimRecipe<ItemStack>) ceRecipe;
|
||||
ItemStack result = trimRecipe.assemble(input, new ItemBuildContext(this.plugin.adapt(player), ContextHolder.EMPTY));
|
||||
event.setResult(result);
|
||||
if (!ceRecipe.id().equals(recipeId)) {
|
||||
correctSmithingRecipeUsed(inventory, ceRecipe);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -956,9 +968,9 @@ public class RecipeEventListener implements Listener {
|
||||
ItemStack addition = inventory.getInputMineral();
|
||||
|
||||
SmithingInput<ItemStack> input = new SmithingInput<>(
|
||||
getOptimizedIDItem(base),
|
||||
getOptimizedIDItem(template),
|
||||
getOptimizedIDItem(addition)
|
||||
getUniqueIdItem(base),
|
||||
getUniqueIdItem(template),
|
||||
getUniqueIdItem(addition)
|
||||
);
|
||||
|
||||
Recipe<ItemStack> ceRecipe = this.recipeManager.recipeByInput(RecipeTypes.SMITHING_TRANSFORM, input);
|
||||
@@ -967,16 +979,10 @@ public class RecipeEventListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player;
|
||||
try {
|
||||
player = (Player) CraftBukkitReflections.method$InventoryView$getPlayer.invoke(event.getView());
|
||||
} catch (ReflectiveOperationException e) {
|
||||
this.plugin.logger().warn("Failed to get inventory viewer", e);
|
||||
return;
|
||||
}
|
||||
Player player = InventoryUtils.getPlayerFromInventoryEvent(event);
|
||||
|
||||
CustomSmithingTransformRecipe<ItemStack> transformRecipe = (CustomSmithingTransformRecipe<ItemStack>) ceRecipe;
|
||||
ItemStack processed = transformRecipe.assemble(new ItemBuildContext(this.plugin.adapt(player), ContextHolder.EMPTY), this.itemManager.wrap(base));
|
||||
ItemStack processed = transformRecipe.assemble(input, new ItemBuildContext(this.plugin.adapt(player), ContextHolder.EMPTY));
|
||||
event.setResult(processed);
|
||||
if (!ceRecipe.id().equals(recipeId)) {
|
||||
correctSmithingRecipeUsed(inventory, ceRecipe);
|
||||
@@ -996,12 +1002,12 @@ public class RecipeEventListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
private OptimizedIDItem<ItemStack> getOptimizedIDItem(@Nullable ItemStack itemStack) {
|
||||
private UniqueIdItem<ItemStack> getUniqueIdItem(@Nullable ItemStack itemStack) {
|
||||
if (ItemStackUtils.isEmpty(itemStack)) {
|
||||
return EMPTY;
|
||||
return this.itemManager.uniqueEmptyItem();
|
||||
} else {
|
||||
Item<ItemStack> wrappedItem = this.itemManager.wrap(itemStack);
|
||||
return new OptimizedIDItem<>(wrappedItem.recipeIngredientId(), itemStack);
|
||||
return new UniqueIdItem<>(wrappedItem.recipeIngredientId(), wrappedItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@ import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistries
|
||||
import net.momirealms.craftengine.bukkit.util.KeyUtils;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
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.UniqueIdItem;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.SingleItemInput;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ReflectionUtils;
|
||||
@@ -133,7 +133,7 @@ public class RecipeInjector {
|
||||
);
|
||||
|
||||
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(wrappedItem.recipeIngredientId(), itemStack));
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new UniqueIdItem<>(wrappedItem.recipeIngredientId(), wrappedItem));
|
||||
CustomCookingRecipe<ItemStack> ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(injectedCacheCheck.customRecipeType(), input, injectedCacheCheck.lastCustomRecipe());
|
||||
if (ceRecipe == null) {
|
||||
return Optional.empty();
|
||||
@@ -179,7 +179,7 @@ public class RecipeInjector {
|
||||
}
|
||||
|
||||
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(wrappedItem.recipeIngredientId(), itemStack));
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new UniqueIdItem<>(wrappedItem.recipeIngredientId(), wrappedItem));
|
||||
CustomCookingRecipe<ItemStack> ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(injectedCacheCheck.customRecipeType(), input, injectedCacheCheck.lastCustomRecipe());
|
||||
if (ceRecipe == null) {
|
||||
return Optional.empty();
|
||||
@@ -220,7 +220,7 @@ public class RecipeInjector {
|
||||
|
||||
ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(FastNMS.INSTANCE.field$SingleRecipeInput$item(args[0]));
|
||||
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(wrappedItem.recipeIngredientId(), itemStack));
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new UniqueIdItem<>(wrappedItem.recipeIngredientId(), wrappedItem));
|
||||
CustomCookingRecipe<ItemStack> ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(injectedCacheCheck.customRecipeType(), input, injectedCacheCheck.lastCustomRecipe());
|
||||
if (ceRecipe == null) {
|
||||
return Optional.empty();
|
||||
@@ -265,7 +265,7 @@ 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);
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new OptimizedIDItem<>(wrappedItem.recipeIngredientId(), itemStack));
|
||||
SingleItemInput<ItemStack> input = new SingleItemInput<>(new UniqueIdItem<>(wrappedItem.recipeIngredientId(), wrappedItem));
|
||||
CustomCookingRecipe<ItemStack> ceRecipe = (CustomCookingRecipe<ItemStack>) recipeManager.recipeByInput(injectedCacheCheck.customRecipeType(), input, injectedCacheCheck.lastCustomRecipe());
|
||||
// 这个ce配方并不存在,那么应该返回空
|
||||
if (ceRecipe == null) {
|
||||
|
||||
@@ -2290,12 +2290,24 @@ public final class CoreReflections {
|
||||
|
||||
public static final Constructor<?> constructor$SmithingTransformRecipe = requireNonNull(
|
||||
VersionHelper.isOrAbove1_21_5()
|
||||
? ReflectionUtils.getConstructor(clazz$SmithingTransformRecipe, Optional.class, clazz$Ingredient, Optional.class, clazz$TransmuteResult)
|
||||
: VersionHelper.isOrAbove1_21_2()
|
||||
? ReflectionUtils.getConstructor(clazz$SmithingTransformRecipe, Optional.class, Optional.class, Optional.class, clazz$ItemStack)
|
||||
: VersionHelper.isOrAbove1_20_2()
|
||||
? ReflectionUtils.getConstructor(clazz$SmithingTransformRecipe, clazz$Ingredient, clazz$Ingredient, clazz$Ingredient, clazz$ItemStack)
|
||||
: ReflectionUtils.getConstructor(clazz$SmithingTransformRecipe, clazz$ResourceLocation, clazz$Ingredient, clazz$Ingredient, clazz$Ingredient, clazz$ItemStack)
|
||||
? ReflectionUtils.getConstructor(clazz$SmithingTransformRecipe, Optional.class, clazz$Ingredient, Optional.class, clazz$TransmuteResult)
|
||||
: VersionHelper.isOrAbove1_21_2()
|
||||
? ReflectionUtils.getConstructor(clazz$SmithingTransformRecipe, Optional.class, Optional.class, Optional.class, clazz$ItemStack)
|
||||
: VersionHelper.isOrAbove1_20_2()
|
||||
? ReflectionUtils.getConstructor(clazz$SmithingTransformRecipe, clazz$Ingredient, clazz$Ingredient, clazz$Ingredient, clazz$ItemStack)
|
||||
: ReflectionUtils.getConstructor(clazz$SmithingTransformRecipe, clazz$ResourceLocation, clazz$Ingredient, clazz$Ingredient, clazz$Ingredient, clazz$ItemStack)
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$SmithingTrimRecipe = requireNonNull(
|
||||
ReflectionUtils.getClazz(BukkitReflectionUtils.assembleMCClass("world.item.crafting.SmithingTrimRecipe"))
|
||||
);
|
||||
|
||||
public static final Constructor<?> constructor$SmithingTrimRecipe = requireNonNull(
|
||||
VersionHelper.isOrAbove1_21_5() ?
|
||||
ReflectionUtils.getConstructor(clazz$SmithingTrimRecipe, clazz$Ingredient, clazz$Ingredient, clazz$Ingredient, clazz$Holder) :
|
||||
VersionHelper.isOrAbove1_20_2() ?
|
||||
ReflectionUtils.getConstructor(clazz$SmithingTrimRecipe, clazz$Ingredient, clazz$Ingredient, clazz$Ingredient) :
|
||||
ReflectionUtils.getConstructor(clazz$SmithingTrimRecipe, clazz$ResourceLocation, clazz$Ingredient, clazz$Ingredient, clazz$Ingredient)
|
||||
);
|
||||
|
||||
public static final Method method$RecipeManager$addRecipe = requireNonNull(
|
||||
@@ -3771,4 +3783,35 @@ public final class CoreReflections {
|
||||
"world.item.BlockItem"
|
||||
)
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$ArmorTrim = requireNonNull(
|
||||
ReflectionUtils.getClazz(
|
||||
VersionHelper.isOrAbove1_21_2() ?
|
||||
BukkitReflectionUtils.assembleCBClass("world.item.equipment.trim.ArmorTrim") :
|
||||
BukkitReflectionUtils.assembleMCClass("world.item.armortrim.ArmorTrim")
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$ArmorTrim$CODEC = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(clazz$ArmorTrim, Codec.class, 0)
|
||||
);
|
||||
|
||||
public static final Codec<?> instance$ArmorTrim$CODEC;
|
||||
|
||||
static {
|
||||
try {
|
||||
instance$ArmorTrim$CODEC = (Codec<?>) field$ArmorTrim$CODEC.get(null);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new ReflectionInitException("Failed to initialize ArmorTrim CODEC", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static final Method method$ArmorTrim$setTrim = ReflectionUtils.getStaticMethod(
|
||||
clazz$ArmorTrim, boolean.class, clazz$RegistryAccess, clazz$ItemStack, clazz$ArmorTrim
|
||||
);
|
||||
|
||||
public static final Method method$ArmorTrim$getTrim =
|
||||
VersionHelper.isOrAbove1_20_2() ?
|
||||
ReflectionUtils.getStaticMethod(clazz$ArmorTrim, Optional.class, clazz$RegistryAccess, clazz$ItemStack, boolean.class) :
|
||||
ReflectionUtils.getStaticMethod(clazz$ArmorTrim, Optional.class, clazz$RegistryAccess, clazz$ItemStack);
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import net.momirealms.craftengine.bukkit.item.recipe.BukkitRecipeManager;
|
||||
import net.momirealms.craftengine.core.block.BlockKeys;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemKeys;
|
||||
import net.momirealms.craftengine.core.item.recipe.OptimizedIDItem;
|
||||
import net.momirealms.craftengine.core.item.recipe.RecipeTypes;
|
||||
import net.momirealms.craftengine.core.item.recipe.UniqueIdItem;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.SingleItemInput;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
@@ -78,14 +78,14 @@ public class InteractUtils {
|
||||
});
|
||||
registerInteraction(BlockKeys.SOUL_CAMPFIRE, (player, item, blockState, result) -> {
|
||||
if (!Config.enableRecipeSystem()) return false;
|
||||
return BukkitRecipeManager.instance().recipeByInput(RecipeTypes.CAMPFIRE_COOKING, new SingleItemInput<>(new OptimizedIDItem<>(
|
||||
item.recipeIngredientId(), item.getItem()
|
||||
return BukkitRecipeManager.instance().recipeByInput(RecipeTypes.CAMPFIRE_COOKING, new SingleItemInput<>(new UniqueIdItem<>(
|
||||
item.recipeIngredientId(), item
|
||||
))) != null;
|
||||
});
|
||||
registerInteraction(BlockKeys.CAMPFIRE, (player, item, blockState, result) -> {
|
||||
if (!Config.enableRecipeSystem()) return false;
|
||||
return BukkitRecipeManager.instance().recipeByInput(RecipeTypes.CAMPFIRE_COOKING, new SingleItemInput<>(new OptimizedIDItem<>(
|
||||
item.recipeIngredientId(), item.getItem()
|
||||
return BukkitRecipeManager.instance().recipeByInput(RecipeTypes.CAMPFIRE_COOKING, new SingleItemInput<>(new UniqueIdItem<>(
|
||||
item.recipeIngredientId(), item
|
||||
))) != null;
|
||||
});
|
||||
registerInteraction(BlockKeys.DECORATED_POT, (player, item, blockState, result) -> true);
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package net.momirealms.craftengine.bukkit.util;
|
||||
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
|
||||
@@ -7,6 +10,14 @@ public class InventoryUtils {
|
||||
|
||||
private InventoryUtils() {}
|
||||
|
||||
public static Player getPlayerFromInventoryEvent(InventoryEvent event) {
|
||||
if (VersionHelper.isOrAbove1_21()) {
|
||||
return (Player) event.getView().getPlayer();
|
||||
} else {
|
||||
return LegacyInventoryUtils.getPlayerFromInventoryEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getSuitableHotBarSlot(PlayerInventory inventory) {
|
||||
int selectedSlot = inventory.getHeldItemSlot();
|
||||
int i;
|
||||
|
||||
@@ -135,6 +135,11 @@ warning.config.recipe.smithing_transform.post_processor.missing_type: "<yellow>I
|
||||
warning.config.recipe.smithing_transform.post_processor.invalid_type: "<yellow>Issue found in file <arg:0> - The smithing transform recipe '<arg:1>' is using an invalid post processor type '<arg:2>'.</yellow>"
|
||||
warning.config.recipe.smithing_transform.post_processor.keep_component.missing_components: "<yellow>Issue found in file <arg:0> - The smithing transform recipe '<arg:1>' is missing the required argument 'components' for post-processors 'keep_components'.</yellow>"
|
||||
warning.config.recipe.smithing_transform.post_processor.keep_component.missing_tags: "<yellow>Issue found in file <arg:0> - The smithing transform recipe '<arg:1>' is missing the required argument 'tags' for post-processors 'keep_tags'.</yellow>"
|
||||
warning.config.recipe.smithing_transform.missing_base: "<yellow>Issue found in file <arg:0> - The smithing transform recipe '<arg:1>' is missing the required 'base' argument.</yellow>"
|
||||
warning.config.recipe.smithing_trim.missing_base: "<yellow>Issue found in file <arg:0> - The smithing trim recipe '<arg:1>' is missing the required 'base' argument.</yellow>"
|
||||
warning.config.recipe.smithing_trim.missing_template_type: "<yellow>Issue found in file <arg:0> - The smithing trim recipe '<arg:1>' is missing the required 'template-type' argument.</yellow>"
|
||||
warning.config.recipe.smithing_trim.missing_addition: "<yellow>Issue found in file <arg:0> - The smithing trim recipe '<arg:1>' is missing the required 'addition' argument.</yellow>"
|
||||
warning.config.recipe.smithing_trim.missing_pattern: "<yellow>Issue found in file <arg:0> - The smithing trim recipe '<arg:1>' is missing the required 'pattern' argument.</yellow>"
|
||||
warning.config.i18n.unknown_locale: "<yellow>Issue found in file <arg:0> - Unknown locale '<arg:1>'.</yellow>"
|
||||
warning.config.template.duplicate: "<yellow>Issue found in file <arg:0> - Duplicated template '<arg:1>'. Please check if there is the same configuration in other files.</yellow>"
|
||||
warning.config.template.invalid: "<yellow>Issue found in file <arg:0> - The config '<arg:1>' is using an invalid template '<arg:2>'.</yellow>"
|
||||
|
||||
@@ -135,6 +135,11 @@ warning.config.recipe.smithing_transform.post_processor.missing_type: "<yellow>
|
||||
warning.config.recipe.smithing_transform.post_processor.invalid_type: "<yellow>在文件 <arg:0> 发现问题 - 锻造升级配方 '<arg:1>' 使用了无效的后处理器类型 '<arg:2>'</yellow>"
|
||||
warning.config.recipe.smithing_transform.post_processor.keep_component.missing_components: "<yellow>在文件 <arg:0> 发现问题 - 锻造升级配方 '<arg:1>' 的 'keep_components' 后处理器缺少必需的 'components' 参数</yellow>"
|
||||
warning.config.recipe.smithing_transform.post_processor.keep_component.missing_tags: "<yellow>在文件 <arg:0> 发现问题 - 锻造升级配方 '<arg:1>' 的 'keep_tags' 后处理器缺少必需的 'tags' 参数</yellow>"
|
||||
warning.config.recipe.smithing_transform.missing_base: "<yellow>在文件 <arg:0> 发现问题 - 锻造升级配方 '<arg:1>' 缺少必需的 'base' 参数</yellow>"
|
||||
warning.config.recipe.smithing_trim.missing_base: "<yellow>在文件 <arg:0> 发现问题 - 锻造纹饰配方 '<arg:1>' 缺少必需的 'base' 参数</yellow>"
|
||||
warning.config.recipe.smithing_trim.missing_template_type: "<yellow>在文件 <arg:0> 发现问题 - 锻造纹饰配方 '<arg:1>' 缺少必需的 'template-type' 参数</yellow>"
|
||||
warning.config.recipe.smithing_trim.missing_addition: "<yellow>在文件 <arg:0> 发现问题 - 锻造纹饰配方 '<arg:1>' 缺少必需的 'addition' 参数</yellow>"
|
||||
warning.config.recipe.smithing_trim.missing_pattern: "<yellow>在文件 <arg:0> 发现问题 - 锻造纹饰配方 '<arg:1>' 缺少必需的 'pattern' 参数</yellow>"
|
||||
warning.config.i18n.unknown_locale: "<yellow>在文件 <arg:0> 发现问题 - 未知的语言环境 '<arg:1>'</yellow>"
|
||||
warning.config.template.duplicate: "<yellow>在文件 <arg:0> 发现问题 - 重复的模板 '<arg:1>' 请检查其他文件中是否存在相同配置</yellow>"
|
||||
warning.config.template.argument.self_increase_int.invalid_range: "<yellow>在文件 <arg:0> 发现问题 - 模板 '<arg:1>' 在 'self_increase_int' 参数中使用了一个起始值 '<arg:2>' 大于终止值 '<arg:3>'</yellow>"
|
||||
|
||||
@@ -331,8 +331,13 @@ public class AbstractItem<W extends ItemWrapper<I>, I> implements Item<I> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag getNBTTag(Object... path) {
|
||||
return this.factory.getNBTTag(this.item, path);
|
||||
public Tag getTag(Object... path) {
|
||||
return this.factory.getTag(this.item, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getExactTag(Object... path) {
|
||||
return this.factory.getExactTag(this.item, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -366,6 +371,11 @@ public class AbstractItem<W extends ItemWrapper<I>, I> implements Item<I> {
|
||||
return this.factory.getExactComponent(this.item, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExactComponent(Object type, Object value) {
|
||||
this.factory.setExactComponent(this.item, type, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getJavaComponent(Object type) {
|
||||
return this.factory.getJavaComponent(this.item, type);
|
||||
|
||||
@@ -600,7 +600,7 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
||||
Map<String, Object> data = MiscUtils.castToMap(obj, false);
|
||||
String material = data.get("material").toString().toLowerCase(Locale.ENGLISH);
|
||||
String pattern = data.get("pattern").toString().toLowerCase(Locale.ENGLISH);
|
||||
return new TrimModifier<>(material, pattern);
|
||||
return new TrimModifier<>(Key.of(material), Key.of(pattern));
|
||||
}, "trim");
|
||||
registerDataType((obj) -> {
|
||||
List<Key> components = MiscUtils.getAsStringList(obj).stream().map(Key::of).toList();
|
||||
|
||||
@@ -141,7 +141,9 @@ public interface Item<I> {
|
||||
|
||||
Object getJavaTag(Object... path);
|
||||
|
||||
Tag getNBTTag(Object... path);
|
||||
Tag getTag(Object... path);
|
||||
|
||||
Object getExactTag(Object... path);
|
||||
|
||||
Item<I> setTag(Object value, Object... path);
|
||||
|
||||
@@ -153,6 +155,8 @@ public interface Item<I> {
|
||||
|
||||
void removeComponent(Object type);
|
||||
|
||||
void setExactComponent(Object type, Object value);
|
||||
|
||||
Object getExactComponent(Object type);
|
||||
|
||||
Object getJavaComponent(Object type);
|
||||
|
||||
@@ -38,7 +38,7 @@ public abstract class ItemFactory<W extends ItemWrapper<I>, I> {
|
||||
|
||||
protected abstract Object getJavaTag(W item, Object... path);
|
||||
|
||||
protected abstract Tag getNBTTag(W item, Object... path);
|
||||
protected abstract Tag getTag(W item, Object... path);
|
||||
|
||||
protected abstract void setTag(W item, Object value, Object... path);
|
||||
|
||||
@@ -50,6 +50,10 @@ public abstract class ItemFactory<W extends ItemWrapper<I>, I> {
|
||||
|
||||
protected abstract Object getExactComponent(W item, Object type);
|
||||
|
||||
protected abstract Object getExactTag(W item, Object... path);
|
||||
|
||||
protected abstract void setExactComponent(W item, Object type, Object value);
|
||||
|
||||
protected abstract Object getJavaComponent(W item, Object type);
|
||||
|
||||
protected abstract JsonElement getJsonComponent(W item, Object type);
|
||||
|
||||
@@ -4,6 +4,7 @@ import net.momirealms.craftengine.core.entity.player.Player;
|
||||
import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
|
||||
import net.momirealms.craftengine.core.item.equipment.Equipment;
|
||||
import net.momirealms.craftengine.core.item.modifier.ItemDataModifier;
|
||||
import net.momirealms.craftengine.core.item.recipe.UniqueIdItem;
|
||||
import net.momirealms.craftengine.core.pack.model.LegacyOverridesModel;
|
||||
import net.momirealms.craftengine.core.pack.model.ModernItemModel;
|
||||
import net.momirealms.craftengine.core.pack.model.generation.ModelGenerator;
|
||||
@@ -107,4 +108,8 @@ public interface ItemManager<T> extends Manageable, ModelGenerator {
|
||||
Item<T> s2c(Item<T> item, Player player);
|
||||
|
||||
Item<T> c2s(Item<T> item);
|
||||
|
||||
UniqueIdItem<T> uniqueEmptyItem();
|
||||
|
||||
Item<T> applyTrim(Item<T> base, Item<T> addition, Item<T> template, Key pattern);
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
package net.momirealms.craftengine.core.item.data;
|
||||
|
||||
public record Trim(String pattern, String material) {
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
public record Trim(Key pattern, Key material) {
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public class TrimBasedEquipment extends AbstractEquipment {
|
||||
@Override
|
||||
public <I> List<ItemDataModifier<I>> modifiers() {
|
||||
return List.of(
|
||||
new TrimModifier<>(AbstractPackManager.NEW_TRIM_MATERIAL, this.assetId.toString()),
|
||||
new TrimModifier<>(Key.of(AbstractPackManager.NEW_TRIM_MATERIAL), this.assetId),
|
||||
new HideTooltipModifier<>(List.of(ComponentKeys.TRIM))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ public class AttributeModifiersModifier<I> implements ItemDataModifier<I> {
|
||||
networkData.put(ComponentKeys.ATTRIBUTE_MODIFIERS.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
} else {
|
||||
Tag previous = item.getNBTTag("AttributeModifiers");
|
||||
Tag previous = item.getTag("AttributeModifiers");
|
||||
if (previous != null) {
|
||||
networkData.put("AttributeModifiers", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
|
||||
@@ -59,7 +59,7 @@ public class ComponentModifier<I> implements ItemDataModifier<I> {
|
||||
item.setNBTComponent(entry.left(), entry.right());
|
||||
}
|
||||
if (this.customData != null) {
|
||||
CompoundTag tag = (CompoundTag) item.getNBTTag(ComponentKeys.CUSTOM_DATA);
|
||||
CompoundTag tag = (CompoundTag) item.getTag(ComponentKeys.CUSTOM_DATA);
|
||||
if (tag != null) {
|
||||
for (Map.Entry<String, Tag> entry : this.customData.entrySet()) {
|
||||
tag.put(entry.getKey(), entry.getValue());
|
||||
|
||||
@@ -36,7 +36,7 @@ public class CustomModelDataModifier<I> implements ItemDataModifier<I> {
|
||||
networkData.put(ComponentKeys.CUSTOM_MODEL_DATA.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
} else {
|
||||
Tag previous = item.getNBTTag("CustomModelData");
|
||||
Tag previous = item.getTag("CustomModelData");
|
||||
if (previous != null) {
|
||||
networkData.put("CustomModelData", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
|
||||
@@ -46,7 +46,7 @@ public class CustomNameModifier<I> implements ItemDataModifier<I> {
|
||||
networkData.put(ComponentKeys.CUSTOM_NAME.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
} else {
|
||||
Tag previous = item.getNBTTag("display", "Name");
|
||||
Tag previous = item.getTag("display", "Name");
|
||||
if (previous != null) {
|
||||
networkData.put("display.Name", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
|
||||
@@ -36,7 +36,7 @@ public class DyedColorModifier<I> implements ItemDataModifier<I> {
|
||||
networkData.put(ComponentKeys.DYED_COLOR.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
} else {
|
||||
Tag previous = item.getNBTTag("display", "color");
|
||||
Tag previous = item.getTag("display", "color");
|
||||
if (previous != null) {
|
||||
networkData.put("display.color", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
|
||||
@@ -54,7 +54,7 @@ public class DynamicLoreModifier<I> implements ItemDataModifier<I> {
|
||||
networkData.put(ComponentKeys.LORE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
} else {
|
||||
Tag previous = item.getNBTTag("display", "Lore");
|
||||
Tag previous = item.getTag("display", "Lore");
|
||||
if (previous != null) {
|
||||
networkData.put("display.Lore", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
|
||||
@@ -41,7 +41,7 @@ public class EnchantmentModifier<I> implements ItemDataModifier<I> {
|
||||
networkData.put(ComponentKeys.STORED_ENCHANTMENTS.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
} else {
|
||||
Tag previous = item.getNBTTag("StoredEnchantments");
|
||||
Tag previous = item.getTag("StoredEnchantments");
|
||||
if (previous != null) {
|
||||
networkData.put("StoredEnchantments", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
@@ -57,7 +57,7 @@ public class EnchantmentModifier<I> implements ItemDataModifier<I> {
|
||||
networkData.put(ComponentKeys.ENCHANTMENTS.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
} else {
|
||||
Tag previous = item.getNBTTag("Enchantments");
|
||||
Tag previous = item.getTag("Enchantments");
|
||||
if (previous != null) {
|
||||
networkData.put("Enchantments", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
|
||||
@@ -94,7 +94,7 @@ public class HideTooltipModifier<I> implements ItemDataModifier<I> {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Tag previous = item.getNBTTag("HideFlags");
|
||||
Tag previous = item.getTag("HideFlags");
|
||||
if (previous != null) {
|
||||
networkData.put("HideFlags", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
|
||||
@@ -37,7 +37,7 @@ public class ItemNameModifier<I> implements ItemDataModifier<I> {
|
||||
networkData.put(ComponentKeys.ITEM_NAME.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
} else {
|
||||
Tag previous = item.getNBTTag("display", "Name");
|
||||
Tag previous = item.getTag("display", "Name");
|
||||
if (previous != null) {
|
||||
networkData.put("display.Name", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
|
||||
@@ -53,7 +53,7 @@ public class LoreModifier<I> implements ItemDataModifier<I> {
|
||||
networkData.put(ComponentKeys.LORE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
} else {
|
||||
Tag previous = item.getNBTTag("display", "Lore");
|
||||
Tag previous = item.getTag("display", "Lore");
|
||||
if (previous != null) {
|
||||
networkData.put("display.Lore", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
|
||||
@@ -41,7 +41,7 @@ public class TagsModifier<I> implements ItemDataModifier<I> {
|
||||
@Override
|
||||
public Item<I> prepareNetworkItem(Item<I> item, ItemBuildContext context, CompoundTag networkData) {
|
||||
for (Map.Entry<String, Object> entry : this.arguments.entrySet()) {
|
||||
Tag previous = item.getNBTTag(entry.getKey());
|
||||
Tag previous = item.getTag(entry.getKey());
|
||||
if (previous != null) {
|
||||
networkData.put(entry.getKey(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
|
||||
@@ -5,15 +5,16 @@ import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
||||
import net.momirealms.craftengine.core.item.data.Trim;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
|
||||
public class TrimModifier<I> implements ItemDataModifier<I> {
|
||||
private final String material;
|
||||
private final String pattern;
|
||||
private final Key material;
|
||||
private final Key pattern;
|
||||
|
||||
public TrimModifier(String material, String pattern) {
|
||||
public TrimModifier(Key material, Key pattern) {
|
||||
this.material = material;
|
||||
this.pattern = pattern;
|
||||
}
|
||||
@@ -39,7 +40,7 @@ public class TrimModifier<I> implements ItemDataModifier<I> {
|
||||
networkData.put(ComponentKeys.TRIM.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
} else {
|
||||
Tag previous = item.getNBTTag("Trim");
|
||||
Tag previous = item.getTag("Trim");
|
||||
if (previous != null) {
|
||||
networkData.put("Trim", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
|
||||
@@ -36,7 +36,7 @@ public class UnbreakableModifier<I> implements ItemDataModifier<I> {
|
||||
networkData.put(ComponentKeys.UNBREAKABLE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
} else {
|
||||
Tag previous = item.getNBTTag("Unbreakable");
|
||||
Tag previous = item.getTag("Unbreakable");
|
||||
if (previous != null) {
|
||||
networkData.put("Unbreakable", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.RecipeInput;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class AbstractGroupedRecipe<T> implements Recipe<T> {
|
||||
public abstract class AbstractGroupedRecipe<T> implements FixedResultRecipe<T> {
|
||||
protected final String group;
|
||||
protected final Key id;
|
||||
protected final CustomRecipeResult<T> result;
|
||||
@@ -15,6 +16,11 @@ public abstract class AbstractGroupedRecipe<T> implements Recipe<T> {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T assemble(RecipeInput input, ItemBuildContext context) {
|
||||
return this.result(context);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String group() {
|
||||
return group;
|
||||
|
||||
@@ -5,6 +5,7 @@ import net.momirealms.craftengine.core.item.recipe.vanilla.VanillaRecipeReader;
|
||||
import net.momirealms.craftengine.core.item.recipe.vanilla.reader.VanillaRecipeReader1_20;
|
||||
import net.momirealms.craftengine.core.item.recipe.vanilla.reader.VanillaRecipeReader1_20_5;
|
||||
import net.momirealms.craftengine.core.item.recipe.vanilla.reader.VanillaRecipeReader1_21_2;
|
||||
import net.momirealms.craftengine.core.item.recipe.vanilla.reader.VanillaRecipeReader1_21_5;
|
||||
import net.momirealms.craftengine.core.pack.LoadingSequence;
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
@@ -41,7 +42,9 @@ public abstract class AbstractRecipeManager<T> implements RecipeManager<T> {
|
||||
}
|
||||
|
||||
private VanillaRecipeReader initVanillaRecipeReader() {
|
||||
if (VersionHelper.isOrAbove1_21_2()) {
|
||||
if (VersionHelper.isOrAbove1_21_5()) {
|
||||
return new VanillaRecipeReader1_21_5();
|
||||
} else if (VersionHelper.isOrAbove1_21_2()) {
|
||||
return new VanillaRecipeReader1_21_2();
|
||||
} else if (VersionHelper.isOrAbove1_20_5()) {
|
||||
return new VanillaRecipeReader1_20_5();
|
||||
@@ -137,7 +140,9 @@ public abstract class AbstractRecipeManager<T> implements RecipeManager<T> {
|
||||
protected void registerInternalRecipe(Key id, Recipe<T> recipe) {
|
||||
this.byType.computeIfAbsent(recipe.type(), k -> new ArrayList<>()).add(recipe);
|
||||
this.byId.put(id, recipe);
|
||||
this.byResult.computeIfAbsent(recipe.result().item().id(), k -> new ArrayList<>()).add(recipe);
|
||||
if (recipe instanceof FixedResultRecipe<?> fixedResult) {
|
||||
this.byResult.computeIfAbsent(fixedResult.result().item().id(), k -> new ArrayList<>()).add(recipe);
|
||||
}
|
||||
HashSet<Key> usedKeys = new HashSet<>();
|
||||
for (Ingredient<T> ingredient : recipe.ingredientsInUse()) {
|
||||
for (UniqueKey holder : ingredient.items()) {
|
||||
|
||||
@@ -106,7 +106,7 @@ public class CustomShapedRecipe<T> extends CustomCraftingTableRecipe<T> {
|
||||
} else {
|
||||
optional = this.ingredients.get(j + i * this.width);
|
||||
}
|
||||
OptimizedIDItem<T> itemStack = input.getItem(j, i);
|
||||
UniqueIdItem<T> itemStack = input.getItem(j, i);
|
||||
if (!Ingredient.isInstance(optional, itemStack)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class CustomSmithingTransformRecipe<T> implements Recipe<T> {
|
||||
public class CustomSmithingTransformRecipe<T> implements FixedResultRecipe<T> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
private final Key id;
|
||||
private final CustomRecipeResult<T> result;
|
||||
@@ -51,7 +51,7 @@ public class CustomSmithingTransformRecipe<T> implements Recipe<T> {
|
||||
&& checkIngredient(this.addition, smithingInput.addition());
|
||||
}
|
||||
|
||||
private boolean checkIngredient(Ingredient<T> ingredient, OptimizedIDItem<T> item) {
|
||||
private boolean checkIngredient(Ingredient<T> ingredient, UniqueIdItem<T> item) {
|
||||
if (ingredient != null) {
|
||||
if (item == null || item.isEmpty()) {
|
||||
return false;
|
||||
@@ -85,13 +85,16 @@ public class CustomSmithingTransformRecipe<T> implements Recipe<T> {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public T result(ItemBuildContext context) {
|
||||
return this.result.buildItemStack(context);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T assemble(ItemBuildContext context, Item<T> base) {
|
||||
@Override
|
||||
public T assemble(RecipeInput input, ItemBuildContext context) {
|
||||
SmithingInput<T> smithingInput = ((SmithingInput<T>) input);
|
||||
Item<T> base = smithingInput.base().item();
|
||||
T result = this.result(context);
|
||||
Item<T> wrappedResult = (Item<T>) CraftEngine.instance().itemManager().wrap(result);
|
||||
Item<T> finalResult = wrappedResult;
|
||||
@@ -104,7 +107,6 @@ public class CustomSmithingTransformRecipe<T> implements Recipe<T> {
|
||||
return finalResult.getItem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomRecipeResult<T> result() {
|
||||
return this.result;
|
||||
}
|
||||
@@ -130,6 +132,9 @@ public class CustomSmithingTransformRecipe<T> implements Recipe<T> {
|
||||
@Override
|
||||
public Recipe<A> create(Key id, Map<String, Object> arguments) {
|
||||
List<String> base = MiscUtils.getAsStringList(arguments.get("base"));
|
||||
if (base.isEmpty()) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.smithing_transform.missing_base");
|
||||
}
|
||||
List<String> addition = MiscUtils.getAsStringList(arguments.get("addition"));
|
||||
List<String> template = MiscUtils.getAsStringList(arguments.get("template-type"));
|
||||
boolean mergeComponents = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("merge-components", true), "merge-components");
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.RecipeInput;
|
||||
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.util.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class CustomSmithingTrimRecipe<T> implements Recipe<T> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
private final Key id;
|
||||
private final Ingredient<T> base;
|
||||
private final Ingredient<T> template;
|
||||
private final Ingredient<T> addition;
|
||||
@Nullable // 1.21.5
|
||||
private final Key pattern;
|
||||
|
||||
public CustomSmithingTrimRecipe(@NotNull Key id,
|
||||
@NotNull Ingredient<T> base,
|
||||
@NotNull Ingredient<T> template,
|
||||
@NotNull Ingredient<T> addition,
|
||||
@Nullable Key pattern
|
||||
) {
|
||||
this.id = id;
|
||||
this.base = base;
|
||||
this.template = template;
|
||||
this.addition = addition;
|
||||
this.pattern = pattern;
|
||||
if (pattern == null && VersionHelper.isOrAbove1_21_5()) {
|
||||
throw new IllegalStateException("SmithingTrimRecipe cannot have a null pattern on 1.21.5 and above.");
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public T assemble(RecipeInput input, ItemBuildContext context) {
|
||||
SmithingInput<T> smithingInput = (SmithingInput<T>) input;
|
||||
Item<T> processed = (Item<T>) CraftEngine.instance().itemManager().applyTrim((Item<Object>) smithingInput.base(), (Item<Object>) smithingInput.addition(), (Item<Object>) smithingInput.template(), this.pattern);
|
||||
return processed.getItem();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public boolean matches(RecipeInput input) {
|
||||
SmithingInput<T> smithingInput = (SmithingInput<T>) input;
|
||||
return checkIngredient(this.base, smithingInput.base())
|
||||
&& checkIngredient(this.template, smithingInput.template())
|
||||
&& checkIngredient(this.addition, smithingInput.addition());
|
||||
}
|
||||
|
||||
private boolean checkIngredient(Ingredient<T> ingredient, UniqueIdItem<T> item) {
|
||||
if (ingredient != null) {
|
||||
if (item == null || item.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return ingredient.test(item);
|
||||
} else {
|
||||
return item == null || item.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Ingredient<T>> ingredientsInUse() {
|
||||
List<Ingredient<T>> ingredients = new ArrayList<>();
|
||||
ingredients.add(this.base);
|
||||
ingredients.add(this.template);
|
||||
ingredients.add(this.addition);
|
||||
return ingredients;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Key type() {
|
||||
return RecipeTypes.SMITHING_TRIM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key id() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Ingredient<T> base() {
|
||||
return this.base;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Ingredient<T> template() {
|
||||
return template;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Ingredient<T> addition() {
|
||||
return addition;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Key pattern() {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"DuplicatedCode"})
|
||||
public static class Factory<A> implements RecipeFactory<A> {
|
||||
|
||||
@Override
|
||||
public Recipe<A> create(Key id, Map<String, Object> arguments) {
|
||||
List<String> base = MiscUtils.getAsStringList(arguments.get("base"));
|
||||
if (base.isEmpty()) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.smithing_trim.missing_base");
|
||||
}
|
||||
List<String> addition = MiscUtils.getAsStringList(arguments.get("addition"));
|
||||
if (addition.isEmpty()) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.smithing_trim.missing_addition");
|
||||
}
|
||||
List<String> template = MiscUtils.getAsStringList(arguments.get("template-type"));
|
||||
if (template.isEmpty()) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.smithing_trim.missing_template_type");
|
||||
}
|
||||
Key pattern = VersionHelper.isOrAbove1_21_5() ? Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("pattern"), "warning.config.recipe.smithing_trim.missing_pattern")) : null;
|
||||
return new CustomSmithingTrimRecipe<>(id, toIngredient(base), toIngredient(template), toIngredient(addition), pattern);
|
||||
}
|
||||
|
||||
private Ingredient<A> toIngredient(List<String> items) {
|
||||
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(UniqueKey.create(Key.of(item)));
|
||||
}
|
||||
}
|
||||
return Ingredient.of(holders);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
|
||||
public interface FixedResultRecipe<T> extends Recipe<T> {
|
||||
|
||||
T result(ItemBuildContext context);
|
||||
|
||||
CustomRecipeResult<T> result();
|
||||
}
|
||||
@@ -5,14 +5,14 @@ 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<UniqueKey> {
|
||||
public class Ingredient<T> implements Predicate<UniqueIdItem<T>>, StackedContents.IngredientInfo<UniqueKey> {
|
||||
private final List<UniqueKey> items;
|
||||
|
||||
public Ingredient(List<UniqueKey> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
public static <T> boolean isInstance(Optional<Ingredient<T>> optionalIngredient, OptimizedIDItem<T> stack) {
|
||||
public static <T> boolean isInstance(Optional<Ingredient<T>> optionalIngredient, UniqueIdItem<T> stack) {
|
||||
return optionalIngredient.map((ingredient) -> ingredient.test(stack))
|
||||
.orElseGet(stack::isEmpty);
|
||||
}
|
||||
@@ -26,9 +26,9 @@ public class Ingredient<T> implements Predicate<OptimizedIDItem<T>>, StackedCont
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(OptimizedIDItem<T> optimizedIDItem) {
|
||||
public boolean test(UniqueIdItem<T> uniqueIdItem) {
|
||||
for (UniqueKey item : this.items()) {
|
||||
if (optimizedIDItem.is(item)) {
|
||||
if (uniqueIdItem.is(item)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
|
||||
public class OptimizedIDItem<T> {
|
||||
private final T rawItem;
|
||||
private final UniqueKey uniqueId;
|
||||
|
||||
public OptimizedIDItem(UniqueKey uniqueId, T rawItem) {
|
||||
this.uniqueId = uniqueId;
|
||||
this.rawItem = rawItem;
|
||||
}
|
||||
|
||||
public UniqueKey id() {
|
||||
return uniqueId;
|
||||
}
|
||||
|
||||
public T rawItem() {
|
||||
return rawItem;
|
||||
}
|
||||
|
||||
public boolean is(UniqueKey id) {
|
||||
return uniqueId == id;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return uniqueId == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "OptimizedIDItem{" +
|
||||
"uniqueId=" + uniqueId +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -11,9 +11,7 @@ public interface Recipe<T> {
|
||||
|
||||
boolean matches(RecipeInput input);
|
||||
|
||||
T result(ItemBuildContext context);
|
||||
|
||||
CustomRecipeResult<T> result();
|
||||
T assemble(RecipeInput input, ItemBuildContext context);
|
||||
|
||||
List<Ingredient<T>> ingredientsInUse();
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import java.util.List;
|
||||
public class RecipeFinder {
|
||||
private final StackedContents<UniqueKey> stackedContents = new StackedContents<>();
|
||||
|
||||
public <T> void addInput(OptimizedIDItem<T> item) {
|
||||
public <T> void addInput(UniqueIdItem<T> item) {
|
||||
if (!item.isEmpty()) {
|
||||
this.stackedContents.add(item.id(), 1);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ public class RecipeTypes {
|
||||
register(CAMPFIRE_COOKING, CustomCampfireRecipe.FACTORY);
|
||||
register(STONECUTTING, CustomStoneCuttingRecipe.FACTORY);
|
||||
register(SMITHING_TRANSFORM, CustomSmithingTransformRecipe.FACTORY);
|
||||
register(SMITHING_TRIM, CustomSmithingTrimRecipe.FACTORY);
|
||||
}
|
||||
|
||||
public static <T> void register(Key key, RecipeFactory<T> factory) {
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class UniqueIdItem<T> {
|
||||
private final Item<T> rawItem;
|
||||
private final UniqueKey uniqueId;
|
||||
|
||||
public UniqueIdItem(@NotNull UniqueKey uniqueId, @NotNull Item<T> rawItem) {
|
||||
this.uniqueId = uniqueId;
|
||||
this.rawItem = rawItem;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public UniqueKey id() {
|
||||
return uniqueId;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Item<T> item() {
|
||||
return this.rawItem;
|
||||
}
|
||||
|
||||
public boolean is(UniqueKey id) {
|
||||
return this.uniqueId == id;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.uniqueId == UniqueKey.AIR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UniqueIdItem[" + "uniqueId=" + uniqueId + ", item=" + rawItem.getItem() + ']';
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.input;
|
||||
|
||||
import net.momirealms.craftengine.core.item.recipe.OptimizedIDItem;
|
||||
import net.momirealms.craftengine.core.item.recipe.RecipeFinder;
|
||||
import net.momirealms.craftengine.core.item.recipe.UniqueIdItem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -10,16 +10,16 @@ import java.util.List;
|
||||
public class CraftingInput<T> implements RecipeInput {
|
||||
private final int width;
|
||||
private final int height;
|
||||
private final List<OptimizedIDItem<T>> items;
|
||||
private final List<UniqueIdItem<T>> items;
|
||||
private final int ingredientCount;
|
||||
private final RecipeFinder finder = new RecipeFinder();
|
||||
|
||||
private CraftingInput(int width, int height, List<OptimizedIDItem<T>> items) {
|
||||
private CraftingInput(int width, int height, List<UniqueIdItem<T>> items) {
|
||||
this.height = height;
|
||||
this.width = width;
|
||||
this.items = items;
|
||||
int i = 0;
|
||||
for (OptimizedIDItem<T> item : items) {
|
||||
for (UniqueIdItem<T> item : items) {
|
||||
if (!item.isEmpty()) {
|
||||
i++;
|
||||
this.finder.addInput(item);
|
||||
@@ -32,7 +32,7 @@ public class CraftingInput<T> implements RecipeInput {
|
||||
return finder;
|
||||
}
|
||||
|
||||
public static <T> CraftingInput<T> of(int width, int height, List<OptimizedIDItem<T>> stacks) {
|
||||
public static <T> CraftingInput<T> of(int width, int height, List<UniqueIdItem<T>> stacks) {
|
||||
if (width <= 0 || height <= 0) {
|
||||
return new CraftingInput<>(0, 0, Collections.emptyList());
|
||||
}
|
||||
@@ -43,7 +43,7 @@ public class CraftingInput<T> implements RecipeInput {
|
||||
int maxRow = -1;
|
||||
|
||||
for (int index = 0; index < width * height; index++) {
|
||||
OptimizedIDItem<T> item = stacks.get(index);
|
||||
UniqueIdItem<T> item = stacks.get(index);
|
||||
if (!item.isEmpty()) {
|
||||
int row = index / width;
|
||||
int col = index % width;
|
||||
@@ -65,7 +65,7 @@ public class CraftingInput<T> implements RecipeInput {
|
||||
return new CraftingInput<>(width, height, stacks);
|
||||
}
|
||||
|
||||
List<OptimizedIDItem<T>> trimmed = new ArrayList<>(newWidth * newHeight);
|
||||
List<UniqueIdItem<T>> trimmed = new ArrayList<>(newWidth * newHeight);
|
||||
for (int row = minRow; row <= maxRow; row++) {
|
||||
for (int col = minCol; col <= maxCol; col++) {
|
||||
int originalIndex = col + row * width;
|
||||
@@ -92,11 +92,11 @@ public class CraftingInput<T> implements RecipeInput {
|
||||
return items.size();
|
||||
}
|
||||
|
||||
public OptimizedIDItem<T> getItem(int x, int y) {
|
||||
public UniqueIdItem<T> getItem(int x, int y) {
|
||||
return this.items.get(x + y * width);
|
||||
}
|
||||
|
||||
public OptimizedIDItem<T> getItem(int index) {
|
||||
public UniqueIdItem<T> getItem(int index) {
|
||||
return this.items.get(index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.input;
|
||||
|
||||
import net.momirealms.craftengine.core.item.recipe.OptimizedIDItem;
|
||||
import net.momirealms.craftengine.core.item.recipe.UniqueIdItem;
|
||||
|
||||
public record SingleItemInput<T>(OptimizedIDItem<T> input) implements RecipeInput {
|
||||
public record SingleItemInput<T>(UniqueIdItem<T> input) implements RecipeInput {
|
||||
}
|
||||
|
||||
@@ -1,33 +1,34 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.input;
|
||||
|
||||
import net.momirealms.craftengine.core.item.recipe.OptimizedIDItem;
|
||||
import net.momirealms.craftengine.core.item.recipe.UniqueIdItem;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class SmithingInput<T> implements RecipeInput {
|
||||
private final OptimizedIDItem<T> base;
|
||||
private final OptimizedIDItem<T> template;
|
||||
private final OptimizedIDItem<T> addition;
|
||||
private final UniqueIdItem<T> base;
|
||||
private final UniqueIdItem<T> template;
|
||||
private final UniqueIdItem<T> addition;
|
||||
|
||||
public SmithingInput(@Nullable OptimizedIDItem<T> base,
|
||||
@Nullable OptimizedIDItem<T> template,
|
||||
@Nullable OptimizedIDItem<T> addition) {
|
||||
public SmithingInput(@NotNull UniqueIdItem<T> base,
|
||||
@Nullable UniqueIdItem<T> template,
|
||||
@Nullable UniqueIdItem<T> addition) {
|
||||
this.base = base;
|
||||
this.template = template;
|
||||
this.addition = addition;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public OptimizedIDItem<T> base() {
|
||||
@NotNull
|
||||
public UniqueIdItem<T> base() {
|
||||
return base;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public OptimizedIDItem<T> template() {
|
||||
public UniqueIdItem<T> template() {
|
||||
return template;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public OptimizedIDItem<T> addition() {
|
||||
public UniqueIdItem<T> addition() {
|
||||
return addition;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ public abstract class VanillaGroupedRecipe implements VanillaRecipe {
|
||||
return group;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeResult result() {
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,4 @@ import net.momirealms.craftengine.core.util.Key;
|
||||
public interface VanillaRecipe {
|
||||
|
||||
Key type();
|
||||
|
||||
RecipeResult result();
|
||||
}
|
||||
|
||||
@@ -19,4 +19,6 @@ public interface VanillaRecipeReader {
|
||||
VanillaStoneCuttingRecipe readStoneCutting(JsonObject json);
|
||||
|
||||
VanillaSmithingTransformRecipe readSmithingTransform(JsonObject json);
|
||||
|
||||
VanillaSmithingTrimRecipe readSmithingTrim(JsonObject json);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ public class VanillaSmithingTransformRecipe implements VanillaRecipe {
|
||||
return RecipeTypes.SMITHING_TRANSFORM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeResult result() {
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.vanilla;
|
||||
|
||||
import net.momirealms.craftengine.core.item.recipe.RecipeTypes;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class VanillaSmithingTrimRecipe implements VanillaRecipe {
|
||||
@Nullable // 1.21.5
|
||||
private final String pattern;
|
||||
|
||||
private final List<String> base;
|
||||
private final List<String> template;
|
||||
private final List<String> addition;
|
||||
|
||||
public VanillaSmithingTrimRecipe(List<String> base, List<String> template, List<String> addition, @Nullable String pattern) {
|
||||
this.base = base;
|
||||
this.template = template;
|
||||
this.addition = addition;
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
return RecipeTypes.SMITHING_TRIM;
|
||||
}
|
||||
|
||||
public List<String> base() {
|
||||
return base;
|
||||
}
|
||||
|
||||
public List<String> template() {
|
||||
return template;
|
||||
}
|
||||
|
||||
public List<String> addition() {
|
||||
return addition;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String pattern() {
|
||||
return pattern;
|
||||
}
|
||||
}
|
||||
@@ -101,6 +101,16 @@ public class VanillaRecipeReader1_20 extends AbstractRecipeReader {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VanillaSmithingTrimRecipe readSmithingTrim(JsonObject json) {
|
||||
return new VanillaSmithingTrimRecipe(
|
||||
readSingleIngredient(json.get("base")),
|
||||
readSingleIngredient(json.get("template")),
|
||||
readSingleIngredient(json.get("addition")),
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
protected List<String> readSingleIngredient(JsonElement json) {
|
||||
List<String> ingredients = new ArrayList<>();
|
||||
if (json.isJsonObject()) {
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.vanilla.reader;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.item.recipe.vanilla.VanillaSmithingTrimRecipe;
|
||||
|
||||
public class VanillaRecipeReader1_21_5 extends VanillaRecipeReader1_21_2 {
|
||||
|
||||
@Override
|
||||
public VanillaSmithingTrimRecipe readSmithingTrim(JsonObject json) {
|
||||
return new VanillaSmithingTrimRecipe(
|
||||
readSingleIngredient(json.get("base")),
|
||||
readSingleIngredient(json.get("template")),
|
||||
readSingleIngredient(json.get("addition")),
|
||||
json.get("pattern").getAsString()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.momirealms.craftengine.core.util;
|
||||
|
||||
import net.momirealms.craftengine.core.item.ItemKeys;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -7,6 +8,8 @@ import java.util.Map;
|
||||
|
||||
public final class UniqueKey {
|
||||
private static final Map<Key, UniqueKey> CACHE = new HashMap<>(4096, 0.5f);
|
||||
public static final UniqueKey AIR = UniqueKey.create(ItemKeys.AIR);
|
||||
|
||||
private final Key key;
|
||||
|
||||
private UniqueKey(Key key) {
|
||||
@@ -23,6 +26,11 @@ public final class UniqueKey {
|
||||
}
|
||||
|
||||
public Key key() {
|
||||
return key;
|
||||
return this.key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.key.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G
|
||||
|
||||
# Project settings
|
||||
# Rule: [major update].[feature update].[bug fix]
|
||||
project_version=0.0.59.8
|
||||
project_version=0.0.59.9
|
||||
config_version=41
|
||||
lang_version=22
|
||||
project_group=net.momirealms
|
||||
@@ -23,10 +23,10 @@ jar_relocator_version=1.7
|
||||
adventure_bundle_version=4.23.0
|
||||
cloud_core_version=2.0.0
|
||||
cloud_services_version=2.0.0
|
||||
cloud_brigadier_version=2.0.0-beta.10
|
||||
cloud_bukkit_version=2.0.0-beta.10
|
||||
cloud_paper_version=2.0.0-beta.10
|
||||
cloud_minecraft_extras_version=2.0.0-beta.10
|
||||
cloud_brigadier_version=2.0.0-beta.11
|
||||
cloud_bukkit_version=2.0.0-beta.11
|
||||
cloud_paper_version=2.0.0-beta.11
|
||||
cloud_minecraft_extras_version=2.0.0-beta.11
|
||||
boosted_yaml_version=1.3.7
|
||||
bstats_version=3.1.0
|
||||
caffeine_version=3.2.0
|
||||
@@ -50,7 +50,7 @@ byte_buddy_version=1.17.5
|
||||
ahocorasick_version=0.6.3
|
||||
snake_yaml_version=2.4
|
||||
anti_grief_version=0.18
|
||||
nms_helper_version=1.0.30
|
||||
nms_helper_version=1.0.32
|
||||
evalex_version=3.5.0
|
||||
reactive_streams_version=1.0.4
|
||||
amazon_awssdk_version=2.31.23
|
||||
|
||||
Reference in New Issue
Block a user