Problem with FEATURE_ICE

OrionVeteran

Deity
Joined
Dec 25, 2003
Messages
2,443
Location
Newport News VA
I have an Ice Breaker unit that can move on impassable terrain and remove ice. I want to move the Ice Breaker to a plot with ice (as opposed to snow, which is a land plot). I have a function that does a search for nearby plots within a specified range.

Spoiler :

Code:
def doIceBreakerPlacement(pUnit):
	# Orion's Icebreaker Mod
	# 1. Moves Icebreaker to unowned plots, within range of 10 plots.
	# 2. If it finds ice next to land, it moves the Icebreaker to that plot.
	iOwner = pUnit.getOwner()	
	FoundTargetIcePlot = False
	pUnitPlot = CyMap().plot(pUnit.getX(), pUnit.getY())
	iPlotOwner = pUnitPlot.getOwner()
	iBreakIce = gc.getInfoTypeForString("BUILD_BREAK_ICE")
	iFeatureIce = gc.getInfoTypeForString("FEATURE_ICE")
				
	if pUnitPlot.isCity():
		# Kick the naval unit out of the city
		StandardFunctions.kickNavalUnitOutOfCity(pUnit)
	
	if not pUnitPlot.isCity():
		# water plot must be owned by player or by nobody
		if iPlotOwner == iOwner or iPlotOwner == -1:			
			# Make sure the water plot is next to land
			if pUnitPlot.isAdjacentToLand():
				# plot must have ice
				if pUnitPlot.getFeatureType() == gc.getInfoTypeForString("FEATURE_ICE"):					#CyInterface().addImmediateMessage("A", "")
					# Break the Ice
					pUnit.getGroup().pushMission(MissionTypes.MISSION_BUILD, iBreakIce, -1, 0, True, False, MissionAITypes.NO_MISSIONAI, pUnitPlot, pUnit)
				
				# No Ice on plot 
				else:
					# Find plot to move Ice Breaker
					for iPlotLoop in range(CyMap().numPlots()):
						pLoopPlot = CyMap().plotByIndex(iPlotLoop)
						# find shortest path between the source plot and the destination plot.
						# ******* Ice Breaker must be on a water plot for the calculatePathDistance command to work
						iPlotDistance = CyMap().calculatePathDistance(pUnitPlot, pLoopPlot)
						if iPlotDistance in range(1, 10):
							# Find a water plot
							if pLoopPlot.isWater():
								ipLoopPlotOwner = pLoopPlot.getOwner()
								# water plot must be owned by player or by nobody
								if ipLoopPlotOwner == iOwner or ipLoopPlotOwner == -1:
									CyInterface().addImmediateMessage("A", "")
									# Make sure the water plot is next to land
									if pLoopPlot.isAdjacentToLand():
										# plot must have ice
										CyInterface().addImmediateMessage("B", "")
										[COLOR="Red"][B]if pLoopPlot.getFeatureType() == gc.getInfoTypeForString("FEATURE_ICE"):[/B][/COLOR]										#if pLoopPlot.getFeatureType() == iFeatureIce:
											CyInterface().addImmediateMessage("C", "")
											FoundTargetIcePlot = True
											TargetIcePlot = pLoopPlot
											break
								
								
	if FoundTargetIcePlot:
		CyInterface().addImmediateMessage("D", "")
		pUnit.getGroup().pushMission(MissionTypes.MISSION_MOVE_TO, TargetIcePlot.getX(), TargetIcePlot.getY(), 0, False, True, MissionAITypes.NO_MISSIONAI, pUnitPlot, pUnit)
		CyMap().resetPathDistance()


I want to move the Ice Breaker unit to an ice plot, but the code fails to progress past the red line (near the end of the code), which is crucial to the success of this function. :mad: Please note that my test game has a qualified plot just 3 plots away from an Ice Breaker unit. How can I fix this?
 
Well I have isolated the problem to the impassable attribute of the ICE plot feature. If I remove the 1 and make it:

