Modmodding Q&A Thread

You can find that in SpecialBuildingInfos. This file isn't changed in DoC, so you won't find it in the mod folder. You can find it in assets/XML/Buildings of BTS.

EDIT: Ninja'd by Leoreth
 
Generic monasteries are in Buildings\SpecialBuildingInfos.xml. This file is unchanged in DoC and therefore not in the mod folder, you have to copy it there if you want to edit it.

All specific monasteries are instances of this generic monastery "special building". A UB can only replace one monastery for a specific religion (unless you create 9 instances of the UB, one for every religion). Not sure how tech obsoletion in building and special building XML interact with each other, but probably the building XML does not override the special building XML.

I need UB for a specific religion so it is OK. I'll check the SpecialBuildingInfos.xml.

You can find that in SpecialBuildingInfos. This file isn't changed in DoC, so you won't find it in the mod folder. You can find it in assets/XML/Buildings of BTS.

EDIT: Ninja'd by Leoreth

:lol:


Yeah I looked on mod folder but it wasn't there. Thanks for that advice.



++ Anyone have some idea about what happens if I make monastery UB and remove <SpecialBuildingType> part from it's part in CIV4BuildingInfos.xml?
 
This could work, but it might lose some effects associated with monasteries (religious building construction modifier, AP hammers, missionary construction).
 
I'm trying to assign custom txt_keys to the hill and mountain terrain to get them to display their real abilites. The ocean txt_key displays correctly but the hill txt_key only half displays and the mountain txt_key doesn't display at all. No python errors appear.
Code:
	def placeSpecial(self):
		screen = self.top.getScreen()
		panelName = self.top.getNextWidgetName()
		screen.addPanel(panelName, localText.getText("TXT_KEY_PEDIA_SPECIAL_ABILITIES", ()), "", True, False, self.X_SPECIAL_PANE, self.Y_SPECIAL_PANE, self.W_SPECIAL_PANE, self.H_SPECIAL_PANE, PanelStyles.PANEL_STYLE_BLUE50)
		listName = self.top.getNextWidgetName()
		screen.attachListBoxGFC(panelName, listName, "", TableStyles.TABLE_STYLE_EMPTY)
		screen.enableSelect(listName, False)
[B]		if self.iTerrain == gc.getInfoTypeForString("TERRAIN_OCEAN"):
			szSpecialText = localText.getText('TXT_KEY_TERRAIN_OCEAN_HELP', ())
			szSpecialText += CyGameTextMgr().getTerrainHelp(self.iTerrain, True)
		elif self.iTerrain == gc.getInfoTypeForString("TERRAIN_HILL"):
			szSpecialText = localText.getText('TXT_KEY_PEDIA_HILL_MID', ())
		elif self.iTerrain == gc.getInfoTypeForString("TERRAIN_MOUNTAIN"):
			szSpecialText = localText.getText('TXT_KEY_PEDIA_MOUNTAIN_MID', ())
			szSpecialText += CyGameTextMgr().getTerrainHelp(self.iTerrain, True)
		else:
			szSpecialText = CyGameTextMgr().getTerrainHelp(self.iTerrain, True)[/B]
		splitText = string.split(szSpecialText, "\n")
		for special in splitText:
			if len(special) != 0:
				screen.appendListBoxString(listName, special, WidgetTypes.WIDGET_GENERAL, -1, -1, CvUtil.FONT_LEFT_JUSTIFY)
Code:
	def placeStats(self):
		screen = self.top.getScreen()
		panelName = self.top.getNextWidgetName()
		screen.addListBoxGFC(panelName, "", self.X_STATS_PANE, self.Y_STATS_PANE, self.W_STATS_PANE, self.H_STATS_PANE, TableStyles.TABLE_STYLE_EMPTY)
		screen.enableSelect(panelName, False)
[B]		if self.iTerrain == gc.getInfoTypeForString("TERRAIN_HILL"):
			szYield = localText.getText('TXT_KEY_PEDIA_HILL_TOP', ())[/B]
		for k in range(YieldTypes.NUM_YIELD_TYPES):
			iYield = gc.getTerrainInfo(self.iTerrain).getYield(k)
			if (iYield != 0):
				szYield = (u"%s: %i" % (gc.getYieldInfo(k).getDescription().upper(), iYield))
				screen.appendListBoxString(panelName, u"<font=3>" + szYield + (u"%c" % gc.getYieldInfo(k).getChar()) + u"</font>", WidgetTypes.WIDGET_GENERAL, 0, 0, CvUtil.FONT_LEFT_JUSTIFY)
