Adding new Resource Yields to Future Techs

You might want to add your changes to the city output for Production (and food if including food as production, as for worker/settler) to:

int CvCity::getProductionDifference(int iProductionNeeded, int iProduction, int iProductionModifier, bool bFoodProduction, bool bOverflow) const


This is where the city checks to discover how much production to apply each turn. It does request what the Base yield rates are in the course of this function though. I cannot recall why I had decided not to apply straight to the base yield rate when I had first set up my own fields to modify city output, but IIRC there is a function which completely resets the base rates when recalculating them on a semi-regular basis.


Food would be placed in

CvCity::foodDifference

And for basic commerce, probably in:

void CvCity::updateCommerce(CommerceTypes eIndex)
 
Placing xienwolf's code . . . in either void CvCity::changeBaseYieldRate or void CvCity::setBaseYieldRate instead of the orignal placement of int CvCity::getBaseYieldRate results in all the FutureYields being counted 6 times.

This is due to how these functions work. When you add an Engineer specialist to a city, it calls CvCity::changeBaseYieldRate(YIELD_PRODUCTION, 2). If you remove it, it calls the same function again with -2 for the second parameter.

If that function also adds the future yields each time it's called, it will add them for each specialist you add and each specialist you remove. The function is called for other reasons as well, so the effects keep adding over and over again. This is why these functions cannot be used for this effect.

Leaving the above code in int CvCity::getBaseYieldRate still results in the glitchy implemention described previously.

I still don't see why this is, but I accept that it doesn't work. That's why I am investigating the route of using changeBaseYieldRate() just like all the other effects: specialists, buildings, corporations, etc.

@ EF, I'm afraid I found your info in post #75 confusing... Is the described code to be inserted into CvPlayer.cpp, or CvCity.cpp?

It goes in CvPlayer, but it's not complete as I posted. You would need to alter your CvTeam code like this:

Code:
GET_PLAYER((PlayerTypes)iI).changeFreeCityYield(YIELD_FOOD, GC.getTechInfo(eTech).getFutureFood() * iChange);
GET_PLAYER((PlayerTypes)iI).changeFreeCityYield(YIELD_PRODUCTION, GC.getTechInfo(eTech).getFutureProduction() * iChange);
GET_PLAYER((PlayerTypes)iI).changeFreeCityYield(YIELD_COMMERCE, GC.getTechInfo(eTech).getFutureCommerce() * iChange);
 
You might want to add your changes to the city output for Production (and food if including food as production, as for worker/settler) to:

int CvCity::getProductionDifference(int iProductionNeeded, int iProduction, int iProductionModifier, bool bFoodProduction, bool bOverflow) const

and

CvCity::foodDifference

And for basic commerce, probably in:

void CvCity::updateCommerce(CommerceTypes eIndex)

But these functions use getYieldRate() which uses getBaseYieldRate(), so they shouldn't need to be modified. I looked for a function that would calculate the total yield for a city from its constituent parts, but all I could find was CvPlot::calculateYield(). There is CvCity::updateYield(), but unlike updateCommerce(), it doesn't calculate the full value. Instead it only tells each plot in the city radius to update its yield in case it's changed.

I can find no function to calculate the total yield for a city. I also cannot find the function that assigns a city to another player during capture. Is a new city created with the same values? If so, how does its yield get calculated?
 
Yes, when you capture a city it creates a new city on the tile, transfers some information, then deleted the old city. Same way that units upgrade.

Okay, I see CvPlayer::acquireCity() takes care of this. I guess this is where you would add in a call to CvCity::changeBaseYieldRate() based on the new owner.
 
Well, for what its worth I'm still working on my approach. Unfortunately I've run into a minor problem-getting it to show up in the Civilopedia.
Now, for background, when I added my TechYieldRateModifier changes to Warlords, I used the following code in CvGameTxtMgr.cpp:

Code:
//	Yield Modifiers
	setYieldChangeHelp(szBuffer, L"", L"", gDLL->getText("TXT_KEY_TECH_IN_ALL_CITIES").GetCString(), GC.getTechInfo(eTech).getYieldModifierArray(), true);

Now I thought that if I simple changed .getYieldModifierArray() to .getYieldChange, that this would work-unfortunately the compiler says otherwise. Indeed, I get the following message:

Code:
CvGameTextMgr.cpp(4999) : error C2664: 'CvGameTextMgr::setYieldChangeHelp' : cannot convert parameter 5 from 'int (int) const' to 'const int *'

Can anyone suggest what I might be doing wrong here, and how I should change it?

Aussie.
 
Never mind, I'm just a moron-its not getYieldChange, its .getYieldChangeArray(). All I needed to do was take the time to look back over my CvInfos file to figure that out-now I feel silly :rolleyes:
 
OK, so here is what I've got so far. Altering XML files was never my strong suit, so it looks a little....buggy. Can anyone tell me how to fix the issues in this screenshot? I'd very much appreciate it :)!



Aussie

Very strange, for some reason the image isn't displaying. Well I'll just add it as an attachment instead.
 

Attachments

  • Tech_Mod_Screenshot0000.JPG
    Tech_Mod_Screenshot0000.JPG
    115.6 KB · Views: 61
Aussie, if you mean the fact that it says "+2% :hammers: TXT_KEY_TECH_YIELD_CHANGE, it's likely because you haven't setup an entry in one of the files in the Assets\XML\Text directory. It actually doesn't matter which file you put the entry into, but it should look something like:
Code:
<TEXT>
		<Tag>TXT_KEY_TECH_YIELD_CHANGE</Tag>
		<English>added to city production.</English>
</TEXT>

That would result in this being displayed instead: "+2% :hammers: added to city production."

Oh, and I should confirm: it's fairly easy to change these arrays you're setting up from being percentages to integers, right? And thanks again!
 
Well, in truth it should already be an integer-as it uses a very similar array to what I used to create my BuildingYieldChange mod. I think the % has more to do with the XML than with the SDK-won't know until I add the functionality though.

As for the Code snippet EF, it looks like this:

Code:
//	Yield Change
	setYieldChangeHelp(szBuffer, L"", L"", gDLL->getText("TXT_KEY_TECH_YIELD_CHANGE").GetCString(), GC.getTechInfo(eTech).getYieldChangeArray(), true);

Hope that helps.

Aussie.
 
No problem, its

Code:
<TEXT>
		<Tag>TXT_KEY_TECH_YIELD_CHANGE</Tag>
		<English>[ICON_BULLET]D1_Change%F2_Icon</English>
		<French>[ICON_BULLET]D1_Change%F2_Icon</French>
		<German>[ICON_BULLET]D1_Change%F2_Icon</German>
		<Italian>[ICON_BULLET]D1_Change%F2_Icon</Italian>
		<Spanish>[ICON_BULLET]D1_Change%F2_Icon</Spanish>
	</TEXT>

Hope that helps

Aussie_Lurker.
 
Is setYieldChangeHelp() an existing function in the SDK? I don't have the code in front of me. I don't see how that XML string works as it's missing the % for the first value (D1), and the result made me expect to see a double percent for the second.

Maybe I just need some sleep. :crazyeye:
 
@EF: re posts 75 & 82 then, the code in #75 is an entirely new function? Would I leave my original changes in int CvCity::getYieldRate(YieldTypes eIndex) const in CvCity.cpp then? Or does this new code in CvPlayer mean I should leave CvCity empty?

EDIT: Just tried a compile with the sugested changes for CvPlayer, and I realized I left a bunch of stuff out. So I'm copying all the entries for FreeCityCommerce, which should do the trick. Except, FreeCityCommerce uses an array, and none of my stuff is setup for that... There's no easy way to fix that, is there...? If this code is the answer, I have to switch to an array, right?
 
