Need some help with Python

nokmirt

Emperor
Joined
Feb 14, 2009
Messages
5,088
Location
Iowa USA
Ok, I have been working on a mod and I would like some help on my WWI events.py file. The mod was done by Jon Shafer, but I would like to change my revolution checks not to start until 1917. Now in my scenario for this mod, I have changed my turns to weeks instead of months. So my first turn starts on week 1 August, 1914. Now I would like to not have revolutions, to not start being checked until Week 1 March 1917. But I do not know how to change the python to do this. I am going to put the code in a spoiler, and if anyone can change it that knows Python, I would appreciate the help. Then me give the changed code and I will implement it into the mod. The mod is for CIV 4 v1.74. Thank you
Spoiler :
# World War I
# Civilization 4 (c) 2005 Firaxis Games

# Created by - Jon 'Trip' Shafer
# Have fun!

from CvPythonExtensions import *
import sys
import Popup as PyPopup
from PyHelpers import PyPlayer
import pickle
import CvEventManager
from CvScreenEnums import *
from PyHelpers import *
import CvUtil

# globals
gc = CyGlobalContext()
localText = CyTranslator()

DefaultUnitAI = UnitAITypes.NO_UNITAI
class CvWWIEvents(CvEventManager.CvEventManager):

def __init__(self):

CvEventManager.CvEventManager.__init__(self)

# Number of turns for this scenario
self.iMaxTurn = 60

# Offset value set in WorldBuilder save
self.iTurnOffset = 7

self.iJoinCentralPowersThreshold = 400#400
self.iJoinEntenteThreshold = -400#-400

self.iRevolutionMod = 0#0
self.iRebelSpawnChance = 10#15
self.iUnitSpawnRange = 2#2
self.iCitySpawnUnitCounterMax = 10#6

# The number by which the turn is divided to get the factor to multiply US reinforcements by (turn 60 / 10 = 6)
self.iUSAReinforcementTurnFactor = 10#15
self.iUSAGoldAmount = 50#50
self.iUSAReinforceCounter = 4#6
self.aiUSAReinforceWaterPlot = [1, 46]

self.iManualBuildUnitChance = 70#70

#############

self.iCentralPowersID = 0
self.iEntenteID = 1

self.iGermanyID = 0
self.iAustriaHungaryID = 1
self.iOttomansID = 2
self.iRussiaID = 3
self.iFranceID = 4
self.iBritainID = 5
self.iItalyID = 6
self.iUSAID = 7
self.iSerbiaID = 8
self.iBulgariaID = 9
self.iRomaniaID = 10
self.iBelgiumID = 11
self.iSpainID = 12
self.iSwedenID = 13
self.iGreeceID = 14
self.iDenmarkID = 15
self.iNetherlandsID = 16
self.iPortugalID = 17
self.iBarbariansID = 18
self.iNumPlayers = 18

self.szEventText = ""
self.szResultText = ""

def turnChecker(self, iTurn):

# XXX - Temp for use while debugging/reloading
self.initValues()

self.szGameDate = CyGameTextMgr().getTimeStr(iTurn, false)

# Check for alignment of various civs to determine if they should declare war on anyone
self.changeAlignment()

# Check for Revolution
self.checkForRevolution(iTurn)

# Alter City Unit Spawning Counters
self.alterCitySpawnUnitCounters()

self.doReinforcements(iTurn)

# Insert all game turn events here
# return

# print("Turn is: %d" %(iTurn))
if (iTurn == 7 + self.iTurnOffset):#7
self.Mar_1915()
elif (iTurn == 8 + self.iTurnOffset):#8
self.Apr_1915()
elif (iTurn == 17 + self.iTurnOffset):#17
self.Jan_1916()
elif (iTurn == 31 + self.iTurnOffset):#31
self.Mar_1917()
elif (iTurn == 33 + self.iTurnOffset):#33
self.May_1917()

# Determine the start-game state
def setupGame(self):

# Temporary Measure to turn off 'Feats'
CyMessageControl().sendPlayerOption(PlayerOptionTypes.PLAYEROPTION_ADVISOR_POPUPS, false)

self.initValues()

# Used to prevent the AI from acting the same at the start of every game
# self.randomizeStartingArmies()

for iPlayerLoop in range(self.iNumPlayers):

pPlayer = gc.getPlayer(iPlayerLoop)

# Set default script data manually since we need defaults for all values in array or else we crash:
# [ iPlayerAlignment | bInRevolution | iNumUnitsLost ]
aScriptData = [0, false, 0]
pPlayer.setScriptData(pickle.dumps(aScriptData))

