int CvPlayerAI::AI_getPlotDanger(CvPlot* pPlot, int iRange, bool bTestMoves) const
{
PROFILE_FUNC();
// Sanguo Mod Performance, start, added by poyuzhe 08.12.09
if (iRange == -1 || iRange > DANGER_RANGE)
{
iRange = DANGER_RANGE;
}
if (pPlot->getPlayerDangerCache(getID(), iRange) != MAX_SHORT)
{
return pPlot->getPlayerDangerCache(getID(), iRange);
}
else
{
CLLNode<IDInfo>* pUnitNode;
CvUnit* pLoopUnit;
CvPlot* pLoopPlot;
int iCount;
int iDistance;
int iBorderDanger;
int iDX, iDY;
CvArea *pPlotArea = pPlot->area();
iCount = 0;
iBorderDanger = 0;
/*if (iRange == -1)
{
iRange = DANGER_RANGE;
}*/
for (iDX = -(iRange); iDX <= iRange; iDX++)
{
for (iDY = -(iRange); iDY <= iRange; iDY++)
{
pLoopPlot = plotXY(pPlot->getX_INLINE(), pPlot->getY_INLINE(), iDX, iDY);
if (pLoopPlot != NULL)
{
if (pLoopPlot->area() == pPlotArea)
{
iDistance = stepDistance(pPlot->getX_INLINE(), pPlot->getY_INLINE(), pLoopPlot->getX_INLINE(), pLoopPlot->getY_INLINE());
if (atWar(pLoopPlot->getTeam(), getTeam()))
{
if (iDistance == 1)
{
iBorderDanger++;
}
else if ((iDistance == 2) && (pLoopPlot->isRoute()))
{
iBorderDanger++;
}
}
pUnitNode = pLoopPlot->headUnitNode();
while (pUnitNode != NULL)
{
pLoopUnit = ::getUnit(pUnitNode->m_data);
pUnitNode = pLoopPlot->nextUnitNode(pUnitNode);
if (pLoopUnit->isEnemy(getTeam()))
{
if (pLoopUnit->canAttack())
{
if (!(pLoopUnit->isInvisible(getTeam(), false)))
{
if (pLoopUnit->canMoveOrAttackInto(pPlot))
{
//if (!bTestMoves)
//{
//iCount++;
//}
//else
//{
int iDangerRange = pLoopUnit->baseMoves();
iDangerRange += ((pLoopPlot->isValidRoute(pLoopUnit)) ? 1 : 0);
if (iDangerRange >= iDistance)
{
iCount++;
}
//}
}
}
}
}
}
}
}
}
}
if (iBorderDanger > 0)
{
if (!isHuman() && !pPlot->isCity())
{
iCount += iBorderDanger;
}
}
pPlot->setPlayerDangerCache(getID(), iRange, std::min(iCount, MAX_SHORT));
return std::min(iCount, MAX_SHORT);
}
//return iCount;
// Sanguo Mod Performance, end
}
iDangerRange += ((pLoopPlot->isValidRoute(pLoopUnit)) ? 1 : 0);
bool CvPlot::isValidRoute(const CvUnit* pUnit) const
{
if (isRoute())
{
if (!pUnit->isEnemy(getTeam(), this) || pUnit->isEnemyRoute())
{
return true;
}
}
return false;
}
I think so. But if we check isHuman, then performance shouldn't be a problem, and we can call:So why does the +1 for standing on a road exist? Just because it might be connected by road to the target tile and it would be too expensive to actually check?
pLoopUnit->generatePath(pPlot, MOVE_MAX_MOVES, false, NULL, 1)
I'm assuming that most of the calls are coming from the various CvUnitAI::AI_*Move functions, which should never(?) be called on human units. Also, a generatePath call with iMaxPath=1 shouldn't take that long. It might even be OK for the AI, though with railroads and helicopters ...[...] Do you really think isHuman() would cut down performance costs enough? It's still just reduction by a constant factor. [...]
if(!bTestMoves)
return true;
else {
int iDangerRange = pLoopUnit->baseMoves();
if(pLoopPlot->isValidRoute(pLoopUnit, /*bAssumeRevealed=*/false))
iDangerRange++;
if(isHuman()) {
// Check path
return (iDistance <= 3 && pLoopUnit->generatePath(
pPlot, MOVE_MAX_MOVES | MOVE_IGNORE_DANGER,
false, NULL, 1, true));
}
if(iDangerRange >= iDistance)
return true;
}
bool CvUnit::generatePath(const CvPlot* pToPlot, int iFlags, bool bReuse, int* piPathTurns, int iMaxPath,
bool bUseTempFinder) const {
if(!bUseTempFinder)
return getGroup()->generatePath(plot(), pToPlot, iFlags, bReuse, piPathTurns, iMaxPath);
// Use a temp pathfinder, so as not to interfere with the normal one.
FAssert(!bReuse);
KmodPathFinder temp_finder;
temp_finder.SetSettings(getGroup(), iFlags, iMaxPath, GC.getMOVE_DENOMINATOR());
bool r = temp_finder.GeneratePath(pToPlot);
if(piPathTurns != NULL)
*piPathTurns = temp_finder.GetPathTurns();
return r;
}
bool KmodPathFinder::ProcessNode() {
OpenList_t::iterator best_it = open_list.end(); {
int iLowestCost = end_node ? end_node->m_iKnownCost : MAX_INT;
for (OpenList_t::iterator it = open_list.begin(); it != open_list.end(); ++it) {
if ((*it)->m_iTotalCost < iLowestCost &&
(settings.iMaxPath < 0 || (*it)->m_iData2 <= settings.iMaxPath)) {
best_it = it;
iLowestCost = (*it)->m_iTotalCost;
}
}
}
// if we didn't find a suitable node to process, then quit.
if (best_it == open_list.end())
return false;
[...]
// open a new node for each direction coming off the chosen node.
Interesting. Though ... if the warrior is there, threatening a worker, then no hypothetical unit should be needed, no? For my own mod, I needed a function to measure path lengths in between cities. At first, I had actually called generatePath on whatever units happened to be present in the city, so the RoM code would've been an improvement. By now, I have a proper solution based on an abandoned BBAI function (CvPlot.cpp#L3238).Btw, some mods (Rise of Mankind \ C2C ) have added the capability to generate paths for "hypothetical" units which could be used to detect threats more reliably. Then we could finally deal with the "double-woodsman promoted warrior steals a worker" tactic...
int CvCity::getCultureTimes100(PlayerTypes ePlayer) const
{
if (plot()->getCultureConversionPlayer() == ePlayer)
{
return (getActualTotalCultureTimes100() - getActualCultureTimes100(ePlayer)) * plot()->getCultureConversionRate() / 100 + getActualCultureTimes100(ePlayer);
}
return getActualCultureTimes100(ePlayer) * (100 - plot()->getCultureConversionRate()) / 100;
}
return (long)getActualCultureTimes100(ePlayer) * (100l - (long)plot()->getCultureConversionRate()) / 100l;
long lActualCultureTimes100 = (long)getActualCultureTimes100(ePlayer);
long lConversionRate = (long)plot()->getCultureConversionRate()
return lActualCultureTimes100 * (100l - lConversionRate) / 100l;
Sorry if I stole attention from your question, but if you need general information about adding units I suggest just looking into the tutorials section, which covers that kind of thing. I think several mods have already done the land transport unit in particular (e.g. the Humvee unit in History Rewritten, iirc) where you can look it up as an example.Hello, I am new to mods (and Civfanatics) and was wondering how difficult it is to create a new unit. At the moment I want to make a land troop transport such as a truck or helicopter that can carry infantry units. Or, perhaps a mod which is primarily oriented on additional late game stuff. I do not want 8,000 new units or a mod such as caveman2cosmos which takes me 6 months to play. I just want more unit variety within the modern era. As in different types of units, not extra eras or upgrades. Any suggestions would be mighty helpful. c: