ai

omegaflames

Warlord
Joined
Sep 21, 2012
Messages
181
where are the ai files at for civ 4? im looking to get the ai to spread religion more often if it controls a religion's shrine (that and to see about getting the ai to actually use my terraforming spells)
 
Do you have experience with modding the DLL/SDK? It takes some setup and good knowledge of programming to do. To modify the AI you usually have to modify the DLL/SDK and change files like CvPlayerAI.cpp and CvUnitAI.cpp. This would probably be required for what you want to do with religion.

If you don't have experience with the DLL then there are some ways around it that would be easier. You could create new missionary units that can only be built in the religion's holy city, and give those units a high value for iAIWeight. A higher value of iAIWeight should make the AI build more of them. That would all be done in the CIV4UnitInfos.xml file.

I haven't looked at how the terraforming AI works in FFH, but I noticed this
Code:
<bAllowAutomateTerrain>1</bAllowAutomateTerrain>
in CIV4SpellInfos.xml for terraforming spells like Bloom in Tholal's More Naval AI.
 
With the help of articnightwolf I got a small block of code that might do the job but I'm having trouble getting it to actually do anything. What I wanted to do was everytime a unit moved in his territory if it could cast the terraform spell (in this case spring) then it should cast it. I found a couple places in cvspellinterface and cveventmanager that might be the code that gets executed when a unit moves but so far when I move my own mages they aren't casting spring. In cvspellinterface I have
Code:
def onMove(argsList):
	pCaster, pPlot, eImp = argsList
	imp = gc.getImprovementInfo(eImp)
	eval(imp.getPythonOnMove())
[COLOR="Red"]	pPlot = caster.plot()
	pPlayer = gc.getPlayer(caster.getOwner())
	if caster.getOwner() == pPlot.getOwner():
		if caster.canCast(gc.getInfoTypeForString('SPELL_SPRING'), false):
			caster.cast(gc.getInfoTypeForString('SPELL_SPRING'))[/COLOR]
and in cveventmanager I have
Code:
	def onUnitMove(self, argsList):
		'unit move'
		pPlot,pUnit,pOldPlot = argsList
		player = PyPlayer(pUnit.getOwner())
		unitInfo = PyInfo.UnitInfo(pUnit.getUnitType())
		if (not self.__LOG_MOVEMENT):
			return
		if player and unitInfo:
			CvUtil.pyPrint('Player %d Civilization %s unit %s is moving to %d, %d' 
				%(player.getID(), player.getCivilizationName(), unitInfo.getDescription(), 
				pUnit.getX(), pUnit.getY()))
[COLOR="Red"]		if pUnit.getOwner() == pPlot.getOwner():
			if pUnit.canCast(gc.getInfoTypeForString('SPELL_SPRING'), false):
				pUnit.cast(gc.getInfoTypeForString('SPELL_SPRING'))[/COLOR]
Red text is what I added myself. I tried replacing "pUnit" in the cvveventmanager part with "caster" but that didn't help either. Any thoughts as to what I'm doing wrong?
 
With the help of articnightwolf I got a small block of code that might do the job but I'm having trouble getting it to actually do anything. What I wanted to do was everytime a unit moved in his territory if it could cast the terraform spell (in this case spring) then it should cast it. I found a couple places in cvspellinterface and cveventmanager that might be the code that gets executed when a unit moves but so far when I move my own mages they aren't casting spring. In cvspellinterface I have [..]

well, not sure whether it is where the problem lies, but red part you added in def onUnitMove should definitely be BEFORE this
Code:
if (not self.__LOG_MOVEMENT):
return

also, for the record, i'd like to mention, that the changes you are making might slow the game, since you will execute these every time someone moves unit
 
