[PYTHON] How to make a leader only say his specific dialogue

TreeSpawned

Chieftain
Joined
Oct 21, 2018
Messages
7
Location
Germany
I writing a mod, where I want one of my leaderheads to only ever respond with dialogue, that is associated with him in particular, i.e. responses that have his LeaderType and not any dialogue responses that are generic to all leaders, i.e. responses without any LeaderType.

I think I almost have a solution, but I don't have any experience programming in Python and therefore i am stuck.

Searching through the Python code I found the file CvDiplomacy.py which seems to be what I am looking for.
In it there is a function called filterUserResponse. If I read correctly this method determines which of all the possible sentences is returned for a specific diplo line.
It goes through all the lines that there are and those that do not fit it's criteria are dismissed using 'continue'. And those that fit all criteria are added to a list called 'responses' in the end from which a random one is chosen.

So I am guessing all I need to programm is: 1. Check if this is the leader I want 2. Check if the line is not associated with any leader and if both those critieria are met, throw out that line with a 'continue'.
I tried it like this, but it does nothing:

if (theirPlayer.getLeaderType() == "LEADER_MURKY" and
not self.isUsed(diploInfo.getLeaderHeadTypes, i, gc.getNumLeaderHeadInfos())):
continue

'theirPlayer' is defined further up in the same function using:
theirPlayer = gc.getPlayer(self.diploScreen.getWhoTradingWith())

From what I think I have found out testing this code (I have no idea how to debug this other than trying it out in-game), I think the first condition is never met, It doesn't matter if the leader I am contacting is LEADER_MURKY or anyone else, the first line always returns false.
The second line I copied from the already existing check for the leader type. I hope I am correct in assuming this checks whether the line has any leader type.

Does anyone know what my error is? Is the return value of .getLeaderType() not a string? Am I comparing strings incorrectly? Or is it something else entirely?

I am looking forward to all of your feedback.
 
So I got it working. This it what it looks like:

if (theirPlayer.getNameKey() == 'TXT_KEY_LEADER_MURKY' and
diploInfo.getType().startswith('AI') and
not self.isUsed(diploInfo.getLeaderHeadTypes, i, gc.getNumLeaderHeadInfos())):
continue

It turns out theirPlayer.getLeaderType() returns an int of an Enum of all the leaders. I figured out what the value of my leader is, but I decided not to write down that number into the code, because this number changes, whenever a new leader is added or the order of the leaders is changed in CIV4LeaderHeadInfos.xml. So I used the NameKey instead, which works.
Additionally I added a check if the "type" of the diplo line starts with 'AI', that way the so called "User_Diplo" which is the text that appears in the Menu Options in the Diplomacy window, is not changed, only the "AI_DIPLO", the things the leader actually says.
 
Great that you've figured it out. There's a bare-bones online documentation of the Python API:
http://civ4bug.sourceforge.net/PythonAPI

The more canonical way to check the leader would be (typed from memory, so perhaps not 100% correct):
theirPlayer.getLeaderType() == gc.getInfoTypeForString("LEADER_MURKY")
assuming that gc = CyGlobals() is defined. Though I don't see any advantage over your solution in this case.

As for debugging, well, :(
print "theirPlayer.getLeaderType()=" + str(theirPlayer.getLeaderType())
will print to PythonDbg.log in My Games\Beyond the Sword\Logs if LoggingEnabled=1 is set in My Games\Beyond the Sword\CivilizationIV.ini.
 
Thanks for your response.
I did end up looking through that this documentation. But I couldn't find a function that would give me the id from the string.
Using getInfoTypeForString is exactly what I was looking for and what I will use now. I agree there is no functional difference, but it just feels more professional :).
And I debugged using "raise NameError(valueIWantToSee)", after turning off HidePythonExceptions in the CivilizationIV.ini :lol:
 
And I debugged using "raise NameError(valueIWantToSee)", after turning off HidePythonExceptions in the CivilizationIV.ini :lol:
I got tired of not getting the python errors and in particular bug reports where python failed without any error message. I edited CvXMLLoadUtility::LoadPlayerOptions() and added:
PHP:
gDLL->ChangeINIKeyValue("CONFIG", "HidePythonExceptions", "0");
Now it's no longer possible to turn python errors off. I did this after missing a bug because the ini file had reset itself and removed the python errors.
 
Top Bottom