Skip to content
This repository was archived by the owner on Jun 3, 2024. It is now read-only.

Commit a7d1dd3

Browse files
authored
Merge pull request #33 from IceCryptonym/master
LivingFallEvent and PlayerFlyableFallEvent
2 parents aca009f + 14e807e commit a7d1dd3

5 files changed

Lines changed: 185 additions & 0 deletions

File tree

patchwork-events-entity/src/main/java/com/patchworkmc/impl/event/entity/EntityEvents.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@
2828
import net.minecraftforge.event.entity.living.LivingDamageEvent;
2929
import net.minecraftforge.event.entity.living.LivingSpawnEvent;
3030
import net.minecraftforge.event.entity.living.LivingEvent;
31+
import net.minecraftforge.event.entity.living.LivingFallEvent;
3132
import net.minecraftforge.event.entity.player.PlayerEvent;
33+
import net.minecraftforge.event.entity.player.PlayerFlyableFallEvent;
3234
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
3335
import net.minecraftforge.eventbus.api.Event;
3436
import net.minecraftforge.eventbus.api.Event.Result;
@@ -93,6 +95,15 @@ public static float onLivingHurt(LivingEntity entity, DamageSource src, float da
9395
return MinecraftForge.EVENT_BUS.post(event) ? 0 : event.getAmount();
9496
}
9597

