Indicating captured cities

Joined
Apr 11, 2015
Messages
438
I was wondering if it would be possible for conquered cities to be indicated as such in the city banner.

Currently, only conquered capitals are indicated.

t85XOGp.png


It would make mods like Rosetta - Dynamic City Names feasible to use.

I've looked through the files, and there are a couple of bits of relevant code.

From Expansion1_CityBanner_Text.XML:
Code:
<GameData>
    <EnglishText>
        <Row Tag="LOC_CITY_BANNER_ORIGINAL_CAPITAL_TT">
            <Text>Original capital of {1_Owner}</Text>
        </Row>
        <Row Tag="LOC_CITY_BANNER_NEW_CAPITAL_TT">
            <Text>New capital of {1_Owner}</Text>
        </Row>
        <Row Tag="LOC_CITY_BANNER_CAPTURED_CAPITAL_TT">
            <Text>Original capital of {1_OriginalOwner} (Captured)</Text>
        </Row>
        <Row Tag="LOC_CITY_BANNER_OTHER_CITY_TT">
            <Text>City of {1_Owner}</Text>
        </Row>
        <Row Tag="LOC_CITY_BANNER_CITY_STATE_TT">
            <Text>City State</Text>
        </Row>
        <Row Tag="LOC_CITY_BANNER_FREE_CITY_TT">
            <Text>Free City</Text>
        </Row>
   </EnglishText>
</GameData>

From Expansion1_Icons_CityBanner.XML:
Code:
<GameInfo>
    <IconDefinitions>
        <Row Name="ICON_CITY_CAPITAL" Atlas="ICON_ATLAS_EXPANSION_1_CITY_CAPITAL" Index="0"/>
        <Row Name="ICON_NEW_CAPITAL" Atlas="ICON_ATLAS_EXPANSION_1_CITY_CAPITAL" Index="1"/>
        <Row Name="ICON_CAPTURED_CAPITAL" Atlas="ICON_ATLAS_EXPANSION_1_CITY_CAPITAL" Index="2"/>
        <Row Name="ICON_OTHER_CITIES" Atlas="ICON_ATLAS_EXPANSION_1_CITY_CAPITAL" Index="3"/>
        <Row Name="ICON_CITY_STATE" Atlas="ICON_ATLAS_EXPANSION_1_CITY_CAPITAL" Index="4"/>
        <Row Name="ICON_FORMER_CAPITAL" Atlas="ICON_ATLAS_EXPANSION_1_CITY_CAPITAL" Index="5"/>
    </IconDefinitions>
</GameInfo>
Could try something like this and see if it works:
Code:
        <Row Tag="LOC_CITY_BANNER_CAPTURED_OTHER_CITY_TT"">
            <Text>Original city of {1_OriginalOwner} (Captured)</Text>
        </Row>
 
Last edited:
This code, using an existing Atlas icon, didn't work:
Code:
<GameInfo>
    <IconDefinitions>
        <Row Name="ICON_CAPTURED_OTHER_CITY" Atlas="ICON_ATLAS_EXPANSION_1_CITY_CAPITAL" Index="2"/>
    </IconDefinitions>
</GameInfo>
<GameData>
    <EnglishText>
        <Row Tag="LOC_CITY_BANNER_CAPTURED_OTHER_CITY_TT"">
            <Text>Original city of {1_OriginalOwner} (Captured)</Text>
        </Row>
    </EnglishText>
</GameData>
 
You would need to re-write the CityBannerManager.lua User Interface file to make it look for whether or not the city is a captured one and then to use the new Text tag as the text to display showing the relevant data-insertion for the correct civilization.

Adding more icons and Text Tags without also re-writing the lua file where these types of Text Tags are used by the game will not accomplish anything.

Rosetta Stone works by sending an lua instruction to the game to alter the city's "GetName()" value that is accessed by the game's UI files. The name for a city that is retrieved by any of the game's UI files is a Text Tag like LOC_CIVILIZATION_CHEESEBURGLAR_CITY_01, which the UI file then translates into the correct in-game text to display based on the Language of the User. Rosetta Stone's "City:SetName()" command(s) instruct the game to apply a different Text Tag to that city, and all the game's UI lua files then pick up on and use this alteration.
 
