A (maybe) quick question about population and tech dependency

AW Arcaeca

Deus Vult
Joined
Mar 10, 2013
Messages
3,019
Location
Operation Padlock ground zero
I'm looking for a way to give a new civ +2 production and +1 gold in all cities with 10 or more population after electronics. And almost all of that can be done with just XML... except for the part about needing 10 population, as far as I know.

Given that, I'm looking for a way to give a dummy building to those 10-pop cities using as little Lua as possible, though it looks like I'll need some.

So would this code work at all?
Code:
function NewCivProductionBonus
	local pPlayer = players[playerID]
	if (pPlayer:IsAlive()) and (pPlayer:GetCivilization() == GameInfoTypes.CIVILIZATION_THIS_CIV) then
		local pCity = pPlayer:GetCities()
		local pCityPop = pCity:GetPopulation()
		if (pCityPop >= 10) and (pPlayer:IsHasTech(GameInfoTypes.TECH_ELECTRONICS)) then
			pCity:SetNumRealBuilding(GameInfoTypes.BUILDING_THIS_CIV_BONUS, 1)
		else
			pCity:SetNumRealBuilding(GameInfoTypes.BUILDING_THIS_CIV_BONUS, 0)
		end
	end
Events.ActivePlayerTurnStart.Add(NewCivProductionBonus)
What I'm guessing is the main problem is the line that says
Code:
if (pCityPop >= 10) and (pPlayer:IsHasTech(GameInfoTypes.TECH_ELECTRONICS)) then
since doesn't that function, IIRC, only work with a team, not a player?
 
Code:
function NewCivProductionBonus(playerID)
	local pPlayer = Players[playerID]
	if (pPlayer:IsAlive()) and (pPlayer:GetCivilizationType() == GameInfoTypes.CIVILIZATION_THIS_CIV) then
		for pCity in pPlayer:Cities() do
	  	    local pCityPop = pCity:GetPopulation()
	  	    if (pCityPop >= 10) and (Teams[pPlayer:GetTeam()]:IsHasTech(GameInfoTypes.TECH_ELECTRONICS)) then
		  	pCity:SetNumRealBuilding(GameInfoTypes.BUILDING_THIS_CIV_BONUS, 1)
		  else
		  	pCity:SetNumRealBuilding(GameInfoTypes.BUILDING_THIS_CIV_BONUS, 0)
		  end
             end
	end
GameEvents.PlayerDoTurn.Add(NewCivProductionBonus)

Notes:

1. Changed the hook to GameEvents.PlayerDoTurn. Events.ActivePlayerTurnStart only fires on the human player's turn, and you most likely want your trait to work if the AI controls your civ as well.

2. Make sure that you have the arguments that need to be passed to the function in parentheses after the function name. In this case, you'd need the player ID to determine pPlayer, so I added playerID after the function name. PlayerDoTurn passes this to the function.

3. To iterate over each city, you need to have a for loop as shown in the code.

4. IsHasTech() is a Team function rather than a Player function, so pPlayer:IsHasTech() would cause an error. The easiest way to find a player's tech is Teams[pPlayer:GetTeam()]:IsHasTech().

Hope this helps!
 
It does help, thanks!
So knowing that, I was also looking for a way to give a new civ's UU a promotion after researching Radar, but seeing as how the promotions table doesn't seem to have a <PrereqTech> column, it seems that I'll probably need to use lua for that too...

So then this should work?
Code:
function NewCivUUCombatBonus(playerID)
	local pPlayer = Players[playerID]
	if (pPlayer:IsAlive()) and (pPlayer:GetCivilizationType() == GameInfoTypes.CIVILIZATION_THIS_CIV) then
		for pUnit in pPlayer:GetUnits() do
		if (pUnit:GetUnitType() == GameInfoTypes.UNIT_THIS_UNIT) and (Teams[pPlayer:GetTeam()].IsHasTech(GameInfoTypes.TECH_RADAR)) then
			pUnit:SetHasPromotion(GameInfoTypes.PROMOTION_THIS_PROMOTION, true)
		else
			pUnit:SetHasPromotion(GameInfoTypes.PROMOTION_THIS_PROMOTION, false)
		end
	end