Code:
<bImpassable>0</bImpassable>

...Then the code works perfectly! ...and the my AI Ice Breakers start removing ICE. So my answer appears to be changing this attribute and then go into the units and prevent all Naval units except submarines and Icebreakers from entering ICE plots. If someone has a better idea, please let me know.

:thanx:
 
I think all you need to do is set the bCanMoveImpassable tag for your Icebreakers to a 1

That setting was given to the Ice Breaker previously, which allowed Human players to go to Ice plots and break ice. Only the AI couldn't break ice. The search for the various plots could be used for any unit and you would still have the impassable issue with the detection of Ice plots. If there was a way via python to overide the impassable attribute to allow the detection of ICE plots, I would rather go down that road. I just don't know of a way to do that.
 
That setting was given to the Ice Breaker previously, which allowed Human players to go to Ice plots and break ice. Only the AI couldn't break ice. The search for the various plots could be used for any unit and you would still have the impassable issue with the detection of Ice plots. If there was a way via python to overide the impassable attribute to allow the detection of ICE plots, I would rather go down that road. I just don't know of a way to do that.
The function you used to calculate the distance cannot know that your unit can enter impassable terrain as it takes no unit or type as parameter.
Maybe this unit method will work, it seems to return the distance as last parameter, in turns though instead of plots:
BOOL generatePath (CyPlot pToPlot, INT iFlags, BOOL bReuse, INT piPathTurns)
 
The function you used to calculate the distance cannot know that your unit can enter impassable terrain as it takes no unit or type as parameter.
Maybe this unit method will work, it seems to return the distance as last parameter, in turns though instead of plots:
BOOL generatePath (CyPlot pToPlot, INT iFlags, BOOL bReuse, INT piPathTurns)

The key to the generatePath function is the "pToPlot". So I'll be more specific: We need a function that can detect an impassable "ICE" plot and ID it's location. Why? ...Because the destination "pToPlot" must be identified before we can send a unit to that destination plot. Secondly, there are other functions out there that use the "continue" command to proceed through the loop process after detecting an impassable plot. Continue is used because the function will fail when it detects the impassable plot.
 
The key to the generatePath function is the "pToPlot". So I'll be more specific: We need a function that can detect an impassable "ICE" plot and ID it's location. Why? ...Because the destination "pToPlot" must be identified before we can send a unit to that destination plot. Secondly, there are other functions out there that use the "continue" command to proceed through the loop process after detecting an impassable plot. Continue is used because the function will fail when it detects the impassable plot.
I think you misunderstood me.
Your problem is this line:
iPlotDistance = CyMap().calculatePathDistance(pUnitPlot, pLoopPlot)
It will always fail for ice target plots as they are impassable.

But your unit can enter the impassable plot. So a generatePath on the unit will not fail and piPathTurns which is a return value will give you an estimate of the path length in turns to reach the target plot for the icebreaker.
So try to generate a path to all plots within a range of 10 in x and y direction around the current position that have ice and then only take it if piPathTurns is below a certain threshold.
 
I think you misunderstood me.
Your problem is this line:
iPlotDistance = CyMap().calculatePathDistance(pUnitPlot, pLoopPlot)
It will always fail for ice target plots as they are impassable.

But your unit can enter the impassable plot. So a generatePath on the unit will not fail and piPathTurns which is a return value will give you an estimate of the path length in turns to reach the target plot for the icebreaker.
So try to generate a path to all plots within a range of 10 in x and y direction around the current position that have ice and then only take it if piPathTurns is below a certain threshold.

Any chance you could provide an example function?
 
Any chance you could provide an example function?
In pseudo code:
for each plot in range 10 from current plot in x direction
for each plot in range 10 from current plot in y direction
if plot has feature ICE
if (add your other restrictions to the ice plot here)
if generatePath to the plot with ice breaker unit works and the distance in turns is smaller than 2 (returned from generatePath in the last variable)
then push the mission to go there and break some ice
 
Back
Top Bottom