mirror of
https://github.com/1dot13/source.git
synced 2026-08-12 14:10:23 +02:00
New feature: transport groups (#172)
https://thepit.ja-galaxy-forum.com/index.php?t=msg&goto=365395
This commit is contained in:
@@ -633,6 +633,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve1");
|
||||
switch( GetEnemyEncounterCode() )
|
||||
{
|
||||
case ENEMY_ENCOUNTER_CODE:
|
||||
case TRANSPORT_INTERCEPT_CODE:
|
||||
gpAR->ubPlayerDefenceAdvantage = 21; //Skewed to the player's advantage for convenience purposes.
|
||||
break;
|
||||
case ENEMY_INVASION_CODE:
|
||||
@@ -1745,6 +1746,7 @@ void RenderAutoResolve()
|
||||
swprintf( str, gpStrategicString[STR_AR_ATTACK_HEADER] );
|
||||
break;
|
||||
case ENEMY_ENCOUNTER_CODE:
|
||||
case TRANSPORT_INTERCEPT_CODE:
|
||||
swprintf( str, gpStrategicString[STR_AR_ENCOUNTER_HEADER] );
|
||||
break;
|
||||
case ENEMY_INVASION_CODE:
|
||||
@@ -6058,6 +6060,5 @@ BOOLEAN IndividualMilitiaInUse_AutoResolve( UINT32 aMilitiaId )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ set(StrategicSrc
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Strategic Status.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Strategic Town Loyalty.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/strategic town reputation.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Strategic Transport Groups.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Strategic Turns.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/strategic.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/strategicmap.cpp"
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "LuaInitNPCs.h" // added by Flugente
|
||||
#include "MiniEvents.h"
|
||||
#include "Rebel Command.h"
|
||||
#include "interface Dialogue.h"
|
||||
|
||||
#include "connect.h"
|
||||
|
||||
@@ -668,6 +669,11 @@ BOOLEAN ExecuteStrategicEvent( STRATEGICEVENT *pEvent )
|
||||
case EVENT_REBELCOMMAND:
|
||||
RebelCommand::HandleStrategicEvent(pEvent->uiParam);
|
||||
break;
|
||||
|
||||
case EVENT_RETURN_TRANSPORT_GROUP:
|
||||
// for this action, we only care about the groupid, which is in the event param
|
||||
ExecuteStrategicAIAction(NPC_ACTION_RETURN_TRANSPORT_GROUP, 0, 0, pEvent->uiParam);
|
||||
break;
|
||||
}
|
||||
gfPreventDeletionOfAnyEvent = fOrigPreventFlag;
|
||||
return TRUE;
|
||||
|
||||
@@ -154,6 +154,9 @@ enum
|
||||
|
||||
EVENT_REBELCOMMAND,
|
||||
|
||||
EVENT_RETURN_TRANSPORT_GROUP,
|
||||
EVENT_TRANSPORT_GROUP_DEFEATED,
|
||||
|
||||
NUMBER_OF_EVENT_TYPES_PLUS_ONE,
|
||||
NUMBER_OF_EVENT_TYPES = NUMBER_OF_EVENT_TYPES_PLUS_ONE - 1
|
||||
};
|
||||
@@ -217,4 +220,4 @@ void DeleteAllStrategicEvents();
|
||||
// Flugente: return vector of all events of type ubCallbackID with time and param
|
||||
std::vector< std::pair<UINT32, UINT32> > GetAllStrategicEventsOfType( UINT8 ubCallbackID );
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -137,6 +137,7 @@ CHAR16 gEventName[NUMBER_OF_EVENT_TYPES_PLUS_ONE][40]={
|
||||
L"ArmyFinishTraining",
|
||||
L"MiniEvent",
|
||||
L"ARC_Event",
|
||||
L"ReturnTransportGroup",
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "LuaInitNPCs.h" // added by Flugente
|
||||
#include "Game Event Hook.h" // added by Flugente
|
||||
#include "Rebel Command.h"
|
||||
#include "Strategic Transport Groups.h"
|
||||
|
||||
#include "Quests.h"
|
||||
#include "connect.h"
|
||||
@@ -841,6 +842,8 @@ void fillMapColoursForVisitedSectors(INT32(&colorMap)[ MAXIMUM_VALID_Y_COORDINAT
|
||||
}
|
||||
}
|
||||
|
||||
FillMapColoursForTransportGroups(colorMap);
|
||||
|
||||
if (RebelCommand::ShowEnemyMovementTargets())
|
||||
{
|
||||
const auto targetColor = MAP_SHADE_LT_RED;
|
||||
@@ -8584,6 +8587,25 @@ void DetermineMapIntelData( INT32 asSectorZ )
|
||||
}
|
||||
}
|
||||
|
||||
// transport groups
|
||||
std::map<UINT8, TransportGroupSectorInfo> map = GetTransportGroupSectorInfo();
|
||||
for (const auto iter : map)
|
||||
{
|
||||
CHAR16 str[128];
|
||||
|
||||
switch (iter.second)
|
||||
{
|
||||
case TransportGroupSectorInfo::TransportGroupSectorInfo_LocatedGroup:
|
||||
swprintf( str, gpStrategicString[STR_PB_TRANSPORT_GROUP]);
|
||||
break;
|
||||
|
||||
case TransportGroupSectorInfo::TransportGroupSectorInfo_LocatedDestination:
|
||||
swprintf( str, gpStrategicString[STR_PB_TRANSPORT_GROUP_EN_ROUTE]);
|
||||
break;
|
||||
}
|
||||
AddIntelAndQuestMapDataForSector( SECTORX(iter.first), SECTORY(iter.first), MAP_SHADE_LT_YELLOW, -1, str, L"" );
|
||||
}
|
||||
|
||||
// uncovered terrorists we know of
|
||||
for ( int cnt = 0; cnt < 6; ++cnt )
|
||||
{
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "CampaignStats.h" // added by Flugente
|
||||
#include "militiasquads.h" // added by Flugente
|
||||
#include "SkillCheck.h" // added by Flugente
|
||||
#include "Strategic Transport Groups.h"
|
||||
|
||||
#ifdef JA2UB
|
||||
#include "ub_config.h"
|
||||
@@ -438,7 +439,7 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
|
||||
}
|
||||
else if ( pBattleGroup && pBattleGroup->usGroupTeam != OUR_TEAM && NumNonPlayerTeamMembersInSector( pBattleGroup->ubSectorX, pBattleGroup->ubSectorY, MILITIA_TEAM ) > 0 )
|
||||
{
|
||||
SetEnemyEncounterCode( ENEMY_ENCOUNTER_CODE );
|
||||
SetEnemyEncounterCode( pBattleGroup->usGroupTeam == ENEMY_TEAM && pBattleGroup->pEnemyGroup->ubIntention == TRANSPORT ? TRANSPORT_INTERCEPT_CODE : ENEMY_ENCOUNTER_CODE );
|
||||
}
|
||||
else if( GetEnemyEncounterCode() == ENTERING_ENEMY_SECTOR_CODE ||
|
||||
GetEnemyEncounterCode() == ENEMY_ENCOUNTER_CODE ||
|
||||
@@ -452,7 +453,8 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
|
||||
GetEnemyEncounterCode() == CONCEALINSERTION_CODE ||
|
||||
GetEnemyEncounterCode() == BLOODCAT_ATTACK_CODE ||
|
||||
GetEnemyEncounterCode() == ZOMBIE_ATTACK_CODE ||
|
||||
GetEnemyEncounterCode() == BANDIT_ATTACK_CODE )
|
||||
GetEnemyEncounterCode() == BANDIT_ATTACK_CODE ||
|
||||
GetEnemyEncounterCode() == TRANSPORT_INTERCEPT_CODE )
|
||||
{
|
||||
//use same code
|
||||
SetExplicitEnemyEncounterCode( GetEnemyEncounterCode() );
|
||||
@@ -679,8 +681,24 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
|
||||
{
|
||||
SetEnemyEncounterCode( ENEMY_ENCOUNTER_CODE );
|
||||
|
||||
GROUP* pGroup = gpGroupList;
|
||||
BOOLEAN encounteredTransportGroup = FALSE;
|
||||
while (pGroup)
|
||||
{
|
||||
if (pGroup->usGroupTeam == ENEMY_TEAM && pGroup->pEnemyGroup->ubIntention == TRANSPORT && pGroup->ubSectorX == gpBattleGroup->ubSectorX && pGroup->ubSectorY == gpBattleGroup->ubSectorY && pGroup->ubSectorZ == gpBattleGroup->ubSectorZ)
|
||||
{
|
||||
encounteredTransportGroup = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
pGroup = pGroup->next;
|
||||
}
|
||||
if (encounteredTransportGroup)
|
||||
{
|
||||
SetEnemyEncounterCode( TRANSPORT_INTERCEPT_CODE );
|
||||
}
|
||||
// Flugente: no ambushes on an airdrop
|
||||
if ( !fAirDrop )
|
||||
else if ( !fAirDrop )
|
||||
{
|
||||
//Don't consider ambushes until the player has reached 25% (normal) progress
|
||||
if( gfHighPotentialForAmbush )
|
||||
@@ -798,7 +816,9 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
|
||||
}
|
||||
else
|
||||
{ //Are enemies invading a town, or just encountered the player.
|
||||
if( GetTownIdForSector( gubPBSectorX, gubPBSectorY ) )
|
||||
if (pBattleGroup && pBattleGroup->usGroupTeam == ENEMY_TEAM && pBattleGroup->pEnemyGroup->ubIntention == TRANSPORT)
|
||||
SetEnemyEncounterCode( TRANSPORT_INTERCEPT_CODE );
|
||||
else if( GetTownIdForSector( gubPBSectorX, gubPBSectorY ) )
|
||||
SetEnemyEncounterCode( ENEMY_INVASION_CODE );
|
||||
//SAM sites not in towns will also be considered to be important
|
||||
else if( pSector->uiFlags & SF_SAM_SITE )
|
||||
@@ -866,7 +886,7 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
|
||||
}
|
||||
HideButton( giMapContractButton );
|
||||
|
||||
if( GetEnemyEncounterCode() == ENEMY_ENCOUNTER_CODE )
|
||||
if( GetEnemyEncounterCode() == ENEMY_ENCOUNTER_CODE || GetEnemyEncounterCode() == TRANSPORT_INTERCEPT_CODE )
|
||||
{ //we know how many enemies are here, so until we leave the sector, we will continue to display the value.
|
||||
//the flag will get cleared when time advances after the fEnemyInSector flag is clear.
|
||||
|
||||
@@ -955,6 +975,7 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
|
||||
{
|
||||
case CREATURE_ATTACK_CODE:
|
||||
case ENEMY_ENCOUNTER_CODE:
|
||||
case TRANSPORT_INTERCEPT_CODE:
|
||||
case ENEMY_INVASION_CODE:
|
||||
case ENEMY_INVASION_AIRDROP_CODE:
|
||||
case BLOODCAT_ATTACK_CODE:
|
||||
@@ -1213,6 +1234,7 @@ void RenderPBHeader( INT32 *piX, INT32 *piWidth)
|
||||
swprintf( str, gpStrategicString[ STR_PB_ENEMYINVASION_HEADER ] );
|
||||
break;
|
||||
case ENEMY_ENCOUNTER_CODE:
|
||||
case TRANSPORT_INTERCEPT_CODE:
|
||||
swprintf( str, gpStrategicString[ STR_PB_ENEMYENCOUNTER_HEADER ] );
|
||||
break;
|
||||
case ENEMY_AMBUSH_CODE:
|
||||
@@ -2520,6 +2542,10 @@ void LogBattleResults( UINT8 ubVictoryCode)
|
||||
break;
|
||||
case CONCEALINSERTION_CODE:
|
||||
break;
|
||||
case TRANSPORT_INTERCEPT_CODE:
|
||||
AddHistoryToPlayersLog( HISTORY_INTERCEPTED_TRANSPORT_GROUP, 0, GetWorldTotalMin(), sSectorX, sSectorY );
|
||||
NotifyTransportGroupDefeated();
|
||||
break;
|
||||
}
|
||||
|
||||
// Flugente: campaign stats
|
||||
@@ -2534,6 +2560,7 @@ void LogBattleResults( UINT8 ubVictoryCode)
|
||||
AddHistoryToPlayersLog( HISTORY_LOSTTOWNSECTOR, 0, GetWorldTotalMin(), sSectorX, sSectorY );
|
||||
break;
|
||||
case ENEMY_ENCOUNTER_CODE:
|
||||
case TRANSPORT_INTERCEPT_CODE:
|
||||
AddHistoryToPlayersLog( HISTORY_LOSTBATTLE, 0, GetWorldTotalMin(), sSectorX, sSectorY );
|
||||
break;
|
||||
case ENEMY_AMBUSH_CODE:
|
||||
@@ -2567,6 +2594,7 @@ void LogBattleResults( UINT8 ubVictoryCode)
|
||||
gCurrentIncident.usIncidentFlags |= INCIDENT_ATTACK_ENEMY;
|
||||
break;
|
||||
case ENEMY_ENCOUNTER_CODE:
|
||||
case TRANSPORT_INTERCEPT_CODE:
|
||||
case ENTERING_ENEMY_SECTOR_CODE:
|
||||
case CREATURE_ATTACK_CODE:
|
||||
case ENTERING_BLOODCAT_LAIR_CODE:
|
||||
|
||||
@@ -47,6 +47,8 @@ enum
|
||||
BLOODCAT_ATTACK_CODE, // Flugente: like CREATURE_ATTACK_CODE, but with cats
|
||||
ZOMBIE_ATTACK_CODE, // Flugente: like CREATURE_ATTACK_CODE, but with zombies
|
||||
BANDIT_ATTACK_CODE, // Flugente: like CREATURE_ATTACK_CODE, but with bandits
|
||||
|
||||
TRANSPORT_INTERCEPT_CODE, // rftr: like ENEMY_ENCOUNTER_CODE
|
||||
};
|
||||
|
||||
extern BOOLEAN gfAutoAmbush;
|
||||
@@ -112,4 +114,4 @@ enum
|
||||
};
|
||||
void LogBattleResults( UINT8 ubVictoryCode);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "CampaignStats.h" // added by Flugente
|
||||
#include "ASD.h" // added by Flugente
|
||||
#include "Interface Panels.h"
|
||||
#include "Strategic Transport Groups.h"
|
||||
|
||||
#ifdef JA2BETAVERSION
|
||||
extern BOOLEAN gfClearCreatureQuest;
|
||||
@@ -98,7 +99,6 @@ void HandleBloodCatDeaths( SECTORINFO *pSector );
|
||||
|
||||
extern void Ensure_RepairedGarrisonGroup( GARRISON_GROUP **ppGarrison, INT32 *pGarraySize );
|
||||
|
||||
|
||||
void ValidateEnemiesHaveWeapons()
|
||||
{
|
||||
#ifdef JA2BETAVERSION
|
||||
@@ -613,6 +613,9 @@ BOOLEAN PrepareEnemyForSectorBattle()
|
||||
|
||||
gfPendingNonPlayerTeam[ENEMY_TEAM] = FALSE;
|
||||
|
||||
// rftr: clear cached transport groups
|
||||
ClearTransportGroupMap();
|
||||
|
||||
if( gbWorldSectorZ > 0 )
|
||||
return PrepareEnemyForUndergroundBattle();
|
||||
|
||||
@@ -640,9 +643,9 @@ BOOLEAN PrepareEnemyForSectorBattle()
|
||||
|
||||
for( unsigned ubIndex = 0; ubIndex < ubDirNumber; ++ubIndex )
|
||||
{
|
||||
while ( NumMobileEnemiesInSector( SECTORX( pusMoveDir[ubIndex][0] ), SECTORY( pusMoveDir[ubIndex][0] ) ) && GetNonPlayerGroupInSector( SECTORX( pusMoveDir[ubIndex][0] ), SECTORY( pusMoveDir[ubIndex][0] ), ENEMY_TEAM ) )
|
||||
while ( NumMobileEnemiesInSector( SECTORX( pusMoveDir[ubIndex][0] ), SECTORY( pusMoveDir[ubIndex][0] ) ) && GetNonPlayerGroupInSectorForReinforcement( SECTORX( pusMoveDir[ubIndex][0] ), SECTORY( pusMoveDir[ubIndex][0] ), ENEMY_TEAM ) )
|
||||
{
|
||||
pGroup = GetNonPlayerGroupInSector( SECTORX( pusMoveDir[ubIndex][0] ), SECTORY( pusMoveDir[ubIndex][0] ), ENEMY_TEAM );
|
||||
pGroup = GetNonPlayerGroupInSectorForReinforcement( SECTORX( pusMoveDir[ubIndex][0] ), SECTORY( pusMoveDir[ubIndex][0] ), ENEMY_TEAM );
|
||||
|
||||
pGroup->ubPrevX = pGroup->ubSectorX;
|
||||
pGroup->ubPrevY = pGroup->ubSectorY;
|
||||
@@ -669,10 +672,23 @@ BOOLEAN PrepareEnemyForSectorBattle()
|
||||
HandleArrivalOfReinforcements( pGroup );
|
||||
}
|
||||
|
||||
// for transport groups, track how many enemies of each type we're adding so we can update drops for them
|
||||
if (pGroup->usGroupTeam == ENEMY_TEAM && pGroup->pEnemyGroup->ubIntention == TRANSPORT && pGroup->ubSectorX == gWorldSectorX && pGroup->ubSectorY == gWorldSectorY && !gbWorldSectorZ)
|
||||
{
|
||||
AddToTransportGroupMap(pGroup->ubGroupID, SOLDIER_CLASS_ADMINISTRATOR, pGroup->pEnemyGroup->ubNumAdmins);
|
||||
AddToTransportGroupMap(pGroup->ubGroupID, SOLDIER_CLASS_ARMY, pGroup->pEnemyGroup->ubNumTroops);
|
||||
AddToTransportGroupMap(pGroup->ubGroupID, SOLDIER_CLASS_ELITE, pGroup->pEnemyGroup->ubNumElites);
|
||||
AddToTransportGroupMap(pGroup->ubGroupID, SOLDIER_CLASS_ROBOT, pGroup->pEnemyGroup->ubNumRobots);
|
||||
AddToTransportGroupMap(pGroup->ubGroupID, SOLDIER_CLASS_JEEP, pGroup->pEnemyGroup->ubNumJeeps);
|
||||
AddToTransportGroupMap(pGroup->ubGroupID, SOLDIER_CLASS_TANK, pGroup->pEnemyGroup->ubNumTanks);
|
||||
}
|
||||
|
||||
pGroup = pGroup->next;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateTransportGroupInventory();
|
||||
|
||||
ValidateEnemiesHaveWeapons();
|
||||
UnPauseGame();
|
||||
return ( ( BOOLEAN) ( gpBattleGroup->ubGroupSize > 0 ) );
|
||||
@@ -852,6 +868,7 @@ BOOLEAN PrepareEnemyForSectorBattle()
|
||||
if ( pGroup->usGroupTeam == ENEMY_TEAM && !pGroup->fVehicle &&
|
||||
pGroup->ubSectorX == gWorldSectorX && pGroup->ubSectorY == gWorldSectorY && !gbWorldSectorZ )
|
||||
{ //Process enemy group in sector.
|
||||
const BOOLEAN isTransportGroup = pGroup->pEnemyGroup->ubIntention == TRANSPORT;
|
||||
if( sNumSlots > 0 )
|
||||
{
|
||||
AssertGE(pGroup->pEnemyGroup->ubNumAdmins, pGroup->pEnemyGroup->ubAdminsInBattle);
|
||||
@@ -865,6 +882,9 @@ BOOLEAN PrepareEnemyForSectorBattle()
|
||||
}
|
||||
pGroup->pEnemyGroup->ubAdminsInBattle += ubNumAdmins;
|
||||
ubTotalAdmins += ubNumAdmins;
|
||||
|
||||
if (isTransportGroup)
|
||||
AddToTransportGroupMap(pGroup->ubGroupID, SOLDIER_CLASS_ADMINISTRATOR, ubNumAdmins);
|
||||
}
|
||||
if( sNumSlots > 0 )
|
||||
{ //Add regular army forces.
|
||||
@@ -879,6 +899,9 @@ BOOLEAN PrepareEnemyForSectorBattle()
|
||||
}
|
||||
pGroup->pEnemyGroup->ubTroopsInBattle += ubNumTroops;
|
||||
ubTotalTroops += ubNumTroops;
|
||||
|
||||
if (isTransportGroup)
|
||||
AddToTransportGroupMap(pGroup->ubGroupID, SOLDIER_CLASS_ARMY, ubNumTroops);
|
||||
}
|
||||
if( sNumSlots > 0 )
|
||||
{ //Add elite troops
|
||||
@@ -893,6 +916,9 @@ BOOLEAN PrepareEnemyForSectorBattle()
|
||||
}
|
||||
pGroup->pEnemyGroup->ubElitesInBattle += ubNumElites;
|
||||
ubTotalElites += ubNumElites;
|
||||
|
||||
if (isTransportGroup)
|
||||
AddToTransportGroupMap(pGroup->ubGroupID, SOLDIER_CLASS_ELITE, ubNumElites);
|
||||
}
|
||||
if( sNumSlots > 0 )
|
||||
{ //Add robots
|
||||
@@ -907,6 +933,9 @@ BOOLEAN PrepareEnemyForSectorBattle()
|
||||
}
|
||||
pGroup->pEnemyGroup->ubRobotsInBattle += ubNumRobots;
|
||||
ubTotalRobots += ubNumRobots;
|
||||
|
||||
if (isTransportGroup)
|
||||
AddToTransportGroupMap(pGroup->ubGroupID, SOLDIER_CLASS_ROBOT, ubNumRobots);
|
||||
}
|
||||
if( sNumSlots > 0 )
|
||||
{ //Add tanks
|
||||
@@ -921,6 +950,9 @@ BOOLEAN PrepareEnemyForSectorBattle()
|
||||
}
|
||||
pGroup->pEnemyGroup->ubTanksInBattle += ubNumTanks;
|
||||
ubTotalTanks += ubNumTanks;
|
||||
|
||||
if (isTransportGroup)
|
||||
AddToTransportGroupMap(pGroup->ubGroupID, SOLDIER_CLASS_TANK, ubNumTanks);
|
||||
}
|
||||
if ( sNumSlots > 0 )
|
||||
{
|
||||
@@ -936,6 +968,9 @@ BOOLEAN PrepareEnemyForSectorBattle()
|
||||
}
|
||||
pGroup->pEnemyGroup->ubJeepsInBattle += ubNumJeeps;
|
||||
ubTotalJeeps += ubNumJeeps;
|
||||
|
||||
if (isTransportGroup)
|
||||
AddToTransportGroupMap(pGroup->ubGroupID, SOLDIER_CLASS_JEEP, ubNumJeeps);
|
||||
}
|
||||
//NOTE:
|
||||
//no provisions for profile troop leader or retreat groups yet.
|
||||
@@ -976,6 +1011,7 @@ BOOLEAN PrepareEnemyForSectorBattle()
|
||||
unsigned firstSlot = gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID;
|
||||
unsigned lastSlot = gTacticalStatus.Team[ ENEMY_TEAM ].bLastID;
|
||||
unsigned slotsAvailable = lastSlot-firstSlot+1;
|
||||
|
||||
while( pGroup && sNumSlots > 0 )
|
||||
{
|
||||
if ( pGroup->usGroupTeam != OUR_TEAM && !pGroup->fVehicle &&
|
||||
@@ -1088,6 +1124,7 @@ BOOLEAN PrepareEnemyForSectorBattle()
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Flugente: instead of just crashing the game without any explanation to the user, ignore this issue if it still exists.
|
||||
@@ -1103,6 +1140,8 @@ BOOLEAN PrepareEnemyForSectorBattle()
|
||||
pGroup = pGroup->next;
|
||||
}
|
||||
|
||||
UpdateTransportGroupInventory();
|
||||
|
||||
ValidateEnemiesHaveWeapons();
|
||||
UnPauseGame();
|
||||
|
||||
@@ -2145,6 +2184,16 @@ void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ub
|
||||
UINT8 ubTotalSoldiers;
|
||||
UINT8 bDesiredDirection=0;
|
||||
|
||||
// while transport groups can't normally reinforce, this covers the case where a transport group enters a sector (via normal movement)
|
||||
// where a battle is in progress.
|
||||
if (pGroup && pGroup->pEnemyGroup->ubIntention == TRANSPORT)
|
||||
{
|
||||
AddToTransportGroupMap(pGroup->ubGroupID, SOLDIER_CLASS_ADMINISTRATOR, ubNumAdmins);
|
||||
AddToTransportGroupMap(pGroup->ubGroupID, SOLDIER_CLASS_ARMY, ubNumTroops);
|
||||
AddToTransportGroupMap(pGroup->ubGroupID, SOLDIER_CLASS_ELITE, ubNumElites);
|
||||
AddToTransportGroupMap(pGroup->ubGroupID, SOLDIER_CLASS_JEEP, ubNumJeeps);
|
||||
}
|
||||
|
||||
switch( ubStrategicInsertionCode )
|
||||
{
|
||||
case INSERTION_CODE_NORTH: bDesiredDirection = SOUTHEAST; break;
|
||||
@@ -3594,3 +3643,5 @@ void CorrectTurncoatCount( INT16 sSectorX, INT16 sSectorY )
|
||||
pGroup = pGroup->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -41,8 +41,10 @@ How to add a new admin action:
|
||||
- if effect applies outside of towns, add help text range band as appropriate to SetupAdminActionBox
|
||||
|
||||
How to add a new mission:
|
||||
- add to the RebelCommandAgentMissions enum in the header
|
||||
- add strings to text files (szRebelCommandAgentMissionsText)
|
||||
- add strings to text files (szRebelCommandText (trait bonuses), szRebelCommandAgentMissionsText (title/description))
|
||||
- add to the RebelCommandText and RebelCommandAgentMissions enums in the header
|
||||
- add to the RebelCommandAgentMissionsText enums in the cpp
|
||||
- add mission variables to GameSettings
|
||||
- add values to MissionHelpers::missionInfo table in SetupInfo()
|
||||
- add to valid check in HandleStrategicEvent() (allows advance from first event/prepare to second event/active effect)
|
||||
- add to SetupMissionAgentBox() (mission description and merc bonus text)
|
||||
@@ -91,6 +93,7 @@ Points of interest:
|
||||
#include "Strategic Mines.h"
|
||||
#include "Strategic Movement.h"
|
||||
#include "Strategic Town Loyalty.h"
|
||||
#include "Strategic Transport Groups.h"
|
||||
#include "Structure Wrap.h"
|
||||
#include "Tactical Save.h"
|
||||
#include "Text.h"
|
||||
@@ -405,6 +408,7 @@ enum RebelCommandAgentMissionsText // keep this synced with szRebelCommandAgentM
|
||||
{
|
||||
MISSION_TEXT(DEEP_DEPLOYMENT)
|
||||
MISSION_TEXT(DISRUPT_ASD)
|
||||
MISSION_TEXT(FORGE_TRANSPORT_ORDERS)
|
||||
MISSION_TEXT(GET_ENEMY_MOVEMENT_TARGETS)
|
||||
MISSION_TEXT(IMPROVE_LOCAL_SHOPS)
|
||||
MISSION_TEXT(REDUCE_STRATEGIC_DECISION_SPEED)
|
||||
@@ -2221,6 +2225,7 @@ BOOLEAN SetupMissionAgentBox(UINT16 x, UINT16 y, INT8 index)
|
||||
{
|
||||
case RCAM_DEEP_DEPLOYMENT: swprintf(sText, szRebelCommandAgentMissionsText[RCAMT_DEEP_DEPLOYMENT_TITLE]); break;
|
||||
case RCAM_DISRUPT_ASD: swprintf(sText, szRebelCommandAgentMissionsText[RCAMT_DISRUPT_ASD_TITLE]); break;
|
||||
case RCAM_FORGE_TRANSPORT_ORDERS: swprintf(sText, szRebelCommandAgentMissionsText[RCAMT_FORGE_TRANSPORT_ORDERS_TITLE]); break;
|
||||
case RCAM_GET_ENEMY_MOVEMENT_TARGETS: swprintf(sText, szRebelCommandAgentMissionsText[RCAMT_GET_ENEMY_MOVEMENT_TARGETS_TITLE]); break;
|
||||
case RCAM_IMPROVE_LOCAL_SHOPS: swprintf(sText, szRebelCommandAgentMissionsText[RCAMT_IMPROVE_LOCAL_SHOPS_TITLE]); break;
|
||||
case RCAM_REDUCE_STRATEGIC_DECISION_SPEED: swprintf(sText, szRebelCommandAgentMissionsText[RCAMT_REDUCE_STRATEGIC_DECISION_SPEED_TITLE]); break;
|
||||
@@ -2241,6 +2246,7 @@ BOOLEAN SetupMissionAgentBox(UINT16 x, UINT16 y, INT8 index)
|
||||
{
|
||||
case RCAM_DEEP_DEPLOYMENT: missionDurationBase = gRebelCommandSettings.iDeepDeploymentDuration; break;
|
||||
case RCAM_DISRUPT_ASD: missionDurationBase = gRebelCommandSettings.iDisruptAsdDuration; break;
|
||||
case RCAM_FORGE_TRANSPORT_ORDERS: missionDurationBase = 1; break; // instant effect
|
||||
case RCAM_GET_ENEMY_MOVEMENT_TARGETS: missionDurationBase = gRebelCommandSettings.iGetEnemyMovementTargetsDuration; break;
|
||||
case RCAM_IMPROVE_LOCAL_SHOPS: missionDurationBase = gRebelCommandSettings.iImproveLocalShopsDuration; break;
|
||||
case RCAM_REDUCE_STRATEGIC_DECISION_SPEED: missionDurationBase = gRebelCommandSettings.iReduceStrategicDecisionSpeedDuration; break;
|
||||
@@ -2264,6 +2270,7 @@ BOOLEAN SetupMissionAgentBox(UINT16 x, UINT16 y, INT8 index)
|
||||
{
|
||||
case RCAM_DEEP_DEPLOYMENT: missionSuccessChanceBase = gRebelCommandSettings.iDeepDeploymentSuccessChance; break;
|
||||
case RCAM_DISRUPT_ASD: missionSuccessChanceBase = gRebelCommandSettings.iDisruptAsdSuccessChance; break;
|
||||
case RCAM_FORGE_TRANSPORT_ORDERS: missionSuccessChanceBase = gRebelCommandSettings.iForgeTransportOrdersSuccessChance; break;
|
||||
case RCAM_GET_ENEMY_MOVEMENT_TARGETS: missionSuccessChanceBase = gRebelCommandSettings.iGetEnemyMovementTargetsSuccessChance; break;
|
||||
case RCAM_IMPROVE_LOCAL_SHOPS: missionSuccessChanceBase = gRebelCommandSettings.iImproveLocalShopsSuccessChance; break;
|
||||
case RCAM_REDUCE_STRATEGIC_DECISION_SPEED: missionSuccessChanceBase = gRebelCommandSettings.iReduceStrategicDecisionSpeedSuccessChance; break;
|
||||
@@ -2284,6 +2291,7 @@ BOOLEAN SetupMissionAgentBox(UINT16 x, UINT16 y, INT8 index)
|
||||
{
|
||||
case RCAM_DEEP_DEPLOYMENT: swprintf(sText, szRebelCommandAgentMissionsText[RCAMT_DEEP_DEPLOYMENT_DESC]); break;
|
||||
case RCAM_DISRUPT_ASD: swprintf(sText, szRebelCommandAgentMissionsText[RCAMT_DISRUPT_ASD_DESC]); break;
|
||||
case RCAM_FORGE_TRANSPORT_ORDERS: swprintf(sText, szRebelCommandAgentMissionsText[RCAMT_FORGE_TRANSPORT_ORDERS_DESC]); break;
|
||||
case RCAM_GET_ENEMY_MOVEMENT_TARGETS: swprintf(sText, szRebelCommandAgentMissionsText[RCAMT_GET_ENEMY_MOVEMENT_TARGETS_DESC]); break;
|
||||
case RCAM_IMPROVE_LOCAL_SHOPS: swprintf(sText, szRebelCommandAgentMissionsText[RCAMT_IMPROVE_LOCAL_SHOPS_DESC]); break;
|
||||
case RCAM_REDUCE_STRATEGIC_DECISION_SPEED: swprintf(sText, szRebelCommandAgentMissionsText[RCAMT_REDUCE_STRATEGIC_DECISION_SPEED_DESC]); break;
|
||||
@@ -2454,6 +2462,12 @@ BOOLEAN SetupMissionAgentBox(UINT16 x, UINT16 y, INT8 index)
|
||||
}
|
||||
}
|
||||
|
||||
case RCAM_FORGE_TRANSPORT_ORDERS:
|
||||
{
|
||||
// no special modifiers. included for completeness.
|
||||
}
|
||||
break;
|
||||
|
||||
case RCAM_GET_ENEMY_MOVEMENT_TARGETS:
|
||||
{
|
||||
// no special modifiers. included for completeness.
|
||||
@@ -2610,7 +2624,13 @@ BOOLEAN SetupMissionAgentBox(UINT16 x, UINT16 y, INT8 index)
|
||||
swprintf(sText, szRebelCommandText[RCT_MISSION_CANT_START_CONTRACT_EXPIRING]);
|
||||
}
|
||||
}
|
||||
else if (agentIndex[index] == mercs.size() && rebelCommandSaveInfo.availableMissions[index] == RCAM_SEND_SUPPLIES_TO_TOWN)
|
||||
else if (agentIndex[index] == mercs.size() &&
|
||||
(
|
||||
rebelCommandSaveInfo.availableMissions[index] == RCAM_SEND_SUPPLIES_TO_TOWN ||
|
||||
rebelCommandSaveInfo.availableMissions[index] == RCAM_FORGE_TRANSPORT_ORDERS
|
||||
)
|
||||
|
||||
)
|
||||
{
|
||||
canStartMission = FALSE;
|
||||
swprintf(sText, szRebelCommandText[RCT_MISSION_CANT_USE_REBEL_AGENT]);
|
||||
@@ -2847,6 +2867,14 @@ void PrepareMission(INT8 index)
|
||||
}
|
||||
break;
|
||||
|
||||
case RCAM_FORGE_TRANSPORT_ORDERS:
|
||||
{
|
||||
missionTitle = RCAMT_FORGE_TRANSPORT_ORDERS_TITLE;
|
||||
missionSuccessChance = gRebelCommandSettings.iForgeTransportOrdersSuccessChance;
|
||||
missionDuration = 12;
|
||||
}
|
||||
break;
|
||||
|
||||
case RCAM_GET_ENEMY_MOVEMENT_TARGETS:
|
||||
{
|
||||
missionTitle = RCAMT_GET_ENEMY_MOVEMENT_TARGETS_TITLE;
|
||||
@@ -3897,6 +3925,7 @@ void DailyUpdate()
|
||||
{
|
||||
if (i == RCAM_SOLDIER_BOUNTIES_KINGPIN && !(CheckFact(FACT_KINGPIN_INTRODUCED_SELF, 0) == TRUE && CheckFact(FACT_KINGPIN_DEAD, 0) == FALSE && CheckFact(FACT_KINGPIN_IS_ENEMY, 0) == FALSE && CurrentPlayerProgressPercentage() >= 30)) continue;
|
||||
else if (i == RCAM_DISRUPT_ASD && gGameExternalOptions.fASDActive == FALSE) continue;
|
||||
else if (i == RCAM_FORGE_TRANSPORT_ORDERS && gGameExternalOptions.fStrategicTransportGroupsEnabled == FALSE) continue;
|
||||
|
||||
validMissions.insert(static_cast<RebelCommandAgentMissions>(i));
|
||||
}
|
||||
@@ -4299,6 +4328,16 @@ void SetupInfo()
|
||||
{0, 0, 0, 0},
|
||||
{0, MissionHelpers::DISRUPT_ASD_STEAL_FUEL, MissionHelpers::DISRUPT_ASD_DESTROY_RESERVES, 0}
|
||||
});
|
||||
//RCAM_FORGE_TRANSPORT_ORDERS
|
||||
MissionHelpers::missionInfo.push_back(
|
||||
{
|
||||
{COVERT_NT },
|
||||
{-1},
|
||||
{0},
|
||||
{0.f},
|
||||
{0},
|
||||
{0}
|
||||
});
|
||||
//RCAM_GET_ENEMY_MOVEMENT_TARGETS
|
||||
MissionHelpers::missionInfo.push_back(
|
||||
{
|
||||
@@ -4902,6 +4941,7 @@ void HandleStrategicEvent(const UINT32 eventParam)
|
||||
{
|
||||
case RCAM_DEEP_DEPLOYMENT:
|
||||
case RCAM_DISRUPT_ASD:
|
||||
case RCAM_FORGE_TRANSPORT_ORDERS:
|
||||
case RCAM_GET_ENEMY_MOVEMENT_TARGETS:
|
||||
case RCAM_IMPROVE_LOCAL_SHOPS:
|
||||
case RCAM_REDUCE_STRATEGIC_DECISION_SPEED:
|
||||
@@ -4926,7 +4966,15 @@ void HandleStrategicEvent(const UINT32 eventParam)
|
||||
if (validMission)
|
||||
{
|
||||
const UINT32 activatedMissionParam = SerialiseMissionSecondEvent(evt1.sentGenericRebelAgent, evt1.mercProfileId, mission, extraBits);
|
||||
AddStrategicEvent(EVENT_REBELCOMMAND, GetWorldTotalMin() + 60 * evt1.missionDurationInHours, activatedMissionParam);
|
||||
if (mission == RCAM_FORGE_TRANSPORT_ORDERS)
|
||||
{
|
||||
// don't send a follow-up event for instant-result missions
|
||||
}
|
||||
else
|
||||
{
|
||||
AddStrategicEvent(EVENT_REBELCOMMAND, GetWorldTotalMin() + 60 * evt1.missionDurationInHours, activatedMissionParam);
|
||||
missionMap.insert(std::make_pair(mission, activatedMissionParam));
|
||||
}
|
||||
|
||||
if (!evt1.sentGenericRebelAgent)
|
||||
{
|
||||
@@ -4935,6 +4983,11 @@ void HandleStrategicEvent(const UINT32 eventParam)
|
||||
SOLDIERTYPE* pSoldier = MercPtrs[i];
|
||||
if (pSoldier->ubProfile == evt1.mercProfileId)
|
||||
{
|
||||
if (mission == RCAM_FORGE_TRANSPORT_ORDERS)
|
||||
{
|
||||
ForceDeployTransportGroup(SECTOR(pSoldier->sSectorX, pSoldier->sSectorY));
|
||||
}
|
||||
|
||||
// mission successful! give some experience pts
|
||||
StatChange(pSoldier, LDRAMT, 20, FROM_SUCCESS);
|
||||
StatChange(pSoldier, WISDOMAMT, 15, FROM_SUCCESS);
|
||||
@@ -4943,7 +4996,6 @@ void HandleStrategicEvent(const UINT32 eventParam)
|
||||
}
|
||||
}
|
||||
|
||||
missionMap.insert(std::make_pair(mission, activatedMissionParam));
|
||||
swprintf(msgBoxText, szRebelCommandText[RCT_MISSION_SUCCESS], szRebelCommandAgentMissionsText[evt1.missionId * 2]);
|
||||
swprintf(screenMsgText, szRebelCommandText[RCT_MISSION_SUCCESS], szRebelCommandAgentMissionsText[evt1.missionId * 2]);
|
||||
ScreenMsg(FONT_MCOLOR_LTGREEN, MSG_INTERFACE, screenMsgText);
|
||||
|
||||
@@ -78,6 +78,7 @@ enum RebelCommandAgentMissions
|
||||
RCAM_NONE = -1,
|
||||
RCAM_DEEP_DEPLOYMENT = 0,
|
||||
RCAM_DISRUPT_ASD, // only available if ASD enabled
|
||||
RCAM_FORGE_TRANSPORT_ORDERS,
|
||||
RCAM_GET_ENEMY_MOVEMENT_TARGETS, // aka Strategic Intel
|
||||
RCAM_IMPROVE_LOCAL_SHOPS,
|
||||
RCAM_REDUCE_STRATEGIC_DECISION_SPEED, // aka Slower Strategic Decisions
|
||||
|
||||
@@ -246,13 +246,13 @@ BOOLEAN ARMoveBestMilitiaManFromAdjacentSector(INT16 sMapX, INT16 sMapY)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GROUP* GetNonPlayerGroupInSector( INT16 sMapX, INT16 sMapY, UINT8 usTeam )
|
||||
GROUP* GetNonPlayerGroupInSectorForReinforcement( INT16 sMapX, INT16 sMapY, UINT8 usTeam )
|
||||
{
|
||||
GROUP *curr;
|
||||
curr = gpGroupList;
|
||||
while( curr )
|
||||
{
|
||||
if ( curr->ubSectorX == sMapX && curr->ubSectorY == sMapY && curr->usGroupTeam == usTeam && curr->ubGroupID )
|
||||
if ( curr->ubSectorX == sMapX && curr->ubSectorY == sMapY && curr->usGroupTeam == usTeam && curr->ubGroupID && (curr->usGroupTeam != ENEMY_TEAM || curr->pEnemyGroup->ubIntention != TRANSPORT) )
|
||||
return curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
@@ -280,7 +280,7 @@ UINT8 DoReinforcementAsPendingNonPlayer( INT16 sMapX, INT16 sMapY, UINT8 usTeam
|
||||
|
||||
for( ubIndex = 0; ubIndex < ubDirNumber; ++ubIndex )
|
||||
{
|
||||
while ( (pGroup = GetNonPlayerGroupInSector( SECTORX( pusMoveDir[ubIndex][0] ), SECTORY( pusMoveDir[ubIndex][0] ), usTeam )) != NULL )
|
||||
while ( (pGroup = GetNonPlayerGroupInSectorForReinforcement( SECTORX( pusMoveDir[ubIndex][0] ), SECTORY( pusMoveDir[ubIndex][0] ), usTeam )) != NULL )
|
||||
{
|
||||
pGroup->ubPrevX = pGroup->ubSectorX;
|
||||
pGroup->ubPrevY = pGroup->ubSectorY;
|
||||
|
||||
@@ -12,6 +12,6 @@ UINT8 NumEnemiesInFiveSectors( INT16 sMapX, INT16 sMapY );
|
||||
//For Tactical
|
||||
UINT8 DoReinforcementAsPendingNonPlayer( INT16 sMapX, INT16 sMapY, UINT8 usTeam );
|
||||
void AddPossiblePendingMilitiaToBattle();
|
||||
GROUP* GetNonPlayerGroupInSector( INT16 sMapX, INT16 sMapY, UINT8 usTeam );
|
||||
GROUP* GetNonPlayerGroupInSectorForReinforcement( INT16 sMapX, INT16 sMapY, UINT8 usTeam );
|
||||
|
||||
#endif
|
||||
+102
-73
@@ -33,6 +33,9 @@
|
||||
#include "interface dialogue.h"
|
||||
#include "ASD.h" // added by Flugente
|
||||
#include "Rebel Command.h"
|
||||
#include "Game Event Hook.h"
|
||||
#include "Strategic Town Loyalty.h"
|
||||
#include "Strategic Transport Groups.h"
|
||||
|
||||
#include "GameInitOptionsScreen.h"
|
||||
|
||||
@@ -488,7 +491,6 @@ extern INT16 sWorldSectorLocationOfFirstBattle;
|
||||
|
||||
void ReassignAIGroup( GROUP **pGroup );
|
||||
void TransferGroupToPool( GROUP **pGroup );
|
||||
void SendGroupToPool( GROUP **pGroup );
|
||||
|
||||
//Simply orders all garrisons to take troops from the patrol groups and send the closest troops from them. Any garrison,
|
||||
//whom there request isn't fulfilled (due to lack of troops), will recieve their reinforcements from the queen (P3).
|
||||
@@ -2418,6 +2420,11 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic5");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pGroup->pEnemyGroup->ubIntention == TRANSPORT)
|
||||
{
|
||||
ProcessTransportGroupReachedDestination(pGroup);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{ //This is a floating group at his final destination...
|
||||
if( pGroup->pEnemyGroup->ubIntention != STAGING && pGroup->pEnemyGroup->ubIntention != REINFORCEMENTS )
|
||||
@@ -3458,7 +3465,7 @@ void EvaluateQueenSituation()
|
||||
dEnemyGeneralsSpeedupFactor *= RebelCommand::GetStrategicDecisionSpeedModifier();
|
||||
|
||||
uiOffset += dEnemyGeneralsSpeedupFactor * (zDiffSetting[gGameOptions.ubDifficultyLevel].iBaseDelayInMinutesBetweenEvaluations + Random( zDiffSetting[gGameOptions.ubDifficultyLevel].iEvaluationDelayVariance ));
|
||||
|
||||
|
||||
// Check/update reinforcements pool if old behavior is enabled
|
||||
if ( !gfUnlimitedTroops && zDiffSetting[gGameOptions.ubDifficultyLevel].iQueenPoolIncrementDaysPerDifficultyLevel == 0 )
|
||||
{
|
||||
@@ -3488,88 +3495,88 @@ void EvaluateQueenSituation()
|
||||
// Gradually promote any remaining admins into troops
|
||||
UpgradeAdminsToTroops();
|
||||
|
||||
if( ( giRequestPoints <= 0 ) || ( ( giReinforcementPoints <= 0 ) && ( giReinforcementPool <= 0 ) ) )
|
||||
{ //we either have no reinforcements or request for reinforcements.
|
||||
return;
|
||||
}
|
||||
// consider deploying a transport group
|
||||
ExecuteStrategicAIAction( NPC_ACTION_DEPLOY_TRANSPORT_GROUP, 0, 0 );
|
||||
|
||||
// anv: only consider garrisons and patrols that can be reinforced
|
||||
// otherwise unreinforcable groups will stall the rest, effectively breaking entire system
|
||||
|
||||
Ensure_RepairedGarrisonGroup( &gGarrisonGroup, &giGarrisonArraySize ); /* added NULL fix, 2007-03-03, Sgt. Kolja */
|
||||
|
||||
for( i = 0; i < giGarrisonArraySize; i++ )
|
||||
// we either have reinforcements or a request for reinforcements
|
||||
if (giRequestPoints > 0 && (giReinforcementPoints > 0 || giReinforcementPool > 0))
|
||||
{
|
||||
RecalculateGarrisonWeight( i );
|
||||
iWeight = gGarrisonGroup[ i ].bWeight;
|
||||
if( iWeight > 0 )
|
||||
// anv: only consider garrisons and patrols that can be reinforced
|
||||
// otherwise unreinforcable groups will stall the rest, effectively breaking entire system
|
||||
|
||||
Ensure_RepairedGarrisonGroup( &gGarrisonGroup, &giGarrisonArraySize ); /* added NULL fix, 2007-03-03, Sgt. Kolja */
|
||||
|
||||
for( i = 0; i < giGarrisonArraySize; i++ )
|
||||
{
|
||||
if( !gGarrisonGroup[ i ].ubPendingGroupID &&
|
||||
EnemyPermittedToAttackSector( NULL, gGarrisonGroup[ i ].ubSectorID ) &&
|
||||
GarrisonRequestingMinimumReinforcements( i ) )
|
||||
RecalculateGarrisonWeight( i );
|
||||
iWeight = gGarrisonGroup[ i ].bWeight;
|
||||
if( iWeight > 0 )
|
||||
{
|
||||
if( ReinforcementsApproved( i, &usDefencePoints ) )
|
||||
if( !gGarrisonGroup[ i ].ubPendingGroupID &&
|
||||
EnemyPermittedToAttackSector( NULL, gGarrisonGroup[ i ].ubSectorID ) &&
|
||||
GarrisonRequestingMinimumReinforcements( i ) )
|
||||
{
|
||||
iApplicableGarrisonIds[iApplicableGarrisons] = i;
|
||||
iApplicableGarrisons++;
|
||||
iApplicableRequestPoints += gGarrisonGroup[ i ].bWeight;
|
||||
if( ReinforcementsApproved( i, &usDefencePoints ) )
|
||||
{
|
||||
iApplicableGarrisonIds[iApplicableGarrisons] = i;
|
||||
iApplicableGarrisons++;
|
||||
iApplicableRequestPoints += gGarrisonGroup[ i ].bWeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( i = 0; i < giPatrolArraySize; i++ )
|
||||
{
|
||||
RecalculatePatrolWeight( i );
|
||||
iWeight = gPatrolGroup[ i ].bWeight;
|
||||
if( iWeight > 0 )
|
||||
for( i = 0; i < giPatrolArraySize; i++ )
|
||||
{
|
||||
if( !gPatrolGroup[ i ].ubPendingGroupID && PatrolRequestingMinimumReinforcements( i ) )
|
||||
RecalculatePatrolWeight( i );
|
||||
iWeight = gPatrolGroup[ i ].bWeight;
|
||||
if( iWeight > 0 )
|
||||
{
|
||||
iApplicablePatrolIds[iApplicablePatrols] = i;
|
||||
iApplicablePatrols++;
|
||||
iApplicableRequestPoints += gPatrolGroup[ i ].bWeight;
|
||||
if( !gPatrolGroup[ i ].ubPendingGroupID && PatrolRequestingMinimumReinforcements( i ) )
|
||||
{
|
||||
iApplicablePatrolIds[iApplicablePatrols] = i;
|
||||
iApplicablePatrols++;
|
||||
iApplicableRequestPoints += gPatrolGroup[ i ].bWeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !iApplicableRequestPoints )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//now randomly choose who gets the reinforcements.
|
||||
// giRequestPoints is the combined sum of all the individual weights of all garrisons and patrols requesting reinforcements
|
||||
//iRandom = Random( giRequestPoints );
|
||||
iRandom = Random( iApplicableRequestPoints );
|
||||
|
||||
iOrigRequestPoints = giRequestPoints; // debug only!
|
||||
|
||||
//go through garrisons first
|
||||
for( i = 0; i < iApplicableGarrisons; i++ )
|
||||
{
|
||||
iSumOfAllWeights += iWeight; // debug only!
|
||||
iWeight = gGarrisonGroup[ iApplicableGarrisonIds[i] ].bWeight;
|
||||
if( iRandom < iWeight )
|
||||
if( iApplicableRequestPoints )
|
||||
{
|
||||
//This is the group that gets the reinforcements!
|
||||
if ( SendReinforcementsForGarrison( iApplicableGarrisonIds[i] , usDefencePoints, NULL ) )
|
||||
return;
|
||||
}
|
||||
iRandom -= iWeight;
|
||||
}
|
||||
//now randomly choose who gets the reinforcements.
|
||||
// giRequestPoints is the combined sum of all the individual weights of all garrisons and patrols requesting reinforcements
|
||||
//iRandom = Random( giRequestPoints );
|
||||
iRandom = Random( iApplicableRequestPoints );
|
||||
|
||||
//go through the patrol groups
|
||||
for( i = 0; i < iApplicablePatrols; i++ )
|
||||
{
|
||||
iSumOfAllWeights += iWeight; // debug only!
|
||||
iWeight = gPatrolGroup[ iApplicablePatrolIds[i] ].bWeight;
|
||||
if( iRandom < iWeight )
|
||||
{
|
||||
//This is the group that gets the reinforcements!
|
||||
if ( SendReinforcementsForPatrol( iApplicablePatrolIds[i], NULL ) )
|
||||
return;
|
||||
iOrigRequestPoints = giRequestPoints; // debug only!
|
||||
|
||||
//go through garrisons first
|
||||
for( i = 0; i < iApplicableGarrisons; i++ )
|
||||
{
|
||||
iSumOfAllWeights += iWeight; // debug only!
|
||||
iWeight = gGarrisonGroup[ iApplicableGarrisonIds[i] ].bWeight;
|
||||
if( iRandom < iWeight )
|
||||
{
|
||||
//This is the group that gets the reinforcements!
|
||||
if ( SendReinforcementsForGarrison( iApplicableGarrisonIds[i] , usDefencePoints, NULL ) )
|
||||
return;
|
||||
}
|
||||
iRandom -= iWeight;
|
||||
}
|
||||
|
||||
//go through the patrol groups
|
||||
for( i = 0; i < iApplicablePatrols; i++ )
|
||||
{
|
||||
iSumOfAllWeights += iWeight; // debug only!
|
||||
iWeight = gPatrolGroup[ iApplicablePatrolIds[i] ].bWeight;
|
||||
if( iRandom < iWeight )
|
||||
{
|
||||
//This is the group that gets the reinforcements!
|
||||
if ( SendReinforcementsForPatrol( iApplicablePatrolIds[i], NULL ) )
|
||||
return;
|
||||
}
|
||||
iRandom -= iWeight;
|
||||
}
|
||||
}
|
||||
iRandom -= iWeight;
|
||||
}
|
||||
|
||||
ValidateWeights( 27 );
|
||||
@@ -5125,7 +5132,7 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
|
||||
if ( ubNumSoldiers )
|
||||
{
|
||||
InitializeGroup(GROUP_TYPE_ATTACK, ubNumSoldiers, grouptroops[0], groupelites[0], grouprobots[0], groupjeeps[0], grouptanks[0], Random(10) < difficultyMod);
|
||||
totalusedsoldiers += grouptroops[0] + groupelites[0] + grouprobots[0], grouptanks[0] + groupjeeps[0];
|
||||
totalusedsoldiers += grouptroops[0] + groupelites[0] + grouprobots[0] + grouptanks[0] + groupjeeps[0];
|
||||
}
|
||||
|
||||
pGroup = CreateNewEnemyGroupDepartingFromSector( SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY ), 0, grouptroops[0], groupelites[0], grouprobots[0], grouptanks[0], groupjeeps[0] );
|
||||
@@ -5386,6 +5393,14 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
|
||||
gubNumAwareBattles = zDiffSetting[gGameOptions.ubDifficultyLevel].iNumAwareBattles;
|
||||
break;
|
||||
|
||||
case NPC_ACTION_DEPLOY_TRANSPORT_GROUP:
|
||||
DeployTransportGroup();
|
||||
break;
|
||||
|
||||
case NPC_ACTION_RETURN_TRANSPORT_GROUP:
|
||||
ReturnTransportGroup(option1);
|
||||
break;
|
||||
|
||||
default:
|
||||
ScreenMsg( FONT_RED, MSG_DEBUG, L"QueenAI failed to handle action code %d.", usActionCode );
|
||||
break;
|
||||
@@ -6403,8 +6418,14 @@ void UpgradeAdminsToTroops()
|
||||
// if there are any admins currently in this group
|
||||
if ( pGroup->pEnemyGroup->ubNumAdmins > 0 )
|
||||
{
|
||||
// skip transport groups
|
||||
if (pGroup->pEnemyGroup->ubIntention == TRANSPORT)
|
||||
{
|
||||
pGroup = pGroup->next;
|
||||
continue;
|
||||
}
|
||||
// if it's a patrol group
|
||||
if ( pGroup->pEnemyGroup->ubIntention == PATROL )
|
||||
else if ( pGroup->pEnemyGroup->ubIntention == PATROL )
|
||||
{
|
||||
sPatrolIndex = FindPatrolGroupIndexForGroupID( pGroup->ubGroupID );
|
||||
Assert( sPatrolIndex != -1 );
|
||||
@@ -6508,9 +6529,17 @@ INT16 FindGarrisonIndexForGroupIDPending( UINT8 ubGroupID )
|
||||
|
||||
void TransferGroupToPool( GROUP **pGroup )
|
||||
{
|
||||
//Madd: unlimited reinforcements?
|
||||
if ( !gfUnlimitedTroops )
|
||||
giReinforcementPool += (*pGroup)->ubGroupSize;
|
||||
if ((*pGroup)->usGroupTeam == ENEMY_TEAM)
|
||||
{
|
||||
//Madd: unlimited reinforcements?
|
||||
if ( !gfUnlimitedTroops )
|
||||
giReinforcementPool += (*pGroup)->ubGroupSize;
|
||||
|
||||
AddStrategicAIResources(ASD_ROBOT, (*pGroup)->pEnemyGroup->ubNumRobots);
|
||||
AddStrategicAIResources(ASD_JEEP, (*pGroup)->pEnemyGroup->ubNumJeeps);
|
||||
AddStrategicAIResources(ASD_TANK, (*pGroup)->pEnemyGroup->ubNumTanks);
|
||||
}
|
||||
|
||||
|
||||
RemovePGroup( *pGroup );
|
||||
*pGroup = NULL;
|
||||
|
||||
@@ -38,6 +38,7 @@ BOOLEAN StrategicAILookForAdjacentGroups( GROUP *pGroup );
|
||||
void RemoveGroupFromStrategicAILists( UINT8 ubGroupID );
|
||||
void RecalculateSectorWeight( UINT8 ubSectorID );
|
||||
void RecalculateGroupWeight( GROUP *pGroup );
|
||||
void SendGroupToPool( GROUP **pGroup );
|
||||
|
||||
BOOLEAN OkayForEnemyToMoveThroughSector( UINT8 ubSectorID );
|
||||
BOOLEAN EnemyPermittedToAttackSector( GROUP **pGroup, UINT8 ubSectorID );
|
||||
@@ -78,7 +79,8 @@ BOOLEAN PermittedToFillPatrolGroup( INT32 iPatrolID );
|
||||
enum GROUP_TYPE
|
||||
{
|
||||
GROUP_TYPE_ATTACK,
|
||||
GROUP_TYPE_PATROL
|
||||
GROUP_TYPE_PATROL,
|
||||
GROUP_TYPE_TRANSPORT
|
||||
};
|
||||
|
||||
void ASDInitializePatrolGroup(GROUP *pGroup);
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "Creature Spreading.h" // added by Flugente
|
||||
#include "MilitiaIndividual.h" // added by Flugente
|
||||
#include "Rebel Command.h"
|
||||
#include "Strategic Transport Groups.h"
|
||||
|
||||
#include "MilitiaSquads.h"
|
||||
#include "Vehicles.h"
|
||||
@@ -3635,7 +3636,10 @@ INT32 GetSectorMvtTimeForGroup( UINT8 ubSector, UINT8 ubDirection, GROUP *pGroup
|
||||
dEnemyGeneralsSpeedupFactor = max( 0.75f, dEnemyGeneralsSpeedupFactor - gStrategicStatus.usVIPsLeft * gGameExternalOptions.fEnemyGeneralStrategicMovementSpeedBonus );
|
||||
}
|
||||
|
||||
iBestTraverseTime = dEnemyGeneralsSpeedupFactor * iBestTraverseTime;
|
||||
// rftr: transport groups move slower than normal
|
||||
const FLOAT transportSpeedFactor = pGroup->pEnemyGroup->ubIntention == TRANSPORT ? 2.0f : 1.0f;
|
||||
|
||||
iBestTraverseTime = dEnemyGeneralsSpeedupFactor * transportSpeedFactor * iBestTraverseTime;
|
||||
|
||||
iBestTraverseTime = iBestTraverseTime * (100 + RebelCommand::GetHarriersSpeedPenalty(ubSector)) / 100;
|
||||
}
|
||||
@@ -3816,6 +3820,13 @@ void HandleArrivalOfReinforcements( GROUP *pGroup )
|
||||
ResetMortarsOnTeamCount();
|
||||
ResetNumSquadleadersInArmyGroup(); // added by SANDRO
|
||||
AddPossiblePendingEnemiesToBattle();
|
||||
|
||||
if (pGroup->pEnemyGroup->ubIntention == TRANSPORT)
|
||||
{
|
||||
// normally, transport groups can't reinforce, but this can be hit normally if a battle is occuring in a sector
|
||||
// where a transport group is moving into.
|
||||
UpdateTransportGroupInventory();
|
||||
}
|
||||
}
|
||||
else if ( pGroup->usGroupTeam == MILITIA_TEAM )
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@ enum //enemy intentions,
|
||||
PATROL, //enemy is moving around determining safe areas.
|
||||
REINFORCEMENTS, //enemy group has intentions to fortify position at final destination.
|
||||
ASSAULT, //enemy is ready to fight anything they encounter.
|
||||
TRANSPORT, //rftr: enemy is carrying out non-combat tasks, but still has an escort
|
||||
NUM_ENEMY_INTENTIONS
|
||||
};
|
||||
|
||||
@@ -109,6 +110,9 @@ typedef struct ENEMYGROUP
|
||||
#define GROUPFLAG_KNOWN_DIRECTION 0x00000080
|
||||
#define GROUPFLAG_KNOWN_NUMBER 0x00000100
|
||||
|
||||
// rftr: strategic transport group direction flag
|
||||
#define GROUPFLAG_TRANSPORT_ENROUTE 0x00000200
|
||||
|
||||
typedef struct GROUP
|
||||
{
|
||||
BOOLEAN fDebugGroup; //for testing purposes -- handled differently in certain cases.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,31 @@
|
||||
#ifndef _STRATEGIC_TRANSPORT_GROUPS_H
|
||||
#define _STRATEGIC_TRANSPORT_GROUPS_H
|
||||
|
||||
#include "Campaign Types.h"
|
||||
#include "Types.h"
|
||||
#include <map>
|
||||
|
||||
enum TransportGroupSectorInfo
|
||||
{
|
||||
TransportGroupSectorInfo_LocatedGroup = 0,
|
||||
TransportGroupSectorInfo_LocatedDestination,
|
||||
};
|
||||
|
||||
struct GROUP;
|
||||
|
||||
BOOLEAN DeployTransportGroup();
|
||||
BOOLEAN ForceDeployTransportGroup(UINT8 sectorId);
|
||||
BOOLEAN ReturnTransportGroup(INT32 groupId);
|
||||
void FillMapColoursForTransportGroups(INT32(&colorMap)[MAXIMUM_VALID_Y_COORDINATE][MAXIMUM_VALID_X_COORDINATE]);
|
||||
void ProcessTransportGroupReachedDestination(GROUP* pGroup);
|
||||
void UpdateTransportGroupInventory();
|
||||
|
||||
const std::map<UINT8, TransportGroupSectorInfo> GetTransportGroupSectorInfo();
|
||||
|
||||
void AddToTransportGroupMap(UINT8 groupId, int soldierClass, UINT8 amount);
|
||||
void ClearTransportGroupMap();
|
||||
|
||||
void NotifyTransportGroupDefeated();
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user