Hooks
static bool BeforeCvTacticalAI_PlotEnemyTerritoryOperationMoves(CvTacticalAI* self, CvAIEnemyTerritoryOperation* pOperation);static void AfterCvTacticalAI_PlotEnemyTerritoryOperationMoves(CvTacticalAI* self, CvAIEnemyTerritoryOperation* pOperation);static void ReplaceCvTacticalAI_PlotEnemyTerritoryOperationMoves(void (*original)(CvTacticalAI*, CvAIEnemyTerritoryOperation*), CvTacticalAI* self, CvAIEnemyTerritoryOperation* pOperation);CivRegisterBefore<CivHooks::CvTacticalAI_PlotEnemyTerritoryOperationMoves>(host, &BeforeCvTacticalAI_PlotEnemyTerritoryOperationMoves);CivRegisterAfter<CivHooks::CvTacticalAI_PlotEnemyTerritoryOperationMoves>(host, &AfterCvTacticalAI_PlotEnemyTerritoryOperationMoves);CivRegisterReplace<CivHooks::CvTacticalAI_PlotEnemyTerritoryOperationMoves>(host, &ReplaceCvTacticalAI_PlotEnemyTerritoryOperationMoves);
Code
4328/// Move a large army to its destination against an enemy target4329void CvTacticalAI::PlotEnemyTerritoryOperationMoves(CvAIEnemyTerritoryOperation* pOperation)4330{4331 // Simplification - assume only 1 army per operation now4332 if(pOperation->GetFirstArmyID() == -1)4333 {4334 return;4335 }4336 CvArmyAI* pThisArmy = m_pPlayer->getArmyAI(pOperation->GetFirstArmyID());43374338 m_OperationUnits.clear();4339 m_GeneralsToMove.clear();4340 m_ParatroopersToMove.clear();4341 pThisArmy->UpdateCheckpointTurns();43424343 // RECRUITING4344 if(pThisArmy->GetArmyAIState() == ARMYAISTATE_WAITING_FOR_UNITS_TO_REINFORCE)4345 {4346 // If no estimate for when recruiting will end, let the rest of the AI use these units4347 if(pThisArmy->GetTurnAtNextCheckpoint() == ARMYSLOT_UNKNOWN_TURN_AT_CHECKPOINT)4348 {4349 return;4350 }4351 else4352 {4353 for(int iI = 0; iI < pThisArmy->GetNumFormationEntries(); iI++)4354 {4355 CvArmyFormationSlot* pSlot = pThisArmy->GetFormationSlot(iI);4356 if(pSlot->GetUnitID() != NO_UNIT)4357 {4358 // See if we are just able to get to muster point in time. If so, time for us to head over there4359 UnitHandle pUnit = m_pPlayer->getUnit(pSlot->GetUnitID());4360 if(pUnit && !pUnit->TurnProcessed())4361 {4362 // Great general?4363 if(pUnit->IsGreatGeneral() || pUnit->IsGreatAdmiral())4364 {4365 if(pUnit->getMoves() > 0)4366 {4367 CvOperationUnit operationUnit;4368 operationUnit.SetUnitID(pUnit->GetID());4369 operationUnit.SetPosition((MultiunitPositionTypes)m_CachedInfoTypes[eMUPOSITION_CIVILIAN_SUPPORT]);4370 m_GeneralsToMove.push_back(operationUnit);4371 }4372 }43734374 else4375 {4376 CvMultiUnitFormationInfo* pkMultiUnitFormationInfo = GC.getMultiUnitFormationInfo(pThisArmy->GetFormationIndex());4377 if(pkMultiUnitFormationInfo)4378 {4379 const CvFormationSlotEntry& thisSlotEntry = pkMultiUnitFormationInfo->getFormationSlotEntry(iI);43804381 // Continue moving to target4382 if(pSlot->HasStartedOnOperation())4383 {4384 MoveWithFormation(pUnit, thisSlotEntry.m_ePositionType);4385 }43864387 else4388 {4389 // See if we are just able to get to muster point in time. If so, time for us to head over there4390 int iTurns = TurnsToReachTarget(pUnit, pOperation->GetMusterPlot(), true /*bReusePaths*/, true, true);4391 if(iTurns + GC.getGame().getGameTurn() >= pThisArmy->GetTurnAtNextCheckpoint())4392 {4393 pSlot->SetStartedOnOperation(true);4394 MoveWithFormation(pUnit, thisSlotEntry.m_ePositionType);4395 }4396 }4397 }4398 }4399 }4400 }4401 }4402 ExecuteGatherMoves(pThisArmy);4403 }4404 }44054406 // GATHERING FORCES4407 else if(pThisArmy->GetArmyAIState() == ARMYAISTATE_WAITING_FOR_UNITS_TO_CATCH_UP)4408 {4409 ClearEnemiesNearArmy(pThisArmy);44104411 // Request moves for all units4412 for(int iI = 0; iI < pThisArmy->GetNumFormationEntries(); iI++)4413 {4414 CvArmyFormationSlot* pSlot = pThisArmy->GetFormationSlot(iI);4415 if(pSlot->GetUnitID() != NO_UNIT)4416 {4417 UnitHandle pUnit = m_pPlayer->getUnit(pSlot->GetUnitID());4418 if(pUnit && !pUnit->TurnProcessed())4419 {4420 // Great general or admiral?4421 if(pUnit->IsGreatGeneral() || pUnit->IsGreatAdmiral())4422 {4423 if(pUnit->getMoves() > 0)4424 {4425 CvOperationUnit operationUnit;4426 operationUnit.SetUnitID(pUnit->GetID());4427 operationUnit.SetPosition((MultiunitPositionTypes)m_CachedInfoTypes[eMUPOSITION_CIVILIAN_SUPPORT]);4428 m_GeneralsToMove.push_back(operationUnit);4429 }4430 }44314432 else4433 {4434 pSlot->SetStartedOnOperation(true);4435 CvMultiUnitFormationInfo* pkMultiUnitFormationInfo = GC.getMultiUnitFormationInfo(pThisArmy->GetFormationIndex());4436 if(pkMultiUnitFormationInfo)4437 {4438 const CvFormationSlotEntry& thisSlotEntry = pkMultiUnitFormationInfo->getFormationSlotEntry(iI);4439 MoveWithFormation(pUnit, thisSlotEntry.m_ePositionType);4440 }4441 }4442 }4443 }4444 }4445 ExecuteGatherMoves(pThisArmy);4446 }44474448 // MOVING TO TARGET4449 else if(pThisArmy->GetArmyAIState() == ARMYAISTATE_MOVING_TO_DESTINATION)4450 {4451 // Update army's current location4452 CvPlot* pThisTurnTarget;4453 CvPlot* pClosestCurrentCOMonPath = NULL;4454 pThisTurnTarget = pOperation->ComputeCenterOfMassForTurn(pThisArmy, &pClosestCurrentCOMonPath);4455 if(pThisTurnTarget == NULL)4456 {4457 pOperation->SetToAbort(AI_ABORT_LOST_PATH);4458 return;4459 }44604461 pThisArmy->SetXY(pThisTurnTarget->getX(), pThisTurnTarget->getY());4462 ClearEnemiesNearArmy(pThisArmy);44634464 // Request moves for all units4465 for(int iI = 0; iI < pThisArmy->GetNumFormationEntries(); iI++)4466 {4467 CvArmyFormationSlot* pSlot = pThisArmy->GetFormationSlot(iI);4468 if(pSlot->GetUnitID() != NO_UNIT)4469 {4470 UnitHandle pUnit = m_pPlayer->getUnit(pSlot->GetUnitID());4471 if(pUnit && !pUnit->TurnProcessed())4472 {4473 // Great general?4474 if(pUnit->IsGreatGeneral() || pUnit->IsGreatAdmiral())4475 {4476 if(pUnit->getMoves() > 0)4477 {4478 CvOperationUnit operationUnit;4479 operationUnit.SetUnitID(pUnit->GetID());4480 operationUnit.SetPosition((MultiunitPositionTypes)m_CachedInfoTypes[eMUPOSITION_CIVILIAN_SUPPORT]);4481 m_GeneralsToMove.push_back(operationUnit);4482 }4483 }4484 else4485 {4486 CvMultiUnitFormationInfo* pkMultiUnitFormationInfo = GC.getMultiUnitFormationInfo(pThisArmy->GetFormationIndex());4487 if(pkMultiUnitFormationInfo)4488 {4489 const CvFormationSlotEntry& thisSlotEntry = pkMultiUnitFormationInfo->getFormationSlotEntry(iI);4490 MoveWithFormation(pUnit, thisSlotEntry.m_ePositionType);4491 }4492 }4493 }4494 }4495 }4496 ExecuteFormationMoves(pThisArmy, pClosestCurrentCOMonPath);4497 }44984499 if(m_ParatroopersToMove.size() > 0)4500 {4501 //MoveParatroopers(pThisArmy);4502 }45034504 if(m_GeneralsToMove.size() > 0)4505 {4506 MoveGreatGeneral(pThisArmy);4507 }4508}