GAP from Trade Routes

Chrisy15

Flower, Beautiful
Joined
Jul 9, 2015
Messages
2,137
Hello Lua modders!

I'm here because of a problem to do with trade routes.

I'm trying to give Golden Age points to the player based off of the gold they are receiving from their International Trade Routes.

I've been basing it off of LeeS's code, but I've run into a problem.

These are my two functions:

Code:
function C15_SKorea_DTP_GAPfromTradeRoutes(iPlayer, pCity, tPlayerTradeRoutes)
	local iTradeRouteGoldTotal = 0
	[COLOR="Red"]for i = 1, #tPlayerTradeRoutes do[/COLOR] --Error is refering to this line - forgot that you wouldn't be able to see that!
		if (tPlayerTradeRoutes[i]["FromID"] == iPlayer) and not (tPlayerTradeRoutes[i]["ToID"] == iPlayer) then
			if tPlayerTradeRoutes[i]["FromCity"] == pCity then
				iTradeRouteGoldTotal = iTradeRouteGoldTotal + tPlayerTradeRoutes[i]["FromGPT"]
			end
		end
	end
	
	return iTradeRouteGoldTotal
end

Code:
function C15_SKorea_GAPfromTradeRoutes(iPlayer)
	local pPlayer = Players[iPlayer]
	if pPlayer:GetCivilizationType() == civilisationID then
		local tPlayerTradeRoutes = pPlayer:GetTradeRoutes()
		if #tPlayerTradeRoutes > 0 then
			for pCity in pPlayer:Cities() do
				C15_SKorea_DTP_GAPfromTradeRoutes(iPlayer, pCity, tPlayerTradeRoutes)
				pPlayer:ChangeGoldenAgeProgressMeter(iTradeRouteGoldTotal)
				print("GAP added: ", iTradeRouteGoldTotal)
			end
		end
	end
end

if isSKActive then
	GameEvents.PlayerDoTurn.Add(C15_SKorea_GAPfromTradeRoutes)
	print("GAP From Trade Routes added!")
end

However, for some reason, tPlayerTradeRoutes is a nil value:

Code:
\C15_SKorea_TopPanelSupport.lua:65: attempt to get length of local 'tPlayerTradeRoutes' (a nil value)

The value remains nil regardless of whether there are any trade routes or not; the DTP function doesn't fire if there aren't any trade routes, but it does still remain nil.

Any explanation?
 
I'm not getting any errors from running your code, whether or not the player has any active trade routes. You do have one slight error that needs to be fixed. In the following I used America for the civ to test under:
Code:
local civilisationID = GameInfoTypes.CIVILIZATION_AMERICA

function C15_SKorea_DTP_GAPfromTradeRoutes(iPlayer, pCity, tPlayerTradeRoutes)
	local iTradeRouteGoldTotal = 0
	for i = 1, #tPlayerTradeRoutes do
		if (tPlayerTradeRoutes[i]["FromID"] == iPlayer) and not (tPlayerTradeRoutes[i]["ToID"] == iPlayer) then
			if tPlayerTradeRoutes[i]["FromCity"] == pCity then
				iTradeRouteGoldTotal = iTradeRouteGoldTotal + tPlayerTradeRoutes[i]["FromGPT"]
			end
		end
	end
	
	return iTradeRouteGoldTotal
end
function C15_SKorea_GAPfromTradeRoutes(iPlayer)
	local pPlayer = Players[iPlayer]
	if pPlayer:GetCivilizationType() == civilisationID then
		local tPlayerTradeRoutes = pPlayer:GetTradeRoutes()
		if #tPlayerTradeRoutes > 0 then
			for pCity in pPlayer:Cities() do
				[color="blue"]local iTradeRouteGoldTotal = [/color]C15_SKorea_DTP_GAPfromTradeRoutes(iPlayer, pCity, tPlayerTradeRoutes)
				pPlayer:ChangeGoldenAgeProgressMeter(iTradeRouteGoldTotal)
				print("GAP added: ", iTradeRouteGoldTotal)
			end
		end
	end
end
	GameEvents.PlayerDoTurn.Add(C15_SKorea_GAPfromTradeRoutes)
	print("GAP From Trade Routes added!")
Note that I also altered this part of your code:
Code:
if isSKActive then
	GameEvents.PlayerDoTurn.Add(C15_SKorea_GAPfromTradeRoutes)
	print("GAP From Trade Routes added!")
