Dynamic Civilization Names

Okay, I've now gotten it to show up as tribes or peoples at the beginning for all civs. However, now it won't change to Free City of ____ or Free State of _____ once I've founded my capital. :(
 
I think the problem might be that it's still not checking in between turns, even with the change to onBeginPlayerTurn. I've played a game about 10 turns in and it still wouldn't change with my city. Not sure what would be stopping it from checking though.
 
Please forgive my ignorance. But wanted to ask is there a way that leaders could determine the name of a civ?

Like say if someone wanted to put HRE and Germany into one civilization. In this example placing all of the leaders into the Germany civilization. And say you begin with one leader and when you swap to Charlemagne you civ could be renamed Holy Roman Empire or whatever based on what leader you have. Then the following civic description would follow.
 
Definitely possible ... right now if you name yourself:

Description: The Smurf Empire
Short: Smurf
Adjective: Smurfese

Then later in the game you may find yourself ruling the "Republic of Smurf" or the "Smurfese Kingdom".

Basically what needs to happen is that when the leader changes the short and adjective versions of the civ name need to change. The proper way to do this would be to augment each leader XML def with Civ name fields and make these accessible through the SDK. The quick and easy way would be to create a Python-level association (like is currently done in RebelTypes.py) to match leader types with civ name strings.