You would need to re-write the CityBannerManager.lua User Interface file to make it look for whether or not the city is a captured one and then to use the new Text tag as the text to display showing the relevant data-insertion for the correct civilization.

Adding more icons and Text Tags without also re-writing the lua file where these types of Text Tags are used by the game will not accomplish anything.

Rosetta Stone works by sending an lua instruction to the game to alter the city's "GetName()" value that is accessed by the game's UI files. The name for a city that is retrieved by any of the game's UI files is a Text Tag like LOC_CIVILIZATION_CHEESEBURGLAR_CITY_01, which the UI file then translates into the correct in-game text to display based on the Language of the User. Rosetta Stone's "City:SetName()" command(s) instruct the game to apply a different Text Tag to that city, and all the game's UI lua files then pick up on and use this alteration.
Thanks.

It looks like this is the code relating to captured capitals, or the lower section of it is, anyway:

Code:
            instance.Button:SetTexture("Banner_TypeSlot");
            instance.Button:RegisterCallback(Mouse.eLClick, OnCapitalIconClicked);
            instance.Button:SetVoid1(playerID);
            instance.Button:SetVoid2(cityID);
            instance.Button:SetToolTipString(tooltip);

            -- ORIGINAL OWNER CAPITAL ICON
            if pCity:GetOwner() ~= pCity:GetOriginalOwner() and pCity:IsOriginalCapital() then
                local pOriginalOwner:table = Players[pCity:GetOriginalOwner()];
                -- Only show the captured capital icon for major civs
                if pOriginalOwner:IsMajor() then
                    local instance:table = self.m_InfoIconIM:GetInstance();
                    instance.Icon:SetIcon("ICON_CAPTURED_CAPITAL");
                    local pOriginalOwnerConfig:table = PlayerConfigurations[pCity:GetOriginalOwner()];
                    instance.Button:SetToolTipString(Locale.Lookup("LOC_CITY_BANNER_CAPTURED_CAPITAL_TT", pOriginalOwnerConfig:GetCivilizationShortDescription()));
                    instance.Button:RegisterCallback(Mouse.eLClick, OnCapitalIconClicked);
                    instance.Button:SetVoid1(pCity:GetOriginalOwner());
                    instance.Button:SetVoid2(cityID);
                end
            end
        end

So, for the mod, there would need to be two new icons:

1) Captured city-state

City-states may be considered as capitals of Minor Civilizations, in which case the "only show the captured capital icon for major civs" rule from the existing code could be removed, but it would probably better if city-states had their own code, so they could get their own Text description saying they were a captured city-state.

2) Captured non-capital cities ("OTHER_CITY")

I'm not so experienced with LUA, but I am looking at the code and will relate my understanding of it.

So, starting with the code for non-capital cities ("OTHER_CITY"). I presume it would require duplicating the existing section of code and changing certain parts of it. I've highlighted in red the parts that look like they need to be changed, and will address each in turn.

if pCity:GetOwner() ~= pCity:GetOriginalOwner() and pCity:IsOriginalCapital() then
local pOriginalOwner:table = Players[pCity:GetOriginalOwner()];
-- Only show the captured capital icon for major civs
if pOriginalOwner:IsMajor() then
local instance:table = self.m_InfoIconIM:GetInstance();
instance.Icon:SetIcon("ICON_CAPTURED_CAPITAL");
local pOriginalOwnerConfig:table = PlayerConfigurations[pCity:GetOriginalOwner()];
instance.Button:SetToolTipString(Locale.Lookup("LOC_CITY_BANNER_CAPTURED_CAPITAL_TT", pOriginalOwnerConfig:GetCivilizationShortDescription()));
instance.Button:RegisterCallback(Mouse.eLClick, OnCapitalIconClicked);
instance.Button:SetVoid1(pCity:GetOriginalOwner());
instance.Button:SetVoid2(cityID);

