mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-12-02 17:02:25 +00:00
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:
parent
597b06ae52
commit
a1a4a97dcd
4 changed files with 26 additions and 4 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue