Changing city yield dynamically with LUA

Archi

Chieftain
Joined
Sep 12, 2015
Messages
5
Hello, I've been trying to create my own mod but I simply can't find a way to change city yield dynamically. What I want to achieve is to make a city give 1 faith per 2 population. I had something like this that worked:

function FaithPerPop(pPlayer)
print("Function Loaded")
for pCity in pPlayer:Cities() do
local pPop = pCity:GetPopulation();
if (pPop >= 2) then
print("Pop is bigger or equal 2")
local x = pCity:Plot():GetX();
local y = pCity:Plot():GetY();
Game.SetPlotExtraYield(x, y, YieldTypes.YIELD_FAITH, pPop/2)
end
end
end

Problem here is that it kept increasing the faith on the city tile by pPop/2 every single turn. Also I am not sure this is the best way to do this since there is no indication that the faith changed because the civs unique trait. Any ideas how to do this? :)
 
So I've tried your idea with Player.ChangeFaith and it does work :3 though the link on the other thread doesn't seem to work anymore sadly so I will have to find another way to add something to the top panel :) But many thanks for your reply it did help me ^^
 
You could also add dummy buildings to the city. Each dummy building should provide +1 Faith, and you would set the number of buildings in the city equal to the Population of the city divided by 2 and rounded down.
 
Nice idea :) One problem though I find with lua is that when I divide two intergers it seem to round up, ie: 3/2 gives 2 is there a way that I can force it to round down or should I convert to decimal, divide and round down and convert to integers again?
 
One problem though I find with lua is that when I divide two intergers it seem to round up, ie: 3/2 gives 2 is there a way that I can force it to round down or should I convert to decimal, divide and round down and convert to integers again?
Lua isn't doing the rounding, CiV is, when you pass your values and it expects integers. Lua's "number" type will go from an int to a float automatically behind the scenes. Normal division in Lua (a/b) is float division. You can use 2 slashes for floor division (a//b).
 
Lua isn't doing the rounding, CiV is, when you pass your values and it expects integers. Lua's "number" type will automatically go from an int to a float automatically behind the scenes. Normal division in Lua (a/b) is float division. You can use 2 slashes for floor division (a//b).

I did not realize there was a shortcut instead of math.floor(a/b)

I suppose I should go back and re-read the info on available lua math operators.
 
I've been looking through the civ 5 lua reference manual and I can't seem to find a function that adds a specific building to the city, also is it possible to add multiple of the same building to accomplish the "dummy building" solution as mentioned in a earlier comment? :)
 
pCity:SetNumRealBuilding(iBuildingID, iNumberBuildingToSet)

iBuildingID and iNumberBuildingToSet are variables in this example.
  • iBuildingID needs to be the ID# of the building as established in the game's database.
    • While you can directly state the ID# of a building if you know what it is, this is not generally a good idea since for buildings added via a mod, the ID# of the building assigned by the game for any one user will vary depending upon how many other mods add buildings, and in which order these mods are loaded into the game's database.
    • Stating this local iBuildingID = GameInfoTypes.BUILDING_SOMETHING_OR_OTHER will grab that ID# for the stated building and stick it into variable iBuildingID
  • iNumberBuildingToSet is just the integer number of how many copies of the building are needed.

So any of these methods will work for adding some number of BUILDING_SOMETHING_OR_OTHER into a city:
  1. Hard-Coded (and assuming the game-assigned ID of the building is "214" and 12 copies of the building are required):
    Code:
    pCity:SetNumRealBuilding(214, 12)
  2. Grabbing the ID# directly within the SetNumRealBuilding command and adding 12 copies of the building:
    Code:
    pCity:SetNumRealBuilding(GameInfoTypes.BUILDING_SOMETHING_OR_OTHER, 12)
  3. 'Caching' the ID# into a local variable, and adding 12 copies of the building to a city:
    Code:
    local iBuildingID = GameInfoTypes.BUILDING_SOMETHING_OR_OTHER
    
    pCity:SetNumRealBuilding(iBuildingID, 12)
  4. 'Caching' the ID# into a local variable, and adding copies of the building to a city based on whatever integer value is currently within variable iNumberBuildingToSet:
    Code:
    local iBuildingID = GameInfoTypes.BUILDING_SOMETHING_OR_OTHER
    
    pCity:SetNumRealBuilding(iBuildingID, iNumberBuildingToSet)
  5. Removing all copies of the building from the city:
    Code:
    local iBuildingID = GameInfoTypes.BUILDING_SOMETHING_OR_OTHER
    
    pCity:SetNumRealBuilding(iBuildingID, 0)
You would place this within your for pCity in pPlayer:Cities() do loop, except that if you 'Cache' the ID# of the building you should do this before the loop is even activated because otherwise there would little point to 'Caching' the ID#.
Code:
local iBuildingID = GameInfoTypes.BUILDING_SOMETHING_OR_OTHER
local iDesiredPopDivisor = 2

function FaithPerPop(pPlayer)
	print("Function Loaded")
	for pCity in pPlayer:Cities() do
		local iPop = pCity:GetPopulation()
		if (iPop >= iDesiredPopDivisor) then
			print("Pop of " .. pCity:GetName() .. " is greater than " .. iDesiredPopDivisor .. " and was " .. iPop)
			pCity:SetNumRealBuilding(iBuildingID, math.floor(iPop/iDesiredPopDivisor))
		else print("Pop of " .. pCity:GetName() .. " is not greater than " .. iDesiredPopDivisor .. " and was " .. iPop)
			pCity:SetNumRealBuilding(iBuildingID, 0)
		end
	end
end
 
Back
Top Bottom