IsOriginalCapital - Not sure what this would need to be. Hypothetically, it would be IsOriginalOtherCity

Or maybe it would need some sort of code saying IF [Capital then use this icon] OTHERWISE [use the OtherCity icon]

pOriginalOwner:IsMajor - I guess this probably is not an issue and can be left unaltered.

ICON_CAPTURED_CAPITAL - Presumably, this would involve creating a new name, graphical icon and adding extra line of code to <IconDefinitions> in XML

LOC_CITY_BANNER_CAPTURED_CAPITAL_TT - Presumably, this would involve creating a new name and adding a couple of lines to <EnglishText> in XML.

OnCapitalIconClicked - Not sure about this.

So it seems like it could be doable, except, perhaps, for the IsOriginalCapital/IsOriginalOtherCity bit. May involve searching Lua for times the game code has needed to specify non-capital cities.
 
Last edited:
For the non-capital cities, what if "== false" was added at the end of the line?
Code:
if pCity:GetOwner() ~= pCity:GetOriginalOwner() and pCity:IsOriginalCapital() == false
Is the "==false" acting on just IsOriginalCapital, or both IsOriginalCapital and GetOriginalOwner?

Or what about:

Code:
if pCity:GetOwner() ~= pCity:GetOriginalOwner() == true and pCity:IsOriginalCapital() == false
 
Last edited:
For the non-capital cities, what if "== false" was added at the end of the line?
Code:
if pCity:GetOwner() ~= pCity:GetOriginalOwner() and pCity:IsOriginalCapital() == false
Is the "==false" acting on just IsOriginalCapital, or both IsOriginalCapital and GetOriginalOwner?
The equality check against the "pCity:IsOriginalCapital()" method would only be used against the later of the two. It would be the same as saying
Code:
if (pCity:GetOwner() ~= pCity:GetOriginalOwner()) and (pCity:IsOriginalCapital() == false) then
Or what about:

Code:
if pCity:GetOwner() ~= pCity:GetOriginalOwner() == true and pCity:IsOriginalCapital() == false
This would not work for various reasons but mostly because no scripting language I am aware of would ever accept this sort of a syntax
Code:
if pCity:GetOwner() ~= pCity:GetOriginalOwner() == true
And the portion of the line as written is already making that evaluation
Code:
if pCity:GetOwner() ~= pCity:GetOriginalOwner()
Is to be interpretted as the code saying
Code:
if it is true that the value for pCity:GetOwner() is not equal to the value for pCity:GetOriginalOwner(), proceed
lua inherently evaluates all conditional querries (ie, X == Y, X ~= Y) as to whether under the current situation the answer to the question being posed is a true statement. Lua only acts upon the "then" portion of a code-chunk if everything between the "if" and "then" command-words are evaluated as being true statements under the current conditions.

One city will pass the "true" test because it is not currently owned by its original owner and it is also an original player capital. The next city may or may not pass the "true" test. This is what I mean by under the current conditions.
 
The equality check against the "pCity:IsOriginalCapital()" method would only be used against the later of the two. It would be the same as saying
Code:
if (pCity:GetOwner() ~= pCity:GetOriginalOwner()) and (pCity:IsOriginalCapital() == false) then
This would not work for various reasons but mostly because no scripting language I am aware of would ever accept this sort of a syntax
Code:
if pCity:GetOwner() ~= pCity:GetOriginalOwner() == true
And the portion of the line as written is already making that evaluation
Code:
if pCity:GetOwner() ~= pCity:GetOriginalOwner()
Is to be interpretted as the code saying
Code:
if it is true that the value for pCity:GetOwner() is not equal to the value for pCity:GetOriginalOwner(), proceed
lua inherently evaluates all conditional querries (ie, X == Y, X ~= Y) as to whether under the current situation the answer to the question being posed is a true statement. Lua only acts upon the "then" portion of a code-chunk if everything between the "if" and "then" command-words are evaluated as being true statements under the current conditions.

