Reveal Map with Dummy Building?

TheOneHitPupper

Chieftain
Joined
Jun 15, 2017
Messages
98
I'm trying to incorporate a custom league resolution for an overhaul mod I'm working on. The idea of this custom resolution is to act as if all players researched the Satellites tech and the map is revealed accordingly. I see two ways of doing this.

1. Make a dummy tech and set it to hidden from the Tech tree. Use "MapVisible" from the Technologies table and then write a .lua script to give it to a player when the dummy building is built.
2. Write a .lua script that uses the Plot:SetRevealed() method (found from this thread) and have it execute when the dummy building is built.

I'm trying my hand at writing the code for the 1st method. Here's what I have so far:
Code:
function GlobalTech(ownerId, cityId, buildingType, bGold, bFaithOrCulture)
    if buildingType == GameInfoTypes.BUILDING_GLOBAL_EXPLORATION then
        local pPlayer = Players[ownerId]
        local pTeam = Teams[pPlayer:GetTeam()]
        if not pTeam:IsHasTech(GameInfoTypes.TECH_GLOBAL_EXPLORATION) then
            pTeam:SetHasTech(GameInfoTypes.TECH_GLOBAL_EXPLORATION, true)
        end
    end
end
GameEvents.CityConstructed.Add(GlobalTech)

Doesn't seem to be executing correctly when I add the building in through IGE.

At this point, all I need is a script that gives the Tech_Global_Exploration to players with the Building_Global_Exploration built. Everything else seems to be working correctly. I've very little understanding on working with lua and have hit a brick wall here. Any help would be appreciated!
 
Last edited:
Add some print statements and check the logs to so if your code is being installed and called. Then if still not working, attach the complete mod - just makes it so much easier for others to debug
 
GameEvents.CityConstructed triggers only if City actually constructs the building - it will not fire upon SetNumRealBuilding (IGE is probably using it) or SetNumFreeBuilding.

SetRevealed() is better since it doesn't require "dummy" object.
Code:
for i, v in pairs(Players) do -- iterate through players
    if v:IsEverAlive() and (not v:IsMinorCiv()) then  -- checking if major is obtional
        iTeam = v:GetTeam();
        for i = 0, Map.GetNumPlots() - 1 do
            Map.GetPlotByIndex(i):SetPlotRevealed(iTeam);
        end
    end
end

I think i miss connection between adopting resolution and acquiring BUILDING_GLOBAL_EXPLORATION, can resolution grants buildings/allows construction? And it is the most important part: hooking upon resolution being adopted.
The way I would probably do it in lua, is to check on barbarian playerdoturn (or first player after barbarian - depends when resolution triggers) if league adopted "custom resolution" and then fire a reveal function + make it fire only once. There is access to leagues in lua, yet not so sure about resolutions.
 
Add some print statements and check the logs to so if your code is being installed and called. Then if still not working, attach the complete mod - just makes it so much easier for others to debug
Looks like the function is being called, but still having issues with detecting if the building is built. I'll attach the mod to this post.

GameEvents.CityConstructed triggers only if City actually constructs the building - it will not fire upon SetNumRealBuilding (IGE is probably using it) or SetNumFreeBuilding.

SetRevealed() is better since it doesn't require "dummy" object.
Code:
for i, v in pairs(Players) do -- iterate through players
    if v:IsEverAlive() and (not v:IsMinorCiv()) then  -- checking if major is obtional
        iTeam = v:GetTeam();
        for i = 0, Map.GetNumPlots() - 1 do
            Map.GetPlotByIndex(i):SetPlotRevealed(iTeam);
        end
    end
end

I think i miss connection between adopting resolution and acquiring BUILDING_GLOBAL_EXPLORATION, can resolution grants buildings/allows construction? And it is the most important part: hooking upon resolution being adopted.
The way I would probably do it in lua, is to check on barbarian playerdoturn (or first player after barbarian - depends when resolution triggers) if league adopted "custom resolution" and then fire a reveal function + make it fire only once. There is access to leagues in lua, yet not so sure about resolutions.
I'm not sure how resolution hooks work, but it seems like it'd be simpler to use a dummy building, since resolutions are able to grant free buildings natively. I'm just not sure how to get the Lua script to detect if a building is present in a city. I've changed the trigger for the function to GameEvents.PlayerDoTurn instead to reflect your input about IGE not detecting GameEvents.CityConstructed. Here's the new code, which can also be seen in the mod that I've attached.

Code:
function GlobalTech(ownerId, cityId, buildingType, bGold, bFaithOrCulture)
    print("LuaTest function loaded")
    local pPlayer = Players[ownerId]
    local pTeam = Teams[pPlayer:GetTeam()]
    if (pCity:GetNumBuildings(GameInfoTypes.BUILDING_GLOBAL_EXPLORATION ) > 0) then
        print("GE building detected")
        if not pTeam:IsHasTech(GameInfoTypes.TECH_GLOBAL_EXPLORATION) then
            pTeam:SetHasTech(GameInfoTypes.TECH_GLOBAL_EXPLORATION, true)
        end
    end
end
GameEvents.PlayerDoTurn.Add(GlobalTech)
 

Attachments

http://modiki.civfanatics.com/index.php?title=Lua_and_UI_Reference_(Civ5)
I don't think any in-game resolution includes "free building in all Cities", that's a waste. Ok, so the concept should work. PlayerDoTurn grants one variable: player's ID and fires at the "start" (not really but keep it simple) of turn of each player.

Code:
print("TheOneHitPupper resolution script loaded")
local bFired = false;
function DoGlobalRevealAllTeams()
    print("Detected resolution revealing terrain!")
    bFired = true;
    for ip,v in pairs(Players) do
        if v:IsEverAlive() and (not v:IsMinorCiv()) then
            local iTeam = v:GetTeam();
            for i = 0, Map.GetNumPlots() - 1 do
                if not Map.GetPlotByIndex(i):IsRevealed(iTeam) then
                    Map.GetPlotByIndex(i):SetRevealed(iTeam, true)
                end
            end 
        end
    end
end
function HasDummyBuildingAnyCity(iPlayer)
    for iCity in Players[iPlayer]:Cities() do
        return iCity:IsHasBuilding(GameInfoTypes.BUILDING_GLOBAL_EXPLORATION);
    end
    return false;
end
GameEvents.PlayerDoTurn.Add(function(iPlayer)
    if bFired then
        return
    end
    if HasDummyBuildingAnyCity(iPlayer) then
        DoGlobalRevealAllTeams()
    end
end)
This should also works with IGE (with turn of delay).
 
http://modiki.civfanatics.com/index.php?title=Lua_and_UI_Reference_(Civ5)
I don't think any in-game resolution includes "free building in all Cities", that's a waste. Ok, so the concept should work. PlayerDoTurn grants one variable: player's ID and fires at the "start" (not really but keep it simple) of turn of each player.

Code:
print("TheOneHitPupper resolution script loaded")
local bFired = false;
function DoGlobalRevealAllTeams()
    print("Detected resolution revealing terrain!")
    bFired = true;
    for ip,v in pairs(Players) do
        if v:IsEverAlive() and (not v:IsMinorCiv()) then
            local iTeam = v:GetTeam();
            for i = 0, Map.GetNumPlots() - 1 do
                if not Map.GetPlotByIndex(i):IsRevealed(iTeam) then
                    Map.GetPlotByIndex(i):SetRevealed(iTeam, true)
                end
            end
        end
    end
end
function HasDummyBuildingAnyCity(iPlayer)
    for iCity in Players[iPlayer]:Cities() do
        return iCity:IsHasBuilding(GameInfoTypes.BUILDING_GLOBAL_EXPLORATION);
    end
    return false;
end
GameEvents.PlayerDoTurn.Add(function(iPlayer)
    if bFired then
        return
    end
    if HasDummyBuildingAnyCity(iPlayer) then
        DoGlobalRevealAllTeams()
    end
end)
This should also works with IGE (with turn of delay).
The script works perfectly! I cannot thank you enough! I'll be sure to credit you when I release my overhaul mod soon :D
 
Last edited:
Player:CountNumBuildings(iBuildingID)

You don't need execution through all a player's cities looking for whether it has the building.
Code:
GameEvents.PlayerDoTurn.Add(function(iPlayer)
    if bFired then
        return
    end
    if (Players[iPlayer]:CountNumBuildings(GameInfoTypes.BUILDING_GLOBAL_EXPLORATION) > 0) then
        DoGlobalRevealAllTeams()
    end
end)
Function "HasDummyBuildingAnyCity(iPlayer)" isn't really needed.
 
Player:CountNumBuildings(iBuildingID)

You don't need execution through all a player's cities looking for whether it has the building.
Code:
GameEvents.PlayerDoTurn.Add(function(iPlayer)
    if bFired then
        return
    end
    if (Players[iPlayer]:CountNumBuildings(GameInfoTypes.BUILDING_GLOBAL_EXPLORATION) > 0) then
        DoGlobalRevealAllTeams()
    end
end)
Function "HasDummyBuildingAnyCity(iPlayer)" isn't really needed.
I love the simplicity. Code looks good, thanks for the post! If anyone needs it, the whole script looks like this:

Code:
print("TheOneHitPupper resolution script loaded")
local bFired = false;
function DoGlobalRevealAllTeams()
    print("Detected resolution revealing terrain!")
    bFired = true;
    for ip,v in pairs(Players) do
        if v:IsEverAlive() and (not v:IsMinorCiv()) then
            local iTeam = v:GetTeam();
            for i = 0, Map.GetNumPlots() - 1 do
                if not Map.GetPlotByIndex(i):IsRevealed(iTeam) then
                    Map.GetPlotByIndex(i):SetRevealed(iTeam, true)
                end
            end
        end
    end
end

GameEvents.PlayerDoTurn.Add(function(iPlayer)
    if bFired then
        return
    end
    if (Players[iPlayer]:CountNumBuildings(GameInfoTypes.BUILDING_GLOBAL_EXPLORATION) > 0) then
        DoGlobalRevealAllTeams()
    end
end)
 
Back
Top Bottom