This is the code I used to make hills and mountains appear if relevant:
Code:
	def getTerrainList(self):
[B]		list = []
		for i in range(10):
			item = gc.getTerrainInfo(i)
			if item:
				list.append((item.getDescription(), i))
		if self.isSortLists():
			list.sort()
		return list
[/B]
Also how do I get "for i in range(10)" which currently selects the 1st - 10th terrains in the xml file, to select only the 10th?
 
I'm trying to assign custom txt_keys to the hill and mountain terrain to get them to display their real abilites. The ocean txt_key displays correctly but the hill txt_key only half displays and the mountain txt_key doesn't display at all. No python errors appear.

What do you exactly mean with "hill text only display half?

Spoiler :
Code:
	def placeSpecial(self):
		screen = self.top.getScreen()
		panelName = self.top.getNextWidgetName()
		screen.addPanel(panelName, localText.getText("TXT_KEY_PEDIA_SPECIAL_ABILITIES", ()), "", True, False, self.X_SPECIAL_PANE, self.Y_SPECIAL_PANE, self.W_SPECIAL_PANE, self.H_SPECIAL_PANE, PanelStyles.PANEL_STYLE_BLUE50)
		listName = self.top.getNextWidgetName()
		screen.attachListBoxGFC(panelName, listName, "", TableStyles.TABLE_STYLE_EMPTY)
		screen.enableSelect(listName, False)
[B]		if self.iTerrain == gc.getInfoTypeForString("TERRAIN_OCEAN"):
			szSpecialText = localText.getText('TXT_KEY_TERRAIN_OCEAN_HELP', ())
			szSpecialText += CyGameTextMgr().getTerrainHelp(self.iTerrain, True)
		elif self.iTerrain == gc.getInfoTypeForString("TERRAIN_HILL"):
			szSpecialText = localText.getText('TXT_KEY_PEDIA_HILL_MID', ())
		elif self.iTerrain == gc.getInfoTypeForString("TERRAIN_MOUNTAIN"):
			szSpecialText = localText.getText('TXT_KEY_PEDIA_MOUNTAIN_MID', ())
			szSpecialText += CyGameTextMgr().getTerrainHelp(self.iTerrain, True)
		else:
			szSpecialText = CyGameTextMgr().getTerrainHelp(self.iTerrain, True)[/B]
		splitText = string.split(szSpecialText, "\n")
		for special in splitText:
			if len(special) != 0:
				screen.appendListBoxString(listName, special, WidgetTypes.WIDGET_GENERAL, -1, -1, CvUtil.FONT_LEFT_JUSTIFY)

You could try to move the extra text out of the szSpecialText. I think this causes the problem. The code beneath bypasses that:

Code:
	def placeSpecial(self):
		screen = self.top.getScreen()
		panelName = self.top.getNextWidgetName()
		screen.addPanel(panelName, localText.getText("TXT_KEY_PEDIA_SPECIAL_ABILITIES", ()), "", True, False, self.X_SPECIAL_PANE, self.Y_SPECIAL_PANE, self.W_SPECIAL_PANE, self.H_SPECIAL_PANE, PanelStyles.PANEL_STYLE_BLUE50)
		listName = self.top.getNextWidgetName()
		screen.attachListBoxGFC(panelName, listName, "", TableStyles.TABLE_STYLE_EMPTY)
		screen.enableSelect(listName, False)
		[COLOR="Red"]szSpecialText = CyGameTextMgr().getTerrainHelp(self.iTerrain, True)
		szExtraText = ""[/COLOR]
		if self.iTerrain == gc.getInfoTypeForString("TERRAIN_OCEAN"):
			[COLOR="red"]szExtraText[/COLOR] = localText.getText('TXT_KEY_TERRAIN_OCEAN_HELP', ())
		elif self.iTerrain == gc.getInfoTypeForString("TERRAIN_HILL"):
			[COLOR="red"]szExtraText[/COLOR] = localText.getText('TXT_KEY_PEDIA_HILL_MID', ())
		elif self.iTerrain == gc.getInfoTypeForString("TERRAIN_MOUNTAIN"):
			[COLOR="red"]szExtraText[/COLOR] = localText.getText('TXT_KEY_PEDIA_MOUNTAIN_MID', ())
		splitText = string.split(szSpecialText, "\n")
