1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

Updated City Name Manager

Discussion in 'Rhye's and Fall Modmods' started by Baldyr, Jul 31, 2010.

  1. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    Zaanzie, you did good. :goodjob: You qualify to do this, so I guess all you need to do while we wait (you could check the data for errors also) is to talk with nody and gang about what portion of the data you wanna process. Because two or more people shouldn't work on the same data at the same time.
     
  2. usi

    usi Shogun

    Joined:
    Jun 20, 2007
    Messages:
    239
    Location:
    Connecticut, USA
    OK, I started reading the python code, and the problem seems to be that the value of "player" is sometimes the same as "city[0]" 's in the processEntries function. At least for the Sanshan/Dalnij/Dairen/Dalian case, there is no mistake in the original file, so, processEntries and/or specialCases requires some changes, though I am not yet sure precisely where should be changed and how.

    Other than that, Viking city names seem to be missing.
     
  3. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    No, you're missing something. When there is an exception, then the city name variable isn't a string type, but rather a tuple containing a ePlayer and a string. So this is all you are seeing - the script has to get both the ePlayer and the city name string from the tuple. Because it has to be written in dictionary format, not tuple format.

    And I remember looking up the current code for this specific dynamic city name change and finding it flawed. Can you prove that it isn't? Or do I need to revisit it and prove that it is? (Basically my script has already proved this, unless its flawed, of course. I'm not aware of any such flaw at this point.)

    edit: This is what special cases/exceptions really are:
    Code:
            for player in entries:
                    entry = entries[player]
                    for eCurrent in range(27):
                            alias = getAlias(entry, eCurrent)
                            if alias != "" and not alias in lAliases:
                                    specialCases[lPlayers[eCurrent]] = (lPlayers[ePlayer], alias)
    So the code loops through all city name map entries for the a map tile stored in the entries dictionary. Then loops through all major players assigning those value to eCurrent. Then it calls getAlias() which in turn runs Rhye's conditional statements in renameCities() - all of them - with eCurrent as "iPlayer" and entry as "szName" (or whatever the variable is in Rhye's code). If the returned string isn't present in the lAliases list for that tile, then something is broken with Rhye's code. Hence the city name alias causing the issue and the city name map owner are added as a tuple in the specialCases dictionary for that tile.

    This is the actual logic behind the raw data I submitted. I still think the important thing is to correct any issues with the raw data, unless of course there is something wrong with my script. (Then we correct that instead.)

    Interesting. What do you mean? For instance?
     
  4. Zaanzie

    Zaanzie Chieftain

    Joined:
    Aug 5, 2010
    Messages:
    140
    Location:
    Belgium
    I don't completely understand wat you mean.
     
  5. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    I mean that nody is already doing his own alternate City Name Manager. I was hoping he'll adopt my new setup and work with that instead. This pretty much makes him group leader on this thing.

    So if you're doing say the Low Countries, then anyone else probably shouldn't be doing those tiles. Because then we end up with two conflicting sets of data - and we only need one.
     
  6. usi

    usi Shogun

    Joined:
    Jun 20, 2007
    Messages:
    239
    Location:
    Connecticut, USA
    With the Viking city names, for example, I couldn't find Nidaros nor its plot (62, 63) in the generated file.
    I guess such cities are skipped because they never get renamed via conquests or city trades.
    Changing
    Code:
    if len(entries) > 0:
    to something like
    Code:
    if len(lAliases) > 0:
    might solve the problem. But I'm just guessing.

    I don't mean the original file is error-free.
    But with Sanshan etc, I find no error in the original file.

    Based on the huge array in the original file, if China builds a city on one of these plots, the city will be named Sanshan.
    It must be working - I have built Sanshan many times.
    If that's Japan, it will be Dairen, and if that's Russia, it will be Dal'nij, based on the array.

    Then, here's the list of Sanshan etc related lines in the original file

    Code:
    Line 2323 (when China got - but not built - the city)
    elif (sName == "Dal'nij" or sName == 'Dairen'):
        city.setName('Dalian', False)
    	
    Line 2948 (when Japan got the city)
    elif (sName == "Dal'nij" or sName == 'Dalian' or sName == 'Sanshan'):
        city.setName('Dairen', False)
    
    Line 4391 (when Russia got the city)
    elif (sName == 'Dairen' or sName == 'Dalian' or sName == 'Sanshan'):
    	city.setName("Dal'nij", False)
    The first set of lines make Russian name (Dal'nij) or Japanese (Dairen) name to Chinese name (Dalian).
    The second set of lines make Russian name (Dal'nij), initial Chinese name (Sanshan), or later Chinese name (Dalian) to Japanese name (Dairen).
    The third set works like the socond one.

    So, none of the lines appear to be problematic, though, yeah, I found no apparent problem in your code yet either (going through a lot of arrays and hashes in loops isn't easy without a good debugging tool).
     
  7. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    The raw data isn't mirroring the city name maps exactly and this is by design. A map tile entry with no dynamic city name change data is a basically a dud, although it would still provide a iDefault value for unlikely founders settling on that tile. Do we need such entries? (The default names are basically left over information that could be discarded as easily. I might just do that if we can't start agreeing on these issues...)

    Keep in mind that there are over 8000 tiles in RFC and we might end up with a lot of data entries if we include every single tile represented in the city name maps. Like those Roman city names that aren't really city names, but rather geographical names.

    Looking at the City Name Manager code you posted there should indeed not be any issue with that tile/those tiles. Now explain to me why this data isn't doing Rhye's code justice:
    Code:
    (106, 47): { iDefault:'Sanshan', iChina:(iChina, 'Dalian'), iJapan:'Dairen', iRussia:'Dal'nij' },
    (106, 47): { iDefault:'Dairen', iChina:'Dalian', iRussia:'Dal'nij' },
    (106, 47): { iDefault:'Dal'nij', iChina:'Dalian', iJapan:'Dairen' },
    Sure, we need to process this data, pick which default name we wanna use and so on. But even the new Chinese name is included on the first line as an exception. (When China re-acquires the city it renames to Dalian.) So I propose we go with it then. Or we choose any other of these 3 lines. Or we come up with something better ourselves. But can we please just accept Rhye's code as it is and start processing the data it is generating?

    I'm not seeing any of the problems you're trying to point out. Sorry. But I do appreciate you trying to validate the data. This is more important than me being right or my script being perfect. Because I'll change it in a heartbeat as soon as I know what you need.

    And I didn't ask you to debug my script, just to look over the raw data - and compare the information with Rhye's original logic.
     
  8. usi

    usi Shogun

    Joined:
    Jun 20, 2007
    Messages:
    239
    Location:
    Connecticut, USA
    I'm not trying to pollute your code. I would only make suggestions. No worry.:lol:

    Well, then, which data in which file will be looked for if someone including the Vikings founds a city on the plot for Nidaros?
    In the original file, if a civ founds a city in a "-1" plot, "city" tags in CIV4CivilizationInfos.xml will be checked.
    So, unless we somehow accomodate Nidaros for the plot, Vikings will build Birka (the first city tag entry in the xml), instead of Nidaros.
    Thus, default plot names should be provided in the generated file or in another file.

    Let me make sure one thing.

    Am I right to read
    Code:
    iChina:(iChina, 'Dalian') 
    as
    Code:
    If China got the city when its previous owner is China, the city will be named 'Dalian'
    ?

    I was reading the code this way, and because it is impossible to conquer a Chinese city as China, I said that it was not working.

    But after reading your latest post, I started to doubt that the code might read
    Code:
    If China got the city, and if it was initially built by China, the city will be named 'Dalian'
    If so, there is no error or likes. If that's the case, sorry, I misunderstood.
    But I presume that with this interpretation there must be a storage for initial founders of all the cities. Is that right?
     
  9. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    I apologize for the increasing desperation coming through in the tone of my voice, but now I've actually put more work into explaining how my setup works than into the actual coding. I seriously don't know how much of the same questions I can stomach.

    The are no issues, as far as I can see. And you can still basically get what ever it is your hearts desire - you explain it to me and I ask the stupid questions. Hows that?

    The city name maps, for the last (!) time, are and always will be king. Nothing trumps a city name map. Never. Ever. (Don't even think about such a thing. Seriously.) So forget about the my data even existing for founding cities - except of course if there is no city map entry for the tile. Then its the default name - for any adjacent tile if none exists for the exact tile. And only if all else fails will the game resort the the XML city name list.

    But I seriously regret ever proposing any "default" names, because as far as I can tell nobody has been able to understand what they are or what the do. So that is the definition of a bad idea. My bad.

    And I'm using the CyCity.getOriginalOwner() method - does this answer your last question?

    If someone doesn't start validating the raw data very soon I will just forget about the whole thing and everyone can do whatever they want. Use the old City Name Manager, process the raw data I supplied, come up with your own setup, whatever. Because we're doing absolutely no progress with my idea. What so ever.

    Any more questions?
     
  10. usi

    usi Shogun

    Joined:
    Jun 20, 2007
    Messages:
    239
    Location:
    Connecticut, USA
    I guess now I know better, but could you organize information a bit better, make it more comprehensible for average people, and place it on the first post?

    Following other people's logic isn't easy, especially when the ideas are scattered around in many pages of a thread.
    Unless many people - as opposed to nobody - can understand how it works, the nearly 2000 lines of data can't get processed properly.
     
  11. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    Yeah, you're absolutely right. I don't believe this is doable either. Someone would need to organize this better. But since I don't think anyone is going to be able to validate the data, there would be no point.

    And I just realized the data I posted is missing any Celtic/Byzantine "special cases".

    edit: I attached a new version of the raw data, since my script turned out to be missing something after all. Do with it what you may.

    Also, this is the prototype for the actual City Name Manager code:
    Spoiler :
    Code:
    iDefault = -1
    
    dynamicCityNameDict = {
    }
    
    class CityNameManager:
    
            def assignName(self, pCity):
                    """Names a city depending on its plot"""
                    iOwner = pCity.getOwner()
                    if (iOwner < iNumMajorPlayers):
                            cityName = tCityMap[iOwner][67 - pCity.getY()][pCity.getX()]
                            if (cityName != "-1"):
                                    self.setCityName(pCity, cityName)
                                    return
                    self.renameCities(pCity, iDefault)
    
            def renameCities(self, pCity, iNewOwner):
                    """Renames a city depending on the map tile"""
                    tCoords = (pCity.getX(), pCity.getY())
                    newName = self.getDynamicName(tCoords, pCity, iNewOwner)
                    if len(newName):
                             self.setCityName(pCity, newName)
                    else:
                             self.checkAdjacentTiles(pCity, tCoords, iNewOwner, newName)
    
            def checkAdjacentTiles(self, pCity, tCoords, iPlayer, newName):
                    for iX in range(tCoords[0] - 1, tCoords[0] + 2):
                             for iY in range(tCoords[1] - 1, tCoords[1] + 2):
                                     newName = self.getDynamicName((iX, iY), pCity, iPlayer)
                                     if len(newName):
                                             self.setCityName(pCity, newName)
                                             return
    
            def setCityName(self, pCity, newName):
                    pCity.setName(newName, False)
    
            def getDynamicName(self, tCoords, pCity, iPlayer):
                    entry = dynamicCityNameDict.get(tCoords, {})
                    if len(entry):
                            defaultName = entry.get(-1, "")
                            if iPlayer == iDefault:
                                    return defaultName
                            newName = entry.get(iPlayer, defaultName)
                            if isinstance(newName, tuple):
                                    if pCity.getOriginalOwner() == newName[0]:
                                            newName = newName[1]
                                    else:
                                            newName = defaultName
                            return newName
                    return ""

    It needs to be tested throughly, of course. But first the processed data must be entered inside dynamicCityNameDict. Because on its own the code of course achieves nothing.

    If someone finds any use for any of this they may indeed use it. Unfortunately I can't get the data right on my own, so its all pretty useless to me. But it was great fun figuring out the code, and I think I learned a lot. Too bad I was never able to explain any of this however. Because I tested it and it works, but the data is still missing, so it can't be tested in-game. I doubt it ever will be.
     

    Attached Files:

  12. nody

    nody Chieftain

    Joined:
    Nov 28, 2004
    Messages:
    1,168
    Location:
    Noviomagus, Batavia
    I'm sorry. I just have a big problem with having just one rename per civ per tile.

    That means no Nouvelle Ibérie or no Nueva Orleans or American Savannah or no American St. Augustine anymore.

    Can't you change the system to a system that works WITHOUT tile-coordinates and WITH original city names.

    I think it would possibly make the code a lot shorter and faster.

    Example:

    A row of city names per civ like: iSpain: 'Nueva Orléans', iFrance 'Nouvelle Orléans', iEngland/iAmerica: 'New Orleans', etc.

    If the original city name is one of those then python should check what civ is playing and rename it accordingly, if the civ isn't in the row then it shouldn't be renamed (or include a default name if you wish).

    It will take care of several tiles at once, since New Orleans can be found on more than 1 tile (as most city names).

    A similar line could take care of Nueva Iberia if Spain founds city on that tile with all the renames of that name.

    Is this possible?
     
  13. Zaanzie

    Zaanzie Chieftain

    Joined:
    Aug 5, 2010
    Messages:
    140
    Location:
    Belgium
    I have 2 problems.

    1) Is there somewhere a map with the tile-coordinates?
    2) I've been searching and I think the Amsterdam-tile is (57, 53), but the list says that it's Utrecht.
     
  14. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    I don't understand what you mean, but I bet you are still confused about how my setup works. Lets just forget about the whole thing, is my humble suggestion. Because nobody will ever be able to understand it anyway. There is no point.

    No.

    No, it wouldn't. But you are welcome to code whatever you want yourself.

    I don't know, I didn't read your example. I can't be bothered with this anymore.

    I'll probably use my own work in another City Name Manager mod-mod in the future. It will probably not be anything like what I tried to propose in this thread, so it won't be of any use for the excellent dynamic city name expansion project you're already running.

    So instead of an expanded City Name Manager with enhancements and new features, there will be the expanded City Name Manager (yours) and a enhanced City Name Manager (mine). But it won't be possible to merge these, so people would have to choose which one to use.
     
  15. Chiyochan

    Chiyochan Chieftain

    Joined:
    Jul 28, 2007
    Messages:
    710
    Location:
    Chiyochan's Country
    I never liked the idea of city names like that for the earth map, I always name my cities based on region if possible, papa new guinea, Sumatra, Kansai, Kanto, Korea, etc.
     

Share This Page