Quick Modding Questions Thread

Hello and 2 Questions:

which python file is responsible for the inside city screen?


Thank You!

CvMainInterface.Py It contains the python for both the map and the city screens. I have been toying with splitting it into 3 python files one for the map, one for the city and a main control one. As far as I can see that is the first step needed before you can add extra map and build screens eg build screen for forts or nomadic units. It is a big job and I keep getting side tracked.
 
I have been toying with splitting it into 3 python files one for the map, one for the city and a main control one. As far as I can see that is the first step needed before you can add extra map and build screens eg build screen for forts or nomadic units. It is a big job and I keep getting side tracked.
I could have written the very same thing, including the sidetracked part :lol:

Please tell if you manage to do it. Hopefully in git or similar where it is possible to track each commit.
 
Hello and 2 Questions:

which python file is responsible for the inside city screen?

where is is determine which icon/button is displayed as tiny religion symbol on top of cities (on main map) and inside city screen?

Thank You!

1) City screen is as DH said.

2) If you are referring to which file determines the "place" to display the icons:
City screen is still CvMainInterface.Py
Map is not defined via python, it is not in that file.
 
Editing those files is quite the process though. There is a a fairly concise tutorial for it though.
Editing GameFont files is a whole lot easier if you use GameFontEditor. Just load the file, paste the icon into the slot where it should be and say yes to resizing (if needed).

Determining which icon is used for which religion and placing it on the city billboard is done in the DLL. Presumably you can do what you want without modding the DLL, but it does allow you to take full control of the entire GameFont system if you have the skills. While it seems to be the natural way to do it, a significant part of GameFont setup is moved to the exe in Colonization for what seems like no good reason at all.
 
Thank you everyone!
One more question, by any chance you could tell on which line in CvMainInterface.Py it deals with position of religious icons inside city screen?
I added 1 more religion and it is displayed just outside the field of view. I want to move the icons position to the left a bit so new icon is visible.

Thank You!
 
You have 8 religions now but you might want to have more in the future. I suggest that you take a look at the Just Another Religion Mod where they have the screens from Johny Smith which allow more religions.

Beware to merge the modifications into your own file(s) as I believe the Johny Smith one is not from BtS 3.19. All changes should be marked JARM.
 
It's set somewhere in XML, often globalDefineALT.xml. That's a general answer to getDefineINT as I'm unfamiliar with SURVIVES_SINKING_PROBABILITY. Sounds a bit like a mod specific feature.

Thank you i found it and i know now.

GlobalDefines.xml:
Code:
	<Define>
		<DefineName>SURVIVES_SINKING_PROBABILITY</DefineName>
		<iDefineIntVal>4</iDefineIntVal>
	</Define>
 
You have 8 religions now but you might want to have more in the future. I suggest that you take a look at the Just Another Religion Mod where they have the screens from Johny Smith which allow more religions.

Beware to merge the modifications into your own file(s) as I believe the Johny Smith one is not from BtS 3.19. All changes should be marked JARM.

This is a very interesting mod.
On one hand I do not want to have too many religions in my game (8 is definitely enough) on other hand his idea that only 7 out of potential 17 can ever form is really nice one.
But mod merging is something I am reserving for the future ;)

For now, I just want to adjust city screen ;)



EDIT: managed to figure it out ;) its on the line #2308 (xCoord = xResolution - 242 + (i * 34)) if anyone else needs it ;)
 
New Question ;)

I wanted to give Peaks some yields values so city can work this tile (while it remains impassible)
So I went to CIV4TerrainInfos and gave peaks some yields.
But in game city still cannot work those tiles.
Whats up with that? ;)

Question 2. If I want to test if Event works - is there a way to force them by command? like a cheat code or something?


Question 3. I understand some of events refer to python files, but they very hard to track down. For example "Classic Literature" quest. Can't seem to find the part where it gives better rewards based on having Great Library.

Thank You!
 
Repost: As I still need some code for this

Is it possible to get cities to be renamed through python?

Like this: Indraprastha->Delhi (1200 AD)->Shahjahanabad (1600 AD)

Or perhaps through conquest by another civ, let's say if Indraprastha is conquered by the Mughal Empire, it is renamed Shahjahanabad.
 
I wanted to give Peaks some yields values so city can work this tile (while it remains impassible)
So I went to CIV4TerrainInfos and gave peaks some yields.
But in game city still cannot work those tiles.
Whats up with that? ;)

Question 2. If I want to test if Event works - is there a way to force them by command? like a cheat code or something?

Question 3. I understand some of events refer to python files, but they very hard to track down. For example "Classic Literature" quest. Can't seem to find the part where it gives better rewards based on having Great Library.

