From f20b638214cee0c55a8f43c3842e53687e1ba5e5 Mon Sep 17 00:00:00 2001 From: silversurfer Date: Sat, 6 Feb 2016 23:31:57 +0000 Subject: [PATCH] Fix: the game had inconsistent handling of maximum XP level. At some points it was 9, at others it was 10. Now it is 10 throughout the code. New parameters in DifficultySettings.xml: - LevelModifierLowLimit - LevelModifierHighLimit - AllowUnrestrictedXPLevels git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8052 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Editor/EditorMercs.cpp | 4 ++-- GameInitOptionsScreen.h | 3 +++ GameVersion.cpp | 18 +++++++++--------- Tactical/RandomMerc.cpp | 2 +- Tactical/Soldier Create.cpp | 36 +++++++++++++++++++++--------------- Tactical/Soldier Profile.cpp | 6 +++--- XML_DifficultySettings.cpp | 23 +++++++++++++++++++++++ 7 files changed, 62 insertions(+), 30 deletions(-) diff --git a/Editor/EditorMercs.cpp b/Editor/EditorMercs.cpp index f55b2342..10dd013e 100644 --- a/Editor/EditorMercs.cpp +++ b/Editor/EditorMercs.cpp @@ -1899,9 +1899,9 @@ void ExtractAndUpdateMercAttributes() gpSelected->pDetailedPlacement->bMechanical = (INT8)min( GetNumericStrictValueFromField( 11 ), 100 ); gpSelected->pDetailedPlacement->bMorale = (INT8)min( GetNumericStrictValueFromField( 11 ), 100 ); - //make sure that experience level ranges between 1 and 9 + //make sure that experience level ranges between 1 and 10 if( gpSelected->pDetailedPlacement->bExpLevel != -1 ) - gpSelected->pDetailedPlacement->bExpLevel = max( min( gpSelected->pDetailedPlacement->bExpLevel , 9 ), 1 ); + gpSelected->pDetailedPlacement->bExpLevel = max( min( gpSelected->pDetailedPlacement->bExpLevel , 10 ), 1 ); //no such thing as a life max of 0 if( !gpSelected->pDetailedPlacement->bLifeMax ) diff --git a/GameInitOptionsScreen.h b/GameInitOptionsScreen.h index aed65efc..2cd38fa2 100644 --- a/GameInitOptionsScreen.h +++ b/GameInitOptionsScreen.h @@ -77,6 +77,9 @@ typedef struct BOOLEAN bUpgradeAdminsToTroops; BOOLEAN bUpgradeGarrisonsAdminsToTroops; UINT8 usAlwaysUpGradeAdminsToTroopsProgress; + UINT8 usLevelModifierLowLimit; + UINT8 usLevelModifierHighLimit; + BOOLEAN bAllowUnrestrictedXPLevels; BOOLEAN bQueenLosingControlOfSector; BOOLEAN bBloodcatAmbush; BOOLEAN bAirRaidLookForDive; diff --git a/GameVersion.cpp b/GameVersion.cpp index 65131719..bea314b2 100644 --- a/GameVersion.cpp +++ b/GameVersion.cpp @@ -15,9 +15,9 @@ #ifdef JA2EDITOR #ifdef JA2UB - CHAR16 zVersionLabel[256] = { L"Unfinished Business - Map Editor v1.13.8043 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Unfinished Business - Map Editor v1.13.8052 (Development Build)" }; #else - CHAR16 zVersionLabel[256] = { L"Map Editor v1.13.8043 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Map Editor v1.13.8052 (Development Build)" }; #endif // ------------------------------ @@ -27,11 +27,11 @@ //DEBUG BUILD VERSION #ifdef JA2UB - CHAR16 zVersionLabel[256] = { L"Debug: Unfinished Business - v1.13.8043 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Debug: Unfinished Business - v1.13.8052 (Development Build)" }; #elif defined (JA113DEMO) - CHAR16 zVersionLabel[256] = { L"Debug: JA2 Demo - v1.13.8043 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Debug: JA2 Demo - v1.13.8052 (Development Build)" }; #else - CHAR16 zVersionLabel[256] = { L"Debug: v1.13.8043 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Debug: v1.13.8052 (Development Build)" }; #endif #elif defined CRIPPLED_VERSION @@ -46,16 +46,16 @@ //RELEASE BUILD VERSION #ifdef JA2UB - CHAR16 zVersionLabel[256] = { L"Release Unfinished Business - v1.13.8043 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Release Unfinished Business - v1.13.8052 (Development Build)" }; #elif defined (JA113DEMO) - CHAR16 zVersionLabel[256] = { L"Release JA2 Demo - v1.13.8043 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Release JA2 Demo - v1.13.8052 (Development Build)" }; #else - CHAR16 zVersionLabel[256] = { L"Release v1.13.8043 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Release v1.13.8052 (Development Build)" }; #endif #endif -CHAR8 czVersionNumber[16] = { "Build 16.01.28" }; //YY.MM.DD +CHAR8 czVersionNumber[16] = { "Build 16.02.06" }; //YY.MM.DD CHAR16 zTrackingNumber[16] = { L"Z" }; // SAVE_GAME_VERSION is defined in header, change it there diff --git a/Tactical/RandomMerc.cpp b/Tactical/RandomMerc.cpp index 420383b4..f110fac8 100644 --- a/Tactical/RandomMerc.cpp +++ b/Tactical/RandomMerc.cpp @@ -796,7 +796,7 @@ void RandomizeMerc(UINT8 profile_id, MERCPROFILESTRUCT* merc, BOOL random_gear_k memset(merc->bSkillTraits, 0, sizeof(merc->bSkillTraits)); //determine character level and points (absolute maximum = 666 points) - merc->bExpLevel = Random(9) + 1; + merc->bExpLevel = Random(10) + 1; INT16 points = 300 + (merc->bExpLevel * 10) + Random(20); //determine roles and traits diff --git a/Tactical/Soldier Create.cpp b/Tactical/Soldier Create.cpp index 45b65599..fc8ad8f8 100644 --- a/Tactical/Soldier Create.cpp +++ b/Tactical/Soldier Create.cpp @@ -2379,14 +2379,19 @@ void CreateDetailedPlacementGivenBasicPlacementInfo( SOLDIERCREATE_STRUCT *pp, B DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CreateDetailedPlacementGivenBasicPlacementInfo: adjust stats and level")); // Adjust level and statistics for Linda's prespecified relative attribute level + + // silversurfer: new variable level range which modifies the narrow old ranges below + INT8 sRandomizedLevelModifier = Random( zDiffSetting[gGameOptions.ubDifficultyLevel].usLevelModifierLowLimit + zDiffSetting[gGameOptions.ubDifficultyLevel].usLevelModifierHighLimit + 1 ); + sRandomizedLevelModifier = sRandomizedLevelModifier - zDiffSetting[gGameOptions.ubDifficultyLevel].usLevelModifierLowLimit; + switch ( bp->bRelativeAttributeLevel ) { // NOTE: bStatsModifier already includes the bExpLevelModifier since it's based on the level itself! - case 0: bExpLevelModifier += -1; bStatsModifier += -1; break; - case 1: bExpLevelModifier += -1; bStatsModifier += 0; break; - case 2: bExpLevelModifier += 0; bStatsModifier += 0; break; - case 3: bExpLevelModifier += +1; bStatsModifier += 0; break; - case 4: bExpLevelModifier += +1; bStatsModifier += +1; break; + case 0: bExpLevelModifier += -1 + sRandomizedLevelModifier; bStatsModifier += -1; break; + case 1: bExpLevelModifier += -1 + sRandomizedLevelModifier; bStatsModifier += 0; break; + case 2: bExpLevelModifier += 0 + sRandomizedLevelModifier; bStatsModifier += 0; break; + case 3: bExpLevelModifier += +1 + sRandomizedLevelModifier; bStatsModifier += 0; break; + case 4: bExpLevelModifier += +1 + sRandomizedLevelModifier; bStatsModifier += +1; break; default: AssertMsg( FALSE, String( "Invalid bRelativeAttributeLevel = %d", bp->bRelativeAttributeLevel ) ); @@ -2513,11 +2518,11 @@ void CreateDetailedPlacementGivenBasicPlacementInfo( SOLDIERCREATE_STRUCT *pp, B ubStatsLevel = min( 10, ubStatsLevel ); //maximum stats level of 9 // 10 - Madd - this will probably apply to all dif levels though //Set the minimum base attribute - bBaseAttribute = 49 + ( 4 * ubStatsLevel ); + bBaseAttribute = 45 + ( 4 * ubStatsLevel ); DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CreateDetailedPlacementGivenBasicPlacementInfo: roll stats and skills")); //Roll soldier's statistics and skills - //Stat range is currently 49-99, bell-curved around a range of 16 values dependent on the stats level + //Stat range is currently 49-100, bell-curved around a range of 16 values dependent on the stats level pp->bLifeMax = (INT8)(bBaseAttribute + Random( 9 ) + Random( 8 )); pp->bLife = pp->bLifeMax; pp->bAgility = (INT8)(bBaseAttribute + Random( 9 ) + Random( 8 )); @@ -2534,8 +2539,9 @@ void CreateDetailedPlacementGivenBasicPlacementInfo( SOLDIERCREATE_STRUCT *pp, B // CJC: now calculate the REAL experience level if in the really upper end // Madd + // silversurfer: changed that to be optional. Some players might want to have the full level range for the opposition without playing "Insane". DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CreateDetailedPlacementGivenBasicPlacementInfo: reduce stats and level")); - if ( gGameOptions.ubDifficultyLevel <= DIF_LEVEL_HARD ) + if ( gGameOptions.ubDifficultyLevel <= DIF_LEVEL_HARD && !zDiffSetting[gGameOptions.ubDifficultyLevel].bAllowUnrestrictedXPLevels ) ReduceHighExpLevels( &( pp->bExpLevel ) ); pp->fVisible = 0; @@ -2784,10 +2790,10 @@ void UpdateSoldierWithStaticDetailedInformation( SOLDIERTYPE *s, SOLDIERCREATE_S INT8 bBaseAttribute; s->stats.bExpLevel = spp->bExpLevel; //Set the minimum base attribute - bBaseAttribute = 49 + ( 4 * s->stats.bExpLevel ); + bBaseAttribute = 45 + ( 4 * s->stats.bExpLevel ); //Roll enemy's combat statistics, taking bExpLevel into account. - //Stat range is currently 40-99, slightly bell-curved around the bExpLevel + //Stat range is currently 49-100, slightly bell-curved around the bExpLevel s->stats.bLifeMax = (INT8)(bBaseAttribute + Random( 9 ) + Random( 8 )); s->stats.bLife = s->stats.bLifeMax; s->stats.bAgility = (INT8)(bBaseAttribute + Random( 9 ) + Random( 8 )); @@ -2877,17 +2883,17 @@ void ModifySoldierAttributesWithNewRelativeLevel( SOLDIERTYPE *s, INT8 bRelative //Set the experience level based on the relative attribute level // NOTE OF WARNING: THIS CURRENTLY IGNORES THE ENEMY CLASS (ADMIN/REG/ELITE) FOR CALCULATING LEVEL & ATTRIBUTES - // Rel level 0: Lvl 1, 1: Lvl 2-3, 2: Lvl 4-5, 3: Lvl 6-7, 4: Lvl 8-9 - s->stats.bExpLevel = (INT8)(2 * bRelativeAttributeLevel + Random(2)); + // Rel level 0: Lvl 1-2, 1: Lvl 2-4, 2: Lvl 4-6, 3: Lvl 6-8, 4: Lvl 8-10 + s->stats.bExpLevel = (INT8)(2 * bRelativeAttributeLevel + Random(3)); s->stats.bExpLevel = max( 1, s->stats.bExpLevel ); //minimum level of 1 - s->stats.bExpLevel = min( 9, s->stats.bExpLevel ); //maximum level of 9 + s->stats.bExpLevel = min( 10, s->stats.bExpLevel ); //maximum level of 9 // 10 //Set the minimum base attribute - bBaseAttribute = 49 + ( 4 * s->stats.bExpLevel ); + bBaseAttribute = 45 + ( 4 * s->stats.bExpLevel ); //Roll enemy's combat statistics, taking bExpLevel into account. - //Stat range is currently 40-99, slightly bell-curved around the bExpLevel + //Stat range is currently 49-100, slightly bell-curved around the bExpLevel s->stats.bLifeMax = (INT8)(bBaseAttribute + Random( 9 ) + Random( 8 )); s->stats.bLife = s->stats.bLifeMax; // added by SANDRO - insta-healable injury zero on soldier creation diff --git a/Tactical/Soldier Profile.cpp b/Tactical/Soldier Profile.cpp index 79e9196a..c51630b1 100644 --- a/Tactical/Soldier Profile.cpp +++ b/Tactical/Soldier Profile.cpp @@ -463,7 +463,7 @@ void RandomStats() { pProfile = &(gMercProfiles[cnt]); // Buggler: +/- random range will be limited due to min/max allowed value - pProfile->bExpLevel = RandomAbsoluteRange( pProfile->bExpLevel, 1, 9, Exp, Type ); + pProfile->bExpLevel = RandomAbsoluteRange( pProfile->bExpLevel, 1, 10, Exp, Type ); pProfile->bLifeMax = RandomAbsoluteRange( pProfile->bLifeMax, 1, 100, Stats, Type ); pProfile->bLife = pProfile->bLifeMax; pProfile->bAgility = RandomAbsoluteRange( pProfile->bAgility, 1, 100, Stats, Type ); @@ -488,7 +488,7 @@ void RandomStats() pProfile = &(gMercProfiles[cnt]); if ( gRandomStatsValue[cnt].RandomExpLevel == TRUE ) - pProfile->bExpLevel = RandomAbsoluteRange( pProfile->bExpLevel, 1, 9, Exp, Type ); + pProfile->bExpLevel = RandomAbsoluteRange( pProfile->bExpLevel, 1, 10, Exp, Type ); if ( gRandomStatsValue[cnt].RandomLife == TRUE ) pProfile->bLifeMax = RandomAbsoluteRange( pProfile->bLifeMax, 1, 100, Stats, Type ); @@ -534,7 +534,7 @@ void RandomStats() pProfile = &(gMercProfiles[cnt]); if ( gRandomStatsValue[cnt].RandomExpLevel == TRUE ) - pProfile->bExpLevel = RandomAbsoluteRange( pProfile->bExpLevel, 1, 9, Exp, Type ); + pProfile->bExpLevel = RandomAbsoluteRange( pProfile->bExpLevel, 1, 10, Exp, Type ); bBaseAttribute = gRandomStatsValue[cnt].BaseAttribute + ( 4 * pProfile->bExpLevel ); diff --git a/XML_DifficultySettings.cpp b/XML_DifficultySettings.cpp index e7fa15e9..6d683a6d 100644 --- a/XML_DifficultySettings.cpp +++ b/XML_DifficultySettings.cpp @@ -96,6 +96,9 @@ DifficultySettingsParseDataStartElementHandle(void *userData, const XML_Char *na strcmp(name, "UpgradeAdminsToTroops") == 0 || strcmp(name, "UpgradeGarrisonsAdminsToTroops") == 0 || strcmp(name, "AlwaysUpGradeAdminsToTroopsProgress" ) == 0 || + strcmp(name, "LevelModifierLowLimit" ) == 0 || + strcmp(name, "LevelModifierHighLimit" ) == 0 || + strcmp(name, "AllowUnrestrictedXPLevels" ) == 0 || strcmp(name, "QueenAttackLosingControlOfSector") == 0 || strcmp(name, "BloodcatAmbushSectors") == 0 || strcmp(name, "AirRaidLookForDive") == 0 || @@ -205,6 +208,9 @@ difficultySettingsEndElementHandle(void *userData, const XML_Char *name) zDiffSetting[pData->curDifficultySettings.uiIndex].bUpgradeAdminsToTroops = pData->curDifficultySettings.bUpgradeAdminsToTroops; zDiffSetting[pData->curDifficultySettings.uiIndex].bUpgradeGarrisonsAdminsToTroops = pData->curDifficultySettings.bUpgradeGarrisonsAdminsToTroops; zDiffSetting[pData->curDifficultySettings.uiIndex].usAlwaysUpGradeAdminsToTroopsProgress = pData->curDifficultySettings.usAlwaysUpGradeAdminsToTroopsProgress; + zDiffSetting[pData->curDifficultySettings.uiIndex].usLevelModifierLowLimit = pData->curDifficultySettings.usLevelModifierLowLimit; + zDiffSetting[pData->curDifficultySettings.uiIndex].usLevelModifierHighLimit = pData->curDifficultySettings.usLevelModifierHighLimit; + zDiffSetting[pData->curDifficultySettings.uiIndex].bAllowUnrestrictedXPLevels = pData->curDifficultySettings.bAllowUnrestrictedXPLevels; zDiffSetting[pData->curDifficultySettings.uiIndex].bQueenLosingControlOfSector = pData->curDifficultySettings.bQueenLosingControlOfSector; @@ -485,6 +491,23 @@ difficultySettingsEndElementHandle(void *userData, const XML_Char *name) pData->curDifficultySettings.usAlwaysUpGradeAdminsToTroopsProgress = (UINT8)atol( pData->szCharData ); pData->curDifficultySettings.usAlwaysUpGradeAdminsToTroopsProgress = min( pData->curDifficultySettings.usAlwaysUpGradeAdminsToTroopsProgress, 100 ); } + else if ( strcmp( name, "LevelModifierLowLimit" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curDifficultySettings.usLevelModifierLowLimit = (UINT8)atol( pData->szCharData ); + pData->curDifficultySettings.usLevelModifierLowLimit = min( pData->curDifficultySettings.usLevelModifierLowLimit, 5 ); + } + else if ( strcmp( name, "LevelModifierHighLimit" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curDifficultySettings.usLevelModifierHighLimit = (UINT8)atol( pData->szCharData ); + pData->curDifficultySettings.usLevelModifierHighLimit = min( pData->curDifficultySettings.usLevelModifierHighLimit, 5 ); + } + else if(strcmp(name, "AllowUnrestrictedXPLevels") == 0) + { + pData->curElement = ELEMENT; + pData->curDifficultySettings.bAllowUnrestrictedXPLevels = (BOOLEAN) atol(pData->szCharData); + } else if(strcmp(name, "QueenAttackLosingControlOfSector") == 0) { pData->curElement = ELEMENT;