-------------------------------------------------
-- Updates banner to reflect latest city info.
-------------------------------------------------
function RefreshCityBanner(cityBanner, iActiveTeam, iActivePlayer)
if ( Instances[ cityBanner.playerID ] == nil or Instances[ cityBanner.playerID ][ cityBanner.cityID ] == nil ) then
return;
end
local strToolTip = "";
local player = Players[cityBanner.playerID];
local team = Players[cityBanner.playerID]:GetTeam();
local isActivePlayerCity = (cityBanner.playerID == iActivePlayer);
local isActiveTeamCity = false;
if (iActiveTeam == team) then
isActiveTeamCity = true;
end
-- grab city using playerID and cityID
local city = player:GetCityByID(cityBanner.cityID);
-- for debugging purposes, we want to be able to create a city banner without a DLL-side city
--assert(city);
local bHasSpy = false;
local strSpyName = nil;
local strSpyRank = nil;
if(city ~= nil) then
local cityX = city:GetX();
local cityY = city:GetY();
local activePlayer = Players[iActivePlayer]
local spies = activePlayer:GetEspionageSpies();
for i,v in ipairs(spies) do
if(v.CityX == cityX and v.CityY == cityY) then
bHasSpy = true;
strSpyName = Locale.Lookup(v.Name);
strSpyRank = Locale.Lookup(v.Rank);
end
end
end
local controls = cityBanner.SubControls;
-- Update colors
local primaryColor, secondaryColor = player:GetPlayerColors();
if player:IsMinorCiv() then
primaryColor, secondaryColor = secondaryColor, primaryColor;
end
local backgroundColor = {x = secondaryColor.x, y = secondaryColor.y, z = secondaryColor.z, w = 0.7};
controls.CityBannerBackground:SetColor(backgroundColor);
if( isActiveTeamCity )then
controls.CityBannerBGLeftHL:SetColor( backgroundColor );
controls.CityBannerBGRightHL:SetColor( backgroundColor );
controls.CityBannerRightBackground:SetColor( backgroundColor );
controls.CityBannerLeftBackground:SetColor( backgroundColor );
else
--NOTE: If the active player were to ever change (such as during an auto play) these controls will not exist because
-- the city banner is of the "active player" type and not the "other player" type.
-- This fix is merely a fix to the Lua nil value error and not a proper solution to the problem.
if(controls.RightBackground ~= nil and controls.LeftBackground ~= nil) then
controls.RightBackground:SetColor( backgroundColor );
controls.LeftBackground:SetColor( backgroundColor );
end
end
local textColor = {x = primaryColor.x, y = primaryColor.y, z = primaryColor.z, w = 1};
local textColor200 = {x = primaryColor.x, y = primaryColor.y, z = primaryColor.z, w = 0.7};
local textColorShadow = {x = 0, y = 0, z = 0, w = 0.5};
local textColorSoft = {x = 1, y = 1, z = 1, w = 0.5};
if(controls.CityProductionName) then
controls.CityProductionName:SetColor(textColor200, 0);
end
controls.CityName:SetColor(textColor, 0);
controls.CityName:SetColor(textColorShadow, 1);
controls.CityName:SetColor(textColorSoft, 2);
--print("No city");
if city ~= nil then
-- Update name
local cityName = city:GetNameKey();
local localizedCityName = Locale.ConvertTextKey(cityName);
local convertedKey = Locale.ToUpper(localizedCityName);
-- Update capital icon
local isCapital = city:IsCapital() or Players[city:GetOriginalOwner()]:IsMinorCiv();
if (city:IsCapital() and not player:IsMinorCiv()) then
convertedKey = "[ICON_CAPITAL]" .. convertedKey;
end
controls.CityName:SetText(convertedKey);
if (isActivePlayerCity) then
if (city:IsPuppet()) then
strToolTip = Locale.ConvertTextKey("TXT_KEY_CITY_ANNEX_TT");
else
strToolTip = Locale.ConvertTextKey("TXT_KEY_CITY_ENTER_CITY_SCREEN");
end
elseif (isActiveTeamCity) then
strToolTip = Locale.ConvertTextKey("TXT_KEY_CITY_TEAMMATE");
elseif (Game.IsOption( GameOptionTypes.GAMEOPTION_ALWAYS_WAR )) then
strToolTip = Locale.ConvertTextKey("TXT_KEY_ALWAYS_AT_WAR_WITH_CITY");
elseif (player:IsMinorCiv()) then
local strStatusTT = GetCityStateStatusToolTip(iActivePlayer, cityBanner.playerID, false);
strToolTip = strToolTip .. strStatusTT;
controls.StatusIconBG:SetToolTipString(strStatusTT);
controls.StatusIcon:SetToolTipString(strStatusTT);
elseif (not Teams[Game.GetActiveTeam()]:IsHasMet(player:GetTeam())) then
strToolTip = Locale.ConvertTextKey("TXT_KEY_HAVENT_MET");
else
strToolTip = Locale.ConvertTextKey("TXT_KEY_TALK_TO_PLAYER");
end
local eReligion = city:GetReligiousMajority();
if (eReligion >= 0) then
local religion = GameInfo.Religions[eReligion];
IconHookup( religion.PortraitIndex, 32, religion.IconAtlas, controls.ReligiousIcon );
IconHookup( religion.PortraitIndex, 32, religion.IconAtlas, controls.ReligiousIconShadow );
end
local religionToolTip = "";
if(GetReligionTooltip) then
religionToolTip = GetReligionTooltip(city);
end
if (religionToolTip ~= "") then
strToolTip = strToolTip .. "[NEWLINE]----------------[NEWLINE]" .. religionToolTip;
end
controls.BannerButton:SetToolTipString(strToolTip);
if (controls.ReligiousIcon ~= nil) then
controls.ReligiousIcon:SetToolTipString(religionToolTip);
end
local bHasReligion = (eReligion >= 0);
if (controls.ReligiousIcon ~= nil) then
controls.ReligiousIconContainer:SetHide(not bHasReligion);
end
DoResizeBanner(controls);
-- Connected to capital?
if (isActiveTeamCity) then
if (not city:IsCapital() and player:IsCapitalConnectedToCity(city) and not city:IsBlockaded()) then
controls.ConnectedIcon:SetHide(false);
controls.ConnectedIcon:SetToolTipString(Locale.ConvertTextKey("TXT_KEY_CITY_CONNECTED"));
else
controls.ConnectedIcon:SetHide(true);
end
end
-- Blockaded
if (city:IsBlockaded()) then
controls.BlockadedIcon:SetHide(false);
controls.BlockadedIcon:SetToolTipString(Locale.ConvertTextKey("TXT_KEY_CITY_BLOCKADED"));
else
controls.BlockadedIcon:SetHide(true);
end
-- Being Razed
if (city:IsRazing()) then
controls.RazingIcon:SetHide(false);
controls.RazingIcon:SetToolTipString(Locale.ConvertTextKey( "TXT_KEY_CITY_BURNING", tostring(city:GetRazingTurns()) ));
else
controls.RazingIcon:SetHide(true);
end
-- In Resistance
if (city:IsResistance()) then
controls.ResistanceIcon:SetHide(false);
controls.ResistanceIcon:SetToolTipString(Locale.ConvertTextKey( "TXT_KEY_CITY_RESISTANCE", tostring(city:GetResistanceTurns()) ));
else
controls.ResistanceIcon:SetHide(true);
end
-- Puppet Status
if (city:IsPuppet()) then
controls.PuppetIcon:SetHide(false);
if(isActivePlayerCity) then
controls.PuppetIcon:SetToolTipString(Locale.ConvertTextKey("TXT_KEY_CITY_PUPPET"));
else
controls.PuppetIcon:SetToolTipString(Locale.ConvertTextKey("TXT_KEY_CITY_PUPPET_OTHER"));
end
else
controls.PuppetIcon:SetHide(true);
end
-- Occupation Status
if (city:IsOccupied() and not city:IsNoOccupiedUnhappiness()) then
controls.OccupiedIcon:SetHide(false);
controls.OccupiedIcon:SetToolTipString(Locale.ConvertTextKey( "TXT_KEY_CITY_OCCUPIED"));
else
controls.OccupiedIcon:SetHide(true);
end
if(bHasSpy) then
controls.SpyIcon:SetHide(false);
if (isActivePlayerCity) then
controls.SpyIcon:LocalizeAndSetToolTip("TXT_KEY_CITY_SPY_YOUR_CITY_TT", strSpyRank, strSpyName, city:GetName(), strSpyRank, strSpyName);
elseif (player:IsMinorCiv()) then
controls.SpyIcon:LocalizeAndSetToolTip("TXT_KEY_CITY_SPY_CITY_STATE_TT", strSpyRank, strSpyName, city:GetName(), strSpyRank, strSpyName);
else
controls.SpyIcon:LocalizeAndSetToolTip("TXT_KEY_CITY_SPY_OTHER_CIV_TT", strSpyRank, strSpyName, city:GetName(), strSpyRank, strSpyName, strSpyRank, strSpyName);
end
else
controls.SpyIcon:SetHide(true);
end
controls.IconsStack:ReprocessAnchoring();
-- Update strength
local cityStrengthStr = math.floor(city:GetStrengthValue() / 100);
local garrisonedUnit = city:GetGarrisonedUnit();
if garrisonedUnit == nil then
if isActiveTeamCity then
controls.GarrisonFrame:SetHide(true);
end
end
controls.CityStrength:SetText(cityStrengthStr);
if isActiveTeamCity then
controls.EjectGarrison:SetHide(true);
end
UpdateRangeStrikeIcon(cityBanner);
-- Update population
local cityPopulation = math.floor(city:GetPopulation());
controls.CityPopulation:SetText(cityPopulation);
-- Update Growth Time
if(controls.CityGrowth) then
local cityGrowth = city:GetFoodTurnsLeft();
if (city:IsFoodProduction() or city:FoodDifferenceTimes100() == 0) then
cityGrowth = "-";
controls.CityBannerRightBackground:SetToolTipString(Locale.ConvertTextKey("TXT_KEY_CITY_STOPPED_GROWING_TT", localizedCityName, cityPopulation));
elseif city:FoodDifferenceTimes100() < 0 then
cityGrowth = "[COLOR_WARNING_TEXT]-[ENDCOLOR]";
controls.CityBannerRightBackground:SetToolTipString(Locale.ConvertTextKey("TXT_KEY_CITY_STARVING_TT",localizedCityName ));
else
controls.CityBannerRightBackground:SetToolTipString(Locale.ConvertTextKey("TXT_KEY_CITY_WILL_GROW_TT", localizedCityName, cityPopulation, cityPopulation+1, cityGrowth));
end
controls.CityGrowth:SetText(cityGrowth);
end
-- Update Production Time
if(controls.BuildGrowth) then
local buildGrowth = "-";
if (city:IsProduction() and not city:IsProductionProcess()) then
if (city:GetCurrentProductionDifferenceTimes100(false, false) > 0) then
buildGrowth = city:GetProductionTurnsLeft();
end
end
controls.BuildGrowth:SetText(buildGrowth);
end
-- Update Growth Meter
if (controls.GrowthBar) then
local iCurrentFood = city:GetFood();
local iFoodNeeded = city:GrowthThreshold();
local iFoodPerTurn = city:FoodDifference();
local iCurrentFoodPlusThisTurn = iCurrentFood + iFoodPerTurn;
local fGrowthProgressPercent = iCurrentFood / iFoodNeeded;
local fGrowthProgressPlusThisTurnPercent = iCurrentFoodPlusThisTurn / iFoodNeeded;
if (fGrowthProgressPlusThisTurnPercent > 1) then
fGrowthProgressPlusThisTurnPercent = 1
end
controls.GrowthBar:SetPercent( fGrowthProgressPercent );
controls.GrowthBarShadow:SetPercent( fGrowthProgressPlusThisTurnPercent );
end
-- Update Production Meter
if (controls.ProductionBar) then
local iCurrentProduction = city:GetProduction();
local iProductionNeeded = city:GetProductionNeeded();
local iProductionPerTurn = city:GetYieldRate(YieldTypes.YIELD_PRODUCTION);
if (city:IsFoodProduction()) then
iProductionPerTurn = iProductionPerTurn + city:GetYieldRate(YieldTypes.YIELD_FOOD) - city:FoodConsumption(true);
end
local iCurrentProductionPlusThisTurn = iCurrentProduction + iProductionPerTurn;
local fProductionProgressPercent = iCurrentProduction / iProductionNeeded;
local fProductionProgressPlusThisTurnPercent = iCurrentProductionPlusThisTurn / iProductionNeeded;
if (fProductionProgressPlusThisTurnPercent > 1) then
fProductionProgressPlusThisTurnPercent = 1
end
controls.ProductionBar:SetPercent( fProductionProgressPercent );
controls.ProductionBarShadow:SetPercent( fProductionProgressPlusThisTurnPercent );
end
-- Update Production Name
local cityProductionName = city:GetProductionNameKey();
--if city:IsOccupation() then
--cityProductionName = "City in unrest";
if cityProductionName == nil or string.len(cityProductionName) == 0 then
cityProductionName = "TXT_KEY_PRODUCTION_NO_PRODUCTION";
end
if(controls.CityProductionName) then
convertedKey = Locale.ConvertTextKey(cityProductionName);
controls.CityProductionName:SetText(convertedKey);
if controls.CityBannerLeftBackground then
if cityProductionName == "TXT_KEY_PRODUCTION_NO_PRODUCTION" then
controls.CityBannerLeftBackground:SetToolTipString(Locale.ConvertTextKey( "TXT_KEY_CITY_NOT_PRODUCING", localizedCityName ));
else
local productionTurnsLeft = city:GetProductionTurnsLeft();
local tooltipString;
if productionTurnsLeft > 99 then
tooltipString = Locale.ConvertTextKey(Locale.ConvertTextKey("TXT_KEY_CITY_CURRENTLY_PRODUCING_99PLUS_TT", localizedCityName, cityProductionName));
else
tooltipString = Locale.ConvertTextKey(Locale.ConvertTextKey("TXT_KEY_CITY_CURRENTLY_PRODUCING_TT", localizedCityName, cityProductionName, productionTurnsLeft));
end
controls.CityBannerLeftBackground:SetToolTipString(tooltipString);
end
end
end
-- Update Production icon
if controls.CityBannerProductionImage then
local unitProduction = city:GetProductionUnit();
local buildingProduction = city:GetProductionBuilding();
local projectProduction = city:GetProductionProject();
local processProduction = city:GetProductionProcess();
local noProduction = false;
if unitProduction ~= -1 then
local thisUnitInfo = GameInfo.Units[unitProduction];
if IconHookup( thisUnitInfo.PortraitIndex, 45, thisUnitInfo.IconAtlas, controls.CityBannerProductionImage ) then
controls.CityBannerProductionImage:SetHide( false );
else
controls.CityBannerProductionImage:SetHide( true );
end
elseif buildingProduction ~= -1 then
local thisBuildingInfo = GameInfo.Buildings[buildingProduction];
if IconHookup( thisBuildingInfo.PortraitIndex, 45, thisBuildingInfo.IconAtlas, controls.CityBannerProductionImage ) then
controls.CityBannerProductionImage:SetHide( false );
else
controls.CityBannerProductionImage:SetHide( true );
end
elseif projectProduction ~= -1 then
local thisProjectInfo = GameInfo.Projects[projectProduction];
if IconHookup( thisProjectInfo.PortraitIndex, 45, thisProjectInfo.IconAtlas, controls.CityBannerProductionImage ) then
controls.CityBannerProductionImage:SetHide( false );
else
controls.CityBannerProductionImage:SetHide( true );
end
elseif processProduction ~= -1 then
local thisProcessInfo = GameInfo.Processes[processProduction];
if IconHookup( thisProcessInfo.PortraitIndex, 45, thisProcessInfo.IconAtlas, controls.CityBannerProductionImage ) then
controls.CityBannerProductionImage:SetHide( false );
else
controls.CityBannerProductionImage:SetHide( true );
end
else -- really should have an error texture
controls.CityBannerProductionImage:SetHide(true);
end
if isActivePlayerCity then
controls.CityBannerProductionButton:RegisterCallback( Mouse.eLClick, OnProdClick );
controls.CityBannerProductionButton:SetVoids( city:GetID(), nil );
controls.BannerButton:SetDisabled( false );
end
end
-- This is another player's banner instance
if( controls.MinorIndicator and controls.StatusIcon ) then
controls.StatusIcon:SetColor( textColor );
local civType = player:GetCivilizationType();
local civInfo = GameInfo.Civilizations[civType];
if( player:IsMinorCiv() ) then
SetUpMinorMeter(iActivePlayer, cityBanner.playerID, controls, textColor );
-- minor trait icon
controls.StatusIcon:SetTexture( GameInfo.MinorCivTraits[ GameInfo.MinorCivilizations[ player:GetMinorCivType() ].MinorCivTrait ].TraitIcon );
controls.StatusIcon:SetTextureOffsetVal( 0, 0 );
else
IconHookup( civInfo.PortraitIndex, 32, civInfo.AlphaIconAtlas, controls.StatusIcon );
controls.StatusIcon:SetOffsetX( 0 );
controls.StatusIconBG:SetHide( true );
controls.StatusMeterFrame:SetHide( true );
end
local pOriginalOwner = Players[ city:GetOriginalOwner() ];
if( pOriginalOwner:IsMinorCiv() ) then
--if( city:IsPuppet() or city:IsOccupied() ) then
--if( pOriginalOwner ~= player ) then
local _, originalColor = pOriginalOwner:GetPlayerColors();
originalColor.w = 1;
civType = pOriginalOwner:GetCivilizationType();
civInfo = GameInfo.Civilizations[civType];
IconHookup( civInfo.PortraitIndex, 32, civInfo.AlphaIconAtlas, controls.MinorIndicator );
controls.MinorIndicator:SetColor( originalColor );
controls.MinorIndicator:SetHide( false );
-- controls.MinorOccupiedSpacer:SetHide( false );
-- controls.NameStack:SetOffsetX( -7 );
else
controls.MinorIndicator:SetHide( true );
-- controls.MinorOccupiedSpacer:SetHide( true );
-- controls.NameStack:SetOffsetX( -3 );
end
controls.NameStack:CalculateSize();
controls.NameStack:ReprocessAnchoring();
end
-- Refresh the damage bar too
RefreshCityDamage( cityBanner, city:GetDamage(), city:GetMaxHitPoints() );
end
if(controls.NameStack)then
controls.NameStack:CalculateSize();
controls.NameStack:ReprocessAnchoring();
end
controls.IconsStack:CalculateSize();
controls.IconsStack:ReprocessAnchoring();
end