1) Because Peaks and Hills are not really terrains but plots. Both can be set on terrains (Grass, Plains, ...). In the TerrainInfos file, some tags will work for them (like forbidding founding cities on Hills), some won't.

2) ?

3) Not really difficult. All are in Python/EntryPoints/CvRandomEventInterface.py.

Just find the function referred to in the various Python tags in the Event & EventTrigger XML files and locate them in the Python file.

Or in the Python file, search for BUILDING_GREAT_LIBRARY (in your case applyClassicLiteratureDone3)...
 
1) Because Peaks and Hills are not really terrains but plots. Both can be set on terrains (Grass, Plains, ...). In the TerrainInfos file, some tags will work for them (like forbidding founding cities on Hills), some won't.

2) ?

3) Not really difficult. All are in Python/EntryPoints/CvRandomEventInterface.py.

Just find the function referred to in the various Python tags in the Event & EventTrigger XML files and locate them in the Python file.

Or in the Python file, search for BUILDING_GREAT_LIBRARY (in your case applyClassicLiteratureDone3)...

1. Ok so, any idea where I can look to control the peaks? Like where does the games sets that Hills must loose 1 food and gain 1 hammer?

2 - I guess you don't know that one ;)

3. Thanks, I will look it up! ;)
 
1) CIV4YieldInfos.xml (in Vanilla/Terrain)

2) right! ;)

PS: Not that you asked, but there is no plot.xml file

Per memory (see a WB file for example):

Plot 0 = Peak

Plot 1 = Hill

Plot 2 = flat land (Grass, Plains, Desert, Tundra or Snow)

Plot 3 = water planes (Coast or Ocean)
 
2) Check how it is done for partisan event in CvEventManager
 
1) CIV4YieldInfos.xml (in Vanilla/Terrain)

unfortunately playing with this file did nothing for me - it seems that game is hard coded somewhere to nullify any value assigned to a peak.
Unless it can be altered somewhere else.

2) Check how it is done for partisan event in CvEventManager

Ok I looked at it... and frankly I not sure what to do with it ;) Could you please elaborate? ;)
 
1) Perhaps - I've never tried to alter Peak values.

2) or XML only, you could just give temporarily an iWeight of -1 to the event in the trigger file... (thought of that during the night!). The event is then fired as soon as all the conditions are met.
 
I need some help. I have some ideas but i really don't know which is the best, maybe you will help me.

There are two memberships, first is CIVIC_GDI_MEMEBERSHIP, second is CIVIC_NOD_MEMBERSHIP. Main idea is simple and work with FFH2 source code, all civilization with same civic are in same pact (similar like Apostolic palace, but is different, if you play FFH2 you know for two memberships, that work same/similar like that).

IDEAS:
1) I search for the best balance, but if i give to GDI +10%production, and to NOD +10%food, i will have for example 9/10 as members in GDI, and 1/10 to NOD, or vice versa.

2) I try with corporations, i give to palace to generate BONUS_ALIGNMENT, and CORP_NOD and CORP_GDI to consume that resource, and give some python code, that every turn is chance to corporation random spread in some city in the world. However all AIs switch to STATE_PROPERTY civic and with that i can't spread regular corporation outside my borders , and this disrupts balance in game. To switch to GDI civic (require higher % of CORP_GDI than CORP_NOD in their cities), to NOD civic (require higher % of CORP_NOD than CORP_GDI in their cities).

3) Not tested yet, but i have idea to make two new religions REL_GDI and REL_NOD, but i don't want to civilization switch to these religion (or i want, don't really know at this moment), player/AI than can chose GDI (require GDI as state rel) or NOD (require NOD as state rel) civic, but if see further, what if player want to play with CHOSE RELIGION game option, then they can found NOD or GDI in Ancient times, but i would like that be in DIGITAL age (first era after MODERN). I will must to make some limit like can't found that religions before DIGITAL age, i don't know is really this idea is the best.

