Adding new Resource Yields to Future Techs

Oops, thanks xienwolf for catching the missing *. That's the danger of "coding" in Notepad. ;)

My guess is that the header (.h) file doesn't match the .cpp file for the getYieldChangeArray() function. Make sure they look the same: int * and empty parens (). If they match, make sure you do a full rebuild. It sounds like the header file might still be a bare int.

Regarding "Array", I only added that to match all the other similar attributes that have the same functions. You are correct that you could call it billyBobAndFrankAreMean() if you wanted.

In getYieldChange(int i), you are asking for a single yield change value. In getYieldChangeArray(), you are asking for the whole array of values. This is necessary because setYieldChangeHelp() expects and array of values. "int *" means array of "int"s, and empty parens () means that it doesn't require any information passed to it to do its work. You need to tell getYieldChange(int i) which yield to return, whereas getYieldChangeArray() returns them all.
 
Ok, so you've suggested int* getYieldChangeArray() because sometimes I will need to call the entire array, and sometimes I'll want just an individual yield, in which case I would call getYieldChange(int i).

How would I tell the system which yield to call in the second case? getYieldChange(YIELD_FOOD i)?
 
Ok, so you've suggested int* getYieldChangeArray() because sometimes I will need to call the entire array, and sometimes I'll want just an individual yield, in which case I would call getYieldChange(int i).

Exactly. CvGTM will be the only one to use getYCArray() while everyone else will use getYC(int i).

Note: You'll eventually need to expose CvTechInfo:: and CvPlayer::getYieldChange(int i) to Python, but we can do that at the end so you can get this displayed correctly in BUG.​

How would I tell the system which yield to call in the second case? getYieldChange(YIELD_FOOD i)?

Not quite. The "int" says what type of value the "i" parameter will hold. When calling the function, you only pass in the value for "i", you don't name it again:

Code:
int iYieldChange = getYieldChange(YIELD_FOOD);

That being said, you shouldn't ever need to do this yourself. You'll always call getYieldChange(int i) in the context of a loop over all yield types, or by passing in an existing variable such as iIndex.

Where do you stand now? Is it compiling? Working?
 
I think missing the "*" in CvInfos.h did it. But now a new error! Yay... (and there was much rejoicing...)

I can't have both of the following in CvInfos.cpp:
Code:
int* CvTechInfo::getYieldChangeArray() const	
{
	return m_piYieldChange;
}

int* CvTechInfo::getYieldChangeArray() const	
{
	FAssertMsg(i < NUM_YIELD_TYPES, "Index out of bounds");
	FAssertMsg(i > -1, "Index out of bounds");
	return m_piYieldChange ? m_piYieldChange[eIndex] : -1;
}
This gets thrown out when compiling:
CvInfos.cpp|1294|error C2084: function 'int *CvTechInfo::getYieldChangeArray(void) const' already has a body|
CvInfos.cpp|1297|error C2065: 'eIndex' : undeclared identifier|
Which one do I get rid of?
 
You need both. The first one is now correct. Change the second function back to how it was before:

Code:
[B]int CvTechInfo::getYieldChange(int i) const[/B]
{
	FAssertMsg(i < NUM_YIELD_TYPES, "Index out of bounds");
	FAssertMsg(i > -1, "Index out of bounds");
	return m_piYieldChange ? m_piYieldChange[eIndex] : -1;
}

The two matching declarations in CvInfos.h should be

Code:
int* getYieldChangeArray() const;
int getYieldChange(int i) const;

Think of the array of integers as a book of phone numbers. getYieldChangeArray() is a function asking for the entire phone book while getYieldChange(int i) is asking for the ith phone number.
 
Thanks EF. It's great being able to post these situations and have an answer waiting when I get up/home from work.

