diff --git a/build.gradle.kts b/build.gradle.kts index 77fffed4..e20d9799 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,8 +1,8 @@ import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale import com.diffplug.gradle.spotless.SpotlessExtension -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.databind.ObjectMapper import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import net.fabricmc.loom.api.LoomGradleExtensionAPI @@ -11,7 +11,6 @@ import net.fabricmc.loom.task.RemapJarTask import dev.architectury.plugin.ArchitectPluginExtension import me.shedaniel.unifiedpublishing.UnifiedPublishingExtension -import java.util.* plugins { java @@ -224,15 +223,18 @@ for (platform in platforms) { shadowCommon(project(path = ":common", configuration = "transformProduction${capitalise(platform)}")) { isTransitive = false } } + sourceSets { + main { + resources { + srcDir(file("src/generated/resources")) + exclude("**/.cache") + } + } + } + tasks { processResources { extra["commonProps"] = mapOf("version" to project.version) + project.properties - - from(fileTree(project(":common").file("src/generated/resources"))) { - val conventionTags = ObjectMapper().readValue(file("convention_tags.json"), object: TypeReference>() {}) - expand(conventionTags) - exclude("**/.cache") - } } withType { diff --git a/fabric/build.gradle.kts b/fabric/build.gradle.kts index 4a4805bb..f283dfdc 100644 --- a/fabric/build.gradle.kts +++ b/fabric/build.gradle.kts @@ -12,7 +12,7 @@ loom { property("fabric-api.datagen") property("fabric-api.datagen.modid", rootProject.property("modId").toString()) - property("fabric-api.datagen.output-dir", project(":common").file("src/generated/resources").absolutePath) + property("fabric-api.datagen.output-dir", file("src/generated/resources").absolutePath) property("fabric-api.datagen.strict-validation") } } diff --git a/fabric/convention_tags.json b/fabric/convention_tags.json deleted file mode 100644 index 1de6956f..00000000 --- a/fabric/convention_tags.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "copper_ingot": "c:copper_ingots", - "iron_ingot": "c:iron_ingots" -} diff --git a/fabric/src/data/java/gripe/_90/megacells/datagen/LocalisationProvider.java b/fabric/src/data/java/gripe/_90/megacells/datagen/LocalisationProvider.java index a2dd8953..8ef55790 100644 --- a/fabric/src/data/java/gripe/_90/megacells/datagen/LocalisationProvider.java +++ b/fabric/src/data/java/gripe/_90/megacells/datagen/LocalisationProvider.java @@ -1,14 +1,15 @@ package gripe._90.megacells.datagen; +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricLanguageProvider; + import gripe._90.megacells.definition.MEGABlocks; import gripe._90.megacells.definition.MEGAItems; import gripe._90.megacells.definition.MEGATranslations; -import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; -import net.fabricmc.fabric.api.datagen.v1.provider.FabricLanguageProvider; class LocalisationProvider extends FabricLanguageProvider { - protected LocalisationProvider(FabricDataOutput output, String locale) { - super(output, locale); + protected LocalisationProvider(FabricDataOutput output) { + super(output, "en_us"); } @Override diff --git a/fabric/src/data/java/gripe/_90/megacells/datagen/MEGADataGenerators.java b/fabric/src/data/java/gripe/_90/megacells/datagen/MEGADataGenerators.java index 5ee357fe..60400f52 100644 --- a/fabric/src/data/java/gripe/_90/megacells/datagen/MEGADataGenerators.java +++ b/fabric/src/data/java/gripe/_90/megacells/datagen/MEGADataGenerators.java @@ -1,6 +1,5 @@ package gripe._90.megacells.datagen; -import java.util.List; import java.util.concurrent.CompletableFuture; import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; @@ -15,17 +14,12 @@ public void onInitializeDataGenerator(FabricDataGenerator generator) { var pack = generator.createPack(); var registries = CompletableFuture.supplyAsync(VanillaRegistries::createLookup, Util.backgroundExecutor()); - var blockTagsProvider = pack - .addProvider((FabricDataOutput packOutput) -> new TagProvider.Blocks(packOutput, registries)); - pack.addProvider( - (FabricDataOutput packOutput) -> new TagProvider.Items(packOutput, registries, blockTagsProvider)); + var blockTags = pack.addProvider((FabricDataOutput output) -> new TagProvider.Blocks(output, registries)); + pack.addProvider((FabricDataOutput output) -> new TagProvider.Items(output, registries, blockTags)); - pack.addProvider(LootTableProvider::new); pack.addProvider(ModelProvider::new); pack.addProvider(RecipeProvider::new); - - for (var en : List.of("en_us", "en_gb", "en_ca", "en_au", "en_nz")) { - pack.addProvider((FabricDataOutput packOutput) -> new LocalisationProvider(packOutput, en)); - } + pack.addProvider(LootTableProvider::new); + pack.addProvider(LocalisationProvider::new); } } diff --git a/fabric/src/data/java/gripe/_90/megacells/datagen/ModelProvider.java b/fabric/src/data/java/gripe/_90/megacells/datagen/ModelProvider.java index f4ed0757..38670beb 100644 --- a/fabric/src/data/java/gripe/_90/megacells/datagen/ModelProvider.java +++ b/fabric/src/data/java/gripe/_90/megacells/datagen/ModelProvider.java @@ -7,6 +7,7 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; import com.ibm.icu.impl.Pair; import org.jetbrains.annotations.NotNull; @@ -19,6 +20,7 @@ import net.minecraft.data.models.blockstates.PropertyDispatch; import net.minecraft.data.models.blockstates.Variant; import net.minecraft.data.models.blockstates.VariantProperties; +import net.minecraft.data.models.blockstates.VariantProperty; import net.minecraft.data.models.model.DelegatedModel; import net.minecraft.data.models.model.ModelTemplate; import net.minecraft.data.models.model.ModelTemplates; @@ -26,6 +28,7 @@ import net.minecraft.data.models.model.TextureSlot; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; import appeng.api.orientation.BlockOrientation; import appeng.block.crafting.AbstractCraftingUnitBlock; @@ -64,6 +67,9 @@ class ModelProvider extends FabricModelProvider { Optional.of(AppEng.makeId("item/cable_interface")), Optional.empty(), SIDES, TextureSlot.BACK, TextureSlot.FRONT); + private static final VariantProperty Z_ROT = new VariantProperty<>("ae2:z", + r -> new JsonPrimitive(r.ordinal() * 90)); + ModelProvider(FabricDataOutput output) { super(output); } @@ -91,8 +97,6 @@ public void generateBlockStateModels(BlockModelGenerators generator) { @Override public void generateItemModels(ItemModelGenerators generator) { - generatePartModels(generator); - generator.generateFlatItem(MEGAItems.MEGA_ITEM_CELL_HOUSING.asItem(), ModelTemplates.FLAT_ITEM); generator.generateFlatItem(MEGAItems.MEGA_FLUID_CELL_HOUSING.asItem(), ModelTemplates.FLAT_ITEM); @@ -141,6 +145,8 @@ public void generateItemModels(ItemModelGenerators generator) { driveCell("mega_item_cell", generator); driveCell("mega_fluid_cell", generator); driveCell("bulk_item_cell", generator); + + generatePartModels(generator); } private void generatePartModels(ItemModelGenerators generator) { @@ -153,8 +159,8 @@ private void cellModel(ItemDefinition cell, ItemModelGenerators generator) { .put(TextureSlot.LAYER1, AppEng.makeId("item/storage_cell_led")), generator.output); } - private void portableModel(ItemDefinition portable, String screenType, - ResourceLocation housingTexture, ItemModelGenerators generator) { + private void portableModel(ItemDefinition portable, String screenType, ResourceLocation housingTexture, + ItemModelGenerators generator) { var path = portable.id().getPath(); var tierSuffix = path.substring(path.lastIndexOf('_') + 1); PORTABLE.create(Utils.makeId("item/" + portable.id().getPath()), new TextureMapping() @@ -187,22 +193,30 @@ private void craftingUnit(Block block, String texture, BlockModelGenerators gene } private void craftingMonitor(BlockModelGenerators generator) { - var formed = Utils.makeId("block/crafting/monitor_formed"); var unformed = Utils.makeId("block/crafting/monitor"); var unit = Utils.makeId("block/crafting/unit"); + var unformedModel = ModelTemplates.CUBE.create(unformed, new TextureMapping() + .put(TextureSlot.NORTH, unformed) + .put(TextureSlot.EAST, unit) + .put(TextureSlot.SOUTH, unit) + .put(TextureSlot.WEST, unit) + .put(TextureSlot.DOWN, unit) + .put(TextureSlot.UP, unit) + .put(TextureSlot.PARTICLE, unformed), generator.modelOutput); + + var formedModel = Utils.makeId("block/crafting/monitor_formed"); generator.blockStateOutput.accept(MultiVariantGenerator.multiVariant(MEGABlocks.CRAFTING_MONITOR.block()) - .with(PropertyDispatch.property(AbstractCraftingUnitBlock.FORMED) - .select(false, Variant.variant().with(VariantProperties.MODEL, - ModelTemplates.CUBE.create(unformed, new TextureMapping() - .put(TextureSlot.NORTH, unformed) - .put(TextureSlot.EAST, unit) - .put(TextureSlot.SOUTH, unit) - .put(TextureSlot.WEST, unit) - .put(TextureSlot.DOWN, unit) - .put(TextureSlot.UP, unit) - .put(TextureSlot.PARTICLE, unformed), generator.modelOutput))) - .select(true, Variant.variant().with(VariantProperties.MODEL, formed)))); - generator.modelOutput.accept(formed, () -> customModelLoader(formed)); + .with(PropertyDispatch.properties(AbstractCraftingUnitBlock.FORMED, BlockStateProperties.FACING) + .generate((formed, facing) -> { + if (formed) { + return Variant.variant().with(VariantProperties.MODEL, formedModel); + } else { + return applyOrientation( + Variant.variant().with(VariantProperties.MODEL, unformedModel), + BlockOrientation.get(facing)); + } + }))); + generator.modelOutput.accept(formedModel, () -> customModelLoader(formedModel)); generator.delegateItemModel(MEGABlocks.CRAFTING_MONITOR.block(), unformed); } @@ -234,20 +248,42 @@ private void patternProviderBlock(BlockModelGenerators generator) { return Variant.variant().with(VariantProperties.MODEL, normal); } else { var orientation = BlockOrientation.get(forward); - - // + 90 because the default model is oriented UP, while block orientation assumes NORTH - var angleX = normalizeAngle(orientation.getAngleX() + 90); - var angleY = normalizeAngle(orientation.getAngleY()); - - return Variant.variant().with(VariantProperties.MODEL, oriented) - .with(VariantProperties.X_ROT, rotationByAngle(angleX)) - .with(VariantProperties.Y_ROT, rotationByAngle(angleY)); + return applyRotation( + Variant.variant().with(VariantProperties.MODEL, oriented), + // + 90 because the default model is oriented UP, while block orientation assumes NORTH + orientation.getAngleX() + 90, + orientation.getAngleY(), + 0); } }))); generator.delegateItemModel(MEGABlocks.MEGA_PATTERN_PROVIDER.block(), normal); } + protected Variant applyOrientation(Variant variant, BlockOrientation orientation) { + return applyRotation(variant, + orientation.getAngleX(), + orientation.getAngleY(), + orientation.getAngleZ()); + } + + protected Variant applyRotation(Variant variant, int angleX, int angleY, int angleZ) { + angleX = normalizeAngle(angleX); + angleY = normalizeAngle(angleY); + angleZ = normalizeAngle(angleZ); + + if (angleX != 0) { + variant = variant.with(VariantProperties.X_ROT, rotationByAngle(angleX)); + } + if (angleY != 0) { + variant = variant.with(VariantProperties.Y_ROT, rotationByAngle(angleY)); + } + if (angleZ != 0) { + variant = variant.with(Z_ROT, rotationByAngle(angleZ)); + } + return variant; + } + private int normalizeAngle(int angle) { return angle - (angle / 360) * 360; } diff --git a/fabric/src/data/java/gripe/_90/megacells/datagen/RecipeProvider.java b/fabric/src/data/java/gripe/_90/megacells/datagen/RecipeProvider.java index c7064350..16a10c09 100644 --- a/fabric/src/data/java/gripe/_90/megacells/datagen/RecipeProvider.java +++ b/fabric/src/data/java/gripe/_90/megacells/datagen/RecipeProvider.java @@ -1,11 +1,6 @@ package gripe._90.megacells.datagen; -import java.util.Collection; -import java.util.Collections; import java.util.function.Consumer; -import java.util.stream.Stream; - -import com.google.gson.JsonObject; import org.jetbrains.annotations.NotNull; @@ -16,7 +11,8 @@ import net.minecraft.data.recipes.RecipeCategory; import net.minecraft.data.recipes.ShapedRecipeBuilder; import net.minecraft.data.recipes.ShapelessRecipeBuilder; -import net.minecraft.world.item.ItemStack; +import net.minecraft.tags.TagKey; +import net.minecraft.world.item.Item; import net.minecraft.world.item.Items; import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.level.ItemLike; @@ -39,9 +35,6 @@ import gripe._90.megacells.util.Utils; class RecipeProvider extends FabricRecipeProvider { - private static final String IRON_INGOT = "iron_ingot"; - private static final String COPPER_INGOT = "copper_ingot"; - RecipeProvider(FabricDataOutput output) { super(output); } @@ -55,19 +48,19 @@ public void buildRecipes(@NotNull Consumer consumer) { component(consumer, MEGAItems.TIER_64M, MEGAItems.TIER_16M, AEItems.MATTER_BALL.asItem()); component(consumer, MEGAItems.TIER_256M, MEGAItems.TIER_64M, AEItems.MATTER_BALL.asItem()); - housing(consumer, MEGAItems.MEGA_ITEM_CELL_HOUSING, IRON_INGOT); - housing(consumer, MEGAItems.MEGA_FLUID_CELL_HOUSING, COPPER_INGOT); + housing(consumer, MEGAItems.MEGA_ITEM_CELL_HOUSING, ConventionTags.IRON_INGOT); + housing(consumer, MEGAItems.MEGA_FLUID_CELL_HOUSING, ConventionTags.COPPER_INGOT); - cell(consumer, MEGAItems.ITEM_CELL_1M, MEGAItems.CELL_COMPONENT_1M, MEGAItems.MEGA_ITEM_CELL_HOUSING, IRON_INGOT); - cell(consumer, MEGAItems.ITEM_CELL_4M, MEGAItems.CELL_COMPONENT_4M, MEGAItems.MEGA_ITEM_CELL_HOUSING, IRON_INGOT); - cell(consumer, MEGAItems.ITEM_CELL_16M, MEGAItems.CELL_COMPONENT_16M, MEGAItems.MEGA_ITEM_CELL_HOUSING, IRON_INGOT); - cell(consumer, MEGAItems.ITEM_CELL_64M, MEGAItems.CELL_COMPONENT_64M, MEGAItems.MEGA_ITEM_CELL_HOUSING, IRON_INGOT); - cell(consumer, MEGAItems.ITEM_CELL_256M, MEGAItems.CELL_COMPONENT_256M, MEGAItems.MEGA_ITEM_CELL_HOUSING, IRON_INGOT); - cell(consumer, MEGAItems.FLUID_CELL_1M, MEGAItems.CELL_COMPONENT_1M, MEGAItems.MEGA_FLUID_CELL_HOUSING, COPPER_INGOT); - cell(consumer, MEGAItems.FLUID_CELL_4M, MEGAItems.CELL_COMPONENT_4M, MEGAItems.MEGA_FLUID_CELL_HOUSING, COPPER_INGOT); - cell(consumer, MEGAItems.FLUID_CELL_16M, MEGAItems.CELL_COMPONENT_16M, MEGAItems.MEGA_FLUID_CELL_HOUSING, COPPER_INGOT); - cell(consumer, MEGAItems.FLUID_CELL_64M, MEGAItems.CELL_COMPONENT_64M, MEGAItems.MEGA_FLUID_CELL_HOUSING, COPPER_INGOT); - cell(consumer, MEGAItems.FLUID_CELL_256M, MEGAItems.CELL_COMPONENT_256M, MEGAItems.MEGA_FLUID_CELL_HOUSING, COPPER_INGOT); + cell(consumer, MEGAItems.ITEM_CELL_1M, MEGAItems.CELL_COMPONENT_1M, MEGAItems.MEGA_ITEM_CELL_HOUSING, ConventionTags.IRON_INGOT); + cell(consumer, MEGAItems.ITEM_CELL_4M, MEGAItems.CELL_COMPONENT_4M, MEGAItems.MEGA_ITEM_CELL_HOUSING, ConventionTags.IRON_INGOT); + cell(consumer, MEGAItems.ITEM_CELL_16M, MEGAItems.CELL_COMPONENT_16M, MEGAItems.MEGA_ITEM_CELL_HOUSING, ConventionTags.IRON_INGOT); + cell(consumer, MEGAItems.ITEM_CELL_64M, MEGAItems.CELL_COMPONENT_64M, MEGAItems.MEGA_ITEM_CELL_HOUSING, ConventionTags.IRON_INGOT); + cell(consumer, MEGAItems.ITEM_CELL_256M, MEGAItems.CELL_COMPONENT_256M, MEGAItems.MEGA_ITEM_CELL_HOUSING, ConventionTags.IRON_INGOT); + cell(consumer, MEGAItems.FLUID_CELL_1M, MEGAItems.CELL_COMPONENT_1M, MEGAItems.MEGA_FLUID_CELL_HOUSING, ConventionTags.COPPER_INGOT); + cell(consumer, MEGAItems.FLUID_CELL_4M, MEGAItems.CELL_COMPONENT_4M, MEGAItems.MEGA_FLUID_CELL_HOUSING, ConventionTags.COPPER_INGOT); + cell(consumer, MEGAItems.FLUID_CELL_16M, MEGAItems.CELL_COMPONENT_16M, MEGAItems.MEGA_FLUID_CELL_HOUSING, ConventionTags.COPPER_INGOT); + cell(consumer, MEGAItems.FLUID_CELL_64M, MEGAItems.CELL_COMPONENT_64M, MEGAItems.MEGA_FLUID_CELL_HOUSING, ConventionTags.COPPER_INGOT); + cell(consumer, MEGAItems.FLUID_CELL_256M, MEGAItems.CELL_COMPONENT_256M, MEGAItems.MEGA_FLUID_CELL_HOUSING, ConventionTags.COPPER_INGOT); portable(consumer, MEGAItems.PORTABLE_ITEM_CELL_1M, MEGAItems.CELL_COMPONENT_1M, MEGAItems.MEGA_ITEM_CELL_HOUSING); portable(consumer, MEGAItems.PORTABLE_ITEM_CELL_4M, MEGAItems.CELL_COMPONENT_4M, MEGAItems.MEGA_ITEM_CELL_HOUSING); @@ -145,7 +138,7 @@ public void buildRecipes(@NotNull Consumer consumer) { .pattern("ICI") .pattern("E#E") .pattern("ILI") - .define('I', placeholderTag(IRON_INGOT)) + .define('I', ConventionTags.IRON_INGOT) .define('C', AEItems.CALCULATION_PROCESSOR) .define('E', AEItems.ENGINEERING_PROCESSOR) .define('L', AEItems.LOGIC_PROCESSOR) @@ -158,7 +151,7 @@ public void buildRecipes(@NotNull Consumer consumer) { .pattern("VPV") .pattern("ICI") .define('C', AEItems.CALCULATION_PROCESSOR) - .define('I', placeholderTag(IRON_INGOT)) + .define('I', ConventionTags.IRON_INGOT) .define('P', AEBlocks.PATTERN_PROVIDER) .define('V', AEBlocks.QUARTZ_VIBRANT_GLASS) .unlockedBy("has_pattern_provider", has(ConventionTags.PATTERN_PROVIDER)) @@ -209,7 +202,7 @@ private void specialisedComponent(Consumer consumer, ItemLike to } private void cell(Consumer consumer, ItemDefinition cell, ItemDefinition component, - ItemDefinition housing, String housingMaterial) { + ItemDefinition housing, TagKey housingMaterial) { ShapedRecipeBuilder.shaped(RecipeCategory.MISC, cell) .pattern("aba") .pattern("bcb") @@ -217,7 +210,7 @@ private void cell(Consumer consumer, ItemDefinition cell, Ite .define('a', AEBlocks.QUARTZ_VIBRANT_GLASS) .define('b', AEItems.SKY_DUST) .define('c', component) - .define('d', placeholderTag(housingMaterial)) + .define('d', housingMaterial) .unlockedBy("has_" + component.id().getPath(), has(component)) .save(consumer, Utils.makeId("cells/standard/" + cell.id().getPath())); @@ -242,14 +235,14 @@ private void portable(Consumer consumer, ItemDefinition cell, .save(consumer, Utils.makeId("cells/portable/" + cell.id().getPath())); } - private void housing(Consumer consumer, ItemDefinition housing, String housingMaterial) { + private void housing(Consumer consumer, ItemDefinition housing, TagKey housingMaterial) { ShapedRecipeBuilder.shaped(RecipeCategory.MISC, housing) .pattern("aba") .pattern("b b") .pattern("ddd") .define('a', AEBlocks.QUARTZ_VIBRANT_GLASS) .define('b', AEItems.SKY_DUST) - .define('d', placeholderTag(housingMaterial)) + .define('d', housingMaterial) .unlockedBy("has_dusts/sky_stone", has(AEItems.SKY_DUST)) .save(consumer, Utils.makeId("cells/" + housing.id().getPath())); } @@ -279,24 +272,4 @@ private void manaCells(Consumer consumer, ItemDefinition cell .unlockedBy("has_dense_energy_cell", has(AEBlocks.DENSE_ENERGY_CELL)) .save(consumer, Utils.makeId("cells/portable/" + portable.id().getPath())); } - - private Ingredient placeholderTag(String placeholder) { - return Ingredient.fromValues(Stream.of(new PlaceholderTagValue(placeholder))); - } - - private record PlaceholderTagValue(String placeholder) implements Ingredient.Value { - @NotNull - @Override - public Collection getItems() { - return Collections.emptyList(); - } - - @NotNull - @Override - public JsonObject serialize() { - var tag = new JsonObject(); - tag.addProperty("tag", "$" + placeholder); - return tag; - } - } } diff --git a/forge/build.gradle.kts b/forge/build.gradle.kts index df281118..57f8608e 100644 --- a/forge/build.gradle.kts +++ b/forge/build.gradle.kts @@ -1,14 +1,26 @@ -val generated = file("src/generated/resources") - loom { val modId: String by project runs { create("data") { data() + name("Minecraft Data") + programArgs("--all", "--mod", modId) - programArgs("--output", generated.absolutePath) + programArgs("--output", file("src/generated/resources").absolutePath) + programArgs("--existing", project(":common").file("src/main/resources").absolutePath) programArgs("--existing", file("src/main/resources").absolutePath) + + mods { + create(modId) { + // this doesn't actually work yet for the time being + sourceSet(sourceSets.create("data") { + val main = sourceSets.main.get() + compileClasspath += main.compileClasspath + main.output + runtimeClasspath += main.runtimeClasspath + main.output + }) + } + } } } @@ -90,15 +102,6 @@ dependencies { modRuntimeOnly("curse.maven:jade-324717:${property("jadeFile")}") } -sourceSets { - main { - resources { - srcDir(generated) - exclude("**/.cache") - } - } -} - tasks.processResources { filesMatching("META-INF/mods.toml") { val commonProps: Map by extra diff --git a/forge/convention_tags.json b/forge/convention_tags.json deleted file mode 100644 index c7d6f5b3..00000000 --- a/forge/convention_tags.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "copper_ingot": "forge:ingots/copper", - "iron_ingot": "forge:ingots/iron" -} diff --git a/forge/src/main/java/gripe/_90/megacells/datagen/LocalisationProvider.java b/forge/src/main/java/gripe/_90/megacells/datagen/LocalisationProvider.java new file mode 100644 index 00000000..49286915 --- /dev/null +++ b/forge/src/main/java/gripe/_90/megacells/datagen/LocalisationProvider.java @@ -0,0 +1,25 @@ +package gripe._90.megacells.datagen; + +import net.minecraft.data.PackOutput; +import net.minecraftforge.common.data.LanguageProvider; + +import gripe._90.megacells.definition.MEGABlocks; +import gripe._90.megacells.definition.MEGAItems; +import gripe._90.megacells.definition.MEGATranslations; +import gripe._90.megacells.util.Utils; + +class LocalisationProvider extends LanguageProvider { + public LocalisationProvider(PackOutput output) { + super(output, Utils.MODID, "en_us"); + } + + @Override + protected void addTranslations() { + MEGAItems.getItems().forEach(item -> add(item.asItem(), item.getEnglishName())); + MEGABlocks.getBlocks().forEach(block -> add(block.block(), block.getEnglishName())); + + for (var translation : MEGATranslations.values()) { + add(translation.getTranslationKey(), translation.getEnglishText()); + } + } +} diff --git a/forge/src/main/java/gripe/_90/megacells/datagen/LootTableProvider.java b/forge/src/main/java/gripe/_90/megacells/datagen/LootTableProvider.java new file mode 100644 index 00000000..e8e3a37a --- /dev/null +++ b/forge/src/main/java/gripe/_90/megacells/datagen/LootTableProvider.java @@ -0,0 +1,47 @@ +package gripe._90.megacells.datagen; + +import java.util.List; +import java.util.Set; + +import org.jetbrains.annotations.NotNull; + +import net.minecraft.data.PackOutput; +import net.minecraft.data.loot.BlockLootSubProvider; +import net.minecraft.world.flag.FeatureFlags; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.storage.loot.LootPool; +import net.minecraft.world.level.storage.loot.LootTable; +import net.minecraft.world.level.storage.loot.entries.LootItem; +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; +import net.minecraft.world.level.storage.loot.predicates.ExplosionCondition; +import net.minecraft.world.level.storage.loot.providers.number.ConstantValue; + +import appeng.core.definitions.BlockDefinition; + +import gripe._90.megacells.definition.MEGABlocks; + +class LootTableProvider extends net.minecraft.data.loot.LootTableProvider { + public LootTableProvider(PackOutput output) { + super(output, Set.of(), List.of(new SubProviderEntry(BlockLoot::new, LootContextParamSets.BLOCK))); + } + + private static class BlockLoot extends BlockLootSubProvider { + protected BlockLoot() { + super(Set.of(), FeatureFlags.DEFAULT_FLAGS); + } + + @Override + protected void generate() { + for (var block : getKnownBlocks()) { + add(block, LootTable.lootTable().withPool(LootPool.lootPool().setRolls(ConstantValue.exactly(1)) + .add(LootItem.lootTableItem(block)).when(ExplosionCondition.survivesExplosion()))); + } + } + + @NotNull + @Override + protected Iterable getKnownBlocks() { + return MEGABlocks.getBlocks().stream().map(BlockDefinition::block).map(Block.class::cast)::iterator; + } + } +} diff --git a/forge/src/main/java/gripe/_90/megacells/datagen/MEGADataGenerators.java b/forge/src/main/java/gripe/_90/megacells/datagen/MEGADataGenerators.java new file mode 100644 index 00000000..8bd36f8e --- /dev/null +++ b/forge/src/main/java/gripe/_90/megacells/datagen/MEGADataGenerators.java @@ -0,0 +1,33 @@ +package gripe._90.megacells.datagen; + +import java.util.concurrent.CompletableFuture; + +import net.minecraft.Util; +import net.minecraft.data.registries.VanillaRegistries; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.data.event.GatherDataEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +import gripe._90.megacells.util.Utils; + +@Mod.EventBusSubscriber(modid = Utils.MODID, bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) +public class MEGADataGenerators { + @SubscribeEvent + public static void onGatherData(GatherDataEvent event) { + var pack = event.getGenerator().getVanillaPack(true); + var existing = event.getExistingFileHelper(); + + var registries = CompletableFuture.supplyAsync(VanillaRegistries::createLookup, Util.backgroundExecutor()); + var blockTags = pack.addProvider(output -> new TagProvider.Blocks(output, registries, existing)); + pack.addProvider(output -> new TagProvider.Items(output, registries, blockTags.contentsGetter(), existing)); + + pack.addProvider(output -> new ModelProvider.Items(output, existing)); + pack.addProvider(output -> new ModelProvider.Blocks(output, existing)); + pack.addProvider(output -> new ModelProvider.Parts(output, existing)); + + pack.addProvider(RecipeProvider::new); + pack.addProvider(LootTableProvider::new); + pack.addProvider(LocalisationProvider::new); + } +} diff --git a/forge/src/main/java/gripe/_90/megacells/datagen/ModelProvider.java b/forge/src/main/java/gripe/_90/megacells/datagen/ModelProvider.java new file mode 100644 index 00000000..4d594516 --- /dev/null +++ b/forge/src/main/java/gripe/_90/megacells/datagen/ModelProvider.java @@ -0,0 +1,323 @@ +package gripe._90.megacells.datagen; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gson.JsonPrimitive; +import com.ibm.icu.impl.Pair; + +import org.jetbrains.annotations.NotNull; + +import net.minecraft.data.PackOutput; +import net.minecraft.data.models.blockstates.MultiVariantGenerator; +import net.minecraft.data.models.blockstates.PropertyDispatch; +import net.minecraft.data.models.blockstates.Variant; +import net.minecraft.data.models.blockstates.VariantProperties; +import net.minecraft.data.models.blockstates.VariantProperty; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.PackType; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraftforge.client.model.generators.BlockModelBuilder; +import net.minecraftforge.client.model.generators.BlockStateProvider; +import net.minecraftforge.client.model.generators.ConfiguredModel; +import net.minecraftforge.client.model.generators.ItemModelProvider; +import net.minecraftforge.client.model.generators.ModelFile; +import net.minecraftforge.common.data.ExistingFileHelper; + +import appeng.api.orientation.BlockOrientation; +import appeng.block.crafting.AbstractCraftingUnitBlock; +import appeng.block.networking.EnergyCellBlock; +import appeng.core.AppEng; +import appeng.core.definitions.BlockDefinition; +import appeng.core.definitions.ItemDefinition; +import appeng.init.client.InitItemModelsProperties; + +import gripe._90.megacells.block.MEGAPatternProviderBlock; +import gripe._90.megacells.definition.MEGABlocks; +import gripe._90.megacells.definition.MEGAItems; +import gripe._90.megacells.definition.MEGAParts; +import gripe._90.megacells.util.Utils; + +abstract class ModelProvider { + static class Items extends ItemModelProvider { + // spotless:off + private static final ResourceLocation CRAFTING_PATTERN = AppEng.makeId("item/crafting_pattern"); + + private static final ResourceLocation STORAGE_CELL_LED = AppEng.makeId("item/storage_cell_led"); + private static final ResourceLocation PORTABLE_CELL_LED = AppEng.makeId("item/portable_cell_led"); + + private static final ResourceLocation PORTABLE_CELL_ITEM_HOUSING = AppEng.makeId("item/portable_cell_item_housing"); + private static final ResourceLocation PORTABLE_CELL_FLUID_HOUSING = AppEng.makeId("item/portable_cell_fluid_housing"); + + private static final ResourceLocation CABLE_INTERFACE = AppEng.makeId("item/cable_interface"); + //spotless:on + + public Items(PackOutput output, ExistingFileHelper existing) { + super(output, Utils.MODID, existing); + existing.trackGenerated(CRAFTING_PATTERN, TEXTURE); + existing.trackGenerated(STORAGE_CELL_LED, TEXTURE); + existing.trackGenerated(PORTABLE_CELL_LED, TEXTURE); + existing.trackGenerated(PORTABLE_CELL_ITEM_HOUSING, TEXTURE); + existing.trackGenerated(PORTABLE_CELL_FLUID_HOUSING, TEXTURE); + existing.trackGenerated(CABLE_INTERFACE, MODEL); + } + + @Override + protected void registerModels() { + basicItem(MEGAItems.MEGA_ITEM_CELL_HOUSING.asItem()); + basicItem(MEGAItems.MEGA_FLUID_CELL_HOUSING.asItem()); + + basicItem(MEGAItems.CELL_COMPONENT_1M.asItem()); + basicItem(MEGAItems.CELL_COMPONENT_4M.asItem()); + basicItem(MEGAItems.CELL_COMPONENT_16M.asItem()); + basicItem(MEGAItems.CELL_COMPONENT_64M.asItem()); + basicItem(MEGAItems.CELL_COMPONENT_256M.asItem()); + basicItem(MEGAItems.BULK_CELL_COMPONENT.asItem()); + + basicItem(MEGAItems.GREATER_ENERGY_CARD.asItem()); + basicItem(MEGAItems.COMPRESSION_CARD.asItem()); + + singleTexture(MEGAItems.DECOMPRESSION_PATTERN.id().getPath(), mcLoc("item/generated"), "layer0", + CRAFTING_PATTERN); + + MEGAItems.getItemPortables().forEach(p -> portableModel(p, "item", PORTABLE_CELL_ITEM_HOUSING)); + MEGAItems.getFluidPortables().forEach(p -> portableModel(p, "fluid", PORTABLE_CELL_FLUID_HOUSING)); + + var cells = new ArrayList<>(MEGAItems.getItemCells()); + cells.addAll(MEGAItems.getFluidCells()); + cells.add(MEGAItems.BULK_ITEM_CELL); + + cells.forEach(this::cellModel); + + patternProviderPart(); + } + + private void cellModel(ItemDefinition cell) { + var path = cell.id().getPath(); + singleTexture(path, mcLoc("item/generated"), "layer0", Utils.makeId("item/cell/standard/" + path)) + .texture("layer1", STORAGE_CELL_LED); + } + + private void portableModel(ItemDefinition portable, String screenType, ResourceLocation housingTexture) { + var path = portable.id().getPath(); + var tierSuffix = path.substring(path.lastIndexOf('_') + 1); + singleTexture(path, mcLoc("item/generated"), "layer0", + Utils.makeId("item/cell/portable/portable_cell_%s_screen".formatted(screenType))) + .texture("layer1", PORTABLE_CELL_LED).texture("layer2", housingTexture) + .texture("layer3", "item/cell/portable/portable_cell_side_%s".formatted(tierSuffix)); + } + + private void patternProviderPart() { + withExistingParent(MEGAParts.MEGA_PATTERN_PROVIDER.id().getPath(), CABLE_INTERFACE) + .texture("back", "part/mega_monitor_back") + .texture("front", "part/mega_pattern_provider") + .texture("sides", "part/mega_monitor_sides"); + } + } + + static class Blocks extends BlockStateProvider { + // because for whatever reason this isn't fucking accessible from BlockStateProvider + private static final ExistingFileHelper.ResourceType MODEL = new ExistingFileHelper.ResourceType( + PackType.CLIENT_RESOURCES, ".json", "models"); + + private static final VariantProperty Z_ROT = new VariantProperty<>("ae2:z", + r -> new JsonPrimitive(r.ordinal() * 90)); + + private static final ResourceLocation DRIVE_CELL = AppEng.makeId("block/drive/drive_cell"); + + public Blocks(PackOutput output, ExistingFileHelper existing) { + super(output, Utils.MODID, existing); + existing.trackGenerated(DRIVE_CELL, MODEL); + } + + @Override + protected void registerStatesAndModels() { + energyCell(); + patternProvider(); + + var craftingUnits = List.of( + Pair.of(MEGABlocks.MEGA_CRAFTING_UNIT, "unit"), + Pair.of(MEGABlocks.CRAFTING_STORAGE_1M, "1m_storage"), + Pair.of(MEGABlocks.CRAFTING_STORAGE_4M, "4m_storage"), + Pair.of(MEGABlocks.CRAFTING_STORAGE_16M, "16m_storage"), + Pair.of(MEGABlocks.CRAFTING_STORAGE_64M, "64m_storage"), + Pair.of(MEGABlocks.CRAFTING_STORAGE_256M, "256m_storage"), + Pair.of(MEGABlocks.CRAFTING_ACCELERATOR, "accelerator")); + craftingUnits.forEach(block -> craftingModel(block.first, block.second)); + craftingMonitor(); + + driveCell("mega_item_cell"); + driveCell("mega_fluid_cell"); + driveCell("bulk_item_cell"); + } + + private void driveCell(String texture) { + var path = "block/drive/cells/" + texture; + models().withExistingParent(path, DRIVE_CELL).texture("cell", path); + } + + private void energyCell() { + var cell = MEGABlocks.MEGA_ENERGY_CELL; + var path = cell.id().getPath(); + var blockBuilder = getVariantBuilder(cell.block()); + var models = new ArrayList(); + + for (var i = 0; i < 5; i++) { + var model = models().cubeAll(path + "_" + i, Utils.makeId("block/" + path + "_" + i)); + blockBuilder.partialState().with(EnergyCellBlock.ENERGY_STORAGE, i) + .setModels(new ConfiguredModel(model)); + models.add(model); + } + + var item = itemModels().withExistingParent(path, models.get(0).getLocation()); + + for (var i = 1; i < models.size(); i++) { + float fillFactor = i / (float) models.size(); + item.override() + .predicate(InitItemModelsProperties.ENERGY_FILL_LEVEL_ID, fillFactor) + .model(models.get(i)); + } + } + + private void craftingModel(BlockDefinition block, String name) { + var blockModel = models().cubeAll("block/crafting/" + name, Utils.makeId("block/crafting/" + name)); + getVariantBuilder(block.block()) + .partialState().with(AbstractCraftingUnitBlock.FORMED, false) + .setModels(new ConfiguredModel(blockModel)) + .partialState().with(AbstractCraftingUnitBlock.FORMED, true) + .setModels(new ConfiguredModel(models().getBuilder("ae2:block/crafting/mega_" + name + "_formed"))); + simpleBlockItem(block.block(), blockModel); + } + + private void craftingMonitor() { + var formedModel = AppEng.makeId("block/crafting/mega_monitor_formed"); + models().getBuilder("ae2:block/crafting/mega_monitor_formed"); + + var monitor = Utils.makeId("block/crafting/monitor"); + var unit = Utils.makeId("block/crafting/unit"); + var unformedModel = models().cube("block/crafting/mega_monitor", unit, unit, monitor, unit, unit, unit) + .texture("particle", monitor); + + multiVariantGenerator(MEGABlocks.CRAFTING_MONITOR) + .with(PropertyDispatch.properties(AbstractCraftingUnitBlock.FORMED, BlockStateProperties.FACING) + .generate((formed, facing) -> { + if (formed) { + return Variant.variant().with(VariantProperties.MODEL, formedModel); + } else { + return applyOrientation( + Variant.variant().with(VariantProperties.MODEL, + unformedModel.getLocation()), + BlockOrientation.get(facing)); + } + })); + + simpleBlockItem(MEGABlocks.CRAFTING_MONITOR.block(), unformedModel); + } + + private void patternProvider() { + var def = MEGABlocks.MEGA_PATTERN_PROVIDER; + var normalModel = cubeAll(def.block()); + simpleBlockItem(def.block(), normalModel); + + var arrow = Utils.makeId("block/mega_pattern_provider_alternate_arrow"); + var orientedModel = models().cube("block/mega_pattern_provider_oriented", + Utils.makeId("block/mega_pattern_provider_alternate"), + Utils.makeId("block/mega_pattern_provider_alternate_front"), arrow, arrow, arrow, arrow) + .texture("particle", "block/mega_pattern_provider"); + + multiVariantGenerator(MEGABlocks.MEGA_PATTERN_PROVIDER, Variant.variant()) + .with(PropertyDispatch.property(MEGAPatternProviderBlock.PUSH_DIRECTION).generate(pushDirection -> { + var forward = pushDirection.getDirection(); + if (forward == null) { + return Variant.variant().with(VariantProperties.MODEL, normalModel.getLocation()); + } else { + var orientation = BlockOrientation.get(forward); + return applyRotation( + Variant.variant().with(VariantProperties.MODEL, orientedModel.getLocation()), + // + 90 because the default model is oriented UP, while block orientation assumes + // NORTH + orientation.getAngleX() + 90, + orientation.getAngleY(), + 0); + } + })); + } + + private MultiVariantGenerator multiVariantGenerator(BlockDefinition block, Variant... variants) { + if (variants.length == 0) { + variants = new Variant[] { Variant.variant() }; + } + + var builder = MultiVariantGenerator.multiVariant(block.block(), variants); + registeredBlocks.put(block.block(), () -> builder.get().getAsJsonObject()); + return builder; + } + + protected Variant applyOrientation(Variant variant, BlockOrientation orientation) { + return applyRotation(variant, + orientation.getAngleX(), + orientation.getAngleY(), + orientation.getAngleZ()); + } + + protected Variant applyRotation(Variant variant, int angleX, int angleY, int angleZ) { + angleX = normalizeAngle(angleX); + angleY = normalizeAngle(angleY); + angleZ = normalizeAngle(angleZ); + + if (angleX != 0) { + variant = variant.with(VariantProperties.X_ROT, rotationByAngle(angleX)); + } + if (angleY != 0) { + variant = variant.with(VariantProperties.Y_ROT, rotationByAngle(angleY)); + } + if (angleZ != 0) { + variant = variant.with(Z_ROT, rotationByAngle(angleZ)); + } + return variant; + } + + private int normalizeAngle(int angle) { + return angle - (angle / 360) * 360; + } + + private VariantProperties.Rotation rotationByAngle(int angle) { + return switch (angle) { + case 0 -> VariantProperties.Rotation.R0; + case 90 -> VariantProperties.Rotation.R90; + case 180 -> VariantProperties.Rotation.R180; + case 270 -> VariantProperties.Rotation.R270; + default -> throw new IllegalArgumentException("Invalid angle: " + angle); + }; + } + } + + static class Parts extends net.minecraftforge.client.model.generators.ModelProvider { + private static final ResourceLocation PATTERN_PROVIDER = AppEng.makeId("part/pattern_provider_base"); + + public Parts(PackOutput output, ExistingFileHelper existing) { + super(output, Utils.MODID, "part", BlockModelBuilder::new, existing); + existing.trackGenerated(PATTERN_PROVIDER, MODEL); + } + + @NotNull + @Override + public String getName() { + return "Part Models: " + modid; + } + + @Override + protected void registerModels() { + patternProvider(); + } + + private void patternProvider() { + withExistingParent("part/mega_pattern_provider", PATTERN_PROVIDER) + .texture("back", "part/mega_monitor_back") + .texture("front", "part/mega_pattern_provider") + .texture("particle", "part/mega_monitor_back") + .texture("sides", "part/mega_monitor_sides") + .texture("sidesStatus", "part/mega_monitor_sides_status"); + } + } +} diff --git a/forge/src/main/java/gripe/_90/megacells/datagen/RecipeProvider.java b/forge/src/main/java/gripe/_90/megacells/datagen/RecipeProvider.java new file mode 100644 index 00000000..b569fca8 --- /dev/null +++ b/forge/src/main/java/gripe/_90/megacells/datagen/RecipeProvider.java @@ -0,0 +1,274 @@ +package gripe._90.megacells.datagen; + +import java.util.Objects; +import java.util.function.Consumer; + +import org.jetbrains.annotations.NotNull; + +import net.minecraft.data.PackOutput; +import net.minecraft.data.recipes.FinishedRecipe; +import net.minecraft.data.recipes.RecipeCategory; +import net.minecraft.data.recipes.ShapedRecipeBuilder; +import net.minecraft.data.recipes.ShapelessRecipeBuilder; +import net.minecraft.tags.TagKey; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.level.ItemLike; +import net.minecraftforge.registries.ForgeRegistries; + +import appeng.api.util.AEColor; +import appeng.core.definitions.AEBlocks; +import appeng.core.definitions.AEItems; +import appeng.core.definitions.AEParts; +import appeng.core.definitions.BlockDefinition; +import appeng.core.definitions.ItemDefinition; +import appeng.datagen.providers.tags.ConventionTags; +import appeng.items.storage.StorageTier; +import appeng.recipes.handlers.InscriberProcessType; +import appeng.recipes.handlers.InscriberRecipeBuilder; + +import gripe._90.megacells.definition.MEGABlocks; +import gripe._90.megacells.definition.MEGAItems; +import gripe._90.megacells.definition.MEGAParts; +import gripe._90.megacells.integration.appbot.AppBotItems; +import gripe._90.megacells.util.Utils; + +public class RecipeProvider extends net.minecraft.data.recipes.RecipeProvider { + public RecipeProvider(PackOutput output) { + super(output); + } + + @Override + protected void buildRecipes(@NotNull Consumer consumer) { + // spotless:off + component(consumer, MEGAItems.TIER_1M, StorageTier.SIZE_256K, AEItems.SKY_DUST.asItem()); + component(consumer, MEGAItems.TIER_4M, MEGAItems.TIER_1M, AEItems.ENDER_DUST.asItem()); + component(consumer, MEGAItems.TIER_16M, MEGAItems.TIER_4M, AEItems.ENDER_DUST.asItem()); + component(consumer, MEGAItems.TIER_64M, MEGAItems.TIER_16M, AEItems.MATTER_BALL.asItem()); + component(consumer, MEGAItems.TIER_256M, MEGAItems.TIER_64M, AEItems.MATTER_BALL.asItem()); + + housing(consumer, MEGAItems.MEGA_ITEM_CELL_HOUSING, ConventionTags.IRON_INGOT); + housing(consumer, MEGAItems.MEGA_FLUID_CELL_HOUSING, ConventionTags.COPPER_INGOT); + + cell(consumer, MEGAItems.ITEM_CELL_1M, MEGAItems.CELL_COMPONENT_1M, MEGAItems.MEGA_ITEM_CELL_HOUSING, ConventionTags.IRON_INGOT); + cell(consumer, MEGAItems.ITEM_CELL_4M, MEGAItems.CELL_COMPONENT_4M, MEGAItems.MEGA_ITEM_CELL_HOUSING, ConventionTags.IRON_INGOT); + cell(consumer, MEGAItems.ITEM_CELL_16M, MEGAItems.CELL_COMPONENT_16M, MEGAItems.MEGA_ITEM_CELL_HOUSING, ConventionTags.IRON_INGOT); + cell(consumer, MEGAItems.ITEM_CELL_64M, MEGAItems.CELL_COMPONENT_64M, MEGAItems.MEGA_ITEM_CELL_HOUSING, ConventionTags.IRON_INGOT); + cell(consumer, MEGAItems.ITEM_CELL_256M, MEGAItems.CELL_COMPONENT_256M, MEGAItems.MEGA_ITEM_CELL_HOUSING, ConventionTags.IRON_INGOT); + cell(consumer, MEGAItems.FLUID_CELL_1M, MEGAItems.CELL_COMPONENT_1M, MEGAItems.MEGA_FLUID_CELL_HOUSING, ConventionTags.COPPER_INGOT); + cell(consumer, MEGAItems.FLUID_CELL_4M, MEGAItems.CELL_COMPONENT_4M, MEGAItems.MEGA_FLUID_CELL_HOUSING, ConventionTags.COPPER_INGOT); + cell(consumer, MEGAItems.FLUID_CELL_16M, MEGAItems.CELL_COMPONENT_16M, MEGAItems.MEGA_FLUID_CELL_HOUSING, ConventionTags.COPPER_INGOT); + cell(consumer, MEGAItems.FLUID_CELL_64M, MEGAItems.CELL_COMPONENT_64M, MEGAItems.MEGA_FLUID_CELL_HOUSING, ConventionTags.COPPER_INGOT); + cell(consumer, MEGAItems.FLUID_CELL_256M, MEGAItems.CELL_COMPONENT_256M, MEGAItems.MEGA_FLUID_CELL_HOUSING, ConventionTags.COPPER_INGOT); + + portable(consumer, MEGAItems.PORTABLE_ITEM_CELL_1M, MEGAItems.CELL_COMPONENT_1M, MEGAItems.MEGA_ITEM_CELL_HOUSING); + portable(consumer, MEGAItems.PORTABLE_ITEM_CELL_4M, MEGAItems.CELL_COMPONENT_4M, MEGAItems.MEGA_ITEM_CELL_HOUSING); + portable(consumer, MEGAItems.PORTABLE_ITEM_CELL_16M, MEGAItems.CELL_COMPONENT_16M, MEGAItems.MEGA_ITEM_CELL_HOUSING); + portable(consumer, MEGAItems.PORTABLE_ITEM_CELL_64M, MEGAItems.CELL_COMPONENT_64M, MEGAItems.MEGA_ITEM_CELL_HOUSING); + portable(consumer, MEGAItems.PORTABLE_ITEM_CELL_256M, MEGAItems.CELL_COMPONENT_256M, MEGAItems.MEGA_ITEM_CELL_HOUSING); + portable(consumer, MEGAItems.PORTABLE_FLUID_CELL_1M, MEGAItems.CELL_COMPONENT_1M, MEGAItems.MEGA_FLUID_CELL_HOUSING); + portable(consumer, MEGAItems.PORTABLE_FLUID_CELL_4M, MEGAItems.CELL_COMPONENT_4M, MEGAItems.MEGA_FLUID_CELL_HOUSING); + portable(consumer, MEGAItems.PORTABLE_FLUID_CELL_16M, MEGAItems.CELL_COMPONENT_16M, MEGAItems.MEGA_FLUID_CELL_HOUSING); + portable(consumer, MEGAItems.PORTABLE_FLUID_CELL_64M, MEGAItems.CELL_COMPONENT_64M, MEGAItems.MEGA_FLUID_CELL_HOUSING); + portable(consumer, MEGAItems.PORTABLE_FLUID_CELL_256M, MEGAItems.CELL_COMPONENT_256M, MEGAItems.MEGA_FLUID_CELL_HOUSING); + + specialisedComponent(consumer, MEGAItems.CELL_COMPONENT_16M, AEItems.SPATIAL_16_CELL_COMPONENT, MEGAItems.BULK_CELL_COMPONENT); + // spotless:on + + ShapedRecipeBuilder.shaped(RecipeCategory.MISC, MEGAItems.BULK_ITEM_CELL) + .pattern("aba") + .pattern("bcb") + .pattern("ddd") + .define('a', AEBlocks.QUARTZ_VIBRANT_GLASS) + .define('b', AEItems.SKY_DUST) + .define('c', MEGAItems.BULK_CELL_COMPONENT) + .define('d', Items.NETHERITE_INGOT) + .unlockedBy("has_bulk_cell_component", has(MEGAItems.BULK_CELL_COMPONENT)) + .save(consumer, Utils.makeId("cells/standard/bulk_item_cell")); + + ShapedRecipeBuilder.shaped(RecipeCategory.MISC, MEGABlocks.MEGA_ENERGY_CELL) + .pattern("aaa") + .pattern("aba") + .pattern("aaa") + .define('a', AEBlocks.DENSE_ENERGY_CELL) + .define('b', AEItems.ENGINEERING_PROCESSOR) + .unlockedBy("has_dense_energy_cell", has(AEBlocks.DENSE_ENERGY_CELL)) + .unlockedBy("has_engineering_processor", has(AEItems.ENGINEERING_PROCESSOR)) + .save(consumer, Utils.makeId("crafting/mega_energy_cell")); + + ShapedRecipeBuilder.shaped(RecipeCategory.MISC, MEGABlocks.MEGA_CRAFTING_UNIT) + .pattern("aba") + .pattern("cdc") + .pattern("aba") + .define('a', AEBlocks.CRAFTING_UNIT) + .define('b', AEItems.LOGIC_PROCESSOR) + .define('c', AEParts.SMART_CABLE.item(AEColor.TRANSPARENT)) + .define('d', AEItems.ENGINEERING_PROCESSOR) + .unlockedBy("has_logic_processor", has(AEItems.LOGIC_PROCESSOR)) + .save(consumer, Utils.makeId("crafting/mega_crafting_unit")); + craftingBlock(consumer, MEGABlocks.CRAFTING_ACCELERATOR, AEItems.ENGINEERING_PROCESSOR); + craftingBlock(consumer, MEGABlocks.CRAFTING_STORAGE_1M, MEGAItems.CELL_COMPONENT_1M); + craftingBlock(consumer, MEGABlocks.CRAFTING_STORAGE_4M, MEGAItems.CELL_COMPONENT_4M); + craftingBlock(consumer, MEGABlocks.CRAFTING_STORAGE_16M, MEGAItems.CELL_COMPONENT_16M); + craftingBlock(consumer, MEGABlocks.CRAFTING_STORAGE_64M, MEGAItems.CELL_COMPONENT_64M); + craftingBlock(consumer, MEGABlocks.CRAFTING_STORAGE_256M, MEGAItems.CELL_COMPONENT_256M); + craftingBlock(consumer, MEGABlocks.CRAFTING_MONITOR, AEParts.STORAGE_MONITOR); + + ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, MEGAItems.GREATER_ENERGY_CARD) + .requires(AEItems.ADVANCED_CARD) + .requires(MEGABlocks.MEGA_ENERGY_CELL) + .unlockedBy("has_advanced_card", has(AEItems.ADVANCED_CARD)) + .unlockedBy("has_mega_energy_cell", has(MEGABlocks.MEGA_ENERGY_CELL)) + .save(consumer, Utils.makeId("crafting/greater_energy_card")); + ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, MEGAItems.GREATER_ENERGY_CARD) + .requires(AEItems.ENERGY_CARD) + .requires(MEGABlocks.MEGA_ENERGY_CELL) + .unlockedBy("has_advanced_card", has(AEItems.ADVANCED_CARD)) + .unlockedBy("has_mega_energy_cell", has(MEGABlocks.MEGA_ENERGY_CELL)) + .save(consumer, Utils.makeId("crafting/greater_energy_card_upgraded")); + + ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, MEGAItems.COMPRESSION_CARD) + .requires(AEItems.ADVANCED_CARD) + .requires(AEItems.MATTER_BALL) + .unlockedBy("has_advanced_card", has(AEItems.ADVANCED_CARD)) + .unlockedBy("has_matter_ball", has(AEItems.MATTER_BALL)) + .save(consumer, Utils.makeId("crafting/compression_card")); + ShapedRecipeBuilder.shaped(RecipeCategory.MISC, MEGAParts.DECOMPRESSION_MODULE) + .pattern("ICI") + .pattern("E#E") + .pattern("ILI") + .define('I', ConventionTags.IRON_INGOT) + .define('C', AEItems.CALCULATION_PROCESSOR) + .define('E', AEItems.ENGINEERING_PROCESSOR) + .define('L', AEItems.LOGIC_PROCESSOR) + .define('#', MEGAItems.COMPRESSION_CARD) + .unlockedBy("has_compression_card", has(MEGAItems.COMPRESSION_CARD)) + .save(consumer, Utils.makeId("crafting/decompression_module")); + + ShapedRecipeBuilder.shaped(RecipeCategory.MISC, MEGABlocks.MEGA_PATTERN_PROVIDER) + .pattern("ICI") + .pattern("VPV") + .pattern("ICI") + .define('C', AEItems.CALCULATION_PROCESSOR) + .define('I', ConventionTags.IRON_INGOT) + .define('P', AEBlocks.PATTERN_PROVIDER) + .define('V', AEBlocks.QUARTZ_VIBRANT_GLASS) + .unlockedBy("has_pattern_provider", has(ConventionTags.PATTERN_PROVIDER)) + .save(consumer, Utils.makeId("network/mega_pattern_provider")); + + ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, MEGAParts.MEGA_PATTERN_PROVIDER) + .requires(MEGABlocks.MEGA_PATTERN_PROVIDER) + .unlockedBy("has_mega_pattern_provider", has(MEGABlocks.MEGA_PATTERN_PROVIDER)) + .save(consumer, Utils.makeId("network/mega_pattern_provider_part")); + ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, MEGABlocks.MEGA_PATTERN_PROVIDER) + .requires(MEGAParts.MEGA_PATTERN_PROVIDER) + .unlockedBy("has_cable_mega_pattern_provider", has(MEGAParts.MEGA_PATTERN_PROVIDER)) + .save(consumer, Utils.makeId("network/mega_pattern_provider_block")); + + if (Utils.PLATFORM.isModLoaded("appbot")) { + manaCells(consumer, AppBotItems.MANA_CELL_1M, AppBotItems.PORTABLE_MANA_CELL_1M, MEGAItems.TIER_1M); + manaCells(consumer, AppBotItems.MANA_CELL_4M, AppBotItems.PORTABLE_MANA_CELL_4M, MEGAItems.TIER_4M); + manaCells(consumer, AppBotItems.MANA_CELL_16M, AppBotItems.PORTABLE_MANA_CELL_16M, MEGAItems.TIER_16M); + manaCells(consumer, AppBotItems.MANA_CELL_64M, AppBotItems.PORTABLE_MANA_CELL_64M, MEGAItems.TIER_64M); + manaCells(consumer, AppBotItems.MANA_CELL_256M, AppBotItems.PORTABLE_MANA_CELL_256M, MEGAItems.TIER_256M); + } + } + + private void component(Consumer consumer, StorageTier tier, StorageTier preceding, + ItemLike binder) { + var precedingComponent = preceding.componentSupplier().get(); + ShapedRecipeBuilder.shaped(RecipeCategory.MISC, tier.componentSupplier().get()) + .pattern("aba") + .pattern("cdc") + .pattern("aca") + .define('a', binder) + .define('b', AEItems.CALCULATION_PROCESSOR) + .define('c', precedingComponent) + .define('d', AEBlocks.QUARTZ_VIBRANT_GLASS) + .unlockedBy("has_" + Objects.requireNonNull(ForgeRegistries.ITEMS.getKey(precedingComponent)).getPath(), + has(precedingComponent)) + .save(consumer, Utils.makeId("cells/" + Objects + .requireNonNull(ForgeRegistries.ITEMS.getKey(tier.componentSupplier().get())).getPath())); + } + + private void specialisedComponent(Consumer consumer, ItemLike top, ItemLike bottom, + ItemDefinition output) { + InscriberRecipeBuilder.inscribe(AEItems.SINGULARITY, output, 1) + .setMode(InscriberProcessType.PRESS) + .setTop(Ingredient.of(top)).setBottom(Ingredient.of(bottom)) + .save(consumer, Utils.makeId("inscriber/" + output.id().getPath())); + } + + private void cell(Consumer consumer, ItemDefinition cell, ItemDefinition component, + ItemDefinition housing, TagKey housingMaterial) { + ShapedRecipeBuilder.shaped(RecipeCategory.MISC, cell) + .pattern("aba") + .pattern("bcb") + .pattern("ddd") + .define('a', AEBlocks.QUARTZ_VIBRANT_GLASS) + .define('b', AEItems.SKY_DUST) + .define('c', component) + .define('d', housingMaterial) + .unlockedBy("has_" + component.id().getPath(), has(component)) + .save(consumer, Utils.makeId("cells/standard/" + cell.id().getPath())); + + ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, cell) + .requires(housing) + .requires(component) + .unlockedBy("has_" + component.id().getPath(), has(component)) + .unlockedBy("has_" + housing.id().getPath(), has(housing)) + .save(consumer, Utils.makeId("cells/standard/" + cell.id().getPath() + "_with_housing")); + } + + private void portable(Consumer consumer, ItemDefinition cell, ItemDefinition component, + ItemDefinition housing) { + ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, cell) + .requires(AEBlocks.CHEST) + .requires(component) + .requires(AEBlocks.DENSE_ENERGY_CELL) + .requires(housing) + .unlockedBy("has_" + housing.id().getPath(), has(housing)) + .unlockedBy("has_" + component.id().getPath(), has(component)) + .unlockedBy("has_dense_energy_cell", has(AEBlocks.DENSE_ENERGY_CELL)) + .save(consumer, Utils.makeId("cells/portable/" + cell.id().getPath())); + } + + private void housing(Consumer consumer, ItemDefinition housing, TagKey housingMaterial) { + ShapedRecipeBuilder.shaped(RecipeCategory.MISC, housing) + .pattern("aba") + .pattern("b b") + .pattern("ddd") + .define('a', AEBlocks.QUARTZ_VIBRANT_GLASS) + .define('b', AEItems.SKY_DUST) + .define('d', housingMaterial) + .unlockedBy("has_dusts/sky_stone", has(AEItems.SKY_DUST)) + .save(consumer, Utils.makeId("cells/" + housing.id().getPath())); + } + + private void craftingBlock(Consumer consumer, BlockDefinition unit, ItemLike part) { + ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, unit) + .requires(MEGABlocks.MEGA_CRAFTING_UNIT) + .requires(part) + .unlockedBy("has_mega_crafting_unit", has(MEGABlocks.MEGA_CRAFTING_UNIT)) + .save(consumer, Utils.makeId("crafting/" + unit.id().getPath())); + } + + private void manaCells(Consumer consumer, ItemDefinition cell, ItemDefinition portable, + StorageTier tier) { + var component = tier.componentSupplier().get(); + var componentPath = Objects.requireNonNull(ForgeRegistries.ITEMS.getKey(component)).getPath(); + + ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, cell).requires(AppBotItems.MEGA_MANA_CELL_HOUSING) + .requires(tier.componentSupplier().get()).unlockedBy("has_" + componentPath, has(component)) + .unlockedBy("has_mega_mana_cell_housing", has(AppBotItems.MEGA_MANA_CELL_HOUSING)) + .save(consumer, Utils.makeId("cells/standard/" + cell.id().getPath() + "_with_housing")); + + ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, portable).requires(AEBlocks.CHEST).requires(component) + .requires(AEBlocks.DENSE_ENERGY_CELL).requires(AppBotItems.MEGA_MANA_CELL_HOUSING) + .unlockedBy("has_mega_mana_cell_housing", has(AppBotItems.MEGA_MANA_CELL_HOUSING)) + .unlockedBy("has_" + componentPath, has(component)) + .unlockedBy("has_dense_energy_cell", has(AEBlocks.DENSE_ENERGY_CELL)) + .save(consumer, Utils.makeId("cells/portable/" + portable.id().getPath())); + } +} diff --git a/forge/src/main/java/gripe/_90/megacells/datagen/TagProvider.java b/forge/src/main/java/gripe/_90/megacells/datagen/TagProvider.java new file mode 100644 index 00000000..f246b294 --- /dev/null +++ b/forge/src/main/java/gripe/_90/megacells/datagen/TagProvider.java @@ -0,0 +1,64 @@ +package gripe._90.megacells.datagen; + +import java.util.concurrent.CompletableFuture; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.core.HolderLookup; +import net.minecraft.data.PackOutput; +import net.minecraft.data.tags.ItemTagsProvider; +import net.minecraft.resources.ResourceKey; +import net.minecraft.tags.BlockTags; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import net.minecraftforge.common.data.BlockTagsProvider; +import net.minecraftforge.common.data.ExistingFileHelper; +import net.minecraftforge.registries.ForgeRegistries; + +import appeng.api.features.P2PTunnelAttunement; +import appeng.core.definitions.BlockDefinition; +import appeng.core.definitions.ItemDefinition; + +import gripe._90.megacells.definition.MEGABlocks; +import gripe._90.megacells.definition.MEGAParts; +import gripe._90.megacells.definition.MEGATags; +import gripe._90.megacells.util.Utils; + +abstract class TagProvider { + static class Items extends ItemTagsProvider { + public Items(PackOutput output, CompletableFuture registries, + CompletableFuture> blockTags, @Nullable ExistingFileHelper existing) { + super(output, registries, blockTags, Utils.MODID, existing); + } + + @Override + protected void addTags(@NotNull HolderLookup.Provider provider) { + tag(P2PTunnelAttunement.getAttunementTag(P2PTunnelAttunement.ENERGY_TUNNEL)) + .add(getKey(MEGABlocks.MEGA_ENERGY_CELL)); + tag(MEGATags.MEGA_PATTERN_PROVIDER) + .add(getKey(MEGABlocks.MEGA_PATTERN_PROVIDER)) + .add(getKey(MEGAParts.MEGA_PATTERN_PROVIDER)); + } + + private ResourceKey getKey(ItemDefinition item) { + return ForgeRegistries.ITEMS.getResourceKey(item.asItem()).orElse(null); + } + } + + static class Blocks extends BlockTagsProvider { + public Blocks(PackOutput output, CompletableFuture registries, + @Nullable ExistingFileHelper existing) { + super(output, registries, Utils.MODID, existing); + } + + @Override + protected void addTags(@NotNull HolderLookup.Provider provider) { + MEGABlocks.getBlocks().forEach(block -> tag(BlockTags.MINEABLE_WITH_PICKAXE).add(getKey(block))); + } + + private ResourceKey getKey(BlockDefinition block) { + return ForgeRegistries.BLOCKS.getResourceKey(block.block()).orElse(null); + } + } +} diff --git a/forge/src/main/java/gripe/_90/megacells/forge/MEGACellsClient.java b/forge/src/main/java/gripe/_90/megacells/forge/MEGACellsClient.java index a2fc15a2..e9468c05 100644 --- a/forge/src/main/java/gripe/_90/megacells/forge/MEGACellsClient.java +++ b/forge/src/main/java/gripe/_90/megacells/forge/MEGACellsClient.java @@ -54,7 +54,7 @@ private void initRenderTypes(FMLClientSetupEvent ignoredEvent) { private void initModels(ModelEvent.RegisterGeometryLoaders event) { for (var type : MEGACraftingUnitType.values()) { - BuiltInModelHooks.addBuiltInModel(Utils.makeId("block/crafting/" + type.getAffix() + "_formed"), + BuiltInModelHooks.addBuiltInModel(AppEng.makeId("block/crafting/mega_" + type.getAffix() + "_formed"), new CraftingCubeModel(new MEGACraftingUnitModelProvider(type))); } diff --git a/forge/src/main/java/gripe/_90/megacells/integration/appmek/datagen/AppMekDataGenerators.java b/forge/src/main/java/gripe/_90/megacells/integration/appmek/datagen/AppMekDataGenerators.java index 9dbd3731..0ff78b33 100644 --- a/forge/src/main/java/gripe/_90/megacells/integration/appmek/datagen/AppMekDataGenerators.java +++ b/forge/src/main/java/gripe/_90/megacells/integration/appmek/datagen/AppMekDataGenerators.java @@ -1,15 +1,10 @@ package gripe._90.megacells.integration.appmek.datagen; -import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.data.event.GatherDataEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; import gripe._90.megacells.util.Utils; -@Mod.EventBusSubscriber(modid = Utils.MODID, bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) public class AppMekDataGenerators { - @SubscribeEvent public static void onGatherData(GatherDataEvent event) { if (Utils.PLATFORM.isModLoaded("appmek")) { var pack = event.getGenerator().getVanillaPack(true);