Fix for Roar spell in 0.34h

bc1

Joined
Jan 12, 2004
Messages
1,332
For those annoyed by this bug, here's a fix:
- the python exception can be fixed by changing line 2385 in CvSpellInterface from "for i in range(pLoopPlot.getNumUnits(),-1,-1)" to "for i in range(pLoopPlot.getNumUnits()-1,-1,-1)"
- for the spell to actually work change line 123 in CustomFunctions.py from "if abs(pLoopPlot.getX() - pPlot.getX()>1) or abs(pLoopPlot.getY() - pPlot.getY()>1):" to "if (abs(pLoopPlot.getX() - pPlot.getX())>1) or (abs(pLoopPlot.getY() - pPlot.getY())>1):"

It's also in the bug thread on page 51...
 
That second line probably needs to be:

Code:
if (abs(pLoopPlot.getX() - pPlot.getX())>1) or (abs(pLoopPlot.getY() - pPlot.getY())>1):
 
After some experience with the gold dragon's roar spell, I ran into a few issues:
1: scared units were running around kicking my own units out of enemy territory (when taking their plot)
2: powerfull entrenched units have an equal chance at being scared than a weak unit, even leading to deserted enemy cities with a roar from a redlined dragon
3: units ran away from entrenched position to undefended terrain for easy picking

So I made myself a modified spell to address these issues
1: use "canMoveInto" rather than "canMoveOrAttackInto" to work around setXY undesirable behavior when enemy units are present
2: apply a modifier to spell resistance based on roughly estimated chance of surviving dragon assault
3: increase chance unit will runaway somewhere safe

If anyone cares here's the substitude code for "doFear" in CustomFunction.py (lines starting with "CyInterface()." can be removed, only for debug purposes, but then the last else: also has to go)
Code:
	def doFear(self, pVictim, pPlot, pCaster, bResistable):
		if pVictim.isImmuneToFear():
			return False
		if bResistable:
			CyInterface().addCombatMessage(pCaster.getOwner(),'%s %s: %f vs %f probability model %f' % (gc.getPlayer(pVictim.getOwner()).getName(), pVictim.getName(), pVictim.currCombatStrFloat(pVictim.plot(),pCaster), pCaster.currCombatStrFloat(pVictim.plot(),pVictim), ((pVictim.currCombatStrFloat(pVictim.plot(),pCaster)/pCaster.currCombatStrFloat(pVictim.plot(),pVictim))**4) ) )
			if CyGame().getSorenRandNum(100, "Fear") < ((pVictim.currCombatStrFloat(pVictim.plot(),pCaster)/pCaster.currCombatStrFloat(pVictim.plot(),pVictim))**4) * (pVictim.getResistChance(pCaster, gc.getInfoTypeForString('SPELL_ROAR')) ):
				CyInterface().addCombatMessage(pCaster.getOwner(),'%s %s at %d,%d stands firm' % (gc.getPlayer(pVictim.getOwner()).getName(), pVictim.getName(), pVictim.getX(), pVictim.getY()) )
				return False
		iX = pVictim.getX()
		iY = pVictim.getY()
		pBestPlot = -1
		iBestPlot = -1
		for iiX in range(iX-1, iX+2, 1):
			for iiY in range(iY-1, iY+2, 1):
				pLoopPlot = CyMap().plot(iiX,iiY)
				if not pLoopPlot.isNone():
					if pVictim.canMoveInto(pLoopPlot, False, False, False):
						if (abs(pLoopPlot.getX() - pPlot.getX()) > 1) or (abs(pLoopPlot.getY() - pPlot.getY()) > 1):
							iRnd = CyGame().getSorenRandNum(50, "Fear") + pLoopPlot.defenseModifier(pVictim.getTeam(),true,false)
							if pLoopPlot.isCity():
								if pLoopPlot.getPlotCity().getOwner() == pVictim.getOwner():
									iRnd += 50
							if iRnd > iBestPlot:
								iBestPlot = iRnd
								pBestPlot = pLoopPlot
		if pBestPlot != -1:
			CyInterface().addCombatMessage(pCaster.getOwner(),'%s %s at %d,%d flees to %d,%d' % (gc.getPlayer(pVictim.getOwner()).getName(), pVictim.getName(), pVictim.getX(), pVictim.getY(),pBestPlot.getX(), pBestPlot.getY()) )
			pVictim.setXY(pBestPlot.getX(), pBestPlot.getY(), false, true, true)
			return True
		else:	
			CyInterface().addCombatMessage(pCaster.getOwner(),'%s %s at %d,%d cannot flee' % (gc.getPlayer(pVictim.getOwner()).getName(), pVictim.getName(), pVictim.getX(), pVictim.getY()) )
		return False
 
Back
Top Bottom