Seat the second camel passenger behind the first

This commit is contained in:
DUzzL committed 2026-11-02 06:33:28 +01:00
1 parent c2d352e0a3
commit 191cc8cdbc
2 files changed
+51 -7

No files matched your search

+16 -1
View File
@@ -131,7 +131,22 @@ impl Game<'_> {
continue;
};
let vehicle = &self.mobs[j];
let attach = riders::passenger_attachment(vehicle);
let mut attach = riders::passenger_attachment(vehicle);
if horizon_client::mobs::camel::is_camel(vehicle.species()) {
// Camel.getPassengerAttachmentPoint: the seat follows the
// rider's place in `getPassengers` (load order).
let aboard: Vec<usize> = (0..self.mobs.len())
.filter(|&k| self.mobs[k].extra.mount == Some(v))
.collect();
let seat = aboard.iter().position(|&k| k == i).unwrap_or(0);
let animal = horizon_client::mobs::drops::is_animal(self.mobs[i].species());
attach = horizon_client::mobs::camel::passenger_attachment_at(
vehicle,
seat,
aboard.len(),
animal,
);
}
let (pos, prev) = (vehicle.position, vehicle.previous);
let (yaw, prev_yaw) = (vehicle.yaw, vehicle.previous_yaw);
let (body, prev_body) = (vehicle.body_yaw, vehicle.previous_body_yaw);
+35 -6
View File
@@ -195,15 +195,29 @@ pub fn leash_offset(m: &Mob) -> [f64; 3] {
f64::from(m.width() * 0.56),
]
}
/// `Camel.getPassengerAttachmentPoint` of the one rider Horizon seats, before
/// `Camel.getPassengerAttachmentPoint` of the first (driver) seat, before
/// the camel's yaw turns it: half a block ahead (scaled by `getAgeScale`, 0.6
/// for a baby) at the body anchor, which sinks while the camel sits. The
/// second seat (-0.7 behind, 0.2 more for an animal) is not used: nothing
/// seats a second rider yet.
/// for a baby) at the body anchor, which sinks while the camel sits.
pub fn passenger_attachment(m: &Mob) -> [f64; 3] {
passenger_attachment_at(m, 0, 1, false)
}
/// `Camel.getPassengerAttachmentPoint` for the passenger at `index` of `count`
/// (`getPassengers().indexOf`): with more than one aboard the second seat is
/// 0.7 behind the middle, and an `Animal` sits 0.2 further ahead.
pub fn passenger_attachment_at(m: &Mob, index: usize, count: usize, animal: bool) -> [f64; 3] {
let scale = if m.is_baby() { 0.6 } else { 1.0 };
let height = body_anchor_y(m, true, m.height(), scale) as f32;
[0.0, f64::from(height), f64::from(0.5 * scale)]
let driver = index == 0;
let height = body_anchor_y(m, driver, m.height(), scale) as f32;
let mut offset = 0.5_f32;
if count > 1 {
if !driver {
offset = -0.7;
}
if animal {
offset += 0.2;
}
}
[0.0, f64::from(height), f64::from(offset * scale)]
}
/// `Camel.updateWalkAnimation`: the speed the legs go toward and how fast
/// they get there (`WalkAnimationState.update`) for `distance` blocks moved.
@@ -470,6 +484,21 @@ mod tests {
use serde_json::json;
use std::sync::Arc;
/// `Camel.getPassengerAttachmentPoint`: the second of two passengers sits
/// 0.7 behind the middle, 0.5 ahead for the driver, 0.2 more for an animal.
#[test]
fn the_second_passenger_sits_behind() {
with_test_world(&[], |_, types| {
let kind = std::sync::Arc::new(types.types["minecraft:camel_husk"].clone());
let m = Mob::new(1, kind, Vec3::new(0.5, 64.0, 0.5), 0.0);
assert_eq!(passenger_attachment_at(&m, 0, 2, false)[2], 0.5);
assert!((passenger_attachment_at(&m, 1, 2, false)[2] + 0.7).abs() < 1e-6);
assert!((passenger_attachment_at(&m, 1, 2, true)[2] + 0.5).abs() < 1e-6);
assert!((passenger_attachment_at(&m, 0, 2, true)[2] - 0.7).abs() < 1e-6);
assert_eq!(passenger_attachment_at(&m, 0, 1, true)[2], 0.5);
});
}
/// `CamelAi.RandomSitting.checkExtraStartConditions`: a camel sits down
/// only with no controlling passenger and no lead. A husk on its back
/// controls it (`Mob.getControllingPassenger`), a slime does not