diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 5eb35283..c62ff8fe 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -808,7 +808,7 @@ static boolean IsNameGood(char *name, INT32 playernum) else if (len == 1) // Agh! { // Last ditch effort... - sprintf(name, "%d", M_Random() & 7); + sprintf(name, "%d", M_RandomKey(10)); if (!IsNameGood (name, playernum)) return false; } @@ -3583,7 +3583,7 @@ retryscramble: for (i = 0; i < playercount; i++) { if (repick) - newteam = (INT16)((M_Random() % 2) + 1); + newteam = (INT16)((M_RandomByte() % 2) + 1); // One team has the most players they can get, assign the rest to the other team. if (red == maxcomposition || blue == maxcomposition) @@ -3628,7 +3628,7 @@ retryscramble: { if (repick) { - newteam = (INT16)((M_Random() % 2) + 1); + newteam = (INT16)((M_RandomByte() % 2) + 1); repick = false; } else diff --git a/src/g_game.c b/src/g_game.c index 1f6834ac..65a91b81 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2349,7 +2349,7 @@ mapthing_t *G_FindCTFStart(INT32 playernum) return NULL; } - if ((!players[playernum].ctfteam && numredctfstarts && (!numbluectfstarts || P_Random() & 1)) || players[playernum].ctfteam == 1) //red + if ((!players[playernum].ctfteam && numredctfstarts && (!numbluectfstarts || P_RandomChance(FRACUNIT/2))) || players[playernum].ctfteam == 1) //red { if (!numredctfstarts) { @@ -5487,7 +5487,7 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(void) UINT8 i; WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker for (i = 0; i < 16; i++, p++) - *p = P_Random(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. + *p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. #else WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker md5_buffer((char *)p+16, demo_p - (p+16), (void *)p); // make a checksum of everything after the checksum in the file. @@ -5569,7 +5569,7 @@ boolean G_CheckDemoStatus(void) UINT8 i; WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker for (i = 0; i < 16; i++, p++) - *p = P_Random(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. + *p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. #else WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker md5_buffer((char *)p+16, demo_p - (p+16), p); // make a checksum of everything after the checksum in the file. diff --git a/src/hardware/hw3sound.c b/src/hardware/hw3sound.c index efc1d247..c6843092 100644 --- a/src/hardware/hw3sound.c +++ b/src/hardware/hw3sound.c @@ -384,12 +384,12 @@ INT32 HW3S_I_StartSound(const void *origin_p, source3D_data_t *source_parm, chan /*if (gamemode != heretic) { if (sfx_id >= sfx_sawup && sfx_id <= sfx_sawhit) - pitch += 8 - (M_Random()&15); + pitch += 8 - (M_RandomByte()&15); else if (sfx_id != sfx_itemup && sfx_id != sfx_tink) - pitch += 16 - (M_Random()&31); + pitch += 16 - (M_RandomByte()&31); } else*/ - pitch = 128 + (M_Random() & 7) - (M_Random() & 7); + pitch = 128 + (M_RandomByte() & 7) - (M_RandomByte() & 7); } #endif diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index fb369387..a93e96dc 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -871,7 +871,7 @@ void HWR_DoCoronasLighting(FOutVector *outVerts, gr_vissprite_t *spr) size = p_lspr->corona_radius * ((outVerts[0].z+120.0f)/950.0f); // d'ou vienne ces constante ? break; case ROCKET_SPR: - p_lspr->corona_color = (((M_Random()>>1)&0xff)<<24)|0x0040ff; + p_lspr->corona_color = (((M_RandomByte()>>1)&0xff)<<24)|0x0040ff; // don't need a break case CORONA_SPR: size = p_lspr->corona_radius * ((outVerts[0].z+60.0f)/100.0f); // d'ou vienne ces constante ? @@ -974,7 +974,7 @@ void HWR_DrawCoronas(void) size = p_lspr->corona_radius * ((cz+120.0f)/950.0f); // d'ou vienne ces constante ? break; case ROCKET_SPR: - Surf.FlatColor.s.alpha = (UINT8)((M_Random()>>1)&0xff); + Surf.FlatColor.s.alpha = (UINT8)((M_RandomByte()>>1)&0xff); // don't need a break case CORONA_SPR: size = p_lspr->corona_radius * ((cz+60.0f)/100.0f); // d'ou vienne ces constante ? diff --git a/src/lua_baselib.c b/src/lua_baselib.c index a7f2eb39..1488f402 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -96,17 +96,17 @@ static int lib_evalMath(lua_State *L) // M_RANDOM ////////////// -static int lib_pRandom(lua_State *L) +static int lib_pRandomFixed(lua_State *L) { NOHUD - lua_pushinteger(L, P_Random()); + lua_pushfixed(L, P_RandomFixed()); return 1; } -static int lib_pSignedRandom(lua_State *L) +static int lib_pRandomByte(lua_State *L) { NOHUD - lua_pushinteger(L, P_SignedRandom()); + lua_pushinteger(L, P_RandomByte()); return 1; } @@ -134,6 +134,30 @@ static int lib_pRandomRange(lua_State *L) return 1; } +// Deprecated, macros, etc. +static int lib_pRandom(lua_State *L) +{ + NOHUD + LUA_Deprecated(L, "P_Random", "P_RandomByte"); + lua_pushinteger(L, P_RandomByte()); + return 1; +} + +static int lib_pSignedRandom(lua_State *L) +{ + NOHUD + lua_pushinteger(L, P_SignedRandom()); + return 1; +} + +static int lib_pRandomChance(lua_State *L) +{ + fixed_t p = luaL_checkfixed(L, 1); + NOHUD + lua_pushboolean(L, P_RandomChance(p)); + return 1; +} + // P_MAPUTIL /////////////// @@ -1934,10 +1958,13 @@ static luaL_Reg lib[] = { {"EvalMath", lib_evalMath}, // m_random - {"P_Random",lib_pRandom}, - {"P_SignedRandom",lib_pSignedRandom}, + {"P_RandomFixed",lib_pRandomFixed}, + {"P_RandomByte",lib_pRandomByte}, {"P_RandomKey",lib_pRandomKey}, {"P_RandomRange",lib_pRandomRange}, + {"P_Random",lib_pRandom}, // DEPRECATED + {"P_SignedRandom",lib_pSignedRandom}, // MACRO + {"P_RandomChance",lib_pRandomChance}, // MACRO // p_maputil {"P_AproxDistance",lib_pAproxDistance}, diff --git a/src/m_cheat.c b/src/m_cheat.c index 3ccb2e10..fdba600a 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -598,9 +598,9 @@ void Command_CauseCfail_f(void) } P_UnsetThingPosition(players[consoleplayer].mo); - P_Random(); - P_Random(); - P_Random(); + P_RandomFixed(); + P_RandomByte(); + P_RandomFixed(); players[consoleplayer].mo->x = 0; players[consoleplayer].mo->y = 123311; //cfail cansuled kthxbye players[consoleplayer].mo->z = 123311; diff --git a/src/m_random.c b/src/m_random.c index fce65b88..79f3af11 100644 --- a/src/m_random.c +++ b/src/m_random.c @@ -10,7 +10,7 @@ // See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- /// \file m_random.c -/// \brief LCG PRNG originally created for XMOD +/// \brief RNG for client effects and PRNG for game actions #include "doomdef.h" #include "doomtype.h" @@ -19,48 +19,57 @@ #include "m_random.h" #include "m_fixed.h" + + // --------------------------- // RNG functions (not synched) // --------------------------- -/** Provides a random byte. - * Used outside the p_xxx game code and not synchronized in netgames. This is - * for anything that doesn't need to be synced, e.g. precipitation. +/** Provides a random fixed point number. Distribution is uniform. + * As with all M_Random functions, not synched in netgames. * - * \return A random byte, 0 to 255. + * \return A random fixed point number from [0,1). */ -UINT8 M_Random(void) +fixed_t M_RandomFixed(void) { - return (rand() & 255); +#if RAND_MAX < 65535 + // Compensate for insufficient randomness. + fixed_t rndv = (rand()&1)<<15; + return rand()^rndv; +#else + return (rand() & 0xFFFF); +#endif } -/** Provides a random signed byte. Distribution is uniform. - * As with all M_*Random functions, not synched in netgames. +/** Provides a random byte. Distribution is uniform. + * As with all M_Random functions, not synched in netgames. * - * \return A random byte, -128 to 127. - * \sa M_Random + * \return A random integer from [0, 255]. */ -INT32 M_SignedRandom(void) +UINT8 M_RandomByte(void) { - return M_Random() - 128; + return (rand() & 0xFF); } -/** Provides a random number in between 0 and the given number - 1. - * Distribution is uniform. Use for picking random elements from an array. - * As with all M_*Random functions, not synched in netgames. +/** Provides a random integer for picking random elements from an array. + * Distribution is uniform. + * As with all M_Random functions, not synched in netgames. * - * \return A random number, 0 to arg1-1. + * \param a Number of items in array. + * \return A random integer from [0,a). */ INT32 M_RandomKey(INT32 a) { return (INT32)((rand()/((unsigned)RAND_MAX+1.0f))*a); } -/** Provides a random number in between a specific range. +/** Provides a random integer in a given range. * Distribution is uniform. - * As with all M_*Random functions, not synched in netgames. + * As with all M_Random functions, not synched in netgames. * - * \return A random number, arg1 to arg2. + * \param a Lower bound. + * \param b Upper bound. + * \return A random integer from [a,b]. */ INT32 M_RandomRange(INT32 a, INT32 b) { @@ -74,54 +83,65 @@ INT32 M_RandomRange(INT32 a, INT32 b) // ------------------------ // Holds the current seed. -static UINT32 randomseed = 0; +static UINT32 randomseed = 0xBADE4404; // Holds the INITIAL seed value. Used for demos, possibly other debugging. -static UINT32 initialseed = 0; +static UINT32 initialseed = 0xBADE4404; -/** - * Provides a random byte and sets the seed appropriately. - * The nature of this PRNG allows it to cycle through about two million numbers - * before it finally starts repeating numeric sequences. - * That's more than good enough for our purposes. +/** Provides a random fixed point number. + * This is a variant of an xorshift PRNG; state fits in a 32 bit integer structure. * - * \return A random byte, 0 to 255. + * \return A random fixed point number from [0,1). */ -#ifndef DEBUGRANDOM -UINT8 P_Random(void) +ATTRINLINE static fixed_t FUNCINLINE __internal_prng__(void) { -#else -UINT8 P_RandomD(const char *rfile, INT32 rline) -{ - CONS_Printf("P_Random() at: %sp %d\n", rfile, rline); -#endif - randomseed = (randomseed*746151647)+48205429; - return (UINT8)((randomseed >> 17)&255); + randomseed ^= randomseed >> 13; + randomseed ^= randomseed >> 11; + randomseed ^= randomseed << 21; + return ( (randomseed*36548569) >> 4) & (FRACUNIT-1); } -/** Provides a random number from -128 to 127. +/** Provides a random fixed point number. Distribution is uniform. + * Literally a wrapper for the internal PRNG function. + * + * \return A random fixed point number from [0,1). + */ +#ifndef DEBUGRANDOM +fixed_t P_RandomFixed(void) +{ +#else +UINT8 P_RandomFixedD(const char *rfile, INT32 rline) +{ + CONS_Printf("P_RandomFixed() at: %sp %d\n", rfile, rline); +#endif + return __internal_prng__(); +} + +/** Provides a random byte. Distribution is uniform. + * If you're curious, (&0xFF00) >> 8 gives the same result + * as a fixed point multiplication by 256. + * + * \return Random integer from [0, 255]. + * \sa __internal_prng__ + */ +#ifndef DEBUGRANDOM +UINT8 P_RandomByte(void) +{ +#else +UINT8 P_RandomByteD(const char *rfile, INT32 rline) +{ + CONS_Printf("P_RandomByte() at: %sp %d\n", rfile, rline); +#endif + return (UINT8)((__internal_prng__()&0xFF00)>>8); +} + +/** Provides a random integer for picking random elements from an array. * Distribution is uniform. + * NOTE: Maximum range is 65536. * - * \return Random number from -128 to 127. - * \sa P_Random - */ -#ifndef DEBUGRANDOM -INT32 P_SignedRandom(void) -{ -#else -INT32 P_SignedRandomD(const char *rfile, INT32 rline) -{ - CONS_Printf("P_SignedRandom() at: %sp %d\n", rfile, rline); -#endif - return P_Random() - 128; -} - -/** Provides a random number in between 0 and the given number - 1. - * Distribution is uniform, also calls for two numbers for bigger output range. - * Use for picking random elements from an array. - * - * \return A random number, 0 to arg1-1. - * \sa P_Random + * \param a Number of items in array. + * \return A random integer from [0,a). + * \sa __internal_prng__ */ #ifndef DEBUGRANDOM INT32 P_RandomKey(INT32 a) @@ -131,16 +151,17 @@ INT32 P_RandomKeyD(const char *rfile, INT32 rline, INT32 a) { CONS_Printf("P_RandomKey() at: %sp %d\n", rfile, rline); #endif - INT32 prandom = P_Random(); // note: forcing explicit function call order - prandom |= P_Random() << 8; // (function call order is not strictly defined) - return (INT32)((prandom/65536.0f)*a); + return (INT32)((__internal_prng__() * a) >> FRACBITS); } -/** Provides a random number in between a specific range. - * Distribution is uniform, also calls for two numbers for bigger output range. +/** Provides a random integer in a given range. + * Distribution is uniform. + * NOTE: Maximum range is 65536. * - * \return A random number, arg1 to arg2. - * \sa P_Random + * \param a Lower bound. + * \param b Upper bound. + * \return A random integer from [a,b]. + * \sa __internal_prng__ */ #ifndef DEBUGRANDOM INT32 P_RandomRange(INT32 a, INT32 b) @@ -150,21 +171,27 @@ INT32 P_RandomRangeD(const char *rfile, INT32 rline, INT32 a, INT32 b) { CONS_Printf("P_RandomRange() at: %sp %d\n", rfile, rline); #endif - INT32 prandom = P_Random(); // note: forcing explicit function call order - prandom |= P_Random() << 8; // (function call order is not strictly defined) - return (INT32)((prandom/65536.0f)*(b-a+1))+a; + return (INT32)((__internal_prng__() * (b-a+1)) >> FRACBITS) + a; } -/** Provides a random byte without saving what the seed would be. - * Used just to debug the PRNG. + + +// ---------------------- +// PRNG seeds & debugging +// ---------------------- + +/** Peeks to see what the next result from the PRNG will be. + * Used for debugging. * - * \return A 'random' byte, 0 to 255. - * \sa P_Random + * \return A 'random' fixed point number from [0,1). + * \sa __internal_prng__ */ -UINT8 P_RandomPeek(void) +fixed_t P_RandomPeek(void) { - UINT32 r = (randomseed*746151647)+48205429; - return (UINT8)((r >> 17)&255); + UINT32 r = randomseed; + fixed_t ret = __internal_prng__(); + randomseed = r; + return ret; } /** Gets the current random seed. Used by netgame savegames. @@ -213,6 +240,9 @@ void P_SetRandSeedD(const char *rfile, INT32 rline, UINT32 seed) { CONS_Printf("P_SetRandSeed() at: %sp %d\n", rfile, rline); #endif + // xorshift requires a nonzero seed + // this should never happen, but just in case it DOES, we check + if (!seed) seed = 0xBADE4404; randomseed = initialseed = seed; } @@ -222,5 +252,5 @@ void P_SetRandSeedD(const char *rfile, INT32 rline, UINT32 seed) */ UINT32 M_RandomizedSeed(void) { - return ((totalplaytime & 0xFFFF) << 16)|(rand() & 0xFFFF); + return ((totalplaytime & 0xFFFF) << 16)|M_RandomFixed(); } diff --git a/src/m_random.h b/src/m_random.h index 42c87160..90784a5d 100644 --- a/src/m_random.h +++ b/src/m_random.h @@ -20,32 +20,42 @@ //#define DEBUGRANDOM + // M_Random functions pull random numbers of various types that aren't network synced. -// P_Random functions pulls random bytes from a LCG PRNG that is network synced. +// P_Random functions pulls random bytes from a PRNG that is network synced. // RNG functions -UINT8 M_Random(void); -INT32 M_SignedRandom(void); -INT32 M_RandomKey(INT32 a); -INT32 M_RandomRange(INT32 a, INT32 b); +fixed_t M_RandomFixed(void); +UINT8 M_RandomByte(void); +INT32 M_RandomKey(INT32 a); +INT32 M_RandomRange(INT32 a, INT32 b); // PRNG functions #ifdef DEBUGRANDOM -#define P_Random() P_RandomD(__FILE__, __LINE__) -#define P_SignedRandom() P_SignedRandomD(__FILE__, __LINE__) -#define P_RandomKey(c) P_RandomKeyD(__FILE__, __LINE__, c) +#define P_RandomFixed() P_RandomFixedD(__FILE__, __LINE__) +#define P_RandomByte() P_RandomByteD(__FILE__, __LINE__) +#define P_RandomKey(c) P_RandomKeyD(__FILE__, __LINE__, c) #define P_RandomRange(c, d) P_RandomRangeD(__FILE__, __LINE__, c, d) -UINT8 P_RandomD(const char *rfile, INT32 rline); -INT32 P_SignedRandomD(const char *rfile, INT32 rline); -INT32 P_RandomKeyD(const char *rfile, INT32 rline, INT32 a); -INT32 P_RandomRangeD(const char *rfile, INT32 rline, INT32 a, INT32 b); +fixed_t P_RandomFixedD(const char *rfile, INT32 rline); +UINT8 P_RandomByteD(const char *rfile, INT32 rline); +INT32 P_RandomKeyD(const char *rfile, INT32 rline, INT32 a); +INT32 P_RandomRangeD(const char *rfile, INT32 rline, INT32 a, INT32 b); #else -UINT8 P_Random(void); -INT32 P_SignedRandom(void); -INT32 P_RandomKey(INT32 a); -INT32 P_RandomRange(INT32 a, INT32 b); +fixed_t P_RandomFixed(void); +UINT8 P_RandomByte(void); +INT32 P_RandomKey(INT32 a); +INT32 P_RandomRange(INT32 a, INT32 b); #endif -UINT8 P_RandomPeek(void); + +// Macros for other functions +#define M_SignedRandom() ((INT32)M_RandomByte() - 128) // [-128, 127] signed byte, originally a +#define P_SignedRandom() ((INT32)P_RandomByte() - 128) // function of its own, moved to a macro + +#define M_RandomChance(p) (M_RandomFixed() < p) // given fixed point probability, p, between 0 (0%) +#define P_RandomChance(p) (P_RandomFixed() < p) // and FRACUNIT (100%), returns true p% of the time + +// Debugging +fixed_t P_RandomPeek(void); // Working with the seed for PRNG #ifdef DEBUGRANDOM diff --git a/src/p_enemy.c b/src/p_enemy.c index ffb69082..82391a74 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -386,7 +386,7 @@ boolean P_CheckMissileRange(mobj_t *actor) if (actor->type == MT_EGGMOBILE && dist > 160) dist = 160; - if (P_Random() < dist) + if (P_RandomByte() < dist) return false; return true; @@ -486,7 +486,7 @@ static boolean P_TryWalk(mobj_t *actor) { if (!P_Move(actor, actor->info->speed)) return false; - actor->movecount = P_Random() & 15; + actor->movecount = P_RandomByte() & 15; return true; } @@ -539,7 +539,7 @@ void P_NewChaseDir(mobj_t *actor) } // try other directions - if (P_Random() > 200 || abs(deltay) > abs(deltax)) + if (P_RandomChance(25*FRACUNIT/32) || abs(deltay) > abs(deltax)) { tdir = d[1]; d[1] = d[2]; @@ -577,7 +577,7 @@ void P_NewChaseDir(mobj_t *actor) } // randomly determine direction of search - if (P_Random() & 1) + if (P_RandomChance(FRACUNIT/2)) { for (tdir = DI_EAST; tdir <= DI_SOUTHEAST; tdir++) { @@ -632,7 +632,7 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed // BP: first time init, this allow minimum lastlook changes if (actor->lastlook < 0) - actor->lastlook = P_Random(); + actor->lastlook = P_RandomByte(); actor->lastlook %= MAXPLAYERS; @@ -707,7 +707,7 @@ static boolean P_LookForShield(mobj_t *actor) // BP: first time init, this allow minimum lastlook changes if (actor->lastlook < 0) - actor->lastlook = P_Random(); + actor->lastlook = P_RandomByte(); actor->lastlook %= MAXPLAYERS; @@ -2293,12 +2293,7 @@ void A_SkullAttack(mobj_t *actor) if (locvar1 == 1) actor->angle += ANGLE_180; else if (locvar1 == 2) - { - if (P_Random() & 1) - actor->angle += ANGLE_90; - else - actor->angle -= ANGLE_90; - } + actor->angle += (P_RandomChance(FRACUNIT/2)) ? ANGLE_90 : -ANGLE_90; an = actor->angle >> ANGLETOFINESHIFT; @@ -2398,9 +2393,9 @@ void A_BossScream(mobj_t *actor) explodetype = (mobjtype_t)locvar2; if (actor->eflags & MFE_VERTICALFLIP) - z = actor->z + actor->height - mobjinfo[explodetype].height - FixedMul((P_Random()<<(FRACBITS-2)) - 8*FRACUNIT, actor->scale); + z = actor->z + actor->height - mobjinfo[explodetype].height - FixedMul((P_RandomByte()<<(FRACBITS-2)) - 8*FRACUNIT, actor->scale); else - z = actor->z + FixedMul((P_Random()<<(FRACBITS-2)) - 8*FRACUNIT, actor->scale); + z = actor->z + FixedMul((P_RandomByte()<<(FRACBITS-2)) - 8*FRACUNIT, actor->scale); mo = P_SpawnMobj(x, y, z, explodetype); if (actor->eflags & MFE_VERTICALFLIP) @@ -3461,7 +3456,7 @@ void A_BubbleSpawn(mobj_t *actor) return; // don't make bubble! } - prandom = P_Random(); + prandom = P_RandomByte(); if (leveltime % (3*TICRATE) < 8) bubble = P_SpawnMobj(actor->x, actor->y, actor->z + (actor->height / 2), MT_EXTRALARGEBUBBLE); @@ -3509,7 +3504,7 @@ void A_FanBubbleSpawn(mobj_t *actor) return; // don't make bubble! } - prandom = P_Random(); + prandom = P_RandomByte(); if ((prandom & 0x7) == 0x7) bubble = P_SpawnMobj(actor->x, actor->y, hz, MT_SMALLBUBBLE); @@ -3550,7 +3545,7 @@ void A_BubbleRise(mobj_t *actor) // Move around slightly to make it look like it's bending around the water if (!locvar1) { - UINT8 prandom = P_Random(); + UINT8 prandom = P_RandomByte(); if (!(prandom & 0x7)) // *****000 { P_InstaThrust(actor, prandom & 0x70 ? actor->angle + ANGLE_90 : actor->angle, @@ -3833,7 +3828,7 @@ void A_ThrownRing(mobj_t *actor) // first time init, this allow minimum lastlook changes if (actor->lastlook < 0) - actor->lastlook = P_Random(); + actor->lastlook = P_RandomByte(); actor->lastlook %= MAXPLAYERS; @@ -3913,7 +3908,7 @@ void A_SetSolidSteam(mobj_t *actor) #endif actor->flags &= ~MF_NOCLIP; actor->flags |= MF_SOLID; - if (!(P_Random() & 7)) + if (P_RandomChance(FRACUNIT/8)) { if (actor->info->deathsound) S_StartSound(actor, actor->info->deathsound); // Hiss! @@ -4055,7 +4050,7 @@ void A_JetChase(mobj_t *actor) if (actor->reactiontime) actor->reactiontime--; - if (P_Random() % 32 == 1) + if (P_RandomChance(FRACUNIT/32)) { actor->momx = actor->momx / 2; actor->momy = actor->momy / 2; @@ -4416,7 +4411,7 @@ void A_JetgThink(mobj_t *actor) if (actor->target) { - if (P_Random() <= 32 && !actor->reactiontime) + if (P_RandomChance(FRACUNIT/8) && !actor->reactiontime) P_SetMobjState(actor, actor->info->missilestate); else A_JetChase (actor); @@ -4469,10 +4464,10 @@ void A_MouseThink(mobj_t *actor) { if (twodlevel || actor->flags2 & MF2_TWOD) { - if (P_Random() & 1) + if (P_RandomChance(FRACUNIT/2)) actor->angle += ANGLE_180; } - else if (P_Random() & 1) + else if (P_RandomChance(FRACUNIT/2)) actor->angle += ANGLE_90; else actor->angle -= ANGLE_90; @@ -4878,7 +4873,7 @@ void A_RockSpawn(mobj_t *actor) type = MT_ROCKCRUMBLE1 + (sides[line->sidenum[0]].rowoffset >> FRACBITS); if (line->flags & ML_NOCLIMB) - randomoomph = P_Random() * (FRACUNIT/32); + randomoomph = P_RandomByte() * (FRACUNIT/32); else randomoomph = 0; @@ -5172,7 +5167,7 @@ void A_CrawlaCommanderThink(mobj_t *actor) if (locvar1) { - if (actor->health < 2 && P_Random() < 2) + if (actor->health < 2 && P_RandomChance(FRACUNIT/128)) P_SpawnMissile(actor, actor->target, locvar1); } @@ -5187,8 +5182,8 @@ void A_CrawlaCommanderThink(mobj_t *actor) actor->threshold = 0; // Roam around, somewhat in the player's direction. - actor->angle += (P_Random()<<10); - actor->angle -= (P_Random()<<10); + actor->angle += (P_RandomByte()<<10); + actor->angle -= (P_RandomByte()<<10); if (actor->health > 1) P_InstaThrust(actor, actor->angle, FixedMul(10*FRACUNIT, actor->scale)); @@ -5204,7 +5199,7 @@ void A_CrawlaCommanderThink(mobj_t *actor) actor->threshold = 1; } } - actor->reactiontime = 2*TICRATE + P_Random()/2; + actor->reactiontime = 2*TICRATE + P_RandomByte()/2; } if (actor->health == 1) @@ -5222,8 +5217,8 @@ void A_CrawlaCommanderThink(mobj_t *actor) } else { - UINT8 prandom = P_Random(); - actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_Random() & 1 ? -prandom : +prandom); + UINT8 prandom = P_RandomByte(); + actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_RandomChance(FRACUNIT/2) ? -prandom : +prandom); P_InstaThrust(actor, actor->angle, FixedDiv(FixedMul(locvar2, actor->scale), 3*FRACUNIT/2)); actor->momz = FixedMul(locvar2, actor->scale); // Bounce up in air } @@ -5552,7 +5547,7 @@ void A_MixUp(mobj_t *actor) { if (counter > 255) // fail-safe to avoid endless loop break; - prandom = P_Random(); + prandom = P_RandomByte(); prandom %= numplayers; // I love modular arithmetic, don't you? if (prandom) // Make sure it's not a useless mix break; @@ -5701,7 +5696,7 @@ void A_RecyclePowers(mobj_t *actor) { UINT8 tempint; - i = j + ((P_Random() + leveltime) % (numplayers - j)); + i = j + ((P_RandomByte() + leveltime) % (numplayers - j)); tempint = postscramble[j]; postscramble[j] = postscramble[i]; postscramble[i] = tempint; @@ -5814,7 +5809,7 @@ void A_Boss1Chase(mobj_t *actor) { if (actor->health > actor->info->damage) { - if (P_Random() & 1) + if (P_RandomChance(FRACUNIT/2)) P_SetMobjState(actor, actor->info->missilestate); else P_SetMobjState(actor, actor->info->meleestate); @@ -5833,7 +5828,7 @@ void A_Boss1Chase(mobj_t *actor) // ? nomissile: // possibly choose another target - if (multiplayer && P_Random() < 2) + if (multiplayer && P_RandomChance(FRACUNIT/128)) { if (P_LookForPlayers(actor, true, false, 0)) return; // got a new target @@ -5871,7 +5866,7 @@ nomissile: deltay = actor->target->y - actor->y; actor->movedir = diags[((deltay < 0)<<1) + (deltax > 0)]; - actor->movecount = P_Random() & 15; + actor->movecount = P_RandomByte() & 15; } } @@ -5897,13 +5892,13 @@ void A_Boss2Chase(mobj_t *actor) // Startup randomness if (actor->reactiontime <= -666) - actor->reactiontime = 2*TICRATE + P_Random(); + actor->reactiontime = 2*TICRATE + P_RandomByte(); // When reactiontime hits zero, he will go the other way if (--actor->reactiontime <= 0) { reverse = true; - actor->reactiontime = 2*TICRATE + P_Random(); + actor->reactiontime = 2*TICRATE + P_RandomByte(); } P_SetTarget(&actor->target, P_GetClosestAxis(actor)); @@ -5990,12 +5985,12 @@ void A_Boss2Chase(mobj_t *actor) if (actor->info->attacksound) S_StartAttackSound(actor, actor->info->attacksound); - if (P_Random() & 1) + if (P_RandomChance(FRACUNIT/2)) { goop->momx *= 2; goop->momy *= 2; } - else if (P_Random() > 128) + else if (P_RandomChance(129*FRACUNIT/256)) { goop->momx *= 3; goop->momy *= 3; @@ -6153,7 +6148,7 @@ void A_Boss7Chase(mobj_t *actor) { A_FaceTarget(actor); P_SetMobjState(actor, S_BLACKEGG_SHOOT1); - actor->movecount = TICRATE + P_Random()/2; + actor->movecount = TICRATE + P_RandomByte()/2; return; } @@ -6162,7 +6157,7 @@ void A_Boss7Chase(mobj_t *actor) if (actor->reactiontime <= 0 && actor->z == actor->floorz) { - // Here, we'll call P_Random() and decide what kind of attack to do + // Here, we'll call P_RandomByte() and decide what kind of attack to do switch(actor->threshold) { case 0: // Lob cannon balls @@ -6170,7 +6165,7 @@ void A_Boss7Chase(mobj_t *actor) { A_FaceTarget(actor); P_SetMobjState(actor, actor->info->xdeathstate); - actor->movecount = 7*TICRATE + P_Random(); + actor->movecount = 7*TICRATE + P_RandomByte(); break; } actor->threshold++; @@ -6180,9 +6175,9 @@ void A_Boss7Chase(mobj_t *actor) P_SetMobjState(actor, S_BLACKEGG_SHOOT1); if (actor->health > actor->info->damage) - actor->movecount = TICRATE + P_Random()/3; + actor->movecount = TICRATE + P_RandomByte()/3; else - actor->movecount = TICRATE + P_Random()/2; + actor->movecount = TICRATE + P_RandomByte()/2; break; case 2: // Homing Missile A_FaceTarget(actor); @@ -6266,8 +6261,8 @@ void A_Boss2PogoSFX(mobj_t *actor) } else { - UINT8 prandom = P_Random(); - actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_Random() & 1 ? -prandom : +prandom); + UINT8 prandom = P_RandomByte(); + actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_RandomChance(FRACUNIT/2) ? -prandom : +prandom); P_InstaThrust(actor, actor->angle, FixedMul(FixedMul(actor->info->speed,(locvar2)), actor->scale)); } if (actor->info->activesound) S_StartSound(actor, actor->info->activesound); @@ -6307,10 +6302,10 @@ void A_Boss2PogoTarget(mobj_t *actor) // Target hit, retreat! if (actor->target->player->powers[pw_flashing] > TICRATE || actor->flags2 & MF2_FRET) { - UINT8 prandom = P_Random(); + UINT8 prandom = P_RandomByte(); actor->z++; // unstick from the floor actor->momz = FixedMul(locvar1, actor->scale); // Bounce up in air - actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_Random() & 1 ? -prandom : +prandom); // Pick a direction, and randomize it. + actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_RandomChance(FRACUNIT/2) ? -prandom : +prandom); // Pick a direction, and randomize it. P_InstaThrust(actor, actor->angle+ANGLE_180, FixedMul(FixedMul(actor->info->speed,(locvar2)), actor->scale)); // Move at wandering speed } // Try to land on top of the player. @@ -6347,10 +6342,10 @@ void A_Boss2PogoTarget(mobj_t *actor) // Wander semi-randomly towards the player to get closer. else { - UINT8 prandom = P_Random(); + UINT8 prandom = P_RandomByte(); actor->z++; // unstick from the floor actor->momz = FixedMul(locvar1, actor->scale); // Bounce up in air - actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_Random() & 1 ? -prandom : +prandom); // Pick a direction, and randomize it. + actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) + (P_RandomChance(FRACUNIT/2) ? -prandom : +prandom); // Pick a direction, and randomize it. P_InstaThrust(actor, actor->angle, FixedMul(FixedMul(actor->info->speed,(locvar2)), actor->scale)); // Move at wandering speed } // Boing! @@ -7084,7 +7079,7 @@ void A_SmokeTrailer(mobj_t *actor) P_SetObjectMomZ(th, FRACUNIT, false); th->destscale = actor->scale; P_SetScale(th, actor->scale); - th->tics -= P_Random() & 3; + th->tics -= P_RandomByte() & 3; if (th->tics < 1) th->tics = 1; } @@ -7183,7 +7178,7 @@ void A_ChangeAngleRelative(mobj_t *actor) // rather than the ranges, so <0 and >360 work as possible values. -Red INT32 locvar1 = var1; INT32 locvar2 = var2; - //angle_t angle = (P_Random()+1)<<24; + //angle_t angle = (P_RandomByte()+1)<<24; const fixed_t amin = locvar1*FRACUNIT; const fixed_t amax = locvar2*FRACUNIT; //const angle_t amin = FixedAngle(locvar1*FRACUNIT); @@ -7217,7 +7212,7 @@ void A_ChangeAngleAbsolute(mobj_t *actor) { INT32 locvar1 = var1; INT32 locvar2 = var2; - //angle_t angle = (P_Random()+1)<<24; + //angle_t angle = (P_RandomByte()+1)<<24; const fixed_t amin = locvar1*FRACUNIT; const fixed_t amax = locvar2*FRACUNIT; //const angle_t amin = FixedAngle(locvar1*FRACUNIT); @@ -7825,7 +7820,7 @@ void A_RandomState(mobj_t *actor) return; #endif - P_SetMobjState(actor, P_Random()&1 ? locvar1 : locvar2); + P_SetMobjState(actor, P_RandomChance(FRACUNIT/2) ? locvar1 : locvar2); } // Function: A_RandomStateRange @@ -8516,34 +8511,32 @@ void A_SearchForPlayers(mobj_t *actor) // Function: A_CheckRandom // -// Description: Calls a state by chance (around 1/var1). +// Description: Calls a state by chance. // -// var1 = denominator (can't exceed 100) +// var1: +// lower 16 bits = denominator +// upper 16 bits = numerator (defaults to 1 if zero) // var2 = state number // void A_CheckRandom(mobj_t *actor) { INT32 locvar1 = var1; INT32 locvar2 = var2; - INT32 i, chance; - INT32 rndadd = 0; + fixed_t chance = FRACUNIT; + #ifdef HAVE_BLUA if (LUA_CallAction("A_CheckRandom", actor)) return; #endif + if ((locvar1 & 0xFFFF) == 0) + return; - if(locvar1 > 100) - locvar1 = 100; + // The PRNG doesn't suck anymore, OK? + if (locvar1 >> 16) + chance *= (locvar1 >> 16); + chance /= (locvar1 & 0xFFFF); - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i]) - rndadd += abs((int)players[i].mo->x) + abs((int)players[i].mo->y) + abs((int)players[i].mo->z); - - rndadd = rndadd % 10000; //additional component to enlarge random number - - chance = (P_Random() + rndadd) % locvar1; - - if (chance == 0) + if (P_RandomChance(chance)) P_SetMobjState(actor, locvar2); } @@ -9890,7 +9883,7 @@ void A_BrakChase(mobj_t *actor) S_StartSound(actor, (sfxenum_t)locvar2); // make active sound - if (actor->type != MT_CYBRAKDEMON && actor->info->activesound && P_Random() < 3) + if (actor->type != MT_CYBRAKDEMON && actor->info->activesound && P_RandomChance(3*FRACUNIT/256)) { S_StartSound(actor, actor->info->activesound); } diff --git a/src/p_inter.c b/src/p_inter.c index c08f1f26..7809d6c5 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1253,7 +1253,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (special->target && special->target->state == &states[S_BLACKEGG_SHOOT1]) { - if (special->target->health <= 2 && (P_Random() & 1)) + if (special->target->health <= 2 && P_RandomChance(FRACUNIT/2)) P_SetMobjState(special->target, special->target->info->missilestate); else P_SetMobjState(special->target, special->target->info->raisestate); @@ -2203,29 +2203,17 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) default: if (target->info->doomednum) + prandom = target->info->doomednum%5; // "Random" animal for new enemies. + else + prandom = P_RandomKey(5); // No placable object, just use a random number. + + switch(prandom) { - switch(target->info->doomednum%5) - { default: item = MT_BUNNY; break; case 1: item = MT_BIRD; break; case 2: item = MT_MOUSE; break; case 3: item = MT_COW; break; case 4: item = MT_CHICKEN; break; - } - } - else - { - prandom = P_Random(); - if (prandom < 51) - item = MT_BUNNY; - else if (prandom < 102) - item = MT_BIRD; - else if (prandom < 153) - item = MT_MOUSE; - else if (prandom < 204) - item = MT_COW; - else - item = MT_CHICKEN; } break; } @@ -3103,7 +3091,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da // Killing dead. Just for kicks. // Require source and inflictor be player. Don't hurt for firing rings. - if (cv_killingdead.value && (source && source->player) && (inflictor && inflictor->player) && P_Random() < 80) + if (cv_killingdead.value && (source && source->player) && (inflictor && inflictor->player) && P_RandomChance(5*FRACUNIT/16)) P_DamageMobj(source, target, target, 1); // do the damage @@ -3617,7 +3605,7 @@ void P_PlayerFlagBurst(player_t *player, boolean toss) P_InstaThrust(flag, player->mo->angle, FixedMul(6*FRACUNIT, player->mo->scale)); else { - angle_t fa = P_Random()*FINEANGLES/256; + angle_t fa = P_RandomByte()*FINEANGLES/256; flag->momx = FixedMul(FINECOSINE(fa), FixedMul(6*FRACUNIT, player->mo->scale)); if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) flag->momy = FixedMul(FINESINE(fa), FixedMul(6*FRACUNIT, player->mo->scale)); diff --git a/src/p_lights.c b/src/p_lights.c index 2dfe006d..a9758c72 100644 --- a/src/p_lights.c +++ b/src/p_lights.c @@ -51,7 +51,7 @@ void T_FireFlicker(fireflicker_t *flick) if (--flick->count) return; - amount = (INT16)((UINT8)(P_Random() & 3) * 16); + amount = (INT16)((UINT8)(P_RandomByte() & 3) * 16); if (flick->sector->lightlevel - amount < flick->minlight) flick->sector->lightlevel = (INT16)flick->minlight; @@ -235,7 +235,7 @@ strobe_t *P_SpawnAdjustableStrobeFlash(sector_t *minsector, sector_t *maxsector, flash->minlight = 0; if (!inSync) - flash->count = (P_Random() & 7) + 1; + flash->count = (P_RandomByte() & 7) + 1; else flash->count = 1; diff --git a/src/p_mobj.c b/src/p_mobj.c index ce67f1a5..dd8c4d26 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -652,9 +652,9 @@ void P_EmeraldManager(void) break; if (leveltime < TICRATE) // Start of map - spawnpoints[j]->threshold = 60*TICRATE + P_Random() * (TICRATE/5); + spawnpoints[j]->threshold = 60*TICRATE + P_RandomByte() * (TICRATE/5); else - spawnpoints[j]->threshold = P_Random() * (TICRATE/5); + spawnpoints[j]->threshold = P_RandomByte() * (TICRATE/5); break; } @@ -683,26 +683,26 @@ void P_ExplodeMissile(mobj_t *mo) explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); P_SetScale(explodemo, mo->scale); explodemo->destscale = mo->destscale; - explodemo->momx += (P_Random() % 32) * FixedMul(FRACUNIT/8, explodemo->scale); - explodemo->momy += (P_Random() % 32) * FixedMul(FRACUNIT/8, explodemo->scale); + explodemo->momx += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale); + explodemo->momy += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale); S_StartSound(explodemo, sfx_pop); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); P_SetScale(explodemo, mo->scale); explodemo->destscale = mo->destscale; - explodemo->momx += (P_Random() % 64) * FixedMul(FRACUNIT/8, explodemo->scale); - explodemo->momy -= (P_Random() % 64) * FixedMul(FRACUNIT/8, explodemo->scale); + explodemo->momx += (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale); + explodemo->momy -= (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale); S_StartSound(explodemo, sfx_dmpain); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); P_SetScale(explodemo, mo->scale); explodemo->destscale = mo->destscale; - explodemo->momx -= (P_Random() % 128) * FixedMul(FRACUNIT/8, explodemo->scale); - explodemo->momy += (P_Random() % 128) * FixedMul(FRACUNIT/8, explodemo->scale); + explodemo->momx -= (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale); + explodemo->momy += (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale); S_StartSound(explodemo, sfx_pop); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); P_SetScale(explodemo, mo->scale); explodemo->destscale = mo->destscale; - explodemo->momx -= (P_Random() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); - explodemo->momy -= (P_Random() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); + explodemo->momx -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); + explodemo->momy -= (P_RandomByte() % 96) * FixedMul(FRACUNIT/8, explodemo->scale); S_StartSound(explodemo, sfx_cybdth); // Hack: Release an animal. @@ -2405,12 +2405,12 @@ static boolean P_ZMovement(mobj_t *mo) // If deafed, give the tumbleweed another random kick if it runs out of steam. mom.z += P_MobjFlip(mo)*FixedMul(6*FRACUNIT, mo->scale); - if (P_Random() & 1) + if (P_RandomChance(FRACUNIT/2)) mom.x += FixedMul(6*FRACUNIT, mo->scale); else mom.x -= FixedMul(6*FRACUNIT, mo->scale); - if (P_Random() & 1) + if (P_RandomChance(FRACUNIT/2)) mom.y += FixedMul(6*FRACUNIT, mo->scale); else mom.y -= FixedMul(6*FRACUNIT, mo->scale); @@ -2886,7 +2886,7 @@ static boolean P_SceneryZMovement(mobj_t *mo) for (i = 0; i < 4; ++i) // split into four { - prandom = P_Random(); + prandom = P_RandomByte(); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_SMALLBUBBLE); explodemo->momx += ((prandom & 0x0F) << (FRACBITS-2)) * (i & 2 ? -1 : 1); explodemo->momy += ((prandom & 0xF0) << (FRACBITS-6)) * (i & 1 ? -1 : 1); @@ -3218,13 +3218,13 @@ void P_MobjCheckWater(mobj_t *mobj) // Create tons of bubbles for (i = 0; i < bubblecount; i++) { - // P_Random()s are called individually to allow consistency + // P_RandomByte()s are called individually to allow consistency // across various compilers, since the order of function calls // in C is not part of the ANSI specification. - prandom[0] = P_Random(); - prandom[1] = P_Random(); - prandom[2] = P_Random(); - prandom[3] = P_Random(); + prandom[0] = P_RandomByte(); + prandom[1] = P_RandomByte(); + prandom[2] = P_RandomByte(); + prandom[3] = P_RandomByte(); bubbletype = MT_SMALLBUBBLE; if (!(prandom[0] & 0x3)) // medium bubble chance up to 64 from 32 @@ -3826,7 +3826,7 @@ boolean P_BossTargetPlayer(mobj_t *actor, boolean closest) // first time init, this allow minimum lastlook changes if (actor->lastlook < 0) - actor->lastlook = P_Random(); + actor->lastlook = P_RandomByte(); actor->lastlook &= PLAYERSMASK; for( ; ; actor->lastlook = (actor->lastlook+1) & PLAYERSMASK) @@ -4707,7 +4707,7 @@ static void P_Boss7Thinker(mobj_t *mobj) if (mobj->state == &states[S_BLACKEGG_STND] && mobj->tics == mobj->state->tics) { - mobj->reactiontime += P_Random(); + mobj->reactiontime += P_RandomByte(); if (mobj->health <= mobj->info->damage) mobj->reactiontime /= 4; @@ -4901,7 +4901,7 @@ static void P_Boss7Thinker(mobj_t *mobj) if (mobj->tracer && mobj->tracer->type == MT_BOSS3WAYPOINT && mobj->tracer->spawnpoint && (mobj->tracer->spawnpoint->options & 7) == waypointNum) { - if (P_Random() & 1) + if (P_RandomChance(FRACUNIT/2)) waypointNum++; else waypointNum--; @@ -4913,7 +4913,7 @@ static void P_Boss7Thinker(mobj_t *mobj) } if (waypointNum == 0 && mobj->health <= mobj->info->damage) - waypointNum = 1 + (P_Random() & 1); + waypointNum = 1 + (P_RandomFixed() & 1); // scan the thinkers to find // the waypoint to use @@ -5013,7 +5013,7 @@ static void P_Boss7Thinker(mobj_t *mobj) P_SetMobjState(mobj, mobj->info->spawnstate); } else if (mobj->state == &states[mobj->info->deathstate] && mobj->tics == mobj->state->tics) - S_StartSound(0, sfx_bedie1 + (P_Random() & 1)); + S_StartSound(0, sfx_bedie1 + (P_RandomFixed() & 1)); } @@ -5440,7 +5440,7 @@ static void P_Boss9Thinker(mobj_t *mobj) // An incoming attack is detected! What should we do?! // Go into vector form! mobj->movedir = ANGLE_11hh - FixedAngle(FixedMul(AngleFixed(ANGLE_11hh), FixedDiv((mobj->info->spawnhealth - mobj->health)<info->spawnhealth-1)<movedir = InvAngle(mobj->movedir); mobj->threshold = 6 + (FixedMul(24<info->spawnhealth - mobj->health)<info->spawnhealth-1)<>FRACBITS); if (mobj->info->activesound) @@ -6042,20 +6042,20 @@ static void P_KoopaThinker(mobj_t *koopa) P_XYMovement(koopa); - if (P_Random() < 8 && koopa->z <= koopa->floorz) + if (P_RandomChance(FRACUNIT/32) && koopa->z <= koopa->floorz) koopa->momz = FixedMul(5*FRACUNIT, koopa->scale); if (koopa->z > koopa->floorz) koopa->momz += FixedMul(FRACUNIT/4, koopa->scale); - if (P_Random() < 4) + if (P_RandomChance(FRACUNIT/64)) { mobj_t *flame; - flame = P_SpawnMobj(koopa->x - koopa->radius + FixedMul(5*FRACUNIT, koopa->scale), koopa->y, koopa->z + (P_Random()<<(FRACBITS-2)), MT_KOOPAFLAME); + flame = P_SpawnMobj(koopa->x - koopa->radius + FixedMul(5*FRACUNIT, koopa->scale), koopa->y, koopa->z + (P_RandomByte()<<(FRACBITS-2)), MT_KOOPAFLAME); flame->momx = -FixedMul(flame->info->speed, flame->scale); S_StartSound(flame, sfx_koopfr); } - else if (P_Random() > 250) + else if (P_RandomChance(5*FRACUNIT/256)) { mobj_t *hammer; hammer = P_SpawnMobj(koopa->x - koopa->radius, koopa->y, koopa->z + koopa->height, MT_HAMMER); @@ -6499,11 +6499,11 @@ void P_MobjThinker(mobj_t *mobj) fixed_t ns; mobj_t *mo2; - i = P_Random(); - z = mobj->subsector->sector->floorheight + ((P_Random()&63)*FRACUNIT); + i = P_RandomByte(); + z = mobj->subsector->sector->floorheight + ((P_RandomByte()&63)*FRACUNIT); for (j = 0; j < 2; j++) { - const angle_t fa = (P_Random()*FINEANGLES/16) & FINEMASK; + const angle_t fa = (P_RandomByte()*FINEANGLES/16) & FINEMASK; ns = 64 * FRACUNIT; x = mobj->x + FixedMul(FINESINE(fa),ns); y = mobj->y + FixedMul(FINECOSINE(fa),ns); @@ -6513,7 +6513,7 @@ void P_MobjThinker(mobj_t *mobj) mo2->momx = FixedMul(FINESINE(fa),ns); mo2->momy = FixedMul(FINECOSINE(fa),ns); - i = P_Random(); + i = P_RandomByte(); if (i % 5 == 0) P_SpawnMobj(x, y, z, MT_CHICKEN); @@ -7999,7 +7999,7 @@ void P_SpawnPrecipitation(void) continue; rainmo = P_SpawnSnowMobj(x, y, height, MT_SNOWFLAKE); - mrand = M_Random(); + mrand = M_RandomByte(); if (mrand < 64) P_SetPrecipMobjState(rainmo, S_SNOW3); else if (mrand < 144) @@ -9167,12 +9167,12 @@ ML_NOCLIMB : Direction not controllable { mobj->momz += FixedMul(16*FRACUNIT, mobj->scale); - if (P_Random() & 1) + if (P_RandomChance(FRACUNIT/2)) mobj->momx += FixedMul(16*FRACUNIT, mobj->scale); else mobj->momx -= FixedMul(16*FRACUNIT, mobj->scale); - if (P_Random() & 1) + if (P_RandomChance(FRACUNIT/2)) mobj->momy += FixedMul(16*FRACUNIT, mobj->scale); else mobj->momy -= FixedMul(16*FRACUNIT,mobj->scale); diff --git a/src/p_spec.c b/src/p_spec.c index 37a05946..145ab2d9 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2059,7 +2059,7 @@ void P_SwitchWeather(INT32 weathernum) precipmobj = (precipmobj_t *)think; precipmobj->flags = mobjinfo[MT_SNOWFLAKE].flags; - z = M_Random(); + z = M_RandomByte(); if (z < 64) z = 2; diff --git a/src/p_tick.c b/src/p_tick.c index c72ab5b6..d45f5882 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -363,7 +363,7 @@ static void P_DoAutobalanceTeams(void) { if (totalred > totalblue) { - i = M_Random() % red; + i = M_RandomKey(red); NetPacket.packet.newteam = 2; NetPacket.packet.playernum = redarray[i]; NetPacket.packet.verification = true; @@ -375,7 +375,7 @@ static void P_DoAutobalanceTeams(void) if (totalblue > totalred) { - i = M_Random() % blue; + i = M_RandomKey(blue); NetPacket.packet.newteam = 1; NetPacket.packet.playernum = bluearray[i]; NetPacket.packet.verification = true; diff --git a/src/p_user.c b/src/p_user.c index 65ba0bc6..077caf3e 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2172,9 +2172,9 @@ static void P_DoBubbleBreath(player_t *player) if (!(player->mo->eflags & MFE_UNDERWATER) || ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL && !(player->pflags & PF_NIGHTSMODE)) || player->spectator) return; - if (!(P_Random() % 16)) + if (P_RandomChance(FRACUNIT/16)) bubble = P_SpawnMobj(player->mo->x, player->mo->y, zh, MT_SMALLBUBBLE); - else if (!(P_Random() % 96)) + else if (P_RandomChance(3*FRACUNIT/256)) bubble = P_SpawnMobj(player->mo->x, player->mo->y, zh, MT_MEDIUMBUBBLE); if (bubble) { @@ -6620,7 +6620,7 @@ static void P_MovePlayer(player_t *player) // Little water sound while touching water - just a nicety. if ((player->mo->eflags & MFE_TOUCHWATER) && !(player->mo->eflags & MFE_UNDERWATER) && !player->spectator) { - if (P_Random() & 1 && leveltime % TICRATE == 0) + if (P_RandomChance(FRACUNIT/2) && leveltime % TICRATE == 0) S_StartSound(player->mo, sfx_floush); } @@ -8439,7 +8439,7 @@ static boolean P_SpectatorJoinGame(player_t *player) else if (redscore > bluescore) changeto = 2; else - changeto = (P_Random() & 1) + 1; + changeto = (P_RandomFixed() & 1) + 1; if (player->mo) { @@ -8690,7 +8690,7 @@ void P_PlayerThink(player_t *player) // Add some extra randomization. if (cmd->forwardmove) - P_Random(); + P_RandomFixed(); #ifdef PARANOIA if (player->playerstate == PST_REBORN) diff --git a/src/st_stuff.c b/src/st_stuff.c index 9a4df8a0..f690ca65 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -592,9 +592,13 @@ static void ST_drawDebugInfo(void) if (cv_debug & DBG_RANDOMIZER) // randomizer testing { + fixed_t peekres = P_RandomPeek(); + peekres *= 10000; // Change from fixed point + peekres >>= FRACBITS; // to displayable decimal + V_DrawRightAlignedString(320, height - 16, V_MONOSPACE, va("Init: %08x", P_GetInitSeed())); V_DrawRightAlignedString(320, height - 8, V_MONOSPACE, va("Seed: %08x", P_GetRandSeed())); - V_DrawRightAlignedString(320, height, V_MONOSPACE, va("== : %8d", P_RandomPeek())); + V_DrawRightAlignedString(320, height, V_MONOSPACE, va("== : .%04d", peekres)); height -= 32; } diff --git a/src/v_video.c b/src/v_video.c index 96d7fd8d..2d02139f 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1991,7 +1991,7 @@ Unoptimized version for (y = 0; y < height; y++) { - if (M_Random() < 32) + if (M_RandomChance(FRACUNIT/8)) // 12.5% heatshifter[y] = true; }