fort spreading borders - python problem

Ahwaric

Shrubbery-hugger
Joined
Nov 12, 2005
Messages
1,217
Location
Kraków, Poland
I am trying to adapt Jeckel's forts to Orbi. I want simplified version, just fort commander & cultural borders. I have managed (using final frontier code) to spawn Fort Commander when the fort is build, then spread borders to the tile and mantain it, together with ownership changing after the fort capture.
But I have one problem I can't deal with. When more than one worker builds the fort, I get one fort commander for each worker building it. Is it possible to limit the spawning to just one unit?

My current code related to spawning is:
Code:
	def onImprovementBuilt(self, argsList):
		'Improvement Built'
		iImprovement, iX, iY = argsList
		pPlot = CyMap().plot(iX, iY)

		iImprovementFortID = CvUtil.findInfoTypeNum(gc.getImprovementInfo,gc.getNumImprovementInfos(),'IMPROVEMENT_FORT')
		iUnitWorkerID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_WORKER')	
		# Fort finished
		if (iImprovement == iImprovementFortID):
			pPlot = CyMap().plot(iX, iY)		
			# Look for Worker on this plot
			for iUnitLoop in range(pPlot.getNumUnits()):
				pUnit = pPlot.getUnit(iUnitLoop)				
				if (pUnit.getScriptData() == "BuildingFort"):
					self.doMakeFort(pUnit.getOwner(), iX, iY)

		if (not self.__LOG_IMPROVEMENT):
			return
		CvUtil.pyPrint('Improvement %s was built at %d, %d'
			%(PyInfo.ImprovementInfo(iImprovement).getDescription(), iX, iY))

	def doMakeFort(self, iPlayer, iX, iY):		
		pPlayer = gc.getPlayer(iPlayer)
		pPlot = CyMap().plot(iX, iY)	
		# Create Commander Unit
		iUnitFortID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_FORT_COMMANDER')
		pPlayer.initUnit(iUnitFortID, iX, iY, UnitAITypes.UNITAI_ATTACK, DirectionTypes.NO_DIRECTION)
		self.updateFortCulture(iPlayer, iX, iY)

Any ideas?
 
You could loop all the units on the tile and make sure there isn't already a Fort Commander on the tile, as it should be impossible to ever have 2 in one location.

I don't get why you are looking for a worker who is building a fort though. Is there some other way to get a fort created? You have already verified by that point that a fort was just generated, so why not just pop up a Fort Commander, and use the current plot owner as the player? Wouldn't work if you are allowing these to be built outside of borders I suppose though. I am picturing them as a way to extend your current borders though, not a way to claim land in the middle of nowhere.

