[PYTHON] Merging GreatDoctor mod with Bug

Nonsense. You, The_J, and EF might be best at Python here.

Thanks, but in fact i'm a horrible coder, you just can't really see it here.
And you forgot Xienwolf, jdog and some of the others which do not regularly look in here.


But back to the problem:

PHP:
Traceback (most recent call last):
  File "BugGameUtils", line 342, in callHandler
  File "BugGameUtils", line 297, in <lambda>
  File "DestinyCvGameUtils", line 564, in canPickPlot
AttributeError: 'module' object has no attribute 'lPlagueCities'

the line 564 returns true for the call if pGodsOfOld.isPlagueCity. pGodsOfOld = GreatDoctorEventManager, and GreatDoctorEventManager.py has only one class GreatDoctorEventManager, so this assignment should be enough to be able to call the function, right?
But somehow this does not work, because else it would not return true, right?
Because the error can't be in isPlagueCity:
PHP:
	def isPlagueCity(self, iX, iY):
		iCoords = ( iX, iY )
		return self.lPlagueCities.count( iCoords ) == 0

EEEEdit: Should it not be pGodsOfOld = GreatDoctorEventManager()?
Because else the constructor is not called and the mentioned variables in the error are not initialized.
crap, i do not have enough experience here.


The other error:
PHP:
Traceback (most recent call last):

  File "CvScreensInterface", line 969, in forceScreenUpdate

  File "CvMainInterface", line 1313, in updateScreen

AttributeError: 'module' object has no attribute 'getPlagueCities'
ERR: Python function forceScreenUpdate failed, module CvScreensInterface

1313 is pGodsOfOld.doPlagueEffect(), same definition as above.
The function itself is:
PHP:
	def doPlagueEffect(self):
		for iCoords in self.lPlagueCities:
			city = gc.getMap( ).plot( iCoords[0], iCoords[1] ).getPlotCity( )
			cityPlotPoint = city.plot( ).getPoint( )
			plagueEffect = gc.getInfoTypeForString("EFFECT_GODS_PLAGUE")
			CyEngine().triggerEffect( plagueEffect, cityPlotPoint )

The problematic function getPlagueCities is nowhere called in there, right?


Something is here really messed up.
 
EEEEdit: Should it not be pGodsOfOld = GreatDoctorEventManager()?
Because else the constructor is not called and the mentioned variables in the error are not initialized.
Yeah, that would be the way to initialize the actual GreatDoctorEventManager instance. Otherwise the pGodsOfOld variable is merely pointing to a class, not an instance of that class.
Spoiler :
I originally figured this out looking at how the PyHelpers class PyPlayer is sometimes assigned to a constant (like pyPlayer) as:
Code:
pyPlayer = PyHelpers.PyPlayer
Because then it is possible to add the parenthesis with the actual ePlayer as an argument to the variable. Like:
Code:
pyPlayer(0).getCities()
If the assignment statement would look like this:
Code:
pyPlayer = PyHelpers.PyPlayer()
Then it wouldn't be valid as the PyPlayer class constructor takes two arguments (self and a ePlayer value).

This is probably the most common one, however:
Code:
cg = CyGlobalContext()
So the module will hold a CyGlobalContext object in that constant for the entire game session. If the constructor was used every time the class was used these would be a whole lot of those objects floating around:
Code:
CyGlobalContext().getGame().getGameTurn()
It gets a bit confusing with CyGame() though:
Code:
game = CyGame()
Because then you create a new game object for that module? :confused: The answer is likely that any CyGame object is merely a reference to the real game object created in the C++ code. Just as CyPlayer and CyTeam instances are references to C++ objects.

One thing I haven't figured out yet though is whether or not these two are exactly the same:
Code:
game = gc.getGame()
and
Code:
game = CyGame()
The first one is returning a CyGame instance, but is it created first? The second one definitely creates a CyGame object, but that's just a reference in-itself, right? What is a CyGame object, really?