One city will pass the "true" test because it is not currently owned by its original owner and it is also an original player capital. The next city may or may not pass the "true" test. This is what I mean by under the current conditions.
So is the first method - just adding "== false" at the end of the line - going to work for all cities?

I tried it out in-game and it appears to have worked. I captured the Maoris' second city and it's showing the captured original capital icon and text.
Spoiler :

ZIzBnZ9.png

 
If that'll work, then I am assuming the LUA part of the mod, for non-capital cities, will involve duplicating the existing code for captured capital cities, and making the following changes:

1) Add "== false" after pCity:IsOriginalCapital()

2) Change "ICON_CAPTURED_CAPITAL" to "ICON_CAPTURED_OTHER_CITY"

3) Change "LOC_CITY_BANNER_CAPTURED_CAPITAL_TT" to "LOC_CITY_BANNER_CAPTURED_OTHER_CITY_TT"

So:
Code:
            if pCity:GetOwner() ~= pCity:GetOriginalOwner() and pCity:IsOriginalCapital()  == false then
                local pOriginalOwner:table = Players[pCity:GetOriginalOwner()];
                -- Only show the captured other city icon for major civs
                if pOriginalOwner:IsMajor() then
                    local instance:table = self.m_InfoIconIM:GetInstance();
                    instance.Icon:SetIcon("ICON_CAPTURED_OTHER_CITY");
                    local pOriginalOwnerConfig:table = PlayerConfigurations[pCity:GetOriginalOwner()];
                    instance.Button:SetToolTipString(Locale.Lookup("LOC_CITY_BANNER_CAPTURED_OTHER_CITY_TT", pOriginalOwnerConfig:GetCivilizationShortDescription()));
                    instance.Button:RegisterCallback(Mouse.eLClick, OnCapitalIconClicked);
                    instance.Button:SetVoid1(pCity:GetOriginalOwner());
                    instance.Button:SetVoid2(cityID);
                end
            end
        end
 
It worked for city-states too. I just changed pOriginalOwner:IsMajor() to pOriginalOwner:IsMinor()

Does anyone have the graphics for these icons?

<Row Name="ICON_CITY_CAPITAL" Atlas="ICON_ATLAS_EXPANSION_1_CITY_CAPITAL" Index="0"/>
<Row Name="ICON_NEW_CAPITAL" Atlas="ICON_ATLAS_EXPANSION_1_CITY_CAPITAL" Index="1"/>
<Row Name="ICON_CAPTURED_CAPITAL" Atlas="ICON_ATLAS_EXPANSION_1_CITY_CAPITAL" Index="2"/>
<Row Name="ICON_OTHER_CITIES" Atlas="ICON_ATLAS_EXPANSION_1_CITY_CAPITAL" Index="3"/>
<Row Name="ICON_CITY_STATE" Atlas="ICON_ATLAS_EXPANSION_1_CITY_CAPITAL" Index="4"/>
<Row Name="ICON_FORMER_CAPITAL" Atlas="ICON_ATLAS_EXPANSION_1_CITY_CAPITAL" Index="5"/>

Presumably, they are in the Development Assets bundle, which would take 37 Gigabytes/two and a half hours to download.
 
So long as the Atlas name you are referencing to is already a part of the game you will not need to do anything so far as creating a new icon image. You can just add a new definition of an icon in table <IconDefinitions> and re-use the existing Atlas and Portrait "Index" number.
 
I guess I can download the Assets package tomorrow.

Meanwhile, here's the XML, except for the Atlas link to new graphical icons:
Code:
<GameInfo>
    <IconDefinitions>
        <Row Name="ICON_CAPTURED_OTHER_CITY" Atlas="ICON_ATLAS_EXPANSION_1_CITY_CAPITAL" Index="3"/>
        <Row Name="ICON_CAPTURED_CITY_STATE" Atlas="ICON_ATLAS_EXPANSION_1_CITY_CAPITAL" Index="4"/>
    </IconDefinitions>
