diff --git a/src/main/java/dev/latvian/mods/kubejs/BuiltinKubeJSPlugin.java b/src/main/java/dev/latvian/mods/kubejs/BuiltinKubeJSPlugin.java index e890dd540..798917178 100644 --- a/src/main/java/dev/latvian/mods/kubejs/BuiltinKubeJSPlugin.java +++ b/src/main/java/dev/latvian/mods/kubejs/BuiltinKubeJSPlugin.java @@ -135,6 +135,7 @@ import dev.latvian.mods.kubejs.util.ID; import dev.latvian.mods.kubejs.util.JsonIO; import dev.latvian.mods.kubejs.util.JsonUtils; +import dev.latvian.mods.kubejs.util.KubeResourceLocation; import dev.latvian.mods.kubejs.util.ListJS; import dev.latvian.mods.kubejs.util.MapJS; import dev.latvian.mods.kubejs.util.NBTIOWrapper; @@ -532,6 +533,7 @@ public void registerTypeWrappers(TypeWrapperRegistry registry) { registry.register(Duration.class, TimeJS::durationOf); registry.register(ResourceLocation.class, ID::mc); + registry.register(KubeResourceLocation.class, KubeResourceLocation::wrap); registry.register(CompoundTag.class, (from, target) -> NBTUtils.isTagCompound(from), NBTUtils::toTagCompound); registry.register(CollectionTag.class, (from, target) -> NBTUtils.isTagCollection(from), NBTUtils::toTagCollection); registry.register(ListTag.class, (from, target) -> NBTUtils.isTagCollection(from), NBTUtils::toTagList); diff --git a/src/main/java/dev/latvian/mods/kubejs/holder/HolderWrapper.java b/src/main/java/dev/latvian/mods/kubejs/holder/HolderWrapper.java index 83d03ebe7..98ee48645 100644 --- a/src/main/java/dev/latvian/mods/kubejs/holder/HolderWrapper.java +++ b/src/main/java/dev/latvian/mods/kubejs/holder/HolderWrapper.java @@ -1,6 +1,7 @@ package dev.latvian.mods.kubejs.holder; import dev.latvian.mods.kubejs.script.KubeJSContext; +import dev.latvian.mods.kubejs.util.Cast; import dev.latvian.mods.kubejs.util.ID; import dev.latvian.mods.kubejs.util.RegExpKJS; import dev.latvian.mods.rhino.Context; @@ -20,9 +21,26 @@ public interface HolderWrapper { static Holder wrap(KubeJSContext cx, Object from, TypeInfo param) { if (from instanceof Holder h) { return h; + } else if (from == null) { + throw Context.reportRuntimeError("Can't interpret 'null' as a Holder", cx); } var registry = cx.lookupRegistry(param, from); + + if (!ID.isKey(from)) { + var h = registry.wrapAsHolder(Cast.to(from)); + + if (h instanceof Holder.Direct) { + var baseClass = cx.lookupRegistryType(param, from).baseClass(); + + if (!baseClass.isInstance(from)) { + throw Context.reportRuntimeError("Can't interpret '" + from + "' as Holder: can't cast object to '" + baseClass.getName() + "' of " + registry.key().location(), cx); + } + } + + return h; + } + var id = ID.mc(from); var holder = registry.getHolder(id); diff --git a/src/main/java/dev/latvian/mods/kubejs/item/ItemModelPropertiesKubeEvent.java b/src/main/java/dev/latvian/mods/kubejs/item/ItemModelPropertiesKubeEvent.java index 36e90d85c..c025c2d05 100644 --- a/src/main/java/dev/latvian/mods/kubejs/item/ItemModelPropertiesKubeEvent.java +++ b/src/main/java/dev/latvian/mods/kubejs/item/ItemModelPropertiesKubeEvent.java @@ -2,7 +2,7 @@ import dev.latvian.mods.kubejs.event.KubeStartupEvent; import dev.latvian.mods.kubejs.typings.Info; -import dev.latvian.mods.kubejs.util.ID; +import dev.latvian.mods.kubejs.util.KubeResourceLocation; import net.minecraft.client.renderer.item.ClampedItemPropertyFunction; import net.minecraft.client.renderer.item.ItemProperties; import net.minecraft.world.item.crafting.Ingredient; @@ -14,8 +14,8 @@ public class ItemModelPropertiesKubeEvent implements KubeStartupEvent { More about model properties: https://minecraft.wiki/w/Tutorials/Models#Item_predicates """) - public void register(Ingredient ingredient, String overwriteId, ClampedItemPropertyFunction callback) { - var id = ID.kjs(overwriteId); + public void register(Ingredient ingredient, KubeResourceLocation overwriteId, ClampedItemPropertyFunction callback) { + var id = overwriteId.wrapped(); if (ingredient.kjs$isWildcard()) { ItemProperties.registerGeneric(id, callback); @@ -28,7 +28,7 @@ public void register(Ingredient ingredient, String overwriteId, ClampedItemPrope } @Info("Register a model property for all items.") - public void registerAll(String overwriteId, ClampedItemPropertyFunction callback) { - ItemProperties.registerGeneric(ID.kjs(overwriteId), callback); + public void registerAll(KubeResourceLocation overwriteId, ClampedItemPropertyFunction callback) { + ItemProperties.registerGeneric(overwriteId.wrapped(), callback); } } diff --git a/src/main/java/dev/latvian/mods/kubejs/recipe/KubeRecipe.java b/src/main/java/dev/latvian/mods/kubejs/recipe/KubeRecipe.java index 391424036..49997d2cf 100644 --- a/src/main/java/dev/latvian/mods/kubejs/recipe/KubeRecipe.java +++ b/src/main/java/dev/latvian/mods/kubejs/recipe/KubeRecipe.java @@ -22,6 +22,7 @@ import dev.latvian.mods.kubejs.script.ConsoleJS; import dev.latvian.mods.kubejs.script.SourceLine; import dev.latvian.mods.kubejs.util.Cast; +import dev.latvian.mods.kubejs.util.KubeResourceLocation; import dev.latvian.mods.kubejs.util.SlotFilter; import dev.latvian.mods.kubejs.util.UtilsJS; import dev.latvian.mods.rhino.Context; @@ -196,8 +197,8 @@ public final void save() { changed = true; } - public KubeRecipe id(ResourceLocation id) { - this.id = id; + public KubeRecipe id(KubeResourceLocation id) { + this.id = id.wrapped(); save(); return this; } diff --git a/src/main/java/dev/latvian/mods/kubejs/registry/RegistryKubeEvent.java b/src/main/java/dev/latvian/mods/kubejs/registry/RegistryKubeEvent.java index e876b6342..e02e6e6eb 100644 --- a/src/main/java/dev/latvian/mods/kubejs/registry/RegistryKubeEvent.java +++ b/src/main/java/dev/latvian/mods/kubejs/registry/RegistryKubeEvent.java @@ -6,7 +6,7 @@ import dev.latvian.mods.kubejs.event.KubeStartupEvent; import dev.latvian.mods.kubejs.script.ConsoleJS; import dev.latvian.mods.kubejs.script.SourceLine; -import dev.latvian.mods.kubejs.util.ID; +import dev.latvian.mods.kubejs.util.KubeResourceLocation; import dev.latvian.mods.rhino.Context; import net.minecraft.core.Registry; import net.minecraft.resources.ResourceKey; @@ -26,7 +26,7 @@ public RegistryKubeEvent(ResourceKey> registryKey) { this.created = new LinkedList<>(); } - public BuilderBase create(Context cx, String id, String type) { + public BuilderBase create(Context cx, KubeResourceLocation id, String type) { var sourceLine = SourceLine.of(cx); var t = builderInfo.namedType(type); @@ -34,7 +34,7 @@ public BuilderBase create(Context cx, String id, String type) { throw new KubeRuntimeException("Unknown type '" + type + "' for object '" + id + "'!").source(sourceLine); } - var b = t.factory().createBuilder(ID.kjs(id)); + var b = t.factory().createBuilder(id.wrapped()); if (b == null) { throw new KubeRuntimeException("Unknown type '" + type + "' for object '" + id + "'!").source(sourceLine); @@ -50,7 +50,7 @@ public BuilderBase create(Context cx, String id, String type) { return b; } - public BuilderBase create(Context cx, String id) { + public BuilderBase create(Context cx, KubeResourceLocation id) { var sourceLine = SourceLine.of(cx); var t = builderInfo.defaultType(); @@ -58,7 +58,7 @@ public BuilderBase create(Context cx, String id) { throw new KubeRuntimeException("Registry '" + registryKey.location() + "' doesn't have a default type registered!").source(sourceLine); } - var b = t.factory().createBuilder(ID.kjs(id)); + var b = t.factory().createBuilder(id.wrapped()); if (b == null) { throw new KubeRuntimeException("Unknown type '" + t.type() + "' for object '" + id + "'!").source(sourceLine); @@ -72,15 +72,14 @@ public BuilderBase create(Context cx, String id) { return b; } - public CustomBuilderObject createCustom(Context cx, String id, Supplier object) { + public CustomBuilderObject createCustom(Context cx, KubeResourceLocation id, Supplier object) { var sourceLine = SourceLine.of(cx); if (object == null) { throw new KubeRuntimeException("Tried to register a null object with id: " + id).source(sourceLine); } - var rl = ID.kjs(id); - var b = new CustomBuilderObject(rl, object); + var b = new CustomBuilderObject(id.wrapped(), object); b.sourceLine = sourceLine; b.registryKey = registryKey; addBuilder(b); diff --git a/src/main/java/dev/latvian/mods/kubejs/registry/ServerRegistryKubeEvent.java b/src/main/java/dev/latvian/mods/kubejs/registry/ServerRegistryKubeEvent.java index eb015748a..8a7778090 100644 --- a/src/main/java/dev/latvian/mods/kubejs/registry/ServerRegistryKubeEvent.java +++ b/src/main/java/dev/latvian/mods/kubejs/registry/ServerRegistryKubeEvent.java @@ -6,7 +6,7 @@ import dev.latvian.mods.kubejs.error.KubeRuntimeException; import dev.latvian.mods.kubejs.event.KubeEvent; import dev.latvian.mods.kubejs.script.SourceLine; -import dev.latvian.mods.kubejs.util.ID; +import dev.latvian.mods.kubejs.util.KubeResourceLocation; import dev.latvian.mods.rhino.Context; import net.minecraft.core.Registry; import net.minecraft.resources.ResourceKey; @@ -29,7 +29,7 @@ public ServerRegistryKubeEvent(ResourceKey> registryKey, DynamicOps< this.builders = builders; } - public BuilderBase create(Context cx, String id, String type) { + public BuilderBase create(Context cx, KubeResourceLocation id, String type) { var sourceLine = SourceLine.of(cx); var t = builderInfo.namedType(type); @@ -38,7 +38,7 @@ public BuilderBase create(Context cx, String id, String type) { throw new IllegalArgumentException("Unknown type '" + type + "' for object '" + id + "'!"); } - var b = t.factory().createBuilder(ID.kjs(id)); + var b = t.factory().createBuilder(id.wrapped()); if (b == null) { throw new KubeRuntimeException("Unknown type '" + type + "' for object '" + id + "'!").source(sourceLine); @@ -50,7 +50,7 @@ public BuilderBase create(Context cx, String id, String type) { } } - public BuilderBase create(Context cx, String id) { + public BuilderBase create(Context cx, KubeResourceLocation id) { var sourceLine = SourceLine.of(cx); var t = builderInfo.defaultType(); @@ -58,7 +58,7 @@ public BuilderBase create(Context cx, String id) { throw new KubeRuntimeException("Registry '" + registryKey.location() + "' doesn't have a default type registered!").source(sourceLine); } - var b = t.factory().createBuilder(ID.kjs(id)); + var b = t.factory().createBuilder(id.wrapped()); if (b == null) { throw new KubeRuntimeException("Unknown type '" + t.type() + "' for object '" + id + "'!").source(sourceLine); @@ -70,24 +70,24 @@ public BuilderBase create(Context cx, String id) { } } - public CustomBuilderObject createCustom(Context cx, String id, Supplier object) { + public CustomBuilderObject createCustom(Context cx, KubeResourceLocation id, Supplier object) { var sourceLine = SourceLine.of(cx); if (object == null) { throw new KubeRuntimeException("Tried to register a null object with id: " + id).source(sourceLine); } - var b = new CustomBuilderObject(ID.kjs(id), object); + var b = new CustomBuilderObject(id.wrapped(), object); b.sourceLine = sourceLine; b.registryKey = registryKey; builders.add(b); return b; } - public CustomBuilderObject createFromJson(Context cx, String id, JsonElement json) { + public CustomBuilderObject createFromJson(Context cx, KubeResourceLocation id, JsonElement json) { var sourceLine = SourceLine.of(cx); - var b = new CustomBuilderObject(ID.kjs(id), () -> codec.parse(jsonOps, json).result().orElseThrow()); + var b = new CustomBuilderObject(id.wrapped(), () -> codec.parse(jsonOps, json).result().orElseThrow()); b.sourceLine = sourceLine; b.registryKey = registryKey; builders.add(b); diff --git a/src/main/java/dev/latvian/mods/kubejs/script/KubeJSContext.java b/src/main/java/dev/latvian/mods/kubejs/script/KubeJSContext.java index 56238bfa7..1db14e290 100644 --- a/src/main/java/dev/latvian/mods/kubejs/script/KubeJSContext.java +++ b/src/main/java/dev/latvian/mods/kubejs/script/KubeJSContext.java @@ -17,7 +17,6 @@ import net.minecraft.core.HolderSet; import net.minecraft.core.Registry; import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; import java.lang.reflect.AccessibleObject; @@ -76,10 +75,6 @@ public Scriptable wrapAsJavaObject(Scriptable scope, Object javaObject, TypeInfo return super.wrapAsJavaObject(scope, javaObject, target); } - private static boolean isKey(Object from) { - return from instanceof CharSequence || from instanceof ResourceLocation || from instanceof ResourceKey; - } - @Override public int internalConversionWeightLast(Object fromObj, TypeInfo target) { var c = target.asClass(); @@ -154,7 +149,7 @@ protected Object internalJsToJavaLast(Object from, TypeInfo target) { throw throwAsScriptRuntimeEx(new IllegalAccessException("Reflection access denied"), this); } else if (from instanceof Holder holder && c.isInstance(holder.value())) { return holder.value(); - } else if (isKey(from)) { + } else if (ID.isKey(from)) { var reg = RegistryType.lookup(target); if (reg != null) { diff --git a/src/main/java/dev/latvian/mods/kubejs/util/ID.java b/src/main/java/dev/latvian/mods/kubejs/util/ID.java index 83b754634..9caa26147 100644 --- a/src/main/java/dev/latvian/mods/kubejs/util/ID.java +++ b/src/main/java/dev/latvian/mods/kubejs/util/ID.java @@ -87,4 +87,8 @@ static ResourceLocation mc(@Nullable Object o) { static ResourceLocation kjs(@Nullable Object o) { return of(o, true); } + + static boolean isKey(Object from) { + return from instanceof CharSequence || from instanceof ResourceLocation || from instanceof ResourceKey; + } } diff --git a/src/main/java/dev/latvian/mods/kubejs/util/KubeResourceLocation.java b/src/main/java/dev/latvian/mods/kubejs/util/KubeResourceLocation.java new file mode 100644 index 000000000..387fb4d7d --- /dev/null +++ b/src/main/java/dev/latvian/mods/kubejs/util/KubeResourceLocation.java @@ -0,0 +1,17 @@ +package dev.latvian.mods.kubejs.util; + +import net.minecraft.resources.ResourceLocation; + +/** + * Exists to indicate that a ResourceLocation would use kubejs: namespace by default when written as plain string. Should only be used as an argument in registry methods + */ +public record KubeResourceLocation(ResourceLocation wrapped) { + public static KubeResourceLocation wrap(Object from) { + return new KubeResourceLocation(ID.kjs(from)); + } + + @Override + public String toString() { + return wrapped.toString(); + } +}