Improvement placement control

PawelS

Ancient Druid
Joined
Dec 11, 2003
Messages
2,811
Location
Poland
When working on improvements for my mod, I encountered some cases where I want to restrict them to some plot types, which can't be done through the existing tables and columns in the database. For example, I want my version of the Terrace Farm to require the following:

(grass OR plains) AND hills AND (fresh water OR adjacent mountain)

I think it can probably be done using the CanBuild event, but I'm not very good at such things, so I need an example of Lua code that does something similar to be able to do it properly. I'd be grateful if someone can post such an example here, or point me to it...
 
When working on improvements for my mod, I encountered some cases where I want to restrict them to some plot types, which can't be done through the existing tables and columns in the database. For example, I want my version of the Terrace Farm to require the following:

(grass OR plains) AND hills AND (fresh water OR adjacent mountain)

I think it can probably be done using the CanBuild event, but I'm not very good at such things, so I need an example of Lua code that does something similar to be able to do it properly. I'd be grateful if someone can post such an example here, or point me to it...

Is there a CanBuild game event? I can't find one in the Modiki or the DLL. Are you using an extension provided by whoward's DLL or your own?

Assuming CanBuild is an event of some kind that gives the x and y coordinates of a plot and that it expects a single boolean return value. (It may also supply a unit and player ID so you can check the unit is the right kind to build it?) With all that, something like this:

Code:
include("PlotIterators")
-- We're using whoward's plot iterators because they're awesome

function CanBuildMyCoolImprovement(iX, iY)
	local pPlot = Map.GetPlot(iX, iY)
	
	if (pPlot:GetTerrainType() == GameInfoTypes.TERRAIN_GRASS 
		or pPlot:GetTerrainType() == GameInfoTypes.TERRAIN_PLAINS)
		and pPlot:GetPlotType() == GameInfoTypes.PLOT_HILLS
		and (pPlot:IsFreshWater()
		or IsAdjacentMountain(iX, iY)) then
			return true
	else
		return false
	end
end
GameEvents.CanBuild.Add(CanBuildMyCoolImprovement)

function IsAdjacentMountain(iX, iY)
	local pPlot = Map.GetPlot(iX, iY)
	
	for pEdgePlot in PlotRingIterator(pPlot, 1) do
		if pEdgePlot:GetPlotType() == GameInfoTypes.PLOT_MOUNTAIN then
			return true
		end
	end
	
	return false
end

Disclaimer: completely untested, and you'll need whoward's plot iterators. The above script should be an InGameUIAddin with VFS=false.
 
I did some more research, and it seems I was mistaken: there is no CanBuild event, there are only CanBuild functions tied to Plot, Unit and Player objects. If I understand it correctly (and, as I already mentioned, I'm not a Lua modding expert), these functions just check the standard conditions of building an improvement, and don't allow the modder to add new conditions.

If the above is true, then probably I need DLL changes to achieve what I want. But thanks for trying to help me, anyway :)
 
I did some more research, and it seems I was mistaken: there is no CanBuild event, there are only CanBuild functions tied to Plot, Unit and Player objects. If I understand it correctly (and, as I already mentioned, I'm not a Lua modding expert), these functions just check the standard conditions of building an improvement, and don't allow the modder to add new conditions.

If the above is true, then probably I need DLL changes to achieve what I want. But thanks for trying to help me, anyway :)

Yeah, I thought it might be like this. There are definitely CanBuild functions in the C++ unit objects (and, oh, such fun you will have working with them, they are monolithic and terrible) but their results aren't modifiable from Lua.
 
Back
Top Bottom