def getWidgetHelp(self, argsList): eWidgetType, iData1, iData2, bOption = argsList printd("eWidgetType %d, iData1 %d, iData2 %d, bOption %d" % (eWidgetType, iData1, iData2, bOption)) #PB Mod begin if (iData1 == 302016): return localText.getText("TXT_KEY_MOD_UNPAUSE_DESC", ()) #PB Mod end szHelpText = u"" # All the FF specific widget help is for widgets with a type of WidgetTypes.WIDGET_GENERAL (FFP post 1.81, for B5, by G-E) if (eWidgetType == WidgetTypes.WIDGET_GENERAL): # Only show tool tip help when players have the tutorial on if (not CyUserProfile().getPlayerOption(PlayerOptionTypes.PLAYEROPTION_MODDER_1)): # Selected Planet if (iData1 == 666): szHelpText = localText.getText("TXT_KEY_FF_INTERFACE_SELECTED_PLANET_HELP", ()) # Planet Population elif (iData1 == 667): szHelpText = localText.getText("TXT_KEY_FF_INTERFACE_PLANET_POPULATION_HELP", ()) # Planet Yield elif (iData1 == 668): szHelpText = localText.getText("TXT_KEY_FF_INTERFACE_PRODUCES_HELP", ()) # Planet Assign Building elif (iData1 == 669): szHelpText = localText.getText("TXT_KEY_FF_INTERFACE_PLANET_BUILDINGS_HELP", ()) # Planet Widgets in Lower-Right if (iData1 >= 671 and iData1 <= 678): pHeadSelectedCity = CyInterface().getHeadSelectedCity() pSystem = CvSolarSystem.getSystemAt(pHeadSelectedCity.getX(), pHeadSelectedCity.getY()) #FFPBUG iPlanetRing = iData1 - 670 pPlanet = pSystem.getPlanet(iPlanetRing) iFood = pPlanet.getTotalYield(pHeadSelectedCity.getOwner(), 0) iProduction = pPlanet.getTotalYield(pHeadSelectedCity.getOwner(), 1) iCommerce = pPlanet.getTotalYield(pHeadSelectedCity.getOwner(), 2) iCultureLevel = pPlanet.getPlanetCulturalRange() if pPlanet.isBonus(): szHelpText = pPlanet.getName() + "\n" + localText.getText("TXT_KEY_FF_INTERFACE_PLANET_SELECTION_HELP_0", (iFood, iProduction, iCommerce)) + "\n" + localText.getText("TXT_KEY_FFPLUS_PLANET_SELECTION_HELP", (iCultureLevel,)) + "\n" + u"%c " % gc.getBonusInfo(pPlanet.getBonusType()).getChar() + localText.getText("TXT_KEY_FFPLUS_PLANET_SELECTION_BONUS", (gc.getBonusInfo(pPlanet.getBonusType()).getDescription(),)) # Planetary Resource Indicator else: szHelpText = pPlanet.getName() + "\n" + localText.getText("TXT_KEY_FF_INTERFACE_PLANET_SELECTION_HELP_0", (iFood, iProduction, iCommerce)) + "\n" + localText.getText("TXT_KEY_FFPLUS_PLANET_SELECTION_HELP", (iCultureLevel,)) if (not CyUserProfile().getPlayerOption(PlayerOptionTypes.PLAYEROPTION_MODDER_1)): szHelpText += "\n" + localText.getText("TXT_KEY_FF_INTERFACE_PLANET_SELECTION_HELP", ()) return szHelpText
def doMeltdown(self,argsList): pCity = argsList[0] pSystem = CvSolarSystem.getSystemAt(pCity.getX(), pCity.getY()) iMeltPlanet = -1 # check to see if there is a meltdown for iBuilding in range(gc.getNumBuildingInfos()): if pCity.getNumBuilding(iBuilding) > 0 : iBuildingNukeExRand = gc.getBuildingInfo(iBuilding).getNukeExplosionRand() if iBuildingNukeExRand != 0 : if CyGame().getSorenRandNum(iBuildingNukeExRand, "FFP: meltdown check in doMeltdown callback") == 0 : # a building has had a meltdown, check planets for buildings of this type and pick one lPlanets = [] for iPlanet in range(pSystem.getNumPlanets()): pPlanet = pSystem.getPlanetByIndex(iPlanet) if pPlanet.isHasBuilding(iBuilding) : lPlanets.append(pPlanet) iMeltPlanet = CyGame().getSorenRandNum(len(lPlanets), "FPP: meltdown planet") pMeltPlanet = lPlanets[iMeltPlanet] # for the sake of simplicity, have it so that no star system will get more than one meltdown in a turn break # break out of building loop if iMeltPlanet == -1 : # no meltdown so exit now (always return True to avoid DLL's meltdown processing) return True pPlayer = gc.getPlayer(pCity.getOwner()) # defined now since we don't need it above pCityPlot = pCity.plot() # Meltdown effects (same as nuke effects, but applied to meltdown planet instead of best planet) # 1) set the planet to be disabled # 2) remove all buildings from the now dead planet, dealing with capitol if on this planet # 3) if thre was a bonus on the planet, remove it from planet and plot # 4) chance of specified feature being distributed around system # 5) unit damage (possibly killed) # 6) population reduction # 1) disable pMeltPlanet.setDisabled(true) pMeltPlanet.setPopulation(0) # 2) remove buildings for iBuilding in range(gc.getNumBuildingInfos()): if pMeltPlanet.isHasBuilding(iBuilding) and not gc.getBuildingInfo(iBuilding).isNukeImmune(): bRemove = True if (gc.getBuildingInfo(iBuilding).isCapital()): if (pPlayer.getNumCities () > 1): # The following call moves the capitol building, removing it from this city's data # in the DLL (which is why there is no manual setNumRealBuilding in here) # and adding it to the new capital city's data in the DLL plus adding it to that system's # current build planet to get it into the Python planet data. printd("Meltdown: finding new capial system") pPlayer.findNewCapital() else: # This is this civ's only system so we can't move the capitol building to a different one. # Try to move it to a different planet instead. printd("Meltdown: moving capitol to different planet in same system") # Select the planet that is the largest population limit planet # (using production as tie breaker) that is not the planet being wiped out bRemove = False aiPlanetList = pSystem.getSizeYieldPlanetIndexList(1) # 1 is production, arbitrarily selected for iLoopPlanet in range( len(aiPlanetList)): pLoopPlanet = pSystem.getPlanetByIndex(aiPlanetList[iLoopPlanet][2]) if (pLoopPlanet.getOrbitRing() != pMeltPlanet.getOrbitRing()): pLoopPlanet.setHasBuilding(iBuilding, true) printd("Meltdown: moved Capitol to planet at ring %d" % pLoopPlanet.getOrbitRing()) bRemove = True break else: pCity.setNumRealBuilding(iBuilding, pCity.getNumRealBuilding(iBuilding)-1) if bRemove : # The only time this is not the case is when it is the capitol and there is no other # planet it can be moved to. You always need a Capitol, so it stays on the dead planet pMeltPlanet.setHasBuilding(iBuilding, false) # 2.5) unlisted above, but here anyway if (pSystem.getBuildingPlanetRing() == pMeltPlanet.getOrbitRing()): # This system's current build planet is the planet being wiped out, # change it to some other planet, like the new "best" planet. # There is an issue if every planet in the current infuence range is dead - # in such a case there is no planet that should be having things built on it. # With any luck, this will never come up. pSystem.setBuildingPlanetRing(pSystem.getPlanetByIndex(CvSolarSystem.getBestPlanetInSystem(pSystem)).getOrbitRing()) # 3) remove bonus if (pMeltPlanet.isBonus()): # planet being melted has a bonus, remove it from the planet and the plot pMeltPlanet.setBonusType(-1) pCityPlot.setBonusType(-1) # 4) feature spread for iDX in range(-1, 2) : for iDY in range (-1, 2) : if (iDX != 0) and (iDY != 0) : pPlot = plotXY( pCity.getX(), pCity.getY(), iDX, iDY) if pPlot and not pPlot.isNone(): if not pPlot.isImpassable() and (FeatureTypes.NO_FEATURE == pPlot.getFeatureType()) : if (CyGame().getSorenRandNum(100, "Meltdown Fallout") < gc.getDefineINT("NUKE_FALLOUT_PROB")) : pPlot.setImprovementType(ImprovementTypes.NO_IMPROVEMENT) pPlot.setFeatureType(gc.getDefineINT("NUKE_FEATURE"), 0) # 5) unit damage - only check units on this plot! lUnit = [] for i in range(pCityPlot.getNumUnits()): pLoopUnit = pCityPlot.getUnit(i) if ( not pLoopUnit.isDead()): #is the unit alive? lUnit.append(pLoopUnit) #add unit instance to list for pUnit in lUnit : if not pUnit.isDead() and not pUnit.isNukeImmune() : iNukeDamage = gc.getDefineINT("NUKE_UNIT_DAMAGE_BASE") + CyGame().getSorenRandNum(gc.getDefineINT("NUKE_UNIT_DAMAGE_RAND_1"), "Nuke Damage 1") + CyGame().getSorenRandNum(gc.getDefineINT("NUKE_UNIT_DAMAGE_RAND_2"), "Nuke Damage 2") iNukeDamage *= max(0, (pCity.getNukeModifier() + 100)) iNukeDamage /= 100 if pUnit.canFight() or (pUnit.airBaseCombatStr() > 0) : printd("Meltdown: unit %s damaged for %d" % (pUnit.getName().encode('unicode_escape'), iNukeDamage)) pUnit.changeDamage(iNukeDamage, PlayerTypes.NO_PLAYER) elif iNukeDamage >= gc.getDefineINT("NUKE_NON_COMBAT_DEATH_THRESHOLD") : printd("Meltdown: non-combat unit %s killed from damage over threshold" % (pUnit.getName().encode('unicode_escape'),)) pUnit.kill(false, PlayerTypes.NO_PLAYER) # 6) population reduction iNukedPopulation = (pCity.getPopulation() * (gc.getDefineINT("NUKE_POPULATION_DEATH_BASE") + CyGame().getSorenRandNum(gc.getDefineINT("NUKE_POPULATION_DEATH_RAND_1"), "Population Nuked 1") + CyGame().getSorenRandNum(gc.getDefineINT("NUKE_POPULATION_DEATH_RAND_2"), "Population Nuked 2"))) / 100 iNukedPopulation *= max(0, (pCity.getNukeModifier() + 100)) iNukedPopulation /= 100 pCity.changePopulation(-(min((pCity.getPopulation() - 1), iNukedPopulation))) # Now update the city and display FinalFrontier = CvEventInterface.getEventManager().FinalFrontier FinalFrontier.getAI().doCityAIUpdate(pCity) pSystem.updateDisplay() # give message that this has happened szBuffer = localText.getText("TXT_KEY_MISC_MELTDOWN_CITY", (pCity.getName(),)) CyInterface().addMessage( pCity.getOwner(), False, gc.getDefineINT("EVENT_MESSAGE_TIME"), szBuffer, "AS2D_MELTDOWN", InterfaceMessageTypes.MESSAGE_TYPE_MINOR_EVENT, CyArtFileMgr().getInterfaceArtInfo("INTERFACE_UNHEALTHY_PERSON").getPath(), gc.getInfoTypeForString("COLOR_RED"), pCity.getX(), pCity.getY(), True, True) return True
def getCityFoundValue(self, argsList): iPlayer, iPlotX, iPlotY = argsList iFoundValue = -1 # Any value besides -1 will be used pPlot = CyMap().plot(iPlotX, iPlotY) iFeatureIDSolarSystem = gc.getInfoTypeForString('FEATURE_SOLAR_SYSTEM') if (pPlot.getFeatureType() == iFeatureIDSolarSystem and not pPlot.isCity()): printd("Determing Found Value for Plot at %d, %d" %(iPlotX, iPlotY)) # CP - Adjust base value based on path distance from capital (not straight line distance) pCapCity = gc.getPlayer(iPlayer).getCapitalCity() if pCapCity and not pCapCity.isNone() : iDistance = CyMap().calculatePathDistance(pCapCity.plot(), pPlot) if iDistance == -1 : # can't get there from here return 0 else : # no capital city, - would normally mean first city not founded yet, I suppose. iDistance = 1 iFoundValue = 10000 / (iDistance + 1) # CP - this provides only a small distance penalty # Determine System value by planetary composition if (CyGame().getElapsedGameTurns() > 0): #iFoundValue = 0 FinalFrontier = CvEventInterface.getEventManager().FinalFrontier pSystem = CvSolarSystem.getSystemAt(iPlotX, iPlotY) #FFPBUG for iPlanetLoop in range(pSystem.getNumPlanets()): pPlanet = pSystem.getPlanetByIndex(iPlanetLoop) iPlanetValue = 0 # Green Planet if (pPlanet.getPlanetType() == CvSolarSystem.iPlanetTypeGreen): iPlanetValue = 400 # Not Green Planet else: iPlanetValue = 200 # CP - Give some value to planetary resources (God-Emperor, for version 1.6) if (pPlanet.isBonus()): iPlanetValue += 100 # This may need adjusting # Two Civ-specific increase to this. # The Forge gets -1 food in each system, so extra food is good for them meaning +50 for the resources that give extra food # Trade routes are very good for the Red Syndicate, so +50 for each trade route iTraitForge = gc.getInfoTypeForString('TRAIT_THE_FORGE') iTraitSyndicate = gc.getInfoTypeForString('TRAIT_SYNDICATE') pPlayer = gc.getPlayer(iPlayer) pBonus = gc.getBonusInfo(pPlanet.getBonusType()) if (pPlayer.hasTrait(iTraitForge) and pBonus.getHealth() > 0): # all heath providing bonuses increase the planet's food iPlanetValue += 50 elif (pPlayer.hasTrait(iTraitSyndicate) and pBonus.getHappiness() > 0): # all happy providing bonuses' related buildings give at least 1 extra trade route pBonusBuilding = gc.getBuildingInfo(FinalFrontier.dBonusBuildings[pPlanet.getBonusType()]) iPlanetValue += 50 * pBonusBuilding.getTradeRoutes() # Planet Size iPlanetValue *= (pPlanet.getPlanetSize() + 1) + 2 # The +2 is to simply weight things a bit so that large planets aren't THAT much more valuable than small ones # Can it be used right away? if (pPlanet.getOrbitRing() < CvSolarSystem.g_iPlanetRange3): iPlanetValue *= 2 printd("Orbit Ring %d iPlanetValue: %d" %(pPlanet.getOrbitRing(), iPlanetValue)) iFoundValue += iPlanetValue else: iFoundValue = 0 return iFoundValue
def calculateScore(self,argsList): ePlayer = argsList[0] bFinal = argsList[1] bVictory = argsList[2] FinalFrontier = CvEventInterface.getEventManager().FinalFrontier iMaxPopulation = FinalFrontier.iMaxPopulation iPopulationScore = CvUtil.getScoreComponent(gc.getPlayer(ePlayer).getPopScore(), gc.getGame().getInitPopulation(), iMaxPopulation, gc.getDefineINT("SCORE_POPULATION_FACTOR"), True, bFinal, bVictory) printd("Pop Score Stuff") printd(gc.getPlayer(ePlayer).getPopScore()) printd(gc.getGame().getInitPopulation()) printd(iMaxPopulation) printd(iPopulationScore) iPlayerLandScore = gc.getPlayer(ePlayer).getTotalLand() iLandScore = CvUtil.getScoreComponent(iPlayerLandScore , gc.getGame().getInitLand(), gc.getGame().getMaxLand(), gc.getDefineINT("SCORE_LAND_FACTOR"), True, bFinal, bVictory) printd("Land Score Stuff") printd(iPlayerLandScore) printd(gc.getGame().getInitLand()) printd(gc.getGame().getMaxLand()) printd(iLandScore) iTechScore = CvUtil.getScoreComponent(gc.getPlayer(ePlayer).getTechScore(), gc.getGame().getInitTech(), gc.getGame().getMaxTech(), gc.getDefineINT("SCORE_TECH_FACTOR"), True, bFinal, bVictory) iWondersScore = CvUtil.getScoreComponent(gc.getPlayer(ePlayer).getWondersScore(), gc.getGame().getInitWonders(), gc.getGame().getMaxWonders(), gc.getDefineINT("SCORE_WONDER_FACTOR"), False, bFinal, bVictory) iTotalScore = int(iLandScore + iWondersScore + iTechScore + iPopulationScore) printd("Player %d Score: %d Pop: %d Land: %d Tech: %d Wonders: %d" %(ePlayer, iTotalScore, iPopulationScore, iLandScore, iTechScore, iWondersScore)) return iTotalScore
def getWidgetHelp(self, argsList): eWidgetType, iData1, iData2, bOption = argsList printd("eWidgetType %d, iData1 %d, iData2 %d, bOption %d" % (eWidgetType, iData1, iData2, bOption)) #PB Mod begin if (iData1 == 302016): return localText.getText("TXT_KEY_MOD_UNPAUSE_DESC", ()) #PB Mod end szHelpText = u"" # All the FF specific widget help is for widgets with a type of WidgetTypes.WIDGET_GENERAL (FFP post 1.81, for B5, by G-E) if (eWidgetType == WidgetTypes.WIDGET_GENERAL): # Only show tool tip help when players have the tutorial on if (not CyUserProfile().getPlayerOption( PlayerOptionTypes.PLAYEROPTION_MODDER_1)): # Selected Planet if (iData1 == 666): szHelpText = localText.getText( "TXT_KEY_FF_INTERFACE_SELECTED_PLANET_HELP", ()) # Planet Population elif (iData1 == 667): szHelpText = localText.getText( "TXT_KEY_FF_INTERFACE_PLANET_POPULATION_HELP", ()) # Planet Yield elif (iData1 == 668): szHelpText = localText.getText( "TXT_KEY_FF_INTERFACE_PRODUCES_HELP", ()) # Planet Assign Building elif (iData1 == 669): szHelpText = localText.getText( "TXT_KEY_FF_INTERFACE_PLANET_BUILDINGS_HELP", ()) # Planet Widgets in Lower-Right if (iData1 >= 671 and iData1 <= 678): pHeadSelectedCity = CyInterface().getHeadSelectedCity() pSystem = CvSolarSystem.getSystemAt( pHeadSelectedCity.getX(), pHeadSelectedCity.getY()) #FFPBUG iPlanetRing = iData1 - 670 pPlanet = pSystem.getPlanet(iPlanetRing) iFood = pPlanet.getTotalYield(pHeadSelectedCity.getOwner(), 0) iProduction = pPlanet.getTotalYield( pHeadSelectedCity.getOwner(), 1) iCommerce = pPlanet.getTotalYield(pHeadSelectedCity.getOwner(), 2) iCultureLevel = pPlanet.getPlanetCulturalRange() if pPlanet.isBonus(): szHelpText = pPlanet.getName() + "\n" + localText.getText( "TXT_KEY_FF_INTERFACE_PLANET_SELECTION_HELP_0", (iFood, iProduction, iCommerce) ) + "\n" + localText.getText( "TXT_KEY_FFPLUS_PLANET_SELECTION_HELP", (iCultureLevel, ) ) + "\n" + u"%c " % gc.getBonusInfo( pPlanet.getBonusType()).getChar() + localText.getText( "TXT_KEY_FFPLUS_PLANET_SELECTION_BONUS", (gc.getBonusInfo( pPlanet.getBonusType()).getDescription(), )) # Planetary Resource Indicator else: szHelpText = pPlanet.getName() + "\n" + localText.getText( "TXT_KEY_FF_INTERFACE_PLANET_SELECTION_HELP_0", (iFood, iProduction, iCommerce)) + "\n" + localText.getText( "TXT_KEY_FFPLUS_PLANET_SELECTION_HELP", (iCultureLevel, )) if (not CyUserProfile().getPlayerOption( PlayerOptionTypes.PLAYEROPTION_MODDER_1)): szHelpText += "\n" + localText.getText( "TXT_KEY_FF_INTERFACE_PLANET_SELECTION_HELP", ()) return szHelpText
def getCityFoundValue(self, argsList): iPlayer, iPlotX, iPlotY = argsList iFoundValue = -1 # Any value besides -1 will be used pPlot = CyMap().plot(iPlotX, iPlotY) iFeatureIDSolarSystem = gc.getInfoTypeForString('FEATURE_SOLAR_SYSTEM') if (pPlot.getFeatureType() == iFeatureIDSolarSystem and not pPlot.isCity()): printd("Determing Found Value for Plot at %d, %d" % (iPlotX, iPlotY)) # CP - Adjust base value based on path distance from capital (not straight line distance) pCapCity = gc.getPlayer(iPlayer).getCapitalCity() if pCapCity and not pCapCity.isNone(): iDistance = CyMap().calculatePathDistance( pCapCity.plot(), pPlot) if iDistance == -1: # can't get there from here return 0 else: # no capital city, - would normally mean first city not founded yet, I suppose. iDistance = 1 iFoundValue = 10000 / ( iDistance + 1 ) # CP - this provides only a small distance penalty # Determine System value by planetary composition if (CyGame().getElapsedGameTurns() > 0): #iFoundValue = 0 FinalFrontier = CvEventInterface.getEventManager( ).FinalFrontier pSystem = CvSolarSystem.getSystemAt(iPlotX, iPlotY) #FFPBUG for iPlanetLoop in range(pSystem.getNumPlanets()): pPlanet = pSystem.getPlanetByIndex(iPlanetLoop) iPlanetValue = 0 # Green Planet if (pPlanet.getPlanetType() == CvSolarSystem.iPlanetTypeGreen): iPlanetValue = 400 # Not Green Planet else: iPlanetValue = 200 # CP - Give some value to planetary resources (God-Emperor, for version 1.6) if (pPlanet.isBonus()): iPlanetValue += 100 # This may need adjusting # Two Civ-specific increase to this. # The Forge gets -1 food in each system, so extra food is good for them meaning +50 for the resources that give extra food # Trade routes are very good for the Red Syndicate, so +50 for each trade route iTraitForge = gc.getInfoTypeForString( 'TRAIT_THE_FORGE') iTraitSyndicate = gc.getInfoTypeForString( 'TRAIT_SYNDICATE') pPlayer = gc.getPlayer(iPlayer) pBonus = gc.getBonusInfo(pPlanet.getBonusType()) if ( pPlayer.hasTrait(iTraitForge) and pBonus.getHealth() > 0 ): # all heath providing bonuses increase the planet's food iPlanetValue += 50 elif ( pPlayer.hasTrait(iTraitSyndicate) and pBonus.getHappiness() > 0 ): # all happy providing bonuses' related buildings give at least 1 extra trade route pBonusBuilding = gc.getBuildingInfo( FinalFrontier.dBonusBuildings[ pPlanet.getBonusType()]) iPlanetValue += 50 * pBonusBuilding.getTradeRoutes( ) # Planet Size iPlanetValue *= ( pPlanet.getPlanetSize() + 1 ) + 2 # The +2 is to simply weight things a bit so that large planets aren't THAT much more valuable than small ones # Can it be used right away? if (pPlanet.getOrbitRing() < CvSolarSystem.g_iPlanetRange3): iPlanetValue *= 2 printd("Orbit Ring %d iPlanetValue: %d" % (pPlanet.getOrbitRing(), iPlanetValue)) iFoundValue += iPlanetValue else: iFoundValue = 0 return iFoundValue
def doMeltdown(self, argsList): pCity = argsList[0] pSystem = CvSolarSystem.getSystemAt(pCity.getX(), pCity.getY()) iMeltPlanet = -1 # check to see if there is a meltdown for iBuilding in range(gc.getNumBuildingInfos()): if pCity.getNumBuilding(iBuilding) > 0: iBuildingNukeExRand = gc.getBuildingInfo( iBuilding).getNukeExplosionRand() if iBuildingNukeExRand != 0: if CyGame().getSorenRandNum( iBuildingNukeExRand, "FFP: meltdown check in doMeltdown callback") == 0: # a building has had a meltdown, check planets for buildings of this type and pick one lPlanets = [] for iPlanet in range(pSystem.getNumPlanets()): pPlanet = pSystem.getPlanetByIndex(iPlanet) if pPlanet.isHasBuilding(iBuilding): lPlanets.append(pPlanet) iMeltPlanet = CyGame().getSorenRandNum( len(lPlanets), "FPP: meltdown planet") pMeltPlanet = lPlanets[iMeltPlanet] # for the sake of simplicity, have it so that no star system will get more than one meltdown in a turn break # break out of building loop if iMeltPlanet == -1: # no meltdown so exit now (always return True to avoid DLL's meltdown processing) return True pPlayer = gc.getPlayer( pCity.getOwner()) # defined now since we don't need it above pCityPlot = pCity.plot() # Meltdown effects (same as nuke effects, but applied to meltdown planet instead of best planet) # 1) set the planet to be disabled # 2) remove all buildings from the now dead planet, dealing with capitol if on this planet # 3) if thre was a bonus on the planet, remove it from planet and plot # 4) chance of specified feature being distributed around system # 5) unit damage (possibly killed) # 6) population reduction # 1) disable pMeltPlanet.setDisabled(true) pMeltPlanet.setPopulation(0) # 2) remove buildings for iBuilding in range(gc.getNumBuildingInfos()): if pMeltPlanet.isHasBuilding(iBuilding) and not gc.getBuildingInfo( iBuilding).isNukeImmune(): bRemove = True if (gc.getBuildingInfo(iBuilding).isCapital()): if (pPlayer.getNumCities() > 1): # The following call moves the capitol building, removing it from this city's data # in the DLL (which is why there is no manual setNumRealBuilding in here) # and adding it to the new capital city's data in the DLL plus adding it to that system's # current build planet to get it into the Python planet data. printd("Meltdown: finding new capial system") pPlayer.findNewCapital() else: # This is this civ's only system so we can't move the capitol building to a different one. # Try to move it to a different planet instead. printd( "Meltdown: moving capitol to different planet in same system" ) # Select the planet that is the largest population limit planet # (using production as tie breaker) that is not the planet being wiped out bRemove = False aiPlanetList = pSystem.getSizeYieldPlanetIndexList( 1) # 1 is production, arbitrarily selected for iLoopPlanet in range(len(aiPlanetList)): pLoopPlanet = pSystem.getPlanetByIndex( aiPlanetList[iLoopPlanet][2]) if (pLoopPlanet.getOrbitRing() != pMeltPlanet.getOrbitRing()): pLoopPlanet.setHasBuilding(iBuilding, true) printd( "Meltdown: moved Capitol to planet at ring %d" % pLoopPlanet.getOrbitRing()) bRemove = True break else: pCity.setNumRealBuilding( iBuilding, pCity.getNumRealBuilding(iBuilding) - 1) if bRemove: # The only time this is not the case is when it is the capitol and there is no other # planet it can be moved to. You always need a Capitol, so it stays on the dead planet pMeltPlanet.setHasBuilding(iBuilding, false) # 2.5) unlisted above, but here anyway if (pSystem.getBuildingPlanetRing() == pMeltPlanet.getOrbitRing()): # This system's current build planet is the planet being wiped out, # change it to some other planet, like the new "best" planet. # There is an issue if every planet in the current infuence range is dead - # in such a case there is no planet that should be having things built on it. # With any luck, this will never come up. pSystem.setBuildingPlanetRing( pSystem.getPlanetByIndex( CvSolarSystem.getBestPlanetInSystem( pSystem)).getOrbitRing()) # 3) remove bonus if ( pMeltPlanet.isBonus() ): # planet being melted has a bonus, remove it from the planet and the plot pMeltPlanet.setBonusType(-1) pCityPlot.setBonusType(-1) # 4) feature spread for iDX in range(-1, 2): for iDY in range(-1, 2): if (iDX != 0) and (iDY != 0): pPlot = plotXY(pCity.getX(), pCity.getY(), iDX, iDY) if pPlot and not pPlot.isNone(): if not pPlot.isImpassable() and ( FeatureTypes.NO_FEATURE == pPlot.getFeatureType()): if (CyGame().getSorenRandNum( 100, "Meltdown Fallout") < gc.getDefineINT("NUKE_FALLOUT_PROB")): pPlot.setImprovementType( ImprovementTypes.NO_IMPROVEMENT) pPlot.setFeatureType( gc.getDefineINT("NUKE_FEATURE"), 0) # 5) unit damage - only check units on this plot! lUnit = [] for i in range(pCityPlot.getNumUnits()): pLoopUnit = pCityPlot.getUnit(i) if (not pLoopUnit.isDead()): #is the unit alive? lUnit.append(pLoopUnit) #add unit instance to list for pUnit in lUnit: if not pUnit.isDead() and not pUnit.isNukeImmune(): iNukeDamage = gc.getDefineINT( "NUKE_UNIT_DAMAGE_BASE") + CyGame().getSorenRandNum( gc.getDefineINT("NUKE_UNIT_DAMAGE_RAND_1"), "Nuke Damage 1") + CyGame().getSorenRandNum( gc.getDefineINT("NUKE_UNIT_DAMAGE_RAND_2"), "Nuke Damage 2") iNukeDamage *= max(0, (pCity.getNukeModifier() + 100)) iNukeDamage /= 100 if pUnit.canFight() or (pUnit.airBaseCombatStr() > 0): printd("Meltdown: unit %s damaged for %d" % (pUnit.getName().encode('unicode_escape'), iNukeDamage)) pUnit.changeDamage(iNukeDamage, PlayerTypes.NO_PLAYER) elif iNukeDamage >= gc.getDefineINT( "NUKE_NON_COMBAT_DEATH_THRESHOLD"): printd( "Meltdown: non-combat unit %s killed from damage over threshold" % (pUnit.getName().encode('unicode_escape'), )) pUnit.kill(false, PlayerTypes.NO_PLAYER) # 6) population reduction iNukedPopulation = ( pCity.getPopulation() * (gc.getDefineINT("NUKE_POPULATION_DEATH_BASE") + CyGame().getSorenRandNum( gc.getDefineINT("NUKE_POPULATION_DEATH_RAND_1"), "Population Nuked 1") + CyGame().getSorenRandNum( gc.getDefineINT("NUKE_POPULATION_DEATH_RAND_2"), "Population Nuked 2"))) / 100 iNukedPopulation *= max(0, (pCity.getNukeModifier() + 100)) iNukedPopulation /= 100 pCity.changePopulation(-(min((pCity.getPopulation() - 1), iNukedPopulation))) # Now update the city and display FinalFrontier = CvEventInterface.getEventManager().FinalFrontier FinalFrontier.getAI().doCityAIUpdate(pCity) pSystem.updateDisplay() # give message that this has happened szBuffer = localText.getText("TXT_KEY_MISC_MELTDOWN_CITY", (pCity.getName(), )) CyInterface().addMessage( pCity.getOwner(), False, gc.getDefineINT("EVENT_MESSAGE_TIME"), szBuffer, "AS2D_MELTDOWN", InterfaceMessageTypes.MESSAGE_TYPE_MINOR_EVENT, CyArtFileMgr().getInterfaceArtInfo( "INTERFACE_UNHEALTHY_PERSON").getPath(), gc.getInfoTypeForString("COLOR_RED"), pCity.getX(), pCity.getY(), True, True) return True
def calculateScore(self, argsList): ePlayer = argsList[0] bFinal = argsList[1] bVictory = argsList[2] FinalFrontier = CvEventInterface.getEventManager().FinalFrontier iMaxPopulation = FinalFrontier.iMaxPopulation iPopulationScore = CvUtil.getScoreComponent( gc.getPlayer(ePlayer).getPopScore(), gc.getGame().getInitPopulation(), iMaxPopulation, gc.getDefineINT("SCORE_POPULATION_FACTOR"), True, bFinal, bVictory) printd("Pop Score Stuff") printd(gc.getPlayer(ePlayer).getPopScore()) printd(gc.getGame().getInitPopulation()) printd(iMaxPopulation) printd(iPopulationScore) iPlayerLandScore = gc.getPlayer(ePlayer).getTotalLand() iLandScore = CvUtil.getScoreComponent( iPlayerLandScore, gc.getGame().getInitLand(), gc.getGame().getMaxLand(), gc.getDefineINT("SCORE_LAND_FACTOR"), True, bFinal, bVictory) printd("Land Score Stuff") printd(iPlayerLandScore) printd(gc.getGame().getInitLand()) printd(gc.getGame().getMaxLand()) printd(iLandScore) iTechScore = CvUtil.getScoreComponent( gc.getPlayer(ePlayer).getTechScore(), gc.getGame().getInitTech(), gc.getGame().getMaxTech(), gc.getDefineINT("SCORE_TECH_FACTOR"), True, bFinal, bVictory) iWondersScore = CvUtil.getScoreComponent( gc.getPlayer(ePlayer).getWondersScore(), gc.getGame().getInitWonders(), gc.getGame().getMaxWonders(), gc.getDefineINT("SCORE_WONDER_FACTOR"), False, bFinal, bVictory) iTotalScore = int(iLandScore + iWondersScore + iTechScore + iPopulationScore) printd( "Player %d Score: %d Pop: %d Land: %d Tech: %d Wonders: %d" % (ePlayer, iTotalScore, iPopulationScore, iLandScore, iTechScore, iWondersScore)) return iTotalScore