Culture from Non State Trait

phungus420

Deity
Joined
Mar 1, 2003
Messages
6,296
So I'm trying to add an ability to receive culture from non state religions as an effect of a trait. I have working code (supplied by Tsentom1 :)) that does this, however it is flawed: It doesn't display the information in the city screen. While I'm glad to have the effect functioning, I need it to display properly.

I'm kind of wondering where I should start here. But here is something that looks promising to me:

From CvCity.cpp

Code:
	if ((GET_PLAYER(getOwnerINLINE()).getStateReligion() == eReligion) || (GET_PLAYER(getOwnerINLINE()).getStateReligion() == NO_RELIGION))
	{
		if (isHasReligion(eReligion))
		{
			iCommerce += GC.getReligionInfo(eReligion).getStateReligionCommerce(eIndex);

			if (isHolyCity(eReligion))
			{
				iCommerce += GC.getReligionInfo(eReligion).getHolyCityCommerce(eIndex);
			}
		}
	}

Am I correct in assuming this is where the code is screening out Non State religion "commerce"? Further down it looks like this is then converted to culture, I think this is the right spot.

Any ideas on how to add in an: if getPlayer - gettagIwillcreateinTraitinfos ; Don't screen out non state
function?

I'm going to reread Xieno's tutorial on adding a boolean tag, but I'm pretty sure I understand that, I'm interested in once I get a tag in there, how to get it to function.
 
You're on the right track. Just a clarification: :gold:, :science:, :culture:, and :espionage: are the four CommerceTypes, so having it call it iCommerce is not unusual given that the function is calculating the value of the eIndex'th type of commerce earned by the religion.

That hints at one issue: if you check for the trait here, make sure that either

a) you want the trait to allow any commerce from non-state religions, or
b) you check that eIndex is :culture: as well.

Given that the normal game doesn't give any non-:culture: commerce from religions, I'll go with (a) above. I think the best way to handle this is to add a function on CvPlayer that returns true if they have the trait rather than checking for the trait itself. How about "NonStateReligionCommerce"?

Code:
if ((GET_PLAYER(getOwnerINLINE()).getStateReligion() == eReligion) 
    || (GET_PLAYER(getOwnerINLINE()).getStateReligion() == NO_RELIGION) 
    [B]|| (GET_PLAYER(getOwnerINLINE()).isNonStateReligionCommerce())[/B])
...

and in CvPlayer:

Code:
void CvPlayer::init(PlayerTypes eID)
{
    ...
    if (hasTrait((TraitTypes)iI))
    {
        setNonStateReligionCommerce(GC.getTraitInfo((TraitTypes)iI).isNonStateReligionCommerce());
        ...
}

bool CvPlayer::isNonStateReligionCommerce() const
{
    return m_bNonStateReligionCommerce;
}

void CvPlayer::setNonStateReligionCommerce(bool bNewValue)
{
    if (m_bNonStateReligionCommerce != bNewValue)
    {
        m_bNonStateReligionCommerce = bNewValue;
        updateReligionCommerce();
        AI_makeAssignWorkDirty();
    }
}

You'll also need to call setNonStateReligionCommerce() in CvPlayer::init() and load/save the bNonStateReligionCommerce field with the player.
 
After building a debug build, which required building an entire new gamecore, the crash went away. So aparently when adding a new tag to the XML you are forced to recompile an entire new core, instead of just compiling a new object file?
That makes things take a lot longer, takes about an hour and a half to compile a whole new gamecore on my machine :(

Will I need to make an entire new dll from scratch when I add in the functionality as well?


Well, I haven't even been able to start working on those nuts and bolts yet... Something is messing up with just adding the tag to TraitInfos. I've followed Xeino's directions to the T, tried them mulitiple times, and while it compiles fine, I get a crash while loading XML. I'm certain it's not a XML schema issue, as without the SDK changes I don't get a crash, and when I try to remove the Schema and tags after trying the new dll, I still get a crash.

As per the tutorial found in: An Idiot's Guide to the dll -Adding a boolean tag to the XML

These are the steps I have taken:
1)Added XML schema information, tested, no crash, game plays fine with non functional tags in place.

2)Opened up CvInfos.h
-Searched for CvTraitInfo
-followed directions and added:
Spoiler :
Code:
...
	DllExport int getMaxTeamBuildingProductionModifier() const;				// Exposed to Python
	DllExport int getMaxPlayerBuildingProductionModifier() const;				// Exposed to Python
	[B]bool isNonStateReligionCommerce() const;//phungus -Enlightened[/B]

	DllExport const TCHAR* getShortDescription() const;				// Exposed to Python
	void setShortDescription(const TCHAR* szVal);
