diff --git a/Assets/UI/PartialScreens/WorldRankings.lua b/Assets/UI/PartialScreens/WorldRankings.lua
new file mode 100644
index 0000000..f62719e
--- /dev/null
+++ b/Assets/UI/PartialScreens/WorldRankings.lua
@@ -0,0 +1,2526 @@
+-- ===========================================================================
+-- Contains scaffolding for WorldRankings and other Right Anchored screens
+-- ===========================================================================
+include("TabSupport");
+include("InstanceManager");
+include("SupportFunctions");
+include("AnimSidePanelSupport");
+include("TeamSupport");
+
+-- ===========================================================================
+-- DEBUG
+-- ===========================================================================
+local m_isDebugForceShowAllScoreCategories :boolean = false; -- (false) Show all scoring categories under details
+
+-- ===========================================================================
+-- CONSTANTS
+-- ===========================================================================
+local RELOAD_CACHE_ID:string = "WorldRankings"; -- Must be unique (usually the same as the file name)
+local REQUIREMENT_CONTEXT:string = "VictoryProgress";
+local DATA_FIELD_SELECTION:string = "Selection";
+local DATA_FIELD_LEADER_TOOLTIP:string = "LeaderTooltip";
+local DATA_FIELD_HEADER_HEIGHT:string = "HeaderHeight";
+local DATA_FIELD_HEADER_RESIZED:string = "HeaderResized";
+local DATA_FIELD_HEADER_EXPANDED:string = "HeaderExpanded";
+local DATA_FIELD_OVERALL_PLAYERS_IM:string = "OverallPlayersIM";
+local DATA_FIELD_DOMINATED_CITIES_IM:string = "DominatedCitiesIM";
+local DATA_FIELD_RELIGION_CONVERTED_CIVS_IM:string = "ConvertedCivsIM";
+
+local PADDING_HEADER:number = 10;
+local PADDING_CULTURE_HEADER:number = 90;
+local PADDING_GENERIC_ITEM_BG:number = 25;
+local PADDING_TAB_BUTTON_TEXT:number = 17;
+local PADDING_EXTRA_TAB_BG:number = 10;
+local PADDING_EXTRA_TAB_SHADOW:number = 23;
+local PADDING_ADVISOR_TEXT_BG:number = 20;
+local PADDING_RELIGION_NAME_BG:number = 42;
+local PADDING_RELIGION_BG_HEIGHT:number = 26;
+local PADDING_VICTORY_GRADIENT:number = 45;
+local PADDING_NEXT_STEP_HIGHLIGHT:number = 4;
+local PADDING_VICTORY_LABEL_UNDERLINE:number = 90;
+local PADDING_SCORE_DETAILS_BUTTON_WIDTH:number = 40;
+local OFFSET_VIEW_CONTENTS:number = 130;
+local OFFSET_ADVISOR_ICON_Y:number = 5;
+local OFFSET_ADVISOR_TEXT_Y:number = 70;
+local OFFSET_HIDDEN_SCROLLBAR:number = 7;
+local OFFSET_CONTRACT_BUTTON_Y:number = 63;
+local OFFSET_SCIENCE_REQUIREMENTS_Y:number = 80;
+local SIZE_OVERALL_TOP_PLAYER_ICON:number = 48;
+local SIZE_OVERALL_PLAYER_ICON:number = 36;
+local SIZE_OVERALL_BG_HEIGHT:number = 100;
+local SIZE_OVERALL_INSTANCE:number = 40;
+local SIZE_VICTORY_ICON_SMALL:number = 64;
+local SIZE_RELIGION_BG_HEIGHT:number = 55;
+local SIZE_RELIGION_ICON_SMALL:number = 22;
+local SIZE_RELIGION_CIV_ICON:number = 30;
+local SIZE_GENERIC_ITEM_MIN_Y:number = 54;
+local SIZE_SCORE_ITEM_DEFAULT:number = 54;
+local SIZE_SCORE_ITEM_DETAILS:number = 180;
+local SIZE_STACK_DEFAULT:number = 225;
+local SIZE_HEADER_DEFAULT:number = 60;
+local SIZE_HEADER_MIN_Y:number = 46;
+local SIZE_HEADER_MAX_Y:number = 270;
+local SIZE_HEADER_ICON:number = 80;
+local SIZE_LEADER_ICON:number = 55;
+local SIZE_CIV_ICON:number = 36;
+
+local TEAM_RIBBON_PREFIX:string = "ICON_TEAM_RIBBON_";
+local TEAM_RIBBON_SIZE_TOP_TEAM:number = 53;
+local TEAM_RIBBON_SIZE:number = 44;
+
+local TEAM_ICON_PREFIX:string = "Team";
+local TEAM_ICON_SIZE_TOP_TEAM:number = 38;
+local TEAM_ICON_SIZE:number = 28;
+
+local TAB_SCORE:string = Locale.Lookup("LOC_WORLD_RANKINGS_SCORE_TAB");
+local TAB_OVERALL:string = Locale.Lookup("LOC_WORLD_RANKINGS_OVERALL_TAB");
+local TAB_SCIENCE:string = Locale.Lookup("LOC_WORLD_RANKINGS_SCIENCE_TAB");
+local TAB_CULTURE:string = Locale.Lookup("LOC_WORLD_RANKINGS_CULTURE_TAB");
+local TAB_RELIGION:string = Locale.Lookup("LOC_WORLD_RANKINGS_RELIGION_TAB");
+local TAB_DOMINATION:string = Locale.Lookup("LOC_WORLD_RANKINGS_DOMINATION_TAB");
+
+local SCORE_TITLE:string = Locale.Lookup("LOC_WORLD_RANKINGS_SCORE_VICTORY");
+local SCORE_DETAILS:string = Locale.Lookup("LOC_WORLD_RANKINGS_SCORE_DETAILS");
+
+local SCIENCE_ICON:string = "ICON_VICTORY_TECHNOLOGY";
+local SCIENCE_TITLE:string = Locale.Lookup("LOC_WORLD_RANKINGS_SCIENCE_VICTORY");
+local SCIENCE_DETAILS:string = Locale.Lookup("LOC_WORLD_RANKINGS_SCIENCE_DETAILS");
+local SCIENCE_REQUIREMENTS:table = {
+ Locale.Lookup("LOC_WORLD_RANKINGS_SCIENCE_REQUIREMENT_1"),
+ Locale.Lookup("LOC_WORLD_RANKINGS_SCIENCE_REQUIREMENT_2"),
+ Locale.Lookup("LOC_WORLD_RANKINGS_SCIENCE_REQUIREMENT_3")
+};
+
+local CULTURE_ICON:string = "ICON_VICTORY_CULTURE";
+local CULTURE_TITLE:string = Locale.Lookup("LOC_WORLD_RANKINGS_CULTURE_VICTORY");
+local CULTURE_VICTORY_DETAILS:string = Locale.Lookup("LOC_WORLD_RANKINGS_CULTURE_VICTORY_DETAILS");
+local CULTURE_DOMESTIC_TOURISTS:string = Locale.Lookup("LOC_WORLD_RANKINGS_CULTURE_DETAILS_DOMESTIC_TOURISTS");
+local CULTURE_VISITING_TOURISTS:string = Locale.Lookup("LOC_WORLD_RANKINGS_CULTURE_DETAILS_VISITING_TOURISTS");
+
+local DOMINATION_ICON:string = "ICON_VICTORY_DOMINATION";
+local DOMINATION_TITLE:string = Locale.Lookup("LOC_WORLD_RANKINGS_DOMINATION_VICTORY");
+local DOMINATION_DETAILS:string = Locale.Lookup("LOC_WORLD_RANKINGS_DOMINATION_DETAILS");
+local DOMINATION_HAS_ORIGINAL_CAPITAL:string = Locale.Lookup("LOC_WORLD_RANKINGS_DOMINATION_HAS_ORIGINAL_CAPITAL");
+
+local RELIGION_ICON:string = "ICON_VICTORY_RELIGIOUS";
+local RELIGION_TITLE:string = Locale.Lookup("LOC_WORLD_RANKINGS_RELIGION_VICTORY");
+local RELIGION_DETAILS:string = Locale.Lookup("LOC_WORLD_RANKINGS_RELIGION_DETAILS");
+
+local ICON_GENERIC:string = "ICON_VICTORY_GENERIC";
+local ICON_UNKNOWN_CIV:string = "ICON_CIVILIZATION_UNKNOWN";
+local LOC_UNKNOWN_CIV:string = Locale.Lookup("LOC_WORLD_RANKING_UNMET_PLAYER");
+local LOC_UNKNOWN_CIV_COLORED:string = Locale.Lookup("LOC_WORLD_RANKING_UNMET_PLAYER_COLORED");
+
+local UNKNOWN_COLOR:number = RGBAValuesToABGRHex(1, 1, 1, 1);
+
+--antonjs: Removed the other state and related text, in favor of showing all information together. Leaving state functionality intact in case we want to use it in the future.
+--[[
+local CULTURE_HOW_TO_VICTORY:string = Locale.Lookup("LOC_WORLD_RANKINGS_CULTURE_HOW_TO_VICTORY");
+local CULTURE_HOW_TO_TOURISM:string = Locale.Lookup("LOC_WORLD_RANKINGS_CULTURE_HOW_TO_TOURISM");
+local CULTURE_TOURISM_DETAILS:string = Locale.Lookup("LOC_WORLD_RANKINGS_CULTURE_TOURISM_DETAILS");
+--]]
+local CULTURE_HEADER_STATES:table = {
+ WHAT_IS_CULTURE_VICTORY = 0;
+};
+
+local SPACE_PORT_DISTRICT_INFO:table = GameInfo.Districts["DISTRICT_SPACEPORT"];
+local EARTH_SATELLITE_PROJECT_INFOS:table = {
+ GameInfo.Projects["PROJECT_LAUNCH_EARTH_SATELLITE"]
+};
+local MOON_LANDING_PROJECT_INFOS:table = {
+ GameInfo.Projects["PROJECT_LAUNCH_MOON_LANDING"]
+};
+local MARS_COLONY_PROJECT_INFOS:table = {
+ GameInfo.Projects["PROJECT_LAUNCH_MARS_REACTOR"],
+ GameInfo.Projects["PROJECT_LAUNCH_MARS_HABITATION"],
+ GameInfo.Projects["PROJECT_LAUNCH_MARS_HYDROPONICS"]
+};
+local SCIENCE_PROJECTS:table = {
+ EARTH_SATELLITE_PROJECT_INFOS,
+ MOON_LANDING_PROJECT_INFOS,
+ MARS_COLONY_PROJECT_INFOS
+};
+
+local STANDARD_VICTORY_TYPES:table = {
+ "VICTORY_DEFAULT",
+ "VICTORY_SCORE",
+ "VICTORY_TECHNOLOGY",
+ "VICTORY_CULTURE",
+ "VICTORY_CONQUEST",
+ "VICTORY_RELIGIOUS"
+};
+
+function IsCustomVictoryType(victoryType:string)
+ for _, checkVictoryType in ipairs(STANDARD_VICTORY_TYPES) do
+ if victoryType == checkVictoryType then
+ return false;
+ end
+ end
+ return true;
+end
+
+-- ===========================================================================
+-- PLAYER VARIABLES
+-- ===========================================================================
+local m_LocalPlayer:table;
+local m_LocalPlayerID:number;
+-- ===========================================================================
+-- SCREEN VARIABLES
+-- ===========================================================================
+local m_TabSupport:table; -- TabSupport
+local m_AnimSupport:table; --AnimSidePanelSupport
+local m_ActiveHeader:table;
+local m_TotalTabSize:number = 0;
+local m_MaxExtraTabSize:number = 0;
+local m_ExtraTabs:table = {};
+local m_HeaderInstances:table = {};
+local m_ActiveViewUpdate:ifunction;
+local m_ShowScoreDetails:boolean = false;
+local m_CultureHeaderState:number = CULTURE_HEADER_STATES.WHAT_IS_CULTURE_VICTORY;
+local m_TabSupportIM:table = InstanceManager:new("TabInstance", "Button", Controls.TabContainer);
+local m_GenericHeaderIM:table = InstanceManager:new("GenericHeaderInstance", "HeaderTop"); -- Used by Score, Religion and Domination Views
+local m_ScienceHeaderIM:table = InstanceManager:new("ScienceHeaderInstance", "HeaderTop", Controls.ScienceViewHeader);
+local m_CultureHeaderIM:table = InstanceManager:new("CultureHeaderInstance", "HeaderTop", Controls.CultureViewHeader);
+local m_OverallIM:table = InstanceManager:new("OverallInstance", "ButtonBG", Controls.OverallViewStack);
+
+local m_ScoreIM:table = InstanceManager:new("ScoreInstance", "ButtonBG", Controls.ScoreViewStack);
+local m_ScoreTeamIM:table = InstanceManager:new("ScoreTeamInstance", "ButtonFrame", Controls.ScoreViewStack);
+
+local m_ScienceIM:table = InstanceManager:new("ScienceInstance", "ButtonBG", Controls.ScienceViewStack);
+local m_ScienceTeamIM:table = InstanceManager:new("ScienceTeamInstance", "ButtonFrame", Controls.ScienceViewStack);
+
+local m_CultureIM:table = InstanceManager:new("CultureInstance", "ButtonBG", Controls.CultureViewStack);
+local m_CultureTeamIM:table = InstanceManager:new("CultureTeamInstance", "ButtonFrame", Controls.CultureViewStack);
+
+local m_DominationIM:table = InstanceManager:new("DominationInstance", "ButtonBG", Controls.DominationViewStack);
+local m_DominationTeamIM:table = InstanceManager:new("DominationTeamInstance", "ButtonFrame", Controls.DominationViewStack);
+
+local m_ReligionIM:table = InstanceManager:new("ReligionInstance", "ButtonBG", Controls.ReligionViewStack);
+local m_ReligionTeamIM:table = InstanceManager:new("ReligionTeamInstance", "ButtonFrame", Controls.ReligionViewStack);
+
+local m_GenericIM:table = InstanceManager:new("GenericInstance", "ButtonBG", Controls.GenericViewStack);
+local m_GenericTeamIM:table = InstanceManager:new("GenericTeamInstance", "ButtonFrame", Controls.GenericViewStack);
+
+local m_ExtraTabsIM:table = InstanceManager:new("ExtraTab", "Button", Controls.ExtraTabStack);
+
+local m_CivTooltip = {};
+TTManager:GetTypeControlTable("CivTooltip", m_CivTooltip);
+
+local m_TeamTooltip = {};
+TTManager:GetTypeControlTable("TeamTooltip", m_TeamTooltip);
+
+-- ===========================================================================
+-- Called once during Init
+-- ===========================================================================
+function PopulateTabs()
+
+ -- Clean up previous data
+ m_ExtraTabs = {};
+ m_TotalTabSize = 0;
+ m_MaxExtraTabSize = 0;
+ m_ExtraTabsIM:ResetInstances();
+ m_TabSupportIM:ResetInstances();
+
+ -- Deselect previously selected tab
+ if(m_TabSupport ~= nil) then
+ m_TabSupport.SelectTab(nil);
+ if(m_TabSupport.prevSelectedControl ~= nil) then
+ m_TabSupport.prevSelectedControl[DATA_FIELD_SELECTION]:SetHide(true);
+ end
+ end
+
+ -- Create TabSupport object
+ m_TabSupport = CreateTabs(Controls.TabContainer, 42, 34, 0xFF331D05);
+
+ local defaultTab = AddTab(TAB_OVERALL, ViewOverall);
+
+ -- Add default victory types in a pre-determined order
+ if(GameConfiguration.IsAnyMultiplayer() or Game.IsVictoryEnabled("VICTORY_SCORE")) then
+ AddTab(TAB_SCORE, ViewScore);
+ end
+ if(Game.IsVictoryEnabled("VICTORY_TECHNOLOGY")) then
+ AddTab(TAB_SCIENCE, ViewScience);
+ end
+ if(Game.IsVictoryEnabled("VICTORY_CULTURE")) then
+ AddTab(TAB_CULTURE, ViewCulture);
+ end
+ if(Game.IsVictoryEnabled("VICTORY_CONQUEST")) then
+ AddTab(TAB_DOMINATION, ViewDomination);
+ end
+ if(Game.IsVictoryEnabled("VICTORY_RELIGIOUS")) then
+ AddTab(TAB_RELIGION, ViewReligion);
+ end
+
+ -- Add custom (modded) victory types
+ for row in GameInfo.Victories() do
+ local victoryType:string = row.VictoryType;
+ if IsCustomVictoryType(victoryType) and Game.IsVictoryEnabled(victoryType) then
+ AddTab(Locale.Lookup(row.Name), function() ViewGeneric(victoryType); end);
+ end
+ end
+
+ if m_TotalTabSize > Controls.TabContainer:GetSizeX() then
+ Controls.ExpandExtraTabs:SetHide(false);
+ for _, tabInst in pairs(m_ExtraTabs) do
+ tabInst.Button:SetSizeX(m_MaxExtraTabSize);
+ end
+ else
+ Controls.ExpandExtraTabs:SetHide(true);
+ end
+
+ Controls.ExtraTabs:SetOffsetX(-1 * Controls.ExtraTabStack:GetSizeX() + PADDING_EXTRA_TAB_BG);
+ Controls.ExtraTabsBG:SetSizeVal(Controls.ExtraTabStack:GetSizeX() + PADDING_EXTRA_TAB_BG, Controls.ExtraTabStack:GetSizeY() + PADDING_EXTRA_TAB_BG);
+ Controls.ExtraTabsShadow:SetSizeVal(Controls.ExtraTabStack:GetSizeX() + PADDING_EXTRA_TAB_SHADOW, Controls.ExtraTabStack:GetSizeY() + PADDING_EXTRA_TAB_SHADOW);
+
+ m_TabSupport.SelectTab(defaultTab);
+ m_TabSupport.EvenlySpreadTabs();
+end
+
+function AddTab(label:string, onClickCallback:ifunction)
+
+ local tabInst:table = m_TabSupportIM:GetInstance();
+ tabInst.Button[DATA_FIELD_SELECTION] = tabInst.Selection;
+
+ tabInst.Button:SetText(label);
+ local textControl = tabInst.Button:GetTextControl();
+ textControl:SetHide(false);
+
+ local textSize:number = textControl:GetSizeX();
+ tabInst.Button:SetSizeX(textSize + PADDING_TAB_BUTTON_TEXT);
+ tabInst.Button:RegisterCallback(Mouse.eMouseEnter, function() UI.PlaySound("Main_Menu_Mouse_Over"); end);
+ tabInst.Selection:SetSizeX(textSize + PADDING_TAB_BUTTON_TEXT + 4);
+
+ m_TotalTabSize = m_TotalTabSize + tabInst.Button:GetSizeX();
+ if m_TotalTabSize > Controls.TabContainer:GetSizeX() then
+ m_TabSupportIM:ReleaseInstance(tabInst);
+ AddExtraTab(label, onClickCallback);
+ else
+
+ local callback = function()
+ if(m_TabSupport.prevSelectedControl ~= nil) then
+ m_TabSupport.prevSelectedControl[DATA_FIELD_SELECTION]:SetHide(true);
+ end
+ tabInst.Selection:SetHide(false);
+ onClickCallback();
+ CloseExtraTabs();
+ end
+
+ m_TabSupport.AddTab(tabInst.Button, callback);
+ end
+
+ return tabInst.Button;
+end
+
+function AddExtraTab(label:string, onClickCallback:ifunction)
+ local extraTabInst:table = m_ExtraTabsIM:GetInstance();
+ extraTabInst.Button:SetText(label);
+
+ local callback = function()
+ if(m_TabSupport.selectedControl ~= nil) then
+ m_TabSupport.selectedControl[DATA_FIELD_SELECTION]:SetHide(true);
+ m_TabSupport.SetSelectedTabVisually(nil);
+ end
+ for _,tabInst in pairs(m_ExtraTabs) do
+ tabInst.Button:SetSelected(tabInst == extraTabInst);
+ end
+ onClickCallback();
+ end
+
+ extraTabInst.Button:RegisterCallback(Mouse.eLClick, callback);
+
+ local textControl = extraTabInst.Button:GetTextControl();
+ local textSize:number = textControl:GetSizeX();
+ extraTabInst.Button:SetSizeX(textSize + PADDING_TAB_BUTTON_TEXT);
+ extraTabInst.Button:RegisterCallback(Mouse.eMouseEnter, function() UI.PlaySound("Main_Menu_Mouse_Over"); end);
+
+ local tabSize:number = extraTabInst.Button:GetSizeX();
+ if tabSize > m_MaxExtraTabSize then
+ m_MaxExtraTabSize = tabSize;
+ end
+
+ table.insert(m_ExtraTabs, extraTabInst);
+end
+
+-- ===========================================================================
+-- Called anytime player switches tabs
+-- ===========================================================================
+function ResetState(newView:ifunction)
+ m_ActiveHeader = nil;
+ m_ActiveViewUpdate = newView;
+ Controls.OverallView:SetHide(true);
+ Controls.ScoreView:SetHide(true);
+ Controls.ScienceView:SetHide(true);
+ Controls.CultureView:SetHide(true);
+ Controls.DominationView:SetHide(true);
+ Controls.ReligionView:SetHide(true);
+ Controls.GenericView:SetHide(true);
+
+ -- Reset tourism lens unless we're now view the Culture tab
+ if newView ~= ViewCulture then
+ ResetTourismLens();
+ end
+end
+
+function ChangeActiveHeader(headerType:string, headerIM:table, parentControl:table)
+ m_ActiveHeader = m_HeaderInstances[headerType];
+ if(m_ActiveHeader == nil) then
+ m_ActiveHeader = headerIM:GetInstance(parentControl);
+ m_HeaderInstances[headerType] = m_ActiveHeader;
+ end
+end
+
+function GetCivNameAndIcon(playerID:number, bColorUnmetPlayer:boolean)
+ local name:string, icon:string;
+ local playerConfig:table = PlayerConfigurations[playerID];
+ if(playerID == m_LocalPlayerID or playerConfig:IsHuman() or m_LocalPlayer == nil or m_LocalPlayer:GetDiplomacy():HasMet(playerID)) then
+ name = Locale.Lookup(playerConfig:GetPlayerName());
+ if playerID == m_LocalPlayerID or m_LocalPlayer == nil or m_LocalPlayer:GetDiplomacy():HasMet(playerID) then
+ icon = "ICON_" .. playerConfig:GetCivilizationTypeName();
+ else
+ icon = ICON_UNKNOWN_CIV;
+ end
+ else
+ name = bColorUnmetPlayer and LOC_UNKNOWN_CIV_COLORED or LOC_UNKNOWN_CIV;
+ icon = ICON_UNKNOWN_CIV;
+ end
+ return name, icon;
+end
+
+function ColorCivIcon(instance:table, playerID:number)
+ if(playerID == m_LocalPlayerID or m_LocalPlayer == nil or m_LocalPlayer:GetDiplomacy():HasMet(playerID)) then
+ local backColor, frontColor = UI.GetPlayerColors(playerID);
+ local darkerBackColor = DarkenLightenColor(backColor,(-55),230);
+ local brighterBackColor = DarkenLightenColor(backColor,80,255);
+ instance.CivIcon:SetColor(frontColor);
+ if(instance.CivIconBacking ~= nil) then
+ instance.CivIconBacking:SetColor(backColor);
+ else
+ instance.CivBacking_Base:SetColor(backColor);
+ instance.CivBacking_Lighter:SetColor(brighterBackColor);
+ instance.CivBacking_Darker:SetColor(darkerBackColor);
+ end
+ else
+ instance.CivIcon:SetColor(UNKNOWN_COLOR);
+ if(instance.CivIconBacking ~= nil) then
+ instance.CivIconBacking:SetColor(UNKNOWN_COLOR);
+ else
+ instance.CivBacking_Base:SetColor(backColor);
+ instance.CivBacking_Lighter:SetColor(brighterBackColor);
+ instance.CivBacking_Darker:SetColor(darkerBackColor);
+ end
+ end
+end
+
+-- ===========================================================================
+-- Called to update a generic header instance
+-- ===========================================================================
+function PopulateGenericHeader(resizeCallback:ifunction, title:string, subTitle:string, details:string, headerIcon:string, advisorIcon:string)
+
+ local textureOffsetX:number, textureOffsetY:number, textureSheet:string = IconManager:FindIconAtlas(headerIcon, SIZE_HEADER_ICON);
+ if(textureSheet == nil or textureSheet == "") then
+ UI.DataError("Could not find icon in PopulateGenericHeader: icon=\""..headerIcon.."\", iconSize="..tostring(SIZE_HEADER_ICON));
+ else
+ m_ActiveHeader.HeaderIcon:SetTexture(textureOffsetX, textureOffsetY, textureSheet);
+ end
+
+ m_ActiveHeader.HeaderLabel:SetText(Locale.ToUpper(Locale.Lookup(title)));
+ if(subTitle ~= nil and subTitle ~= "") then
+ m_ActiveHeader.HeaderSubLabel:SetHide(false);
+ m_ActiveHeader.HeaderSubLabel:SetText(Locale.Lookup(subTitle));
+ else
+ m_ActiveHeader.HeaderSubLabel:SetHide(true);
+ end
+
+ m_ActiveHeader.AdvisorText:SetText(details and Locale.Lookup(details) or "");
+
+ m_ActiveHeader.ExpandHeaderButton:RegisterCallback(Mouse.eLClick, OnExpandHeader);
+ m_ActiveHeader.ContractHeaderButton:RegisterCallback(Mouse.eLClick, OnContractHeader);
+
+ if(m_ActiveHeader[DATA_FIELD_HEADER_EXPANDED] == nil) then
+ m_ActiveHeader[DATA_FIELD_HEADER_EXPANDED] = true;
+ end
+
+ m_ActiveHeader[DATA_FIELD_HEADER_RESIZED] = resizeCallback;
+ RealizeHeaderSize();
+end
+
+-- ===========================================================================
+-- Called anytime player presses expand/contract button on a Header Instance
+-- ===========================================================================
+function OnExpandHeader(data1:number, data2:number, control:table)
+ if(control == m_ActiveHeader.ExpandHeaderButton) then
+ m_ActiveHeader.AdvisorIcon:SetHide(false);
+ m_ActiveHeader.AdvisorText:SetHide(false);
+ m_ActiveHeader.AdvisorTextBG:SetHide(false);
+ m_ActiveHeader.ExpandHeaderButton:SetHide(true);
+ m_ActiveHeader.ContractHeaderButton:SetHide(false);
+ m_ActiveHeader[DATA_FIELD_HEADER_EXPANDED] = true;
+ RealizeHeaderSize();
+ end
+end
+function OnContractHeader(data1:number, data2:number, control:table)
+ if(control == m_ActiveHeader.ContractHeaderButton) then
+ m_ActiveHeader.AdvisorIcon:SetHide(true);
+ m_ActiveHeader.AdvisorText:SetHide(true);
+ m_ActiveHeader.AdvisorTextBG:SetHide(true);
+ m_ActiveHeader.ExpandHeaderButton:SetHide(false);
+ m_ActiveHeader.ContractHeaderButton:SetHide(true);
+ m_ActiveHeader[DATA_FIELD_HEADER_EXPANDED] = false;
+ RealizeHeaderSize();
+ end
+end
+
+-- ===========================================================================
+-- Called anytime header changes size (when it's expanded / contracted)
+-- ===========================================================================
+function RealizeHeaderSize()
+ if(m_ActiveHeader[DATA_FIELD_HEADER_EXPANDED]) then
+ local textBubbleHeight:number = m_ActiveHeader.AdvisorText:GetSizeY() + PADDING_ADVISOR_TEXT_BG;
+ if(textBubbleHeight > SIZE_HEADER_MAX_Y) then
+ textBubbleHeight = SIZE_HEADER_MAX_Y;
+ elseif textBubbleHeight < SIZE_HEADER_MIN_Y then
+ textBubbleHeight = SIZE_HEADER_MIN_Y;
+ end
+ m_ActiveHeader.AdvisorTextBG:SetSizeY(textBubbleHeight);
+ m_ActiveHeader.AdvisorIcon:SetOffsetY(OFFSET_ADVISOR_ICON_Y + textBubbleHeight);
+ m_ActiveHeader.HeaderFrame:SetSizeY(OFFSET_ADVISOR_TEXT_Y + textBubbleHeight);
+ m_ActiveHeader.ContractHeaderButton:SetOffsetY(OFFSET_CONTRACT_BUTTON_Y + textBubbleHeight);
+ m_ActiveHeader[DATA_FIELD_HEADER_HEIGHT] = textBubbleHeight;
+ else
+ m_ActiveHeader.HeaderFrame:SetSizeY(SIZE_HEADER_DEFAULT);
+ m_ActiveHeader[DATA_FIELD_HEADER_HEIGHT] = SIZE_HEADER_DEFAULT;
+ end
+ -- Center header label if sub label is not present
+ if(m_ActiveHeader.HeaderSubLabel:IsHidden()) then
+ m_ActiveHeader.HeaderLabel:SetOffsetY(25);
+ else
+ m_ActiveHeader.HeaderLabel:SetOffsetY(18);
+ end
+ if(m_ActiveHeader[DATA_FIELD_HEADER_RESIZED] ~= nil) then
+ m_ActiveHeader[DATA_FIELD_HEADER_RESIZED]();
+ end
+end
+
+-- ===========================================================================
+-- Utility to reduce code duplication
+-- ===========================================================================
+function RealizeStackAndScrollbar(stackControl:table, scrollbarControl:table, offsetStackIfScrollbarHidden:boolean)
+ stackControl:CalculateSize();
+ stackControl:ReprocessAnchoring();
+ scrollbarControl:CalculateInternalSize();
+ scrollbarControl:ReprocessAnchoring();
+ scrollbarControl:SetScrollValue(0);
+ if(offsetStackIfScrollbarHidden ~= nil) then
+ if(scrollbarControl:GetScrollBar():IsHidden()) then
+ stackControl:SetOffsetX(OFFSET_HIDDEN_SCROLLBAR);
+ else
+ stackControl:SetOffsetX(0);
+ end
+ end
+end
+
+-- ===========================================================================
+-- Called when Overall tab is selected (or when screen re-opens if selected)
+-- ===========================================================================
+function ViewOverall()
+ ResetState(ViewOverall);
+ Controls.OverallView:SetHide(false);
+
+ m_OverallIM:ResetInstances();
+
+ -- Add default victory types in a pre-determined order
+ if(Game.IsVictoryEnabled("VICTORY_TECHNOLOGY")) then
+ PopulateOverallInstance(m_OverallIM:GetInstance(), "VICTORY_TECHNOLOGY", "SCIENCE");
+ end
+ if(Game.IsVictoryEnabled("VICTORY_CULTURE")) then
+ PopulateOverallInstance(m_OverallIM:GetInstance(), "VICTORY_CULTURE", "CULTURE");
+ end
+ if(Game.IsVictoryEnabled("VICTORY_CONQUEST")) then
+ PopulateOverallInstance(m_OverallIM:GetInstance(), "VICTORY_CONQUEST", "DOMINATION");
+ end
+ if(Game.IsVictoryEnabled("VICTORY_RELIGIOUS")) then
+ PopulateOverallInstance(m_OverallIM:GetInstance(), "VICTORY_RELIGIOUS", "RELIGION");
+ end
+
+ -- Add custom (modded) victory types
+ for row in GameInfo.Victories() do
+ local victoryType:string = row.VictoryType;
+ if IsCustomVictoryType(victoryType) and Game.IsVictoryEnabled(victoryType) then
+ PopulateOverallInstance(m_OverallIM:GetInstance(), victoryType);
+
+ end
+ end
+
+ Controls.OverallViewStack:CalculateSize();
+ Controls.OverallViewStack:ReprocessAnchoring();
+ Controls.OverallViewScrollbar:CalculateInternalSize();
+ Controls.OverallViewScrollbar:ReprocessAnchoring();
+
+ if(Controls.OverallViewScrollbar:GetScrollBar():IsHidden()) then
+ Controls.OverallViewStack:SetOffsetX(-3);
+ else
+ Controls.OverallViewStack:SetOffsetX(-5);
+ end
+end
+
+
+function PopulateOverallInstance(instance:table, victoryType:string, typeText:string)
+
+ local victoryInfo:table= GameInfo.Victories[victoryType];
+
+ instance.VictoryLabel:SetText(Locale.ToUpper(Locale.Lookup(victoryInfo.Name)));
+ instance.VictoryLabelUnderline:SetSizeX(instance.VictoryLabel:GetSizeX() + PADDING_VICTORY_LABEL_UNDERLINE);
+
+ local icon:string;
+ local color:number;
+ if typeText ~= nil then
+ icon = "ICON_VICTORY_" .. typeText;
+ color = UI.GetColorValue("COLOR_VICTORY_" .. typeText);
+ else
+ icon = victoryInfo.Icon or ICON_GENERIC;
+ color = UI.GetColorValue("White");
+ end
+ instance.VictoryBanner:SetColor(color);
+ instance.VictoryLabelGradient:SetColor(color);
+
+ if icon ~= nil then
+ local textureOffsetX:number, textureOffsetY:number, textureSheet:string = IconManager:FindIconAtlas(icon, SIZE_VICTORY_ICON_SMALL);
+ if(textureSheet == nil or textureSheet == "") then
+ UI.DataError("Could not find icon in PopulateOverallInstance: icon=\""..icon.."\", iconSize="..tostring(SIZE_VICTORY_ICON_SMALL));
+ else
+ instance.VictoryIcon:SetTexture(textureOffsetX, textureOffsetY, textureSheet);
+ instance.VictoryIcon:SetHide(false);
+ end
+ else
+ instance.VictoryIcon:SetHide(true);
+ end
+
+ -- Tiebreak score functions
+ local firstTiebreakerText = "LOC_WORLD_RANKINGS_OVERVIEW_DOMINATION_SCORE";
+ local firstTiebreakerFunction = function(p)
+ return p:GetScore();
+ end;
+ local secondTiebreakerText = "LOC_WORLD_RANKINGS_OVERVIEW_DOMINATION_SCORE";
+ local secondTiebreakerFunction = function(p)
+ return p:GetScore();
+ end;
+ if (victoryType == "VICTORY_TECHNOLOGY") then
+ firstTiebreakerText = "LOC_WORLD_RANKINGS_OVERVIEW_SCIENCE_NUM_TECHS";
+ firstTiebreakerFunction = function(p)
+ return p:GetStats():GetNumTechsResearched();
+ end;
+ secondTiebreakerText = "LOC_WORLD_RANKINGS_OVERVIEW_SCIENCE_SCIENCE_RATE";
+ secondTiebreakerFunction = function(p)
+ return p:GetTechs():GetScienceYield();
+ end;
+ elseif (victoryType == "VICTORY_CULTURE") then
+ firstTiebreakerText = "LOC_WORLD_RANKINGS_OVERVIEW_CULTURE_TOURISM_RATE";
+ firstTiebreakerFunction = function(p)
+ return p:GetStats():GetTourism();
+ end;
+ secondTiebreakerText = "LOC_WORLD_RANKINGS_OVERVIEW_CULTURE_CULTURE_RATE";
+ secondTiebreakerFunction = function(p)
+ return p:GetCulture():GetCultureYield();
+ end;
+ elseif (victoryType == "VICTORY_CONQUEST") then
+ firstTiebreakerText = "LOC_WORLD_RANKINGS_OVERVIEW_DOMINATION_MILITARY_STRENGTH";
+ firstTiebreakerFunction = function(p)
+ return p:GetStats():GetMilitaryStrengthWithoutTreasury();
+ end;
+ elseif (victoryType == "VICTORY_RELIGIOUS") then
+ firstTiebreakerText = "LOC_WORLD_RANKINGS_OVERVIEW_RELIGION_CITIES_FOLLOWING_RELIGION";
+ firstTiebreakerFunction = function(p)
+ return p:GetStats():GetNumCitiesFollowingReligion();
+ end;
+ secondTiebreakerText = "LOC_WORLD_RANKINGS_OVERVIEW_RELIGION_FAITH_RATE";
+ secondTiebreakerFunction = function(p)
+ return p:GetReligion():GetFaithYield();
+ end;
+ end
+
+ -- Team tiebreaker score functions
+ local firstTeamTiebreakerFunction = function(playerData, playerCount)
+ local averageScore:number = 0;
+
+ -- Add player scores
+ for playerID, player in pairs(playerData) do
+ averageScore = averageScore + player.FirstTiebreakScore;
+ end
+
+ -- Divide by player count
+ averageScore = averageScore / playerCount;
+
+ return averageScore;
+ end;
+ local secondTeamTiebreakerFunction = function(playerData, playerCount)
+ local averageScore:number = 0;
+
+ -- Add player scores
+ for playerID, player in pairs(playerData) do
+ averageScore = averageScore + player.SecondTiebreakScore;
+ end
+
+ -- Divide by player count
+ averageScore = averageScore / playerCount;
+
+ return averageScore;
+ end;
+
+ -- Gather team data
+ local teamData:table = {};
+ for teamID, team in pairs(Teams) do
+ if (teamID >= 0) then
+ -- If progress is nil, then the team is not capable of earning a victory (ex: city-state teams and barbarian teams).
+ -- Skip any team that is incapable of earning a victory.
+ local progress = Game.GetVictoryProgressForTeam(victoryType, teamID);
+ if(progress ~= nil) then
+ -- PlayerData
+ local playerData:table = {};
+ local playerCount:number = 0;
+ for i, playerID in ipairs(team) do
+ if IsAliveAndMajor(playerID) then
+ local pPlayer = Players[playerID];
+ playerData[playerID] = {
+ Player = pPlayer,
+ FirstTiebreakScore = firstTiebreakerFunction(pPlayer),
+ SecondTiebreakScore = secondTiebreakerFunction(pPlayer),
+ FirstTiebreakSummary = Locale.Lookup(firstTiebreakerText, Round(firstTiebreakerFunction(pPlayer), 1)),
+ SecondTiebreakSummary = Locale.Lookup(secondTiebreakerText, Round(secondTiebreakerFunction(pPlayer), 1)),
+ };
+
+ playerCount = playerCount + 1;
+ end
+ end
+
+ table.insert(teamData, {
+ -- Team Data
+ TeamID = teamID,
+ TeamScore = progress,
+ PlayerData = playerData,
+ PlayerCount = playerCount,
+ FirstTeamTiebreakScore = firstTeamTiebreakerFunction(playerData, playerCount);
+ SecondTeamTiebreakScore = secondTeamTiebreakerFunction(playerData, playerCount);
+ });
+ end
+ end
+ end
+
+ -- Sort teams by score
+ table.sort(teamData, function(a, b)
+ if (a.TeamScore == b.TeamScore) then
+ if (a.FirstTeamTiebreakScore == b.FirstTeamTiebreakScore) then
+ if (a.SecondTeamTiebreakScore == b.SecondTeamTiebreakScore) then
+ return a.TeamID > b.TeamID;
+ end
+ return a.SecondTeamTiebreakScore > b.SecondTeamTiebreakScore;
+ end
+ return a.FirstTeamTiebreakScore > b.FirstTeamTiebreakScore;
+ end
+ return a.TeamScore > b.TeamScore;
+ end);
+
+ -- Ensure we have Instance Managers for the player meters
+ local playersIM:table = instance[DATA_FIELD_OVERALL_PLAYERS_IM];
+ if(playersIM == nil) then
+ playersIM = InstanceManager:new("OverallPlayerInstance", "CivIconBackingFaded", instance.PlayerStack);
+ instance[DATA_FIELD_OVERALL_PLAYERS_IM] = playersIM;
+ end
+ playersIM:ResetInstances();
+
+ -- Populate top team/player icon
+ if teamData[1].PlayerCount > 1 then
+ PopulateOverallTeamIconInstance(instance, teamData[1], TEAM_ICON_SIZE_TOP_TEAM, TEAM_RIBBON_SIZE_TOP_TEAM);
+ else
+ PopulateOverallPlayerIconInstance(instance, teamData[1], SIZE_OVERALL_TOP_PLAYER_ICON);
+ end
+
+ -- Populate other team/player icons
+ if #teamData > 1 then
+ for i = 2, #teamData, 1 do
+ local playerInstance:table = playersIM:GetInstance();
+ if teamData[i].PlayerCount > 1 then
+ PopulateOverallTeamIconInstance(playerInstance, teamData[i], TEAM_ICON_SIZE, TEAM_RIBBON_SIZE);
+ else
+ PopulateOverallPlayerIconInstance(playerInstance, teamData[i], SIZE_OVERALL_PLAYER_ICON);
+ end
+ end
+ end
+
+ -- Determine if local player is leading
+ local isLocalPlayerLeading:boolean = false;
+ local leadingTeam:table = teamData[1];
+ for playerID, data in pairs(teamData[1].PlayerData) do
+ if playerID == m_LocalPlayerID then
+ isLocalPlayerLeading = true;
+ end
+ end
+
+ -- Populate leading and local player labels
+ if isLocalPlayerLeading then
+ -- You or your team is leading
+ instance.VictoryPlayer:SetText("");
+ if teamData[1].PlayerCount > 1 then
+ instance.VictoryLeading:SetText(Locale.Lookup("LOC_WORLD_RANKINGS_FIRST_PLACE_TEAM_SIMPLE"));
+ else
+ instance.VictoryLeading:SetText(Locale.Lookup("LOC_WORLD_RANKINGS_FIRST_PLACE_YOU_SIMPLE"));
+ end
+ else
+ -- Set top team/player text
+ local topName:string = "";
+ if teamData[1].PlayerCount > 1 then
+ topName = Locale.Lookup("LOC_WORLD_RANKINGS_TEAM", GameConfiguration.GetTeamName(teamData[1].TeamID));
+ else
+ local topPlayerID:number = Teams[teamData[1].TeamID][1];
+ if(m_LocalPlayer == nil or m_LocalPlayer:GetDiplomacy():HasMet(topPlayerID))then
+ topName = Locale.Lookup(GameInfo.Civilizations[PlayerConfigurations[Teams[teamData[1].TeamID][1]]:GetCivilizationTypeID()].Name);
+ else
+ topName = LOC_UNKNOWN_CIV;
+ end
+ end
+ instance.VictoryLeading:SetText(Locale.Lookup("LOC_WORLD_RANKINGS_FIRST_PLACE_OTHER_SIMPLE", topName));
+
+ -- Set local team/player text
+ for teamPosition, team in ipairs(teamData) do
+ for playerID, data in pairs(team.PlayerData) do
+ if playerID == m_LocalPlayerID then
+ local localPlayerPositionText:string = Locale.Lookup("LOC_WORLD_RANKINGS_" .. teamPosition .. "_PLACE");
+ local localPlayerDescription:string = "";
+
+ if team.PlayerCount > 1 then
+ localPlayerDescription = Locale.Lookup("LOC_WORLD_RANKINGS_OTHER_PLACE_TEAM_SIMPLE", localPlayerPositionText);
+ else
+ localPlayerDescription = Locale.Lookup("LOC_WORLD_RANKINGS_OTHER_PLACE_SIMPLE", localPlayerPositionText);
+ end
+
+ instance.VictoryPlayer:SetText(localPlayerDescription);
+ end
+ end
+ end
+ end
+
+ instance.ButtonBG:SetSizeY(SIZE_OVERALL_BG_HEIGHT + math.max(instance.PlayerStack:GetSizeY(), SIZE_OVERALL_INSTANCE));
+end
+
+function PopulateOverallTeamIconInstance(instance:table, teamData:table, iconSize:number, ribbonSize:number)
+ -- Update team icon
+ local teamColor:number = GetTeamColor(teamData.TeamID);
+ local teamIconName:string = TEAM_ICON_PREFIX .. iconSize;
+ instance.CivIcon:SetSizeVal(iconSize, iconSize);
+ instance.CivIcon:SetTexture(teamIconName);
+ instance.CivIconFaded:SetSizeVal(iconSize, iconSize);
+ instance.CivIconFaded:SetTexture(teamIconName);
+ instance.CivIcon:SetPercent(teamData.TeamScore);
+ instance.CivIcon:SetColor(teamColor);
+ instance.CivIconBacking:SetPercent(teamData.TeamScore);
+ instance.CivIconBacking:SetColor(teamColor);
+
+ -- Determine if this is the local players team
+ instance.LocalPlayer:SetHide(true);
+ for playerID, data in pairs(teamData.PlayerData) do
+ if playerID == m_LocalPlayerID then
+ instance.LocalPlayer:SetHide(false);
+ end
+ end
+
+ -- Update team ribbon
+ local teamRibbonName = TEAM_RIBBON_PREFIX .. tostring(teamData.TeamID);
+ instance.TeamRibbon:SetIcon(teamRibbonName, ribbonSize);
+ instance.TeamRibbon:SetHide(false);
+ instance.TeamRibbon:SetColor(teamColor);
+
+ -- Update tooltip
+ SetTeamTooltip(instance.CivIcon, teamData);
+end
+
+function PopulateOverallPlayerIconInstance(instance:table, teamData:table, iconSize:number)
+ -- Take the player ID from the first team member who should be the only team member
+ local playerID:number = Teams[teamData.TeamID][1];
+ local playerData:table = teamData.PlayerData[playerID];
+ if(playerData ~= nil) then
+ ColorCivIcon(instance, playerID);
+
+ local civName:string, civIcon:string = GetCivNameAndIcon(playerID);
+
+ local details:string;
+ if playerData.FirstTiebreakSummary == playerData.SecondTiebreakSummary then
+ details = playerData.FirstTiebreakSummary;
+ else
+ details = playerData.FirstTiebreakSummary .. "[NEWLINE]" .. playerData.SecondTiebreakSummary;
+ end
+
+ local textureOffsetX, textureOffsetY, textureSheet = IconManager:FindIconAtlas(civIcon, iconSize);
+ if(textureSheet == nil or textureSheet == "") then
+ UI.DataError("Could not find icon in PopulateOverallPlayerIconInstance: icon=\""..civIcon.."\", iconSize="..tostring(iconSize));
+ else
+ instance.CivIcon:SetSizeVal(iconSize, iconSize);
+ instance.CivIcon:SetTexture(textureOffsetX, textureOffsetY, textureSheet);
+ instance.CivIconFaded:SetTexture(textureOffsetX, textureOffsetY, textureSheet);
+ instance.CivIcon:SetPercent(teamData.TeamScore);
+ instance.CivIconBacking:SetPercent(teamData.TeamScore);
+ SetLeaderTooltip(instance, playerID, details);
+ end
+
+ instance.LocalPlayer:SetHide(playerID ~= m_LocalPlayerID);
+ instance.TeamRibbon:SetHide(true);
+ end
+end
+
+function SetTeamTooltip(control:table, teamData)
+ control:SetToolTipType("TeamTooltip");
+ control:SetToolTipCallback(function() UpdateTeamTooltip(control, teamData); end);
+end
+
+function UpdateTeamTooltip(control, teamData)
+ if m_TeamTooltip.TooltipIM == nil then
+ m_TeamTooltip.TooltipIM = InstanceManager:new("TeamTooltipInstance", "BG", m_TeamTooltip.CivStack);
+ end
+
+ m_TeamTooltip.TooltipIM:ResetInstances();
+
+ -- Tracks the widest instance
+ local maxWidth:number = 0;
+
+ -- Create an instance for each met player on this team
+ for playerID, playerData in pairs(teamData.PlayerData) do
+ if m_LocalPlayerID == playerID or m_LocalPlayer:GetDiplomacy():HasMet(playerID) then
+ local civInstance:table = m_TeamTooltip.TooltipIM:GetInstance();
+
+ -- Hide/show necessary controls
+ civInstance.LeaderIcon:SetHide(false);
+ civInstance.YouIndicator:SetHide(false);
+ civInstance.LeaderName:SetHide(false);
+ civInstance.UnmetLabel:SetHide(true);
+
+ -- Update local player indicator
+ civInstance.YouIndicator:SetHide(playerID ~= m_LocalPlayerID);
+
+ local playerConfig:table = PlayerConfigurations[playerID];
+ local leaderTypeName:string = playerConfig:GetLeaderTypeName();
+ if(leaderTypeName ~= nil) then
+ -- Update player icon
+ local textureOffsetX:number, textureOffsetY:number, textureSheet:string = IconManager:FindIconAtlas("ICON_"..leaderTypeName, SIZE_LEADER_ICON);
+ if(textureSheet == nil or textureSheet == "") then
+ UI.DataError("Could not find icon in UpdateLeaderTooltip: icon=\"".."ICON_"..leaderTypeName.."\", iconSize="..tostring(SIZE_LEADER_ICON));
+ else
+ civInstance.LeaderIcon:SetTexture(textureOffsetX, textureOffsetY, textureSheet);
+ end
+
+ -- Update description string
+ local desc:string;
+ local leaderDesc:string = playerConfig:GetLeaderName();
+ local civDesc:string = playerConfig:GetCivilizationDescription();
+ if GameConfiguration.IsAnyMultiplayer() and playerData.Player:IsHuman() then
+ local name = Locale.Lookup(playerConfig:GetPlayerName());
+ desc = Locale.Lookup("LOC_DIPLOMACY_DEAL_PLAYER_PANEL_TITLE", leaderDesc, civDesc) .. " (" .. name .. ")";
+ else
+ desc = Locale.Lookup("LOC_DIPLOMACY_DEAL_PLAYER_PANEL_TITLE", leaderDesc, civDesc);
+ end
+
+ if playerData.FirstTiebreakSummary and playerData.FirstTiebreakSummary ~= "" then
+ desc = desc .. "[NEWLINE]" .. playerData.FirstTiebreakSummary;
+ end
+
+ if playerData.SecondTiebreakSummary and playerData.SecondTiebreakSummary ~= "" and playerData.SecondTiebreakSummary ~= playerData.FirstTiebreakSummary then
+ desc = desc .. "[NEWLINE]" .. playerData.SecondTiebreakSummary;
+ end
+
+ civInstance.LeaderName:SetText(desc);
+ civInstance.BG:DoAutoSize();
+
+ -- Track the most wide instance so we can widen smaller instances to match
+ if civInstance.BG:GetSizeX() > maxWidth then
+ maxWidth = civInstance.BG:GetSizeX();
+ end
+ end
+ end
+ end
+
+ -- Create an unmet instance for each unmet player on this team
+ for playerID, playerData in pairs(teamData.PlayerData) do
+ if m_LocalPlayerID ~= playerID and not m_LocalPlayer:GetDiplomacy():HasMet(playerID) then
+ local civInstance:table = m_TeamTooltip.TooltipIM:GetInstance();
+
+ -- Hide/show necessary controls
+ civInstance.LeaderIcon:SetHide(true);
+ civInstance.YouIndicator:SetHide(true);
+ civInstance.LeaderName:SetHide(true);
+ civInstance.UnmetLabel:SetHide(false);
+
+ -- Set the unmet text based on whether this is human or AI
+ local playerConfig:table = PlayerConfigurations[playerID];
+ if GameConfiguration.IsAnyMultiplayer() and playerData.Player:IsHuman() then
+ civInstance.UnmetLabel:SetText(Locale.Lookup("LOC_DIPLOPANEL_UNMET_PLAYER") .. " (" .. playerConfig:GetPlayerName() .. ")");
+ else
+ civInstance.UnmetLabel:SetText(Locale.Lookup("LOC_DIPLOPANEL_UNMET_PLAYER"));
+ end
+
+ civInstance.BG:DoAutoSize();
+ end
+ end
+
+ -- Widen all instances to match up
+ for i=1,m_TeamTooltip.TooltipIM.m_iCount,1 do
+ local instance:table = m_TeamTooltip.TooltipIM:GetAllocatedInstance(i);
+ if instance and instance.BG:GetSizeX() < maxWidth then
+ instance.BG:SetSizeX(maxWidth);
+ end
+ end
+end
+
+function SetLeaderTooltip(instance:table, playerID:number, details:string)
+ local pPlayer:table = Players[playerID];
+ local playerConfig:table = PlayerConfigurations[playerID];
+ if(playerID ~= m_LocalPlayerID and m_LocalPlayer ~= nil and not m_LocalPlayer:GetDiplomacy():HasMet(playerID)) then
+ instance.CivIcon:SetToolTipType();
+ instance.CivIcon:ClearToolTipCallback();
+ if GameConfiguration.IsAnyMultiplayer() and pPlayer:IsHuman() then
+ instance.CivIcon:SetToolTipString(Locale.Lookup("LOC_DIPLOPANEL_UNMET_PLAYER") .. " (" .. playerConfig:GetPlayerName() .. ")");
+ else
+ instance.CivIcon:SetToolTipString(Locale.Lookup("LOC_DIPLOPANEL_UNMET_PLAYER"));
+ end
+ else
+ instance.CivIcon:SetToolTipType("CivTooltip");
+ instance.CivIcon:SetToolTipCallback(function() UpdateLeaderTooltip(instance, playerID, details); end);
+ end
+end
+
+function UpdateLeaderTooltip(instance:table, playerID:number, details:string)
+ local pPlayer:table = Players[playerID];
+ local playerConfig:table = PlayerConfigurations[playerID];
+ if(pPlayer ~= nil and playerConfig ~= nil) then
+
+ m_CivTooltip.YouIndicator:SetHide(playerID ~= m_LocalPlayerID);
+
+ local leaderTypeName:string = playerConfig:GetLeaderTypeName();
+ if(leaderTypeName ~= nil) then
+ local textureOffsetX:number, textureOffsetY:number, textureSheet:string = IconManager:FindIconAtlas("ICON_"..leaderTypeName, SIZE_LEADER_ICON);
+ if(textureSheet == nil or textureSheet == "") then
+ UI.DataError("Could not find icon in UpdateLeaderTooltip: icon=\"".."ICON_"..leaderTypeName.."\", iconSize="..tostring(SIZE_LEADER_ICON));
+ else
+ m_CivTooltip.LeaderIcon:SetTexture(textureOffsetX, textureOffsetY, textureSheet);
+ end
+
+ local desc:string;
+ local leaderDesc:string = playerConfig:GetLeaderName();
+ local civDesc:string = playerConfig:GetCivilizationDescription();
+ if GameConfiguration.IsAnyMultiplayer() and pPlayer:IsHuman() then
+ local name = Locale.Lookup(playerConfig:GetPlayerName());
+ desc = Locale.Lookup("LOC_DIPLOMACY_DEAL_PLAYER_PANEL_TITLE", leaderDesc, civDesc) .. " (" .. name .. ")";
+ else
+ desc = Locale.Lookup("LOC_DIPLOMACY_DEAL_PLAYER_PANEL_TITLE", leaderDesc, civDesc);
+ end
+
+ if (details ~= nil and details ~= "") then
+ desc = desc .. "[NEWLINE]" .. details;
+ end
+ m_CivTooltip.LeaderName:SetText(desc);
+ m_CivTooltip.BG:DoAutoSize();
+ end
+ end
+end
+
+-- ===========================================================================
+-- Called when Score tab is selected (or when screen re-opens if selected)
+-- ===========================================================================
+function ViewScore()
+ ResetState(ViewScore);
+ Controls.ScoreView:SetHide(false);
+
+ ChangeActiveHeader("VICTORY_SCORE", m_GenericHeaderIM, Controls.ScoreViewHeader);
+ local subTitle:string = Locale.Lookup("LOC_WORLD_RANKINGS_SCORE_CONDITION", Game.GetMaxGameTurns());
+ PopulateGenericHeader(RealizeScoreStackSize, SCORE_TITLE, subTitle, SCORE_DETAILS, ICON_GENERIC);
+
+ -- Gather data
+ local scoreData:table = GatherScoreData();
+
+ -- Sort teams
+ table.sort(scoreData, function(a, b) return a.TeamScore > b.TeamScore; end);
+
+ m_ScoreIM:ResetInstances();
+ m_ScoreTeamIM:ResetInstances();
+
+ for i, teamData in ipairs(scoreData) do
+ if #teamData.PlayerData > 1 then
+ -- Sort players before displaying
+ table.sort(teamData.PlayerData, function(a, b) return a.PlayerScore> b.PlayerScore; end);
+
+ -- Display as team
+ PopulateScoreTeamInstance(m_ScoreTeamIM:GetInstance(), teamData);
+ elseif #teamData.PlayerData > 0 then
+ -- Display as single civ
+ PopulateScoreInstance(m_ScoreIM:GetInstance(), teamData.PlayerData[1]);
+ end
+ end
+
+ RealizeScoreStackSize();
+end
+
+function GatherScoreData()
+ local data:table = {};
+
+ for teamID, team in pairs(Teams) do
+ if teamID >= 0 then
+ local teamData:table = { TeamID = teamID, PlayerData = {}, TeamScore = 0 };
+
+ -- Add players
+ for i, playerID in ipairs(team) do
+ if IsAliveAndMajor(playerID) then
+ local pPlayer:table = Players[playerID];
+ local playerData:table = { PlayerID = playerID, PlayerScore = pPlayer:GetScore(), Categories = {} };
+
+ -- Add player score to team score
+ teamData.TeamScore = teamData.TeamScore + playerData.PlayerScore;
+
+ -- Look up category scores
+ local scoreCategories = GameInfo.ScoringCategories;
+ local numCategories:number = #scoreCategories;
+ for i = 0, numCategories - 1 do
+ if scoreCategories[i].Multiplier > 0 or m_isDebugForceShowAllScoreCategories then
+ table.insert(playerData.Categories, { CategoryID = i, CategoryScore = pPlayer:GetCategoryScore(i) });
+ end
+ end
+
+ table.insert(teamData.PlayerData, playerData);
+ end
+ end
+
+ -- Only add teams with at least one living, major player
+ if #teamData.PlayerData > 0 then
+ table.insert(data, teamData);
+ end
+ end
+ end
+
+ return data;
+end
+
+function PopulateScoreTeamInstance(instance:table, teamData:table)
+
+ PopulateTeamInstanceShared(instance, teamData.TeamID);
+
+ -- Add team members to player stack
+ if instance.PlayerStackIM == nil then
+ instance.PlayerStackIM = InstanceManager:new("ScoreInstance", "ButtonBG", instance.ScorePlayerInstanceStack);
+ end
+
+ instance.PlayerStackIM:ResetInstances();
+
+ for i, playerData in ipairs(teamData.PlayerData) do
+ PopulateScoreInstance(instance.PlayerStackIM:GetInstance(), playerData);
+ end
+
+ -- Update combined team score
+ instance.TeamScore:SetText(tostring(teamData.TeamScore));
+end
+
+function PopulateScoreInstance(instance:table, playerData:table)
+ PopulatePlayerInstanceShared(instance, playerData.PlayerID);
+
+ instance.Score:SetText(playerData.PlayerScore);
+
+
+ if(m_ShowScoreDetails) then
+ instance.ButtonBG:SetSizeY(SIZE_SCORE_ITEM_DETAILS);
+
+ local detailsText:string = "";
+ for i, category in ipairs(playerData.Categories) do
+ local categoryInfo:table = GameInfo.ScoringCategories[category.CategoryID];
+ detailsText = detailsText .. Locale.Lookup(categoryInfo.Name) .. ": " .. category.CategoryScore;
+
+ -- Add new lines between categories but not at the end
+ if i <= #playerData.Categories then
+ detailsText = detailsText .. "[NEWLINE]";
+ end
+ end
+
+ instance.Details:SetText(detailsText);
+ instance.Details:SetHide(false);
+ else
+ instance.ButtonBG:SetSizeY(SIZE_SCORE_ITEM_DEFAULT);
+ instance.Details:SetHide(true);
+ end
+end
+
+function RealizeScoreStackSize()
+ local _, screenY:number = UIManager:GetScreenSizeVal();
+
+ if(m_ActiveHeader[DATA_FIELD_HEADER_EXPANDED]) then
+ local headerHeight:number = m_ActiveHeader[DATA_FIELD_HEADER_HEIGHT];
+ Controls.ScoreViewContents:SetOffsetY(OFFSET_VIEW_CONTENTS + headerHeight + PADDING_HEADER);
+ Controls.ScoreViewScrollbar:SetSizeY(screenY - (SIZE_STACK_DEFAULT + (headerHeight + PADDING_HEADER)));
+ else
+ Controls.ScoreViewContents:SetOffsetY(OFFSET_VIEW_CONTENTS);
+ Controls.ScoreViewScrollbar:SetSizeY(screenY - SIZE_STACK_DEFAULT);
+ end
+
+ RealizeStackAndScrollbar(Controls.ScoreViewStack, Controls.ScoreViewScrollbar, true);
+
+ local textSize:number = Controls.ScoreDetailsButton:GetTextControl():GetSizeX();
+ Controls.ScoreDetailsButton:SetSizeX(textSize + PADDING_SCORE_DETAILS_BUTTON_WIDTH);
+end
+
+function ToggleScoreDetails()
+ m_ShowScoreDetails = not m_ShowScoreDetails;
+ Controls.ScoreDetailsCheck:SetCheck(m_ShowScoreDetails);
+ ViewScore();
+end
+
+-- ===========================================================================
+-- Called when Science tab is selected (or when screen re-opens if selected)
+-- ===========================================================================
+function ViewScience()
+ ResetState(ViewScience);
+ Controls.ScienceView:SetHide(false);
+
+ ChangeActiveHeader("VICTORY_TECHNOLOGY", m_ScienceHeaderIM, Controls.ScienceViewHeader);
+ PopulateGenericHeader(RealizeScienceStackSize, SCIENCE_TITLE, "", SCIENCE_DETAILS, SCIENCE_ICON);
+
+ local totalCost:number = 0;
+ local currentProgress:number = 0;
+ local progressText:string = "";
+ local progressResults:table = { 0, 0, 0 }; -- initialize with 3 elements
+ local finishedProjects:table = { {}, {}, {} };
+
+ local bHasSpaceport:boolean = false;
+ if (m_LocalPlayer ~= nil) then
+ for _,district in m_LocalPlayer:GetDistricts():Members() do
+ if (district ~= nil and district:IsComplete() and district:GetType() == SPACE_PORT_DISTRICT_INFO.Index) then
+ bHasSpaceport = true;
+ break;
+ end
+ end
+
+ local pPlayerStats:table = m_LocalPlayer:GetStats();
+ local pPlayerCities:table = m_LocalPlayer:GetCities();
+ for _, city in pPlayerCities:Members() do
+ local pBuildQueue:table = city:GetBuildQueue();
+ -- 1st milestone - satelite launch
+ totalCost = 0;
+ currentProgress = 0;
+ for i, projectInfo in ipairs(EARTH_SATELLITE_PROJECT_INFOS) do
+ local projectCost:number = pBuildQueue:GetProjectCost(projectInfo.Index);
+ local projectProgress:number = projectCost;
+ if pPlayerStats:GetNumProjectsAdvanced(projectInfo.Index) == 0 then
+ projectProgress = pBuildQueue:GetProjectProgress(projectInfo.Index);
+ end
+ totalCost = totalCost + projectCost;
+ currentProgress = currentProgress + projectProgress;
+ finishedProjects[1][i] = projectProgress == projectCost;
+ end
+ progressResults[1] = currentProgress / totalCost;
+
+ -- 2nd milestone - moon landing
+ totalCost = 0;
+ currentProgress = 0;
+ for i, projectInfo in ipairs(MOON_LANDING_PROJECT_INFOS) do
+ local projectCost:number = pBuildQueue:GetProjectCost(projectInfo.Index);
+ local projectProgress:number = projectCost;
+ if pPlayerStats:GetNumProjectsAdvanced(projectInfo.Index) == 0 then
+ projectProgress = pBuildQueue:GetProjectProgress(projectInfo.Index);
+ end
+ totalCost = totalCost + projectCost;
+ currentProgress = currentProgress + projectProgress;
+ finishedProjects[2][i] = projectProgress == projectCost;
+ end
+ progressResults[2] = currentProgress / totalCost;
+
+ -- 3rd milestone - mars landing
+ totalCost = 0;
+ currentProgress = 0;
+ for i, projectInfo in ipairs(MARS_COLONY_PROJECT_INFOS) do
+ local projectCost:number = pBuildQueue:GetProjectCost(projectInfo.Index);
+ local projectProgress:number = projectCost;
+ if pPlayerStats:GetNumProjectsAdvanced(projectInfo.Index) == 0 then
+ projectProgress = pBuildQueue:GetProjectProgress(projectInfo.Index);
+ end
+ totalCost = totalCost + projectCost;
+ currentProgress = currentProgress + projectProgress;
+ finishedProjects[3][i] = projectProgress == projectCost;
+ end
+ progressResults[3] = currentProgress / totalCost;
+ end
+ end
+
+ local nextStep:string = "";
+ for i, result in ipairs(progressResults) do
+ if(result < 1) then
+ progressText = progressText .. "[ICON_Bolt]";
+ if(nextStep == "") then
+ nextStep = GetNextStepForScienceProject(m_LocalPlayer, SCIENCE_PROJECTS[i], bHasSpaceport, finishedProjects[i]);
+ end
+ else
+ progressText = progressText .. "[ICON_CheckmarkBlue] ";
+ end
+ progressText = progressText .. SCIENCE_REQUIREMENTS[i];
+ if(i < 3) then progressText = progressText .. "[NEWLINE]"; end
+ end
+
+ m_ActiveHeader.AdvisorTextCentered:SetText(progressText);
+ m_ActiveHeader.AdvisorTextNextStep:SetText(Locale.Lookup("LOC_WORLD_RANKINGS_SCIENCE_NEXT_STEP", nextStep));
+
+ m_ScienceIM:ResetInstances();
+ m_ScienceTeamIM:ResetInstances();
+
+ for teamID, team in pairs(Teams) do
+ if teamID >= 0 then
+ if #team > 1 then
+ PopulateScienceTeamInstance(m_ScienceTeamIM:GetInstance(), teamID);
+ else
+ local pPlayer = Players[team[1]];
+ if (pPlayer:IsAlive() == true and pPlayer:IsMajor() == true) then
+ PopulateScienceInstance(m_ScienceIM:GetInstance(), pPlayer);
+ end
+ end
+ end
+ end
+
+ RealizeScienceStackSize();
+end
+
+function GetNextStepForScienceProject(pPlayer:table, projectInfos:table, bHasSpaceport:boolean, finishedProjects:table)
+
+ if(not bHasSpaceport) then
+ return Locale.Lookup("LOC_WORLD_RANKINGS_SCIENCE_NEXT_STEP_BUILD", Locale.Lookup(SPACE_PORT_DISTRICT_INFO.Name));
+ end
+
+ local playerTech:table = pPlayer:GetTechs();
+ local numProjectInfos:number = table.count(projectInfos);
+ for i, projectInfo in ipairs(projectInfos) do
+
+ if(projectInfo.PrereqTech ~= nil) then
+ local tech:table = GameInfo.Technologies[projectInfo.PrereqTech];
+ if(not playerTech:HasTech(tech.Index)) then
+ return Locale.Lookup("LOC_WORLD_RANKINGS_SCIENCE_NEXT_STEP_RESEARCH", Locale.Lookup(tech.Name));
+ end
+ end
+
+ if(not finishedProjects[i]) then
+ return Locale.Lookup(projectInfo.Name);
+ end
+ end
+ return "";
+end
+
+function PopulateTeamInstanceShared(instance, teamID)
+ -- Update team color
+ local teamColor:number = GetTeamColor(teamID);
+ instance.TeamButton:SetColor(teamColor);
+ instance.TeamIconBacking:SetColor(teamColor);
+ instance.TeamIcon:SetColor(teamColor);
+
+ -- Update team ribbon
+ local teamRibbonName:string = TEAM_RIBBON_PREFIX .. tostring(teamID);
+ instance.TeamRibbon:SetIcon(teamRibbonName, TEAM_RIBBON_SIZE);
+ instance.TeamRibbon:SetColor(teamColor);
+
+ -- Update team name
+ instance.TeamName:SetText(Locale.Lookup("LOC_WORLD_RANKINGS_TEAM", GameConfiguration.GetTeamName(teamID)));
+
+ -- Update Team Tooltip
+ local teamData:table = { PlayerData = {} };
+ for i, playerID in ipairs(Teams[teamID]) do
+ if IsAliveAndMajor(playerID) then
+ teamData.PlayerData[playerID] = { Player = Players[playerID] };
+ end
+ end
+ SetTeamTooltip(instance.TeamIcon, teamData);
+end
+
+function PopulatePlayerInstanceShared(instance, playerID)
+ local civName, civIcon:string = GetCivNameAndIcon(playerID, true);
+
+ -- Update civ icon and leader tooltip
+ local textureOffsetX:number, textureOffsetY:number, textureSheet:string = IconManager:FindIconAtlas(civIcon, SIZE_CIV_ICON);
+ if(textureSheet == nil or textureSheet == "") then
+ UI.DataError("Could not find icon in PopulatePlayerInstanceShared: icon=\""..civIcon.."\", iconSize="..tostring(SIZE_CIV_ICON));
+ else
+ instance.CivIcon:SetTexture(textureOffsetX, textureOffsetY, textureSheet);
+ SetLeaderTooltip(instance, playerID);
+ end
+ ColorCivIcon(instance, playerID);
+
+ -- Update player name
+ if m_LocalPlayer == nil or m_LocalPlayer:GetDiplomacy():HasMet(playerID) or m_LocalPlayerID == playerID then
+ instance.CivName:SetText(civName);
+ TruncateStringWithTooltip(instance.CivName, 180, civName);
+ else
+ instance.CivName:SetText(LOC_UNKNOWN_CIV);
+ end
+
+ -- Update local player indicator
+ if instance.LocalPlayer then
+ instance.LocalPlayer:SetHide(playerID ~= m_LocalPlayerID);
+ end
+end
+
+function PopulateScienceTeamInstance(instance:table, teamID:number)
+
+ PopulateTeamInstanceShared(instance, teamID);
+
+ -- Add team members to player stack
+ if instance.PlayerStackIM == nil then
+ instance.PlayerStackIM = InstanceManager:new("ScienceInstance", "ButtonBG", instance.SciencePlayerInstanceStack);
+ end
+
+ instance.PlayerStackIM:ResetInstances();
+
+ local teamProgressData:table = {};
+ for i, playerID in ipairs(Teams[teamID]) do
+ if IsAliveAndMajor(playerID) then
+ local pPlayer:table = Players[playerID];
+ local progressData = PopulateScienceInstance(instance.PlayerStackIM:GetInstance(), pPlayer);
+ if progressData then
+ table.insert(teamProgressData, progressData);
+ end
+ end
+ end
+
+ -- Sort team progress data
+ table.sort(teamProgressData, function(a, b)
+ -- Compare stage 1 progress
+ local aScore = a.projectProgresses[1] / a.projectTotals[1];
+ local bScore = b.projectProgresses[1] / b.projectTotals[1];
+ if aScore == bScore then
+ -- Compare stage 2 progress
+ aScore = a.projectProgresses[2] / a.projectTotals[2];
+ bScore = b.projectProgresses[2] / b.projectTotals[2];
+ if aScore == bScore then
+ -- Compare stage 3 progress
+ aScore = a.projectProgresses[3] / a.projectTotals[3];
+ bScore = b.projectProgresses[3] / b.projectTotals[3];
+ if aScore == bScore then
+ return a.playerID < b.playerID;
+ end
+ end
+ end
+ return aScore > bScore;
+ end);
+
+ -- Populate the team progress with the progress of the furthest player
+ if teamProgressData and #teamProgressData > 0 then
+ PopulateScienceProgressMeters(instance, teamProgressData[1]);
+ end
+end
+
+function PopulateScienceInstance(instance:table, pPlayer:table)
+ local playerID:number = pPlayer:GetID();
+ PopulatePlayerInstanceShared(instance, playerID);
+
+ -- Progress Data to be returned from function
+ local progressData = nil;
+ local bHasMet = m_LocalPlayer == nil or m_LocalPlayer:GetDiplomacy():HasMet(playerID);
+ if (bHasMet == true or playerID == Game.GetLocalPlayer()) then
+
+ local bHasSpaceport:boolean = false;
+ for _,district in pPlayer:GetDistricts():Members() do
+ if (district ~= nil and district:IsComplete() and district:GetType() == SPACE_PORT_DISTRICT_INFO.Index) then
+ bHasSpaceport = true;
+ break;
+ end
+ end
+
+ local pPlayerStats:table = pPlayer:GetStats();
+ local pPlayerCities:table = pPlayer:GetCities();
+ local projectTotals:table = { 0, 0, 0 };
+ local projectProgresses:table = { 0, 0, 0 };
+ local finishedProjects:table = { {}, {}, {} };
+ for _, city in pPlayerCities:Members() do
+ local pBuildQueue:table = city:GetBuildQueue();
+
+ -- 1st milestone - satelite launch
+ for i, projectInfo in ipairs(EARTH_SATELLITE_PROJECT_INFOS) do
+ local projectCost:number = pBuildQueue:GetProjectCost(projectInfo.Index);
+ local projectProgress:number = projectCost;
+ if pPlayerStats:GetNumProjectsAdvanced(projectInfo.Index) == 0 then
+ projectProgress = pBuildQueue:GetProjectProgress(projectInfo.Index);
+ end
+ finishedProjects[1][i] = false;
+ if projectProgress ~= 0 then
+ projectTotals[1] = projectTotals[1] + projectCost;
+ projectProgresses[1] = projectProgresses[1] + projectProgress;
+ finishedProjects[1][i] = projectProgress == projectCost;
+ end
+ end
+
+ -- 2nd milestone - moon landing
+ for i, projectInfo in ipairs(MOON_LANDING_PROJECT_INFOS) do
+ local projectCost:number = pBuildQueue:GetProjectCost(projectInfo.Index);
+ local projectProgress:number = projectCost;
+ if pPlayerStats:GetNumProjectsAdvanced(projectInfo.Index) == 0 then
+ projectProgress = pBuildQueue:GetProjectProgress(projectInfo.Index);
+ end
+ finishedProjects[2][i] = false;
+ if projectProgress ~= 0 then
+ projectTotals[2] = projectTotals[2] + projectCost;
+ projectProgresses[2] = projectProgresses[2] + projectProgress;
+ finishedProjects[2][i] = projectProgress == projectCost;
+ end
+ end
+
+ -- 3rd milestone - mars landing
+ for i, projectInfo in ipairs(MARS_COLONY_PROJECT_INFOS) do
+ local projectCost:number = pBuildQueue:GetProjectCost(projectInfo.Index);
+ local projectProgress:number = projectCost;
+ if pPlayerStats:GetNumProjectsAdvanced(projectInfo.Index) == 0 then
+ projectProgress = pBuildQueue:GetProjectProgress(projectInfo.Index);
+ end
+ finishedProjects[3][i] = false;
+ if projectProgress ~= 0 then
+ projectTotals[3] = projectTotals[3] + projectCost;
+ projectProgresses[3] = projectProgresses[3] + projectProgress;
+ finishedProjects[3][i] = projectProgress == projectCost;
+ end
+ end
+ end
+
+ -- Save data to be returned
+ progressData = {};
+ progressData.playerID = playerID;
+ progressData.projectTotals = projectTotals;
+ progressData.projectProgresses = projectProgresses;
+ progressData.bHasSpaceport = bHasSpaceport;
+ progressData.finishedProjects = finishedProjects;
+
+ PopulateScienceProgressMeters(instance, progressData);
+ else -- Unmet civ
+ for i = 1, 3 do
+ instance["ObjBar_" .. i]:SetPercent(0);
+ instance["ObjFill_" .. i]:SetHide(true);
+ instance["ObjHidden_" .. i]:SetHide(false);
+ instance["ObjToggle_ON_" .. i]:SetHide(true);
+ instance["ObjToggle_ON_" .. i]:SetToolTipString("");
+ instance["ObjToggle_OFF_" .. i]:SetToolTipString("");
+ end
+ end
+
+ return progressData;
+end
+
+function PopulateScienceProgressMeters(instance:table, progressData:table)
+ for i = 1, 3 do
+ instance["ObjHidden_" .. i]:SetHide(true);
+ instance["ObjFill_" .. i]:SetHide(progressData.projectProgresses[i] == 0);
+ instance["ObjBar_" .. i]:SetPercent(progressData.projectProgresses[i] / progressData.projectTotals[i]);
+ instance["ObjToggle_ON_" .. i]:SetHide(progressData.projectTotals[i] == 0 or progressData.projectProgresses[i] ~= progressData.projectTotals[i]);
+ end
+
+ local pPlayer = Players[progressData.playerID];
+ instance.ObjBG_1:SetToolTipString(GetTooltipForScienceProject(pPlayer, EARTH_SATELLITE_PROJECT_INFOS, progressData.bHasSpaceport, progressData.finishedProjects[1]));
+ instance.ObjBG_2:SetToolTipString(GetTooltipForScienceProject(pPlayer, MOON_LANDING_PROJECT_INFOS, nil, progressData.finishedProjects[2]));
+ instance.ObjBG_3:SetToolTipString(GetTooltipForScienceProject(pPlayer, MARS_COLONY_PROJECT_INFOS, nil, progressData.finishedProjects[3]));
+end
+
+function GetTooltipForScienceProject(pPlayer:table, projectInfos:table, bHasSpaceport:boolean, finishedProjects:table)
+
+ local result:string = "";
+
+ -- Only show spaceport for first tooltip
+ if bHasSpaceport ~= nil then
+ if(bHasSpaceport) then
+ result = result .. "[ICON_CheckmarkBlue]";
+ else
+ result = result .. "[ICON_Bolt]";
+ end
+ result = result .. Locale.Lookup("LOC_WORLD_RANKINGS_SCIENCE_NEXT_STEP_BUILD", Locale.Lookup(SPACE_PORT_DISTRICT_INFO.Name)) .. "[NEWLINE]";
+ end
+
+ local playerTech:table = pPlayer:GetTechs();
+ local numProjectInfos:number = table.count(projectInfos);
+ for i, projectInfo in ipairs(projectInfos) do
+
+ if(projectInfo.PrereqTech ~= nil) then
+ local tech:table = GameInfo.Technologies[projectInfo.PrereqTech];
+ if(playerTech:HasTech(tech.Index)) then
+ result = result .. "[ICON_CheckmarkBlue]";
+ else
+ result = result .. "[ICON_Bolt]";
+ end
+ result = result .. Locale.Lookup("LOC_WORLD_RANKINGS_SCIENCE_NEXT_STEP_RESEARCH", Locale.Lookup(tech.Name)) .. "[NEWLINE]";
+ end
+
+ if(finishedProjects[i]) then
+ result = result .. "[ICON_CheckmarkBlue]";
+ else
+ result = result .. "[ICON_Bolt]";
+ end
+ result = result .. Locale.Lookup(projectInfo.Name);
+ if(i < numProjectInfos) then result = result .. "[NEWLINE]"; end
+ end
+
+ return result;
+end
+
+function RealizeScienceStackSize()
+ local _, screenY:number = UIManager:GetScreenSizeVal();
+
+ if(m_ActiveHeader[DATA_FIELD_HEADER_EXPANDED]) then
+ local headerHeight:number = m_ActiveHeader[DATA_FIELD_HEADER_HEIGHT];
+ m_ActiveHeader.AdvisorTextCentered:SetOffsetY(OFFSET_SCIENCE_REQUIREMENTS_Y + m_ActiveHeader.AdvisorText:GetSizeY() + PADDING_HEADER);
+ m_ActiveHeader.AdvisorTextNextStep:SetOffsetY(m_ActiveHeader.AdvisorTextCentered:GetOffsetY() + m_ActiveHeader.AdvisorTextCentered:GetSizeY() + PADDING_HEADER);
+ m_ActiveHeader.NextStepHighlight:SetOffsetY(-m_ActiveHeader.AdvisorTextNextStep:GetSizeY() + PADDING_NEXT_STEP_HIGHLIGHT);
+ headerHeight = headerHeight + m_ActiveHeader.AdvisorTextCentered:GetSizeY() + m_ActiveHeader.AdvisorTextNextStep:GetSizeY() + (PADDING_HEADER * 2);
+ m_ActiveHeader.AdvisorTextBG:SetSizeY(headerHeight);
+ m_ActiveHeader.AdvisorIcon:SetOffsetY(OFFSET_ADVISOR_ICON_Y + headerHeight);
+ m_ActiveHeader.HeaderFrame:SetSizeY(OFFSET_ADVISOR_TEXT_Y + headerHeight);
+ m_ActiveHeader.ContractHeaderButton:SetOffsetY(OFFSET_CONTRACT_BUTTON_Y + headerHeight);
+ Controls.ScienceViewContents:SetOffsetY(OFFSET_VIEW_CONTENTS + headerHeight + PADDING_HEADER);
+ Controls.ScienceViewScrollbar:SetSizeY(screenY - (SIZE_STACK_DEFAULT + (headerHeight + PADDING_HEADER)));
+ m_ActiveHeader.AdvisorTextCentered:SetHide(false);
+ m_ActiveHeader.AdvisorTextNextStep:SetHide(false);
+ else
+ Controls.ScienceViewContents:SetOffsetY(OFFSET_VIEW_CONTENTS);
+ Controls.ScienceViewScrollbar:SetSizeY(screenY - SIZE_STACK_DEFAULT);
+ m_ActiveHeader.AdvisorTextCentered:SetHide(true);
+ m_ActiveHeader.AdvisorTextNextStep:SetHide(true);
+ end
+
+ RealizeStackAndScrollbar(Controls.ScienceViewStack, Controls.ScienceViewScrollbar, true);
+
+ --local textSize:number = Controls.ScienceDetailsButton:GetTextControl():GetSizeX();
+ --Controls.ScienceDetailsButton:SetSizeX(textSize + PADDING_SCORE_DETAILS_BUTTON_WIDTH);
+end
+
+-- ===========================================================================
+function ResetTourismLens()
+ if UILens.IsLensActive("TourismWithUnits") then
+ UILens.SetActive("Default");
+ end
+end
+
+-- ===========================================================================
+-- Called when Culture tab is selected (or when screen re-opens if selected)
+-- ===========================================================================
+function SetCultureHeaderState(state:number)
+ m_CultureHeaderState = state;
+ ViewCulture();
+end
+
+function ViewCulture()
+ ResetState(ViewCulture);
+ Controls.CultureView:SetHide(false);
+
+ ChangeActiveHeader("VICTORY_CULTURE", m_CultureHeaderIM, Controls.CultureViewHeader);
+
+ -- Active the Tourism lens if it isn't already
+ if not UILens.IsLensActive("TourismWithUnits") then
+ UILens.SetActive("TourismWithUnits");
+ end
+
+ local detailsText:string;
+ if(m_CultureHeaderState == CULTURE_HEADER_STATES.WHAT_IS_CULTURE_VICTORY) then
+ detailsText = CULTURE_VICTORY_DETAILS;
+ m_ActiveHeader.DomesticTourism:SetText(CULTURE_DOMESTIC_TOURISTS);
+ m_ActiveHeader.VisitingTourism:SetText(CULTURE_VISITING_TOURISTS);
+ else
+ UI.DataError("Unknown m_CultureHeaderState in ViewCulture: " .. tostring(m_CultureHeaderState));
+ end
+
+ PopulateGenericHeader(RealizeCultureStackSize, CULTURE_TITLE, "", detailsText, CULTURE_ICON);
+
+ -- Gather data
+ local cultureData:table = GatherCultureData();
+
+ -- Sort by team
+ table.sort(cultureData, function(a, b) return a.BestNumVisitingUs / a.BestNumRequiredTourists > b.BestNumVisitingUs / b.BestNumRequiredTourists; end);
+
+ m_CultureIM:ResetInstances();
+ m_CultureTeamIM:ResetInstances();
+
+ for i, teamData in ipairs(cultureData) do
+ if #teamData.PlayerData > 1 then
+ -- Display as team
+ PopulateCultureTeamInstance(m_CultureTeamIM:GetInstance(), teamData);
+ elseif #teamData.PlayerData > 0 then
+ -- Display as single civ
+ PopulateCultureInstance(m_CultureIM:GetInstance(), teamData.PlayerData[1]);
+ end
+ end
+
+ RealizeCultureStackSize();
+end
+
+function GatherCultureData()
+ local data:table = {};
+
+ for teamID, team in pairs(Teams) do
+ if teamID >= 0 then
+ local teamData:table = { TeamID = teamID, PlayerData = {}, BestNumVisitingUs = 0, BestNumRequiredTourists = 1 };
+
+ -- Add players
+ for i, playerID in ipairs(team) do
+ if IsAliveAndMajor(playerID) then
+ local pPlayer:table = Players[playerID];
+ local playerData:table = {
+ PlayerID = playerID,
+ NumRequiredTourists = 0,
+ NumStaycationers = pPlayer:GetCulture():GetStaycationers(),
+ NumVisitingUs = pPlayer:GetCulture():GetTouristsTo() };
+
+ -- Determine number of tourist needed for victory
+ -- Has to be one more than every other players number of domestic tourists
+ for i, player in ipairs(Players) do
+ if i ~= playerID and IsAliveAndMajor(i) and player:GetTeam() ~= teamID then
+ local iStaycationers = player:GetCulture():GetStaycationers();
+ if iStaycationers >= playerData.NumRequiredTourists then
+ playerData.NumRequiredTourists = iStaycationers + 1;
+ end
+ end
+ end
+
+ -- See if this player has the best score for this team
+ local currentTeamScore:number = teamData.BestNumVisitingUs / teamData.BestNumRequiredTourists;
+ local playerScore:number = playerData.NumVisitingUs / playerData.NumRequiredTourists;
+ if currentTeamScore < playerScore or (currentTeamScore == playerScore and teamData.BestNumRequiredTourists < playerData.NumRequiredTourists) then
+ teamData.BestNumVisitingUs = playerData.NumVisitingUs;
+ teamData.BestNumRequiredTourists = playerData.NumRequiredTourists;
+ end
+
+ table.insert(teamData.PlayerData, playerData);
+ end
+ end
+
+ -- Only add teams with at least one living, major player
+ if #teamData.PlayerData > 0 then
+ table.insert(data, teamData);
+ end
+ end
+ end
+
+ return data;
+end
+
+function PopulateCultureTeamInstance(instance:table, teamData:table)
+ PopulateTeamInstanceShared(instance, teamData.TeamID);
+
+ -- Add team members to player stack
+ if instance.PlayerStackIM == nil then
+ instance.PlayerStackIM = InstanceManager:new("CultureInstance", "ButtonBG", instance.CulturePlayerInstanceStack);
+ end
+
+ instance.PlayerStackIM:ResetInstances();
+
+ for i, playerData in ipairs(teamData.PlayerData) do
+ PopulateCultureInstance(instance.PlayerStackIM:GetInstance(), playerData);
+ end
+
+ -- Show score for player closet to winning
+ instance.VisitingTourists:SetText(teamData.BestNumVisitingUs .. "/" .. teamData.BestNumRequiredTourists);
+end
+
+function PopulateCultureInstance(instance:table, playerData:table)
+ local pPlayer:table = Players[playerData.PlayerID];
+
+ PopulatePlayerInstanceShared(instance, playerData.PlayerID);
+
+ instance.VisitingTourists:SetText(playerData.NumVisitingUs .. "/" .. playerData.NumRequiredTourists);
+ instance.TouristsFill:SetPercent(playerData.NumVisitingUs / playerData.NumRequiredTourists);
+ instance.VisitingUsContainer:SetHide(playerData.PlayerID == m_LocalPlayerID);
+
+ local backColor, _ = UI.GetPlayerColors(playerData.PlayerID);
+ local brighterBackColor = DarkenLightenColor(backColor,35,255);
+ if(playerData.PlayerID == m_LocalPlayerID or m_LocalPlayer == nil or m_LocalPlayer:GetDiplomacy():HasMet(playerData.PlayerID)) then
+ instance.DomesticTouristsIcon:SetColor(brighterBackColor);
+ else
+ instance.DomesticTouristsIcon:SetColor(RGBAValuesToABGRHex(1, 1, 1, 0.35));
+ end
+ instance.DomesticTourists:SetText(playerData.NumStaycationers);
+
+ if (m_LocalPlayer ~= nil) then
+ instance.VisitingUsTourists:SetText(m_LocalPlayer:GetCulture():GetTouristsFrom(playerData.PlayerID));
+ instance.VisitingUsTourists:SetToolTipString(m_LocalPlayer:GetCulture():GetTouristsFromTooltip(playerData.PlayerID));
+ instance.VisitingUsIcon:SetToolTipString(m_LocalPlayer:GetCulture():GetTouristsFromTooltip(playerData.PlayerID));
+ end
+end
+
+function RealizeCultureStackSize()
+ local _, screenY:number = UIManager:GetScreenSizeVal();
+
+ if(m_ActiveHeader[DATA_FIELD_HEADER_EXPANDED]) then
+ local headerHeight:number = m_ActiveHeader.AdvisorText:GetSizeY() + PADDING_ADVISOR_TEXT_BG;
+
+ if(m_CultureHeaderState == CULTURE_HEADER_STATES.WHAT_IS_CULTURE_VICTORY) then
+ m_ActiveHeader.HowToAttractTourists:SetOffsetY(headerHeight);
+ headerHeight = headerHeight + math.max(m_ActiveHeader.DomesticTourism:GetSizeY(), m_ActiveHeader.DomesticTourismIcon:GetSizeY()) + (PADDING_HEADER * 2);
+ headerHeight = headerHeight + math.max(m_ActiveHeader.VisitingTourism:GetSizeY(), m_ActiveHeader.VisitingTourismIcon:GetSizeY()) + PADDING_HEADER;
+ m_ActiveHeader.HowToAttractTourists:SetHide(false);
+ else
+ UI.DataError("Unknown m_CultureHeaderState in ViewCulture: " .. tostring(m_CultureHeaderState));
+ end
+
+ m_ActiveHeader.AdvisorTextBG:SetSizeY(headerHeight);
+ m_ActiveHeader.AdvisorIcon:SetOffsetY(OFFSET_ADVISOR_ICON_Y + headerHeight);
+ m_ActiveHeader.HeaderFrame:SetSizeY(OFFSET_ADVISOR_TEXT_Y + headerHeight);
+ m_ActiveHeader.ContractHeaderButton:SetOffsetY(OFFSET_CONTRACT_BUTTON_Y + headerHeight);
+
+ m_ActiveHeader.StateBG:SetOffsetY(headerHeight + PADDING_CULTURE_HEADER);
+
+ headerHeight = headerHeight + m_ActiveHeader.StateBG:GetSizeY() + PADDING_HEADER;
+
+ m_ActiveHeader.NextState:SetOffsetX(m_ActiveHeader.StateBG:GetSizeX());
+
+ Controls.CultureViewContents:SetOffsetY(OFFSET_VIEW_CONTENTS + headerHeight + PADDING_HEADER);
+ Controls.CultureViewScrollbar:SetSizeY(screenY - (SIZE_STACK_DEFAULT + (headerHeight + PADDING_HEADER)));
+ else
+ Controls.CultureViewContents:SetOffsetY(OFFSET_VIEW_CONTENTS);
+ Controls.CultureViewScrollbar:SetSizeY(screenY - SIZE_STACK_DEFAULT);
+ m_ActiveHeader.HowToAttractTourists:SetHide(true);
+ end
+
+ RealizeStackAndScrollbar(Controls.CultureViewStack, Controls.CultureViewScrollbar, true);
+end
+
+-- ===========================================================================
+-- Called when Domination tab is selected (or when screen re-opens if selected)
+-- ===========================================================================
+function ViewDomination()
+ ResetState(ViewDomination);
+ Controls.DominationView:SetHide(false);
+
+ ChangeActiveHeader("VICTORY_CONQUEST", m_GenericHeaderIM, Controls.DominationViewHeader);
+ PopulateGenericHeader(RealizeDominationStackSize, DOMINATION_TITLE, "", DOMINATION_DETAILS, DOMINATION_ICON);
+
+ local dominationData:table = {};
+ for teamID, team in pairs(Teams) do
+ if teamID >= 0 then
+ local teamData:table = { TeamID = teamID, TotalCapturedCapitals = 0, PlayerData = {} };
+
+ for i, playerID in ipairs(team) do
+ if IsAliveAndMajor(playerID) then
+ local pPlayer = Players[playerID];
+ local pCities = pPlayer:GetCities();
+
+ -- Don't show player if they haven't founded a capital city yet
+ local pCapital = pCities:GetCapitalCity();
+ if(pCapital ~= nil) then
+ local playerData:table = {};
+ playerData.PlayerID = playerID;
+ playerData.HasOriginalCapital = false;
+ playerData.CapturedCapitals = {};
+
+ local data = {};
+ for _, city in pCities:Members() do
+ local originalOwnerID:number = city:GetOriginalOwner();
+ local pOriginalOwner:table = Players[originalOwnerID];
+ if(playerID ~= originalOwnerID and pOriginalOwner:IsMajor() and city:IsOriginalCapital()) then
+ table.insert(playerData.CapturedCapitals, originalOwnerID);
+ teamData.TotalCapturedCapitals = teamData.TotalCapturedCapitals + 1;
+ elseif(playerID == originalOwnerID and pOriginalOwner:IsMajor() and city:IsOriginalCapital()) then
+ playerData.HasOriginalCapital = true;
+ end
+ end
+
+ table.insert(teamData.PlayerData, playerData);
+ end
+ end
+ end
+
+ table.insert(dominationData, teamData);
+ end
+ end
+
+ m_DominationIM:ResetInstances();
+ m_DominationTeamIM:ResetInstances();
+
+ -- Sort players within teams by dominated capitals
+ for i, teamData in ipairs(dominationData) do
+ table.sort(teamData.PlayerData, function(a, b) return #a.CapturedCapitals > #b.CapturedCapitals end);
+ end
+
+ -- Sort teams by most combined dominated capitals
+ table.sort(dominationData, function(a, b) return a.TotalCapturedCapitals > b.TotalCapturedCapitals end);
+
+ -- Populate teams
+ for i, teamData in ipairs(dominationData) do
+ if #teamData.PlayerData > 1 then
+ PopulateDominationTeamInstance(m_DominationTeamIM:GetInstance(), teamData);
+ elseif #teamData.PlayerData == 1 then
+ PopulateDominationInstance(m_DominationIM:GetInstance(), teamData.PlayerData[1]);
+ end
+ end
+
+ RealizeDominationStackSize();
+end
+
+function PopulateDominationTeamInstance(instance:table, teamData:table)
+
+ PopulateTeamInstanceShared(instance, teamData.TeamID);
+
+ -- Update captured captials icon stack
+ local dominatedCitiesIM:table = instance[DATA_FIELD_DOMINATED_CITIES_IM];
+ if(dominatedCitiesIM == nil) then
+ dominatedCitiesIM = InstanceManager:new("DominatedCapitalInstance", "CivIconBacking", instance.CapitalsCapturedStack);
+ instance[DATA_FIELD_DOMINATED_CITIES_IM] = dominatedCitiesIM;
+ end
+ dominatedCitiesIM:ResetInstances();
+
+ for i, playerData in ipairs(teamData.PlayerData) do
+ for _, dominatedPlayerID in pairs(playerData.CapturedCapitals) do
+ local dominatedInstance = dominatedCitiesIM:GetInstance();
+ ColorCivIcon(dominatedInstance, dominatedPlayerID);
+
+ local civName:string, civIcon:string = GetCivNameAndIcon(dominatedPlayerID, true);
+ textureOffsetX, textureOffsetY, textureSheet = IconManager:FindIconAtlas(civIcon, SIZE_RELIGION_CIV_ICON);
+ if(textureSheet == nil or textureSheet == "") then
+ UI.DataError("Could not find icon for dominated civ in PopulateDominationInstance: icon=\""..civIcon.."\", iconSize="..tostring(SIZE_RELIGION_CIV_ICON));
+ else
+ dominatedInstance.CivIcon:SetTexture(textureOffsetX, textureOffsetY, textureSheet);
+ SetLeaderTooltip(dominatedInstance, dominatedPlayerID);
+ end
+ end
+ end
+
+ -- Update captured capitals label
+ instance.CapitalsCaptured:SetText(Locale.Lookup("LOC_WORLD_RANKINGS_DOMINATION_SUMMARY", teamData.TotalCapturedCapitals));
+
+ -- Add team members to player stack
+ if instance.PlayerStackIM == nil then
+ instance.PlayerStackIM = InstanceManager:new("DominationInstance", "ButtonBG", instance.PlayerInstanceStack);
+ end
+
+ instance.PlayerStackIM:ResetInstances();
+
+ for i, playerData in ipairs(teamData.PlayerData) do
+ PopulateDominationInstance(instance.PlayerStackIM:GetInstance(), playerData);
+ end
+end
+
+function PopulateDominationInstance(instance:table, playerData:table)
+ local pPlayer:table = Players[playerData.PlayerID];
+
+ PopulatePlayerInstanceShared(instance, playerData.PlayerID);
+
+ instance.HasCapital:SetHide(not playerData.HasOriginalCapital);
+ instance.HasCapital:SetToolTipString(DOMINATION_HAS_ORIGINAL_CAPITAL);
+
+ local dominatedCitiesIM:table = instance[DATA_FIELD_DOMINATED_CITIES_IM];
+ if(dominatedCitiesIM == nil) then
+ dominatedCitiesIM = InstanceManager:new("DominatedCapitalInstance", "CivIconBacking", instance.CapitalsCapturedStack);
+ instance[DATA_FIELD_DOMINATED_CITIES_IM] = dominatedCitiesIM;
+ end
+ dominatedCitiesIM:ResetInstances();
+
+ for _, dominatedPlayerID in pairs(playerData.CapturedCapitals) do
+ local dominatedInstance = dominatedCitiesIM:GetInstance();
+ ColorCivIcon(dominatedInstance, dominatedPlayerID);
+
+ local civName:string, civIcon:string = GetCivNameAndIcon(dominatedPlayerID, true);
+ textureOffsetX, textureOffsetY, textureSheet = IconManager:FindIconAtlas(civIcon, SIZE_RELIGION_CIV_ICON);
+ if(textureSheet == nil or textureSheet == "") then
+ UI.DataError("Could not find icon for dominated civ in PopulateDominationInstance: icon=\""..civIcon.."\", iconSize="..tostring(SIZE_RELIGION_CIV_ICON));
+ else
+ dominatedInstance.CivIcon:SetTexture(textureOffsetX, textureOffsetY, textureSheet);
+ SetLeaderTooltip(dominatedInstance, dominatedPlayerID);
+ end
+ end
+
+ instance.CapitalsCaptured:SetText(Locale.Lookup("LOC_WORLD_RANKINGS_DOMINATION_SUMMARY", #playerData.CapturedCapitals));
+end
+
+function RealizeDominationStackSize()
+ local _, screenY:number = UIManager:GetScreenSizeVal();
+
+ if(m_ActiveHeader[DATA_FIELD_HEADER_EXPANDED]) then
+ local headerHeight:number = m_ActiveHeader[DATA_FIELD_HEADER_HEIGHT];
+ Controls.DominationViewContents:SetOffsetY(OFFSET_VIEW_CONTENTS + headerHeight + PADDING_HEADER);
+ Controls.DominationViewScrollbar:SetSizeY(screenY - (SIZE_STACK_DEFAULT + (headerHeight + PADDING_HEADER)));
+ else
+ Controls.DominationViewContents:SetOffsetY(OFFSET_VIEW_CONTENTS);
+ Controls.DominationViewScrollbar:SetSizeY(screenY - SIZE_STACK_DEFAULT);
+ end
+
+ RealizeStackAndScrollbar(Controls.DominationViewStack, Controls.DominationViewScrollbar, true);
+end
+
+-- ===========================================================================
+-- Called when Religion tab is selected (or when screen re-opens if selected)
+-- ===========================================================================
+function ViewReligion()
+ ResetState(ViewReligion);
+ Controls.ReligionView:SetHide(false);
+
+ ChangeActiveHeader("VICTORY_RELIGIOUS", m_GenericHeaderIM, Controls.ReligionViewHeader);
+ PopulateGenericHeader(RealizeReligionStackSize, RELIGION_TITLE, "", RELIGION_DETAILS, RELIGION_ICON);
+
+ m_ReligionIM:ResetInstances();
+ m_ReligionTeamIM:ResetInstances();
+
+ local religionData:table, totalCivs:number = GatherReligionData();
+
+ for i, teamData in ipairs(religionData) do
+ if #teamData.PlayerData > 1 then
+ -- Display as team
+ PopulateReligionTeamInstance(m_ReligionTeamIM:GetInstance(), teamData, totalCivs);
+ elseif #teamData.PlayerData > 0 then
+ -- Display as single civ
+ if teamData.PlayerData[1].ReligionType > 0 then
+ PopulateReligionInstance(m_ReligionIM:GetInstance(), teamData.PlayerData[1], totalCivs);
+ end
+ end
+ end
+
+ RealizeReligionStackSize();
+end
+
+function GatherReligionData()
+ local data:table = {};
+ local totalCivs:number = 0;
+
+ for teamID, team in pairs(Teams) do
+ if teamID >= 0 then
+ local teamData:table = { TeamID = teamID, PlayerData = {}, ReligionTypes = {}, ConvertedCivs = {} };
+
+ -- Add players
+ for i, playerID in ipairs(team) do
+ if IsAliveAndMajor(playerID) then
+ totalCivs = totalCivs + 1;
+ local pPlayer:table = Players[playerID];
+ local playerData:table = { PlayerID = playerID, ConvertedCivs = {} };
+
+ local pReligion = pPlayer:GetReligion();
+ if pReligion ~= nil then
+ playerData.ReligionType = pReligion:GetReligionTypeCreated();
+ if playerData.ReligionType ~= -1 then
+
+ -- Add religion to team religions if unique
+ local containsReligion:boolean = false;
+ for i, religionType in ipairs(teamData.ReligionTypes) do
+ if religionType == playerData.ReligionType then
+ containsReligion = true;
+ end
+ end
+ if not containsReligion then
+ table.insert(teamData.ReligionTypes, playerData.ReligionType );
+ end
+
+ -- Determine which civs our religion has taken over
+ for otherID, player in ipairs(Players) do
+ if IsAliveAndMajor(otherID) then
+ local pOtherReligion = player:GetReligion();
+ if pOtherReligion ~= nil then
+ local otherReligionType:number = pOtherReligion:GetReligionInMajorityOfCities();
+ if otherReligionType == playerData.ReligionType then
+ table.insert(playerData.ConvertedCivs, otherID);
+
+ -- Add convert civs to team converted civs if unique
+ local containsCiv:boolean = false;
+ for i, convertedCivID in ipairs(teamData.ConvertedCivs) do
+ if convertedCivID == otherID then
+ containsCiv = true;
+ end
+ end
+ if not containsCiv then
+ table.insert(teamData.ConvertedCivs, otherID );
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+
+ table.insert(teamData.PlayerData, playerData);
+ end
+ end
+
+ -- Only add teams with at least one living, major player
+ if #teamData.PlayerData > 0 then
+ table.insert(data, teamData);
+ end
+ end
+ end
+
+ return data, totalCivs;
+end
+
+function PopulateReligionTeamInstance(instance:table, teamData:table, totalCivs:number)
+ PopulateTeamInstanceShared(instance, teamData.TeamID);
+
+ -- Add team members to player stack
+ if instance.PlayerStackIM == nil then
+ instance.PlayerStackIM = InstanceManager:new("ReligionInstance", "ButtonBG", instance.PlayerInstanceStack);
+ end
+
+ instance.PlayerStackIM:ResetInstances();
+
+ for i, playerData in ipairs(teamData.PlayerData) do
+ if playerData.ReligionType > 0 then
+ PopulateReligionInstance(instance.PlayerStackIM:GetInstance(), playerData, totalCivs);
+ end
+ end
+
+ local convertedCivsIM:table = instance[DATA_FIELD_RELIGION_CONVERTED_CIVS_IM];
+ if(convertedCivsIM == nil) then
+ convertedCivsIM = InstanceManager:new("ConvertedReligionInstance", "CivIconBacking", instance.CivsConvertedStack);
+ instance[DATA_FIELD_RELIGION_CONVERTED_CIVS_IM] = convertedCivsIM;
+ end
+
+ convertedCivsIM:ResetInstances();
+
+ for i, convertedCivID in ipairs(teamData.ConvertedCivs) do
+ local convertedInstance:table = convertedCivsIM:GetInstance();
+
+ ColorCivIcon(convertedInstance, convertedCivID);
+
+ local civName:string, civIcon:string = GetCivNameAndIcon(convertedCivID, true);
+ textureOffsetX, textureOffsetY, textureSheet = IconManager:FindIconAtlas(civIcon, SIZE_RELIGION_CIV_ICON);
+ if(textureSheet == nil or textureSheet == "") then
+ UI.DataError("Could not find icon for converted religion in PopulateReligionInstance: icon=\""..civIcon.."\", iconSize="..tostring(SIZE_RELIGION_CIV_ICON));
+ else
+ convertedInstance.CivIcon:SetTexture(textureOffsetX, textureOffsetY, textureSheet);
+ SetLeaderTooltip(convertedInstance, convertedCivID);
+ end
+ end
+
+ instance.CivsConverted:SetText(Locale.Lookup("LOC_WORLD_RANKINGS_RELIGION_CONVERT_SUMMARY", #teamData.ConvertedCivs .. "/" .. totalCivs, "LOC_WORLD_RANKINGS_RELIGION_TEAMS_RELIGIONS"));
+end
+
+function PopulateReligionInstance(instance:table, playerData:table, totalCivs:number)
+
+ PopulatePlayerInstanceShared(instance, playerData.PlayerID);
+
+ local religionData = GameInfo.Religions[playerData.ReligionType];
+ local religionColor:number = UI.GetColorValue(religionData.Color);
+
+ instance.ReligionName:SetColor(religionColor);
+ instance.ReligionName:SetText(Game.GetReligion():GetName(playerData.ReligionType));
+ instance.ReligionBG:SetSizeX(instance.ReligionName:GetSizeX() + PADDING_RELIGION_NAME_BG);
+ instance.ReligionBG:SetColor(religionColor);
+
+ local textureOffsetX:number, textureOffsetY:number, textureSheet:string = IconManager:FindIconAtlas("ICON_" .. religionData.ReligionType, SIZE_RELIGION_ICON_SMALL);
+ if(textureSheet == nil or textureSheet == "") then
+ UI.DataError("Could not find icon in PopulateReligionInstance: icon=\"".."ICON_" .. religionData.ReligionType.."\", iconSize="..tostring(SIZE_RELIGION_ICON_SMALL) );
+ else
+ instance.ReligionIcon:SetColor(religionColor);
+ instance.ReligionIcon:SetTexture(textureOffsetX, textureOffsetY, textureSheet);
+ end
+
+ local convertedCivsIM:table = instance[DATA_FIELD_RELIGION_CONVERTED_CIVS_IM];
+ if(convertedCivsIM == nil) then
+ convertedCivsIM = InstanceManager:new("ConvertedReligionInstance", "CivIconBacking", instance.CivsConvertedStack);
+ instance[DATA_FIELD_RELIGION_CONVERTED_CIVS_IM] = convertedCivsIM;
+ end
+
+ convertedCivsIM:ResetInstances();
+
+ for i, convertedCivID in ipairs(playerData.ConvertedCivs) do
+ local convertedInstance:table = convertedCivsIM:GetInstance();
+
+ ColorCivIcon(convertedInstance, convertedCivID);
+
+ local civName:string, civIcon:string = GetCivNameAndIcon(convertedCivID, true);
+ textureOffsetX, textureOffsetY, textureSheet = IconManager:FindIconAtlas(civIcon, SIZE_RELIGION_CIV_ICON);
+ if(textureSheet == nil or textureSheet == "") then
+ UI.DataError("Could not find icon for converted religion in PopulateReligionInstance: icon=\""..civIcon.."\", iconSize="..tostring(SIZE_RELIGION_CIV_ICON));
+ else
+ convertedInstance.CivIcon:SetTexture(textureOffsetX, textureOffsetY, textureSheet);
+ SetLeaderTooltip(convertedInstance, convertedCivID);
+ end
+ end
+
+ if #playerData.ConvertedCivs == 0 then
+ instance.ButtonBG:SetSizeY(SIZE_RELIGION_BG_HEIGHT + instance.CivsConvertedStack:GetSizeY());
+ else
+ instance.ButtonBG:SetSizeY(PADDING_RELIGION_BG_HEIGHT + instance.CivsConvertedStack:GetSizeY());
+ end
+
+ instance.CivsConverted:SetText(Locale.Lookup("LOC_WORLD_RANKINGS_RELIGION_CONVERT_SUMMARY", #playerData.ConvertedCivs .. "/" .. totalCivs, Game.GetReligion():GetName(playerData.ReligionType)));
+end
+
+function RealizeReligionStackSize()
+ local _, screenY:number = UIManager:GetScreenSizeVal();
+
+ if(m_ActiveHeader[DATA_FIELD_HEADER_EXPANDED]) then
+ local headerHeight:number = m_ActiveHeader[DATA_FIELD_HEADER_HEIGHT];
+ Controls.ReligionViewContents:SetOffsetY(OFFSET_VIEW_CONTENTS + headerHeight + PADDING_HEADER);
+ Controls.ReligionViewScrollbar:SetSizeY(screenY - (SIZE_STACK_DEFAULT + (headerHeight + PADDING_HEADER)));
+ else
+ Controls.ReligionViewContents:SetOffsetY(OFFSET_VIEW_CONTENTS);
+ Controls.ReligionViewScrollbar:SetSizeY(screenY - SIZE_STACK_DEFAULT);
+ end
+
+ RealizeStackAndScrollbar(Controls.ReligionViewStack, Controls.ReligionViewScrollbar, true);
+end
+
+-- ===========================================================================
+-- Called when Generic (custom victory type) tab is selected (or when screen re-opens if selected)
+-- ===========================================================================
+function ViewGeneric(victoryType:string)
+ ResetState(function() ViewGeneric(victoryType); end);
+ Controls.GenericView:SetHide(false);
+
+ ChangeActiveHeader("GENERIC", m_GenericHeaderIM, Controls.GenericViewHeader);
+
+ local victoryInfo:table = GameInfo.Victories[victoryType];
+ PopulateGenericHeader(RealizeGenericStackSize, victoryInfo.Name, nil, victoryInfo.Description, ICON_GENERIC);
+
+ local genericData:table = GatherGenericData();
+
+ m_GenericIM:ResetInstances();
+ m_GenericTeamIM:ResetInstances();
+
+ for i, teamData in ipairs(genericData) do
+ if #teamData.PlayerData > 1 then
+ PopulateGenericTeamInstance(m_GenericTeamIM:GetInstance(), teamData, victoryType);
+ else
+ PopulateGenericInstance(m_GenericIM:GetInstance(), teamData.PlayerData[1], victoryType, true);
+ end
+ end
+
+ RealizeGenericStackSize();
+end
+
+function GatherGenericData()
+ local data:table = {};
+
+ for teamID, team in pairs(Teams) do
+ if teamID >= 0 then
+ local teamData:table = { TeamID = teamID, PlayerData = {} };
+
+ -- Add players
+ for i, playerID in ipairs(team) do
+ if IsAliveAndMajor(playerID) then
+ local pPlayer:table = Players[playerID];
+ local playerData:table = { PlayerID = playerID };
+
+ table.insert(teamData.PlayerData, playerData);
+ end
+ end
+
+ -- Only add teams with at least one living, major player
+ if #teamData.PlayerData > 0 then
+ table.insert(data, teamData);
+ end
+ end
+ end
+
+ return data;
+end
+
+function PopulateGenericTeamInstance(instance:table, teamData:table, victoryType:string)
+ PopulateTeamInstanceShared(instance, teamData.TeamID);
+
+ -- Add team members to player stack
+ if instance.PlayerStackIM == nil then
+ instance.PlayerStackIM = InstanceManager:new("GenericInstance", "ButtonBG", instance.PlayerInstanceStack);
+ end
+
+ instance.PlayerStackIM:ResetInstances();
+
+ for i, playerData in ipairs(teamData.PlayerData) do
+ PopulateGenericInstance(instance.PlayerStackIM:GetInstance(), playerData, victoryType, false);
+ end
+
+ local requirementSetID:number = Game.GetVictoryRequirements(teamData.TeamID, victoryType);
+ if requirementSetID ~= nil and requirementSetID ~= -1 then
+
+ local detailsText:string = "";
+ local innerRequirements:table = GameEffects.GetRequirementSetInnerRequirements(requirementSetID);
+
+ for _, requirementID in ipairs(innerRequirements) do
+
+ if detailsText ~= "" then
+ detailsText = detailsText .. "[NEWLINE]";
+ end
+
+ local requirementKey:string = GameEffects.GetRequirementTextKey(requirementID, REQUIREMENT_CONTEXT);
+ local requirementText:string = GameEffects.GetRequirementText(requirementID, requirementKey);
+
+ if requirementText ~= nil then
+ detailsText = detailsText .. requirementText;
+ else
+ local requirementState:string = GameEffects.GetRequirementState(requirementID);
+ local requirementDetails:table = GameEffects.GetRequirementDefinition(requirementID);
+ if requirementState == "Met" or requirementState == "AlwaysMet" then
+ detailsText = detailsText .. "[ICON_CheckmarkBlue] ";
+ else
+ detailsText = detailsText .. "[ICON_Bolt]";
+ end
+ detailsText = detailsText .. requirementDetails.ID;
+ end
+ end
+ instance.Details:SetText(detailsText);
+ else
+ instance.Details:LocalizeAndSetText("LOC_OPTIONS_DISABLED");
+ end
+
+ local itemSize:number = instance.Details:GetSizeY() + PADDING_GENERIC_ITEM_BG;
+ if itemSize < SIZE_GENERIC_ITEM_MIN_Y then
+ itemSize = SIZE_GENERIC_ITEM_MIN_Y;
+ end
+
+ instance.ButtonFrame:SetSizeY(itemSize);
+end
+
+function PopulateGenericInstance(instance:table, playerData:table, victoryType:string, showTeamDetails:boolean )
+ local civName, civIcon:string = GetCivNameAndIcon(playerData.PlayerID, true);
+
+ local textureOffsetX:number, textureOffsetY:number, textureSheet:string = IconManager:FindIconAtlas(civIcon, SIZE_CIV_ICON);
+ if(textureSheet == nil or textureSheet == "") then
+ UI.DataError("Could not find icon in PopulateViewAncientRivalsInstance: icon=\""..civIcon.."\", iconSize="..tostring(SIZE_CIV_ICON));
+ else
+ instance.CivIcon:SetTexture(textureOffsetX, textureOffsetY, textureSheet);
+ SetLeaderTooltip(instance, playerData.PlayerID);
+ end
+
+ ColorCivIcon(instance, playerData.PlayerID);
+ instance.CivName:SetText(civName);
+ instance.LocalPlayer:SetHide(playerData.PlayerID ~= m_LocalPlayerID);
+
+ if showTeamDetails then
+ local requirementSetID:number = Game.GetVictoryRequirements(Players[playerData.PlayerID]:GetTeam(), victoryType);
+ if requirementSetID ~= nil and requirementSetID ~= -1 then
+
+ local detailsText:string = "";
+ local innerRequirements:table = GameEffects.GetRequirementSetInnerRequirements(requirementSetID);
+
+ for _, requirementID in ipairs(innerRequirements) do
+
+ if detailsText ~= "" then
+ detailsText = detailsText .. "[NEWLINE]";
+ end
+
+ local requirementKey:string = GameEffects.GetRequirementTextKey(requirementID, REQUIREMENT_CONTEXT);
+ local requirementText:string = GameEffects.GetRequirementText(requirementID, requirementKey);
+
+ if requirementText ~= nil then
+ detailsText = detailsText .. requirementText;
+ else
+ local requirementState:string = GameEffects.GetRequirementState(requirementID);
+ local requirementDetails:table = GameEffects.GetRequirementDefinition(requirementID);
+ if requirementState == "Met" or requirementState == "AlwaysMet" then
+ detailsText = detailsText .. "[ICON_CheckmarkBlue] ";
+ else
+ detailsText = detailsText .. "[ICON_Bolt]";
+ end
+ detailsText = detailsText .. requirementDetails.ID;
+ end
+ end
+ instance.Details:SetText(detailsText);
+ else
+ instance.Details:LocalizeAndSetText("LOC_OPTIONS_DISABLED");
+ end
+ else
+ instance.Details:SetText("");
+ end
+
+ local itemSize:number = instance.Details:GetSizeY() + PADDING_GENERIC_ITEM_BG;
+ if itemSize < SIZE_GENERIC_ITEM_MIN_Y then
+ itemSize = SIZE_GENERIC_ITEM_MIN_Y;
+ end
+
+ instance.ButtonBG:SetSizeY(itemSize);
+end
+
+function RealizeGenericStackSize()
+ local _, screenY:number = UIManager:GetScreenSizeVal();
+
+ if(m_ActiveHeader[DATA_FIELD_HEADER_EXPANDED]) then
+ local headerHeight:number = m_ActiveHeader[DATA_FIELD_HEADER_HEIGHT];
+ Controls.GenericViewContents:SetOffsetY(OFFSET_VIEW_CONTENTS + headerHeight + PADDING_HEADER);
+ Controls.GenericViewScrollbar:SetSizeY(screenY - (SIZE_STACK_DEFAULT + (headerHeight + PADDING_HEADER)));
+ else
+ Controls.GenericViewContents:SetOffsetY(OFFSET_VIEW_CONTENTS);
+ Controls.GenericViewScrollbar:SetSizeY(screenY - SIZE_STACK_DEFAULT);
+ end
+
+ RealizeStackAndScrollbar(Controls.GenericViewStack, Controls.GenericViewScrollbar, true);
+end
+
+-- ===========================================================================
+-- Logic that governs extra tabs
+-- ===========================================================================
+function ToggleExtraTabs()
+ local shouldHide:boolean = not Controls.ExtraTabs:IsHidden();
+ Controls.ExtraTabs:SetHide(shouldHide);
+ Controls.ExpandExtraTabs:SetSelected(not shouldHide);
+end
+
+function CloseExtraTabs()
+ Controls.ExtraTabs:SetHide(true);
+ Controls.ExpandExtraTabs:SetSelected(false);
+ for _,tabInst in pairs(m_ExtraTabs) do
+ tabInst.Button:SetSelected(false);
+ end
+end
+
+-- ===========================================================================
+-- Update player data and refresh the display state
+-- ===========================================================================
+function UpdatePlayerData()
+ if (Game.GetLocalPlayer() ~= -1) then
+ m_LocalPlayer = Players[Game.GetLocalPlayer()];
+ m_LocalPlayerID = m_LocalPlayer:GetID();
+ else
+ m_LocalPlayer = nil;
+ m_LocalPlayerID = -1;
+ end
+end
+function UpdateData()
+ UpdatePlayerData();
+ if(m_LocalPlayer ~= nil and m_ActiveViewUpdate ~= nil) then
+ m_ActiveViewUpdate();
+ end
+end
+
+-- ===========================================================================
+-- SCREEN EVENTS
+-- ===========================================================================
+function Open()
+ -- dont show panel if there is no local player
+ local localPlayerID = Game.GetLocalPlayer();
+ if (localPlayerID == -1) then
+ return
+ end
+
+ UpdateData();
+ m_AnimSupport.Show();
+ UI.PlaySound("CityStates_Panel_Open");
+ -- Ensure we're the only partial screen currenly up
+ LuaEvents.WorldRankings_CloseCityStates();
+end
+
+-- ===========================================================================
+function Close()
+ m_AnimSupport.Hide();
+ if not ContextPtr:IsHidden() then
+ UI.PlaySound("CityStates_Panel_Close");
+ end
+ LuaEvents.WorldRankings_Close();
+
+ -- Don't reset lens if activating a modal lens. MinimapPanel will handle activating the proper lens.
+ if UI.GetInterfaceMode() ~= InterfaceModeTypes.VIEW_MODAL_LENS then
+ ResetTourismLens();
+ end
+end
+
+-- ===========================================================================
+function Toggle()
+ if(m_AnimSupport.IsVisible()) then
+ Close();
+ else
+ Open();
+ end
+end
+
+-- ===========================================================================
+-- HOT-RELOADING EVENTS
+-- ===========================================================================
+function OnInit(isReload:boolean)
+ if isReload then
+ LuaEvents.GameDebug_GetValues(RELOAD_CACHE_ID);
+ end
+end
+function OnShutdown()
+ LuaEvents.GameDebug_AddValue(RELOAD_CACHE_ID, "isHidden", ContextPtr:IsHidden());
+ if(m_TabSupport ~= nil and m_TabSupport.selectedControl ~= nil) then
+ LuaEvents.GameDebug_AddValue(RELOAD_CACHE_ID, "selectedTabText", m_TabSupport.selectedControl:GetTextControl():GetText());
+ end
+ if(m_ActiveHeader ~= nil) then
+ LuaEvents.GameDebug_AddValue(RELOAD_CACHE_ID, "activeHeaderExpanded", m_ActiveHeader[DATA_FIELD_HEADER_EXPANDED]);
+ end
+end
+function OnGameDebugReturn(context:string, contextTable:table)
+ if context == RELOAD_CACHE_ID and contextTable["isHidden"] ~= nil and not contextTable["isHidden"] then
+ Open();
+ -- Select previously selected tab
+ local selectedTabText:string = contextTable["selectedTabText"];
+ for _, tab in pairs(m_TabSupport.tabControls) do
+ if tab:GetTextControl():GetText() == selectedTabText then
+ m_TabSupport.SelectTab(tab);
+ end
+ end
+
+ if(m_ActiveHeader ~= nil) then
+ m_ActiveHeader[DATA_FIELD_HEADER_EXPANDED] = contextTable["activeHeaderExpanded"];
+ if(m_ActiveHeader[DATA_FIELD_HEADER_EXPANDED]) then
+ OnExpandHeader(0, 0, m_ActiveHeader.ExpandHeaderButton);
+ else
+ OnContractHeader(0, 0, m_ActiveHeader.ContractHeaderButton);
+ end
+ end
+ end
+end
+
+-- ===========================================================================
+-- Hot-seat functionality
+-- ===========================================================================
+function OnLocalPlayerTurnEnd()
+ if(GameConfiguration.IsHotseat()) then
+ Close();
+ end
+end
+
+-- ===========================================================================
+-- Game Events
+-- ===========================================================================
+function OnCapitalCityChanged()
+ if(m_AnimSupport.IsVisible()) then
+ m_AnimSupport.Hide();
+ end
+end
+
+-- ===========================================================================
+-- Game Engine Event
+-- ===========================================================================
+function OnInterfaceModeChanged(eOldMode:number, eNewMode:number)
+ if m_AnimSupport.IsVisible() and eNewMode == InterfaceModeTypes.VIEW_MODAL_LENS then
+ Close();
+ end
+end
+
+-- ===========================================================================
+-- LUA Event
+-- Explicit close (from partial screen hooks), part of closing everything,
+-- ===========================================================================
+function OnCloseAllExcept( contextToStayOpen:string )
+ if contextToStayOpen == ContextPtr:GetID() then return; end
+ Close();
+end
+
+-- ===========================================================================
+-- INIT (Generic)
+-- ===========================================================================
+function Initialize()
+
+ -- Animation Controller
+ m_AnimSupport = CreateScreenAnimation(Controls.SlideAnim, Close);
+
+ -- Hot-Reload Events
+ ContextPtr:SetInitHandler(OnInit);
+ ContextPtr:SetShutdown(OnShutdown);
+ LuaEvents.GameDebug_Return.Add(OnGameDebugReturn);
+
+ -- UI Callbacks
+ ContextPtr:SetInputHandler(m_AnimSupport.OnInputHandler, true);
+
+ Controls.CloseButton:SetOffsetY(50); -- Move close button down to account for TabHeader
+ Controls.CloseButton:RegisterCallback(Mouse.eLClick, Close);
+ Controls.CloseButton:RegisterCallback( Mouse.eMouseEnter, function() UI.PlaySound("Main_Menu_Mouse_Over"); end);
+ Controls.ExpandExtraTabs:RegisterCallback(Mouse.eLClick, ToggleExtraTabs);
+ Controls.ScoreDetailsCheck:RegisterCallback(Mouse.eLClick, ToggleScoreDetails);
+ Controls.ScoreDetailsButton:RegisterCallback(Mouse.eLClick, ToggleScoreDetails);
+ Controls.ScoreDetailsButton:RegisterCallback( Mouse.eMouseEnter, function() UI.PlaySound("Main_Menu_Mouse_Over"); end);
+ Controls.Title:SetText(Locale.Lookup("LOC_WORLD_RANKINGS_TITLE"));
+ Controls.TabHeader:ChangeParent(Controls.Background); -- To make it render beneath the banner image
+
+ -- Game Events
+ Events.CapitalCityChanged.Add(OnCapitalCityChanged);
+ Events.InterfaceModeChanged.Add( OnInterfaceModeChanged );
+ Events.LocalPlayerTurnEnd.Add(OnLocalPlayerTurnEnd);
+ Events.SystemUpdateUI.Add(m_AnimSupport.OnUpdateUI);
+
+ -- Lua Events
+ LuaEvents.PartialScreenHooks_ToggleWorldRankings.Add(Toggle);
+ LuaEvents.PartialScreenHooks_OpenWorldRankings.Add(Open);
+ LuaEvents.PartialScreenHooks_CloseWorldRankings.Add(Close);
+ LuaEvents.PartialScreenHooks_CloseAllExcept.Add(OnCloseAllExcept);
+ LuaEvents.PartialScreenHooks_ViewScore.Add(ViewScore);
+ LuaEvents.PartialScreenHooks_ViewScience.Add(ViewScience);
+ LuaEvents.PartialScreenHooks_ViewCulture.Add(ViewCulture);
+ LuaEvents.PartialScreenHooks_ViewDomination.Add(ViewDomination);
+ LuaEvents.PartialScreenHooks_ViewReligion.Add(ViewReligion);
+
+ UpdatePlayerData();
+ PopulateTabs();
+end
+Initialize();
diff --git a/Assets/UI/toppanel.lua b/Assets/UI/toppanel.lua
index 8cacff9..e0964fe 100644
--- a/Assets/UI/toppanel.lua
+++ b/Assets/UI/toppanel.lua
@@ -532,6 +532,13 @@ function Initialize()
Controls.MenuButton:RegisterCallback( Mouse.eLClick, OnMenu );
Controls.MenuButton:RegisterCallback( Mouse.eMouseEnter, function() UI.PlaySound("Main_Menu_Mouse_Over"); end);
+ -- Open victorycondition for yield (P_Sanja)
+ Controls.ScienceBacking:RegisterCallback( Mouse.eLClick, function() LuaEvents.PartialScreenHooks_OpenWorldRankings(); LuaEvents.PartialScreenHooks_ViewScience(); end );
+ Controls.CultureBacking:RegisterCallback( Mouse.eLClick, function() LuaEvents.PartialScreenHooks_OpenWorldRankings(); LuaEvents.PartialScreenHooks_ViewCulture(); end );
+ Controls.FaithBacking:RegisterCallback( Mouse.eLClick, function() LuaEvents.PartialScreenHooks_OpenWorldRankings(); LuaEvents.PartialScreenHooks_ViewReligion(); end );
+ Controls.TourismBacking:RegisterCallback( Mouse.eLClick, function() LuaEvents.PartialScreenHooks_OpenWorldRankings(); LuaEvents.PartialScreenHooks_ViewCulture(); end );
+ Controls.GoldBacking:RegisterCallback( Mouse.eLClick, function() LuaEvents.PartialScreenHooks_OpenWorldRankings(); LuaEvents.PartialScreenHooks_ViewScore(); end );
+
-- Game Events
Events.AnarchyBegins.Add( OnRefreshYields );
Events.AnarchyEnds.Add( OnRefreshYields );
diff --git a/Assets/UI/toppanel.xml b/Assets/UI/toppanel.xml
index 1d03ef8..c42ba34 100644
--- a/Assets/UI/toppanel.xml
+++ b/Assets/UI/toppanel.xml
@@ -45,7 +45,7 @@
-
+
@@ -53,7 +53,7 @@
-
+
diff --git a/cqui.modinfo b/cqui.modinfo
index 1bb8c2f..800c0ba 100644
--- a/cqui.modinfo
+++ b/cqui.modinfo
@@ -165,6 +165,7 @@
Assets/UI/Panels/unitpanel.lua
Assets/UI/PartialScreens/citystates.lua
Assets/UI/PartialScreens/citystates.xml
+ Assets/UI/PartialScreens/WorldRankings.lua
Assets/UI/Popups/greatpeoplepopup.lua
Assets/UI/Popups/greatpeoplepopup.xml
Assets/UI/Popups/mappinlistpanel.lua
@@ -290,6 +291,7 @@
Assets/UI/Panels/unitpanel.lua
Assets/UI/PartialScreens/citystates.lua
Assets/UI/PartialScreens/citystates.xml
+ Assets/UI/PartialScreens/WorldRankings.lua
Assets/UI/Popups/greatpeoplepopup.lua
Assets/UI/Popups/greatpeoplepopup.xml
Assets/UI/Popups/mappinlistpanel.lua