Skip to content

Commit

Permalink
After Damage Event (FabricMC#4051)
Browse files Browse the repository at this point in the history
* after damage event

* add after damage event to testmod

* remove amount > 0 check to capture shield blocking

* add javadoc

* dont fire event if killed

* clarify javadoc a bit more

* fix checkstyle issue

* fix other checkstyle issues lol

* rename damageDealt to baseDamageTaken

(cherry picked from commit 2122d82)
  • Loading branch information
TheDeathlyCow authored and modmuss50 committed Aug 26, 2024
1 parent ca1fb63 commit 6cca2be
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,22 @@ public final class ServerLivingEntityEvents {
return true;
});

/**
* An event that is called after an entity is damaged. This is fired from {@link LivingEntity#damage} after damage
* is applied, or after that damage was blocked by a shield.
*
* <p>The base damage taken is the damage initially applied to the entity. Damage taken is the amount of damage the
* entity actually took, after effects such as shields and extra freezing damage are applied. Damage taken does NOT
* include damage reduction from armor and enchantments.
*
* <p>This event is not fired if the entity was killed by the damage.
*/
public static final Event<AfterDamage> AFTER_DAMAGE = EventFactory.createArrayBacked(AfterDamage.class, callbacks -> (entity, source, baseDamageTaken, damageTaken, blocked) -> {
for (AfterDamage callback : callbacks) {
callback.afterDamage(entity, source, baseDamageTaken, damageTaken, blocked);
}
});

/**
* An event that is called when an entity takes fatal damage.
*
Expand Down Expand Up @@ -104,6 +120,21 @@ public interface AllowDamage {
boolean allowDamage(LivingEntity entity, DamageSource source, float amount);
}

@FunctionalInterface
public interface AfterDamage {
/**
* Called after a living entity took damage, unless they were killed. The base damage taken is given as damage
* taken before armor or enchantments are applied, but after other effects like shields are applied.
*
* @param entity the entity that was damaged
* @param source the source of the damage
* @param baseDamageTaken the amount of damage initially dealt
* @param damageTaken the amount of damage actually taken by the entity, before armor and enchantment effects
* @param blocked whether the damage was blocked by a shield
*/
void afterDamage(LivingEntity entity, DamageSource source, float baseDamageTaken, float damageTaken, boolean blocked);
}

@FunctionalInterface
public interface AllowDeath {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;

import net.minecraft.block.BedBlock;
import net.minecraft.block.BlockState;
Expand Down Expand Up @@ -83,6 +84,13 @@ private void beforeDamage(DamageSource source, float amount, CallbackInfoReturna
}
}

@Inject(method = "damage", at = @At("TAIL"), locals = LocalCapture.CAPTURE_FAILHARD)
private void afterDamage(DamageSource source, float amount, CallbackInfoReturnable<Boolean> cir, float dealt, boolean blocked) {
if (!isDead()) {
ServerLivingEntityEvents.AFTER_DAMAGE.invoker().afterDamage((LivingEntity) (Object) this, source, dealt, amount, blocked);
}
}

@Inject(method = "sleep", at = @At("RETURN"))
private void onSleep(BlockPos pos, CallbackInfo info) {
EntitySleepEvents.START_SLEEPING.invoker().onStartSleeping((LivingEntity) (Object) this, pos);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ public void onInitialize() {
return true;
});

ServerLivingEntityEvents.AFTER_DAMAGE.register((entity, source, baseDamageTaken, damageTaken, blocked) -> {
LOGGER.info("Entity {} received {} damage from {} (initially dealt {}, blocked {})", entity.getName().getString(), damageTaken, source.getName(), baseDamageTaken, blocked);
});

ServerLivingEntityEvents.ALLOW_DEATH.register((entity, source, amount) -> {
LOGGER.info("{} is going to die to {} damage from {} damage source", entity.getName().getString(), amount, source.getName());

Expand Down

0 comments on commit 6cca2be

Please sign in to comment.