OptiFine entity models: the local player's model knows when it's in water

Its fluids were never set, so swimming read as crawling for its
animations.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
some-du6eandClaude Opus 5.5 committed 2026-11-01 18:20:21 -06:00
1 parent 1d20a9db1d
commit e4b2778edb
2 files changed
+19

No files matched your search

@@ -427,6 +427,7 @@ impl Game<'_> {
let visually_swimming =
p.pose == Pose::Swimming || (!p.fall_flying && p.pose == Pose::FallFlying);
let in_water = p.fluids.was_touching_water;
let in_lava = p.is_in_lava();
let (yaw, pitch) = (self.yaw, self.pitch);
let main = self.inventory[self.selected].clone();
let off = self.offhand.as_ref().map(|s| s.item.clone());
@@ -497,6 +498,9 @@ impl Game<'_> {
m.extra.crouching = crouching;
// Guests and server players take their pose from DATA_POSE, not here.
m.extra.avatar_pose = pose;
// What custom entity model animations read of the fluids (`is_in_water`, crawling).
m.fluids.in_water = in_water;
m.fluids.in_lava = in_lava;
m.extra.passenger = riding;
m.extra.previous_velocity = m.velocity;
m.velocity = velocity;
@@ -956,6 +956,21 @@ mod tests {
);
}
#[test]
fn the_swimming_pose_in_water_swims_without_crawling() {
let mut m = mob();
m.extra.pose = 3;
let model = bone("root", vec![]);
let animation = animate(&model, &[("root.tx", "is_swimming + is_crawling * 2")]);
let mut read = |in_water: bool| {
m.fluids.in_water = in_water;
let mut poses = Poses::new(&model);
animation.run_in(&Frame::default(), &m, &still(), &mut poses);
poses.get("root")[0]
};
assert_eq!([read(true), read(false)], [1.0, 3.0]);
}
#[test]
fn a_fox_sits_by_its_own_flags() {
let mut m = mob();