98+
public static float[] onLivingFall(LivingEntity entity, float distance, float damageMultiplier) {
99+
LivingFallEvent event = new LivingFallEvent(entity, distance, damageMultiplier);
100+
return MinecraftForge.EVENT_BUS.post(event) ? null : new float[]{ event.getDistance(), event.getDamageMultiplier() };
101+
}
102+
103+
public static void onFlyablePlayerFall(PlayerEntity player, float distance, float damageMultiplier) {
104+
MinecraftForge.EVENT_BUS.post(new PlayerFlyableFallEvent(player, distance, damageMultiplier));
105+
}
106+
96107
public static float onLivingDamage(LivingEntity entity, DamageSource src, float damage) {
97108
LivingDamageEvent event = new LivingDamageEvent(entity, src, damage);
98109
return MinecraftForge.EVENT_BUS.post(event) ? 0 : event.getAmount();

patchwork-events-entity/src/main/java/com/patchworkmc/mixin/event/entity/MixinLivingEntity.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
package com.patchworkmc.mixin.event.entity;
2121

2222
import org.spongepowered.asm.mixin.Mixin;
23+
import org.spongepowered.asm.mixin.Unique;
2324
import org.spongepowered.asm.mixin.injection.At;
2425
import org.spongepowered.asm.mixin.injection.Inject;
2526
import org.spongepowered.asm.mixin.injection.ModifyVariable;
@@ -33,6 +34,9 @@
3334

3435
@Mixin(LivingEntity.class)
3536
public class MixinLivingEntity {
37+
@Unique
38+
private float[] fallData;
39+
3640
// TODO: Forge bug: PlayerEntity calls its super, so this event gets fired twice on the client.
3741
@Inject(method = "onDeath", at = @At("HEAD"), cancellable = true)
3842
private void hookDeath(DamageSource source, CallbackInfo callback) {
@@ -76,6 +80,27 @@ private void hookApplyDamageForHurtEventCancel(DamageSource source, float damage
7680
}
7781
}
7882

83+
@ModifyVariable(method = "handleFallDamage", at = @At(value = "INVOKE", target = "net/minecraft/entity/Entity.handleFallDamage(FF)V", shift = At.Shift.BEFORE), ordinal = 0)
84+
private float hookHandleFallDamageDistance(float distance, float damageMultiplier) {
85+
return fallData[0];
86+
}
87+
88+
@ModifyVariable(method = "handleFallDamage", at = @At(value = "INVOKE", target = "net/minecraft/entity/Entity.handleFallDamage(FF)V", shift = At.Shift.AFTER), ordinal = 1)
89+
private float hookHandleFallDamageMultiplier(float distance, float damageMultiplier) {
90+
return fallData[1];
91+
}
92+
93+
@Inject(method = "handleFallDamage", at = @At("HEAD"), cancellable = true)
94+
private void hookHandleFallDamageCancel(float distance, float damageMultiplier, CallbackInfo info) {
95+
LivingEntity entity = (LivingEntity) (Object) this;
96+
97+
fallData = EntityEvents.onLivingFall(entity, distance, damageMultiplier);
98+
99+
if (fallData == null) {
100+
info.cancel();
101+
}
102+
}
103+
79104
// No shift, because we are specifically not modifying the value for this function call.
80105
// TODO: Forge patches a bit later into the function here, being inconsistent with their patch for PlayerEntity. For the moment, I don't feel like finding an injection point for that, and this may be a Forge bug?
81106
@ModifyVariable(method = "applyDamage", argsOnly = true, at = @At(value = "INVOKE", target = "net/minecraft/entity/LivingEntity.setAbsorptionAmount (F)V", ordinal = 0))

patchwork-events-entity/src/main/java/com/patchworkmc/mixin/event/entity/MixinPlayerEntity.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
package com.patchworkmc.mixin.event.entity;
2121

2222
import org.spongepowered.asm.mixin.Mixin;
23+
import org.spongepowered.asm.mixin.Shadow;
2324
import org.spongepowered.asm.mixin.injection.At;
2425
import org.spongepowered.asm.mixin.injection.Inject;
2526
import org.spongepowered.asm.mixin.injection.ModifyVariable;
@@ -29,6 +30,7 @@
2930
import net.minecraft.entity.Entity;
3031
import net.minecraft.entity.LivingEntity;
3132
import net.minecraft.entity.damage.DamageSource;
33+
import net.minecraft.entity.player.PlayerAbilities;
3234
import net.minecraft.entity.player.PlayerEntity;
3335
import net.minecraft.util.ActionResult;
3436
import net.minecraft.util.Hand;
@@ -37,6 +39,9 @@
3739

3840
@Mixin(PlayerEntity.class)
3941
public class MixinPlayerEntity {
42+
@Shadow
43+
public PlayerAbilities abilities;
44+
4045
@Inject(method = "interact", at = @At("HEAD"), cancellable = true)
4146
private void hookInteractEntity(Entity entity, Hand hand, CallbackInfoReturnable<ActionResult> callback) {
4247
PlayerEntity player = (PlayerEntity) (Object) this;
@@ -99,6 +104,14 @@ private void hookApplyDamageForHurtEventCancel(DamageSource source, float damage
99104
}
100105
}
101106

107+
@Inject(method = "handleFallDamage", at = @At("RETURN"))
108+
private void hookHandleFallDamage(float distance, float damageMultiplier) {
109+
if (abilities.allowFlying) {
110+
PlayerEntity player = (PlayerEntity) (Object) this;
111+
EntityEvents.onFlyablePlayerFall(player, distance, damageMultiplier);
112+
}
113+
}
114+
102115
// No shift, because we are specifically not modifying the value for this function call.
103116
@ModifyVariable(method = "applyDamage", argsOnly = true, at = @At(value = "INVOKE", target = "net/minecraft/entity/player/PlayerEntity.setAbsorptionAmount (F)V", ordinal = 0))
104117
private float hookApplyDamageForDamageEvent(float damage, DamageSource source) {
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Minecraft Forge, Patchwork Project
3+
* Copyright (c) 2016-2020, 2019-2020
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation version 2.1
8+
* of the License.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
package net.minecraftforge.event.entity.living;
21+
22+
import net.minecraft.entity.LivingEntity;
23+
24+
/**
25+
* LivingFallEvent is fired when a {@link LivingEntity} is set to be falling.
26+
*
27+
* <p>This event is fired whenever a {@link LivingEntity} is set to fall in
28+
* {@link LivingEntity#fall(float, float)}.</p>
29+
*
30+
* <p>For players that are able to fly, {@link net.minecraftforge.event.entity.player.PlayerFlyableFallEvent} will be fired instead.</p>
31+
*
32+
* <p>This event is fired via {@link com.patchworkmc.impl.event.entity.EntityEvents#onLivingFall(LivingEntity, float, float)}.</p>
33+
*
34+
* <p>{@link #distance} contains the distance the {@link LivingEntity} is to fall. If this event is cancelled, this value is set to 0.0F.</p>
35+
*
36+
* <p>This event is cancellable.
37+
* If this event is cancelled, the {@link LivingEntity} does not take fall damage.</p>
38+
*
39+
* <p>This event is fired on the {@link MinecraftForge#EVENT_BUS}.</p>
40+
*/
41+
public class LivingFallEvent extends LivingEvent {
42+
private float distance;
43+
private float damageMultiplier;
44+
45+
// For EventBus
46+
public LivingFallEvent() {
47+
this(null, 0, 0);
48+
}
49+
50+
public LivingFallEvent(LivingEntity entity, float distance, float damageMultiplier) {
51+
super(entity);
52+
53+
this.setDistance(distance);
54+
this.setDamageMultiplier(damageMultiplier);
55+
}
56+
57+
public float getDistance() {
58+
return distance;
59+
}
60+
61+
public void setDistance(float distance) {
62+
this.distance = distance;
63+
}
64+
65+
public float getDamageMultiplier() {
66+
return damageMultiplier;
67+
}
68+
69+
public void setDamageMultiplier(float damageMultiplier) {
70+
this.damageMultiplier = damageMultiplier;
71+
}
72+
73+
@Override
74+
public boolean isCancelable() {
75+
return true;
76+
}
77+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Minecraft Forge, Patchwork Project
3+
* Copyright (c) 2016-2020, 2019-2020
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation version 2.1
8+
* of the License.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
package net.minecraftforge.event.entity.player;
21+
22+
import net.minecraft.entity.player.PlayerEntity;
23+
24+
/**
25+
* Occurs when a player falls, but is able to fly.
26+
* {@link net.minecraftforge.event.entity.living.LivingFallEvent} will be fired for players that are not able to fly.
27+
*/
28+
public class PlayerFlyableFallEvent extends PlayerEvent {
29+
private float distance;
30+
private float multiplier;
31+
32+
// For EventBus
33+
public PlayerFlyableFallEvent() {
34+
this(null, 0, 0);
35+
}
36+
37+
public PlayerFlyableFallEvent(PlayerEntity player, float distance, float multiplier) {
38+
super(player);
39+
40+
this.distance = distance;
41+
this.multiplier = multiplier;
42+
}
43+
44+
public float getDistance() {
45+
return distance;
46+
}
47+
48+
public void setDistance(float distance) {
49+
this.distance = distance;
50+
}
51+
52+
public float getMultiplier() {
53+
return multiplier;
54+
}
55+
56+
public void setMultiplier(float multiplier) {
57+
this.multiplier = multiplier;
58+
}
59+
}

0 commit comments

Comments
 (0)