Problem with BUG 4.0 and CvGameUtils.py (after BUG Mod Update 3.6 -> 4.0)

Cybah

Emperor
Joined
Jun 22, 2007
Messages
1,481
Hi there! After upgrading BUG Mod from 3.6 to 4.0 (newest SVN) for my own mod, it seems that CvGameUtils.py is not loading anymore or there are problems with it.

Also, I dunno if I need to modify CvEventManager.py now with all of my custom additions?

As you can see on the screenshot, you can build all of the 4 processes. Normally you should only be able to build the 125% one after you have built a special wonder.






GameUtils Code:

Code:
	def canMaintain(self,argsList):
		pCity = argsList[0]
		eProcess = argsList[1]
		bContinue = argsList[2]

## Troyes Start ##

		pPlayer = gc.getPlayer(pCity.getOwner())

		b_Troyes = gc.getInfoTypeForString("BUILDING_TROYES")
		obsoleteTech = gc.getBuildingInfo(b_Troyes).getObsoleteTech()

		if ( eProcess == gc.getInfoTypeForString("PROCESS_WEALTH2") ) or ( eProcess == gc.getInfoTypeForString("PROCESS_CULTURE2") ):
			if ( gc.getTeam(pPlayer.getTeam()).isHasTech(obsoleteTech) == false or obsoleteTech == -1 ):
				for iCity in range(pPlayer.getNumCities()):
					ppCity = pPlayer.getCity(iCity)
					if ppCity.getNumActiveBuilding(b_Troyes) == true:
						return True

		b_Copernicus = gc.getInfoTypeForString("BUILDING_COPERNICUS")
		obsoleteTechC = gc.getBuildingInfo(b_Copernicus).getObsoleteTech()

		if eProcess == gc.getInfoTypeForString("PROCESS_RESEARCH2"):
			if ( gc.getTeam(pPlayer.getTeam()).isHasTech(obsoleteTechC) == false or obsoleteTechC == -1 ):
				for iCity in range(pPlayer.getNumCities()):
					ppCity = pPlayer.getCity(iCity)
					if ppCity.getNumActiveBuilding(b_Copernicus) == true:
						return True

## Troyes End ##

		return False

	def cannotMaintain(self,argsList):
		pCity = argsList[0]
		eProcess = argsList[1]
		bContinue = argsList[2]

		pPlayer = gc.getPlayer(pCity.getOwner())

		iTechCurrency = CvUtil.findInfoTypeNum(gc.getTechInfo,gc.getNumTechInfos(),'TECH_CURRENCY')
		if gc.getTeam(pPlayer.getTeam()).isHasTech(iTechCurrency):
			if eProcess == gc.getInfoTypeForString("PROCESS_WEALTH0"):
				return True

		if eProcess == gc.getInfoTypeForString("PROCESS_WEALTH0"):
			if gc.getTeam(pPlayer.getTeam()).isHasTech(iTechCurrency):
				return True

## Troyes Start ##

		pPlayer = gc.getPlayer(pCity.getOwner())

		b_Troyes = gc.getInfoTypeForString("BUILDING_TROYES")
		obsoleteTech = gc.getBuildingInfo(b_Troyes).getObsoleteTech()

		if ( gc.getTeam(pPlayer.getTeam()).isHasTech(obsoleteTech) == false or obsoleteTech == -1 ):
			for iCity in range(pPlayer.getNumCities()):
				ppCity = pPlayer.getCity(iCity)
				if ppCity.getNumActiveBuilding(b_Troyes) == true:
					if ( eProcess == gc.getInfoTypeForString("PROCESS_WEALTH") ) or ( eProcess == gc.getInfoTypeForString("PROCESS_CULTURE") ):
						return True


		if ( eProcess == gc.getInfoTypeForString("PROCESS_WEALTH2") ) or ( eProcess == gc.getInfoTypeForString("PROCESS_CULTURE2") ):
			if ( gc.getTeam(pPlayer.getTeam()).isHasTech(obsoleteTech) == false or obsoleteTech == -1 ):
				for iCity in range(pPlayer.getNumCities()):
					ppCity = pPlayer.getCity(iCity)
					if ppCity.getNumActiveBuilding(b_Troyes) == false:
						return true
			if ( gc.getTeam(pPlayer.getTeam()).isHasTech(obsoleteTech) == true or obsoleteTech == 1 ):
				return True

			
		b_Copernicus = gc.getInfoTypeForString("BUILDING_COPERNICUS")
		obsoleteTechC = gc.getBuildingInfo(b_Copernicus).getObsoleteTech()

		if ( gc.getTeam(pPlayer.getTeam()).isHasTech(obsoleteTechC) == false or obsoleteTechC == -1 ):
			for iCity in range(pPlayer.getNumCities()):
				ppCity = pPlayer.getCity(iCity)
				if ppCity.getNumActiveBuilding(b_Copernicus) == true:
					if eProcess == gc.getInfoTypeForString("PROCESS_RESEARCH"):
						return True


		if eProcess == gc.getInfoTypeForString("PROCESS_RESEARCH2"):
			if ( gc.getTeam(pPlayer.getTeam()).isHasTech(obsoleteTechC) == false or obsoleteTechC == -1 ):
				for iCity in range(pPlayer.getNumCities()):
					ppCity = pPlayer.getCity(iCity)
					if ppCity.getNumActiveBuilding(b_Copernicus) == false:
						return true
			if ( gc.getTeam(pPlayer.getTeam()).isHasTech(obsoleteTechC) == true or obsoleteTechC == 1 ):
				return True

