#ifndef __RANDOM_ #define __RANDOM_ #define BMP_RANDOM #include "types.h" #include "DEBUG.H" #include "GameSettings.h" //IMPORTANT: Changing this define will invalidate the JA2 save. If this is necessary, please ifdef your own value. #define MAX_PREGENERATED_NUMS 256 #ifdef BMP_RANDOM//dnl ch55 111009 !!!Do not undefine this if plan play Big maps, old random generator not work properly and return only 2^15 different values although seems that should return all posible INT32 values extern UINT32 guiPreRandomIndex; extern UINT32 guiPreRandomNums[MAX_PREGENERATED_NUMS]; extern void InitializeRandom(void); extern UINT32 GetRndNum(UINT32 maxnum); extern bool gfMPDebugOutputRandoms; UINT32 NewRandom(UINT32 max); extern GAME_EXTERNAL_OPTIONS gGameExternalOptions; inline UINT32 Random(UINT32 uiRange) { if (gGameExternalOptions.fNewRandom) return NewRandom(uiRange); else return GetRndNum(uiRange); } /*inline INT32 iRandom(UINT32 uiRange) { return(GetRndNum(uiRange)); }*/ inline BOOLEAN Chance( UINT32 uiChance ) { return((BOOLEAN)(Random(100) < uiChance)); } inline UINT32 PreRandom(UINT32 uiRange) { return Random(uiRange); //return(GetRndNum(uiRange)); } inline BOOLEAN PreChance( UINT32 uiChance ) { return((BOOLEAN)(PreRandom(100) < uiChance)); } #else #include extern UINT32 guiPreRandomIndex; extern std::vector guiPreRandomNums; extern void InitializeRandom(void); // WDS 04/20/2009 -- Random functions were moved to inline functions here in the header file // to speed up the whole program a bit. // Returns a pseudo-random unsigned integer between 0 and uiRange-1 inclusive. // NOTE THE -1! So if you call Random(100) the numbers returned will // be between 0 and 99 inclusive. inline UINT32 Random(UINT32 uiRange) { // Always return 0, if no range given (it's not an error) if (uiRange == 0) return(0); return rand() * uiRange / RAND_MAX % uiRange; } // Returns a pseudo-random integer between 0 and uiRange-1 /*inline INT32 iRandom(UINT32 uiRange) { // Always return 0, if no range given (it's not an error) if (uiRange == 0) return(0); return rand() * uiRange / RAND_MAX % uiRange; }*/ //Chance( 74 ) returns TRUE 74% of the time. If uiChance >= 100, then it will always return TRUE. inline BOOLEAN Chance( UINT32 uiChance ) { //AssertLE(uiChance, 100); // lalien: since uiChance calculation is based on different values it can happen that uiChance is > than 100% // It's not critical because uiChance >= 100 will always return TRUE. No need to crash the entire game. // Make sure that uiChance value is not < than 0, or it can switch to positive return (BOOLEAN)(Random( 100 ) < uiChance); } //Returns a pregenerated random number. //Used to deter Ian's tactic of shoot, miss, restore saved game :) inline UINT32 PreRandom( UINT32 uiRange ) { UINT32 uiNum; if( uiRange == 0 ) return 0; //Extract the current pregenerated number uiNum = guiPreRandomNums[ guiPreRandomIndex ] * uiRange / RAND_MAX % uiRange; //Go to the next index. guiPreRandomIndex++; // Reload the random numbers even so often if (guiPreRandomIndex == MAX_PREGENERATED_NUMS / 2) { // [0..(MAX_PREGENERATED_NUMS/2) -1] for( unsigned idx = 0; idx < MAX_PREGENERATED_NUMS / 2; ++idx ) { guiPreRandomNums[ idx ] = rand(); } } else if (guiPreRandomIndex >= (UINT32)MAX_PREGENERATED_NUMS ) { // [MAX_PREGENERATED_NUMS/2 .. MAX_PREGENERATED_NUMS-1] for( unsigned idx = MAX_PREGENERATED_NUMS / 2; idx < MAX_PREGENERATED_NUMS; ++idx ) { guiPreRandomNums[ idx ] = rand(); } guiPreRandomIndex = 0; } return uiNum; } inline BOOLEAN PreChance( UINT32 uiChance ) { //AssertLE(uiChance, 100); // lalien: since uiChance calculation is based on different values it can happen that uiChance is > than 100% // It's not critical because uiChance >= 100 will always return TRUE. No need to crash the entire game. // Make sure that uiChance value is not < than 0, or it can switch to positive return (BOOLEAN)(PreRandom( 100 ) < uiChance); } #endif #endif