[COLOR="red"]		if szExtraText != "":
			screen.appendListBoxString(listName, szExtraText, WidgetTypes.WIDGET_GENERAL, -1, -1, CvUtil.FONT_LEFT_JUSTIFY)[/COLOR]
		for special in splitText:
			if len(special) != 0:
				screen.appendListBoxString(listName, special, WidgetTypes.WIDGET_GENERAL, -1, -1, CvUtil.FONT_LEFT_JUSTIFY)

Personally, I would replace the gc.getInfoTypeForString() with con.ixxx. (You can find the correct integers in consts.py. That means you need to add "Import Consts as con" in the beginning of the file. But this is just something that makes the code a bit cleaner IMO.

Spoiler :
Code:
	def placeStats(self):
		screen = self.top.getScreen()
		panelName = self.top.getNextWidgetName()
		screen.addListBoxGFC(panelName, "", self.X_STATS_PANE, self.Y_STATS_PANE, self.W_STATS_PANE, self.H_STATS_PANE, TableStyles.TABLE_STYLE_EMPTY)
		screen.enableSelect(panelName, False)
[B]		if self.iTerrain == gc.getInfoTypeForString("TERRAIN_HILL"):
			szYield = localText.getText('TXT_KEY_PEDIA_HILL_TOP', ())[/B]
		for k in range(YieldTypes.NUM_YIELD_TYPES):
			iYield = gc.getTerrainInfo(self.iTerrain).getYield(k)
			if (iYield != 0):
				szYield = (u"%s: %i" % (gc.getYieldInfo(k).getDescription().upper(), iYield))
				screen.appendListBoxString(panelName, u"<font=3>" + szYield + (u"%c" % gc.getYieldInfo(k).getChar()) + u"</font>", WidgetTypes.WIDGET_GENERAL, 0, 0, CvUtil.FONT_LEFT_JUSTIFY)

You gave szYield a string for hills. But it won't be assigned to the Listbox.

This is the code I used to make hills and mountains appear if relevant:
Spoiler :
Code:
	def getTerrainList(self):
[B]		list = []
		for i in range(10):
			item = gc.getTerrainInfo(i)
			if item:
				list.append((item.getDescription(), i))
		if self.isSortLists():
			list.sort()
		return list
[/B]

Also how do I get "for i in range(10)" which currently selects the 1st - 10th terrains in the xml file, to select only the 10th?

There are 2 easy solutions:
Code:
	def getTerrainList(self):
		list = []
		for i in range([COLOR="Red"]con.iTerrainPeak, con.iTerrainHills[/COLOR]):
			item = gc.getTerrainInfo(i)
			if item:
				list.append((item.getDescription(), i))
		if self.isSortLists():
			list.sort()
		return list
(You have to insert import Consts as on top of the file, OR use the gc.getInfoTypeForString method instead of con.xxx)

Or you can just simply use:
Code:
	def getTerrainList(self):
		list = []
		[COLOR="red"]#for i in range(con.iTerrainPeak, con.iTerrainHills):[/COLOR]
		item = gc.getTerrainInfo([COLOR="red"]10[/COLOR])
		if item:
			list.append((item.getDescription(), i))
		if self.isSortLists():
			list.sort()
		return list
 
I'm trying to assign custom txt_keys to the hill and mountain terrain to get them to display their real abilites. The ocean txt_key displays correctly but the hill txt_key only half displays and the mountain txt_key doesn't display at all. No python errors appear.
I think what is causing your problem is that you don't account for the difference between plot type, terrain and feature.

Plot type is the elevation of the tile: water, flatlands, hills, peak. You can also check this using PyPlot.isPeak() and similar methods.

Terrain is what climate the tile has: grass, plains, desert. Feature is what else is on the tile, like forests.

This is the code I used to make hills and mountains appear if relevant:
Code:
	def getTerrainList(self):
[B]		list = []
		for i in range(10):
			item = gc.getTerrainInfo(i)
			if item:
				list.append((item.getDescription(), i))
		if self.isSortLists():
			list.sort()
		return list
[/B]
Also how do I get "for i in range(10)" which currently selects the 1st - 10th terrains in the xml file, to select only the 10th?
I don't understand what the purpose of this method is. Where do you want to make hills and mountains "appear"? And why do you use a method that creates a list when you only want one element?

Or you can just simply use:
Code:
	def getTerrainList(self):
		list = []
		[COLOR="red"]#for i in range(con.iTerrainPeak, con.iTerrainHills):[/COLOR]
			item = gc.getTerrainInfo([COLOR="red"]10[/COLOR])
			if item:
				list.append((item.getDescription(), i))
		if self.isSortLists():
			list.sort()
		return list
Be careful to correct the indentations in this though.
 
This is more of a general question, but I can't save anything I move into a new folder (for a mod that I'm working on). It always goes to "save as" and then when I override it, it says that the "path is denied". Has anybody seen this before?

