Three lua errors in Anno Domini - please help

Rob (R8XFT)

Ancient Briton
Retired Moderator
Joined
Aug 11, 2002
Messages
10,866
Location
Leeds (UK)
My lua logs point to three errors in my lua scripts. Could someone please let me know what to change to correct these?

1. Error logs state:
Runtime Error: C:\Users\Rob\Documents\My Games\Sid Meier's Civilization 5\MODS\Anno Domini (BNW) (v 7)\Lua/FreeShrineScript.lua:38: attempt to concatenate local 't' (a nil value)

Spoiler :
Code:
function OnCityFoundCheck (player, numBuilds, iBuilding, iTech, pTeam)
	local player = Players[iPlayer];
	local numBuilds = GetNumFreeBuildingonTech(player);
	local b = GetFreeBuilding(player);
	if b ~= nil then
		local iBuilding = GameInfoTypes["" .. b .. ""]
	end
	local t = GetFreeBuildingTechPrereq(player);
	if t ~= nil then
		local iTech = GameInfo.Technologies["" .. t .. ""].ID
	end
	local i = player:CountNumBuildings(GameInfoTypes["" .. b .. ""])
	local teamID = player:GetTeam();
	local pTeam = Teams[teamID];
	if (pTeam:IsHasTech(iTech)) then
	for pCity in player:Cities() do
		if i < numBuilds then
			pCity:SetNumRealBuilding(GameInfoTypes["" .. b .. ""], 1)
			local i = player:CountNumBuildings(GameInfoTypes["" .. b .. ""])
		end
	end
	end
	if i == numBuilds then
		GameEvents.PlayerCityFounded.Remove(OnCityFoundCheck);
	end
end



function TraitFreeBT(iPlayer)
	local player = Players[iPlayer];
	local numBuilds = GetNumFreeBuildingonTech(player);
	local b = GetFreeBuilding(player);
	local t = GetFreeBuildingTechPrereq(player);
	local iTech = GameInfoTypes["" .. t .. ""]
	local teamID = player:GetTeam();
	local pTeam = Teams[teamID];
	if b ~= nil and t ~=nil then
		if numBuilds == -1 then
			if (pTeam:IsHasTech(iTech)) then
				for pCity in player:Cities() do
					print ("Condition 1");
					pCity:SetNumRealBuilding(GameInfoTypes["" .. b .. ""], 1)
				end
			end
		elseif (player:GetNumCities() == numBuilds) then
			if (pTeam:IsHasTech(iTech)) then
				for pCity in player:Cities() do
					print ("Condition 2");
					pCity:SetNumRealBuilding(GameInfoTypes["" .. b .. ""], 1)
				end
			end
		elseif (player:GetNumCities() < numBuilds) then
			if (pTeam:IsHasTech(iTech)) then
				for pCity in player:Cities() do
					print ("Condition 3");
					print (t);
					print (iTech);
					pCity:SetNumRealBuilding(GameInfoTypes["" .. b .. ""], 1)
					GameEvents.PlayerCityFounded.Add(OnCityFoundCheck);
				end
			end
		elseif (player:GetNumCities() > numBuilds) then
			if (pTeam:IsHasTech(iTech)) then
				for pCity in player:Cities() do
					print ("Condition 4");
					local i = player:CountNumBuildings(GameInfoTypes["" .. b .. ""])
					if i < numBuilds then
						pCity:SetNumRealBuilding(GameInfoTypes["" .. b .. ""], 1)
						local i = player:CountNumBuildings(GameInfoTypes["" .. b .. ""])
					end
				end
			end
		end
	end
end
GameEvents.PlayerDoTurn.Add(TraitFreeBT);


function GetFreeBuilding(player)
	if player == nil or not player:IsAlive() or 
			player:IsBarbarian() or player:IsMinorCiv() then
		return nil;
	end
	local trait = GetMajorTrait(player);
	return trait.FreeBuildingonTech;
end

function GetFreeBuildingTechPrereq(player)
	if player == nil or not player:IsAlive() or 
			player:IsBarbarian() or player:IsMinorCiv() then
		return nil;
	end
	local trait = GetMajorTrait(player);
	return trait.FreeBuildingTechPrereq;
end

