From caf2d248706e73d5ef55bacab7874d22753fbc0f Mon Sep 17 00:00:00 2001 From: Aarav Gupta Date: Sat, 23 Aug 2025 11:28:29 +0530 Subject: [PATCH 1/3] Setup 1.21.1 multi-loader with dependencies --- .gitattributes | 17 +- .github/FUNDING.yml | 1 - .github/workflows/PUBLISH.yml | 12 +- .gitignore | 13 +- README.md | 9 +- build.gradle | 214 +----------------- buildSrc/build.gradle | 3 + .../src/main/groovy/multiloader-common.gradle | 128 +++++++++++ .../src/main/groovy/multiloader-loader.gradle | 44 ++++ common/build.gradle | 43 ++++ .../createaddoncompatibility/CommonClass.java | 31 +++ .../createaddoncompatibility/Constants.java | 11 + .../mixin/MixinMinecraft.java | 19 ++ .../platform/Services.java | 30 +++ .../platform/services/IPlatformHelper.java | 36 +++ .../createaddoncompatibility.mixins.json | 16 ++ {src => common/src}/main/resources/logo.png | Bin common/src/main/resources/pack.mcmeta | 6 + fabric/build.gradle | 37 +++ .../CreateAddonCompatibility.java | 18 ++ .../mixin/MixinTitleScreen.java | 20 ++ .../platform/FabricPlatformHelper.java | 24 ++ ...tibility.platform.services.IPlatformHelper | 1 + ...reateaddoncompatibility.fabric.mixins.json | 16 ++ fabric/src/main/resources/fabric.mod.json | 36 +++ gradle.properties | 73 +++--- gradle/wrapper/gradle-wrapper.jar | Bin 62076 -> 0 bytes gradle/wrapper/gradle-wrapper.properties | 3 +- gradlew | 27 ++- gradlew.bat | 22 +- neoforge/build.gradle | 48 ++++ .../CreateAddonCompatibility.java | 13 ++ .../mixin/MixinTitleScreen.java | 20 ++ .../platform/NeoForgePlatformHelper.java | 26 +++ .../resources/META-INF/neoforge.mods.toml | 50 ++++ ...tibility.platform.services.IPlatformHelper | 1 + ...ateaddoncompatibility.neoforge.mixins.json | 14 ++ settings.gradle | 36 ++- .../copycats/tags/items/copycat_block.json | 8 - .../data/copycats/tags/items/copycat_box.json | 8 - .../copycats/tags/items/copycat_catwalk.json | 8 - .../copycats/tags/items/copycat_slab.json | 8 - .../copycats/tags/items/copycat_stairs.json | 13 -- .../tags/items/six_way_gearbox.json | 12 - .../data/forge/tags/fluids/crude_oil.json | 20 -- .../forge/tags/fluids/liquid_plastic.json | 20 -- .../data/forge/tags/fluids/lubricant.json | 12 - .../data/forge/tags/items/ingots/plastic.json | 8 - .../CreateAddonCompatibility.java | 27 --- .../data/datagen/DataGenerators.java | 28 --- .../data/datagen/ModBlockTagGenerator.java | 22 -- .../data/datagen/ModFluidTagGenerator.java | 39 ---- .../data/datagen/ModItemTagGenerator.java | 52 ----- .../data/tags/CopycatsTags.java | 20 -- .../tags/CreateAddonCompatibilityTags.java | 18 -- .../data/tags/ForgeTags.java | 30 --- .../MixinBlastFurnaceOutputBlockEntity.java | 77 ------- .../mixin/MixinUnifyConfig.java | 62 ----- .../registry/ModDatapacks.java | 37 --- src/main/resources/META-INF/mods.toml | 152 ------------- .../createaddoncompatibility/lang/en_us.json | 4 - .../ad_astra-cryo_fuel.json | 19 -- .../ad_astra-fuel.json | 19 -- .../createaddition-bioethanol.json | 19 -- .../garnished-peanut_oil.json | 19 -- .../railways_liquid_fuel/compat-diesel.json | 6 - .../railways_liquid_fuel/compat-ethanol.json | 6 - .../railways_liquid_fuel/compat-gasoline.json | 6 - .../railways_liquid_fuel/compat-plantoil.json | 6 - .../compat-reinforced_pressure_tube.json | 30 --- .../tfmg/distillation/compat-crude_oil.json | 38 ---- .../compat-crude_oil_no_naptha.json | 34 --- .../compat-pneumaticcraft-turbine_engine.json | 113 --------- .../data/ad_astra/tags/fluids/fuel.json | 13 -- .../pack.mcmeta | 8 - .../mixins.createaddoncompatibility.json | 16 -- src/main/resources/pack.mcmeta | 8 - 77 files changed, 825 insertions(+), 1338 deletions(-) delete mode 100644 .github/FUNDING.yml create mode 100644 buildSrc/build.gradle create mode 100644 buildSrc/src/main/groovy/multiloader-common.gradle create mode 100644 buildSrc/src/main/groovy/multiloader-loader.gradle create mode 100644 common/build.gradle create mode 100644 common/src/main/java/dev/amronos/createaddoncompatibility/CommonClass.java create mode 100644 common/src/main/java/dev/amronos/createaddoncompatibility/Constants.java create mode 100644 common/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinMinecraft.java create mode 100644 common/src/main/java/dev/amronos/createaddoncompatibility/platform/Services.java create mode 100644 common/src/main/java/dev/amronos/createaddoncompatibility/platform/services/IPlatformHelper.java create mode 100644 common/src/main/resources/createaddoncompatibility.mixins.json rename {src => common/src}/main/resources/logo.png (100%) create mode 100644 common/src/main/resources/pack.mcmeta create mode 100644 fabric/build.gradle create mode 100644 fabric/src/main/java/dev/amronos/createaddoncompatibility/CreateAddonCompatibility.java create mode 100644 fabric/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinTitleScreen.java create mode 100644 fabric/src/main/java/dev/amronos/createaddoncompatibility/platform/FabricPlatformHelper.java create mode 100644 fabric/src/main/resources/META-INF/services/dev.amronos.createaddoncompatibility.platform.services.IPlatformHelper create mode 100644 fabric/src/main/resources/createaddoncompatibility.fabric.mixins.json create mode 100644 fabric/src/main/resources/fabric.mod.json delete mode 100644 gradle/wrapper/gradle-wrapper.jar mode change 100644 => 100755 gradlew create mode 100644 neoforge/build.gradle create mode 100644 neoforge/src/main/java/dev/amronos/createaddoncompatibility/CreateAddonCompatibility.java create mode 100644 neoforge/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinTitleScreen.java create mode 100644 neoforge/src/main/java/dev/amronos/createaddoncompatibility/platform/NeoForgePlatformHelper.java create mode 100644 neoforge/src/main/resources/META-INF/neoforge.mods.toml create mode 100644 neoforge/src/main/resources/META-INF/services/dev.amronos.createaddoncompatibility.platform.services.IPlatformHelper create mode 100644 neoforge/src/main/resources/createaddoncompatibility.neoforge.mixins.json delete mode 100644 src/generated/resources/data/copycats/tags/items/copycat_block.json delete mode 100644 src/generated/resources/data/copycats/tags/items/copycat_box.json delete mode 100644 src/generated/resources/data/copycats/tags/items/copycat_catwalk.json delete mode 100644 src/generated/resources/data/copycats/tags/items/copycat_slab.json delete mode 100644 src/generated/resources/data/copycats/tags/items/copycat_stairs.json delete mode 100644 src/generated/resources/data/createaddoncompatibility/tags/items/six_way_gearbox.json delete mode 100644 src/generated/resources/data/forge/tags/fluids/crude_oil.json delete mode 100644 src/generated/resources/data/forge/tags/fluids/liquid_plastic.json delete mode 100644 src/generated/resources/data/forge/tags/fluids/lubricant.json delete mode 100644 src/generated/resources/data/forge/tags/items/ingots/plastic.json delete mode 100644 src/main/java/com/amronos/createaddoncompatibility/CreateAddonCompatibility.java delete mode 100644 src/main/java/com/amronos/createaddoncompatibility/data/datagen/DataGenerators.java delete mode 100644 src/main/java/com/amronos/createaddoncompatibility/data/datagen/ModBlockTagGenerator.java delete mode 100644 src/main/java/com/amronos/createaddoncompatibility/data/datagen/ModFluidTagGenerator.java delete mode 100644 src/main/java/com/amronos/createaddoncompatibility/data/datagen/ModItemTagGenerator.java delete mode 100644 src/main/java/com/amronos/createaddoncompatibility/data/tags/CopycatsTags.java delete mode 100644 src/main/java/com/amronos/createaddoncompatibility/data/tags/CreateAddonCompatibilityTags.java delete mode 100644 src/main/java/com/amronos/createaddoncompatibility/data/tags/ForgeTags.java delete mode 100644 src/main/java/com/amronos/createaddoncompatibility/mixin/MixinBlastFurnaceOutputBlockEntity.java delete mode 100644 src/main/java/com/amronos/createaddoncompatibility/mixin/MixinUnifyConfig.java delete mode 100644 src/main/java/com/amronos/createaddoncompatibility/registry/ModDatapacks.java delete mode 100644 src/main/resources/META-INF/mods.toml delete mode 100644 src/main/resources/assets/createaddoncompatibility/lang/en_us.json delete mode 100644 src/main/resources/data/createaddoncompatibility/diesel_engine_fuel_type/ad_astra-cryo_fuel.json delete mode 100644 src/main/resources/data/createaddoncompatibility/diesel_engine_fuel_type/ad_astra-fuel.json delete mode 100644 src/main/resources/data/createaddoncompatibility/diesel_engine_fuel_type/createaddition-bioethanol.json delete mode 100644 src/main/resources/data/createaddoncompatibility/diesel_engine_fuel_type/garnished-peanut_oil.json delete mode 100644 src/main/resources/data/createaddoncompatibility/railways/railways_liquid_fuel/compat-diesel.json delete mode 100644 src/main/resources/data/createaddoncompatibility/railways/railways_liquid_fuel/compat-ethanol.json delete mode 100644 src/main/resources/data/createaddoncompatibility/railways/railways_liquid_fuel/compat-gasoline.json delete mode 100644 src/main/resources/data/createaddoncompatibility/railways/railways_liquid_fuel/compat-plantoil.json delete mode 100644 src/main/resources/data/createaddoncompatibility/recipes/pneumaticcraft/thermo_plant/compat-reinforced_pressure_tube.json delete mode 100644 src/main/resources/data/createaddoncompatibility/recipes/tfmg/distillation/compat-crude_oil.json delete mode 100644 src/main/resources/data/createaddoncompatibility/recipes/tfmg/distillation/compat-crude_oil_no_naptha.json delete mode 100644 src/main/resources/data/createaddoncompatibility/recipes/tfmg/sequenced_assembly/compat-pneumaticcraft-turbine_engine.json delete mode 100644 src/main/resources/datapacks/rockets_use_adastra_fuels_only/data/ad_astra/tags/fluids/fuel.json delete mode 100644 src/main/resources/datapacks/rockets_use_adastra_fuels_only/pack.mcmeta delete mode 100644 src/main/resources/mixins.createaddoncompatibility.json delete mode 100644 src/main/resources/pack.mcmeta diff --git a/.gitattributes b/.gitattributes index dfe0770..20fc528 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,15 @@ -# Auto detect text files and perform LF normalization -* text=auto +* text eol=lf +*.bat text eol=crlf +*.patch text eol=lf +*.java text eol=lf +*.gradle text eol=crlf +*.png binary +*.gif binary +*.exe binary +*.dll binary +*.jar binary +*.lzma binary +*.zip binary +*.pyd binary +*.cfg text eol=lf +*.jks binary \ No newline at end of file diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 5f67b25..0000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1 +0,0 @@ -ko_fi: amronos \ No newline at end of file diff --git a/.github/workflows/PUBLISH.yml b/.github/workflows/PUBLISH.yml index 97c27f1..7594f15 100644 --- a/.github/workflows/PUBLISH.yml +++ b/.github/workflows/PUBLISH.yml @@ -1,10 +1,10 @@ name: Publish on GitHub, Modrinth, CurseForge -on: [ workflow_dispatch ] +on: [workflow_dispatch] env: - MINECRAFT_VERSION: 1.20.1 - JAVA_VERSION: 17 + MINECRAFT_VERSION: 1.21.1 + JAVA_VERSION: 21 VERSION: 0.2.4 VERSION_TYPE: release PUBLISH_GITHUB_TOKEN: ${{ secrets.PUBLISH_GITHUB_TOKEN }} @@ -55,15 +55,13 @@ jobs: curseforge-id: 1000148 curseforge-token: "${{env.PUBLISH_CURSEFORGE_TOKEN}}" - name: "Create: Addon Compatibility - v${{env.VERSION}} - ${{env.MINECRAFT_VERSION}} - (neo)forge" + name: "Create: Addon Compatibility - v${{env.VERSION}} - ${{env.MINECRAFT_VERSION}} - neoforge" version: "${{env.VERSION}}" version-type: "${{env.VERSION_TYPE}}" changelog-file: LATEST_CHANGELOG.md game-version-filter: releases - loaders: | - forge - neoforge + loaders: neoforge files: "build/libs/createaddoncompatibility-${{env.VERSION}}.jar" diff --git a/.gitignore b/.gitignore index af7dd5e..461017f 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,8 @@ out *.ipr *.iws *.iml -.idea +.idea/* +!.idea/scopes # gradle build @@ -20,12 +21,4 @@ build # other eclipse run -run-data -.cache -*.vscode -*.zip -*.mrpack -*.exe - -# Files from Forge MDK -forge*changelog.txt +runs diff --git a/README.md b/README.md index 31ecf4a..60fee0a 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ Create: Connected takes priority, recipes have been unified, Create Utilities's Mods: [Immersive Engineering](https://modrinth.com/mod/immersiveengineering), [TFMG](https://modrinth.com/mod/create-tfmg)
Coal Coke Dust from both mods works in both mods' processes and recipes. +
@@ -64,23 +65,27 @@ Kerosene, Molten/Liquid Plastic, Lubricant/Lubrication Oil from both mods works

