Skip to content
This repository was archived by the owner on Jun 3, 2024. It is now read-only.
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
import net.minecraftforge.event.entity.living.LivingDamageEvent;
import net.minecraftforge.event.entity.living.LivingSpawnEvent;
import net.minecraftforge.event.entity.living.LivingEvent;
import net.minecraftforge.event.entity.living.LivingFallEvent;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.event.entity.player.PlayerFlyableFallEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.eventbus.api.Event.Result;
Expand Down Expand Up @@ -93,6 +95,15 @@ public static float onLivingHurt(LivingEntity entity, DamageSource src, float da
return MinecraftForge.EVENT_BUS.post(event) ? 0 : event.getAmount();
}

public static float[] onLivingFall(LivingEntity entity, float distance, float damageMultiplier) {
LivingFallEvent event = new LivingFallEvent(entity, distance, damageMultiplier);
return MinecraftForge.EVENT_BUS.post(event) ? null : new float[]{ event.getDistance(), event.getDamageMultiplier() };
}

public static void onFlyablePlayerFall(PlayerEntity player, float distance, float damageMultiplier) {
MinecraftForge.EVENT_BUS.post(new PlayerFlyableFallEvent(player, distance, damageMultiplier));
}

public static float onLivingDamage(LivingEntity entity, DamageSource src, float damage) {
LivingDamageEvent event = new LivingDamageEvent(entity, src, damage);
return MinecraftForge.EVENT_BUS.post(event) ? 0 : event.getAmount();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package com.patchworkmc.mixin.event.entity;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
Expand All @@ -33,6 +34,9 @@

@Mixin(LivingEntity.class)
public class MixinLivingEntity {
@Unique
private float[] fallData;

// TODO: Forge bug: PlayerEntity calls its super, so this event gets fired twice on the client.
@Inject(method = "onDeath", at = @At("HEAD"), cancellable = true)
private void hookDeath(DamageSource source, CallbackInfo callback) {
Expand Down Expand Up @@ -76,6 +80,27 @@ private void hookApplyDamageForHurtEventCancel(DamageSource source, float damage
}
}

@ModifyVariable(method = "handleFallDamage", at = @At(value = "INVOKE", target = "net/minecraft/entity/Entity.handleFallDamage(FF)V", shift = At.Shift.BEFORE), ordinal = 0)
private float hookHandleFallDamageDistance(float distance, float damageMultiplier) {
return fallData[0];
}

@ModifyVariable(method = "handleFallDamage", at = @At(value = "INVOKE", target = "net/minecraft/entity/Entity.handleFallDamage(FF)V", shift = At.Shift.AFTER), ordinal = 1)
private float hookHandleFallDamageMultiplier(float distance, float damageMultiplier) {
return fallData[1];
}

@Inject(method = "handleFallDamage", at = @At("HEAD"), cancellable = true)
private void hookHandleFallDamageCancel(float distance, float damageMultiplier, CallbackInfo info) {
LivingEntity entity = (LivingEntity) (Object) this;

fallData = EntityEvents.onLivingFall(entity, distance, damageMultiplier);

if (fallData == null) {
info.cancel();
}
}

// No shift, because we are specifically not modifying the value for this function call.
// 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?
@ModifyVariable(method = "applyDamage", argsOnly = true, at = @At(value = "INVOKE", target = "net/minecraft/entity/LivingEntity.setAbsorptionAmount (F)V", ordinal = 0))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package com.patchworkmc.mixin.event.entity;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
Expand All @@ -29,6 +30,7 @@
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.player.PlayerAbilities;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
Expand All @@ -37,6 +39,9 @@

@Mixin(PlayerEntity.class)
public class MixinPlayerEntity {
@Shadow
public PlayerAbilities abilities;

@Inject(method = "interact", at = @At("HEAD"), cancellable = true)
private void hookInteractEntity(Entity entity, Hand hand, CallbackInfoReturnable<ActionResult> callback) {
PlayerEntity player = (PlayerEntity) (Object) this;
Expand Down Expand Up @@ -99,6 +104,14 @@ private void hookApplyDamageForHurtEventCancel(DamageSource source, float damage
}
}

@Inject(method = "handleFallDamage", at = @At("RETURN"))
private void hookHandleFallDamage(float distance, float damageMultiplier) {
if (abilities.allowFlying) {
PlayerEntity player = (PlayerEntity) (Object) this;
EntityEvents.onFlyablePlayerFall(player, distance, damageMultiplier);
}
}

// No shift, because we are specifically not modifying the value for this function call.
@ModifyVariable(method = "applyDamage", argsOnly = true, at = @At(value = "INVOKE", target = "net/minecraft/entity/player/PlayerEntity.setAbsorptionAmount (F)V", ordinal = 0))
private float hookApplyDamageForDamageEvent(float damage, DamageSource source) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Minecraft Forge, Patchwork Project
* Copyright (c) 2016-2020, 2019-2020
*
* 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.event.entity.living;

import net.minecraft.entity.LivingEntity;

/**
* LivingFallEvent is fired when a {@link LivingEntity} is set to be falling.
*
* <p>This event is fired whenever a {@link LivingEntity} is set to fall in
* {@link LivingEntity#fall(float, float)}.</p>
*
* <p>For players that are able to fly, {@link net.minecraftforge.event.entity.player.PlayerFlyableFallEvent} will be fired instead.</p>
*
* <p>This event is fired via {@link com.patchworkmc.impl.event.entity.EntityEvents#onLivingFall(LivingEntity, float, float)}.</p>
*
* <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>
*
* <p>This event is cancellable.
* If this event is cancelled, the {@link LivingEntity} does not take fall damage.</p>
*
* <p>This event is fired on the {@link MinecraftForge#EVENT_BUS}.</p>
*/
public class LivingFallEvent extends LivingEvent {
private float distance;
private float damageMultiplier;

// For EventBus
public LivingFallEvent() {
this(null, 0, 0);
}

public LivingFallEvent(LivingEntity entity, float distance, float damageMultiplier) {
super(entity);

this.setDistance(distance);
this.setDamageMultiplier(damageMultiplier);
}

public float getDistance() {
return distance;
}

public void setDistance(float distance) {
this.distance = distance;
}

public float getDamageMultiplier() {
return damageMultiplier;
}

public void setDamageMultiplier(float damageMultiplier) {
this.damageMultiplier = damageMultiplier;
}

@Override
public boolean isCancelable() {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Minecraft Forge, Patchwork Project
* Copyright (c) 2016-2020, 2019-2020
*
* 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.event.entity.player;

import net.minecraft.entity.player.PlayerEntity;

/**
* Occurs when a player falls, but is able to fly.
Comment thread
IceCryptonym marked this conversation as resolved.
* {@link net.minecraftforge.event.entity.living.LivingFallEvent} will be fired for players that are not able to fly.
*/
public class PlayerFlyableFallEvent extends PlayerEvent {
private float distance;
private float multiplier;

// For EventBus
public PlayerFlyableFallEvent() {
this(null, 0, 0);
}

public PlayerFlyableFallEvent(PlayerEntity player, float distance, float multiplier) {
super(player);

this.distance = distance;
this.multiplier = multiplier;
}

public float getDistance() {
return distance;
}

public void setDistance(float distance) {
this.distance = distance;
}

public float getMultiplier() {
return multiplier;
}

public void setMultiplier(float multiplier) {
this.multiplier = multiplier;
}
}