# Set player default commerce to 100% gold since there are no techs
pPlayer.setCommercePercent(CommerceTypes.COMMERCE_RESEARCH, 70)

# Loop through player's units
# for iUnitLoop in range(pPlayer.getNumUnits()):
#
# self.setUnitDisbandCounter(iPlayerLoop, iUnitLoop, -1)

# Set player default alignments: 400 means war against Entente, -400 means war against Central Powers
self.setPlayerAlignment(self.iItalyID, -200)
self.setPlayerAlignment(self.iUSAID, -50)
self.setPlayerAlignment(self.iBulgariaID, 200)
self.setPlayerAlignment(self.iRomaniaID, -75)
self.setPlayerAlignment(self.iGreeceID, -50)

def initValues(self):

self.iCavalryID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_CAVALRY')#83
self.iBasicLightArtilleryID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_BASIC_LIGHT_ARTILLERY')
self.iAdvancedLightArtilleryID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_ADVANCED_LIGHT_ARTILLERY')
self.iMachineGunID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_MACHINE_GUN')
self.iTankID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_TANK')
self.iPoisonGasID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_POISON_GAS')
self.iBiplaneID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_BIPLANE')
self.iDestroyerID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_DESTROYER')
self.iDreadnaughtID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_DREADNAUGHT')
self.iSubmarineID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_SUBMARINE')
self.iTransportID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_TRANSPORT')

self.iBasicInfantryID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_BASIC_INFANTRY')
self.iAdvancedInfantryID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_ADVANCED_INFANTRY')
self.iBasicGermanInfantryID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_BASIC_GERMAN_INFANTRY')
self.iAdvancedGermanInfantryID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_ADVANCED_GERMAN_INFANTRY')
self.iBasicAustroHungarianInfantryID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_BASIC_AUSTRO-HUNGARIAN_INFANTRY')
self.iAdvancedAustroHungarianInfantryID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_ADVANCED_AUSTRO-HUNGARIAN_INFANTRY')
self.iBasicOttomanInfantryID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_BASIC_OTTOMAN_INFANTRY')
self.iAdvancedOttomanInfantryID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_ADVANCED_OTTOMAN_INFANTRY')
self.iBasicRussianInfantryID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_BASIC_RUSSIAN_INFANTRY')
self.iAdvancedRussianInfantryID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_ADVANCED_RUSSIAN_INFANTRY')
self.iBasicFrenchInfantryID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_BASIC_FRENCH_INFANTRY')
self.iAdvancedFrenchInfantryID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_ADVANCED_FRENCH_INFANTRY')
self.iBasicBritishInfantryID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_BASIC_BRITISH_INFANTRY')
self.iAdvancedBritishInfantryID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_ADVANCED_BRITISH_INFANTRY')
self.iBasicItalianInfantryID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_BASIC_ITALIAN_INFANTRY')
self.iAdvancedItalianInfantryID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_ADVANCED_ITALIAN_INFANTRY')
self.iBasicAmericanInfantryID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_BASIC_AMERICAN_INFANTRY')
self.iAdvancedAmericanInfantryID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_ADVANCED_AMERICAN_INFANTRY')

self.iConscriptionCenterID = CvUtil.findInfoTypeNum(gc.getBuildingInfo,gc.getNumBuildingInfos(),'WWI_BUILDING_CONSCRIPTION_CENTER')#99

self.iMobileAttackDoctrineID = CvUtil.findInfoTypeNum(gc.getTechInfo,gc.getNumTechInfos(),'WWI_TECH_MOBILE_ATTACK_DOCTRINE')
self.iArmoredVehiclesID = CvUtil.findInfoTypeNum(gc.getTechInfo,gc.getNumTechInfos(),'WWI_TECH_ARMORED_VEHICLES')

for iPlayerLoop in range(self.iNumPlayers):

pyPlayer = PyPlayer(iPlayerLoop)
# Loop through player's cities
apCityList = pyPlayer.getCityList()

for pCityLoop in apCityList:

# Initialize City
self.initCity(pCityLoop)

###########################################################################################
####################################### MISC EVENTS #######################################
###########################################################################################

def changeAlignment(self):

# Per-turn player alignment change
self.changePlayerAlignment(self.iItalyID, -10)
self.changePlayerAlignment(self.iUSAID, -10)
self.changePlayerAlignment(self.iBulgariaID, 10)
self.changePlayerAlignment(self.iRomaniaID, -10)
self.changePlayerAlignment(self.iGreeceID, -10)

