Building happiness change bug

SadoMacho

spanker of civilizations
Joined
Aug 15, 2006
Messages
811
Location
Flanders, Belgium
I was making a MOD with new civics and I used theBuildinghappinesschange options like in the standard civic 'nationhood' where barracks get +2 :) . I noticed that this is only possible for standard buildings and not for the unique buildings. In the standard CIV IV Warlords the Ikhanda (= zulu barracks) doesn't get the +2 :) under nationhood.

In the same way, I can't give extra : to unique building, unless you code the standard and the unique building, so it appears in the civic screen.

Example :
give walls +1 :)
=> celtic dun doesn't get this.

Give walls and celtic dun +1:
=> in civic screen +1 :) for walls and dun appears for all civs.

Is this a bug?
If it is, will Firaxis do something about it?
If it isn't, how can I code this more ellegantly?
 
The Ikhanda not giving happiness under nationhood has to be a bug.
 
I was making a MOD with new civics and I used theBuildinghappinesschange options like in the standard civic 'nationhood' where barracks get +2 :) . I noticed that this is only possible for standard buildings and not for the unique buildings. In the standard CIV IV Warlords the Ikhanda (= zulu barracks) doesn't get the +2 :) under nationhood.

In the same way, I can't give extra : to unique building, unless you code the standard and the unique building, so it appears in the civic screen.

Example :
give walls +1 :)
=> celtic dun doesn't get this.

Give walls and celtic dun +1:
=> in civic screen +1 :) for walls and dun appears for all civs.

Is this a bug?
If it is, will Firaxis do something about it?
If it isn't, how can I code this more ellegantly?

This is a real bug. I checked the SDK code, and found the error there. Currently, Nationhood does not give its bonus to Zulu Ikhanda.

There are two ways to fix this:
(1) Change the defintion so that in XML, a building class, not a building type is specified. This would be a huge change, would invalidate a lot of existing mods, and requires significant XML, Python and XML changes.
(2) Change the XML to specify Ikhanda as well as Barracks and change the SDK to display the correct thing. I will specify the code changes needed to make this fix, as it is much less disruptive (albeit harder for a mod coder to get right).

First, change Civ4CivicInfos.xml, lines 575-584 to the following, by adding the Ikhanda:
Code:
<BuildingHappinessChanges>
	<BuildingHappinessChange>
		<BuildingType>BUILDING_BARRACKS</BuildingType>
		<iHappinessChange>2</iHappinessChange>
	</BuildingHappinessChange>
	[B]<BuildingHappinessChange>
		<BuildingType>BUILDING_ZULU_IKHANDA</BuildingType>
		<iHappinessChange>2</iHappinessChange>
	</BuildingHappinessChange>[/B]
</BuildingHappinessChanges>

This will cause the game to behave properly, although it will have the following display 'bug':
nationhoodfixed.jpg


and this as well:
nationhoodbug.jpg


Note, there is also the same bug in the SDK with buildings that have BuildingHappinessChanges. (There are no such buildings in the default XML, but if you add some, then the same display bug will occur). In the following picture, you can see the bug where Monuments are changed so that they give +1 happy if you build a forge (or mint). (Note, BuildingHappinessChanges for buildings are global, so building one affects every city, this makes this example not very realistic, but it would make sense if someone created civilization specific wonders...)
Spoiler example changes, this is not a fix, Civ4Buildinginfos.xml replace line 5404 with: :
Code:
<BuildingHappinessChanges>
	<BuildingHappinessChange>
		<BuildingType>BUILDING_FORGE</BuildingType>
		<iHappinessChange>1</iHappinessChange>
	</BuildingHappinessChange>
	<BuildingHappinessChange>
		<BuildingType>BUILDING_MALI_MINT</BuildingType>
		<iHappinessChange>1</iHappinessChange>
	</BuildingHappinessChange>
</BuildingHappinessChanges>
buildingextrabuildinghappinessbug.jpg



You need to SDK changes to fix the bugs:

in CvGameTextMgr:: parseCivicInfo, CvGameTextMgr.cpp, lines 3336-3343:
Spoiler old code :
Code:
//	Building Happiness
for (iI = 0; iI < GC.getNumBuildingInfos(); iI++)
{
	if (GC.getCivicInfo(eCivic).getBuildingHappinessChanges(iI) != 0)
	{
		szHelpText += NEWLINE + gDLL->getText("TXT_KEY_CIVIC_BUILDING_HAPPINESS", GC.getCivicInfo(eCivic).getBuildingHappinessChanges(iI), ((GC.getCivicInfo(eCivic).getBuildingHappinessChanges(iI) > 0) ? gDLL->getSymbolID(HAPPY_CHAR) : gDLL->getSymbolID(UNHAPPY_CHAR)), GC.getBuildingInfo((BuildingTypes)iI).getTextKeyWide());
	}
}
fix:
Code:
//	Building Happiness
for (iI = 0; iI < GC.getNumBuildingInfos(); iI++)
{
	if (GC.getCivicInfo(eCivic).getBuildingHappinessChanges(iI) != 0)
	{
		[B]// make sure this building is valid for this player (so we do not list class buildings twice)
		PlayerTypes ePlayer = bPlayerContext ? GC.getGameINLINE().getActivePlayer() : NO_PLAYER;
		BuildingClassTypes eLoopBuildingClass = (BuildingClassTypes)GC.getBuildingInfo((BuildingTypes)iI).getBuildingClassType();
		if (ePlayer == NO_PLAYER || iI == GC.getCivilizationInfo(GET_PLAYER(ePlayer).getCivilizationType()).getCivilizationBuildings(eLoopBuildingClass))
		{[/B]
			szHelpText += NEWLINE + gDLL->getText("TXT_KEY_CIVIC_BUILDING_HAPPINESS", GC.getCivicInfo(eCivic).getBuildingHappinessChanges(iI), ((GC.getCivicInfo(eCivic).getBuildingHappinessChanges(iI) > 0) ? gDLL->getSymbolID(HAPPY_CHAR) : gDLL->getSymbolID(UNHAPPY_CHAR)), GC.getBuildingInfo((BuildingTypes)iI).getTextKeyWide());
		}
	}
}

in CvGameTextMgr::setBuildingHelp , CvGameTextMgr.cpp, lines 5197-5208:
Spoiler old code :
Code:
for (iI = 0; iI < GC.getNumBuildingInfos(); iI++)
{
	if (GC.getBuildingInfo(eBuilding).getBuildingHappinessChanges(iI) != 0)
	{
		szTempBuffer.Format(L"&#37;s%s", NEWLINE, gDLL->getText("TXT_KEY_BUILDING_HAPPINESS_CHANGE", GC.getBuildingInfo(eBuilding).getBuildingHappinessChanges(iI),
			((GC.getBuildingInfo(eBuilding).getBuildingHappinessChanges(iI) > 0) ? gDLL->getSymbolID(HAPPY_CHAR) : gDLL->getSymbolID(UNHAPPY_CHAR))).c_str());
		CvWString szBuilding;
		szBuilding.Format(L"<link=literal>%s</link>", GC.getBuildingInfo((BuildingTypes)iI).getDescription());
		setListHelp(szBuffer, szTempBuffer, szBuilding, L", ", (GC.getBuildingInfo(eBuilding).getBuildingHappinessChanges(iI) != iLast));
		iLast = GC.getBuildingInfo(eBuilding).getBuildingHappinessChanges(iI);
	}
}
fix:
Code:
for (iI = 0; iI < GC.getNumBuildingInfos(); iI++)
{
	if (GC.getBuildingInfo(eBuilding).getBuildingHappinessChanges(iI) != 0)
	{
		[B]// make sure this building is valid for this player (so we do not list class buildings twice)
		BuildingClassTypes eLoopBuildingClass = (BuildingClassTypes)GC.getBuildingInfo((BuildingTypes)iI).getBuildingClassType();
		if (ePlayer == NO_PLAYER || iI == GC.getCivilizationInfo(GET_PLAYER(ePlayer).getCivilizationType()).getCivilizationBuildings(eLoopBuildingClass))
		{[/B]
			szTempBuffer.Format(L"%s%s", NEWLINE, gDLL->getText("TXT_KEY_BUILDING_HAPPINESS_CHANGE", GC.getBuildingInfo(eBuilding).getBuildingHappinessChanges(iI),
				((GC.getBuildingInfo(eBuilding).getBuildingHappinessChanges(iI) > 0) ? gDLL->getSymbolID(HAPPY_CHAR) : gDLL->getSymbolID(UNHAPPY_CHAR))).c_str());
			CvWString szBuilding;
			szBuilding.Format(L"<link=literal>%s</link>", GC.getBuildingInfo((BuildingTypes)iI).getDescription());
			setListHelp(szBuffer, szTempBuffer, szBuilding, L", ", (GC.getBuildingInfo(eBuilding).getBuildingHappinessChanges(iI) != iLast));
			iLast = GC.getBuildingInfo(eBuilding).getBuildingHappinessChanges(iI);
		}
	}
}

and the result is (from the perspective of the UB user):
nationhoodfixedSDK.jpg

and
monumentmintgiveshappy.jpg


-Iustus
 
The XML way to solve this, I figured out myself; but it doesn't look nice, does it.
The SDK way look great.
Thx for the help!

The point is you need to make the XML fix first. That will actually make the gameplay be correct.

Changing the SDK will make the display be correct, but it will not solve the XML bug which is causing the Zulu to get a smaller bonus from Nationhood.

-Iustus
 
Back
Top Bottom