function GetNumFreeBuildingonTech(player)
	if player == nil or not player:IsAlive() or 
			player:IsBarbarian() or player:IsMinorCiv() then
		return -1;
	end
	local trait = GetMajorTrait(player);
	return trait.NumFreeBuildingonTech;
end

function GetMajorTrait(pPlayer)
	local leader = GameInfo.Leaders[pPlayer:GetLeaderType()];
	local leaderTrait = GameInfo.Leader_Traits("LeaderType ='" .. leader.Type .. "'")();
	return GameInfo.Traits[leaderTrait.TraitType];
end
2. Error logs state:
Runtime Error: C:\Users\Rob\Documents\My Games\Sid Meier's Civilization 5\MODS\Anno Domini (BNW) (v 7)\Lua/BelgaeUA.lua:60: attempt to index local 'leaderTrait' (a nil value)

Spoiler :
Code:
include("NewSaveUtils.lua");

function DoubleResistance(playerID, bCapital, iX, iY, newPlayerID)
	local loser = Players[playerID];
	-- applicable?
	local leader = GameInfo.Leaders[loser:GetLeaderType()];
	local leaderTrait = GameInfo.Leader_Traits("LeaderType ='" .. leader.Type .. "'")();
	local trait = GameInfo.Traits[leaderTrait.TraitType];
	if not trait.DoubleResistance then return end
	-- ok go
	print("double resistance check");
	local pCity = Map.GetPlot(iX, iY):GetPlotCity();
	if pCity:IsResistance() then
		print("in resistance");
		print("resistance: " .. pCity:GetResistanceTurns());
		pCity:ChangeResistanceTurns(pCity:GetResistanceTurns());
		print("new resistance: " .. pCity:GetResistanceTurns());
	end
end
GameEvents.CityCaptureComplete.Add( DoubleResistance );



function CivilianCulturePerTurn(iPlayer)
	local player = Players[iPlayer];
	if not HasCcpt(player) then return end
	-- ok go
	print("civilian culture check");
	local prevCCPT = GetPersistentProperty(GetCcptLabel(iPlayer)) or 0;
	local currCCPT = GetCcpt(player);
	print("culture: " .. currCCPT);
	player:ChangeJONSCulturePerTurnForFree(currCCPT - prevCCPT);
	SetPersistentProperty(GetCcptLabel(iPlayer), currCCPT);

	-- show in toolbar
	local strCultureStr;
			
	if (Game.IsOption(GameOptionTypes.GAMEOPTION_NO_POLICIES)) then
		strCultureStr = Locale.ConvertTextKey("TXT_KEY_TOP_PANEL_POLICIES_OFF");
	else
			
		if (player:GetNextPolicyCost() > 0) then
			strCultureStr = string.format("%i/%i (+%i)", player:GetJONSCulture(), player:GetNextPolicyCost(), player:GetTotalJONSCulturePerTurn());
		else
			strCultureStr = string.format("%i (+%i)", player:GetJONSCulture(), player:GetTotalJONSCulturePerTurn());
		end
			
		strCultureStr = "[ICON_CULTURE][COLOR:255:0:255:255]" .. strCultureStr .. "[/COLOR]";
	end
			
	ContextPtr:LookUpControl("/InGame/TopPanel/CultureString"):SetText(strCultureStr);
end
GameEvents.PlayerDoTurn.Add( CivilianCulturePerTurn );

function HasCcpt(player)
	if IsValidPlayer(player) then 
		local leader = GameInfo.Leaders[player:GetLeaderType()];
		local leaderTrait = GameInfo.Leader_Traits("LeaderType ='" .. leader.Type .. "'")();
		local trait = GameInfo.Traits[leaderTrait.TraitType];
		if trait.CivilianCulture then 
			return true;
		end
	end
	return false;
end

function GetCcpt(player)
	local CCPT = player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_WORKER"].ID);
	CCPT = CCPT + 2 * (
		player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_SETTLER"].ID) +
		player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_MISSIONARY"].ID) +
		player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_INQUISITOR"].ID)
	);
	CCPT = CCPT + 4 * (
		player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_GREAT_ADMIRAL"].ID) +
		player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_ARTIST"].ID) +
		player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_SCIENTIST"].ID) +
		player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_ENGINEER"].ID) +
		player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_MERCHANT"].ID) +
		player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_GREAT_GENERAL"].ID) +
		player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_PROPHET"].ID)
	);
		local team = Teams[player:GetTeam()];
	if team:GetAtWarCount(false) == 0 then
		CCPT = CCPT + 3 * player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_HORSEMAN"].ID);
	end
	return CCPT;
