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; 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 // FRandom :: StaticPrintSeeds

View file

@ -199,7 +199,7 @@ public:
void ClearDynamic3DFloorData(); void ClearDynamic3DFloorData();
void WorldDone(void); void WorldDone(void);
void AirControlChanged(); 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); bool AlignFlat(int linenum, int side, int fc);
void ReplaceTextures(const char *fromname, const char *toname, int flags); 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; AActor *searcher;
@ -324,7 +324,8 @@ AActor *FLevelLocals::SelectTeleDest (int tid, int tag, bool norandom)
{ {
if (count != 1 && !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; searcher = NULL;
while (count > 0) 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. { // Don't teleport if hit back of line, so you can get out of teleporter.
return 0; return 0;
} }
searcher = SelectTeleDest(tid, tag, predicting); searcher = SelectTeleDest(tid, tag, false, thing->player != nullptr && thing->player->mo == thing);
if (searcher == NULL) if (searcher == NULL)
{ {
return false; return false;

View file

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