From 61b7c43e287685c3bdf5f38411fea1cc96d75e76 Mon Sep 17 00:00:00 2001 From: Gh4zi Date: Fri, 9 Oct 2026 07:40:52 +0300 Subject: [PATCH] Fix flower pots floating up when woken; walking past moves clutter only A physics prop's hull is its model's whole bounds, a potted plant's leaves included, so a pot where the map placed it can already overlap a pillar or shelf. Once woken, every physics step found it starting in solid and lifted it a unit, so it rose until the hull cleared the obstacle and fell asleep in the air; each later wake lifted it again. A prop starting in solid now stays where it is and settles. Walking past woke any physics prop whose bounding sphere touched the player's box and gave it the player's velocity: a large pot's sphere (75 units, the leaves) reached the player well before the pot did, so walking near one pushed it along. Only clutter (cans, bottles, luggage) is moved by walking now; bullets and explosions still move breakable props. Checked on mp_terminal: pots floated after walking past them on this branch before the change; with it, walking past the bookshop pot (com_potted_plant_large at 1177 5453) leaves it on the floor. Co-Authored-By: Claude Opus 5.5 --- crates/render_anim/src/occupancy/dyn_ent_phys.rs | 10 ++++------ .../render_frontend/src/adapters/anim/dyn_ent_wake.rs | 5 ++++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/crates/render_anim/src/occupancy/dyn_ent_phys.rs b/crates/render_anim/src/occupancy/dyn_ent_phys.rs index c8bdc82..32ca162 100644 --- a/crates/render_anim/src/occupancy/dyn_ent_phys.rs +++ b/crates/render_anim/src/occupancy/dyn_ent_phys.rs @@ -202,14 +202,12 @@ fn integrate_body(body: &mut DynEntPhysBody, clip: &ClipCollision, dt: f32) { CONTENTS_SOLID, ); if hit.allsolid || hit.startsolid { + // The hull is the model's whole bounds (a potted plant's leaves with it), so a prop where + // the map placed it can already overlap a wall, pillar or shelf. Lifting it out a unit a + // step floated such props up until the hull cleared the obstacle, where they fell asleep + // in the air; the map's placement stands instead and the prop settles where it is. body.vel = Vec3::ZERO; body.on_ground = true; - let lift = if body.mins[2] < 0.0 { - -body.mins[2] - } else { - 1.0 - }; - body.origin.z += lift; return; } if hit.fraction < 1.0 { diff --git a/crates/render_frontend/src/adapters/anim/dyn_ent_wake.rs b/crates/render_frontend/src/adapters/anim/dyn_ent_wake.rs index 8ac25ad..027bc13 100644 --- a/crates/render_frontend/src/adapters/anim/dyn_ent_wake.rs +++ b/crates/render_frontend/src/adapters/anim/dyn_ent_wake.rs @@ -862,7 +862,10 @@ pub(crate) fn wake_player_overlap( let maxs = origin + PLAYER_MAXS; let catalog = catalog.as_deref(); for (entity, inst, transform) in &instances { - if world.is_awake(entity) { + // Walking past moves clutter (cans, bottles, luggage) only: a breakable prop's sphere + // takes in a potted plant's leaves, so walking near one pushed the pot along at the + // player's speed. Bullets and explosions still move them. + if inst.ty != asset_world::DynEntType::Clutter || world.is_awake(entity) { continue; } let Some(preset) = can_wake(inst) else {