4) I forgot to mention that we have to 2 wonder something like GDI_HEADQUARTERS and NOD_HEADQUARTERS and this buildings are necessary for voting, like UN. Players wait to both of this building be built, and after that i have several ideas:
- 4.1) All even teams will be members of GDI, all odd teams will be member of NOD. After this that is impossible to switch to another membership. If you are vassal you are automatic member of master membership.
- 4.2) Demand some specific score, for example if your score is even you became member of GDI, if is odd you became member of NOD. After this that is impossible to switch to another membership. If you are vassal you are automatic member of master membership.
- 4.3) Demand some specific resource to became a member of some membership, for example copper to GDI, iron to NOD. After this that is impossible to switch to another membership. If you are vassal you are automatic member of master membership.
- 4.4) If your capital have even population you will became member of GDI, if have odd population you will became member of NOD. Same for vassals and banned switching as in previous.
- 4.5) If number of your total empire population is even you are GDI, if is odd you are NOD. Same for vassals and banned switching as in previous.
- 4.6) Random generation will determine which membership you will belong. Same for vassals and banned switching as in previous.
- 4.7) Example 10 players! Player with the best score and player with the worst game score (1st and 10th) are in GDI, 2nd and 9th are in NOD, 3rd and 8th are in GDI, 4th and 7th are in NOD, 5th goes to GDI 6th goes to NOD. if is odd numbers of players, the last-one will be random determine.

5) Some your idea, advice, whatever, i just want to make this balance something like 5 vs 5 or 4 vs 6, not 8 vs 2.


Sorry if i write something understandable, i wrote this quick.
 
How to add this bit of code:
Code:
			if iGameTurn!=0:
			if iGameTurn%2 == 0:
				self.doCheckDepletion()
	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")
To this bit of code:
Code:
##Basic Expanded v1.1 by modifieda4 2012

from CvPythonExtensions import *
import CvUtil
import PyHelpers
import CvAdvisorUtils
import CvTechChooser
import BugCore
import BugUtil
import CvEventInterface
import CvScreensInterface

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


class BasicExpandedEvent:

	def __init__(self, eventMgr):
		self.eventMgr = eventMgr
		eventMgr.addEventHandler("buildingBuilt", self.onBuildingBuilt)
		eventMgr.addEventHandler("cityLost", self.onCityLost)
		eventMgr.addEventHandler("cityRazed", self.onCityRazed)
		self.iArcologyCityID=-1

	def onBuildingBuilt(self, argsList):
		'Building Completed'
		pCity, iBuildingType = argsList
		game = gc.getGame()
		
		if iBuildingType == CvUtil.findInfoTypeNum(gc.getBuildingInfo, gc.getNumBuildingInfos(), "BUILDING_ARCOLOGY_SHIELDING"):
			pCity.setNumRealBuilding(CvUtil.findInfoTypeNum(gc.getBuildingInfo, gc.getNumBuildingInfos(), "BUILDING_ARCOLOGY"), False)
		elif iBuildingType == CvUtil.findInfoTypeNum(gc.getBuildingInfo, gc.getNumBuildingInfos(), "BUILDING_ADVANCED_SHIELDING"):
			pCity.setNumRealBuilding(CvUtil.findInfoTypeNum(gc.getBuildingInfo, gc.getNumBuildingInfos(), "BUILDING_ARCOLOGY_SHIELDING"), False)

	def onCityLost(self, argsList):
		'City Lost'
		city = argsList[0]
		player = PyPlayer(city.getOwner())
		if city.getID() == self.iArcologyCityID:
			city.plot().setImprovementType(gc.getInfoTypeForString("IMPROVEMENT_CITY_RUINS_ARCOLOGY"))

	def onCityRazed(self, argsList):
		'City Razed'
		city, iPlayer = argsList
		iOwner = city.findHighestCulture()

		self.iArcologyCityID = -1
		if city.getNumRealBuilding(gc.getInfoTypeForString("BUILDING_ARCOLOGY")) or city.getNumRealBuilding(gc.getInfoTypeForString("BUILDING_ARCOLOGY_SHIELDING")) or city.getNumRealBuilding(gc.getInfoTypeForString("BUILDING_ADVANCED_SHIELDING")):
			self.iArcologyCityID = city.getID()			
			

def cannotConstruct(argsList):
	pCity = argsList[0]
	eBuilding = argsList[1]
	bContinue = argsList[2]
	bTestVisible = argsList[3]
	bIgnoreCost = argsList[4]
	#BugUtil.alert("check construct")	
	# player can't build an arcology if they have shielding or advanced shielding
	if eBuilding == gc.getInfoTypeForString("BUILDING_ARCOLOGY"):
		if pCity.getNumRealBuilding(gc.getInfoTypeForString("BUILDING_ARCOLOGY_SHIELDING")) or pCity.getNumRealBuilding(gc.getInfoTypeForString("BUILDING_ADVANCED_SHIELDING")):
			return True
		
	# player can't build shielding if they have advanced
	if eBuilding == gc.getInfoTypeForString("BUILDING_ARCOLOGY_SHIELDING"):
		if pCity.getNumRealBuilding(gc.getInfoTypeForString("BUILDING_ADVANCED_SHIELDING")):
			return True


	return False

Simply adding it doesn't work, what things are missing?
 
Back
Top Bottom