end
but only to make it a little easier to add the code into an existing game I was running. In the saved game I was running I have two food trade-routes running, and the code executed properly and reported '0' golden age points being added for each city in the empire because they were Food routes. I then started a whole new test-game and on the first turn neither got an error report in the log, nor the line telling me how many golden age points were added because of trade routes related to my capital city1.

In what type of file are you trying to run this code? Is it part of a UI replacement file that takes the place of a standard game file, such as TopPanel.lua ?



1this is as it should be because:
Code:
print("GAP added: ", iTradeRouteGoldTotal)
should only run when the player has trade routes going.
 
I'm not getting any errors from running your code, whether or not the player has any active trade routes. You do have one slight error that needs to be fixed. In the following I used America for the civ to test under:
Code:
local civilisationID = GameInfoTypes.CIVILIZATION_AMERICA

function C15_SKorea_DTP_GAPfromTradeRoutes(iPlayer, pCity, tPlayerTradeRoutes)
	local iTradeRouteGoldTotal = 0
	for i = 1, #tPlayerTradeRoutes do
		if (tPlayerTradeRoutes[i]["FromID"] == iPlayer) and not (tPlayerTradeRoutes[i]["ToID"] == iPlayer) then
			if tPlayerTradeRoutes[i]["FromCity"] == pCity then
				iTradeRouteGoldTotal = iTradeRouteGoldTotal + tPlayerTradeRoutes[i]["FromGPT"]
			end
		end
	end
	
	return iTradeRouteGoldTotal
end
function C15_SKorea_GAPfromTradeRoutes(iPlayer)
	local pPlayer = Players[iPlayer]
	if pPlayer:GetCivilizationType() == civilisationID then
		local tPlayerTradeRoutes = pPlayer:GetTradeRoutes()
		if #tPlayerTradeRoutes > 0 then
			for pCity in pPlayer:Cities() do
				[color="blue"]local iTradeRouteGoldTotal = [/color]C15_SKorea_DTP_GAPfromTradeRoutes(iPlayer, pCity, tPlayerTradeRoutes)
				pPlayer:ChangeGoldenAgeProgressMeter(iTradeRouteGoldTotal)
				print("GAP added: ", iTradeRouteGoldTotal)
			end
		end
	end
end
	GameEvents.PlayerDoTurn.Add(C15_SKorea_GAPfromTradeRoutes)
	print("GAP From Trade Routes added!")
Note that I also altered this part of your code:
Code:
if isSKActive then
	GameEvents.PlayerDoTurn.Add(C15_SKorea_GAPfromTradeRoutes)
	print("GAP From Trade Routes added!")
end
but only to make it a little easier to add the code into an existing game I was running. In the saved game I was running I have two food trade-routes running, and the code executed properly and reported '0' golden age points being added for each city in the empire because they were Food routes. I then started a whole new test-game and on the first turn neither got an error report in the log, nor the line telling me how many golden age points were added because of trade routes related to my capital city1.

In what type of file are you trying to run this code? Is it part of a UI replacement file that takes the place of a standard game file, such as TopPanel.lua ?



1this is as it should be because:
Code:
print("GAP added: ", iTradeRouteGoldTotal)
should only run when the player has trade routes going.

Hooray - LeeS to the rescue!

The first function returns the variable to be used by the Dynamic Top Panel. The runtime error appears when hovering over the GAP on the TopPanel, meaning that something isn't working there. Adding in the variable definition has made the code start working, but the number of GA points given isn't right; despite the route only yielding 2 Gold, I'm getting 162 GAPs - have I done some maths wrong or something?

If it helps, this is the SQL for the DTP:

Code:
CREATE TABLE IF NOT EXISTS 
	JFD_TopPanelIncludes (
	FileName				text		default null);

CREATE TABLE IF NOT EXISTS 
    JFD_TopPanelAdditions (
    CivilizationType        text        REFERENCES Civilizations(Type)  default null,
    YieldType               text        REFERENCES Yields(Type)         default null,
    YieldSourceFunction     text                                        default null,
    YieldSourceToolTip      text                                        default null,
    MiscToolTipFunction     text                                        default null);

INSERT INTO JFD_TopPanelIncludes
		(FileName)
VALUES	('C15_SKorea_TopPanelSupport.lua');

