-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
LivingBreatheEvent and LivingDrownEvent #7810
LivingBreatheEvent and LivingDrownEvent #7810
Conversation
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.
Question for you: why do you need three events to handle this logic? I'm pretty sure this could be done in a single cancelable event. For example, if the event is canceled, execute Forge logic where it checks if it can or can not breathe and then sets the amount. Calling three events every tick for something that could be done in one seems resource consuming.
+ boolean flag2 = this.func_208600_a(FluidTags.field_206959_a) && !this.field_70170_p.func_180495_p(new BlockPos(this.func_226277_ct_(), this.func_226280_cw_(), this.func_226281_cx_())).func_203425_a(Blocks.field_203203_C); | ||
+ | ||
+ if (flag2 && !this.field_70170_p.field_72995_K && this.func_184218_aH() && this.func_184187_bx() != null && !this.func_184187_bx().canBeRiddenInWater(this)) { | ||
+ this.func_184210_p(); | ||
+ } | ||
+ | ||
+ boolean canBreathe = !flag2 || this.func_70648_aU() || EffectUtils.func_205133_c(this) || flag1; | ||
+ net.minecraftforge.event.entity.living.LivingBreatheEvent event = new net.minecraftforge.event.entity.living.LivingBreatheEvent(this, canBreathe); | ||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); | ||
+ | ||
+ if (!event.isCanBreathe()) { | ||
+ net.minecraftforge.event.entity.living.LivingConsumeAirEvent event1 = new net.minecraftforge.event.entity.living.LivingConsumeAirEvent(this, -this.func_70682_h(0)); | ||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event1); | ||
+ this.func_70050_g(MathHelper.func_76125_a(this.func_70086_ai() - event1.getAmount(), -20, this.func_205010_bg())); | ||
+ | ||
+ if (this.func_70086_ai() == -20) { | ||
+ this.func_70050_g(0); | ||
+ Vector3d vector3d = this.func_213322_ci(); | ||
+ | ||
+ for (int i = 0; i < 8; ++i) { | ||
+ double d2 = this.field_70146_Z.nextDouble() - this.field_70146_Z.nextDouble(); | ||
+ double d3 = this.field_70146_Z.nextDouble() - this.field_70146_Z.nextDouble(); | ||
+ double d4 = this.field_70146_Z.nextDouble() - this.field_70146_Z.nextDouble(); | ||
+ this.field_70170_p.func_195594_a(ParticleTypes.field_197612_e, this.func_226277_ct_() + d2, this.func_226278_cu_() + d3, this.func_226281_cx_() + d4, vector3d.field_72450_a, vector3d.field_72448_b, vector3d.field_72449_c); |
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.
This is really invasive. You do not need this much of a rewrite to handle this logic. You can simply add the event below #isAlive, post it, and then store the result in the flag to pass into multiple places. You also reverse the logic of when the entity stops riding which in vanilla's case doesn't break behavior but could in other mods. You can also use ForgeHooks
to handle the actual event creation bring this down to just three lines added with a few more modified.
src/test/java/net/minecraftforge/debug/entity/living/LivingAirEventTest.java
Outdated
Show resolved
Hide resolved
src/main/java/net/minecraftforge/event/entity/living/LivingBreatheEvent.java
Show resolved
Hide resolved
src/main/java/net/minecraftforge/event/entity/living/LivingBreatheEvent.java
Outdated
Show resolved
Hide resolved
src/main/java/net/minecraftforge/event/entity/living/LivingConsumeAirEvent.java
Outdated
Show resolved
Hide resolved
src/main/java/net/minecraftforge/event/entity/living/LivingRefillAirEvent.java
Outdated
Show resolved
Hide resolved
src/test/java/net/minecraftforge/debug/entity/living/LivingAirEventTest.java
Outdated
Show resolved
Hide resolved
src/test/java/net/minecraftforge/debug/entity/living/LivingBreatheEventTest.java
Show resolved
Hide resolved
+ net.minecraftforge.event.entity.living.LivingRefillAirEvent event1 = new net.minecraftforge.event.entity.living.LivingRefillAirEvent(this, this.func_207300_l(0)); | ||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event1); | ||
+ this.func_70050_g(MathHelper.func_76125_a(this.func_70086_ai() + event1.getAmount(), -20, this.func_205010_bg())); |
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.
Same applies here that this could all go in ForgeHooks
to reduce the amount of calls.
} else if (this.func_70086_ai() < this.func_205010_bg()) { | ||
- } else if (this.func_70086_ai() < this.func_205010_bg()) { | ||
- this.func_70050_g(this.func_207300_l(this.func_70086_ai())); | ||
+ } else { |
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.
Fires event unnecessarily. The point of the event is to refill. If you are not or your air meter is full, you should have no reason to fire the event.
So I formatted the forge classes and added the missing license headers.
This is basically the vanilla code: if (isUnderWater && !notInBubbleColumn) {
if (!canBreatheUnderwater && !hasWaterBreathing && !damageIsDisabled) {
// consume air
}
// check if vehicle can be ridden underwater
} else if (air < maxAir) {
// refill air
} So to insert the events the only way I could think of was to:
You are free to help me making this less invasive though I didn't see a way to keep the original structure in tact. Which is the reason why it is how it is now.
(two events every tick not three)
As described above |
You can just create a method within
But...that would never do anything. This is why I said the three event calls could be reduced down to one. That one event would be cancelable and set if the user can breathe and the amount to add/remove. When canceled, the event will execute the forge data retrieved from the event. |
Hm I guess this could work. |
You should always do the least amount of lines added/modified as possible within the vanilla class. |
So I update this again. Now it is only one event which is fired inside a ForgeHooks method and thus the changes required to the vanilla class are very small now. |
Hello! @Meldexun, please leave a comment whether you wish to continue this PR and update it to the latest active version of 1.18 (or leave an explanation why this PR's changes are not applicable to 1.18). If we do not hear back from you after some time, this PR will be closed for inactivity. |
Hi, yes I would like to continue this PR. I have created a new branch in my fork for MC 1.18 https://github.com/Meldexun/MinecraftForge/tree/living-breathe-event-1.18. So how should I proceed now? Should I create a new pull request? |
@Meldexun, you have two options here:
|
dc6f6a5
to
09585de
Compare
…d add living drown event
I updated everything to MC 1.18 now. Also I moved pretty much all changes into the |
This may be easier to implement in 1.19 with the new fluid API. I'm going to close this old one for inactivity (which is entirely our fault!) and we can continue if you'd like in a new PR. |
This PR adds three new events to allow modders to control if a living entity can breathe and how air is consumed/refilled.
With the LivingBreatheEvent modders could easily prevent players from breathing in something like a moon dimension or allow players to breathe everywhere while wearing a specific item.
Withe the LivingConsumeAirEvent and LivingRefillAirEvent modders could change how air is consumed/refilled or add an item which can hold air which will be refilled when the players air is full.
Currently a problem could be something like this:
When a modder adds a moon dimension where the player can't breathe then he has to revert the refilling of the air supply and the make the player consume air. This would be a lot cleaner and compatibility between mods would be easier to achieve with the LivingBreatheEvent.
I also added two test mods which each add an item with make usage of the events.