EDIT: You could also set a simple Boolean during your loop to find a worker. Start the boolean before the loop as false, and if a worker is found, set it to true. Require that the boolean is false in order to bother checking if the unit is a worker at all (or just break the loop statement after the first worker, but I don't know the command to break a loop prematurely, other than to define iUnitLoop = pPlot.getNumUnits() + 1, which would ensure that the loop stops running)
 
First of all, thanks for a quick answer.
I want to allow the forts to be build in the willderness and then allow them to upgrade. Initially, I set them to extend borders only to fort plot itself, then at castle or citadel stage adding 1-tile radius.
This way they can be used to extendyour borders in far away terrain, which is worthless to settle, or to create far-away defensive points.
That is why I look for a worker - I need a check who build the fort.

EDIT: You could also set a simple Boolean during your loop to find a worker. Start the boolean before the loop as false, and if a worker is found, set it to true. Require that the boolean is false in order to bother checking if the unit is a worker at all (or just break the loop statement after the first worker, but I don't know the command to break a loop prematurely, other than to define iUnitLoop = pPlot.getNumUnits() + 1, which would ensure that the loop stops running)

And here you got me lost... Might I ask for a sample code? With some advice where to put it :) I am really bad at coding and after spending a few hours trying to fix it, I gave up...

Just in case, I also added the following
Code:
	def onUnitBuildImprovement(self, argsList):
		'Unit begins enacting a Build (building an Improvement or Route)'
		pUnit, iBuild, bFinished = argsList		
		iBuildFortID = CvUtil.findInfoTypeNum(gc.getBuildInfo,gc.getNumBuildInfos(),'BUILD_FORT')	
		# Fort WAS built
		if (iBuild == iBuildFortID):
			pUnit.setScriptData("BuildingFort")

Apart from that, some culture code, but that works fine and is executed after the commander is created.
 
Code:
	def onImprovementBuilt(self, argsList):
		'Improvement Built'
		iImprovement, iX, iY = argsList
		pPlot = CyMap().plot(iX, iY)

		iImprovementFortID = CvUtil.findInfoTypeNum(gc.getImprovementInfo,gc.getNumImprovementInfos(),'IMPROVEMENT_FORT')
		iUnitWorkerID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_WORKER')	
		# Fort finished
		if (iImprovement == iImprovementFortID):
			pPlot = CyMap().plot(iX, iY)		
			# Look for Worker on this plot
			for iUnitLoop in range(pPlot.getNumUnits()):
				pUnit = pPlot.getUnit(iUnitLoop)				
				if (pUnit.getScriptData() == "BuildingFort"):
					self.doMakeFort(pUnit.getOwner(), iX, iY)
[COLOR="DarkOrange"]					iUnitLoop = pPlot.getNumUnits() + 1[/COLOR]

		if (not self.__LOG_IMPROVEMENT):
			return
		CvUtil.pyPrint('Improvement %s was built at %d, %d'
			%(PyInfo.ImprovementInfo(iImprovement).getDescription(), iX, iY))

	def doMakeFort(self, iPlayer, iX, iY):		
		pPlayer = gc.getPlayer(iPlayer)
		pPlot = CyMap().plot(iX, iY)	
		# Create Commander Unit
		iUnitFortID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_FORT_COMMANDER')
		pPlayer.initUnit(iUnitFortID, iX, iY, UnitAITypes.UNITAI_ATTACK, DirectionTypes.NO_DIRECTION)
		self.updateFortCulture(iPlayer, iX, iY)


Code:
	def onImprovementBuilt(self, argsList):
		'Improvement Built'
		iImprovement, iX, iY = argsList
		pPlot = CyMap().plot(iX, iY)

		iImprovementFortID = CvUtil.findInfoTypeNum(gc.getImprovementInfo,gc.getNumImprovementInfos(),'IMPROVEMENT_FORT')
		iUnitWorkerID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_WORKER')	
		# Fort finished
		if (iImprovement == iImprovementFortID):
			pPlot = CyMap().plot(iX, iY)		
			# Look for Worker on this plot
[COLOR="#ff8c00"]			bDone = False[/COLOR]
			for iUnitLoop in range(pPlot.getNumUnits()):
				pUnit = pPlot.getUnit(iUnitLoop)				
				if (pUnit.getScriptData() == "BuildingFort"[COLOR="#ff8c00"] and not bDone[/COLOR]):
[COLOR="#ff8c00"]					bDone = True[/COLOR]
					self.doMakeFort(pUnit.getOwner(), iX, iY)

		if (not self.__LOG_IMPROVEMENT):
			return
		CvUtil.pyPrint('Improvement %s was built at %d, %d'
			%(PyInfo.ImprovementInfo(iImprovement).getDescription(), iX, iY))

	def doMakeFort(self, iPlayer, iX, iY):		
		pPlayer = gc.getPlayer(iPlayer)
		pPlot = CyMap().plot(iX, iY)	
		# Create Commander Unit
		iUnitFortID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_FORT_COMMANDER')
		pPlayer.initUnit(iUnitFortID, iX, iY, UnitAITypes.UNITAI_ATTACK, DirectionTypes.NO_DIRECTION)
		self.updateFortCulture(iPlayer, iX, iY)


Those are 2 ways I can think of to do it. Additions are in orange. Of course, I hate python, so I cannot guarantee that my format is flawless.
 
First one still allows for more than one commander, but the second option works like a charm :)

Thanks a lot!
 
Not to rain on your parade, but the python method is very processor intensive and always caused me bad slowdowns. Then again, maybe it was just me that had those problems.
 
That is the thing I am afraid of, but I decided to try.
I try to stick to the code adapted from final frontier and I do not think it should be worse than dynamic jungle/deep changes jungle for Mazatl.
If it will cause slowdown, I can always just keep the commanders - they are one-time python users ;)
 
Back
Top Bottom