And the same goes for CyMap objects. There is only one map per game, right? Are all objects created with the CyMap() constructor identical pointers to some C++ object? Are actual objects even being created?
 
A bit arrogant? I thought about a warning...

The GreatDoctorEventManager is imported into DestinyCvGameUtils and the assignment looks right for me :dunno:.

Nothing has changed from the first post, there is no error until you click on the plague button, the pointer changes to the "plot picker" then once you mouse over a city, the exception pops up ( see the first post complete code).

Everything works as it should, the city gets unhealthiness, the effect plays and a message pops up but still get the error from the first post.
 
Nothing has changed from the first post, there is no error until you click on the plague button, the pointer changes to the "plot picker" then once you mouse over a city, the exception pops up ( see the first post complete code).

Everything works as it should, the city gets unhealthiness, the effect plays and a message pops up but still get the error from the first post.
Aha, this happens in-game... When you mouse-over a city the code will look for the plague city list, which is nowhere to be found... (Why this is would be anyones guess.)

Perhaps the code looking for the city list could be removed entirely? Because you say the functionality is fine - despite the exception, to boot.

Try commenting out something that references the self.lPlagueCities (or whatever) and you should at least get rid of the exception. There might be some odd reason to get this code back in though, but if it achieves nothing you would have lost nothing.

Unfortunately I don't know exactly what the plague feature does, so I'm afraid I'm not being too helpful. :rolleyes:
 
The definition code isn't anything special, but could be wrong. It was made this way after talking to Afforess.
Code:
pGodsOfOld=GreatDoctorEventManager

originally in the non-bug merged code it was this:
Code:
pGodsOfOld=CvEventInterface.getEventManager()
Now I'm thinking that the original line achieves something that the new one doesn't. The original assignment fetches a event manager instance without creating one (through the getEventManager() method). The suggested new one is merely a reference to a... module? Or perhaps a class in that module (depending on how the import statement looks like)?

pGodsOfOld probably needs to be a reference to the original GreatDoctorEventManager instance - probably created in CvEventManager.py or something. That would have to be passed along to the DestinyCvEventManager constructor as an argument, then set-up as a global variable:
Code:
class DestinyCvEventManager:
    def __init__(self, [COLOR="Red"]pObject[/COLOR]):
        [COLOR="Red"]global pGodsOfOld
        pGodsOfOld = pObject[/COLOR]
The instance could probably work as a field of the DestinyCvEventManager class also:
Code:
class DestinyCvEventManager:
    def __init__(self, [COLOR="Red"]pObject[/COLOR]):
        [COLOR="Red"]self.pGodsOfOld = pObject[/COLOR]
Then every "pGodsOfOld" would have to be changed to "self.pGodsOfOld". (This is probably the proper way to do it however.)
 
Aha, this happens in-game... When you mouse-over a city the code will look for the plague city list, which is nowhere to be found... (Why this is would be anyones guess.)

Perhaps the code looking for the city list could be removed entirely? Because you say the functionality is fine - despite the exception, to boot.

Try commenting out something that references the self.lPlagueCities (or whatever) and you should at least get rid of the exception. There might be some odd reason to get this code back in though, but if it achieves nothing you would have lost nothing.

Unfortunately I don't know exactly what the plague feature does, so I'm afraid I'm not being too helpful. :rolleyes:

The plaguecities list contains a listing of cities that have the plague. This is pickled in and out so that it persists over save/load games and is a check so you can't re-plague a plagued city until it's plague effect has expired. Plagues have a timer before they wear off and can spread along trade routes.

The functionality is fine as far as affecting the one city at that point, but the tracking of it's persistance and "spreadability" feature would be lost if those lines were commented out. I'll do more tests extended features once this part no longer causes exceptions.
 
Now I'm thinking that the original line achieves something that the new one doesn't. The original assignment fetches a event manager instance without creating one (through the getEventManager() method). The suggested new one is merely a reference to a... module? Or perhaps a class in that module (depending on how the import statement looks like)?

