diff --git a/common/src/main/java/dev/anvilcraft/lib/data/DataProviderType.java b/common/src/main/java/dev/anvilcraft/lib/data/DataProviderType.java
index b2645cb..3291cf5 100644
--- a/common/src/main/java/dev/anvilcraft/lib/data/DataProviderType.java
+++ b/common/src/main/java/dev/anvilcraft/lib/data/DataProviderType.java
@@ -1,10 +1,14 @@
package dev.anvilcraft.lib.data;
+import net.minecraft.data.DataGenerator;
import net.minecraft.data.DataProvider;
-import net.minecraft.data.recipes.RecipeProvider;
import net.minecraft.data.tags.TagsProvider;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+import java.util.function.Consumer;
public interface DataProviderType
{
DataProviderType ITEM_MODEL = new DataProviderType<>() {
@@ -12,11 +16,40 @@ public interface DataProviderType {
DataProviderType BLOCK_MODEL = new DataProviderType<>() {
};
DataProviderType RECIPE = new DataProviderType<>() {
+ @Override
+ public void create(@NotNull DataGenerator.PackGenerator generator, @NotNull String namespace, @NotNull List> consumer) {
+ generator.addProvider(output -> {
+ RegistratorRecipeProvider provider = new RegistratorRecipeProvider(output);
+ consumer.forEach(c -> c.accept(provider));
+ return provider;
+ });
+ }
};
DataProviderType> ITEM_TAG = new DataProviderType<>() {
};
DataProviderType> BLOCK_TAG = new DataProviderType<>() {
};
DataProviderType LANG = new DataProviderType<>() {
+ @Override
+ public void create(@NotNull DataGenerator.PackGenerator generator, @NotNull String namespace, @NotNull List> consumer) {
+ generator.addProvider(output -> {
+ LanguageProvider provider = new LanguageProvider(output, namespace);
+ consumer.forEach(c -> c.accept(provider));
+ return provider;
+ });
+ generator.addProvider(output -> {
+ LanguageProvider provider = new UpsideDownLanguageProvider(output, namespace);
+ consumer.forEach(c -> c.accept(provider));
+ return provider;
+ });
+ }
};
+
+ default void create(@NotNull DataGenerator.PackGenerator generator, @NotNull String namespace, @NotNull List> consumer) {
+ }
+
+ @SuppressWarnings("unchecked")
+ default void create(@NotNull String namespace, @NotNull DataGenerator.PackGenerator generator, @NotNull List> consumer) {
+ this.create(generator, namespace, consumer.stream().map(c -> (Consumer) c).toList());
+ }
}
diff --git a/common/src/main/java/dev/anvilcraft/lib/data/LanguageProvider.java b/common/src/main/java/dev/anvilcraft/lib/data/LanguageProvider.java
index a9cb38a..4d6a1e6 100644
--- a/common/src/main/java/dev/anvilcraft/lib/data/LanguageProvider.java
+++ b/common/src/main/java/dev/anvilcraft/lib/data/LanguageProvider.java
@@ -8,12 +8,16 @@
import org.jetbrains.annotations.NotNull;
import java.nio.file.Path;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
import java.util.concurrent.CompletableFuture;
-public abstract class LanguageProvider implements DataProvider {
+public class LanguageProvider implements DataProvider {
protected final String namespace;
protected final String languageCode;
protected final PackOutput dataOutput;
+ protected final Map translations = Collections.synchronizedMap(new HashMap<>());
protected LanguageProvider(PackOutput dataOutput, String namespace, String languageCode) {
this.namespace = namespace;
@@ -21,7 +25,20 @@ protected LanguageProvider(PackOutput dataOutput, String namespace, String langu
this.dataOutput = dataOutput;
}
- public abstract void add(TranslationBuilder builder);
+ public static @NotNull LanguageProvider create(PackOutput dataOutput, String namespace, @NotNull String languageCode) {
+ if (languageCode.equals("en_ud")) {
+ return new UpsideDownLanguageProvider(dataOutput, namespace);
+ }
+ return new LanguageProvider(dataOutput, namespace, languageCode);
+ }
+
+ protected void add(@NotNull TranslationBuilder builder) {
+ this.translations.forEach(builder::add);
+ }
+
+ public void add(String translationKey, String value) {
+ this.translations.put(translationKey, value);
+ }
public LanguageProvider(PackOutput dataOutput, String namespace) {
this(dataOutput, namespace, "en_us");
@@ -36,8 +53,8 @@ public LanguageProvider(PackOutput dataOutput, String namespace) {
protected @NotNull Path getLangFilePath(String code) {
return this.dataOutput
- .createPathProvider(PackOutput.Target.RESOURCE_PACK, "lang")
- .json(new ResourceLocation(this.namespace, code));
+ .createPathProvider(PackOutput.Target.RESOURCE_PACK, "lang")
+ .json(new ResourceLocation(this.namespace, code));
}
@Override
diff --git a/common/src/main/java/dev/anvilcraft/lib/data/RegistratorRecipeProvider.java b/common/src/main/java/dev/anvilcraft/lib/data/RegistratorRecipeProvider.java
index 572fbaa..5dd8f31 100644
--- a/common/src/main/java/dev/anvilcraft/lib/data/RegistratorRecipeProvider.java
+++ b/common/src/main/java/dev/anvilcraft/lib/data/RegistratorRecipeProvider.java
@@ -5,10 +5,14 @@
import net.minecraft.data.recipes.RecipeProvider;
import org.jetbrains.annotations.NotNull;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import java.util.function.Consumer;
public class RegistratorRecipeProvider extends RecipeProvider implements Consumer {
- Consumer writer;
+ private final List recipes = Collections.synchronizedList(new ArrayList<>());
+ private Consumer writer;
public RegistratorRecipeProvider(PackOutput output) {
super(output);
@@ -17,7 +21,7 @@ public RegistratorRecipeProvider(PackOutput output) {
@Override
public void accept(FinishedRecipe finishedRecipe) {
if (this.writer == null) {
- /*TODO log error*/
+ this.recipes.add(finishedRecipe);
return;
}
this.writer.accept(finishedRecipe);
@@ -26,5 +30,6 @@ public void accept(FinishedRecipe finishedRecipe) {
@Override
public void buildRecipes(@NotNull Consumer writer) {
this.writer = writer;
+ this.recipes.forEach(writer);
}
}
diff --git a/common/src/main/java/dev/anvilcraft/lib/data/UpsideDownLanguageProvider.java b/common/src/main/java/dev/anvilcraft/lib/data/UpsideDownLanguageProvider.java
index 772b35a..92bff89 100644
--- a/common/src/main/java/dev/anvilcraft/lib/data/UpsideDownLanguageProvider.java
+++ b/common/src/main/java/dev/anvilcraft/lib/data/UpsideDownLanguageProvider.java
@@ -11,11 +11,16 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-public abstract class UpsideDownLanguageProvider extends LanguageProvider {
+public class UpsideDownLanguageProvider extends LanguageProvider {
protected UpsideDownLanguageProvider(PackOutput dataOutput, String namespace) {
super(dataOutput, namespace, "en_ud");
}
+ @Override
+ public @NotNull String getName() {
+ return "UpsideDownLanguage";
+ }
+
@Override
public @NotNull CompletableFuture> run(@NotNull CachedOutput output) {
JsonObject object = new JsonObject();
diff --git a/common/src/main/java/dev/anvilcraft/lib/registrator/AbstractRegistrator.java b/common/src/main/java/dev/anvilcraft/lib/registrator/AbstractRegistrator.java
index 6ca2701..07844fe 100644
--- a/common/src/main/java/dev/anvilcraft/lib/registrator/AbstractRegistrator.java
+++ b/common/src/main/java/dev/anvilcraft/lib/registrator/AbstractRegistrator.java
@@ -26,7 +26,7 @@
@SuppressWarnings("unused")
public abstract class AbstractRegistrator {
protected final BuilderManager manager = new BuilderManager();
- protected final Map, List>> dataProviders = Collections.synchronizedMap(new HashMap<>());
+ protected final Map, List>> dataProviders = Collections.synchronizedMap(new HashMap<>());
private final String modid;
protected AbstractRegistrator(String modid) {
@@ -70,13 +70,12 @@ public void data(DataProviderType
type, Consumer
public void init() {
}
- @SuppressWarnings("unchecked")
- protected
List> getDataProviders(DataProviderType type) {
- return (List>) (List>) this.dataProviders.getOrDefault(type, Collections.emptyList());
- }
-
@SuppressWarnings("UnusedReturnValue")
- public AbstractRegistrator initDatagen(DataGenerator generator) {
+ public AbstractRegistrator initDatagen(DataGenerator.PackGenerator generator) {
+ for (Map.Entry, List>> entry : this.dataProviders.entrySet()) {
+ entry.getKey().create(this.modid, generator, entry.getValue());
+ }
+
return this;
}
@@ -89,4 +88,8 @@ public AbstractRegistrator addBuilder(Registry registry, EntryBuilder e
protected List> getBuilders(Registry registry) {
return this.manager.getBuilders(registry);
}
+
+ public void lang(String key, String name) {
+ this.data(DataProviderType.LANG, provider -> provider.add(key, name));
+ }
}
diff --git a/common/src/main/java/dev/anvilcraft/lib/registrator/builder/EntryBuilder.java b/common/src/main/java/dev/anvilcraft/lib/registrator/builder/EntryBuilder.java
index 8cfb1fa..391b357 100644
--- a/common/src/main/java/dev/anvilcraft/lib/registrator/builder/EntryBuilder.java
+++ b/common/src/main/java/dev/anvilcraft/lib/registrator/builder/EntryBuilder.java
@@ -3,6 +3,7 @@
import dev.anvilcraft.lib.registrator.AbstractRegistrator;
import dev.anvilcraft.lib.registrator.entry.RegistryEntry;
import net.minecraft.resources.ResourceLocation;
+import org.jetbrains.annotations.NotNull;
public abstract class EntryBuilder {
protected final AbstractRegistrator registrator;
@@ -21,4 +22,22 @@ protected EntryBuilder(AbstractRegistrator registrator, String id) {
public ResourceLocation getId() {
return this.registrator.of(this.id);
}
+
+ protected static @NotNull String toTitleCase(@NotNull String input) {
+ // 使用下划线分割字符串
+ String[] parts = input.split("_");
+ StringBuilder result = new StringBuilder();
+
+ for (String part : parts) {
+ // 将每个单词的首字母转为大写,其余字母保持原样
+ if (!part.isEmpty()) {
+ result.append(Character.toUpperCase(part.charAt(0)));
+ result.append(part.substring(1));
+ }
+ result.append(" ");
+ }
+
+ // 删除最后一个多余的空格
+ return result.toString().trim();
+ }
}
diff --git a/common/src/main/java/dev/anvilcraft/lib/registrator/builder/ItemBuilder.java b/common/src/main/java/dev/anvilcraft/lib/registrator/builder/ItemBuilder.java
index 581fc54..5e66bcd 100644
--- a/common/src/main/java/dev/anvilcraft/lib/registrator/builder/ItemBuilder.java
+++ b/common/src/main/java/dev/anvilcraft/lib/registrator/builder/ItemBuilder.java
@@ -6,6 +6,7 @@
import dev.anvilcraft.lib.mixin.ItemPropertiesAccessor;
import dev.anvilcraft.lib.registrator.AbstractRegistrator;
import dev.anvilcraft.lib.registrator.entry.ItemEntry;
+import net.minecraft.Util;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.Item;
@@ -26,6 +27,7 @@ public ItemBuilder(AbstractRegistrator registrator, String id, Function(this);
+ this.lang(toTitleCase(this.id));
}
public ItemBuilder model(BiConsumer, AnvilLibItemModelProvider> consumer) {
@@ -48,7 +50,9 @@ public ItemBuilder recipe(BiConsumer, RegistratorRecipeProvider>
return this;
}
+ @SuppressWarnings("UnusedReturnValue")
public ItemBuilder lang(String name) {
+ this.registrator.lang(Util.makeDescriptionId("item", this.registrator.of(this.id)), name);
return this;
}
@@ -63,14 +67,14 @@ public ItemBuilder initProperties(Supplier- supplier) {
if (supplier instanceof ItemEntry> itemEntry) {
ItemPropertiesAccessor accessor = (ItemPropertiesAccessor) itemEntry.getItemBuilder().properties;
if (
- accessor.getMaxStackSize() != defaultProperties.getMaxStackSize()
- && thisAccessor.getMaxStackSize() == defaultProperties.getMaxStackSize()
+ accessor.getMaxStackSize() != defaultProperties.getMaxStackSize()
+ && thisAccessor.getMaxStackSize() == defaultProperties.getMaxStackSize()
) {
this.properties.stacksTo(accessor.getMaxStackSize());
}
if (
- accessor.getMaxDamage() != defaultProperties.getMaxDamage()
- && thisAccessor.getMaxDamage() == defaultProperties.getMaxDamage()
+ accessor.getMaxDamage() != defaultProperties.getMaxDamage()
+ && thisAccessor.getMaxDamage() == defaultProperties.getMaxDamage()
) {
this.properties.durability(accessor.getMaxDamage());
}
@@ -78,8 +82,8 @@ public ItemBuilder initProperties(Supplier
- supplier) {
this.properties.craftRemainder(accessor.getCraftingRemainingItem());
}
if (
- accessor.getRarity() != defaultProperties.getRarity()
- && thisAccessor.getRarity() == defaultProperties.getRarity()
+ accessor.getRarity() != defaultProperties.getRarity()
+ && thisAccessor.getRarity() == defaultProperties.getRarity()
) {
this.properties.rarity(accessor.getRarity());
}
@@ -93,8 +97,8 @@ public ItemBuilder initProperties(Supplier
- supplier) {
Item item = supplier.get();
if (item != null) {
if (
- item.getMaxDamage() != defaultProperties.getMaxDamage()
- && thisAccessor.getMaxDamage() == defaultProperties.getMaxDamage()
+ item.getMaxDamage() != defaultProperties.getMaxDamage()
+ && thisAccessor.getMaxDamage() == defaultProperties.getMaxDamage()
) {
this.properties.durability(item.getMaxDamage());
}
@@ -102,25 +106,25 @@ public ItemBuilder initProperties(Supplier
- supplier) {
this.properties.craftRemainder(item.getCraftingRemainingItem());
}
if (
- item.getRarity(new ItemStack(item)) != defaultProperties.getRarity()
- && thisAccessor.getRarity() == defaultProperties.getRarity()
+ item.getRarity(new ItemStack(item)) != defaultProperties.getRarity()
+ && thisAccessor.getRarity() == defaultProperties.getRarity()
) {
this.properties.rarity(item.getRarity(new ItemStack(item)));
}
if (
- item.getMaxStackSize() != defaultProperties.getMaxStackSize()
- && thisAccessor.getMaxStackSize() == defaultProperties.getMaxStackSize()
+ item.getMaxStackSize() != defaultProperties.getMaxStackSize()
+ && thisAccessor.getMaxStackSize() == defaultProperties.getMaxStackSize()
) {
this.properties.stacksTo(item.getMaxStackSize());
}
if (
- item.getFoodProperties() != null
- && thisAccessor.getFoodProperties() == null
+ item.getFoodProperties() != null
+ && thisAccessor.getFoodProperties() == null
) {
this.properties.food(item.getFoodProperties());
}
if (
- item.isFireResistant() && !thisAccessor.isFireResistant()
+ item.isFireResistant() && !thisAccessor.isFireResistant()
) {
this.properties.fireResistant();
}
diff --git a/fabric/src/test/generated/resources/.cache/2fc0a18b1befa47ffaddca78faee788f5ecfb9cb b/fabric/src/test/generated/resources/.cache/2fc0a18b1befa47ffaddca78faee788f5ecfb9cb
new file mode 100644
index 0000000..53487f4
--- /dev/null
+++ b/fabric/src/test/generated/resources/.cache/2fc0a18b1befa47ffaddca78faee788f5ecfb9cb
@@ -0,0 +1,3 @@
+// 1.20.1 2024-08-31T15:38:52.951909 AnvilLib Test/Recipes
+4cd064cbd4fa1437c2a145d2176b2cbb5b7ccc06 data/anvil-lib-test/advancements/recipes/misc/test.json
+5ff54d03f1e14bdfe21d703af7ab8622773d680c data/anvil-lib-test/recipes/test.json
diff --git a/fabric/src/test/generated/resources/.cache/af8f5f55c1320d7b783487b0749ad66525e7e7eb b/fabric/src/test/generated/resources/.cache/af8f5f55c1320d7b783487b0749ad66525e7e7eb
new file mode 100644
index 0000000..1f8497e
--- /dev/null
+++ b/fabric/src/test/generated/resources/.cache/af8f5f55c1320d7b783487b0749ad66525e7e7eb
@@ -0,0 +1,2 @@
+// 1.20.1 2024-08-31T15:38:52.958558 AnvilLib Test/UpsideDownLanguage
+4f2270cb5b55f19f5fd5a278fec75b064631cbfa assets/anvil-lib-test/lang/en_ud.json
diff --git a/fabric/src/test/generated/resources/.cache/be0358542ac885878a467772a460af89c9bc4d44 b/fabric/src/test/generated/resources/.cache/be0358542ac885878a467772a460af89c9bc4d44
new file mode 100644
index 0000000..dc9eac3
--- /dev/null
+++ b/fabric/src/test/generated/resources/.cache/be0358542ac885878a467772a460af89c9bc4d44
@@ -0,0 +1,2 @@
+// 1.20.1 2024-08-31T15:38:52.956432 AnvilLib Test/Language
+5cca06a243afdcb758b4e9b0c89bb9a8e102719d assets/anvil-lib-test/lang/en_us.json
diff --git a/fabric/src/test/generated/resources/assets/anvil-lib-test/lang/en_ud.json b/fabric/src/test/generated/resources/assets/anvil-lib-test/lang/en_ud.json
new file mode 100644
index 0000000..6c5dafa
--- /dev/null
+++ b/fabric/src/test/generated/resources/assets/anvil-lib-test/lang/en_ud.json
@@ -0,0 +1,3 @@
+{
+ "item.anvil-lib-test.test": "ʇsǝ⟘"
+}
\ No newline at end of file
diff --git a/fabric/src/test/generated/resources/assets/anvil-lib-test/lang/en_us.json b/fabric/src/test/generated/resources/assets/anvil-lib-test/lang/en_us.json
new file mode 100644
index 0000000..a5ea16b
--- /dev/null
+++ b/fabric/src/test/generated/resources/assets/anvil-lib-test/lang/en_us.json
@@ -0,0 +1,3 @@
+{
+ "item.anvil-lib-test.test": "Test"
+}
\ No newline at end of file
diff --git a/fabric/src/test/generated/resources/data/anvil-lib-test/advancements/recipes/misc/test.json b/fabric/src/test/generated/resources/data/anvil-lib-test/advancements/recipes/misc/test.json
new file mode 100644
index 0000000..48d4c43
--- /dev/null
+++ b/fabric/src/test/generated/resources/data/anvil-lib-test/advancements/recipes/misc/test.json
@@ -0,0 +1,35 @@
+{
+ "parent": "minecraft:recipes/root",
+ "criteria": {
+ "has_apple": {
+ "conditions": {
+ "items": [
+ {
+ "items": [
+ "minecraft:apple"
+ ]
+ }
+ ]
+ },
+ "trigger": "minecraft:inventory_changed"
+ },
+ "has_the_recipe": {
+ "conditions": {
+ "recipe": "anvil-lib-test:test"
+ },
+ "trigger": "minecraft:recipe_unlocked"
+ }
+ },
+ "requirements": [
+ [
+ "has_apple",
+ "has_the_recipe"
+ ]
+ ],
+ "rewards": {
+ "recipes": [
+ "anvil-lib-test:test"
+ ]
+ },
+ "sends_telemetry_event": false
+}
\ No newline at end of file
diff --git a/fabric/src/test/generated/resources/data/anvil-lib-test/recipes/test.json b/fabric/src/test/generated/resources/data/anvil-lib-test/recipes/test.json
new file mode 100644
index 0000000..d9aef35
--- /dev/null
+++ b/fabric/src/test/generated/resources/data/anvil-lib-test/recipes/test.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "category": "misc",
+ "key": {
+ "x": {
+ "item": "minecraft:apple"
+ }
+ },
+ "pattern": [
+ "xxx",
+ "xxx",
+ "xxx"
+ ],
+ "result": {
+ "item": "anvil-lib-test:test"
+ },
+ "show_notification": true
+}
\ No newline at end of file
diff --git a/fabric/src/test/java/dev/anvilcraft/lib/test/AnvilLibTestDataGenerator.java b/fabric/src/test/java/dev/anvilcraft/lib/test/AnvilLibTestDataGenerator.java
index 036d21c..55ab76b 100644
--- a/fabric/src/test/java/dev/anvilcraft/lib/test/AnvilLibTestDataGenerator.java
+++ b/fabric/src/test/java/dev/anvilcraft/lib/test/AnvilLibTestDataGenerator.java
@@ -2,10 +2,11 @@
import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint;
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
+import org.jetbrains.annotations.NotNull;
public class AnvilLibTestDataGenerator implements DataGeneratorEntrypoint {
@Override
- public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) {
- AnvilLibTest.REGISTRATOR.initDatagen(fabricDataGenerator);
+ public void onInitializeDataGenerator(@NotNull FabricDataGenerator fabricDataGenerator) {
+ AnvilLibTest.REGISTRATOR.initDatagen(fabricDataGenerator.createPack());
}
}
diff --git a/fabric/src/test/java/dev/anvilcraft/lib/test/TestRegisters.java b/fabric/src/test/java/dev/anvilcraft/lib/test/TestRegisters.java
index abb6ecb..f5184b8 100644
--- a/fabric/src/test/java/dev/anvilcraft/lib/test/TestRegisters.java
+++ b/fabric/src/test/java/dev/anvilcraft/lib/test/TestRegisters.java
@@ -5,6 +5,7 @@
import dev.anvilcraft.lib.registrator.entry.TagKeyEntry;
import net.minecraft.core.registries.Registries;
import net.minecraft.data.recipes.RecipeCategory;
+import net.minecraft.data.recipes.RecipeProvider;
import net.minecraft.data.recipes.ShapedRecipeBuilder;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.Items;
@@ -27,6 +28,7 @@ public class TestRegisters {
.pattern("xxx")
.pattern("xxx")
.define('x', Items.APPLE)
+ .unlockedBy("has_apple", RecipeProvider.has(Items.APPLE))
.save(provider))
.register();