Event when City can expand ?

Serp

King
Joined
Apr 1, 2015
Messages
666
Hi,

is there a event or simular which is only fired when a town is able to get a tile because of culture? It does not matter which tile, I only want to catch the moment where borders expands.

I know from whowards dll:
GameEvents.CityCanAcquirePlot.Add(function(iPlayer, iCity, iPlotX, iPlotY) return true end)

But the problem is, that this event also fires, when you select a city (everytime) or hover over the city flag (only with EUI) -.- I don't know how to sort out those UI things cleanly, because I want to use it in mutliplayer.


The base problem is the following:
I want to improve whowards UI-Expansion mod, which uses dll changes, to send a notification, when City is able to expand. When you click the notification, a PopUp is called, which opens the city screen and you can buy one plot for free. This is the important code which can be found in UICityExpansion.lua:

Code:
function OnPopup(popupInfo)
  if (popupInfo.Type ~= popupButton) then
    return
  end
  
  if (popupInfo.Data1 ~= -1) then
    local pPlayer = Players[Game.GetActivePlayer()]
    local pCity = pPlayer:GetCityByID(popupInfo.Data1)
    
    if pCity and not pCity:IsPuppet() then
          -- print(string.format("Opening CityView for %s, forcing buy plots mode", pCity:GetName()))
          LuaEvents.CityViewForceBuyPlotsMode()
          UI.DoSelectCityAtPlot(pCity:Plot())
    end

    -- Dismiss the notification - ideally we'd do this when the player buys a tile
    -- However, if the player doesn't buy a tile, they'll get another notification next turn anyway
    -- print(string.format("Dismiss notification %i", popupInfo.Data2))
    pPlayer:DismissNotification(popupInfo.Data2, false)
  end

  -- Immediately dismiss this pop-up (as the City View screen is now open)  
  Events.SerialEventGameMessagePopupProcessed.CallImmediate(popupButton, 0)
end
Events.SerialEventGameMessagePopup.Add(OnPopup)

The problem is now, that the popup only works for the active player. With whowards mod, which only opens cityview in lua, this is no problem (the rest is made in dll).
But I want to add a way to enable and disable this manual choosing ingame. Unfortunately whoward did nearly everything important in dll, so I see no way to disable this mod for a specific town ingame.
That's why I added a new building and the code now looks like:

Code:
function OnPopup(popupInfo)
  if (popupInfo.Type ~= popupButton) then
    return
  end
  
  if (popupInfo.Data1 ~= -1) then
    local pPlayer = Players[Game.GetActivePlayer()]
    local pCity = pPlayer:GetCityByID(popupInfo.Data1)
    
    if pCity and not pCity:IsPuppet() then
      if (pCity:GetNumBuilding(GameInfoTypes.BUILDING_BORDERMANAGEMENT) == 0) then-- if you have this building in your town, you can choose manually, otherwise it is automatic  --  SERP , the next buyable plot is bought (for 0) automatically and get highlighted.
        local pCityID = pCity:GetID();
        local plot = pCity:GetNextBuyablePlot();
        Network.SendCityBuyPlot(pCityID, plot:GetX(), plot:GetY()) -- buy plot (which should cost 0)
        Network.SendUpdateCityCitizens( pCityID ) -- update citizens
        local target_hex = ToHexFromGrid(Vector2(plot:GetX(), plot:GetY()))
        Events.GameplayFX(target_hex.x, target_hex.y, -1) -- light the plot
        -- UI.LookAt(plot, 0) -- move to plot, deactivated 
      else
          -- print(string.format("Opening CityView for %s, forcing buy plots mode", pCity:GetName()))
          LuaEvents.CityViewForceBuyPlotsMode()
          UI.DoSelectCityAtPlot(pCity:Plot())
      end
	end

    -- Dismiss the notification - ideally we'd do this when the player buys a tile
    -- However, if the player doesn't buy a tile, they'll get another notification next turn anyway
    -- print(string.format("Dismiss notification %i", popupInfo.Data2))
    pPlayer:DismissNotification(popupInfo.Data2, false)
  end

  -- Immediately dismiss this pop-up (as the City View screen is now open)  
  Events.SerialEventGameMessagePopupProcessed.CallImmediate(popupButton, 0)
end
Events.SerialEventGameMessagePopup.Add(OnPopup)

But unfortunately this causes desync, because the active player is used in the poup event. I also dont know, if the popup event is even fired for both players at the same time, or only for the one whos city can expand.

That's why I thought of an event, that is fired, when a city can expand.
If I have such an event, which is fired for all players the same way, I could do the building chekc and so on there.
 
I think I solved it... at least now I have something that finds out, if a city is able to expand:

Code:
local Position = {}
function OnTurn(iPlayer)

    local pPlayer = Players[iPlayer]
    
    if (not pPlayer:IsHuman()) then
        return
    end
    
    for pCity in pPlayer:Cities() do
        if ([B]pCity:GetJONSCultureStored() >= pCity:GetJONSCultureThreshold()[/B] and pCity:GetNumBuilding(iBorderManagement) == 0) then
            local pCityID = pCity:GetID();
            local plot = pCity:GetNextBuyablePlot();
            Network.SendCityBuyPlot(pCityID, plot:GetX(), plot:GetY()) -- buy plot (which should cost 0)
            Network.SendUpdateCityCitizens( pCityID ) -- update citizens
            local target_hex = ToHexFromGrid(Vector2(plot:GetX(), plot:GetY()))
            Events.GameplayFX(target_hex.x, target_hex.y, -1) -- light the plot
            Position.xPosition = plot:GetX()
            Position.yPosition = plot:GetY()
        end
    end
end
GameEvents.PlayerDoTurn.Add(OnTurn)
	


function OnPopup(popupInfo)
 
  if (popupInfo.Type ~= popupButton) then
    return
  end
  
  if (popupInfo.Data1 ~= -1) then
    local pPlayer = Players[Game.GetActivePlayer()]
    local pCity = pPlayer:GetCityByID(popupInfo.Data1)
    if pCity and not pCity:IsPuppet() then
      if (pCity:GetNumBuilding(iBorderManagement) == 0) then -- just highlight and jump to the previously bought plot, the rest is done at playerdoturn
        local target_hex = ToHexFromGrid(Vector2(Position.xPosition, Position.yPosition))
        Events.GameplayFX(target_hex.x, target_hex.y, -1) -- light the plot
      else
          LuaEvents.CityViewForceBuyPlotsMode()
          UI.DoSelectCityAtPlot(pCity:Plot())
      end
	end

    pPlayer:DismissNotification(popupInfo.Data2, false)
  end

  Events.SerialEventGameMessagePopupProcessed.CallImmediate(popupButton, 0)
end
Events.SerialEventGameMessagePopup.Add(OnPopup)

I will test now, if it works without problems in multiplayer.

edit:
Okay, the Position thing will of course not work for more than one human player :D
Since the notification is automatically dismissed after a new plot is bought, the notification does appear only for 0.1seconds, if we don't have the building. So I think we can delete the whole position saving.
 
Back
Top Bottom