Your solution worked (hadn't previously realized the point), but leaves yet another new error. In CvInfos.cpp, this:
Code:
int CvTechInfo::getYieldChange(int i) const
{
	FAssertMsg(i < NUM_YIELD_TYPES, "Index out of bounds");
	FAssertMsg(i > -1, "Index out of bounds");
	return m_piYieldChange ? m_piYieldChange[eIndex] : -1;
}
results in this:
CvInfos.cpp|1297|error C2065: 'eIndex' : undeclared identifier|
I see that in other functions using the "?" modifier (right term?), the second call of the affected string ends in "", not "[eIndex]". So, I've tried that, and the compile progressed past CvInfos.cpp. But it turns out CvPlayer.cpp is riddled with errors. Could you take a look please?

View attachment Array.rar

Thanks!
 
Still an error there. eIndex would yell at you for being undefined. In the last link it should read:

return m_piYieldChange ? m_piYieldChange : -1;[/code]


And just to break this line down into english:

"Since something called this function and we promised to provide them with an INT value, we must return something (COMMAND: return -- FUNCTION: Send a value back to calling address).

So first check if there is a variable called m_piYieldChange (COMMAND: m_piYieldChange ? -- FUNCTION: An abbreviation for "if (m_piYieldChange)", which just checks to ensure that your array DOES exist before trying to get information from it).

Should there be such a variable, go ahead and give them the value which they requested from it (COMMAND: m_piYieldChange -- FUNCTION: Selects the i'th value from the array. Must use i since that is the value which was passed to this function, thus the one requested)

However, if there is not such a variable, just tell them -1 (COMMAND: : -1 -- FUNCTION: Abbreviation for "else -1", -1 is the default used in Civ for "there wasn't a proper value here")


EDIT: Bah, wasn't quite fast enough to save you the headache ;)
 
Just a quickie, here's the compiler errors:
CvPlayer.cpp|47|error C2065: 'm_aiYieldChange' : undeclared identifier|
CvPlayer.cpp|107|error C3861: 'm_aiYieldChange': identifier not found, even with argument-dependent lookup|
CvPlayer.cpp|107|error C2541: 'delete' : cannot delete objects that are not pointers|
CvPlayer.cpp|107|error C3861: 'm_aiYieldChange': identifier not found, even with argument-dependent lookup|
CvPlayer.cpp|107|error C3861: 'm_aiYieldChange': identifier not found, even with argument-dependent lookup|
CvPlayer.cpp|517|error C3861: 'm_aiYieldChange': identifier not found, even with argument-dependent lookup|
CvPlayer.cpp|10444|error C3861: 'm_aiYieldChange': identifier not found, even with argument-dependent lookup|
CvPlayer.cpp|10454|error C3861: 'm_aiYieldChange': identifier not found, even with argument-dependent lookup|
CvPlayer.cpp|10454|error C3861: 'm_aiYieldChange': identifier not found, even with argument-dependent lookup|
CvPlayer.cpp|15756|error C3861: 'm_aiYieldChange': identifier not found, even with argument-dependent lookup|
CvPlayer.cpp|16227|error C3861: 'm_aiYieldChange': identifier not found, even with argument-dependent lookup|
 
error C2065: 'm_aiYieldChange' : undeclared identifier

This means that you did not declare the m_aiYieldChange field in the header file (CvPlayer.h). In fact, all other errors stem from this error. Add this line (1162) to CvPlayer.h and you should be right as rain:

Code:
	int* m_aiSeaPlotYield;
[B]	[COLOR="YellowGreen"]int* m_aiYieldChange;[/COLOR][/B]
	int* m_aiYieldRateModifier;
	int* m_aiCapitalYieldRateModifier;
 
While no one has ever accused C++ compiler error messages of being easy to understand, with practice you'll learn to discern the problems they're trying to point out. Even if the message doesn't make sense, you can always go to the offending line number and ask yourself, "What possible problems could this line have?"

In the case of

Code:
m_aiYieldChange = NULL;

there are (realistically) only two things that could go wrong:

  • You haven't told the compiler what m_aiYieldChange is, or
  • m_aiYieldChange's type won't accept the value NULL (which is 0).
 
Ya, this was just really a case of me trying one last time before I had to leave for work, seeing red in CodeBlocks, posting, and booting it to work. Stoopid, stoopid... And I'd promised you to always read everything through first!!! :blush:

---

In case you're still up, here's a new error:
CvTeam.cpp|5487|error C2275: 'YieldTypes' : illegal use of this type as an expression|
CvTeam.cpp|5487|error C2146: syntax error : missing ')' before identifier 'eIndex'|
CvTeam.cpp|5487|error C2059: syntax error : ')'|
It came form this line of code:
Code:
GET_PLAYER((PlayerTypes)iI).changeYieldChange(YieldTypes eIndex, GC.getTechInfo(eTech).getYieldChange() * iChange);



Now, I tried rewriting it as (subtle change bold):
Code:
GET_PLAYER((PlayerTypes)iI).changeYieldChange([COLOR="Red"][B]([/B][/COLOR]YieldTypes[COLOR="red"][B])[/B][/COLOR] eIndex, GC.getTechInfo(eTech).getYieldChange() * iChange);
and got this error instead:
CvTeam.cpp|5487|error C2065: 'eIndex' : undeclared identifier|
CvTeam.cpp|5487|error C2660: 'CvTechInfo::getYieldChange' : function does not take 0 arguments|
If I figure this out within the next 15-20, I'll just edit this post...

---

EDIT: Ooh, ooh!! I think I got it!! I changed the above line of code to this:
Code:
GET_PLAYER((PlayerTypes)iI).changeYieldChange(YIELD_FOOD, GC.getTechInfo(eTech).getYieldChange(NUM_YIELD_TYPES) * iChange);
GET_PLAYER((PlayerTypes)iI).changeYieldChange(YIELD_PRODUCTION, GC.getTechInfo(eTech).getYieldChange(NUM_YIELD_TYPES) * iChange);
GET_PLAYER((PlayerTypes)iI).changeYieldChange(YIELD_COMMERCE, GC.getTechInfo(eTech).getYieldChange(NUM_YIELD_TYPES) * iChange);
and it seemed to do the trick!!!
 
You got it. "YieldType" is a type specifier like "int". You only use it in a function declaration (telling the compiler what to expect when the function is called. When you are actually calling the function from somewhere else, you only pass in the value. YIELD_FOOD is one such value of type YieldType.

Keep on truckin'! :goodjob:
 
WHOOP-WHOOP-whoop-whoop-WHOOP!!!!!!!! :woohoo::goodjob: :D:rotfl:

OK, I am now fully an array convert!!! It works!!!!!

So, now I just have to get the AI to know what it is, and what to do with it. And expose it to Python for easy tracking in the City Screen.

Then, I can move onto making the Shrines provide Commerce, not Gold, and seperating out the extra Happy & Health provided by the game already for "better" logging in the CIty Screen. ...

...

Drat, now I'm depressed again... :lol:

EF, xienwolf, Aussie, :thanx:.

Here's an UTD fileset too: View attachment Array.rar
 
When you get "no response" from your code, the first thing to check after making sure you're using the right DLL (you probably are since you see pedia changes) is to add logging to your code so you can see that it is going where you expect it to go.

Add a message to CvTeam::processTech() [or whatever CvTeam function you modified] saying, "calling CvPlayer" just before it calls CvPlayer::changeYieldChange().

Add a message to CvPlayer::changeYieldChange() displaying the iIndex (or iYield, whatever it's called) and iChange values.

Add a message to CvCity::changeBaseYieldRate() displaying the same thing as the previous one (iIndex and iChange).
 
Just missed your post, see above EF!!!! Here's what I changed to make it work (in CvTeam.cpp):
Code:
GET_PLAYER((PlayerTypes)iI).changeYieldChange(YIELD_FOOD, GC.getTechInfo(eTech).getYieldChange([COLOR="red"]YIELD_FOOD[/COLOR]) * iChange);
GET_PLAYER((PlayerTypes)iI).changeYieldChange(YIELD_PRODUCTION, GC.getTechInfo(eTech).getYieldChange([COLOR="Red"]YIELD_PRODUCTION[/COLOR]) * iChange);
GET_PLAYER((PlayerTypes)iI).changeYieldChange(YIELD_COMMERCE, GC.getTechInfo(eTech).getYieldChange([COLOR="Red"]YIELD_COMMERCE[/COLOR]) * iChange);
 
I didn't read that far into the lines you posted a couple posts above once i saw the first YieldType error, so nice catch. :goodjob:

As I said a couple times, one thing left to do still is fix CvPlayer::acquireCity() or whatever function is responsible for capturing/gifting a city. It needs to apply the new owner's YieldChange to itself. I'll take a look again at that code Sunday (or maybe tomorrow night) to see if it's obvious.

BTW, exposing the various getXXX() functions to Python is pretty easy. Each should require only a single line of code IIRC. If you want to take a stab at it, just pick some similar function and see how it's done in the CyFoo.cpp or CyFoo.h files. Oh, I guess they won't be a single line of code after all as I forgot a step.
 
Top Bottom