";
+
+ if(Game.IsVictoryEnabled("VICTORY_TECHNOLOGY")) then
+ PopulateVictoryType("VICTORY_TECHNOLOGY", "" .. Locale.Lookup("LOC_WORLD_RANKINGS_SCIENCE_TAB").." ");
+ bShownAType = true;
+ end
+ if(Game.IsVictoryEnabled("VICTORY_CULTURE")) then
+ PopulateVictoryType("VICTORY_CULTURE", "" .. Locale.Lookup("LOC_WORLD_RANKINGS_CULTURE_TAB").." ");
+ bShownAType = true;
+ end
+ if(Game.IsVictoryEnabled("VICTORY_CONQUEST")) then
+ PopulateVictoryType("VICTORY_CONQUEST", "" .. Locale.Lookup("LOC_WORLD_RANKINGS_DOMINATION_TAB").." ");
+ bShownAType = true;
+ end
+ if(Game.IsVictoryEnabled("VICTORY_RELIGIOUS")) then
+ PopulateVictoryType("VICTORY_RELIGIOUS", "" .. Locale.Lookup("LOC_WORLD_RANKINGS_RELIGION_TAB").." ");
+ bShownAType = true;
+ end
+ if(Game.IsVictoryEnabled("VICTORY_DIPLOMATIC")) then
+ PopulateVictoryType("VICTORY_DIPLOMATIC", "" .. Locale.Lookup("LOC_DIPLOMATIC").." ");
+ bShownAType = true;
+ end
+
+ -- Add custom (modded) victory types
+ for row in GameInfo.Victories() do
+ local victoryType:string = row.VictoryType;
+ if IsCustomVictoryType(victoryType) and Game.IsVictoryEnabled(victoryType) and not bShownAType then
+ fullStr = fullStr .. Locale.Lookup("LOC_HUD_CITY_NOT_APPLICABLE");
+ bShownAType = true;
+ end
+ end
+
+ if not bShownAType then
+ fullStr = fullStr .. Locale.Lookup("LOC_HUD_CITY_NOT_APPLICABLE");
+ end
+
+ UI.SetARXTagContentByID("Content", fullStr);
+end
+
+-- ===========================================================================
+-- Draw the Gossip Log screen
+-- ===========================================================================
+function DrawGossipLog()
+ local strDate = Calendar.MakeYearStr(Game.GetCurrentGameTurn());
+ local iNumAdded:number = 0;
+ local iMaxAdded:number;
+ local playerConfig:table = PlayerConfigurations[Game.GetLocalPlayer()];
+ local name:string = Locale.Lookup(playerConfig:GetPlayerName());
+
+ if m_bIsPortrait then
+ iMaxAdded = 35;
+ else
+ iMaxAdded = 22;
+ end
+
+ fullStr = fullStr.."
"..name.." "..Locale.Lookup("LOC_DIPLOMACY_INTEL_GOSSIP_COLON").." ";
+
+ --Only show the gossip generated in the last 100 turns. Otherwise we can end up with a TON of gossip, and everything bogs down.
+ for iPlayer = 0, PlayerManager.GetWasEverAliveCount() - 1 do
+ if PlayerManager.IsAlive(iPlayer) then
+ local gossipManager = Game.GetGossipManager();
+ local iCurrentTurn = Game.GetCurrentGameTurn();
+ local earliestTurn = iCurrentTurn - 100;
+ local gossipStringTable = gossipManager:GetRecentVisibleGossipStrings(earliestTurn, m_LocalPlayerID, iPlayer);
+ for i, currTable:table in pairs(gossipStringTable) do
+
+ local gossipString = currTable[1];
+ local gossipTurn = currTable[2];
+
+ if (gossipString ~= nil) then
+ if iNumAdded < iMaxAdded then
+ fullStr = fullStr..gossipString.."";
+ iNumAdded = iNumAdded + 1;
+ end
+ else
+ break;
+ end
+ end
+ end
+ end
+
+ if iNumAdded == 0 then
+ fullStr = fullStr..Locale.Lookup("LOC_DIPLOMACY_GOSSIP_ITEM_NONE_THIS_TURN").."
";
+ end
+
+ UI.SetARXTagContentByID("Content", fullStr);
+end
+
+-- ===========================================================================
+-- Clear ARX if exiting to main menu
+-- ===========================================================================
+function OnExitToMain()
+ UI.SetARXTagContentByID("top5", " ");
+ UI.SetARXTagContentByID("victory", " ");
+ UI.SetARXTagContentByID("gossip", " ");
+ UI.SetARXTagContentByID("Content", " ");
+end
+
+-- ===========================================================================
+-- Refresh the ARX screen
+-- ===========================================================================
+function RefreshARX()
+ if UI.HasARX() then
+ local strDate = Calendar.MakeYearStr(Game.GetCurrentGameTurn());
+
+ m_bIsPortrait = UI.IsARXDisplayPortrait();
+
+ if (Game.GetLocalPlayer() ~= -1) then
+ m_LocalPlayer = Players[Game.GetLocalPlayer()];
+ m_LocalPlayerID = m_LocalPlayer:GetID();
+ end
+
+ -- fill in button texts (generating full button HTML here fails for an unknown reason, may have to use JavaScript to be fully dynamic)
+ UI.SetARXTagContentByID("top5", ""..Locale.Lookup("LOC_ARX_TOP_5").."");
+ UI.SetARXTagContentByID("victory", ""..Locale.Lookup("LOC_VICTORYSTATUS_PANEL_HEADER").."");
+ UI.SetARXTagContentByID("gossip", ""..Locale.Lookup("LOC_ARX_GOSSIP_LOG").."");
+
+ -- make buttons visible
+ UI.SetARXTagsPropertyByClass("button", "style.visibility", "visible");
+
+ -- header with civ name
+ local playerName;
+ if(m_LocalPlayerID and PlayerConfigurations[m_LocalPlayerID]) then
+ local bOnTeam = false;
+ local team = Teams[m_LocalPlayer:GetTeam()];
+ if(team ~= nil and #team ~= 1) then
+ bOnTeam = true;
+ end
+
+ if bOnTeam then
+ playerName = Locale.Lookup(PlayerConfigurations[m_LocalPlayerID]:GetPlayerName())..", "..Locale.Lookup("LOC_WORLD_RANKINGS_TEAM", m_LocalPlayer:GetTeam());
+ else
+ playerName = Locale.Lookup(PlayerConfigurations[m_LocalPlayerID]:GetPlayerName());
+ end
+ else
+ playerName = Locale.Lookup("LOC_MULTIPLAYER_UNKNOWN");
+ end
+
+ fullStr = "".. playerName .."";
+ -- and turn and date
+ fullStr = fullStr.." " .. Locale.Lookup("LOC_TOP_PANEL_CURRENT_TURN").." "..tostring(Game.GetCurrentGameTurn());
+
+ if m_bIsPortrait then
+ fullStr = fullStr..", "..strDate;
+ else
+ fullStr = fullStr..", "..strDate;
+ end
+
+ local eraName;
+ if(m_LocalPlayer) then
+ local eraIndex = m_LocalPlayer:GetEra() + 1;
+ local era = m_kEras[eraIndex];
+ if(era) then
+ eraName = Locale.Lookup("LOC_GAME_ERA_DESC", era.Name);
+ end
+ end
+
+ if(eraName == nil) then
+ eraName = Locale.Lookup("LOC_MULTIPLAYER_UNKNOWN");
+ end
+
+ fullStr = fullStr..", ".. eraName .."";
+
+ if m_ScreenMode == 0 then
+ DrawTop5();
+ end
+ if m_ScreenMode == 1 then
+ DrawVictoryProgress();
+ end
+ if m_ScreenMode == 2 then
+ DrawGossipLog();
+ end
+ end
+end
+
+-- ===========================================================================
+-- Handle turn change
+-- ===========================================================================
+function OnTurnBegin()
+ RefreshARX();
+end
+
+-- ===========================================================================
+-- Handle ARX taps
+-- ===========================================================================
+function OnARXTap(szButtonID:string)
+ if szButtonID == "top5" then
+ m_ScreenMode = 0;
+ end
+ if szButtonID == "victory" then
+ m_ScreenMode = 1;
+ end
+ if szButtonID == "gossip" then
+ m_ScreenMode = 2;
+ end
+
+ RefreshARX();
+end
+
+-- ===========================================================================
+-- Reset the hooks that are visible for hotseat
+-- ===========================================================================
+function OnLocalPlayerChanged()
+ RefreshARX();
+end
+
+-- ===========================================================================
+-- Update our scores when a city is captured
+-- ===========================================================================
+function OnCityOccupationChanged(player, cityID)
+ RefreshARX();
+end
+
+-- ===========================================================================
+function Initialize()
+
+ Events.LocalPlayerChanged.Add( OnLocalPlayerChanged );
+ Events.TurnBegin.Add( OnTurnBegin );
+ Events.ARXTap.Add( OnARXTap );
+ Events.ARXOrientationChanged.Add( RefreshARX );
+ Events.ExitToMainMenu.Add( OnExitToMain );
+ Events.CityOccupationChanged.Add( OnCityOccupationChanged );
+
+ -- build era table
+ m_kEras = {};
+ for row:table in GameInfo.Eras() do
+ table.insert(m_kEras, {
+ Name = row.Name,
+ ChronologyIndex = row.ChronologyIndex,
+ });
+ end
+ table.sort(m_kEras, function(a,b)
+ return a.ChronologyIndex < b.ChronologyIndex;
+ end);
+
+ OnTurnBegin();
+end
+Initialize();
diff --git a/Replacements/ActionPanel.xml b/Replacements/ActionPanel.xml
index 15718f3..0f0701a 100644
--- a/Replacements/ActionPanel.xml
+++ b/Replacements/ActionPanel.xml
@@ -2,14 +2,13 @@
-
-
+
-
-
-
-
+
+
+
+
@@ -82,11 +81,11 @@
-
+
-
-
+
+
@@ -102,8 +101,8 @@
-
-
+
+
@@ -234,7 +233,7 @@
-
+
@@ -245,7 +244,7 @@
-
+
diff --git a/Replacements/ActionPanel_Expansion2.lua b/Replacements/ActionPanel_Expansion2.lua
new file mode 100644
index 0000000..739534f
--- /dev/null
+++ b/Replacements/ActionPanel_Expansion2.lua
@@ -0,0 +1,38 @@
+-- ===========================================================================
+-- INCLUDES
+-- ===========================================================================
+include("ActionPanel_Expansion1.lua");
+
+XP1_AllowAutoEndTurn_Expansion = AllowAutoEndTurn_Expansion;
+XP1_LateInitialize = LateInitialize;
+XP1_OnTurnBegin = OnTurnBegin;
+local m_CongressIsInSession:boolean = false;
+
+local specialSessionLookString:string = Locale.Lookup("LOC_ACTION_PANEL_WORLD_CONGRESS_SPECIAL_SESSION");
+local specialSessionLookTooltip:string = Locale.Lookup("LOC_ACTION_PANEL_WORLD_CONGRESS_SPECIAL_SESSION_TOOLTIP");
+
+local congressBlockingString:string = Locale.Lookup("LOC_RESUME_CONGRESS");
+local congressBlockingTooltip:string = Locale.Lookup("LOC_RESUME_CONGRESS");
+
+g_kMessageInfo[EndTurnBlockingTypes.ENDTURN_BLOCKING_WORLD_CONGRESS_LOOK] = {Message = specialSessionLookString, ToolTip = specialSessionLookTooltip , Icon="ICON_NOTIFICATION_WORLD_CONGRESS" };
+g_kMessageInfo[EndTurnBlockingTypes.ENDTURN_BLOCKING_WORLD_CONGRESS_SESSION] = {Message = congressBlockingString, ToolTip = congressBlockingTooltip , Icon="ICON_NOTIFICATION_WORLD_CONGRESS" };
+
+function LateInitialize()
+ Events.LocalPlayerTurnBegin.Add(OnTurnBegin);
+ OnTurnBegin();
+ XP1_LateInitialize();
+end
+
+function OnTurnBegin()
+ local pWorldCongress:table = Game.GetWorldCongress();
+ m_CongressIsInSession = pWorldCongress:IsInSession();
+ XP1_OnTurnBegin();
+end
+
+function AllowAutoEndTurn_Expansion()
+ -- Disable AutoEndTurn while World Congress is in session.
+ if(m_CongressIsInSession) then
+ return false;
+ end
+ return true;
+end
\ No newline at end of file
diff --git a/Replacements/CityPanelOverview_Expansion2.lua b/Replacements/CityPanelOverview_Expansion2.lua
new file mode 100644
index 0000000..0715a17
--- /dev/null
+++ b/Replacements/CityPanelOverview_Expansion2.lua
@@ -0,0 +1,85 @@
+-- Copyright 2017-2018, Firaxis Games
+
+-- ===========================================================================
+-- Base File
+-- ===========================================================================
+include("CityPanelOverview_Expansion1");
+
+-- ===========================================================================
+-- Cached Base Functions
+-- ===========================================================================
+XP1_HideAll = HideAll;
+XP1_View = View;
+XP1_LateInitialize = LateInitialize;
+
+
+-- ===========================================================================
+-- MEMBERS
+-- ===========================================================================
+local m_PowerPanel :table = nil;
+local m_PowerButtonInstance :table = nil;
+local m_ToolTip :string = "LOC_HUD_CITY_POWER_TOOLTIP";
+
+
+-- ===========================================================================
+function HideAll()
+ XP1_HideAll();
+ if m_PowerButtonInstance then
+ m_PowerButtonInstance.Button:SetSelected(false);
+ m_PowerButtonInstance.Icon:SetColorByName("White");
+ if m_PowerPanel then
+ m_PowerPanel:SetHide(true);
+ end
+ end
+end
+
+-- ===========================================================================
+function View(data)
+ XP1_View(data);
+ if GetSelectedTabButton() == m_PowerButtonInstance.Button then
+ RefreshPowerPanel();
+ end
+end
+
+-- ===========================================================================
+function RefreshPowerPanel()
+ LuaEvents.CityPanelTabRefresh();
+end
+
+-- ===========================================================================
+function OnTogglePowerTab()
+ if m_PowerButtonInstance then
+ ToggleOverviewTab(m_PowerButtonInstance.Button);
+ end
+end
+
+-- ===========================================================================
+function OnSelectPowerTab()
+ HideAll();
+
+ -- Context has to be shown before CityPanelTabRefresh to ensure a proper Refresh
+ m_PowerPanel:SetHide(false);
+
+ m_PowerButtonInstance.Button:SetSelected(true);
+ m_PowerButtonInstance.Icon:SetColorByName("DarkBlue");
+ UI.PlaySound("UI_CityPanel_ButtonClick");
+ Controls.PanelDynamicTab:SetHide(false);
+
+ RefreshPowerPanel();
+end
+
+-- ===========================================================================
+function LateInitialize()
+ XP1_LateInitialize();
+
+ m_PowerPanel = ContextPtr:LoadNewContext("CityPanelPower", Controls.PanelDynamicTab);
+ m_PowerPanel:SetSizeX(Controls.PanelDynamicTab:GetSizeX());
+ m_PowerPanel:SetSizeY(Controls.PanelDynamicTab:GetSizeY());
+ LuaEvents.CityPanel_ToggleOverviewPower.Add( OnTogglePowerTab );
+
+ m_PowerButtonInstance = GetTabButtonInstance();
+ m_PowerButtonInstance.Icon:SetIcon("ICON_STAT_POWER");
+ m_PowerButtonInstance.Button:SetToolTipString(Locale.Lookup(m_ToolTip));
+
+ AddTab(m_PowerButtonInstance.Button, OnSelectPowerTab );
+end
diff --git a/Replacements/CityPanel_Expansion2.lua b/Replacements/CityPanel_Expansion2.lua
new file mode 100644
index 0000000..ee09baa
--- /dev/null
+++ b/Replacements/CityPanel_Expansion2.lua
@@ -0,0 +1,54 @@
+-- Copyright 2018-2019, Firaxis Games
+
+include("CityPanel_Expansion1");
+
+-- ===========================================================================
+-- Function overrides
+-- ===========================================================================
+function DisplayGrowthTile()
+ local bCanShowGrowth:boolean = true;
+ local iLocalPlayerID:number = Game.GetLocalPlayer();
+ local kResolutions:table = Game.GetWorldCongress():GetResolutions(iLocalPlayerID);
+
+ if kResolutions ~= nil then
+ for i, kResolutionData in pairs(kResolutions) do
+ if type(kResolutionData) == "table" then -- There's a "Stage" key in kResolutions
+ if kResolutionData.ChosenOption == "LOC_WORLD_CONGRESS_NO_CULTURE_BORDER_GROWTH_DESC" and tonumber(kResolutionData.ChosenThing) == iLocalPlayerID then
+ bCanShowGrowth = false;
+ end
+ end
+ end
+ end
+
+ if g_pCity ~= nil and bCanShowGrowth and HasCapability("CAPABILITY_CULTURE") then
+ local cityCulture:table = g_pCity:GetCulture();
+ if cityCulture ~= nil then
+ local newGrowthPlot:number = cityCulture:GetNextPlot();
+ if(newGrowthPlot ~= -1 and newGrowthPlot ~= g_growthPlotId) then
+ g_growthPlotId = newGrowthPlot;
+
+ local cost:number = cityCulture:GetNextPlotCultureCost();
+ local currentCulture:number = cityCulture:GetCurrentCulture();
+ local currentYield:number = cityCulture:GetCultureYield();
+ local currentGrowth:number = math.max(math.min(currentCulture / cost, 1.0), 0);
+ local nextTurnGrowth:number = math.max(math.min((currentCulture + currentYield) / cost, 1.0), 0);
+
+ UILens.SetLayerGrowthHex(m_PurchasePlot, Game.GetLocalPlayer(), g_growthPlotId, 1, "GrowthHexBG");
+ UILens.SetLayerGrowthHex(m_PurchasePlot, Game.GetLocalPlayer(), g_growthPlotId, nextTurnGrowth, "GrowthHexNext");
+ UILens.SetLayerGrowthHex(m_PurchasePlot, Game.GetLocalPlayer(), g_growthPlotId, currentGrowth, "GrowthHexCurrent");
+
+ local turnsRemaining:number = cityCulture:GetTurnsUntilExpansion();
+ Controls.TurnsLeftDescription:SetText(Locale.ToUpper(Locale.Lookup("LOC_HUD_CITY_TURNS_UNTIL_BORDER_GROWTH", turnsRemaining)));
+ Controls.TurnsLeftLabel:SetText(turnsRemaining);
+ Controls.GrowthHexStack:CalculateSize();
+ g_growthHexTextWidth = Controls.GrowthHexStack:GetSizeX();
+
+ Events.Camera_Updated.Add(OnCameraUpdate);
+ Events.CityMadePurchase.Add(OnCityMadePurchase);
+ Controls.GrowthHexAnchor:SetHide(false);
+ OnCameraUpdate();
+ end
+ end
+ end
+end
+
diff --git a/Replacements/CityStates.xml b/Replacements/CityStates.xml
index d623e9d..d8181d5 100644
--- a/Replacements/CityStates.xml
+++ b/Replacements/CityStates.xml
@@ -25,7 +25,7 @@
-
+
@@ -224,7 +224,7 @@
-
+
diff --git a/Replacements/CityStates_Expansion1.lua b/Replacements/CityStates_Expansion1.lua
index 8acf2b4..d2570d5 100644
--- a/Replacements/CityStates_Expansion1.lua
+++ b/Replacements/CityStates_Expansion1.lua
@@ -61,7 +61,7 @@ function AddCityStateRow( kCityState:table )
local tooltip = Locale.Lookup("LOC_CITY_STATE_PANEL_HAS_AMBASSADOR_TOOLTIP");
local localPlayerID:number = Game.GetLocalPlayer();
- local pLocalPlayerDiplomacy = Players[localPlayerID]:GetDiplomacy();
+ local pLocalPlayerDiplomacy:table = Players[localPlayerID]:GetDiplomacy();
for playerID, playerHasAmbassador in pairs(ambassadorData.Ambassadors) do
local playerConfig = PlayerConfigurations[playerID];
if (playerID == localPlayerID or pLocalPlayerDiplomacy:HasMet(playerID)) then
@@ -88,13 +88,12 @@ function AddInfluenceRow(cityStateID:number, playerID:number, influence:number,
local localPlayerID:number = Game.GetLocalPlayer();
local playerHasAmbassador:boolean = m_CityStateGovernors[cityStateID] and m_CityStateGovernors[cityStateID].Ambassadors[playerID] or false;
kItem.AmbassadorIcon:SetHide(not playerHasAmbassador);
- local pLocalPlayerDiplomacy = Players[localPlayerID]:GetDiplomacy();
+ local pLocalPlayerDiplomacy:table = Players[localPlayerID]:GetDiplomacy();
local playerName:string = Locale.Lookup("LOC_LOYALTY_PANEL_UNMET_CIV");
if (playerID == localPlayerID or pLocalPlayerDiplomacy:HasMet(playerID)) then
playerName = playerConfig:GetPlayerName();
end
kItem.AmbassadorIcon:SetToolTipString(Locale.Lookup("LOC_CITY_STATE_PANEL_CIV_AMBASSADOR_TOOLTIP", playerName));
-
return kItem;
end
\ No newline at end of file
diff --git a/Replacements/CityStates_Expansion2.lua b/Replacements/CityStates_Expansion2.lua
new file mode 100644
index 0000000..d894afe
--- /dev/null
+++ b/Replacements/CityStates_Expansion2.lua
@@ -0,0 +1,71 @@
+include("CityStates_Expansion1");
+
+-- ===========================================================================
+-- Variables
+-- ===========================================================================
+
+-- ===========================================================================
+-- CACHE BASE FUNCTIONS
+-- ===========================================================================
+BASE_GetSuzerainBonusText = GetSuzerainBonusText;
+
+-- ===========================================================================
+function GetSuzerainBonusText(playerID:number)
+ local leader :string = PlayerConfigurations[playerID]:GetLeaderTypeName();
+ local leaderInfo:table = GameInfo.Leaders[leader];
+ local player = Players[playerID];
+ if leaderInfo == nil then
+ UI.DataError("GetSuzerainBonusText, cannot determine the type of city state suzerain bonus for player #: "..tostring(playerID) );
+ return "UNKNOWN";
+ end
+
+ local text :string = "";
+
+ -- Unique Bonus
+ for leaderTraitPairInfo in GameInfo.LeaderTraits() do
+ if (leader ~= nil and leader == leaderTraitPairInfo.LeaderType) then
+ local traitInfo = GameInfo.Traits[leaderTraitPairInfo.TraitType];
+ if (traitInfo ~= nil) then
+ local name = PlayerConfigurations[playerID]:GetCivilizationShortDescription();
+ text = text .. "[COLOR:SuzerainDark]" .. Locale.Lookup("LOC_CITY_STATES_SUZERAIN_UNIQUE_BONUS", name) .. "[ENDCOLOR] ";
+ if (player ~= nil) then
+ if (player:GetInfluence():IsSuzerainUniqueBonusDisabled()) then
+ text = text .. " [COLOR:Civ6Red]" .. Locale.Lookup("LOC_CITY_STATE_PANEL_UNIQUE_SUZERAIN_BONUS_DISABLED") .. "[ENDCOLOR] ";
+ end
+ end
+ text = text .. Locale.Lookup(traitInfo.Description);
+ end
+ end
+ end
+
+ -- Diplomatic Bonus
+ text = text .. "[NEWLINE][NEWLINE]" .. Locale.Lookup("LOC_CITY_STATES_SUZERAIN_DIPLOMATIC_BONUS");
+
+ local comma_separator = Locale.Lookup("LOC_GRAMMAR_COMMA_SEPARATOR");
+
+ -- Resources Available
+ local resourceIcons :string = "";
+ if (player ~= nil) then
+ for resourceInfo in GameInfo.Resources() do
+ local resource = resourceInfo.Index;
+ -- Include exports and accumulated resources, so we see what another player is getting if suzerain
+ if (player:GetResources():HasResource(resource) or player:GetResources():HasExportedResource(resource) or player:GetResources():GetResourceAccumulationPerTurn(resource) > 0) then
+ local amount = player:GetResources():GetResourceAccumulationPerTurn(resource); -- Accumulated resources (strategics)
+ if (amount == 0) then
+ amount = player:GetResources():GetResourceAmount(resource) + player:GetResources():GetExportedResourceAmount(resource); -- "Access" resources (luxuries, bonuses)
+ end
+ if (resourceIcons ~= "") then
+ resourceIcons = resourceIcons .. comma_separator;
+ end
+ resourceIcons = resourceIcons .. amount .. " [ICON_" .. resourceInfo.ResourceType .. "] " .. Locale.Lookup(resourceInfo.Name);
+ end
+ end
+ end
+ if (resourceIcons ~= "") then
+ text = text .. " " .. resourceIcons;
+ else
+ text = text .. " " .. Locale.Lookup("LOC_CITY_STATES_SUZERAIN_NO_RESOURCES_AVAILABLE");
+ end
+
+ return text;
+end
\ No newline at end of file
diff --git a/Replacements/CitySupport.lua b/Replacements/CitySupport.lua
index 8d80dd6..c99a2de 100644
--- a/Replacements/CitySupport.lua
+++ b/Replacements/CitySupport.lua
@@ -228,7 +228,7 @@ function GetProductionInfoOfCity( pCity:table, productionHash:number )
local eMilitaryFormationType :number = pBuildQueue:GetCurrentProductionTypeModifier();
productionName = Locale.Lookup(unitDef.Name);
description = unitDef.Description;
- tooltip = ToolTipHelper.GetUnitToolTip(hash);
+ tooltip = ToolTipHelper.GetUnitToolTip(hash, eMilitaryFormationType, pBuildQueue);
progress = pBuildQueue:GetUnitProgress(unitDef.Index);
prodTurnsLeft = pBuildQueue:GetTurnsLeft(unitDef.UnitType, eMilitaryFormationType);
kIcons = { iconName, prefixOnlyIconName, eraOnlyIconName, fallbackIconName, "ICON_"..unitDef.UnitType.."_PORTRAIT"}
@@ -531,6 +531,7 @@ function GetCityData( pCity:table )
data.AmenitiesFromGovernors = pCityGrowth:GetAmenitiesFromGovernors();
data.AmenitiesFromDistricts = pCityGrowth:GetAmenitiesFromDistricts();
data.AmenitiesFromNaturalWonders = pCityGrowth:GetAmenitiesFromNaturalWonders();
+ data.AmenitiesFromTraits = pCityGrowth:GetAmenitiesFromTraits();
data.AmenityAdvice = pCity:GetAmenityAdvice();
data.CityWallHPPercent = (wallHitpoints-currentWallDamage) / wallHitpoints;
data.CityWallCurrentHP = wallHitpoints-currentWallDamage;
@@ -600,7 +601,7 @@ function GetCityData( pCity:table )
Name = GameInfo.Buildings[building.BuildingType].Name,
Citizens = kPlot:GetWorkerCount(),
isPillaged = pCityBuildings:IsPillaged(type),
- Maintenance = GameInfo.Buildings[building.BuildingType].Maintenance --Expense in gold
+ Maintenance = pCityBuildings:GetBuildingMaintenance(type),
});
end
end
diff --git a/Replacements/CivicsTree_Expansion2.lua b/Replacements/CivicsTree_Expansion2.lua
new file mode 100644
index 0000000..b5b5abd
--- /dev/null
+++ b/Replacements/CivicsTree_Expansion2.lua
@@ -0,0 +1,314 @@
+-- ===========================================================================
+-- CivicsTree Replacement
+-- Civilization VI, Firaxis Games
+-- ===========================================================================
+include("CivicsTree");
+
+-- ===========================================================================
+-- Add to base tables
+-- ===========================================================================
+local BASE_GetCurrentData = GetCurrentData;
+
+-- Add to item status table. Instead of enum use hash of "UNREVEALED"; special case.
+ITEM_STATUS["UNREVEALED"] = 0xB87BE593;
+STATUS_ART[ITEM_STATUS.UNREVEALED] = { Name="UNREVEALED", TextColor0=0xff202726, TextColor1=0x00000000, FillTexture="CivicsTree_GearButtonTile_Disabled.dds", BGU=0,BGV=(SIZE_NODE_Y*3), HideIcon=true, IsButton=false, BoltOn=false, IconBacking=PIC_METER_BACK };
+STATUS_ART_LARGE[ITEM_STATUS.UNREVEALED]= { Name="UNREVEALED", TextColor0=0xff202726, TextColor1=0x00000000, FillTexture="CivicsTree_GearButton2Tile_Disabled.dds", BGU=0,BGV=(SIZE_NODE_LARGE_Y*3),HideIcon=true, IsButton=false, BoltOn=false, IconBacking=PIC_METER_BACK };
+
+
+-- ===========================================================================
+-- OVERRIDE BASE FUNCTIONS
+-- ===========================================================================
+function PopulateItemData() -- Note that we are overriding this function without calling its base version. This version requires no parameters.
+
+ local kItemDefaults :table = {}; -- Table to return
+
+ function GetHash(t)
+ local r = GameInfo.Types[t];
+ if(r) then
+ return r.Hash;
+ else
+ return 0;
+ end
+ end
+
+ local tCivicModCache:table = TechAndCivicSupport_BuildCivicModifierCache();
+
+ local civicNodes:table = Game.GetCulture():GetActiveCivicNodes();
+ for _,civicNode in ipairs(civicNodes) do
+
+ local row:table = GameInfo.Civics[civicNode.CivicType];
+
+ local kEntry:table = {};
+ kEntry.Type = row.CivicType;
+ kEntry.Name = row.Name;
+ kEntry.BoostText = "";
+ kEntry.Column = -1;
+ kEntry.Cost = civicNode.Cost;
+ kEntry.Description = row.Description and Locale.Lookup( row.Description );
+ kEntry.EraType = row.EraType;
+ kEntry.Hash = GetHash(kEntry.Type);
+ kEntry.Index = civicNode.CivicType;
+ kEntry.IsBoostable = false;
+ kEntry.IsRevealed = false;
+ kEntry.Prereqs = {}; -- IDs for prerequisite item(s)
+ kEntry.UITreeRow = row.UITreeRow;
+ kEntry.Unlocks = {}; -- Each unlock has: unlockType, iconUnavail, iconAvail, tooltip
+
+ -- Only add if not debugging or in debug range.
+ if (table.count(debugExplicitList) == 0 and debugFilterEraMaxIndex ==-1 ) or
+ (table.count(debugExplicitList) == 0 and kEntry.Index < debugFilterEraMaxIndex) or
+ (table.count(debugExplicitList) ~= 0 and debugExplicitList[kEntry.Index] ~= nil) then
+
+ kEntry.ModifierList = tCivicModCache[kEntry.Type];
+
+ -- Boost?
+ for boostRow in GameInfo.Boosts() do
+ if boostRow.CivicType == kEntry.Type then
+ kEntry.BoostText = Locale.Lookup( boostRow.TriggerDescription );
+ kEntry.IsBoostable = true;
+ kEntry.BoostAmount = boostRow.Boost;
+ break;
+ end
+ end
+
+ if (table.count(civicNode.PrereqCivicTypes) > 0) then
+ for __,prereqCivicType in ipairs(civicNode.PrereqCivicTypes) do
+ local prereqRow:table = GameInfo.Civics[prereqCivicType];
+ if prereqRow ~= nil then
+ table.insert( kEntry.Prereqs, prereqRow.CivicType );
+ end
+ end
+ end
+ -- If no prereqs were found, set item to special tree start value
+ if table.count(kEntry.Prereqs) == 0 then
+ table.insert(kEntry.Prereqs, PREREQ_ID_TREE_START);
+ end
+
+ -- Warn if DB has an out of bounds entry.
+ if kEntry.UITreeRow < ROW_MIN or kEntry.UITreeRow > ROW_MAX then
+ UI.DataError("UITreeRow for '"..kEntry.Type.."' has an out of bound UITreeRow="..tostring(kEntry.UITreeRow).." MIN="..tostring(ROW_MIN).." MAX="..tostring(ROW_MAX));
+ end
+
+ AddCivicToEra( kEntry );
+
+ -- Save entry into master list.
+ kItemDefaults[kEntry.Type] = kEntry;
+ end
+ end
+
+ return kItemDefaults;
+end
+
+-- ===========================================================================
+-- Fill out live data from base game and then add IsRevealed to items.
+-- ===========================================================================
+function GetCurrentData( ePlayer:number )
+ local kData:table = BASE_GetCurrentData(ePlayer);
+
+ -- Loop through all items and add an IsRevealed field.
+ local pPlayerCultureManager:table = Players[ePlayer]:GetCulture();
+ if (pPlayerCultureManager ~= nil) then
+ for type,item in pairs(g_kItemDefaults) do
+ kData[DATA_FIELD_LIVEDATA][type]["IsRevealed"] = pPlayerCultureManager:IsCivicRevealed(item.Index);
+ end
+ end
+ return kData;
+end
+
+-- ===========================================================================
+-- Now its own function so Mods / Expansions can modify the nodes
+-- ===========================================================================
+function PopulateNode(uiNode, playerTechData)
+
+ local item :table = g_kItemDefaults[uiNode.Type]; -- static item data
+ local live :table = playerTechData[DATA_FIELD_LIVEDATA][uiNode.Type]; -- live (changing) data
+ local status :number = live.IsRevealed and live.Status or ITEM_STATUS.UNREVEALED;
+ local artInfo :table = (uiNode.IsLarge) and STATUS_ART_LARGE[status] or STATUS_ART[status];
+
+ if(status == ITEM_STATUS.RESEARCHED) then
+ for _,prereqId in pairs(item.Prereqs) do
+ if(prereqId ~= PREREQ_ID_TREE_START) then
+ local prereq :table = g_kItemDefaults[prereqId];
+ local previousRow :number = prereq.UITreeRow;
+ local previousColumn:number = g_kEras[prereq.EraType].PriorColumns;
+
+ for lineNum,line in pairs(g_uiConnectorSets[item.Type..","..prereqId]) do
+ if(lineNum == 1 or lineNum == 5) then
+ line:SetTexture("Controls_TreePathEW");
+ end
+ if( lineNum == 3) then
+ line:SetTexture("Controls_TreePathNS");
+ end
+
+ if(lineNum==2)then
+ if previousRow < item.UITreeRow then
+ line:SetTexture("Controls_TreePathSE");
+ else
+ line:SetTexture("Controls_TreePathNE");
+ end
+ end
+
+ if(lineNum==4)then
+ if previousRow < item.UITreeRow then
+ line:SetTexture("Controls_TreePathES");
+ else
+ line:SetTexture("Controls_TreePathEN");
+ end
+ end
+ end
+ end
+ end
+ end
+
+ uiNode.NodeName:SetColor( artInfo.TextColor0, 0 );
+ uiNode.NodeName:SetColor( artInfo.TextColor1, 1 );
+
+ uiNode.UnlockStack:SetHide( status==ITEM_STATUS.UNREVEALED ); -- Show/hide unlockables based on revealed status.
+
+ local techName :string = (status==ITEM_STATUS.UNREVEALED) and Locale.Lookup("LOC_CIVICS_TREE_UNREVEALED_CIVIC") or Locale.Lookup(item.Name);
+ if debugShowIDWithName then
+ uiNode.NodeName:SetText( tostring(item.Index).." ".. techName); -- Debug output
+ else
+ uiNode.NodeName:SetText( Locale.ToUpper( techName )); -- Normal output
+ end
+
+ if live.Turns > 0 then
+ uiNode.Turns:SetHide( false );
+ uiNode.Turns:SetColor( artInfo.TextColor0, 0 );
+ uiNode.Turns:SetColor( artInfo.TextColor1, 1 );
+ uiNode.Turns:SetText( Locale.Lookup("LOC_TECH_TREE_TURNS",live.Turns) );
+ else
+ uiNode.Turns:SetHide( true );
+ end
+
+ if item.IsBoostable and status ~= ITEM_STATUS.RESEARCHED and status ~= ITEM_STATUS.UNREVEALED then
+ uiNode.BoostIcon:SetHide( false );
+ uiNode.BoostText:SetHide( false );
+ uiNode.BoostText:SetColor( artInfo.TextColor0, 0 );
+ uiNode.BoostText:SetColor( artInfo.TextColor1, 1 );
+
+ local boostText:string;
+ if live.IsBoosted then
+ boostText = TXT_BOOSTED.." "..item.BoostText;
+ uiNode.BoostIcon:SetTexture( PIC_BOOST_ON );
+ uiNode.BoostMeter:SetHide( false );
+ uiNode.BoostedBack:SetHide( false );
+ else
+ boostText = TXT_TO_BOOST.." "..item.BoostText;
+ uiNode.BoostedBack:SetHide( true );
+ uiNode.BoostIcon:SetTexture( PIC_BOOST_OFF );
+ uiNode.BoostMeter:SetHide( false );
+ local boostAmount = (item.BoostAmount*.01) + (live.Progress/ live.Cost);
+ uiNode.BoostMeter:SetPercent( boostAmount );
+ end
+ TruncateStringWithTooltip(uiNode.BoostText, MAX_BEFORE_TRUNC_TO_BOOST, boostText);
+ else
+ uiNode.BoostIcon:SetHide( true );
+ uiNode.BoostText:SetHide( true );
+ uiNode.BoostedBack:SetHide( true );
+ uiNode.BoostMeter:SetHide( true );
+ end
+
+ if status == ITEM_STATUS.CURRENT then
+ uiNode.GearAnim:SetHide( false );
+ else
+ uiNode.GearAnim:SetHide( true );
+ end
+
+ if live.Progress > 0 then
+ uiNode.ProgressMeter:SetHide( false );
+ uiNode.ProgressMeter:SetPercent(live.Progress / live.Cost);
+ else
+ uiNode.ProgressMeter:SetHide( true );
+ end
+
+ -- Set art for icon area
+ -- Set art and tool tip for icon area
+ if status == ITEM_STATUS.UNREVEALED then
+ uiNode.NodeButton:SetToolTipString(Locale.Lookup("LOC_CIVICS_TREE_UNREVEALED_TOOLTIP"));
+ uiNode.Icon:SetIcon("ICON_TECH_UNREVEALED");
+ uiNode.IconBacking:SetHide(true);
+ uiNode.BoostMeter:SetColor(0x66ffffff);
+ uiNode.BoostIcon:SetColor(0x66000000);
+ else
+ uiNode.NodeButton:SetToolTipString(ToolTipHelper.GetToolTip(item.Type, Game.GetLocalPlayer()));
+
+ if(item.Type ~= nil) then
+ local iconName :string = DATA_ICON_PREFIX .. item.Type;
+ if (artInfo.Name == "BLOCKED" or artInfo.Name == "LARGEBLOCKED") then
+ uiNode.IconBacking:SetHide(true);
+ iconName = iconName .. "_FOW";
+ uiNode.BoostMeter:SetColor(0x66ffffff);
+ uiNode.BoostIcon:SetColor(0x66000000);
+ else
+ uiNode.IconBacking:SetHide(false);
+ iconName = iconName;
+ uiNode.BoostMeter:SetColor(0xffffffff);
+ uiNode.BoostIcon:SetColor(0xffffffff);
+ end
+ local textureOffsetX, textureOffsetY, textureSheet = IconManager:FindIconAtlas(iconName,42);
+ if (textureOffsetX ~= nil) then
+ uiNode.Icon:SetTexture( textureOffsetX, textureOffsetY, textureSheet );
+ end
+ end
+ end
+
+ if artInfo.IsButton then
+ uiNode.OtherStates:SetHide( true );
+ uiNode.NodeButton:SetTextureOffsetVal( artInfo.BGU, artInfo.BGV );
+ else
+ uiNode.OtherStates:SetHide( false );
+ uiNode.OtherStates:SetTextureOffsetVal( artInfo.BGU, artInfo.BGV );
+ end
+
+ if artInfo.FillTexture ~= nil then
+ uiNode.FillTexture:SetHide( false );
+ uiNode.FillTexture:SetTexture( artInfo.FillTexture );
+ else
+ uiNode.FillTexture:SetHide( true );
+ end
+
+ if artInfo.BoltOn then
+ uiNode.Bolt:SetTexture(PIC_BOLT_ON);
+ else
+ uiNode.Bolt:SetTexture(PIC_BOLT_OFF);
+ end
+
+ uiNode.IconBacking:SetTexture(artInfo.IconBacking);
+
+ -- Darken items not making it past filter.
+ local currentFilter:table = playerTechData[DATA_FIELD_UIOPTIONS].filter;
+ if currentFilter == nil or currentFilter.Func == nil or currentFilter.Func( item.Type ) then
+ uiNode.FilteredOut:SetHide( true );
+ else
+ uiNode.FilteredOut:SetHide( false );
+ end
+
+ -- Civilopedia: Only show if revealed civic; only wire up handlers if not in an on-rails tutorial.
+ function OpenPedia()
+ if live.IsRevealed then
+ LuaEvents.OpenCivilopedia(uiNode.Type);
+ end
+ end
+ if IsTutorialRunning()==false then
+ uiNode.NodeButton:RegisterCallback( Mouse.eRClick, OpenPedia);
+ uiNode.OtherStates:RegisterCallback( Mouse.eRClick,OpenPedia);
+ end
+
+ -- Show/Hide Recommended Icon
+ if live.IsRecommended and live.AdvisorType ~= nil then
+ uiNode.RecommendedIcon:SetIcon(live.AdvisorType);
+ uiNode.RecommendedIcon:SetHide(false);
+ else
+ uiNode.RecommendedIcon:SetHide(true);
+ end
+end
+
+
+-- ===========================================================================
+-- Can a tech be searched; true if revealed.
+-- ===========================================================================
+function IsSearchable(civicType)
+ local kData:table = GetLiveData();
+ return kData[civicType]["IsRevealed"];
+end
diff --git a/Replacements/DeclareWarPopup_Expansion2.lua b/Replacements/DeclareWarPopup_Expansion2.lua
new file mode 100644
index 0000000..f5f5602
--- /dev/null
+++ b/Replacements/DeclareWarPopup_Expansion2.lua
@@ -0,0 +1,61 @@
+--[[
+-- Created by Sam Batista on Aug 03 2017
+-- Copyright (c) Firaxis Games
+--]]
+-- ===========================================================================
+-- INCLUDE BASE FILE
+-- ===========================================================================
+include("DeclareWarPopup_Expansion1");
+
+BASE_OnShow = OnShow;
+
+-- ===========================================================================
+-- OVERRIDE BASE FUNCTIONS
+-- ===========================================================================
+function OnShow(eAttackingPlayer:number, kDefendingPlayers:table, eWarType:number, confirmCallbackFn)
+ BASE_OnShow(eAttackingPlayer, kDefendingPlayers, eWarType, confirmCallbackFn);
+
+ local pAttacker = Players[eAttackingPlayer];
+ local iWarmongerPoints = 0;
+ local bFoundMajorPowerDefender = false;
+ local eDefendingMinor = -1;
+ for i, eDefendingPlayer in ipairs(kDefendingPlayers) do
+ local kParams = {};
+ kParams.WarState = eWarType;
+ bSuccess, tResults = DiplomacyManager.TestAction(eFromPlayer, eDefendingPlayer, DiplomacyActionTypes.SET_WAR_STATE, kParams);
+
+ local tmp = pAttacker:GetDiplomacy():ComputeDOWWarmongerPoints(eDefendingPlayer, kParams.WarState);
+ iWarmongerPoints = math.max(tmp, iWarmongerPoints); -- Pick the worst penalty and go with it
+
+ if (Players[eDefendingPlayer]:IsMajor()) then
+ bFoundMajorPowerDefender = true;
+ else
+ eDefendingMinor = eDefendingPlayer;
+ end
+ end
+
+ local szString = "LOC_DIPLO_CHOICE_GENERATES_GRIEVANCES_INFO";
+ if (bFoundMajorPowerDefender == false) then
+ local pMinorPlayerInfluence:table = Players[eDefendingMinor]:GetInfluence();
+ if (pMinorPlayerInfluence:GetSuzerain() ~= eAttackingPlayer and pMinorPlayerInfluence:GetSuzerain() ~= -1) then
+ szString = "LOC_DIPLO_CHOICE_GENERATES_GRIEVANCES_INFO_SUZERAIN";
+ iWarmongerPoints = GlobalParameters.GRIEVANCES_SUZERAIN_CITY_STATE_DOW;
+ else
+ iWarmongerPoints = 0;
+
+ -- Some other power beside the declarer have envoys here?
+ local majorPlayers = PlayerManager.GetAliveMajors();
+ for _, player in ipairs(majorPlayers) do
+ if (player:GetID() ~= eAttackingPlayer and pMinorPlayerInfluence:GetTokensReceived(player:GetID()) > 0) then
+ szString = "LOC_DIPLO_CHOICE_GENERATES_GRIEVANCES_INFO_ENVOYS_PRESENT";
+ iWarmongerPoints = GlobalParameters.GRIEVANCES_HAVE_ENVOYS_CITY_STATE_DOW;
+ break;
+ end
+ end
+ end
+ end
+
+ g_ConsequenceItemIM:ResetInstances();
+ local consequenceItem = g_ConsequenceItemIM:GetInstance(Controls.WarmongerStack);
+ consequenceItem.Text:SetText(Locale.Lookup(szString, iWarmongerPoints));
+end
\ No newline at end of file
diff --git a/Replacements/DiplomacyActionView.xml b/Replacements/DiplomacyActionView.xml
new file mode 100644
index 0000000..69261e7
--- /dev/null
+++ b/Replacements/DiplomacyActionView.xml
@@ -0,0 +1,528 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ y
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Replacements/DiplomacyActionView_Expansion1.lua b/Replacements/DiplomacyActionView_Expansion1.lua
index f747647..e00178d 100644
--- a/Replacements/DiplomacyActionView_Expansion1.lua
+++ b/Replacements/DiplomacyActionView_Expansion1.lua
@@ -397,6 +397,7 @@ function AddIntelEmergency(tabContainer:table)
m_EmergencyTabContext:SetHide(false);
+
-- Create tab button
local tabButtonInstance:table = CreateTabButton();
tabButtonInstance.Button:RegisterCallback( Mouse.eLClick, function() ShowPanel(tabAnchor.Anchor); end );
diff --git a/Replacements/DiplomacyActionView_Expansion2.lua b/Replacements/DiplomacyActionView_Expansion2.lua
new file mode 100644
index 0000000..df388d3
--- /dev/null
+++ b/Replacements/DiplomacyActionView_Expansion2.lua
@@ -0,0 +1,302 @@
+-- Copyright 2018, Firaxis Games
+
+-- ===========================================================================
+-- INCLUDE XP1 Functionality
+-- ===========================================================================
+include("DiplomacyActionView_Expansion1.lua");
+
+
+-- ===========================================================================
+-- CACHE FUNCTIONS
+-- Do not make cache functions local so overriden functions can check these names.
+-- ===========================================================================
+BASE_Close = Close;
+BASE_LateInitialize = LateInitialize;
+BASE_OnShow = OnShow;
+XP1_PopulateIntelPanels = PopulateIntelPanels;
+
+
+-- ===========================================================================
+-- MEMBERS
+-- ===========================================================================
+local m_uiWorldCongressInfoContext :table = nil;
+
+
+-- ===========================================================================
+-- OVERRIDE BASE FUNCTIONS
+-- ===========================================================================
+function AddOverviewAgendas(overviewInstance:table)
+ GetIntelOverviewAgendas():ResetInstances();
+ local overviewAgendasInst:table = GetIntelOverviewAgendas():GetInstance(overviewInstance.IntelOverviewStack);
+
+ GetIntelOverviewAgendaEntries():ResetInstances();
+
+ if (PlayerConfigurations[ms_SelectedPlayerID]:IsHuman()) then
+ -- Humans don't have agendas, at least ones we can show
+ overviewAgendasInst.Top:SetHide(true);
+ else
+ overviewAgendasInst.Top:SetHide(false);
+ -- What Historical Agenda does the selected player have?
+ local leader:string = PlayerConfigurations[ms_SelectedPlayerID]:GetLeaderTypeName();
+
+ local localPlayerDiplomacy = ms_LocalPlayer:GetDiplomacy();
+ local iAccessLevel = localPlayerDiplomacy:GetVisibilityOn(ms_SelectedPlayerID);
+
+ -- What randomly assigned agendas does the selected player have?
+ -- Determine whether our Diplomatic Visibility allows us to see random agendas
+ local bRevealRandom = false;
+ for row in GameInfo.Visibilities() do
+ if (row.Index <= iAccessLevel and row.RevealAgendas == true) then
+ bRevealRandom = true;
+ end
+ end
+ local kAgendaTypes = {};
+ kAgendaTypes = ms_SelectedPlayer:GetAgendasAndVisibilities();
+ --GetAgendaTypes() returns ALL of my agendas, including the historical agenda.
+ --To retrieve only the randomly assigned agendas, delete the first entry from the table.
+ local numRandomAgendas = table.count(kAgendaTypes);
+ local numHiddenAgendas = 0;
+ local numRandomAgendas = 0;
+ for i, entry in ipairs(kAgendaTypes) do
+ if (entry.Visibility <= iAccessLevel) then
+ local randomAgenda = GetIntelOverviewAgendaEntries():GetInstance(overviewAgendasInst.OverviewAgendasStack);
+ randomAgenda.Text:LocalizeAndSetText( GameInfo.Agendas[entry.Agenda].Name );
+ randomAgenda.Text:LocalizeAndSetToolTip( GameInfo.Agendas[entry.Agenda].Description );
+ numRandomAgendas = numRandomAgendas + 1;
+ else
+ numHiddenAgendas = numHiddenAgendas + 1;
+ end
+ end
+ if ( numHiddenAgendas > 0 ) then
+ local hiddenAgenda = GetIntelOverviewAgendaEntries():GetInstance(overviewAgendasInst.OverviewAgendasStack);
+ hiddenAgenda.Text:LocalizeAndSetText("LOC_DIPLOMACY_HIDDEN_AGENDAS", numHiddenAgendas, numHiddenAgendas>1 );
+ if ( numHiddenAgendas > 1 ) then
+ hiddenAgenda.Text:LocalizeAndSetToolTip("LOC_DIPLOMACY_HIDDEN_AGENDAS_TT");
+ else
+ hiddenAgenda.Text:LocalizeAndSetToolTip("LOC_DIPLOMACY_HIDDEN_AGENDAS_TT_LATE");
+ end
+ elseif (numHiddenAgendas == 0) then
+ if (numRandomAgendas == 0) then
+ local noRandomAgendas = GetIntelOverviewAgendaEntries():GetInstance(overviewAgendasInst.OverviewAgendasStack);
+ noRandomAgendas.Text:LocalizeAndSetText("LOC_DIPLOMACY_RANDOM_AGENDA_NONE");
+ noRandomAgendas.Text:SetToolTipString(nil); -- disable tooltip for this one
+ end
+ end
+ end
+
+ return not overviewAgendasInst.Top:IsHidden();
+end
+
+-- ===========================================================================
+function PopulateStatementList( options: table, rootControl: table, isSubList: boolean )
+ local buttonIM:table;
+ local stackControl:table;
+ local selectionText :string = "[SIZE_16]"; -- Resetting the string size for the new button instance
+ if (isSubList) then
+ buttonIM = g_ActionListIM;
+ stackControl = rootControl.SubOptionStack;
+ else
+ buttonIM = g_SubActionListIM;
+ stackControl = rootControl.OptionStack;
+ end
+ buttonIM:ResetInstances();
+
+ for _, selection in ipairs(options) do
+ local instance :table = buttonIM:GetInstance(stackControl);
+ local selectionText :string = selectionText.. Locale.Lookup(selection.Text);
+ local callback :ifunction;
+ local tooltipString :string = nil;
+ if( selection.Key ~= nil) then
+ callback = function() OnSelectInitialDiplomacyStatement( selection.Key ) end;
+
+ local pActionDef = GameInfo.DiplomaticActions[selection.DiplomaticActionType];
+ instance.Button:SetToolTipString(GetStatementButtonTooltip(pActionDef));
+
+ -- If costs gold add text
+ local iCost = GetGoldCost(selection.Key);
+ if iCost > 0 then
+ local szGoldString = Locale.Lookup("LOC_DIPLO_CHOICE_GOLD_INFO", iCost);
+ selectionText = selectionText .. szGoldString;
+ end
+
+ local pDiploActionData:table = GameInfo.DiplomaticActions_XP2[selection.DiplomaticActionType];
+ if pDiploActionData ~= nil then
+ local favorCost = pDiploActionData.FavorCost;
+ if favorCost ~= nil then
+ selectionText = selectionText .. Locale.Lookup("LOC_DIPLO_CHOICE_FAVOR_INFO", favorCost);
+ end
+ end
+
+ -- If war statement add warmongering info
+ if (IsWarChoice(selection.Key))then
+ local eWarType = GetWarType(selection.Key);
+ local iWarmongerPoints = ms_LocalPlayer:GetDiplomacy():ComputeDOWWarmongerPoints(ms_SelectedPlayerID, eWarType);
+ local szWarmongerString = Locale.Lookup("LOC_DIPLO_CHOICE_GENERATES_GRIEVANCES_INFO", iWarmongerPoints);
+ selectionText = selectionText .. szWarmongerString;
+
+ -- Change callback to prompt first.
+ callback = function()
+ LuaEvents.DiplomacyActionView_ConfirmWarDialog(ms_LocalPlayerID, ms_SelectedPlayerID, eWarType);
+ end;
+ end
+
+ --If denounce statement change callback to prompt first.
+ if (selection.Key == "CHOICE_DENOUNCE")then
+ local szWarmongerString = Locale.Lookup("LOC_DIPLO_CHOICE_GENERATES_GRIEVANCES_INFO", GlobalParameters.GRIEVANCES_FOR_DENOUNCEMENT);
+ selectionText = selectionText .. szWarmongerString;
+ local denounceFn = function() OnSelectInitialDiplomacyStatement( selection.Key ); end;
+ callback = function()
+ local playerConfig = PlayerConfigurations[ms_SelectedPlayer:GetID()];
+ if (playerConfig ~= nil) then
+
+ selectedCivName = playerConfig:GetCivilizationShortDescription();
+ m_PopupDialog:Reset();
+ m_PopupDialog:AddText(Locale.Lookup("LOC_DENOUNCE_POPUP_BODY", selectedCivName));
+ m_PopupDialog:AddButton(Locale.Lookup("LOC_CANCEL"), nil);
+ m_PopupDialog:AddButton(Locale.Lookup("LOC_DIPLO_CHOICE_DENOUNCE_NO_GRIEVANCE"), denounceFn, nil, nil, "PopupButtonInstanceRed");
+ m_PopupDialog:Open();
+
+ end
+ end;
+ end
+
+ instance.ButtonText:SetText( selectionText );
+ if (selection.IsDisabled == nil or selection.IsDisabled == false) then
+ instance.Button:RegisterCallback(Mouse.eMouseEnter, function() UI.PlaySound("Main_Menu_Mouse_Over"); end);
+ instance.Button:RegisterCallback( Mouse.eLClick, callback );
+ instance.ButtonText:SetColor( COLOR_BUTTONTEXT_NORMAL );
+ instance.Button:SetDisabled( false );
+ else
+ instance.ButtonText:SetColor( COLOR_BUTTONTEXT_DISABLED );
+ instance.Button:SetDisabled( true );
+ if (selection.FailureReasons ~= nil) then
+ instance.Button:SetToolTipString(Locale.Lookup(selection.FailureReasons[1]));
+ end
+ end
+ instance.Button:SetDisabled(not g_bIsLocalPlayerTurn or selection.IsDisabled == true);
+ else
+ callback = selection.Callback;
+ instance.ButtonText:SetColor( COLOR_BUTTONTEXT_NORMAL );
+ instance.Button:SetDisabled(not g_bIsLocalPlayerTurn);
+ if ( selection.ToolTip ~= nil) then
+ tooltipString = Locale.Lookup(selection.ToolTip);
+ instance.Button:SetToolTipString(tooltipString);
+ else
+ instance.Button:SetToolTipString(nil); -- Clear any existing
+ end
+ end
+
+ local wasTruncated :boolean = TruncateString(instance.ButtonText, MAX_BEFORE_TRUNC_BUTTON_INST, selectionText);
+ if wasTruncated then
+ local finalTooltipString :string = selectionText;
+ if tooltipString ~= nil then
+ finalTooltipString = finalTooltipString .. "[NEWLINE]" .. tooltipString;
+ end
+ instance.Button:SetToolTipString( finalTooltipString );
+ end
+
+ -- Append tooltip string to the end of the tooltip if it exists in this selection
+ if selection.Tooltip then
+ local currentTooltipString = instance.Button:GetToolTipString();
+ instance.Button:SetToolTipString(currentTooltipString .. Locale.Lookup(selection.Tooltip));
+ end
+
+ instance.Button:RegisterCallback(Mouse.eMouseEnter, function() UI.PlaySound("Main_Menu_Mouse_Over"); end);
+ instance.Button:RegisterCallback( Mouse.eLClick, callback );
+ end
+ if (isSubList) then
+ local instance :table = buttonIM:GetInstance(stackControl);
+ selectionText = selectionText.. Locale.Lookup("LOC_CANCEL_BUTTON");
+ instance.ButtonText:SetText( selectionText );
+ instance.Button:SetToolTipString(nil);
+ instance.Button:SetDisabled(false);
+ instance.ButtonText:SetColor( COLOR_BUTTONTEXT_NORMAL );
+ instance.Button:RegisterCallback(Mouse.eMouseEnter, function() UI.PlaySound("Main_Menu_Mouse_Over"); end);
+ instance.Button:RegisterCallback( Mouse.eLClick, function() ShowOptionStack(false); end );
+ end
+ stackControl:CalculateSize();
+end
+
+-- ===========================================================================
+function PopulateIntelPanels( kTabContainer:table)
+ XP1_PopulateIntelPanels( kTabContainer );
+
+ AddWorldCongressInfoTab( kTabContainer );
+
+ -- Refresh contexts (if this isn't being called from an override.)
+ if XP2_PopulateIntelPanels == nil then
+ LuaEvents.DiploScene_RefreshTabs(GetSelectedPlayerID());
+ end
+end
+
+-- ===========================================================================
+function AddWorldCongressInfoTab( kTabContainer:table )
+
+ -- Create tab
+ local kTabAnchor :table = GetTabAnchor( kTabContainer );
+ if m_uiWorldCongressInfoContext == nil then
+ m_uiWorldCongressInfoContext = ContextPtr:LoadNewContext("DiplomacyActionView_WorldCongressTab", kTabAnchor.Anchor);
+ else
+ m_uiWorldCongressInfoContext:ChangeParent( kTabAnchor.Anchor );
+ end
+
+ -- Create tab button
+ local uiTabButton:table = CreateTabButton();
+ uiTabButton.Button:RegisterCallback( Mouse.eLClick, function() ShowPanel(kTabAnchor.Anchor); end );
+ uiTabButton.Button:SetToolTipString(Locale.Lookup("LOC_DIPLOACTION_WORLD_CONGRESS_TAB_TOOLTIP"));
+ uiTabButton.ButtonIcon:SetIcon("ICON_STAT_GRIEVANCE");
+
+ -- Cache references to the button instance and header text on the panel instance
+ kTabAnchor.Anchor.m_ButtonInstance = uiTabButton;
+ kTabAnchor.Anchor.m_HeaderText = Locale.ToUpper("LOC_DIPLOACTION_INTEL_REPORT_GRIEVANCES");
+end
+
+-- ===========================================================================
+function Close()
+ BASE_Close();
+ local pWorldCongress:table = Game.GetWorldCongress();
+ LuaEvents.DiplomacyActionView_HideCongress();
+end
+
+-- ===========================================================================
+function OnShow()
+ BASE_OnShow();
+ if Game.GetEras():GetCurrentEra() >= GlobalParameters.WORLD_CONGRESS_INITIAL_ERA then
+ Controls.TabBar:SetHide(false);
+ else
+ Controls.TabBar:SetHide(true);
+ end
+end
+
+-- ===========================================================================
+function OnTalkToLeader( playerID : number )
+ local pWorldCongress:table = Game.GetWorldCongress();
+ m_LiteMode = pWorldCongress:IsInSession();
+ OnOpenDiplomacyActionView( playerID );
+end
+
+-- ===========================================================================
+function LateInitialize()
+ BASE_LateInitialize();
+ LuaEvents.WorldCongress_OpenDiplomacyActionViewLite.Add(OnOpenDiplomacyActionViewLite);
+ LuaEvents.WorldCongress_OpenDiplomacyActionView.Add(OnOpenDiplomacyActionView);
+
+ local isCongressInSession:boolean = false;
+
+ Events.WorldCongressStage1.Add(function() isCongressInSession = true; end);
+ Events.WorldCongressStage2.Add(function() isCongressInSession = true; end);
+ Events.WorldCongressFinished.Add(function() isCongressInSession = false; end);
+
+ Controls.WCButton:RegisterCallback(Mouse.eLClick, function()
+ OnClose();
+ if not isCongressInSession then
+ LuaEvents.DiplomacyActionView_ShowCongressResults();
+ else
+ LuaEvents.DiplomacyActionView_ResumeCongress();
+ end
+ end);
+ Controls.LaunchBacking:SetSizeX(Controls.TabBar:GetSizeX() + 144);
+ Controls.LaunchBackingTile:SetSizeX(Controls.TabBar:GetSizeX() + 10);
+ Controls.LaunchBarDropShadow:SetSizeX(Controls.TabBar:GetSizeX());
+ ContextPtr:SetShowHandler( OnShow );
+end
\ No newline at end of file
diff --git a/Replacements/DiplomacyDealView.lua b/Replacements/DiplomacyDealView.lua
new file mode 100644
index 0000000..65441d5
--- /dev/null
+++ b/Replacements/DiplomacyDealView.lua
@@ -0,0 +1,2769 @@
+-- ===========================================================================
+-- Diplomacy Trade View Manager
+-- ===========================================================================
+include( "InstanceManager" );
+include( "Colors" );
+include( "Civ6Common" ); -- AutoSizeGridButton
+include( "SupportFunctions" );
+include( "PopupDialog" );
+include( "ToolTipHelper_PlayerYields" );
+include( "CivilizationIcon" );
+include( "GreatWorksSupport" );
+
+
+-- ===========================================================================
+-- Globals
+-- ===========================================================================
+g_LocalPlayer = nil;
+g_OtherPlayer = nil;
+g_AvailableGroups = {};
+g_IconOnlyIM = InstanceManager:new( "IconOnly", "SelectButton", Controls.IconOnlyContainer );
+g_IconAndTextIM = InstanceManager:new( "IconAndText", "SelectButton", Controls.IconAndTextContainer );
+g_ValueEditDealItemID = -1; -- The ID of the deal item that is being value edited.
+g_ValueEditDealItemControlTable = nil; -- The control table of the deal item that is being edited.
+
+-- These are initialized in CreateGroupTypes
+DealItemGroupTypes = nil;
+AvailableDealItemGroupTypes = nil;
+
+-- ===========================================================================
+-- VARIABLES
+-- ===========================================================================
+local ms_PlayerPanelIM :table = InstanceManager:new( "PlayerAvailablePanel", "Root" );
+local ms_LeftRightListIM :table = InstanceManager:new( "LeftRightList", "List", Controls.LeftRightListContainer );
+local ms_TopDownListIM :table = InstanceManager:new( "TopDownList", "List", Controls.TopDownListContainer );
+local ms_AgreementOptionIM :table = InstanceManager:new( "AgreementOptionInstance", "AgreementOptionButton", Controls.ValueEditStack );
+
+local OTHER_PLAYER = 0;
+local LOCAL_PLAYER = 1;
+
+ms_OtherPlayerID = -1;
+local ms_OtherPlayerIsHuman = false;
+
+ms_InitiatedByPlayerID = -1;
+
+local ms_bIsGift = false;
+ms_bIsDemand = false;
+local ms_bExiting = false;
+
+local ms_LastIncomingDealProposalAction = DealProposalAction.PENDING;
+
+local m_kPopupDialog :table; -- Will use custom "popup" since in leader mode the Popup stack is disabled.
+
+local ms_DealGroups = {};
+
+local ms_DealAgreementsGroup = {};
+
+local ms_DefaultOneTimeGoldAmount = 100;
+
+local ms_DefaultMultiTurnGoldAmount = 10;
+local ms_DefaultMultiTurnGoldDuration = 30;
+
+local ms_bForceUpdateOnCommit = false;
+
+local ms_bDontUpdateOnBack = false;
+
+local MAX_DEAL_ITEM_EDIT_HEIGHT = 300;
+
+-- ===========================================================================
+function SetIconToSize(iconControl, iconName, iconSize)
+ if iconSize == nil then
+ iconSize = 50;
+ end
+ local x, y, szIconName, iconSize = IconManager:FindIconAtlasNearestSize(iconName, iconSize, true);
+ iconControl:SetTexture(x, y, szIconName);
+ iconControl:SetSizeVal(iconSize, iconSize);
+end
+
+-- ===========================================================================
+function InitializeDealGroups()
+
+ for i = 1, table.count(AvailableDealItemGroupTypes), 1 do
+ g_AvailableGroups[i] = {};
+ end
+
+ for i = 1, table.count(DealItemGroupTypes), 1 do
+ ms_DealGroups[i] = {};
+ end
+
+end
+
+-- ===========================================================================
+function GetPlayerType(player : table)
+ if (player:GetID() == g_LocalPlayer:GetID()) then
+ return LOCAL_PLAYER;
+ end
+
+ return OTHER_PLAYER;
+end
+
+-- ===========================================================================
+function GetPlayerOfType(playerType : number)
+ if (playerType == LOCAL_PLAYER) then
+ return g_LocalPlayer;
+ end
+
+ return g_OtherPlayer;
+end
+
+-- ===========================================================================
+function GetOtherPlayer(player : table)
+ if (player ~= nil and player:GetID() == g_OtherPlayer:GetID()) then
+ return g_LocalPlayer;
+ end
+
+ return g_OtherPlayer;
+end
+
+-- ===========================================================================
+function SetDefaultLeaderDialogText()
+ if (ms_bIsDemand == true and ms_InitiatedByPlayerID == ms_OtherPlayerID) then
+ SetLeaderDialog("LOC_DIPLO_DEMAND_INTRO", "");
+ else
+ SetLeaderDialog("LOC_DIPLO_DEAL_INTRO", "");
+ end
+end
+
+-- ===========================================================================
+function ProposeWorkingDeal(bIsAutoPropose : boolean)
+ if (bIsAutoPropose == nil) then
+ bIsAutoPropose = false;
+ end
+
+ if (not DealManager.HasPendingDeal(g_LocalPlayer:GetID(), g_OtherPlayer:GetID())) then
+ if (ms_bIsDemand) then
+ DealManager.SendWorkingDeal(DealProposalAction.DEMANDED, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ else
+ if (bIsAutoPropose) then
+ DealManager.SendWorkingDeal(DealProposalAction.INSPECT, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ else
+ DealManager.SendWorkingDeal(DealProposalAction.PROPOSED, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ end
+ end
+ end
+end
+
+-- ===========================================================================
+function RequestEqualizeWorkingDeal()
+ if (not DealManager.HasPendingDeal(g_LocalPlayer:GetID(), g_OtherPlayer:GetID())) then
+ DealManager.SendWorkingDeal(DealProposalAction.EQUALIZE, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ end
+end
+
+-- ===========================================================================
+function DealIsEmpty()
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ if (pDeal == nil or pDeal:GetItemCount() == 0) then
+ return true;
+ end
+
+ return false;
+end
+
+-- ===========================================================================
+-- Update the proposed working deal. This is called as items are changed in the deal.
+-- It is primarily used to 'auto-propose' the deal when working with an AI.
+function UpdateProposedWorkingDeal()
+ if (ms_LastIncomingDealProposalAction ~= DealProposalAction.PENDING or IsAutoPropose()) then
+
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ if (pDeal == nil or pDeal:GetItemCount() == 0 or ms_bIsDemand) then
+ -- Is a demand or no items, restart
+ ms_LastIncomingDealProposalAction = DealProposalAction.PENDING;
+ UpdateDealStatus();
+ else
+ if (IsAutoPropose()) then
+ ProposeWorkingDeal(true);
+ end
+ end
+ end
+end
+
+-- ===========================================================================
+function UpdateOtherPlayerText(otherPlayerSays)
+ local bHide = true;
+ if (g_OtherPlayer ~= nil and otherPlayerSays ~= nil) then
+ local playerConfig = PlayerConfigurations[g_OtherPlayer:GetID()];
+ if (playerConfig ~= nil) then
+ -- leader icon
+ local otherPlayerController = CivilizationIcon:AttachInstance(Controls.OtherPlayerBubbleIcon);
+ otherPlayerController:UpdateIconFromPlayerID(g_OtherPlayer:GetID());
+
+ -- Set the leader name
+ local leaderDesc = playerConfig:GetLeaderName();
+ Controls.OtherPlayerBubbleName:SetText(Locale.ToUpper(Locale.Lookup("LOC_DIPLOMACY_DEAL_OTHER_PLAYER_SAYS", leaderDesc)));
+ end
+ end
+ -- When we get dialog for what the leaders say during a trade, we can add it here!
+end
+
+-- ===========================================================================
+function OnToggleCollapseGroup(iconList : table)
+ if (iconList.ListStack:IsHidden()) then
+ iconList.ListStack:SetHide(false);
+ else
+ iconList.ListStack:SetHide(true);
+ end
+
+ iconList.List:CalculateSize();
+ iconList.List:ReprocessAnchoring();
+end
+-- ===========================================================================
+function CreateHorizontalGroup(rootStack : table, title : string)
+ local iconList = ms_LeftRightListIM:GetInstance(rootStack);
+ if (title == nil or title == "") then
+ iconList.Title:SetHide(true); -- No title
+ else
+ iconList.TitleText:LocalizeAndSetText(title);
+ end
+ iconList.List:CalculateSize();
+ iconList.List:ReprocessAnchoring();
+
+ return iconList;
+end
+
+-- ===========================================================================
+function CreateVerticalGroup(rootStack : table, title : string)
+ local iconList = ms_TopDownListIM:GetInstance(rootStack);
+ if (title == nil or title == "") then
+ iconList.Title:SetHide(true); -- No title
+ else
+ iconList.TitleText:LocalizeAndSetText(title);
+ end
+ iconList.List:CalculateSize();
+ iconList.List:ReprocessAnchoring();
+
+ return iconList;
+end
+
+
+-- ===========================================================================
+function CreatePlayerAvailablePanel(playerType : number, rootControl : table)
+
+ --local playerPanel = ms_PlayerPanelIM:GetInstance(rootControl);
+
+ g_AvailableGroups[AvailableDealItemGroupTypes.GOLD][playerType] = g_AvailableGroups[AvailableDealItemGroupTypes.FAVOR][playerType];
+ g_AvailableGroups[AvailableDealItemGroupTypes.LUXURY_RESOURCES][playerType] = CreateHorizontalGroup(rootControl, "LOC_DIPLOMACY_DEAL_LUXURY_RESOURCES");
+ g_AvailableGroups[AvailableDealItemGroupTypes.STRATEGIC_RESOURCES][playerType] = CreateHorizontalGroup(rootControl, "LOC_DIPLOMACY_DEAL_STRATEGIC_RESOURCES");
+ g_AvailableGroups[AvailableDealItemGroupTypes.AGREEMENTS][playerType] = CreateVerticalGroup(rootControl, "LOC_DIPLOMACY_DEAL_AGREEMENTS");
+ g_AvailableGroups[AvailableDealItemGroupTypes.CITIES][playerType] = CreateVerticalGroup(rootControl, "LOC_DIPLOMACY_DEAL_CITIES");
+ g_AvailableGroups[AvailableDealItemGroupTypes.OTHER_PLAYERS][playerType] = CreateVerticalGroup(rootControl, "LOC_DIPLOMACY_DEAL_OTHER_PLAYERS");
+ g_AvailableGroups[AvailableDealItemGroupTypes.GREAT_WORKS][playerType] = CreateVerticalGroup(rootControl, "LOC_DIPLOMACY_DEAL_GREAT_WORKS");
+ g_AvailableGroups[AvailableDealItemGroupTypes.CAPTIVES][playerType] = CreateVerticalGroup(rootControl, "LOC_DIPLOMACY_DEAL_CAPTIVES");
+
+ rootControl:CalculateSize();
+ rootControl:ReprocessAnchoring();
+
+ return playerPanel;
+end
+
+-- ===========================================================================
+function CreatePlayerDealPanel(playerType : number, rootControl : table)
+--This creates the containers for the offer area...
+ --ms_DealGroups[DealItemGroupTypes.RESOURCES][playerType] = CreateHorizontalGroup(rootControl);
+ --ms_DealGroups[DealItemGroupTypes.AGREEMENTS][playerType] = CreateVerticalGroup(rootControl);
+ --**********************************************************************
+ -- Currently putting them all in the same control.
+ ms_DealGroups[DealItemGroupTypes.RESOURCES][playerType] = rootControl;
+ ms_DealGroups[DealItemGroupTypes.AGREEMENTS][playerType] = rootControl;
+ ms_DealGroups[DealItemGroupTypes.CITIES][playerType] = rootControl;
+ ms_DealGroups[DealItemGroupTypes.GREAT_WORKS][playerType] = rootControl;
+ ms_DealGroups[DealItemGroupTypes.CAPTIVES][playerType] = rootControl;
+
+end
+
+-- ===========================================================================
+function OnValuePulldownCommit(forType)
+
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ if (pDeal ~= nil) then
+
+ local pDealItem = pDeal:FindItemByID(g_ValueEditDealItemID);
+ if (pDealItem ~= nil) then
+ pDealItem:SetValueType( forType );
+
+ local valueName = pDealItem:GetValueTypeNameID();
+ if (g_ValueEditDealItemControlTable ~= nil) then
+ -- Keep the text on the icon, that is currently hidden, up to date too.
+ g_ValueEditDealItemControlTable.ValueText:LocalizeAndSetText(pDealItem:GetValueTypeNameID(valueName));
+ end
+
+ UpdateDealStatus();
+ UpdateProposedWorkingDeal();
+ end
+ end
+
+ Controls.ValueEditPopupBackground:SetHide(true);
+
+end
+
+-- ===========================================================================
+function SetValueText(icon, pDealItem)
+
+ if (icon.ValueText ~= nil) then
+ local valueName = pDealItem:GetValueTypeNameID();
+ if (valueName == nil) then
+ if (pDealItem:HasPossibleValues()) then
+ valueName = "LOC_DIPLOMACY_DEAL_CLICK_TO_CHANGE_DEAL_PARAMETER";
+ end
+ end
+ if (valueName ~= nil) then
+ icon.ValueText:LocalizeAndSetText(valueName);
+ icon.ValueText:SetHide(false);
+ else
+ icon.ValueText:SetHide(true);
+ end
+ end
+end
+
+-- ===========================================================================
+function CreatePanels()
+
+ -- Create the Other Player Panels
+ CreatePlayerAvailablePanel(OTHER_PLAYER, Controls.TheirInventoryStack);
+
+ -- Create the Local Player Panels
+ CreatePlayerAvailablePanel(LOCAL_PLAYER, Controls.MyInventoryStack);
+
+ CreatePlayerDealPanel(OTHER_PLAYER, Controls.TheirOfferStack);
+ CreatePlayerDealPanel(LOCAL_PLAYER, Controls.MyOfferStack);
+
+ Controls.EqualizeDeal:RegisterCallback( Mouse.eLClick, OnEqualizeDeal );
+ Controls.EqualizeDeal:RegisterCallback( Mouse.eMouseEnter, function() UI.PlaySound("Main_Menu_Mouse_Over"); end);
+ Controls.AcceptDeal:RegisterCallback( Mouse.eLClick, OnProposeOrAcceptDeal );
+ Controls.AcceptDeal:RegisterCallback( Mouse.eMouseEnter, function() UI.PlaySound("Main_Menu_Mouse_Over"); end);
+ Controls.DemandDeal:RegisterCallback( Mouse.eLClick, OnProposeOrAcceptDeal );
+ Controls.DemandDeal:RegisterCallback( Mouse.eMouseEnter, function() UI.PlaySound("Main_Menu_Mouse_Over"); end);
+ Controls.RefuseDeal:RegisterCallback(Mouse.eLClick, OnRefuseDeal);
+ Controls.RefuseDeal:RegisterCallback( Mouse.eMouseEnter, function() UI.PlaySound("Main_Menu_Mouse_Over"); end);
+ Controls.ResumeGame:RegisterCallback(Mouse.eLClick, OnResumeGame);
+ Controls.ResumeGame:RegisterCallback( Mouse.eMouseEnter, function() UI.PlaySound("Main_Menu_Mouse_Over"); end);
+
+end
+
+function CreateGroupTypes()
+ AvailableDealItemGroupTypes = {
+ GOLD = 1,
+ LUXURY_RESOURCES = 2,
+ STRATEGIC_RESOURCES = 3,
+ AGREEMENTS = 4,
+ CITIES = 5,
+ OTHER_PLAYERS = 6,
+ GREAT_WORKS = 7,
+ CAPTIVES = 8,
+ };
+
+ DealItemGroupTypes = {
+ GOLD = 1,
+ RESOURCES = 2,
+ AGREEMENTS = 3,
+ CITIES = 4,
+ GREAT_WORKS = 5,
+ CAPTIVES = 6
+ };
+end
+
+-- ===========================================================================
+-- Find the 'instance' table from the control
+function FindIconInstanceFromControl(rootControl : table)
+
+ if (rootControl ~= nil) then
+ local controlTable = g_IconOnlyIM:FindInstanceByControl(rootControl);
+ if (controlTable == nil) then
+ controlTable = g_IconAndTextIM:FindInstanceByControl(rootControl);
+ end
+
+ return controlTable;
+ end
+
+ return nil;
+end
+
+-- ===========================================================================
+-- Show or hide the "amount text" or the "Value Text" sub-control of the supplied control instance
+function SetHideValueText(controlTable : table, bHide : boolean)
+
+ if (controlTable ~= nil) then
+ if (controlTable.AmountText ~= nil) then
+ controlTable.AmountText:SetHide(bHide);
+ end
+ if (controlTable.ValueText ~= nil) then
+ controlTable.ValueText:SetHide(bHide);
+ end
+ end
+end
+
+-- ===========================================================================
+-- Detach the value edit overlay from anything it is attached to.
+function ClearValueEdit()
+
+ SetHideValueText(g_ValueEditDealItemControlTable, false);
+
+ g_ValueEditDealItemControlTable = nil
+ g_ValueEditDealItemID = -1;
+
+end
+
+-- ===========================================================================
+function UpdateDealStatus()
+ local bDealValid = false;
+ ClearValueEdit();
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ if (pDeal ~= nil) then
+ if (pDeal:GetItemCount() > 0) then
+ bDealValid = true;
+ end
+ end
+
+ if (bDealValid) then
+ if pDeal:Validate() ~= DealValidationResult.VALID then
+ bDealValid = false;
+ end
+ end
+
+ Controls.EqualizeDeal:SetHide(ms_bIsDemand);
+
+ -- Have we sent out a deal?
+ local bHasPendingDeal = DealManager.HasPendingDeal(g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+
+ if (not bHasPendingDeal and ms_LastIncomingDealProposalAction == DealProposalAction.PENDING) then
+ -- We have yet to send out a deal.
+ Controls.AcceptDeal:SetHide(true);
+ local showDemand = bDealValid and ms_bIsDemand;
+ Controls.DemandDeal:SetHide(not showDemand);
+ else
+ local cantAccept = (ms_LastIncomingDealProposalAction ~= DealProposalAction.ACCEPTED and ms_LastIncomingDealProposalAction ~= DealProposalAction.PROPOSED and ms_LastIncomingDealProposalAction ~= DealProposalAction.ADJUSTED) or not bDealValid or bHasPendingDeal;
+ Controls.AcceptDeal:SetHide(cantAccept);
+ if (ms_bIsDemand) then
+ if (g_LocalPlayer:GetID() == ms_InitiatedByPlayerID) then
+ -- Local human is making a demand
+ if (ms_LastIncomingDealProposalAction == DealProposalAction.ACCEPTED) then
+ Controls.DemandDeal:SetHide(cantAccept);
+ -- The other player has accepted the demand, but we must enact it.
+ -- We won't have the human need to press the accept button, just do it and exit.
+ OnProposeOrAcceptDeal();
+ return;
+ else
+ Controls.AcceptDeal:SetHide(true);
+ Controls.DemandDeal:SetHide(false);
+ end
+ else
+ Controls.DemandDeal:SetHide(true);
+ end
+ else
+ Controls.DemandDeal:SetHide(true);
+ end
+ end
+
+ UpdateProposalButtons(bDealValid);
+
+ ResizeDealAndButtons();
+end
+
+-- ===========================================================================
+function ResizeDealAndButtons()
+
+ -- Find the widest deal button text and size others to match
+ local refuseX, refuseY = AutoSizeGridButton(Controls.RefuseDeal,200,32,10,"1");
+ local equalizeX, equalizeY = AutoSizeGridButton(Controls.EqualizeDeal,200,32,10,"1");
+ local acceptX, acceptY = AutoSizeGridButton(Controls.AcceptDeal,200,41,10,"1");
+
+ local minX = refuseX;
+ if not Controls.EqualizeDeal:IsHidden() and minX < equalizeX then
+ minX = equalizeX;
+ end
+ if not Controls.AcceptDeal:IsHidden() and minX < acceptX then
+ minX = acceptX;
+ end
+
+ if Controls.RefuseDeal:GetSizeX() < minX then
+ Controls.RefuseDeal:SetSizeX(minX);
+ end
+ if Controls.EqualizeDeal:GetSizeX() < minX then
+ Controls.EqualizeDeal:SetSizeX(minX);
+ end
+ if Controls.AcceptDeal:GetSizeX() < minX then
+ Controls.AcceptDeal:SetSizeX(minX);
+ end
+
+ Controls.DealOptionsStack:CalculateSize();
+ Controls.DealOptionsStack:ReprocessAnchoring();
+
+ Controls.TheirOfferStack:CalculateSize();
+ Controls.TheirOfferBracket:DoAutoSize();
+ Controls.TheirOfferScroll:CalculateSize();
+
+ Controls.MyOfferStack:CalculateSize();
+ Controls.MyOfferBracket:DoAutoSize();
+ Controls.MyOfferScroll:CalculateSize();
+end
+
+-- ===========================================================================
+-- The Human has ask to have the deal equalized. Well, what the AI is
+-- willing to take.
+function OnEqualizeDeal()
+ ClearValueEdit();
+ RequestEqualizeWorkingDeal();
+end
+
+-- ===========================================================================
+-- Propose the deal, if this is the first time, or accept it, if the other player has
+-- accepted it.
+function OnProposeOrAcceptDeal()
+
+ ClearValueEdit();
+
+ if (ms_LastIncomingDealProposalAction == DealProposalAction.PENDING or
+ ms_LastIncomingDealProposalAction == DealProposalAction.REJECTED or
+ ms_LastIncomingDealProposalAction == DealProposalAction.EQUALIZE_FAILED) then
+ ProposeWorkingDeal();
+ UpdateDealStatus();
+ UI.PlaySound("Confirm_Bed_Positive");
+ else
+ if (ms_LastIncomingDealProposalAction == DealProposalAction.ACCEPTED or ms_LastIncomingDealProposalAction == DealProposalAction.PROPOSED or ms_LastIncomingDealProposalAction == DealProposalAction.ADJUSTED) then
+ -- Any adjustments?
+ if (DealManager.AreWorkingDealsEqual(g_LocalPlayer:GetID(), g_OtherPlayer:GetID())) then
+ -- Yes, we can accept
+ -- if deal will trigger war, prompt user before confirming deal
+ local sendDealAndContinue = function()
+ -- Send the deal. This will also send out a POSITIVE response statement
+ DealManager.SendWorkingDeal(DealProposalAction.ACCEPTED, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ OnContinue();
+ UI.PlaySound("Confirm_Bed_Positive");
+ end;
+
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ local pJointWarItem = pDeal:FindItemByType(DealItemTypes.AGREEMENTS, DealAgreementTypes.JOINT_WAR);
+ if DealAgreementTypes.JOINT_WAR and pJointWarItem then
+ local iWarType = pJointWarItem:GetParameterValue("WarType");
+
+ if (iWarType == nil) then iWarType = WarTypes.FORMAL_WAR; end
+
+ local targetPlayerID = pJointWarItem:GetValueType();
+ if (targetPlayerID >= 0) then
+ LuaEvents.DiplomacyActionView_ConfirmWarDialog(g_LocalPlayer:GetID(), targetPlayerID, iWarType, sendDealAndContinue);
+ else
+ UI.DataError("Invalid Player ID to declare Joint War to: " .. targetPlayerID);
+ end
+ else
+ local pThirdPartyWarItem = pDeal:FindItemByType(DealItemTypes.AGREEMENTS, DealAgreementTypes.THIRD_PARTY_WAR);
+ if (DealAgreementTypes.THIRD_PARTY_WAR and pThirdPartyWarItem) then
+ local iWarType = pThirdPartyWarItem:GetParameterValue("WarType");
+
+ if (iWarType == nil) then iWarType = WarTypes.FORMAL_WAR; end
+
+ local targetPlayerID = pThirdPartyWarItem:GetValueType();
+ if (targetPlayerID >= 0) then
+ LuaEvents.DiplomacyActionView_ConfirmWarDialog(g_LocalPlayer:GetID(), targetPlayerID, iWarType, sendDealAndContinue);
+ else
+ UI.DataError("Invalid Player ID to declare Third Party War to: " .. targetPlayerID);
+ end
+ else
+ sendDealAndContinue();
+ end
+ end
+ else
+ -- No, send an adjustment and stay in the deal view.
+ DealManager.SendWorkingDeal(DealProposalAction.ADJUSTED, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ UpdateDealStatus();
+ end
+ end
+ end
+end
+
+-- ===========================================================================
+function OnRefuseDeal(bForceClose)
+
+ if (bForceClose == nil) then
+ bForceClose = false;
+ end
+
+ local bHasPendingDeal = DealManager.HasPendingDeal(g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+
+ local sessionID = DiplomacyManager.FindOpenSessionID(Game.GetLocalPlayer(), g_OtherPlayer:GetID());
+ if (sessionID ~= nil) then
+ if (not ms_OtherPlayerIsHuman and not bHasPendingDeal) then
+ -- Refusing an AI's deal
+ ClearValueEdit();
+
+ if (ms_InitiatedByPlayerID == ms_OtherPlayerID) then
+ -- AI started this, so tell them that we don't want the deal
+ if (bForceClose == true) then
+ -- Forcing the close, usually because the turn timer expired
+ DealManager.SendWorkingDeal(DealProposalAction.REJECTED, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ DiplomacyManager.CloseSession(sessionID);
+ StartExitAnimation();
+ else
+ DiplomacyManager.AddResponse(sessionID, Game.GetLocalPlayer(), "NEGATIVE");
+ end
+ else
+ -- Else close the session
+ DiplomacyManager.CloseSession(sessionID);
+ StartExitAnimation();
+ end
+ else
+ if (ms_OtherPlayerIsHuman) then
+ if (bHasPendingDeal) then
+ -- Canceling the deal with the other player.
+ DealManager.SendWorkingDeal(DealProposalAction.CLOSED, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ else
+ if (ms_InitiatedByPlayerID ~= Game.GetLocalPlayer()) then
+ -- Refusing the deal with the other player.
+ DealManager.SendWorkingDeal(DealProposalAction.REJECTED, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ end
+ end
+
+ DiplomacyManager.CloseSession(sessionID);
+ StartExitAnimation();
+ end
+ end
+ else
+ -- We have lost our session!
+ if (not ContextPtr:IsHidden()) then
+ if (not ms_bExiting) then
+ OnResumeGame();
+ end
+ end
+ end
+
+end
+
+-- ===========================================================================
+function OnResumeGame()
+
+ -- Exiting back to wait for a response
+ ClearValueEdit();
+
+ local sessionID = DiplomacyManager.FindOpenSessionID(Game.GetLocalPlayer(), g_OtherPlayer:GetID());
+ if (sessionID ~= nil) then
+ DiplomacyManager.CloseSession(sessionID);
+ end
+
+ -- Start the exit animation, it will call OnContinue when complete
+ StartExitAnimation();
+end
+
+-- ===========================================================================
+function OnExitFadeComplete()
+ if(Controls.TradePanelFade:IsReversing()) then
+ Controls.TradePanelFade:SetSpeed(2);
+ Controls.TradePanelSlide:SetSpeed(2);
+
+ OnContinue();
+ end
+end
+Controls.TradePanelFade:RegisterEndCallback(OnExitFadeComplete);
+-- ===========================================================================
+-- Change the value number edit by a delta
+function OnValueAmountEditDelta(dealItemID:number, delta:number)
+
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ if (pDeal ~= nil) then
+
+ local pDealItem = pDeal:FindItemByID(dealItemID);
+ if (pDealItem ~= nil) then
+ local iNewAmount = tonumber(Controls.ValueAmountEditBox:GetText() or 0) + delta;
+ iNewAmount = clip(iNewAmount, 1, pDealItem:GetMaxAmount());
+ Controls.ValueAmountEditBox:SetText(tostring(iNewAmount));
+ end
+ end
+end
+
+-- ===========================================================================
+-- Detach the value edit if it is attached to the control
+function DetachValueEdit(itemID: number)
+
+ if (itemID == g_ValueEditDealItemID) then
+ ClearValueEdit();
+ end
+
+end
+
+-- ===========================================================================
+function IsItemValueEditable(itemType: number)
+ return itemType == DealItemTypes.GOLD or itemType == DealItemTypes.RESOURCES;
+end
+
+-- ===========================================================================
+function GetItemTypeIcon(pDealItem: table)
+ local itemType = pDealItem:GetType();
+ if (itemType == DealItemTypes.GOLD) then
+ return "ICON_YIELD_GOLD_5";
+ elseif (itemType == DealItemTypes.RESOURCES) then
+ local resourceType = pDealItem:GetValueType();
+ local resourceDesc = GameInfo.Resources[resourceType];
+ return "ICON_" .. resourceDesc.ResourceType;
+ end
+ return nil;
+end
+
+-- ===========================================================================
+-- Reattach the value edit overlay to the control set it is editing.
+function ReAttachValueEdit()
+
+ if (g_ValueEditDealItemControlTable ~= nil) then
+
+ SetHideValueText(g_ValueEditDealItemControlTable, true);
+
+ -- Display the number in the value edit field
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ if (pDeal ~= nil) then
+
+ local pDealItem = pDeal:FindItemByID(g_ValueEditDealItemID);
+ if (pDealItem ~= nil) then
+
+ local itemID = pDealItem:GetID();
+ local itemType = pDealItem:GetType();
+ if (IsItemValueEditable(itemType)) then
+ -- Hide/show everything for GOLD and RESOURCE options
+ ms_AgreementOptionIM:ResetInstances();
+ Controls.ValueEditIconGrid:SetHide(false);
+ Controls.ValueAmountEditBoxContainer:SetHide(false);
+
+ local iDuration = pDealItem:GetDuration();
+
+ Controls.ValueEditHeaderLabel:SetText(Locale.Lookup("LOC_DIPLOMACY_DEAL_HOW_MANY"));
+
+ if (iDuration == 0) then
+ ---- One time
+ Controls.ValueEditValueText:SetHide(true);
+ else
+ ---- Multi-turn
+ Controls.ValueEditValueText:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_FOR_TURNS", iDuration);
+ Controls.ValueEditValueText:SetHide(false);
+ end
+
+ SetIconToSize(Controls.ValueEditIcon, GetItemTypeIcon(pDealItem));
+
+ Controls.ValueEditAmountText:SetText(tostring(pDealItem:GetAmount()));
+ Controls.ValueEditAmountText:SetHide(false);
+
+ Controls.ValueAmountEditBox:SetText(tostring(pDealItem:GetAmount()));
+ Controls.ValueEditButton:RegisterCallback( Mouse.eLClick, function() OnValueEditButton(itemID); end );
+ Controls.ValueAmountEditLeftButton:RegisterCallback( Mouse.eLClick, function() OnValueAmountEditDelta(itemID, -1); end );
+ Controls.ValueAmountEditRightButton:RegisterCallback( Mouse.eLClick, function() OnValueAmountEditDelta(itemID, 1); end );
+ elseif (itemType == DealItemTypes.AGREEMENTS) then
+ local subType = pDealItem:GetSubType();
+ local iDuration = pDealItem:GetDuration();
+
+ ShowAgreementOptionPopup(subType, iDuration, pDealItem:GetFromPlayerID());
+ else
+ -- The value of the item cannot be adjusted so don't show a popup
+ return;
+ end
+ end
+ end
+
+ Controls.ValueEditIconGrid:DoAutoSize();
+
+ ResizeValueEditScrollPanel();
+
+ Controls.ValueEditPopup:DoAutoSize();
+ Controls.ValueEditPopupBackground:SetHide(false);
+ end
+
+end
+
+-- ===========================================================================
+-- Attach the value edit overlay to a control set.
+function AttachValueEdit(rootControl : table, dealItemID : number)
+
+ ClearValueEdit();
+
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ if (pDeal ~= nil) then
+
+ local pDealItem = pDeal:FindItemByID(dealItemID);
+ if (pDealItem ~= nil) then
+ -- Do we have something to edit?
+ if (pDealItem:HasPossibleValues() or pDealItem:HasPossibleAmounts()) then
+ -- Yes
+ g_ValueEditDealItemControlTable = FindIconInstanceFromControl(rootControl);
+ g_ValueEditDealItemID = dealItemID;
+
+ ReAttachValueEdit();
+ end
+ end
+ end
+
+end
+
+-- ===========================================================================
+-- Update the deal panel for a player
+function UpdateDealPanel(player)
+
+ -- If we modify the deal without sending it to the AI then reset the status to PENDING
+ ms_LastIncomingDealProposalAction = DealProposalAction.PENDING;
+
+ UpdateDealStatus();
+
+ PopulatePlayerDealPanel(Controls.TheirOfferStack, g_OtherPlayer);
+ PopulatePlayerDealPanel(Controls.MyOfferStack, g_LocalPlayer);
+
+ ResizeDealAndButtons();
+
+end
+
+-- ===========================================================================
+function OnClickAvailableOneTimeGold(player, iAddAmount : number)
+
+ if (ms_bIsDemand == true and ms_InitiatedByPlayerID == ms_OtherPlayerID) then
+ -- Can't modifiy demand that is not ours
+ return;
+ end
+
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ if (pDeal ~= nil) then
+
+ local pPlayerTreasury = player:GetTreasury();
+ local bFound = false;
+
+ -- Already there?
+ local dealItems = pDeal:FindItemsByType(DealItemTypes.GOLD, DealItemSubTypes.NONE, player:GetID());
+ local pDealItem;
+ if (dealItems ~= nil) then
+ for i, pDealItem in ipairs(dealItems) do
+ if (pDealItem:GetDuration() == 0) then
+ -- Already have a one time gold. Up the amount
+ iAddAmount = pDealItem:GetAmount() + iAddAmount;
+ iAddAmount = clip(iAddAmount, nil, pDealItem:GetMaxAmount());
+ if (iAddAmount ~= pDealItem:GetAmount()) then
+ pDealItem:SetAmount(iAddAmount);
+ bFound = true;
+ break;
+ else
+ return; -- No change, just exit
+ end
+ end
+ end
+ end
+
+ -- Doesn't exist yet, add it.
+ if (not bFound) then
+
+ -- Going to add anything?
+ pDealItem = pDeal:AddItemOfType(DealItemTypes.GOLD, player:GetID());
+ if (pDealItem ~= nil) then
+
+ -- Set the duration, so the max amount calculation knows what we are doing
+ pDealItem:SetDuration(0);
+
+ -- Adjust the gold to our max
+ iAddAmount = clip(iAddAmount, nil, pDealItem:GetMaxAmount());
+ if (iAddAmount > 0) then
+ pDealItem:SetAmount(iAddAmount);
+ bFound = true;
+ else
+ -- It is empty, remove it.
+ local itemID = pDealItem:GetID();
+ pDeal:RemoveItemByID(itemID);
+ end
+ end
+ end
+
+
+ if (bFound) then
+ UpdateProposedWorkingDeal();
+ UpdateDealPanel(player);
+ end
+ end
+end
+
+-- ===========================================================================
+function OnClickAvailableMultiTurnGold(player, iAddAmount : number, iDuration : number)
+
+ if (ms_bIsDemand == true and ms_InitiatedByPlayerID == ms_OtherPlayerID) then
+ -- Can't modifiy demand that is not ours
+ return;
+ end
+
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ if (pDeal ~= nil) then
+
+ local pPlayerTreasury = player:GetTreasury();
+
+ local bFound = false;
+ UI.PlaySound("UI_GreatWorks_Put_Down");
+
+ -- Already there?
+ local dealItems = pDeal:FindItemsByType(DealItemTypes.GOLD, DealItemSubTypes.NONE, player:GetID());
+ local pDealItem;
+ if (dealItems ~= nil) then
+ for i, pDealItem in ipairs(dealItems) do
+ if (pDealItem:GetDuration() ~= 0) then
+ -- Already have a multi-turn gold. Up the amount
+ iAddAmount = pDealItem:GetAmount() + iAddAmount;
+ iAddAmount = clip(iAddAmount, nil, pDealItem:GetMaxAmount());
+ if (iAddAmount ~= pDealItem:GetAmount()) then
+ pDealItem:SetAmount(iAddAmount);
+ bFound = true;
+ break;
+ else
+ return; -- No change, just exit
+ end
+ end
+ end
+ end
+
+ -- Doesn't exist yet, add it.
+ if (not bFound) then
+ -- Going to add anything?
+ pDealItem = pDeal:AddItemOfType(DealItemTypes.GOLD, player:GetID());
+ if (pDealItem ~= nil) then
+
+ -- Set the duration, so the max amount calculation knows what we are doing
+ pDealItem:SetDuration(iDuration);
+
+ -- Adjust the gold to our max
+ iAddAmount = clip(iAddAmount, nil, pDealItem:GetMaxAmount());
+
+ if (iAddAmount > 0) then
+ pDealItem:SetAmount(iAddAmount);
+ bFound = true;
+ else
+ -- It is empty, remove it.
+ local itemID = pDealItem:GetID();
+ pDeal:RemoveItemByID(itemID);
+ end
+ end
+ end
+
+ if (bFound) then
+ UpdateProposedWorkingDeal();
+ UpdateDealPanel(player);
+ end
+ end
+end
+
+-- ===========================================================================
+-- Clip val to be within the range of min and max
+function clip(val: number, min: number, max: number)
+ if min and val < min then
+ val = min;
+ elseif max and val > max then
+ val = max;
+ end
+ return val;
+end
+
+-- ===========================================================================
+-- Check to see if the deal should be auto-proposed.
+function IsAutoPropose()
+ if (not ms_OtherPlayerIsHuman) then
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ pDeal:Validate();
+ if (pDeal ~= nil and not ms_bIsDemand and pDeal:IsValid() and not DealManager.HasPendingDeal(g_LocalPlayer:GetID(), g_OtherPlayer:GetID())) then
+ local iItemsFromLocal = pDeal:GetItemCount(g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ local iItemsFromOther = pDeal:GetItemCount(g_OtherPlayer:GetID(), g_LocalPlayer:GetID());
+
+ if (iItemsFromLocal > 0 or iItemsFromOther > 0) then
+ return true;
+ end
+ end
+ end
+ return false;
+end
+
+-- ===========================================================================
+-- Check the state of the deal and show/hide the special proposal buttons for a possible gift (not actually possible until XP2)
+function UpdateProposalButtonsForGift(iItemsFromLocal : number, iItemsFromOther : number)
+ if (iItemsFromLocal == 0 and iItemsFromOther > 0) then
+ return true;
+ end
+
+ return false;
+end
+
+-- ===========================================================================
+-- Check the state of the deal and show/hide the special proposal buttons
+function UpdateProposalButtons(bDealValid)
+
+ local bDealIsPending = DealManager.HasPendingDeal(g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+
+ if (bDealValid and (not bDealIsPending or not ms_OtherPlayerIsHuman)) then
+ Controls.ResumeGame:SetHide(true);
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ Controls.EqualizeDeal:SetHide(ms_bIsDemand);
+ if (pDeal ~= nil) then
+
+ local iItemsFromLocal = pDeal:GetItemCount(g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ local iItemsFromOther = pDeal:GetItemCount(g_OtherPlayer:GetID(), g_LocalPlayer:GetID());
+ ms_bIsGift = pDeal:IsGift() and iItemsFromOther > 0;
+
+ -- Hide/show directions if either side has no items
+ Controls.MyDirections:SetHide( iItemsFromLocal > 0);
+ Controls.TheirDirections:SetHide( iItemsFromOther > 0);
+
+ if (not ms_bIsDemand) then
+ if (not ms_OtherPlayerIsHuman) then
+ -- Dealing with an AI
+ if (pDeal:HasUnacceptableItems()) then
+ Controls.EqualizeDeal:SetHide(true);
+ Controls.AcceptDeal:SetHide(true);
+ SetLeaderDialog("LOC_DIPLO_DEAL_UNACCEPTABLE_DEAL", "");
+ elseif (iItemsFromLocal > 0 and iItemsFromOther == 0) then
+ -- One way gift?
+
+ if ms_LastIncomingDealProposalAction == DealProposalAction.EQUALIZE_FAILED then
+ -- Equalize failed, hide the button, and we can't accept now!
+ -- Except... not.
+ -- The AI will yield EQUALIZE_FAILED if it would have accepted the gift without modifications.
+ -- The AI does not distinguish between 'this gift is fine as is' and 'i would not give you anything for that'.
+ Controls.AcceptDeal:SetShow(false);
+ Controls.EqualizeDeal:SetShow(false);
+ SetLeaderDialog("LOC_DIPLO_DEAL_LEADER_GIFT_EQUALIZE_FAILED", "");
+ elseif ms_LastIncomingDealProposalAction == DealProposalAction.REJECTED then
+ -- Most likely autoproposed, there's a chance for an equalize. No accept, again.
+ Controls.AcceptDeal:SetShow(false);
+ Controls.EqualizeDeal:SetShow(true);
+ Controls.EqualizeDeal:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_WHAT_WOULD_IT_TAKE");
+ Controls.EqualizeDeal:LocalizeAndSetToolTip("LOC_DIPLOMACY_DEAL_WHAT_IT_WILL_TAKE_TOOLTIP");
+ SetLeaderDialog("LOC_DIPLO_MAKE_DEAL_AI_REFUSE_DEAL_ANY_ANY", "");
+ else
+ -- No immediate complaints, I guess we can show both equalize and accept.
+ Controls.AcceptDeal:SetShow(true);
+ Controls.AcceptDeal:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_GIFT_DEAL");
+ Controls.EqualizeDeal:SetShow(true);
+ Controls.EqualizeDeal:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_WHAT_WOULD_YOU_GIVE_ME");
+ Controls.EqualizeDeal:LocalizeAndSetToolTip("LOC_DIPLO_DEAL_WHAT_WOULD_YOU_GIVE_ME_TOOLTIP");
+ SetLeaderDialog("LOC_DIPLO_DEAL_LEADER_GIFT", "LOC_DIPLO_DEAL_LEADER_GIFT_EFFECT");
+ end
+ elseif ms_bIsGift then -- Incoming gift
+ Controls.EqualizeDeal:SetShow(false);
+ else
+ if (UpdateProposalButtonsForGift(iItemsFromLocal, iItemsFromOther)) then
+ -- AI was unable to equalize for the requested items so hide the equalize button
+ if ms_LastIncomingDealProposalAction == DealProposalAction.EQUALIZE_FAILED then
+ Controls.EqualizeDeal:SetHide(true);
+ SetLeaderDialog("LOC_DIPLO_DEAL_LEADER_EQUALIZE_FAILED", "");
+ else
+ Controls.EqualizeDeal:SetHide(false);
+ SetLeaderDialog("LOC_DIPLO_DEAL_UNFAIR", "");
+ end
+
+ Controls.EqualizeDeal:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_WHAT_WOULD_IT_TAKE");
+ Controls.EqualizeDeal:LocalizeAndSetToolTip("LOC_DIPLOMACY_DEAL_WHAT_IT_WILL_TAKE_TOOLTIP");
+ Controls.AcceptDeal:SetHide(true); --If either of the above buttons are showing, disable the main accept button
+
+ else --Something is being offered on both sides
+ -- Show equalize button if the accept button is hidden and the AI already hasn't attempted to equalize the deal
+ if Controls.AcceptDeal:IsHidden() and ms_LastIncomingDealProposalAction ~= DealProposalAction.EQUALIZE_FAILED then
+ Controls.EqualizeDeal:SetHide(false);
+ Controls.EqualizeDeal:LocalizeAndSetText("LOC_DIPLOMACY_MAKE_DEAL_EQUITABLE");
+ Controls.EqualizeDeal:LocalizeAndSetToolTip("LOC_DIPLOMACY_MAKE_DEAL_EQUITABLE_TOOLTIP");
+ else
+ Controls.EqualizeDeal:SetHide(true);
+ if ms_LastIncomingDealProposalAction == DealProposalAction.PROPOSED then
+ SetLeaderDialog("LOC_DIPLO_DEAL_INTRO_AI", "");
+ elseif ms_LastIncomingDealProposalAction == DealProposalAction.ACCEPTED then
+ SetLeaderDialog("LOC_DIPLO_MAKE_DEAL_AI_ACCEPT_DEAL_ANY_ANY", "");
+ elseif ms_LastIncomingDealProposalAction == DealProposalAction.ADJUSTED then
+ SetLeaderDialog("LOC_DIPLO_DEAL_LEADER_EQUALIZE_SUCCEEDED", "");
+ else
+ SetLeaderDialog("LOC_DIPLO_DEAL_LEADER_EQUALIZE_FAILED", "");
+ end
+ end
+
+ Controls.AcceptDeal:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_ACCEPT_DEAL");
+ end
+ end
+ else
+ -- Dealing with another human
+
+ Controls.EqualizeDeal:SetHide(true);
+ Controls.AcceptDeal:SetHide(false);
+
+ if (ms_LastIncomingDealProposalAction == DealProposalAction.PENDING) then
+ -- Just starting the deal
+ if (iItemsFromLocal > 0 and iItemsFromOther == 0) then
+ -- Is this one way to them?
+ Controls.MyDirections:SetHide(true);
+ Controls.TheirDirections:SetHide(false);
+ Controls.AcceptDeal:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_GIFT_DEAL");
+ else
+ -- Everything else is a proposal to another human
+ Controls.MyDirections:SetHide(true);
+ Controls.TheirDirections:SetHide(true);
+ Controls.AcceptDeal:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_PROPOSE_DEAL");
+ end
+ -- Make sure the leader text is set to something appropriate.
+ SetDefaultLeaderDialogText();
+ else
+ Controls.MyDirections:SetHide(true);
+ Controls.TheirDirections:SetHide(true);
+ -- Are the incoming and outgoing deals the same?
+ if (DealManager.AreWorkingDealsEqual(g_LocalPlayer:GetID(), g_OtherPlayer:GetID())) then
+ Controls.AcceptDeal:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_ACCEPT_DEAL");
+ else
+ Controls.AcceptDeal:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_PROPOSE_DEAL");
+ end
+ end
+ end
+ else
+ -- Is a Demand
+ if (ms_InitiatedByPlayerID == ms_OtherPlayerID) then
+ Controls.MyDirections:SetHide(true);
+ Controls.TheirDirections:SetHide(true);
+ SetDefaultLeaderDialogText();
+ else
+ if (iItemsFromOther == 0) then
+ Controls.TheirDirections:SetHide(false);
+ else
+ Controls.TheirDirections:SetHide(true);
+ end
+ -- Demand against another player
+ SetLeaderDialog("LOC_DIPLO_DEAL_LEADER_DEMAND", "LOC_DIPLO_DEAL_LEADER_DEMAND_EFFECT");
+ end
+ end
+ else
+ -- Make sure the leader text is set to something appropriate.
+ SetDefaultLeaderDialogText();
+ end
+ else
+ --There isn't a valid deal, or we are just viewing a pending deal.
+ local bIsViewing = (bDealIsPending and ms_OtherPlayerIsHuman);
+
+ local iItemsFromLocal = 0;
+ local iItemsFromOther = 0;
+
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ if (pDeal ~= nil) then
+ iItemsFromLocal = pDeal:GetItemCount(g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ iItemsFromOther = pDeal:GetItemCount(g_OtherPlayer:GetID(), g_LocalPlayer:GetID());
+ end
+
+ Controls.MyDirections:SetHide( bIsViewing or iItemsFromLocal > 0);
+ Controls.TheirDirections:SetHide( bIsViewing or iItemsFromOther > 0);
+ Controls.EqualizeDeal:SetHide(true);
+ Controls.AcceptDeal:SetHide(true);
+ Controls.DemandDeal:SetHide(true);
+
+ if (not DealIsEmpty() and not bDealValid) then
+ -- Set have the other leader tell them that the deal has invalid items.
+ SetLeaderDialog("LOC_DIPLOMACY_DEAL_INVALID", "");
+ else
+ SetDefaultLeaderDialogText();
+ end
+
+ Controls.ResumeGame:SetHide(not bIsViewing);
+ end
+
+ if (bDealIsPending and ms_OtherPlayerIsHuman) then
+ if (ms_bIsDemand) then
+ Controls.RefuseDeal:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_CANCEL_DEMAND");
+ elseif ms_bIsGift then -- Incoming gift
+ Controls.RefuseDeal:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_REFUSE_GIFT");
+ else
+ Controls.RefuseDeal:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_CANCEL_DEAL");
+ end
+ else
+ -- Did the other player start this or the local player?
+ if (ms_InitiatedByPlayerID == ms_OtherPlayerID) then
+ if (not bDealValid) then
+ -- Our changes have made the deal invalid, say cancel instead
+ Controls.RefuseDeal:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_CANCEL_DEAL");
+ else
+ if (ms_bIsDemand) then
+ Controls.AcceptDeal:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_ACCEPT_DEMAND");
+ Controls.RefuseDeal:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_REFUSE_DEMAND");
+ elseif ms_bIsGift then -- Incoming gift
+ Controls.AcceptDeal:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_ACCEPT_GIFT");
+ Controls.RefuseDeal:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_REFUSE_GIFT");
+ else
+ Controls.RefuseDeal:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_REFUSE_DEAL");
+ end
+ end
+ else
+ Controls.RefuseDeal:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_EXIT_DEAL");
+ end
+ end
+ Controls.DealOptionsStack:CalculateSize();
+ Controls.DealOptionsStack:ReprocessAnchoring();
+
+ if (ms_bIsDemand) then
+ if (ms_InitiatedByPlayerID == ms_OtherPlayerID) then
+ -- Demand from the other player and we are responding
+ Controls.MyOfferBracket:SetHide(false);
+ Controls.MyOfferLabel:SetHide(false);
+ Controls.TheirOfferLabel:SetHide(true);
+ Controls.TheirOfferBracket:SetHide(true);
+ else
+ -- Demand from us, to the other player
+ Controls.MyOfferBracket:SetHide(true);
+ Controls.MyOfferLabel:SetHide(true);
+ Controls.TheirOfferLabel:SetHide(false);
+ Controls.TheirOfferBracket:SetHide(false);
+ end
+ else
+ Controls.MyOfferLabel:SetHide(false);
+ Controls.MyOfferBracket:SetHide(false);
+ Controls.TheirOfferLabel:SetHide(false);
+ Controls.TheirOfferBracket:SetHide(false);
+ end
+end
+
+-- ===========================================================================
+function PopulateAvailableGold(player : table, iconList : table)
+
+ local iAvailableItemCount = 0;
+
+ local eFromPlayerID = player:GetID();
+ local eToPlayerID = GetOtherPlayer(player):GetID();
+
+ local pForDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ local possibleResources = DealManager.GetPossibleDealItems(eFromPlayerID, eToPlayerID, DealItemTypes.GOLD, pForDeal);
+ if (possibleResources ~= nil) then
+ for i, entry in ipairs(possibleResources) do
+ if (entry.Duration == 0) then
+ -- One time gold
+ local playerTreasury:table = player:GetTreasury();
+ local goldBalance :number = math.floor(playerTreasury:GetGoldBalance());
+
+ if (not ms_bIsDemand) then
+ -- One time gold
+ local icon = g_IconOnlyIM:GetInstance(iconList.ListStack);
+ icon.AmountText:SetText(goldBalance);
+ icon.SelectButton:SetToolTipString(nil); -- We recycle the entries, so make sure this is clear.
+ SetIconToSize(icon.Icon, "ICON_YIELD_GOLD_5");
+ icon.SelectButton:RegisterCallback( Mouse.eLClick, function() OnClickAvailableOneTimeGold(player, ms_DefaultOneTimeGoldAmount); end );
+ icon.SelectButton:RegisterCallback( Mouse.eLClick, function() OnClickAvailableOneTimeGold(player, ms_DefaultOneTimeGoldAmount); end );
+ icon.Icon:SetColor(1, 1, 1);
+ iAvailableItemCount = iAvailableItemCount + 1;
+ end
+ else
+ -- Multi-turn gold
+ icon = g_IconAndTextIM:GetInstance(iconList.ListStack);
+ SetIconToSize(icon.Icon, "ICON_YIELD_GOLD_5");
+ icon.IconText:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_GOLD_PER_TURN");
+ icon.SelectButton:SetToolTipString(nil); -- We recycle the entries, so make sure this is clear.
+ icon.SelectButton:RegisterCallback( Mouse.eLClick, function() OnClickAvailableMultiTurnGold(player, ms_DefaultMultiTurnGoldAmount, ms_DefaultMultiTurnGoldDuration); end );
+ icon.ValueText:SetHide(true);
+ icon.Icon:SetColor(1, 1, 1);
+
+ iconList.ListStack:CalculateSize();
+ iconList.List:ReprocessAnchoring();
+
+ iAvailableItemCount = iAvailableItemCount + 1;
+ end
+ end
+ end
+
+ return iAvailableItemCount;
+end
+
+-- ===========================================================================
+function OnClickAvailableBasic(itemType, player, valueType)
+
+ if (ms_bIsDemand == true and ms_InitiatedByPlayerID == ms_OtherPlayerID) then
+ -- Can't modifiy demand that is not ours
+ return;
+ end
+
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ if (pDeal ~= nil) then
+
+ -- Already there?
+ local pDealItem = pDeal:FindItemByValueType(itemType, DealItemSubTypes.NONE, valueType, player:GetID());
+ if (pDealItem == nil) then
+ -- No
+ pDealItem = pDeal:AddItemOfType(itemType, player:GetID());
+ if (pDealItem ~= nil) then
+ pDealItem:SetValueType(valueType);
+ UpdateDealPanel(player);
+ UpdateProposedWorkingDeal();
+ end
+ end
+ end
+end
+
+-- ===========================================================================
+function OnClickAvailableResource(player, resourceType)
+
+ if (ms_bIsDemand == true and ms_InitiatedByPlayerID == ms_OtherPlayerID) then
+ -- Can't modifiy demand that is not ours
+ return;
+ end
+
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ if (pDeal ~= nil) then
+
+ -- Already there?
+ local dealItems = pDeal:FindItemsByType(DealItemTypes.RESOURCES, DealItemSubTypes.NONE, player:GetID());
+ local pDealItem;
+ if (dealItems ~= nil) then
+ for i, pDealItem in ipairs(dealItems) do
+ if pDealItem:GetValueType() == resourceType then
+ -- Check for non-zero duration. There may already be a one-time transfer of the resource if a city is in the deal.
+ if (pDealItem:GetDuration() ~= 0) then
+ return; -- Already in there.
+ end
+ end
+ end
+ end
+
+ local pPlayerResources = player:GetResources();
+ -- Get the total amount of the resource we have. This does not take into account anything already in the deal.
+ local iAmount = pPlayerResources:GetResourceAmount( resourceType );
+ if (iAmount > 0) then
+
+ pDealItem = pDeal:AddItemOfType(DealItemTypes.RESOURCES, player:GetID());
+ if (pDealItem ~= nil) then
+ -- Add one
+ pDealItem:SetValueType(resourceType);
+ pDealItem:SetAmount(1);
+ pDealItem:SetDuration(30); -- Default to this many turns
+
+ -- After we add the item, test to see if the item is valid, it is possible that we have exceeded the amount of resources we can trade.
+ if not pDealItem:IsValid() then
+ pDeal:RemoveItemByID(pDealItem:GetID());
+ pDealItem = nil;
+ else
+ UI.PlaySound("UI_GreatWorks_Put_Down");
+ end
+
+ UpdateDealPanel(player);
+ UpdateProposedWorkingDeal();
+ end
+ end
+ end
+end
+
+-- ===========================================================================
+function OnClickAvailableAgreement(player, agreementType, agreementTurns)
+
+ if (ms_bIsDemand == true and ms_InitiatedByPlayerID == ms_OtherPlayerID) then
+ -- Can't modifiy demand that is not ours
+ return;
+ end
+
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ if (pDeal ~= nil) then
+
+ -- Already there?
+ local pDealItem = pDeal:FindItemByType(DealItemTypes.AGREEMENTS, agreementType, player:GetID());
+ if (pDealItem == nil) then
+ if (agreementType == DealAgreementTypes.JOINT_WAR or
+ agreementType == DealAgreementTypes.THIRD_PARTY_WAR or
+ agreementType == DealAgreementTypes.RESEARCH_AGREEMENT ) then
+ ShowAgreementOptionPopup(agreementType, agreementTurns, player:GetID());
+ else
+ -- No
+ pDealItem = pDeal:AddItemOfType(DealItemTypes.AGREEMENTS, player:GetID());
+ if (pDealItem ~= nil) then
+ pDealItem:SetSubType(agreementType);
+ pDealItem:SetDuration(agreementTurns);
+
+ UpdateDealPanel(player);
+ UpdateProposedWorkingDeal();
+ UI.PlaySound("UI_GreatWorks_Put_Down");
+ end
+ end
+ end
+ end
+end
+
+-- ===========================================================================
+function OnSelectAgreementOption(agreementType, agreementTurns, agreementValue, agreementParameters, fromPlayerId)
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ if (pDeal ~= nil) then
+
+ -- Already there?
+ local pDealItem = pDeal:FindItemByType(DealItemTypes.AGREEMENTS, agreementType, fromPlayerId);
+ if (pDealItem ~= nil) then
+ -- deal manager doesn't update properly unless we delete the deal item
+ -- and add a new one.
+ if (not pDealItem:IsLocked()) then
+ local itemID = pDealItem:GetID();
+ DetachValueEdit(itemID);
+ pDeal:RemoveItemByID(itemID);
+ pDealItem = pDeal:AddItemOfType(DealItemTypes.AGREEMENTS, fromPlayerId);
+ end
+ else
+ pDealItem = pDeal:AddItemOfType(DealItemTypes.AGREEMENTS, fromPlayerId);
+ end
+
+ if (pDealItem ~= nil) then
+ pDealItem:SetSubType(agreementType);
+ pDealItem:SetDuration(agreementTurns);
+ pDealItem:SetValueType(agreementValue);
+
+ if (agreementType == DealAgreementTypes.JOINT_WAR or
+ agreementType == DealAgreementTypes.THIRD_PARTY_WAR) then
+ pDealItem:SetParameterValue("WarType", agreementParameters.WarType);
+ end
+
+ UpdateDealPanel(g_LocalPlayer);
+ UpdateProposedWorkingDeal();
+ UI.PlaySound("UI_GreatWorks_Put_Down");
+ end
+
+ Controls.ValueEditPopupBackground:SetHide(true);
+ end
+end
+
+-- ===========================================================================
+function ShowAgreementOptionPopup(agreementType, agreementTurns, fromPlayerId)
+
+ -- Hide/show everything for AGREEMENTS options
+ ms_AgreementOptionIM:ResetInstances();
+ Controls.ValueEditIconGrid:SetHide(true);
+ Controls.ValueAmountEditBoxContainer:SetHide(true);
+
+ -- don't update when backing out of this on a war
+ if ((agreementType == DealAgreementTypes.JOINT_WAR) or
+ (agreementType == DealAgreementTypes.THIRD_PARTY_WAR)) then
+ ms_bDontUpdateOnBack = true;
+ end
+
+ if agreementType == DealAgreementTypes.RESEARCH_AGREEMENT then
+ Controls.ValueEditHeaderLabel:SetText(Locale.Lookup("LOC_DIPLOMACY_DEAL_SELECT_TECH"));
+ elseif agreementType == DealAgreementTypes.ALLIANCE then
+ Controls.ValueEditHeaderLabel:SetText(Locale.Lookup("LOC_DIPLOMACY_DEAL_SELECT_ALLIANCE"));
+ else
+ Controls.ValueEditHeaderLabel:SetText(Locale.Lookup("LOC_DIPLOMACY_DEAL_SELECT_TARGET"));
+ end
+
+ local toPlayerId = g_LocalPlayer:GetID();
+ if (toPlayerId == fromPlayerId ) then
+ toPlayerId = g_OtherPlayer:GetID();
+ end
+ local pForDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ local possibleValues = DealManager.GetPossibleDealItems(fromPlayerId, toPlayerId, DealItemTypes.AGREEMENTS, agreementType, pForDeal);
+ if (possibleValues ~= nil) then
+ for i, entry in ipairs(possibleValues) do
+ local instance:table = ms_AgreementOptionIM:GetInstance();
+
+ local szDisplayName = "";
+ local szItemName = Locale.Lookup(entry.ForTypeDisplayName);
+ if (entry.SubType == DealAgreementTypes.RESEARCH_AGREEMENT) then
+ local eTech = GameInfo.Technologies[entry.ForType].Index;
+ local iTurns = g_LocalPlayer:GetDiplomacy():ComputeResearchAgreementTurns(g_OtherPlayer, eTech);
+ szDisplayName = Locale.Lookup("LOC_DIPLOMACY_DEAL_PARAMETER_WITH_TURNS", szItemName, iTurns);
+ instance.AgreementOptionIcon:SetIcon("ICON_" .. entry.ForTypeName);
+ instance.AgreementOptionIcon:SetHide(false);
+ else
+ if (entry.SubType == DealAgreementTypes.JOINT_WAR or
+ entry.SubType == DealAgreementTypes.THIRD_PARTY_WAR) then
+ szDisplayName = szItemName;
+
+ -- Have a type of war that describes the joint war?
+ if entry.Parameters ~= nil then
+ if entry.Parameters.WarType ~= nil then
+ local warDef = GameInfo.Wars[entry.Parameters.WarType];
+ if warDef ~= nil then
+ szDisplayName = szDisplayName .. "[newline]" .. Locale.Lookup(warDef.Name);
+ end
+ end
+ end
+
+ instance.AgreementOptionIcon:SetHide(true);
+ else
+ szDisplayName = szItemName;
+ instance.AgreementOptionIcon:SetHide(true);
+ end
+ end
+
+ instance.AgreementOptionLabel:SetText(szDisplayName);
+
+ if agreementType == DealAgreementTypes.ALLIANCE then
+ local allianceLevel:number = g_LocalPlayer:GetDiplomacy():GetAllianceLevel(g_OtherPlayer);
+ local allianceData:table = GameInfo.Alliances[entry.ForTypeName];
+ local tooltip = Game.GetGameDiplomacy():GetAllianceBenefitsString(allianceData.Index, allianceLevel, true);
+ instance.AgreementOptionButton:SetToolTipString(tooltip);
+ else
+ instance.AgreementOptionButton:SetToolTipString("");
+ end
+
+ local agreementValueType = entry.ForType;
+ local agreementParameters = entry.Parameters;
+ instance.AgreementOptionButton:RegisterCallback(Mouse.eLClick, function()
+ OnSelectAgreementOption(agreementType, agreementTurns, agreementValueType, agreementParameters, fromPlayerId);
+ end);
+
+ Controls.ValueEditButton:RegisterCallback( Mouse.eLClick, OnAgreementBackButton );
+ end
+ end
+
+ Controls.ValueEditIconGrid:DoAutoSize();
+
+ ResizeValueEditScrollPanel();
+
+ Controls.ValueEditPopup:DoAutoSize();
+ Controls.ValueEditPopupBackground:SetHide(false);
+end
+
+-- ===========================================================================
+function ResizeValueEditScrollPanel()
+ -- Resize scroll panel to a maximum height of five agreement options
+ Controls.ValueEditStack:CalculateSize();
+ if Controls.ValueEditStack:GetSizeY() > MAX_DEAL_ITEM_EDIT_HEIGHT then
+ Controls.ValueEditScrollPanel:SetSizeY(MAX_DEAL_ITEM_EDIT_HEIGHT);
+ else
+ Controls.ValueEditScrollPanel:SetSizeY(Controls.ValueEditStack:GetSizeY());
+ end
+ Controls.ValueEditScrollPanel:CalculateSize();
+end
+
+-- ===========================================================================
+function OnAgreementBackButton()
+ if not ms_bDontUpdateOnBack then
+ UpdateDealPanel(g_LocalPlayer);
+ UpdateProposedWorkingDeal();
+ end
+ ms_bDontUpdateOnBack = false;
+ Controls.ValueEditPopupBackground:SetHide(true);
+end
+
+-- ===========================================================================
+function OnClickAvailableGreatWork(player, type)
+
+ OnClickAvailableBasic(DealItemTypes.GREATWORK, player, type);
+ UI.PlaySound("UI_GreatWorks_Put_Down");
+
+end
+
+-- ===========================================================================
+function OnClickAvailableCaptive(player, type)
+
+ OnClickAvailableBasic(DealItemTypes.CAPTIVE, player, type);
+ UI.PlaySound("UI_GreatWorks_Put_Down");
+
+end
+
+-- ===========================================================================
+function OnClickAvailableCity(player, valueType, subType)
+
+ if (ms_bIsDemand == true and ms_InitiatedByPlayerID == ms_OtherPlayerID) then
+ -- Can't modifiy demand that is not ours
+ return;
+ end
+
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ if (pDeal ~= nil) then
+
+ -- Already there?
+ local pDealItem = pDeal:FindItemByValueType(DealItemTypes.CITIES, subType, valueType, player:GetID());
+ if (pDealItem == nil) then
+ -- No
+ pDealItem = pDeal:AddItemOfType(DealItemTypes.CITIES, player:GetID());
+ if (pDealItem ~= nil) then
+ pDealItem:SetSubType(subType);
+ pDealItem:SetValueType(valueType);
+ if (not pDealItem:IsValid(pDeal)) then
+ pDeal:RemoveItemByID(pDealItem:GetID());
+ end
+ UpdateDealPanel(player);
+ UpdateProposedWorkingDeal();
+ end
+ end
+ end
+
+ UI.PlaySound("UI_GreatWorks_Put_Down");
+
+end
+
+-- ===========================================================================
+function OnRemoveDealItem(player, itemID)
+
+ if (ms_bIsDemand == true and ms_InitiatedByPlayerID == ms_OtherPlayerID) then
+ -- Can't remove it
+ return;
+ end
+
+ DetachValueEdit(itemID);
+
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ if (pDeal ~= nil) then
+
+ local pDealItem = pDeal:FindItemByID(itemID);
+ if (pDealItem ~= nil) then
+ if (not pDealItem:IsLocked()) then
+ if (pDeal:RemoveItemByID(itemID)) then
+ UpdateDealPanel(player);
+ UpdateProposedWorkingDeal();
+ UI.PlaySound("UI_GreatWorks_Pick_Up");
+ end
+ end
+ end
+ end
+end
+
+-- ===========================================================================
+function OnSelectValueDealItem(player, itemID, controlInstance)
+
+ if (ms_bIsDemand == true and ms_InitiatedByPlayerID == ms_OtherPlayerID) then
+ -- Can't edit it
+ return;
+ end
+
+ if (controlInstance ~= nil) then
+ AttachValueEdit(controlInstance, itemID);
+ end
+end
+
+-- ===========================================================================
+function OnValueEditButton(itemID)
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ if pDeal then
+ local pDealItem = pDeal:FindItemByID(itemID);
+ if pDealItem then
+ local newAmount:number = tonumber(Controls.ValueAmountEditBox:GetText());
+ newAmount = clip(newAmount, 1, pDealItem:GetMaxAmount());
+
+ if (newAmount ~= pDealItem:GetAmount()) then
+ local subtype = pDealItem:GetSubType();
+ local duration = pDealItem:GetDuration();
+ local valueType = pDealItem:GetValueType();
+ local fromPlayerId = pDealItem:GetFromPlayerID();
+ local type = pDealItem:GetType();
+ if (not pDealItem:IsLocked()) then
+ DetachValueEdit(itemID);
+ pDeal:RemoveItemByID(itemID);
+ pDealItem = pDeal:AddItemOfType(type, fromPlayerId);
+ pDealItem:SetSubType(subtype);
+ pDealItem:SetDuration(duration);
+ pDealItem:SetValueType(valueType);
+ end
+
+ pDealItem:SetAmount(newAmount);
+ ms_bForceUpdateOnCommit = true;
+ UpdateProposedWorkingDeal();
+ end
+
+ if g_ValueEditDealItemControlTable then
+ g_ValueEditDealItemControlTable.AmountText:SetText(newAmount);
+ g_ValueEditDealItemControlTable.AmountText:SetHide(false);
+ end
+ UpdateDealStatus();
+ end
+ end
+
+ Controls.ValueEditPopupBackground:SetHide(true);
+end
+
+-- ===========================================================================
+function PopulateAvailableResources(player : table, iconList : table, className : string)
+
+ local iAvailableItemCount = 0;
+ local pForDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ local possibleResources = DealManager.GetPossibleDealItems(player:GetID(), GetOtherPlayer(player):GetID(), DealItemTypes.RESOURCES, pForDeal);
+ if (possibleResources ~= nil) then
+ for i, entry in ipairs(possibleResources) do
+
+ local resourceDesc = GameInfo.Resources[entry.ForType];
+ if (resourceDesc ~= nil) then
+ -- Do we have some and is it a luxury item?
+ if (entry.MaxAmount > 0 and resourceDesc.ResourceClassType == className ) then
+ local icon = g_IconOnlyIM:GetInstance(iconList.ListStack);
+ SetIconToSize(icon.Icon, "ICON_" .. resourceDesc.ResourceType);
+ icon.AmountText:SetText(tostring(entry.MaxAmount));
+ icon.AmountText:SetHide(false);
+
+ local resourceType = entry.ForType;
+ -- What to do when double clicked/tapped.
+ icon.SelectButton:RegisterCallback( Mouse.eLClick, function() OnClickAvailableResource(player, resourceType); end );
+ -- Set a tool tip
+ if entry.IsValid then
+ icon.SelectButton:LocalizeAndSetToolTip(resourceDesc.Name);
+ icon.SelectButton:SetDisabled(false);
+ icon.Icon:SetColor(1, 1, 1);
+ else
+ local tempstr = Locale.Lookup(resourceDesc.Name).."[NEWLINE][COLOR_RED]";
+ if player ~= g_LocalPlayer then
+ tempstr = tempstr .. Locale.Lookup("LOC_DEAL_PLAYER_HAS_NO_CAP_ROOM");
+ icon.SelectButton:SetToolTipString(tempstr);
+ else
+ tempstr = tempstr .. Locale.Lookup("LOC_DEAL_AI_HAS_NO_CAP_ROOM");
+ icon.SelectButton:SetToolTipString(tempstr);
+ end
+ icon.SelectButton:SetDisabled(true);
+ icon.Icon:SetColor(0.5, 0.5, 0.5);
+ end
+ icon.SelectButton:ReprocessAnchoring();
+
+ iAvailableItemCount = iAvailableItemCount + 1;
+ end
+ end
+ end
+
+ iconList.ListStack:CalculateSize();
+ iconList.List:ReprocessAnchoring();
+ end
+
+ -- Hide if empty
+ iconList.GetTopControl():SetHide( iconList.ListStack:GetSizeX()==0 );
+
+ return iAvailableItemCount;
+end
+
+-- ===========================================================================
+function PopulateAvailableLuxuryResources(player : table, iconList : table)
+
+ local iAvailableItemCount = 0;
+ iAvailableItemCount = iAvailableItemCount + PopulateAvailableResources(player, iconList, "RESOURCECLASS_LUXURY");
+ return iAvailableItemCount;
+end
+
+-- ===========================================================================
+function PopulateAvailableStrategicResources(player : table, iconList : table)
+
+ local iAvailableItemCount = 0;
+ iAvailableItemCount = iAvailableItemCount + PopulateAvailableResources(player, iconList, "RESOURCECLASS_STRATEGIC");
+ return iAvailableItemCount;
+end
+
+-- ===========================================================================
+function PopulateAvailableAgreements(player : table, iconList : table)
+
+ local iAvailableItemCount = 0;
+ local pForDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ local possibleAgreements = DealManager.GetPossibleDealItems(player:GetID(), GetOtherPlayer(player):GetID(), DealItemTypes.AGREEMENTS, pForDeal);
+ if (possibleAgreements ~= nil) then
+ for i, entry in ipairs(possibleAgreements) do
+ local agreementType = entry.SubType;
+
+ local agreementDuration = entry.Duration;
+ local icon = g_IconAndTextIM:GetInstance(iconList.ListStack);
+
+ local info: table = GameInfo.DiplomaticActions[ agreementType ];
+ if (info ~= nil) then
+ SetIconToSize(icon.Icon, "ICON_".. info.DiplomaticActionType, 38);
+ end
+ icon.AmountText:SetHide(true);
+ icon.IconText:LocalizeAndSetText(entry.SubTypeName);
+ icon.SelectButton:SetDisabled( not entry.IsValid and entry.ValidationResult ~= DealValidationResult.MISSING_DEPENDENCY ); -- Hide if invalid, unless it is just missing a dependency, the user will update that when it is added to the deal.
+ icon.ValueText:SetHide(true);
+ icon.Icon:SetColor(1, 1, 1);
+
+ -- What to do when double clicked/tapped.
+ icon.SelectButton:RegisterCallback( Mouse.eLClick, function() OnClickAvailableAgreement(player, agreementType, agreementDuration); end );
+ -- Set a tool tip if their is a duration
+ if (entry.Duration > 0) then
+ local szTooltip = Locale.Lookup("LOC_DIPLOMACY_DEAL_PARAMETER_WITH_TURNS", entry.SubTypeName, entry.Duration);
+ icon.SelectButton:SetToolTipString(szTooltip);
+ else
+ icon.SelectButton:SetToolTipString(nil);
+ end
+
+ -- icon.SelectButton:LocalizeAndSetToolTip( );
+ icon.SelectButton:ReprocessAnchoring();
+
+ iAvailableItemCount = iAvailableItemCount + 1;
+ end
+
+ iconList.ListStack:CalculateSize();
+ iconList.List:ReprocessAnchoring();
+ end
+
+ -- Hide if empty
+ iconList.GetTopControl():SetHide( iconList.ListStack:GetSizeX()==0 );
+
+ return iAvailableItemCount;
+end
+
+-- ===========================================================================
+function MakeCityToolTip(player : table, cityID : number)
+ local pCity = player:GetCities():FindID( cityID );
+ if (pCity ~= nil) then
+ local szToolTip = Locale.Lookup("LOC_DEAL_CITY_POPULATION_TOOLTIP", pCity:GetPopulation());
+ local districtNames = {};
+ local pCityDistricts = pCity:GetDistricts();
+ if (pCityDistricts ~= nil) then
+
+ for i, pDistrict in pCityDistricts:Members() do
+ local pDistrictDef = GameInfo.Districts[ pDistrict:GetType() ];
+ if (pDistrictDef ~= nil) then
+ local districtType:string = pDistrictDef.DistrictType;
+ -- Skip the city center and any wonder districts
+ if (districtType ~= "DISTRICT_CITY_CENTER" and districtType ~= "DISTRICT_WONDER") then
+ table.insert(districtNames, pDistrictDef.Name);
+ end
+ end
+ end
+ end
+
+ if (#districtNames > 0) then
+ szToolTip = szToolTip .. "[NEWLINE]" .. Locale.Lookup("LOC_DEAL_CITY_DISTRICTS_TOOLTIP");
+ for i, name in ipairs(districtNames) do
+ szToolTip = szToolTip .. "[NEWLINE]" .. Locale.Lookup(name);
+ end
+ end
+
+ -- Add Resources
+ local extractedResources = player:GetResources():GetResourcesExtractedByCity( cityID, ResultFormat.SUMMARY );
+ if extractedResources ~= nil and #extractedResources > 0 then
+ szToolTip = szToolTip .. "[NEWLINE]" .. Locale.Lookup("LOC_DEAL_CITY_RESOURCES_TOOLTIP");
+ for i, entry in ipairs(extractedResources) do
+ local resourceDesc = GameInfo.Resources[entry.ResourceType];
+ if resourceDesc ~= nil then
+ szToolTip = szToolTip .. "[NEWLINE]" .. Locale.Lookup(resourceDesc.Name) .. " : " .. tostring(entry.Amount);
+ end
+ end
+ end
+
+ -- Add Great Works
+ local cityGreatWorks = player:GetCulture():GetGreatWorksInCity( cityID );
+ if cityGreatWorks ~= nil and #cityGreatWorks > 0 then
+ szToolTip = szToolTip .. "[NEWLINE]" .. Locale.Lookup("LOC_DEAL_CITY_GREAT_WORKS_TOOLTIP");
+ for i, entry in ipairs(cityGreatWorks) do
+ local greatWorksDesc = GameInfo.GreatWorks[entry.GreatWorksType];
+ if greatWorksDesc ~= nil then
+ szToolTip = szToolTip .. "[NEWLINE]" .. Locale.Lookup(greatWorksDesc.Name);
+ end
+ end
+ end
+
+ return szToolTip;
+ end
+
+ return "";
+end
+
+-- ===========================================================================
+function PopulateAvailableCities(player : table, iconList : table)
+
+ local iAvailableItemCount = 0;
+ local pForDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ local possibleItems = DealManager.GetPossibleDealItems(player:GetID(), GetOtherPlayer(player):GetID(), DealItemTypes.CITIES, pForDeal);
+ if (possibleItems ~= nil) then
+ for i, entry in ipairs(possibleItems) do
+
+ local type = entry.ForType;
+ local subType = entry.SubType;
+ local icon = g_IconAndTextIM:GetInstance(iconList.ListStack);
+ SetIconToSize(icon.Icon, "ICON_BUILDINGS", 45);
+ icon.AmountText:SetHide(true);
+ icon.IconText:LocalizeAndSetText(entry.ForTypeName);
+ icon.SelectButton:SetDisabled( not entry.IsValid and entry.ValidationResult ~= DealValidationResult.MISSING_DEPENDENCY ); -- Hide if invalid, unless it is just missing a dependency, the user will update that when it is added to the deal.
+ icon.ValueText:SetHide(true);
+ icon.Icon:SetColor(1, 1, 1);
+
+ -- What to do when double clicked/tapped.
+ icon.SelectButton:RegisterCallback( Mouse.eLClick, function() OnClickAvailableCity(player, type, subType); end );
+
+ -- Since we're ceding this city make sure to look for this city in the current owners city list
+ if entry.SubType == 1 then -- CitySubTypes:CEDE_OCCUPIED
+ icon.SelectButton:SetToolTipString( MakeCityToolTip(GetOtherPlayer(player), type) );
+ else
+ icon.SelectButton:SetToolTipString( MakeCityToolTip(player, type) );
+ end
+
+ iAvailableItemCount = iAvailableItemCount + 1;
+ end
+
+ iconList.ListStack:CalculateSize();
+ end
+
+ -- Hide if empty
+ iconList.GetTopControl():SetHide( iconList.ListStack:GetSizeX()==0 );
+
+ return iAvailableItemCount;
+end
+
+-- ===========================================================================
+function PopulateAvailableOtherPlayers(player : table, iconList : table)
+
+ local iAvailableItemCount = 0;
+ -- Hide if empty
+ iconList.GetTopControl():SetHide( iconList.ListStack:GetSizeX()==0 );
+
+ return iAvailableItemCount;
+end
+
+-- ===========================================================================
+function PopulateAvailableGreatWorks(player : table, iconList : table)
+
+ local iAvailableItemCount = 0;
+ local pForDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ local possibleItems = DealManager.GetPossibleDealItems(player:GetID(), GetOtherPlayer(player):GetID(), DealItemTypes.GREATWORK, pForDeal);
+ if (possibleItems ~= nil) then
+ for i, entry in ipairs(possibleItems) do
+ local greatWorkDesc = GameInfo.GreatWorks[entry.ForTypeDescriptionID];
+ if (greatWorkDesc ~= nil) then
+ local type = entry.ForType;
+ local icon = g_IconAndTextIM:GetInstance(iconList.ListStack);
+ SetIconToSize(icon.Icon, "ICON_" .. greatWorkDesc.GreatWorkType, 45);
+ icon.AmountText:SetHide(true);
+ icon.IconText:LocalizeAndSetText(entry.ForTypeName);
+ icon.SelectButton:SetDisabled( not entry.IsValid and entry.ValidationResult ~= DealValidationResult.MISSING_DEPENDENCY ); -- Hide if invalid, unless it is just missing a dependency, the user will update that when it is added to the deal.
+ icon.ValueText:SetHide(true);
+ icon.Icon:SetColor(1, 1, 1);
+
+ -- What to do when double clicked/tapped.
+ icon.SelectButton:RegisterCallback( Mouse.eLClick, function() OnClickAvailableGreatWork(player, type); end );
+ -- Set a tool tip
+
+ local strGreatWorkTooltip = GreatWorksSupport_GetBasicTooltip(entry.ForType, false);
+ icon.SelectButton:SetToolTipString(strGreatWorkTooltip);
+ icon.SelectButton:ReprocessAnchoring();
+
+ iAvailableItemCount = iAvailableItemCount + 1;
+ end
+ end
+
+ iconList.ListStack:CalculateSize();
+ iconList.List:ReprocessAnchoring();
+ end
+
+ -- Hide if empty
+ iconList.GetTopControl():SetHide( iconList.ListStack:GetSizeX()==0 );
+
+ return iAvailableItemCount;
+
+end
+
+-- ===========================================================================
+function PopulateAvailableCaptives(player : table, iconList : table)
+
+ local iAvailableItemCount = 0;
+
+ local pForDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ local possibleItems = DealManager.GetPossibleDealItems(player:GetID(), GetOtherPlayer(player):GetID(), DealItemTypes.CAPTIVE, pForDeal);
+ if (possibleItems ~= nil) then
+ for i, entry in ipairs(possibleItems) do
+
+ local type = entry.ForType;
+ local icon = g_IconAndTextIM:GetInstance(iconList.ListStack);
+ SetIconToSize(icon.Icon, "ICON_UNIT_SPY");
+ icon.AmountText:SetHide(true);
+ if (entry.ForTypeName ~= nil ) then
+ icon.IconText:LocalizeAndSetText(entry.ForTypeName);
+ end
+ icon.SelectButton:SetDisabled( not entry.IsValid and entry.ValidationResult ~= DealValidationResult.MISSING_DEPENDENCY ); -- Hide if invalid, unless it is just missing a dependency, the user will update that when it is added to the deal.
+ icon.ValueText:SetHide(true);
+ icon.Icon:SetColor(1, 1, 1);
+
+ -- What to do when double clicked/tapped.
+ icon.SelectButton:RegisterCallback( Mouse.eLClick, function() OnClickAvailableCaptive(player, type); end );
+ icon.SelectButton:SetToolTipString(nil); -- We recycle the entries, so make sure this is clear.
+ icon.SelectButton:ReprocessAnchoring();
+
+ iAvailableItemCount = iAvailableItemCount + 1;
+ end
+
+ iconList.ListStack:CalculateSize();
+ iconList.List:ReprocessAnchoring();
+ end
+
+ -- Hide if empty
+ iconList.GetTopControl():SetHide( iconList.ListStack:GetSizeX()==0 );
+
+ return iAvailableItemCount;
+end
+
+-- ===========================================================================
+function PopulatePlayerAvailablePanel(rootControl : table, player : table)
+
+ local iAvailableItemCount = 0;
+
+ if (player ~= nil) then
+
+ local playerType = GetPlayerType(player);
+ if (ms_bIsDemand and player:GetID() == ms_InitiatedByPlayerID) then
+ -- This is a demand, so hide all the demanding player's items
+ for i = 1, table.count(AvailableDealItemGroupTypes), 1 do
+ g_AvailableGroups[i][playerType].GetTopControl():SetHide(true);
+ end
+ else
+ g_AvailableGroups[AvailableDealItemGroupTypes.GOLD][playerType].GetTopControl():SetHide(false);
+
+ iAvailableItemCount = iAvailableItemCount + PopulateAvailableGold(player, g_AvailableGroups[AvailableDealItemGroupTypes.GOLD][playerType]);
+ iAvailableItemCount = iAvailableItemCount + PopulateAvailableLuxuryResources(player, g_AvailableGroups[AvailableDealItemGroupTypes.LUXURY_RESOURCES][playerType]);
+ iAvailableItemCount = iAvailableItemCount + PopulateAvailableStrategicResources(player, g_AvailableGroups[AvailableDealItemGroupTypes.STRATEGIC_RESOURCES][playerType]);
+
+ if (not ms_bIsDemand) then
+ iAvailableItemCount = iAvailableItemCount + PopulateAvailableAgreements(player, g_AvailableGroups[AvailableDealItemGroupTypes.AGREEMENTS][playerType]);
+ else
+ g_AvailableGroups[AvailableDealItemGroupTypes.AGREEMENTS][playerType].GetTopControl():SetHide(true);
+ end
+
+ iAvailableItemCount = iAvailableItemCount + PopulateAvailableCities(player, g_AvailableGroups[AvailableDealItemGroupTypes.CITIES][playerType]);
+
+ if (not ms_bIsDemand) then
+ iAvailableItemCount = iAvailableItemCount + PopulateAvailableOtherPlayers(player, g_AvailableGroups[AvailableDealItemGroupTypes.OTHER_PLAYERS][playerType]);
+ else
+ g_AvailableGroups[AvailableDealItemGroupTypes.OTHER_PLAYERS][playerType].GetTopControl():SetHide(false);
+ end
+
+ iAvailableItemCount = iAvailableItemCount + PopulateAvailableGreatWorks(player, g_AvailableGroups[AvailableDealItemGroupTypes.GREAT_WORKS][playerType]);
+ iAvailableItemCount = iAvailableItemCount + PopulateAvailableCaptives(player, g_AvailableGroups[AvailableDealItemGroupTypes.CAPTIVES][playerType]);
+
+ end
+
+ rootControl:CalculateSize();
+ rootControl:ReprocessAnchoring();
+
+ end
+
+ return iAvailableItemCount;
+end
+
+-- ===========================================================================
+function PopulateDealBasic(player : table, iconList : table, populateType : number, iconName : string)
+
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ local playerType = GetPlayerType(player);
+ if (pDeal ~= nil) then
+
+ local pDealItem;
+ for pDealItem in pDeal:Items() do
+ local type = pDealItem:GetType();
+ if (pDealItem:GetFromPlayerID() == player:GetID()) then
+ local iDuration = pDealItem:GetDuration();
+ local dealItemID = pDealItem:GetID();
+
+ if (type == populateType) then
+ local icon = g_IconAndTextIM:GetInstance(iconList);
+ SetIconToSize(icon.Icon, iconName);
+ icon.AmountText:SetHide(true);
+ local typeName = pDealItem:GetValueTypeNameID();
+ if (typeName ~= nil) then
+ icon.IconText:LocalizeAndSetText(typeName);
+ end
+
+ -- Show/hide unacceptable item notification
+ icon.UnacceptableIcon:SetHide(not pDealItem:IsUnacceptable());
+
+ icon.SelectButton:RegisterCallback(Mouse.eRClick, function(void1, void2, self) OnRemoveDealItem(player, dealItemID, self); end);
+ icon.SelectButton:RegisterCallback( Mouse.eLClick, function(void1, void2, self) OnSelectValueDealItem(player, dealItemID, self); end );
+
+ icon.SelectButton:SetToolTipString(nil); -- We recycle the entries, so make sure this is clear.
+ icon.SelectButton:SetDisabled(false);
+ icon.Icon:SetColor(1, 1, 1);
+ end
+ end
+ end
+
+ iconList:CalculateSize();
+ iconList:ReprocessAnchoring();
+
+ end
+
+end
+
+-- ===========================================================================
+function GetParentItemTransferToolTip(parentDealItem)
+ local szToolTip = "";
+
+ -- If it is from a city, put the city name in the tool tip.
+ if (parentDealItem:GetType() == DealItemTypes.CITIES) then
+
+ local cityTypeName = parentDealItem:GetValueTypeNameID();
+ if (cityTypeName ~= nil) then
+ local cityName = Locale.Lookup(cityTypeName);
+ local szTransfer = Locale.Lookup("LOC_DEAL_ITEM_TRANSFERRED_WITH_CITY_TOOLTIP", cityName);
+
+ szToolTip = "[NEWLINE]" .. szTransfer;
+ end
+ end
+
+ return szToolTip;
+end
+-- ===========================================================================
+function PopulateDealResources(player : table, iconList : table)
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ local playerType = GetPlayerType(player);
+ if (pDeal ~= nil) then
+ g_IconOnlyIM:ReleaseInstanceByParent(iconList);
+ g_IconAndTextIM:ReleaseInstanceByParent(iconList);
+
+ local pDealItem;
+ for pDealItem in pDeal:Items() do
+
+ local type = pDealItem:GetType();
+ if (pDealItem:GetFromPlayerID() == player:GetID()) then
+ local iDuration = pDealItem:GetDuration();
+ local dealItemID = pDealItem:GetID();
+ -- Gold?
+ if (type == DealItemTypes.GOLD) then
+ local icon;
+ if (iDuration == 0) then
+ -- One time
+ icon = g_IconOnlyIM:GetInstance(iconList);
+ else
+ -- Multi-turn
+ icon = g_IconAndTextIM:GetInstance(iconList);
+ icon.IconText:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_FOR_TURNS", iDuration);
+ icon.ValueText:SetHide(true);
+ end
+ SetIconToSize(icon.Icon, "ICON_YIELD_GOLD_5");
+ icon.AmountText:SetText(tostring(pDealItem:GetAmount()));
+ icon.AmountText:SetHide(false);
+
+ -- Show/hide unacceptable item notification
+ icon.UnacceptableIcon:SetHide(not pDealItem:IsUnacceptable());
+
+ icon.SelectButton:RegisterCallback(Mouse.eRClick, function(void1, void2, self) OnRemoveDealItem(player, dealItemID, self); end);
+ icon.SelectButton:RegisterCallback( Mouse.eLClick, function(void1, void2, self) OnSelectValueDealItem(player, dealItemID, self); end );
+ icon.SelectButton:SetToolTipString(nil); -- We recycle the entries, so make sure this is clear.
+ icon.SelectButton:SetDisabled(false);
+ icon.Icon:SetColor(1, 1, 1);
+ if (dealItemID == g_ValueEditDealItemID) then
+ g_ValueEditDealItemControlTable = icon;
+ end
+ else
+ if (type == DealItemTypes.RESOURCES) then
+
+ local resourceType = pDealItem:GetValueType();
+ local icon;
+ if (iDuration == 0) then
+ -- One time
+ icon = g_IconOnlyIM:GetInstance(iconList);
+ else
+ -- Multi-turn
+ icon = g_IconAndTextIM:GetInstance(iconList);
+ icon.IconText:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_FOR_TURNS", iDuration);
+ icon.ValueText:SetHide(true);
+ end
+ local resourceDesc = GameInfo.Resources[resourceType];
+ SetIconToSize(icon.Icon, "ICON_" .. resourceDesc.ResourceType);
+ icon.AmountText:SetText(tostring(pDealItem:GetAmount()));
+ icon.AmountText:SetHide(false);
+
+ -- Show/hide unacceptable item notification
+ icon.UnacceptableIcon:SetHide(not pDealItem:IsUnacceptable());
+
+ local szToolTip = Locale.Lookup(resourceDesc.Name);
+
+ local parentDealItem = pDeal:GetItemParent(pDealItem);
+
+ if parentDealItem == nil then
+ -- No parent, the user can click on the item to change it.
+ icon.SelectButton:RegisterCallback(Mouse.eRClick, function(void1, void2, self) OnRemoveDealItem(player, dealItemID, self); end);
+ icon.SelectButton:RegisterCallback( Mouse.eLClick, function(void1, void2, self) OnSelectValueDealItem(player, dealItemID, self); end );
+ icon.SelectButton:SetDisabled(false);
+ icon.Icon:SetColor(1, 1, 1);
+ else
+ icon.SelectButton:ClearCallback( Mouse.eRClick ); -- Clear, we are re-using control instances
+ icon.SelectButton:ClearCallback( Mouse.eLClick );
+
+ szToolTip = szToolTip .. GetParentItemTransferToolTip(parentDealItem);
+ end
+
+ -- Set a tool tip
+ icon.SelectButton:SetToolTipString(szToolTip);
+
+ -- KWG: Make a way for the icon manager to have categories, so the API is like this
+ -- icon.Icon:SetTexture(IconManager:FindIconAtlasForType(IconTypes.RESOURCE, resourceType));
+
+ if (dealItemID == g_ValueEditDealItemID) then
+ g_ValueEditDealItemControlTable = icon;
+ end
+ end --end else if the item isn't gold
+ end -- end for each item in dael
+ end -- end if deal
+ end
+
+ iconList:CalculateSize();
+ iconList:ReprocessAnchoring();
+
+ end
+
+end
+
+-- ===========================================================================
+function PopulateDealAgreements(player : table, iconList : table)
+
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ local playerType = GetPlayerType(player);
+ if (pDeal ~= nil) then
+
+ local pDealItem;
+ for pDealItem in pDeal:Items() do
+
+ local type = pDealItem:GetType();
+ if (pDealItem:GetFromPlayerID() == player:GetID()) then
+ local dealItemID = pDealItem:GetID();
+ -- Agreement?
+ if (type == DealItemTypes.AGREEMENTS) then
+ local icon = g_IconAndTextIM:GetInstance(iconList);
+ local info: table = GameInfo.DiplomaticActions[ pDealItem:GetSubType() ];
+ if (info ~= nil) then
+ SetIconToSize(icon.Icon, "ICON_".. info.DiplomaticActionType, 38);
+ end
+
+ icon.AmountText:SetHide(true);
+ local subTypeDisplayName = pDealItem:GetSubTypeNameID();
+ if (subTypeDisplayName ~= nil) then
+ icon.IconText:LocalizeAndSetText(subTypeDisplayName);
+ end
+ icon.SelectButton:SetToolTipString(nil); -- We recycle the entries, so make sure this is clear.
+
+ -- Show/hide unacceptable item notification
+ icon.UnacceptableIcon:SetHide(not pDealItem:IsUnacceptable());
+
+ -- Populate the value pulldown
+ SetValueText(icon, pDealItem);
+
+ icon.SelectButton:RegisterCallback(Mouse.eRClick, function(void1, void2, self) OnRemoveDealItem(player, dealItemID, self); end);
+
+ if(info.DiplomaticActionType == "DIPLOACTION_JOINT_WAR" and pDealItem:GetFromPlayerID() == g_OtherPlayer:GetID()) then
+ icon.SelectButton:SetDisabled(true);
+ icon.SelectButton:SetToolTipString(Locale.Lookup("LOC_JOINT_WAR_CANNOT_EDIT_THEIRS_TOOLTIP"));
+ else
+ icon.SelectButton:SetDisabled(false);
+ icon.SelectButton:RegisterCallback( Mouse.eLClick, function(void1, void2, self) OnSelectValueDealItem(player, dealItemID, self); end );
+ icon.Icon:SetColor(1, 1, 1);
+ end
+ end
+ end
+ end
+
+ iconList:CalculateSize();
+ iconList:ReprocessAnchoring();
+
+ end
+
+end
+
+-- ===========================================================================
+function PopulateDealGreatWorks(player : table, iconList : table)
+
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ local playerType = GetPlayerType(player);
+ if (pDeal ~= nil) then
+
+ local pDealItem;
+ for pDealItem in pDeal:Items() do
+
+ local type = pDealItem:GetType();
+ if (pDealItem:GetFromPlayerID() == player:GetID()) then
+ local iDuration = pDealItem:GetDuration();
+ local dealItemID = pDealItem:GetID();
+
+ if (type == DealItemTypes.GREATWORK) then
+ local icon = g_IconAndTextIM:GetInstance(iconList);
+
+ local typeID = pDealItem:GetValueTypeID();
+ SetIconToSize(icon.Icon, "ICON_" .. typeID, 45);
+ icon.AmountText:SetHide(true);
+
+ local typeName = pDealItem:GetValueTypeNameID();
+
+ local strTooltip :string = "";
+
+ if (typeName ~= nil) then
+ icon.IconText:LocalizeAndSetText(typeName);
+ strTooltip = Locale.Lookup( GreatWorksSupport_GetBasicTooltip(pDealItem:GetValueType(), false) );
+ else
+ icon.IconText:SetText(nil);
+ end
+
+ icon.ValueText:SetHide(true);
+
+ -- Show/hide unacceptable item notification
+ icon.UnacceptableIcon:SetHide(not pDealItem:IsUnacceptable());
+
+ local parentDealItem = pDeal:GetItemParent(pDealItem);
+
+ if parentDealItem == nil then
+ -- No parent, we can remove independently
+ icon.SelectButton:RegisterCallback(Mouse.eRClick, function(void1, void2, self) OnRemoveDealItem(player, dealItemID, self); end);
+ icon.SelectButton:RegisterCallback( Mouse.eLClick, function(void1, void2, self) OnSelectValueDealItem(player, dealItemID, self); end );
+ icon.SelectButton:SetDisabled(false);
+ icon.Icon:SetColor(1, 1, 1);
+ else
+ icon.SelectButton:ClearCallback( Mouse.eRClick );
+ icon.SelectButton:ClearCallback( Mouse.eLClick );
+ -- Add on to the tool tip to show why it is there.
+ strTooltip = strTooltip .. GetParentItemTransferToolTip(parentDealItem);
+ end
+
+ icon.SelectButton:SetToolTipString(strTooltip);
+ end
+ end
+ end
+
+ iconList:CalculateSize();
+ iconList:ReprocessAnchoring();
+
+ end
+
+end
+
+-- ===========================================================================
+function PopulateDealCaptives(player : table, iconList : table)
+
+ PopulateDealBasic(player, iconList, DealItemTypes.CAPTIVE, "ICON_UNIT_SPY");
+
+end
+
+-- ===========================================================================
+function PopulateDealCities(player : table, iconList : table)
+
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ local playerType = GetPlayerType(player);
+ if (pDeal ~= nil) then
+
+ local pDealItem;
+ for pDealItem in pDeal:Items() do
+
+ local type = pDealItem:GetType();
+ if (pDealItem:GetFromPlayerID() == player:GetID()) then
+ local dealItemID = pDealItem:GetID();
+
+ if (type == DealItemTypes.CITIES) then
+ local icon = g_IconAndTextIM:GetInstance(iconList);
+ SetIconToSize(icon.Icon, "ICON_BUILDINGS");
+ icon.AmountText:SetHide(true);
+ local typeName = pDealItem:GetValueTypeNameID();
+ if (typeName ~= nil) then
+ icon.IconText:LocalizeAndSetText(typeName);
+ end
+
+ -- Show/hide unacceptable item notification
+ icon.UnacceptableIcon:SetHide(not pDealItem:IsUnacceptable());
+
+ icon.SelectButton:RegisterCallback(Mouse.eRClick, function(void1, void2, self) OnRemoveDealItem(player, dealItemID, self); end);
+ icon.SelectButton:RegisterCallback( Mouse.eLClick, function(void1, void2, self) OnSelectValueDealItem(player, dealItemID, self); end );
+ icon.SelectButton:SetDisabled(false);
+ icon.Icon:SetColor(1, 1, 1);
+
+ icon.SelectButton:SetToolTipString( MakeCityToolTip(player, pDealItem:GetValueType() ) );
+ end
+ end
+ end
+
+ iconList:CalculateSize();
+ iconList:ReprocessAnchoring();
+
+ end
+
+
+end
+
+-- ===========================================================================
+function PopulatePlayerDealPanel(rootControl : table, player : table)
+
+ if (player ~= nil) then
+
+ local playerType = GetPlayerType(player);
+ PopulateDealResources(player, ms_DealGroups[DealItemGroupTypes.RESOURCES][playerType]);
+ PopulateDealAgreements(player, ms_DealGroups[DealItemGroupTypes.AGREEMENTS][playerType]);
+ PopulateDealCaptives(player, ms_DealGroups[DealItemGroupTypes.CAPTIVES][playerType]);
+ PopulateDealGreatWorks(player, ms_DealGroups[DealItemGroupTypes.GREAT_WORKS][playerType]);
+ PopulateDealCities(player, ms_DealGroups[DealItemGroupTypes.CITIES][playerType]);
+
+ rootControl:CalculateSize();
+ rootControl:ReprocessAnchoring();
+ end
+end
+
+-- ===========================================================================
+function HandleESC()
+ -- Were we just viewing the deal?
+ if ( m_kPopupDialog:IsOpen()) then
+ m_kPopupDialog:Close();
+ elseif (not Controls.ResumeGame:IsHidden()) then
+ OnResumeGame();
+ else
+ OnRefuseDeal();
+ end
+end
+
+-- ===========================================================================
+-- INPUT Handlings
+-- If this context is visible, it will get a crack at the input.
+-- ===========================================================================
+function KeyHandler( key:number )
+ if (key == Keys.VK_ESCAPE) then
+ HandleESC();
+ return true;
+ end
+
+ return false;
+end
+
+-- ===========================================================================
+function InputHandler( pInputStruct:table )
+ local uiMsg = pInputStruct:GetMessageType();
+ if uiMsg == KeyEvents.KeyUp then
+ return KeyHandler( pInputStruct:GetKey() );
+ end
+ if (uiMsg == MouseEvents.LButtonUp or
+ uiMsg == MouseEvents.RButtonUp or
+ uiMsg == MouseEvents.MButtonUp or
+ uiMsg == MouseEvents.PointerUp) then
+ ClearValueEdit();
+ end
+
+ return false;
+end
+
+-- ===========================================================================
+-- Handle a request to be shown, this should only be called by
+-- the diplomacy statement handler.
+-- ===========================================================================
+
+function OnShowMakeDeal(otherPlayerID)
+ ms_OtherPlayerID = otherPlayerID;
+ ms_bIsDemand = false;
+ ContextPtr:SetHide( false );
+end
+LuaEvents.DiploPopup_ShowMakeDeal.Add(OnShowMakeDeal);
+
+-- ===========================================================================
+-- Handle a request to be shown, this should only be called by
+-- the diplomacy statement handler.
+-- ===========================================================================
+
+function OnShowMakeDemand(otherPlayerID)
+ ms_OtherPlayerID = otherPlayerID;
+ ms_bIsDemand = true;
+ ContextPtr:SetHide( false );
+end
+LuaEvents.DiploPopup_ShowMakeDemand.Add(OnShowMakeDemand);
+
+-- ===========================================================================
+-- Handle a request to be hidden, this should only be called by
+-- the diplomacy statement handler.
+-- ===========================================================================
+
+function OnHideDeal(otherPlayerID)
+ OnContinue();
+end
+LuaEvents.DiploPopup_HideDeal.Add(OnHideDeal);
+
+-- ===========================================================================
+-- The other player has updated the deal
+function OnDiplomacyIncomingDeal(eFromPlayer, eToPlayer, eAction)
+ if (eFromPlayer == ms_OtherPlayerID) then
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.INCOMING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ if (pDeal ~= nil) then
+ ms_bIsGift = pDeal:IsGift();
+
+ -- Copy the deal to our OUTGOING deal back to the other player, in case we want to make modifications
+ DealManager.CopyIncomingToOutgoingWorkingDeal(g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ ms_LastIncomingDealProposalAction = eAction;
+
+ PopulatePlayerDealPanel(Controls.TheirOfferStack, g_OtherPlayer);
+ PopulatePlayerDealPanel(Controls.MyOfferStack, g_LocalPlayer);
+ UpdateDealStatus();
+ end
+ end
+end
+Events.DiplomacyIncomingDeal.Add(OnDiplomacyIncomingDeal);
+
+-- ===========================================================================
+-- Handle a deal changing, usually from an incoming statement.
+-- ===========================================================================
+
+function OnDealUpdated(otherPlayerID, eAction, szText)
+ if (not ContextPtr:IsHidden()) then
+ -- Display some updated text.
+ if (szText ~= nil and szText ~= "") then
+ SetLeaderDialog(szText, "");
+ end
+ -- Update deal and possible override text from szText
+ OnDiplomacyIncomingDeal( otherPlayerID, Game.GetLocalPlayer(), eAction);
+ end
+end
+LuaEvents.DiploPopup_DealUpdated.Add(OnDealUpdated);
+
+-- ===========================================================================
+function SetLeaderDialog(leaderDialog:string, leaderEffect:string)
+ -- Update dialog
+ Controls.LeaderDialog:LocalizeAndSetText(leaderDialog);
+
+ -- Add parentheses to the effect text unless the text is ""
+ if leaderEffect ~= "" then
+ leaderEffect = "(" .. Locale.Lookup(leaderEffect) .. ")";
+ end
+ Controls.LeaderEffect:SetText(leaderEffect);
+
+ -- Recenter text
+ Controls.LeaderDialogStack:CalculateSize();
+ Controls.LeaderDialogStack:ReprocessAnchoring();
+end
+
+-- ===========================================================================
+function StartExitAnimation()
+ -- Start the exit animation, it will call OnContinue when complete
+ ms_bExiting = true;
+ Controls.YieldSlide:Reverse();
+ Controls.YieldAlpha:Reverse();
+ Controls.TradePanelFade:Reverse();
+ Controls.TradePanelSlide:Reverse();
+ Controls.TradePanelFade:SetSpeed(5);
+ Controls.TradePanelSlide:SetSpeed(5);
+ UI.PlaySound("UI_Diplomacy_Menu_Change");
+end
+
+-- ===========================================================================
+function OnContinue()
+ ContextPtr:SetHide( true );
+end
+
+-- ===========================================================================
+-- Functions for setting the data in the yield area
+-- ===========================================================================
+
+function FormatValuePerTurn( value:number )
+ return Locale.ToNumber(value, "+#,###.#;-#,###.#");
+end
+
+function RefreshYields()
+
+ local ePlayer :number = Game.GetLocalPlayer();
+ local localPlayer :table= nil;
+ if ePlayer ~= -1 then
+ localPlayer = Players[ePlayer];
+ if localPlayer == nil then
+ return;
+ end
+ else
+ return;
+ end
+
+ ---- SCIENCE ----
+ local playerTechnology :table = localPlayer:GetTechs();
+ local currentScienceYield :number = playerTechnology:GetScienceYield();
+ Controls.SciencePerTurn:SetText( FormatValuePerTurn(currentScienceYield) );
+ Controls.ScienceBacking:SetToolTipString( GetScienceTooltip() );
+ Controls.ScienceStack:CalculateSize();
+
+ ---- CULTURE----
+ local playerCulture :table = localPlayer:GetCulture();
+ local currentCultureYield :number = playerCulture:GetCultureYield();
+ Controls.CulturePerTurn:SetText( FormatValuePerTurn(currentCultureYield) );
+ Controls.CultureBacking:SetToolTipString( GetCultureTooltip() );
+ Controls.CultureStack:CalculateSize();
+
+ ---- GOLD ----
+ local playerTreasury:table = localPlayer:GetTreasury();
+ local goldYield :number = playerTreasury:GetGoldYield() - playerTreasury:GetTotalMaintenance();
+ local goldBalance :number = math.floor(playerTreasury:GetGoldBalance());
+ Controls.GoldBalance:SetText( Locale.ToNumber(goldBalance, "#,###.#"));
+ Controls.GoldPerTurn:SetText( FormatValuePerTurn(goldYield) );
+ Controls.GoldBacking:SetToolTipString(GetGoldTooltip());
+ Controls.GoldStack:CalculateSize();
+
+ ---- FAITH ----
+ local playerReligion :table = localPlayer:GetReligion();
+ local faithYield :number = playerReligion:GetFaithYield();
+ local faithBalance :number = playerReligion:GetFaithBalance();
+ Controls.FaithBalance:SetText( Locale.ToNumber(faithBalance, "#,###.#"));
+ Controls.FaithPerTurn:SetText( FormatValuePerTurn(faithYield) );
+ Controls.FaithBacking:SetToolTipString( GetFaithTooltip() );
+ Controls.FaithStack:CalculateSize();
+ if (faithYield == 0) then
+ Controls.FaithBacking:SetHide(true);
+ else
+ Controls.FaithBacking:SetHide(false);
+ end
+
+ Controls.YieldStack:CalculateSize();
+ Controls.YieldStack:ReprocessAnchoring();
+end
+-- ===========================================================================
+
+-- ===========================================================================
+function OnShow()
+ RefreshYields();
+ Controls.YieldAlpha:SetToBeginning();
+ Controls.YieldAlpha:Play();
+ Controls.YieldSlide:SetToBeginning();
+ Controls.YieldSlide:Play();
+ Controls.TradePanelFade:SetToBeginning();
+ Controls.TradePanelFade:Play();
+ Controls.TradePanelSlide:SetToBeginning();
+ Controls.TradePanelSlide:Play();
+ Controls.LeaderDialogFade:SetToBeginning();
+ Controls.LeaderDialogFade:Play();
+ Controls.LeaderDialogSlide:SetToBeginning();
+ Controls.LeaderDialogSlide:Play();
+ Controls.ValueEditPopupBackground:SetHide(true);
+
+ g_IconOnlyIM:ResetInstances();
+ g_IconAndTextIM:ResetInstances();
+
+ ms_bExiting = false;
+
+ if (Game.GetLocalPlayer() == -1) then
+ return;
+ end
+
+ -- For hotload testing, force the other player to be valid
+ if (ms_OtherPlayerID == -1) then
+ local playerID = 0
+ for playerID = 0, GameDefines.MAX_PLAYERS-1, 1 do
+ if (playerID ~= Game.GetLocalPlayer() and Players[playerID]:IsAlive()) then
+ ms_OtherPlayerID = playerID;
+ break;
+ end
+ end
+ end
+
+ -- Set up some globals for easy access
+ g_LocalPlayer = Players[Game.GetLocalPlayer()];
+ g_OtherPlayer = Players[ms_OtherPlayerID];
+ ms_OtherPlayerIsHuman = g_OtherPlayer:IsHuman();
+
+ local sessionID = DiplomacyManager.FindOpenSessionID(Game.GetLocalPlayer(), g_OtherPlayer:GetID());
+ if (sessionID ~= nil) then
+ local sessionInfo = DiplomacyManager.GetSessionInfo(sessionID);
+ ms_InitiatedByPlayerID = sessionInfo.FromPlayer;
+ end
+
+ -- Did the AI start this or the human?
+ if (ms_InitiatedByPlayerID == ms_OtherPlayerID) then
+ ms_LastIncomingDealProposalAction = DealProposalAction.PROPOSED;
+
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.INCOMING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ ms_bIsGift = pDeal:IsGift();
+
+ DealManager.CopyIncomingToOutgoingWorkingDeal(g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.INCOMING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ ms_bIsGift = pDeal:IsGift();
+ else
+ ms_LastIncomingDealProposalAction = DealProposalAction.PENDING;
+ -- We are NOT clearing the current outgoing deal. This allows other screens to pre-populate the deal.
+ end
+
+ UpdateOtherPlayerText(1);
+ SetDefaultLeaderDialogText();
+
+ local iAvailableItemCount = 0;
+ -- Available content to trade. Shouldn't change during the session, but it might, especially in multiplayer.
+ iAvailableItemCount = iAvailableItemCount + PopulatePlayerAvailablePanel(Controls.MyInventoryStack, g_LocalPlayer);
+ iAvailableItemCount = iAvailableItemCount + PopulatePlayerAvailablePanel(Controls.TheirInventoryStack, g_OtherPlayer);
+
+ Controls.MyInventoryScroll:CalculateSize();
+ Controls.TheirInventoryScroll:CalculateSize();
+
+ m_kPopupDialog:Close(); -- Close and reset the popup in case it's open
+
+ if (iAvailableItemCount == 0) then
+ if (ms_bIsDemand) then
+ m_kPopupDialog:AddText(Locale.Lookup("LOC_DIPLO_DEMAND_NO_AVAILABLE_ITEMS"));
+ m_kPopupDialog:AddTitle( Locale.ToUpper(Locale.Lookup("LOC_DIPLO_CHOICE_MAKE_DEMAND")))
+ m_kPopupDialog:AddButton( Locale.Lookup("LOC_OK_BUTTON"), OnRefuseDeal);
+ else
+ m_kPopupDialog:AddText( Locale.Lookup("LOC_DIPLO_DEAL_NO_AVAILABLE_ITEMS"));
+ m_kPopupDialog:AddTitle( Locale.ToUpper(Locale.Lookup("LOC_DIPLO_CHOICE_MAKE_DEAL")))
+ m_kPopupDialog:AddButton( Locale.Lookup("LOC_OK_BUTTON"), OnRefuseDeal);
+ end
+ m_kPopupDialog:Open();
+ end
+
+ PopulatePlayerDealPanel(Controls.TheirOfferStack, g_OtherPlayer);
+ PopulatePlayerDealPanel(Controls.MyOfferStack, g_LocalPlayer);
+ UpdateDealStatus();
+
+ -- We may be coming into this screen with a deal already set, which needs to be sent to the AI for inspection. Check that.
+ -- Don't send AI proposals for inspection or they will think the player was the creator of the deal
+ if (IsAutoPropose() and (ms_InitiatedByPlayerID ~= ms_OtherPlayerID or ms_OtherPlayerIsHuman)) then
+ ProposeWorkingDeal(true);
+ end
+
+ Controls.MyOfferScroll:CalculateSize();
+ Controls.TheirOfferScroll:CalculateSize();
+
+ LuaEvents.DiploBasePopup_HideUI(true);
+ TTManager:ClearCurrent(); -- Clear any tool tips raised;
+
+ Controls.DealOptionsStack:CalculateSize();
+ Controls.DealOptionsStack:ReprocessAnchoring();
+end
+
+----------------------------------------------------------------
+function OnHide()
+ LuaEvents.DiploBasePopup_HideUI(false);
+end
+
+-- ===========================================================================
+-- Context CTOR
+-- ===========================================================================
+function OnInit( isHotload )
+ LateInitialize();
+
+ if (isHotload and not ContextPtr:IsHidden()) then
+ OnShow();
+ end
+end
+
+-- ===========================================================================
+-- Context DESTRUCTOR
+-- Not called when screen is dismissed, only if the whole context is removed!
+-- ===========================================================================
+function OnShutdown()
+
+end
+
+-- ===========================================================================
+function OnLocalPlayerTurnEnd()
+ if (not ContextPtr:IsHidden()) then
+ -- Were we just viewing the deal?
+ if (not Controls.ResumeGame:IsHidden()) then
+ OnResumeGame();
+ else
+ OnRefuseDeal(true);
+ end
+ OnContinue();
+ end
+end
+
+-- ===========================================================================
+function OnPlayerDefeat( player, defeat, eventID)
+ local localPlayer = Game.GetLocalPlayer();
+ if (localPlayer and localPlayer >= 0) then -- Check to see if there is any local player
+ -- Was it the local player?
+ if (localPlayer == player) then
+ OnLocalPlayerTurnEnd();
+ end
+ end
+end
+
+-- ===========================================================================
+function OnTeamVictory(team, victory, eventID)
+
+ local localPlayer = Game.GetLocalPlayer();
+ if (localPlayer and localPlayer >= 0) then -- Check to see if there is any local player
+ OnLocalPlayerTurnEnd();
+ end
+end
+
+-- ===========================================================================
+-- Engine Event
+-- ===========================================================================
+function OnUserRequestClose()
+ -- Is this showing; if so then it needs to raise dialog to handle close
+ if (not ContextPtr:IsHidden()) then
+ m_kPopupDialog:Reset();
+ m_kPopupDialog:AddText(Locale.Lookup("LOC_CONFIRM_EXIT_TXT"));
+ m_kPopupDialog:AddButton(Locale.Lookup("LOC_NO"), nil);
+ m_kPopupDialog:AddButton(Locale.Lookup("LOC_YES"), OnQuitYes, nil, nil, "PopupButtonInstanceRed");
+ m_kPopupDialog:Open();
+ end
+end
+function OnQuitYes()
+ Events.UserConfirmedClose();
+end
+
+-- ===========================================================================
+function LateInitialize()
+ CreateGroupTypes();
+ InitializeDealGroups();
+ CreatePanels();
+end
+
+-- ===========================================================================
+function Initialize()
+
+ ContextPtr:SetInitHandler( OnInit );
+ ContextPtr:SetInputHandler( InputHandler, true );
+ ContextPtr:SetShutdown( OnShutdown );
+ ContextPtr:SetShowHandler( OnShow );
+ ContextPtr:SetHideHandler( OnHide );
+
+ Events.LocalPlayerTurnEnd.Add( OnLocalPlayerTurnEnd );
+ Events.PlayerDefeat.Add( OnPlayerDefeat );
+ Events.TeamVictory.Add( OnTeamVictory );
+
+ Events.UserRequestClose.Add( OnUserRequestClose );
+
+ m_kPopupDialog = PopupDialog:new( "DiplomacyDealView" );
+end
+
+Initialize();
diff --git a/Replacements/DiplomacyDealView_Expansion2.lua b/Replacements/DiplomacyDealView_Expansion2.lua
new file mode 100644
index 0000000..2f93a01
--- /dev/null
+++ b/Replacements/DiplomacyDealView_Expansion2.lua
@@ -0,0 +1,290 @@
+--[[
+-- Created by Andrew Garrett
+-- Copyright (c) Firaxis Games 2018
+--]]
+
+-- ===========================================================================
+-- INCLUDES
+-- ===========================================================================
+include("DiplomacyDealView.lua");
+
+-- ===========================================================================
+-- VARIABLES
+-- ===========================================================================
+local ms_DefaultOneTimeFavorAmount = 1;
+
+-- ===========================================================================
+-- CACHE BASE FUNCTIONS
+-- ===========================================================================
+BASE_GetItemTypeIcon = GetItemTypeIcon;
+BASE_CreateGroupTypes = CreateGroupTypes;
+BASE_IsItemValueEditable = IsItemValueEditable;
+BASE_PopulateDealResources = PopulateDealResources;
+BASE_CreatePlayerAvailablePanel = CreatePlayerAvailablePanel;
+BASE_PopulatePlayerAvailablePanel = PopulatePlayerAvailablePanel;
+
+-- ===========================================================================
+-- OVERRIDE BASE FUNCTIONS
+-- ===========================================================================
+function OnClickAvailableResource(player, resourceType)
+
+ if (ms_bIsDemand == true and ms_InitiatedByPlayerID == ms_OtherPlayerID) then
+ -- Can't modifiy demand that is not ours
+ return;
+ end
+
+ local pBaseResourceDef = GameInfo.Resources[resourceType];
+ local pResourceDef = GameInfo.Resource_Consumption[pBaseResourceDef.ResourceType];
+
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, Game.GetLocalPlayer(), GetOtherPlayer():GetID());
+ if (pDeal ~= nil) then
+
+ -- Already there?
+ local dealItems = pDeal:FindItemsByType(DealItemTypes.RESOURCES, DealItemSubTypes.NONE, player:GetID());
+ local pDealItem;
+ if (dealItems ~= nil) then
+ for i, pDealItem in ipairs(dealItems) do
+ if pDealItem:GetValueType() == resourceType then
+ -- Check for non-zero duration. There may already be a one-time transfer of the resource if a city is in the deal.
+ if (pDealItem:GetDuration() ~= 0) then
+ return; -- Already in there.
+ end
+ if (pResourceDef ~= nil and pResourceDef.Accumulate) then
+ -- already have this, up the amount
+ local iAddAmount = pDealItem:GetAmount() + 1;
+ iAddAmount = clip(iAddAmount, nil, pDealItem:GetMaxAmount());
+ if (iAddAmount ~= pDealItem:GetAmount()) then
+ pDealItem:SetAmount(iAddAmount);
+
+ if not pDealItem:IsValid() then
+ pDealItem:SetAmount(iAddAmount-1);
+ return;
+ else
+ UI.PlaySound("UI_GreatWorks_Put_Down");
+ UpdateDealPanel(player);
+
+ UpdateProposedWorkingDeal();
+ return;
+ end
+ else
+ return;
+ end
+ end
+ end
+ end
+ end
+
+ -- we don't need to check how many the player has, the deal manager will reject if we try to add too many
+ local pPlayerResources = player:GetResources();
+ pDealItem = pDeal:AddItemOfType(DealItemTypes.RESOURCES, player:GetID());
+ if (pDealItem ~= nil) then
+ -- Add one
+ pDealItem:SetValueType(resourceType);
+ pDealItem:SetAmount(1);
+ if (pResourceDef ~= nil and pResourceDef.Accumulate) then
+ pDealItem:SetDuration(0);
+ else
+ pDealItem:SetDuration(30); -- Default to this many turns
+ end
+
+ -- After we add the item, test to see if the item is valid, it is possible that we have exceeded the amount of resources we can trade.
+ if not pDealItem:IsValid() then
+ pDeal:RemoveItemByID(pDealItem:GetID());
+ pDealItem = nil;
+ else
+ UI.PlaySound("UI_GreatWorks_Put_Down");
+ end
+
+ UpdateDealPanel(player);
+ UpdateProposedWorkingDeal();
+ end
+ end
+end
+
+
+-- ===========================================================================
+-- Check the state of the deal and show/hide the special proposal buttons for a possible gift (not actually possible until XP2)
+function UpdateProposalButtonsForGift(iItemsFromLocal : number, iItemsFromOther : number)
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ if (iItemsFromLocal == 0 and iItemsFromOther > 0 and not pDeal:IsGift()) then
+ return true;
+ end
+
+ return false;
+end
+
+-- ===========================================================================
+function GetItemTypeIcon(pDealItem: table)
+ if (pDealItem:GetType() == DealItemTypes.FAVOR) then
+ return "ICON_YIELD_FAVOR";
+ end
+ return BASE_GetItemTypeIcon(pDealItem);
+end
+
+-- ===========================================================================
+function CreateGroupTypes()
+ BASE_CreateGroupTypes();
+ AvailableDealItemGroupTypes.FAVOR = table.count(AvailableDealItemGroupTypes) + 1;
+ DealItemGroupTypes.FAVOR = table.count(DealItemGroupTypes) + 1;
+end
+
+-- ===========================================================================
+function IsItemValueEditable(itemType: number)
+ return BASE_IsItemValueEditable(itemType) or itemType == DealItemTypes.FAVOR;
+end
+
+-- ===========================================================================
+function PopulateDealResources(player: table, iconList: table)
+
+ BASE_PopulateDealResources(player, iconList);
+
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ local playerType = GetPlayerType(player);
+ if (pDeal ~= nil) then
+ for pDealItem in pDeal:Items() do
+ if (pDealItem:GetFromPlayerID() == player:GetID()) then
+ local type = pDealItem:GetType();
+ local iDuration = pDealItem:GetDuration();
+ local dealItemID = pDealItem:GetID();
+ -- Gold?
+ if (type == DealItemTypes.FAVOR) then
+ local icon;
+ if (iDuration == 0) then
+ -- One time
+ icon = g_IconOnlyIM:GetInstance(iconList);
+ SetIconToSize(icon.Icon, "ICON_YIELD_FAVOR");
+ icon.AmountText:SetText(tostring(pDealItem:GetAmount()));
+ icon.AmountText:SetHide(false);
+ icon.Icon:SetColor(1, 1, 1);
+
+ -- Show/hide unacceptable item notification
+ icon.UnacceptableIcon:SetHide(not pDealItem:IsUnacceptable());
+
+ icon.SelectButton:RegisterCallback(Mouse.eRClick, function(void1, void2, self) OnRemoveDealItem(player, dealItemID, self); end);
+ icon.SelectButton:RegisterCallback( Mouse.eLClick, function(void1, void2, self) OnSelectValueDealItem(player, dealItemID, self); end );
+ icon.SelectButton:SetToolTipString(nil); -- We recycle the entries, so make sure this is clear.
+ icon.SelectButton:SetDisabled(false);
+ if (dealItemID == g_ValueEditDealItemID) then
+ g_ValueEditDealItemControlTable = icon;
+ end
+ else
+ -- Multi-turn
+ UI.DataError("Favor can only be traded in lump sums, but gamecore is indicating duration. This may be an issue @sbatista & @agarrett");
+ end
+ end -- end for each item in deal
+ end -- end if deal
+ end
+ end
+
+end
+
+-- ===========================================================================
+function CreatePlayerAvailablePanel(playerType: number, rootControl: table)
+ g_AvailableGroups[AvailableDealItemGroupTypes.FAVOR][playerType] = CreateHorizontalGroup(rootControl);
+ return BASE_CreatePlayerAvailablePanel(playerType, rootControl);
+end
+
+-- ===========================================================================
+function PopulatePlayerAvailablePanel(rootControl: table, player: table)
+
+ local playerType = GetPlayerType(player);
+ local iAvailableItemCount = PopulateAvailableFavor(player, g_AvailableGroups[AvailableDealItemGroupTypes.FAVOR][playerType]);
+ iAvailableItemCount = iAvailableItemCount + BASE_PopulatePlayerAvailablePanel(rootControl, player);
+ return iAvailableItemCount;
+end
+
+function PopulateAvailableFavor(player: table, iconList: table)
+
+ local iAvailableItemCount = 0;
+
+ local eFromPlayerID = player:GetID();
+ local eToPlayerID = GetOtherPlayer(player):GetID();
+
+ local pForDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ local possibleResources = DealManager.GetPossibleDealItems(eFromPlayerID, eToPlayerID, DealItemTypes.FAVOR, pForDeal);
+ if ((possibleResources ~= nil) and (player:GetFavor() > 0)) then
+ for i, entry in ipairs(possibleResources) do
+ -- One time favor
+ local favorBalance:number = player:GetFavor();
+
+ if (not ms_bIsDemand) then
+ local icon = g_IconOnlyIM:GetInstance(iconList.ListStack);
+ icon.AmountText:SetText(favorBalance);
+ icon.SelectButton:SetToolTipString(Locale.Lookup("LOC_DIPLOMATIC_FAVOR_NAME")); -- We recycle the entries, so make sure this is clear.
+ SetIconToSize(icon.Icon, "ICON_YIELD_FAVOR");
+ icon.SelectButton:RegisterCallback( Mouse.eLClick, function() OnClickAvailableOneTimeFavor(player, ms_DefaultOneTimeFavorAmount); end );
+ icon.SelectButton:RegisterCallback( Mouse.eLClick, function() OnClickAvailableOneTimeFavor(player, ms_DefaultOneTimeFavorAmount); end );
+ icon.Icon:SetColor(1, 1, 1);
+ icon.SelectButton:SetDisabled(false);
+
+ iAvailableItemCount = iAvailableItemCount + 1;
+ end
+ end
+ end
+
+ return iAvailableItemCount;
+end
+
+-- ===========================================================================
+function OnClickAvailableOneTimeFavor(player, iAddAmount: number)
+
+ if (ms_bIsDemand == true and ms_InitiatedByPlayerID == ms_OtherPlayerID) then
+ -- Can't modifiy demand that is not ours
+ return;
+ end
+
+ local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
+ if (pDeal ~= nil) then
+
+ local bFound = false;
+
+ -- Already there?
+ local dealItems = pDeal:FindItemsByType(DealItemTypes.FAVOR, DealItemSubTypes.NONE, player:GetID());
+ local pDealItem;
+ if (dealItems ~= nil) then
+ for i, pDealItem in ipairs(dealItems) do
+ if (pDealItem:GetDuration() == 0) then
+ -- Already have a one time favor. Up the amount
+ iAddAmount = pDealItem:GetAmount() + iAddAmount;
+ iAddAmount = clip(iAddAmount, nil, pDealItem:GetMaxAmount());
+ if (iAddAmount ~= pDealItem:GetAmount()) then
+ pDealItem:SetAmount(iAddAmount);
+ bFound = true;
+ break;
+ else
+ return; -- No change, just exit
+ end
+ end
+ end
+ end
+
+ -- Doesn't exist yet, add it.
+ if (not bFound) then
+
+ -- Going to add anything?
+ pDealItem = pDeal:AddItemOfType(DealItemTypes.FAVOR, player:GetID());
+ if (pDealItem ~= nil) then
+
+ -- Set the duration, so the max amount calculation knows what we are doing
+ pDealItem:SetDuration(0);
+
+ -- Adjust the favor to our max
+ iAddAmount = clip(iAddAmount, nil, pDealItem:GetMaxAmount());
+ if (iAddAmount > 0) then
+ pDealItem:SetAmount(iAddAmount);
+ bFound = true;
+ else
+ -- It is empty, remove it.
+ local itemID = pDealItem:GetID();
+ pDeal:RemoveItemByID(itemID);
+ end
+ end
+ end
+
+
+ if (bFound) then
+ UpdateProposedWorkingDeal();
+ UpdateDealPanel(player);
+ end
+ end
+end
diff --git a/Replacements/DiplomacyRibbon.xml b/Replacements/DiplomacyRibbon.xml
new file mode 100644
index 0000000..5834067
--- /dev/null
+++ b/Replacements/DiplomacyRibbon.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Replacements/DiplomacyRibbon_Expansion1.lua b/Replacements/DiplomacyRibbon_Expansion1.lua
index efbb8d8..51c6d61 100644
--- a/Replacements/DiplomacyRibbon_Expansion1.lua
+++ b/Replacements/DiplomacyRibbon_Expansion1.lua
@@ -1,5 +1,6 @@
--- Copyright 2017-2018, Firaxis Games.-- ===========================================================================
+-- Copyright 2017-2018, Firaxis Games.
+-- ===========================================================================
-- Base File
-- ===========================================================================
include("DiplomacyRibbon");
diff --git a/Replacements/DiplomacyRibbon_Expansion2.lua b/Replacements/DiplomacyRibbon_Expansion2.lua
new file mode 100644
index 0000000..1857e9f
--- /dev/null
+++ b/Replacements/DiplomacyRibbon_Expansion2.lua
@@ -0,0 +1,88 @@
+-- Copyright 2018, Firaxis Games.
+
+-- ===========================================================================
+-- INCLUDES
+-- ===========================================================================
+include("DiplomacyRibbon_Expansion1.lua");
+include("GameCapabilities");
+include("CongressButton");
+
+
+-- ===========================================================================
+-- OVERRIDE BASE FUNCTIONS
+-- ===========================================================================
+BASE_LateInitialize = LateInitialize;
+BASE_UpdateLeaders = UpdateLeaders;
+BASE_RealizeSize = RealizeSize;
+
+
+-- ===========================================================================
+-- MEMBERS
+-- ===========================================================================
+local m_kCongressButtonIM :table = nil;
+local m_uiCongressButtonInstance:table = nil;
+local m_congressButtonWidth :number = 0;
+
+-- ===========================================================================
+-- FUNCTIONS
+-- ===========================================================================
+
+-- ===========================================================================
+function UpdateLeaders()
+ -- Create and add World Congress button if one was allocated (based on capabilities)
+ if m_kCongressButtonIM then
+ if Game.GetEras():GetCurrentEra() >= GlobalParameters.WORLD_CONGRESS_INITIAL_ERA then
+ m_kCongressButtonIM:ResetInstances();
+ local congressProgButtonClass:table = {};
+ kCongressButton, m_uiCongressButtonInstance = CongressButton:GetInstance( m_kCongressButtonIM );
+ m_congressButtonWidth = m_uiCongressButtonInstance.Top:GetSizeX();
+ end
+ end
+
+ BASE_UpdateLeaders();
+end
+
+
+-- ===========================================================================
+function RealizeSize( additionalElementsWidth:number )
+ BASE_RealizeSize( m_congressButtonWidth );
+ --The Congress button takes up one leader slot, so the max num of leaders used to calculate scroll is reduced by one in XP2
+ g_maxNumLeaders = g_maxNumLeaders - 1;
+end
+
+-- ===========================================================================
+function OnLeaderClicked(playerID : number )
+ -- Send an event to open the leader in the diplomacy view (only if they met)
+ local pWorldCongress:table = Game.GetWorldCongress();
+ local localPlayerID:number = Game.GetLocalPlayer();
+ if playerID == localPlayerID or Players[localPlayerID]:GetDiplomacy():HasMet(playerID) then
+ if pWorldCongress:IsInSession() then
+ LuaEvents.DiplomacyActionView_OpenLite(playerID);
+ else
+ LuaEvents.DiplomacyRibbon_OpenDiplomacyActionView(playerID);
+ end
+ end
+end
+
+-- ===========================================================================
+function LateInitialize()
+
+ BASE_LateInitialize();
+
+ Events.DiplomacyRelationshipChanged.Add( UpdateLeaders );
+ Events.MultiplayerPlayerConnected.Add(UpdateLeaders);
+ Events.MultiplayerPostPlayerDisconnected.Add(UpdateLeaders);
+ Events.LocalPlayerChanged.Add(UpdateLeaders);
+ Events.PlayerInfoChanged.Add(UpdateLeaders);
+ Events.PlayerDefeat.Add(UpdateLeaders);
+ Events.PlayerRestored.Add(UpdateLeaders);
+ Events.LocalPlayerTurnBegin.Add(UpdateLeaders);
+
+ if HasCapability("CAPABILITY_WORLD_CONGRESS") then
+ m_kCongressButtonIM = InstanceManager:new("CongressButton", "Top", Controls.LeaderStack);
+ end
+
+ if not XP2_LateInitialize then -- Only update leaders if this is the last in the call chain.
+ UpdateLeaders();
+ end
+end
diff --git a/Replacements/EndGameMenu_Expansion2.lua b/Replacements/EndGameMenu_Expansion2.lua
new file mode 100644
index 0000000..9a27f91
--- /dev/null
+++ b/Replacements/EndGameMenu_Expansion2.lua
@@ -0,0 +1,13 @@
+include("GameCapabilities");
+
+-- Add the new victory type
+Styles["VICTORY_DIPLOMATIC"] = {
+ RibbonIcon = "ICON_VICTORY_DIPLOMATIC",
+ Ribbon = "EndGame_Ribbon_Diplomatic",
+ RibbonTile = "EndGame_RibbonTile_Diplomatic",
+ Background = "EndGame_BG_Time",
+ Movie = "XP2Victory_Diplomatic.bk2",
+ SndStart = "Play_Cinematic_Endgame_Diplomatic",
+ SndStop = "Stop_Cinematic_Endgame_Diplomatic",
+ Color = "COLOR_VICTORY_DIPLOMATIC",
+};
diff --git a/Replacements/FullscreenMapPopup_Expansion2.lua b/Replacements/FullscreenMapPopup_Expansion2.lua
new file mode 100644
index 0000000..0b5c40c
--- /dev/null
+++ b/Replacements/FullscreenMapPopup_Expansion2.lua
@@ -0,0 +1,23 @@
+-- Copyright 2018, Firaxis Games
+include( "FullscreenMapPopup" );
+
+-- ===========================================================================
+-- Super functions
+-- ===========================================================================
+BASE_LateInitialize = LateInitialize;
+
+
+-- ===========================================================================
+-- Game EVENT
+-- ===========================================================================
+function OnWorldCongressStage1()
+ if UIManager:IsInPopupQueue( ContextPtr ) then
+ Close();
+ end
+end
+
+-- ===========================================================================
+function LateInitialize()
+ BASE_LateInitialize();
+ Events.WorldCongressStage1.Add( OnWorldCongressStage1 );
+end
diff --git a/Replacements/GovernmentScreen_Expansion1.lua b/Replacements/GovernmentScreen_Expansion1.lua
index e75ddc1..a13f5c3 100644
--- a/Replacements/GovernmentScreen_Expansion1.lua
+++ b/Replacements/GovernmentScreen_Expansion1.lua
@@ -52,3 +52,4 @@ function RealizeFilterTabs()
BASE_RealizeFilterTabs();
CreatePolicyTabButton("LOC_GOVT_FILTER_DARK", FilterDarkPolicies);
end
+
diff --git a/Replacements/GovernmentScreen_Expansion2.lua b/Replacements/GovernmentScreen_Expansion2.lua
new file mode 100644
index 0000000..7bf87a4
--- /dev/null
+++ b/Replacements/GovernmentScreen_Expansion2.lua
@@ -0,0 +1,50 @@
+-- Copyright 2018, Firaxis Games
+include("GovernmentScreen_Expansion1");
+
+-- ===========================================================================
+-- OVERRIDE
+-- RETURNS: true if policy is available to the player at this time.
+-- ===========================================================================
+function IsPolicyAvailable( kPlayerCulture:table, policyHash:number )
+ local isPolicyObtainable :boolean = not kPlayerCulture:IsPolicyBanned( policyHash );
+ local isSlottable :boolean = kPlayerCulture:CanPolicyBeSlotted( policyHash );
+ local isRelevant :boolean = not kPlayerCulture:IsPolicyObsolete( policyHash );
+
+ return isPolicyObtainable and isSlottable and isRelevant;
+end
+
+-- ===========================================================================
+-- OVERRIDE
+-- ===========================================================================
+function GetGovernmentStatsText(governmentType:string)
+ local text:string = "";
+ local governmentInfo:table = GameInfo.Governments[governmentType];
+ if (governmentInfo ~= nil) then
+ for governmentXP2Info in GameInfo.Governments_XP2() do
+ if (governmentXP2Info ~= nil and governmentXP2Info.GovernmentType == governmentType) then
+ text = text .. "[ICON_FAVOR]" .. governmentXP2Info.Favor;
+ break;
+ end
+ end
+ text = text .. "[ICON_Envoy]" .. governmentInfo.InfluenceTokensPerThreshold;
+ end
+ return text;
+end
+
+-- ===========================================================================
+-- OVERRIDE
+-- ===========================================================================
+function GetGovernmentStatsTooltip(governmentType:string)
+ local text:string = "";
+ local governmentInfo:table = GameInfo.Governments[governmentType];
+ if (governmentInfo ~= nil) then
+ for governmentXP2Info in GameInfo.Governments_XP2() do
+ if (governmentXP2Info ~= nil and governmentXP2Info.GovernmentType == governmentType) then
+ text = text .. Locale.Lookup("LOC_GOVT_FAVOR_PER_TURN", governmentXP2Info.Favor) .. "[NEWLINE][NEWLINE]";
+ break;
+ end
+ end
+ text = text .. Locale.Lookup("LOC_GOVT_INFLUENCE_POINTS_TOWARDS_ENVOYS", governmentInfo.InfluencePointsPerTurn, governmentInfo.InfluencePointsThreshold, governmentInfo.InfluenceTokensPerThreshold);
+ end
+ return text;
+end
\ No newline at end of file
diff --git a/Replacements/GreatWorksOverview_Expansion2.lua b/Replacements/GreatWorksOverview_Expansion2.lua
new file mode 100644
index 0000000..59ca6c3
--- /dev/null
+++ b/Replacements/GreatWorksOverview_Expansion2.lua
@@ -0,0 +1,284 @@
+
+--[[
+-- Created by Samuel Batista
+-- Copyright (c) Firaxis Games 2018
+--]]
+
+-- ===========================================================================
+-- INCLUDES
+-- ===========================================================================
+include("GreatWorksOverview.lua");
+
+-- ===========================================================================
+-- OVERRIDE BASE FUNCTIONS
+-- ===========================================================================
+include("InstanceManager");
+include("PopupDialog")
+include("GameCapabilities");
+include("GreatWorksSupport");
+
+-- ===========================================================================
+-- CONSTANTS Shoul probably switch the base game to just use globals.
+-- ===========================================================================
+local RELOAD_CACHE_ID:string = "GreatWorksOverview"; -- Must be unique (usually the same as the file name)
+
+local SIZE_SLOT_TYPE_ICON:number = 40;
+local SIZE_GREAT_WORK_ICON:number = 64;
+local PADDING_PROVIDING_LABEL:number = 10;
+local PADDING_PLACING_DETAILS:number = 5;
+local PADDING_PLACING_ICON:number = 10;
+local PADDING_BUTTON_EDGES:number = 20;
+local MIN_PADDING_SLOTS:number = 2;
+local MAX_PADDING_SLOTS:number = 30;
+local MAX_NUM_SLOTS:number = 6;
+
+local NUM_RELIC_TEXTURES:number = 24;
+local NUM_ARIFACT_TEXTURES:number = 25;
+local GREAT_WORK_RELIC_TYPE:string = "GREATWORKOBJECT_RELIC";
+local GREAT_WORK_ARTIFACT_TYPE:string = "GREATWORKOBJECT_ARTIFACT";
+
+local LOC_PLACING:string = Locale.Lookup("LOC_GREAT_WORKS_PLACING");
+local LOC_TOURISM:string = Locale.Lookup("LOC_GREAT_WORKS_TOURISM");
+local LOC_THEME_BONUS:string = Locale.Lookup("LOC_GREAT_WORKS_THEMED_BONUS");
+local LOC_SCREEN_TITLE:string = Locale.Lookup("LOC_GREAT_WORKS_SCREEN_TITLE");
+local LOC_ORGANIZE_GREAT_WORKS:string = Locale.Lookup("LOC_GREAT_WORKS_ORGANIZE_GREAT_WORKS");
+
+local DATA_FIELD_SLOT_CACHE:string = "SlotCache";
+local DATA_FIELD_GREAT_WORK_IM:string = "GreatWorkIM";
+local DATA_FIELD_TOURISM_YIELD:string = "TourismYield";
+local DATA_FIELD_THEME_BONUS_IM:string = "ThemeBonusIM";
+
+local YIELD_FONT_ICONS:table = {
+ YIELD_FOOD = "[ICON_FoodLarge]",
+ YIELD_PRODUCTION = "[ICON_ProductionLarge]",
+ YIELD_GOLD = "[ICON_GoldLarge]",
+ YIELD_SCIENCE = "[ICON_ScienceLarge]",
+ YIELD_CULTURE = "[ICON_CultureLarge]",
+ YIELD_FAITH = "[ICON_FaithLarge]",
+ TourismYield = "[ICON_TourismLarge]"
+};
+
+local DEFAULT_GREAT_WORKS_ICONS:table = {
+ GREATWORKSLOT_WRITING = "ICON_GREATWORKOBJECT_WRITING",
+ GREATWORKSLOT_PALACE = "ICON_GREATWORKOBJECT_SCULPTURE",
+ GREATWORKSLOT_ART = "ICON_GREATWORKOBJECT_PORTRAIT",
+ GREATWORKSLOT_CATHEDRAL = "ICON_GREATWORKOBJECT_RELIGIOUS",
+ GREATWORKSLOT_ARTIFACT = "ICON_GREATWORKOBJECT_ARTIFACT_ERA_ANCIENT",
+ GREATWORKSLOT_MUSIC = "ICON_GREATWORKOBJECT_MUSIC",
+ GREATWORKSLOT_RELIC = "ICON_GREATWORKOBJECT_RELIC"
+};
+
+local m_during_move:boolean = false;
+local m_dest_building:number = 0;
+local m_dest_city;
+local m_isLocalPlayerTurn:boolean = true;
+
+-- ===========================================================================
+-- SCREEN VARIABLES
+-- ===========================================================================
+local m_FirstGreatWork:table = nil;
+local m_GreatWorkYields:table = nil;
+local m_GreatWorkSelected:table = nil;
+local m_GreatWorkBuildings:table = nil;
+local m_GreatWorkSlotsIM:table = InstanceManager:new("GreatWorkSlot", "TopControl", Controls.GreatWorksStack);
+local m_TotalResourcesIM:table = InstanceManager:new("AgregateResource", "Resource", Controls.TotalResources);
+
+
+-- ===========================================================================
+-- PLAYER VARIABLES
+-- ===========================================================================
+local m_LocalPlayer:table;
+local m_LocalPlayerID:number;
+
+function GetThemeDescription(buildingType:string)
+ local localPlayerID = Game.GetLocalPlayer();
+ local localPlayer = Players[localPlayerID];
+
+ if(localPlayer == nil) then
+ return nil;
+ end
+
+ local eBuilding = localPlayer:GetCulture():GetAutoThemedBuilding();
+ local bAutoTheme = localPlayer:GetCulture():IsAutoThemedEligible(GameInfo.Buildings[buildingType].Hash);
+
+ if (GameInfo.Buildings[buildingType].Index == eBuilding) then
+ return Locale.Lookup("LOC_BUILDING_THEMINGBONUS_FULL_MUSEUM");
+ elseif(bAutoTheme == true) then
+ return Locale.Lookup("LOC_BUILDING_THEMINGBONUS_FULL_MUSEUM");
+ else
+ for row in GameInfo.Building_GreatWorks() do
+ if row.BuildingType == buildingType then
+ if row.ThemingBonusDescription ~= nil then
+ return Locale.Lookup(row.ThemingBonusDescription);
+ end
+ end
+ end
+ end
+ return nil;
+end
+
+function PopulateGreatWorkSlot(instance:table, pCity:table, pCityBldgs:table, pBuildingInfo:table)
+
+ instance.DefaultBG:SetHide(false);
+ instance.DisabledBG:SetHide(true);
+ instance.HighlightedBG:SetHide(true);
+ instance.DefaultBG:RegisterCallback(Mouse.eLClick, function() end); -- clear callback
+ instance.HighlightedBG:RegisterCallback(Mouse.eLClick, function() end); -- clear callback
+
+ local buildingType:string = pBuildingInfo.BuildingType;
+ local buildingIndex:number = pBuildingInfo.Index;
+ local themeDescription = GetThemeDescription(buildingType);
+ instance.CityName:SetText(Locale.Lookup(pCity:GetName()));
+ instance.BuildingName:SetText(Locale.ToUpper(Locale.Lookup(pBuildingInfo.Name)));
+
+ -- Ensure we have Instance Managers for the great works
+ local greatWorkIM:table = instance[DATA_FIELD_GREAT_WORK_IM];
+ if(greatWorkIM == nil) then
+ greatWorkIM = InstanceManager:new("GreatWork", "TopControl", instance.GreatWorks);
+ instance[DATA_FIELD_GREAT_WORK_IM] = greatWorkIM;
+ else
+ greatWorkIM:ResetInstances();
+ end
+
+ local index:number = 0;
+ local numGreatWorks:number = 0;
+ local numThemedGreatWorks:number = 0;
+ local instanceCache:table = {};
+ local firstGreatWork:table = nil;
+ local numSlots:number = pCityBldgs:GetNumGreatWorkSlots(buildingIndex);
+ local localPlayerID = Game.GetLocalPlayer();
+ local localPlayer = Players[localPlayerID];
+
+ if(localPlayer == nil) then
+ return nil;
+ end
+
+ local bAutoTheme = localPlayer:GetCulture():IsAutoThemedEligible();
+
+ if (numSlots ~= nil and numSlots > 0) then
+ for _:number=0, numSlots - 1 do
+ local instance:table = greatWorkIM:GetInstance();
+ local greatWorkIndex:number = pCityBldgs:GetGreatWorkInSlot(buildingIndex, index);
+ local greatWorkSlotType:number = pCityBldgs:GetGreatWorkSlotType(buildingIndex, index);
+ local greatWorkSlotString:string = GameInfo.GreatWorkSlotTypes[greatWorkSlotType].GreatWorkSlotType;
+
+ PopulateGreatWork(instance, pCityBldgs, pBuildingInfo, index, greatWorkIndex, greatWorkSlotString);
+ index = index + 1;
+ instanceCache[index] = instance;
+ if greatWorkIndex ~= -1 then
+ numGreatWorks = numGreatWorks + 1;
+ local greatWorkType:number = pCityBldgs:GetGreatWorkTypeFromIndex(greatWorkIndex);
+ local greatWorkInfo:table = GameInfo.GreatWorks[greatWorkType];
+ if firstGreatWork == nil then
+ firstGreatWork = greatWorkInfo;
+ end
+ if greatWorkInfo ~= nil and GreatWorkFitsTheme(pCityBldgs, pBuildingInfo, greatWorkIndex, greatWorkInfo) then
+ numThemedGreatWorks = numThemedGreatWorks + 1;
+ end
+ end
+ end
+
+ if firstGreatWork ~= nil and themeDescription ~= nil and buildingType ~= "BUILDING_QUEENS_BIBLIOTHEQUE" then
+ local slotTypeIcon:string = "ICON_" .. firstGreatWork.GreatWorkObjectType;
+ if firstGreatWork.GreatWorkObjectType == "GREATWORKOBJECT_ARTIFACT" then
+ slotTypeIcon = slotTypeIcon .. "_" .. firstGreatWork.EraType;
+ end
+
+ local textureOffsetX:number, textureOffsetY:number, textureSheet:string = IconManager:FindIconAtlas(slotTypeIcon, SIZE_SLOT_TYPE_ICON);
+ if(textureSheet == nil or textureSheet == "") then
+ UI.DataError("Could not find slot type icon in PopulateGreatWorkSlot: icon=\""..slotTypeIcon.."\", iconSize="..tostring(SIZE_SLOT_TYPE_ICON));
+ else
+ for i:number=0, numSlots - 1 do
+ local slotIndex:number = index - i;
+ instanceCache[slotIndex].SlotTypeIcon:SetTexture(textureOffsetX, textureOffsetY, textureSheet);
+ end
+ end
+ end
+ end
+
+ instance[DATA_FIELD_SLOT_CACHE] = instanceCache;
+
+ local numSlots:number = table.count(instanceCache);
+ if(numSlots > 1) then
+ local slotRange:number = MAX_NUM_SLOTS - 2;
+ local paddingRange:number = MAX_PADDING_SLOTS - MIN_PADDING_SLOTS;
+ local finalPadding:number = ((MAX_NUM_SLOTS - numSlots) * paddingRange / slotRange) + MIN_PADDING_SLOTS;
+ instance.GreatWorks:SetPadding(finalPadding);
+ else
+ instance.GreatWorks:SetPadding(0);
+ end
+
+ -- Ensure we have Instance Managers for the theme bonuses
+ local themeBonusIM:table = instance[DATA_FIELD_THEME_BONUS_IM];
+ if(themeBonusIM == nil) then
+ themeBonusIM = InstanceManager:new("Resource", "Resource", instance.ThemeBonuses);
+ instance[DATA_FIELD_THEME_BONUS_IM] = themeBonusIM;
+ else
+ themeBonusIM:ResetInstances();
+ end
+
+ if numGreatWorks == 0 then
+ if themeDescription ~= nil then
+ instance.ThemingLabel:SetText(Locale.Lookup("LOC_GREAT_WORKS_THEME_BONUS_PROGRESS", numThemedGreatWorks, numSlots));
+ instance.ThemingLabel:SetToolTipString(themeDescription);
+ end
+ else
+ instance.ThemingLabel:SetText("");
+ instance.ThemingLabel:SetToolTipString("");
+ if pCityBldgs:IsBuildingThemedCorrectly(buildingIndex) then
+ instance.ThemingLabel:SetText(LOC_THEME_BONUS);
+ if m_during_move then
+ if buildingIndex == m_dest_building then
+ if (m_dest_city == pCityBldgs:GetCity():GetID()) then
+ UI.PlaySound("UI_GREAT_WORKS_BONUS_ACHIEVED");
+ end
+ end
+ end
+ else
+ if themeDescription ~= nil then
+ -- if we're being called due to moving a work
+ if numSlots > 1 then
+ if(bAutoTheme == true) then
+ instance.ThemingLabel:SetText(Locale.Lookup("LOC_GREAT_WORKS_THEME_BONUS_PROGRESS", numGreatWorks, numSlots));
+ else
+ instance.ThemingLabel:SetText(Locale.Lookup("LOC_GREAT_WORKS_THEME_BONUS_PROGRESS", numThemedGreatWorks, numSlots));
+ end
+
+ if m_during_move then
+ if buildingIndex == m_dest_building then
+ if (m_dest_city == pCityBldgs:GetCity():GetID()) then
+ if numThemedGreatWorks == 2 then
+ UI.PlaySound("UI_GreatWorks_Bonus_Increased");
+ end
+ end
+ end
+ end
+ end
+
+ if instance.ThemingLabel:GetText() ~= "" then
+ instance.ThemingLabel:SetToolTipString(themeDescription);
+ end
+ end
+ end
+ end
+
+ for row in GameInfo.Yields() do
+ local yieldValue:number = pCityBldgs:GetBuildingYieldFromGreatWorks(row.Index, buildingIndex);
+ if yieldValue > 0 then
+ AddYield(themeBonusIM:GetInstance(), Locale.Lookup(row.Name), YIELD_FONT_ICONS[row.YieldType], yieldValue);
+ end
+ end
+
+ local regularTourism:number = pCityBldgs:GetBuildingTourismFromGreatWorks(false, buildingIndex);
+ local religionTourism:number = pCityBldgs:GetBuildingTourismFromGreatWorks(true, buildingIndex);
+ local totalTourism:number = regularTourism + religionTourism;
+
+ if totalTourism > 0 then
+ AddYield(themeBonusIM:GetInstance(), LOC_TOURISM, YIELD_FONT_ICONS[DATA_FIELD_TOURISM_YIELD], totalTourism);
+ end
+
+ instance.ThemeBonuses:CalculateSize();
+ instance.ThemeBonuses:ReprocessAnchoring();
+
+ return numGreatWorks;
+end
\ No newline at end of file
diff --git a/Replacements/InGame.lua b/Replacements/InGame.lua
new file mode 100644
index 0000000..dfd5b13
--- /dev/null
+++ b/Replacements/InGame.lua
@@ -0,0 +1,372 @@
+-- Copyright 2015-2018, Firaxis Games
+-- XP2 root context for ingame (aka: All-the-things)
+-- MODs / Expansions cannot use partial replacement as this context is
+-- directly added to the UI Control Tree via engine.
+
+include( "LocalPlayerActionSupport" );
+include( "InputSupport" );
+
+
+-- ===========================================================================
+-- CONSTANTS
+-- ===========================================================================
+local TIME_UNTIL_UPDATE:number = 0.1; -- time to wait before attempting to release delayshow popups.
+
+
+-- ===========================================================================
+-- VARIABLES
+-- ===========================================================================
+
+local DefaultMessageHandler = {};
+local m_bulkHideTracker :number = 0;
+local m_lastBulkHider:string = "first call";
+g_uiAddins = {};
+
+local m_PauseId :number = Input.GetActionId("PauseMenu");
+local m_QuicksaveId :number = Input.GetActionId("QuickSave");
+
+local m_HexColoringReligion : number = UILens.CreateLensLayerHash("Hex_Coloring_Religion");
+local m_CulturalIdentityLens: number = UILens.CreateLensLayerHash("Cultural_Identity_Lens");
+local m_TouristTokens : number = UILens.CreateLensLayerHash("Tourist_Tokens");
+local m_activeLocalPlayer : number = -1;
+local m_timeUntilPopupCheck : number = 0;
+
+-- ===========================================================================
+-- FUNCTIONS
+-- ===========================================================================
+
+-- ===========================================================================
+-- Open up the TopOptionsMenu with the utmost priority.
+-- ===========================================================================
+function OpenInGameOptionsMenu()
+ LuaEvents.InGame_OpenInGameOptionsMenu();
+end
+
+-- ===========================================================================
+-- LUA Event
+-- ===========================================================================
+function OnTutorialToggleInGameOptionsMenu()
+ if Controls.TopOptionsMenu:IsHidden() then
+ OpenInGameOptionsMenu();
+ else
+ LuaEvents.InGame_CloseInGameOptionsMenu();
+ end
+end
+
+-- ===========================================================================
+DefaultMessageHandler[KeyEvents.KeyUp] =
+ function( pInputStruct:table )
+
+ local uiKey = pInputStruct:GetKey();
+
+ if( uiKey == Keys.VK_ESCAPE ) then
+ if( Controls.TopOptionsMenu:IsHidden() ) then
+ OpenInGameOptionsMenu();
+ return true;
+ end
+ return false; -- Already open, let it handle it.
+
+ elseif( uiKey == Keys.B and pInputStruct:IsShiftDown() and pInputStruct:IsAltDown() and (not UI.IsFinalRelease()) ) then
+ -- DEBUG: Force unhiding
+ local msg:string = "***PLAYER Force Bulk unhiding SHIFT+ALT+B ***";
+ UI.DataError(msg);
+ m_bulkHideTracker = 1;
+ BulkHide(false, msg);
+
+ elseif( uiKey == Keys.J and pInputStruct:IsShiftDown() and pInputStruct:IsAltDown() and (not UI.IsFinalRelease()) ) then
+ if m_bulkHideTracker < 1 then
+ BulkHide(true, "Forced" );
+ else
+ BulkHide(false, "Forced" );
+ end
+ end
+
+ return false;
+ end
+
+----------------------------------------------------------------
+-- LoadGameViewStateDone Event Handler
+----------------------------------------------------------------
+function OnLoadGameViewStateDone()
+ -- show HUD elements that relay on the gamecache being fully initialized.
+ if(GameConfiguration.IsNetworkMultiplayer()) then
+ Controls.MultiplayerTurnManager:SetHide(false);
+ end
+end
+
+----------------------------------------------------------------
+-- Input handling
+----------------------------------------------------------------
+function OnInputHandler( pInputStruct )
+ local uiMsg = pInputStruct:GetMessageType();
+
+ if DefaultMessageHandler[uiMsg] ~= nil then
+ return DefaultMessageHandler[uiMsg]( pInputStruct );
+ end
+ return false;
+end
+
+----------------------------------------------------------------
+function OnShow()
+ Controls.WorldViewControls:SetHide( false );
+
+ local pFriends = Network.GetFriends();
+ if (pFriends ~= nil) then
+ if (GameConfiguration.IsAnyMultiplayer()) then
+ if GameConfiguration.IsHotseat() then
+ pFriends:SetRichPresence("civPresence", "LOC_PRESENCE_IN_GAME_HOTSEAT");
+ elseif GameConfiguration.IsLANMultiplayer() then
+ pFriends:SetRichPresence("civPresence", "LOC_PRESENCE_IN_GAME_LAN");
+ elseif GameConfiguration.IsPlayByCloud() then
+ pFriends:SetRichPresence("civPresence", "LOC_PRESENCE_IN_GAME_PLAYBYCLOUD");
+ else
+ pFriends:SetRichPresence("civPresence", "LOC_PRESENCE_IN_GAME_ONLINE");
+ end
+ else
+ pFriends:SetRichPresence("civPresence", "LOC_PRESENCE_IN_GAME_SP");
+ end
+ end
+end
+
+
+-- ===========================================================================
+-- Hide (or Show) all the contexts part of the BULK group.
+-- ===========================================================================
+function BulkHide( isHide:boolean, debugWho:string )
+
+ -- Tracking for debugging:
+ m_bulkHideTracker = m_bulkHideTracker + (isHide and 1 or -1);
+ print("Request to BulkHide( "..tostring(isHide)..", "..debugWho.." ), Show on 0 = "..tostring(m_bulkHideTracker));
+
+ if m_bulkHideTracker < 0 then
+ UI.DataError("Request to bulk show past limit by "..debugWho..". Last bulk shown by "..m_lastBulkHider);
+ m_bulkHideTracker = 0;
+ end
+ m_lastBulkHider = debugWho;
+
+ -- Do the bulk hiding/showing
+ local kGroups:table = {"WorldViewControls", "HUD", "PartialScreens", "Screens", "TopLevelHUD" };
+ for i,group in ipairs(kGroups) do
+ local pContext :table = ContextPtr:LookUpControl("/InGame/"..group);
+ if pContext == nil then
+ UI.DataError("InGame is unable to BulkHide("..isHide..") '/InGame/"..group.."' because the Context doesn't exist.");
+ else
+ if m_bulkHideTracker == 1 and isHide then
+ pContext:SetHide(true);
+ elseif m_bulkHideTracker == 0 and isHide==false then
+ pContext:SetHide(false);
+ RestartRefreshRequest();
+ else
+ -- Do nothing
+ end
+ end
+ end
+end
+
+
+-- ===========================================================================
+-- Hotkey Event
+-- ===========================================================================
+function OnInputActionTriggered( actionId )
+ if actionId == m_PauseId then
+ if( Controls.TopOptionsMenu:IsHidden() ) then
+ OpenInGameOptionsMenu();
+ return true;
+ end
+ elseif actionId == m_QuicksaveId then
+ -- Quick save
+ if CanLocalPlayerSaveGame() then
+ local gameFile = {};
+ gameFile.Name = "quicksave";
+ gameFile.Location = SaveLocations.LOCAL_STORAGE;
+ gameFile.Type= Network.GetGameConfigurationSaveType();
+ gameFile.IsAutosave = false;
+ gameFile.IsQuicksave = true;
+
+ Network.SaveGame(gameFile);
+ UI.PlaySound("Confirm_Bed_Positive");
+ end
+ end
+end
+
+-- ===========================================================================
+-- Gamecore Event
+-- Called once per layer that is turned on when a new lens is activated,
+-- or when a player explicitly turns off the layer from the "player" lens.
+-- ===========================================================================
+function OnLensLayerOn( layerHash:number )
+ if layerHash == m_HexColoringReligion or layerHash == m_CulturalIdentityLens or
+ layerHash == m_TouristTokens then
+ Controls.CityBannerManager:ChangeParent(Controls.BannerAndFlags);
+ end
+end
+
+-- ===========================================================================
+-- Gamecore Event
+-- Called once per layer that is turned on when a new lens is deactivated,
+-- or when a player explicitly turns off the layer from the "player" lens.
+-- ===========================================================================
+function OnLensLayerOff( layerHash:number )
+ if layerHash == m_HexColoringReligion or layerHash == m_CulturalIdentityLens or
+ layerHash == m_TouristTokens then
+ Controls.UnitFlagManager:ChangeParent(Controls.BannerAndFlags);
+ end
+end
+
+-- ===========================================================================
+-- EVENT
+-- ===========================================================================
+function OnTurnBegin()
+ m_activeLocalPlayer = Game.GetLocalPlayer();
+end
+
+-- ===========================================================================
+-- EVENT
+-- ===========================================================================
+function OnTurnEnd()
+ m_activeLocalPlayer = -1;
+end
+
+
+-- ===========================================================================
+function RestartRefreshRequest()
+ -- Increasing this adds a delay, but will make it less likely that lower
+ -- priority popups will be shown before all the popups are in added in
+ -- the queue.
+ m_timeUntilPopupCheck = TIME_UNTIL_UPDATE;
+ ContextPtr:SetRefreshHandler( OnRefreshAttemptPopupRelease );
+ ContextPtr:RequestRefresh();
+end
+
+-- ===========================================================================
+-- EVENT
+-- Gamecore is done processing events; this may fire multiple times as a
+-- turn begins, as well as after player actions.
+-- ===========================================================================
+function OnGameCoreEventPlaybackComplete()
+ -- Gate using this based on whether or not it's firing for a local player
+ if m_activeLocalPlayer == -1 then return; end;
+ RestartRefreshRequest();
+end
+
+-- ===========================================================================
+-- UI Manager Callback
+-- ===========================================================================
+function OnPopupQueueChange( isQueuing:boolean )
+ if m_timeUntilPopupCheck <= 0 then
+ RestartRefreshRequest();
+ end
+end
+
+-- ===========================================================================
+-- Event
+-- ===========================================================================
+function OnUIIdle()
+ -- If a countdown to check hasn't started, kick one off.
+ if m_timeUntilPopupCheck <= 0 then
+ RestartRefreshRequest();
+ end
+end
+
+-- ===========================================================================
+function IsAbleToShowDelayedPopups()
+ local isBulkHideOkay :boolean = (m_bulkHideTracker == 0);
+ local isQueueEnabled :boolean = (UIManager:IsPopupQueueDisabled() == false);
+ return isBulkHideOkay and isQueueEnabled;
+end
+
+-- ===========================================================================
+-- UI Callback
+-- ===========================================================================
+function OnRefreshAttemptPopupRelease( delta:number )
+ m_timeUntilPopupCheck = m_timeUntilPopupCheck - delta;
+ if m_timeUntilPopupCheck <= 0 then
+ -- Only release delayed popups if a bulk hide operation isn't currently happening.
+ if IsAbleToShowDelayedPopups() then
+ UIManager:ShowDelayedPopups(); -- Show any popups that had been added to Forge waiting to be shown
+ end
+ ContextPtr:ClearRefreshHandler();
+ else
+ ContextPtr:RequestRefresh();
+ end
+end
+
+-- ===========================================================================
+function OnDiplomacyHideIngameUI() BulkHide( true, "Diplomacy" ); Input.PushActiveContext(InputContext.Diplomacy); end
+function OnDiplomacyShowIngameUI() BulkHide(false, "Diplomacy" ); Input.PopContext(); end
+function OnDisasterRevealPopupShown() BulkHide( true, "NaturalDisaster" ); end
+function OnDisasterRevealPopupClosed() BulkHide(false, "NaturalDisaster" ); end
+function OnEndGameMenuShown() BulkHide( true, "EndGame" ); Input.PushActiveContext(InputContext.EndGame); end
+function OnEndGameMenuClosed() BulkHide(false, "EndGame" ); Input.PopContext(); end
+function OnFullscreenMapShown() BulkHide( true, "FullscreenMap" ); Input.PushActiveContext(InputContext.FullscreenMap);end
+function OnFullscreenMapClosed() BulkHide(false, "FullscreenMap" ); Input.PopContext(); end
+function OnNaturalWonderPopupShown() BulkHide( true, "NaturalWonder" ); end
+function OnNaturalWonderPopupClosed() BulkHide(false, "NaturalWonder" ); end
+function OnProjectBuiltShown() BulkHide( true, "Project" ); end
+function OnProjectBuiltClosed() BulkHide(false, "Project" ); end
+function OnRockBandMoviePopupShown() BulkHide( true, "RockBand" ); end
+function OnRockBandMoviePopupClosed() BulkHide(false, "RockBand" ); end
+function OnTutorialEndHide() BulkHide( true, "TutorialEnd" ); end
+function OnWonderBuiltPopupShown() BulkHide( true, "Wonder" ); end
+function OnWonderBuiltPopupClosed() BulkHide(false, "Wonder" ); end
+
+-- ===========================================================================
+function OnShutdown()
+ UIManager:ClearPopupChangeHandler();
+end
+
+-- ===========================================================================
+-- Cannot use LateInitialize patterns as this context is attached via C++
+-- ===========================================================================
+function Initialize()
+
+ m_activeLocalPlayer = Game.GetLocalPlayer();
+
+ -- Support for Modded Add-in UI's
+ for i, addin in ipairs(Modding.GetUserInterfaces("InGame")) do
+ print("Loading InGame UI - " .. addin.ContextPath);
+ local id :string = addin.ContextPath:sub( -(string.find( string.reverse(addin.ContextPath), '/') - 1) ); -- grab id from end of path
+ local isHidden :boolean = true;
+ local newContext:table = ContextPtr:LoadNewContext(addin.ContextPath, Controls.AdditionalUserInterfaces, id, isHidden); -- Content, ID, hidden
+ table.insert(g_uiAddins, newContext);
+ end
+
+ ContextPtr:SetInputHandler( OnInputHandler, true );
+ ContextPtr:SetShowHandler( OnShow );
+ ContextPtr:SetRefreshHandler( OnRefreshAttemptPopupRelease );
+ ContextPtr:SetShutdown( OnShutdown );
+ UIManager:SetPopupChangeHandler( OnPopupQueueChange );
+
+ Events.GameCoreEventPlaybackComplete.Add( OnGameCoreEventPlaybackComplete );
+ Events.InputActionTriggered.Add( OnInputActionTriggered );
+ Events.LensLayerOff.Add( OnLensLayerOff );
+ Events.LensLayerOn.Add( OnLensLayerOn );
+ Events.LoadGameViewStateDone.Add( OnLoadGameViewStateDone );
+ Events.LocalPlayerTurnBegin.Add( OnTurnBegin );
+ Events.LocalPlayerTurnEnd.Add( OnTurnEnd );
+ Events.UIIdle.Add( OnUIIdle );
+
+
+ -- NOTE: Using UI open/closed pairs in the case of end game; where
+ -- the same player receives both a victory and defeat messages
+ -- across the wire.
+ LuaEvents.DiplomacyActionView_HideIngameUI.Add( OnDiplomacyHideIngameUI );
+ LuaEvents.DiplomacyActionView_ShowIngameUI.Add( OnDiplomacyShowIngameUI );
+ LuaEvents.EndGameMenu_Shown.Add( OnEndGameMenuShown );
+ LuaEvents.EndGameMenu_Closed.Add( OnEndGameMenuClosed );
+ LuaEvents.FullscreenMap_Shown.Add( OnFullscreenMapShown );
+ LuaEvents.FullscreenMap_Closed.Add( OnFullscreenMapClosed );
+ LuaEvents.ProjectBuiltPopup_Shown.Add( OnProjectBuiltShown );
+ LuaEvents.ProjectBuiltPopup_Closed.Add( OnProjectBuiltClosed );
+ LuaEvents.NaturalDisasterPopup_Shown.Add( OnDisasterRevealPopupShown );
+ LuaEvents.NaturalDisasterPopup_Closed.Add( OnDisasterRevealPopupClosed );
+ LuaEvents.NaturalWonderPopup_Shown.Add( OnNaturalWonderPopupShown );
+ LuaEvents.NaturalWonderPopup_Closed.Add( OnNaturalWonderPopupClosed );
+ LuaEvents.RockBandMoviePopup_Shown.Add( OnRockBandMoviePopupShown );
+ LuaEvents.RockBandMoviePopup_Closed.Add( OnRockBandMoviePopupClosed );
+ LuaEvents.Tutorial_ToggleInGameOptionsMenu.Add( OnTutorialToggleInGameOptionsMenu );
+ LuaEvents.Tutorial_TutorialEndHideBulkUI.Add( OnTutorialEndHide );
+ LuaEvents.WonderBuiltPopup_Shown.Add( OnWonderBuiltPopupShown );
+ LuaEvents.WonderBuiltPopup_Closed.Add( OnWonderBuiltPopupClosed );
+end
+Initialize();
diff --git a/Replacements/InGame.xml b/Replacements/InGame.xml
new file mode 100644
index 0000000..db67ce3
--- /dev/null
+++ b/Replacements/InGame.xml
@@ -0,0 +1,146 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Replacements/InGameTopOptionsMenu.xml b/Replacements/InGameTopOptionsMenu.xml
index 0c21481..fca0b33 100644
--- a/Replacements/InGameTopOptionsMenu.xml
+++ b/Replacements/InGameTopOptionsMenu.xml
@@ -32,7 +32,7 @@
-
+
@@ -49,18 +49,18 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
@@ -82,7 +82,7 @@
-
+
diff --git a/Replacements/LaunchBar_Expansion2.lua b/Replacements/LaunchBar_Expansion2.lua
new file mode 100644
index 0000000..1f9ff4f
--- /dev/null
+++ b/Replacements/LaunchBar_Expansion2.lua
@@ -0,0 +1,108 @@
+-- ===========================================================================
+-- HUD's Launch Bar XP2
+-- Copyright (c) 2018 Firaxis Games
+-- ===========================================================================
+
+-- ===========================================================================
+-- XP1 File
+-- ===========================================================================
+include("LaunchBar_Expansion1");
+
+
+-- ===========================================================================
+-- CACHE BASE FUNCTIONS
+-- ===========================================================================
+XP1_LateInitialize = LateInitialize;
+XP1_CloseAllPopups = CloseAllPopups;
+XP1_OnInputActionTriggered = OnInputActionTriggered;
+XP1_OnTurnBegin = OnTurnBegin;
+
+-- ===========================================================================
+-- MEMBERS
+-- ===========================================================================
+local m_isClimateOpen :boolean = false;
+local m_uiClimateInstance :table = {};
+
+
+-- ===========================================================================
+-- Lua Event
+-- ===========================================================================
+function OnClimateScreenOpened()
+ m_isClimateOpen = true;
+ if m_uiClimateInstance ~= nil then
+ m_uiClimateInstance.AlertIndicator:SetHide(true);
+ end
+ OnOpen();
+end
+
+
+-- ===========================================================================
+-- Lua Event
+-- ===========================================================================
+function OnClimateScreenClosed()
+ m_isClimateOpen = false;
+ OnClose();
+end
+
+
+-- ===========================================================================
+-- UI Callback
+-- ===========================================================================
+function OnToggleClimateScreen()
+ if not m_isClimateOpen then
+ CloseAllPopups();
+ end
+ LuaEvents.Launchbar_ToggleClimateScreen();
+end
+
+-- ===========================================================================
+function CloseAllPopups()
+ XP1_CloseAllPopups();
+ LuaEvents.Launchbar_Expansion2_ClimateScreen_Close();
+end
+
+-- ===========================================================================
+function OnTurnBegin()
+ XP1_OnTurnBegin();
+
+ local kCurrentEvent:table = GameRandomEvents.GetCurrentTurnEvent();
+ if kCurrentEvent ~= nil then
+ local kCurrentEventDef:table = GameInfo.RandomEvents[kCurrentEvent.RandomEvent];
+ if kCurrentEventDef ~= nil then
+ if kCurrentEventDef.EffectOperatorType == "SEA_LEVEL" then
+ m_uiClimateInstance.AlertIndicator:SetHide(false);
+ end
+ end
+ end
+end
+
+-- ===========================================================================
+-- Input Hotkey Event
+-- ===========================================================================
+function OnInputActionTriggered( actionId:number )
+ XP1_OnInputActionTriggered( actionId );
+
+ -- Always available, so advanced players can plan their acquisitions
+ if ( actionId == Input.GetActionId("ToggleWorldClimate") ) then
+ OnToggleClimateScreen();
+ end
+end
+
+-- ===========================================================================
+function LateInitialize()
+
+ -- Climate Related:
+ if GameCapabilities.HasCapability("CAPABILITY_WORLD_CLIMATE_VIEW") then
+ ContextPtr:BuildInstanceForControl("LaunchBarItem", m_uiClimateInstance, Controls.ButtonStack );
+ m_uiClimateInstance.LaunchItemButton:RegisterCallback(Mouse.eLClick, OnToggleClimateScreen);
+ m_uiClimateInstance.LaunchItemButton:SetTexture("LaunchBar_Hook_GovernmentButton");
+ m_uiClimateInstance.LaunchItemButton:SetToolTipString(Locale.Lookup("LOC_LAUNCHBAR_CLIMATE_PROGRESS_TOOLTIP"));
+ m_uiClimateInstance.LaunchItemIcon:SetTexture("LaunchBar_Hook_Climate");
+ m_uiClimateInstance.AlertIndicator:SetToolTipString(Locale.Lookup("LOC_CLIMATE_LAUNCHBAR_BANG_TOOLTIP"));
+
+ LuaEvents.ClimateScreen_Opened.Add( OnClimateScreenOpened );
+ LuaEvents.ClimateScreen_Closed.Add( OnClimateScreenClosed );
+ end
+
+ XP1_LateInitialize(); -- This forces a refresh view so only call after the above has occurred.
+end
diff --git a/Replacements/MinimapPanel.xml b/Replacements/MinimapPanel.xml
index ea987b8..d58433d 100644
--- a/Replacements/MinimapPanel.xml
+++ b/Replacements/MinimapPanel.xml
@@ -81,7 +81,7 @@
-
+
diff --git a/Replacements/MinimapPanel_Expansion2.lua b/Replacements/MinimapPanel_Expansion2.lua
new file mode 100644
index 0000000..1e08bf1
--- /dev/null
+++ b/Replacements/MinimapPanel_Expansion2.lua
@@ -0,0 +1,88 @@
+-- Copyright 2018, Firaxis Games
+
+-- ===========================================================================
+-- Base File
+-- ===========================================================================
+include("MinimapPanel_Expansion1");
+
+-- ===========================================================================
+-- Cached Base Functions
+-- ===========================================================================
+XP1_LateInitialize = LateInitialize;
+
+-- ===========================================================================
+-- Members
+-- ===========================================================================
+local m_MapLabelToggles = { };
+
+-- ===========================================================================
+function CreateMapLabelToggle( szLayer, szText, szTooltip, pSetCB )
+ local nLayerHash = UILens.CreateLensLayerHash(szLayer);
+ local bEnabled = UILens.IsLayerOn(nLayerHash);
+
+ local ToggleFunction = function()
+ if UILens.IsLayerOn(nLayerHash) then
+ UILens.ToggleLayerOff(nLayerHash);
+ pSetCB(false);
+ else
+ UILens.ToggleLayerOn(nLayerHash);
+ pSetCB(true);
+ end
+ end
+
+ m_MapLabelToggles[nLayerHash] = CreateMapOptionButton( szText, szTooltip, ToggleFunction, bEnabled );
+
+ local mapToggle = m_MapLabelToggles[nLayerHash];
+
+ -- Setup a function to 'Restore' the control and option state.
+ mapToggle.Restore = function()
+
+ local bState = pSetCB();
+
+ mapToggle.ToggleButton:SetCheck(bState);
+ if bState then
+ UILens.ToggleLayerOn(nLayerHash);
+ else
+ UILens.ToggleLayerOff(nLayerHash);
+ end
+ end
+
+ mapToggle.Restore();
+
+ Controls.MapOptionsStack:CalculateSize();
+end
+
+-- ===========================================================================
+function OnGovernorPromoted(ePlayer, eGovernor, ePromotion)
+ -- The unique Ottoman governor's last promotion can affect loyalty
+ local nCulturalIdentityLens = UILens.CreateLensLayerHash("Cultural_Identity_Lens");
+ if ePlayer == Game.GetLocalPlayer() and UILens.IsLayerOn(nCulturalIdentityLens) then
+ UpdateLoyaltyLens();
+ end
+end
+
+-- ===========================================================================
+function OnUserOptionsActivated_XP2()
+
+ for i, mapOption in pairs(m_MapLabelToggles) do
+ if mapOption.Restore ~= nil then
+ mapOption.Restore();
+ end
+ end
+end
+
+-- ===========================================================================
+function LateInitialize()
+ CreateMapLabelToggle( "MapLabels_Deserts", "LOC_HUD_TOGGLE_DESERT_LABELS", "LOC_HUD_TOGGLE_DESERT_LABELS_TOOLTIP", UserConfiguration.ShowMapLabelsDeserts );
+ CreateMapLabelToggle( "MapLabels_MountainRanges", "LOC_HUD_TOGGLE_MOUNTAIN_RANGE_LABELS", "LOC_HUD_TOGGLE_MOUNTAIN_RANGE_LABELS_TOOLTIP", UserConfiguration.ShowMapLabelsMountainRanges );
+ CreateMapLabelToggle( "MapLabels_NationalParks", "LOC_HUD_TOGGLE_NATIONAL_PARK_LABELS", "LOC_HUD_TOGGLE_NATIONAL_PARK_LABELS_TOOLTIP", UserConfiguration.ShowMapLabelsNationalParks );
+ CreateMapLabelToggle( "MapLabels_NaturalWonders", "LOC_HUD_TOGGLE_NATURAL_WONDER_LABELS", "LOC_HUD_TOGGLE_NATURAL_WONDER_LABELS_TOOLTIP", UserConfiguration.ShowMapLabelsNaturalWonders );
+ CreateMapLabelToggle( "MapLabels_Rivers", "LOC_HUD_TOGGLE_RIVER_LABELS", "LOC_HUD_TOGGLE_RIVER_LABELS_TOOLTIP", UserConfiguration.ShowMapLabelsRivers );
+ CreateMapLabelToggle( "MapLabels_Volcanoes", "LOC_HUD_TOGGLE_VOLCANO_LABELS", "LOC_HUD_TOGGLE_VOLCANO_LABELS_TOOLTIP", UserConfiguration.ShowMapLabelsVolcanoes );
+
+ Events.GovernorPromoted.Add( OnGovernorPromoted );
+ Events.UserOptionsActivated.Add( OnUserOptionsActivated_XP2 );
+
+ -- must be called after we set up our labels to avoid nil reference
+ XP1_LateInitialize();
+end
diff --git a/Replacements/NotificationPanel_Expansion2.lua b/Replacements/NotificationPanel_Expansion2.lua
new file mode 100644
index 0000000..a62f6f4
--- /dev/null
+++ b/Replacements/NotificationPanel_Expansion2.lua
@@ -0,0 +1,114 @@
+-- Copyright 2018, Firaxis Games
+
+include("NotificationPanel_Expansion1");
+
+-- ===========================================================================
+-- LOCALS
+-- ===========================================================================
+local m_pSpecialSessionNotification = nil;
+
+-- ===========================================================================
+-- GLOBALS
+-- ===========================================================================
+XP1_RegisterHandlers = RegisterHandlers;
+
+-- ===========================================================================
+function OnSpecialSessionWorldCongress( notificationEntry )
+ if (notificationEntry ~= nil and notificationEntry.m_PlayerID == Game.GetLocalPlayer()) then
+ local pNotification :table = GetActiveNotificationFromEntry(notificationEntry);
+ if pNotification ~= nil then
+ LuaEvents.NotificationPanel_OpenWorldCongressProposeEmergencies();
+ end
+ end
+end
+
+-- ===========================================================================
+function OnWorldCongressNotification( notificationEntry )
+ if (notificationEntry ~= nil and notificationEntry.m_PlayerID == Game.GetLocalPlayer()) then
+ local pNotification :table = GetActiveNotificationFromEntry(notificationEntry);
+ if pNotification ~= nil then
+ LuaEvents.NotificationPanel_ResumeCongress();
+ end
+ end
+end
+
+-- ===========================================================================
+function OnWorldCongressResultsNotification( notificationEntry )
+ if (notificationEntry ~= nil and notificationEntry.m_PlayerID == Game.GetLocalPlayer()) then
+ local pNotification :table = GetActiveNotificationFromEntry(notificationEntry);
+ if pNotification ~= nil then
+ NotificationManager.Dismiss(pNotification:GetPlayerID(), pNotification:GetID());
+ LuaEvents.NotificationPanel_OpenWorldCongressResults();
+ end
+ end
+end
+
+-- ===========================================================================
+function OnAddSpecialSession( pNotification:table )
+ OnDefaultAddNotification( pNotification );
+ m_pSpecialSessionNotification = pNotification;
+ LuaEvents.WorldCongressPopup_OnSpecialSessionNotificationAdded();
+end
+
+-- ===========================================================================
+function OnDismissSpecialSession( playerID:number, notificationID:number )
+ m_pSpecialSessionNotification = nil;
+ OnDefaultDismissNotification( playerID, notificationID );
+ LuaEvents.WorldCongressPopup_OnSpecialSessionNotificationDismissed();
+end
+
+-- ===========================================================================
+function OnDismissSpecialSessionNotification()
+ UI.AssertMsg(m_pSpecialSessionNotification ~= nil, "Tried to dismiss special session notification, but it was nil - @sbatista");
+ if m_pSpecialSessionNotification then
+ OnDismissSpecialSession(m_pSpecialSessionNotification:GetPlayerID(), m_pSpecialSessionNotification:GetID());
+ end
+end
+
+-- ===========================================================================
+function OnCityUnpoweredNotification(notificationEntry)
+ if (notificationEntry ~= nil and notificationEntry.m_PlayerID == Game.GetLocalPlayer()) then
+ local pNotification : table = GetActiveNotificationFromEntry(notificationEntry);
+ if pNotification ~= nil then
+ LookAtNotification( pNotification );
+ end
+ LuaEvents.CityPanel_ToggleOverviewPower();
+ end
+end
+
+-- ===========================================================================
+function RegisterHandlers()
+
+ XP1_RegisterHandlers();
+
+ LuaEvents.WorldCongressPopup_DismissSpecialSessionNotification.Add(OnDismissSpecialSessionNotification);
+
+ g_notificationHandlers[NotificationTypes.NOTIFICATION_WORLD_CONGRESS_SPECIAL_SESSION_BLOCKING] = MakeDefaultHandlers();
+ g_notificationHandlers[NotificationTypes.NOTIFICATION_WORLD_CONGRESS_SPECIAL_SESSION_NON_BLOCKING] = MakeDefaultHandlers();
+ g_notificationHandlers[NotificationTypes.NOTIFICATION_WORLD_CONGRESS_SPECIAL_SESSION_CAN_BE_CALLED] = MakeDefaultHandlers();
+ g_notificationHandlers[NotificationTypes.NOTIFICATION_WORLD_CONGRESS_EMERGENCY_CAN_BE_CALLED] = MakeDefaultHandlers();
+
+ g_notificationHandlers[NotificationTypes.NOTIFICATION_WORLD_CONGRESS_SPECIAL_SESSION_BLOCKING].Add = OnAddSpecialSession;
+ g_notificationHandlers[NotificationTypes.NOTIFICATION_WORLD_CONGRESS_SPECIAL_SESSION_NON_BLOCKING].Add = OnAddSpecialSession;
+ g_notificationHandlers[NotificationTypes.NOTIFICATION_WORLD_CONGRESS_SPECIAL_SESSION_CAN_BE_CALLED].Add = OnAddSpecialSession;
+ g_notificationHandlers[NotificationTypes.NOTIFICATION_WORLD_CONGRESS_EMERGENCY_CAN_BE_CALLED].Add = OnAddSpecialSession;
+
+ g_notificationHandlers[NotificationTypes.NOTIFICATION_WORLD_CONGRESS_SPECIAL_SESSION_BLOCKING].Dismiss = OnDismissSpecialSession;
+ g_notificationHandlers[NotificationTypes.NOTIFICATION_WORLD_CONGRESS_SPECIAL_SESSION_NON_BLOCKING].Dismiss = OnDismissSpecialSession;
+ g_notificationHandlers[NotificationTypes.NOTIFICATION_WORLD_CONGRESS_SPECIAL_SESSION_CAN_BE_CALLED].Dismiss = OnDismissSpecialSession;
+ g_notificationHandlers[NotificationTypes.NOTIFICATION_WORLD_CONGRESS_EMERGENCY_CAN_BE_CALLED].Dismiss = OnDismissSpecialSession;
+
+ g_notificationHandlers[NotificationTypes.NOTIFICATION_WORLD_CONGRESS_SPECIAL_SESSION_BLOCKING].Activate = OnSpecialSessionWorldCongress;
+ g_notificationHandlers[NotificationTypes.NOTIFICATION_WORLD_CONGRESS_SPECIAL_SESSION_NON_BLOCKING].Activate = OnSpecialSessionWorldCongress;
+ g_notificationHandlers[NotificationTypes.NOTIFICATION_WORLD_CONGRESS_SPECIAL_SESSION_CAN_BE_CALLED].Activate = OnSpecialSessionWorldCongress;
+ g_notificationHandlers[NotificationTypes.NOTIFICATION_WORLD_CONGRESS_EMERGENCY_CAN_BE_CALLED].Activate = OnSpecialSessionWorldCongress;
+
+ g_notificationHandlers[NotificationTypes.NOTIFICATION_WORLD_CONGRESS_BLOCKING] = MakeDefaultHandlers();
+ g_notificationHandlers[NotificationTypes.NOTIFICATION_WORLD_CONGRESS_BLOCKING].Activate = OnWorldCongressNotification;
+
+ g_notificationHandlers[NotificationTypes.NOTIFICATION_WORLD_CONGRESS_RESULTS] = MakeDefaultHandlers();
+ g_notificationHandlers[NotificationTypes.NOTIFICATION_WORLD_CONGRESS_RESULTS].Activate = OnWorldCongressResultsNotification;
+
+ g_notificationHandlers[NotificationTypes.CITY_UNPOWERED] = MakeDefaultHandlers();
+ g_notificationHandlers[NotificationTypes.CITY_UNPOWERED].Activate = OnCityUnpoweredNotification;
+end
\ No newline at end of file
diff --git a/Replacements/PartialScreenHooks_Expansion1.lua b/Replacements/PartialScreenHooks_Expansion1.lua
index cb70dc4..48efacb 100644
--- a/Replacements/PartialScreenHooks_Expansion1.lua
+++ b/Replacements/PartialScreenHooks_Expansion1.lua
@@ -70,4 +70,4 @@ function LateInitialize()
LuaEvents.EraProgressPanel_Open.Add( OnEraProgressPanelOpen );
LuaEvents.EraProgressPanel_Close.Add( OnEraProgressPanelClose );
LuaEvents.PartialScreenHooks_Expansion1_ToggleEraProgress.Add( OnToggleEraProgress );
-end
+end
\ No newline at end of file
diff --git a/Replacements/PartialScreenHooks_Expansion2.lua b/Replacements/PartialScreenHooks_Expansion2.lua
new file mode 100644
index 0000000..7dc9323
--- /dev/null
+++ b/Replacements/PartialScreenHooks_Expansion2.lua
@@ -0,0 +1,72 @@
+-- ===========================================================================
+-- HUD Partial Screen Hooks XP2
+-- Hooks to buttons in the upper right of the main screen HUD.
+-- MyScreen left in as sample to wire up subsequent screens.
+-- ===========================================================================
+
+
+-- ===========================================================================
+-- INCLUDE XP1 FILE
+-- ===========================================================================
+include("PartialScreenHooks_Expansion1");
+
+
+-- ===========================================================================
+-- CACHE BASE FUNCTIONS
+-- ===========================================================================
+XP1_IsPartialScreenOpen = IsPartialScreenOpen;
+XP1_LateInitialize = LateInitialize;
+
+
+-- ===========================================================================
+-- MEMBERS
+-- ===========================================================================
+local m_isMyScreenOpen :boolean = false;
+
+-- ===========================================================================
+-- OVERRIDE
+-- ===========================================================================
+function IsPartialScreenOpen( optionalScreenName:string )
+
+ if (optionalScreenName == nil or optionalScreenName == "MyScreen") and m_isMyScreenOpen then
+ return true;
+ elseif optionalScreenName == "MyScreen" then
+ return false;
+ end
+
+ return XP1_IsPartialScreenOpen( optionalScreenName );
+end
+
+
+-- ===========================================================================
+function OnToggleMyScreen()
+ if IsPartialScreenOpen("MyScreen") then
+ LuaEvents.PartialScreenHooks_CloseMyScreen();
+ else
+ -- If any partial screen is open; close it and then open the Climate screen.
+ if IsPartialScreenOpen() then
+ LuaEvents.PartialScreenHooks_CloseAllExcept("MyScreen");
+ end
+ LuaEvents.PartialScreenHooks_OpenMyScreen();
+ end
+end
+
+-- ===========================================================================
+function OnMyScreenOpen()
+ m_isMyScreenOpen = true;
+end
+
+-- ===========================================================================
+function OnMyScreenClose()
+ m_isMyScreenOpen = false;
+end
+
+-- ===========================================================================
+-- OVERRIDE
+-- ===========================================================================
+function LateInitialize()
+ XP1_LateInitialize();
+ LuaEvents.MyScreen_Opened.Add( OnMyScreenOpen );
+ LuaEvents.MyScreen_Closed.Add( OnMyScreenClose );
+ LuaEvents.PartialScreenHooks_Expansion2_MyScreen.Add( OnToggleMyScreen );
+end
\ No newline at end of file
diff --git a/Replacements/PlotTooltip_Expansion2.lua b/Replacements/PlotTooltip_Expansion2.lua
new file mode 100644
index 0000000..2fd73e8
--- /dev/null
+++ b/Replacements/PlotTooltip_Expansion2.lua
@@ -0,0 +1,507 @@
+-- Copyright 2018, Firaxis Games
+
+include("PlotToolTip");
+
+
+-- ===========================================================================
+-- CACHE BASE FUNCTIONS
+-- ===========================================================================
+BASE_FetchData = FetchData;
+BASE_GetDetails = GetDetails;
+
+-- ===========================================================================
+-- OVERRIDE BASE FUNCTIONS
+-- ===========================================================================
+function FetchData(plot)
+ local data = BASE_FetchData(plot);
+
+ data.IsVolcano = MapFeatureManager.IsVolcano(plot);
+ data.RiverNames = RiverManager.GetRiverName(plot);
+ data.VolcanoName = MapFeatureManager.GetVolcanoName(plot);
+ data.Active = MapFeatureManager.IsActiveVolcano(plot);
+ data.Erupting = MapFeatureManager.IsVolcanoErupting(plot);
+ data.Storm = GameClimate.GetActiveStormTypeAtPlot(plot);
+ data.Drought = GameClimate.GetActiveDroughtTypeAtPlot(plot);
+ data.DroughtTurns = GameClimate.GetDroughtTurnsAtPlot(plot);
+ data.CoastalLowland = TerrainManager.GetCoastalLowlandType(plot);
+ local territory = Territories.GetTerritoryAt(plot:GetIndex());
+ if (territory) then
+ data.TerritoryName = territory:GetName();
+ else
+ data.TerritoryName = nil;
+ end
+ if (data.CoastalLowland ~= -1) then
+ data.Flooded = TerrainManager.IsFlooded(plot);
+ data.Submerged = TerrainManager.IsSubmerged(plot);
+ else
+ data.Flooded = false;
+ data.Submerged = false;
+ end
+
+ return data;
+end
+
+-- ===========================================================================
+function GetDetails(data)
+ local details = {};
+
+ if(data.Owner ~= nil) then
+
+ local szOwnerString;
+
+ local pPlayerConfig = PlayerConfigurations[data.Owner];
+ if (pPlayerConfig ~= nil) then
+ szOwnerString = Locale.Lookup(pPlayerConfig:GetCivilizationShortDescription());
+ end
+
+ if (szOwnerString == nil or string.len(szOwnerString) == 0) then
+ szOwnerString = Locale.Lookup("LOC_TOOLTIP_PLAYER_ID", data.Owner);
+ end
+
+ local pPlayer = Players[data.Owner];
+ if(GameConfiguration:IsAnyMultiplayer() and pPlayer:IsHuman()) then
+ szOwnerString = szOwnerString .. " (" .. Locale.Lookup(pPlayerConfig:GetPlayerName()) .. ")";
+ end
+
+ table.insert(details, Locale.Lookup("LOC_TOOLTIP_CITY_OWNER",szOwnerString, data.OwningCityName));
+ end
+
+ if(data.FeatureType ~= nil) then
+ local szFeatureString = Locale.Lookup(GameInfo.Features[data.FeatureType].Name);
+ local localPlayer = Players[Game.GetLocalPlayer()];
+ local addCivicName = GameInfo.Features[data.FeatureType].AddCivic;
+ if (localPlayer ~= nil and addCivicName ~= nil) then
+ local civicIndex = GameInfo.Civics[addCivicName].Index;
+ if (localPlayer:GetCulture():HasCivic(civicIndex)) then
+ local szAdditionalString;
+ if (not data.FeatureAdded) then
+ szAdditionalString = Locale.Lookup("LOC_TOOLTIP_PLOT_WOODS_OLD_GROWTH");
+ else
+ szAdditionalString = Locale.Lookup("LOC_TOOLTIP_PLOT_WOODS_SECONDARY");
+ end
+ szFeatureString = szFeatureString .. " " .. szAdditionalString;
+ end
+ end
+ table.insert(details, szFeatureString);
+ end
+ if(data.NationalPark ~= "") then
+ table.insert(details, data.NationalPark);
+ end
+
+ if(data.ResourceType ~= nil) then
+ --if it's a resource that requires a tech to improve, let the player know that in the tooltip
+ local resourceType = data.ResourceType;
+ local resource = GameInfo.Resources[resourceType];
+
+ local resourceString = Locale.Lookup(resource.Name);
+ local resourceTechType;
+ local resourceHash = GameInfo.Resources[resourceType].Hash;
+
+ local terrainType = data.TerrainType;
+ local featureType = data.FeatureType;
+
+ local valid_feature = false;
+ local valid_terrain = false;
+
+ -- Are there any improvements that specifically require this resource?
+ for row in GameInfo.Improvement_ValidResources() do
+ if (row.ResourceType == resourceType) then
+ -- Found one! Now. Can it be constructed on this terrain/feature
+ local improvementType = row.ImprovementType;
+ local has_feature = false;
+ for inner_row in GameInfo.Improvement_ValidFeatures() do
+ if(inner_row.ImprovementType == improvementType) then
+ has_feature = true;
+ if(inner_row.FeatureType == featureType) then
+ valid_feature = true;
+ end
+ end
+ end
+ valid_feature = not has_feature or valid_feature;
+
+ local has_terrain = false;
+ for inner_row in GameInfo.Improvement_ValidTerrains() do
+ if(inner_row.ImprovementType == improvementType) then
+ has_terrain = true;
+ if(inner_row.TerrainType == terrainType) then
+ valid_terrain = true;
+ end
+ end
+ end
+ valid_terrain = not has_terrain or valid_terrain;
+
+ if( GameInfo.Terrains[terrainType].TerrainType == "TERRAIN_COAST") then
+ if ("DOMAIN_SEA" == GameInfo.Improvements[improvementType].Domain) then
+ valid_terrain = true;
+ elseif ("DOMAIN_LAND" == GameInfo.Improvements[improvementType].Domain) then
+ valid_terrain = false;
+ end
+ else
+ if ("DOMAIN_SEA" == GameInfo.Improvements[improvementType].Domain) then
+ valid_terrain = false;
+ elseif ("DOMAIN_LAND" == GameInfo.Improvements[improvementType].Domain) then
+ valid_terrain = true;
+ end
+ end
+
+ if(valid_feature == true and valid_terrain == true) then
+ resourceTechType = GameInfo.Improvements[improvementType].PrereqTech;
+ break;
+ end
+ end
+ end
+ local localPlayer = Players[Game.GetLocalPlayer()];
+ if (localPlayer ~= nil) then
+ local playerResources = localPlayer:GetResources();
+ if(playerResources:IsResourceVisible(resourceHash)) then
+ if (resourceTechType ~= nil and valid_feature == true and valid_terrain == true) then
+ local playerTechs = localPlayer:GetTechs();
+ local techType = GameInfo.Technologies[resourceTechType];
+ if (techType ~= nil and not playerTechs:HasTech(techType.Index)) then
+ resourceString = resourceString .. "[COLOR:Civ6Red] ( " .. Locale.Lookup("LOC_TOOLTIP_REQUIRES") .. " " .. Locale.Lookup(techType.Name) .. ")[ENDCOLOR]";
+ end
+ end
+
+ table.insert(details, resourceString);
+ end
+ end
+ end
+
+ if (data.IsVolcano == true) then
+ local szVolcanoString = Locale.Lookup("LOC_VOLCANO_TOOLTIP_STRING", data.VolcanoName);
+ if (data.Erupting) then
+ szVolcanoString = szVolcanoString .. " " .. Locale.Lookup("LOC_VOLCANO_ERUPTING_STRING");
+ elseif (data.Active) then
+ szVolcanoString = szVolcanoString .. " " .. Locale.Lookup("LOC_VOLCANO_ACTIVE_STRING");
+ end
+ table.insert(details, szVolcanoString);
+ end
+
+ if (data.IsRiver and data.RiverNames) then
+ table.insert(details, Locale.Lookup("LOC_RIVER_TOOLTIP_STRING", data.RiverNames));
+ end
+
+ if (data.TerritoryName ~= nil) then
+ table.insert(details, Locale.Lookup(data.TerritoryName));
+ end
+
+ if (data.Storm ~= -1) then
+ table.insert(details, Locale.Lookup(GameInfo.RandomEvents[data.Storm].Name));
+ end
+
+ if (data.Drought ~= -1) then
+ table.insert(details, Locale.Lookup("LOC_DROUGHT_TOOLTIP_STRING", GameInfo.RandomEvents[data.Drought].Name, data.DroughtTurns));
+ end
+
+ -- Movement cost
+ if (not data.Impassable and data.MovementCost > 0) then
+ table.insert(details, Locale.Lookup("LOC_TOOLTIP_MOVEMENT_COST", data.MovementCost));
+ end
+
+ -- ROUTE TILE
+ if (data.IsRoute and not data.Impassable) then
+ local routeInfo = GameInfo.Routes[data.RouteType];
+ if (routeInfo ~= nil and routeInfo.MovementCost ~= nil and routeInfo.Name ~= nil) then
+
+ local str;
+ if(data.RoutePillaged) then
+ str = Locale.Lookup("LOC_TOOLTIP_ROUTE_MOVEMENT_PILLAGED", routeInfo.MovementCost, routeInfo.Name);
+ else
+ str = Locale.Lookup("LOC_TOOLTIP_ROUTE_MOVEMENT", routeInfo.MovementCost, routeInfo.Name);
+ end
+
+ table.insert(details, str);
+ end
+ end
+
+ -- Defense modifier
+ if (data.DefenseModifier ~= 0) then
+ table.insert(details, Locale.Lookup("LOC_TOOLTIP_DEFENSE_MODIFIER", data.DefenseModifier));
+ end
+
+ -- Appeal
+ local feature = nil;
+ if (data.FeatureType ~= nil) then
+ feature = GameInfo.Features[data.FeatureType];
+ end
+
+ if ((data.FeatureType ~= nil and feature.NaturalWonder) or not data.IsWater) then
+ local strAppealDescriptor;
+ for row in GameInfo.AppealHousingChanges() do
+ local iMinimumValue = row.MinimumValue;
+ local szDescription = row.Description;
+ if (data.Appeal >= iMinimumValue) then
+ strAppealDescriptor = Locale.Lookup(szDescription);
+ break;
+ end
+ end
+ if(strAppealDescriptor) then
+ table.insert(details, Locale.Lookup("LOC_TOOLTIP_APPEAL", strAppealDescriptor, data.Appeal));
+ end
+ end
+
+ -- Do not include ('none') continent line unless continent plot. #35955
+ if (data.Continent ~= nil) then
+ table.insert(details, Locale.Lookup("LOC_TOOLTIP_CONTINENT", GameInfo.Continents[data.Continent].Description));
+ end
+
+ -- Conditional display based on tile type
+
+ -- WONDER TILE
+ if(data.WonderType ~= nil) then
+
+ table.insert(details, "------------------");
+
+ if (data.WonderComplete == true) then
+ table.insert(details, Locale.Lookup(GameInfo.Buildings[data.WonderType].Name));
+
+ else
+
+ table.insert(details, Locale.Lookup(GameInfo.Buildings[data.WonderType].Name) .. " " .. Locale.Lookup("LOC_TOOLTIP_PLOT_CONSTRUCTION_TEXT"));
+ end
+ end
+
+ -- CITY TILE
+ if(data.IsCity == true and data.DistrictType ~= nil) then
+
+ table.insert(details, "------------------");
+
+ table.insert(details, Locale.Lookup(GameInfo.Districts[data.DistrictType].Name))
+
+ for yieldType, v in pairs(data.Yields) do
+ local yield = GameInfo.Yields[yieldType].Name;
+ local yieldicon = GameInfo.Yields[yieldType].IconString;
+ local str = tostring(v) .. Locale.Lookup(yieldicon) .. Locale.Lookup(yield);
+ table.insert(details, str);
+ end
+
+ if(data.ResourceType ~= nil and data.DistrictType ~= nil) then
+ local localPlayer = Players[Game.GetLocalPlayer()];
+ if (localPlayer ~= nil) then
+ local playerResources = localPlayer:GetResources();
+ if(playerResources:IsResourceVisible(resourceHash)) then
+ local resourceTechType = GameInfo.Resources[data.ResourceType].PrereqTech;
+ if (resourceTechType ~= nil) then
+ local playerTechs = localPlayer:GetTechs();
+ local techType = GameInfo.Technologies[resourceTechType];
+ if (techType ~= nil and playerTechs:HasTech(techType.Index)) then
+ local kConsumption:table = GameInfo.Resource_Consumption[data.ResourceType];
+ if (kConsumption ~= nil) then
+ if (kConsumption.Accumulate) then
+ local iExtraction = kConsumption.ImprovedExtractionRate;
+ if (iExtraction > 0) then
+ local resourceName:string = GameInfo.Resources[data.ResourceType].Name;
+ local resourceIcon:string = "[ICON_" .. data.ResourceType .. "]";
+ table.insert(details, Locale.Lookup("LOC_RESOURCE_ACCUMULATION_EXISTING_IMPROVEMENT", iExtraction, resourceIcon, resourceName));
+ end
+ end
+ end
+ end
+ end
+
+ table.insert(details, resourceString);
+ end
+ end
+ end
+
+ --if(data.Buildings ~= nil and table.count(data.Buildings) > 0) then
+ -- table.insert(details, "Buildings: ");
+
+ -- for i, v in ipairs(data.Buildings) do
+ -- table.insert(details, " " .. Locale.Lookup(v));
+ -- end
+ --end
+
+ --if(data.Constructions ~= nil and table.count(data.Constructions) > 0) then
+ -- table.insert(details, "UnderConstruction: ");
+ --
+ -- for i, v in ipairs(data.Constructions) do
+ -- table.insert(details, " " .. Locale.Lookup(v));
+ -- end
+ --end
+
+ -- DISTRICT TILE
+ elseif(data.DistrictID ~= -1 and data.DistrictType ~= nil) then
+ if (not GameInfo.Districts[data.DistrictType].InternalOnly) then --Ignore 'Wonder' districts
+ -- Plot yields (ie. from Specialists)
+ if (data.Yields ~= nil) then
+ if (table.count(data.Yields) > 0) then
+ table.insert(details, "------------------");
+ table.insert(details, Locale.Lookup("LOC_PEDIA_CONCEPTS_PAGE_CITIES_9_CHAPTER_CONTENT_TITLE")); -- "Specialists", text lock :'()
+ end
+ for yieldType, v in pairs(data.Yields) do
+ local yield = GameInfo.Yields[yieldType].Name;
+ local yieldicon = GameInfo.Yields[yieldType].IconString;
+ local str = tostring(v) .. Locale.Lookup(yieldicon) .. Locale.Lookup(yield);
+ table.insert(details, str);
+ end
+ end
+
+ -- Inherent district yields
+ local sDistrictName :string = Locale.Lookup(Locale.Lookup(GameInfo.Districts[data.DistrictType].Name));
+ if (data.DistrictPillaged) then
+ sDistrictName = sDistrictName .. " " .. Locale.Lookup("LOC_TOOLTIP_PLOT_PILLAGED_TEXT");
+ elseif (not data.DistrictComplete) then
+ sDistrictName = sDistrictName .. " " .. Locale.Lookup("LOC_TOOLTIP_PLOT_CONSTRUCTION_TEXT");
+ end
+ table.insert(details, "------------------");
+ table.insert(details, sDistrictName);
+ if (data.DistrictYields ~= nil) then
+ for yieldType, v in pairs(data.DistrictYields) do
+ local yield = GameInfo.Yields[yieldType].Name;
+ local yieldicon = GameInfo.Yields[yieldType].IconString;
+ local str = tostring(v) .. Locale.Lookup(yieldicon) .. Locale.Lookup(yield);
+ table.insert(details, str);
+ end
+ end
+
+ if(data.ResourceType ~= nil and data.DistrictType ~= nil) then
+ local localPlayer = Players[Game.GetLocalPlayer()];
+ if (localPlayer ~= nil) then
+ local playerResources = localPlayer:GetResources();
+ if(playerResources:IsResourceVisible(resourceHash)) then
+ local resourceTechType = GameInfo.Resources[data.ResourceType].PrereqTech;
+ if (resourceTechType ~= nil) then
+ local playerTechs = localPlayer:GetTechs();
+ local techType = GameInfo.Technologies[resourceTechType];
+ if (techType ~= nil and playerTechs:HasTech(techType.Index)) then
+ local kConsumption:table = GameInfo.Resource_Consumption[data.ResourceType];
+ if (kConsumption ~= nil) then
+ if (kConsumption.Accumulate) then
+ local iExtraction = kConsumption.ImprovedExtractionRate;
+ if (iExtraction > 0) then
+ local resourceName:string = GameInfo.Resources[data.ResourceType].Name;
+ local resourceIcon:string = "[ICON_" .. data.ResourceType .. "]";
+ table.insert(details, Locale.Lookup("LOC_RESOURCE_ACCUMULATION_EXISTING_IMPROVEMENT", iExtraction, resourceIcon, resourceName));
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+
+
+ -- OTHER TILE
+ else
+ table.insert(details, "------------------");
+ if(data.ImprovementType ~= nil) then
+ local improvementStr = Locale.Lookup(GameInfo.Improvements[data.ImprovementType].Name);
+ if (data.ImprovementPillaged) then
+ improvementStr = improvementStr .. " " .. Locale.Lookup("LOC_TOOLTIP_PLOT_PILLAGED_TEXT");
+ end
+ table.insert(details, improvementStr)
+ end
+
+ for yieldType, v in pairs(data.Yields) do
+ local yield = GameInfo.Yields[yieldType].Name;
+ local yieldicon = GameInfo.Yields[yieldType].IconString;
+ local str = tostring(v) .. Locale.Lookup(yieldicon) .. Locale.Lookup(yield);
+ table.insert(details, str);
+ end
+
+ if(data.ResourceType ~= nil and data.ImprovementType ~= nil) then
+ local localPlayer = Players[Game.GetLocalPlayer()];
+ if (localPlayer ~= nil) then
+ local playerResources = localPlayer:GetResources();
+ if(playerResources:IsResourceVisible(resourceHash)) then
+ local resourceTechType = GameInfo.Resources[data.ResourceType].PrereqTech;
+ if (resourceTechType ~= nil) then
+ local playerTechs = localPlayer:GetTechs();
+ local techType = GameInfo.Technologies[resourceTechType];
+ if (techType ~= nil and playerTechs:HasTech(techType.Index)) then
+ local kConsumption:table = GameInfo.Resource_Consumption[data.ResourceType];
+ if (kConsumption ~= nil) then
+ if (kConsumption.Accumulate) then
+ local iExtraction = kConsumption.ImprovedExtractionRate;
+ if (iExtraction > 0) then
+ local resourceName:string = GameInfo.Resources[data.ResourceType].Name;
+ local resourceIcon:string = "[ICON_" .. data.ResourceType .. "]";
+ table.insert(details, Locale.Lookup("LOC_RESOURCE_ACCUMULATION_EXISTING_IMPROVEMENT", iExtraction, resourceIcon, resourceName));
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+
+ if(data.Impassable == true) then
+ table.insert(details, Locale.Lookup("LOC_TOOLTIP_PLOT_IMPASSABLE_TEXT"));
+ end
+
+ -- NATURAL WONDER TILE
+ if(data.FeatureType ~= nil) then
+ if(feature.NaturalWonder) then
+ table.insert(details, "------------------");
+ table.insert(details, Locale.Lookup(feature.Description));
+ end
+ end
+
+ -- For districts, city center show all building info including Great Works
+ -- For wonders, just show Great Work info
+ if (data.IsCity or data.WonderType ~= nil or data.DistrictID ~= -1) then
+ if(data.BuildingNames ~= nil and table.count(data.BuildingNames) > 0) then
+ local cityBuildings = data.OwnerCity:GetBuildings();
+ if (data.WonderType == nil) then
+ table.insert(details, Locale.Lookup("LOC_TOOLTIP_PLOT_BUILDINGS_TEXT"));
+ end
+ local greatWorksSection: table = {};
+ for i, v in ipairs(data.BuildingNames) do
+ if (data.WonderType == nil) then
+ if (data.BuildingsPillaged[i]) then
+ table.insert(details, "- " .. Locale.Lookup(v) .. " " .. Locale.Lookup("LOC_TOOLTIP_PLOT_PILLAGED_TEXT"));
+ else
+ table.insert(details, "- " .. Locale.Lookup(v));
+ end
+ end
+ local iSlots = cityBuildings:GetNumGreatWorkSlots(data.BuildingTypes[i]);
+ for j = 0, iSlots - 1, 1 do
+ local greatWorkIndex:number = cityBuildings:GetGreatWorkInSlot(data.BuildingTypes[i], j);
+ if (greatWorkIndex ~= -1) then
+ local greatWorkType:number = cityBuildings:GetGreatWorkTypeFromIndex(greatWorkIndex)
+ table.insert(greatWorksSection, "- " .. Locale.Lookup(GameInfo.GreatWorks[greatWorkType].Name));
+ end
+ end
+ end
+ if #greatWorksSection > 0 then
+ table.insert(details, Locale.Lookup("LOC_GREAT_WORKS") .. ":");
+ for i, v in ipairs(greatWorksSection) do
+ table.insert(details, v);
+ end
+ end
+ end
+ end
+
+ -- Show number of civilians working here
+ if (data.Owner == Game.GetLocalPlayer() and data.Workers > 0) then
+ table.insert(details, Locale.Lookup("LOC_TOOLTIP_PLOT_WORKED_TEXT", data.Workers));
+ end
+
+ if (data.Fallout > 0) then
+ table.insert(details, Locale.Lookup("LOC_TOOLTIP_PLOT_CONTAMINATED_TEXT", data.Fallout));
+ end
+
+ if (data.CoastalLowland ~= -1) then
+ local szDetailsText = "";
+ if (data.CoastalLowland == 0) then
+ szDetailsText = Locale.Lookup("LOC_COASTAL_LOWLAND_1M_NAME");
+ elseif (data.CoastalLowland == 1) then
+ szDetailsText = Locale.Lookup("LOC_COASTAL_LOWLAND_2M_NAME");
+ elseif (data.CoastalLowland == 2) then
+ szDetailsText = Locale.Lookup("LOC_COASTAL_LOWLAND_3M_NAME");
+ end
+ if (data.Submerged) then
+ szDetailsText = szDetailsText .. " " .. Locale.Lookup ("LOC_COASTAL_LOWLAND_SUBMERGED");
+ elseif (data.Flooded) then
+ szDetailsText = szDetailsText .. " " .. Locale.Lookup ("LOC_COASTAL_LOWLAND_FLOODED");
+ end
+ table.insert(details, szDetailsText);
+ end
+
+ return details;
+end
\ No newline at end of file
diff --git a/Replacements/RazeCity_Expansion2.lua b/Replacements/RazeCity_Expansion2.lua
new file mode 100644
index 0000000..5fe90b2
--- /dev/null
+++ b/Replacements/RazeCity_Expansion2.lua
@@ -0,0 +1,108 @@
+-- Copyright 2018, Firaxis Games
+include("RazeCity");
+
+-- ===========================================================================
+-- OVERRIDES
+-- ===========================================================================
+
+-- ===========================================================================
+function OnOpen()
+ local localPlayerID = Game.GetLocalPlayer();
+ local localPlayer = Players[localPlayerID];
+ if (localPlayer == nil) then
+ return;
+ end
+
+ g_pSelectedCity = localPlayer:GetCities():GetNextCapturedCity();
+
+ Controls.PanelHeader:LocalizeAndSetText("LOC_RAZE_CITY_HEADER");
+ Controls.CityHeader:LocalizeAndSetText("LOC_RAZE_CITY_NAME_LABEL");
+ Controls.CityName:LocalizeAndSetText(g_pSelectedCity:GetName());
+ Controls.CityPopulation:LocalizeAndSetText("LOC_RAZE_CITY_POPULATION_LABEL");
+ Controls.NumPeople:SetText(tostring(g_pSelectedCity:GetPopulation()));
+ Controls.CityDistricts:LocalizeAndSetText("LOC_RAZE_CITY_DISTRICTS_LABEL");
+ local iNumDistricts = g_pSelectedCity:GetDistricts():GetNumZonedDistrictsRequiringPopulation();
+ Controls.NumDistricts:SetText(tostring(iNumDistricts));
+
+ local szWarmongerString;
+ local eOriginalOwner = g_pSelectedCity:GetOriginalOwner();
+ local originalOwnerPlayer = Players[eOriginalOwner];
+ local eOwnerBeforeOccupation = g_pSelectedCity:GetOwnerBeforeOccupation();
+ local eConqueredFrom = g_pSelectedCity:GetJustConqueredFrom();
+ local bWipedOut = (originalOwnerPlayer:GetCities():GetCount() < 1);
+ local eLastTransferType = g_pSelectedCity:GetLastTransferType();
+ local iFavorForLiberation = GlobalParameters.FAVOR_FOR_LIBERATE_PLAYER_CITY;
+ local pPlayerConfig = PlayerConfigurations[eOriginalOwner];
+ local isMinorCiv = pPlayerConfig:GetCivilizationLevelTypeID() ~= CivilizationLevelTypes.CIVILIZATION_LEVEL_FULL_CIV;
+ if (isMinorCiv) then
+ iFavorForLiberation = GlobalParameters.FAVOR_FOR_LIBERATE_CITY_STATE;
+ end
+ local cities = originalOwnerPlayer:GetCities();
+ if (not isMinorCiv and cities:GetCount() == 0) then
+ iFavorForLiberation = iFavorForLiberation + GlobalParameters.FAVOR_FOR_REVIVE_PLAYER;
+ end
+
+ if (eOriginalOwner ~= eOwnerBeforeOccupation and localPlayer:GetDiplomacy():CanLiberateCityTo(eOriginalOwner) and eOriginalOwner ~= eConqueredFrom) then
+ Controls.Button1:LocalizeAndSetText("LOC_RAZE_CITY_LIBERATE_FOUNDER_BUTTON_LABEL", PlayerConfigurations[eOriginalOwner]:GetCivilizationShortDescription());
+ szWarmongerString = Locale.Lookup("LOC_XP2_RAZE_CITY_LIBERATE_WARMONGER_EXPLANATION", iFavorForLiberation);
+ Controls.Button1:LocalizeAndSetToolTip("LOC_RAZE_CITY_LIBERATE_EXPLANATION", szWarmongerString);
+ Controls.Button1:SetHide(false);
+ else
+ Controls.Button1:SetHide(true);
+ end
+
+ if (localPlayer:GetDiplomacy():CanLiberateCityTo(eOwnerBeforeOccupation) and eOwnerBeforeOccupation ~= eConqueredFrom) then
+ Controls.Button2:LocalizeAndSetText("LOC_RAZE_CITY_LIBERATE_PREWAR_OWNER_BUTTON_LABEL", PlayerConfigurations[eOwnerBeforeOccupation]:GetCivilizationShortDescription());
+ szWarmongerString = Locale.Lookup("LOC_XP2_RAZE_CITY_LIBERATE_WARMONGER_EXPLANATION", iFavorForLiberation);
+ Controls.Button2:LocalizeAndSetToolTip("LOC_RAZE_CITY_LIBERATE_EXPLANATION", szWarmongerString);
+ Controls.Button2:SetHide(false);
+ else
+ Controls.Button2:SetHide(true);
+ end
+
+ Controls.Button3:LocalizeAndSetText("LOC_RAZE_CITY_KEEP_BUTTON_LABEL");
+ if (eLastTransferType == CityTransferTypes.BY_GIFT) then
+ szWarmongerString = Locale.Lookup("LOC_RAZE_CITY_KEEP_EXPLANATION_TRADED");
+ Controls.Button3:LocalizeAndSetToolTip(szWarmongerString);
+ elseif (Players[eConqueredFrom]:IsFreeCities()) then
+ Controls.Button3:LocalizeAndSetToolTip("LOC_XP2_RAZE_CITY_KEEP_FREE_CITY_EXPLANATION");
+ elseif (bWipedOut ~= true) then
+ local iWarmongerPoints = localPlayer:GetDiplomacy():ComputeCityWarmongerPoints(g_pSelectedCity, eConqueredFrom, false);
+ szWarmongerString = Locale.Lookup("LOC_XP2_RAZE_CITY_KEEP_WARMONGER_EXPLANATION", iWarmongerPoints);
+ Controls.Button3:LocalizeAndSetToolTip("LOC_RAZE_CITY_KEEP_EXPLANATION", szWarmongerString);
+ else
+ local iWarmongerPoints = localPlayer:GetDiplomacy():ComputeCityWarmongerPoints(g_pSelectedCity, eConqueredFrom, false);
+ iWarmongerPoints = (iWarmongerPoints * GlobalParameters.WARMONGER_FINAL_MAJOR_CITY_MULTIPLIER) / 100;
+ szWarmongerString = Locale.Lookup("LOC_XP2_RAZE_CITY_KEEP_LAST_CITY_EXPLANATION", iWarmongerPoints);
+ Controls.Button3:LocalizeAndSetToolTip(szWarmongerString);
+ end
+
+ Controls.Button4:LocalizeAndSetText("LOC_RAZE_CITY_RAZE_BUTTON_LABEL");
+ if (g_pSelectedCity:CanRaze()) then
+ if (Players[eConqueredFrom]:IsFreeCities()) then
+ Controls.Button4:LocalizeAndSetToolTip("LOC_XP2_RAZE_CITY_RAZE_FREE_CITY_EXPLANATION");
+ elseif (bWipedOut ~= true) then
+ local iWarmongerPoints = localPlayer:GetDiplomacy():ComputeCityWarmongerPoints(g_pSelectedCity, eConqueredFrom, true);
+ szWarmongerString = Locale.Lookup("LOC_XP2_RAZE_CITY_RAZE_WARMONGER_EXPLANATION", iWarmongerPoints);
+ Controls.Button4:LocalizeAndSetToolTip("LOC_RAZE_CITY_RAZE_EXPLANATION", szWarmongerString);
+ else
+ local iWarmongerPoints = localPlayer:GetDiplomacy():ComputeCityWarmongerPoints(g_pSelectedCity, eConqueredFrom, true);
+ szWarmongerString = Locale.Lookup("LOC_XP2_RAZE_CITY_RAZE_LAST_CITY_EXPLANATION", iWarmongerPoints);
+ Controls.Button4:LocalizeAndSetToolTip(szWarmongerString);
+ end
+ Controls.Button4:SetDisabled(false);
+ else
+ Controls.Button4:LocalizeAndSetToolTip("LOC_RAZE_CITY_RAZE_DISABLED_EXPLANATION");
+ Controls.Button4:SetDisabled(true);
+
+ end
+
+ Controls.PopupStack:CalculateSize();
+
+ UIManager:QueuePopup(ContextPtr, PopupPriority.Medium);
+
+ Controls.PopupAlphaIn:SetToBeginning();
+ Controls.PopupAlphaIn:Play();
+ Controls.PopupSlideIn:SetToBeginning();
+ Controls.PopupSlideIn:Play();
+end
diff --git a/Replacements/ReportScreen.xml b/Replacements/ReportScreen.xml
index 85f16c9..eb6f05c 100644
--- a/Replacements/ReportScreen.xml
+++ b/Replacements/ReportScreen.xml
@@ -3,7 +3,7 @@
-
+
@@ -19,7 +19,7 @@
-
+
@@ -126,11 +126,11 @@
-
+
-
+
-
+
@@ -348,7 +348,7 @@
-
+
@@ -633,7 +633,7 @@
-
+
diff --git a/Replacements/ReportScreen_Expansion2.lua b/Replacements/ReportScreen_Expansion2.lua
new file mode 100644
index 0000000..0f7b549
--- /dev/null
+++ b/Replacements/ReportScreen_Expansion2.lua
@@ -0,0 +1,276 @@
+-- Copyright 2017-2018, 2017 Firaxis Games
+include("ReportScreen_Expansion1");
+
+-- ===========================================================================
+-- Constants
+-- ===========================================================================
+local SIZE_HEIGHT_PADDING_BOTTOM_ADJUST :number = 85; -- (Total Y - (scroll area + THIS PADDING)) = bottom area
+
+
+-- ===========================================================================
+-- Override base game
+-- ===========================================================================
+function AppendXP2ResourceData(kResourceData:table)
+ local playerID:number = Game.GetLocalPlayer();
+ if playerID == PlayerTypes.NONE then
+ UI.DataError("Unable to get valid playerID for ReportScreen_Expansion2.");
+ return;
+ end
+
+ local player:table = Players[playerID];
+
+ local pResources:table = player:GetResources();
+ if pResources then
+ for row in GameInfo.Resources() do
+ local resourceHash:number = row.Hash;
+ local resourceUnitCostPerTurn:number = pResources:GetUnitResourceDemandPerTurn(resourceHash);
+ local resourcePowerCostPerTurn:number = pResources:GetPowerResourceDemandPerTurn(resourceHash);
+ local reservedCostForProduction:number = pResources:GetReservedResourceAmount(resourceHash);
+ local miscResourceTotal:number = pResources:GetResourceAmount(resourceHash);
+ local importResources:number = pResources:GetResourceImportPerTurn(resourceHash);
+
+ if resourceUnitCostPerTurn > 0 then
+ AddResourceData(kResourceData, row.Index, "LOC_PRODUCITON_PANEL_UNITS_TOOLTIP", "-", -resourceUnitCostPerTurn);
+ end
+
+ if resourcePowerCostPerTurn > 0 then
+ AddResourceData(kResourceData, row.Index, "LOC_UI_PEDIA_POWER_COST", "-", -resourcePowerCostPerTurn);
+ end
+
+ if reservedCostForProduction > 0 then
+ AddResourceData(kResourceData, row.Index, "LOC_RESOURCE_REPORTS_ITEM_IN_RESERVE", "-", -reservedCostForProduction);
+ end
+
+ if kResourceData[row.Index] == nil and miscResourceTotal > 0 then
+ local titleString:string = importResources > 0 and "LOC_RESOURCE_REPORTS_CITY_STATES" or "LOC_HUD_REPORTS_MISC_RESOURCE_SOURCE";
+ AddResourceData(kResourceData, row.Index, titleString, "-", miscResourceTotal);
+ elseif importResources > 0 then
+ AddResourceData(kResourceData, row.Index, "LOC_RESOURCE_REPORTS_CITY_STATES", "-", importResources);
+ end
+
+ end
+ end
+
+ return kResourceData;
+end
+
+function AddResourceData( kResources:table, eResourceType:number, EntryString:string, ControlString:string, InAmount:number)
+ local kResource :table = GameInfo.Resources[eResourceType];
+
+ --Artifacts need to be excluded because while TECHNICALLY a resource, they do nothing to contribute in a way that is relevant to any other resource
+ --or screen. So... exclusion.
+ if kResource.ResourceClassType == "RESOURCECLASS_ARTIFACT" then
+ return;
+ end
+
+ local localPlayerID = Game.GetLocalPlayer();
+ local localPlayer = Players[localPlayerID];
+ if localPlayer then
+ local pPlayerResources:table = localPlayer:GetResources();
+ if pPlayerResources then
+ if kResources[eResourceType] == nil then
+ kResources[eResourceType] = {
+ EntryList = {},
+ Icon = "[ICON_"..kResource.ResourceType.."]",
+ IsStrategic = kResource.ResourceClassType == "RESOURCECLASS_STRATEGIC",
+ IsLuxury = GameInfo.Resources[eResourceType].ResourceClassType == "RESOURCECLASS_LUXURY",
+ IsBonus = GameInfo.Resources[eResourceType].ResourceClassType == "RESOURCECLASS_BONUS",
+ Total = 0,
+ Maximum = pPlayerResources:GetResourceStockpileCap(eResourceType),
+ Stockpile = pPlayerResources:GetResourceAmount(eResourceType)
+ };
+ end
+
+ if EntryString ~= "" then
+ table.insert( kResources[eResourceType].EntryList,
+ {
+ EntryText = EntryString,
+ ControlText = ControlString,
+ Amount = InAmount,
+ });
+ end
+
+ kResources[eResourceType].Total = kResources[eResourceType].Total + InAmount;
+ end
+ end
+end
+
+function AddMiscResourceData(pResourceData:table, kResourceTable:table)
+ --Append our resource entries before we continue
+ kResourceTable = AppendXP2ResourceData(kResourceTable);
+
+ -- Resources not yet accounted for come from other gameplay bonuses
+ if pResourceData then
+ for row in GameInfo.Resources() do
+ local internalResourceAmount:number = pResourceData:GetResourceAmount(row.Index);
+ local resourceUnitConsumptionPerTurn:number = -pResourceData:GetUnitResourceDemandPerTurn(row.ResourceType);
+ local resourcePowerConsumptionPerTurn:number = -pResourceData:GetPowerResourceDemandPerTurn(row.ResourceType);
+ local resourceAccumulationPerTurn:number = pResourceData:GetResourceAccumulationPerTurn(row.ResourceType);
+ local resourceDelta:number = resourceUnitConsumptionPerTurn + resourcePowerConsumptionPerTurn + resourceAccumulationPerTurn;
+ if (row.ResourceClassType == "RESOURCECLASS_STRATEGIC") then
+ internalResourceAmount = resourceDelta;
+ end
+ if (internalResourceAmount > 0 or internalResourceAmount < 0) then
+ if (kResourceTable[row.Index] ~= nil) then
+ if (internalResourceAmount > kResourceTable[row.Index].Total) then
+ AddResourceData(kResourceTable, row.Index, "LOC_HUD_REPORTS_MISC_RESOURCE_SOURCE", "-", internalResourceAmount - kResourceTable[row.Index].Total);
+ end
+ else
+ AddResourceData(kResourceTable, row.Index, "LOC_HUD_REPORTS_MISC_RESOURCE_SOURCE", "-", internalResourceAmount);
+ end
+ end
+
+ --Stockpile only?
+ if pResourceData:GetResourceAmount(row.ResourceType) > 0 then
+ AddResourceData(kResourceTable, row.Index, "", "", 0);
+ end
+
+ end
+ end
+
+ return kResourceTable;
+end
+
+-- ===========================================================================
+-- Tab Callback
+-- ===========================================================================
+function ViewResourcesPage()
+
+ ResetTabForNewPageContent();
+
+ local strategicResources:string = "";
+ local luxuryResources :string = "";
+ local kBonuses :table = {};
+ local kLuxuries :table = {};
+ local kStrategics :table = {};
+
+
+ for eResourceType,kSingleResourceData in pairs(m_kResourceData) do
+
+ if next(kSingleResourceData.EntryList) then
+ local instance:table = NewCollapsibleGroupInstance();
+
+ local kResource :table = GameInfo.Resources[eResourceType];
+ instance.RowHeaderButton:SetText( kSingleResourceData.Icon..Locale.Lookup( kResource.Name ) );
+
+ local pHeaderInstance:table = {};
+ ContextPtr:BuildInstanceForControl( "ResourcesHeaderInstance", pHeaderInstance, instance.ContentStack ) ;
+
+ local kResourceEntries:table = kSingleResourceData.EntryList;
+ for i,kEntry in ipairs(kResourceEntries) do
+ local pEntryInstance:table = {};
+ ContextPtr:BuildInstanceForControl( "ResourcesEntryInstance", pEntryInstance, instance.ContentStack ) ;
+ pEntryInstance.CityName:SetText( Locale.Lookup(kEntry.EntryText) );
+ pEntryInstance.Control:SetText( Locale.Lookup(kEntry.ControlText) );
+ pEntryInstance.Amount:SetText( (kEntry.Amount<=0) and tostring(kEntry.Amount) or "+"..tostring(kEntry.Amount) );
+ end
+
+ local pFooterInstance:table = {};
+ ContextPtr:BuildInstanceForControl( "ResourcesFooterInstance", pFooterInstance, instance.ContentStack ) ;
+ local valueString:string = tostring(kSingleResourceData.Total);
+ if kSingleResourceData.IsStrategic then
+ if kSingleResourceData.Total > 0 then
+ valueString = "+" .. valueString;
+ end
+ end
+ pFooterInstance.Amount:SetText( valueString );
+
+ -- Show how many of this resource are being allocated to what cities
+ local localPlayerID = Game.GetLocalPlayer();
+ local localPlayer = Players[localPlayerID];
+ local citiesProvidedTo: table = localPlayer:GetResources():GetResourceAllocationCities(GameInfo.Resources[kResource.ResourceType].Index);
+ local numCitiesProvidingTo: number = table.count(citiesProvidedTo);
+ if (numCitiesProvidingTo > 0) then
+ pFooterInstance.AmenitiesContainer:SetHide(false);
+ pFooterInstance.Amenities:SetText("[ICON_Amenities][ICON_GoingTo]" .. Locale.Lookup("LOC_HUD_REPORTS_CITY_AMENITIES", numCitiesProvidingTo));
+ local amenitiesTooltip: string = "";
+ local playerCities = localPlayer:GetCities();
+ for i,city in ipairs(citiesProvidedTo) do
+ local cityName = Locale.Lookup(playerCities:FindID(city.CityID):GetName());
+ if i ~=1 then
+ amenitiesTooltip = amenitiesTooltip.. "[NEWLINE]";
+ end
+ amenitiesTooltip = amenitiesTooltip.. city.AllocationAmount.." [ICON_".. kResource.ResourceType.."] [Icon_GoingTo] " ..cityName;
+ end
+ pFooterInstance.Amenities:SetToolTipString(amenitiesTooltip);
+ else
+ pFooterInstance.AmenitiesContainer:SetHide(true);
+ end
+ SetGroupCollapsePadding(instance, pFooterInstance.Top:GetSizeY() );
+ RealizeGroup( instance );
+ end
+
+ if kSingleResourceData.IsStrategic then
+ table.insert(kStrategics, kSingleResourceData.Icon .. " " .. tostring( kSingleResourceData.Stockpile ) .. "/" .. tostring(kSingleResourceData.Maximum));
+ elseif kSingleResourceData.IsLuxury then
+ table.insert(kLuxuries, kSingleResourceData.Icon .. tostring( kSingleResourceData.Total ) );
+ else
+ table.insert(kBonuses, kSingleResourceData.Icon .. tostring( kSingleResourceData.Total ) );
+ end
+ end
+
+ m_strategicResourcesIM:ResetInstances();
+ for i,v in ipairs(kStrategics) do
+ local resourceInstance:table = m_strategicResourcesIM:GetInstance();
+ resourceInstance.Info:SetText( v );
+ end
+ Controls.StrategicResources:CalculateSize();
+ Controls.StrategicGrid:ReprocessAnchoring();
+
+ m_bonusResourcesIM:ResetInstances();
+ for i,v in ipairs(kBonuses) do
+ local resourceInstance:table = m_bonusResourcesIM:GetInstance();
+ resourceInstance.Info:SetText( v );
+ end
+ Controls.BonusResources:CalculateSize();
+ Controls.BonusGrid:ReprocessAnchoring();
+
+ m_luxuryResourcesIM:ResetInstances();
+ for i,v in ipairs(kLuxuries) do
+ local resourceInstance:table = m_luxuryResourcesIM:GetInstance();
+ resourceInstance.Info:SetText( v );
+ end
+
+ Controls.LuxuryResources:CalculateSize();
+ Controls.LuxuryResources:ReprocessAnchoring();
+ Controls.LuxuryGrid:ReprocessAnchoring();
+
+ Controls.Stack:CalculateSize();
+ Controls.Scroll:CalculateSize();
+
+ Controls.CollapseAll:SetHide(false);
+ Controls.BottomYieldTotals:SetHide( true );
+ Controls.BottomResourceTotals:SetHide( false );
+ Controls.Scroll:SetSizeY( Controls.Main:GetSizeY() - (Controls.BottomResourceTotals:GetSizeY() + SIZE_HEIGHT_PADDING_BOTTOM_ADJUST ) );
+end
+
+-- ===========================================================================
+function GetCityResourceData( pCity:table )
+ -- Loop through all the plots for a given city; tallying the resource amount.
+ local kResources : table = {};
+ local localPlayerID = Game.GetLocalPlayer();
+ local localPlayer = Players[localPlayerID];
+ if localPlayer then
+ local pPlayerResources:table = localPlayer:GetResources();
+ if pPlayerResources then
+ local kExtractedResources = pPlayerResources:GetResourcesExtractedByCity( pCity:GetID(), ResultFormat.SUMMARY );
+ if kExtractedResources ~= nil and table.count(kExtractedResources) > 0 then
+ for i, entry in ipairs(kExtractedResources) do
+ if entry.Amount > 0 then
+ kResources[entry.ResourceType] = entry.Amount;
+ end
+ end
+ end
+ end
+ end
+ return kResources;
+end
+
+-- ===========================================================================
+function Resize()
+ local topPanelSizeY:number = 10;
+
+ x,y = UIManager:GetScreenSizeVal();
+ Controls.Main:SetSizeY( y - topPanelSizeY );
+ Controls.Main:SetOffsetY( topPanelSizeY * 0.5 );
+end
diff --git a/Replacements/ResearchListInstance.xml b/Replacements/ResearchListInstance.xml
new file mode 100644
index 0000000..791f198
--- /dev/null
+++ b/Replacements/ResearchListInstance.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Replacements/SelectedUnit_Expansion2.lua b/Replacements/SelectedUnit_Expansion2.lua
new file mode 100644
index 0000000..b3b87ca
--- /dev/null
+++ b/Replacements/SelectedUnit_Expansion2.lua
@@ -0,0 +1,73 @@
+
+--[[
+-- Copyright (c) Firaxis Games 2018
+--]]
+
+-- ===========================================================================
+-- INCLUDES
+-- ===========================================================================
+include("SelectedUnit");
+
+-- ===========================================================================
+-- OVERRIDE BASE FUNCTIONS
+-- ===========================================================================
+function RealizeGreatPersonLens(kUnit:table )
+ UILens.ClearLayerHexes(m_HexColoringGreatPeople);
+ if UILens.IsLayerOn( m_HexColoringGreatPeople ) then
+ UILens.ToggleLayerOff(m_HexColoringGreatPeople);
+ end
+ if kUnit ~= nil and ( not UI.IsGameCoreBusy() ) then
+ local playerID:number = kUnit:GetOwner();
+ if playerID == Game.GetLocalPlayer() then
+ local kUnitArchaeology:table = kUnit:GetArchaeology();
+ local kUnitGreatPerson:table = kUnit:GetGreatPerson();
+ local kUnitRockBand:table = kUnit:GetRockBand();
+ if kUnitGreatPerson ~= nil and kUnitGreatPerson:IsGreatPerson() then
+ local greatPersonInfo:table = GameInfo.GreatPersonIndividuals[kUnitGreatPerson:GetIndividual()];
+ -- Highlight an area around the Great Person (if they have an area of effect trait)
+ local areaHighlightPlots:table = {};
+ if (greatPersonInfo ~= nil and greatPersonInfo.AreaHighlightRadius ~= nil) then
+ areaHighlightPlots = kUnitGreatPerson:GetAreaHighlightPlots();
+ end
+ -- Highlight the plots the Great Person could use its action on
+ local activationPlots:table = {};
+ if (greatPersonInfo ~= nil and greatPersonInfo.ActionEffectTileHighlighting ~= nil and greatPersonInfo.ActionEffectTileHighlighting) then
+ local rawActivationPlots:table = kUnitGreatPerson:GetActivationHighlightPlots();
+ for _,plotIndex:number in ipairs(rawActivationPlots) do
+ table.insert(activationPlots, {"Great_People", plotIndex});
+ end
+ end
+ UILens.SetLayerHexesArea(m_HexColoringGreatPeople, playerID, areaHighlightPlots, activationPlots);
+ UILens.ToggleLayerOn(m_HexColoringGreatPeople);
+ elseif( kUnitArchaeology ~= nil and GameInfo.Units[kUnit:GetUnitType()].ExtractsArtifacts == true) then
+ -- Highlight plots that can activated by Archaeologists
+ local activationPlots:table = {};
+ local rawActivationPlots:table = kUnitArchaeology:GetActivationHighlightPlots();
+ for _,plotIndex:number in ipairs(rawActivationPlots) do
+ table.insert(activationPlots, {"Great_People", plotIndex});
+ end
+
+ UILens.SetLayerHexesArea(m_HexColoringGreatPeople, playerID, {}, activationPlots);
+ UILens.ToggleLayerOn(m_HexColoringGreatPeople);
+ elseif GameInfo.Units[kUnit:GetUnitType()].ParkCharges > 0 and kUnit:GetParkCharges() > 0 then -- Highlight plots that can activated by Naturalists
+ local parkPlots:table = {};
+ local rawParkPlots:table = Game.GetNationalParks():GetPossibleParkTiles(playerID);
+ for _,plotIndex:number in ipairs(rawParkPlots) do
+ table.insert(parkPlots, {"Great_People", plotIndex});
+ end
+ UILens.SetLayerHexesArea(m_HexColoringGreatPeople, playerID, {}, parkPlots);
+ UILens.ToggleLayerOn(m_HexColoringGreatPeople);
+ elseif kUnitRockBand ~= nil and GameInfo.Units[kUnit:GetUnitType()].UnitType == "UNIT_ROCK_BAND" then -- Highlight plots that can activated by RockBands
+ -- Highlight the plots the RockBand could use its action on
+ local activationPlots:table = {};
+ local rawActivationPlots:table = kUnitRockBand:GetActivationHighlightPlots();
+ for _,plotIndex:number in ipairs(rawActivationPlots) do
+ table.insert(activationPlots, {"Great_People", plotIndex});
+ end
+
+ UILens.SetLayerHexesArea(m_HexColoringGreatPeople, playerID, {}, activationPlots);
+ UILens.ToggleLayerOn(m_HexColoringGreatPeople);
+ end
+ end
+ end
+end
diff --git a/Replacements/TechTreeNode.xml b/Replacements/TechTreeNode.xml
index 03466d7..fa7511a 100644
--- a/Replacements/TechTreeNode.xml
+++ b/Replacements/TechTreeNode.xml
@@ -1,33 +1,34 @@
-
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
diff --git a/Replacements/TechTree_Expansion2.lua b/Replacements/TechTree_Expansion2.lua
new file mode 100644
index 0000000..16f3c7e
--- /dev/null
+++ b/Replacements/TechTree_Expansion2.lua
@@ -0,0 +1,302 @@
+-- ===========================================================================
+-- TechTree Replacement
+-- Civilization VI, Firaxis Games
+-- ===========================================================================
+include("TechTree_Expansion1");
+
+-- ===========================================================================
+-- Add to base tables
+-- ===========================================================================
+local BASE_GetCurrentData = GetCurrentData;
+
+
+-- Add to item status table. Instead of enum use hash of "UNREVEALED"; special case.
+ITEM_STATUS["UNREVEALED"] = 0xB87BE593;
+STATUS_ART[ITEM_STATUS.UNREVEALED] = { Name="UNREVEALED", TextColor0=0xff202726, TextColor1=0x00000000, FillTexture="TechTree_GearButtonTile_Disabled.dds",BGU=0,BGV=(SIZE_NODE_Y*3), IsButton=false, BoltOn=false, IconBacking=PIC_METER_BACK };
+
+
+-- ===========================================================================
+-- Complete override
+-- ===========================================================================
+function PopulateItemData() -- Note that we are overriding this function without calling its base version. This version requires no parameters.
+
+ local kItemDefaults :table = {}; -- Table to return
+
+ function GetHash(t)
+ local r = GameInfo.Types[t];
+ if(r) then
+ return r.Hash;
+ else
+ return 0;
+ end
+ end
+
+ local techNodes:table = Game.GetTechs():GetActiveTechNodes();
+ for _,techNode in ipairs(techNodes) do
+
+ local row:table = GameInfo.Technologies[techNode.TechType];
+
+ local kEntry:table = {};
+ kEntry.Type = row.TechnologyType;
+ kEntry.Name = row.Name;
+ kEntry.BoostText = "";
+ kEntry.Column = -1;
+ kEntry.Cost = techNode.Cost;
+ kEntry.Description = row.Description and Locale.Lookup( row.Description );
+ kEntry.EraType = row.EraType;
+ kEntry.Hash = GetHash(kEntry.Type);
+ kEntry.Index = row.Index;
+ kEntry.IsBoostable = false;
+ kEntry.Prereqs = {}; -- IDs for prerequisite item(s)
+ kEntry.UITreeRow = row.UITreeRow;
+ kEntry.Unlocks = {}; -- Each unlock has: unlockType, iconUnavail, iconAvail, tooltip
+
+ -- Boost?
+ for boostRow in GameInfo.Boosts() do
+ if boostRow.TechnologyType == kEntry.Type then
+ kEntry.BoostText = Locale.Lookup( boostRow.TriggerDescription );
+ kEntry.IsBoostable = true;
+ kEntry.BoostAmount = boostRow.Boost;
+ break;
+ end
+ end
+
+ if (table.count(techNode.PrereqTechTypes) > 0) then
+ for __,prereqTechType in ipairs(techNode.PrereqTechTypes) do
+ local prereqRow:table = GameInfo.Technologies[prereqTechType];
+ table.insert( kEntry.Prereqs, prereqRow.TechnologyType );
+ end
+ end
+ -- If no prereqs were found, set item to special tree start value
+ if table.count(kEntry.Prereqs) == 0 then
+ table.insert(kEntry.Prereqs, PREREQ_ID_TREE_START);
+ end
+
+ -- Warn if DB has an out of bounds entry.
+ if kEntry.UITreeRow < ROW_MIN or kEntry.UITreeRow > ROW_MAX then
+ UI.DataError("UITreeRow for '"..kEntry.Type.."' has an out of bound UITreeRow="..tostring(kEntry.UITreeRow).." MIN="..tostring(ROW_MIN).." MAX="..tostring(ROW_MAX));
+ end
+
+ AddTechToEra( kEntry );
+
+ -- Save entry into master list.
+ kItemDefaults[kEntry.Type] = kEntry;
+ end
+
+ return kItemDefaults;
+end
+
+-- ===========================================================================
+-- Fill out live data from base game and then add IsRevealed to items.
+-- ===========================================================================
+function GetCurrentData( ePlayer:number, eCompletedTech:number )
+ local kData:table = BASE_GetCurrentData(ePlayer, eCompletedTech );
+
+ -- Loop through all items and add an IsRevealed field.
+ local playerTechs:table = Players[ePlayer]:GetTechs();
+ if (playerTechs ~= nil) then
+ for type,item in pairs(g_kItemDefaults) do
+ kData[DATA_FIELD_LIVEDATA][type]["IsRevealed"] = playerTechs:IsTechRevealed(item.Index);
+ end
+ end
+ return kData;
+end
+
+-- ===========================================================================
+-- Complete override
+-- Hide node content which is not revealed (has not been discovered)
+-- ===========================================================================
+function PopulateNode(uiNode, playerTechData)
+ local item :table = g_kItemDefaults[uiNode.Type]; -- static item data
+ local live :table = playerTechData[DATA_FIELD_LIVEDATA][uiNode.Type]; -- live (changing) data
+ local status :number = live.IsRevealed and live.Status or ITEM_STATUS.UNREVEALED;
+ local artInfo :table = STATUS_ART[status]; -- art/styles for this state
+
+ if(status == ITEM_STATUS.RESEARCHED) then
+ for _,prereqId in pairs(item.Prereqs) do
+ if(prereqId ~= PREREQ_ID_TREE_START) then
+ local prereq :table = g_kItemDefaults[prereqId];
+ local previousRow :number = prereq.UITreeRow;
+ local previousColumn:number = g_kEras[prereq.EraType].PriorColumns;
+
+ for lineNum,line in pairs(g_uiConnectorSets[item.Type..","..prereqId]) do
+ if(lineNum == 1 or lineNum == 5) then
+ line:SetTexture("Controls_TreePathEW");
+ end
+ if( lineNum == 3) then
+ line:SetTexture("Controls_TreePathNS");
+ end
+
+ if(lineNum == 2)then
+ if previousRow < item.UITreeRow then
+ line:SetTexture("Controls_TreePathSE");
+ else
+ line:SetTexture("Controls_TreePathNE");
+ end
+ end
+
+ if(lineNum == 4)then
+ if previousRow < item.UITreeRow then
+ line:SetTexture("Controls_TreePathES");
+ else
+ line:SetTexture("Controls_TreePathEN");
+ end
+ end
+ end
+ end
+ end
+ end
+
+ uiNode.NodeName:SetColor( artInfo.TextColor0, 0 );
+ uiNode.NodeName:SetColor( artInfo.TextColor1, 1 );
+
+ uiNode.UnlockStack:SetHide( status==ITEM_STATUS.UNREVEALED ); -- Show/hide unlockables based on revealed status.
+
+ local nodeName :string = (status==ITEM_STATUS.UNREVEALED) and Locale.Lookup("LOC_TECH_TREE_UNREVEALED_TECH") or Locale.Lookup(item.Name);
+ if debugShowIDWithName then
+ uiNode.NodeName:SetText( tostring(item.Index).." ".. nodeName); -- Debug output
+ else
+ uiNode.NodeName:SetText( Locale.ToUpper( nodeName )); -- Normal output
+ end
+
+ if live.Turns > 0 then
+ uiNode.Turns:SetHide( false );
+ uiNode.Turns:SetColor( artInfo.TextColor0, 0 );
+ uiNode.Turns:SetColor( artInfo.TextColor1, 1 );
+ uiNode.Turns:SetText( Locale.Lookup("LOC_TECH_TREE_TURNS",live.Turns) );
+ else
+ uiNode.Turns:SetHide( true );
+ end
+
+ if item.IsBoostable and status ~= ITEM_STATUS.RESEARCHED and status ~= ITEM_STATUS.UNREVEALED then
+ uiNode.BoostIcon:SetHide( false );
+ uiNode.BoostText:SetHide( false );
+ uiNode.BoostText:SetColor( artInfo.TextColor0, 0 );
+ uiNode.BoostText:SetColor( artInfo.TextColor1, 1 );
+
+ local boostText:string;
+ if live.IsBoosted then
+ boostText = TXT_BOOSTED.." "..item.BoostText;
+ uiNode.BoostIcon:SetTexture( PIC_BOOST_ON );
+ uiNode.BoostMeter:SetHide( true );
+ uiNode.BoostedBack:SetHide( false );
+ else
+ boostText = TXT_TO_BOOST.." "..item.BoostText;
+ uiNode.BoostedBack:SetHide( true );
+ uiNode.BoostIcon:SetTexture( PIC_BOOST_OFF );
+ uiNode.BoostMeter:SetHide( false );
+ local boostAmount = (item.BoostAmount*.01) + (live.Progress/ live.Cost);
+ uiNode.BoostMeter:SetPercent( boostAmount );
+ end
+ TruncateStringWithTooltip(uiNode.BoostText, MAX_BEFORE_TRUNC_TO_BOOST, boostText);
+ else
+ uiNode.BoostIcon:SetHide( true );
+ uiNode.BoostText:SetHide( true );
+ uiNode.BoostedBack:SetHide( true );
+ uiNode.BoostMeter:SetHide( true );
+ end
+
+ if status == ITEM_STATUS.CURRENT then
+ uiNode.GearAnim:SetHide( false );
+ else
+ uiNode.GearAnim:SetHide( true );
+ end
+
+ if live.Progress > 0 then
+ uiNode.ProgressMeter:SetHide( false );
+ uiNode.ProgressMeter:SetPercent(live.Progress / live.Cost);
+ else
+ uiNode.ProgressMeter:SetHide( true );
+ end
+
+ -- Show/Hide Recommended Icon
+ if live.IsRecommended and live.AdvisorType ~= nil then
+ uiNode.RecommendedIcon:SetIcon(live.AdvisorType);
+ uiNode.RecommendedIcon:SetHide(false);
+ else
+ uiNode.RecommendedIcon:SetHide(true);
+ end
+
+ -- Set art and tool tip for icon area
+ if status == ITEM_STATUS.UNREVEALED then
+ uiNode.NodeButton:SetToolTipString(Locale.Lookup("LOC_TECH_TREE_UNREVEALED_TOOLTIP"));
+ uiNode.Icon:SetIcon("ICON_TECH_UNREVEALED");
+ uiNode.IconBacking:SetHide(true);
+ uiNode.BoostMeter:SetColor(0x66ffffff);
+ uiNode.BoostIcon:SetColor(0x66000000);
+ else
+
+ uiNode.NodeButton:SetToolTipString(ToolTipHelper.GetToolTip(item.Type, Game.GetLocalPlayer()));
+
+ if(uiNode.Type ~= nil) then
+ local iconName :string = DATA_ICON_PREFIX .. uiNode.Type;
+ if (artInfo.Name == "BLOCKED") then
+ uiNode.IconBacking:SetHide(true);
+ iconName = iconName .. "_FOW";
+ uiNode.BoostMeter:SetColor(0x66ffffff);
+ uiNode.BoostIcon:SetColor(0x66000000);
+ else
+ uiNode.IconBacking:SetHide(false);
+ iconName = iconName;
+ uiNode.BoostMeter:SetColor(0xffffffff);
+ uiNode.BoostIcon:SetColor(0xffffffff);
+ end
+ local textureOffsetX, textureOffsetY, textureSheet = IconManager:FindIconAtlas(iconName, 42);
+ if (textureOffsetX ~= nil) then
+ uiNode.Icon:SetTexture( textureOffsetX, textureOffsetY, textureSheet );
+ end
+ end
+ end
+
+ if artInfo.IsButton then
+ uiNode.OtherStates:SetHide( true );
+ uiNode.NodeButton:SetTextureOffsetVal( artInfo.BGU, artInfo.BGV );
+ else
+ uiNode.OtherStates:SetHide( false );
+ uiNode.OtherStates:SetTextureOffsetVal( artInfo.BGU, artInfo.BGV );
+ end
+
+ if artInfo.FillTexture ~= nil then
+ uiNode.FillTexture:SetHide( false );
+ uiNode.FillTexture:SetTexture( artInfo.FillTexture );
+ else
+ uiNode.FillTexture:SetHide( true );
+ end
+
+ if artInfo.BoltOn then
+ uiNode.Bolt:SetTexture(PIC_BOLT_ON);
+ else
+ uiNode.Bolt:SetTexture(PIC_BOLT_OFF);
+ end
+
+ uiNode.IconBacking:SetTexture(artInfo.IconBacking);
+
+ -- Darken items not making it past filter.
+ local currentFilter:table = playerTechData[DATA_FIELD_UIOPTIONS].filter;
+ if currentFilter == nil or currentFilter.Func == nil or currentFilter.Func( item.Type ) then
+ uiNode.FilteredOut:SetHide( true );
+ else
+ uiNode.FilteredOut:SetHide( false );
+ end
+
+ -- Civilopedia: Only show if revealed tech; only wire up handlers if not in an on-rails tutorial.
+ function OpenPedia()
+ if live.IsRevealed then
+ LuaEvents.OpenCivilopedia(uiNode.Type);
+ end
+ end
+ if IsTutorialRunning()==false then
+ uiNode.NodeButton:RegisterCallback( Mouse.eRClick, OpenPedia);
+ uiNode.OtherStates:RegisterCallback( Mouse.eRClick,OpenPedia);
+ end
+
+ UpdateAllianceIcon(uiNode);
+end
+
+-- ===========================================================================
+-- Can a tech be searched; true if revealed.
+-- ===========================================================================
+function IsSearchable(techType)
+ local kData:table = GetLiveData();
+ return kData[techType]["IsRevealed"];
+end
diff --git a/Replacements/TopPanel.lua b/Replacements/TopPanel.lua
new file mode 100644
index 0000000..96b712a
--- /dev/null
+++ b/Replacements/TopPanel.lua
@@ -0,0 +1,540 @@
+-- Copyright 2018, Firaxis Games
+
+-- ===========================================================================
+-- HUD Top of Screen Area
+-- ===========================================================================
+include( "InstanceManager" );
+include( "SupportFunctions" ); -- Round
+include( "ToolTipHelper_PlayerYields" );
+
+
+-- ===========================================================================
+-- CONSTANTS
+-- ===========================================================================
+META_PADDING = 100; -- The amount of padding to give the meta area to make enough room for the (+) when there is resource overflow
+FONT_MULTIPLIER = 11; -- The amount to multiply times the string length to approximate the width in pixels of the label control
+
+
+-- ===========================================================================
+-- VARIABLES
+-- ===========================================================================
+m_YieldButtonSingleManager = InstanceManager:new( "YieldButton_SingleLabel", "Top", Controls.YieldStack );
+m_YieldButtonDoubleManager = InstanceManager:new( "YieldButton_DoubleLabel", "Top", Controls.YieldStack );
+m_kResourceIM = InstanceManager:new( "ResourceInstance", "Top", Controls.ResourceStack );
+m_viewReportsX = 0; -- With of view report button
+local m_OpenPediaId;
+
+
+-- ===========================================================================
+-- Yield handles
+-- ===========================================================================
+local m_ScienceYieldButton :table = nil;
+local m_CultureYieldButton :table = nil;
+local m_GoldYieldButton :table = nil;
+local m_TourismYieldButton :table = nil;
+local m_FaithYieldButton :table = nil;
+
+
+-- ===========================================================================
+-- Game Engine Event
+-- ===========================================================================
+function OnCityInitialized( playerID:number, cityID:number )
+ if playerID == Game.GetLocalPlayer() then
+ RefreshYields();
+ end
+end
+
+-- ===========================================================================
+-- Game Engine Event
+-- ===========================================================================
+function OnLocalPlayerChanged( playerID:number , prevLocalPlayerID:number )
+ if playerID == -1 then return; end
+ local player = Players[playerID];
+ local pPlayerCities :table = player:GetCities();
+ RefreshAll();
+end
+
+-- ===========================================================================
+function OnMenu()
+ LuaEvents.InGame_OpenInGameOptionsMenu();
+end
+
+-- ===========================================================================
+-- Takes a value and returns the string verison with +/- and rounded to
+-- the tenths decimal place.
+-- ===========================================================================
+function FormatValuePerTurn( value:number )
+ if(value == 0) then
+ return Locale.ToNumber(value);
+ else
+ return Locale.Lookup("{1: number +#,###.#;-#,###.#}", value);
+ end
+end
+
+-- ===========================================================================
+-- Refresh Data and View
+-- ===========================================================================
+function RefreshYields()
+ local ePlayer :number = Game.GetLocalPlayer();
+ local localPlayer :table= nil;
+ if ePlayer ~= -1 then
+ localPlayer = Players[ePlayer];
+ if localPlayer == nil then
+ return;
+ end
+ else
+ return;
+ end
+
+ ---- SCIENCE ----
+ m_ScienceYieldButton = m_ScienceYieldButton or m_YieldButtonSingleManager:GetInstance();
+ local playerTechnology :table = localPlayer:GetTechs();
+ local currentScienceYield :number = playerTechnology:GetScienceYield();
+ m_ScienceYieldButton.YieldPerTurn:SetText( FormatValuePerTurn(currentScienceYield) );
+
+ m_ScienceYieldButton.YieldBacking:SetToolTipString( GetScienceTooltip() );
+ m_ScienceYieldButton.YieldIconString:SetText("[ICON_ScienceLarge]");
+ m_ScienceYieldButton.YieldButtonStack:CalculateSize();
+
+
+ ---- CULTURE----
+ m_CultureYieldButton = m_CultureYieldButton or m_YieldButtonSingleManager:GetInstance();
+ local playerCulture :table = localPlayer:GetCulture();
+ local currentCultureYield :number = playerCulture:GetCultureYield();
+ m_CultureYieldButton.YieldPerTurn:SetText( FormatValuePerTurn(currentCultureYield) );
+ m_CultureYieldButton.YieldPerTurn:SetColorByName("ResCultureLabelCS");
+
+ m_CultureYieldButton.YieldBacking:SetToolTipString( GetCultureTooltip() );
+ m_CultureYieldButton.YieldBacking:SetColor(0x99fe2aec);
+ m_CultureYieldButton.YieldIconString:SetText("[ICON_CultureLarge]");
+ m_CultureYieldButton.YieldButtonStack:CalculateSize();
+
+ ---- FAITH ----
+ m_FaithYieldButton = m_FaithYieldButton or m_YieldButtonDoubleManager:GetInstance();
+ local playerReligion :table = localPlayer:GetReligion();
+ local faithYield :number = playerReligion:GetFaithYield();
+ local faithBalance :number = playerReligion:GetFaithBalance();
+ m_FaithYieldButton.YieldBalance:SetText( Locale.ToNumber(faithBalance, "#,###.#") );
+ m_FaithYieldButton.YieldPerTurn:SetText( FormatValuePerTurn(faithYield) );
+ m_FaithYieldButton.YieldBacking:SetToolTipString( GetFaithTooltip() );
+ m_FaithYieldButton.YieldIconString:SetText("[ICON_FaithLarge]");
+ m_FaithYieldButton.YieldButtonStack:CalculateSize();
+
+ ---- GOLD ----
+ if GameCapabilities.HasCapability("CAPABILITY_GOLD") then
+ m_GoldYieldButton = m_GoldYieldButton or m_YieldButtonDoubleManager:GetInstance();
+ local playerTreasury:table = localPlayer:GetTreasury();
+ local goldYield :number = playerTreasury:GetGoldYield() - playerTreasury:GetTotalMaintenance();
+ local goldBalance :number = math.floor(playerTreasury:GetGoldBalance());
+ m_GoldYieldButton.YieldBalance:SetText( Locale.ToNumber(goldBalance, "#,###.#") );
+ m_GoldYieldButton.YieldBalance:SetColorByName("ResGoldLabelCS");
+ m_GoldYieldButton.YieldPerTurn:SetText( FormatValuePerTurn(goldYield) );
+ m_GoldYieldButton.YieldIconString:SetText("[ICON_GoldLarge]");
+ m_GoldYieldButton.YieldPerTurn:SetColorByName("ResGoldLabelCS");
+
+ m_GoldYieldButton.YieldBacking:SetToolTipString( GetGoldTooltip() );
+ m_GoldYieldButton.YieldBacking:SetColorByName("ResGoldLabelCS");
+ m_GoldYieldButton.YieldButtonStack:CalculateSize();
+ end
+
+
+
+ ---- TOURISM ----
+ if GameCapabilities.HasCapability("CAPABILITY_TOURISM") then
+ m_TourismYieldButton = m_TourismYieldButton or m_YieldButtonSingleManager:GetInstance();
+ local tourismRate = Round(localPlayer:GetStats():GetTourism(), 1);
+ local tourismRateTT:string = Locale.Lookup("LOC_WORLD_RANKINGS_OVERVIEW_CULTURE_TOURISM_RATE", tourismRate);
+ local tourismBreakdown = localPlayer:GetStats():GetTourismToolTip();
+ if(tourismBreakdown and #tourismBreakdown > 0) then
+ tourismRateTT = tourismRateTT .. "[NEWLINE][NEWLINE]" .. tourismBreakdown;
+ end
+
+ m_TourismYieldButton.YieldPerTurn:SetText( tourismRate );
+ m_TourismYieldButton.YieldBacking:SetToolTipString(tourismRateTT);
+ m_TourismYieldButton.YieldPerTurn:SetColorByName("ResTourismLabelCS");
+ m_TourismYieldButton.YieldBacking:SetColorByName("ResTourismLabelCS");
+ m_TourismYieldButton.YieldIconString:SetText("[ICON_TourismLarge]");
+ if (tourismRate > 0) then
+ m_TourismYieldButton.Top:SetHide(false);
+ else
+ m_TourismYieldButton.Top:SetHide(true);
+ end
+ end
+
+ Controls.YieldStack:CalculateSize();
+ Controls.StaticInfoStack:CalculateSize();
+ Controls.InfoStack:CalculateSize();
+
+ Controls.YieldStack:RegisterSizeChanged( RefreshResources );
+ Controls.StaticInfoStack:RegisterSizeChanged( RefreshResources );
+end
+
+-- ===========================================================================
+-- Game Engine Event
+function OnRefreshYields()
+ ContextPtr:RequestRefresh();
+end
+
+-- ===========================================================================
+function RefreshTrade()
+
+ local localPlayer = Players[Game.GetLocalPlayer()];
+ if (localPlayer == nil) then
+ return;
+ end
+
+ ---- ROUTES ----
+ local playerTrade :table = localPlayer:GetTrade();
+ local routesActive :number = playerTrade:GetNumOutgoingRoutes();
+ local sRoutesActive :string = "" .. routesActive;
+ local routesCapacity:number = playerTrade:GetOutgoingRouteCapacity();
+ if (routesCapacity > 0) then
+ if (routesActive > routesCapacity) then
+ sRoutesActive = "[COLOR_RED]" .. sRoutesActive .. "[ENDCOLOR]";
+ elseif (routesActive < routesCapacity) then
+ sRoutesActive = "[COLOR_GREEN]" .. sRoutesActive .. "[ENDCOLOR]";
+ end
+ Controls.TradeRoutesActive:SetText(sRoutesActive);
+ Controls.TradeRoutesCapacity:SetText(routesCapacity);
+
+ local sTooltip = Locale.Lookup("LOC_TOP_PANEL_TRADE_ROUTES_TOOLTIP_ACTIVE", routesActive);
+ sTooltip = sTooltip .. "[NEWLINE]";
+ sTooltip = sTooltip .. Locale.Lookup("LOC_TOP_PANEL_TRADE_ROUTES_TOOLTIP_CAPACITY", routesCapacity);
+ sTooltip = sTooltip .. "[NEWLINE][NEWLINE]";
+ sTooltip = sTooltip .. Locale.Lookup("LOC_TOP_PANEL_TRADE_ROUTES_TOOLTIP_SOURCES_HELP");
+ Controls.TradeRoutes:SetToolTipString(sTooltip);
+ Controls.TradeRoutes:SetHide(false);
+ else
+ Controls.TradeRoutes:SetHide(true);
+ end
+
+ Controls.TradeStack:CalculateSize();
+ Controls.TradeStack:ReprocessAnchoring();
+end
+
+-- ===========================================================================
+function RefreshInfluence()
+ if GameCapabilities.HasCapability("CAPABILITY_TOP_PANEL_ENVOYS") then
+ local localPlayer = Players[Game.GetLocalPlayer()];
+ if (localPlayer == nil) then
+ return;
+ end
+
+ local playerInfluence :table = localPlayer:GetInfluence();
+ local influenceBalance :number = Round(playerInfluence:GetPointsEarned(), 1);
+ local influenceRate :number = Round(playerInfluence:GetPointsPerTurn(), 1);
+ local influenceThreshold:number = playerInfluence:GetPointsThreshold();
+ local envoysPerThreshold:number = playerInfluence:GetTokensPerThreshold();
+ local currentEnvoys :number = playerInfluence:GetTokensToGive();
+
+ local sTooltip = "";
+
+ if (currentEnvoys > 0) then
+ sTooltip = sTooltip .. Locale.Lookup("LOC_TOP_PANEL_INFLUENCE_TOOLTIP_ENVOYS", currentEnvoys);
+ sTooltip = sTooltip .. "[NEWLINE][NEWLINE]";
+ end
+ sTooltip = sTooltip .. Locale.Lookup("LOC_TOP_PANEL_INFLUENCE_TOOLTIP_POINTS_THRESHOLD", envoysPerThreshold, influenceThreshold);
+ sTooltip = sTooltip .. "[NEWLINE][NEWLINE]";
+ sTooltip = sTooltip .. Locale.Lookup("LOC_TOP_PANEL_INFLUENCE_TOOLTIP_POINTS_BALANCE", influenceBalance);
+ sTooltip = sTooltip .. "[NEWLINE]";
+ sTooltip = sTooltip .. Locale.Lookup("LOC_TOP_PANEL_INFLUENCE_TOOLTIP_POINTS_RATE", influenceRate);
+ sTooltip = sTooltip .. "[NEWLINE][NEWLINE]";
+ sTooltip = sTooltip .. Locale.Lookup("LOC_TOP_PANEL_INFLUENCE_TOOLTIP_SOURCES_HELP");
+
+ local meterRatio = influenceBalance / influenceThreshold;
+ if (meterRatio < 0) then
+ meterRatio = 0;
+ elseif (meterRatio > 1) then
+ meterRatio = 1;
+ end
+ Controls.EnvoysMeter:SetPercent(meterRatio);
+ Controls.EnvoysNumber:SetText(tostring(currentEnvoys));
+ Controls.Envoys:SetToolTipString(sTooltip);
+ Controls.EnvoysStack:CalculateSize();
+ Controls.EnvoysStack:ReprocessAnchoring();
+ else
+ Controls.Envoys:SetHide(true);
+ end
+end
+
+-- ===========================================================================
+function RefreshTime()
+ local format = UserConfiguration.GetClockFormat();
+
+ local strTime;
+
+ if(format == 1) then
+ strTime = os.date("%H:%M");
+ else
+ strTime = os.date("%I:%M %p");
+
+ -- Remove the leading zero (if any) from 12-hour clock format
+ if(string.sub(strTime, 1, 1) == "0") then
+ strTime = string.sub(strTime, 2);
+ end
+ end
+
+ Controls.Time:SetText( strTime );
+ local d = Locale.Lookup("{1_Time : datetime full}", os.time());
+ Controls.Time:SetToolTipString(d);
+ Controls.TimeArea:ReprocessAnchoring();
+end
+
+-- ===========================================================================
+function RefreshResources()
+ local localPlayerID = Game.GetLocalPlayer();
+ if (localPlayerID ~= -1) then
+ m_kResourceIM:ResetInstances();
+ local pPlayerResources = Players[localPlayerID]:GetResources();
+ local yieldStackX = Controls.YieldStack:GetSizeX();
+ local infoStackX = Controls.StaticInfoStack:GetSizeX();
+ local metaStackX = Controls.RightContents:GetSizeX();
+ local screenX, _:number = UIManager:GetScreenSizeVal();
+ local maxSize = screenX - yieldStackX - infoStackX - metaStackX - m_viewReportsX - META_PADDING;
+ if (maxSize < 0) then maxSize = 0; end
+ local currSize = 0;
+ local isOverflow = false;
+ local overflowString = "";
+ local plusInstance:table;
+ for resource in GameInfo.Resources() do
+ if (resource.ResourceClassType ~= nil and resource.ResourceClassType ~= "RESOURCECLASS_BONUS" and resource.ResourceClassType ~="RESOURCECLASS_LUXURY" and resource.ResourceClassType ~="RESOURCECLASS_ARTIFACT") then
+ local amount = pPlayerResources:GetResourceAmount(resource.ResourceType);
+ if (amount > 0) then
+ local resourceText = "[ICON_"..resource.ResourceType.."] ".. amount;
+ local numDigits = 3;
+ if (amount >= 10) then
+ numDigits = 4;
+ end
+ local guessinstanceWidth = math.ceil(numDigits * FONT_MULTIPLIER);
+ if(currSize + guessinstanceWidth < maxSize and not isOverflow) then
+ if (amount ~= 0) then
+ local instance:table = m_kResourceIM:GetInstance();
+ instance.ResourceText:SetText(resourceText);
+ instance.ResourceText:SetToolTipString(Locale.Lookup(resource.Name).."[NEWLINE]"..Locale.Lookup("LOC_TOOLTIP_STRATEGIC_RESOURCE"));
+ instanceWidth = instance.ResourceText:GetSizeX();
+ currSize = currSize + instanceWidth;
+ end
+ else
+ if (not isOverflow) then
+ overflowString = amount.. "[ICON_"..resource.ResourceType.."]".. Locale.Lookup(resource.Name);
+ local instance:table = m_kResourceIM:GetInstance();
+ instance.ResourceText:SetText("[ICON_Plus]");
+ plusInstance = instance.ResourceText;
+ else
+ overflowString = overflowString .. "[NEWLINE]".. amount.. "[ICON_"..resource.ResourceType.."]".. Locale.Lookup(resource.Name);
+ end
+ isOverflow = true;
+ end
+ end
+ end
+ end
+ if (plusInstance ~= nil) then
+ plusInstance:SetToolTipString(overflowString);
+ end
+ Controls.ResourceStack:CalculateSize();
+ if(Controls.ResourceStack:GetSizeX() == 0) then
+ Controls.Resources:SetHide(true);
+ else
+ Controls.Resources:SetHide(false);
+ end
+ end
+end
+
+-- ===========================================================================
+-- Game Engine Event
+-- ===========================================================================
+function OnRefreshResources()
+ RefreshResources();
+end
+
+-- ===========================================================================
+-- Use an animation control to occasionally (not per frame!) callback for
+-- an update on the current time.
+-- ===========================================================================
+function OnRefreshTimeTick()
+ RefreshTime();
+ Controls.TimeCallback:SetToBeginning();
+ Controls.TimeCallback:Play();
+end
+
+-- ===========================================================================
+function RefreshTurnsRemaining()
+
+ local endTurn = Game.GetGameEndTurn(); -- This EXCLUSIVE, i.e. the turn AFTER the last playable turn.
+ local turn = Game.GetCurrentGameTurn();
+
+ if GameCapabilities.HasCapability("CAPABILITY_DISPLAY_NORMALIZED_TURN") then
+ turn = (turn - GameConfiguration.GetStartTurn()) + 1; -- Keep turns starting at 1.
+ if endTurn > 0 then
+ endTurn = endTurn - GameConfiguration.GetStartTurn();
+ end
+ end
+
+ if endTurn > 0 then
+ -- We have a hard turn limit
+ Controls.Turns:SetText(tostring(turn) .. "/" .. tostring(endTurn - 1));
+ else
+ Controls.Turns:SetText(tostring(turn));
+ end
+
+ local strDate = Calendar.MakeYearStr(turn);
+ Controls.CurrentDate:SetText(strDate);
+end
+
+-- ===========================================================================
+function OnWMDUpdate(owner, WMDtype)
+ local eLocalPlayer = Game.GetLocalPlayer();
+ if ( eLocalPlayer ~= -1 and owner == eLocalPlayer ) then
+ local player = Players[owner];
+ local playerWMDs = player:GetWMDs();
+
+ for entry in GameInfo.WMDs() do
+ if (entry.WeaponType == "WMD_NUCLEAR_DEVICE") then
+ local count = playerWMDs:GetWeaponCount(entry.Index);
+ if (count > 0) then
+ Controls.NuclearDevices:SetHide(false);
+ Controls.NuclearDeviceCount:SetText(count);
+ else
+ Controls.NuclearDevices:SetHide(true);
+ end
+
+ elseif (entry.WeaponType == "WMD_THERMONUCLEAR_DEVICE") then
+ local count = playerWMDs:GetWeaponCount(entry.Index);
+ if (count > 0) then
+ Controls.ThermoNuclearDevices:SetHide(false);
+ Controls.ThermoNuclearDeviceCount:SetText(count);
+ else
+ Controls.ThermoNuclearDevices:SetHide(true);
+ end
+ end
+ end
+
+ Controls.YieldStack:CalculateSize();
+ end
+
+ OnRefreshYields(); -- Don't directly refresh, call EVENT version so it's queued in the next context update.
+end
+
+-- ===========================================================================
+function OnGreatPersonActivated(playerID:number)
+ if ( Game.GetLocalPlayer() == playerID ) then
+ OnRefreshYields();
+ end
+end
+
+-- ===========================================================================
+function OnGreatWorkCreated(playerID:number)
+ if ( Game.GetLocalPlayer() == playerID ) then
+ OnRefreshYields();
+ end
+end
+
+-- ===========================================================================
+function RefreshAll()
+ RefreshTurnsRemaining();
+ RefreshTrade();
+ RefreshInfluence();
+ RefreshYields();
+ RefreshTime();
+ OnWMDUpdate( Game.GetLocalPlayer() );
+end
+
+-- ===========================================================================
+-- Game Engine Event
+-- ===========================================================================
+function OnTurnBegin()
+ RefreshAll();
+end
+
+-- ===========================================================================
+-- Game Engine Event
+-- ===========================================================================
+function OnUpdateUI( type:number, tag:string, iData1:number, iData2:number, strData1:string)
+ if type == SystemUpdateUI.ScreenResize then
+ -- TODO?
+ end
+end
+
+-- ===========================================================================
+function OnRefresh()
+ ContextPtr:ClearRequestRefresh();
+ RefreshYields();
+end
+
+
+
+-- ===========================================================================
+-- Game Engine Event
+-- Wait until the game engine is done loading before the initial refresh,
+-- otherwise there is a chance the load of the LUA threads (UI & core) will
+-- clash and then we'll all have a bad time. :(
+-- ===========================================================================
+function OnLoadGameViewStateDone()
+ RefreshAll();
+end
+
+
+-- ===========================================================================
+function LateInitialize()
+
+ -- UI Callbacks
+ Controls.CivpediaButton:RegisterCallback( Mouse.eLClick, function() LuaEvents.ToggleCivilopedia(); end);
+ Controls.CivpediaButton:RegisterCallback( Mouse.eMouseEnter, function() UI.PlaySound("Main_Menu_Mouse_Over"); end);
+ Controls.MenuButton:RegisterCallback( Mouse.eLClick, OnMenu );
+ Controls.MenuButton:RegisterCallback( Mouse.eMouseEnter, function() UI.PlaySound("Main_Menu_Mouse_Over"); end);
+ Controls.TimeCallback:RegisterEndCallback( OnRefreshTimeTick );
+
+ -- Game Events
+ Events.AnarchyBegins.Add( OnRefreshYields );
+ Events.AnarchyEnds.Add( OnRefreshYields );
+ Events.BeliefAdded.Add( OnRefreshYields );
+ Events.CityInitialized.Add( OnCityInitialized );
+ Events.CityFocusChanged.Add( OnRefreshYields );
+ Events.CityWorkerChanged.Add( OnRefreshYields );
+ Events.DiplomacySessionClosed.Add( OnRefreshYields );
+ Events.FaithChanged.Add( OnRefreshYields );
+ Events.GovernmentChanged.Add( OnRefreshYields );
+ Events.GovernmentPolicyChanged.Add( OnRefreshYields );
+ Events.GovernmentPolicyObsoleted.Add( OnRefreshYields );
+ Events.GreatWorkCreated.Add( OnGreatWorkCreated );
+ Events.ImprovementAddedToMap.Add( OnRefreshResources );
+ Events.ImprovementRemovedFromMap.Add( OnRefreshResources );
+ Events.InfluenceChanged.Add( RefreshInfluence );
+ Events.LoadGameViewStateDone.Add( OnLoadGameViewStateDone );
+ Events.LocalPlayerChanged.Add( OnLocalPlayerChanged );
+ Events.PantheonFounded.Add( OnRefreshYields );
+ Events.PlayerAgeChanged.Add( OnRefreshYields );
+ Events.ResearchCompleted.Add( OnRefreshResources );
+ Events.PlayerResourceChanged.Add( OnRefreshResources );
+ Events.SystemUpdateUI.Add( OnUpdateUI );
+ Events.TradeRouteActivityChanged.Add( RefreshTrade );
+ Events.TradeRouteCapacityChanged.Add( RefreshTrade );
+ Events.TreasuryChanged.Add( OnRefreshYields );
+ Events.TurnBegin.Add( OnTurnBegin );
+ Events.UnitAddedToMap.Add( OnRefreshYields );
+ Events.UnitGreatPersonActivated.Add( OnGreatPersonActivated );
+ Events.UnitKilledInCombat.Add( OnRefreshYields );
+ Events.UnitRemovedFromMap.Add( OnRefreshYields );
+ Events.VisualStateRestored.Add( OnTurnBegin );
+ Events.WMDCountChanged.Add( OnWMDUpdate );
+ Events.CityProductionChanged.Add( OnRefreshResources);
+
+ -- If no expansions function are in scope, ready to refresh and show values.
+ if not XP1_LateInitialize then
+ RefreshYields();
+ end
+end
+
+
+-- ===========================================================================
+function OnInit( isReload:boolean )
+ LateInitialize();
+end
+
+-- ===========================================================================
+function Initialize()
+ -- UI Callbacks
+ ContextPtr:SetInitHandler( OnInit );
+ ContextPtr:SetRefreshHandler( OnRefresh );
+end
+Initialize();
diff --git a/Replacements/TopPanel.xml b/Replacements/TopPanel.xml
new file mode 100644
index 0000000..c264ec1
--- /dev/null
+++ b/Replacements/TopPanel.xml
@@ -0,0 +1,137 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Replacements/TopPanel_Expansion1.lua b/Replacements/TopPanel_Expansion1.lua
index d048e9f..3d7ab67 100644
--- a/Replacements/TopPanel_Expansion1.lua
+++ b/Replacements/TopPanel_Expansion1.lua
@@ -43,4 +43,7 @@ function LateInitialize()
BASE_LateInitialize();
Events.LocalPlayerTurnBegin.Add( OnLocalPlayerTurnBegin );
OnLocalPlayerTurnBegin();
+ if not XP1_LateInitialize then
+ RefreshYields();
+ end
end
diff --git a/Replacements/TopPanel_Expansion2.lua b/Replacements/TopPanel_Expansion2.lua
new file mode 100644
index 0000000..28dc138
--- /dev/null
+++ b/Replacements/TopPanel_Expansion2.lua
@@ -0,0 +1,193 @@
+-- ===========================================================================
+-- HUD Top of Screen Area
+-- XP2 Override
+-- ===========================================================================
+include( "TopPanel_Expansion1" );
+
+
+-- ===========================================================================
+-- Super functions
+-- ===========================================================================
+BASE_RefreshYields = RefreshYields;
+XP1_LateInitialize = LateInitialize;
+
+
+-- ===========================================================================
+-- Yield handles
+-- ===========================================================================
+local m_FavorYieldButton:table = nil;
+
+
+-- ===========================================================================
+-- OVERRIDE
+-- ===========================================================================
+function RefreshResources()
+ local localPlayerID = Game.GetLocalPlayer();
+ local localPlayer = Players[localPlayerID];
+ if (localPlayerID ~= -1) then
+ m_kResourceIM:ResetInstances();
+ local pPlayerResources:table = localPlayer:GetResources();
+ local yieldStackX:number = Controls.YieldStack:GetSizeX();
+ local infoStackX:number = Controls.StaticInfoStack:GetSizeX();
+ local metaStackX:number = Controls.RightContents:GetSizeX();
+ local screenX, _:number = UIManager:GetScreenSizeVal();
+ local maxSize:number = screenX - yieldStackX - infoStackX - metaStackX - m_viewReportsX - META_PADDING;
+ if (maxSize < 0) then maxSize = 0; end
+ local currSize:number = 0;
+ local isOverflow:boolean = false;
+ local overflowString:string = "";
+ local plusInstance:table;
+ for resource in GameInfo.Resources() do
+ if (resource.ResourceClassType ~= nil and resource.ResourceClassType ~= "RESOURCECLASS_BONUS" and resource.ResourceClassType ~="RESOURCECLASS_LUXURY" and resource.ResourceClassType ~="RESOURCECLASS_ARTIFACT") then
+
+ local stockpileAmount:number = pPlayerResources:GetResourceAmount(resource.ResourceType);
+ local stockpileCap:number = pPlayerResources:GetResourceStockpileCap(resource.ResourceType);
+ local reservedAmount:number = pPlayerResources:GetReservedResourceAmount(resource.ResourceType);
+ local accumulationPerTurn:number = pPlayerResources:GetResourceAccumulationPerTurn(resource.ResourceType);
+ local importPerTurn:number = pPlayerResources:GetResourceImportPerTurn(resource.ResourceType);
+ local bonusPerTurn:number = pPlayerResources:GetBonusResourcePerTurn(resource.ResourceType);
+ local unitConsumptionPerTurn:number = pPlayerResources:GetUnitResourceDemandPerTurn(resource.ResourceType);
+ local powerConsumptionPerTurn:number = pPlayerResources:GetPowerResourceDemandPerTurn(resource.ResourceType);
+ local totalConsumptionPerTurn:number = unitConsumptionPerTurn + powerConsumptionPerTurn;
+ local totalAmount:number = stockpileAmount + reservedAmount;
+
+ if (totalAmount > stockpileCap) then
+ totalAmount = stockpileCap;
+ end
+
+ local iconName:string = "[ICON_"..resource.ResourceType.."]";
+
+ local totalAccumulationPerTurn:number = accumulationPerTurn + importPerTurn + bonusPerTurn;
+
+ resourceText = iconName .. " " .. stockpileAmount;
+
+ local numDigits:number = 3;
+ if (stockpileAmount >= 10) then
+ numDigits = 4;
+ end
+ local guessinstanceWidth:number = math.ceil(numDigits * FONT_MULTIPLIER);
+
+ local tooltip:string = iconName .. " " .. Locale.Lookup(resource.Name);
+ if (reservedAmount ~= 0) then
+ --instance.ResourceText:SetColor(0xFF2DFFF8); -- YELLOW
+ tooltip = tooltip .. "[NEWLINE]" .. totalAmount .. "/" .. stockpileCap .. " " .. Locale.Lookup("LOC_RESOURCE_ITEM_IN_STOCKPILE");
+ tooltip = tooltip .. "[NEWLINE]-" .. reservedAmount .. " " .. Locale.Lookup("LOC_RESOURCE_ITEM_IN_RESERVE");
+ else
+ --instance.ResourceText:SetColor(0xFFFFFFFF); -- WHITE
+ tooltip = tooltip .. "[NEWLINE]" .. totalAmount .. "/" .. stockpileCap .. " " .. Locale.Lookup("LOC_RESOURCE_ITEM_IN_STOCKPILE");
+ end
+ if (totalAccumulationPerTurn >= 0) then
+ tooltip = tooltip .. "[NEWLINE]" .. Locale.Lookup("LOC_RESOURCE_ACCUMULATION_PER_TURN", totalAccumulationPerTurn);
+ else
+ tooltip = tooltip .. "[NEWLINE][COLOR_RED]" .. Locale.Lookup("LOC_RESOURCE_ACCUMULATION_PER_TURN", totalAccumulationPerTurn) .. "[ENDCOLOR]";
+ end
+ if (accumulationPerTurn > 0) then
+ tooltip = tooltip .. "[NEWLINE] " .. Locale.Lookup("LOC_RESOURCE_ACCUMULATION_PER_TURN_EXTRACTED", accumulationPerTurn);
+ end
+ if (importPerTurn > 0) then
+ tooltip = tooltip .. "[NEWLINE] " .. Locale.Lookup("LOC_RESOURCE_ACCUMULATION_PER_TURN_FROM_CITY_STATES", importPerTurn);
+ end
+ if (bonusPerTurn > 0) then
+ tooltip = tooltip .. "[NEWLINE] " .. Locale.Lookup("LOC_RESOURCE_ACCUMULATION_PER_TURN_FROM_BONUS_SOURCES", bonusPerTurn);
+ end
+ if (totalConsumptionPerTurn > 0) then
+ tooltip = tooltip .. "[NEWLINE]" .. Locale.Lookup("LOC_RESOURCE_CONSUMPTION", totalConsumptionPerTurn);
+ if (unitConsumptionPerTurn > 0) then
+ tooltip = tooltip .. "[NEWLINE]" .. Locale.Lookup("LOC_RESOURCE_UNIT_CONSUMPTION_PER_TURN", unitConsumptionPerTurn);
+ end
+ if (powerConsumptionPerTurn > 0) then
+ tooltip = tooltip .. "[NEWLINE]" .. Locale.Lookup("LOC_RESOURCE_POWER_CONSUMPTION_PER_TURN", powerConsumptionPerTurn);
+ end
+ end
+
+ if (stockpileAmount > 0 or totalAccumulationPerTurn > 0 or totalConsumptionPerTurn > 0) then
+ if(currSize + guessinstanceWidth < maxSize and not isOverflow) then
+ if (stockpileCap > 0) then
+ local instance:table = m_kResourceIM:GetInstance();
+ if (totalAccumulationPerTurn > totalConsumptionPerTurn) then
+ instance.ResourceVelocity:SetHide(false);
+ instance.ResourceVelocity:SetTexture("CityCondition_Rising");
+ elseif (totalAccumulationPerTurn < totalConsumptionPerTurn) then
+ instance.ResourceVelocity:SetHide(false);
+ instance.ResourceVelocity:SetTexture("CityCondition_Falling");
+ else
+ instance.ResourceVelocity:SetHide(true);
+ end
+
+ instance.ResourceText:SetText(resourceText);
+ instance.ResourceText:SetToolTipString(tooltip);
+ instanceWidth = instance.ResourceText:GetSizeX();
+ currSize = currSize + instanceWidth;
+ end
+ else
+ if (not isOverflow) then
+ overflowString = tooltip;
+ local instance:table = m_kResourceIM:GetInstance();
+ instance.ResourceText:SetText("[ICON_Plus]");
+ plusInstance = instance.ResourceText;
+ else
+ overflowString = overflowString .. "[NEWLINE]" .. tooltip;
+ end
+ isOverflow = true;
+ end
+ end
+ end
+ end
+
+ if (plusInstance ~= nil) then
+ plusInstance:SetToolTipString(overflowString);
+ end
+
+ Controls.ResourceStack:CalculateSize();
+
+ if(Controls.ResourceStack:GetSizeX() == 0) then
+ Controls.Resources:SetHide(true);
+ else
+ Controls.Resources:SetHide(false);
+ end
+ end
+end
+
+
+-- ===========================================================================
+-- Favor in the top bar should not ship as is.
+-- TODO: Remove this implementation
+-- ===========================================================================
+function RefreshYields()
+ BASE_RefreshYields();
+
+ local localPlayerID = Game.GetLocalPlayer();
+ if localPlayerID ~= -1 then
+ local localPlayer = Players[localPlayerID];
+
+ --Favor
+ m_FavorYieldButton = m_FavorYieldButton or m_YieldButtonDoubleManager:GetInstance();
+ local playerFavor :number = localPlayer:GetFavor();
+ local favorPerTurn :number = localPlayer:GetFavorPerTurn();
+ local tooltip :string = Locale.Lookup("LOC_WORLD_CONGRESS_TOP_PANEL_FAVOR_TOOLTIP");
+
+ local details = localPlayer:GetFavorPerTurnToolTip();
+ if(details and #details > 0) then
+ tooltip = tooltip .. "[NEWLINE]" .. details;
+ end
+
+ m_FavorYieldButton.YieldBalance:SetText(Locale.ToNumber(playerFavor, "#,###.#"));
+ m_FavorYieldButton.YieldBalance:SetColorByName("ResFavorLabelCS");
+ m_FavorYieldButton.YieldPerTurn:SetText(FormatValuePerTurn(favorPerTurn));
+ m_FavorYieldButton.YieldPerTurn:SetColorByName("ResFavorLabelCS");
+ m_FavorYieldButton.YieldBacking:SetToolTipString(tooltip);
+ m_FavorYieldButton.YieldBacking:SetColorByName("ResFavorLabelCS");
+ m_FavorYieldButton.YieldIconString:SetText("[ICON_FAVOR_LARGE]");
+ m_FavorYieldButton.YieldButtonStack:CalculateSize();
+ end
+end
+
+
+-- ===========================================================================
+function LateInitialize()
+ XP1_LateInitialize();
+ Events.FavorChanged.Add( OnRefreshYields );
+ if not XP2_LateInitialize then
+ RefreshYields();
+ end
+end
\ No newline at end of file
diff --git a/Replacements/TutorialUIRoot_Expansion1.lua b/Replacements/TutorialUIRoot_Expansion1.lua
index 9ab81eb..c3fdbc4 100644
--- a/Replacements/TutorialUIRoot_Expansion1.lua
+++ b/Replacements/TutorialUIRoot_Expansion1.lua
@@ -35,5 +35,7 @@ function IsListenerAbleToProcessOnNonPlayerTurn( listenerName:string )
or listenerName == "TargetEmergencySuccess"
or listenerName == "EmergencyFailure"
or listenerName == "EmergencyTrigger"
- or listenerName == "EmergencySuccess";
+ or listenerName == "EmergencySuccess"
+ or listenerName == "WorldCongressStage3"
+ or listenerName == "WorldCongressFinished";
end
\ No newline at end of file
diff --git a/Replacements/UnitPanel_Expansion2.lua b/Replacements/UnitPanel_Expansion2.lua
new file mode 100644
index 0000000..5b1e4c7
--- /dev/null
+++ b/Replacements/UnitPanel_Expansion2.lua
@@ -0,0 +1,145 @@
+-- ===========================================================================
+-- Copyright (c) 2018 Firaxis Games
+-- ===========================================================================
+
+-- ===========================================================================
+-- INCLUDE XP1 FILE
+-- ===========================================================================
+include("UnitPanel_Expansion1");
+
+
+-- ===========================================================================
+-- Add to base tables
+-- ===========================================================================
+local BASE_InitSubjectData = InitSubjectData;
+local BASE_GetBuildImprovementParameters = GetBuildImprovementParameters;
+local BASE_ReadCustomUnitStats = ReadCustomUnitStats;
+local Base_RealizeSpecializedViews = RealizeSpecializedViews;
+local BASE_FilterUnitStatsFromUnitData = FilterUnitStatsFromUnitData;
+
+
+-- ===========================================================================
+-- OVERRIDE
+-- Call base to get values and then XP2 related fields.
+-- ===========================================================================
+function InitSubjectData()
+ local kSubjectData:table = BASE_InitSubjectData();
+ kSubjectData.RockBandLevel = -1;
+ kSubjectData.AlbumSales = 0;
+ kSubjectData.IsRockbandUnit = false;
+ return kSubjectData;
+end
+
+
+-- ===========================================================================
+-- OVERRIDE
+-- Populate XP2 specific units that have custom stats.
+-- ===========================================================================
+function ReadCustomUnitStats( pUnit:table, kSubjectData:table )
+ kSubjectData = BASE_ReadCustomUnitStats(pUnit, kSubjectData );
+ if GameInfo.Units[kSubjectData.UnitType].UnitType == "UNIT_ROCK_BAND" then
+ kSubjectData.IsRockbandUnit = true;
+ kSubjectData.RockBandLevel = pUnit:GetRockBand():GetRockBandLevel();
+ kSubjectData.AlbumSales = pUnit:GetRockBand():GetAlbumSales();
+ end
+
+ return kSubjectData;
+end
+
+
+-- ===========================================================================
+-- OVERRIDE
+-- Is this hash representing an improvement to be built?
+-- ===========================================================================
+function IsBuildingImprovement( actionHash:number )
+ return (actionHash == UnitOperationTypes.BUILD_IMPROVEMENT
+ or actionHash == UnitOperationTypes.BUILD_IMPROVEMENT_ADJACENT);
+end
+
+
+-- ===========================================================================
+-- OVERRIDE
+-- Obtain the parameters for a building improvement.
+-- actionHash, the hash of the type of the operation type
+-- pUnit, the unit doing the operation
+-- ===========================================================================
+function GetBuildImprovementParameters(actionHash, pUnit)
+ if actionHash == UnitOperationTypes.BUILD_IMPROVEMENT_ADJACENT then
+ return {}; -- no parameters
+ end
+ return BASE_GetBuildImprovementParameters(actionHash, pUnit);
+end
+
+-- ===========================================================================
+-- OVERRIDE
+-- Returns: Callback function, Disabled state
+-- ===========================================================================
+function GetBuildImprovementCallback( actionHash :number, isDisabledIn:boolean )
+ local callbackFn :ifunction = OnUnitActionClicked_BuildImprovement;
+ local isDisabled :boolean = isDisabledIn;
+ if (actionHash == UnitOperationTypes.BUILD_IMPROVEMENT_ADJACENT) then
+ callbackFn = OnUnitActionClicked_BuildImprovementAdjacent;
+ isDisabledModified = false;
+ else
+ callbackFn = OnUnitActionClicked_BuildImprovement;
+ isDisabledModified = isDisabled;
+ end
+ return callbackFn, isDisabledModified;
+end
+
+-- ===========================================================================
+function AddUpgradeResourceCost( pUnit:table )
+ local toolTipString:string = "";
+ if (GameInfo.Units_XP2~= nil) then
+ local upgradeResource, upgradeResourceCost = pUnit:GetUpgradeResourceCost();
+ if (upgradeResource ~= nil and upgradeResource >= 0) then
+ local resourceName:string = Locale.Lookup(GameInfo.Resources[upgradeResource].Name);
+ local resourceIcon = "[ICON_" .. GameInfo.Resources[upgradeResource].ResourceType .. "]";
+ toolTipString = "[NEWLINE]" .. Locale.Lookup("LOC_UNITOPERATION_UPGRADE_RESOURCE_INFO", upgradeResourceCost, resourceIcon, resourceName)
+ end
+ end
+ return toolTipString;
+end
+
+-- ===========================================================================
+-- UnitAction was clicked.
+-- ===========================================================================
+function OnUnitActionClicked_BuildImprovementAdjacent( improvementHash, dummy )
+ if (g_isOkayToProcess) then
+ local pSelectedUnit = UI.GetHeadSelectedUnit();
+ if (pSelectedUnit ~= nil) then
+ local tParameters = {};
+ tParameters[UnitOperationTypes.PARAM_IMPROVEMENT_TYPE] = improvementHash;
+ tParameters[UnitOperationTypes.PARAM_OPERATION_TYPE] = UnitOperationTypes.BUILD_IMPROVEMENT_ADJACENT;
+ UI.SetInterfaceMode(InterfaceModeTypes.BUILD_IMPROVEMENT_ADJACENT, tParameters);
+ end
+ ContextPtr:RequestRefresh();
+ end
+end
+
+-- ===========================================================================
+function RockbandView( kData:table )
+ if kData.IsRockbandUnit == false then return; end
+ -- TODO: populate with rock band information if using a custom view (may want to remove stats data entries)
+end
+
+
+-- ===========================================================================
+-- OVERRIDE
+-- ===========================================================================
+function FilterUnitStatsFromUnitData( kUnitData:table, ignoreStatType:number )
+ local kData:table= BASE_FilterUnitStatsFromUnitData( kUnitData, ignoreStatType );
+
+ if kUnitData.IsRockbandUnit then
+ table.insert(kData, {Value = kUnitData.AlbumSales, Type = "ActionCharges", Label = "LOC_HUD_UNIT_PANEL_ROCK_BAND_ALBUM_SALES", FontIcon="[ICON_Charges_Large]", IconName="ICON_STAT_RECORD_SALES"});
+ table.insert(kData, {Value = kUnitData.RockBandLevel, Type = "SpreadCharges", Label = "LOC_HUD_UNIT_PANEL_ROCK_BAND_LEVEL", FontIcon="[ICON_ReligionStat_Large]", IconName="ICON_STAT_ROCKBAND_LEVEL"});
+ end
+
+ return kData;
+end
+
+-- ===========================================================================
+function RealizeSpecializedViews( kData:table )
+ Base_RealizeSpecializedViews(kData);
+ RockbandView(kData);
+end
\ No newline at end of file
diff --git a/Replacements/WorldInput_Expansion1.lua b/Replacements/WorldInput_Expansion1.lua
index 4b1a22a..aa632e4 100644
--- a/Replacements/WorldInput_Expansion1.lua
+++ b/Replacements/WorldInput_Expansion1.lua
@@ -137,6 +137,7 @@ function OnInterfaceModeLeave_PriorityTarget(eNewMode:number)
UILens.ClearLayerHexes(g_HexColoringMovement);
end
+
-- ===========================================================================
-- OVERRIDE
-- ===========================================================================
diff --git a/Replacements/WorldInput_Expansion2.lua b/Replacements/WorldInput_Expansion2.lua
new file mode 100644
index 0000000..9e87f25
--- /dev/null
+++ b/Replacements/WorldInput_Expansion2.lua
@@ -0,0 +1,165 @@
+--[[
+-- Copyright (c) 2018 Firaxis Games
+--]]
+-- ===========================================================================
+-- INCLUDE XP1 FILE
+-- ===========================================================================
+include("WorldInput_Expansion1");
+
+-- ===========================================================================
+-- CACHE BASE FUNCTIONS
+-- ===========================================================================
+XP1_LateInitialize = LateInitialize;
+
+
+-- ===========================================================================
+-- Code related to the Unit's 'BuildImprovementAdjacent' mode
+-- ===========================================================================
+function OnMouseBuildImprovementAdjacentEnd( pInputStruct:table )
+ -- If a drag was occurring, end it; otherwise raise event.
+ if g_isMouseDragging then
+ g_isMouseDragging = false;
+ elseif IsSelectionAllowedAt( UI.GetCursorPlotID() ) then
+ BuildImprovementAdjacent(pInputStruct);
+ end
+ EndDragMap();
+ g_isMouseDownInWorld = false;
+ return true;
+end
+
+-- ===========================================================================
+function BuildImprovementAdjacent( pInputStruct:table )
+ local plotID = UI.GetCursorPlotID();
+ if Map.IsPlot(plotID) then
+ local plot = Map.GetPlotByIndex(plotID);
+
+ local tParameters = {};
+ tParameters[UnitOperationTypes.PARAM_X] = plot:GetX();
+ tParameters[UnitOperationTypes.PARAM_Y] = plot:GetY();
+ tParameters[UnitOperationTypes.PARAM_IMPROVEMENT_TYPE] = UI.GetInterfaceModeParameter(UnitOperationTypes.PARAM_IMPROVEMENT_TYPE);
+
+ local pSelectedUnit = UI.GetHeadSelectedUnit();
+ if (UnitManager.CanStartOperation( pSelectedUnit, UnitOperationTypes.BUILD_IMPROVEMENT_ADJACENT, nil, tParameters)) then
+ UnitManager.RequestOperation( pSelectedUnit, UnitOperationTypes.BUILD_IMPROVEMENT_ADJACENT, tParameters);
+ UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
+ end
+ end
+ return true;
+end
+
+-- ===========================================================================
+function OnInterfaceModeChange_BuildImprovementAdjacent( eNewMode:number )
+ UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
+ local pSelectedUnit = UI.GetHeadSelectedUnit();
+ local eOperation = UI.GetInterfaceModeParameter(UnitOperationTypes.PARAM_OPERATION_TYPE);
+ local tParameters = {};
+ tParameters[UnitOperationTypes.PARAM_IMPROVEMENT_TYPE] = UI.GetInterfaceModeParameter(UnitOperationTypes.PARAM_IMPROVEMENT_TYPE);
+ local tResults = UnitManager.GetOperationTargets(pSelectedUnit, eOperation, tParameters);
+ local allPlots = tResults[UnitOperationResults.PLOTS];
+ if allPlots then
+ g_targetPlots = allPlots;
+
+ -- Highlight the plots available to attack a priority target
+ if (table.count(g_targetPlots) ~= 0) then
+ local pOverlay:object = UILens.GetOverlay("PlacementValidOverlay");
+ if pOverlay ~= nil then
+ pOverlay:CreateSprites( g_targetPlots, "Placement_Valid", 0 );
+ end
+ end
+ end
+end
+
+-- ===========================================================================
+function OnInterfaceModeLeave_BuildImprovementAdjacent( eNewMode:number )
+ UIManager:SetUICursor(CursorTypes.NORMAL);
+ local pOverlay:object = UILens.GetOverlay("PlacementValidOverlay");
+ if pOverlay ~= nil then
+ pOverlay:ClearAll();
+ end
+end
+
+
+------------------------------------------------------------------------------------------------
+-- Code related to a Unit's 'Jump' move ability
+------------------------------------------------------------------------------------------------
+function OnMouseMoveJumpEnd(pInputStruct)
+ -- If a drag was occurring, end it; otherwise raise event.
+ if g_isMouseDragging then
+ g_isMouseDragging = false;
+ elseif IsSelectionAllowedAt( UI.GetCursorPlotID() ) then
+ MoveJump(pInputStruct);
+ end
+ EndDragMap();
+ g_isMouseDownInWorld = false;
+ return true;
+end
+------------------------------------------------------------------------------------------------
+function MoveJump(pInputStruct)
+ local plotID = UI.GetCursorPlotID();
+ if Map.IsPlot(plotID) then
+ local plot = Map.GetPlotByIndex(plotID);
+
+ local tParameters = {};
+ tParameters[UnitCommandTypes.PARAM_X] = plot:GetX();
+ tParameters[UnitCommandTypes.PARAM_Y] = plot:GetY();
+
+ local pSelectedUnit = UI.GetHeadSelectedUnit();
+ if (UnitManager.CanStartCommand( pSelectedUnit, UnitCommandTypes.MOVE_JUMP, tParameters)) then
+ UnitManager.RequestCommand( pSelectedUnit, UnitCommandTypes.MOVE_JUMP, tParameters);
+ UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
+ end
+ end
+ return true;
+end
+------------------------------------------------------------------------------------------------
+function OnInterfaceModeChange_MoveJump(eNewMode)
+ UIManager:SetUICursor(CursorTypes.RANGE_ATTACK);
+ local pSelectedUnit = UI.GetHeadSelectedUnit();
+ local tResults = UnitManager.GetCommandTargets(pSelectedUnit, UnitCommandTypes.MOVE_JUMP );
+ local allPlots = tResults[CityCommandResults.PLOTS];
+ if allPlots then
+ g_targetPlots = {};
+ for i,modifier in ipairs(tResults[CityCommandResults.PLOTS]) do
+ table.insert(g_targetPlots, allPlots[i]);
+ end
+
+ -- Highlight the plots available to jump to
+ if (table.count(g_targetPlots) ~= 0) then
+ UILens.ToggleLayerOn(g_HexColoringMovement);
+ UILens.SetLayerHexesArea(g_HexColoringMovement, Game.GetLocalPlayer(), g_targetPlots);
+ end
+ end
+end
+--------------------------------------------------------------------------------------------------
+function OnInterfaceModeLeave_MoveJump(eNewMode:number)
+ UIManager:SetUICursor(CursorTypes.NORMAL);
+ UILens.ToggleLayerOff(g_HexColoringMovement);
+ UILens.ClearLayerHexes(g_HexColoringMovement);
+end
+
+
+
+-- ===========================================================================
+-- OVERRIDE
+-- ===========================================================================
+function LateInitialize()
+
+ XP1_LateInitialize();
+
+ InterfaceModeMessageHandler[InterfaceModeTypes.BUILD_IMPROVEMENT_ADJACENT] = {};
+ InterfaceModeMessageHandler[InterfaceModeTypes.BUILD_IMPROVEMENT_ADJACENT][INTERFACEMODE_ENTER]= OnInterfaceModeChange_BuildImprovementAdjacent;
+ InterfaceModeMessageHandler[InterfaceModeTypes.BUILD_IMPROVEMENT_ADJACENT][INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_BuildImprovementAdjacent;
+ InterfaceModeMessageHandler[InterfaceModeTypes.BUILD_IMPROVEMENT_ADJACENT][MouseEvents.LButtonUp] = OnMouseBuildImprovementAdjacentEnd;
+ InterfaceModeMessageHandler[InterfaceModeTypes.BUILD_IMPROVEMENT_ADJACENT][KeyEvents.KeyUp] = OnPlacementKeyUp;
+
+ InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_JUMP] = {};
+ InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_JUMP][INTERFACEMODE_ENTER]= OnInterfaceModeChange_MoveJump;
+ InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_JUMP][INTERFACEMODE_LEAVE] = OnInterfaceModeLeave_MoveJump;
+ InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_JUMP][MouseEvents.LButtonUp] = OnMouseMoveJumpEnd;
+ InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_JUMP][KeyEvents.KeyUp] = OnPlacementKeyUp;
+
+ if g_isTouchEnabled then
+ InterfaceModeMessageHandler[InterfaceModeTypes.BUILD_IMPROVEMENT_ADJACENT][MouseEvents.PointerUp] = OnMouseBuildImprovementAdjacentEnd;
+ InterfaceModeMessageHandler[InterfaceModeTypes.MOVE_JUMP][MouseEvents.PointerUp] = OnMouseMoveJumpEnd;
+ end
+end
\ No newline at end of file
diff --git a/Replacements/WorldRankings.xml b/Replacements/WorldRankings.xml
new file mode 100644
index 0000000..6686625
--- /dev/null
+++ b/Replacements/WorldRankings.xml
@@ -0,0 +1,666 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Replacements/WorldRankings_Expansion2.lua b/Replacements/WorldRankings_Expansion2.lua
new file mode 100644
index 0000000..5595f8a
--- /dev/null
+++ b/Replacements/WorldRankings_Expansion2.lua
@@ -0,0 +1,704 @@
+-- Copyright 2018, Firaxis Games
+
+-- ===========================================================================
+-- Includes
+-- ===========================================================================
+include("WorldRankings");
+
+-- ===========================================================================
+-- Constants
+-- ===========================================================================
+local PADDING_GENERIC_ITEM_BG:number = 25;
+local SIZE_GENERIC_ITEM_MIN_Y:number = 54;
+local DATA_FIELD_SELECTION:string = "Selection";
+local PADDING_TAB_BUTTON_TEXT:number = 27;
+
+local m_ScienceIM:table = InstanceManager:new("ScienceInstance", "ButtonBG", Controls.ScienceViewStack);
+local m_ScienceTeamIM:table = InstanceManager:new("ScienceTeamInstance", "ButtonFrame", Controls.ScienceViewStack);
+local m_ScienceHeaderIM:table = InstanceManager:new("ScienceHeaderInstance", "HeaderTop", Controls.ScienceViewHeader);
+
+local SPACE_PORT_DISTRICT_INFO:table = GameInfo.Districts["DISTRICT_SPACEPORT"];
+local EARTH_SATELLITE_EXP2_PROJECT_INFOS:table = {
+ GameInfo.Projects["PROJECT_LAUNCH_EARTH_SATELLITE"]
+};
+local MOON_LANDING_EXP2_PROJECT_INFOS:table = {
+ GameInfo.Projects["PROJECT_LAUNCH_MOON_LANDING"]
+};
+local MARS_COLONY_EXP2_PROJECT_INFOS:table = {
+ GameInfo.Projects["PROJECT_LAUNCH_MARS_BASE"],
+};
+local EXOPLANET_EXP2_PROJECT_INFOS:table = {
+ GameInfo.Projects["PROJECT_LAUNCH_EXOPLANET_EXPEDITION"],
+};
+local SCIENCE_PROJECTS_EXP2:table = {
+ EARTH_SATELLITE_EXP2_PROJECT_INFOS,
+ MOON_LANDING_EXP2_PROJECT_INFOS,
+ MARS_COLONY_EXP2_PROJECT_INFOS,
+ EXOPLANET_EXP2_PROJECT_INFOS
+};
+
+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_EXP2");
+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"),
+ Locale.Lookup("LOC_WORLD_RANKINGS_SCIENCE_REQUIREMENT_4")
+};
+
+-- ===========================================================================
+-- Cached Functions
+-- ===========================================================================
+BASE_PopulateTabs = PopulateTabs;
+BASE_AddTab = AddTab;
+BASE_AddExtraTab = AddExtraTab;
+BASE_OnTabClicked = OnTabClicked;
+BASE_PopulateGenericInstance = PopulateGenericInstance;
+BASE_PopulateGenericTeamInstance = PopulateGenericTeamInstance;
+BASE_GetDefaultStackSize = GetDefaultStackSize;
+
+g_victoryData.VICTORY_DIPLOMATIC = {
+ GetText = function(p)
+ local total = GlobalParameters.DIPLOMATIC_VICTORY_POINTS_REQUIRED;
+ local current = 0;
+ if (p:IsAlive()) then
+ current = p:GetStats():GetDiplomaticVictoryPoints();
+ end
+
+ return Locale.Lookup("LOC_WORLD_RANKINGS_DIPLOMATIC_POINTS_TT", current, total);
+ end,
+ GetScore = function(p)
+ local current = 0;
+ if (p:IsAlive()) then
+ current = p:GetStats():GetDiplomaticVictoryPoints();
+ end
+
+ return current;
+ end
+};
+
+-- ===========================================================================
+-- Overrides
+-- ===========================================================================
+function OnTabClicked(tabInst:table, onClickCallback:ifunction)
+ return function()
+ DeselectPreviousTab();
+ DeselectExtraTabs();
+ tabInst.Selection:SetHide(false);
+ onClickCallback();
+ end
+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, true);
+ 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, "VictoryProgress");
+ local requirementText:string = GameEffects.GetRequirementText(requirementID, requirementKey);
+
+ if requirementText ~= nil then
+ detailsText = detailsText .. requirementText;
+ local civIconClass = CivilizationIcon:AttachInstance(instance.CivilizationIcon or instance);
+ if playerData ~= nil then
+ civIconClass:SetLeaderTooltip(playerData.PlayerID, requirementText);
+ end
+ 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
+ instance.Details:SetText(detailsText);
+ end
+ 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 )
+ PopulatePlayerInstanceShared(instance, playerData.PlayerID);
+
+ 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, "VictoryProgress");
+ local requirementText:string = GameEffects.GetRequirementText(requirementID, requirementKey);
+
+ if requirementText ~= nil then
+ detailsText = detailsText .. requirementText;
+ local civIconClass = CivilizationIcon:AttachInstance(instance.CivilizationIcon or instance);
+ civIconClass:SetLeaderTooltip(playerData.PlayerID, 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
+
+-- ===========================================================================
+-- 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, 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 - satellite launch
+ totalCost = 0;
+ currentProgress = 0;
+ for i, projectInfo in ipairs(EARTH_SATELLITE_EXP2_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_EXP2_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_EXP2_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;
+
+ -- 4th milestone - exoplanet expeditiion
+ totalCost = 0;
+ currentProgress = 0;
+ for i, projectInfo in ipairs(EXOPLANET_EXP2_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[4][i] = projectProgress == projectCost;
+ end
+ progressResults[4] = 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_EXP2[i], bHasSpaceport, finishedProjects[i]);
+ end
+ else
+ progressText = progressText .. "[ICON_CheckmarkBlue] ";
+ end
+ progressText = progressText .. SCIENCE_REQUIREMENTS[i];
+ if(i < 4) then progressText = progressText .. "[NEWLINE]"; end
+ end
+
+ m_ActiveHeader.AdvisorTextCentered:SetText(progressText);
+ if (nextStep ~= "") then
+ m_ActiveHeader.AdvisorTextNextStep:SetText(Locale.Lookup("LOC_WORLD_RANKINGS_SCIENCE_NEXT_STEP", nextStep));
+ else
+ local lightYears = m_LocalPlayer:GetStats():GetScienceVictoryPoints();
+ local totalLightYears = m_LocalPlayer:GetStats():GetScienceVictoryPointsTotalNeeded();
+ m_ActiveHeader.AdvisorTextNextStep:SetText(Locale.Lookup("LOC_WORLD_RANKINGS_SCIENCE_HAS_MOVED", lightYears, totalLightYears));
+ end
+
+ 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 PopulateScienceInstance(instance:table, pPlayer:table)
+ local playerID:number = pPlayer:GetID();
+ PopulatePlayerInstanceShared(instance, playerID);
+
+ -- Progress Data to be returned from function
+ local progressData = nil;
+
+ 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, 0 };
+ local projectProgresses:table = { 0, 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_EXP2_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_EXP2_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_EXP2_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;
+ projectTotals[3] = projectTotals[3] + projectCost;
+ if projectProgress ~= 0 then
+ projectProgresses[3] = projectProgresses[3] + projectProgress;
+ finishedProjects[3][i] = projectProgress == projectCost;
+ end
+ end
+
+ -- 4th milestone - exoplanet expedition
+ for i, projectInfo in ipairs(EXOPLANET_EXP2_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[4][i] = false;
+ projectTotals[4] = projectTotals[4] + projectCost;
+ if projectProgress ~= 0 then
+ projectProgresses[4] = projectProgresses[4] + projectProgress;
+ finishedProjects[4][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);
+
+ return progressData;
+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 PopulateScienceProgressMeters(instance:table, progressData:table)
+ local pPlayer = Players[progressData.playerID];
+
+ for i = 1, 4 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
+
+ instance["ObjHidden_5"]:SetHide(true);
+ -- if bar 4 is at 100%, light up bar 5
+ if ((progressData.projectProgresses[4] >= progressData.projectTotals[4]) and (progressData.projectTotals[4] ~= 0)) then
+ local lightYears = pPlayer:GetStats():GetScienceVictoryPoints();
+ local lightYearsPerTurn = pPlayer:GetStats():GetScienceVictoryPointsPerTurn();
+ local totalLightYears = m_LocalPlayer:GetStats():GetScienceVictoryPointsTotalNeeded();
+
+ instance["ObjFill_5"]:SetHide(false);
+ instance["ObjToggle_ON_5"]:SetHide(lightYears == 0 or lightYears < lightYearsPerTurn);
+ -- my test save returns a larger value for light years than for years needed, so guard against drawing errors
+ if lightYears > totalLightYears then
+ lightYears = totalLightYears;
+ end
+ instance["ObjBar_5"]:SetPercent(lightYears/totalLightYears);
+ instance.ObjBG_5:SetToolTipString(Locale.Lookup("LOC_WORLD_RANKINGS_SCIENCE_IS_MOVING", lightYearsPerTurn));
+ else
+ instance["ObjFill_5"]:SetHide(true);
+ instance["ObjToggle_ON_5"]:SetHide(true);
+ instance["ObjBar_5"]:SetPercent(0);
+ instance.ObjBG_5:SetToolTipString(Locale.Lookup("LOC_WORLD_RANKINGS_SCIENCE_NO_LAUNCH"));
+ end
+
+ instance.ObjBG_1:SetToolTipString(GetTooltipForScienceProject(pPlayer, EARTH_SATELLITE_EXP2_PROJECT_INFOS, progressData.bHasSpaceport, progressData.finishedProjects[1]));
+ instance.ObjBG_2:SetToolTipString(GetTooltipForScienceProject(pPlayer, MOON_LANDING_EXP2_PROJECT_INFOS, nil, progressData.finishedProjects[2]));
+ instance.ObjBG_3:SetToolTipString(GetTooltipForScienceProject(pPlayer, MARS_COLONY_EXP2_PROJECT_INFOS, nil, progressData.finishedProjects[3]));
+ instance.ObjBG_4:SetToolTipString(GetTooltipForScienceProject(pPlayer, EXOPLANET_EXP2_PROJECT_INFOS, nil, progressData.finishedProjects[4]));
+end
+
+-- ===========================================================================
+-- 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 g_TabSupport then
+ g_TabSupport.SelectTab(nil);
+ DeselectPreviousTab();
+ DeselectExtraTabs();
+ end
+
+ -- Create TabSupport object
+ g_TabSupport = CreateTabs(Controls.TabContainer, 42, 44, 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
+ BASE_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
+ if (victoryType == "VICTORY_DIPLOMATIC") then
+ AddTab(Locale.Lookup("LOC_TOOLTIP_DIPLOMACY_CONGRESS_BUTTON"), function() ViewDiplomatic(victoryType); end);
+ else
+ AddTab(Locale.Lookup(row.Name), function() ViewGeneric(victoryType); end);
+ end
+ end
+ end
+
+ if m_TotalTabSize > (Controls.TabContainer:GetSizeX()*2) 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.ExpandExtraTabs:SetHide(true);
+
+ g_TabSupport.SelectTab(defaultTab);
+ g_TabSupport.CenterAlignTabs(0, 450, 32);
+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() * 2) then
+ m_TabSupportIM:ReleaseInstance(tabInst);
+ AddExtraTab(label, onClickCallback);
+ else
+ g_TabSupport.AddTab(tabInst.Button, OnTabClicked(tabInst, onClickCallback));
+ end
+
+ return tabInst.Button;
+end
+
+function AddExtraTab(label:string, onClickCallback:ifunction)
+ local extraTabInst:table = m_ExtraTabsIM:GetInstance();
+
+ extraTabInst.Button:SetText(label);
+ extraTabInst.Button:RegisterCallback(Mouse.eLClick, OnExtraTabClicked(extraTabInst, onClickCallback));
+
+ 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
+
+function ViewDiplomatic(victoryType:string)
+ ResetState(function() ViewDiplomatic(victoryType); end);
+ Controls.GenericView:SetHide(false);
+
+ ChangeActiveHeader("GENERIC", m_GenericHeaderIM, Controls.GenericViewHeader);
+
+ local victoryInfo:table = GameInfo.Victories[victoryType];
+ if victoryInfo.Icon ~= nil then
+ PopulateGenericHeader(RealizeGenericStackSize, victoryInfo.Name, nil, victoryInfo.Description, victoryInfo.Icon);
+ else
+ PopulateGenericHeader(RealizeGenericStackSize, victoryInfo.Name, nil, victoryInfo.Description, ICON_GENERIC);
+ end
+
+ local genericData:table = GatherGenericData();
+
+ m_GenericIM:ResetInstances();
+ m_GenericTeamIM:ResetInstances();
+
+ local ourData:table = {};
+
+ for i, teamData in ipairs(genericData) do
+ local ourTeamData:table = { teamData, score };
+
+ ourTeamData.teamData = teamData;
+ local progress = Game.GetVictoryProgressForTeam(victoryType, teamData.TeamID);
+ if progress == nil then
+ progress = 0;
+ end
+ ourTeamData.score = progress;
+
+ table.insert(ourData, ourTeamData);
+ end
+
+ table.sort(ourData, function(a, b)
+ return a.score > b.score;
+ end);
+
+ for i, theData in ipairs(ourData) do
+ if #theData.teamData.PlayerData > 1 then
+ PopulateGenericTeamInstance(m_GenericTeamIM:GetInstance(), theData.teamData, victoryType);
+ else
+ PopulateGenericInstance(m_GenericIM:GetInstance(), theData.teamData.PlayerData[1], victoryType, true);
+ end
+ end
+
+ RealizeGenericStackSize();
+end
+
+function GetDefaultStackSize()
+ return 265;
+end
+
+-- ===========================================================================
+-- Constructor
+-- ===========================================================================
+function Initialize()
+ ToggleExtraTabs(); -- Start with extra tabs opened so DiplomaticVictory tab is visible by default
+end
+Initialize();
\ No newline at end of file
diff --git a/Replacements/WorldTracker.xml b/Replacements/WorldTracker.xml
new file mode 100644
index 0000000..2d87805
--- /dev/null
+++ b/Replacements/WorldTracker.xml
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Subtitles/de_DE/XP2Victory_Diplomatic.srt b/Subtitles/de_DE/XP2Victory_Diplomatic.srt
new file mode 100644
index 0000000..fa8230e
--- /dev/null
+++ b/Subtitles/de_DE/XP2Victory_Diplomatic.srt
@@ -0,0 +1,28 @@
+1
+00:00:01,610 --> 00:00:04,970
+Von Anfang an wolltet Ihr nichts als Frieden.
+
+2
+00:00:04,970 --> 00:00:08,210
+Ihr habt gegen Aggressoren Stellung bezogen ...
+
+3
+00:00:08,510 --> 00:00:11,410
+... und wart stets um Kooperation bemüht.
+
+4
+00:00:11,910 --> 00:00:15,620
+Das habt Ihr nicht nur um Eures Ruhmes willen getan ...
+
+5
+00:00:15,710 --> 00:00:19,620
+... sondern weil Würde jedem von uns gebührt.
+
+6
+00:00:20,700 --> 00:00:27,310
+So habt Ihr dafür gesorgt, dass Euer andauerndes Engagement für den Frieden aller ...
+
+7
+00:00:27,410 --> 00:00:31,320
+... der Grundstein für die Welt von morgen sein wird.
+
diff --git a/Subtitles/de_DE/XP2_Opening.srt b/Subtitles/de_DE/XP2_Opening.srt
new file mode 100644
index 0000000..1953752
--- /dev/null
+++ b/Subtitles/de_DE/XP2_Opening.srt
@@ -0,0 +1,76 @@
+1
+00:00:05,400 --> 00:00:09,510
+Der menschliche Fortschritt kennt keine Grenzen.
+
+2
+00:00:11,288 --> 00:00:14,460
+Aber das hat auch immer seinen Preis.
+
+3
+00:00:24,471 --> 00:00:27,863
+Obwohl wir jetzt im größten Wohlstand leben ...
+
+4
+00:00:28,314 --> 00:00:31,818
+... erinnert uns ein Blick in die Vergangenheit ...
+
+5
+00:00:34,710 --> 00:00:39,460
+... dass wir die Natur niemals unterschätzen dürfen.
+
+6
+00:00:45,063 --> 00:00:48,840
+Sie verschlingt das mächtigste Imperium ...
+
+7
+00:00:51,317 --> 00:00:54,462
+... und selbst die Größten und Mächtigsten unter uns
+
+8
+00:00:56,911 --> 00:00:59,848
+... zittern vor ihrem Zorn.
+
+9
+00:01:08,520 --> 00:01:13,423
+Doch der Mensch übersteht alle Widrigkeiten.
+
+10
+00:01:15,416 --> 00:01:18,748
+Er lebt im Einklang mit der Erde ...
+
+11
+00:01:25,755 --> 00:01:28,552
+... oder er unterwirft sie.
+
+12
+00:01:33,053 --> 00:01:36,980
+Er richtet den Blick auf den fernen Horizont …
+
+13
+00:01:40,983 --> 00:01:42,982
+und findet einen Weg ...
+
+14
+00:01:47,213 --> 00:01:49,414
+... hin zu Innovationen ...
+
+15
+00:01:55,630 --> 00:01:58,611
+... doch auch zu ungewollten Katastrophen.
+
+16
+00:02:04,910 --> 00:02:11,678
+Um zu überleben, müssen wir neue Lösungen für alte Probleme finden ...
+
+17
+00:02:14,853 --> 00:02:21,416
+... um die Welt zu erhalten für uns und die Generationen nach uns.
+
+18
+00:02:22,663 --> 00:02:28,315
+Mit vereinten Kräften schauen wir über Grenzen hinaus.
+
+19
+00:02:28,610 --> 00:02:35,819
+Und begrüßen die nächste Ära menschlicher Zivilisation.
+
diff --git a/Subtitles/en_US/XP2Victory_Diplomatic.srt b/Subtitles/en_US/XP2Victory_Diplomatic.srt
new file mode 100644
index 0000000..7f862c1
--- /dev/null
+++ b/Subtitles/en_US/XP2Victory_Diplomatic.srt
@@ -0,0 +1,29 @@
+1
+00:00:01,610 --> 00:00:04,970
+From your earliest desire to live in peace…
+
+2
+00:00:04,970 --> 00:00:08,210
+... To the times when you stood against aggression…
+
+3
+00:00:08,510 --> 00:00:11,410
+…you have always sought cooperation.
+
+4
+00:00:11,910 --> 00:00:15,620
+You did not do this merely to brighten your own glory …
+
+5
+00:00:15,710 --> 00:00:19,620
+...But because dignity, belongs to each of us.
+
+6
+00:00:20,700 --> 00:00:27,310
+And in so doing, you have proved that your ancient
+and eternal commitment to a shared peace…
+
+7
+00:00:27,410 --> 00:00:31,320
+will be the foundation, of the world of tomorrow.
+
diff --git a/Subtitles/en_US/XP2_Opening.srt b/Subtitles/en_US/XP2_Opening.srt
new file mode 100644
index 0000000..cbc0c12
--- /dev/null
+++ b/Subtitles/en_US/XP2_Opening.srt
@@ -0,0 +1,76 @@
+1
+00:00:05,400 --> 00:00:09,510
+Human advancement knows no boundary.
+
+2
+00:00:11,288 --> 00:00:14,460
+But this has not been without its price.
+
+3
+00:00:24,471 --> 00:00:27,863
+Though we stand at the height of prosperity…
+
+4
+00:00:28,314 --> 00:00:31,818
+We need only look to the past to remember…
+
+5
+00:00:34,710 --> 00:00:39,460
+...That Nature is a power that cannot be ignored.
+
+6
+00:00:45,063 --> 00:00:48,840
+Consuming even the mightiest empires…
+
+7
+00:00:51,317 --> 00:00:54,462
+And causing the greatest among us
+
+8
+00:00:56,911 --> 00:00:59,848
+... to tremble in her fury.
+
+9
+00:01:08,520 --> 00:01:13,423
+Yet from adversity the human spirit endures…
+
+10
+00:01:15,416 --> 00:01:18,748
+Finding ways to coexist with the Earth…
+
+11
+00:01:25,755 --> 00:01:28,552
+Or bend it to our cause.
+
+12
+00:01:33,053 --> 00:01:36,980
+Pursuing a course beyond distant horizons...
+
+13
+00:01:40,983 --> 00:01:42,982
+and revealing paths…
+
+14
+00:01:47,213 --> 00:01:49,414
+...both towards innovation..
+
+15
+00:01:55,630 --> 00:01:58,611
+And unintended catastrophe.
+
+16
+00:02:04,910 --> 00:02:11,678
+Our survival necessitates new solutions to old problems.
+
+17
+00:02:14,853 --> 00:02:21,416
+To ensure a future both for ourselves and generations to come…
+
+18
+00:02:22,663 --> 00:02:28,315
+United in purpose, we must now look beyond borders.
+
+19
+00:02:28,610 --> 00:02:35,819
+And welcome the dawn of the next era in human civilization.
+
diff --git a/Subtitles/es_ES/XP2Victory_Diplomatic.srt b/Subtitles/es_ES/XP2Victory_Diplomatic.srt
new file mode 100644
index 0000000..f284920
--- /dev/null
+++ b/Subtitles/es_ES/XP2Victory_Diplomatic.srt
@@ -0,0 +1,28 @@
+1
+00:00:01,610 --> 00:00:04,970
+De vuestro deseo original para vivir en paz
+
+2
+00:00:04,970 --> 00:00:08,210
+a las veces en las que resististeis las agresiones,
+
+3
+00:00:08,510 --> 00:00:11,410
+siempre habéis intentado cooperar.
+
+4
+00:00:11,910 --> 00:00:15,620
+No lo hicisteis solo por ensalzar vuestra propia gloria,
+
+5
+00:00:15,710 --> 00:00:19,620
+también porque la dignidad nos pertenece a todos.
+
+6
+00:00:20,700 --> 00:00:27,310
+De este modo habéis demostrado que vuestro compromiso ancestral y eterno por compartir la paz
+
+7
+00:00:27,410 --> 00:00:31,320
+será la piedra angular del mundo del mañana.
+
diff --git a/Subtitles/es_ES/XP2_Opening.srt b/Subtitles/es_ES/XP2_Opening.srt
new file mode 100644
index 0000000..f866580
--- /dev/null
+++ b/Subtitles/es_ES/XP2_Opening.srt
@@ -0,0 +1,76 @@
+1
+00:00:05,400 --> 00:00:09,510
+El progreso humano no conoce límites,
+
+2
+00:00:11,288 --> 00:00:14,460
+pero siempre hay que pagar un precio.
+
+3
+00:00:24,471 --> 00:00:27,863
+Aunque estemos viviendo una época de prosperidad,
+
+4
+00:00:28,314 --> 00:00:31,818
+solo hay que mirar al pasado para recordar
+
+5
+00:00:34,710 --> 00:00:39,460
+que el poder de la naturaleza no se debe ignorar.
+
+6
+00:00:45,063 --> 00:00:48,840
+Ha consumido a los imperios más poderosos,
+
+7
+00:00:51,317 --> 00:00:54,462
+y hasta los mejores de nosotros
+
+8
+00:00:56,911 --> 00:00:59,848
+temblamos ante su furia.
+
+9
+00:01:08,520 --> 00:01:13,923
+Pero el espíritu humano siempre prevalece
+
+10
+00:01:15,416 --> 00:01:18,748
+y consigue coexistir con el planeta
+
+11
+00:01:25,755 --> 00:01:28,552
+o someterlo para su causa.
+
+12
+00:01:33,053 --> 00:01:36,980
+Podemos ir más allá de horizontes distantes y
+
+13
+00:01:41,500 --> 00:01:44,000
+revelar sendas
+
+14
+00:01:47,000 --> 00:01:49,614
+hacia futuras innovaciones
+
+15
+00:01:55,630 --> 00:01:59,100
+e inevitables catástrofes.
+
+16
+00:02:04,910 --> 00:02:11,678
+Necesitamos nuevas soluciones para antiguos problemas.
+
+17
+00:02:14,853 --> 00:02:21,416
+Para garantizar nuestro futuro y el de futuras generaciones
+
+18
+00:02:22,663 --> 00:02:28,315
+debemos vencer las fronteras trabajando mano a mano
+
+19
+00:02:28,610 --> 00:02:35,819
+y dar la bienvenida a la próxima era de la civilización.
+
diff --git a/Subtitles/fr_FR/XP2Victory_Diplomatic.srt b/Subtitles/fr_FR/XP2Victory_Diplomatic.srt
new file mode 100644
index 0000000..0d777d6
--- /dev/null
+++ b/Subtitles/fr_FR/XP2Victory_Diplomatic.srt
@@ -0,0 +1,28 @@
+1
+00:00:01,610 --> 00:00:04,970
+Depuis vos premiers désirs de vivre en paix...
+
+2
+00:00:04,970 --> 00:00:08,210
+...à vos rejets formels de toute agression...
+
+3
+00:00:08,510 --> 00:00:11,410
+...vous avez toujours voulu coopérer.
+
+4
+00:00:11,910 --> 00:00:15,620
+Vous ne l'avez pas fait pour assurer votre propre gloire...
+
+5
+00:00:15,710 --> 00:00:19,620
+...mais parce que la dignité nous appartient à tous.
+
+6
+00:00:20,700 --> 00:00:27,310
+Et ce faisant, vous avez prouvé que votre engagement de longue date pour une paix partagée...
+
+7
+00:00:27,410 --> 00:00:31,320
+...serait la fondation du monde de demain.
+
diff --git a/Subtitles/fr_FR/XP2_Opening.srt b/Subtitles/fr_FR/XP2_Opening.srt
new file mode 100644
index 0000000..970a946
--- /dev/null
+++ b/Subtitles/fr_FR/XP2_Opening.srt
@@ -0,0 +1,76 @@
+1
+00:00:05,400 --> 00:00:09,510
+Les progrès humains n'ont aucune limite...
+
+2
+00:00:11,288 --> 00:00:14,460
+Mais il y a un revers à cette médaille.
+
+3
+00:00:24,471 --> 00:00:27,863
+Car même si nous sommes plus prospères que jamais...
+
+4
+00:00:28,314 --> 00:00:31,818
+Un regard vers le passé suffit à nous rappeler...
+
+5
+00:00:34,710 --> 00:00:39,460
+...que la nature est une puissance qu'on ne doit pas ignorer.
+
+6
+00:00:45,063 --> 00:00:48,840
+Même les plus grands empires ne sont pas à l'abri...
+
+7
+00:00:51,317 --> 00:00:54,462
+Et même les plus brillants parmi nous...
+
+8
+00:00:56,911 --> 00:00:59,848
+...ont tremblé devant sa colère.
+
+9
+00:01:08,520 --> 00:01:13,423
+Mais dans l'adversité, l'esprit humain survit...
+
+10
+00:01:15,416 --> 00:01:18,748
+Il apprend à vivre en paix avec la Terre...
+
+11
+00:01:25,755 --> 00:01:28,552
+...ou bien à l'exploiter.
+
+12
+00:01:33,053 --> 00:01:36,980
+Poursuivant notre route au-delà des horizons,
+
+13
+00:01:40,983 --> 00:01:42,982
+et ouvrant la voie...
+
+14
+00:01:47,213 --> 00:01:49,414
+...vers de grandes innovations...
+
+15
+00:01:55,630 --> 00:01:58,611
+...et des catastrophes imprévisibles...
+
+16
+00:02:04,910 --> 00:02:11,678
+...notre survie requiert de trouver de nouvelles solutions à de vieux problèmes...
+
+17
+00:02:14,853 --> 00:02:21,416
+Pour assurer un avenir, pour nous-mêmes et pour les générations futures...
+
+18
+00:02:22,663 --> 00:02:28,315
+Unis dans notre but, nous devons voir au-delà des frontières...
+
+19
+00:02:28,610 --> 00:02:35,819
+...et accueillir l'aube d'une nouvelle ère pour la civilisation humaine.
+
diff --git a/Subtitles/it_IT/XP2Victory_Diplomatic.srt b/Subtitles/it_IT/XP2Victory_Diplomatic.srt
new file mode 100644
index 0000000..6724c0f
--- /dev/null
+++ b/Subtitles/it_IT/XP2Victory_Diplomatic.srt
@@ -0,0 +1,28 @@
+1
+00:00:01,610 --> 00:00:04,970
+Dalla prima volta che hai desiderato la pace...
+
+2
+00:00:04,970 --> 00:00:08,210
+...ai momenti in cui ti sei levato contro l'aggressione...
+
+3
+00:00:08,510 --> 00:00:11,410
+...hai sempre cercato la cooperazione.
+
+4
+00:00:11,910 --> 00:00:15,620
+Non l'hai fatto solamente per dare lustro alla tua gloria...
+
+5
+00:00:15,710 --> 00:00:19,620
+...ma perché ciascuno di noi merita la propria dignità.
+
+6
+00:00:20,700 --> 00:00:27,310
+Così facendo, hai dimostrato che la tua antica ed eterna dedizione verso una pace condivisa...
+
+7
+00:00:27,410 --> 00:00:31,320
+sarà il fondamento del mondo di domani.
+
diff --git a/Subtitles/it_IT/XP2_Opening.srt b/Subtitles/it_IT/XP2_Opening.srt
new file mode 100644
index 0000000..3fc097d
--- /dev/null
+++ b/Subtitles/it_IT/XP2_Opening.srt
@@ -0,0 +1,76 @@
+1
+00:00:05,400 --> 00:00:09,510
+Il progresso umano non conosce confini.
+
+2
+00:00:11,288 --> 00:00:14,460
+Ma ogni passo avanti ha un prezzo.
+
+3
+00:00:24,471 --> 00:00:27,863
+Anche se abbiamo raggiunto il picco della prosperità...
+
+4
+00:00:28,314 --> 00:00:31,818
+ci basta rivolgere lo sguardo al passato per ricordare...
+
+5
+00:00:34,710 --> 00:00:39,460
+...che la Natura ha una forza che non può essere ignorata.
+
+6
+00:00:45,063 --> 00:00:48,840
+Una forza che può consumare anche gli imperi più grandi...
+
+7
+00:00:51,317 --> 00:00:54,462
+Che è in grado di far tremare i potenti...
+
+8
+00:00:56,911 --> 00:00:59,848
+...al cospetto della sua furia.
+
+9
+00:01:08,520 --> 00:01:13,423
+Eppure lo spirito umano sa resistere in mezzo alle avversità...
+
+10
+00:01:15,416 --> 00:01:18,748
+Trovando sempre il modo di coesistere con la Terra...
+
+11
+00:01:25,755 --> 00:01:28,552
+o di piegarla al suo volere.
+
+12
+00:01:33,053 --> 00:01:36,980
+Così puntiamo oltre l'orizzonte
+
+13
+00:01:40,983 --> 00:01:42,982
+seguendo un cammino...
+
+14
+00:01:47,213 --> 00:01:49,414
+...che conduce all'innovazione...
+
+15
+00:01:55,630 --> 00:01:58,611
+e allo stesso tempo alla catastrofe.
+
+16
+00:02:04,910 --> 00:02:11,678
+La nostra sopravvivenza richiede nuove soluzioni per vecchi problemi.
+
+17
+00:02:14,853 --> 00:02:21,416
+Per assicurare un futuro a noi stessi e alle generazioni che verranno...
+
+18
+00:02:22,663 --> 00:02:28,315
+Uniti da un obiettivo comune, dobbiamo guardare oltre i confini nazionali.
+
+19
+00:02:28,610 --> 00:02:35,819
+E salutare l'alba di una nuova epoca nella civiltà umana.
+
diff --git a/Subtitles/ja_JP/XP2Victory_Diplomatic.srt b/Subtitles/ja_JP/XP2Victory_Diplomatic.srt
new file mode 100644
index 0000000..add2058
--- /dev/null
+++ b/Subtitles/ja_JP/XP2Victory_Diplomatic.srt
@@ -0,0 +1,28 @@
+1
+00:00:01,610 --> 00:00:04,970
+平和な暮らしを求めた時代から…
+
+2
+00:00:04,970 --> 00:00:08,210
+…侵略者に立ち向かった時代まで…
+
+3
+00:00:08,510 --> 00:00:11,410
+…あなたは常に協力を求め
+
+4
+00:00:11,910 --> 00:00:15,620
+自身の栄光を高めるだけにとどまらず…
+
+5
+00:00:15,710 --> 00:00:19,620
+すべての人の尊厳を守ってきました。
+
+6
+00:00:20,700 --> 00:00:27,310
+そして証明したのです。共に平和を実現するという、変わることなきあなたの願いが…
+
+7
+00:00:27,410 --> 00:00:31,320
+明日の世界を築く礎となることを。
+
diff --git a/Subtitles/ja_JP/XP2_Opening.srt b/Subtitles/ja_JP/XP2_Opening.srt
new file mode 100644
index 0000000..f1df088
--- /dev/null
+++ b/Subtitles/ja_JP/XP2_Opening.srt
@@ -0,0 +1,76 @@
+1
+00:00:05,305 --> 00:00:08,837
+人類の進歩は留まるところを知りません。
+
+2
+00:00:11,322 --> 00:00:14,168
+ですが、進歩には代償がつきものです。
+
+3
+00:00:24,663 --> 00:00:27,486
+私たちは繁栄を極めましたが…
+
+4
+00:00:28,463 --> 00:00:31,805
+過去を振り返れば、すぐに思い出せます。
+
+5
+00:00:34,709 --> 00:00:39,666
+…大自然の力を侮るわけにはいかないということを。
+
+6
+00:00:45,208 --> 00:00:48,155
+時には強大な帝国さえも滅ぼし…
+
+7
+00:00:51,461 --> 00:00:53,641
+時として偉大な人々すらも
+
+8
+00:00:57,065 --> 00:00:59,562
+…恐れおののかせた力です。
+
+9
+00:01:08,436 --> 00:01:13,372
+しかし、人類はどんな逆境にもくじけることなく…
+
+10
+00:01:15,433 --> 00:01:18,287
+時には地球とうまく共生し…
+
+11
+00:01:25,817 --> 00:01:28,342
+時には利用してきました。
+
+12
+00:01:33,001 --> 00:01:36,262
+はるかな水平線の彼方を目指す旅路…
+
+13
+00:01:40,927 --> 00:01:42,814
+その先に待つもの…
+
+14
+00:01:47,343 --> 00:01:49,564
+それは革新かもしれません…
+
+15
+00:01:55,797 --> 00:01:58,674
+予期せぬ破滅であるかもしれません。
+
+16
+00:02:04,906 --> 00:02:10,830
+古くからの問題に、今、新たなる答えを出そうではありませんか。
+
+17
+00:02:15,366 --> 00:02:21,225
+私たち自身、そしてこれから生まれてくる子供たちの未来を守るために…
+
+18
+00:02:22,745 --> 00:02:28,314
+国境を越え、私たちは今こそ団結しなければなりません。
+
+19
+00:02:29,019 --> 00:02:35,411
+そして人類の文明を導くのです。新たな時代へと。
+
diff --git a/Subtitles/ko_KR/XP2Victory_Diplomatic.srt b/Subtitles/ko_KR/XP2Victory_Diplomatic.srt
new file mode 100644
index 0000000..8a7aba2
--- /dev/null
+++ b/Subtitles/ko_KR/XP2Victory_Diplomatic.srt
@@ -0,0 +1,28 @@
+1
+00:00:01,610 --> 00:00:04,970
+평화로운 삶을 염원했던 오래전부터...
+
+2
+00:00:04,970 --> 00:00:08,210
+... 적의 공격에 맞섰던 시대까지...
+
+3
+00:00:08,510 --> 00:00:11,410
+...여러분은 항상 힘을 합쳐 함께했습니다.
+
+4
+00:00:11,910 --> 00:00:15,620
+이는 자신만의 영광이 아닌 ...
+
+5
+00:00:15,710 --> 00:00:19,620
+...모두의 존엄을 위함이었습니다.
+
+6
+00:00:20,700 --> 00:00:27,310
+이러한 과정에서 모두의 평화를 위해 오래전부터 이어져 온 여러분의 영원한 노력이...
+
+7
+00:00:27,410 --> 00:00:31,320
+미래를 위한 기반으로 작용한다는 사실을 확인할 수 있었습니다.
+
diff --git a/Subtitles/ko_KR/XP2_Opening.srt b/Subtitles/ko_KR/XP2_Opening.srt
new file mode 100644
index 0000000..d6b1400
--- /dev/null
+++ b/Subtitles/ko_KR/XP2_Opening.srt
@@ -0,0 +1,76 @@
+1
+00:00:05,400 --> 00:00:09,567
+인간은 멈출 줄 모르고 앞을 향해 나아갑니다.
+
+2
+00:00:11,288 --> 00:00:14,075
+그리고 그 대가를 톡톡히 치릅니다.
+
+3
+00:00:24,732 --> 00:00:27,962
+비록 우리는 가장 번영한 시대를 목도하고 있으나...
+
+4
+00:00:28,314 --> 00:00:30,832
+과거를 돌아보며 기억해야 합니다...
+
+5
+00:00:34,710 --> 00:00:39,469
+...무시할 수 없는 거대한 힘은 바로 자연이라는 사실을 말이죠.
+
+6
+00:00:45,063 --> 00:00:48,630
+자연은 가장 강력한 제국조차 무너뜨리며...
+
+7
+00:00:51,317 --> 00:00:55,010
+그 분노 앞에서는 가장 위대한 위인조차
+
+8
+00:00:56,911 --> 00:00:59,572
+... 두려움에 떨기 마련입니다.
+
+9
+00:01:08,520 --> 00:01:12,638
+그럼에도 인간은 이 모든 역경을 극복하고...
+
+10
+00:01:15,416 --> 00:01:18,565
+지구와 공존하기 위한 길을 찾거나...
+
+11
+00:01:25,755 --> 00:01:28,126
+목적을 위해 변화시켰습니다.
+
+12
+00:01:33,053 --> 00:01:34,837
+먼 지평선을 넘어
+
+13
+00:01:40,983 --> 00:01:43,327
+새로운 길을 찾는 탐험은...
+
+14
+00:01:47,213 --> 00:01:49,197
+혁신을 불러올 수도..
+
+15
+00:01:55,630 --> 00:01:59,350
+그리고 의도치 않은 재앙을 불러올 수도 있습니다.
+
+16
+00:02:04,910 --> 00:02:12,039
+인류는 이제 오래전부터 이어진 문제에 대한 새로운 해결책을 찾아야 생존할 수 있습니다.
+
+17
+00:02:15,242 --> 00:02:19,338
+자신과 후대를 위해 안전한 미래를 보장하고...
+
+18
+00:02:22,663 --> 00:02:27,847
+목표를 위해 함께 국경을 초월하여 협력해야 합니다.
+
+19
+00:02:28,610 --> 00:02:32,904
+인간 문명의 새로운 시대를 맞이하려면 말이죠.
+
diff --git a/Subtitles/pl_PL/XP2Victory_Diplomatic.srt b/Subtitles/pl_PL/XP2Victory_Diplomatic.srt
new file mode 100644
index 0000000..f9d6d2a
--- /dev/null
+++ b/Subtitles/pl_PL/XP2Victory_Diplomatic.srt
@@ -0,0 +1,28 @@
+1
+00:00:01,610 --> 00:00:04,970
+Od najwcześniejszego pragnienia, by żyć w pokoju...
+
+2
+00:00:04,970 --> 00:00:08,210
+...po czasy, gdy sprzeciwiliście się agresji...
+
+3
+00:00:08,510 --> 00:00:11,410
+...zawsze dążyliście do współpracy.
+
+4
+00:00:11,910 --> 00:00:15,620
+Nie robiliście tego tylko po to, by zyskać większą chwałę...
+
+5
+00:00:15,710 --> 00:00:19,620
+...ale dlatego, że każde z nas ma prawo do godności.
+
+6
+00:00:20,700 --> 00:00:27,310
+Czyniąc to, udowodniliście, że wasze starożytne i niegasnące oddanie wspólnemu pokojowi...
+
+7
+00:00:27,410 --> 00:00:31,320
+...będzie fundamentem świata przyszłości.
+
diff --git a/Subtitles/pl_PL/XP2_Opening.srt b/Subtitles/pl_PL/XP2_Opening.srt
new file mode 100644
index 0000000..72834fa
--- /dev/null
+++ b/Subtitles/pl_PL/XP2_Opening.srt
@@ -0,0 +1,76 @@
+1
+00:00:05,400 --> 00:00:09,510
+Rozwój ludzkości nie zna granic.
+
+2
+00:00:11,288 --> 00:00:14,460
+Ale płacimy za to pewną cenę.
+
+3
+00:00:24,471 --> 00:00:27,863
+Choć żyjemy w okresie niebywałego dostatku...
+
+4
+00:00:28,314 --> 00:00:31,818
+...nie możemy zapominać o przeszłości...
+
+5
+00:00:34,710 --> 00:00:39,460
+...która uczy, że nie należy lekceważyć potęgi natury.
+
+6
+00:00:45,063 --> 00:00:48,840
+Natury niszczącej największe imperia...
+
+7
+00:00:51,317 --> 00:00:54,462
+...i przerażającej swą furią...
+
+8
+00:00:56,911 --> 00:00:59,848
+...największych spośród nas.
+
+9
+00:01:08,520 --> 00:01:13,423
+Jednak duch ludzkości jest nieugięty.
+
+10
+00:01:15,416 --> 00:01:18,748
+Potrafimy żyć z Ziemią w zgodzie...
+
+11
+00:01:25,755 --> 00:01:28,552
+...lub nagiąć ją do naszych celów.
+
+12
+00:01:33,053 --> 00:01:36,980
+Wyznaczamy nowy kurs
+
+13
+00:01:40,983 --> 00:01:42,982
+i odkrywamy ścieżki wiodące...
+
+14
+00:01:47,213 --> 00:01:49,414
+...zarówno ku innowacji...
+
+15
+00:01:55,630 --> 00:01:58,611
+...jak i niezamierzonej katastrofie.
+
+16
+00:02:04,910 --> 00:02:11,678
+Nasze przetrwanie wymaga nowych rozwiązań dawnych problemów...
+
+17
+00:02:14,853 --> 00:02:21,416
+...które zabezpieczą byt zarówno nasz, jak i przyszłych pokoleń...
+
+18
+00:02:22,663 --> 00:02:28,315
+Zjednoczeni wspólnym celem musimy zapomnieć o podziałach...
+
+19
+00:02:28,610 --> 00:02:35,819
+...i powitać świt nowej ery ludzkiej cywilizacji.
+
diff --git a/Subtitles/pt_BR/XP2Victory_Diplomatic.srt b/Subtitles/pt_BR/XP2Victory_Diplomatic.srt
new file mode 100644
index 0000000..51be64d
--- /dev/null
+++ b/Subtitles/pt_BR/XP2Victory_Diplomatic.srt
@@ -0,0 +1,28 @@
+1
+00:00:01,610 --> 00:00:04,970
+Desde o seu primeiro anseio pela paz…
+
+2
+00:00:04,970 --> 00:00:08,210
+… até as vezes que você precisou se defender…
+
+3
+00:00:08,510 --> 00:00:11,410
+… você sempre buscou a união.
+
+4
+00:00:11,910 --> 00:00:15,620
+Você não fez isso só para exaltar a sua própria glória…
+
+5
+00:00:15,710 --> 00:00:19,620
+Fez porque todos nós merecemos dignidade.
+
+6
+00:00:20,700 --> 00:00:27,310
+E fazendo isso, você provou que o seu antigo e eterno comprometimento com a paz…
+
+7
+00:00:27,410 --> 00:00:31,320
+… será o alicerce do mundo de amanhã.
+
diff --git a/Subtitles/pt_BR/XP2_Opening.srt b/Subtitles/pt_BR/XP2_Opening.srt
new file mode 100644
index 0000000..9747af0
--- /dev/null
+++ b/Subtitles/pt_BR/XP2_Opening.srt
@@ -0,0 +1,76 @@
+1
+00:00:05,400 --> 00:00:09,510
+O avanço humano não conhece limites.
+
+2
+00:00:11,288 --> 00:00:14,460
+Mas sempre há um preço a ser pago.
+
+3
+00:00:24,471 --> 00:00:27,863
+Mesmo estando no ápice da prosperidade,
+
+4
+00:00:28,314 --> 00:00:31,818
+basta olhar para o passado para nos lembra
+
+5
+00:00:34,710 --> 00:00:39,460
+que a força da natureza não deve ser ignorada.
+
+6
+00:00:45,063 --> 00:00:48,840
+Consumindo até mesmo os impérios mais poderosos
+
+7
+00:00:51,317 --> 00:00:54,462
+e fazendo os melhores dentre nós
+
+8
+00:00:56,911 --> 00:00:59,848
+tremerem com sua fúria.
+
+9
+00:01:08,520 --> 00:01:13,423
+Mas na adversidade o espírito humano prevalece
+
+10
+00:01:15,416 --> 00:01:18,748
+e encontra formas de coexistir com a Terra
+
+11
+00:01:25,755 --> 00:01:28,552
+ou de explorá-la a nosso favor.
+
+12
+00:01:33,053 --> 00:01:36,980
+Em busca de rotas além do horizonte,
+
+13
+00:01:40,983 --> 00:01:42,982
+revelando novos caminhos
+
+14
+00:01:47,213 --> 00:01:49,414
+que levam tanto à inovação
+
+15
+00:01:55,630 --> 00:01:58,611
+quanto à catástrofes imprevisíveis.
+
+16
+00:02:04,910 --> 00:02:11,678
+Nossa sobrevivência depende de novas soluções para velhos problemas.
+
+17
+00:02:14,853 --> 00:02:21,416
+Para garantir um futuro para nós e as nossas futuras gerações.
+
+18
+00:02:22,663 --> 00:02:28,315
+Unidos por um único propósito, devemos olhar além das fronteiras.
+
+19
+00:02:28,610 --> 00:02:35,819
+E saudar a alvorada de uma nova era da civilização humana.
+
diff --git a/Subtitles/ru_RU/XP2Victory_Diplomatic.srt b/Subtitles/ru_RU/XP2Victory_Diplomatic.srt
new file mode 100644
index 0000000..606fec2
--- /dev/null
+++ b/Subtitles/ru_RU/XP2Victory_Diplomatic.srt
@@ -0,0 +1,28 @@
+1
+00:00:01,610 --> 00:00:04,970
+И в мирные времена,
+
+2
+00:00:04,970 --> 00:00:08,210
+и на войне за правое дело –
+
+3
+00:00:08,510 --> 00:00:11,410
+ты всегда ищешь союзников.
+
+4
+00:00:11,910 --> 00:00:15,620
+Не для того лишь, чтобы ярче воссияла твоя слава...
+
+5
+00:00:15,710 --> 00:00:19,620
+Но потому, что веришь в достоинство других людей.
+
+6
+00:00:20,700 --> 00:00:27,310
+Твои деяния – свидетельство того, что вечное стремление ко всеобщему миру
+
+7
+00:00:27,410 --> 00:00:31,320
+станет фундаментом для будущего человечества.
+
diff --git a/Subtitles/ru_RU/XP2_Opening.srt b/Subtitles/ru_RU/XP2_Opening.srt
new file mode 100644
index 0000000..93ac4e1
--- /dev/null
+++ b/Subtitles/ru_RU/XP2_Opening.srt
@@ -0,0 +1,76 @@
+1
+00:00:05,400 --> 00:00:09,510
+Для человечества в мире нет преград.
+
+2
+00:00:11,288 --> 00:00:14,460
+Но за все в этой жизни нужно платить.
+
+3
+00:00:24,471 --> 00:00:27,863
+Сейчас мы наслаждаемся славой и процветанием...
+
+4
+00:00:28,314 --> 00:00:31,818
+Но стоит лишь обернуться назад – и мы увидим,
+
+5
+00:00:34,710 --> 00:00:39,460
+сколь безжалостна бывает слепая сила природы.
+
+6
+00:00:45,063 --> 00:00:48,840
+Она несет погибель могущественнейшим империям...
+
+7
+00:00:51,317 --> 00:00:54,462
+И даже величайшие из людей
+
+8
+00:00:56,911 --> 00:00:59,848
+содрогаются перед ее мощью.
+
+9
+00:01:08,520 --> 00:01:13,423
+Но невзгоды лишь закаляют характер человека.
+
+10
+00:01:15,416 --> 00:01:18,748
+Он либо учится мирно сосуществовать с Землей...
+
+11
+00:01:25,755 --> 00:01:28,552
+либо подчиняет ее своей воле.
+
+12
+00:01:33,053 --> 00:01:35,000
+Мы движемся вперед
+
+13
+00:01:40,550 --> 00:01:44,300
+и прокладываем новые пути,
+
+14
+00:01:47,213 --> 00:01:49,414
+которые ведут к открытиям...
+
+15
+00:01:55,630 --> 00:01:58,611
+и непредвиденным катастрофам.
+
+16
+00:02:04,910 --> 00:02:11,678
+Чтобы выжить, придется искать новые пути решения старых проблем.
+
+17
+00:02:14,853 --> 00:02:21,416
+Если мы хотим обеспечить счастливое будущее грядущим поколениям...
+
+18
+00:02:22,663 --> 00:02:28,315
+Мы должны найти союзников за горизонтом...
+
+19
+00:02:28,610 --> 00:02:35,819
+И достойно встретить зарю новой эры человечества.
+
diff --git a/Subtitles/zh_Hans_CN/XP2Victory_Diplomatic.srt b/Subtitles/zh_Hans_CN/XP2Victory_Diplomatic.srt
new file mode 100644
index 0000000..28b5abe
--- /dev/null
+++ b/Subtitles/zh_Hans_CN/XP2Victory_Diplomatic.srt
@@ -0,0 +1,28 @@
+1
+00:00:01,610 --> 00:00:04,970
+从起初追寻和平的意愿…
+
+2
+00:00:04,970 --> 00:00:08,210
+到奋起反抗侵略的时刻…
+
+3
+00:00:08,510 --> 00:00:11,410
+您总是在寻求合作。
+
+4
+00:00:11,910 --> 00:00:15,620
+您所做的并非仅为个人荣誉…
+
+5
+00:00:15,710 --> 00:00:19,620
+而因尊严皆为你我共享。
+
+6
+00:00:20,700 --> 00:00:27,310
+通过合作,您实现了自己亘古不变和平共处的承诺…
+
+7
+00:00:27,410 --> 00:00:31,320
+而这也将成为未来世界的基石。
+
diff --git a/Subtitles/zh_Hans_CN/XP2_Opening.srt b/Subtitles/zh_Hans_CN/XP2_Opening.srt
new file mode 100644
index 0000000..af79c60
--- /dev/null
+++ b/Subtitles/zh_Hans_CN/XP2_Opening.srt
@@ -0,0 +1,76 @@
+1
+00:00:05,926 --> 00:00:08,228
+人类的进步并无边界。
+
+2
+00:00:11,172 --> 00:00:13,852
+但进步亦非毫无代价。
+
+3
+00:00:24,761 --> 00:00:27,536
+我们虽站在繁荣富强之巅…
+
+4
+00:00:28,442 --> 00:00:30,914
+但回首过去便能忆起…
+
+5
+00:00:35,576 --> 00:00:38,501
+自然之力绝非你我所能忽视。
+
+6
+00:00:45,409 --> 00:00:47,768
+它能吞噬伟大的帝国…
+
+7
+00:00:52,146 --> 00:00:54,222
+亦能让英明神武之人
+
+8
+00:00:57,657 --> 00:00:59,601
+在盛怒下颤抖。
+
+9
+00:01:09,340 --> 00:01:12,850
+然而人类之精神却能力挺难关…
+
+10
+00:01:15,681 --> 00:01:18,215
+找到与地球共存的方法…
+
+11
+00:01:25,879 --> 00:01:27,792
+或使其为我所用。
+
+12
+00:01:33,501 --> 00:01:36,067
+追寻遥远天地之外的航向,
+
+13
+00:01:41,116 --> 00:01:42,288
+将引领我们…
+
+14
+00:01:47,427 --> 00:01:49,319
+走向那创新之路…
+
+15
+00:01:55,871 --> 00:01:57,840
+与意想不到的灾难。
+
+16
+00:02:05,007 --> 00:02:09,862
+在生存课题上,我们需要为旧麻烦找到新答案。
+
+17
+00:02:15,679 --> 00:02:20,433
+才能为自己和子孙后代开创美好未来…
+
+18
+00:02:22,763 --> 00:02:27,141
+众志成城,我们必须放下彼此成见。
+
+19
+00:02:28,832 --> 00:02:35,063
+同时迎接人类文明新篇章的破晓曙光。
+
diff --git a/Subtitles/zh_Hant_HK/XP2Victory_Diplomatic.srt b/Subtitles/zh_Hant_HK/XP2Victory_Diplomatic.srt
new file mode 100644
index 0000000..dfcc122
--- /dev/null
+++ b/Subtitles/zh_Hant_HK/XP2Victory_Diplomatic.srt
@@ -0,0 +1,28 @@
+1
+00:00:01,610 --> 00:00:04,970
+從你意欲追尋和平開始…
+
+2
+00:00:04,970 --> 00:00:08,210
+到你起身對抗狼子野心…
+
+3
+00:00:08,510 --> 00:00:11,410
+你總是尋求攜手合作。
+
+4
+00:00:11,910 --> 00:00:15,620
+你做這些不僅是為自己的榮耀…
+
+5
+00:00:15,710 --> 00:00:19,620
+也是因為你相信我們皆有尊嚴。
+
+6
+00:00:20,700 --> 00:00:27,310
+也因此,你證明了自己由古至今對和平共處的不懈努力…
+
+7
+00:00:27,410 --> 00:00:31,320
+而這將為明日的世界奠定基礎。
+
diff --git a/Subtitles/zh_Hant_HK/XP2_Opening.srt b/Subtitles/zh_Hant_HK/XP2_Opening.srt
new file mode 100644
index 0000000..e731171
--- /dev/null
+++ b/Subtitles/zh_Hant_HK/XP2_Opening.srt
@@ -0,0 +1,76 @@
+1
+00:00:06,380 --> 00:00:08,320
+人類的進步無疆無域。
+
+2
+00:00:11,880 --> 00:00:13,840
+但不代表進步沒有代價。
+
+3
+00:00:24,680 --> 00:00:26,840
+儘管我們站在繁榮的巔峰,
+
+4
+00:00:26,840 --> 00:00:29,340
+只要以史為鏡我們便能銘記…
+
+5
+00:00:35,870 --> 00:00:38,230
+永遠不能忽略大自然的力量。
+
+6
+00:00:45,650 --> 00:00:47,920
+它能吞噬最為強大的帝國…
+
+7
+00:00:52,680 --> 00:00:54,080
+讓偉人中的偉人
+
+8
+00:00:57,990 --> 00:00:59,820
+也拜倒於其怒火之下。
+
+9
+00:01:09,630 --> 00:01:13,130
+但面對逆境,人類精神仍不磨滅…
+
+10
+00:01:15,930 --> 00:01:18,290
+尋找著與地球共處的方式…
+
+11
+00:01:26,080 --> 00:01:27,880
+或者將其為我所用。
+
+12
+00:01:33,610 --> 00:01:36,340
+追尋著比地平線更遠的彼岸景色,
+
+13
+00:01:41,280 --> 00:01:42,540
+開創道路…
+
+14
+00:01:47,790 --> 00:01:49,480
+前方不只有創新…
+
+15
+00:01:56,140 --> 00:01:57,780
+還有不可預料的災難。
+
+16
+00:02:05,380 --> 00:02:09,600
+為了生存,我們必須為老問題找到新解方。
+
+17
+00:02:15,870 --> 00:02:20,150
+才能確保我們和子孫後代有個美好將來…
+
+18
+00:02:22,980 --> 00:02:27,000
+有志一同的我們必須放下門戶之見。
+
+19
+00:02:29,680 --> 00:02:32,750
+同時迎接人類文明新時代的光明開端。
+
diff --git a/WorldView/CityBannerInstances.xml b/WorldView/CityBannerInstances.xml
index 65a6bb2..f50f997 100644
--- a/WorldView/CityBannerInstances.xml
+++ b/WorldView/CityBannerInstances.xml
@@ -48,7 +48,7 @@
-
+
@@ -74,7 +74,9 @@
-
+
@@ -137,15 +139,15 @@
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
@@ -222,17 +224,8 @@
-
-
-
-
-
-
-
-
-
-
+
@@ -241,6 +234,14 @@
+
+
+
+
+
+
+
+
@@ -260,5 +261,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/WorldView/CityBannerManager.lua b/WorldView/CityBannerManager.lua
index aff1bae..1deeaf2 100644
--- a/WorldView/CityBannerManager.lua
+++ b/WorldView/CityBannerManager.lua
@@ -7,9 +7,23 @@ include( "InstanceManager" );
include( "SupportFunctions" );
include( "LoyaltySupport" );
include( "Civ6Common" );
+include( "Colors" );
include( "LuaClass" );
include( "CitySupport" );
+-- ===========================================================================
+-- GLOBALS
+-- ===========================================================================
+CityBanner = {};
+
+BANNERTYPE_CITY_CENTER = 0;
+BANNERTYPE_ENCAMPMENT = 1;
+BANNERTYPE_AERODROME = 2;
+BANNERTYPE_MISSILE_SILO = 3;
+BANNERTYPE_OTHER_DISTRICT = 4;
+BANNERTYPE_MOUNTAIN_TUNNEL = 5;
+BANNERTYPE_QHAPAQ_NAN = 6;
+
-- ===========================================================================
-- CONSTANTS
-- ===========================================================================
@@ -68,12 +82,6 @@ local ZOFFSET_3DVIEW :number = 36;
local SIZEOFPOPANDPROD :number = 80; --The amount to add to the city banner to account for the size of the production icon and population number
local SIZEOFPOPANDPRODMETERS :number = 15; --The amount to add to the city banner backing width to allow for the production and population meters to appear
-local BANNERTYPE_CITY_CENTER :number = 0;
-local BANNERTYPE_ENCAMPMENT :number = 1;
-local BANNERTYPE_AERODROME :number = 2;
-local BANNERTYPE_MISSILE_SILO :number = 3;
-local BANNERTYPE_OTHER_DISTRICT :number = 4;
-
local BANNERSTYLE_LOCAL_TEAM :number = 0;
local BANNERSTYLE_OTHER_TEAM :number = 1;
@@ -89,7 +97,6 @@ local m_refreshLocalPlayerProduction:boolean = false;
-- ===========================================================================
-- MEMBERS
-- ===========================================================================
-CityBanner = {};
local CityBannerInstances :table = {};
local MiniBannerInstances :table = {};
@@ -98,6 +105,8 @@ local m_AerodromeBannerIM :table = InstanceManager:new( "AerodromeBanner", "Anch
local m_WMDBannerIM :table = InstanceManager:new( "WMDBanner", "Anchor", Controls.CityBanners );
local m_EncampmentBannerIM :table = InstanceManager:new( "EncampmentBanner", "Anchor", Controls.CityBanners );
local m_DistrictBannerIM :table = InstanceManager:new( "DistrictBanner", "Anchor", Controls.CityBanners );
+local m_TunnelBannerIM :table = InstanceManager:new( "TunnelBanner", "Anchor", Controls.CityBanners );
+local m_QhapaqNanBannerIM :table = InstanceManager:new( "QhapaqNanBanner", "Anchor", Controls.CityBanners );
local m_HolySiteIconsIM :table = InstanceManager:new( "HolySiteIcon", "Anchor", Controls.CityDistrictIcons );
local m_HexColoringReligion : number = UILens.CreateLensLayerHash("Hex_Coloring_Religion");
@@ -106,7 +115,6 @@ local m_CulturalIdentityLens : number = UILens.CreateLensLayerHash("Cultural_Ide
local m_CityDetailsLens : number = UILens.CreateLensLayerHash("City_Details");
local m_EmpireDetailsLens : number = UILens.CreateLensLayerHash("Empire_Details");
-
-- ===========================================================================
-- FUNCTIONS
-- ===========================================================================
@@ -232,7 +240,7 @@ function CityBanner:Initialize( playerID: number, cityID : number, districtID :
self.m_DetailStatusIM = InstanceManager:new( "CityDetailStatus", "Icon", self.m_Instance.CityDetailsStatus );
end
if self.m_DetailEffectsIM == nil then
- self.m_DetailEffectsIM = InstanceManager:new( "CityDetailEffect", "Icon", self.m_Instance.CityDetailsEffects );
+ self.m_DetailEffectsIM = InstanceManager:new( "CityDetailEffect", "Button", self.m_Instance.CityDetailsEffects );
end
if self.m_InfoIconIM == nil then
self.m_InfoIconIM = InstanceManager:new( "CityInfoType", "Button", self.m_Instance.CityInfoStack );
@@ -298,6 +306,10 @@ function CityBanner:Initialize( playerID: number, cityID : number, districtID :
elseif (bannerType == BANNERTYPE_OTHER_DISTRICT) then
self:CreateDistrictBanner();
self:UpdateDistrictBanner();
+ elseif (bannerType == BANNERTYPE_MOUNTAIN_TUNNEL) then
+ self:CreateTunnelBanner();
+ elseif (bannerType == BANNERTYPE_QHAPAQ_NAN) then
+ self:CreateQhapaqNanBanner();
end
self:UpdateName();
@@ -622,6 +634,30 @@ function CityBanner:UpdateDistrictBanner()
end
end
+-- ===========================================================================
+function CityBanner:CreateTunnelBanner()
+ -- Set the appropriate instance factory (mini banner one) for this flag...
+ self.m_InstanceManager = m_TunnelBannerIM;
+ self.m_Instance = self.m_InstanceManager:GetInstance();
+
+ self.m_IsImprovementBanner = true;
+
+ -- it's an banner not associated with a district, so the districtID should be a plot index
+ self.m_PlotX, self.m_PlotY = Map.GetPlotLocation(self.m_DistrictID);
+end
+
+-- ===========================================================================
+function CityBanner:CreateQhapaqNanBanner()
+ -- Set the appropriate instance factory (mini banner one) for this flag...
+ self.m_InstanceManager = m_QhapaqNanBannerIM;
+ self.m_Instance = self.m_InstanceManager:GetInstance();
+
+ self.m_IsImprovementBanner = true;
+
+ -- it's an banner not associated with a district, so the districtID should be a plot index
+ self.m_PlotX, self.m_PlotY = Map.GetPlotLocation(self.m_DistrictID);
+end
+
-- ===========================================================================
function CityBanner:CreateEncampmentBanner()
-- Set the appropriate instance factory (mini banner one) for this flag...
@@ -782,6 +818,14 @@ function CityBanner:UpdateColor()
if self.m_Instance.Banner_Base ~= nil then
self.m_Instance.Banner_Base:SetColor( backColor );
end
+ elseif (self.m_Type == BANNERTYPE_MOUNTAIN_TUNNEL) then
+ if self.m_Instance.Banner_Base ~= nil then
+ self.m_Instance.Banner_Base:SetColor( backColor );
+ end
+ elseif (self.m_Type == BANNERTYPE_QHAPAQ_NAN) then
+ if self.m_Instance.Banner_Base ~= nil then
+ self.m_Instance.Banner_Base:SetColor( backColor );
+ end
else
self.m_Instance.MiniBannerBackground:SetColor( backColor );
end
@@ -820,9 +864,13 @@ function CityBanner:UpdateProduction(pCity:table)
self.m_StatProductionIM:ResetInstances();
local productionInstance:table = self.m_StatProductionIM:GetInstance();
- productionInstance.Button:RegisterCallback( Mouse.eLClick, OnProductionClick );
- productionInstance.Button:SetVoid1(pCity:GetOwner());
- productionInstance.Button:SetVoid2(pCity:GetID());
+ if pCity:GetOwner() == Game.GetLocalPlayer() then
+ productionInstance.Button:RegisterCallback( Mouse.eLClick, OnProductionClick );
+ productionInstance.Button:SetVoid1(pCity:GetOwner());
+ productionInstance.Button:SetVoid2(pCity:GetID());
+ else
+ productionInstance.Button:ClearCallback( Mouse.eLClick );
+ end
local pBuildQueue :table = pCity:GetBuildQueue();
if (pBuildQueue ~= nil) then
@@ -1008,7 +1056,15 @@ function OnGovernorIconClicked(playerID: number, cityID: number)
else
OnCityBannerLookAt(playerID, cityID);
end
- LuaEvents.GovernorPanel_Toggle(playerID, cityID);
+ LuaEvents.GovernorPanel_Toggle();
+end
+
+-- ===========================================================================
+function OnPowerIconClicked( playerID:number, cityID:number )
+ if (playerID == Game.GetLocalPlayer()) then
+ OnCityBannerClick(playerID, cityID);
+ LuaEvents.CityPanel_ToggleOverviewPower();
+ end
end
-- ===========================================================================
@@ -1182,6 +1238,13 @@ function CityBanner:UpdateStats()
else
self:UpdatePopulation(false, pCity, pCityGrowth);
self:UpdateGovernor(pCity);
+
+ -- Espionage View should show a cities production if they have the proper diplo visibility
+ if HasEspionageView(iCityOwner, pCity:GetID()) then
+ self:UpdateProduction(pCity);
+ elseif self.m_StatProductionIM ~= nil then
+ self.m_StatProductionIM:ResetInstances();
+ end
end
--- DEFENSE INFO ---
@@ -1257,10 +1320,15 @@ function CityBanner:UpdateStats()
end
-- ===========================================================================
-function SetDetailIcon(instance:table, icon:string, tooltip:string)
+function SetDetailIcon( instance:table, icon:string, tooltip:string )
instance.Icon:SetHide(icon == nil);
if icon then instance.Icon:SetIcon(icon); end
instance.Icon:SetToolTipString(tooltip and tooltip or "");
+
+ -- If we have a button clear the callback incase we were previously doing something else
+ if instance.Button ~= nil then
+ instance.Button:ClearCallback( Mouse.eLClick );
+ end
end
-- ===========================================================================
@@ -1334,6 +1402,27 @@ function CityBanner:UpdateDetails()
end
end
+ local pCityPower:table = pCity:GetPower();
+ local freePower = pCityPower:GetFreePower();
+ local temporaryPower = pCityPower:GetTemporaryPower();
+ local requiredPower = pCityPower:GetRequiredPower();
+ local powerTooltip = "";
+ local powerIconKey = "PowerInsufficient";
+ if (pCityPower:IsFullyPowered()) then
+ powerIconKey = "Power";
+ powerTooltip = Locale.Lookup("LOC_CITY_BANNER_POWERED_CITY", requiredPower, freePower, temporaryPower);
+ if (pCityPower:IsFullyPoweredByActiveProject()) then
+ powerTooltip = powerTooltip .. "[NEWLINE]" .. Locale.Lookup("LOC_CITY_BANNER_POWERED_CITY_FROM_ACTIVE_PROJECT");
+ end
+ else
+ powerTooltip = Locale.Lookup("LOC_CITY_BANNER_UNPOWERED_CITY", requiredPower, freePower, temporaryPower);
+ end
+ if (freePower > 0 or temporaryPower > 0 or requiredPower > 0) then
+ local kPowerDetailEffectInst:table = self.m_DetailEffectsIM:GetInstance();
+ SetDetailIcon(kPowerDetailEffectInst, powerIconKey, powerTooltip);
+ kPowerDetailEffectInst.Button:RegisterCallback( Mouse.eLClick, function() OnPowerIconClicked(cityOwner, pCity:GetID()); end );
+ end
+
self.m_Instance.CityDetailsEffects:CalculateSize();
end
@@ -1544,7 +1633,54 @@ function OnCapitalIconClicked( playerID:number, cityID:number )
LuaEvents.CityBannerManager_CityPanelOverview();
else
OnCityBannerLookAt(playerID, cityID);
+ if HasEspionageView(playerID, cityID) then
+ UI.DeselectAll();
+ LuaEvents.CityBannerManager_ShowEnemyCityOverview(playerID, cityID);
+ end
+ end
+end
+
+-- ===========================================================================
+function HasEspionageView( ownerID:number, cityID:number )
+ local localPlayerID:number = Game.GetLocalPlayer();
+ if localPlayerID == -1 then
+ return;
+ end
+
+ -- Determine if the local player has any appropriate diplo visibilty to view this city
+ local eVisibility:number = -1;
+ local canViewCapital:boolean = false;
+ local pLocalPlayer:table = Players[localPlayerID];
+ if pLocalPlayer then
+ local pLocalPlayerDiplo:table = pLocalPlayer:GetDiplomacy();
+ if pLocalPlayerDiplo then
+ eVisibility = pLocalPlayerDiplo:GetVisibilityOn(ownerID);
+ local kVisDef:table = GameInfo.Visibilities_XP2[eVisibility];
+ if kVisDef.EspionageViewAll == true then
+ -- We can view all of this players cities
+ return true;
+ end
+
+ if kVisDef.EspionageViewCapital == true then
+ canViewCapital = true;
+ end
+ end
end
+
+ -- Check if this city is the capital if we can view the players capital
+ if canViewCapital then
+ local pOwner:table = Players[ownerID];
+ if pOwner then
+ local pCity:table = pOwner:GetCities():FindID(cityID);
+ if pCity then
+ if pCity:IsCapital() then
+ return true;
+ end
+ end
+ end
+ end
+
+ return false;
end
-- ===========================================================================
@@ -1585,9 +1721,7 @@ function CityBanner:UpdateInfo( pCity : table )
-- CAPITAL ICON
if pPlayer then
local instance:table = self.m_InfoIconIM:GetInstance();
- instance.Button:RegisterCallback(Mouse.eLClick, OnCapitalIconClicked);
- instance.Button:SetVoid1(playerID);
- instance.Button:SetVoid2(cityID);
+ local tooltip:string = "";
if pPlayer:IsMajor() then
if pCity:IsOriginalCapital() and pCity:GetOriginalOwner() == pCity:GetOwner() then
@@ -1598,24 +1732,38 @@ function CityBanner:UpdateInfo( pCity : table )
-- Former original capital
instance.Icon:SetIcon("ICON_FORMER_CAPITAL");
end
- instance.Button:SetToolTipString(Locale.Lookup("LOC_CITY_BANNER_ORIGINAL_CAPITAL_TT", pPlayerConfig:GetCivilizationShortDescription()));
+ tooltip = tooltip .. Locale.Lookup("LOC_CITY_BANNER_ORIGINAL_CAPITAL_TT", pPlayerConfig:GetCivilizationShortDescription());
elseif pCity:IsCapital() then
-- New capital
instance.Icon:SetIcon("ICON_NEW_CAPITAL");
- instance.Button:SetToolTipString(Locale.Lookup("LOC_CITY_BANNER_NEW_CAPITAL_TT", pPlayerConfig:GetCivilizationShortDescription()));
+ tooltip = tooltip .. Locale.Lookup("LOC_CITY_BANNER_NEW_CAPITAL_TT", pPlayerConfig:GetCivilizationShortDescription());
else
-- Other cities
instance.Icon:SetIcon("ICON_OTHER_CITIES");
- instance.Button:SetToolTipString(Locale.Lookup("LOC_CITY_BANNER_OTHER_CITY_TT", pPlayerConfig:GetCivilizationShortDescription()));
+ tooltip = tooltip .. Locale.Lookup("LOC_CITY_BANNER_OTHER_CITY_TT", pPlayerConfig:GetCivilizationShortDescription());
end
+
+ if GameCapabilities.HasCapability("CAPABILITY_ESPIONAGE") then
+ if Game.GetLocalPlayer() == playerID or HasEspionageView(playerID, cityID) then
+ tooltip = tooltip .. Locale.Lookup("LOC_ESPIONAGE_VIEW_ENABLED_TT");
+ else
+ tooltip = tooltip .. Locale.Lookup("LOC_ESPIONAGE_VIEW_DISABLED_TT");
+ end
+ end
+
elseif pPlayer:IsFreeCities() then
instance.Icon:SetIcon("ICON_CIVILIZATION_FREE_CITIES");
- instance.Button:SetToolTipString(Locale.Lookup("LOC_CITY_BANNER_FREE_CITY_TT"));
+ tooltip = tooltip .. Locale.Lookup("LOC_CITY_BANNER_FREE_CITY_TT");
else
instance.Icon:SetIcon("ICON_CITY_STATE");
- instance.Button:SetToolTipString(Locale.Lookup("LOC_CITY_BANNER_CITY_STATE_TT"));
+ tooltip = tooltip .. Locale.Lookup("LOC_CITY_BANNER_CITY_STATE_TT");
end
+ instance.Button:RegisterCallback(Mouse.eLClick, OnCapitalIconClicked);
+ instance.Button:SetVoid1(playerID);
+ instance.Button:SetVoid2(cityID);
+ instance.Button:SetToolTipString(tooltip);
+
-- ORIGINAL OWNER CAPITAL ICON
if pCity:GetOwner() ~= pCity:GetOriginalOwner() and pCity:IsOriginalCapital() then
local pOriginalOwner:table = Players[pCity:GetOriginalOwner()];
@@ -1762,7 +1910,7 @@ function CityBanner:UpdateReligion()
numOfActiveReligions = numOfActiveReligions + 1;
end
end
-
+
-- Sort religions by largest number of followers
table.sort(activeReligions, function(a,b) return a.Followers > b.Followers; end);
@@ -2360,10 +2508,10 @@ function OnICBMStrikeButtonClick( iPlotID, eWMD )
if (pPlot ~= nil) then
local pCity = Cities.GetPlotPurchaseCity(pPlot);
if (pCity ~= nil) then
- -- force recalculation of reachable area if we're already in strike mode
- if UI.GetInterfaceMode() == InterfaceModeTypes.ICBM_STRIKE then
- UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
- end
+ -- force recalculation of reachable area if we're already in strike mode
+ if UI.GetInterfaceMode() == InterfaceModeTypes.ICBM_STRIKE then
+ UI.SetInterfaceMode(InterfaceModeTypes.SELECTION);
+ end
UI.SelectCity(pCity);
UILens.SetActive("Default");
local tParameters = {};
@@ -2487,8 +2635,7 @@ function OnImprovementAddedToMap(locX, locY, eImprovementType, eOwner)
return;
end
- -- Right now we're only interested in the Airstrip improvement
- if ( improvementData.AirSlots == 0 and improvementData.WeaponSlots == 0) then
+ if ( improvementData.AirSlots == 0 and improvementData.WeaponSlots == 0 and improvementData.ImprovementType ~= "IMPROVEMENT_MOUNTAIN_TUNNEL" and improvementData.ImprovementType ~= "IMPROVEMENT_MOUNTAIN_ROAD" ) then
return;
end
@@ -2507,6 +2654,10 @@ function OnImprovementAddedToMap(locX, locY, eImprovementType, eOwner)
local cityID = ownerCity:GetID();
-- we're passing the plotID as the districtID argument because we need the location of the improvement
AddMiniBannerToMap( eOwner, cityID, plotID, BANNERTYPE_MISSILE_SILO );
+ elseif ( improvementData.ImprovementType == "IMPROVEMENT_MOUNTAIN_TUNNEL" ) then
+ AddMiniBannerToMap( eOwner, -1, plotID, BANNERTYPE_MOUNTAIN_TUNNEL );
+ elseif ( improvementData.ImprovementType == "IMPROVEMENT_MOUNTAIN_ROAD" ) then
+ AddMiniBannerToMap( eOwner, -1, plotID, BANNERTYPE_QHAPAQ_NAN);
end
else
miniBanner:UpdateStats();
@@ -2584,8 +2735,9 @@ function OnImprovementVisibilityChanged( locX :number, locY :number, eImprovemen
if ( eImprovementType == -1 ) then
return;
end
+ local data:table = GameInfo.Improvements[eImprovementType];
-- We're only interested in the Airstrip or Missile Silo improvements
- if ( GameInfo.Improvements[eImprovementType].AirSlots > 0 or GameInfo.Improvements[eImprovementType].WeaponSlots > 0) then
+ if (data.ImprovementType == "IMPROVEMENT_MOUNTAIN_TUNNEL" or data.ImprovementType == "IMPROVEMENT_MOUNTAIN_ROAD" or data.AirSlots > 0 or data.WeaponSlots > 0) then
local plotID = Map.GetPlotIndex(locX, locY);
if (plotID > 0) then
local plot = Map.GetPlotByIndex(plotID);
@@ -2599,8 +2751,6 @@ function OnImprovementVisibilityChanged( locX :number, locY :number, eImprovemen
end
end
end
- else
- return;
end
end
@@ -3322,6 +3472,8 @@ function RealizeReligion()
end
end
end
+
+ local bReligionsVisible = UILens.IsLayerOn( m_HexColoringReligion );
end
-- ===========================================================================
@@ -3520,13 +3672,9 @@ end
-- ===========================================================================
function OnGovernorEjected( cityOwner: number, cityID: number, playerID: number, governorID: number )
local cityBanner:table = GetCityBanner(cityOwner, cityID);
- for _, playerBannerInstances in pairs(CityBannerInstances) do
- for id, banner in pairs(playerBannerInstances) do
- if (banner ~= nil and banner:IsVisible()) then
- banner:UpdateStats();
- banner:UpdateLoyalty();
- end
- end
+ if (cityBanner ~= nil) then
+ cityBanner:UpdateStats();
+ cityBanner:UpdateLoyalty();
end
end
@@ -3545,7 +3693,7 @@ function Initialize()
Events.CityDefenseStatusChanged.Add( OnCityDefenseStatusChanged );
Events.CityFocusChanged.Add( OnCityFocusChange );
Events.CityNameChanged.Add( OnCityNameChange );
- Events.CityProductionQueueChanged.Add( OnCityProductionChanged);
+ Events.CityProductionQueueChanged.Add(OnCityProductionChanged);
Events.CityProductionUpdated.Add( OnCityProductionUpdate);
Events.CityProductionCompleted.Add( OnCityProductionCompleted);
Events.CityReligionChanged.Add( OnCityReligionChanged );
diff --git a/WorldView/CityBannerManager.xml b/WorldView/CityBannerManager.xml
index 8cea5cd..f84b840 100644
--- a/WorldView/CityBannerManager.xml
+++ b/WorldView/CityBannerManager.xml
@@ -7,5 +7,5 @@
-
+
\ No newline at end of file