## Installation -The mod is currently only available for 1.20.1 (neo)forge. Fabric/Quilt versions and >=1.21.1 versions will come soon. A port to 1.19.2 is not planned.
+ +The mod is currently only available for 1.20.1 and 1.21.1 (neo)forge. Fabric/Quilt versions will come soon.
[Almost Unified](https://modrinth.com/mod/almost-unified) is required to be installed.


## Compatibility Configuration + To change which mod has the priority in compatibility, modify the `modPriorities` in `config/almostunified/unify.json`, for more info look at [this](https://github.com/AlmostReliable/almostunified/wiki/Unification-Config).

There are datapacks present in the mod which allow you to change certain things about compatibility between different mods.
-They can be enabled during world creation or by using the ``/datapack enable`` command. +They can be enabled during world creation or by using the `/datapack enable` command.

## Suggestions / More Compatibility Features + I do have more compatibility features planned, but if you have any ideas feel free to create an issue on GitHub or tell me in the Discord server.

## Credits + Thanks to the creators of the various mods for which compatibility has been added in this mod.
Thanks to the AlmostReliable team for making Almost Unified, without which this mod would have been very difficult to make.
Finally, thanks to the people on the Minecraft Mod Development discord for helping me out with some features in the mod. diff --git a/build.gradle b/build.gradle index 499db5f..9a70037 100644 --- a/build.gradle +++ b/build.gradle @@ -1,212 +1,6 @@ plugins { - id 'eclipse' - id 'idea' - id 'maven-publish' - id 'net.minecraftforge.gradle' version '[6.0,6.2)' - id 'org.spongepowered.mixin' version '0.7.+' - id 'org.parchmentmc.librarian.forgegradle' version '1.+' -} - - -version = mod_version -group = mod_group_id - -base { - archivesName = mod_id -} - -java.toolchain.languageVersion = JavaLanguageVersion.of(17) - -println "Java: ${System.getProperty 'java.version'}, JVM: ${System.getProperty 'java.vm.version'} (${System.getProperty 'java.vendor'}), Arch: ${System.getProperty 'os.arch'}" -minecraft { - mappings channel: mapping_channel, version: mapping_version - - copyIdeResources = true - - // generateRunFolders = true - - // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') - - - runs { - configureEach { - workingDirectory project.file('run') - - property 'forge.logging.markers', 'REGISTRIES' - property 'forge.logging.console.level', 'debug' - - - mods { - "${mod_id}" { - source sourceSets.main - } - } - } - - client { - property 'forge.enabledGameTestNamespaces', mod_id - property 'mixin.env.remapRefMap', 'true' - property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg" - } - - server { - property 'forge.enabledGameTestNamespaces', mod_id - property 'mixin.env.remapRefMap', 'true' - property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg" - } - - // This run config launches GameTestServer and runs all registered gametests, then exits. - // By default, the server will crash when no gametests are provided. - // The gametest system is also enabled by default for other run configs under the /test command. - gameTestServer { - property 'forge.enabledGameTestNamespaces', mod_id - } - - data { - // example of overriding the workingDirectory set in configureEach above - workingDirectory project.file('run-data') - - // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. - args '--mod', mod_id, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/') - } - } -} - -sourceSets.main.resources { srcDir 'src/generated/resources' } - -repositories { - maven { - name = 'Create Mod Maven' - url = 'https://maven.createmod.net' - } - maven { - name = 'Fuzss Maven' - url = 'https://raw.githubusercontent.com/Fuzss/modresources/main/maven/' - } - maven { - name = 'tterrag maven' - url = 'https://maven.tterrag.com/' - } - maven { - // location of the maven that hosts JEI files since January 2023 - name = "Jared's maven" - url = "https://maven.blamejared.com/" - } - maven { - // location of a maven mirror for JEI files, as a fallback - name = "ModMaven" - url = "https://modmaven.dev" - } - maven { - name = "Modrinth Maven" - url = "https://api.modrinth.com/maven" - } - maven { - name = "Curseforge Maven" - url = "https://cursemaven.com" - } -} - -dependencies { - minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" - - annotationProcessor 'org.spongepowered:mixin:0.8.5:processor' - - implementation(fg.deobf("com.simibubi.create:create-${minecraft_version}:${create_version}:slim") { transitive = false }) - implementation(fg.deobf("net.createmod.ponder:Ponder-Forge-${minecraft_version}:${ponder_version}")) - compileOnly(fg.deobf("dev.engine-room.flywheel:flywheel-forge-api-${minecraft_version}:${flywheel_version}")) - runtimeOnly(fg.deobf("dev.engine-room.flywheel:flywheel-forge-${minecraft_version}:${flywheel_version}")) - implementation(fg.deobf("com.tterrag.registrate:Registrate:${registrate_version}")) - - compileOnly(annotationProcessor("io.github.llamalad7:mixinextras-common:0.4.1")) - implementation("io.github.llamalad7:mixinextras-forge:0.4.1") - - // compile against the JEI API but do not include it at runtime - compileOnly(fg.deobf("mezz.jei:jei-${minecraft_version}-common-api:${jei_version}")) - compileOnly(fg.deobf("mezz.jei:jei-${minecraft_version}-forge-api:${jei_version}")) - // at runtime, use the full JEI jar for Forge - runtimeOnly(fg.deobf("mezz.jei:jei-${minecraft_version}-forge:${jei_version}")) - - implementation fg.deobf("com.almostreliable.mods:almostunified-forge:${almostunified_version}") - - implementation fg.deobf("maven.modrinth:create-diesel-generators:${createdieselgenerators_version}") - implementation fg.deobf("curse.maven:create-industry-693815:6255138") -} - - - -// This block of code expands all declared replace properties in the specified resource targets. -// A missing property will result in an error. Properties are expanded using ${} Groovy notation. -// When "copyIdeResources" is enabled, this will also run before the game launches in IDE environments. -// See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html -tasks.named('processResources', ProcessResources).configure { - var replaceProperties = [ - minecraft_version: minecraft_version, - minecraft_version_range: minecraft_version_range, - forge_version: forge_version, - forge_version_range: forge_version_range, - loader_version_range: loader_version_range, - mod_id: mod_id, - mod_name: mod_name, - mod_license: mod_license, - mod_version: mod_version, - mod_authors: mod_authors, - mod_description: mod_description, - create_version: create_version, - create_version_range: create_version_range, - jei_version: jei_version, - almostunified_version: almostunified_version, - createdieselgenerators_version: createdieselgenerators_version, - tfmg_version: tfmg_version - ] - inputs.properties replaceProperties - - filesMatching(['META-INF/mods.toml', 'pack.mcmeta']) { - expand replaceProperties + [project: project] - } -} - - -jar { - manifest { - attributes([ - "Specification-Title" : mod_name, - "Specification-Vendor" : mod_authors, - "Specification-Version" : "1", // We are version 1 of ourselves - "Implementation-Title" : project.name, - "Implementation-Version" : project.jar.archiveVersion, - "Implementation-Vendor" : mod_authors, - "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"), - "MixinConfigs" : "mixins.${mod_id}.json" - ]) - } - -} - -// However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing: -// tasks.named('publish').configure { -// dependsOn 'reobfJar' -// } - -// Example configuration to allow publishing using the maven-publish plugin -publishing { - publications { - register('mavenJava', MavenPublication) { - artifact jar - } - } - repositories { - maven { - url "file://${project.projectDir}/mcmodsrepo" - } - } -} - -tasks.withType(JavaCompile).configureEach { - options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation -} - -mixin { - add sourceSets.main, 'createaddoncompatibility.refmap.json' - config 'mixins.createaddoncompatibility.json' + // see https://fabricmc.net/develop/ for new versions + // id 'fabric-loom' version '1.11-SNAPSHOT' apply false + // see https://projects.neoforged.net/neoforged/moddevgradle for new versions + id 'net.neoforged.moddev' version '2.0.107' apply false } diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle new file mode 100644 index 0000000..6784052 --- /dev/null +++ b/buildSrc/build.gradle @@ -0,0 +1,3 @@ +plugins { + id 'groovy-gradle-plugin' +} diff --git a/buildSrc/src/main/groovy/multiloader-common.gradle b/buildSrc/src/main/groovy/multiloader-common.gradle new file mode 100644 index 0000000..22afc29 --- /dev/null +++ b/buildSrc/src/main/groovy/multiloader-common.gradle @@ -0,0 +1,128 @@ +plugins { + id 'java-library' + id 'maven-publish' +} + +base { + archivesName = "${mod_id}-${project.name}-${minecraft_version}" +} + +java { + toolchain.languageVersion = JavaLanguageVersion.of(java_version) + withSourcesJar() + withJavadocJar() +} + +repositories { + mavenCentral() + // https://docs.gradle.org/current/userguide/declaring_repositories.html#declaring_content_exclusively_found_in_one_repository + exclusiveContent { + forRepository { + maven { + name = 'Sponge' + url = 'https://repo.spongepowered.org/repository/maven-public' + } + } + filter { includeGroupAndSubgroups('org.spongepowered') } + } + exclusiveContent { + forRepositories( + maven { + name = 'ParchmentMC' + url = 'https://maven.parchmentmc.org/' + }, + maven { + name = "NeoForge" + url = 'https://maven.neoforged.net/releases' + } + ) + filter { includeGroup('org.parchmentmc.data') } + } + maven { + name = 'BlameJared' + url = 'https://maven.blamejared.com' + } + maven { url = "https://maven.createmod.net" } // Create, Ponder, Flywheel + maven { url = "https://maven.ithundxr.dev/snapshots" } // Registrate +} + +// Declare capabilities on the outgoing configurations. +// Read more about capabilities here: https://docs.gradle.org/current/userguide/component_capabilities.html#sec:declaring-additional-capabilities-for-a-local-component +['apiElements', 'runtimeElements', 'sourcesElements', 'javadocElements'].each { variant -> + configurations."$variant".outgoing { + capability("$group:${base.archivesName.get()}:$version") + capability("$group:$mod_id-${project.name}-${minecraft_version}:$version") + capability("$group:$mod_id:$version") + } + publishing.publications.configureEach { + suppressPomMetadataWarningsFor(variant) + } +} + +sourcesJar { + from(rootProject.file('LICENSE')) { + rename { "${it}_${mod_name}" } + } +} + +jar { + from(rootProject.file('LICENSE')) { + rename { "${it}_${mod_name}" } + } + + manifest { + attributes([ + 'Specification-Title' : mod_name, + 'Specification-Vendor' : mod_author, + 'Specification-Version' : project.jar.archiveVersion, + 'Implementation-Title' : project.name, + 'Implementation-Version': project.jar.archiveVersion, + 'Implementation-Vendor' : mod_author, + 'Built-On-Minecraft' : minecraft_version + ]) + } +} + +processResources { + var expandProps = [ + 'version' : version, + 'group' : project.group, //Else we target the task's group. + 'minecraft_version' : minecraft_version, + 'minecraft_version_range' : minecraft_version_range, + 'fabric_version' : fabric_version, + 'fabric_loader_version' : fabric_loader_version, + 'mod_name' : mod_name, + 'mod_author' : mod_author, + 'mod_id' : mod_id, + 'license' : license, + 'description' : project.description, + 'neoforge_version' : neoforge_version, + 'neoforge_loader_version_range': neoforge_loader_version_range, + 'credits' : credits, + 'java_version' : java_version, + 'create_version' : create_version, + 'ponder_version' : ponder_version, + 'flywheel_version' : flywheel_version, + 'registrate_version' : registrate_version, + 'almostunified_version' : almostunified_version, + ] + + filesMatching(['pack.mcmeta', 'fabric.mod.json', 'META-INF/mods.toml', 'META-INF/neoforge.mods.toml', '*.mixins.json']) { + expand expandProps + } + inputs.properties(expandProps) +} + +publishing { + publications { + register('mavenJava', MavenPublication) { + artifactId base.archivesName.get() + from components.java + } + } + repositories { + maven { + url System.getenv('local_maven_url') + } + } +} diff --git a/buildSrc/src/main/groovy/multiloader-loader.gradle b/buildSrc/src/main/groovy/multiloader-loader.gradle new file mode 100644 index 0000000..92e2325 --- /dev/null +++ b/buildSrc/src/main/groovy/multiloader-loader.gradle @@ -0,0 +1,44 @@ +plugins { + id 'multiloader-common' +} + +configurations { + commonJava{ + canBeResolved = true + } + commonResources{ + canBeResolved = true + } +} + +dependencies { + compileOnly(project(':common')) { + capabilities { + requireCapability "$group:$mod_id" + } + } + commonJava project(path: ':common', configuration: 'commonJava') + commonResources project(path: ':common', configuration: 'commonResources') +} + +tasks.named('compileJava', JavaCompile) { + dependsOn(configurations.commonJava) + source(configurations.commonJava) +} + +processResources { + dependsOn(configurations.commonResources) + from(configurations.commonResources) +} + +tasks.named('javadoc', Javadoc).configure { + dependsOn(configurations.commonJava) + source(configurations.commonJava) +} + +tasks.named('sourcesJar', Jar) { + dependsOn(configurations.commonJava) + from(configurations.commonJava) + dependsOn(configurations.commonResources) + from(configurations.commonResources) +} diff --git a/common/build.gradle b/common/build.gradle new file mode 100644 index 0000000..d4ca1d4 --- /dev/null +++ b/common/build.gradle @@ -0,0 +1,43 @@ +plugins { + id 'multiloader-common' + id 'net.neoforged.moddev' +} + +neoForge { + neoFormVersion = neo_form_version + // Automatically enable AccessTransformers if the file exists + def at = file('src/main/resources/META-INF/accesstransformer.cfg') + if (at.exists()) { + accessTransformers.from(at.absolutePath) + } + parchment { + minecraftVersion = parchment_minecraft + mappingsVersion = parchment_version + } +} + +dependencies { + compileOnly group: 'org.spongepowered', name: 'mixin', version: '0.8.5' + // fabric and neoforge both bundle mixinextras, so it is safe to use it in common + compileOnly group: 'io.github.llamalad7', name: 'mixinextras-common', version: '0.3.5' + annotationProcessor group: 'io.github.llamalad7', name: 'mixinextras-common', version: '0.3.5' + // Dependencies + compileOnly "com.almostreliable.mods:almostunified-common:${almostunified_version}" +} + +configurations { + commonJava { + canBeResolved = false + canBeConsumed = true + } + commonResources { + canBeResolved = false + canBeConsumed = true + } +} + +artifacts { + commonJava sourceSets.main.java.sourceDirectories.singleFile + commonResources sourceSets.main.resources.sourceDirectories.singleFile +} + diff --git a/common/src/main/java/dev/amronos/createaddoncompatibility/CommonClass.java b/common/src/main/java/dev/amronos/createaddoncompatibility/CommonClass.java new file mode 100644 index 0000000..5b9a29e --- /dev/null +++ b/common/src/main/java/dev/amronos/createaddoncompatibility/CommonClass.java @@ -0,0 +1,31 @@ +package dev.amronos.createaddoncompatibility; + +import dev.amronos.createaddoncompatibility.platform.Services; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.world.item.Items; + +// This class is part of the common project meaning it is shared between all supported loaders. Code written here can only +// import and access the vanilla codebase, libraries used by vanilla, and optionally third party libraries that provide +// common compatible binaries. This means common code can not directly use loader specific concepts such as Forge events +// however it will be compatible with all supported mod loaders. +public class CommonClass { + + // The loader specific projects are able to import and use any code from the common project. This allows you to + // write the majority of your code here and load it from your loader specific projects. This example has some + // code that gets invoked by the entry point of the loader specific projects. + public static void init() { + + Constants.LOG.info("Hello from Common init on {}! we are currently in a {} environment!", Services.PLATFORM.getPlatformName(), Services.PLATFORM.getEnvironmentName()); + Constants.LOG.info("The ID for diamonds is {}", BuiltInRegistries.ITEM.getKey(Items.DIAMOND)); + + // It is common for all supported loaders to provide a similar feature that can not be used directly in the + // common code. A popular way to get around this is using Java's built-in service loader feature to create + // your own abstraction layer. You can learn more about this in our provided services class. In this example + // we have an interface in the common code and use a loader specific implementation to delegate our call to + // the platform specific approach. + if (Services.PLATFORM.isModLoaded("examplemod")) { + + Constants.LOG.info("Hello to examplemod"); + } + } +} \ No newline at end of file diff --git a/common/src/main/java/dev/amronos/createaddoncompatibility/Constants.java b/common/src/main/java/dev/amronos/createaddoncompatibility/Constants.java new file mode 100644 index 0000000..03c7044 --- /dev/null +++ b/common/src/main/java/dev/amronos/createaddoncompatibility/Constants.java @@ -0,0 +1,11 @@ +package dev.amronos.createaddoncompatibility; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Constants { + + public static final String MOD_ID = "createaddoncompatibility"; + public static final String MOD_NAME = "Create: Addon Compatiblity"; + public static final Logger LOG = LoggerFactory.getLogger(MOD_NAME); +} \ No newline at end of file diff --git a/common/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinMinecraft.java b/common/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinMinecraft.java new file mode 100644 index 0000000..24cbab0 --- /dev/null +++ b/common/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinMinecraft.java @@ -0,0 +1,19 @@ +package dev.amronos.createaddoncompatibility.mixin; + +import dev.amronos.createaddoncompatibility.Constants; +import net.minecraft.client.Minecraft; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Minecraft.class) +public class MixinMinecraft { + + @Inject(at = @At("TAIL"), method = "") + private void init(CallbackInfo info) { + + Constants.LOG.info("This line is printed by an example mod common mixin!"); + Constants.LOG.info("MC Version: {}", Minecraft.getInstance().getVersionType()); + } +} \ No newline at end of file diff --git a/common/src/main/java/dev/amronos/createaddoncompatibility/platform/Services.java b/common/src/main/java/dev/amronos/createaddoncompatibility/platform/Services.java new file mode 100644 index 0000000..90b4a22 --- /dev/null +++ b/common/src/main/java/dev/amronos/createaddoncompatibility/platform/Services.java @@ -0,0 +1,30 @@ +package dev.amronos.createaddoncompatibility.platform; + +import dev.amronos.createaddoncompatibility.Constants; +import dev.amronos.createaddoncompatibility.platform.services.IPlatformHelper; + +import java.util.ServiceLoader; + +// Service loaders are a built-in Java feature that allow us to locate implementations of an interface that vary from one +// environment to another. In the context of MultiLoader we use this feature to access a mock API in the common code that +// is swapped out for the platform specific implementation at runtime. +public class Services { + + // In this example we provide a platform helper which provides information about what platform the mod is running on. + // For example this can be used to check if the code is running on Forge vs Fabric, or to ask the modloader if another + // mod is loaded. + public static final IPlatformHelper PLATFORM = load(IPlatformHelper.class); + + // This code is used to load a service for the current environment. Your implementation of the service must be defined + // manually by including a text file in META-INF/services named with the fully qualified class name of the service. + // Inside the file you should write the fully qualified class name of the implementation to load for the platform. For + // example our file on Forge points to ForgePlatformHelper while Fabric points to FabricPlatformHelper. + public static T load(Class clazz) { + + final T loadedService = ServiceLoader.load(clazz) + .findFirst() + .orElseThrow(() -> new NullPointerException("Failed to load service for " + clazz.getName())); + Constants.LOG.debug("Loaded {} for service {}", loadedService, clazz); + return loadedService; + } +} \ No newline at end of file diff --git a/common/src/main/java/dev/amronos/createaddoncompatibility/platform/services/IPlatformHelper.java b/common/src/main/java/dev/amronos/createaddoncompatibility/platform/services/IPlatformHelper.java new file mode 100644 index 0000000..c6e8334 --- /dev/null +++ b/common/src/main/java/dev/amronos/createaddoncompatibility/platform/services/IPlatformHelper.java @@ -0,0 +1,36 @@ +package dev.amronos.createaddoncompatibility.platform.services; + +public interface IPlatformHelper { + + /** + * Gets the name of the current platform + * + * @return The name of the current platform. + */ + String getPlatformName(); + + /** + * Checks if a mod with the given id is loaded. + * + * @param modId The mod to check if it is loaded. + * @return True if the mod is loaded, false otherwise. + */ + boolean isModLoaded(String modId); + + /** + * Check if the game is currently in a development environment. + * + * @return True if in a development environment, false otherwise. + */ + boolean isDevelopmentEnvironment(); + + /** + * Gets the name of the environment type as a string. + * + * @return The name of the environment type. + */ + default String getEnvironmentName() { + + return isDevelopmentEnvironment() ? "development" : "production"; + } +} \ No newline at end of file diff --git a/common/src/main/resources/createaddoncompatibility.mixins.json b/common/src/main/resources/createaddoncompatibility.mixins.json new file mode 100644 index 0000000..623e2a3 --- /dev/null +++ b/common/src/main/resources/createaddoncompatibility.mixins.json @@ -0,0 +1,16 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "dev.amronos.createaddoncompatibility.mixin", + "refmap": "${mod_id}.refmap.json", + "compatibilityLevel": "JAVA_18", + "mixins": [], + "client": [ + "MixinMinecraft" + ], + "server": [], + "injectors": { + "defaultRequire": 1 + } +} + diff --git a/src/main/resources/logo.png b/common/src/main/resources/logo.png similarity index 100% rename from src/main/resources/logo.png rename to common/src/main/resources/logo.png diff --git a/common/src/main/resources/pack.mcmeta b/common/src/main/resources/pack.mcmeta new file mode 100644 index 0000000..52854ec --- /dev/null +++ b/common/src/main/resources/pack.mcmeta @@ -0,0 +1,6 @@ +{ + "pack": { + "description": "${mod_name}", + "pack_format": 8 + } +} \ No newline at end of file diff --git a/fabric/build.gradle b/fabric/build.gradle new file mode 100644 index 0000000..f82b365 --- /dev/null +++ b/fabric/build.gradle @@ -0,0 +1,37 @@ +plugins { + id 'multiloader-loader' + id 'fabric-loom' +} +dependencies { + minecraft "com.mojang:minecraft:${minecraft_version}" + mappings loom.layered { + officialMojangMappings() + parchment("org.parchmentmc.data:parchment-${parchment_minecraft}:${parchment_version}@zip") + } + modImplementation "net.fabricmc:fabric-loader:${fabric_loader_version}" + modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_version}" +} + +loom { + def aw = project(':common').file("src/main/resources/${mod_id}.accesswidener") + if (aw.exists()) { + accessWidenerPath.set(aw) + } + mixin { + defaultRefmapName.set("${mod_id}.refmap.json") + } + runs { + client { + client() + setConfigName('Fabric Client') + ideConfigGenerated(true) + runDir('runs/client') + } + server { + server() + setConfigName('Fabric Server') + ideConfigGenerated(true) + runDir('runs/server') + } + } +} \ No newline at end of file diff --git a/fabric/src/main/java/dev/amronos/createaddoncompatibility/CreateAddonCompatibility.java b/fabric/src/main/java/dev/amronos/createaddoncompatibility/CreateAddonCompatibility.java new file mode 100644 index 0000000..d1c3fb9 --- /dev/null +++ b/fabric/src/main/java/dev/amronos/createaddoncompatibility/CreateAddonCompatibility.java @@ -0,0 +1,18 @@ +package dev.amronos.createaddoncompatibility; + +import net.fabricmc.api.ModInitializer; + +public class CreateAddonCompatibility implements ModInitializer { + + @Override + public void onInitialize() { + + // This method is invoked by the Fabric mod loader when it is ready + // to load your mod. You can access Fabric and Common code in this + // project. + + // Use Fabric to bootstrap the Common mod. + Constants.LOG.info("Hello Fabric world!"); + CommonClass.init(); + } +} diff --git a/fabric/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinTitleScreen.java b/fabric/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinTitleScreen.java new file mode 100644 index 0000000..ca83143 --- /dev/null +++ b/fabric/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinTitleScreen.java @@ -0,0 +1,20 @@ +package dev.amronos.createaddoncompatibility.mixin; + +import dev.amronos.createaddoncompatibility.Constants; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.TitleScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(TitleScreen.class) +public class MixinTitleScreen { + + @Inject(at = @At("HEAD"), method = "init()V") + private void init(CallbackInfo info) { + + Constants.LOG.info("This line is printed by an example mod mixin from Fabric!"); + Constants.LOG.info("MC Version: {}", Minecraft.getInstance().getVersionType()); + } +} \ No newline at end of file diff --git a/fabric/src/main/java/dev/amronos/createaddoncompatibility/platform/FabricPlatformHelper.java b/fabric/src/main/java/dev/amronos/createaddoncompatibility/platform/FabricPlatformHelper.java new file mode 100644 index 0000000..1a3371f --- /dev/null +++ b/fabric/src/main/java/dev/amronos/createaddoncompatibility/platform/FabricPlatformHelper.java @@ -0,0 +1,24 @@ +package com.example.examplemod.platform; + +import com.example.examplemod.platform.services.IPlatformHelper; +import net.fabricmc.loader.api.FabricLoader; + +public class FabricPlatformHelper implements IPlatformHelper { + + @Override + public String getPlatformName() { + return "Fabric"; + } + + @Override + public boolean isModLoaded(String modId) { + + return FabricLoader.getInstance().isModLoaded(modId); + } + + @Override + public boolean isDevelopmentEnvironment() { + + return FabricLoader.getInstance().isDevelopmentEnvironment(); + } +} diff --git a/fabric/src/main/resources/META-INF/services/dev.amronos.createaddoncompatibility.platform.services.IPlatformHelper b/fabric/src/main/resources/META-INF/services/dev.amronos.createaddoncompatibility.platform.services.IPlatformHelper new file mode 100644 index 0000000..29d9205 --- /dev/null +++ b/fabric/src/main/resources/META-INF/services/dev.amronos.createaddoncompatibility.platform.services.IPlatformHelper @@ -0,0 +1 @@ +dev.amronos.createaddoncompatibility.platform.FabricPlatformHelper diff --git a/fabric/src/main/resources/createaddoncompatibility.fabric.mixins.json b/fabric/src/main/resources/createaddoncompatibility.fabric.mixins.json new file mode 100644 index 0000000..8c19947 --- /dev/null +++ b/fabric/src/main/resources/createaddoncompatibility.fabric.mixins.json @@ -0,0 +1,16 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "dev.amronos.createaddoncompatibility.mixin", + "refmap": "${mod_id}.refmap.json", + "compatibilityLevel": "JAVA_21", + "mixins": [], + "client": [ + "MixinTitleScreen" + ], + "server": [], + "injectors": { + "defaultRequire": 1 + } +} + diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..f80ea75 --- /dev/null +++ b/fabric/src/main/resources/fabric.mod.json @@ -0,0 +1,36 @@ +{ + "schemaVersion": 1, + "id": "${mod_id}", + "version": "${version}", + "name": "${mod_name}", + "description": "${description}", + "authors": [ + "${mod_author}" + ], + "contact": { + "homepage": "https://fabricmc.net/", + "sources": "https://github.com/FabricMC/fabric-example-mod" + }, + "license": "${license}", + "icon": "${mod_id}.png", + "environment": "*", + "entrypoints": { + "main": [ + "dev.amronos.createaddoncompatibility.CreateAddonCompatibility" + ] + }, + "mixins": [ + "${mod_id}.mixins.json", + "${mod_id}.fabric.mixins.json" + ], + "depends": { + "fabricloader": ">=${fabric_loader_version}", + "fabric-api": "*", + "minecraft": "${minecraft_version}", + "java": ">=${java_version}" + }, + "suggests": { + "another-mod": "*" + } +} + diff --git a/gradle.properties b/gradle.properties index 1b60634..75cbd7d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,37 +1,42 @@ -# Sets default memory used for gradle commands. Can be overridden by user or command line properties. -# This is required to provide enough memory for the Minecraft decompilation process. -org.gradle.jvmargs=-Xmx3G -org.gradle.daemon=false - - -minecraft_version=1.20.1 -minecraft_version_range=[1.20.1] -forge_version=47.1.47 -forge_version_range=[47,) -loader_version_range=[47,) - - -mapping_channel=parchment -mapping_version=2023.09.03-1.20.1 - +# Important Notes: +# Every field you add must be added to the root build.gradle expandProps map. -mod_id=createaddoncompatibility -mod_group_id=com.amronos.createaddoncompatibility - -mod_version=0.2.4 +# Project +version=0.2.4 +group=dev.amronos.createaddoncompatibility +java_version=21 -mod_license=GNU Lesser General Public License v3.0 +# Common +minecraft_version=1.21.1 mod_name=Create: Addon Compatibility -mod_authors=Amronos -mod_description=Adds compatibility for and between different create addons. - - -create_version = 6.0.3-71 -create_version_range = [6.0.3,) -ponder_version = 1.0.51 -flywheel_version = 1.0.1 -registrate_version = MC1.20-1.3.3 -jei_version=15.20.0.106 -almostunified_version=1.20.1-0.9.3 -createdieselgenerators_version = 1.20.1-1.3.1 -tfmg_version = 0.9.3-1.20.1 +mod_author=Amronos +mod_id=createaddoncompatibility +license=GNU Lesser General Public License v3.0 +credits= +description=Adds compatibility for and between different create addons. +minecraft_version_range=[1.21.1] +## This is the version of minecraft that the 'common' project uses, you can find a list of all versions here +## https://projects.neoforged.net/neoforged/neoform +neo_form_version=1.21.1-20240808.144430 +# The version of ParchmentMC that is used, see https://parchmentmc.org/docs/getting-started#choose-a-version for new versions +parchment_minecraft=1.21.1 +parchment_version=2024.11.17 + +# Fabric +fabric_version=0.116.5+1.21.1 +fabric_loader_version=0.17.2 + +# NeoForge +neoforge_version=21.1.203 +neoforge_loader_version_range=[4,) + +# Dependencies +create_version=6.0.6-98 +ponder_version=1.0.59 +flywheel_version=1.0.4 +registrate_version=MC1.21-1.3.0+62 +almostunified_version=1.21.1-1.3.0 + +# Gradle +org.gradle.jvmargs=-Xmx3G +org.gradle.daemon=false diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index c1962a79e29d3e0ab67b14947c167a862655af9b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62076 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 20db9ad..ff23a68 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 index aeb74cb..f5feea6 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -83,7 +85,9 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -130,10 +134,13 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. @@ -141,7 +148,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -149,7 +156,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -198,11 +205,11 @@ fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/gradlew.bat b/gradlew.bat index 93e3f59..9d21a21 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -43,11 +45,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail diff --git a/neoforge/build.gradle b/neoforge/build.gradle new file mode 100644 index 0000000..ac78c9f --- /dev/null +++ b/neoforge/build.gradle @@ -0,0 +1,48 @@ +plugins { + id 'multiloader-loader' + id 'net.neoforged.moddev' +} + +neoForge { + version = neoforge_version + // Automatically enable neoforge AccessTransformers if the file exists + def at = project(':common').file('src/main/resources/META-INF/accesstransformer.cfg') + if (at.exists()) { + accessTransformers.from(at.absolutePath) + } + parchment { + minecraftVersion = parchment_minecraft + mappingsVersion = parchment_version + } + runs { + configureEach { + systemProperty('neoforge.enabledGameTestNamespaces', mod_id) + ideName = "NeoForge ${it.name.capitalize()} (${project.path})" // Unify the run config names with fabric + } + client { + client() + } + data { + data() + } + server { + server() + } + } + mods { + "${mod_id}" { + sourceSet sourceSets.main + } + } +} + +dependencies { + implementation("com.simibubi.create:create-${minecraft_version}:${create_version}:slim") { transitive = false } + implementation("net.createmod.ponder:Ponder-NeoForge-${minecraft_version}:${ponder_version}") + compileOnly("dev.engine-room.flywheel:flywheel-neoforge-api-${minecraft_version}:${flywheel_version}") + runtimeOnly("dev.engine-room.flywheel:flywheel-neoforge-${minecraft_version}:${flywheel_version}") + implementation("com.tterrag.registrate:Registrate:${registrate_version}") + compileOnly("com.almostreliable.mods:almostunified-neoforge:${almostunified_version}") +} + +sourceSets.main.resources { srcDir 'src/generated/resources' } \ No newline at end of file diff --git a/neoforge/src/main/java/dev/amronos/createaddoncompatibility/CreateAddonCompatibility.java b/neoforge/src/main/java/dev/amronos/createaddoncompatibility/CreateAddonCompatibility.java new file mode 100644 index 0000000..2838463 --- /dev/null +++ b/neoforge/src/main/java/dev/amronos/createaddoncompatibility/CreateAddonCompatibility.java @@ -0,0 +1,13 @@ +package dev.amronos.createaddoncompatibility; + + +import net.neoforged.bus.api.IEventBus; +import net.neoforged.fml.common.Mod; + +@Mod(Constants.MOD_ID) +public class CreateAddonCompatibility { + + public CreateAddonCompatibility(IEventBus eventBus) { + CommonClass.init(); + } +} diff --git a/neoforge/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinTitleScreen.java b/neoforge/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinTitleScreen.java new file mode 100644 index 0000000..3a439f5 --- /dev/null +++ b/neoforge/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinTitleScreen.java @@ -0,0 +1,20 @@ +package dev.amronos.createaddoncompatibility.mixin; + +import dev.amronos.createaddoncompatibility.Constants; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.TitleScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(TitleScreen.class) +public class MixinTitleScreen { + + @Inject(at = @At("HEAD"), method = "init()V") + private void init(CallbackInfo info) { + + Constants.LOG.info("This line is printed by an example mod mixin from NeoForge!"); + Constants.LOG.info("MC Version: {}", Minecraft.getInstance().getVersionType()); + } +} diff --git a/neoforge/src/main/java/dev/amronos/createaddoncompatibility/platform/NeoForgePlatformHelper.java b/neoforge/src/main/java/dev/amronos/createaddoncompatibility/platform/NeoForgePlatformHelper.java new file mode 100644 index 0000000..d85fd11 --- /dev/null +++ b/neoforge/src/main/java/dev/amronos/createaddoncompatibility/platform/NeoForgePlatformHelper.java @@ -0,0 +1,26 @@ +package dev.amronos.createaddoncompatibility.platform; + +import dev.amronos.createaddoncompatibility.platform.services.IPlatformHelper; +import net.neoforged.fml.ModList; +import net.neoforged.fml.loading.FMLLoader; + +public class NeoForgePlatformHelper implements IPlatformHelper { + + @Override + public String getPlatformName() { + + return "NeoForge"; + } + + @Override + public boolean isModLoaded(String modId) { + + return ModList.get().isLoaded(modId); + } + + @Override + public boolean isDevelopmentEnvironment() { + + return !FMLLoader.isProduction(); + } +} diff --git a/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/neoforge/src/main/resources/META-INF/neoforge.mods.toml new file mode 100644 index 0000000..3a27deb --- /dev/null +++ b/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -0,0 +1,50 @@ +modLoader = "javafml" +loaderVersion = "${neoforge_loader_version_range}" +license = "${license}" +issueTrackerURL="https://github.com/Amronos/${mod_id}/issues/" + +[[mods]] +modId = "${mod_id}" +version = "${version}" +displayName = "${mod_name}" +updateJSONURL="https://api.modrinth.com/updates/QgrK9rtJ/forge_updates.json" +displayURL="https://modrinth.com/mod/${mod_id}" +logoFile="logo.png" +credits="${credits}" +authors = "${mod_author}" +description = '''${description}''' + +[[mixins]] +config = "${mod_id}.mixins.json" +[[mixins]] +config = "${mod_id}.neoforge.mixins.json" + +[[dependencies.${mod_id}]] +modId = "neoforge" +type="required" +versionRange = "[${neoforge_version},)" +ordering = "NONE" +side = "BOTH" + +[[dependencies.${mod_id}]] +modId = "minecraft" +type="required" +versionRange = "${minecraft_version_range}" +ordering = "NONE" +side = "BOTH" + +[[dependencies.${mod_id}]] +modId="almostunified" +mandatory=true +versionRange="[${almostunified_version},)" +ordering="AFTER" +side="SERVER" +referralUrl="https://modrinth.com/mod/almost-unified" + +[[dependencies.${mod_id}]] +modId="create" +mandatory=true +versionRange="[6.0.6,6.1.0)" +ordering="AFTER" +side="BOTH" +referralUrl="https://modrinth.com/mod/create" diff --git a/neoforge/src/main/resources/META-INF/services/dev.amronos.createaddoncompatibility.platform.services.IPlatformHelper b/neoforge/src/main/resources/META-INF/services/dev.amronos.createaddoncompatibility.platform.services.IPlatformHelper new file mode 100644 index 0000000..133c1aa --- /dev/null +++ b/neoforge/src/main/resources/META-INF/services/dev.amronos.createaddoncompatibility.platform.services.IPlatformHelper @@ -0,0 +1 @@ +dev.amronos.createaddoncompatibility.platform.NeoForgePlatformHelper diff --git a/neoforge/src/main/resources/createaddoncompatibility.neoforge.mixins.json b/neoforge/src/main/resources/createaddoncompatibility.neoforge.mixins.json new file mode 100644 index 0000000..3fc45af --- /dev/null +++ b/neoforge/src/main/resources/createaddoncompatibility.neoforge.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "dev.amronos.createaddoncompatibility.mixin", + "compatibilityLevel": "JAVA_21", + "mixins": [], + "client": [ + "MixinTitleScreen" + ], + "server": [], + "injectors": { + "defaultRequire": 1 + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 0a02867..77067c8 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,15 +1,39 @@ pluginManagement { repositories { gradlePluginPortal() - maven { - name = 'MinecraftForge' - url = 'https://maven.minecraftforge.net/' + mavenCentral() + exclusiveContent { + forRepository { + maven { + name = 'Fabric' + url = uri('https://maven.fabricmc.net') + } + } + filter { + includeGroup('net.fabricmc') + includeGroup('fabric-loom') + } + } + exclusiveContent { + forRepository { + maven { + name = 'Sponge' + url = uri('https://repo.spongepowered.org/repository/maven-public') + } + } + filter { + includeGroupAndSubgroups("org.spongepowered") + } } - maven { url = 'https://maven.parchmentmc.org' } - maven { url = 'https://repo.spongepowered.org/repository/maven-public/'} } } plugins { - id 'org.gradle.toolchains.foojay-resolver-convention' version '0.5.0' + id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0' } + +// This should match the folder name of the project, or else IDEA may complain (see https://youtrack.jetbrains.com/issue/IDEA-317606) +rootProject.name = 'createaddoncompatibility' +include('common') +// include('fabric') +include('neoforge') diff --git a/src/generated/resources/data/copycats/tags/items/copycat_block.json b/src/generated/resources/data/copycats/tags/items/copycat_block.json deleted file mode 100644 index bbbc2eb..0000000 --- a/src/generated/resources/data/copycats/tags/items/copycat_block.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "values": [ - { - "id": "create_dd:copycat_block", - "required": false - } - ] -} \ No newline at end of file diff --git a/src/generated/resources/data/copycats/tags/items/copycat_box.json b/src/generated/resources/data/copycats/tags/items/copycat_box.json deleted file mode 100644 index 1516b28..0000000 --- a/src/generated/resources/data/copycats/tags/items/copycat_box.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "values": [ - { - "id": "create_connected:copycat_box", - "required": false - } - ] -} \ No newline at end of file diff --git a/src/generated/resources/data/copycats/tags/items/copycat_catwalk.json b/src/generated/resources/data/copycats/tags/items/copycat_catwalk.json deleted file mode 100644 index 84195b1..0000000 --- a/src/generated/resources/data/copycats/tags/items/copycat_catwalk.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "values": [ - { - "id": "create_connected:copycat_catwalk", - "required": false - } - ] -} \ No newline at end of file diff --git a/src/generated/resources/data/copycats/tags/items/copycat_slab.json b/src/generated/resources/data/copycats/tags/items/copycat_slab.json deleted file mode 100644 index ac4c1f3..0000000 --- a/src/generated/resources/data/copycats/tags/items/copycat_slab.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "values": [ - { - "id": "create_dd:copycat_slab", - "required": false - } - ] -} \ No newline at end of file diff --git a/src/generated/resources/data/copycats/tags/items/copycat_stairs.json b/src/generated/resources/data/copycats/tags/items/copycat_stairs.json deleted file mode 100644 index c062b54..0000000 --- a/src/generated/resources/data/copycats/tags/items/copycat_stairs.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "replace": true, - "values": [ - { - "id": "copycats:copycat_stairs", - "required": false - }, - { - "id": "create_connected:copycat_stairs", - "required": false - } - ] -} \ No newline at end of file diff --git a/src/generated/resources/data/createaddoncompatibility/tags/items/six_way_gearbox.json b/src/generated/resources/data/createaddoncompatibility/tags/items/six_way_gearbox.json deleted file mode 100644 index e5b336b..0000000 --- a/src/generated/resources/data/createaddoncompatibility/tags/items/six_way_gearbox.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "values": [ - { - "id": "create_connected:six_way_gearbox", - "required": false - }, - { - "id": "createutilities:gearcube", - "required": false - } - ] -} \ No newline at end of file diff --git a/src/generated/resources/data/forge/tags/fluids/crude_oil.json b/src/generated/resources/data/forge/tags/fluids/crude_oil.json deleted file mode 100644 index 0676d47..0000000 --- a/src/generated/resources/data/forge/tags/fluids/crude_oil.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "values": [ - { - "id": "ad_astra:oil", - "required": false - }, - { - "id": "ad_astra:flowing_oil", - "required": false - }, - { - "id": "pneumaticcraft:oil", - "required": false - }, - { - "id": "pneumaticcraft:flowing_oil", - "required": false - } - ] -} \ No newline at end of file diff --git a/src/generated/resources/data/forge/tags/fluids/liquid_plastic.json b/src/generated/resources/data/forge/tags/fluids/liquid_plastic.json deleted file mode 100644 index b4faaf3..0000000 --- a/src/generated/resources/data/forge/tags/fluids/liquid_plastic.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "values": [ - { - "id": "pneumaticcraft:plastic", - "required": false - }, - { - "id": "pneumaticcraft:flowing_plastic", - "required": false - }, - { - "id": "tfmg:liquid_plastic", - "required": false - }, - { - "id": "tfmg:flowing_liquid_plastic", - "required": false - } - ] -} \ No newline at end of file diff --git a/src/generated/resources/data/forge/tags/fluids/lubricant.json b/src/generated/resources/data/forge/tags/fluids/lubricant.json deleted file mode 100644 index 52a710b..0000000 --- a/src/generated/resources/data/forge/tags/fluids/lubricant.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "values": [ - { - "id": "tfmg:lubrication_oil", - "required": false - }, - { - "id": "tfmg:flowing_lubrication_oil", - "required": false - } - ] -} \ No newline at end of file diff --git a/src/generated/resources/data/forge/tags/items/ingots/plastic.json b/src/generated/resources/data/forge/tags/items/ingots/plastic.json deleted file mode 100644 index bc00a71..0000000 --- a/src/generated/resources/data/forge/tags/items/ingots/plastic.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "values": [ - { - "id": "pneumaticcraft:plastic", - "required": false - } - ] -} \ No newline at end of file diff --git a/src/main/java/com/amronos/createaddoncompatibility/CreateAddonCompatibility.java b/src/main/java/com/amronos/createaddoncompatibility/CreateAddonCompatibility.java deleted file mode 100644 index 9fb37a2..0000000 --- a/src/main/java/com/amronos/createaddoncompatibility/CreateAddonCompatibility.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.amronos.createaddoncompatibility; - -import com.mojang.logging.LogUtils; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.AddPackFindersEvent; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import org.slf4j.Logger; -import com.amronos.createaddoncompatibility.registry.ModDatapacks; - -@Mod(CreateAddonCompatibility.MOD_ID) -public class CreateAddonCompatibility { - public static final String MOD_ID = "createaddoncompatibility"; - public static final Logger LOGGER = LogUtils.getLogger(); - - public CreateAddonCompatibility() { - IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); - MinecraftForge.EVENT_BUS.register(this); - - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::callRegisterModDatapacks); - } - - public void callRegisterModDatapacks(final AddPackFindersEvent event) { - ModDatapacks.registerModDatapacks(event); - } -} diff --git a/src/main/java/com/amronos/createaddoncompatibility/data/datagen/DataGenerators.java b/src/main/java/com/amronos/createaddoncompatibility/data/datagen/DataGenerators.java deleted file mode 100644 index c2260ae..0000000 --- a/src/main/java/com/amronos/createaddoncompatibility/data/datagen/DataGenerators.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.amronos.createaddoncompatibility.data.datagen; - -import com.amronos.createaddoncompatibility.CreateAddonCompatibility; -import net.minecraft.core.HolderLookup; -import net.minecraft.data.DataGenerator; -import net.minecraft.data.PackOutput; -import net.minecraftforge.common.data.ExistingFileHelper; -import net.minecraftforge.data.event.GatherDataEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; - -import java.util.concurrent.CompletableFuture; - -@Mod.EventBusSubscriber(modid = CreateAddonCompatibility.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) -public class DataGenerators { - @SubscribeEvent - public static void gatherData(GatherDataEvent event){ - DataGenerator generator = event.getGenerator(); - PackOutput packOutput = generator.getPackOutput(); - CompletableFuture lookupProvider = event.getLookupProvider(); - ExistingFileHelper existingFileHelper = event.getExistingFileHelper(); - - ModBlockTagGenerator blockTagGenerator = - generator.addProvider(event.includeServer(), new ModBlockTagGenerator(packOutput, lookupProvider, existingFileHelper)); - generator.addProvider(event.includeServer(), new ModFluidTagGenerator(packOutput, lookupProvider, existingFileHelper)); - generator.addProvider(event.includeServer(), new ModItemTagGenerator(packOutput, lookupProvider, blockTagGenerator.contentsGetter(), existingFileHelper)); - } -} diff --git a/src/main/java/com/amronos/createaddoncompatibility/data/datagen/ModBlockTagGenerator.java b/src/main/java/com/amronos/createaddoncompatibility/data/datagen/ModBlockTagGenerator.java deleted file mode 100644 index d4b2ad9..0000000 --- a/src/main/java/com/amronos/createaddoncompatibility/data/datagen/ModBlockTagGenerator.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.amronos.createaddoncompatibility.data.datagen; - -import com.amronos.createaddoncompatibility.CreateAddonCompatibility; -import net.minecraft.core.HolderLookup; -import net.minecraft.data.PackOutput; -import net.minecraftforge.common.data.BlockTagsProvider; -import net.minecraftforge.common.data.ExistingFileHelper; -import org.jetbrains.annotations.Nullable; - -import java.util.concurrent.CompletableFuture; - -public class ModBlockTagGenerator extends BlockTagsProvider { - - public ModBlockTagGenerator(PackOutput output, CompletableFuture lookupProvider, @Nullable ExistingFileHelper existingFileHelper) { - super(output, lookupProvider, CreateAddonCompatibility.MOD_ID, existingFileHelper); - } - - @Override - protected void addTags(HolderLookup.Provider provider) { - - } -} diff --git a/src/main/java/com/amronos/createaddoncompatibility/data/datagen/ModFluidTagGenerator.java b/src/main/java/com/amronos/createaddoncompatibility/data/datagen/ModFluidTagGenerator.java deleted file mode 100644 index 94df197..0000000 --- a/src/main/java/com/amronos/createaddoncompatibility/data/datagen/ModFluidTagGenerator.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.amronos.createaddoncompatibility.data.datagen; - -import com.amronos.createaddoncompatibility.CreateAddonCompatibility; -import com.amronos.createaddoncompatibility.data.tags.ForgeTags; -import net.minecraft.core.HolderLookup; -import net.minecraft.data.PackOutput; -import net.minecraft.data.tags.FluidTagsProvider; -import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.common.data.ExistingFileHelper; -import org.jetbrains.annotations.Nullable; - -import java.util.concurrent.CompletableFuture; - - -public class ModFluidTagGenerator extends FluidTagsProvider { - public ModFluidTagGenerator(PackOutput p_255941_, CompletableFuture p_256600_, @Nullable ExistingFileHelper existingFileHelper) { - super(p_255941_, p_256600_, CreateAddonCompatibility.MOD_ID, existingFileHelper); - } - - @Override - protected void addTags(HolderLookup.Provider pProvider) { - this.tag(ForgeTags.Fluids.CRUDE_OIL) - .addOptional(new ResourceLocation("ad_astra", "oil")) - .addOptional(new ResourceLocation("ad_astra", "flowing_oil")) - .addOptional(new ResourceLocation("pneumaticcraft", "oil")) - .addOptional(new ResourceLocation("pneumaticcraft", "flowing_oil")) - ; - this.tag(ForgeTags.Fluids.LIQUID_PLASTIC) - .addOptional(new ResourceLocation("pneumaticcraft", "plastic")) - .addOptional(new ResourceLocation("pneumaticcraft", "flowing_plastic")) - .addOptional(new ResourceLocation("tfmg", "liquid_plastic")) - .addOptional(new ResourceLocation("tfmg", "flowing_liquid_plastic")) - ; - this.tag(ForgeTags.Fluids.LUBRICANT) - .addOptional(new ResourceLocation("tfmg", "lubrication_oil")) - .addOptional(new ResourceLocation("tfmg", "flowing_lubrication_oil")) - ; - } -} diff --git a/src/main/java/com/amronos/createaddoncompatibility/data/datagen/ModItemTagGenerator.java b/src/main/java/com/amronos/createaddoncompatibility/data/datagen/ModItemTagGenerator.java deleted file mode 100644 index b5c4487..0000000 --- a/src/main/java/com/amronos/createaddoncompatibility/data/datagen/ModItemTagGenerator.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.amronos.createaddoncompatibility.data.datagen; - -import com.amronos.createaddoncompatibility.CreateAddonCompatibility; -import com.amronos.createaddoncompatibility.data.tags.CopycatsTags; -import com.amronos.createaddoncompatibility.data.tags.CreateAddonCompatibilityTags; -import com.amronos.createaddoncompatibility.data.tags.ForgeTags; -import net.minecraft.core.HolderLookup; -import net.minecraft.data.PackOutput; -import net.minecraft.data.tags.ItemTagsProvider; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.block.Block; -import net.minecraftforge.common.data.ExistingFileHelper; -import org.jetbrains.annotations.Nullable; - -import java.util.concurrent.CompletableFuture; - -public class ModItemTagGenerator extends ItemTagsProvider { - public ModItemTagGenerator(PackOutput p_275343_, CompletableFuture p_275729_, CompletableFuture> p_275322_, @Nullable ExistingFileHelper existingFileHelper) { - super(p_275343_, p_275729_, p_275322_, CreateAddonCompatibility.MOD_ID, existingFileHelper); - } - - @Override - protected void addTags(HolderLookup.Provider provider) { - this.tag(ForgeTags.Items.PLASTIC) - .addOptional(new ResourceLocation("pneumaticcraft", "plastic")) - ; - - - this.tag(CreateAddonCompatibilityTags.Items.SIX_WAY_GEARBOX) - .addOptional(new ResourceLocation("create_connected", "six_way_gearbox")) - .addOptional(new ResourceLocation("createutilities", "gearcube")) - ; - - this.tag(CopycatsTags.Items.COPYCAT_BLOCK) - .addOptional(new ResourceLocation("create_dd", "copycat_block")) - ; - this.tag(CopycatsTags.Items.COPYCAT_BOX) - .addOptional(new ResourceLocation("create_connected", "copycat_box")) - ; - this.tag(CopycatsTags.Items.COPYCAT_CATWALK) - .addOptional(new ResourceLocation("create_connected", "copycat_catwalk")) - ; - this.tag(CopycatsTags.Items.COPYCAT_SLAB) - .addOptional(new ResourceLocation("create_dd", "copycat_slab")) - ; - this.tag(CopycatsTags.Items.COPYCAT_STAIRS) - .replace(true) - .addOptional(new ResourceLocation("copycats", "copycat_stairs")) - .addOptional(new ResourceLocation("create_connected", "copycat_stairs")) - ; - } -} diff --git a/src/main/java/com/amronos/createaddoncompatibility/data/tags/CopycatsTags.java b/src/main/java/com/amronos/createaddoncompatibility/data/tags/CopycatsTags.java deleted file mode 100644 index 78ddb5b..0000000 --- a/src/main/java/com/amronos/createaddoncompatibility/data/tags/CopycatsTags.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.amronos.createaddoncompatibility.data.tags; - -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.ItemTags; -import net.minecraft.tags.TagKey; -import net.minecraft.world.item.Item; - -public class CopycatsTags { - public static class Items { - public static final TagKey COPYCAT_BLOCK = tag("copycat_block"); - public static final TagKey COPYCAT_BOX = tag("copycat_box"); - public static final TagKey COPYCAT_CATWALK = tag("copycat_catwalk"); - public static final TagKey COPYCAT_SLAB = tag("copycat_slab"); - public static final TagKey COPYCAT_STAIRS = tag("copycat_stairs"); - - private static TagKey tag(String name) { - return ItemTags.create(new ResourceLocation("copycats", name)); - } - } -} diff --git a/src/main/java/com/amronos/createaddoncompatibility/data/tags/CreateAddonCompatibilityTags.java b/src/main/java/com/amronos/createaddoncompatibility/data/tags/CreateAddonCompatibilityTags.java deleted file mode 100644 index 8a48cbc..0000000 --- a/src/main/java/com/amronos/createaddoncompatibility/data/tags/CreateAddonCompatibilityTags.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.amronos.createaddoncompatibility.data.tags; - -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.FluidTags; -import net.minecraft.tags.ItemTags; -import net.minecraft.tags.TagKey; -import net.minecraft.world.item.Item; -import net.minecraft.world.level.material.Fluid; - -public class CreateAddonCompatibilityTags { - public static class Items { - public static final TagKey SIX_WAY_GEARBOX = tag("six_way_gearbox"); - - private static TagKey tag(String name) { - return ItemTags.create(new ResourceLocation("createaddoncompatibility", name)); - } - } -} diff --git a/src/main/java/com/amronos/createaddoncompatibility/data/tags/ForgeTags.java b/src/main/java/com/amronos/createaddoncompatibility/data/tags/ForgeTags.java deleted file mode 100644 index f873609..0000000 --- a/src/main/java/com/amronos/createaddoncompatibility/data/tags/ForgeTags.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.amronos.createaddoncompatibility.data.tags; - -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.FluidTags; -import net.minecraft.tags.ItemTags; -import net.minecraft.tags.TagKey; -import net.minecraft.world.item.Item; -import net.minecraft.world.level.material.Fluid; - -public class ForgeTags { - - public static class Fluids { - public static final TagKey CRUDE_OIL = tag("crude_oil"); - public static final TagKey LIQUID_PLASTIC = tag("liquid_plastic"); - public static final TagKey LUBRICANT = tag("lubricant"); - - private static TagKey tag(String name) { - return FluidTags.create(new ResourceLocation("forge", name)); - } - } - - public static class Items { - public static final TagKey PLASTIC = tag("ingots/plastic"); - public static final TagKey COKE_DUST = tag("dusts/coal_coke"); - - private static TagKey tag(String name) { - return ItemTags.create(new ResourceLocation("forge", name)); - } - } -} diff --git a/src/main/java/com/amronos/createaddoncompatibility/mixin/MixinBlastFurnaceOutputBlockEntity.java b/src/main/java/com/amronos/createaddoncompatibility/mixin/MixinBlastFurnaceOutputBlockEntity.java deleted file mode 100644 index edae042..0000000 --- a/src/main/java/com/amronos/createaddoncompatibility/mixin/MixinBlastFurnaceOutputBlockEntity.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.amronos.createaddoncompatibility.mixin; - -import com.amronos.createaddoncompatibility.data.tags.ForgeTags; -import com.drmangotea.tfmg.blocks.machines.metal_processing.blast_furnace.BlastFurnaceOutputBlockEntity; -import com.drmangotea.tfmg.registry.TFMGItems; -import com.simibubi.create.foundation.item.SmartInventory; -import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.item.ItemStack; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Pseudo; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - -import java.util.List; - -@Pseudo -@Mixin(BlastFurnaceOutputBlockEntity.class) -public class MixinBlastFurnaceOutputBlockEntity { - @Shadow - public SmartInventory fuelInventory; - @Shadow - public SmartInventory inputInventory; - - @Unique - public SmartInventory createaddoncompatibility$previousFuelInventory; - @Unique - public SmartInventory createaddoncompatibility$previousInputInventory; - - @Inject(remap = false, method = "acceptInsertedItems", at = @At(value = "HEAD")) - private void savePreviousInventory(CallbackInfo info){ - createaddoncompatibility$previousFuelInventory = fuelInventory; - createaddoncompatibility$previousInputInventory = inputInventory; - } - - @Inject(remap = false, method = "acceptInsertedItems", at = @At(value = "TAIL"), locals = LocalCapture.CAPTURE_FAILSOFT) - private void acceptInsertedItems(CallbackInfo info, List itemsToPick) { - fuelInventory = createaddoncompatibility$previousFuelInventory; - inputInventory = createaddoncompatibility$previousInputInventory; - for (ItemEntity itemEntity : itemsToPick) { - ItemStack itemStack = itemEntity.getItem(); - int count; - int freeSpace2; - if (itemStack.is(ForgeTags.Items.COKE_DUST)) { - freeSpace2 = this.fuelInventory.getStackInSlot(0).getMaxStackSize() - this.fuelInventory.getStackInSlot(0).getCount(); - count = itemStack.getCount(); - if (count > freeSpace2) { - itemStack.setCount(itemStack.getCount() - freeSpace2); - this.fuelInventory.setItem(0, new ItemStack(TFMGItems.COAL_COKE_DUST.get(), this.fuelInventory.getStackInSlot(0).getCount() + freeSpace2)); - } else { - this.fuelInventory.setItem(0, new ItemStack(TFMGItems.COAL_COKE_DUST.get(), this.fuelInventory.getStackInSlot(0).getCount() + itemStack.getCount())); - itemEntity.discard(); - } - } else { - if (itemStack.getCount() == 1) { - itemStack.setCount(2); - itemEntity.setItem(itemStack); - } - - freeSpace2 = this.inputInventory.getStackInSlot(0).getMaxStackSize() - this.inputInventory.getStackInSlot(0).getCount(); - count = itemStack.getCount(); - if (this.inputInventory.isEmpty() || this.inputInventory.getItem(0).is(itemStack.getItem())) { - if (count > freeSpace2) { - itemStack.setCount(itemStack.getCount() - freeSpace2); - this.inputInventory.setItem(0, new ItemStack(itemStack.getItem(), this.inputInventory.getStackInSlot(0).getCount() + freeSpace2)); - } else { - this.inputInventory.setItem(0, new ItemStack(itemStack.getItem(), this.inputInventory.getStackInSlot(0).getCount() + itemStack.getCount())); - itemEntity.discard(); - } - } - } - } - } -} diff --git a/src/main/java/com/amronos/createaddoncompatibility/mixin/MixinUnifyConfig.java b/src/main/java/com/amronos/createaddoncompatibility/mixin/MixinUnifyConfig.java deleted file mode 100644 index 2f3aad1..0000000 --- a/src/main/java/com/amronos/createaddoncompatibility/mixin/MixinUnifyConfig.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.amronos.createaddoncompatibility.mixin; - -import com.almostreliable.unified.config.UnifyConfig; -import com.amronos.createaddoncompatibility.CreateAddonCompatibility; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyVariable; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@Mixin(UnifyConfig.Serializer.class) -public class MixinUnifyConfig { - - @ModifyVariable(method = "deserialize", at = @At(value = "RETURN"), ordinal = 0, index = 3, name = "modPriorities", remap = false) - private List modPrioritiesMixin(List modPriorities){ - CreateAddonCompatibility.LOGGER.info("Adding modPriorities for AlmostUnified, this will not reflect in unify.json"); - modPriorities = new ArrayList<>(modPriorities); - List cacModPriorities = new ArrayList(); - cacModPriorities.add("pneumaticcraft"); - cacModPriorities.add("copycats"); - cacModPriorities.add("create_connected"); - cacModPriorities.add("createutilities"); - cacModPriorities.add("create_dd"); - cacModPriorities.add("tfmg"); - for (String i : cacModPriorities) { - if (!modPriorities.contains(i)) { - modPriorities.add(i); - } - } - modPriorities = Collections.unmodifiableList(modPriorities); - return modPriorities; - } - - @ModifyVariable(method = "deserialize", at = @At(value = "RETURN"), ordinal = 2, index = 5, name = "tags", remap = false) - private List tagsMixin(List tags){ - CreateAddonCompatibility.LOGGER.info("Adding tags for AlmostUnified, this will not reflect in unify.json"); - tags = new ArrayList<>(tags); - List cacTags = new ArrayList(); - cacTags.add("forge:plastic_sheet"); - cacTags.add("createaddoncompatibility:six_way_gearbox"); - cacTags.add("copycats:copycat_beam"); - cacTags.add("copycats:copycat_block"); - cacTags.add("copycats:copycat_board"); - cacTags.add("copycats:copycat_box"); - cacTags.add("copycats:copycat_catwalk"); - cacTags.add("copycats:copycat_fence"); - cacTags.add("copycats:copycat_fence_gate"); - cacTags.add("copycats:copycat_slab"); - cacTags.add("copycats:copycat_stairs"); - cacTags.add("copycats:copycat_vertical_step"); - cacTags.add("copycats:copycat_wall"); - for (String i : cacTags) { - if (!tags.contains(i)) { - tags.add(i); - } - } - tags = Collections.unmodifiableList(tags); - return tags; - } -} diff --git a/src/main/java/com/amronos/createaddoncompatibility/registry/ModDatapacks.java b/src/main/java/com/amronos/createaddoncompatibility/registry/ModDatapacks.java deleted file mode 100644 index f53b1e0..0000000 --- a/src/main/java/com/amronos/createaddoncompatibility/registry/ModDatapacks.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.amronos.createaddoncompatibility.registry; - -import com.amronos.createaddoncompatibility.CreateAddonCompatibility; -import net.minecraft.ChatFormatting; -import net.minecraft.network.chat.Component; -import net.minecraft.server.packs.PackType; -import net.minecraft.server.packs.PathPackResources; -import net.minecraft.server.packs.repository.Pack; -import net.minecraft.server.packs.repository.PackSource; -import net.minecraftforge.event.AddPackFindersEvent; -import net.minecraftforge.fml.ModList; - -import java.nio.file.Path; - -public class ModDatapacks { - public static void registerModDatapacks(final AddPackFindersEvent event) { - if (ModList.get().isLoaded("ad_astra")) { - registerModDatapacks(event, "rockets_use_adastra_fuels_only"); - } - } - - private static void registerModDatapacks(final AddPackFindersEvent event, String name) { - if (event.getPackType() == PackType.SERVER_DATA) { - Path path = ModList.get().getModFileById(CreateAddonCompatibility.MOD_ID).getFile().findResource("datapacks/" + name); - Pack builtinDataPack = Pack.readMetaAndCreate( - CreateAddonCompatibility.MOD_ID + ":" + name, - Component.translatable("datapack." + CreateAddonCompatibility.MOD_ID + "." + name), - false, - (a) -> new PathPackResources(a, path, false), - PackType.SERVER_DATA, - Pack.Position.TOP, - PackSource.create((arg) -> Component.translatable("pack.nameAndSource", arg, Component.translatable("pack.source.builtin")).withStyle(ChatFormatting.GRAY), false) - ); - event.addRepositorySource((packConsumer) -> packConsumer.accept(builtinDataPack)); - } - } -} diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml deleted file mode 100644 index d187d86..0000000 --- a/src/main/resources/META-INF/mods.toml +++ /dev/null @@ -1,152 +0,0 @@ -modLoader="javafml" -loaderVersion= "${loader_version_range}" - -license="GNU Lesser General Public License v3.0" -issueTrackerURL="https://github.com/Amronos/${mod_id}/issues" -showAsResourcePack=false - -[[mods]] -modId="${mod_id}" -version="${mod_version}" -displayName="Create: Addon Compatibility" -updateJSONURL="https://api.modrinth.com/updates/QgrK9rtJ/forge_updates.json" -displayURL="https://modrinth.com/mod/${mod_id}" -logoFile="logo.png" -#credits="" -authors="Amronos" -description="Adds compatibility for and between different create addons." - - -[dependencies] -[[dependencies.${mod_id}]] -modId="minecraft" -mandatory=true -versionRange="${minecraft_version_range}" -ordering="NONE" -side="BOTH" - -[[dependencies.${mod_id}]] -modId="forge" -mandatory=true -versionRange="${forge_version_range}" -ordering="NONE" -side="BOTH" - -[[dependencies.${mod_id}]] -modId="almostunified" -mandatory=true -versionRange="[${almostunified_version},)" -ordering="AFTER" -side="BOTH" -referralUrl="https://modrinth.com/mod/almost-unified" - -[[dependencies.${mod_id}]] -modId="ad_astra" -mandatory=false -versionRange="[1.15.18,)" -ordering="AFTER" -side="BOTH" -referralUrl="https://modrinth.com/mod/ad-astra" - -[[dependencies.${mod_id}]] -modId="copycats" -mandatory=false -versionRange="[1.3.8+mc.1.20.1-forge,)" -ordering="AFTER" -side="BOTH" -referralUrl="https://modrinth.com/mod/copycats" - -[[dependencies.${mod_id}]] -modId="create" -mandatory=true -versionRange="${create_version_range}" -ordering="AFTER" -side="BOTH" -referralUrl="https://modrinth.com/mod/create" - -[[dependencies.${mod_id}]] -modId="createaddition" -mandatory=false -versionRange="[1.20.1-1.2.2,)" -ordering="AFTER" -side="BOTH" -referralUrl="https://modrinth.com/mod/createaddition" - -[[dependencies.${mod_id}]] -modId="create_connected" -mandatory=false -versionRange="[0.8.2-mc1.20.1,)" -ordering="AFTER" -side="BOTH" -referralUrl="https://modrinth.com/mod/create-connected" - -[[dependencies.${mod_id}]] -modId="create_dd" -mandatory=false -versionRange="[0.1a.Release-Early-Dev,)" -ordering="AFTER" -side="BOTH" -referralUrl="https://modrinth.com/mod/create-dreams-and-desires" - -[[dependencies.${mod_id}]] -modId="createdieselgenerators" -mandatory=false -versionRange="[${createdieselgenerators_version},)" -ordering="AFTER" -side="BOTH" -referralUrl="https://modrinth.com/mod/create-diesel-generators" - -[[dependencies.${mod_id}]] -modId="createutilities" -mandatory=false -versionRange="[0.3.0,)" -ordering="AFTER" -side="BOTH" -referralUrl="https://modrinth.com/mod/create-utilities" - -[[dependencies.${mod_id}]] -modId="destroy" -mandatory=false -versionRange="[0.1.0-snapshot-6,)" -ordering="AFTER" -side="BOTH" -referralUrl="https://modrinth.com/mod/destroy" - -[[dependencies.${mod_id}]] -modId="garnished" -mandatory=false -versionRange="[1.8.3,)" -ordering="AFTER" -side="BOTH" -referralUrl="https://modrinth.com/mod/create-garnished" - -[[dependencies.${mod_id}]] -modId="jei" -mandatory=false -versionRange="[${jei_version},)" -ordering="AFTER" -side="CLIENT" - -[[dependencies.${mod_id}]] -modId="pneumaticcraft" -mandatory=false -versionRange="[6.0.14,)" -ordering="AFTER" -side="BOTH" -referralUrl="https://modrinth.com/mod/pneumaticcraft-repressurized" - -[[dependencies.${mod_id}]] -modId="railways" -mandatory=false -versionRange="[1.6.3,)" -ordering="AFTER" -side="BOTH" -referralUrl="https://modrinth.com/mod/create-steam-n-rails" - -[[dependencies.${mod_id}]] -modId="tfmg" -mandatory=false -versionRange="[${tfmg_version},)" -ordering="AFTER" -side="BOTH" -referralUrl="https://modrinth.com/mod/create-tfmg" diff --git a/src/main/resources/assets/createaddoncompatibility/lang/en_us.json b/src/main/resources/assets/createaddoncompatibility/lang/en_us.json deleted file mode 100644 index 5a98d02..0000000 --- a/src/main/resources/assets/createaddoncompatibility/lang/en_us.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "datapack.createaddoncompatibility.rockets_use_adastra_fuels_only": "Rockets Use Ad Astra Fuels Only", - "datapack.createaddoncompatibility.rockets_use_adastra_fuels_only.description": "Makes Ad Astra rockets use only Ad Astra fuels." -} diff --git a/src/main/resources/data/createaddoncompatibility/diesel_engine_fuel_type/ad_astra-cryo_fuel.json b/src/main/resources/data/createaddoncompatibility/diesel_engine_fuel_type/ad_astra-cryo_fuel.json deleted file mode 100644 index 0bccec6..0000000 --- a/src/main/resources/data/createaddoncompatibility/diesel_engine_fuel_type/ad_astra-cryo_fuel.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "fluid": "ad_astra:cryo_fuel", - "sound_speed": 1, - "normal": { - "speed": 96.0, - "strength": 2048.0, - "burn_rate": 2 - }, - "modular": { - "speed": 96.0, - "strength": 3072.0, - "burn_rate": 2 - }, - "huge": { - "speed": 128.0, - "strength": 4096.0, - "burn_rate": 2 - } -} diff --git a/src/main/resources/data/createaddoncompatibility/diesel_engine_fuel_type/ad_astra-fuel.json b/src/main/resources/data/createaddoncompatibility/diesel_engine_fuel_type/ad_astra-fuel.json deleted file mode 100644 index 40e419f..0000000 --- a/src/main/resources/data/createaddoncompatibility/diesel_engine_fuel_type/ad_astra-fuel.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "fluid": "ad_astra:fuel", - "sound_speed": 1, - "normal": { - "speed": 96.0, - "strength": 2048.0, - "burn_rate": 2 - }, - "modular": { - "speed": 96.0, - "strength": 3072.0, - "burn_rate": 2 - }, - "huge": { - "speed": 128.0, - "strength": 4096.0, - "burn_rate": 2 - } -} diff --git a/src/main/resources/data/createaddoncompatibility/diesel_engine_fuel_type/createaddition-bioethanol.json b/src/main/resources/data/createaddoncompatibility/diesel_engine_fuel_type/createaddition-bioethanol.json deleted file mode 100644 index 0a75127..0000000 --- a/src/main/resources/data/createaddoncompatibility/diesel_engine_fuel_type/createaddition-bioethanol.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "fluid": "createaddition:bioethanol", - "sound_speed": 1, - "normal": { - "speed": 96.0, - "strength": 2048.0, - "burn_rate": 1 - }, - "modular": { - "speed": 96.0, - "strength": 2048.0, - "burn_rate": 1 - }, - "huge": { - "speed": 128.0, - "strength": 8192.0, - "burn_rate": 1 - } -} diff --git a/src/main/resources/data/createaddoncompatibility/diesel_engine_fuel_type/garnished-peanut_oil.json b/src/main/resources/data/createaddoncompatibility/diesel_engine_fuel_type/garnished-peanut_oil.json deleted file mode 100644 index 387429e..0000000 --- a/src/main/resources/data/createaddoncompatibility/diesel_engine_fuel_type/garnished-peanut_oil.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "fluid": "garnished:peanut_oil", - "sound_speed": 1, - "normal": { - "speed": 96.0, - "strength": 2048.0, - "burn_rate": 2 - }, - "modular": { - "speed": 96.0, - "strength": 3072.0, - "burn_rate": 2 - }, - "huge": { - "speed": 128.0, - "strength": 4096.0, - "burn_rate": 2 - } -} diff --git a/src/main/resources/data/createaddoncompatibility/railways/railways_liquid_fuel/compat-diesel.json b/src/main/resources/data/createaddoncompatibility/railways/railways_liquid_fuel/compat-diesel.json deleted file mode 100644 index 4521846..0000000 --- a/src/main/resources/data/createaddoncompatibility/railways/railways_liquid_fuel/compat-diesel.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "fluids": [ - "#forge:diesel" - ], - "fuel_ticks": 550 -} diff --git a/src/main/resources/data/createaddoncompatibility/railways/railways_liquid_fuel/compat-ethanol.json b/src/main/resources/data/createaddoncompatibility/railways/railways_liquid_fuel/compat-ethanol.json deleted file mode 100644 index 25596a3..0000000 --- a/src/main/resources/data/createaddoncompatibility/railways/railways_liquid_fuel/compat-ethanol.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "fluids": [ - "#forge:ethanol" - ], - "fuel_ticks": 250 -} diff --git a/src/main/resources/data/createaddoncompatibility/railways/railways_liquid_fuel/compat-gasoline.json b/src/main/resources/data/createaddoncompatibility/railways/railways_liquid_fuel/compat-gasoline.json deleted file mode 100644 index 72c6d96..0000000 --- a/src/main/resources/data/createaddoncompatibility/railways/railways_liquid_fuel/compat-gasoline.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "fluids": [ - "#forge:gasoline" - ], - "fuel_ticks": 550 -} diff --git a/src/main/resources/data/createaddoncompatibility/railways/railways_liquid_fuel/compat-plantoil.json b/src/main/resources/data/createaddoncompatibility/railways/railways_liquid_fuel/compat-plantoil.json deleted file mode 100644 index 65ba54d..0000000 --- a/src/main/resources/data/createaddoncompatibility/railways/railways_liquid_fuel/compat-plantoil.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "fluids": [ - "#forge:plantoil" - ], - "fuel_ticks": 250 -} diff --git a/src/main/resources/data/createaddoncompatibility/recipes/pneumaticcraft/thermo_plant/compat-reinforced_pressure_tube.json b/src/main/resources/data/createaddoncompatibility/recipes/pneumaticcraft/thermo_plant/compat-reinforced_pressure_tube.json deleted file mode 100644 index c392fd2..0000000 --- a/src/main/resources/data/createaddoncompatibility/recipes/pneumaticcraft/thermo_plant/compat-reinforced_pressure_tube.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "type": "forge:conditional", - "recipes": [ - { - "conditions": [ - { - "type": "forge:mod_loaded", - "modid": "pneumaticcraft" - } - ], - "recipe": { - "type": "pneumaticcraft:thermo_plant", - "exothermic": false, - "fluid_input": { - "type": "pneumaticcraft:fluid", - "amount": 50, - "tag": "forge:liquid_plastic" - }, - "item_input": { - "item": "pneumaticcraft:pressure_tube" - }, - "item_output": { - "item": "pneumaticcraft:reinforced_pressure_tube" - }, - "pressure": 1.5 - } - } - ] -} - \ No newline at end of file diff --git a/src/main/resources/data/createaddoncompatibility/recipes/tfmg/distillation/compat-crude_oil.json b/src/main/resources/data/createaddoncompatibility/recipes/tfmg/distillation/compat-crude_oil.json deleted file mode 100644 index bf5402b..0000000 --- a/src/main/resources/data/createaddoncompatibility/recipes/tfmg/distillation/compat-crude_oil.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "type": "tfmg:distillation", - - "ingredients": [ - { - "fluidTag": "forge:crude_oil", - "nbt": {}, - "amount": 180 - } - ], - - "results": [ - { - "fluid": "tfmg:heavy_oil", - "amount": 40 - }, - { - "fluid": "tfmg:diesel", - "amount": 30 - }, - { - "fluid": "tfmg:kerosene", - "amount": 20 - }, - { - "fluid": "tfmg:naphtha", - "amount": 20 - }, - { - "fluid": "tfmg:gasoline", - "amount": 40 - }, - { - "fluid": "tfmg:lpg", - "amount": 30 - } - ] -} diff --git a/src/main/resources/data/createaddoncompatibility/recipes/tfmg/distillation/compat-crude_oil_no_naptha.json b/src/main/resources/data/createaddoncompatibility/recipes/tfmg/distillation/compat-crude_oil_no_naptha.json deleted file mode 100644 index 7f7c11d..0000000 --- a/src/main/resources/data/createaddoncompatibility/recipes/tfmg/distillation/compat-crude_oil_no_naptha.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "type": "tfmg:distillation", - - "ingredients": [ - { - "fluidTag": "forge:crude_oil", - "nbt": {}, - "amount": 340 - } - ], - - "results": [ - { - "fluid": "tfmg:heavy_oil", - "amount": 80 - }, - { - "fluid": "tfmg:diesel", - "amount": 60 - }, - { - "fluid": "tfmg:kerosene", - "amount": 40 - }, - { - "fluid": "tfmg:gasoline", - "amount": 80 - }, - { - "fluid": "tfmg:lpg", - "amount": 60 - } - ] -} diff --git a/src/main/resources/data/createaddoncompatibility/recipes/tfmg/sequenced_assembly/compat-pneumaticcraft-turbine_engine.json b/src/main/resources/data/createaddoncompatibility/recipes/tfmg/sequenced_assembly/compat-pneumaticcraft-turbine_engine.json deleted file mode 100644 index 6f9725c..0000000 --- a/src/main/resources/data/createaddoncompatibility/recipes/tfmg/sequenced_assembly/compat-pneumaticcraft-turbine_engine.json +++ /dev/null @@ -1,113 +0,0 @@ -{ - "type": "forge:conditional", - "recipes": [ - { - "conditions": [ - { - "type": "forge:mod_loaded", - "modid": "pneumaticcraft" - } - ], - "recipe": { - "type": "create:sequenced_assembly", - "ingredient": { - "item": "tfmg:engine_base" - }, - "transitionalItem": { - "item": "tfmg:unfinished_turbine_engine" - }, - "sequence": [ - { - "type": "create:deploying", - "ingredients": [ - { - "item": "tfmg:unfinished_turbine_engine" - }, - { - "item": "tfmg:turbine_blade" - } - ], - "results": [ - { - "item": "tfmg:unfinished_turbine_engine" - } - ] - }, - { - "type": "create:deploying", - "ingredients": [ - { - "item": "tfmg:unfinished_turbine_engine" - }, - { - "item": "tfmg:screw" - } - ], - "results": [ - { - "item": "tfmg:unfinished_turbine_engine" - } - ] - }, - { - "type": "create:deploying", - "ingredients": [ - { - "item": "tfmg:unfinished_turbine_engine" - }, - { - "item": "tfmg:screwdriver" - } - ], - "results": [ - { - "item": "tfmg:unfinished_turbine_engine" - } - ] - }, - { - "type": "create:filling", - "ingredients": [ - { - "item": "tfmg:unfinished_turbine_engine" - }, - { - "fluid": "pneumaticcraft:lubricant", - "nbt": {}, - "amount": 1000 - } - ], - "results": [ - { - "item": "tfmg:unfinished_turbine_engine" - } - ] - }, - { - "type": "create:deploying", - "ingredients": [ - { - "item": "tfmg:unfinished_turbine_engine" - }, - { - "item": "tfmg:steel_mechanism" - } - ], - "results": [ - { - "item": "tfmg:unfinished_turbine_engine" - } - ] - } - ], - "results": [ - { - "item": "tfmg:turbine_engine", - "count": 2 - } - ], - "loops": 6 - } - } - ] -} diff --git a/src/main/resources/datapacks/rockets_use_adastra_fuels_only/data/ad_astra/tags/fluids/fuel.json b/src/main/resources/datapacks/rockets_use_adastra_fuels_only/data/ad_astra/tags/fluids/fuel.json deleted file mode 100644 index cff7210..0000000 --- a/src/main/resources/datapacks/rockets_use_adastra_fuels_only/data/ad_astra/tags/fluids/fuel.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "replace": true, - "values": [ - { - "id": "ad_astra:fuel", - "required": false - }, - { - "id": "ad_astra:cryo_fuel", - "required": false - } - ] -} diff --git a/src/main/resources/datapacks/rockets_use_adastra_fuels_only/pack.mcmeta b/src/main/resources/datapacks/rockets_use_adastra_fuels_only/pack.mcmeta deleted file mode 100644 index 44ef1b8..0000000 --- a/src/main/resources/datapacks/rockets_use_adastra_fuels_only/pack.mcmeta +++ /dev/null @@ -1,8 +0,0 @@ -{ - "pack": { - "pack_format": 15, - "description": { - "translate": "datapack.createaddoncompatibility.rockets_use_adastra_fuels_only.description" - } - } -} diff --git a/src/main/resources/mixins.createaddoncompatibility.json b/src/main/resources/mixins.createaddoncompatibility.json deleted file mode 100644 index 2c3cb45..0000000 --- a/src/main/resources/mixins.createaddoncompatibility.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "required": true, - "package": "com.amronos.createaddoncompatibility.mixin", - "refmap": "createaddoncompatibility.refmap.json", - "compatibilityLevel": "JAVA_17", - "mixins": [ - "MixinBlastFurnaceOutputBlockEntity", - "MixinUnifyConfig" - ], - "client": [ - ], - "injectors": { - "defaultRequire": 1 - }, - "minVersion": "0.8" -} diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta deleted file mode 100644 index eca79ae..0000000 --- a/src/main/resources/pack.mcmeta +++ /dev/null @@ -1,8 +0,0 @@ -{ - "pack": { - "description": { - "text": "${mod_id} resources" - }, - "pack_format": 15 - } -} \ No newline at end of file From 64d9f208c0ec3b0a15863e52fd60e597426fe67b Mon Sep 17 00:00:00 2001 From: Aarav Gupta Date: Tue, 26 Aug 2025 18:10:31 +0530 Subject: [PATCH 2/3] Port almostunified mixins --- .../createaddoncompatibility/CommonClass.java | 26 +------- .../mixin/MixinMinecraft.java | 19 ------ .../mixin/MixinUnifySerializer.java | 61 +++++++++++++++++++ .../createaddoncompatibility.mixins.json | 7 +-- neoforge/build.gradle | 4 +- .../mixin/MixinTitleScreen.java | 20 ------ ...ateaddoncompatibility.neoforge.mixins.json | 8 +-- 7 files changed, 71 insertions(+), 74 deletions(-) delete mode 100644 common/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinMinecraft.java create mode 100644 common/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinUnifySerializer.java delete mode 100644 neoforge/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinTitleScreen.java diff --git a/common/src/main/java/dev/amronos/createaddoncompatibility/CommonClass.java b/common/src/main/java/dev/amronos/createaddoncompatibility/CommonClass.java index 5b9a29e..0435ba4 100644 --- a/common/src/main/java/dev/amronos/createaddoncompatibility/CommonClass.java +++ b/common/src/main/java/dev/amronos/createaddoncompatibility/CommonClass.java @@ -1,31 +1,7 @@ package dev.amronos.createaddoncompatibility; -import dev.amronos.createaddoncompatibility.platform.Services; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.world.item.Items; - -// This class is part of the common project meaning it is shared between all supported loaders. Code written here can only -// import and access the vanilla codebase, libraries used by vanilla, and optionally third party libraries that provide -// common compatible binaries. This means common code can not directly use loader specific concepts such as Forge events -// however it will be compatible with all supported mod loaders. public class CommonClass { - // The loader specific projects are able to import and use any code from the common project. This allows you to - // write the majority of your code here and load it from your loader specific projects. This example has some - // code that gets invoked by the entry point of the loader specific projects. public static void init() { - - Constants.LOG.info("Hello from Common init on {}! we are currently in a {} environment!", Services.PLATFORM.getPlatformName(), Services.PLATFORM.getEnvironmentName()); - Constants.LOG.info("The ID for diamonds is {}", BuiltInRegistries.ITEM.getKey(Items.DIAMOND)); - - // It is common for all supported loaders to provide a similar feature that can not be used directly in the - // common code. A popular way to get around this is using Java's built-in service loader feature to create - // your own abstraction layer. You can learn more about this in our provided services class. In this example - // we have an interface in the common code and use a loader specific implementation to delegate our call to - // the platform specific approach. - if (Services.PLATFORM.isModLoaded("examplemod")) { - - Constants.LOG.info("Hello to examplemod"); - } } -} \ No newline at end of file +} diff --git a/common/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinMinecraft.java b/common/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinMinecraft.java deleted file mode 100644 index 24cbab0..0000000 --- a/common/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinMinecraft.java +++ /dev/null @@ -1,19 +0,0 @@ -package dev.amronos.createaddoncompatibility.mixin; - -import dev.amronos.createaddoncompatibility.Constants; -import net.minecraft.client.Minecraft; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(Minecraft.class) -public class MixinMinecraft { - - @Inject(at = @At("TAIL"), method = "") - private void init(CallbackInfo info) { - - Constants.LOG.info("This line is printed by an example mod common mixin!"); - Constants.LOG.info("MC Version: {}", Minecraft.getInstance().getVersionType()); - } -} \ No newline at end of file diff --git a/common/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinUnifySerializer.java b/common/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinUnifySerializer.java new file mode 100644 index 0000000..9ff8786 --- /dev/null +++ b/common/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinUnifySerializer.java @@ -0,0 +1,61 @@ +package dev.amronos.createaddoncompatibility.mixin; + +import com.almostreliable.unified.config.UnificationConfig; +import dev.amronos.createaddoncompatibility.Constants; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@Mixin(UnificationConfig.UnifySerializer.class) +public class MixinUnifySerializer { + @ModifyVariable(method = "handleDeserialization*", at = @At(value = "RETURN"), ordinal = 0, name = "modPriorities", remap = false) + private List modPrioritiesMixin(List modPriorities){ + Constants.LOG.info("Adding modPriorities for AlmostUnified, this will not reflect in unify.json"); + modPriorities = new ArrayList<>(modPriorities); + List cacModPriorities = new ArrayList<>(); + cacModPriorities.add("pneumaticcraft"); + cacModPriorities.add("copycats"); + cacModPriorities.add("create_connected"); + cacModPriorities.add("createutilities"); + cacModPriorities.add("create_dd"); + cacModPriorities.add("tfmg"); + for (String i : cacModPriorities) { + if (!modPriorities.contains(i)) { + modPriorities.add(i); + } + } + modPriorities = Collections.unmodifiableList(modPriorities); + return modPriorities; + } + + @ModifyVariable(method = "handleDeserialization*", at = @At(value = "RETURN"), ordinal = 2, name = "tags", remap = false) + private List tagsMixin(List tags){ + Constants.LOG.info("Adding tags for AlmostUnified, this will not reflect in unify.json"); + tags = new ArrayList<>(tags); + List cacTags = new ArrayList<>(); + cacTags.add("forge:plastic_sheet"); + cacTags.add("createaddoncompatibility:six_way_gearbox"); + cacTags.add("copycats:copycat_beam"); + cacTags.add("copycats:copycat_block"); + cacTags.add("copycats:copycat_board"); + cacTags.add("copycats:copycat_box"); + cacTags.add("copycats:copycat_catwalk"); + cacTags.add("copycats:copycat_fence"); + cacTags.add("copycats:copycat_fence_gate"); + cacTags.add("copycats:copycat_slab"); + cacTags.add("copycats:copycat_stairs"); + cacTags.add("copycats:copycat_vertical_step"); + cacTags.add("copycats:copycat_wall"); + for (String i : cacTags) { + if (!tags.contains(i)) { + tags.add(i); + } + } + tags = Collections.unmodifiableList(tags); + return tags; + } +} diff --git a/common/src/main/resources/createaddoncompatibility.mixins.json b/common/src/main/resources/createaddoncompatibility.mixins.json index 623e2a3..9e5c9da 100644 --- a/common/src/main/resources/createaddoncompatibility.mixins.json +++ b/common/src/main/resources/createaddoncompatibility.mixins.json @@ -4,13 +4,12 @@ "package": "dev.amronos.createaddoncompatibility.mixin", "refmap": "${mod_id}.refmap.json", "compatibilityLevel": "JAVA_18", - "mixins": [], - "client": [ - "MixinMinecraft" + "mixins": [ + "MixinUnifySerializer" ], + "client": [], "server": [], "injectors": { "defaultRequire": 1 } } - diff --git a/neoforge/build.gradle b/neoforge/build.gradle index ac78c9f..41c8299 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -42,7 +42,7 @@ dependencies { compileOnly("dev.engine-room.flywheel:flywheel-neoforge-api-${minecraft_version}:${flywheel_version}") runtimeOnly("dev.engine-room.flywheel:flywheel-neoforge-${minecraft_version}:${flywheel_version}") implementation("com.tterrag.registrate:Registrate:${registrate_version}") - compileOnly("com.almostreliable.mods:almostunified-neoforge:${almostunified_version}") + implementation("com.almostreliable.mods:almostunified-neoforge:${almostunified_version}") } -sourceSets.main.resources { srcDir 'src/generated/resources' } \ No newline at end of file +sourceSets.main.resources { srcDir 'src/generated/resources' } diff --git a/neoforge/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinTitleScreen.java b/neoforge/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinTitleScreen.java deleted file mode 100644 index 3a439f5..0000000 --- a/neoforge/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinTitleScreen.java +++ /dev/null @@ -1,20 +0,0 @@ -package dev.amronos.createaddoncompatibility.mixin; - -import dev.amronos.createaddoncompatibility.Constants; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.screens.TitleScreen; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(TitleScreen.class) -public class MixinTitleScreen { - - @Inject(at = @At("HEAD"), method = "init()V") - private void init(CallbackInfo info) { - - Constants.LOG.info("This line is printed by an example mod mixin from NeoForge!"); - Constants.LOG.info("MC Version: {}", Minecraft.getInstance().getVersionType()); - } -} diff --git a/neoforge/src/main/resources/createaddoncompatibility.neoforge.mixins.json b/neoforge/src/main/resources/createaddoncompatibility.neoforge.mixins.json index 3fc45af..8d3fdab 100644 --- a/neoforge/src/main/resources/createaddoncompatibility.neoforge.mixins.json +++ b/neoforge/src/main/resources/createaddoncompatibility.neoforge.mixins.json @@ -3,12 +3,12 @@ "minVersion": "0.8", "package": "dev.amronos.createaddoncompatibility.mixin", "compatibilityLevel": "JAVA_21", - "mixins": [], - "client": [ - "MixinTitleScreen" + "mixins": [ + "MixinUnifySerializer" ], + "client": [], "server": [], "injectors": { "defaultRequire": 1 } -} \ No newline at end of file +} From e20db3e0241aa86ac8a606538105d0517505281b Mon Sep 17 00:00:00 2001 From: Aarav Gupta Date: Sat, 18 Oct 2025 15:37:13 +0530 Subject: [PATCH 3/3] Port tags and fix almost unified mixins --- .github/workflows/PUBLISH.yml | 4 +- .gitignore | 1 + .../data/tags/CommonTags.java | 34 ++++++++++++++ .../data/tags/CopycatsTags.java | 23 ++++++++++ .../mixin/MixinUnifySerializer.java | 26 +++++------ .../createaddoncompatibility.mixins.json | 6 +-- neoforge/build.gradle | 1 + .../data/c/tags/fluid/crude_oil.json | 8 ++++ .../data/c/tags/fluid/lubricant.json | 8 ++++ .../data/c/tags/fluid/lubrication_oil.json | 8 ++++ .../resources/data/c/tags/fluid/plastic.json | 20 +++++++++ .../data/c/tags/item/ingots/plastic.json | 8 ++++ .../copycats/tags/item/copycat_block.json | 8 ++++ .../data/copycats/tags/item/copycat_box.json | 8 ++++ .../copycats/tags/item/copycat_catwalk.json | 8 ++++ .../data/copycats/tags/item/copycat_slab.json | 8 ++++ .../copycats/tags/item/copycat_stairs.json | 13 ++++++ .../CreateAddonCompatibility.java | 2 + .../data/datagen/ModBlockTagsProvider.java | 19 ++++++++ .../data/datagen/ModDataGenerator.java | 24 ++++++++++ .../data/datagen/ModFluidTagsProvider.java | 38 ++++++++++++++++ .../data/datagen/ModItemTagsProvider.java | 45 +++++++++++++++++++ 22 files changed, 300 insertions(+), 20 deletions(-) create mode 100644 common/src/main/java/dev/amronos/createaddoncompatibility/data/tags/CommonTags.java create mode 100644 common/src/main/java/dev/amronos/createaddoncompatibility/data/tags/CopycatsTags.java create mode 100644 neoforge/src/generated/resources/data/c/tags/fluid/crude_oil.json create mode 100644 neoforge/src/generated/resources/data/c/tags/fluid/lubricant.json create mode 100644 neoforge/src/generated/resources/data/c/tags/fluid/lubrication_oil.json create mode 100644 neoforge/src/generated/resources/data/c/tags/fluid/plastic.json create mode 100644 neoforge/src/generated/resources/data/c/tags/item/ingots/plastic.json create mode 100644 neoforge/src/generated/resources/data/copycats/tags/item/copycat_block.json create mode 100644 neoforge/src/generated/resources/data/copycats/tags/item/copycat_box.json create mode 100644 neoforge/src/generated/resources/data/copycats/tags/item/copycat_catwalk.json create mode 100644 neoforge/src/generated/resources/data/copycats/tags/item/copycat_slab.json create mode 100644 neoforge/src/generated/resources/data/copycats/tags/item/copycat_stairs.json create mode 100644 neoforge/src/main/java/dev/amronos/createaddoncompatibility/data/datagen/ModBlockTagsProvider.java create mode 100644 neoforge/src/main/java/dev/amronos/createaddoncompatibility/data/datagen/ModDataGenerator.java create mode 100644 neoforge/src/main/java/dev/amronos/createaddoncompatibility/data/datagen/ModFluidTagsProvider.java create mode 100644 neoforge/src/main/java/dev/amronos/createaddoncompatibility/data/datagen/ModItemTagsProvider.java diff --git a/.github/workflows/PUBLISH.yml b/.github/workflows/PUBLISH.yml index 7594f15..6db1938 100644 --- a/.github/workflows/PUBLISH.yml +++ b/.github/workflows/PUBLISH.yml @@ -55,7 +55,7 @@ jobs: curseforge-id: 1000148 curseforge-token: "${{env.PUBLISH_CURSEFORGE_TOKEN}}" - name: "Create: Addon Compatibility - v${{env.VERSION}} - ${{env.MINECRAFT_VERSION}} - neoforge" + name: "Create: Addon Compatibility - v${{env.VERSION}} - Neoforge - ${{env.MINECRAFT_VERSION}}" version: "${{env.VERSION}}" version-type: "${{env.VERSION_TYPE}}" changelog-file: LATEST_CHANGELOG.md @@ -63,7 +63,7 @@ jobs: loaders: neoforge - files: "build/libs/createaddoncompatibility-${{env.VERSION}}.jar" + files: "neoforge/build/libs/createaddoncompatibility-neoforge-${{env.MINECRAFT_VERSION}}-${{env.VERSION}}.jar" dependencies: | create(required){modrinth:create}{curseforge:328085}#(ignore:github) diff --git a/.gitignore b/.gitignore index 461017f..e0ccc6d 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ build .gradle # other +.cache eclipse run runs diff --git a/common/src/main/java/dev/amronos/createaddoncompatibility/data/tags/CommonTags.java b/common/src/main/java/dev/amronos/createaddoncompatibility/data/tags/CommonTags.java new file mode 100644 index 0000000..733968f --- /dev/null +++ b/common/src/main/java/dev/amronos/createaddoncompatibility/data/tags/CommonTags.java @@ -0,0 +1,34 @@ +package dev.amronos.createaddoncompatibility.data.tags; + +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.material.Fluid; + +public class CommonTags { + public static class Fluids { + public static final TagKey CRUDE_OIL = tag("crude_oil"); + public static final TagKey PLASTIC = tag("plastic"); + public static final TagKey LUBRICANT = tag("lubricant"); + public static final TagKey LUBRICATION_OIL = tag("lubrication_oil"); + + private static TagKey tag(String name) { + return TagKey.create( + Registries.FLUID, + ResourceLocation.fromNamespaceAndPath("c", name) + ); + } + } + + public static class Items { + public static final TagKey PLASTIC = tag("ingots/plastic"); + + private static TagKey tag(String name) { + return TagKey.create( + Registries.ITEM, + ResourceLocation.fromNamespaceAndPath("c", name) + ); + } + } +} diff --git a/common/src/main/java/dev/amronos/createaddoncompatibility/data/tags/CopycatsTags.java b/common/src/main/java/dev/amronos/createaddoncompatibility/data/tags/CopycatsTags.java new file mode 100644 index 0000000..709c23a --- /dev/null +++ b/common/src/main/java/dev/amronos/createaddoncompatibility/data/tags/CopycatsTags.java @@ -0,0 +1,23 @@ +package dev.amronos.createaddoncompatibility.data.tags; + +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; +import net.minecraft.world.item.Item; + +public class CopycatsTags { + public static class Items { + public static final TagKey COPYCAT_BLOCK = tag("copycat_block"); + public static final TagKey COPYCAT_BOX = tag("copycat_box"); + public static final TagKey COPYCAT_CATWALK = tag("copycat_catwalk"); + public static final TagKey COPYCAT_SLAB = tag("copycat_slab"); + public static final TagKey COPYCAT_STAIRS = tag("copycat_stairs"); + + private static TagKey tag(String name) { + return TagKey.create( + Registries.ITEM, + ResourceLocation.fromNamespaceAndPath("copycats", name) + ); + } + } +} diff --git a/common/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinUnifySerializer.java b/common/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinUnifySerializer.java index 9ff8786..137594b 100644 --- a/common/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinUnifySerializer.java +++ b/common/src/main/java/dev/amronos/createaddoncompatibility/mixin/MixinUnifySerializer.java @@ -7,37 +7,34 @@ import org.spongepowered.asm.mixin.injection.ModifyVariable; import java.util.ArrayList; -import java.util.Collections; import java.util.List; @Mixin(UnificationConfig.UnifySerializer.class) public class MixinUnifySerializer { - @ModifyVariable(method = "handleDeserialization*", at = @At(value = "RETURN"), ordinal = 0, name = "modPriorities", remap = false) + @ModifyVariable(method = "handleDeserialization*", at = @At(value = "STORE"), name = "modPriorities", remap = false) private List modPrioritiesMixin(List modPriorities){ Constants.LOG.info("Adding modPriorities for AlmostUnified, this will not reflect in unify.json"); - modPriorities = new ArrayList<>(modPriorities); + ArrayList newModPriorities = new ArrayList<>(modPriorities); List cacModPriorities = new ArrayList<>(); cacModPriorities.add("pneumaticcraft"); cacModPriorities.add("copycats"); cacModPriorities.add("create_connected"); - cacModPriorities.add("createutilities"); cacModPriorities.add("create_dd"); cacModPriorities.add("tfmg"); for (String i : cacModPriorities) { - if (!modPriorities.contains(i)) { - modPriorities.add(i); + if (!newModPriorities.contains(i)) { + newModPriorities.add(i); } } - modPriorities = Collections.unmodifiableList(modPriorities); - return modPriorities; + return newModPriorities; } - @ModifyVariable(method = "handleDeserialization*", at = @At(value = "RETURN"), ordinal = 2, name = "tags", remap = false) + @ModifyVariable(method = "handleDeserialization*", at = @At(value = "STORE"), name = "tags", remap = false) private List tagsMixin(List tags){ Constants.LOG.info("Adding tags for AlmostUnified, this will not reflect in unify.json"); - tags = new ArrayList<>(tags); + ArrayList newTags = new ArrayList<>(tags); List cacTags = new ArrayList<>(); - cacTags.add("forge:plastic_sheet"); + cacTags.add("c:ingots/plastic"); cacTags.add("createaddoncompatibility:six_way_gearbox"); cacTags.add("copycats:copycat_beam"); cacTags.add("copycats:copycat_block"); @@ -51,11 +48,10 @@ private List tagsMixin(List tags){ cacTags.add("copycats:copycat_vertical_step"); cacTags.add("copycats:copycat_wall"); for (String i : cacTags) { - if (!tags.contains(i)) { - tags.add(i); + if (!newTags.contains(i)) { + newTags.add(i); } } - tags = Collections.unmodifiableList(tags); - return tags; + return newTags; } } diff --git a/common/src/main/resources/createaddoncompatibility.mixins.json b/common/src/main/resources/createaddoncompatibility.mixins.json index 9e5c9da..1c8facd 100644 --- a/common/src/main/resources/createaddoncompatibility.mixins.json +++ b/common/src/main/resources/createaddoncompatibility.mixins.json @@ -4,11 +4,11 @@ "package": "dev.amronos.createaddoncompatibility.mixin", "refmap": "${mod_id}.refmap.json", "compatibilityLevel": "JAVA_18", - "mixins": [ + "mixins": [], + "client": [], + "server": [ "MixinUnifySerializer" ], - "client": [], - "server": [], "injectors": { "defaultRequire": 1 } diff --git a/neoforge/build.gradle b/neoforge/build.gradle index 41c8299..03ce602 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -24,6 +24,7 @@ neoForge { } data { data() + programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath() } server { server() diff --git a/neoforge/src/generated/resources/data/c/tags/fluid/crude_oil.json b/neoforge/src/generated/resources/data/c/tags/fluid/crude_oil.json new file mode 100644 index 0000000..118d63c --- /dev/null +++ b/neoforge/src/generated/resources/data/c/tags/fluid/crude_oil.json @@ -0,0 +1,8 @@ +{ + "values": [ + { + "id": "pneumaticcraft:flowing_oil", + "required": false + } + ] +} \ No newline at end of file diff --git a/neoforge/src/generated/resources/data/c/tags/fluid/lubricant.json b/neoforge/src/generated/resources/data/c/tags/fluid/lubricant.json new file mode 100644 index 0000000..bba6835 --- /dev/null +++ b/neoforge/src/generated/resources/data/c/tags/fluid/lubricant.json @@ -0,0 +1,8 @@ +{ + "values": [ + { + "id": "#c:lubrication_oil", + "required": false + } + ] +} \ No newline at end of file diff --git a/neoforge/src/generated/resources/data/c/tags/fluid/lubrication_oil.json b/neoforge/src/generated/resources/data/c/tags/fluid/lubrication_oil.json new file mode 100644 index 0000000..a1a79be --- /dev/null +++ b/neoforge/src/generated/resources/data/c/tags/fluid/lubrication_oil.json @@ -0,0 +1,8 @@ +{ + "values": [ + { + "id": "#c:lubricant", + "required": false + } + ] +} \ No newline at end of file diff --git a/neoforge/src/generated/resources/data/c/tags/fluid/plastic.json b/neoforge/src/generated/resources/data/c/tags/fluid/plastic.json new file mode 100644 index 0000000..b4faaf3 --- /dev/null +++ b/neoforge/src/generated/resources/data/c/tags/fluid/plastic.json @@ -0,0 +1,20 @@ +{ + "values": [ + { + "id": "pneumaticcraft:plastic", + "required": false + }, + { + "id": "pneumaticcraft:flowing_plastic", + "required": false + }, + { + "id": "tfmg:liquid_plastic", + "required": false + }, + { + "id": "tfmg:flowing_liquid_plastic", + "required": false + } + ] +} \ No newline at end of file diff --git a/neoforge/src/generated/resources/data/c/tags/item/ingots/plastic.json b/neoforge/src/generated/resources/data/c/tags/item/ingots/plastic.json new file mode 100644 index 0000000..bc00a71 --- /dev/null +++ b/neoforge/src/generated/resources/data/c/tags/item/ingots/plastic.json @@ -0,0 +1,8 @@ +{ + "values": [ + { + "id": "pneumaticcraft:plastic", + "required": false + } + ] +} \ No newline at end of file diff --git a/neoforge/src/generated/resources/data/copycats/tags/item/copycat_block.json b/neoforge/src/generated/resources/data/copycats/tags/item/copycat_block.json new file mode 100644 index 0000000..bbbc2eb --- /dev/null +++ b/neoforge/src/generated/resources/data/copycats/tags/item/copycat_block.json @@ -0,0 +1,8 @@ +{ + "values": [ + { + "id": "create_dd:copycat_block", + "required": false + } + ] +} \ No newline at end of file diff --git a/neoforge/src/generated/resources/data/copycats/tags/item/copycat_box.json b/neoforge/src/generated/resources/data/copycats/tags/item/copycat_box.json new file mode 100644 index 0000000..1516b28 --- /dev/null +++ b/neoforge/src/generated/resources/data/copycats/tags/item/copycat_box.json @@ -0,0 +1,8 @@ +{ + "values": [ + { + "id": "create_connected:copycat_box", + "required": false + } + ] +} \ No newline at end of file diff --git a/neoforge/src/generated/resources/data/copycats/tags/item/copycat_catwalk.json b/neoforge/src/generated/resources/data/copycats/tags/item/copycat_catwalk.json new file mode 100644 index 0000000..84195b1 --- /dev/null +++ b/neoforge/src/generated/resources/data/copycats/tags/item/copycat_catwalk.json @@ -0,0 +1,8 @@ +{ + "values": [ + { + "id": "create_connected:copycat_catwalk", + "required": false + } + ] +} \ No newline at end of file diff --git a/neoforge/src/generated/resources/data/copycats/tags/item/copycat_slab.json b/neoforge/src/generated/resources/data/copycats/tags/item/copycat_slab.json new file mode 100644 index 0000000..ac4c1f3 --- /dev/null +++ b/neoforge/src/generated/resources/data/copycats/tags/item/copycat_slab.json @@ -0,0 +1,8 @@ +{ + "values": [ + { + "id": "create_dd:copycat_slab", + "required": false + } + ] +} \ No newline at end of file diff --git a/neoforge/src/generated/resources/data/copycats/tags/item/copycat_stairs.json b/neoforge/src/generated/resources/data/copycats/tags/item/copycat_stairs.json new file mode 100644 index 0000000..c062b54 --- /dev/null +++ b/neoforge/src/generated/resources/data/copycats/tags/item/copycat_stairs.json @@ -0,0 +1,13 @@ +{ + "replace": true, + "values": [ + { + "id": "copycats:copycat_stairs", + "required": false + }, + { + "id": "create_connected:copycat_stairs", + "required": false + } + ] +} \ No newline at end of file diff --git a/neoforge/src/main/java/dev/amronos/createaddoncompatibility/CreateAddonCompatibility.java b/neoforge/src/main/java/dev/amronos/createaddoncompatibility/CreateAddonCompatibility.java index 2838463..97cb9b8 100644 --- a/neoforge/src/main/java/dev/amronos/createaddoncompatibility/CreateAddonCompatibility.java +++ b/neoforge/src/main/java/dev/amronos/createaddoncompatibility/CreateAddonCompatibility.java @@ -1,6 +1,7 @@ package dev.amronos.createaddoncompatibility; +import dev.amronos.createaddoncompatibility.data.datagen.ModDataGenerator; import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.common.Mod; @@ -9,5 +10,6 @@ public class CreateAddonCompatibility { public CreateAddonCompatibility(IEventBus eventBus) { CommonClass.init(); + eventBus.register(ModDataGenerator.class); } } diff --git a/neoforge/src/main/java/dev/amronos/createaddoncompatibility/data/datagen/ModBlockTagsProvider.java b/neoforge/src/main/java/dev/amronos/createaddoncompatibility/data/datagen/ModBlockTagsProvider.java new file mode 100644 index 0000000..2c6dc1c --- /dev/null +++ b/neoforge/src/main/java/dev/amronos/createaddoncompatibility/data/datagen/ModBlockTagsProvider.java @@ -0,0 +1,19 @@ +package dev.amronos.createaddoncompatibility.data.datagen; + +import dev.amronos.createaddoncompatibility.Constants; +import net.minecraft.core.HolderLookup; +import net.minecraft.data.PackOutput; +import net.neoforged.neoforge.common.data.BlockTagsProvider; +import net.neoforged.neoforge.common.data.ExistingFileHelper; +import org.jetbrains.annotations.Nullable; + +import java.util.concurrent.CompletableFuture; + +public class ModBlockTagsProvider extends BlockTagsProvider { + public ModBlockTagsProvider(PackOutput output, CompletableFuture lookupProvider, @Nullable ExistingFileHelper existingFileHelper) { + super(output, lookupProvider, Constants.MOD_ID, existingFileHelper); + } + + @Override + protected void addTags(HolderLookup.Provider provider) {} +} diff --git a/neoforge/src/main/java/dev/amronos/createaddoncompatibility/data/datagen/ModDataGenerator.java b/neoforge/src/main/java/dev/amronos/createaddoncompatibility/data/datagen/ModDataGenerator.java new file mode 100644 index 0000000..2944906 --- /dev/null +++ b/neoforge/src/main/java/dev/amronos/createaddoncompatibility/data/datagen/ModDataGenerator.java @@ -0,0 +1,24 @@ +package dev.amronos.createaddoncompatibility.data.datagen; + +import net.minecraft.core.HolderLookup; +import net.minecraft.data.DataGenerator; +import net.minecraft.data.PackOutput; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.neoforge.common.data.ExistingFileHelper; +import net.neoforged.neoforge.data.event.GatherDataEvent; + +import java.util.concurrent.CompletableFuture; + +public class ModDataGenerator { + @SubscribeEvent + public static void gatherData(GatherDataEvent event) { + DataGenerator generator = event.getGenerator(); + PackOutput output = generator.getPackOutput(); + CompletableFuture lookupProvider = event.getLookupProvider(); + ExistingFileHelper existingFileHelper = event.getExistingFileHelper(); + + ModBlockTagsProvider blockTagsProvider = generator.addProvider(event.includeServer(), new ModBlockTagsProvider(output, lookupProvider, existingFileHelper)); + generator.addProvider(event.includeServer(), new ModFluidTagsProvider(output, lookupProvider, existingFileHelper)); + generator.addProvider(event.includeServer(), new ModItemTagsProvider(output, lookupProvider, blockTagsProvider.contentsGetter(), existingFileHelper)); + } +} diff --git a/neoforge/src/main/java/dev/amronos/createaddoncompatibility/data/datagen/ModFluidTagsProvider.java b/neoforge/src/main/java/dev/amronos/createaddoncompatibility/data/datagen/ModFluidTagsProvider.java new file mode 100644 index 0000000..cc61369 --- /dev/null +++ b/neoforge/src/main/java/dev/amronos/createaddoncompatibility/data/datagen/ModFluidTagsProvider.java @@ -0,0 +1,38 @@ +package dev.amronos.createaddoncompatibility.data.datagen; + +import dev.amronos.createaddoncompatibility.Constants; +import dev.amronos.createaddoncompatibility.data.tags.CommonTags; +import net.minecraft.core.HolderLookup; +import net.minecraft.data.PackOutput; +import net.minecraft.data.tags.FluidTagsProvider; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.neoforge.common.data.ExistingFileHelper; +import org.jetbrains.annotations.Nullable; + +import java.util.concurrent.CompletableFuture; + +public class ModFluidTagsProvider extends FluidTagsProvider { + + public ModFluidTagsProvider(PackOutput output, CompletableFuture provider, @Nullable ExistingFileHelper existingFileHelper) { + super(output, provider, Constants.MOD_ID, existingFileHelper); + } + + @Override + protected void addTags(HolderLookup.Provider lookupProvider) { + tag(CommonTags.Fluids.CRUDE_OIL) + .addOptional(ResourceLocation.fromNamespaceAndPath("pneumaticcraft", "flowing_oil")) + ; + tag(CommonTags.Fluids.PLASTIC) + .addOptional(ResourceLocation.fromNamespaceAndPath("pneumaticcraft", "plastic")) + .addOptional(ResourceLocation.fromNamespaceAndPath("pneumaticcraft", "flowing_plastic")) + .addOptional(ResourceLocation.fromNamespaceAndPath("tfmg", "liquid_plastic")) + .addOptional(ResourceLocation.fromNamespaceAndPath("tfmg", "flowing_liquid_plastic")) + ; + tag(CommonTags.Fluids.LUBRICANT) + .addOptionalTag(ResourceLocation.fromNamespaceAndPath("c", "lubrication_oil")) + ; + tag(CommonTags.Fluids.LUBRICATION_OIL) + .addOptionalTag(ResourceLocation.fromNamespaceAndPath("c", "lubricant")) + ; + } +} diff --git a/neoforge/src/main/java/dev/amronos/createaddoncompatibility/data/datagen/ModItemTagsProvider.java b/neoforge/src/main/java/dev/amronos/createaddoncompatibility/data/datagen/ModItemTagsProvider.java new file mode 100644 index 0000000..9df359c --- /dev/null +++ b/neoforge/src/main/java/dev/amronos/createaddoncompatibility/data/datagen/ModItemTagsProvider.java @@ -0,0 +1,45 @@ +package dev.amronos.createaddoncompatibility.data.datagen; + +import dev.amronos.createaddoncompatibility.Constants; +import dev.amronos.createaddoncompatibility.data.tags.CommonTags; +import dev.amronos.createaddoncompatibility.data.tags.CopycatsTags; +import net.minecraft.core.HolderLookup; +import net.minecraft.data.PackOutput; +import net.minecraft.data.tags.ItemTagsProvider; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.Block; +import net.neoforged.neoforge.common.data.ExistingFileHelper; +import org.jetbrains.annotations.Nullable; + +import java.util.concurrent.CompletableFuture; + +public class ModItemTagsProvider extends ItemTagsProvider { + public ModItemTagsProvider(PackOutput output, CompletableFuture lookupProvider, CompletableFuture> blockTags, @Nullable ExistingFileHelper existingFileHelper) { + super(output, lookupProvider, blockTags, Constants.MOD_ID, existingFileHelper); + } + + @Override + protected void addTags(HolderLookup.Provider provider) { + this.tag(CommonTags.Items.PLASTIC) + .addOptional(ResourceLocation.fromNamespaceAndPath("pneumaticcraft", "plastic")) + ; + + this.tag(CopycatsTags.Items.COPYCAT_BLOCK) + .addOptional(ResourceLocation.fromNamespaceAndPath("create_dd", "copycat_block")) + ; + this.tag(CopycatsTags.Items.COPYCAT_BOX) + .addOptional(ResourceLocation.fromNamespaceAndPath("create_connected", "copycat_box")) + ; + this.tag(CopycatsTags.Items.COPYCAT_CATWALK) + .addOptional(ResourceLocation.fromNamespaceAndPath("create_connected", "copycat_catwalk")) + ; + this.tag(CopycatsTags.Items.COPYCAT_SLAB) + .addOptional(ResourceLocation.fromNamespaceAndPath("create_dd", "copycat_slab")) + ; + this.tag(CopycatsTags.Items.COPYCAT_STAIRS) + .replace(true) + .addOptional(ResourceLocation.fromNamespaceAndPath("copycats", "copycat_stairs")) + .addOptional(ResourceLocation.fromNamespaceAndPath("create_connected", "copycat_stairs")) + ; + } +}