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..f3f26163 --- /dev/null +++ b/buildSrc/src/main/groovy/patchwork-api.submodule-conventions.gradle @@ -0,0 +1,8 @@ +plugins { + id 'patchwork-api.checkstyle' + id 'patchwork-api.submodule-noprocess' +} + +dependencies { + annotationProcessor project(':patchwork-god-classes-processor') +} 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..3bee7ae2 --- /dev/null +++ b/patchwork-api-base/src/main/java/net/patchworkmc/annotations/GodClass.java @@ -0,0 +1,49 @@ +/* + * 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, Modifier.STATIC }; +} 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..f7e4b597 --- /dev/null +++ b/patchwork-god-classes-processor/build.gradle @@ -0,0 +1,18 @@ +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.google.code.gson:gson:2.8.6' +} 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..758a2d29 --- /dev/null +++ b/patchwork-god-classes-processor/src/main/java/net/patchworkmc/processor/god_classes/GodClassProcessor.java @@ -0,0 +1,168 @@ +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.Set; +import java.util.stream.Collectors; + +import javax.annotation.processing.AbstractProcessor; +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.google.gson.Gson; + +import net.patchworkmc.annotations.GodClass; + +@SupportedAnnotationTypes("net.patchworkmc.annotations.GodClass") +@SupportedSourceVersion(SourceVersion.RELEASE_8) +public class GodClassProcessor extends AbstractProcessor { + public GodClassProcessor() { + super(); + } + + // static class TargetFile { +// List elements; +// } + + //JsonElement annotated_items; + private HashMap> annotated_items; + + @Override + public synchronized void init(ProcessingEnvironment processingEnvironment) { + super.init(processingEnvironment); + + annotated_items = new HashMap<>(); + } + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + Gson gson = new Gson(); + for ( Element element : roundEnv.getElementsAnnotatedWith(GodClass.class) ) { + if (!element.getModifiers().containsAll(Arrays.asList(Modifier.STATIC, Modifier.PUBLIC))) { + processingEnv.getMessager().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); + SourceElement sourceElement = new SourceElement(); + + String[] split = target.value().split(":"); + if (split.length < 2) { + processingEnv.getMessager().printMessage( + Diagnostic.Kind.ERROR, + "GodClass annotation missing element name", + element + ); + continue; + } else if (split.length > 2) { + processingEnv.getMessager().printMessage( + Diagnostic.Kind.ERROR, + "GodClass annotation has too many seperators indicating element name", + element + ); + continue; + } + + String target_class = split[0]; + sourceElement.target_name = split[1]; + + ElementKind kind = element.getKind(); + if (kind.isClass()) { + TypeElement type_element = ((TypeElement)element); + sourceElement.source_class = type_element + .getQualifiedName().toString(); + + sourceElement.constructors = type_element.getEnclosedElements().stream() + .filter(e -> e.getKind() == ElementKind.CONSTRUCTOR) + .map(e -> ((ExecutableElement)e).getParameters().stream().map(SourceElement.Arg::new).collect(Collectors.toList())) + .collect(Collectors.toList()); + } else { + sourceElement.source_name = element.getSimpleName().toString(); + try { + sourceElement.source_class = ((TypeElement)element.getEnclosingElement()) + .getQualifiedName().toString(); + } catch (ClassCastException ex) { + processingEnv.getMessager().printMessage( + Diagnostic.Kind.ERROR, + "Annotated item must be a direct member of a type", + element + ); + continue; + } + } + + sourceElement.modifiers = target.modifiers(); + + if (kind.isField()) { +// Types.direct +// element.asType().getKind(); + sourceElement.type = new SourceElement.Ty(element.asType()); + } else if (kind == ElementKind.METHOD) { + ExecutableElement exec_element = (ExecutableElement) element; + sourceElement.type = new SourceElement.Ty(exec_element.getReturnType()); + sourceElement.args = exec_element + .getParameters() + .stream() + .map(SourceElement.Arg::new) + .collect(Collectors.toList()); + + sourceElement.type_args = exec_element + .getTypeParameters() + .stream() + .map(SourceElement.TypeArg::new) + .collect(Collectors.toList()); + } else if (!kind.isClass()) { + processingEnv.getMessager().printMessage( + Diagnostic.Kind.ERROR, + "Annotated item must be a method, field, or class", + element + ); + } + + annotated_items + .computeIfAbsent(target_class, k -> new ArrayList<>()) + .add(sourceElement); + + processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "found @GodClass at " + element); + } + + if (roundEnv.processingOver()) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Writing god class info to json"); + try { + Writer writer = processingEnv.getFiler() + .createResource(StandardLocation.CLASS_OUTPUT, "", "generated/god_classes.json") + .openWriter(); + + gson.toJson(annotated_items, SourceElement.serialized_type, writer); + writer.close(); + } catch (IOException ex) { + processingEnv.getMessager().printMessage( + Diagnostic.Kind.ERROR, + "Failed to write json: " + ex + ); + } + } + + return true; + } +} diff --git a/patchwork-god-classes-processor/src/main/java/net/patchworkmc/processor/god_classes/SourceElement.java b/patchwork-god-classes-processor/src/main/java/net/patchworkmc/processor/god_classes/SourceElement.java new file mode 100644 index 00000000..2f727d62 --- /dev/null +++ b/patchwork-god-classes-processor/src/main/java/net/patchworkmc/processor/god_classes/SourceElement.java @@ -0,0 +1,104 @@ +package net.patchworkmc.processor.god_classes; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.List; +import java.util.stream.Collectors; + +import javax.lang.model.element.Modifier; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.TypeParameterElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; + +import com.google.gson.reflect.TypeToken; + +// Remember to update copy in buildSrc when modified! +public class SourceElement { + public SourceElement() {} + + // fully qualified name to class + String source_class; + // short name relative to source class + String source_name; + // short name relative to generated class + String target_name; + // element modifiers + // TODO: rework? + Modifier[] modifiers; + + List> constructors; + + // type for field, return type for method + Ty type; + // argument types for method + List args; + List type_args; + + public static class Arg { + Arg() {} + Arg(Ty ty, String n) { + type = ty; + name = n; + } + Arg(VariableElement var) { + type = new SourceElement.Ty(var.asType()); + name = var.getSimpleName().toString(); + } + + Ty type; + String name; + } + + public static class TypeArg { + TypeArg() {} + TypeArg(String n, List b) { + name = n; + bounds = b; + } + + TypeArg(TypeParameterElement elem) { + name = elem.getSimpleName().toString(); + bounds = elem.getBounds() + .stream() + .map(Ty::new) + .collect(Collectors.toList()); + } + + + String name; + List bounds; + } + + public static class Ty { + Ty() {} + + Ty(String n, List g) { + name = n; + generics = g; + } + + Ty(TypeMirror tm) { + if (tm.getKind() == TypeKind.DECLARED) { + TypeElement ty = (TypeElement)((DeclaredType)tm).asElement(); + name = ty.getQualifiedName().toString(); + //name = ty.getSimpleName().toString(); + generics = ty.getTypeParameters() + .stream() + .map(TypeArg::new).collect(Collectors.toList()); + } else { + name = tm.toString(); + } + + isPrimitive = tm.getKind().isPrimitive(); + } + + String name; + List generics; + boolean isPrimitive; + } + + public static final Type serialized_type = new TypeToken>>(){}.getType(); +} 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..e3ecebec 100644 --- a/patchwork-god-classes/build.gradle +++ b/patchwork-god-classes/build.gradle @@ -1,17 +1,67 @@ +buildscript { + repositories { + maven { + url "https://dl.bintray.com/pdvrieze/maven" + } + } + + dependencies { + classpath 'net.devrieze:gradle-codegen:0.5.11' + } +} + +plugins { + id 'patchwork-api.submodule-noprocess' +} + +apply plugin: 'net.devrieze.gradlecodegen' + archivesBaseName = "patchwork-god-classes" version = getSubprojectVersion(project, "0.4.0") +configurations { + generateImpl + implementation.extendsFrom(generateImpl) + generatorsCompile.extendsFrom(generateImpl) +} + 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') + // TODO: add to patchwork-api.submodule-conventions plugin? + generateImpl project(path: ':patchwork-fml', configuration: 'dev') + generateImpl project(path: ':patchwork-capabilities', configuration: 'dev') + generateImpl project(path: ':patchwork-events-entity', configuration: 'dev') + generateImpl project(path: ':patchwork-events-input', configuration: 'dev') + generateImpl project(path: ':patchwork-events-lifecycle', configuration: 'dev') + generateImpl project(path: ':patchwork-events-rendering', configuration: 'dev') + generateImpl project(path: ':patchwork-events-world', configuration: 'dev') + generateImpl project(path: ':patchwork-extensions-block', configuration: 'dev') + generateImpl project(path: ':patchwork-extensions-item', configuration: 'dev') + generateImpl project(path: ':patchwork-loot', configuration: 'dev') + generateImpl project(path: ':patchwork-networking', configuration: 'dev') + + generatorsCompile project(':patchwork-god-classes-processor') + generatorsCompile 'org.glassfish.jaxb:codemodel:3.0.0-M5' + generatorsCompile 'com.google.code.gson:gson:2.8.6' +} + +def annotation_stream = configurations.generateImpl.getFiles().stream().map { + println(it) + def god_class = resources.text.fromArchiveEntry(it, "generated/god_classes.json"); + if (!god_class.inputFiles.isEmpty()) { + return god_class.asReader(); + } + return null; +}.filter { + return it != null; +}; + +generate { + // plugin default is something like 'gen/main' then 'java/' + outputDir = 'build/generated/sources/god_classes/java' + dirGenerator { + outputDir = 'main/' + generator = 'net.patchworkmc.processor.god_classes.GodClassCodegen' + input = new AbstractMap.SimpleImmutableEntry(annotation_stream, rootProject.file("HEADER").text) + } } diff --git a/patchwork-god-classes/src/generators/java/net/patchworkmc/processor/god_classes/GodClassCodegen.java b/patchwork-god-classes/src/generators/java/net/patchworkmc/processor/god_classes/GodClassCodegen.java new file mode 100644 index 00000000..466f2d28 --- /dev/null +++ b/patchwork-god-classes/src/generators/java/net/patchworkmc/processor/god_classes/GodClassCodegen.java @@ -0,0 +1,201 @@ +/* + * 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.processor.god_classes; + +import java.io.File; +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import com.google.gson.Gson; +import com.sun.codemodel.CodeWriter; +import com.sun.codemodel.JClass; +import com.sun.codemodel.JClassAlreadyExistsException; +import com.sun.codemodel.JCodeModel; +import com.sun.codemodel.JDefinedClass; +import com.sun.codemodel.JDocComment; +import com.sun.codemodel.JExpr; +import com.sun.codemodel.JFieldVar; +import com.sun.codemodel.JInvocation; +import com.sun.codemodel.JMethod; +import com.sun.codemodel.JMod; +import com.sun.codemodel.JPackage; +import com.sun.codemodel.JType; +import com.sun.codemodel.JVar; +import com.sun.codemodel.writer.FileCodeWriter; +import com.sun.codemodel.writer.FilterCodeWriter; +import com.sun.codemodel.writer.ProgressCodeWriter; + +public class GodClassCodegen { + private static final String[] docstring = { + "Generated \"God Class\" stub intended for use by Forge mods only.", + "Members of this class are thin generated shims for methods in other modules." + }; + + // TODO: replicate annotations on generated method + public void doGenerate(File dir, Map.Entry, String> input) throws IOException, JClassAlreadyExistsException, ClassNotFoundException { + //new AbstractMap.SimpleImmutableEntry, File>(input, null); + Gson gson = new Gson(); + HashMap> classes = input.getKey().map(reader -> { + HashMap> elem = gson.fromJson(reader, SourceElement.serialized_type); + return elem; + }).reduce(new HashMap<>(), (acc, map) -> { + map.forEach((key, val) -> acc.merge(key, val, (a, b) -> { + a.addAll(b); return a; + })); + return acc; + }); + + JCodeModel cm = new JCodeModel(); + + for (Map.Entry> e: classes.entrySet()) { + JDefinedClass gen_class = cm._class(e.getKey()); + + gen_class.javadoc().append(String.join("\n", docstring)); + + for (SourceElement elem: e.getValue()) { + if (elem.args != null) { + // method + // TODO: modifiers + + JType returnType = getType(cm, elem.type); + + JMethod gen_method = gen_class.method(JMod.PUBLIC | JMod.STATIC, returnType, elem.target_name); + + for (SourceElement.TypeArg typeArg: elem.type_args) { + // NOTE: I can't deal with more than one type bound! + + try { + gen_method.generify(typeArg.name, (JClass) getType(cm, typeArg.bounds.get(0))); + } catch (IndexOutOfBoundsException ex) { + gen_method.generify(typeArg.name); + } + } + + JInvocation invoke = cm.directClass(elem.source_class).staticInvoke(elem.source_name); + + for (SourceElement.Arg arg: elem.args) { + JVar gen_param = gen_method.param(getType(cm, arg.type), arg.name); + + invoke.arg(gen_param); + } + + if (elem.type.name.equals("void")) { + gen_method.body().add(invoke); + } else { + gen_method.body()._return(invoke); + } + } else if (elem.type != null) { + // field + // TODO: modifiers + + JFieldVar gen_field = gen_class.field(JMod.PUBLIC | JMod.STATIC, getType(cm, elem.type), elem.target_name); + + gen_field.assign(cm.directClass(elem.source_class).staticRef(elem.source_name)); + } else { + // inner class + // TODO: modifiers + JDefinedClass inner = gen_class._class(JMod.PUBLIC | JMod.STATIC, elem.target_name); + inner._extends(cm.directClass(elem.source_class)); + // TODO: modifiers + // TODO: how to decide which constructor(s) + for (List constructor: elem.constructors) { + JMethod gen_init = inner.constructor(JMod.PUBLIC); + JInvocation call_super = JExpr.invoke("super"); + + for (SourceElement.Arg arg: constructor) { + JVar gen_param = gen_init.param(getType(cm, arg.type), arg.name); + + call_super.arg(gen_param); + } + + gen_init.body().add(call_super); + } + } + } + } + + CodeWriter src = new LicenseCodeWriter(new ProgressCodeWriter(new FileCodeWriter(dir), System.out), input.getValue()); + + cm.build(src); + } + + JType getType(JCodeModel cm, SourceElement.Ty type) { + if (type.isPrimitive) { + return JType.parse(cm, type.name); + } else { + // i'd use parseType for everything but it keeps throwing NullPointerException iirc so... + JClass ref = cm.directClass(type.name); + + if (type.generics != null) { + for (SourceElement.TypeArg arg: type.generics) { + ref.narrow(getTypeArg(cm, arg)); + } + } + + return ref; + } + } + + JClass getTypeArg(JCodeModel cm, SourceElement.TypeArg arg) { + try { + return (JClass) getType(cm, arg.bounds.get(0)); + } catch (IndexOutOfBoundsException ex) { + return cm.wildcard(); + } + } + + // https://github.com/javaee/jaxb-codemodel/blob/5e0fd4234b180c88fbc808bfadc6d75e34d76e5e/codemodel/codemodel/src/main/java/com/sun/codemodel/writer/PrologCodeWriter.java + static class LicenseCodeWriter extends FilterCodeWriter { + private final String license; + LicenseCodeWriter(CodeWriter core, String license) { + super(core); + this.license = license; + } + + @Override + public Writer openSource(JPackage pkg, String fileName) throws IOException { + Writer w = super.openSource(pkg, fileName); + + if (license != null) { + w.write("/*\n"); + + for (String line: license.split("\n")) { + w.write(" *"); + + if (!line.isEmpty()) { + w.write(" "); + w.write(line); + } + + w.write("\n"); + } + + w.write(" */\n"); + } + + return w; + } + } +} 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..e6616e0f 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 @@ -36,13 +36,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("net.minecraftforge.common.ForgeHooks:lootContext") 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 +87,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(); @@ -104,7 +109,9 @@ public static String readPoolName(JsonObject json) { return ctx.poolCount == 1 ? "main" : "pool" + (ctx.poolCount - 1); } + // TODO (codegen): constructor was private in ForgeHooks before introducing codegen // 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; 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'