def spellSpiralGate(argslist):
if isinstance( argslist, tuple ):
makeHelpText = True
eSpell, caster = argslist
else:
caster = argslist
makeHelpText=False
iPlayer = caster.getOwner()
pPlayer = gc.getPlayer(iPlayer)
eTeam = gc.getTeam(pPlayer.getTeam())
bonusCategory = dict()
bonusCategory['false laroth'] = dict()
bonusCategory['archer'] = dict()
bonusCategory['adept'] = dict()
bonusCategory['melee'] = dict()
bonusCategory['recon'] = dict()
bonusCategory['mounted'] = dict()
bonusCategory['supplies'] = dict()
bonusCategory['population'] = dict()
unitUpgrades = dict()
# A list of units to be given
# Each unit is described with a tuple
# ( unitString, bonusCategoryName, promotionList, name)
giveUnits = []
giveUnits.append( ( 'UNIT_NECROMANCER', 'false laroth', ['PROMOTION_DEATH1', 'PROMOTION_DEATH2', 'PROMOTION_SPIRIT1', 'PROMOTION_SPIRIT2', 'PROMOTION_SHADOW1', 'PROMOTION_SHADOW2', 'PROMOTION_COMBAT1', 'PROMOTION_COMBAT2', 'PROMOTION_HIDDEN', 'PROMOTION_IMPLACABLE', ], CyTranslator().getText('TXT_KEY_UNIT_FALSE_LAROTH',() ) ) )
bonusCategory['false laroth']['xp'] = 10
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_ARCHERY') ):
giveUnits.append( ( 'UNIT_ARCHER', 'archer', ['PROMOTION_IMPLACABLE', ], 'Anyon' ) )
giveUnits.append( ( 'UNIT_ARCHER', 'archer', ['PROMOTION_IMPLACABLE', ], 'Lann' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_BRONZE_WORKING') ):
giveUnits.append( ( 'UNIT_HONORED_BAND', 'melee', ['PROMOTION_IMPLACABLE', ], 'Medb' ) )
giveUnits.append( ( 'UNIT_HONORED_BAND', 'melee', ['PROMOTION_IMPLACABLE', ], 'Aife' ) )
bonusCategory['melee']['weapons'] = 'PROMOTION_BRONZE_WEAPONS'
bonusCategory['false laroth']['weapons'] = 'PROMOTION_BRONZE_WEAPONS'
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_IRON_WORKING') ):
giveUnits.append( ( 'UNIT_PRINCIPES', 'melee', ['PROMOTION_IMPLACABLE', ], 'Scathach' ) )
giveUnits.append( ( 'UNIT_PRINCIPES', 'melee', ['PROMOTION_IMPLACABLE', ], 'Voadica' ) )
giveUnits.append( ( 'UNIT_HONORED_BAND', 'melee', [], '' ) )
bonusCategory['melee']['weapons'] = 'PROMOTION_IRON_WEAPONS'
bonusCategory['false laroth']['weapons'] = 'PROMOTION_IRON_WEAPONS'
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_TRADE')):
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_STIRRUPS')):
giveUnits.append( ( 'UNIT_HORSE_ARCHER', 'mounted', [], '' ) )
giveUnits.append( ( 'UNIT_HORSE_ARCHER', 'mounted', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_WARHORSES')):
giveUnits.append( ( 'UNIT_HORSE_ARCHER', 'mounted', [], '' ) )
giveUnits.append( ( 'UNIT_HORSE_ARCHER', 'mounted', [], '' ) )
giveUnits.append( ( 'UNIT_HORSE_ARCHER', 'mounted', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
# if eTeam.isHasTech(gc.getInfoTypeForString('TECH_ARMORED_CAVALRY')):
# giveUnits.append( ( 'UNIT_HORSE_ARCHER', 'mounted', ['PROMOTION_COMBAT1', ], '' ) )
# giveUnits.append( ( 'UNIT_HORSE_ARCHER', 'mounted', ['PROMOTION_COMBAT1', ], '' ) )
# giveUnits.append( ( 'UNIT_SPIRAL_SUPPLIES', 'supplies', [], '' ) )
# giveUnits.append( ( 'UNIT_SPIRAL_SUPPLIES', 'supplies', [], '' ) )
# bonusCategory['mounted']['xp'] = 10
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_ANIMAL_HANDLING')):
giveUnits.append( ( 'UNIT_CETRATUS', 'recon', [], '' ) )
giveUnits.append( ( 'UNIT_CETRATUS', 'recon', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_FERAL_BOND')):
giveUnits.append( ( 'UNIT_GHOSTWALKER', 'recon', [], '' ) )
giveUnits.append( ( 'UNIT_GHOSTWALKER', 'recon', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_ANIMAL_MASTERY')):
giveUnits.append( ( 'UNIT_GHOSTWALKER', 'recon', ['PROMOTION_IMPLACABLE', ], 'Gurith' ) )
giveUnits.append( ( 'UNIT_GHOSTWALKER', 'recon', ['PROMOTION_IMPLACABLE', 'PROMOTION_COMBAT1', 'PROMOTION_COMBAT2', ], 'Fathen' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_SMELTING')):
giveUnits.append( ( 'UNIT_HONORED_BAND', 'melee', [], '' ) )
# giveUnits.append( ( 'UNIT_SPIRAL_SUPPLIES', 'supplies', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_SANITATION')):
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_MEDICINE')):
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_MITHRIL_WORKING')):
# giveUnits.append( ( 'UNIT_SPIRAL_SUPPLIES', 'supplies', [], '' ) )
giveUnits.append( ( 'UNIT_PHALANX', 'melee', [ ], '' ) )
giveUnits.append( ( 'UNIT_PHALANX', 'melee', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
bonusCategory['melee'].setdefault( 'promotions', [] ).append( 'PROMOTION_ENCHANTED_BLADE' )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_ASTRONOMY')):
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_BOWYERS')):
giveUnits.append( ( 'UNIT_LONGBOWMAN', 'archer', [], '' ) )
giveUnits.append( ( 'UNIT_LONGBOWMAN', 'archer', [], '' ) )
giveUnits.append( ( 'UNIT_LONGBOWMAN', 'archer', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_PRECISION')):
giveUnits.append( ( 'UNIT_LONGBOWMAN', 'archer', [], '' ) )
giveUnits.append( ( 'UNIT_LONGBOWMAN', 'archer', [], '' ) )
giveUnits.append( ( 'UNIT_MARKSMAN', 'archer', ['PROMOTION_IMPLACABLE', ], 'Tadc' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_TAXATION')):
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_GUILDS')):
# giveUnits.append( ( 'UNIT_SPIRAL_SUPPLIES', 'supplies', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_MERCANTILISM')):
# giveUnits.append( ( 'UNIT_SPIRAL_SUPPLIES', 'supplies', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_MILITARY_STRATEGY')):
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
bonusCategory['melee']['xp'] = 6
bonusCategory['archer']['xp'] = 6
bonusCategory['recon']['xp'] = 6
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_ENGINEERING')):
# giveUnits.append( ( 'UNIT_SPIRAL_SUPPLIES', 'supplies', [], '' ) )
giveUnits.append( ( 'UNIT_CATAPULT', 'supplies', ['PROMOTION_ACCURACY', ], '' ) )
giveUnits.append( ( 'UNIT_CATAPULT', 'supplies', ['PROMOTION_BARRAGE1', ], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_BLASTING_POWDER')):
giveUnits.append( ( 'UNIT_BONE_HORDE', 'archer', [], '' ) )
giveUnits.append( ( 'UNIT_BONE_HORDE', 'archer', [], '' ) )
giveUnits.append( ( 'UNIT_BONE_HORDE', 'archer', [], '' ) )
giveUnits.append( ( 'UNIT_BONE_HORDE', 'archer', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_SORCERY')):
unitUpgrades['UNIT_ADEPT'] = 'UNIT_NECROMANCER'
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_ARCANE_LORE')):
giveUnits.append( ( 'UNIT_NECROMANCER', 'adept', ['PROMOTION_DEATH1', 'PROMOTION_DEATH2', ], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_STRENGTH_OF_WILL')):
giveUnits.append( ( 'UNIT_NECROMANCER', 'adept', ['PROMOTION_DEATH1', 'PROMOTION_DEATH2', 'PROMOTION_COMBAT1', ], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_PASS_THROUGH_THE_ETHER')):
giveUnits.append( ( 'UNIT_NECROMANCER', 'adept', ['PROMOTION_DEATH1', 'PROMOTION_COMBAT2', 'PROMOTION_COMBAT1', ], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
# giveUnits.append( ( 'UNIT_SPIRAL_SUPPLIES', 'supplies', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_MACHINERY')):
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
giveUnits.append( ( 'UNIT_CATAPULT', 'supplies', [], '' ) )
giveUnits.append( ( 'UNIT_CATAPULT', 'supplies', [], '' ) )
# giveUnits.append( ( 'UNIT_SPIRAL_SUPPLIES', 'supplies', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_OMNISCIENCE')):
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
giveUnits.append( ( 'UNIT_NECROMANCER', 'adept', ['PROMOTION_DEATH1', 'PROMOTION_DEATH2', 'PROMOTION_COMBAT1', 'PROMOTION_COMBAT2', 'PROMOTION_COMBAT3', ], '' ) )
giveUnits.append( ( 'UNIT_NECROMANCER', 'adept', ['PROMOTION_DEATH1', 'PROMOTION_DEATH2', 'PROMOTION_COMBAT1', 'PROMOTION_FIRE1', 'PROMOTION_FIRE2', 'PROMOTION_IMPLACABLE', ], 'Tetricues' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_DIVINATION')):
bonusCategory['adept']['xp'] = bonusCategory['adept'].get('xp', 0 ) +2
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_ALTERATION')):
giveUnits.append( ( 'UNIT_GHOSTWALKER', 'recon', ['PROMOTION_ILLUSION', 'PROMOTION_IMPLACABLE', ], 'Otal the Faded' ) )
bonusCategory['adept']['xp'] = bonusCategory['adept'].get('xp', 0 ) +2
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_NECROMANCY')):
bonusCategory['adept']['xp'] = bonusCategory['adept'].get('xp', 0 ) +2
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_ELEMENTALISM')):
bonusCategory['archer'].setdefault( 'promotions', [] ).append( 'PROMOTION_FLAMING_ARROWS' )
bonusCategory['adept']['xp'] = bonusCategory['adept'].get('xp', 0 ) +2
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_RELIGIOUS_LAW')):
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_THEOLOGY')):
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_COMMUNE_WITH_NATURE')):
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_FANATICISM')):
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
giveUnits.append( ( 'UNIT_REVENANT', 'melee', ['PROMOTION_INQUISITOR', ], 'Rasaec the Hollow' ) ) # Revenants are disciples, but very melee like disciples
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_MALEVOLENT_DESIGNS')):
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_RIGHTEOUSNESS')):
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
if eTeam.isHasTech(gc.getInfoTypeForString('TECH_DIVINE_ESSENCE')):
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
giveUnits.append( ( 'UNIT_AWAKENED', 'population', [], '' ) )
giveUnits.append( ( 'UNIT_ABOMINATION', 'melee', [], '' ) )
if not makeHelpText:
pCapital = pPlayer.getCapitalCity()
capitalX = pCapital.getX()
capitalY = pCapital.getY()
bestPlotGoodness = -1
iBestPlot = None
for i in xrange (CyMap().numPlots()):
pPlot = CyMap().plotByIndex(i)
plotGoodness = -1
if ( pPlot.getOwner() != iPlayer
and not pPlot.isWater()
and pPlot.getNumUnits() == 0
and not pPlot.isCity()
and not pPlot.isImpassable() ):
plotGoodness = CyGame().getSorenRandNum(500, "Place Spiral Gate")
# I'm placing a limit on the added goodness.
# This makes final goodness a bit less map dependant and less predictable.
# The limits will need finetuning.
# With a limit of 250, all continents with at least 175 tiles are equally good.
plotGoodness += min( pPlot.area().getNumTiles() * 2, 100 )
# With a limit of 500, all continents with at least 100 unclaimed tiles are equally good.
plotGoodness += min( pPlot.area().getNumUnownedTiles() * 5, 400 )
# Distance to capital is squared, since area is squared
# With a limit of 450, all tiles further away than 450**.5 or 21 squares are equally good
plotGoodness += min( ( (pPlot.getX()-capitalX)**2 + (pPlot.getY()-capitalY)**2 ), 750)
if not pPlot.isOwned():
plotGoodness += 300
if plotGoodness > bestPlotGoodness:
bestPlotGoodness = plotGoodness
pBestPlot = pPlot
if pBestPlot is None:
# It's a world spell, it shouldn't fail just because. Probably won't anyway
# but just to be sure.
pBestPlot = pCapital.plot()
pBestPlot.setFeatureType(gc.getInfoTypeForString('FEATURE_HAUNTED_LANDS'),0)
commonInitUnitArgs = ( pBestPlot.getX(), pBestPlot.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_NORTH )
for unitString, bonusCategoryName, promotionList, name in giveUnits:
while unitString in unitUpgrades:
unitString = unitUpgrades[unitString]
newUnit = pPlayer.initUnit(gc.getInfoTypeForString(unitString), pBestPlot.getX(), pBestPlot.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_NORTH)
# newUnit = pPlayer.initUnit( gc.getInfoTypeForString(unitString), *commonInitUnitArgs )
for promotionString in promotionList:
newUnit.setHasPromotion( gc.getInfoTypeForString( promotionString ), True)
if 'promotions' in bonusCategory[bonusCategoryName]:
for promotionString in bonusCategory[bonusCategoryName]['promotions']:
newUnit.setHasPromotion( gc.getInfoTypeForString( promotionString ), True)
if 'weapons' in bonusCategory[bonusCategoryName]:
newUnit.setHasPromotion( gc.getInfoTypeForString( bonusCategory[bonusCategoryName]['weapons'] ), True)
if 'xp' in bonusCategory[bonusCategoryName]:
newUnit.setExperience(bonusCategory[bonusCategoryName]['xp'], -1)
if name:
newUnit.setName(name)
else:
counts = dict( (key,0) for key in [ 'false laroth', 'archer', 'adept', 'melee', 'recon', 'mounted', 'supplies', 'population' ])
for unitString, bonusCategoryName, promotionList, name in giveUnits:
counts[unitString] = counts.get( unitString, 0) +1
counts[bonusCategoryName] += 1
counts['military'] = sum( c for key, c in counts.iteritems() if key in set( [ 'false laroth', 'archer', 'adept', 'melee', 'recon', 'mounted', ] ) )
templateHelpString = 'Treachery in the Land of the Dead. A false Laroth steals away additional subjects for the Scions. Currently casting this spell will give %(military)i military units, %(supplies)i supplies, and %(population)i Awakened. The units will appear in a random, probably distant, location.'
return templateHelpString % counts