## Troyes End ##

		return False


This worked under 3.6.

Any ideas/advices?
 
I guess it has something to do with this:

PHP:
  Configuration

If you have your own GameUtils class, you can tell BUG to detect and register all or some of the handlers and listeners in it using the <gameutils> element. For each function in the class, if its name matches a callback name exactly it is assigned as a handler, or if it matches the callback name with "Listener" on the end it is assigned as a listener, otherwise it is ignored.

Set the override attribute to True to have the new handlers be called before any existing ones. Otherwise they will be called after the existing handlers but always before the base handler from CvGameUtils. Since all listeners are called, they are not affected by this optional attribute.

<gameutils module="MyMod" class="MyGameUtils" override="True"/>

but WHERE do I have to set this? do I have to create a new .xml config file?
 
Sorry, just completed a move and am catching up on forum posts. You can add a <gameutils> element to any existing or new XML file. If you have a config XML file for your mod already, just add it there.

If you remove CvGameInterfaceFile.py, you will break future BUG features and any other mods that use BUG's Modular Game Utils.
 
Code:
	<gameutils module="CvGameUtils" class="CvGameUtils"/>

I added above code to init.xml, then went well. Thanks!

By the way, I hope that BUG import CvGameUtils.py as default.
Anyway thanks again EmperorFool!:D
 
BUG uses CvGameUtils, but it assumes the it has not been modified from the original. Most of the functions in the original return a value that signifies "do the normal thing". It uses those values to determine whether or not it should call the other handlers.

If you modify CvGameUtils.py, you are in for a world of hurt. You have several choices here, laid out in that thread I linked. Oh, I forgot to add the main documentation for game-utils, sorry.
 
If you modify CvGameUtils.py, you are in for a world of hurt. You have several choices here, laid out in that thread I linked. Oh, I forgot to add the main documentation for game-utils, sorry.
Thanks, this was just the information I was looking for as I'm updating BUG in my modpack (3.6->4.0) and I do have heavily modified CvGameUtils.py in my mod. Got to see how much this "hurts" :lol:
 
@zappara - If you have any suggestions about how to make this easier or what are the hardest parts, please let me know. I tried to make it as easy as I could figure how to by allowing you to use CvGameUtils (renamed) as your GU object after removing all the functions you didn't modify. That way you don't have to name each callback you want to use. Is that how you are updating it?
 
@zappara - If you have any suggestions about how to make this easier or what are the hardest parts, please let me know. I tried to make it as easy as I could figure how to by allowing you to use CvGameUtils (renamed) as your GU object after removing all the functions you didn't modify. That way you don't have to name each callback you want to use. Is that how you are updating it?
Yes, I renamed CvGameUtils to RoMGameUtils and removed all the functions that I haven't modified. I then added the <gameutils...> define with override true to BUG's init.xml (wasn't sure where I was supposed to place it as this wasn't said in the guide). Now the game loads just fine but once the map has been made and the game starts the BUG complains about some undefined callbacks (f.ex. IsInquistionConditions) which are in my RoMGameUtils. If I understood correctly I need to add callbacks, handles and listeners for all those new functions (init.xml?) - I'm slowly getting there and the process doesn't seem too complicated. :)
 
