citynames for earthmap

sT0!ka

Chieftain
Joined
Dec 27, 2008
Messages
13
Hi there,

after checking a lot of threads on different civ4-sites to find out, how it is possible to implement 'realistic' citynames on an earthmap, after beginning to try it on my own by learning how to handle all that python-xml-sdk-ffs-stuff, i'm still walking in the dark and need to ask professional civ4modders ^^

In detail: i want to use the 18civs-earthmap together with one pretty huge list of actual citynames of our real earth - similar to the mod of Rhye, but without changing the names or any specials. Just one list for all civ's and everytime, when a settler wants to found a city, the name will be automatically choosen. I'm sure you know what i mean.

Beside creating the citylist for nearly all the plots on the map (pretty much work) i need to know, where to implement the little script, which says the settler how to name its city. And how to tell the map to use that script. I tried to create a little mod and started working on it, but it's pretty difficult without nearly no knowledge of - all that ... ^^
So - maybe someone else did a similar thing and is able to give me some example or hints ..

thx for all help,
alex.

Moderator Action: Download is here .
 
of course the first thing i tried was to modify some Rhye-files ^^ but its pretty difficult to find all necessary stuff for creating cities and for the event, to change their names.

I found 3 important python-files:
"CvEventManager.py"
"CvRFCEventHandler.py"
"CityNameManager.py"