GameEvents.PlayerDoTurn.Add(NewCivUUCombatBonus)
A couple of notes:
I made sure to use pPlayer:GetTeam and GameEvents.PlayerDoTurn.Add, as you suggested. But what I don't get about the iterator is that seemingly, after looking through your code that using a "for" loop doesn't require a "local" first. Is that right?
 
Vicevirtuoso, for whatever reason the code you posted didn't work, even with VFS=false and an InGameUIAddin entry. Does it really need
Code:
local pCity = pPlayer:GetCities()
in there after all, or is that just my random guessing?

EDIT: Well, then again, my own code to add the promotion didn't work either...
 
Vicevirtuoso, for whatever reason the code you posted didn't work, even with VFS=false and an InGameUIAddin entry. Does it really need
Code:
local pCity = pPlayer:GetCities()
in there after all, or is that just my random guessing?

Admittedly, I didn't plug the own code into Civ itself to verify it works, but I'm not seeing the error just by reading over it.

I do know that you don't need to define a local for pCity before the loop. Using a for loop automatically defines the variable for the duration of the loop.

Do you have Firetuner running? See if there are any error messages in it when your game cycles through turns.
 
Do you have Firetuner running? See if there are any error messages in it when your game cycles through turns.
Firetuner works, but I don't have the slightest idea how to use it...
 
Just have it running while the game runs. Keep the "Lua Console" tab open, and if there are errors in a Lua script, the console will print an italicized line beginning with "Syntax error" or "Runtime error".
 
Nothing showed up in Firetuner (assuming I set it up correctly) but the dummy building still doesn't show up either.
 
Put this before the rest of the code, outside of any functions. The text in parentheses will show up in the Lua Console if your script loads successfully.

Code:
print("AgressiveWimp's script loaded successfully")

If you don't see it, you don't have it properly loading through the mod properties. If it is showing up without errors and this message prints, you may need to double check to see if there are any spelling errors with the entries for your civilization and building.
 
Text didn't show up, so I guess that means the mod properties aren't working correctly?
And I'm assuming I don't need to be worrying about panels, so all I'm doing is the lua console is open while the mod is active.

So how exactly do I make the lua "load properly through the mod properties"?
If it helps, the mod is attached:
 
Check lua.log, both files have syntax errors (missing end statements at the very least)
 
Well, according to the lua.log the problem was in both lua files I was missing an "end" statement. (as whoward69 said)
Still, neither file works, even after fixing that...
Firetuner still doesn't work, I can't find any spelling errors, no syntax errors from the lua.log (anymore)... What else could it be?
 
All I could think of that might be the problem is this line:
Code:
for pCity in pPlayer:Cities() do
where my random guess is it should actually be:
Code:
for pCity in pPlayer:[B][Color="Blue"]Get[/COLOR][/B]Cities() do
But that didn't work either. :(

On the bright side, I found the print statements in the lua.log, so at least it's doing something. But it's still not working, and I can't think of anything else to do.

The coding currently used:
Spoiler UA Bonus :
Code:
print("Taiwan Bonus LUA loaded successfully.")
function TaiwanProductionBonus(playerID)
	local pPlayer = Players[playerID]
	if (pPlayer:IsAlive()) and (pPlayer:GetCivilizationType() == GameInfoTypes.CIVILIZATION_TAIWAN) then
		for pCity in pPlayer:GetCities() do
	  	    local pCityPop = pCity:GetPopulation()
	  	    if (pCityPop >= 10) and (Teams[pPlayer:GetTeam()]:IsHasTech(GameInfoTypes.TECH_ELECTRONICS)) then
		  		pCity:SetNumRealBuilding(GameInfoTypes.BUILDING_TAIWAN_BONUS, 1)
			 else
				pCity:SetNumRealBuilding(GameInfoTypes.BUILDING_TAIWAN_BONUS, 0)
			 end
                 end
	end
