diff --git a/Strategic/ASD.cpp b/Strategic/ASD.cpp index e66176df..63f76dc8 100644 --- a/Strategic/ASD.cpp +++ b/Strategic/ASD.cpp @@ -354,6 +354,10 @@ void ASDDecideHeliOperations() if ( (*it).flagmask & ENEMYHELI_ORDERS ) continue; + // if we dont have enough soldiers left to staff a helicopter, don't send one out + if ( giReinforcementPool < gEnemyHeliMaxTroops ) + continue; + ENEMY_HELI& heli = (*it); UINT32 totalrating = 0; @@ -569,10 +573,8 @@ UINT8 ENEMY_HELI::SetHeliFlightPath( UINT8 aDest ) void ENEMY_HELI::Destroy( ) { - troopcount = 0; hp = 0; - fuel = 0; - + flagmask |= ENEMYHELI_DESTROYED; // if the player knows about this heli, play a sound and leave a message @@ -590,16 +592,41 @@ void ENEMY_HELI::Destroy( ) } } - // if a helicopter was shot down, remember that for the sector - we might spawn a downed pilot for the player to search! + // if a helicopter was shot down, there might be survivors or wreckage if ( flagmask & ENEMYHELI_SHOTDOWN ) { - SECTORINFO *pSectorInfo = &(SectorInfo[sector_current]); + // remember that a heli crashed here. When entering the sector the next time, we might spawn a downed pilot or wreckage + SectorInfo[sector_current].usSectorInfoFlag |= SECTORINFO_ENEMYHELI_SHOTDOWN; - if ( pSectorInfo ) + // if the heli had soldiers aboard, they might have survived the crash. Add them to the sector in that case + // don't do this in sectors that are impassable + if ( troopcount && !SectorIsImpassable( sector_current ) ) { - pSectorInfo->usSectorInfoFlag |= SECTORINFO_ENEMYHELI_SHOTDOWN; + // it is possible that we shoot down a helicopter while in a fight. In this case, adding soldiers to a sector would either cause a second battle or a state where a fight should start but doesn't + // both is bad, so we simply don't add soldiers in that case. The player will hardly notice, as there is only a chance that soldiers survive anyway + if ( !gTacticalStatus.fEnemyInSector && !(gTacticalStatus.uiFlags & INCOMBAT) ) + { + // chance that they survived at all + if ( Chance( 75 ) ) + { + // not all might have made it + SectorInfo[sector_current].ubNumElites = min( 255, SectorInfo[sector_current].ubNumElites + 1 + Random(troopcount) ); + + // if no militia or mercs are here, enemy takes this sector + if ( PlayerMercsInSector( SECTORX( sector_current ), SECTORY( sector_current ), 0 ) + NumNonPlayerTeamMembersInSector( SECTORX( sector_current ), SECTORY( sector_current ), MILITIA_TEAM ) <= 0 ) + { + SetThisSectorAsEnemyControlled( SECTORX( sector_current ), SECTORY( sector_current ), 0, TRUE ); + } + + CheckCombatInSectorDueToUnusualEnemyArrival( ENEMY_TEAM, SECTORX( sector_current ), SECTORY( sector_current ), 0 ); + } + } } } + + // reduce these at the end, as we might do sth based on them + fuel = 0; + troopcount = 0; } void EnemyHeliInit( ) diff --git a/Strategic/MilitiaSquads.cpp b/Strategic/MilitiaSquads.cpp index 77584233..253b2687 100644 --- a/Strategic/MilitiaSquads.cpp +++ b/Strategic/MilitiaSquads.cpp @@ -167,8 +167,6 @@ void GenerateMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY, UINT16 usTotalMilitiaAtTarget = NumNonPlayerTeamMembersInSector( sTMapX, sTMapY, MILITIA_TEAM ); // Desired number of Greens, Regulars and Elites to create. UINT8 ubTargetGreen, ubTargetRegular, ubTargetElite; - // Upgrade points for replacing militia with better ones. - UINT8 ubUpgradePoints; // Calculate default number of militia to place in Target Sector. UINT8 ubMilitiaToTrain = gGameExternalOptions.guiNumMobileMilitiaTrained; // Percentage of troops that should be of any one type: diff --git a/Strategic/Strategic Movement Costs.cpp b/Strategic/Strategic Movement Costs.cpp index 07884df9..8a7f8b4a 100644 --- a/Strategic/Strategic Movement Costs.cpp +++ b/Strategic/Strategic Movement Costs.cpp @@ -30,7 +30,6 @@ extern void UpdateCustomMapMovementCosts(); // ja25 UB extern void MakeBadSectorListFromMapsOnHardDrive( BOOLEAN fDisplayMessages ); // ja25 UB extern void AddCustomMap( INT32 iRow, INT32 iCol, BOOLEAN fDisplayMessages, BOOLEAN fMessageIfNotExist ); //ja25 UB extern UNDERGROUND_SECTORINFO* NewUndergroundNode( UINT8 ubSectorX, UINT8 ubSectorY, UINT8 ubSectorZ ); -extern BOOLEAN SectorIsImpassableUB( INT16 sSector ); #endif typedef enum diff --git a/Strategic/Strategic Movement.h b/Strategic/Strategic Movement.h index ea86c3af..37c01f83 100644 --- a/Strategic/Strategic Movement.h +++ b/Strategic/Strategic Movement.h @@ -304,6 +304,8 @@ void RandomizePatrolGroupLocation( GROUP *pGroup ); BOOLEAN InitStrategicMovementCosts(); +BOOLEAN SectorIsImpassable( INT16 sSector ); + void PlaceGroupInSector( UINT8 ubGroupID, INT16 sPrevX, INT16 sPrevY, INT16 sNextX, INT16 sNextY, INT8 bZ, BOOLEAN fCheckForBattle ); void SetGroupArrivalTime( GROUP *pGroup, UINT32 uiArrivalTime ); diff --git a/Tactical/Campaign.cpp b/Tactical/Campaign.cpp index 1ca3e2ad..5d459c97 100644 --- a/Tactical/Campaign.cpp +++ b/Tactical/Campaign.cpp @@ -1971,18 +1971,18 @@ UINT16 CountSurfaceSectorsVisited( void ) return( ubSectorsVisited ); } + // HEADROCK: Count number of VISITABLE sectors UINT16 TotalVisitableSurfaceSectors( void ) { UINT8 ubMapX, ubMapY; UINT16 ubVisitableSectors = 0; - - + for ( ubMapX = 1; ubMapX < MAP_WORLD_X - 1; ubMapX++ ) { for ( ubMapY = 1; ubMapY < MAP_WORLD_Y - 1; ubMapY++ ) { - if( SectorInfo[ SECTOR(ubMapX,ubMapY) ].ubTraversability[ THROUGH_STRATEGIC_MOVE ] != GROUNDBARRIER && SectorInfo[ SECTOR(ubMapX,ubMapY) ].ubTraversability[ THROUGH_STRATEGIC_MOVE ] != EDGEOFWORLD ) + if ( !SectorIsImpassable( SECTOR( ubMapX, ubMapY ) ) ) ++ubVisitableSectors; } }