INSERT INTO JFD_TopPanelAdditions
		(CivilizationType,			YieldType,			YieldSourcefunction,								YieldSourceToolTip)
VALUES	('CIVILIZATION_C15_SKOREA',	'YIELD_GOLDEN_AGE',		'C15_SKorea_DTP_GAPfromTradeRoutes',			'TXT_KEY_C15_GAP_TRADE_ROUTES'),
		('CIVILIZATION_C15_SKOREA',	'YIELD_GOLD',		'C15_SKorea_DTP_GPTfromScience',					'TXT_KEY_C15_GPTSCIENCE'); --Note that this one works fine
 
From my original code:
Code:
iTradeRouteGoldTotal = math.ceil(((iTradeRouteGoldTotal * (iNumberMajorWars * .1))[B][COLOR="Red"]/100 [/COLOR][/B])/iNumberCityTradeRoutes)
Note the division by '100'.

------------------------------------------------------------------------------------------------------------------

This gives values where '200' = '2'
Code:
tPlayerTradeRoutes[i]["FromGPT"]
I don't remember whether the "ToGPT" in the player's trade-routes table also gives values in '100' = '1' as well.

-------------------------------------------------------------------------------------------------------------------

I'm not familiar enough with JFD's Dynamic Top Panel to know if what you are doing is 'good' for that or not
 
From my original code:
Code:
iTradeRouteGoldTotal = math.ceil(((iTradeRouteGoldTotal * (iNumberMajorWars * .1))[B][COLOR="Red"]/100 [/COLOR][/B])/iNumberCityTradeRoutes)
Note the division by '100'.

------------------------------------------------------------------------------------------------------------------

This gives values where '200' = '2'
Code:
tPlayerTradeRoutes[i]["FromGPT"]
I don't remember whether the "ToGPT" in the player's trade-routes table also gives values in '100' = '1' as well.

-------------------------------------------------------------------------------------------------------------------

I'm not familiar enough with JFD's Dynamic Top Panel to know if what you are doing is 'good' for that or not

... That would explain it. Serves me for not paying attention to your code :)

Out of interest, why in this for statement:

Code:
for i = 1, #tPlayerTradeRoutes do

is i = 1? Isn't i the increment, and therefore setting it to 1 will mean that only one trade route is checked?
 
no. in a 'for' loop structured that way 'i' is given from "iStartingValue" to "iEndingValue" starting from "iStartingValue" and by default is incremented by '1' every time it goes through the loop until it finishes when 'i' has been incremented up to "iEndingValue". The loop executes and handles both "i = iStartingValue" and "i = iEndingValue" and all integer values in-between so long as the increment by which to alter 'i' each time the loop is executed is '1'.

Basic structure of a 'for' loop with "integer assignments":
Code:
for i = iStartingValue, iEndingValue, iIncrement do
	--stuff that should be done for each sequential value of 'i' as each is handled
end
When "iIncrement" is omitted, it is assumed to be '1'


-----------------------------------------------------------------------------

The structure of a 'for' loop is different when iterating through all a player's cities, units, etc., or when using a 'for' loop to run through the contents of an lua-table, but the concept of what happens inside the loop is the same, ie, each "value" is handled one at a time in the same way based on the code between the 'for' line and its terminating 'end'.
 
no. in a 'for' loop structured that way 'i' is given from "iStartingValue" to "iEndingValue" starting from "iStartingValue" and by default is incremented by '1' every time it goes through the loop until it finishes when 'i' has been incremented up to "iEndingValue". The loop executes and handles both "i = iStartingValue" and "i = iEndingValue" and all integer values in-between so long as the increment by which to alter 'i' each time the loop is executed is '1'.

Basic structure of a 'for' loop with "integer assignments":
Code:
for i = iStartingValue, iEndingValue, iIncrement do
	--stuff that should be done for each sequential value of 'i' as each is handled
end
When "iIncrement" is omitted, it is assumed to be '1'


-----------------------------------------------------------------------------

The structure of a 'for' loop is different when iterating through all a player's cities, units, etc., or when using a 'for' loop to run through the contents of an lua-table, but the concept of what happens inside the loop is the same, ie, each "value" is handled one at a time in the same way based on the code between the 'for' line and its terminating 'end'.

Okay, thanks!
 
Back
Top Bottom