iItalyAlignment = self.getPlayerAlignment(self.iItalyID)
iUSAAlignment = self.getPlayerAlignment(self.iUSAID)
iBulgariaAlignment = self.getPlayerAlignment(self.iBulgariaID)
iRomaniaAlignment = self.getPlayerAlignment(self.iRomaniaID)
iGreeceAlignment = self.getPlayerAlignment(self.iGreeceID)

print("XXX - iItalyAlignment Alignment is %d" %(iItalyAlignment))
print("XXX - iUSAAlignment Alignment is %d" %(iUSAAlignment))
print("XXX - iBulgariaAlignment Alignment is %d" %(iBulgariaAlignment))
print("XXX - iRomaniaAlignment Alignment is %d" %(iRomaniaAlignment))
print("XXX - iGreeceAlignment Alignment is %d" %(iGreeceAlignment))

aiCivIDs = [self.iItalyID, self.iUSAID, self.iBulgariaID, self.iRomaniaID, self.iGreeceID]
aiCivAlignments = [iItalyAlignment, iUSAAlignment, iBulgariaAlignment, iRomaniaAlignment, iGreeceAlignment]

# Loop through all these civs

for iPlayerLoop in aiCivIDs:

pPlayer = gc.getPlayer(iPlayerLoop)
pTeam = gc.getTeam(pPlayer.getTeam())

if (not pPlayer.isHuman()):

iPlayerAlignment = self.getPlayerAlignment(iPlayerLoop)
bRepeating = true # This is used so that the American initial unit add event isn't called more than one time

# Declare war on the Entente
if (iPlayerAlignment >= self.iJoinCentralPowersThreshold):

print("XXX - Player %d has joined the Central Powers!" %(iPlayerLoop))

if (not pTeam.isAtWar(self.iEntenteID)):
# pTeam.declareWar(self.iEntenteID, false)
gc.getTeam(self.iCentralPowersID).addTeam(pPlayer.getTeam())
bRepeating = false

# Declare war on the Central Powers
elif (iPlayerAlignment <= self.iJoinEntenteThreshold):

print("XXX - Player %d has joined the Entente!" %(iPlayerLoop))

if (not pTeam.isAtWar(self.iCentralPowersID)):
# pTeam.declareWar(self.iCentralPowersID, false)
gc.getTeam(self.iEntenteID).addTeam(pPlayer.getTeam())
bRepeating = false

# Set event text (if applicable)
if (iPlayerLoop == self.iItalyID):
self.szEventText = localText.getText("TXT_KEY_WWI_EVENT_ITALY_JOINS_ALLIES_DESC", ())
self.szResultText = localText.getText("TXT_KEY_WWI_EVENT_ITALY_JOINS_ALLIES_EFFECT", ())
self.displayEventText()

elif (iPlayerLoop == self.iUSAID):
self.szEventText = localText.getText("TXT_KEY_WWI_EVENT_USA_JOINS_WAR_DESC", ())
self.szResultText = localText.getText("TXT_KEY_WWI_EVENT_USA_JOINS_WAR_EFFECT", ())
self.displayEventText()
else:
return

# Need to add a unit to the Americans manually otherwise they don't really 'exist' and aren't technically at war with anyone - which is bad
if (iPlayerLoop == self.iUSAID and bRepeating == false):

pUSAPlayer = gc.getPlayer(self.iUSAID)

# Determine a plot for the unit to go to, then add them

iWaterPlotRange = 4

aiWaterUnitsPlot = self.findUnitPlacementPlot(self.iUSAID, self.aiUSAReinforceWaterPlot[0], self.aiUSAReinforceWaterPlot[1], false)

if (aiWaterUnitsPlot == "Oh Snap"):
return

else:
iX = aiWaterUnitsPlot[0]
iY = aiWaterUnitsPlot[1]

pUSAPlayer.initUnit(self.iDestroyerID, iX, iY, UnitAITypes.UNITAI_ESCORT_SEA)
pUSAPlayer.initUnit(self.iDestroyerID, iX, iY, UnitAITypes.UNITAI_ESCORT_SEA)

def checkForRevolution(self, iTurn):

# Factor between 1.0 and 2.0 making revolution more likely
fRevolutionModifier = iTurn / (self.iMaxTurn * 1.0) * 2
if (fRevolutionModifier < 1.0):
fRevolutionModifier = 1.0

# Loop through all players
for iPlayerLoop in range(self.iNumPlayers):

pPlayer = gc.getPlayer(iPlayerLoop)

print("XXX - Player %d has lost %d Units" %(iPlayerLoop, self.getPlayerNumUnitsLost(iPlayerLoop)))

if (pPlayer.isAlive()):

if (self.isPlayerInRevolution(iPlayerLoop)):

