Tempermental DLL?

lemonjelly

Modding For Ethne
Joined
Jan 5, 2008
Messages
864
Location
UK
In my DLL, I've merged a few things, with no problems at all, until recently, where my DLL has became increasingly temperamental.

Some code breaks the game, sometimes rebuilding the DLL fixes it, but usually I just have to revert my changes, completely rebuild the DLL several times until it starts working again, and then carry on.

The DLL always breaks at one point, when you found your city, after you've named it, and before the build menu appears.
A debug DLL points to
Code:
CvPromotionInfo& CvGlobals::getPromotionInfo(PromotionTypes ePromotionNum)
{
	FAssert(ePromotionNum > -1);
	FAssert(ePromotionNum < GC.getNumPromotionInfos());
	return *(m_paPromotionInfo[ePromotionNum]);
}
And says that ePromotionNum is in the far minuses, yet I've never touched promotions yet, the code that breaks it could be in CvCityInfos.cpp, or even building the DLL with the Better AI debug log flag.

I really have no idea what's going on, but it's almost impossible to determine whether my code is broken, or whether my DLL is playing up, when I'm adding new stuff, which, understandably is a massive problem.

All the sources are here, I'd really appreciate it if somebody could look at it for me.
 
So, I get this popup:
Code:
Assert Failed

File:  CvGlobals.cpp
Line:  2281
Expression:  ePromotionNum > -1
Message:  

----------------------------------------------------------

I click Debug, it takes me to VS2010, where it says Civ4BtS has triggered a breakpoint, I click Break, it takes me to the red line:

Code:
CvPromotionInfo& CvGlobals::getPromotionInfo(PromotionTypes ePromotionNum)
{
	[COLOR="Red"]FAssert(ePromotionNum > -1);[/COLOR]
	FAssert(ePromotionNum < GC.getNumPromotionInfos());
	return *(m_paPromotionInfo[ePromotionNum]);
}

ePromotion is listed as having a value of -1163005939 in the Autos screen, then in the Call Stack, I get:

Spoiler :
Code:
>	CvGameCoreDLL.dll!CvGlobals::getPromotionInfo(PromotionTypes ePromotionNum=-1163005939)  Line 2281 + 0x36 bytes	C++
 	CvGameCoreDLL.dll!CvGameTextMgr::parsePromotionHelp(CvWStringBuffer & szBuffer={...}, PromotionTypes ePromotion=-1163005939, const unsigned short * pcNewline=0x04ee2838)  Line 4993 + 0x10 bytes	C++
 	CvGameCoreDLL.dll!CvGameTextMgr::setBasicUnitHelp(CvWStringBuffer & szBuffer={...}, UnitTypes eUnit=11, bool bCivilopediaText=false)  Line 7235	C++
 	CvGameCoreDLL.dll!CvGameTextMgr::setUnitHelp(CvWStringBuffer & szBuffer={...}, UnitTypes eUnit=11, bool bCivilopediaText=false, bool bStrategyText=true, bool bTechChooserText=false, CvCity * pCity=0x1b945808)  Line 8080	C++
 	CvGameCoreDLL.dll!CvDLLWidgetData::parseTrainHelp(CvWidgetDataStruct & widgetDataStruct={...}, CvWStringBuffer & szBuffer={...})  Line 1751	C++
 	CvGameCoreDLL.dll!CvDLLWidgetData::parseHelp(CvWStringBuffer & szBuffer={...}, CvWidgetDataStruct & widgetDataStruct={...})  Line 77	C++
 	Civ4BeyondSword.exe!004d0755() 	
 	[Frames below may be incorrect and/or missing, no symbols loaded for Civ4BeyondSword.exe]	
 	kernel32.dll!75f114dd() 	
 	msvcr71.dll!7c34218a() 	
 	CvGameCoreDLL.dll!CvPlayer::getUnitButton(UnitTypes eUnit=-1163005939)  Line 3435 + 0xb bytes	C++
 	baadf000()

But I've not touched anything in promotions, nor their help tags, or anything.
 
It seems that the leader promotion for unit 11 (the 12th in UnitInfos xml) is not initialized properly, or actually not initialized at all (its value is -1163005939 == 0xBAADF00D which is assigned automatically to unused memory when debugging).
 
