[Python]: Help, How does python assign GP names?

Civkid1991

in shade of poison trees
Joined
Feb 20, 2006
Messages
871
I was just looking through some of the python files but can't find it. Does anyone know how python assignes names to the great people when they are born? What function does it use to get the name from the xml?:confused:

Ty,

~Civkid~
 
The names for great persons are set in python they are set in the SDK when the great person unit is spawned. This is done when the init method in the CvUnit class calls the getUnitNames method from the CvUnitInfo class.
 
Code:
	if (GC.getGameINLINE().getUnitCreatedCount(getUnitType()) < GC.getUnitInfo(getUnitType()).getNumUnitNames())
	{
		iUnitName = GC.getGameINLINE().getUnitCreatedCount(getUnitType());

		iUnitName *= max(0, (GC.getWorldInfo(GC.getMapINLINE().getWorldSize()).getUnitNameModifier() + 100));
		iUnitName /= 100;

		if (iUnitName < GC.getUnitInfo(getUnitType()).getNumUnitNames())
		{
			setName(gDLL->getText(GC.getUnitInfo(getUnitType()).getUnitNames(iUnitName)));
		}
	}

:cry: It's not as simple as i thought it would be... is it possible to get an explination (mostly for the functions)?
 
If you are just addind or changing the names of the great people they are found in the unit info class.
 
No, i was think of changeing it so that i would have a diffrent file that holds various names for units. When a unit is created it will take a name from the namepool. I just don't know how C++ takes the name from the xml files. That's why I asked about the great people... to see how it works

With python... i was thinking of an event or editing the initUnit function so that there would be a change name function inside (which would get the name from the xml) but i don't know how to get info from custom files using python
 
You mean how in Warlords when a great person is born their name is randomly chosen form the list? I couldn't possibly help you there. I do hope someday to learn python.
 
similar to that (i don't have warlords so it would be for vanilla civ) but this would be for normal units. Say i have a city, i build a unit, a worrior, and when it spaws on the city it will be automaticlly assigned a name from the namepool.
 
It seems as if you can add unique unit names by making a string list inside the XML. I've never tried, but I guess it would be like this:

Code:
<UniqueNames>
	<UniqueName>TXT_KEY_GREAT_PERSON_MOSES</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_MAHAVIRA</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_ZOROASTER</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_ANANDA</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_CHUANG_TZU</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_MENCIUS</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_MO_TZU</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_ST_JOHN</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_ST_PETER</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_ST_PAUL</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_RABBI_AKIVA</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_MANI</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_ST_AUGUSTINE</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_ST_PATRICK</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_ABU_BAKR</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_SHANKARA</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_KOBO_DAISHI</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_ATISHA</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_ST_THOMAS_AQUINAS</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_MOHAMMED_SHAH</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_TSONGKHAPA</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_JEANNE_ARC</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_NARAK</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_TIPU_SULTAN</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_RAMAKRISHNA</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_NARAYANA_GURU</UniqueName>
	<UniqueName>TXT_KEY_GREAT_PERSON_SOJOURNER_TRUTH</UniqueName>
</UniqueNames>

Just before the code you put from the CvUnit::init() method, the unit's name is set to their default. "Great Prophet", for example. I believe this would be done in CvUnit::reset().

Then, it does the code you're referring to:

Code:
if (GC.getGameINLINE().getUnitCreatedCount(getUnitType()) < GC.getUnitInfo(getUnitType()).getNumUnitNames())

What this does is check how many total units of that type of been created, and compares it to how many unique names it has. For example, if 20 great prophets have been created and there are 30 unique names for great prophets, then this function will pass.

Code:
iUnitName = GC.getGameINLINE().getUnitCreatedCount(getUnitType());

This code will get the number of units created. The first time a prophet is spawned, there are zero prophets that have been created, so it gets name number 0 (moses). The game object (which is retrieved using getGameINLINE() ) has a counter that keeps track of how many units of a certain type have been created. When the unit's created, that counter is incremented. So, the second time a great prophet spawns, the counter will be at 1, and the 1th name is used (mahavira).

Code:
iUnitName *= max(0, (GC.getWorldInfo(GC.getMapINLINE().getWorldSize()).getUnitNameModifier() + 100));
iUnitName /= 100;

This part makes it a bit tricky. The iUnitName is multiplied by a number. The getUnitName modifier by default ranges from 50 to 0. Here are some values:

iUnitName before this code -> iUnitName after this code

At getUnitNameModifier() == 50 (WORLDSIZE_DUEL)

0 -> 0
1 -> 1
2 -> 3
3 -> 4
4 -> 6
5 -> 7


At getUnitNameModifier() == 20 (WORLDSIZE_STANDARD)

0 -> 0
1 -> 1
2 -> 2
3 -> 3
4 -> 4
5 -> 6


At getUnitNameModifier() == 0 (WORLDSIZE_HUGE)

0 -> 0
1 -> 1
2 -> 2
etc.

What is the point of doing this? My best guess is that Firaxis found that in larger games, more units can be developed. Thus, by placing the unit names in historical order, you have a better chance of drawing the name of a figure that is somewhat at the same time as the game if you have games with less prophets being made "skip" a few names.

Finally, it does one last check:

Code:
if (iUnitName < GC.getUnitInfo(getUnitType()).getNumUnitNames())
{
	setName(gDLL->getText(GC.getUnitInfo(getUnitType()).getUnitNames(iUnitName)));
}

If the new iUnitName that it generated is past the list of total unit names, then no unique name will be given. Thus, if the name to be used is 50 and there are only 30 names, it doesn't assign it a new name. If there is a unique name for it, then the unit's name is set to that unique name.

So, that's what the code does in a nutshell. I'm willing to bet that, because the unique names can be put into the XML, you can probably make them use a random name rather than the above algorithm for generating a name by changing the onUnitCreated function in CvEventManager.py. Just get a random number between 0 and gc.getUnitInfo(eUnitType).getNumUnitNames(). Then, set the unit's name using:

Code:
pUnit.setName(gc.getUnitInfo(eUnitType).getUnitNames(iRandomNum)
 
Gerikes said:
pUnit.setName(gc.getUnitInfo(eUnitType).getUnitNames(iRandomNum)

getUnitNames() is part of the CyUnitInfo, that would explain why I never found it when I looked in the CyUnit methods. :thanx: Gerikes. :)
 
Back
Top Bottom