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.
This commit is contained in:
Boondorl 2024-05-04 20:35:44 -04:00 committed by Ricardo Luís Vaz Silva
parent 4c140224a2
commit 597b06ae52
47 changed files with 213 additions and 154 deletions

View file

@ -169,7 +169,7 @@ static const char *TelefragSounds[] =
#endif
static int LastAnnounceTime;
static FRandom pr_bbannounce ("BBAnnounce");
static FRandom pr_bbannounce ("BBAnnounce", true);
// CODE --------------------------------------------------------------------

View file

@ -61,7 +61,7 @@ enum
{
DEFAULT_PITCH = 128,
};
static FRandom pr_soundpitch ("SoundPitch");
static FRandom pr_soundpitch ("SoundPitch", true);
SoundEngine* soundEngine;
//==========================================================================

View file

@ -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<FRandom *> NewRNGs;
FRandom *FRandom::RNGList, *FRandom::CRNGList;
static TDeletingArray<FRandom *> NewRNGs, NewCRNGs;
// CODE --------------------------------------------------------------------
@ -139,14 +139,22 @@ static TDeletingArray<FRandom *> 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;
}

View file

@ -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<FRandom>& backups);
static void RestoreRNGState(TArray<FRandom>& 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)

View file

@ -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)

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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.
////////////////////////////////////////////////////////////////////////////////

View file

@ -60,8 +60,8 @@ static TArray<uint8_t> 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
{

View file

@ -61,7 +61,7 @@ extern void InitBotStuff();
extern void ClearStrifeTypes();
TArray<PClassActor *> PClassActor::AllActorClasses;
FRandom FState::pr_statetics("StateTics");
FRandom FState::pr_statetics("StateTics", false);
cycle_t ActionCycles;

View file

@ -56,7 +56,7 @@ FTextureAnimator TexAnim;
// PRIVATE DATA DEFINITIONS ------------------------------------------------
static FRandom pr_animatepictures ("AnimatePics");
static FRandom pr_animatepictures ("AnimatePics", true);
// CODE --------------------------------------------------------------------

View file

@ -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;

View file

@ -67,7 +67,7 @@
static FMemArena DynLightArena(sizeof(FDynamicLight) * 200);
static TArray<FDynamicLight*> FreeList;
static FRandom randLight;
static FRandom randLight(true);
extern TArray<FLightDefaults *> StateLights;

View file

@ -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)

View file

@ -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.

View file

@ -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;

View file

@ -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];

View file

@ -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.

View file

@ -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

View file

@ -38,7 +38,7 @@
#include "gi.h"
#include <vm.h>
static FRandom pr_lightning ("Lightning");
static FRandom pr_lightning ("Lightning", false);
IMPLEMENT_CLASS(DLightningThinker, false, false)

View file

@ -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);
//-----------------------------------------------------------------------------

View file

@ -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)

View file

@ -36,7 +36,7 @@
#include "actorinlines.h"
#include <p_maputl.h>
static FRandom pr_quake ("Quake");
static FRandom pr_quake ("Quake", true);
IMPLEMENT_CLASS(DEarthquake, false, true)

View file

@ -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.

View file

@ -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,

View file

@ -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))

View file

@ -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.

View file

@ -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)

View file

@ -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.

View file

@ -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

View file

@ -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()
{

View file

@ -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);
/*
==============================================================================

View file

@ -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)

View file

@ -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
{

View file

@ -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);

View file

@ -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)
{

View file

@ -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)

View file

@ -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);
//==========================================================================
//

View file

@ -94,8 +94,8 @@ struct InterpolationViewer
// PRIVATE DATA DECLARATIONS -----------------------------------------------
static TArray<InterpolationViewer> 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<DVector3a> InterpolationPath;

View file

@ -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('(');

View file

@ -1163,7 +1163,7 @@ TArray<uint8_t> 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)
{

View file

@ -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 --------------------------------------------------------------------

View file

@ -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.

View file

@ -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");
}

View file

@ -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);
}
}