the last file sets up map-arrays with all the names and the function """Names a city depending on its plot""" (all the ELIF-lines i don't need, because i just want to have one single citymap for all civs).

so i created a new mod and deleted all unimportant stuff of those files and tried to modify a little - without success; either there was an errormessage or no changes happened (the 'normal' citynames were used).

i think there are some problems with importing the files. at least the line "from CvPythonExtensions import *" seems to be important, but there is no files like that (maybe it will be created when starting the game? i don't know).

also the "CvRFCEventManager.py" seems to be important, although there isn't mentioned any word of citybuilding or else.

some code from rhye's files:

from "CityNameManager.py":
Code:
tCityMap = (
#Egypt
((	"-1",	"-1", ....... ,"-1",	"Kadesh",	"Kadesh" ..............,	"-1"))

....

        def assignName(self, city):
                """Names a city depending on its plot"""
                iOwner = city.getOwner()
                if (iOwner < iNumMajorPlayers):
                        cityName = tCityMap[iOwner][67-city.getY()][city.getX()]
                        if (cityName != "-1"):
                                city.setName(cityName, False)
(iOwner should not be important, because only one citymap for all civs ..)

from "CvRFCEventHandler.py":
Code:
	def __init__(self, eventManager):

...

		eventManager.addEventHandler("cityBuilt", self.onCityBuilt)

...

self.cnm = CityNameMap.CityNameMap()

...

        def onCityBuilt(self, argsList):
                'City Built'
                city = argsList[0]
                
                iOwner = city.getOwner()
                
                if (iOwner < con.iNumActivePlayers): 
                        self.cnm.assignName(city)

and from "CvEventManager.py":
Code:
	def onCityBuilt(self, argsList):
		'City Built'
		city = argsList[0]
		#if (city.getOwner() == gc.getGame().getActivePlayer()):
 		#	self.__eventEditCityNameBegin(city, False)	    #Rhye
		CvUtil.pyPrint('City Built Event: %s' %(city.getName()))

those files/code should be modified i think, but it's very problematic to me :/ and there are probably missing includes/imports or else

well - still working on it ...

everybody: feel free to help ;-)

greetz - alex.
 
the simplest way is to replace
cityName = tCityMap[iOwner][67-city.getY()][city.getX()]
with
cityName = tCityMap[0][67-city.getY()][city.getX()]

and then add all your city names in the first (egyptian) map
 
Thanks a lot for answer, Rhye. It's the first useful hint i got.

Now i'm able to create an own citymap for all civs, but i still can use it only in RFC. But i want to use this feature for another map/mod (like "Earth18Civs.Civ4WorldBuilderSave").

I didn't mentioned, it would be only for private use, playing multiplayer in a LAN with some friends ;-)

So i still have some questions and it would be an honor to me, if you could help a little more.

How can i export only the citymap-feature? Which files? Is it that much work or difficult, to change all neccessary things?

At least the RFC-map is a very nice one. Is it possible to export this too, for multiplayer-use?

Btw i enjoy playing RFC a lot. It's a great mod!

So - really a lot of thanks for further help - Alex.
 
it's a bit complicated to export just the citymap feature. You'd need to create another event handler (such as CvRFCEventHandler.py) that calls assignName and renamecities inside the city name manager file, on city founded and acquired
 
Thx for fast reply 8)

Ok, i started from the beginning:

Creating a "test mod" with only /PublicMaps ("Earth18Civs.Civ4WorldBuilderSave" in it) and with "test mod/Assets/Python/CityNameManager.py and CvTestEventHandler.py

I deleted all code, which seemed unimportant to me (like mercenary-stuff and so on).

Imported also the "CvEventManager.py" to stop the eventEditCityNameBegin.

Mod is working, but not the citynamemanager. How can i include those files (manager and eventhandler)? Something left maybe in the code?

CityNameManager.py:
Code:
from CvPythonExtensions import *
import CvUtil
import PyHelpers
import Popup
import Consts as con

# globals
gc = CyGlobalContext()
PyPlayer = PyHelpers.PyPlayer

### Constants ###

# initialise player variables to player IDs from WBS
iEgypt = con.iEgypt
iIndia = con.iIndia
iChina = con.iChina
iBabylonia = con.iBabylonia
iGreece = con.iGreece
iPersia = con.iPersia
iCarthage = con.iCarthage
iRome = con.iRome
iJapan = con.iJapan
iEthiopia = con.iEthiopia
iMaya = con.iMaya
iVikings = con.iVikings
iArabia = con.iArabia
iKhmer = con.iKhmer
iSpain = con.iSpain
iFrance = con.iFrance
iEngland = con.iEngland
iGermany = con.iGermany
iRussia = con.iRussia
iNetherlands = con.iNetherlands
iHolland = con.iHolland
iMali = con.iMali
iTurkey = con.iTurkey
iPortugal = con.iPortugal
iInca = con.iInca
iMongolia = con.iMongolia
iAztecs = con.iAztecs
iAmerica = con.iAmerica

iNumPlayers = con.iNumPlayers
iNumMajorPlayers = con.iNumMajorPlayers
iNumActivePlayers = con.iNumActivePlayers

iBarbarian = con.iBarbarian
iNumTotalPlayers = con.iNumTotalPlayers
      
# city coordinates

tCityMap = (
#ALL
((	"-1",	"-1",	"-1", .....................................
,	"-1",	"-1",	)),
)

class CityNameManager:

        def assignName(self, city):
                """Names a city depending on its plot"""
                iOwner = city.getOwner()
                if (iOwner < iNumMajorPlayers):
                        cityName = tCityMap[0][67-city.getY()][city.getX()]
                        if (cityName != "-1"):
                                city.setName(cityName, False)

        def renameCities(self, city, iNewOwner):
                """Renames a city depending on its owner"""

                sName = city.getName()

                if (iNewOwner == iEgypt):                                                        
                        if (sName == 'Yerushalayim' or sName == 'Aelia Capitolina'):
                                city.setName('Aarru-Hetep', False)
..................and so on

CvTestEventhandler.py:
Code:
from CvPythonExtensions import *
import CvUtil
import PyHelpers 
import Popup as PyPopup 
import CityNameManager  

gc = CyGlobalContext()        
#iBetrayalCheaters = 15

PyPlayer = PyHelpers.PyPlayer
PyGame = PyHelpers.PyGame()
PyInfo = PyHelpers.PyInfo

# Set to true to print out debug messages in the logs
g_bDebug = false

# Default valus is 1 
g_bUpdatePeriod = 5 #Rhye

# Default valus is 1 
g_bAIThinkPeriod = 6 #Rhye (5 in Warlords, 4 in vanilla)

# globals

###################################################
class CvTestEventHandler:

        def __init__(self, eventManager):


                # initialize base class

                eventManager.addEventHandler("cityAcquired", self.onCityAcquired) #Stability

                eventManager.addEventHandler("cityBuilt", self.onCityBuilt) #Stability


               
                self.eventManager = eventManager

                self.cnm = CityNameManager.CityNameManager()

        def onCityAcquired(self, argsList):
                #'City Acquired'
                owner,playerType,city,bConquest,bTrade = argsList
                #CvUtil.pyPrint('City Acquired Event: %s' %(city.getName()))
                self.cnm.renameCities(city, playerType)
                
                return 0

        def onCityBuilt(self, argsList):
                'City Built'
                city = argsList[0]
                
                iOwner = city.getOwner()
                
                if (iOwner < con.iNumActivePlayers): 
                        self.cnm.assignName(city)

thx again ;)
 
