Compare commits

...
67 Commits
Author SHA1 Message Date
LexManos 064ae6961b New 1.16.5 RB. 2021-07-21 18:25:45 -07:00
SizableShrimp 22d609ed6c ForgeGradle 5.1 and Gradle 7, which allows development on J16. Runtime still targets J8. (#7877) 2021-07-21 14:21:09 -07:00
LexManos 315bbb74ff Work around javac scoping issue. 2021-07-19 21:55:46 -07:00
LexManos 4e4d31b68c Fix LAN worlds where registry entries have been removed. 2021-07-19 21:15:26 -07:00
William Bradford Larcombe 1a17fa6129 Fix FakePlayers having null connection and add FakePlayer test mod (#7733) 2021-07-19 12:54:42 -07:00
AterAnimAvis ca9df21258 Use '{assets_root}' rather than task output path for userdev config (#7873)
Signed-off-by: AterAnimAvis <[email protected]>
2021-07-17 18:23:30 +02:00
Silk 93d7fa54fc Fix missing userdev config for datagen runs (#7871)
Signed-off-by: TheSilkMiner <[email protected]>
2021-07-17 13:14:38 +02:00
Bailey Hollingsworth f235d80d9f Adds a damage float in Lightning Entity and patches Entity to use it. (#7849) 2021-07-16 20:12:40 -07:00
Mike Garay be34dd89a9 Patch several mob classes to let them use modded versions of their ranged weapons (#7845) 2021-07-16 20:12:33 -07:00
AwesomeSyd239 6663f23e13 Add Fishing bobber projectile impact event (#7842) 2021-07-16 19:41:51 -07:00
OneLemonyBoi f9f7ef2580 Removes misapplied patch in Entity (#7841) 2021-07-16 19:38:56 -07:00
OneLemonyBoi 86352e9c19 Removes misleading Nullable annotation from canCreatureSpawn (#7840) 2021-07-16 19:38:06 -07:00
OneLemonyBoi 8c8b31435b Corrects the assigning of mob kills, Fixes MC-121048 (#7836) 2021-07-16 19:37:12 -07:00
OneLemonyBoi 16b3e2780e Updates MouseHelper to allow for Horizontal Scroll to be recognized as Vertical Scroll (#7834) 2021-07-16 19:31:14 -07:00
Take Weiland 1121f18413 Fix entities losing their scoreboard data when they are unloaded (#7826) 2021-07-16 19:24:29 -07:00
Take Weiland 96804fb4df [1.16] Allow blocks other than beds or respawn anchors to act as respawn points (#7824) 2021-07-16 19:23:36 -07:00
LexManos 03a6dbb405 Regen patches 2021-07-16 19:12:38 -07:00
Won-Ton 77e8c72589 Add AT entries for DimensionSettings to make them easier for mods to work with (#7817) 2021-07-16 18:03:56 -07:00
cech12 043e49a694 New hook to allow Trapdoors be climbable for custom ladders (#7816) 2021-07-16 18:01:27 -07:00
King Lemming 5169f1f6fe Convenience change for potion enumeration - does not change patch size in any meaningful way! (#7811) 2021-07-16 17:56:08 -07:00
Mike Garay 2bd83b26aa Adds knockback attribute to players and updated knockback calculation to PlayerEntity#attack (#7806) 2021-07-16 17:52:58 -07:00
Sekwah e6c1814122 Fix mod menu URL click bounds (#7804) 2021-07-16 17:51:11 -07:00
Daniel Houck 7f2892de7e Fix vanilla rotation/mirroring issues (#7803)
Patch minecraft to fix MC-227255 and MC-134110, which are block
rotation and mirroring issues.  I noticed this from problems with
Structurize, but this probably affects any other mods that allow
rotating or mirroring structures (as well as vanilla structure blocks).
2021-07-16 17:50:29 -07:00
PersonTheCat 439ba462d6 Synchronize ResourcePackList#addPackFinder (#7799) 2021-07-16 17:48:10 -07:00
mikewk 7c6ae3e61e Fixes tryFluidTransfer_Internal to respect the FluidStack drainable when draining fluidSource. (#7782) 2021-07-16 17:45:39 -07:00
Take Weiland f9b894ecbf Add IRecipeType parameter to burn time hooks (#7771) 2021-07-16 17:37:41 -07:00
Andy Dingley df53db351e Use MobGriefingEvent for PiglinEntity when determining whether Piglins want to pick up items. (#7762) 2021-07-16 17:35:24 -07:00
Andy Dingley 9aa04c8036 [1.16.x] Remove redundant mobgriefing check in SmallFireaballEntity. (#7761) 2021-07-16 17:33:59 -07:00
Queekusme 626496cec0 Changed AbstractFurnaceTileEntity's canBurn and burn functions to use IRecipe's 'assemble' instead of 'getResultItem' (#7756) 2021-07-16 17:33:02 -07:00
covers1624 022482a3bd Bypass chunk future chain when processing loads and getChunk called. (#7697) 2021-07-16 17:26:45 -07:00
DaemonUmbra dd228a9ac1 Removed sidedness from PacketBuffer methods. (#7236)
Affected methods:
* readLongArray (x2)
* readSectionPos
* readString (no-arg variant)
2021-07-16 17:25:11 -07:00
Silk a6d1646591 Add data generators for sounds.json (#6982) 2021-07-16 17:24:16 -07:00
Take Weiland 39f9f393db Add custom TextureAtlasSprite loaders (#7822)
Adds a system for mods to specify custom texture loaders which can be requested by the resource pack through a metadata section in the .mcmeta file. Due to technical reasons, png file is still required for MC to identify a texture as existing, even if the loader doesn't use it.
2021-07-16 01:55:43 +02:00
Commoble d35784eb14 Fix PlayerGameModeEventTest and ForgeWorldTypeTest so they don't crash the dedicated server when running forge_test_server in forgedev (#7869) 2021-07-15 16:40:07 -07:00
LexManos 31fb15c88d Add userdev to run config. 2021-07-13 18:15:54 -07:00
Take Weiland 29f175743b Add truncation to FMLStatusPing to work around protocol limits (#7818) 2021-06-16 19:23:20 -07:00
SizableShrimp 33499db93f Remove ModelResourceLocation patch for SAS entry (#7813) 2021-06-09 09:35:03 -07:00
Take Weiland 84381553a9 Fix jar file path detection if the path contains a "!" (#7790) 2021-06-08 13:26:01 -07:00
mrp-v2 2a7dde3d2e Add method to get the number of elements in a model builder (#7792) 2021-06-08 12:49:25 -07:00
Take Weiland aa4f24c915 Fix vanilla packet splitter remote detection and add advancement packet splitting (#7802) 2021-06-08 12:47:37 -07:00
Nightenom 1d87831773 Add option for linear filtering of text texture (#7645) 2021-06-08 21:33:31 +02:00
mrp-v2 65e99f9b58 Use empty model instead of missing model for non-existant layers in multilayer models (#7750)
Fixes issues when using multi-layer models as part of composite models
2021-06-08 21:07:33 +02:00
LexManos b98991dc70 Add debug logging to packet compression encoder.
Should make figuring out who is sending large packets easier.
Disable with -Pforge.disablePacketCompressionDebug=true
2021-06-03 10:29:49 -07:00
LexManos 435e65eb18 Removed signature line from mod list screen. #7500 2021-05-23 11:08:45 -07:00
Curle 8211a5048a Reinstate the MinecartCollisionHandler field to AbstractMinecartEntity (#7748) Closes #7506. 2021-05-17 13:51:23 -07:00
Curle 167f14f4a1 Fix PlayerEvent.BreakSpeed's pos being nullable. (#7747) Closes #7615. 2021-05-17 13:46:11 -07:00
Curle f332642409 Fix OBJ Loader data gen string (#7746) Closes #7616 2021-05-17 13:43:37 -07:00
noeppi_noeppi 77d41023b5 Add an event similar to PlayerEvent.NameFormat but for the name shown in the tab list. (#7740) 2021-05-17 13:17:01 -07:00
Curle da2594289c Fix filling buckets with fluids without bucket items consuming the fluid (#7745) Closes #7670 2021-05-17 13:10:27 -07:00
David Quintana 6f3da80b5a Work around crash while loading flatworld with modded structures. (#7764)
* Work around crash while loading flatworld with modded structures.

* Maybe fix issue with gradle daemon leaking memory and slowing down CI builds.
2021-05-14 00:11:46 +02:00
gigaherz 474b47ea51 Update Forge to Gradle 6.9 2021-05-12 23:33:33 +02:00
Trikzon b6ce4fb066 Add barrels and barrels/wooden block and item tag (#7676) 2021-04-30 10:53:19 -07:00
KnightMiner 1406f2bf1f Fix shears not properly breaking tripwire (MC-129055) (#7718) 2021-04-30 10:52:02 -07:00
JoJoModding 5125775992 Fix Line endings in tooltips not handled properly in multiplayer screen Closes #7738 (#7739) 2021-04-30 10:42:15 -07:00
Sydney 929c7b7a0b Fix cats, phantoms and pillagers saying they're at BlockPos.ZERO during LivingSpawnEvent.CheckSpawn (#7722) 2021-04-23 13:27:56 -07:00
mrp-v2 7bf02e7dcd [1.16] Add missing Multipart Blockstate Builder feature: Nested condition groups (#7677) 2021-04-22 22:55:18 -07:00
Dennis C 9d0d249eaf Pass BlockPos to BlockParticleData used for "fall impact" particle (#7705) 2021-04-22 22:53:58 -07:00
sciwhiz12 c4b1df1fc7 Check version ranges of optional dependencies when present (#7710)
If an optional dependency is present, but it does not conform to the version range,
it will now error out in the same fashion as missing required dependencies, instead
of a more cryptic error down the line due to a missing method/class/field/etc.

Implements and closes #7696
2021-04-22 22:52:24 -07:00
Take Weiland b3f253df61 Fix ClientVisualization crashing on systems without monitors (#7719) 2021-04-22 22:45:38 -07:00
atkarimarton dc099069fa Fix Furnace Minecarts going faster then vanilla (#7725) 2021-04-22 22:29:33 -07:00
AterAnimAvis e80c785563 Update for Forge's new maven (#7723) 2021-04-22 22:28:18 -07:00
cpw 1f9611204f A bloody quote FFS
Signed-off-by: cpw <[email protected]>
2021-04-18 11:35:05 -04:00
cpw 0120f6274d Update for new maven
Signed-off-by: cpw <[email protected]>
2021-04-18 11:28:54 -04:00
cpw c0e74bc8a8 Fix broken java9hacks for j16 handling..
Signed-off-by: cpw <[email protected]>
2021-04-02 14:27:25 -04:00
SizableShrimp 80feb0aeb2 Add generic EntityTeleportEvent (#7694) 2021-03-29 18:05:13 -07:00
covers1624 f47429717d Restore SS version, fixes findFieldInstanceChecks 2021-03-22 16:51:53 +10:30
Take Weiland 0239a736ec Fix sign textures being stitched onto every texture atlas (#7690) 2021-03-17 10:04:07 -07:00
160 changed files with 4643 additions and 857 deletions

No files matched your search

-2
View File
@@ -39,8 +39,6 @@ changelog.txt
*.7z
/logs/
gradle.properties
!/mdk/gradle.properties
/projects/forge/rejects/
# Srg2Source causes import bugs on these patches. If you intentionnally change these, remove the ignore.
Vendored
+17 -6
View File
@@ -36,9 +36,11 @@ pipeline {
}
stage('setup') {
steps {
sh './gradlew ${GRADLE_ARGS} --refresh-dependencies --continue setup'
withGradle {
sh './gradlew ${GRADLE_ARGS} --refresh-dependencies --continue setup'
}
script {
env.MYVERSION = sh(returnStdout: true, script: './gradlew :forge:properties -q | grep "version:" | awk \'{print $2}\'').trim()
env.MYVERSION = sh(returnStdout: true, script: './gradlew :forge:properties -q | grep "^version:" | cut -d" " -f2').trim()
}
}
}
@@ -59,15 +61,22 @@ pipeline {
}
}
environment {
FORGE_MAVEN = credentials('forge-maven-forge-user')
CROWDIN = credentials('forge-crowdin')
KEYSTORE = credentials('forge-jenkins-keystore-old')
KEYSTORE_KEYPASS = credentials('forge-jenkins-keystore-old-keypass')
KEYSTORE_STOREPASS = credentials('forge-jenkins-keystore-old-keypass')
}
steps {
sh './gradlew ${GRADLE_ARGS} :forge:publish -PforgeMavenUser=${FORGE_MAVEN_USR} -PforgeMavenPassword=${FORGE_MAVEN_PSW} -PkeystoreKeyPass=${KEYSTORE_KEYPASS} -PkeystoreStorePass=${KEYSTORE_STOREPASS} -Pkeystore=${KEYSTORE} -PcrowdinKey=${CROWDIN}'
sh 'curl --user ${FORGE_MAVEN} http://files.minecraftforge.net/maven/manage/promote/latest/net.minecraftforge.forge/${MYVERSION}'
withCredentials([usernamePassword(credentialsId: 'maven-forge-user', usernameVariable: 'MAVEN_USER', passwordVariable: 'MAVEN_PASSWORD')]) {
withGradle {
sh './gradlew ${GRADLE_ARGS} :forge:publish -PkeystoreKeyPass=${KEYSTORE_KEYPASS} -PkeystoreStorePass=${KEYSTORE_STOREPASS} -Pkeystore=${KEYSTORE} -PcrowdinKey=${CROWDIN}'
}
}
}
post {
success {
build job: 'filegenerator', parameters: [string(name: 'COMMAND', value: "promote net.minecraftforge:forge ${env.MYVERSION} latest")], propagate: false, wait: false
}
}
}
stage('test_publish_pr') { //Publish to local repo to test full process, but don't include credentials so it can't sign/publish to maven
@@ -78,7 +87,9 @@ pipeline {
CROWDIN = credentials('forge-crowdin')
}
steps {
sh './gradlew ${GRADLE_ARGS} :forge:publish -PcrowdinKey=${CROWDIN}'
withGradle {
sh './gradlew ${GRADLE_ARGS} :forge:publish -PcrowdinKey=${CROWDIN}'
}
}
}
}
+125 -81
View File
@@ -1,11 +1,11 @@
buildscript {
repositories {
mavenLocal()
maven { url = 'https://files.minecraftforge.net/maven' }
maven { url = 'https://maven.minecraftforge.net/' }
mavenCentral()
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:4.1.+'
classpath 'net.minecraftforge.gradle:ForgeGradle:5.1.+'
}
}
@@ -16,20 +16,21 @@ import java.util.Date
import java.util.LinkedHashMap
import net.minecraftforge.forge.tasks.*
import static net.minecraftforge.forge.tasks.Util.*
import net.minecraftforge.gradle.common.task.DownloadMavenArtifact
import net.minecraftforge.gradle.common.task.ExtractInheritance
import net.minecraftforge.gradle.common.task.SignJar
import net.minecraftforge.gradle.patcher.task.TaskReobfuscateJar
import net.minecraftforge.gradle.common.tasks.DownloadMavenArtifact
import net.minecraftforge.gradle.common.tasks.ExtractInheritance
import net.minecraftforge.gradle.common.tasks.SignJar
import net.minecraftforge.gradle.patcher.tasks.ReobfuscateJar
import org.apache.tools.ant.filters.ReplaceTokens
import org.gradle.plugins.ide.eclipse.model.SourceFolder
plugins {
id 'org.cadixdev.licenser' version '0.5.0'
id 'org.cadixdev.licenser' version '0.6.1'
id 'com.github.ben-manes.versions' version '0.36.0'
id 'net.minecraftforge.gradleutils' version '1.+'
id 'eclipse'
}
Util.init() //Init all our extension methods!
Util.init() //Init all our extension methods
println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch'))
@@ -55,7 +56,7 @@ project(':mcp') {
mavenLocal()
}
mcp {
config = MC_VERSION + '-' + MCP_VERSION
config MC_VERSION + '-' + MCP_VERSION
pipeline = 'joined'
}
}
@@ -182,30 +183,30 @@ project(':forge') {
}
ext {
GIT_INFO = Util.gitInfo(rootProject.file('.'))
GIT_INFO = gradleutils.gitInfo
SPEC_VERSION = GIT_INFO.tag
// The new versioning sceme is <MCVersion>-<ForgeMC>.<RB>.<CommitsSinceRB>
// ForgeMC is a unique identifier for every MC version we have supported.
// Essentially, the same as the old, except dropping the first number, and the builds are no longer unique.
MCP_ARTIFACT = project(':mcp').mcp.config
SPECIAL_SOURCE = 'net.md-5:SpecialSource:1.9.0'
SPECIAL_SOURCE_MCP = 'net.md-5:SpecialSource:1.8.3'
MCP_ARTIFACT = project(':mcp').mcp.config.get()
SPECIAL_SOURCE = 'net.md-5:SpecialSource:1.10.0'
SPECIAL_SOURCE_MCP = 'net.md-5:SpecialSource:1.8.5'
VERSION_JSON = project(':mcp').file('build/mcp/downloadJson/version.json')
BINPATCH_TOOL = 'net.minecraftforge:binarypatcher:1.0.12:fatjar'
INSTALLER_TOOLS = 'net.minecraftforge:installertools:1.1.11'
INSTALLER_TOOLS = 'net.minecraftforge:installertools:1.2.6'
}
version = Util.getVersion(GIT_INFO, MC_VERSION)
version = gradleutils.getMCTagOffsetBranchVersion(MC_VERSION)
println('Forge Version: ' + version)
patcher {
exc = file("$rootDir/src/main/resources/forge.exc")
excs.from file("$rootDir/src/main/resources/forge.exc")
parent = project(':clean')
patches = file("$rootDir/patches/minecraft")
patchedSrc = file('src/main/java')
srgPatches = true
accessTransformer = file("$rootDir/src/main/resources/META-INF/accesstransformer.cfg")
sideAnnotationStripper = file("$rootDir/src/main/resources/forge.sas")
accessTransformers.from file("$rootDir/src/main/resources/META-INF/accesstransformer.cfg")
sideAnnotationStrippers.from file("$rootDir/src/main/resources/forge.sas")
runs {
forge_client {
@@ -217,7 +218,7 @@ project(':forge') {
environment 'target', 'fmldevclient'
environment 'assetIndex', '{asset_index}'
environment 'assetDirectory', downloadAssets.output
environment 'nativesDirectory', extractNatives.output
environment 'nativesDirectory', extractNatives.output.get().asFile
environment 'MC_VERSION', MC_VERSION
environment 'MCP_VERSION', MCP_VERSION
@@ -231,7 +232,10 @@ project(':forge') {
ideaModule "${rootProject.name}.${project.name}.userdev"
mods {
forge { source sourceSets.main }
forge {
source sourceSets.main
source sourceSets.userdev
}
}
}
@@ -293,6 +297,8 @@ project(':forge') {
workingDirectory project.file('run')
environment 'target', 'fmldevdata'
environment 'assetIndex', '{asset_index}'
environment 'assetDirectory', downloadAssets.output
environment 'MC_VERSION', MC_VERSION
environment 'MCP_VERSION', MCP_VERSION
@@ -403,13 +409,13 @@ project(':forge') {
fmllauncherImplementation.extendsFrom(installer, implementation)
}
dependencies {
installer 'org.ow2.asm:asm:9.0'
installer 'org.ow2.asm:asm-commons:9.0'
installer 'org.ow2.asm:asm-tree:9.0'
installer 'org.ow2.asm:asm-util:9.0'
installer 'org.ow2.asm:asm-analysis:9.0'
installer 'org.ow2.asm:asm:9.1'
installer 'org.ow2.asm:asm-commons:9.1'
installer 'org.ow2.asm:asm-tree:9.1'
installer 'org.ow2.asm:asm-util:9.1'
installer 'org.ow2.asm:asm-analysis:9.1'
installer 'cpw.mods:modlauncher:8.0.9'
installer 'cpw.mods:grossjava9hacks:1.3.+'
installer 'cpw.mods:grossjava9hacks:1.3.3'
installer 'net.minecraftforge:accesstransformers:3.0.1'
installer 'org.antlr:antlr4-runtime:4.9.1' //Dep of AccessTransformer
installer 'net.minecraftforge:eventbus:4.0.+'
@@ -450,7 +456,7 @@ project(':forge') {
if (changelog.exists())
extraTxts += changelog
task crowdin(type: CrowdinTask) {
task crowdin(type: Crowdin) {
key = project.hasProperty('crowdinKey') ? project.crowdinKey : null
//TODO: Merge our english.json?
}
@@ -459,8 +465,8 @@ project(':forge') {
['Client', 'Server', 'Joined'].each { side ->
def gen = tasks.getByName("gen${side}BinPatches")
gen.tool = BINPATCH_TOOL
task "apply${side}BinPatches"(type: net.minecraftforge.gradle.common.task.ApplyBinPatches, dependsOn: gen) {
clean = { gen.cleanJar }
task "apply${side}BinPatches"(type: net.minecraftforge.gradle.common.tasks.ApplyBinPatches, dependsOn: gen) {
clean = gen.cleanJar
patch = gen.output
tool = BINPATCH_TOOL
}
@@ -470,21 +476,21 @@ project(':forge') {
task "create${side}SRG"(type: net.minecraftforge.gradle.userdev.tasks.RenameJar, dependsOn: srgTask) {
tool = SPECIAL_SOURCE_MCP + ':shaded'
args = ['--stable', '--in-jar', '{input}', '--out-jar', '{output}', '--srg-in', '{mappings}']
mappings = { srgTask.output }
input = { gen.cleanJar }
mappings = srgTask.output
input = gen.cleanJar
output = file("build/create${name}SRG/output.jar")
}
}
task downloadLibraries(type: DownloadLibrariesTask, dependsOn: ':mcp:setupMCP') {
task downloadLibraries(type: DownloadLibraries, dependsOn: ':mcp:setupMCP') {
input = VERSION_JSON
output = rootProject.file('build/libraries/')
}
task extractInheritance(type: ExtractInheritance, dependsOn: [genJoinedBinPatches, downloadLibraries]) {
tool = INSTALLER_TOOLS + ':fatjar'
input { genJoinedBinPatches.cleanJar }
doFirst { downloadLibraries.libraries.each{ addLibrary(it) } }
input = genJoinedBinPatches.cleanJar
libraries.addAll downloadLibraries.librariesOutput.map { rf -> Files.readAllLines(rf.asFile.toPath()).stream().map(File::new).collect(java.util.stream.Collectors.toList()) }
}
task findFieldInstanceChecks(type: FieldCompareFinder, dependsOn: ['createJoinedSRG']) {
@@ -523,40 +529,42 @@ project(':forge') {
}
}
task checkATs(type: CheckATs, dependsOn: extractInheritance) {
task checkATs(type: CheckATs, dependsOn: [extractInheritance, createSrg2Mcp]) {
inheritance = extractInheritance.output
ats = patcher.accessTransformers
ats.from patcher.accessTransformers
mappings = createSrg2Mcp.output
}
task checkSAS(type: CheckSAS, dependsOn: extractInheritance) {
inheritance = extractInheritance.output
sass = patcher.sideAnnotationStrippers
sass.from patcher.sideAnnotationStrippers
}
task checkExcs(type: CheckExcs, dependsOn: jar) {
binary = jar.archivePath
excs = patcher.excs
binary = jar.archiveFile
excs.from patcher.excs
}
task checkAll(dependsOn: [checkATs, checkSAS, checkExcs, findFieldInstanceChecks]){}
task checkPatchesAndFix(type: CheckPatches) {
task checkPatchesAndFix(type: CheckPatches, dependsOn: genPatches) {
patchDir = file("$rootDir/patches")
autoFix = true
}
task checkPatches(type: CheckPatches) {
task checkPatches(type: CheckPatches, dependsOn: genPatches) {
patchDir = file("$rootDir/patches")
autoFix = false
}
genPatches {
finalizedBy checkPatches
autoHeader true
lineEnding = '\n'
}
task launcherJson(dependsOn: ['signUniversalJar', 'signLauncherJar']) {
inputs.file universalJar.archivePath
inputs.file { launcherJar.archivePath }
inputs.file universalJar.archiveFile
inputs.file { launcherJar.archiveFile }
ext {
output = file('build/version.json')
vanilla = project(':mcp').file('build/mcp/downloadJson/version.json')
@@ -583,7 +591,18 @@ project(':forge') {
inheritsFrom: MC_VERSION,
logging: {},
arguments: [
game: ['--launchTarget', 'fmlclient', '--fml.forgeVersion', "${project.version.substring(MC_VERSION.length() + 1)}", '--fml.mcVersion', "${MC_VERSION}", '--fml.forgeGroup', "${project.group}", '--fml.mcpVersion', "${MCP_VERSION}"]
game: ['--launchTarget', 'fmlclient', '--fml.forgeVersion', "${project.version.substring(MC_VERSION.length() + 1)}", '--fml.mcVersion', "${MC_VERSION}", '--fml.forgeGroup', "${project.group}", '--fml.mcpVersion', "${MCP_VERSION}"],
// Support running with Java 8 and up, including 16
jvm: [
// Allow these JVM args to not crash Java 8
'-XX:+IgnoreUnrecognizedVMOptions',
// ModLauncher uses sun.security.util.ManifestEntryVerifier and needs access to it
'--add-exports=java.base/sun.security.util=ALL-UNNAMED',
// JDK bug, not fixed properly - https://bugs.openjdk.java.net/browse/JDK-8186019
'--add-exports=jdk.naming.dns/com.sun.jndi.dns=java.naming',
// ModLauncher reflects field 'jv' in java.util.jar.JarVerifier
'--add-opens=java.base/java.util.jar=ALL-UNNAMED'
]
],
libraries: [
[
@@ -593,8 +612,8 @@ project(':forge') {
artifact: [
path: "${project.group.replace('.', '/')}/${project.name}/${project.version}/${project.name}-${project.version}.jar",
url: "", //Do not include the URL so that the installer/launcher won't grab it. This is also why we don't have the universal classifier
sha1: launcherJar.archivePath.sha1(),
size: launcherJar.archivePath.length()
sha1: launcherJar.archiveFile.get().asFile.sha1(),
size: launcherJar.archiveFile.get().asFile.length()
]
]
]
@@ -613,7 +632,7 @@ project(':forge') {
task installerJson(dependsOn: [launcherJson, genClientBinPatches, applyClientBinPatches, applyServerBinPatches/*, createClientSRG, createServerSRG*/]) {
ext {
output = file('build/install_profile.json')
JAR_SPLITTER = 'net.minecraftforge:jarsplitter:1.1.2'
JAR_SPLITTER = 'net.minecraftforge:jarsplitter:1.1.4'
}
doFirst {
ext.BIN_PATCHER = BINPATCH_TOOL.substring(0, BINPATCH_TOOL.length() - 1 - BINPATCH_TOOL.split(':')[3].length())
@@ -635,8 +654,8 @@ project(':forge') {
artifact: [
path: "${project.group.replace('.', '/')}/${project.name}/${project.version}/${project.name}-${project.version}-universal.jar",
url: "", //Do not include the URL so that the installer/launcher won't grab it. This is also why we don't have the universal classifier
sha1: universalJar.archivePath.sha1(),
size: universalJar.archivePath.length()
sha1: universalJar.archiveFile.get().asFile.sha1(),
size: universalJar.archiveFile.get().asFile.length()
]
]
]
@@ -667,16 +686,16 @@ project(':forge') {
server: "[net.minecraft:server:${MC_VERSION}-${MCP_VERSION}:slim]"
],
MC_SLIM_SHA: [
client: "'${tasks.getByName('downloadClientSlim').output.sha1()}'",
server: "'${tasks.getByName('downloadServerSlim').output.sha1()}'"
client: "'${tasks.getByName('downloadClientSlim').output.get().asFile.sha1()}'",
server: "'${tasks.getByName('downloadServerSlim').output.get().asFile.sha1()}'"
],
MC_EXTRA: [
client: "[net.minecraft:client:${MC_VERSION}-${MCP_VERSION}:extra]",
server: "[net.minecraft:server:${MC_VERSION}-${MCP_VERSION}:extra]"
],
MC_EXTRA_SHA: [
client: "'${tasks.getByName('downloadClientExtra').output.sha1()}'",
server: "'${tasks.getByName('downloadServerExtra').output.sha1()}'"
client: "'${tasks.getByName('downloadClientExtra').output.get().asFile.sha1()}'",
server: "'${tasks.getByName('downloadServerExtra').output.get().asFile.sha1()}'"
],
MC_SRG: [
client: "[net.minecraft:client:${MC_VERSION}-${MCP_VERSION}:srg]",
@@ -691,8 +710,8 @@ project(':forge') {
server: "[${project.group}:${project.name}:${project.version}:server]"
],
PATCHED_SHA: [
client: "'${applyClientBinPatches.output.sha1()}'",
server: "'${applyServerBinPatches.output.sha1()}'"
client: "'${applyClientBinPatches.output.get().asFile.sha1()}'",
server: "'${applyServerBinPatches.output.get().asFile.sha1()}'"
],
MCP_VERSION: [
client: "'${MCP_VERSION}'",
@@ -771,7 +790,7 @@ project(':forge') {
from extraTxts
// add crowdin locales
from { crowdin.output.exists() ? zipTree(crowdin.output) : null}
from { crowdin.output.present && crowdin.output.get().asFile.exists() ? zipTree(crowdin.output) : null}
dependsOn crowdin
duplicatesStrategy = 'exclude'
@@ -819,12 +838,12 @@ project(':forge') {
}
task downloadInstaller(type: DownloadMavenArtifact) {
artifact = 'net.minecraftforge:installer:2.0.+:shrunk'
artifact = 'net.minecraftforge:installer:2.1.+:shrunk'
changing = true
}
task installerJar(type: Zip, dependsOn: [downloadInstaller, installerJson, launcherJson, genClientBinPatches, genServerBinPatches, 'signUniversalJar', 'signLauncherJar']) {
classifier = 'installer'
archiveClassifier = 'installer'
archiveExtension = 'jar' //Needs to be Zip task to not override Manifest, so set extension
destinationDirectory = file('build/libs')
from(extraTxts)
@@ -847,8 +866,10 @@ project(':forge') {
}
from(installerJson.output)
from(launcherJson.output)
from(zipTree(downloadInstaller.output)) {
duplicatesStrategy = 'exclude'
if (downloadInstaller.output.present) {
from(zipTree(downloadInstaller.output)) {
duplicatesStrategy = 'exclude'
}
}
}
@@ -862,8 +883,8 @@ project(':forge') {
storePass = jarsigner.storepass
keyPass = jarsigner.keypass
keyStore = jarsigner.keystore
inputFile = t.archivePath
outputFile = t.archivePath
inputFile = t.archiveFile
outputFile = t.archiveFile
doFirst {
project.logger.lifecycle('Signing: ' + inputFile)
}
@@ -873,7 +894,7 @@ project(':forge') {
task makeMdk(type: Zip) {
archiveBaseName = project.name
classifier = 'mdk'
archiveClassifier = 'mdk'
archiveVersion = project.version
destinationDirectory = file('build/libs')
@@ -906,13 +927,19 @@ project(':forge') {
userdevConfig {
def artifacts = getArtifacts(project, project.configurations.installer, true)
artifacts.each { key, lib ->
addLibrary(lib.name)
libraries.add(lib.name)
}
addLibrary("${project.group}:${project.name}:${project.version}:launcher")
libraries.add("${project.group}:${project.name}:${project.version}:launcher")
runs {
client {
main 'net.minecraftforge.userdev.LaunchTesting'
// Support mod devs running on Java 8 and up, including 16
jvmArgs '-XX:+IgnoreUnrecognizedVMOptions'
jvmArgs '--add-exports=java.base/sun.security.util=ALL-UNNAMED'
jvmArgs '--add-exports=jdk.naming.dns/com.sun.jndi.dns=java.naming'
jvmArgs '--add-opens=java.base/java.util.jar=ALL-UNNAMED'
environment 'target', 'fmluserdevclient'
environment 'assetIndex', '{asset_index}'
environment 'assetDirectory', '{assets_root}'
@@ -929,6 +956,12 @@ project(':forge') {
server {
main 'net.minecraftforge.userdev.LaunchTesting'
// Support mod devs running on Java 8 and up, including 16
jvmArgs '-XX:+IgnoreUnrecognizedVMOptions'
jvmArgs '--add-exports=java.base/sun.security.util=ALL-UNNAMED'
jvmArgs '--add-exports=jdk.naming.dns/com.sun.jndi.dns=java.naming'
jvmArgs '--add-opens=java.base/java.util.jar=ALL-UNNAMED'
environment 'target', 'fmluserdevserver'
environment 'MC_VERSION', "${MC_VERSION}"
@@ -942,7 +975,15 @@ project(':forge') {
data {
main 'net.minecraftforge.userdev.LaunchTesting'
// Support mod devs running on Java 8 and up, including 16
jvmArgs '-XX:+IgnoreUnrecognizedVMOptions'
jvmArgs '--add-exports=java.base/sun.security.util=ALL-UNNAMED'
jvmArgs '--add-exports=jdk.naming.dns/com.sun.jndi.dns=java.naming'
jvmArgs '--add-opens=java.base/java.util.jar=ALL-UNNAMED'
environment 'target', 'fmluserdevdata'
environment 'assetIndex', '{asset_index}'
environment 'assetDirectory', '{assets_root}'
environment 'MC_VERSION', "${MC_VERSION}"
environment 'FORGE_GROUP', "${project.group}"
@@ -972,10 +1013,10 @@ project(':forge') {
tasks {
main {
files = files("$rootDir/src/main/java")
files.from files("$rootDir/src/main/java")
}
test {
files = files("$rootDir/src/test/java")
files.from files("$rootDir/src/test/java")
}
}
}
@@ -990,16 +1031,16 @@ project(':forge') {
tool = SPECIAL_SOURCE + ':shaded'
}
task userdevExtrasReobf(type:TaskReobfuscateJar) {
task userdevExtrasReobf(type: ReobfuscateJar) {
dependsOn userdevExtras, createMcp2Srg
input = tasks.userdevExtras.archivePath
classpath = project.configurations.compile
input = tasks.userdevExtras.archiveFile
classpath.from project.configurations.userdevCompileClasspath
srg = tasks.createMcp2Srg.output
tool = SPECIAL_SOURCE + ':shaded'
}
userdevJar {
dependsOn userdevExtrasReobf
dependsOn tasks.userdevExtrasReobf
from (zipTree(tasks.userdevExtrasReobf.output)) {
into '/inject/'
}
@@ -1009,22 +1050,22 @@ project(':forge') {
}
extractRangeMap {
addDependencies jar.archivePath
addSources sourceSets.userdev.java.srcDirs
dependencies.from jar.archiveFile
sources.from sourceSets.userdev.java.srcDirs
}
applyRangeMap {
setSources sourceSets.userdev.java.srcDirs
sources.from sourceSets.userdev.java.srcDirs
}
tasks.eclipse.dependsOn('genEclipseRuns')
if (project.hasProperty('UPDATE_MAPPINGS')) {
extractRangeMap {
sources sourceSets.test.java.srcDirs
sources.from sourceSets.test.java.srcDirs
addDependencies compileTestJava.classpath
}
applyRangeMap {
sources sourceSets.test.java.srcDirs
sources.from sourceSets.test.java.srcDirs
}
sourceSets.test.java.srcDirs.each { extractMappedNew.addTarget it }
}
@@ -1073,12 +1114,15 @@ project(':forge') {
}
repositories {
maven {
if (project.hasProperty('forgeMavenPassword')) {
credentials {
username project.properties.forgeMavenUser
password project.properties.forgeMavenPassword
if (System.env.MAVEN_USER) {
url "https://maven.minecraftforge.net/releases/"
authentication {
basic(BasicAuthentication)
}
credentials {
username = System.env.MAVEN_USER ?: 'not'
password = System.env.MAVEN_PASSWORD ?: 'set'
}
url 'https://files.minecraftforge.net/maven/manage/upload'
} else {
url 'file://' + rootProject.file('repo').getAbsolutePath()
}
+4 -3
View File
@@ -1,8 +1,9 @@
repositories {
maven { url = 'https://maven.minecraftforge.net/' }
mavenCentral()
}
dependencies {
implementation 'org.ow2.asm:asm:9.0'
implementation 'org.ow2.asm:asm-tree:9.0'
implementation 'org.eclipse.jgit:org.eclipse.jgit:5.10.0.202012080955-r'
implementation 'org.ow2.asm:asm:9.1'
implementation 'org.ow2.asm:asm-tree:9.1'
implementation 'net.minecraftforge:srgutils:0.4.+'
}
@@ -1,15 +1,13 @@
package net.minecraftforge.forge.tasks
import groovy.json.JsonBuilder
import org.gradle.api.DefaultTask
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import org.objectweb.asm.ClassReader
import org.objectweb.asm.Opcodes
import org.objectweb.asm.Type
import org.objectweb.asm.tree.ClassNode
import org.objectweb.asm.tree.FieldNode
import org.objectweb.asm.tree.MethodNode
@@ -17,42 +15,47 @@ import org.objectweb.asm.tree.MethodNode
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
public abstract class BytecodeFinder extends DefaultTask {
@InputFile File jar
@OutputFile output = project.file("build/${name}/output.json")
abstract class BytecodeFinder extends DefaultTask {
@InputFile abstract RegularFileProperty getJar()
@OutputFile abstract RegularFileProperty getOutput()
BytecodeFinder() {
output.convention(project.layout.buildDirectory.dir(name).map { it.file("output.json") })
}
@TaskAction
protected void exec() {
Util.init()
if (output.exists())
output.delete()
def outputFile = output.get().asFile
if (outputFile.exists())
outputFile.delete()
pre()
jar.withInputStream { i ->
jar.get().asFile.withInputStream { i ->
new ZipInputStream(i).withCloseable { zin ->
ZipEntry zein
while ((zein = zin.nextEntry) != null) {
if (zein.name.endsWith('.class')) {
def node = new ClassNode(Opcodes.ASM7)
def node = new ClassNode(Opcodes.ASM9)
new ClassReader(zin).accept(node, 0)
process(node)
}
}
}
}
post()
output.text = new JsonBuilder(getData()).toPrettyString()
outputFile.text = new JsonBuilder(getData()).toPrettyString()
}
protected process(ClassNode node) {
if (node.fields != null) node.fields.each { process(node, it) }
if (node.methods != null) node.methods.each { process(node, it) }
}
protected pre() {}
protected process(ClassNode parent, FieldNode node) {}
protected process(ClassNode parent, MethodNode node) {}
@@ -1,20 +1,23 @@
package net.minecraftforge.forge.tasks
import java.util.ArrayList
import java.util.TreeMap
import net.minecraftforge.srgutils.IMappingFile
import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.TaskAction
import org.objectweb.asm.Opcodes
public class CheckATs extends DefaultTask {
@InputFile File inheritance
@InputFiles File[] ats
abstract class CheckATs extends DefaultTask {
@InputFile abstract RegularFileProperty getInheritance()
@InputFiles abstract ConfigurableFileCollection getAts()
@InputFile @Optional abstract RegularFileProperty getMappings()
@TaskAction
protected void exec() {
def mappings = mappings.map { IMappingFile.load(it.asFile) }.getOrNull()
Util.init()
def parse = { line ->
def idx = line.indexOf('#')
@@ -41,7 +44,7 @@ public class CheckATs extends DefaultTask {
default: return -1
}
}
def json = inheritance.json()
def json = inheritance.get().asFile.json()
ats.each { f ->
TreeMap lines = [:]
@@ -51,12 +54,12 @@ public class CheckATs extends DefaultTask {
if (line.startsWith('#group ')) {
def (modifier, cls, desc, comment, key) = parse.call(line.substring(7))
if (!desc.equals('*') && !desc.equals('*()') && !desc.equals('<init>'))
if (desc != '*' && desc != '*()' && desc != '<init>')
throw new IllegalStateException('Invalid group: ' + line)
group = [modifier: modifier, cls: cls, desc: desc, comment: comment,
'existing': [] as Set,
'children': [] as TreeSet,
existing: [] as Set,
children: [] as TreeSet,
group: true
]
if (lines.containsKey(key))
@@ -93,7 +96,7 @@ public class CheckATs extends DefaultTask {
if (jcls == null) {
lines.remove(key)
println('Invalid Group: ' + key)
} else if ('*'.equals(entry['desc'])) {
} else if ('*' == entry['desc']) {
if (!jcls.containsKey('fields')) {
lines.remove(key)
println('Invalid Group, Class has no fields: ' + key)
@@ -114,13 +117,13 @@ public class CheckATs extends DefaultTask {
}
entry['existing'].stream().findAll{ !entry['children'].contains(it) }.each{ println('Removed: ' + it) }
}
} else if ('*()'.equals(entry['desc'])) {
} else if ('*()' == entry['desc']) {
if (!jcls.containsKey('methods')) {
lines.remove(key)
println('Invalid Group, Class has no methods: ' + key)
} else {
jcls['methods'].each{ mtd, value ->
if (mtd.startsWith('<clinit>'))
if (mtd.startsWith('<clinit>') || mtd.startsWith('lambda$'))
return
key = cls + ' ' + mtd.replace(' ', '')
if (accessLevel.call(value['access']) < accessStr.call(entry['modifier'])) {
@@ -137,7 +140,7 @@ public class CheckATs extends DefaultTask {
}
entry['existing'].stream().findAll{ !entry['children'].contains(it) }.each{ println('Removed: ' + it) }
}
} else if ('<init>'.equals(entry['desc'])) { //Make all public non-abstract subclasses
} else if ('<init>' == entry['desc']) { //Make all public non-abstract subclasses
json.each{ tcls,value ->
if (!value.containsKey('methods') || ((value['access'] & Opcodes.ACC_ABSTRACT) != 0))
return
@@ -182,7 +185,7 @@ public class CheckATs extends DefaultTask {
lines.remove(key)
println('Invalid: ' + key)
} else if (entry['desc'] == '') {
if (accessLevel.call(jcls['access']) >= accessStr.call(entry['modifier']) && (entry.comment == null || !entry.comment.startsWith('#force '))) {
if (accessLevel.call(jcls['access']) > accessStr.call(entry['modifier']) && (entry.comment == null || !entry.comment.startsWith('#force '))) {
lines.remove(key)
println('Invalid Narrowing: ' + key)
}
@@ -192,7 +195,7 @@ public class CheckATs extends DefaultTask {
println('Invalid: ' + key)
} else {
def value = jcls['fields'][entry['desc']]
if (accessLevel.call(value['access']) >= accessStr.call(entry['modifier']) && (entry.comment == null || !entry.comment.startsWith('#force '))) {
if (accessLevel.call(value['access']) > accessStr.call(entry['modifier']) && (entry.comment == null || !entry.comment.startsWith('#force '))) {
lines.remove(key)
println('Invalid Narrowing: ' + key)
println(entry.comment)
@@ -205,7 +208,7 @@ public class CheckATs extends DefaultTask {
println('Invalid: ' + key)
} else {
def value = jcls['methods'][jdesc]
if (accessLevel.call(value['access']) >= accessStr.call(entry['modifier']) && (entry.comment == null || !entry.comment.startsWith('#force '))) {
if (accessLevel.call(value['access']) > accessStr.call(entry['modifier']) && (entry.comment == null || !entry.comment.startsWith('#force '))) {
lines.remove(key)
println('Invalid Narrowing: ' + key)
}
@@ -216,12 +219,44 @@ public class CheckATs extends DefaultTask {
def data = []
def remapComment = { entry ->
if (!mappings || !entry || !entry.desc) return null
def comment = entry.comment?.substring(1)?.trim()
def jsonCls = json.get(entry.cls.replaceAll('\\.', '/'))
def mappingsClass = mappings?.getClass(jsonCls.name)
if (!mappingsClass) return entry.comment
def idx = entry.desc.indexOf('(')
def mappedName = idx == -1
? mappingsClass.remapField(entry.desc)
: mappingsClass.remapMethod(entry.desc.substring(0, idx), entry.desc.substring(idx))
if (!mappedName) return entry.comment
if (mappedName == '<init>')
mappedName = 'constructor'
if (comment?.startsWith(mappedName))
return '# ' + comment
if (comment && comment.indexOf(' ') != -1) {
def split = comment.split(" - ").toList()
if (split[0].indexOf(' ') != -1)
// The first string is more than one word, so append before it
return "# ${mappedName} - ${comment}"
split.remove(0)
return "# ${mappedName} - ${String.join(' - ', split)}"
}
return '# ' + mappedName
}
lines.each { key,value ->
if (!value.group) {
data.add(value.modifier + ' ' + key + (value.comment == null ? '' : ' ' + value.comment))
def comment = remapComment.call(value)
data.add(value.modifier + ' ' + key + (comment ? ' ' + comment : ''))
} else {
data.add('#group ' + value.modifier + ' ' + key + (value.comment == null ? '' : ' ' + value.comment))
value.children.each{ data.add(value.modifier + ' ' + it) }
value.children.each {
def line = value.modifier + ' ' + it
def (modifier, cls, desc, comment) = parse.call(line)
comment = remapComment.call([modifier: modifier, cls: cls, desc: desc, comment: comment])
data.add(line + (comment ? ' ' + comment : ''))
}
data.add('#endgroup')
}
}
@@ -1,33 +1,27 @@
package net.minecraftforge.forge.tasks
import java.util.ArrayList
import java.util.TreeMap
import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.TaskAction
import org.objectweb.asm.ClassReader
import org.objectweb.asm.ClassVisitor
import org.objectweb.asm.MethodVisitor
import org.objectweb.asm.Opcodes
import org.objectweb.asm.Type
import org.objectweb.asm.*
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
public class CheckExcs extends DefaultTask {
@InputFile File binary
@InputFiles File[] excs
abstract class CheckExcs extends DefaultTask {
@InputFile abstract RegularFileProperty getBinary()
@InputFiles abstract ConfigurableFileCollection getExcs()
@TaskAction
protected void exec() {
Util.init()
def known = []
binary.withInputStream { i ->
binary.get().asFile.withInputStream { i ->
new ZipInputStream(i).withCloseable { zin ->
def visitor = new ClassVisitor(Opcodes.ASM7) {
def visitor = new ClassVisitor(Opcodes.ASM9) {
private String cls
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
@@ -68,8 +62,7 @@ public class CheckExcs extends DefaultTask {
def (key, value) = line.split('=', 2)
if (!known.contains(key)) {
println(key)
println('Invalid: ' + line)
println('Unknown: ' + line)
return
}
@@ -1,6 +1,7 @@
package net.minecraftforge.forge.tasks
import org.gradle.api.DefaultTask
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.TaskAction
@@ -9,8 +10,8 @@ import java.nio.file.Files
import java.nio.file.Paths
import java.util.regex.Pattern
public class CheckPatches extends DefaultTask {
@InputDirectory File patchDir
abstract class CheckPatches extends DefaultTask {
@InputDirectory abstract DirectoryProperty getPatchDir()
@Input boolean autoFix = false
@TaskAction
@@ -21,7 +22,7 @@ public class CheckPatches extends DefaultTask {
]
def verified = true;
project.fileTree(patchDir).each { patch ->
patchDir.get().asFileTree.each { patch ->
def patchPath = project.rootDir.toPath().relativize(patch.toPath())
verified &= verifyPatch(patch, autoFix, patchPath.toString(), hasS2SArtifact.contains(patchPath))
}
@@ -31,7 +32,7 @@ public class CheckPatches extends DefaultTask {
}
def verifyPatch(patch, fix, patchPath, hasS2SArtifact) {
def hunk_start_pattern = Pattern.compile('^@@ -[0-9,]* \\+[0-9,]* @@$')
def hunk_start_pattern = Pattern.compile('^@@ -[0-9,]* \\+[0-9,_]* @@$')
def white_space_pattern = Pattern.compile('^[+\\-]\\s*$')
def import_pattern = Pattern.compile('^[+\\-]\\s*import.*')
def field_pattern = Pattern.compile('^[+\\-][\\s]*((public|protected|private)[\\s]*)?(static[\\s]*)?(final)?([^=;]*)(=.*)?;\\s*$')
@@ -1,22 +1,20 @@
package net.minecraftforge.forge.tasks
import java.util.ArrayList
import java.util.TreeMap
import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.TaskAction
import org.objectweb.asm.Opcodes
public class CheckSAS extends DefaultTask {
@InputFile File inheritance
@InputFiles File[] sass
abstract class CheckSAS extends DefaultTask {
@InputFile abstract RegularFileProperty getInheritance()
@InputFiles abstract ConfigurableFileCollection getSass()
@TaskAction
protected void exec() {
Util.init()
def json = inheritance.json()
def json = inheritance.get().asFile.json()
sass.each { f ->
def lines = []
@@ -22,7 +22,7 @@ public class ClosureHelper {
}
}
static def apply(def obj, Closure cl) {
static <T> T apply(T obj, Closure cl) {
cl.delegate = obj
cl.resolveStrategy = Closure.DELEGATE_FIRST
cl()
@@ -1,47 +1,55 @@
package net.minecraftforge.forge.tasks
import org.gradle.api.DefaultTask
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
import java.util.zip.ZipOutputStream
import java.net.URL
public class CrowdinTask extends DefaultTask {
@Input String id = 'minecraft-forge'
@Input @Optional String key
abstract class Crowdin extends DefaultTask {
@Input abstract Property<String> getId()
@Input @Optional abstract Property<String> getKey()
@Input boolean json = true
@OutputFile output = project.file("build/${name}/output.zip")
@OutputFile export = project.file("build/${name}/export.json")
CrowdinTask() {
@OutputFile abstract RegularFileProperty getOutput()
@OutputFile abstract RegularFileProperty getExport()
Crowdin() {
outputs.upToDateWhen{ false }
id.convention('minecraft-forge')
output.convention(project.layout.buildDirectory.dir(name).map {it.file("output.zip") })
export.convention(project.layout.buildDirectory.dir(name).map {it.file("export.json") })
}
@TaskAction
def run() {
if (output.exists())
output.delete()
File outputFile = output.get().asFile
File exportFile = export.get().asFile
if (outputFile.exists())
outputFile.delete()
if (key == null)
if (!key.isPresent())
return
String key = this.key.get()
String id = this.id.get()
// Force an export
new URL("https://api.crowdin.com/api/project/${id}/export?key=${key}").withInputStream { i ->
export.withOutputStream { it << i }
new URL("https://api.crowdin.com/api/project/${id}/export?key=${key}").withInputStream { i ->
exportFile.withOutputStream { it << i }
}
if (!export.text.contains('success')) {
throw new RuntimeException("Crowdin export failed, see ${export} for more info")
if (!exportFile.text.contains('success')) {
throw new RuntimeException("Crowdin export failed, see ${exportFile} for more info")
}
new URL("https://api.crowdin.com/api/project/${id}/download/all.zip?key=${key}").withInputStream { i ->
new ZipInputStream(i).withCloseable { zin ->
output.withOutputStream { out ->
outputFile.withOutputStream { out ->
new ZipOutputStream(out).withCloseable { zout ->
ZipEntry zein
while ((zein = zin.nextEntry) != null) {
@@ -0,0 +1,51 @@
package net.minecraftforge.forge.tasks
import org.gradle.api.DefaultTask
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import java.nio.file.Files
abstract class DownloadLibraries extends DefaultTask {
@InputFile abstract RegularFileProperty getInput()
@OutputDirectory abstract DirectoryProperty getOutput()
@OutputFile abstract RegularFileProperty getLibrariesOutput()
DownloadLibraries() {
output.convention(project.layout.buildDirectory.dir(name))
librariesOutput.convention(project.layout.buildDirectory.dir(name).map(d -> d.file('libraries.txt')))
}
@TaskAction
def run() {
Util.init()
File outputDir = output.get().asFile
def libraries = new ArrayList()
def json = input.get().asFile.json().libraries.each { lib ->
//TODO: Thread?
def artifacts = [lib.downloads.artifact] + lib.downloads.get('classifiers', [:]).values()
artifacts.each{ art ->
def target = new File(outputDir, art.path)
libraries.add(target.absolutePath)
if (!target.exists() || !art.sha1.equals(target.sha1())) {
project.logger.lifecycle("Downloading ${art.url}")
if (!target.parentFile.exists()) {
target.parentFile.mkdirs()
}
new URL(art.url).withInputStream { i ->
target.withOutputStream { it << i }
}
if (!art.sha1.equals(target.sha1())) {
throw new IllegalStateException("Failed to download ${art.url} to ${target.canonicalPath} SHA Mismatch")
}
}
}
}
Files.write(librariesOutput.get().asFile.toPath(), libraries)
}
}
@@ -1,43 +0,0 @@
package net.minecraftforge.forge.tasks
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.OutputDirectory
import java.io.File
import java.util.HashSet
import java.util.Set
import java.net.URL
public class DownloadLibrariesTask extends DefaultTask {
@InputFile File input
@OutputDirectory File output = project.file("build/${name}/")
Set<File> libraries = new HashSet<>()
@TaskAction
def run() {
Util.init()
def json = input.json().libraries.each { lib ->
//TODO: Thread?
def artifacts = [lib.downloads.artifact] + lib.downloads.get('classifiers', [:]).values()
artifacts.each{ art ->
def target = new File(output, art.path)
libraries.add(target)
if (!target.exists() || !art.sha1.equals(target.sha1())) {
project.logger.lifecycle("Downloading ${art.url}")
if (!target.parentFile.exists()) {
target.parentFile.mkdirs()
}
new URL(art.url).withInputStream { i ->
target.withOutputStream { it << i }
}
if (!art.sha1.equals(target.sha1())) {
throw new IllegalStateException("Failed to download ${art.url} to ${target.canonicalPath} SHA Mismatch")
}
}
}
}
}
}
@@ -1,30 +1,21 @@
package net.minecraftforge.forge.tasks
import groovy.transform.EqualsAndHashCode
import java.util.ArrayList
import java.util.HashMap
import java.util.TreeMap
import java.util.TreeSet
import java.util.function.BiConsumer
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.Nested
import org.gradle.api.tasks.Optional
import org.objectweb.asm.Opcodes
import org.objectweb.asm.Type
import org.objectweb.asm.tree.ClassNode
import org.objectweb.asm.tree.FieldNode
import org.objectweb.asm.tree.MethodNode
import static org.objectweb.asm.Opcodes.*
public class FieldCompareFinder extends BytecodeFinder {
abstract class FieldCompareFinder extends BytecodeFinder {
@Nested
Map<String, Search> fields = [:] as HashMap
@Internal
Map<Search, String> fieldsReverse = [:] as HashMap
@Internal
Map<String, Set<ObjectTarget>> targets = [:] as TreeMap
@Override
@@ -53,6 +44,7 @@ public class FieldCompareFinder extends BytecodeFinder {
}
}
@Internal
@Override
protected Object getData() {
def ret = [:] as HashMap
@@ -2,14 +2,8 @@ package net.minecraftforge.forge.tasks
import groovy.json.JsonSlurper
import java.io.File
import java.security.MessageDigest
import java.text.SimpleDateFormat
import java.util.Date
import org.eclipse.jgit.api.Git
import org.eclipse.jgit.lib.AbbreviatedObjectId
import org.eclipse.jgit.lib.ObjectId
public class Util {
static void init() {
@@ -72,7 +66,7 @@ public class Util {
def path = "${folder}${filename}"
def url = "https://libraries.minecraft.net/${path}"
if (!checkExists(url)) {
url = "https://files.minecraftforge.net/maven/${path}"
url = "https://maven.minecraftforge.net/${path}"
}
//TODO remove when Mojang launcher is updated
if (!classifiers && art.classifier != null) {
@@ -131,42 +125,4 @@ public class Util {
throw e
}
}
public static def gitInfo(dir) {
init()
def git = null
try {
git = Git.open(dir)
} catch (org.eclipse.jgit.errors.RepositoryNotFoundException e) {
return [
tag: '0.0',
offset: '0',
hash: '00000000',
branch: 'master',
commit: '0000000000000000000000',
abbreviatedId: '00000000'
]
}
def desc = git.describe().setLong(true).setTags(true).call().rsplit('-', 2)
def head = git.repository.resolve('HEAD')
def ret = [:]
ret.tag = desc[0]
ret.offset = desc[1]
ret.hash = desc[2]
ret.branch = git.repository.branch
ret.commit = ObjectId.toString(head)
ret.abbreviatedId = head.abbreviate(8).name()
return ret
}
public static String getVersion(info, mc_version) {
def branch = info.branch
if (branch != null && branch.startsWith('pulls/'))
branch = 'pr' + branch.rsplit('/', 1)[1]
if (branch in [null, 'master', 'HEAD', mc_version, mc_version + '.0', mc_version.rsplit('.', 1)[0] + '.x'])
return "${mc_version}-${info.tag}.${info.offset}".toString()
return "${mc_version}-${info.tag}.${info.offset}-${branch}".toString()
}
}
+2 -2
View File
@@ -2,8 +2,8 @@
MinecraftForge
=============
[![Stable Release](https://img.shields.io/badge/dynamic/json?url=https://files.minecraftforge.net/maven/net/minecraftforge/forge/promotions_slim.json&label=Stable&prefix=1.16.5-&query=$.promos["1.16.5-recommended"]&color=brightgreen&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBjbGFzcz0ic3ZnLWlubGluZS0tZmEgZmEtc3RhciBmYS13LTE4IiBhcmlhLWhpZGRlbj0idHJ1ZSIgZGF0YS1pY29uPSJzdGFyIiBkYXRhLXByZWZpeD0iZmFzIiBmb2N1c2FibGU9ImZhbHNlIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCA1NzYgNTEyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cGF0aCBkPSJNMjU5LjMgMTcuOEwxOTQgMTUwLjIgNDcuOSAxNzEuNWMtMjYuMiAzLjgtMzYuNyAzNi4xLTE3LjcgNTQuNmwxMDUuNyAxMDMtMjUgMTQ1LjVjLTQuNSAyNi4zIDIzLjIgNDYgNDYuNCAzMy43TDI4OCA0MzkuNmwxMzAuNyA2OC43YzIzLjIgMTIuMiA1MC45LTcuNCA0Ni40LTMzLjdsLTI1LTE0NS41IDEwNS43LTEwM2MxOS0xOC41IDguNS01MC44LTE3LjctNTQuNkwzODIgMTUwLjIgMzE2LjcgMTcuOGMtMTEuNy0yMy42LTQ1LjYtMjMuOS01Ny40IDB6IiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K)](https://files.minecraftforge.net)
[![Latest Release](https://img.shields.io/badge/dynamic/json?url=https://files.minecraftforge.net/maven/net/minecraftforge/forge/promotions_slim.json&label=Latest&prefix=1.16.5-&query=$.promos["1.16.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.16.5-&query=$.promos["1.16.5-recommended"]&color=brightgreen&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBjbGFzcz0ic3ZnLWlubGluZS0tZmEgZmEtc3RhciBmYS13LTE4IiBhcmlhLWhpZGRlbj0idHJ1ZSIgZGF0YS1pY29uPSJzdGFyIiBkYXRhLXByZWZpeD0iZmFzIiBmb2N1c2FibGU9ImZhbHNlIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCA1NzYgNTEyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cGF0aCBkPSJNMjU5LjMgMTcuOEwxOTQgMTUwLjIgNDcuOSAxNzEuNWMtMjYuMiAzLjgtMzYuNyAzNi4xLTE3LjcgNTQuNmwxMDUuNyAxMDMtMjUgMTQ1LjVjLTQuNSAyNi4zIDIzLjIgNDYgNDYuNCAzMy43TDI4OCA0MzkuNmwxMzAuNyA2OC43YzIzLjIgMTIuMiA1MC45LTcuNCA0Ni40LTMzLjdsLTI1LTE0NS41IDEwNS43LTEwM2MxOS0xOC41IDguNS01MC44LTE3LjctNTQuNkwzODIgMTUwLjIgMzE2LjcgMTcuOGMtMTEuNy0yMy42LTQ1LjYtMjMuOS01Ny40IDB6IiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K)](https://files.minecraftforge.net)
[![Latest Release](https://img.shields.io/badge/dynamic/json?url=https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json&label=Latest&prefix=1.16.5-&query=$.promos["1.16.5-latest"]&color=blue&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBjbGFzcz0ic3ZnLWlubGluZS0tZmEgZmEtYnVnIGZhLXctMTYiIGFyaWEtaGlkZGVuPSJ0cnVlIiBkYXRhLWljb249ImJ1ZyIgZGF0YS1wcmVmaXg9ImZhcyIgZm9jdXNhYmxlPSJmYWxzZSIgcm9sZT0iaW1nIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTUxMS45ODggMjg4LjljLS40NzggMTcuNDMtMTUuMjE3IDMxLjEtMzIuNjUzIDMxLjFINDI0djE2YzAgMjEuODY0LTQuODgyIDQyLjU4NC0xMy42IDYxLjE0NWw2MC4yMjggNjAuMjI4YzEyLjQ5NiAxMi40OTcgMTIuNDk2IDMyLjc1OCAwIDQ1LjI1NS0xMi40OTggMTIuNDk3LTMyLjc1OSAxMi40OTYtNDUuMjU2IDBsLTU0LjczNi01NC43MzZDMzQ1Ljg4NiA0NjcuOTY1IDMxNC4zNTEgNDgwIDI4MCA0ODBWMjM2YzAtNi42MjctNS4zNzMtMTItMTItMTJoLTI0Yy02LjYyNyAwLTEyIDUuMzczLTEyIDEydjI0NGMtMzQuMzUxIDAtNjUuODg2LTEyLjAzNS05MC42MzYtMzIuMTA4bC01NC43MzYgNTQuNzM2Yy0xMi40OTggMTIuNDk3LTMyLjc1OSAxMi40OTYtNDUuMjU2IDAtMTIuNDk2LTEyLjQ5Ny0xMi40OTYtMzIuNzU4IDAtNDUuMjU1bDYwLjIyOC02MC4yMjhDOTIuODgyIDM3OC41ODQgODggMzU3Ljg2NCA4OCAzMzZ2LTE2SDMyLjY2NkMxNS4yMyAzMjAgLjQ5MSAzMDYuMzMuMDEzIDI4OC45LS40ODQgMjcwLjgxNiAxNC4wMjggMjU2IDMyIDI1Nmg1NnYtNTguNzQ1bC00Ni42MjgtNDYuNjI4Yy0xMi40OTYtMTIuNDk3LTEyLjQ5Ni0zMi43NTggMC00NS4yNTUgMTIuNDk4LTEyLjQ5NyAzMi43NTgtMTIuNDk3IDQ1LjI1NiAwTDE0MS4yNTUgMTYwaDIyOS40ODlsNTQuNjI3LTU0LjYyN2MxMi40OTgtMTIuNDk3IDMyLjc1OC0xMi40OTcgNDUuMjU2IDAgMTIuNDk2IDEyLjQ5NyAxMi40OTYgMzIuNzU4IDAgNDUuMjU1TDQyNCAxOTcuMjU1VjI1Nmg1NmMxNy45NzIgMCAzMi40ODQgMTQuODE2IDMxLjk4OCAzMi45ek0yNTcgMGMtNjEuODU2IDAtMTEyIDUwLjE0NC0xMTIgMTEyaDIyNEMzNjkgNTAuMTQ0IDMxOC44NTYgMCAyNTcgMHoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo=
)](https://files.minecraftforge.net) [![Discord](https://img.shields.io/discord/313125603924639766.svg?color=%237289da&label=Discord&logo=discord&logoColor=%237289da)](https://discord.gg/UvedJ9m) [![Support](https://img.shields.io/badge/Patreon-Support-orange.svg?logo=Patreon)](https://www.patreon.com/LexManos)
Forge is a free, open-source modding API all of your favourite mods use!
+4
View File
@@ -0,0 +1,4 @@
# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
# This is required to provide enough memory for the Minecraft decompilation process.
org.gradle.jvmargs=-Xmx3G
org.gradle.daemon=false
Binary file not shown.
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+33 -20
View File
@@ -1,5 +1,21 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
@@ -28,7 +44,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
@@ -66,6 +82,7 @@ esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@@ -109,10 +126,11 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
@@ -138,19 +156,19 @@ if $cygwin ; then
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
i=`expr $i + 1`
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
@@ -159,14 +177,9 @@ save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
Vendored
+24 -19
View File
@@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -35,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -45,28 +64,14 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
+5 -5
View File
@@ -1,10 +1,10 @@
buildscript {
repositories {
maven { url = 'https://files.minecraftforge.net/maven' }
maven { url = 'https://maven.minecraftforge.net' }
mavenCentral()
}
dependencies {
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '4.1.+', changing: true
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true
}
}
apply plugin: 'net.minecraftforge.gradle'
@@ -43,7 +43,7 @@ minecraft {
workingDirectory project.file('run')
// Recommended logging data for a userdev environment
// The markers can be changed as needed.
// The markers can be changed as needed.
// "SCAN": For mods scan.
// "REGISTRIES": For firing of registry events.
// "REGISTRYDUMP": For getting the contents of all registries.
@@ -65,7 +65,7 @@ minecraft {
workingDirectory project.file('run')
// Recommended logging data for a userdev environment
// The markers can be changed as needed.
// The markers can be changed as needed.
// "SCAN": For mods scan.
// "REGISTRIES": For firing of registry events.
// "REGISTRYDUMP": For getting the contents of all registries.
@@ -87,7 +87,7 @@ minecraft {
workingDirectory project.file('run')
// Recommended logging data for a userdev environment
// The markers can be changed as needed.
// The markers can be changed as needed.
// "SCAN": For mods scan.
// "REGISTRIES": For firing of registry events.
// "REGISTRYDUMP": For getting the contents of all registries.
@@ -1,5 +1,15 @@
--- a/net/minecraft/block/BeehiveBlock.java
+++ b/net/minecraft/block/BeehiveBlock.java
@@ -65,6 +_,9 @@
public int func_180641_l(BlockState p_180641_1_, World p_180641_2_, BlockPos p_180641_3_) {
return p_180641_1_.func_177229_b(field_226873_c_);
}
+ // Forge: Fixed MC-227255 Beehives and bee nests do not rotate/mirror correctly in structure blocks
+ @Override public BlockState func_185499_a(BlockState blockState, net.minecraft.util.Rotation rotation) { return (BlockState)blockState.func_206870_a(field_226872_b_, rotation.func_185831_a(blockState.func_177229_b(field_226872_b_))); }
+ @Override public BlockState func_185471_a(BlockState blockState, net.minecraft.util.Mirror mirror) { return blockState.func_185907_a(mirror.func_185800_a(blockState.func_177229_b(field_226872_b_))); }
public void func_180657_a(World p_180657_1_, PlayerEntity p_180657_2_, BlockPos p_180657_3_, BlockState p_180657_4_, @Nullable TileEntity p_180657_5_, ItemStack p_180657_6_) {
super.func_180657_a(p_180657_1_, p_180657_2_, p_180657_3_, p_180657_4_, p_180657_5_, p_180657_6_);
@@ -85,6 +_,7 @@
List<BeeEntity> list = p_226881_1_.func_217357_a(BeeEntity.class, (new AxisAlignedBB(p_226881_2_)).func_72314_b(8.0D, 6.0D, 8.0D));
if (!list.isEmpty()) {
@@ -0,0 +1,12 @@
--- a/net/minecraft/block/ChestBlock.java
+++ b/net/minecraft/block/ChestBlock.java
@@ -325,7 +_,8 @@
}
public BlockState func_185471_a(BlockState p_185471_1_, Mirror p_185471_2_) {
- return p_185471_1_.func_185907_a(p_185471_2_.func_185800_a(p_185471_1_.func_177229_b(field_176459_a)));
+ BlockState rotated = p_185471_1_.func_185907_a(p_185471_2_.func_185800_a(p_185471_1_.func_177229_b(field_176459_a)));
+ return p_185471_2_ == Mirror.NONE ? rotated : rotated.func_206870_a(field_196314_b, rotated.func_177229_b(field_196314_b).func_208081_a()); // Forge: Fixed MC-134110 Structure mirroring breaking apart double chests
}
protected void func_206840_a(StateContainer.Builder<Block, BlockState> p_206840_1_) {
@@ -9,9 +9,9 @@
+ @Override
+ public boolean isLadder(BlockState state, net.minecraft.world.IWorldReader world, BlockPos pos, net.minecraft.entity.LivingEntity entity) {
+ if (state.func_177229_b(field_176283_b)) {
+ BlockState down = world.func_180495_p(pos.func_177977_b());
+ if (down.func_203425_a(net.minecraft.block.Blocks.field_150468_ap))
+ return down.func_177229_b(LadderBlock.field_176382_a) == state.func_177229_b(field_185512_D);
+ BlockPos downPos = pos.func_177977_b();
+ BlockState down = world.func_180495_p(downPos);
+ return down.func_177230_c().makesOpenTrapdoorAboveClimbable(down, world, downPos, state);
+ }
+ return false;
+ }
@@ -0,0 +1,12 @@
--- a/net/minecraft/block/TripWireHookBlock.java
+++ b/net/minecraft/block/TripWireHookBlock.java
@@ -150,8 +_,8 @@
BlockPos blockpos2 = p_176260_2_.func_177967_a(direction, k);
BlockState blockstate2 = ablockstate[k];
if (blockstate2 != null) {
+ if (!p_176260_1_.func_180495_p(blockpos2).func_196958_f()) { // FORGE: fix MC-129055
p_176260_1_.func_180501_a(blockpos2, blockstate2.func_206870_a(field_176265_M, Boolean.valueOf(flag2)), 3);
- if (!p_176260_1_.func_180495_p(blockpos2).func_196958_f()) {
}
}
}
@@ -26,7 +26,7 @@
}, "mouseReleased event handler", this.field_198036_a.field_71462_r.getClass().getCanonicalName());
}
}
@@ -110,7 +_,7 @@
@@ -110,18 +_,26 @@
}
}
}
@@ -35,7 +35,17 @@
}
}
@@ -121,7 +_,9 @@
private void func_198020_a(long p_198020_1_, double p_198020_3_, double p_198020_5_) {
if (p_198020_1_ == Minecraft.func_71410_x().func_228018_at_().func_198092_i()) {
- double d0 = (this.field_198036_a.field_71474_y.field_216843_O ? Math.signum(p_198020_5_) : p_198020_5_) * this.field_198036_a.field_71474_y.field_208033_V;
+ // FORGE: Allows for Horizontal Scroll to be recognized as Vertical Scroll - Fixes MC-121772
+ double offset = p_198020_5_;
+ if (Minecraft.field_142025_a && p_198020_5_ == 0) {
+ offset = p_198020_3_;
+ }
+
+ double d0 = (this.field_198036_a.field_71474_y.field_216843_O ? Math.signum(offset) : offset) * this.field_198036_a.field_71474_y.field_208033_V;
if (this.field_198036_a.field_213279_p == null) {
if (this.field_198036_a.field_71462_r != null) {
double d1 = this.field_198040_e * (double)this.field_198036_a.func_228018_at_().func_198107_o() / (double)this.field_198036_a.func_228018_at_().func_198105_m();
double d2 = this.field_198041_f * (double)this.field_198036_a.func_228018_at_().func_198087_p() / (double)this.field_198036_a.func_228018_at_().func_198083_n();
@@ -0,0 +1,16 @@
--- a/net/minecraft/client/renderer/RenderType.java
+++ b/net/minecraft/client/renderer/RenderType.java
@@ -215,11 +_,11 @@
}
public static RenderType func_228658_l_(ResourceLocation p_228658_0_) {
- return func_228633_a_("text", DefaultVertexFormats.field_227852_q_, 7, 256, false, true, RenderType.State.func_228694_a_().func_228724_a_(new RenderState.TextureState(p_228658_0_, false, false)).func_228713_a_(field_228517_i_).func_228726_a_(field_228515_g_).func_228719_a_(field_228528_t_).func_228728_a_(false));
+ return net.minecraftforge.client.ForgeRenderTypes.getText(p_228658_0_);
}
public static RenderType func_228660_m_(ResourceLocation p_228660_0_) {
- return func_228633_a_("text_see_through", DefaultVertexFormats.field_227852_q_, 7, 256, false, true, RenderType.State.func_228694_a_().func_228724_a_(new RenderState.TextureState(p_228660_0_, false, false)).func_228713_a_(field_228517_i_).func_228726_a_(field_228515_g_).func_228719_a_(field_228528_t_).func_228715_a_(field_228492_B_).func_228727_a_(field_228496_F_).func_228728_a_(false));
+ return net.minecraftforge.client.ForgeRenderTypes.getTextSeeThrough(p_228660_0_);
}
public static RenderType func_228657_l_() {
@@ -1,10 +0,0 @@
--- a/net/minecraft/client/renderer/model/ModelResourceLocation.java
+++ b/net/minecraft/client/renderer/model/ModelResourceLocation.java
@@ -5,7 +_,6 @@
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
-@OnlyIn(Dist.CLIENT)
public class ModelResourceLocation extends ResourceLocation {
private final String field_177519_c;
@@ -26,3 +26,12 @@
if (j1 < p_229220_4_) {
field_147635_d.warn("{}: dropping miplevel from {} to {}, because of minimum power of two: {}", this.field_229214_j_, p_229220_4_, j1, i1);
k1 = j1;
@@ -200,6 +_,8 @@
try (IResource iresource = p_229218_1_.func_199002_a(resourcelocation)) {
NativeImage nativeimage = NativeImage.func_195713_a(iresource.func_199027_b());
+ TextureAtlasSprite customSprite = net.minecraftforge.client.ForgeHooksClient.loadTextureAtlasSprite(this, p_229218_1_, p_229218_2_, iresource, p_229218_3_, p_229218_4_, p_229218_6_, p_229218_7_, p_229218_5_, nativeimage);
+ if (customSprite != null) return customSprite;
return new TextureAtlasSprite(this, p_229218_2_, p_229218_5_, p_229218_3_, p_229218_4_, p_229218_6_, p_229218_7_, nativeimage);
} catch (RuntimeException runtimeexception) {
field_147635_d.error("Unable to parse metadata from {}", resourcelocation, runtimeexception);
@@ -0,0 +1,12 @@
--- a/net/minecraft/command/impl/SpreadPlayersCommand.java
+++ b/net/minecraft/command/impl/SpreadPlayersCommand.java
@@ -162,7 +_,8 @@
spreadplayerscommand$position = p_241072_2_[i++];
}
- entity.func_223102_j((double)MathHelper.func_76128_c(spreadplayerscommand$position.field_198713_a) + 0.5D, (double)spreadplayerscommand$position.func_198710_a(p_241072_1_, p_241072_3_), (double)MathHelper.func_76128_c(spreadplayerscommand$position.field_198714_b) + 0.5D);
+ net.minecraftforge.event.entity.living.EntityTeleportEvent.SpreadPlayersCommand event = net.minecraftforge.event.ForgeEventFactory.onEntityTeleportSpreadPlayersCommand(entity, (double)MathHelper.func_76128_c(spreadplayerscommand$position.field_198713_a) + 0.5D, (double)spreadplayerscommand$position.func_198710_a(p_241072_1_, p_241072_3_), (double)MathHelper.func_76128_c(spreadplayerscommand$position.field_198714_b) + 0.5D);
+ if (!event.isCanceled()) entity.func_223102_j(event.getTargetX(), event.getTargetY(), event.getTargetZ());
double d2 = Double.MAX_VALUE;
for(SpreadPlayersCommand.Position spreadplayerscommand$position1 : p_241072_2_) {
@@ -1,5 +1,15 @@
--- a/net/minecraft/command/impl/TeleportCommand.java
+++ b/net/minecraft/command/impl/TeleportCommand.java
@@ -121,6 +_,9 @@
}
private static void func_201127_a(CommandSource p_201127_0_, Entity p_201127_1_, ServerWorld p_201127_2_, double p_201127_3_, double p_201127_5_, double p_201127_7_, Set<SPlayerPositionLookPacket.Flags> p_201127_9_, float p_201127_10_, float p_201127_11_, @Nullable TeleportCommand.Facing p_201127_12_) throws CommandSyntaxException {
+ net.minecraftforge.event.entity.living.EntityTeleportEvent.TeleportCommand event = net.minecraftforge.event.ForgeEventFactory.onEntityTeleportCommand(p_201127_1_, p_201127_3_, p_201127_5_, p_201127_7_);
+ if (event.isCanceled()) return;
+ p_201127_3_ = event.getTargetX(); p_201127_5_ = event.getTargetY(); p_201127_7_ = event.getTargetZ();
BlockPos blockpos = new BlockPos(p_201127_3_, p_201127_5_, p_201127_7_);
if (!World.func_234935_k_(blockpos)) {
throw field_241077_a_.create();
@@ -159,7 +_,6 @@
p_201127_1_.func_70012_b(p_201127_3_, p_201127_5_, p_201127_7_, f1, f);
p_201127_1_.func_70034_d(f1);
@@ -1,6 +1,6 @@
--- a/net/minecraft/data/Main.java
+++ b/net/minecraft/data/Main.java
@@ -21,8 +_,13 @@
@@ -21,8 +_,15 @@
OptionSpec<Void> optionspec6 = optionparser.accepts("all", "Include all generators");
OptionSpec<String> optionspec7 = optionparser.accepts("output", "Output folder").withRequiredArg().defaultsTo("generated");
OptionSpec<String> optionspec8 = optionparser.accepts("input", "Input folder").withRequiredArg();
@@ -9,6 +9,8 @@
+ OptionSpec<java.io.File> gameDir = optionparser.accepts("gameDir").withRequiredArg().ofType(java.io.File.class).defaultsTo(new java.io.File(".")).required(); //Need by modlauncher, so lets just eat it
+ OptionSpec<String> mod = optionparser.accepts("mod", "A modid to dump").withRequiredArg().withValuesSeparatedBy(",");
+ OptionSpec<Void> flat = optionparser.accepts("flat", "Do not append modid prefix to output directory when generating for multiple mods");
+ OptionSpec<String> assetIndex = optionparser.accepts("assetIndex").withRequiredArg();
+ OptionSpec<java.io.File> assetsDir = optionparser.accepts("assetsDir").withRequiredArg().ofType(java.io.File.class);
OptionSet optionset = optionparser.parse(p_main_0_);
- if (!optionset.has(optionspec) && optionset.hasOptions()) {
+ if (!optionset.has(optionspec) && optionset.hasOptions() && !(optionset.specs().size() == 1 && optionset.has(gameDir))) {
@@ -28,7 +30,7 @@
+ java.util.Set<String> existingMods = new java.util.HashSet<>(optionset.valuesOf(existingMod));
+ java.util.Set<String> mods = new java.util.HashSet<>(optionset.valuesOf(mod));
+ boolean isFlat = mods.isEmpty() || optionset.has(flat);
+ net.minecraftforge.fml.DatagenModLoader.begin(mods, path, inputs, existingPacks, existingMods, flag2, flag1, flag3, flag4, flag5, isFlat);
+ net.minecraftforge.fml.DatagenModLoader.begin(mods, path, inputs, existingPacks, existingMods, flag2, flag1, flag3, flag4, flag5, isFlat, optionset.valueOf(assetIndex), optionset.valueOf(assetsDir));
+ if (mods.contains("minecraft") || mods.isEmpty())
+ func_200264_a(isFlat ? path : path.resolve("minecraft"), inputs, flag1, flag2, flag3, flag4, flag5).func_200392_c();
} else {
@@ -58,14 +58,6 @@
}
public void func_213301_b(Pose p_213301_1_) {
@@ -330,6 +_,7 @@
public boolean func_233562_a_(Entity p_233562_1_, double p_233562_2_) {
double d0 = p_233562_1_.field_233557_ao_.field_72450_a - this.field_233557_ao_.field_72450_a;
+ if (this.isAddedToWorld() && !this.field_70170_p.field_72995_K && field_70170_p instanceof ServerWorld) ((ServerWorld)this.field_70170_p).func_217464_b(this); // Forge - Process chunk registration after moving.
double d1 = p_233562_1_.field_233557_ao_.field_72448_b - this.field_233557_ao_.field_72448_b;
double d2 = p_233562_1_.field_233557_ao_.field_72449_c - this.field_233557_ao_.field_72449_c;
return d0 * d0 + d1 * d1 + d2 * d2 < p_233562_2_ * p_233562_2_;
@@ -560,7 +_,7 @@
this.field_70140_Q = (float)((double)this.field_70140_Q + (double)MathHelper.func_76133_a(func_213296_b(vector3d)) * 0.6D);
@@ -209,6 +201,15 @@
public boolean func_205710_ba() {
return true;
}
@@ -1948,7 +_,7 @@
this.func_70015_d(8);
}
- this.func_70097_a(DamageSource.field_180137_b, 5.0F);
+ this.func_70097_a(DamageSource.field_180137_b, p_241841_2_.getDamage());
}
public void func_203002_i(boolean p_203002_1_) {
@@ -2032,7 +_,7 @@
}
@@ -0,0 +1,14 @@
--- a/net/minecraft/entity/ICrossbowUser.java
+++ b/net/minecraft/entity/ICrossbowUser.java
@@ -24,9 +_,9 @@
void func_230283_U__();
default void func_234281_b_(LivingEntity p_234281_1_, float p_234281_2_) {
- Hand hand = ProjectileHelper.func_221274_a(p_234281_1_, Items.field_222114_py);
+ Hand hand = ProjectileHelper.getWeaponHoldingHand(p_234281_1_, item -> item instanceof CrossbowItem);
ItemStack itemstack = p_234281_1_.func_184586_b(hand);
- if (p_234281_1_.func_233631_a_(Items.field_222114_py)) {
+ if (p_234281_1_.func_233634_a_(item -> item instanceof CrossbowItem)) {
CrossbowItem.func_220014_a(p_234281_1_.field_70170_p, p_234281_1_, hand, itemstack, p_234281_2_, (float)(14 - p_234281_1_.field_70170_p.func_175659_aa().func_151525_a() * 4));
}
@@ -19,7 +19,7 @@
}
protected void func_184231_a(double p_184231_1_, boolean p_184231_3_, BlockState p_184231_4_, BlockPos p_184231_5_) {
@@ -260,9 +_,10 @@
@@ -260,10 +_,11 @@
if (!this.field_70170_p.field_72995_K && this.field_70143_R > 3.0F && p_184231_3_) {
float f = (float)MathHelper.func_76123_f(this.field_70143_R - 3.0F);
@@ -27,10 +27,12 @@
+ if (!p_184231_4_.isAir(field_70170_p, p_184231_5_)) {
double d0 = Math.min((double)(0.2F + f / 15.0F), 2.5D);
int i = (int)(150.0D * d0);
- ((ServerWorld)this.field_70170_p).func_195598_a(new BlockParticleData(ParticleTypes.field_197611_d, p_184231_4_), this.func_226277_ct_(), this.func_226278_cu_(), this.func_226281_cx_(), i, 0.0D, 0.0D, 0.0D, (double)0.15F);
+ if (!p_184231_4_.addLandingEffects((ServerWorld)this.field_70170_p, p_184231_5_, p_184231_4_, this, i))
((ServerWorld)this.field_70170_p).func_195598_a(new BlockParticleData(ParticleTypes.field_197611_d, p_184231_4_), this.func_226277_ct_(), this.func_226278_cu_(), this.func_226281_cx_(), i, 0.0D, 0.0D, 0.0D, (double)0.15F);
+ ((ServerWorld)this.field_70170_p).func_195598_a(new BlockParticleData(ParticleTypes.field_197611_d, p_184231_4_).setPos(p_184231_5_), this.func_226277_ct_(), this.func_226278_cu_(), this.func_226281_cx_(), i, 0.0D, 0.0D, 0.0D, (double)0.15F);
}
}
@@ -330,7 +_,7 @@
}
}
@@ -0,0 +1,38 @@
--- a/net/minecraft/entity/ai/brain/task/ShootTargetTask.java
+++ b/net/minecraft/entity/ai/brain/task/ShootTargetTask.java
@@ -24,7 +_,7 @@
protected boolean func_212832_a_(ServerWorld p_212832_1_, E p_212832_2_) {
LivingEntity livingentity = func_233887_a_(p_212832_2_);
- return p_212832_2_.func_233631_a_(Items.field_222114_py) && BrainUtil.func_233876_c_(p_212832_2_, livingentity) && BrainUtil.func_233869_a_(p_212832_2_, livingentity, 0);
+ return p_212832_2_.func_233634_a_(item -> item instanceof CrossbowItem) && BrainUtil.func_233876_c_(p_212832_2_, livingentity) && BrainUtil.func_233869_a_(p_212832_2_, livingentity, 0);
}
protected boolean func_212834_g_(ServerWorld p_212834_1_, E p_212834_2_, long p_212834_3_) {
@@ -42,7 +_,7 @@
p_212835_2_.func_184602_cy();
}
- if (p_212835_2_.func_233631_a_(Items.field_222114_py)) {
+ if (p_212835_2_.func_233634_a_(item -> item instanceof CrossbowItem)) {
p_212835_2_.func_213671_a(false);
CrossbowItem.func_220011_a(p_212835_2_.func_184607_cu(), false);
}
@@ -51,7 +_,7 @@
private void func_233888_a_(E p_233888_1_, LivingEntity p_233888_2_) {
if (this.field_233886_c_ == ShootTargetTask.Status.UNCHARGED) {
- p_233888_1_.func_184598_c(ProjectileHelper.func_221274_a(p_233888_1_, Items.field_222114_py));
+ p_233888_1_.func_184598_c(ProjectileHelper.getWeaponHoldingHand(p_233888_1_, item -> item instanceof CrossbowItem));
this.field_233886_c_ = ShootTargetTask.Status.CHARGING;
p_233888_1_.func_213671_a(true);
} else if (this.field_233886_c_ == ShootTargetTask.Status.CHARGING) {
@@ -74,7 +_,7 @@
}
} else if (this.field_233886_c_ == ShootTargetTask.Status.READY_TO_ATTACK) {
p_233888_1_.func_82196_d(p_233888_2_, 1.0F);
- ItemStack itemstack1 = p_233888_1_.func_184586_b(ProjectileHelper.func_221274_a(p_233888_1_, Items.field_222114_py));
+ ItemStack itemstack1 = p_233888_1_.func_184586_b(ProjectileHelper.getWeaponHoldingHand(p_233888_1_, item -> item instanceof CrossbowItem));
CrossbowItem.func_220011_a(itemstack1, false);
this.field_233886_c_ = ShootTargetTask.Status.UNCHARGED;
}
@@ -9,3 +9,12 @@
}
public boolean func_75253_b() {
@@ -117,7 +_,7 @@
}
}
} else if (--this.field_188503_e <= 0 && this.field_188504_f >= -60) {
- this.field_188499_a.func_184598_c(ProjectileHelper.func_221274_a(this.field_188499_a, Items.field_151031_f));
+ this.field_188499_a.func_184598_c(ProjectileHelper.getWeaponHoldingHand(this.field_188499_a, item -> item instanceof BowItem));
}
}
@@ -0,0 +1,29 @@
--- a/net/minecraft/entity/ai/goal/RangedCrossbowAttackGoal.java
+++ b/net/minecraft/entity/ai/goal/RangedCrossbowAttackGoal.java
@@ -33,7 +_,7 @@
}
private boolean func_220745_g() {
- return this.field_220748_a.func_233631_a_(Items.field_222114_py);
+ return this.field_220748_a.func_233634_a_(item -> item instanceof CrossbowItem);
}
public boolean func_75253_b() {
@@ -88,7 +_,7 @@
this.field_220748_a.func_70671_ap().func_75651_a(livingentity, 30.0F, 30.0F);
if (this.field_220749_b == RangedCrossbowAttackGoal.CrossbowState.UNCHARGED) {
if (!flag2) {
- this.field_220748_a.func_184598_c(ProjectileHelper.func_221274_a(this.field_220748_a, Items.field_222114_py));
+ this.field_220748_a.func_184598_c(ProjectileHelper.getWeaponHoldingHand(this.field_220748_a, item -> item instanceof CrossbowItem));
this.field_220749_b = RangedCrossbowAttackGoal.CrossbowState.CHARGING;
this.field_220748_a.func_213671_a(true);
}
@@ -112,7 +_,7 @@
}
} else if (this.field_220749_b == RangedCrossbowAttackGoal.CrossbowState.READY_TO_ATTACK && flag) {
this.field_220748_a.func_82196_d(livingentity, 1.0F);
- ItemStack itemstack1 = this.field_220748_a.func_184586_b(ProjectileHelper.func_221274_a(this.field_220748_a, Items.field_222114_py));
+ ItemStack itemstack1 = this.field_220748_a.func_184586_b(ProjectileHelper.getWeaponHoldingHand(this.field_220748_a, item -> item instanceof CrossbowItem));
CrossbowItem.func_220011_a(itemstack1, false);
this.field_220749_b = RangedCrossbowAttackGoal.CrossbowState.UNCHARGED;
}
@@ -1,5 +1,28 @@
--- a/net/minecraft/entity/effect/LightningBoltEntity.java
+++ b/net/minecraft/entity/effect/LightningBoltEntity.java
@@ -30,6 +_,7 @@
private boolean field_184529_d;
@Nullable
private ServerPlayerEntity field_204810_e;
+ private float damage = 5.0F;
public LightningBoltEntity(EntityType<? extends LightningBoltEntity> p_i231491_1_, World p_i231491_2_) {
super(p_i231491_1_, p_i231491_2_);
@@ -51,6 +_,14 @@
this.field_204810_e = p_204809_1_;
}
+ public void setDamage(float damage){
+ this.damage = damage;
+ }
+
+ public float getDamage(){
+ return this.damage;
+ }
+
public void func_70071_h_() {
super.func_70071_h_();
if (this.field_70262_b == 2) {
@@ -83,6 +_,7 @@
List<Entity> list = this.field_70170_p.func_175674_a(this, new AxisAlignedBB(this.func_226277_ct_() - 3.0D, this.func_226278_cu_() - 3.0D, this.func_226281_cx_() - 3.0D, this.func_226277_ct_() + 3.0D, this.func_226278_cu_() + 6.0D + 3.0D, this.func_226281_cx_() + 3.0D), Entity::func_70089_S);
@@ -4,8 +4,8 @@
if (entity instanceof ServerPlayerEntity) {
ServerPlayerEntity serverplayerentity = (ServerPlayerEntity)entity;
if (serverplayerentity.field_71135_a.func_147298_b().func_150724_d() && serverplayerentity.field_70170_p == this.field_70170_p && !serverplayerentity.func_70608_bn()) {
+ net.minecraftforge.event.entity.living.EnderTeleportEvent event = new net.minecraftforge.event.entity.living.EnderTeleportEvent(serverplayerentity, this.func_226277_ct_(), this.func_226278_cu_(), this.func_226281_cx_(), 5.0F);
+ if (!net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) { // Don't indent to lower patch size
+ net.minecraftforge.event.entity.living.EntityTeleportEvent.EnderPearl event = net.minecraftforge.event.ForgeEventFactory.onEnderPearlLand(serverplayerentity, this.func_226277_ct_(), this.func_226278_cu_(), this.func_226281_cx_(), this, 5.0F);
+ if (!event.isCanceled()) { // Don't indent to lower patch size
if (this.field_70146_Z.nextFloat() < 0.05F && this.field_70170_p.func_82736_K().func_223586_b(GameRules.field_223601_d)) {
EndermiteEntity endermiteentity = EntityType.field_200804_r.func_200721_a(this.field_70170_p);
endermiteentity.func_175496_a(true);
@@ -9,6 +9,14 @@
private static final DataParameter<Integer> field_184265_a = EntityDataManager.func_187226_a(AbstractMinecartEntity.class, DataSerializers.field_187192_b);
private static final DataParameter<Integer> field_184266_b = EntityDataManager.func_187226_a(AbstractMinecartEntity.class, DataSerializers.field_187192_b);
private static final DataParameter<Float> field_184267_c = EntityDataManager.func_187226_a(AbstractMinecartEntity.class, DataSerializers.field_187193_c);
@@ -77,6 +_,7 @@
p_226574_0_.put(RailShape.NORTH_WEST, Pair.of(vector3i2, vector3i));
p_226574_0_.put(RailShape.NORTH_EAST, Pair.of(vector3i2, vector3i1));
});
+ private static net.minecraftforge.common.IMinecartCollisionHandler COLLISIONS = null;
private int field_70510_h;
private double field_70511_i;
private double field_70509_j;
@@ -89,6 +_,7 @@
private double field_70507_ar;
@OnlyIn(Dist.CLIENT)
@@ -17,6 +25,21 @@
protected AbstractMinecartEntity(EntityType<?> p_i48538_1_, World p_i48538_2_) {
super(p_i48538_1_, p_i48538_2_);
@@ -103,6 +_,14 @@
this.field_70167_r = p_i48539_5_;
this.field_70166_s = p_i48539_7_;
}
+
+ public net.minecraftforge.common.IMinecartCollisionHandler getCollisionHandler() {
+ return COLLISIONS;
+ }
+
+ public static void registerCollisionHandler(@Nullable net.minecraftforge.common.IMinecartCollisionHandler handler) {
+ COLLISIONS = handler;
+ }
public static AbstractMinecartEntity func_184263_a(World p_184263_0_, double p_184263_1_, double p_184263_3_, double p_184263_5_, AbstractMinecartEntity.Type p_184263_7_) {
if (p_184263_7_ == AbstractMinecartEntity.Type.CHEST) {
@@ -138,7 +_,7 @@
}
@@ -1,5 +1,17 @@
--- a/net/minecraft/entity/item/minecart/FurnaceMinecartEntity.java
+++ b/net/minecraft/entity/item/minecart/FurnaceMinecartEntity.java
@@ -72,6 +_,11 @@
return 0.2D;
}
+ @Override
+ public float getMaxCartSpeedOnRail() {
+ return 0.2f;
+ }
+
public void func_94095_a(DamageSource p_94095_1_) {
super.func_94095_a(p_94095_1_);
if (!p_94095_1_.func_94541_c() && this.field_70170_p.func_82736_K().func_223586_b(GameRules.field_223604_g)) {
@@ -111,6 +_,8 @@
}
@@ -1,8 +1,20 @@
--- a/net/minecraft/entity/monster/AbstractSkeletonEntity.java
+++ b/net/minecraft/entity/monster/AbstractSkeletonEntity.java
@@ -173,6 +_,8 @@
@@ -154,7 +_,7 @@
if (this.field_70170_p != null && !this.field_70170_p.field_72995_K) {
this.field_70714_bg.func_85156_a(this.field_85038_e);
this.field_70714_bg.func_85156_a(this.field_85037_d);
- ItemStack itemstack = this.func_184586_b(ProjectileHelper.func_221274_a(this, Items.field_151031_f));
+ ItemStack itemstack = this.func_184586_b(ProjectileHelper.getWeaponHoldingHand(this, item -> item instanceof net.minecraft.item.BowItem));
if (itemstack.func_77973_b() == Items.field_151031_f) {
int i = 20;
if (this.field_70170_p.func_175659_aa() != Difficulty.HARD) {
@@ -171,8 +_,10 @@
}
public void func_82196_d(LivingEntity p_82196_1_, float p_82196_2_) {
ItemStack itemstack = this.func_213356_f(this.func_184586_b(ProjectileHelper.func_221274_a(this, Items.field_151031_f)));
- ItemStack itemstack = this.func_213356_f(this.func_184586_b(ProjectileHelper.func_221274_a(this, Items.field_151031_f)));
+ ItemStack itemstack = this.func_213356_f(this.func_184586_b(ProjectileHelper.getWeaponHoldingHand(this, item -> item instanceof net.minecraft.item.BowItem)));
AbstractArrowEntity abstractarrowentity = this.func_213624_b(itemstack, p_82196_2_);
+ if (this.func_184614_ca().func_77973_b() instanceof net.minecraft.item.BowItem)
+ abstractarrowentity = ((net.minecraft.item.BowItem)this.func_184614_ca().func_77973_b()).customArrow(abstractarrowentity);
@@ -36,8 +36,8 @@
boolean flag1 = blockstate.func_204520_s().func_206884_a(FluidTags.field_206959_a);
if (flag && !flag1) {
- boolean flag2 = this.func_213373_a(p_70825_1_, p_70825_3_, p_70825_5_, true);
+ net.minecraftforge.event.entity.living.EnderTeleportEvent event = new net.minecraftforge.event.entity.living.EnderTeleportEvent(this, p_70825_1_, p_70825_3_, p_70825_5_, 0);
+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) return false;
+ net.minecraftforge.event.entity.living.EntityTeleportEvent.EnderEntity event = net.minecraftforge.event.ForgeEventFactory.onEnderTeleport(this, p_70825_1_, p_70825_3_, p_70825_5_);
+ if (event.isCanceled()) return false;
+ boolean flag2 = this.func_213373_a(event.getTargetX(), event.getTargetY(), event.getTargetZ(), true);
if (flag2 && !this.func_174814_R()) {
this.field_70170_p.func_184148_a((PlayerEntity)null, this.field_70169_q, this.field_70167_r, this.field_70166_s, SoundEvents.field_187534_aX, this.func_184176_by(), 1.0F, 1.0F);
@@ -1,8 +1,11 @@
--- a/net/minecraft/entity/monster/IllusionerEntity.java
+++ b/net/minecraft/entity/monster/IllusionerEntity.java
@@ -182,6 +_,8 @@
@@ -180,8 +_,10 @@
}
public void func_82196_d(LivingEntity p_82196_1_, float p_82196_2_) {
ItemStack itemstack = this.func_213356_f(this.func_184586_b(ProjectileHelper.func_221274_a(this, Items.field_151031_f)));
- ItemStack itemstack = this.func_213356_f(this.func_184586_b(ProjectileHelper.func_221274_a(this, Items.field_151031_f)));
+ ItemStack itemstack = this.func_213356_f(this.func_184586_b(ProjectileHelper.getWeaponHoldingHand(this, item -> item instanceof net.minecraft.item.BowItem)));
AbstractArrowEntity abstractarrowentity = ProjectileHelper.func_221272_a(this, itemstack, p_82196_2_);
+ if (this.func_184614_ca().func_77973_b() instanceof net.minecraft.item.BowItem)
+ abstractarrowentity = ((net.minecraft.item.BowItem)this.func_184614_ca().func_77973_b()).customArrow(abstractarrowentity);
@@ -0,0 +1,11 @@
--- a/net/minecraft/entity/monster/PillagerEntity.java
+++ b/net/minecraft/entity/monster/PillagerEntity.java
@@ -120,7 +_,7 @@
public AbstractIllagerEntity.ArmPose func_193077_p() {
if (this.func_213675_dX()) {
return AbstractIllagerEntity.ArmPose.CROSSBOW_CHARGE;
- } else if (this.func_233631_a_(Items.field_222114_py)) {
+ } else if (this.func_233634_a_(item -> item instanceof net.minecraft.item.CrossbowItem)) {
return AbstractIllagerEntity.ArmPose.CROSSBOW_HOLD;
} else {
return this.func_213398_dR() ? AbstractIllagerEntity.ArmPose.ATTACKING : AbstractIllagerEntity.ArmPose.NEUTRAL;
@@ -30,9 +30,9 @@
if (blockpos1.func_177956_o() > 0 && this.field_70170_p.func_175623_d(blockpos1) && this.field_70170_p.func_175723_af().func_177746_a(blockpos1) && this.field_70170_p.func_226665_a__(this, new AxisAlignedBB(blockpos1))) {
Direction direction = this.func_234299_g_(blockpos1);
+ if (direction != null) {
+ net.minecraftforge.event.entity.living.EnderTeleportEvent event = new net.minecraftforge.event.entity.living.EnderTeleportEvent(this, blockpos1.func_177958_n(), blockpos1.func_177956_o(), blockpos1.func_177952_p(), 0);
+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) direction = null;
+ blockpos1 = new BlockPos(event.getTargetX(), event.getTargetY(), event.getTargetZ());
+ net.minecraftforge.event.entity.living.EntityTeleportEvent.EnderEntity event = net.minecraftforge.event.ForgeEventFactory.onEnderTeleport(this, blockpos1.func_177958_n(), blockpos1.func_177956_o(), blockpos1.func_177952_p());
+ if (event.isCanceled()) direction = null;
+ blockpos1 = new BlockPos(event.getTargetX(), event.getTargetY(), event.getTargetZ());
+ }
+
if (direction != null) {
@@ -1,5 +1,14 @@
--- a/net/minecraft/entity/monster/piglin/PiglinEntity.java
+++ b/net/minecraft/entity/monster/piglin/PiglinEntity.java
@@ -265,7 +_,7 @@
} else if (this.func_234433_eX_()) {
return PiglinAction.CROSSBOW_CHARGE;
} else {
- return this.func_213398_dR() && this.func_233631_a_(Items.field_222114_py) ? PiglinAction.CROSSBOW_HOLD : PiglinAction.DEFAULT;
+ return this.func_213398_dR() && this.func_233634_a_(item -> item instanceof net.minecraft.item.CrossbowItem) ? PiglinAction.CROSSBOW_HOLD : PiglinAction.DEFAULT;
}
}
@@ -307,7 +_,7 @@
}
@@ -9,3 +18,12 @@
this.func_184201_a(EquipmentSlotType.OFFHAND, p_234439_1_);
this.func_233663_d_(EquipmentSlotType.OFFHAND);
} else {
@@ -317,7 +_,7 @@
}
public boolean func_230293_i_(ItemStack p_230293_1_) {
- return this.field_70170_p.func_82736_K().func_223586_b(GameRules.field_223599_b) && this.func_98052_bS() && PiglinTasks.func_234474_a_(this, p_230293_1_);
+ return net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.field_70170_p, this) && this.func_98052_bS() && PiglinTasks.func_234474_a_(this, p_230293_1_);
}
protected boolean func_234440_o_(ItemStack p_234440_1_) {
@@ -36,3 +36,12 @@
return true;
}
}
@@ -673,7 +_,7 @@
}
private static boolean func_234494_c_(LivingEntity p_234494_0_) {
- return p_234494_0_.func_233631_a_(Items.field_222114_py);
+ return p_234494_0_.func_233634_a_(item -> item instanceof net.minecraft.item.CrossbowItem);
}
private static void func_234501_d_(LivingEntity p_234501_0_) {
@@ -23,7 +23,7 @@
public static AttributeModifierMap.MutableAttribute func_234570_el_() {
- return LivingEntity.func_233639_cI_().func_233815_a_(Attributes.field_233823_f_, 1.0D).func_233815_a_(Attributes.field_233821_d_, (double)0.1F).func_233814_a_(Attributes.field_233825_h_).func_233814_a_(Attributes.field_233828_k_);
+ return LivingEntity.func_233639_cI_().func_233815_a_(Attributes.field_233823_f_, 1.0D).func_233815_a_(Attributes.field_233821_d_, (double)0.1F).func_233814_a_(Attributes.field_233825_h_).func_233814_a_(Attributes.field_233828_k_).func_233814_a_(net.minecraftforge.common.ForgeMod.REACH_DISTANCE.get());
+ return LivingEntity.func_233639_cI_().func_233815_a_(Attributes.field_233823_f_, 1.0D).func_233815_a_(Attributes.field_233821_d_, (double)0.1F).func_233814_a_(Attributes.field_233825_h_).func_233814_a_(Attributes.field_233828_k_).func_233814_a_(net.minecraftforge.common.ForgeMod.REACH_DISTANCE.get()).func_233814_a_(Attributes.field_233824_g_);
}
protected void func_70088_a() {
@@ -163,6 +163,16 @@
float f = p_70665_2_ - f2;
if (f > 0.0F && f < 3.4028235E37F) {
this.func_195067_a(Stats.field_212738_J, Math.round(f * 10.0F));
@@ -859,8 +_,8 @@
if (f2 != 0.0F) {
this.func_71020_j(p_70665_1_.func_76345_d());
float f1 = this.func_110143_aJ();
- this.func_70606_j(this.func_110143_aJ() - f2);
this.func_110142_aN().func_94547_a(p_70665_1_, f1, f2);
+ this.func_70606_j(f1 - f2); // Forge: moved to fix MC-121048
if (f2 < 3.4028235E37F) {
this.func_195067_a(Stats.field_188112_z, Math.round(f2 * 10.0F));
}
@@ -909,6 +_,8 @@
return ActionResultType.PASS;
@@ -198,6 +208,15 @@
if (p_71059_1_.func_70075_an()) {
if (!p_71059_1_.func_85031_j(this)) {
float f = (float)this.func_233637_b_(Attributes.field_233823_f_);
@@ -1028,7 +_,7 @@
if (f > 0.0F || f1 > 0.0F) {
boolean flag = f2 > 0.9F;
boolean flag1 = false;
- int i = 0;
+ float i = (float)this.func_233637_b_(Attributes.field_233824_g_); // Forge: Initialize this value to the attack knockback attribute of the player, which is by default 0
i = i + EnchantmentHelper.func_77501_a(this);
if (this.func_70051_ag() && flag) {
this.field_70170_p.func_184148_a((PlayerEntity)null, this.func_226277_ct_(), this.func_226278_cu_(), this.func_226281_cx_(), SoundEvents.field_187721_dT, this.func_184176_by(), 1.0F, 1.0F);
@@ -1038,8 +_,10 @@
boolean flag2 = flag && this.field_70143_R > 0.0F && !this.field_70122_E && !this.func_70617_f_() && !this.func_70090_H() && !this.func_70644_a(Effects.field_76440_q) && !this.func_184218_aH() && p_71059_1_ instanceof LivingEntity;
@@ -257,17 +276,15 @@
super.func_213366_dy();
if (this.field_70170_p instanceof ServerWorld && p_225652_2_) {
((ServerWorld)this.field_70170_p).func_72854_c();
@@ -1242,8 +_,8 @@
}
return optional;
- } else if (block instanceof BedBlock && BedBlock.func_235330_a_(p_242374_0_)) {
- return BedBlock.func_242652_a(EntityType.field_200729_aH, p_242374_0_, p_242374_1_, p_242374_2_);
+ } else if (blockstate.isBed(p_242374_0_, p_242374_1_, null) && BedBlock.func_235330_a_(p_242374_0_)) {
+ return blockstate.getBedSpawnPosition(EntityType.field_200729_aH, p_242374_0_, p_242374_1_, p_242374_2_, null);
@@ -1245,7 +_,7 @@
} else if (block instanceof BedBlock && BedBlock.func_235330_a_(p_242374_0_)) {
return BedBlock.func_242652_a(EntityType.field_200729_aH, p_242374_0_, p_242374_1_, p_242374_2_);
} else if (!p_242374_3_) {
return Optional.empty();
- return Optional.empty();
+ return blockstate.getRespawnPosition(EntityType.field_200729_aH, p_242374_0_, p_242374_1_, p_242374_2_, null);
} else {
boolean flag = block.func_181623_g();
boolean flag1 = p_242374_0_.func_180495_p(p_242374_1_.func_177984_a()).func_177230_c().func_181623_g();
@@ -1425,6 +_,7 @@
public boolean func_225503_b_(float p_225503_1_, float p_225503_2_) {
@@ -150,6 +150,19 @@
}
public ChatVisibility func_147096_v() {
@@ -1276,7 +_,11 @@
@Nullable
public ITextComponent func_175396_E() {
- return null;
+ if (!this.hasTabListName) {
+ this.tabListDisplayName = net.minecraftforge.event.ForgeEventFactory.getPlayerTabListDisplayName(this);
+ this.hasTabListName = true;
+ }
+ return this.tabListDisplayName;
}
public void func_184609_a(Hand p_184609_1_) {
@@ -1301,14 +_,14 @@
this.func_184210_p();
if (p_200619_1_ == this.field_70170_p) {
@@ -193,10 +206,11 @@
this.field_70170_p.func_217376_c(itementity);
ItemStack itemstack = itementity.func_92059_d();
if (p_146097_3_) {
@@ -1403,6 +_,15 @@
@@ -1402,6 +_,29 @@
}
return itementity;
}
+ }
+ }
+
+ private String language = "en_us";
@@ -206,6 +220,19 @@
+ */
+ public String getLanguage() {
+ return this.language;
+ }
+
+ // We need this as tablistDisplayname may be null even if the the event was fired.
+ private boolean hasTabListName = false;
+ private ITextComponent tabListDisplayName = null;
+ /**
+ * Force the name displayed in the tab list to refresh, by firing {@link net.minecraftforge.event.entity.player.PlayerEvent.TabListNameFormat}.
+ */
+ public void refreshTabListName() {
+ ITextComponent oldName = this.tabListDisplayName;
+ this.tabListDisplayName = net.minecraftforge.event.ForgeEventFactory.getPlayerTabListDisplayName(this);
+ if (!java.util.Objects.equals(oldName, this.tabListDisplayName)) {
+ this.func_184102_h().func_184103_al().func_148540_a(new net.minecraft.network.play.server.SPlayerListItemPacket(net.minecraft.network.play.server.SPlayerListItemPacket.Action.UPDATE_DISPLAY_NAME, this));
}
}
@Nullable
@@ -1,5 +1,14 @@
--- a/net/minecraft/entity/projectile/FishingBobberEntity.java
+++ b/net/minecraft/entity/projectile/FishingBobberEntity.java
@@ -245,7 +_,7 @@
private void func_190624_r() {
RayTraceResult raytraceresult = ProjectileHelper.func_234618_a_(this, this::func_230298_a_);
- this.func_70227_a(raytraceresult);
+ if (raytraceresult.func_216346_c() == RayTraceResult.Type.MISS || !net.minecraftforge.event.ForgeEventFactory.onProjectileImpact(this, raytraceresult)) this.func_70227_a(raytraceresult);
}
protected boolean func_230298_a_(Entity p_230298_1_) {
@@ -300,7 +_,7 @@
double d1 = (double)((float)MathHelper.func_76128_c(this.func_226278_cu_()) + 1.0F);
double d2 = this.func_226281_cx_() + (double)(f2 * (float)this.field_146038_az * 0.1F);
@@ -9,3 +9,18 @@
if (d0 == 0.0D) {
entity = entity1;
vector3d = vector3d1;
@@ -123,8 +_,14 @@
}
}
+ @Deprecated // Forge: Use the version below that takes in a Predicate<Item> instead of an Item
public static Hand func_221274_a(LivingEntity p_221274_0_, Item p_221274_1_) {
return p_221274_0_.func_184614_ca().func_77973_b() == p_221274_1_ ? Hand.MAIN_HAND : Hand.OFF_HAND;
+ }
+
+ public static Hand getWeaponHoldingHand(LivingEntity livingEntity, Predicate<Item> itemPredicate)
+ {
+ return itemPredicate.test(livingEntity.func_184614_ca().func_77973_b()) ? Hand.MAIN_HAND : Hand.OFF_HAND;
}
public static AbstractArrowEntity func_221272_a(LivingEntity p_221272_0_, ItemStack p_221272_1_, float p_221272_2_) {
@@ -5,7 +5,7 @@
if (!this.field_70170_p.field_72995_K) {
Entity entity = this.func_234616_v_();
- if (entity == null || !(entity instanceof MobEntity) || this.field_70170_p.func_82736_K().func_223586_b(GameRules.field_223599_b)) {
+ if (entity == null || !(entity instanceof MobEntity) || this.field_70170_p.func_82736_K().func_223586_b(GameRules.field_223599_b) || net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.field_70170_p, this.getEntity())) {
+ if (entity == null || !(entity instanceof MobEntity) || net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.field_70170_p, this.getEntity())) {
BlockPos blockpos = p_230299_1_.func_216350_a().func_177972_a(p_230299_1_.func_216354_b());
if (this.field_70170_p.func_175623_d(blockpos)) {
this.field_70170_p.func_175656_a(blockpos, AbstractFireBlock.func_235326_a_(this.field_70170_p, blockpos));
@@ -0,0 +1,11 @@
--- a/net/minecraft/inventory/container/AbstractFurnaceContainer.java
+++ b/net/minecraft/inventory/container/AbstractFurnaceContainer.java
@@ -150,7 +_,7 @@
}
protected boolean func_217058_b(ItemStack p_217058_1_) {
- return AbstractFurnaceTileEntity.func_213991_b(p_217058_1_);
+ return net.minecraftforge.common.ForgeHooks.getBurnTime(p_217058_1_, this.field_217065_f) > 0;
}
@OnlyIn(Dist.CLIENT)
@@ -0,0 +1,13 @@
--- a/net/minecraft/item/ChorusFruitItem.java
+++ b/net/minecraft/item/ChorusFruitItem.java
@@ -29,7 +_,9 @@
p_77654_3_.func_184210_p();
}
- if (p_77654_3_.func_213373_a(d3, d4, d5, true)) {
+ net.minecraftforge.event.entity.living.EntityTeleportEvent.ChorusFruit event = net.minecraftforge.event.ForgeEventFactory.onChorusFruitTeleport(p_77654_3_, d3, d4, d5);
+ if (event.isCanceled()) return itemstack;
+ if (p_77654_3_.func_213373_a(event.getTargetX(), event.getTargetY(), event.getTargetZ(), true)) {
SoundEvent soundevent = p_77654_3_ instanceof FoxEntity ? SoundEvents.field_232710_ez_ : SoundEvents.field_187544_ad;
p_77654_2_.func_184148_a((PlayerEntity)null, d0, d1, d2, soundevent, SoundCategory.PLAYERS, 1.0F, 1.0F);
p_77654_3_.func_184185_a(soundevent, 1.0F, 1.0F);
@@ -0,0 +1,24 @@
--- a/net/minecraft/network/NettyCompressionEncoder.java
+++ b/net/minecraft/network/NettyCompressionEncoder.java
@@ -9,6 +_,8 @@
private final byte[] field_179302_a = new byte[8192];
private final Deflater field_179300_b;
private int field_179301_c;
+ private static final boolean DISABLE_PACKET_DEBUG = Boolean.parseBoolean(System.getProperty("forge.disablePacketCompressionDebug", "false"));
+ private static final org.apache.logging.log4j.Logger LOGGER = org.apache.logging.log4j.LogManager.getLogger();
public NettyCompressionEncoder(int p_i46005_1_) {
this.field_179301_c = p_i46005_1_;
@@ -22,6 +_,12 @@
packetbuffer.func_150787_b(0);
packetbuffer.writeBytes(p_encode_2_);
} else {
+ if (!DISABLE_PACKET_DEBUG && i > 2097152) {
+ p_encode_2_.markReaderIndex();
+ LOGGER.error("Attempted to send packet over maximum protocol size: {} > 2097152\nData:\n{}", i,
+ net.minecraftforge.fml.common.network.ByteBufUtils.getContentDump(p_encode_2_));
+ p_encode_2_.resetReaderIndex();
+ }
byte[] abyte = new byte[i];
p_encode_2_.readBytes(abyte);
packetbuffer.func_150787_b(abyte.length);
@@ -1,15 +1,15 @@
--- a/net/minecraft/network/PacketBuffer.java
+++ b/net/minecraft/network/PacketBuffer.java
@@ -39,7 +_,7 @@
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@@ -37,7 +_,7 @@
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.text.ITextComponent;
-public class PacketBuffer extends ByteBuf {
+public class PacketBuffer extends ByteBuf implements net.minecraftforge.common.extensions.IForgePacketBuffer {
private final ByteBuf field_150794_a;
public PacketBuffer(ByteBuf p_i45154_1_) {
@@ -292,6 +_,15 @@
@@ -287,6 +_,15 @@
}
public PacketBuffer func_150788_a(ItemStack p_150788_1_) {
@@ -25,7 +25,7 @@
if (p_150788_1_.func_190926_b()) {
this.writeBoolean(false);
} else {
@@ -300,8 +_,8 @@
@@ -295,8 +_,8 @@
this.func_150787_b(Item.func_150891_b(item));
this.writeByte(p_150788_1_.func_190916_E());
CompoundNBT compoundnbt = null;
@@ -36,7 +36,7 @@
}
this.func_150786_a(compoundnbt);
@@ -317,7 +_,7 @@
@@ -312,7 +_,7 @@
int i = this.func_150792_a();
int j = this.readByte();
ItemStack itemstack = new ItemStack(Item.func_150899_d(i), j);
@@ -55,11 +55,11 @@
- static class MixPredicate<T> {
- private final T field_185198_a;
+ static class MixPredicate<T extends net.minecraftforge.registries.ForgeRegistryEntry<T>> {
+ private final net.minecraftforge.registries.IRegistryDelegate<T> field_185198_a;
+ public static class MixPredicate<T extends net.minecraftforge.registries.ForgeRegistryEntry<T>> {
+ public final net.minecraftforge.registries.IRegistryDelegate<T> field_185198_a;
private final Ingredient field_185199_b;
- private final T field_185200_c;
+ private final net.minecraftforge.registries.IRegistryDelegate<T> field_185200_c;
+ public final net.minecraftforge.registries.IRegistryDelegate<T> field_185200_c;
public MixPredicate(T p_i47570_1_, Ingredient p_i47570_2_, T p_i47570_3_) {
- this.field_185198_a = p_i47570_1_;
@@ -15,7 +15,7 @@
return this.field_198988_b.get(p_198981_1_);
+ }
+
+ public void addPackFinder(IPackFinder packFinder) {
+ public synchronized void addPackFinder(IPackFinder packFinder) {
+ this.field_198987_a.add(packFinder);
}
@@ -106,6 +106,19 @@
if (flag2) {
serverplayerentity.field_71135_a.func_147359_a(new SPlaySoundEffectPacket(SoundEvents.field_232818_ms_, SoundCategory.BLOCKS, (double)blockpos.func_177958_n(), (double)blockpos.func_177956_o(), (double)blockpos.func_177952_p(), 1.0F, 1.0F));
}
@@ -745,12 +_,6 @@
if (serverstatisticsmanager == null) {
File file1 = this.field_72400_f.func_240776_a_(FolderName.field_237246_b_).toFile();
File file2 = new File(file1, uuid + ".json");
- if (!file2.exists()) {
- File file3 = new File(file1, p_152602_1_.func_200200_C_().getString() + ".json");
- if (file3.exists() && file3.isFile()) {
- file3.renameTo(file2);
- }
- }
serverstatisticsmanager = new ServerStatisticsManager(this.field_72400_f, file2);
this.field_148547_k.put(uuid, serverstatisticsmanager);
@@ -769,6 +_,8 @@
this.field_192055_p.put(uuid, playeradvancements);
}
@@ -56,6 +56,15 @@
}
}
}
@@ -270,7 +_,7 @@
protected boolean func_214008_b(@Nullable IRecipe<?> p_214008_1_) {
if (!this.field_214012_a.get(0).func_190926_b() && p_214008_1_ != null) {
- ItemStack itemstack = p_214008_1_.func_77571_b();
+ ItemStack itemstack = ((IRecipe<ISidedInventory>) p_214008_1_).func_77572_b(this);
if (itemstack.func_190926_b()) {
return false;
} else {
@@ -279,10 +_,10 @@
return true;
} else if (!itemstack1.func_77969_a(itemstack)) {
@@ -69,7 +78,13 @@
}
}
} else {
@@ -298,7 +_,7 @@
@@ -293,12 +_,12 @@
private void func_214007_c(@Nullable IRecipe<?> p_214007_1_) {
if (p_214007_1_ != null && this.func_214008_b(p_214007_1_)) {
ItemStack itemstack = this.field_214012_a.get(0);
- ItemStack itemstack1 = p_214007_1_.func_77571_b();
+ ItemStack itemstack1 = ((IRecipe<ISidedInventory>) p_214007_1_).func_77572_b(this);
ItemStack itemstack2 = this.field_214012_a.get(2);
if (itemstack2.func_190926_b()) {
this.field_214012_a.set(2, itemstack1.func_77946_l());
} else if (itemstack2.func_77973_b() == itemstack1.func_77973_b()) {
@@ -83,7 +98,7 @@
} else {
Item item = p_213997_1_.func_77973_b();
- return func_214001_f().getOrDefault(item, 0);
+ return net.minecraftforge.common.ForgeHooks.getBurnTime(p_213997_1_);
+ return net.minecraftforge.common.ForgeHooks.getBurnTime(p_213997_1_, this.field_214014_c);
}
}
@@ -92,10 +107,19 @@
public static boolean func_213991_b(ItemStack p_213991_0_) {
- return func_214001_f().containsKey(p_213991_0_.func_77973_b());
+ return net.minecraftforge.common.ForgeHooks.getBurnTime(p_213991_0_) > 0;
+ return net.minecraftforge.common.ForgeHooks.getBurnTime(p_213991_0_, null) > 0;
}
public int[] func_180463_a(Direction p_180463_1_) {
@@ -410,7 +_,7 @@
return true;
} else {
ItemStack itemstack = this.field_214012_a.get(1);
- return func_213991_b(p_94041_2_) || p_94041_2_.func_77973_b() == Items.field_151133_ar && itemstack.func_77973_b() != Items.field_151133_ar;
+ return net.minecraftforge.common.ForgeHooks.getBurnTime(p_94041_2_, this.field_214014_c) > 0 || p_94041_2_.func_77973_b() == Items.field_151133_ar && itemstack.func_77973_b() != Items.field_151133_ar;
}
}
@@ -473,5 +_,28 @@
p_194018_1_.func_194112_a(itemstack);
}
@@ -1,5 +1,23 @@
--- a/net/minecraft/world/gen/FlatGenerationSettings.java
+++ b/net/minecraft/world/gen/FlatGenerationSettings.java
@@ -147,8 +_,16 @@
biomegenerationsettings$builder.func_242513_a(GenerationStage.Decoration.LAKES, Features.field_243790_P);
}
+ Map<Structure<?>, StructureFeature<?, ?>> map = new java.util.HashMap<>(field_202247_j);
+ net.minecraft.util.registry.WorldGenRegistries.field_243654_f.func_201756_e().filter(f -> !map.containsKey(f.field_236268_b_)).forEach(f -> map.put(f.field_236268_b_, f));
for(Entry<Structure<?>, StructureSeparationSettings> entry : this.field_236933_f_.func_236195_a_().entrySet()) {
- biomegenerationsettings$builder.func_242516_a(biomegenerationsettings.func_242491_a(field_202247_j.get(entry.getKey())));
+ if (!map.containsKey(entry.getKey())) {
+ field_211404_q.error("FORGE: There's no known StructureFeature for {} when preparing the {} flatworld biome." +
+ " The structure will be skipped and may not spawn." +
+ " Please register your StructureFeatures in the WorldGenRegistries!", entry.getKey().func_143025_a(), biome.getRegistryName());
+ continue;
+ }
+ biomegenerationsettings$builder.func_242516_a(biomegenerationsettings.func_242491_a(map.get(entry.getKey())));
}
boolean flag = (!this.field_202245_D || this.field_242867_d.func_230519_c_(biome).equals(Optional.of(Biomes.field_185440_P))) && this.field_236934_k_;
@@ -174,7 +_,7 @@
}
}
@@ -1,5 +1,13 @@
--- a/net/minecraft/world/server/ChunkHolder.java
+++ b/net/minecraft/world/server/ChunkHolder.java
@@ -61,6 +_,7 @@
private final ChunkHolder.IPlayerProvider field_219328_w;
private boolean field_219329_x;
private boolean field_244384_x;
+ Chunk currentlyLoading; //Forge - Used to bypass future chain when loading chunks.
public ChunkHolder(ChunkPos p_i50716_1_, int p_i50716_2_, WorldLightManager p_i50716_3_, ChunkHolder.IListener p_i50716_4_, ChunkHolder.IPlayerProvider p_i50716_5_) {
this.field_219319_n = p_i50716_1_;
@@ -204,7 +_,7 @@
}
@@ -8,11 +8,23 @@
}
this.func_219229_a(p_219185_5_);
@@ -601,6 +_,7 @@
@@ -581,6 +_,8 @@
chunk.func_217318_w();
if (this.field_219254_h.add(chunkpos.func_201841_a())) {
chunk.func_177417_c(true);
+ try {
+ p_219200_1_.currentlyLoading = chunk; //Forge - bypass the future chain when getChunk is called, this prevents deadlocks.
this.field_219255_i.func_147448_a(chunk.func_177434_r().values());
List<Entity> list = null;
ClassInheritanceMultiMap<Entity>[] aclassinheritancemultimap = chunk.func_177429_s();
@@ -601,6 +_,10 @@
if (list != null) {
list.forEach(chunk::func_76622_b);
}
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkEvent.Load(chunk));
+ } finally {
+ p_219200_1_.currentlyLoading = null;//Forge - Stop bypassing the future chain.
+ }
}
return chunk;
@@ -1,5 +1,17 @@
--- a/net/minecraft/world/server/ServerChunkProvider.java
+++ b/net/minecraft/world/server/ServerChunkProvider.java
@@ -125,6 +_,11 @@
}
}
+ ChunkHolder chunkholder = this.func_217213_a(i);
+ if (chunkholder != null && chunkholder.currentlyLoading != null) {
+ return chunkholder.currentlyLoading; //Forge - If the requested chunk is loading, bypass the future chain to prevent a deadlock.
+ }
+
iprofiler.func_230035_c_("getChunkCacheMiss");
CompletableFuture<Either<IChunk, ChunkHolder.IChunkLoadingError>> completablefuture = this.func_217233_c(p_212849_1_, p_212849_2_, p_212849_3_, p_212849_4_);
this.field_217243_i.func_213161_c(completablefuture::isDone);
@@ -353,7 +_,7 @@
if (optional1.isPresent()) {
Chunk chunk = optional1.get();
@@ -140,7 +140,7 @@
this.func_217465_m(p_217440_1_);
return true;
}
@@ -879,12 +_,17 @@
@@ -879,10 +_,14 @@
}
@@ -157,15 +157,13 @@
+ enderdragonpartentity.remove(keepData);
}
}
+ p_217484_1_.remove(keepData);
this.field_175741_N.remove(p_217484_1_.func_110124_au());
this.func_72863_F().func_217226_b(p_217484_1_);
@@ -898,6 +_,8 @@
@@ -898,6 +_,9 @@
this.field_217495_I.remove(((MobEntity)p_217484_1_).func_70661_as());
}
+ p_217484_1_.onRemovedFromWorld();
+ p_217484_1_.remove(keepData);
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityLeaveWorldEvent(p_217484_1_, this));
}
@@ -1,10 +1,13 @@
--- a/net/minecraft/world/spawner/CatSpawner.java
+++ b/net/minecraft/world/spawner/CatSpawner.java
@@ -80,6 +_,7 @@
@@ -80,8 +_,9 @@
if (catentity == null) {
return 0;
} else {
+ catentity.func_174828_a(p_221122_1_, 0.0F, 0.0F); // Fix MC-147659: Some witch huts spawn the incorrect cat
+ if(net.minecraftforge.common.ForgeHooks.canEntitySpawn(catentity, p_221122_2_, p_221122_1_.func_177958_n(), p_221122_1_.func_177956_o(), p_221122_1_.func_177952_p(), null, SpawnReason.NATURAL) == -1) return 0;
catentity.func_213386_a(p_221122_2_, p_221122_2_.func_175649_E(p_221122_1_), SpawnReason.NATURAL, (ILivingEntityData)null, (CompoundNBT)null);
catentity.func_174828_a(p_221122_1_, 0.0F, 0.0F);
- catentity.func_174828_a(p_221122_1_, 0.0F, 0.0F);
p_221122_2_.func_242417_l(catentity);
return 1;
}
@@ -1,10 +1,10 @@
--- a/net/minecraft/world/spawner/PatrolSpawner.java
+++ b/net/minecraft/world/spawner/PatrolSpawner.java
@@ -94,6 +_,7 @@
return false;
} else {
PatrollerEntity patrollerentity = EntityType.field_220350_aJ.func_200721_a(p_222695_1_);
+ if(net.minecraftforge.common.ForgeHooks.canEntitySpawn(patrollerentity, p_222695_1_, p_222695_2_.func_177958_n(), p_222695_2_.func_177956_o(), p_222695_2_.func_177952_p(), null, SpawnReason.PATROL) == -1) return false;
if (patrollerentity != null) {
if (p_222695_4_) {
patrollerentity.func_213635_r(true);
@@ -101,6 +_,7 @@
}
patrollerentity.func_70107_b((double)p_222695_2_.func_177958_n(), (double)p_222695_2_.func_177956_o(), (double)p_222695_2_.func_177952_p());
+ if(net.minecraftforge.common.ForgeHooks.canEntitySpawn(patrollerentity, p_222695_1_, p_222695_2_.func_177958_n(), p_222695_2_.func_177956_o(), p_222695_2_.func_177952_p(), null, SpawnReason.PATROL) == -1) return false;
patrollerentity.func_213386_a(p_222695_1_, p_222695_1_.func_175649_E(p_222695_2_), SpawnReason.PATROL, (ILivingEntityData)null, (CompoundNBT)null);
p_222695_1_.func_242417_l(patrollerentity);
return true;
@@ -1,10 +1,10 @@
--- a/net/minecraft/world/spawner/PhantomSpawner.java
+++ b/net/minecraft/world/spawner/PhantomSpawner.java
@@ -57,6 +_,7 @@
@@ -58,6 +_,7 @@
for(int i1 = 0; i1 < l; ++i1) {
PhantomEntity phantomentity = EntityType.field_203097_aH.func_200721_a(p_230253_1_);
+ if(net.minecraftforge.common.ForgeHooks.canEntitySpawn(phantomentity, p_230253_1_, blockpos1.func_177958_n(), blockpos1.func_177956_o(), blockpos1.func_177952_p(), null, SpawnReason.NATURAL) == -1) return 0;
phantomentity.func_174828_a(blockpos1, 0.0F, 0.0F);
+ if(net.minecraftforge.common.ForgeHooks.canEntitySpawn(phantomentity, p_230253_1_, blockpos1.func_177958_n(), blockpos1.func_177956_o(), blockpos1.func_177952_p(), null, SpawnReason.NATURAL) == -1) return 0;
ilivingentitydata = phantomentity.func_213386_a(p_230253_1_, difficultyinstance, SpawnReason.NATURAL, ilivingentitydata, (CompoundNBT)null);
p_230253_1_.func_242417_l(phantomentity);
}
+7
View File
@@ -1,3 +1,10 @@
pluginManagement {
repositories {
gradlePluginPortal()
maven { url = 'https://maven.minecraftforge.net/' }
}
}
rootProject.name = 'Forge'
include ':mcp'
@@ -54,8 +54,9 @@ public class LibraryFinder {
try {
Path path;
final URI uri = resource.toURI();
if (uri.getRawSchemeSpecificPart().contains("!")) {
path = Paths.get(new URI(uri.getRawSchemeSpecificPart().split("!")[0]));
if (uri.getScheme().equals("jar") && uri.getRawSchemeSpecificPart().contains("!/")) {
int lastExcl = uri.getRawSchemeSpecificPart().lastIndexOf("!/");
path = Paths.get(new URI(uri.getRawSchemeSpecificPart().substring(0, lastExcl)));
} else {
path = Paths.get(new URI("file://"+uri.getRawSchemeSpecificPart().substring(0, uri.getRawSchemeSpecificPart().length()-resourceName.length())));
}
@@ -247,25 +247,27 @@ public class ModSorter
.flatMap(Collection::stream)
.collect(Collectors.groupingBy(Function.identity(), Java9BackportUtils.flatMapping(e -> e.getDependencies().stream(), Collectors.toList())));
final Set<IModInfo.ModVersion> mandatoryModVersions = modVersionDependencies
final Set<IModInfo.ModVersion> modRequirements = modVersionDependencies
.values()
.stream()
.flatMap(Collection::stream)
.filter(mv -> mv.isMandatory() && mv.getSide().isCorrectSide())
.filter(mv -> mv.getSide().isCorrectSide())
.collect(Collectors.toSet());
LOGGER.debug(LOADING, "Found {} mandatory requirements", mandatoryModVersions.size());
final Set<IModInfo.ModVersion> missingVersions = mandatoryModVersions
final long mandatoryRequired = modRequirements.stream().filter(IModInfo.ModVersion::isMandatory).count();
LOGGER.debug(LOADING, "Found {} mod requirements ({} mandatory, {} optional)", modRequirements.size(), mandatoryRequired, modRequirements.size() - mandatoryRequired);
final Set<IModInfo.ModVersion> missingVersions = modRequirements
.stream()
.filter(mv->this.modVersionNotContained(mv, modVersions))
.filter(mv -> (mv.isMandatory() || modVersions.containsKey(mv.getModId())) && this.modVersionNotContained(mv, modVersions))
.collect(Collectors.toSet());
LOGGER.debug(LOADING, "Found {} mandatory mod requirements missing", missingVersions.size());
final long mandatoryMissing = missingVersions.stream().filter(IModInfo.ModVersion::isMandatory).count();
LOGGER.debug(LOADING, "Found {} mod requirements missing ({} mandatory, {} optional)", missingVersions.size(), mandatoryMissing, missingVersions.size() - mandatoryMissing);
if (!missingVersions.isEmpty()) {
return missingVersions
.stream()
.map(mv -> new ExceptionData("fml.modloading.missingdependency", mv.getOwner(),
mv.getModId(), mv.getOwner().getModId(), mv.getVersionRange(),
.map(mv -> new ExceptionData(mv.isMandatory() ? "fml.modloading.missingdependency" : "fml.modloading.missingdependency.optional",
mv.getOwner(), mv.getModId(), mv.getOwner().getModId(), mv.getVersionRange(),
modVersions.getOrDefault(mv.getModId(), new DefaultArtifactVersion("null"))))
.collect(Collectors.toList());
}
@@ -196,7 +196,7 @@ public class RuntimeDistCleaner implements ILaunchPluginService
private final List<Handle> dynamicLambdaHandles = new ArrayList<>();
public LambdaGatherer() {
super(Opcodes.ASM7);
super(Opcodes.ASM9);
}
public void accept(MethodNode method) {
@@ -34,7 +34,7 @@ public class ModAnnotationVisitor extends AnnotationVisitor
public ModAnnotationVisitor(LinkedList<ModAnnotation> annotations, ModAnnotation annotation)
{
super(Opcodes.ASM7);
super(Opcodes.ASM9);
this.annotations = annotations;
this.annotation = annotation;
}
@@ -42,7 +42,7 @@ public class ModClassVisitor extends ClassVisitor
private final LinkedList<ModAnnotation> annotations = new LinkedList<>();
public ModClassVisitor()
{
super(Opcodes.ASM7);
super(Opcodes.ASM9);
}
@@ -34,7 +34,7 @@ public class ModFieldVisitor extends FieldVisitor
public ModFieldVisitor(String name, final LinkedList<ModAnnotation> annotations)
{
super(Opcodes.ASM7);
super(Opcodes.ASM9);
this.fieldName = name;
this.annotations = annotations;
}
@@ -170,10 +170,12 @@ public class ModFileInfo implements IModFileInfo, IConfigurable
return Strings.isNullOrEmpty(license);
}
/* This data can only be trusted for the manifest and signature file itself. We do not validate each entry in the jar. Coremods exists, it would be useless */
public Optional<CodeSigner[]> getCodeSigners() {
return this.signers;
}
/* This data can only be trusted for the manifest and signature file itself. We do not validate each entry in the jar. Coremods exists, it would be useless */
public Optional<String> getCodeSigningFingerprint() {
return Java9BackportUtils.toStream(this.signers)
.flatMap(csa->csa[0].getSignerCertPath().getCertificates().stream())
@@ -184,6 +186,7 @@ public class ModFileInfo implements IModFileInfo, IConfigurable
.map(str-> String.join(":", str.split("(?<=\\G.{2})")));
}
/* This data can only be trusted for the manifest and signature file itself. We do not validate each entry in the jar. Coremods exists, it would be useless */
public Optional<String> getTrustData() {
return Java9BackportUtils.toStream(this.signers)
.flatMap(csa->csa[0].getSignerCertPath().getCertificates().stream())
@@ -35,7 +35,7 @@ public class ModMethodVisitor extends MethodVisitor {
public ModMethodVisitor(String name, String desc, final LinkedList<ModAnnotation> annotations)
{
super(Opcodes.ASM7);
super(Opcodes.ASM9);
this.methodName = name;
this.methodDescriptor = desc;
this.annotations = annotations;
@@ -111,14 +111,20 @@ class ClientVisualization implements EarlyProgressVisualization.Visualization {
IntBuffer monPosLeft = stack.mallocInt(1);
IntBuffer monPosTop = stack.mallocInt(1);
glfwGetWindowSize(window, pWidth, pHeight);
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwGetMonitorPos(glfwGetPrimaryMonitor(), monPosLeft, monPosTop);
// Center the window
glfwSetWindowPos(
window,
(vidmode.width() - pWidth.get(0)) / 2 + monPosLeft.get(0),
(vidmode.height() - pHeight.get(0)) / 2 + monPosTop.get(0)
);
// try to center the window, this is a best-effort as there may not be
// a primary monitor and we might not even be on the primary monitor...
long primaryMonitor = glfwGetPrimaryMonitor();
if (primaryMonitor != NULL)
{
GLFWVidMode vidmode = glfwGetVideoMode(primaryMonitor);
glfwGetMonitorPos(primaryMonitor, monPosLeft, monPosTop);
glfwSetWindowPos(
window,
(vidmode.width() - pWidth.get(0)) / 2 + monPosLeft.get(0),
(vidmode.height() - pHeight.get(0)) / 2 + monPosTop.get(0)
);
}
IntBuffer iconWidth = stack.mallocInt(1);
IntBuffer iconHeight = stack.mallocInt(1);
IntBuffer iconChannels = stack.mallocInt(1);
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"#forge:barrels/wooden"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"minecraft:barrel"
]
}
@@ -49,6 +49,7 @@ db2cd929128c8a6e8e0b02437f90ad8d24238206 assets/data_gen_test/models/block/torch
098d8b38409fff6cc14a4e56355bedb1fc5931d1 assets/data_gen_test/models/item/test_block.json
b029993275f16569b0edf093362f55df6ea6f9be assets/data_gen_test/models/item/test_block_model.json
726e1884e53151492ca05bd752c67031603570f6 assets/data_gen_test/models/item/test_generated_model.json
61e57e44de5506da3937499a4fe46f84b856ba52 assets/data_gen_test/sounds.json
1767c874758bd7c3235db446b6219e6e1edd25b4 assets/minecraft/blockstates/acacia_door.json
e41383b4c13ec922c0f5cfa2cc313d88fd294685 assets/minecraft/blockstates/acacia_fence.json
967d268bfcf32474b61578bef16e853b6360dd73 assets/minecraft/blockstates/acacia_fence_gate.json
@@ -0,0 +1,125 @@
{
"ambient.underwater.loop.additions": {
"sounds": [
"ambient/underwater/additions/bubbles1",
"ambient/underwater/additions/bubbles2",
"ambient/underwater/additions/bubbles3",
"ambient/underwater/additions/bubbles4",
"ambient/underwater/additions/bubbles5",
"ambient/underwater/additions/bubbles6",
"ambient/underwater/additions/water1",
"ambient/underwater/additions/water2"
]
},
"ambient.underwater.loop.additions.ultra_rare": {
"sounds": [
"ambient/underwater/additions/animal2",
"ambient/underwater/additions/dark1",
{
"name": "ambient/underwater/additions/dark2",
"volume": 0.7
},
"ambient/underwater/additions/dark3",
"ambient/underwater/additions/dark4"
]
},
"block.lava.ambient": {
"subtitle": "subtitles.block.lava.ambient",
"sounds": [
"liquid/lava"
]
},
"entity.dolphin.ambient_water": {
"subtitle": "subtitles.entity.dolphin.ambient_water",
"sounds": [
{
"name": "mob/dolphin/idle_water1",
"volume": 0.8
},
"mob/dolphin/idle_water2",
"mob/dolphin/idle_water3",
"mob/dolphin/idle_water4",
"mob/dolphin/idle_water5",
"mob/dolphin/idle_water6",
{
"name": "mob/dolphin/idle_water7",
"volume": 0.75
},
{
"name": "mob/dolphin/idle_water8",
"volume": 0.75
},
"mob/dolphin/idle_water9",
{
"name": "mob/dolphin/idle_water10",
"volume": 0.8
}
]
},
"entity.parrot.imitate.drowned": {
"subtitle": "subtitles.entity.parrot.imitate.drowned",
"sounds": [
{
"name": "entity.drowned.ambient",
"type": "event",
"volume": 0.6,
"pitch": 1.8
}
]
},
"item.trident.return": {
"subtitle": "subtitles.item.trident.return",
"sounds": [
{
"name": "item/trident/return1",
"volume": 0.8
},
{
"name": "item/trident/return2",
"volume": 0.8,
"pitch": 1.2
},
{
"name": "item/trident/return3",
"volume": 0.8,
"pitch": 0.8
},
{
"name": "item/trident/return2",
"volume": 0.8
},
{
"name": "item/trident/return2",
"volume": 0.8,
"pitch": 1.2
},
{
"name": "item/trident/return2",
"volume": 0.8,
"pitch": 0.8
},
{
"name": "item/trident/return3",
"volume": 0.8
},
{
"name": "item/trident/return3",
"volume": 0.8,
"pitch": 1.2
},
{
"name": "item/trident/return3",
"volume": 0.8,
"pitch": 0.8
}
]
},
"music_disc.blocks": {
"sounds": [
{
"name": "records/blocks",
"stream": true
}
]
}
}
@@ -61,6 +61,8 @@ import net.minecraft.fluid.FluidState;
import net.minecraft.inventory.EquipmentSlotType;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.RecipeManager;
import net.minecraft.resources.IResource;
import net.minecraft.resources.IResourceManager;
import net.minecraft.util.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.MovementInput;
@@ -84,6 +86,7 @@ import net.minecraftforge.client.event.*;
import net.minecraftforge.client.event.sound.PlaySoundEvent;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.client.model.animation.Animation;
import net.minecraftforge.client.textures.ForgeTextureMetadata;
import net.minecraftforge.common.ForgeMod;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.model.TransformationHelper;
@@ -164,7 +167,9 @@ public class ForgeHooksClient
StartupMessageManager.mcLoaderConsumer().ifPresent(c->c.accept("Atlas Stitching : "+map.location().toString()));
ModLoader.get().postEvent(new TextureStitchEvent.Pre(map, resourceLocations));
// ModelLoader.White.INSTANCE.register(map); // TODO Custom TAS
Atlases.SIGN_MATERIALS.values().forEach(material -> resourceLocations.add(material.texture()));
Atlases.SIGN_MATERIALS.values().stream()
.filter(rm -> rm.atlasLocation().equals(map.location()))
.forEach(rm -> resourceLocations.add(rm.texture()));
}
public static void onTextureStitchedPost(AtlasTexture map)
@@ -820,4 +825,18 @@ public class ForgeHooksClient
{
return Optional.of(ForgeWorldTypeScreens.getDefaultGenerator());
}
@Nullable
public static TextureAtlasSprite loadTextureAtlasSprite(
AtlasTexture atlasTexture,
IResourceManager resourceManager, TextureAtlasSprite.Info textureInfo,
IResource resource,
int atlasWidth, int atlasHeight,
int spriteX, int spriteY, int mipmapLevel,
NativeImage image
)
{
ForgeTextureMetadata metadata = ForgeTextureMetadata.forResource(resource);
return metadata.getLoader() == null ? null : metadata.getLoader().load(atlasTexture, resourceManager, textureInfo, resource, atlasWidth, atlasHeight, spriteX, spriteY, mipmapLevel, image);
}
}
@@ -19,18 +19,21 @@
package net.minecraftforge.client;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderState;
import net.minecraft.client.renderer.RenderState.TextureState;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.RenderType.State;
import net.minecraft.client.renderer.texture.AtlasTexture;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.util.NonNullLazy;
import net.minecraftforge.common.util.NonNullSupplier;
import org.lwjgl.opengl.GL11;
import net.minecraft.client.renderer.RenderState.TextureState;
import net.minecraft.client.renderer.RenderType.State;
import java.util.function.Supplier;
@SuppressWarnings("deprecation")
public enum ForgeRenderTypes
@@ -43,6 +46,8 @@ public enum ForgeRenderTypes
ITEM_UNLIT_TRANSLUCENT(()-> getUnlitTranslucent(AtlasTexture.LOCATION_BLOCKS)),
ITEM_UNSORTED_UNLIT_TRANSLUCENT(()-> getUnlitTranslucent(AtlasTexture.LOCATION_BLOCKS, false));
public static boolean enableTextTextureLinearFiltering = false;
/**
* @return A RenderType fit for multi-layer solid item rendering.
*/
@@ -110,6 +115,22 @@ public enum ForgeRenderTypes
return Internal.layeredItemCutoutMipped(textureLocation);
}
/**
* @return Replacement of {@link RenderType#getText(ResourceLocation)}, but with optional linear texture filtering.
*/
public static RenderType getText(ResourceLocation locationIn)
{
return Internal.getText(locationIn);
}
/**
* @return Replacement of {@link RenderType#getTextSeeThrough(ResourceLocation)}, but with optional linear texture filtering.
*/
public static RenderType getTextSeeThrough(ResourceLocation locationIn)
{
return Internal.getTextSeeThrough(locationIn);
}
// ----------------------------------------
// Implementation details below this line
// ----------------------------------------
@@ -209,5 +230,43 @@ public enum ForgeRenderTypes
.createCompositeState(true);
return create("forge_item_entity_translucent_cull", DefaultVertexFormats.NEW_ENTITY, 7, 256, true, true, rendertype$state);
}
public static RenderType getText(ResourceLocation locationIn) {
RenderType.State rendertype$state = RenderType.State.builder()
.setTextureState(new CustomizableTextureState(locationIn, () -> ForgeRenderTypes.enableTextTextureLinearFiltering, () -> false))
.setAlphaState(DEFAULT_ALPHA)
.setTransparencyState(TRANSLUCENT_TRANSPARENCY)
.setLightmapState(LIGHTMAP)
.createCompositeState(false);
return create("forge_text", DefaultVertexFormats.POSITION_COLOR_TEX_LIGHTMAP, 7, 256, false, true, rendertype$state);
}
public static RenderType getTextSeeThrough(ResourceLocation locationIn) {
RenderType.State rendertype$state = RenderType.State.builder()
.setTextureState(new CustomizableTextureState(locationIn, () -> ForgeRenderTypes.enableTextTextureLinearFiltering, () -> false))
.setAlphaState(DEFAULT_ALPHA)
.setTransparencyState(TRANSLUCENT_TRANSPARENCY)
.setLightmapState(LIGHTMAP)
.setDepthTestState(NO_DEPTH_TEST)
.setWriteMaskState(COLOR_WRITE)
.createCompositeState(false);
return create("forge_text_see_through", DefaultVertexFormats.POSITION_COLOR_TEX_LIGHTMAP, 7, 256, false, true, rendertype$state);
}
}
private static class CustomizableTextureState extends TextureState
{
private CustomizableTextureState(ResourceLocation resLoc, Supplier<Boolean> blur, Supplier<Boolean> mipmap)
{
super(resLoc, blur.get(), mipmap.get());
this.setupState = () -> {
this.blur = blur.get();
this.mipmap = mipmap.get();
RenderSystem.enableTexture();
TextureManager texturemanager = Minecraft.getInstance().getTextureManager();
texturemanager.bind(resLoc);
texturemanager.getTexture(resLoc).setFilter(this.blur, this.mipmap);
};
}
}
}
@@ -23,7 +23,9 @@ import java.io.IOException;
import java.util.BitSet;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
@@ -45,6 +47,7 @@ import net.minecraft.resources.IResourceManager;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.client.textures.ITextureAtlasSpriteLoader;
public class MinecraftForgeClient
{
@@ -156,4 +159,21 @@ public class MinecraftForgeClient
IResource iresource1 = resourceManager.getResource(resourceLocation);
return NativeImage.read(iresource1.getInputStream());
}
private static final Map<ResourceLocation, ITextureAtlasSpriteLoader> textureAtlasSpriteLoaders = new ConcurrentHashMap<>();
/**
* Register a custom ITextureAtlasSprite loader. Call this method during {@link net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent}.
*/
public static void registerTextureAtlasSpriteLoader(ResourceLocation name, ITextureAtlasSpriteLoader loader)
{
textureAtlasSpriteLoaders.put(name, loader);
}
@Nullable
public static ITextureAtlasSpriteLoader getTextureAtlasSpriteLoader(ResourceLocation name)
{
return textureAtlasSpriteLoaders.get(name);
}
}
@@ -30,34 +30,26 @@ import net.minecraft.util.ResourceLocation;
public interface IForgeTextureAtlasSprite
{
/**
* The result of this function determines is the below 'load' function is called, and the
* default vanilla loading code is bypassed completely.
* @param manager Main resource manager
* @param location File resource location
* @return True to use your own custom load code and bypass vanilla loading.
* @deprecated See {@link net.minecraftforge.client.textures.ITextureAtlasSpriteLoader}
*/
@Deprecated
default boolean hasCustomLoader(IResourceManager manager, ResourceLocation location)
{
return false;
}
/**
* Load the specified resource as this sprite's data.
* Returning false from this function will prevent this icon from being stitched onto the master texture.
* @param manager Main resource manager
* @param location File resource location
* @param textureGetter accessor for dependencies. All of them will be loaded before this one
* @return False to prevent this Icon from being stitched
* @deprecated See {@link net.minecraftforge.client.textures.ITextureAtlasSpriteLoader}
*/
@Deprecated
default boolean load(IResourceManager manager, ResourceLocation location, Function<ResourceLocation, TextureAtlasSprite> textureGetter)
{
return true;
}
/**
* @return all textures that should be loaded before this texture.
*/
@Deprecated
default Collection<ResourceLocation> getDependencies()
{
return ImmutableList.of();
@@ -97,12 +97,9 @@ public final class MultiLayerModel implements IModelGeometry<MultiLayerModel>
@Override
public IBakedModel bake(IModelConfiguration owner, ModelBakery bakery, Function<RenderMaterial, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ItemOverrideList overrides, ResourceLocation modelLocation)
{
IUnbakedModel missing = ModelLoader.instance().getMissingModel();
return new MultiLayerBakedModel(
owner.useSmoothLighting(), owner.isShadedInGui(), owner.isSideLit(),
spriteGetter.apply(owner.resolveTexture("particle")), overrides, convertRenderTypes,
missing.bake(bakery, spriteGetter, modelTransform, modelLocation),
buildModels(models, modelTransform, bakery, spriteGetter, modelLocation),
PerspectiveMapWrapper.getTransforms(new ModelTransformComposition(owner.getCombinedTransform(), modelTransform))
);
@@ -117,18 +114,17 @@ public final class MultiLayerModel implements IModelGeometry<MultiLayerModel>
protected final boolean isSideLit;
protected final TextureAtlasSprite particle;
protected final ItemOverrideList overrides;
private final IBakedModel missing;
private final List<BakedQuad> missing = ImmutableList.of();
private final boolean convertRenderTypes;
private final List<Pair<IBakedModel, RenderType>> itemLayers;
public MultiLayerBakedModel(
boolean ambientOcclusion, boolean isGui3d, boolean isSideLit, TextureAtlasSprite particle, ItemOverrideList overrides,
boolean convertRenderTypes, IBakedModel missing, List<Pair<RenderType, IBakedModel>> models,
boolean convertRenderTypes, List<Pair<RenderType, IBakedModel>> models,
ImmutableMap<TransformType, TransformationMatrix> cameraTransforms)
{
this.isSideLit = isSideLit;
this.cameraTransforms = cameraTransforms;
this.missing = missing;
this.ambientOcclusion = ambientOcclusion;
this.gui3d = isGui3d;
this.particle = particle;
@@ -159,8 +155,10 @@ public final class MultiLayerModel implements IModelGeometry<MultiLayerModel>
// support for item layer rendering
if (state == null && convertRenderTypes)
layer = ITEM_RENDER_TYPE_MAPPING.inverse().getOrDefault(layer, layer);
// assumes that child model will handle this state properly. FIXME?
return models.getOrDefault(layer, missing).getQuads(state, side, rand, extraData);
if (models.containsKey(layer))
return models.get(layer).getQuads(state, side, rand, extraData);
else
return missing;
}
@Override
@@ -199,6 +199,15 @@ public class ModelBuilder<T extends ModelBuilder<T>> extends ModelFile {
return elements.get(index);
}
/**
* Gets the number of elements in this model builder
* @return the number of elements in this model builder
*/
public int getElementCount()
{
return elements.size();
}
/**
* Use a custom loader instead of the vanilla elements.
* @param customLoaderFactory
@@ -29,6 +29,7 @@ import com.google.common.base.Preconditions;
import com.google.common.collect.Multimap;
import com.google.common.collect.MultimapBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import net.minecraft.block.Block;
@@ -75,11 +76,15 @@ public final class MultiPartBlockStateBuilder implements IGeneratedBlockstate {
public BlockStateProvider.ConfiguredModelList models;
public boolean useOr;
public final Multimap<Property<?>, Comparable<?>> conditions = MultimapBuilder.linkedHashKeys().arrayListValues().build();
public final List<ConditionGroup> nestedConditionGroups = new ArrayList<>();
PartBuilder(BlockStateProvider.ConfiguredModelList models) {
this.models = models;
}
/**
* Makes this part get applied if any of the conditions/condition groups are true, instead of all of them needing to be true.
*/
public PartBuilder useOr() {
this.useOr = true;
return this;
@@ -99,6 +104,7 @@ public final class MultiPartBlockStateBuilder implements IGeneratedBlockstate {
* @throws IllegalArgumentException if {@code prop} has already been configured
* @throws IllegalArgumentException if {@code prop} is not applicable to the
* current block's state
* @throws IllegalStateException if {@code !nestedConditionGroups.isEmpty()}
*/
@SafeVarargs
public final <T extends Comparable<T>> PartBuilder condition(Property<T> prop, T... values) {
@@ -107,31 +113,33 @@ public final class MultiPartBlockStateBuilder implements IGeneratedBlockstate {
Preconditions.checkArgument(values.length > 0, "Value list must not be empty");
Preconditions.checkArgument(!conditions.containsKey(prop), "Cannot set condition for property \"%s\" more than once", prop.getName());
Preconditions.checkArgument(canApplyTo(owner), "IProperty %s is not valid for the block %s", prop, owner);
Preconditions.checkState(nestedConditionGroups.isEmpty(), "Can't have normal conditions if there are already nested condition groups");
this.conditions.putAll(prop, Arrays.asList(values));
return this;
}
/**
* Allows having nested groups of conditions if there are not any normal conditions.
* @throws IllegalStateException if {@code !conditions.isEmpty()}
*/
public final ConditionGroup nestedGroup()
{
Preconditions.checkState(conditions.isEmpty(), "Can't have nested condition groups if there are already normal conditions");
ConditionGroup group = new ConditionGroup();
this.nestedConditionGroups.add(group);
return group;
}
public MultiPartBlockStateBuilder end() { return MultiPartBlockStateBuilder.this; }
JsonObject toJson() {
JsonObject out = new JsonObject();
if (!conditions.isEmpty()) {
JsonObject when = new JsonObject();
for (Entry<Property<?>, Collection<Comparable<?>>> e : conditions.asMap().entrySet()) {
StringBuilder activeString = new StringBuilder();
for (Comparable<?> val : e.getValue()) {
if (activeString.length() > 0)
activeString.append("|");
activeString.append(((Property) e.getKey()).getName(val));
}
when.addProperty(e.getKey().getName(), activeString.toString());
}
if (useOr) {
JsonObject innerWhen = when;
when = new JsonObject();
when.add("OR", innerWhen);
}
out.add("when", when);
out.add("when", MultiPartBlockStateBuilder.toJson(this.conditions, this.useOr));
}
else if (!nestedConditionGroups.isEmpty())
{
out.add("when", MultiPartBlockStateBuilder.toJson(this.nestedConditionGroups, this.useOr));
}
out.add("apply", models.toJSON());
return out;
@@ -140,5 +148,142 @@ public final class MultiPartBlockStateBuilder implements IGeneratedBlockstate {
public boolean canApplyTo(Block b) {
return b.getStateDefinition().getProperties().containsAll(conditions.keySet());
}
public class ConditionGroup
{
public final Multimap<Property<?>, Comparable<?>> conditions = MultimapBuilder.linkedHashKeys().arrayListValues().build();
public final List<ConditionGroup> nestedConditionGroups = new ArrayList<>();
private ConditionGroup parent = null;
public boolean useOr;
/**
* Set a condition for this part, which consists of a property and a set of
* valid values. Can be called multiple times for multiple different properties.
*
* @param <T> the type of the property value
* @param prop the property
* @param values a set of valid values
* @return this builder
* @throws NullPointerException if {@code prop} is {@code null}
* @throws NullPointerException if {@code values} is {@code null}
* @throws IllegalArgumentException if {@code values} is empty
* @throws IllegalArgumentException if {@code prop} has already been configured
* @throws IllegalArgumentException if {@code prop} is not applicable to the
* current block's state
* @throws IllegalStateException if {@code !nestedConditionGroups.isEmpty()}
*/
@SafeVarargs
public final <T extends Comparable<T>> ConditionGroup condition(Property<T> prop, T... values)
{
Preconditions.checkNotNull(prop, "Property must not be null");
Preconditions.checkNotNull(values, "Value list must not be null");
Preconditions.checkArgument(values.length > 0, "Value list must not be empty");
Preconditions.checkArgument(!conditions.containsKey(prop), "Cannot set condition for property \"%s\" more than once", prop.getName());
Preconditions.checkArgument(canApplyTo(owner), "IProperty %s is not valid for the block %s", prop, owner);
Preconditions.checkState(nestedConditionGroups.isEmpty(), "Can't have normal conditions if there are already nested condition groups");
this.conditions.putAll(prop, Arrays.asList(values));
return this;
}
/**
* Allows having nested groups of conditions if there are not any normal conditions.
* @throws IllegalStateException if {@code !conditions.isEmpty()}
*/
public ConditionGroup nestedGroup()
{
Preconditions.checkState(conditions.isEmpty(), "Can't have nested condition groups if there are already normal conditions");
ConditionGroup group = new ConditionGroup();
group.parent = this;
this.nestedConditionGroups.add(group);
return group;
}
/**
* Ends this nested condition group and returns the parent condition group
*
* @throws IllegalStateException If this is not a nested condition group
*/
public ConditionGroup endNestedGroup()
{
if (parent == null)
throw new IllegalStateException("This condition group is not nested, use end() instead");
return parent;
}
/**
* Ends this condition group and returns the part builder
*
* @throws IllegalStateException If this is a nested condition group
*/
public MultiPartBlockStateBuilder.PartBuilder end()
{
if (this.parent != null)
throw new IllegalStateException("This is a nested condition group, use endNestedGroup() instead");
return MultiPartBlockStateBuilder.PartBuilder.this;
}
/**
* Makes this part get applied if any of the conditions/condition groups are true, instead of all of them needing to be true.
*/
public ConditionGroup useOr()
{
this.useOr = true;
return this;
}
JsonObject toJson()
{
if (!this.conditions.isEmpty())
{
return MultiPartBlockStateBuilder.toJson(this.conditions, this.useOr);
}
else if (!this.nestedConditionGroups.isEmpty())
{
return MultiPartBlockStateBuilder.toJson(this.nestedConditionGroups, this.useOr);
}
return new JsonObject();
}
}
}
private static JsonObject toJson(List<PartBuilder.ConditionGroup> conditions, boolean useOr)
{
JsonObject groupJson = new JsonObject();
JsonArray innerGroupJson = new JsonArray();
groupJson.add(useOr ? "OR" : "AND", innerGroupJson);
for (PartBuilder.ConditionGroup group : conditions)
{
innerGroupJson.add(group.toJson());
}
return groupJson;
}
private static JsonObject toJson(Multimap<Property<?>, Comparable<?>> conditions, boolean useOr)
{
JsonObject groupJson = new JsonObject();
for (Entry<Property<?>, Collection<Comparable<?>>> e : conditions.asMap().entrySet())
{
StringBuilder activeString = new StringBuilder();
for (Comparable<?> val : e.getValue())
{
if (activeString.length() > 0)
activeString.append("|");
activeString.append(((Property) e.getKey()).getName(val));
}
groupJson.addProperty(e.getKey().getName(), activeString.toString());
}
if (useOr)
{
JsonArray innerWhen = new JsonArray();
for (Entry<String, JsonElement> entry : groupJson.entrySet())
{
JsonObject obj = new JsonObject();
obj.add(entry.getKey(), entry.getValue());
innerWhen.add(obj);
}
groupJson = new JsonObject();
groupJson.add("OR", innerWhen);
}
return groupJson;
}
}
@@ -110,7 +110,7 @@ public class OBJLoaderBuilder<T extends ModelBuilder<T>> extends CustomLoaderBui
json.addProperty("ambientToFullbright", ambientToFullbright);
if (materialLibraryOverrideLocation != null)
json.addProperty("materialLibraryOverrideLocation", materialLibraryOverrideLocation.toString());
json.addProperty("materialLibraryOverride", materialLibraryOverrideLocation.toString());
return json;
}
@@ -0,0 +1,98 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.client.textures;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.resources.IResource;
import net.minecraft.resources.data.IMetadataSectionSerializer;
import net.minecraft.util.JSONUtils;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.MinecraftForgeClient;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
/**
* The "forge" section of texture metadata files (.mcmeta). Currently used only to specify custom
* TextureAtlasSprite loaders.
* @see ITextureAtlasSpriteLoader
*/
public final class ForgeTextureMetadata
{
public static final ForgeTextureMetadata EMPTY = new ForgeTextureMetadata(null);
public static final IMetadataSectionSerializer<ForgeTextureMetadata> SERIALIZER = new Serializer();
public static ForgeTextureMetadata forResource(IResource resource)
{
ForgeTextureMetadata metadata = resource.getMetadata(SERIALIZER);
return metadata == null ? EMPTY : metadata;
}
@Nullable
private final ITextureAtlasSpriteLoader loader;
public ForgeTextureMetadata(@Nullable ITextureAtlasSpriteLoader loader)
{
this.loader = loader;
}
@Nullable
public ITextureAtlasSpriteLoader getLoader()
{
return loader;
}
private static final class Serializer implements IMetadataSectionSerializer<ForgeTextureMetadata>
{
@Override
@Nonnull
public String getMetadataSectionName()
{
return "forge";
}
@Override
@Nonnull
public ForgeTextureMetadata fromJson(JsonObject json)
{
@Nullable
ITextureAtlasSpriteLoader loader;
if (json.has("loader"))
{
ResourceLocation loaderName = new ResourceLocation(JSONUtils.getAsString(json, "loader"));
loader = MinecraftForgeClient.getTextureAtlasSpriteLoader(loaderName);
if (loader == null)
{
throw new JsonSyntaxException("Unknown TextureAtlasSpriteLoader " + loaderName);
}
}
else
{
loader = null;
}
return new ForgeTextureMetadata(loader);
}
}
}
@@ -0,0 +1,59 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.client.textures;
import javax.annotation.Nonnull;
import net.minecraft.client.renderer.texture.AtlasTexture;
import net.minecraft.client.renderer.texture.NativeImage;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.resources.IResource;
import net.minecraft.resources.IResourceManager;
import net.minecraft.util.ResourceLocation;
/**
* A loader for custom TextureAtlasSprite implementations.<br>
* The loader can be specified in the corresponding .mcmeta file for a texture as follows:
* <pre>
* {
* "forge": {
* "loader": "examplemod:example_tas_loader"
* }
* }
* </pre>
* @see net.minecraftforge.client.MinecraftForgeClient#registerTextureAtlasSpriteLoader(ResourceLocation, ITextureAtlasSpriteLoader)
*/
public interface ITextureAtlasSpriteLoader
{
/**
* Load a TextureAtlasSprite for the given resource.
*/
@Nonnull
TextureAtlasSprite load(
AtlasTexture atlas,
IResourceManager resourceManager, TextureAtlasSprite.Info textureInfo,
IResource resource,
int atlasWidth, int atlasHeight,
int spriteX, int spriteY, int mipmapLevel,
NativeImage image
);
}
@@ -63,6 +63,7 @@ import net.minecraft.entity.ai.attributes.AttributeModifierMap;
import net.minecraft.entity.ai.attributes.GlobalEntityTypeAttributes;
import net.minecraft.fluid.*;
import net.minecraft.inventory.EquipmentSlotType;
import net.minecraft.item.crafting.IRecipeType;
import net.minecraft.loot.LootContext;
import net.minecraft.loot.LootTable;
import net.minecraft.loot.LootTableManager;
@@ -1244,10 +1245,16 @@ public class ForgeHooks
private static final Map<IRegistryDelegate<Item>, Integer> VANILLA_BURNS = new HashMap<>();
@Deprecated // use variant with IRecipeType
public static int getBurnTime(ItemStack stack)
{
return getBurnTime(stack, null);
}
/**
* Gets the burn time of this itemstack.
*/
public static int getBurnTime(ItemStack stack)
public static int getBurnTime(ItemStack stack, @Nullable IRecipeType<?> recipeType)
{
if (stack.isEmpty())
{
@@ -1256,8 +1263,8 @@ public class ForgeHooks
else
{
Item item = stack.getItem();
int ret = stack.getBurnTime();
return ForgeEventFactory.getItemBurnTime(stack, ret == -1 ? VANILLA_BURNS.getOrDefault(item.delegate, 0) : ret);
int ret = stack.getBurnTime(recipeType);
return ForgeEventFactory.getItemBurnTime(stack, ret == -1 ? VANILLA_BURNS.getOrDefault(item.delegate, 0) : ret, recipeType);
}
}
@@ -25,7 +25,7 @@ import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
/**
* This class defines a replacement for the default minecart collision code.
* Only one handler can be registered at a time. It it registered with EntityMinecart.registerCollisionHandler().
* Only one handler can be registered at a time. It it registered with AbstractMinecartEntity.registerCollisionHandler().
* If you use this, make it a configuration option.
* @author CovertJaguar
*/
@@ -42,6 +42,8 @@ public class Tags
{
private static void init(){}
public static final IOptionalNamedTag<Block> BARRELS = tag("barrels");
public static final IOptionalNamedTag<Block> BARRELS_WOODEN = tag("barrels/wooden");
public static final IOptionalNamedTag<Block> CHESTS = tag("chests");
public static final IOptionalNamedTag<Block> CHESTS_ENDER = tag("chests/ender");
public static final IOptionalNamedTag<Block> CHESTS_TRAPPED = tag("chests/trapped");
@@ -137,6 +139,8 @@ public class Tags
{
private static void init(){}
public static final IOptionalNamedTag<Item> BARRELS = tag("barrels");
public static final IOptionalNamedTag<Item> BARRELS_WOODEN = tag("barrels/wooden");
public static final IOptionalNamedTag<Item> BONES = tag("bones");
public static final IOptionalNamedTag<Item> BOOKSHELVES = tag("bookshelves");
public static final IOptionalNamedTag<Item> CHESTS = tag("chests");
@@ -31,6 +31,8 @@ import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import net.minecraft.data.IDataProvider;
import net.minecraft.client.resources.ResourceIndex;
import net.minecraft.client.resources.VirtualAssetsPack;
import net.minecraft.resources.FilePack;
import net.minecraft.resources.FolderPack;
import net.minecraft.resources.IResource;
@@ -46,6 +48,8 @@ import net.minecraftforge.fml.event.lifecycle.GatherDataEvent;
import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
import net.minecraftforge.fml.packs.ModFileResourcePack;
import javax.annotation.Nullable;
/**
* Enables data providers to check if other data files currently exist. The
* instance provided in the {@link GatherDataEvent} utilizes the standard
@@ -105,11 +109,22 @@ public class ExistingFileHelper {
* @param existingMods
* @param enable
*/
@Deprecated // TODO: Remove in 1.17
public ExistingFileHelper(Collection<Path> existingPacks, Set<String> existingMods, boolean enable) {
this(existingPacks, existingMods, enable, null, null);
}
public ExistingFileHelper(Collection<Path> existingPacks, final Set<String> existingMods, boolean enable, @Nullable final String assetIndex, @Nullable final File assetsDir) {
this.clientResources = new SimpleReloadableResourceManager(ResourcePackType.CLIENT_RESOURCES);
this.serverData = new SimpleReloadableResourceManager(ResourcePackType.SERVER_DATA);
this.clientResources.add(new VanillaPack("minecraft", "realms"));
if (assetIndex != null && assetsDir != null)
{
this.clientResources.add(new VirtualAssetsPack(new ResourceIndex(assetsDir, assetIndex)));
}
this.serverData.add(new VanillaPack("minecraft"));
for (Path existing : existingPacks) {
File file = existing.toFile();
IResourcePack pack = file.isDirectory() ? new FolderPack(file) : new FilePack(file);
@@ -46,6 +46,8 @@ public class ForgeBlockTagsProvider extends BlockTagsProvider
@Override
public void addTags()
{
tag(BARRELS).addTag(BARRELS_WOODEN);
tag(BARRELS_WOODEN).add(Blocks.BARREL);
tag(CHESTS).addTags(CHESTS_ENDER, CHESTS_TRAPPED, CHESTS_WOODEN);
tag(CHESTS_ENDER).add(Blocks.ENDER_CHEST);
tag(CHESTS_TRAPPED).add(Blocks.TRAPPED_CHEST);
Loaded 100 of 160 files, more files were not shown because too many files have changed in this diff. Show more