SDK changes-little help please?

Joined
Jul 21, 2003
Messages
7,819
Location
Adelaide, South Australia
Hi guys,

Well I am continuing to struggle on with my changes to the CvInfos.xml file, but have run into a major problem. The thing is that I want a tag which will modify the yields and commerces in State Religion cities. I have successfully done this in CvInfos and CvPlayer, but CvCity is proving to be a massive headache :(.
What I thought I would try was a modification of the existing StateReligionHappiness portion of the file (seemed to make sense, as they work along similar lines.) This is what I have done:
Code:
int CvCity::getStateReligionCommerceRateModifier(CommerceTypes eIndex1, ReligionTypes eIndex2)
{
	FAssertMsg(eIndex >= 0, "eIndex expected to be >= 0");
	FAssertMsg(eIndex1 < NUM_COMMERCE_TYPES, "eIndex expected to be < NUM_COMMERCE_TYPES");
	FAssertMsg(eIndex2 < GC.getNumReligionInfos(), "eIndex expected to be < GC.getNumReligionInfos()");
	return m_aiStateReligionCommerceRateModifier[eIndex];
}


void CvCity::changeStateReligionCommerceRateModifier(CommerceTypes eIndex1, ReligionTypes eIndex2, int iChange)
{
	FAssertMsg(eIndex >= 0, "eIndex expected to be >= 0");
	FAssertMsg(eIndex1 < NUM_COMMERCE_TYPES, "eIndex expected to be < NUM_COMMERCE_TYPES");
	FAssertMsg(eIndex2 < GC.getNumReligionInfos(), "eIndex expected to be < GC.getNumReligionInfos()");

	if (iChange != 0)
	{
		m_aiStateReligionCommerceRateModifier[eIndex] = (m_aiStateReligionCommerceRateModifier[eIndex] + iChange);

		AI_setAssignWorkDirty(true);
	}
}

Now this isn't causing massive errors, but it IS telling me that
Code:
m_aiStateReligionCommerceRateModifier[eIndex]
is an undeclared identifier, and that the identifier is not found, even with argument-dependant loop.
Now I can't see how this can be the case, as I refer to it several time prior to this section of code. Can anyone tell me where I am going wrong? Do I have to go back and change something in CvPlayer or CvInfos? I hate constantly asking for help, but I have been working on this all day, without making any progress! Thankyou in advance :).

Aussie_Lurker.
 
Aussie_Lurker,

The reason why it isn't working for you is because you never defined the m_aiStateReligionCommerceRateModifier variable in the CvCity class. It only exists in your CvPlayer class. This is one of the problems that you were having before...
 
Well, at the risk of seeming dense, where DO I define m_aiStateReligionCommerceModifier? I mean, everywhere m_aiBuildingYieldChange occurs I have put a reference to StateReligionRateModifiers. It also keeps telling me that eReligion is undefined, even though it turns up in other parts of the file. I just can't seem to see where I am going wrong, and its making my head hurt a LOT :(. Could you possibly point me in the right direction TheLopez? I hate bothering you like this all the time, but you just seem to have a gift for this :). Needless to say that I will continue to persevere in the meantime, but any help you can provide would be VERY much appreciated, as always :).

Aussie_Lurker.
 
Are you sure the error is from the array with the long name, or the fact that you have the arguments named "eIndex1" and "eIndex2" and the index of the array a varaible called just plain "eIndex"?

You'd probably get the same error in the first FAssertMsg above what it's ignoring that line because it's a release build and not a debug build.
 
Actually, funny story. I copied and pasted the CvCity::getBonusYieldRateModifier and CvCity::changeBonusYieldRateModifier sections of the file, renamed everything accordingly, and it compiled fine?!?! Of course, whether it works or not is a wholly different matter!

Aussie_Lurker.
 
OK, through perseverence it appears that I have solved my compilation difficulties with StateReligion. However, I was trying to define StateReligionYieldRateModifier, but it says its 'not a member of CvReligionInfo'?! So, how do I make it a member of CvReligionInfo? It may prove unimportant in the grand scheme of things, but it would be nice to figure this kind of stuff out ;). As always, your help is ALWAYS greatly appreciated :).

