for row in GameInfo Table?

Enginseer

Salientia of the Community Patch
Supporter
Joined
Nov 7, 2012
Messages
3,674
Location
Somewhere in California
I know that you can use GameInfo to extract XML data into LUA, but how would I organize them into a database of leaders for LUA?

Or am I doing this right at all?

Code:
local LeaderFlavor = {}
for row in GameInfo.Leader_Flavors() do
	table.insert(LeaderFlavor, {row.LeaderType, row.FlavorType, row.Flavor})
end
print(table.getn(LeaderFlavor))
 
table.insert() expects two (optionally three) parameters, where the first parameter is the table name and the second parameter is the value to insert into the table - see http://www.lua.org/pil/19.2.html

table.insert(t, x) is the same as t[(#t+1)] = x

the optional third parameter (n) is the index to insert at, in which case all table entries with an index greater than n are moved up by one, and the new entry is inserted at t[n]

Assuming you want to insert all the values listed as a single entry you will need to do

table.insert(LeaderFlavor, {row.LeaderType, row.FlavorType, row.Flavor})

you can then get the Nth FlavorType as LeaderFlavor[n][2] - as FlavorType is the 2nd item in the (anonymous) array created and stored as the Nth item
 
So, how would I use the item as a function then?
Code:
function LeaderCheck (iPlayer)
   local pPlayer = Players[iPlayer]
   local pCapitalCity = pPlayer:GetCapitalCity()
	if LeaderFlavor[pPlayer][1] >= 5 then --Does the leader have a high flavor_offense high enough to benefit?
		pCapitalCity:SetNumRealBuilding(GameInfoTypes.BUILDING_FLAVOR_OFFENSE, 1) then
	end
end
GameEvents.PlayerDoTurn.Add(LeaderCheck)
 
LeaderFlavor[pPlayer][1]

is meaningless

pPlayer is an object, so will look like a string like "Object:29845"

Even if you use iPlayer (or pPlayer:GetID()) it is still meaningless as LeaderFlavor is not indexed by player id, but as a sequential list of rows retrieved from the Leader_Flavors table.

You need to get the LeaderType (index 1) and the FlavorType (index 2) you're interested in for the specific pPlayer and then loop (i) the LeaderFlavor array and compare LeaderFlavor[1] with the LeaderType and LeaderFlavor[2] with the FlavorType and if those two match you can do the final comparison of LeaderFlavor[3] (the Flavor value) for being greater than or equal to 5.

However, in that case, you really should be building a multidimensional array indexed by LeaderType and FlavorType and not a linear array that you then have to loop over every time
 
However, in that case, you really should be building a multidimensional array indexed by LeaderType and FlavorType and not a linear array that you then have to loop over every time

Multidimensional array? :confused: Like.. this?
Code:
LeaderFlavor = {}
    for row in GameInfo.Leader_Flavors() do
      LeaderFlavor[row.LeaderType] = {} 
      for row in GameInfo.Leader_Flavors() do
        LeaderFlavor[row.LeaderType][row.FlavorType] = {}
            for row in GameInfo.Leader_Flavors() do
                  LeaderFlavor[row.LeaderType][row.FlavorType][row.Flavor] = {}
            end
          end
      end
end
 
An array (table) within another array.

This is a two-dimensional array:
t = {{1,2,3}, {4,5,6}, {7,8,9}}

It has two 'layers', so to speak.

So, how would I implement the layers using the GameInfo?
 
I don't have time right now to read the rest of the thread, but here it goes:

Code:
tLeaderFlavor = {}
tLeaderFlavor[iLeaderType] = {Offense = iOffenseValue, Defense = iDefenseValue [B](etc)[/B]}

These i*Value you'll set yourself - through iterating the game flavor tables - before creating the arrays, obviously.

Then, when you need to iterate, you do:
Code:
for i, v in pairs(tLeaderFlavor) do
	if i == iLeaderType and v.Offense > iOffenseThreshold then
		-- run code
	end
end

The variable 'i' here will be the iLeaderType. I don't know how you will get it, because I don't know what is the purpouse of this.
I hope it is clear, I can't be more precise because of time constraints, sorry.

EDIT:
Useless extra step removed.
 
This is a classic example of where asking the wrong initial question is taking you further and further from the solution.

if LeaderFlavor[pPlayer][1] >= 5 then --Does the leader have a high flavor_offense

The requirement is "how do I get a specific flavour value for a given player"

You can answer this directly via a database query, but if you're asking a lot of these questions, you definitely want to cache the answers

Code:
local playerFlavors = nil

function getPlayerFlavors(iPlayer)
    local flavors = {}
    
    for row in DB.Query("SELECT f.ID AS flavor, lf.Flavor AS value FROM Leaders l, Leader_Flavors lf, Flavors f WHERE l.ID=? AND l.Type=lf.LeaderType AND lf.FlavorType=f.Type", Players[iPlayer]:GetLeaderType()) do
        flavors[row.flavor] = row.value
    end
    
    return flavors
end

function cachePlayerFlavors()
    for iPlayer = 0, GameDefines.MAX_MAJOR_CIVS-1, 1 do
        if (Players[iPlayer]:IsEverAlive()) then
            playerFlavors[iPlayer] = getPlayerFlavors(iPlayer)
        else
            playerFlavors[iPlayer] = {}
        end
    end
end

function getPlayerFlavour(iPlayer, iFlavor)
    if (playerFlavors == nil) then
        cachePlayerFlavors()
    end
    
    return playerFlavors[iPlayer][iFlavor] or -1
end

-- You can now do getPlayerFlavor(iPlayer, GameInfoTypes.FLAVOR_NAVAL_RECON)
-- to get the specific flavour integer value for the given player's leader
 
Back
Top Bottom