Is that function IsInquistionConditions() a new callback that exists in CvGameInterface.py and is called from the SDK or is it just a utility function used by the other callbacks? If the latter, you can ignore the warnings or move them outside of the class to be at module level (assuming they don't need attributes defined in the class).

If the former, you need to tell BUG about those new callbacks using the <callback> element. Check out Creating New Callbacks.

For each new callback (one that doesn't exist in the original CvGameUtils) you need to add a <callback> child element to the <gameutils> element providing the name and type/value of the default value--the value returned when the callback isn't overridden.

Code:
<gameutils ...>
    <callback name="IsInquistionConditions" type="..." default="..."/>
</gameutils>

I haven't used this functionality much yet myself, so you'll have to let me know how well this works for you. First, let me know if those extra functions are indeed new callbacks. If so, try this out and see if they work. I'm concerned that the gameutils class will be processed before the <callback>s are detected. This will give you the warnings but end up defining the callbacks correctly. If so, I will see about having the callbacks defined first before the whole gameutils is processed. In that case, I'll need to detect duplicated handlers and ignore them.
 
Is that function IsInquistionConditions() a new callback that exists in CvGameInterface.py and is called from the SDK or is it just a utility function used by the other callbacks? If the latter, you can ignore the warnings or move them outside of the class to be at module level (assuming they don't need attributes defined in the class).
I'm pretty sure they are just utility functions - part of RevDCM's 2.5 Inquisition python code which is based on OrionVeteran's Inquisition mod v2.0 (with my own tweaks) and there's like half a dozen new functions.

I think OrionVeteran has changed his mod to use now own Inquisition module instead of adding more functions to gameutils so I'll have to take a look at his mod's newer version and see if I can merge it to my mod and then remove those utility functions from RoMGameUtils if I don't need them anymore. It'll be probably next weekend before I can post more about this as these merge operations are rather time consuming and I got limited amount of time next week for modding - I also got to figure out how to get that new religion screen's top section to scroll as my mod adds few of them (and RoM modmods add lot more religions) - current RoM version has scrolling religion screen.
 
Yes, I believe OrionVeteran updated his mod to use this method of a modular game utils as well, but I'm not 100% sure. He definitely created his own module for the utility functions as I remember reading about that.

As for scrolling religion screen, that would be a nice addition to BUG. It will be harder because Ruff has modified the top section, but not impossible. Do you have a link to the latest scrolling religion screen used in RevDCM?
 
As for scrolling religion screen, that would be a nice addition to BUG. It will be harder because Ruff has modified the top section, but not impossible. Do you have a link to the latest scrolling religion screen used in RevDCM?
I think the scrolling religion screen I've used in my mod was one of the screens in this modcomp
 
I've now converted the CvGameUtils to RoMGameUtils and moved all those extra functions I had there to CvUtils (Inquisition functions). Those new callbacks weren't in the SDK, just in python so I didn't need to define any new callbacks to the xml file. Looks like the RoMGameUtils are executed without problems now and the code you've written works perfectly fine. :)

In init.xml I added line <load mod="RoMSettings"> and then in RoMSettings.xml I had the RoMGameUtils defined. I assume this was the correct way to do it - the guide didn't mention exact method for this.

With the new religion screen I had some progress - I got the city section to handle n religions. Now only got to figure out how to get the top section of the screen to scroll horizontally.
 
With the new religion screen I had some progress - I got the city section to handle n religions. Now only got to figure out how to get the top section of the screen to scroll horizontally.

I have two python files for the main interface and for the religion screen both merged with BUG 3.6 which handle multiple religions if you like. I cannot really remember where I got those before merging them; this is not my work but I don't remember who to credit for that :blush: Still, don't hesitate to ask me if you want them
 
In init.xml I added line <load mod="RoMSettings"> and then in RoMSettings.xml I had the RoMGameUtils defined. I assume this was the correct way to do it - the guide didn't mention exact method for this.

Yes, that's the best way. In RoMSettings.xml you should only need one line for the game utils:

Code:
<gameutils module="RoMGameUtils" class="RoMGameUtils"/>

With the new religion screen I had some progress - I got the city section to handle n religions. Now only got to figure out how to get the top section of the screen to scroll horizontally.

If you post up the new file, I will look into merging it into BUG for others to use.

I have two python files for the main interface and for the religion screen both merged with BUG 3.6 which handle multiple religions if you like. I cannot really remember where I got those before merging them.

I think they were done by johnny smith but I'm not 100% sure.
 
If you post up the new file, I will look into merging it into BUG for others to use.
Here's the screen which city section works with n religions. I haven't touched the top section of the screen so it's not scrolling - I've only looked at johny's screen and tried to compare it with the new screen but it seems to be quite a task (for my low python skills) to get that part of the screen changed. You'll probably figure it out easier and faster than I do. I've marked all the changes I made with some comments.

Here's also a pic how it looks with 11 religions.
 

Attachments

  • CvReligionScreen.zip
    6.5 KB · Views: 75
  • Religionscreen.JPG
    Religionscreen.JPG
    72.4 KB · Views: 92
I'm merging this now and had a quick question. Ruff did this screen, so I'm just playing catch-up. One thing I notice is that it depends on the buildings all being defined in a single contiguous block. When you added your religions, did you do this with the buildings?
 
Top Bottom