end
GameEvents.PlayerDoTurn.Add(TaiwanProductionBonus)
Spoiler UU Free Promotion :
Code:
print("Kang Ding Class Frigate Bonus LUA loaded successfully.")
function TaiwanKangDingCombatBonus(playerID)
	local pPlayer = Players[playerID]
	if (pPlayer:IsAlive()) and (pPlayer:GetCivilizationType() == GameInfoTypes.CIVILIZATION_TAIWAN) then
		for pUnit in pPlayer:GetUnits() do
			if (pUnit:GetUnitType() == GameInfoTypes.UNIT_KANG_DING) and (Teams[pPlayer:GetTeam()].IsHasTech(GameInfoTypes.TECH_RADAR)) then
				pUnit:SetHasPromotion(GameInfoTypes.PROMOTION_KANG_DING, true)
			else
				pUnit:SetHasPromotion(GameInfoTypes.PROMOTION_KANG_DING, false)
			end
		end
	end
end
GameEvents.PlayerDoTurn.Add(TaiwanKangDingCombatBonus)
 
Okay, I finally got around to downloading and looking at the code like I should have earlier. This is based off of the file you uploaded, so of course won't be accounting for any changes you've made to it since then.

In TaiwanKangDingCombatBonus.lua:
  • You need two additional "end" statements before the GameEvents call
  • Before the IsHasTech function call, there should be a colon ( : ) instead of a period ( . )

In TaiwanProductionBonus.lua:
  • You need one additional "end" statement before the GameEvents call

Doing this made the code work for me, though it's currently giving a Floating Gardens since BUILDING_TAIWAN_BONUS is not defined yet. Also, PROMOTION_KANG_DING is showing the title and text of the Insta Heal promotion, though I'm assuming that's just placeholder info.
 
Okay, I finally got around to downloading and looking at the code like I should have earlier. This is based off of the file you uploaded, so of course won't be accounting for any changes you've made to it since then.

In TaiwanKangDingCombatBonus.lua:
  • You need two additional "end" statements before the GameEvents call
  • Before the IsHasTech function call, there should be a colon ( : ) instead of a period ( . )

In TaiwanProductionBonus.lua:
  • You need one additional "end" statement before the GameEvents call

Doing this made the code work for me, though it's currently giving a Floating Gardens since BUILDING_TAIWAN_BONUS is not defined yet. Also, PROMOTION_KANG_DING is showing the title and text of the Insta Heal promotion, though I'm assuming that's just placeholder info.

Okay, so I fixed the "end" errors, but a couple of notes:

1) I'm not seeing a period anywhere in line 11 of TaiwanProductionBonus.lua (the IsHasTech line), except in GameInfoTypes.TECH_ELECTRONICS, which is actually after the IsHasTech function, so I'm not sure what you're talking about there...

2) I have no idea why it's giving floating gardens, since BUILDING_TAIWAN_BONUS is defined in AW's Taiwan Mod > XML > Buildings > TaiwanDummyBuilding.xml

3) And lastly, the text references for PROMOTION_KANG_DING aren't placeholders, I just haven't gotten around to writing the text for them.
 
1) I'm not seeing a period anywhere in line 11 of TaiwanProductionBonus.lua (the IsHasTech line), except in GameInfoTypes.TECH_ELECTRONICS, which is actually after the IsHasTech function, so I'm not sure what you're talking about there...
This error is in the TaiwanKangDingCombatBonus.lua file, not the production bonus one. (Where you pass GameInfoTypes.TECH_RADAR into the function.)
 
This error is in the TaiwanKangDingCombatBonus.lua file, not the production bonus one. (Where you pass GameInfoTypes.TECH_RADAR into the function.)