pGodsOfOld probably needs to be a reference to the original GreatDoctorEventManager instance - probably created in CvEventManager.py or something. That would have to be passed along to the DestinyCvEventManager constructor as an argument, then set-up as a global variable:
Code:
class DestinyCvEventManager:
    def __init__(self, [COLOR="Red"]pObject[/COLOR]):
        [COLOR="Red"]global pGodsOfOld
        pGodsOfOld = pObject[/COLOR]
The instance could probably work as a field of the DestinyCvEventManager class also:
Code:
class DestinyCvEventManager:
    def __init__(self, [COLOR="Red"]pObject[/COLOR]):
        [COLOR="Red"]self.pGodsOfOld = pObject[/COLOR]
Then every "pGodsOfOld" would have to be changed to "self.pGodsOfOld". (This is probably the proper way to do it however.)

I've read your post, and I think you are on to something. If I was using only CVEventmanager, the code would work, as it does with the modcomp of thsi code that I already put together (link)

But I'm using BUG, so there's no modding CvEventManager.py, it's not possible because Bug doesn't reference it, it is replaced by BugEventmanager which is different.

This probably holds the answer
Code:
The original assignment fetches a event manager instance without creating one (through the getEventManager() method). The suggested new one is merely a reference to a... module? Or perhaps a class in that module (depending on how the import statement looks like)?

I'll dig through EF's Bug + Event tutorial to see what it says again to see if it says anything about using existing instances w/o creating new ones.
 
Wow, this thread got long quick. I don't have the time to read it all, so let me sum up.

Most of us have some combination of self- and school-learning. I find the combination to be most effective versus one or the other, but that's just a generalization. Some people can rip through a new language easily by scanning some sample code while others require more hand-holding. There's nothing wrong with either case; just make use of your skills (know what they are), and show some initiative. :)

That being said, I'm clearly the best at everything! My mom said so. :p

Knowing that you took some Java classes helps me tailor my advice. In Python "self" is equivalent to Java's "this": it is a reference to the object that received a method call.

Code:
class Foo:
    def __init__(self, name):
        self.name = name
    def greet(self):
        print "hi ", self.name

f = Foo("Bob")
f.greet()
> hi Bob

Here you can see that "self" is declared as the first parameter to every method in the class. This is convention--you can call it whatever you want but you'll confuse people. The key is that when you write "f.greet()", "f" is assigned to "self" inside the "greet()" method. This is automatic in Python--the object that receives the method call is passed as the first argument to the method.

Note above that you cannot call "greet()" by itself; you must put a reference to a Foo object before it, e.g. "f.". In the same way you cannot call getPlagueCities() without an instance of the GreatDoctorEventManager (or whatever it was called) class. There's a very simple way to expose this to other modules:

Code:
# GreatDoctorEventManager

[B]eventMgr = None[/B]

...

class GreatDoctorEventManager:
    def __init__(self, bugEventMgr):
        [B]global eventMgr[/B]
        [B]eventMgr = self[/B]
        ...
    def getPlagueCities(self, ...):
        ...

Now you can call from GreatDoctorGameUtils.py like this:

Code:
# GreatDoctorGameUtils

import GreatDoctorEventManager

...

lPlagueCities = GreatDoctorEventManager.eventMgr.getPlagueCities()

This works because BUG will create only one GreatDoctorEventManager, and it assigns itself to GreatDoctorEventManager.eventMgr when it's created.
 
One question: Will a global value also be valid in other modules?
Spoiler :
Because I was trying to redesign the RFC mod and take out all the pickling (well not on save/load game) a while ago and realized I couldn't make all class instances available in all modules. Whatever I did there would always be yet another modules that wasn't getting the values it requested (since I took out the pickled scriptDict). And since everything wasn't even connected to the event manager (like interface and advisor modules) I deemed it impossible.
 
Global variables and functions in one module are available to any other module that imports it by placing the module's name in front.

Code:
[B]# Foo.py[/B]

x = 5


[B]# Bar.py[/B]

print x  # error, x does not exist in Bar

