CvUnit::UnitPathTo(int, int, int, int, bool)
- Defined in
- CvUnit.cpp, line 23020
- Class
- CvUnit
- Hook name
CivHooks::CvUnit_UnitPathTo
Hand-placed hooks inside
A replacement for this function that does not call original stops these hooks from running.
Hooks
static bool BeforeCvUnit_UnitPathTo(CvUnit* self, int iX, int iY, int iFlags, int iPrevETA, bool bBuildingRoute, int& result);static void AfterCvUnit_UnitPathTo(CvUnit* self, int iX, int iY, int iFlags, int iPrevETA, bool bBuildingRoute, int& result);static int ReplaceCvUnit_UnitPathTo(int (*original)(CvUnit*, int, int, int, int, bool), CvUnit* self, int iX, int iY, int iFlags, int iPrevETA, bool bBuildingRoute);CivRegisterBefore<CivHooks::CvUnit_UnitPathTo>(host, &BeforeCvUnit_UnitPathTo);CivRegisterAfter<CivHooks::CvUnit_UnitPathTo>(host, &AfterCvUnit_UnitPathTo);CivRegisterReplace<CivHooks::CvUnit_UnitPathTo>(host, &ReplaceCvUnit_UnitPathTo);
Code
23017// Returns the number of turns it will take to reach the target. 23018// If no move was made it will return 0. 23019// If it can reach the target in one turn or less than one turn (i.e. not use up all its movement points) it will return 123020int CvUnit::UnitPathTo(int iX, int iY, int iFlags, int iPrevETA, bool bBuildingRoute)23021{23022 VALIDATE_OBJECT23023 CvPlot* pDestPlot;23024 CvPlot* pPathPlot = NULL;2302523026 LOG_UNIT_MOVES_MESSAGE_OSTR( std::string("UnitPathTo() : player ") << GET_PLAYER(getOwner()).getName() << std::string(" ") << getName() << std::string(" id=") << GetID() << std::string(" moving to ") << iX << std::string(", ") << iY);2302723028 if(at(iX, iY))23029 {23030 LOG_UNIT_MOVES_MESSAGE("Already at location");23031 return 0;23032 }2303323034 CvAssert(!IsBusy());23035 CvAssert(getOwner() != NO_PLAYER);2303623037 CvMap& kMap = GC.getMap();23038 pDestPlot = kMap.plot(iX, iY);23039 CvAssertMsg(pDestPlot != NULL, "DestPlot is not assigned a valid value");23040 if(!pDestPlot)23041 {23042 LOG_UNIT_MOVES_MESSAGE("Destination is not a valid plot location");23043 return 0;23044 }2304523046 CvAssertMsg(canMove(), "canAllMove is expected to be true");2304723048 if(getDomainType() == DOMAIN_AIR)23049 {23050 if(!canMoveInto(*pDestPlot))23051 {23052#if defined(CIV_HOST_API)23053 CivHandUnitOrdersCancelled(this, CIV_ORDERS_CANNOT_LAND);hand-placed hook: UnitOrdersCancelled23054#endif23055 return 0;23056 }2305723058 pPathPlot = pDestPlot;23059 m_kLastPath.clear(); // Not used by air units, keep it clear.23060 }23061 else23062 {23063 if(bBuildingRoute)23064 {23065 if(!GC.GetBuildRouteFinder().GeneratePath(getX(), getY(), iX, iY, getOwner()))23066 {23067 LOG_UNIT_MOVES_MESSAGE("Unable to generate path with BuildRouteFinder");23068#if defined(CIV_HOST_API)23069 CivHandUnitOrdersCancelled(this, CIV_ORDERS_NO_ROUTE_TO_BUILD);hand-placed hook: UnitOrdersCancelled23070#endif23071 return 0;23072 }2307323074 CvAStarNode* pNode = GC.GetBuildRouteFinder().GetLastNode();23075 if(pNode)23076 {23077 // walk the nodes until the next node23078 while(pNode->m_pParent && pNode->m_pParent->m_pParent)23079 {23080 pNode = pNode->m_pParent;23081 }2308223083 pPathPlot = GC.getMap().plotCheckInvalid(pNode->m_iX, pNode->m_iY);23084 }2308523086 if(!pPathPlot || !canMoveInto(*pPathPlot, iFlags | MOVEFLAG_DESTINATION))23087 {23088#if defined(CIV_HOST_API)23089 CivHandUnitOrdersCancelled(this, CIV_ORDERS_ROUTE_BLOCKED);hand-placed hook: UnitOrdersCancelled23090#endif23091 // add route interrupted23092 CvNotifications* pNotifications = GET_PLAYER(getOwner()).GetNotifications();23093 if(pNotifications)23094 {23095 CvString strBuffer = GetLocalizedText("TXT_KEY_NOTIFICATION_ROUTE_TO_CANCELLED");23096 CvString strSummary = GetLocalizedText("TXT_KEY_NOTIFICATION_SUMMARY_ROUTE_TO_CANCELLED");23097 pNotifications->Add(NOTIFICATION_GENERIC, strBuffer, strSummary, getX(), getY(), -1);23098 }2309923100#ifdef LOG_UNIT_MOVES23101 if(!pPathPlot)23102 LOG_UNIT_MOVES_MESSAGE("pPathPlot is NULL");23103 else23104 LOG_UNIT_MOVES_MESSAGE_OSTR(std::string("Cannot move into pPathPlot ") << pPathPlot->getX() << std::string(" ") << pPathPlot->getY());23105#endif23106 return 0;23107 }23108 }23109 else23110 {23111 bool bPathGenerated = UpdatePathCache(pDestPlot, iFlags);2311223113 if (!bPathGenerated)23114 {23115 LOG_UNIT_MOVES_MESSAGE("Unable to Generate path");23116#if defined(CIV_HOST_API)23117 CivHandUnitOrdersCancelled(this, CIV_ORDERS_NO_PATH);hand-placed hook: UnitOrdersCancelled23118#endif23119 return 0;23120 }2312123122 pPathPlot = GetPathFirstPlot();23123 }23124 }2312523126 bool bRejectMove = false;2312723128 // slewis'd23129 if(m_kLastPath.size() != 0)23130 {23131 const CvPathNode& kNode = m_kLastPath.front();23132 // If we were provided with a previous ETA, check against the new one and if it is two turns greater, cancel the move.23133 // We probably revealed something that is causing the unit to take longer to reach the target.23134 if(iPrevETA >= 0 && kNode.m_iData2 > iPrevETA + 2)23135 {23136 LOG_UNIT_MOVES_MESSAGE_OSTR(std::string("Rejecting move iPrevETA=") << iPrevETA << std::string(", m_iData2=") << kNode.m_iData2);23137#if defined(CIV_HOST_API)23138 CivHandUnitOrdersCancelled(this, CIV_ORDERS_PATH_LONGER);hand-placed hook: UnitOrdersCancelled23139#endif23140 bRejectMove = true;23141 }2314223143 if(kNode.m_iData2 == 1 && !canMoveInto(*pDestPlot, MOVEFLAG_PRETEND_CORRECT_EMBARK_STATE)) // if we should end our turn there this turn, but can't move into that tile23144 {23145 // this is a bit tricky23146 // we want to see if this move would be a capture move23147 // Since we can't move into the tile, there may be an enemy unit there23148 // We can't move into tiles with enemy combat units, so getBestDefender should return null on the tile23149 // If there is no defender but we can attack move into the tile, then we know that it is a civilian unit and we should be able to move into it23150 const UnitHandle pDefender = pDestPlot->getBestDefender(NO_PLAYER, getOwner(), this, true);23151 if(!pDefender && !pDestPlot->isEnemyCity(*this) && canMoveInto(*pDestPlot, MOVEFLAG_ATTACK | MOVEFLAG_PRETEND_CORRECT_EMBARK_STATE))23152 {23153 // Turn on ability to move into enemy units in this case so we can capture civilians23154 iFlags |= MOVE_UNITS_THROUGH_ENEMY;23155 }2315623157 const MissionData* pkMissionData = GetHeadMissionData();23158 CvAssertMsg(pkMissionData, "Unit mission is null. Need to rethink this code!");23159 if(pkMissionData != NULL && pkMissionData->iPushTurn != GC.getGame().getGameTurn())23160 {23161 LOG_UNIT_MOVES_MESSAGE_OSTR(std::string("Rejecting move pkMissionData->iPushTurn=") << pkMissionData->iPushTurn << std::string(", GC.getGame().getGameTurn()=") << GC.getGame().getGameTurn());23162#if defined(CIV_HOST_API)23163 CivHandUnitOrdersCancelled(this, CIV_ORDERS_DESTINATION_BLOCKED);hand-placed hook: UnitOrdersCancelled23164#endif23165 bRejectMove = true;23166 }23167 }2316823169 if(bRejectMove)23170 {23171 m_kLastPath.clear();23172 // slewis - perform its queued moves?23173 PublishQueuedVisualizationMoves();23174 return 0;23175 }23176 }23177 // end slewis'd2317823179 bool bEndMove = (pPathPlot == pDestPlot);23180 bool bMoved = UnitMove(pPathPlot, iFlags & MOVE_UNITS_THROUGH_ENEMY, NULL, bEndMove);2318123182 int iETA = 1;23183 uint uiCachedPathSize = m_kLastPath.size();23184 if (uiCachedPathSize)23185 {23186 iETA = m_kLastPath[ 0 ].m_iData2;23187 // Only do the shift if we actually moved23188 if (bMoved)23189 {23190 if(uiCachedPathSize > 1)23191 {23192 // Go back to front, adjusting the turns if needed23193 if (m_kLastPath[ uiCachedPathSize - 1 ].m_iData2 != m_kLastPath[ uiCachedPathSize - 2 ].m_iData2)23194 {23195 // We have exhausted a turns worth of nodes. Adjust all the others.23196 // KWG: It is unlikely that we will use this path again, because the unit is out of moves anyhow. Should we just clear the path and save time?23197 for (uint uiIndex = uiCachedPathSize - 1; uiIndex--; )23198 {23199 CvPathNode* pNode = &m_kLastPath[uiIndex];23200 if (pNode->m_iData2 > 0)23201 pNode->m_iData2 -= 1;23202 }23203 }2320423205 m_kLastPath.pop_back();23206 }23207 else23208 m_kLastPath.clear();23209 }23210 else23211 m_kLastPath.clear(); // Failed to move, recalculate.23212 }2321323214 return iETA;23215}
Calls
BaseVector::clearBaseVector::frontBaseVector::operator[]BaseVector::pop_backBaseVector::sizeCivHandUnitOrdersCancelled- CvAStar::GeneratePath(int, int, int, int, int, bool)
- CvAStar::GetLastNode()
- CvGame::getGameTurn()
- CvGlobals::GetBuildRouteFinder()
- CvGlobals::getGame()
- CvGlobals::getMap()
- CvMap::plot(int, int) const
- CvMap::plotCheckInvalid(int, int) const
- CvNotifications::Add(NotificationTypes, const char *, const char *, int, int, int, int)
- CvPlayer::GetNotifications() const
- CvPlayerAI::getPlayer(PlayerTypes)
- CvPlot::getBestDefender(PlayerTypes, PlayerTypes, const CvUnit *, bool, bool, bool, bool)
- CvPlot::isEnemyCity(const CvUnit &) const
CvString::operator const char *- CvUnit::at(int, int) const
- CvUnit::canMoveInto(const CvPlot &, byte) const
- CvUnit::getDomainType() const
- CvUnit::GetHeadMissionData()
- CvUnit::getOwner() const
- CvUnit::GetPathFirstPlot() const
- CvUnit::getX() const
- CvUnit::getY() const
- CvUnit::PublishQueuedVisualizationMoves()
- CvUnit::UnitMove(CvPlot *, bool, CvUnit *, bool)
- CvUnit::UpdatePathCache(CvPlot *, int)
FObjectHandle::operator!- GetLocalizedText(const char *)