AI_chooseProduction, cities sitting idle

The_J

Say No 2 Net Validations
Administrator
Supporter
Joined
Oct 22, 2008
Messages
39,658
Location
DE/NL/FR
So, i tried my hands on 2 requested projects with a python effect, and realized afterwards that the AI will never ever build them, because there's no XML value to influence that.

But i remembered the AI_chooseProduction function in CvGameUtils, and that you can hook in there to influence the production choice.
I added my code, tested it...and it wrecked the AI! The code was executed, but the cities were just sitting idle, doing nothing.
Since the AI is still randomly chaning the production from *nothing* to the preferred units or buildings, there must be somewhere be a really damn small and dumb error, which i can't see at the moment.

Can anyone maybe take a look at the code (see below)?

Spoiler :
PHP:
	def AI_chooseProduction(self,argsList):
		pCity = argsList[0]
###hanseatic league - AI start
		pPlot = pCity.plot()
		if pPlot.isCoastalLand():
                        pPlayer = gc.getPlayer(pCity.getOwner())
                        iHanse = gc.getInfoTypeForString("PROJECT_HANSEATIC_LEAGUE")
                        if pPlayer.canCreate(iHanse, True,False):                        
                                pTeam = gc.getTeam(pPlayer.getTeam())
                                if pTeam.isHasTech(gc.getInfoTypeForString("TECH_ASTRONOMY")):
                                        if pTeam.getAtWarCount(True)<=0:                                                
                                                pCity.chooseProduction(pCity.getProductionUnit (),pCity.getProductionBuilding (),iHanse,False,False)
                                                return True                                               
                                                
###hanseatic league - AI end		
		return False

In my opinion it should work, and i also don't get any exception messages, but something is borked.
The included prerequisites are custom for the project, and since turning the True into a False will fix the problem i know the code works to its end...but something doesn't. Does anyone see what exactly?
 
It seems odd to call pCity.chooseProduction. For the human player this shows a pop-up, but I have no idea what it does for an AI (if anything). I'm pretty sure you should just decide if you are going to make the AI produce the thing and if so put it in the city's build queue via pCity.pushOrder(...).

The way it looks to me (having just checked CvCity.cpp) is that the DLL uses AI_chooseProduction for the AI (or cities the human has set to automated production) and uses chooseProduction for the human. See lines 10960-10980 in CvCity.cpp, for example. Another example is 11335-11339. It always checks to see whether the player is human or not and only calls chooseProduction for the human.
 
It seems odd to call pCity.chooseProduction. For the human player this shows a pop-up, but I have no idea what it does for an AI (if anything).

:hmm: interesting, haven't thought that this might be the problem.
But it does affect the AI...but just not right :think:.

I'm pretty sure you should just decide if you are going to make the AI produce the thing and if so put it in the city's build queue via pCity.pushOrder(...).

Thanks :goodjob:, will try that :).
 
You dont have to push anything. Just return the production you want instead of False.

IE, return iHanse

That is certainly not the case. When doing the callback in the DLL, it only checks the returned value for true/false. If the callback returns true (1) then the CvCityAI::AI_chooseProduction() function exits immediately without doing anything else. If anything other than 1 is returned, it runs it's own production determination algorithm (it never looks at the returned value again).

Like so:
Code:
	gDLL->getPythonIFace()->callFunction(PYGameModule, "AI_chooseProduction", argsList.makeFunctionArgs(), &lResult);
	delete pyCity;	// python fxn must not hold on to this pointer
	if (lResult == 1)
	{
		return;
	}
That one check to see if lResult is 1 is the only time the return value from the callback is ever used in the function.
 
Top Bottom