Assigning a City a unique identifier

FramedArchitect

Reluctant Modder
Joined
Mar 25, 2012
Messages
802
Location
Missouri
I'm creating an array that I need to hold unique city identifiers (i.e. I need a city identifier that survives conquest, gifting, razing, saving*, etc).

Can the city instance serve as a unique identifier in the array? Or should I just save a playerID with the cityID in order to pull the city instance as needed?

*The city identifier will be saved as persistent data with Pazyryk's TableSaverLoader.
 
Can the city instance serve as a unique identifier in the array? Or should I just save a playerID with the cityID in order to pull the city instance as needed?

That's pretty much what Firaxis does right now if you look in firetuner.

Another approach might be to store the plot X,Y coordinates as they are unique and can easily be referenced via:
local city = plot:GetPlotCity();
 
Nothing "survives" all of those listed events.

For every city on the map at the current time both [iPlayer:iCity] and [iPlotX:iPlotY] are unique

Both remain the same over game save/load

For conquest, gift (in trade) or buyout [iPlotX:iPlotY] stays the same but [iPlayer:iCity] changes (both parts as the game core creates a brand new city for the receiving player and copies info from the old city to the new)

For razing neither are unique as iCity may be reassigned to a new city built by iPlayer and anyone may build a new city on the old plot - in either case you will have one "unique" reference to two (or more) possible cities

A combination of both (ie [iPlayer:iCity:iPlotX:iPlotY]) will give you the least chance of a clash - as that implies that iPlayer just happened to rebuild a city on a previously razed plot that just happens to get the same city id as the old one on that plot. A probability not worth worrying about! You will also need to hook the CityCaptureComplete event to change player/city id when a city changes hands.
 
Thanks for the replies. I've gone with your suggestion, and am using x, y coords as identifiers. I'm using SerialEventCityDestroyed to clean up the array and avoid a "new city on old plot" issue.

Commander, you may be able to help me out here, as I've run into an issue when adding new city bar icons (like razing, connected, etc) via CityBannerManager.

I have a global function that returns boolean to turn on my new city bar icon. The function iterates the above referenced array. Oddly, CityBannerManager always gets a false return on this global, whereas other internal functions return expected values. I am hooking CityBannerManager's city instance, and I'm thinking this may be the problem?
 
I'm using SerialEventCityDestroyed to clean up the array and avoid a "new city on old plot" issue.

Like most of the SerialEvents that only triggers if the player can see the plot, you'll need to use GameEvents.SetPopulation which triggers for all cities regardless. See TurnsRemaining.lua in the DLC_02 (Spain and Inca?) scenario for an example.
 
Commander, you may be able to help me out here, as I've run into an issue when adding new city bar icons (like razing, connected, etc) via CityBannerManager.

I have a global function that returns boolean to turn on my new city bar icon. The function iterates the above referenced array. Oddly, CityBannerManager always gets a false return on this global, whereas other internal functions return expected values. I am hooking CityBannerManager's city instance, and I'm thinking this may be the problem?

The way I reference my global arrays in the UI is based on the method Gedemon uses in his RED WWII mod.

I use the share utils available on the forum (comes with Gedemon's mod) and have the following entries in my lua files.

My main file has the following:
Code:
include( "ShareData.lua" )

-----------------------------------------------------------------------------------------------------------------------
-- Data Sharing Functions
-----------------------------------------------------------------------------------------------------------------------
-- Global arrays I reference in my scenario...

function ShareGlobalTables()
	print("Sharing Global Tables...")
	g_Towns = share ("Towns", g_Towns)
	g_CitySupplyData = share ("CityData", g_CitySupplyData)
	g_GlobalSupplyCounters = share ("GlobalCounters", g_GlobalSupplyCounters)
end

Those tables are global array I reference in my UI files.

I then create a separate reference lua file (lets call it ReferenceArrays.lua for this example ) that contains the following:
Code:
--------------------------------------------------------------
-- Share global tables after initialization...
--------------------------------------------------------------
Events.LoadScreenClose.Add( ShareGlobalTables )

Then all I need to do is add the following entry at the top of my CityBanner file

Code:
include ("ReferenceArrays")

Then my arrays are exposed and used by the UI. Hopefully that is what you are asking, otherwise, whoward might be better at answering your question as he is the resident UI guru.
 
I use iPlot for this rather than x, y. Arrays are simpler that way. You have to write your own GetPlotIndexFromXY() function, but that's easy.
 
Then my arrays are exposed and used by the UI. Hopefully that is what you are asking, otherwise, whoward might be better at answering your question as he is the resident UI guru.

Hi Commander, yes that was my question exactly. Thank you for sharing your method, it works exactly as you explained!

However, I had to load up SaveUtils in order to enable SaveData, which then squashed Pazyryk's TableSaverLoader functionality. Do you use saveutils, too, or a modified version of savedata?
 
Back
Top Bottom