diff --git a/build.gradle b/build.gradle index 9e3118a3..eff8d610 100644 --- a/build.gradle +++ b/build.gradle @@ -3,20 +3,16 @@ plugins { id 'eclipse' id 'idea' id 'maven-publish' - id 'fabric-loom' version '0.5-SNAPSHOT' apply false id 'net.minecrell.licenser' version '0.4.1' id "org.ajoberstar.grgit" version "3.1.1" id 'com.jfrog.bintray' version '1.8.4' + id 'patchwork-api.module-conventions' + id 'patchwork-api.checkstyle' } def ENV = System.getenv() -class Globals { - static def baseVersion = "0.10.0" - static def mcVersion = "1.14.4" - static def yarnVersion = "+build.16" -} -version = Globals.baseVersion //+ "+" + (ENV.BUILD_NUMBER ? ("build." + ENV.BUILD_NUMBER) : "local") + "-" + getBranch() +version = project.baseVersion //+ "+" + (ENV.BUILD_NUMBER ? ("build." + ENV.BUILD_NUMBER) : "local") + "-" + getBranch() logger.lifecycle("Building Patchwork: " + version) @@ -44,86 +40,6 @@ def getBranch() { return branch.substring(branch.lastIndexOf("/") + 1) } -allprojects { - apply plugin: 'checkstyle' - apply plugin: 'maven-publish' - apply plugin: 'fabric-loom' - apply plugin: 'net.minecrell.licenser' - apply plugin: 'com.jfrog.bintray' - sourceCompatibility = 1.8 - targetCompatibility = 1.8 - - group = "net.patchworkmc.patchwork-api" - - loom { - shareCaches = true - } - - repositories { - maven { url 'https://dl.bintray.com/patchworkmc/Patchwork-Maven/' } - } - - dependencies { - minecraft "com.mojang:minecraft:$Globals.mcVersion" - mappings "net.fabricmc:yarn:${Globals.mcVersion}${Globals.yarnVersion}:v2" - modImplementation "net.fabricmc:fabric-loader:0.10.0+build.208" - modImplementation "net.fabricmc.fabric-api:fabric-api:0.15.1+build.260-1.14" - - implementation 'net.patchworkmc:patchwork-eventbus:2.0.1:all' - implementation 'com.google.code.findbugs:jsr305:3.0.2' - - // For EventBus - implementation 'net.jodah:typetools:0.6.0' - } - - configurations { - dev - } - - jar { - classifier = "dev" - } - - afterEvaluate { - remapJar { - input = file("${project.buildDir}/libs/$archivesBaseName-${version}-dev.jar") - archiveName = "${archivesBaseName}-${version}.jar" - } - - artifacts { - dev file: file("${project.buildDir}/libs/$archivesBaseName-${version}-dev.jar"), type: "jar", builtBy: jar - } - - processResources { - inputs.property "version", project.version - - from(sourceSets.main.resources.srcDirs) { - include "fabric.mod.json" - expand "version": project.version - } - - from(sourceSets.main.resources.srcDirs) { - exclude "fabric.mod.json" - } - } - - license { - header rootProject.file('HEADER') - include '**/*.java' - } - } - - task sourcesJar(type: Jar, dependsOn: classes) { - classifier = 'sources' - from sourceSets.main.allSource - } - - checkstyle { - configFile = rootProject.file("checkstyle.xml") - toolVersion = '8.36.2' - } -} - javadoc { options.memberLevel = "PACKAGE" allprojects.each { @@ -132,61 +48,6 @@ javadoc { classpath = sourceSets.main.compileClasspath } -subprojects { - task remapMavenJar(type: Copy, dependsOn: remapJar) { - afterEvaluate { - from("${project.buildDir}/libs/$archivesBaseName-${version}.jar") - into("${project.buildDir}/libs/") - rename {String fn -> "$archivesBaseName-${version}-maven.jar"} - } - } - - publishing { - publications { - create("${archivesBaseName}_mavenJava", MavenPublication) { - afterEvaluate { - artifact(file("${project.buildDir}/libs/$archivesBaseName-${version}-maven.jar")) { - builtBy remapMavenJar - } - artifact(sourcesJar) { - builtBy remapSourcesJar - } - } - } - } - } - - bintray { - user = project.hasProperty('bintrayUser') ? project.getProperty('bintrayUser') : System.getenv('bintray_user') - key = project.hasProperty('bintrayKey') ? project.getProperty('bintrayKey') : System.getenv('bintray_key') - publish = true - override = true - publications = ["${archivesBaseName}_mavenJava"] - pkg { - repo = project.bintrayRepo - name = archivesBaseName - user = bintray.user - userOrg = project.repoOwner - licenses = [project.codeLicense] - desc = project.description - websiteUrl = "https://github.com/${project.repoOwner}/${project.repoName}" - issueTrackerUrl = "https://github.com/${project.repoOwner}/${project.repoName}/issues" - vcsUrl = "https://github.com/${project.repoOwner}/${project.repoName}.git" - publicDownloadNumbers = true - - githubRepo = "${project.repoOwner}/${project.repoName}" - version { - name = project.version - released = new Date() - } - } - } - - javadoc.enabled = false -} - -subprojects.each { bintrayUpload.dependsOn("${it.path}:bintrayUpload") } - bintray { user = project.hasProperty('bintrayUser') ? project.getProperty('bintrayUser') : System.getenv('bintray_user') key = project.hasProperty('bintrayKey') ? project.getProperty('bintrayKey') : System.getenv('bintray_key') @@ -247,8 +108,6 @@ publishing { } task licenseFormatAll -subprojects {p -> licenseFormatAll.dependsOn("${p.path}:licenseFormat")} -subprojects.each {remapJar.dependsOn("${it.path}:remapJar")} repositories { flatDir { @@ -259,15 +118,8 @@ repositories { } dependencies { - afterEvaluate { - subprojects.each { - compile project(path: ":${it.name}", configuration: "dev") - include project("${it.name}:") - } - } - - minecraft "com.mojang:minecraft:$Globals.mcVersion" - mappings "net.fabricmc:yarn:${Globals.mcVersion}${Globals.yarnVersion}:v2" + minecraft "com.mojang:minecraft:$project.mcVersion" + mappings "net.fabricmc:yarn:${project.mcVersion}${project.yarnVersion}:v2" modImplementation "net.fabricmc:fabric-loader:0.10.0+build.208" modImplementation "net.fabricmc.fabric-api:fabric-api:0.15.1+build.260-1.14" @@ -277,10 +129,6 @@ dependencies { include 'net.patchworkmc:patchwork-eventbus:2.0.0:all' } -loom { - shareCaches = true -} - task copyIdeaFiles(type: Copy) { if (file(".idea/").exists()) { diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle new file mode 100644 index 00000000..2c53070b --- /dev/null +++ b/buildSrc/build.gradle @@ -0,0 +1,17 @@ +plugins { + id 'groovy-gradle-plugin' +} + +repositories { + mavenCentral() + maven { url 'https://dl.bintray.com/patchworkmc/Patchwork-Maven/' } + maven { + name = 'Fabric' + url = 'https://maven.fabricmc.net/' + } + mavenLocal() +} + +dependencies { + implementation 'net.fabricmc:fabric-loom:0.5-SNAPSHOT' +} diff --git a/buildSrc/src/main/groovy/patchwork-api.checkstyle.gradle b/buildSrc/src/main/groovy/patchwork-api.checkstyle.gradle new file mode 100644 index 00000000..c710cdb7 --- /dev/null +++ b/buildSrc/src/main/groovy/patchwork-api.checkstyle.gradle @@ -0,0 +1,8 @@ +plugins { + id 'checkstyle' +} + +checkstyle { + configFile = rootProject.file("checkstyle.xml") + toolVersion = '8.36.2' +} diff --git a/buildSrc/src/main/groovy/patchwork-api.module-conventions.gradle b/buildSrc/src/main/groovy/patchwork-api.module-conventions.gradle new file mode 100644 index 00000000..5e0fd410 --- /dev/null +++ b/buildSrc/src/main/groovy/patchwork-api.module-conventions.gradle @@ -0,0 +1,77 @@ +plugins { +// id 'java' +// id 'eclipse' +// id 'idea' + id 'maven-publish' + id 'fabric-loom' + id 'net.minecrell.licenser' //version '0.4.1' + id 'com.jfrog.bintray' //version '1.8.4' +} + +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + +group = "net.patchworkmc.patchwork-api" + +loom { + shareCaches = true +} + +repositories { + maven { url 'https://dl.bintray.com/patchworkmc/Patchwork-Maven/' } +} + +dependencies { + minecraft "com.mojang:minecraft:$rootProject.mcVersion" + mappings "net.fabricmc:yarn:${rootProject.mcVersion}${rootProject.yarnVersion}:v2" + modImplementation "net.fabricmc:fabric-loader:0.10.0+build.208" + modImplementation "net.fabricmc.fabric-api:fabric-api:0.15.1+build.260-1.14" + + implementation 'net.patchworkmc:patchwork-eventbus:2.0.1:all' + implementation 'com.google.code.findbugs:jsr305:3.0.2' + + // For EventBus + implementation 'net.jodah:typetools:0.6.0' +} + +configurations { + dev +} + +jar { + classifier = "dev" +} + +afterEvaluate { + remapJar { + input = file("${project.buildDir}/libs/$archivesBaseName-${version}-dev.jar") + archiveName = "${archivesBaseName}-${version}.jar" + } + + artifacts { + dev file: file("${project.buildDir}/libs/$archivesBaseName-${version}-dev.jar"), type: "jar", builtBy: jar + } + + processResources { + inputs.property "version", project.version + + from(project.sourceSets.main.resources.srcDirs) { + include "fabric.mod.json" + expand "version": project.version + } + + from(project.sourceSets.main.resources.srcDirs) { + exclude "fabric.mod.json" + } + } + + license { + header rootProject.file('HEADER') + include '**/*.java' + } +} + +task sourcesJar(type: Jar, dependsOn: classes) { + classifier = 'sources' + from project.sourceSets.main.allSource +} diff --git a/buildSrc/src/main/groovy/patchwork-api.submodule-conventions.gradle b/buildSrc/src/main/groovy/patchwork-api.submodule-conventions.gradle new file mode 100644 index 00000000..b0a1fb14 --- /dev/null +++ b/buildSrc/src/main/groovy/patchwork-api.submodule-conventions.gradle @@ -0,0 +1,4 @@ +plugins { + id 'patchwork-api.checkstyle' + id 'patchwork-api.submodule-noprocess' +} diff --git a/buildSrc/src/main/groovy/patchwork-api.submodule-noprocess.gradle b/buildSrc/src/main/groovy/patchwork-api.submodule-noprocess.gradle new file mode 100644 index 00000000..9be3e522 --- /dev/null +++ b/buildSrc/src/main/groovy/patchwork-api.submodule-noprocess.gradle @@ -0,0 +1,67 @@ +plugins { + id 'patchwork-api.module-conventions' +} + +task remapMavenJar(type: Copy, dependsOn: remapJar) { + afterEvaluate { + from("${project.buildDir}/libs/$archivesBaseName-${version}.jar") + into("${project.buildDir}/libs/") + rename {String fn -> "$archivesBaseName-${version}-maven.jar"} + } +} + +publishing { + publications { + create("${archivesBaseName}_mavenJava", MavenPublication) { + afterEvaluate { + artifact(file("${project.buildDir}/libs/$archivesBaseName-${version}-maven.jar")) { + builtBy remapMavenJar + } + artifact(sourcesJar) { + builtBy remapSourcesJar + } + } + } + } +} + +bintray { + user = project.hasProperty('bintrayUser') ? project.getProperty('bintrayUser') : System.getenv('bintray_user') + key = project.hasProperty('bintrayKey') ? project.getProperty('bintrayKey') : System.getenv('bintray_key') + publish = true + override = true + publications = ["${archivesBaseName}_mavenJava"] + pkg { + repo = project.bintrayRepo + name = archivesBaseName + user = bintray.user + userOrg = project.repoOwner + licenses = [project.codeLicense] + desc = project.description + websiteUrl = "https://github.com/${project.repoOwner}/${project.repoName}" + issueTrackerUrl = "https://github.com/${project.repoOwner}/${project.repoName}/issues" + vcsUrl = "https://github.com/${project.repoOwner}/${project.repoName}.git" + publicDownloadNumbers = true + + githubRepo = "${project.repoOwner}/${project.repoName}" + version { + name = project.version + released = new Date() + } + } +} + +rootProject.bintrayUpload.dependsOn(bintrayUpload) + +javadoc.enabled = false + +rootProject.licenseFormatAll.dependsOn(licenseFormat) + +rootProject.remapJar.dependsOn(remapJar) + +rootProject.dependencies { + afterEvaluate { + compile project(path: ":${project.name}", configuration: "dev") + include project(":${project.name}:") + } +} diff --git a/gradle.properties b/gradle.properties index 68fb2e1c..e0eb03ab 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,3 +7,8 @@ repoName=patchwork-api repoOwner=patchworkmc bintrayRepo=Patchwork-Maven codeLicense=LGPL-2.1 + + +baseVersion = 0.10.0 +mcVersion = 1.14.4 +yarnVersion = +build.16 diff --git a/patchwork-api-base/build.gradle b/patchwork-api-base/build.gradle index b6e5b010..0772bde7 100644 --- a/patchwork-api-base/build.gradle +++ b/patchwork-api-base/build.gradle @@ -1,2 +1,7 @@ +plugins { + id 'patchwork-api.submodule-noprocess' + id 'patchwork-api.checkstyle' +} + archivesBaseName = "patchwork-api-base" version = getSubprojectVersion(project, "0.1.1") diff --git a/patchwork-api-base/src/main/java/net/patchworkmc/annotations/GodClass.java b/patchwork-api-base/src/main/java/net/patchworkmc/annotations/GodClass.java new file mode 100644 index 00000000..3def8ff8 --- /dev/null +++ b/patchwork-api-base/src/main/java/net/patchworkmc/annotations/GodClass.java @@ -0,0 +1,60 @@ +/* + * Minecraft Forge, Patchwork Project + * Copyright (c) 2016-2020, 2019-2020 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.patchworkmc.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.lang.model.element.Modifier; + +/** + * Decorator for elements present in a "god class". + */ +@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.TYPE }) +@Retention(RetentionPolicy.CLASS) +public @interface GodClass { + /** + * Fully qualified name of the targeted god class + ':' + the name of the element. + * e.g. "net.minecraftforge.common.ForgeHooks:onLivingUpdate" + * + * @return FQN of target class + element name. + */ + String value(); + + /** + * Modifiers for the target generated element. + * + * @return the modifiers that should be used when generating the element on the target class + */ + Modifier[] modifiers() default { Modifier.PUBLIC }; + + /** + * Decorator for constructors that should be generated in an inner class. + */ + @Target({ ElementType.CONSTRUCTOR }) + public @interface Constructor { + /** + * @return the modifiers that should be used when generating the constructor on the target inner class + */ + Modifier[] value() default { Modifier.PUBLIC }; + } +} diff --git a/patchwork-biomes/build.gradle b/patchwork-biomes/build.gradle index ede250ae..a4a5f148 100644 --- a/patchwork-biomes/build.gradle +++ b/patchwork-biomes/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-biomes" version = getSubprojectVersion(project, "0.3.1") diff --git a/patchwork-capabilities/build.gradle b/patchwork-capabilities/build.gradle index 86d756b2..cc258104 100644 --- a/patchwork-capabilities/build.gradle +++ b/patchwork-capabilities/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-capabilities" version = getSubprojectVersion(project, "0.5.0") diff --git a/patchwork-capabilities/src/main/java/net/patchworkmc/impl/capability/CapabilityEvents.java b/patchwork-capabilities/src/main/java/net/patchworkmc/impl/capability/CapabilityEvents.java index 42794d67..88613abe 100644 --- a/patchwork-capabilities/src/main/java/net/patchworkmc/impl/capability/CapabilityEvents.java +++ b/patchwork-capabilities/src/main/java/net/patchworkmc/impl/capability/CapabilityEvents.java @@ -26,9 +26,12 @@ import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.event.AttachCapabilitiesEvent; +import net.patchworkmc.annotations.GodClass; + public class CapabilityEvents { // This is less restrictive than Forge's implementation, since patchwork can't make vanilla extend stuff at random. @SuppressWarnings("unchecked") + @GodClass("net.minecraftforge.event.ForgeEventFactory:gatherCapabilities") @Nullable public static CapabilityDispatcher gatherCapabilities(Class type, T provider, @Nullable ICapabilityProvider parent) { AttachCapabilitiesEvent event = new AttachCapabilitiesEvent((Class) type, provider); @@ -40,4 +43,10 @@ public static CapabilityDispatcher gatherCapabilities(Class typ return null; } } + + @GodClass("net.minecraftforge.event.ForgeEventFactory:gatherCapabilities") + @Nullable + public static CapabilityDispatcher gatherCapabilities(Class type, T provider) { + return gatherCapabilities(type, provider, null); + } } diff --git a/patchwork-data-generators/build.gradle b/patchwork-data-generators/build.gradle index a11d767d..4dbda3d4 100644 --- a/patchwork-data-generators/build.gradle +++ b/patchwork-data-generators/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-data-generators" version = getSubprojectVersion(project, "0.3.1") diff --git a/patchwork-dispatcher/build.gradle b/patchwork-dispatcher/build.gradle index d373ad5a..8bcb369b 100644 --- a/patchwork-dispatcher/build.gradle +++ b/patchwork-dispatcher/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-dispatcher" version = getSubprojectVersion(project, "0.5.0") diff --git a/patchwork-enum-hacks/build.gradle b/patchwork-enum-hacks/build.gradle index 3d1c94d8..f9d084c2 100644 --- a/patchwork-enum-hacks/build.gradle +++ b/patchwork-enum-hacks/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-enum-hacks" version = getSubprojectVersion(project, "0.3.1") diff --git a/patchwork-events-entity/build.gradle b/patchwork-events-entity/build.gradle index 6b25c101..bb51bfda 100644 --- a/patchwork-events-entity/build.gradle +++ b/patchwork-events-entity/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-events-entity" version = getSubprojectVersion(project, "0.7.0") diff --git a/patchwork-events-entity/src/main/java/net/patchworkmc/impl/event/entity/EntityEvents.java b/patchwork-events-entity/src/main/java/net/patchworkmc/impl/event/entity/EntityEvents.java index 39fc5e20..ec33c5b6 100644 --- a/patchwork-events-entity/src/main/java/net/patchworkmc/impl/event/entity/EntityEvents.java +++ b/patchwork-events-entity/src/main/java/net/patchworkmc/impl/event/entity/EntityEvents.java @@ -22,6 +22,8 @@ import java.util.List; import java.util.Collection; +import javax.annotation.Nullable; + import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.extensions.IForgeItem; import net.minecraftforge.event.entity.EntityEvent; @@ -76,11 +78,13 @@ import net.fabricmc.fabric.api.event.player.UseBlockCallback; import net.fabricmc.fabric.api.event.player.UseItemCallback; +import net.patchworkmc.annotations.GodClass; import net.patchworkmc.mixin.event.entity.StorageMinecartEntityAccessor; public class EntityEvents implements ModInitializer { private static final Logger LOGGER = LogManager.getLogger("patchwork-events-entity"); + @GodClass("net.minecraftforge.common.ForgeHooks:onInteractEntity") public static ActionResult onInteractEntity(PlayerEntity player, Entity entity, Hand hand) { PlayerInteractEvent.EntityInteract event = new PlayerInteractEvent.EntityInteract(player, hand, entity); @@ -89,10 +93,12 @@ public static ActionResult onInteractEntity(PlayerEntity player, Entity entity, return event.isCanceled() ? event.getCancellationResult() : null; } + @GodClass("net.minecraftforge.common.ForgeHooks:onLivingDeath") public static boolean onLivingDeath(LivingEntity entity, DamageSource src) { return MinecraftForge.EVENT_BUS.post(new LivingDeathEvent(entity, src)); } + @GodClass("net.minecraftforge.common.ForgeHooks:onLivingUpdate") public static boolean onLivingUpdateEvent(LivingEntity entity) { return MinecraftForge.EVENT_BUS.post(new LivingEvent.LivingUpdateEvent(entity)); } @@ -113,29 +119,47 @@ public static boolean onLivingAttack(LivingEntity entity, DamageSource src, floa return MinecraftForge.EVENT_BUS.post(new LivingAttackEvent(entity, src, damage)); } + // TODO: forge calls the equivilant to this in LivingEntity, but patchwork only calls the equivilant to onPlayerAttack + @GodClass("net.minecraftforge.common.ForgeHooks:onLivingAttack") + public static boolean forgehooks$onLivingAttack(LivingEntity entity, DamageSource src, float amount) { + return entity instanceof PlayerEntity || forgehooks$onPlayerAttack(entity, src, amount); + } + + @GodClass("net.minecraftforge.common.ForgeHooks:onPlayerAttack") + public static boolean forgehooks$onPlayerAttack(LivingEntity entity, DamageSource src, float amount) { + return !onLivingAttack(entity, src, amount); + } + + @GodClass("net.minecraftforge.common.ForgeHooks:onLivingSetAttackTarget") public static void onLivingSetAttackTarget(LivingEntity entity, LivingEntity target) { MinecraftForge.EVENT_BUS.post(new LivingSetAttackTargetEvent(entity, target)); } + @GodClass("net.minecraftforge.common.ForgeHooks:onLivingHurt") public static float onLivingHurt(LivingEntity entity, DamageSource src, float damage) { LivingHurtEvent event = new LivingHurtEvent(entity, src, damage); return MinecraftForge.EVENT_BUS.post(event) ? 0 : event.getAmount(); } + @Nullable + @GodClass("net.minecraftforge.common.ForgeHooks:onLivingFall") public static float[] onLivingFall(LivingEntity entity, float distance, float damageMultiplier) { LivingFallEvent event = new LivingFallEvent(entity, distance, damageMultiplier); return MinecraftForge.EVENT_BUS.post(event) ? null : new float[]{ event.getDistance(), event.getDamageMultiplier() }; } + @GodClass("net.minecraftforge.event.ForgeEventFactory:onPlayerFall") public static void onFlyablePlayerFall(PlayerEntity player, float distance, float damageMultiplier) { MinecraftForge.EVENT_BUS.post(new PlayerFlyableFallEvent(player, distance, damageMultiplier)); } + @GodClass("net.minecraftforge.common.ForgeHooks:onLivingDamage") public static float onLivingDamage(LivingEntity entity, DamageSource src, float damage) { LivingDamageEvent event = new LivingDamageEvent(entity, src, damage); return MinecraftForge.EVENT_BUS.post(event) ? 0 : event.getAmount(); } + @GodClass("net.minecraftforge.common.ForgeHooks:onLivingDrops") public static boolean onLivingDrops(LivingEntity entity, DamageSource source, Collection drops, int lootingLevel, boolean recentlyHit) { return MinecraftForge.EVENT_BUS.post(new LivingDropsEvent(entity, source, drops, lootingLevel, recentlyHit)); } @@ -146,6 +170,7 @@ public static float getEyeHeight(Entity entity, EntityPose pose, EntityDimension return event.getNewHeight(); } + @GodClass("net.minecraftforge.event.ForgeEventFactory:canEntitySpawn") public static Result canEntitySpawn(MobEntity entity, IWorld world, double x, double y, double z, MobSpawnerLogic spawner, SpawnType spawnType) { if (entity == null) { return Result.DEFAULT; @@ -156,6 +181,13 @@ public static Result canEntitySpawn(MobEntity entity, IWorld world, double x, do return event.getResult(); } + @GodClass("net.minecraftforge.common.ForgeHooks:canEntitySpawn") + public static int forgehooks$canEntitySpawn(MobEntity entity, IWorld world, double x, double y, double z, MobSpawnerLogic spawner, SpawnType spawnReason) { + Event.Result res = canEntitySpawn(entity, world, x, y, z, null, spawnReason); + return res == Event.Result.DEFAULT ? 0 : res == Event.Result.DENY ? -1 : 1; + } + + @GodClass("net.minecraftforge.event.ForgeEventFactory:canEntitySpawnSpawner") public static boolean canEntitySpawnFromSpawner(MobEntity entity, World world, double x, double y, double z, MobSpawnerLogic spawner) { Result result = canEntitySpawn(entity, world, x, y, z, spawner, SpawnType.SPAWNER); @@ -178,10 +210,12 @@ public static boolean canEntitySpawnNaturally(MobEntity entity, IWorld world, do } } + @GodClass("net.minecraftforge.event.ForgeEventFactory:doSpecialSpawn") public static boolean doSpecialSpawn(MobEntity entity, IWorld world, double x, double y, double z, MobSpawnerLogic spawner, SpawnType spawnType) { return MinecraftForge.EVENT_BUS.post(new LivingSpawnEvent.SpecialSpawn(entity, world, x, y, z, spawner, spawnType)); } + @GodClass("net.minecraftforge.common.ForgeHooks:onPlayerAttackTarget") public static boolean attackEntity(PlayerEntity player, Entity target) { if (MinecraftForge.EVENT_BUS.post(new AttackEntityEvent(player, target))) { return false; @@ -202,26 +236,32 @@ public static void onItemTooltip(ItemStack itemStack, PlayerEntity entityPlayer, MinecraftForge.EVENT_BUS.post(new ItemTooltipEvent(itemStack, entityPlayer, list, flags)); } + @GodClass("net.minecraftforge.event.ForgeEventFactory:onAnimalTame") public static boolean onAnimalTame(AnimalEntity animal, PlayerEntity tamer) { return MinecraftForge.EVENT_BUS.post(new AnimalTameEvent(animal, tamer)); } + @GodClass("net.minecraftforge.event.ForgeEventFactory:onProjectileImpact") public static boolean onProjectileImpact(Entity entity, HitResult ray) { return MinecraftForge.EVENT_BUS.post(new ProjectileImpactEvent(entity, ray)); } + @GodClass("net.minecraftforge.event.ForgeEventFactory:onProjectileImpact") public static boolean onProjectileImpact(ProjectileEntity arrow, HitResult ray) { return MinecraftForge.EVENT_BUS.post(new ProjectileImpactEvent.Arrow(arrow, ray)); } + @GodClass("net.minecraftforge.event.ForgeEventFactory:onProjectileImpact") public static boolean onProjectileImpact(ExplosiveProjectileEntity fireball, HitResult ray) { return MinecraftForge.EVENT_BUS.post(new ProjectileImpactEvent.Fireball(fireball, ray)); } + @GodClass("net.minecraftforge.event.ForgeEventFactory:onProjectileImpact") public static boolean onProjectileImpact(ThrownEntity throwable, HitResult ray) { return MinecraftForge.EVENT_BUS.post(new ProjectileImpactEvent.Throwable(throwable, ray)); } + @GodClass("net.minecraftforge.common.ForgeHooks:onTravelToDimension") public static boolean onTravelToDimension(Entity entity, DimensionType dimensionType) { EntityTravelToDimensionEvent event = new EntityTravelToDimensionEvent(entity, dimensionType); boolean result = !MinecraftForge.EVENT_BUS.post(event); diff --git a/patchwork-events-entity/src/main/java/net/patchworkmc/impl/event/entity/PlayerEvents.java b/patchwork-events-entity/src/main/java/net/patchworkmc/impl/event/entity/PlayerEvents.java index 9e908e1e..7523ccc0 100644 --- a/patchwork-events-entity/src/main/java/net/patchworkmc/impl/event/entity/PlayerEvents.java +++ b/patchwork-events-entity/src/main/java/net/patchworkmc/impl/event/entity/PlayerEvents.java @@ -30,31 +30,40 @@ import net.minecraft.item.ItemStack; import net.minecraft.world.dimension.DimensionType; +import net.patchworkmc.annotations.GodClass; + public class PlayerEvents { + @GodClass("net.minecraftforge.fml.hooks.BasicEventHooks:firePlayerChangedDimensionEvent") public static void firePlayerChangedDimensionEvent(PlayerEntity player, DimensionType fromDim, DimensionType toDim) { MinecraftForge.EVENT_BUS.post(new PlayerEvent.PlayerChangedDimensionEvent(player, fromDim, toDim)); } + @GodClass("net.minecraftforge.fml.hooks.BasicEventHooks:firePlayerLoggedIn") public static void firePlayerLoggedIn(PlayerEntity player) { MinecraftForge.EVENT_BUS.post(new PlayerEvent.PlayerLoggedInEvent(player)); } + @GodClass("net.minecraftforge.fml.hooks.BasicEventHooks:firePlayerLoggedOut") public static void firePlayerLoggedOut(PlayerEntity player) { MinecraftForge.EVENT_BUS.post(new PlayerEvent.PlayerLoggedOutEvent(player)); } + @GodClass("net.minecraftforge.fml.hooks.BasicEventHooks:firePlayerRespawnEvent") public static void firePlayerRespawnEvent(PlayerEntity player, boolean alive) { MinecraftForge.EVENT_BUS.post(new PlayerEvent.PlayerRespawnEvent(player, alive)); } + @GodClass("net.minecraftforge.fml.hooks.BasicEventHooks:firePlayerItemPickupEvent") public static void firePlayerItemPickupEvent(PlayerEntity player, ItemEntity item, ItemStack clone) { MinecraftForge.EVENT_BUS.post(new PlayerEvent.ItemPickupEvent(player, item, clone)); } + @GodClass("net.minecraftforge.fml.hooks.BasicEventHooks:firePlayerCraftingEvent") public static void firePlayerCraftingEvent(PlayerEntity player, ItemStack crafted, Inventory craftMatrix) { MinecraftForge.EVENT_BUS.post(new PlayerEvent.ItemCraftedEvent(player, crafted, craftMatrix)); } + @GodClass("net.minecraftforge.fml.hooks.BasicEventHooks:firePlayerSmeltedEvent") public static void firePlayerSmeltedEvent(PlayerEntity player, ItemStack smelted) { MinecraftForge.EVENT_BUS.post(new PlayerEvent.ItemSmeltedEvent(player, smelted)); } @@ -63,6 +72,7 @@ public static void firePlayerSmeltedEvent(PlayerEntity player, ItemStack smelted * * @return -1 if the event was canceled, 0 if the event was denied or had no result set, and 1 if the event was allowed */ + @GodClass("net.minecraftforge.event.ForgeEventFactory:onItemPickup") public static int onItemPickup(PlayerEntity player, ItemEntity entityItem) { Event event = new EntityItemPickupEvent(player, entityItem); if (MinecraftForge.EVENT_BUS.post(event)) return -1; diff --git a/patchwork-events-input/build.gradle b/patchwork-events-input/build.gradle index a863d4c1..e8b52676 100644 --- a/patchwork-events-input/build.gradle +++ b/patchwork-events-input/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-events-input" version = getSubprojectVersion(project, "0.3.1") diff --git a/patchwork-events-input/src/main/java/net/patchworkmc/impl/event/input/InputEvents.java b/patchwork-events-input/src/main/java/net/patchworkmc/impl/event/input/InputEvents.java index 65a2951b..08fc1058 100644 --- a/patchwork-events-input/src/main/java/net/patchworkmc/impl/event/input/InputEvents.java +++ b/patchwork-events-input/src/main/java/net/patchworkmc/impl/event/input/InputEvents.java @@ -25,23 +25,28 @@ import net.minecraft.client.Mouse; +import net.patchworkmc.annotations.GodClass; import net.patchworkmc.api.input.ForgeMouse; public class InputEvents { + @GodClass("net.minecraftforge.client.ForgeHooksClient:fireMouseInput") public static void fireMouseInput(int button, int action, int mods) { MinecraftForge.EVENT_BUS.post(new InputEvent.MouseInputEvent(button, action, mods)); } + @GodClass("net.minecraftforge.client.ForgeHooksClient:fireKeyInput") public static void fireKeyInput(int key, int scanCode, int action, int modifiers) { MinecraftForge.EVENT_BUS.post(new InputEvent.KeyInputEvent(key, scanCode, action, modifiers)); } + @GodClass("net.minecraftforge.client.ForgeHooksClient:onMouseScroll") public static boolean onMouseScroll(Mouse mouseHelper, double scrollDelta) { final Event event = new InputEvent.MouseScrollEvent(scrollDelta, mouseHelper.wasLeftButtonClicked(), ((ForgeMouse) mouseHelper).isMiddleDown(), mouseHelper.wasRightButtonClicked(), mouseHelper.getX(), mouseHelper.getY()); return MinecraftForge.EVENT_BUS.post(event); } + @GodClass("net.minecraftforge.client.ForgeHooksClient:onRawMouseClicked") public static boolean onRawMouseClicked(int button, int action, int mods) { return MinecraftForge.EVENT_BUS.post(new InputEvent.RawMouseEvent(button, action, mods)); } diff --git a/patchwork-events-lifecycle/build.gradle b/patchwork-events-lifecycle/build.gradle index b3413f5b..ff6ba9b8 100644 --- a/patchwork-events-lifecycle/build.gradle +++ b/patchwork-events-lifecycle/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-events-lifecycle" version = getSubprojectVersion(project, "0.3.2") diff --git a/patchwork-events-lifecycle/src/main/java/net/patchworkmc/impl/event/lifecycle/LifecycleEvents.java b/patchwork-events-lifecycle/src/main/java/net/patchworkmc/impl/event/lifecycle/LifecycleEvents.java index b1bc0e4e..f8dd67e2 100644 --- a/patchwork-events-lifecycle/src/main/java/net/patchworkmc/impl/event/lifecycle/LifecycleEvents.java +++ b/patchwork-events-lifecycle/src/main/java/net/patchworkmc/impl/event/lifecycle/LifecycleEvents.java @@ -46,6 +46,8 @@ import net.fabricmc.fabric.api.event.world.WorldTickCallback; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; +import net.patchworkmc.annotations.GodClass; + public class LifecycleEvents implements ModInitializer { public static void fireWorldTickEvent(TickEvent.Phase phase, World world) { LogicalSide side = world.isClient() ? LogicalSide.CLIENT : LogicalSide.SERVER; @@ -140,4 +142,56 @@ public void onInitialize() { ServerTickEvents.START_SERVER_TICK.register(server -> fireServerTickEvent(TickEvent.Phase.START)); ServerTickEvents.END_SERVER_TICK.register(server -> fireServerTickEvent(TickEvent.Phase.END)); } + + // wrappers called by generated god class + + @GodClass("net.minecraftforge.fml.hooks.BasicEventHooks:onPlayerPreTick") + public static void onPlayerPreTick(PlayerEntity player) { + firePlayerTickEvent(TickEvent.Phase.START, player); + } + + @GodClass("net.minecraftforge.fml.hooks.BasicEventHooks:onPlayerPostTick") + public static void onPlayerPostTick(PlayerEntity player) { + firePlayerTickEvent(TickEvent.Phase.END, player); + } + + @GodClass("net.minecraftforge.fml.hooks.BasicEventHooks:onPreWorldTick") + public static void onPreWorldTick(World world) { + fireWorldTickEvent(TickEvent.Phase.START, world); + } + + @GodClass("net.minecraftforge.fml.hooks.BasicEventHooks:onPostWorldTick") + public static void onPostWorldTick(World world) { + fireWorldTickEvent(TickEvent.Phase.END, world); + } + + @GodClass("net.minecraftforge.fml.hooks.BasicEventHooks:onPreClientTick") + public static void onPreClientTick() { + fireClientTickEvent(TickEvent.Phase.START); + } + + @GodClass("net.minecraftforge.fml.hooks.BasicEventHooks:onPostClientTick") + public static void onPostClientTick() { + fireClientTickEvent(TickEvent.Phase.END); + } + + @GodClass("net.minecraftforge.fml.hooks.BasicEventHooks:onPreServerTick") + public static void onPreServerTick() { + fireServerTickEvent(TickEvent.Phase.START); + } + + @GodClass("net.minecraftforge.fml.hooks.BasicEventHooks:onPostServerTick") + public static void onPostServerTick() { + fireServerTickEvent(TickEvent.Phase.END); + } + + @GodClass("net.minecraftforge.fml.hooks.BasicEventHooks:onRenderTickStart") + public static void onRenderTickStart(float timer) { + fireRenderTickEvent(TickEvent.Phase.START, timer); + } + + @GodClass("net.minecraftforge.fml.hooks.BasicEventHooks:onRenderTickEnd") + public static void onRenderTickEnd(float timer) { + fireRenderTickEvent(TickEvent.Phase.END, timer); + } } diff --git a/patchwork-events-rendering/build.gradle b/patchwork-events-rendering/build.gradle index ddf53656..bc293d49 100644 --- a/patchwork-events-rendering/build.gradle +++ b/patchwork-events-rendering/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-client-colors" version = getSubprojectVersion(project, "0.3.3") diff --git a/patchwork-events-rendering/src/main/java/net/patchworkmc/impl/event/render/RenderEvents.java b/patchwork-events-rendering/src/main/java/net/patchworkmc/impl/event/render/RenderEvents.java index c00d6e3f..9850c80d 100644 --- a/patchwork-events-rendering/src/main/java/net/patchworkmc/impl/event/render/RenderEvents.java +++ b/patchwork-events-rendering/src/main/java/net/patchworkmc/impl/event/render/RenderEvents.java @@ -37,19 +37,25 @@ import net.minecraft.util.hit.EntityHitResult; import net.minecraft.util.hit.HitResult; +import net.patchworkmc.annotations.GodClass; + public class RenderEvents { + @GodClass("net.minecraftforge.client.ForgeHooksClient:onBlockColorsInit") public static void onBlockColorsInit(BlockColors blockColors) { ModLoader.get().postEvent(new ColorHandlerEvent.Block(blockColors)); } + @GodClass("net.minecraftforge.client.ForgeHooksClient:onItemColorsInit") public static void onItemColorsInit(ItemColors itemColors, BlockColors blockColors) { ModLoader.get().postEvent(new ColorHandlerEvent.Item(itemColors, blockColors)); } + @GodClass("net.minecraftforge.client.ForgeHooksClient:onTextureStitchedPre") public static void onTextureStitchPre(SpriteAtlasTexture spriteAtlasTexture, Set set) { ModLoader.get().postEvent(new TextureStitchEvent.Pre(spriteAtlasTexture, set)); } + @GodClass("net.minecraftforge.client.ForgeHooksClient:onTextureStitchedPost") public static void onTextureStitchPost(SpriteAtlasTexture spriteAtlasTexture) { ModLoader.get().postEvent(new TextureStitchEvent.Post(spriteAtlasTexture)); } diff --git a/patchwork-events-world/build.gradle b/patchwork-events-world/build.gradle index 4f1515d5..31caf270 100644 --- a/patchwork-events-world/build.gradle +++ b/patchwork-events-world/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-events-world" version = getSubprojectVersion(project, "0.5.0") diff --git a/patchwork-events-world/src/main/java/net/patchworkmc/impl/event/world/WorldEvents.java b/patchwork-events-world/src/main/java/net/patchworkmc/impl/event/world/WorldEvents.java index bb4e65ae..c41c7e42 100644 --- a/patchwork-events-world/src/main/java/net/patchworkmc/impl/event/world/WorldEvents.java +++ b/patchwork-events-world/src/main/java/net/patchworkmc/impl/event/world/WorldEvents.java @@ -48,6 +48,8 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.ServerChunkEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents; +import net.patchworkmc.annotations.GodClass; + public class WorldEvents implements ModInitializer { public static boolean onCreateWorldSpawn(IWorld world, LevelInfo settings) { return MinecraftForge.EVENT_BUS.post(new WorldEvent.CreateSpawnPosition(world, settings)); @@ -109,6 +111,7 @@ public void onInitialize() { ServerChunkEvents.CHUNK_UNLOAD.register((server, chunk) -> MinecraftForge.EVENT_BUS.post(new ChunkEvent.Unload(chunk))); } + @GodClass("net.minecraftforge.event.ForgeEventFactory:saplingGrowTree") public static boolean onSaplingGrowTree(IWorld world, Random rand, BlockPos pos) { SaplingGrowTreeEvent event = new SaplingGrowTreeEvent(world, rand, pos); MinecraftForge.EVENT_BUS.post(event); diff --git a/patchwork-extensions-bakedmodel/build.gradle b/patchwork-extensions-bakedmodel/build.gradle index 37e07886..10c20dfa 100644 --- a/patchwork-extensions-bakedmodel/build.gradle +++ b/patchwork-extensions-bakedmodel/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-extensions-bakedmodel" version = getSubprojectVersion(project, "0.1.0") diff --git a/patchwork-extensions-block/build.gradle b/patchwork-extensions-block/build.gradle index 94d52bfd..9ac286cb 100644 --- a/patchwork-extensions-block/build.gradle +++ b/patchwork-extensions-block/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-extensions-block" version = getSubprojectVersion(project, "0.5.0") diff --git a/patchwork-extensions-block/src/main/java/net/patchworkmc/impl/extensions/block/BlockHarvestManager.java b/patchwork-extensions-block/src/main/java/net/patchworkmc/impl/extensions/block/BlockHarvestManager.java index 51fa3f4c..37f46850 100644 --- a/patchwork-extensions-block/src/main/java/net/patchworkmc/impl/extensions/block/BlockHarvestManager.java +++ b/patchwork-extensions-block/src/main/java/net/patchworkmc/impl/extensions/block/BlockHarvestManager.java @@ -48,6 +48,8 @@ import net.minecraft.world.GameMode; import net.minecraft.world.World; +import net.patchworkmc.annotations.GodClass; + public class BlockHarvestManager { private static final ThreadLocal> expDrops = ThreadLocal.withInitial(Stack::new); @@ -114,6 +116,7 @@ public static boolean isVanillaBlock(Block block) { * Called by Mixin and ForgeHooks. * @return experience dropped, -1 = block breaking is cancelled. */ + @GodClass("net.minecraftforge.common.ForgeHooks:onBlockBreakEvent") public static int onBlockBreakEvent(World world, GameMode gameMode, ServerPlayerEntity player, BlockPos pos) { // Logic from tryHarvestBlock for pre-canceling the event boolean preCancelEvent = false; @@ -166,12 +169,14 @@ public static int onBlockBreakEvent(World world, GameMode gameMode, ServerPlayer // TODO: Leaving this unfired is intentional. See: https://github.com/MinecraftForge/MinecraftForge/issues/5828 @Deprecated + @GodClass("net.minecraftforge.event.ForgeEventFactory:fireBlockHarvesting") public static float fireBlockHarvesting(DefaultedList drops, World world, BlockPos pos, BlockState state, int fortune, float dropChance, boolean silkTouch, PlayerEntity player) { BlockEvent.HarvestDropsEvent event = new BlockEvent.HarvestDropsEvent(world, pos, state, fortune, dropChance, drops, player, silkTouch); MinecraftForge.EVENT_BUS.post(event); return event.getDropChance(); } + @GodClass("net.minecraftforge.common.ForgeHooks:onFarmlandTrample") public static boolean onFarmlandTrample(World world, BlockPos pos, BlockState state, float fallDistance, Entity entity) { // TODO: In forge, the possibility of trampling is handled by IForgeEntity.canTrample // Maybe there's a good way to reconcile that to not break any Fabric mods trying to diff --git a/patchwork-extensions-blockentity/build.gradle b/patchwork-extensions-blockentity/build.gradle index 5e3d9979..44e9dd84 100644 --- a/patchwork-extensions-blockentity/build.gradle +++ b/patchwork-extensions-blockentity/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-extensions-blockentity" version = getSubprojectVersion(project, "0.2.0") diff --git a/patchwork-extensions-entity/build.gradle b/patchwork-extensions-entity/build.gradle index e8588585..3500ffe2 100644 --- a/patchwork-extensions-entity/build.gradle +++ b/patchwork-extensions-entity/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-extensions-entity" version = getSubprojectVersion(project, "0.1.0") diff --git a/patchwork-extensions-item/build.gradle b/patchwork-extensions-item/build.gradle index c2c1b90f..c97c5e6f 100644 --- a/patchwork-extensions-item/build.gradle +++ b/patchwork-extensions-item/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-extensions-item" version = getSubprojectVersion(project, "0.4.1") diff --git a/patchwork-extensions-item/src/main/java/net/patchworkmc/impl/extensions/item/PatchworkArmorItemHandler.java b/patchwork-extensions-item/src/main/java/net/patchworkmc/impl/extensions/item/PatchworkArmorItemHandler.java index 1f8ab4dc..e34fa387 100644 --- a/patchwork-extensions-item/src/main/java/net/patchworkmc/impl/extensions/item/PatchworkArmorItemHandler.java +++ b/patchwork-extensions-item/src/main/java/net/patchworkmc/impl/extensions/item/PatchworkArmorItemHandler.java @@ -32,6 +32,8 @@ import net.minecraft.util.Identifier; import net.minecraft.world.World; +import net.patchworkmc.annotations.GodClass; + public interface PatchworkArmorItemHandler { @SuppressWarnings("rawtypes") BipedEntityModel getArmorModelHook(LivingEntity entity, ItemStack itemStack, EquipmentSlot slot, BipedEntityModel model); @@ -41,12 +43,14 @@ public interface PatchworkArmorItemHandler { /** * Called by mixins(MixinArmorFeatureRenderer) and ForgeHooksClient. */ + @GodClass("net.minecraftforge.client.ForgeHooksClient:getArmorTexture") static String patchwork$getArmorTexture(Entity entity, ItemStack itemStack, String defaultTexture, EquipmentSlot slot, String type) { IForgeItem forgeItem = (IForgeItem) itemStack.getItem(); String result = forgeItem.getArmorTexture(itemStack, entity, slot, type); return result != null ? result : defaultTexture; } + @GodClass("net.minecraftforge.client.ForgeHooksClient:getArmorModel") static > A patchwork$getArmorModel(LivingEntity entityLiving, ItemStack itemStack, EquipmentSlot slot, A _default) { IForgeItem forgeItem = (IForgeItem) itemStack.getItem(); A model = forgeItem.getArmorModel(entityLiving, itemStack, slot, _default); diff --git a/patchwork-extensions-shearing/build.gradle b/patchwork-extensions-shearing/build.gradle index 8cca74d3..92f308d2 100644 --- a/patchwork-extensions-shearing/build.gradle +++ b/patchwork-extensions-shearing/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-extensions-shearing" version = getSubprojectVersion(project, "0.3.1") diff --git a/patchwork-extensions/build.gradle b/patchwork-extensions/build.gradle index d9b090fe..a888956e 100644 --- a/patchwork-extensions/build.gradle +++ b/patchwork-extensions/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-extensions" version = getSubprojectVersion(project, "0.3.1") diff --git a/patchwork-fake-players/build.gradle b/patchwork-fake-players/build.gradle index 4819591f..19fffe6c 100644 --- a/patchwork-fake-players/build.gradle +++ b/patchwork-fake-players/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-fake-players" version = getSubprojectVersion(project, "0.1.1") diff --git a/patchwork-fml/build.gradle b/patchwork-fml/build.gradle index 717a1a56..20d0fe36 100644 --- a/patchwork-fml/build.gradle +++ b/patchwork-fml/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-fml" version = getSubprojectVersion(project, "0.5.0") diff --git a/patchwork-god-classes-processor/build.gradle b/patchwork-god-classes-processor/build.gradle new file mode 100644 index 00000000..f054e4df --- /dev/null +++ b/patchwork-god-classes-processor/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'java' +} + +group 'net.patchworkmc.patchwork-api' +version '0.10.0' + +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + +repositories { + mavenCentral() +} + +dependencies { + implementation project(path: ':patchwork-api-base', configuration: 'dev') + implementation 'com.squareup:javapoet:1.13.0' + implementation 'javax.annotation:javax.annotation-api:1.3.2' +} diff --git a/patchwork-god-classes-processor/src/main/java/net/patchworkmc/processor/god_classes/GodClassProcessor.java b/patchwork-god-classes-processor/src/main/java/net/patchworkmc/processor/god_classes/GodClassProcessor.java new file mode 100644 index 00000000..8e202cfc --- /dev/null +++ b/patchwork-god-classes-processor/src/main/java/net/patchworkmc/processor/god_classes/GodClassProcessor.java @@ -0,0 +1,222 @@ +package net.patchworkmc.processor.god_classes; + +import java.io.IOException; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.annotation.Generated; +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.Filer; +import javax.annotation.processing.Messager; +import javax.annotation.processing.ProcessingEnvironment; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.annotation.processing.SupportedSourceVersion; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.TypeElement; +import javax.tools.Diagnostic; +import javax.tools.StandardLocation; + +import com.squareup.javapoet.AnnotationSpec; +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.CodeBlock; +import com.squareup.javapoet.FieldSpec; +import com.squareup.javapoet.JavaFile; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterSpec; +import com.squareup.javapoet.TypeName; +import com.squareup.javapoet.TypeSpec; +import com.squareup.javapoet.TypeVariableName; + +import net.patchworkmc.annotations.GodClass; + +@SupportedAnnotationTypes({ "net.patchworkmc.annotations.GodClass", "net.patchworkmc.annotations.GodClass.Constructor" }) +@SupportedSourceVersion(SourceVersion.RELEASE_8) +public class GodClassProcessor extends AbstractProcessor { + public GodClassProcessor() { + super(); + } + + private HashMap generated_classes; + + private Messager messager; + private Filer filer; + + @Override + public synchronized void init(ProcessingEnvironment processingEnvironment) { + super.init(processingEnvironment); + + generated_classes = new HashMap<>(); + messager = processingEnvironment.getMessager(); + filer = processingEnvironment.getFiler(); + } + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + for ( Element element : roundEnv.getElementsAnnotatedWith(GodClass.class) ) { + messager.printMessage(Diagnostic.Kind.NOTE, "found @GodClass at " + element); + if (!element.getModifiers().containsAll(Arrays.asList(Modifier.STATIC, Modifier.PUBLIC))) { + messager.printMessage( + Diagnostic.Kind.ERROR, + "Annotated item must be public static", + element + ); + + continue; + } + + // TODO: getAnnotationsByType? aka, supporting multiple annotations on the same element + GodClass target = element.getAnnotation(GodClass.class); + String[] split = target.value().split(":"); + if (split.length < 2) { + messager.printMessage( + Diagnostic.Kind.ERROR, + "GodClass annotation missing element name", + element + ); + continue; + } else if (split.length > 2) { + messager.printMessage( + Diagnostic.Kind.ERROR, + "GodClass annotation has too many seperators indicating element name", + element + ); + continue; + } + + // This is fine unless we ever stop following java conventions for package and class names. + ClassName target_class_name = ClassName.bestGuess(split[0]); + String target_item_name = split[1]; + + TypeSpec.Builder target_class = generated_classes.computeIfAbsent(target_class_name, TypeSpec::classBuilder); + target_class.addOriginatingElement(element); + + // TODO: no annotations are currently passed through, pass (some of them?) through. + ElementKind kind = element.getKind(); + if (kind.isField()) { + ClassName source_class = ClassName.get((TypeElement) element.getEnclosingElement()); + target_class.addField( + FieldSpec.builder(TypeName.get(element.asType()), target_item_name, Modifier.STATIC) + .addModifiers(target.modifiers()) + .initializer( + CodeBlock.of("$T.$N", source_class, element.getSimpleName()) + ).build() + ); + } else if (kind == ElementKind.METHOD) { + ExecutableElement exec_element = (ExecutableElement) element; + ClassName source_class = ClassName.get((TypeElement) element.getEnclosingElement()); + + TypeName return_type = TypeName.get(exec_element.getReturnType()); + List parameters = exec_element.getParameters().stream() + .map(ParameterSpec::get) + .collect(Collectors.toList()); + List typeVars = exec_element.getTypeParameters().stream() + .map(TypeVariableName::get) + .collect(Collectors.toList()); + + CodeBlock.Builder body = CodeBlock.builder(); + + if (return_type != TypeName.VOID) { + body.add("return "); + } + + // I would specify type parameters as part of this but java always infers them, so nevermind. + body.add( + "$T.$N($L)", + source_class, + exec_element.getSimpleName(), + parameters.stream() + .map(param -> CodeBlock.of("$N", param)) + .collect(CodeBlock.joining(", ")) + ); + + target_class.addMethod( + MethodSpec.methodBuilder(target_item_name) + .addModifiers(Modifier.STATIC) + .addModifiers(target.modifiers()) + .addTypeVariables(typeVars) + .addParameters(parameters) + .returns(return_type) + .addStatement(body.build()) + .build() + ); + } else if (kind.isClass()) { + TypeElement typeElement = (TypeElement)element; + target_class.addType( + TypeSpec.classBuilder(target_class_name.nestedClass(target_item_name)) + .addModifiers(Modifier.STATIC) + .addModifiers(target.modifiers()) + .superclass(typeElement.asType()) + .addMethods( + typeElement.getEnclosedElements().stream() + .filter(e -> e.getKind() == ElementKind.CONSTRUCTOR && e.getAnnotation(GodClass.Constructor.class) != null) + .map(e -> (ExecutableElement)e) + .map(e -> { + List params = e.getParameters().stream() + .map(ParameterSpec::get) + .collect(Collectors.toList()); + + return MethodSpec.constructorBuilder() + .addModifiers(e.getAnnotation(GodClass.Constructor.class).value()) + .addParameters(params) + .addStatement( + "super$L", + params.stream() + .map(p -> CodeBlock.of("$N", p)) + .collect(CodeBlock.joining(", ", "(", ")")) + ).build(); + }).collect(Collectors.toList()) + ).build() + ); + } else { + messager.printMessage( + Diagnostic.Kind.ERROR, + "Annotated item must be a method, field, or class", + element + ); + } + } + + if (roundEnv.processingOver()) { + Filer filer = processingEnv.getFiler(); + + for (Map.Entry entry: generated_classes.entrySet()) { + messager.printMessage( + Diagnostic.Kind.NOTE, + "Writing generated source for: " + entry.getKey().canonicalName() + ); + + try { + TypeSpec clazz = entry.getValue() + //.addModifiers(Modifier.PUBLIC) + .addAnnotation(AnnotationSpec.builder(Generated.class) + .addMember("value", "$S", "net.patchworkmc.processor.god_classes.GodClassProcessor") + .build() + ).build(); + JavaFile.builder(entry.getKey().packageName(), clazz) + // I would add the license here, but the style wouldn't be correct so meh + //.addFileComment() + .build() + .writeTo(filer); + } catch (IOException e) { + messager.printMessage( + Diagnostic.Kind.ERROR, + "Failed to write generated source: " + e + ); + } + } + } + + return true; + } +} diff --git a/patchwork-god-classes-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/patchwork-god-classes-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor new file mode 100644 index 00000000..5c89fbeb --- /dev/null +++ b/patchwork-god-classes-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -0,0 +1 @@ +net.patchworkmc.processor.god_classes.GodClassProcessor diff --git a/patchwork-god-classes/README.md b/patchwork-god-classes/README.md index 2d17ec0e..acaf0f10 100644 --- a/patchwork-god-classes/README.md +++ b/patchwork-god-classes/README.md @@ -10,3 +10,4 @@ Therefore, this module exists to dispatch calls to these classes to the disperat ## TODO * Implement the methods on these classes that are actually already implemented in Patchwork. + * ForgeHooks.onInteractEntityAt diff --git a/patchwork-god-classes/build.gradle b/patchwork-god-classes/build.gradle index b831c326..197a0bd8 100644 --- a/patchwork-god-classes/build.gradle +++ b/patchwork-god-classes/build.gradle @@ -1,17 +1,69 @@ +import org.gradle.internal.jvm.Jvm + +import java.util.stream.Collectors + +plugins { + id 'patchwork-api.submodule-noprocess' + id 'patchwork-api.checkstyle' +} + archivesBaseName = "patchwork-god-classes" version = getSubprojectVersion(project, "0.4.0") +configurations { + processImpl + implementation.extendsFrom(processImpl) +} + dependencies { implementation project(path: ':patchwork-api-base', configuration: 'dev') - implementation project(path: ':patchwork-fml', configuration: 'dev') - implementation project(path: ':patchwork-capabilities', configuration: 'dev') - implementation project(path: ':patchwork-events-entity', configuration: 'dev') - implementation project(path: ':patchwork-events-input', configuration: 'dev') - implementation project(path: ':patchwork-events-lifecycle', configuration: 'dev') - implementation project(path: ':patchwork-events-rendering', configuration: 'dev') - implementation project(path: ':patchwork-events-world', configuration: 'dev') - implementation project(path: ':patchwork-extensions-block', configuration: 'dev') - implementation project(path: ':patchwork-extensions-item', configuration: 'dev') - implementation project(path: ':patchwork-loot', configuration: 'dev') - implementation project(path: ':patchwork-networking', configuration: 'dev') + implementation 'javax.annotation:javax.annotation-api:1.3.2' + // TODO: make submodules do this in submodule-conventions? + processImpl project(path: ':patchwork-fml', configuration: 'dev') + processImpl project(path: ':patchwork-capabilities', configuration: 'dev') + processImpl project(path: ':patchwork-events-entity', configuration: 'dev') + processImpl project(path: ':patchwork-events-input', configuration: 'dev') + processImpl project(path: ':patchwork-events-lifecycle', configuration: 'dev') + processImpl project(path: ':patchwork-events-rendering', configuration: 'dev') + processImpl project(path: ':patchwork-events-world', configuration: 'dev') + processImpl project(path: ':patchwork-extensions-block', configuration: 'dev') + processImpl project(path: ':patchwork-extensions-item', configuration: 'dev') + processImpl project(path: ':patchwork-loot', configuration: 'dev') + processImpl project(path: ':patchwork-networking', configuration: 'dev') + + annotationProcessor project(':patchwork-god-classes-processor') } + + +compileJava.options.compilerArgumentProviders.add(new CommandLineArgumentProvider() { + @Override + Iterable asArguments() { + configurations.getByName('processImpl').files.stream().flatMap { + def classes = [] + zipTree(it).matching { + include "net/patchworkmc/**/*.class" + exclude "net/patchworkmc/mixin/**" + // TODO: revisit if we ever want to delegate to another forge class + // currently this fails because NightCoreConfig isn't on the classpath + // i.e. we'll eventually need to depend on the dependencies of our dependencies. + //include "net/minecraftforge/**/*.class" + }.visit { FileVisitDetails file -> + if (file.directory) { + return; + } + String clazz = file.getRelativePath().toString(); + classes.add(clazz.substring(0, clazz.length() - ".class".length()).replace('/', '.')) + } + + return classes.stream() + }.collect(Collectors.toSet()) + } +}) + +// force use of CommandLineJavaCompiler +// NOTE: Jvm.current and Jvm.getJavaHome are internal apis, but have been around unchanged for 10 years, +// so this will probably work on any version of gradle we're likely to use. +compileJava.options.fork(javaHome: Jvm.current().getJavaHome()) +// just put a file in source so it tries to compile *something* +// TODO: remove this if/when we have a non-generated class file in patchwork-god-classes +compileJava.source("src/main/resources/fabric.mod.json") diff --git a/patchwork-god-classes/src/main/java/net/minecraftforge/client/ForgeHooksClient.java b/patchwork-god-classes/src/main/java/net/minecraftforge/client/ForgeHooksClient.java deleted file mode 100644 index 213953b4..00000000 --- a/patchwork-god-classes/src/main/java/net/minecraftforge/client/ForgeHooksClient.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Minecraft Forge, Patchwork Project - * Copyright (c) 2016-2020, 2019-2020 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.client; - -import java.util.Set; - -import net.minecraft.client.color.block.BlockColors; -import net.minecraft.client.color.item.ItemColors; -import net.minecraft.client.render.entity.model.BipedEntityModel; -import net.minecraft.client.texture.SpriteAtlasTexture; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EquipmentSlot; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.util.Identifier; -import net.minecraft.client.Mouse; - -import net.patchworkmc.impl.event.input.InputEvents; -import net.patchworkmc.impl.event.render.RenderEvents; -import net.patchworkmc.impl.extensions.item.PatchworkArmorItemHandler; - -/* - * Note: this class is intended for mod use only, to dispatch to the implementations kept in their own modules. - * Do not keep implementation details here, methods should be thin wrappers around methods in other modules. - */ -public class ForgeHooksClient { - public static String getArmorTexture(Entity entity, ItemStack armor, String defaultTexture, EquipmentSlot slot, String type) { - return PatchworkArmorItemHandler.patchwork$getArmorTexture(entity, armor, defaultTexture, slot, type); - } - - public static > A getArmorModel(LivingEntity livingEntity, ItemStack itemStack, EquipmentSlot slot, A defaultModel) { - return PatchworkArmorItemHandler.patchwork$getArmorModel(livingEntity, itemStack, slot, defaultModel); - } - - public static void fireMouseInput(int button, int action, int mods) { - InputEvents.fireMouseInput(button, action, mods); - } - - public static void fireKeyInput(int key, int scanCode, int action, int modifiers) { - InputEvents.fireKeyInput(key, scanCode, action, modifiers); - } - - public static boolean onMouseScroll(Mouse mouseHelper, double scrollDelta) { - return InputEvents.onMouseScroll(mouseHelper, scrollDelta); - } - - public static boolean onRawMouseClicked(int button, int action, int mods) { - return InputEvents.onRawMouseClicked(button, action, mods); - } - - public static void onBlockColorsInit(BlockColors blockColors) { - RenderEvents.onBlockColorsInit(blockColors); - } - - public static void onItemColorsInit(ItemColors itemColors, BlockColors blockColors) { - RenderEvents.onItemColorsInit(itemColors, blockColors); - } - - public static void onTextureStitchedPre(SpriteAtlasTexture map, Set resourceLocations) { - RenderEvents.onTextureStitchPre(map, resourceLocations); - } - - public static void onTextureStitchedPost(SpriteAtlasTexture map) { - RenderEvents.onTextureStitchPost(map); - } -} diff --git a/patchwork-god-classes/src/main/java/net/minecraftforge/common/ForgeHooks.java b/patchwork-god-classes/src/main/java/net/minecraftforge/common/ForgeHooks.java deleted file mode 100644 index 14d37442..00000000 --- a/patchwork-god-classes/src/main/java/net/minecraftforge/common/ForgeHooks.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Minecraft Forge, Patchwork Project - * Copyright (c) 2016-2020, 2019-2020 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.common; - -import java.util.Collection; - -import javax.annotation.Nullable; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; -import net.minecraftforge.event.ForgeEventFactory; -import net.minecraftforge.eventbus.api.Event; - -import net.minecraft.block.BlockState; -import net.minecraft.world.dimension.DimensionType; -import net.minecraft.entity.Entity; -import net.minecraft.entity.ItemEntity; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.SpawnType; -import net.minecraft.entity.damage.DamageSource; -import net.minecraft.entity.mob.MobEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.loot.LootManager; -import net.minecraft.loot.LootTable; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.GameMode; -import net.minecraft.world.IWorld; -import net.minecraft.world.MobSpawnerLogic; -import net.minecraft.world.World; - -import net.patchworkmc.impl.event.entity.EntityEvents; -import net.patchworkmc.impl.extensions.block.BlockHarvestManager; -import net.patchworkmc.impl.loot.LootHooks; - -/* - * Note: this class is intended for mod use only, to dispatch to the implementations kept in their own modules. - * Do not keep implementation details here, methods should be thin wrappers around methods in other modules. - */ -public class ForgeHooks { - public static int canEntitySpawn(MobEntity entity, IWorld world, double x, double y, double z, MobSpawnerLogic spawner, SpawnType spawnReason) { - Event.Result res = ForgeEventFactory.canEntitySpawn(entity, world, x, y, z, null, spawnReason); - return res == Event.Result.DEFAULT ? 0 : res == Event.Result.DENY ? -1 : 1; - } - - // TODO: onInteractEntityAt - - public static ActionResult onInteractEntity(PlayerEntity player, Entity entity, Hand hand) { - return EntityEvents.onInteractEntity(player, entity, hand); - } - - public static boolean onLivingDeath(LivingEntity entity, DamageSource src) { - return EntityEvents.onLivingDeath(entity, src); - } - - public static boolean onLivingUpdate(LivingEntity entity) { - return EntityEvents.onLivingUpdateEvent(entity); - } - - // TODO: forge calls the equivilant to this in LivingEntity, but patchwork only calls the equivilant to onPlayerAttack - public static boolean onLivingAttack(LivingEntity entity, DamageSource src, float amount) { - return entity instanceof PlayerEntity || onPlayerAttack(entity, src, amount); - } - - public static boolean onPlayerAttack(LivingEntity entity, DamageSource src, float amount) { - return !EntityEvents.onLivingAttack(entity, src, amount); - } - - // optifine wants this? O.o - public static void onLivingSetAttackTarget(LivingEntity entity, LivingEntity target) { - EntityEvents.onLivingSetAttackTarget(entity, target); - } - - public static float onLivingHurt(LivingEntity entity, DamageSource src, float amount) { - return EntityEvents.onLivingHurt(entity, src, amount); - } - - @Nullable - public static float[] onLivingFall(LivingEntity entity, float distance, float damageMultiplier) { - return EntityEvents.onLivingFall(entity, distance, damageMultiplier); - } - - public static float onLivingDamage(LivingEntity entity, DamageSource src, float amount) { - return EntityEvents.onLivingDamage(entity, src, amount); - } - - public static boolean onLivingDrops(LivingEntity entity, DamageSource source, Collection drops, int lootingLevel, boolean recentlyHit) { - return EntityEvents.onLivingDrops(entity, source, drops, lootingLevel, recentlyHit); - } - - public static boolean onPlayerAttackTarget(PlayerEntity player, Entity target) { - return EntityEvents.attackEntity(player, target); - } - - public static boolean onTravelToDimension(Entity entity, DimensionType dimensionType) { - return EntityEvents.onTravelToDimension(entity, dimensionType); - } - - public static int onBlockBreakEvent(World world, GameMode gameType, ServerPlayerEntity entityPlayer, BlockPos pos) { - return BlockHarvestManager.onBlockBreakEvent(world, gameType, entityPlayer, pos); - } - - @SuppressWarnings({ "rawtypes", "unused" }) - private static ThreadLocal lootContext = LootHooks.lootContext; - - // Need to have the class here to make some mod hacks work - public static class LootTableContext extends LootHooks.LootTableContext { - private LootTableContext(Identifier name, boolean custom) { - super(name, custom); - } - } - - @Nullable - public static LootTable loadLootTable(Gson gson, Identifier name, JsonObject data, boolean custom, LootManager lootTableManager) { - return LootHooks.loadLootTable(gson, name, data, custom, lootTableManager); - } - - public static String readPoolName(JsonObject json) { - return LootHooks.readPoolName(json); - } - - public static boolean onFarmlandTrample(World world, BlockPos pos, BlockState state, float fallDistance, Entity entity) { - return BlockHarvestManager.onFarmlandTrample(world, pos, state, fallDistance, entity); - } -} diff --git a/patchwork-god-classes/src/main/java/net/minecraftforge/event/ForgeEventFactory.java b/patchwork-god-classes/src/main/java/net/minecraftforge/event/ForgeEventFactory.java deleted file mode 100644 index 3812397d..00000000 --- a/patchwork-god-classes/src/main/java/net/minecraftforge/event/ForgeEventFactory.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Minecraft Forge, Patchwork Project - * Copyright (c) 2016-2020, 2019-2020 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.event; - -import java.util.Random; - -import javax.annotation.Nullable; - -import net.minecraftforge.common.capabilities.CapabilityDispatcher; -import net.minecraftforge.common.capabilities.ICapabilityProvider; -import net.minecraftforge.eventbus.api.Event; - -import net.minecraft.entity.SpawnType; -import net.minecraft.entity.mob.MobEntity; -import net.minecraft.entity.passive.AnimalEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.Entity; -import net.minecraft.entity.ItemEntity; -import net.minecraft.entity.projectile.ExplosiveProjectileEntity; -import net.minecraft.entity.projectile.ProjectileEntity; -import net.minecraft.entity.thrown.ThrownEntity; -import net.minecraft.loot.LootManager; -import net.minecraft.loot.LootTable; -import net.minecraft.util.Identifier; -import net.minecraft.util.hit.HitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.IWorld; -import net.minecraft.world.MobSpawnerLogic; -import net.minecraft.world.World; -import net.minecraft.block.BlockState; -import net.minecraft.item.ItemStack; -import net.minecraft.util.DefaultedList; - -import net.patchworkmc.impl.capability.CapabilityEvents; -import net.patchworkmc.impl.event.entity.EntityEvents; -import net.patchworkmc.impl.event.entity.PlayerEvents; -import net.patchworkmc.impl.event.loot.LootEvents; -import net.patchworkmc.impl.event.world.WorldEvents; -import net.patchworkmc.impl.extensions.block.BlockHarvestManager; - -/* - * Note: this class is intended for mod use only, to dispatch to the implementations kept in their own modules. - * Do not keep implementation details here, methods should be thin wrappers around methods in other modules. - */ -public class ForgeEventFactory { - @Nullable - public static CapabilityDispatcher gatherCapabilities(Class type, T provider) { - return gatherCapabilities(type, provider, null); - } - - @Nullable - public static CapabilityDispatcher gatherCapabilities(Class type, T provider, @Nullable ICapabilityProvider parent) { - return CapabilityEvents.gatherCapabilities(type, provider, parent); - } - - public static Event.Result canEntitySpawn(MobEntity entity, IWorld world, double x, double y, double z, MobSpawnerLogic spawner, SpawnType spawnReason) { - return EntityEvents.canEntitySpawn(entity, world, x, y, z, spawner, spawnReason); - } - - public static boolean canEntitySpawnSpawner(MobEntity entity, World world, float x, float y, float z, MobSpawnerLogic spawner) { - return EntityEvents.canEntitySpawnFromSpawner(entity, world, x, y, z, spawner); - } - - public static void onPlayerFall(PlayerEntity player, float distance, float multiplier) { - EntityEvents.onFlyablePlayerFall(player, distance, multiplier); - } - - public static boolean doSpecialSpawn(MobEntity entity, World world, float x, float y, float z, MobSpawnerLogic spawner, SpawnType spawnReason) { - return EntityEvents.doSpecialSpawn(entity, world, x, y, z, spawner, spawnReason); - } - - public static LootTable loadLootTable(Identifier name, LootTable table, LootManager lootTableManager) { - return LootEvents.loadLootTable(name, table, lootTableManager); - } - - public static boolean saplingGrowTree(IWorld world, Random rand, BlockPos pos) { - return WorldEvents.onSaplingGrowTree(world, rand, pos); - } - - // Forge might remove BlockEvent.HarvestDropsEvent, which is replaced by the new loot modifier. - @Deprecated - public static float fireBlockHarvesting(DefaultedList drops, World world, BlockPos pos, BlockState state, int fortune, float dropChance, boolean silkTouch, PlayerEntity player) { - return BlockHarvestManager.fireBlockHarvesting(drops, world, pos, state, fortune, dropChance, silkTouch, player); - } - - public static boolean onAnimalTame(AnimalEntity animal, PlayerEntity tamer) { - return EntityEvents.onAnimalTame(animal, tamer); - } - - public static boolean onProjectileImpact(Entity entity, HitResult ray) { - return EntityEvents.onProjectileImpact(entity, ray); - } - - public static boolean onProjectileImpact(ProjectileEntity arrow, HitResult ray) { - return EntityEvents.onProjectileImpact(arrow, ray); - } - - public static boolean onProjectileImpact(ExplosiveProjectileEntity fireball, HitResult ray) { - return EntityEvents.onProjectileImpact(fireball, ray); - } - - public static boolean onProjectileImpact(ThrownEntity throwable, HitResult ray) { - return EntityEvents.onProjectileImpact(throwable, ray); - } - - public static int onItemPickup(ItemEntity item, PlayerEntity player) { - return PlayerEvents.onItemPickup(player, item); - } -} diff --git a/patchwork-god-classes/src/main/java/net/minecraftforge/fml/client/ClientHooks.java b/patchwork-god-classes/src/main/java/net/minecraftforge/fml/client/ClientHooks.java deleted file mode 100644 index cb087f9c..00000000 --- a/patchwork-god-classes/src/main/java/net/minecraftforge/fml/client/ClientHooks.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Minecraft Forge, Patchwork Project - * Copyright (c) 2016-2020, 2019-2020 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.client; - -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.network.ClientPlayerInteractionManager; -import net.minecraft.network.ClientConnection; - -import net.patchworkmc.impl.networking.ClientNetworkingEvents; - -public class ClientHooks { - public static void firePlayerLogin(final ClientPlayerInteractionManager interactionManager, final ClientPlayerEntity player, final ClientConnection clientConnection) { - ClientNetworkingEvents.firePlayerLogin(interactionManager, player, clientConnection); - } - - public static void firePlayerLogout(final ClientPlayerInteractionManager interactionManager, final ClientPlayerEntity player) { - ClientNetworkingEvents.firePlayerLogout(interactionManager, player); - } - - public static void firePlayerRespawn(final ClientPlayerInteractionManager interactionManager, final ClientPlayerEntity oldPlayer, final ClientPlayerEntity newPlayer, final ClientConnection clientConnection) { - ClientNetworkingEvents.firePlayerRespawn(interactionManager, oldPlayer, newPlayer, clientConnection); - } -} diff --git a/patchwork-god-classes/src/main/java/net/minecraftforge/fml/hooks/BasicEventHooks.java b/patchwork-god-classes/src/main/java/net/minecraftforge/fml/hooks/BasicEventHooks.java deleted file mode 100644 index 8dce0091..00000000 --- a/patchwork-god-classes/src/main/java/net/minecraftforge/fml/hooks/BasicEventHooks.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Minecraft Forge, Patchwork Project - * Copyright (c) 2016-2020, 2019-2020 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.hooks; - -import net.minecraftforge.event.TickEvent; - -import net.minecraft.entity.ItemEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.inventory.Inventory; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import net.minecraft.world.dimension.DimensionType; - -import net.patchworkmc.impl.event.entity.PlayerEvents; -import net.patchworkmc.impl.event.lifecycle.LifecycleEvents; - -/* - * Note: this class is intended for mod use only, to dispatch to the implementations kept in their own modules. - * Do not keep implementation details here, methods should be thin wrappers around methods in other modules. - */ -public class BasicEventHooks { - public static void firePlayerChangedDimensionEvent(PlayerEntity player, DimensionType fromDim, DimensionType toDim) { - PlayerEvents.firePlayerChangedDimensionEvent(player, fromDim, toDim); - } - - public static void firePlayerLoggedIn(PlayerEntity player) { - PlayerEvents.firePlayerLoggedIn(player); - } - - public static void firePlayerLoggedOut(PlayerEntity player) { - PlayerEvents.firePlayerLoggedOut(player); - } - - public static void firePlayerRespawnEvent(PlayerEntity player, boolean endConquered) { - PlayerEvents.firePlayerRespawnEvent(player, endConquered); - } - - public static void firePlayerItemPickupEvent(PlayerEntity player, ItemEntity item, ItemStack clone) { - PlayerEvents.firePlayerItemPickupEvent(player, item, clone); - } - - public static void firePlayerCraftingEvent(PlayerEntity player, ItemStack crafted, Inventory craftMatrix) { - PlayerEvents.firePlayerCraftingEvent(player, crafted, craftMatrix); - } - - public static void firePlayerSmeltedEvent(PlayerEntity player, ItemStack smelted) { - PlayerEvents.firePlayerSmeltedEvent(player, smelted); - } - - // TODO: onRenderTickStart - // TODO: onRenderTickEnd - - public static void onPlayerPreTick(PlayerEntity player) { - LifecycleEvents.firePlayerTickEvent(TickEvent.Phase.START, player); - } - - public static void onPlayerPostTick(PlayerEntity player) { - LifecycleEvents.firePlayerTickEvent(TickEvent.Phase.END, player); - } - - public static void onPreWorldTick(World world) { - LifecycleEvents.fireWorldTickEvent(TickEvent.Phase.START, world); - } - - public static void onPostWorldTick(World world) { - LifecycleEvents.fireWorldTickEvent(TickEvent.Phase.END, world); - } - - public static void onPreClientTick() { - LifecycleEvents.fireClientTickEvent(TickEvent.Phase.START); - } - - public static void onPostClientTick() { - LifecycleEvents.fireClientTickEvent(TickEvent.Phase.END); - } - - public static void onPreServerTick() { - LifecycleEvents.fireServerTickEvent(TickEvent.Phase.START); - } - - public static void onPostServerTick() { - LifecycleEvents.fireServerTickEvent(TickEvent.Phase.END); - } - - public static void onRenderTickStart(float timer) { - LifecycleEvents.fireRenderTickEvent(TickEvent.Phase.START, timer); - } - - public static void onRenderTickEnd(float timer) { - LifecycleEvents.fireRenderTickEvent(TickEvent.Phase.END, timer); - } -} diff --git a/patchwork-gui/build.gradle b/patchwork-gui/build.gradle index 3e2cd99f..94ec08ae 100644 --- a/patchwork-gui/build.gradle +++ b/patchwork-gui/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-gui" version = getSubprojectVersion(project, "0.3.1") diff --git a/patchwork-items/build.gradle b/patchwork-items/build.gradle index 7a586ec2..4a26928d 100644 --- a/patchwork-items/build.gradle +++ b/patchwork-items/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-items" version = getSubprojectVersion(project, "0.1.1") diff --git a/patchwork-key-bindings/build.gradle b/patchwork-key-bindings/build.gradle index cb121cca..101f7e80 100644 --- a/patchwork-key-bindings/build.gradle +++ b/patchwork-key-bindings/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-key-bindings" version = getSubprojectVersion(project, "0.2.1") diff --git a/patchwork-level-generators/build.gradle b/patchwork-level-generators/build.gradle index 2abe1f77..579e1a5b 100644 --- a/patchwork-level-generators/build.gradle +++ b/patchwork-level-generators/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-level-generators" version = getSubprojectVersion(project, "0.3.1") diff --git a/patchwork-loot/build.gradle b/patchwork-loot/build.gradle index 1ef88065..5a554042 100644 --- a/patchwork-loot/build.gradle +++ b/patchwork-loot/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-loot" version = getSubprojectVersion(project, "0.3.1") diff --git a/patchwork-loot/src/main/java/net/patchworkmc/impl/event/loot/LootEvents.java b/patchwork-loot/src/main/java/net/patchworkmc/impl/event/loot/LootEvents.java index c732f201..190d26cf 100644 --- a/patchwork-loot/src/main/java/net/patchworkmc/impl/event/loot/LootEvents.java +++ b/patchwork-loot/src/main/java/net/patchworkmc/impl/event/loot/LootEvents.java @@ -26,7 +26,10 @@ import net.minecraft.loot.LootTable; import net.minecraft.util.Identifier; +import net.patchworkmc.annotations.GodClass; + public class LootEvents { + @GodClass("net.minecraftforge.event.ForgeEventFactory:loadLootTable") public static LootTable loadLootTable(Identifier name, LootTable table, LootManager manager) { LootTableLoadEvent event = new LootTableLoadEvent(name, table, manager); diff --git a/patchwork-loot/src/main/java/net/patchworkmc/impl/loot/LootHooks.java b/patchwork-loot/src/main/java/net/patchworkmc/impl/loot/LootHooks.java index 88a5d840..f3001a50 100644 --- a/patchwork-loot/src/main/java/net/patchworkmc/impl/loot/LootHooks.java +++ b/patchwork-loot/src/main/java/net/patchworkmc/impl/loot/LootHooks.java @@ -23,6 +23,7 @@ import java.util.HashSet; import javax.annotation.Nullable; +import javax.lang.model.element.Modifier; import com.google.common.collect.Queues; import com.google.common.collect.Sets; @@ -36,13 +37,17 @@ import net.minecraft.util.Identifier; import net.minecraft.util.JsonHelper; +import net.patchworkmc.annotations.GodClass; import net.patchworkmc.impl.event.loot.LootEvents; // NOTE: this class is more or less a direct copy of parts of Forge's ForgeHooks. public class LootHooks { // Made public for Patchwork's own use + // TODO (codegen): make private in ForgeHooks + @GodClass(value = "net.minecraftforge.common.ForgeHooks:lootContext", modifiers = Modifier.PRIVATE) public static ThreadLocal> lootContext = new ThreadLocal>(); + @GodClass("net.minecraftforge.common.ForgeHooks:loadLootTable") public static LootTable loadLootTable(Gson gson, Identifier name, JsonElement data, boolean custom, LootManager lootTableManager) { Deque que = lootContext.get(); @@ -83,6 +88,7 @@ private static LootTableContext getLootTableContext() { return ctx; } + @GodClass("net.minecraftforge.common.ForgeHooks:readPoolName") public static String readPoolName(JsonObject json) { LootTableContext ctx = LootHooks.getLootTableContext(); ctx.resetPoolCtx(); @@ -105,6 +111,7 @@ public static String readPoolName(JsonObject json) { } // Made public for Patchwork's own use + @GodClass("net.minecraftforge.common.ForgeHooks:LootTableContext") public static class LootTableContext { public final Identifier name; public final boolean custom; @@ -113,6 +120,7 @@ public static class LootTableContext { public int entryCount = 0; private HashSet entryNames = Sets.newHashSet(); + @GodClass.Constructor(Modifier.PRIVATE) protected LootTableContext(Identifier name, boolean custom) { this.name = name; this.custom = custom; diff --git a/patchwork-model-loader/build.gradle b/patchwork-model-loader/build.gradle index bfc7eea6..44fe8f90 100644 --- a/patchwork-model-loader/build.gradle +++ b/patchwork-model-loader/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-model-loader" version = getSubprojectVersion(project, "0.2.3") diff --git a/patchwork-networking-messages/build.gradle b/patchwork-networking-messages/build.gradle index 53c5cb4f..82be6128 100644 --- a/patchwork-networking-messages/build.gradle +++ b/patchwork-networking-messages/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-networking-messages" version = getSubprojectVersion(project, "0.3.2") diff --git a/patchwork-networking/build.gradle b/patchwork-networking/build.gradle index 8598ae7f..67a73e6b 100644 --- a/patchwork-networking/build.gradle +++ b/patchwork-networking/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-networking" version = getSubprojectVersion(project, "0.4.0") diff --git a/patchwork-networking/src/main/java/net/patchworkmc/impl/networking/ClientNetworkingEvents.java b/patchwork-networking/src/main/java/net/patchworkmc/impl/networking/ClientNetworkingEvents.java index 2545045a..c8578624 100644 --- a/patchwork-networking/src/main/java/net/patchworkmc/impl/networking/ClientNetworkingEvents.java +++ b/patchwork-networking/src/main/java/net/patchworkmc/impl/networking/ClientNetworkingEvents.java @@ -26,15 +26,20 @@ import net.minecraft.client.network.ClientPlayerInteractionManager; import net.minecraft.network.ClientConnection; +import net.patchworkmc.annotations.GodClass; + public class ClientNetworkingEvents { + @GodClass("net.minecraftforge.fml.client.ClientHooks:firePlayerLogin") public static void firePlayerLogin(final ClientPlayerInteractionManager interactionManager, final ClientPlayerEntity player, final ClientConnection clientConnection) { MinecraftForge.EVENT_BUS.post(new ClientPlayerNetworkEvent.LoggedInEvent(interactionManager, player, clientConnection)); } + @GodClass("net.minecraftforge.fml.client.ClientHooks:firePlayerLogout") public static void firePlayerLogout(final ClientPlayerInteractionManager interactionManager, final ClientPlayerEntity player) { MinecraftForge.EVENT_BUS.post(new ClientPlayerNetworkEvent.LoggedOutEvent(interactionManager, player, player != null ? player.networkHandler != null ? player.networkHandler.getConnection() : null : null)); } + @GodClass("net.minecraftforge.fml.client.ClientHooks:firePlayerRespawn") public static void firePlayerRespawn(final ClientPlayerInteractionManager interactionManager, final ClientPlayerEntity oldPlayer, final ClientPlayerEntity newPlayer, final ClientConnection clientConnection) { MinecraftForge.EVENT_BUS.post(new ClientPlayerNetworkEvent.RespawnEvent(interactionManager, oldPlayer, newPlayer, clientConnection)); } diff --git a/patchwork-recipes/build.gradle b/patchwork-recipes/build.gradle index 4a67bc47..345b9ed2 100644 --- a/patchwork-recipes/build.gradle +++ b/patchwork-recipes/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-recipes" version = getSubprojectVersion(project, "0.3.1") diff --git a/patchwork-registries/build.gradle b/patchwork-registries/build.gradle index 24b4a453..650e3b01 100644 --- a/patchwork-registries/build.gradle +++ b/patchwork-registries/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-registries" version = getSubprojectVersion(project, "0.4.1") diff --git a/patchwork-resource/build.gradle b/patchwork-resource/build.gradle index 988ae3a3..9bf6e1dd 100644 --- a/patchwork-resource/build.gradle +++ b/patchwork-resource/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-resource" version = getSubprojectVersion(project, "0.2.1") diff --git a/patchwork-tags/build.gradle b/patchwork-tags/build.gradle index 1a57ca20..d0a92fd1 100644 --- a/patchwork-tags/build.gradle +++ b/patchwork-tags/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-tags" version = getSubprojectVersion(project, "0.1.1") diff --git a/patchwork-tooltype/build.gradle b/patchwork-tooltype/build.gradle index 180d0814..638744c7 100644 --- a/patchwork-tooltype/build.gradle +++ b/patchwork-tooltype/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-tooltype" version = getSubprojectVersion(project, "0.3.1") diff --git a/patchwork-vanilla-patches/build.gradle b/patchwork-vanilla-patches/build.gradle index b78cb526..a3cf0051 100644 --- a/patchwork-vanilla-patches/build.gradle +++ b/patchwork-vanilla-patches/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'patchwork-api.submodule-conventions' +} + archivesBaseName = "patchwork-vanilla-patches" version = getSubprojectVersion(project, "0.3.1") diff --git a/settings.gradle b/settings.gradle index f76b2991..02c20563 100644 --- a/settings.gradle +++ b/settings.gradle @@ -33,6 +33,7 @@ include 'patchwork-extensions-shearing' include 'patchwork-fake-players' include 'patchwork-fml' include 'patchwork-god-classes' +include 'patchwork-god-classes-processor' include 'patchwork-gui' include 'patchwork-items' include 'patchwork-key-bindings'