Merge pull request #8077 from horizon-rust/fix/parrot-flying-speed-attribute

🤖 Agent: FlyingMoveControl now reads the flying_speed attribute, not the type's 0.4, so #7822's summoned parrot with flying_speed base 0 stays put (Horizon's drift was exactly 0.4 × 0.02 per tick). New head = main merged in, run-parity dropped: the old head's only failure was pack_screen on playhorizon (its .local has no lang files). parity-main checks command_exec.
This commit is contained in:
Ludovic Marie authored and GitHub committed 2026-11-03 09:12:59 +01:00
commit f42ef42ef6
3 files changed
+28 -5

No files matched your search

+12
View File
@@ -1491,6 +1491,18 @@ pub fn mob_from_nbt(
}
"minecraft:attack_damage" => m.attrs.attack_damage = v as f32,
"minecraft:attack_knockback" => m.attrs.attack_knockback = v,
"minecraft:flying_speed"
if crate::mobs::finalize::default_value(
&m,
crate::mobs::finalize::Attr::FlyingSpeed,
) != Some(v) =>
{
crate::mobs::finalize::set_base(
&mut m,
crate::mobs::finalize::Attr::FlyingSpeed,
v,
)
}
_ => {}
}
}
+2 -1
View File
@@ -185,7 +185,8 @@ impl Mob {
* if self.on_ground {
attr_speed
} else {
self.kind.flying_speed
// getAttributeValue(FLYING_SPEED): a summon's base counts.
super::finalize::value(self, super::finalize::Attr::FlyingSpeed)
}) as f32;
self.set_speed(speed);
let sd = (xd * xd + zd * zd).sqrt();
+14 -4
View File
@@ -409,9 +409,11 @@ pub enum Attr {
JumpStrength,
Armor,
BurningTime,
/// `Attributes.FLYING_SPEED`: what `FlyingMoveControl` flies at.
FlyingSpeed,
}
impl Attr {
pub const ALL: [Self; 9] = [
pub const ALL: [Self; 10] = [
Self::MaxHealth,
Self::MovementSpeed,
Self::FollowRange,
@@ -421,6 +423,7 @@ impl Attr {
Self::JumpStrength,
Self::Armor,
Self::BurningTime,
Self::FlyingSpeed,
];
pub fn name(self) -> &'static str {
match self {
@@ -433,6 +436,7 @@ impl Attr {
Self::JumpStrength => "jump_strength",
Self::Armor => "armor",
Self::BurningTime => "burning_time",
Self::FlyingSpeed => "flying_speed",
}
}
/// The attribute's registry id (`minecraft:` and its name), without
@@ -448,6 +452,7 @@ impl Attr {
Self::JumpStrength => "minecraft:jump_strength",
Self::Armor => "minecraft:armor",
Self::BurningTime => "minecraft:burning_time",
Self::FlyingSpeed => "minecraft:flying_speed",
}
}
/// `RangedAttribute` bounds.
@@ -460,7 +465,7 @@ impl Attr {
Self::KnockbackResistance | Self::SpawnReinforcements => (0.0, 1.0),
Self::JumpStrength => (0.0, 32.0),
Self::Armor => (0.0, 30.0),
Self::BurningTime => (0.0, 1024.0),
Self::BurningTime | Self::FlyingSpeed => (0.0, 1024.0),
}
}
}
@@ -496,7 +501,12 @@ pub fn base_value(m: &Mob, a: Attr) -> f64 {
.as_ref()
.and_then(|s| s.bases.iter().find(|(x, _)| *x == a).map(|(_, v)| *v))
.or_else(|| default_value(m, a))
.unwrap_or(if a == Attr::BurningTime { 1.0 } else { 0.0 })
.unwrap_or(match a {
Attr::BurningTime => 1.0,
// The registry's default, as the type's `flying_speed` falls back to.
Attr::FlyingSpeed => 0.4,
_ => 0.0,
})
}
/// The transient modifiers of the mob's state (`SPEED_MODIFIER_BABY`).
pub fn transient(m: &Mob, a: Attr) -> Option<(f64, Op)> {
@@ -594,7 +604,7 @@ fn refresh(m: &mut Mob, a: Attr) {
Attr::KnockbackResistance => m.attrs.knockback_resistance = value(m, a),
Attr::SpawnReinforcements => m.attrs.spawn_reinforcements = value(m, a),
Attr::JumpStrength => m.attrs.jump_strength = value(m, a),
Attr::Armor | Attr::BurningTime => {}
Attr::Armor | Attr::BurningTime | Attr::FlyingSpeed => {}
}
}
/// The value without the transient baby modifier (`speed_bonus` applies