Skip to content

Commit

Permalink
Almost fixed recipe issues
Browse files Browse the repository at this point in the history
  • Loading branch information
LatvianModder committed Jun 11, 2024
1 parent fbb99d0 commit cf02150
Show file tree
Hide file tree
Showing 27 changed files with 413 additions and 126 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,18 @@
import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType;
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import com.mojang.serialization.DynamicOps;
import dev.latvian.mods.kubejs.script.KubeJSContext;
import dev.latvian.mods.kubejs.util.Cast;
import dev.latvian.mods.rhino.Context;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.component.DataComponentMap;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.component.DataComponentType;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.NbtOps;
import net.minecraft.nbt.Tag;
import net.minecraft.nbt.TagParser;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.RegistryOps;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.component.CustomData;

Expand All @@ -27,7 +25,7 @@ public interface DataComponentWrapper {
Dynamic2CommandExceptionType ERROR_MALFORMED_COMPONENT = new Dynamic2CommandExceptionType((object, object2) -> Component.translatableEscape("arguments.item.component.malformed", object, object2));
SimpleCommandExceptionType ERROR_EXPECTED_COMPONENT = new SimpleCommandExceptionType(Component.translatable("arguments.item.component.expected"));

static DataComponentMap readMap(RegistryOps<Tag> registryOps, StringReader reader) throws CommandSyntaxException {
static DataComponentMap readMap(DynamicOps<Tag> registryOps, StringReader reader) throws CommandSyntaxException {
reader.skipWhitespace();
DataComponentMap.Builder builder = null;

Expand Down Expand Up @@ -81,7 +79,7 @@ static DataComponentMap readMap(RegistryOps<Tag> registryOps, StringReader reade
return builder == null ? DataComponentMap.EMPTY : builder.build();
}

static DataComponentPatch readPatch(RegistryOps<Tag> registryOps, StringReader reader) throws CommandSyntaxException {
static DataComponentPatch readPatch(DynamicOps<Tag> registryOps, StringReader reader) throws CommandSyntaxException {
reader.skipWhitespace();
DataComponentPatch.Builder builder = null;

Expand Down Expand Up @@ -153,7 +151,7 @@ static DataComponentType<?> readComponentType(StringReader stringReader) throws

static DataComponentMap mapOf(Context cx, Object o) {
try {
return readMap(((KubeJSContext) cx).getRegistries().createSerializationContext(NbtOps.INSTANCE), new StringReader(o.toString()));
return readMap(((KubeJSContext) cx).getNbtRegistryOps(), new StringReader(o.toString()));
} catch (CommandSyntaxException ex) {
((KubeJSContext) cx).getConsole().error("Error parsing DataComponentMap", ex);
return DataComponentMap.EMPTY;
Expand All @@ -162,15 +160,14 @@ static DataComponentMap mapOf(Context cx, Object o) {

static DataComponentPatch patchOf(Context cx, Object o) {
try {
return readPatch(((KubeJSContext) cx).getRegistries().createSerializationContext(NbtOps.INSTANCE), new StringReader(o.toString()));
return readPatch(((KubeJSContext) cx).getNbtRegistryOps(), new StringReader(o.toString()));
} catch (CommandSyntaxException ex) {
((KubeJSContext) cx).getConsole().error("Error parsing DataComponentPatch", ex);
return DataComponentPatch.EMPTY;
}
}

static StringBuilder mapToString(StringBuilder builder, HolderLookup.Provider registries, DataComponentMap map) {
var dynamicOps = registries.createSerializationContext(NbtOps.INSTANCE);
static StringBuilder mapToString(StringBuilder builder, DynamicOps<Tag> dynamicOps, DataComponentMap map) {
builder.append('[');

boolean first = true;
Expand All @@ -194,8 +191,7 @@ static StringBuilder mapToString(StringBuilder builder, HolderLookup.Provider re
return builder;
}

static StringBuilder patchToString(StringBuilder builder, HolderLookup.Provider registries, DataComponentPatch patch) {
var dynamicOps = registries.createSerializationContext(NbtOps.INSTANCE);
static StringBuilder patchToString(StringBuilder builder, DynamicOps<Tag> dynamicOps, DataComponentPatch patch) {
builder.append('[');

boolean first = true;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
package dev.latvian.mods.kubejs.bindings;

import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.serialization.DynamicOps;
import dev.latvian.mods.kubejs.item.ingredient.IngredientJS;
import dev.latvian.mods.kubejs.script.KubeJSContext;
import dev.latvian.mods.kubejs.typings.Info;
import dev.latvian.mods.rhino.Context;
import net.minecraft.nbt.Tag;
import net.minecraft.tags.TagKey;
import net.minecraft.util.Mth;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.level.ItemLike;
import net.neoforged.neoforge.common.crafting.SizedIngredient;

@Info("Various SizedIngredient related helper methods")
public interface SizedIngredientWrapper {
@Info("A completely empty ingredient that will only match air")
SizedIngredient none = new SizedIngredient(Ingredient.EMPTY, 1);
SizedIngredient empty = new SizedIngredient(Ingredient.EMPTY, 1);
@Info("An ingredient that matches everything")
SizedIngredient all = new SizedIngredient(IngredientWrapper.all, 1);

Expand All @@ -24,6 +33,38 @@ static SizedIngredient ofTag(TagKey<Item> tag, int count) {
}

static SizedIngredient wrap(Context cx, Object from) {
return none;
if (from instanceof SizedIngredient s) {
return s;
} else if (from instanceof Ingredient ingredient) {
return new SizedIngredient(ingredient, 1);
} else if (from instanceof ItemStack stack) {
return new SizedIngredient(Ingredient.of(stack.kjs$withCount(1)), stack.getCount());
} else if (from instanceof ItemLike item) {
return new SizedIngredient(Ingredient.of(item), 1);
} else if (from instanceof CharSequence) {
try {
return read(((KubeJSContext) cx).getNbtRegistryOps(), new StringReader(from.toString()));
} catch (Exception ex) {
return empty;
}
}

return empty;
}

static SizedIngredient read(DynamicOps<Tag> registryOps, StringReader reader) throws CommandSyntaxException {
int count = 1;

if (StringReader.isAllowedNumber(reader.peek())) {
count = Mth.ceil(reader.readDouble());
reader.expect('x');
reader.skipWhitespace();

if (count < 1) {
throw new IllegalArgumentException("SizedIngredient count smaller than 1 is not allowed!");
}
}

return new SizedIngredient(IngredientJS.read(registryOps, reader), count);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtOps;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.network.chat.ClickEvent;
import net.minecraft.network.chat.Component;
Expand Down Expand Up @@ -543,7 +544,7 @@ private static int hand(ServerPlayer player, InteractionHand hand) {

// item info
// id
player.sendSystemMessage(copy(stack.kjs$toItemString0(player.server.registryAccess()), ChatFormatting.GREEN, "Item ID"));
player.sendSystemMessage(copy(stack.kjs$toItemString0(player.server.registryAccess().createSerializationContext(NbtOps.INSTANCE)), ChatFormatting.GREEN, "Item ID"));
// item tags
var itemTags = holder.tags().toList();
for (var tag : itemTags) {
Expand Down Expand Up @@ -604,8 +605,8 @@ private static int hotbar(ServerPlayer player) {
}

private static int dump(List<ItemStack> stacks, ServerPlayer player, String name) {
var registries = player.server.registryAccess();
var dump = stacks.stream().filter(is -> !is.isEmpty()).map(is -> is.kjs$toItemString0(registries)).toList();
var ops = player.server.registryAccess().createSerializationContext(NbtOps.INSTANCE);
var dump = stacks.stream().filter(is -> !is.isEmpty()).map(is -> is.kjs$toItemString0(ops)).toList();
player.sendSystemMessage(copy(dump.toString(), ChatFormatting.WHITE, name + " Item List"));
return 1;
}
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/dev/latvian/mods/kubejs/core/IngredientKJS.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import dev.latvian.mods.kubejs.item.ItemStackJS;
import dev.latvian.mods.kubejs.item.ItemStackSet;
import dev.latvian.mods.kubejs.recipe.InputReplacement;
import dev.latvian.mods.kubejs.recipe.KubeRecipe;
import dev.latvian.mods.kubejs.recipe.ReplacementMatch;
import dev.latvian.mods.kubejs.util.WithCodec;
import dev.latvian.mods.rhino.Context;
import dev.latvian.mods.rhino.util.RemapPrefixForJS;
Expand Down Expand Up @@ -129,4 +131,13 @@ public interface IngredientKJS extends IngredientSupplierKJS, InputReplacement,
default Codec<?> getCodec(Context cx) {
return Ingredient.CODEC;
}

@Override
default Object replaceInput(Context cx, KubeRecipe recipe, ReplacementMatch match, InputReplacement original) {
if (original instanceof SizedIngredientKJS s) {
return new SizedIngredient(kjs$self(), s.kjs$self().count());
}

return this;
}
}
13 changes: 7 additions & 6 deletions src/main/java/dev/latvian/mods/kubejs/core/ItemStackKJS.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.latvian.mods.kubejs.core;

import com.mojang.serialization.Codec;
import com.mojang.serialization.DynamicOps;
import dev.latvian.mods.kubejs.bindings.DataComponentWrapper;
import dev.latvian.mods.kubejs.item.ChancedItem;
import dev.latvian.mods.kubejs.item.ItemStackJS;
Expand All @@ -19,11 +20,11 @@
import dev.latvian.mods.rhino.util.SpecialEquality;
import dev.latvian.mods.rhino.util.ToStringJS;
import net.minecraft.core.Holder;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.component.DataComponentMap;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.component.DataComponentType;
import net.minecraft.core.component.DataComponents;
import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
Expand Down Expand Up @@ -126,7 +127,7 @@ default boolean specialEquals(Context cx, Object o, boolean shallow) {
}

default String kjs$getComponentString(KubeJSContext cx) {
return DataComponentWrapper.patchToString(new StringBuilder(), cx.getRegistries(), kjs$self().getComponentsPatch()).toString();
return DataComponentWrapper.patchToString(new StringBuilder(), cx.getNbtRegistryOps(), kjs$self().getComponentsPatch()).toString();
}

@ReturnsSelf
Expand Down Expand Up @@ -238,14 +239,14 @@ default boolean specialEquals(Context cx, Object o, boolean shallow) {

@Override
default String toStringJS(Context cx) {
return kjs$toItemString0(((KubeJSContext) cx).getRegistries());
return kjs$toItemString0(((KubeJSContext) cx).getNbtRegistryOps());
}

default String kjs$toItemString(KubeJSContext cx) {
return kjs$toItemString0(cx.getRegistries());
return kjs$toItemString0(cx.getNbtRegistryOps());
}

default String kjs$toItemString0(HolderLookup.Provider registries) {
default String kjs$toItemString0(DynamicOps<Tag> dynamicOps) {
var is = kjs$self();
var count = is.getCount();

Expand All @@ -264,7 +265,7 @@ default String toStringJS(Context cx) {
builder.append(kjs$getId());

if (!is.isComponentsPatchEmpty()) {
DataComponentWrapper.patchToString(builder, registries, is.getComponentsPatch());
DataComponentWrapper.patchToString(builder, dynamicOps, is.getComponentsPatch());
}

builder.append('\'');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import dev.latvian.mods.kubejs.recipe.KubeRecipe;
import dev.latvian.mods.kubejs.recipe.ReplacementMatch;
import dev.latvian.mods.rhino.Context;
import net.minecraft.world.item.crafting.Ingredient;
import net.neoforged.neoforge.common.crafting.SizedIngredient;

public interface SizedIngredientKJS extends InputReplacement {
Expand All @@ -13,8 +14,10 @@ public interface SizedIngredientKJS extends InputReplacement {

@Override
default Object replaceInput(Context cx, KubeRecipe recipe, ReplacementMatch match, InputReplacement original) {
if ((Object) original instanceof SizedIngredient o) {
return new SizedIngredient(kjs$self().ingredient(), o.count());
if (original instanceof SizedIngredientKJS o) {
return new SizedIngredient(kjs$self().ingredient(), o.kjs$self().count());
} else if (original instanceof Ingredient) {
return kjs$self().ingredient();
}

return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ public abstract class ReloadableServerResourcesMixin implements ReloadableServer

@Inject(method = "<init>", at = @At("RETURN"))
private void init(RegistryAccess.Frozen registryAccess, FeatureFlagSet featureFlagSet, Commands.CommandSelection commandSelection, int functionCompilationLevel, CallbackInfo ci) {
UtilsJS.staticRegistries = registryAccess;
kjs$serverScriptManager = new ServerScriptManager((ReloadableServerResources) (Object) this, registryAccess);
UtilsJS.staticRegistries = kjs$serverScriptManager.registries;
UtilsJS.staticNbtRegistryOps = kjs$serverScriptManager.nbtRegistryOps;
UtilsJS.staticJsonRegistryOps = kjs$serverScriptManager.jsonRegistryOps;
tagManager.kjs$setResources(this);
recipes.kjs$setResources(this);
kjs$serverScriptManager.reload();
Expand Down
21 changes: 11 additions & 10 deletions src/main/java/dev/latvian/mods/kubejs/helpers/IngredientHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
import dev.latvian.mods.kubejs.ingredient.ModIngredient;
import dev.latvian.mods.kubejs.ingredient.RegExIngredient;
import dev.latvian.mods.kubejs.ingredient.WildcardIngredient;
import dev.latvian.mods.kubejs.util.ID;
import dev.latvian.mods.kubejs.util.Tags;
import net.minecraft.core.HolderSet;
import net.minecraft.core.component.DataComponentMap;
import net.minecraft.core.component.DataComponentPredicate;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.crafting.Ingredient;
import net.neoforged.neoforge.common.crafting.CompoundIngredient;
import net.neoforged.neoforge.common.crafting.DataComponentIngredient;
Expand All @@ -34,8 +35,8 @@ public Ingredient wildcard() {
return WildcardIngredient.INSTANCE.toVanilla();
}

public Ingredient tag(String tag) {
return Ingredient.of(Tags.item(ID.mc(tag)));
public Ingredient tag(ResourceLocation tag) {
return Ingredient.of(Tags.item(tag));
}

public Ingredient mod(String mod) {
Expand All @@ -62,16 +63,16 @@ public Ingredient and(Ingredient[] ingredients) {
return ingredients.length == 0 ? Ingredient.EMPTY : ingredients.length == 1 ? ingredients[0] : IntersectionIngredient.of(ingredients);
}

public Ingredient matchComponents(ItemStack item, boolean strong) {
return new DataComponentIngredient(HolderSet.direct(item.getItemHolder()), DataComponentPredicate.allOf(item.getComponents()), strong).toVanilla();
public Ingredient matchComponents(Item item, DataComponentMap map, boolean strong) {
return new DataComponentIngredient(HolderSet.direct(item.builtInRegistryHolder()), DataComponentPredicate.allOf(map), strong).toVanilla();
}

public Ingredient strongComponents(ItemStack item) {
return matchComponents(item, true);
public Ingredient strongComponents(Item item, DataComponentMap map) {
return matchComponents(item, map, true);
}

public Ingredient weakComponents(ItemStack item) {
return matchComponents(item, false);
public Ingredient weakComponents(Item item, DataComponentMap map) {
return matchComponents(item, map, false);
}

public boolean isWildcard(Ingredient ingredient) {
Expand Down
40 changes: 34 additions & 6 deletions src/main/java/dev/latvian/mods/kubejs/helpers/RecipeHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import com.google.gson.JsonObject;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.DynamicOps;
import dev.latvian.mods.kubejs.recipe.RecipesKubeEvent;
import dev.latvian.mods.kubejs.util.ConsoleJS;
import net.minecraft.resources.RegistryOps;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.GsonHelper;
import net.minecraft.world.item.crafting.RecipeHolder;
Expand All @@ -23,19 +23,47 @@ public static RecipeHelper get() {
}

@Nullable
public RecipeHolder<?> fromJson(RegistryOps<JsonElement> ops, RecipeSerializer<?> serializer, ResourceLocation id, JsonObject json) {
public RecipeHolder<?> fromJson(DynamicOps<JsonElement> ops, RecipeSerializer<?> serializer, ResourceLocation id, JsonObject json) {
try {
return new RecipeHolder<>(id, serializer.codec().decode(ops, ops.getMap(json).result().get()).getOrThrow());
var map = ops.getMap(json).result();

if (map.isEmpty()) {
if (!FMLLoader.isProduction()) {
ConsoleJS.SERVER.error("Error parsing recipe " + id + ": Couldn't convert " + json + " to a map");
}

return null;
}

var codec = serializer.codec();

if (codec == null) {
if (!FMLLoader.isProduction()) {
ConsoleJS.SERVER.error("Error parsing recipe " + id + ": Codec not found in " + serializer.getClass().getName());
}

return null;
}

var recipe = codec.decode(ops, map.get());

if (recipe.error().isPresent()) {
if (!FMLLoader.isProduction()) {
ConsoleJS.SERVER.error("Error parsing recipe " + id + ": " + recipe.error().get().message());
}
} else if (recipe.isSuccess()) {
return new RecipeHolder<>(id, recipe.getOrThrow());
}
} catch (Exception e) {
if (!FMLLoader.isProduction()) {
ConsoleJS.SERVER.error("Error parsing recipe " + id, e, RecipesKubeEvent.CREATE_RECIPE_SKIP_ERROR);
}

return null;
}

return null;
}

public DataResult<JsonObject> validate(RegistryOps<JsonElement> ops, JsonElement jsonElement) {
public DataResult<JsonObject> validate(DynamicOps<JsonElement> ops, JsonElement jsonElement) {
if (!jsonElement.isJsonObject()) {
return DataResult.error(() -> "not a json object: " + jsonElement);
}
Expand Down
Loading

0 comments on commit cf02150

Please sign in to comment.