• Our friends from AlphaCentauri2.info are in need of technical assistance. If you have experience with the LAMP stack and some hours to spare, please help them out and post here.

How to retrieve value at index in a table?

Thalassicus

Bytes and Nibblers
Joined
Nov 9, 2005
Messages
11,057
Location
Texas
Trying to retrieve a value from a table by index:

Code:
    local cityTable = toPlayer:Cities();
    local toCity = cityTable [i];

This return an error, "attempt to index local cityTable (a function value)"

Similar problem with:

Code:
for key,value in pairs(toPlayer:Cities()) do

This confused my brother (helping me learn Lua) as every list he's worked with has been able to use the "in pairs" mechanism. So we tried the following:

Code:
print(fromPlayer:Cities());

Output is:

Code:
function: 15BD4A18     table: 15899E90

Clearly this data is a table, yet table operations can't be used on it. It appears to be treating it as a function data type, and not the return value of the function (which is a table). How can I access indices in this table?
 
The confusion here is caused by the fact that toPlayer:Cities() returns a city-object, not a table. Pairs or ipairs can't traverse objects. You could make some sense to your example if you try use it like this:

Code:
toPlayer = Players[Game.GetActivePlayer()]
for oCity in toPlayer:Cities() do
  print(oCity:GetName())
end
 
I guess what I'm trying to say is, everything in Lua is a table, right? Or at the very least, that city object instance stores a table/list of cities which was at memory location 15899E90 the for loop traverses...

I need to retrieve a random city from that list, instead of looping through all of them. Basically, this:

Code:
city = player:Cities()[Map.Rand(player:GetNumCities())];
 
I haven't figured out how to traverse objects in lua. I'd really want to know if that is possible?

That print does return a table, but it's once again userdata. You can get that table (to look into it yourself) with command:
Code:
local toPlayer = Players[ Game.GetActivePlayer() ]
local aFunction, bTable = toPlayer:Cities()

Only solution I can see is to loop through all of them. But that just me. ;)
 
Then you'll need to find a function on the Player object that returns a specific city by index, such as CityByID() or CityForIndex() or IndexCity(). These are all total guesses at what cryptic names Firaxis actually chose. Hopefully there's one that takes an integer and returns a City object.

It appears that Cities() returns an object that provides iterative access to the list of cities and is designed to work in the for loop. It's like an iterator in C++.

To answer your other question, yes all objects are tables. However, that doesn't mean they provide a nice "by index" method of accessing their elements if they happen to encapsulate a list of items. As for using it in pairs(), I assume this fails because the functions are actually in the object's metatable and not the table itself.

Take this with a giant grain of salt as I haven't started playing with it yet. :)
 
Back
Top Bottom