mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-08 17:19:10 -10:00
Native mods: living_incoming_damage_v2 fires after the victim's invulnerability check
An invulnerable or dead mob fired v2 although vanilla's hurtServer returns early and NeoForge's LivingIncomingDamageEvent comes after that check. Mob::refuses_damage is the guard damage_with already ran, now shared. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
1 parent
37b8a8bfe2
commit
f152b155a6
6 files changed
+15
-11
No files matched your search
@@ -186,7 +186,8 @@ impl Game<'_> {
|
||||
let aim = self.attacker_aim(source.attacker);
|
||||
let kind = self.mobs[index].kind.id.clone();
|
||||
let mut amount = amount;
|
||||
if !crate::mod_api::mods().is_empty() {
|
||||
// After the invulnerability guard, as `LivingIncomingDamageEvent` fires.
|
||||
if !crate::mod_api::mods().is_empty() && !self.mobs[index].refuses_damage(&source) {
|
||||
let victim = &self.mobs[index];
|
||||
let position = victim.position;
|
||||
let view = super::view_vector(victim.head_yaw, victim.head_pitch);
|
||||
|
||||
@@ -7041,7 +7041,7 @@ impl Game<'_> {
|
||||
/// this has a host and snapshots of the weapon, victim position/view and
|
||||
/// DamageSource position. The acting player's network id is `causing`
|
||||
/// (also the direct entity). Weapon enchantments include their levels.
|
||||
/// Runs before the victim's immunity guards and v1; cancellation refuses
|
||||
/// Runs after the victim's invulnerability check (an invulnerable or dead victim fires nothing) and before v1; cancellation refuses
|
||||
/// delivery. Other damage routes still only fire v1. API @API:living_incoming_damage_v2@.
|
||||
pub(super) fn native_living_incoming_damage_v2(
|
||||
&mut self,
|
||||
|
||||
@@ -2787,6 +2787,13 @@ impl Mob {
|
||||
pub fn damage(&mut self, amount: f32, source: Damage) -> bool {
|
||||
self.damage_with(amount, source, None)
|
||||
}
|
||||
/// `LivingEntity.isInvulnerableTo` and dead or removed: only #bypasses_invulnerability gets
|
||||
/// past the flag. The guard every damage hook runs after (`LivingIncomingDamageEvent`).
|
||||
pub fn refuses_damage(&self, source: &Damage) -> bool {
|
||||
!self.alive()
|
||||
|| self.removed
|
||||
|| (self.invulnerable_flag && !source.kind.bypasses_invulnerability())
|
||||
}
|
||||
/// `damage` by a source with a weapon: `armor_effectiveness` runs the
|
||||
/// weapon's armor-effectiveness enchantments (breach) over the armor fraction.
|
||||
pub fn damage_with(
|
||||
@@ -2807,11 +2814,7 @@ impl Mob {
|
||||
// about, so `Player.attack` goes on with its extra knockback and its aftermath.
|
||||
return sulfur_cube::immune_to(&source);
|
||||
}
|
||||
// LivingEntity.isInvulnerableTo: only #bypasses_invulnerability gets past it.
|
||||
if !self.alive()
|
||||
|| self.removed
|
||||
|| (self.invulnerable_flag && !source.kind.bypasses_invulnerability())
|
||||
{
|
||||
if self.refuses_damage(&source) {
|
||||
return false;
|
||||
}
|
||||
// Ghast.isReflectedFireball: a fireball a player turned back is
|
||||
|
||||
+1
-1
@@ -4523,7 +4523,7 @@ pub trait Hooks: Send + Sync {
|
||||
/// this has a host and snapshots of the weapon, victim position/view and
|
||||
/// DamageSource position. The acting player's network id is `causing`
|
||||
/// (also the direct entity). Weapon enchantments include their levels.
|
||||
/// Runs before the victim's immunity guards and v1; cancellation refuses
|
||||
/// Runs after the victim's invulnerability check (an invulnerable or dead victim fires nothing) and before v1; cancellation refuses
|
||||
/// delivery. Other damage routes still only fire v1. API @API:living_incoming_damage_v2@.
|
||||
///
|
||||
/// Return `Flow::Cancel` to take it: this sets `canceled`, and later mods are skipped.
|
||||
|
||||
+2
-2
@@ -357,8 +357,8 @@ catalog and the hook points' sources (`native_hooks.rs`, `gfx/native_render.rs`,
|
||||
It receives a mutable `Host`, attacker/victim network ids, damage type, optional source position, victim position
|
||||
and current view vector, and an optional weapon snapshot. `weapon.enchantments()` exposes enchantment ids and
|
||||
levels. Change `amount` or return `Flow::Cancel`; the host can read the world and play sounds through its helpers.
|
||||
It currently fires for player-to-mob melee, sweep and spear hits (including LAN guests), before the victim's
|
||||
immunity guards and v1. Unless canceled, v1 receives the modified amount. It is not a replacement for v1 on
|
||||
It currently fires for player-to-mob melee, sweep and spear hits (including LAN guests), after the victim's invulnerability check (an invulnerable or dead victim fires nothing) and before
|
||||
v1. Unless canceled, v1 receives the modified amount. It is not a replacement for v1 on
|
||||
projectiles, player victims, dragons, mob attacks or environmental damage. There is no extra per-hit allocation
|
||||
without loaded mods. The fragment `living_incoming_damage_v2.json` receives its API number at merge.
|
||||
|
||||
|
||||
@@ -13,5 +13,5 @@
|
||||
}
|
||||
],
|
||||
"rust_summary": "a host-aware player-weapon damage hook (`native_living_incoming_damage_v2`), leaving v1 compatible.",
|
||||
"doc_summary": "`native_living_incoming_damage_v2`: a host-aware damage hook for a player's melee, sweep and spear hits on mobs, including LAN guests. It supplies the attacker/victim network ids, damage type, optional source position, victim position/view vector and the weapon snapshot (read `ItemStack::enchantments()` for ids and levels). Mods can change damage, cancel delivery and use Host helpers, including sounds. It fires before the victim's immunity guards and v1; v1 then sees the changed amount unless v2 canceled. Projectiles, player victims, dragons, mob attacks and environmental damage still only fire v1. No extra work or allocation when no mods are loaded. This is additive, like `menu_button_v2`, not a signature change to v1. Bundles need \"hooks\": @API:living_incoming_damage_v2@."
|
||||
"doc_summary": "`native_living_incoming_damage_v2`: a host-aware damage hook for a player's melee, sweep and spear hits on mobs, including LAN guests. It supplies the attacker/victim network ids, damage type, optional source position, victim position/view vector and the weapon snapshot (read `ItemStack::enchantments()` for ids and levels). Mods can change damage, cancel delivery and use Host helpers, including sounds. It fires after the victim's invulnerability check (an invulnerable or dead victim fires nothing) and before v1; v1 then sees the changed amount unless v2 canceled. Projectiles, player victims, dragons, mob attacks and environmental damage still only fire v1. No extra work or allocation when no mods are loaded. This is additive, like `menu_button_v2`, not a signature change to v1. Bundles need \"hooks\": @API:living_incoming_damage_v2@."
|
||||
}
|
||||
Reference in new issue
Block a user