HELP with merging my mod and BUG!!!

Alright, when I tried it again it said there was an indentation error on line 49 of the DiplomacyEventManager.py file. Here's the code for it:

Code:
class DiplomacyEventManager:
	def __init__(self, eventmanager):
        eventManager.addEventHandler("GameStart", self.onGameStart)
        eventManager.addEventHandler("OnLoad", self.onLoadGame)
        eventManager.addEventHandler("GameStart", self.onGameStart)
        eventManager.addEventHandler("BeginGameTurn", self.onBeginGameTurn)
        eventManager.addEventHandler("cityRazed", self.onCityRazed)
        eventManager.addEventHandler("cityDoTurn", self.onCityDoTurn)

Line 49 is the first event handler thing. So right under the def__init line. How should it be indented?
 
Right, leave the code you added:

Code:
		###circus hagenbeck start part 1
                self.oldcity = [-1,-1]
                ###circus hagenbeck end part 1        
		
		# Next War tracks cities that have been razed
		self.iArcologyCityID = -1

But the other stuff should go. Python cannot cause a CTD. It can only call something in the DLL that causes a CTD, but that's rare. 99% of CTDs are problems with XML, mostly pointing to invalid Art.
 
1) Every line after that that is supposed to be part of the __init__ function needs to be indented more than that line is, equal to the later lines that were already part of the function. They are currently indented the same amount, as far as python is concerned.

2) Don't mix tabs and spaces to indent. It will only work if you are very lucky. Civ4's files use tabs, so use tabs. If your editor is changing tabs to some specific number of spaces, turn that feature off (for example, in Notepad++ it is on the "Edit Components" tab of the Preferences pop-up you get via the "Preferences..." item on the Settings menu).
 
Python will assume each tab is 8 spaces, so you have indented the def and the lines under it to the same amount, even though your editor probably uses 4 spaces per tab. This is why you never want to mix spaces and tabs. Ever. Never ever!

No, not even then. Don't do it. Just say no. Mixing BAD!
 
Thanks EF, I'll try it out again. Here is what it looks like now.

Code:
## Sid Meier's Civilization 4
## Copyright Firaxis Games 2006
## 
## CvEventManager
## This class is passed an argsList from CvAppInterface.onEvent
## The argsList can contain anything from mouse location to key info
## The EVENTLIST that are being notified can be found 


from CvPythonExtensions import *
import CvUtil
import CvScreensInterface
import CvDebugTools
import CvWBPopups
import PyHelpers
import Popup as PyPopup
import CvCameraControls
import CvTopCivs
import sys
import CvWorldBuilderScreen
import CvAdvisorUtils
import CvTechChooser

import pickle

# BUG - Next War Merge - start
import SdToolkit
SD_MOD_ID = "NextWar"
SD_NUKES_ID = "NumNukes"
# BUG - Next War Merge - end

gc = CyGlobalContext()
localText = CyTranslator()
PyPlayer = PyHelpers.PyPlayer
PyInfo = PyHelpers.PyInfo


# globals
###################################################


g_iNumNukesWarningMessage = 7
g_iNumNukesGameOver = 20



class DiplomacyEventManager:
	def __init__(self, eventmanager):
		eventManager.addEventHandler("GameStart", self.onGameStart)
		eventManager.addEventHandler("OnLoad", self.onLoadGame)
		eventManager.addEventHandler("GameStart", self.onGameStart)
		eventManager.addEventHandler("BeginGameTurn", self.onBeginGameTurn)
		eventManager.addEventHandler("cityRazed", self.onCityRazed)
		eventManager.addEventHandler("cityDoTurn", self.onCityDoTurn)

		###circus hagenbeck start part 1
                self.oldcity = [-1,-1]
                ###circus hagenbeck end part 1        
		
		# Next War tracks cities that have been razed
		self.iArcologyCityID = -1
		
	def onLoadGame(self, argsList):
		CvAdvisorUtils.resetNoLiberateCities()
# BUG - Next War Merge - start
		# convert old script data list to SdToolkit for old saves
		data = gc.getGame().getScriptData()
		if isinstance(data, list):
			CvUtil.pyPrint('converting script data: %s' % data)
			iNukes = list[0]
			gc.getGame().setScriptData("")
			SdToolkit.sdSetGlobal(SD_MOD_ID, SD_NUKES_ID, iNukes)
# BUG - Next War Merge - end
		return 0

	def onGameStart(self, argsList):
		'Called at the start of the game'

		self.initScriptData()
		
		### circus hagenbeck start part 2
	        if (gc.getGame().getGameTurnYear() <> gc.getDefineINT("START_YEAR")):
                        for iPlayer in range (gc.getMAX_PLAYERS()):
                                player = gc.getPlayer(iPlayer)
				if player.isAlive():
                                        numbuildings = player.countNumBuildings(gc.getInfoTypeForString("BUILDING_CIRCUS_HAGENBECK"))
                                        if numbuildings>0:
                                                for iCity in range(player.getNumCities()):
                                                        pCity = player.getCity(iCity)
                                                        if pCity.getNumBuilding(gc.getInfoTypeForString("BUILDING_CIRCUS_HAGENBECK"))>0:
                                                                self.oldcity = [iPlayer,iCity]
                                                                return
                ###circus hagenbeck end part 2          
		# Are we using the scenario file? If so, then show the backstory popup
		if (CyMap().plot(0,0).getScriptData() == "Scenario"):
			for iPlayer in range(gc.getMAX_PLAYERS()):
				player = gc.getPlayer(iPlayer)
				if (player.isAlive() and player.isHuman()):
					popupInfo = CyPopupInfo()
					popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_TEXT)
					szTitle = u"<font=4b>" + localText.getText("TXT_KEY_NEXT_WAR_BACKSTORY_TITLE", ()) + u"</font>"
					szBody = u"<font=3>" + localText.getText("TXT_KEY_NEXT_WAR_BACKSTORY_TEXT", ()) + u"</font>"
					popupInfo.setText(szTitle + u"\n\n" + szBody)
					popupInfo.addPopup(iPlayer)
		if (gc.getGame().getGameTurnYear() == gc.getDefineINT("START_YEAR") and not gc.getGame().isOption(GameOptionTypes.GAMEOPTION_ADVANCED_START)):
			for iPlayer in range(gc.getMAX_PLAYERS()):
				player = gc.getPlayer(iPlayer)
				if (player.isAlive() and player.isHuman()):
					popupInfo = CyPopupInfo()
					popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON_SCREEN)
					popupInfo.setText(u"showDawnOfMan")
					popupInfo.addPopup(iPlayer)
		else:
			CyInterface().setSoundSelectionReady(true)

		if gc.getGame().isPbem():
			for iPlayer in range(gc.getMAX_PLAYERS()):
				player = gc.getPlayer(iPlayer)
				if (player.isAlive() and player.isHuman()):
					popupInfo = CyPopupInfo()
					popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_DETAILS)
					popupInfo.setOption1(true)
					popupInfo.addPopup(iPlayer)
																	
		CvAdvisorUtils.resetNoLiberateCities()

	def onBeginGameTurn(self, argsList):
		'Called at the beginning of the end of each turn'
		iGameTurn = argsList[0]
