Hello, I want to identify all cities with a specific improvement around

liwy

Chieftain
Joined
Nov 15, 2009
Messages
63
Location
Brussels
Hello, I want to identify all cities (in the civ) with a specific improvement around them. In this case the improvement in question is the plantation as I want to create an event for the abolition of slavery.The ultimate goal is to add some unhappiness from those poor planters who would not be able to oppress other people ever again...

Here is what I hope to be a good beginning, but now I must retrieve the list of the included cities.
Code:
def canApplyPlantersRebellion(argsList):
	iEvent = argsList[0]
	kTriggeredData = argsList[1]
	
	listPlantation = []
	listPlantation.append(CvUtil.findInfoTypeNum(gc.getImprovementInfo,gc.getNumImprovementInfos(),'IMPROVEMENT_PLANTATION'))
	
	listPlots = []
	loopPlot.isCity()
		for iDX in range(-1, 2):
			for iDY in range(-1, 2):
				loopPlot = plotXY(kTriggeredData.iPlotX, kTriggeredData.iPlotY, iDX, iDY)
				if not loopPlot.isNone():
					if (iDX != 0 or iDY != 0):
						if loopPlot.getImprovementType() != -1:
							listPlots.append(loopPlot)

		return
	for i in range(3):
		if len(listPlots) > 0:
			plot = listPlots[gc.getGame().getSorenRandNum(len(listPlots), "")]
			iImprovement = plot.getImprovementType()
			if iImprovement in listPlantation:
				return true
 
I would make something like this in the DLL for a number of reasons (performance being the main one), but looking up how the python interface handles something like this is modding education in its own way. The idea is the same as in the DLL.

Just for the record: this is completely untested as I wrote the code directly into the browser.

I would start by looping all cities for a player and store the cities, which fits your criteria. Something like this:
PHP:
listCities = []
PlantationID = CvUtil.findInfoTypeNum(gc.getImprovementInfo,gc.getNumImprovementInfos(),'IMPROVEMENT_PLANTATION')
hasPlantation = False
(loopCity, iter) = player.firstCity(false)
while(loopCity):
	if self.cityHasImprovement(loopCity, PlantationID):
		listCities.append(loopCity)
		hasPlantation = True
	(loopCity, iter) = player.nextCity(iter, false) # move pointer to the next city

# listCities should now hold a list of cities with plantations.
# hasPlantation should provide the same answer as checking if length of listCities > 0
The function cityHasImprovement should be added somewhere else in the same file. It should be something like this:
PHP:
def cityHasImprovement(self, pCity, ImprovementID):
	X = pCity.getX()
	Y = pCity.getY()
	for plotNum in range(gc.getNUM_CITY_PLOTS()):
		LoopPlot = plotCity(X, Y, plotNum)
		if LoopPlot.getImprovementType() == ImprovementID:
			return True

	# failed to locate any improvements of the selected type
	return False
I think that should do it.

I decided to look up the ID of plantations first because of two reasons:
1: it's slow to look up a string and storing the resulting int speeds up the code.
2: cityHasImprovement can now be used to look for other improvements elsewhere without changing the function itself.

I would like to know if this actually works. As I said, I would have coded it in the DLL and I haven't actually tried looped city plots from python. I think this is the correct syntax.
 
1) plotCity not exposed to python
2) No checks for plot ownership
 
1) plotCity not exposed to python
Taken from CyGameCoreUtilsInterface.cpp in vanilla BTS:
PHP:
python::def("plotCity", cyPlotCity, python::return_value_policy<python::manage_new_object>(), "CyPlot* (int iX, int iY, int iIndex)");
I haven't tested it, but it looks ok to me, both this part and the cyPlotCity function.

However it isn't used in vanilla python code, but that shouldn't matter as long as it is exposed by the DLL.

2) No checks for plot ownership
I thought about that, but then I forgot about it when I reached that part. Yeah, that should be checked. It might also be worth to consider if the city should work the plot or if it is enough to just have an unused plantation.
 
Back
Top Bottom