Added RNG snapshotting for predicting

Allows RNG seeds to be played back in a predictive way paving the road for predictive behaviors that rely on RNG.
This commit is contained in:
Boondorl 2024-11-04 13:15:47 -05:00 committed by Ricardo Luís Vaz Silva
parent 597b06ae52
commit a1a4a97dcd
4 changed files with 26 additions and 4 deletions

View file

@ -388,6 +388,21 @@ FRandom *FRandom::StaticFindRNG (const char *name, bool client)
return probe;
}
void FRandom::SaveRNGState(TArray<FRandom>& backups)
{
for (auto cur = RNGList; cur != nullptr; cur = cur->Next)
backups.Push(*cur);
}
void FRandom::RestoreRNGState(TArray<FRandom>& backups)
{
unsigned int i = 0u;
for (auto cur = RNGList; cur != nullptr; cur = cur->Next)
*cur = backups[i++];
backups.Clear();
}
//==========================================================================
//
// FRandom :: StaticPrintSeeds

View file

@ -199,7 +199,7 @@ public:
void ClearDynamic3DFloorData();
void WorldDone(void);
void AirControlChanged();
AActor *SelectTeleDest(int tid, int tag, bool norandom);
AActor *SelectTeleDest(int tid, int tag, bool norandom, bool isPlayer);
bool AlignFlat(int linenum, int side, int fc);
void ReplaceTextures(const char *fromname, const char *toname, int flags);

View file

@ -272,7 +272,7 @@ DEFINE_ACTION_FUNCTION(AActor, Teleport)
//
//-----------------------------------------------------------------------------
AActor *FLevelLocals::SelectTeleDest (int tid, int tag, bool norandom)
AActor *FLevelLocals::SelectTeleDest (int tid, int tag, bool norandom, bool isPlayer)
{
AActor *searcher;
@ -324,7 +324,8 @@ AActor *FLevelLocals::SelectTeleDest (int tid, int tag, bool norandom)
{
if (count != 1 && !norandom)
{
count = 1 + (pr_teleport() % count);
// Players get their own RNG seed to reduce likelihood of breaking prediction.
count = 1 + ((isPlayer ? pr_playerteleport() : pr_teleport()) % count);
}
searcher = NULL;
while (count > 0)
@ -395,7 +396,7 @@ bool FLevelLocals::EV_Teleport (int tid, int tag, line_t *line, int side, AActor
{ // Don't teleport if hit back of line, so you can get out of teleporter.
return 0;
}
searcher = SelectTeleDest(tid, tag, predicting);
searcher = SelectTeleDest(tid, tag, false, thing->player != nullptr && thing->player->mo == thing);
if (searcher == NULL)
{
return false;

View file

@ -144,6 +144,8 @@ static DVector3 LastPredictedPosition;
static int LastPredictedPortalGroup;
static int LastPredictedTic;
static TArray<FRandom> PredictionRNG;
static player_t PredictionPlayerBackup;
static AActor *PredictionActor;
static TArray<uint8_t> PredictionActorBackupArray;
@ -1461,6 +1463,8 @@ void P_PredictPlayer (player_t *player)
return;
}
FRandom::SaveRNGState(PredictionRNG);
// Save original values for restoration later
PredictionPlayerBackup.CopyFrom(*player, false);
@ -1600,6 +1604,8 @@ void P_UnPredictPlayer ()
// Q: Can this happen? If yes, can we continue?
}
FRandom::RestoreRNGState(PredictionRNG);
AActor *savedcamera = player->camera;
auto &actInvSel = act->PointerVar<AActor*>(NAME_InvSel);