Fix explosions: link entities in SVD_ReadFrame with trBase origin

Entities must be linked immediately when injected, not deferred to
G_RunFrame. When multiple server frames execute per SV_Frame cycle,
the clearing loop in the next iteration unlinks entities before the
snapshot is built — one-frame entities (explosions, temp effects)
are lost. G_RunFrame still runs BG_EvaluateTrajectory + trap_LinkEntity
to refine origins for moving entities (rockets with TR_LINEAR).

Also restore SNAPFLAG_RESET_ENTITIES on unpause so fast-moving
entities snap instead of interpolating through the pause gap.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
serge_shubin 2026-03-24 17:43:10 +08:00
parent 3d8291658f
commit 3dadde6fd1

View file

@ -663,12 +663,16 @@ static qboolean SVD_ReadFrame( fileHandle_t f ) {
demo.playPrevEntities[entNum].es = newEs;
demo.playPrevEntities[entNum].active = qtrue;
// apply to server entity (entity linking done in G_RunFrame
// which has BG_EvaluateTrajectory for computing currentOrigin)
// apply to server entity and link for PVS.
// use trBase as initial origin — G_RunFrame will refine with
// BG_EvaluateTrajectory for moving entities (rockets etc).
ent = SV_GentityNum( entNum );
ent->s = newEs;
ent->s.number = entNum;
ent->r.svFlags = demo.playPrevEntities[entNum].svFlags;
VectorCopy( newEs.pos.trBase, ent->r.currentOrigin );
ent->r.linked = qtrue;
SV_LinkEntity( ent );
if ( entNum + 1 > sv.num_entities ) {
sv.num_entities = entNum + 1;
@ -908,7 +912,10 @@ void SVD_Pause_f( void ) {
if ( !demo.paused ) {
// resuming — toggle SERVERCOUNT to reset client snapshot timing
// (drifted during pause from identical serverTimes).
// also reset entities so fast-moving objects (rockets) snap to
// position instead of interpolating through the pause gap.
svs.snapFlagServerBit ^= SNAPFLAG_SERVERCOUNT;
svs.snapFlagServerBit |= SNAPFLAG_RESET_ENTITIES;
}
Com_Printf( "Demo playback %s.\n", demo.paused ? "paused" : "resumed" );
}