diff --git a/src/m_random.c b/src/m_random.c index 8a59db7c1..166c6bf2e 100644 --- a/src/m_random.c +++ b/src/m_random.c @@ -231,7 +231,7 @@ UINT32 P_GetInitSeedD(const char *rfile, INT32 rline, pr_class_t pr_class) } /** Sets the random seed. - * Used at the beginning of the game, and also for netgames. + * Used at the beginning of a game. * * \param pr_class RNG class to adjust. * \param seed New random seed. @@ -251,8 +251,31 @@ void P_SetRandSeedD(const char *rfile, INT32 rline, pr_class_t pr_class, UINT32 rng.seed[pr_class] = rng.init[pr_class] = seed; } +/** Sets both the initial seed and the current seed. + * Used for netgame sync. + * + * \param pr_class RNG class to adjust. + * \param init Sent initial seed. + * \param seed Sent current seed. + * \sa P_SetRandSeed + */ +#ifndef DEBUGRANDOM +void P_SetRandSeedNet(pr_class_t pr_class, UINT32 init, UINT32 seed) +{ +#else +void P_SetRandSeedNetD(const char *rfile, INT32 rline, pr_class_t pr_class, UINT32 init, UINT32 seed) +{ + CONS_Printf("P_SetRandSeedNet(%u) at: %sp %d\n", pr_class, rfile, rline); +#endif + if (!init) init = DEFAULT_SEED; + rng.init[pr_class] = init; + + if (!seed) seed = DEFAULT_SEED; + rng.seed[pr_class] = seed; +} + /** Initializes random seeds for all classes. - * Used at the beginning of the game. + * Used at the beginning of a game. * * \param rindex New random index. * \sa P_SetRandSeed diff --git a/src/m_random.h b/src/m_random.h index bf3884eec..6f534b219 100644 --- a/src/m_random.h +++ b/src/m_random.h @@ -106,13 +106,16 @@ fixed_t P_RandomPeek(pr_class_t pr_class); #define P_GetRandSeed(pr) P_GetRandSeedD(__FILE__, __LINE__, pr) #define P_GetInitSeed(pr) P_GetInitSeedD(__FILE__, __LINE__, pr) #define P_SetRandSeed(pr, s) P_SetRandSeedD(__FILE__, __LINE__, pr, s) +#define P_SetRandSeedNet(pr, i, s) P_SetRandSeedD(__FILE__, __LINE__, pr, i, s) UINT32 P_GetRandSeedD(const char *rfile, INT32 rline, pr_class_t pr_class); UINT32 P_GetInitSeedD(const char *rfile, INT32 rline, pr_class_t pr_class); void P_SetRandSeedD(const char *rfile, INT32 rline, pr_class_t pr_class, UINT32 seed); +void P_SetRandSeedNetD(const char *rfile, INT32 rline, pr_class_t pr_class, UINT32 init, UINT32 seed); #else UINT32 P_GetRandSeed(pr_class_t pr_class); UINT32 P_GetInitSeed(pr_class_t pr_class); void P_SetRandSeed(pr_class_t pr_class, UINT32 seed); +void P_SetRandSeedNet(pr_class_t pr_class, UINT32 init, UINT32 seed); #endif void P_ClearRandom(UINT32 seed); diff --git a/src/p_saveg.c b/src/p_saveg.c index d7756f0f7..b668c322b 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -4452,6 +4452,17 @@ static inline void P_UnArchiveSPGame(INT16 mapoverride) playeringame[consoleplayer] = true; } +static void P_NetArchiveRNG(void) +{ + size_t i; + + for (i = 0; i < PRNUMCLASS; i++) + { + WRITEUINT32(save_p, P_GetInitSeed(i)); + WRITEUINT32(save_p, P_GetRandSeed(i)); + } +} + static void P_NetArchiveMisc(boolean resending) { size_t i; @@ -4475,10 +4486,7 @@ static void P_NetArchiveMisc(boolean resending) WRITEUINT32(save_p, pig); } - for (i = 0; i < PRNUMCLASS; i++) - { - WRITEUINT32(save_p, P_GetRandSeed(i)); - } + P_NetArchiveRNG(); WRITEUINT32(save_p, tokenlist); @@ -4602,6 +4610,19 @@ static void P_NetArchiveMisc(boolean resending) } } +static inline void P_NetUnArchiveRNG(void) +{ + size_t i; + + for (i = 0; i < PRNUMCLASS; i++) + { + UINT32 init = READUINT32(save_p); + UINT32 seed = READUINT32(save_p); + + P_SetRandSeedNet(i, init, seed); + } +} + static inline boolean P_NetUnArchiveMisc(boolean reloading) { size_t i; @@ -4638,10 +4659,7 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading) } } - for (i = 0; i < PRNUMCLASS; i++) - { - P_SetRandSeed(i, READUINT32(save_p)); - } + P_NetUnArchiveRNG(); tokenlist = READUINT32(save_p); @@ -4894,8 +4912,6 @@ boolean P_LoadGame(INT16 mapoverride) boolean P_LoadNetGame(boolean reloading) { - size_t i; - CV_LoadNetVars(&save_p); if (!P_NetUnArchiveMisc(reloading)) @@ -4918,12 +4934,6 @@ boolean P_LoadNetGame(boolean reloading) LUA_UnArchive(&save_p); - // This is stupid and hacky, but maybe it'll work! - for (i = 0; i < PRNUMCLASS; i++) - { - P_SetRandSeed(i, P_GetInitSeed(i)); - } - // The precipitation would normally be spawned in P_SetupLevel, which is called by // P_NetUnArchiveMisc above. However, that would place it up before P_NetUnArchiveThinkers, // so the thinkers would be deleted later. Therefore, P_SetupLevel will *not* spawn