I'm trying to use Firaxis Live Tuner (FLT) to access and process game information and then highlight "interesting" plots. I'm stumped and need help.
I've created an FLT panel (code below) in which I define "InGame" and "_TunerResourcePanel" as "CompatitableStates" and identify "_TunerResourcePanel" as a "LoadState". (code below)
The code almost works. When opened in FLT, the code creates a panel with two items in, what I call, the "CompatibleStates" selection box (the box next to the "New Control" selection box at the top of the FLT tab created for the panel). When I select "_TunerResourcePanel" the panel is initialized and works as expected - except the "Highlight Resource Plots" action creates an error (i.e., turns red). Apparently "UI.HighlightPlots" is not accessible to the panel in the _TunerResourcePanel "context". When I select "InGame" in the "CompatibleStates" selection box, the panel is not initialized and, as a result, does not access and process game information as desired. However, the Highlight Resource Plots action can highlight "interesting" plots. Apparently it has access to "UI.HighlightPlots". Indeed, the hard-coded plot indexes are highlighted on the game map when the action is taken in InGame "context". So, it appears that the FLT code can access and process game information and highlight "interesting" plots. However it can't do both in the same "context".
How can I make UI.HighlightPlots and my lua "LoadState" code accessible at the same time in the FLT panel?
ltp code:
_TunerResourcePanel code:
I've created an FLT panel (code below) in which I define "InGame" and "_TunerResourcePanel" as "CompatitableStates" and identify "_TunerResourcePanel" as a "LoadState". (code below)
The code almost works. When opened in FLT, the code creates a panel with two items in, what I call, the "CompatibleStates" selection box (the box next to the "New Control" selection box at the top of the FLT tab created for the panel). When I select "_TunerResourcePanel" the panel is initialized and works as expected - except the "Highlight Resource Plots" action creates an error (i.e., turns red). Apparently "UI.HighlightPlots" is not accessible to the panel in the _TunerResourcePanel "context". When I select "InGame" in the "CompatibleStates" selection box, the panel is not initialized and, as a result, does not access and process game information as desired. However, the Highlight Resource Plots action can highlight "interesting" plots. Apparently it has access to "UI.HighlightPlots". Indeed, the hard-coded plot indexes are highlighted on the game map when the action is taken in InGame "context". So, it appears that the FLT code can access and process game information and highlight "interesting" plots. However it can't do both in the same "context".
How can I make UI.HighlightPlots and my lua "LoadState" code accessible at the same time in the FLT panel?
ltp code:
Code:
<?xml version="1.0"?>
<PanelData xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Name>Resource Locator</Name>
<App>Civ6</App>
<EnterAction>
</EnterAction>
<ExitAction />
<CompatibleStates>
<string>InGame</string>
<string>_TunerResourcePanel</string>
</CompatibleStates>
<LoadStates>
<string>_TunerResourcePanel</string>
</LoadStates>
<Actions>
<ActionData><Name>Add Resource</Name>
<Location>
<X>200</X>
<Y>30</Y>
</Location>
<Action>
if efn_SelectedResource then
table.insert(efn_ResourcesToLocateList, efn_SelectedResource)
end
</Action>
</ActionData>
<ActionData><Name>Remove Resource</Name>
<Location>
<X>200</X>
<Y>60</Y>
</Location>
<Action>
if efn_SelectedResourceToLocateIndex then
table.remove(efn_ResourcesToLocateList, efn_SelectedResourceToLocateIndex)
end
</Action>
</ActionData>
<ActionData><Name>Remove All</Name>
<Location>
<X>200</X>
<Y>90</Y>
</Location>
<Action>
efn_ResourcesToLocateList = {}
</Action>
</ActionData>
<ActionData><Name>Highlight Resource Plots</Name>
<Location>
<X>325</X>
<Y>300</Y>
</Location>
<Action>
print("Highlight Resource Plots")
local plotsToHighlight = {}
UI.HighlightPlots(PlotHighlightTypes.PLACEMENT, false)
if efn_ResourcePinData and (#efn_ResourcePinData > 0) then
print("Highlight Resource Plots. Count: " .. #efn_ResourcePinData)
local idxPin, pinData
for idxPin, pinData in ipairs(efn_ResourcePinData) do
table.insert(plotsToHighlight, pinData.PlotIndex)
end
print(plotsToHighlight)
UI.HighlightPlots(PlotHighlightTypes.PLACEMENT, true, plotsToHighlight)
else
plotsToHighlight = {1744, 1821}
print("Highlight Resource Plots. Hardcoded at ", plotsToHighlight)
UI.HighlightPlots(PlotHighlightTypes.PLACEMENT, true, plotsToHighlight)
end
</Action>
</ActionData>
</Actions>
<StringControls />
<IntegerControls />
<FloatControls />
<BooleanControls>
<BooleanControlData><Name>Show Only Revealed Resources</Name>
<Location>
<X>325</X>
<Y>220</Y>
</Location>
<GetFunction>function()
return efn_OnlyRevealedResources
end
</GetFunction>
<SetFunction>function(value)
efn_OnlyRevealedResources = value
end
</SetFunction>
</BooleanControlData>
<BooleanControlData><Name>Show Only Revealed Plots</Name>
<Location>
<X>325</X>
<Y>260</Y>
</Location>
<GetFunction>function()
return efn_OnlyRevealedPlots
end
</GetFunction>
<SetFunction>function(value)
efn_OnlyRevealedPlots = value
end
</SetFunction>
</BooleanControlData> </BooleanControls>
<TableViews />
<DataViews />
<StatTrackers />
<SelectionLists>
<SelectionListData><Name>Resources:150</Name>
<Location>
<X>10</X>
<Y>30</Y>
</Location>
<Size>
<Width>175</Width>
<Height>350</Height>
</Size>
<PopulateList>function()
return efn_ResourceNames
end
</PopulateList>
<OnSelection>function(selection)
efn_SelectedResource = selection
end
</OnSelection>
<Sorted>true</Sorted>
</SelectionListData>
<SelectionListData><Name>ID:25;Resources To Locate:150</Name>
<Location>
<X>325</X>
<Y>30</Y>
</Location>
<Size>
<Width>175</Width>
<Height>175</Height>
</Size>
<PopulateList>function()
local itemList = {}
if efn_ResourcesToLocateList ~= nil then
local idxLoc, resName
for idxLoc, resName in ipairs(efn_ResourcesToLocateList) do
itemList[idxLoc] = idxLoc .. ";" .. resName
end
end
return itemList
end
</PopulateList>
<OnSelection>function(selection)
efn_SelectedResourceToLocateIndex = tonumber(selection)
end
</OnSelection>
<Sorted>true</Sorted>
</SelectionListData>
<SelectionListData><Name>ID:25;Resource:150;MapId:50;X:25;Y:25;Rev:25</Name>
<Location>
<X>545</X>
<Y>30</Y>
</Location>
<Size>
<Width>325</Width>
<Height>350</Height>
</Size>
<PopulateList>function()
local idxPin, pinData
efn_ResourcePinData = {}
local resourcePinList = {}
if efn_ResourcesToLocateList then
local resourceIndexesToLocate = {}
local idxPlayer, Player, playerVis
local idxLoc, resName, idxRes
idxPlayer = Game.GetLocalPlayer()
playerVis = PlayersVisibility[idxPlayer]
player = Players[idxPlayer]
-- add efn_ResourcesToLocateList items to resourceIndexesToLocate consistent with efn_OnlyRevealedResources
for idxLoc, resName in ipairs(efn_ResourcesToLocateList) do
if (not efn_OnlyRevealedResources) or efn_IsResourceRevealed(resName, player) then
resourceIndexesToLocate[resName] = efn_ResourceDataByName[resName].Index
end
end
-- create a table of pin location data for plots containing resourcesToLocate consistent with efn_OnlyRevealedPlots.
local idxPlot, plotRevealed, plot, resType
idxPin = 0
for idxPlot = 0, Map.GetPlotCount() - 1 do
plotRevealed = "no"; if playerVis:IsRevealed(idxPlot) then plotRevealed = "yes" end
if (not efn_OnlyRevealedPlots) or (plotRevealed == "yes") then
plot = Map.GetPlotByIndex(idxPlot)
resType = plot:GetResourceType()
for resName, idxRes in pairs(resourceIndexesToLocate) do
if resType == idxRes then
idxPin = idxPin + 1
efn_ResourcePinData[idxPin] = {Name = resName, PlotIndex = idxPlot, PlotX = plot:GetX(), PlotY = plot:GetY()}
resourcePinList[idxPin] = idxPin .. ";" .. resName .. ";" .. idxPlot .. ";" .. plot:GetX() .. ";" .. plot:GetY() .. ";" .. plotRevealed
break
end
end
end
end
end
return resourcePinList
end
</PopulateList>
<OnSelection>function(selection)
efn_SelectedLocatedResourceIndex = tonumber(selection)
end
</OnSelection>
<Sorted>true</Sorted>
</SelectionListData>
<SelectionListData><Name>Map Pins</Name>
<Location>
<X>880</X>
<Y>30</Y>
</Location>
<Size>
<Width>150</Width>
<Height>350</Height>
</Size>
<PopulateList>function()
return efn_ResourcesToLocateList
end
</PopulateList>
<OnSelection>function(selection)
efn_SelectedResource = selection
end
</OnSelection>
<Sorted>true</Sorted>
</SelectionListData>
</SelectionLists>
<MultiselectLists />
</PanelData>
_TunerResourcePanel code:
Code:
g_PanelHasFocus = false
g_SelectedPlayer = -1
efn_OnlyRevealedResources = true
efn_OnlyRevealedPlots = true
efn_ResourceNames = {}
efn_ResourceDataByName = {}
efn_ResourcesToLocateList = {}
efn_ResourcePinData = {}
-------------------------------------------------------------------------------
function efn_IsResourceRevealed(resName, player)
-- Function returns true iff the specified resource has been revealed to the specified player
print("efn_ResourceRevealed entered")
local idxTech, idxCivic, techRevealed, civicRevealed
local resource = efn_ResourceDataByName[resName]
idxTech = resource.IndexPrereqTech
idxCivic = resource.IndexPrereqCivic
techRevealed = (idxTech == -1) or player:GetTechs():HasTech(idxTech)
civicRevealed = (idxCivic == -1) or player:GetCulture():HasCivic(idxCivic)
return techRevealed and civicRevealed
end
function efn_Initialize()
print("_TunerResourcePanel loading")
local resource, resourceName, prereqTech, idxPrereqTech, prereqCivic, idxPrereqCivic
for resource in GameInfo.Resources() do
resourceName = string.gsub(resource.ResourceType, "RESOURCE_", "")
table.insert(efn_ResourceNames, resourceName)
prereqTech = resource.PrereqTech
idxPrereqTech = -1; if prereqTech then idxPrereqTech = GameInfo.Technologies[prereqTech].Index end
prereqCivic = resource.PrereqCivic
idxPrereqCivic = -1; if prereqCivic then idxPrereqCivic = GameInfo.Civics[prereqCivic].Index end
efn_ResourceDataByName[resourceName] = {Index = resource.Index, IndexPrereqTech = idxPrereqTech, IndexPrereqCivic = idxPrereqCivic}
end
print("Initialized Resource Data Lists:")
print("\tCount\t\tName\t\tIndex\tIndexReqTech\t\tIndexReqCivic")
local idxRes, resourceData
for idxRes, resourceName in ipairs(efn_ResourceNames) do
resourceData = efn_ResourceDataByName[resourceName]
print("\t" .. idxRes .. "\t" .. resourceName .. "\t" .. resourceData.Index .. "\t" .. resourceData.IndexPrereqTech .. "\t" .. resourceData.IndexPrereqCivic)
end
print("**********************************")
end
efn_Initialize()