end

function GetCcptLabel(iPlayer)
	return "CCPT_score_p" .. iPlayer;
end

function IsValidPlayer(player)
	return player ~= nil and player:IsAlive() and not player:IsBarbarian();
end
3. Error logs state:
Syntax Error: C:\Users\Rob\Documents\My Games\Sid Meier's Civilization 5\MODS\Anno Domini (BNW) (v 7)\Lua/KushanUA.lua:34: 'end' expected near '<eof>'
Runtime Error: Error loading C:\Users\Rob\Documents\My Games\Sid Meier's Civilization 5\MODS\Anno Domini (BNW) (v 7)\Lua/KushanUA.lua.

Spoiler :
Code:
local iKushanCivType = GameInfoTypes.CIVILIZATION_KUSHAN
local iInfluenceBonus = 1

-- This function gets called at the start of EVERY player's turn
function OnPlayerDoTurn(iPlayer)
  local pPlayer = Players[iPlayer]

  -- Is this the Kushan player?
  if (pPlayer:GetCivilizationType() == iKushanCivType) then
    -- For every trade route the Kushan player has
    for _, route in ipairs(pPlayer:GetTradeRoutes()) do
      if (route.FromID == route.ToID) then
        -- It's a domestic route
      else
        -- It's an international route
        local pToPlayer = Players[route.ToID]
    
        if (pToPlayer:IsMinorCiv()) then
          -- Trade route to a minor
          
          -- Give an influence (friendship) boost with the City State
          pToPlayer:ChangeMinorCivFriendshipWithMajor(iPlayer, iInfluenceBonus)
        else
          -- Trade route to a major
        end
      end
    end
  end
end
GameEvents.PlayerDoTurn.Add(function(iPlayer)
 
1)
GameEvents.PlayerDoTurn.Add(TraitFreeBT); will be called for all players - including minors and the barbarians
local t = GetFreeBuildingTechPrereq(player); returns nil for some of those players
local iTech = GameInfoTypes["" .. t .. ""] will then barf with the "concatenating nil" error message

2)
Edit: Assuming your database entries are correct for your new majors
IsValidPlayer() doesn't exclude minors.
Minors don't have Leaders or Traits, which the following lines then assume they do
Code:
if IsValidPlayer(player) then 
  local leader = GameInfo.Leaders[player:GetLeaderType()];
  local leaderTrait = GameInfo.Leader_Traits("LeaderType ='" .. leader.Type .. "'")();
  local trait = GameInfo.Traits[leaderTrait.TraitType];

