diff --git a/src/g_game.c b/src/g_game.c index 063e9a60..c455b3c9 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4656,8 +4656,14 @@ char *G_BuildMapTitle(INT32 mapnum) #define DEMOMARKER 0x80 // demoend UINT8 demo_extradata[MAXPLAYERS]; +UINT8 demo_writerng; // 0=no, 1=yes, 2=yes but on a timeout static ticcmd_t oldcmd[MAXPLAYERS]; +#define DW_END 0xFF // End of extradata block +#define DW_RNG 0xFE // Check RNG seed! + +#define DW_EXTRASTUFF 0xFE // Numbers below this are reserved for writing player slot data + // For Metal Sonic and time attack ghosts #define GZT_XYZ 0x01 #define GZT_MOMXY 0x02 @@ -4727,7 +4733,7 @@ void G_ReadDemoExtraData(void) p = READUINT8(demo_p); - while (p != 0xFF) + while (p < DW_EXTRASTUFF) { extradata = READUINT8(demo_p); @@ -4810,6 +4816,24 @@ void G_ReadDemoExtraData(void) p = READUINT8(demo_p); } + while (p != DW_END) + { + INT32 rng; + + switch (p) + { + case DW_RNG: + rng = READUINT32(demo_p); + if (P_GetRandSeed() != rng) + { + P_SetRandSeed(rng); + CONS_Alert(CONS_WARNING, "Random seed has desynced!\n"); + } + } + + p = READUINT8(demo_p); + } + if (!(demoflags & DF_GHOST) && *demo_p == DEMOMARKER) { // end of demo data stream @@ -4857,6 +4881,7 @@ void G_WriteDemoExtraData(void) } if (demo_extradata[i] & DXD_PLAYSTATE) { + demo_writerng = 1; if (!playeringame[i]) WRITEUINT8(demo_p, DXD_PST_LEFT); else if ( @@ -4872,7 +4897,25 @@ void G_WriteDemoExtraData(void) demo_extradata[i] = 0; } - WRITEUINT8(demo_p, 0xFF); + // May not be necessary, but might as well play it safe... + if ((leveltime & 255) == 128) + demo_writerng = 1; + + { + static UINT8 timeout = 0; + + if (timeout) timeout--; + + if (demo_writerng == 1 || (demo_writerng == 2 && timeout == 0)) + { + demo_writerng = 0; + timeout = 16; + WRITEUINT8(demo_p, DW_RNG); + WRITEUINT32(demo_p, P_GetRandSeed()); + } + } + + WRITEUINT8(demo_p, DW_END); } void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum) diff --git a/src/g_game.h b/src/g_game.h index 6e4f6408..73dcb1ce 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -155,6 +155,7 @@ typedef enum } ghostcolor_t; extern UINT8 demo_extradata[MAXPLAYERS]; +extern UINT8 demo_writerng; #define DXD_RESPAWN 0x01 // "respawn" command in console #define DXD_SKIN 0x02 // skin changed #define DXD_NAME 0x04 // name changed diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 78f972f8..36becc56 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -163,6 +163,7 @@ static int lib_pRandomFixed(lua_State *L) { NOHUD lua_pushfixed(L, P_RandomFixed()); + demo_writerng = 2; return 1; } @@ -170,6 +171,7 @@ static int lib_pRandomByte(lua_State *L) { NOHUD lua_pushinteger(L, P_RandomByte()); + demo_writerng = 2; return 1; } @@ -181,6 +183,7 @@ static int lib_pRandomKey(lua_State *L) if (a > 65536) LUA_UsageWarning(L, "P_RandomKey: range > 65536 is undefined behavior"); lua_pushinteger(L, P_RandomKey(a)); + demo_writerng = 2; return 1; } @@ -198,6 +201,7 @@ static int lib_pRandomRange(lua_State *L) if ((b-a+1) > 65536) LUA_UsageWarning(L, "P_RandomRange: range > 65536 is undefined behavior"); lua_pushinteger(L, P_RandomRange(a, b)); + demo_writerng = 2; return 1; } @@ -207,6 +211,7 @@ static int lib_pRandom(lua_State *L) NOHUD LUA_Deprecated(L, "P_Random", "P_RandomByte"); lua_pushinteger(L, P_RandomByte()); + demo_writerng = 2; return 1; } @@ -214,6 +219,7 @@ static int lib_pSignedRandom(lua_State *L) { NOHUD lua_pushinteger(L, P_SignedRandom()); + demo_writerng = 2; return 1; } @@ -222,6 +228,7 @@ static int lib_pRandomChance(lua_State *L) fixed_t p = luaL_checkfixed(L, 1); NOHUD lua_pushboolean(L, P_RandomChance(p)); + demo_writerng = 2; return 1; }