Aussie_Lurker.
 
Aussie_Lurker said:
OK, through perseverence it appears that I have solved my compilation difficulties with StateReligion. However, I was trying to define StateReligionYieldRateModifier, but it says its 'not a member of CvReligionInfo'?! So, how do I make it a member of CvReligionInfo? It may prove unimportant in the grand scheme of things, but it would be nice to figure this kind of stuff out ;). As always, your help is ALWAYS greatly appreciated :).

Aussie_Lurker.

It's tough to see what you're trying to do without the exact code, including what file that it comes from.

In order to add things to the CvReligionInfo, you'd have to do like Kael has shown in his tutorial, Adding new XML attributes, only do it in the CvReligionInfo rather than the CvLeaderHeadInfo as shown in the tutorial.
 
Ger is right we need to get a better handle on the ultimate inteded usage of the data member, it looks to me that your intending to hold data on the current City bonus for Commerce from Religion. By storing that data in the City rather then referencing the player every time commerce is calculated you give cities the ability to have a local bonus (say from a Building) above and beyond the player level bonus. You must deside, dose this number reflect/take into account the presense or absense of the State Religion in the city. If it Dose then passing the religion IS important.

But on the other hand if this number is mearly the POTENTIAL bonus IF the stateReligion IS INFACT ALSO PRESENT, inwhich case their would be a check for religion outside this data to the tune of

if (hasReligion(GetOwner.getStateReligion())
{ TotalCommerceModifier += getStateReligionCommerceModifier() }


This is personaly how I would recomend doing it, the StateReligion check is quick and when their is a change in the Player level StateReligionCommerceModifier such as the processing of a Civic, its a trivial loop to update all the cities with the change, without needing to check religion.

I dont see how you will need to add anything to ReligionInfos, unless your planing for different state Religions to give StateReligionCommerceModifiers, for Example "Cristianity as a StateReligion gives -25% Science in Cities with Cristianity", I had'nt noticed anything like that in your plans so I doubt thats what your looking for.
 
Nope, nothing complex like that just a simple: if you have the Reformist Religious civic, then all State Religion cities get +25% hammers.
Actually, though, everything was running fine last night-until I tried to build a new .dll file. The CvPlayer and CvCity files are giving me a hard time at one specific section namely this section of CvPlayer:

Code:
nt CvPlayer::getStateReligionYieldRateModifier(YieldTypes eIndex)
{
	FAssertMsg(eIndex >= 0, "eIndex is expected to be non-negative (invalid Index)");
	FAssertMsg(eIndex < NUM_YIELD_TYPES, "eIndex is expected to be within maximum bounds (invalid Index)");
	return m_aiStateReligionYieldRateModifier[eIndex];
}


void CvPlayer::changeStateReligionYieldRateModifier(YieldTypes eIndex, int iChange)
{
	CvCity* pLoopCity;
	int iLoop;

	FAssertMsg(eIndex1 >= 0, "eIndex is expected to be non-negative (invalid Index)");
	FAssertMsg(eIndex2 < NUM_YIELD_TYPES, "eIndex is expected to be within maximum bounds (invalid Index)");

	if (iChange != 0)
	{
		m_aiStateReligionYieldRateModifier[eIndex] = (m_aiStateReligionYieldRateModifier[eIndex] + iChange);
		FAssert(getStateReligionYieldRateModifier(eIndex) >= 0);

		for (pLoopCity = firstCity(&iLoop); pLoopCity != NULL; pLoopCity = nextCity(&iLoop))
		{
			[B]pLoopCity->changeStateReligionYieldRateModifier();[/B]
		}
	}
}

is spitting out a
Code:
CvCity::changeStateReligionYieldRateModifier: function does not take 0 arguments

Now the line in question refers to this section of CvCity, namely:

Code:
void CvCity::changeStateReligionYieldRateModifier(YieldTypes eIndex, int iChange)
{
	FAssertMsg(eIndex >= 0, "eIndex expected to be >= 0");
	FAssertMsg(eIndex < NUM_YIELD_TYPES, "eIndex expected to be < NUM_YIELD_TYPES");

	if (iChange != 0)
	{
		m_aiStateReligionYieldRateModifier[eIndex] = (m_aiStateReligionYieldRateModifier[eIndex] + iChange);
		FAssert(getYieldRate(eIndex) >= 0);

		if (eIndex == YIELD_COMMERCE)
		{
			updateCommerce();
		}

		AI_setAssignWorkDirty(true);

		if (getTeam() == GC.getGameINLINE().getActiveTeam())
		{
			setInfoDirty(true);
		}
	}
}

but I can seriously see no reason why it should be telling me this! I am sorry to always bug you guys with these issues, but I am a self-confessed novice in computer languagues!! Maybe I should just give up and go and learn German eh? ;) Anyway thankyou guys, so much, for all your help to date-it means a great deal :)

