What's wrong with this code? (Adds a dummy building in the capital per trade route)

Toggaf

Chieftain
Joined
Jan 7, 2013
Messages
32
This doesn't seem to work at all. Not really sure what I'm doing since I'm really new to LUA, and have just patched most of this together from other sources.

Code:
function DummyTrade(playerID)

	local player = Players[playerID];
	if not IsMajorCiv(player) then return 
	end

	local leaderID = GameInfo.Leaders[player:GetLeaderType()].ID;
	if leaderID == GameInfo.Leaders["LEADER_STADTRADT"].ID then
		local iBuilding = GameInfo.Buildings[BUILDING_ULMDUMMY].ID;
		local city = player:GetCapitalCity();
		local tr = Player.GetTradeRoutes();
		if city ~= nil then
			city:SetNumRealBuilding(iBuilding, tr);
		end
	end
end

GameEvents.PlayerDoTurn.Add(DummyTrade)
 
Providing the context you are working in would also help.... from what I can see, you are trying to give the player a bonus amount of whatever yield/bonuses in their capital, based on the number of trade routes they have in total...?

I'm not a LUA expert either, so just a couple pointers:
- Did you enable logging? Try putting print statements in your function and see where the trace ends up.
- IsMajorCiv does not appear to be an actual function (likely your problem, as the C++ source code does not have a LUA hook for it).... the functionality you are trying to achieve should be the function "IsMinorCiv".
 
This doesn't seem to work at all. Not really sure what I'm doing since I'm really new to LUA, and have just patched most of this together from other sources.

Code:
function DummyTrade(playerID)

	local player = Players[playerID];
	if not IsMajorCiv(player) then return 
	end

	local leaderID = GameInfo.Leaders[player:GetLeaderType()].ID;
	if leaderID == GameInfo.Leaders["LEADER_STADTRADT"].ID then
		local iBuilding = GameInfo.Buildings[BUILDING_ULMDUMMY].ID;
		local city = player:GetCapitalCity();
		
		if city ~= nil then
			city:SetNumRealBuilding(iBuilding, tr);
		end
	end
end

GameEvents.PlayerDoTurn.Add(DummyTrade)



  • When you are trying to limit the function to only running for major civilizations, you would normally want:

    Code:
    if player:IsMinorCiv() then return end
    if player:IsBarbarian() then return end
  • You can combine the two conditions "player:IsMinorCiv()" and "player:IsBarbarian()" into a single "if .... then .... end" chunk of code using an "or", but for simplicity it is sometimes easier to read your own code by not trying to combine too much stuff all in one block of code.
  • The method you are using:

    Code:
    local tr = Player.GetTradeRoutes();
    Is going to give you all the information about the player's trade routes, but not directly the number of trade routes the player has. Plus, "Player" is not the same as "player", so that line in your code will give an error (probably one saying you are trying to index a global that is currently "nil"). "player" has been defined, but "Player" has not. Download JFD's Churchill as leader of England mod and take a look at his lua. He is making use of the GetTradeRoutes() command.
    If you change that line to:
    Code:
    local tr = player:GetTradeRoutes();
    "tr" will be an lua table holding all the info about the player's trade routes, but not an integer value.
  • Since CIV5 limits one (1) civ can only have one (1) leader, I would simply use the civilization itself as the limiter for when the code should run, rather than the leader, as you are attempting to do. I would re-draft the upper portion of your code as follows:
    Code:
    iBuilding = GameInfoTypes.BUILDING_ULMDUMMY
    iRequiredCiv = GameInfoTypes.CIVILIZATION_ROME	--simply change from CIVILIZATION_ROME to the correct civilization name
    
    function DummyTrade(playerID)
    	local player = Players[playerID];
    	if not player:IsAlive() then return end
    	if player:GetCivilizationType() ~= iRequiredCiv then return end
    	local city = player:GetCapitalCity();
    
    	--NOTHING MUCH CHANGED BELOW EXCEPT TO FIX THE player vs Player PROBLEM
    	local tr = player:GetTradeRoutes();
    	if city ~= nil then
    		city:SetNumRealBuilding(iBuilding, tr);
    	end
    
    end
    
    GameEvents.PlayerDoTurn.Add(DummyTrade)
    • use of "GameInfoTypes" in the way shown will auto-recognize that the building name as given (BUILDING_ULMDUMMY) is contained within the <Buildings> XML/SQL table and has a unique ID #. The ID # will be thrown into the variable named "iBuilding"
    • the same will be true for the way "GameInfoTypes" functions with the use of a civilization name (CIVILIZATION_ROME). The game will auto-recognize it is a civilization name in the XML/SQL, and will stick its correct ID # into variable "iRequiredCiv"
    • this works both for "stock" Firaxis-made game elements that have a unique ID #, as well as all mod-added elements (such as a building or a unit or a civilization) that fit into game tables that have/require a unique "Type" and "ID".
    • by moving the two lines out of the function and placing them above it, the game will only have to search-out the ID #s once (when the mod gets loaded into the game), and not on every single player turn. Any function contained within the same "xxxx.lua" can also reference the exact same variable names and will get the exact same data for them.
 
Thanks for all the help! I'll look into it now and hopefully be able to get it working
 

;)

If a person is using lua to run game logic in a roundabout method to achieve an effect that could be done straight in C++, then I'd think it's a safe to make the assumption that they have not modded the DLL to make the lua hook.

Alternatively, if the DLL they were using had that function predefined, I'd expect them to at least make a passing reference / allusion to the fact (that they were using a custom DLL).
 
If you change that line to:
Code:
local tr = player:GetTradeRoutes();
"tr" will be an lua table holding all the info about the player's trade routes, but not an integer value.

You'll need to use #tr to get the actual number of trade routes from the table that GetTradeRoutes returns.

Code:
city:SetNumRealBuilding(iBuilding, #tr);
 
You'll need to use #tr to get the actual number of trade routes from the table that GetTradeRoutes returns.

Code:
city:SetNumRealBuilding(iBuilding, #tr);
Yeah, I hadn't had a chance to think through whether directly using the '#' for table length would work in all cases because I wasn't sure how the trade routes are "inserted" into the table, sequentially or otherwise.
 
Yeah, I hadn't had a chance to think through whether directly using the '#' for table length would work in all cases because I wasn't sure how the trade routes are "inserted" into the table, sequentially or otherwise.

I've been using

Code:
local tIncomingTR =  pPlayer:GetTradeRoutesToYou()
local iNumTR = #tIncomingTR

for one of my own mods and it appears to work, although my testing hasn't been that comprehensive. I'm guessing GetTradeRoutes should work if GetTradeRoutesToYou seems to.
 
Back
Top Bottom