###circus hagenbeck start part 3		
		if (CyGame().getTurnYear(iGameTurn)>=1890) and ( iGameTurn % 3 ==0 ):
                        counter = 0
                        while True:
                                counter = counter+1
                                if counter>=100:break
                                dice = gc.getGame().getMapRand()
                                iPlayer = dice.get(gc.getMAX_PLAYERS (), "Players")
                                pPlayer = gc.getPlayer(iPlayer)
                                if pPlayer.isNone():continue
                                if pPlayer.isAlive():
                                        iCity = dice.get(pPlayer.getNumCities () , "Cities" )
                                        pCity = pPlayer.getCity(iCity)
                                        if pCity.isNone():continue
                                        pCity.setNumRealBuilding(gc.getInfoTypeForString("BUILDING_CIRCUSHAGENBECK"),1)
                                        CyInterface().addMessage(iPlayer,false,20,CyTranslator().getText("TXT_KEY_CIRCUS_MOVED",(pCity.getName (),pCity.getName ())),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(gc.getInfoTypeForString("COLOR_GREEN")), pCity.getX(), pCity.getY(), True,True) 
                                        if self.oldcity <>[-1,-1]:
                                                otherplayer = gc.getPlayer(self.oldcity[0])
                                                othercity = otherplayer.getCity(self.oldcity[1])
                                                if not othercity.isNone():
                                                        othercity.setNumRealBuilding(gc.getInfoTypeForString("BUILDING_CIRCUSHAGENBECK"),0)
                                                        CyInterface().addMessage(self.oldcity[0],false,20,CyTranslator().getText("TXT_KEY_CIRCUS_LOST",(othercity.getName (),othercity.getName ())),'',0,'Art/Interface/Buttons/General/warning_popup.dds',ColorTypes(gc.getInfoTypeForString("COLOR_RED")), othercity.getX(), othercity.getY(), True,True)
                                        self.oldcity = [iPlayer,iCity]                                 
                                        
                                        break
###circus hagenbeck end part 3         
		CvTopCivs.CvTopCivs().turnChecker(iGameTurn)
		if (CyMap().plot(0,0).getScriptData() == "Scenario"):
			if iGameTurn!=0:
				if iGameTurn%2 == 0:
					self.doCheckDepletion()
		
	def onCityRazed(self, argsList):
		'City Razed'
		city, iPlayer = argsList
		iOwner = city.findHighestCulture()

		# Partisans!
		if city.getPopulation > 1 and iOwner != -1 and iPlayer != -1:
			owner = gc.getPlayer(iOwner)
			if not owner.isBarbarian() and owner.getNumCities() > 0:
				if gc.getTeam(owner.getTeam()).isAtWar(gc.getPlayer(iPlayer).getTeam()):
					if gc.getNumEventTriggerInfos() > 0: # prevents mods that don't have events from getting an error
						iEvent = CvUtil.findInfoTypeNum(gc.getEventTriggerInfo, gc.getNumEventTriggerInfos(),'EVENTTRIGGER_PARTISANS')
						if iEvent != -1 and gc.getGame().isEventActive(iEvent) and owner.getEventTriggerWeight(iEvent) < 0:
							triggerData = owner.initTriggeredData(iEvent, true, -1, city.getX(), city.getY(), iPlayer, city.getID(), -1, -1, -1, -1)
			
		#Raze the Arcology
		owner = PyPlayer(city.getOwner())
		razor = PyPlayer(iPlayer)
		
		self.iArcologyCityID = -1
		
		if city.getNumRealBuilding(gc.getInfoTypeForString("BUILDING_ARCOLOGY")) or city.getNumRealBuilding(gc.getInfoTypeForString("BUILDING_ARCOLOGY_SHIELDING")) or city.getNumRealBuilding(gc.getInfoTypeForString("BUILDING_DEFLECTOR_SHIELDING")):
			self.iArcologyCityID = city.getID()
		
		CvUtil.pyPrint('Player %d Civilization %s City %s was razed by Player %d' 
			%(owner.getID(), owner.getCivilizationName(), city.getName(), razor.getID()))	
		CvUtil.pyPrint("City Razed Event: %s" %(city.getName(),))
	
	def onCityDoTurn(self, argsList):
		'City Production'
		pCity = argsList[0]
		iPlayer = argsList[1]
        
# no anger defying UN resolutions start #
		iGovernmentCivicOption = CvUtil.findInfoTypeNum(gc.getCivicOptionInfo,gc.getNumCivicOptionInfos(),'CIVICOPTION_GOVERNMENT')
		iPoliceState = CvUtil.findInfoTypeNum(gc.getCivicInfo,gc.getNumCivicInfos(),'CIVIC_POLICE_STATE')
		pPlayer = gc.getPlayer(iPlayer)
		iGovernmentCivic = pPlayer.getCivics(iGovernmentCivicOption)

		if (iGovernmentCivic == iPoliceState):
			pCity.changeDefyResolutionAngerTimer(pCity.getDefyResolutionAngerTimer())
# no anger defying UN resolutions end #        

		CvAdvisorUtils.cityAdvise(pCity, iPlayer)
	