Maybe your current user account does not have the privileges to perform that action in this folder?

Here's a screenshot:

attachment.php


I'm certain this is more of a problem with the computer/account, but I have an administrator account. Anybody know a fix to this?
 

Attachments

  • bug.PNG
    bug.PNG
    95.6 KB · Views: 209
Save it somewhere else and copy and paste it to the correct folder. That problem happens to me too.

Thanks. Is there any sort of permanent fix or is that the only thing possible?
 
I haven't figured out any sort of permanent fixes, I've just gotten used to having two copies of whatever I want to put in my Program Files folder (which includes all the RFC modmods I play...).
 
Did you try to give yourself permission to edit the file in the properties? I wasn't enabled to edit files in the Program Files by default, but I changed it. (Right click on the mods folder --> properties --> security)
 
Did you try to give yourself permission to edit the file in the properties? I wasn't enabled to edit files in the Program Files by default, but I changed it. (Right click on the mods folder --> properties --> security)

It worked! Thanks.
 
I'm trying to use Visual C++ 2008 to compile the dll but I keep getting these errors

Code:
1> "C:\Program Files (x86)\Microsoft Visual C++ Toolkit 2003\bin\link.exe" /out:Release\CvGameCoreDLL.dll /INCREMENTAL:NO /OPT:REF /OPT:ICF /PDB:"Release\CvGameCoreDLL.pdb" /DLL /NOLOGO /SUBSYSTEM:WINDOWS /LARGEADDRESSAWARE /TLBID:1 /LIBPATH:Python24/libs /LIBPATH:boost-1.32.0/libs/ boost_python-vc71-mt-1_32.lib /LIBPATH:"C:\Program Files (x86)\Microsoft Visual C++ Toolkit 2003/lib" /LIBPATH:"C:\Program Files (x86)\Microsoft SDKs/Lib"  /LIBPATH:"C:\Program Files (x86)\Firaxis Games\Sid Meier's Civilization 4\Beyond the Sword\CvGameCoreDLL\Boost-1.32.0/libs" /LIBPATH:"C:\Program Files (x86)\Firaxis Games\Sid Meier's Civilization 4\Beyond the Sword\CvGameCoreDLL\Python24/libs" winmm.lib user32.lib Release\CvArea.obj  Release\CvArtFileMgr.obj  Release\CvBugOptions.obj  Release\CvCity.obj  Release\CvCityAI.obj  Release\CvDeal.obj  Release\CvDiploParameters.obj  Release\CvDLLButtonPopup.obj  Release\CvDLLEntity.obj  Release\CvDLLPython.obj  Release\CvDllPythonEvents.obj  Release\CvDllTranslator.obj  Release\CvDLLWidgetData.obj  Release\CvEventReporter.obj  Release\CvFractal.obj  Release\CvGame.obj  Release\CvGameAI.obj  Release\CvGameCoreDLL.obj  Release\CvGameCoreUtils.obj  Release\CvGameInterface.obj  Release\CvGameTextMgr.obj  Release\CvGlobals.obj  Release\CvHallOfFameInfo.obj  Release\CvInfos.obj  Release\CvInfoWater.obj  Release\CvInitCore.obj  Release\CvMap.obj  Release\CvMapGenerator.obj  Release\CvMessageControl.obj  Release\CvMessageData.obj  Release\CvPlayer.obj  Release\CvPlayerAI.obj  Release\CvPlot.obj  Release\CvPlotGroup.obj  Release\CvPopupInfo.obj  Release\CvPopupReturn.obj  Release\CvRandom.obj  Release\CvReplayInfo.obj  Release\CvReplayMessage.obj  Release\CvRhyes.obj  Release\CvSelectionGroup.obj  Release\CvSelectionGroupAI.obj  Release\CvStatistics.obj  Release\CvStructs.obj  Release\CvTalkingHeadMessage.obj  Release\CvTeam.obj  Release\CvTeamAI.obj  Release\CvTextScreens.obj  Release\CvUnit.obj  Release\CvUnitAI.obj  Release\CvXMLLoadUtility.obj  Release\CvXMLLoadUtilityGet.obj  Release\CvXMLLoadUtilityInit.obj  Release\CvXMLLoadUtilitySet.obj  Release\CyArea.obj  Release\CyAreaInterface.obj  Release\CyArgsList.obj  Release\CyArtFileMgr.obj  Release\CyArtFileMgrInterface.obj  Release\CyCity.obj  Release\CyCityInterface1.obj  Release\CyCityInterface2.obj  Release\CyDeal.obj  Release\CyEnumsInterface.obj  Release\CyGame.obj  Release\CyGameCoreUtils.obj  Release\CyGameCoreUtilsInterface.obj  Release\CyGameInterface.obj  Release\CyGameTextMgr.obj  Release\CyGameTextMgrInterface.obj  Release\CyGlobalContext.obj  Release\CyGlobalContextInterface1.obj  Release\CyGlobalContextInterface2.obj  Release\CyGlobalContextInterface3.obj  Release\CyGlobalContextInterface4.obj  Release\CyHallOfFameInfo.obj  Release\CyHallOfFameInterface.obj  Release\CyInfoInterface1.obj  Release\CyInfoInterface2.obj  Release\CyInfoInterface3.obj  Release\CyMap.obj  Release\CyMapGenerator.obj  Release\CyMapGeneratorInterface.obj  Release\CyMapInterface.obj  Release\CyMessageControl.obj  Release\CyMessageControlInterface.obj  Release\CyPlayer.obj  Release\CyPlayerInterface1.obj  Release\CyPlayerInterface2.obj  Release\CyPlot.obj  Release\CyPlotInterface1.obj  Release\CyRandomInterface.obj  Release\CyReplayInfo.obj  Release\CySelectionGroup.obj  Release\CySelectionGroupInterface.obj  Release\CyStructsInterface1.obj  Release\CyTeam.obj  Release\CyTeamInterface.obj  Release\CyUnit.obj  Release\CyUnitInterface1.obj  Release\FAssert.obj  Release\FDialogTemplate.obj  Release\_precompile.obj   
1>   Creating library Release\CvGameCoreDLL.lib and object Release\CvGameCoreDLL.exp
1>CvPlot.obj : error LNK2019: unresolved external symbol _GetProcessMemoryInfo@12 referenced in function "bool __cdecl NeedToFreeMemory(void)" (?NeedToFreeMemory@@YA_NXZ)
1>Release\CvGameCoreDLL.dll : fatal error LNK1120: 1 unresolved externals
1>NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual C++ Toolkit 2003\bin\link.exe"' : return code '0x460'
1>Stop.
1>Project : error PRJ0019: A tool returned an error code from "Performing Makefile project actions"
1>Build log was saved at "file://c:\Users\Andrew\Desktop\Alternative\CvGameCoreDLL\CvGameCoreDLL\Debug\BuildLog.htm"
1>CvGameCoreDLL - 4 error(s), 18 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Does anyone know why?
 
Yes, I think there's an additional dependency for the graphical paging feature that's not in the general makefile you find in the guides. Isn't my own makefile in the SVN? If so, make use of that, otherwise I'll look it up when I'm at home.
 
Yes, I think there's an additional dependency for the graphical paging feature that's not in the general makefile you find in the guides. Isn't my own makefile in the SVN?

I don't think so, if it is I can't seem to find it.
 
Okay I'll post the required change later then.
 
Okay, what you need to do is include psapi.lib in your libraries. The library should be part of the Windows C++ distribution you installed when setting up the compiler so that should be fine.

I have attached my makefile, but depending on how you set up your project using it directly might not work.
 

Attachments

So earlier I was asking about the location of some UPs. Do you think you could tell me where the following civs' UPs are:

Poland, Indonesia, China, Holy Rome (old and new), France, India (old), Harappa, Mongols, England.
 
Back
Top Bottom