From 597b06ae52f82a7d38b7887721dd998d0e443401 Mon Sep 17 00:00:00 2001 From: Boondorl Date: Sat, 4 May 2024 20:35:44 -0400 Subject: [PATCH] Added CRandom functions Unique RNG namespace for client-side effects and HUDs. Identifiers for these cannot clash with identifiers that affect the playsim making them completely safe to use in HUD elements. They also won't be saved. --- src/bbannouncer.cpp | 2 +- src/common/audio/sound/s_sound.cpp | 2 +- src/common/engine/m_random.cpp | 50 ++++++++++++------- src/common/engine/m_random.h | 11 ++-- src/common/engine/namedef.h | 6 +++ src/common/scripting/backend/codegen.cpp | 38 +++++++++++--- src/d_netinfo.cpp | 2 +- src/g_game.cpp | 4 +- src/g_level.cpp | 2 +- src/g_statusbar/sbarinfo_commands.cpp | 2 +- src/gamedata/decallib.cpp | 4 +- src/gamedata/info.cpp | 2 +- src/gamedata/textures/animations.cpp | 2 +- src/p_conversation.cpp | 2 +- src/playsim/a_dynlight.cpp | 2 +- src/playsim/a_specialspot.cpp | 2 +- src/playsim/bots/b_func.cpp | 2 +- src/playsim/bots/b_game.cpp | 2 +- src/playsim/bots/b_move.cpp | 6 +-- src/playsim/bots/b_think.cpp | 2 +- src/playsim/fragglescript/t_func.cpp | 2 +- src/playsim/mapthinkers/a_lightning.cpp | 2 +- src/playsim/mapthinkers/a_lights.cpp | 8 +-- src/playsim/mapthinkers/a_plats.cpp | 2 +- src/playsim/mapthinkers/a_quake.cpp | 2 +- src/playsim/p_acs.cpp | 2 +- src/playsim/p_actionfunctions.cpp | 28 +++++------ src/playsim/p_effect.cpp | 2 +- src/playsim/p_enemy.cpp | 38 +++++++------- src/playsim/p_interaction.cpp | 12 ++--- src/playsim/p_lnspec.cpp | 2 +- src/playsim/p_map.cpp | 8 +-- src/playsim/p_mobj.cpp | 42 ++++++++-------- src/playsim/p_sight.cpp | 4 +- src/playsim/p_spec.cpp | 2 +- src/playsim/p_switch.cpp | 2 +- src/playsim/p_teleport.cpp | 3 +- src/playsim/p_things.cpp | 2 +- src/playsim/p_user.cpp | 2 +- src/playsim/shadowinlines.h | 2 +- src/rendering/r_utility.cpp | 4 +- src/scripting/decorate/thingdef_exp.cpp | 35 +++++++------ src/sound/s_doomsound.cpp | 2 +- src/sound/s_sndseq.cpp | 2 +- wadsrc/static/zscript/engine/base.zs | 4 +- .../zscript/ui/menu/conversationmenu.zs | 6 +-- .../zscript/ui/statusbar/heretic_sbar.zs | 2 +- 47 files changed, 213 insertions(+), 154 deletions(-) diff --git a/src/bbannouncer.cpp b/src/bbannouncer.cpp index 07bc2305e7..caf9f9f42a 100644 --- a/src/bbannouncer.cpp +++ b/src/bbannouncer.cpp @@ -169,7 +169,7 @@ static const char *TelefragSounds[] = #endif static int LastAnnounceTime; -static FRandom pr_bbannounce ("BBAnnounce"); +static FRandom pr_bbannounce ("BBAnnounce", true); // CODE -------------------------------------------------------------------- diff --git a/src/common/audio/sound/s_sound.cpp b/src/common/audio/sound/s_sound.cpp index 852d389f5a..b9084692d5 100644 --- a/src/common/audio/sound/s_sound.cpp +++ b/src/common/audio/sound/s_sound.cpp @@ -61,7 +61,7 @@ enum { DEFAULT_PITCH = 128, }; -static FRandom pr_soundpitch ("SoundPitch"); +static FRandom pr_soundpitch ("SoundPitch", true); SoundEngine* soundEngine; //========================================================================== diff --git a/src/common/engine/m_random.cpp b/src/common/engine/m_random.cpp index 3af14526bb..df4d532176 100644 --- a/src/common/engine/m_random.cpp +++ b/src/common/engine/m_random.cpp @@ -79,11 +79,11 @@ // EXTERNAL DATA DECLARATIONS ---------------------------------------------- -FRandom pr_exrandom("EX_Random"); +FRandom pr_exrandom("EX_Random", false); // PUBLIC DATA DEFINITIONS ------------------------------------------------- -FRandom M_Random; +FRandom M_Random(true); // Global seed. This is modified predictably to initialize every RNG. uint32_t rngseed; @@ -126,8 +126,8 @@ CCMD(rngseed) // PRIVATE DATA DEFINITIONS ------------------------------------------------ -FRandom *FRandom::RNGList; -static TDeletingArray NewRNGs; +FRandom *FRandom::RNGList, *FRandom::CRNGList; +static TDeletingArray NewRNGs, NewCRNGs; // CODE -------------------------------------------------------------------- @@ -139,14 +139,22 @@ static TDeletingArray NewRNGs; // //========================================================================== -FRandom::FRandom () -: NameCRC (0) +FRandom::FRandom (bool client) +: NameCRC (0), bClient(client) { #ifndef NDEBUG Name = NULL; #endif - Next = RNGList; - RNGList = this; + if (client) + { + Next = CRNGList; + CRNGList = this; + } + else + { + Next = RNGList; + RNGList = this; + } Init(0); } @@ -158,7 +166,7 @@ FRandom::FRandom () // //========================================================================== -FRandom::FRandom (const char *name) +FRandom::FRandom (const char *name, bool client) : bClient(client) { NameCRC = CalcCRC32 ((const uint8_t *)name, (unsigned int)strlen (name)); #ifndef NDEBUG @@ -170,7 +178,7 @@ FRandom::FRandom (const char *name) #endif // Insert the RNG in the list, sorted by CRC - FRandom **prev = &RNGList, *probe = RNGList; + FRandom **prev = (client ? &CRNGList : &RNGList), * probe = (client ? CRNGList : RNGList); while (probe != NULL && probe->NameCRC < NameCRC) { @@ -205,8 +213,8 @@ FRandom::~FRandom () FRandom *last = NULL; - prev = &RNGList; - rng = RNGList; + prev = bClient ? &CRNGList : &RNGList; + rng = bClient ? CRNGList : RNGList; while (rng != NULL && rng != this) { @@ -237,6 +245,11 @@ void FRandom::StaticClearRandom () { rng->Init(rngseed); } + + for (FRandom* rng = FRandom::CRNGList; rng != NULL; rng = rng->Next) + { + rng->Init(rngseed); + } } //========================================================================== @@ -345,15 +358,15 @@ void FRandom::StaticReadRNGState(FSerializer &arc) // //========================================================================== -FRandom *FRandom::StaticFindRNG (const char *name) +FRandom *FRandom::StaticFindRNG (const char *name, bool client) { uint32_t NameCRC = CalcCRC32 ((const uint8_t *)name, (unsigned int)strlen (name)); // Use the default RNG if this one happens to have a CRC of 0. - if (NameCRC == 0) return &pr_exrandom; + if (NameCRC == 0) return client ? &M_Random : &pr_exrandom; // Find the RNG in the list, sorted by CRC - FRandom **prev = &RNGList, *probe = RNGList; + FRandom **prev = (client ? &CRNGList : &RNGList), *probe = (client ? CRNGList : RNGList); while (probe != NULL && probe->NameCRC < NameCRC) { @@ -364,10 +377,13 @@ FRandom *FRandom::StaticFindRNG (const char *name) if (probe == NULL || probe->NameCRC != NameCRC) { // A matching RNG doesn't exist yet so create it. - probe = new FRandom(name); + probe = new FRandom(name, client); // Store the new RNG for destruction when ZDoom quits. - NewRNGs.Push(probe); + if (client) + NewCRNGs.Push(probe); + else + NewRNGs.Push(probe); } return probe; } diff --git a/src/common/engine/m_random.h b/src/common/engine/m_random.h index d9eec6c44c..991d812dbf 100644 --- a/src/common/engine/m_random.h +++ b/src/common/engine/m_random.h @@ -44,8 +44,8 @@ class FSerializer; class FRandom : public SFMTObj { public: - FRandom (); - FRandom (const char *name); + FRandom (bool client); + FRandom (const char *name, bool client); ~FRandom (); int Seed() const @@ -170,7 +170,9 @@ public: static void StaticClearRandom (); static void StaticReadRNGState (FSerializer &arc); static void StaticWriteRNGState (FSerializer &file); - static FRandom *StaticFindRNG(const char *name); + static FRandom *StaticFindRNG(const char *name, bool client); + static void SaveRNGState(TArray& backups); + static void RestoreRNGState(TArray& backups); #ifndef NDEBUG static void StaticPrintSeeds (); @@ -182,8 +184,9 @@ private: #endif FRandom *Next; uint32_t NameCRC; + bool bClient; - static FRandom *RNGList; + static FRandom *RNGList, *CRNGList; }; extern uint32_t rngseed; // The starting seed (not part of state) diff --git a/src/common/engine/namedef.h b/src/common/engine/namedef.h index 13827382c0..be0c47649e 100644 --- a/src/common/engine/namedef.h +++ b/src/common/engine/namedef.h @@ -41,6 +41,12 @@ xx(Random2) xx(RandomPick) xx(FRandomPick) xx(SetRandomSeed) +xx(CRandom) +xx(CFRandom) +xx(CRandom2) +xx(CRandomPick) +xx(CFRandomPick) +xx(CSetRandomSeed) xx(BuiltinRandomSeed) xx(BuiltinNew) xx(GetClass) diff --git a/src/common/scripting/backend/codegen.cpp b/src/common/scripting/backend/codegen.cpp index df1c48c22e..86bd606f9e 100644 --- a/src/common/scripting/backend/codegen.cpp +++ b/src/common/scripting/backend/codegen.cpp @@ -8268,8 +8268,12 @@ static bool CheckFunctionCompatiblity(FScriptPosition &ScriptPosition, PFunction FxFunctionCall::FxFunctionCall(FName methodname, FName rngname, FArgumentList &&args, const FScriptPosition &pos) : FxExpression(EFX_FunctionCall, pos) { + const bool isClient = methodname == NAME_CRandom || methodname == NAME_CFRandom + || methodname == NAME_CRandomPick || methodname == NAME_CFRandomPick + || methodname == NAME_CRandom2 || methodname == NAME_CSetRandomSeed; + MethodName = methodname; - RNG = &pr_exrandom; + RNG = isClient ? &M_Random : &pr_exrandom; ArgList = std::move(args); if (rngname != NAME_None) { @@ -8281,7 +8285,16 @@ FxFunctionCall::FxFunctionCall(FName methodname, FName rngname, FArgumentList && case NAME_FRandomPick: case NAME_Random2: case NAME_SetRandomSeed: - RNG = FRandom::StaticFindRNG(rngname.GetChars()); + RNG = FRandom::StaticFindRNG(rngname.GetChars(), false); + break; + + case NAME_CRandom: + case NAME_CFRandom: + case NAME_CRandomPick: + case NAME_CFRandomPick: + case NAME_CRandom2: + case NAME_CSetRandomSeed: + RNG = FRandom::StaticFindRNG(rngname.GetChars(), true); break; default: @@ -8547,13 +8560,22 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx) } break; + case NAME_CSetRandomSeed: + if (CheckArgSize(NAME_CRandom, ArgList, 1, 1, ScriptPosition)) + { + func = new FxRandomSeed(RNG, ArgList[0], ScriptPosition, ctx.FromDecorate); + ArgList[0] = nullptr; + } + break; + case NAME_Random: + case NAME_CRandom: // allow calling Random without arguments to default to (0, 255) if (ArgList.Size() == 0) { func = new FxRandom(RNG, new FxConstant(0, ScriptPosition), new FxConstant(255, ScriptPosition), ScriptPosition, ctx.FromDecorate); } - else if (CheckArgSize(NAME_Random, ArgList, 2, 2, ScriptPosition)) + else if (CheckArgSize(MethodName, ArgList, 2, 2, ScriptPosition)) { func = new FxRandom(RNG, ArgList[0], ArgList[1], ScriptPosition, ctx.FromDecorate); ArgList[0] = ArgList[1] = nullptr; @@ -8561,7 +8583,8 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx) break; case NAME_FRandom: - if (CheckArgSize(NAME_FRandom, ArgList, 2, 2, ScriptPosition)) + case NAME_CFRandom: + if (CheckArgSize(MethodName, ArgList, 2, 2, ScriptPosition)) { func = new FxFRandom(RNG, ArgList[0], ArgList[1], ScriptPosition); ArgList[0] = ArgList[1] = nullptr; @@ -8570,14 +8593,17 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx) case NAME_RandomPick: case NAME_FRandomPick: + case NAME_CRandomPick: + case NAME_CFRandomPick: if (CheckArgSize(MethodName, ArgList, 1, -1, ScriptPosition)) { - func = new FxRandomPick(RNG, ArgList, MethodName == NAME_FRandomPick, ScriptPosition, ctx.FromDecorate); + func = new FxRandomPick(RNG, ArgList, MethodName == NAME_FRandomPick || MethodName == NAME_CFRandomPick, ScriptPosition, ctx.FromDecorate); } break; case NAME_Random2: - if (CheckArgSize(NAME_Random2, ArgList, 0, 1, ScriptPosition)) + case NAME_CRandom2: + if (CheckArgSize(MethodName, ArgList, 0, 1, ScriptPosition)) { func = new FxRandom2(RNG, ArgList.Size() == 0? nullptr : ArgList[0], ScriptPosition, ctx.FromDecorate); if (ArgList.Size() > 0) ArgList[0] = nullptr; diff --git a/src/d_netinfo.cpp b/src/d_netinfo.cpp index bac6eddfe8..369abcca30 100644 --- a/src/d_netinfo.cpp +++ b/src/d_netinfo.cpp @@ -52,7 +52,7 @@ #include "gstrings.h" #include "g_game.h" -static FRandom pr_pickteam ("PickRandomTeam"); +static FRandom pr_pickteam ("PickRandomTeam", false); CVAR (Float, autoaim, 35.f, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (String, name, "Player", CVAR_USERINFO | CVAR_ARCHIVE); diff --git a/src/g_game.cpp b/src/g_game.cpp index 42ce6e99a9..774c7b5b24 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -93,8 +93,8 @@ #include "fs_findfile.h" -static FRandom pr_dmspawn ("DMSpawn"); -static FRandom pr_pspawn ("PlayerSpawn"); +static FRandom pr_dmspawn ("DMSpawn", false); +static FRandom pr_pspawn ("PlayerSpawn", false); extern int startpos, laststartpos; diff --git a/src/g_level.cpp b/src/g_level.cpp index bc0cd378af..0cf5ddb21a 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -175,7 +175,7 @@ ELightMode getRealLightmode(FLevelLocals* Level, bool for3d) CVAR(Int, sv_alwaystally, 0, CVAR_SERVERINFO) -static FRandom pr_classchoice ("RandomPlayerClassChoice"); +static FRandom pr_classchoice ("RandomPlayerClassChoice", false); extern level_info_t TheDefaultLevelInfo; extern bool timingdemo; diff --git a/src/g_statusbar/sbarinfo_commands.cpp b/src/g_statusbar/sbarinfo_commands.cpp index 749294adc2..85944b6478 100644 --- a/src/g_statusbar/sbarinfo_commands.cpp +++ b/src/g_statusbar/sbarinfo_commands.cpp @@ -3227,7 +3227,7 @@ class CommandDrawGem : public SBarInfoCommand int chainWiggle; static FRandom pr_chainwiggle; }; -FRandom CommandDrawGem::pr_chainwiggle; //use the same method of chain wiggling as heretic. +FRandom CommandDrawGem::pr_chainwiggle(true); //use the same method of chain wiggling as heretic. //////////////////////////////////////////////////////////////////////////////// diff --git a/src/gamedata/decallib.cpp b/src/gamedata/decallib.cpp index 6243502f84..2babc3b458 100644 --- a/src/gamedata/decallib.cpp +++ b/src/gamedata/decallib.cpp @@ -60,8 +60,8 @@ static TArray DecalTranslations; // Sometimes two machines in a game will disagree on the state of // decals. I do not know why. -static FRandom pr_decalchoice ("DecalChoice"); -static FRandom pr_decal ("Decal"); +static FRandom pr_decalchoice ("DecalChoice", true); +static FRandom pr_decal ("Decal", true); class FDecalGroup : public FDecalBase { diff --git a/src/gamedata/info.cpp b/src/gamedata/info.cpp index 67fb87f678..6cff5943ec 100644 --- a/src/gamedata/info.cpp +++ b/src/gamedata/info.cpp @@ -61,7 +61,7 @@ extern void InitBotStuff(); extern void ClearStrifeTypes(); TArray PClassActor::AllActorClasses; -FRandom FState::pr_statetics("StateTics"); +FRandom FState::pr_statetics("StateTics", false); cycle_t ActionCycles; diff --git a/src/gamedata/textures/animations.cpp b/src/gamedata/textures/animations.cpp index b0dce0a551..5cd072b149 100644 --- a/src/gamedata/textures/animations.cpp +++ b/src/gamedata/textures/animations.cpp @@ -56,7 +56,7 @@ FTextureAnimator TexAnim; // PRIVATE DATA DEFINITIONS ------------------------------------------------ -static FRandom pr_animatepictures ("AnimatePics"); +static FRandom pr_animatepictures ("AnimatePics", true); // CODE -------------------------------------------------------------------- diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index f8ee0a8e5b..f897db7598 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -62,7 +62,7 @@ #include "doommenu.h" #include "g_game.h" -static FRandom pr_randomspeech("RandomSpeech"); +static FRandom pr_randomspeech("RandomSpeech", true); static int ConversationMenuY; diff --git a/src/playsim/a_dynlight.cpp b/src/playsim/a_dynlight.cpp index 3dc653898e..1470b07961 100644 --- a/src/playsim/a_dynlight.cpp +++ b/src/playsim/a_dynlight.cpp @@ -67,7 +67,7 @@ static FMemArena DynLightArena(sizeof(FDynamicLight) * 200); static TArray FreeList; -static FRandom randLight; +static FRandom randLight(true); extern TArray StateLights; diff --git a/src/playsim/a_specialspot.cpp b/src/playsim/a_specialspot.cpp index b658c18300..b332b78004 100644 --- a/src/playsim/a_specialspot.cpp +++ b/src/playsim/a_specialspot.cpp @@ -39,7 +39,7 @@ #include "a_pickups.h" #include "vm.h" -static FRandom pr_spot ("SpecialSpot"); +static FRandom pr_spot ("SpecialSpot", false); IMPLEMENT_CLASS(DSpotState, false, false) diff --git a/src/playsim/bots/b_func.cpp b/src/playsim/bots/b_func.cpp index e537bf9f7e..fa9f2c80d7 100644 --- a/src/playsim/bots/b_func.cpp +++ b/src/playsim/bots/b_func.cpp @@ -54,7 +54,7 @@ #include "p_checkposition.h" #include "actorinlines.h" -static FRandom pr_botdofire ("BotDoFire"); +static FRandom pr_botdofire ("BotDoFire", false); //Checks TRUE reachability from bot to a looker. diff --git a/src/playsim/bots/b_game.cpp b/src/playsim/bots/b_game.cpp index 3863ac923b..eb8eb5d1ab 100644 --- a/src/playsim/bots/b_game.cpp +++ b/src/playsim/bots/b_game.cpp @@ -98,7 +98,7 @@ Everything that is changed is marked (maybe commented) with "Added by MC" #include "i_system.h" // for SHARE_DIR #endif // !_WIN32 && !__APPLE__ -static FRandom pr_botspawn ("BotSpawn"); +static FRandom pr_botspawn ("BotSpawn", false); cycle_t BotThinkCycles, BotSupportCycles; int BotWTG; diff --git a/src/playsim/bots/b_move.cpp b/src/playsim/bots/b_move.cpp index 4d91839d8e..0922618322 100644 --- a/src/playsim/bots/b_move.cpp +++ b/src/playsim/bots/b_move.cpp @@ -53,9 +53,9 @@ #include "p_checkposition.h" #include "actorinlines.h" -static FRandom pr_botopendoor ("BotOpenDoor"); -static FRandom pr_bottrywalk ("BotTryWalk"); -static FRandom pr_botnewchasedir ("BotNewChaseDir"); +static FRandom pr_botopendoor ("BotOpenDoor", false); +static FRandom pr_bottrywalk ("BotTryWalk", false); +static FRandom pr_botnewchasedir ("BotNewChaseDir", false); // borrow some tables from p_enemy.cpp extern dirtype_t opposite[9]; diff --git a/src/playsim/bots/b_think.cpp b/src/playsim/bots/b_think.cpp index 9fba192d58..deef49aa12 100644 --- a/src/playsim/bots/b_think.cpp +++ b/src/playsim/bots/b_think.cpp @@ -52,7 +52,7 @@ #include "d_player.h" #include "actorinlines.h" -static FRandom pr_botmove ("BotMove"); +static FRandom pr_botmove ("BotMove", false); //This function is called each tic for each bot, //so this is what the bot does. diff --git a/src/playsim/fragglescript/t_func.cpp b/src/playsim/fragglescript/t_func.cpp index f9fff1b9ef..3a463c3a20 100644 --- a/src/playsim/fragglescript/t_func.cpp +++ b/src/playsim/fragglescript/t_func.cpp @@ -56,7 +56,7 @@ using namespace FileSys; -static FRandom pr_script("FScript"); +static FRandom pr_script("FScript", false); // functions. FParser::SF_ means Script Function not, well.. heh, me diff --git a/src/playsim/mapthinkers/a_lightning.cpp b/src/playsim/mapthinkers/a_lightning.cpp index f6e0f713dd..47f6623b11 100644 --- a/src/playsim/mapthinkers/a_lightning.cpp +++ b/src/playsim/mapthinkers/a_lightning.cpp @@ -38,7 +38,7 @@ #include "gi.h" #include -static FRandom pr_lightning ("Lightning"); +static FRandom pr_lightning ("Lightning", false); IMPLEMENT_CLASS(DLightningThinker, false, false) diff --git a/src/playsim/mapthinkers/a_lights.cpp b/src/playsim/mapthinkers/a_lights.cpp index 9cd7fb20f1..48acdcd762 100644 --- a/src/playsim/mapthinkers/a_lights.cpp +++ b/src/playsim/mapthinkers/a_lights.cpp @@ -43,10 +43,10 @@ // State. #include "serializer.h" -static FRandom pr_flicker ("Flicker"); -static FRandom pr_lightflash ("LightFlash"); -static FRandom pr_strobeflash ("StrobeFlash"); -static FRandom pr_fireflicker ("FireFlicker"); +static FRandom pr_flicker ("Flicker", true); +static FRandom pr_lightflash ("LightFlash", true); +static FRandom pr_strobeflash ("StrobeFlash", true); +static FRandom pr_fireflicker ("FireFlicker", true); //----------------------------------------------------------------------------- diff --git a/src/playsim/mapthinkers/a_plats.cpp b/src/playsim/mapthinkers/a_plats.cpp index c688295e4e..0f6fa9ce96 100644 --- a/src/playsim/mapthinkers/a_plats.cpp +++ b/src/playsim/mapthinkers/a_plats.cpp @@ -37,7 +37,7 @@ #include "p_spec.h" #include "g_levellocals.h" -static FRandom pr_doplat ("DoPlat"); +static FRandom pr_doplat ("DoPlat", false); IMPLEMENT_CLASS(DPlat, false, false) diff --git a/src/playsim/mapthinkers/a_quake.cpp b/src/playsim/mapthinkers/a_quake.cpp index b21951562e..e6fb687fa5 100644 --- a/src/playsim/mapthinkers/a_quake.cpp +++ b/src/playsim/mapthinkers/a_quake.cpp @@ -36,7 +36,7 @@ #include "actorinlines.h" #include -static FRandom pr_quake ("Quake"); +static FRandom pr_quake ("Quake", true); IMPLEMENT_CLASS(DEarthquake, false, true) diff --git a/src/playsim/p_acs.cpp b/src/playsim/p_acs.cpp index 89aee643d2..211b155c29 100644 --- a/src/playsim/p_acs.cpp +++ b/src/playsim/p_acs.cpp @@ -540,7 +540,7 @@ -FRandom pr_acs ("ACS"); +FRandom pr_acs ("ACS", false); // I imagine this much stack space is probably overkill, but it could // potentially get used with recursive functions. diff --git a/src/playsim/p_actionfunctions.cpp b/src/playsim/p_actionfunctions.cpp index ea7090c1df..91bff0bc20 100644 --- a/src/playsim/p_actionfunctions.cpp +++ b/src/playsim/p_actionfunctions.cpp @@ -73,19 +73,19 @@ #include "shadowinlines.h" #include "i_time.h" -static FRandom pr_camissile ("CustomActorfire"); -static FRandom pr_cabullet ("CustomBullet"); -static FRandom pr_cwjump ("CustomWpJump"); -static FRandom pr_cwpunch ("CustomWpPunch"); -static FRandom pr_grenade ("ThrowGrenade"); - FRandom pr_crailgun ("CustomRailgun"); -static FRandom pr_spawndebris ("SpawnDebris"); -static FRandom pr_spawnitemex ("SpawnItemEx"); -static FRandom pr_burst ("Burst"); -static FRandom pr_monsterrefire ("MonsterRefire"); -static FRandom pr_teleport("A_Teleport"); -static FRandom pr_bfgselfdamage("BFGSelfDamage"); - FRandom pr_cajump("CustomJump"); +static FRandom pr_camissile ("CustomActorfire", false); +static FRandom pr_cabullet ("CustomBullet", false); +static FRandom pr_cwjump ("CustomWpJump", false); +static FRandom pr_cwpunch ("CustomWpPunch", false); +static FRandom pr_grenade ("ThrowGrenade", false); + FRandom pr_crailgun ("CustomRailgun", false); +static FRandom pr_spawndebris ("SpawnDebris", false); +static FRandom pr_spawnitemex ("SpawnItemEx", false); +static FRandom pr_burst ("Burst", false); +static FRandom pr_monsterrefire ("MonsterRefire", false); +static FRandom pr_teleport("A_Teleport", false); +static FRandom pr_bfgselfdamage("BFGSelfDamage", false); + FRandom pr_cajump("CustomJump", false); //========================================================================== // @@ -746,7 +746,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_StopSoundEx) // Generic seeker missile function // //========================================================================== -static FRandom pr_seekermissile ("SeekerMissile"); +static FRandom pr_seekermissile ("SeekerMissile", false); enum { SMF_LOOK = 1, diff --git a/src/playsim/p_effect.cpp b/src/playsim/p_effect.cpp index f96ec13011..31b3e3128b 100644 --- a/src/playsim/p_effect.cpp +++ b/src/playsim/p_effect.cpp @@ -65,7 +65,7 @@ CVAR (Int, r_rail_trailsparsity, 1, CVAR_ARCHIVE); CVAR (Bool, r_particles, true, 0); EXTERN_CVAR(Int, r_maxparticles); -FRandom pr_railtrail("RailTrail"); +FRandom pr_railtrail("RailTrail", true); #define FADEFROMTTL(a) (1.f/(a)) diff --git a/src/playsim/p_enemy.cpp b/src/playsim/p_enemy.cpp index 120f37231e..d3a5a66b21 100644 --- a/src/playsim/p_enemy.cpp +++ b/src/playsim/p_enemy.cpp @@ -54,26 +54,26 @@ #include "gi.h" -static FRandom pr_checkmissilerange ("CheckMissileRange"); -static FRandom pr_opendoor ("OpenDoor"); -static FRandom pr_trywalk ("TryWalk"); -static FRandom pr_newchasedir ("NewChaseDir"); -static FRandom pr_lookformonsters ("LookForMonsters"); -static FRandom pr_lookforplayers ("LookForPlayers"); -static FRandom pr_scaredycat ("Anubis"); - FRandom pr_chase ("Chase"); - FRandom pr_facetarget ("FaceTarget"); - FRandom pr_railface ("RailFace"); -static FRandom pr_look2 ("LookyLooky"); -static FRandom pr_look3 ("IGotHooky"); -static FRandom pr_slook ("SlooK"); -static FRandom pr_dropoff ("Dropoff"); -static FRandom pr_defect ("Defect"); -static FRandom pr_avoidcrush("AvoidCrush"); -static FRandom pr_stayonlift("StayOnLift"); +static FRandom pr_checkmissilerange ("CheckMissileRange", false); +static FRandom pr_opendoor ("OpenDoor", false); +static FRandom pr_trywalk ("TryWalk", false); +static FRandom pr_newchasedir ("NewChaseDir", false); +static FRandom pr_lookformonsters ("LookForMonsters", false); +static FRandom pr_lookforplayers ("LookForPlayers", false); +static FRandom pr_scaredycat ("Anubis", false); + FRandom pr_chase ("Chase", false); + FRandom pr_facetarget ("FaceTarget", false); + FRandom pr_railface ("RailFace", false); +static FRandom pr_look2 ("LookyLooky", false); +static FRandom pr_look3 ("IGotHooky", false); +static FRandom pr_slook ("SlooK", false); +static FRandom pr_dropoff ("Dropoff", false); +static FRandom pr_defect ("Defect", false); +static FRandom pr_avoidcrush("AvoidCrush", false); +static FRandom pr_stayonlift("StayOnLift", false); -static FRandom pr_skiptarget("SkipTarget"); -static FRandom pr_enemystrafe("EnemyStrafe"); +static FRandom pr_skiptarget("SkipTarget", false); +static FRandom pr_enemystrafe("EnemyStrafe", false); // movement interpolation is fine for objects that are moved by their own // velocity. But for monsters it is problematic. diff --git a/src/playsim/p_interaction.cpp b/src/playsim/p_interaction.cpp index 0ae77e914c..eed16b87fc 100644 --- a/src/playsim/p_interaction.cpp +++ b/src/playsim/p_interaction.cpp @@ -63,12 +63,12 @@ #include "actorinlines.h" #include "d_main.h" -static FRandom pr_botrespawn ("BotRespawn"); -static FRandom pr_killmobj ("ActorDie"); -FRandom pr_damagemobj ("ActorTakeDamage"); -static FRandom pr_lightning ("LightningDamage"); -static FRandom pr_poison ("PoisonDamage"); -static FRandom pr_switcher ("SwitchTarget"); +static FRandom pr_botrespawn ("BotRespawn", false); +static FRandom pr_killmobj ("ActorDie", false); +FRandom pr_damagemobj ("ActorTakeDamage", false); +static FRandom pr_lightning ("LightningDamage", false); +static FRandom pr_poison ("PoisonDamage", false); +static FRandom pr_switcher ("SwitchTarget", false); CVAR (Bool, cl_showsprees, true, CVAR_ARCHIVE) CVAR (Bool, cl_showmultikills, true, CVAR_ARCHIVE) diff --git a/src/playsim/p_lnspec.cpp b/src/playsim/p_lnspec.cpp index 00318dfbb1..c0a3997852 100644 --- a/src/playsim/p_lnspec.cpp +++ b/src/playsim/p_lnspec.cpp @@ -95,7 +95,7 @@ static DCeiling::ECrushMode CRUSHTYPE(int a, bool withslowdown) return withslowdown? DCeiling::ECrushMode::crushSlowdown : DCeiling::ECrushMode::crushDoom; } -static FRandom pr_glass ("GlassBreak"); +static FRandom pr_glass ("GlassBreak", false); // There are aliases for the ACS specials that take names instead of numbers. // This table maps them onto the real number-based specials. diff --git a/src/playsim/p_map.cpp b/src/playsim/p_map.cpp index 5892049930..197ab55f1f 100644 --- a/src/playsim/p_map.cpp +++ b/src/playsim/p_map.cpp @@ -103,10 +103,10 @@ static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, DVector2 * static void SpawnShootDecal(AActor *t1, AActor *defaults, const FTraceResults &trace); static void SpawnDeepSplash(AActor *t1, const FTraceResults &trace, AActor *puff); -static FRandom pr_tracebleed("TraceBleed"); -static FRandom pr_checkthing("CheckThing"); -static FRandom pr_lineattack("LineAttack"); -static FRandom pr_crunch("DoCrunch"); +static FRandom pr_tracebleed("TraceBleed", false); +static FRandom pr_checkthing("CheckThing", false); +static FRandom pr_lineattack("LineAttack", false); +static FRandom pr_crunch("DoCrunch", false); // keep track of special lines as they are hit, // but don't process them until the move is proven valid diff --git a/src/playsim/p_mobj.cpp b/src/playsim/p_mobj.cpp index 0f9a918036..bb8d3be1af 100644 --- a/src/playsim/p_mobj.cpp +++ b/src/playsim/p_mobj.cpp @@ -122,29 +122,29 @@ EXTERN_CVAR (Int, cl_rockettrails) // PRIVATE DATA DEFINITIONS ------------------------------------------------ -static FRandom pr_explodemissile ("ExplodeMissile"); -static FRandom pr_reflect ("Reflect"); -static FRandom pr_nightmarerespawn ("NightmareRespawn"); -static FRandom pr_botspawnmobj ("BotSpawnActor"); -static FRandom pr_spawnmapthing ("SpawnMapThing"); -static FRandom pr_spawnpuff ("SpawnPuff"); -static FRandom pr_spawnblood ("SpawnBlood"); -static FRandom pr_splatter ("BloodSplatter"); -static FRandom pr_takedamage ("TakeDamage"); -static FRandom pr_splat ("FAxeSplatter"); -static FRandom pr_ripperblood ("RipperBlood"); -static FRandom pr_chunk ("Chunk"); -static FRandom pr_checkmissilespawn ("CheckMissileSpawn"); -static FRandom pr_missiledamage ("MissileDamage"); -static FRandom pr_multiclasschoice ("MultiClassChoice"); -static FRandom pr_rockettrail("RocketTrail"); -static FRandom pr_uniquetid("UniqueTID"); +static FRandom pr_explodemissile ("ExplodeMissile", false); +static FRandom pr_reflect ("Reflect", false); +static FRandom pr_nightmarerespawn ("NightmareRespawn", false); +static FRandom pr_botspawnmobj ("BotSpawnActor", false); +static FRandom pr_spawnmapthing ("SpawnMapThing", false); +static FRandom pr_spawnpuff ("SpawnPuff", false); +static FRandom pr_spawnblood ("SpawnBlood", false); +static FRandom pr_splatter ("BloodSplatter", false); +static FRandom pr_takedamage ("TakeDamage", false); +static FRandom pr_splat ("FAxeSplatter", false); +static FRandom pr_ripperblood ("RipperBlood", false); +static FRandom pr_chunk ("Chunk", false); +static FRandom pr_checkmissilespawn ("CheckMissileSpawn", false); +static FRandom pr_missiledamage ("MissileDamage", false); +static FRandom pr_multiclasschoice ("MultiClassChoice", false); +static FRandom pr_rockettrail("RocketTrail", false); +static FRandom pr_uniquetid("UniqueTID", false); // PUBLIC DATA DEFINITIONS ------------------------------------------------- -FRandom pr_spawnmobj ("SpawnActor"); -FRandom pr_bounce("Bounce"); -FRandom pr_spawnmissile("SpawnMissile"); +FRandom pr_spawnmobj ("SpawnActor", false); +FRandom pr_bounce("Bounce", false); +FRandom pr_spawnmissile("SpawnMissile", false); CUSTOM_CVAR (Float, sv_gravity, 800.f, CVAR_SERVERINFO|CVAR_NOSAVE|CVAR_NOINITCALL) { @@ -7956,7 +7956,7 @@ void AActor::SetTranslation(FName trname) // PROP A_RestoreSpecialPosition // //--------------------------------------------------------------------------- -static FRandom pr_restore("RestorePos"); +static FRandom pr_restore("RestorePos", false); void AActor::RestoreSpecialPosition() { diff --git a/src/playsim/p_sight.cpp b/src/playsim/p_sight.cpp index 2cf957c8ce..a2fc76c46c 100644 --- a/src/playsim/p_sight.cpp +++ b/src/playsim/p_sight.cpp @@ -37,8 +37,8 @@ #include "g_levellocals.h" #include "actorinlines.h" -static FRandom pr_botchecksight ("BotCheckSight"); -static FRandom pr_checksight ("CheckSight"); +static FRandom pr_botchecksight ("BotCheckSight", false); +static FRandom pr_checksight ("CheckSight", false); /* ============================================================================== diff --git a/src/playsim/p_spec.cpp b/src/playsim/p_spec.cpp index 3851bd7483..385d17f924 100644 --- a/src/playsim/p_spec.cpp +++ b/src/playsim/p_spec.cpp @@ -100,7 +100,7 @@ #include "c_console.h" #include "p_spec_thinkers.h" -static FRandom pr_actorinspecialsector ("ActorInSpecialSector"); +static FRandom pr_actorinspecialsector ("ActorInSpecialSector", false); EXTERN_CVAR(Bool, cl_predict_specials) EXTERN_CVAR(Bool, forcewater) diff --git a/src/playsim/p_switch.cpp b/src/playsim/p_switch.cpp index e89f030114..2af3054d31 100644 --- a/src/playsim/p_switch.cpp +++ b/src/playsim/p_switch.cpp @@ -49,7 +49,7 @@ #include "actorinlines.h" #include "animations.h" -static FRandom pr_switchanim ("AnimSwitch"); +static FRandom pr_switchanim ("AnimSwitch", true); class DActiveButton : public DThinker { diff --git a/src/playsim/p_teleport.cpp b/src/playsim/p_teleport.cpp index a69d3654c0..c39c6df1dc 100644 --- a/src/playsim/p_teleport.cpp +++ b/src/playsim/p_teleport.cpp @@ -36,7 +36,8 @@ #define FUDGEFACTOR 10 -static FRandom pr_teleport ("Teleport"); +static FRandom pr_teleport ("Teleport", false); +static FRandom pr_playerteleport("PlayerTeleport", false); CVAR (Bool, telezoom, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); diff --git a/src/playsim/p_things.cpp b/src/playsim/p_things.cpp index 3391030aac..878366d7b5 100644 --- a/src/playsim/p_things.cpp +++ b/src/playsim/p_things.cpp @@ -47,7 +47,7 @@ #include "actorinlines.h" #include "vm.h" -static FRandom pr_leadtarget ("LeadTarget"); +static FRandom pr_leadtarget ("LeadTarget", false); bool FLevelLocals::EV_Thing_Spawn (int tid, AActor *source, int type, DAngle angle, bool fog, int newtid) { diff --git a/src/playsim/p_user.cpp b/src/playsim/p_user.cpp index a98a7c523c..463d8f6e31 100644 --- a/src/playsim/p_user.cpp +++ b/src/playsim/p_user.cpp @@ -95,7 +95,7 @@ #include "s_music.h" #include "d_main.h" -static FRandom pr_skullpop ("SkullPop"); +static FRandom pr_skullpop ("SkullPop", false); // [SP] Allows respawn in single player CVAR(Bool, sv_singleplayerrespawn, false, CVAR_SERVERINFO | CVAR_CHEAT) diff --git a/src/playsim/shadowinlines.h b/src/playsim/shadowinlines.h index b36b051ac4..6c0e9176f5 100644 --- a/src/playsim/shadowinlines.h +++ b/src/playsim/shadowinlines.h @@ -17,7 +17,7 @@ extern FRandom pr_spawnmissile; extern FRandom pr_facetarget; extern FRandom pr_railface; extern FRandom pr_crailgun; -inline FRandom pr_shadowaimz("VerticalShadowAim"); +inline FRandom pr_shadowaimz("VerticalShadowAim", false); //========================================================================== // diff --git a/src/rendering/r_utility.cpp b/src/rendering/r_utility.cpp index 5313f738c2..7311341e63 100644 --- a/src/rendering/r_utility.cpp +++ b/src/rendering/r_utility.cpp @@ -94,8 +94,8 @@ struct InterpolationViewer // PRIVATE DATA DECLARATIONS ----------------------------------------------- static TArray PastViewers; -static FRandom pr_torchflicker ("TorchFlicker"); -static FRandom pr_hom; +static FRandom pr_torchflicker ("TorchFlicker", true); +static FRandom pr_hom(true); bool NoInterpolateView; // GL needs access to this. static TArray InterpolationPath; diff --git a/src/scripting/decorate/thingdef_exp.cpp b/src/scripting/decorate/thingdef_exp.cpp index 1b27342be0..831fcf0c6c 100644 --- a/src/scripting/decorate/thingdef_exp.cpp +++ b/src/scripting/decorate/thingdef_exp.cpp @@ -47,9 +47,9 @@ extern FRandom pr_exrandom; -static FxExpression *ParseRandom(FScanner &sc, FName identifier, PClassActor *cls); -static FxExpression *ParseRandomPick(FScanner &sc, FName identifier, PClassActor *cls); -static FxExpression *ParseRandom2(FScanner &sc, PClassActor *cls); +static FxExpression *ParseRandom(FScanner &sc, FName identifier, PClassActor *cls, bool client); +static FxExpression *ParseRandomPick(FScanner &sc, FName identifier, PClassActor *cls, bool client); +static FxExpression *ParseRandom2(FScanner &sc, PClassActor *cls, bool client); static FxExpression *ParseAbs(FScanner &sc, PClassActor *cls); static FxExpression *ParseAtan2(FScanner &sc, FName identifier, PClassActor *cls); static FxExpression *ParseMinMax(FScanner &sc, FName identifier, PClassActor *cls); @@ -491,12 +491,17 @@ static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls) { case NAME_Random: case NAME_FRandom: - return ParseRandom(sc, identifier, cls); + case NAME_CRandom: + case NAME_CFRandom: + return ParseRandom(sc, identifier, cls, identifier == NAME_CRandom || identifier == NAME_CFRandom); case NAME_RandomPick: case NAME_FRandomPick: - return ParseRandomPick(sc, identifier, cls); + case NAME_CRandomPick: + case NAME_CFRandomPick: + return ParseRandomPick(sc, identifier, cls, identifier == NAME_CRandomPick || identifier == NAME_CFRandomPick); case NAME_Random2: - return ParseRandom2(sc, cls); + case NAME_CRandom2: + return ParseRandom2(sc, cls, identifier == NAME_CRandom2); default: if (cls != nullptr) { @@ -559,14 +564,14 @@ static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls) return NULL; } -static FRandom *ParseRNG(FScanner &sc) +static FRandom *ParseRNG(FScanner &sc, bool client) { FRandom *rng; if (sc.CheckToken('[')) { sc.MustGetToken(TK_Identifier); - rng = FRandom::StaticFindRNG(sc.String); + rng = FRandom::StaticFindRNG(sc.String, client); sc.MustGetToken(']'); } else @@ -576,9 +581,9 @@ static FRandom *ParseRNG(FScanner &sc) return rng; } -static FxExpression *ParseRandom(FScanner &sc, FName identifier, PClassActor *cls) +static FxExpression *ParseRandom(FScanner &sc, FName identifier, PClassActor *cls, bool client) { - FRandom *rng = ParseRNG(sc); + FRandom *rng = ParseRNG(sc, client); sc.MustGetToken('('); FxExpression *min = ParseExpressionM (sc, cls); @@ -586,7 +591,7 @@ static FxExpression *ParseRandom(FScanner &sc, FName identifier, PClassActor *cl FxExpression *max = ParseExpressionM (sc, cls); sc.MustGetToken(')'); - if (identifier == NAME_Random) + if (identifier == NAME_Random || identifier == NAME_CRandom) { return new FxRandom(rng, min, max, sc, true); } @@ -596,7 +601,7 @@ static FxExpression *ParseRandom(FScanner &sc, FName identifier, PClassActor *cl } } -static FxExpression *ParseRandomPick(FScanner &sc, FName identifier, PClassActor *cls) +static FxExpression *ParseRandomPick(FScanner &sc, FName identifier, PClassActor *cls, bool client) { bool floaty = identifier == NAME_FRandomPick; FRandom *rng; @@ -604,7 +609,7 @@ static FxExpression *ParseRandomPick(FScanner &sc, FName identifier, PClassActor list.Clear(); int index = 0; - rng = ParseRNG(sc); + rng = ParseRNG(sc, client); sc.MustGetToken('('); for (;;) @@ -618,9 +623,9 @@ static FxExpression *ParseRandomPick(FScanner &sc, FName identifier, PClassActor return new FxRandomPick(rng, list, floaty, sc, true); } -static FxExpression *ParseRandom2(FScanner &sc, PClassActor *cls) +static FxExpression *ParseRandom2(FScanner &sc, PClassActor *cls, bool client) { - FRandom *rng = ParseRNG(sc); + FRandom *rng = ParseRNG(sc, client); FxExpression *mask = NULL; sc.MustGetToken('('); diff --git a/src/sound/s_doomsound.cpp b/src/sound/s_doomsound.cpp index 33604ce61f..4b2d597bca 100644 --- a/src/sound/s_doomsound.cpp +++ b/src/sound/s_doomsound.cpp @@ -1163,7 +1163,7 @@ TArray DoomSoundEngine::ReadSound(int lumpnum) // This is overridden to use a synchronized RNG. // //========================================================================== -static FRandom pr_randsound("RandSound"); +static FRandom pr_randsound("RandSound", true); FSoundID DoomSoundEngine::PickReplacement(FSoundID refid) { diff --git a/src/sound/s_sndseq.cpp b/src/sound/s_sndseq.cpp index 99b58a8f9b..cfe8ed9c10 100644 --- a/src/sound/s_sndseq.cpp +++ b/src/sound/s_sndseq.cpp @@ -288,7 +288,7 @@ static const hexenseq_t HexenSequences[] = { static int SeqTrans[MAX_SNDSEQS*3]; -static FRandom pr_sndseq ("SndSeq"); +static FRandom pr_sndseq ("SndSeq", true); // CODE -------------------------------------------------------------------- diff --git a/wadsrc/static/zscript/engine/base.zs b/wadsrc/static/zscript/engine/base.zs index e25c822291..8abd04ee3c 100644 --- a/wadsrc/static/zscript/engine/base.zs +++ b/wadsrc/static/zscript/engine/base.zs @@ -788,7 +788,9 @@ class Object native // // Intrinsic random number generation functions. Note that the square // bracket syntax for specifying an RNG ID is only available for these - // functions. + // functions. If the function is prefixed with a C, this is a client-side RNG + // call that isn't backed up while predicting and has a unique name space from + // regular RNG calls. This should be used for things like HUD elements. // clearscope void SetRandomSeed[Name rngId = 'None'](int seed); // Set the seed for the given RNG. // clearscope int Random[Name rngId = 'None'](int min, int max); // Use the given RNG to generate a random integer number in the range (min, max) inclusive. // clearscope int Random2[Name rngId = 'None'](int mask); // Use the given RNG to generate a random integer number, and do a "union" (bitwise AND, AKA &) operation with the bits in the mask integer. diff --git a/wadsrc/static/zscript/ui/menu/conversationmenu.zs b/wadsrc/static/zscript/ui/menu/conversationmenu.zs index 1b1d3c011f..4e8210b1ac 100644 --- a/wadsrc/static/zscript/ui/menu/conversationmenu.zs +++ b/wadsrc/static/zscript/ui/menu/conversationmenu.zs @@ -216,11 +216,11 @@ class ConversationMenu : Menu let goodbyestr = mCurNode.Goodbye; if (goodbyestr.Length() == 0) { - goodbyestr = String.Format("$TXT_RANDOMGOODBYE_%d", Random[RandomSpeech](1, NUM_RANDOM_GOODBYES)); + goodbyestr = String.Format("$TXT_RANDOMGOODBYE_%d", CRandom[RandomSpeech](1, NUM_RANDOM_GOODBYES)); } else if (goodbyestr.Left(7) == "RANDOM_") { - goodbyestr = String.Format("$TXT_%s_%02d", goodbyestr, Random[RandomSpeech](1, NUM_RANDOM_LINES)); + goodbyestr = String.Format("$TXT_%s_%02d", goodbyestr, CRandom[RandomSpeech](1, NUM_RANDOM_LINES)); } goodbyestr = Stringtable.Localize(goodbyestr); if (goodbyestr.Length() == 0 || goodbyestr.Left(1) == "$") goodbyestr = "Bye."; @@ -254,7 +254,7 @@ class ConversationMenu : Menu String toSay = mCurNode.Dialogue; if (toSay.Left(7) == "RANDOM_") { - let dlgtext = String.Format("$TXT_%s_%02d", toSay, random[RandomSpeech](1, NUM_RANDOM_LINES)); + let dlgtext = String.Format("$TXT_%s_%02d", toSay, crandom[RandomSpeech](1, NUM_RANDOM_LINES)); toSay = Stringtable.Localize(dlgtext); if (toSay.Left(1) == "$") toSay = Stringtable.Localize("$TXT_GOAWAY"); } diff --git a/wadsrc/static/zscript/ui/statusbar/heretic_sbar.zs b/wadsrc/static/zscript/ui/statusbar/heretic_sbar.zs index 62cc27efa4..135b711c2d 100644 --- a/wadsrc/static/zscript/ui/statusbar/heretic_sbar.zs +++ b/wadsrc/static/zscript/ui/statusbar/heretic_sbar.zs @@ -45,7 +45,7 @@ class HereticStatusBar : BaseStatusBar // wiggle the chain if it moves if (Level.time & 1) { - wiggle = (mHealthInterpolator.GetValue() != CPlayer.health) && Random[ChainWiggle](0, 1); + wiggle = (mHealthInterpolator.GetValue() != CPlayer.health) && CRandom[ChainWiggle](0, 1); } }