When the leader changes you'd update the Short and Adjective versions of the civ name based on the new leader and then call the DynamicCivNames civics-based naming function. Right now that's not guaranteed to change the name as I keep the old name if the civics-based parts are similar (ie, don't constantly switch from "___ Kingdom" to "Kingdom of ___") ... I'll add a flag for the next version to force the name to update which will make the new name stick and check that version into WoC.
 
The proper way to do this would be to augment each leader XML def with Civ name fields and make these accessible through the SDK.
Wouldn't this create problems with non default civs? It would be a serious pain if people who merge this mod (of which there are many), had to rebuild the leaderheadsinfos file.
 
Wouldn't this create problems with non default civs? It would be a serious pain if people who merge this mod (of which there are many), had to rebuild the leaderheadsinfos file.

I wouldn't been this for the main version of the mod, don't worry. That was just for if the WoC team wanted to tackel it the "right" way.

I think I will create the Python style functionality for the main mod though, with a default of having no change to the normal names.
 
Is any way to edit the dynamic civ names through XML? I suck at Python. I've added about 3 new government civics to one of my mods, and I'd like to know how to set those up with dynamic names.
 
In order to fix a bug in the "normal" game involving spawned colonies reusing IDs of eliminated players one option I'm considering is implementing some of the changes dynamic civ names makes (such as storing a copy of the name string in the player object) in the Unofficial Patch. However, I noticed the component adds the names to the save file. Does that break compatibility with saves from the unmodified game?
 
Yeah, I'm pretty sure it would break compatibility. Is there a thread describing the particular problem?

You could also consider writing an empty string to CvInitCore::setCivDescription, etc in CvGame::addPlayer perhaps.
There's not a thread, just a save that was posted to the solver sticky topic. (Description; save) The base problem seems to be that CvPlayer::getName() (and related functions) default to using the non-SDK gDLL->getPlayerName() function if it's non-empty. But when a player is eliminated and a colony takes the slot, gDLL->getPlayerName() still returns the name of the now-dead original player.

Will the CvInitCore::set___() methods allow us to clear or change those strings that are returned by the non-SDK functions during a running game? So I could explicitly do a CvInitCore::setLeaderName(), etc. after the CvGame::addPlayer() call in CvPlayer::splitEmpire()? That would be ideal.

But if that doesn't work, I will probably wind up putting an explicit colony bypass in the getName() functions and force it to go from leaderhead info when the player was a colony. So for example the following:

Code:
const wchar* CvPlayer::getName(uint uiForm) const
{
	if (isEmpty(gDLL->getPlayerName(getID(), uiForm)) || (GC.getGameINLINE().isMPOption(MPOPTION_ANONYMOUS) && isAlive() && GC.getGameINLINE().getGameState() == GAMESTATE_ON))
	{
		return GC.getLeaderHeadInfo(getLeaderType()).getDescription(uiForm);
	}
	else
	{
		return gDLL->getPlayerName(getID(), uiForm);
	}
}

would change to:
Code:
const wchar* CvPlayer::getName(uint uiForm) const
{
	if ( (getParent() != NO_PLAYER) || (isEmpty(gDLL->getPlayerName(getID(), uiForm)) || (GC.getGameINLINE().isMPOption(MPOPTION_ANONYMOUS) && isAlive() && GC.getGameINLINE().getGameState() == GAMESTATE_ON)))
	{
		return GC.getLeaderHeadInfo(getLeaderType()).getDescription(uiForm);
	}
	else
	{
		return gDLL->getPlayerName(getID(), uiForm);
	}
}

That should force a custom name bypass for a colony (since only colonies have a parent defined) without causing any side effects.
 
I am 99% certain that the CvInitCore::set___("") methods will work. There are a bunch of similar calls in CvGame::addPlayer ... if you remove them you can get some really strange results so they definitely have the intended effect.

If it was me, I'd put the name clearing inside of CvGame::addPlayer with a check to see if the civ type is actually changing ... doesn't really matter for the unofficial patch, but it does make a difference in Revolution where new players show up all the time outside the colony mechanics.

Your fallback solution also sounds reasonable, but I think the CvInitCore methods are the way to go.
 
OK, following that advice, I'm going to try adding the following block to the beginning of CvGame::addPlayer():
Code:
	LeaderHeadTypes eOldLeader = GET_PLAYER(eNewPlayer).getLeaderType();
	CivilizationTypes eOldCiv = GET_PLAYER(eNewPlayer).getCivilizationType();
	CvWString szEmptyString = "";
	if ( ((eOldLeader != NO_LEADER) && (eOldLeader != eLeader)) || ((eOldCiv != NO_CIVILIZATION) && (eOldCiv != eCiv)) ) 
	{
		GC.getInitCore().setLeaderName(eNewPlayer, szEmptyString);
		GC.getInitCore().setCivAdjective(eNewPlayer, szEmptyString);
		GC.getInitCore().setCivDescription(eNewPlayer, szEmptyString);
		GC.getInitCore().setCivShortDesc(eNewPlayer, szEmptyString);
	}
Seems to work OK on an initial test; can you think of any problems that might cause or things I should watch out for?

EDIT: And would it be better to separate out the leader name blanking from the civ name blanking like so?
Code:
	CvWString szEmptyString = "";
	LeaderHeadTypes eOldLeader = GET_PLAYER(eNewPlayer).getLeaderType();
	if ( (eOldLeader != NO_LEADER) && (eOldLeader != eLeader) ) 
	{
		GC.getInitCore().setLeaderName(eNewPlayer, szEmptyString);
	}
	CivilizationTypes eOldCiv = GET_PLAYER(eNewPlayer).getCivilizationType();
	if ( (eOldCiv != NO_CIVILIZATION) && (eOldCiv != eCiv) ) 
	{
		GC.getInitCore().setCivAdjective(eNewPlayer, szEmptyString);
		GC.getInitCore().setCivDescription(eNewPlayer, szEmptyString);
		GC.getInitCore().setCivShortDesc(eNewPlayer, szEmptyString);
	}
 
Great work! I'm totally interested in this, but is it compatible with 3.17?
 
Is there any way to get dynamic names to show up on the scoreboard instead of leader names or civilization names? IE Seeing "Kingdom of Rome" or whatever on the scoreboard, without having to mouse over it or anything.

It's been done with RFC's dynamic civname component before, and it doesn't really crowd the screen at all, even for the longer dynamic names. I tried searching the forums here for this, but I couldn't find any previous topics or posts on the issue, so I thought it'd be appropriate to post my request in this thread.
 
Top Bottom