Aussie_Lurker.
 
Aussie_Lurker said:
...
Code:
pLoopCity->changeStateReligionYieldRateModifier[b]()[/b];
...
Code:
CvCity::changeStateReligionYieldRateModifier: function does not take 0 arguments
...
Code:
void CvCity::changeStateReligionYieldRateModifier[b](YieldTypes eIndex, int iChange)[/b]
...


You're trying to call a function which takes two arguments, and you're not passing it any arguments.
 
Gerikes. Thank you so VERY, VERY MUCH!!!!! I feel like such a total idiot now :mischief:. This is what happens when a novice tries to make changes at 1am ;). If only I had the near robotic staying power of TheLopez eh? ;)
I really ought to have seen it, but I originally did have a seperate 'updateStateReligionYieldRateModifier()' section which I later removed-which is probably where I went wrong.
Now, however, I notice that I may have run into a wholly new problem!? This section of code would work fine for ReligionCommerceRateModifiers because-as the Impaler suggests-this is already covered when the computer runs the 'hasStateReligion' test for Commerce. However, I DON'T believe it would do this for yield. So, the question I need to ask next is: 'what kind of code would I need to add to get the computer to calculate yield changes from religion, and where would I need to put it?
Thanks in advance :).

Aussie_Lurker.
 
Right, now I am just getting ANNOYED!!!!!! :mad: I have now written this correction to the above line:

Code:
pLoopCity->changeStateReligionYieldRateModifier(YieldTypes)(eIndex);

Now its telling me that YieldTypes is an illegal use of this expression!!! WTH?? What the hell have I done wrong this time. Man, I am this close to giving the whole thing up as a wholly bad idea :(.

Aussie_Lurker.
 
Oh, please ignore my last little outburst-couldn't see the forest for the trees, as they say. Of course YieldTypes isn't the argument, eIndex is. iChange therefore was the second argument :rolleyes:. Whoops. Oh well, at least I SEEM to be learning, slowly....
My other, larger dilemma still persists though. I am guessing that I will have to make alterations to the CvInfos file to allow Religion to process Yield changes. Then, of course, I will almost certainly have to make those same changes in CvPlayer and CvCity wherever Religion gets a mention. Would that be fairly accurate? Thanks again guys, your help is incalculable :).

Aussie_Lurker.
 
As I said earlier you dont need to do anything to ReligionInfos if your just doing Civics that give a bonus for state religions without regard to any individual religion. Only if you wanted specific religions to have different bonuses would you need to make a change their.

YieldRateModifiers are computed by this function

int CvCity::getBaseYieldRateModifier(YieldTypes eIndex, int iExtra) const

This adds up all the various Yield Modifiers, for example Power, Capitol ect ect. Just add another if statment testing for presense of stateReligion and add in the modifier.

Consider brushing up the basic to intermediate level C++ syntax (that or get sleep), this can help to greatly reduce frustration over simple syntax errors. (you make fewer errors and can diagnose them almost instantly, I frequently run the compiler JUST to flag my syntax errors) I find that reading about coding without actualy doing any coding is very ineffective (you cant retain the un-utilized knowlage), simultaniosly coding && Studying is much better, you get very good retention of what your reading because your imediatly applying it to real code and you reduce your frustration level.
 