&
Code:
...
	int m_iMaxTeamBuildingProductionModifier;		
	int m_iMaxPlayerBuildingProductionModifier;
	[B]bool m_bNonStateReligionCommerce; //phungus -Enlightened[/B]

	CvString m_szShortDescription;
To CvInfos.h

3)Opened up CvInfos.cpp
-Searched for CvTraitInfo and added:
Code:
...
m_iMaxTeamBuildingProductionModifier(0),		
m_iMaxPlayerBuildingProductionModifier(0),
[B]m_bNonStateReligionCommerce(false), //phungus -Enlightened[/B]
m_paiExtraYieldThreshold(NULL),
and
Code:
...
int CvTraitInfo::getMaxPlayerBuildingProductionModifier() const	
{
	return m_iMaxPlayerBuildingProductionModifier; 
}

[B]bool CvTraitInfo::isNonStateReligionCommerce() const	//phungus -Enlightened
{
	return m_bNonStateReligionCommerce; 
}[/B]

const TCHAR* CvTraitInfo::getShortDescription() const
and
Code:
...
	pXML->GetChildXmlValByName(&m_iMaxTeamBuildingProductionModifier, "iMaxTeamBuildingProductionModifier");
	pXML->GetChildXmlValByName(&m_iMaxPlayerBuildingProductionModifier, "iMaxPlayerBuildingProductionModifier");
[B]	pXML->GetChildXmlValByName(&m_bNonStateReligionCommerce, "bNonStateReligionCommerce"); //phungus -Enlightened[/B]

	if (gDLL->getXMLIFace()->SetToChildByTagName(pXML->GetXML(), "ExtraYieldThresholds"))

Also this is the schema changes:
Code:
...
	<ElementType name="iMaxPlayerBuildingProductionModifier" content="textOnly" dt:type="int"/>
	<ElementType name="bNonStateReligionCommerce" content="textOnly" dt:type="boolean"/>
	<ElementType name="iExtraYieldThreshold" content="textOnly" dt:type="int"/>
Code:
...
		<element type="iMaxTeamBuildingProductionModifier"/>
		<element type="iMaxPlayerBuildingProductionModifier"/>
		<element type="bNonStateReligionCommerce" minOccurs="0"/>
		<element type="ExtraYieldThresholds"/>

I've done this about 7 times now, just hoping I was creating a typo somewhere, but can't find anything. Like I said compiles fine, just crashes when initializing XML. Also nothing in the error logs worth mentioning. What am I doing wrong here?
 
You'll also need to call setNonStateReligionCommerce() in CvPlayer::init() and load/save the bNonStateReligionCommerce field with the player.
I'm more then a little confused by this, but I'll work off of what I know, and maybe this is what you mean :crazyeye:

So I'm using a new entity in CvPlayer, namely:
setNonStateReligionCommerce()
So I need to create this in CvPlayer.h correct?
For a boolean we use: bool isWhateverICall() const;

But for setNonStateReligionCommerce(), I"m not positive this is a boolean... Is it? do I just set it up the same way in CvPlayer.h as I did the isNonStateReligionCommerce() call?

