Python error with AStarTools

Ninja2

Great Engineer
Joined
Nov 17, 2005
Messages
1,142
Location
Denmarkia
I'm getting this error in pythonerr.log:

Code:
Traceback (most recent call last):

  File "CvScreensInterface", line 899, in handleInput

  File "CvMainInterface", line 6667, in handleInput

  File "CvMainInterface", line 706, in getPlotListButtonName

  File "CvMainInterface", line 2100, in highlightMoves

  File "AStarTools", line 507, in highlightMoveArea

  File "AStarTools", line 464, in setPlotColor

  File "AStarTools", line 406, in checkUnit

ArgumentError: Python argument types in
    CyUnit.getSeeInvisibleType(CyUnit)
did not match C++ signature:
    getSeeInvisibleType(class CyUnit {lvalue}, int)
ERR: Python function handleInput failed, module CvScreensInterface

I'm guessing it's because I have defined more invisibility types than the standard BTS. How can I fix this glitch? I think it might be causing CTD's under certain circumstances.
 
Looks like that function was changed in BTS. The Warlords version didn't have a parameter. I'm going to be out of town until next week, and even then I probably won't have time to look at it. For now, take a look at the SDK's CvUnit and see what that parameter is supposed to be. Maybe you can figure out what to pass in.

Interesting that you are hitting it and no one else. Is there a special case it occurs? Although, it's possible that I just haven't noticed it, but the move highlighting works for me. BTW, this shouldn't cause a CTD. That would happen if a bad value was passed in, but BUG isn't passing anything in so the call doesn't go through.
 
Well, here is the function getSeeInvisibleType from the 3.17 source:

Code:
InvisibleTypes CvUnit::getSeeInvisibleType(int i) const
{
	return (InvisibleTypes)(m_pUnitInfo->getSeeInvisibleType(i));
}

In the XML, the tag SeeInvisible is not an int, it's a text string, like INVISIBLE_SUBMARINE. So what does this mean?
 
Have you had a chance to think this over, EF? :)
 
Weird, I didn't see your previous reply.

Strings like this in XML get converted to integers using CyGlobalContext.getInfoTypeForString(string): units, terrain types, yields, religions, buildings, everything. The integers they return go from 0 to one minus the number of related items. For example, if there are 53 buildings, the integers returned for all buildings are 0 to 52.

Thus, each element within a given set of related items has a unit integer identifier matching its unique string identifier.

In C++, each of these sets of numbers gets turned into a type such as InvisibleTypes with named constants for each defined in Enums.h (or some similar file). Given the function you posted, it looks like each UnitInfo has an array (list) of invisible types that it can see. My guess is that originally each unit could possibly see one invisible type, but with BTS they changed it so each unit could see more than one invisible type.

Thus CvUnit has getNumSeeInvisibleTypes() which returns the number of invisible types that unit can see, and then you can call getSeeInvisibleType(i) for each index.

Code:
for i in range(pUnit.getNumSeeInvisibleTypes()):
    eInvisibleType = pUnit.getSeeInvisibleType(i)
    # use eInvisibleType somehow

I'll take a look at AStarTools this week to see about fixing it. It should be a simple matter of looping over the types as above to check if a unit can see an invisible unit. That you added new types won't be the problem. The problem is that BTS changed the function parameter list but I didn't update AStarTools when I added it to BUG.
 
Alright, thanks for looking into this.
 
I haven't tested this yet, but maybe you can give it a shot. I've replaced lines 406-415 here

Code:
  403 		for i in range(iNumUnits):
  404 			pUnit = pPlot.getUnit(i)
  405 			iTeam = pUnit.getTeam()
  406 			if ((pUnit.getInvisibleType() == InvisibleTypes.NO_INVISIBLE) or \
  407 				(pUnit.getInvisibleType() == self.pUnit.getSeeInvisibleType())) and \
  408 				(not pUnit.isCounterSpy()):
  409 				if (iTeam != self.iActivePlayerTeam):
  410 					if (gc.getTeam(iTeam).isBarbarian()):
  411 						bBarbarian = true
  412 					elif (gc.getTeam(iTeam).isAtWar(self.iActivePlayerTeam)):
  413 						bEnemy = true
  414 					else:
  415 						bNeutral = true
  416 		if bEnemy:
  417 			return PleOpt.MH_Color_Enemy_Unit()

with the following lines 406-421 (modified file attached for you):

Code:
  403 		for i in range(iNumUnits):
  404 			pUnit = pPlot.getUnit(i)
  405 			iTeam = pUnit.getTeam()
  406 			if (pUnit.isCounterSpy()):
  407 				continue
  408 			iInvisibleType = pUnit.getInvisibleType()
  409 			if (iInvisibleType != InvisibleTypes.NO_INVISIBLE):
  410 				for j in range(self.pUnit.getNumSeeInvisibleTypes()):
  411 					if (iInvisibleType == self.pUnit.getSeeInvisibleType(j)):
  412 						break
  413 				else:
  414 					continue
  415 			if (iTeam != self.iActivePlayerTeam):
  416 				if (gc.getTeam(iTeam).isBarbarian()):
  417 					bBarbarian = true
  418 				elif (gc.getTeam(iTeam).isAtWar(self.iActivePlayerTeam)):
  419 					bEnemy = true
  420 				else:
  421 					bNeutral = true
  422 		if bEnemy:
  423 			return PleOpt.MH_Color_Enemy_Unit()

If you try it, please let me know how it works. I will optimize it for speed once it's working.
 
Thanks, I'll try it out and report back. Might be a few weeks, though, before I get back, as I have an annual report to do in the next week.
 
Top Bottom