City Captured Event

CivilizationAce

Warlord
Joined
Jan 17, 2017
Messages
236
I've used "Events InGame.ltp" to monitor the events thrown when I capture a city. It shows no "City captured" event.

In the absence of a such event I figured that I'd use DistrictRemovedFromMap, CityAddedToMap, and TurnBegin to infer when city capture has occurred.

However, before I went ahead I wondered if there is an easier way. I wonder if "Events InGame.ltp" shows all the events.

Does anyone have any experience with "Events InGame.ltp" that may shed light on this or know of a suitable event (that's obviously not logged by "Events InGame.ltp")?
 
Last edited:
FYI It occurred to me that the .ltp may be a text file. Turns out it is. I hoped to find it catching events generically, but each event it can capture is named in the file, so I guess its completeness is limited by the writer's knowledge, which leaves us still without confirmation that there's no straightforward "City captured" event.
 
IIRC there may be one that was added in the last patch.

ATM I also use the district/city removed/added events.
 
ATM I also use the district/city removed/added events.
I wondered if there's a way to create and throw a new event after the CityAddedToMap event, say "CityCaptured(x,y,capturedByPlayerID,capturedFromPlayerID)", but as far as I can tell event handling isn't part of core lua and I can find no reference to how this instance of lua defines/generates events.
 
You can do that using lua events, I'll try to post an example when back from work.
 
Yep, just as @Gedemon said.

in one file you create a function for your event and register it with LuaEvents

function MyEventFunction( iParam:number )
--your code
end
LuaEvents.TriggerMyEvent.Add( MyEventFunction );

then in any other file you can call it:

LuaEvents.TriggerMyEvent(4);
LuaEvents.TriggerMyEvent(2);

ofc, iParam is just an example, you can have any params you want.

Edit. Btw, this is how Firaxis scripts are communicating with each other, there are a ton of those in their scripts. It may get confusing because they've got a peculiar naming convention. If an event is defined in scriptA and called by scriptB they name it scriptB_event. So, you've got a LuaEvents.scriptB_event.Add() in scriptA... It's totally strange, at least for me, as I would have named it scriptA_event.
 
Last edited:
LuaEvents.TriggerMyEvent(4);
I wondered if it could be that simple, but when I read about the LuaEvents object (the VelociraptorAttack example) and it said "To define a custom event", I presumed that by custom it meant a custom event added by Firaxis to lua, not one we could add ourselves.

If an event is defined in scriptA and called by scriptB they name it scriptB_event
You're right of course – it's gibberish. What if new code required it to be called from scriptC as well? Apart from anything else a third programmer then looking at the code in scriptC would be totally confused. It's an example of trying to apply synchronous thinking to an asynchronous environment.
 
I'll try to post an example when back from work
Thanks, but I think I've got the idea :). I've come up with the following totally untested code to, hopefully, throw an event to mark city capture or trade:
Spoiler Speculative code :
Code:
function OnLoadScreenClose()
    var CityCenterRemovedLog = {};
    Events.DistrictRemovedFromMap.Add(OnDistrictRemovedFromMap)
    Events.TurnBegin.Add(OnTurnBegin);
    Events.CityInitialized.Add(OnCityInitialized);
end

function OnTurnBegin()
    CityCenterRemovedLog = {};                                                            -- Clear the table to avoid confusion in following turns
end

function OnDistrictRemovedFromMap(iOwner,iMoot1,iMoot2,iX,iY,iType)
    if iType == 0 then                                                                    -- The last parameter seems to relate to the district type where 0 is city center.
        table.Insert(CityCenterRemovedLog, {oldOwner=iOwner,x=iX,y=iY})                    -- Log the location and original owner as a table within the main table.
    end
end

function OnCityInitialized(iPlayer,iMoot,iX,iY)
    for k,city in pairs(CityCenterRemovedLog) do                                        -- Go through the log one city at a time. Each city is a table.
        if city["oldOwner"] ~= iPlayer and city["x"] == iX and city["y"] == iY then        -- Same place different player
            units = Units.GetUnitsInPlot(Map.GetPlot(iX,iY));                            -- Now differentiate between conquest and trade
            local conquest = false;
            for _,unit in pairs(units)
                if unit:GetOwner() = iPlayer and unit:GetType() ~= "UNIT_SPY" then
                    conquest = true;
                    break
                end
            end
            LuaEvents.CityChangedOwner(iPlayer,city["oldOwner"],iX,iY);
            if conquest then
                LuaEvents.CityCaptured(iPlayer,city["oldOwner"],iX,iY);                    -- Throw the event, in the form CityCaptured(newOwner,oldOwner,X,Y)
            else
                LuaEvents.CityTraded(iPlayer,city["oldOwner"],iX,iY);
            end
            table.remove(CityCenterRemovedLog , k)                                        -- Remove the element from the table in case TurnBegin ticks by year rather than player turn.
            return
        end
    end
end

Events.LoadScreenClose.Add(OnLoadScreenClose)
One concern is what happens when a city is traded. As far as I can tell the events log exactly the same way, so I've added code to check if the new owner has a non-spy unit there, but my worry is that technically the city may change hands after the attack but before the unit has moved in or that those two things may be asynchronous. I'll see what I can do to pick that up while testing.

I haven't got around to coding the consumption of any of the events yet. I just wanted to make something stand alone to throw them that I can use on later mods as well as the one in hand.

P.S. If anyone is considering copying this I wouldn't recommend doing that yet — a) It's untested and b) 'a)' should be enough.
 
I've added the GameEvents in the Lua Object thread, but I've not looked at the other events and the dump for the google doc was made before the winter patch.
 
Top Bottom