[Solved] LUA How to get the list of all available techs ?

if you want your code to run through all the techs in the game, you just do as:
Code:
for row in GameInfo.Technologies() do
    ---do something for each tech
    print(row.TechnologyType)
end
If you wanted to store all these techs in a temporary lua table that you can then access later you can do as
Code:
local tTableOfAllTechs = {}
for row in GameInfo.Technologies() do
    tTableOfAllTechs[row.Index] = row.TechnologyType
end
for k,v in pairs(tTableOfAllTechs) do
     print(Tech Index # " .. k .. " is for " .. v)
end
This would print into the lua log file a listing of all the Index #s used by the game as assigned to each tech.*

But whether it is useful to run through the entire xml table of techs (or store all this stuff into a temporary lua table) is a question whose answer is entirely dependant on what you want to do with the information you can gather from doing so.

Spoiler * :
I am fully aware you can just make the print-out as you go through the actual xml-table via the for row in GameInfo.Technologies() do iteration, but that would not show a way you can cache and then refer back to that data later
 
Thanks LeeS, another very helpful post. I can code my way through basic LUA,
http://steamcommunity.com/sharedfiles/filedetails/?id=893261596
I can figure out stuff from other's codes, but I have a very hard time accessing the game data.
If I may, where do the "row" come from? Is it an XML/SQL function that can be used in lua ? an lua function ? I never came across that. if it works as I think, it will be very interesting indeed.

As for what I want to do, is to randomly disable a tech when another one is discovered, the very basic fundamental for my mod.
https://forums.civfanatics.com/threads/any-interest-in-a-create-your-civ-as-you-play-mod.604391/
I already know I will run into troubles, because there is no function to disable a tech. However, in the tutorials, it is possible to disable techs, so I will try to use that code. Or make the research cost really huge. I will see.

I will try to figure out how to do this before maybe requesting help.

Thanks again.
 
"row" here is just a variable that will be localized to the for-loop it is stated on:
Code:
for row in GameInfo.Technologies() do
    print(row.TechnologyType)
end
I can call the variable "Cheeseburger":
Code:
for Cheeseburger in GameInfo.Technologies() do
    print(Cheeseburger.TechnologyType)
end
or "Technology":
Code:
for Technology in GameInfo.Technologies() do
    print(Technology.TechnologyType)
end
Don't worry that it seemed like a mystery-thing. It took me the longest time during civ5 days to "twig" to this inherent ability of lua "for" loops when running through the items in an xml table via the for X in GameInfo.XML_TableName() do iteration method. X can be any reasonable variable-name, but throughout the loop you have to refer to it as you did on the line with the "for .... do" commands.

For civ5 and civ6 xml tables, each row in the xml table is read out in turn by the for loop, and the data within that row is placed into an "indexable" lua-table temporarily using the name you gave as X for the time it takes to run through the commands within the loop for that given row within the XML table. So I can grab the data from the specific columns I am interested in that are used within that xml-table (like as I did for row.TechnologyType).

This inherent "name-it-what-you-want" ability is inherent in all for loops in lua. So I can do this, using "iLoopPlayer" as the variable that contains the player's ID# for each player in turn as the loop is executed:
Code:
for iLoopPlayer = 1, 62 do	--altered to check all players other than the human and the barb
	local pLoopPlayer = Players[iLoopPlayer]
	if pLoopPlayer:IsAlive() then
		local sPlayerCivName = PlayerConfigurations[iLoopPlayer]:GetCivilizationTypeName()
		local sPlayerLeaderName = PlayerConfigurations[iLoopPlayer]:GetLeaderTypeName()
		print("Player # " .. iLoopPlayer .. " is being used as " .. sPlayerCivName .. " with leader of " .. sPlayerLeaderName)
		local pCities = pLoopPlayer:GetCities();
		if pCities:GetCount() > 0 then
			for i, pCity in pCities:Members() do
				print(Locale.Lookup(pCity:GetName()) .. " is producing " .. tostring(pCity:GetBuildQueue():CurrentlyBuilding()))
			end
		else
			print(sPlayerLeaderName .. " has no cities")
		end
	end
end
I could just as well have called the variable "LumpyGoats" and as long as I change the name everywhere the code will execute identically
Code:
for LumpyGoats = 1, 62 do	--altered to check all players other than the human and the barb
	local pLoopPlayer = Players[LumpyGoats]
	if pLoopPlayer:IsAlive() then
		local sPlayerCivName = PlayerConfigurations[LumpyGoats]:GetCivilizationTypeName()
		local sPlayerLeaderName = PlayerConfigurations[LumpyGoats]:GetLeaderTypeName()
		print("Player # " .. LumpyGoats .. " is being used as " .. sPlayerCivName .. " with leader of " .. sPlayerLeaderName)
		local pCities = pLoopPlayer:GetCities();
		if pCities:GetCount() > 0 then
			for i, pCity in pCities:Members() do
				print(Locale.Lookup(pCity:GetName()) .. " is producing " .. tostring(pCity:GetBuildQueue():CurrentlyBuilding()))
			end
		else
			print(sPlayerLeaderName .. " has no cities")
		end
	end
end
But when you go back to your own code later you discover pretty quick why we all tend to use names like "row", "Technology", "iPlayer", "PlayerID" that are related to the thing we are doing instead of names like "Hamburger", "LumpyGoats", "LambsOnTheGreenage".
 
Last edited:
Back
Top Bottom