Golden Age Points for Exporting Luxuries

Reedstilt

Prince
Joined
May 8, 2013
Messages
434
I'm working on a Wonder and I can't get the lua to work right (I'm pretty sure I misunderstood the advice I was initially given).

The goal of the Wonder is to provide Golden Age Points for each copy of a Luxury resource traded away. Let's say 4 Golden Age Points per copy. If anyone has any advice / is feeling generous enough to code it, I'd greatly appreciate either.
 
Untested, but should work

Code:
local iGoldenWonder = GameInfoTypes.BUILDING_NEUSCHWANSTEIN
local iGoldenMultiplier = 4

local pGoldenWonderPlot = nil

function [COLOR="DeepSkyBlue"][B]OnGoldenWonderPlayerDoTurn[/B][/COLOR](iPlayer)
    if (iPlayer == GameDefines.MAX_CIV_PLAYERS-1) then
        -- This is the Barbarian's turn (ie the end of the round), so grant the GA points to whomever controls the Golden Wonder
        if (pGoldenWonderPlot) then
            local pGoldenWonderCity = pGoldenWonderPlot:GetPlotCity()
        
            if (pGoldenWonderCity) then
                if (pGoldenWonderCity:IsHasBuilding(iGoldenWonder)) then
                    local iGolderOwner = pGoldenWonderCity:GetOwner()
                    
                    if (iGolderOwner < GameDefines.MAX_MAJOR_CIVS) then
                        local pGoldenOwner = Players[iGolderOwner]
                        
                        -- Typically you don't accrue GA points during a Golden Age
                        if (not pGoldenOwner:IsGoldenAge()) then
                            local iExportedLux = 0
                        
                            for pResource in GameInfo.Resources() do
                                local iResource = pResource.ID

                                if (Game.GetResourceUsageType(iResource) == ResourceUsageTypes.RESOURCEUSAGE_LUXURY) then
                                    if (pGoldenOwner:GetNumResourceAvailable(iResource, true) > 0) then
                                        -- If you only want to count the number of luxury TYPES exported and not the total number of exports, make the next line "+ 1"
                                        iExportedLux = iExportedLux + pGoldenOwner:GetResourceExport(iResource)
                                    end
                                end
                            end
                            
                            pGoldenOwner:ChangeGoldenAgeProgressMeter(iExportedLux * iGoldenMultiplier)
                        end
                    else
                        -- The Golden Wonder is currently controlled by a City State
                    end
                else
                    -- This can happen if a city is razed on the plot and another immediately founded
                    GameEvents.PlayerDoTurn.Remove(OnGoldenWonderPlayerDoTurn)
                end
            else
                -- The city on this plot has been razed; the Wonder has been destroyed
                GameEvents.PlayerDoTurn.Remove(OnGoldenWonderPlayerDoTurn)
            end
        else
            -- This should never happen
            GameEvents.PlayerDoTurn.Remove(OnGoldenWonderPlayerDoTurn)
        end
    end
end

function [COLOR="Green"][B]OnCityConstructed[/B][/COLOR](iPlayer, iCity, iBuilding)
    if (iBuilding == iGoldenWonder) then
        -- We want the plot and not the city, as the city could change hands
        pGoldenWonderPlot = Players[iPlayer]:GetCityByID(iCity):Plot()
        
        -- Don't need to watch for the Golden Wonder being built any more
        GameEvents.CityConstructed.Remove(OnCityConstructed)
    end
end
GameEvents.CityConstructed.Add(OnCityConstructed)

-- If loading a game, we need to find the Golden Wonder
function FindGoldenWonder()
    for iPlayer = 0, GameDefines.MAX_CIV_PLAYERS-2, 1 do -- -2 as the Barbies will never have it!
        local pPlayer = Players[iPlayer]
        
        if (pPlayer:IsAlive()) then
            for pCity in pPlayer:Cities() do
                if (pCity:IsHasBuilding(iGoldenWonder)) then
                    -- Remember the plot it's in
                    pGoldenWonderPlot = pCity:Plot()

                    GameEvents.[COLOR="Magenta"][B]PlayerDoTurn[/B][/COLOR].Add(OnGoldenWonderPlayerDoTurn)

                    -- Don't need to watch for the Golden Wonder being built any more
                    GameEvents.CityConstructed.Remove(OnCityConstructed)
                    return
                end
            end
        end
    end
end

FindGoldenWonder()

We hook the (new) CityConstructed event to detect the required Golden Wonder (defined as iGoldenWonder at the top, change that to whatever you want) being built in a city, and use that to install a PlayerDoTurn event handler to do the real work

The OnGoldenWonderPlayerDoTurn event handler waits until the Barbarian's turn (ie the end of the round) and then checks for the Golden Wonder still being in existence and controlled by a major. If we tested at the beginning of every turn, players in a team could exploit the wonder by trading the city back and forth between themselves. GameEvents.PlayerDoTurn.Add(OnGoldenWonderPlayerDoTurn)



If the wonder is controlled by a major, and that major is not already in a Golden Age (typically GA points don't accrue during a Golden Age), we count how many luxuries are being exported, multiply that by iGoldenMultiplier (defined at the top) and grant the controlling player that many GA points

Edit: And the bit I forgot, on loading a game, we'll need to find the Golden Wonder if already constructed

Simples!
 
Thanks for the help, whoward. Unfortunately, it doesn't seem to be working when I tried it out. May be an issue with one my end. Pretty sure, I updated the files correctly, but I'll have to double check that later.
 
Anything in Lua.log?

Set as an InGameUIAddin?

You changed BUILDING_NEUSCHWANSTEIN to something else?

Failing that, attach the mod
 
Anything in Lua.log?

Set as an InGameUIAddin?

You changed BUILDING_NEUSCHWANSTEIN to something else?

Failing that, attach the mod

It was just a quick test to see if it was working or not, so I didn't bother turning on the log at the time. As for the other two questions, yes to both. Since it might be day or so before I get a chance to sit down an tinker with it again, here's a link to the mod.
 
That's not the mod, that's the Visual Studio project file ;)
 
Zip the mod and attach it (see 3rd link in my sig) as my anti-virus software is detecting a virus either in the upload or from the download site
 
I think William forgot to add the PlayerDoTurn in FindGoldenWonder so the every-turn event won't run if a saved game is loaded and the wonder has already been constructed.

[edit] I just ran the mod in a quick test and don't see syntax lua errors or database errors. But I did not set-up the conditions to test whether the code gets run-time errors or such.

[edit-edit] I just added a print confirmation line at the bottom of your lua file and the line I set to make the code print to the lua log is appearing correctly. Just confirms that the structure of the mod itself looks and functions OK. I also don't see any mismatch issues between what the wonder's Building <Type> is and what you are referencing in the 1st line of the lua -- I've made that goof more times than I care to remember.
 
Corrected and tested
Code:
local iGoldenWonder = GameInfoTypes.BUILDING_PUEBLO_BONITO
local iGoldenMultiplier = 4

local pGoldenWonderPlot = nil

function OnGoldenWonderPlayerDoTurn(iPlayer)
    if (iPlayer == GameDefines.MAX_PLAYERS-1) then
        -- This is the Barbarian's turn (ie the end of the round), so grant the GA points to whomever controls the Golden Wonder
        if (pGoldenWonderPlot) then
            local pGoldenWonderCity = pGoldenWonderPlot:GetPlotCity()
        
            if (pGoldenWonderCity) then
                if (pGoldenWonderCity:IsHasBuilding(iGoldenWonder)) then
                    local iGolderOwner = pGoldenWonderCity:GetOwner()
                    
                    if (iGolderOwner < GameDefines.MAX_MAJOR_CIVS) then
                        local pGoldenOwner = Players[iGolderOwner]
                        
                        -- Typically you don't accrue GA points during a Golden Age
                        if (not pGoldenOwner:IsGoldenAge()) then
                            local iExportedLux = 0
                        
                            for pResource in GameInfo.Resources() do
                                local iResource = pResource.ID

                                if (Game.GetResourceUsageType(iResource) == ResourceUsageTypes.RESOURCEUSAGE_LUXURY) then
                                    if (pGoldenOwner:GetNumResourceAvailable(iResource, true) > 0) then
                                        -- If you only want to count the number of luxury TYPES exported and not the total number of exports, make the next line "+ 1"
                                        iExportedLux = iExportedLux + pGoldenOwner:GetResourceExport(iResource)
                                    end
                                end
                            end
                            
                            pGoldenOwner:ChangeGoldenAgeProgressMeter(iExportedLux * iGoldenMultiplier)
                        end
                    else
                        -- The Golden Wonder is currently controlled by a City State
                    end
                else
                    -- This can happen if a city is razed on the plot and another immediately founded
                    GameEvents.PlayerDoTurn.Remove(OnGoldenWonderPlayerDoTurn)
                end
            else
                -- The city on this plot has been razed; the Wonder has been destroyed
                GameEvents.PlayerDoTurn.Remove(OnGoldenWonderPlayerDoTurn)
            end
        else
            -- Should never happen
            GameEvents.PlayerDoTurn.Remove(OnGoldenWonderPlayerDoTurn)
        end
    end
end

function OnCityConstructed(iPlayer, iCity, iBuilding)
    if (iBuilding == iGoldenWonder) then
        -- Don't need to watch for the Golden Wonder being built any more
        GameEvents.CityConstructed.Remove(OnCityConstructed)

        -- We want the plot and not the city, as the city could change hands
        pGoldenWonderPlot = Players[iPlayer]:GetCityByID(iCity):Plot()
        
        GameEvents.PlayerDoTurn.Add(OnGoldenWonderPlayerDoTurn)
    end
end
GameEvents.CityConstructed.Add(OnCityConstructed)

-- If loading a game, we need to find the Golden Wonder
function FindGoldenWonder()
    for iPlayer = 0, GameDefines.MAX_PLAYERS-2, 1 do -- -2 as the Barbies will never have it!
        local pPlayer = Players[iPlayer]
        
        if (pPlayer:IsAlive()) then
            for pCity in pPlayer:Cities() do
                if (pCity:IsHasBuilding(iGoldenWonder)) then
                    -- Don't need to watch for the Golden Wonder being built any more
                    GameEvents.CityConstructed.Remove(OnCityConstructed)

                    -- Remember the plot it's in
                    pGoldenWonderPlot = pCity:Plot()
                    print(string.format("Found the Golden Wonder in %s", pCity:GetName()))

                    GameEvents.PlayerDoTurn.Add(OnGoldenWonderPlayerDoTurn)
                    return
                end
            end
        end
    end
end

FindGoldenWonder()
 
I put in the revised lua and it's working perfectly now. Thanks for all the help, whoward! I should be releasing the wonder in a day or two. Just got one more to finish in the set, but it's an easy one.
 
Back
Top Bottom