import Foo
print x  # error, x does not exist in Bar

print Foo.x  # success!
> 5
 
Global variables and functions in one module are available to any other module that imports it by placing the module's name in front.
Yeah, I think this was the limitation I wasn't able to overcome.
 
Wow, this thread got long quick. I don't have the time to read it all, so let me sum up.

Most of us have some combination of self- and school-learning. I find the combination to be most effective versus one or the other, but that's just a generalization. Some people can rip through a new language easily by scanning some sample code while others require more hand-holding. There's nothing wrong with either case; just make use of your skills (know what they are), and show some initiative. :)

That being said, I'm clearly the best at everything! My mom said so. :p
Spoiler :

Knowing that you took some Java classes helps me tailor my advice. In Python "self" is equivalent to Java's "this": it is a reference to the object that received a method call.

Code:
class Foo:
    def __init__(self, name):
        self.name = name
    def greet(self):
        print "hi ", self.name

f = Foo("Bob")
f.greet()
> hi Bob

Here you can see that "self" is declared as the first parameter to every method in the class. This is convention--you can call it whatever you want but you'll confuse people. The key is that when you write "f.greet()", "f" is assigned to "self" inside the "greet()" method. This is automatic in Python--the object that receives the method call is passed as the first argument to the method.

Note above that you cannot call "greet()" by itself; you must put a reference to a Foo object before it, e.g. "f.". In the same way you cannot call getPlagueCities() without an instance of the GreatDoctorEventManager (or whatever it was called) class. There's a very simple way to expose this to other modules:

Code:
# GreatDoctorEventManager

[B]eventMgr = None[/B]

...

class GreatDoctorEventManager:
    def __init__(self, bugEventMgr):
        [B]global eventMgr[/B]
        [B]eventMgr = self[/B]
        ...
    def getPlagueCities(self, ...):
        ...

Now you can call from GreatDoctorGameUtils.py like this:

Code:
# GreatDoctorGameUtils

import GreatDoctorEventManager

...

lPlagueCities = GreatDoctorEventManager.eventMgr.getPlagueCities()

This works because BUG will create only one GreatDoctorEventManager, and it assigns itself to GreatDoctorEventManager.eventMgr when it's created.

Well, I've been working at this still for the past couple days and I'm at another stopping point. The code is fine without BUG, I'm just trying to modify it to work with my main mod which has BUG and Revdcm.

I'll post where I'm stuck here in a sec once I've dug through the code and sorted where I'm at at this point.

Ok..

I've modified the code to skip the whole plot picker function to make it more like the Great Spy where the action button just shows up when you are on a valid plot. This isn't 100% (button is always there) but I am confident I can do that when the time comes. I'm still troubleshooting the action and effects.

So currently, it works.. Sorta. I can take my great doctor to a city, press the button and the text will show up and the effect will be applied - some reason the Effect does not play as it should but there are no exceptions until I end the turn to see how the plague spread, plague decay functions work.

This must have something to do with how Bug is loading my eventmanager and comes from this code:
Code:
	def onBeginGameTurn(self, argsList):
		'Called at the beginning of the end of each turn'
		iGameTurn = argsList[0]
		#CvTopCivs.CvTopCivs().turnChecker(iGameTurn)
		###########  Great Doctor Mod by Tsentom1 updated by Smeagolheart Start  ###########  						
		#Plague
		if gc.getMap().plotByIndex(0).getScriptData() == "Plague On":
			self.doPlagueSpread()
		else:
			self.doPlagueDecay()
		###########  Great Doctor Mod by Tsentom1 updated by Smeagolheart End  ##########

This causes an exception
Code:
Traceback (most recent call last):
  File "BugEventManager", line 361, in _handleDefaultEvent
  File "DynamicCivNames", line 95, in onBeginPlayerTurn
  File "SdToolKitCustom", line 292, in sdObjectExists
AttributeError: 'list' object has no attribute 'has_key'

