infinite looping unit

vincentz

Programmer
Joined
Feb 4, 2009
Messages
3,614
Location
Denmark
Anyone knows what this code does?

Code:
template <class T>
T* FFreeListTrashArray<T>::getAt(int iID) const
{
    int iIndex;

    if ((iID == FFreeList::INVALID_INDEX) || (m_pArray == NULL))
    {
        return NULL;
    }

    iIndex = (iID & FLTA_INDEX_MASK);

    assert(iIndex >= 0);

    if ((iIndex <= m_iLastIndex) &&
        (m_pArray[iIndex].pData != NULL))
    {
        if (((iID & FLTA_ID_MASK) == 0) || (m_pArray[iIndex].pData->getID() == iID))
        {
            return m_pArray[iIndex].pData;
        }
    }

    return NULL;
}

My game went into an infinite loop at

if ((iID == FFreeList::INVALID_INDEX) || (m_pArray == NULL))
{
return NULL;
}

and before that it it went through

Code:
CvUnit* CvPlayer::getUnit(int iID) const
{
    return (m_units.getAt(iID));
}
Code:
CvUnit* getUnit(IDInfo unit)
{
    if ((unit.eOwner >= 0) && unit.eOwner < MAX_PLAYERS)
    {
        return (GET_PLAYER((PlayerTypes)unit.eOwner).getUnit(unit.iID));
    }

    return NULL;
}
Code:
bool CvSelectionGroup::canFight()
{
    CLLNode<IDInfo>* pUnitNode;
    CvUnit* pLoopUnit;

    pUnitNode = headUnitNode();

    while (pUnitNode != NULL)
    {
        pLoopUnit = ::getUnit(pUnitNode->m_data);
        pUnitNode = nextUnitNode(pUnitNode);

        if (pLoopUnit->canFight())
        {
            return true;
        }
    }

    return false;
}
and before that it was in int pathValid(FAStarNode* parent, FAStarNode* node, int data, const void* pointer, FAStar* finder)

I got this from the debugger:

0485A8D8 mov ecx,dword ptr [pToPlot]
0485A8DB call CvPlot::getY_INLINE (443035Ah)
0485A8E0 push eax
0485A8E1 mov ecx,dword ptr [pToPlot]
0485A8E4 call CvPlot::getX_INLINE (4432DA8h)
0485A8E9 push eax
0485A8EA mov ecx,dword ptr [pFromPlot]
0485A8ED call CvPlot::getY_INLINE (443035Ah)
0485A8F2 push eax
0485A8F3 mov ecx,dword ptr [pFromPlot]
0485A8F6 call CvPlot::getX_INLINE (4432DA8h)

But that means the to and from plot is the same, and I didnt get a failed assert on that :(
btw is it 146,63? Not sure I read the hex right.

As far as I can tell its a Marine trying to get on a transport, but why its stalled I have no idea.
 
Turns out it was one of these marines, though not the injured one, n Darius lower left city) that was holding back. It had UnitAI_Attack and was set for skipturn
Donno if that info helps.

iO1v0A8.png
 
The short answer is that CvSelectionGroup::canFight() tells if at least one unit in the group can fight.

Let's narrow it down to this:
PHP:
pUnitNode = headUnitNode(); // first unit in group
while (pUnitNode != NULL)
{
    pLoopUnit = ::getUnit(pUnitNode->m_data); // get the actual unit pointer
    pUnitNode = nextUnitNode(pUnitNode); // move to the next unit node
}
pUnitNode is first set to the first unit in the SelectionGroup. The loop then sets it to the next for each iteration. At some point it should have gone through all of them and pUnitNode should become NULL, hence ending the loop.

pLoopUnit is a unit pointer, which is set to each of the units in question. It uses getUnit(), which is why it's called for each iteration.

If it fails to end the while loop in CvSelectionGroup::canFight(), then the only explanation I can think of is that the Selection Group is corrupted and and the next chain goes A->B->C->D->B->C-> etc. I have no idea how that can happen, but it's the only way I can see an infinite loop in the code in question.

The functions called byCvSelectionGroup::canFight() doesn't contain loops and as such shouldn't contain infinite loops.

Alternatively the problem is thatCvSelectionGroup::canFight() is called in a loop. pathValid() doesn't contain any loops, which means that one should be called in a loop. The caller is the pathfinder inside the exe. We can assume that one doesn't suddenly introduce infinite loops or we would have encountered that long ago. It appears to be using A* pathfinding btw.

I'm not really sure what else to say about this based on what you have written. I wouldn't have expected an infinite loop in the code in question and I can't really think of a good reason why you would get one. Somehow I have a feeling that the cause of the infinite loop is not in the code you have written here, but that leaves the question: where is the offending code? I have no idea.
 
Back
Top Bottom