python help needed for FFH mapscript

[to_xp]Gekko

QCT junkie
Joined
Dec 16, 2005
Messages
7,950
Location
Seyda Neen, Vvardenfell
Guys, I need help with this bit of python...


Code:
x = plot.getX()
y = plot.getY()

# cycle through the surrounding plots
for xx in range(x - 3, x + 3):
	for yy in range(y - 3, y + 3):
		if yy == y or xx == x:
			continue
		nPlot = gameMap.plot(xx,yy)
		featureType = nPlot.getFeatureType()
		terrainType = nPlot.getTerrainType()
		cityRing = float(max(abs(x-xx),abs(y-yy)))
		cityRingMod = 0
		if nPlot.isRiver():
			cityRingMod = -1

		# With FfH we need to make sure we don't break the unique
		# features, which are really improvements.
		if nPlot.getImprovementType() == ImprovementTypes.NO_IMPROVEMENT and nPlot.getBonusType(TeamTypes.NO_TEAM) == BonusTypes.NO_BONUS:
			if terrainType == tundra: 
				if tv < 2:
					if PRand.random() > 0.1 * (cityRing + cityRingMod):
						nPlot.setTerrainType(grass,True,True)
					elif PRand.random() > 0.1 * (cityRing + cityRingMod):
						nPlot.setTerrainType(snow,True,True)
			if nPlot.getPlotType() == PlotTypes.PLOT_HILLS:
				if PRand.random() > 0.3 * (cityRing + cityRingMod):
					nPlot.setPlotType(PlotTypes.PLOT_LAND,True,True)
					if nPlot.isRiver() and terrainType == desert:
					       nPlot.setFeatureType(mc.itFeatureFloodPlains,0)	
			elif nPlot.isPeak():
				if PRand.random() > 0.15 * (cityRing + cityRingMod) or cityRing == 1:
					nPlot.setPlotType(PlotTypes.PLOT_HILLS,True,True)

			if featureType == mc.itFeatureJungle and jv < 2:
				if PRand.random() > 0.15 * (cityRing + cityRingMod):
					nPlot.setFeatureType(mc.itFeatureForest,0)
			elif featureType == mc.itFeatureForest and tv > 1:
				if PRand.random() > 0.25 * (cityRing + cityRingMod):
					nPlot.setFeatureType(mc.itNoFeature,0)

			if PRand.random() > 0.2 * (cityRing + cityRingMod):
				nPlot.setTerrainType(grass,True,True)
			elif terrainType == snow and tv < 2:
				if PRand.random() > 0.1 * (cityRing + cityRingMod):
					nPlot.setTerrainType(tundra,True,True)
return






ok so what this code does is clear bad terrain around starting positions in a square shape.

However, it leaves a big + shape unchanged directly above, below, left and right of the starting tile. it looks horrible O.o

How could I change the code to also include those tiles? the starting tile should be considered cityRing == 0 , adjacent ones cityRing == 1 etc.

also it would be awesome if the range for this clearing could be tied to map size: 3 for duel/tiny, 4 for small/standard, 5 for large/huge .


Many, many thanks in advance to anyone that can help :)
 
Thank you! :)

I've been told just removing those 2 lines of code you mention would also work, would there be any difference between the two options?
 
[to_xp]Gekko;11167659 said:
Thank you! :)

I've been told just removing those 2 lines of code you mention would also work, would there be any difference between the two options?
Actually that is even better as you want to process the starting position itself as well.
 
xx == x, when x coordinate = same as your plot.getX() results in a horizontal line untouched
yy == y, when y coordinate = same as your plot.getY() results in a vertical line untouched

Thus,
OR case, results in both happening, which is your cross.
AND case, only happens when both occurs, which is exactly at your plot
Remove both lines, Neither case will occur, every plot in that squre will be edited
 
thanx for the explanation, now I get how it works :)

I'm wondering how it calculates the cityrings now though. I've had to set it to work on a 5 tiles radius to get it to actually work on a 4 tile radius, which seems to suggest it's counting the starting tile as 1 instead of 0 like before.

So now I'm hoping it's not running the code twice in those two lines that used to be untouched, and also that it's not counting the first ring as cityRing == 2 etc, which would mess up the values used for softening...
 
usually, if I want a radius of 2,

i will use for x in range (iX - 2, iX +3, 1)
because, the last number is not included.
So it will use iX -2, iX -1, iX, iX +1, iX +2

