From fe53dcc1aaf709eb717bf291b6755d1f0d9f59fc Mon Sep 17 00:00:00 2001 From: Amirhan-Taipovjan-Greatest-I <51203385+Amirhan-Taipovjan-Greatest-I@users.noreply.github.com> Date: Thu, 18 Jan 2024 21:15:25 +0300 Subject: [PATCH 01/10] Actualized Vanilla-ish Tatar Translation! --- src/main/resources/assets/owo/lang/tt_ru.json | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/main/resources/assets/owo/lang/tt_ru.json diff --git a/src/main/resources/assets/owo/lang/tt_ru.json b/src/main/resources/assets/owo/lang/tt_ru.json new file mode 100644 index 00000000..c4f394fb --- /dev/null +++ b/src/main/resources/assets/owo/lang/tt_ru.json @@ -0,0 +1,56 @@ +{ + "modmenu.descriptionTranslation.owo": "әйе бу начар мин беләм", + "modmenu.summaryTranslation.owo": "әйе бу начар мин беләм", + "text.owo.itemGroup.tab_template": [ + { "index": 0 }, + { "text": " > ", "color": "gray" }, + { "index": 1, "color": "dark_gray" } + ], + "text.owo.itemGroup.select_hint": {"text": "Берничә сайлау өчен Shift төймәсенә басыгыз", "color": "gray"}, + "text.owo.configure_hot_reload.title": "Кайнар яңадан йөкләү", + "text.owo.configure_hot_reload.choose_file": "Файлны сайлау", + "text.owo.configure_hot_reload.save": "Саклау", + "text.owo.configure_hot_reload.model": [ + {"text": "Модель: ", "color": "yellow"}, + {"index": 0, "color": "gray"} + ], + "text.owo.configure_hot_reload.reload_from.unset": "Сайланмаган", + "text.owo.configure_hot_reload.reload_from": [ + {"text": "Яңадан йөкләү урыны: ", "color": "yellow"}, + {"index": 0, "color": "gray"} + ], + "text.owo.config.search": "Эзләү...", + "text.owo.config.search.matches": "%$2d нәтиҗәдән %$1d нәтиҗә", + "text.owo.config.search.no_matches": "Нәтиҗәләр юк", + "text.owo.config.must_restart": "Сез керткән кайбер үзгәрешләр куллану өчен яңадан йөкләүне таләп итә", + "text.owo.config.button.exit_minecraft": "Minecraft-тан чыгу", + "text.owo.config.button.ignore_restart": "Яңадан кушу соңрак", + "text.owo.config.button.range.edit_as_text": "Текст кебек үзгәртү", + "text.owo.config.button.range.edit_with_slider": "Шудырма белән үзгәртү", + "text.owo.config.applies_after_restart": [ + {"text": "⏻ ", "color": "#FAEA48"}, + {"text": "Бу көйләү яңадан йөкләүдән соң кулланыла", "color": "gray"} + ], + "text.owo.config.managed_by_server": [ + {"text": "⚑ ", "color": "#EB1D36"}, + {"text": "Бу көйләү сервер белән идарә ителә\n Аны үзгәртү өчен өзелегез", "color": "gray"} + ], + "text.owo.config.button.reload": "Яңадан йөкләү", + "text.owo.config.button.done": "Булды", + "text.owo.config.sections": {"text": "Бүлекләр", "underlined": true}, + "text.owo.config.list.add_entry": "Элементны өстәү", + "text.owo.config.boolean_toggle.enabled": [ + "", + {"text": "[", "color": "gray"}, + {"text": "✔", "color": "#28FFBF"}, + {"text": "]", "color": "gray"}, + " Кушык" + ], + "text.owo.config.boolean_toggle.disabled": [ + "", + {"text": "[", "color": "gray"}, + {"text": "❌", "color": "#EB1D36"}, + {"text": "]", "color": "gray"}, + " Сүнек" + ] +} From 9430849ec569885f23e8e74065a32e2830e2a6dc Mon Sep 17 00:00:00 2001 From: Amirhan-Taipovjan-Greatest-I <51203385+Amirhan-Taipovjan-Greatest-I@users.noreply.github.com> Date: Sat, 27 Apr 2024 18:36:31 +0300 Subject: [PATCH 02/10] =?UTF-8?q?Changed=20"Reload"=20Translation=20to=20j?= =?UTF-8?q?ust=20"=E2=86=BB"=20Symbol=20to=20avoid=20being=20not=20fitting?= =?UTF-8?q?=20in=20Button.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/assets/owo/lang/tt_ru.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/assets/owo/lang/tt_ru.json b/src/main/resources/assets/owo/lang/tt_ru.json index c4f394fb..be474121 100644 --- a/src/main/resources/assets/owo/lang/tt_ru.json +++ b/src/main/resources/assets/owo/lang/tt_ru.json @@ -35,7 +35,7 @@ {"text": "⚑ ", "color": "#EB1D36"}, {"text": "Бу көйләү сервер белән идарә ителә\n Аны үзгәртү өчен өзелегез", "color": "gray"} ], - "text.owo.config.button.reload": "Яңадан йөкләү", + "text.owo.config.button.reload": "↻", "text.owo.config.button.done": "Булды", "text.owo.config.sections": {"text": "Бүлекләр", "underlined": true}, "text.owo.config.list.add_entry": "Элементны өстәү", From 7b19a64281d7268630cff80b25ab1d7b8570b944 Mon Sep 17 00:00:00 2001 From: Amirhan-Taipovjan-Greatest-I <51203385+Amirhan-Taipovjan-Greatest-I@users.noreply.github.com> Date: Wed, 29 May 2024 21:29:17 +0300 Subject: [PATCH 03/10] Actualization of Tatar Translation! --- src/main/resources/assets/owo/lang/tt_ru.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/assets/owo/lang/tt_ru.json b/src/main/resources/assets/owo/lang/tt_ru.json index be474121..4438608b 100644 --- a/src/main/resources/assets/owo/lang/tt_ru.json +++ b/src/main/resources/assets/owo/lang/tt_ru.json @@ -37,6 +37,7 @@ ], "text.owo.config.button.reload": "↻", "text.owo.config.button.done": "Булды", + "text.owo.config.sections_tooltip": "Бүлекләр", "text.owo.config.sections": {"text": "Бүлекләр", "underlined": true}, "text.owo.config.list.add_entry": "Элементны өстәү", "text.owo.config.boolean_toggle.enabled": [ From b8085cf0f367605f950627065860f3941ec10e81 Mon Sep 17 00:00:00 2001 From: Basique Date: Sat, 3 Aug 2024 01:36:46 +0300 Subject: [PATCH 04/10] update wisdom --- src/main/java/io/wispforest/owo/util/Wisdom.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/wispforest/owo/util/Wisdom.java b/src/main/java/io/wispforest/owo/util/Wisdom.java index f8a7a314..bb35db9d 100644 --- a/src/main/java/io/wispforest/owo/util/Wisdom.java +++ b/src/main/java/io/wispforest/owo/util/Wisdom.java @@ -56,7 +56,8 @@ private Wisdom() {} "I saw ppl complain that minor updates between big updates will ruin it for modders but I thought modders were very good and they can do what we do in a week so they should be ok with updating their mods to new versions in a day, right? :titantroll:", "that's a CanPickUpLoot baby zombie, the most annoying thing ever. he runs around like crazy and picks up all your shit", "blod: I think I need to take a book out of your page", - "blod: he her" + "blod: he her", + "BasiqueEvangelist: what if... iphones" ); public static void spread() { From fbcea1828e5919e396c7eb8956d20a6d25a5350c Mon Sep 17 00:00:00 2001 From: Basique Date: Sun, 4 Aug 2024 02:30:42 +0300 Subject: [PATCH 05/10] add my newest single --- src/main/java/io/wispforest/owo/util/Wisdom.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/wispforest/owo/util/Wisdom.java b/src/main/java/io/wispforest/owo/util/Wisdom.java index bb35db9d..0c6d70bf 100644 --- a/src/main/java/io/wispforest/owo/util/Wisdom.java +++ b/src/main/java/io/wispforest/owo/util/Wisdom.java @@ -57,7 +57,8 @@ private Wisdom() {} "that's a CanPickUpLoot baby zombie, the most annoying thing ever. he runs around like crazy and picks up all your shit", "blod: I think I need to take a book out of your page", "blod: he her", - "BasiqueEvangelist: what if... iphones" + "BasiqueEvangelist: what if... iphones", + "Cheese Cheese Creeper, the newest release from MC Basic" ); public static void spread() { From 68b0aa6c590264ab5013340fe9af6e7d0421709d Mon Sep 17 00:00:00 2001 From: glisco Date: Fri, 9 Aug 2024 22:46:40 +0200 Subject: [PATCH 06/10] move RecipeManager injection for parsing remainders to fix #286 --- .../recipe_remainders/RecipeManagerMixin.java | 22 ++++++++++++------- .../uwu/{recipes => recipe}/test_recipe.json | 0 .../uwu_shaped_recipe.json | 0 3 files changed, 14 insertions(+), 8 deletions(-) rename src/testmod/resources/data/uwu/{recipes => recipe}/test_recipe.json (100%) rename src/testmod/resources/data/uwu/{recipes => recipe}/uwu_shaped_recipe.json (100%) diff --git a/src/main/java/io/wispforest/owo/mixin/recipe_remainders/RecipeManagerMixin.java b/src/main/java/io/wispforest/owo/mixin/recipe_remainders/RecipeManagerMixin.java index e3ddbf08..1298fd98 100644 --- a/src/main/java/io/wispforest/owo/mixin/recipe_remainders/RecipeManagerMixin.java +++ b/src/main/java/io/wispforest/owo/mixin/recipe_remainders/RecipeManagerMixin.java @@ -1,35 +1,41 @@ package io.wispforest.owo.mixin.recipe_remainders; -import com.google.gson.JsonObject; +import com.google.gson.JsonElement; import com.google.gson.JsonParseException; import com.google.gson.JsonPrimitive; +import com.llamalad7.mixinextras.sugar.Local; import com.mojang.serialization.JsonOps; import io.wispforest.owo.util.RecipeRemainderStorage; -import net.minecraft.inventory.Inventory; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.recipe.*; +import net.minecraft.recipe.Recipe; +import net.minecraft.recipe.RecipeEntry; +import net.minecraft.recipe.RecipeManager; +import net.minecraft.recipe.RecipeType; import net.minecraft.recipe.input.RecipeInput; -import net.minecraft.registry.RegistryWrapper; +import net.minecraft.resource.ResourceManager; import net.minecraft.util.Identifier; import net.minecraft.util.JsonHelper; -import net.minecraft.util.Util; import net.minecraft.util.collection.DefaultedList; +import net.minecraft.util.profiler.Profiler; import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import java.util.HashMap; +import java.util.Map; import java.util.Optional; @Mixin(RecipeManager.class) public abstract class RecipeManagerMixin { - @Inject(method = "deserialize", at = @At(value = "RETURN")) - private static void deserializeRecipeSpecificRemainders(Identifier id, JsonObject json, RegistryWrapper.WrapperLookup registryLookup, CallbackInfoReturnable> cir) { + @Inject(method = "apply(Ljava/util/Map;Lnet/minecraft/resource/ResourceManager;Lnet/minecraft/util/profiler/Profiler;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/recipe/RecipeEntry;(Lnet/minecraft/util/Identifier;Lnet/minecraft/recipe/Recipe;)V")) + private void deserializeRecipeSpecificRemainders(Map map, ResourceManager resourceManager, Profiler profiler, CallbackInfo ci, @Local Map.Entry entry) { + var json = entry.getValue().getAsJsonObject(); if (!json.has("owo:remainders")) return; var remainders = new HashMap(); @@ -46,7 +52,7 @@ private static void deserializeRecipeSpecificRemainders(Identifier id, JsonObjec } if (remainders.isEmpty()) return; - RecipeRemainderStorage.store(id, remainders); + RecipeRemainderStorage.store(entry.getKey(), remainders); } @Inject(method = "getRemainingStacks", at = @At(value = "RETURN", ordinal = 0), locals = LocalCapture.CAPTURE_FAILHARD) diff --git a/src/testmod/resources/data/uwu/recipes/test_recipe.json b/src/testmod/resources/data/uwu/recipe/test_recipe.json similarity index 100% rename from src/testmod/resources/data/uwu/recipes/test_recipe.json rename to src/testmod/resources/data/uwu/recipe/test_recipe.json diff --git a/src/testmod/resources/data/uwu/recipes/uwu_shaped_recipe.json b/src/testmod/resources/data/uwu/recipe/uwu_shaped_recipe.json similarity index 100% rename from src/testmod/resources/data/uwu/recipes/uwu_shaped_recipe.json rename to src/testmod/resources/data/uwu/recipe/uwu_shaped_recipe.json From 2e883e1a7a9ee9e38a16988d6e2c1a093dcfa72b Mon Sep 17 00:00:00 2001 From: Basique Date: Fri, 23 Aug 2024 16:19:21 +0300 Subject: [PATCH 07/10] first impl of component-derived-components --- .../owo/ext/DerivedComponentMap.java | 64 +++++++++++++++++++ .../java/io/wispforest/owo/ext/OwoItem.java | 10 +++ .../mixin/ext/ComponentMapImplAccessor.java | 17 +++++ .../owo/mixin/ext/ComponentMapImplMixin.java | 16 +++++ .../wispforest/owo/mixin/ext/ItemMixin.java | 9 +++ .../owo/mixin/ext/ItemStackMixin.java | 55 ++++++++++++++++ src/main/resources/fabric.mod.json | 3 + src/main/resources/owo.mixins.json | 12 ++-- .../wispforest/uwu/items/UwuCounterItem.java | 57 +++++++++++++++++ .../io/wispforest/uwu/items/UwuItems.java | 1 + .../resources/assets/uwu/lang/en_us.json | 1 + .../assets/uwu/models/item/counter.json | 6 ++ 12 files changed, 247 insertions(+), 4 deletions(-) create mode 100644 src/main/java/io/wispforest/owo/ext/DerivedComponentMap.java create mode 100644 src/main/java/io/wispforest/owo/ext/OwoItem.java create mode 100644 src/main/java/io/wispforest/owo/mixin/ext/ComponentMapImplAccessor.java create mode 100644 src/main/java/io/wispforest/owo/mixin/ext/ComponentMapImplMixin.java create mode 100644 src/main/java/io/wispforest/owo/mixin/ext/ItemMixin.java create mode 100644 src/main/java/io/wispforest/owo/mixin/ext/ItemStackMixin.java create mode 100644 src/testmod/java/io/wispforest/uwu/items/UwuCounterItem.java create mode 100644 src/testmod/resources/assets/uwu/models/item/counter.json diff --git a/src/main/java/io/wispforest/owo/ext/DerivedComponentMap.java b/src/main/java/io/wispforest/owo/ext/DerivedComponentMap.java new file mode 100644 index 00000000..4f8f56c8 --- /dev/null +++ b/src/main/java/io/wispforest/owo/ext/DerivedComponentMap.java @@ -0,0 +1,64 @@ +package io.wispforest.owo.ext; + +import net.minecraft.component.ComponentChanges; +import net.minecraft.component.ComponentMap; +import net.minecraft.component.ComponentMapImpl; +import net.minecraft.component.ComponentType; +import net.minecraft.item.ItemStack; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +import java.util.Set; + +@ApiStatus.Internal +public class DerivedComponentMap implements ComponentMap { + private final ComponentMap base; + private final ComponentMapImpl delegate; + + public DerivedComponentMap(ComponentMap base) { + this.base = base; + this.delegate = new ComponentMapImpl(base); + } + + public static ComponentMap reWrapIfNeeded(ComponentMap original) { + if (original instanceof DerivedComponentMap derived) { + return new DerivedComponentMap(derived.base); + } else { + return original; + } + } + + public void derive(ItemStack owner) { + delegate.setChanges(ComponentChanges.EMPTY); + var builder = ComponentChanges.builder(); + owner.getItem().deriveStackComponents(owner.getComponents(), builder); + delegate.setChanges(builder.build()); + } + + @Nullable + @Override + public T get(ComponentType type) { + return delegate.get(type); + } + + @Override + public Set> getTypes() { + return delegate.getTypes(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + DerivedComponentMap that = (DerivedComponentMap) o; + return base.equals(that.base) && delegate.equals(that.delegate); + } + + @Override + public int hashCode() { + int result = base.hashCode(); + result = 31 * result + delegate.hashCode(); + return result; + } +} diff --git a/src/main/java/io/wispforest/owo/ext/OwoItem.java b/src/main/java/io/wispforest/owo/ext/OwoItem.java new file mode 100644 index 00000000..c598dda5 --- /dev/null +++ b/src/main/java/io/wispforest/owo/ext/OwoItem.java @@ -0,0 +1,10 @@ +package io.wispforest.owo.ext; + +import net.minecraft.component.ComponentChanges; +import net.minecraft.component.ComponentMap; + +public interface OwoItem { + default void deriveStackComponents(ComponentMap source, ComponentChanges.Builder target) { + + } +} diff --git a/src/main/java/io/wispforest/owo/mixin/ext/ComponentMapImplAccessor.java b/src/main/java/io/wispforest/owo/mixin/ext/ComponentMapImplAccessor.java new file mode 100644 index 00000000..717ba5d3 --- /dev/null +++ b/src/main/java/io/wispforest/owo/mixin/ext/ComponentMapImplAccessor.java @@ -0,0 +1,17 @@ +package io.wispforest.owo.mixin.ext; + +import net.minecraft.component.ComponentMap; +import net.minecraft.component.ComponentMapImpl; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(ComponentMapImpl.class) +public interface ComponentMapImplAccessor { + @Accessor("baseComponents") + ComponentMap owo$getBaseComponents(); + + @Accessor("baseComponents") + @Mutable + void owo$setBaseComponents(ComponentMap baseComponents); +} diff --git a/src/main/java/io/wispforest/owo/mixin/ext/ComponentMapImplMixin.java b/src/main/java/io/wispforest/owo/mixin/ext/ComponentMapImplMixin.java new file mode 100644 index 00000000..6ea852f3 --- /dev/null +++ b/src/main/java/io/wispforest/owo/mixin/ext/ComponentMapImplMixin.java @@ -0,0 +1,16 @@ +package io.wispforest.owo.mixin.ext; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import io.wispforest.owo.ext.DerivedComponentMap; +import net.minecraft.component.ComponentMap; +import net.minecraft.component.ComponentMapImpl; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(ComponentMapImpl.class) +public class ComponentMapImplMixin { + @ModifyExpressionValue(method = "copy", at = @At(value = "FIELD", target = "Lnet/minecraft/component/ComponentMapImpl;baseComponents:Lnet/minecraft/component/ComponentMap;")) + private ComponentMap reWrapDerived(ComponentMap original) { + return DerivedComponentMap.reWrapIfNeeded(original); + } +} diff --git a/src/main/java/io/wispforest/owo/mixin/ext/ItemMixin.java b/src/main/java/io/wispforest/owo/mixin/ext/ItemMixin.java new file mode 100644 index 00000000..43b74fde --- /dev/null +++ b/src/main/java/io/wispforest/owo/mixin/ext/ItemMixin.java @@ -0,0 +1,9 @@ +package io.wispforest.owo.mixin.ext; + +import io.wispforest.owo.ext.OwoItem; +import net.minecraft.item.Item; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(Item.class) +public class ItemMixin implements OwoItem { +} diff --git a/src/main/java/io/wispforest/owo/mixin/ext/ItemStackMixin.java b/src/main/java/io/wispforest/owo/mixin/ext/ItemStackMixin.java new file mode 100644 index 00000000..6792224d --- /dev/null +++ b/src/main/java/io/wispforest/owo/mixin/ext/ItemStackMixin.java @@ -0,0 +1,55 @@ +package io.wispforest.owo.mixin.ext; + +import io.wispforest.owo.ext.DerivedComponentMap; +import net.minecraft.component.ComponentChanges; +import net.minecraft.component.ComponentMap; +import net.minecraft.component.ComponentMapImpl; +import net.minecraft.item.ItemConvertible; +import net.minecraft.item.ItemStack; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ItemStack.class) +public class ItemStackMixin { + @Shadow @Final ComponentMapImpl components; + + @Unique private DerivedComponentMap owo$derivedMap; + + @Inject(method = "(Lnet/minecraft/item/ItemConvertible;ILnet/minecraft/component/ComponentMapImpl;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;postProcessComponents(Lnet/minecraft/item/ItemStack;)V")) + private void injectDerivedComponentMap(ItemConvertible item, int count, ComponentMapImpl components, CallbackInfo ci) { + var base = ((ComponentMapImplAccessor)(Object) this.components).owo$getBaseComponents(); + + if (base instanceof DerivedComponentMap derived) { + owo$derivedMap = derived; + } else { + owo$derivedMap = new DerivedComponentMap(base); + ((ComponentMapImplAccessor)(Object) this.components).owo$setBaseComponents(owo$derivedMap); + } + } + + // TODO: for some reason mixin doesn't like it if I put all the injects in one method. + @Inject(method = "(Lnet/minecraft/item/ItemConvertible;ILnet/minecraft/component/ComponentMapImpl;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;postProcessComponents(Lnet/minecraft/item/ItemStack;)V", shift = At.Shift.AFTER)) + private void deriveComponents1(ItemConvertible item, int count, ComponentMapImpl components, CallbackInfo ci) { + owo$derivedMap.derive((ItemStack)(Object) this); + } + + @Inject(method = "applyChanges", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;postProcessComponents(Lnet/minecraft/item/ItemStack;)V", shift = At.Shift.AFTER)) + private void deriveComponents2(ComponentChanges changes, CallbackInfo ci) { + owo$derivedMap.derive((ItemStack)(Object) this); + } + + @Inject(method = "applyUnvalidatedChanges", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;postProcessComponents(Lnet/minecraft/item/ItemStack;)V", shift = At.Shift.AFTER)) + private void deriveComponents3(ComponentChanges changes, CallbackInfo ci) { + owo$derivedMap.derive((ItemStack)(Object) this); + } + + @Inject(method = "applyComponentsFrom", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;postProcessComponents(Lnet/minecraft/item/ItemStack;)V", shift = At.Shift.AFTER)) + private void deriveComponents4(ComponentMap components, CallbackInfo ci) { + owo$derivedMap.derive((ItemStack)(Object) this); + } +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 98b66d5b..c9c8c4ca 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -79,6 +79,9 @@ ], "net/minecraft/class_1792\u0024class_1793": [ "io/wispforest/owo/itemgroup/OwoItemSettingsExtension" + ], + "net/minecraft/class_1792": [ + "io/wispforest/owo/ext/OwoItem" ] } } diff --git a/src/main/resources/owo.mixins.json b/src/main/resources/owo.mixins.json index cb024776..46ef156e 100644 --- a/src/main/resources/owo.mixins.json +++ b/src/main/resources/owo.mixins.json @@ -5,6 +5,7 @@ "compatibilityLevel": "JAVA_16", "mixins": [ "BufferBuilderAccessor", + "CachedRegistryInfoGetterAccessor", "ClientConnectionMixin", "ComponentTypeBuilderMixin", "Copenhagen", @@ -22,17 +23,21 @@ "ServerPlayerInteractionManagerMixin", "SetComponentsLootFunctionAccessor", "TagGroupLoaderMixin", + "ext.ComponentMapImplAccessor", + "ext.ComponentMapImplMixin", + "ext.ItemMixin", + "ext.ItemStackMixin", "itemgroup.ItemGroupAccessor", - "itemgroup.ItemSettingsMixin", "itemgroup.ItemMixin", + "itemgroup.ItemSettingsMixin", "offline.AdvancementProgressAccessor", "offline.PlayerAdvancementTrackerMixin", "offline.ProgressMapAccessor", "offline.WorldSaveHandlerMixin", "recipe_remainders.CraftingResultSlotMixin", "recipe_remainders.RecipeManagerMixin", - "registry.SimpleRegistryMixin", "registry.ReferenceAccessor", + "registry.SimpleRegistryMixin", "text.LanguageMixin", "text.TextCodecsMixin", "text.TranslatableTextContentMixin", @@ -41,8 +46,7 @@ "tweaks.LevelInfoMixin", "ui.SlotAccessor", "ui.SlotMixin", - "ui.access.BlockEntityAccessor", - "CachedRegistryInfoGetterAccessor" + "ui.access.BlockEntityAccessor" ], "client": [ "ClientCommonNetworkHandlerAccessor", diff --git a/src/testmod/java/io/wispforest/uwu/items/UwuCounterItem.java b/src/testmod/java/io/wispforest/uwu/items/UwuCounterItem.java new file mode 100644 index 00000000..259bdc47 --- /dev/null +++ b/src/testmod/java/io/wispforest/uwu/items/UwuCounterItem.java @@ -0,0 +1,57 @@ +package io.wispforest.uwu.items; + +import io.wispforest.endec.Endec; +import net.minecraft.component.ComponentChanges; +import net.minecraft.component.ComponentMap; +import net.minecraft.component.ComponentType; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.AttributeModifierSlot; +import net.minecraft.component.type.AttributeModifiersComponent; +import net.minecraft.entity.attribute.EntityAttributeModifier; +import net.minecraft.entity.attribute.EntityAttributes; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.util.Hand; +import net.minecraft.util.Identifier; +import net.minecraft.util.Rarity; +import net.minecraft.util.TypedActionResult; +import net.minecraft.world.World; + +public class UwuCounterItem extends Item { + private static final ComponentType COUNT = Registry.register( + Registries.DATA_COMPONENT_TYPE, + Identifier.of("uwu", "count"), + ComponentType.builder() + .endec(Endec.INT) + .build() + ); + + public UwuCounterItem() { + super(new Settings().rarity(Rarity.UNCOMMON)); + } + + @Override + public TypedActionResult use(World world, PlayerEntity user, Hand hand) { + var stack = user.getStackInHand(hand); + + if (user.isSneaking()) { + stack.apply(COUNT, 0, old -> old - 1); + } else { + stack.apply(COUNT, 0, old -> old + 1); + } + + return TypedActionResult.success(stack); + } + + @Override + public void deriveStackComponents(ComponentMap source, ComponentChanges.Builder target) { + target.add(DataComponentTypes.ATTRIBUTE_MODIFIERS, AttributeModifiersComponent.builder() + .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, + new EntityAttributeModifier(Identifier.of("uwu", "counter_attribute"), source.getOrDefault(COUNT, 0), EntityAttributeModifier.Operation.ADD_VALUE), + AttributeModifierSlot.MAINHAND) + .build()); + } +} diff --git a/src/testmod/java/io/wispforest/uwu/items/UwuItems.java b/src/testmod/java/io/wispforest/uwu/items/UwuItems.java index 23e360b1..68786734 100644 --- a/src/testmod/java/io/wispforest/uwu/items/UwuItems.java +++ b/src/testmod/java/io/wispforest/uwu/items/UwuItems.java @@ -13,6 +13,7 @@ public class UwuItems implements ItemRegistryContainer { public static final Item TEST_STICK = new UwuTestStickItem(); public static final Item SCREEN_SHARD = new UwuScreenShardItem(); + public static final Item COUNTER = new UwuCounterItem(); @RegistryNamespace("uowou") public static class OwoCompatItems implements ItemRegistryContainer { diff --git a/src/testmod/resources/assets/uwu/lang/en_us.json b/src/testmod/resources/assets/uwu/lang/en_us.json index 0b535933..0f317a89 100644 --- a/src/testmod/resources/assets/uwu/lang/en_us.json +++ b/src/testmod/resources/assets/uwu/lang/en_us.json @@ -17,6 +17,7 @@ "color": "#3AB0FF" } ], + "item.uwu.counter": "Counter", "text.config.uwu.title": "Test Config Screen", "key.uwu.hud_test": [ { diff --git a/src/testmod/resources/assets/uwu/models/item/counter.json b/src/testmod/resources/assets/uwu/models/item/counter.json new file mode 100644 index 00000000..6c7be6f6 --- /dev/null +++ b/src/testmod/resources/assets/uwu/models/item/counter.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "item/compass_16" + } +} \ No newline at end of file From 06b229911119262427b7d5f202f7ba3075cde10a Mon Sep 17 00:00:00 2001 From: Basique Date: Tue, 27 Aug 2024 19:12:39 +0300 Subject: [PATCH 08/10] make SyncedProperty and ScreenHandlerMixin pass in registry context --- .../owo/client/screens/SyncedProperty.java | 18 +++++++++++++--- .../owo/mixin/ScreenHandlerMixin.java | 10 ++++++--- .../wispforest/owo/network/OwoNetChannel.java | 21 ------------------- .../io/wispforest/uwu/EpicScreenHandler.java | 10 +++++++++ 4 files changed, 32 insertions(+), 27 deletions(-) diff --git a/src/main/java/io/wispforest/owo/client/screens/SyncedProperty.java b/src/main/java/io/wispforest/owo/client/screens/SyncedProperty.java index 77408320..d9d6c9ec 100644 --- a/src/main/java/io/wispforest/owo/client/screens/SyncedProperty.java +++ b/src/main/java/io/wispforest/owo/client/screens/SyncedProperty.java @@ -1,21 +1,26 @@ package io.wispforest.owo.client.screens; import io.wispforest.endec.Endec; +import io.wispforest.endec.SerializationContext; +import io.wispforest.owo.serialization.RegistriesAttribute; import io.wispforest.owo.util.Observable; import net.minecraft.network.PacketByteBuf; +import net.minecraft.screen.ScreenHandler; import org.jetbrains.annotations.ApiStatus; public class SyncedProperty extends Observable { private final int index; private final Endec endec; + private final ScreenHandler owner; private boolean needsSync; @ApiStatus.Internal - public SyncedProperty(int index, Endec endec, T initial) { + public SyncedProperty(int index, Endec endec, T initial, ScreenHandler owner) { super(initial); this.index = index; this.endec = endec; + this.owner = owner; } public int index() { @@ -30,12 +35,12 @@ public boolean needsSync() { @ApiStatus.Internal public void write(PacketByteBuf buf) { needsSync = false; - buf.write(this.endec, value); + buf.write(serializationContext(), this.endec, value); } @ApiStatus.Internal public void read(PacketByteBuf buf) { - this.set(buf.read(this.endec)); + this.set(buf.read(serializationContext(), this.endec)); } @Override @@ -48,4 +53,11 @@ protected void notifyObservers(T value) { public void markDirty() { notifyObservers(value); } + + private SerializationContext serializationContext() { + var player = this.owner.player(); + if (player == null) return SerializationContext.empty(); + + return SerializationContext.attributes(RegistriesAttribute.of(player.getRegistryManager())); + } } diff --git a/src/main/java/io/wispforest/owo/mixin/ScreenHandlerMixin.java b/src/main/java/io/wispforest/owo/mixin/ScreenHandlerMixin.java index 0bbc8402..6b3d7385 100644 --- a/src/main/java/io/wispforest/owo/mixin/ScreenHandlerMixin.java +++ b/src/main/java/io/wispforest/owo/mixin/ScreenHandlerMixin.java @@ -1,5 +1,6 @@ package io.wispforest.owo.mixin; +import io.wispforest.endec.SerializationContext; import io.wispforest.endec.impl.ReflectiveEndecBuilder; import io.wispforest.owo.client.screens.OwoScreenHandler; import io.wispforest.owo.client.screens.ScreenInternals; @@ -7,6 +8,7 @@ import io.wispforest.owo.client.screens.SyncedProperty; import io.wispforest.owo.network.NetworkException; import io.wispforest.endec.Endec; +import io.wispforest.owo.serialization.RegistriesAttribute; import io.wispforest.owo.serialization.endec.MinecraftEndecs; import io.wispforest.owo.util.pond.OwoScreenHandlerExtension; import net.fabricmc.api.EnvType; @@ -106,8 +108,9 @@ public void sendMessage(@NotNull R message) { throw new NetworkException("Tried to send message of unknown type " + message.getClass()); } + var ctx = SerializationContext.attributes(RegistriesAttribute.of(this.owo$player.getRegistryManager())); var buf = PacketByteBufs.create(); - buf.write(messageData.endec(), message); + buf.write(ctx, messageData.endec(), message); var packet = new ScreenInternals.LocalPacket(messageData.id(), buf); @@ -136,13 +139,14 @@ public void sendMessage(@NotNull R message) { @SuppressWarnings({"rawtypes", "unchecked"}) public void owo$handlePacket(ScreenInternals.LocalPacket packet, boolean clientbound) { ScreenhandlerMessageData messageData = (clientbound ? this.owo$clientboundMessages : this.owo$serverboundMessages).get(packet.packetId()); + var ctx = SerializationContext.attributes(RegistriesAttribute.of(this.owo$player.getRegistryManager())); - messageData.handler().accept(packet.payload().read(messageData.endec())); + messageData.handler().accept(packet.payload().read(ctx, messageData.endec())); } @Override public SyncedProperty createProperty(Class clazz, Endec endec, T initial) { - var prop = new SyncedProperty<>(this.owo$properties.size(), endec, initial); + var prop = new SyncedProperty<>(this.owo$properties.size(), endec, initial, (ScreenHandler)(Object) this); this.owo$properties.add(prop); return prop; } diff --git a/src/main/java/io/wispforest/owo/network/OwoNetChannel.java b/src/main/java/io/wispforest/owo/network/OwoNetChannel.java index c1de375e..144cb989 100644 --- a/src/main/java/io/wispforest/owo/network/OwoNetChannel.java +++ b/src/main/java/io/wispforest/owo/network/OwoNetChannel.java @@ -445,27 +445,6 @@ private void createEndec(Class messageClass, int handlerIn } } - @SuppressWarnings("unchecked") - private PacketByteBuf encode(R message, EnvType target) { - var buffer = PacketByteBufs.create(); - - final var messageClass = message.getClass(); - - if (!this.endecsByClass.containsKey(messageClass)) { - throw new NetworkException("Message class '" + messageClass + "' is not registered"); - } - - final IndexedEndec endec = (IndexedEndec) this.endecsByClass.get(messageClass); - if (endec.handlerIndex(target) == -1) { - throw new NetworkException("Message class '" + messageClass + "' has no handler registered for target environment " + target); - } - - buffer.writeVarInt(endec.handlerIndex(target)); - buffer.write(endec.endec, message); - - return buffer; - } - public class ClientHandle { /** diff --git a/src/testmod/java/io/wispforest/uwu/EpicScreenHandler.java b/src/testmod/java/io/wispforest/uwu/EpicScreenHandler.java index 80cecb20..ef18e88f 100644 --- a/src/testmod/java/io/wispforest/uwu/EpicScreenHandler.java +++ b/src/testmod/java/io/wispforest/uwu/EpicScreenHandler.java @@ -3,13 +3,16 @@ import io.wispforest.owo.client.screens.ScreenUtils; import io.wispforest.owo.client.screens.SlotGenerator; import io.wispforest.owo.client.screens.SyncedProperty; +import net.minecraft.component.DataComponentTypes; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.SimpleInventory; import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; import net.minecraft.screen.ScreenHandler; import net.minecraft.screen.ScreenHandlerContext; import net.minecraft.screen.slot.SlotActionType; +import net.minecraft.text.Text; import java.util.concurrent.ThreadLocalRandom; @@ -20,6 +23,7 @@ public class EpicScreenHandler extends ScreenHandler { private final ScreenHandlerContext context; public final SyncedProperty epicNumber; + public final SyncedProperty cringeStack; public EpicScreenHandler(int syncId, PlayerInventory inventory) { this(syncId, inventory, ScreenHandlerContext.EMPTY); @@ -35,6 +39,8 @@ public EpicScreenHandler(int syncId, PlayerInventory inventory, ScreenHandlerCon this.epicNumber = this.createProperty(String.class, ""); this.epicNumber.set(generateEpicName()); + this.cringeStack = this.createProperty(ItemStack.class, ItemStack.EMPTY); + this.addClientboundMessage(MaldMessage.class, this::handleMald); this.addServerboundMessage(EpicMessage.class, this::handleEpic); } @@ -45,6 +51,10 @@ private void handleMald(MaldMessage r) { private void handleEpic(EpicMessage r) { this.epicNumber.set(generateEpicName() + " " + r.number); + + var stacc = Items.FEATHER.getDefaultStack(); + stacc.set(DataComponentTypes.CUSTOM_NAME, Text.literal(this.epicNumber.get())); + this.cringeStack.set(stacc); } @Override From 8eea7df4246ae5c9a83c34715d6345417ba2c93d Mon Sep 17 00:00:00 2001 From: Basique Date: Fri, 30 Aug 2024 23:32:24 +0300 Subject: [PATCH 09/10] add javadoc and @ApiStatus.Experimental --- src/main/java/io/wispforest/owo/ext/OwoItem.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/wispforest/owo/ext/OwoItem.java b/src/main/java/io/wispforest/owo/ext/OwoItem.java index c598dda5..908bda2f 100644 --- a/src/main/java/io/wispforest/owo/ext/OwoItem.java +++ b/src/main/java/io/wispforest/owo/ext/OwoItem.java @@ -2,9 +2,14 @@ import net.minecraft.component.ComponentChanges; import net.minecraft.component.ComponentMap; +import org.jetbrains.annotations.ApiStatus; public interface OwoItem { - default void deriveStackComponents(ComponentMap source, ComponentChanges.Builder target) { - - } + /** + * Generates component-derived-components from the stack's components + * @param source a map containing the item stack's non-derived components + * @param target a builder for the derived component map + */ + @ApiStatus.Experimental + default void deriveStackComponents(ComponentMap source, ComponentChanges.Builder target) { } } From 212005b2706c7889aec20219e818e7ae759a38ee Mon Sep 17 00:00:00 2001 From: glisco Date: Tue, 3 Sep 2024 19:20:09 +0200 Subject: [PATCH 10/10] move config screen providers into separate class to avoid initializing the screen class --- gradle.properties | 2 +- .../owo/compat/modmenu/OwoModMenuPlugin.java | 4 +- .../wispforest/owo/config/ConfigWrapper.java | 3 +- .../owo/config/OwoConfigCommand.java | 10 +-- .../owo/config/ui/ConfigScreen.java | 35 ++++------ .../owo/config/ui/ConfigScreenProviders.java | 64 +++++++++++++++++++ 6 files changed, 87 insertions(+), 31 deletions(-) create mode 100644 src/main/java/io/wispforest/owo/config/ui/ConfigScreenProviders.java diff --git a/gradle.properties b/gradle.properties index 1049e403..d7192a86 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ minecraft_version=1.21 yarn_mappings=1.21+build.2 loader_version=0.15.11 # Mod Properties -mod_version=0.12.11 +mod_version=0.12.12 maven_group=io.wispforest archives_base_name=owo-lib # Dependencies diff --git a/src/main/java/io/wispforest/owo/compat/modmenu/OwoModMenuPlugin.java b/src/main/java/io/wispforest/owo/compat/modmenu/OwoModMenuPlugin.java index 47cd8e1c..bb7308ff 100644 --- a/src/main/java/io/wispforest/owo/compat/modmenu/OwoModMenuPlugin.java +++ b/src/main/java/io/wispforest/owo/compat/modmenu/OwoModMenuPlugin.java @@ -3,7 +3,7 @@ import com.google.common.collect.ForwardingMap; import com.terraformersmc.modmenu.api.ConfigScreenFactory; import com.terraformersmc.modmenu.api.ModMenuApi; -import io.wispforest.owo.config.ui.ConfigScreen; +import io.wispforest.owo.config.ui.ConfigScreenProviders; import net.minecraft.util.Util; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -19,7 +19,7 @@ public class OwoModMenuPlugin implements ModMenuApi { protected @NotNull Map> delegate() { return Util.make( new HashMap<>(), - map -> ConfigScreen.forEachProvider((s, provider) -> map.put(s, provider::apply)) + map -> ConfigScreenProviders.forEach((s, provider) -> map.put(s, provider::apply)) ); } }; diff --git a/src/main/java/io/wispforest/owo/config/ConfigWrapper.java b/src/main/java/io/wispforest/owo/config/ConfigWrapper.java index 32b799c0..69e50d3c 100644 --- a/src/main/java/io/wispforest/owo/config/ConfigWrapper.java +++ b/src/main/java/io/wispforest/owo/config/ConfigWrapper.java @@ -12,6 +12,7 @@ import io.wispforest.owo.Owo; import io.wispforest.owo.config.annotation.*; import io.wispforest.owo.config.ui.ConfigScreen; +import io.wispforest.owo.config.ui.ConfigScreenProviders; import io.wispforest.owo.serialization.endec.MinecraftEndecs; import io.wispforest.owo.ui.core.Color; import io.wispforest.owo.util.NumberReflection; @@ -88,7 +89,7 @@ protected ConfigWrapper(Class clazz, Consumer janksonBuilder if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT && clazz.isAnnotationPresent(Modmenu.class)) { var modmenuAnnotation = clazz.getAnnotation(Modmenu.class); - ConfigScreen.registerProvider( + ConfigScreenProviders.registerOwoConfigScreen( modmenuAnnotation.modId(), screen -> ConfigScreen.createWithCustomModel(Identifier.of(modmenuAnnotation.uiModelId()), this, screen) ); diff --git a/src/main/java/io/wispforest/owo/config/OwoConfigCommand.java b/src/main/java/io/wispforest/owo/config/OwoConfigCommand.java index 8f204a64..4398ad32 100644 --- a/src/main/java/io/wispforest/owo/config/OwoConfigCommand.java +++ b/src/main/java/io/wispforest/owo/config/OwoConfigCommand.java @@ -10,10 +10,12 @@ import com.mojang.brigadier.suggestion.SuggestionsBuilder; import io.wispforest.owo.Owo; import io.wispforest.owo.config.ui.ConfigScreen; +import io.wispforest.owo.config.ui.ConfigScreenProviders; import io.wispforest.owo.ops.TextOps; import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.screen.Screen; import net.minecraft.command.CommandRegistryAccess; import net.minecraft.command.CommandSource; import net.minecraft.text.Text; @@ -35,15 +37,15 @@ public static void register(CommandDispatcher dispatc }))); } - private static class ConfigScreenArgumentType implements ArgumentType { + private static class ConfigScreenArgumentType implements ArgumentType { private static final SimpleCommandExceptionType NO_SUCH_CONFIG_SCREEN = new SimpleCommandExceptionType( TextOps.concat(Owo.PREFIX, Text.literal("no config screen with that id")) ); @Override - public ConfigScreen parse(StringReader reader) throws CommandSyntaxException { - var provider = ConfigScreen.getProvider(reader.readString()); + public Screen parse(StringReader reader) throws CommandSyntaxException { + var provider = ConfigScreenProviders.get(reader.readString()); if (provider == null) throw NO_SUCH_CONFIG_SCREEN.create(); return provider.apply(null); @@ -52,7 +54,7 @@ public ConfigScreen parse(StringReader reader) throws CommandSyntaxException { @Override public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) { var configNames = new ArrayList(); - ConfigScreen.forEachProvider((s, screenFunction) -> configNames.add(s)); + ConfigScreenProviders.forEach((s, screenFunction) -> configNames.add(s)); return CommandSource.suggestMatching(configNames, builder); } } diff --git a/src/main/java/io/wispforest/owo/config/ui/ConfigScreen.java b/src/main/java/io/wispforest/owo/config/ui/ConfigScreen.java index 57af1e9c..6bd8ebb1 100644 --- a/src/main/java/io/wispforest/owo/config/ui/ConfigScreen.java +++ b/src/main/java/io/wispforest/owo/config/ui/ConfigScreen.java @@ -28,7 +28,6 @@ import net.minecraft.util.Formatting; import net.minecraft.util.Identifier; import org.apache.commons.lang3.mutable.MutableBoolean; -import org.apache.commons.lang3.mutable.MutableInt; import org.jetbrains.annotations.Nullable; import org.lwjgl.glfw.GLFW; @@ -55,8 +54,6 @@ public class ConfigScreen extends BaseUIModelScreen { public static final Identifier DEFAULT_MODEL_ID = Identifier.of("owo", "config"); - private static final Map> CONFIG_SCREEN_PROVIDERS = new HashMap<>(); - private static final Map>, OptionComponentFactory> DEFAULT_FACTORIES = new HashMap<>(); /** * A set of extra option factories - add to this if you want to override @@ -104,35 +101,27 @@ public static ConfigScreen createWithCustomModel(Identifier modelId, ConfigWrapp } /** - * Register the given config screen provider. This is primarily - * used for making your config available in ModMenu and to the - * {@code /owo-config} command, although other places my use it as well - * - * @param modId The mod id for which to supply a config screen - * @param supplier The supplier to register - this gets the parent screen - * as argument - * @throws IllegalArgumentException If a config screen provider is - * already registered for the given mod id + * @deprecated Use {@link ConfigScreenProviders#register(String, Function)} instead */ + @Deprecated(forRemoval = true) public static void registerProvider(String modId, Function supplier) { - if (CONFIG_SCREEN_PROVIDERS.put(modId, supplier) != null) { - throw new IllegalArgumentException("Tried to register config screen provider for mod id " + modId + " twice"); - } + ConfigScreenProviders.registerOwoConfigScreen(modId, supplier); } /** - * Get the config screen provider associated with - * the given mod id - * - * @return The associated config screen provider, or {@code null} if - * none is registered + * @deprecated Use {@link ConfigScreenProviders#get(String)} instead */ + @Deprecated(forRemoval = true) public static @Nullable Function getProvider(String modId) { - return CONFIG_SCREEN_PROVIDERS.get(modId); + return ConfigScreenProviders.getOwoProvider(modId); } + /** + * @deprecated Use {@link ConfigScreenProviders#forEach(BiConsumer)} instead + */ + @Deprecated(forRemoval = true) public static void forEachProvider(BiConsumer> action) { - CONFIG_SCREEN_PROVIDERS.forEach(action); + ConfigScreenProviders.forEachOwoProvider(action); } @Override @@ -462,7 +451,7 @@ public void removed() { UIParsing.registerFactory("config-text-box", element -> new ConfigTextBox()); } - private record SearchMatches(String query, List matches) {} + protected record SearchMatches(String query, List matches) {} public static class SearchHighlighterComponent extends BaseComponent { diff --git a/src/main/java/io/wispforest/owo/config/ui/ConfigScreenProviders.java b/src/main/java/io/wispforest/owo/config/ui/ConfigScreenProviders.java new file mode 100644 index 00000000..15ccba7a --- /dev/null +++ b/src/main/java/io/wispforest/owo/config/ui/ConfigScreenProviders.java @@ -0,0 +1,64 @@ +package io.wispforest.owo.config.ui; + +import net.minecraft.client.gui.screen.Screen; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.BiConsumer; +import java.util.function.Function; + +public class ConfigScreenProviders { + + private static final Map> PROVIDERS = new HashMap<>(); + private static final Map> OWO_SCREEN_PROVIDERS = new HashMap<>(); + + /** + * Register the given config screen provider. This is primarily + * used for making a config screen available in ModMenu and to the + * {@code /owo-config} command, although other places my use it as well + * + * @param modId The mod id for which to supply a config screen + * @param supplier The supplier to register - this gets the parent screen + * as argument + * @throws IllegalArgumentException If a config screen provider is + * already registered for the given mod id + */ + public static void register(String modId, Function supplier) { + if (PROVIDERS.put(modId, supplier) != null) { + throw new IllegalArgumentException("Tried to register config screen provider for mod id " + modId + " twice"); + } + } + + /** + * Get the config screen provider associated with + * the given mod id + * + * @return The associated config screen provider, or {@code null} if + * none is registered + */ + public static @Nullable Function get(String modId) { + return PROVIDERS.get(modId); + } + + public static void forEach(BiConsumer> action) { + PROVIDERS.forEach(action); + } + + // -- internal methods for backwards-compat in ConfigScreen -- + + @ApiStatus.Internal + public static void registerOwoConfigScreen(String modId, Function supplier) { + register(modId, supplier); + OWO_SCREEN_PROVIDERS.put(modId, supplier); + } + + static @Nullable Function getOwoProvider(String modId) { + return OWO_SCREEN_PROVIDERS.get(modId); + } + + static void forEachOwoProvider(BiConsumer> action) { + OWO_SCREEN_PROVIDERS.forEach(action); + } +}