ok, well, i have no idea, how a debug line looks like :mischief: but i tried such a debug-tool in PythonWin. A lot of importerrors occur (like "ImportError: No module named CvPythonExtensions"). Probably the wrong way, to find the bug.

yeah Consts.py was missing (i used it some times before, but not yet in the new testmod; thx4hint). So i included it and changed the nations in addition to the 18Civs-map. Still no success :( i also included PyHelpers.py and CvUtil.py.

consts.py:
Code:
# Constants


# globals

from CvPythonExtensions import *
gc = CyGlobalContext()

l0Array =       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
l0ArrayActive = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
l0ArrayTotal =  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

lm1Array =      [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]

# initialise player variables to player IDs from WBS
iEgypt = 0
iIndia = 1
iChina = 2
iGreece = 3
iRome = 4
iPersia = 5
iJapan = 6
iGermany = 7
iMongolia = 8
iFrance = 9
iArabia = 10
iSpain = 11
iEngland = 12
iRussia = 13
iMali = 14
iInca = 15
iAztecs = 16
iAmerica = 17

iNumPlayers = 18
iNumMajorPlayers = 18
iNumActivePlayers = 18
iNumTotalPlayers = 19
iBarbarian = 19
iNumTotalPlayersB = 20

# starting locations coordinates
tCapitals = (
(69, 33), #tThebes
(90, 40), #tDelhi
(102, 47), #tBeijing
(67, 41), #tAthens
(60, 44), #tRome
(82, 39), #tPersepolis
(113, 45), #tKyoto
(62, 52), #tBerlin
(99, 51), #tKarakorum
(55, 50), #tParis
(75, 33), #tMecca
(52, 43), #tMadrid
(53, 54), #tLondon
(73, 54), #tMoskow
(53, 31), #tTimbuktu
(28, 22), #tCuzco
(18, 37), #tTenochtitlan
(27, 46) #tWashington
)

thx again and again. i can't express how happy i would be, if this thing will work!
 
I have decided to help you out sTO!ka. I started with making the map. I took the RFC 3000 BC unlocked map and the Earth18Civs map and have merged them. There are more civs in RFC than 18, so I used the 18 civs from Earth18Civs:

----------------
Earth18Civs
----------------

Egypt
India
China
Greece
Rome
Persia
Japan
Germany
Mongol
France
Arabia
Spain
England
Russia
Mali
Inca
Aztec
America

----------------
RFC civs
----------------

iEgypt = 0
iIndia = 1
iChina = 2
#iBabylonia = 3
iGreece = 4
iPersia = 5
#iCarthage = 6
iRome = 7
iJapan = 8
#iEthiopia = 9
#iMaya = 10
#iVikings = 11
iArabia = 12
#iKhmer = 13
iSpain = 14
iFrance = 15
iEngland = 16
iGermany = 17
iRussia = 18
#iNetherlands = 19
iMali = 20
#iPortugal = 21
iInca = 22
iMongolia = 23
iAztecs = 24
#iTurkey = 25
iAmerica = 26

# to be removed

I then made the following changes:

- BONUS_COTTON -> BONUS_INCENSE
- removed BonusType=BONUS_SWAMP
- FeatureType=FEATURE_MUD -> FeatureType=FEATURE_JUNGLE
- TerrainType=TERRAIN_MARSH -> TerrainType=TERRAIN_GRASS

I then updated the starting locations by using this part from Consts.py

Code:
# starting locations coordinates
tCapitals = (
(69, 33), #tThebes
(90, 40), #tDelhi
(102, 47), #tBeijing
(76, 40), #tBabylon
(67, 41), #tAthens
(82, 39), #tPersepolis
(58, 39), #tCarthage
(60, 44), #tRome
(113, 45), #tKyoto
(72, 29), #tAksum
(22, 35), #tTikal
(61, 62), #tNidaros
(75, 33), #tMecca
(102, 34), #tAngkor
(52, 43), #tMadrid
(55, 50), #tParis
(53, 54), #tLondon
(62, 52), #tBerlin
(73, 54), #tMoskow
(57, 53), #tAmsterdam
(53, 31), #tTimbuktu
(49, 43), #tLisboa
(28, 22), #tCuzco
(99, 51), #tKarakorum
(18, 37), #tTenochtitlan
(70, 43), #tSogut ((72, 43), #tKonya  #71?)
(27, 46) #tWashington
)

The result is a working BTS earth map with enlarged Europe. You can download the attachment and drop it in PublicMaps to play it just like Earth18Civs.

With this map, you don't have to redefine the coordinates from the Python. I'll start with the Python part next...
 

Attachments

  • RFC18Civs.zip
    37.2 KB · Views: 265
I have the Python part working:

onCityBuilt:



onCityAcquired:



I'll run a couple of more tests before I upload the entire thing...

Edit: Testing was needed, as I forgot to switch the order of Rome and Persia. In Earth18civs Rome comes before Persia, but in RFC after.

P.S. The terrain graphics in the screenshots are from Blue Marble
 
Looks like I've got a working version. I have added some XML for:

- minimal city distance: 2 -> 1
- civ colors: same as in RFC
- city lists: same as in RFC (naming of cities in case of tCityMap value = -1)

@stO!Ka

Let me know if you find any bugs. I haven't tested all the civs...

To play this, extract zip to Mods, load mod "Dynamic City Names", choose Single Player -> Play Scenario -> RFC18Civs

EDIT: removed old, buggy attachment. See post #24 for new version
 
@strategyonly

Ok, I have updated the attachment and have made the changes in the Permanent Settings of my editor, so it won't happen again (forgot that). As for editors: I get you when it comes to Notepad+, I've never been able to make it my main editor, but that's because I have been using EditPlus for so long now. But just plain Notepad? How do you ever get things done quickly without any form of syntax highlighting?
 
@strategyonly

Ok, I have updated the attachment and have made the changes in the Permanent Settings of my editor, so it won't happen again (forgot that). As for editors: I get you when it comes to Notepad+, I've never been able to make it my main editor, but that's because I have been using EditPlus for so long now. But just plain Notepad? How do you ever get things done quickly without any form of syntax highlighting?


Yeah i tried Notepad + and it messed up my XML so i went back to regular Notepad, i really like it alot, i dont know, thats what i started with and i have tried like five different XML editors and HATE them so Notepad is my main choice, well only choice, LOL. And thx.

EDIT: OK just tried the map again above and same thing.
 
@fierabras and all you're awesome :crazyeye: it would have took me weeks, to mangage all that

i'll need to try it ...........
 
Let me know how it works out...

i'm so happy ^^ that's all i ever wanted, thx again!! :)