So, the XML is
Code:
			<LeaderPromotion>PROMOTION_LEADER</LeaderPromotion>
			<iLeaderExperience>20</iLeaderExperience>

And that promotion is
Code:
		<PromotionInfo>
			<Type>PROMOTION_LEADER</Type>
			<Description>TXT_KEY_PROMOTION_GREAT_GENERAL</Description>
			<Sound>AS2D_IF_LEVELUP</Sound>
			<bLeader>1</bLeader>
			<iUpgradeDiscount>100</iUpgradeDiscount>
			<UnitCombats>
				<UnitCombat>
					<UnitCombatType>UNITCOMBAT_SURVEY</UnitCombatType>
					<bUnitCombat>1</bUnitCombat>
				</UnitCombat>
				<UnitCombat>
					<UnitCombatType>UNITCOMBAT_ROLLERS</UnitCombatType>
					<bUnitCombat>1</bUnitCombat>
				</UnitCombat>
				<UnitCombat>
					<UnitCombatType>UNITCOMBAT_ASTROINFANTRY</UnitCombatType>
					<bUnitCombat>1</bUnitCombat>
				</UnitCombat>
				<UnitCombat>
					<UnitCombatType>UNITCOMBAT_SPACESHIP</UnitCombatType>
					<bUnitCombat>1</bUnitCombat>
				</UnitCombat>
				<UnitCombat>
					<UnitCombatType>UNITCOMBAT_FLOATERS</UnitCombatType>
					<bUnitCombat>1</bUnitCombat>
				</UnitCombat>
				<UnitCombat>
					<UnitCombatType>UNITCOMBAT_BATTLE_DRONE</UnitCombatType>
					<bUnitCombat>1</bUnitCombat>
				</UnitCombat>
			</UnitCombats>
			<Button>,Art/Interface/Buttons/Promotions/Combat5.dds,Art/Interface/Buttons/Warlords_Atlas_1.dds,5,10</Button>
		</PromotionInfo>
I fail to see where the error is :(

Also, how did you work that out from the horrible mess of messages?
Stuff like this would be interesting to know :)

EDIT:
Oh, I see where it says unit 11 now, but how did you know it was the leader promotion?
And, do you have any idea why sometimes it loads perfectly fine?
 
Well, in the callstack you can see that parsePromotionHelp() is called directly from setBasicUnitHelp(). Unless I missed anything (which is really really possible), there is only one place where parsePromotionHelp() is called from setBasicUnitHelp(), which is the promotion leader.

I don't really know what happens there :dunno:
And I don't really have the time to debug it myself. Sorry. But you can try, if you want. Try debugging the loading of the relevant unit info, for example.
 
I tried removing all Leader Promotion tags, and I still get the error, which is strange, but if I remove it from that unit, it tells me the error is on Unit 0, so the first unit, which is a settler, which doesn't have that tag set at all.

If I remove that tag from the schema, will I seriously break things, or will Civ just skip that tag?

EDIT:
I removed the LeaderPromotion and iLeaderExperience from the DLL, leaving the canLead ect bits to return 0 or false, and I compiled, and it works perfectly, even fixing the lag I got between city name popup and build queue.
I've got no idea why this code causes issues, and it's probably going to break the AI or something, but, until I can find out why the code broke, I'll leave it like this.
 
Removing these breaks Warlords functionality - a warlord will not grant XP and special promotions. And it might even break the ability of a GG to become a warlord.

Is unit 11 supposed to become a warlord? Because otherwise its LeaderPromotion is supposed to be NONE.
 
Yeah, I know, which sucks, but I've never used a warlord, they don't seem too common.

Unit 11 is the Great General, so it's correct to have it :)
 
It still seems weird to me. There must be a problem somewhere. But I guess that depends on how much time you can invest in finding it.
 
Yeah, but it's a strange problem, which only triggers sometimes, I've got no idea what's wrong, but since I've commented out that crash, I've added loads more code, and I've not had any problems, apart from any unit being able to take the "Lead by Great General" promotion, which is just because I've been too lazy to delete that promotion.
 
Back
Top Bottom