As many times as you have pointed out my blunders I just had to sit for a while and watch the little hammer pound away on that head, mostly glad it wasn't mine

I think you are confusing me with Mary Poppins. I'm not practically perfect in every way. I do make bugs once in a while, specially when I write something and then tell other people to test it. There is a reason why it needs testing
It tells quite a bit about you that you get entertained by a looping gif. If nothing else, then you might like slap-stick comedy
Hmm, I seen the length() function before but still, not sure how to use it in my code with
getAllowedUnitClassImmigration(iI). Do I need to like I said, make a new function in CvInfos.cpp just to get the length()?
That would be silly. I think I misunderstood you as I was talking of the player allowed cache. Now I took a closer look at what you actually did and it's a civic info code only. I don't actually see the problem. Maybe the problem is that you commented out the code
Code:
UnitClassArray<int> m_jaAllowedUnitClassImmigration;
This one works on UnitClassTypes. The last half of JustInTimeArray.h tells which array types are available and length if allocated. In this case
Code:
template<class T>
class UnitClassArray: public JustInTimeArray<T>
{
public:
UnitClassArray() : JustInTimeArray<T>(JIT_ARRAY_UNIT_CLASS, [B]GC.getNumUnitClassInfos()[/B]){};
UnitClassArray(T eDefault) : JustInTimeArray<T>(JIT_ARRAY_UNIT_CLASS, [B]GC.getNumUnitClassInfos()[/B], eDefault){};
};
Adding more array types is just a matter of copying this code and edit length and name. I do that from time to time and other people are allowed to do that too. JIT_ARRAY_UNIT_CLASS is just an ID from an enum in the top of the same file. That ID is only used in CvPlayer::updateInventionEffectCacheSingleArray().
I do have a few comments on the code, which is likely just confusing naming. iI and i aren't good variable names. iUnit and iUnitClass would be better. iI is defined elsewhere. It looks like Firaxis preferred to reuse the loop variables in multiple loops. However it helps the compiler if you declare the int each time like
for (int iI = 0;. You looks for positive kCivicInfo.getAllowedUnitClassImmigration and then you print TXT_KEY_CIVIC_
PREVENT_UNITCLASS_IMMIGRATION. Negative allow prevents and positive enables. All of this are minor and shouldn't prevent the code from working.
Also, I had to adjust the updateInventionEffectCache() because it was only designed for Techs, not Civics also. Before I figured out what all was going on I moved m_iCityPlotFoodBonus to work just like vanilla code with a changeCityPlotFoodBonus(int iChange), it's the easiest way I know how to do this and it works

I have local modifications to those lines as well. Now I will get a conflict. Well that happens and I actually planned that change as well.
EDIT: why change m_iCityPlotFoodBonus? It worked just fine as far as I'm aware and there is a reason why I changed it in the first place. By not having the cache in the savegame, we will be free to modify the XML and then load a savegame and it will be updated. By saving the cache, savegames will not update to changed XML settings and we will have a less stable XML testing setup. I had a plan to remove XML settings from savegames as much as possible to make it easier to modify XML.
As for simplicity, what you removed couldn't be simpler. It sets the variable to a default value, then it loops all civics and modifies the variable according to the player owned civics. Think about it.
Code:
m_iCityPlotFoodBonus = 0;
for (int iCivic = 0; iCivic < GC.getNumCivicInfos(); ++iCivic)
{
CvCivicInfo& kCivicInfo = GC.getCivicInfo((CivicTypes) iCivic);
if (getIdeasResearched((CivicTypes) iCivic) > 0)
{
m_iCityPlotFoodBonus += kCivicInfo.getCenterPlotFoodBonus();
Removing all code not relevant to this feature we end up with this. m_iCityPlotFoodBonus ends up being the combined value of all owned civics' getCenterPlotFoodBonus(). Splitting this into multiple functions and saving the result is actually way more complex.
Also I screwed up merging the conflict and lost my local changes to the file. From now on I merge only after making backups
EDIT2: no loss anyway. I just told VC++ not to reload CvPlayer.cpp and I could copy the modified code. I take that as a warning and a close call for code loss.
Could we just add a new boolean to processCivics that checks if the InventionEffectCache needs updated, instead of updating every time a tech or civic is added? Not like this code gets called often though so may not be necessary.
I have been thinking something like that as the function has grown to do much more than originally intended. I'm not sure what would be best as starting to avoid calls would add the risk of not calling when needed.
Maybe something like adding a CvCivicInfo pointer as argument and if it isn't NULL, then it can optionally skip stuff. For instance if m_jaAllowedUnitClassImmigration contains just 0s, then m_jaAllowedUnitClassImmigration.isAllocated() will be false. This mean we only update the cache if isAllocated() is true. Everything should update if the civic pointer is NULL because that would be on game load.
I think right now we should just focus on getting the civic stuff to work. We can worry about such optimization later.