a few civs seems to be bugged still. But i just took a fast look on, using chipotle-cheat-mode to view the whole earth: there are England, Germany, Russia, Mongolia, Arabs, Spain (?), Inca with the wrong names. that's it, i think.
 
i'm so happy ^^ that's all i ever wanted, thx again!! :)

a few civs seems to be bugged still. But i just took a fast look on, using chipotle-cheat-mode to view the whole earth: there are England, Germany, Russia, Mongolia, Arabs, Spain (?), Inca with the wrong names. that's it, i think.

Correct, I checked and the order of civs in CvCityNameManager.py is still not in sync with the order of civs in the WBS(map). I also made a typo in the 'XML/Civilizations' folder, so the new city lists and civ colors were not active yet. Another more trickier problem is the translation of special characters. For instance:

Tenochtitl& #225;n becomes Tenochtitl#225;n, instead of Tenochtitlán

This problem took me a while until I found the answer in Rhye's dll source for CvCity.cpp

Code:
void CvCity::setName(const wchar* szNewValue, bool bFound)
{
	CvWString szName(szNewValue);
	//gDLL->stripSpecialCharacters(szName); //Rhye - enable &#xxx;

The stripSpecialCharacters() function removes the '&' and therefore Rhye commented it out and deactivated it. I'll see if I can make a workaround without using a dll.
 
Top Bottom