[MODCOMP] Obsolete Buildings

Jean Elcard

The Flavournator
Joined
Feb 26, 2006
Messages
1,008
Location
Leipzig, Germany
Obsolete Buildings

This is more or less a spin-off of an other mod of mine, but I release it as a stand-alone mod component, because it's a really nice and easy to use mechanism. In some way it is similar to TheLopez "Upgradeable Buildings" mod, but there are significant differences in functionality and especially in the way it's coded.

Short Description:

This mod component allows you to specify buildings, which, if built, obsolete other buildings in the same city. "Obsoletes" in this context means, that they will replace their predecessors in the same city and prevent them from being built there again as long as the successor exists in the city. This works also with complex multiple levels of obsoletenesses.

The Facts:

  • One building may obsolete an arbitrary number of other building classes.
  • Any number of different buildings are allowed to obsolete the same building classes.
  • Transitivity: If Building B obsoletes A and C obsoletes B, then C also obsoletes A automatically.
  • Only in the city buildable buildings show up in the building menue.
  • Civilopedia shows all buildings which become obsolete by building a certain building and all buildings which obsolete in turn this one.
  • In the city screen only buildings, you've built in the city already, will show up as becoming obsolete in the help text of a building you are allowed to construct. (see the attached screenshot)
Example:

I've included a rather academical example with no real practical relevance but it demonstrates very well, what the mod does. See the first figure in the attached graph below. The letters stand for different buildings and an arrow from one building to another means, that the first building obsoletes the latter. Blue arrwos are declared in XML and orange arrows are automatically generated transitive connections. You may play around with this example ingame to get a feeling for it.

How to use:

Very easy. Just add a XML tag like this to the building you want to obsolete another building class in CIV4BuildingInfos.xml.

Code:
<ObsoleteBuildingClasses>
	<ObsoleteBuildingClass>
		<BuildingClassType>BUILDINGCLASS_B</BuildingClassType>
		<bObsolete>1</bObsolete>
	</ObsoleteBuildingClass>
</ObsoleteBuildingClasses>

That's it, but be careful not to create circles like in figure 2 of the attached graph. Your game will crash because of eternal recursion.

Modder who would like to integrate my mod component might be interested in knowing, that I marked all modifications made by me in C++ and XML by comments starting with "OB:".

Download:

Obsolete Buildings v0.1.0 for Civilization IV (Vanilla) v1.74: Link
Obsolete Buildings v0.1.1 for Civilization IV (Beyond the Sword) v3.17: Link (06/20/08)

If you find any bugs please tell me. Otherwise have fun.

Jean Elcard (aka Elgor)
 

Attachments

  • screen1bts.png
    screen1bts.png
    49.5 KB · Views: 373
  • screen2bts.png
    screen2bts.png
    237.5 KB · Views: 527
  • screen3bts.png
    screen3bts.png
    127.3 KB · Views: 387
Any possibility of using this in BTS? There's a packaged mod that could really benefit from building obsolescence.
 
Version 0.1.0 converted to Beyond the Sword 3.02, uploaded and now ready for download!

There were quite some changes necessary to make the mod work again. I've also transformed the example for BtS to the new modular XML. So be sure to activate this in your CivilizationIV.ini:

Code:
; Modular XML Loading
ModularLoading = 1
 
Easter comes early this year! A version compatible to BtS 3.13 is up. Check the first post.

Notice that there is no need to fiddle around with your CivilizationIV.ini anymore in order to make this mod work. This is due to acitvating modular XML loading by mod means became possible with BtS 3.13.
 
I tried to merge this to my mod and now get:
Code:
Traceback (most recent call last):

  File "CvScreensInterface", line 207, in pediaMain

  File "CvPediaMain", line 960, in pediaJump

  File "CvPediaMain", line 259, in showScreen

  File "CvPediaMain", line 392, in placeBuildings

RuntimeError: unidentifiable C++ exception
ERR: Python function pediaMain failed, module CvScreensInterface
this is giving me hard crashes. Any idea what part of your code could be that sensitive here? CvPediaMain is unmodified but I'm trying to merge on top of FFH code in the SDK(compiled fine and no obvious conflicts).
 
Ok forget about the bug above that was a missing artdefine but the game keeps crashing as soon I want to enter the cityscreen. I compiled a debug.dll and it gives me an assert on:

Code:
CvBuildingInfo& CvGlobals::getBuildingInfo(BuildingTypes eBuildingNum)
{
	[B]FAssert(eBuildingNum > -1);[/B]
	FAssert(eBuildingNum < GC.getNumBuildingInfos());
	return *(m_paBuildingInfo[eBuildingNum]);
}

Then crashes. Any idea?

Edit: I know this is probably not much of a hint I can give here, but it be sad to have to remove this again as it works nicely as standalone modcomp. As I'm a noob I don't really know what even this assert means...

