Create Building in City from lua code?

greyTiger

Warlord
Joined
Oct 7, 2010
Messages
198
Location
Australia
Has anyone been able to create a building in a city from a lua script? I would like to create a building when a certain set of criteria is triggered by the player or ai opponent. I have seen a few possible options:

1) CityManager().CreateBuilding(city, buildingType, constructionCost, plot);

This option always seems to throw an error expected function not table. I have been unable to determine what part of the call is incorrect. I discovered this function call in one of the WorldBuilder scripts for Firetuner.

2) city:GetBuildQueue():CreateBuilding(city, buildingType, constructionCost, plot);

As with option 1 I run into the expected function not table error.

3) CityManager.RequestCommand(city, CityCommandTypes.PURCHASE, params);

This call does not error out, but does not purchase the building for the city either. It just doesn't seem to do anything :(

If anyone has had any luck using any of these function calls in Civ 6 or has another way of creating a building in a city on the fly in a lua script then any assistance you can provide would be appreciated.

Cheers
 

LeeS

Imperator
Joined
Jul 23, 2013
Messages
7,241
Location
Illinois, USA
Try like this. The code has to be set-up as a Gameplay Script in the modinfo file, which means it will no longer run when a saved game is reloaded. The methods being used are invalid in a UI context, and will simply cause the game to lock if attempted in a UI context, or will cause the game to refuse to load the file which will result in a missing UI panel and/or CTD-level problems when trying to access the panel.
Code:
local iExtraFreeBuilding = GameInfo.Buildings["BUILDING_MONUMENT"].Index
-- ===========================================================================
--	Game Engine Event: PlayerTurnActivated
-- ===========================================================================

function GiveFreeMonuments( iPlayer, bIsFirstTime )
	local pPlayer = Players[iPlayer]
	if pPlayer:IsHuman() and (pPlayer:GetCities():GetCapitalCity() ~= nil) then
		print("GiveFreeMonuments: Player is Human and Capital City has been founded")
		local pCities:table = pPlayer:GetCities();
		for i, pCity in pCities:Members() do
			local sCityName = Locale.Lookup(pCity:GetName())
			if not pCity:GetBuildings():HasBuilding(iExtraFreeBuilding) then
				print("GiveFreeMonuments: " .. sCityName .. " Did not have a monument in the city. It was placed in the city")
				local pCityPlot = Map.GetPlot(pCity:GetX(), pCity:GetY())
				local pCityBuildQ = pCity:GetBuildQueue()
				pCityBuildQ:CreateIncompleteBuilding(iExtraFreeBuilding, pCityPlot:GetIndex(), 100);
			else
				print("GiveFreeMonuments: " .. sCityName .. " had a monument in the city. None was needed.")
			end
		end
	else
		print("GiveFreeMonuments: Player is not Human or Capital City has not been founded")
	end
end
Events.PlayerTurnActivated.Add(GiveFreeMonuments)
I made the code only work for the human player for testing purposes. You can also add the building when the city is founded using event
Code:
-- ===========================================================================
--	Game Engine Event: CityInitialized
-- ===========================================================================
function OnCityInitialized(iPlayer, CityID)
	local pPlayer = Players[iPlayer]
	local pCity = pPlayer:GetCities():FindID(CityID)

	-- etc
end
Events.CityInitialized.Add(OnCityInitialized);
 
Last edited:

Horem

Emperor
Joined
Apr 1, 2010
Messages
1,721
Location
Wales, UK
You know there is an Effect to grant buildings?

<Row Type="EFFECT_GRANT_BUILDING_IN_CAPITAL" Kind="KIND_EFFECT"/>
<Row Type="EFFECT_GRANT_BUILDING_IN_CITY" Kind="KIND_EFFECT"/>

To which you can attach a wide range of requriements.
 
Last edited:

greyTiger

Warlord
Joined
Oct 7, 2010
Messages
198
Location
Australia
Try like this. The code has to be set-up as a Gameplay Script in the modinfo file, which means it will no longer run when a saved game is reloaded. The methods being used are invalid in a UI context, and will simply cause the game to lock if attempted in a UI context, or will cause the game to refuse to load the file which will result in a missing UI panel and/or CTD-level problems when trying to access the panel.

Thanks for the information and example. I had heard of the issue with Gameplay scripts not working in saved games and was trying to stick to a UI script, but I did not realize that the methods I was considering using could cause such severe issues in a UI script. I have decided to put aside automatic creation of a building or project when my new victory conditions are met for the time being (until Firaxis releases the modding tools and\or fixes the Gameplay script issue). I'll instead require that the player build the Victory Monument when my criteria are met. Not the ideal solution but something that should work.

Really do appreciate the insight you have provided. Thanks again.
 

greyTiger

Warlord
Joined
Oct 7, 2010
Messages
198
Location
Australia
You know there is an Effect to grant buildings?

<Row Type="EFFECT_GRANT_BUILDING_IN_CAPITAL" Kind="KIND_EFFECT"/>
<Row Type="EFFECT_GRANT_BUILDING_IN_CITY" Kind="KIND_EFFECT"/>

To which you can attach a wide range of requriements.

I looked into using the effect you mentioned. I was unable to determine a way of hooking it up to my criteria for my new victory. As I mentioned to LeeS I'll put the auto creation of the building aside for now (before I go mad from staring at the code and tables).
 
Top Bottom