# Player is in Revolution, now make him PAY!
self.checkForUnitSpawning(iPlayerLoop)

# Okay, we're in Revolution, no need to check any further for this player
continue

iNumUnitsLost = self.getPlayerNumUnitsLost(iPlayerLoop)
iTotalPopulation = pPlayer.getTotalPopulation()

# Don't want dead people messing with stuff
if (iTotalPopulation <= 0):
return

fRevolutionChance = iNumUnitsLost / (iTotalPopulation * 8.0) * fRevolutionModifier * 100 + self.iRevolutionMod
iRoll = self.getRand(98) + 1# Measure to prevent a roll of 0

print("XXX - Checking for Player %d revolution with fChance of %f and Rand of %d; %d UnitsLost and Pop of %d" %(iPlayerLoop, fRevolutionChance, iRoll, iNumUnitsLost, iTotalPopulation))

# Check final factor against rand
if (fRevolutionChance > iRoll):

self.setPlayerInRevolution(iPlayerLoop, true)

# Set event text
if (iPlayerLoop == self.iRussiaID):
self.szEventText = localText.getText("TXT_KEY_WWI_EVENT_RUSSIAN_REVOLUTION_DESC", ())
else:
self.szEventText = localText.getText("TXT_KEY_WWI_EVENT_GENERIC_REVOLUTION_DESC", ())

self.szResultText = localText.getText("TXT_KEY_WWI_EVENT_GENERIC_REVOLUTION_EFFECT", (pPlayer.getCivilizationShortDescription(0),))

self.displayEventText()

def checkForUnitSpawning(self, iPlayerID):

# Loop through all player cities
pyPlayer = PyPlayer(iPlayerID)
apCityList = pyPlayer.getCityList()

for pCityLoop in apCityList:
iCityID = pCityLoop.getID()
iCityX = pCityLoop.getX()
iCityY = pCityLoop.getY()

# If this city has spawned a unit recently then no more units
if (self.getCitySpawnUnitCounter(iPlayerID, iCityID) == 0):

iUnitSpawnRoll = self.getRand(99)
# print("iUnitSpawnRoll: %d" %(iUnitSpawnRoll))
# Create Infantry for the Barbarians
if (iUnitSpawnRoll < self.iRebelSpawnChance):

aiSpawnPlot = self.findUnitPlacementPlot(self.iBarbariansID, iCityX, iCityY, true, true, self.iUnitSpawnRange)
# print("Spawn Plot: %d, %d" %(aiSpawnPlot[0], aiSpawnPlot[1]))
if (aiSpawnPlot == "Oh Snap"):
return
else:
pBarbarians = gc.getPlayer(self.iBarbariansID)

print("XXX - Player %d in revolution; Rebel spawning at [%d, %d]" %(iPlayerID, aiSpawnPlot[0], aiSpawnPlot[1]))
pBarbarians.initUnit(self.iBasicInfantryID, aiSpawnPlot[0], aiSpawnPlot[1], UnitAITypes.UNITAI_ATTACK)

self.setCitySpawnUnitCounter(iPlayerID, iCityID, self.iCitySpawnUnitCounterMax)

def alterCitySpawnUnitCounters(self):

# Loop through all players' cities
for iPlayerLoop in range(self.iNumPlayers):

pPlayer = PyPlayer(iPlayerLoop)
apCityList = pPlayer.getCityList()

for pCity in apCityList:

iCityID = pCity.getID()
# Reduce CitySpawnUnit counter by 1 in applicable cities
if (self.getCitySpawnUnitCounter(iPlayerLoop, iCityID) > 0):

self.changeCitySpawnUnitCounter(iPlayerLoop, iCityID, -1)


I was also wondering if their were any ways to make the ai a little better, using Python? Also I could not find the Python events tutorial, can anyone tell me where I can find it, I would love to see it. Thanks for the Help, this is the last step before playtesting, it should be a decent little mod to hold us over until Blood and Iron comes out.
 
You have to add after "def checkForRevolution":

PHP:
def checkForRevolution(self, iTurn)

if (CyGame().getGameTurn() > 128):

[...]

I'm not quite sure whether it's the 128th game turn.

Don't forget to use the tab key! :D
 
You have to add after "def checkForRevolution":

PHP:
def checkForRevolution(self, iTurn)

if (CyGame().getGameTurn() > 128):

[...]

I'm not quite sure whether it's the 128th game turn.

Don't forget to use the tab key! :D

Thank you very much, but I tried it and it does not work, what could I be doing wrong?
 
Thank You magic66, I had some trouble with indentation but it works now, and I am not sure about the exact gameturn either, so I am going to playtest.
 
Top Bottom