Compare commits

..
31 Commits
Author SHA1 Message Date
Jonathing c047cf136c 1.21.3 RB 1
https://forums.minecraftforge.net/topic/154393-forge-531-minecraft-1213/
2025-03-01 16:56:32 -05:00
Jonathing f4287ecc81 Add missed license headers (#10475) 2025-03-01 21:35:03 +00:00
JonathingandLexManos 364a1e737f Speed up mod annotation scanning by ~30% (#10466)
Co-authored-by: LexManos <[email protected]>
2025-03-01 21:34:40 +00:00
Jonathing 45a977bb33 [1.21.3] Bump dependencies, most notably EventBus (#10385)
- CoreMods 5.2.4 -> 5.2.6
- EventBus 6.2.15 -> 6.2.27
    - Reduced memory usage
    - Further performance improvements
    - Fixed EventBus#39, unregistered listeners are now immediately reclaimable by the GC
- Apache MavenArtifact 3.8.5 -> 3.8.8
- NightConfig 3.7.3 -> 3.7.4
2025-02-12 17:51:46 -08:00
Jonathing ab00c907e7 Add fast graphics render type to block model jsons (#10395)
Make modded leaves behave like vanilla leaves by default (Fixes #10389)
2025-02-12 17:39:27 -08:00
979abb2b93 Re-introduce ItemStack Capabilities (#10362)
Co-authored-by: RealMangoRage <[email protected]>
Co-authored-by: LexManos <[email protected]>
2025-02-12 17:30:29 -08:00
Jonathing 056360b050 Re-introduce IForgeItem.damageItem when an item takes damage, Fixes #10344 (#10372) 2025-02-12 17:29:44 -08:00
Jonathing 960fce505c Add updated tag context to AddReloadListenerEvent (#10416)
Fixes using custom tags in GlobalLootModifiers.
2025-02-12 17:21:30 -08:00
JonathingandLexManos ea597ff45a Fix redstone update order not matching vanilla. (#10392)
Fix redstone updates for comparators going up/down incorrectly. Related: #9973
Fix game test structure rotations being inconsistant (#10391)

Co-authored-by: LexManos <[email protected]>
2025-02-12 17:11:56 -08:00
Jonathing f35dce7eb3 Fix corrupted and invalidly symlinked worlds crashing on level select (#10415) 2025-02-12 17:03:06 -08:00
Jonathing ef224bd2b8 Fix ModelDiscovery using Item components early (#10418) 2025-02-12 17:02:52 -08:00
Jonathing 0749f49b6c Fix forced chunks never being ticked by the server (#10365) 2025-02-12 13:37:21 -08:00
Jonathing 5c508efaa9 Fix shield disabling being completely ignored (#10317) 2025-01-27 15:28:07 -08:00
JonathingandJoseph T. McQuigg dbafe039d8 Fix issues in VillagerTrades.EmeraldsForVillagerTypeItem related to custom Villager Types (#10357)
Co-authored-by: Joseph T. McQuigg <[email protected]>
2025-01-27 15:27:42 -08:00
JonathingandLexManos b36ee22925 GameTestHelper additions (#10339)
Co-authored-by: LexManos <[email protected]>
2025-01-27 09:44:26 -08:00
Jonathing 287ee7b0b5 Update Gradle to 8.12.1 (#10353)
IntelliJ download sources in MDK
2025-01-27 09:44:11 -08:00
Jonathing 5f67621477 Fix JOpt Simple by bumping ModLaucnher (#10348) 2025-01-27 09:43:49 -08:00
Jonathing f237e7a8c3 Fix incorrect method reference in TntBlock.explode() (#10327) 2025-01-25 18:15:54 +00:00
Jonathing a54420de36 Fix JOpt Simple needing a strict version requirement declaration (#10312) 2025-01-25 18:15:36 +00:00
Jonathing 65dbdc8eb0 Bump dependencies (#10275)
- EventBus 6.2.8 -> 6.2.15
- Bootstrap 2.1.3 -> 2.1.8
- SecureModules 2.2.20 -> 2.2.21
- AccessTransformers 8.2.0 -> 8.2.1
- ModLauncher 10.2.2 -> 10.2.3
These bumps include further cleanup and optimisations.
2025-01-04 16:17:38 +00:00
Jonathing d42979f620 Simplify Title Screen Brandings (#10288) 2025-01-02 21:34:03 -08:00
Jonathing ac56afc99c Clean and fix Forge's internal coremods, fixes finalizeSpawn hook. 2024-12-30 14:36:16 -08:00
Gabriel Harris-Rouquette 81b7bfe4ea Update jline for better darwin/arm64 support (#10281) 2024-12-30 09:46:25 -08:00
Jonathing 4cbcf64ce1 Bump CoreMods to 5.2.4 (#10267) 2024-12-23 15:36:20 -08:00
JonathingandPaint_Ninja 29b763a0c3 Simplify memory usage display on loading screen (#10237)
Co-authored-by: Paint_Ninja <[email protected]>
2024-12-23 12:52:39 -08:00
JonathingandPaint_Ninja 52f41a4448 Deprecate @ObjectHolder, add a couple of fast-paths (#10232)
Co-authored-by: Paint_Ninja <[email protected]>
2024-12-23 12:51:51 -08:00
JonathingandPaint_Ninja 597409e2f2 Skip Vanilla classes for the CapabilityTokenSubclass transformer (#10225)
Co-authored-by: Paint_Ninja <[email protected]>
2024-12-23 12:42:07 -08:00
JonathingandPaint_Ninja 21fbd72585 Skip Forge classes in the RuntimeEnumExtender transformer (#10220)
Mod classes are still transformed as usual

Co-authored-by: Paint_Ninja <[email protected]>
2024-12-23 12:30:09 -08:00
JonathingandPaint_Ninja 83a09f7584 Skip processing Forge classes in RuntimeDistCleaner (#10212)
Co-authored-by: Paint_Ninja <[email protected]>
2024-12-23 12:19:40 -08:00
Jonathing 0e864fbe6e Fix NightConfig FileWatcher causing dedicated server to hang when exiting (#10214) 2024-12-23 12:09:22 -08:00
Jonathing 2fd8900c01 Allow mipmap lowering to be disabled (#10256) 2024-12-23 11:57:00 -08:00
1170 changed files with 15847 additions and 17524 deletions

No files matched your search

-1
View File
@@ -3,7 +3,6 @@
*.patch text eol=lf
*.java text eol=lf
*.gradle text eol=crlf
**/MANIFEST.MF text eol=crlf
*.png binary
*.gif binary
*.exe binary
-5
View File
@@ -41,8 +41,3 @@ src/*/generated/**/.cache/
/ForgeRoot.ipr
/ForgeRoot.iws
# APT stuff
/*/.gitignore
/*/.factorypath
/*/.apt_generated/
+2 -2
View File
@@ -4,8 +4,8 @@ repositories {
}
dependencies {
implementation 'org.ow2.asm:asm:9.8'
implementation 'org.ow2.asm:asm-tree:9.8'
implementation 'org.ow2.asm:asm:9.7'
implementation 'org.ow2.asm:asm-tree:9.7'
implementation 'net.minecraftforge:srgutils:0.5.10'
implementation 'commons-io:commons-io:2.13.0'
implementation 'com.google.code.gson:gson:2.10.1'
+17 -49
View File
@@ -92,18 +92,18 @@ final String MAVEN_PATH = ext.MAVEN_PATH
final String BINPATCH_TOOL = 'net.minecraftforge:binarypatcher:1.2.0:fatjar'
final String INSTALLER_TOOLS = 'net.minecraftforge:installertools:1.4.3'
final String FART = 'net.minecraftforge:ForgeAutoRenamingTool:1.0.6'
final String S2S_TOOL = 'net.minecraftforge:Srg2Source:8.1.1:fatjar'
final String S2S_TOOL = 'net.minecraftforge:Srg2Source:8.1.0:fatjar'
configurations {
// Don't pull all libraries, if we're missing something, add it to the installer list so the installer knows to download it.
bootstrap { transitive = false }
installer {
installer {
extendsFrom(bootstrap)
transitive = false
transitive = false
}
installerextra {
installerextra {
extendsFrom(bootstrap)
transitive = false
transitive = false
}
api.extendsFrom(installer)
}
@@ -117,14 +117,14 @@ dependencies {
bootstrap(libs.securemodules) // Has Union file system in it
bootstrap(libs.unsafe) // Needed by securemodules
bootstrap(libs.bundles.asm) // Needed by securemodules
implementation(libs.jopt.simple)
installer(libs.bootstrap)
installer(libs.bootstrap.api) // Needed by securemodules
installer(libs.accesstransformers)
installer(libs.eventbus)
installer(libs.jspecify) // Dep of EventBus
installer(libs.typetools) // Dep of EventBus
installer(libs.forgespi)
installer(libs.coremods)
installer(libs.nashorn) // Dep of Coremods
@@ -147,8 +147,6 @@ dependencies {
runtimeOnly(libs.bootstrap)
runtimeOnly(libs.bootstrap.dev)
annotationProcessor(libs.eventbus.validator)
}
tasks.named('extractRangeMap').configure {
@@ -168,7 +166,7 @@ patcher {
runs {
forge_client {
property 'eventbus.api.strictRuntimeChecks', 'true'
property 'eventbus.checkTypesOnDispatch', 'true'
property 'org.lwjgl.system.SharedLibraryExtractDirectory', 'lwjgl_dll'
args '--launchTarget', 'forge_dev_client',
@@ -211,6 +209,7 @@ patcher {
'--all',
'--validate',
'--output', rootProject.file('src/main/generated/'),
'--validate',
'--existing', sourceSets.main.resources.srcDirs[0],
'--assetsDir', downloadAssets.output,
'--assetIndex', "{asset_index}"
@@ -228,30 +227,6 @@ patcher {
'--assetsDir', downloadAssets.output,
'--assetIndex', "{asset_index}"
}
forge_client_data {
args '--launchTarget', 'forge_dev_client_data',
'--mod', 'forge',
'--all',
'--output', rootProject.file('src/main/generated/'),
'--existing', sourceSets.main.resources.srcDirs[0],
'--assetsDir', downloadAssets.output,
'--assetIndex', "{asset_index}"
}
forge_client_data_test {
source sourceSets.test
args '--launchTarget', 'forge_dev',
'--launchEntry', 'minecraft/net.minecraft.client.data.Main',
'--launchData',
'--mod', '.+',
'--all',
'--output', rootProject.file('src/test/generated/'),
'--existing', sourceSets.main.resources.srcDirs[0],
'--existing', sourceSets.test.resources.srcDirs[0],
'--assetsDir', downloadAssets.output,
'--assetIndex', "{asset_index}"
}
}
}
@@ -293,11 +268,11 @@ tasks.register('downloadCrowdin', Download) {
tasks.userdevConfig.configure {
configurations.installer.allDependencies.forEach {
def dep = it.toString()
if (it instanceof ProjectDependency)
if (it instanceof ProjectDependency)
dep = "net.minecraftforge:$it.dependencyProject.name:$it.dependencyProject.version"
libraries.add(dep)
}
inject = '' // We don't have a userdev sourceset anymore. Empty as a gradle workaround...
runs {
client {
@@ -309,13 +284,6 @@ tasks.userdevConfig.configure {
args '--assetsDir', '{assets_root}'
}
clientData {
environment 'MCP_MAPPINGS', '{mcp_mappings}'
args '--launchTarget', "forge_userdev_client_data"
args '--assetIndex', '{asset_index}'
args '--assetsDir', '{assets_root}'
}
server {
environment 'MCP_MAPPINGS', '{mcp_mappings}'
property 'forge.enableGameTest', 'true'
@@ -525,7 +493,7 @@ tasks.register('serverShimJar', Jar) {
from {
zipTree(downloadServerShim.output).find { it.name == 'MANIFEST.MF' }
}
attributes('Class-Path': configurations.bootstrap.resolvedConfiguration.resolvedArtifacts.collect { "libraries/${Util.getMavenInfoFromDep(it).path}" }.join(' '))
}
archiveClassifier = 'shim'
@@ -618,7 +586,7 @@ tasks.register('checkJarCompatibility', CheckJarCompatibility) {
baseLibraries.from(project.tasks.named('createJoinedSRG').flatMap { it.output })
inputJar = project.tasks.named('reobfJar').flatMap { it.output }
commonLibraries.from(project.configurations.minecraftImplementation)
commonLibraries.from(project.configurations.installer)
}
@@ -639,11 +607,11 @@ tasks.register('launcherJson', LauncherJson).configure {
tasks.register('installerJson', InstallerJson) {
icon = rootProject.file('icon.ico')
// Json to install into the client's launcher
dependsOn(launcherJson)
input.from(launcherJson.output)
// Download Official Mappings
dependsOn(downloadClientMappings, downloadServerMappings)
input.from(downloadClientMappings.output, downloadServerMappings.output)
@@ -1091,7 +1059,7 @@ publishing {
license gradleutils.pom.Licenses.LGPLv2_1
}
}
repositories {
maven gradleutils.publishingForgeMaven
}
+1 -1
View File
@@ -44,7 +44,7 @@ tasks.withType(JavaCompile).configureEach {
dependsOn 'processResources' // Needed because we merge the output of this with the output of the compile task. And gradle detects downstream tasks using the output without a hard dep
options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation
options.warnings = false // Shutup deprecated for removal warnings
options.forkOptions.jvmArgs += '-Xmx6G' // Needed to make compiling faster, and not run out of heap space in some cases.
options.forkOptions.jvmArgs += '-Xmx3G' // Needed to make compiling faster, and not run out of heap space in some cases.
}
// Merge the resources and classes into the same directory. We'll need to split them at runtime because
+2 -8
View File
@@ -2,8 +2,8 @@
MinecraftForge
=============
[![Stable Release](https://img.shields.io/badge/dynamic/json?url=https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json&label=Stable&prefix=1.21.4-&query=$.promos["1.21.4-recommended"]&color=brightgreen&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBjbGFzcz0ic3ZnLWlubGluZS0tZmEgZmEtc3RhciBmYS13LTE4IiBhcmlhLWhpZGRlbj0idHJ1ZSIgZGF0YS1pY29uPSJzdGFyIiBkYXRhLXByZWZpeD0iZmFzIiBmb2N1c2FibGU9ImZhbHNlIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCA1NzYgNTEyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cGF0aCBkPSJNMjU5LjMgMTcuOEwxOTQgMTUwLjIgNDcuOSAxNzEuNWMtMjYuMiAzLjgtMzYuNyAzNi4xLTE3LjcgNTQuNmwxMDUuNyAxMDMtMjUgMTQ1LjVjLTQuNSAyNi4zIDIzLjIgNDYgNDYuNCAzMy43TDI4OCA0MzkuNmwxMzAuNyA2OC43YzIzLjIgMTIuMiA1MC45LTcuNCA0Ni40LTMzLjdsLTI1LTE0NS41IDEwNS43LTEwM2MxOS0xOC41IDguNS01MC44LTE3LjctNTQuNkwzODIgMTUwLjIgMzE2LjcgMTcuOGMtMTEuNy0yMy42LTQ1LjYtMjMuOS01Ny40IDB6IiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K)][Download]
[![Latest Release](https://img.shields.io/badge/dynamic/json?url=https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json&label=Latest&prefix=1.21.5-&query=$.promos["1.21.5-latest"]&color=blue&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBjbGFzcz0ic3ZnLWlubGluZS0tZmEgZmEtYnVnIGZhLXctMTYiIGFyaWEtaGlkZGVuPSJ0cnVlIiBkYXRhLWljb249ImJ1ZyIgZGF0YS1wcmVmaXg9ImZhcyIgZm9jdXNhYmxlPSJmYWxzZSIgcm9sZT0iaW1nIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTUxMS45ODggMjg4LjljLS40NzggMTcuNDMtMTUuMjE3IDMxLjEtMzIuNjUzIDMxLjFINDI0djE2YzAgMjEuODY0LTQuODgyIDQyLjU4NC0xMy42IDYxLjE0NWw2MC4yMjggNjAuMjI4YzEyLjQ5NiAxMi40OTcgMTIuNDk2IDMyLjc1OCAwIDQ1LjI1NS0xMi40OTggMTIuNDk3LTMyLjc1OSAxMi40OTYtNDUuMjU2IDBsLTU0LjczNi01NC43MzZDMzQ1Ljg4NiA0NjcuOTY1IDMxNC4zNTEgNDgwIDI4MCA0ODBWMjM2YzAtNi42MjctNS4zNzMtMTItMTItMTJoLTI0Yy02LjYyNyAwLTEyIDUuMzczLTEyIDEydjI0NGMtMzQuMzUxIDAtNjUuODg2LTEyLjAzNS05MC42MzYtMzIuMTA4bC01NC43MzYgNTQuNzM2Yy0xMi40OTggMTIuNDk3LTMyLjc1OSAxMi40OTYtNDUuMjU2IDAtMTIuNDk2LTEyLjQ5Ny0xMi40OTYtMzIuNzU4IDAtNDUuMjU1bDYwLjIyOC02MC4yMjhDOTIuODgyIDM3OC41ODQgODggMzU3Ljg2NCA4OCAzMzZ2LTE2SDMyLjY2NkMxNS4yMyAzMjAgLjQ5MSAzMDYuMzMuMDEzIDI4OC45LS40ODQgMjcwLjgxNiAxNC4wMjggMjU2IDMyIDI1Nmg1NnYtNTguNzQ1bC00Ni42MjgtNDYuNjI4Yy0xMi40OTYtMTIuNDk3LTEyLjQ5Ni0zMi43NTggMC00NS4yNTUgMTIuNDk4LTEyLjQ5NyAzMi43NTgtMTIuNDk3IDQ1LjI1NiAwTDE0MS4yNTUgMTYwaDIyOS40ODlsNTQuNjI3LTU0LjYyN2MxMi40OTgtMTIuNDk3IDMyLjc1OC0xMi40OTcgNDUuMjU2IDAgMTIuNDk2IDEyLjQ5NyAxMi40OTYgMzIuNzU4IDAgNDUuMjU1TDQyNCAxOTcuMjU1VjI1Nmg1NmMxNy45NzIgMCAzMi40ODQgMTQuODE2IDMxLjk4OCAzMi45ek0yNTcgMGMtNjEuODU2IDAtMTEyIDUwLjE0NC0xMTIgMTEyaDIyNEMzNjkgNTAuMTQ0IDMxOC44NTYgMCAyNTcgMHoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo=
[![Stable Release](https://img.shields.io/badge/dynamic/json?url=https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json&label=Stable&prefix=1.21.3-&query=$.promos["1.21.3-recommended"]&color=brightgreen&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBjbGFzcz0ic3ZnLWlubGluZS0tZmEgZmEtc3RhciBmYS13LTE4IiBhcmlhLWhpZGRlbj0idHJ1ZSIgZGF0YS1pY29uPSJzdGFyIiBkYXRhLXByZWZpeD0iZmFzIiBmb2N1c2FibGU9ImZhbHNlIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCA1NzYgNTEyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cGF0aCBkPSJNMjU5LjMgMTcuOEwxOTQgMTUwLjIgNDcuOSAxNzEuNWMtMjYuMiAzLjgtMzYuNyAzNi4xLTE3LjcgNTQuNmwxMDUuNyAxMDMtMjUgMTQ1LjVjLTQuNSAyNi4zIDIzLjIgNDYgNDYuNCAzMy43TDI4OCA0MzkuNmwxMzAuNyA2OC43YzIzLjIgMTIuMiA1MC45LTcuNCA0Ni40LTMzLjdsLTI1LTE0NS41IDEwNS43LTEwM2MxOS0xOC41IDguNS01MC44LTE3LjctNTQuNkwzODIgMTUwLjIgMzE2LjcgMTcuOGMtMTEuNy0yMy42LTQ1LjYtMjMuOS01Ny40IDB6IiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K)][Download]
[![Latest Release](https://img.shields.io/badge/dynamic/json?url=https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json&label=Latest&prefix=1.21.3-&query=$.promos["1.21.3-latest"]&color=blue&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBjbGFzcz0ic3ZnLWlubGluZS0tZmEgZmEtYnVnIGZhLXctMTYiIGFyaWEtaGlkZGVuPSJ0cnVlIiBkYXRhLWljb249ImJ1ZyIgZGF0YS1wcmVmaXg9ImZhcyIgZm9jdXNhYmxlPSJmYWxzZSIgcm9sZT0iaW1nIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTUxMS45ODggMjg4LjljLS40NzggMTcuNDMtMTUuMjE3IDMxLjEtMzIuNjUzIDMxLjFINDI0djE2YzAgMjEuODY0LTQuODgyIDQyLjU4NC0xMy42IDYxLjE0NWw2MC4yMjggNjAuMjI4YzEyLjQ5NiAxMi40OTcgMTIuNDk2IDMyLjc1OCAwIDQ1LjI1NS0xMi40OTggMTIuNDk3LTMyLjc1OSAxMi40OTYtNDUuMjU2IDBsLTU0LjczNi01NC43MzZDMzQ1Ljg4NiA0NjcuOTY1IDMxNC4zNTEgNDgwIDI4MCA0ODBWMjM2YzAtNi42MjctNS4zNzMtMTItMTItMTJoLTI0Yy02LjYyNyAwLTEyIDUuMzczLTEyIDEydjI0NGMtMzQuMzUxIDAtNjUuODg2LTEyLjAzNS05MC42MzYtMzIuMTA4bC01NC43MzYgNTQuNzM2Yy0xMi40OTggMTIuNDk3LTMyLjc1OSAxMi40OTYtNDUuMjU2IDAtMTIuNDk2LTEyLjQ5Ny0xMi40OTYtMzIuNzU4IDAtNDUuMjU1bDYwLjIyOC02MC4yMjhDOTIuODgyIDM3OC41ODQgODggMzU3Ljg2NCA4OCAzMzZ2LTE2SDMyLjY2NkMxNS4yMyAzMjAgLjQ5MSAzMDYuMzMuMDEzIDI4OC45LS40ODQgMjcwLjgxNiAxNC4wMjggMjU2IDMyIDI1Nmg1NnYtNTguNzQ1bC00Ni42MjgtNDYuNjI4Yy0xMi40OTYtMTIuNDk3LTEyLjQ5Ni0zMi43NTggMC00NS4yNTUgMTIuNDk4LTEyLjQ5NyAzMi43NTgtMTIuNDk3IDQ1LjI1NiAwTDE0MS4yNTUgMTYwaDIyOS40ODlsNTQuNjI3LTU0LjYyN2MxMi40OTgtMTIuNDk3IDMyLjc1OC0xMi40OTcgNDUuMjU2IDAgMTIuNDk2IDEyLjQ5NyAxMi40OTYgMzIuNzU4IDAgNDUuMjU1TDQyNCAxOTcuMjU1VjI1Nmg1NmMxNy45NzIgMCAzMi40ODQgMTQuODE2IDMxLjk4OCAzMi45ek0yNTcgMGMtNjEuODU2IDAtMTEyIDUwLjE0NC0xMTIgMTEyaDIyNEMzNjkgNTAuMTQ0IDMxOC44NTYgMCAyNTcgMHoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo=
)][Download] [![Discord](https://img.shields.io/discord/313125603924639766.svg?color=%237289da&label=Discord&logo=discord&logoColor=%237289da)][Discord] [![Support](https://img.shields.io/badge/Patreon-Support-orange.svg?logo=Patreon)][Patreon]
Forge is a free, open-source modding API all of your favourite mods use!
@@ -70,11 +70,6 @@ Please ensure you have a valid email address associated with your GitHub account
to use and modify. However, it costs money to run such a large project as this, so please consider
[becoming a patron][Patreon].*
### Thanks
[![YourKit](https://www.yourkit.com/images/yklogo.png)](https://www.yourkit.com/)
YourKit for providing us accesss to their [YourKit Java Profiler] which helps identify bottlenecks and places for improvment.
[Contributing]: ./CONTRIBUTING.md
[CLA]: https://cla-assistant.io/MinecraftForge/MinecraftForge
@@ -98,4 +93,3 @@ YourKit for providing us accesss to their [YourKit Java Profiler] which helps id
[Pull-Requests]: https://docs.minecraftforge.net/en/latest/forgedev/#making-changes-and-pull-requests
[Patreon]: https://www.patreon.com/LexManos
[YourKit Java Profiler]: https://www.yourkit.com/java/profiler/
+1 -2
View File
@@ -10,10 +10,9 @@ plugins {
apply from: rootProject.file('build_shared.gradle')
dependencies {
compileOnly(libs.jetbrains.annotations)
compileOnly(libs.nulls)
api(libs.eventbus)
annotationProcessor(libs.eventbus.validator)
implementation(project(':fmlloader'))
implementation(libs.commons.io)
@@ -5,7 +5,7 @@
package net.minecraftforge.fml;
import net.minecraftforge.eventbus.api.bus.BusGroup;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.config.IConfigEvent;
import net.minecraftforge.fml.loading.FMLLoader;
@@ -29,7 +29,7 @@ public class Bindings {
/**
* @return A supplier of net.minecraftforge.common.MinecraftForge#EVENT_BUS
*/
public static Supplier<BusGroup> getForgeBus() {
public static Supplier<IEventBus> getForgeBus() {
return PROVIDER.getForgeBusSupplier();
}
@@ -25,18 +25,7 @@ import java.util.function.Supplier;
* <li>When you want to call one thing on one side, another thing on the other and return a result {@link #safeRunForDist(Supplier, Supplier)}</li>
* <li>When you want to run something on one side {@link #safeRunWhenOn(Dist, Supplier)}</li>
* </ul>
*
* @deprecated Historically, this allowed for safe execution of code on the correct side by exploiting a low-level
* detail in Java 8, but in newer versions a simple if check is enough.
* <br>
* For example:
* <pre>{@code
* if (FMLEnvironment.dist.isClient()) {
* // client code here
* }
* }</pre>
*/
@Deprecated(since = "1.21.5", forRemoval = true)
public final class DistExecutor
{
private static final Logger LOGGER = LogManager.getLogger();
@@ -5,13 +5,13 @@
package net.minecraftforge.fml;
import net.minecraftforge.eventbus.api.bus.BusGroup;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.config.IConfigEvent;
import java.util.function.Supplier;
public interface IBindingsProvider {
Supplier<BusGroup> getForgeBusSupplier();
Supplier<IEventBus> getForgeBusSupplier();
Supplier<I18NParser> getMessageParser();
Supplier<IConfigEvent.ConfigConfig> getConfigConfiguration();
}
@@ -5,6 +5,8 @@
package net.minecraftforge.fml;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.event.IModBusEvent;
import net.minecraftforge.fml.loading.progress.ProgressMeter;
import java.util.Optional;
@@ -59,13 +61,14 @@ public interface IModLoadingState {
/**
* Builds the transition task for this state with a blank pre-sync and post-sync task.
*
* @param <T> a type of event fired on the mod-specific event bus
* @param syncExecutor a synchronous executor
* @param parallelExecutor a parallel executor
* @param progressBar a progress meter for tracking progress
* @return a transition task for this state
* @see #buildTransition(Executor, Executor, ProgressMeter, Function, Function)
*/
default Optional<CompletableFuture<Void>> buildTransition(
default <T extends Event & IModBusEvent> Optional<CompletableFuture<Void>> buildTransition(
final Executor syncExecutor,
final Executor parallelExecutor,
final ProgressMeter progressBar
@@ -80,6 +83,7 @@ public interface IModLoadingState {
* Builds the transition task for this state. The pre-sync and post-sync task functions allow the transition builder
* to run these tasks on the same executor as the actual event dispatch and pre/post hooks.
*
* @param <T> a type of event fired on the mod-specific event bus
* @param syncExecutor a synchronous executor
* @param parallelExecutor a parallel executor
* @param progressBar a progress meter for tracking progress
@@ -87,6 +91,7 @@ public interface IModLoadingState {
* @param postSyncTask a function which returns a task to run after event post-dispatch hook
* @return a transition task for this state
*/
<T extends Event & IModBusEvent>
Optional<CompletableFuture<Void>> buildTransition(final Executor syncExecutor,
final Executor parallelExecutor,
final ProgressMeter progressBar,
@@ -5,6 +5,7 @@
package net.minecraftforge.fml;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.event.IModBusEvent;
import net.minecraftforge.fml.loading.progress.ProgressMeter;
@@ -19,7 +20,7 @@ import org.jetbrains.annotations.Nullable;
public interface IModStateTransition {
/** Magic value to allow me to optimize the futures list by ignoring the default value without making old methods nullable. */
BiFunction<Executor, ? extends EventGenerator<?>, CompletableFuture<Void>> NULL_HOOK = (e, g) -> CompletableFuture.completedFuture(null);
public static final BiFunction<Executor, ? extends EventGenerator<?>, CompletableFuture<Void>> NULL_HOOK = (e, g) -> CompletableFuture.completedFuture(null);
static IModStateTransition buildNoopTransition() {
return ModStateTransitionHelper.NOOP;
@@ -50,7 +51,7 @@ public interface IModStateTransition {
}
@Nullable
default <T extends IModBusEvent> EventGenerator<T> eventFunction() {
default <T extends Event & IModBusEvent> EventGenerator<T> eventFunction() {
return null;
}
@@ -73,8 +74,8 @@ public interface IModStateTransition {
@Deprecated(since = "1.21.3", forRemoval = true)
default BiFunction<Executor, ? extends EventGenerator<?>, CompletableFuture<Void>> postDispatchHook() { return NULL_HOOK; }
interface EventGenerator<T extends IModBusEvent> extends Function<ModContainer, T> {
static <FN extends IModBusEvent> EventGenerator<FN> fromFunction(Function<ModContainer, FN> fn) {
interface EventGenerator<T extends Event & IModBusEvent> extends Function<ModContainer, T> {
static <FN extends Event & IModBusEvent> EventGenerator<FN> fromFunction(Function<ModContainer, FN> fn) {
return fn::apply;
}
}
@@ -5,6 +5,7 @@
package net.minecraftforge.fml;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.config.IConfigEvent;
import net.minecraftforge.fml.config.ModConfig;
import net.minecraftforge.fml.event.IModBusEvent;
@@ -161,5 +162,5 @@ public abstract class ModContainer {
* Accept an arbitrary event for processing by the mod. Probably posted to an event bus in the lower level container.
* @param e Event to accept
*/
protected <T extends IModBusEvent> void acceptEvent(T e) {}
protected <T extends Event & IModBusEvent> void acceptEvent(T e) {}
}
@@ -6,6 +6,7 @@
package net.minecraftforge.fml;
import com.google.common.collect.ImmutableList;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.event.IModBusEvent;
import net.minecraftforge.fml.loading.FMLEnvironment;
import net.minecraftforge.fml.loading.FMLLoader;
@@ -87,7 +88,7 @@ public class ModLoader {
this.loadingModList = FMLLoader.getLoadingModList();
this.loadingExceptions = this.loadingModList.getErrors().stream()
.flatMap(ModLoadingException::fromEarlyException)
.collect(Collectors.toList());
.toList();
this.loadingWarnings = this.loadingModList.getBrokenFiles().stream()
.map(file -> new ModLoadingWarning(null, ModLoadingStage.VALIDATE, InvalidModIdentifier.identifyJarProblem(file.getFilePath()).orElse("fml.modloading.brokenfile"), file.getFileName()))
.collect(Collectors.toList());
@@ -154,13 +155,11 @@ public class ModLoader {
loadingStateValid = false;
throw new LoadingFailedException(loadingExceptions);
}
var failedBounds = new ArrayList<ForgeFeature.Bound>();
for (var mod : loadingModList.getMods()) {
for (var feature : mod.getForgeFeatures()) {
if (!ForgeFeature.testFeature(FMLEnvironment.dist, feature))
failedBounds.add(feature);
}
}
List<? extends ForgeFeature.Bound> failedBounds = loadingModList.getMods().stream()
.map(ModInfo::getForgeFeatures)
.flatMap(List::stream)
.filter(bound -> !ForgeFeature.testFeature(FMLEnvironment.dist, bound))
.toList();
if (!failedBounds.isEmpty()) {
LOGGER.fatal(CORE, "Failed to validate feature bounds for mods: {}", failedBounds);
@@ -358,53 +357,49 @@ public class ModLoader {
return completedStates.contains(state);
}
public <T extends IModBusEvent> void runEventGenerator(Function<ModContainer, T> generator) {
public <T extends Event & IModBusEvent> void runEventGenerator(Function<ModContainer, T> generator) {
if (!loadingStateValid) {
LOGGER.error("Cowardly refusing to send event generator to a broken mod state");
return;
}
for (var mod : ModList.get().getLoadedMods())
mod.acceptEvent(generator.apply(mod));
ModList.get().forEachModInOrder(mc -> mc.acceptEvent(generator.apply(mc)));
}
public <T extends IModBusEvent> void postEvent(T e) {
var cls = e.getClass();
public <T extends Event & IModBusEvent> void postEvent(T e) {
if (!loadingStateValid) {
LOGGER.error("Cowardly refusing to send event {} to a broken mod state", e.getClass().getName());
return;
}
for (var mod : ModList.get().getLoadedMods())
mod.acceptEvent(e);
ModList.get().forEachModInOrder(mc -> mc.acceptEvent(e));
}
public <T extends IModBusEvent> T postEventWithReturn(T e) {
public <T extends Event & IModBusEvent> T postEventWithReturn(T e) {
if (!loadingStateValid) {
LOGGER.error("Cowardly refusing to send event {} to a broken mod state", e.getClass().getName());
return e;
}
for (var mod : ModList.get().getLoadedMods())
mod.acceptEvent(e);
ModList.get().forEachModInOrder(mc -> mc.acceptEvent(e));
return e;
}
@SuppressWarnings("removal")
public <T extends IModBusEvent> void postEventWrapContainerInModOrder(T event) {
public <T extends Event & IModBusEvent> void postEventWrapContainerInModOrder(T event) {
postEventWithWrapInModOrder(event,
(mc, e) -> ModLoadingContext.get().setActiveContainer(mc),
(mc, e) -> ModLoadingContext.get().setActiveContainer(null)
);
}
public <T extends IModBusEvent> void postEventWithWrapInModOrder(T e, BiConsumer<ModContainer, T> pre, BiConsumer<ModContainer, T> post) {
public <T extends Event & IModBusEvent> void postEventWithWrapInModOrder(T e, BiConsumer<ModContainer, T> pre, BiConsumer<ModContainer, T> post) {
if (!loadingStateValid) {
LOGGER.error("Cowardly refusing to send event {} to a broken mod state", e.getClass().getName());
return;
}
for (var mod : ModList.get().getLoadedMods()) {
pre.accept(mod, e);
mod.acceptEvent(e);
post.accept(mod, e);
}
ModList.get().forEachModInOrder(mc -> {
pre.accept(mc, e);
mc.acceptEvent(e);
post.accept(mc, e);
});
}
public List<ModLoadingWarning> getWarnings() {
@@ -421,7 +416,7 @@ public class ModLoader {
return runningDataGen;
}
private static final class ErroredModContainer extends ModContainer {
private static class ErroredModContainer extends ModContainer {
public ErroredModContainer() {
super();
}
@@ -5,6 +5,8 @@
package net.minecraftforge.fml;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.event.IModBusEvent;
import net.minecraftforge.fml.loading.progress.ProgressMeter;
import java.util.Optional;
@@ -34,7 +36,7 @@ public record ModLoadingState(
Optional<IModStateTransition> transition
) implements IModLoadingState {
@Override
public Optional<CompletableFuture<Void>> buildTransition(
public <T extends Event & IModBusEvent> Optional<CompletableFuture<Void>> buildTransition(
final Executor syncExecutor,
final Executor parallelExecutor,
final ProgressMeter progressBar,
@@ -9,16 +9,15 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.Executor;
import java.util.function.BiFunction;
import java.util.function.Function;
import org.jetbrains.annotations.ApiStatus;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.IModStateTransition.EventGenerator;
import net.minecraftforge.fml.event.IModBusEvent;
import net.minecraftforge.fml.loading.progress.ProgressMeter;
@@ -42,7 +41,7 @@ class ModStateTransitionHelper {
if (t.stream().noneMatch(e -> e.exception() != null)) {
return CompletableFuture.completedFuture(null);
} else {
final var throwables = t.stream().map(FutureResult::exception).filter(Objects::nonNull).toList();
final var throwables = t.stream().map(FutureResult::exception).filter(e -> e != null).toList();
CompletableFuture<Void> cf = new CompletableFuture<>();
final RuntimeException accumulator = new RuntimeException();
cf.completeExceptionally(accumulator);
@@ -71,15 +70,13 @@ class ModStateTransitionHelper {
for (var future : futures) {
int i = list.size();
list.add(null);
@SuppressWarnings("unchecked") // Bypass a weird javac error with generic by forcing it to be the exact type we want.
var raw = ((CompletableFuture<V>)future);
results[i] = raw.whenComplete((result, exception) -> list.set(i, new FutureResult<>(result, exception)));
results[i] = future.whenComplete((result, exception) -> list.set(i, new FutureResult<>(result, exception)));
}
return CompletableFuture.allOf(results).handle((r, th)->null).thenApply(res -> list);
}
private static <T extends IModBusEvent> void addCompletableFutureTaskForModDispatch(
private static <T extends Event & IModBusEvent> void addCompletableFutureTaskForModDispatch(
final IModStateTransition transition,
final Executor executor,
final List<CompletableFuture<Void>> completableFutures,
@@ -138,14 +135,14 @@ class ModStateTransitionHelper {
completableFutures.add(postDispatchHook);
}
private static <T extends IModBusEvent> CompletableFuture<Void> getHook(BiFunction<Executor, ? extends EventGenerator<?>, CompletableFuture<Void>> hook, Executor executor, EventGenerator<T> eventGenerator) {
private static <T extends Event & IModBusEvent> CompletableFuture<Void> getHook(BiFunction<Executor, ? extends EventGenerator<?>, CompletableFuture<Void>> hook, Executor executor, EventGenerator<T> eventGenerator) {
if (hook == null || hook == IModStateTransition.NULL_HOOK) return null;
@SuppressWarnings("unchecked")
var hookTyped = (BiFunction<Executor, EventGenerator<T>, CompletableFuture<Void>>)hook;
return hookTyped.apply(executor, eventGenerator);
}
static <T extends IModBusEvent> CompletableFuture<Void> build(
static <T extends Event & IModBusEvent> CompletableFuture<Void> build(
final IModStateTransition transition,
final String name,
final Executor syncExecutor,
@@ -5,7 +5,7 @@
package net.minecraftforge.fml.config;
import net.minecraftforge.eventbus.api.event.InheritableEvent;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.Bindings;
import java.util.function.Function;
@@ -29,7 +29,7 @@ public interface IConfigEvent {
ModConfig getConfig();
@SuppressWarnings("unchecked")
default <T extends InheritableEvent & IConfigEvent> T self() {
default <T extends Event & IConfigEvent> T self() {
return (T) this;
}
}
@@ -5,27 +5,8 @@
package net.minecraftforge.fml.event;
import net.minecraftforge.eventbus.api.bus.BusGroup;
import net.minecraftforge.eventbus.api.bus.EventBus;
import net.minecraftforge.eventbus.api.event.InheritableEvent;
/**
* Marker interface for events dispatched on the ModLifecycle event bus instead of the primary event bus
*/
public interface IModBusEvent extends InheritableEvent {
/**
* @param modEventBusGroup Obtained from {@link net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext#getModBusGroup()} or your language provider's equivalent.
* @param eventClass The event type you want to get the associated bus for.
*/
static <T extends IModBusEvent> EventBus<T> getBus(BusGroup modEventBusGroup, Class<T> eventClass) {
// Do not copy! Temporary solution until the FML rewrite is complete. May throw in future
// without prior notice.
//
// Mods creating their own events should directly assign the result of the create method to a
// static final field in their event class, without wrapping or calling multiple times.
//
// Mods using existing events should instead use the existing static final BUS field in the
// event class (for most events) or getBus(BusGroup) method (for mod bus events).
return EventBus.create(modEventBusGroup, eventClass);
}
public interface IModBusEvent {
}
+1 -1
View File
@@ -28,7 +28,7 @@ java {
}
dependencies {
compileOnly(libs.jetbrains.annotations)
compileOnly(libs.nulls)
implementation(project(':fmlloader'))
implementation(project(':fmlcore'))
implementation(libs.bundles.lwjgl)
@@ -90,12 +90,7 @@ public class DisplayWindow implements ImmediateWindowProvider {
// The GL ID of the window. Used for all operations
private long window;
// The thread that contains and ticks the window while Forge is loading mods
private static final ScheduledExecutorService renderScheduler = Executors.newSingleThreadScheduledExecutor(r -> {
final var thread = Executors.defaultThreadFactory().newThread(r);
thread.setName("EarlyDisplay");
thread.setDaemon(true);
return thread;
});
private ScheduledExecutorService renderScheduler;
private int fbWidth;
private int fbHeight;
private int fbScale;
@@ -154,7 +149,7 @@ public class DisplayWindow implements ImmediateWindowProvider {
}
this.maximized = parsed.has(maximizedopt) || FMLConfig.getBoolConfigValue(FMLConfig.ConfigValue.EARLY_WINDOW_MAXIMIZED);
StartupNotificationManager.modLoaderConsumer().ifPresent(c->c.accept("Forge loading " + FMLLoader.versionInfo().forgeVersion()));
StartupNotificationManager.modLoaderConsumer().ifPresent(c->c.accept("Forge loading " + forgeVersion));
performanceInfo = new PerformanceInfo();
return start(mcVersion, forgeVersion);
}
@@ -243,7 +238,7 @@ public class DisplayWindow implements ImmediateWindowProvider {
var date = Calendar.getInstance();
if (FMLConfig.getBoolConfigValue(FMLConfig.ConfigValue.EARLY_WINDOW_SQUIR) || (date.get(Calendar.MONTH) == Calendar.APRIL && date.get(Calendar.DAY_OF_MONTH) == 1))
this.elements.addFirst(RenderElement.squir());
this.elements.add(0, RenderElement.squir());
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -292,6 +287,12 @@ public class DisplayWindow implements ImmediateWindowProvider {
* Start the window and Render Thread; we're ready to go.
*/
public Runnable start(@Nullable String mcVersion, final String forgeVersion) {
renderScheduler = Executors.newSingleThreadScheduledExecutor(r -> {
final var thread = Executors.defaultThreadFactory().newThread(r);
thread.setName("EarlyDisplay");
thread.setDaemon(true);
return thread;
});
initWindow(mcVersion);
this.initializationFuture = renderScheduler.schedule(() -> initRender(mcVersion, forgeVersion), 1, TimeUnit.MILLISECONDS);
return this::periodicTick;
@@ -303,7 +304,7 @@ public class DisplayWindow implements ImmediateWindowProvider {
return this.glVersion;
}
private static void crashElegantly(String errorDetails) {
private void crashElegantly(String errorDetails) {
StringBuilder msgBuilder = new StringBuilder(2000);
msgBuilder.append("Failed to initialize graphics window with current settings.\n");
msgBuilder.append("\n\n");
@@ -511,7 +512,7 @@ public class DisplayWindow implements ImmediateWindowProvider {
this.winY = y;
}
}
private static void handleLastGLFWError(BiConsumer<Integer, String> handler) {
private void handleLastGLFWError(BiConsumer<Integer, String> handler) {
try (MemoryStack memorystack = MemoryStack.stackPush()) {
PointerBuffer pointerbuffer = memorystack.mallocPointer(1);
int error = glfwGetError(pointerbuffer);
@@ -639,7 +640,7 @@ public class DisplayWindow implements ImmediateWindowProvider {
}
public void addMojangTexture(final int textureId) {
this.elements.addFirst(RenderElement.mojang(textureId, framecount));
this.elements.add(0, RenderElement.mojang(textureId, framecount));
}
public void close() {
@@ -22,8 +22,8 @@ public class RenderElement {
static int globalAlpha = 255;
private int retireCount;
@FunctionalInterface
interface Renderer {
void accept(SimpleBufferBuilder bb, DisplayContext context, int frame);
default Renderer then(Renderer r) {
@@ -38,9 +38,6 @@ public class RenderElement {
interface TextureRenderer {
void accept(SimpleBufferBuilder bb, DisplayContext context, int[] size, int frame);
}
/** @deprecated Use {@link Renderer} directly. This was always eagerly resolved, making it an unnecessary wrapper. */
@Deprecated(since = "1.21.5", forRemoval = true)
@FunctionalInterface
interface Initializer extends Supplier<Renderer> {}
@@ -59,18 +56,11 @@ public class RenderElement {
}
}
/** @deprecated Use {@link RenderElement#RenderElement(Renderer)} instead */
@Deprecated(since = "1.21.5", forRemoval = true)
public RenderElement(final Initializer rendererInitializer) {
this.bb = new SimpleBufferBuilder(1);
this.renderer = rendererInitializer.get();
}
public RenderElement(Renderer renderer) {
this.bb = new SimpleBufferBuilder(1);
this.renderer = renderer;
}
public boolean render(DisplayContext ctx, int count) {
this.renderer.accept(bb, ctx, count);
return this.retireCount == 0 || this.retireCount < count;
@@ -85,7 +75,7 @@ public class RenderElement {
List<SimpleFont.DisplayText> texts = new ArrayList<>();
for (int i = messages.size() - 1; i >= 0; i--) {
final StartupNotificationManager.AgeMessage pair = messages.get(i);
final float fade = Math.clamp((4000.0f - (float) pair.age() - ( i - 4 ) * 1000.0f) / 5000.0f, 0.0f, 1.0f);
final float fade = clamp((4000.0f - (float) pair.age() - ( i - 4 ) * 1000.0f) / 5000.0f, 0.0f, 1.0f);
if (fade <0.01f) continue;
Message msg = pair.message();
int colour = Math.min((int)(fade * 255f), globalAlpha) << 24 | 0xFFFFFF;
@@ -94,9 +84,19 @@ public class RenderElement {
font.generateVerticesForTexts(10, context.scaledHeight() - texts.size() * font.lineSpacing() + font.descent() - 10, bb, texts.toArray(SimpleFont.DisplayText[]::new));
}
public static RenderElement monag() {
return new RenderElement(RenderElement.initializeTexture("monagstudios.png", 45000, 4, (bb, ctx, sz, frame) -> {
var size = 256;
var x0 = (ctx.width() - 2 * size) / 2;
var y0 = 64;
QuadHelper.loadQuad(bb, x0, x0+size, y0, y0+size/2f, 0f, 1f, 0f, 0.5f, 0xFFFFFFFF);
QuadHelper.loadQuad(bb, x0+size, x0+2*size, y0, y0+size/2f, 0f, 1f, 0.5f, 1f, 0xFFFFFFFF);
}));
}
public static RenderElement mojang(final int textureId, final int frameStart) {
return new RenderElement((bb, ctx, frame) -> {
return new RenderElement(()->(bb, ctx, frame) -> {
var size = 256 * ctx.scale();
var x0 = (ctx.scaledWidth() - 2 * size) / 2;
var y0 = 64 * ctx.scale() + 32;
@@ -148,11 +148,11 @@ public class RenderElement {
}));
}
public static RenderElement progressBars(SimpleFont font) {
return new RenderElement((bb, ctx, frame) -> RenderElement.startupProgressBars(font, bb, ctx, frame));
return new RenderElement(() -> (bb, ctx, frame) -> RenderElement.startupProgressBars(font, bb, ctx, frame));
}
public static RenderElement performanceBar(SimpleFont font) {
return new RenderElement((bb, ctx, frame) -> RenderElement.memoryInfo(font, bb, ctx, frame));
return new RenderElement(() -> (bb, ctx, frame) -> RenderElement.memoryInfo(font, bb, ctx, frame));
}
public static void startupProgressBars(SimpleFont font, final SimpleBufferBuilder buffer, final DisplayContext context, final int frameNumber) {
@@ -187,10 +187,10 @@ public class RenderElement {
}
private static float[] indeterminateBar(int frame, boolean isActive) {
if (RenderElement.globalAlpha != 0xFF || !isActive) {
return new float[] { 0f, 1f };
return new float[] {0f,1f};
} else {
int progress = frame % 100;
return new float[] { Math.clamp((progress - 2) / 100f, 0f, 1f), Math.clamp((progress + 2) / 100f, 0f, 1f) };
var progress = frame % 100;
return new float[]{clamp((progress - 2) / 100f, 0f, 1f), clamp((progress + 2) / 100f, 0f, 1f)};
}
}
@@ -249,8 +249,8 @@ public class RenderElement {
};
}
private static Renderer initializeText(SimpleFont font, TextGenerator textGenerator) {
return (bb, context, frame) -> renderText(font, textGenerator, bb, context);
private static Initializer initializeText(SimpleFont font, TextGenerator textGenerator) {
return () -> (bb, context, frame) -> renderText(font, textGenerator, bb, context);
}
private static void renderText(final SimpleFont font, final TextGenerator textGenerator, final SimpleBufferBuilder bb, final DisplayContext context) {
@@ -264,13 +264,14 @@ public class RenderElement {
private static TextGenerator text(int x, int y, String text, int colour) {
return (bb, font, context) -> font.generateVerticesForTexts(x, y, bb, new SimpleFont.DisplayText(text, colour));
}
private static Renderer initializeTexture(final String textureFileName, int size, int textureNumber, TextureRenderer positionAndColour) {
int[] imgSize = STBHelper.loadTextureFromClasspath(textureFileName, size, GL_TEXTURE0 + textureNumber + INDEX_TEXTURE_OFFSET);
return (bb, ctx, frame) -> {
ctx.elementShader().updateTextureUniform(textureNumber + INDEX_TEXTURE_OFFSET);
ctx.elementShader().updateRenderTypeUniform(ElementShader.RenderType.TEXTURE);
renderTexture(bb, ctx, frame, imgSize, positionAndColour);
private static Initializer initializeTexture(final String textureFileName, int size, int textureNumber, TextureRenderer positionAndColour) {
return ()->{
int[] imgSize = STBHelper.loadTextureFromClasspath(textureFileName, size, GL_TEXTURE0 + textureNumber + INDEX_TEXTURE_OFFSET);
return (bb, ctx, frame) -> {
ctx.elementShader().updateTextureUniform(textureNumber + INDEX_TEXTURE_OFFSET);
ctx.elementShader().updateRenderTypeUniform(ElementShader.RenderType.TEXTURE);
renderTexture(bb, ctx, frame, imgSize, positionAndColour);
};
};
}
@@ -280,13 +281,21 @@ public class RenderElement {
bb.draw();
}
@Deprecated(since = "1.21.5", forRemoval = true)
public static float clamp(float num, float min, float max) {
return Math.clamp(num, min, max);
if (num < min) {
return min;
} else {
return Math.min(num, max);
}
}
public static int clamp(int num, int min, int max) {
return Math.min(max, Math.max(num, min));
if (num < min) {
return min;
} else {
return Math.min(num, max);
}
}
public static int hsvToRGB(float hue, float saturation, float value) {
@@ -22,7 +22,7 @@ public class SimpleFont {
private final int textureNumber;
private final int lineSpacing;
private final int descent;
private static final int GLYPH_COUNT = 127 - 32;
private final int GLYPH_COUNT = 127-32;
private final Glyph[] glyphs;
private record Glyph(char c, int charwidth, int[] pos, float[] uv) {
@@ -120,7 +120,7 @@ public class SimpleFont {
case '\n', '\t' -> 0;
case ' ' -> glyphs[0].charwidth();
default -> {
if (c - 32 < GLYPH_COUNT && c > 32) {
if (c - 32 < this.GLYPH_COUNT && c > 32) {
yield this.glyphs[c - 32].charwidth();
} else {
yield 0;
@@ -151,7 +151,7 @@ public class SimpleFont {
case '\t' -> new Pos(pos.x()+font.glyphs[0].charwidth() * 4, pos.y(), pos.minx());
case ' ' -> new Pos(pos.x()+font.glyphs[0].charwidth(), pos.y(), pos.minx());
default -> {
if (c-32 < GLYPH_COUNT && c > 32) {
if (c-32 < font.GLYPH_COUNT && c > 32) {
pos = font.glyphs[c - 32].loadQuad(pos, colour(), bb);
}
yield pos;
+3 -23
View File
@@ -5,7 +5,6 @@ plugins {
id 'maven-publish'
id 'net.minecraftforge.licenser'
id 'net.minecraftforge.gradleutils'
alias(libs.plugins.apt)
}
apply from: rootProject.file('build_shared.gradle')
@@ -13,7 +12,7 @@ apply from: rootProject.file('build_shared.gradle')
configurations.forEach{ it.transitive = false }
dependencies {
compileOnly(libs.jetbrains.annotations)
compileOnly(libs.nulls)
api(libs.bundles.asm) // Needed by all the black magic
api(libs.forgespi)
@@ -37,11 +36,10 @@ dependencies {
implementation(libs.terminalconsoleappender)
implementation(libs.jimfs)
// Needed because we have a custom log4j plugin, and they removed package scanning and require a data file to be generated
implementation(libs.log4j.core)
annotationProcessor(libs.bundles.log4j)
testCompileOnly(libs.jetbrains.annotations)
testCompileOnly(libs.nulls)
testRuntimeOnly(libs.bootstrap)
}
@@ -87,7 +85,7 @@ publishing {
license PomUtils.Licenses.LGPLv2_1
}
}
repositories {
maven gradleutils.publishingForgeMaven
}
@@ -104,23 +102,5 @@ tasks.register('writeForgeVersionJson') {
}
tasks.named('generateResources').configure {
dependsOn('eclipseJdt')
dependsOn('eclipseJdtApt')
dependsOn('eclipseFactorypath')
dependsOn('writeForgeVersionJson')
}
eclipse {
classpath {
// We need to set the default output directory for the log4j annotation processor
// Ideally we'd just set the value, but the eclipse plugin deduplicates the output directories
// So we have to do a hacky whenMerged
//defaultOutputDir = file('bin/main')
file.whenMerged {
entries.each { entry ->
if (entry.kind == 'output' && entry.hasProperty('path'))
entry.path = 'bin/main'
}
}
}
}
@@ -6,13 +6,14 @@
package net.minecraftforge.fml.loading;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class BackgroundWaiter {
private static final ExecutorService runner = Executors.newSingleThreadExecutor();
public static void runAndTick(Runnable r, Runnable tick) {
var runner = Executors.newSingleThreadExecutor();
ImmediateWindowHandler.updateProgress("Loading bootstrap resources");
final Future<?> work = runner.submit(r);
do {
@@ -56,6 +56,7 @@ public class FMLLoader {
checkPackage(ITransformationService.class, "4.0", "ModLauncher");
accessTransformer = getPlugin(env, "accesstransformer", "1.0", "AccessTransformer");
/*eventBus =*/ getPlugin(env, "eventbus", "1.0", "EventBus");
runtimeDistCleaner = getPlugin(env, "runtimedistcleaner", "1.0", "RuntimeDistCleaner");
coreModProvider = getSingleService(ICoreModProvider.class, "CoreMod");
LOGGER.debug(CORE, "FML found CoreMod version : {}", JarVersionLookupHandler.getInfo(coreModProvider.getClass()).impl().version().orElse("MISSING"));
@@ -7,6 +7,7 @@ package net.minecraftforge.fml.loading;
import com.mojang.logging.LogUtils;
import cpw.mods.modlauncher.api.*;
import joptsimple.OptionSpecBuilder;
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
import net.minecraftforge.forgespi.Environment;
import org.jetbrains.annotations.NotNull;
@@ -18,6 +19,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
import static net.minecraftforge.fml.loading.LogMarkers.CORE;
public class FMLServiceProvider implements ITransformationService {
@@ -40,21 +40,6 @@ public class RuntimeDistCleaner implements ILaunchPluginService {
return "runtimedistcleaner";
}
private static final EnumSet<Phase> YAY = EnumSet.of(Phase.AFTER);
private static final EnumSet<Phase> NAY = EnumSet.noneOf(Phase.class);
@Override
public EnumSet<Phase> handlesClass(Type classType, boolean isEmpty) {
if (isEmpty)
return NAY;
String internalName = classType.getInternalName();
if (internalName.startsWith("net/minecraftforge/"))
return NAY;
return YAY;
}
@Override
public int processClassWithFlags(final Phase phase, final ClassNode classNode, final Type classType, final String reason) {
var changed = false;
@@ -213,6 +198,21 @@ public class RuntimeDistCleaner implements ILaunchPluginService {
};
}
private static final EnumSet<Phase> YAY = EnumSet.of(Phase.AFTER);
private static final EnumSet<Phase> NAY = EnumSet.noneOf(Phase.class);
@Override
public EnumSet<Phase> handlesClass(Type classType, boolean isEmpty) {
if (isEmpty)
return NAY;
String internalName = classType.getInternalName();
if (internalName.startsWith("net/minecraftforge/"))
return NAY;
return YAY;
}
private static class LambdaGatherer extends MethodVisitor {
private static final Handle META_FACTORY = new Handle(Opcodes.H_INVOKESTATIC,
"java/lang/invoke/LambdaMetafactory", "metafactory",
@@ -18,7 +18,9 @@ import org.apache.logging.log4j.util.PerformanceSensitive;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* A wrapper for {@link HighlightConverter} that auto-disables ANSI when the terminal doesn't support it.
@@ -9,6 +9,7 @@ import cpw.mods.modlauncher.api.LamdbaExceptionUtils.Supplier_WithExceptions;
import net.minecraftforge.fml.loading.StringUtils;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Optional;
import java.util.function.BiPredicate;
import java.util.stream.Stream;
@@ -43,10 +43,10 @@ public final class MinecraftLocator extends AbstractModProvider implements IModL
mods.set("modId", "minecraft");
mods.set("version", FMLLoader.versionInfo().mcVersion());
mods.set("displayName", "Minecraft");
//mods.set("logoFile", "mcplogo.png");
//mods.set("credits", "Mojang, deobfuscated by MCP");
//mods.set("authors", "MCP: Searge,ProfMobius,IngisKahn,Fesh0r,ZeuX,R4wk,LexManos,Bspkrs");
mods.set("description", "The base Minecraft game, published by Mojang decompiled and deobfuscated by Forge");
mods.set("logoFile", "mcplogo.png");
mods.set("credits", "Mojang, deobfuscated by MCP");
mods.set("authors", "MCP: Searge,ProfMobius,IngisKahn,Fesh0r,ZeuX,R4wk,LexManos,Bspkrs");
mods.set("description", "Minecraft, decompiled and deobfuscated with MCP technology");
conf.set("mods", List.of(mods));
var configWrapper = new NightConfigWrapper(conf);
@@ -17,6 +17,7 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
@@ -81,10 +81,6 @@ class ArgumentList {
.toArray(String[]::new);
}
public boolean has(String key) {
return this.values.containsKey(key);
}
public boolean hasValue(String key) {
return getOrDefault(key, null) != null;
}
@@ -22,10 +22,6 @@ abstract class CommonDevLaunchHandler extends CommonLaunchHandler {
super(type, prefix);
}
protected CommonDevLaunchHandler(String name) {
super(name);
}
@Override public String getNaming() { return "mcp"; }
@Override public boolean isProduction() { return false; }
@@ -33,35 +29,13 @@ abstract class CommonDevLaunchHandler extends CommonLaunchHandler {
protected String[] preLaunch(String[] arguments, ModuleLayer layer) {
super.preLaunch(arguments, layer);
var args = ArgumentList.from(arguments);
if (this.module == null) {
var entry = args.get("launchEntry");
if (entry == null)
throw new IllegalArgumentException("When using " + this.name() + " launch target you must specify a --launchEntry argument");
args.remove("launchEntry");
int idx = entry.indexOf('/');
if (idx == -1) {
this.module = "minecraft";
this.main = entry;
} else {
this.module = entry.substring(0, idx);
this.main = entry.substring(idx + 1);
}
if (args.has("launchData")) {
args.remove("launchData");
this.isData = true;
}
}
if (getDist().isDedicatedServer())
return args.getArguments();
return arguments;
if (isData())
return args.getArguments();
return arguments;
var args = ArgumentList.from(arguments);
String username = args.get("username");
if (username != null) { // Replace '#' placeholders with random numbers
@@ -29,27 +29,17 @@ import java.util.List;
public abstract class CommonLaunchHandler implements ILaunchHandlerService {
protected static final Logger LOGGER = LogUtils.getLogger();
private final String name;
protected Dist dist = Dist.CLIENT;
protected boolean isData = false;
protected String module;
protected String main;
protected final LaunchType type;
private final String prefix;
protected CommonLaunchHandler(LaunchType type, String prefix) {
this(prefix + type.name());
this.dist = type.dist();
this.isData = type.data();
this.module = type.module();
this.main = type.main();
this.type = type;
this.prefix = prefix;
}
protected CommonLaunchHandler(String name) {
this.name = name;
}
@Override public String name() { return this.name; }
public Dist getDist() { return this.dist; }
public boolean isData() { return this.isData; }
@Override public String name() { return this.prefix + this.type.name(); }
public Dist getDist() { return this.type.dist(); }
public boolean isData() { return this.type.data(); }
public boolean isProduction() { return false; }
public abstract String getNaming();
@@ -76,15 +66,14 @@ public abstract class CommonLaunchHandler implements ILaunchHandlerService {
}
protected ServiceRunner makeService(final String[] arguments, final ModuleLayer gameLayer) {
return () -> runTarget(this.module, this.main, arguments, gameLayer);
return () -> runTarget(this.type.module(), this.type.main(), arguments, gameLayer);
}
protected record LaunchType(String name, String module, String main, Dist dist, boolean data) {};
protected static final LaunchType CLIENT = new LaunchType("client", "minecraft", "net.minecraft.client.main.Main", Dist.CLIENT, false);
protected static final LaunchType CLIENT_DATA = new LaunchType("client_data", "minecraft", "net.minecraft.client.data.Main", Dist.CLIENT, true);
protected static final LaunchType DATA = new LaunchType("data", "minecraft", "net.minecraft.data.Main", Dist.CLIENT, true);
protected static final LaunchType SERVER = new LaunchType("server", "minecraft", "net.minecraft.server.Main", Dist.DEDICATED_SERVER, false);
protected static final LaunchType SERVER_GAMETEST = new LaunchType("server_gametest", "minecraft", "net.minecraft.gametest.Main", Dist.DEDICATED_SERVER, false);
protected static final LaunchType SERVER_GAMETEST = new LaunchType("server_gametest", "net.minecraftforge.forge", "net.minecraftforge.gametest.GameTestMain", Dist.DEDICATED_SERVER, false);
protected void runTarget(String module, String target, final String[] arguments, final ModuleLayer layer) throws Throwable {
var mod = layer.findModule(module).orElse(null);
@@ -14,14 +14,12 @@ sealed abstract class ForgeDevLaunchHandler extends CommonDevLaunchHandler {
super(type, "forge_dev_");
}
private ForgeDevLaunchHandler(String name) {
super(name);
}
@Override
public List<Path> getMinecraftPaths() {
// The client extra jar is on the classpath we can try locating it using the .mcassetsroot which vanilla uses for loading data
var extra = getPathFromResource("assets/.mcassetsroot");
// The extra jar is on the classpath, so try and pull it out of the legacy classpath
var legacyCP = findClassPath();
var extra = findJarOnClasspath(legacyCP, "client-extra");
// Minecraft is an exploded directory, so find it.
var minecraft = getPathFromResource("net/minecraft/client/Minecraft.class");
var forge = getPathFromResource("net/minecraftforge/common/MinecraftForge.class");
@@ -41,12 +39,6 @@ sealed abstract class ForgeDevLaunchHandler extends CommonDevLaunchHandler {
}
}
public static final class ClientData extends ForgeDevLaunchHandler {
public ClientData() {
super(CLIENT_DATA);
}
}
public static final class Data extends ForgeDevLaunchHandler {
public Data() {
super(DATA);
@@ -64,10 +56,4 @@ sealed abstract class ForgeDevLaunchHandler extends CommonDevLaunchHandler {
super(SERVER_GAMETEST);
}
}
public static final class Custom extends ForgeDevLaunchHandler {
public Custom() {
super("forge_dev");
}
}
}
@@ -96,14 +96,14 @@ public final class ForgeDevLocator extends AbstractModProvider implements IModLo
// Find resource directories for every mod in this group
var paths = new LinkedHashSet<Path>();
for (var modid : modids.stream().sorted().toList()) {
for (var modid : modids) {
var rsc = path.resolve(modid);
if (Files.exists(rsc))
paths.add(rsc);
}
var root = memory.getPath(modids.iterator().next()); // use the first modid as our root
buildModsToml(paths, modids, root, pkg.startsWith("net/minecraftforge/debug/client/"));
buildModsToml(paths, modids, root);
buildPackMeta(paths, root);
moveModuleInfo(paths, root);
@@ -187,7 +187,7 @@ public final class ForgeDevLocator extends AbstractModProvider implements IModLo
}
// Builds or update the mods.toml file for all @Mods in this package
private static void buildModsToml(Set<Path> resources, Set<String> modids, Path root, boolean clientOnly) {
private static void buildModsToml(Set<Path> resources, Set<String> modids, Path root) {
var toml = resources.stream()
.map(p -> p.resolve(MODS_TOML))
.filter(Files::exists)
@@ -205,8 +205,7 @@ public final class ForgeDevLocator extends AbstractModProvider implements IModLo
var defaults = Map.of(
"modLoader", "javafml",
"loaderVersion", "[0,)",
"license", "Doesnt fucking matter",
"clientSideOnly", clientOnly
"license", "Doesnt fucking matter"
);
for (var key : defaults.keySet()) {
@@ -8,18 +8,17 @@ package net.minecraftforge.fml.loading.targets;
import net.minecraftforge.fml.loading.FMLLoader;
import java.nio.file.Path;
import java.util.List;
import java.util.function.BiPredicate;
import org.jetbrains.annotations.ApiStatus;
import cpw.mods.jarhandling.SecureJar;
@ApiStatus.Internal
sealed abstract class ForgeUserdevLaunchHandler extends CommonDevLaunchHandler {
private ForgeUserdevLaunchHandler(LaunchType type) {
super(type, "forge_userdev_");
}
private ForgeUserdevLaunchHandler(String name) {
super(name);
}
@Override
public List<Path> getMinecraftPaths() {
var legacyCP = findClassPath();
@@ -27,7 +26,7 @@ sealed abstract class ForgeUserdevLaunchHandler extends CommonDevLaunchHandler {
// Minecraft is extra jar {resources} + forge jar {patches}
// The MC extra and forge jars are on the classpath, so try and pull them out
var extra = findJarOnClasspath(legacyCP, "client-extra"); // This should be "client-" + vers.mcAndMCPVersion() + "-extra" but FG6 qwerks
var extra = findJarOnClasspath(legacyCP, "client-extra");
var forge = findJarOnClasspath(legacyCP, "forge-" + vers.mcAndForgeVersion());
// We need to filter the forge jar to just MC code
var minecraft = CommonDevLaunchHandler.getMinecraftOnly(extra, forge);
@@ -40,12 +39,6 @@ sealed abstract class ForgeUserdevLaunchHandler extends CommonDevLaunchHandler {
}
}
public static final class ClientData extends ForgeUserdevLaunchHandler {
public ClientData() {
super(CLIENT_DATA);
}
}
public static final class Data extends ForgeUserdevLaunchHandler {
public Data() {
super(DATA);
@@ -63,10 +56,4 @@ sealed abstract class ForgeUserdevLaunchHandler extends CommonDevLaunchHandler {
super(SERVER_GAMETEST);
}
}
public static final class Custom extends ForgeUserdevLaunchHandler {
public Custom() {
super("forge_userdev");
}
}
}
@@ -4,16 +4,12 @@ net.minecraftforge.fml.loading.targets.ForgeProdLaunchHandler$Server
# Mod Developers
net.minecraftforge.fml.loading.targets.ForgeUserdevLaunchHandler$Client
net.minecraftforge.fml.loading.targets.ForgeUserdevLaunchHandler$ClientData
net.minecraftforge.fml.loading.targets.ForgeUserdevLaunchHandler$Custom
net.minecraftforge.fml.loading.targets.ForgeUserdevLaunchHandler$Data
net.minecraftforge.fml.loading.targets.ForgeUserdevLaunchHandler$Server
net.minecraftforge.fml.loading.targets.ForgeUserdevLaunchHandler$ServerGameTest
#Working on Forge itself
net.minecraftforge.fml.loading.targets.ForgeDevLaunchHandler$Client
net.minecraftforge.fml.loading.targets.ForgeDevLaunchHandler$ClientData
net.minecraftforge.fml.loading.targets.ForgeDevLaunchHandler$Custom
net.minecraftforge.fml.loading.targets.ForgeDevLaunchHandler$Data
net.minecraftforge.fml.loading.targets.ForgeDevLaunchHandler$Server
net.minecraftforge.fml.loading.targets.ForgeDevLaunchHandler$ServerGameTest
+1 -1
View File
@@ -4,7 +4,7 @@
SPDX-License-Identifier: LGPL-2.1-only
-->
<Configuration status="warn" shutdownHook="disable">
<Configuration status="warn" packages="net.minecrell.terminalconsole,net.minecrell.terminalconsole.util,com.mojang.util,cpw.mods.modlauncher.log,net.minecraftforge.fml.loading.log4j" shutdownHook="disable">
<filters>
<ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
<MarkerFilter marker="NETWORK_PACKETS" onMatch="${sys:forge.logging.marker.networking:-DENY}" onMismatch="NEUTRAL"/>
+7 -7
View File
@@ -1,17 +1,17 @@
# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
# This is required to provide enough memory for the Minecraft decompilation process.
org.gradle.jvmargs=-Xmx6G
org.gradle.jvmargs=-Xmx3G
org.gradle.daemon=false
org.gradle.parallel=true
JAVA_VERSION=21
MC_VERSION=1.21.8
MC_VERSION=1.21.3
MC_NEXT_VERSION=1.22
MCP_VERSION=20250717.105350
MCP_VERSION=20241025.112443
MAPPING_CHANNEL=official
MAPPING_VERSION=1.21.8
MAPPING_VERSION=1.21.3
# Set to true before the first build of a new MC version, so we don't do compatibility checks
// Set to true before the first build of a new MC version, so we don't do compatibility checks
CHECK_COMPATIBILITY=false
# Set to true to allow for fuzzy patching. Useful during updateing
UPDATING=false
// Set to true to allow for fuzzy patching. Useful during updateing
UPDATING=false
+1 -1
View File
@@ -10,7 +10,7 @@ plugins {
apply from: rootProject.file('build_shared.gradle')
dependencies {
compileOnly(libs.jetbrains.annotations)
compileOnly(libs.nulls)
implementation(project(':fmlloader'))
implementation(project(':fmlcore'))
implementation(libs.unsafe)
@@ -12,10 +12,9 @@ import java.lang.annotation.Target;
import java.util.function.Supplier;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.eventbus.api.bus.BusGroup;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.Bindings;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import org.jspecify.annotations.Nullable;
/**
* This defines a Mod to FML.
@@ -25,11 +24,12 @@ import org.jspecify.annotations.Nullable;
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Mod {
public @interface Mod
{
/**
* The unique mod identifier for this mod.
* <b>Required to be lowercased in the English locale for compatibility. Will be truncated to 64 characters long.</b>
* <br>
* <b>Required to be lowercased in the english locale for compatibility. Will be truncated to 64 characters long.</b>
*
* This will be used to identify your mod for third parties (other mods), it will be used to identify your mod for registries such as block and item registries.
* By default, you will have a resource domain that matches the modid. All these uses require that constraints are imposed on the format of the modid.
*/
@@ -61,40 +61,32 @@ public @interface Mod {
String modid() default "";
/**
* Specify an alternative bus to listen to.
* <br>
* If you know all listeners in this class are for a specific bus, you can set it here to speed up registration.
* Specify an alternative bus to listen to
*
* @return the bus you wish to listen to
*/
Bus bus() default Bus.BOTH;
Bus bus() default Bus.FORGE;
enum Bus {
/**
* The main BusGroup that most game events are fired on.
* The main Forge Event Bus.
*
* <p>See {@code MinecraftForge#EVENT_BUS}</p>
*/
FORGE(Bindings.getForgeBus()),
/**
* The mod-specific event BusGroup, usually for mod lifecycle events.
* @see FMLJavaModLoadingContext#getModBusGroup()
* The mod specific Event bus.
* @see FMLJavaModLoadingContext#getModEventBus()
*/
MOD(()-> FMLJavaModLoadingContext.get().getModBusGroup()),
MOD(()-> FMLJavaModLoadingContext.get().getModEventBus());
/**
* Both the {@link #FORGE} and {@link #MOD} buses. This is slower to register events in your class but
* allows you to listen to events from different BusGroup types without needing separate classes annotated
* with {@link EventBusSubscriber}.
*/
BOTH(() -> null);
private final Supplier<IEventBus> busSupplier;
private final Supplier<@Nullable BusGroup> busSupplier;
Bus(Supplier<@Nullable BusGroup> eventBusSupplier) {
Bus(final Supplier<IEventBus> eventBusSupplier) {
this.busSupplier = eventBusSupplier;
}
public Supplier<@Nullable BusGroup> bus() {
public Supplier<IEventBus> bus() {
return busSupplier;
}
}
@@ -7,40 +7,22 @@ package net.minecraftforge.fml.javafmlmod;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.eventbus.api.bus.BusGroup;
import net.minecraftforge.eventbus.api.bus.CancellableEventBus;
import net.minecraftforge.eventbus.api.bus.EventBus;
import net.minecraftforge.eventbus.api.event.characteristic.Cancellable;
import net.minecraftforge.eventbus.api.listener.EventListener;
import net.minecraftforge.eventbus.api.listener.ObjBooleanBiConsumer;
import net.minecraftforge.eventbus.api.listener.Priority;
import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
import net.minecraftforge.eventbus.internal.Event;
import net.minecraftforge.fml.Logging;
import net.minecraftforge.fml.ModContainer;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
import net.minecraftforge.fml.event.IModBusEvent;
import net.minecraftforge.forgespi.language.ModFileScanData;
import net.minecraftforge.forgespi.language.ModFileScanData.AnnotationData;
import net.minecraftforge.forgespi.language.ModFileScanData.EnumData;
import net.minecraftforge.fml.loading.FMLEnvironment;
import net.minecraftforge.unsafe.UnsafeHacks;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jspecify.annotations.Nullable;
import org.objectweb.asm.Type;
import java.lang.invoke.LambdaMetafactory;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
@@ -93,7 +75,7 @@ public class AutomaticEventSubscriber {
if (Objects.equals(mod.getModId(), modId) && sides.contains(FMLEnvironment.dist)) {
try {
LOGGER.debug(Logging.LOADING, "Auto-subscribing {} to {}", data.clazz().getClassName(), busTarget);
EventBusSubscriberLogic.register(busTarget.bus().get(), Class.forName(data.clazz().getClassName(), true, loader));
busTarget.bus().get().register(Class.forName(data.clazz().getClassName(), true, loader));
} catch (ClassNotFoundException e) {
LOGGER.fatal(Logging.LOADING, "Failed to load mod class {} for @EventBusSubscriber annotation", data.clazz(), e);
throw new RuntimeException(e);
@@ -106,320 +88,4 @@ public class AutomaticEventSubscriber {
private static <R> R value(AnnotationData data, String key, R value) {
return (R)data.annotationData().getOrDefault(key, value);
}
/**
* This is mostly a carbon copy of EventBus 7's internal EventListenerFactory, with some changes to support adding
* to different BusGroups based on the event type, among other things.
*/
private static final class EventBusSubscriberLogic {
private EventBusSubscriberLogic() {}
private static final boolean STRICT_RUNTIME_CHECKS = Boolean.getBoolean("eventbus.api.strictRuntimeChecks");
/**
* If true, performs exhaustive validation on bulk registration to aid debugging.
*/
private static final boolean STRICT_REGISTRATION_CHECKS = STRICT_RUNTIME_CHECKS || Boolean.getBoolean("eventbus.api.strictRegistrationChecks");
private static final MethodType RETURNS_CONSUMER = MethodType.methodType(Consumer.class);
private static final MethodType RETURNS_PREDICATE = MethodType.methodType(Predicate.class);
private static final MethodType RETURNS_MONITOR = MethodType.methodType(ObjBooleanBiConsumer.class);
/** The method type of the {@link Consumer} functional interface ({@code void accept(Object)}) */
private static final MethodType CONSUMER_FI_TYPE = MethodType.methodType(void.class, Object.class);
/** The method type of the {@link Predicate} functional interface ({@code boolean test(Object)}) */
private static final MethodType PREDICATE_FI_TYPE = CONSUMER_FI_TYPE.changeReturnType(boolean.class);
/** The method type of the {@link ObjBooleanBiConsumer} functional interface ({@code void accept(Object, boolean)}) */
private static final MethodType MONITOR_FI_TYPE = MethodType.methodType(void.class, Object.class, boolean.class);
public static void register(@Nullable BusGroup busGroup, Class<?> listenerClass) {
if (STRICT_REGISTRATION_CHECKS) registerStrict(busGroup, listenerClass);
else registerLenient(busGroup, listenerClass);
}
@SuppressWarnings({"unchecked", "rawtypes"})
public static void registerLenient(@Nullable BusGroup busGroup, Class<?> listenerClass) {
Method[] declaredMethods = listenerClass.getDeclaredMethods();
if (declaredMethods.length == 0)
throw new IllegalArgumentException("No declared methods found in " + listenerClass);
Class<?> firstValidListenerEventType = null;
int listenersCount = 0;
for (var method : declaredMethods) {
if (!Modifier.isStatic(method.getModifiers()))
continue;
if (method.isSynthetic())
continue; // EventBus#89
int paramCount = method.getParameterCount();
if (paramCount == 0 || paramCount > 2)
continue;
Class<?> returnType = method.getReturnType();
if (returnType != void.class && returnType != boolean.class)
continue;
if (!method.isAnnotationPresent(SubscribeEvent.class))
continue;
Class<?>[] parameterTypes = method.getParameterTypes();
if (!Event.class.isAssignableFrom(parameterTypes[0]))
throw new IllegalArgumentException("First parameter of a @SubscribeEvent method must be an event");
Class<? extends Event> eventType = (Class<? extends Event>) parameterTypes[0];
var subscribeEventAnnotation = method.getAnnotation(SubscribeEvent.class);
registerListener(busGroup, paramCount, returnType, eventType, subscribeEventAnnotation, method);
listenersCount++;
if (firstValidListenerEventType == null)
firstValidListenerEventType = eventType;
}
if (listenersCount == 0)
throw new IllegalArgumentException("No listeners found in " + listenerClass);
else if (firstValidListenerEventType == null)
throw new IllegalArgumentException("No valid listeners found in " + listenerClass);
}
@SuppressWarnings({"unchecked"})
public static void registerStrict(BusGroup busGroup, Class<?> listenerClass) {
Class<? extends Event> firstValidListenerEventType = null;
List<Method> declaredMethods = Arrays.stream(listenerClass.getDeclaredMethods())
.filter(Predicate.not(Method::isSynthetic)) // EventBus#89
.toList();
if (declaredMethods.isEmpty()) {
var errMsg = "No declared methods found in " + listenerClass.getName();
var superClass = listenerClass.getSuperclass();
if (superClass != null && superClass != Record.class && superClass != Enum.class) {
errMsg += ". Note that listener inheritance is not supported. " +
"If you are trying to inherit listeners, please use @Override and @SubscribeEvent on the method in the subclass.";
}
throw fail(listenerClass, errMsg);
}
int listenersCount = 0;
for (var method : declaredMethods) {
var hasSubscribeEvent = method.isAnnotationPresent(SubscribeEvent.class);
int paramCount = method.getParameterCount();
if (hasSubscribeEvent && (paramCount == 0 || paramCount > 2))
throw fail(method, "Invalid number of parameters: " + paramCount + " (expected 1 or 2)");
if (paramCount == 0)
continue;
Class<?> returnType = method.getReturnType();
Class<?>[] parameterTypes = method.getParameterTypes();
var firstParamExtendsEvent = Event.class.isAssignableFrom(parameterTypes[0]);
if (!hasSubscribeEvent && firstParamExtendsEvent)
throw fail(method, "Missing @SubscribeEvent annotation");
if (hasSubscribeEvent) {
var firstParamExtendsCancellable = Cancellable.class.isAssignableFrom(parameterTypes[0]);
var subscribeEventAnnotation = method.getAnnotation(SubscribeEvent.class);
var isMonitoringPriority = subscribeEventAnnotation.priority() == Priority.MONITOR;
if (!firstParamExtendsEvent)
throw fail(method, "First parameter of a @SubscribeEvent method must be an event");
var eventType = (Class<? extends Event>) parameterTypes[0];
if (returnType != void.class && returnType != boolean.class)
throw fail(method, "Invalid return type: " + returnType.getName() + " (expected void or boolean)");
if (!Modifier.isStatic(method.getModifiers()))
throw fail(method, "Listener method needs to be static");
if (isMonitoringPriority && (returnType == boolean.class || subscribeEventAnnotation.alwaysCancelling()))
throw fail(method, "Monitoring listeners cannot cancel events");
if (paramCount == 2) {
if (!firstParamExtendsCancellable)
throw fail(method, "Cancellation-aware monitoring listeners are only valid for cancellable events");
if (!boolean.class.isAssignableFrom(parameterTypes[1]))
throw fail(method, "Second parameter of a cancellation-aware monitoring listener must be a boolean");
if (!isMonitoringPriority)
throw fail(method, "Cancellation-aware monitoring listeners must have a priority of MONITOR");
}
if (!firstParamExtendsCancellable) {
if (subscribeEventAnnotation.alwaysCancelling())
throw fail(method, "Always cancelling listeners are only valid for cancellable events");
if (returnType == boolean.class)
throw fail(method, "Return type boolean is only valid for cancellable events");
}
registerListener(busGroup, paramCount, returnType, eventType, subscribeEventAnnotation, method);
listenersCount++;
if (firstValidListenerEventType == null)
firstValidListenerEventType = eventType;
}
}
if (listenersCount == 0)
throw fail(listenerClass, "No listeners found");
else if (firstValidListenerEventType == null)
throw fail(listenerClass, "No valid listeners found");
}
@SuppressWarnings({"unchecked", "rawtypes"})
private static EventListener registerListener(@Nullable BusGroup busGroup,
int paramCount, Class<?> returnType, Class<? extends Event> eventType,
SubscribeEvent subscribeEventAnnotation, Method method) {
if (busGroup == null) {
busGroup = IModBusEvent.class.isAssignableFrom(eventType)
? FMLJavaModLoadingContext.get().getModBusGroup()
: BusGroup.DEFAULT;
}
// determine the listener type from its parameters and return type
if (paramCount == 1) {
var priority = subscribeEventAnnotation.priority();
if (returnType == void.class) {
if (Cancellable.class.isAssignableFrom(eventType)) {
// Consumer<Event & Cancellable>
var eventBus = CancellableEventBus.create(busGroup, (Class) eventType);
if (subscribeEventAnnotation.alwaysCancelling()) {
return eventBus.addListener(priority, true, createConsumer(method));
} else {
return eventBus.addListener(priority, createConsumer(method));
}
} else {
// Consumer<Event>
return EventBus.create(busGroup, eventType)
.addListener(priority, createConsumer(method));
}
} else {
// Predicate<Event & EventCharacteristic.Cancellable>
if (!Cancellable.class.isAssignableFrom(eventType))
throw fail(method, "Return type boolean is only valid for cancellable events");
if (subscribeEventAnnotation.alwaysCancelling())
throw new IllegalArgumentException("Always cancelling listeners must have a void return type");
return CancellableEventBus.create(busGroup, (Class) eventType)
.addListener(priority, createPredicate(method));
}
} else {
// ObjBooleanBiConsumer<Event & Cancellable>
if (returnType != void.class)
throw new IllegalArgumentException("Cancellation-aware monitoring listeners must have a void return type");
if (subscribeEventAnnotation.alwaysCancelling())
throw new IllegalArgumentException("Monitoring listeners cannot cancel events");
return CancellableEventBus.create(busGroup, (Class) eventType).addListener(createMonitor(method));
}
}
private static IllegalArgumentException fail(Class<?> listenerClass, String reason) {
return new IllegalArgumentException("Failed to register " + listenerClass.getName() + ": " + reason);
}
private static IllegalArgumentException fail(Method mtd, String reason) {
return new IllegalArgumentException("Failed to register " + mtd.getDeclaringClass().getName() + "." + mtd.getName() + ": " + reason);
}
@SuppressWarnings("unchecked")
private static <T extends Event> Consumer<T> createConsumer(Method callback) {
var factoryMH = getOrMakeFactory(callback, RETURNS_CONSUMER, CONSUMER_FI_TYPE, "accept");
try {
return (Consumer<T>) factoryMH.invokeExact();
} catch (Exception e) {
throw makeRuntimeException(callback, e);
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
@SuppressWarnings("unchecked")
private static <T extends Event> Predicate<T> createPredicate(Method callback) {
var factoryMH = getOrMakeFactory(callback, RETURNS_PREDICATE, PREDICATE_FI_TYPE, "test");
try {
return (Predicate<T>) factoryMH.invokeExact();
} catch (Exception e) {
throw makeRuntimeException(callback, e);
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
@SuppressWarnings("unchecked")
private static <T extends Event> ObjBooleanBiConsumer<T> createMonitor(Method callback) {
var factoryMH = getOrMakeFactory(callback, RETURNS_MONITOR, MONITOR_FI_TYPE, "accept");
try {
return (ObjBooleanBiConsumer<T>) factoryMH.invokeExact();
} catch (Exception e) {
throw makeRuntimeException(callback, e);
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
private static MethodHandle getOrMakeFactory(Method callback, MethodType factoryReturnType,
MethodType fiMethodType, String fiMethodName) {
return makeFactory(callback, factoryReturnType, fiMethodType, fiMethodName);
}
private static MethodHandle makeFactory(Method callback,
MethodType factoryReturnType,
MethodType fiMethodType, String fiMethodName) {
final class DodgyLookup {
private DodgyLookup() {}
private static final MethodHandles.Lookup INSTANCE;
static {
try {
var lookupField = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP");
UnsafeHacks.setAccessible(lookupField);
INSTANCE = (MethodHandles.Lookup) lookupField.get(null);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
try {
var callbackDeclaredClass = callback.getDeclaringClass();
var lookup = DodgyLookup.INSTANCE.in(callbackDeclaredClass);
var mh = lookup.unreflect(callback);
return LambdaMetafactory.metafactory(
lookup, fiMethodName, factoryReturnType, fiMethodType, mh, mh.type()
).getTarget();
} catch (Exception e) {
throw makeRuntimeException(callback, e);
}
}
private static RuntimeException makeRuntimeException(Method callback, Exception e) {
return switch (e) {
case IllegalAccessException iae -> {
var errMsg = "Failed to create listener";
if (!Modifier.isPublic(callback.getModifiers()))
errMsg += " - is it public?";
yield new RuntimeException(errMsg, iae);
}
case NullPointerException npe -> new RuntimeException(
"Failed to create listener - was given a non-static method without an instance to invoke it with",
npe
);
default -> new RuntimeException("Failed to create listener", e);
};
}
}
}
@@ -5,13 +5,14 @@
package net.minecraftforge.fml.javafmlmod;
import net.minecraftforge.eventbus.api.bus.BusGroup;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.ModLoadingContext;
/**
* Use the context provided by your language loader in your mod's constructor
*/
public class FMLJavaModLoadingContext extends ModLoadingContext {
public class FMLJavaModLoadingContext extends ModLoadingContext
{
private final FMLModContainer container;
FMLJavaModLoadingContext(FMLModContainer container) {
@@ -19,10 +20,11 @@ public class FMLJavaModLoadingContext extends ModLoadingContext {
}
/**
* @return The mod's event bus group, to allow subscription to Mod specific events
* @return The mod's event bus, to allow subscription to Mod specific events
*/
public BusGroup getModBusGroup() {
return container.getModBusGroup();
public IEventBus getModEventBus()
{
return container.getEventBus();
}
/**
@@ -37,15 +39,9 @@ public class FMLJavaModLoadingContext extends ModLoadingContext {
* Helper to get the right instance from the {@link ModLoadingContext} correctly.
* @return The FMLJavaMod language specific extension from the ModLoadingContext
*
* @deprecated use {@link FMLJavaModLoadingContext} in your mod constructor. For example: {@snippet :
* @Mod("examplemod")
* public final class ExampleMod {
* public ExampleMod(FMLJavaModLoadingContext context) {
* // Use context from the param instead of FMLJavaModLoadingContext.get() or ModLoadingContext.get()
* }
* }}
* @deprecated use {@link FMLJavaModLoadingContext} in your mod constructor
*/
@Deprecated(forRemoval = true, since = "1.21.1")
@Deprecated(forRemoval = true, since="1.21.1")
public static FMLJavaModLoadingContext get() {
return ModLoadingContext.get().extension();
}
@@ -5,8 +5,11 @@
package net.minecraftforge.fml.javafmlmod;
import net.minecraftforge.eventbus.api.bus.BusGroup;
import net.minecraftforge.eventbus.api.bus.EventBus;
import net.minecraftforge.eventbus.EventBusErrorMessage;
import net.minecraftforge.eventbus.api.BusBuilder;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.eventbus.api.IEventListener;
import net.minecraftforge.fml.ModContainer;
import net.minecraftforge.fml.ModLoadingException;
import net.minecraftforge.fml.ModLoadingStage;
@@ -33,7 +36,7 @@ public class FMLModContainer extends ModContainer {
private static final Logger LOGGER = LogManager.getLogger();
private static final Marker LOADING = MarkerManager.getMarker("LOADING");
private final ModFileScanData scanResults;
private final BusGroup eventBusGroup;
private final IEventBus eventBus;
private Object modInstance;
private final Class<?> modClass;
private final FMLJavaModLoadingContext context = new FMLJavaModLoadingContext(this);
@@ -43,7 +46,7 @@ public class FMLModContainer extends ModContainer {
LOGGER.debug(LOADING,"Creating FMLModContainer instance for {}", className);
this.scanResults = modFileScanResults;
activityMap.put(ModLoadingStage.CONSTRUCT, this::constructMod);
this.eventBusGroup = BusGroup.create("modBusFor" + info.getModId());
this.eventBus = BusBuilder.builder().setExceptionHandler(FMLModContainer::onEventFailed).setTrackPhases(false).markerType(IModBusEvent.class).useModLauncher().build();
this.contextExtension = () -> context;
try {
var moduleName = info.getOwningFile().moduleName();
@@ -125,6 +128,10 @@ public class FMLModContainer extends ModContainer {
implAddExportsOrOpens.invoke(target, pkg, reader, open, /*syncVM*/true);
}
private static void onEventFailed(IEventBus iEventBus, Event event, IEventListener[] iEventListeners, int i, Throwable throwable) {
LOGGER.error(new EventBusErrorMessage(event, i, iEventListeners, throwable));
}
private void constructMod() {
try {
LOGGER.trace(LOADING, "Loading mod instance {} of type {}", getModId(), modClass.getName());
@@ -166,17 +173,15 @@ public class FMLModContainer extends ModContainer {
return modInstance;
}
public BusGroup getModBusGroup() {
return this.eventBusGroup;
public IEventBus getEventBus() {
return this.eventBus;
}
@Override
protected <T extends IModBusEvent> void acceptEvent(final T e) {
protected <T extends Event & IModBusEvent> void acceptEvent(final T e) {
try {
LOGGER.trace(LOADING, "Firing event for modid {} : {}", this.getModId(), e);
@SuppressWarnings("unchecked")
var eventBus = (EventBus<T>) IModBusEvent.getBus(eventBusGroup, e.getClass());
eventBus.post(e);
this.eventBus.post(e);
LOGGER.trace(LOADING, "Fired event for modid {} : {}", this.getModId(), e);
} catch (Throwable t) {
LOGGER.error(LOADING,"Caught exception during event {} dispatch for modid {}", e, this.getModId(), t);
@@ -185,10 +190,8 @@ public class FMLModContainer extends ModContainer {
}
@Override
@SuppressWarnings({"rawtypes", "unchecked"})
public void dispatchConfigEvent(IConfigEvent event) {
var eventBus = (EventBus) EventBus.create(eventBusGroup, event.self().getClass());
eventBus.post(event.self());
this.eventBus.post(event.self());
}
@Override
+1 -1
View File
@@ -15,7 +15,7 @@ java {
}
dependencies {
compileOnly(libs.jetbrains.annotations)
compileOnly(libs.nulls)
implementation(project(':fmlloader'))
implementation(project(':fmlcore'))
@@ -6,32 +6,41 @@
package net.minecraftforge.fml.lowcodemod;
import com.mojang.logging.LogUtils;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.IExtensionPoint;
import net.minecraftforge.fml.ModContainer;
import net.minecraftforge.fml.loading.LogMarkers;
import net.minecraftforge.fml.event.IModBusEvent;
import net.minecraftforge.forgespi.language.IModInfo;
import net.minecraftforge.forgespi.language.ModFileScanData;
import org.slf4j.Logger;
public class LowCodeModContainer extends ModContainer {
import java.util.Objects;
import static net.minecraftforge.fml.loading.LogMarkers.LOADING;
public class LowCodeModContainer extends ModContainer
{
private static final Logger LOGGER = LogUtils.getLogger();
private final Object modInstance;
public LowCodeModContainer(IModInfo info, ModFileScanData modFileScanResults, ModuleLayer gameLayer) {
public LowCodeModContainer(IModInfo info, ModFileScanData modFileScanResults, ModuleLayer gameLayer)
{
super(info);
LOGGER.debug(LogMarkers.LOADING, "Creating LowCodeModContainer for {}", info.getModId());
LOGGER.debug(LOADING, "Creating LowCodeModContainer for {}", info.getModId());
this.modInstance = new Object();
this.contextExtension = () -> null;
this.extensionPoints.remove(IExtensionPoint.DisplayTest.class);
}
@Override
public boolean matches(Object mod) {
public boolean matches(Object mod)
{
return mod == modInstance;
}
@Override
public Object getMod() {
public Object getMod()
{
return modInstance;
}
}
+1 -1
View File
@@ -10,7 +10,7 @@ plugins {
apply from: rootProject.file('build_shared.gradle')
dependencies {
compileOnly(libs.jetbrains.annotations)
compileOnly(libs.nulls)
implementation(project(':fmlloader'))
implementation(project(':fmlcore'))
}
+22 -41
View File
@@ -2,7 +2,7 @@ plugins {
id 'eclipse'
id 'idea'
id 'maven-publish'
id 'net.minecraftforge.gradle' version '[6.0.36,6.2)'
id 'net.minecraftforge.gradle' version '[6.0.24,6.2)'
}
version = mod_version
@@ -22,13 +22,17 @@ minecraft {
// official MCVersion Official field/method names from Mojang mapping files
// parchment YYYY.MM.DD-MCVersion Open community-sourced parameter names and javadocs layered on top of official
//
// You must be aware of the Mojang license when using the 'official' or 'parchment' mappings.
// See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md
//
// Parchment is an unofficial project maintained by ParchmentMC, separate from MinecraftForge
// Additional setup is needed to use their mappings: https://parchmentmc.org/docs/getting-started
//
// Use non-default mappings at your own risk. They may not always work.
// Simply re-run your setup task after changing the mappings to update your workspace.
mappings channel: mapping_channel, version: mapping_version
// Forge 1.20.6 and newer use official mappings at runtime, so we shouldn't reobf from official to SRG
// Tell FG to not automtically create the reobf tasks, as we now use Official mappings at runtime, If you don't use them at dev time then you'll have to fix your reobf yourself.
reobf = false
// When true, this property will have all Eclipse/IntelliJ IDEA run configurations run the "prepareX" task for the given run configuration before launching the game.
@@ -46,7 +50,8 @@ minecraft {
// By default, the folder name of a run configuration is the name of the Gradle project containing it.
// generateRunFolders = true
// This property enables access transformers for use in development, applied to the Minecraft artifact.
// This property enables access transformers for use in development.
// They will be applied to the Minecraft artifact.
// The access transformer file can be anywhere in the project.
// However, it must be at "META-INF/accesstransformer.cfg" in the final mod jar to be loaded by Forge.
// This default location is a best practice to automatically put the file in the right place in the final jar.
@@ -60,18 +65,17 @@ minecraft {
configureEach {
workingDirectory project.file('run')
// Optional additional logging. The markers can be added/remove as needed, separated by commas.
// Recommended logging data for a userdev environment
// The markers can be added/remove as needed separated by commas.
// "SCAN": For mods scan.
// "REGISTRIES": For firing of registry events.
// "REGISTRYDUMP": For getting the contents of all registries.
// property 'forge.logging.markers', 'REGISTRIES'
property 'forge.logging.markers', 'REGISTRIES'
// Recommended logging level for the console
// You can set various levels here.
// Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels
property 'forge.logging.console.level', 'debug'
// Recommended for development - enables more descriptive errors at the cost of slower startup and registration.
property 'eventbus.api.strictRuntimeChecks', 'true'
// arg "-mixin.config=${mod_id}.mixins.json"
}
client {
@@ -106,26 +110,7 @@ sourceSets.main.resources { srcDir 'src/generated/resources' }
repositories {
// Put repositories for dependencies here
mavenCentral()
maven {
name = 'Forge'
url = 'https://maven.minecraftforge.net'
}
maven {
name = 'Minecraft libraries'
url = 'https://libraries.minecraft.net'
}
exclusiveContent {
forRepository {
maven {
name = 'Sponge'
url = 'https://repo.spongepowered.org/repository/maven-public'
}
}
filter {
includeGroupAndSubgroups('org.spongepowered')
}
}
// ForgeGradle automatically adds the Forge maven and Maven Central for you
// If you have mod jar dependencies in ./libs, you can declare them as a repository like so.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html#sub:flat_dir_resolver
@@ -142,11 +127,6 @@ dependencies {
// then special handling is done to allow a setup of a vanilla dependency without the use of an external repository.
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
// Forge 1.21.6+ uses EventBus 7, which shifts most of its runtime validation to compile-time via an annotation processor
// to improve performance in production environments. This line is required to enable said compile-time validation
// in your development environment, helping you catch issues early.
annotationProcessor 'net.minecraftforge:eventbus-validator:7.0-beta.10'
// Example mod dependency with JEI
// The JEI API is declared for compile time use, while the full JEI artifact is used at runtime
// compileOnly "mezz.jei:jei-${mc_version}-common-api:${jei_version}"
@@ -167,7 +147,7 @@ dependencies {
// A missing property will result in an error. Properties are expanded using ${} Groovy notation.
// When "copyIdeResources" is enabled, this will also run before the game launches in IDE environments.
// See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html
tasks.named('processResources', ProcessResources) {
tasks.named('processResources', ProcessResources).configure {
var replaceProperties = [
minecraft_version: minecraft_version, minecraft_version_range: minecraft_version_range,
forge_version: forge_version, forge_version_range: forge_version_range,
@@ -183,7 +163,7 @@ tasks.named('processResources', ProcessResources) {
}
// Example for how to get properties into the manifest for reading at runtime.
tasks.named('jar', Jar) {
tasks.named('jar', Jar).configure {
manifest {
attributes([
'Specification-Title' : mod_id,
@@ -193,7 +173,6 @@ tasks.named('jar', Jar) {
'Implementation-Version' : project.jar.archiveVersion,
'Implementation-Vendor' : mod_authors
])
// attributes['MixinConfigs'] = "${mod_id}.mixins.json"
}
}
@@ -215,7 +194,8 @@ tasks.withType(JavaCompile).configureEach {
options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation
}
// IntelliJ no longer downloads javadocs and sources by default, this tells Gradle to force IntelliJ to do it.
// IntelliJ no longer downloads javadocs and sources by default.
// This tells Gradle to force IDEA to do it.
idea.module { downloadJavadoc = downloadSources = true }
eclipse {
@@ -225,7 +205,8 @@ eclipse {
synchronizationTasks 'genEclipseRuns'
}
// Merge the resources and classes into the same directory, because Java expects modules to be in a single directory.
// Merge the resources and classes into the same directory.
// This is done because java expects modules to be in a single directory.
// And if we have it in multiple we have to do performance intensive hacks like having the UnionFileSystem
// This will eventually be migrated to ForgeGradle so modders don't need to manually do it. But that is later.
sourceSets.each {
+2 -9
View File
@@ -1,15 +1,8 @@
# Sets default memory used for Gradle commands. Can be overridden by user or command line properties.
# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
# This is required to provide enough memory for the Minecraft decompilation process.
org.gradle.jvmargs=-Xmx5G
org.gradle.jvmargs=-Xmx3G
org.gradle.daemon=false
# In the case that Gradle needs to fork to recompile, this will set the memory for that process.
systemProp.net.minecraftforge.gradle.repo.recompile.fork=true
systemProp.net.minecraftforge.gradle.repo.recompile.fork.args=-Xmx5G
# Opts-out of ForgeGradle automatically adding mavenCentral(), Forge's maven and MC libs maven to the repositories block
systemProp.net.minecraftforge.gradle.repo.attach=false
## Environment Properties
+2 -2
View File
@@ -9,5 +9,5 @@ pluginManagement {
}
plugins {
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.10.0'
}
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.7.0'
}
@@ -1,12 +0,0 @@
--- a/com/mojang/blaze3d/opengl/GlCommandEncoder.java
+++ b/com/mojang/blaze3d/opengl/GlCommandEncoder.java
@@ -132,6 +_,9 @@
GlStateManager._colorMask(true, true, true, true);
GlStateManager._clear(16384);
GlStateManager._glFramebufferTexture2D(36160, 36064, 3553, 0, 0);
+ // Forge: if using stencil, clear it as well (3553 = GlConst.GL_TEXTURE_2D)
+ if (p_394273_.isStencilEnabled())
+ GlStateManager._glFramebufferTexture2D(GlConst.GL_FRAMEBUFFER, org.lwjgl.opengl.GL30.GL_STENCIL_ATTACHMENT, GlConst.GL_TEXTURE_2D, 0, 0);
GlStateManager._glBindFramebuffer(36160, 0);
}
}
@@ -1,34 +0,0 @@
--- a/com/mojang/blaze3d/opengl/GlDebug.java
+++ b/com/mojang/blaze3d/opengl/GlDebug.java
@@ -23,6 +_,14 @@
@OnlyIn(Dist.CLIENT)
public class GlDebug {
+ /**
+ * TODO: [Forge][Rendering][VEN] Expose this in the configs
+ * <p>
+ * Will enable synchronous OpenGL debug logging, which means the message will be sent from the call that
+ * would have caused the error. Additionally, enables printing a stacktrace when and where this occurs.
+ */
+ private static final boolean PRINT_STACKTRACE_ON_ERROR = Boolean.getBoolean("forge.printGLStackOnError");
+
private static final Logger LOGGER = LogUtils.getLogger();
private static final int CIRCULAR_LOG_SIZE = 10;
private final Queue<GlDebug.LogEntry> MESSAGE_BUFFER = EvictingQueue.create(10);
@@ -105,6 +_,8 @@
}
LOGGER.info("OpenGL debug message: {}", gldebug$logentry);
+ // TODO: [VEN] Trim the stack trace
+ if (PRINT_STACKTRACE_ON_ERROR) LOGGER.info("Trace: ", new Throwable("GlDebug"));
}
public List<String> getLastOpenGlDebugMessages() {
@@ -121,6 +_,7 @@
@Nullable
public static GlDebug enableDebugCallback(int p_394351_, boolean p_393026_, Set<String> p_393339_) {
+ p_393026_ |= PRINT_STACKTRACE_ON_ERROR;
if (p_394351_ <= 0) {
return null;
} else {
@@ -1,74 +0,0 @@
--- a/com/mojang/blaze3d/opengl/GlDevice.java
+++ b/com/mojang/blaze3d/opengl/GlDevice.java
@@ -89,8 +_,15 @@
public GpuTexture createTexture(
@Nullable Supplier<String> p_397830_, int p_394481_, TextureFormat p_394839_, int p_391831_, int p_395609_, int p_407582_, int p_408928_
) {
+ return createTexture(p_397830_, p_394481_, p_394839_, p_391831_, p_395609_, p_407582_, p_408928_, false);
+ }
+
+ @Override
+ public GpuTexture createTexture(
+ @Nullable Supplier<String> p_397830_, int p_394481_, TextureFormat p_394839_, int p_391831_, int p_395609_, int p_407582_, int p_408928_, boolean stencil
+ ) {
return this.createTexture(
- this.debugLabels.exists() && p_397830_ != null ? p_397830_.get() : null, p_394481_, p_394839_, p_391831_, p_395609_, p_407582_, p_408928_
+ this.debugLabels.exists() && p_397830_ != null ? p_397830_.get() : null, p_394481_, p_394839_, p_391831_, p_395609_, p_407582_, p_408928_, stencil
);
}
@@ -98,6 +_,15 @@
public GpuTexture createTexture(
@Nullable String p_394142_, int p_395535_, TextureFormat p_394951_, int p_393944_, int p_392329_, int p_408015_, int p_406483_
) {
+ return createTexture(p_394142_, p_395535_, p_394951_, p_393944_, p_392329_, p_408015_, p_406483_, false);
+ }
+
+ @Override
+ public GpuTexture createTexture(
+ @Nullable String p_394142_, int p_395535_, TextureFormat p_394951_, int p_393944_, int p_392329_, int p_408015_, int p_406483_, boolean stencil
+ ) {
+ // Forge: stencil rendering is only for depth
+ stencil &= p_394951_.hasDepthAspect();
if (p_406483_ < 1) {
throw new IllegalArgumentException("mipLevels must be at least 1");
} else if (p_408015_ < 1) {
@@ -148,11 +_,14 @@
GlStateManager._texImage2D(
k,
l,
+ stencil ? org.lwjgl.opengl.GL30.GL_DEPTH32F_STENCIL8 :
GlConst.toGlInternalId(p_394951_),
p_393944_ >> l,
p_392329_ >> l,
0,
+ stencil ? org.lwjgl.opengl.GL30.GL_DEPTH_STENCIL :
GlConst.toGlExternalId(p_394951_),
+ stencil ? org.lwjgl.opengl.GL30.GL_FLOAT_32_UNSIGNED_INT_24_8_REV :
GlConst.toGlType(p_394951_),
null
);
@@ -163,11 +_,14 @@
GlStateManager._texImage2D(
j,
i1,
+ stencil ? org.lwjgl.opengl.GL30.GL_DEPTH32F_STENCIL8 :
GlConst.toGlInternalId(p_394951_),
p_393944_ >> i1,
p_392329_ >> i1,
0,
+ stencil ? org.lwjgl.opengl.GL30.GL_DEPTH_STENCIL :
GlConst.toGlExternalId(p_394951_),
+ stencil ? org.lwjgl.opengl.GL30.GL_FLOAT_32_UNSIGNED_INT_24_8_REV :
GlConst.toGlType(p_394951_),
null
);
@@ -180,7 +_,7 @@
} else if (j1 != 0) {
throw new IllegalStateException("OpenGL error " + j1);
} else {
- GlTexture gltexture = new GlTexture(p_395535_, p_394142_, p_394951_, p_393944_, p_392329_, p_408015_, p_406483_, i);
+ GlTexture gltexture = new GlTexture(p_395535_, p_394142_, p_394951_, p_393944_, p_392329_, p_408015_, p_406483_, i, stencil);
this.debugLabels.applyLabel(gltexture);
return gltexture;
}
@@ -1,32 +0,0 @@
--- a/com/mojang/blaze3d/opengl/GlStateManager.java
+++ b/com/mojang/blaze3d/opengl/GlStateManager.java
@@ -89,6 +_,11 @@
}
}
+ public static boolean _isBlendEnabled() {
+ RenderSystem.assertOnRenderThread();
+ return BLEND.mode.enabled;
+ }
+
public static void _disableBlend() {
RenderSystem.assertOnRenderThread();
BLEND.mode.disable();
@@ -404,9 +_,17 @@
}
}
+ /* Stores the last values sent into glMultiTexCoord2f */
+ public static float lastBrightnessX = 0.0f;
+ public static float lastBrightnessY = 0.0f;
+
public static void _texParameter(int p_393876_, int p_397998_, int p_396741_) {
RenderSystem.assertOnRenderThread();
GL11.glTexParameteri(p_393876_, p_397998_, p_396741_);
+ if (p_393876_ == GL13.GL_TEXTURE1) {
+ lastBrightnessX = p_397998_;
+ lastBrightnessY = p_396741_;
+ }
}
public static int _getTexLevelParameter(int p_393352_, int p_397204_, int p_396319_) {
@@ -1,33 +0,0 @@
--- a/com/mojang/blaze3d/opengl/GlTexture.java
+++ b/com/mojang/blaze3d/opengl/GlTexture.java
@@ -19,8 +_,13 @@
private int views;
protected GlTexture(int p_394590_, String p_393950_, TextureFormat p_392837_, int p_391379_, int p_391947_, int p_396659_, int p_408255_, int p_408889_) {
+ this(p_394590_, p_393950_, p_392837_, p_391379_, p_391947_, p_396659_, p_408255_, p_408889_, false);
+ }
+
+ protected GlTexture(int p_394590_, String p_393950_, TextureFormat p_392837_, int p_391379_, int p_391947_, int p_396659_, int p_408255_, int p_408889_, boolean stencil) {
super(p_394590_, p_393950_, p_392837_, p_391379_, p_391947_, p_396659_, p_408255_);
this.id = p_408889_;
+ this.stencilEnabled = stencil;
}
@Override
@@ -93,6 +_,16 @@
public void setTextureFilter(FilterMode p_394977_, FilterMode p_397175_, boolean p_393558_) {
super.setTextureFilter(p_394977_, p_397175_, p_393558_);
this.modesDirty = true;
+ }
+
+
+ /* FORGE START */
+
+ private final boolean stencilEnabled;
+
+ @Override
+ public boolean isStencilEnabled() {
+ return this.stencilEnabled;
}
@Override
@@ -1,18 +1,28 @@
--- a/com/mojang/blaze3d/pipeline/RenderTarget.java
+++ b/com/mojang/blaze3d/pipeline/RenderTarget.java
@@ -92,7 +_,7 @@
this.width = p_83951_;
this.height = p_83952_;
@@ -96,7 +_,10 @@
GlStateManager._texParameter(3553, 34892, 0);
GlStateManager._texParameter(3553, 10242, 33071);
GlStateManager._texParameter(3553, 10243, 33071);
+ if (!stencilEnabled)
GlStateManager._texImage2D(3553, 0, 6402, this.width, this.height, 0, 6402, 5126, null);
+ else
+ GlStateManager._texImage2D(3553, 0, org.lwjgl.opengl.GL30.GL_DEPTH32F_STENCIL8, this.width, this.height, 0, org.lwjgl.opengl.GL30.GL_DEPTH_STENCIL, org.lwjgl.opengl.GL30.GL_FLOAT_32_UNSIGNED_INT_24_8_REV, null);
}
this.setFilterMode(9728, true);
@@ -108,6 +_,7 @@
GlStateManager._glFramebufferTexture2D(36160, 36064, 3553, this.colorTextureId, 0);
if (this.useDepth) {
- this.depthTexture = gpudevice.createTexture(() -> this.label + " / Depth", 15, TextureFormat.DEPTH32, p_83951_, p_83952_, 1, 1);
+ this.depthTexture = gpudevice.createTexture(() -> this.label + " / Depth", 15, TextureFormat.DEPTH32, p_83951_, p_83952_, 1, 1, this.stencilEnabled);
this.depthTextureView = gpudevice.createTextureView(this.depthTexture);
this.depthTexture.setTextureFilter(FilterMode.NEAREST, false);
this.depthTexture.setAddressMode(AddressMode.CLAMP_TO_EDGE);
@@ -166,5 +_,26 @@
@Nullable
public GpuTextureView getDepthTextureView() {
return this.depthTextureView;
GlStateManager._glFramebufferTexture2D(36160, 36096, 3553, this.depthBufferId, 0);
+ if (stencilEnabled) GlStateManager._glFramebufferTexture2D(org.lwjgl.opengl.GL30.GL_FRAMEBUFFER, org.lwjgl.opengl.GL30.GL_STENCIL_ATTACHMENT, 3553, this.depthBufferId, 0);
}
this.checkStatus();
@@ -229,5 +_,26 @@
public int getDepthTextureId() {
return this.depthBufferId;
+ }
+
+ private boolean stencilEnabled = false;
@@ -0,0 +1,32 @@
--- a/com/mojang/blaze3d/platform/GlStateManager.java
+++ b/com/mojang/blaze3d/platform/GlStateManager.java
@@ -94,6 +_,11 @@
}
}
+ public static boolean _isBlendEnabled() {
+ RenderSystem.assertOnRenderThread();
+ return BLEND.mode.enabled;
+ }
+
public static void _disableBlend() {
RenderSystem.assertOnRenderThread();
BLEND.mode.disable();
@@ -519,9 +_,17 @@
}
}
+ /* Stores the last values sent into glMultiTexCoord2f */
+ public static float lastBrightnessX = 0.0f;
+ public static float lastBrightnessY = 0.0f;
+
public static void _texParameter(int p_84161_, int p_84162_, float p_84163_) {
RenderSystem.assertOnRenderThreadOrInit();
GL11.glTexParameterf(p_84161_, p_84162_, p_84163_);
+ if (p_84161_ == GL13.GL_TEXTURE1) {
+ lastBrightnessX = p_84162_;
+ lastBrightnessY = p_84163_;
+ }
}
public static void _texParameter(int p_84332_, int p_84333_, int p_84334_) {
@@ -16,9 +16,9 @@
}
+ }
this.setMode();
this.refreshFramebufferSize();
@@ -266,6 +_,9 @@
GLFW.glfwMakeContextCurrent(this.window);
GL.createCapabilities();
@@ -267,6 +_,9 @@
GLFW.glfwGetFramebufferSize(this.window, aint, aint1);
this.framebufferWidth = aint[0] > 0 ? aint[0] : 1;
this.framebufferHeight = aint1[0] > 0 ? aint1[0] : 1;
@@ -1,20 +0,0 @@
--- a/com/mojang/blaze3d/systems/GpuDevice.java
+++ b/com/mojang/blaze3d/systems/GpuDevice.java
@@ -26,7 +_,17 @@
@Nullable Supplier<String> p_394357_, int p_395623_, TextureFormat p_395807_, int p_395802_, int p_396157_, int p_408810_, int p_407070_
);
+ /** Forge: same as {@link #createTexture(Supplier, int, TextureFormat, int, int, int)} but with stencil support */
+ default GpuTexture createTexture(@Nullable Supplier<String> p_394357_, int p_395623_, TextureFormat p_395807_, int p_395802_, int p_396157_, int p_408810_, int p_407070_, boolean stencil) {
+ return this.createTexture(p_394357_, p_395623_, p_395807_, p_395802_, p_396157_, p_408810_, p_407070_);
+ }
+
GpuTexture createTexture(@Nullable String p_391798_, int p_391800_, TextureFormat p_393333_, int p_395600_, int p_394065_, int p_408732_, int p_407125_);
+
+ /** Forge: same as {@link #createTexture(String, int, TextureFormat, int, int, int)} but with stencil support */
+ default GpuTexture createTexture(@Nullable String p_391798_, int p_391800_, TextureFormat p_393333_, int p_395600_, int p_394065_, int p_408732_, int p_407125_, boolean stencil) {
+ return this.createTexture(p_391798_, p_391800_, p_393333_, p_395600_, p_394065_, p_408732_, p_407125_);
+ }
GpuTextureView createTextureView(GpuTexture p_409045_);
@@ -0,0 +1,14 @@
--- a/com/mojang/blaze3d/systems/RenderSystem.java
+++ b/com/mojang/blaze3d/systems/RenderSystem.java
@@ -196,6 +_,11 @@
GlStateManager._depthMask(p_69459_);
}
+ public static boolean isBlendEnabled() {
+ assertOnRenderThread();
+ return GlStateManager._isBlendEnabled();
+ }
+
public static void enableBlend() {
assertOnRenderThread();
GlStateManager._enableBlend();
@@ -1,11 +0,0 @@
--- a/com/mojang/blaze3d/textures/GpuTexture.java
+++ b/com/mojang/blaze3d/textures/GpuTexture.java
@@ -6,7 +_,7 @@
@OnlyIn(Dist.CLIENT)
@DontObfuscate
-public abstract class GpuTexture implements AutoCloseable {
+public abstract class GpuTexture implements AutoCloseable, net.minecraftforge.client.extensions.IForgeGpuTexture {
public static final int USAGE_COPY_DST = 1;
public static final int USAGE_COPY_SRC = 2;
public static final int USAGE_TEXTURE_BINDING = 4;
@@ -1,11 +1,11 @@
--- a/com/mojang/blaze3d/vertex/PoseStack.java
+++ b/com/mojang/blaze3d/vertex/PoseStack.java
@@ -15,7 +_,7 @@
import org.joml.Vector3fc;
@@ -14,7 +_,7 @@
import org.joml.Vector3f;
@OnlyIn(Dist.CLIENT)
-public class PoseStack {
+public class PoseStack implements net.minecraftforge.client.extensions.IForgePoseStack {
private final List<PoseStack.Pose> poses = new ArrayList<>(16);
private int lastIndex;
private final Deque<PoseStack.Pose> poseStack = Util.make(Queues.newArrayDeque(), p_85848_ -> {
Matrix4f matrix4f = new Matrix4f();
Matrix3f matrix3f = new Matrix3f();
@@ -1,6 +1,6 @@
--- a/com/mojang/blaze3d/vertex/VertexConsumer.java
+++ b/com/mojang/blaze3d/vertex/VertexConsumer.java
@@ -15,7 +_,7 @@
@@ -13,7 +_,7 @@
import org.lwjgl.system.MemoryStack;
@OnlyIn(Dist.CLIENT)
@@ -9,7 +9,7 @@
VertexConsumer addVertex(float p_344294_, float p_342213_, float p_344859_);
VertexConsumer setColor(int p_342749_, int p_344324_, int p_343336_, int p_342831_);
@@ -135,9 +_,11 @@
@@ -133,9 +_,11 @@
int j1 = ARGB.color(k, (int)f3, (int)f4, (int)f5);
int k1 = LightTexture.lightCoordsWithEmission(p_331444_[i1], l);
@@ -1,23 +1,23 @@
--- a/com/mojang/blaze3d/vertex/VertexFormat.java
+++ b/com/mojang/blaze3d/vertex/VertexFormat.java
@@ -21,7 +_,7 @@
@@ -14,7 +_,7 @@
import net.minecraftforge.api.distmarker.OnlyIn;
@OnlyIn(Dist.CLIENT)
@DontObfuscate
-public class VertexFormat {
+public class VertexFormat implements net.minecraftforge.client.extensions.IForgeVertexFormat {
public static final int UNKNOWN_ELEMENT = -1;
private static final boolean USE_STAGING_BUFFER_WORKAROUND = Util.getPlatform() == Util.OS.WINDOWS && Util.isAarch64();
private final List<VertexFormatElement> elements;
private final List<String> names;
@@ -23,6 +_,7 @@
private final int[] offsetsByElement = new int[32];
@Nullable
@@ -35,6 +_,7 @@
private GpuBuffer immediateDrawVertexBuffer;
@Nullable
private GpuBuffer immediateDrawIndexBuffer;
private VertexBuffer immediateDrawVertexBuffer;
+ private final com.google.common.collect.ImmutableMap<String, VertexFormatElement> elementMapping;
VertexFormat(List<VertexFormatElement> p_343616_, List<String> p_345241_, IntList p_345522_, int p_344162_) {
this.elements = p_343616_;
@@ -47,6 +_,11 @@
@@ -35,6 +_,11 @@
int j = vertexformatelement != null ? p_343616_.indexOf(vertexformatelement) : -1;
this.offsetsByElement[i] = j != -1 ? p_345522_.getInt(j) : -1;
}
@@ -29,13 +29,13 @@
}
public static VertexFormat.Builder builder() {
@@ -169,6 +_,9 @@
);
return this.immediateDrawIndexBuffer;
@@ -141,6 +_,9 @@
return vertexbuffer;
}
+
+ public ImmutableMap<String, VertexFormatElement> getElementMapping() { return elementMapping; }
+ public int getOffset(int index) { return offsetsByElement[index]; }
@OnlyIn(Dist.CLIENT)
@DontObfuscate
public static class Builder {
@@ -1,15 +1,15 @@
--- a/com/mojang/math/Transformation.java
+++ b/com/mojang/math/Transformation.java
@@ -14,7 +_,7 @@
@@ -13,7 +_,7 @@
import org.joml.Quaternionf;
import org.joml.Vector3f;
-public final class Transformation {
+public final class Transformation implements net.minecraftforge.common.extensions.IForgeTransformation {
private final Matrix4fc matrix;
private final Matrix4f matrix;
public static final Codec<Transformation> CODEC = RecordCodecBuilder.create(
p_269604_ -> p_269604_.group(
@@ -174,5 +_,19 @@
@@ -169,5 +_,19 @@
vector3f1.lerp(p_175938_.getScale(), p_175939_);
quaternionf1.slerp(p_175938_.getRightRotation(), p_175939_);
return new Transformation(vector3f, quaternionf, vector3f1, quaternionf1);
@@ -34,4 +34,4 @@
+ this.stackTrace = t.getStackTrace();
}
public static void populateBlockDetails(CrashReportCategory p_178951_, LevelHeightAccessor p_178952_, BlockPos p_178953_, BlockState p_178954_) {
public static void populateBlockDetails(CrashReportCategory p_178951_, LevelHeightAccessor p_178952_, BlockPos p_178953_, @Nullable BlockState p_178954_) {
@@ -1,6 +1,6 @@
--- a/net/minecraft/SharedConstants.java
+++ b/net/minecraft/SharedConstants.java
@@ -175,6 +_,7 @@
@@ -170,6 +_,7 @@
}
static {
@@ -1,7 +1,7 @@
--- a/net/minecraft/Util.java
+++ b/net/minecraft/Util.java
@@ -268,7 +_,7 @@
.getSchema(DataFixUtils.makeKey(SharedConstants.getCurrentVersion().dataVersion().version()))
@@ -264,7 +_,7 @@
.getSchema(DataFixUtils.makeKey(SharedConstants.getCurrentVersion().getDataVersion().getVersion()))
.getChoiceType(p_137552_, p_137553_);
} catch (IllegalArgumentException illegalargumentexception) {
- LOGGER.error("No data fixer registered for {}", p_137553_);
@@ -1,6 +1,6 @@
--- a/net/minecraft/advancements/Advancement.java
+++ b/net/minecraft/advancements/Advancement.java
@@ -226,7 +_,11 @@
@@ -214,7 +_,11 @@
}
public AdvancementHolder save(Consumer<AdvancementHolder> p_138390_, String p_138391_) {
@@ -1,7 +1,7 @@
--- a/net/minecraft/advancements/AdvancementRewards.java
+++ b/net/minecraft/advancements/AdvancementRewards.java
@@ -43,6 +_,7 @@
LootParams lootparams = new LootParams.Builder(serverlevel)
@@ -41,6 +_,7 @@
LootParams lootparams = new LootParams.Builder(p_9990_.serverLevel())
.withParameter(LootContextParams.THIS_ENTITY, p_9990_)
.withParameter(LootContextParams.ORIGIN, p_9990_.position())
+ .withLuck(p_9990_.getLuck())
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/Camera.java
+++ b/net/minecraft/client/Camera.java
@@ -133,9 +_,13 @@
@@ -120,9 +_,13 @@
}
protected void setRotation(float p_90573_, float p_90574_) {
@@ -15,7 +15,7 @@
FORWARDS.rotate(this.rotation, this.forwards);
UP.rotate(this.rotation, this.up);
LEFT.rotate(this.rotation, this.left);
@@ -251,6 +_,13 @@
@@ -238,6 +_,13 @@
public float getPartialTickTime() {
return this.partialTickTime;
@@ -28,4 +28,4 @@
+ return this.level.getBlockState(this.blockPosition).getStateAtViewpoint(this.level, this.blockPosition, this.position);
}
@Override
@OnlyIn(Dist.CLIENT)
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/KeyMapping.java
+++ b/net/minecraft/client/KeyMapping.java
@@ -15,9 +_,9 @@
@@ -14,9 +_,9 @@
import net.minecraftforge.api.distmarker.OnlyIn;
@OnlyIn(Dist.CLIENT)
@@ -12,7 +12,7 @@
private static final Set<String> CATEGORIES = Sets.newHashSet();
public static final String CATEGORY_MOVEMENT = "key.categories.movement";
public static final String CATEGORY_MISC = "key.categories.misc";
@@ -43,14 +_,14 @@
@@ -42,14 +_,14 @@
private int clickCount;
public static void click(InputConstants.Key p_90836_) {
@@ -29,7 +29,7 @@
if (keymapping != null) {
keymapping.setDown(p_90839_);
}
@@ -101,7 +_,7 @@
@@ -100,7 +_,7 @@
}
public boolean isDown() {
@@ -38,7 +38,7 @@
}
public String getCategory() {
@@ -137,7 +_,16 @@
@@ -136,7 +_,16 @@
public int compareTo(KeyMapping p_90841_) {
return this.category.equals(p_90841_.category)
? I18n.get(this.name).compareTo(I18n.get(p_90841_.name))
@@ -56,7 +56,7 @@
}
public static Supplier<Component> createNameSupplier(String p_90843_) {
@@ -146,6 +_,20 @@
@@ -145,6 +_,20 @@
}
public boolean same(KeyMapping p_90851_) {
@@ -77,7 +77,7 @@
return this.key.equals(p_90851_.key);
}
@@ -164,11 +_,13 @@
@@ -163,11 +_,13 @@
}
public Component getTranslatedKeyMessage() {
@@ -92,10 +92,10 @@
}
public String saveString() {
@@ -182,5 +_,88 @@
@Nullable
public static KeyMapping get(String p_378660_) {
return ALL.get(p_378660_);
@@ -176,5 +_,88 @@
public void setDown(boolean p_90846_) {
this.isDown = p_90846_;
+ }
+
+ private net.minecraftforge.client.settings.KeyModifier keyModifierDefault = net.minecraftforge.client.settings.KeyModifier.NONE;
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/KeyboardHandler.java
+++ b/net/minecraft/client/KeyboardHandler.java
@@ -440,12 +_,12 @@
@@ -424,12 +_,12 @@
if (screen != null) {
try {
if (p_90897_ != 1 && p_90897_ != 2) {
@@ -15,7 +15,7 @@
return;
}
}
@@ -504,6 +_,7 @@
@@ -505,6 +_,7 @@
}
}
}
@@ -23,7 +23,7 @@
}
}
@@ -513,10 +_,10 @@
@@ -514,10 +_,10 @@
if (screen != null && this.minecraft.getOverlay() == null) {
try {
if (Character.isBmpCodePoint(p_90891_)) {
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/Minecraft.java
+++ b/net/minecraft/client/Minecraft.java
@@ -256,7 +_,7 @@
@@ -253,7 +_,7 @@
import org.slf4j.Logger;
@OnlyIn(Dist.CLIENT)
@@ -9,7 +9,7 @@
static Minecraft instance;
private static final Logger LOGGER = LogUtils.getLogger();
public static final boolean ON_OSX = Util.getPlatform() == Util.OS.OSX;
@@ -435,7 +_,6 @@
@@ -433,7 +_,6 @@
}
}, Util.nonCriticalIoPool());
LOGGER.info("Setting user: {}", this.user.getName());
@@ -17,7 +17,7 @@
this.demo = p_91084_.game.demo;
this.allowsMultiplayer = !p_91084_.game.disableMultiplayer;
this.allowsChat = !p_91084_.game.disableChat;
@@ -486,10 +_,9 @@
@@ -480,15 +_,15 @@
LOGGER.error("Couldn't set icon", (Throwable)ioexception);
}
@@ -26,26 +26,24 @@
- this.mouseHandler.setup(this.window.getWindow());
this.keyboardHandler = new KeyboardHandler(this);
- this.keyboardHandler.setup(this.window.getWindow());
RenderSystem.initRenderer(
this.window.getWindow(),
this.options.glDebugVerbosity,
@@ -500,6 +_,7 @@
LOGGER.info("Using optional rendering extensions: {}", String.join(", ", RenderSystem.getDevice().getEnabledExtensions()));
RenderSystem.initRenderer(this.options.glDebugVerbosity, false);
this.mainRenderTarget = new MainTarget(this.window.getWidth(), this.window.getHeight());
this.mainRenderTarget.setClearColor(0.0F, 0.0F, 0.0F, 0.0F);
this.mainRenderTarget.clear();
this.resourceManager = new ReloadableResourceManager(PackType.CLIENT_RESOURCES);
+ net.minecraftforge.client.loading.ClientModLoader.begin(this, this.resourcePackRepository, this.resourceManager);
this.resourcePackRepository.reload();
this.options.loadSelectedResourcePacks(this.resourcePackRepository);
this.languageManager = new LanguageManager(this.options.languageCode, p_340763_ -> {
@@ -578,6 +_,7 @@
this.blockEntityRenderDispatcher = new BlockEntityRenderDispatcher(this.font, this.modelManager.entityModels(), this.blockRenderer, this.itemModelResolver, this.itemRenderer, this.entityRenderDispatcher);
this.resourceManager.registerReloadListener(this.blockEntityRenderDispatcher);
@@ -562,6 +_,7 @@
);
this.resourceManager.registerReloadListener(this.entityRenderDispatcher);
this.particleEngine = new ParticleEngine(this.level, this.textureManager);
+ net.minecraftforge.client.ForgeHooksClient.onRegisterParticleProviders(this.particleEngine);
this.resourceManager.registerReloadListener(this.particleEngine);
this.paintingTextures = new PaintingTextureManager(this.textureManager);
this.resourceManager.registerReloadListener(this.paintingTextures);
@@ -593,6 +_,9 @@
@@ -577,6 +_,9 @@
this.resourceManager.registerReloadListener(this.gpuWarnlistManager);
this.resourceManager.registerReloadListener(this.regionalCompliancies);
this.gui = new Gui(this);
@@ -53,17 +51,17 @@
+ this.mouseHandler.setup(this.window.getWindow());
+ this.keyboardHandler.setup(this.window.getWindow());
this.debugRenderer = new DebugRenderer(this);
RealmsClient realmsclient = RealmsClient.getOrCreate(this);
RealmsClient realmsclient = RealmsClient.create(this);
this.realmsDataFetcher = new RealmsDataFetcher(realmsclient);
@@ -626,6 +_,7 @@
}
@@ -600,6 +_,7 @@
this.options.fullscreen().set(this.window.isFullscreen());
}
+ net.minecraftforge.client.ForgeHooksClient.initClientHooks(this, this.resourceManager);
this.window.updateVsync(this.options.enableVsync().get());
this.window.updateRawMouseInput(this.options.rawMouseInput().get());
this.window.setDefaultErrorCallback();
@@ -648,16 +_,17 @@
@@ -620,16 +_,17 @@
GameLoadTimesEvent.INSTANCE.beginStep(TelemetryProperty.LOAD_TIME_LOADING_OVERLAY_MS);
Minecraft.GameLoadCookie minecraft$gameloadcookie = new Minecraft.GameLoadCookie(realmsclient, p_91084_.quickPlay);
this.setOverlay(
@@ -71,20 +69,20 @@
- this, reloadinstance, p_296164_ -> Util.ifElse(p_296164_, p_296162_ -> this.rollbackResourcePacks(p_296162_, minecraft$gameloadcookie), () -> {
+ net.minecraftforge.fml.loading.ImmediateWindowHandler.<LoadingOverlay>loadingOverlay(
+ () -> this, () -> reloadinstance, p_296164_ -> Util.ifElse(p_296164_, p_296162_ -> this.rollbackResourcePacks(p_296162_, minecraft$gameloadcookie), () -> {
if (SharedConstants.IS_RUNNING_IN_IDE) {
this.selfTest();
}
if (SharedConstants.IS_RUNNING_IN_IDE) {
this.selfTest();
}
this.reloadStateTracker.finishReload();
this.onResourceLoadFinished(minecraft$gameloadcookie);
+ net.minecraftforge.client.loading.ClientModLoader.completeModLoading();
}), false
this.reloadStateTracker.finishReload();
this.onResourceLoadFinished(minecraft$gameloadcookie);
+ net.minecraftforge.client.loading.ClientModLoader.completeModLoading();
}), false
- )
+ ).get()
);
this.quickPlayLog = QuickPlayLog.of(p_91084_.quickPlay.logPath());
this.quickPlayLog = QuickPlayLog.of(p_91084_.quickPlay.path());
this.framerateLimitTracker = new FramerateLimitTracker(this.options, this);
@@ -759,6 +_,7 @@
@@ -724,6 +_,7 @@
StringBuilder stringbuilder = new StringBuilder("Minecraft");
if (checkModStatus().shouldReportAsModified()) {
stringbuilder.append("*");
@@ -92,7 +90,7 @@
}
stringbuilder.append(" ");
@@ -782,6 +_,8 @@
@@ -747,6 +_,8 @@
}
private UserApiService createUserApiService(YggdrasilAuthenticationService p_193586_, GameConfig p_193587_) {
@@ -101,7 +99,7 @@
return p_193587_.user.user.getType() != User.Type.MSA
? UserApiService.OFFLINE
: p_193586_.createUserApiService(p_193587_.user.user.getAccessToken());
@@ -792,7 +_,7 @@
@@ -757,7 +_,7 @@
}
private void rollbackResourcePacks(Throwable p_91240_, @Nullable Minecraft.GameLoadCookie p_299515_) {
@@ -110,7 +108,7 @@
this.clearResourcePacksOnError(p_91240_, null, p_299515_);
} else {
Util.throwAsRuntime(p_91240_);
@@ -1078,12 +_,6 @@
@@ -1043,12 +_,6 @@
LOGGER.error("setScreen called from non-game thread");
}
@@ -123,7 +121,7 @@
if (p_91153_ == null && this.clientLevelTeardownInProgress) {
throw new IllegalStateException("Trying to return to in-game GUI during disconnection");
} else {
@@ -1097,6 +_,23 @@
@@ -1062,6 +_,23 @@
}
}
@@ -147,15 +145,15 @@
this.screen = p_91153_;
if (this.screen != null) {
this.screen.added();
@@ -1180,6 +_,7 @@
@@ -1146,6 +_,7 @@
FreeTypeUtil.destroy();
Util.shutdownExecutors();
RenderSystem.getDevice().close();
+ net.minecraftforge.fml.config.ConfigTracker.INSTANCE.forceUnload();
} catch (Throwable throwable) {
LOGGER.error("Shutdown failure!", throwable);
throw throwable;
@@ -1248,9 +_,11 @@
@@ -1215,9 +_,11 @@
this.mouseHandler.handleAccumulatedMovement();
profilerfiller.pop();
if (!this.noRender) {
@@ -167,8 +165,8 @@
}
profilerfiller.push("blit");
@@ -1379,10 +_,12 @@
this.window.setGuiScale(i);
@@ -1339,10 +_,12 @@
this.window.setGuiScale((double)i);
if (this.screen != null) {
this.screen.resize(this, this.window.getGuiScaledWidth(), this.window.getGuiScaledHeight());
+ net.minecraftforge.client.ForgeHooksClient.resizeGuiLayers(this, this.window.getGuiScaledWidth(), this.window.getGuiScaledHeight());
@@ -180,7 +178,7 @@
this.gameRenderer.resize(this.window.getWidth(), this.window.getHeight());
this.mouseHandler.setIgnoreFirstMove();
}
@@ -1520,6 +_,7 @@
@@ -1483,6 +_,7 @@
}
public void stop() {
@@ -188,14 +186,14 @@
this.running = false;
}
@@ -1547,10 +_,18 @@
@@ -1511,10 +_,18 @@
if (p_91387_ && this.hitResult != null && this.hitResult.getType() == HitResult.Type.BLOCK) {
BlockHitResult blockhitresult = (BlockHitResult)this.hitResult;
BlockPos blockpos = blockhitresult.getBlockPos();
- if (!this.level.getBlockState(blockpos).isAir()) {
+ if (!this.level.isEmptyBlock(blockpos)) {
+ var inputEvent = new net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered(0, this.options.keyAttack, InteractionHand.MAIN_HAND);
+ if (net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered.BUS.post(inputEvent)) {
+ var inputEvent = net.minecraftforge.client.event.ForgeEventFactoryClient.onClickInput(0, this.options.keyAttack, InteractionHand.MAIN_HAND);
+ if (inputEvent.isCanceled()) {
+ if (inputEvent.shouldSwingHand()) {
+ this.particleEngine.addBlockHitEffects(blockpos, blockhitresult);
+ this.player.swing(InteractionHand.MAIN_HAND);
@@ -210,16 +208,16 @@
this.player.swing(InteractionHand.MAIN_HAND);
}
}
@@ -1578,6 +_,8 @@
@@ -1542,6 +_,8 @@
return false;
} else {
boolean flag = false;
+ var inputEvent = new net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered(0, this.options.keyAttack, InteractionHand.MAIN_HAND);
+ if (!net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered.BUS.post(inputEvent))
+ var inputEvent = net.minecraftforge.client.event.ForgeEventFactoryClient.onClickInput(0, this.options.keyAttack, InteractionHand.MAIN_HAND);
+ if (!inputEvent.isCanceled())
switch (this.hitResult.getType()) {
case ENTITY:
this.gameMode.attack(this.player, ((EntityHitResult)this.hitResult).getEntity());
@@ -1585,7 +_,7 @@
@@ -1549,7 +_,7 @@
case BLOCK:
BlockHitResult blockhitresult = (BlockHitResult)this.hitResult;
BlockPos blockpos = blockhitresult.getBlockPos();
@@ -228,7 +226,7 @@
this.gameMode.startDestroyBlock(blockpos, blockhitresult.getDirection());
if (this.level.getBlockState(blockpos).isAir()) {
flag = true;
@@ -1598,8 +_,10 @@
@@ -1562,8 +_,10 @@
}
this.player.resetAttackStrengthTicker();
@@ -239,12 +237,12 @@
this.player.swing(InteractionHand.MAIN_HAND);
return flag;
}
@@ -1615,6 +_,12 @@
@@ -1579,6 +_,12 @@
}
for (InteractionHand interactionhand : InteractionHand.values()) {
+ var inputEvent = new net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered(1, this.options.keyUse, interactionhand);
+ if (net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered.BUS.post(inputEvent)) {
+ var inputEvent = net.minecraftforge.client.event.ForgeEventFactoryClient.onClickInput(1, this.options.keyUse, interactionhand);
+ if (inputEvent.isCanceled()) {
+ if (inputEvent.shouldSwingHand()) this.player.swing(interactionhand);
+ return;
+ }
@@ -252,7 +250,7 @@
ItemStack itemstack = this.player.getItemInHand(interactionhand);
if (!itemstack.isItemEnabled(this.level.enabledFeatures())) {
return;
@@ -1635,7 +_,7 @@
@@ -1599,7 +_,7 @@
}
if (interactionresult instanceof InteractionResult.Success interactionresult$success2) {
@@ -261,16 +259,16 @@
this.player.swing(interactionhand);
}
@@ -1647,7 +_,7 @@
@@ -1611,7 +_,7 @@
int i = itemstack.getCount();
InteractionResult interactionresult1 = this.gameMode.useItemOn(this.player, interactionhand, blockhitresult);
if (interactionresult1 instanceof InteractionResult.Success interactionresult$success) {
- if (interactionresult$success.swingSource() == InteractionResult.SwingSource.CLIENT) {
+ if (interactionresult$success.swingSource() == InteractionResult.SwingSource.CLIENT && inputEvent.shouldSwingHand()) {
this.player.swing(interactionhand);
if (!itemstack.isEmpty() && (itemstack.getCount() != i || this.player.hasInfiniteMaterials())) {
if (!itemstack.isEmpty() && (itemstack.getCount() != i || this.gameMode.hasInfiniteItems())) {
this.gameRenderer.itemInHandRenderer.itemUsed(interactionhand);
@@ -1663,6 +_,9 @@
@@ -1627,6 +_,9 @@
}
}
@@ -280,7 +278,7 @@
if (!itemstack.isEmpty()
&& this.gameMode.useItem(this.player, interactionhand) instanceof InteractionResult.Success interactionresult$success1) {
if (interactionresult$success1.swingSource() == InteractionResult.SwingSource.CLIENT) {
@@ -1692,6 +_,8 @@
@@ -1656,6 +_,8 @@
}
ProfilerFiller profilerfiller = Profiler.get();
@@ -289,7 +287,7 @@
profilerfiller.push("gui");
this.chatListener.tick();
this.gui.tick(this.pause);
@@ -1778,6 +_,7 @@
@@ -1745,6 +_,7 @@
this.tutorial.tick();
@@ -297,7 +295,7 @@
try {
this.level.tick(() -> true);
} catch (Throwable throwable1) {
@@ -1791,6 +_,7 @@
@@ -1758,6 +_,7 @@
throw new ReportedException(crashreport1);
}
@@ -305,7 +303,7 @@
}
profilerfiller.popPush("animateTick");
@@ -1815,6 +_,7 @@
@@ -1782,6 +_,7 @@
profilerfiller.popPush("keyboard");
this.keyboardHandler.tick();
profilerfiller.pop();
@@ -313,7 +311,7 @@
}
private boolean isLevelRunningNormally() {
@@ -2031,6 +_,7 @@
@@ -1983,6 +_,7 @@
}
public void setLevel(ClientLevel p_91157_, ReceivingLevelScreen.Reason p_335893_) {
@@ -321,7 +319,7 @@
this.updateScreenAndTick(new ReceivingLevelScreen(() -> false, p_335893_));
this.level = p_91157_;
this.updateLevelInEngines(p_91157_);
@@ -2068,6 +_,7 @@
@@ -2020,6 +_,7 @@
IntegratedServer integratedserver = this.singleplayerServer;
this.singleplayerServer = null;
this.gameRenderer.resetData();
@@ -329,7 +327,7 @@
this.gameMode = null;
this.narrator.clear();
this.clientLevelTeardownInProgress = true;
@@ -2075,6 +_,7 @@
@@ -2027,6 +_,7 @@
try {
this.updateScreenAndTick(p_335030_);
if (this.level != null) {
@@ -337,7 +335,7 @@
if (integratedserver != null) {
ProfilerFiller profilerfiller = Profiler.get();
profilerfiller.push("waitForServer");
@@ -2088,6 +_,7 @@
@@ -2040,6 +_,7 @@
this.gui.onDisconnected();
this.isLocalServer = false;
@@ -345,11 +343,40 @@
}
this.level = null;
@@ -2236,6 +_,7 @@
@@ -2187,6 +_,7 @@
private void pickBlock() {
if (this.hitResult != null && this.hitResult.getType() != HitResult.Type.MISS) {
+ if (net.minecraftforge.client.event.ForgeEventFactoryClient.onClickInputPickBlock(this.options.keyPickItem)) return;
boolean flag = Screen.hasControlDown();
switch (this.hitResult) {
case BlockHitResult blockhitresult:
+ if (net.minecraftforge.client.event.ForgeEventFactoryClient.onClickInput(2, this.options.keyPickItem, InteractionHand.MAIN_HAND).isCanceled()) return;
boolean flag = this.player.getAbilities().instabuild;
BlockEntity blockentity = null;
HitResult.Type hitresult$type = this.hitResult.getType();
@@ -2199,7 +_,7 @@
}
Block block = blockstate.getBlock();
- itemstack = block.getCloneItemStack(this.level, blockpos, blockstate);
+ itemstack = blockstate.getCloneItemStack(this.hitResult, this.level, blockpos, this.player);
if (itemstack.isEmpty()) {
return;
}
@@ -2213,7 +_,7 @@
}
Entity entity = ((EntityHitResult)this.hitResult).getEntity();
- itemstack = entity.getPickResult();
+ itemstack = entity.getPickedResult(this.hitResult);
if (itemstack == null) {
return;
}
@@ -2818,6 +_,10 @@
@Nullable
public static String getLauncherBrand() {
return System.getProperty("minecraft.launcher.brand");
+ }
+
+ public ItemColors getItemColors() {
+ return this.itemColors;
}
@OnlyIn(Dist.CLIENT)
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/MouseHandler.java
+++ b/net/minecraft/client/MouseHandler.java
@@ -90,6 +_,7 @@
@@ -85,6 +_,7 @@
this.activeButton = -1;
}
@@ -8,7 +8,7 @@
if (this.minecraft.getOverlay() == null) {
if (this.minecraft.screen == null) {
if (!this.mouseGrabbed && flag) {
@@ -103,7 +_,7 @@
@@ -98,7 +_,7 @@
screen.afterMouseAction();
try {
@@ -17,7 +17,7 @@
return;
}
} catch (Throwable throwable1) {
@@ -116,7 +_,7 @@
@@ -112,7 +_,7 @@
}
} else {
try {
@@ -26,18 +26,18 @@
return;
}
} catch (Throwable throwable) {
@@ -150,6 +_,7 @@
@@ -147,6 +_,7 @@
}
}
}
+ net.minecraftforge.client.event.ForgeEventFactoryClient.onMouseButtonPost(p_91532_, p_91533_, p_91534_);
}
public void fillMousePositionDetails(CrashReportCategory p_398230_, Window p_398216_) {
@@ -189,7 +_,9 @@
private void onScroll(long p_91527_, double p_91528_, double p_91529_) {
@@ -160,7 +_,9 @@
if (this.minecraft.screen != null) {
double d3 = this.getScaledXPos(this.minecraft.getWindow());
double d4 = this.getScaledYPos(this.minecraft.getWindow());
double d3 = this.xpos * (double)this.minecraft.getWindow().getGuiScaledWidth() / (double)this.minecraft.getWindow().getScreenWidth();
double d4 = this.ypos * (double)this.minecraft.getWindow().getGuiScaledHeight() / (double)this.minecraft.getWindow().getScreenHeight();
- this.minecraft.screen.mouseScrolled(d3, d4, d1, d2);
+ if (net.minecraftforge.client.event.ForgeEventFactoryClient.onScreenMouseScrollPre(this.minecraft.screen, d3, d4, d1, d2)) return;
+ if (this.minecraft.screen.mouseScrolled(d3, d4, d1, d2)) return;
@@ -45,7 +45,7 @@
this.minecraft.screen.afterMouseAction();
} else if (this.minecraft.player != null) {
Vector2i vector2i = this.scrollWheelHandler.onMouseScroll(d1, d2);
@@ -198,6 +_,7 @@
@@ -169,6 +_,7 @@
}
int i = vector2i.y == 0 ? -vector2i.x : vector2i.y;
@@ -53,8 +53,8 @@
if (this.minecraft.player.isSpectator()) {
if (this.minecraft.gui.getSpectatorGui().isMenuActive()) {
this.minecraft.gui.getSpectatorGui().onMouseScrolled(-i);
@@ -303,7 +_,7 @@
double d5 = getScaledYPos(window, this.accumulatedDY);
@@ -274,7 +_,7 @@
double d5 = this.accumulatedDY * (double)this.minecraft.getWindow().getGuiScaledHeight() / (double)this.minecraft.getWindow().getScreenHeight();
try {
- screen.mouseDragged(d2, d3, this.activeButton, d4, d5);
@@ -62,7 +62,7 @@
} catch (Throwable throwable) {
CrashReport crashreport1 = CrashReport.forThrowable(throwable, "mouseDragged event handler");
screen.fillCrashDetails(crashreport1);
@@ -393,6 +_,14 @@
@@ -349,6 +_,14 @@
public double ypos() {
return this.ypos;
@@ -1,24 +1,16 @@
--- a/net/minecraft/client/Options.java
+++ b/net/minecraft/client/Options.java
@@ -671,7 +_,8 @@
@@ -698,7 +_,8 @@
},
new OptionInstance.LazyEnum<>(
() -> Stream.concat(Stream.of(""), Minecraft.getInstance().getSoundManager().getAvailableSoundDevices().stream()).toList(),
- p_232011_ -> Minecraft.getInstance().isRunning() && p_232011_ != "" && !Minecraft.getInstance().getSoundManager().getAvailableSoundDevices().contains(p_232011_)
+ // FORGE: fix incorrect string comparison - PR #8767
+ p_232011_ -> Minecraft.getInstance().isRunning() && (p_232011_ == null || !p_232011_.isEmpty()) && !Minecraft.getInstance().getSoundManager().getAvailableSoundDevices().contains(p_232011_)
? Optional.empty()
: Optional.of(p_232011_),
? Optional.empty()
: Optional.of(p_232011_),
Codec.STRING
@@ -705,6 +_,7 @@
);
public boolean syncWrites;
public boolean startedCleanly = true;
+ private final Map<String, String> unknownKeys = new java.util.HashMap<>();
public OptionInstance<Boolean> darkMojangStudiosBackground() {
return this.darkMojangStudiosBackground;
@@ -1088,6 +_,7 @@
@@ -1079,6 +_,7 @@
}
public Options(Minecraft p_92138_, File p_92139_) {
@@ -26,16 +18,15 @@
this.minecraft = p_92138_;
this.optionsFile = new File(p_92139_, "options.txt");
boolean flag = Runtime.getRuntime().maxMemory() >= 1000000000L;
@@ -1222,15 +_,28 @@
this.startedCleanly = p_168428_.process("startedCleanly", this.startedCleanly);
p_168428_.process("showNowPlayingToast", this.showNowPlayingToast);
p_168428_.process("musicFrequency", this.musicFrequency);
+ processOptionsKeysOnly(p_168428_);
+ processOptionsEnd(p_168428_);
@@ -1210,12 +_,22 @@
p_168428_.process("telemetryOptInExtra", this.telemetryOptInExtra);
this.onboardAccessibility = p_168428_.process("onboardAccessibility", this.onboardAccessibility);
p_168428_.process("menuBackgroundBlurriness", this.menuBackgroundBlurriness);
+ processOptionsForge(p_168428_);
+ }
+ // FORGE: split off to allow reloading keys after mod loading is done
+ private void processOptionsKeysOnly(Options.FieldAccess p_168428_) {
+ // FORGE: split off to allow reloading options after mod loading is done
+ private void processOptionsForge(Options.FieldAccess p_168428_) {
for (KeyMapping keymapping : this.keyMappings) {
- String s = keymapping.saveString();
+ String s = keymapping.saveString() + (keymapping.getKeyModifier() != net.minecraftforge.client.settings.KeyModifier.NONE ? ":" + keymapping.getKeyModifier() : "");
@@ -50,13 +41,8 @@
+ }
}
}
+ }
+ private void processOptionsEnd(Options.FieldAccess p_168428_) {
for (SoundSource soundsource : SoundSource.values()) {
p_168428_.process("soundCategory_" + soundsource.getName(), this.soundSourceVolumes.get(soundsource));
}
@@ -1245,6 +_,10 @@
@@ -1233,6 +_,10 @@
}
public void load() {
@@ -67,60 +53,17 @@
try {
if (!this.optionsFile.exists()) {
return;
@@ -1269,7 +_,8 @@
this.graphicsMode.set(isTrue(optional.get()) ? GraphicsStatus.FANCY : GraphicsStatus.FAST);
@@ -1260,7 +_,8 @@
}
}
- this.processOptions(
+ java.util.function.Consumer<FieldAccess> processor = limited ? this::processOptionsKeysOnly : this::processOptions;
+ java.util.function.Consumer<FieldAccess> processor = limited ? this::processOptionsForge : this::processOptions;
+ processor.accept(
new Options.FieldAccess() {
@Nullable
private String getValue(String p_394210_) {
@@ -1350,6 +_,17 @@
);
compoundtag1.getString("fullscreenResolution").ifPresent(p_389133_ -> this.fullscreenVideoModeString = p_389133_);
KeyMapping.resetMapping();
+
+ if (limited) {
+ this.unknownKeys.clear();
+ } else {
+ var knownKeys = Arrays.stream(this.keyMappings).map(k -> "key_" + k.getName()).collect(Collectors.toSet());
+ for (var entry : compoundtag1.entrySet()) {
+ if (entry.getKey().startsWith("key_") && entry.getValue().asString().isPresent() && !knownKeys.contains(entry.getKey()))
+ this.unknownKeys.put(entry.getKey(), entry.getValue().asString().get());
+ }
+ }
+
} catch (Exception exception) {
LOGGER.error("Failed to load options", (Throwable)exception);
}
@@ -1377,9 +_,11 @@
public void save() {
try (final PrintWriter printwriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(this.optionsFile), StandardCharsets.UTF_8))) {
printwriter.println("version:" + SharedConstants.getCurrentVersion().dataVersion().version());
+ var seen = new java.util.HashSet<String>();
this.processOptions(
new Options.FieldAccess() {
public void writePrefix(String p_168491_) {
+ seen.add(p_168491_);
printwriter.print(p_168491_);
printwriter.print(':');
}
@@ -1435,6 +_,12 @@
if (s != null) {
printwriter.println("fullscreenResolution:" + s);
}
+ // Forge add any unknown keys so that Mods can add keybindings between vanilla loading/saving its config.
+ for (var entry : this.unknownKeys.entrySet()) {
+ if (!seen.contains(entry.getKey()))
+ printwriter.println(entry.getKey() + ":" + entry.getValue());
+ }
+
} catch (Exception exception) {
LOGGER.error("Failed to save options", (Throwable)exception);
}
@@ -1473,6 +_,7 @@
private String getValueOrNull(String p_168459_) {
@@ -1451,6 +_,7 @@
}
public void broadcastOptions() {
@@ -128,7 +71,7 @@
if (this.minecraft.player != null) {
this.minecraft.player.connection.broadcastClientInformation(this.buildPlayerInformation());
}
@@ -1586,6 +_,23 @@
@@ -1564,6 +_,23 @@
public static Component genericValueLabel(Component p_231901_, int p_231902_) {
return genericValueLabel(p_231901_, Component.literal(Integer.toString(p_231902_)));
@@ -1,32 +1,30 @@
--- a/net/minecraft/client/Screenshot.java
+++ b/net/minecraft/client/Screenshot.java
@@ -43,6 +_,13 @@
file2 = new File(file1, p_92297_);
}
@@ -54,14 +_,24 @@
file2 = new File(file1, p_92307_);
}
+ var event = new net.minecraftforge.client.event.ScreenshotEvent(p_389141_, file2);
+ if (net.minecraftforge.client.event.ScreenshotEvent.BUS.post(event)) {
+ p_92301_.accept(event.getCancelMessage());
+ return;
+ }
+ final File target = event.getScreenshotFile();
+ var event = net.minecraftforge.client.event.ForgeEventFactoryClient.onScreenshot(nativeimage, file2);
+ if (event.isCanceled()) {
+ p_92311_.accept(event.getCancelMessage());
+ return;
+ }
+ final File target = event.getScreenshotFile();
+
Util.ioPool()
.execute(
() -> {
@@ -50,10 +_,13 @@
NativeImage $$4x = p_389141_;
try {
- p_389141_.writeToFile(file2);
- Component component = Component.literal(file2.getName())
+ p_389141_.writeToFile(target);
+ Component component = Component.literal(target.getName())
.withStyle(ChatFormatting.UNDERLINE)
.withStyle(p_389149_ -> p_389149_.withClickEvent(new ClickEvent.OpenFile(file2.getAbsoluteFile())));
+ if (event.getResultMessage() != null)
+ p_92301_.accept(event.getResultMessage());
+ else
p_92301_.accept(Component.translatable("screenshot.success", component));
} catch (Throwable throwable1) {
if (p_389141_ != null) {
Util.ioPool()
.execute(
() -> {
try {
- nativeimage.writeToFile(file2);
- Component component = Component.literal(file2.getName())
+ nativeimage.writeToFile(target);
+ Component component = Component.literal(target.getName())
.withStyle(ChatFormatting.UNDERLINE)
- .withStyle(p_168608_ -> p_168608_.withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_FILE, file2.getAbsolutePath())));
+ .withStyle(p_168608_ -> p_168608_.withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_FILE, target.getAbsolutePath())));
+ if (event.getResultMessage() != null)
+ p_92311_.accept(event.getResultMessage());
+ else
p_92311_.accept(Component.translatable("screenshot.success", component));
} catch (Exception exception) {
LOGGER.warn("Couldn't save screenshot", (Throwable)exception);
@@ -1,16 +1,16 @@
--- a/net/minecraft/client/color/block/BlockColors.java
+++ b/net/minecraft/client/color/block/BlockColors.java
@@ -30,7 +_,8 @@
@@ -29,7 +_,8 @@
@OnlyIn(Dist.CLIENT)
public class BlockColors {
private static final int DEFAULT = -1;
public static final int LILY_PAD_IN_WORLD = -14647248;
public static final int LILY_PAD_DEFAULT = -9321636;
- private final IdMapper<BlockColor> blockColors = new IdMapper<>(32);
+ // Forge: Use registry delegate as non-Vanilla block ids are not constant
+ private final java.util.Map<net.minecraft.core.Holder.Reference<Block>, BlockColor> blockColors = new java.util.HashMap<>(32);
private final Map<Block, Set<Property<?>>> coloringStates = Maps.newHashMap();
public static BlockColors createDefault() {
@@ -95,11 +_,12 @@
@@ -91,11 +_,12 @@
}, Blocks.MELON_STEM, Blocks.PUMPKIN_STEM);
blockcolors.addColoringState(StemBlock.AGE, Blocks.MELON_STEM, Blocks.PUMPKIN_STEM);
blockcolors.register((p_92596_, p_92597_, p_92598_, p_92599_) -> p_92597_ != null && p_92598_ != null ? -14647248 : -9321636, Blocks.LILY_PAD);
@@ -24,7 +24,7 @@
if (blockcolor != null) {
return blockcolor.getColor(p_92583_, null, null, 0);
} else {
@@ -109,13 +_,15 @@
@@ -105,13 +_,15 @@
}
public int getColor(BlockState p_92578_, @Nullable BlockAndTintGetter p_92579_, @Nullable BlockPos p_92580_, int p_92581_) {
@@ -0,0 +1,35 @@
--- a/net/minecraft/client/color/item/ItemColors.java
+++ b/net/minecraft/client/color/item/ItemColors.java
@@ -26,7 +_,8 @@
@OnlyIn(Dist.CLIENT)
public class ItemColors {
private static final int DEFAULT = -1;
- private final IdMapper<ItemColor> itemColors = new IdMapper<>(32);
+ // Forge: Use registry delegate as non-Vanilla item ids are not constant
+ private final java.util.Map<net.minecraft.core.Holder.Reference<Item>, ItemColor> itemColors = new java.util.HashMap<>(32);
public static ItemColors createDefault(BlockColors p_92684_) {
ItemColors itemcolors = new ItemColors();
@@ -101,17 +_,20 @@
(p_357654_, p_357655_) -> p_357655_ == 0 ? -1 : ARGB.opaque(p_357654_.getOrDefault(DataComponents.MAP_COLOR, MapItemColor.DEFAULT).rgb()),
Items.FILLED_MAP
);
+ net.minecraftforge.client.ForgeHooksClient.onItemColorsInit(itemcolors, p_92684_);
return itemcolors;
}
public int getColor(ItemStack p_92677_, int p_92678_) {
- ItemColor itemcolor = this.itemColors.byId(BuiltInRegistries.ITEM.getId(p_92677_.getItem()));
+ ItemColor itemcolor = this.itemColors.get(net.minecraftforge.registries.ForgeRegistries.ITEMS.getDelegateOrThrow(p_92677_.getItem()));
return itemcolor == null ? -1 : itemcolor.getColor(p_92677_, p_92678_);
}
+ /** @deprecated Register via {@link net.minecraftforge.client.event.RegisterColorHandlersEvent.Item} */
+ @Deprecated
public void register(ItemColor p_92690_, ItemLike... p_92691_) {
for (ItemLike itemlike : p_92691_) {
- this.itemColors.addMapping(p_92690_, Item.getId(itemlike.asItem()));
+ this.itemColors.put(net.minecraftforge.registries.ForgeRegistries.ITEMS.getDelegateOrThrow(itemlike.asItem()), p_92690_);
}
}
}
@@ -1,22 +0,0 @@
--- a/net/minecraft/client/data/Main.java
+++ b/net/minecraft/client/data/Main.java
@@ -31,13 +_,18 @@
OptionSpec<Void> optionspec1 = optionparser.accepts("client", "Include client generators");
OptionSpec<Void> optionspec2 = optionparser.accepts("all", "Include all generators");
OptionSpec<String> optionspec3 = optionparser.accepts("output", "Output folder").withRequiredArg().defaultsTo("generated");
+ OptionSpec<String> inputSpec = optionparser.accepts("input", "Input folder").withRequiredArg();
+ var loader = net.minecraftforge.data.loading.DatagenModLoader.setup(optionparser, true);
OptionSet optionset = optionparser.parse(p_375526_);
- if (!optionset.has(optionspec) && optionset.hasOptions()) {
+ if (!optionset.has(optionspec) && optionset.hasOptions() && loader.hasArgs(optionset)) {
+ var input = optionset.valuesOf(inputSpec).stream().map(Paths::get).toList();
Path path = Paths.get(optionspec3.value(optionset));
boolean flag = optionset.has(optionspec2);
boolean flag1 = flag || optionset.has(optionspec1);
Bootstrap.bootStrap();
ClientBootstrap.bootstrap();
+ if (!loader.run(optionset, path, input, flag, flag1, flag, flag, true))
+ return;
DataGenerator datagenerator = new DataGenerator(path, SharedConstants.getCurrentVersion(), true);
addClientProviders(datagenerator, flag1);
datagenerator.run();
@@ -1,12 +0,0 @@
--- a/net/minecraft/client/data/models/ItemModelGenerators.java
+++ b/net/minecraft/client/data/models/ItemModelGenerators.java
@@ -871,6 +_,9 @@
this.declareCustomModelItem(Items.COD);
this.declareCustomModelItem(Items.FEATHER);
this.declareCustomModelItem(Items.LEAD);
+ // moved from validate to here, because it's just vanilla default blocks
+ if (this.itemModelOutput instanceof ModelProvider.ItemInfoCollector collector)
+ collector.generateDefaultBlockModels();
}
@OnlyIn(Dist.CLIENT)
@@ -1,111 +0,0 @@
--- a/net/minecraft/client/data/models/ModelProvider.java
+++ b/net/minecraft/client/data/models/ModelProvider.java
@@ -45,11 +_,11 @@
@Override
public CompletableFuture<?> run(CachedOutput p_376268_) {
- ModelProvider.ItemInfoCollector modelprovider$iteminfocollector = new ModelProvider.ItemInfoCollector();
- ModelProvider.BlockStateGeneratorCollector modelprovider$blockstategeneratorcollector = new ModelProvider.BlockStateGeneratorCollector();
+ ModelProvider.ItemInfoCollector modelprovider$iteminfocollector = new ModelProvider.ItemInfoCollector(this::getKnownItems);
+ ModelProvider.BlockStateGeneratorCollector modelprovider$blockstategeneratorcollector = new ModelProvider.BlockStateGeneratorCollector(this::getKnownBlocks);
ModelProvider.SimpleModelCollector modelprovider$simplemodelcollector = new ModelProvider.SimpleModelCollector();
- new BlockModelGenerators(modelprovider$blockstategeneratorcollector, modelprovider$iteminfocollector, modelprovider$simplemodelcollector).run();
- new ItemModelGenerators(modelprovider$iteminfocollector, modelprovider$simplemodelcollector).run();
+ getBlockModelGenerators(modelprovider$blockstategeneratorcollector, modelprovider$iteminfocollector, modelprovider$simplemodelcollector).run();
+ getItemModelGenerators(modelprovider$iteminfocollector, modelprovider$simplemodelcollector).run();
modelprovider$blockstategeneratorcollector.validate();
modelprovider$iteminfocollector.finalizeAndValidate();
return CompletableFuture.allOf(
@@ -59,6 +_,22 @@
);
}
+ protected Stream<Block> getKnownBlocks() {
+ return BuiltInRegistries.BLOCK.stream().filter(block -> "minecraft".equals(block.builtInRegistryHolder().key().location().getNamespace()));
+ }
+
+ protected Stream<Item> getKnownItems() {
+ return BuiltInRegistries.ITEM.stream().filter(item -> "minecraft".equals(item.builtInRegistryHolder().key().location().getNamespace()));
+ }
+
+ protected BlockModelGenerators getBlockModelGenerators(BlockStateGeneratorCollector blocks, ItemInfoCollector items, SimpleModelCollector models) {
+ return new BlockModelGenerators(blocks, items, models);
+ }
+
+ protected ItemModelGenerators getItemModelGenerators(ItemInfoCollector items, SimpleModelCollector models) {
+ return new ItemModelGenerators(items, models);
+ }
+
@Override
public final String getName() {
return "Model Definitions";
@@ -67,6 +_,15 @@
@OnlyIn(Dist.CLIENT)
public static class BlockStateGeneratorCollector implements Consumer<BlockModelDefinitionGenerator> {
private final Map<Block, BlockModelDefinitionGenerator> generators = new HashMap<>();
+ private final Supplier<Stream<Block>> known;
+
+ public BlockStateGeneratorCollector() {
+ this(() -> BuiltInRegistries.BLOCK.stream().filter(block -> "minecraft".equals(block.builtInRegistryHolder().key().location().getNamespace())));
+ }
+
+ public BlockStateGeneratorCollector(Supplier<Stream<Block>> known) {
+ this.known = known;
+ }
public void accept(BlockModelDefinitionGenerator p_393399_) {
Block block = p_393399_.block();
@@ -77,7 +_,7 @@
}
public void validate() {
- Stream<Holder.Reference<Block>> stream = BuiltInRegistries.BLOCK.listElements().filter(p_376480_ -> true);
+ Stream<Holder.Reference<Block>> stream = known.get().map(Block::builtInRegistryHolder);
List<ResourceLocation> list = stream.filter(p_378423_ -> !this.generators.containsKey(p_378423_.value()))
.map(p_378200_ -> p_378200_.key().location())
.toList();
@@ -97,6 +_,15 @@
public static class ItemInfoCollector implements ItemModelOutput {
private final Map<Item, ClientItem> itemInfos = new HashMap<>();
private final Map<Item, Item> copies = new HashMap<>();
+ private final Supplier<Stream<Item>> known;
+
+ public ItemInfoCollector() {
+ this(() -> BuiltInRegistries.ITEM.stream().filter(item -> "minecraft".equals(item.builtInRegistryHolder().key().location().getNamespace())));
+ }
+
+ public ItemInfoCollector(Supplier<Stream<Item>> known) {
+ this.known = known;
+ }
@Override
public void accept(Item p_376450_, ItemModel.Unbaked p_378513_) {
@@ -115,7 +_,7 @@
this.copies.put(p_376965_, p_377438_);
}
- public void finalizeAndValidate() {
+ public void generateDefaultBlockModels() {
BuiltInRegistries.ITEM.forEach(p_378629_ -> {
if (!this.copies.containsKey(p_378629_)) {
if (p_378629_ instanceof BlockItem blockitem && !this.itemInfos.containsKey(blockitem)) {
@@ -124,6 +_,8 @@
}
}
});
+ }
+ public void finalizeAndValidate() {
this.copies.forEach((p_376289_, p_375718_) -> {
ClientItem clientitem = this.itemInfos.get(p_375718_);
if (clientitem == null) {
@@ -132,8 +_,8 @@
this.register(p_376289_, clientitem);
}
});
- List<ResourceLocation> list = BuiltInRegistries.ITEM
- .listElements()
+ List<ResourceLocation> list = known.get()
+ .map(item -> item.builtInRegistryHolder())
.filter(p_377225_ -> !this.itemInfos.containsKey(p_377225_.value()))
.map(p_378591_ -> p_378591_.key().location())
.toList();
@@ -1,11 +1,11 @@
--- a/net/minecraft/client/gui/Font.java
+++ b/net/minecraft/client/gui/Font.java
@@ -32,7 +_,7 @@
import org.joml.Matrix4f;
@@ -33,7 +_,7 @@
import org.joml.Vector3f;
@OnlyIn(Dist.CLIENT)
-public class Font {
+public class Font implements net.minecraftforge.client.extensions.IForgeFont {
private static final float EFFECT_DEPTH = 0.01F;
private static final float OVER_EFFECT_DEPTH = 0.01F;
private static final float UNDER_EFFECT_DEPTH = -0.01F;
private static final Vector3f SHADOW_OFFSET = new Vector3f(0.0F, 0.0F, 0.03F);
public static final int ALPHA_CUTOFF = 8;
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/gui/Gui.java
+++ b/net/minecraft/client/gui/Gui.java
@@ -151,7 +_,7 @@
@@ -147,7 +_,7 @@
public float vignetteBrightness = 1.0F;
private int toolHighlightTimer;
private ItemStack lastToolHighlight = ItemStack.EMPTY;
@@ -9,16 +9,16 @@
private final SubtitleOverlay subtitleOverlay;
private final SpectatorGui spectatorGui;
private final PlayerTabOverlay tabList;
@@ -377,7 +_,7 @@
int i = Mth.floor(this.minecraft.mouseHandler.getScaledXPos(window));
int j = Mth.floor(this.minecraft.mouseHandler.getScaledYPos(window));
p_329202_.nextStratum();
@@ -345,7 +_,7 @@
Window window = this.minecraft.getWindow();
int i = Mth.floor(this.minecraft.mouseHandler.xpos() * (double)window.getGuiScaledWidth() / (double)window.getScreenWidth());
int j = Mth.floor(this.minecraft.mouseHandler.ypos() * (double)window.getGuiScaledHeight() / (double)window.getScreenHeight());
- this.chat.render(p_329202_, this.tickCount, i, j, false);
+ net.minecraftforge.client.ForgeHooksClient.onCustomizeChatEvent(p_329202_, this.chat, window, i, j, this.tickCount);
}
}
@@ -472,6 +_,8 @@
@@ -443,6 +_,8 @@
for (MobEffectInstance mobeffectinstance : Ordering.natural().reverse().sortedCopy(collection)) {
Holder<MobEffect> holder = mobeffectinstance.getEffect();
@@ -27,15 +27,15 @@
if (mobeffectinstance.showIcon()) {
int k = p_282812_.guiWidth();
int l = 1;
@@ -502,6 +_,7 @@
@@ -473,6 +_,7 @@
}
}
+ if (renderer.renderGuiIcon(mobeffectinstance, this, p_282812_, k, l, 0, f)) continue;
p_282812_.blitSprite(RenderPipelines.GUI_TEXTURED, getMobEffectSprite(holder), k + 3, l + 3, 18, 18, ARGB.white(f));
}
}
@@ -598,6 +_,10 @@
TextureAtlasSprite textureatlassprite = mobeffecttexturemanager.get(holder);
int l1 = k;
int k1 = l;
@@ -623,6 +_,10 @@
}
private void renderSelectedItemName(GuiGraphics p_283501_) {
@@ -46,7 +46,7 @@
Profiler.get().push("selectedItemName");
if (this.toolHighlightTimer > 0 && !this.lastToolHighlight.isEmpty()) {
MutableComponent mutablecomponent = Component.empty().append(this.lastToolHighlight.getHoverName()).withStyle(this.lastToolHighlight.getRarity().color());
@@ -605,9 +_,13 @@
@@ -630,9 +_,13 @@
mutablecomponent.withStyle(ChatFormatting.ITALIC);
}
@@ -62,7 +62,7 @@
if (!this.minecraft.gameMode.canHurtPlayer()) {
k += 14;
}
@@ -618,7 +_,7 @@
@@ -643,7 +_,7 @@
}
if (l > 0) {
@@ -71,8 +71,8 @@
}
}
@@ -1148,7 +_,7 @@
ItemStack itemstack = this.minecraft.player.getInventory().getSelectedItem();
@@ -1152,7 +_,7 @@
ItemStack itemstack = this.minecraft.player.getInventory().getSelected();
if (itemstack.isEmpty()) {
this.toolHighlightTimer = 0;
- } else if (this.lastToolHighlight.isEmpty() || !itemstack.is(this.lastToolHighlight.getItem()) || !itemstack.getHoverName().equals(this.lastToolHighlight.getHoverName())) {
@@ -1,144 +1,160 @@
--- a/net/minecraft/client/gui/GuiGraphics.java
+++ b/net/minecraft/client/gui/GuiGraphics.java
@@ -72,7 +_,7 @@
import org.joml.Vector3f;
@@ -53,7 +_,7 @@
import org.joml.Vector2ic;
@OnlyIn(Dist.CLIENT)
-public class GuiGraphics {
+public class GuiGraphics implements net.minecraftforge.client.extensions.IForgeGuiGraphics {
public static final float MAX_GUI_Z = 10000.0F;
public static final float MIN_GUI_Z = -10000.0F;
private static final int EXTRA_SPACE_AFTER_FIRST_TOOLTIP_LINE = 2;
private final Minecraft minecraft;
private final Matrix3x2fStack pose;
@@ -875,6 +_,7 @@
@@ -227,6 +_,11 @@
}
public int drawString(Font p_283343_, @Nullable String p_281896_, int p_283569_, int p_283418_, int p_281560_, boolean p_282130_) {
+ return this.drawString(p_283343_, p_281896_, (float)p_283569_, (float)p_283418_, p_281560_, p_282130_);
+ }
+
+ // Forge: Add float variant for x,y coordinates
+ public int drawString(Font p_283343_, @Nullable String p_281896_, float p_283569_, float p_283418_, int p_281560_, boolean p_282130_) {
return p_281896_ == null
? 0
: p_283343_.drawInBatch(
@@ -248,6 +_,11 @@
}
public int drawString(Font p_282636_, FormattedCharSequence p_281596_, int p_281586_, int p_282816_, int p_281743_, boolean p_282394_) {
+ return this.drawString(p_282636_, p_281596_, (float)p_281586_, (float)p_282816_, p_281743_, p_282394_);
+ }
+
+ // Forge: Add float variant for x,y coordinates
+ public int drawString(Font p_282636_, FormattedCharSequence p_281596_, float p_281586_, float p_282816_, int p_281743_, boolean p_282394_) {
return p_282636_.drawInBatch(
p_281596_,
(float)p_281586_,
@@ -872,6 +_,7 @@
CrashReport crashreport = CrashReport.forThrowable(throwable, "Rendering item");
CrashReportCategory crashreportcategory = crashreport.addCategory("Item being rendered");
crashreportcategory.setDetail("Item Type", () -> String.valueOf(p_283653_.getItem()));
+ crashreportcategory.setDetail("Registry Name", () -> String.valueOf(net.minecraftforge.registries.ForgeRegistries.ITEMS.getKey(p_283653_.getItem())));
crashreportcategory.setDetail("Item Components", () -> String.valueOf(p_283653_.getComponents()));
crashreportcategory.setDetail("Item Foil", () -> String.valueOf(p_283653_.hasFoil()));
crashreportcategory.setDetail("Item Type", () -> String.valueOf(p_281675_.getItem()));
+ crashreportcategory.setDetail("Registry Name", () -> String.valueOf(net.minecraftforge.registries.ForgeRegistries.ITEMS.getKey(p_281675_.getItem())));
crashreportcategory.setDetail("Item Components", () -> String.valueOf(p_281675_.getComponents()));
crashreportcategory.setDetail("Item Foil", () -> String.valueOf(p_281675_.hasFoil()));
throw new ReportedException(crashreport);
@@ -893,6 +_,7 @@
this.renderItemCooldown(p_283349_, p_282641_, p_282146_);
@@ -892,13 +_,24 @@
this.renderItemCount(p_282005_, p_283349_, p_282641_, p_282146_, p_282803_);
this.pose.popMatrix();
this.renderItemCooldown(p_283349_, p_282641_, p_282146_);
this.pose.popPose();
+ net.minecraftforge.client.ItemDecoratorHandler.of(p_283349_).render(this, p_282005_, p_283349_, p_282641_, p_282146_);
}
}
@@ -904,21 +_,30 @@
this.setTooltipForNextFrame(this.minecraft.font, p_407686_, DefaultTooltipPositioner.INSTANCE, p_410475_, p_407139_, false);
}
+ private ItemStack tooltipStack = ItemStack.EMPTY;
+
public void setTooltipForNextFrame(Font p_408152_, ItemStack p_410145_, int p_410585_, int p_408354_) {
+ this.tooltipStack = p_410145_;
this.setTooltipForNextFrame(
p_408152_, Screen.getTooltipFromItem(this.minecraft, p_410145_), p_410145_.getTooltipImage(), p_410585_, p_408354_, p_410145_.get(DataComponents.TOOLTIP_STYLE)
+ private ItemStack tooltipStack = ItemStack.EMPTY;
public void renderTooltip(Font p_282308_, ItemStack p_282781_, int p_282687_, int p_282292_) {
+ this.tooltipStack = p_282781_;
this.renderTooltip(
p_282308_, Screen.getTooltipFromItem(this.minecraft, p_282781_), p_282781_.getTooltipImage(), p_282687_, p_282292_, p_282781_.get(DataComponents.TOOLTIP_STYLE)
);
+ this.tooltipStack = ItemStack.EMPTY;
}
public void setTooltipForNextFrame(Font p_407170_, List<Component> p_407123_, Optional<TooltipComponent> p_409349_, int p_406573_, int p_409911_) {
this.setTooltipForNextFrame(p_407170_, p_407123_, p_409349_, p_406573_, p_409911_, null);
}
+ public void setTooltipForNextFrame(Font font, List<Component> textComponents, Optional<TooltipComponent> tooltipComponent, ItemStack stack, int mouseX, int mouseY) {
+ this.tooltipStack = stack;
+ this.setTooltipForNextFrame(font, textComponents, tooltipComponent, mouseX, mouseY, stack.get(DataComponents.TOOLTIP_STYLE));
+ this.tooltipStack = ItemStack.EMPTY;
+ }
+
public void setTooltipForNextFrame(
Font p_407847_, List<Component> p_408847_, Optional<TooltipComponent> p_410489_, int p_409369_, int p_407472_, @Nullable ResourceLocation p_410303_
+ public void renderTooltip(Font font, List<Component> textComponents, Optional<TooltipComponent> tooltipComponent, ItemStack stack, int mouseX, int mouseY) {
+ this.tooltipStack = stack;
+ this.renderTooltip(font, textComponents, tooltipComponent, mouseX, mouseY, stack.get(DataComponents.TOOLTIP_STYLE));
+ this.tooltipStack = ItemStack.EMPTY;
}
public void renderTooltip(Font p_283128_, List<Component> p_282716_, Optional<TooltipComponent> p_281682_, int p_283678_, int p_281696_) {
@@ -908,8 +_,7 @@
public void renderTooltip(
Font p_362491_, List<Component> p_368544_, Optional<TooltipComponent> p_362815_, int p_366300_, int p_368952_, @Nullable ResourceLocation p_368469_
) {
- List<ClientTooltipComponent> list = p_408847_.stream().map(Component::getVisualOrderText).map(ClientTooltipComponent::create).collect(Util.toMutableList());
- p_410489_.ifPresent(p_325321_ -> list.add(list.isEmpty() ? 0 : 1, ClientTooltipComponent.create(p_325321_)));
+ List<ClientTooltipComponent> list = net.minecraftforge.client.ForgeHooksClient.gatherTooltipComponents(this.tooltipStack, p_408847_, p_410489_, p_409369_, guiWidth(), guiHeight(), p_407847_);
this.setTooltipForNextFrameInternal(p_407847_, list, p_409369_, p_407472_, DefaultTooltipPositioner.INSTANCE, p_410303_, false);
- List<ClientTooltipComponent> list = p_368544_.stream().map(Component::getVisualOrderText).map(ClientTooltipComponent::create).collect(Util.toMutableList());
- p_362815_.ifPresent(p_325321_ -> list.add(list.isEmpty() ? 0 : 1, ClientTooltipComponent.create(p_325321_)));
+ List<ClientTooltipComponent> list = net.minecraftforge.client.ForgeHooksClient.gatherTooltipComponents(this.tooltipStack, p_368544_, p_362815_, p_366300_, guiWidth(), guiHeight(), p_362491_);
this.renderTooltipInternal(p_362491_, list, p_366300_, p_368952_, DefaultTooltipPositioner.INSTANCE, p_368469_);
}
@@ -931,7 +_,22 @@
@@ -922,7 +_,22 @@
}
public void setComponentTooltipForNextFrame(Font p_406239_, List<Component> p_410275_, int p_410594_, int p_409343_) {
- this.setComponentTooltipForNextFrame(p_406239_, p_410275_, p_410594_, p_409343_, null);
+ List<ClientTooltipComponent> components = net.minecraftforge.client.ForgeHooksClient.gatherTooltipComponents(this.tooltipStack, p_410275_, p_410594_, guiWidth(), guiHeight(), p_406239_);
+ this.setTooltipForNextFrameInternal(p_406239_, components, p_410594_, p_409343_, DefaultTooltipPositioner.INSTANCE, null, false);
public void renderComponentTooltip(Font p_282739_, List<Component> p_281832_, int p_282191_, int p_282446_) {
- this.renderComponentTooltip(p_282739_, p_281832_, p_282191_, p_282446_, null);
+ List<ClientTooltipComponent> components = net.minecraftforge.client.ForgeHooksClient.gatherTooltipComponents(this.tooltipStack, p_281832_, p_282191_, guiWidth(), guiHeight(), p_282739_);
+ this.renderTooltipInternal(p_282739_, components, p_282191_, p_282446_, DefaultTooltipPositioner.INSTANCE, null);
+ }
+
+ public void renderComponentTooltip(Font font, List<? extends net.minecraft.network.chat.FormattedText> tooltips, int mouseX, int mouseY, ItemStack stack) {
+ this.tooltipStack = stack;
+ List<ClientTooltipComponent> components = net.minecraftforge.client.ForgeHooksClient.gatherTooltipComponents(stack, tooltips, mouseX, guiWidth(), guiHeight(), font);
+ this.setTooltipForNextFrameInternal(font, components, mouseX, mouseY, DefaultTooltipPositioner.INSTANCE, null, false);
+ this.renderTooltipInternal(font, components, mouseX, mouseY, DefaultTooltipPositioner.INSTANCE, null);
+ this.tooltipStack = ItemStack.EMPTY;
+ }
+
+ public void renderComponentTooltipFromElements(Font font, List<com.mojang.datafixers.util.Either<FormattedText, TooltipComponent>> elements, int mouseX, int mouseY, ItemStack stack) {
+ this.tooltipStack = stack;
+ List<ClientTooltipComponent> components = net.minecraftforge.client.ForgeHooksClient.gatherTooltipComponentsFromElements(stack, elements, mouseX, guiWidth(), guiHeight(), font);
+ this.setTooltipForNextFrameInternal(font, components, mouseX, mouseY, DefaultTooltipPositioner.INSTANCE, null, false);
+ this.renderTooltipInternal(font, components, mouseX, mouseY, DefaultTooltipPositioner.INSTANCE, null);
+ this.tooltipStack = ItemStack.EMPTY;
}
public void setComponentTooltipForNextFrame(Font p_408650_, List<Component> p_407512_, int p_406019_, int p_408123_, @Nullable ResourceLocation p_409993_) {
@@ -994,11 +_,13 @@
ClientTooltipPositioner p_409451_,
@Nullable ResourceLocation p_409298_
public void renderComponentTooltip(Font p_369090_, List<Component> p_365405_, int p_368143_, int p_366244_, @Nullable ResourceLocation p_364763_) {
@@ -964,11 +_,13 @@
@Nullable ResourceLocation p_368234_
) {
+ var preEvent = net.minecraftforge.client.ForgeHooksClient.onRenderTooltipPre(this.tooltipStack, this, p_283678_, p_281696_, guiWidth(), guiHeight(), p_282716_, p_283128_, p_409451_);
+ if (preEvent == null) return;
int i = 0;
int j = p_282716_.size() == 1 ? -2 : 0;
if (!p_282615_.isEmpty()) {
+ var preEvent = net.minecraftforge.client.ForgeHooksClient.onRenderTooltipPre(this.tooltipStack, this, p_283230_, p_283417_, guiWidth(), guiHeight(), p_282615_, p_282675_, p_282442_);
+ if (preEvent.isCanceled()) return;
int i = 0;
int j = p_282615_.size() == 1 ? -2 : 0;
for (ClientTooltipComponent clienttooltipcomponent : p_282716_) {
- int k = clienttooltipcomponent.getWidth(p_283128_);
+ int k = clienttooltipcomponent.getWidth(preEvent.getFont());
if (k > i) {
i = k;
for (ClientTooltipComponent clienttooltipcomponent : p_282615_) {
- int k = clienttooltipcomponent.getWidth(p_282675_);
+ int k = clienttooltipcomponent.getWidth(preEvent.getFont());
if (k > i) {
i = k;
}
@@ -978,18 +_,19 @@
int i2 = i;
int j2 = j;
- Vector2ic vector2ic = p_282442_.positionTooltip(this.guiWidth(), this.guiHeight(), p_283230_, p_283417_, i, j);
+ Vector2ic vector2ic = p_282442_.positionTooltip(this.guiWidth(), this.guiHeight(), preEvent.getX(), preEvent.getY(), i2, j2);
int l = vector2ic.x();
int i1 = vector2ic.y();
this.pose.pushPose();
int j1 = 400;
- TooltipRenderUtil.renderTooltipBackground(this, l, i1, i, j, 400, p_368234_);
+ var background_event = net.minecraftforge.client.event.ForgeEventFactoryClient.onRenderTooltipBackground(this.tooltipStack, this, l, i1, preEvent.getFont(), p_282615_, p_368234_);
+ TooltipRenderUtil.renderTooltipBackground(this, l, i1, i, j, 400, background_event.getBackground());
this.pose.translate(0.0F, 0.0F, 400.0F);
int k1 = i1;
for (int l1 = 0; l1 < p_282615_.size(); l1++) {
ClientTooltipComponent clienttooltipcomponent1 = p_282615_.get(l1);
- clienttooltipcomponent1.renderText(p_282675_, l, k1, this.pose.last().pose(), this.bufferSource);
+ clienttooltipcomponent1.renderText(preEvent.getFont(), l, k1, this.pose.last().pose(), this.bufferSource);
k1 += clienttooltipcomponent1.getHeight(p_282675_) + (l1 == 0 ? 2 : 0);
}
@@ -1008,16 +_,17 @@
int l1 = i;
int i2 = j;
- Vector2ic vector2ic = p_409451_.positionTooltip(this.guiWidth(), this.guiHeight(), p_283678_, p_281696_, i, j);
+ Vector2ic vector2ic = p_409451_.positionTooltip(this.guiWidth(), this.guiHeight(), preEvent.getX(), preEvent.getY(), i, j);
int l = vector2ic.x();
int i1 = vector2ic.y();
this.pose.pushMatrix();
- TooltipRenderUtil.renderTooltipBackground(this, l, i1, i, j, p_409298_);
+ var background_event = net.minecraftforge.client.event.ForgeEventFactoryClient.onRenderTooltipBackground(this.tooltipStack, this, l, i1, preEvent.getFont(), p_282716_, p_409298_);
+ TooltipRenderUtil.renderTooltipBackground(this, l, i1, i, j, background_event.getBackground());
int j1 = i1;
@@ -997,7 +_,7 @@
for (int k1 = 0; k1 < p_282716_.size(); k1++) {
ClientTooltipComponent clienttooltipcomponent1 = p_282716_.get(k1);
- clienttooltipcomponent1.renderText(this, p_283128_, l, j1);
+ clienttooltipcomponent1.renderText(this, preEvent.getFont(), l, j1);
j1 += clienttooltipcomponent1.getHeight(p_283128_) + (k1 == 0 ? 2 : 0);
for (int k2 = 0; k2 < p_282615_.size(); k2++) {
ClientTooltipComponent clienttooltipcomponent2 = p_282615_.get(k2);
- clienttooltipcomponent2.renderImage(p_282675_, l, k1, i2, j2, this);
+ clienttooltipcomponent2.renderImage(preEvent.getFont(), l, k1, i2, j2, this);
k1 += clienttooltipcomponent2.getHeight(p_282675_) + (k2 == 0 ? 2 : 0);
}
@@ -1054,6 +_,10 @@
}
}
}
@@ -1025,7 +_,7 @@
for (int j2 = 0; j2 < p_282716_.size(); j2++) {
ClientTooltipComponent clienttooltipcomponent2 = p_282716_.get(j2);
- clienttooltipcomponent2.renderImage(p_283128_, l, j1, l1, i2, this);
+ clienttooltipcomponent2.renderImage(preEvent.getFont(), l, j1, l1, i2, this);
j1 += clienttooltipcomponent2.getHeight(p_283128_) + (j2 == 0 ? 2 : 0);
}
@@ -1222,6 +_,14 @@
public void submitProfilerChartRenderState(List<ResultField> p_408565_, int p_410147_, int p_406156_, int p_407365_, int p_408180_) {
this.guiRenderState.submitPicturesInPictureState(new GuiProfilerChartRenderState(p_408565_, p_410147_, p_406156_, p_407365_, p_408180_, this.scissorStack.peek()));
+ }
+
+ public GuiRenderState getRenderState() {
+ return this.guiRenderState;
+ }
+
+ public GuiGraphics.ScissorStack getScissorStack() {
+ return this.scissorStack;
+ public MultiBufferSource.BufferSource getBufferSource() {
+ return this.bufferSource;
}
@OnlyIn(Dist.CLIENT)
public void drawSpecial(Consumer<MultiBufferSource> p_367429_) {
@@ -1,11 +1,11 @@
--- a/net/minecraft/client/gui/components/AbstractButton.java
+++ b/net/minecraft/client/gui/components/AbstractButton.java
@@ -38,7 +_,7 @@
@@ -39,7 +_,7 @@
this.getHeight(),
ARGB.white(this.alpha)
);
- int i = ARGB.color(this.alpha, this.active ? -1 : -6250336);
- int i = this.active ? 16777215 : 10526880;
+ int i = getFGColor();
this.renderString(p_281670_, minecraft.font, i);
this.renderString(p_281670_, minecraft.font, i | Mth.ceil(this.alpha * 255.0F) << 24);
}
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/gui/components/AbstractWidget.java
+++ b/net/minecraft/client/gui/components/AbstractWidget.java
@@ -236,6 +_,25 @@
@@ -259,6 +_,25 @@
this.focused = p_93693_;
}
@@ -11,7 +11,7 @@
+
+ public int getFGColor() {
+ if (packedFGColor != UNSET_FG_COLOR) return packedFGColor;
+ return net.minecraft.util.ARGB.color(this.alpha, this.active ? -1 : -6250336); // White : Light Grey
+ return this.active ? 16777215 : 10526880; // White : Light Grey
+ }
+
+ public void setFGColor(int color) {
@@ -1,17 +1,17 @@
--- a/net/minecraft/client/gui/components/BossHealthOverlay.java
+++ b/net/minecraft/client/gui/components/BossHealthOverlay.java
@@ -67,13 +_,16 @@
@@ -66,13 +_,16 @@
for (LerpingBossEvent lerpingbossevent : this.events.values()) {
int k = i / 2 - 91;
+ var event = net.minecraftforge.client.ForgeHooksClient.onCustomizeBossEventProgress(p_283175_, this.minecraft.getWindow(), lerpingbossevent, k, j, 10 + this.minecraft.font.lineHeight);
+ if (event != null) {
+ if (!event.isCanceled()) {
this.drawBar(p_283175_, k, j, lerpingbossevent);
Component component = lerpingbossevent.getName();
int l = this.minecraft.font.width(component);
int i1 = i / 2 - l / 2;
int j1 = j - 9;
p_283175_.drawString(this.minecraft.font, component, i1, j1, -1);
p_283175_.drawString(this.minecraft.font, component, i1, j1, 16777215);
- j += 10 + 9;
+ }
+ j += event.getIncrement();
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/gui/components/DebugScreenOverlay.java
+++ b/net/minecraft/client/gui/components/DebugScreenOverlay.java
@@ -139,9 +_,9 @@
@@ -105,9 +_,9 @@
@Nullable
private CompletableFuture<LevelChunk> serverChunk;
private boolean renderDebug;
@@ -13,7 +13,7 @@
private final LocalSampleLogger frameTimeLogger = new LocalSampleLogger(1);
private final LocalSampleLogger tickTimeLogger = new LocalSampleLogger(TpsDebugDimensions.values().length);
private final LocalSampleLogger pingLogger = new LocalSampleLogger(1);
@@ -183,15 +_,19 @@
@@ -135,14 +_,18 @@
this.clientChunk = null;
}
@@ -29,14 +29,13 @@
+ protected void drawText(ProfilerFiller profilerfiller, GuiGraphics p_281427_) {
this.drawGameInformation(p_281427_);
this.drawSystemInformation(p_281427_);
p_281427_.nextStratum();
+ }
+
+ protected void drawFPSCharts(ProfilerFiller profilerfiller, GuiGraphics p_281427_) {
this.profilerPieChart.setBottomOffset(10);
if (this.renderFpsCharts) {
int i = p_281427_.guiWidth();
@@ -204,7 +_,9 @@
@@ -155,7 +_,9 @@
this.profilerPieChart.setBottomOffset(this.tpsChart.getFullHeight());
}
@@ -46,7 +45,7 @@
if (this.renderNetworkCharts) {
int l = p_281427_.guiWidth();
int i1 = l / 2;
@@ -220,12 +_,22 @@
@@ -171,12 +_,22 @@
try (Zone zone = profilerfiller.zone("profilerPie")) {
this.profilerPieChart.render(p_281427_);
}
@@ -71,7 +70,7 @@
list.add("");
boolean flag = this.minecraft.getSingleplayerServer() != null;
list.add(
@@ -239,11 +_,18 @@
@@ -190,11 +_,18 @@
+ (this.renderNetworkCharts ? " visible" : " hidden")
);
list.add("For help: press F3 + Q");
@@ -91,7 +90,7 @@
this.renderLines(p_281261_, list, false);
}
@@ -597,6 +_,7 @@
@@ -543,6 +_,7 @@
list.add("");
list.add(ChatFormatting.UNDERLINE + "Targeted Entity");
list.add(String.valueOf(BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType())));
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/gui/components/toasts/ToastManager.java
+++ b/net/minecraft/client/gui/components/toasts/ToastManager.java
@@ -146,6 +_,7 @@
@@ -107,6 +_,7 @@
}
public void addToast(Toast p_360768_) {
@@ -1,10 +0,0 @@
--- a/net/minecraft/client/gui/render/GuiRenderer.java
+++ b/net/minecraft/client/gui/render/GuiRenderer.java
@@ -134,6 +_,7 @@
builder.put((Class<? extends PictureInPictureRenderState>)pictureinpicturerenderer.getRenderStateClass(), pictureinpicturerenderer);
}
+ net.minecraftforge.client.ForgeHooksClient.onRegisterPictureInPictureRenderers(p_410565_, p_410441_, builder);
this.pictureInPictureRenderers = builder.buildOrThrow();
}
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/gui/screens/LoadingOverlay.java
+++ b/net/minecraft/client/gui/screens/LoadingOverlay.java
@@ -61,6 +_,8 @@
@@ -62,6 +_,8 @@
return p_169325_ & 16777215 | p_169326_ << 24;
}
@@ -9,17 +9,17 @@
@Override
public void render(GuiGraphics p_281839_, int p_282704_, int p_283650_, float p_283394_) {
int i = p_281839_.guiWidth();
@@ -97,6 +_,7 @@
@@ -100,6 +_,7 @@
f2 = 1.0F;
}
+ if (renderContents(p_281839_, f2)) {
int l2 = (int)(p_281839_.guiWidth() * 0.5);
int i1 = (int)(p_281839_.guiHeight() * 0.5);
double d0 = Math.min(p_281839_.guiWidth() * 0.75, (double)p_281839_.guiHeight()) * 0.25;
@@ -112,12 +_,14 @@
int k2 = (int)((double)p_281839_.guiWidth() * 0.5);
int l2 = (int)((double)p_281839_.guiHeight() * 0.5);
double d1 = Math.min((double)p_281839_.guiWidth() * 0.75, (double)p_281839_.guiHeight()) * 0.25;
@@ -115,12 +_,14 @@
if (f < 1.0F) {
this.drawProgressBar(p_281839_, i / 2 - k1, i2 - 5, i / 2 + k1, i2 + 5, 1.0F - Mth.clamp(f, 0.0F, 1.0F));
this.drawProgressBar(p_281839_, i / 2 - j1, l1 - 5, i / 2 + j1, l1 + 5, 1.0F - Mth.clamp(f, 0.0F, 1.0F));
}
+ }
@@ -32,7 +32,7 @@
try {
this.reload.checkExceptions();
this.onFinish.accept(Optional.empty());
@@ -125,7 +_,6 @@
@@ -128,7 +_,6 @@
this.onFinish.accept(Optional.of(throwable));
}
@@ -1,10 +1,10 @@
--- a/net/minecraft/client/gui/screens/PauseScreen.java
+++ b/net/minecraft/client/gui/screens/PauseScreen.java
@@ -105,6 +_,7 @@
@@ -95,6 +_,7 @@
} else {
gridlayout$rowhelper.addChild(this.openScreenButton(PLAYER_REPORTING, () -> new SocialInteractionsScreen(this)));
}
+ gridlayout$rowhelper.addChild(Button.builder(Component.translatable("fml.menu.mods"), button -> this.minecraft.setScreen(new net.minecraftforge.client.gui.ModListScreen(this))).width(BUTTON_WIDTH_FULL).build(), 2);
this.disconnectButton = gridlayout$rowhelper.addChild(Button.builder(CommonComponents.disconnectButtonLabel(this.minecraft.isLocalServer()), p_280815_ -> {
p_280815_.active = false;
Component component = this.minecraft.isLocalServer() ? RETURN_TO_MENU : CommonComponents.GUI_DISCONNECT;
this.disconnectButton = gridlayout$rowhelper.addChild(Button.builder(component, p_280815_ -> {
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/gui/screens/Screen.java
+++ b/net/minecraft/client/gui/screens/Screen.java
@@ -191,7 +_,7 @@
@@ -200,7 +_,7 @@
}
public void onClose() {
@@ -9,37 +9,37 @@
}
protected <T extends GuiEventListener & Renderable & NarratableEntry> T addRenderableWidget(T p_169406_) {
@@ -339,8 +_,10 @@
@@ -311,8 +_,10 @@
this.width = p_96608_;
this.height = p_96609_;
if (!this.initialized) {
+ if (!net.minecraftforge.client.event.ScreenEvent.Init.Pre.BUS.post(new net.minecraftforge.client.event.ScreenEvent.Init.Pre(this, this.children, this::addEventWidget, this::removeWidget)))
+ if (!net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.ScreenEvent.Init.Pre(this, this.children, this::addEventWidget, this::removeWidget)))
this.init();
this.setInitialFocus();
+ net.minecraftforge.client.event.ScreenEvent.Init.Post.BUS.post(new net.minecraftforge.client.event.ScreenEvent.Init.Post(this, this.children, this::addEventWidget, this::removeWidget));
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.ScreenEvent.Init.Post(this, this.children, this::addEventWidget, this::removeWidget));
} else {
this.repositionElements();
}
@@ -353,8 +_,10 @@
@@ -325,8 +_,10 @@
protected void rebuildWidgets() {
this.clearWidgets();
this.clearFocus();
+ if (!net.minecraftforge.client.event.ScreenEvent.Init.Pre.BUS.post(new net.minecraftforge.client.event.ScreenEvent.Init.Pre(this, this.children, this::addEventWidget, this::removeWidget)))
+ if (!net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.ScreenEvent.Init.Pre(this, this.children, this::addEventWidget, this::removeWidget)))
this.init();
this.setInitialFocus();
+ net.minecraftforge.client.event.ScreenEvent.Init.Post.BUS.post(new net.minecraftforge.client.event.ScreenEvent.Init.Post(this, this.children, this::addEventWidget, this::removeWidget));
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.ScreenEvent.Init.Post(this, this.children, this::addEventWidget, this::removeWidget));
}
protected void fadeWidgets(float p_409453_) {
@@ -389,6 +_,7 @@
@Override
@@ -353,6 +_,7 @@
this.renderBlurredBackground(p_283688_);
this.renderBlurredBackground();
this.renderMenuBackground(p_283688_);
+ net.minecraftforge.client.event.ForgeEventFactoryClient.onRenderScreenBackground(this, p_283688_);
}
protected void renderBlurredBackground(GuiGraphics p_407253_) {
@@ -492,6 +_,19 @@
protected void renderBlurredBackground() {
@@ -454,6 +_,19 @@
}
public void onFilesDrop(List<Path> p_96591_) {
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/gui/screens/TitleScreen.java
+++ b/net/minecraft/client/gui/screens/TitleScreen.java
@@ -54,6 +_,7 @@
@@ -60,6 +_,7 @@
private boolean fading;
private long fadeInStart;
private final LogoRenderer logoRenderer;
@@ -8,7 +8,7 @@
public TitleScreen() {
this(false);
@@ -106,11 +_,15 @@
@@ -115,11 +_,15 @@
int j = this.width - i - 2;
int k = 24;
int l = this.height / 4 + 48;
@@ -24,7 +24,7 @@
l = this.createTestWorldButton(l, 24);
SpriteIconButton spriteiconbutton = this.addRenderableWidget(
@@ -175,7 +_,7 @@
@@ -184,7 +_,7 @@
}).bounds(this.width / 2 - 100, i = p_96764_ + p_96765_, 200, 20).tooltip(tooltip).build()).active = flag;
this.addRenderableWidget(
Button.builder(Component.translatable("menu.online"), p_325369_ -> this.minecraft.setScreen(new RealmsMainScreen(this)))
@@ -33,22 +33,30 @@
.tooltip(tooltip)
.build()
)
@@ -295,9 +_,18 @@
s = s + I18n.get("menu.modded");
}
@@ -293,6 +_,7 @@
if ((i & -67108864) != 0) {
super.render(p_282860_, p_281753_, p_283539_, p_282628_);
this.logoRenderer.renderLogo(p_282860_, this.width, f);
+ net.minecraftforge.client.ForgeHooksClient.renderMainMenu(this, p_282860_, this.font, this.width, this.height, i);
if (this.splash != null && !this.minecraft.options.hideSplashTexts().get()) {
this.splash.render(p_282860_, this.width, this.font, i);
}
@@ -308,10 +_,18 @@
s = s + I18n.get("menu.modded");
}
- p_282860_.drawString(this.font, s, 2, this.height - 10, ARGB.color(f, -1));
+ final float f_f = f;
+ net.minecraftforge.internal.BrandingControl.forEachLine(true, true, (brd, brdline) ->
+ p_282860_.drawString(this.font, brd, 2, this.height - ( 10 + brdline * (this.font.lineHeight + 1)), ARGB.color(f_f, -1))
+ );
- p_282860_.drawString(this.font, s, 2, this.height - 10, 16777215 | i);
+ net.minecraftforge.internal.BrandingControl.forEachLine(true, true, (brd, brdline) ->
+ p_282860_.drawString(this.font, brd, 2, this.height - ( 10 + brdline * (this.font.lineHeight + 1)), 16777215 | i)
+ );
+
+ net.minecraftforge.internal.BrandingControl.forEachAboveCopyrightLine((brd, brdline) ->
+ p_282860_.drawString(this.font, brd, this.width - font.width(brd), this.height - (10 + (brdline + 1) * ( this.font.lineHeight + 1)), ARGB.color(f_f, -1))
+ );
+ net.minecraftforge.internal.BrandingControl.forEachAboveCopyrightLine((brd, brdline) ->
+ p_282860_.drawString(this.font, brd, this.width - font.width(brd), this.height - (10 + (brdline + 1) * ( this.font.lineHeight + 1)), 16777215 | i)
+ );
+
if (this.realmsNotificationsEnabled() && f >= 1.0F) {
this.realmsNotificationsScreen.render(p_282860_, p_281753_, p_283539_, p_282628_);
if (this.realmsNotificationsEnabled() && f >= 1.0F) {
this.realmsNotificationsScreen.render(p_282860_, p_281753_, p_283539_, p_282628_);
}
+ if (f >= 1.0f) this.modUpdateNotification.render(p_282860_, p_281753_, p_283539_, p_282628_);
}
}
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/gui/screens/advancements/AdvancementTab.java
+++ b/net/minecraft/client/gui/screens/advancements/AdvancementTab.java
@@ -39,6 +_,7 @@
@@ -38,6 +_,7 @@
private int maxY = Integer.MIN_VALUE;
private float fade;
private boolean centered;
@@ -8,7 +8,7 @@
public AdvancementTab(
Minecraft p_97145_, AdvancementsScreen p_97146_, AdvancementTabType p_97147_, int p_97148_, AdvancementNode p_297568_, DisplayInfo p_97150_
@@ -55,6 +_,15 @@
@@ -54,6 +_,15 @@
this.addWidget(this.root, p_297568_.holder());
}
@@ -24,7 +24,7 @@
public AdvancementTabType getType() {
return this.type;
}
@@ -145,8 +_,8 @@
@@ -147,8 +_,8 @@
return null;
} else {
for (AdvancementTabType advancementtabtype : AdvancementTabType.values()) {
@@ -37,8 +37,8 @@
this.advancements.setSelectedTab(advancementtab.getRootNode().holder(), true);
break;
}
@@ -183,10 +_,12 @@
p_283395_.blit(RenderPipelines.GUI_TEXTURED, WINDOW_LOCATION, p_281890_, p_282532_, 0.0F, 0.0F, 252, 140, 256, 256);
@@ -181,10 +_,12 @@
p_283395_.blit(RenderType::guiTextured, WINDOW_LOCATION, p_281890_, p_282532_, 0.0F, 0.0F, 252, 140, 256, 256);
if (this.tabs.size() > 1) {
for (AdvancementTab advancementtab : this.tabs.values()) {
+ if (advancementtab.getPage() == tabPage)
@@ -50,11 +50,11 @@
advancementtab1.drawIcon(p_283395_, p_281890_, p_282532_);
}
}
@@ -205,6 +_,7 @@
@@ -202,6 +_,7 @@
if (this.tabs.size() > 1) {
for (AdvancementTab advancementtab : this.tabs.values()) {
+ if (advancementtab.getPage() == tabPage)
if (advancementtab.isMouseOver(p_281519_, p_283371_, p_283556_, p_282458_)) {
p_282784_.setTooltipForNextFrame(this.font, advancementtab.getTitle(), p_283556_, p_282458_);
if (advancementtab.isMouseOver(p_281519_, p_283371_, (double)p_283556_, (double)p_282458_)) {
p_282784_.renderTooltip(this.font, advancementtab.getTitle(), p_283556_, p_282458_);
}
@@ -1,52 +1,52 @@
--- a/net/minecraft/client/gui/screens/inventory/AbstractContainerScreen.java
+++ b/net/minecraft/client/gui/screens/inventory/AbstractContainerScreen.java
@@ -107,6 +_,7 @@
@@ -108,6 +_,7 @@
int i = this.leftPos;
int j = this.topPos;
super.render(p_409971_, p_409213_, p_408205_, p_408282_);
+ net.minecraftforge.client.event.ForgeEventFactoryClient.onContainerRenderBackground(this, p_409971_, p_409213_, p_408205_);
p_409971_.pose().pushMatrix();
p_409971_.pose().translate(i, j);
this.renderLabels(p_409971_, p_409213_, p_408205_);
super.render(p_283479_, p_283661_, p_281248_, p_281886_);
+ net.minecraftforge.client.event.ForgeEventFactoryClient.onContainerRenderBackground(this, p_283479_, p_283661_, p_281248_);
p_283479_.pose().pushPose();
p_283479_.pose().translate((float)i, (float)j, 0.0F);
Slot slot = this.hoveredSlot;
@@ -119,6 +_,8 @@
this.onStopHovering(slot);
}
+ net.minecraftforge.client.event.ForgeEventFactoryClient.onContainerRenderForeground(this, p_409971_, p_409213_, p_408205_);
+ net.minecraftforge.client.event.ForgeEventFactoryClient.onContainerRenderForeground(this, p_283479_, p_283661_, p_281248_);
+
p_409971_.pose().popMatrix();
}
@@ -202,7 +_,7 @@
this.renderLabels(p_283479_, p_283661_, p_281248_);
ItemStack itemstack = this.draggingItem.isEmpty() ? this.menu.getCarried() : this.draggingItem;
if (!itemstack.isEmpty()) {
@@ -199,7 +_,7 @@
ItemStack itemstack = this.hoveredSlot.getItem();
if (this.menu.getCarried().isEmpty() || this.showTooltipWithItemInHand(itemstack)) {
p_283594_.setTooltipForNextFrame(
p_283594_.renderTooltip(
- this.font, this.getTooltipFromContainerItem(itemstack), itemstack.getTooltipImage(), p_282171_, p_281909_, itemstack.get(DataComponents.TOOLTIP_STYLE)
+ this.font, this.getTooltipFromContainerItem(itemstack), itemstack.getTooltipImage(), itemstack, p_282171_, p_281909_
);
}
}
@@ -218,7 +_,8 @@
private void renderFloatingItem(GuiGraphics p_282567_, ItemStack p_281330_, int p_281772_, int p_281689_, @Nullable String p_282568_) {
@@ -217,7 +_,8 @@
p_282567_.pose().pushPose();
p_282567_.pose().translate(0.0F, 0.0F, 232.0F);
p_282567_.renderItem(p_281330_, p_281772_, p_281689_);
- p_282567_.renderItemDecorations(this.font, p_281330_, p_281772_, p_281689_ - (this.draggingItem.isEmpty() ? 0 : 8), p_282568_);
+ var font = net.minecraftforge.client.extensions.common.IClientItemExtensions.of(p_281330_).getFont(p_281330_, net.minecraftforge.client.extensions.common.IClientItemExtensions.FontContext.ITEM_COUNT);
+ p_282567_.renderItemDecorations(font == null ? this.font : font, p_281330_, p_281772_, p_281689_ - (this.draggingItem.isEmpty() ? 0 : 8), p_282568_);
p_282567_.pose().popPose();
}
protected void renderLabels(GuiGraphics p_281635_, int p_282681_, int p_283686_) {
@@ -319,7 +_,8 @@
@@ -324,7 +_,8 @@
if (super.mouseClicked(p_97748_, p_97749_, p_97750_)) {
return true;
} else {
- boolean flag = this.minecraft.options.keyPickItem.matchesMouse(p_97750_) && this.minecraft.player.hasInfiniteMaterials();
- boolean flag = this.minecraft.options.keyPickItem.matchesMouse(p_97750_) && this.minecraft.gameMode.hasInfiniteItems();
+ InputConstants.Key mouseKey = InputConstants.Type.MOUSE.getOrCreate(p_97750_);
+ boolean flag = this.minecraft.options.keyPickItem.isActiveAndMatches(mouseKey);
Slot slot = this.getHoveredSlot(p_97748_, p_97749_);
long i = Util.getMillis();
this.doubleclick = this.lastClickSlot == slot && i - this.lastClickTime < 250L && this.lastClickButton == p_97750_;
@@ -330,6 +_,7 @@
@@ -335,6 +_,7 @@
int j = this.leftPos;
int k = this.topPos;
boolean flag1 = this.hasClickedOutside(p_97748_, p_97749_, j, k, p_97750_);
@@ -54,7 +54,7 @@
int l = -1;
if (slot != null) {
l = slot.index;
@@ -355,7 +_,7 @@
@@ -360,7 +_,7 @@
}
} else if (!this.isQuickCrafting) {
if (this.menu.getCarried().isEmpty()) {
@@ -63,7 +63,7 @@
this.slotClicked(slot, l, p_97750_, ClickType.CLONE);
} else {
boolean flag2 = l != -999
@@ -383,7 +_,7 @@
@@ -388,7 +_,7 @@
this.quickCraftingType = 0;
} else if (p_97750_ == 1) {
this.quickCraftingType = 1;
@@ -72,7 +72,7 @@
this.quickCraftingType = 2;
}
}
@@ -459,10 +_,13 @@
@@ -467,10 +_,13 @@
@Override
public boolean mouseReleased(double p_97812_, double p_97813_, int p_97814_) {
@@ -86,7 +86,7 @@
int k = -1;
if (slot != null) {
k = slot.index;
@@ -479,7 +_,7 @@
@@ -487,7 +_,7 @@
if (slot2 != null
&& slot2.mayPickup(this.minecraft.player)
&& slot2.hasItem()
@@ -95,7 +95,7 @@
&& AbstractContainerMenu.canItemQuickReplace(slot2, this.lastQuickMoved, true)) {
this.slotClicked(slot2, slot2.index, p_97814_, ClickType.QUICK_MOVE);
}
@@ -545,7 +_,7 @@
@@ -551,7 +_,7 @@
this.slotClicked(null, -999, AbstractContainerMenu.getQuickcraftMask(2, this.quickCraftingType), ClickType.QUICK_CRAFT);
} else if (!this.menu.getCarried().isEmpty()) {
@@ -104,7 +104,7 @@
this.slotClicked(slot, k, p_97814_, ClickType.CLONE);
} else {
boolean flag1 = k != -999
@@ -622,9 +_,10 @@
@@ -631,9 +_,10 @@
@Override
public boolean keyPressed(int p_97765_, int p_97766_, int p_97767_) {
@@ -116,7 +116,7 @@
this.onClose();
return true;
} else {
@@ -698,6 +_,13 @@
@@ -707,4 +_,11 @@
super.onClose();
}
@@ -127,6 +127,4 @@
+ public int getGuiTop() { return topPos; }
+ public int getXSize() { return imageWidth; }
+ public int getYSize() { return imageHeight; }
@OnlyIn(Dist.CLIENT)
record SnapbackData(ItemStack item, Vector2i start, Vector2i end, long time) {
}
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java
+++ b/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java
@@ -113,6 +_,8 @@
@@ -115,6 +_,8 @@
private final Set<TagKey<Item>> visibleTags = new HashSet<>();
private final boolean displayOperatorCreativeTab;
private final EffectsInInventory effects;
@@ -9,7 +9,7 @@
public CreativeModeInventoryScreen(LocalPlayer p_344408_, FeatureFlagSet p_260074_, boolean p_259569_) {
super(new CreativeModeInventoryScreen.ItemPickerMenu(p_344408_), p_344408_.getInventory(), CommonComponents.EMPTY);
@@ -161,7 +_,7 @@
@@ -163,7 +_,7 @@
private void refreshCurrentTabContents(Collection<ItemStack> p_261591_) {
int i = this.menu.getRowIndexForScroll(this.scrollOffs);
this.menu.items.clear();
@@ -18,9 +18,9 @@
this.refreshSearchResults();
} else {
this.menu.items.addAll(p_261591_);
@@ -329,6 +_,35 @@
@@ -331,6 +_,35 @@
protected void init() {
if (this.minecraft.player.hasInfiniteMaterials()) {
if (this.minecraft.gameMode.hasInfiniteItems()) {
super.init();
+ this.pages.clear();
+ int tabIndex = 0;
@@ -54,7 +54,7 @@
this.searchBox = new EditBox(this.font, this.leftPos + 82, this.topPos + 6, 80, 9, Component.translatable("itemGroup.search"));
this.searchBox.setMaxLength(50);
this.searchBox.setBordered(false);
@@ -375,7 +_,7 @@
@@ -377,7 +_,7 @@
public boolean charTyped(char p_98521_, int p_98522_) {
if (this.ignoreTextInput) {
return false;
@@ -63,7 +63,7 @@
return false;
} else {
String s = this.searchBox.getValue();
@@ -394,7 +_,7 @@
@@ -396,7 +_,7 @@
@Override
public boolean keyPressed(int p_98547_, int p_98548_, int p_98549_) {
this.ignoreTextInput = false;
@@ -72,7 +72,7 @@
if (this.minecraft.options.keyChat.matches(p_98547_, p_98548_)) {
this.ignoreTextInput = true;
this.selectTab(CreativeModeTabs.searchTab());
@@ -430,6 +_,7 @@
@@ -432,6 +_,7 @@
}
private void refreshSearchResults() {
@@ -80,7 +80,7 @@
this.menu.items.clear();
this.visibleTags.clear();
String s = this.searchBox.getValue();
@@ -442,10 +_,10 @@
@@ -444,10 +_,10 @@
SearchTree<ItemStack> searchtree;
if (s.startsWith("#")) {
s = s.substring(1);
@@ -93,27 +93,27 @@
}
this.menu.items.addAll(searchtree.search(s.toLowerCase(Locale.ROOT)));
@@ -477,7 +_,8 @@
@@ -479,7 +_,8 @@
@Override
protected void renderLabels(GuiGraphics p_283168_, int p_281774_, int p_281466_) {
if (selectedTab.showTitle()) {
- p_283168_.drawString(this.font, selectedTab.getDisplayName(), 8, 6, -12566464, false);
+ com.mojang.blaze3d.opengl.GlStateManager._disableBlend();
- p_283168_.drawString(this.font, selectedTab.getDisplayName(), 8, 6, 4210752, false);
+ com.mojang.blaze3d.systems.RenderSystem.disableBlend();
+ p_283168_.drawString(this.font, selectedTab.getDisplayName(), 8, 6, selectedTab.getLabelColor(), false);
}
}
@@ -487,7 +_,7 @@
double d0 = p_98531_ - this.leftPos;
double d1 = p_98532_ - this.topPos;
@@ -489,7 +_,7 @@
double d0 = p_98531_ - (double)this.leftPos;
double d1 = p_98532_ - (double)this.topPos;
- for (CreativeModeTab creativemodetab : CreativeModeTabs.tabs()) {
+ for (CreativeModeTab creativemodetab : currentPage.getVisibleTabs()) {
if (this.checkTabClicked(creativemodetab, d0, d1)) {
return true;
}
@@ -509,7 +_,7 @@
double d1 = p_98623_ - this.topPos;
@@ -511,7 +_,7 @@
double d1 = p_98623_ - (double)this.topPos;
this.scrolling = false;
- for (CreativeModeTab creativemodetab : CreativeModeTabs.tabs()) {
@@ -121,7 +121,7 @@
if (this.checkTabClicked(creativemodetab, d0, d1)) {
this.selectTab(creativemodetab);
return true;
@@ -603,13 +_,15 @@
@@ -605,13 +_,15 @@
this.originalSlots = null;
}
@@ -138,23 +138,32 @@
this.refreshSearchResults();
} else {
@@ -673,7 +_,14 @@
@@ -677,7 +_,15 @@
super.render(p_283000_, p_281317_, p_282770_, p_281295_);
this.effects.renderTooltip(p_283000_, p_281317_, p_282770_);
this.effects.render(p_283000_, p_281317_, p_282770_, p_281295_);
- for (CreativeModeTab creativemodetab : CreativeModeTabs.tabs()) {
+ if (this.pages.size() != 1) {
+ Component page = Component.literal(String.format("%d / %d", this.pages.indexOf(this.currentPage) + 1, this.pages.size()));
+ p_283000_.pose().pushMatrix();
+ p_283000_.pose().pushPose();
+ p_283000_.pose().translate(0F, 0F, 300F);
+ p_283000_.drawString(font, page.getVisualOrderText(), leftPos + (imageWidth / 2) - (font.width(page) / 2), topPos - 44, -1);
+ p_283000_.pose().popMatrix();
+ p_283000_.pose().popPose();
+ }
+
+ for (CreativeModeTab creativemodetab : currentPage.getVisibleTabs()) {
if (this.checkTabHovering(p_283000_, creativemodetab, p_281317_, p_282770_)) {
break;
}
@@ -697,7 +_,7 @@
@@ -689,6 +_,7 @@
p_283000_.renderTooltip(this.font, TRASH_SLOT_TOOLTIP, p_281317_, p_282770_);
}
+ com.mojang.blaze3d.systems.RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
this.renderTooltip(p_283000_, p_281317_, p_282770_);
}
@@ -701,7 +_,7 @@
public List<Component> getTooltipFromContainerItem(ItemStack p_281769_) {
boolean flag = this.hoveredSlot != null && this.hoveredSlot instanceof CreativeModeInventoryScreen.CustomCreativeSlot;
boolean flag1 = selectedTab.getType() == CreativeModeTab.Type.CATEGORY;
@@ -163,7 +172,7 @@
TooltipFlag.Default tooltipflag$default = this.minecraft.options.advancedItemTooltips ? TooltipFlag.Default.ADVANCED : TooltipFlag.Default.NORMAL;
TooltipFlag tooltipflag = flag ? tooltipflag$default.asCreative() : tooltipflag$default;
List<Component> list = p_281769_.getTooltipLines(Item.TooltipContext.of(this.minecraft.level), this.minecraft.player, tooltipflag);
@@ -718,7 +_,7 @@
@@ -720,7 +_,7 @@
int i = 1;
for (CreativeModeTab creativemodetab : CreativeModeTabs.tabs()) {
@@ -172,7 +181,7 @@
list1.add(i++, creativemodetab.getDisplayName().copy().withStyle(ChatFormatting.BLUE));
}
}
@@ -729,7 +_,7 @@
@@ -731,7 +_,7 @@
@Override
protected void renderBg(GuiGraphics p_282663_, float p_282504_, int p_282089_, int p_282249_) {
@@ -181,15 +190,15 @@
if (creativemodetab != selectedTab) {
this.renderTabButton(p_282663_, creativemodetab);
}
@@ -745,6 +_,7 @@
p_282663_.blitSprite(RenderPipelines.GUI_TEXTURED, resourcelocation, j, k + (int)((i - k - 17) * this.scrollOffs), 12, 15);
@@ -747,6 +_,7 @@
p_282663_.blitSprite(RenderType::guiTextured, resourcelocation, j, k + (int)((float)(i - k - 17) * this.scrollOffs), 12, 15);
}
+ if (currentPage.getVisibleTabs().contains(selectedTab)) //Forge: only display tab selection when the selected tab is on the current page
this.renderTabButton(p_282663_, selectedTab);
if (selectedTab.getType() == CreativeModeTab.Type.INVENTORY) {
InventoryScreen.renderEntityInInventoryFollowsMouse(
@@ -763,7 +_,7 @@
@@ -765,7 +_,7 @@
}
private int getTabX(CreativeModeTab p_260136_) {
@@ -198,7 +207,7 @@
int j = 27;
int k = 27 * i;
if (p_260136_.isAlignedRight()) {
@@ -775,7 +_,7 @@
@@ -777,7 +_,7 @@
private int getTabY(CreativeModeTab p_260181_) {
int i = 0;
@@ -207,7 +216,7 @@
i -= 32;
} else {
i += this.imageHeight;
@@ -803,8 +_,8 @@
@@ -805,8 +_,8 @@
protected void renderTabButton(GuiGraphics p_283590_, CreativeModeTab p_283489_) {
boolean flag = p_283489_ == selectedTab;
@@ -218,15 +227,15 @@
int j = this.leftPos + this.getTabX(p_283489_);
int k = this.topPos - (flag1 ? 28 : -(this.imageHeight - 4));
ResourceLocation[] aresourcelocation;
@@ -814,6 +_,7 @@
@@ -816,6 +_,7 @@
aresourcelocation = flag ? SELECTED_BOTTOM_TABS : UNSELECTED_BOTTOM_TABS;
}
+ com.mojang.blaze3d.opengl.GlStateManager._enableBlend(); //Forge: Make sure blend is enabled else tabs show a white border.
p_283590_.blitSprite(RenderPipelines.GUI_TEXTURED, aresourcelocation[Mth.clamp(i, 0, aresourcelocation.length)], j, k, 26, 32);
int l = j + 13 - 8;
int i1 = k + 16 - 8 + (flag1 ? 1 : -1);
@@ -850,6 +_,14 @@
+ com.mojang.blaze3d.systems.RenderSystem.enableBlend(); //Forge: Make sure blend is enabled else tabs show a white border.
p_283590_.blitSprite(RenderType::guiTextured, aresourcelocation[Mth.clamp(i, 0, aresourcelocation.length)], j, k, 26, 32);
p_283590_.pose().pushPose();
p_283590_.pose().translate(0.0F, 0.0F, 100.0F);
@@ -857,6 +_,14 @@
}
}
@@ -241,7 +250,7 @@
@OnlyIn(Dist.CLIENT)
static class CustomCreativeSlot extends Slot {
public CustomCreativeSlot(Container p_98633_, int p_98634_, int p_98635_, int p_98636_) {
@@ -1031,6 +_,22 @@
@@ -1038,6 +_,22 @@
@Override
public boolean mayPickup(Player p_98665_) {
return this.target.mayPickup(p_98665_);
@@ -258,8 +267,8 @@
+ }
+
+ @Override
+ public Slot setBackground(ResourceLocation sprite) {
+ this.target.setBackground(sprite);
+ public Slot setBackground(ResourceLocation atlas, ResourceLocation sprite) {
+ this.target.setBackground(atlas, sprite);
+ return this;
}
}
Loaded 100 of 1170 files, more files were not shown because too many files have changed in this diff. Show more