As far as load/saving bNonStatReligionCommerce in player, doesn't CvPlayer automatically have access to all the trait tags anyway? Or am I way off on what you are getting at?
 
OK, so after getting some help from Snarko, it almost compiled, here is what I have (after the steps covered above in post #3 for setting up the tag originally in the XML)

CvPlayer.h

Spoiler :
Code:
	//phungus -Enlightened
	bool isNonStateReligionCommerce() const;
	void setNonStateReligionCommerce(bool bNewValue);	
	//phungus -End
...

	bool m_bNonStateReligionCommerce;	//phungus -Enlightened

CvPlayer.cpp
Code:
			if (hasTrait((TraitTypes)iI))
			{
				setNonStateReligionCommerce(GC.getTraitInfo((TraitTypes)iI).isNonStateReligionCommerce());//phungus -Enlightened

...
	m_bNonStateReligionCommerce =false;	//phungus -Enlightened

...
	pStream->Read(&m_bNonStateReligionCommerce);	//phungus -Enlightened

...
	pStream->Write(m_bNonStateReligionCommerce); //phungus -Enlightened

After it compiles and starts linking the object files, I get this error:

Code:
1>   Creating library Final_Release\CvGameCoreDLL.lib and object Final_Release\CvGameCoreDLL.exp
1>CvPlayer.obj : error LNK2019: unresolved external symbol "public: void __thiscall CvPlayer::setNonStateReligionCommerce(bool)" (?setNonStateReligionCommerce@CvPlayer@@QAEX_N@Z) referenced in function "public: void __thiscall CvPlayer::init(enum PlayerTypes)" (?init@CvPlayer@@QAEXW4PlayerTypes@@@Z)
1>Final_Release\CvGameCoreDLL.dll : fatal error LNK1120: 1 unresolved externals
1>NMAKE : fatal error U1077: '"C:\Program Files\Microsoft Visual C++ Toolkit 2003/bin/link.exe"' : return code '0x460'
1>Stop.

:confused:

Edit: I have tried an entirely fresh recompile, and get a similar error (actually it causes 2 errors now, instead of 1)
Code:
1> "C:\Program Files\Microsoft Visual C++ Toolkit 2003/bin/link.exe" /dll /nologo  /LIBPATH:Python24/libs /LIBPATH:boost-1.32.0/libs/ /LIBPATH:"C:\Program Files\Microsoft Visual C++ Toolkit 2003/lib" /LIBPATH:"C:\Program Files\Microsoft Platform SDK/Lib" /out:Final_Release\CvGameCoreDLL.dll  boost_python-vc71-mt-1_32.lib winmm.lib user32.lib  Final_Release\CvArea.obj Final_Release\CvArtFileMgr.obj Final_Release\CvCity.obj Final_Release\CvCityAI.obj Final_Release\CvDLLButtonPopup.obj Final_Release\CvDLLEntity.obj Final_Release\CvDLLPython.obj Final_Release\CvDLLWidgetData.obj Final_Release\CvDeal.obj Final_Release\CvDiploParameters.obj Final_Release\CvFractal.obj Final_Release\CvGame.obj Final_Release\CvGameAI.obj Final_Release\CvGameCoreDLL.obj Final_Release\CvGameCoreUtils.obj Final_Release\CvGameInterface.obj Final_Release\CvGameTextMgr.obj Final_Release\CvGlobals.obj Final_Release\CvHallOfFameInfo.obj Final_Release\CvInfoWater.obj Final_Release\CvInfos.obj Final_Release\CvInitCore.obj Final_Release\CvMap.obj Final_Release\CvMapGenerator.obj Final_Release\CvPlayer.obj Final_Release\CvPlayerAI.obj Final_Release\CvPlot.obj Final_Release\CvPlotGroup.obj Final_Release\CvPopupInfo.obj Final_Release\CvPopupReturn.obj Final_Release\CvRandom.obj Final_Release\CvReplayInfo.obj Final_Release\CvReplayMessage.obj Final_Release\CvSelectionGroup.obj Final_Release\CvSelectionGroupAI.obj Final_Release\CvStructs.obj Final_Release\CvTalkingHeadMessage.obj Final_Release\CvTeam.obj Final_Release\CvTeamAI.obj Final_Release\CvUnit.obj Final_Release\CvUnitAI.obj Final_Release\CvXMLLoadUtility.obj Final_Release\CvXMLLoadUtilityGet.obj Final_Release\CvXMLLoadUtilityInit.obj Final_Release\CvXMLLoadUtilitySet.obj Final_Release\CyArea.obj Final_Release\CyAreaInterface.obj Final_Release\CyArgsList.obj Final_Release\CyArtFileMgr.obj Final_Release\CyArtFileMgrInterface.obj Final_Release\CyCity.obj Final_Release\CyCityInterface1.obj Final_Release\CyCityInterface2.obj Final_Release\CyDeal.obj Final_Release\CyEnumsInterface.obj Final_Release\CyGame.obj Final_Release\CyGameCoreUtils.obj Final_Release\CyGameCoreUtilsInterface.obj Final_Release\CyGameInterface.obj Final_Release\CyGameTextMgr.obj Final_Release\CyGameTextMgrInterface.obj Final_Release\CyGlobalContext.obj Final_Release\CyGlobalContextInterface1.obj Final_Release\CyGlobalContextInterface2.obj Final_Release\CyGlobalContextInterface3.obj Final_Release\CyGlobalContextInterface4.obj Final_Release\CyHallOfFameInfo.obj Final_Release\CyHallOfFameInterface.obj Final_Release\CyInfoInterface1.obj Final_Release\CyInfoInterface2.obj Final_Release\CyInfoInterface3.obj Final_Release\CyMap.obj Final_Release\CyMapGenerator.obj Final_Release\CyMapGeneratorInterface.obj Final_Release\CyMapInterface.obj Final_Release\CyPlayer.obj Final_Release\CyPlayerInterface1.obj Final_Release\CyPlayerInterface2.obj Final_Release\CyPlot.obj Final_Release\CyPlotInterface1.obj Final_Release\CyRandomInterface.obj Final_Release\CyReplayInfo.obj Final_Release\CySelectionGroup.obj Final_Release\CySelectionGroupInterface.obj Final_Release\CyStructsInterface1.obj Final_Release\CyTeam.obj Final_Release\CyTeamInterface.obj Final_Release\CyUnit.obj Final_Release\CyUnitInterface1.obj Final_Release\FAssert.obj Final_Release\FDialogTemplate.obj Final_Release\_precompile.obj   /debug /INCREMENTAL:NO /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF 
1>   Creating library Final_Release\CvGameCoreDLL.lib and object Final_Release\CvGameCoreDLL.exp
1>CvCity.obj : error LNK2019: unresolved external symbol "public: bool __thiscall CvPlayer::isNonStateReligionCommerce(void)const " (?isNonStateReligionCommerce@CvPlayer@@QBE_NXZ) referenced in function "public: int __thiscall CvCity::getReligionCommerceByReligion(enum CommerceTypes,enum ReligionTypes)const " (?getReligionCommerceByReligion@CvCity@@QBEHW4CommerceTypes@@W4ReligionTypes@@@Z)
1>CvPlayer.obj : error LNK2019: unresolved external symbol "public: void __thiscall CvPlayer::setNonStateReligionCommerce(bool)" (?setNonStateReligionCommerce@CvPlayer@@QAEX_N@Z) referenced in function "public: void __thiscall CvPlayer::init(enum PlayerTypes)" (?init@CvPlayer@@QAEXW4PlayerTypes@@@Z)
1>Final_Release\CvGameCoreDLL.dll : fatal error LNK1120: 2 unresolved externals



Nevermind, just missed a crucial part of EF's code. It compiles now. Time to test it.
 
:goodjob: Nice Emperor Fool, and thanks Snarko. It works, still one minor problem though, while it displays in the culture bar, it's not picking up in the religion icons at the top of the city screen. Any chance this is related to BUG, and does anyone know where the Culture/happiness display for religions in the top part of the city screen is handled?

Edit:
Might this be it:
Code:
	if (eStateReligion == eReligion || eStateReligion == NO_RELIGION || bForceState)
	{
		for (i = 0; i < NUM_COMMERCE_TYPES; i++)
		{
			iCommerce = GC.getReligionInfo(eReligion).getStateReligionCommerce((CommerceTypes)i);

			if (pCity->isHolyCity(eReligion))
			{
				iCommerce += GC.getReligionInfo(eReligion).getHolyCityCommerce((CommerceTypes)i);
			}

			if (iCommerce != 0)
			{
				if (bHandled)
				{
					szBuffer.append(L", ");
				}

				szTempBuffer.Format(L"%s%d%c", iCommerce > 0 ? "+" : "", iCommerce, GC.getCommerceInfo((CommerceTypes)i).getChar());
				szBuffer.append(szTempBuffer);
				bHandled = true;
			}
		}
	}
 
If you are asking about text displayed in a hover, it's not BUG. These are all produced by CvTextMgr.cpp. Which hover: the commerce ones next to the sliders or the religion ones in the top-right (if they have hovers, I don't recall)?

But yes, that code you posted does check that they have no state religion or the one in question. You need to add a call to isNonStateReligionCommerce() here.
 
I'm still very new at this, so don't quite understand where or how to start. So does this mean I have to establish the bool isNonStateReligionCommerce() const;? Also seems odd, I can't find any GetPlayerOnline() calls in gametext manager, so how do I get it to call the player's traits?

Edit: Yeah, when I tried:
if (eStateReligion == eReligion || eStateReligion == NO_RELIGION || (GET_PLAYER(getOwnerINLINE()).isNonStateReligionCommerce()) || bForceState)
Like before for CvCity, it throws an error saying it doesn't know what getOwnerINLINE() is
:(
 
Does this mean I have to establish the bool isNonStateReligionCommerce() const;?

Yes, you need to add this function to CvPlayer. I had that code in my original post, and I think later you said you added the correct declarations to CvPlayer.h. So I don't understand what your question above is. If it relates to the edit you had below it, then yes you are doing it almost right.

It doesn't know what getOwnerINLINE() is

That's because getOwnerINLINE() is a function on CvCity. In this function on CvGameTextMgr, you have pCity which is the CvCity object of interest.

Code:
if (eStateReligion == eReligion || eStateReligion == NO_RELIGION || (GET_PLAYER([B]pCity->[/B]getOwnerINLINE()).isNonStateReligionCommerce()) || bForceState)
 
You Rock EF :cheers:

So, just for clarification, what's going on here pCity->getOwnerINLINE() is that since the object pCity exists in CvGameTextManager but the function getOwnerINLINE() doesn't, you can call any function from the City Object file in CvGameTextManager by calling it through the object CvGameTextManager recognizes without the need of defining the function in CvGameTextManager? Is this a pointer? And is that how it works?

For the next thing I'm trying to do, at first I thought it would be simple after seeing the code, but I failed. I'm trying to double the price of a unit upgrade if the unitCombat type changes. This is what I tried:
Code:
	iPrice = GC.getDefineINT("BASE_UNIT_UPGRADE_COST");

	iPrice += (std::max(0, (GET_PLAYER(getOwnerINLINE()).getProductionNeeded(eUnit) - GET_PLAYER(getOwnerINLINE()).getProductionNeeded(getUnitType()))) * GC.getDefineINT("UNIT_UPGRADE_COST_PER_PRODUCTION"));
	//phungus ChangeUnitCombatUpgradePrice
		if ( (GET_PLAYER(getOwnerINLINE()).getUnitCombatType(eUnit)) != GET_PLAYER(getOwnerINLINE()).getUnitCombatType(getUnitType()) )
		{
		iPrice *= 2;
		}
	//phungus end
The error the compiler gives is that getUnitCombatType is not a member of CvPlayerAI
 
So, just for clarification, what's going on here pCity->getOwnerINLINE() is that since the object pCity exists in CvGameTextManager but the function getOwnerINLINE() doesn't, you can call any function from the City Object file in CvGameTextManager by calling it through the object CvGameTextManager recognizes without the need of defining the function in CvGameTextManager? Is this a pointer? And is that how it works?

Yes, pCity is a pointer to a CvCity object. The files CvCity.h/cpp define a class with data and functions. But the class by itself doesn't do anything; it's like an idea. Similarly, a car is an idea describing a 4-wheel vehicle with an engine, steering wheel, gears, etc. You cannot drive a "car".

You need an actual car, in C++ terms a Car object or "instance" such as the 1984 Honda Accord 4-door with license plate 1CIV4989. The pCity pointer is akin to referring to that car as "my car". I can "drive my car" and "wash my car", etc. I can also give it to you and you can do those same things to it.

In the case of this function, I expect that pCity was passed in as a parameter. That's what made it available. Then using its getOwnerINLINE() function (which returns the player # that owns the city), you call the global GET_PLAYER function (actually a macro that calls a GC function) to get a CvPlayer object.

For the next thing I'm trying to do, at first I thought it would be simple after seeing the code, but I failed. I'm trying to double the price of a unit upgrade if the unitCombat type changes.

The reason this failed is that CvPlayerAI doesn't have any information about units. Instead, you either need either a CvUnit or CvUnitInfo object. A CvUnit object exists for each unit on the map, e.g. Monty's 3rd Archer. A CvUnitInfo object exists for each type of unit in the XML files, e.g. "UNIT_ARCHER".

CvUnit has the function getUnitCombatType(), but to get the Combat Type for a given unit type you need to look up its CvUnitInfo first.

Code:
//phungus ChangeUnitCombatUpgradePrice
	if ( GC.getUnitInfo(eUnit).getUnitCombatType() != getUnitCombatType() )
	{
		iPrice *= 2;
	}
//phungus end

GC.getUnitInto(eUnit) works just like the GET_PLAYER(ePlayer) function.
 
Is it possible this has created an assert somewhere?

I'm currently getting a failed assert message under debugging in CvCity, unfortunately it just refers me to here:
Code:
bool CvCity::isHasReligion(ReligionTypes eIndex) const													 
{
	[B]FAssertMsg(eIndex >= 0, "eIndex expected to be >= 0");[/B]
	FAssertMsg(eIndex < GC.getNumReligionInfos(), "eIndex expected to be < GC.getNumReligionInfos()");
	return m_pabHasReligion[eIndex];
}

But since it's from something related to religion, I'm wondering if this function I just added might be the cause. Any ideas?
 
You cannot ask CvCity if it has the religion NO_RELIGION. If you are using VisualStudio you can attach the debugger to the running game and set a breakpoint there. This will let you see how you got there.
 
Is anyone interested in this code? I can of course upload this as a modcomp, and also the UnitUpgradePriceModifier code. Thing is though this is merged with modified RevDCM source so it's a bit of work to isolate it and change it to default SDK code. I don't want to go through that if no one has a use for it.
 
So I'm trying to debug this failed assert. When I start a new game this assert instantly get's thrown. If I step in or out I get here (bofore hitting a brick wall, of no source code available, I can try to push through, but It goes like 20 steps bombarding me with this and then starts returning unrelated stuff when it goes back to the source code):

Code:
bool CyCity::isHasReligion(int /*ReligionTypes*/ iIndex)
{
	return m_pCity ? m_pCity->isHasReligion((ReligionTypes) iIndex) : false;
}

Stepping into the source code I get the above and
Code:
inline CvGlobals& CvGlobals::getInstance()
{
	return gGlobals;
}

Code:
int CvGlobals::getNumReligionInfos()
{
	return (int)m_paReligionInfo.size();
}

This happens at the end of a turn as well. I saw some reference to doAIdirtyWork somewhere, but I can't reproduce it :dunno:

Anyone who has experience with debugging and C++ have any ideas? I reported this assert in the Revolutions forum, but aparently it's not intrinsic to that mod, so I'm pretty sure the culture from non state religion is causing it somehow.
 
When you get to the breakpoint on this assertion, look at the call stack that shows the chain of function calls that lead to this point. Work backwards to find out why someone is calling this function with NO_RELIGION as the parameter.
 
The call stack is what I mean. In terms of working backwards (or forwards) the only thing I can see to use are the step into or step out of commands. Using those, the code above is the only things that appeared for source code. Everything else was just assembler drible, I probably stepped through 100s of assembler stuff by now, and haven't seen anything linkable to the source code other then what's above, or some random stuff from unrecognized source code files (like vector.hpp)

I found the reference to dirty work though:
Code:
	[0x4734ac58] {m_iEmphasizeAvoidGrowthCount=0 m_iEmphasizeGreatPeopleCount=0 m_bAssignWorkDirty=true ...}	[const CvCity * const]
and this:
Code:
		[CvCityAI]	{m_iEmphasizeAvoidGrowthCount=0 m_iEmphasizeGreatPeopleCount=0 m_bAssignWorkDirty=true ...}	[CvCityAI]
both under the autos window, this stuff shows up only if I click on the break point, or the line of code imediatly beneith it in the call stack.
 
It's mildly annoying, but once it brings you into the Assembler, it won't bring you back out automatically when it hits DLL code again. So it helps to set up a hotkey of some kind which will do your Step function of choice (Probably INTO so you are as cautious as possible) and then close the assembler window. If the window isn't open, it'll take you to "real code" when able to.
 
Does step into move along the code, or move back up the code? Basically how can I follow back from when the failed assert is triggered to locate the cause of the NO_RELIGION call? I'm more then a little confused by this to be honest, there is no magic track back through source code function I can find. And it just seems like step into should move forward through the code, which doesn't help track back the cause.

Also there doesn't seem to be any in game problem caused by this failed assert. But I haven't updated the official version of Legends due to it. What is this failed assert actually doing in game? Ie, Is it harmful in any way?

Also if anyone with more experience in Software development wanted to give me a hand, I'm more then willing to upload the debug gamecore and associated gamecore.pdb (thing is huge like 70MB). This is for the latest test build of the Legends of Revolution mod I have up. Of course I realize most of you that could help out already have your own projects, but figure I'd throw that out there just in case :mischief:
 
Think in terms of how code is nested for the Step Out, Into, Over translations.


You are currently in a function, which was called from somewhere else, Step Out to go ignore the rest of the current function and wake up when you get back to that caller, you will quite likely call another function from inside of this function. To see what happens during that function, Step Into the code and it takes you to that function to run it line-by-line. If you honestly don't care what happens during that function, then Step Over it to continue with the next line of THIS function.


You can never back up to see what was recently processed, but you can use Step Out to find where you were called from (essentially the same as clicking on the Stack display, except you move on to the next line, so might hop back quite a far distance if this was called from the last line of a few functions)


Asserts are just there to notify the programmer that something he didn't want to happen wound up happening. So basically: If you don't know what the assert is trying to tell you, or if you don't care about the value it analyzes, then just ignore them.

In this case, the only problem you should face is if the religion is used as an index to fetch information from an array. Negative numbers tossed into array checks are VERY BAD and cause things to break in difficult to find ways (which is what most of the asserts in the DLL are designed to catch)
 
Top Bottom