Founding cities only on specific tiles

oh joy now it's messed up in a new and varied way??????

It says i'm generating -120012012112ish gold although it goes up slowly in the positive, and my starting unit is automatically upgraded to the maximum level it just keeps promoting!!

as well as a bunch of other stuff just happening before its supposed to?
 
First you want to make sure that normal Settlers can in fact settle anywhere, so check for that first. Then do a resource-by-resource check of all your special settlers after that, with a two-part 'if' - one to check the unit and one to check for the resource. Finally, to make sure nobody else settles anywhere, the entire function should return True at the end (since we explicitly stated all the places people could settle in those 'if' statements).

Code:
	def cannotFoundCity(self,argsList):
		iPlayer, iPlotX, iPlotY = argsList
		pPlot = CyMap().plot(iPlotX, iPlotY)
		for i in range(pPlot.getNumUnits()):
			pUnit = pPlot.getUnit(i)
			if pUnit.getUnitType() == gc.getInfoTypeForString('UNIT_SETTLER'):
				return False
			elif pUnit.getUnitType() == gc.getInfoTypeForString('UNIT_COPPER_SETTLER'):
				if pPlot.getBonusType() == gc.getInfoTypeForString('BONUS_COPPER'):
					return False
			elif pUnit.getUnitType() == gc.getInfoTypeForString('UNIT_RICE_SETTLER'):
				if pPlot.getBonusType() == gc.getInfoTypeForString('BONUS_RICE'):
					return False
			elif pUnit.getUnitType() == gc.getInfoTypeForString('UNIT_CORN_SETTLER'):
				if pPlot.getBonusType() == gc.getInfoTypeForString('BONUS_CORN'):
					return False
		return True

Of course all those other kinds of Settlers need to be defined, but you can just copy the XML for normal Settlers and change the names and they should work (although I don't know how the AI would react to a Settler that can't settle everywhere!). (and of course I haven't tested this function, but if you have the callback set to true it should run and restrict where you can settle.. you can test whether it's running by cutting out all the code but "return True" and seeing if it prevents settling at all).
 
grrrr....

I tried your code Cao, but the special settler still won't only found on the specific tile type it still works everywhere.

also when i added it, it messed thing up like before e.g. the gold meter at the top say -123234843 (random long number) any ideas why it would do that?

heres my code:

def cannotFoundCity(self,argsList):
iPlayer, iPlotX, iPlotY = argsList
pPlot = CyMap().plot(iPlotX, iPlotY)
for i in range(pPlot.getNumUnits()):
pUnit = pPlot.getUnit(i)
if pUnit.getUnitType() == gc.getInfoTypeForString('UNIT_SETTLER'):
return False
elif pUnit.getUnitType() == gc.getInfoTypeForString('UNIT_EXCAVATOR'):
if pPlot.getFeatureType() == gc.getInfoTypeForString('FEATURE_RUIN'):
return False
return True

If i delete it the game goes back to working properly??
 
heres my code:
Can you put your code in a [ code ] block please? It's the # key in the message editor. Python pays attention to spaces/tabs/etc which isn't true in most languages, so it might be as simple as an indentation error.
 
Do you actually need the elifs in there? Most Civilization 4 python I've seen omits them.

The code should look like this, I think:

Code:
def cannotFoundCity(self,argsList):
	iPlayer, iPlotX, iPlotY = argsList
	pPlot = CyMap().plot(iPlotX, iPlotY)
	for i in range(pPlot.getNumUnits()):
		pUnit = pPlot.getUnit(i)
		if pUnit.getUnitType() == gc.getInfoTypeForString('UNIT_SETTLER'):
			return False
		elif pUnit.getUnitType() == gc.getInfoTypeForString('UNIT_EXCAVATOR'):
			if pPlot.getFeatureType() == gc.getInfoTypeForString('FEATURE_RUIN'): 
				return False
		return True

Wait, I think I see your error, well, at least one. Ruins are improvements, not features. So, the game is looking for "FEATURE_RUIN", not finding one, and then simply allowing your unit to settle wherever. Further, the actual name of the City Ruins is IMPROVEMENT_CITY_RUINS... unless you've added a FEATURE_RUIN?

Python doesn't check to make sure the referenced XML is valid, only that the Python syntax is correct.
 
Do you actually need the elifs in there? Most Civilization 4 python I've seen omits them.

The code should look like this, I think:
That final 'return True' should be on the same indentation level as the 'for' statement. You only want to return True once you know none of the units can settle; if you have it inside the 'for' loop then as soon as you have a non-Settler in the stack you can settle.
 
right ok, I was wondering if the indentations were specifically important, i thought they might be but didn't know in what way.

Yeah sorry about the ruin thing I am working in the fury road mod and it has city ruins as a feature of the landscape its in terrain features xml and i've checked that it matches.

Eventually if the concept works I want to create new terrain features to actually apply it to but unless i can get the concept working and understood there's no point.
 
Code:
def cannotFoundCity(self,argsList):
	iPlayer, iPlotX, iPlotY = argsList
	pPlot = CyMap().plot(iPlotX, iPlotY)
	for i in range(pPlot.getNumUnits()):
	pUnit = pPlot.getUnit(i)
	if pUnit.getUnitType() == gc.getInfoTypeForString('UNIT_SETTLER'):
		return False
	elif pUnit.getUnitType() == gc.getInfoTypeForString('UNIT_EXCAVATOR'):
	if pPlot.getFeatureType() == gc.getInfoTypeForString('FEATURE_RUIN'):		
		return False
	return True
 
Code:
def cannotFoundCity(self,argsList):
	iPlayer, iPlotX, iPlotY = argsList
	pPlot = CyMap().plot(iPlotX, iPlotY)
	for i in range(pPlot.getNumUnits()):
	pUnit = pPlot.getUnit(i)
	if pUnit.getUnitType() == gc.getInfoTypeForString('UNIT_SETTLER'):
		return False
	elif pUnit.getUnitType() == gc.getInfoTypeForString('UNIT_EXCAVATOR'):
	if pPlot.getFeatureType() == gc.getInfoTypeForString('FEATURE_RUIN'):		
		return False
	return True

This is wrong. After "for", "if", "elif", you must indent, so it should look something like this:

Code:
def cannotFoundCity(self,argsList):
	iPlayer, iPlotX, iPlotY = argsList
	pPlot = CyMap().plot(iPlotX, iPlotY)
	for i in range(pPlot.getNumUnits()):
		pUnit = pPlot.getUnit(i)
		if pUnit.getUnitType() == gc.getInfoTypeForString('UNIT_SETTLER'):
			return False
		elif pUnit.getUnitType() == gc.getInfoTypeForString('UNIT_EXCAVATOR'):
			if pPlot.getFeatureType() == gc.getInfoTypeForString('FEATURE_RUIN'):		
				return False
	return True

Try using this code and see if it works.
 
EDIT: Don't triple-post like that if you don't have to, because if I'm replying to one post, it's annoying to have my stuff come up in the middle.

Use the EDIT button instead.
 
Code:
def cannotFoundCity(self,argsList):
	iPlayer, iPlotX, iPlotY = argsList
	pPlot = CyMap().plot(iPlotX, iPlotY)
	for i in range(pPlot.getNumUnits()):
		pUnit = pPlot.getUnit(i)
		if pUnit.getUnitType() == gc.getInfoTypeForString('UNIT_SETTLER'):
			return False
		elif pUnit.getUnitType() == gc.getInfoTypeForString('UNIT_EXCAVATOR'):
			if pPlot.getFeatureType() == gc.getInfoTypeForString('FEATURE_RUIN'):		
					return False
		return True

thats how it looks now?
 
Code:
def cannotFoundCity(self,argsList):
	iPlayer, iPlotX, iPlotY = argsList
	pPlot = CyMap().plot(iPlotX, iPlotY)
	for i in range(pPlot.getNumUnits()):
		pUnit = pPlot.getUnit(i)
		if pUnit.getUnitType() == gc.getInfoTypeForString('UNIT_SETTLER'):
			return False
		elif pUnit.getUnitType() == gc.getInfoTypeForString('UNIT_EXCAVATOR'):
			if pPlot.getFeatureType() == gc.getInfoTypeForString('FEATURE_RUIN'):		
					return False
		return True

thats how it looks now?

The second to last line, "return False", is indented one tab too many.

Apart from that, it's good.
 
right i tried to indent the def line and when i loaded a game it crashed while loading up, this may have been a coincidence though so I will try again.

Also Fury Road has it's own CvFuryRoadGameUtils, this is where I put it, do I need to bring a BTS GameUtil file over and add it into there instead or do I need to add something else to the FuryRoad version instead?
 
Top Bottom