Code:
def spellSpring(caster):
	pPlot = caster.plot()
	if pPlot.isnotPeak():
		if pPlayer.isHuman() == False:
			if pPlayer.getCivilizationType() == gc.getInfoTypeForString('CIVILIZATION_ILLIANS'):
				if pPlot.getTerrainType()==gc.getInfoTypeForString('TERRAIN_DESERT'):
					if pPlot.getFeatureType() != gc.getInfoTypeForString('FEATURE_FLOOD_PLAINS'):
						if pPlot.getFeatureType() != gc.getInfoTypeForString('FEATURE_OASIS'):
							pPlot.setTerrainType(gc.getInfoTypeForString('TERRAIN_PLAINS'),True,True)
				if pPlot.getTerrainType()==gc.getInfoTypeForString('TERRAIN_BURNING_SANDS'):
					if pPlot.getFeatureType() != gc.getInfoTypeForString('FEATURE_FLOOD_PLAINS'):
						if pPlot.getFeatureType() != gc.getInfoTypeForString('FEATURE_OASIS'):
							pPlot.setTerrainType(gc.getInfoTypeForString('TERRAIN_FIELDS_OF_PERDITION'),True,True)
			if pPlayer.getCivilizationType() != gc.getInfoTypeForString('CIVILIZATION_MALAKIM'):
				if pPlayer.getCivilizationType() != gc.getInfoTypeForString('CIVILIZATION_ILLIANS'):
					if pPlot.getTerrainType()==gc.getInfoTypeForString('TERRAIN_PLAINS'):
						pPlot.setTerrainType(gc.getInfoTypeForString('TERRAIN_GRASS'),True,True)
					if pPlot.getTerrainType()==gc.getInfoTypeForString('TERRAIN_FIELDS_OF_PERDITION'):
						pPlot.setTerrainType(gc.getInfoTypeForString('TERRAIN_BROKEN_LANDS'),True,True)
					if pPlot.getTerrainType() == gc.getInfoTypeForString('TERRAIN_DESERT'):
						if pPlot.getFeatureType() != gc.getInfoTypeForString('FEATURE_FLOOD_PLAINS'):
							if pPlot.getFeatureType() != gc.getInfoTypeForString('FEATURE_OASIS'):
								pPlot.setTerrainType(gc.getInfoTypeForString('TERRAIN_PLAINS'),True,True)
					if pPlot.getTerrainType() == gc.getInfoTypeForString('TERRAIN_BURNING_SANDS'):
						if pPlot.getFeatureType() != gc.getInfoTypeForString('FEATURE_FLOOD_PLAINS'):
							if pPlot.getFeatureType() != gc.getInfoTypeForString('FEATURE_OASIS'):
								pPlot.setTerrainType(gc.getInfoTypeForString('TERRAIN_FIELDS_OF_PERDITION'),True,True)
		if pPlayer.isHuman() == True:
			if pPlot.getTerrainType()==gc.getInfoTypeForString('TERRAIN_PLAINS'):
				pPlot.setTerrainType(gc.getInfoTypeForString('TERRAIN_GRASS'),True,True)
			if pPlot.getTerrainType()==gc.getInfoTypeForString('TERRAIN_FIELDS_OF_PERDITION'):
				pPlot.setTerrainType(gc.getInfoTypeForString('TERRAIN_BROKEN_LANDS'),True,True)
			if pPlot.getTerrainType() == gc.getInfoTypeForString('TERRAIN_DESERT'):
				if pPlot.getFeatureType() != gc.getInfoTypeForString('FEATURE_FLOOD_PLAINS'):
					if pPlot.getFeatureType() != gc.getInfoTypeForString('FEATURE_OASIS'):
						pPlot.setTerrainType(gc.getInfoTypeForString('TERRAIN_PLAINS'),True,True)
			if pPlot.getTerrainType() == gc.getInfoTypeForString('TERRAIN_BURNING_SANDS'):
				if pPlot.getFeatureType() != gc.getInfoTypeForString('FEATURE_FLOOD_PLAINS'):
					if pPlot.getFeatureType() != gc.getInfoTypeForString('FEATURE_OASIS'):
						pPlot.setTerrainType(gc.getInfoTypeForString('TERRAIN_FIELDS_OF_PERDITION'),True,True)
	iX = pPlot.getX()
	iY = pPlot.getY()
	for iiX in range(iX-1, iX+2, 1):
		for iiY in range(iY-1, iY+2, 1):
			pPlot2 = CyMap().plot(iiX,iiY)
			if pPlot2.getFeatureType() == gc.getInfoTypeForString('FEATURE_FLAMES'):
				pPlot2.setFeatureType(-1, -1)
			if pPlot2.getImprovementType() == gc.getInfoTypeForString('IMPROVEMENT_SMOKE'):
				pPlot2.setImprovementType(-1)
 
putting this here for future reference
Code:
	def onUnitMove(self, argsList):
		'unit move'
		pPlot,pUnit,pOldPlot = argsList
		player = PyPlayer(pUnit.getOwner())
		unitInfo = PyInfo.UnitInfo(pUnit.getUnitType())
		if player.isHuman() == False:
			if pUnit.getOwner() == pPlot.getOwner():
				if pUnit.canCast(gc.getInfoTypeForString('SPELL_SPRING'), False):
					pUnit.cast(gc.getInfoTypeForString('SPELL_SPRING'))
				if pUnit.canCast(gc.getInfoTypeForString('SPELL_SCORCH'), False):
					pUnit.cast(gc.getInfoTypeForString('SPELL_SCORCH'))
				if pUnit.canCast(gc.getInfoTypeForString('SPELL_SNOWYDAY'), False):
					pUnit.cast(gc.getInfoTypeForString('SPELL_SNOWYDAY'))
		if (not self.__LOG_MOVEMENT):
			return
		if player and unitInfo:
			CvUtil.pyPrint('Player %d Civilization %s unit %s is moving to %d, %d' 
				%(player.getID(), player.getCivilizationName(), unitInfo.getDescription(), 
				pUnit.getX(), pUnit.getY()))
 
Regarding the check being done potentially large numbers of times per turn (especially late game) - you can check if any unit is in a particular tile/s which will mean only one check per tile. Late game you may check hundreds of times per turn.

Maybe have a check beforehand that only allows the check on certain game turns (or before a certain time) or some other restriction.
 
Hey sorry for the late reply but I didn't realize I didn't have the forums emailing me when posts got made to my subscribed threads.

What I'd really like to do is have only check when a caster type of unit is moving onto the tile (possibly via the CvSpellInterface.py). If I can get the onMove to work there then that will at least prevent any unit that can't cast anyway from going throu the check.
 
Top Bottom