mirror of
https://github.com/vladtrc/iw4L
synced 2026-10-26 02:11:39 -04:00
Draw a falling body between its snapshots instead of in 20 Hz jumps
present_pose drew a body between its previous and current snapshot only when both were TR_INTERPOLATE. A falling or sliding corpse (TR_GRAVITY) was drawn at its snapshot position for a whole 50 ms and then jumped, and so was every switch between resting and falling. Each snapshot position of a corpse is already where the body was at that snapshot, so corpses are now drawn between the two whatever their trajectory type. Players keep the old rule. A corpse slot is reused for later deaths, so an entity number can hold a new body. A corpse whose death time (time2) or victim changes is now a new entity and is not drawn sliding over from where the old body lay. Seen on the Mac: a flying body's drawn position changes on every frame while the server moves it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -64,9 +64,11 @@ impl CEntityRuntime {
|
||||
return;
|
||||
};
|
||||
if !self.in_next_snap()
|
||||
|| !matches!(self.pose_e_type as i32, ET_PLAYER | ET_PLAYER_CORPSE)
|
||||
|| previous.pos.tr_type != TR_INTERPOLATE
|
||||
|| self.current.pos.tr_type != TR_INTERPOLATE
|
||||
|| !lerps_between_snapshots(
|
||||
self.pose_e_type as i32,
|
||||
previous.pos.tr_type,
|
||||
self.current.pos.tr_type,
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -92,6 +94,19 @@ impl CEntityRuntime {
|
||||
}
|
||||
}
|
||||
|
||||
fn lerps_between_snapshots(e_type: i32, previous_tr_type: i32, current_tr_type: i32) -> bool {
|
||||
match e_type {
|
||||
ET_PLAYER_CORPSE => true,
|
||||
ET_PLAYER => previous_tr_type == TR_INTERPOLATE && current_tr_type == TR_INTERPOLATE,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn another_body(current: &EntityState, next: &EntityState) -> bool {
|
||||
next.e_type == ET_PLAYER_CORPSE
|
||||
&& (current.time2 != next.time2 || current.client_num != next.client_num)
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct PlayerDrawGate {
|
||||
pub eyes_entity_num: i32,
|
||||
@@ -246,8 +261,9 @@ pub fn apply_existing(rt: &mut CEntityRuntime, next: EntityState, at_time_ms: i3
|
||||
let was_in = rt.in_next_snap();
|
||||
let e_type_changed = rt.next_state.e_type != next.e_type;
|
||||
let teleport = (rt.next_state.e_flags ^ next.e_flags) & EFLAGS_TELEPORT != 0;
|
||||
if !was_in || e_type_changed || teleport {
|
||||
let new_entity = !was_in || e_type_changed;
|
||||
let other_body = another_body(&rt.next_state, &next);
|
||||
if !was_in || e_type_changed || teleport || other_body {
|
||||
let new_entity = !was_in || e_type_changed || other_body;
|
||||
reset_entity(rt, next, at_time_ms, new_entity);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user