New Feature: Militia Volunteer Pool limits the number of militia we can train. Turned off by default.

GameDir >= r2210 is recommended.

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7746 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Flugente
2015-02-22 18:52:41 +00:00
parent caf482614a
commit c7c085b04f
17 changed files with 165 additions and 6 deletions
+14
View File
@@ -1412,6 +1412,10 @@ BOOLEAN CanCharacterTrainMilitia( SOLDIERTYPE *pSoldier )
{
AssertNotNIL(pSoldier);
// Flugente: militia volunteer pool
if ( !GetVolunteerPool() )
return FALSE;
// Make sure the basic sector/merc variables are still applicable. This is simply a fail-safe.
if( !BasicCanCharacterTrainMilitia( pSoldier ) )
{
@@ -2480,6 +2484,9 @@ void UpdateAssignments()
// reset scan flags in all sectors
ClearSectorScanResults();
// update militia volunteer count
UpdateVolunteers();
// run through sectors and handle each type in sector
for(sX = 0 ; sX < MAP_WORLD_X; ++sX )
{
@@ -18375,6 +18382,13 @@ BOOLEAN CanCharacterTrainMilitiaWithErrorReport( SOLDIERTYPE *pSoldier )
return( FALSE );
}
if ( !GetVolunteerPool() )
{
swprintf( sString, L"There are no volunteers for militia left!" );
DoScreenIndependantMessageBox( sString, MSG_BOX_FLAG_OK, NULL );
return (FALSE);
}
if ( 100 <= GetMobileMilitiaQuota( TRUE ) )
return ( FALSE );
+22 -1
View File
@@ -7667,6 +7667,25 @@ void MilitiaGroupBoxButtonCallback( GUI_BUTTON *btn, INT32 reason )
void DisplayMilitiaGroupBox()
{
// if we play with a limited militia pool, show us how many we have
if ( fShowMilitia && gGameExternalOptions.fMilitiaVolunteerPool )
{
CHAR16 sVolunteerString[200];
SetFont( FONT12ARIAL );
if ( GetVolunteerPool() >= 2 * gGameExternalOptions.iTrainingSquadSize )
SetFontForeground( FONT_FCOLOR_GREEN );
else if ( GetVolunteerPool( ) >= gGameExternalOptions.iTrainingSquadSize )
SetFontForeground( FONT_FCOLOR_YELLOW );
else
SetFontForeground( FONT_FCOLOR_RED );
// header
swprintf( sVolunteerString, szMilitiaStrategicMovementText[8], GetVolunteerPool( ), CalcHourlyVolunteerGain( ) );
mprintf( MapScreenRect.iLeft + 20, MapScreenRect.iBottom - 10, sVolunteerString );
}
if ( !gMilitiaGroupBoxCreated )
return;
@@ -7679,6 +7698,8 @@ void DisplayMilitiaGroupBox()
return;
}
SetFontForeground( FONT_FCOLOR_WHITE );
CreateMilitiaGroupBoxVideoObjects();
// move to defines later
@@ -7715,7 +7736,7 @@ void DisplayMilitiaGroupBox()
SetFontForeground( FONT_FCOLOR_WHITE );
SetFontBackground( FONT_MCOLOR_BLACK );
//Display the background for the drop down window
//Display the background
ColorFillVideoSurfaceArea( FRAME_BUFFER, gMilitiaGroupBoxX, gMilitiaGroupBoxY, gMilitiaGroupBoxX + MILITIAGROUPBOX_WIDTH, gMilitiaGroupBoxY + MILITIAGROUPBOX_HEIGHT, Get16BPPColor( FROMRGB( 50, 50, 50 ) ) );
// mouse region - clicking on a group name selects that group
+7 -1
View File
@@ -191,6 +191,9 @@ void GenerateMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY,
ubMilitiaToTrain = CalcNumMilitiaTrained(ubBestLeadership, TRUE);
}
// Flugente: our pool of volunteers limits how many militia can be created
ubMilitiaToTrain = min( ubMilitiaToTrain, GetVolunteerPool( ) );
// HEADROCK HAM 3.4: Composition of new Mobile Militia groups is now dictated by two INI settings controlling
// the percentage of Elites and Regulars within the group. If the percentage for either is above 0, at least
// one militia of that type will be created every time. Green militia are created based on whatever remains.
@@ -302,6 +305,9 @@ void GenerateMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY,
ubTargetGreen--;
}
// Flugente: substract volunteers
AddVolunteers( -ubMilitiaToTrain );
while (ubMilitiaToTrain > 0)
{
@@ -447,7 +453,7 @@ void GenerateMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY,
--pTargetSector->ubNumberOfCivsAtLevel[ELITE_MILITIA];
}
}
// Update the militia if the current sector is affected
if (gfStrategicMilitiaChangesMade)
{
+10 -1
View File
@@ -28,6 +28,7 @@
// HEADROCK HAM 3.6: Added for facility string printing...
#include "PopUpBox.h"
#include "CampaignStats.h" // added by Flugente
#include "Town Militia.h" // added by Flugente
#endif
#include "postalservice.h"
@@ -391,10 +392,18 @@ BOOLEAN SetThisSectorAsPlayerControlled( INT16 sMapX, INT16 sMapY, INT8 bMapZ, B
//if ( ubTraverseType == )
if ( GetTownIdForSector( sMapX, sMapY ) != BLANK_SECTOR )
UINT8 townid = GetTownIdForSector( sMapX, sMapY );
if ( townid != BLANK_SECTOR )
{
// first liberation of a town sector -> special texts
gCurrentIncident.usIncidentFlags |= INCIDENT_FIRST_LIBERATION;
// liberating a town sector for the first time grants us an initial wave of volunteers
UINT16 population = GetSectorPopulation( sMapX, sMapY );
FLOAT loyalpopulation = gTownLoyalty[townid].ubRating * population / 100;
AddVolunteers( loyalpopulation * gGameExternalOptions.dMilitiaVolunteerGainFactorLiberation );
}
}
+69 -2
View File
@@ -127,6 +127,9 @@ void TownMilitiaTrainingCompleted( SOLDIERTYPE *pTrainer, INT16 sMapX, INT16 sMa
UINT8 ubTrainerEffectiveLeadership = FindBestMilitiaTrainingLeadershipInSector ( sMapX, sMapY, pTrainer->bSectorZ, TOWN_MILITIA );
UINT8 iTrainingSquadSize = __min(iMaxMilitiaPerSector, CalcNumMilitiaTrained(ubTrainerEffectiveLeadership, FALSE));
// Flugente: our pool of volunteers limits how many militia can be created
iTrainingSquadSize = min( iTrainingSquadSize, GetVolunteerPool( ) );
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Militia1");
// get town index
@@ -310,6 +313,8 @@ void TownMilitiaTrainingCompleted( SOLDIERTYPE *pTrainer, INT16 sMapX, INT16 sMa
++ubMilitiaTrained;
}
AddVolunteers( -ubMilitiaTrained );
if (gfStrategicMilitiaChangesMade)
{
ResetMilitia();
@@ -2142,7 +2147,7 @@ UINT8 CalcNumMilitiaTrained(UINT8 ubBestLeadership, BOOLEAN fMobile)
ubMilitiaToTrain = __max(3, ubMilitiaToTrain);
}
}
return (ubMilitiaToTrain);
}
@@ -2428,4 +2433,66 @@ UINT32 CalcMilitiaUpkeep( void )
}
return (uiTotalPayment);
}
}
// Flugente: our militia volunteer pool is limited
INT32 GetVolunteerPool()
{
// if this feature is off, we simply assume we have reserves
if ( !gGameExternalOptions.fMilitiaVolunteerPool )
return 999999;
// the pool is actually a float number, only return full volunteers though
return (INT32)LaptopSaveInfo.dMilitiaVolunteerPool;
}
// add/remove volunteers from pool
void AddVolunteers( FLOAT asNum )
{
LaptopSaveInfo.dMilitiaVolunteerPool = max( 0, LaptopSaveInfo.dMilitiaVolunteerPool + asNum );
}
FLOAT CalcHourlyVolunteerGain()
{
FLOAT loyalpopulation = 0.0f; // the number of loyal citizens, from which we derive the hourly volunteer gain
FLOAT populationmodifier = 1.0f; // certain sectors/facilities under our control increase the volunteer gain
for ( UINT8 sX = 1; sX < MAP_WORLD_X - 1; ++sX )
{
for ( UINT8 sY = 1; sY < MAP_WORLD_X - 1; ++sY )
{
// not if the enemy controls this sector
if ( StrategicMap[CALCULATE_STRATEGIC_INDEX( sX, sY )].fEnemyControlled )
continue;
UINT8 sector = SECTOR( sX, sY );
SECTORINFO *pSectorInfo = &(SectorInfo[sector]);
if ( !pSectorInfo )
continue;
// TODO: modifier increase for every farm we control
if ( pSectorInfo->ubTraversability[THROUGH_STRATEGIC_MOVE] == FARMLAND || pSectorInfo->ubTraversability[THROUGH_STRATEGIC_MOVE] == FARMLAND_ROAD )
populationmodifier += gGameExternalOptions.dMilitiaVolunteerMultiplierFarm;
UINT8 ubTownID = StrategicMap[CALCULATE_STRATEGIC_INDEX( sX, sY )].bNameId;
if ( ubTownID != BLANK_SECTOR )
{
UINT16 population = GetSectorPopulation( sX, sY );
loyalpopulation += gTownLoyalty[ubTownID].ubRating * population / 100;
}
}
}
FLOAT hourlygain = loyalpopulation * populationmodifier * gGameExternalOptions.dMilitiaVolunteerGainFactorHourly;
return hourlygain;
}
// every hour, controlled sectors add to our volunteer pool
void UpdateVolunteers()
{
AddVolunteers( CalcHourlyVolunteerGain() );
}
+12
View File
@@ -112,4 +112,16 @@ typedef struct MILITIA_LIST_TYPE
// HEADROCK HAM 3.6: Calculate upkeep costs for militia
UINT32 CalcMilitiaUpkeep( void );
// Flugente: militia volunteer pool
// how many volunteers do we currently have?
INT32 GetVolunteerPool();
// add/remove volunteers from pool
void AddVolunteers( FLOAT asNum );
FLOAT CalcHourlyVolunteerGain();
// every hour, controlled sectors add to our volunteer pool
void UpdateVolunteers();
#endif