Yes, I am saying to remove the changes you made to getBaseYieldRate() and/or getYieldRate(). Instead, the code I posted in #75 calls changeBaseYieldRate() so the normal code takes care of passing it along to other CvCity functions.

My code uses an array in CvPlayer since Aussie_Lurker posted how to do that previously. I'm trying to post enough so you can understand and get it to work yourself, as I don't have time to do it all myself. I haven't touched BUG in over a month and really want to get back to it.

All you should need to add is the array declaration in CvPlayer.h and the initialization and deletion in CvPlayer.cpp. The final piece will be making some change to CvPlayer::assignCity() to handle the case of conquering/gifting cities.
 
OK, I get all that, and thank-you again, I do appreciate both what you are trying to do and that you are doing it. But my concern previously (sorry I wasn't clear) is with updating my initial changes in CGTM, CvInfos, & CyInfoInterface1 to read from an array and display the info correctly. I'm having some trouble finding an array in CGTM that I can model after...

Here's what I changed CvGameTextMgr.h to:
Code:
	void buildFutureYieldString( CvWStringBuffer& szBuffer, TechTypes eTech, int iTieldType, bool bList = false, bool bPlayerContext = false );
from:
Spoiler what CGTM.h used to be :
Code:
	void buildFutureFoodRateString( CvWStringBuffer& szBuffer, TechTypes eTech, bool bList = false, bool bPlayerContext = false );
	void buildFutureProductionRateString( CvWStringBuffer& szBuffer, TechTypes eTech, bool bList = false, bool bPlayerContext = false );
 	void buildFutureCommerceRateString( CvWStringBuffer& szBuffer, TechTypes eTech, bool bList = false, bool bPlayerContext = false );

But I don't know which of the many different Yield functions in CGTM.cpp to model after... Too many choices, all of which look like they might work...
 
Yay! I finally got around to setting up SDK compilation, and it finally works after a few failed attempts. I couldn't get VS 2008 to work, but VS 2005 worked the first time. Cést la vie.

So, here's an example for you in CvGTM, line 4695:

Code:
//  Yield Modifiers
setYieldChangeHelp(
    szHelpText, 
    L"", 
    L"", 
    gDLL->getText("TXT_KEY_CIVIC_IN_ALL_CITIES").GetCString(), 
    [B]GC.getCivicInfo(eCivic).getYieldModifierArray(),[/B] 
    true);

and line 8728:

Code:
void CvGameTextMgr::setYieldChangeHelp(
    CvWStringBuffer &szBuffer, 
    const CvWString& szStart, 
    const CvWString& szSpace, 
    const CvWString& szEnd, 
    [B]const int* piYieldChange,[/B] 
    bool bPercent, 
    bool bNewLine)

In fact, it looks like you might be able to use that function directly--no need to create a new one.
 
So, just add a second entry for line 4695 change the bolded part to read:

GC.GetTechInfo(eTech).GetFutureYieldArray(),

And add a second entry of line 8728 and change it to CvGameTextMgr::setFutureYieldChangeHelp(etc,etc, const int* piFutureYieldChange, etc).

Would that be right?
 
No, I meant that you need to add a call to setYieldChangeHelp() that looks like line 4695. You should add it to setTechHelp(), the function that builds the tech info hover text.

For example, insert lines 4945-7:

Code:
//  Happiness increase...
buildHappinessRateString(szBuffer, eTech, true, bPlayerContext);

[B]//  Yield increase...
setYieldChangeHelp(
    szHelpText, 
    L"", 
    L"", 
    gDLL->getText("TXT_KEY_TECH_YIELD_CHANGE").GetCString(), 
    GC.getTechInfo(eTech).[COLOR="DarkOrange"]getFutureYieldArray[/COLOR](), 
    false,
    true);[/B]

//  Free Techs...

You'll need to use the correct name of the array-accessing function that you added to CvTechInfo (the orange). This is similar to the code Aussie_Lurker posted a few days back (his used percentages, but the only difference is a "false" versus "true").
 
Top Bottom