diff --git a/GameSettings.cpp b/GameSettings.cpp index 807e39755..32bd06c16 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -1487,6 +1487,7 @@ void LoadGameExternalOptions() gGameExternalOptions.fBackPackWeightLowersAP = iniReader.ReadBoolean("Tactical Gameplay Settings","BACKPACKWEIGHT_LOWERS_AP", TRUE); gGameExternalOptions.fEnemyJams = iniReader.ReadBoolean("Tactical Gameplay Settings", "ENEMY_JAMS", true, false); + gGameExternalOptions.fNewRandom = iniReader.ReadBoolean("Tactical Gameplay Settings", "NEW_RANDOM", true, false); //################# Tactical Enemy Role Settings ################## diff --git a/GameSettings.h b/GameSettings.h index 4cd21e47a..181c4b61e 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -548,6 +548,8 @@ typedef struct // sevenfm: enemy gun jams BOOLEAN fEnemyJams; + // use new code for random + BOOLEAN fNewRandom; // WDS - Improve Tony's and Devin's inventory like BR's // silversurfer: not used anymore, see "Tactical\XML_Merchants.cpp" for "useBRSetting" diff --git a/Standard Gaming Platform/Random.cpp b/Standard Gaming Platform/Random.cpp index c4d4fe88f..d78445dd3 100644 --- a/Standard Gaming Platform/Random.cpp +++ b/Standard Gaming Platform/Random.cpp @@ -40,6 +40,27 @@ UINT32 MPPreRandom( UINT32 uiRange ) UINT32 guiPreRandomIndex; UINT32 guiPreRandomNums[MAX_PREGENERATED_NUMS]; +#include + +std::random_device gRandomDevice; // only used once to initialize (seed) engine +std::mt19937 gRandomNumberGenerator(gRandomDevice()); // random-number engine used (Mersenne-Twister in this case) + +UINT32 NewRandom(UINT32 max) +{ + if (is_networked && is_client) + return MPPreRandom(max); + + if (max <= 1) + return 0; + + UINT32 min = 0; + + std::uniform_int_distribution uni(min, max - 1); // guaranteed unbiased + + auto random_integer = uni(gRandomNumberGenerator); + return random_integer; +} + UINT32 GetRndNum(UINT32 maxnum) { if (is_networked && is_client) @@ -52,8 +73,6 @@ UINT32 GetRndNum(UINT32 maxnum) { GetCursorPos(&pt);// Get cursor location srand(maxnum ^ rnd ^ pt.x ^ pt.y ^ GetTickCount()); -//SendFmtMsg("Random Number Generator Reinitialized."); -//for(int l=0;l<100;l++)SendFmtMsg("%2d", Random(100)); } if(maxnum == 0) return(0); diff --git a/Standard Gaming Platform/random.h b/Standard Gaming Platform/random.h index 7da2a523f..008c3c684 100644 --- a/Standard Gaming Platform/random.h +++ b/Standard Gaming Platform/random.h @@ -5,6 +5,7 @@ #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 @@ -18,15 +19,22 @@ 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) { - return(GetRndNum(uiRange)); + if (gGameExternalOptions.fNewRandom) + return NewRandom(uiRange); + else + return GetRndNum(uiRange); } -inline INT32 iRandom(UINT32 uiRange) +/*inline INT32 iRandom(UINT32 uiRange) { return(GetRndNum(uiRange)); -} +}*/ inline BOOLEAN Chance( UINT32 uiChance ) { @@ -35,7 +43,8 @@ inline BOOLEAN Chance( UINT32 uiChance ) inline UINT32 PreRandom(UINT32 uiRange) { - return(GetRndNum(uiRange)); + return Random(uiRange); + //return(GetRndNum(uiRange)); } inline BOOLEAN PreChance( UINT32 uiChance ) @@ -70,13 +79,13 @@ inline UINT32 Random(UINT32 uiRange) // Returns a pseudo-random integer between 0 and uiRange-1 -inline INT32 iRandom(UINT32 uiRange) +/*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. diff --git a/Strategic/Queen Command.cpp b/Strategic/Queen Command.cpp index 9cbf0242a..fd2eefc01 100644 --- a/Strategic/Queen Command.cpp +++ b/Strategic/Queen Command.cpp @@ -1910,7 +1910,9 @@ void AddPossiblePendingEnemiesToBattle() else { // WANNE: Hack: If no valid insertion is found, get random insertion instead of Assert() error - UINT32 rndInsertionCode = GetRndNum(3); + // sevenfm: use Random() instead + //UINT32 rndInsertionCode = GetRndNum(3); + UINT32 rndInsertionCode = Random(4); ubInsertionCode = rndInsertionCode; //Assert(0); @@ -1929,9 +1931,11 @@ void AddPossiblePendingEnemiesToBattle() else { // WANNE: Hack: If no valid insertion is found, get random insertion instead of Assert() error - UINT32 rndInsertionCode = GetRndNum(3); + // sevenfm: use Random() instead + //UINT32 rndInsertionCode = GetRndNum(3); + UINT32 rndInsertionCode = Random(4); ubInsertionCode = rndInsertionCode; - + //Assert(0); } } diff --git a/Tactical/Soldier Init List.cpp b/Tactical/Soldier Init List.cpp index c9bec31b1..ffbaf7c21 100644 --- a/Tactical/Soldier Init List.cpp +++ b/Tactical/Soldier Init List.cpp @@ -680,9 +680,10 @@ BOOLEAN AddPlacementToWorld( SOLDIERINITNODE *curr, GROUP *pGroup = NULL ) if (tempDetailedPlacement.ubProfile == NO_PROFILE) {//dnl!!! // these guys should be guarding Tony! + // sevenfm: PreRandom(1) always returns 0, use PreRandom(2) instead tempDetailedPlacement.sInsertionGridNo = gModSettings.iPornShopEntranceGridNo + - (INT16) ( PreRandom( 8 ) * ( PreRandom( 1 ) ? -1 : 1) - + PreRandom( 8 ) * ( PreRandom( 1 ) ? -1 : 1) * WORLD_ROWS ); + //(INT16)(PreRandom(8) * (PreRandom(1) ? -1 : 1) + PreRandom(8) * (PreRandom(1) ? -1 : 1) * WORLD_ROWS); + (INT16)(PreRandom(8) * (PreRandom(2) ? -1 : 1) + PreRandom(8) * (PreRandom(2) ? -1 : 1) * WORLD_ROWS); switch( PreRandom( 3 ) ) { @@ -701,9 +702,10 @@ BOOLEAN AddPlacementToWorld( SOLDIERINITNODE *curr, GROUP *pGroup = NULL ) else if (tempDetailedPlacement.ubProfile == BILLY ) {//dnl!!! // billy should now be able to roam around + // sevenfm: PreRandom(1) always returns 0, use PreRandom(2) instead tempDetailedPlacement.sInsertionGridNo = gModSettings.iPornShopEntranceGridNo + - (INT16) ( PreRandom( 30 ) * ( PreRandom( 1 ) ? -1 : 1) - + PreRandom( 30 ) * ( PreRandom( 1 ) ? -1 : 1) * WORLD_ROWS ); + //(INT16)(PreRandom(30) * (PreRandom(1) ? -1 : 1) + PreRandom(30) * (PreRandom(1) ? -1 : 1) * WORLD_ROWS); + (INT16)(PreRandom(30) * (PreRandom(2) ? -1 : 1) + PreRandom(30) * (PreRandom(2) ? -1 : 1) * WORLD_ROWS); tempDetailedPlacement.bOrders = SEEKENEMY; } else if ( tempDetailedPlacement.ubProfile == MADAME )