Is this possible in Python?

ripple01

Emperor
Joined
Mar 7, 2006
Messages
1,254
Location
New York City
I am merging some of Ekmek's Prophet Driven Religion into my personal mod and I have merged most of it without any problems, even the Python.

For a quick background, Ekmek's mod changes religions so that they are founded through Great Prophets instead of through techs. There are different "founding buildings" set up for each religion and the Great Prophet builds these buildings thereby founding the religion, almost identical to the way it builds each religions Shrine.

However, there are two issues (both mentioned in Ekmek's thread) that I want to see if I can figure out how to solve.

1) There is no code for the AI to build the "founding building" that corresponds with its favorite religion. I have found a way in Python to identify the player's favorite religion. What I am unsure of if it is possible to direct the AI to build the appropriate "founding buidling" that corresponds with the favorite religion.

2) The second issue is somewhat related. Currently, the AI will build the "founding buildings" in order of how they are in the XML (unsure if it is in the Buildings XML or the Religions XML, but could test this pretty easily if need be.) So all the religions are founded in the same order every game (Judaism, then Christianity, then Islam, etc.). Is there way to use a random number generator to randomize which "founding building" the AI will choose so that the religions are not founded in the same order every game.

Many thanks for any points in the right direction. I can post any code or answer any other questions if necessary.
 
You basically can't impact AI "decision making" via Python. But you can identify units (like prophets) and have those be deleted and spawn buildings (like a shrine) in the city previously occupied by that unit. Its not exactly the same as having the AI use a special unit action, even if the result would be identical.

So it would be quite possible to have a script that checks if AI players currently have prophet units. Some logic would then "decide" whether or not that unit will be used for building the shrine corresponding to some religion according to some other logic.

Tell me if you need help with the actual scripting.
 
Actually, you can override the AI in various ways. In this case, it would be the AI_unitUpdate callback. Final Frontier uses this to sometimes force a construction ship to go build a starbase. Using this would avoid the "loop over all units and check for a great prophet every turn" thing, replacing it with an "is this unit a great prophet" each time a unit is updating its orders.
 
Oh, please explain more! Where is this AI_unitUpdate call-back? How does it work, exactly?
 
It is one of the standard callbacks in CvGameUtils.py. There is no entry for it in PythonCallbackDefines.xml to enable/disable it, so it must always be called.

It is evidently called any time a unit needs new orders. If the function returns True, that means that it has told the unit to do something via the Python and the DLL does not need to decide what to do for it. One slight caveat: actually killing a unit in this callback can possibly cause a crash - there is a comment in the Final Frontier Python that indicates this (the odd part is that in FF the unit is not killed in this callback, it is killed - or a timer is set that will cause it to be killed when it hits 0, actually - in the onImprovementBuilt event handler).

I have not looked at the SDK to determine if there is anything else involved that could complicate things.

You can look at Final Frontier for an example (or Final Frontier Plus for a slightly more complicated example, since it adds a second type of station that the construction ship can be made to build).
 
Interesting. I have to admit, this is a little above my paygrade. Baldyr, if you are interested in working with this AI_unitUpdate call back, and want to se this situation as a test example, please be my guest. I would be indebted to you. :) I am slowly trying to learn some Python (using Python Programming: A Guide to Computer Science, which is a great beginning textbook) but might not be at this level for a little while.

Thanks for your input, God-Emperor.
 
Ok, I'll look into it once I get the time. Patience, little grasshopper... ;)

Be sure to remind me after the weekend. :p
 
Ok, I'll look into it once I get the time. Patience, little grasshopper... ;)

Be sure to remind me after the weekend. :p

Sure thing, no rush. I am also going to check out your Python tutorial you are working on. It looks great, thanks for taking the time to write it to help noobs like myself.
 
I looked at the FF Python AI code and it wasn't very accessible. :p

How exactly does the mod make a unit carry out a specific task? Like building a shrine.
 
Short answer: MISSION_CONSTRUCT appears to be the thing.

Longer answer:
To actually get the unit to do something, you give it the appropriate mission via the unit's selection group's pushMission method. Moving is a little easier to do since they added a specific method for just moving called pushMoveToMission.

Examples:
1) this is how FF gets a construction ship to move to the location where it is supposed to build a starbase:
pUnit.getGroup().pushMoveToMission(iX, iY)
2) this is how it makes it actually build the improvement:
pUnit.getGroup().pushMission(MissionTypes.MISSION_BUILD, iBuild, -1, -1, false, true, MissionAITypes.MISSIONAI_BUILD, pUnit.plot(), pUnit)

The rest of the stuff in FF is just determining where to build the starbase, or not build one if there are no more good places.

So I expect it would be something similar. Once you have the unit decide where to make it build the building via some rating system for the owner's cities (there should be some factor about ability to move there - if the best place is on a different continent and you don't have airports yet then it could be difficult to get it to go there so such a case might lower the rating of that city). If the unit is not there, set it to move there. If it is there then it looks like the mission to push is just the MISSION_CONSTRUCT. There are, of course, complications - like how safe is it to move to the other city (watch out for animals, barbarians, enemy units). This is more complicated that the FF case which which just blindly sends construction ships off out into space unescorted - if they die, they die- but great people are much more valuable than workers so you don't just want to blindly send them off half way across the map by themselves.

It would be easier if you always just built the thing in the city where the GP was generated. That might be good enough.
 
Yeah, I'll try to get around trying this out. I do have some other stuff to take care of first, though.
 
Ouch, unfortunately not. :p That window of opportunity closed some weeks ago...
 
Top Bottom