####### Next War Functions ######
## Added Fort to doCheckDepletion -- otherwise bonuses worked via forts would never be subject to resource depletion.   JKP


	def doCheckDepletion(self):
		self.doCheckWorkedResource("BONUS_ALUMINUM", "IMPROVEMENT_MINE", 880)
		self.doCheckWorkedResource("BONUS_ALUMINUM", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_BANANA", "IMPROVEMENT_PLANTATION", 1120)
		self.doCheckWorkedResource("BONUS_BANANA", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_CLAM", "IMPROVEMENT_FISHING_BOATS", 880)
		self.doCheckWorkedResource("BONUS_COAL", "IMPROVEMENT_MINE", 880)
		self.doCheckWorkedResource("BONUS_COAL", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_COPPER", "IMPROVEMENT_MINE", 880)
		self.doCheckWorkedResource("BONUS_COPPER", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_CORN", "IMPROVEMENT_FARM", 1120)
		self.doCheckWorkedResource("BONUS_CORN", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_COW", "IMPROVEMENT_PASTURE", 1120)
		self.doCheckWorkedResource("BONUS_COW", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_CRAB", "IMPROVEMENT_FISHING_BOATS", 1120)
		self.doCheckWorkedResource("BONUS_DEER", "IMPROVEMENT_CAMP", 780)
		self.doCheckWorkedResource("BONUS_DEER", "IMPROVEMENT_FORT", 780)
		self.doCheckWorkedResource("BONUS_DYE", "IMPROVEMENT_PLANTATION", 1120)
		self.doCheckWorkedResource("BONUS_DYE", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_FISH", "IMPROVEMENT_FISHING_BOATS", 880)
		self.doCheckWorkedResource("BONUS_FUR", "IMPROVEMENT_CAMP", 560)
		self.doCheckWorkedResource("BONUS_FUR", "IMPROVEMENT_FORT", 560)
		self.doCheckWorkedResource("BONUS_GEMS", "IMPROVEMENT_MINE", 1120)
		self.doCheckWorkedResource("BONUS_GEMS", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_GOLD", "IMPROVEMENT_MINE", 880)
		self.doCheckWorkedResource("BONUS_GOLD", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_HORSE", "IMPROVEMENT_PASTURE", 1120)
		self.doCheckWorkedResource("BONUS_HORSE", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_IRON", "IMPROVEMENT_MINE", 880)
		self.doCheckWorkedResource("BONUS_IRON", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_IVORY", "IMPROVEMENT_CAMP", 560)
		self.doCheckWorkedResource("BONUS_IVORY", "IMPROVEMENT_FORT", 560)
		self.doCheckWorkedResource("BONUS_MARBLE", "IMPROVEMENT_QUARRY", 750)
		self.doCheckWorkedResource("BONUS_MARBLE", "IMPROVEMENT_FORT", 750)
		self.doCheckWorkedResource("BONUS_OIL", "IMPROVEMENT_WELL", 880)
		self.doCheckWorkedResource("BONUS_OIL", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_OIL", "IMPROVEMENT_OFFSHORE_PLATFORM", 880)
		self.doCheckWorkedResource("BONUS_PIG", "IMPROVEMENT_PASTURE", 1120)
		self.doCheckWorkedResource("BONUS_PIG", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_RICE", "IMPROVEMENT_FARM", 1120)
		self.doCheckWorkedResource("BONUS_RICE", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_SILK", "IMPROVEMENT_PLANTATION", 1120)
		self.doCheckWorkedResource("BONUS_SILK", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_SILVER", "IMPROVEMENT_MINE", 880)
		self.doCheckWorkedResource("BONUS_SILVER", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_SPICES", "IMPROVEMENT_PLANTATION", 1120)
		self.doCheckWorkedResource("BONUS_SPICES", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_STONE", "IMPROVEMENT_QUARRY", 750)
		self.doCheckWorkedResource("BONUS_STONE", "IMPROVEMENT_FORT", 750)
		self.doCheckWorkedResource("BONUS_SUGAR", "IMPROVEMENT_PLANTATION", 1120)
		self.doCheckWorkedResource("BONUS_SUGAR", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_URANIUM", "IMPROVEMENT_MINE", 880)
		self.doCheckWorkedResource("BONUS_URANIUM", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_WHALE", "IMPROVEMENT_WHALING_BOATS", 560)
		self.doCheckWorkedResource("BONUS_WHEAT", "IMPROVEMENT_FARM", 1120)
		self.doCheckWorkedResource("BONUS_WHEAT", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_WINE", "IMPROVEMENT_WINERY", 1120)
		self.doCheckWorkedResource("BONUS_WINE", "IMPROVEMENT_FORT", 1120)

	def doCheckWorkedResource(self, bonus, improvement, randomInt):
            
		iBonus = CvUtil.findInfoTypeNum(gc.getBonusInfo, gc.getNumBonusInfos(), bonus)
        
		if (iBonus == -1):
			return
        
		lValidPlots = self.getPlotListbyBonus(iBonus)
        
		if len(lValidPlots) == 0:
			return
                
##If you have the requisite improvement (incl. fort) or if the plot is being worked by a City, continue.
                        
			for plot in lValidPlots:
				P = False
                
				if plot.getImprovementType() == CvUtil.findInfoTypeNum(gc.getImprovementInfo, gc.getNumImprovementInfos(), improvement):
					P = True
				elif plot.isCity():
					P = True

				if P == True:
					if self.getRandomNumber(randomInt) == 0:
                    
						pBonusInfo = gc.getBonusInfo(iBonus)
                    
						plot.setBonusType(-1)
                    
						szTitle = localText.getText("TEXT_KEY_NEXT_WAR_RESOURCE_DEPLETED_TITLE", ())# (pBonusInfo.getDescription(), plotgetX(), plot.getY()))
                        #szText = localText.getText("TEXT_KEY_NEXT_WAR_RESOURCE_DEPLETED", (pBonusInfo.getDescription(), plot.getX(), plot.getY()))
                        #Not sure what the above commented out code for (debugging?) -- it was commented out in PM's original NextWar code.  JKP1187
                        
						CyInterface().addMessage(plot.getOwner(), False, gc.getEVENT_MESSAGE_TIME(), szTitle, "AS2D_DISCOVERBONUS", InterfaceMessageTypes.MESSAGE_TYPE_MINOR_EVENT, pBonusInfo.getButton(), gc.getInfoTypeForString("COLOR_GREEN"), plot.getX(), plot.getY(), True, True)		
				else:
					return
				

### Below are additional functions necessary to the activity of the resource depl'n code:

	def getPlotListbyBonus(self, iBonus):
		lPlots = []
		totalPlots = gc.getMap().numPlots()
		
		for i in range(totalPlots):
			plot = gc.getMap().plotByIndex(i)
			iOwner = plot.getOwner()
			if (iOwner != -1):
				if plot.getBonusType(gc.getPlayer(iOwner).getTeam()) == iBonus:
					lPlots.append(plot)
		return lPlots

	def getRandomNumber(self, int):
		return gc.getGame().getSorenRandNum(int, "Next War")


# BUG - Next War Merge - start
	def initScriptData(self):
		
		# Set default script data manually since we need defaults for all values in the array before any functions can be called on them
		iDefaultNumNukesFired = 0
		SdToolkit.sdSetGlobal(SD_MOD_ID, SD_NUKES_ID, iDefaultNumNukesFired)
		
	def getGameNumNukes(self):
		return SdToolkit.sdGetGlobal(SD_MOD_ID, SD_NUKES_ID)

	def setGameNumNukes(self, iValue):
		SdToolkit.sdSetGlobal(SD_MOD_ID, SD_NUKES_ID, iValue)
		self.checkNukeStuff(iValue)
		
	def changeGameNumNukes(self, iChange):
		self.setGameNumNukes(self.getGameNumNukes() + iChange)
# BUG - Next War Merge - end

As far as the indentation goes...

1) Every line after that that is supposed to be part of the __init__ function needs to be indented more than that line is, equal to the later lines that were already part of the function. They are currently indented the same amount, as far as python is concerned.

2) Don't mix tabs and spaces to indent. It will only work if you are very lucky. Civ4's files use tabs, so use tabs. If your editor is changing tabs to some specific number of spaces, turn that feature off (for example, in Notepad++ it is on the "Edit Components" tab of the Preferences pop-up you get via the "Preferences..." item on the Settings menu).

Well, I don't really know what to do, I use Scintilla Text Editor to do my editing. I am using tabs and it looks ilke the indentation is right. I have posted a screenshot of the portion in question.
 
If you go up to post 101 and use your mouse to select the text, by moving your mouse around while the button is still down you can see that what is posted is showing as 1 single tab before the "def" but 8 spaces on each line after that.

What it appears to be showing you and what you get when you do your cut'n'paste seems to be 2 different things.

It seems to be be showing 2 tabs, but really using 8 spaces. It ought to have some setting somewhere to change this.

Did you do the indenting by hitting the tab key or spaces?

Edit: in your new post, 105, it appears to be the correct 2 tabs in front of the "eventmanager" lines, but spaces in front of the "self.oldcity = [-1,-1]" and the line after that.
 
I think I got the indentation thing right now. But I got a python error that said this...

attachment.php

...what is that about?
 
I expect is is because you used "eventmanager" (no capital M) on the "__init__" line. Change that to eventManager.

Python is case sensitive.

Thanks, I'll give it another go.

BTW, you guys are going to KILL me when I ask how I can add new things to this. Like if I had to add another wonder or feature or something.
 
Seems to be working well now, thanks everyone! :goodjob:

Although, I did have to click okay at the dawn of man screen three times. Which was very strange. There weren't three windows at once though, I clicked it, it went away for a second (said autosaving...) than came up again, repeated that twice, and then it went into the game. Strange right?

Now, I have a few more things I have to add to the mod. What I'm going to do is playtest this up until Leonardo's Workshop just to see if it still works (it probably will) then I'll move on to adding the effects for King Richard's Crusade. I'm pretty sure I know what to do, but if I run into problems I'll ask you guys again if you don't mind.
 
While it won't break anything to leave this stuff in, you should at some point go through and remove duplicate code that has been copied from CvEventManager. With BUG, the event handlers in CvEventManager are still active. Thus you can remove this line

Code:
CvTopCivs.CvTopCivs().turnChecker(iGameTurn)

from near the end of your event manager's onBeginGameTurn() function. You can remove everything starting with

Code:
if (gc.getGame().getGameTurnYear() == gc.getDefineINT("START_YEAR") and not gc.getGame().isOption(GameOptionTypes.GAMEOPTION_ADVANCED_START)):

(I think) from onGameStart(). And you can remove\

Code:
		CvUtil.pyPrint('Player %d Civilization %s City %s was razed by Player %d' 
			%(owner.getID(), owner.getCivilizationName(), city.getName(), razor.getID()))	
		CvUtil.pyPrint("City Razed Event: %s" %(city.getName(),))

and this

Code:
CvAdvisorUtils.cityAdvise(pCity, iPlayer)

Removing these duplicate blocks of code will make your mod work better. Without doing so, you'll get two Dawn of Man popups, two "SoAndSo says you're the weakest civ, good bye!" messages, duplicate "city razed" log messages, etc. Basically, compare your event manager side-by-side with CvEventManager from BTS. Compare each event handler in your EM with the function in CvEM. Be careful as you cannot remove things that yours uses. For example, you cannot remove these duplicated lines

Code:
	def onCityDoTurn(self, argsList):
		'City Production'
		pCity = argsList[0]
		iPlayer = argsList[1]

because the code right below it (which you need to keep) uses the iPlayer variable.

Like if I had to add another wonder or feature or something.

NOT ALLOWED! :p

Seriously, it'll get easier as you go. I cannot over-recommend that you take a weekend to work through that free online book/tutorial for Python. It's not rocket science, and you'll have far more fun modding when you can do stuff more quickly and on your own. I'm always happy to help people learn to code.
 
Although, I did have to click okay at the dawn of man screen three times.

This is due to the duplicated code as I mentioned in my post right after yours. That you see it three times instead of twice makes me think you have another event manager in there as well. Make sure you do not have a CvEventManager.py module in your mod. You should just have the module above.
 
Alright, so if I get rid of the duplicate code I shouldn't get all the extra pop-ups and stuff? Fantastic. :goodjob:

I'm still getting this sporadic Assert Failure during the game. I still can't figure out what it is from, but it pops up twice at a time:

attachment.php

Do you have any idea what this is, what could be causing it, and if it is bad?
 
While it won't break anything to leave this stuff in, you should at some point go through and remove duplicate code that has been copied from CvEventManager. With BUG, the event handlers in CvEventManager are still active. Thus you can remove this line

Code:
CvTopCivs.CvTopCivs().turnChecker(iGameTurn)

from near the end of your event manager's onBeginGameTurn() function. You can remove everything starting with

Code:
if (gc.getGame().getGameTurnYear() == gc.getDefineINT("START_YEAR") and not gc.getGame().isOption(GameOptionTypes.GAMEOPTION_ADVANCED_START)):

(I think) from onGameStart(). And you can remove\

Code:
		CvUtil.pyPrint('Player %d Civilization %s City %s was razed by Player %d' 
			%(owner.getID(), owner.getCivilizationName(), city.getName(), razor.getID()))	
		CvUtil.pyPrint("City Razed Event: %s" %(city.getName(),))

and this

Code:
CvAdvisorUtils.cityAdvise(pCity, iPlayer)

Removing these duplicate blocks of code will make your mod work better. Without doing so, you'll get two Dawn of Man popups, two "SoAndSo says you're the weakest civ, good bye!" messages, duplicate "city razed" log messages, etc. Basically, compare your event manager side-by-side with CvEventManager from BTS. Compare each event handler in your EM with the function in CvEM. Be careful as you cannot remove things that yours uses. For example, you cannot remove these duplicated lines

Code:
	def onCityDoTurn(self, argsList):
		'City Production'
		pCity = argsList[0]
		iPlayer = argsList[1]

because the code right below it (which you need to keep) uses the iPlayer variable.



NOT ALLOWED! :p

Seriously, it'll get easier as you go. I cannot over-recommend that you take a weekend to work through that free online book/tutorial for Python. It's not rocket science, and you'll have far more fun modding when you can do stuff more quickly and on your own. I'm always happy to help people learn to code.

I actually didn't notice most of this code in my file. Here it is, would you mind just highliting a couple of the things you meant here?

Code:
## Sid Meier's Civilization 4
## Copyright Firaxis Games 2006
## 
## CvEventManager
## This class is passed an argsList from CvAppInterface.onEvent
## The argsList can contain anything from mouse location to key info
## The EVENTLIST that are being notified can be found 


from CvPythonExtensions import *
import CvUtil
import CvScreensInterface
import CvDebugTools
import CvWBPopups
import PyHelpers
import Popup as PyPopup
import CvCameraControls
import CvTopCivs
import sys
import CvWorldBuilderScreen
import CvAdvisorUtils
import CvTechChooser

import pickle

# BUG - Next War Merge - start
import SdToolkit
SD_MOD_ID = "NextWar"
SD_NUKES_ID = "NumNukes"
# BUG - Next War Merge - end

gc = CyGlobalContext()
localText = CyTranslator()
PyPlayer = PyHelpers.PyPlayer
PyInfo = PyHelpers.PyInfo


# globals
###################################################


g_iNumNukesWarningMessage = 7
g_iNumNukesGameOver = 20



class DiplomacyEventManager:
	def __init__(self, eventManager):
		eventManager.addEventHandler("GameStart", self.onGameStart)
		eventManager.addEventHandler("OnLoad", self.onLoadGame)
		eventManager.addEventHandler("GameStart", self.onGameStart)
		eventManager.addEventHandler("BeginGameTurn", self.onBeginGameTurn)
		eventManager.addEventHandler("cityRazed", self.onCityRazed)
		eventManager.addEventHandler("cityDoTurn", self.onCityDoTurn)

		###circus hagenbeck start part 1
                self.oldcity = [-1,-1]
                ###circus hagenbeck end part 1        
		
		# Next War tracks cities that have been razed
		self.iArcologyCityID = -1
		
	def onLoadGame(self, argsList):
		CvAdvisorUtils.resetNoLiberateCities()
# BUG - Next War Merge - start
		# convert old script data list to SdToolkit for old saves
		data = gc.getGame().getScriptData()
		if isinstance(data, list):
			CvUtil.pyPrint('converting script data: %s' % data)
			iNukes = list[0]
			gc.getGame().setScriptData("")
			SdToolkit.sdSetGlobal(SD_MOD_ID, SD_NUKES_ID, iNukes)
# BUG - Next War Merge - end
		return 0

	def onGameStart(self, argsList):
		'Called at the start of the game'

		self.initScriptData()
		
		### circus hagenbeck start part 2
	        if (gc.getGame().getGameTurnYear() <> gc.getDefineINT("START_YEAR")):
                        for iPlayer in range (gc.getMAX_PLAYERS()):
                                player = gc.getPlayer(iPlayer)
				if player.isAlive():
                                        numbuildings = player.countNumBuildings(gc.getInfoTypeForString("BUILDING_CIRCUS_HAGENBECK"))
                                        if numbuildings>0:
                                                for iCity in range(player.getNumCities()):
                                                        pCity = player.getCity(iCity)
                                                        if pCity.getNumBuilding(gc.getInfoTypeForString("BUILDING_CIRCUS_HAGENBECK"))>0:
                                                                self.oldcity = [iPlayer,iCity]
                                                                return
                ###circus hagenbeck end part 2          
		# Are we using the scenario file? If so, then show the backstory popup
		if (CyMap().plot(0,0).getScriptData() == "Scenario"):
			for iPlayer in range(gc.getMAX_PLAYERS()):
				player = gc.getPlayer(iPlayer)
				if (player.isAlive() and player.isHuman()):
					popupInfo = CyPopupInfo()
					popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_TEXT)
					szTitle = u"<font=4b>" + localText.getText("TXT_KEY_NEXT_WAR_BACKSTORY_TITLE", ()) + u"</font>"
					szBody = u"<font=3>" + localText.getText("TXT_KEY_NEXT_WAR_BACKSTORY_TEXT", ()) + u"</font>"
					popupInfo.setText(szTitle + u"\n\n" + szBody)
					popupInfo.addPopup(iPlayer)
		if (gc.getGame().getGameTurnYear() == gc.getDefineINT("START_YEAR") and not gc.getGame().isOption(GameOptionTypes.GAMEOPTION_ADVANCED_START)):
			for iPlayer in range(gc.getMAX_PLAYERS()):
				player = gc.getPlayer(iPlayer)
				if (player.isAlive() and player.isHuman()):
					popupInfo = CyPopupInfo()
					popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON_SCREEN)
					popupInfo.setText(u"showDawnOfMan")
					popupInfo.addPopup(iPlayer)
		else:
			CyInterface().setSoundSelectionReady(true)

		if gc.getGame().isPbem():
			for iPlayer in range(gc.getMAX_PLAYERS()):
				player = gc.getPlayer(iPlayer)
				if (player.isAlive() and player.isHuman()):
					popupInfo = CyPopupInfo()
					popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_DETAILS)
					popupInfo.setOption1(true)
					popupInfo.addPopup(iPlayer)
																	
		CvAdvisorUtils.resetNoLiberateCities()

	def onBeginGameTurn(self, argsList):
		'Called at the beginning of the end of each turn'
		iGameTurn = argsList[0]
###circus hagenbeck start part 3		
		if (CyGame().getTurnYear(iGameTurn)>=1890) and ( iGameTurn % 3 ==0 ):
                        counter = 0
                        while True:
                                counter = counter+1
                                if counter>=100:break
                                dice = gc.getGame().getMapRand()
                                iPlayer = dice.get(gc.getMAX_PLAYERS (), "Players")
                                pPlayer = gc.getPlayer(iPlayer)
                                if pPlayer.isNone():continue
                                if pPlayer.isAlive():
                                        iCity = dice.get(pPlayer.getNumCities () , "Cities" )
                                        pCity = pPlayer.getCity(iCity)
                                        if pCity.isNone():continue
                                        pCity.setNumRealBuilding(gc.getInfoTypeForString("BUILDING_CIRCUSHAGENBECK"),1)
                                        CyInterface().addMessage(iPlayer,false,20,CyTranslator().getText("TXT_KEY_CIRCUS_MOVED",(pCity.getName (),pCity.getName ())),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(gc.getInfoTypeForString("COLOR_GREEN")), pCity.getX(), pCity.getY(), True,True) 
                                        if self.oldcity <>[-1,-1]:
                                                otherplayer = gc.getPlayer(self.oldcity[0])
                                                othercity = otherplayer.getCity(self.oldcity[1])
                                                if not othercity.isNone():
                                                        othercity.setNumRealBuilding(gc.getInfoTypeForString("BUILDING_CIRCUSHAGENBECK"),0)
                                                        CyInterface().addMessage(self.oldcity[0],false,20,CyTranslator().getText("TXT_KEY_CIRCUS_LOST",(othercity.getName (),othercity.getName ())),'',0,'Art/Interface/Buttons/General/warning_popup.dds',ColorTypes(gc.getInfoTypeForString("COLOR_RED")), othercity.getX(), othercity.getY(), True,True)
                                        self.oldcity = [iPlayer,iCity]                                 
                                        
                                        break
###circus hagenbeck end part 3         
		
	def onCityRazed(self, argsList):
		'City Razed'
		city, iPlayer = argsList
		iOwner = city.findHighestCulture()

		# Partisans!
		if city.getPopulation > 1 and iOwner != -1 and iPlayer != -1:
			owner = gc.getPlayer(iOwner)
			if not owner.isBarbarian() and owner.getNumCities() > 0:
				if gc.getTeam(owner.getTeam()).isAtWar(gc.getPlayer(iPlayer).getTeam()):
					if gc.getNumEventTriggerInfos() > 0: # prevents mods that don't have events from getting an error
						iEvent = CvUtil.findInfoTypeNum(gc.getEventTriggerInfo, gc.getNumEventTriggerInfos(),'EVENTTRIGGER_PARTISANS')
						if iEvent != -1 and gc.getGame().isEventActive(iEvent) and owner.getEventTriggerWeight(iEvent) < 0:
							triggerData = owner.initTriggeredData(iEvent, true, -1, city.getX(), city.getY(), iPlayer, city.getID(), -1, -1, -1, -1)
			
		#Raze the Arcology
		owner = PyPlayer(city.getOwner())
		razor = PyPlayer(iPlayer)
		
		self.iArcologyCityID = -1
		
		if city.getNumRealBuilding(gc.getInfoTypeForString("BUILDING_ARCOLOGY")) or city.getNumRealBuilding(gc.getInfoTypeForString("BUILDING_ARCOLOGY_SHIELDING")) or city.getNumRealBuilding(gc.getInfoTypeForString("BUILDING_DEFLECTOR_SHIELDING")):
			self.iArcologyCityID = city.getID()
		
		CvUtil.pyPrint('Player %d Civilization %s City %s was razed by Player %d' 
			%(owner.getID(), owner.getCivilizationName(), city.getName(), razor.getID()))	
		CvUtil.pyPrint("City Razed Event: %s" %(city.getName(),))
	
	def onCityDoTurn(self, argsList):
		'City Production'
		pCity = argsList[0]
		iPlayer = argsList[1]
        
# no anger defying UN resolutions start #
		iGovernmentCivicOption = CvUtil.findInfoTypeNum(gc.getCivicOptionInfo,gc.getNumCivicOptionInfos(),'CIVICOPTION_GOVERNMENT')
		iPoliceState = CvUtil.findInfoTypeNum(gc.getCivicInfo,gc.getNumCivicInfos(),'CIVIC_POLICE_STATE')
		pPlayer = gc.getPlayer(iPlayer)
		iGovernmentCivic = pPlayer.getCivics(iGovernmentCivicOption)

		if (iGovernmentCivic == iPoliceState):
			pCity.changeDefyResolutionAngerTimer(pCity.getDefyResolutionAngerTimer())
# no anger defying UN resolutions end #        

		CvAdvisorUtils.cityAdvise(pCity, iPlayer)
	
####### Next War Functions ######
## Added Fort to doCheckDepletion -- otherwise bonuses worked via forts would never be subject to resource depletion.   JKP


	def doCheckDepletion(self):
		self.doCheckWorkedResource("BONUS_ALUMINUM", "IMPROVEMENT_MINE", 880)
		self.doCheckWorkedResource("BONUS_ALUMINUM", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_BANANA", "IMPROVEMENT_PLANTATION", 1120)
		self.doCheckWorkedResource("BONUS_BANANA", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_CLAM", "IMPROVEMENT_FISHING_BOATS", 880)
		self.doCheckWorkedResource("BONUS_COAL", "IMPROVEMENT_MINE", 880)
		self.doCheckWorkedResource("BONUS_COAL", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_COPPER", "IMPROVEMENT_MINE", 880)
		self.doCheckWorkedResource("BONUS_COPPER", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_CORN", "IMPROVEMENT_FARM", 1120)
		self.doCheckWorkedResource("BONUS_CORN", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_COW", "IMPROVEMENT_PASTURE", 1120)
		self.doCheckWorkedResource("BONUS_COW", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_CRAB", "IMPROVEMENT_FISHING_BOATS", 1120)
		self.doCheckWorkedResource("BONUS_DEER", "IMPROVEMENT_CAMP", 780)
		self.doCheckWorkedResource("BONUS_DEER", "IMPROVEMENT_FORT", 780)
		self.doCheckWorkedResource("BONUS_DYE", "IMPROVEMENT_PLANTATION", 1120)
		self.doCheckWorkedResource("BONUS_DYE", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_FISH", "IMPROVEMENT_FISHING_BOATS", 880)
		self.doCheckWorkedResource("BONUS_FUR", "IMPROVEMENT_CAMP", 560)
		self.doCheckWorkedResource("BONUS_FUR", "IMPROVEMENT_FORT", 560)
		self.doCheckWorkedResource("BONUS_GEMS", "IMPROVEMENT_MINE", 1120)
		self.doCheckWorkedResource("BONUS_GEMS", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_GOLD", "IMPROVEMENT_MINE", 880)
		self.doCheckWorkedResource("BONUS_GOLD", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_HORSE", "IMPROVEMENT_PASTURE", 1120)
		self.doCheckWorkedResource("BONUS_HORSE", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_IRON", "IMPROVEMENT_MINE", 880)
		self.doCheckWorkedResource("BONUS_IRON", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_IVORY", "IMPROVEMENT_CAMP", 560)
		self.doCheckWorkedResource("BONUS_IVORY", "IMPROVEMENT_FORT", 560)
		self.doCheckWorkedResource("BONUS_MARBLE", "IMPROVEMENT_QUARRY", 750)
		self.doCheckWorkedResource("BONUS_MARBLE", "IMPROVEMENT_FORT", 750)
		self.doCheckWorkedResource("BONUS_OIL", "IMPROVEMENT_WELL", 880)
		self.doCheckWorkedResource("BONUS_OIL", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_OIL", "IMPROVEMENT_OFFSHORE_PLATFORM", 880)
		self.doCheckWorkedResource("BONUS_PIG", "IMPROVEMENT_PASTURE", 1120)
		self.doCheckWorkedResource("BONUS_PIG", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_RICE", "IMPROVEMENT_FARM", 1120)
		self.doCheckWorkedResource("BONUS_RICE", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_SILK", "IMPROVEMENT_PLANTATION", 1120)
		self.doCheckWorkedResource("BONUS_SILK", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_SILVER", "IMPROVEMENT_MINE", 880)
		self.doCheckWorkedResource("BONUS_SILVER", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_SPICES", "IMPROVEMENT_PLANTATION", 1120)
		self.doCheckWorkedResource("BONUS_SPICES", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_STONE", "IMPROVEMENT_QUARRY", 750)
		self.doCheckWorkedResource("BONUS_STONE", "IMPROVEMENT_FORT", 750)
		self.doCheckWorkedResource("BONUS_SUGAR", "IMPROVEMENT_PLANTATION", 1120)
		self.doCheckWorkedResource("BONUS_SUGAR", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_URANIUM", "IMPROVEMENT_MINE", 880)
		self.doCheckWorkedResource("BONUS_URANIUM", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_WHALE", "IMPROVEMENT_WHALING_BOATS", 560)
		self.doCheckWorkedResource("BONUS_WHEAT", "IMPROVEMENT_FARM", 1120)
		self.doCheckWorkedResource("BONUS_WHEAT", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_WINE", "IMPROVEMENT_WINERY", 1120)
		self.doCheckWorkedResource("BONUS_WINE", "IMPROVEMENT_FORT", 1120)

	def doCheckWorkedResource(self, bonus, improvement, randomInt):
            
		iBonus = CvUtil.findInfoTypeNum(gc.getBonusInfo, gc.getNumBonusInfos(), bonus)
        
		if (iBonus == -1):
			return
        
		lValidPlots = self.getPlotListbyBonus(iBonus)
        
		if len(lValidPlots) == 0:
			return
                
##If you have the requisite improvement (incl. fort) or if the plot is being worked by a City, continue.
                        
			for plot in lValidPlots:
				P = False
                
				if plot.getImprovementType() == CvUtil.findInfoTypeNum(gc.getImprovementInfo, gc.getNumImprovementInfos(), improvement):
					P = True
				elif plot.isCity():
					P = True

				if P == True:
					if self.getRandomNumber(randomInt) == 0:
                    
						pBonusInfo = gc.getBonusInfo(iBonus)
                    
						plot.setBonusType(-1)
                    
						szTitle = localText.getText("TEXT_KEY_NEXT_WAR_RESOURCE_DEPLETED_TITLE", ())# (pBonusInfo.getDescription(), plotgetX(), plot.getY()))
                        #szText = localText.getText("TEXT_KEY_NEXT_WAR_RESOURCE_DEPLETED", (pBonusInfo.getDescription(), plot.getX(), plot.getY()))
                        #Not sure what the above commented out code for (debugging?) -- it was commented out in PM's original NextWar code.  JKP1187
                        
						CyInterface().addMessage(plot.getOwner(), False, gc.getEVENT_MESSAGE_TIME(), szTitle, "AS2D_DISCOVERBONUS", InterfaceMessageTypes.MESSAGE_TYPE_MINOR_EVENT, pBonusInfo.getButton(), gc.getInfoTypeForString("COLOR_GREEN"), plot.getX(), plot.getY(), True, True)		
				else:
					return
				

### Below are additional functions necessary to the activity of the resource depl'n code:

	def getPlotListbyBonus(self, iBonus):
		lPlots = []
		totalPlots = gc.getMap().numPlots()
		
		for i in range(totalPlots):
			plot = gc.getMap().plotByIndex(i)
			iOwner = plot.getOwner()
			if (iOwner != -1):
				if plot.getBonusType(gc.getPlayer(iOwner).getTeam()) == iBonus:
					lPlots.append(plot)
		return lPlots

	def getRandomNumber(self, int):
		return gc.getGame().getSorenRandNum(int, "Next War")


# BUG - Next War Merge - start
	def initScriptData(self):
		
		# Set default script data manually since we need defaults for all values in the array before any functions can be called on them
		iDefaultNumNukesFired = 0
		SdToolkit.sdSetGlobal(SD_MOD_ID, SD_NUKES_ID, iDefaultNumNukesFired)
		
	def getGameNumNukes(self):
		return SdToolkit.sdGetGlobal(SD_MOD_ID, SD_NUKES_ID)

	def setGameNumNukes(self, iValue):
		SdToolkit.sdSetGlobal(SD_MOD_ID, SD_NUKES_ID, iValue)
		self.checkNukeStuff(iValue)
		
	def changeGameNumNukes(self, iChange):
		self.setGameNumNukes(self.getGameNumNukes() + iChange)
# BUG - Next War Merge - end

In fact, I think the only thing I noticed was the first line you told me to get rid of.
 
I'll take a look at that assert. I think there may be a recent bug in BUG that's causing it. It's definitely a problem--asking if team A has met team TEAM_NONE which isn't kosher, but it's probably a display issue only so not a huge deal.
 
I don't have a CvEventManager.py file, but there is a BUGEventManager.py file. This should be there though, right?

Yes, that belongs there. Removing it will break a lot of stuff. Once you get the duplicate code removed it'll be easier to spot remaining duplicate events.

I actually didn't notice most of this code in my file. Here it is, would you mind just highliting a couple of the things you meant here?

Um, I spotted a couple of the things just skimming the code by eye. Please try using your editor's find command. Paste in the first line of each duplicate code block I posted (just the text part) and see what happens. If your editor doesn't have a find command (:eek:) go get Notepad++. Even if it does, go get Notepad++. :)
 
Alright, well I see that code there but they don't appear to be in the places you referenced. I'll go ahead and delete all of those and try a test run. :goodjob:

I use Scintilla Text Editor, which I'm pretty comfortable with it. Is notepad++ that much better though?
 
Alright, well I see that code there but they don't appear to be in the places you referenced.

It's possible, but the more important part is that the code itself matches what I posted.

I use Scintilla Text Editor, which I'm pretty comfortable with it. Is notepad++ that much better though?

I haven't used Scintilla before, so I cannot compare. If it cannot show you the whitespace characters to easily discern between space and tab, or do automatic replacements for you, or do syntax highlighting (coloring the Python keywords in a different color), or do automatic tabbing, then yes, Notepad++ is better. ;)

That being said, I would normally recommend staying with what you know as long as it doesn't break your code or slow you down.
 
I haven't used Scintilla before, so I cannot compare. If it cannot show you the whitespace characters to easily discern between space and tab, or do automatic replacements for you, or do syntax highlighting (coloring the Python keywords in a different color), or do automatic tabbing, then yes, Notepad++ is better. ;)

That being said, I would normally recommend staying with what you know as long as it doesn't break your code or slow you down.

Yeah, it does all of that stuff. :goodjob:

Anyway, there is a problem though. I went ahead and deleted the code you told me to delete (don't fret though, in case I did it wrong I kept a backup copy, I always keep backup copies). But I got this assert failure after doing so when trying to start a new game:

attachment.php

Now, I have also attached an image of the Civilopedia entry for the Olympic Games (which is what this is referring too, I know it says HAGENBECK, but I kept the same tags I just changed the text on it, so that part is correct) so you knew it was in there and for some reason this was telling me it wasn't. It also seems to be referring to the EspionageInfos xml file, which I thought was odd but I guess if it is a bug or messed up code something like that could easily occur.

Anyway, after deleting the stuff you told me this is what I came up with (i.e. the DiplomacyEventManager.py file that I edited which "caused" this Assert Failure to happen). Do you notice anything I did wrong here:

Code:
## Sid Meier's Civilization 4
## Copyright Firaxis Games 2006
## 
## CvEventManager
## This class is passed an argsList from CvAppInterface.onEvent
## The argsList can contain anything from mouse location to key info
## The EVENTLIST that are being notified can be found 


from CvPythonExtensions import *
import CvUtil
import CvScreensInterface
import CvDebugTools
import CvWBPopups
import PyHelpers
import Popup as PyPopup
import CvCameraControls
import CvTopCivs
import sys
import CvWorldBuilderScreen
import CvAdvisorUtils
import CvTechChooser

import pickle

# BUG - Next War Merge - start
import SdToolkit
SD_MOD_ID = "NextWar"
SD_NUKES_ID = "NumNukes"
# BUG - Next War Merge - end

gc = CyGlobalContext()
localText = CyTranslator()
PyPlayer = PyHelpers.PyPlayer
PyInfo = PyHelpers.PyInfo


# globals
###################################################


g_iNumNukesWarningMessage = 7
g_iNumNukesGameOver = 20



class DiplomacyEventManager:
	def __init__(self, eventManager):
		eventManager.addEventHandler("GameStart", self.onGameStart)
		eventManager.addEventHandler("OnLoad", self.onLoadGame)
		eventManager.addEventHandler("GameStart", self.onGameStart)
		eventManager.addEventHandler("BeginGameTurn", self.onBeginGameTurn)
		eventManager.addEventHandler("cityRazed", self.onCityRazed)
		eventManager.addEventHandler("cityDoTurn", self.onCityDoTurn)

		###circus hagenbeck start part 1
                self.oldcity = [-1,-1]
                ###circus hagenbeck end part 1        
		
		# Next War tracks cities that have been razed
		self.iArcologyCityID = -1
		
	def onLoadGame(self, argsList):
		CvAdvisorUtils.resetNoLiberateCities()
# BUG - Next War Merge - start
		# convert old script data list to SdToolkit for old saves
		data = gc.getGame().getScriptData()
		if isinstance(data, list):
			CvUtil.pyPrint('converting script data: %s' % data)
			iNukes = list[0]
			gc.getGame().setScriptData("")
			SdToolkit.sdSetGlobal(SD_MOD_ID, SD_NUKES_ID, iNukes)
# BUG - Next War Merge - end
		return 0

	def onGameStart(self, argsList):
		'Called at the start of the game'

		self.initScriptData()
		
		### circus hagenbeck start part 2
	        if (gc.getGame().getGameTurnYear() <> gc.getDefineINT("START_YEAR")):
                        for iPlayer in range (gc.getMAX_PLAYERS()):
                                player = gc.getPlayer(iPlayer)
				if player.isAlive():
                                        numbuildings = player.countNumBuildings(gc.getInfoTypeForString("BUILDING_CIRCUS_HAGENBECK"))
                                        if numbuildings>0:
                                                for iCity in range(player.getNumCities()):
                                                        pCity = player.getCity(iCity)
                                                        if pCity.getNumBuilding(gc.getInfoTypeForString("BUILDING_CIRCUS_HAGENBECK"))>0:
                                                                self.oldcity = [iPlayer,iCity]
                                                                return
                ###circus hagenbeck end part 2          
		# Are we using the scenario file? If so, then show the backstory popup
		if (CyMap().plot(0,0).getScriptData() == "Scenario"):
			for iPlayer in range(gc.getMAX_PLAYERS()):
				player = gc.getPlayer(iPlayer)
				if (player.isAlive() and player.isHuman()):
					popupInfo = CyPopupInfo()
					popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_TEXT)
					szTitle = u"<font=4b>" + localText.getText("TXT_KEY_NEXT_WAR_BACKSTORY_TITLE", ()) + u"</font>"
					szBody = u"<font=3>" + localText.getText("TXT_KEY_NEXT_WAR_BACKSTORY_TEXT", ()) + u"</font>"
					popupInfo.setText(szTitle + u"\n\n" + szBody)
					popupInfo.addPopup(iPlayer)

		if gc.getGame().isPbem():
			for iPlayer in range(gc.getMAX_PLAYERS()):
				player = gc.getPlayer(iPlayer)
				if (player.isAlive() and player.isHuman()):
					popupInfo = CyPopupInfo()
					popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_DETAILS)
					popupInfo.setOption1(true)
					popupInfo.addPopup(iPlayer)
																	
		CvAdvisorUtils.resetNoLiberateCities()

	def onBeginGameTurn(self, argsList):
		'Called at the beginning of the end of each turn'
		iGameTurn = argsList[0]
###circus hagenbeck start part 3		
		if (CyGame().getTurnYear(iGameTurn)>=1890) and ( iGameTurn % 3 ==0 ):
                        counter = 0
                        while True:
                                counter = counter+1
                                if counter>=100:break
                                dice = gc.getGame().getMapRand()
                                iPlayer = dice.get(gc.getMAX_PLAYERS (), "Players")
                                pPlayer = gc.getPlayer(iPlayer)
                                if pPlayer.isNone():continue
                                if pPlayer.isAlive():
                                        iCity = dice.get(pPlayer.getNumCities () , "Cities" )
                                        pCity = pPlayer.getCity(iCity)
                                        if pCity.isNone():continue
                                        pCity.setNumRealBuilding(gc.getInfoTypeForString("BUILDING_CIRCUSHAGENBECK"),1)
                                        CyInterface().addMessage(iPlayer,false,20,CyTranslator().getText("TXT_KEY_CIRCUS_MOVED",(pCity.getName (),pCity.getName ())),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(gc.getInfoTypeForString("COLOR_GREEN")), pCity.getX(), pCity.getY(), True,True) 
                                        if self.oldcity <>[-1,-1]:
                                                otherplayer = gc.getPlayer(self.oldcity[0])
                                                othercity = otherplayer.getCity(self.oldcity[1])
                                                if not othercity.isNone():
                                                        othercity.setNumRealBuilding(gc.getInfoTypeForString("BUILDING_CIRCUSHAGENBECK"),0)
                                                        CyInterface().addMessage(self.oldcity[0],false,20,CyTranslator().getText("TXT_KEY_CIRCUS_LOST",(othercity.getName (),othercity.getName ())),'',0,'Art/Interface/Buttons/General/warning_popup.dds',ColorTypes(gc.getInfoTypeForString("COLOR_RED")), othercity.getX(), othercity.getY(), True,True)
                                        self.oldcity = [iPlayer,iCity]                                 
                                        
                                        break
###circus hagenbeck end part 3         
		
	def onCityRazed(self, argsList):
		'City Razed'
		city, iPlayer = argsList
		iOwner = city.findHighestCulture()

		# Partisans!
		if city.getPopulation > 1 and iOwner != -1 and iPlayer != -1:
			owner = gc.getPlayer(iOwner)
			if not owner.isBarbarian() and owner.getNumCities() > 0:
				if gc.getTeam(owner.getTeam()).isAtWar(gc.getPlayer(iPlayer).getTeam()):
					if gc.getNumEventTriggerInfos() > 0: # prevents mods that don't have events from getting an error
						iEvent = CvUtil.findInfoTypeNum(gc.getEventTriggerInfo, gc.getNumEventTriggerInfos(),'EVENTTRIGGER_PARTISANS')
						if iEvent != -1 and gc.getGame().isEventActive(iEvent) and owner.getEventTriggerWeight(iEvent) < 0:
							triggerData = owner.initTriggeredData(iEvent, true, -1, city.getX(), city.getY(), iPlayer, city.getID(), -1, -1, -1, -1)
			
		#Raze the Arcology
		owner = PyPlayer(city.getOwner())
		razor = PyPlayer(iPlayer)
		
		self.iArcologyCityID = -1
		
		if city.getNumRealBuilding(gc.getInfoTypeForString("BUILDING_ARCOLOGY")) or city.getNumRealBuilding(gc.getInfoTypeForString("BUILDING_ARCOLOGY_SHIELDING")) or city.getNumRealBuilding(gc.getInfoTypeForString("BUILDING_DEFLECTOR_SHIELDING")):
			self.iArcologyCityID = city.getID()
	
	def onCityDoTurn(self, argsList):
		'City Production'
		pCity = argsList[0]
		iPlayer = argsList[1]
        
# no anger defying UN resolutions start #
		iGovernmentCivicOption = CvUtil.findInfoTypeNum(gc.getCivicOptionInfo,gc.getNumCivicOptionInfos(),'CIVICOPTION_GOVERNMENT')
		iPoliceState = CvUtil.findInfoTypeNum(gc.getCivicInfo,gc.getNumCivicInfos(),'CIVIC_POLICE_STATE')
		pPlayer = gc.getPlayer(iPlayer)
		iGovernmentCivic = pPlayer.getCivics(iGovernmentCivicOption)

		if (iGovernmentCivic == iPoliceState):
			pCity.changeDefyResolutionAngerTimer(pCity.getDefyResolutionAngerTimer())
# no anger defying UN resolutions end #        

####### Next War Functions ######
## Added Fort to doCheckDepletion -- otherwise bonuses worked via forts would never be subject to resource depletion.   JKP


	def doCheckDepletion(self):
		self.doCheckWorkedResource("BONUS_ALUMINUM", "IMPROVEMENT_MINE", 880)
		self.doCheckWorkedResource("BONUS_ALUMINUM", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_BANANA", "IMPROVEMENT_PLANTATION", 1120)
		self.doCheckWorkedResource("BONUS_BANANA", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_CLAM", "IMPROVEMENT_FISHING_BOATS", 880)
		self.doCheckWorkedResource("BONUS_COAL", "IMPROVEMENT_MINE", 880)
		self.doCheckWorkedResource("BONUS_COAL", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_COPPER", "IMPROVEMENT_MINE", 880)
		self.doCheckWorkedResource("BONUS_COPPER", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_CORN", "IMPROVEMENT_FARM", 1120)
		self.doCheckWorkedResource("BONUS_CORN", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_COW", "IMPROVEMENT_PASTURE", 1120)
		self.doCheckWorkedResource("BONUS_COW", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_CRAB", "IMPROVEMENT_FISHING_BOATS", 1120)
		self.doCheckWorkedResource("BONUS_DEER", "IMPROVEMENT_CAMP", 780)
		self.doCheckWorkedResource("BONUS_DEER", "IMPROVEMENT_FORT", 780)
		self.doCheckWorkedResource("BONUS_DYE", "IMPROVEMENT_PLANTATION", 1120)
		self.doCheckWorkedResource("BONUS_DYE", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_FISH", "IMPROVEMENT_FISHING_BOATS", 880)
		self.doCheckWorkedResource("BONUS_FUR", "IMPROVEMENT_CAMP", 560)
		self.doCheckWorkedResource("BONUS_FUR", "IMPROVEMENT_FORT", 560)
		self.doCheckWorkedResource("BONUS_GEMS", "IMPROVEMENT_MINE", 1120)
		self.doCheckWorkedResource("BONUS_GEMS", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_GOLD", "IMPROVEMENT_MINE", 880)
		self.doCheckWorkedResource("BONUS_GOLD", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_HORSE", "IMPROVEMENT_PASTURE", 1120)
		self.doCheckWorkedResource("BONUS_HORSE", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_IRON", "IMPROVEMENT_MINE", 880)
		self.doCheckWorkedResource("BONUS_IRON", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_IVORY", "IMPROVEMENT_CAMP", 560)
		self.doCheckWorkedResource("BONUS_IVORY", "IMPROVEMENT_FORT", 560)
		self.doCheckWorkedResource("BONUS_MARBLE", "IMPROVEMENT_QUARRY", 750)
		self.doCheckWorkedResource("BONUS_MARBLE", "IMPROVEMENT_FORT", 750)
		self.doCheckWorkedResource("BONUS_OIL", "IMPROVEMENT_WELL", 880)
		self.doCheckWorkedResource("BONUS_OIL", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_OIL", "IMPROVEMENT_OFFSHORE_PLATFORM", 880)
		self.doCheckWorkedResource("BONUS_PIG", "IMPROVEMENT_PASTURE", 1120)
		self.doCheckWorkedResource("BONUS_PIG", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_RICE", "IMPROVEMENT_FARM", 1120)
		self.doCheckWorkedResource("BONUS_RICE", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_SILK", "IMPROVEMENT_PLANTATION", 1120)
		self.doCheckWorkedResource("BONUS_SILK", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_SILVER", "IMPROVEMENT_MINE", 880)
		self.doCheckWorkedResource("BONUS_SILVER", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_SPICES", "IMPROVEMENT_PLANTATION", 1120)
		self.doCheckWorkedResource("BONUS_SPICES", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_STONE", "IMPROVEMENT_QUARRY", 750)
		self.doCheckWorkedResource("BONUS_STONE", "IMPROVEMENT_FORT", 750)
		self.doCheckWorkedResource("BONUS_SUGAR", "IMPROVEMENT_PLANTATION", 1120)
		self.doCheckWorkedResource("BONUS_SUGAR", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_URANIUM", "IMPROVEMENT_MINE", 880)
		self.doCheckWorkedResource("BONUS_URANIUM", "IMPROVEMENT_FORT", 880)
		self.doCheckWorkedResource("BONUS_WHALE", "IMPROVEMENT_WHALING_BOATS", 560)
		self.doCheckWorkedResource("BONUS_WHEAT", "IMPROVEMENT_FARM", 1120)
		self.doCheckWorkedResource("BONUS_WHEAT", "IMPROVEMENT_FORT", 1120)
		self.doCheckWorkedResource("BONUS_WINE", "IMPROVEMENT_WINERY", 1120)
		self.doCheckWorkedResource("BONUS_WINE", "IMPROVEMENT_FORT", 1120)

	def doCheckWorkedResource(self, bonus, improvement, randomInt):
            
		iBonus = CvUtil.findInfoTypeNum(gc.getBonusInfo, gc.getNumBonusInfos(), bonus)
        
		if (iBonus == -1):
			return
        
		lValidPlots = self.getPlotListbyBonus(iBonus)
        
		if len(lValidPlots) == 0:
			return
                
##If you have the requisite improvement (incl. fort) or if the plot is being worked by a City, continue.
                        
			for plot in lValidPlots:
				P = False
                
				if plot.getImprovementType() == CvUtil.findInfoTypeNum(gc.getImprovementInfo, gc.getNumImprovementInfos(), improvement):
					P = True
				elif plot.isCity():
					P = True

				if P == True:
					if self.getRandomNumber(randomInt) == 0:
                    
						pBonusInfo = gc.getBonusInfo(iBonus)
                    
						plot.setBonusType(-1)
                    
						szTitle = localText.getText("TEXT_KEY_NEXT_WAR_RESOURCE_DEPLETED_TITLE", ())# (pBonusInfo.getDescription(), plotgetX(), plot.getY()))
                        #szText = localText.getText("TEXT_KEY_NEXT_WAR_RESOURCE_DEPLETED", (pBonusInfo.getDescription(), plot.getX(), plot.getY()))
                        #Not sure what the above commented out code for (debugging?) -- it was commented out in PM's original NextWar code.  JKP1187
                        
						CyInterface().addMessage(plot.getOwner(), False, gc.getEVENT_MESSAGE_TIME(), szTitle, "AS2D_DISCOVERBONUS", InterfaceMessageTypes.MESSAGE_TYPE_MINOR_EVENT, pBonusInfo.getButton(), gc.getInfoTypeForString("COLOR_GREEN"), plot.getX(), plot.getY(), True, True)		
				else:
					return
				

### Below are additional functions necessary to the activity of the resource depl'n code:

	def getPlotListbyBonus(self, iBonus):
		lPlots = []
		totalPlots = gc.getMap().numPlots()
		
		for i in range(totalPlots):
			plot = gc.getMap().plotByIndex(i)
			iOwner = plot.getOwner()
			if (iOwner != -1):
				if plot.getBonusType(gc.getPlayer(iOwner).getTeam()) == iBonus:
					lPlots.append(plot)
		return lPlots

	def getRandomNumber(self, int):
		return gc.getGame().getSorenRandNum(int, "Next War")


# BUG - Next War Merge - start
	def initScriptData(self):
		
		# Set default script data manually since we need defaults for all values in the array before any functions can be called on them
		iDefaultNumNukesFired = 0
		SdToolkit.sdSetGlobal(SD_MOD_ID, SD_NUKES_ID, iDefaultNumNukesFired)
		
	def getGameNumNukes(self):
		return SdToolkit.sdGetGlobal(SD_MOD_ID, SD_NUKES_ID)

	def setGameNumNukes(self, iValue):
		SdToolkit.sdSetGlobal(SD_MOD_ID, SD_NUKES_ID, iValue)
		self.checkNukeStuff(iValue)
		
	def changeGameNumNukes(self, iChange):
		self.setGameNumNukes(self.getGameNumNukes() + iChange)
# BUG - Next War Merge - end

Thanks for helping me by the way guys, I feel like I'm really being annoying to you but I also feel like I'm really close to getting this thing right. :goodjob:
 
Back
Top Bottom