If you do the same for y, u will end up getting this:

XXXXX
XXXXX
XXXXX
XXXXX
XXXXX

If you do not want the 4 corners to be included, additional check has to be done
 
the last number is not included! that's what I was witnessing then...

so what I need for a radius of 4 around the starting plot is actually:


Code:
for xx in range(x - 4, x + 5, 1):
for yy in range(y - 4, y + 5, 1):

( what's the 1 for? )


Do you think it will then use the correct cityRing values in all directions?



Thanks a lot for the help, much appreciated :)
 
the last number is to set the increment each loop.

for x in range (3, 10, 2):
first time, x is 3, 2nd time x is 5, 3rd time x is 7...

Without it, x in range (3, 10), it just assumes the increment to be 1.
so (3, 10) and (3, 10, 1) actually do the same thing, but when you want the increment to be different than 1, then the 3rd number has a meaning.

If your ideal situation is just a complete square, 4 units to left and right, including the corners.
Then, yeah, the above code will do
 
the last number is to set the increment each loop.

for x in range (3, 10, 2):
first time, x is 3, 2nd time x is 5, 3rd time x is 7...

Without it, x in range (3, 10), it just assumes the increment to be 1.
so (3, 10) and (3, 10, 1) actually do the same thing, but when you want the increment to be different than 1, then the 3rd number has a meaning.


so if the third number is 1 anyway it's actually redundant to include it?



If your ideal situation is just a complete square, 4 units to left and right, including the corners.
Then, yeah, the above code will do


A complete square, 4 units to left and right, including the corners is the ideal starting situation, yes.

If you check the code in the OP you can see how then for each plot a random number is chosen, then multiplied by the cityRing value so that the effect gets weaker as distance from the center grows.

However, I'm not 100% sure it now correctly sets the cityRing value.
 
yea, redundant if always 1.

Not too sure about your cityRing effects, but here I realise we havent answered your second question.

getWorldSize() function will return the size of the world literally. 0 = duel, 1 = tiny n so on.

I still exploring the various functions myself using this website:
http://civ4bug.sourceforge.net/PythonAPI/index4.html
 
thanks, I'll test a bit to see if the cityRing values act as they should or not :D

another user suggested something like:


Spoiler :
Code:
iradius = 4

if gc.getWorldInfo(map.getWorldSize()).getType() = gc.getInfoTypeForString('WORLDSIZE_DUEL') or gc.getWorldInfo(map.getWorldSize()).getType() = gc.getInfoTypeForString('WORLDSIZE_TINY'):
	iradius = 3
elif gc.getWorldInfo(map.getWorldSize()).getType() = gc.getInfoTypeForString('WORLDSIZE_LARGE') or gc.getWorldInfo(map.getWorldSize()).getType() = gc.getInfoTypeForString('WORLDSIZE_HUGE'):
	iradius = 5
[/QUOTE]

for my second question, which seems like it would work :)
 
Your cityRing value looks correct. It assumes square city rings (not the crosses that Civ uses for workable city radius) and considers river plots as one closer.
 
let's see if I'm doing this right... :D

Code:
x = plot.getX()
y = plot.getY()
iradius = 4
if gc.getWorldInfo(map.getWorldSize()).getType() = gc.getInfoTypeForString('WORLDSIZE_DUEL') or gc.getWorldInfo(map.getWorldSize()).getType() = gc.getInfoTypeForString('WORLDSIZE_TINY'):
	iradius = 3
elif gc.getWorldInfo(map.getWorldSize()).getType() = gc.getInfoTypeForString('WORLDSIZE_LARGE') or gc.getWorldInfo(map.getWorldSize()).getType() = gc.getInfoTypeForString('WORLDSIZE_HUGE'):
	iradius = 5

# cycle through the surrounding plots
for xx in range(x - iradius, x + (iradius + 1)):
	for yy in range(y - iradius, y + (iradius + 1)):
		nPlot = gameMap.plot(xx,yy)
		featureType = nPlot.getFeatureType()
		terrainType = nPlot.getTerrainType()
		cityRing = float(max(abs(x-xx),abs(y-yy)))
		cityRingMod = 0
		if nPlot.isRiver():
			cityRingMod = -1


this seems like it would do everything I wanted it to do :)
 
i believe it should be == rather than = in the first 2 if statements when u want to compare if they are similar
 
Back
Top Bottom