whoward69
DLL Minion
However, this won't catch when a player sells off buildings
Code:
GameEvents.CitySoldBuilding.Add(function (iPlayer, iCity, iBuilding) ... end)
However, this won't catch when a player sells off buildings
GameEvents.CitySoldBuilding.Add(function (iPlayer, iCity, iBuilding) ... end)
Code:GameEvents.CitySoldBuilding.Add(function (iPlayer, iCity, iBuilding) ... end)
didn't address the point about catching a City being razed it means there really isn't any real way to do so.
It's a game event, so I would imagine so. If nothing else, as Pazyryk taught us, events can be directly called instead of just subscribed to, and so I assume it works in reverse: events can be subscribed to instead of directly called...I see a GameEvents.SetPopulation() but that doesn't seem like it would report population changes.. outside of that, I can't see anything obviously related to population (or at least has 'population' in its method name.)
tBuildingsInRazedCity = {}
...
-- assuming pCity is already defined:
if pCity:IsRazing() then
[COLOR="Red"]for pBuilding in pCity:Buildings() do[/COLOR]
tBuildingsInRazedCity[pCity:GetID()] = { pBuilding }
end
end
...
tBuildingsInRazedCity = {}
...
-- assuming pCity is already defined:
if pCity:IsRazing() then
for row in GameInfo.Buildings() do
if (pCity:IsHasBuilding(row.Type)) then
tBuildingsInRazedCity[pCity:GetID()] = { row.Type }
end
end
end
...
for row in GameInfo.Buildings() do
if pCity:[B]IsHasBuilding[/B](row.ID) then
print(pCity:GetName() .. " has " .. tostring(pCity:[B][COLOR="Blue"]GetNumBuilding[/COLOR][/B](row.ID)) .. " x " .. row.Type .. " (" .. Locale.ConvertTextKey(row.Description) .. ")")
end
end
BuildingX = GameInfoTypes.BuildingX
tBuildingsInRazedCity = {}
-- params of table: playerID, x, y, {Buildings}
GameEvents.SetPopulation.Add(
function(iX, iY, iPopOld, iPopNew)
local pCity = Map.GetPlot(iX, iY):GetPlotCity()
if (iPopNew < iPopOld) then -- if the population decreased; next we'll chec kto see if that's because of city razing
if (pCity:IsRazing()) and (pCity:IsHasBuilding(BuildingX) then
for row in GameInfo.Buildings() do
if (pCity:IsHasBuilding(row.Type)) then
tBuildingsInRazedCity[pCity:GetOwner():GetID(), iX, iY] = { row.Type }
end
end
end
end
end)
GameEvents.PlayerCityFounded.Add(
function(iPlayer, iX, iY)
local pPlot = Map.GetPlot(iX, iY)
local pCity = pPlot:GetPlotCity()
for a,b,c,d in pairs(tBuildingsInRazedCity) do
-- a == iPlayer, b == x, c == y, d == {Buildings}
if (pPlot == Map.GetPlot(b, c)) and (iPlayer == a) then
pCity:SetNumRealBuilding(d, 1)
end
end
end)
pCity:IsHasBuilding(row.Type)
tBuildingsInRazedCity[#tBuildingsInRazedCity + 1] = {pCity:GetOwner():GetID(), iX, iY, buildingTable}
for a,b in pairs(tBuildingsInRazedCity) do
local iStoredPlayerID = b[1]
local iStoredX = b[2]
local iStoredY = b[3]
if (pPlot == Map.GetPlot(iStoredX, iStoredY)) and (iPlayer == iStoredPlayerID) then
local buildingTable = b[4]
for i = 1, #buildingTable do
pCity:SetNumRealBuilding(buildingTable[i], 1)
end
end
end
From what I understand, City.GetOwner() -> Player, Player.GetID() -> playerID.(Unrelated: What the heck is pCity:GetOwner():GetID() supposed to do? Aren't they the same thing?)
If that's the case, then every other time I've used something along the lines of "if the city has this building then" is wrong. But now you have me doubting it too. I guess it could be changed to "if pCity:GetNumBuilding(row.Type) > 0 then". Or change it to row.ID, but I prefer the former because for all those other codes that fed Type into IsHasBuilding(), I'm not sure how to get the ID of that building... isn't it something like GameInfo.BUILDING_X.ID?I don't believe this will work. Per the wiki's documentation along with Firaxis' native examples there, IsHasBuilding() should be expecting a building ID -- you keep trying to feed it the building type string, which may cause it to fail. Maybe it won't, I haven't tried it.
Not the first time, either. :/Jeez. Some of your assumptions and oddities with your code are making me confused, haha.
From what I understand, City.GetOwner() -> Player, Player.GetID() -> playerID.
> UI.GetHeadSelectedCity():GetOwner()
0
> UI.GetHeadSelectedCity():GetOwner():GetID()
Runtime Error: _cmdr = {UI.GetHeadSelectedCity():GetOwner():GetID()}:1: attempt to index a number value
If that's the case, then every other time I've used something along the lines of "if the city has this building then" is wrong. But now you have me doubting it too. I guess it could be changed to "if pCity:GetNumBuilding(row.Type) > 0 then". Or change it to row.ID, but I prefer the former because for all those other codes that fed Type into IsHasBuilding(), I'm not sure how to get the ID of that building... isn't it something like GameInfo.BUILDING_X.ID?
I typically don't like dealing IDs for a reason I still haven't nailed down. I honestly don't know why IDs make me shudder more than any other integer variable.
> UI.GetHeadSelectedCity():SetNumRealBuilding(GameInfoTypes.BUILDING_MARKET,1)
1
> UI.GetHeadSelectedCity():IsHasBuilding(GameInfo.Buildings.BUILDING_MARKET.Type)
false
> GameInfo.Buildings.BUILDING_MARKET.Type
BUILDING_MARKET
> type(GameInfo.Buildings.BUILDING_MARKET.Type)
string
> UI.GetHeadSelectedCity():IsHasBuilding(GameInfo.Buildings.BUILDING_MARKET.ID)
true
Yeah, I just found that on the modwiki too. (While finding the returned value of Plot.GetOwner() and finding that it returns a playerID, checked City.GetOwner() and found that it returns the same)According to the modiki GetOwner() already returns you the player ID.
if (pPlayer:GetCivilizationType() == GameInfoTypes.CIVILIZATION_X) then
if (Leader_Traits{LeaderType={GameInfo.Civilization_Leaders{CivilizationType={GameInfo.Civilizations{ID=pPlayer:GetCivilizationType()}}}}} == GameInfoTypes.TRAIT_X) then
if (Leader_Traits{...
leaderType = GameInfo.Leaders[pPlayer:GetLeaderType()].Type
leadertraitType = GameInfo.Leader_Traits("LeaderType ='" .. leaderType .. "'")().TraitType
traitType = GameInfo.Traits[leadertraitType]
if traitType.CanUseUnlimitedBladeWorks == 1 or traitType.CanUseUnlimitedBladeWorks == true then
tWhoIsArcher[i] = true
bAnyArchers = true
end
Beware the mod that adds additional traits to all/some leaders.
My understanding was also that "GameInfo." does not [edit]always[edit] give you the information as it is after mods have made changes to the database, whereas "GameInfoTypes" does do so.
Treat that whole paragraph as a strike-through. I can't find where I (must have mis-re) remembered seeing a comment about issues relating to GameInfo as opposed to GameInfoTypes. I generally only use GameInfo when I want to look through the contents of a game table as inWhere did you see this?
This would be disconcerting if true, but I don't think this should happen, since all of the database changes are made when you enable the mods at the MODS screen, but the Lua doesn't run until you actually generate a map and load a game.
At least in my testing, GameInfo and GameInfoTypes always returned data that matched up with what I was seeing in the database via SQLite Manager.
for row in GameInfo.Buildings() do
local freeUnitDetails = GameInfo.Units{ID=iFreeUnit}()
local iBuildingSomething = GameInfoTypes.BUILDING_SOMETHING
or
local iBuildingSomething = GameInfoTypes["BUILDING_SOMETHING"]