New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
2nd attempt [1.12.x] Custom Fluids Behave Like Water #4619
Conversation
…orge into 1.12.x-fluidbehavior
Squashed commits: [aa1ffae53] Patches look clean. Ready for pull request.
I know the Forge folks are busy, but I'd like to make a case to get this PR implemented soon as there are a lot of other fluid-related PRs pending such as fluid sounds, fluid place events, fluid ingredients, fluids as fuels, and so forth. For the most part I don't think there are a lot of conflicts, in those other PRs but as my PR is the most far-reaching it will provide a good foundation for the rest. and should probably be implemented first. I know other priorities like 1.13 are looming, but the sheer number of PRs related to fluids seems to indicate a healthy interest in the modding community which would be nice to fulfill sooner than later. Thanks! |
@@ -1456,7 +1461,7 @@ | |||
+ @SideOnly (Side.CLIENT) | |||
+ public Vec3d getFogColor(World world, BlockPos pos, IBlockState state, Entity entity, Vec3d originalColor, float partialTicks) | |||
+ { | |||
+ if (state.func_185904_a() == Material.field_151586_h) | |||
+ if (state.func_185904_a().isLiquidOtherThanLava()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's out-of-scope for this PR, but this is the place I really, really, really want to be replaced with state.func_185904_a().getFogColor()
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean? The fog color when you're inside a fluid already changes to the fluid color. I submitted a separate PR for this recently.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #4462
As a modder who has spend hours on getting our fluids to even remotely behaving like water without all the bugs you get from being water, I really like this. Just one thing I noticed: isSwimmable() is used both for allowing an entity to swim and for the AI to route into the liquid, isn't it? I think there should be a difference between the two things as there are liquids you can swim in but that do damage you when you do. |
Okay, that is a good suggestion. Most of my work was of course replicating water capabilities, but the tricky thing was how to handle lava-like (meaning ones that damage). Even though both are technically liquids, lava really only has a couple behaviors like water. So in the few places in vanilla code where lava was called out I have a method to distinguish (liquid other than lava). However, your request makes me wonder if maybe there are any other lava-like properties that should be teased apart more specifically. Let me look. Thanks for the feedback. Please help test if you can -- need to confirm that vanilla liquids still behave as expected in addition to being to fully customize our own fluids. |
Looking at it further, the isSwimmable() I implemented is really about path navigation. The ability to swim in a fluid is the same for all fluids. I think this is the right thing to do (for now). Now arguably you might want something else to happen but frankly there is no vanilla movement mechanism for a liquid you can't swim in. The Fluid system tries to allow for gases though, but as mentioned in other Issue submissions the isGaseous is pretty broken. We really need a major overhaul to get that to work. You can also argue that based on physics the density and viscosity of the fluid should be considered for swimming. But again someone would have to come up with a whole new movement mechanism. Like should you sink faster in low density fluids? Would high density fluids automatically float you? Swim slower in high viscosity fluids? So, at this point my PR has all fluids allow for swimming movement. The isSwimmable() method is meant to indicate the fluid should be allowed for swimming path finding. I think gases and alternative physics for swimming in different densities would be really cool. But I highly recommend we leave that to a separate PR. |
I'm fine with it as it is, just, plz, adapt the JavaDoc? |
Okay, I'll update the java doc to clarify what "swimmable" means in the morning. |
Dang it, people keep pushing liquid-related PRs while my overhaul is pending. I'll resolve the merge conflicts when I get a chance over the next day or so. |
There's quite a bit of fluid related PRs and others that are waiting to be merged, but can this be merged soon since a lot of people are waiting for this. |
Certainly interested in feedback and having people try it. I'll also try to resolve conflicts this week. |
# Conflicts: # patches/minecraft/net/minecraft/block/Block.java.patch # patches/minecraft/net/minecraft/block/BlockLiquid.java.patch # patches/minecraft/net/minecraft/client/renderer/ActiveRenderInfo.java.patch # patches/minecraft/net/minecraft/client/renderer/EntityRenderer.java.patch # patches/minecraft/net/minecraft/entity/EntityLivingBase.java.patch # patches/minecraft/net/minecraft/world/WorldEntitySpawner.java.patch # src/main/java/net/minecraftforge/common/ForgeHooks.java
i want to express how this sounds like a very good pr to me, it's very smart, has clear purpose and author is really trying to improve something even though he is ignored for 8 months and still has good will, that's tremendous. |
This is a massive overhaul that needs more people's input. Moving down the diffs so this is more of a train of thoughts: https://github.com/MinecraftForge/MinecraftForge/pull/4619/files#diff-81128f9af712143e66ecac33b43ebd31R20 Could also use a note somewhere saying you change this, a seperate PR to fix this bug? |
Hey Lex, thanks for the detailed consideration. Yes, definitely a fairly big thing so needs input/testing. High Level Discussion Points There are a lot of reasons to not use WATER material, but best reason is that there are lots of fluids people want to do that shouldn't replicate all the behavior. Imagine something like gasoline that that you want to flow and push you like water, but don't want it to nourish plants, put out fire, or have fish in it. Most things you might want to do can probably be done with creative coding, however the most difficult thing is having the fluid push you like water. To replicate that you have to do a bunch of event handling including reflection and copying extensive portions of vanilla behavior. You can get the pushing by simply making the material WATER, but then you get everything else that water gets. Implementation Style Comments I agree about the issue with my setters causing post-constructor changes. While functionally I think that would be safe to allow it does seem counter to the idea of representing a physical property. I was mainly trying to avoid needing complicated constructors. So you're right a builder system would be better. Let me see about implementing that (I'm not that familiar with doing that, but will check out the builders you all have been adding lately). Alternatively, probably easy to create a locking system. Regarding why there are separate functions for everything instead of saying "canHydrate()" is because there are lots of examples where you don't want it all to come together. Fluids are not all water-like. Functional Points To Discuss Regarding whether there is a case where fluids wouldn't push entities, there is the bigger discussion about how the Fluid system represents density to the point of gasses and such. For example, I would say that if you wanted to use the system to create a "dry ice" like fog that flows like a liquid you wouldn't want it to push you. If there was a full API for heavier-than-air gasses then you could argue that most/all fluids should push. I like your idea of returning a push force though. For isSwimmable, I like your idea of returning PathNodeType, but I'll need to see where that would hook in. Will definitely look at doing that. Regarding sponge absorption holding more than water, that is definitely something I would have liked to have implemented, but seemed like a big thing on its own. I guess there would need to be a "universal sponge" similar to the universal bucket concept. So on a "to do" list. The canFreeze() is easier than the sponge problem because the result of freezing would clearly be a distinct block -- I like your idea of having way of associating fluids with their "frozen" version. Bit of work but would be worth it. It had been on my "to do" as well. For something like the canFloatBoat() your feedback is good -- the actual boat type should be passed in and therefore you could conditionally float it. Let me look at doing that. For the canDrownEntity() flipping to canBreath() based on material is a good idea. I'll implement that. Whether you can fish in a fluid can certainly be separated out from canSpawnWaterCreatures(). Since fish themselves aren't really an entity on their own, I kinda figured "wherever there are water creatures you can probably fish". But easy enough to separate. I do like the idea of having ability to adjust fishing loot tables based on the fluid so I'll look at that. Conclusion I appreciate your time on giving feedback. I'm willing to code up almost all the above, however as you mentioned with 1.13 coming maybe I should just reset/wait and see about re-implementing after that? |
This pull request has been automatically marked as stale because it has not had recent activity, and will be closed if no further activity occurs. If this pull request was overlooked, forgotten, or should remain open for any other reason, please reply here to call attention to it and remove the stale status. Thank you for your contributions. |
Not stale, give it more time... |
This pull request has been automatically marked as stale because it has not had recent activity, and will be closed if no further activity occurs. If this pull request was overlooked, forgotten, or should remain open for any other reason, please reply here to call attention to it and remove the stale status. Thank you for your contributions. |
not stale |
This pull request has been automatically marked as stale because it has not had recent activity, and will be closed if no further activity occurs. If this pull request was overlooked, forgotten, or should remain open for any other reason, please reply here to call attention to it and remove the stale status. Thank you for your contributions. |
I think 1.13 is coming closer... |
1 similar comment
I think 1.13 is coming closer... |
This should probably be tagged for 1.14, as most fluid stuff is being delayed until then, due to Mojang's rewrite. |
Yeah - 1.13 is more like a "stepping stone" version than a version to really play on. |
It is a bit of a catch-22 that the largest PRs that take the most work to maintain are the ones that stay open for comments the longest. There's not much that can be done to fix that. As it stands this PR has bad merges in the patch files, and has had little input/review other than the same 3 people. It feels like a bit late in the 1.12 lifecycle to merge such a large overhaul. It might be time to consider targeting 1.13. While a lot of the fluid system is WIP in 1.13, the actual interaction with entities is pretty similar AFAIK. |
The suggested feature of custom loot tables for fluid materials would be really useful imho |
This pull request has been automatically marked as stale because it has not had recent activity, and will be closed if no further activity occurs. If this pull request was overlooked, forgotten, or should remain open for any other reason, please reply here to call attention to it and remove the stale status. Thank you for your contributions. |
This pull request has been automatically closed because it has not had recent activity. Please feel free to update or reopen it. |
Preface: This is a 2nd attempt, superseding #4478. After some failed attempts at rebasing (which wiped out my changes to vanilla classes) plus some further changes I wanted to make, I had to start new fork and do a significant re-write. I apologize to those who spent time reviewing the last one, although this PR ultimately is much the same.
Background: Custom fluids do not naturally do water-like things such as drown entities, push entities along with flow, water plants, float boats, etc. This PR addresses all these behaviors. The reason it hadn't been done previously is because Material.WATER was hard-coded throughout the vanilla code, so needs a patch for every behavior. Each patch is very simple, but water does a lot of stuff which is why so many files are affected.
Implementation Approach:
Material class has several added properties to reflect each waterlike behavior, along with setter and getter. Eg. setCanDrownEntity(). All default to false and existing liquids WATER and LAVA are set appropriately so this is entirely non-breaking.
Almost everywhere there is a check for Material.WATER was called, it is replaced with appropriate material property getter. There are a few exceptions for things related specifically to BlockLiquid as that class explicitly only handles WATER and LAVA (since custom "liquids" should use the fluid system).
The isInsideMaterial() method is replaced with some targeted ForgeHooks versions that pass a predicate instead (for test against the material property). So you can test if you're inside a drownable material, a material that can float a boat, etc. Note that there is one method that tests the entity's head and another that tests the entire bounding box.
Features Implemented:
Features Not Implemented (Possible Future Enhancements):
Testing:
Summary:
I know this is a big PR, but the logic is pretty simple and it provides a LOT of functionality with good modder control.