I tried switching out the code to modify GameTurn and PlayerTurn because the error mentions PlayerTurn but either way the exception is the same.

If I comment out the code and skip it entirely, there is no exception! It seems to me that maybe it's not reading the scriptdata correctly?
 
Your error traceback goes through DynamicCivNames, and that is not the file you are modifying. It is curious that this error goes away when you comment out your onBeginGameTurn. When you comment it out, are you commenting out the entire function, or are you leaving the function there with an empty body? If you are commenting out the entire function, are you also removing the line which registers your function for bug? If you are not removing this line, then I bet when bug fails to find your function, it also fails to call other similar registered functions. This is only a guess.

I am not an expert on pickle, but I believe that the sdtoolkit function shown in your traceback is related to pickle and layers on top of it. One possibility may be to switch off dynamic civ names in the bug options panel. That is a workaround, but at least it would let you keep going.

In general when merging complex mods written by other people, I have found that they have unexpected internal dependencies. It may be hard for a third author to sort out the dependencies between two other authors' code. It may be painful, but I find it is a good learning experience.

EDIT: in the area of unexpected dependencies, it occurs to me that "hiding" information in plot (0,0) may be a common trick. It is possible that two mods may conflict over this data, which could also explain why you see no error when your code is commented out. Try finding all places in your mod which use plotByIndex(0).getScriptData, and change the 0 to 1. If that works, then at least you know what is causing the conflict.
 
Your error traceback goes through DynamicCivNames, and that is not the file you are modifying. It is curious that this error goes away when you comment out your onBeginGameTurn. When you comment it out, are you commenting out the entire function, or are you leaving the function there with an empty body? If you are commenting out the entire function, are you also removing the line which registers your function for bug? If you are not removing this line, then I bet when bug fails to find your function, it also fails to call other similar registered functions. This is only a guess.
I'm thinking that two separate mods are using sdToolkit but they aren't working together. Because that would be the whole point of using it in the first place (unless you get it bundled with BUG, of course).

EDIT: in the area of unexpected dependencies, it occurs to me that "hiding" information in plot (0,0) may be a common trick. It is possible that two mods may conflict over this data, which could also explain why you see no error when your code is commented out. Try finding all places in your mod which use plotByIndex(0).getScriptData, and change the 0 to 1. If that works, then at least you know what is causing the conflict.
Yeah, that would be a clear conflict. I think the best way forward would be to read up on sdToolkit and convert all pickled scriptData to one single dictionary stored in the CyGame instance. No reason to hide one bit of data in the game object, another in a player object and yet a third in a plot object.

Regarding the actual plot you could also be on the lookout for this bit of code:
Code:
plot(0, 0)
as that equals to using
Code:
plotByIndex(0)
or so I would think.
 
Yes I comment out the whole thing and it is fine, no exceptions.

So this is just checking plot(0, 0) for some data? At first I thought it was checking actual plots for whether it had plaguedata set or not. Makes sense.

Here's the code from dynamiccivnames it's reporting an error on. I don't see any scriptdata there on a plot?
Spoiler :

Code:
	def onBeginPlayerTurn( self, argsList ) :
		iGameTurn, iPlayer = argsList

		# Stuff at end of previous players turn
		iPrevPlayer = iPlayer - 1
		while( iPrevPlayer >= 0 and not gc.getPlayer(iPrevPlayer).isAlive() ) :
				iPrevPlayer -= 1

		if( iPrevPlayer < 0 ) :
			iPrevPlayer = gc.getBARBARIAN_PLAYER()

		if( iPrevPlayer >= 0 and iPrevPlayer < gc.getBARBARIAN_PLAYER() ) :
			iPlayer = iPrevPlayer
			pPlayer = gc.getPlayer( iPlayer )