3)
GameEvents.PlayerDoTurn.Add(function(iPlayer)
should be
GameEvents.PlayerDoTurn.Add(OnPlayerDoTurn)
 
Thanks. I've corrected number three. With respect to first two issues, they each are for a trait with one particular civ. Therefore, do I just need a one-liner to say that if it's any other civ then end?

Forgive me, as I'm only learning this at the moment, but would I replace

Code:
local player = Players[playerID]

with

Code:
local player = Players[playerID]
	if player:GetCivilizationType() ~= GetCivID("CIVILIZATION_BELGAE") then return end
??

or is it "isvalidplayer" that I need to update?


Having updated Belgae with the isvalidplayer (at the bottom of the code) and Elam's free shrine script with the addition to local player = Players[playerID] in two places, this is the code - is it correct?

Spoiler :
Code:
function DoubleResistance(playerID, bCapital, iX, iY, newPlayerID)
	local loser = Players[playerID];
	-- applicable?
	local leader = GameInfo.Leaders[loser:GetLeaderType()];
	local leaderTrait = GameInfo.Leader_Traits("LeaderType ='" .. leader.Type .. "'")();
	local trait = GameInfo.Traits[leaderTrait.TraitType];
	if not trait.DoubleResistance then return end
	-- ok go
	print("double resistance check");
	local pCity = Map.GetPlot(iX, iY):GetPlotCity();
	if pCity:IsResistance() then
		print("in resistance");
		print("resistance: " .. pCity:GetResistanceTurns());
		pCity:ChangeResistanceTurns(pCity:GetResistanceTurns());
		print("new resistance: " .. pCity:GetResistanceTurns());
	end
end
GameEvents.CityCaptureComplete.Add( DoubleResistance );



function CivilianCulturePerTurn(iPlayer)
	local player = Players[iPlayer];
	if not HasCcpt(player) then return end
	-- ok go
	print("civilian culture check");
	local prevCCPT = GetPersistentProperty(GetCcptLabel(iPlayer)) or 0;
	local currCCPT = GetCcpt(player);
	print("culture: " .. currCCPT);
	player:ChangeJONSCulturePerTurnForFree(currCCPT - prevCCPT);
	SetPersistentProperty(GetCcptLabel(iPlayer), currCCPT);

	-- show in toolbar
	local strCultureStr;
			
	if (Game.IsOption(GameOptionTypes.GAMEOPTION_NO_POLICIES)) then
		strCultureStr = Locale.ConvertTextKey("TXT_KEY_TOP_PANEL_POLICIES_OFF");
	else
			
		if (player:GetNextPolicyCost() > 0) then
			strCultureStr = string.format("%i/%i (+%i)", player:GetJONSCulture(), player:GetNextPolicyCost(), player:GetTotalJONSCulturePerTurn());
		else
			strCultureStr = string.format("%i (+%i)", player:GetJONSCulture(), player:GetTotalJONSCulturePerTurn());
		end
			
		strCultureStr = "[ICON_CULTURE][COLOR:255:0:255:255]" .. strCultureStr .. "[/COLOR]";
	end
			
	ContextPtr:LookUpControl("/InGame/TopPanel/CultureString"):SetText(strCultureStr);
end
GameEvents.PlayerDoTurn.Add( CivilianCulturePerTurn );

function HasCcpt(player)
	if IsValidPlayer(player) then 
		local leader = GameInfo.Leaders[player:GetLeaderType()];
		local leaderTrait = GameInfo.Leader_Traits("LeaderType ='" .. leader.Type .. "'")();
		local trait = GameInfo.Traits[leaderTrait.TraitType];
		if trait.CivilianCulture then 
			return true;
		end
	end
	return false;
end

function GetCcpt(player)
	local CCPT = player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_WORKER"].ID);
	CCPT = CCPT + 2 * (
		player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_SETTLER"].ID) +
		player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_MISSIONARY"].ID) +
		player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_INQUISITOR"].ID)
	);
	CCPT = CCPT + 4 * (
		player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_GREAT_ADMIRAL"].ID) +
		player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_ARTIST"].ID) +
		player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_SCIENTIST"].ID) +
		player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_ENGINEER"].ID) +
		player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_MERCHANT"].ID) +
		player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_GREAT_GENERAL"].ID) +
		player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_PROPHET"].ID)
	);
		local team = Teams[player:GetTeam()];
	if team:GetAtWarCount(false) == 0 then
		CCPT = CCPT + 3 * player:GetUnitClassCount(GameInfo.UnitClasses["UNITCLASS_HORSEMAN"].ID);
	end
	return CCPT;
end

function GetCcptLabel(iPlayer)
	return "CCPT_score_p" .. iPlayer;
end

function IsValidPlayer(player)
	if player:GetCivilizationType() ~= GetCivID("CIVILIZATION_BELGAE") then return end
end

Spoiler :
Code:
function OnCityFoundCheck (player, numBuilds, iBuilding, iTech, pTeam)
	local player = Players[iPlayer];
		if player:GetCivilizationType() ~= GetCivID("CIVILIZATION_ELAM") then return end
	local numBuilds = GetNumFreeBuildingonTech(player);
	local b = GetFreeBuilding(player);
	if b ~= nil then
		local iBuilding = GameInfoTypes["" .. b .. ""]
	end
	local t = GetFreeBuildingTechPrereq(player);
	if t ~= nil then
		local iTech = GameInfo.Technologies["" .. t .. ""].ID
	end
	local i = player:CountNumBuildings(GameInfoTypes["" .. b .. ""])
	local teamID = player:GetTeam();
	local pTeam = Teams[teamID];
	if (pTeam:IsHasTech(iTech)) then
	for pCity in player:Cities() do
		if i < numBuilds then
			pCity:SetNumRealBuilding(GameInfoTypes["" .. b .. ""], 1)
			local i = player:CountNumBuildings(GameInfoTypes["" .. b .. ""])
		end
	end
	end
	if i == numBuilds then
		GameEvents.PlayerCityFounded.Remove(OnCityFoundCheck);
	end
end



function TraitFreeBT(iPlayer)
	local player = Players[iPlayer];
		if player:GetCivilizationType() ~= GetCivID("CIVILIZATION_ELAM") then return end
	local numBuilds = GetNumFreeBuildingonTech(player);
	local b = GetFreeBuilding(player);
	local t = GetFreeBuildingTechPrereq(player);
	local iTech = GameInfoTypes["" .. t .. ""]
	local teamID = player:GetTeam();
	local pTeam = Teams[teamID];
	if b ~= nil and t ~=nil then
		if numBuilds == -1 then
			if (pTeam:IsHasTech(iTech)) then
				for pCity in player:Cities() do
					print ("Condition 1");
					pCity:SetNumRealBuilding(GameInfoTypes["" .. b .. ""], 1)
				end
			end
		elseif (player:GetNumCities() == numBuilds) then
			if (pTeam:IsHasTech(iTech)) then
				for pCity in player:Cities() do
					print ("Condition 2");
					pCity:SetNumRealBuilding(GameInfoTypes["" .. b .. ""], 1)
				end
			end
		elseif (player:GetNumCities() < numBuilds) then
			if (pTeam:IsHasTech(iTech)) then
				for pCity in player:Cities() do
					print ("Condition 3");
					print (t);
					print (iTech);
					pCity:SetNumRealBuilding(GameInfoTypes["" .. b .. ""], 1)
					GameEvents.PlayerCityFounded.Add(OnCityFoundCheck);
				end
			end
		elseif (player:GetNumCities() > numBuilds) then
			if (pTeam:IsHasTech(iTech)) then
				for pCity in player:Cities() do
					print ("Condition 4");
					local i = player:CountNumBuildings(GameInfoTypes["" .. b .. ""])
					if i < numBuilds then
						pCity:SetNumRealBuilding(GameInfoTypes["" .. b .. ""], 1)
						local i = player:CountNumBuildings(GameInfoTypes["" .. b .. ""])
					end
				end
			end
		end
	end
end
GameEvents.PlayerDoTurn.Add(TraitFreeBT);


function GetFreeBuilding(player)
	if player == nil or not player:IsAlive() or 
			player:IsBarbarian() or player:IsMinorCiv() then
		return nil;
	end
	local trait = GetMajorTrait(player);
	return trait.FreeBuildingonTech;
end

function GetFreeBuildingTechPrereq(player)
	if player == nil or not player:IsAlive() or 
			player:IsBarbarian() or player:IsMinorCiv() then
		return nil;
	end
	local trait = GetMajorTrait(player);
	return trait.FreeBuildingTechPrereq;
end

function GetNumFreeBuildingonTech(player)
	if player == nil or not player:IsAlive() or 
			player:IsBarbarian() or player:IsMinorCiv() then
		return -1;
	end
	local trait = GetMajorTrait(player);
	return trait.NumFreeBuildingonTech;
end

function GetMajorTrait(pPlayer)
	local leader = GameInfo.Leaders[pPlayer:GetLeaderType()];
	local leaderTrait = GameInfo.Leader_Traits("LeaderType ='" .. leader.Type .. "'")();
	return GameInfo.Traits[leaderTrait.TraitType];
end
 
Thanks! I've introduced these scripts to the mod and now this is what the error logs indicate:

[21578.947] Runtime Error: C:\Users\Rob\Documents\My Games\Sid Meier's Civilization 5\MODS\Anno Domini (BNW) (v 7)\Lua/BelgaeUA.lua:96: attempt to call global 'GetCivID' (a nil value)
[21578.947] Runtime Error: C:\Users\Rob\Documents\My Games\Sid Meier's Civilization 5\MODS\Anno Domini (BNW) (v 7)\Lua/FreeShrineScript.lua:36: attempt to call global 'GetCivID' (a nil value)

Appreciating what you've advised already and looking at the other thread, is this a case of it saying it can't find anything because those civs aren't in this game, but it won't cause a crash?
 
There is no definition of the function GetCivID("CIVILIZATION_ELAM")

You can just use GameInfoTypes.CIVILIZATION_ELAM
 
Back
Top Bottom