From c3884c40966e14a7397ee5d4305ce9589cd22eaa Mon Sep 17 00:00:00 2001 From: Hiiragi Russell Tsubasa <97942736+Hiiragi283@users.noreply.github.com> Date: Fri, 25 Oct 2024 18:48:38 +0900 Subject: [PATCH] split integration parts from original --- .gitignore | 3 +- build.gradle.kts | 8 +- gradle/libs.versions.toml | 10 +- .../ragium/integration/RIKeyBinds.kt | 18 +++ .../integration/RagiumClientIntegration.kt | 32 +++++ .../integration/data/RIDataGenerator.kt | 14 ++ .../integration/data/RIRecipeProvider.kt | 31 ++++ .../data/recipe/TRRecipeProvider.kt | 67 +++++++++ .../jade/HTEnergyNetworkProvider.kt | 24 ++++ .../integration/jade/HTMachineProvider.kt | 94 +++++++++++++ .../ragium/integration/jade/JadeExtensions.kt | 21 +++ .../integration/jade/RagiumJadePlugin.kt | 27 ++++ .../patchouli/HTCustomCraftingPage.kt | 83 +++++++++++ .../patchouli/HTMachineRecipePage.kt | 95 +++++++++++++ .../patchouli/PatchouliExtensions.kt | 36 +++++ .../patchouli/RagiumPatchouliInit.kt | 40 ++++++ .../rei/HTMachineRecipeCategory.kt | 132 ++++++++++++++++++ .../integration/rei/HTMachineRecipeDisplay.kt | 63 +++++++++ .../ragium/integration/rei/REIExtensions.kt | 103 ++++++++++++++ .../ragium/integration/rei/RagiumREIClient.kt | 106 ++++++++++++++ .../recipes/misc/shapeless/guide_book.json | 29 ++++ .../ragium/recipe/shapeless/guide_book.json | 30 ++++ .../blast_furnace/ragi_steel_ingot.json | 21 +++ .../ragium/data/RagiumDataGenerator.kt | 10 ++ .../ragium/integration/RagiumIntegration.kt | 41 ++++++ .../accessories/HTEmptyAccessory.kt | 5 + .../accessories/HTOpenBackpackPayload.kt | 21 +++ .../accessories/HTWrappedAccessory.kt | 16 +++ .../accessories/RagiumAccessoriesInit.kt | 45 ++++++ .../ragi_wiki/en_us/categories/alchemy.json | 5 + .../ragi_wiki/en_us/categories/foods.json | 5 + .../ragi_wiki/en_us/categories/machines.json | 5 + .../en_us/categories/oil_chemistry.json | 5 + .../ragi_wiki/en_us/categories/tier1.json | 5 + .../ragi_wiki/en_us/categories/tier2.json | 5 + .../ragi_wiki/en_us/categories/tier3.json | 5 + .../en_us/entries/tier1/ragi_alloy.json | 24 ++++ .../en_us/entries/tier1/raginite.json | 15 ++ .../en_us/entries/tier1/raw_raginite.json | 23 +++ .../patchouli_books/ragi_wiki/book.json | 9 ++ src/main/resources/fabric.mod.json | 18 ++- 41 files changed, 1334 insertions(+), 15 deletions(-) create mode 100644 src/client/kotlin/hiiragi283/ragium/integration/RIKeyBinds.kt create mode 100644 src/client/kotlin/hiiragi283/ragium/integration/RagiumClientIntegration.kt create mode 100644 src/client/kotlin/hiiragi283/ragium/integration/data/RIDataGenerator.kt create mode 100644 src/client/kotlin/hiiragi283/ragium/integration/data/RIRecipeProvider.kt create mode 100644 src/client/kotlin/hiiragi283/ragium/integration/data/recipe/TRRecipeProvider.kt create mode 100644 src/client/kotlin/hiiragi283/ragium/integration/jade/HTEnergyNetworkProvider.kt create mode 100644 src/client/kotlin/hiiragi283/ragium/integration/jade/HTMachineProvider.kt create mode 100644 src/client/kotlin/hiiragi283/ragium/integration/jade/JadeExtensions.kt create mode 100644 src/client/kotlin/hiiragi283/ragium/integration/jade/RagiumJadePlugin.kt create mode 100644 src/client/kotlin/hiiragi283/ragium/integration/patchouli/HTCustomCraftingPage.kt create mode 100644 src/client/kotlin/hiiragi283/ragium/integration/patchouli/HTMachineRecipePage.kt create mode 100644 src/client/kotlin/hiiragi283/ragium/integration/patchouli/PatchouliExtensions.kt create mode 100644 src/client/kotlin/hiiragi283/ragium/integration/patchouli/RagiumPatchouliInit.kt create mode 100644 src/client/kotlin/hiiragi283/ragium/integration/rei/HTMachineRecipeCategory.kt create mode 100644 src/client/kotlin/hiiragi283/ragium/integration/rei/HTMachineRecipeDisplay.kt create mode 100644 src/client/kotlin/hiiragi283/ragium/integration/rei/REIExtensions.kt create mode 100644 src/client/kotlin/hiiragi283/ragium/integration/rei/RagiumREIClient.kt create mode 100644 src/main/generated/data/ragium/advancement/recipes/misc/shapeless/guide_book.json create mode 100644 src/main/generated/data/ragium/recipe/shapeless/guide_book.json create mode 100644 src/main/generated/data/ragium/recipe/techreborn/blast_furnace/ragi_steel_ingot.json create mode 100644 src/main/kotlin/hiiragi283/ragium/data/RagiumDataGenerator.kt create mode 100644 src/main/kotlin/hiiragi283/ragium/integration/RagiumIntegration.kt create mode 100644 src/main/kotlin/hiiragi283/ragium/integration/accessories/HTEmptyAccessory.kt create mode 100644 src/main/kotlin/hiiragi283/ragium/integration/accessories/HTOpenBackpackPayload.kt create mode 100644 src/main/kotlin/hiiragi283/ragium/integration/accessories/HTWrappedAccessory.kt create mode 100644 src/main/kotlin/hiiragi283/ragium/integration/accessories/RagiumAccessoriesInit.kt create mode 100644 src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/alchemy.json create mode 100644 src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/foods.json create mode 100644 src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/machines.json create mode 100644 src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/oil_chemistry.json create mode 100644 src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/tier1.json create mode 100644 src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/tier2.json create mode 100644 src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/tier3.json create mode 100644 src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/entries/tier1/ragi_alloy.json create mode 100644 src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/entries/tier1/raginite.json create mode 100644 src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/entries/tier1/raw_raginite.json create mode 100644 src/main/resources/data/ragium/patchouli_books/ragi_wiki/book.json diff --git a/.gitignore b/.gitignore index 0743826..989176f 100644 --- a/.gitignore +++ b/.gitignore @@ -34,10 +34,11 @@ run/ .cache .kotlin docs +libs/ # java hs_err_*.log replay_*.log *.hprof -*.jfr \ No newline at end of file +*.jfr diff --git a/build.gradle.kts b/build.gradle.kts index 66e6989..0953cf8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -40,8 +40,9 @@ repositories { loom { // accessWidenerPath = file("src/main/resources/ht_materials.accesswidener") splitEnvironmentSourceSets() + mods { - create("ragium") { + create("ragium_integrations") { sourceSet(sourceSets.main.get()) sourceSet(sourceSets.getByName("client")) } @@ -84,7 +85,6 @@ dependencies { exclude(module = "fabric-api") exclude(module = "fabric-loader") } - // modImplementation(libs.modonomicon) { isTransitive = false } modImplementation(libs.bundles.mods.include) { exclude(module = "fabric-api") @@ -102,8 +102,8 @@ dependencies { exclude(module = "fabric-loader") } - implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) - implementation(project(":ragium")) { isTransitive = false } + // modImplementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) + modImplementation(project(path = ":ragium", configuration = "namedElements")) testImplementation("org.jetbrains.kotlin:kotlin-test") } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 88a16c7..d5d3ace 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -53,19 +53,15 @@ mods-fabric = [ "fabric-kotlin", "fabric-loader", "accessories", + "libgui", "jade", "mod-modmenu", "patchouli", "rei", "tech-reborn" ] -mods-include = [ - "energy", - "libgui" -] -mods-compile = [ - -] +mods-include = [] +mods-compile = [] mods-runtime = [] [plugins] diff --git a/src/client/kotlin/hiiragi283/ragium/integration/RIKeyBinds.kt b/src/client/kotlin/hiiragi283/ragium/integration/RIKeyBinds.kt new file mode 100644 index 0000000..58f1d68 --- /dev/null +++ b/src/client/kotlin/hiiragi283/ragium/integration/RIKeyBinds.kt @@ -0,0 +1,18 @@ +package hiiragi283.ragium.integration + +import hiiragi283.ragium.api.RagiumAPI +import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper +import net.minecraft.client.option.KeyBinding +import org.lwjgl.glfw.GLFW + +object RIKeyBinds { + const val CATEGORY: String = "category.${RagiumAPI.MOD_ID}.${RagiumAPI.MOD_ID}" + + @JvmField + val OPEN_BACKPACK: KeyBinding = KeyBindingHelper.registerKeyBinding( + KeyBinding(keyId("open_backpack"), GLFW.GLFW_KEY_O, CATEGORY), + ) + + @JvmStatic + private fun keyId(name: String): String = "key.${RagiumAPI.MOD_ID}.$name" +} diff --git a/src/client/kotlin/hiiragi283/ragium/integration/RagiumClientIntegration.kt b/src/client/kotlin/hiiragi283/ragium/integration/RagiumClientIntegration.kt new file mode 100644 index 0000000..c321098 --- /dev/null +++ b/src/client/kotlin/hiiragi283/ragium/integration/RagiumClientIntegration.kt @@ -0,0 +1,32 @@ +package hiiragi283.ragium.integration + +import hiiragi283.ragium.api.extension.isModLoaded +import hiiragi283.ragium.common.RagiumContents +import hiiragi283.ragium.integration.accessories.HTOpenBackpackPayload +import hiiragi283.ragium.integration.patchouli.RagiumPatchouliInit +import io.wispforest.accessories.api.AccessoriesCapability +import net.fabricmc.api.ClientModInitializer +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking +import net.minecraft.client.MinecraftClient + +object RagiumClientIntegration : ClientModInitializer { + override fun onInitializeClient() { + RIKeyBinds + + if (isModLoaded("accessories")) { + ClientTickEvents.END_CLIENT_TICK.register { client: MinecraftClient -> + while (RIKeyBinds.OPEN_BACKPACK.wasPressed()) { + val capability: AccessoriesCapability = client.player?.accessoriesCapability() ?: break + if (capability.isEquipped(RagiumContents.Misc.BACKPACK.asItem())) { + ClientPlayNetworking.send(HTOpenBackpackPayload) + } + } + } + } + + if (isModLoaded("patchouli")) { + RagiumPatchouliInit.init() + } + } +} diff --git a/src/client/kotlin/hiiragi283/ragium/integration/data/RIDataGenerator.kt b/src/client/kotlin/hiiragi283/ragium/integration/data/RIDataGenerator.kt new file mode 100644 index 0000000..497c61b --- /dev/null +++ b/src/client/kotlin/hiiragi283/ragium/integration/data/RIDataGenerator.kt @@ -0,0 +1,14 @@ +package hiiragi283.ragium.integration.data + +import hiiragi283.ragium.integration.data.recipe.TRRecipeProvider +import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint +import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator + +object RIDataGenerator : DataGeneratorEntrypoint { + override fun onInitializeDataGenerator(fabricDataGenerator: FabricDataGenerator) { + val pack: FabricDataGenerator.Pack = fabricDataGenerator.createPack() + // server + pack.addProvider(::RIRecipeProvider) + pack.addProvider(::TRRecipeProvider) + } +} diff --git a/src/client/kotlin/hiiragi283/ragium/integration/data/RIRecipeProvider.kt b/src/client/kotlin/hiiragi283/ragium/integration/data/RIRecipeProvider.kt new file mode 100644 index 0000000..1c369c7 --- /dev/null +++ b/src/client/kotlin/hiiragi283/ragium/integration/data/RIRecipeProvider.kt @@ -0,0 +1,31 @@ +package hiiragi283.ragium.integration.data + +import hiiragi283.ragium.api.RagiumAPI +import hiiragi283.ragium.api.data.recipe.HTShapelessRecipeJsonBuilder +import hiiragi283.ragium.common.RagiumContents +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput +import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider +import net.fabricmc.fabric.api.resource.conditions.v1.ResourceConditions +import net.fabricmc.fabric.api.tag.convention.v2.ConventionalItemTags +import net.minecraft.data.server.recipe.RecipeExporter +import net.minecraft.item.Items +import net.minecraft.registry.RegistryWrapper +import net.minecraft.util.Identifier +import vazkii.patchouli.common.item.ItemModBook +import java.util.concurrent.CompletableFuture + +class RIRecipeProvider( + output: FabricDataOutput, + completableFuture: CompletableFuture +) : FabricRecipeProvider(output, completableFuture) { + override fun getRecipeIdentifier(identifier: Identifier): Identifier = RagiumAPI.id(identifier.path) + + override fun generate(exporter: RecipeExporter) { + HTShapelessRecipeJsonBuilder + .create(ItemModBook.forBook(RagiumAPI.id("ragi_wiki"))) + .input(Items.BOOK) + .input(RagiumContents.RawMaterials.CRUDE_RAGINITE) + .input(ConventionalItemTags.IRON_INGOTS) + .offerTo(withConditions(exporter, ResourceConditions.allModsLoaded("patchouli"))) + } +} diff --git a/src/client/kotlin/hiiragi283/ragium/integration/data/recipe/TRRecipeProvider.kt b/src/client/kotlin/hiiragi283/ragium/integration/data/recipe/TRRecipeProvider.kt new file mode 100644 index 0000000..a0a2eb0 --- /dev/null +++ b/src/client/kotlin/hiiragi283/ragium/integration/data/recipe/TRRecipeProvider.kt @@ -0,0 +1,67 @@ +package hiiragi283.ragium.integration.data.recipe + +import hiiragi283.ragium.api.RagiumAPI +import hiiragi283.ragium.api.extension.splitWith +import hiiragi283.ragium.common.RagiumContents +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput +import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider +import net.fabricmc.fabric.api.tag.convention.v2.ConventionalItemTags +import net.minecraft.data.server.recipe.RecipeExporter +import net.minecraft.item.ItemStack +import net.minecraft.recipe.Ingredient +import net.minecraft.registry.RegistryWrapper +import net.minecraft.util.Identifier +import reborncore.common.crafting.RebornRecipe +import reborncore.common.crafting.SizedIngredient +import techreborn.init.ModRecipes +import techreborn.recipe.recipes.BlastFurnaceRecipe +import java.util.concurrent.CompletableFuture + +@Suppress("UnstableApiUsage") +class TRRecipeProvider( + output: FabricDataOutput, + completableFuture: CompletableFuture +) : FabricRecipeProvider(output, completableFuture) { + override fun getName(): String = "Recipes/Tech Reborn" + + override fun getRecipeIdentifier(identifier: Identifier): Identifier = RagiumAPI.id(identifier.splitWith('/')) + + override fun generate(exporter: RecipeExporter) { + exporter.accept( + id("blast_furnace/ragi_steel_ingot"), + BlastFurnaceRecipe( + ModRecipes.BLAST_FURNACE, + listOf( + SizedIngredient(1, Ingredient.fromTag(ConventionalItemTags.IRON_INGOTS)), + SizedIngredient(4, Ingredient.ofItems(RagiumContents.Dusts.RAGINITE)) + ), + listOf( + ItemStack(RagiumContents.Ingots.RAGI_STEEL) + ), + 128, + 20 * 10, + 1700 + ), + null + ) + + exporter.accept( + id("alloy_smelter/ragi_alloy_ingot"), + RebornRecipe.Default( + ModRecipes.ALLOY_SMELTER, + listOf( + SizedIngredient(1, Ingredient.fromTag(ConventionalItemTags.COPPER_INGOTS)), + SizedIngredient(4, Ingredient.ofItems(RagiumContents.Dusts.CRUDE_RAGINITE)) + ), + listOf( + ItemStack(RagiumContents.Ingots.RAGI_ALLOY) + ), + 6, + 20 * 10, + ), + null + ) + } + + private fun id(path: String): Identifier = Identifier.of("techreborn", path) +} diff --git a/src/client/kotlin/hiiragi283/ragium/integration/jade/HTEnergyNetworkProvider.kt b/src/client/kotlin/hiiragi283/ragium/integration/jade/HTEnergyNetworkProvider.kt new file mode 100644 index 0000000..3d57e11 --- /dev/null +++ b/src/client/kotlin/hiiragi283/ragium/integration/jade/HTEnergyNetworkProvider.kt @@ -0,0 +1,24 @@ +package hiiragi283.ragium.integration.jade + +import hiiragi283.ragium.api.extension.energyNetwork +import hiiragi283.ragium.api.world.HTEnergyNetwork +import hiiragi283.ragium.common.init.RagiumTranslationKeys +import net.minecraft.client.MinecraftClient +import net.minecraft.text.Text +import net.minecraft.util.Identifier +import snownee.jade.api.BlockAccessor +import snownee.jade.api.IBlockComponentProvider +import snownee.jade.api.ITooltip +import snownee.jade.api.config.IPluginConfig + +object HTEnergyNetworkProvider : IBlockComponentProvider { + // IBlockComponentProvider // + + override fun getUid(): Identifier = RagiumJadePlugin.NETWORK_INTERFACE + + override fun appendTooltip(tooltip: ITooltip, accessor: BlockAccessor, config: IPluginConfig) { + MinecraftClient.getInstance().server?.getWorld(accessor.level.registryKey)?.energyNetwork?.let { network: HTEnergyNetwork -> + tooltip.add(Text.translatable(RagiumTranslationKeys.PROVIDER_JADE_NETWORK_INTERFACE, network.amount)) + } + } +} diff --git a/src/client/kotlin/hiiragi283/ragium/integration/jade/HTMachineProvider.kt b/src/client/kotlin/hiiragi283/ragium/integration/jade/HTMachineProvider.kt new file mode 100644 index 0000000..11aa045 --- /dev/null +++ b/src/client/kotlin/hiiragi283/ragium/integration/jade/HTMachineProvider.kt @@ -0,0 +1,94 @@ +package hiiragi283.ragium.integration.jade + +import com.mojang.serialization.Codec +import com.mojang.serialization.MapCodec +import hiiragi283.ragium.api.inventory.HTSimpleInventory +import hiiragi283.ragium.api.machine.HTMachineEntity +import hiiragi283.ragium.api.machine.HTMachineTier +import hiiragi283.ragium.api.machine.HTMachineType +import hiiragi283.ragium.api.machine.HTMachineTypeRegistry +import hiiragi283.ragium.api.machine.multiblock.HTMultiblockController +import hiiragi283.ragium.common.init.RagiumTranslationKeys +import net.minecraft.nbt.NbtCompound +import net.minecraft.text.Text +import net.minecraft.util.Identifier +import net.minecraft.util.math.Vec2f +import snownee.jade.api.BlockAccessor +import snownee.jade.api.IBlockComponentProvider +import snownee.jade.api.IServerDataProvider +import snownee.jade.api.ITooltip +import snownee.jade.api.config.IPluginConfig +import snownee.jade.api.ui.IElementHelper +import kotlin.jvm.optionals.getOrNull + +object HTMachineProvider : IBlockComponentProvider, IServerDataProvider { + @JvmField + val TYPE: MapCodec = HTMachineTypeRegistry.CODEC.fieldOf("type") + + @JvmField + val TIER: MapCodec = HTMachineTier.CODEC.fieldOf("tier") + + @JvmField + val INVENTORY: MapCodec = HTSimpleInventory.CODEC.fieldOf("inventory") + + @JvmField + val TICK: MapCodec = Codec.INT.fieldOf("tick") + + @JvmField + val MAX_TICK: MapCodec = Codec.INT.fieldOf("maxTick") + + @JvmField + val PREVIEW: MapCodec = Codec.BOOL.fieldOf("preview") + + // IBlockComponentProvider // + + override fun getUid(): Identifier = RagiumJadePlugin.MACHINE + + override fun appendTooltip(tooltip: ITooltip, accessor: BlockAccessor, config: IPluginConfig) { + val type: HTMachineType = accessor + .readData(TYPE) + .getOrNull() + ?: return + val tier: HTMachineTier = accessor + .readData(TIER) + .orElse(HTMachineTier.PRIMITIVE) + type.appendTooltip( + tooltip::add, + tier, + ) + + val progress: Int = accessor.readData(TICK).orElse(0) + val maxProgress: Int = accessor.readData(MAX_TICK).orElse(tier.tickRate) + val helper: IElementHelper = IElementHelper.get() + accessor.readData(INVENTORY).ifPresent { inventory: HTSimpleInventory -> + if (!inventory.isEmpty) { + tooltip.add(helper.item(inventory.getStack(0))) + tooltip.append(helper.item(inventory.getStack(1))) + tooltip.append(helper.item(inventory.getStack(2))) + tooltip.append(helper.spacer(4, 0)) + tooltip.append(helper.progress(progress.toFloat() / maxProgress.toFloat()).translate(Vec2f(-2.0f, 0.0f))) + tooltip.append(helper.item(inventory.getStack(4))) + tooltip.append(helper.item(inventory.getStack(5))) + tooltip.append(helper.item(inventory.getStack(6))) + } + } + + val showPreview: Boolean = accessor.readData(PREVIEW).getOrNull() ?: return + tooltip.add(Text.translatable(RagiumTranslationKeys.MACHINE_SHOW_PREVIEW, showPreview)) + } + + // IServerDataProvider // + + override fun appendServerData(nbt: NbtCompound, accessor: BlockAccessor) { + accessor.machineEntity?.let { machine: HTMachineEntity -> + accessor.writeData(TYPE, machine.machineType) + accessor.writeData(TIER, machine.tier) + accessor.writeData(INVENTORY, machine.parent) + accessor.writeData(TICK, machine.propertyDelegate.get(0)) + accessor.writeData(MAX_TICK, machine.propertyDelegate.get(1)) + if (machine is HTMultiblockController) { + accessor.writeData(PREVIEW, machine.showPreview) + } + } + } +} diff --git a/src/client/kotlin/hiiragi283/ragium/integration/jade/JadeExtensions.kt b/src/client/kotlin/hiiragi283/ragium/integration/jade/JadeExtensions.kt new file mode 100644 index 0000000..7a1c433 --- /dev/null +++ b/src/client/kotlin/hiiragi283/ragium/integration/jade/JadeExtensions.kt @@ -0,0 +1,21 @@ +package hiiragi283.ragium.integration.jade + +import hiiragi283.ragium.api.machine.HTMachineEntity +import hiiragi283.ragium.common.block.entity.HTMetaMachineBlockEntity +import net.minecraft.block.Block +import snownee.jade.api.* + +// IWailaPlugin // + +fun IWailaCommonRegistration.registerBlock(provider: IServerDataProvider, block: Block) { + registerBlockDataProvider(provider, block::class.java) +} + +fun IWailaClientRegistration.registerBlock(provider: IBlockComponentProvider, block: Block) { + registerBlockComponent(provider, block::class.java) +} + +// BlockAccessor // + +val BlockAccessor.machineEntity: HTMachineEntity? + get() = (blockEntity as? HTMetaMachineBlockEntity)?.machineEntity diff --git a/src/client/kotlin/hiiragi283/ragium/integration/jade/RagiumJadePlugin.kt b/src/client/kotlin/hiiragi283/ragium/integration/jade/RagiumJadePlugin.kt new file mode 100644 index 0000000..639ac0f --- /dev/null +++ b/src/client/kotlin/hiiragi283/ragium/integration/jade/RagiumJadePlugin.kt @@ -0,0 +1,27 @@ +package hiiragi283.ragium.integration.jade + +import hiiragi283.ragium.api.RagiumAPI +import hiiragi283.ragium.common.init.RagiumBlocks +import net.minecraft.util.Identifier +import snownee.jade.api.IWailaClientRegistration +import snownee.jade.api.IWailaCommonRegistration +import snownee.jade.api.IWailaPlugin + +object RagiumJadePlugin : IWailaPlugin { + @JvmField + val MACHINE: Identifier = RagiumAPI.id("machine") + + @JvmField + val NETWORK_INTERFACE: Identifier = RagiumAPI.id("network_interface") + + override fun register(registration: IWailaCommonRegistration) { + registration.registerBlock(HTMachineProvider, RagiumBlocks.META_MACHINE) + } + + override fun registerClient(registration: IWailaClientRegistration) { + registration.registerBlock(HTMachineProvider, RagiumBlocks.META_MACHINE) + registration.registerBlock(HTEnergyNetworkProvider, RagiumBlocks.NETWORK_INTERFACE) + + RagiumAPI.log { info("Jade integration enabled!") } + } +} diff --git a/src/client/kotlin/hiiragi283/ragium/integration/patchouli/HTCustomCraftingPage.kt b/src/client/kotlin/hiiragi283/ragium/integration/patchouli/HTCustomCraftingPage.kt new file mode 100644 index 0000000..792583b --- /dev/null +++ b/src/client/kotlin/hiiragi283/ragium/integration/patchouli/HTCustomCraftingPage.kt @@ -0,0 +1,83 @@ +package hiiragi283.ragium.integration.patchouli + +import net.minecraft.item.Item +import net.minecraft.item.ItemConvertible +import net.minecraft.item.ItemStack +import net.minecraft.recipe.Ingredient +import net.minecraft.recipe.Recipe +import net.minecraft.recipe.RecipeSerializer +import net.minecraft.recipe.RecipeType +import net.minecraft.recipe.input.RecipeInput +import net.minecraft.registry.RegistryWrapper +import net.minecraft.registry.tag.TagKey +import net.minecraft.util.Identifier +import net.minecraft.util.collection.DefaultedList +import net.minecraft.world.World +import vazkii.patchouli.client.book.BookContentsBuilder +import vazkii.patchouli.client.book.BookEntry +import vazkii.patchouli.client.book.page.abstr.PageSimpleProcessingRecipe + +class HTCustomCraftingPage : PageSimpleProcessingRecipe>(object : RecipeType> {}) { + companion object { + private val registry: MutableMap = mutableMapOf() + + @JvmStatic + fun register( + id: Identifier, + input: ItemConvertible, + icon: ItemStack, + output: ItemStack, + ) { + registry[id] = DummyRecipe(Ingredient.ofItems(input), icon, output) + } + + @JvmStatic + fun register( + id: Identifier, + input: TagKey, + icon: ItemStack, + output: ItemStack, + ) { + registry[id] = DummyRecipe(Ingredient.fromTag(input), icon, output) + } + } + + @Transient + private var loadedId: Identifier? = null + + override fun loadRecipe( + level: World?, + builder: BookContentsBuilder, + entry: BookEntry, + res: Identifier?, + ): Recipe<*>? { + if (level == null || res == null) return null + if (loadedId == res) return null + registry[res] + val recipe: DummyRecipe = registry[res] ?: return null + entry.addRelevantStack(builder, recipe.getResult(level.registryManager), pageNum) + loadedId = res + return recipe + } + + // Recipe // + + private class DummyRecipe(private val input: Ingredient, private val icon: ItemStack, private val output: ItemStack) : + Recipe { + override fun matches(input: RecipeInput, world: World): Boolean = false + + override fun craft(input: RecipeInput, lookup: RegistryWrapper.WrapperLookup): ItemStack = output + + override fun fits(width: Int, height: Int): Boolean = true + + override fun getResult(registriesLookup: RegistryWrapper.WrapperLookup?): ItemStack = output + + override fun getIngredients(): DefaultedList = DefaultedList.ofSize(1, input) + + override fun createIcon(): ItemStack = icon + + override fun getSerializer(): RecipeSerializer<*>? = null + + override fun getType(): RecipeType<*>? = null + } +} diff --git a/src/client/kotlin/hiiragi283/ragium/integration/patchouli/HTMachineRecipePage.kt b/src/client/kotlin/hiiragi283/ragium/integration/patchouli/HTMachineRecipePage.kt new file mode 100644 index 0000000..d9f7624 --- /dev/null +++ b/src/client/kotlin/hiiragi283/ragium/integration/patchouli/HTMachineRecipePage.kt @@ -0,0 +1,95 @@ +package hiiragi283.ragium.integration.patchouli + +import com.mojang.blaze3d.systems.RenderSystem +import hiiragi283.ragium.api.recipe.HTMachineRecipe +import hiiragi283.ragium.common.init.RagiumRecipeTypes +import net.minecraft.client.gui.DrawContext +import net.minecraft.item.ItemStack +import net.minecraft.world.World +import vazkii.patchouli.client.book.gui.GuiBook +import vazkii.patchouli.client.book.page.abstr.PageDoubleRecipeRegistry + +class HTMachineRecipePage : PageDoubleRecipeRegistry(RagiumRecipeTypes.MACHINE) { + override fun drawRecipe( + graphics: DrawContext, + recipe: HTMachineRecipe, + recipeX: Int, + recipeY: Int, + mouseX: Int, + mouseY: Int, + second: Boolean, + ) { + RenderSystem.enableBlend() + // background tex + graphics.drawTexture(book.craftingTexture, recipeX - 2, recipeY - 2, 0F, 0F, 100, 62, 128, 256) + // header + parent.drawCenteredStringNoShadow( + graphics, + getTitle(second).asOrderedText(), + GuiBook.PAGE_WIDTH / 2, + recipeY - 10, + book.headerColor, + ) + // catalyst + parent.renderIngredient(graphics, recipeX + 79, recipeY + 22, mouseX, mouseY, recipe.catalyst) + // input + parent.renderIngredient( + graphics, + recipeX + 0 * 19 + 3, + recipeY + 0 * 19 + 3, + mouseX, + mouseY, + recipe.itemInputs.getOrNull(0), + ) + parent.renderIngredient( + graphics, + recipeX + 1 * 19 + 3, + recipeY + 0 * 19 + 3, + mouseX, + mouseY, + recipe.itemInputs.getOrNull(1), + ) + parent.renderIngredient( + graphics, + recipeX + 2 * 19 + 3, + recipeY + 0 * 19 + 3, + mouseX, + mouseY, + recipe.itemInputs.getOrNull(2), + ) + // output + parent.renderResult( + graphics, + recipeX + 0 * 19 + 3, + recipeY + 2 * 19 + 3, + mouseX, + mouseY, + recipe.itemOutputs.getOrNull(0), + ) + parent.renderResult( + graphics, + recipeX + 1 * 19 + 3, + recipeY + 2 * 19 + 3, + mouseX, + mouseY, + recipe.itemOutputs.getOrNull(1), + ) + parent.renderResult( + graphics, + recipeX + 2 * 19 + 3, + recipeY + 2 * 19 + 3, + mouseX, + mouseY, + recipe.itemOutputs.getOrNull(2), + ) + // icon + parent.renderItemStack(graphics, recipeX + 79, recipeY + 41, mouseX, mouseY, recipe.createIcon()) + } + + override fun getRecipeOutput(level: World?, recipe: HTMachineRecipe?): ItemStack { + if (level == null || recipe == null) return ItemStack.EMPTY + return recipe.getResult(level.registryManager) + } + + override fun getRecipeHeight(): Int = 78 +} diff --git a/src/client/kotlin/hiiragi283/ragium/integration/patchouli/PatchouliExtensions.kt b/src/client/kotlin/hiiragi283/ragium/integration/patchouli/PatchouliExtensions.kt new file mode 100644 index 0000000..8b77244 --- /dev/null +++ b/src/client/kotlin/hiiragi283/ragium/integration/patchouli/PatchouliExtensions.kt @@ -0,0 +1,36 @@ +package hiiragi283.ragium.integration.patchouli + +import hiiragi283.ragium.api.recipe.HTIngredient +import hiiragi283.ragium.api.recipe.HTRecipeResult +import net.minecraft.client.gui.DrawContext +import net.minecraft.item.ItemStack +import vazkii.patchouli.client.book.gui.GuiBookEntry + +// GuiBookEntry // + +fun GuiBookEntry.renderIngredient( + context: DrawContext, + x: Int, + y: Int, + mouseX: Int, + mouseY: Int, + ingredient: HTIngredient.Item?, +) { + val stacks: List = ingredient?.matchingStacks ?: return + if (stacks.isNotEmpty()) { + renderItemStack(context, x, y, mouseX, mouseY, stacks[(ticksInBook / 20) % stacks.size]) + } +} + +fun GuiBookEntry.renderResult( + context: DrawContext, + x: Int, + y: Int, + mouseX: Int, + mouseY: Int, + result: HTRecipeResult.Item?, +) { + result?.stack?.let { + renderItemStack(context, x, y, mouseX, mouseY, it) + } +} diff --git a/src/client/kotlin/hiiragi283/ragium/integration/patchouli/RagiumPatchouliInit.kt b/src/client/kotlin/hiiragi283/ragium/integration/patchouli/RagiumPatchouliInit.kt new file mode 100644 index 0000000..252d4fa --- /dev/null +++ b/src/client/kotlin/hiiragi283/ragium/integration/patchouli/RagiumPatchouliInit.kt @@ -0,0 +1,40 @@ +package hiiragi283.ragium.integration.patchouli + +import hiiragi283.ragium.api.RagiumAPI +import hiiragi283.ragium.api.tags.RagiumItemTags +import hiiragi283.ragium.common.RagiumContents +import net.minecraft.item.Items +import net.minecraft.util.Identifier +import vazkii.patchouli.client.book.BookPage +import vazkii.patchouli.client.book.ClientBookRegistry + +object RagiumPatchouliInit { + @JvmStatic + fun init() { + addPageType(RagiumAPI.MOD_ID, "machine_recipe") + addPageType(RagiumAPI.MOD_ID, "custom_recipe") + + HTCustomCraftingPage.register( + RagiumAPI.id("raw_raginite"), + RagiumItemTags.RAGINITE_ORES, + Items.WOODEN_PICKAXE.defaultStack, + RagiumContents.RawMaterials.RAGINITE + .asItem() + .defaultStack, + ) + + HTCustomCraftingPage.register( + RagiumAPI.id("raginite_dust"), + RagiumContents.Dusts.CRUDE_RAGINITE, + Items.CAULDRON.defaultStack, + RagiumContents.Dusts.RAGINITE + .asItem() + .defaultStack, + ) + } + + @JvmStatic + private inline fun addPageType(modId: String, name: String) { + ClientBookRegistry.INSTANCE.pageTypes[Identifier.of(modId, name)] = T::class.java + } +} diff --git a/src/client/kotlin/hiiragi283/ragium/integration/rei/HTMachineRecipeCategory.kt b/src/client/kotlin/hiiragi283/ragium/integration/rei/HTMachineRecipeCategory.kt new file mode 100644 index 0000000..06d9712 --- /dev/null +++ b/src/client/kotlin/hiiragi283/ragium/integration/rei/HTMachineRecipeCategory.kt @@ -0,0 +1,132 @@ +package hiiragi283.ragium.integration.rei + +import hiiragi283.ragium.api.machine.HTMachineTier +import hiiragi283.ragium.api.machine.HTMachineType +import hiiragi283.ragium.api.recipe.HTMachineRecipe +import hiiragi283.ragium.common.init.RagiumTranslationKeys +import me.shedaniel.math.Point +import me.shedaniel.math.Rectangle +import me.shedaniel.rei.api.client.gui.Renderer +import me.shedaniel.rei.api.client.gui.widgets.Slot +import me.shedaniel.rei.api.client.gui.widgets.Tooltip +import me.shedaniel.rei.api.client.gui.widgets.Widget +import me.shedaniel.rei.api.client.gui.widgets.Widgets +import me.shedaniel.rei.api.client.registry.display.DisplayCategory +import me.shedaniel.rei.api.common.category.CategoryIdentifier +import me.shedaniel.rei.api.common.entry.EntryStack +import me.shedaniel.rei.api.common.util.EntryStacks +import net.fabricmc.api.EnvType +import net.fabricmc.api.Environment +import net.minecraft.component.ComponentChanges +import net.minecraft.component.DataComponentTypes +import net.minecraft.item.Item +import net.minecraft.item.ItemStack +import net.minecraft.item.Items +import net.minecraft.registry.Registries +import net.minecraft.registry.entry.RegistryEntry +import net.minecraft.text.Text +import net.minecraft.util.Formatting + +@Environment(EnvType.CLIENT) +class HTMachineRecipeCategory(private val type: HTMachineType) : DisplayCategory { + override fun getCategoryIdentifier(): CategoryIdentifier = type.categoryId + + override fun getTitle(): Text = type.text + + override fun getIcon(): Renderer = type.createEntryStack(HTMachineTier.PRIMITIVE) + + override fun setupDisplay(display: HTMachineRecipeDisplay, bounds: Rectangle): List = buildList { + this += Widgets.createRecipeBase(bounds) + this += Widgets.createArrow(getPoint(bounds, 3.25, 0.0)).animationDurationTicks(200.0) + this.addAll( + when (display) { + is HTMachineRecipeDisplay.Simple -> setupSimple(display, bounds) + is HTMachineRecipeDisplay.Large -> setupLarge(display, bounds) + }, + ) + // catalyst + this += createSlot(bounds, 3.5, 1.0, display.catalyst).markInput() + // info + this += createInfoSlot(bounds, 7, 1, display).markOutput() + } + + private fun setupSimple(display: HTMachineRecipeDisplay, bounds: Rectangle): List = buildList { + // inputs + this += createSlot(bounds, 1, 0, display.inputEntries.getOrNull(0)).markInput() + this += createSlot(bounds, 2, 0, display.inputEntries.getOrNull(1)).markInput() + this += createSlot(bounds, 2, 1, display.inputEntries.getOrNull(2)).markInput() + // outputs + this += createSlot(bounds, 5, 0, display.outputEntries.getOrNull(0)).markOutput() + this += createSlot(bounds, 6, 0, display.outputEntries.getOrNull(1)).markOutput() + this += createSlot(bounds, 5, 1, display.outputEntries.getOrNull(2)).markOutput() + } + + private fun setupLarge(display: HTMachineRecipeDisplay, bounds: Rectangle): List = buildList { + // inputs + this += createSlot(bounds, 0, 0, display.inputEntries.getOrNull(0)).markInput() + this += createSlot(bounds, 1, 0, display.inputEntries.getOrNull(1)).markInput() + this += createSlot(bounds, 2, 0, display.inputEntries.getOrNull(2)).markInput() + this += createSlot(bounds, 1, 1, display.inputEntries.getOrNull(3)).markInput() + this += createSlot(bounds, 2, 1, display.inputEntries.getOrNull(4)).markInput() + // outputs + this += createSlot(bounds, 5, 0, display.outputEntries.getOrNull(0)).markOutput() + this += createSlot(bounds, 6, 0, display.outputEntries.getOrNull(1)).markOutput() + this += createSlot(bounds, 7, 0, display.outputEntries.getOrNull(2)).markOutput() + this += createSlot(bounds, 5, 1, display.outputEntries.getOrNull(3)).markOutput() + this += createSlot(bounds, 6, 1, display.outputEntries.getOrNull(4)).markOutput() + } + + override fun getDisplayHeight(): Int = 18 * 2 + 8 + + override fun getDisplayWidth(display: HTMachineRecipeDisplay): Int = 18 * 8 + 8 + + // Utils // + + fun getPoint(bounds: Rectangle, x: Int, y: Int): Point = Point(bounds.x + 5 + x * 18, bounds.y + 5 + y * 18) + + fun getPoint(bounds: Rectangle, x: Double, y: Double): Point = Point(bounds.x + 5 + x * 18, bounds.y + 5 + y * 18) + + fun createSlot( + bounds: Rectangle, + x: Int, + y: Int, + ingredient: Collection>?, + ): Slot = Widgets + .createSlot(getPoint(bounds, x, y)) + .entries(ingredient ?: listOf()) + + fun createSlot( + bounds: Rectangle, + x: Double, + y: Double, + ingredient: Collection>?, + ): Slot = Widgets + .createSlot(getPoint(bounds, x, y)) + .entries(ingredient ?: listOf()) + + fun createInfoSlot( + bounds: Rectangle, + x: Int, + y: Int, + display: HTMachineRecipeDisplay, + ): Slot = Widgets + .createSlot(getPoint(bounds, x, y)) + .entries(listOf(createInfoEntry(display.recipe))) + + protected fun createInfoEntry(recipe: HTMachineRecipe): EntryStack<*> { + val entry: RegistryEntry = Registries.ITEM.getEntry(Items.WRITABLE_BOOK) + val components: ComponentChanges = ComponentChanges + .builder() + .add( + DataComponentTypes.ITEM_NAME, + Text.translatable(RagiumTranslationKeys.REI_RECIPE_INFO).formatted(Formatting.LIGHT_PURPLE), + ).build() + val stack = ItemStack(entry, 1, components) + val tier: HTMachineTier = recipe.tier + return EntryStacks.of(stack).tooltipProcessor { _: EntryStack, tooltip: Tooltip -> + tooltip.add(tier.tierText) + tooltip.add(tier.recipeCostText) + tooltip + } + } +} diff --git a/src/client/kotlin/hiiragi283/ragium/integration/rei/HTMachineRecipeDisplay.kt b/src/client/kotlin/hiiragi283/ragium/integration/rei/HTMachineRecipeDisplay.kt new file mode 100644 index 0000000..96c9279 --- /dev/null +++ b/src/client/kotlin/hiiragi283/ragium/integration/rei/HTMachineRecipeDisplay.kt @@ -0,0 +1,63 @@ +package hiiragi283.ragium.integration.rei + +import hiiragi283.ragium.api.recipe.HTMachineRecipe +import me.shedaniel.rei.api.common.category.CategoryIdentifier +import me.shedaniel.rei.api.common.display.Display +import me.shedaniel.rei.api.common.entry.EntryIngredient +import net.fabricmc.api.EnvType +import net.fabricmc.api.Environment +import net.minecraft.util.Identifier +import java.util.* + +@Environment(EnvType.CLIENT) +sealed class HTMachineRecipeDisplay(val recipe: HTMachineRecipe, val id: Identifier) : Display { + fun getItemInput(index: Int): EntryIngredient = recipe.itemInputs.getOrNull(index)?.entryIngredient ?: EntryIngredient.empty() + + fun getFluidInput(index: Int): EntryIngredient = recipe.fluidInputs.getOrNull(index)?.entryIngredient ?: EntryIngredient.empty() + + fun getItemOutput(index: Int): EntryIngredient = recipe.itemOutputs.getOrNull(index)?.entryIngredient ?: EntryIngredient.empty() + + fun getFluidOutput(index: Int): EntryIngredient = recipe.fluidOutputs.getOrNull(index)?.entryIngredient ?: EntryIngredient.empty() + + val catalyst: EntryIngredient = recipe.catalyst?.entryIngredient ?: EntryIngredient.empty() + + override fun getCategoryIdentifier(): CategoryIdentifier<*> = recipe.machineType.categoryId + + final override fun getDisplayLocation(): Optional = Optional.of(id) + + // Simple // + + class Simple(recipe: HTMachineRecipe, id: Identifier) : HTMachineRecipeDisplay(recipe, id) { + override fun getInputEntries(): List = buildList { + add(getItemInput(0)) + add(getItemInput(1)) + add(getFluidInput(0)) + } + + override fun getOutputEntries(): List = buildList { + add(getItemOutput(0)) + add(getItemOutput(1)) + add(getFluidOutput(0)) + } + } + + // Large // + + class Large(recipe: HTMachineRecipe, id: Identifier) : HTMachineRecipeDisplay(recipe, id) { + override fun getInputEntries(): List = buildList { + add(getItemInput(0)) + add(getItemInput(1)) + add(getItemInput(2)) + add(getFluidInput(0)) + add(getFluidInput(1)) + } + + override fun getOutputEntries(): List = buildList { + add(getItemOutput(0)) + add(getItemOutput(1)) + add(getItemOutput(2)) + add(getFluidOutput(0)) + add(getFluidOutput(1)) + } + } +} diff --git a/src/client/kotlin/hiiragi283/ragium/integration/rei/REIExtensions.kt b/src/client/kotlin/hiiragi283/ragium/integration/rei/REIExtensions.kt new file mode 100644 index 0000000..978b18b --- /dev/null +++ b/src/client/kotlin/hiiragi283/ragium/integration/rei/REIExtensions.kt @@ -0,0 +1,103 @@ +package hiiragi283.ragium.integration.rei + +import hiiragi283.ragium.api.machine.HTMachineConvertible +import hiiragi283.ragium.api.machine.HTMachineTier +import hiiragi283.ragium.api.recipe.HTIngredient +import hiiragi283.ragium.api.recipe.HTRecipeResult +import me.shedaniel.rei.api.common.category.CategoryIdentifier +import me.shedaniel.rei.api.common.entry.EntryIngredient +import me.shedaniel.rei.api.common.entry.EntryStack +import me.shedaniel.rei.api.common.util.EntryStacks +import me.shedaniel.rei.impl.Internals +import net.minecraft.enchantment.Enchantment +import net.minecraft.enchantment.EnchantmentLevelEntry +import net.minecraft.fluid.Fluid +import net.minecraft.item.EnchantedBookItem +import net.minecraft.item.ItemStack +import net.minecraft.item.Items +import net.minecraft.registry.DynamicRegistryManager +import net.minecraft.registry.RegistryKey +import net.minecraft.registry.RegistryKeys +import net.minecraft.registry.entry.RegistryEntry + +// Accessors // + +@Suppress("UnstableApiUsage") +val dynamicRegistry: () -> DynamicRegistryManager + get() = Internals::getRegistryAccess + +// CategoryIdentifier // + +val HTMachineConvertible.categoryId: CategoryIdentifier + get() = CategoryIdentifier.of(asMachine().id) + +// EntryStack // + +fun HTMachineConvertible.createEntryStack(tier: HTMachineTier): EntryStack = + EntryStacks.of(createItemStack(tier)) + +fun createEnchantedBook(key: RegistryKey): EntryStack = dynamicRegistry() + .get(RegistryKeys.ENCHANTMENT) + .getEntry(key) + .map { EnchantmentLevelEntry(it, 1) } + .map(EnchantedBookItem::forEnchantment) + .map(EntryStacks::of) + .orElse(EntryStacks.of(Items.ENCHANTED_BOOK)) + +// Display // + +/*@JvmField +val INPUT_ENTRIES: HTPropertyKey.Defaulted<(HTMachineRecipe) -> List> = + HTPropertyKey.Defaulted( + RagiumAPI.id("input_entries"), + value = { recipe: HTMachineRecipe -> + buildList { + add(recipe.getInput(0)?.entryIngredient ?: EntryIngredient.empty()) + add(recipe.getInput(1)?.entryIngredient ?: EntryIngredient.empty()) + add(recipe.getInput(2)?.entryIngredient ?: EntryIngredient.empty()) + add(EntryIngredients.ofIngredient(recipe.catalyst)) + } + }, + ) + +@JvmField +val OUTPUT_ENTRIES: HTPropertyKey.Defaulted<(HTMachineRecipe) -> List> = + HTPropertyKey.Defaulted( + RagiumAPI.id("output_entries"), + value = { recipe: HTMachineRecipe -> + recipe.outputs.map(HTRecipeResult::entryIngredient) + }, + )*/ + +// fun HTMachineType.getInputEntries(recipe: HTMachineRecipe): List = getOrDefault(INPUT_ENTRIES)(recipe) + +// fun HTMachineType.getOutputEntries(recipe: HTMachineRecipe): List = getOrDefault(OUTPUT_ENTRIES)(recipe) + +// WeightedIngredient // + +val HTIngredient<*, *, *>.entryStacks: List> + get() = when (this) { + is HTIngredient.Fluid -> entryMap.map { (fluid: RegistryEntry, amount: Long) -> + EntryStacks.of( + fluid.value(), + amount + ) + } + + is HTIngredient.Item -> matchingStacks.map(EntryStacks::of) + } + +val HTIngredient<*, *, *>.entryIngredient: EntryIngredient + get() = EntryIngredient.of(entryStacks) + +// HTRecipeResult // + +val HTRecipeResult<*, *, *>.entryStack: EntryStack<*> + get() = when (this) { + is HTRecipeResult.Fluid -> EntryStacks.of(resourceAmount.resource.fluid, resourceAmount.amount) + is HTRecipeResult.Item -> EntryStacks.of(stack) + } + +val HTRecipeResult<*, *, *>.entryIngredient: EntryIngredient + get() = EntryIngredient.of(entryStack) + diff --git a/src/client/kotlin/hiiragi283/ragium/integration/rei/RagiumREIClient.kt b/src/client/kotlin/hiiragi283/ragium/integration/rei/RagiumREIClient.kt new file mode 100644 index 0000000..cdfdeb7 --- /dev/null +++ b/src/client/kotlin/hiiragi283/ragium/integration/rei/RagiumREIClient.kt @@ -0,0 +1,106 @@ +package hiiragi283.ragium.integration.rei + +import hiiragi283.ragium.api.RagiumAPI +import hiiragi283.ragium.api.extension.component1 +import hiiragi283.ragium.api.extension.component2 +import hiiragi283.ragium.api.machine.HTMachineTier +import hiiragi283.ragium.api.machine.HTMachineType +import hiiragi283.ragium.api.recipe.HTMachineRecipe +import hiiragi283.ragium.common.init.RagiumBlocks +import hiiragi283.ragium.common.init.RagiumEnchantments +import hiiragi283.ragium.common.init.RagiumMachineTypes +import hiiragi283.ragium.common.init.RagiumRecipeTypes +import hiiragi283.ragium.common.screen.HTProcessorScreenHandler +import me.shedaniel.rei.api.client.plugins.REIClientPlugin +import me.shedaniel.rei.api.client.registry.category.CategoryRegistry +import me.shedaniel.rei.api.client.registry.display.DisplayRegistry +import me.shedaniel.rei.api.client.registry.transfer.TransferHandlerRegistry +import me.shedaniel.rei.api.client.registry.transfer.simple.SimpleTransferHandler +import me.shedaniel.rei.api.common.category.CategoryIdentifier +import me.shedaniel.rei.api.common.entry.EntryStack +import me.shedaniel.rei.api.common.util.EntryStacks +import me.shedaniel.rei.plugin.common.BuiltinPlugin +import net.fabricmc.api.EnvType +import net.fabricmc.api.Environment +import net.minecraft.item.ItemStack +import net.minecraft.recipe.RecipeEntry +import net.minecraft.util.Identifier + +@Environment(EnvType.CLIENT) +object RagiumREIClient : REIClientPlugin { + init { + RagiumAPI.log { info("REI Integration enabled!") } + } + + // REIClientPlugin // + + override fun registerCategories(registry: CategoryRegistry) { + // Machines + RagiumAPI.getInstance().machineTypeRegistry.processors.forEach { type: HTMachineType -> + registry.add(HTMachineRecipeCategory(type)) + HTMachineTier.entries.map(type::createEntryStack).forEach { stack: EntryStack -> + registry.addWorkstations(type.categoryId, stack) + } + } + registry.addWorkstations( + RagiumMachineTypes.Processor.GRINDER.categoryId, + EntryStacks.of(RagiumBlocks.MANUAL_GRINDER), + ) + + // Enchantment + registry.addWorkstations( + BuiltinPlugin.SMELTING, + createEnchantedBook(RagiumEnchantments.SMELTING), + ) + registry.addWorkstations( + RagiumMachineTypes.Processor.GRINDER.categoryId, + createEnchantedBook(RagiumEnchantments.SLEDGE_HAMMER), + ) + registry.addWorkstations( + RagiumMachineTypes.SAW_MILL.categoryId, + createEnchantedBook(RagiumEnchantments.BUZZ_SAW), + ) + } + + override fun registerDisplays(registry: DisplayRegistry) { + // Machines + registry.registerRecipeFiller( + HTMachineRecipe::class.java, + RagiumRecipeTypes.MACHINE, + ) { entry: RecipeEntry -> + val (id: Identifier, recipe: HTMachineRecipe) = entry + when (recipe.sizeType) { + HTMachineRecipe.SizeType.SIMPLE -> HTMachineRecipeDisplay.Simple(recipe, id) + HTMachineRecipe.SizeType.LARGE -> HTMachineRecipeDisplay.Large(recipe, id) + } + } + } + + /*override fun registerScreens(registry: ScreenRegistry) { + // Machines + registry.registerContainerClickArea( + Rectangle(5 + 18 * 4, 5 + 18 * 1, 18, 18), + HTProcessorScreen::class.java, + *getMachineIds().toTypedArray(), + ) + }*/ + + @Suppress("UnstableApiUsage") + override fun registerTransferHandlers(registry: TransferHandlerRegistry) { + // Machines + RagiumAPI + .getInstance() + .machineTypeRegistry + .processors + .map(HTMachineType::categoryId) + .forEach { id: CategoryIdentifier -> + registry.register( + SimpleTransferHandler.create( + HTProcessorScreenHandler::class.java, + id, + SimpleTransferHandler.IntRange(0, 3), + ), + ) + } + } +} diff --git a/src/main/generated/data/ragium/advancement/recipes/misc/shapeless/guide_book.json b/src/main/generated/data/ragium/advancement/recipes/misc/shapeless/guide_book.json new file mode 100644 index 0000000..47d04a9 --- /dev/null +++ b/src/main/generated/data/ragium/advancement/recipes/misc/shapeless/guide_book.json @@ -0,0 +1,29 @@ +{ + "fabric:load_conditions": [ + { + "condition": "fabric:all_mods_loaded", + "values": [ + "patchouli" + ] + } + ], + "parent": "minecraft:recipes/root", + "criteria": { + "has_the_recipe": { + "conditions": { + "recipe": "patchouli:shapeless/guide_book" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe" + ] + ], + "rewards": { + "recipes": [ + "patchouli:shapeless/guide_book" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/ragium/recipe/shapeless/guide_book.json b/src/main/generated/data/ragium/recipe/shapeless/guide_book.json new file mode 100644 index 0000000..f06a842 --- /dev/null +++ b/src/main/generated/data/ragium/recipe/shapeless/guide_book.json @@ -0,0 +1,30 @@ +{ + "fabric:load_conditions": [ + { + "condition": "fabric:all_mods_loaded", + "values": [ + "patchouli" + ] + } + ], + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + { + "item": "minecraft:book" + }, + { + "item": "ragium:raw_crude_raginite" + }, + { + "tag": "c:ingots/iron" + } + ], + "result": { + "components": { + "patchouli:book": "ragium:ragi_wiki" + }, + "count": 1, + "id": "patchouli:guide_book" + } +} \ No newline at end of file diff --git a/src/main/generated/data/ragium/recipe/techreborn/blast_furnace/ragi_steel_ingot.json b/src/main/generated/data/ragium/recipe/techreborn/blast_furnace/ragi_steel_ingot.json new file mode 100644 index 0000000..b69af2f --- /dev/null +++ b/src/main/generated/data/ragium/recipe/techreborn/blast_furnace/ragi_steel_ingot.json @@ -0,0 +1,21 @@ +{ + "type": "techreborn:blast_furnace", + "heat": 1000, + "ingredients": [ + { + "tag": "c:ingots/iron" + }, + { + "count": 4, + "item": "ragium:raginite_dust" + } + ], + "outputs": [ + { + "count": 1, + "id": "ragium:ragi_steel_ingot" + } + ], + "power": 128, + "time": 100 +} \ No newline at end of file diff --git a/src/main/kotlin/hiiragi283/ragium/data/RagiumDataGenerator.kt b/src/main/kotlin/hiiragi283/ragium/data/RagiumDataGenerator.kt new file mode 100644 index 0000000..ab92df4 --- /dev/null +++ b/src/main/kotlin/hiiragi283/ragium/data/RagiumDataGenerator.kt @@ -0,0 +1,10 @@ +package hiiragi283.ragium.data + +import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint +import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator + +object RagiumDataGenerator : DataGeneratorEntrypoint { + override fun onInitializeDataGenerator(fabricDataGenerator: FabricDataGenerator) { + // Just a dummy + } +} diff --git a/src/main/kotlin/hiiragi283/ragium/integration/RagiumIntegration.kt b/src/main/kotlin/hiiragi283/ragium/integration/RagiumIntegration.kt new file mode 100644 index 0000000..abd9622 --- /dev/null +++ b/src/main/kotlin/hiiragi283/ragium/integration/RagiumIntegration.kt @@ -0,0 +1,41 @@ +package hiiragi283.ragium.integration + +import hiiragi283.ragium.api.RagiumAPI +import hiiragi283.ragium.api.extension.isModLoaded +import hiiragi283.ragium.api.extension.openBackpackScreen +import hiiragi283.ragium.common.init.RagiumComponentTypes +import hiiragi283.ragium.integration.accessories.HTOpenBackpackPayload +import hiiragi283.ragium.integration.accessories.RagiumAccessoriesInit +import io.wispforest.accessories.api.AccessoriesCapability +import net.fabricmc.api.ModInitializer +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking +import net.minecraft.item.ItemStack +import net.minecraft.server.network.ServerPlayerEntity +import net.minecraft.world.World + +object RagiumIntegration : ModInitializer { + override fun onInitialize() { + HTOpenBackpackPayload + + RagiumAPI.getInstance().registerIntegration(::registerIntegrations) + } + + private fun registerIntegrations() { + if (isModLoaded("accessories")) { + RagiumAccessoriesInit.init() + + ServerPlayNetworking.registerGlobalReceiver( + HTOpenBackpackPayload.ID, + ) { _: HTOpenBackpackPayload, context: ServerPlayNetworking.Context -> + val player: ServerPlayerEntity = context.player() + val world: World = player.world + val capability: AccessoriesCapability = player.accessoriesCapability() ?: return@registerGlobalReceiver + capability + .getEquipped { it.contains(RagiumComponentTypes.COLOR) } + ?.firstOrNull { it.reference.slotName() == "back" } + ?.stack + ?.let { stack: ItemStack -> openBackpackScreen(world, player, stack) } + } + } + } +} diff --git a/src/main/kotlin/hiiragi283/ragium/integration/accessories/HTEmptyAccessory.kt b/src/main/kotlin/hiiragi283/ragium/integration/accessories/HTEmptyAccessory.kt new file mode 100644 index 0000000..36b7f0e --- /dev/null +++ b/src/main/kotlin/hiiragi283/ragium/integration/accessories/HTEmptyAccessory.kt @@ -0,0 +1,5 @@ +package hiiragi283.ragium.integration.accessories + +import io.wispforest.accessories.api.Accessory + +data object HTEmptyAccessory : Accessory diff --git a/src/main/kotlin/hiiragi283/ragium/integration/accessories/HTOpenBackpackPayload.kt b/src/main/kotlin/hiiragi283/ragium/integration/accessories/HTOpenBackpackPayload.kt new file mode 100644 index 0000000..31921d4 --- /dev/null +++ b/src/main/kotlin/hiiragi283/ragium/integration/accessories/HTOpenBackpackPayload.kt @@ -0,0 +1,21 @@ +package hiiragi283.ragium.integration.accessories + +import hiiragi283.ragium.api.RagiumAPI +import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry +import net.minecraft.network.RegistryByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.packet.CustomPayload + +data object HTOpenBackpackPayload : CustomPayload { + + @JvmField + val PACKET_CODEC: PacketCodec = PacketCodec.unit(HTOpenBackpackPayload) + + @JvmField + val ID: CustomPayload.Id = + CustomPayload.Id(RagiumAPI.id("open_backpack")).apply { + PayloadTypeRegistry.playC2S().register(this, PACKET_CODEC) + } + + override fun getId(): CustomPayload.Id = ID +} diff --git a/src/main/kotlin/hiiragi283/ragium/integration/accessories/HTWrappedAccessory.kt b/src/main/kotlin/hiiragi283/ragium/integration/accessories/HTWrappedAccessory.kt new file mode 100644 index 0000000..0c153e2 --- /dev/null +++ b/src/main/kotlin/hiiragi283/ragium/integration/accessories/HTWrappedAccessory.kt @@ -0,0 +1,16 @@ +package hiiragi283.ragium.integration.accessories + +import hiiragi283.ragium.api.accessory.HTAccessoryRegistry +import io.wispforest.accessories.api.Accessory +import io.wispforest.accessories.api.slot.SlotReference +import net.minecraft.item.ItemStack + +object HTWrappedAccessory : Accessory { + override fun onEquip(stack: ItemStack, reference: SlotReference) { + HTAccessoryRegistry.onEquipped(reference.entity(), stack) + } + + override fun onUnequip(stack: ItemStack, reference: SlotReference) { + HTAccessoryRegistry.onUnequipped(reference.entity(), stack) + } +} diff --git a/src/main/kotlin/hiiragi283/ragium/integration/accessories/RagiumAccessoriesInit.kt b/src/main/kotlin/hiiragi283/ragium/integration/accessories/RagiumAccessoriesInit.kt new file mode 100644 index 0000000..48e8913 --- /dev/null +++ b/src/main/kotlin/hiiragi283/ragium/integration/accessories/RagiumAccessoriesInit.kt @@ -0,0 +1,45 @@ +package hiiragi283.ragium.integration.accessories + +import hiiragi283.ragium.api.RagiumAPI +import hiiragi283.ragium.api.accessory.HTAccessoryRegistry +import hiiragi283.ragium.api.accessory.HTAccessorySlotTypes +import hiiragi283.ragium.common.RagiumContents +import io.wispforest.accessories.api.AccessoriesAPI +import io.wispforest.accessories.api.Accessory +import io.wispforest.accessories.api.components.AccessoriesDataComponents +import io.wispforest.accessories.api.components.AccessorySlotValidationComponent +import net.fabricmc.fabric.api.item.v1.DefaultItemComponentEvents +import net.minecraft.component.ComponentMap +import net.minecraft.item.Item +import net.minecraft.item.ItemConvertible + +object RagiumAccessoriesInit { + private val slotCache: MutableMap> = mutableMapOf() + + @JvmStatic + fun init() { + HTAccessoryRegistry.slotTypes.forEach { (item: ItemConvertible, slot: HTAccessorySlotTypes) -> + registerAccessory(item, HTWrappedAccessory, slot) + } + + registerAccessory(RagiumContents.Misc.BACKPACK, HTEmptyAccessory, HTAccessorySlotTypes.BACK) + + DefaultItemComponentEvents.MODIFY.register { context: DefaultItemComponentEvents.ModifyContext -> + context.modify(slotCache::containsKey) { builder: ComponentMap.Builder, item: Item -> + val slots: Set = slotCache.getOrDefault(item, setOf()) + builder.add( + AccessoriesDataComponents.SLOT_VALIDATION, + AccessorySlotValidationComponent(slots, setOf()), + ) + } + } + + RagiumAPI.log { info("Accessories integration loaded!") } + } + + @JvmStatic + private fun registerAccessory(item: ItemConvertible, accessory: Accessory, vararg slots: HTAccessorySlotTypes) { + AccessoriesAPI.registerAccessory(item.asItem(), accessory) + slotCache[item.asItem()] = slots.map(HTAccessorySlotTypes::asString).toSet() + } +} diff --git a/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/alchemy.json b/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/alchemy.json new file mode 100644 index 0000000..d7ce47c --- /dev/null +++ b/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/alchemy.json @@ -0,0 +1,5 @@ +{ + "name": "Alchemy", + "description": "Alchemy content", + "icon": "ragium:ragium_dust" +} diff --git a/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/foods.json b/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/foods.json new file mode 100644 index 0000000..343dca9 --- /dev/null +++ b/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/foods.json @@ -0,0 +1,5 @@ +{ + "name": "Foods", + "description": "Foods", + "icon": "ragium:sweet_berries_cake" +} diff --git a/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/machines.json b/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/machines.json new file mode 100644 index 0000000..cd9301a --- /dev/null +++ b/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/machines.json @@ -0,0 +1,5 @@ +{ + "name": "Machines", + "description": "Machines", + "icon": "ragium:meta_machine" +} diff --git a/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/oil_chemistry.json b/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/oil_chemistry.json new file mode 100644 index 0000000..f9c7632 --- /dev/null +++ b/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/oil_chemistry.json @@ -0,0 +1,5 @@ +{ + "name": "Oil Chemistry", + "description": "Oil Chemistry", + "icon": "ragium:petroleum_fluid_cube" +} diff --git a/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/tier1.json b/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/tier1.json new file mode 100644 index 0000000..83e4e5a --- /dev/null +++ b/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/tier1.json @@ -0,0 +1,5 @@ +{ + "name": "Tier 1", + "description": "First age for Ragium", + "icon": "ragium:ragi_alloy_ingot" +} diff --git a/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/tier2.json b/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/tier2.json new file mode 100644 index 0000000..6902cff --- /dev/null +++ b/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/tier2.json @@ -0,0 +1,5 @@ +{ + "name": "Tier 2", + "description": "Second age for Ragium", + "icon": "ragium:ragi_steel_ingot" +} diff --git a/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/tier3.json b/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/tier3.json new file mode 100644 index 0000000..7d1fbf6 --- /dev/null +++ b/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/categories/tier3.json @@ -0,0 +1,5 @@ +{ + "name": "Tier 3", + "description": "Third age for Ragium", + "icon": "ragium:refined_ragi_steel_ingot" +} diff --git a/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/entries/tier1/ragi_alloy.json b/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/entries/tier1/ragi_alloy.json new file mode 100644 index 0000000..32ceeac --- /dev/null +++ b/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/entries/tier1/ragi_alloy.json @@ -0,0 +1,24 @@ +{ + "name": "Ragi-Alloy", + "icon": "ragium:ragi_alloy_ingot", + "category": "ragium:tier1", + "pages": [ + { + "type": "patchouli:text", + "text": "This is a test entry, but it should show up!" + }, + { + "type": "patchouli:crafting", + "recipe": "ragium:shaped/ragi_alloy_compound", + "recipe2": "ragium:shaped/ragi_alloy_compound_1" + }, + { + "type": "patchouli:smelting", + "recipe": "ragium:smelting/ragi_alloy_ingot" + }, + { + "type": "ragium:machine_recipe", + "recipe": "ragium:grinder/raw_raginite_dust" + } + ] +} diff --git a/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/entries/tier1/raginite.json b/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/entries/tier1/raginite.json new file mode 100644 index 0000000..5bb4acc --- /dev/null +++ b/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/entries/tier1/raginite.json @@ -0,0 +1,15 @@ +{ + "name": "Raginite", + "icon": "ragium:raginite_dust", + "category": "ragium:tier1", + "pages": [ + { + "type": "patchouli:text", + "text": "This is a test entry, but it should show up!" + }, + { + "type": "ragium:custom_recipe", + "recipe": "ragium:raginite_dust" + } + ] +} diff --git a/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/entries/tier1/raw_raginite.json b/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/entries/tier1/raw_raginite.json new file mode 100644 index 0000000..fbbdd75 --- /dev/null +++ b/src/main/resources/assets/ragium/patchouli_books/ragi_wiki/en_us/entries/tier1/raw_raginite.json @@ -0,0 +1,23 @@ +{ + "name": "Raw Raginite", + "icon": "ragium:raw_raginite", + "category": "ragium:tier1", + "pages": [ + { + "type": "patchouli:text", + "text": "This is a test entry, but it should show up!" + }, + { + "type": "patchouli:spotlight", + "title": "Raginite Ore", + "item": "tag:c:ores/raginite", + "text": "Found in overworld" + }, + { + "type": "patchouli:spotlight", + "title": "Raw Raginite", + "item": "ragium:raw_raginite", + "text": "Drops from Raginite Ores" + } + ] +} diff --git a/src/main/resources/data/ragium/patchouli_books/ragi_wiki/book.json b/src/main/resources/data/ragium/patchouli_books/ragi_wiki/book.json new file mode 100644 index 0000000..4b45011 --- /dev/null +++ b/src/main/resources/data/ragium/patchouli_books/ragi_wiki/book.json @@ -0,0 +1,9 @@ +{ + "name": "Ragi-Wiki", + "landing_text": "An official wiki for Ragium", + "version": 1, + "creative_tab": "ragium:item", + "use_resource_pack": true, + "book_texture": "patchouli:textures/gui/book_red.png", + "model": "patchouli:book_red" +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 4858085..c980852 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -15,21 +15,33 @@ "icon": "assets/ragium/textures/item/refined_ragi_steel_ingot.png", "environment": "*", "entrypoints": { + "main": [ + { + "value": "hiiragi283.ragium.integration.RagiumIntegration", + "adapter": "kotlin" + } + ], + "client": [ + { + "value": "hiiragi283.ragium.integration.RagiumClientIntegration", + "adapter": "kotlin" + } + ], "fabric-datagen": [ { - "value": "hiiragi283.ragium.data.RagiumDataGenerator", + "value": "hiiragi283.ragium.integration.data.RIDataGenerator", "adapter": "kotlin" } ], "jade": [ { - "value": "hiiragi283.ragium.client.integration.jade.RagiumJadePlugin", + "value": "hiiragi283.ragium.integration.jade.RagiumJadePlugin", "adapter": "kotlin" } ], "rei_client": [ { - "value": "hiiragi283.ragium.client.integration.rei.RagiumREIClient", + "value": "hiiragi283.ragium.integration.rei.RagiumREIClient", "adapter": "kotlin" } ]