I hear what you are saying Impaler. The funny thing is that I get less frustrated when my compiling shows I have over a dozen errors (effectively the computer telling me my coding is utter CRAP ;) ) than when it tells me I have a single line error-an error which comes as a result of 1 or 2 missing letters :mad:. You would think they would have made computers a little less literal by now ;).
Anyway, I will be leaving off my coding efforts for the next day or so-out of neccessity-and hopefully my mind will be a bit fresher. Hope so, because I also still have to sort out an issue with BuildingCommerceChange. I think I have it 99.99% right, but have probably added the commerce change factor to the wrong line in the Commerces section of CvCity :rolleyes: . Hope that is all it is!

Aussie_Lurker.
 
Well, thanks once again Impaler for your advice. In the end I "borrowed" the section of code which determined if a StateReligion city got an XP bonus, and just altered it to my needs-and it compiled very nicely. I also shifted the +BuildingCommerceChange line to a formula further down in hopes that this is where my troubles with this are occuring. Anyway, don't have time to test it tonight, unfortunately, but should be able to let you know if it all worked in the next 24 hours or so :).

Aussie_Lurker.
 
OK, I just can't figure out where I am going wrong anymore :(. I have made all the adjustments I thought I would need to make in order to get changeStateReligionYieldModifier to work, but it still won't function as it should :(. If it helps, these are the critical sections of CvCity.cpp and CvPlayer. Can anyone see where my fault might lay?
First, CvCity.cpp:

Code:
int CvCity::getBaseYieldRateModifier(YieldTypes eIndex, int iExtra) const
{
	int iModifier;

	iModifier = getYieldRateModifier(eIndex);

	iModifier += getBonusYieldRateModifier(eIndex);

	if (isPower())
	{
		iModifier += getPowerYieldRateModifier(eIndex);
	}

	if (area() != NULL)
	{
		iModifier += area()->getYieldRateModifier(getOwnerINLINE(), eIndex);
	}

	iModifier += GET_PLAYER(getOwnerINLINE()).getYieldRateModifier(eIndex);

[B]// Changes Start
    if (GET_PLAYER(getOwnerINLINE()).getStateReligion() != NO_RELIGION)
	{
		if (isHasReligion(GET_PLAYER(getOwnerINLINE()).getStateReligion()))
		{
			iModifier += GET_PLAYER(getOwnerINLINE()).getStateReligionYieldRateModifier(eIndex);
		}
	}
// Changes End[/B]


	if (isCapital())
	{
		iModifier += GET_PLAYER(getOwnerINLINE()).getCapitalYieldRateModifier(eIndex);
	}

	iModifier += iExtra;

	return max(0, (iModifier + 100));
}

Code:
// Changes Start
int CvCity::getStateReligionYieldRateModifier(YieldTypes eIndex) const
{
	FAssertMsg(eIndex >= 0, "eIndex expected to be >= 0");
	FAssertMsg(eIndex < NUM_YIELD_TYPES, "eIndex expected to be < NUM_YIELD_TYPES");
	return m_aiStateReligionYieldRateModifier[eIndex];
}


void CvCity::changeStateReligionYieldRateModifier(YieldTypes eIndex, int iChange)
{
	FAssertMsg(eIndex >= 0, "eIndex expected to be >= 0");
	FAssertMsg(eIndex < NUM_YIELD_TYPES, "eIndex expected to be < NUM_YIELD_TYPES");

	if (iChange != 0)
	{
		m_aiStateReligionYieldRateModifier[eIndex] = (m_aiStateReligionYieldRateModifier[eIndex] + iChange);
		FAssert(getYieldRate(eIndex) >= 0);

		if (eIndex == YIELD_COMMERCE)
		{
			updateCommerce();
		}

		AI_setAssignWorkDirty(true);

		if (getTeam() == GC.getGameINLINE().getActiveTeam())
		{
			setInfoDirty(true);
		}
	}
}
// Changes End

and this in CvPlayer.cpp:

Code:
int CvPlayer::getStateReligionYieldRateModifier(YieldTypes eIndex)
{
	FAssertMsg(eIndex >= 0, "eIndex is expected to be non-negative (invalid Index)");
	FAssertMsg(eIndex < NUM_YIELD_TYPES, "eIndex is expected to be within maximum bounds (invalid Index)");
	return m_aiStateReligionYieldRateModifier[eIndex];
}


void CvPlayer::changeStateReligionYieldRateModifier(YieldTypes eIndex, int iChange)
{
	CvCity* pLoopCity;
	int iLoop;

	FAssertMsg(eIndex1 >= 0, "eIndex is expected to be non-negative (invalid Index)");
	FAssertMsg(eIndex2 < NUM_YIELD_TYPES, "eIndex is expected to be within maximum bounds (invalid Index)");

	if (iChange != 0)
	{
		m_aiStateReligionYieldRateModifier[eIndex] = (m_aiStateReligionYieldRateModifier[eIndex] + iChange);
		FAssert(getStateReligionYieldRateModifier(eIndex) >= 0);

		for (pLoopCity = firstCity(&iLoop); pLoopCity != NULL; pLoopCity = nextCity(&iLoop))
		{
			pLoopCity->changeStateReligionYieldRateModifier(eIndex, iChange);
		}
	}
}
Anyway, I REALLY hate to bother you guys all the time, but you are all such fonts of knowledge, and I always try not to bother you until I have exhausted all other options first.
Anyway, thankyou in advance for any assistance you can provide.

Aussie_Lurker.
 
OK, so things seem to go from bad to worse :(. Having hit a wall on StateReligionYieldModifiers, I decided to go back to CvInfos, CyInfoInterface and CvGameTxtMgr to add a few new tags-namely TradeCommerceModifier, SpecialistExtraYields and FreeSpecialistChanges. The Compilation and Building steps went perfectly fine, as did my modifications of the GameInfoSchema and Civ4GameTextInfo XML files. However, when I tried to load it up (to see if modifications to the new tags would show up in-game) it immediately halted-with the error message that Civ4PlayerOptionsInfo.xml could not be loaded :(. It seems that all of my modification efforts are coming to naught this weekend-can any of you guys help me? Thankyou in advance.

Aussie_Lurker.
 
Aussie_Lurker said:
The Compilation and Building steps went perfectly fine, as did my modifications of the GameInfoSchema and Civ4GameTextInfo XML files. However, when I tried to load it up (to see if modifications to the new tags would show up in-game) it immediately halted-with the error message that Civ4PlayerOptionsInfo.xml could not be loaded :(.

Aussie_Lurker.


An error like that tells me there are problems with a schema file. An error that gives you a specific line in an XML file is due to that file. These errors at start time are typically not SDK issues.

As for the code above, what's wrong with it? Is it not compiling? Compiling but you're getting a wrong answer? Crashing?

Without a debugger, it's tough to pinpoint the problems (especially if you don't know what the problem is!). You're best bet is to have a system in the form of a game save or something where you know exactly how a function should work, because you know what the variables will be at the beginning. Then, put logging functions into the function or functions so that you can then go through the logs and discover between what two portions of the log that the function went wrong. Then, you can analyze that by going through the lines of code (probably using paper and a calculator to calculate the variables, remembering to do what it says in your CODE, not what you THINK your code is doing) and see what went wrong.
 
Heres "A" Problem

iModifier += GET_PLAYER(getOwnerINLINE()).getStateReligionYieldRateModifier(eIndex);

If your just adding the Player Modifier their's no point in keeping a City level modifier as well, If your going to go to the trouble of having City level data you might as well use it (its worth it because it allows the City to have a localized bonus from say a wonder or building in addition to the Player level bonus). So that line should be

iModifier += getStateReligionYieldRateModifier(eIndex);

By not putting the GET_PLAYER infront of that your calling the City function of the same name, which itself should be loaded with data from the player when their was a change their.

With the code you had you still should have gotten the bonus when you changed Civics unless ProcessCivics() is failing to update the player. Or the Infoclass is holding nothing but zero's. If you cant see the info on the Civics effect list then its the later, if not the former.

Dont think your mod isn't working because your not seeing a "+X% on your Yield". You should set the Yield Modifier realy huge when testing (like +500%) then go in the game and ignore all the text just look at your hammer bar is it or is it not 5 times larger then it should be. Text can be fixed up later but will be missleading untill them.
 
Back
Top Bottom