### ERROR IS FROM THE NEXT LINE### 
			if( pPlayer.isAlive() and SDTK.sdObjectExists( "Revolution", pPlayer ) ) :  
				#CvUtil.pyPrint("  Name - Object exists %d"%(iPlayer))
				prevCivics = SDTK.sdObjectGetVal( "Revolution", pPlayer, 'CivicList' )
				if( not prevCivics == None ) :
					for i in range(0,gc.getNumCivicOptionInfos()):
						if( not prevCivics[i] == pPlayer.getCivics(i) ) :
							self.setNewNameByCivics(iPlayer)
							return
							
				revTurn = SDTK.sdObjectGetVal( "Revolution", pPlayer, 'RevolutionTurn' )
				if( not revTurn == None and game.getGameTurn() - revTurn == 30 and pPlayer.getNumCities() > 0 ) :
					# "Graduate" from rebel name
					self.setNewNameByCivics(iPlayer)
					return
					
			if( pPlayer.isAlive() and SDTK.sdObjectExists( "BarbarianCiv", pPlayer ) ) :
				barbTurn = SDTK.sdObjectGetVal( "BarbarianCiv", pPlayer, 'SpawnTurn' )
				if( not barbTurn == None and game.getGameTurn() - barbTurn == 30 ) :
					# "Graduate" from barb civ name
					self.setNewNameByCivics(iPlayer)
					return
			
			if( pPlayer.isAlive() and not SDTK.sdObjectExists( "BarbarianCiv", pPlayer )) :
				if( 'Tribe' in pPlayer.getCivilizationDescription(0) ) :
					if( pPlayer.getCurrentEra() > 0 or pPlayer.getTotalPopulation() >= 3 ) :
						# Graduate from game start name
						CvUtil.pyPrint("  Name - Graduating from game start name Player %d"%(iPlayer))
						self.setNewNameByCivics(iPlayer)
						return


Here's DoEventPlague
Spoiler :

Code:
	def doEventPlague( self, targetPlot ):
		plotX = targetPlot.getX()
		plotY = targetPlot.getY()
		city = gc.getMap( ).plot( plotX, plotY ).getPlotCity()
		szCityName = city.getName()		
		iPlagueEffect = CvUtil.findInfoTypeNum( gc.getEffectInfo, gc.getNumEffectInfos( ), "EFFECT_GODS_PLAGUE" )
		iCoords = ( plotX, plotY )

		self.lPlagueCities.append( iCoords )
		self.doPlagueEffect( city )
		plot = city.plot()
		szTitle = localText.getText("TXT_KEY_GODS_PLAGUE_START", ( szCityName, ))
		CyInterface().addMessage(plot.getOwner(), True, gc.getEVENT_MESSAGE_TIME(), szTitle, "AS2D_PLAGUE", InterfaceMessageTypes.MESSAGE_TYPE_INFO, gc.getEffectInfo(iPlagueEffect).getButton(), gc.getInfoTypeForString("COLOR_RED"), plot.getX(), plot.getY(), True, True)	
		#plot 5 is Plague
		gc.getMap().plotByIndex(0).setScriptData("Plague On")
		#plot 6 is Black Death Counter
		gc.getMap().plotByIndex(1).setScriptData("10")

The comments say plotByIndex(0) is equal to plot 5. Okay.

Plots are reviewed here
Spoiler :

Code:
	def doPlagueSpread(self):
		iPlagueEffect = CvUtil.findInfoTypeNum( gc.getEffectInfo, gc.getNumEffectInfos( ), "EFFECT_GODS_PLAGUE" )

		#counts down turns remaining of plague
		if gc.getMap().plotByIndex(1).getScriptData() == "10":
			gc.getMap().plotByIndex(1).setScriptData("9")
		elif gc.getMap().plotByIndex(1).getScriptData() == "9":
			gc.getMap().plotByIndex(1).setScriptData("8")			
		elif gc.getMap().plotByIndex(1).getScriptData() == "8":
			gc.getMap().plotByIndex(1).setScriptData("7")
		elif gc.getMap().plotByIndex(1).getScriptData() == "7":
			gc.getMap().plotByIndex(1).setScriptData("6")
		elif gc.getMap().plotByIndex(1).getScriptData() == "6":
			gc.getMap().plotByIndex(1).setScriptData("5")
		elif gc.getMap().plotByIndex(1).getScriptData() == "5":
			gc.getMap().plotByIndex(1).setScriptData("4")
		elif gc.getMap().plotByIndex(1).getScriptData() == "4":
			gc.getMap().plotByIndex(1).setScriptData("3")
		elif gc.getMap().plotByIndex(1).getScriptData() == "3":
			gc.getMap().plotByIndex(1).setScriptData("2")
		elif gc.getMap().plotByIndex(1).getScriptData() == "2":
			gc.getMap().plotByIndex(1).setScriptData("1")
		else:
			gc.getMap().plotByIndex(0).setScriptData("")
		
		lPlayers = PyGame().getCivPlayerList()
		lValidCities = []
