Bazaar developer reference

CvTacticalAI::PlotSingleHexOperationMoves(CvAIEscortedOperation *)

Defined in
CvTacticalAI.cpp, line 4048
Class
CvTacticalAI
Hook name
CivHooks::CvTacticalAI_PlotSingleHexOperationMoves

Hooks

static bool BeforeCvTacticalAI_PlotSingleHexOperationMoves(CvTacticalAI* self, CvAIEscortedOperation* pOperation);static void AfterCvTacticalAI_PlotSingleHexOperationMoves(CvTacticalAI* self, CvAIEscortedOperation* pOperation);static void ReplaceCvTacticalAI_PlotSingleHexOperationMoves(void (*original)(CvTacticalAI*, CvAIEscortedOperation*), CvTacticalAI* self, CvAIEscortedOperation* pOperation);CivRegisterBefore<CivHooks::CvTacticalAI_PlotSingleHexOperationMoves>(host, &BeforeCvTacticalAI_PlotSingleHexOperationMoves);CivRegisterAfter<CivHooks::CvTacticalAI_PlotSingleHexOperationMoves>(host, &AfterCvTacticalAI_PlotSingleHexOperationMoves);CivRegisterReplace<CivHooks::CvTacticalAI_PlotSingleHexOperationMoves>(host, &ReplaceCvTacticalAI_PlotSingleHexOperationMoves);

Code

