mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-11-10 15:22:20 +00:00
Merge branch 'bp_random2' into 'next'
xorshift* PRNG This needs testing to ensure I didn't mess anything up switching function names around. Our PRNG sucks. This is probably obvious. I wish I had known better at the time I implemented it, but oh well. The replacement is an xorshift* PRNG variant with period 2^32 - 1 (meaning that the PRNG state will loop after four billion calls ... that's not likely to happen), versus the old PRNG's period of about 2^22 (?). The output is also much more random and less predictable; the old PRNG would fall into a predictable loop of output after about 4000 numbers were generated, which isn't much. The PRNG here also outputs numbers as fixed point from [0,1) (that's 0 to FRACUNIT-1, in other words) instead of single bytes at a time. This makes it much easier to calculate things for, say, P_RandomRange and P_RandomKey. A new macro, P_RandomChance(p), is now in use that returns true _p_ percent of the time, where _p_ is a fixed_t probability from 0 (0%) to FRACUNIT (100%). This doesn't affect netgames at all; the code for seed saving and restoring is identical (aside from a check to prevent seed being set to 0, which breaks xorshift PRNGs). Demos break, but A: _duh_ and B: they're already broken by all the changes to physics to accommodate slopes. P_Random is deprecated in Lua, as the function was renamed to P_RandomByte. Aside from that, nothing special. See merge request !64
This commit is contained in:
commit
b288d8a399
17 changed files with 302 additions and 250 deletions
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 ?
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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;
|
||||
|
|
182
src/m_random.c
182
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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
133
src/p_enemy.c
133
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);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
70
src/p_mobj.c
70
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)<<FRACBITS, (mobj->info->spawnhealth-1)<<FRACBITS)));
|
||||
if (P_Random()&1)
|
||||
if (P_RandomChance(FRACUNIT/2))
|
||||
mobj->movedir = InvAngle(mobj->movedir);
|
||||
mobj->threshold = 6 + (FixedMul(24<<FRACBITS, FixedDiv((mobj->info->spawnhealth - mobj->health)<<FRACBITS, (mobj->info->spawnhealth-1)<<FRACBITS))>>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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
10
src/p_user.c
10
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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue