Compare commits

...
114 Commits
Author SHA1 Message Date
ichttt 863ab2ca18 Fix CME when removing ticket managers (#5861) 2019-09-03 14:22:38 -07:00
Ben Staddon 45da4f6910 Add checks for tile entities in now-unloaded chunks (#5724) 2019-08-28 19:25:57 -07:00
Bartosz Skrzypczak c2630d2a79 Fix client sometimes generating biomes, causing incorrect biome generation on integrated server (#5720) 2019-08-28 19:25:11 -07:00
Ben Staddon 05f4f5ec77 Fix invalid placeholder entity attributes (MC-150405) (#5718) 2019-08-28 19:22:56 -07:00
Ben Staddon a5d0a86760 Allow conditional loading of advancements (#5255) 2019-08-28 19:02:29 -07:00
Derik 7b4a01703b Fix lightning not triggering EntityJoinWorldEvent (#5290) 2019-08-28 18:58:43 -07:00
Ben Staddon 3b99c80636 Improve performance of persistent chunk checks (#5706) 2019-08-28 18:21:38 -07:00
LexManos 20efd7150a Fix copy paste derp 2019-08-28 18:19:45 -07:00
LexManos c56377e4ee Remove test publish group. 2019-08-28 17:44:19 -07:00
LexManos 3e98e16f39 Fix windows installer directory. 2019-08-28 17:24:52 -07:00
LexManos d41cb552a1 Use official launch4j plugin to potentially fix build. 2019-08-28 17:08:36 -07:00
LexManos ae2cb06d2c Move to Jenkinsfile and new Jenkins server. 2019-08-28 16:06:54 -07:00
Gabriel Harris-Rouquette 9de9193062 Fix error prone state lookup during rail neighbor updates. (#6028) 2019-08-15 10:42:21 -07:00
Unnoen f8d32a8525 Don't cache OBJ and B3D models. Throw model loading errors immediately. (#5758) 2019-08-02 14:16:20 -07:00
Ben Staddon dac053415b Improve performance of smooth vertex lighting (#5763) 2019-08-02 14:14:41 -07:00
Joseph C. Sible 7a52116665 Fix SidedInvWrapper hashCode when side is null (#5787) 2019-08-02 14:12:52 -07:00
Ben Staddon 9ba67cedf1 Fix concurrent modification when loading chunk tickets (#5876) 2019-08-02 13:43:12 -07:00
Cloudhunter 5aac0beba9 Fix link applying to whole component in chat if component starts with link (#5910) 2019-08-02 13:41:18 -07:00
Ben Staddon 7849aebab0 Protect against concurrent modification in World#setTileEntity (#5752) 2019-08-02 13:39:05 -07:00
Ben Staddon ea26df0174 Fix more potentially unclosed resources (#5760) 2019-08-02 13:33:43 -07:00
Ben Staddon 3a62514e60 Fix various unclosed I/O resources (#5766) 2019-08-02 13:32:08 -07:00
Ben Staddon 9a636e3c76 Fix vanilla handling of options file (MC-117449, MC-151173) (#5725) 2019-05-13 10:01:08 -07:00
clienthax fa35f30e86 Update EnumHelper to be compatible with Eclipse's OpenJ9 JVM. (#5712) 2019-05-08 17:46:04 -07:00
tterrag 633fd9bd2e Revert "Invalidate tile entities that are queued for removal (#5512)"
This reverts commit 75788f63ee.

This solution is invalid as TEs are free to modify the world tileEntities
list, usually indirectly via chunkloading, from inside invalidate().

This happens in vanilla, in TileEntityChest#invalidate, where it calls
checkForAdjacentChests(), which has the potential to load neighboring
chunks and cause a CME.

A more sophisticated solution is needed.
2019-04-13 09:54:03 -04:00
Ben Staddon 3c426a2e66 Fix some vertex format changes not being handled correctly (#5368) 2019-04-11 16:05:19 -04:00
Ben Staddon 25375f63cc Transform vertex normals as well as positions when generating quads (#5242) 2019-04-11 12:59:16 -04:00
Robert WC Seifert 45cadab7c5 Fix for SidedInvWrapper isItemValid using wrong slot (#5642) 2019-04-11 11:29:14 -04:00
Ben Staddon 75788f63ee Invalidate tile entities that are queued for removal (#5512) 2019-04-11 11:03:36 -04:00
lclc98 3e7b8809b6 Added Wool to OreDictionary (#5414) 2019-04-11 11:01:40 -04:00
CreativeMD 6162f438f1 Fixed boat not taking care of block-liquid hooks (#5086) 2019-04-11 10:18:26 -04:00
Ben Staddon 1752e57ea0 Add Forge dimension-changing hooks to spectator handling code (#5212) 2019-04-11 10:05:19 -04:00
ichttt e91ef7f56b Minor performace improvement when building chunks and rendering blocks (#5286) 2019-04-11 10:03:01 -04:00
Ben Staddon 24f7be2f37 Catch json parsing errors from constants/factories files (#5258) 2019-04-11 08:52:23 -04:00
Ben Staddon 208ed997d4 Allow custom DataSerializers to be registered safely (#5245) 2019-04-11 08:33:12 -04:00
cpw 1f12642a05 Try and make 1.13 mods more obviously wrong in 1.12..
Signed-off-by: cpw <[email protected]>
2019-04-06 13:54:54 -04:00
tterrag e7beed4875 Fix #5651 Re-add canPlaceBlockOnSide check in World#mayPlace 2019-03-28 00:33:59 -04:00
Pokechu22 69a44e6414 Fail fast when null is used with setTag instead of crashing in writeEntry (#5257) 2019-03-22 12:53:07 -04:00
tterrag 3870951a37 Fix block placement not checking for player collision 2019-03-20 23:18:26 -04:00
Wyn Price af4fcd73a4 Added more Constants (#5323) 2019-03-15 15:38:52 -04:00
Thanh-Phuong 04a6b6c2d0 [1.12.2] Add a few events pertaining to villages (#5302) 2019-03-12 01:01:35 -04:00
Tyler Hancock 1b15c127a6 [1.12] Fix special spawn event not firing in many cases. (#5389) 2019-03-12 00:44:08 -04:00
Ben Staddon 8670abca57 Only prompt for missing registries on local worlds (#5348) 2019-03-12 00:34:29 -04:00
Christopher Krier f3d364397d Add EntityPlaceEvent (#5057) 2019-03-12 00:22:47 -04:00
Ben Staddon cc95c40b5b Generalise EnumRarity to an interface (#5182) 2019-03-12 00:02:57 -04:00
Ben Staddon e6fbf39591 Apply access-level changes to inner class attributes (#5468) 2019-02-14 22:46:35 -08:00
Ben Staddon 8cbac6af97 Fix small logic error in ItemTextureQuadConverter (#5463) 2019-02-13 17:03:37 -05:00
Ben Staddon 87cbf735a2 Better support for custom bows (#5209) 2019-02-13 15:58:43 -05:00
Ben Staddon bcbf184915 Improve tracking of used dimension IDs (#5249)
Closes #5378 Large dimension IDs bloat level.data
2019-02-13 15:28:58 -05:00
Phylogeny 965d872856 Fixed incorrect string representation of string list config property default values in their comments. 2019-02-13 15:26:53 -05:00
CovertJaguar 41a098e2f7 Remove FluidStack amount from hashcode calculation (#5272) 2019-02-06 15:35:18 -08:00
Ben Staddon 41d07e7aae Fix up torch placement logic to handle more vanilla special-casing (#5426) 2019-02-04 11:48:08 -08:00
LexManos d1adf00158 Written size does not include int bytes. 2019-02-01 00:46:29 -08:00
LexManos ed67b6fd31 Extend Region files to support >1MB per chunk.
If the 'sector count' is 255, ask the compressed data header for the proper length.
2019-02-01 00:34:45 -08:00
tterrag1098 d5ff207fab Add default impl to IConfigElement#getValidValuesDisplay 2019-01-19 16:40:49 -05:00
tterrag da7c299f7e Simplify custom item rendering by removing GL emissivity hacks 2019-01-10 06:09:06 -05:00
tterrag 204ebdc6dd Support diffuse lighting flag in item rendering 2019-01-04 13:48:36 -05:00
Ben Staddon be565d2ddc Add a hook to allow continuously using items through stack changes (#4834)
* Add a hook to allow continuously using items through stack changes

* Update licences
2019-01-03 23:22:24 -05:00
oOMitchOo 21f7c31f62 Added an additional constructor to every implementation of IFluidBlock. It is now possible to create a fluid block with a Fluid, Material and MapColor, so that the Material's MapColor isn't used for the blocks MapColor. (#5293) 2019-01-03 23:10:56 -05:00
Ben Staddon 4e11c95d0e Add redirects to PotionEffect to respect registry replacement (#5213) 2019-01-03 23:02:11 -05:00
AlexiyOrlov d1478ca529 Add an annotation for @Config elements which will automatically create a slider control (#5026) 2019-01-03 22:07:24 -05:00
Ben Staddon 359d4fe2d5 Fix small logic error in emissive item rendering code (#5320) 2019-01-03 21:11:34 -05:00
Phylogeny d3f27cf6fb Allow config GUI cycling button elements generated from enums to display toString return values, rather than actual values. (#5125) 2019-01-03 21:08:05 -05:00
Ben Staddon 3dd8c8ae6f Fix incorrect indexing in mipmap generation code (#5201) 2019-01-03 21:00:39 -05:00
Ben Staddon 54882f2564 Ensure slave maps are cleaned up when handling registry overrides (#5250) 2019-01-03 20:36:32 -05:00
Daniel Scalzi c5402d50fa Fix issue with --modListFile. (#5316) 2019-01-02 17:28:04 -08:00
LexManos a5f29570a3 Fix potential issues with the Minecraft FakePlayer lingering around after world unloads. 2018-12-07 22:03:32 -08:00
tterrag dd27209565 Fix potion remove event not always firing, add expiry event 2018-12-02 13:20:02 -05:00
tterrag f1d1e8853b Clean up CraftingHelper constants loading API 2018-12-02 03:05:53 -05:00
tterrag 5ef199f6d7 Fix crash from CraftingHelper due to FileSystem being closed early 2018-12-01 23:33:22 -05:00
mcenderdragon 2a5268c699 added PotionHooks, closes #3867, #4375 (#4614)
* solved merge confilct

* improved var names & removed tabs

* Added spaces around !=

* fixed typo
2018-12-01 20:13:13 -05:00
ichttt 32c24be6b4 Add a hook for farmland watering (#4891)
* Add a FarmlandWaterCheckEvent to allow mods to override when Farmland is watered or not

* revert 1.12.2 json

* Move the farmland patch to a ticket based instead of a event based system

* Minor changes

* Faster isValid checks, faster validation/invalidation if the state did not change, expand test mod to include a test for the validation system

* remove isValid boolean flag, we can express it with the tick counter

* Fix test mod resource warnings

* Remove tick timeout, add a javadoc note to invalidate on chunk unload, cleaned up test mod

* Allow mods to provide custom handling to determine if a pos is valid or not

* Make SimpleTicket more simple, make register public so custom tickets can be registered

* Fixes for review

* Add missing license headers

* Use a weak hash set

* Split up the map into smaller chunk based maps

* Add missing license headers

* Make MultiTicketManager more universal for custom implementations, cleanup imports
2018-12-01 20:08:04 -05:00
temp1011 5f56b7cd09 Add methods to allow loading json constants outside of _constants (#4975)
* add interface methods for loading json constants from an arbitary file

* use try-with-resources

* don't make modders create jsoncontext, clean up resource use

* very minor cleanup
2018-12-01 19:46:19 -05:00
ichttt 7f337cf230 Compute ASMDataTable submaps parallel, speeds up contructing mods (#5246)
* Compute submaps parallel, speeds up contructing mods by a lot

* Use stream API better
2018-12-01 19:38:46 -05:00
ichttt 7731e1cd75 Add logging for data manager key registration errors (#5129) 2018-12-01 16:28:02 -08:00
Ben Staddon f8879b1316 Improve support for custom block path types (#5203) 2018-12-01 16:27:20 -08:00
Luke Gilfoyle 3dfe47944d Fix missing comments in configs created with annotations (#5189) 2018-12-01 16:14:48 -08:00
Ben Staddon c11a712e2f Allow items to control the rate of repair from mending (#5102) 2018-12-01 16:08:15 -08:00
Ben Staddon 5771c8ffea Improve exception handling from server starting events (#5226) 2018-11-23 18:08:24 -08:00
Ben Staddon 9587f08ece Improve context provided by potion icon rendering hooks (#5111) 2018-11-23 16:36:29 -08:00
MrRiegel 73b6d10e5a Fix an ObjectHolderRef internal error message (#5214) 2018-11-23 16:03:44 -08:00
tterrag 90c244acb4 Implement rendering for item models with emissive quads (#5047) 2018-11-23 15:57:00 -08:00
Ben Staddon 3cf97f43fe Fix minor issue in getFilledPercentage for Fluid rendering (#5206) 2018-11-23 15:44:35 -08:00
Ben Staddon 0b47ccc015 Clean up logged mod states (#5227) 2018-11-23 15:42:11 -08:00
Paul Fulham 8d372f95f2 Fix inaccurate main thread name shown in client log (#5078) 2018-11-23 15:40:46 -08:00
Ben Staddon d16472d0ba Improve reflection helper methods (#4853) 2018-11-23 15:37:53 -08:00
Ben Staddon 896db6398f Fix Baked Item models with transformations (#5241) 2018-11-23 15:28:30 -08:00
Ben Staddon e406137b19 Prevent RecipeBook from crashing on empty modded ingredients (#5234) 2018-11-23 15:24:18 -08:00
Vincent Lee 16f4903285 Stop firing LivingSetAttackTargetEvent for setRevengeTarget (#5217) 2018-11-23 15:22:08 -08:00
Ben Staddon 84d322da34 Fix missing string parameters in some log messages (#5210) 2018-11-23 15:20:30 -08:00
Ben Staddon 3a64cb8985 Re-add some missing villager profession patches (#5200)
* Fix zombie villagers only spawning with vanilla professions
* Fix spawning modded villagers that do not have their own building
2018-11-23 15:19:44 -08:00
TheIllusiveC4 2fef75c1de Fix the bed position given to the SleepingTimeCheck event (#5107) 2018-11-23 15:15:33 -08:00
Ben Staddon c040a8865f Fix some null returns from defaulted registries (#5235) 2018-11-15 13:52:45 -08:00
Yanbing Zhao 4931fc1907 Only remove synthetic lambda methods referenced in body of SideOnly methods (#5127) 2018-11-14 21:39:30 -08:00
LexManos 607da1bd9b Use HTTPS for files website. 2018-11-13 16:16:33 -08:00
Ben Staddon ebc4eaddac Fix patches from #5160 setting rotation as well as position (#5233) 2018-11-12 12:50:00 -08:00
LexManos 10dbbf9c19 A different approach to my changes in https://github.com/MinecraftForge/MinecraftForge/commit/8ace535995522bec0557d4217e0d98b3dc76cf1e to fix #5207 2018-11-12 12:47:27 -08:00
Ben Staddon f9c2f715fd Allow IModel to express itself as a vanilla parent (#5195)
* Fix errors caused by fancy missing model being non-vanilla parent

* Switch instanceof checks to a default IModel method

* Small code tweaks
2018-10-18 19:22:32 -04:00
gaudus 4e1f7138ee fixed visual bug with guislider 2018-10-18 19:21:42 -04:00
Ben Staddon 5ae5d81609 Make Forge blockstate variants correctly inherit AO setting from vanilla models (#5190)
* Make Forge blockstate variants correctly inherit AO setting

* Move variant format checks into variant, check for added properties

* Small code cleanup
2018-10-18 19:21:26 -04:00
Ben Staddon 947a004138 Make Forge-provided default transforms accessible to custom models 2018-10-18 19:21:02 -04:00
InsomniaKitten e4ca526d5b Add CreativeTabs#getLabelColor 2018-10-18 19:20:40 -04:00
XCompWiz 1ba084f131 Allow providing a BufferedImage for banner render generation (#5041)
* Adds an Event to allow providing a BufferedImage for the banner render generation (cached)
This allows mods to provide generated banner textures, since banners don't use an atlas.
Includes reference/test implementation.

* Missed some copyright; might as well absolut text match, I guess

* Remove unneeded patch change

* Fix event variable access convention

* Formatting fix

* Improve event handling registration

* Import cleanup

* Replace event approach with Supplier approach

* Better name for test mod (now that it's no longer an event); adds ENABLE flag

* Moves MC code into net.minecraftforge.client.MinecraftForgeClient.getImageLayer to simplify patch

* Generalize naming
2018-10-11 19:25:25 -04:00
Tim 857573f10f Fix Mesa biome entry tags in the BiomeDictionary (#5177) 2018-10-07 12:37:23 -07:00
LexManos 76c138c400 Bump version number for RB. 2018-10-04 00:34:49 -07:00
Ben Staddon 55a7c6d64b Add a notification event for handling game rule changes (#5152) 2018-10-04 00:27:17 -07:00
Ben Staddon 0fb8844623 Patch PotionHelper to use registry delegates (#5142) 2018-10-04 00:25:58 -07:00
Ben Staddon 6337466735 Prevent some texture loading errors from crashing the game (#5121) 2018-10-04 00:24:51 -07:00
Ben Staddon 214275baba Change biome spawn list entries to use factory method where possible (#5075) 2018-10-04 00:24:01 -07:00
Ben Staddon 82262e462e Change universal bucket support to use fluid names instead of instances (#5031) 2018-10-04 00:20:44 -07:00
tterrag ee0d43bbde Fix NPE on clientside entities constructed with null world (#5170) 2018-09-28 12:32:19 -07:00
tterrag 93b704b459 Fix patches from #5160 running on the client and causing stutter 2018-09-27 21:42:06 -04:00
gegy1000 10036aa764 Class transformer optimizations (#5159)
* Filter packages for deobf transformation
* Only serialize transformed class with TerminalTransformer if bytecode changed
2018-09-27 14:27:21 -07:00
mezz fcd00bd4af Update github stale so issues can be Assigned 2018-09-26 21:22:54 -07:00
Gabriel Harris-Rouquette c20a5e8805 Fix MC-136995 - Chunk loading and unloading issue with entities placed in exact positions. (#5160)
Scatter gun patches to improve entity tracking and position tracking. 
Provided by Aikar through the Paper project, this commit of patches combines the following patches:

https://github.com/PaperMC/Paper/blob/fd1bd5223a461b6d98280bb8f2d67280a30dd24a/Spigot-Server-Patches/0306-Mark-chunk-dirty-anytime-entities-change-to-guarante.patch
https://github.com/PaperMC/Paper/blob/fd1bd5223a461b6d98280bb8f2d67280a30dd24a/Spigot-Server-Patches/0315-Always-process-chunk-registration-after-moving.patch
https://github.com/PaperMC/Paper/blob/fd1bd5223a461b6d98280bb8f2d67280a30dd24a/Spigot-Server-Patches/0335-Ensure-chunks-are-always-loaded-on-hard-position-set.patch
https://github.com/PaperMC/Paper/blob/fd1bd5223a461b6d98280bb8f2d67280a30dd24a/Spigot-Server-Patches/0378-Sync-Player-Position-to-Vehicles.patch
2018-09-26 11:08:30 -07:00
204 changed files with 6670 additions and 1359 deletions

No files matched your search

+3 -5
View File
@@ -6,15 +6,15 @@ staleLabel: Stale
unmarkComment: false
# Limit the number of actions per hour, from 1-30. Default is 30
limitPerRun: 1
# Issues with these labels will never be considered stale. Set to `[]` to disable
exemptLabels:
- Assigned
pulls:
# Number of days of inactivity before a Pull Request becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale Pull Request is closed
daysUntilClose: 14
# Pull Requests with these labels will never be considered stale. Set to `[]` to disable
exemptLabels:
- Assigned
# Comment to post when marking as stale. Set to `false` to disable
markComment: >
This pull request has been automatically marked as stale because it has not had recent
@@ -30,8 +30,6 @@ issues:
daysUntilStale: 180
# Number of days of inactivity before a stale Issue is closed
daysUntilClose: 14
# Issues with these labels will never be considered stale. Set to `[]` to disable
exemptLabels: []
# Comment to post when marking as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had activity
Vendored
+112
View File
@@ -0,0 +1,112 @@
@Library('forge-shared-library')_
pipeline {
options {
disableConcurrentBuilds()
}
agent {
docker {
image 'gradlewrapper:latest'
args '-v gradlecache:/gradlecache'
}
}
environment {
GRADLE_ARGS = '--no-daemon --console=plain' // No daemon for now as FG3 kinda derps. //'-Dorg.gradle.daemon.idletimeout=5000'
DISCORD_WEBHOOK = credentials('forge-discord-jenkins-webhook')
DISCORD_PREFIX = "Job: Forge Branch: ${BRANCH_NAME} Build: #${BUILD_NUMBER}"
JENKINS_HEAD = 'https://wiki.jenkins-ci.org/download/attachments/2916393/headshot.png'
}
stages {
stage('fetch') {
steps {
checkout scm
}
}
stage('notify_start') {
when {
not {
changeRequest()
}
}
steps {
discordSend(
title: "${DISCORD_PREFIX} Started",
successful: true,
result: 'ABORTED', //White border
thumbnail: JENKINS_HEAD,
webhookURL: DISCORD_WEBHOOK
)
}
}
stage('ciWriteBuildNumber') {
steps {
sh './gradlew ${GRADLE_ARGS} --refresh-dependencies --continue ciWriteBuildNumber'
script {
env.MYGROUP = sh(returnStdout: true, script: './gradlew properties -q | grep "group:" | awk \'{print $2}\'').trim()
env.MYARTIFACT = sh(returnStdout: true, script: './gradlew properties -q | grep "name:" | awk \'{print $2}\'').trim()
env.MYVERSION = sh(returnStdout: true, script: './gradlew properties -q | grep "version:" | awk \'{print $2}\'').trim()
}
}
}
stage('changelog') {
when {
not {
changeRequest()
}
}
steps {
writeChangelog(currentBuild, 'build/changelog_new.txt')
}
}
stage('publish') {
when {
not {
changeRequest()
}
}
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} uploadArchives -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/${MYGROUP}.${MYARTIFACT}/${MYVERSION}'
}
}
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
when {
changeRequest()
}
environment {
CROWDIN = credentials('forge-crowdin')
}
steps {
sh './gradlew ${GRADLE_ARGS} uploadArchives -PcrowdinKey=${CROWDIN}'
}
}
}
post {
always {
script {
//archiveArtifacts artifacts: 'projects/forge/build/libs/**/*.*', fingerprint: true, onlyIfSuccessful: true, allowEmptyArchive: true
//junit 'build/test-results/*/*.xml'
//jacoco sourcePattern: '**/src/*/java'
if (env.CHANGE_ID == null) { // This is unset for non-PRs
discordSend(
title: "${DISCORD_PREFIX} Finished ${currentBuild.currentResult}",
description: '```\n' + getChanges(currentBuild) + '\n```',
successful: currentBuild.resultIsBetterOrEqualTo("SUCCESS"),
result: currentBuild.currentResult,
thumbnail: JENKINS_HEAD,
webhookURL: DISCORD_WEBHOOK
)
}
}
}
}
}
+53 -42
View File
@@ -4,14 +4,18 @@ buildscript {
mavenCentral()
maven {
name = "forge"
url = "http://files.minecraftforge.net/maven"
url = "https://files.minecraftforge.net/maven"
}
maven {
name = "sonatype"
url = "https://oss.sonatype.org/content/repositories/snapshots/"
}
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath 'edu.sc.seis.launch4j:launch4j:2.4.6'
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
}
}
@@ -22,7 +26,7 @@ plugins {
apply plugin: "maven"
def patcher_plugin = plugins.apply('net.minecraftforge.gradle.patcher')
apply plugin: "net.minecraftforge.gradle.launch4j"
apply plugin: 'edu.sc.seis.launch4j'
minecraft.version = "1.12.2"
@@ -57,6 +61,20 @@ minecraft {
}
}
ext {
//Dirty hack, but keeps our unique version system on new jenkins
BUILD_NUMBER = 2838 + (System.getenv('BUILD_NUMBER') ?: project.ext.properties.buildNumber ?: 0).toInteger()
JAR_SIGNER = [:]
if (project.hasProperty('keystore')) {
JAR_SIGNER = [
storepass: project.properties.keystoreStorePass,
keypass: project.properties.keystoreKeyPass,
keystore: project.properties.keystore
]
}
}
group = 'net.minecraftforge'
version = getVersionFromJava(file("src/main/java/net/minecraftforge/common/ForgeVersion.java"))
@@ -88,6 +106,7 @@ license {
header = project.file('LICENSE-header.txt')
include 'net/minecraftforge/'
exclude 'net/minecraftforge/api/distmarker/'
exclude 'net/minecraftforge/fml/repackage/'
exclude 'net/minecraftforge/server/terminalconsole/'
exclude 'net/minecraftforge/fml/common/versioning/ComparableVersion.java'
@@ -105,20 +124,20 @@ license {
}
}
task changelog(type: JenkinsChangelog) {
// skip if there is no forge jenkins pass
onlyIf {
project.hasProperty('forgeJenkinsPass')
task changelog() {
ext {
changelog_old = rootProject.file('legacy_changelog.txt')
changelog_new = rootProject.file('build/changelog_new.txt')
output = rootProject.file('build/changelog.txt')
}
inputs.file changelog_old
if (changelog_new.exists())
inputs.file changelog_new
outputs.file output
doLast {
output.text = changelog_new.text + '\n' + changelog_old.text
}
outputs.upToDateWhen { false } // never up to date
serverRoot = "http://ci.jenkins.minecraftforge.net/"
jobName = "minecraftforge"
targetBuild = System.env['BUILD_NUMBER'] ?: project.ext.properties.buildNumber ?:0;
authName = "console_script"
authPassword = project.hasProperty('forgeJenkinsPass') ? project.getProperty('forgeJenkinsPass') : "";
output = "build/distributions/${project.name}-${project.version}-changelog.txt"
}
task crowdin(type: CrowdinDownload) {
@@ -135,10 +154,9 @@ def extraTxts = [
"CREDITS.txt",
"LICENSE.txt",
"LICENSE-Paulscode SoundSystem CodecIBXM.txt",
"LICENSE-Paulscode IBXM Library.txt"
"LICENSE-Paulscode IBXM Library.txt",
changelog
]
if (project.hasProperty('forgeJenkinsPass'))
extraTxts += changelog
import groovy.json.JsonSlurper;
import groovy.json.JsonBuilder;
@@ -224,16 +242,11 @@ task signUniversal(type: SignJar, dependsOn: 'outputJar') {
project.hasProperty('jarsigner')
}
def jarsigner = [:];
if (project.hasProperty('jarsigner'))
jarsigner = project.jarsigner;
alias = 'forge'
exclude "paulscode/**"
storePass = jarsigner.storepass
keyPass = jarsigner.keypass
keyStore = jarsigner.keystore
storePass = JAR_SIGNER.storepass
keyPass = JAR_SIGNER.keypass
keyStore = JAR_SIGNER.keystore
inputFile = outputJar.archivePath
outputFile = outputJar.archivePath
}
@@ -274,34 +287,34 @@ tasks.build.dependsOn makeMdk
launch4j {
jar = installer.archivePath.canonicalPath
outfile = file("build/distributions/${project.name}-${project.version}-installer-win.exe").canonicalPath
outfile = "${project.name}-${project.version}-installer-win.exe"
icon = file('icon.ico').canonicalPath
manifest = file('l4jManifest.xml').canonicalPath
jreMinVersion = '1.8.0'
initialHeapPercent = 5;
maxHeapPercent = 100;
jreMinVersion = '1.8.0_101'
initialHeapPercent = 5
maxHeapPercent = 100
}
tasks.generateXmlConfig.dependsOn installer
tasks.createExe.dependsOn installer
tasks.build.dependsOn 'launch4j'
// MAVEN
artifacts {
if (project.hasProperty('forgeJenkinsPass'))
archives changelog.output
archives file("build/distributions/${project.name}-${project.version}-installer-win.exe")
archives(changelog.outputs.files.singleFile) {
classifier = 'changelog'
}
archives file('build/' + launch4j.outputDir + '/' + launch4j.outfile)
archives makeMdk
}
task ciWriteBuildNumber << {
def file = file("src/main/java/net/minecraftforge/common/ForgeVersion.java");
def bn = System.getenv("BUILD_NUMBER")?:project.ext.properties.buildNumber?:0;
def outfile = "";
def ln = "\n"; //Linux line endings because we're on git!
file.eachLine{ String s ->
if (s.matches("^ public static final int buildVersion = [\\d]+;\$"))
s = " public static final int buildVersion = ${bn};";
s = " public static final int buildVersion = ${BUILD_NUMBER};";
if (s.matches('^ public static final String mcVersion = "[^\\"]+";'))
s = " public static final String mcVersion = \"${minecraft.version}\";";
outfile += (s+ln);
@@ -314,15 +327,14 @@ uploadArchives {
dependsOn 'build'
if (project.hasProperty('forgeMavenPass'))
if (project.hasProperty('forgeMavenPassword'))
{
repository(url: "http://files.minecraftforge.net/maven/manage/upload") {
authentication(userName: "forge", password: project.getProperty('forgeMavenPass')) // the elvis operator. look it up.
repository(url: "https://files.minecraftforge.net/maven/manage/upload") {
authentication(userName: project.getProperty('forgeMavenUser'), password: project.getProperty('forgeMavenPassword'))
}
}
else
{
// local repo folder. Might wanna juset use gradle install if you wanans end it to maven-local
repository(url: 'file://localhost/' + project.file('repo').getAbsolutePath())
}
@@ -422,8 +434,7 @@ String getVersionFromJava(File file)
}
}
build = System.getenv("BUILD_NUMBER") ?: project.ext.properties.buildNumber ?: 0
build = BUILD_NUMBER
String branch = null;
if (!System.getenv().containsKey("GIT_BRANCH"))
+430
View File
@@ -0,0 +1,430 @@
Build 2838:
bs2609: Fix vanilla handling of options file (MC-117449, MC-151173) (#5725)
Build 2837:
clienthax: Update EnumHelper to be compatible with Eclipse's OpenJ9 JVM. (#5712)
Build 2836:
tterrag:
Revert "Invalidate tile entities that are queued for removal (#5512)"
This reverts commit 75788f63eea6c33ccef7e5cbcab27ad9ad2c2a04.
This solution is invalid as TEs are free to modify the world
tileEntities list, usually indirectly via chunkloading, from inside
invalidate().
This happens in vanilla, in TileEntityChest#invalidate, where it calls
checkForAdjacentChests(), which has the potential to load neighboring
chunks and cause a CME.
A more sophisticated solution is needed.
Build 2835:
bs2609: Fix some vertex format changes not being handled correctly (#5368)
Build 2834:
bs2609:
Transform vertex normals as well as positions when generating quads
(#5242)
Build 2833:
rseifert.phone: Fix for SidedInvWrapper isItemValid using wrong slot (#5642)
Build 2832:
bs2609: Invalidate tile entities that are queued for removal (#5512)
Build 2831:
lclc98: Added Wool to OreDictionary (#5414)
Build 2830:
CreativeMD: Fixed boat not taking care of block-liquid hooks (#5086)
Build 2829:
bs2609: Add Forge dimension-changing hooks to spectator handling code (#5212)
Build 2828:
ichttt:
Minor performace improvement when building chunks and rendering blocks
(#5286)
Build 2827:
bs2609: Catch json parsing errors from constants/factories files (#5258)
Build 2826:
bs2609: Allow custom DataSerializers to be registered safely (#5245)
Build 2825:
cpw:
Try and make 1.13 mods more obviously wrong in 1.12..
Signed-off-by: cpw <[email protected]>
Build 2824:
tterrag: Fix #5651 Re-add canPlaceBlockOnSide check in World#mayPlace
Build 2823:
Pokechu022:
Fail fast when null is used with setTag instead of crashing in
writeEntry (#5257)
Build 2822:
tterrag: Fix block placement not checking for player collision
Build 2821:
wynprice999: Added more Constants (#5323)
Build 2820:
python0429: [1.12.2] Add a few events pertaining to villages (#5302)
Build 2819:
Tyler Hancock: [1.12] Fix special spawn event not firing in many cases. (#5389)
Build 2818:
bs2609: Only prompt for missing registries on local worlds (#5348)
Build 2817:
ckrier.3000: Add EntityPlaceEvent (#5057)
Build 2816:
bs2609: Generalise EnumRarity to an interface (#5182)
Build 2815:
bs2609: Apply access-level changes to inner class attributes (#5468)
Build 2814:
bs2609: Fix small logic error in ItemTextureQuadConverter (#5463)
Build 2813:
bs2609: Better support for custom bows (#5209)
Build 2812:
CovertJaguar: Remove FluidStack amount from hashcode calculation (#5272)
molecularphylo:
Fixed incorrect string representation of string list config property
default values in their comments.
bs2609:
Improve tracking of used dimension IDs (#5249)
Closes #5378 Large dimension IDs bloat level.data
Build 2811:
bs2609:
Fix up torch placement logic to handle more vanilla special-casing
(#5426)
Build 2810:
LexManos: Written size does not include int bytes.
Build 2809:
LexManos:
Extend Region files to support >1MB per chunk. If the 'sector count' is
255, ask the compressed data header for the proper length.
Build 2808:
tterrag1098: Add default impl to IConfigElement#getValidValuesDisplay
Build 2807:
tterrag: Simplify custom item rendering by removing GL emissivity hacks
Build 2806:
tterrag: Support diffuse lighting flag in item rendering
Build 2805:
bs2609:
Add a hook to allow continuously using items through stack changes
(#4834)
* Add a hook to allow continuously using items through stack changes
* Update licences
Build 2804:
oOMitchOo:
Added an additional constructor to every implementation of IFluidBlock.
It is now possible to create a fluid block with a Fluid, Material and
MapColor, so that the Material's MapColor isn't used for the blocks
MapColor. (#5293)
Build 2803:
bs2609: Add redirects to PotionEffect to respect registry replacement (#5213)
Build 2802:
alexiy.ov:
Add an annotation for @Config elements which will automatically create a
slider control (#5026)
Build 2801:
bs2609: Fix small logic error in emissive item rendering code (#5320)
Build 2800:
molecularphylo:
Allow config GUI cycling button elements generated from enums to display
toString return values, rather than actual values. (#5125)
Build 2799:
bs2609: Fix incorrect indexing in mipmap generation code (#5201)
Build 2798:
bs2609:
Ensure slave maps are cleaned up when handling registry overrides
(#5250)
Build 2797:
d_scalzi: Fix issue with --modListFile. (#5316)
Build 2796:
LexManos:
Fix potential issues with the Minecraft FakePlayer lingering around
after world unloads.
Build 2795:
tterrag: Fix potion remove event not always firing, add expiry event
Build 2794:
tterrag: Clean up CraftingHelper constants loading API
Build 2793:
tterrag: Fix crash from CraftingHelper due to FileSystem being closed early
Build 2792:
tterrag:
added PotionHooks, closes #3867, #4375 (#4614)
* solved merge confilct
* improved var names & removed tabs
* Added spaces around !=
* fixed typo
Build 2791:
tterrag:
Add a hook for farmland watering (#4891)
* Add a FarmlandWaterCheckEvent to allow mods to override when Farmland
is watered or not
* revert 1.12.2 json
* Move the farmland patch to a ticket based instead of a event based
system
* Minor changes
* Faster isValid checks, faster validation/invalidation if the state did
not change, expand test mod to include a test for the validation system
* remove isValid boolean flag, we can express it with the tick counter
* Fix test mod resource warnings
* Remove tick timeout, add a javadoc note to invalidate on chunk unload,
cleaned up test mod
* Allow mods to provide custom handling to determine if a pos is valid
or not
* Make SimpleTicket more simple, make register public so custom tickets
can be registered
* Fixes for review
* Add missing license headers
* Use a weak hash set
* Split up the map into smaller chunk based maps
* Add missing license headers
* Make MultiTicketManager more universal for custom implementations,
cleanup imports
Build 2790:
tterrag:
Add methods to allow loading json constants outside of _constants
(#4975)
* add interface methods for loading json constants from an arbitary file
* use try-with-resources
* don't make modders create jsoncontext, clean up resource use
* very minor cleanup
Build 2789:
tterrag:
Compute ASMDataTable submaps parallel, speeds up contructing mods
(#5246)
* Compute submaps parallel, speeds up contructing mods by a lot
* Use stream API better
Build 2788:
mezz: Add logging for data manager key registration errors (#5129)
Build 2787:
mezz: Improve support for custom block path types (#5203)
Build 2786:
mezz: Fix missing comments in configs created with annotations (#5189)
Build 2785:
mezz: Allow items to control the rate of repair from mending (#5102)
Build 2784:
mezz: Improve exception handling from server starting events (#5226)
Build 2783:
mezz: Improve context provided by potion icon rendering hooks (#5111)
Build 2782:
mezz: Fix an ObjectHolderRef internal error message (#5214)
Build 2781:
mezz: Implement rendering for item models with emissive quads (#5047)
Build 2780:
mezz: Clean up logged mod states (#5227)
mezz: Fix minor issue in getFilledPercentage for Fluid rendering (#5206)
Build 2779:
mezz: Improve reflection helper methods (#4853)
mezz: Fix inaccurate main thread name shown in client log (#5078)
Build 2778:
mezz: Fix Baked Item models with transformations (#5241)
Build 2777:
mezz:
Re-add some missing villager profession patches (#5200)
* Fix zombie villagers only spawning with vanilla professions
* Fix spawning modded villagers that do not have their own building
mezz: Fix missing string parameters in some log messages (#5210)
mezz: Stop firing LivingSetAttackTargetEvent for setRevengeTarget (#5217)
mezz: Prevent RecipeBook from crashing on empty modded ingredients (#5234)
Build 2776:
mezz: Fix the bed position given to the SleepingTimeCheck event (#5107)
Build 2775:
LexManos: Fix some null returns from defaulted registries (#5235)
Build 2774:
LexManos:
Only remove synthetic lambda methods referenced in body of SideOnly
methods (#5127)
Build 2773:
LexManos:
A different approach to my changes in
https://github.com/MinecraftForge/MinecraftForge/commit/8ace535995522bec0557d4217e0d98b3dc76cf1e
to fix #5207
LexManos: Fix patches from #5160 setting rotation as well as position (#5233)
LexManos: Use HTTPS for files website.
Build 2772:
tterrag: Make Forge-provided default transforms accessible to custom models
tterrag:
Make Forge blockstate variants correctly inherit AO setting from vanilla
models (#5190)
* Make Forge blockstate variants correctly inherit AO setting
* Move variant format checks into variant, check for added properties
* Small code cleanup
tterrag: fixed visual bug with guislider
tterrag:
Allow IModel to express itself as a vanilla parent (#5195)
* Fix errors caused by fancy missing model being non-vanilla parent
* Switch instanceof checks to a default IModel method
* Small code tweaks
Build 2771:
tterrag: Add CreativeTabs#getLabelColor
Build 2770:
tterrag:
Allow providing a BufferedImage for banner render generation (#5041)
* Adds an Event to allow providing a BufferedImage for the banner render
generation (cached)
textures, since banners don't use an atlas.
implementation.
* Missed some copyright; might as well absolut text match, I guess
* Remove unneeded patch change
* Fix event variable access convention
* Formatting fix
* Improve event handling registration
* Import cleanup
* Replace event approach with Supplier approach
* Better name for test mod (now that it's no longer an event); adds
ENABLE flag
* Moves MC code into
net.minecraftforge.client.MinecraftForgeClient.getImageLayer to simplify
patch
* Generalize naming
Build 2769:
mezz: Fix Mesa biome entry tags in the BiomeDictionary (#5177)
Build 2768:
LexManos: Bump version number for RB.
Build 2767:
LexManos:
Change biome spawn list entries to use factory method where possible
(#5075)
LexManos: Prevent some texture loading errors from crashing the game (#5121)
LexManos: Patch PotionHelper to use registry delegates (#5142)
LexManos: Add a notification event for handling game rule changes (#5152)
Build 2766:
LexManos:
Change universal bucket support to use fluid names instead of instances
(#5031)
Build 2765:
LexManos: Fix NPE on clientside entities constructed with null world (#5170)
Build 2764:
tterrag: Fix patches from #5160 running on the client and causing stutter
Build 2763:
LexManos:
Class transformer optimizations (#5159)
* Filter packages for deobf transformation
* Only serialize transformed class with TerminalTransformer if bytecode
changed
Build 2762:
github: Update github stale so issues can be Assigned
Build 2761:
LexManos:
Fix MC-136995 - Chunk loading and unloading issue with entities placed
in exact positions. (#5160)
Scatter gun patches to improve entity tracking and position tracking.
Provided by Aikar through the Paper project, this commit of patches
combines the following patches:
https://github.com/PaperMC/Paper/blob/fd1bd5223a461b6d98280bb8f2d67280a30dd24a/Spigot-Server-Patches/0306-Mark-chunk-dirty-anytime-entities-change-to-guarante.patch
https://github.com/PaperMC/Paper/blob/fd1bd5223a461b6d98280bb8f2d67280a30dd24a/Spigot-Server-Patches/0315-Always-process-chunk-registration-after-moving.patch
https://github.com/PaperMC/Paper/blob/fd1bd5223a461b6d98280bb8f2d67280a30dd24a/Spigot-Server-Patches/0335-Ensure-chunks-are-always-loaded-on-hard-position-set.patch
https://github.com/PaperMC/Paper/blob/fd1bd5223a461b6d98280bb8f2d67280a30dd24a/Spigot-Server-Patches/0378-Sync-Player-Position-to-Vehicles.patch
Build 2760:
LexManos: Fix --mods and --modListFile arguments not making it past LaunchWrapper.
Build 2759:
LexManos: Remove BlamingTransformer (#5115)
+1 -1
View File
@@ -1,7 +1,7 @@
buildscript {
repositories {
jcenter()
maven { url = "http://files.minecraftforge.net/maven" }
maven { url = "https://files.minecraftforge.net/maven" }
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
@@ -221,7 +221,7 @@
public SoundType func_185467_w()
{
return this.field_149762_H;
@@ -934,6 +952,1361 @@
@@ -934,6 +952,1388 @@
{
}
@@ -837,13 +837,18 @@
+ */
+ public boolean canPlaceTorchOnTop(IBlockState state, IBlockAccess world, BlockPos pos)
+ {
+ if (state.func_185896_q() || state.func_193401_d(world, pos, EnumFacing.UP) == BlockFaceShape.SOLID)
+ if (this == Blocks.field_185775_db || this == Blocks.field_150428_aP)
+ {
+ return this != Blocks.field_185775_db && this != Blocks.field_150428_aP;
+ return false;
+ }
+ else if (state.func_185896_q() || this instanceof BlockFence || this == Blocks.field_150359_w || this == Blocks.field_150463_bK || this == Blocks.field_150399_cn)
+ {
+ return true;
+ }
+ else
+ {
+ return this instanceof BlockFence || this == Blocks.field_150359_w || this == Blocks.field_150463_bK || this == Blocks.field_150399_cn;
+ BlockFaceShape shape = state.func_193401_d(world, pos, EnumFacing.UP);
+ return (shape == BlockFaceShape.SOLID || shape == BlockFaceShape.CENTER || shape == BlockFaceShape.CENTER_BIG) && !func_193384_b(this);
+ }
+ }
+
@@ -1403,6 +1408,20 @@
+ {
+ return null;
+ }
+
+ /**
+ * Called when entities are swimming in the given liquid and returns the relative height (used by {@link net.minecraft.entity.item.EntityBoat})
+ *
+ * @param world world that is being tested.
+ * @param pos block thats being tested.
+ * @param state state at world/pos
+ * @param material liquid thats being tested.
+ * @return relative height of the given liquid (material), a value between 0 and 1
+ */
+ public float getBlockLiquidHeight(World world, BlockPos pos, IBlockState state, Material material)
+ {
+ return 0;
+ }
+
+ /**
+ * Queries if this block should render in a given layer.
@@ -1540,15 +1559,23 @@
+ return false;
+ }
+
+ /** @deprecated use {@link #getAiPathNodeType(IBlockState, IBlockAccess, BlockPos, net.minecraft.entity.EntityLiving)} */
+ @Nullable
+ @Deprecated // TODO: remove
+ public net.minecraft.pathfinding.PathNodeType getAiPathNodeType(IBlockState state, IBlockAccess world, BlockPos pos)
+ {
+ return isBurning(world, pos) ? net.minecraft.pathfinding.PathNodeType.DAMAGE_FIRE : null;
+ }
+
+ /**
+ * Get the {@code PathNodeType} for this block. Return {@code null} for vanilla behavior.
+ *
+ * @return the PathNodeType
+ */
+ @Nullable
+ public net.minecraft.pathfinding.PathNodeType getAiPathNodeType(IBlockState state, IBlockAccess world, BlockPos pos)
+ public net.minecraft.pathfinding.PathNodeType getAiPathNodeType(IBlockState state, IBlockAccess world, BlockPos pos, @Nullable net.minecraft.entity.EntityLiving entity)
+ {
+ return isBurning(world, pos) ? net.minecraft.pathfinding.PathNodeType.DAMAGE_FIRE : null;
+ return getAiPathNodeType(state, world, pos);
+ }
+
+ /**
@@ -1583,7 +1610,7 @@
public static void func_149671_p()
{
func_176215_a(0, field_176230_a, (new BlockAir()).func_149663_c("air"));
@@ -1105,7 +2478,7 @@
@@ -1105,7 +2505,7 @@
Block block11 = (new BlockQuartz()).func_149672_a(SoundType.field_185851_d).func_149711_c(0.8F).func_149663_c("quartzBlock");
func_176219_a(155, "quartz_block", block11);
func_176219_a(156, "quartz_stairs", (new BlockStairs(block11.func_176223_P().func_177226_a(BlockQuartz.field_176335_a, BlockQuartz.EnumType.DEFAULT))).func_149663_c("stairsQuartz"));
@@ -1592,7 +1619,7 @@
func_176219_a(158, "dropper", (new BlockDropper()).func_149711_c(3.5F).func_149672_a(SoundType.field_185851_d).func_149663_c("dropper"));
func_176219_a(159, "stained_hardened_clay", (new BlockStainedHardenedClay()).func_149711_c(1.25F).func_149752_b(7.0F).func_149672_a(SoundType.field_185851_d).func_149663_c("clayHardenedStained"));
func_176219_a(160, "stained_glass_pane", (new BlockStainedGlassPane()).func_149711_c(0.3F).func_149672_a(SoundType.field_185853_f).func_149663_c("thinStainedGlass"));
@@ -1230,31 +2603,6 @@
@@ -1230,31 +2630,6 @@
block15.field_149783_u = flag;
}
}
@@ -18,3 +18,12 @@
}
private boolean func_176530_e(World p_176530_1_, BlockPos p_176530_2_)
@@ -108,7 +108,7 @@
}
}
- return false;
+ return net.minecraftforge.common.FarmlandWaterManager.hasBlockWaterTicket(p_176530_1_, p_176530_2_);
}
public void func_189540_a(IBlockState p_189540_1_, World p_189540_2_, BlockPos p_189540_3_, Block p_189540_4_, BlockPos p_189540_5_)
@@ -17,7 +17,17 @@
this.func_180688_d(p_176365_1_, p_176365_2_);
return true;
}
@@ -452,4 +452,29 @@
@@ -448,8 +448,39 @@
return (float)p_190972_2_.func_177956_o() + func_190973_f(p_190972_0_, p_190972_1_, p_190972_2_);
}
+ @Override
+ public float getBlockLiquidHeight(World world, BlockPos pos, IBlockState state, Material material)
+ {
+ return BlockLiquid.func_190973_f(state, world, pos);
+ }
+
public BlockFaceShape func_193383_a(IBlockAccess p_193383_1_, IBlockState p_193383_2_, BlockPos p_193383_3_, EnumFacing p_193383_4_)
{
return BlockFaceShape.UNDEFINED;
}
@@ -27,12 +27,13 @@
}
public void func_176213_c(World p_176213_1_, BlockPos p_176213_2_, IBlockState p_176213_3_)
@@ -93,27 +93,27 @@
@@ -93,32 +93,33 @@
{
if (!p_189540_2_.field_72995_K)
{
- BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = (BlockRailBase.EnumRailDirection)p_189540_1_.func_177229_b(this.func_176560_l());
+ BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = getRailDirection(p_189540_2_, p_189540_3_, p_189540_2_.func_180495_p(p_189540_3_), null);
+ final IBlockState currentState = p_189540_2_.func_180495_p(p_189540_3_);
+ BlockRailBase.EnumRailDirection blockrailbase$enumraildirection = getRailDirection(p_189540_2_, p_189540_3_, currentState.func_177230_c() == this ? currentState : p_189540_1_, null);
boolean flag = false;
- if (!p_189540_2_.func_180495_p(p_189540_3_.func_177977_b()).func_185896_q())
@@ -61,7 +62,13 @@
{
flag = true;
}
@@ -154,7 +154,7 @@
- if (flag && !p_189540_2_.func_175623_d(p_189540_3_))
+ if (flag && !currentState.func_177230_c().isAir(currentState, p_189540_2_, p_189540_3_))
{
this.func_176226_b(p_189540_2_, p_189540_3_, p_189540_1_, 0);
p_189540_2_.func_175698_g(p_189540_3_);
@@ -154,7 +155,7 @@
{
super.func_180663_b(p_180663_1_, p_180663_2_, p_180663_3_);
@@ -70,7 +77,7 @@
{
p_180663_1_.func_175685_c(p_180663_2_.func_177984_a(), this, false);
}
@@ -166,8 +166,101 @@
@@ -166,8 +167,101 @@
}
}
@@ -172,7 +179,7 @@
public static enum EnumRailDirection implements IStringSerializable
{
NORTH_SOUTH(0, "north_south"),
@@ -238,6 +331,7 @@
@@ -238,6 +332,7 @@
private IBlockState field_180366_e;
private final boolean field_150656_f;
private final List<BlockPos> field_150657_g = Lists.<BlockPos>newArrayList();
@@ -180,7 +187,7 @@
public Rail(World p_i45739_2_, BlockPos p_i45739_3_, IBlockState p_i45739_4_)
{
@@ -245,8 +339,9 @@
@@ -245,8 +340,9 @@
this.field_180367_c = p_i45739_3_;
this.field_180366_e = p_i45739_4_;
this.field_180365_d = (BlockRailBase)p_i45739_4_.func_177230_c();
@@ -192,7 +199,7 @@
this.func_180360_a(blockrailbase$enumraildirection);
}
@@ -438,7 +533,7 @@
@@ -438,7 +534,7 @@
}
}
@@ -201,7 +208,7 @@
{
if (BlockRailBase.func_176562_d(this.field_150660_b, blockpos.func_177984_a()))
{
@@ -451,7 +546,7 @@
@@ -451,7 +547,7 @@
}
}
@@ -210,7 +217,7 @@
{
if (BlockRailBase.func_176562_d(this.field_150660_b, blockpos3.func_177984_a()))
{
@@ -594,7 +689,7 @@
@@ -594,7 +690,7 @@
}
}
@@ -219,7 +226,7 @@
{
if (BlockRailBase.func_176562_d(this.field_150660_b, blockpos.func_177984_a()))
{
@@ -607,7 +702,7 @@
@@ -607,7 +703,7 @@
}
}
@@ -1,6 +1,14 @@
--- ../src-base/minecraft/net/minecraft/client/Minecraft.java
+++ ../src-work/minecraft/net/minecraft/client/Minecraft.java
@@ -344,7 +344,6 @@
@@ -332,6 +332,7 @@
public Minecraft(GameConfiguration p_i45547_1_)
{
field_71432_P = this;
+ net.minecraftforge.client.ForgeHooksClient.invalidateLog4jThreadCache();
this.field_71412_D = p_i45547_1_.field_178744_c.field_178760_a;
this.field_110446_Y = p_i45547_1_.field_178744_c.field_178759_c;
this.field_130070_K = p_i45547_1_.field_178744_c.field_178758_b;
@@ -344,7 +345,6 @@
this.field_152355_az = (new YggdrasilAuthenticationService(this.field_110453_aa, UUID.randomUUID().toString())).createMinecraftSessionService();
this.field_71449_j = p_i45547_1_.field_178745_a.field_178752_a;
field_147123_G.info("Setting user: {}", (Object)this.field_71449_j.func_111285_a());
@@ -8,7 +16,7 @@
this.field_71459_aj = p_i45547_1_.field_178741_d.field_178756_a;
this.field_71443_c = p_i45547_1_.field_178743_b.field_178764_a > 0 ? p_i45547_1_.field_178743_b.field_178764_a : 1;
this.field_71440_d = p_i45547_1_.field_178743_b.field_178762_b > 0 ? p_i45547_1_.field_178743_b.field_178762_b : 1;
@@ -464,10 +463,10 @@
@@ -464,10 +464,10 @@
this.field_110451_am = new SimpleReloadableResourceManager(this.field_110452_an);
this.field_135017_as = new LanguageManager(this.field_110452_an, this.field_71474_y.field_74363_ab);
this.field_110451_am.func_110542_a(this.field_135017_as);
@@ -21,7 +29,7 @@
this.field_152350_aA = new SkinManager(this.field_71446_o, new File(this.field_110446_Y, "skins"), this.field_152355_az);
this.field_71469_aa = new AnvilSaveConverter(new File(this.field_71412_D, "saves"), this.field_184131_U);
this.field_147127_av = new SoundHandler(this.field_110451_am, this.field_71474_y);
@@ -487,6 +486,8 @@
@@ -487,6 +487,8 @@
this.field_110451_am.func_110542_a(new GrassColorReloadListener());
this.field_110451_am.func_110542_a(new FoliageColorReloadListener());
this.field_71417_B = new MouseHelper();
@@ -30,7 +38,7 @@
this.func_71361_d("Pre startup");
GlStateManager.func_179098_w();
GlStateManager.func_179103_j(7425);
@@ -500,19 +501,24 @@
@@ -500,19 +502,24 @@
GlStateManager.func_179096_D();
GlStateManager.func_179128_n(5888);
this.func_71361_d("Startup");
@@ -55,7 +63,7 @@
this.field_71460_t = new EntityRenderer(this, this.field_110451_am);
this.field_110451_am.func_110542_a(this.field_71460_t);
this.field_175618_aM = new BlockRendererDispatcher(this.field_175617_aL.func_174954_c(), this.field_184127_aH);
@@ -523,23 +529,27 @@
@@ -523,23 +530,27 @@
this.field_110451_am.func_110542_a(this.field_193995_ae);
GlStateManager.func_179083_b(0, 0, this.field_71443_c, this.field_71440_d);
this.field_71452_i = new ParticleManager(this.field_71441_e, this.field_71446_o);
@@ -86,7 +94,7 @@
if (this.field_71474_y.field_74353_u && !this.field_71431_Q)
{
this.func_71352_k();
@@ -748,21 +758,23 @@
@@ -748,21 +759,23 @@
File file2 = new File(file1, "crash-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + "-client.txt");
Bootstrap.func_179870_a(p_71377_1_.func_71502_e());
@@ -113,7 +121,7 @@
}
public boolean func_152349_b()
@@ -770,6 +782,7 @@
@@ -770,6 +783,7 @@
return this.field_135017_as.func_135042_a() || this.field_71474_y.field_151455_aw;
}
@@ -121,7 +129,7 @@
public void func_110436_a()
{
List<IResourcePack> list = Lists.newArrayList(this.field_110449_ao);
@@ -955,11 +968,6 @@
@@ -955,11 +969,6 @@
public void func_147108_a(@Nullable GuiScreen p_147108_1_)
{
@@ -133,7 +141,7 @@
if (p_147108_1_ == null && this.field_71441_e == null)
{
p_147108_1_ = new GuiMainMenu();
@@ -969,6 +977,17 @@
@@ -969,6 +978,17 @@
p_147108_1_ = new GuiGameOver((ITextComponent)null);
}
@@ -151,7 +159,7 @@
if (p_147108_1_ instanceof GuiMainMenu || p_147108_1_ instanceof GuiMultiplayer)
{
this.field_71474_y.field_74330_P = false;
@@ -1082,7 +1101,7 @@
@@ -1082,7 +1102,7 @@
long i1 = System.nanoTime() - l;
this.func_71361_d("Pre render");
this.field_71424_I.func_76318_c("sound");
@@ -160,7 +168,7 @@
this.field_71424_I.func_76319_b();
this.field_71424_I.func_76320_a("render");
GlStateManager.func_179094_E();
@@ -1094,11 +1113,13 @@
@@ -1094,11 +1114,13 @@
if (!this.field_71454_w)
{
@@ -174,7 +182,7 @@
}
this.field_71424_I.func_76319_b();
@@ -1455,9 +1476,9 @@
@@ -1455,9 +1477,9 @@
{
BlockPos blockpos = this.field_71476_x.func_178782_a();
@@ -186,7 +194,7 @@
this.field_71439_g.func_184609_a(EnumHand.MAIN_HAND);
}
}
@@ -1491,7 +1512,7 @@
@@ -1491,7 +1513,7 @@
case BLOCK:
BlockPos blockpos = this.field_71476_x.func_178782_a();
@@ -195,7 +203,7 @@
{
this.field_71442_b.func_180511_b(blockpos, this.field_71476_x.field_178784_b);
break;
@@ -1505,6 +1526,7 @@
@@ -1505,6 +1527,7 @@
}
this.field_71439_g.func_184821_cY();
@@ -203,7 +211,7 @@
}
this.field_71439_g.func_184609_a(EnumHand.MAIN_HAND);
@@ -1570,6 +1592,7 @@
@@ -1570,6 +1593,7 @@
}
}
@@ -211,7 +219,7 @@
if (!itemstack.func_190926_b() && this.field_71442_b.func_187101_a(this.field_71439_g, this.field_71441_e, enumhand) == EnumActionResult.SUCCESS)
{
this.field_71460_t.field_78516_c.func_187460_a(enumhand);
@@ -1630,6 +1653,11 @@
@@ -1630,6 +1654,11 @@
}
Display.setFullscreen(this.field_71431_Q);
@@ -223,7 +231,7 @@
Display.setVSyncEnabled(this.field_71474_y.field_74352_v);
this.func_175601_h();
}
@@ -1676,6 +1704,8 @@
@@ -1676,6 +1705,8 @@
--this.field_71467_ac;
}
@@ -232,7 +240,7 @@
this.field_71424_I.func_76320_a("gui");
if (!this.field_71445_n)
@@ -1877,6 +1907,7 @@
@@ -1877,6 +1908,7 @@
}
this.field_71424_I.func_76319_b();
@@ -240,7 +248,7 @@
this.field_71423_H = func_71386_F();
}
@@ -1982,6 +2013,7 @@
@@ -1982,6 +2014,7 @@
}
}
}
@@ -248,7 +256,7 @@
}
this.func_184117_aA();
@@ -2239,6 +2271,8 @@
@@ -2239,6 +2272,8 @@
{
while (Mouse.next())
{
@@ -257,7 +265,7 @@
int i = Mouse.getEventButton();
KeyBinding.func_74510_a(i - 100, Mouse.getEventButtonState());
@@ -2294,6 +2328,7 @@
@@ -2294,6 +2329,7 @@
this.field_71462_r.func_146274_d();
}
}
@@ -265,7 +273,7 @@
}
}
@@ -2304,6 +2339,7 @@
@@ -2304,6 +2340,7 @@
public void func_71371_a(String p_71371_1_, String p_71371_2_, @Nullable WorldSettings p_71371_3_)
{
@@ -273,14 +281,11 @@
this.func_71403_a((WorldClient)null);
System.gc();
ISaveHandler isavehandler = this.field_71469_aa.func_75804_a(p_71371_1_, false);
@@ -2344,8 +2380,14 @@
@@ -2346,6 +2383,12 @@
this.field_71461_s.func_73720_a(I18n.func_135052_a("menu.loadingLevel"));
- while (!this.field_71437_Z.func_71200_ad())
+ while (!this.field_71437_Z.func_71200_ad() && !this.field_71437_Z.func_71241_aa())
while (!this.field_71437_Z.func_71200_ad())
{
+ if (!net.minecraftforge.fml.common.StartupQuery.check())
+ if (!net.minecraftforge.fml.common.StartupQuery.check() || this.field_71437_Z.func_71241_aa())
+ {
+ func_71403_a(null);
+ func_147108_a(null);
@@ -289,7 +294,7 @@
String s = this.field_71437_Z.func_71195_b_();
if (s != null)
@@ -2371,8 +2413,14 @@
@@ -2371,8 +2414,14 @@
SocketAddress socketaddress = this.field_71437_Z.func_147137_ag().func_151270_a();
NetworkManager networkmanager = NetworkManager.func_150722_a(socketaddress);
networkmanager.func_150719_a(new NetHandlerLoginClient(networkmanager, this, (GuiScreen)null));
@@ -306,7 +311,7 @@
this.field_71453_ak = networkmanager;
}
@@ -2383,6 +2431,8 @@
@@ -2383,6 +2432,8 @@
public void func_71353_a(@Nullable WorldClient p_71353_1_, String p_71353_2_)
{
@@ -315,7 +320,7 @@
if (p_71353_1_ == null)
{
NetHandlerPlayClient nethandlerplayclient = this.func_147114_u();
@@ -2395,6 +2445,18 @@
@@ -2395,6 +2446,18 @@
if (this.field_71437_Z != null && this.field_71437_Z.func_175578_N())
{
this.field_71437_Z.func_71263_m();
@@ -334,7 +339,7 @@
}
this.field_71437_Z = null;
@@ -2418,6 +2480,7 @@
@@ -2418,6 +2481,7 @@
this.field_71456_v.func_181029_i();
this.func_71351_a((ServerData)null);
this.field_71455_al = false;
@@ -342,7 +347,7 @@
}
this.field_147127_av.func_147690_c();
@@ -2434,6 +2497,7 @@
@@ -2434,6 +2498,7 @@
}
TileEntityRendererDispatcher.field_147556_a.func_147543_a(p_71353_1_);
@@ -350,7 +355,7 @@
if (p_71353_1_ != null)
{
@@ -2488,6 +2552,7 @@
@@ -2488,6 +2553,7 @@
EntityPlayerSP entityplayersp = this.field_71439_g;
this.field_71439_g = this.field_71442_b.func_192830_a(this.field_71441_e, this.field_71439_g == null ? new StatisticsManager() : this.field_71439_g.func_146107_m(), this.field_71439_g == null ? new RecipeBook() : this.field_71439_g.func_192035_E());
this.field_71439_g.func_184212_Q().func_187218_a(entityplayersp.func_184212_Q().func_187231_c());
@@ -358,7 +363,7 @@
this.field_71439_g.field_71093_bK = p_71354_1_;
this.field_175622_Z = this.field_71439_g;
this.field_71439_g.func_70065_x();
@@ -2535,159 +2600,8 @@
@@ -2535,159 +2601,8 @@
{
if (this.field_71476_x != null && this.field_71476_x.field_72313_a != RayTraceResult.Type.MISS)
{
@@ -520,7 +525,7 @@
}
}
@@ -2834,6 +2748,7 @@
@@ -2834,6 +2749,7 @@
return field_71432_P;
}
@@ -528,7 +533,7 @@
public ListenableFuture<Object> func_175603_A()
{
return this.func_152344_a(new Runnable()
@@ -3009,18 +2924,8 @@
@@ -3009,18 +2925,8 @@
public static int func_71369_N()
{
@@ -549,7 +554,7 @@
}
public boolean func_70002_Q()
@@ -3152,6 +3057,9 @@
@@ -3152,6 +3058,9 @@
}
else if (this.field_71439_g != null)
{
@@ -559,7 +564,7 @@
if (this.field_71439_g.field_70170_p.field_73011_w instanceof WorldProviderHell)
{
return MusicTicker.MusicType.NETHER;
@@ -3181,11 +3089,11 @@
@@ -3181,11 +3090,11 @@
{
if (Keyboard.getEventKeyState())
{
@@ -573,7 +578,7 @@
{
this.field_71456_v.func_146158_b().func_146227_a(ScreenShotHelper.func_148260_a(this.field_71412_D, this.field_71443_c, this.field_71440_d, this.field_147124_at));
}
@@ -3199,6 +3107,7 @@
@@ -3199,6 +3108,7 @@
}
}
}
@@ -581,7 +586,7 @@
}
}
}
@@ -3328,6 +3237,12 @@
@@ -3328,6 +3238,12 @@
return this.field_184127_aH;
}
@@ -594,7 +599,7 @@
public boolean func_189648_am()
{
return this.field_71439_g != null && this.field_71439_g.func_175140_cp() || this.field_71474_y.field_178879_v;
@@ -3342,4 +3257,9 @@
@@ -3342,4 +3258,9 @@
{
return this.field_193035_aW;
}
@@ -1,5 +1,14 @@
--- ../src-base/minecraft/net/minecraft/client/entity/AbstractClientPlayer.java
+++ ../src-work/minecraft/net/minecraft/client/entity/AbstractClientPlayer.java
@@ -135,7 +135,7 @@
f = 1.0F;
}
- if (this.func_184587_cr() && this.func_184607_cu().func_77973_b() == Items.field_151031_f)
+ if (this.func_184587_cr() && this.func_184607_cu().func_77973_b() instanceof net.minecraft.item.ItemBow)
{
int i = this.func_184612_cw();
float f1 = (float)i / 20.0F;
@@ -152,6 +152,6 @@
f *= 1.0F - f1 * 0.15F;
}
@@ -29,7 +29,7 @@
+ // FORGE - Move status icon check down from above so renderHUDEffect will still be called without a status icon
+ if (potion.func_76400_d())
this.func_73729_b(k + 3, l + 3, i1 % 8 * 18, 198 + i1 / 8 * 18, 18, 18);
+ potion.renderHUDEffect(k, l, potioneffect, field_73839_d, f);
+ potion.renderHUDEffect(potioneffect, this, k, l, this.field_73735_i, f);
}
}
}
@@ -20,6 +20,15 @@
}
public List<String> func_191927_a(ItemStack p_191927_1_)
@@ -142,7 +146,7 @@
{
if (i == 0)
{
- list.set(i, p_191927_1_.func_77953_t().field_77937_e + (String)list.get(i));
+ list.set(i, p_191927_1_.func_77973_b().getForgeRarity(p_191927_1_).getColor() + (String)list.get(i));
}
else
{
@@ -170,7 +174,13 @@
public void func_146283_a(List<String> p_146283_1_, int p_146283_2_, int p_146283_3_)
@@ -67,7 +67,7 @@
if (this.field_147062_A.func_146179_b().isEmpty())
{
for (Item item : Item.field_150901_e)
@@ -366,7 +403,7 @@
@@ -366,10 +403,10 @@
{
CreativeTabs creativetabs = CreativeTabs.field_78032_a[field_147058_w];
@@ -75,7 +75,11 @@
+ if (creativetabs != null && creativetabs.func_78019_g())
{
GlStateManager.func_179084_k();
this.field_146289_q.func_78276_b(I18n.func_135052_a(creativetabs.func_78024_c()), 8, 6, 4210752);
- this.field_146289_q.func_78276_b(I18n.func_135052_a(creativetabs.func_78024_c()), 8, 6, 4210752);
+ this.field_146289_q.func_78276_b(I18n.func_135052_a(creativetabs.func_78024_c()), 8, 6, creativetabs.getLabelColor());
}
}
@@ -401,7 +438,7 @@
for (CreativeTabs creativetabs : CreativeTabs.field_78032_a)
@@ -160,6 +164,15 @@
GlStateManager.func_179131_c(1.0F, 1.0F, 1.0F, 1.0F);
GlStateManager.func_179140_f();
this.func_191948_b(p_73863_1_, p_73863_2_);
@@ -654,7 +719,7 @@
{
if (i == 0)
{
- list.set(i, p_146285_1_.func_77953_t().field_77937_e + (String)list.get(i));
+ list.set(i, p_146285_1_.func_77973_b().getForgeRarity(p_146285_1_).getColor() + (String)list.get(i));
}
else
{
@@ -662,7 +727,10 @@
}
}
@@ -18,3 +18,12 @@
int l = 1;
Iterator<Ingredient> iterator = p_193951_1_.func_192400_c().iterator();
@@ -500,7 +500,7 @@
Ingredient ingredient = iterator.next();
- if (ingredient != Ingredient.field_193370_a)
+ if (ingredient.func_193365_a().length > 0)
{
Slot slot = p_193951_2_.get(l);
this.field_191915_z.func_194187_a(ingredient, slot.field_75223_e, slot.field_75221_f);
@@ -0,0 +1,20 @@
--- ../src-base/minecraft/net/minecraft/client/model/ModelSkeleton.java
+++ ../src-work/minecraft/net/minecraft/client/model/ModelSkeleton.java
@@ -48,7 +48,7 @@
this.field_187075_l = ModelBiped.ArmPose.EMPTY;
ItemStack itemstack = p_78086_1_.func_184586_b(EnumHand.MAIN_HAND);
- if (itemstack.func_77973_b() == Items.field_151031_f && ((AbstractSkeleton)p_78086_1_).func_184725_db())
+ if (itemstack.func_77973_b() instanceof net.minecraft.item.ItemBow && ((AbstractSkeleton)p_78086_1_).func_184725_db())
{
if (p_78086_1_.func_184591_cq() == EnumHandSide.RIGHT)
{
@@ -69,7 +69,7 @@
ItemStack itemstack = ((EntityLivingBase)p_78087_7_).func_184614_ca();
AbstractSkeleton abstractskeleton = (AbstractSkeleton)p_78087_7_;
- if (abstractskeleton.func_184725_db() && (itemstack.func_190926_b() || itemstack.func_77973_b() != Items.field_151031_f))
+ if (abstractskeleton.func_184725_db() && (itemstack.func_190926_b() || !(itemstack.func_77973_b() instanceof net.minecraft.item.ItemBow)))
{
float f = MathHelper.func_76126_a(this.field_78095_p * (float)Math.PI);
float f1 = MathHelper.func_76126_a((1.0F - (1.0F - this.field_78095_p) * (1.0F - this.field_78095_p)) * (float)Math.PI);
@@ -99,3 +99,12 @@
packetbuffer.release();
}
}
@@ -2087,7 +2099,7 @@
if (iattributeinstance == null)
{
- iattributeinstance = abstractattributemap.func_111150_b(new RangedAttribute((IAttribute)null, spacketentityproperties$snapshot.func_151409_a(), 0.0D, 2.2250738585072014E-308D, Double.MAX_VALUE));
+ iattributeinstance = abstractattributemap.func_111150_b(new RangedAttribute((IAttribute)null, spacketentityproperties$snapshot.func_151409_a(), 0.0D, -Double.MAX_VALUE, Double.MAX_VALUE)); // Forge: fix invalid value range (MC-150405)
}
iattributeinstance.func_111128_a(spacketentityproperties$snapshot.func_151410_b());
@@ -33,7 +33,7 @@
this.func_73729_b(i + 6, j + 7, 0 + i1 % 8 * 18, 198 + i1 / 8 * 18, 18, 18);
}
+ potion.renderInventoryEffect(i, j, potioneffect, field_146297_k);
+ potion.renderInventoryEffect(potioneffect, this, i, j, this.field_73735_i);
+ if (!potion.shouldRenderInvText(potioneffect)) { j += l; continue; }
String s1 = I18n.func_135052_a(potion.func_76393_a());
@@ -14,7 +14,7 @@
ItemStack itemstack = abstractclientplayer.func_184607_cu();
- if (itemstack.func_77973_b() == Items.field_151031_f)
+ if (!itemstack.func_190926_b() && itemstack.func_77973_b() == Items.field_151031_f) //Forge: Data watcher can desync and cause this to NPE...
+ if (itemstack.func_77973_b() instanceof net.minecraft.item.ItemBow)
{
EnumHand enumhand1 = abstractclientplayer.func_184600_cs();
flag = enumhand1 == EnumHand.MAIN_HAND;
@@ -9,7 +9,19 @@
this.func_175041_b();
this.field_184395_f = p_i46552_3_;
}
@@ -137,7 +137,7 @@
@@ -113,6 +113,11 @@
private void func_191967_a(IBakedModel p_191967_1_, int p_191967_2_, ItemStack p_191967_3_)
{
+ if (net.minecraftforge.common.ForgeModContainer.allowEmissiveItems)
+ {
+ net.minecraftforge.client.ForgeHooksClient.renderLitItem(this, p_191967_1_, p_191967_2_, p_191967_3_);
+ return;
+ }
Tessellator tessellator = Tessellator.func_178181_a();
BufferBuilder bufferbuilder = tessellator.func_178180_c();
bufferbuilder.func_181668_a(7, DefaultVertexFormats.field_176599_b);
@@ -137,7 +142,7 @@
{
GlStateManager.func_179131_c(1.0F, 1.0F, 1.0F, 1.0F);
GlStateManager.func_179091_B();
@@ -18,7 +30,7 @@
}
else
{
@@ -218,7 +218,7 @@
@@ -218,7 +223,7 @@
k = k | -16777216;
}
@@ -27,7 +39,7 @@
}
}
@@ -240,17 +240,7 @@
@@ -240,17 +245,7 @@
public IBakedModel func_184393_a(ItemStack p_184393_1_, @Nullable World p_184393_2_, @Nullable EntityLivingBase p_184393_3_)
{
IBakedModel ibakedmodel = this.field_175059_m.func_178089_a(p_184393_1_);
@@ -46,7 +58,7 @@
}
public void func_184392_a(ItemStack p_184392_1_, EntityLivingBase p_184392_2_, ItemCameraTransforms.TransformType p_184392_3_, boolean p_184392_4_)
@@ -274,14 +264,9 @@
@@ -274,14 +269,9 @@
GlStateManager.func_179147_l();
GlStateManager.func_187428_a(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
GlStateManager.func_179094_E();
@@ -63,7 +75,7 @@
this.func_180454_a(p_184394_1_, p_184394_2_);
GlStateManager.func_187407_a(GlStateManager.CullFace.BACK);
GlStateManager.func_179121_F();
@@ -314,7 +299,7 @@
@@ -314,7 +304,7 @@
GlStateManager.func_187401_a(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
GlStateManager.func_179131_c(1.0F, 1.0F, 1.0F, 1.0F);
this.func_180452_a(p_191962_2_, p_191962_3_, p_191962_4_.func_177556_c());
@@ -72,7 +84,7 @@
this.func_180454_a(p_191962_1_, p_191962_4_);
GlStateManager.func_179118_c();
GlStateManager.func_179101_C();
@@ -367,6 +352,7 @@
@@ -367,6 +357,7 @@
return String.valueOf((Object)p_184391_2_.func_77973_b());
}
});
@@ -80,7 +92,7 @@
crashreportcategory.func_189529_a("Item Aux", new ICrashReportDetail<String>()
{
public String call() throws Exception
@@ -413,9 +399,12 @@
@@ -413,9 +404,12 @@
p_180453_1_.func_175063_a(s, (float)(p_180453_3_ + 19 - 2 - p_180453_1_.func_78256_a(s)), (float)(p_180453_4_ + 6 + 3), 16777215);
GlStateManager.func_179145_e();
GlStateManager.func_179126_j();
@@ -94,7 +106,7 @@
{
GlStateManager.func_179140_f();
GlStateManager.func_179097_i();
@@ -424,11 +413,10 @@
@@ -424,11 +418,10 @@
GlStateManager.func_179084_k();
Tessellator tessellator = Tessellator.func_178181_a();
BufferBuilder bufferbuilder = tessellator.func_178180_c();
@@ -110,7 +122,7 @@
this.func_181565_a(bufferbuilder, p_180453_3_ + 2, p_180453_4_ + 13, 13, 2, 0, 0, 0, 255);
this.func_181565_a(bufferbuilder, p_180453_3_ + 2, p_180453_4_ + 13, i, 1, j >> 16 & 255, j >> 8 & 255, j & 255, 255);
GlStateManager.func_179147_l();
@@ -1099,6 +1087,7 @@
@@ -1099,6 +1092,7 @@
this.func_175029_a(Blocks.field_185779_df, TileEntityStructure.Mode.LOAD.func_185110_a(), "structure_block");
this.func_175029_a(Blocks.field_185779_df, TileEntityStructure.Mode.CORNER.func_185110_a(), "structure_block");
this.func_175029_a(Blocks.field_185779_df, TileEntityStructure.Mode.DATA.func_185110_a(), "structure_block");
@@ -0,0 +1,11 @@
--- ../src-base/minecraft/net/minecraft/client/renderer/entity/layers/LayerHeldItemWitch.java
+++ ../src-work/minecraft/net/minecraft/client/renderer/entity/layers/LayerHeldItemWitch.java
@@ -53,7 +53,7 @@
float f1 = 0.375F;
GlStateManager.func_179152_a(0.375F, -0.375F, 0.375F);
}
- else if (item == Items.field_151031_f)
+ else if (item instanceof net.minecraft.item.ItemBow)
{
GlStateManager.func_179109_b(0.0F, 0.125F, -0.125F);
GlStateManager.func_179114_b(-45.0F, 0.0F, 1.0F, 0.0F);
@@ -0,0 +1,13 @@
--- ../src-base/minecraft/net/minecraft/client/renderer/texture/LayeredColorMaskTexture.java
+++ ../src-work/minecraft/net/minecraft/client/renderer/texture/LayeredColorMaskTexture.java
@@ -71,9 +71,7 @@
if (s != null)
{
- iresource1 = p_110551_1_.func_110536_a(new ResourceLocation(s));
- BufferedImage bufferedimage2 = TextureUtil.func_177053_a(iresource1.func_110527_b());
-
+ BufferedImage bufferedimage2 = net.minecraftforge.client.MinecraftForgeClient.getImageLayer(new ResourceLocation(s), p_110551_1_);
if (bufferedimage2.getWidth() == bufferedimage.getWidth() && bufferedimage2.getHeight() == bufferedimage.getHeight() && bufferedimage2.getType() == 6)
{
for (int l = 0; l < bufferedimage2.getHeight(); ++l)
@@ -25,7 +25,7 @@
p_174943_2_.func_177059_a(this);
this.func_110569_e();
this.func_147631_c();
@@ -88,13 +99,55 @@
@@ -88,29 +99,74 @@
this.field_94258_i.clear();
int j = Integer.MAX_VALUE;
int k = 1 << this.field_147636_j;
@@ -58,8 +58,9 @@
+ {
+ if(location.equals(loading))
+ {
+ final String error = "circular model dependencies, stack: [" + com.google.common.base.Joiner.on(", ").join(loadingSprites) + "]";
+ final String error = "circular texture dependencies, stack: [" + com.google.common.base.Joiner.on(", ").join(loadingSprites) + "]";
+ net.minecraftforge.fml.client.FMLClientHandler.instance().trackBrokenTexture(resourcelocation, error);
+ return j;
+ }
+ }
+ loadingSprites.addLast(location);
@@ -74,6 +75,8 @@
+ TextureAtlasSprite depSprite = field_110574_e.get(dependency.toString());
+ j = loadTexture(stitcher, p_110571_1_, dependency, depSprite, bar, j, k);
+ }
try
{
+ if (textureatlassprite.hasCustomLoader(p_110571_1_, resourcelocation))
+ {
+ if (textureatlassprite.load(p_110571_1_, resourcelocation, l -> field_110574_e.get(l.toString())))
@@ -82,11 +85,13 @@
+ }
+ }
+ else
try
{
+ {
PngSizeInfo pngsizeinfo = PngSizeInfo.func_188532_a(p_110571_1_.func_110536_a(resourcelocation));
@@ -104,13 +157,13 @@
iresource = p_110571_1_.func_110536_a(resourcelocation);
boolean flag = iresource.func_110526_a("animation") != null;
textureatlassprite.func_188538_a(pngsizeinfo, flag);
}
+ }
catch (RuntimeException runtimeexception)
{
- field_147635_d.error("Unable to parse metadata from {}", resourcelocation, runtimeexception);
@@ -103,7 +108,7 @@
}
finally
{
@@ -122,16 +175,28 @@
@@ -122,16 +178,28 @@
if (j1 < k)
{
@@ -134,7 +139,7 @@
if (i1 < this.field_147636_j)
{
field_147635_d.warn("{}: dropping miplevel from {} to {}, because of minimum power of two: {}", this.field_94254_c, Integer.valueOf(this.field_147636_j), Integer.valueOf(i1), Integer.valueOf(l));
@@ -140,9 +205,11 @@
@@ -140,9 +208,11 @@
this.field_94249_f.func_147963_d(this.field_147636_j);
stitcher.func_110934_a(this.field_94249_f);
@@ -146,7 +151,7 @@
stitcher.func_94305_f();
}
catch (StitcherException stitcherexception)
@@ -151,12 +218,16 @@
@@ -151,12 +221,16 @@
}
field_147635_d.info("Created: {}x{} {}-atlas", Integer.valueOf(stitcher.func_110935_a()), Integer.valueOf(stitcher.func_110936_b()), this.field_94254_c);
@@ -164,7 +169,7 @@
{
String s = textureatlassprite1.func_94215_i();
map.remove(s);
@@ -186,6 +257,8 @@
@@ -186,6 +260,8 @@
{
textureatlassprite2.func_94217_a(this.field_94249_f);
}
@@ -173,7 +178,7 @@
}
private boolean func_184397_a(IResourceManager p_184397_1_, final TextureAtlasSprite p_184397_2_)
@@ -195,7 +268,7 @@
@@ -195,7 +271,7 @@
label62:
{
boolean flag;
@@ -182,7 +187,7 @@
try
{
iresource = p_184397_1_.func_110536_a(resourcelocation);
@@ -292,7 +365,7 @@
@@ -292,7 +368,7 @@
}
else
{
@@ -191,7 +196,7 @@
if (textureatlassprite == null)
{
@@ -318,4 +391,52 @@
@@ -318,4 +394,52 @@
{
return this.field_94249_f;
}
@@ -1,5 +1,14 @@
--- ../src-base/minecraft/net/minecraft/client/renderer/texture/TextureUtil.java
+++ ../src-work/minecraft/net/minecraft/client/renderer/texture/TextureUtil.java
@@ -63,7 +63,7 @@
{
boolean flag = false;
- for (int i = 0; i < p_147949_2_.length; ++i)
+ for (int i = 0; i < p_147949_2_[0].length; ++i)
{
if (p_147949_2_[0][i] >> 24 == 0)
{
@@ -83,6 +83,7 @@
int[] aint1 = aint[l1 - 1];
int[] aint2 = new int[aint1.length >> 2];
@@ -9,7 +9,7 @@
}
public void func_190056_a(World p_190056_1_, TextureManager p_190056_2_, FontRenderer p_190056_3_, Entity p_190056_4_, RayTraceResult p_190056_5_, float p_190056_6_)
@@ -117,12 +117,15 @@
@@ -117,13 +117,17 @@
{
if (p_180546_1_.func_145835_a(this.field_147560_j, this.field_147561_k, this.field_147558_l) < p_180546_1_.func_145833_n())
{
@@ -23,9 +23,11 @@
GlStateManager.func_179131_c(1.0F, 1.0F, 1.0F, 1.0F);
+ }
BlockPos blockpos = p_180546_1_.func_174877_v();
+ if (this.field_147550_f.func_175668_a(blockpos, false)) // Forge: fix MC-123363
this.func_192854_a(p_180546_1_, (double)blockpos.func_177958_n() - field_147554_b, (double)blockpos.func_177956_o() - field_147555_c, (double)blockpos.func_177952_p() - field_147552_d, p_180546_2_, p_180546_3_, 1.0F);
}
@@ -146,6 +149,9 @@
}
@@ -146,6 +150,9 @@
{
try
{
@@ -35,7 +37,7 @@
tileentityspecialrenderer.func_192841_a(p_192854_1_, p_192854_2_, p_192854_4_, p_192854_6_, p_192854_8_, p_192854_9_, p_192854_10_);
}
catch (Throwable throwable)
@@ -172,4 +178,53 @@
@@ -172,4 +179,53 @@
{
return this.field_147557_n;
}
@@ -0,0 +1,22 @@
--- ../src-base/minecraft/net/minecraft/client/resources/ResourcePackRepository.java
+++ ../src-work/minecraft/net/minecraft/client/resources/ResourcePackRepository.java
@@ -310,9 +310,10 @@
private boolean func_190113_a(String p_190113_1_, File p_190113_2_)
{
+ InputStream is = null;
try
{
- String s = DigestUtils.sha1Hex((InputStream)(new FileInputStream(p_190113_2_)));
+ String s = DigestUtils.sha1Hex(is = (InputStream)(new FileInputStream(p_190113_2_)));
if (p_190113_1_.isEmpty())
{
@@ -332,6 +333,7 @@
{
field_177320_c.warn("File {} couldn't be hashed.", p_190113_2_, ioexception);
}
+ finally { IOUtils.closeQuietly(is); } // Forge: close stream after use
return false;
}
@@ -34,7 +34,24 @@
}
if (p_74306_1_ == GameSettings.Options.GRAPHICS)
@@ -1068,7 +1070,12 @@
@@ -724,6 +726,7 @@
public void func_74300_a()
{
+ FileInputStream fileInputStream = null; // Forge: fix MC-151173
try
{
if (!this.field_74354_ai.exists())
@@ -732,7 +735,7 @@
}
this.field_186714_aM.clear();
- List<String> list = IOUtils.readLines(new FileInputStream(this.field_74354_ai));
+ List<String> list = IOUtils.readLines(fileInputStream = new FileInputStream(this.field_74354_ai), StandardCharsets.UTF_8); // Forge: fix MC-117449, MC-151173
NBTTagCompound nbttagcompound = new NBTTagCompound();
for (String s : list)
@@ -1068,7 +1071,12 @@
{
if (s1.equals("key_" + keybinding.func_151464_g()))
{
@@ -48,7 +65,15 @@
}
}
@@ -1132,6 +1139,7 @@
@@ -1100,6 +1108,7 @@
{
field_151454_ax.error("Failed to load options", (Throwable)exception);
}
+ finally { IOUtils.closeQuietly(fileInputStream); } // Forge: fix MC-151173
}
private NBTTagCompound func_189988_a(NBTTagCompound p_189988_1_)
@@ -1132,6 +1141,7 @@
public void func_74303_b()
{
@@ -56,7 +81,7 @@
PrintWriter printwriter = null;
try
@@ -1206,7 +1214,8 @@
@@ -1206,7 +1216,8 @@
for (KeyBinding keybinding : this.field_74324_K)
{
@@ -66,7 +91,7 @@
}
for (SoundCategory soundcategory : SoundCategory.values())
@@ -1440,4 +1449,35 @@
@@ -1440,4 +1451,35 @@
return p_148264_1_;
}
}
@@ -0,0 +1,10 @@
--- ../src-base/minecraft/net/minecraft/command/CommandGameRule.java
+++ ../src-work/minecraft/net/minecraft/command/CommandGameRule.java
@@ -73,6 +73,7 @@
entityplayermp.field_71135_a.func_147359_a(new SPacketEntityStatus(entityplayermp, b0));
}
}
+ net.minecraftforge.event.ForgeEventFactory.onGameRuleChange(p_184898_0_, p_184898_1_, p_184898_2_);
}
public List<String> func_184883_a(MinecraftServer p_184883_1_, ICommandSender p_184883_2_, String[] p_184883_3_, @Nullable BlockPos p_184883_4_)
@@ -44,7 +44,7 @@
return this.field_78033_n < 6;
}
@@ -260,4 +282,45 @@
@@ -260,4 +282,50 @@
item.func_150895_a(this, p_78018_1_);
}
}
@@ -88,5 +88,10 @@
+ public net.minecraft.util.ResourceLocation getBackgroundImage()
+ {
+ return new net.minecraft.util.ResourceLocation("textures/gui/container/creative_inventory/tab_" + this.func_78015_f());
+ }
+
+ public int getLabelColor()
+ {
+ return 4210752;
+ }
}
@@ -46,7 +46,23 @@
public int func_145782_y()
{
return this.field_145783_c;
@@ -1053,7 +1065,7 @@
@@ -344,6 +356,7 @@
this.field_70165_t = p_70107_1_;
this.field_70163_u = p_70107_3_;
this.field_70161_v = p_70107_5_;
+ if (this.isAddedToWorld() && !this.field_70170_p.field_72995_K) this.field_70170_p.func_72866_a(this, false); // Forge - Process chunk registration after moving.
float f = this.field_70130_N / 2.0F;
float f1 = this.field_70131_O;
this.func_174826_a(new AxisAlignedBB(p_70107_1_ - (double)f, p_70107_3_, p_70107_5_ - (double)f, p_70107_1_ + (double)f, p_70107_3_ + (double)f1, p_70107_5_ + (double)f));
@@ -995,6 +1008,7 @@
this.field_70165_t = (axisalignedbb.field_72340_a + axisalignedbb.field_72336_d) / 2.0D;
this.field_70163_u = axisalignedbb.field_72338_b;
this.field_70161_v = (axisalignedbb.field_72339_c + axisalignedbb.field_72334_f) / 2.0D;
+ if (this.isAddedToWorld() && !this.field_70170_p.field_72995_K) this.field_70170_p.func_72866_a(this, false); // Forge - Process chunk registration after moving.
}
protected SoundEvent func_184184_Z()
@@ -1053,7 +1067,7 @@
protected void func_180429_a(BlockPos p_180429_1_, Block p_180429_2_)
{
@@ -55,7 +71,7 @@
if (this.field_70170_p.func_180495_p(p_180429_1_.func_177984_a()).func_177230_c() == Blocks.field_150431_aC)
{
@@ -1259,6 +1271,7 @@
@@ -1259,6 +1273,7 @@
BlockPos blockpos = new BlockPos(i, j, k);
IBlockState iblockstate = this.field_70170_p.func_180495_p(blockpos);
@@ -63,7 +79,7 @@
if (iblockstate.func_185901_i() != EnumBlockRenderType.INVISIBLE)
{
this.field_70170_p.func_175688_a(EnumParticleTypes.BLOCK_CRACK, this.field_70165_t + ((double)this.field_70146_Z.nextFloat() - 0.5D) * (double)this.field_70130_N, this.func_174813_aQ().field_72338_b + 0.1D, this.field_70161_v + ((double)this.field_70146_Z.nextFloat() - 0.5D) * (double)this.field_70130_N, -this.field_70159_w * 4.0D, 1.5D, -this.field_70179_y * 4.0D, Block.func_176210_f(iblockstate));
@@ -1277,12 +1290,12 @@
@@ -1277,12 +1292,12 @@
BlockPos blockpos = new BlockPos(this.field_70165_t, d0, this.field_70161_v);
IBlockState iblockstate = this.field_70170_p.func_180495_p(blockpos);
@@ -80,7 +96,15 @@
}
else
{
@@ -1707,6 +1720,7 @@
@@ -1382,6 +1397,7 @@
this.field_70126_B -= 360.0F;
}
+ if (!this.field_70170_p.field_72995_K) this.field_70170_p.func_72964_e((int) Math.floor(this.field_70165_t) >> 4, (int) Math.floor(this.field_70161_v) >> 4); // Forge - ensure target chunk is loaded.
this.func_70107_b(this.field_70165_t, this.field_70163_u, this.field_70161_v);
this.func_70101_b(p_70080_7_, p_70080_8_);
}
@@ -1707,6 +1723,7 @@
{
p_189511_1_.func_74757_a("Glowing", this.field_184238_ar);
}
@@ -88,7 +112,7 @@
if (!this.field_184236_aF.isEmpty())
{
@@ -1720,6 +1734,9 @@
@@ -1720,6 +1737,9 @@
p_189511_1_.func_74782_a("Tags", nbttaglist);
}
@@ -98,7 +122,7 @@
this.func_70014_b(p_189511_1_);
if (this.func_184207_aI())
@@ -1826,7 +1843,11 @@
@@ -1826,7 +1846,11 @@
this.func_174810_b(p_70020_1_.func_74767_n("Silent"));
this.func_189654_d(p_70020_1_.func_74767_n("NoGravity"));
this.func_184195_f(p_70020_1_.func_74767_n("Glowing"));
@@ -110,7 +134,7 @@
if (p_70020_1_.func_150297_b("Tags", 9))
{
this.field_184236_aF.clear();
@@ -1918,7 +1939,10 @@
@@ -1918,7 +1942,10 @@
{
EntityItem entityitem = new EntityItem(this.field_70170_p, this.field_70165_t, this.field_70163_u + (double)p_70099_2_, this.field_70161_v, p_70099_1_);
entityitem.func_174869_p();
@@ -122,7 +146,7 @@
return entityitem;
}
}
@@ -1985,6 +2009,7 @@
@@ -1985,6 +2012,7 @@
this.field_70159_w = 0.0D;
this.field_70181_x = 0.0D;
this.field_70179_y = 0.0D;
@@ -130,7 +154,7 @@
this.func_70071_h_();
if (this.func_184218_aH())
@@ -2032,6 +2057,7 @@
@@ -2032,6 +2060,7 @@
}
}
@@ -138,7 +162,7 @@
if (p_184205_2_ || this.func_184228_n(p_184205_1_) && p_184205_1_.func_184219_q(this))
{
if (this.func_184218_aH())
@@ -2067,6 +2093,7 @@
@@ -2067,6 +2096,7 @@
if (this.field_184239_as != null)
{
Entity entity = this.field_184239_as;
@@ -146,7 +170,7 @@
this.field_184239_as = null;
entity.func_184225_p(this);
}
@@ -2509,8 +2536,16 @@
@@ -2509,8 +2539,16 @@
@Nullable
public Entity func_184204_a(int p_184204_1_)
{
@@ -163,7 +187,7 @@
this.field_70170_p.field_72984_F.func_76320_a("changeDimension");
MinecraftServer minecraftserver = this.func_184102_h();
int i = this.field_71093_bK;
@@ -2518,7 +2553,7 @@
@@ -2518,7 +2556,7 @@
WorldServer worldserver1 = minecraftserver.func_71218_a(p_184204_1_);
this.field_71093_bK = p_184204_1_;
@@ -172,7 +196,7 @@
{
worldserver1 = minecraftserver.func_71218_a(0);
this.field_71093_bK = 0;
@@ -2529,22 +2564,23 @@
@@ -2529,22 +2567,23 @@
this.field_70170_p.field_72984_F.func_76320_a("reposition");
BlockPos blockpos;
@@ -201,7 +225,7 @@
{
d0 = MathHelper.func_151237_a(d0 * 8.0D, worldserver1.func_175723_af().func_177726_b() + 16.0D, worldserver1.func_175723_af().func_177728_d() - 16.0D);
d1 = MathHelper.func_151237_a(d1 * 8.0D, worldserver1.func_175723_af().func_177736_c() + 16.0D, worldserver1.func_175723_af().func_177733_e() - 16.0D);
@@ -2554,8 +2590,7 @@
@@ -2554,8 +2593,7 @@
d1 = (double)MathHelper.func_76125_a((int)d1, -29999872, 29999872);
float f = this.field_70177_z;
this.func_70012_b(d0, this.field_70163_u, d1, 90.0F, 0.0F);
@@ -211,7 +235,7 @@
blockpos = new BlockPos(this);
}
@@ -2567,7 +2602,7 @@
@@ -2567,7 +2605,7 @@
{
entity.func_180432_n(this);
@@ -220,7 +244,7 @@
{
BlockPos blockpos1 = worldserver1.func_175672_r(worldserver1.func_175694_M());
entity.func_174828_a(blockpos1, entity.field_70177_z, entity.field_70125_A);
@@ -2604,7 +2639,7 @@
@@ -2604,7 +2642,7 @@
public float func_180428_a(Explosion p_180428_1_, World p_180428_2_, BlockPos p_180428_3_, IBlockState p_180428_4_)
{
@@ -229,12 +253,47 @@
}
public boolean func_174816_a(Explosion p_174816_1_, World p_174816_2_, BlockPos p_174816_3_, IBlockState p_174816_4_, float p_174816_5_)
@@ -2901,6 +2936,183 @@
@@ -2901,6 +2939,218 @@
EnchantmentHelper.func_151385_b(p_174815_1_, p_174815_2_);
}
+ /* ================================== Forge Start =====================================*/
+ /**
+ * Internal use for keeping track of entities that are tracked by a world, to
+ * allow guarantees that entity position changes will force a chunk load, avoiding
+ * potential issues with entity desyncing and bad chunk data.
+ */
+ private boolean isAddedToWorld;
+
+ /**
+ * Gets whether this entity has been added to a world (for tracking). Specifically
+ * between the times when an entity is added to a world and the entity being removed
+ * from the world's tracked lists. See {@link World#onEntityAdded(Entity)} and
+ * {@link World#onEntityRemoved(Entity)}.
+ *
+ * @return True if this entity is being tracked by a world
+ */
+ public final boolean isAddedToWorld() { return this.isAddedToWorld; }
+
+ /**
+ * Called after the entity has been added to the world's
+ * ticking list. Can be overriden, but needs to call super
+ * to prevent MC-136995.
+ */
+ public void onAddedToWorld() {
+ this.isAddedToWorld = true;
+ }
+
+ /**
+ * Called after the entity has been removed to the world's
+ * ticking list. Can be overriden, but needs to call super
+ * to prevent MC-136995.
+ */
+ public void onRemovedFromWorld() {
+ this.isAddedToWorld = false;
+ }
+
+ /**
+ * Returns a NBTTagCompound that can be used to store custom data for this entity.
+ * It will be written, and read from disc, so it persists over world saves.
+ * @return A NBTTagCompound
@@ -0,0 +1,10 @@
--- ../src-base/minecraft/net/minecraft/entity/EntityLeashKnot.java
+++ ../src-work/minecraft/net/minecraft/entity/EntityLeashKnot.java
@@ -43,6 +43,7 @@
this.field_70165_t = (double)this.field_174861_a.func_177958_n() + 0.5D;
this.field_70163_u = (double)this.field_174861_a.func_177956_o() + 0.5D;
this.field_70161_v = (double)this.field_174861_a.func_177952_p() + 0.5D;
+ if (this.isAddedToWorld() && !this.field_70170_p.field_72995_K) this.field_70170_p.func_72866_a(this, false); // Forge - Process chunk registration after moving.
}
public void func_174859_a(EnumFacing p_174859_1_)
@@ -47,15 +47,16 @@
while (i > 0)
{
int j = EntityXPOrb.func_70527_a(i);
@@ -442,6 +445,7 @@
{
this.field_70755_b = p_70604_1_;
this.field_70756_c = this.field_70173_aa;
+ net.minecraftforge.common.ForgeHooks.onLivingSetAttackTarget(this, p_70604_1_);
}
@@ -602,7 +605,7 @@
public EntityLivingBase func_110144_aD()
@@ -670,8 +674,10 @@
if (!potioneffect.func_76455_a(this))
{
- if (!this.field_70170_p.field_72995_K)
+ if (!this.field_70170_p.field_72995_K && !net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.PotionEvent.PotionExpiryEvent(this, potioneffect)))
{
iterator.remove();
this.func_70688_c(potioneffect);
@@ -670,8 +673,10 @@
else
{
Collection<PotionEffect> collection = this.field_70713_bf.values();
@@ -68,7 +69,45 @@
this.func_82142_c(this.func_70644_a(MobEffects.field_76441_p));
}
}
@@ -819,6 +825,8 @@
@@ -703,7 +708,10 @@
while (iterator.hasNext())
{
- this.func_70688_c(iterator.next());
+ PotionEffect effect = iterator.next();
+ if(net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.PotionEvent.PotionRemoveEvent(this, effect))) continue;
+
+ this.func_70688_c(effect);
iterator.remove();
}
}
@@ -736,6 +744,7 @@
{
PotionEffect potioneffect = this.field_70713_bf.get(p_70690_1_.func_188419_a());
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.PotionEvent.PotionAddedEvent(this, potioneffect, p_70690_1_));
if (potioneffect == null)
{
this.field_70713_bf.put(p_70690_1_.func_188419_a(), p_70690_1_);
@@ -751,6 +760,9 @@
public boolean func_70687_e(PotionEffect p_70687_1_)
{
+ net.minecraftforge.event.entity.living.PotionEvent.PotionApplicableEvent event = new net.minecraftforge.event.entity.living.PotionEvent.PotionApplicableEvent(this, p_70687_1_);
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event);
+ if (event.getResult() != net.minecraftforge.fml.common.eventhandler.Event.Result.DEFAULT) return event.getResult() == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW;
if (this.func_70668_bt() == EnumCreatureAttribute.UNDEAD)
{
Potion potion = p_70687_1_.func_188419_a();
@@ -777,6 +789,7 @@
public void func_184589_d(Potion p_184589_1_)
{
+ if(net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.PotionEvent.PotionRemoveEvent(this, p_184589_1_))) return;
PotionEffect potioneffect = this.func_184596_c(p_184589_1_);
if (potioneffect != null)
@@ -819,6 +832,8 @@
public void func_70691_i(float p_70691_1_)
{
@@ -77,7 +116,7 @@
float f = this.func_110143_aJ();
if (f > 0.0F)
@@ -839,6 +847,7 @@
@@ -839,6 +854,7 @@
public boolean func_70097_a(DamageSource p_70097_1_, float p_70097_2_)
{
@@ -85,7 +124,7 @@
if (this.func_180431_b(p_70097_1_))
{
return false;
@@ -927,9 +936,9 @@
@@ -927,9 +943,9 @@
this.field_70718_bc = 100;
this.field_70717_bb = (EntityPlayer)entity1;
}
@@ -97,7 +136,7 @@
if (entitywolf.func_70909_n())
{
@@ -1127,7 +1136,7 @@
@@ -1127,7 +1143,7 @@
public void func_70669_a(ItemStack p_70669_1_)
{
@@ -106,7 +145,7 @@
for (int i = 0; i < 5; ++i)
{
@@ -1139,12 +1148,17 @@
@@ -1139,12 +1155,17 @@
vec3d1 = vec3d1.func_178789_a(-this.field_70125_A * 0.017453292F);
vec3d1 = vec3d1.func_178785_b(-this.field_70177_z * 0.017453292F);
vec3d1 = vec3d1.func_72441_c(this.field_70165_t, this.field_70163_u + (double)this.func_70047_e(), this.field_70161_v);
@@ -125,7 +164,7 @@
if (!this.field_70729_aU)
{
Entity entity = p_70645_1_.func_76346_g();
@@ -1165,18 +1179,26 @@
@@ -1165,18 +1186,26 @@
if (!this.field_70170_p.field_72995_K)
{
@@ -157,7 +196,7 @@
}
this.field_70170_p.func_72960_a(this, (byte)3);
@@ -1195,6 +1217,9 @@
@@ -1195,6 +1224,9 @@
public void func_70653_a(Entity p_70653_1_, float p_70653_2_, double p_70653_3_, double p_70653_5_)
{
@@ -167,7 +206,7 @@
if (this.field_70146_Z.nextDouble() >= this.func_110148_a(SharedMonsterAttributes.field_111266_c).func_111126_e())
{
this.field_70160_al = true;
@@ -1253,15 +1278,7 @@
@@ -1253,15 +1285,7 @@
BlockPos blockpos = new BlockPos(i, j, k);
IBlockState iblockstate = this.field_70170_p.func_180495_p(blockpos);
Block block = iblockstate.func_177230_c();
@@ -184,7 +223,7 @@
}
}
@@ -1287,6 +1304,9 @@
@@ -1287,6 +1311,9 @@
public void func_180430_e(float p_180430_1_, float p_180430_2_)
{
@@ -194,7 +233,7 @@
super.func_180430_e(p_180430_1_, p_180430_2_);
PotionEffect potioneffect = this.func_70660_b(MobEffects.field_76430_j);
float f = potioneffect == null ? 0.0F : (float)(potioneffect.func_76458_c() + 1);
@@ -1303,7 +1323,7 @@
@@ -1303,7 +1330,7 @@
if (iblockstate.func_185904_a() != Material.field_151579_a)
{
@@ -203,7 +242,7 @@
this.func_184185_a(soundtype.func_185842_g(), soundtype.func_185843_a() * 0.5F, soundtype.func_185847_b() * 0.75F);
}
}
@@ -1380,17 +1400,20 @@
@@ -1380,17 +1407,20 @@
{
if (!this.func_180431_b(p_70665_1_))
{
@@ -225,7 +264,7 @@
this.func_110149_m(this.func_110139_bj() - p_70665_2_);
}
}
@@ -1447,6 +1470,11 @@
@@ -1447,6 +1477,11 @@
public void func_184609_a(EnumHand p_184609_1_)
{
@@ -237,7 +276,7 @@
if (!this.field_82175_bq || this.field_110158_av >= this.func_82166_i() / 2 || this.field_110158_av < 0)
{
this.field_110158_av = -1;
@@ -1694,7 +1722,7 @@
@@ -1694,7 +1729,7 @@
if (!this.field_70170_p.func_184143_b(axisalignedbb1))
{
@@ -246,7 +285,7 @@
{
this.func_70634_a(d11, this.field_70163_u + 1.0D, d12);
return;
@@ -1702,14 +1730,14 @@
@@ -1702,14 +1737,14 @@
BlockPos blockpos = new BlockPos(d11, this.field_70163_u - 1.0D, d12);
@@ -263,7 +302,7 @@
{
d1 = d11;
d13 = this.field_70163_u + 2.0D;
@@ -1781,16 +1809,17 @@
@@ -1781,16 +1816,17 @@
}
this.field_70160_al = true;
@@ -283,7 +322,7 @@
}
protected float func_189749_co()
@@ -1874,7 +1903,8 @@
@@ -1874,7 +1910,8 @@
if (this.field_70122_E)
{
@@ -293,7 +332,7 @@
}
float f7 = 0.16277136F / (f6 * f6 * f6);
@@ -1894,7 +1924,8 @@
@@ -1894,7 +1931,8 @@
if (this.field_70122_E)
{
@@ -303,7 +342,7 @@
}
if (this.func_70617_f_())
@@ -2054,6 +2085,7 @@
@@ -2054,6 +2092,7 @@
public void func_70071_h_()
{
@@ -311,7 +350,7 @@
super.func_70071_h_();
this.func_184608_ct();
@@ -2096,7 +2128,9 @@
@@ -2096,7 +2135,9 @@
if (!ItemStack.func_77989_b(itemstack1, itemstack))
{
@@ -321,7 +360,7 @@
if (!itemstack.func_190926_b())
{
@@ -2575,6 +2609,40 @@
@@ -2575,6 +2616,40 @@
this.field_70752_e = true;
}
@@ -338,7 +377,7 @@
+ {
+ PotionEffect effect = iterator.next();
+
+ if (effect.isCurativeItem(curativeItem))
+ if (effect.isCurativeItem(curativeItem) && !net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.PotionEvent.PotionRemoveEvent(this, effect)))
+ {
+ func_70688_c(effect);
+ iterator.remove();
@@ -362,7 +401,11 @@
public abstract EnumHandSide func_184591_cq();
public boolean func_184587_cr()
@@ -2595,12 +2663,19 @@
@@ -2592,15 +2667,23 @@
if (this.func_184587_cr())
{
ItemStack itemstack = this.func_184586_b(this.func_184600_cs());
+ if (net.minecraftforge.common.ForgeHooks.canContinueUsing(this.field_184627_bm, itemstack)) this.field_184627_bm = itemstack;
if (itemstack == this.field_184627_bm)
{
@@ -383,7 +426,7 @@
{
this.func_71036_o();
}
@@ -2618,8 +2693,10 @@
@@ -2618,8 +2701,10 @@
if (!itemstack.func_190926_b() && !this.func_184587_cr())
{
@@ -395,7 +438,7 @@
if (!this.field_70170_p.field_72995_K)
{
@@ -2700,7 +2777,10 @@
@@ -2700,7 +2785,10 @@
if (!this.field_184627_bm.func_190926_b() && this.func_184587_cr())
{
this.func_184584_a(this.field_184627_bm, 16);
@@ -407,7 +450,7 @@
this.func_184602_cy();
}
}
@@ -2724,7 +2804,8 @@
@@ -2724,7 +2812,8 @@
{
if (!this.field_184627_bm.func_190926_b())
{
@@ -417,7 +460,7 @@
}
this.func_184602_cy();
@@ -2852,6 +2933,31 @@
@@ -2852,6 +2941,31 @@
return true;
}
@@ -449,7 +492,7 @@
public boolean func_190631_cK()
{
return true;
@@ -2861,4 +2967,30 @@
@@ -2861,4 +2975,30 @@
public void func_191987_a(BlockPos p_191987_1_, boolean p_191987_2_)
{
}
@@ -0,0 +1,11 @@
--- ../src-base/minecraft/net/minecraft/entity/NpcMerchant.java
+++ ../src-work/minecraft/net/minecraft/entity/NpcMerchant.java
@@ -41,7 +41,7 @@
@Nullable
public MerchantRecipeList func_70934_b(EntityPlayer p_70934_1_)
{
- return this.field_70936_c;
+ return net.minecraftforge.event.ForgeEventFactory.listTradeOffers(this, p_70934_1_, this.field_70936_c);
}
public void func_70930_a(@Nullable MerchantRecipeList p_70930_1_)
@@ -0,0 +1,11 @@
--- ../src-base/minecraft/net/minecraft/entity/ai/EntityAIAttackRangedBow.java
+++ ../src-work/minecraft/net/minecraft/entity/ai/EntityAIAttackRangedBow.java
@@ -40,7 +40,7 @@
protected boolean func_188498_f()
{
- return !this.field_188499_a.func_184614_ca().func_190926_b() && this.field_188499_a.func_184614_ca().func_77973_b() == Items.field_151031_f;
+ return !this.field_188499_a.func_184614_ca().func_190926_b() && this.field_188499_a.func_184614_ca().func_77973_b() instanceof ItemBow;
}
public boolean func_75253_b()
@@ -1,6 +1,19 @@
--- ../src-base/minecraft/net/minecraft/entity/item/EntityBoat.java
+++ ../src-work/minecraft/net/minecraft/entity/item/EntityBoat.java
@@ -508,7 +508,7 @@
@@ -449,6 +449,12 @@
blockpos$pooledmutableblockpos.func_181079_c(l1, k1, i2);
IBlockState iblockstate = this.field_70170_p.func_180495_p(blockpos$pooledmutableblockpos);
+ Boolean result = iblockstate.func_177230_c().isAABBInsideMaterial(field_70170_p, blockpos$pooledmutableblockpos, new AxisAlignedBB(blockpos$pooledmutableblockpos), Material.field_151586_h);
+ if (result != null) {
+ if (!result) continue;
+ f = Math.max(f, iblockstate.func_177230_c().getBlockLiquidHeight(field_70170_p, blockpos$pooledmutableblockpos, iblockstate, Material.field_151586_h) + blockpos$pooledmutableblockpos.func_177956_o());
+ }
+
if (iblockstate.func_185904_a() == Material.field_151586_h)
{
f = Math.max(f, BlockLiquid.func_190973_f(iblockstate, this.field_70170_p, blockpos$pooledmutableblockpos));
@@ -508,7 +514,7 @@
if (!list.isEmpty())
{
@@ -9,7 +22,42 @@
++k1;
}
@@ -980,4 +980,20 @@
@@ -551,6 +557,15 @@
blockpos$pooledmutableblockpos.func_181079_c(k1, l1, i2);
IBlockState iblockstate = this.field_70170_p.func_180495_p(blockpos$pooledmutableblockpos);
+ Boolean result = iblockstate.func_177230_c().isAABBInsideMaterial(field_70170_p, blockpos$pooledmutableblockpos, axisalignedbb, Material.field_151586_h);
+ if (result != null) {
+ if (!result) continue;
+
+ float f = iblockstate.func_177230_c().getBlockLiquidHeight(field_70170_p, blockpos$pooledmutableblockpos, iblockstate, Material.field_151586_h) + blockpos$pooledmutableblockpos.func_177956_o();
+ this.field_184465_aD = Math.max((double)f, this.field_184465_aD);
+ flag |= axisalignedbb.field_72338_b < (double)f;
+ }
+
if (iblockstate.func_185904_a() == Material.field_151586_h)
{
float f = BlockLiquid.func_190972_g(iblockstate, this.field_70170_p, blockpos$pooledmutableblockpos);
@@ -594,6 +609,18 @@
blockpos$pooledmutableblockpos.func_181079_c(k1, l1, i2);
IBlockState iblockstate = this.field_70170_p.func_180495_p(blockpos$pooledmutableblockpos);
+ Boolean result = iblockstate.func_177230_c().isAABBInsideMaterial(field_70170_p, blockpos$pooledmutableblockpos, axisalignedbb, Material.field_151586_h);
+ if (result != null) {
+ if (!result) continue;
+
+ if(iblockstate.func_177230_c().getBlockLiquidHeight(field_70170_p, blockpos$pooledmutableblockpos, iblockstate, Material.field_151586_h) > 0)
+ {
+ blockpos$pooledmutableblockpos.func_185344_t();
+ return EntityBoat.Status.UNDER_FLOWING_WATER;
+ } else
+ continue;
+ }
+
if (iblockstate.func_185904_a() == Material.field_151586_h && d0 < (double)BlockLiquid.func_190972_g(iblockstate, this.field_70170_p, blockpos$pooledmutableblockpos))
{
if (((Integer)iblockstate.func_177229_b(BlockLiquid.field_176367_b)).intValue() != 0)
@@ -980,4 +1007,20 @@
return values()[0];
}
}
@@ -8,7 +8,15 @@
if (!flag1 && BlockFalling.func_185759_i(this.field_70170_p.func_180495_p(new BlockPos(this.field_70165_t, this.field_70163_u - 0.009999999776482582D, this.field_70161_v))))
{
this.field_70122_E = false;
@@ -189,7 +190,7 @@
@@ -182,14 +183,14 @@
if (!this.field_145808_f)
{
- if (this.field_70170_p.func_190527_a(block, blockpos1, true, EnumFacing.UP, (Entity)null) && (flag1 || !BlockFalling.func_185759_i(this.field_70170_p.func_180495_p(blockpos1.func_177977_b()))) && this.field_70170_p.func_180501_a(blockpos1, this.field_175132_d, 3))
+ if (this.field_70170_p.func_190527_a(block, blockpos1, true, EnumFacing.UP, this) && (flag1 || !BlockFalling.func_185759_i(this.field_70170_p.func_180495_p(blockpos1.func_177977_b()))) && this.field_70170_p.func_180501_a(blockpos1, this.field_175132_d, 3))
{
if (block instanceof BlockFalling)
{
((BlockFalling)block).func_176502_a_(this.field_70170_p, blockpos1, this.field_175132_d, iblockstate);
}
@@ -19,7 +19,7 @@
if (this.func_180431_b(p_70097_1_))
{
return false;
@@ -208,6 +211,7 @@
@@ -208,14 +211,16 @@
{
if (this.field_70532_c == 0 && p_70100_1_.field_71090_bL == 0)
{
@@ -27,3 +27,25 @@
p_70100_1_.field_71090_bL = 2;
p_70100_1_.func_71001_a(this, 1);
ItemStack itemstack = EnchantmentHelper.func_92099_a(Enchantments.field_185296_A, p_70100_1_);
if (!itemstack.func_190926_b() && itemstack.func_77951_h())
{
- int i = Math.min(this.func_184514_c(this.field_70530_e), itemstack.func_77952_i());
- this.field_70530_e -= this.func_184515_b(i);
+ float ratio = itemstack.func_77973_b().getXpRepairRatio(itemstack);
+ int i = Math.min(roundAverage(this.field_70530_e * ratio), itemstack.func_77952_i());
+ this.field_70530_e -= roundAverage(i / ratio);
itemstack.func_77964_b(itemstack.func_77952_i() - i);
}
@@ -337,4 +342,10 @@
{
return false;
}
+
+ private static int roundAverage(float value)
+ {
+ double floor = Math.floor(value);
+ return (int) floor + (Math.random() < value - floor ? 1 : 0);
+ }
}
@@ -0,0 +1,20 @@
--- ../src-base/minecraft/net/minecraft/entity/monster/AbstractSkeleton.java
+++ ../src-work/minecraft/net/minecraft/entity/monster/AbstractSkeleton.java
@@ -192,7 +192,7 @@
this.field_70714_bg.func_85156_a(this.field_85037_d);
ItemStack itemstack = this.func_184614_ca();
- if (itemstack.func_77973_b() == Items.field_151031_f)
+ if (itemstack.func_77973_b() instanceof net.minecraft.item.ItemBow)
{
int i = 20;
@@ -214,6 +214,8 @@
public void func_82196_d(EntityLivingBase p_82196_1_, float p_82196_2_)
{
EntityArrow entityarrow = this.func_190726_a(p_82196_2_);
+ if (this.func_184614_ca().func_77973_b() instanceof net.minecraft.item.ItemBow)
+ entityarrow = ((net.minecraft.item.ItemBow) this.func_184614_ca().func_77973_b()).customizeArrow(entityarrow);
double d0 = p_82196_1_.field_70165_t - this.field_70165_t;
double d1 = p_82196_1_.func_174813_aQ().field_72338_b + (double)(p_82196_1_.field_70131_O / 3.0F) - entityarrow.field_70163_u;
double d2 = p_82196_1_.field_70161_v - this.field_70161_v;
@@ -39,6 +39,15 @@
{
return false;
}
@@ -508,7 +522,7 @@
IBlockState iblockstate1 = world.func_180495_p(blockpos.func_177977_b());
IBlockState iblockstate2 = this.field_179475_a.func_175489_ck();
- if (iblockstate2 != null && this.func_188518_a(world, blockpos, iblockstate2.func_177230_c(), iblockstate, iblockstate1))
+ if (iblockstate2 != null && this.func_188518_a(world, blockpos, iblockstate2.func_177230_c(), iblockstate, iblockstate1) && net.minecraftforge.event.ForgeEventFactory.onBlockPlace(field_179475_a, new net.minecraftforge.common.util.BlockSnapshot(world, blockpos, iblockstate2), net.minecraft.util.EnumFacing.UP).isCanceled())
{
world.func_180501_a(blockpos, iblockstate2, 3);
this.field_179475_a.func_175490_a((IBlockState)null);
@@ -551,7 +565,7 @@
{
return false;
@@ -0,0 +1,11 @@
--- ../src-base/minecraft/net/minecraft/entity/monster/EntityIllusionIllager.java
+++ ../src-work/minecraft/net/minecraft/entity/monster/EntityIllusionIllager.java
@@ -214,6 +214,8 @@
public void func_82196_d(EntityLivingBase p_82196_1_, float p_82196_2_)
{
EntityArrow entityarrow = this.func_193097_t(p_82196_2_);
+ if (this.func_184614_ca().func_77973_b() instanceof net.minecraft.item.ItemBow)
+ entityarrow = ((net.minecraft.item.ItemBow) this.func_184614_ca().func_77973_b()).customizeArrow(entityarrow);
double d0 = p_82196_1_.field_70165_t - this.field_70165_t;
double d1 = p_82196_1_.func_174813_aQ().field_72338_b + (double)(p_82196_1_.field_70131_O / 3.0F) - entityarrow.field_70163_u;
double d2 = p_82196_1_.field_70161_v - this.field_70161_v;
@@ -1,6 +1,14 @@
--- ../src-base/minecraft/net/minecraft/entity/monster/EntityShulker.java
+++ ../src-work/minecraft/net/minecraft/entity/monster/EntityShulker.java
@@ -426,6 +426,13 @@
@@ -311,6 +311,7 @@
this.field_70165_t = (double)blockpos.func_177958_n() + 0.5D;
this.field_70163_u = (double)blockpos.func_177956_o();
this.field_70161_v = (double)blockpos.func_177952_p() + 0.5D;
+ if (this.isAddedToWorld() && !this.field_70170_p.field_72995_K) this.field_70170_p.func_72866_a(this, false); // Forge - Process chunk registration after moving.
this.field_70169_q = this.field_70165_t;
this.field_70167_r = this.field_70163_u;
this.field_70166_s = this.field_70161_v;
@@ -426,6 +427,13 @@
if (flag)
{
@@ -0,0 +1,17 @@
--- ../src-base/minecraft/net/minecraft/entity/monster/EntitySpider.java
+++ ../src-work/minecraft/net/minecraft/entity/monster/EntitySpider.java
@@ -139,7 +139,13 @@
public boolean func_70687_e(PotionEffect p_70687_1_)
{
- return p_70687_1_.func_188419_a() == MobEffects.field_76436_u ? false : super.func_70687_e(p_70687_1_);
+ if(p_70687_1_.func_188419_a() == MobEffects.field_76436_u)
+ {
+ net.minecraftforge.event.entity.living.PotionEvent.PotionApplicableEvent event = new net.minecraftforge.event.entity.living.PotionEvent.PotionApplicableEvent(this, p_70687_1_);
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event);
+ return event.getResult() == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW;
+ }
+ return super.func_70687_e(p_70687_1_);
}
public boolean func_70841_p()
@@ -37,6 +37,15 @@
if (p_70037_1_.func_150297_b("ConversionTime", 99) && p_70037_1_.func_74762_e("ConversionTime") > -1)
{
@@ -91,7 +101,7 @@
@Nullable
public IEntityLivingData func_180482_a(DifficultyInstance p_180482_1_, @Nullable IEntityLivingData p_180482_2_)
{
- this.func_190733_a(this.field_70170_p.field_73012_v.nextInt(6));
+ net.minecraftforge.fml.common.registry.VillagerRegistry.setRandomProfession(this, this.field_70170_p.field_73012_v);
return super.func_180482_a(p_180482_1_, p_180482_2_);
}
@@ -175,7 +185,7 @@
{
EntityVillager entityvillager = new EntityVillager(this.field_70170_p);
@@ -122,7 +122,13 @@
}
else
{
@@ -617,15 +656,13 @@
@@ -612,20 +651,18 @@
this.func_175554_cu();
}
- return this.field_70963_i;
+ return net.minecraftforge.event.ForgeEventFactory.listTradeOffers(this, p_70934_1_, field_70963_i);
}
private void func_175554_cu()
{
@@ -349,7 +349,7 @@
}
- if (this.field_70170_p.func_72935_r())
+ if (!net.minecraftforge.event.ForgeEventFactory.fireSleepingTimeCheck(this, this.field_71081_bT))
+ if (!net.minecraftforge.event.ForgeEventFactory.fireSleepingTimeCheck(this, p_180469_1_))
{
return EntityPlayer.SleepResult.NOT_POSSIBLE_NOW;
}
@@ -0,0 +1,28 @@
--- ../src-base/minecraft/net/minecraft/item/EnumRarity.java
+++ ../src-work/minecraft/net/minecraft/item/EnumRarity.java
@@ -2,7 +2,7 @@
import net.minecraft.util.text.TextFormatting;
-public enum EnumRarity
+public enum EnumRarity implements net.minecraftforge.common.IRarity
{
COMMON(TextFormatting.WHITE, "Common"),
UNCOMMON(TextFormatting.YELLOW, "Uncommon"),
@@ -17,4 +17,16 @@
this.field_77937_e = p_i45349_3_;
this.field_77934_f = p_i45349_4_;
}
+
+ @Override
+ public TextFormatting getColor()
+ {
+ return this.field_77937_e;
+ }
+
+ @Override
+ public String getName()
+ {
+ return this.field_77934_f;
+ }
}
@@ -38,7 +38,15 @@
public boolean func_77634_r()
{
return this.field_77700_c != null;
@@ -372,7 +375,7 @@
@@ -365,6 +368,7 @@
return p_77636_1_.func_77948_v();
}
+ @Deprecated // use Forge version
public EnumRarity func_77613_e(ItemStack p_77613_1_)
{
return p_77613_1_.func_77948_v() ? EnumRarity.RARE : EnumRarity.COMMON;
@@ -372,7 +376,7 @@
public boolean func_77616_k(ItemStack p_77616_1_)
{
@@ -47,7 +55,7 @@
}
protected RayTraceResult func_77621_a(World p_77621_1_, EntityPlayer p_77621_2_, boolean p_77621_3_)
@@ -389,8 +392,8 @@
@@ -389,8 +393,8 @@
float f5 = MathHelper.func_76126_a(-f * 0.017453292F);
float f6 = f3 * f4;
float f7 = f2 * f4;
@@ -58,7 +66,7 @@
return p_77621_1_.func_147447_a(vec3d, vec3d1, p_77621_3_, !p_77621_3_, false);
}
@@ -409,6 +412,9 @@
@@ -409,6 +413,9 @@
protected boolean func_194125_a(CreativeTabs p_194125_1_)
{
@@ -68,7 +76,7 @@
CreativeTabs creativetabs = this.func_77640_w();
return creativetabs != null && (p_194125_1_ == CreativeTabs.field_78027_g || p_194125_1_ == creativetabs);
}
@@ -435,11 +441,757 @@
@@ -435,11 +442,784 @@
return false;
}
@@ -150,6 +158,15 @@
+ }
+
+ /**
+ * Determines the amount of durability the mending enchantment
+ * will repair, on average, per point of experience.
+ */
+ public float getXpRepairRatio(ItemStack stack)
+ {
+ return 2f;
+ }
+
+ /**
+ * Override this method to change the NBT data being sent to the client.
+ * You should ONLY override this when you have no other choice, as this might change behavior client side!
+ *
@@ -689,6 +706,19 @@
+ }
+
+ /**
+ * Called while an item is in 'active' use to determine if usage should continue.
+ * Allows items to continue being used while sustaining damage, for example.
+ *
+ * @param oldStack the previous 'active' stack
+ * @param newStack the stack currently in the active hand
+ * @return true to set the new stack to active and continue using it
+ */
+ public boolean canContinueUsing(ItemStack oldStack, ItemStack newStack)
+ {
+ return oldStack.equals(newStack);
+ }
+
+ /**
+ * Called to get the Mod ID of the mod that *created* the ItemStack,
+ * instead of the real Mod ID that *registered* it.
+ *
@@ -819,14 +849,19 @@
+ public void setTileEntityItemStackRenderer(@Nullable net.minecraft.client.renderer.tileentity.TileEntityItemStackRenderer teisr)
+ {
+ this.teisr = teisr;
+ }
+ }
+
+ public net.minecraftforge.common.IRarity getForgeRarity(ItemStack stack)
+ {
+ return this.func_77613_e(stack);
+ }
+
+ /* ======================================== FORGE END =====================================*/
+
public static void func_150900_l()
{
func_179214_a(Blocks.field_150350_a, new ItemAir(Blocks.field_150350_a));
@@ -999,6 +1751,8 @@
@@ -999,6 +1779,8 @@
private final float field_78010_h;
private final float field_78011_i;
private final int field_78008_j;
@@ -835,7 +870,7 @@
private ToolMaterial(int p_i1874_3_, int p_i1874_4_, float p_i1874_5_, float p_i1874_6_, int p_i1874_7_)
{
@@ -1034,6 +1788,7 @@
@@ -1034,6 +1816,7 @@
return this.field_78008_j;
}
@@ -843,7 +878,7 @@
public Item func_150995_f()
{
if (this == WOOD)
@@ -1057,5 +1812,21 @@
@@ -1057,5 +1840,21 @@
return this == DIAMOND ? Items.field_151045_i : null;
}
}
@@ -1,7 +1,11 @@
--- ../src-base/minecraft/net/minecraft/item/ItemBlock.java
+++ ../src-work/minecraft/net/minecraft/item/ItemBlock.java
@@ -49,24 +49,12 @@
if (!itemstack.func_190926_b() && p_180614_1_.func_175151_a(p_180614_3_, p_180614_5_, itemstack) && p_180614_2_.func_190527_a(this.field_150939_a, p_180614_3_, false, p_180614_5_, (Entity)null))
@@ -46,27 +46,15 @@
ItemStack itemstack = p_180614_1_.func_184586_b(p_180614_4_);
- if (!itemstack.func_190926_b() && p_180614_1_.func_175151_a(p_180614_3_, p_180614_5_, itemstack) && p_180614_2_.func_190527_a(this.field_150939_a, p_180614_3_, false, p_180614_5_, (Entity)null))
+ if (!itemstack.func_190926_b() && p_180614_1_.func_175151_a(p_180614_3_, p_180614_5_, itemstack) && p_180614_2_.func_190527_a(this.field_150939_a, p_180614_3_, false, p_180614_5_, p_180614_1_))
{
int i = this.func_77647_b(itemstack.func_77960_j());
- IBlockState iblockstate1 = this.field_150939_a.func_180642_a(p_180614_2_, p_180614_3_, p_180614_5_, p_180614_6_, p_180614_7_, p_180614_8_, i, p_180614_1_);
@@ -37,6 +41,15 @@
{
p_179222_3_ = EnumFacing.UP;
}
@@ -136,7 +124,7 @@
p_179222_2_ = p_179222_2_.func_177972_a(p_179222_3_);
}
- return p_179222_1_.func_190527_a(this.field_150939_a, p_179222_2_, false, p_179222_3_, (Entity)null);
+ return p_179222_1_.func_190527_a(this.field_150939_a, p_179222_2_, false, p_179222_3_, p_179222_4_);
}
public String func_77667_c(ItemStack p_77667_1_)
@@ -171,6 +159,36 @@
public Block func_179223_d()
@@ -1,8 +1,11 @@
--- ../src-base/minecraft/net/minecraft/item/ItemBlockSpecial.java
+++ ../src-work/minecraft/net/minecraft/item/ItemBlockSpecial.java
@@ -43,7 +43,7 @@
@@ -41,9 +41,9 @@
if (!itemstack.func_190926_b() && p_180614_1_.func_175151_a(p_180614_3_, p_180614_5_, itemstack) && p_180614_2_.func_190527_a(this.field_150935_a, p_180614_3_, false, p_180614_5_, (Entity)null))
ItemStack itemstack = p_180614_1_.func_184586_b(p_180614_4_);
- if (!itemstack.func_190926_b() && p_180614_1_.func_175151_a(p_180614_3_, p_180614_5_, itemstack) && p_180614_2_.func_190527_a(this.field_150935_a, p_180614_3_, false, p_180614_5_, (Entity)null))
+ if (!itemstack.func_190926_b() && p_180614_1_.func_175151_a(p_180614_3_, p_180614_5_, itemstack) && p_180614_2_.func_190527_a(this.field_150935_a, p_180614_3_, false, p_180614_5_, p_180614_1_))
{
- IBlockState iblockstate1 = this.field_150935_a.func_180642_a(p_180614_2_, p_180614_3_, p_180614_5_, p_180614_6_, p_180614_7_, p_180614_8_, 0, p_180614_1_);
+ IBlockState iblockstate1 = this.field_150935_a.getStateForPlacement(p_180614_2_, p_180614_3_, p_180614_5_, p_180614_6_, p_180614_7_, p_180614_8_, 0, p_180614_1_, p_180614_4_);
@@ -1,5 +1,14 @@
--- ../src-base/minecraft/net/minecraft/item/ItemBow.java
+++ ../src-work/minecraft/net/minecraft/item/ItemBow.java
@@ -37,7 +37,7 @@
}
else
{
- return p_185085_3_.func_184607_cu().func_77973_b() != Items.field_151031_f ? 0.0F : (float)(p_185085_1_.func_77988_m() - p_185085_3_.func_184605_cv()) / 20.0F;
+ return !(p_185085_3_.func_184607_cu().func_77973_b() instanceof ItemBow) ? 0.0F : (float)(p_185085_1_.func_77988_m() - p_185085_3_.func_184605_cv()) / 20.0F;
}
}
});
@@ -90,6 +90,10 @@
boolean flag = entityplayer.field_71075_bZ.field_75098_d || EnchantmentHelper.func_77506_a(Enchantments.field_185312_x, p_77615_1_) > 0;
ItemStack itemstack = this.func_185060_a(entityplayer);
@@ -11,7 +20,7 @@
if (!itemstack.func_190926_b() || flag)
{
if (itemstack.func_190926_b())
@@ -97,12 +101,11 @@
@@ -97,17 +101,17 @@
itemstack = new ItemStack(Items.field_151032_g);
}
@@ -25,7 +34,13 @@
if (!p_77615_2_.field_72995_K)
{
@@ -190,6 +193,9 @@
ItemArrow itemarrow = (ItemArrow)(itemstack.func_77973_b() instanceof ItemArrow ? itemstack.func_77973_b() : Items.field_151032_g);
EntityArrow entityarrow = itemarrow.func_185052_a(p_77615_2_, itemstack, entityplayer);
+ entityarrow = this.customizeArrow(entityarrow);
entityarrow.func_184547_a(entityplayer, entityplayer.field_70125_A, entityplayer.field_70177_z, 0.0F, f * 3.0F, 1.0F);
if (f == 1.0F)
@@ -190,6 +194,9 @@
ItemStack itemstack = p_77659_2_.func_184586_b(p_77659_3_);
boolean flag = !this.func_185060_a(p_77659_2_).func_190926_b();
@@ -35,3 +50,13 @@
if (!p_77659_2_.field_71075_bZ.field_75098_d && !flag)
{
return flag ? new ActionResult(EnumActionResult.PASS, itemstack) : new ActionResult(EnumActionResult.FAIL, itemstack);
@@ -205,4 +212,9 @@
{
return 1;
}
+
+ public EntityArrow customizeArrow(EntityArrow arrow)
+ {
+ return arrow;
+ }
}
@@ -0,0 +1,10 @@
--- ../src-base/minecraft/net/minecraft/item/ItemMonsterPlacer.java
+++ ../src-work/minecraft/net/minecraft/item/ItemMonsterPlacer.java
@@ -234,6 +234,7 @@
entity.func_70012_b(p_77840_2_, p_77840_4_, p_77840_6_, MathHelper.func_76142_g(p_77840_0_.field_73012_v.nextFloat() * 360.0F), 0.0F);
entityliving.field_70759_as = entityliving.field_70177_z;
entityliving.field_70761_aq = entityliving.field_70177_z;
+ if (net.minecraftforge.event.ForgeEventFactory.doSpecialSpawn(entityliving, p_77840_0_, (float) p_77840_2_, (float) p_77840_4_, (float) p_77840_6_, null)) return null;
entityliving.func_180482_a(p_77840_0_.func_175649_E(new BlockPos(entityliving)), (IEntityLivingData)null);
p_77840_0_.func_72838_d(entity);
entityliving.func_70642_aH();
@@ -0,0 +1,11 @@
--- ../src-base/minecraft/net/minecraft/item/ItemRedstone.java
+++ ../src-work/minecraft/net/minecraft/item/ItemRedstone.java
@@ -25,7 +25,7 @@
BlockPos blockpos = flag ? p_180614_3_ : p_180614_3_.func_177972_a(p_180614_5_);
ItemStack itemstack = p_180614_1_.func_184586_b(p_180614_4_);
- if (p_180614_1_.func_175151_a(blockpos, p_180614_5_, itemstack) && p_180614_2_.func_190527_a(p_180614_2_.func_180495_p(blockpos).func_177230_c(), blockpos, false, p_180614_5_, (Entity)null) && Blocks.field_150488_af.func_176196_c(p_180614_2_, blockpos))
+ if (p_180614_1_.func_175151_a(blockpos, p_180614_5_, itemstack) && p_180614_2_.func_190527_a(p_180614_2_.func_180495_p(blockpos).func_177230_c(), blockpos, false, p_180614_5_, p_180614_1_) && Blocks.field_150488_af.func_176196_c(p_180614_2_, blockpos))
{
p_180614_2_.func_175656_a(blockpos, Blocks.field_150488_af.func_176223_P());
@@ -223,7 +223,15 @@
return list;
}
@@ -987,7 +1012,7 @@
@@ -871,6 +896,7 @@
return this.func_77973_b().func_77636_d(this);
}
+ @Deprecated // use Forge version on item
public EnumRarity func_77953_t()
{
return this.func_77973_b().func_77613_e(this);
@@ -987,7 +1013,7 @@
}
else
{
@@ -232,7 +240,16 @@
}
return multimap;
@@ -1130,4 +1155,128 @@
@@ -1032,7 +1058,7 @@
{
NBTTagCompound nbttagcompound = this.func_77955_b(new NBTTagCompound());
itextcomponent.func_150256_b().func_150209_a(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new TextComponentString(nbttagcompound.toString())));
- itextcomponent.func_150256_b().func_150238_a(this.func_77953_t().field_77937_e);
+ itextcomponent.func_150256_b().func_150238_a(this.func_77973_b().getForgeRarity(this).getColor());
}
return itextcomponent;
@@ -1130,4 +1156,128 @@
{
this.func_190917_f(-p_190918_1_);
}
@@ -1,6 +1,14 @@
--- ../src-base/minecraft/net/minecraft/nbt/NBTTagCompound.java
+++ ../src-work/minecraft/net/minecraft/nbt/NBTTagCompound.java
@@ -477,6 +477,7 @@
@@ -82,6 +82,7 @@
public void func_74782_a(String p_74782_1_, NBTBase p_74782_2_)
{
+ if (p_74782_2_ == null) throw new IllegalArgumentException("Invalid null NBT value with key " + p_74782_1_);
this.field_74784_a.put(p_74782_1_, p_74782_2_);
}
@@ -477,6 +478,7 @@
private static byte func_152447_a(DataInput p_152447_0_, NBTSizeTracker p_152447_1_) throws IOException
{
@@ -8,7 +16,7 @@
return p_152447_0_.readByte();
}
@@ -487,6 +488,7 @@
@@ -487,6 +489,7 @@
static NBTBase func_152449_a(byte p_152449_0_, String p_152449_1_, DataInput p_152449_2_, int p_152449_3_, NBTSizeTracker p_152449_4_) throws IOException
{
@@ -1,6 +1,20 @@
--- ../src-base/minecraft/net/minecraft/network/NetHandlerPlayServer.java
+++ ../src-work/minecraft/net/minecraft/network/NetHandlerPlayServer.java
@@ -671,7 +671,10 @@
@@ -377,11 +377,13 @@
}
entity.func_70080_a(d3, d4, d5, f, f1);
+ this.field_147369_b.func_70080_a(d3, d4, d5, this.field_147369_b.field_70177_z, this.field_147369_b.field_70125_A); // Forge - Resync player position on vehicle moving
boolean flag2 = worldserver.func_184144_a(entity, entity.func_174813_aQ().func_186664_h(0.0625D)).isEmpty();
if (flag && (flag1 || !flag2))
{
entity.func_70080_a(d0, d1, d2, f, f1);
+ this.field_147369_b.func_70080_a(d0, d1, d2, this.field_147369_b.field_70177_z, this.field_147369_b.field_70125_A); // Forge - Resync player position on vehicle moving
this.field_147371_a.func_179290_a(new SPacketMoveVehicle(entity));
return;
}
@@ -671,7 +673,10 @@
double d2 = this.field_147369_b.field_70161_v - ((double)blockpos.func_177952_p() + 0.5D);
double d3 = d0 * d0 + d1 * d1 + d2 * d2;
@@ -12,7 +26,7 @@
{
return;
}
@@ -729,7 +732,9 @@
@@ -729,7 +734,9 @@
if (blockpos.func_177956_o() < this.field_147367_d.func_71207_Z() - 1 || enumfacing != EnumFacing.UP && blockpos.func_177956_o() < this.field_147367_d.func_71207_Z())
{
@@ -23,7 +37,31 @@
{
this.field_147369_b.field_71134_c.func_187251_a(this.field_147369_b, worldserver, itemstack, enumhand, blockpos, enumfacing, p_184337_1_.func_187026_d(), p_184337_1_.func_187025_e(), p_184337_1_.func_187020_f());
}
@@ -933,7 +938,9 @@
@@ -789,12 +796,13 @@
{
this.field_147369_b.func_70634_a(entity.field_70165_t, entity.field_70163_u, entity.field_70161_v);
}
- else
+ else if (net.minecraftforge.common.ForgeHooks.onTravelToDimension(this.field_147369_b, entity.field_71093_bK))
{
+ int prevDimension = this.field_147369_b.field_71093_bK;
WorldServer worldserver1 = this.field_147369_b.func_71121_q();
WorldServer worldserver2 = (WorldServer)entity.field_70170_p;
this.field_147369_b.field_71093_bK = entity.field_71093_bK;
- this.func_147359_a(new SPacketRespawn(this.field_147369_b.field_71093_bK, worldserver1.func_175659_aa(), worldserver1.func_72912_H().func_76067_t(), this.field_147369_b.field_71134_c.func_73081_b()));
+ this.func_147359_a(new SPacketRespawn(this.field_147369_b.field_71093_bK, worldserver2.func_175659_aa(), worldserver2.func_72912_H().func_76067_t(), this.field_147369_b.field_71134_c.func_73081_b())); // Forge: Use new dimensions information
this.field_147367_d.func_184103_al().func_187243_f(this.field_147369_b);
worldserver1.func_72973_f(this.field_147369_b);
this.field_147369_b.field_70128_L = false;
@@ -813,6 +821,7 @@
this.field_147369_b.field_71134_c.func_73080_a(worldserver2);
this.field_147367_d.func_184103_al().func_72354_b(this.field_147369_b, worldserver2);
this.field_147367_d.func_184103_al().func_72385_f(this.field_147369_b);
+ net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerChangedDimensionEvent(this.field_147369_b, prevDimension, this.field_147369_b.field_71093_bK);
}
}
}
@@ -933,7 +942,9 @@
}
else
{
@@ -34,7 +72,7 @@
this.field_147367_d.func_184103_al().func_148544_a(itextcomponent, false);
}
@@ -1066,6 +1073,7 @@
@@ -1066,6 +1077,7 @@
else if (p_147340_1_.func_149565_c() == CPacketUseEntity.Action.INTERACT_AT)
{
EnumHand enumhand1 = p_147340_1_.func_186994_b();
@@ -42,7 +80,7 @@
entity.func_184199_a(this.field_147369_b, p_147340_1_.func_179712_b(), enumhand1);
}
else if (p_147340_1_.func_149565_c() == CPacketUseEntity.Action.ATTACK)
@@ -1106,7 +1114,7 @@
@@ -1106,7 +1118,7 @@
return;
}
@@ -51,7 +89,7 @@
if (this.field_147367_d.func_71199_h())
{
@@ -1149,7 +1157,7 @@
@@ -1149,7 +1161,7 @@
{
ItemStack itemstack2 = this.field_147369_b.field_71070_bA.func_184996_a(p_147351_1_.func_149544_d(), p_147351_1_.func_149543_e(), p_147351_1_.func_186993_f(), this.field_147369_b);
@@ -0,0 +1,27 @@
--- ../src-base/minecraft/net/minecraft/network/datasync/DataSerializers.java
+++ ../src-work/minecraft/net/minecraft/network/datasync/DataSerializers.java
@@ -305,20 +305,21 @@
}
};
+ @Deprecated // Forge: ONLY FOR VANILLA - mods should use the Forge registry
public static void func_187189_a(DataSerializer<?> p_187189_0_)
{
- field_187204_n.func_186808_c(p_187189_0_);
+ if (field_187204_n.func_186808_c(p_187189_0_) >= 256) throw new RuntimeException("Vanilla DataSerializer ID limit exceeded");
}
@Nullable
public static DataSerializer<?> func_187190_a(int p_187190_0_)
{
- return (DataSerializer)field_187204_n.func_186813_a(p_187190_0_);
+ return net.minecraftforge.common.ForgeHooks.getSerializer(p_187190_0_, field_187204_n);
}
public static int func_187188_b(DataSerializer<?> p_187188_0_)
{
- return field_187204_n.func_186815_a(p_187188_0_);
+ return net.minecraftforge.common.ForgeHooks.getSerializerId(p_187188_0_, field_187204_n);
}
static
@@ -0,0 +1,22 @@
--- ../src-base/minecraft/net/minecraft/network/datasync/EntityDataManager.java
+++ ../src-work/minecraft/net/minecraft/network/datasync/EntityDataManager.java
@@ -38,7 +38,7 @@
public static <T> DataParameter<T> func_187226_a(Class <? extends Entity > p_187226_0_, DataSerializer<T> p_187226_1_)
{
- if (field_190303_a.isDebugEnabled())
+ if (true || field_190303_a.isDebugEnabled()) //Forge: This is very useful for mods that register keys on classes that are not their own
{
try
{
@@ -46,7 +46,9 @@
if (!oclass.equals(p_187226_0_))
{
- field_190303_a.debug("defineId called for: {} from {}", p_187226_0_, oclass, new RuntimeException());
+ //Forge: log at warn, mods should not add to classes that they don't own, and only add stacktrace when in debug is enabled as it is mostly not needed and consumes time
+ if (field_190303_a.isDebugEnabled()) field_190303_a.warn("defineId called for: {} from {}", p_187226_0_, oclass, new RuntimeException());
+ else field_190303_a.warn("defineId called for: {} from {}", p_187226_0_, oclass);
}
}
catch (ClassNotFoundException var5)
@@ -0,0 +1,20 @@
--- ../src-base/minecraft/net/minecraft/pathfinding/FlyingNodeProcessor.java
+++ ../src-work/minecraft/net/minecraft/pathfinding/FlyingNodeProcessor.java
@@ -272,7 +272,9 @@
EnumSet<PathNodeType> enumset = EnumSet.<PathNodeType>noneOf(PathNodeType.class);
PathNodeType pathnodetype = PathNodeType.BLOCKED;
BlockPos blockpos = new BlockPos(p_186319_5_);
+ this.currentEntity = p_186319_5_;
pathnodetype = this.func_193577_a(p_186319_1_, p_186319_2_, p_186319_3_, p_186319_4_, p_186319_6_, p_186319_7_, p_186319_8_, p_186319_9_, p_186319_10_, enumset, pathnodetype, blockpos);
+ this.currentEntity = null;
if (enumset.contains(PathNodeType.FENCE))
{
@@ -321,6 +323,7 @@
{
pathnodetype = PathNodeType.DAMAGE_CACTUS;
}
+ else if (pathnodetype1 == PathNodeType.DAMAGE_OTHER) pathnodetype = PathNodeType.DAMAGE_OTHER;
else
{
pathnodetype = pathnodetype1 != PathNodeType.WALKABLE && pathnodetype1 != PathNodeType.OPEN && pathnodetype1 != PathNodeType.WATER ? PathNodeType.WALKABLE : PathNodeType.OPEN;
@@ -1,18 +1,60 @@
--- ../src-base/minecraft/net/minecraft/pathfinding/WalkNodeProcessor.java
+++ ../src-work/minecraft/net/minecraft/pathfinding/WalkNodeProcessor.java
@@ -427,6 +427,7 @@
@@ -23,6 +23,7 @@
public class WalkNodeProcessor extends NodeProcessor
{
protected float field_176183_h;
+ protected EntityLiving currentEntity;
public void func_186315_a(IBlockAccess p_186315_1_, EntityLiving p_186315_2_)
{
@@ -295,7 +296,9 @@
PathNodeType pathnodetype = PathNodeType.BLOCKED;
double d0 = (double)p_186319_5_.field_70130_N / 2.0D;
BlockPos blockpos = new BlockPos(p_186319_5_);
+ this.currentEntity = p_186319_5_;
pathnodetype = this.func_193577_a(p_186319_1_, p_186319_2_, p_186319_3_, p_186319_4_, p_186319_6_, p_186319_7_, p_186319_8_, p_186319_9_, p_186319_10_, enumset, pathnodetype, blockpos);
+ this.currentEntity = null;
if (enumset.contains(PathNodeType.FENCE))
{
@@ -399,6 +402,8 @@
{
pathnodetype = PathNodeType.DAMAGE_CACTUS;
}
+
+ if (pathnodetype1 == PathNodeType.DAMAGE_OTHER) pathnodetype = PathNodeType.DAMAGE_OTHER;
}
pathnodetype = this.func_193578_a(p_186330_1_, p_186330_2_, p_186330_3_, p_186330_4_, pathnodetype);
@@ -417,16 +422,19 @@
{
if (i != 0 || j != 0)
{
- Block block = p_193578_1_.func_180495_p(blockpos$pooledmutableblockpos.func_181079_c(i + p_193578_2_, p_193578_3_, j + p_193578_4_)).func_177230_c();
+ IBlockState state = p_193578_1_.func_180495_p(blockpos$pooledmutableblockpos.func_181079_c(i + p_193578_2_, p_193578_3_, j + p_193578_4_));
+ Block block = state.func_177230_c();
+ PathNodeType type = block.getAiPathNodeType(state, p_193578_1_, blockpos$pooledmutableblockpos, this.currentEntity);
- if (block == Blocks.field_150434_aF)
+ if (block == Blocks.field_150434_aF || type == PathNodeType.DAMAGE_CACTUS)
{
p_193578_5_ = PathNodeType.DANGER_CACTUS;
}
- else if (block == Blocks.field_150480_ab)
+ else if (block == Blocks.field_150480_ab || type == PathNodeType.DAMAGE_FIRE)
{
p_193578_5_ = PathNodeType.DANGER_FIRE;
}
+ else if(block.isBurning(p_193578_1_,blockpos$pooledmutableblockpos)) p_193578_5_ = PathNodeType.DAMAGE_FIRE;
+ else if (type == PathNodeType.DAMAGE_OTHER) p_193578_5_ = PathNodeType.DANGER_OTHER;
}
}
}
@@ -443,6 +444,9 @@
@@ -443,6 +451,9 @@
Block block = iblockstate.func_177230_c();
Material material = iblockstate.func_185904_a();
+ PathNodeType type = block.getAiPathNodeType(iblockstate, p_189553_1_, blockpos);
+ PathNodeType type = block.getAiPathNodeType(iblockstate, p_189553_1_, blockpos, this.currentEntity);
+ if (type != null) return type;
+
if (material == Material.field_151579_a)
@@ -20,7 +20,7 @@
public boolean func_76398_f()
{
return this.field_76418_K;
@@ -293,7 +292,85 @@
@@ -293,7 +292,122 @@
return p_111183_2_.func_111164_d() * (double)(p_111183_1_ + 1);
}
@@ -60,11 +60,29 @@
+ * @param y the y coordinate
+ * @param effect the active PotionEffect
+ * @param mc the Minecraft instance, for convenience
+ * @deprecated use {@link #renderInventoryEffect(PotionEffect, net.minecraft.client.gui.Gui, int, int, float)}
+ */
@SideOnly(Side.CLIENT)
+ @Deprecated // TODO: remove
+ public void renderInventoryEffect(int x, int y, PotionEffect effect, net.minecraft.client.Minecraft mc) { }
+
+ /**
+ * Called to draw the this Potion onto the player's inventory when it's active.
+ * This can be used to e.g. render Potion icons from your own texture.
+ *
+ * @param effect the active PotionEffect
+ * @param gui the gui instance
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param z the z level
+ */
+ @SideOnly(Side.CLIENT)
+ public void renderInventoryEffect(PotionEffect effect, net.minecraft.client.gui.Gui gui, int x, int y, float z)
+ {
+ renderInventoryEffect(x, y, effect, net.minecraft.client.Minecraft.func_71410_x());
+ }
+
+ /**
+ * Called to draw the this Potion onto the player's ingame HUD when it's active.
+ * This can be used to e.g. render Potion icons from your own texture.
+ * @param x the x coordinate
@@ -72,11 +90,30 @@
+ * @param effect the active PotionEffect
+ * @param mc the Minecraft instance, for convenience
+ * @param alpha the alpha value, blinks when the potion is about to run out
+ * @deprecated use {@link #renderHUDEffect(PotionEffect, net.minecraft.client.gui.Gui, int, int, float, float)}
+ */
+ @SideOnly(Side.CLIENT)
+ @Deprecated // TODO: remove
+ public void renderHUDEffect(int x, int y, PotionEffect effect, net.minecraft.client.Minecraft mc, float alpha) { }
+
+ /**
+ * Called to draw the this Potion onto the player's ingame HUD when it's active.
+ * This can be used to e.g. render Potion icons from your own texture.
+ *
+ * @param effect the active PotionEffect
+ * @param gui the gui instance
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param z the z level
+ * @param alpha the alpha value, blinks when the potion is about to run out
+ */
+ @SideOnly(Side.CLIENT)
+ public void renderHUDEffect(PotionEffect effect, net.minecraft.client.gui.Gui gui, int x, int y, float z, float alpha)
+ {
+ renderHUDEffect(x, y, effect, net.minecraft.client.Minecraft.func_71410_x(), alpha);
+ }
+
+ /**
+ * Get a fresh list of items that can cure this Potion.
+ * All new PotionEffects created from this Potion will call this to initialize the default curative items
+ * @see PotionEffect#getCurativeItems
@@ -17,7 +17,19 @@
}
public void func_76452_a(PotionEffect p_76452_1_)
@@ -195,12 +198,13 @@
@@ -79,6 +82,11 @@
public Potion func_188419_a()
{
+ return this.getPotionRaw() == null ? null : this.getPotionRaw().delegate.get();
+ }
+
+ private Potion getPotionRaw()
+ {
return this.field_188420_b;
}
@@ -195,12 +203,13 @@
p_82719_1_.func_74768_a("Duration", this.func_76459_b());
p_82719_1_.func_74757_a("Ambient", this.func_82720_e());
p_82719_1_.func_74757_a("ShowParticles", this.func_188418_e());
@@ -32,7 +44,7 @@
Potion potion = Potion.func_188412_a(i);
if (potion == null)
@@ -219,7 +223,7 @@
@@ -219,7 +228,7 @@
flag1 = p_82722_0_.func_74767_n("ShowParticles");
}
@@ -41,7 +53,7 @@
}
}
@@ -232,7 +236,7 @@
@@ -232,7 +241,7 @@
public int compareTo(PotionEffect p_compareTo_1_)
{
int i = 32147;
@@ -50,7 +62,7 @@
}
@SideOnly(Side.CLIENT)
@@ -240,4 +244,85 @@
@@ -240,4 +249,85 @@
{
return this.field_100013_f;
}
@@ -0,0 +1,67 @@
--- ../src-base/minecraft/net/minecraft/potion/PotionHelper.java
+++ ../src-work/minecraft/net/minecraft/potion/PotionHelper.java
@@ -88,7 +88,7 @@
{
PotionHelper.MixPredicate<Item> mixpredicate = (PotionHelper.MixPredicate)field_185214_b.get(i);
- if (mixpredicate.field_185198_a == item && mixpredicate.field_185199_b.apply(p_185206_1_))
+ if (mixpredicate.field_185198_a.get() == item && mixpredicate.field_185199_b.apply(p_185206_1_))
{
return true;
}
@@ -106,7 +106,7 @@
{
PotionHelper.MixPredicate<PotionType> mixpredicate = (PotionHelper.MixPredicate)field_185213_a.get(i);
- if (mixpredicate.field_185198_a == potiontype && mixpredicate.field_185199_b.apply(p_185209_1_))
+ if (mixpredicate.field_185198_a.get() == potiontype && mixpredicate.field_185199_b.apply(p_185209_1_))
{
return true;
}
@@ -127,9 +127,9 @@
{
PotionHelper.MixPredicate<Item> mixpredicate = (PotionHelper.MixPredicate)field_185214_b.get(i);
- if (mixpredicate.field_185198_a == item && mixpredicate.field_185199_b.apply(p_185212_0_))
+ if (mixpredicate.field_185198_a.get() == item && mixpredicate.field_185199_b.apply(p_185212_0_))
{
- return PotionUtils.func_185188_a(new ItemStack((Item)mixpredicate.field_185200_c), potiontype);
+ return PotionUtils.func_185188_a(new ItemStack((Item)mixpredicate.field_185200_c.get()), potiontype);
}
}
@@ -139,9 +139,9 @@
{
PotionHelper.MixPredicate<PotionType> mixpredicate1 = (PotionHelper.MixPredicate)field_185213_a.get(i);
- if (mixpredicate1.field_185198_a == potiontype && mixpredicate1.field_185199_b.apply(p_185212_0_))
+ if (mixpredicate1.field_185198_a.get() == potiontype && mixpredicate1.field_185199_b.apply(p_185212_0_))
{
- return PotionUtils.func_185188_a(new ItemStack(item), (PotionType)mixpredicate1.field_185200_c);
+ return PotionUtils.func_185188_a(new ItemStack(item), (PotionType)mixpredicate1.field_185200_c.get());
}
}
}
@@ -227,17 +227,17 @@
field_185213_a.add(new PotionHelper.MixPredicate(p_193356_0_, p_193356_1_, p_193356_2_));
}
- static class MixPredicate<T>
+ static class MixPredicate<T extends net.minecraftforge.registries.IForgeRegistryEntry.Impl<T>>
{
- final T field_185198_a;
+ final net.minecraftforge.registries.IRegistryDelegate<T> field_185198_a;
final Ingredient field_185199_b;
- final T field_185200_c;
+ 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_;
+ this.field_185198_a = p_i47570_1_.delegate;
this.field_185199_b = p_i47570_2_;
- this.field_185200_c = p_i47570_3_;
+ this.field_185200_c = p_i47570_3_.delegate;
}
}
}
@@ -167,7 +167,7 @@
p_187242_1_.field_71093_bK = p_187242_2_;
WorldServer worldserver1 = this.field_72400_f.func_71218_a(p_187242_1_.field_71093_bK);
- p_187242_1_.field_71135_a.func_147359_a(new SPacketRespawn(p_187242_1_.field_71093_bK, p_187242_1_.field_70170_p.func_175659_aa(), p_187242_1_.field_70170_p.func_72912_H().func_76067_t(), p_187242_1_.field_71134_c.func_73081_b()));
+ p_187242_1_.field_71135_a.func_147359_a(new SPacketRespawn(p_187242_1_.field_71093_bK, worldserver1.func_175659_aa(), worldserver1.func_72912_H().func_76067_t(), p_187242_1_.field_71134_c.func_73081_b()));
+ p_187242_1_.field_71135_a.func_147359_a(new SPacketRespawn(p_187242_1_.field_71093_bK, worldserver1.func_175659_aa(), worldserver1.func_72912_H().func_76067_t(), p_187242_1_.field_71134_c.func_73081_b())); // Forge: Use new dimensions information
this.func_187243_f(p_187242_1_);
worldserver.func_72973_f(p_187242_1_);
p_187242_1_.field_70128_L = false;
@@ -1,13 +1,21 @@
--- ../src-base/minecraft/net/minecraft/util/text/translation/LanguageMap.java
+++ ../src-work/minecraft/net/minecraft/util/text/translation/LanguageMap.java
@@ -23,9 +23,29 @@
@@ -23,10 +23,37 @@
public LanguageMap()
{
+ InputStream inputstream = LanguageMap.class.getResourceAsStream("/assets/minecraft/lang/en_us.lang");
+ inject(this, inputstream);
try
{
- InputStream inputstream = LanguageMap.class.getResourceAsStream("/assets/minecraft/lang/en_us.lang");
+ inject(this, inputstream);
+ }
+ finally
+ {
+ IOUtils.closeQuietly(inputstream); // Forge: close stream after use (MC-153470)
+ }
+ }
+
+ public static void inject(InputStream inputstream)
+ {
+ inject(field_74817_a, inputstream);
@@ -23,15 +31,15 @@
+ public static Map<String, String> parseLangFile(InputStream inputstream)
+ {
+ Map<String, String> table = Maps.newHashMap();
try
{
- InputStream inputstream = LanguageMap.class.getResourceAsStream("/assets/minecraft/lang/en_us.lang");
+ try
+ {
+ inputstream = net.minecraftforge.fml.common.FMLCommonHandler.instance().loadLanguage(table, inputstream);
+ if (inputstream == null) return table;
+
for (String s : IOUtils.readLines(inputstream, StandardCharsets.UTF_8))
{
@@ -37,17 +57,18 @@
if (!s.isEmpty() && s.charAt(0) != '#')
@@ -37,17 +64,18 @@
{
String s1 = astring[0];
String s2 = field_111053_a.matcher(astring[1]).replaceAll("%$1s");
@@ -0,0 +1,10 @@
--- ../src-base/minecraft/net/minecraft/village/VillageSiege.java
+++ ../src-work/minecraft/net/minecraft/village/VillageSiege.java
@@ -146,6 +146,7 @@
if (vec3d != null)
{
+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.village.VillageSiegeEvent(this, field_75537_a, entityplayer, field_75531_f, vec3d))) return false;
break;
}
}
@@ -1,6 +1,14 @@
--- ../src-base/minecraft/net/minecraft/world/World.java
+++ ../src-work/minecraft/net/minecraft/world/World.java
@@ -63,8 +63,15 @@
@@ -11,6 +11,7 @@
import java.util.Random;
import java.util.UUID;
import java.util.function.Supplier;
+
import javax.annotation.Nullable;
import net.minecraft.advancements.AdvancementManager;
import net.minecraft.advancements.FunctionManager;
@@ -63,8 +64,15 @@
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@@ -17,7 +25,7 @@
private int field_181546_a = 63;
protected boolean field_72999_e;
public final List<Entity> field_72996_f = Lists.<Entity>newArrayList();
@@ -108,6 +115,12 @@
@@ -108,6 +116,12 @@
private final WorldBorder field_175728_M;
int[] field_72994_J;
@@ -30,7 +38,7 @@
protected World(ISaveHandler p_i45749_1_, WorldInfo p_i45749_2_, WorldProvider p_i45749_3_, Profiler p_i45749_4_, boolean p_i45749_5_)
{
this.field_73021_x = Lists.newArrayList(this.field_184152_t);
@@ -122,6 +135,7 @@
@@ -122,6 +136,7 @@
this.field_73011_w = p_i45749_3_;
this.field_72995_K = p_i45749_5_;
this.field_175728_M = p_i45749_3_.func_177501_r();
@@ -38,7 +46,7 @@
}
public World func_175643_b()
@@ -131,6 +145,11 @@
@@ -131,6 +146,11 @@
public Biome func_180494_b(final BlockPos p_180494_1_)
{
@@ -50,7 +58,7 @@
if (this.func_175667_e(p_180494_1_))
{
Chunk chunk = this.func_175726_f(p_180494_1_);
@@ -207,7 +226,7 @@
@@ -207,7 +227,7 @@
public boolean func_175623_d(BlockPos p_175623_1_)
{
@@ -59,7 +67,7 @@
}
public boolean func_175667_e(BlockPos p_175667_1_)
@@ -308,24 +327,51 @@
@@ -308,24 +328,51 @@
else
{
Chunk chunk = this.func_175726_f(p_180501_1_);
@@ -114,7 +122,7 @@
this.func_184138_a(p_180501_1_, iblockstate, p_180501_2_, p_180501_3_);
}
@@ -342,8 +388,6 @@
@@ -342,8 +389,6 @@
{
this.func_190522_c(p_180501_1_, block);
}
@@ -123,7 +131,7 @@
}
}
}
@@ -358,7 +402,7 @@
@@ -358,7 +403,7 @@
IBlockState iblockstate = this.func_180495_p(p_175655_1_);
Block block = iblockstate.func_177230_c();
@@ -132,7 +140,7 @@
{
return false;
}
@@ -441,6 +485,9 @@
@@ -441,6 +486,9 @@
public void func_175685_c(BlockPos p_175685_1_, Block p_175685_2_, boolean p_175685_3_)
{
@@ -142,7 +150,7 @@
this.func_190524_a(p_175685_1_.func_177976_e(), p_175685_2_, p_175685_1_);
this.func_190524_a(p_175685_1_.func_177974_f(), p_175685_2_, p_175685_1_);
this.func_190524_a(p_175685_1_.func_177977_b(), p_175685_2_, p_175685_1_);
@@ -456,6 +503,11 @@
@@ -456,6 +504,11 @@
public void func_175695_a(BlockPos p_175695_1_, Block p_175695_2_, EnumFacing p_175695_3_)
{
@@ -154,7 +162,7 @@
if (p_175695_3_ != EnumFacing.WEST)
{
this.func_190524_a(p_175695_1_.func_177976_e(), p_175695_2_, p_175695_1_);
@@ -507,7 +559,7 @@
@@ -507,7 +560,7 @@
{
try
{
@@ -163,7 +171,7 @@
}
catch (Throwable var2)
{
@@ -527,11 +579,11 @@
@@ -527,11 +580,11 @@
{
IBlockState iblockstate = this.func_180495_p(p_190529_1_);
@@ -177,7 +185,7 @@
}
catch (Throwable throwable)
{
@@ -543,7 +595,7 @@
@@ -543,7 +596,7 @@
{
try
{
@@ -186,7 +194,7 @@
}
catch (Throwable var2)
{
@@ -588,7 +640,7 @@
@@ -588,7 +641,7 @@
{
IBlockState iblockstate = this.func_180495_p(blockpos1);
@@ -195,7 +203,7 @@
{
return false;
}
@@ -862,7 +914,7 @@
@@ -862,7 +915,7 @@
public boolean func_72935_r()
{
@@ -204,7 +212,7 @@
}
@Nullable
@@ -1065,6 +1117,13 @@
@@ -1065,6 +1118,13 @@
public void func_184148_a(@Nullable EntityPlayer p_184148_1_, double p_184148_2_, double p_184148_4_, double p_184148_6_, SoundEvent p_184148_8_, SoundCategory p_184148_9_, float p_184148_10_, float p_184148_11_)
{
@@ -218,7 +226,16 @@
for (int i = 0; i < this.field_73021_x.size(); ++i)
{
((IWorldEventListener)this.field_73021_x.get(i)).func_184375_a(p_184148_1_, p_184148_8_, p_184148_9_, p_184148_2_, p_184148_4_, p_184148_6_, p_184148_10_, p_184148_11_);
@@ -1118,6 +1177,9 @@
@@ -1112,12 +1172,18 @@
public boolean func_72942_c(Entity p_72942_1_)
{
+ if(net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityJoinWorldEvent(p_72942_1_, this)))
+ return false;
+
this.field_73007_j.add(p_72942_1_);
return true;
}
public boolean func_72838_d(Entity p_72838_1_)
{
@@ -228,7 +245,7 @@
int i = MathHelper.func_76128_c(p_72838_1_.field_70165_t / 16.0D);
int j = MathHelper.func_76128_c(p_72838_1_.field_70161_v / 16.0D);
boolean flag = p_72838_1_.field_98038_p;
@@ -1140,6 +1202,8 @@
@@ -1140,6 +1206,8 @@
this.func_72854_c();
}
@@ -237,7 +254,23 @@
this.func_72964_e(i, j).func_76612_a(p_72838_1_);
this.field_72996_f.add(p_72838_1_);
this.func_72923_a(p_72838_1_);
@@ -1227,6 +1291,7 @@
@@ -1153,6 +1221,7 @@
{
((IWorldEventListener)this.field_73021_x.get(i)).func_72703_a(p_72923_1_);
}
+ p_72923_1_.onAddedToWorld();
}
public void func_72847_b(Entity p_72847_1_)
@@ -1161,6 +1230,7 @@
{
((IWorldEventListener)this.field_73021_x.get(i)).func_72709_b(p_72847_1_);
}
+ p_72847_1_.onRemovedFromWorld();
}
public void func_72900_e(Entity p_72900_1_)
@@ -1227,6 +1297,7 @@
IBlockState iblockstate = Blocks.field_150348_b.func_176223_P();
BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.func_185346_s();
@@ -245,7 +278,7 @@
try
{
for (int k1 = i; k1 < j; ++k1)
@@ -1269,7 +1334,7 @@
@@ -1269,7 +1340,7 @@
iblockstate1.func_185908_a(this, blockpos$pooledmutableblockpos, p_191504_2_, p_191504_4_, p_191504_1_, false);
@@ -254,7 +287,7 @@
{
boolean flag5 = true;
return flag5;
@@ -1319,11 +1384,10 @@
@@ -1319,11 +1390,10 @@
}
}
}
@@ -267,7 +300,7 @@
public void func_72848_b(IWorldEventListener p_72848_1_)
{
this.field_73021_x.remove(p_72848_1_);
@@ -1361,19 +1425,38 @@
@@ -1361,19 +1431,38 @@
public int func_72967_a(float p_72967_1_)
{
@@ -308,7 +341,7 @@
float f = this.func_72826_c(p_72971_1_);
float f1 = 1.0F - (MathHelper.func_76134_b(f * ((float)Math.PI * 2F)) * 2.0F + 0.2F);
f1 = MathHelper.func_76131_a(f1, 0.0F, 1.0F);
@@ -1386,6 +1469,12 @@
@@ -1386,6 +1475,12 @@
@SideOnly(Side.CLIENT)
public Vec3d func_72833_a(Entity p_72833_1_, float p_72833_2_)
{
@@ -321,7 +354,7 @@
float f = this.func_72826_c(p_72833_2_);
float f1 = MathHelper.func_76134_b(f * ((float)Math.PI * 2F)) * 2.0F + 0.5F;
f1 = MathHelper.func_76131_a(f1, 0.0F, 1.0F);
@@ -1393,9 +1482,7 @@
@@ -1393,9 +1488,7 @@
int j = MathHelper.func_76128_c(p_72833_1_.field_70163_u);
int k = MathHelper.func_76128_c(p_72833_1_.field_70161_v);
BlockPos blockpos = new BlockPos(i, j, k);
@@ -332,7 +365,7 @@
float f3 = (float)(l >> 16 & 255) / 255.0F;
float f4 = (float)(l >> 8 & 255) / 255.0F;
float f5 = (float)(l & 255) / 255.0F;
@@ -1444,20 +1531,25 @@
@@ -1444,20 +1537,25 @@
public float func_72826_c(float p_72826_1_)
{
@@ -361,7 +394,7 @@
public float func_72929_e(float p_72929_1_)
{
float f = this.func_72826_c(p_72929_1_);
@@ -1467,6 +1559,12 @@
@@ -1467,6 +1565,12 @@
@SideOnly(Side.CLIENT)
public Vec3d func_72824_f(float p_72824_1_)
{
@@ -374,7 +407,7 @@
float f = this.func_72826_c(p_72824_1_);
float f1 = MathHelper.func_76134_b(f * ((float)Math.PI * 2F)) * 2.0F + 0.5F;
f1 = MathHelper.func_76131_a(f1, 0.0F, 1.0F);
@@ -1522,9 +1620,9 @@
@@ -1522,9 +1626,9 @@
for (blockpos = new BlockPos(p_175672_1_.func_177958_n(), chunk.func_76625_h() + 16, p_175672_1_.func_177952_p()); blockpos.func_177956_o() >= 0; blockpos = blockpos1)
{
blockpos1 = blockpos.func_177977_b();
@@ -386,7 +419,7 @@
{
break;
}
@@ -1536,6 +1634,12 @@
@@ -1536,6 +1640,12 @@
@SideOnly(Side.CLIENT)
public float func_72880_h(float p_72880_1_)
{
@@ -399,7 +432,7 @@
float f = this.func_72826_c(p_72880_1_);
float f1 = 1.0F - (MathHelper.func_76134_b(f * ((float)Math.PI * 2F)) * 2.0F + 0.25F);
f1 = MathHelper.func_76131_a(f1, 0.0F, 1.0F);
@@ -1570,6 +1674,7 @@
@@ -1570,6 +1680,7 @@
try
{
@@ -407,7 +440,7 @@
++entity.field_70173_aa;
entity.func_70071_h_();
}
@@ -1587,6 +1692,12 @@
@@ -1587,6 +1698,12 @@
entity.func_85029_a(crashreportcategory);
}
@@ -420,7 +453,7 @@
throw new ReportedException(crashreport);
}
@@ -1641,13 +1752,21 @@
@@ -1641,13 +1758,21 @@
{
try
{
@@ -442,7 +475,7 @@
throw new ReportedException(crashreport1);
}
}
@@ -1674,14 +1793,23 @@
@@ -1674,14 +1799,23 @@
this.field_72984_F.func_76318_c("blockEntities");
@@ -469,7 +502,7 @@
Iterator<TileEntity> iterator = this.field_175730_i.iterator();
while (iterator.hasNext())
@@ -1692,7 +1820,7 @@
@@ -1692,7 +1826,7 @@
{
BlockPos blockpos = tileentity.func_174877_v();
@@ -478,7 +511,7 @@
{
try
{
@@ -1700,7 +1828,9 @@
@@ -1700,7 +1834,9 @@
{
return String.valueOf((Object)TileEntity.func_190559_a(tileentity.getClass()));
});
@@ -488,7 +521,7 @@
this.field_72984_F.func_76319_b();
}
catch (Throwable throwable)
@@ -1708,6 +1838,13 @@
@@ -1708,6 +1844,13 @@
CrashReport crashreport2 = CrashReport.func_85055_a(throwable, "Ticking block entity");
CrashReportCategory crashreportcategory2 = crashreport2.func_85058_a("Block entity being ticked");
tileentity.func_145828_a(crashreportcategory2);
@@ -502,7 +535,7 @@
throw new ReportedException(crashreport2);
}
}
@@ -1720,7 +1857,10 @@
@@ -1720,7 +1863,10 @@
if (this.func_175667_e(tileentity.func_174877_v()))
{
@@ -514,7 +547,7 @@
}
}
}
@@ -1764,12 +1904,18 @@
@@ -1764,12 +1910,18 @@
public boolean func_175700_a(TileEntity p_175700_1_)
{
@@ -533,7 +566,7 @@
if (this.field_72995_K)
{
@@ -1785,6 +1931,11 @@
@@ -1785,6 +1937,11 @@
{
if (this.field_147481_N)
{
@@ -545,14 +578,14 @@
this.field_147484_a.addAll(p_147448_1_);
}
else
@@ -1807,9 +1958,13 @@
@@ -1807,9 +1964,13 @@
{
int j2 = MathHelper.func_76128_c(p_72866_1_.field_70165_t);
int k2 = MathHelper.func_76128_c(p_72866_1_.field_70161_v);
- int l2 = 32;
- if (p_72866_2_ && !this.func_175663_a(j2 - 32, 0, k2 - 32, j2 + 32, 0, k2 + 32, true))
+ boolean isForced = getPersistentChunks().containsKey(new net.minecraft.util.math.ChunkPos(j2 >> 4, k2 >> 4));
+ boolean isForced = !this.field_72995_K && getPersistentChunks().containsKey(new net.minecraft.util.math.ChunkPos(j2 >> 4, k2 >> 4));
+ int range = isForced ? 0 : 32;
+ boolean canUpdate = !p_72866_2_ || this.func_175663_a(j2 - range, 0, k2 - range, j2 + range, 0, k2 + range, true);
+ if (!canUpdate) canUpdate = net.minecraftforge.event.ForgeEventFactory.canEntityUpdate(p_72866_1_);
@@ -561,7 +594,7 @@
{
return;
}
@@ -1831,6 +1986,7 @@
@@ -1831,6 +1992,7 @@
}
else
{
@@ -569,7 +602,7 @@
p_72866_1_.func_70071_h_();
}
}
@@ -1914,7 +2070,7 @@
@@ -1914,7 +2076,7 @@
{
Entity entity4 = list.get(j2);
@@ -578,7 +611,7 @@
{
return false;
}
@@ -1972,6 +2128,12 @@
@@ -1972,6 +2134,12 @@
{
IBlockState iblockstate1 = this.func_180495_p(blockpos$pooledmutableblockpos.func_181079_c(l3, i4, j4));
@@ -591,7 +624,7 @@
if (iblockstate1.func_185904_a().func_76224_d())
{
blockpos$pooledmutableblockpos.func_185344_t();
@@ -2011,6 +2173,11 @@
@@ -2011,6 +2179,11 @@
blockpos$pooledmutableblockpos.func_185344_t();
return true;
}
@@ -603,7 +636,7 @@
}
}
}
@@ -2050,6 +2217,16 @@
@@ -2050,6 +2223,16 @@
IBlockState iblockstate1 = this.func_180495_p(blockpos$pooledmutableblockpos);
Block block = iblockstate1.func_177230_c();
@@ -620,7 +653,7 @@
if (iblockstate1.func_185904_a() == p_72918_2_)
{
double d0 = (double)((float)(i4 + 1) - BlockLiquid.func_149801_b(((Integer)iblockstate1.func_177229_b(BlockLiquid.field_176367_b)).intValue()));
@@ -2095,7 +2272,14 @@
@@ -2095,7 +2278,14 @@
{
for (int j4 = j3; j4 < k3; ++j4)
{
@@ -636,7 +669,7 @@
{
blockpos$pooledmutableblockpos.func_185344_t();
return true;
@@ -2116,6 +2300,7 @@
@@ -2116,6 +2306,7 @@
public Explosion func_72885_a(@Nullable Entity p_72885_1_, double p_72885_2_, double p_72885_4_, double p_72885_6_, float p_72885_8_, boolean p_72885_9_, boolean p_72885_10_)
{
Explosion explosion = new Explosion(this, p_72885_1_, p_72885_2_, p_72885_4_, p_72885_6_, p_72885_8_, p_72885_9_, p_72885_10_);
@@ -644,7 +677,7 @@
explosion.func_77278_a();
explosion.func_77279_a(true);
return explosion;
@@ -2238,6 +2423,7 @@
@@ -2238,6 +2429,7 @@
public void func_175690_a(BlockPos p_175690_1_, @Nullable TileEntity p_175690_2_)
{
@@ -652,16 +685,29 @@
if (!this.func_189509_E(p_175690_1_))
{
if (p_175690_2_ != null && !p_175690_2_.func_145837_r())
@@ -2245,6 +2431,8 @@
@@ -2245,7 +2437,10 @@
if (this.field_147481_N)
{
p_175690_2_.func_174878_a(p_175690_1_);
+ if (p_175690_2_.func_145831_w() != this)
+ p_175690_2_.func_145834_a(this); // Forge - set the world early as vanilla doesn't set it until next tick
Iterator<TileEntity> iterator1 = this.field_147484_a.iterator();
+ List<TileEntity> toInvalidate = Lists.newArrayList();
while (iterator1.hasNext())
@@ -2262,7 +2450,8 @@
{
@@ -2253,16 +2448,18 @@
if (tileentity2.func_174877_v().equals(p_175690_1_))
{
- tileentity2.func_145843_s();
+ toInvalidate.add(tileentity2); // Forge - don't call invalidate while iterating
iterator1.remove();
}
}
+ toInvalidate.forEach(TileEntity::func_145843_s);
this.field_147484_a.add(p_175690_2_);
}
else
{
@@ -671,7 +717,7 @@
this.func_175700_a(p_175690_2_);
}
}
@@ -2277,6 +2466,8 @@
@@ -2277,6 +2474,8 @@
{
tileentity2.func_145843_s();
this.field_147484_a.remove(tileentity2);
@@ -680,7 +726,7 @@
}
else
{
@@ -2289,6 +2480,7 @@
@@ -2289,6 +2488,7 @@
this.func_175726_f(p_175713_1_).func_177425_e(p_175713_1_);
}
@@ -688,7 +734,7 @@
}
public void func_147457_a(TileEntity p_147457_1_)
@@ -2315,7 +2507,7 @@
@@ -2315,7 +2515,7 @@
if (chunk1 != null && !chunk1.func_76621_g())
{
IBlockState iblockstate1 = this.func_180495_p(p_175677_1_);
@@ -697,7 +743,7 @@
}
else
{
@@ -2338,6 +2530,7 @@
@@ -2338,6 +2538,7 @@
{
this.field_72985_G = p_72891_1_;
this.field_72992_H = p_72891_2_;
@@ -705,7 +751,7 @@
}
public void func_72835_b()
@@ -2347,6 +2540,11 @@
@@ -2347,6 +2548,11 @@
protected void func_72947_a()
{
@@ -717,7 +763,7 @@
if (this.field_72986_A.func_76059_o())
{
this.field_73004_o = 1.0F;
@@ -2360,6 +2558,11 @@
@@ -2360,6 +2566,11 @@
protected void func_72979_l()
{
@@ -729,7 +775,7 @@
if (this.field_73011_w.func_191066_m())
{
if (!this.field_72995_K)
@@ -2484,6 +2687,11 @@
@@ -2484,6 +2695,11 @@
public boolean func_175670_e(BlockPos p_175670_1_, boolean p_175670_2_)
{
@@ -741,7 +787,7 @@
Biome biome = this.func_180494_b(p_175670_1_);
float f = biome.func_180626_a(p_175670_1_);
@@ -2525,6 +2733,11 @@
@@ -2525,6 +2741,11 @@
public boolean func_175708_f(BlockPos p_175708_1_, boolean p_175708_2_)
{
@@ -753,7 +799,7 @@
Biome biome = this.func_180494_b(p_175708_1_);
float f = biome.func_180626_a(p_175708_1_);
@@ -2542,7 +2755,7 @@
@@ -2542,7 +2763,7 @@
{
IBlockState iblockstate1 = this.func_180495_p(p_175708_1_);
@@ -762,7 +808,7 @@
{
return true;
}
@@ -2574,10 +2787,10 @@
@@ -2574,10 +2795,10 @@
else
{
IBlockState iblockstate1 = this.func_180495_p(p_175638_1_);
@@ -776,7 +822,7 @@
{
k2 = 1;
}
@@ -2589,7 +2802,7 @@
@@ -2589,7 +2810,7 @@
if (k2 >= 15)
{
@@ -785,7 +831,7 @@
}
else if (j2 >= 14)
{
@@ -2630,12 +2843,13 @@
@@ -2630,12 +2851,13 @@
public boolean func_180500_c(EnumSkyBlock p_180500_1_, BlockPos p_180500_2_)
{
@@ -800,7 +846,7 @@
int j2 = 0;
int k2 = 0;
this.field_72984_F.func_76320_a("getBrightness");
@@ -2673,7 +2887,7 @@
@@ -2673,7 +2895,7 @@
int l5 = MathHelper.func_76130_a(k4 - k3);
int i6 = MathHelper.func_76130_a(l4 - l3);
@@ -809,7 +855,7 @@
{
BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.func_185346_s();
@@ -2683,7 +2897,8 @@
@@ -2683,7 +2905,8 @@
int k6 = k4 + enumfacing.func_96559_d();
int l6 = l4 + enumfacing.func_82599_e();
blockpos$pooledmutableblockpos.func_181079_c(j6, k6, l6);
@@ -819,7 +865,7 @@
j5 = this.func_175642_b(p_180500_1_, blockpos$pooledmutableblockpos);
if (j5 == i5 - i7 && k2 < this.field_72994_J.length)
@@ -2725,7 +2940,7 @@
@@ -2725,7 +2948,7 @@
int j9 = Math.abs(i8 - l3);
boolean flag = k2 < this.field_72994_J.length - 6;
@@ -828,7 +874,7 @@
{
if (this.func_175642_b(p_180500_1_, blockpos2.func_177976_e()) < k8)
{
@@ -2791,10 +3006,10 @@
@@ -2791,10 +3014,10 @@
public List<Entity> func_175674_a(@Nullable Entity p_175674_1_, AxisAlignedBB p_175674_2_, @Nullable Predicate <? super Entity > p_175674_3_)
{
List<Entity> list = Lists.<Entity>newArrayList();
@@ -843,7 +889,7 @@
for (int j3 = j2; j3 <= k2; ++j3)
{
@@ -2847,10 +3062,10 @@
@@ -2847,10 +3070,10 @@
public <T extends Entity> List<T> func_175647_a(Class <? extends T > p_175647_1_, AxisAlignedBB p_175647_2_, @Nullable Predicate <? super T > p_175647_3_)
{
@@ -858,7 +904,7 @@
List<T> list = Lists.<T>newArrayList();
for (int j3 = j2; j3 < k2; ++j3)
@@ -2930,11 +3145,13 @@
@@ -2930,11 +3153,13 @@
public void func_175650_b(Collection<Entity> p_175650_1_)
{
@@ -875,7 +921,17 @@
}
}
@@ -2958,7 +3175,7 @@
@@ -2948,7 +3173,8 @@
IBlockState iblockstate1 = this.func_180495_p(p_190527_2_);
AxisAlignedBB axisalignedbb = p_190527_3_ ? null : p_190527_1_.func_176223_P().func_185890_d(this, p_190527_2_);
- if (axisalignedbb != Block.field_185506_k && !this.func_72917_a(axisalignedbb.func_186670_a(p_190527_2_), p_190527_5_))
+ if (!((p_190527_5_ instanceof EntityPlayer) || !net.minecraftforge.event.ForgeEventFactory.onBlockPlace(p_190527_5_, new net.minecraftforge.common.util.BlockSnapshot(this, p_190527_2_, p_190527_1_.func_176223_P()), p_190527_4_).isCanceled())) return false;
+ if (axisalignedbb != Block.field_185506_k && !this.func_72855_b(axisalignedbb.func_186670_a(p_190527_2_))) // Forge: Remove second parameter, we patch placer to be non-null, passing it here skips collision checks for the placer
{
return false;
}
@@ -2958,7 +3184,7 @@
}
else
{
@@ -884,7 +940,7 @@
}
}
@@ -3042,7 +3259,7 @@
@@ -3042,7 +3268,7 @@
public int func_175651_c(BlockPos p_175651_1_, EnumFacing p_175651_2_)
{
IBlockState iblockstate1 = this.func_180495_p(p_175651_1_);
@@ -893,7 +949,7 @@
}
public boolean func_175640_z(BlockPos p_175640_1_)
@@ -3208,6 +3425,8 @@
@@ -3208,6 +3434,8 @@
d2 *= ((Double)MoreObjects.firstNonNull(p_184150_11_.apply(entityplayer1), Double.valueOf(1.0D))).doubleValue();
}
@@ -902,7 +958,7 @@
if ((p_184150_9_ < 0.0D || Math.abs(entityplayer1.field_70163_u - p_184150_3_) < p_184150_9_ * p_184150_9_) && (p_184150_7_ < 0.0D || d1 < d2 * d2) && (d0 == -1.0D || d1 < d0))
{
d0 = d1;
@@ -3269,7 +3488,7 @@
@@ -3269,7 +3497,7 @@
public long func_72905_C()
{
@@ -911,7 +967,7 @@
}
public long func_82737_E()
@@ -3279,17 +3498,17 @@
@@ -3279,17 +3507,17 @@
public long func_72820_D()
{
@@ -932,7 +988,7 @@
if (!this.func_175723_af().func_177746_a(blockpos1))
{
@@ -3301,7 +3520,7 @@
@@ -3301,7 +3529,7 @@
public void func_175652_B(BlockPos p_175652_1_)
{
@@ -941,7 +997,7 @@
}
@SideOnly(Side.CLIENT)
@@ -3321,12 +3540,18 @@
@@ -3321,12 +3549,18 @@
if (!this.field_72996_f.contains(p_72897_1_))
{
@@ -960,7 +1016,7 @@
return true;
}
@@ -3428,8 +3653,7 @@
@@ -3428,8 +3662,7 @@
public boolean func_180502_D(BlockPos p_180502_1_)
{
@@ -970,7 +1026,7 @@
}
@Nullable
@@ -3490,12 +3714,12 @@
@@ -3490,12 +3723,12 @@
public int func_72800_K()
{
@@ -985,7 +1041,7 @@
}
public Random func_72843_D(int p_72843_1_, int p_72843_2_, int p_72843_3_)
@@ -3539,7 +3763,7 @@
@@ -3539,7 +3772,7 @@
@SideOnly(Side.CLIENT)
public double func_72919_O()
{
@@ -994,7 +1050,7 @@
}
public void func_175715_c(int p_175715_1_, BlockPos p_175715_2_, int p_175715_3_)
@@ -3573,7 +3797,7 @@
@@ -3573,7 +3806,7 @@
public void func_175666_e(BlockPos p_175666_1_, Block p_175666_2_)
{
@@ -1003,7 +1059,7 @@
{
BlockPos blockpos1 = p_175666_1_.func_177972_a(enumfacing);
@@ -3581,18 +3805,15 @@
@@ -3581,18 +3814,15 @@
{
IBlockState iblockstate1 = this.func_180495_p(blockpos1);
@@ -1026,7 +1082,7 @@
}
}
}
@@ -3658,6 +3879,124 @@
@@ -3658,6 +3888,124 @@
return j2 >= -128 && j2 <= 128 && k2 >= -128 && k2 <= 128;
}
@@ -164,37 +164,16 @@
public static void func_185358_q()
{
func_185354_a(0, "ocean", new BiomeOcean((new Biome.BiomeProperties("Ocean")).func_185398_c(-1.0F).func_185400_d(0.1F)));
@@ -552,6 +635,7 @@
public Class <? extends EntityLiving > field_76300_b;
public int field_76301_c;
public int field_76299_d;
+ private final java.lang.reflect.Constructor<? extends EntityLiving> ctr;
public SpawnListEntry(Class <? extends EntityLiving > p_i1970_1_, int p_i1970_2_, int p_i1970_3_, int p_i1970_4_)
{
@@ -559,12 +643,26 @@
this.field_76300_b = p_i1970_1_;
this.field_76301_c = p_i1970_3_;
this.field_76299_d = p_i1970_4_;
+
+ try
+ {
+ ctr = p_i1970_1_.getConstructor(World.class);
+ }
+ catch (NoSuchMethodException e)
+ {
+ throw new RuntimeException(e);
+ }
}
public String toString()
@@ -565,6 +648,13 @@
{
return this.field_76300_b.getSimpleName() + "*(" + this.field_76301_c + "-" + this.field_76299_d + "):" + this.field_76292_a;
}
+
+ public EntityLiving newInstance(World world) throws Exception
+ {
+ return ctr.newInstance(world);
+ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.fml.common.registry.EntityRegistry.getEntry(this.field_76300_b);
+ if (entry != null) return (EntityLiving) entry.newInstance(world);
+ return this.field_76300_b.getConstructor(World.class).newInstance(world);
+ }
}
@@ -115,7 +115,7 @@
this.field_76637_e.func_175690_a(p_177436_1_, tileentity1);
}
@@ -738,6 +736,7 @@
@@ -738,11 +736,13 @@
k = this.field_76645_j.length - 1;
}
@@ -123,7 +123,21 @@
p_76612_1_.field_70175_ag = true;
p_76612_1_.field_70176_ah = this.field_76635_g;
p_76612_1_.field_70162_ai = k;
@@ -778,7 +777,7 @@
p_76612_1_.field_70164_aj = this.field_76647_h;
this.field_76645_j[k].add(p_76612_1_);
+ this.func_76630_e(); // Forge - ensure chunks are marked to save after an entity add
}
public void func_76622_b(Entity p_76622_1_)
@@ -763,6 +763,7 @@
}
this.field_76645_j[p_76608_2_].remove(p_76608_1_);
+ this.func_76630_e(); // Forge - ensure chunks are marked to save after entity removals
}
public boolean func_177444_d(BlockPos p_177444_1_)
@@ -778,7 +779,7 @@
{
IBlockState iblockstate = this.func_177435_g(p_177422_1_);
Block block = iblockstate.func_177230_c();
@@ -132,7 +146,7 @@
}
@Nullable
@@ -786,6 +785,12 @@
@@ -786,6 +787,12 @@
{
TileEntity tileentity = this.field_150816_i.get(p_177424_1_);
@@ -145,7 +159,7 @@
if (tileentity == null)
{
if (p_177424_2_ == Chunk.EnumCreateEntityType.IMMEDIATE)
@@ -795,14 +800,9 @@
@@ -795,14 +802,9 @@
}
else if (p_177424_2_ == Chunk.EnumCreateEntityType.QUEUED)
{
@@ -161,7 +175,7 @@
return tileentity;
}
@@ -819,10 +819,11 @@
@@ -819,10 +821,11 @@
public void func_177426_a(BlockPos p_177426_1_, TileEntity p_177426_2_)
{
@@ -174,7 +188,7 @@
{
if (this.field_150816_i.containsKey(p_177426_1_))
{
@@ -854,12 +855,14 @@
@@ -854,12 +857,14 @@
for (ClassInheritanceMultiMap<Entity> classinheritancemultimap : this.field_76645_j)
{
@@ -190,7 +204,7 @@
this.field_76636_d = false;
for (TileEntity tileentity : this.field_150816_i.values())
@@ -871,6 +874,7 @@
@@ -871,6 +876,7 @@
{
this.field_76637_e.func_175681_c(classinheritancemultimap);
}
@@ -198,7 +212,7 @@
}
public void func_76630_e()
@@ -880,8 +884,8 @@
@@ -880,8 +886,8 @@
public void func_177414_a(@Nullable Entity p_177414_1_, AxisAlignedBB p_177414_2_, List<Entity> p_177414_3_, Predicate <? super Entity > p_177414_4_)
{
@@ -209,7 +223,7 @@
i = MathHelper.func_76125_a(i, 0, this.field_76645_j.length - 1);
j = MathHelper.func_76125_a(j, 0, this.field_76645_j.length - 1);
@@ -918,8 +922,8 @@
@@ -918,8 +924,8 @@
public <T extends Entity> void func_177430_a(Class <? extends T > p_177430_1_, AxisAlignedBB p_177430_2_, List<T> p_177430_3_, Predicate <? super T > p_177430_4_)
{
@@ -220,7 +234,7 @@
i = MathHelper.func_76125_a(i, 0, this.field_76645_j.length - 1);
j = MathHelper.func_76125_a(j, 0, this.field_76645_j.length - 1);
@@ -997,6 +1001,9 @@
@@ -997,6 +1003,9 @@
protected void func_186034_a(IChunkGenerator p_186034_1_)
{
@@ -230,7 +244,7 @@
if (this.func_177419_t())
{
if (p_186034_1_.func_185933_a(this, this.field_76635_g, this.field_76647_h))
@@ -1008,8 +1015,10 @@
@@ -1008,8 +1017,10 @@
{
this.func_150809_p();
p_186034_1_.func_185931_b(this.field_76635_g, this.field_76647_h);
@@ -241,7 +255,7 @@
}
public BlockPos func_177440_h(BlockPos p_177440_1_)
@@ -1064,7 +1073,7 @@
@@ -1064,7 +1075,7 @@
{
BlockPos blockpos = this.field_177447_w.poll();
@@ -250,7 +264,7 @@
{
TileEntity tileentity = this.func_177422_i(blockpos);
this.field_76637_e.func_175690_a(blockpos, tileentity);
@@ -1128,6 +1137,13 @@
@@ -1128,6 +1139,13 @@
@SideOnly(Side.CLIENT)
public void func_186033_a(PacketBuffer p_186033_1_, int p_186033_2_, boolean p_186033_3_)
{
@@ -264,7 +278,7 @@
boolean flag = this.field_76637_e.field_73011_w.func_191066_m();
for (int i = 0; i < this.field_76652_q.length; ++i)
@@ -1176,10 +1192,16 @@
@@ -1176,10 +1194,16 @@
this.field_76646_k = true;
this.func_76590_a();
@@ -281,7 +295,21 @@
}
public Biome func_177411_a(BlockPos p_177411_1_, BiomeProvider p_177411_2_)
@@ -1244,13 +1266,13 @@
@@ -1190,7 +1214,12 @@
if (k == 255)
{
- Biome biome = p_177411_2_.func_180300_a(p_177411_1_, Biomes.field_76772_c);
+ // Forge: checking for client ensures that biomes are only generated on integrated server
+ // in singleplayer. Generating biomes on the client may corrupt the biome ID arrays on
+ // the server while they are being generated because IntCache can't be thread safe,
+ // so client and server may end up filling the same array.
+ // This is not necessary in 1.13 and newer versions.
+ Biome biome = field_76637_e.field_72995_K ? Biomes.field_76772_c : p_177411_2_.func_180300_a(p_177411_1_, Biomes.field_76772_c);
k = Biome.func_185362_a(biome);
this.field_76651_r[j << 4 | i] = (byte)(k & 255);
}
@@ -1244,13 +1273,13 @@
BlockPos blockpos1 = blockpos.func_177982_a(k, (j << 4) + i1, l);
boolean flag = i1 == 0 || i1 == 15 || k == 0 || k == 15 || l == 0 || l == 15;
@@ -297,7 +325,7 @@
{
this.field_76637_e.func_175664_x(blockpos2);
}
@@ -1381,7 +1403,7 @@
@@ -1381,7 +1410,7 @@
{
blockpos$mutableblockpos.func_181079_c(blockpos$mutableblockpos.func_177958_n(), l, blockpos$mutableblockpos.func_177952_p());
@@ -306,7 +334,7 @@
{
this.field_76637_e.func_175664_x(blockpos$mutableblockpos);
}
@@ -1420,6 +1442,7 @@
@@ -1420,6 +1449,7 @@
else
{
System.arraycopy(p_177420_1_, 0, this.field_76634_f, 0, this.field_76634_f.length);
@@ -314,7 +342,7 @@
}
}
@@ -1489,4 +1512,55 @@
@@ -1489,4 +1519,55 @@
QUEUED,
CHECK;
}
@@ -32,8 +32,11 @@
ChunkPos chunkpos = new ChunkPos(p_75815_2_, p_75815_3_);
NBTTagCompound nbttagcompound = this.field_75828_a.get(chunkpos);
@@ -67,7 +89,7 @@
@@ -65,9 +87,10 @@
}
nbttagcompound = this.field_193416_e.func_188257_a(FixTypes.CHUNK, CompressedStreamTools.func_74794_a(datainputstream));
+ datainputstream.close(); // Forge: close stream after use
}
- return this.func_75822_a(p_75815_1_, p_75815_2_, p_75815_3_, nbttagcompound);
@@ -41,7 +44,7 @@
}
public boolean func_191063_a(int p_191063_1_, int p_191063_2_)
@@ -80,6 +102,13 @@
@@ -80,6 +103,13 @@
@Nullable
protected Chunk func_75822_a(World p_75822_1_, int p_75822_2_, int p_75822_3_, NBTTagCompound p_75822_4_)
{
@@ -55,7 +58,7 @@
if (!p_75822_4_.func_150297_b("Level", 10))
{
field_151505_a.error("Chunk file at {},{} is missing level data, skipping", Integer.valueOf(p_75822_2_), Integer.valueOf(p_75822_3_));
@@ -103,10 +132,29 @@
@@ -103,10 +133,29 @@
field_151505_a.error("Chunk file at {},{} is in the wrong location; relocating. (Expected {}, {}, got {}, {})", Integer.valueOf(p_75822_2_), Integer.valueOf(p_75822_3_), Integer.valueOf(p_75822_2_), Integer.valueOf(p_75822_3_), Integer.valueOf(chunk.field_76635_g), Integer.valueOf(chunk.field_76647_h));
nbttagcompound.func_74768_a("xPos", p_75822_2_);
nbttagcompound.func_74768_a("zPos", p_75822_3_);
@@ -86,7 +89,7 @@
}
}
}
@@ -121,7 +169,10 @@
@@ -121,7 +170,10 @@
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
nbttagcompound.func_74782_a("Level", nbttagcompound1);
nbttagcompound.func_74768_a("DataVersion", 1343);
@@ -97,7 +100,7 @@
this.func_75824_a(p_75816_2_.func_76632_l(), nbttagcompound);
}
catch (Exception exception)
@@ -305,11 +356,19 @@
@@ -305,11 +357,19 @@
{
NBTTagCompound nbttagcompound2 = new NBTTagCompound();
@@ -117,7 +120,7 @@
}
}
@@ -318,8 +377,16 @@
@@ -318,8 +378,16 @@
for (TileEntity tileentity : p_75820_1_.func_177434_r().values())
{
@@ -134,7 +137,7 @@
}
p_75820_3_.func_74782_a("TileEntities", nbttaglist2);
@@ -345,6 +412,18 @@
@@ -345,6 +413,18 @@
p_75820_3_.func_74782_a("TileTicks", nbttaglist3);
}
@@ -153,7 +156,7 @@
}
private Chunk func_75823_a(World p_75823_1_, NBTTagCompound p_75823_2_)
@@ -388,6 +467,16 @@
@@ -388,6 +468,16 @@
chunk.func_76616_a(p_75823_2_.func_74770_j("Biomes"));
}
@@ -170,7 +173,7 @@
NBTTagList nbttaglist1 = p_75823_2_.func_150295_c("Entities", 10);
for (int j1 = 0; j1 < nbttaglist1.func_74745_c(); ++j1)
@@ -431,8 +520,6 @@
@@ -431,8 +521,6 @@
p_75823_1_.func_180497_b(new BlockPos(nbttagcompound3.func_74762_e("x"), nbttagcompound3.func_74762_e("y"), nbttagcompound3.func_74762_e("z")), block, nbttagcompound3.func_74762_e("t"), nbttagcompound3.func_74762_e("p"));
}
}
@@ -179,7 +182,7 @@
}
@Nullable
@@ -563,4 +650,9 @@
@@ -563,4 +651,9 @@
return entity;
}
}
@@ -1,6 +1,44 @@
--- ../src-base/minecraft/net/minecraft/world/chunk/storage/RegionFile.java
+++ ../src-work/minecraft/net/minecraft/world/chunk/storage/RegionFile.java
@@ -95,6 +95,12 @@
@@ -19,6 +19,9 @@
public class RegionFile
{
+ // Minecraft is limited to 256 sections per chunk. So 1MB. This can easily be override.
+ // So we extend this to use the REAL size when the count is maxed by seeking to that section and reading the length.
+ private static final boolean FORGE_ENABLE_EXTENDED_SAVE = Boolean.parseBoolean(System.getProperty("forge.enableExtendedSave", "true"));
private static final byte[] field_76720_a = new byte[4096];
private final File field_76718_b;
private RandomAccessFile field_76719_c;
@@ -74,13 +77,25 @@
int k = this.field_76719_c.readInt();
this.field_76716_d[j1] = k;
- if (k != 0 && (k >> 8) + (k & 255) <= this.field_76714_f.size())
+ int length = k & 255;
+ if (length == 255)
{
- for (int l = 0; l < (k & 255); ++l)
+ if ((k >> 8) <= this.field_76714_f.size())
+ { // We're maxed out, so we need to read the proper length from the section
+ this.field_76719_c.seek((k >> 8) * 4096);
+ length = (this.field_76719_c.readInt() + 4)/ 4096 + 1;
+ this.field_76719_c.seek(j1 * 4 + 4); //Go back to where we were
+ }
+ }
+ if (k != 0 && (k >> 8) + length <= this.field_76714_f.size())
+ {
+ for (int l = 0; l < length; ++l)
{
this.field_76714_f.set((k >> 8) + l, Boolean.valueOf(false));
}
}
+ else if (length > 0)
+ net.minecraftforge.fml.common.FMLLog.log.warn("Invalid chunk: ({}, {}) Offset: {} Length: {} runs off end file. {}", j1 % 32, (int)(j1 / 32), k >> 8, length, p_i2001_1_);
}
for (int k1 = 0; k1 < 1024; ++k1)
@@ -95,6 +110,12 @@
}
}
@@ -13,3 +51,65 @@
@Nullable
public synchronized DataInputStream func_76704_a(int p_76704_1_, int p_76704_2_)
@@ -117,6 +138,11 @@
{
int j = i >> 8;
int k = i & 255;
+ if (k == 255)
+ {
+ this.field_76719_c.seek(j * 4096);
+ k = (this.field_76719_c.readInt() + 4) / 4096 + 1;
+ }
if (j + k > this.field_76714_f.size())
{
@@ -129,10 +155,12 @@
if (l > 4096 * k)
{
+ net.minecraftforge.fml.common.FMLLog.log.warn("Invalid chunk: ({}, {}) Offset: {} Invalid Size: {}>{} {}", p_76704_1_, p_76704_2_, j, l, k * 4096, field_76718_b);
return null;
}
else if (l <= 0)
{
+ net.minecraftforge.fml.common.FMLLog.log.warn("Invalid chunk: ({}, {}) Offset: {} Invalid Size: {} {}", p_76704_1_, p_76704_2_, j, l, field_76718_b);
return null;
}
else
@@ -179,11 +207,17 @@
int i = this.func_76707_e(p_76706_1_, p_76706_2_);
int j = i >> 8;
int k = i & 255;
+ if (k == 255)
+ {
+ this.field_76719_c.seek(j * 4096);
+ k = (this.field_76719_c.readInt() + 4) / 4096 + 1;
+ }
int l = (p_76706_4_ + 5) / 4096 + 1;
if (l >= 256)
{
- return;
+ if (!FORGE_ENABLE_EXTENDED_SAVE) return;
+ net.minecraftforge.fml.common.FMLLog.log.warn("Large Chunk Detected: ({}, {}) Size: {} {}", p_76706_1_, p_76706_2_, l, field_76718_b);
}
if (j != 0 && k == l)
@@ -231,7 +265,7 @@
if (j1 >= l)
{
j = l1;
- this.func_76711_a(p_76706_1_, p_76706_2_, l1 << 8 | l);
+ this.func_76711_a(p_76706_1_, p_76706_2_, l1 << 8 | (l > 255 ? 255 : l));
for (int j2 = 0; j2 < l; ++j2)
{
@@ -253,7 +287,7 @@
this.field_76715_g += 4096 * l;
this.func_76712_a(j, p_76706_3_, p_76706_4_);
- this.func_76711_a(p_76706_1_, p_76706_2_, j << 8 | l);
+ this.func_76711_a(p_76706_1_, p_76706_2_, j << 8 | (l > 255 ? 255 : l));
}
}
@@ -52,24 +52,26 @@
}
}
@@ -1770,7 +1780,6 @@
@@ -1770,7 +1780,7 @@
EntityZombieVillager entityzombievillager = new EntityZombieVillager(p_74893_1_);
entityzombievillager.func_70012_b((double)j + 0.5D, (double)k, (double)l + 0.5D, 0.0F, 0.0F);
entityzombievillager.func_180482_a(p_74893_1_.func_175649_E(new BlockPos(entityzombievillager)), (IEntityLivingData)null);
- entityzombievillager.func_190733_a(this.func_180779_c(i, 0));
+ entityzombievillager.setForgeProfession(this.chooseForgeProfession(i, net.minecraftforge.fml.common.registry.VillagerRegistry.FARMER));
entityzombievillager.func_110163_bv();
p_74893_1_.func_72838_d(entityzombievillager);
}
@@ -1778,7 +1787,7 @@
@@ -1778,7 +1788,8 @@
{
EntityVillager entityvillager = new EntityVillager(p_74893_1_);
entityvillager.func_70012_b((double)j + 0.5D, (double)k, (double)l + 0.5D, 0.0F, 0.0F);
- entityvillager.func_70938_b(this.func_180779_c(i, p_74893_1_.field_73012_v.nextInt(6)));
+ net.minecraftforge.fml.common.registry.VillagerRegistry.setRandomProfession(entityvillager, p_74893_1_.field_73012_v);
+ entityvillager.setProfession(this.chooseForgeProfession(i, entityvillager.getProfessionForge()));
entityvillager.func_190672_a(p_74893_1_.func_175649_E(new BlockPos(entityvillager)), (IEntityLivingData)null, false);
p_74893_1_.func_72838_d(entityvillager);
}
@@ -1786,13 +1795,21 @@
@@ -1786,13 +1797,21 @@
}
}
@@ -25,9 +25,16 @@ import static net.minecraftforge.common.ForgeVersion.Status.BETA_OUTDATED;
import java.awt.image.BufferedImage;
import java.io.File;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Deque;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import javax.annotation.Nonnull;
@@ -55,6 +62,8 @@ import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.client.renderer.RenderItem;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.BlockFaceUV;
import net.minecraft.client.renderer.block.model.IBakedModel;
@@ -69,8 +78,10 @@ import net.minecraft.client.renderer.color.ItemColors;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.texture.TextureUtil;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
import net.minecraft.client.renderer.vertex.VertexFormatElement.EnumUsage;
@@ -123,6 +134,7 @@ import net.minecraftforge.client.model.animation.Animation;
import net.minecraftforge.client.resource.IResourceType;
import net.minecraftforge.client.resource.SelectiveReloadStateHandler;
import net.minecraftforge.client.resource.VanillaResourceType;
import net.minecraftforge.client.model.pipeline.QuadGatheringTransformer;
import net.minecraftforge.common.ForgeModContainer;
import net.minecraftforge.common.ForgeVersion;
import net.minecraftforge.common.ForgeVersion.Status;
@@ -135,12 +147,15 @@ import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.FMLLog;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.logging.log4j.core.async.ThreadNameCachingStrategy;
import org.apache.logging.log4j.core.impl.ReusableLogEventFactory;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import java.util.function.Predicate;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
public class ForgeHooksClient
@@ -476,6 +491,7 @@ public class ForgeHooksClient
case GENERIC:
GL20.glEnableVertexAttribArray(attr.getIndex());
GL20.glVertexAttribPointer(attr.getIndex(), count, constant, false, stride, buffer);
break;
default:
FMLLog.log.fatal("Unimplemented vanilla attribute upload: {}", attrType.getDisplayName());
}
@@ -506,6 +522,7 @@ public class ForgeHooksClient
break;
case GENERIC:
GL20.glDisableVertexAttribArray(attr.getIndex());
break;
default:
FMLLog.log.fatal("Unimplemented vanilla attribute upload: {}", attrType.getDisplayName());
}
@@ -540,9 +557,10 @@ public class ForgeHooksClient
VertexFormat format = quad.getFormat();
int size = format.getIntegerSize();
int offset = format.getColorOffset() / 4; // assumes that color is aligned
boolean hasColor = format.hasColor();
for(int i = 0; i < 4; i++)
{
int vc = quad.getVertexData()[offset + size * i];
int vc = hasColor ? quad.getVertexData()[offset + size * i] : 0xFFFFFFFF;
float vcr = vc & 0xFF;
float vcg = (vc >>> 8) & 0xFF;
float vcb = (vc >>> 16) & 0xFF;
@@ -578,6 +596,170 @@ public class ForgeHooksClient
{
tileItemMap.put(Pair.of(item, metadata), TileClass);
}
private static class LightGatheringTransformer extends QuadGatheringTransformer {
private static final VertexFormat FORMAT = new VertexFormat().addElement(DefaultVertexFormats.TEX_2F).addElement(DefaultVertexFormats.TEX_2S);
int blockLight, skyLight;
{ setVertexFormat(FORMAT); }
boolean hasLighting()
{
return dataLength[1] >= 2;
}
@Override
protected void processQuad()
{
// Reset light data
blockLight = 0;
skyLight = 0;
// Compute average light for all 4 vertices
for (int i = 0; i < 4; i++)
{
blockLight += (int) ((quadData[1][i][0] * 0xFFFF) / 0x20);
skyLight += (int) ((quadData[1][i][1] * 0xFFFF) / 0x20);
}
// Values must be multiplied by 16, divided by 4 for average => x4
blockLight *= 4;
skyLight *= 4;
}
// Dummy overrides
@Override
public void setQuadTint(int tint) {}
@Override
public void setQuadOrientation(EnumFacing orientation) {}
@Override
public void setApplyDiffuseLighting(boolean diffuse) {}
@Override
public void setTexture(TextureAtlasSprite texture) {}
}
private static final LightGatheringTransformer lightGatherer = new LightGatheringTransformer();
public static void renderLitItem(RenderItem ri, IBakedModel model, int color, ItemStack stack)
{
List<BakedQuad> allquads = new ArrayList<>();
for (EnumFacing enumfacing : EnumFacing.VALUES)
{
allquads.addAll(model.getQuads(null, enumfacing, 0));
}
allquads.addAll(model.getQuads(null, null, 0));
if (allquads.isEmpty()) return;
// Current list of consecutive quads with the same lighting
List<BakedQuad> segment = new ArrayList<>();
// Lighting of the current segment
int segmentBlockLight = 0;
int segmentSkyLight = 0;
// Diffuse lighting state
boolean segmentShading = true;
// State changed by the current segment
boolean segmentLightingDirty = false;
boolean segmentShadingDirty = false;
// If the current segment contains lighting data
boolean hasLighting = false;
for (int i = 0; i < allquads.size(); i++)
{
BakedQuad q = allquads.get(i);
// Lighting of the current quad
int bl = 0;
int sl = 0;
// Fail-fast on ITEM, as it cannot have light data
if (q.getFormat() != DefaultVertexFormats.ITEM && q.getFormat().hasUvOffset(1))
{
q.pipe(lightGatherer);
if (lightGatherer.hasLighting())
{
bl = lightGatherer.blockLight;
sl = lightGatherer.skyLight;
}
}
boolean shade = q.shouldApplyDiffuseLighting();
boolean lightingDirty = segmentBlockLight != bl || segmentSkyLight != sl;
boolean shadeDirty = shade != segmentShading;
// If lighting or color data has changed, draw the segment and flush it
if (lightingDirty || shadeDirty)
{
if (i > 0) // Make sure this isn't the first quad being processed
{
drawSegment(ri, color, stack, segment, segmentBlockLight, segmentSkyLight, segmentShading, segmentLightingDirty && (hasLighting || segment.size() < i), segmentShadingDirty);
}
segmentBlockLight = bl;
segmentSkyLight = sl;
segmentShading = shade;
segmentLightingDirty = lightingDirty;
segmentShadingDirty = shadeDirty;
hasLighting = segmentBlockLight > 0 || segmentSkyLight > 0 || !segmentShading;
}
segment.add(q);
}
drawSegment(ri, color, stack, segment, segmentBlockLight, segmentSkyLight, segmentShading, segmentLightingDirty && (hasLighting || segment.size() < allquads.size()), segmentShadingDirty);
// Clean up render state if necessary
if (hasLighting)
{
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, OpenGlHelper.lastBrightnessX, OpenGlHelper.lastBrightnessY);
GlStateManager.enableLighting();
}
}
private static void drawSegment(RenderItem ri, int baseColor, ItemStack stack, List<BakedQuad> segment, int bl, int sl, boolean shade, boolean updateLighting, boolean updateShading)
{
BufferBuilder bufferbuilder = Tessellator.getInstance().getBuffer();
bufferbuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.ITEM);
float lastBl = OpenGlHelper.lastBrightnessX;
float lastSl = OpenGlHelper.lastBrightnessY;
if (updateShading)
{
if (shade)
{
// (Re-)enable lighting for normal look with shading
GlStateManager.enableLighting();
}
else
{
// Disable lighting to simulate a lack of diffuse lighting
GlStateManager.disableLighting();
}
}
if (updateLighting)
{
// Force lightmap coords to simulate synthetic lighting
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, Math.max(bl, lastBl), Math.max(sl, lastSl));
}
ri.renderQuads(bufferbuilder, segment, baseColor, stack);
Tessellator.getInstance().draw();
// Preserve this as it represents the "world" lighting
OpenGlHelper.lastBrightnessX = lastBl;
OpenGlHelper.lastBrightnessY = lastSl;
segment.clear();
}
/**
* internal, relies on fixed format of FaceBakery
@@ -781,4 +963,23 @@ public class ForgeHooksClient
return true;
}
// Resets cached thread fields in ThreadNameCachingStrategy and ReusableLogEventFactory to be repopulated during their next access.
// This serves a workaround for no built-in method of triggering this type of refresh as brought up by LOG4J2-2178.
public static void invalidateLog4jThreadCache()
{
try
{
Field nameField = ThreadNameCachingStrategy.class.getDeclaredField("THREADLOCAL_NAME");
Field logEventField = ReusableLogEventFactory.class.getDeclaredField("mutableLogEventThreadLocal");
nameField.setAccessible(true);
logEventField.setAccessible(true);
((ThreadLocal<?>) nameField.get(null)).set(null);
((ThreadLocal<?>) logEventField.get(null)).set(null);
}
catch (ReflectiveOperationException | NoClassDefFoundError e)
{
FMLLog.log.error("Unable to invalidate log4j thread cache, thread fields in logs may be inaccurate", e);
}
}
}
@@ -19,12 +19,22 @@
package net.minecraftforge.client;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.BitSet;
import java.util.HashMap;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import javax.annotation.Nonnull;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureUtil;
import net.minecraft.client.resources.IResource;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.ChunkCache;
import net.minecraft.world.World;
@@ -124,4 +134,23 @@ public class MinecraftForgeClient
regionCache.invalidateAll();
regionCache.cleanUp();
}
private static HashMap<ResourceLocation, Supplier<BufferedImage>> bufferedImageSuppliers = new HashMap<ResourceLocation, Supplier<BufferedImage>>();
public static void registerImageLayerSupplier(ResourceLocation resourceLocation, Supplier<BufferedImage> supplier)
{
bufferedImageSuppliers.put(resourceLocation, supplier);
}
@Nonnull
public static BufferedImage getImageLayer(ResourceLocation resourceLocation, IResourceManager resourceManager) throws IOException
{
Supplier<BufferedImage> supplier = bufferedImageSuppliers.get(resourceLocation);
if (supplier != null)
return supplier.get();
try (IResource iresource1 = resourceManager.getResource(resourceLocation))
{
return TextureUtil.readBufferedImage(iresource1.getInputStream());
}
}
}
@@ -44,13 +44,20 @@ public class BakedItemModel implements IBakedModel
protected final ItemOverrideList overrides;
protected final IBakedModel guiModel;
/** @deprecated use {@link #BakedItemModel(ImmutableList, TextureAtlasSprite, ImmutableMap, ItemOverrideList, boolean)} */
@Deprecated // TODO: remove
public BakedItemModel(ImmutableList<BakedQuad> quads, TextureAtlasSprite particle, ImmutableMap<TransformType, TRSRTransformation> transforms, ItemOverrideList overrides)
{
this(quads, particle, transforms, overrides, true);
}
public BakedItemModel(ImmutableList<BakedQuad> quads, TextureAtlasSprite particle, ImmutableMap<TransformType, TRSRTransformation> transforms, ItemOverrideList overrides, boolean untransformed)
{
this.quads = quads;
this.particle = particle;
this.transforms = transforms;
this.overrides = overrides;
this.guiModel = hasGuiIdentity(transforms) ? new BakedGuiItemModel<>(this) : null;
this.guiModel = untransformed && hasGuiIdentity(transforms) ? new BakedGuiItemModel<>(this) : null;
}
private static boolean hasGuiIdentity(ImmutableMap<TransformType, TRSRTransformation> transforms)
@@ -28,6 +28,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import net.minecraft.client.renderer.block.model.ModelBlockDefinition;
import net.minecraft.client.renderer.block.model.ModelRotation;
@@ -90,14 +91,12 @@ public class BlockStateLoader
for (ForgeBlockStateV1.Variant var : entry.getValue())
{
boolean uvLock = var.getUvLock().orElse(false);
boolean smooth = var.getSmooth().orElse(true);
boolean gui3d = var.getGui3d().orElse(true);
int weight = var.getWeight().orElse(1);
if (var.getModel() != null && var.getSubmodels().size() == 0 && var.getTextures().size() == 0 && var.getCustomData().size() == 0 && var.getState().orElse(ModelRotation.X0_Y0) instanceof ModelRotation)
if (var.isVanillaCompatible())
mcVars.add(new Variant(var.getModel(), (ModelRotation)var.getState().orElse(ModelRotation.X0_Y0), uvLock, weight));
else
mcVars.add(new ForgeVariant(location, var.getModel(), var.getState().orElse(TRSRTransformation.identity()), uvLock, smooth, gui3d, weight, var.getTextures(), var.getOnlyPartsVariant(), var.getCustomData()));
mcVars.add(new ForgeVariant(location, var.getModel(), var.getState().orElse(TRSRTransformation.identity()), uvLock, var.getSmooth(), var.getGui3d(), weight, var.getTextures(), var.getOnlyPartsVariant(), var.getCustomData()));
}
variants.put(entry.getKey(), new VariantList(mcVars));
}
@@ -156,11 +155,11 @@ public class BlockStateLoader
private final ImmutableMap<String, String> textures;
private final ImmutableMap<String, SubModel> parts;
private final ImmutableMap<String, String> customData;
private final boolean smooth;
private final boolean gui3d;
private final Optional<Boolean> smooth;
private final Optional<Boolean> gui3d;
private final IModelState state;
public ForgeVariant(ResourceLocation blockstateLocation, @Nullable ResourceLocation model, IModelState state, boolean uvLock, boolean smooth, boolean gui3d, int weight, ImmutableMap<String, String> textures, ImmutableMap<String, SubModel> parts, ImmutableMap<String, String> customData)
ForgeVariant(ResourceLocation blockstateLocation, @Nullable ResourceLocation model, IModelState state, boolean uvLock, Optional<Boolean> smooth, Optional<Boolean> gui3d, int weight, ImmutableMap<String, String> textures, ImmutableMap<String, SubModel> parts, ImmutableMap<String, String> customData)
{
super(model == null ? new ResourceLocation("builtin/missing") : model, state instanceof ModelRotation ? (ModelRotation)state : ModelRotation.X0_Y0, uvLock, weight);
this.blockstateLocation = blockstateLocation;
@@ -172,12 +171,12 @@ public class BlockStateLoader
this.gui3d = gui3d;
}
private IModel runModelHooks(IModel base, boolean smooth, boolean gui3d, boolean uvlock, ImmutableMap<String, String> textureMap, ImmutableMap<String, String> customData)
private IModel runModelHooks(IModel base, Optional<Boolean> smooth, Optional<Boolean> gui3d, boolean uvlock, ImmutableMap<String, String> textureMap, ImmutableMap<String, String> customData)
{
base = base.process(customData);
base = base.retexture(textureMap);
base = base.smoothLighting(smooth);
base = base.gui3d(gui3d);
base = smooth.map(base::smoothLighting).orElse(base);
base = gui3d.map(base::gui3d).orElse(base);
base = base.uvlock(uvlock);
return base;
}
@@ -217,7 +216,7 @@ public class BlockStateLoader
model = ModelLoaderRegistry.getModelOrLogError(modelLocation, "Unable to load block sub-model: \'" + modelLocation);
}
models.put(entry.getKey(), Pair.of(runModelHooks(model, part.smooth, part.gui3d, part.uvLock, part.getTextures(), part.getCustomData()), part.getState()));
models.put(entry.getKey(), Pair.of(runModelHooks(model, Optional.of(part.smooth), Optional.of(part.gui3d), part.uvLock, part.getTextures(), part.getCustomData()), part.getState()));
}
return new MultiModel(getModelLocation(), hasBase ? base : null, models.build());
@@ -32,6 +32,7 @@ import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
import net.minecraft.client.renderer.block.model.ItemOverrideList;
import net.minecraft.client.renderer.block.model.ModelBlock;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.util.EnumFacing;
@@ -95,6 +96,12 @@ final class FancyMissingModel implements IModel
return ImmutableList.of(font2);
}
@Override
public Optional<ModelBlock> asVanillaModel()
{
return missingModel.asVanillaModel();
}
@Override
public IBakedModel bake(IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter)
{
@@ -385,6 +385,11 @@ public class ForgeBlockStateV1 extends Marker
return output;
}
boolean isVanillaCompatible()
{
return model != null && submodels.isEmpty() && textures.isEmpty() && customData.isEmpty() && !smooth.isPresent() && !gui3d.isPresent() && state.orElse(ModelRotation.X0_Y0) instanceof ModelRotation;
}
protected SubModel asGenericSubModel()
{
return new SubModel(state.orElse(TRSRTransformation.identity()), uvLock.orElse(false), smooth.orElse(true), gui3d.orElse(true), getTextures(), model, getCustomData());
@@ -451,77 +456,6 @@ public class ForgeBlockStateV1 extends Marker
throw new UnsupportedOperationException("Forge BlockStateLoader V1 does not support nested submodels.");
}
private static TRSRTransformation get(float tx, float ty, float tz, float ax, float ay, float az, float s)
{
return TRSRTransformation.blockCenterToCorner(new TRSRTransformation(
new Vector3f(tx / 16, ty / 16, tz / 16),
TRSRTransformation.quatFromXYZDegrees(new Vector3f(ax, ay, az)),
new Vector3f(s, s, s),
null));
}
private static final TRSRTransformation flipX = new TRSRTransformation(null, null, new Vector3f(-1, 1, 1), null);
private static TRSRTransformation leftify(TRSRTransformation transform)
{
return TRSRTransformation.blockCenterToCorner(flipX.compose(TRSRTransformation.blockCornerToCenter(transform)).compose(flipX));
}
// Note: these strings might change to a full-blown resource locations in the future, and move from here to some json somewhere
// TODO: vanilla now includes from parent, deprecate?
private static final ImmutableMap<String, IModelState> transforms;
static
{
ImmutableMap.Builder<String, IModelState> builder = ImmutableMap.builder();
builder.put("identity", TRSRTransformation.identity());
// block/block
{
EnumMap<TransformType, TRSRTransformation> map = new EnumMap<>(TransformType.class);
TRSRTransformation thirdperson = get(0, 2.5f, 0, 75, 45, 0, 0.375f);
map.put(TransformType.GUI, get(0, 0, 0, 30, 225, 0, 0.625f));
map.put(TransformType.GROUND, get(0, 3, 0, 0, 0, 0, 0.25f));
map.put(TransformType.FIXED, get(0, 0, 0, 0, 0, 0, 0.5f));
map.put(TransformType.THIRD_PERSON_RIGHT_HAND, thirdperson);
map.put(TransformType.THIRD_PERSON_LEFT_HAND, leftify(thirdperson));
map.put(TransformType.FIRST_PERSON_RIGHT_HAND, get(0, 0, 0, 0, 45, 0, 0.4f));
map.put(TransformType.FIRST_PERSON_LEFT_HAND, get(0, 0, 0, 0, 225, 0, 0.4f));
builder.put("forge:default-block", new SimpleModelState(ImmutableMap.copyOf(map)));
}
// item/generated
{
EnumMap<TransformType, TRSRTransformation> map = new EnumMap<>(TransformType.class);
TRSRTransformation thirdperson = get(0, 3, 1, 0, 0, 0, 0.55f);
TRSRTransformation firstperson = get(1.13f, 3.2f, 1.13f, 0, -90, 25, 0.68f);
map.put(TransformType.GROUND, get(0, 2, 0, 0, 0, 0, 0.5f));
map.put(TransformType.HEAD, get(0, 13, 7, 0, 180, 0, 1));
map.put(TransformType.THIRD_PERSON_RIGHT_HAND, thirdperson);
map.put(TransformType.THIRD_PERSON_LEFT_HAND, leftify(thirdperson));
map.put(TransformType.FIRST_PERSON_RIGHT_HAND, firstperson);
map.put(TransformType.FIRST_PERSON_LEFT_HAND, leftify(firstperson));
map.put(TransformType.FIXED, get(0, 0, 0, 0, 180, 0, 1));
builder.put("forge:default-item", new SimpleModelState(ImmutableMap.copyOf(map)));
}
// item/handheld
{
EnumMap<TransformType, TRSRTransformation> map = new EnumMap<>(TransformType.class);
map.put(TransformType.GROUND, get(0, 2, 0, 0, 0, 0, 0.5f));
map.put(TransformType.HEAD, get(0, 13, 7, 0, 180, 0, 1));
map.put(TransformType.THIRD_PERSON_RIGHT_HAND, get(0, 4, 0.5f, 0, -90, 55, 0.85f));
map.put(TransformType.THIRD_PERSON_LEFT_HAND, get(0, 4, 0.5f, 0, 90, -55, 0.85f));
map.put(TransformType.FIRST_PERSON_RIGHT_HAND, get(1.13f, 3.2f, 1.13f, 0, -90, 25, 0.68f));
map.put(TransformType.FIRST_PERSON_LEFT_HAND, get(1.13f, 3.2f, 1.13f, 0, 90, -25, 0.68f));
map.put(TransformType.FIXED, get(0, 0, 0, 0, 180, 0, 1));
builder.put("forge:default-tool", new SimpleModelState(ImmutableMap.copyOf(map)));
}
transforms = builder.build();
}
@Override
public ForgeBlockStateV1.Variant deserialize(JsonElement element, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
{
@@ -562,7 +496,7 @@ public class ForgeBlockStateV1 extends Marker
if (json.get("transform").isJsonPrimitive() && json.get("transform").getAsJsonPrimitive().isString())
{
String transform = json.get("transform").getAsString();
ret.state = Optional.ofNullable(transforms.get(transform));
ret.state = Transforms.get(transform);
if (!ret.state.isPresent())
{
throw new JsonParseException("transform: unknown default string: " + transform);
@@ -962,4 +896,81 @@ public class ForgeBlockStateV1 extends Marker
else throw new JsonParseException("Rotation: expected array or object, got: " + e);
}
}
public static class Transforms
{
public static TRSRTransformation convert(float tx, float ty, float tz, float ax, float ay, float az, float s)
{
return convert(tx, ty, tz, ax, ay, az, s, s, s);
}
public static TRSRTransformation convert(float tx, float ty, float tz, float ax, float ay, float az, float sx, float sy, float sz)
{
return TRSRTransformation.blockCenterToCorner(new TRSRTransformation(
new Vector3f(tx / 16, ty / 16, tz / 16),
TRSRTransformation.quatFromXYZDegrees(new Vector3f(ax, ay, az)),
new Vector3f(sx, sy, sz),
null
));
}
private static final TRSRTransformation flipX = new TRSRTransformation(null, null, new Vector3f(-1, 1, 1), null);
public static TRSRTransformation leftify(TRSRTransformation transform)
{
return TRSRTransformation.blockCenterToCorner(flipX.compose(TRSRTransformation.blockCornerToCenter(transform)).compose(flipX));
}
public static Optional<IModelState> get(String name)
{
return Optional.ofNullable(transforms.get(name));
}
// Note: these strings might change to a full-blown resource locations in the future, and move from here to some json somewhere
// TODO: vanilla now includes from parent, deprecate?
private static final ImmutableMap<String, IModelState> transforms;
static
{
ImmutableMap.Builder<String, IModelState> builder = ImmutableMap.builder();
builder.put("identity", TRSRTransformation.identity());
// block/block
EnumMap<TransformType, TRSRTransformation> block = new EnumMap<>(TransformType.class);
TRSRTransformation thirdPersonBlock = convert(0, 2.5f, 0, 75, 45, 0, 0.375f);
block.put(TransformType.GUI, convert(0, 0, 0, 30, 225, 0, 0.625f));
block.put(TransformType.GROUND, convert(0, 3, 0, 0, 0, 0, 0.25f));
block.put(TransformType.FIXED, convert(0, 0, 0, 0, 0, 0, 0.5f));
block.put(TransformType.THIRD_PERSON_RIGHT_HAND, thirdPersonBlock);
block.put(TransformType.THIRD_PERSON_LEFT_HAND, leftify(thirdPersonBlock));
block.put(TransformType.FIRST_PERSON_RIGHT_HAND, convert(0, 0, 0, 0, 45, 0, 0.4f));
block.put(TransformType.FIRST_PERSON_LEFT_HAND, convert(0, 0, 0, 0, 225, 0, 0.4f));
builder.put("forge:default-block", new SimpleModelState(ImmutableMap.copyOf(block)));
// item/generated
EnumMap<TransformType, TRSRTransformation> item = new EnumMap<>(TransformType.class);
TRSRTransformation thirdPersonItem = convert(0, 3, 1, 0, 0, 0, 0.55f);
TRSRTransformation firstPersonItem = convert(1.13f, 3.2f, 1.13f, 0, -90, 25, 0.68f);
item.put(TransformType.GROUND, convert(0, 2, 0, 0, 0, 0, 0.5f));
item.put(TransformType.HEAD, convert(0, 13, 7, 0, 180, 0, 1));
item.put(TransformType.THIRD_PERSON_RIGHT_HAND, thirdPersonItem);
item.put(TransformType.THIRD_PERSON_LEFT_HAND, leftify(thirdPersonItem));
item.put(TransformType.FIRST_PERSON_RIGHT_HAND, firstPersonItem);
item.put(TransformType.FIRST_PERSON_LEFT_HAND, leftify(firstPersonItem));
item.put(TransformType.FIXED, convert(0, 0, 0, 0, 180, 0, 1));
builder.put("forge:default-item", new SimpleModelState(ImmutableMap.copyOf(item)));
// item/handheld
EnumMap<TransformType, TRSRTransformation> tool = new EnumMap<>(TransformType.class);
tool.putAll(item);
tool.put(TransformType.THIRD_PERSON_RIGHT_HAND, convert(0, 4, 0.5f, 0, -90, 55, 0.85f));
tool.put(TransformType.THIRD_PERSON_LEFT_HAND, convert(0, 4, 0.5f, 0, 90, -55, 0.85f));
tool.put(TransformType.FIRST_PERSON_RIGHT_HAND, convert(1.13f, 3.2f, 1.13f, 0, -90, 25, 0.68f));
tool.put(TransformType.FIRST_PERSON_LEFT_HAND, convert(1.13f, 3.2f, 1.13f, 0, 90, -25, 0.68f));
builder.put("forge:default-tool", new SimpleModelState(ImmutableMap.copyOf(tool)));
transforms = builder.build();
}
}
}
@@ -25,6 +25,7 @@ import java.util.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ModelBlock;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.util.ResourceLocation;
@@ -121,4 +122,8 @@ public interface IModel
default IModel retexture(ImmutableMap<String, String> textures) {
return this;
}
default Optional<ModelBlock> asVanillaModel() {
return Optional.empty();
}
}
@@ -19,8 +19,6 @@
package net.minecraftforge.client.model;
import javax.vecmath.Vector4f;
import net.minecraftforge.common.ForgeVersion;
import net.minecraft.client.renderer.block.model.BakedQuad;
@@ -33,6 +31,8 @@ import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.model.pipeline.IVertexConsumer;
import net.minecraftforge.client.model.pipeline.TRSRTransformer;
import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
import net.minecraftforge.common.model.IModelState;
import net.minecraftforge.common.model.TRSRTransformation;
@@ -110,6 +110,7 @@ public final class ItemLayerModel implements IModel
{
ImmutableList.Builder<BakedQuad> builder = ImmutableList.builder();
Optional<TRSRTransformation> transform = state.apply(Optional.empty());
boolean identity = !transform.isPresent() || transform.get().isIdentity();
for(int i = 0; i < textures.size(); i++)
{
TextureAtlasSprite sprite = bakedTextureGetter.apply(textures.get(i));
@@ -117,7 +118,7 @@ public final class ItemLayerModel implements IModel
}
TextureAtlasSprite particle = bakedTextureGetter.apply(textures.isEmpty() ? new ResourceLocation("missingno") : textures.get(0));
ImmutableMap<TransformType, TRSRTransformation> map = PerspectiveMapWrapper.getTransforms(state);
return new BakedItemModel(builder.build(), particle, map, overrides);
return new BakedItemModel(builder.build(), particle, map, overrides, identity);
}
public static ImmutableList<BakedQuad> getQuadsForSprite(int tint, TextureAtlasSprite sprite, VertexFormat format, Optional<TRSRTransformation> transform)
@@ -394,51 +395,49 @@ public final class ItemLayerModel implements IModel
float x3, float y3, float z3, float u3, float v3)
{
UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder(format);
builder.setQuadTint(tint);
builder.setQuadOrientation(side);
builder.setTexture(sprite);
putVertex(builder, format, transform, side, x0, y0, z0, u0, v0);
putVertex(builder, format, transform, side, x1, y1, z1, u1, v1);
putVertex(builder, format, transform, side, x2, y2, z2, u2, v2);
putVertex(builder, format, transform, side, x3, y3, z3, u3, v3);
boolean hasTransform = transform.isPresent() && !transform.get().isIdentity();
IVertexConsumer consumer = hasTransform ? new TRSRTransformer(builder, transform.get()) : builder;
putVertex(consumer, format, side, x0, y0, z0, u0, v0);
putVertex(consumer, format, side, x1, y1, z1, u1, v1);
putVertex(consumer, format, side, x2, y2, z2, u2, v2);
putVertex(consumer, format, side, x3, y3, z3, u3, v3);
return builder.build();
}
private static void putVertex(UnpackedBakedQuad.Builder builder, VertexFormat format, Optional<TRSRTransformation> transform, EnumFacing side, float x, float y, float z, float u, float v)
private static void putVertex(IVertexConsumer consumer, VertexFormat format, EnumFacing side, float x, float y, float z, float u, float v)
{
Vector4f vec = new Vector4f();
for(int e = 0; e < format.getElementCount(); e++)
{
switch(format.getElement(e).getUsage())
{
case POSITION:
if(transform.isPresent())
{
vec.x = x;
vec.y = y;
vec.z = z;
vec.w = 1;
transform.get().getMatrix().transform(vec);
builder.put(e, vec.x, vec.y, vec.z, vec.w);
}
else
{
builder.put(e, x, y, z, 1);
}
consumer.put(e, x, y, z, 1f);
break;
case COLOR:
builder.put(e, 1f, 1f, 1f, 1f);
consumer.put(e, 1f, 1f, 1f, 1f);
break;
case UV: if(format.getElement(e).getIndex() == 0)
{
builder.put(e, u, v, 0f, 1f);
break;
}
case NORMAL:
builder.put(e, (float)side.getFrontOffsetX(), (float)side.getFrontOffsetY(), (float)side.getFrontOffsetZ(), 0f);
float offX = (float) side.getFrontOffsetX();
float offY = (float) side.getFrontOffsetY();
float offZ = (float) side.getFrontOffsetZ();
consumer.put(e, offX, offY, offZ, 0f);
break;
case UV:
if(format.getElement(e).getIndex() == 0)
{
consumer.put(e, u, v, 0f, 1f);
break;
}
// else fallthrough to default
default:
builder.put(e);
consumer.put(e);
break;
}
}
@@ -24,11 +24,11 @@ import com.google.common.collect.Lists;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.client.model.pipeline.IVertexConsumer;
import net.minecraftforge.client.model.pipeline.TRSRTransformer;
import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
import net.minecraftforge.common.model.TRSRTransformation;
import javax.vecmath.Vector4f;
import java.util.List;
public final class ItemTextureQuadConverter
@@ -63,7 +63,7 @@ public final class ItemTextureQuadConverter
List<UnpackedBakedQuad> horizontal = convertTextureHorizontal(format, transform, template, sprite, z, facing, color, tint);
List<UnpackedBakedQuad> vertical = convertTextureVertical(format, transform, template, sprite, z, facing, color, tint);
return horizontal.size() >= vertical.size() ? horizontal : vertical;
return horizontal.size() <= vertical.size() ? horizontal : vertical;
}
/** @deprecated use {@link #convertTextureHorizontal(VertexFormat, TRSRTransformation, TextureAtlasSprite, TextureAtlasSprite, float, EnumFacing, int, int)} */
@@ -273,65 +273,59 @@ public final class ItemTextureQuadConverter
builder.setQuadOrientation(side);
builder.setTexture(sprite);
// only apply the transform if it's not identity
boolean hasTransform = !transform.isIdentity();
IVertexConsumer consumer = hasTransform ? new TRSRTransformer(builder, transform) : builder;
if (side == EnumFacing.SOUTH)
{
putVertex(builder, format, transform, side, x1, y1, z, u1, v2, color);
putVertex(builder, format, transform, side, x2, y1, z, u2, v2, color);
putVertex(builder, format, transform, side, x2, y2, z, u2, v1, color);
putVertex(builder, format, transform, side, x1, y2, z, u1, v1, color);
putVertex(consumer, format, side, x1, y1, z, u1, v2, color);
putVertex(consumer, format, side, x2, y1, z, u2, v2, color);
putVertex(consumer, format, side, x2, y2, z, u2, v1, color);
putVertex(consumer, format, side, x1, y2, z, u1, v1, color);
}
else
{
putVertex(builder, format, transform, side, x1, y1, z, u1, v2, color);
putVertex(builder, format, transform, side, x1, y2, z, u1, v1, color);
putVertex(builder, format, transform, side, x2, y2, z, u2, v1, color);
putVertex(builder, format, transform, side, x2, y1, z, u2, v2, color);
putVertex(consumer, format, side, x1, y1, z, u1, v2, color);
putVertex(consumer, format, side, x1, y2, z, u1, v1, color);
putVertex(consumer, format, side, x2, y2, z, u2, v1, color);
putVertex(consumer, format, side, x2, y1, z, u2, v2, color);
}
return builder.build();
}
private static void putVertex(UnpackedBakedQuad.Builder builder, VertexFormat format, TRSRTransformation transform, EnumFacing side,
private static void putVertex(IVertexConsumer consumer, VertexFormat format, EnumFacing side,
float x, float y, float z, float u, float v, int color)
{
Vector4f vec = new Vector4f();
for (int e = 0; e < format.getElementCount(); e++)
{
switch (format.getElement(e).getUsage())
{
case POSITION:
if (transform.isIdentity())
{
builder.put(e, x, y, z, 1);
}
// only apply the transform if it's not identity
else
{
vec.x = x;
vec.y = y;
vec.z = z;
vec.w = 1;
transform.getMatrix().transform(vec);
builder.put(e, vec.x, vec.y, vec.z, vec.w);
}
consumer.put(e, x, y, z, 1f);
break;
case COLOR:
float r = ((color >> 16) & 0xFF) / 255f; // red
float g = ((color >> 8) & 0xFF) / 255f; // green
float b = ((color >> 0) & 0xFF) / 255f; // blue
float g = ((color >> 8) & 0xFF) / 255f; // green
float b = ((color >> 0) & 0xFF) / 255f; // blue
float a = ((color >> 24) & 0xFF) / 255f; // alpha
builder.put(e, r, g, b, a);
consumer.put(e, r, g, b, a);
break;
case NORMAL:
float offX = (float) side.getFrontOffsetX();
float offY = (float) side.getFrontOffsetY();
float offZ = (float) side.getFrontOffsetZ();
consumer.put(e, offX, offY, offZ, 0f);
break;
case UV:
if (format.getElement(e).getIndex() == 0)
{
builder.put(e, u, v, 0f, 1f);
consumer.put(e, u, v, 0f, 1f);
break;
}
case NORMAL:
builder.put(e, (float) side.getFrontOffsetX(), (float) side.getFrontOffsetY(), (float) side.getFrontOffsetZ(), 0f);
break;
// else fallthrough to default
default:
builder.put(e);
consumer.put(e);
break;
}
}
@@ -176,7 +176,7 @@ public final class ModelDynBucket implements IModel
}
}
return new BakedDynBucket(this, builder.build(), particleSprite, format, Maps.immutableEnumMap(transformMap), Maps.newHashMap());
return new BakedDynBucket(this, builder.build(), particleSprite, format, Maps.immutableEnumMap(transformMap), Maps.newHashMap(), transform.isIdentity());
}
/**
@@ -273,19 +273,26 @@ public final class ModelDynBucket implements IModel
public void register(TextureMap map)
{
// only create these textures if they are not added by a resource pack
if (getResource(new ResourceLocation(ForgeVersion.MOD_ID, "textures/items/bucket_cover.png")) == null)
try (IResource cover = getResource(new ResourceLocation(ForgeVersion.MOD_ID, "textures/items/bucket_cover.png"));
IResource base = getResource(new ResourceLocation(ForgeVersion.MOD_ID, "textures/items/bucket_base.png")))
{
ResourceLocation bucketCover = new ResourceLocation(ForgeVersion.MOD_ID, "items/bucket_cover");
BucketCoverSprite bucketCoverSprite = new BucketCoverSprite(bucketCover);
map.setTextureEntry(bucketCoverSprite);
if (cover == null)
{
ResourceLocation bucketCover = new ResourceLocation(ForgeVersion.MOD_ID, "items/bucket_cover");
BucketCoverSprite bucketCoverSprite = new BucketCoverSprite(bucketCover);
map.setTextureEntry(bucketCoverSprite);
}
if (base == null)
{
ResourceLocation bucketBase = new ResourceLocation(ForgeVersion.MOD_ID, "items/bucket_base");
BucketBaseSprite bucketBaseSprite = new BucketBaseSprite(bucketBase);
map.setTextureEntry(bucketBaseSprite);
}
}
if (getResource(new ResourceLocation(ForgeVersion.MOD_ID, "textures/items/bucket_base.png")) == null)
catch (IOException e)
{
ResourceLocation bucketBase = new ResourceLocation(ForgeVersion.MOD_ID, "items/bucket_base");
BucketBaseSprite bucketBaseSprite = new BucketBaseSprite(bucketBase);
map.setTextureEntry(bucketBaseSprite);
FMLLog.log.error("Failed to close resource", e);
}
}
@@ -453,14 +460,15 @@ public final class ModelDynBucket implements IModel
private final Map<String, IBakedModel> cache; // contains all the baked models since they'll never change
private final VertexFormat format;
public BakedDynBucket(ModelDynBucket parent,
ImmutableList<BakedQuad> quads,
TextureAtlasSprite particle,
VertexFormat format,
ImmutableMap<TransformType, TRSRTransformation> transforms,
Map<String, IBakedModel> cache)
BakedDynBucket(ModelDynBucket parent,
ImmutableList<BakedQuad> quads,
TextureAtlasSprite particle,
VertexFormat format,
ImmutableMap<TransformType, TRSRTransformation> transforms,
Map<String, IBakedModel> cache,
boolean untransformed)
{
super(quads, particle, transforms, BakedDynBucketOverrideHandler.INSTANCE);
super(quads, particle, transforms, BakedDynBucketOverrideHandler.INSTANCE, untransformed);
this.format = format;
this.parent = parent;
this.cache = cache;
@@ -27,7 +27,6 @@ import java.util.Optional;
import javax.annotation.Nullable;
import javax.vecmath.Matrix4f;
import javax.vecmath.Vector4f;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.BakedQuad;
@@ -40,6 +39,8 @@ import net.minecraft.client.resources.IResourceManager;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.client.model.pipeline.IVertexConsumer;
import net.minecraftforge.client.model.pipeline.TRSRTransformer;
import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
import net.minecraftforge.common.ForgeVersion;
import net.minecraftforge.common.model.IModelState;
@@ -390,15 +391,19 @@ public final class ModelFluid implements IModel
private BakedQuad buildQuad(EnumFacing side, TextureAtlasSprite texture, boolean flip, boolean offset, VertexParameter x, VertexParameter y, VertexParameter z, VertexParameter u, VertexParameter v)
{
UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder(format);
builder.setQuadOrientation(side);
builder.setTexture(texture);
builder.setQuadTint(0);
boolean hasTransform = transformation.isPresent() && !transformation.get().isIdentity();
IVertexConsumer consumer = hasTransform ? new TRSRTransformer(builder, transformation.get()) : builder;
for (int i = 0; i < 4; i++)
{
int vertex = flip ? 3 - i : i;
putVertex(
builder, side, offset,
consumer, side, offset,
x.get(vertex), y.get(vertex), z.get(vertex),
texture.getInterpolatedU(u.get(vertex)),
texture.getInterpolatedV(v.get(vertex))
@@ -408,7 +413,7 @@ public final class ModelFluid implements IModel
return builder.build();
}
private void putVertex(UnpackedBakedQuad.Builder builder, EnumFacing side, boolean offset, float x, float y, float z, float u, float v)
private void putVertex(IVertexConsumer consumer, EnumFacing side, boolean offset, float x, float y, float z, float u, float v)
{
for(int e = 0; e < format.getElementCount(); e++)
{
@@ -418,32 +423,30 @@ public final class ModelFluid implements IModel
float dx = offset ? side.getDirectionVec().getX() * eps : 0f;
float dy = offset ? side.getDirectionVec().getY() * eps : 0f;
float dz = offset ? side.getDirectionVec().getZ() * eps : 0f;
float[] data = { x - dx, y - dy, z - dz, 1f };
if(transformation.isPresent() && !transformation.get().isIdentity())
{
Vector4f vec = new Vector4f(data);
transformation.get().getMatrix().transform(vec);
vec.get(data);
}
builder.put(e, data);
consumer.put(e, x - dx, y - dy, z - dz, 1f);
break;
case COLOR:
builder.put(e,
((color >> 16) & 0xFF) / 255f,
((color >> 8) & 0xFF) / 255f,
(color & 0xFF) / 255f,
((color >> 24) & 0xFF) / 255f);
float r = ((color >> 16) & 0xFF) / 255f;
float g = ((color >> 8) & 0xFF) / 255f;
float b = ( color & 0xFF) / 255f;
float a = ((color >> 24) & 0xFF) / 255f;
consumer.put(e, r, g, b, a);
break;
case UV: if(format.getElement(e).getIndex() == 0)
{
builder.put(e, u, v, 0f, 1f);
break;
}
case NORMAL:
builder.put(e, (float)side.getFrontOffsetX(), (float)side.getFrontOffsetY(), (float)side.getFrontOffsetZ(), 0f);
float offX = (float) side.getFrontOffsetX();
float offY = (float) side.getFrontOffsetY();
float offZ = (float) side.getFrontOffsetZ();
consumer.put(e, offX, offY, offZ, 0f);
break;
case UV:
if(format.getElement(e).getIndex() == 0)
{
consumer.put(e, u, v, 0f, 1f);
break;
}
// else fallthrough to default
default:
builder.put(e);
consumer.put(e);
break;
}
}
@@ -67,7 +67,6 @@ import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.item.Item;
import net.minecraft.launchwrapper.Launch;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.registry.IRegistry;
@@ -84,6 +83,7 @@ import net.minecraftforge.fml.common.FMLLog;
import net.minecraftforge.fml.common.ProgressManager;
import net.minecraftforge.fml.common.ProgressManager.ProgressBar;
import net.minecraftforge.fml.common.registry.ForgeRegistries;
import net.minecraftforge.fml.relauncher.FMLLaunchHandler;
import net.minecraftforge.registries.IRegistryDelegate;
import org.apache.commons.lang3.tuple.Pair;
@@ -128,7 +128,7 @@ public final class ModelLoader extends ModelBakery
return isLoading;
}
private final boolean enableVerboseMissingInfo = (Boolean)Launch.blackboard.get("fml.deobfuscatedEnvironment") || Boolean.parseBoolean(System.getProperty("forge.verboseMissingModelLogging", "false"));
private final boolean enableVerboseMissingInfo = FMLLaunchHandler.isDeobfuscatedEnvironment() || Boolean.parseBoolean(System.getProperty("forge.verboseMissingModelLogging", "false"));
private final int verboseMissingInfoCount = Integer.parseInt(System.getProperty("forge.verboseMissingModelLoggingCount", "5"));
public ModelLoader(IResourceManager manager, TextureMap map, BlockModelShapes shapes)
@@ -375,23 +375,17 @@ public final class ModelLoader extends ModelBakery
public Collection<ResourceLocation> getTextures()
{
// setting parent here to make textures resolve properly
if(model.getParentLocation() != null)
ResourceLocation parentLocation = model.getParentLocation();
if(parentLocation != null && model.parent == null)
{
if(model.getParentLocation().getResourcePath().equals("builtin/generated"))
if(parentLocation.getResourcePath().equals("builtin/generated"))
{
model.parent = MODEL_GENERATED;
}
else
{
IModel parent = ModelLoaderRegistry.getModelOrLogError(model.getParentLocation(), "Could not load vanilla model parent '" + model.getParentLocation() + "' for '" + model);
if(parent instanceof VanillaModelWrapper)
{
model.parent = ((VanillaModelWrapper) parent).model;
}
else
{
throw new IllegalStateException("vanilla model '" + model + "' can't have non-vanilla parent");
}
model.parent = ModelLoaderRegistry.getModelOrLogError(parentLocation, "Could not load vanilla model parent '" + parentLocation + "' for '" + model + "'")
.asVanillaModel().orElseThrow(() -> new IllegalStateException("vanilla model '" + model + "' can't have non-vanilla parent"));
}
}
@@ -445,7 +439,7 @@ public final class ModelLoader extends ModelBakery
Map<TransformType, TRSRTransformation> tMap = Maps.newEnumMap(TransformType.class);
tMap.putAll(PerspectiveMapWrapper.getTransforms(transforms));
tMap.putAll(PerspectiveMapWrapper.getTransforms(state));
IModelState perState = new SimpleModelState(ImmutableMap.copyOf(tMap));
IModelState perState = new SimpleModelState(ImmutableMap.copyOf(tMap), state.apply(Optional.empty()));
if(hasItemModel(model))
{
@@ -621,6 +615,12 @@ public final class ModelLoader extends ModelBakery
}
return new VanillaModelWrapper(location, model, value, animation);
}
@Override
public Optional<ModelBlock> asVanillaModel()
{
return Optional.of(model);
}
}
private static final class WeightedRandomModel implements IModel
@@ -19,12 +19,12 @@
package net.minecraftforge.client.model;
import javax.vecmath.Matrix3f;
import javax.vecmath.Matrix4f;
import javax.vecmath.Vector3f;
import javax.vecmath.Vector4f;
import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
import net.minecraftforge.common.model.TRSRTransformation;
import com.google.common.collect.ImmutableList;
@@ -42,7 +42,7 @@ import net.minecraft.util.ResourceLocation;
public abstract class SimpleModelFontRenderer extends FontRenderer {
private float r, g, b, a;
private final Matrix4f matrix;
private final TRSRTransformation transform;
private ImmutableList.Builder<BakedQuad> builder = ImmutableList.builder();
private final VertexFormat format;
private final Vector3f normal = new Vector3f(0, 0, 1);
@@ -54,14 +54,9 @@ public abstract class SimpleModelFontRenderer extends FontRenderer {
public SimpleModelFontRenderer(GameSettings settings, ResourceLocation font, TextureManager manager, boolean isUnicode, Matrix4f matrix, VertexFormat format)
{
super(settings, font, manager, isUnicode);
this.matrix = new Matrix4f(matrix);
Matrix3f nm = new Matrix3f();
this.matrix.getRotationScale(nm);
nm.invert();
nm.transpose();
this.transform = new TRSRTransformation(matrix);
this.format = format;
nm.transform(normal);
normal.normalize();
transform.transformNormal(normal);
orientation = EnumFacing.getFacingFromVector(normal.x, normal.y, normal.z);
}
@@ -128,21 +123,15 @@ public abstract class SimpleModelFontRenderer extends FontRenderer {
private void addVertex(UnpackedBakedQuad.Builder quadBuilder, float x, float y, float u, float v)
{
vec.x = x;
vec.y = y;
vec.z = 0;
vec.w = 1;
matrix.transform(vec);
for(int e = 0; e < format.getElementCount(); e++)
{
switch(format.getElement(e).getUsage())
{
case POSITION:
vec.set(x, y, 0f, 1f);
transform.transformPosition(vec);
quadBuilder.put(e, vec.x, vec.y, vec.z, vec.w);
break;
case UV:
quadBuilder.put(e, sprite.getInterpolatedU(u * 16), sprite.getInterpolatedV(v * 16), 0, 1);
break;
case COLOR:
quadBuilder.put(e, r, g, b, a);
break;
@@ -150,6 +139,13 @@ public abstract class SimpleModelFontRenderer extends FontRenderer {
//quadBuilder.put(e, normal.x, normal.y, normal.z, 1);
quadBuilder.put(e, 0, 0, 1, 1);
break;
case UV:
if(format.getElement(e).getIndex() == 0)
{
quadBuilder.put(e, sprite.getInterpolatedU(u * 16), sprite.getInterpolatedV(v * 16), 0, 1);
break;
}
// else fallthrough to default
default:
quadBuilder.put(e);
break;
@@ -100,7 +100,6 @@ public enum B3DLoader implements ICustomModelLoader
private IResourceManager manager;
private final Set<String> enabledDomains = new HashSet<>();
private final Map<ResourceLocation, B3DModel> cache = new HashMap<>();
public void addDomain(String domain)
{
@@ -111,7 +110,6 @@ public enum B3DLoader implements ICustomModelLoader
public void onResourceManagerReload(IResourceManager manager)
{
this.manager = manager;
cache.clear();
}
@Override
@@ -125,38 +123,33 @@ public enum B3DLoader implements ICustomModelLoader
public IModel loadModel(ResourceLocation modelLocation) throws Exception
{
ResourceLocation file = new ResourceLocation(modelLocation.getResourceDomain(), modelLocation.getResourcePath());
if(!cache.containsKey(file))
B3DModel model;
IResource resource = null;
try
{
IResource resource = null;
try
{
try
{
resource = manager.getResource(file);
}
catch(FileNotFoundException e)
{
if(modelLocation.getResourcePath().startsWith("models/block/"))
resource = manager.getResource(new ResourceLocation(file.getResourceDomain(), "models/item/" + file.getResourcePath().substring("models/block/".length())));
else if(modelLocation.getResourcePath().startsWith("models/item/"))
resource = manager.getResource(new ResourceLocation(file.getResourceDomain(), "models/block/" + file.getResourcePath().substring("models/item/".length())));
else throw e;
}
B3DModel.Parser parser = new B3DModel.Parser(resource.getInputStream());
B3DModel model = parser.parse();
cache.put(file, model);
resource = manager.getResource(file);
}
catch(IOException e)
catch(FileNotFoundException e)
{
cache.put(file, null);
throw e;
}
finally
{
IOUtils.closeQuietly(resource);
if(modelLocation.getResourcePath().startsWith("models/block/"))
resource = manager.getResource(new ResourceLocation(file.getResourceDomain(), "models/item/" + file.getResourcePath().substring("models/block/".length())));
else if(modelLocation.getResourcePath().startsWith("models/item/"))
resource = manager.getResource(new ResourceLocation(file.getResourceDomain(), "models/block/" + file.getResourcePath().substring("models/item/".length())));
else throw e;
}
B3DModel.Parser parser = new B3DModel.Parser(resource.getInputStream());
model = parser.parse();
}
catch(IOException e)
{
throw e;
}
finally
{
IOUtils.closeQuietly(resource);
}
B3DModel model = cache.get(file);
if(model == null) throw new ModelLoaderRegistry.LoaderException("Error loading model previously: " + file);
if(!(model.getRoot().getKind() instanceof Mesh))
{
@@ -37,7 +37,6 @@ import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
import javax.vecmath.Matrix3f;
import javax.vecmath.Matrix4f;
import javax.vecmath.Quat4f;
import javax.vecmath.Vector2f;
@@ -45,6 +44,7 @@ import javax.vecmath.Vector3f;
import javax.vecmath.Vector4f;
import net.minecraftforge.common.ForgeVersion;
import net.minecraftforge.common.model.TRSRTransformation;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
@@ -681,25 +681,21 @@ public class B3DModel
else t.setIdentity();
}
TRSRTransformation trsr = new TRSRTransformation(t);
// pos
Vector4f pos = new Vector4f(this.pos), newPos = new Vector4f();
Vector4f pos = new Vector4f(this.pos);
pos.w = 1;
t.transform(pos, newPos);
Vector3f rPos = new Vector3f(newPos.x / newPos.w, newPos.y / newPos.w, newPos.z / newPos.w);
trsr.transformPosition(pos);
Vector3f rPos = new Vector3f(pos.x / pos.w, pos.y / pos.w, pos.z / pos.w);
// normal
Vector3f rNormal = null;
if(this.normal != null)
{
Matrix3f tm = new Matrix3f();
t.getRotationScale(tm);
tm.invert();
tm.transpose();
Vector3f normal = new Vector3f(this.normal);
rNormal = new Vector3f();
tm.transform(normal, rNormal);
rNormal.normalize();
rNormal = new Vector3f(this.normal);
trsr.transformNormal(rNormal);
}
// texCoords TODO
@@ -46,8 +46,6 @@ public enum OBJLoader implements ICustomModelLoader {
private IResourceManager manager;
private final Set<String> enabledDomains = new HashSet<>();
private final Map<ResourceLocation, OBJModel> cache = new HashMap<>();
private final Map<ResourceLocation, Exception> errors = new HashMap<>();
public void addDomain(String domain)
{
@@ -59,8 +57,6 @@ public enum OBJLoader implements ICustomModelLoader {
public void onResourceManagerReload(IResourceManager resourceManager)
{
this.manager = resourceManager;
cache.clear();
errors.clear();
}
@Override
@@ -73,45 +69,36 @@ public enum OBJLoader implements ICustomModelLoader {
public IModel loadModel(ResourceLocation modelLocation) throws Exception
{
ResourceLocation file = new ResourceLocation(modelLocation.getResourceDomain(), modelLocation.getResourcePath());
if (!cache.containsKey(file))
IResource resource = null;
try
{
IResource resource = null;
try
{
try
{
resource = manager.getResource(file);
}
catch (FileNotFoundException e)
{
if (modelLocation.getResourcePath().startsWith("models/block/"))
resource = manager.getResource(new ResourceLocation(file.getResourceDomain(), "models/item/" + file.getResourcePath().substring("models/block/".length())));
else if (modelLocation.getResourcePath().startsWith("models/item/"))
resource = manager.getResource(new ResourceLocation(file.getResourceDomain(), "models/block/" + file.getResourcePath().substring("models/item/".length())));
else throw e;
}
OBJModel.Parser parser = new OBJModel.Parser(resource, manager);
OBJModel model = null;
try
{
model = parser.parse();
}
catch (Exception e)
{
errors.put(modelLocation, e);
}
finally
{
cache.put(modelLocation, model);
}
resource = manager.getResource(file);
}
finally
catch (FileNotFoundException e)
{
IOUtils.closeQuietly(resource);
if (modelLocation.getResourcePath().startsWith("models/block/"))
resource = manager.getResource(new ResourceLocation(file.getResourceDomain(), "models/item/" + file.getResourcePath().substring("models/block/".length())));
else if (modelLocation.getResourcePath().startsWith("models/item/"))
resource = manager.getResource(new ResourceLocation(file.getResourceDomain(), "models/block/" + file.getResourcePath().substring("models/item/".length())));
else throw e;
}
OBJModel.Parser parser = new OBJModel.Parser(resource, manager);
OBJModel model;
try
{
model = parser.parse();
}
catch (Exception e)
{
throw new ModelLoaderRegistry.LoaderException("Error loading model previously: " + file, e);
}
return model;
}
finally
{
IOUtils.closeQuietly(resource);
}
OBJModel model = cache.get(file);
if (model == null) throw new ModelLoaderRegistry.LoaderException("Error loading model previously: " + file, errors.get(modelLocation));
return model;
}
}
}
@@ -35,7 +35,6 @@ import java.util.Set;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import javax.vecmath.Matrix3f;
import javax.vecmath.Matrix4f;
import javax.vecmath.Vector2f;
import javax.vecmath.Vector3f;
@@ -225,7 +224,6 @@ public class OBJModel implements IModel
//Partial reading of the OBJ format. Documentation taken from http://paulbourke.net/dataformats/obj/
public OBJModel parse() throws IOException
{
String currentLine = "";
Material material = new Material();
material.setName(Material.DEFAULT_NAME);
int usemtlCounter = 0;
@@ -234,9 +232,9 @@ public class OBJModel implements IModel
for (;;)
{
lineNum++;
currentLine = objReader.readLine();
String currentLine = objReader.readLine();
if (currentLine == null) break;
currentLine.trim();
currentLine = currentLine.trim();
if (currentLine.isEmpty() || currentLine.startsWith("#")) continue;
try
@@ -388,8 +386,6 @@ public class OBJModel implements IModel
private Set<String> unknownMaterialCommands = new HashSet<String>();
private Map<String, Material> materials = new HashMap<String, Material>();
private Map<String, Group> groups = new HashMap<String, Group>();
private InputStreamReader mtlStream;
private BufferedReader mtlReader;
// private float[] minUVBounds = new float[] {0.0f, 0.0f};
// private float[] maxUVBounds = new float[] {1.0f, 1.0f};
@@ -437,8 +433,6 @@ public class OBJModel implements IModel
ret.unknownMaterialCommands = this.unknownMaterialCommands;
ret.materials = mats;
ret.groups = this.groups;
ret.mtlStream = this.mtlStream;
ret.mtlReader = this.mtlReader;
// ret.minUVBounds = this.minUVBounds;
// ret.maxUVBounds = this.maxUVBounds;
return ret;
@@ -480,10 +474,10 @@ public class OBJModel implements IModel
public void changeMaterialColor(String name, int color)
{
Vector4f colorVec = new Vector4f();
colorVec.w = (color >> 24 & 255) / 255;
colorVec.x = (color >> 16 & 255) / 255;
colorVec.y = (color >> 8 & 255) / 255;
colorVec.z = (color & 255) / 255;
colorVec.w = (color >> 24 & 255) / 255f;
colorVec.x = (color >> 16 & 255) / 255f;
colorVec.y = (color >> 8 & 255) / 255f;
colorVec.z = (color & 255) / 255f;
this.materials.get(name).setColor(colorVec);
}
@@ -505,87 +499,86 @@ public class OBJModel implements IModel
String domain = from.getResourceDomain();
if (!path.contains("/"))
path = from.getResourcePath().substring(0, from.getResourcePath().lastIndexOf("/") + 1) + path;
mtlStream = new InputStreamReader(manager.getResource(new ResourceLocation(domain, path)).getInputStream(), StandardCharsets.UTF_8);
mtlReader = new BufferedReader(mtlStream);
String currentLine = "";
Material material = new Material();
material.setName(Material.WHITE_NAME);
material.setTexture(Texture.WHITE);
this.materials.put(Material.WHITE_NAME, material);
this.materials.put(Material.DEFAULT_NAME, new Material(Texture.WHITE));
for (;;)
ResourceLocation mtlLocation = new ResourceLocation(domain, path);
try (IResource resource = manager.getResource(mtlLocation))
{
currentLine = mtlReader.readLine();
if (currentLine == null) break;
currentLine.trim();
if (currentLine.isEmpty() || currentLine.startsWith("#")) continue;
BufferedReader mtlReader = new BufferedReader(new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8));
String[] fields = WHITE_SPACE.split(currentLine, 2);
String key = fields[0];
String data = fields[1];
Material material = new Material();
material.setName(Material.WHITE_NAME);
material.setTexture(Texture.WHITE);
this.materials.put(Material.WHITE_NAME, material);
this.materials.put(Material.DEFAULT_NAME, new Material(Texture.WHITE));
if (key.equalsIgnoreCase("newmtl"))
for (;;)
{
hasSetColor = false;
hasSetTexture = false;
material = new Material();
material.setName(data);
this.materials.put(data, material);
}
else if (key.equalsIgnoreCase("Ka") || key.equalsIgnoreCase("Kd") || key.equalsIgnoreCase("Ks"))
{
if (key.equalsIgnoreCase("Kd") || !hasSetColor)
String currentLine = mtlReader.readLine();
if (currentLine == null) break;
currentLine = currentLine.trim();
if (currentLine.isEmpty() || currentLine.startsWith("#")) continue;
String[] fields = WHITE_SPACE.split(currentLine, 2);
String key = fields[0];
String data = fields[1];
if (key.equalsIgnoreCase("newmtl"))
{
String[] rgbStrings = WHITE_SPACE.split(data, 3);
Vector4f color = new Vector4f(Float.parseFloat(rgbStrings[0]), Float.parseFloat(rgbStrings[1]), Float.parseFloat(rgbStrings[2]), 1.0f);
hasSetColor = true;
material.setColor(color);
hasSetColor = false;
hasSetTexture = false;
material = new Material();
material.setName(data);
this.materials.put(data, material);
}
else
else if (key.equalsIgnoreCase("Ka") || key.equalsIgnoreCase("Kd") || key.equalsIgnoreCase("Ks"))
{
FMLLog.log.info("OBJModel: A color has already been defined for material '{}' in '{}'. The color defined by key '{}' will not be applied!", material.getName(), new ResourceLocation(domain, path).toString(), key);
}
}
else if (key.equalsIgnoreCase("map_Ka") || key.equalsIgnoreCase("map_Kd") || key.equalsIgnoreCase("map_Ks"))
{
if (key.equalsIgnoreCase("map_Kd") || !hasSetTexture)
{
if (data.contains(" "))
if (key.equalsIgnoreCase("Kd") || !hasSetColor)
{
String[] mapStrings = WHITE_SPACE.split(data);
String texturePath = mapStrings[mapStrings.length - 1];
Texture texture = new Texture(texturePath);
hasSetTexture = true;
material.setTexture(texture);
String[] rgbStrings = WHITE_SPACE.split(data, 3);
Vector4f color = new Vector4f(Float.parseFloat(rgbStrings[0]), Float.parseFloat(rgbStrings[1]), Float.parseFloat(rgbStrings[2]), 1.0f);
hasSetColor = true;
material.setColor(color);
}
else
{
Texture texture = new Texture(data);
hasSetTexture = true;
material.setTexture(texture);
FMLLog.log.info("OBJModel: A color has already been defined for material '{}' in '{}'. The color defined by key '{}' will not be applied!", material.getName(), mtlLocation, key);
}
}
else
else if (key.equalsIgnoreCase("map_Ka") || key.equalsIgnoreCase("map_Kd") || key.equalsIgnoreCase("map_Ks"))
{
FMLLog.log.info("OBJModel: A texture has already been defined for material '{}' in '{}'. The texture defined by key '{}' will not be applied!", material.getName(), new ResourceLocation(domain, path).toString(), key);
if (key.equalsIgnoreCase("map_Kd") || !hasSetTexture)
{
if (data.contains(" "))
{
String[] mapStrings = WHITE_SPACE.split(data);
String texturePath = mapStrings[mapStrings.length - 1];
Texture texture = new Texture(texturePath);
hasSetTexture = true;
material.setTexture(texture);
}
else
{
Texture texture = new Texture(data);
hasSetTexture = true;
material.setTexture(texture);
}
}
else
{
FMLLog.log.info("OBJModel: A texture has already been defined for material '{}' in '{}'. The texture defined by key '{}' will not be applied!", material.getName(), mtlLocation, key);
}
}
}
else if (key.equalsIgnoreCase("d") || key.equalsIgnoreCase("Tr"))
{
//d <-optional key here> float[0.0:1.0, 1.0]
//Tr r g b OR Tr spectral map file OR Tr xyz r g b (CIEXYZ colorspace)
String[] splitData = WHITE_SPACE.split(data);
float alpha = Float.parseFloat(splitData[splitData.length - 1]);
material.getColor().setW(alpha);
}
else
{
if (!unknownMaterialCommands.contains(key))
else if (key.equalsIgnoreCase("d") || key.equalsIgnoreCase("Tr"))
{
unknownMaterialCommands.add(key);
FMLLog.log.info("OBJLoader.MaterialLibrary: key '{}' (model: '{}') is not currently supported, skipping", key, new ResourceLocation(domain, path));
//d <-optional key here> float[0.0:1.0, 1.0]
//Tr r g b OR Tr spectral map file OR Tr xyz r g b (CIEXYZ colorspace)
String[] splitData = WHITE_SPACE.split(data);
float alpha = Float.parseFloat(splitData[splitData.length - 1]);
material.getColor().setW(alpha);
}
else if (unknownMaterialCommands.add(key))
{
FMLLog.log.info("OBJLoader.MaterialLibrary: key '{}' (model: '{}') is not currently supported, skipping", key, mtlLocation);
}
}
}
@@ -845,8 +838,6 @@ public class OBJModel implements IModel
public Face bake(TRSRTransformation transform)
{
Matrix4f m = transform.getMatrix();
Matrix3f mn = null;
Vertex[] vertices = new Vertex[verts.length];
// Normal[] normals = norms != null ? new Normal[norms.length] : null;
// TextureCoordinate[] textureCoords = texCoords != null ? new TextureCoordinate[texCoords.length] : null;
@@ -857,24 +848,16 @@ public class OBJModel implements IModel
// Normal n = norms != null ? norms[i] : null;
// TextureCoordinate t = texCoords != null ? texCoords[i] : null;
Vector4f pos = new Vector4f(v.getPos()), newPos = new Vector4f();
Vector4f pos = new Vector4f(v.getPos());
pos.w = 1;
m.transform(pos, newPos);
vertices[i] = new Vertex(newPos, v.getMaterial());
transform.transformPosition(pos);
vertices[i] = new Vertex(pos, v.getMaterial());
if (v.hasNormal())
{
if(mn == null)
{
mn = new Matrix3f();
m.getRotationScale(mn);
mn.invert();
mn.transpose();
}
Vector3f normal = new Vector3f(v.getNormal().getData()), newNormal = new Vector3f();
mn.transform(normal, newNormal);
newNormal.normalize();
vertices[i].setNormal(new Normal(newNormal));
Vector3f normal = new Vector3f(v.getNormal().getData());
transform.transformNormal(normal);
vertices[i].setNormal(new Normal(normal));
}
if (v.hasTextureCoordinate()) vertices[i].setTextureCoordinate(v.getTextureCoordinate());
@@ -36,10 +36,8 @@ public class ForgeBlockModelRenderer extends BlockModelRenderer
{
private final ThreadLocal<VertexLighterFlat> lighterFlat;
private final ThreadLocal<VertexLighterSmoothAo> lighterSmooth;
private final ThreadLocal<VertexBufferConsumer> wrFlat = new ThreadLocal<>();
private final ThreadLocal<VertexBufferConsumer> wrSmooth = new ThreadLocal<>();
private final ThreadLocal<BufferBuilder> lastRendererFlat = new ThreadLocal<>();
private final ThreadLocal<BufferBuilder> lastRendererSmooth = new ThreadLocal<>();
private final ThreadLocal<VertexBufferConsumer> consumerFlat = ThreadLocal.withInitial(VertexBufferConsumer::new);
private final ThreadLocal<VertexBufferConsumer> consumerSmooth = ThreadLocal.withInitial(VertexBufferConsumer::new);
public ForgeBlockModelRenderer(BlockColors colors)
{
@@ -53,15 +51,14 @@ public class ForgeBlockModelRenderer extends BlockModelRenderer
{
if(ForgeModContainer.forgeLightPipelineEnabled)
{
if(buffer != lastRendererFlat.get())
{
lastRendererFlat.set(buffer);
VertexBufferConsumer newCons = new VertexBufferConsumer(buffer);
wrFlat.set(newCons);
lighterFlat.get().setParent(newCons);
}
wrFlat.get().setOffset(pos);
return render(lighterFlat.get(), world, model, state, pos, buffer, checkSides, rand);
VertexBufferConsumer consumer = consumerFlat.get();
consumer.setBuffer(buffer);
consumer.setOffset(pos);
VertexLighterFlat lighter = lighterFlat.get();
lighter.setParent(consumer);
return render(lighter, world, model, state, pos, buffer, checkSides, rand);
}
else
{
@@ -74,15 +71,14 @@ public class ForgeBlockModelRenderer extends BlockModelRenderer
{
if(ForgeModContainer.forgeLightPipelineEnabled)
{
if(buffer != lastRendererSmooth.get())
{
lastRendererSmooth.set(buffer);
VertexBufferConsumer newCons = new VertexBufferConsumer(buffer);
wrSmooth.set(newCons);
lighterSmooth.get().setParent(newCons);
}
wrSmooth.get().setOffset(pos);
return render(lighterSmooth.get(), world, model, state, pos, buffer, checkSides, rand);
VertexBufferConsumer consumer = consumerSmooth.get();
consumer.setBuffer(buffer);
consumer.setOffset(pos);
VertexLighterSmoothAo lighter = lighterSmooth.get();
lighter.setParent(consumer);
return render(lighter, world, model, state, pos, buffer, checkSides, rand);
}
else
{
@@ -19,15 +19,15 @@
package net.minecraftforge.client.model.pipeline;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
import net.minecraft.client.renderer.vertex.VertexFormatElement.EnumUsage;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.client.ForgeHooksClient;
import org.apache.commons.lang3.tuple.Pair;
import java.util.concurrent.ConcurrentHashMap;
@@ -120,8 +120,14 @@ public class LightUtil
}
}
private static final VertexFormat DEFAULT_FROM = VertexLighterFlat.withNormal(DefaultVertexFormats.BLOCK);
private static final VertexFormat DEFAULT_TO = DefaultVertexFormats.ITEM;
private static final int[] DEFAULT_MAPPING = generateMapping(DEFAULT_FROM, DEFAULT_TO);
public static int[] mapFormats(VertexFormat from, VertexFormat to)
{
//Speedup: in 99.99% this is the mapping, no need to go make a pair, and go through the slower hash map
if (from.equals(DEFAULT_FROM) && to.equals(DEFAULT_TO))
return DEFAULT_MAPPING;
return formatMaps.computeIfAbsent(Pair.of(from, to), pair -> generateMapping(pair.getLeft(), pair.getRight()));
}
@@ -244,6 +250,7 @@ public class LightUtil
}
private static IVertexConsumer tessellator = null;
@Deprecated // TODO: remove
public static IVertexConsumer getTessellator()
{
if(tessellator == null)
@@ -256,6 +263,7 @@ public class LightUtil
}
private static ItemConsumer itemConsumer = null;
@Deprecated // TODO: remove
public static ItemConsumer getItemConsumer()
{
if(itemConsumer == null)
@@ -265,20 +273,29 @@ public class LightUtil
return itemConsumer;
}
// renders quad in any Vertex Format, but is slower
public static void renderQuadColorSlow(BufferBuilder wr, BakedQuad quad, int auxColor)
private static final class ItemPipeline
{
ItemConsumer cons;
if(wr == Tessellator.getInstance().getBuffer())
final VertexBufferConsumer bufferConsumer;
final ItemConsumer itemConsumer;
ItemPipeline()
{
cons = getItemConsumer();
this.bufferConsumer = new VertexBufferConsumer();
this.itemConsumer = new ItemConsumer(bufferConsumer);
}
else
{
cons = new ItemConsumer(new VertexBufferConsumer(wr));
}
float b = (float)(auxColor & 0xFF) / 0xFF;
float g = (float)((auxColor >>> 8) & 0xFF) / 0xFF;
}
private static final ThreadLocal<ItemPipeline> itemPipeline = ThreadLocal.withInitial(ItemPipeline::new);
// renders quad in any Vertex Format, but is slower
public static void renderQuadColorSlow(BufferBuilder buffer, BakedQuad quad, int auxColor)
{
ItemPipeline pipeline = itemPipeline.get();
pipeline.bufferConsumer.setBuffer(buffer);
ItemConsumer cons = pipeline.itemConsumer;
float b = (float)( auxColor & 0xFF) / 0xFF;
float g = (float)((auxColor >>> 8) & 0xFF) / 0xFF;
float r = (float)((auxColor >>> 16) & 0xFF) / 0xFF;
float a = (float)((auxColor >>> 24) & 0xFF) / 0xFF;
@@ -286,16 +303,19 @@ public class LightUtil
quad.pipe(cons);
}
public static void renderQuadColor(BufferBuilder wr, BakedQuad quad, int auxColor)
public static void renderQuadColor(BufferBuilder buffer, BakedQuad quad, int auxColor)
{
if (quad.getFormat().equals(wr.getVertexFormat()))
if (quad.getFormat().equals(buffer.getVertexFormat()))
{
wr.addVertexData(quad.getVertexData());
ForgeHooksClient.putQuadColor(wr, quad, auxColor);
buffer.addVertexData(quad.getVertexData());
if (buffer.getVertexFormat().hasColor())
{
ForgeHooksClient.putQuadColor(buffer, quad, auxColor);
}
}
else
{
renderQuadColorSlow(wr, quad, auxColor);
renderQuadColorSlow(buffer, quad, auxColor);
}
}
@@ -322,7 +342,8 @@ public class LightUtil
if(getVertexFormat().getElement(element).getUsage() == EnumUsage.COLOR)
{
System.arraycopy(auxColor, 0, buf, 0, buf.length);
for(int i = 0; i < 4; i++)
int n = Math.min(4, data.length);
for(int i = 0; i < n; i++)
{
buf[i] *= data[i];
}
@@ -0,0 +1,55 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* 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.model.pipeline;
import net.minecraftforge.common.model.TRSRTransformation;
import javax.vecmath.Vector3f;
import javax.vecmath.Vector4f;
public class TRSRTransformer extends VertexTransformer
{
private final TRSRTransformation transform;
public TRSRTransformer(IVertexConsumer parent, TRSRTransformation transform)
{
super(parent);
this.transform = transform;
}
@Override
public void put(int element, float... data)
{
switch (getVertexFormat().getElement(element).getUsage())
{
case POSITION:
Vector4f pos = new Vector4f(data);
transform.transformPosition(pos);
pos.get(data);
break;
case NORMAL:
Vector3f normal = new Vector3f(data);
transform.transformNormal(normal);
normal.get(data);
break;
}
super.put(element, data);
}
}
@@ -32,16 +32,17 @@ import net.minecraft.util.EnumFacing;
public class VertexBufferConsumer implements IVertexConsumer
{
private static final float[] dummyColor = new float[]{ 1, 1, 1, 1 };
private final BufferBuilder renderer;
private final int[] quadData;
private BufferBuilder renderer;
private int[] quadData;
private int v = 0;
private BlockPos offset = BlockPos.ORIGIN;
public VertexBufferConsumer(BufferBuilder renderer)
public VertexBufferConsumer() {}
public VertexBufferConsumer(BufferBuilder buffer)
{
super();
this.renderer = renderer;
quadData = new int[renderer.getVertexFormat().getNextOffset()/* / 4 * 4 */];
setBuffer(buffer);
}
@Override
@@ -72,6 +73,20 @@ public class VertexBufferConsumer implements IVertexConsumer
}
}
private void checkVertexFormat()
{
if (quadData == null || renderer.getVertexFormat().getNextOffset() != quadData.length)
{
quadData = new int[renderer.getVertexFormat().getNextOffset()];
}
}
public void setBuffer(BufferBuilder buffer)
{
this.renderer = buffer;
checkVertexFormat();
}
public void setOffset(BlockPos offset)
{
this.offset = new BlockPos(offset);
@@ -25,6 +25,7 @@ import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.EntityRenderer;
import net.minecraft.client.renderer.color.BlockColors;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
import net.minecraft.util.EnumFacing;
@@ -107,7 +108,16 @@ public class VertexLighterFlat extends QuadGatheringTransformer
updateIndices();
}
private static VertexFormat withNormal(VertexFormat format)
private static final VertexFormat BLOCK_WITH_NORMAL = withNormalUncached(DefaultVertexFormats.BLOCK);
static VertexFormat withNormal(VertexFormat format)
{
//This is the case in 99.99%. Cache the value, so we don't have to redo it every time, and the speed up the equals check in LightUtil
if (format == DefaultVertexFormats.BLOCK)
return BLOCK_WITH_NORMAL;
return withNormalUncached(format);
}
private static VertexFormat withNormalUncached(VertexFormat format)
{
if (format == null || format.hasNormal()) return format;
return new VertexFormat(format).addElement(NORMAL_4F);
@@ -210,19 +220,19 @@ public class VertexLighterFlat extends QuadGatheringTransformer
pos[2] += blockInfo.getBlockPos().getZ();*/
parent.put(e, position[v]);
break;
case NORMAL: if(normalIndex != -1)
{
case NORMAL:
parent.put(e, normal[v]);
break;
}
case COLOR:
parent.put(e, color[v]);
break;
case UV: if(element.getIndex() == 1)
{
parent.put(e, lightmap[v]);
break;
}
case UV:
if(element.getIndex() == 1)
{
parent.put(e, lightmap[v]);
break;
}
// else fallthrough to default
default:
parent.put(e, quadData[e][v]);
}
@@ -33,8 +33,7 @@ public class VertexLighterSmoothAo extends VertexLighterFlat
@Override
protected void updateLightmap(float[] normal, float[] lightmap, float x, float y, float z)
{
lightmap[0] = calcLightmap(blockInfo.getBlockLight(), x, y, z);
lightmap[1] = calcLightmap(blockInfo.getSkyLight(), x, y, z);
calcLightmap(lightmap, x, y, z);
}
@Override
@@ -47,7 +46,7 @@ public class VertexLighterSmoothAo extends VertexLighterFlat
color[2] *= a;
}
protected float calcLightmap(float[][][][] light, float x, float y, float z)
protected void calcLightmap(float[] lightmap, float x, float y, float z)
{
x *= 2;
y *= 2;
@@ -105,8 +104,12 @@ public class VertexLighterSmoothAo extends VertexLighterFlat
z *= s;
}
float l = 0;
float s = 0;
float[][][][] blockLight = blockInfo.getBlockLight();
float[][][][] skyLight = blockInfo.getSkyLight();
float bl = 0f;
float sl = 0f;
float s = 0f;
for(int ix = 0; ix <= 1; ix++)
{
@@ -124,26 +127,28 @@ public class VertexLighterSmoothAo extends VertexLighterFlat
float sz = vx + vy + 3;
float bx = (2 * vx + vy + vz + 6) / (s3 * sy * sz * (vx + 2));
s += bx;
l += bx * light[0][ix][iy][iz];
s += bx;
bl += bx * blockLight[0][ix][iy][iz];
sl += bx * skyLight[0][ix][iy][iz];
float by = (2 * vy + vz + vx + 6) / (s3 * sz * sx * (vy + 2));
s += by;
l += by * light[1][ix][iy][iz];
s += by;
bl += by * blockLight[1][ix][iy][iz];
sl += by * skyLight[1][ix][iy][iz];
float bz = (2 * vz + vx + vy + 6) / (s3 * sx * sy * (vz + 2));
s += bz;
l += bz * light[2][ix][iy][iz];
s += bz;
bl += bz * blockLight[2][ix][iy][iz];
sl += bz * skyLight[2][ix][iy][iz];
}
}
}
l /= s;
bl /= s;
sl /= s;
if(l > 15f * 0x20 / 0xFFFF) l = 15f * 0x20 / 0xFFFF;
if(l < 0) l = 0;
return l;
lightmap[0] = MathHelper.clamp(bl, 0f, 15f * 0x20 / 0xFFFF);
lightmap[1] = MathHelper.clamp(sl, 0f, 15f * 0x20 / 0xFFFF);
}
protected float getAo(float x, float y, float z)
@@ -443,9 +443,9 @@ public class BiomeDictionary
addTypes(Biomes.EXTREME_HILLS_WITH_TREES, MOUNTAIN, FOREST, SPARSE );
addTypes(Biomes.SAVANNA, HOT, SAVANNA, PLAINS, SPARSE );
addTypes(Biomes.SAVANNA_PLATEAU, HOT, SAVANNA, PLAINS, SPARSE, RARE );
addTypes(Biomes.MESA, MESA, SANDY );
addTypes(Biomes.MESA_ROCK, MESA, SPARSE, SANDY );
addTypes(Biomes.MESA_CLEAR_ROCK, MESA, SANDY );
addTypes(Biomes.MESA, MESA, SANDY, DRY );
addTypes(Biomes.MESA_ROCK, MESA, SANDY, DRY, SPARSE );
addTypes(Biomes.MESA_CLEAR_ROCK, MESA, SANDY, DRY );
addTypes(Biomes.VOID, VOID );
addTypes(Biomes.MUTATED_PLAINS, PLAINS, RARE );
addTypes(Biomes.MUTATED_DESERT, HOT, DRY, SANDY, RARE );
@@ -465,9 +465,9 @@ public class BiomeDictionary
addTypes(Biomes.MUTATED_EXTREME_HILLS_WITH_TREES, MOUNTAIN, SPARSE, RARE );
addTypes(Biomes.MUTATED_SAVANNA, HOT, DRY, SPARSE, SAVANNA, MOUNTAIN, RARE);
addTypes(Biomes.MUTATED_SAVANNA_ROCK, HOT, DRY, SPARSE, SAVANNA, HILLS, RARE);
addTypes(Biomes.MUTATED_MESA, HOT, DRY, SPARSE, SAVANNA, MOUNTAIN, RARE);
addTypes(Biomes.MUTATED_MESA, HOT, DRY, SPARSE, MOUNTAIN, RARE );
addTypes(Biomes.MUTATED_MESA_ROCK, HOT, DRY, SPARSE, HILLS, RARE );
addTypes(Biomes.MUTATED_MESA_CLEAR_ROCK, HOT, DRY, SPARSE, SAVANNA, MOUNTAIN, RARE);
addTypes(Biomes.MUTATED_MESA_CLEAR_ROCK, HOT, DRY, SPARSE, MOUNTAIN, RARE );
if (DEBUG)
@@ -22,7 +22,6 @@ package net.minecraftforge.common;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Hashtable;
import java.util.IdentityHashMap;
import java.util.List;
@@ -75,12 +74,13 @@ public class DimensionManager
}
private static boolean hasInit = false;
private static int lastUsedId = 0;
private static final Int2ObjectMap<WorldServer> worlds = Int2ObjectMaps.synchronize(new Int2ObjectLinkedOpenHashMap<>());
private static final Int2ObjectMap<Dimension> dimensions = Int2ObjectMaps.synchronize(new Int2ObjectLinkedOpenHashMap<>());
private static final IntSet keepLoaded = IntSets.synchronize(new IntOpenHashSet());
private static final IntSet unloadQueue = IntSets.synchronize(new IntLinkedOpenHashSet());
private static final BitSet dimensionMap = new BitSet(Long.SIZE << 4);
private static final IntSet usedIds = new IntOpenHashSet();
private static final ConcurrentMap<World, World> weakWorldMap = new MapMaker().weakKeys().weakValues().makeMap();
private static final Multiset<Integer> leakedWorlds = HashMultiset.create();
@@ -136,7 +136,7 @@ public class DimensionManager
dimensions.put(id, new Dimension(type));
if (id >= 0)
{
dimensionMap.set(id);
usedIds.add(id);
}
}
@@ -412,42 +412,38 @@ public class DimensionManager
* block of free ids. Always call for each individual ID you wish to get.
* @return the next free dimension ID
*/
public static int getNextFreeDimId() {
int next = 0;
while (true)
public static int getNextFreeDimId()
{
int next = lastUsedId;
while (usedIds.contains(next) || !checkAvailable(next))
{
next = dimensionMap.nextClearBit(next);
if (dimensions.containsKey(next))
{
dimensionMap.set(next);
}
else
{
return next;
}
next++;
}
return lastUsedId = next;
}
private static boolean checkAvailable(int id)
{
if (dimensions.containsKey(id))
{
usedIds.add(id);
return false;
}
return true;
}
public static NBTTagCompound saveDimensionDataMap()
{
int[] data = new int[(dimensionMap.length() + Integer.SIZE - 1 )/ Integer.SIZE];
NBTTagCompound dimMap = new NBTTagCompound();
for (int i = 0; i < data.length; i++)
{
int val = 0;
for (int j = 0; j < Integer.SIZE; j++)
{
val |= dimensionMap.get(i * Integer.SIZE + j) ? (1 << j) : 0;
}
data[i] = val;
}
dimMap.setIntArray("DimensionArray", data);
dimMap.setIntArray("UsedIDs", usedIds.toIntArray());
return dimMap;
}
public static void loadDimensionDataMap(@Nullable NBTTagCompound compoundTag)
{
dimensionMap.clear();
usedIds.clear();
lastUsedId = 0;
if (compoundTag == null)
{
IntIterator iterator = dimensions.keySet().iterator();
@@ -456,18 +452,26 @@ public class DimensionManager
int id = iterator.nextInt();
if (id >= 0)
{
dimensionMap.set(id);
usedIds.add(id);
}
}
}
else
{
for (int id : compoundTag.getIntArray("UsedIDs"))
{
usedIds.add(id);
}
// legacy data (load but don't save)
int[] intArray = compoundTag.getIntArray("DimensionArray");
for (int i = 0; i < intArray.length; i++)
{
int data = intArray[i];
if (data == 0) continue;
for (int j = 0; j < Integer.SIZE; j++)
{
dimensionMap.set(i * Integer.SIZE + j, (intArray[i] & (1 << j)) != 0);
if ((data & (1 << j)) != 0) usedIds.add(i * Integer.SIZE + j);
}
}
}
@@ -0,0 +1,174 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.common;
import com.google.common.base.Preconditions;
import com.google.common.collect.MapMaker;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.common.ticket.AABBTicket;
import net.minecraftforge.common.ticket.ChunkTicketManager;
import net.minecraftforge.common.ticket.SimpleTicket;
import net.minecraftforge.fml.common.FMLLog;
import java.util.*;
public class FarmlandWaterManager
{
private static boolean DEBUG = Boolean.parseBoolean(System.getProperty("forge.debugFarmlandWaterManager", "false"));
private static final Int2ObjectMap<Map<ChunkPos, ChunkTicketManager<Vec3d>>> customWaterHandler = new Int2ObjectOpenHashMap<>();
@Deprecated
public static<T extends SimpleTicket<Vec3d>> T addCustomTicket(World world, T ticket, ChunkPos... chunkPoses)
{
return addCustomTicket(world, ticket, chunkPoses[0], Arrays.copyOfRange(chunkPoses, 1, chunkPoses.length));
}
/**
* Adds a custom ticket.
* Use {@link #addAABBTicket(World, AxisAlignedBB)} if you just need a ticket that can water a certain area.
* <br>
* If you don't want to water the region anymore, call {@link SimpleTicket#invalidate()}. Also call this
* when the region this is unloaded (e.g. your TE is unloaded or the block is removed), and validate once it is loaded
* @param world The world where the region should be marked. Only server-side worlds are allowed
* @param ticket Your ticket you want to have registered
* @param masterChunk The chunk pos that is controls when the ticket may be unloaded. The ticket should originate from here.
* @param additionalChunks The chunks in that this ticket wants to operate as well.
* @return The ticket for your requested region.
*/
@SuppressWarnings("unchecked")
public static<T extends SimpleTicket<Vec3d>> T addCustomTicket(World world, T ticket, ChunkPos masterChunk, ChunkPos... additionalChunks)
{
Preconditions.checkArgument(!world.isRemote, "Water region is only determined server-side");
Map<ChunkPos, ChunkTicketManager<Vec3d>> ticketMap = customWaterHandler.computeIfAbsent(world.provider.getDimension(), id -> new MapMaker().weakValues().makeMap());
ChunkTicketManager<Vec3d>[] additionalTickets = new ChunkTicketManager[additionalChunks.length];
for (int i = 0; i < additionalChunks.length; i++)
additionalTickets[i] = ticketMap.computeIfAbsent(additionalChunks[i], ChunkTicketManager::new);
ticket.setManager(ticketMap.computeIfAbsent(masterChunk, ChunkTicketManager::new), additionalTickets);
ticket.validate();
return ticket;
}
/**
* Convenience method to add a ticket that is backed by an AABB.
* <br>
* If you don't want to water the region anymore, call {@link SimpleTicket#invalidate()}. Also call this
* when the region this is unloaded (e.g. your TE is unloaded or the block is removed), and validate once it is loaded
* <br>
* The AABB in the ticket is immutable
* @param world The world where the region should be marked. Only server-side worlds are allowed
* @param aabb The region where blocks should be watered
* @return The ticket for your requested region.
*/
public static AABBTicket addAABBTicket(World world, AxisAlignedBB aabb)
{
if (DEBUG)
FMLLog.log.info("FarmlandWaterManager: New AABBTicket, aabb={}", aabb);
//First calculate all chunks the aabb is in
ChunkPos leftUp = new ChunkPos(((int) aabb.minX) >> 4, ((int) aabb.minZ) >> 4);
ChunkPos rightDown = new ChunkPos(((int) aabb.maxX) >> 4, ((int) aabb.maxZ) >> 4);
Set<ChunkPos> posSet = new HashSet<>();
for (int x = leftUp.x; x <= rightDown.x; x++)
{
for (int z = leftUp.z; z <= rightDown.z; z++)
{
posSet.add(new ChunkPos(x, z));
}
}
ChunkPos masterPos = null;
double masterDistance = Double.MAX_VALUE;
for (ChunkPos pos : posSet) //Find the chunkPos with the lowest distance to the center and choose it as the master pos
{
//basically pos.getCenter but it is Client Side Only in 1.12
Vec3d center = new Vec3d(aabb.minX + (aabb.maxX - aabb.minX) * 0.5D, aabb.minY + (aabb.maxY - aabb.minY) * 0.5D, aabb.minZ + (aabb.maxZ - aabb.minZ) * 0.5D);
double distToCenter = getDistanceSq(pos, center);
if (distToCenter < masterDistance)
{
if (DEBUG)
FMLLog.log.info("FarmlandWaterManager: New better pos then {}: {}, prev dist {}, new dist {}", masterPos, pos, masterDistance, distToCenter);
masterPos = pos;
masterDistance = distToCenter;
}
}
posSet.remove(masterPos);
if (DEBUG)
FMLLog.log.info("FarmlandWaterManager: {} center pos, {} dummy posses. Dist to center {}", masterPos, posSet.toArray(new ChunkPos[0]), masterDistance);
return addCustomTicket(world, new AABBTicket(aabb), masterPos, posSet.toArray(new ChunkPos[0]));
}
private static double getDistanceSq(ChunkPos pos, Vec3d vec3d)
{
//See ChunkPos#getDistanceSq
double d0 = (double)(pos.x * 16 + 8);
double d1 = (double)(pos.z * 16 + 8);
double d2 = d0 - vec3d.x;
double d3 = d1 - vec3d.z;
return d2 * d2 + d3 * d3;
}
/**
* Tests if a block is in a region that is watered by blocks. This does not check vanilla water, see {@link net.minecraft.block.BlockFarmland#hasWater(World, BlockPos)}
* @return true if there is a ticket with an AABB that includes your block
*/
public static boolean hasBlockWaterTicket(World world, BlockPos pos)
{
ChunkTicketManager<Vec3d> ticketManager = getTicketManager(new ChunkPos(pos.getX() >> 4, pos.getZ() >> 4), world);
if (ticketManager != null)
{
//make the vec3d originate in the center of the block
Vec3d posAsVec3d = new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5);
for (SimpleTicket<Vec3d> ticket : ticketManager.getTickets()) {
if (ticket.matches(posAsVec3d))
return true;
}
}
return false;
}
static void removeTickets(Chunk chunk)
{
ChunkTicketManager<Vec3d> ticketManager = getTicketManager(chunk.getPos(), chunk.getWorld());
if (ticketManager != null)
{
if (DEBUG)
FMLLog.log.info("FarmlandWaterManager: got tickets {} at {} before", ticketManager.getTickets().size(), ticketManager.pos);
ticketManager.getTickets().removeIf(next -> next.unload(ticketManager)); //remove if this is the master manager of the ticket
if (DEBUG)
FMLLog.log.info("FarmlandWaterManager: got tickets {} at {} after", ticketManager.getTickets().size(), ticketManager.pos);
}
}
private static ChunkTicketManager<Vec3d> getTicketManager(ChunkPos pos, World world)
{
Preconditions.checkArgument(!world.isRemote, "Water region is only determined server-side");
Map<ChunkPos, ChunkTicketManager<Vec3d>> ticketMap = customWaterHandler.get(world.provider.getDimension());
if (ticketMap == null)
{
return null;
}
return ticketMap.get(pos);
}
}
@@ -22,6 +22,7 @@ package net.minecraftforge.common;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
@@ -29,6 +30,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.WeakHashMap;
import javax.annotation.Nullable;
@@ -104,7 +106,7 @@ public class ForgeChunkManager
private static Map<String, LoadingCallback> callbacks = Maps.newHashMap();
private static Map<World, ImmutableSetMultimap<ChunkPos,Ticket>> forcedChunks = new MapMaker().weakKeys().makeMap();
private static Map<World, ImmutableSetMultimap<ChunkPos,Ticket>> forcedChunks = Collections.synchronizedMap(new WeakHashMap<>());
private static BiMap<UUID,Ticket> pendingEntities = HashBiMap.create();
private static Map<World,Cache<Long, ChunkEntry>> dormantChunkCache = new MapMaker().weakKeys().makeMap();
@@ -585,8 +587,8 @@ public class ForgeChunkManager
}
if (tickets.size() > maxTicketLength)
{
FMLLog.log.warn("The mod {} has too many open chunkloading tickets {}. Excess will be dropped", modId, tickets.size());
tickets.subList(maxTicketLength, tickets.size()).clear();
FMLLog.log.warn("The mod {} has too many open chunkloading tickets: {} (max: {}). Excess will be dropped.", modId, tickets.size(), maxTicketLength);
tickets = tickets.subList(0, maxTicketLength);
}
ForgeChunkManager.tickets.get(world).putAll(modId, tickets);
loadingCallback.ticketsLoaded(ImmutableList.copyOf(tickets), world);
@@ -613,13 +615,14 @@ public class ForgeChunkManager
static void unloadWorld(World world)
{
forcedChunks.remove(world);
// World save fires before this event so the chunk loading info will be done
if (!(world instanceof WorldServer))
{
return;
}
forcedChunks.remove(world);
if (dormantChunkCacheSize != 0) // only if in use
{
dormantChunkCache.remove(world);
@@ -888,7 +891,9 @@ public class ForgeChunkManager
*/
public static ImmutableSetMultimap<ChunkPos, Ticket> getPersistentChunksFor(World world)
{
return forcedChunks.containsKey(world) ? forcedChunks.get(world) : ImmutableSetMultimap.of();
if (world.isRemote) return ImmutableSetMultimap.of();
ImmutableSetMultimap<ChunkPos, Ticket> persistentChunks = forcedChunks.get(world);
return persistentChunks != null ? persistentChunks : ImmutableSetMultimap.of();
}
static void saveWorld(World world)
@@ -81,6 +81,7 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.NetHandlerPlayServer;
import net.minecraft.network.Packet;
import net.minecraft.network.datasync.DataSerializer;
import net.minecraft.network.play.server.SPacketBlockChange;
import net.minecraft.network.play.server.SPacketRecipeBook;
import net.minecraft.network.play.server.SPacketRecipeBook.State;
@@ -93,6 +94,7 @@ import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.IntIdentityHashBiMap;
import net.minecraft.util.JsonUtils;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
@@ -115,6 +117,7 @@ import net.minecraft.world.storage.loot.LootTable;
import net.minecraft.world.storage.loot.LootTableManager;
import net.minecraft.world.storage.loot.conditions.LootCondition;
import net.minecraftforge.common.crafting.CraftingHelper;
import net.minecraftforge.common.crafting.JsonContext;
import net.minecraftforge.common.util.BlockSnapshot;
import net.minecraftforge.event.AnvilUpdateEvent;
import net.minecraftforge.event.DifficultyChangeEvent;
@@ -146,11 +149,14 @@ import net.minecraftforge.fml.common.FMLLog;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.LoaderState;
import net.minecraftforge.fml.common.ModContainer;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import net.minecraftforge.fml.common.eventhandler.Event;
import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher;
import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.ConnectionType;
import net.minecraftforge.fml.common.registry.ForgeRegistries;
import net.minecraftforge.fml.relauncher.ReflectionHelper;
import net.minecraftforge.registries.DataSerializerEntry;
import net.minecraftforge.registries.ForgeRegistry;
import net.minecraftforge.registries.GameData;
import net.minecraftforge.registries.IForgeRegistry;
import net.minecraftforge.registries.RegistryManager;
@@ -195,6 +201,15 @@ public class ForgeHooks
return entry.getStack(rand, fortune);
}
public static boolean canContinueUsing(@Nonnull ItemStack from, @Nonnull ItemStack to)
{
if (!from.isEmpty() && !to.isEmpty())
{
return from.getItem().canContinueUsing(from, to);
}
return false;
}
private static boolean toolInit = false;
//static HashSet<List> toolEffectiveness = new HashSet<List>();
@@ -270,19 +285,19 @@ public class ForgeHooks
}
toolInit = true;
Set<Block> blocks = ReflectionHelper.getPrivateValue(ItemPickaxe.class, null, 0);
Set<Block> blocks = ObfuscationReflectionHelper.getPrivateValue(ItemPickaxe.class, null, "field_150915"+"_c");
for (Block block : blocks)
{
block.setHarvestLevel("pickaxe", 0);
}
blocks = ReflectionHelper.getPrivateValue(ItemSpade.class, null, 0);
blocks = ObfuscationReflectionHelper.getPrivateValue(ItemSpade.class, null, "field_150916"+"_c");
for (Block block : blocks)
{
block.setHarvestLevel("shovel", 0);
}
blocks = ReflectionHelper.getPrivateValue(ItemAxe.class, null, 0);
blocks = ObfuscationReflectionHelper.getPrivateValue(ItemAxe.class, null, "field_150917"+"_c");
for (Block block : blocks)
{
block.setHarvestLevel("axe", 0);
@@ -330,7 +345,6 @@ public class ForgeHooks
return new ItemStack(Items.WHEAT_SEEDS, 1 + rand.nextInt(fortune * 2 + 1));
}
});
initTools();
}
/**
@@ -788,9 +802,8 @@ public class ForgeHooks
link.getStyle().setUnderlined(true);
link.getStyle().setColor(TextFormatting.BLUE);
if (ichat == null)
ichat = link;
else
ichat.appendSibling(link);
ichat = new TextComponentString("");
ichat.appendSibling(link);
}
// Append the rest of the message.
@@ -1304,9 +1317,10 @@ public class ForgeHooks
public static boolean loadAdvancements(Map<ResourceLocation, Advancement.Builder> map)
{
CraftingHelper.init();
boolean errored = false;
setActiveModContainer(null);
//Loader.instance().getActiveModList().forEach((mod) -> loadFactories(mod));
Loader.instance().getActiveModList().forEach(ForgeHooks::loadFactories);
for (ModContainer mod : Loader.instance().getActiveModList())
{
errored |= !loadAdvancements(map, mod);
@@ -1315,6 +1329,11 @@ public class ForgeHooks
return errored;
}
private static void loadFactories(ModContainer mod)
{
CraftingHelper.loadFactories(mod, "assets/" + mod.getModId() + "/advancements", CraftingHelper.CONDITIONS);
}
@Nullable
public static CriticalHitEvent getCriticalHit(EntityPlayer player, Entity target, boolean vanillaCritical, float damageModifier)
{
@@ -1335,6 +1354,8 @@ public class ForgeHooks
private static boolean loadAdvancements(Map<ResourceLocation, Advancement.Builder> map, ModContainer mod)
{
JsonContext ctx = new JsonContext(mod.getModId());
return CraftingHelper.findFiles(mod, "assets/" + mod.getModId() + "/advancements", null,
(root, file) ->
{
@@ -1353,7 +1374,11 @@ public class ForgeHooks
try
{
reader = Files.newBufferedReader(file);
Advancement.Builder builder = JsonUtils.fromJson(AdvancementManager.GSON, reader, Advancement.Builder.class);
String contents = IOUtils.toString(reader);
JsonObject json = JsonUtils.gsonDeserialize(CraftingHelper.GSON, contents, JsonObject.class);
if (!CraftingHelper.processConditions(json, "conditions", ctx))
return true;
Advancement.Builder builder = JsonUtils.gsonDeserialize(AdvancementManager.GSON, contents, Advancement.Builder.class);
map.put(key, builder);
}
catch (JsonParseException jsonparseexception)
@@ -1462,4 +1487,29 @@ public class ForgeHooks
return false;
}
private static final Map<DataSerializer<?>, DataSerializerEntry> serializerEntries = GameData.getSerializerMap();
private static final ForgeRegistry<DataSerializerEntry> serializerRegistry = (ForgeRegistry<DataSerializerEntry>) ForgeRegistries.DATA_SERIALIZERS;
@Nullable
public static DataSerializer<?> getSerializer(int id, IntIdentityHashBiMap<DataSerializer<?>> vanilla)
{
DataSerializer<?> serializer = vanilla.get(id);
if (serializer == null)
{
DataSerializerEntry entry = serializerRegistry.getValue(id);
if (entry != null) serializer = entry.getSerializer();
}
return serializer;
}
public static int getSerializerId(DataSerializer<?> serializer, IntIdentityHashBiMap<DataSerializer<?>> vanilla)
{
int id = vanilla.getId(serializer);
if (id < 0)
{
DataSerializerEntry entry = serializerEntries.get(serializer);
if (entry != null) id = serializerRegistry.getID(entry);
}
return id;
}
}
@@ -26,9 +26,9 @@ import net.minecraft.item.ItemStack;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.util.FakePlayerFactory;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.event.world.ChunkEvent;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.fml.client.FMLClientHandler;
import net.minecraftforge.fml.common.FMLLog;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
@@ -96,5 +96,12 @@ public class ForgeInternalHandler
if (event.phase == Phase.END)
FMLClientHandler.instance().updateCloudSettings();
}
@SubscribeEvent
public void onChunkUnload(ChunkEvent.Unload event)
{
if (!event.getWorld().isRemote)
FarmlandWaterManager.removeTickets(event.getChunk());
}
}
Loaded 100 of 204 files, more files were not shown because too many files have changed in this diff. Show more