Added Headrock's HAM 2.8

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@2650 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Wanne
2009-04-01 12:20:30 +00:00
parent 5f9261273a
commit 335747c3ff
48 changed files with 3439 additions and 406 deletions
+419 -24
View File
@@ -105,10 +105,12 @@ enum {
REPAIR_BIG_POCKETS,
REPAIR_MED_POCKETS,
REPAIR_SML_POCKETS,
REPAIR_LBE_GEAR, // HEADROCK HAM B2.8: New pass type for fixing LBEs only
NUM_REPAIR_PASS_TYPES,
};
#define FINAL_REPAIR_PASS REPAIR_SML_POCKETS
// HEADROCK HAM B2.8: Changed LBEs to be the final pass
#define FINAL_REPAIR_PASS REPAIR_LBE_GEAR
/* CHRISL: bSlot[xx] array declaration needs to reflect largest number of inventory locations. New inventory
@@ -128,6 +130,7 @@ REPAIR_PASS_SLOTS_TYPE gRepairPassSlotList[ NUM_REPAIR_PASS_TYPES ] =
{ /* big pockets */ 4, 7, BIGPOCK1POS, BIGPOCK2POS, BIGPOCK3POS, BIGPOCK4POS, BIGPOCK5POS, BIGPOCK6POS, BIGPOCK7POS, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ /* med pockets */ 0, 4, MEDPOCK1POS, MEDPOCK2POS, MEDPOCK3POS, MEDPOCK4POS, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ /* sml pockets */ 8, 30, SMALLPOCK1POS, SMALLPOCK2POS, SMALLPOCK3POS, SMALLPOCK4POS, SMALLPOCK5POS, SMALLPOCK6POS, SMALLPOCK7POS, SMALLPOCK8POS, SMALLPOCK9POS, SMALLPOCK10POS, SMALLPOCK11POS, SMALLPOCK12POS, SMALLPOCK13POS, SMALLPOCK14POS, SMALLPOCK15POS, SMALLPOCK16POS, SMALLPOCK17POS, SMALLPOCK18POS, SMALLPOCK19POS, SMALLPOCK20POS, SMALLPOCK21POS, SMALLPOCK22POS, SMALLPOCK23POS, SMALLPOCK24POS, SMALLPOCK25POS, SMALLPOCK26POS, SMALLPOCK27POS, SMALLPOCK28POS, SMALLPOCK29POS, SMALLPOCK30POS },
{ /* HEADROCK HAM B2.8: LBE Slot pass */ 0, 5, VESTPOCKPOS, LTHIGHPOCKPOS, RTHIGHPOCKPOS, CPACKPOCKPOS, BPACKPOCKPOS, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
};
extern STR16 sRepairsDoneString[];
@@ -3298,18 +3301,42 @@ void HandleRepairBySoldier( SOLDIERTYPE *pSoldier )
fAnyOfSoldiersOwnItemsWereFixed = UnjamGunsOnSoldier( pSoldier, pSoldier, &ubRepairPtsLeft );
// repair items on self
for( bLoop = 0; bLoop < 2; bLoop++ )
// HEADROCK HAM B2.8: Experimental feature: Fixes LBEs last, as they don't actually require repairs.
for( bLoop = 0; bLoop < 4; bLoop++ )
{
if ( bLoop == 0 )
{
bLoopStart = SECONDHANDPOS;
// HEADROCK: New loop stage only checks second hand, to avoid LBEs.
bLoopEnd = SECONDHANDPOS;
}
else if ( bLoop == 1 )
{
// HEADROCK: Second check is for armor and headgear only.
bLoopStart = HELMETPOS;
bLoopEnd = HEAD2POS;
}
else if ( bLoop == 2 )
{
// HEADROCK: Loop stage altered to run through inventory only
bLoopStart = UsingNewInventorySystem() == false ? BIGPOCKSTART : GUNSLINGPOCKPOS;
// CHRISL: Changed to dynamically determine max inventory locations.
bLoopEnd = (NUM_INV_SLOTS - 1);
}
else
else if ( bLoop == 3 )
{
bLoopStart = HELMETPOS;
bLoopEnd = UsingNewInventorySystem() == false ? HEAD2POS : BPACKPOCKPOS;
if (UsingNewInventorySystem() == true)
{
// HEADROCK: Last loop fixes LBEs
bLoopStart = VESTPOCKPOS;
bLoopEnd = BPACKPOCKPOS;
}
else
{
// HEADROCK: In OIV, simply check everything again.
bLoopStart = SECONDHANDPOS;
bLoopEnd = (NUM_INV_SLOTS - 1);
}
}
// now repair objects running from left hand to small pocket
@@ -3317,10 +3344,12 @@ void HandleRepairBySoldier( SOLDIERTYPE *pSoldier )
{
//CHRISL: These two conditions allow us to repair LBE pocket items at the same time as worn armor, while
// still letting us repair the item in our offhand first.
if(UsingNewInventorySystem() == true && bLoop == 0 && bPocket>SECONDHANDPOS && bPocket<GUNSLINGPOCKPOS)
continue;
if(UsingNewInventorySystem() == true && bLoop == 1 && bPocket==SECONDHANDPOS)
continue;
// HEADROCK HAM B2.8: No longer necessary, as I've artificially added new stages for this. LBE
// pockets are now repaired LAST.
//if(UsingNewInventorySystem() == true && bLoop == 0 && bPocket>SECONDHANDPOS && bPocket<GUNSLINGPOCKPOS)
// continue;
//if(UsingNewInventorySystem() == true && bLoop == 1 && bPocket==SECONDHANDPOS)
// continue;
pObj = &(pSoldier->inv[ bPocket ]);
if ( RepairObject( pSoldier, pSoldier, pObj, &ubRepairPtsLeft ) )
@@ -3693,7 +3722,17 @@ void HandleTrainingInSector( INT16 sMapX, INT16 sMapY, INT8 bZ )
}
// now finally train the grunt
TrainSoldierWithPts( pStudent, sTotalTrainingPts );
// HEADROCK HAM B2.8: A new trainer/student synch system allows students to rest while
// their trainer is asleep. If this happens, the student should not train on their own!
if (gGameExternalOptions.ubSmartTrainingRest == 0 || gGameExternalOptions.ubSmartTrainingRest == 2)
{
TrainSoldierWithPts( pStudent, sTotalTrainingPts );
}
else if ( pTrainer != NULL )
{
// This only occurs if at least one trainer is awake.
TrainSoldierWithPts( pStudent, sTotalTrainingPts );
}
}
}
}
@@ -5587,13 +5626,17 @@ void MakeSureToolKitIsInHand( SOLDIERTYPE *pSoldier )
{
if( Item[pSoldier->inv[ bPocket ].usItem].toolkit )
{
// If the second hand is empty, swap item in first hand there
if (pSoldier->inv[HANDPOS].exists() &&
!pSoldier->inv[SECONDHANDPOS].exists() &&
CanItemFitInPosition(pSoldier, &pSoldier->inv[SECONDHANDPOS], HANDPOS, FALSE)) {
SwapObjs( pSoldier, HANDPOS, SECONDHANDPOS, TRUE );
}
if(!CanItemFitInPosition(pSoldier, &pSoldier->inv[HANDPOS], bPocket, FALSE))
// HEADROCK HAM B2.8: These new conditions will create a bias for swapping an item out of
// our hand.
//If the second hand is free, the item will go to the SECONDHANDPOS while the toolkit
// goes into the HANDPOS
if( Item[pSoldier->inv[HANDPOS].usItem].usItemClass & (IC_WEAPON | IC_PUNCH) && !pSoldier->inv[SECONDHANDPOS].exists())
SwapObjs(pSoldier, HANDPOS, SECONDHANDPOS, TRUE);
// Else, if the gun sling slot is free, and the item can go there, it will.
else if(UsingNewInventorySystem() && !pSoldier->inv[GUNSLINGPOCKPOS].exists() && CanItemFitInPosition(pSoldier, &pSoldier->inv[HANDPOS], GUNSLINGPOCKPOS, FALSE))
SwapObjs(pSoldier, HANDPOS, GUNSLINGPOCKPOS, TRUE);
else if(!CanItemFitInPosition(pSoldier, &pSoldier->inv[HANDPOS], bPocket, FALSE))
SwapObjs(pSoldier, HANDPOS, SECONDHANDPOS, TRUE);
SwapObjs( pSoldier, HANDPOS, bPocket, TRUE );
break;
@@ -5623,13 +5666,17 @@ BOOLEAN MakeSureMedKitIsInHand( SOLDIERTYPE *pSoldier )
if ( Item[pSoldier->inv[ bPocket ].usItem].medicalkit )
{
fCharacterInfoPanelDirty = TRUE;
// If the second hand is empty, swap item in first hand there
if (pSoldier->inv[HANDPOS].exists() &&
!pSoldier->inv[SECONDHANDPOS].exists() &&
CanItemFitInPosition(pSoldier, &pSoldier->inv[SECONDHANDPOS], HANDPOS, FALSE)) {
SwapObjs( pSoldier, HANDPOS, SECONDHANDPOS, TRUE );
}
if(!CanItemFitInPosition(pSoldier, &pSoldier->inv[HANDPOS], bPocket, FALSE))
// HEADROCK HAM B2.8: These new conditions will create a bias for swapping an item out of
// our hand.
//If the second hand is free, the item will go to the SECONDHANDPOS while the medikit
// goes into the HANDPOS
if( Item[pSoldier->inv[HANDPOS].usItem].usItemClass & (IC_WEAPON | IC_PUNCH) && !pSoldier->inv[SECONDHANDPOS].exists())
SwapObjs(pSoldier, HANDPOS, SECONDHANDPOS, TRUE);
// Else, if the gun sling slot is free, and the item can go there, it will.
else if(UsingNewInventorySystem() && !pSoldier->inv[GUNSLINGPOCKPOS].exists() && CanItemFitInPosition(pSoldier, &pSoldier->inv[HANDPOS], GUNSLINGPOCKPOS, FALSE))
SwapObjs(pSoldier, HANDPOS, GUNSLINGPOCKPOS, TRUE);
else if(!CanItemFitInPosition(pSoldier, &pSoldier->inv[HANDPOS], bPocket, FALSE))
SwapObjs(pSoldier, HANDPOS, SECONDHANDPOS, TRUE);
SwapObjs( pSoldier, HANDPOS, bPocket, TRUE );
return(TRUE);
@@ -11719,9 +11766,357 @@ BOOLEAN UnjamGunsOnSoldier( SOLDIERTYPE *pOwnerSoldier, SOLDIERTYPE *pRepairSold
return ( fAnyGunsWereUnjammed );
}
// HEADROCK HAM B2.8: A set of functions to synchronize sleeping periods of trainers and trainees
BOOLEAN SetTrainerSleepWhenTraineesSleep( SOLDIERTYPE *pThisTrainee)
{
UINT16 sMapX = pThisTrainee->sSectorX;
UINT16 sMapY = pThisTrainee->sSectorY;
UINT16 sMapZ = pThisTrainee->sZLevel;
UINT8 bStat = pThisTrainee->bTrainStat;
INT32 iCounter, iNumberOnTeam;
SOLDIERTYPE * pOtherTrainee;
SOLDIERTYPE * pTrainer;
BOOLEAN fAllTraineesAsleep = TRUE;
BOOLEAN fTrainersSentToSleep = FALSE;
if (pThisTrainee->bAssignment != TRAIN_BY_OTHER)
{
// Shouldn't happen...
return (FALSE);
}
iNumberOnTeam =gTacticalStatus.Team[ OUR_TEAM ].bLastID;
// Check to see if all other trainees of the same stat are also asleep
for( iCounter = 0; iCounter < iNumberOnTeam; iCounter++ )
{
pOtherTrainee = &Menptr[ iCounter ];
if (pOtherTrainee->bAssignment == TRAIN_BY_OTHER && pOtherTrainee->bTrainStat == pThisTrainee->bTrainStat &&
pOtherTrainee->sSectorX == sMapX && pOtherTrainee->sSectorY == sMapY && pOtherTrainee->sZLevel == sMapZ &&
pOtherTrainee->bActive && !pOtherTrainee->flags.fMercAsleep )
{
// Trainee is present and awake. Flag is reset to false.
fAllTraineesAsleep = FALSE;
}
}
// If they are all asleep
if (fAllTraineesAsleep)
{
// Look for trainers of that stat, in the same sector
for( iCounter = 0; iCounter < iNumberOnTeam; iCounter++ )
{
pTrainer = &Menptr[ iCounter ];
if (pTrainer->bAssignment == TRAIN_TEAMMATE && pTrainer->bTrainStat == pThisTrainee->bTrainStat &&
pTrainer->sSectorX == sMapX && pTrainer->sSectorY == sMapY && pTrainer->sZLevel == sMapZ &&
pTrainer->bActive && !pTrainer->flags.fMercAsleep )
{
// Trainer will go to sleep
if( SetMercAsleep( pTrainer, FALSE ) )
{
if( gGameSettings.fOptions[ TOPTION_SLEEPWAKE_NOTIFICATION ] )
{
// tell player about it
AddSoldierToWaitingListQueue( pTrainer );
}
// seems unnecessary now? ARM
pTrainer->bOldAssignment = pTrainer->bAssignment;
fTrainersSentToSleep = TRUE;
}
}
}
if (fTrainersSentToSleep)
{
return(TRUE);
}
else
{
return(FALSE);
}
}
else
{
return(FALSE);
}
}
BOOLEAN SetTraineesSleepWhenTrainerSleeps( SOLDIERTYPE *pTrainer)
{
UINT16 sMapX = pTrainer->sSectorX;
UINT16 sMapY = pTrainer->sSectorY;
UINT16 sMapZ = pTrainer->sZLevel;
UINT8 bStat = pTrainer->bTrainStat;
INT32 iCounter, iNumberOnTeam;
BOOLEAN fTraineesSentToSleep = FALSE;
SOLDIERTYPE * pTrainee;
if (pTrainer->bAssignment != TRAIN_TEAMMATE)
{
// Shouldn't happen...
return(FALSE);
}
iNumberOnTeam =gTacticalStatus.Team[ OUR_TEAM ].bLastID;
for( iCounter = 0; iCounter < iNumberOnTeam; iCounter++ )
{
pTrainee = &Menptr[ iCounter ];
if (pTrainee->bAssignment == TRAIN_BY_OTHER && pTrainee->bTrainStat == pTrainer->bTrainStat &&
pTrainee->sSectorX == sMapX && pTrainee->sSectorY == sMapY && pTrainee->sZLevel == sMapZ &&
pTrainee->bActive && !pTrainee->flags.fMercAsleep )
{
// Trainee will go to sleep
if( SetMercAsleep( pTrainee, FALSE ) )
{
if( gGameSettings.fOptions[ TOPTION_SLEEPWAKE_NOTIFICATION ] )
{
// tell player about it
AddSoldierToWaitingListQueue( pTrainee );
}
// seems unnecessary now? ARM
pTrainee->bOldAssignment = pTrainee->bAssignment;
fTraineesSentToSleep = TRUE;
}
}
}
if (fTraineesSentToSleep)
{
return(TRUE);
}
else
{
return(FALSE);
}
}
BOOLEAN SetTrainerWakeWhenTraineesWake( SOLDIERTYPE *pThisTrainee)
{
UINT16 sMapX = pThisTrainee->sSectorX;
UINT16 sMapY = pThisTrainee->sSectorY;
UINT16 sMapZ = pThisTrainee->sZLevel;
UINT8 bStat = pThisTrainee->bTrainStat;
INT32 iCounter, iNumberOnTeam;
SOLDIERTYPE * pOtherTrainee;
SOLDIERTYPE * pTrainer;
BOOLEAN fAllTraineesAwake = TRUE;
BOOLEAN fTrainersWokenUp = FALSE;
if (pThisTrainee->bAssignment != TRAIN_BY_OTHER)
{
// Shouldn't happen...
return (FALSE);
}
iNumberOnTeam =gTacticalStatus.Team[ OUR_TEAM ].bLastID;
// Check to see if all other trainees of the same stat are also asleep
for( iCounter = 0; iCounter < iNumberOnTeam; iCounter++ )
{
pOtherTrainee = &Menptr[ iCounter ];
if (pOtherTrainee->bAssignment == TRAIN_BY_OTHER && pOtherTrainee->bTrainStat == pThisTrainee->bTrainStat &&
pOtherTrainee->sSectorX == sMapX && pOtherTrainee->sSectorY == sMapY && pOtherTrainee->sZLevel == sMapZ &&
pOtherTrainee->bActive && pOtherTrainee->flags.fMercAsleep )
{
// Trainee is present and asleep. Flag is reset to FALSE.
fAllTraineesAwake = FALSE;
}
}
// If they are all awake
if (fAllTraineesAwake)
{
// Look for trainers of that stat, in the same sector
for( iCounter = 0; iCounter < iNumberOnTeam; iCounter++ )
{
pTrainer = &Menptr[ iCounter ];
if (pTrainer->bAssignment == TRAIN_TEAMMATE && pTrainer->bTrainStat == pThisTrainee->bTrainStat &&
pTrainer->sSectorX == sMapX && pTrainer->sSectorY == sMapY && pTrainer->sZLevel == sMapZ &&
pTrainer->bActive && pTrainer->flags.fMercAsleep )
{
// Trainer will wake up
if( SetMercAwake( pTrainer, FALSE, FALSE ) )
{
if( gGameSettings.fOptions[ TOPTION_SLEEPWAKE_NOTIFICATION ] )
{
// tell player about it
AddSoldierToWaitingListQueue( pTrainer );
}
// seems unnecessary now? ARM
pTrainer->bOldAssignment = pTrainer->bAssignment;
fTrainersWokenUp = TRUE;
}
}
}
if (fTrainersWokenUp)
{
return(TRUE);
}
else
{
return(FALSE);
}
}
else
{
return(FALSE);
}
}
BOOLEAN SetTraineesWakeWhenTrainerWakes( SOLDIERTYPE *pTrainer)
{
UINT16 sMapX = pTrainer->sSectorX;
UINT16 sMapY = pTrainer->sSectorY;
UINT16 sMapZ = pTrainer->sZLevel;
UINT8 bStat = pTrainer->bTrainStat;
INT32 iCounter, iNumberOnTeam;
BOOLEAN fTraineesWokenUp = FALSE;
SOLDIERTYPE * pTrainee;
if (pTrainer->bAssignment != TRAIN_TEAMMATE)
{
// Shouldn't happen...
return(FALSE);
}
iNumberOnTeam =gTacticalStatus.Team[ OUR_TEAM ].bLastID;
for( iCounter = 0; iCounter < iNumberOnTeam; iCounter++ )
{
pTrainee = &Menptr[ iCounter ];
if (pTrainee->bAssignment == TRAIN_BY_OTHER && pTrainee->bTrainStat == pTrainer->bTrainStat &&
pTrainee->sSectorX == sMapX && pTrainee->sSectorY == sMapY && pTrainee->sZLevel == sMapZ &&
pTrainee->bActive && pTrainee->flags.fMercAsleep )
{
// Trainee will wake up
if( SetMercAwake( pTrainee, FALSE, FALSE ) )
{
if( gGameSettings.fOptions[ TOPTION_SLEEPWAKE_NOTIFICATION ] )
{
// tell player about it
AddSoldierToWaitingListQueue( pTrainee );
}
// seems unnecessary now? ARM
pTrainee->bOldAssignment = pTrainee->bAssignment;
fTraineesWokenUp = TRUE;
}
}
}
if (fTraineesWokenUp)
{
return(TRUE);
}
else
{
return(FALSE);
}
}
void HandleTrainingSleepSynchronize( SOLDIERTYPE *pSoldier )
{
// HEADROCK HAM B2.8: Trainees will now go to sleep if the trainer goes to sleep.
if ((gGameExternalOptions.ubSmartTrainingSleep == 1 || gGameExternalOptions.ubSmartTrainingSleep == 2) && pSoldier->bAssignment == TRAIN_TEAMMATE)
{
SetTraineesSleepWhenTrainerSleeps( pSoldier );
}
// HEADROCK HAM B2.8: If this is a trainee, and all other trainees are already asleep, put all trainers to sleep as well.
if ( (gGameExternalOptions.ubSmartTrainingSleep == 1 || gGameExternalOptions.ubSmartTrainingSleep == 3 ) && pSoldier->bAssignment == TRAIN_BY_OTHER)
{
SetTrainerSleepWhenTraineesSleep( pSoldier );
}
}
void HandleTrainingWakeSynchronize( SOLDIERTYPE *pSoldier )
{
// HEADROCK HAM B2.8: Trainees will now go to sleep if the trainer goes to sleep.
if ((gGameExternalOptions.ubSmartTrainingWake == 1 || gGameExternalOptions.ubSmartTrainingWake == 2) && pSoldier->bAssignment == TRAIN_TEAMMATE)
{
SetTraineesWakeWhenTrainerWakes( pSoldier );
}
// HEADROCK HAM B2.8: If this is a trainee, and all other trainees are already asleep, put all trainers to sleep as well.
if ( (gGameExternalOptions.ubSmartTrainingWake == 1 || gGameExternalOptions.ubSmartTrainingWake == 3 ) && pSoldier->bAssignment == TRAIN_BY_OTHER)
{
SetTrainerWakeWhenTraineesWake( pSoldier );
}
}
BOOLEAN FindAnyAwakeTrainers( SOLDIERTYPE *pTrainee )
{
UINT16 sMapX = pTrainee->sSectorX;
UINT16 sMapY = pTrainee->sSectorY;
UINT16 sMapZ = pTrainee->sZLevel;
UINT8 bStat = pTrainee->bTrainStat;
INT32 iCounter, iNumberOnTeam;
BOOLEAN fAllTrainersAsleep = TRUE;
SOLDIERTYPE * pTrainer;
if (pTrainee->bAssignment != TRAIN_BY_OTHER)
{
// Shouldn't happen...
return(FALSE);
}
iNumberOnTeam =gTacticalStatus.Team[ OUR_TEAM ].bLastID;
for( iCounter = 0; iCounter < iNumberOnTeam; iCounter++ )
{
pTrainer = &Menptr[ iCounter ];
if (pTrainer->bAssignment == TRAIN_TEAMMATE && pTrainer->bTrainStat == pTrainee->bTrainStat &&
pTrainer->sSectorX == sMapX && pTrainer->sSectorY == sMapY && pTrainer->sZLevel == sMapZ &&
pTrainer->bActive && !pTrainer->flags.fMercAsleep )
{
fAllTrainersAsleep = FALSE;
}
}
return(fAllTrainersAsleep);
}
BOOLEAN FindAnyAwakeTrainees( SOLDIERTYPE *pTrainer )
{
UINT16 sMapX = pTrainer->sSectorX;
UINT16 sMapY = pTrainer->sSectorY;
UINT16 sMapZ = pTrainer->sZLevel;
UINT8 bStat = pTrainer->bTrainStat;
INT32 iCounter, iNumberOnTeam;
BOOLEAN fAllTraineesAsleep = TRUE;
SOLDIERTYPE * pTrainee;
if (pTrainer->bAssignment != TRAIN_TEAMMATE)
{
// Shouldn't happen...
return(FALSE);
}
iNumberOnTeam =gTacticalStatus.Team[ OUR_TEAM ].bLastID;
for( iCounter = 0; iCounter < iNumberOnTeam; iCounter++ )
{
pTrainee = &Menptr[ iCounter ];
if (pTrainee->bAssignment == TRAIN_BY_OTHER && pTrainee->bTrainStat == pTrainer->bTrainStat &&
pTrainee->sSectorX == sMapX && pTrainee->sSectorY == sMapY && pTrainee->sZLevel == sMapZ &&
pTrainee->bActive && !pTrainee->flags.fMercAsleep )
{
fAllTraineesAsleep = FALSE;
}
}
return(fAllTraineesAsleep);
}
+9
View File
@@ -324,6 +324,15 @@ void UnEscortEPC( SOLDIERTYPE *pSoldier );
SOLDIERTYPE *AnyDoctorWhoCanHealThisPatient( SOLDIERTYPE *pPatient, BOOLEAN fThisHour );
// HEADROCK HAM B2.8: A set of functions to synchronize sleeping periods of trainers and trainees
BOOLEAN SetTrainerSleepWhenTraineesSleep( SOLDIERTYPE *pTrainee);
BOOLEAN SetTraineesSleepWhenTrainerSleeps( SOLDIERTYPE *pTrainer );
BOOLEAN SetTrainerWakeWhenTraineesWake( SOLDIERTYPE *pTrainee );
BOOLEAN SetTraineesWakeWhenTrainerWakes( SOLDIERTYPE *pTrainer );
void HandleTrainingSleepSynchronize( SOLDIERTYPE *pSoldier );
void HandleTrainingWakeSynchronize( SOLDIERTYPE *pSoldier );
BOOLEAN FindAnyAwakeTrainers( SOLDIERTYPE *pTrainee );
BOOLEAN FindAnyAwakeTrainees( SOLDIERTYPE *pTrainer );
#endif
+2 -2
View File
@@ -4007,7 +4007,7 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget )
pAttacker->uiFlags |= CELL_FIREDATTARGET | CELL_DIRTY;
if( pAttacker->usAttack < 950 )
usAttack = (UINT16)(pAttacker->usAttack + PreRandom(2000 - pAttacker->usAttack ));
usAttack = (UINT16)(pAttacker->usAttack + PreRandom((INT16)(gGameExternalOptions.iAutoResolveLuckFactor*1000.0) - pAttacker->usAttack ));
else
usAttack = (UINT16)(950 + PreRandom( 50 ));
if( pTarget->uiFlags & CELL_RETREATING && !(pAttacker->uiFlags & CELL_FEMALECREATURE) )
@@ -4016,7 +4016,7 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget )
usAttack = usAttack * 7 / 10;
}
if( pTarget->usDefence < 950 )
usDefence = (UINT16)(pTarget->usDefence + PreRandom(2000 - pTarget->usDefence ));
usDefence = (UINT16)(pTarget->usDefence + PreRandom((INT16)(gGameExternalOptions.iAutoResolveLuckFactor*1000.0) - pTarget->usDefence ));
else
usDefence = (UINT16)(950 + PreRandom( 50 ));
if( pAttacker->uiFlags & CELL_FEMALECREATURE )
+760 -65
View File
@@ -66,6 +66,10 @@
INT32 iRestrictedSectorArraySize;
UINT32 gRestrictMilitia[256];
// HEADROCK HAM B1: Alternate array keeps track of dynamically unrestricted sectors
BOOLEAN gDynamicRestrictMilitia[ 256 ];
// HEADROCK HAM B1: Function that dynamically unrestricts sectors as we take over towns.
extern void AdjustRoamingRestrictions();
UINT8 gpAttackDirs[5][4]; // 0. Green Militia 1. Regular Militia 2. Elite Militia 3. Insertion code
UINT8 guiDirNumber = 0;
@@ -143,9 +147,41 @@ void GenerateMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY )
{
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( sMapX, sMapY ) ] );
StrategicAddMilitiaToSector( sTMapX, sTMapY, GREEN_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] / gGameExternalOptions.guiDivOfOriginalMilitia);
StrategicAddMilitiaToSector( sTMapX, sTMapY, REGULAR_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] / gGameExternalOptions.guiDivOfOriginalMilitia);
StrategicAddMilitiaToSector( sTMapX, sTMapY, ELITE_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] / gGameExternalOptions.guiDivOfOriginalMilitia);
//HEADROCK HAM B2.7: Track the number of militia at the source.
UINT16 bTotalMilitiaAtSource = pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] + pSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] + pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ];
UINT8 bTargetGreen, bTargetRegular, bTargetElite;
UINT8 bUpgradePoints;
if (gGameExternalOptions.fDiverseRoamingMilitiaGroups)
{
bTargetRegular = __max(1,bTotalMilitiaAtSource / (gGameExternalOptions.guiDivOfOriginalMilitia * 4));
bTargetElite = __max(1,bTotalMilitiaAtSource / (gGameExternalOptions.guiDivOfOriginalMilitia * 4));
bTargetGreen = (bTotalMilitiaAtSource / gGameExternalOptions.guiDivOfOriginalMilitia) - (bTargetRegular + bTargetElite);
pSectorInfo = &( SectorInfo[ SECTOR( sTMapX, sTMapY ) ] );
// Continue if we're dealing with a full group that isn't full of veterans
if ( CountMilitia(pSectorInfo) >= gGameExternalOptions.guiMaxMilitiaSquadSize && pSectorInfo->ubNumberOfCivsAtLevel[ELITE_MILITIA] < CountMilitia(pSectorInfo) )
{
bUpgradePoints = bTargetGreen + (bTargetRegular * 2);
bTargetElite += __min(bTargetRegular, pSectorInfo->ubNumberOfCivsAtLevel[REGULAR_MILITIA]);
bUpgradePoints -= (__min(bTargetRegular, pSectorInfo->ubNumberOfCivsAtLevel[REGULAR_MILITIA]))*2;
bTargetRegular = bUpgradePoints;
bTargetGreen = 0;
}
// HEADROCK HAM B2.7: Create 1/2 green, 1/4 regular, 1/4 elite.
StrategicAddMilitiaToSector( sTMapX, sTMapY, GREEN_MILITIA, bTargetGreen);
StrategicAddMilitiaToSector( sTMapX, sTMapY, REGULAR_MILITIA, bTargetRegular);
StrategicAddMilitiaToSector( sTMapX, sTMapY, ELITE_MILITIA, bTargetElite);
}
else
{
StrategicAddMilitiaToSector( sTMapX, sTMapY, GREEN_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] / gGameExternalOptions.guiDivOfOriginalMilitia);
StrategicAddMilitiaToSector( sTMapX, sTMapY, REGULAR_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] / gGameExternalOptions.guiDivOfOriginalMilitia);
StrategicAddMilitiaToSector( sTMapX, sTMapY, ELITE_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] / gGameExternalOptions.guiDivOfOriginalMilitia);
}
pSectorInfo = &( SectorInfo[ SECTOR( sTMapX, sTMapY ) ] );
@@ -178,13 +214,145 @@ void MoveMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY, BOOL
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( sMapX, sMapY ) ] );
SECTORINFO *pTSectorInfo = &( SectorInfo[ SECTOR( sTMapX, sTMapY ) ] );
StrategicAddMilitiaToSector( sTMapX, sTMapY, GREEN_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] );
StrategicAddMilitiaToSector( sTMapX, sTMapY, REGULAR_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] );
StrategicAddMilitiaToSector( sTMapX, sTMapY, ELITE_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] );
UINT8 bGreensSourceTeam = 0, bGreensDestTeam = 0;
UINT8 bRegularsSourceTeam = 0, bRegularsDestTeam = 0;
UINT8 bElitesSourceTeam = 0, bElitesDestTeam = 0;
UINT8 bTotalGreens = 0, bTotalRegulars = 0, bTotalElites = 0;
UINT8 bTotalGreensPercent = 0, bTotalRegularsPercent = 0, bTotalElitesPercent = 0;
INT8 bNewSourceGroupSize = 0, bNewDestGroupSize = 0, bGroupSizeRatio = 0;
StrategicRemoveMilitiaFromSector( sMapX, sMapY, GREEN_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] );
StrategicRemoveMilitiaFromSector( sMapX, sMapY, REGULAR_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] );
StrategicRemoveMilitiaFromSector( sMapX, sMapY, ELITE_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] );
// HEADROCK HAM B2.8
// There are now several methods of militia join-up.
if (PreRandom(100) < gGameExternalOptions.ubRoamingMilitiaSpreadsOutChance)
{
// Militia will attempt to spread out, averaging the size and composition of both groups.
if ( CountMilitia(pSectorInfo) && CountMilitia(pTSectorInfo) )
{
bGreensSourceTeam = pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ];
bGreensDestTeam = pTSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ];
bRegularsSourceTeam = pSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ];
bRegularsDestTeam = pTSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ];
bElitesSourceTeam = pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ];
bElitesDestTeam = pTSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ];
bTotalGreens = bGreensSourceTeam + bGreensDestTeam;
bTotalRegulars = bRegularsSourceTeam + bRegularsDestTeam;
bTotalElites = bElitesSourceTeam + bElitesDestTeam;
// Source team gets half of each group, rounded down
bGreensSourceTeam = bTotalGreens / 2;
bRegularsSourceTeam = bTotalRegulars / 2;
bElitesSourceTeam = bTotalElites / 2;
// Destination team gets half of each group, rounded up
bGreensDestTeam = bTotalGreens - bGreensSourceTeam;
bRegularsDestTeam = bTotalRegulars - bRegularsSourceTeam;
bElitesDestTeam = bTotalElites - bElitesSourceTeam;
// Erase ALL militia from both locations.
StrategicRemoveMilitiaFromSector( sMapX, sMapY, GREEN_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] );
StrategicRemoveMilitiaFromSector( sMapX, sMapY, REGULAR_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] );
StrategicRemoveMilitiaFromSector( sMapX, sMapY, ELITE_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] );
StrategicRemoveMilitiaFromSector( sTMapX, sTMapY, GREEN_MILITIA, pTSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] );
StrategicRemoveMilitiaFromSector( sTMapX, sTMapY, REGULAR_MILITIA, pTSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] );
StrategicRemoveMilitiaFromSector( sTMapX, sTMapY, ELITE_MILITIA, pTSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] );
// Add new militia.
StrategicAddMilitiaToSector( sMapX, sMapY, GREEN_MILITIA, bGreensSourceTeam );
StrategicAddMilitiaToSector( sMapX, sMapY, REGULAR_MILITIA, bRegularsSourceTeam );
StrategicAddMilitiaToSector( sMapX, sMapY, ELITE_MILITIA, bElitesSourceTeam );
StrategicAddMilitiaToSector( sTMapX, sTMapY, GREEN_MILITIA, bGreensDestTeam );
StrategicAddMilitiaToSector( sTMapX, sTMapY, REGULAR_MILITIA, bRegularsDestTeam );
StrategicAddMilitiaToSector( sTMapX, sTMapY, ELITE_MILITIA, bElitesDestTeam );
}
else
{
StrategicAddMilitiaToSector( sTMapX, sTMapY, GREEN_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] );
StrategicAddMilitiaToSector( sTMapX, sTMapY, REGULAR_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] );
StrategicAddMilitiaToSector( sTMapX, sTMapY, ELITE_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] );
StrategicRemoveMilitiaFromSector( sMapX, sMapY, GREEN_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] );
StrategicRemoveMilitiaFromSector( sMapX, sMapY, REGULAR_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] );
StrategicRemoveMilitiaFromSector( sMapX, sMapY, ELITE_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] );
}
}
else
{
if ( gGameExternalOptions.fDiverseRoamingMilitiaGroups )
{
// Diverse Militia Join-up: Destination team gets as many troops as possible, but both teams
// keep an averaged green-regular-elite ratio.
bNewDestGroupSize = __min((CountMilitia(pTSectorInfo) + CountMilitia(pSectorInfo)), (UINT8)gGameExternalOptions.guiMaxMilitiaSquadSize);
bNewSourceGroupSize = __max(0,(CountMilitia(pTSectorInfo) + CountMilitia(pSectorInfo)) - gGameExternalOptions.guiMaxMilitiaSquadSize);
// If there are still going to be two teams after the transfer
if ( bNewSourceGroupSize > 0 )
{
bGreensSourceTeam = pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ];
bGreensDestTeam = pTSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ];
bRegularsSourceTeam = pSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ];
bRegularsDestTeam = pTSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ];
bElitesSourceTeam = pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ];
bElitesDestTeam = pTSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ];
bTotalGreens = bGreensSourceTeam + bGreensDestTeam;
bTotalRegulars = bRegularsSourceTeam + bRegularsDestTeam;
bTotalElites = bElitesSourceTeam + bElitesDestTeam;
bGroupSizeRatio = __max(1,(bNewDestGroupSize / bNewSourceGroupSize));
// Destination team gets the majority of troops (based on the ratios),
// but will always leave at least 1 troop of each type (if available) for the source team
bGreensDestTeam = __min(__min(bTotalGreens, ((bTotalGreens * bGroupSizeRatio) / (bGroupSizeRatio + 1) +1) ), __max(0,bTotalGreens-1));
bRegularsDestTeam = __min(__min(bTotalRegulars, ((bTotalRegulars * bGroupSizeRatio) / (bGroupSizeRatio + 1) +1) ), __max(0,bTotalRegulars-1));
bElitesDestTeam = __min(__min(bTotalElites, ((bTotalElites * bGroupSizeRatio) / (bGroupSizeRatio + 1) +1) ), __max(0,bTotalElites-1));
// Source team gets the remainder (no less than one troop of each type, if available)
bGreensSourceTeam = bTotalGreens - bGreensDestTeam;
bRegularsSourceTeam = bTotalRegulars - bRegularsDestTeam;
bElitesSourceTeam = bTotalElites - bElitesDestTeam;
// Erase ALL militia from both locations.
StrategicRemoveMilitiaFromSector( sMapX, sMapY, GREEN_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] );
StrategicRemoveMilitiaFromSector( sMapX, sMapY, REGULAR_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] );
StrategicRemoveMilitiaFromSector( sMapX, sMapY, ELITE_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] );
StrategicRemoveMilitiaFromSector( sTMapX, sTMapY, GREEN_MILITIA, pTSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] );
StrategicRemoveMilitiaFromSector( sTMapX, sTMapY, REGULAR_MILITIA, pTSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] );
StrategicRemoveMilitiaFromSector( sTMapX, sTMapY, ELITE_MILITIA, pTSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] );
// Add new militia.
StrategicAddMilitiaToSector( sMapX, sMapY, GREEN_MILITIA, bGreensSourceTeam );
StrategicAddMilitiaToSector( sMapX, sMapY, REGULAR_MILITIA, bRegularsSourceTeam );
StrategicAddMilitiaToSector( sMapX, sMapY, ELITE_MILITIA, bElitesSourceTeam );
StrategicAddMilitiaToSector( sTMapX, sTMapY, GREEN_MILITIA, bGreensDestTeam );
StrategicAddMilitiaToSector( sTMapX, sTMapY, REGULAR_MILITIA, bRegularsDestTeam );
StrategicAddMilitiaToSector( sTMapX, sTMapY, ELITE_MILITIA, bElitesDestTeam );
}
else
{
// Move all militia from source to destination.
StrategicAddMilitiaToSector( sTMapX, sTMapY, GREEN_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] );
StrategicAddMilitiaToSector( sTMapX, sTMapY, REGULAR_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] );
StrategicAddMilitiaToSector( sTMapX, sTMapY, ELITE_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] );
StrategicRemoveMilitiaFromSector( sMapX, sMapY, GREEN_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] );
StrategicRemoveMilitiaFromSector( sMapX, sMapY, REGULAR_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] );
StrategicRemoveMilitiaFromSector( sMapX, sMapY, ELITE_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] );
}
}
else
{
// normal join-up. Destination group gets all the best militia. Source team gets the leftovers.
StrategicAddMilitiaToSector( sTMapX, sTMapY, GREEN_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] );
StrategicAddMilitiaToSector( sTMapX, sTMapY, REGULAR_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] );
StrategicAddMilitiaToSector( sTMapX, sTMapY, ELITE_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] );
StrategicRemoveMilitiaFromSector( sMapX, sMapY, GREEN_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] );
StrategicRemoveMilitiaFromSector( sMapX, sMapY, REGULAR_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] );
StrategicRemoveMilitiaFromSector( sMapX, sMapY, ELITE_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] );
}
}
while( !fAlternativeMax && CountMilitia(pTSectorInfo) > gGameExternalOptions.guiMaxMilitiaSquadSize ||
fAlternativeMax && CountMilitia(pTSectorInfo) > gGameExternalOptions.guiMaxMilitiaSquadSizeBattle )
@@ -362,12 +530,40 @@ UINT16 CountDirectionRating( INT16 sMapX, INT16 sMapY, UINT8 uiDir )
BOOLEAN CheckStandardConditionsForDirection( INT16 sSMapX, INT16 sSMapY, INT16 sMapX, INT16 sMapY, BOOLEAN fWithCities, BOOLEAN fForBattle, BOOLEAN fOnlyCitySectors )
{
UINT8 uiTravab = GetTraversability( SECTOR( sSMapX , sSMapY ) , SECTOR( sMapX, sMapY ) );
BOOLEAN fTargetCityAllowsRoaming;
if( uiTravab == GROUNDBARRIER || uiTravab == EDGEOFWORLD ) return FALSE;
if( !fForBattle && gfMSBattle && NumEnemiesInSector( sMapX, sMapY ) ) return FALSE;
return (GetTownIdForSector( sMapX, sMapY ) == BLANK_SECTOR || fWithCities) && !IsThisSectorASAMSector( sMapX, sMapY , 0 ) &&
// HEADROCK HAM B2.7 : This allows roaming militia to move into Minor City sectors, if liberated at least
// once before
if (GetTownIdForSector( sMapX, sMapY ) == BLANK_SECTOR)
{
fTargetCityAllowsRoaming = TRUE;
}
else
{
if (gGameExternalOptions.fAllowMilitiaMoveThroughMinorCities)
{
if ( SectorInfo[SECTOR( sMapX, sMapY )].fSurfaceWasEverPlayerControlled )
{
fTargetCityAllowsRoaming = ( !gfMilitiaAllowedInTown[GetTownIdForSector( sMapX, sMapY )] );
}
else
{
fTargetCityAllowsRoaming = FALSE;
}
}
else
{
fTargetCityAllowsRoaming = FALSE;
}
}
//return (GetTownIdForSector( sMapX, sMapY ) == BLANK_SECTOR || fWithCities) && !IsThisSectorASAMSector( sMapX, sMapY , 0 ) &&
// (GetTownIdForSector( sMapX, sMapY ) != BLANK_SECTOR || !fOnlyCitySectors);// &&
return (fTargetCityAllowsRoaming || fWithCities) && !IsThisSectorASAMSector( sMapX, sMapY , 0 ) &&
(GetTownIdForSector( sMapX, sMapY ) != BLANK_SECTOR || !fOnlyCitySectors);// &&
// ( !NumEnemiesInSector( sMapX, sMapY ) || GetEnemyGroupIdInSector(sMapX, sMapY ) || fForBattle ) &&
// ( fForBattle || CountAllMilitiaInSector( sMapX, sMapY ) < gGameExternalOptions.guiMaxMilitiaSquadSize || PlayerMercsInSector( sMapX, sMapY, 0 ) )
@@ -482,6 +678,7 @@ void UpdateMilitiaSquads(INT16 sMapX, INT16 sMapY )
UINT8 x;//,y;
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( sMapX, sMapY ) ] );
UINT8 uiMilitiaCount;
BOOLEAN fSourceCityAllowsRoaming;
// If we don't want roaming militia
@@ -521,9 +718,14 @@ void UpdateMilitiaSquads(INT16 sMapX, INT16 sMapY )
}
}
// HEADROCK HAM B2.7: If INI flag is set, allow militia to move out of Minor City sectors (Orta, Tixa, San Mona, etc).
if (gGameExternalOptions.fAllowMilitiaMoveThroughMinorCities)
fSourceCityAllowsRoaming = ( !gfMilitiaAllowedInTown[GetTownIdForSector( sMapX, sMapY )] );
else
fSourceCityAllowsRoaming = ( GetTownIdForSector( sMapX, sMapY ) == BLANK_SECTOR );
// moving squad, if it is not a SAM site
if( ( GetTownIdForSector( sMapX, sMapY ) == BLANK_SECTOR ) && (!IsThisSectorASAMSector( sMapX, sMapY, 0 )) )
if( ( fSourceCityAllowsRoaming ) && (!IsThisSectorASAMSector( sMapX, sMapY, 0 )) )
{
if( !PlayerMercsInSector_MSE( (UINT8)sMapX, (UINT8)sMapY, FALSE ) ) // and there's no player's mercs in the sector
{
@@ -559,13 +761,74 @@ void UpdateMilitiaSquads(INT16 sMapX, INT16 sMapY )
//Kaiden: if Restricted Sectors List option is turned on,
// militia can't move to any sectors in the list.
// Unless they are following a group of mercs.
///////////////////////////////////////////////////////////////////
// HEADROCK HAM B1: Restrict roamers by XML as normal, but also
// allow them to move through visited sectors.
// Also, there's an option now to use dynamic restriction. The
// AdjustRoamingRestrictions() function is used to dynamically
// define which sectors are restricted, based on city conquest.
///////////////////////////////////////////////////////////////////
if (gGameExternalOptions.gflimitedRoaming)
for (INT32 i=0;i<iRestrictedSectorArraySize; ++i)
{
// Is militia allowed to move through visited sectors?
if (gGameExternalOptions.bUnrestrictVisited)
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("RestrictedSectors, %d", gRestrictMilitia[i]));
if(pMoveDir[iRandomRes][0] == gRestrictMilitia[i])
return;
// Scan each sector restricted in the XML.
for (INT32 i=0;i<iRestrictedSectorArraySize; ++i)
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("RestrictedSectors, %d", gRestrictMilitia[i]));
// If sector isn't explored yet
if ( SectorInfo[ pMoveDir[iRandomRes][0] ].fSurfaceWasEverPlayerControlled == 0 )
{
// Is militia allowed to move through dynamically defined sectors?
if (gGameExternalOptions.bDynamicRestrictRoaming)
{
// Is destination allowed by Dynamic Array?
if( !gDynamicRestrictMilitia[pMoveDir[iRandomRes][0]] )
{
return;
}
}
// Militia limited to XMLized sectors
else
{
// Is destination allowed by XML?
if(pMoveDir[iRandomRes][0] == gRestrictMilitia[i] )
{
return;
}
}
}
}
}
// Militia must adhere to restrictions, regardless of visited sectors
else
{
for (INT32 i=0;i<iRestrictedSectorArraySize; ++i)
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("RestrictedSectors, %d", gRestrictMilitia[i]));
// Is militia allowed to move through dynamically defined sectors?
if (gGameExternalOptions.bDynamicRestrictRoaming)
{
// Is destination allowed by Dynamic Array?
if( !gDynamicRestrictMilitia[pMoveDir[iRandomRes][0]] )
{
return;
}
}
// Militia limited to XMLized sectors
else
{
// Is destination allowed by XML?
if(pMoveDir[iRandomRes][0] == gRestrictMilitia[i] )
{
return;
}
}
}
}
}
// WDS bug fix for moving militia
int targetX = SECTORX( pMoveDir[ iRandomRes ][0] );
@@ -622,6 +885,11 @@ void CreateMilitiaSquads(INT16 sMapX, INT16 sMapY )
UINT8 x;//,y;
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( sMapX, sMapY ) ] );
UINT8 uiMilitiaCount;
// HEADROCK HAM B2.7: New values:
UINT16 iCounter;
BOOLEAN fFoundValidSector;
UINT16 bTownId;
INT16 sCurrentX, sCurrentY;
// If we're not allowing roaming groups,
@@ -649,68 +917,139 @@ void CreateMilitiaSquads(INT16 sMapX, INT16 sMapY )
// Create new Militia Squad
if( GetTownIdForSector( sMapX, sMapY ) != BLANK_SECTOR )
bTownId = GetTownIdForSector( sMapX, sMapY );
if( bTownId != BLANK_SECTOR )
{
fFoundValidSector = FALSE;
// Check all sectors adjacent to the training sector itself.
GenerateDirectionInfosWithCapacityCheck( sMapX, sMapY, &uiDirNumber, pMoveDir, FALSE, FALSE, FALSE );
if(uiDirNumber)// && Random(100) < CHANCE_TO_GENERATE_A_SQUAD)
{
GenerateDirectionInfos( sMapX, sMapY, &uiDirNumber, pMoveDir, FALSE, FALSE, FALSE );
for( x = 1; x < uiDirNumber ; ++x )pMoveDir[x][1] += pMoveDir[x-1][1];
if(uiDirNumber)// && Random(100) < CHANCE_TO_GENERATE_A_SQUAD)
{
for( x = 1; x < uiDirNumber ; ++x )pMoveDir[x][1] += pMoveDir[x-1][1];
iRandomRes = Random( pMoveDir[ uiDirNumber - 1 ][1] );
iRandomRes = Random( pMoveDir[ uiDirNumber - 1 ][1] );
for( x = 0; x < uiDirNumber; ++x)
if( iRandomRes < pMoveDir[x][1] )
{
iRandomRes = x;
break;
}
// shouldn't be!
if(iRandomRes >= uiDirNumber)iRandomRes = 0;
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%ld,%ld:Dir count %ld, Rand %ld. Go to %ld,%ld", sMapX, sMapY, uiDirNumber, iRandomRes, SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0] ));
GenerateMilitiaSquad( sMapX, sMapY, SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0] ) );
AddToBlockMoveList( SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0] ) );
if( NumEnemiesInSector( SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0] ) ) && CountAllMilitiaInSector( SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0] ) ) )
for( x = 0; x < uiDirNumber; ++x)
if( iRandomRes < pMoveDir[x][1] )
{
/* GROUP* pEnemyGroup = GetGroup( GetEnemyGroupIdInSector( SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0] ) ) );
if(pEnemyGroup && pEnemyGroup->ubGroupID)
{
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Attacking from %ld,%ld to %ld,%ld - enemy's group id %ld", sMapX, sMapY, SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0], pEnemyGroup->ubGroupID ));
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Arrival 1, Arrival 2");
pEnemyGroup->ubPrevX = sMapX;
pEnemyGroup->ubPrevY = sMapY;
pEnemyGroup->ubNextX = SECTORX( pMoveDir[ iRandomRes ][0] );
pEnemyGroup->ubNextY = SECTORY( pMoveDir[ iRandomRes ][0] );
*/
gfMSBattle = TRUE;
// GroupArrivedAtSector( pEnemyGroup->ubGroupID , TRUE, FALSE );
EnterAutoResolveMode( SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0] ) );
// }
iRandomRes = x;
break;
}
// shouldn't be!
if(iRandomRes >= uiDirNumber)iRandomRes = 0;
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%ld,%ld:Dir count %ld, Rand %ld. Go to %ld,%ld", sMapX, sMapY, uiDirNumber, iRandomRes, SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0] ));
GenerateMilitiaSquad( sMapX, sMapY, SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0] ) );
fFoundValidSector = TRUE;
AddToBlockMoveList( SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0] ) );
if( NumEnemiesInSector( SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0] ) ) && CountAllMilitiaInSector( SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0] ) ) )
{
/* GROUP* pEnemyGroup = GetGroup( GetEnemyGroupIdInSector( SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0] ) ) );
if(pEnemyGroup && pEnemyGroup->ubGroupID)
{
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Attacking from %ld,%ld to %ld,%ld - enemy's group id %ld", sMapX, sMapY, SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0], pEnemyGroup->ubGroupID ));
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Arrival 1, Arrival 2");
pEnemyGroup->ubPrevX = sMapX;
pEnemyGroup->ubPrevY = sMapY;
pEnemyGroup->ubNextX = SECTORX( pMoveDir[ iRandomRes ][0] );
pEnemyGroup->ubNextY = SECTORY( pMoveDir[ iRandomRes ][0] );
*/
gfMSBattle = TRUE;
// GroupArrivedAtSector( pEnemyGroup->ubGroupID , TRUE, FALSE );
EnterAutoResolveMode( SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0] ) );
// }
}
else return;
}
// HEADROCK HAM B2.7: Smarter check - looks at each city sector, and checks if there's room around that
// sector to place militia. Also relies on whether the sector has full militia before generating more.
// This section only runs if the program has failed to find suitable sectors around the "home" sector
// (where militia is being trained).
iCounter = 0;
if (gGameExternalOptions.fSmartRoamingMilitiaGenerator)
{
while( pTownNamesList[ iCounter ] != 0 && fFoundValidSector == FALSE )
{
if( pTownNamesList[ iCounter] == bTownId )
{
sCurrentX = GET_X_FROM_STRATEGIC_INDEX( pTownLocationsList[ iCounter ] );
sCurrentY = GET_Y_FROM_STRATEGIC_INDEX( pTownLocationsList[ iCounter ] );
// if sector has enemies or hasn't already been taken at least once, then
if ( !SectorInfo[ SECTOR(sCurrentX, sCurrentY) ].fSurfaceWasEverPlayerControlled || NumEnemiesInSector( sCurrentX, sCurrentY ) > 0 )
{
// skip the rest. Generate no militia from this sector.
iCounter++;
continue;
}
GenerateDirectionInfosWithCapacityCheck( sCurrentX, sCurrentY, &uiDirNumber, pMoveDir, FALSE, TRUE, FALSE );
if(uiDirNumber)// && Random(100) < CHANCE_TO_GENERATE_A_SQUAD)
{
for( x = 1; x < uiDirNumber ; ++x )pMoveDir[x][1] += pMoveDir[x-1][1];
iRandomRes = Random( pMoveDir[ uiDirNumber - 1 ][1] );
for( x = 0; x < uiDirNumber; ++x)
if( iRandomRes < pMoveDir[x][1] )
{
iRandomRes = x;
break;
}
// shouldn't be!
if(iRandomRes >= uiDirNumber)iRandomRes = 0;
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%ld,%ld:Dir count %ld, Rand %ld. Go to %ld,%ld", sMapX, sMapY, uiDirNumber, iRandomRes, SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0] ));
GenerateMilitiaSquad( sCurrentX, sCurrentY, SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0] ) );
fFoundValidSector = TRUE;
AddToBlockMoveList( SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0] ) );
if( NumEnemiesInSector( SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0] ) ) && CountAllMilitiaInSector( SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0] ) ) )
{
/* GROUP* pEnemyGroup = GetGroup( GetEnemyGroupIdInSector( SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0] ) ) );
if(pEnemyGroup && pEnemyGroup->ubGroupID)
{
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Attacking from %ld,%ld to %ld,%ld - enemy's group id %ld", sMapX, sMapY, SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0], pEnemyGroup->ubGroupID ));
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Arrival 1, Arrival 2");
pEnemyGroup->ubPrevX = sMapX;
pEnemyGroup->ubPrevY = sMapY;
pEnemyGroup->ubNextX = SECTORX( pMoveDir[ iRandomRes ][0] );
pEnemyGroup->ubNextY = SECTORY( pMoveDir[ iRandomRes ][0] );
*/
gfMSBattle = TRUE;
// GroupArrivedAtSector( pEnemyGroup->ubGroupID , TRUE, FALSE );
EnterAutoResolveMode( SECTORX( pMoveDir[ iRandomRes ][0] ), SECTORY( pMoveDir[ iRandomRes ][0] ) );
// }
}
}
}
iCounter++;
}
}
}
return;
}
extern BOOLEAN gfMSResetMilitia;
void DoMilitiaHelpFromAdjacentSectors( INT16 sMapX, INT16 sMapY )
@@ -837,3 +1176,359 @@ void MilitiaFollowPlayer( INT16 sMapX, INT16 sMapY, INT16 sDMapX, INT16 sDMapY )
MoveMilitiaSquad( sMapX, sMapY, sDMapX, sDMapY, FALSE );
}
// HEADROCK (HAM): New function to alter Restricted Roaming based on the recent capture of new towns. The area
// around the town will be unrestricted, as well as some road sectors leading away from the town.
// This function runs during sector conquest checks, and only if an entire town has been conquered. It also
// runs at day end, as well as on load/save.
void AdjustRoamingRestrictions()
{
if (!gGameExternalOptions.bDynamicRestrictRoaming)
return;
// to do: Add something to clean up the entire array before setting the flags...
if ( IsTownUnderCompleteControlByPlayer(DRASSEN) )
{
// DRASSEN OUTSKIRTS
gDynamicRestrictMilitia[SECTOR(12,1)] = true;
gDynamicRestrictMilitia[SECTOR(13,1)] = true;
gDynamicRestrictMilitia[SECTOR(14,1)] = true;
gDynamicRestrictMilitia[SECTOR(12,2)] = true;
gDynamicRestrictMilitia[SECTOR(14,2)] = true;
gDynamicRestrictMilitia[SECTOR(12,3)] = true;
gDynamicRestrictMilitia[SECTOR(14,3)] = true;
gDynamicRestrictMilitia[SECTOR(12,4)] = true;
gDynamicRestrictMilitia[SECTOR(14,4)] = true;
gDynamicRestrictMilitia[SECTOR(12,5)] = true;
gDynamicRestrictMilitia[SECTOR(13,5)] = true;
gDynamicRestrictMilitia[SECTOR(14,5)] = true;
// SAM SITE DEFENSE
gDynamicRestrictMilitia[SECTOR(15,5)] = true;
// ROAD WEST TO OMERTA
gDynamicRestrictMilitia[SECTOR(9,2)] = true;
gDynamicRestrictMilitia[SECTOR(10,2)] = true;
gDynamicRestrictMilitia[SECTOR(11,2)] = true;
// ROAD SOUTH TO ALMA
gDynamicRestrictMilitia[SECTOR(12,6)] = true;
}
if ( IsTownUnderCompleteControlByPlayer(ALMA) )
{
// ALMA OUTSKIRTS
gDynamicRestrictMilitia[SECTOR(12,7)] = true;
gDynamicRestrictMilitia[SECTOR(13,7)] = true;
gDynamicRestrictMilitia[SECTOR(14,7)] = true;
gDynamicRestrictMilitia[SECTOR(15,7)] = true;
gDynamicRestrictMilitia[SECTOR(12,8)] = true;
gDynamicRestrictMilitia[SECTOR(15,8)] = true;
gDynamicRestrictMilitia[SECTOR(12,9)] = true;
gDynamicRestrictMilitia[SECTOR(15,9)] = true;
gDynamicRestrictMilitia[SECTOR(12,10)] = true;
gDynamicRestrictMilitia[SECTOR(13,10)] = true;
gDynamicRestrictMilitia[SECTOR(14,10)] = true;
gDynamicRestrictMilitia[SECTOR(15,10)] = true;
// ROAD SOUTH
gDynamicRestrictMilitia[SECTOR(14,11)] = true;
}
if ( IsTownUnderCompleteControlByPlayer(CHITZENA) )
{
// CHITZENA OUTSKIRTS
gDynamicRestrictMilitia[SECTOR(1,1)] = true;
gDynamicRestrictMilitia[SECTOR(3,1)] = true;
gDynamicRestrictMilitia[SECTOR(1,2)] = true;
gDynamicRestrictMilitia[SECTOR(3,2)] = true;
gDynamicRestrictMilitia[SECTOR(1,3)] = true;
gDynamicRestrictMilitia[SECTOR(2,3)] = true;
gDynamicRestrictMilitia[SECTOR(3,3)] = true;
// SAM SITE DEFENSE / ROAD SOUTH
gDynamicRestrictMilitia[SECTOR(3,4)] = true;
gDynamicRestrictMilitia[SECTOR(3,5)] = true;
}
if ( IsTownUnderCompleteControlByPlayer(CAMBRIA) )
{
// CAMBRIA OUTSKIRTS
gDynamicRestrictMilitia[SECTOR(7,5)] = true;
gDynamicRestrictMilitia[SECTOR(8,5)] = true;
gDynamicRestrictMilitia[SECTOR(9,5)] = true;
gDynamicRestrictMilitia[SECTOR(10,5)] = true;
gDynamicRestrictMilitia[SECTOR(7,6)] = true;
gDynamicRestrictMilitia[SECTOR(10,6)] = true;
gDynamicRestrictMilitia[SECTOR(7,7)] = true;
gDynamicRestrictMilitia[SECTOR(10,7)] = true;
gDynamicRestrictMilitia[SECTOR(7,8)] = true;
gDynamicRestrictMilitia[SECTOR(9,8)] = true;
gDynamicRestrictMilitia[SECTOR(10,8)] = true;
// SAM SITE DEFENSE
gDynamicRestrictMilitia[SECTOR(7,9)] = true;
gDynamicRestrictMilitia[SECTOR(9,9)] = true;
// ROAD TO OMERTA
gDynamicRestrictMilitia[SECTOR(9,2)] = true;
gDynamicRestrictMilitia[SECTOR(9,3)] = true;
gDynamicRestrictMilitia[SECTOR(9,4)] = true;
// CROSSROADS WEST
gDynamicRestrictMilitia[SECTOR(6,7)] = true;
// ROAD TO ALMA
gDynamicRestrictMilitia[SECTOR(11,7)] = true;
}
if ( IsTownUnderCompleteControlByPlayer(BALIME) )
{
// BALIME OUTSKIRTS
gDynamicRestrictMilitia[SECTOR(10,11)] = true;
gDynamicRestrictMilitia[SECTOR(11,11)] = true;
gDynamicRestrictMilitia[SECTOR(12,11)] = true;
gDynamicRestrictMilitia[SECTOR(13,11)] = true;
gDynamicRestrictMilitia[SECTOR(10,12)] = true;
gDynamicRestrictMilitia[SECTOR(13,12)] = true;
gDynamicRestrictMilitia[SECTOR(10,13)] = true;
gDynamicRestrictMilitia[SECTOR(13,13)] = true;
// WEST ROAD
gDynamicRestrictMilitia[SECTOR(6,11)] = true;
gDynamicRestrictMilitia[SECTOR(7,11)] = true;
gDynamicRestrictMilitia[SECTOR(8,11)] = true;
gDynamicRestrictMilitia[SECTOR(9,11)] = true;
// SOUTH ROAD
gDynamicRestrictMilitia[SECTOR(8,14)] = true;
gDynamicRestrictMilitia[SECTOR(9,14)] = true;
gDynamicRestrictMilitia[SECTOR(10,14)] = true;
}
if ( IsTownUnderCompleteControlByPlayer(GRUMM) )
{
// GRUMM OUTSKIRTS
gDynamicRestrictMilitia[SECTOR(1,6)] = true;
gDynamicRestrictMilitia[SECTOR(2,6)] = true;
gDynamicRestrictMilitia[SECTOR(3,6)] = true;
gDynamicRestrictMilitia[SECTOR(3,7)] = true;
gDynamicRestrictMilitia[SECTOR(4,7)] = true;
gDynamicRestrictMilitia[SECTOR(4,8)] = true;
gDynamicRestrictMilitia[SECTOR(3,9)] = true;
gDynamicRestrictMilitia[SECTOR(4,9)] = true;
// ROAD NORTH
gDynamicRestrictMilitia[SECTOR(3,5)] = true;
gDynamicRestrictMilitia[SECTOR(3,4)] = true;
// ROAD EAST
gDynamicRestrictMilitia[SECTOR(5,7)] = true;
gDynamicRestrictMilitia[SECTOR(6,7)] = true;
// ROAD SOUTH
gDynamicRestrictMilitia[SECTOR(2,10)] = true;
gDynamicRestrictMilitia[SECTOR(3,10)] = true;
gDynamicRestrictMilitia[SECTOR(2,11)] = true;
}
if ( IsTownUnderCompleteControlByPlayer(DRASSEN) && IsTownUnderCompleteControlByPlayer(CHITZENA) )
{
// ROAD EAST OF SAN-MONA
gDynamicRestrictMilitia[SECTOR(7,3)] = true;
gDynamicRestrictMilitia[SECTOR(8,3)] = true;
gDynamicRestrictMilitia[SECTOR(9,3)] = true;
// SAN MONA
gDynamicRestrictMilitia[SECTOR(5,3)] = true;
gDynamicRestrictMilitia[SECTOR(6,3)] = true;
gDynamicRestrictMilitia[SECTOR(4,4)] = true;
gDynamicRestrictMilitia[SECTOR(5,4)] = true;
}
if ( IsTownUnderCompleteControlByPlayer(CAMBRIA) && ( IsTownUnderCompleteControlByPlayer(CHITZENA) || IsTownUnderCompleteControlByPlayer(DRASSEN) ) )
{
// ROAD TO SAN MONA
gDynamicRestrictMilitia[SECTOR(7,3)] = true;
gDynamicRestrictMilitia[SECTOR(8,3)] = true;
gDynamicRestrictMilitia[SECTOR(9,3)] = true;
}
if ( IsTownUnderCompleteControlByPlayer(CAMBRIA) && ( IsTownUnderCompleteControlByPlayer(DRASSEN) || IsTownUnderCompleteControlByPlayer(CHITZENA) || IsTownUnderCompleteControlByPlayer(GRUMM) ) )
{
// ROAD SOUTH-EAST OF SAN MONA
gDynamicRestrictMilitia[SECTOR(6,4)] = true;
gDynamicRestrictMilitia[SECTOR(7,4)] = true;
// SAN MONA
gDynamicRestrictMilitia[SECTOR(5,3)] = true;
gDynamicRestrictMilitia[SECTOR(6,3)] = true;
gDynamicRestrictMilitia[SECTOR(4,4)] = true;
gDynamicRestrictMilitia[SECTOR(5,4)] = true;
}
if ( IsTownUnderCompleteControlByPlayer(ALMA) && ( IsTownUnderCompleteControlByPlayer(DRASSEN) || IsTownUnderCompleteControlByPlayer(CAMBRIA) ) )
{
// ROAD WEST OF ALMA
gDynamicRestrictMilitia[SECTOR(11,7)] = true;
}
if ( IsTownUnderCompleteControlByPlayer(CHITZENA) && ( IsTownUnderCompleteControlByPlayer(DRASSEN) || IsTownUnderCompleteControlByPlayer(CAMBRIA) || IsTownUnderCompleteControlByPlayer(GRUMM) ) )
{
// SAN MONA
gDynamicRestrictMilitia[SECTOR(5,3)] = true;
gDynamicRestrictMilitia[SECTOR(6,3)] = true;
gDynamicRestrictMilitia[SECTOR(4,4)] = true;
gDynamicRestrictMilitia[SECTOR(5,4)] = true;
// ROAD TO SAN MONA
gDynamicRestrictMilitia[SECTOR(7,3)] = true;
gDynamicRestrictMilitia[SECTOR(8,3)] = true;
gDynamicRestrictMilitia[SECTOR(9,3)] = true;
}
if ( IsTownUnderCompleteControlByPlayer(CAMBRIA) && IsTownUnderCompleteControlByPlayer(ALMA) )
{
// ROAD EAST OF CAMBRIA
gDynamicRestrictMilitia[SECTOR(11,7)] = true;
}
if ( IsTownUnderCompleteControlByPlayer(CAMBRIA) && ( IsTownUnderCompleteControlByPlayer(BALIME) || IsTownUnderCompleteControlByPlayer(GRUMM) || IsTownUnderCompleteControlByPlayer(ALMA) ) )
{
// UPGRADED SAM-SITE DEFENSE FOR CAMBRIA
gDynamicRestrictMilitia[SECTOR(7,10)] = true;
gDynamicRestrictMilitia[SECTOR(8,10)] = true;
gDynamicRestrictMilitia[SECTOR(9,10)] = true; // Tixa. Won't be accessible unless Minor Cities are allowed.
}
if ( IsTownUnderCompleteControlByPlayer(CAMBRIA) && IsTownUnderCompleteControlByPlayer(GRUMM) )
{
// ESTONI
gDynamicRestrictMilitia[SECTOR(6,8)] = true;
// ESTONI MOUNTAIN GATE
gDynamicRestrictMilitia[SECTOR(6,9)] = true;
// SOUTHEAST ROAD TO SAN MONA
gDynamicRestrictMilitia[SECTOR(6,4)] = true;
gDynamicRestrictMilitia[SECTOR(7,4)] = true;
}
if ( IsTownUnderCompleteControlByPlayer(BALIME) && IsTownUnderCompleteControlByPlayer(GRUMM) && IsTownUnderCompleteControlByPlayer(CAMBRIA) )
{
// GRUMM-CAMBRIA-BALIME ROAD
gDynamicRestrictMilitia[SECTOR(6,10)] = true;
}
// CONTROL ALL TOWNS?
if ( IsTownUnderCompleteControlByPlayer(BALIME) && IsTownUnderCompleteControlByPlayer(CAMBRIA) && IsTownUnderCompleteControlByPlayer(CHITZENA) && IsTownUnderCompleteControlByPlayer(DRASSEN) && IsTownUnderCompleteControlByPlayer(ALMA) && IsTownUnderCompleteControlByPlayer(GRUMM) )
{
// ROADS TO MEDUNA
gDynamicRestrictMilitia[SECTOR(6,12)] = true;
gDynamicRestrictMilitia[SECTOR(7,14)] = true;
gDynamicRestrictMilitia[SECTOR(2,12)] = true;
// MEDUNA OUTSKIRTS
gDynamicRestrictMilitia[SECTOR(2,13)] = true;
gDynamicRestrictMilitia[SECTOR(3,13)] = true;
gDynamicRestrictMilitia[SECTOR(4,13)] = true;
gDynamicRestrictMilitia[SECTOR(5,13)] = true;
gDynamicRestrictMilitia[SECTOR(6,13)] = true;
gDynamicRestrictMilitia[SECTOR(6,14)] = true;
}
}
// HEADROCK HAM B2.7: This is a copy of an existing function that generates possible movement directions for militia.
// Due to the widespread use of that function, I've decided to make a new one that calculates directions
// when generating militia. This function checks for available space at the target location. It won't count green
// or regular militia in this total, as they will be replaced by higher grade militia when added.
void GenerateDirectionInfosWithCapacityCheck( INT16 sMapX, INT16 sMapY, UINT8* uiDirNumber, UINT16 pMoveDir[4][3], BOOLEAN fWithCities, BOOLEAN fForBattle, BOOLEAN fOnlyCitySectors )
{
SECTORINFO *pSectorInfo;
*uiDirNumber = 0;
#ifdef DEBUG_SHOW_RATINGS
if( DEBUG_RATINGS_CONDITION )ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%ld,%ld-------------------", sMapX, sMapY );
#endif
pSectorInfo = &( SectorInfo[ SECTOR( sMapX, sMapY - 1 ) ] );
if(CheckStandardConditionsForDirection( sMapX, sMapY, sMapX, sMapY - 1, fWithCities, fForBattle, fOnlyCitySectors ) &&
pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] < gGameExternalOptions.iMaxMilitiaPerSector )
{
pMoveDir[ *uiDirNumber ][0] = SECTOR( sMapX, sMapY - 1 );
if( fForBattle )
pMoveDir[ *uiDirNumber ][1] = 0;
else
pMoveDir[ *uiDirNumber ][1] = CountDirectionRating( sMapX, sMapY, DIR_NORTH );
pMoveDir[ *uiDirNumber ][2] = INSERTION_CODE_NORTH;
#ifdef DEBUG_SHOW_RATINGS
if( DEBUG_RATINGS_CONDITION )ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Priority of north direction - %ld", pMoveDir[ *uiDirNumber ][1]);
#endif
++(*uiDirNumber);
}
pSectorInfo = &( SectorInfo[ SECTOR( sMapX - 1, sMapY ) ] );
if(CheckStandardConditionsForDirection( sMapX, sMapY, sMapX - 1, sMapY, fWithCities, fForBattle, fOnlyCitySectors ) &&
pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] < gGameExternalOptions.iMaxMilitiaPerSector)
{
pMoveDir[ *uiDirNumber ][0] = SECTOR( sMapX - 1, sMapY );
if( fForBattle )
pMoveDir[ *uiDirNumber ][1] = 0;
else
pMoveDir[ *uiDirNumber ][1] = CountDirectionRating( sMapX, sMapY, DIR_WEST );
pMoveDir[ *uiDirNumber ][2] = INSERTION_CODE_WEST;
#ifdef DEBUG_SHOW_RATINGS
if( DEBUG_RATINGS_CONDITION )ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Priority of west direction - %ld", pMoveDir[ *uiDirNumber ][1]);
#endif
++(*uiDirNumber);
}
pSectorInfo = &( SectorInfo[ SECTOR( sMapX , sMapY + 1 ) ] );
if(CheckStandardConditionsForDirection( sMapX, sMapY, sMapX, sMapY + 1, fWithCities, fForBattle, fOnlyCitySectors ) &&
pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] < gGameExternalOptions.iMaxMilitiaPerSector )
{
pMoveDir[ *uiDirNumber ][0] = SECTOR( sMapX, sMapY + 1 );
if( fForBattle )
pMoveDir[ *uiDirNumber ][1] = 0;
else
pMoveDir[ *uiDirNumber ][1] = CountDirectionRating( sMapX, sMapY, DIR_SOUTH );
pMoveDir[ *uiDirNumber ][2] = INSERTION_CODE_SOUTH;
#ifdef DEBUG_SHOW_RATINGS
if( DEBUG_RATINGS_CONDITION )ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Priority of south direction - %ld", pMoveDir[ *uiDirNumber ][1]);
#endif
++(*uiDirNumber);
}
pSectorInfo = &( SectorInfo[ SECTOR( sMapX + 1 , sMapY ) ] );
if(CheckStandardConditionsForDirection( sMapX, sMapY, sMapX + 1, sMapY, fWithCities, fForBattle, fOnlyCitySectors ) &&
pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] < gGameExternalOptions.iMaxMilitiaPerSector )
{
pMoveDir[ *uiDirNumber ][0] = SECTOR( sMapX + 1, sMapY );
if( fForBattle )
pMoveDir[ *uiDirNumber ][1] = 0;
else
pMoveDir[ *uiDirNumber ][1] = CountDirectionRating( sMapX, sMapY, DIR_EAST );
pMoveDir[ *uiDirNumber ][2] = INSERTION_CODE_EAST;
#ifdef DEBUG_SHOW_RATINGS
if( DEBUG_RATINGS_CONDITION )ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Priority of east direction - %ld", pMoveDir[ *uiDirNumber ][1]);
#endif
++(*uiDirNumber);
}
}
+12
View File
@@ -22,4 +22,16 @@ void GenerateDirectionInfos( INT16 sMapX, INT16 sMapY, UINT8* uiDirNumber, UINT1
BOOLEAN MoveOneBestMilitiaMan(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY);
void MilitiaFollowPlayer( INT16 sMapX, INT16 sMapY, INT16 sDMapX, INT16 sDMapY );
// HEADROCK HAM B1: Changes the allowed militia sectors
extern void AdjustRoamingRestrictions();
// HEADROCK HAM B1: Alternate array keeps track of dynamically unrestricted sectors
extern BOOLEAN gDynamicRestrictMilitia[ 256 ];
// HEADROCK HAM B2.7: Wonder why this function wasn't declared here. It is now, to allow Town Militia.cpp to
// access it.
BOOLEAN CheckStandardConditionsForDirection( INT16 sSMapX, INT16 sSMapY, INT16 sMapX, INT16 sMapY, BOOLEAN fWithCities, BOOLEAN fForBattle, BOOLEAN fOnlyCitySectors );
// HEADROCK HAM B2.7: Generates possible movement directions - this is used only in CreateMilitiaGroup(), and
// makes sure that the target sector has room for more militia.
void GenerateDirectionInfosWithCapacityCheck( INT16 sMapX, INT16 sMapY, UINT8* uiDirNumber, UINT16 pMoveDir[4][3], BOOLEAN fWithCities, BOOLEAN fForBattle, BOOLEAN fOnlyCitySectors );
#endif
+7
View File
@@ -40,6 +40,8 @@
#include "finances.h"
#include "GameSettings.h"
#include "Quests.h"
// HEADROCK HAM B1: Additional Include for Dynamic Roaming Restrictions
#include "MilitiaSquads.h"
#endif
@@ -510,6 +512,11 @@ void MercDailyUpdate()
// rebuild list for mapscreen
ReBuildCharactersList( );
// HEADROCK HAM B1: Run a function to redefine Roaming Militia Restrictions.
if (gGameExternalOptions.bDynamicRestrictRoaming)
{
AdjustRoamingRestrictions();
}
}
/*
+10 -2
View File
@@ -342,7 +342,8 @@ UINT32 GetMaxPeriodicRemovalFromMine( INT8 bMineIndex )
return ( 0 );
}
return( gMineStatus[ bMineIndex ].uiMaxRemovalRate );
// HEADROCK HAM B1: Affected by external INI option.
return(( gMineStatus[ bMineIndex ].uiMaxRemovalRate * gGameExternalOptions.iMineIncomePercentage ) / 100);
}
@@ -368,6 +369,8 @@ UINT32 GetMaxDailyRemovalFromMine( INT8 bMineIndex )
// yes, reduce to value of mine
uiAmtExtracted = gMineStatus[ bMineIndex ].uiRemainingOreSupply;
}
// HEADROCK HAM B1: Affected by external INI option.
uiAmtExtracted = (uiAmtExtracted * gGameExternalOptions.iMineIncomePercentage) / 100;
return(uiAmtExtracted);
}
@@ -664,6 +667,8 @@ void HandleIncomeFromMines( void )
// mine this mine
iIncome += MineAMine( bCounter );
}
// HEADROCK HAM B1: Affected by external INI Option.
iIncome = (iIncome * gGameExternalOptions.iMineIncomePercentage) / 100;
if( iIncome )
{
AddTransactionToPlayersBook( DEPOSIT_FROM_SILVER_MINE, 0, GetWorldTotalMin( ), iIncome );
@@ -690,7 +695,8 @@ UINT32 PredictDailyIncomeFromAMine( INT8 bMineIndex )
}
}
return( uiAmtExtracted );
// HEADROCK HAM B1: Affected by external INI Option.
return( ( uiAmtExtracted * gGameExternalOptions.iMineIncomePercentage ) / 100 ) ;
}
@@ -720,6 +726,8 @@ INT32 CalcMaxPlayerIncomeFromMines( void )
// add up the total
iTotal += (MINE_PRODUCTION_NUMBER_OF_PERIODS * gMineStatus[bCounter].uiMaxRemovalRate);
}
// HEADROCK HAM B1: Affected by external INI Option.
iTotal = (iTotal * gGameExternalOptions.iMineIncomePercentage) / 100;
return( iTotal );
}
+7
View File
@@ -33,6 +33,8 @@
#include "history.h"
#include "meanwhile.h"
#include "Strategic Status.h"
// HEADROCK HAM B1: Added include for Dynamic Roaming Militia
#include "MilitiaSquads.h"
#endif
// the max loyalty rating for any given town
@@ -1814,6 +1816,11 @@ void CheckIfEntireTownHasBeenLiberated( INT8 bTownId, INT16 sSectorX, INT16 sSec
{
UpdateLastDayOfPlayerActivity( ( UINT16 ) ( GetWorldDay() + 2 ) );
}
// HEADROCK HAM B1: Run a function to redefine Roaming Militia Restrictions on city capture.
if (gGameExternalOptions.bDynamicRestrictRoaming)
{
AdjustRoamingRestrictions();
}
// set flag even for towns where you can't train militia, useful for knowing Orta/Tixa were previously controlled
gTownLoyalty[ bTownId ].fLiberatedAlready = TRUE;
+239 -23
View File
@@ -653,6 +653,8 @@ extern BOOLEAN gfDeductPoints;
extern void CleanUpStack( OBJECTTYPE * pObj, OBJECTTYPE * pCursorObj );
extern void SwapGoggles(SOLDIERTYPE *pTeamSoldier);
// HEADROCK HAM B2.8: Function to switch team's goggles uniformly
extern void SwapGogglesUniformly(SOLDIERTYPE *pTeamSoldier, BOOLEAN fToNightVision);
UINT32 guiCHARLIST;
UINT32 guiCHARINFO;
@@ -1038,7 +1040,8 @@ void CheckForInventoryModeCancellation();
void ChangeMapScreenMaskCursor( UINT16 usCursor );
void CancelOrShortenPlottedPath( void );
BOOLEAN HandleCtrlOrShiftInTeamPanel( INT8 bCharNumber );
// HEADROCK HAM B2.8: Added argument to enable multi-selecting entire squads
BOOLEAN HandleCtrlOrShiftInTeamPanel( INT8 bCharNumber, BOOLEAN fFromRightClickAssignments );
INT32 GetContractExpiryTime( SOLDIERTYPE *pSoldier );
@@ -9674,7 +9677,8 @@ void TeamListInfoRegionBtnCallBack(MOUSE_REGION *pRegion, INT32 iReason )
if( gCharactersList[ iValue ].fValid == TRUE )
{
if ( HandleCtrlOrShiftInTeamPanel( ( INT8 ) iValue ) )
// HEADROCK HAM B2.8: Added argument for multi-select entire squads
if ( HandleCtrlOrShiftInTeamPanel( ( INT8 ) iValue , FALSE ))
{
return;
}
@@ -9824,7 +9828,8 @@ void TeamListAssignmentRegionBtnCallBack(MOUSE_REGION *pRegion, INT32 iReason )
if( gCharactersList[ iValue ].fValid == TRUE )
{
if ( HandleCtrlOrShiftInTeamPanel( ( INT8 ) iValue ) )
// HEADROCK HAM B2.8: Added argument for multi-select entire squads
if ( HandleCtrlOrShiftInTeamPanel( ( INT8 ) iValue , FALSE ))
{
return;
}
@@ -9892,8 +9897,87 @@ void TeamListAssignmentRegionBtnCallBack(MOUSE_REGION *pRegion, INT32 iReason )
if (iReason & MSYS_CALLBACK_REASON_RBUTTON_UP)
{
// HEADROCK HAM B2.8: Added argument for multi-select entire squads
if ( HandleCtrlOrShiftInTeamPanel( ( INT8 ) iValue, TRUE ))
{
return;
}
// reset selected characters
ResetAllSelectedCharacterModes( );
// HEADROCK HAM B2.8: Right mouse button selects entire squad, if clicked on a squad-assigned character.
// set to new info character...make sure is valid
if( IsMapScreenHelpTextUp() )
{
// stop mapscreen text
StopMapScreenHelpText( );
return;
}
if( gCharactersList[ iValue ].fValid == TRUE )
{
ChangeSelectedInfoChar( ( INT8 ) iValue, TRUE );
pSoldier = &Menptr[ gCharactersList[ iValue ].usSolID ];
// highlight
giDestHighLine = -1;
// reset character
bSelectedAssignChar = -1;
bSelectedDestChar = -1;
bSelectedContractChar = -1;
fPlotForHelicopter = FALSE;
// if not dead or POW, select his sector
if( ( pSoldier->stats.bLife > 0 ) && ( pSoldier->bAssignment != ASSIGNMENT_POW ) )
{
ChangeSelectedMapSector( pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ );
}
// Select all characters in squad
INT16 iCounter;
for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{
if( gCharactersList[ iCounter ].fValid == TRUE )
{
// if not already selected
if( fSelectedListOfMercsForMapScreen[ iCounter ] == FALSE )
{
pSoldier = &( Menptr[ gCharactersList[ iCounter ].usSolID ] );
// if on a squad or in a vehicle
if ( ( pSoldier->bAssignment < ON_DUTY ) || ( pSoldier->bAssignment == VEHICLE ) )
{
// and a member of that squad or vehicle is selected
if ( AnyMercInSameSquadOrVehicleIsSelected( pSoldier ) )
{
// then also select this guy
SetEntryInSelectedCharacterList( ( INT8 ) iCounter );
}
}
}
}
}
// unhilight contract line
giContractHighLine = -1;
// can't assign highlight line
giAssignHighLine = -1;
// dirty team and map regions
fTeamPanelDirty = TRUE;
fMapPanelDirty = TRUE;
//fMapScreenBottomDirty = TRUE;
gfRenderPBInterface = TRUE;
}
else
{
// reset selected characters
ResetAllSelectedCharacterModes( );
}
}
}
@@ -9980,7 +10064,8 @@ void TeamListDestinationRegionBtnCallBack(MOUSE_REGION *pRegion, INT32 iReason )
if( gCharactersList[ iValue ].fValid == TRUE )
{
if ( HandleCtrlOrShiftInTeamPanel( ( INT8 ) iValue ) )
// HEADROCK HAM B2.8: Added argument for multi-select entire squads
if ( HandleCtrlOrShiftInTeamPanel( ( INT8 ) iValue , FALSE ))
{
return;
}
@@ -10153,7 +10238,8 @@ void TeamListSleepRegionBtnCallBack( MOUSE_REGION *pRegion, INT32 iReason )
if( ( gCharactersList[ iValue ].fValid == TRUE ) )
{
if ( HandleCtrlOrShiftInTeamPanel( ( INT8 ) iValue ) )
// HEADROCK HAM B2.8: Added argument for multi-select entire squads
if ( HandleCtrlOrShiftInTeamPanel( ( INT8 ) iValue , FALSE ))
{
return;
}
@@ -10171,6 +10257,8 @@ void TeamListSleepRegionBtnCallBack( MOUSE_REGION *pRegion, INT32 iReason )
// try to wake him up
if( SetMercAwake( pSoldier, TRUE, FALSE ) )
{
// HEADROCK HAM B2.8: New feature wakes all trainees/trainers automatically
HandleTrainingWakeSynchronize( pSoldier );
// propagate
HandleSelectedMercsBeingPutAsleep( TRUE, TRUE );
return;
@@ -10185,6 +10273,8 @@ void TeamListSleepRegionBtnCallBack( MOUSE_REGION *pRegion, INT32 iReason )
// try to put him to sleep
if( SetMercAsleep( pSoldier, TRUE ) )
{
// HEADROCK HAM B2.8: New feature sends all trainees/trainers to sleep automatically
HandleTrainingSleepSynchronize( pSoldier );
// propagate
HandleSelectedMercsBeingPutAsleep( FALSE, TRUE );
return;
@@ -13853,34 +13943,160 @@ void CancelOrShortenPlottedPath( void )
}
BOOLEAN HandleCtrlOrShiftInTeamPanel( INT8 bCharNumber )
BOOLEAN HandleCtrlOrShiftInTeamPanel( INT8 bCharNumber, BOOLEAN fFromRightClickAssignments )
{
// check if shift or ctrl held down, if so, set values in list
if (_KeyDown(CTRL))
// HEADROCK HAM B2.8: New condition based on new argument.
if (fFromRightClickAssignments)
{
ToggleEntryInSelectedList( bCharNumber );
if ( _KeyDown(CTRL) || _KeyDown(SHIFT) )
{
if ( fSelectedListOfMercsForMapScreen[ bCharNumber ] == FALSE )
{
SetEntryInSelectedCharacterList( bCharNumber );
fTeamPanelDirty = TRUE;
fCharacterInfoPanelDirty = TRUE;
INT16 iCounter;
return( TRUE);
for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{
if( gCharactersList[ iCounter ].fValid == TRUE )
{
// if not already selected
if( fSelectedListOfMercsForMapScreen[ iCounter ] == FALSE )
{
SOLDIERTYPE * pSelected = &( Menptr[ gCharactersList[ bCharNumber ].usSolID ] );
SOLDIERTYPE * pSoldier = &( Menptr[ gCharactersList[ iCounter ].usSolID ] );
// if on a squad, or in a vehicle, or IS a vehicle
if ( pSoldier->bAssignment == VEHICLE )
{
// and a member of that squad or vehicle is selected, or we are a vehicle
if ( pSoldier->iVehicleId == pSelected->iVehicleId ||
(pSelected->flags.uiStatusFlags & SOLDIER_VEHICLE && pSoldier->iVehicleId == pSelected->bVehicleID ) ||
(pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE && pSelected->iVehicleId == pSoldier->bVehicleID ) )
{
// then also select this guy
SetEntryInSelectedCharacterList( ( INT8 ) iCounter );
}
}
else if ( pSoldier->bAssignment == pSelected->bAssignment &&
(pSoldier->bAssignment == TRAIN_TEAMMATE || pSoldier->bAssignment == TRAIN_BY_OTHER) &&
pSoldier->sSectorX == pSelected->sSectorX &&
pSoldier->sSectorY == pSelected->sSectorY &&
pSoldier->sZLevel == pSelected->sZLevel )
{
// make sure only trainers/trainees of the same stat are selected together.
if (pSoldier->bTrainStat == pSelected->bTrainStat)
{
SetEntryInSelectedCharacterList( ( INT8 ) iCounter );
}
}
else if ( pSoldier->bAssignment == pSelected->bAssignment &&
pSoldier->sSectorX == pSelected->sSectorX &&
pSoldier->sSectorY == pSelected->sSectorY &&
pSoldier->sZLevel == pSelected->sZLevel )
{
SetEntryInSelectedCharacterList( ( INT8 ) iCounter );
}
}
}
}
}
else
{
// Deselect entire group
ResetEntryForSelectedList( bCharNumber );
INT16 iCounter;
for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{
if( gCharactersList[ iCounter ].fValid == TRUE )
{
// if not already selected
if( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE )
{
SOLDIERTYPE * pSelected = &( Menptr[ gCharactersList[ bCharNumber ].usSolID ] );
SOLDIERTYPE * pSoldier = &( Menptr[ gCharactersList[ iCounter ].usSolID ] );
// if on a squad, or in a vehicle, or IS a vehicle
if ( pSoldier->bAssignment == VEHICLE )
{
// and a member of that squad or vehicle is selected, or we are a vehicle
if ( pSoldier->iVehicleId == pSelected->iVehicleId ||
(pSelected->flags.uiStatusFlags & SOLDIER_VEHICLE && pSoldier->iVehicleId == pSelected->bVehicleID ) ||
(pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE && pSelected->iVehicleId == pSoldier->bVehicleID ) )
{
// then also select this guy
ResetEntryForSelectedList( ( INT8 ) iCounter );
}
}
else if ( pSoldier->bAssignment == pSelected->bAssignment &&
(pSoldier->bAssignment == TRAIN_TEAMMATE || pSoldier->bAssignment == TRAIN_BY_OTHER) &&
pSoldier->sSectorX == pSelected->sSectorX &&
pSoldier->sSectorY == pSelected->sSectorY &&
pSoldier->sZLevel == pSelected->sZLevel )
{
// make sure only trainers/trainees of the same stat are selected together.
if (pSoldier->bTrainStat == pSelected->bTrainStat)
{
ResetEntryForSelectedList( ( INT8 ) iCounter );
}
}
else if ( pSoldier->bAssignment == pSelected->bAssignment &&
pSoldier->sSectorX == pSelected->sSectorX &&
pSoldier->sSectorY == pSelected->sSectorY &&
pSoldier->sZLevel == pSelected->sZLevel )
{
ResetEntryForSelectedList( ( INT8 ) iCounter );
}
}
}
}
}
fTeamPanelDirty = TRUE;
fCharacterInfoPanelDirty = TRUE;
return(TRUE);
}
return (FALSE);
}
else if( _KeyDown(SHIFT) )
else
{
// build a list from the bSelectedInfoChar To here, reset everyone
//empty the list
ResetSelectedListForMapScreen( );
// rebuild the list
BuildSelectedListFromAToB( bSelectedInfoChar, bCharNumber );
// check if shift or ctrl held down, if so, set values in list
if (_KeyDown(CTRL))
{
ToggleEntryInSelectedList( bCharNumber );
fTeamPanelDirty = TRUE;
fCharacterInfoPanelDirty = TRUE;
fTeamPanelDirty = TRUE;
fCharacterInfoPanelDirty = TRUE;
return( TRUE );
return( TRUE);
}
else if( _KeyDown(SHIFT) )
{
// build a list from the bSelectedInfoChar To here, reset everyone
//empty the list
ResetSelectedListForMapScreen( );
// rebuild the list
BuildSelectedListFromAToB( bSelectedInfoChar, bCharNumber );
fTeamPanelDirty = TRUE;
fCharacterInfoPanelDirty = TRUE;
return( TRUE );
}
return( FALSE );
}
return( FALSE );
}
+3
View File
@@ -13,6 +13,9 @@
#define MAX_TOWNS 50 //13 //50
#define MAX_TOWN_SECTORS 260 //40 //260
// HEADROCK HAM B2.7: Moved here from Strategicmap.cpp to allow use by MilitiaSquads.cpp
extern BOOLEAN gfMilitiaAllowedInTown [ MAX_TOWNS ];
// Sector name identifiers
enum Towns
{