4047/// Move a single stack (civilian plus escort) to its destination4048void CvTacticalAI::PlotSingleHexOperationMoves(CvAIEscortedOperation* pOperation)4049{4050	int iUnitID;4051	UnitHandle pCivilian;4052	UnitHandle pEscort;4053	CvPlot* pCivilianMove;4054	CvPlot* pEscortMove;4055	bool bSaveMoves = false;40564057	// Simplification - assume only 1 army per operation now4058	if(pOperation->GetFirstArmyID() == -1)4059	{4060		return;4061	}4062	CvArmyAI* pThisArmy = m_pPlayer->getArmyAI(pOperation->GetFirstArmyID());4063	iUnitID = pThisArmy->GetFirstUnitID();4064	if(iUnitID != -1)4065	{4066		pCivilian = m_pPlayer->getUnit(iUnitID);4067	}40684069	if(!pCivilian)4070	{4071		return;4072	}40734074	// ESCORT AND CIVILIAN MEETING UP4075	if(pThisArmy->GetArmyAIState() == ARMYAISTATE_WAITING_FOR_UNITS_TO_REINFORCE ||4076	        pThisArmy->GetArmyAIState() == ARMYAISTATE_WAITING_FOR_UNITS_TO_CATCH_UP)4077	{4078		pEscort = m_pPlayer->getUnit(pThisArmy->GetNextUnitID());4079		if(!pEscort || pEscort->TurnProcessed())4080		{4081			// Escort died or was poached for other tactical action, operation will clean itself up when call CheckOnTarget()4082			return;4083		}40844085		// Check to make sure escort can get to civilian4086		if(pEscort->GeneratePath(pCivilian->plot()))4087		{4088			// He can, so have civilian remain in place4089			ExecuteMoveToPlot(pCivilian, pCivilian->plot());40904091			if(pThisArmy->GetNumSlotsFilled() > 1)4092			{4093				if(pEscort)4094				{4095					// Move escort over4096					ExecuteMoveToPlot(pEscort, pCivilian->plot());4097					if(GC.getLogging() && GC.getAILogging())4098					{4099						CvString strTemp;4100						CvString strLogString;4101						strTemp = GC.getUnitInfo(pEscort->getUnitType())->GetDescription();4102						strLogString.Format("Moving escorting %s to civilian for operation, Civilian X: %d, Civilian Y: %d, X: %d, Y: %d", strTemp.GetCString(), pCivilian->plot()->getX(), pCivilian->plot()->getY(), pEscort->getX(), pEscort->getY());4103						LogTacticalMessage(strLogString);4104					}4105				}4106			}4107		}41084109		// Find a new place to meet up, look at all hexes adjacent to civilian4110		else4111		{4112			for(int iI = 0; iI < NUM_DIRECTION_TYPES; iI++)4113			{4114				CvPlot* pPlot = plotDirection(pCivilian->getX(), pCivilian->getY(), ((DirectionTypes)iI));4115				if(pPlot != NULL)4116				{4117					// Has to be somewhere we can move and be empty of other units4118					if(pEscort->canEnterTerrain(*pPlot) && pEscort->canEnterTerritory(pPlot->getTeam()))4119					{4120						if(pPlot->getNumUnits() == 0)4121						{4122							if(pEscort->GeneratePath(pPlot) && pCivilian->GeneratePath(pPlot))4123							{4124								ExecuteMoveToPlot(pEscort, pPlot);4125								ExecuteMoveToPlot(pCivilian, pPlot);4126								if(GC.getLogging() && GC.getAILogging())4127								{4128									CvString strTemp;4129									CvString strLogString;4130									strTemp = GC.getUnitInfo(pEscort->getUnitType())->GetDescription();4131									strLogString.Format("Moving escorting %s to open hex, Open hex X: %d, Open hex Y: %d, X: %d, Y: %d", strTemp.GetCString(), pPlot->getX(), pPlot->getY(), pEscort->getX(), pEscort->getY());4132									LogTacticalMessage(strLogString);4133									strTemp = GC.getUnitInfo(pCivilian->getUnitType())->GetDescription();4134									strLogString.Format("Moving %s to open hex, Open hex X: %d, Open hex Y: %d, X: %d, Y: %d", strTemp.GetCString(), pPlot->getX(), pPlot->getY(), pCivilian->getX(), pCivilian->getY());4135									LogTacticalMessage(strLogString);4136								}4137								return;4138							}4139						}4140					}4141				}4142			}41434144			// Didn't find an alternative, must abort operation4145			pOperation->RetargetCivilian(pCivilian.pointer(), pThisArmy);4146			pCivilian->finishMoves();4147			pEscort->finishMoves();4148			if(GC.getLogging() && GC.getAILogging())4149			{4150				CvString strTemp;4151				CvString strLogString;4152				strLogString.Format("Retargeting civilian escort operation. No empty tile adjacent to civilian to meet.");4153				LogTacticalMessage(strLogString);4154			}4155		}4156	}41574158	// MOVING TO TARGET4159	else4160	{4161		// If we're not there yet, we have work to do (otherwise CheckOnTarget() will finish operation for us)4162		if(pCivilian->plot() != pOperation->GetTargetPlot())4163		{4164			// Look at where we'd move this turn taking units into consideration4165			int iFlags = 0;4166			if(pThisArmy->GetNumSlotsFilled() > 1)4167			{4168				iFlags = MOVE_UNITS_IGNORE_DANGER;4169			}41704171			// Handle case of no path found at all for civilian4172			if(!pCivilian->GeneratePath(pOperation->GetTargetPlot(), iFlags, false /*bReuse*/))4173			{4174				pOperation->RetargetCivilian(pCivilian.pointer(), pThisArmy);4175				pCivilian->finishMoves();4176				pEscort = m_pPlayer->getUnit(pThisArmy->GetNextUnitID());4177				if(pEscort)4178				{4179					pEscort->finishMoves();4180				}4181				if(GC.getLogging() && GC.getAILogging())4182				{4183					CvString strLogString;4184					strLogString.Format("Retargeting civilian escort operation (path lost to target), X: %d, Y: %d", pOperation->GetTargetPlot()->getX(), pOperation->GetTargetPlot()->getY());4185					LogTacticalMessage(strLogString);4186				}4187			}41884189			else4190			{4191				pCivilianMove = pCivilian->GetPathEndTurnPlot();4192				bSaveMoves = (pCivilianMove == pOperation->GetTargetPlot());4193				if(pThisArmy->GetNumSlotsFilled() == 1)4194				{4195					ExecuteMoveToPlot(pCivilian, pCivilianMove, bSaveMoves);4196					if(GC.getLogging() && GC.getAILogging())4197					{4198						CvString strLogString;4199						CvString strTemp;4200						strTemp = pCivilian->getUnitInfo().GetDescription();4201						strLogString.Format("Moving %s without escort to target, X: %d, Y: %d", strTemp.GetCString(), pCivilian->plot()->getX(), pCivilian->plot()->getY());4202						LogTacticalMessage(strLogString);4203					}4204				}42054206				else4207				{4208					pEscort = m_pPlayer->getUnit(pThisArmy->GetNextUnitID());42094210					// See if escort can move to the same location in one turn4211					if(TurnsToReachTarget(pEscort, pCivilianMove) <= 1)4212					{4213						ExecuteMoveToPlot(pCivilian, pCivilianMove, bSaveMoves);4214						ExecuteMoveToPlot(pEscort, pCivilianMove);4215						if(GC.getLogging() && GC.getAILogging())4216						{4217							CvString strLogString;4218							CvString strTemp;4219							strTemp = pCivilian->getUnitInfo().GetDescription();4220							strLogString.Format("Moving %s to target, X: %d, Y: %d", strTemp.GetCString(), pCivilian->getX(), pCivilian->getY());4221							LogTacticalMessage(strLogString);4222							strTemp = pEscort->getUnitInfo().GetDescription();4223							strLogString.Format("Moving escorting %s to target, X: %d, Y: %d", strTemp.GetCString(), pEscort->getX(), pEscort->getY());4224							LogTacticalMessage(strLogString);4225						}4226					}42274228					else4229					{4230						CvTacticalAnalysisCell* pCell = GC.getGame().GetTacticalAnalysisMap()->GetCell(pCivilianMove->GetPlotIndex());4231						UnitHandle pBlockingUnit = pCivilianMove->getBestDefender(m_pPlayer->GetID());42324233						// See if friendly blocking unit is ending the turn there, or if no blocking unit (which indicates this is somewhere civilian4234						// can move that escort can't -- like minor civ territory), then find a new path based on moving the escort4235						if(pCell->IsFriendlyTurnEndTile() || !pBlockingUnit)4236						{4237							if(!pEscort->GeneratePath(pOperation->GetTargetPlot(), 0, false /*bReuse*/))4238							{4239								pOperation->RetargetCivilian(pCivilian.pointer(), pThisArmy);4240								pCivilian->finishMoves();4241								pEscort->finishMoves();4242								if(GC.getLogging() && GC.getAILogging())4243								{4244									CvString strLogString;4245									strLogString.Format("Retargeting civilian escort operation (path lost to target), X: %d, Y: %d", pOperation->GetTargetPlot()->getX(), pOperation->GetTargetPlot()->getY());4246									LogTacticalMessage(strLogString);4247								}4248							}4249							else4250							{4251								pEscortMove = pCivilian->GetPathEndTurnPlot();4252								bSaveMoves = (pEscortMove == pOperation->GetTargetPlot());42534254								// See if civilian can move to the same location in one turn4255								if(TurnsToReachTarget(pCivilian, pEscortMove) <= 1)4256								{4257									ExecuteMoveToPlot(pEscort, pEscortMove);4258									ExecuteMoveToPlot(pCivilian, pEscortMove, bSaveMoves);4259									if(GC.getLogging() && GC.getAILogging())4260									{4261										CvString strLogString;4262										CvString strTemp;4263										strTemp = pEscort->getUnitInfo().GetDescription();4264										strLogString.Format("Moving escorting %s to target, X: %d, Y: %d", strTemp.GetCString(), pEscort->getX(), pEscort->getY());4265										LogTacticalMessage(strLogString);4266										strTemp = pCivilian->getUnitInfo().GetDescription();4267										strLogString.Format("Moving %s to target, X: %d, Y: %d", strTemp.GetCString(), pCivilian->getX(), pCivilian->getY());4268										LogTacticalMessage(strLogString);4269									}4270								}4271								else4272								{4273									// Didn't find an alternative, retarget operation4274									pOperation->RetargetCivilian(pCivilian.pointer(), pThisArmy);4275									pCivilian->finishMoves();4276									pEscort->finishMoves();4277									if(GC.getLogging() && GC.getAILogging())4278									{4279										CvString strLogString;4280										strLogString.Format("Retargeting civilian escort operation. Too many blocking units.");4281										LogTacticalMessage(strLogString);4282									}4283								}4284							}4285						}42864287						// Looks like we should be able to move the blocking unit out of the way4288						else4289						{4290							if(ExecuteMoveOfBlockingUnit(pBlockingUnit))4291							{4292								ExecuteMoveToPlot(pEscort, pCivilianMove);4293								ExecuteMoveToPlot(pCivilian, pCivilianMove, bSaveMoves);4294								if(GC.getLogging() && GC.getAILogging())4295								{4296									CvString strLogString;4297									CvString strTemp;4298									strTemp = pEscort->getUnitInfo().GetDescription();4299									strLogString.Format("Moving escorting %s to target, X: %d, Y: %d", strTemp.GetCString(), pEscort->getX(), pEscort->getY());4300									LogTacticalMessage(strLogString);4301									strTemp = pCivilian->getUnitInfo().GetDescription();4302									strLogString.Format("Moving %s to target, X: %d, Y: %d", strTemp.GetCString(), pCivilian->getX(), pCivilian->getY());4303									LogTacticalMessage(strLogString);4304								}4305							}4306							else4307							{43084309								// Didn't find an alternative, try retargeting operation4310								pOperation->RetargetCivilian(pCivilian.pointer(), pThisArmy);4311								pCivilian->finishMoves();4312								pEscort->finishMoves();4313								if(GC.getLogging() && GC.getAILogging())4314								{4315									CvString strLogString;4316									strLogString.Format("Retargeting civilian escort operation. Could not move blocking unit.");4317									LogTacticalMessage(strLogString);4318								}4319							}4320						}4321					}4322				}4323			}4324		}4325	}4326}

Calls

Called by