... moar stuff but not about the plots

So from this one it looks like it counts down on a plot, then removes the "flag" on plotByIndex(0) (no more plaguespread)


Another odd thing is I can load my testgame, there are no plague instances and I end the turn and then get the exception from dynamiccivnames. That means to me that, well it's not even involving the plaguespread and doEventPlague functions. Hmm..
 
Could you perhaps also mark the lines (like with color) that are causing the exception?

My take on this is that you have several different approaches for storing scriptData going on here simultaneously. I guess this will happen when merging stuff, and it could ultimately cause your merge to fail. Unless you know how to read and rewrite the code. (The best way for a BUG mod would probably to work everything into a sdToolkit setup, since it is designed to compartmentalize data from different mods. Its just the overlay that has to be the same universally. Think of it as data structures inside other data structures. And each mod would have its own compartment or data structure under the superstructure.)

Like when the code is referring to sdObjectExists - I think that is a part of the sdToolkit and thus very much involved with pickling and storing scriptData! Why it is happening in another module altogether is probably because of a conflict of some sort. The Great Doctor (or other) mod has replaced some other pre-existing... thing.

But these different ways of storing data could also be a good thing. Because then you don't need to make them work together at all - just make sure they don't conflict with each-other. And by that I mean that they can't share scriptData fields in objects. (Unless, of course, everything is reworked into sdToolkit and the whole thing is stored in the game object.)

As to what causes your most recent exceptions - i simply wouldn't know... :(

I'm sorry if this is somewhat vague, but it is very complex stuff you're dealing with here. I will be very impressed if you actually manage to get it all to work together in a coherent fashion.
 
Yes, the problem is DynamicCivNames and your mod are both trying to use the same object's script data in a different way. You should switch your mod to use SdToolkit (which comes with BUG) or BugData. Either will work since I rewrote SdToolkit to use BugData which I wrote to try to create a simpler interface to using script data.

BUG has several examples of using BugData like ReminderEventManager, UnitNamingEventManager, CvStrategyOverlay. Just search for BugData.

We can help if you can lay out exactly what you need store. I see "Plague On" and "10". What do these mean? What other values are you storing? I think you store a list of cities on each player as well, correct?
 
For this merge, I think I've seen data stored in at least three different ways:
  • A pickled list with values stored in CyPlayer instance #0.
  • Individual string values stored in different CyPlot instances.
  • Using sdToolkit.
I think we have quite a mess in our hands... How many mods are merged together here?
 
For this merge, I think I've seen data stored in at least three different ways:
  • A pickled list with values stored in CyPlayer instance #0.
  • Individual string values stored in different CyPlot instances.
  • Using sdToolkit.
I think we have quite a mess in our hands... How many mods are merged together here?

Well, there are multiple ways to do the same thing right? But there are only two things being joined that are aren't working together at the moment, Revdcm adapted for BUG and GodsOfOld.

These two from GodsOfOld (incl. w/ BTS)
[*]A pickled list with values stored in CyPlayer instance #0.
[*]Individual string values stored in different CyPlot instances.

This from RevDCM on BUG
[*]sdToolkit.
 
Then these separate ways of storing data shouldn't be conflicting, as far as I can see...
 
Back
Top Bottom