Edit2: debugging Call stack - any sense to get from this?
Code:
>	CvGameCoreDLL.dll!CvGlobals::getBuildingInfo(BuildingTypes eBuildingNum=NO_BUILDING)  Line 1944 + 0x3a	C++
 	CvGameCoreDLL.dll!CvGameTextMgr::fillObsoleteWithBuildingArray(bool * pabBuilding=0x34b9f9e8, int iItem=7, BuildingTypes eBuilding=69)  Line 10890 + 0x28	C++
 	CvGameCoreDLL.dll!CvGameTextMgr::setBuildingHelp(CvWStringBuffer & szBuffer={...}, BuildingTypes eBuilding=69, bool bCivilopediaText=false, bool bStrategyText=false, bool bTechChooserText=false, CvCity * pCity=0x3493a838)  Line 8673	C++
 	CvGameCoreDLL.dll!CvDLLWidgetData::parseConstructHelp(CvWidgetDataStruct & widgetDataStruct={...}, CvWStringBuffer & szBuffer={...})  Line 1754	C++
 	CvGameCoreDLL.dll!CvDLLWidgetData::parseHelp(CvWStringBuffer & szBuffer={...}, CvWidgetDataStruct & widgetDataStruct={...})  Line 80	C++
 	Civ4BeyondSword.exe!004e0505() 	
 	msvcr71.dll!7c3416f8() 	
 	msvcp71.dll!7c3a1ce3() 	
 	msvcp71.dll!7c3a1268() 	
 	ntdll.dll!7c92003d() 	
 	msvcr71.dll!7c34218a() 	
 	msvcr71.dll!7c34218f() 	
 	Civ4BeyondSword.exe!007938c4() 	
 	Civ4BeyondSword.exe!00493df0() 	
 	Civ4BeyondSword.exe!005943ef() 	
 	msvcp71.dll!7c3a1e88() 	
 	Civ4BeyondSword.exe!004e0488() 	
 	Civ4BeyondSword.exe!00580b28() 	
 	python24.dll!1e019b15() 	
 	Civ4BeyondSword.exe!004fe06f() 	
 	Civ4BeyondSword.exe!0073998b() 	
 	Civ4BeyondSword.exe!00739876() 	
 	boost_python-vc71-mt-1_32.dll!1000ea8d() 	
 	boost_python-vc71-mt-1_32.dll!1000eb45() 	
 	boost_python-vc71-mt-1_32.dll!100136c1() 	
 	CvGameCoreDLL.dll!boost::python::objects::pointer_holder<CvBuildingInfo *,CvBuildingInfo>::`scalar deleting destructor'()  + 0x14	C++
 	boost_python-vc71-mt-1_32.dll!1000ebd0() 	
 	python24.dll!1e0193cc() 	
 	python24.dll!1e026702() 	
 	python24.dll!1e02767e() 	
 	python24.dll!1e0293b7() 	
 	python24.dll!1e02645b() 	
 	python24.dll!1e02766c() 	
 	python24.dll!1e0293b7() 	
 	python24.dll!1e05e359() 	
 	python24.dll!1e02645b() 	
 	python24.dll!1e02766c() 	
 	python24.dll!1e0293b7() 	
 	python24.dll!1e029d49() 	
 	python24.dll!1e02a3bc() 	
 	python24.dll!1e05f62f() 	
 	python24.dll!1e0193cc() 	
 	python24.dll!1e0262a6() 	
 	python24.dll!1e0193a1() 	
 	Civ4BeyondSword.exe!00910386() 	
 	Civ4BeyondSword.exe!009103f4() 	
 	Civ4BeyondSword.exe!00910594() 	
 	Civ4BeyondSword.exe!004e5258() 	
 	msvcr71.dll!7c3416f8() 	
 	Civ4BeyondSword.exe!004093a9() 	
 	Civ4BeyondSword.exe!00522b48() 	
 	Civ4BeyondSword.exe!0051dd6f() 	
 	Civ4BeyondSword.exe!0041789e() 	
 	user32.dll!7e36940c() 	
 	kernel32.dll!7c83611f() 	
 	msvcr71.dll!7c34218f() 	
 	Civ4BeyondSword.exe!006b7c77() 	
 	Civ4BeyondSword.exe!0041372d() 	
 	msvcp71.dll!7c3a1e88() 	
 	Civ4BeyondSword.exe!006ba4a8() 	
 	Civ4BeyondSword.exe!004e9ac6() 	
 	Civ4BeyondSword.exe!0092bcdf() 	
 	kernel32.dll!7c817067()

Edit3: and while in debugging mode I get also the following exception:
Code:
Traceback (most recent call last):

  File "CvScreensInterface", line 709, in forceScreenRedraw

  File "CvMainInterface", line 719, in redraw

  File "CvMainInterface", line 1438, in updateSelectionButtons

RuntimeError: unidentifiable C++ exception
ERR: Python function forceScreenRedraw failed, module CvScreensInterface
Line 1438:
screen.appendMultiListButton( "BottomButtonContainer", gc.getBuildingInfo(eLoopBuilding).getButton(), iRow, WidgetTypes.WIDGET_CONSTRUCT, i, -1, False )
 
I would really like to help you, but I don't know exactly what's causing these crashes either. I can tell you the meaning of the Assert, though: For some reason, "getBuildingInfo" becomes called with the "eBuildingNum"-parameter < 0, which usually stands for NO_BUILDING. Civ4 returns NO_BUILDING if it can't find a match for a building name in the XML. You might try to find the function calling "getBuildingInfo" with this invalid parameter and take a look why this is happening. According to the debug log, the function in question might be "fillObsoleteWithBuildingArray". This could suggest that there is a typo in your XML somewhere in a tag like this under "BuildingClassType":

Code:
<ObsoleteBuildingClasses>
	<ObsoleteBuildingClass>
		<BuildingClassType>BUILDINGCLASS_A1</BuildingClassType>
		<bObsolete>1</bObsolete>
	</ObsoleteBuildingClass>
</ObsoleteBuildingClasses>

Edit: Just tried to change the BuildingClassType to something invalid and got an XML error while loading civ4. That's too early for being the same crash like yours. Hast to be something else then. I'll tell you, if I get an idea.

Edit2: Would you mind sending me your CIV4BuildingInfos.xml and CIV4BuildingClassInfos.xml? The debug log tells me the problem has maybe something to do with building 69 and building class 7.
 
I would really like to help you, but I don't know exactly what's causing these crashes either. I can tell you the meaning of the Assert, though: For some reason, "getBuildingInfo" becomes called with the "eBuildingNum"-parameter < 0, which usually stands for NO_BUILDING. Civ4 returns NO_BUILDING if it can't find a match for a building name in the XML. You might try to find the function calling "getBuildingInfo" with this invalid parameter and take a look why this is happening. According to the debug log, the function in question might be "fillObsoleteWithBuildingArray". This could suggest that there is a typo in your XML somewhere in a tag like this under "BuildingClassType":

Code:
<ObsoleteBuildingClasses>
	<ObsoleteBuildingClass>
	<BuildingClassType>BUILDINGCLASS_A1</BuildingClassType>
	<bObsolete>1</bObsolete>
</ObsoleteBuildingClass>

Edit: Just tried to change the BuildingClassType to something invalid and got an XML error while loading civ4. That's too early for being the same crash like yours. Hast to be something else then. I'll tell you, if I get an idea.

Edit2: Would you mind sending me your CIV4BuildingInfos.xml and CIV4BuildingClassInfos.xml? The debug log tells me the problem has maybe something to do with building 69 and building class 7.

I appreciate any help I can get, thx.
 

Attachments

No solution yet. The problem is, I can't reproduce the crash. I made a version of Obsolete Buildings (see attachment), which is using the following buildings: Walls, City Walls, High Walls, Castle and Citadel. I took them almost exactly as you are using them in your BuildingInfos and BuldingClassInfos files. Only removed the tech requirements and reduced the costs to "1" each. If I run the OB mod this way, everything works as intended. No crash.

Building 69 is the National Epic and BuildingClass 7 the Academy. Very strange, that the mod is crashing after calling fillObsoleteWithBuildingArray with these two type numbers as its parameters, as your debug call stack seems to indicate.

I'm running a bit out of ideas here. Seems this problem needs some more debugging before there is chance of getting it solved. Sorry.

By the way, to tell High Walls explicitly to obsolete Walls is not really necessary. The mod is deducing this information from the obsolete City Walls tag group by recursively looking which building class becomes obsolete through this building.

Edit: Forgot to mention, that I had to change the Art Defines of the buildings above too, to get the WH Debug version of OB to work properly. Primarily, because the art is not available for me anyway, but maybe the crash has something to do with a faulty button definition or so. Your edit3 made me think this and after all the crash is happening only, if you open the city screen. Did you try, what happens if you hover over the buildings in the civilopedia? Do you get the correct information then or is it crashing too?
 

Attachments

Thx for looking into it. Maybe it's a conflict between your code and the Fall From Heaven codebase I'm using that just doesn't produce an assert. I will make a merge with your mod and a version of FFH that doesn't rely on my owm xml mess to see if it's there or something in my other changes. If that doesn't crash it's probably my fault. If it crashes I'll just have to wait for someone with better skills than mine to make it work with FFH.;)
 
Ok it seems to be some incompatibility with FFH then. You get errors when trying to view the pedia for buildings and for wonders and you crash as soon you try to build a building or enter a city.

Steps to reproduce:
Download FFH and install:
http://forums.civfanatics.com/downloads.php?do=file&id=1&act=down
download and install patch e:
http://kael.civfanatics.net/files/FfH2031e.exe

Get the sourcecode:
http://kael.civfanatics.net/files/CvGameCoreDLL031e.zip

and here the changed files to replace where needed:
 

Attachments

Back
Top Bottom