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;