The game is telling me that 23 != 23

NotSoGood

Emperor
Joined
Jan 25, 2009
Messages
1,077
Location
Finland
I'm still trying to get my hire unit concept to work. I have suggesfully moved it to DLL and started writing the AI for it. But now it turns out it isn't working properly with unique units. I use CvPlayer::canTrain function in my checks but it for some reason it returns false with my UUs.
I'm passing the Musketeer unit to the function (it's number 23 in unit infos).
Code:
bool CvPlayer::canTrain(UnitTypes eUnit, bool bContinue, bool bTestVisible, bool bIgnoreCost) const
{
	PROFILE_FUNC();

	UnitClassTypes eUnitClass;
	int iI;

	eUnitClass = ((UnitClassTypes)(GC.getUnitInfo(eUnit).getUnitClassType()));

	FAssert(GC.getCivilizationInfo(getCivilizationType()).getCivilizationUnits(eUnitClass) == eUnit);
	if (GC.getCivilizationInfo(getCivilizationType()).getCivilizationUnits(eUnitClass) != eUnit)
	{
		return false;
	}
...
So the eUnit is 23 (Musketeer). eUnitClass is eUnit's unitclass (number 22). Okay, to this point it works. (I have checked the numbers and they are correct) But then in the first check when I get the civilization's UU (23) and compare it to the unit I'm passing (23) it returns true in that check and false from the function.

This is what I have in CivilizationInfos.xml
Code:
				<Unit>
					<UnitClassType>UNITCLASS_MUSKETMAN</UnitClassType>
					<UnitType>UNIT_FRENCH_MUSKETEER</UnitType>
				</Unit>
:confused:
That doesn't make sense. Any ideas are welcome.
 
What are you trying to do exactly?

One to mention, because it could be related: canTrain will never allow you to train the UUs of other nations.
I've tested it in python, just returning true will allow you to build GPs, animals, whatever, but not other UUs.
No idea why, i guess this check is done elsewhere.
 
What are you trying to do exactly?

One to mention, because it could be related: canTrain will never allow you to train the UUs of other nations.
I've tested it in python, just returning true will allow you to build GPs, animals, whatever, but not other UUs.
No idea why, i guess this check is done elsewhere.

I'm checking if you can train the unit when you try to hire it. But the odd thing is that I'm trying to check if you can train you're own UU not any other civs'.
 
Could you show your implemenation code? I actually have a decent amount of experience with similar issues, dealing with Legend Units spawning and setting up various canTrain checks. Your code you're showing though is just the assert and check to insure that a player is building a unit that is valid for their civilization, it doesn't show me where the 23 != 23 is actually occuring.
 
What are you trying to do exactly?

One to mention, because it could be related: canTrain will never allow you to train the UUs of other nations.
I've tested it in python, just returning true will allow you to build GPs, animals, whatever, but not other UUs.
No idea why, i guess this check is done elsewhere.

<Offtopic>
UU's are built into your Civilization Type. You need to trick the game into thinking you are a different civilization than you really are. I have this in my mod...
</Offtopic>
 
Could you show your implemenation code? I actually have a decent amount of experience with similar issues, dealing with Legend Units spawning and setting up various canTrain checks. Your code you're showing though is just the assert and check to insure that a player is building a unit that is valid for their civilization, it doesn't show me where the 23 != 23 is actually occuring.

Yes the assert fires when trying to check if I can train the unit. So you think it's a logic problem in my code?
I think I have done it correctly but here's how it goes:

1) The Military Advisor, draws the hire unit screen
Code:
	def unitList(self, screen):
		#this loops all the units to the left, I think it works
		self.numHireUnits = 0
		self.panelCount = 0
		for iUnitClass in range(gc.getNumUnitClassInfos()):
			iUnit = gc.getCivilizationInfo(self.iActivePlayer).getCivilizationUnits(iUnitClass)
			[COLOR="Red"]if gc.getPlayer(self.iActivePlayer).canHireUnit(iUnit):[/COLOR]
				if not self.unitHasAvailableUpgrade(iUnit):
					if self.panelCount < 4:
						self.iUnit = iUnit
						self.panelCount += 1
						self.drawUnitList(screen, iUnit)
					self.numHireUnits += 1