</GameInfo>
<GameData>
    <EnglishText>
        <Row Tag="LOC_CITY_BANNER_CAPTURED_OTHER_CITY_TT">
            <Text>Original city of {1_OriginalOwner}</Text>
        </Row>
        <Row Tag="LOC_CITY_BANNER_CAPTURED_CITY_STATE_TT">
            <Text>Original city of {1_OriginalOwner} (city-state)</Text>
        </Row>
   </EnglishText>
</GameData>
Here are the two sections of lua code, although I don't know where to start or end the edit snip of the code, or how to set them up to be added to the game via lua.
Code:
            instance.Button:SetTexture("Banner_TypeSlot");
            instance.Button:RegisterCallback(Mouse.eLClick, OnCapitalIconClicked);
            instance.Button:SetVoid1(playerID);
            instance.Button:SetVoid2(cityID);
            instance.Button:SetToolTipString(tooltip);

            -- ORIGINAL OWNER OTHER CITY ICON
            if pCity:GetOwner() ~= pCity:GetOriginalOwner() and pCity:IsOriginalCapital()  == false  then
                local pOriginalOwner:table = Players[pCity:GetOriginalOwner()];
                -- Only show the captured other city icon for major civs
                if pOriginalOwner:IsMajor() then
                    local instance:table = self.m_InfoIconIM:GetInstance();
                    instance.Icon:SetIcon("ICON_CAPTURED_OTHER_CITY");
                    local pOriginalOwnerConfig:table = PlayerConfigurations[pCity:GetOriginalOwner()];
                    instance.Button:SetToolTipString(Locale.Lookup("LOC_CITY_BANNER_CAPTURED_OTHER_CITY_TT", pOriginalOwnerConfig:GetCivilizationShortDescription()));
                    instance.Button:RegisterCallback(Mouse.eLClick, OnCapitalIconClicked);
                    instance.Button:SetVoid1(pCity:GetOriginalOwner());
                    instance.Button:SetVoid2(cityID);
                end
            end
        end
Code:
            instance.Button:SetTexture("Banner_TypeSlot");
            instance.Button:RegisterCallback(Mouse.eLClick, OnCapitalIconClicked);
            instance.Button:SetVoid1(playerID);
            instance.Button:SetVoid2(cityID);
            instance.Button:SetToolTipString(tooltip);

            -- ORIGINAL OWNER CITY-STATE ICON
            if pCity:GetOwner() ~= pCity:GetOriginalOwner() and pCity:IsOriginalCapital() then
                local pOriginalOwner:table = Players[pCity:GetOriginalOwner()];
                -- Only show the captured capital icon for minor civs
                if pOriginalOwner:IsMinor() then
                    local instance:table = self.m_InfoIconIM:GetInstance();
                    instance.Icon:SetIcon("ICON_CAPTURED_CITY_STATE");
                    local pOriginalOwnerConfig:table = PlayerConfigurations[pCity:GetOriginalOwner()];
                    instance.Button:SetToolTipString(Locale.Lookup("LOC_CITY_BANNER_CAPTURED_CITY_STATE_TT", pOriginalOwnerConfig:GetCivilizationShortDescription()));
                    instance.Button:RegisterCallback(Mouse.eLClick, OnCapitalIconClicked);
                    instance.Button:SetVoid1(pCity:GetOriginalOwner());
                    instance.Button:SetVoid2(cityID);
                end
            end
        end
 
Here's an old save with captured city-states showing with the captured capital icon.
Spoiler :

r8GPZqr.png

It's good seeing some visual information about cities changing hands, although it does lengthen the city banner.

A more economical solution with regards to space, would be for cities that have changed ownership use a different city icon. The normal city icon - the leftmost icon - is rather dull, being just a dot/circle. Then the original city owner could be revealed when mousing over this icon:

Dx540Ff.png

So it could say:

City of Mongolia
Original city of Bandar Brunei (city-state)
 
Last edited:
I was thinking of doing something like this, with Civilization cities not owned by the original owner having a different City Icon. Mousing over the icon would display the original owner. The image is a screenshot that's been drawn on.

0z8fMxI.png
 
Back
Top Bottom