Gerikes
User of Run-on Sentences.
I don't know if everyone is having this problem, or if it's been well known for awhile. I do know, however, that it really bugs me. At first I thought that it was just a glitch with how python reloading was handled and was out of our reach, but now I realize that it's just the fact that variables are being reset to 0. The problem has to do with some of main screen interface graphics not showing correctly after reloading python modules. The train unit buttons, for example, will no longer show up after I go through the process of reloading the python modules while the game is still running. Everything else, including the new code I made before saving the file, will work fine, but these and a few other buttons are missing. Edit: It appears that if you're in full-screen mode, a few alt-tabs will typically do the trick, eliminating the need for this fix. However, if you run windowed mode, or want to be able to have it load first-time through, then this might be useful.
The problem is with the CvMainInterface.py file. Since this screen is never "remade", the interfaceScreen function is only run once at the very beginning. This is the function that sets many of the global variables. For example, this function sets the global variable g_NumUnitClassInfos to the number of unit classes. This variable in initialized to zero at the top of the file.
When you reload the python files (by saving a python file and then alt-tabbing back to Civ4), the entire file is re-read by the python interpreter, which will in turn run all the commands that aren't part of a function. That includes resetting all of the global variables back to their defaults. So, this would explain why many things wouldn't show up, like unit-train buttons when a city is selected. This is because there is a for-loop that uses the global variable g_NumUnitClassInfos to check if different units are trainable.
Because this global variable is reset to zero whenever the python modules are reloaded, the loop will not loop through, and thus why units would not appear. Many items placement in the main interface depend on these global variables, which is why some items would show correctly, and others wouldn't.
In order to fix this, I added the following pieces of code. The idea is to add a global variable that defaults to "True". At the beginning of the updateScreen, it checks if the global variable is True. If so, it will reset the global variables will be reset using a new function. Then, the variable used to check for if a reload happened is set to False so we don't reload the global variables again until the next time the python file is reloaded.
First, near the top of the file, after the global variables are defined(or before, or during, just somewhere outside of a function) , I put:
Next, we need to check for whenever this is True.
Finally, we'll need to actually have the self.resetGlobals() function. I put this at the top, of course it doesn't matter where. It doesn't even need to be part of the class.
Hope this helps!
The problem is with the CvMainInterface.py file. Since this screen is never "remade", the interfaceScreen function is only run once at the very beginning. This is the function that sets many of the global variables. For example, this function sets the global variable g_NumUnitClassInfos to the number of unit classes. This variable in initialized to zero at the top of the file.
When you reload the python files (by saving a python file and then alt-tabbing back to Civ4), the entire file is re-read by the python interpreter, which will in turn run all the commands that aren't part of a function. That includes resetting all of the global variables back to their defaults. So, this would explain why many things wouldn't show up, like unit-train buttons when a city is selected. This is because there is a for-loop that uses the global variable g_NumUnitClassInfos to check if different units are trainable.
Code:
# Units to construct
for i in range ([b] g_NumUnitClassInfos [/b]):
eLoopUnit = gc.getCivilizationInfo(pHeadSelectedCity.getCivilizationType()).getCivilizationUnits(i)
if (pHeadSelectedCity.canTrain(eLoopUnit, False, True)):
screen.appendMultiListButton( "BottomButtonContainer", gc.getUnitInfo(eLoopUnit).getButton(), iRow, WidgetTypes.WIDGET_TRAIN, i, -1, False )
screen.show( "BottomButtonContainer" )
if ( not pHeadSelectedCity.canTrain(eLoopUnit, False, False) ):
screen.disableMultiListButton( "BottomButtonContainer", iRow, iCount, gc.getUnitInfo(eLoopUnit).getButton() )
iCount = iCount + 1
bFound = True
Because this global variable is reset to zero whenever the python modules are reloaded, the loop will not loop through, and thus why units would not appear. Many items placement in the main interface depend on these global variables, which is why some items would show correctly, and others wouldn't.
In order to fix this, I added the following pieces of code. The idea is to add a global variable that defaults to "True". At the beginning of the updateScreen, it checks if the global variable is True. If so, it will reset the global variables will be reset using a new function. Then, the variable used to check for if a reload happened is set to False so we don't reload the global variables again until the next time the python file is reloaded.
First, near the top of the file, after the global variables are defined(or before, or during, just somewhere outside of a function) , I put:
Code:
# Added by Gerikes for proper python reloading
g_bReset = True
# End Added by Gerikes for proper python reloading
Next, we need to check for whenever this is True.
Code:
# Will update the screen (every 250 MS)
def updateScreen(self):
[b]# Added by Gerikes to re-interface the screen if we've been reset
global g_bReset
if (g_bReset):
self.resetGlobals()
# End Added by Gerikes to re-interface the screen if we've been reset[/b]
Finally, we'll need to actually have the self.resetGlobals() function. I put this at the top, of course it doesn't matter where. It doesn't even need to be part of the class.
Code:
class CvMainInterface:
"Main Interface Screen"
[b]# Added by Gerikes to properly reset globals
def resetGlobals(self):
global g_bReset
g_bReset = False
global g_NumEmphasizeInfos
global g_NumCityTabTypes
global g_NumHurryInfos
global g_NumUnitClassInfos
global g_NumBuildingClassInfos
global g_NumProjectInfos
global g_NumProcessInfos
global g_NumActionInfos
g_NumEmphasizeInfos = gc.getNumEmphasizeInfos()
g_NumCityTabTypes = CityTabTypes.NUM_CITYTAB_TYPES
g_NumHurryInfos = gc.getNumHurryInfos()
g_NumUnitClassInfos = gc.getNumUnitClassInfos()
g_NumBuildingClassInfos = gc.getNumBuildingClassInfos()
g_NumProjectInfos = gc.getNumProjectInfos()
g_NumProcessInfos = gc.getNumProcessInfos()
g_NumActionInfos = gc.getNumActionInfos()
# End Added by Gerikes to properly reset globals[/b]
Hope this helps!