How do you prevent a building from being damaged when the city is captured?

isau

Deity
Joined
Jan 15, 2007
Messages
3,071
Any ideas on how to stop a building from being destroyed when a city is captured? I have some "dummy" buildings that are used for attaching modifiers. They work great, except when the city is captured they are destroyed and can't be repaired. Any ideas?
 
AFAIK there is just a global switch, per district.

Code:
UPDATE Districts SET CaptureRemovesBuildings = '0' WHERE DistrictType ='DISTRICT_CITY_CENTER';

IIRC I've also tried using Lua to manually remove then replace the damaged dummy buildings, but I don't remember if it was working.

(when are they going to give us "Set" functions in Lua for modifiers BTW ?)
 
In lua you should be able to just use
Code:
if pCity:GetBuildings():IsPillaged(iBuilding) then
	pCity:GetBuildings():SetPillaged(iBuilding, false)
end
Rather than deleting and then re-creating. So far as I am able to determine this works correctly.

But for city capture events I just re-build the set of dummies needed in a given city. This works for me in my mod since I am basing everything on the resources, terrain, features, etc., belonging to and surrounding the city, so I have no need to worry about data persistence issues or tracking whether CityX ever had BuildingX.


erm -- clarity note: I was talking to Gedemon
-----------------------------

And yes please can we have some AssignStartingPlots "Set" methods for modifiers directly from lua already !
 
Last edited:
(when are they going to give us "Set" functions in Lua for modifiers BTW ?)



Ah, the holy grail. :) I imagine if we ever get DLL access that will be one of the first things someone creates, as well as Modifier "riders" for units, leaders, civilizations. But cities especially need them, since for units at least there are Abilities which are proximally close. Cities basically need the equivalent of "Abilities."

In lua you should be able to just use
Code:
if pCity:GetBuildings():IsPillaged(iBuilding) then
    pCity:GetBuildings():SetPillaged(iBuilding, false)
end
Rather than deleting and then re-creating. So far as I am able to determine this works correctly.


I'll try this. Do you have an idea what event it should belong to? The Lua portion of the code is still kind of opaque to me. I understand it in theory (I'm an old school Flash Actionscript programmer) but many of the particulars to Civ 6 are still dangerously vague to me, in the crash-to-desktop way.
 
I've been using Events.CityInitialized(iPlayer, iCityID) because it fires both when a city is first founded and as part of a series of events that fire when a city is captured. RaF may add more but I don't yet have RaF.

I use Events.CityInitialized as for example like this (a bunch of additional toolkit functions not shown for clarity) to show what is needed to translate the arguments passed from the gamecore into usable lua objects as understood by Civ6:
Code:
function PlayerFoundedCity(iPlayer, iCityID)
	PrintToLog("[PlayerFoundedCity] iPlayer is " .. tostring(iPlayer))
	if iPlayer == 63 then
		PrintToLog("[PlayerFoundedCity] Player # " .. iPlayer .. " (Barbarians) cannot normally have cities")
		return
	end
	local pPlayer = Players[iPlayer]
	local pCity = pPlayer:GetCities():FindID(iCityID)
	if pCity ~= nil then
		PrintToLog("[PlayerFoundedCity] The founded city was " .. Locale.Lookup(pCity:GetName()))
		-- SetCityUnlockerStatuses is the actual work-horse that sets or removes my dummy buildings
		SetCityUnlockerStatuses(pCity, "PlayerFoundedCity")
	else
		PrintToLog("[PlayerFoundedCity] The founded city was nil")
	end
end
function OnLoadScreenClose()
	--delay until after LoadScreenClose to avoid un-needed executions on reloading saved game
	Events.CityInitialized.Add(PlayerFoundedCity);
end
Events.LoadScreenClose.Add(OnLoadScreenClose)
These all fire in the order shown as part of a city conquest
Code:
GameEvents.CityConquered
Events.CityRemovedFromMap
Events.CityAddedToMap
Events.CityPopulationChanged
Events.CityTileOwnershipChanged (fires in succession for each tile whose ownership was altered)
Events.CityInitialized
Events.CityProductionCompleted
Events.CityPopulationChanged	(you seem to get two firings of this event as part of a city-capture)
Events.CityProductionCompleted	(you seem to get two or more firings of this event as part of a city-capture)
From functions I wrote as a listeners to see what arguments the gamecore passes to GameEvents.CityConquered and Events.CityInitialized
Spoiler :
Code:
function GetArgumentDatas(sOrigin, tTable)
	print("============================================================================================")
	print("[" .. sOrigin .. "]: Dumping Event Hook Argument Data")
	print("............................................................................................")
	for k,v in pairs(tTable) do
		local sKeyType = type(k)
		local sValueType = type(v)
		print("[" .. sOrigin .. "]: Key is of type " .. sKeyType .. " = " .. tostring(k) .. ", Value is of type " .. sValueType .. " = " .. tostring(v))
	end
	print("............................................................................................")
	print("[" .. sOrigin .. "]: dump completed for this firing of the event")
	print("============================================================================================")