2) CyPlayer::canHireUnit(), calls CvPlayer::canHireUnit()
Code:
bool CyPlayer::canHireUnit(int /*UnitTypes*/ iIndex)
{
	[COLOR="Red"]return m_pPlayer ? m_pPlayer->canHireUnit((UnitTypes)iIndex) : false;[/COLOR]
}
3) CvPlayer::canHireUnit(), checks if the player can hire the unit
Code:
bool CvPlayer::canHireUnit(UnitTypes eUnit)
{
	if (GC.getUnitInfo(eUnit).isMilitaryHappiness())
	{
		if (GC.getUnitInfo(eUnit).getDomainType() == DOMAIN_LAND)
		{
			[COLOR="red"]if (canTrain(eUnit))[/COLOR]
			{
				return true;
			}
		}
	}
	return false;
}
4) CvPlayer::canTrain(), checks if player can train the unit
Code:
bool CvPlayer::canTrain(UnitTypes eUnit, bool bContinue, bool bTestVisible, bool bIgnoreCost) const
{
	PROFILE_FUNC();

	UnitClassTypes eUnitClass;
	int iI;

	eUnitClass = ((UnitClassTypes)(GC.getUnitInfo(eUnit).getUnitClassType()));

	FAssert(GC.getCivilizationInfo(getCivilizationType()).getCivilizationUnits(eUnitClass) == eUnit);
	[COLOR="red"]if (GC.getCivilizationInfo(getCivilizationType()).getCivilizationUnits(eUnitClass) != eUnit)[/COLOR]
	{
		[COLOR="Blue"]return false;[/COLOR]
	}
...
 
That at all seems to be unneccessary.
The canTrain option will not allow you to build any other UUs, so that every unit, which you are allowed to build, are either standard units or your own UU.

Ok, lets clarify this once and for all. I was playing as the france which UU is musketeer. In military advisor I loop through all unitclasses and get the civilization's unit. (UU or normal)
Spoiler :
Code:
	def unitList(self, screen):
		#this loops all the units to the left, I think it works
		self.numHireUnits = 0
		self.panelCount = 0
		[COLOR="Blue"]for iUnitClass in range(gc.getNumUnitClassInfos()):[/COLOR]
			[COLOR="Red"]iUnit = gc.getCivilizationInfo(self.iActivePlayer).getCivilizationUnits(iUnitClass)[/COLOR]
			if gc.getPlayer(self.iActivePlayer).canHireUnit(iUnit):
				if not self.unitHasAvailableUpgrade(iUnit):
					if self.panelCount < 4:
						self.iUnit = iUnit
						self.panelCount += 1
						self.drawUnitList(screen, iUnit)
					self.numHireUnits += 1
And then I check if I (france) can train my OWN unique unit.

Was that clear enough? :D
 
You are not getting your civilization type. You are getting the civilization type that happens to have the same index as your player ID which are totally different sets of numbers. Also, don't keep grabbing the civilization info and player each time through the loop; store them in variables.

Code:
	def unitList(self, screen):
		#this loops all the units to the left, I think it works
		self.numHireUnits = 0
		self.panelCount = 0
		[B][COLOR="Red"]player = gc.getPlayer(self.iActivePlayer)[/COLOR][/B]
		[B][COLOR="Red"]civilization = gc.getCivilizationInfo(player.getCivilizationType())[/COLOR][/B]
		for iUnitClass in range(gc.getNumUnitClassInfos()):
			iUnit = [B][COLOR="Red"]civilization[/COLOR][/B].getCivilizationUnits(iUnitClass)
			if [B][COLOR="Red"]player[/COLOR][/B].canHireUnit(iUnit):
				if not self.unitHasAvailableUpgrade(iUnit):
					if self.panelCount < 4:
						self.iUnit = iUnit
						self.panelCount += 1
						self.drawUnitList(screen, iUnit)
					self.numHireUnits += 1
 
Back
Top Bottom