Oh.

So I changed the period to a colon but the building still doesn't show up - not even floating gardens.

Updated coding:
Spoiler TaiwanProductionBonus.lua :
Code:
-- TawianProductionBonus
-- Author: Vicevirtuoso
-- DateCreated: 12/25/2013 9:35:52 AM
--------------------------------------------------------------
print("Taiwan Bonus LUA loaded successfully.")
function TaiwanProductionBonus(playerID)
	local pPlayer = Players[playerID]
	if (pPlayer:IsAlive()) and (pPlayer:GetCivilizationType() == GameInfoTypes.CIVILIZATION_TAIWAN) then
		for pCity in pPlayer:GetCities() do
	  	    local pCityPop = pCity:GetPopulation()
	  	    if (pCityPop >= 10) and (Teams[pPlayer:GetTeam()]:IsHasTech(GameInfoTypes.TECH_ELECTRONICS)) then
		  		pCity:SetNumRealBuilding(GameInfoTypes.BUILDING_TAIWAN_BONUS, 1)
			 else
				pCity:SetNumRealBuilding(GameInfoTypes.BUILDING_TAIWAN_BONUS, 0)
			 end
         end
	end
end
GameEvents.PlayerDoTurn.Add(TaiwanProductionBonus)

Spoiler TaiwanKangDingCombatBonus :
Code:
-- TaiwanKangDingCombatBonus
-- Author: Me, AW
-- DateCreated: 12/25/2013 9:37:25 AM
--------------------------------------------------------------
print("Kang Ding Class Frigate Bonus LUA loaded successfully.")
function TaiwanKangDingCombatBonus(playerID)
	local pPlayer = Players[playerID]
	if (pPlayer:IsAlive()) and (pPlayer:GetCivilizationType() == GameInfoTypes.CIVILIZATION_TAIWAN) then
		for pUnit in pPlayer:GetUnits() do
			if (pUnit:GetUnitType() == GameInfoTypes.UNIT_KANG_DING) and (Teams[pPlayer:GetTeam()]:IsHasTech(GameInfoTypes.TECH_RADAR)) then
				pUnit:SetHasPromotion(GameInfoTypes.PROMOTION_KANG_DING, true)
			else
				pUnit:SetHasPromotion(GameInfoTypes.PROMOTION_KANG_DING, false)
			end
		end
	end
end
GameEvents.PlayerDoTurn.Add(TaiwanKangDingCombatBonus)
 
Only one thing wrong with your coding now -- forgot to mention this in the last post. But yeah, the iterators are Cities() and Units(), not GetCities() or GetUnits(). Putting in GetCities() gives an error.

Code:
 Runtime Error: C:\Users\<redacted>\Documents\My Games\Sid Meier's Civilization 5\MODS\AW's Taiwanese Republic Mod (v 1)\LUA/TawianProductionBonus.lua:9: attempt to call method 'GetCities' (a nil value)
stack traceback:
	C:\Users\<redacted>\Documents\My Games\Sid Meier's Civilization 5\MODS\AW's Taiwanese Republic Mod (v 1)\LUA/TawianProductionBonus.lua:9: in function <C:\Users\<redacted>\Documents\My Games\Sid Meier's Civilization 5\MODS\AW's Taiwanese Republic Mod (v 1)\LUA/TawianProductionBonus.lua:6>


Edit: Did forget to mention that BUILDING_TAIWAN_BONUS isn't showing up in the FireTuner buildings list under Selected City, so something's up with it, at least in the version you uploaded.
 
Well... I got the floating gardens to appear, so I guess the lua works.
But I still have no idea why floating gardens appear instead of the dummy building, and the free promotion for the UU still shows up as "Heal instantly", for whatever reason.

The building type is typed in correctly in the lua and the building file, so the spelling must not be an issue...

Anyway, the newest version:
 
Back
Top Bottom