end

--############################################### CityConquered ########################################################

function OnCityConquered(...)
	--OnCityConquered(iVictoriousPlayer, iDefeatedPlayer, iNewCityID, iCityPlotX, iCityPlotY)
	--iNewCityID gives the ID # the city is using for the new owner (ie, iVictoriousPlayer)
	--iNewCityID will NOT as a general rule match to the ID # used for the same city for the previous owner (ie, iDefeatedPlayer)
	--CityConquered fires before CityRemovedFromMap, CityAddedToMap, and CityInitialized
	--Firing Order: (all functions subscribed to these events fire in this order as part of a city conquest)
	--	GameEvents.CityConquered
	--	Events.CityRemovedFromMap
	--	Events.CityAddedToMap
	--	Events.CityPopulationChanged
	--	Events.CityTileOwnershipChanged (fires in succession for each tile whose ownership was altered)
	--	Events.CityInitialized
	--	Events.CityProductionCompleted
	--	Events.CityPopulationChanged	(you seem to get two firings of this event as part of a city-capture)
	--	Events.CityProductionCompleted	(you seem to get two or more firings of this event as part of a city-capture)
	print("GameEvents.CityConquered fired for function OnCityConquered")
	GetArgumentDatas("OnCityConquered", {...})
end
GameEvents.CityConquered.Add(OnCityConquered)

--############################################### CityInitialized ########################################################

function OnCityInitialized(...)
	--OnCityInitialized(...)
	--OnCityInitialized(iPlayer, iCityID, iX, iY)
	print("Events.CityInitialized fired for function OnCityInitialized")
	GetArgumentDatas("OnCityInitialized", {...})
end
function OnLoadScreenClose()
	--delay until after LoadScreenClose to avoid massive dumps in the log on reloading saved game
	Events.CityInitialized.Add(OnCityInitialized)
end
Events.LoadScreenClose.Add(OnLoadScreenClose)
 
Looking at your update it should be possible via lua to constrain the free China bedrock thing based on a required number of tiles. This would of course run parallel to all the other requirements for the bedrock thing.

Though the logic would take some thinking through, since adding or removing a Great Wall tile improvement would require plot scanning and city-finding, and then after finding nearby cities, determination if the addition or removal of the improvement now qualifies a city for the bedrock thing, or disqualifies it. To simplify matters I would probably not recommend ever removing the Bedrock building even if an improvement was later removed, even though this would set up an exploit.
 
Looking at your update it should be possible via lua to constrain the free China bedrock thing based on a required number of tiles. This would of course run parallel to all the other requirements for the bedrock thing.

Though the logic would take some thinking through, since adding or removing a Great Wall tile improvement would require plot scanning and city-finding, and then after finding nearby cities, determination if the addition or removal of the improvement now qualifies a city for the bedrock thing, or disqualifies it. To simplify matters I would probably not recommend ever removing the Bedrock building even if an improvement was later removed, even though this would set up an exploit.


Thanks for looking into it. :) I figured it as doable with Lua, but I prefer to stick to Modifiers and RequirementSets as much as possible, in part because so many users of my mod end up editing the mod to their taste. You're correct that the Bedrock building is permanent if a player ever builds a piece of Great Wall or does anything else to trigger Bedrock. I figure they paid for Bedrock with their Builder charge, so no harm in letting the Bedrock stay permanently even if they bulldoze the improvement later.

It was nice of Firaxis in R&F to add a Requirement that looks at the number of terrain tiles. That's how I was able to create the Renaissance Bedrock unlock that counts Ocean tiles. I bet there's a lot of cool stuff we modders can use that Requirement for. Mountains, perhaps?
 
Thanks for looking into it. :) I figured it as doable with Lua, but I prefer to stick to Modifiers and RequirementSets as much as possible......
Just wanted to let you know it would be do-able, just would take some logic and thinkery-do.

It was nice of Firaxis in R&F to add a Requirement that looks at the number of terrain tiles. That's how I was able to create the Renaissance Bedrock unlock that counts Ocean tiles. I bet there's a lot of cool stuff we modders can use that Requirement for. Mountains, perhaps?
Heh. I don't have RaF yet so I don't know what-all they added, but my code for the Dummy Buildings Systems was doing this via lua already. # of required moountains in order to construct a "real" building, # of specific feature, specified district adjacent to mountains, specified district adjacent to a required number of mountains, specified terrain (and/or number of plots of given terrain) adjacent or owned by a city, etc.
 
Back
Top Bottom