Civic Attitude Modifier

Okay, I recompiled and loaded it. I saw about 30-40 messages, for each civic with a modifier. I never saw the "Skipping" message.
 
So it means that the readpass2() is fine...?

Maybe the values are reset somewhere? Or the function to get the value is somehow wrong?
 
As I recall decoding the WoC system, it works like this:

  1. Start reading a file (say, Promotions)
    1. Base XML executes pass 1
    2. Base XML executes pass 2
    3. Modules Load one at a time
      1. execute readpass 1 for current module
      2. run copyNonDefaults to move information from the newly read module on top of the currently retained data. If function does nothing, module information is simply discarded
      3. execute readpass 2 for current module
      4. run copyNonDefaults to move information from the previously loaded data on top of the newly read data. If function does nothing all information NOT from the module is discarded
      5. Go to next module if there is another one
    4. Go to next file if there is one (technically, execute next line in CvXMLLoadUtilitySet, which may be for a readpass 3 instead of a new file)
  2. When ordered, readpass3 is executed. Readpass3 translates and then discards raw text information which was loaded during readpass1 (and carried in copynondefaults 1), this is so you can store as a number instead of a string and save memory space.


Now, I don't remember if the copynondefaults stuff happens at all when you haven't got any modules installed, but I am reasonably certain you DO have some modules installed. It could be worthwhile to temporarily remove all modules and see if it works then, or just in general check out your copynondefaultsreadpass2 with some debugging text statements (output for yourself the exact contents of both the current data and the passed in data before the copy, and again after it)
 
No. xienwolf's description seems to match the code we've got at this point. Have you tried running this using a debug DLL?
 
Okay, I got a debug build running, and now that I'm paying attention to what's going on, I'm noticing some weird things (Weird is possibly good.)

I immediately gave myself all the ancient techs via worldbuilder. I switched from Chiefdom to Despotism. All the AI's became best friends with me. Then, when I switched from barter to slavery, all the AI's became furious with me.

EDIT:
Changing any government civics seemed to have no effect, other than that the AI loved me no matter my selection. Choosing another civic of any other type caused their immediate hatred.
 
Do you still have value-setting code that ignores the XML values? If not, what XML values do you have specified? You gotta figure out from the evidence what's going wrong. What can you generalize from those test cases? Are they repeatable? Do they happen the same way every time you try them?
 
Do you still have value-setting code that ignores the XML values? If not, what XML values do you have specified? You gotta figure out from the evidence what's going wrong. What can you generalize from those test cases? Are they repeatable? Do they happen the same way every time you try them?

Both. I had a value setting in the XML for Chiefdom to hate Despotism. I also had the -100 hardcoded.

I'm going to recompile without the hardcoded -100 and play around with values and civics.
 
Okay. In every game, every player seems to start at Friendly with one another. I'm going to go out on a limb here and say that the code must comparing those with the same civic choices and giving some sort of attitude bonus. I switch the modifier from Chiefdom->Despotism, -100; to Chiefdom->Slavery, -100. This seemed to have no effect, even after I switched to slavery and everyone else was running Chiefdom.

EDIT:
When loading the game, it has the following popups
"Found CivicAttitudeChanges"
"Found First CivicAttitudeChange"
"CIVIC_SLAVERY"
"Modifier: -100"
"CIVIC 25: -100"

The fact that it doesn't say Chiefdom for anything makes me wonder if it's comparing the civics correctly.
 
It will only say the target civic name because that's what appears in the XML. We could change the debug output to say the source civic name, but it looks like it's reading the XML fine.

Hmm, "25" looks suspicious because that's the number of civics, so there is no civic with that ID (0 to 24). Does your testing mod have extra civics? If so then the XML looks fine.

Do the Python accessors return correct values now?
 
It will only say the target civic name because that's what appears in the XML. We could change the debug output to say the source civic name, but it looks like it's reading the XML fine.

Hmm, "25" looks suspicious because that's the number of civics, so there is no civic with that ID (0 to 24). Does your testing mod have extra civics? If so then the XML looks fine.

Do the Python accessors return correct values now?

I'm playing Rise of Mankind, and there are a lot more civics than in vanilla BTS.

The python still reads my Civic Attitude Change as 0. However, all the leaders still are best friends with me.
 
UPDATE.

I added this back to the NonCopyDefaults:
Code:
	if (m_piCivicAttitudeChanges)
    {
        for ( int i = 0; i < GC.getNumCivicInfos(); i++ )
        {
            if ( m_piCivicAttitudeChanges[i] == iDefault )
            {
                m_piCivicAttitudeChanges[i] = pClassInfo->getCivicAttitudeChange(i);
            }
        }
    }

and tested out the python and I got -100!!

Now, the only thing, the code seems to be working backwords. Before I switched to slavery, everyone hated me. When I switched, everyone loved me.
 
Ah yeah, good finding! I'm not used to this part of the code, not using WoC over Orbis...

Anyway, *now*, you may have an issue with the code getting the attitude modifier, the one where you loop over civics.
 
Hmm, so now you have the same array-copying code in both copyNonDefaults() and copyNonDefaultsReadPass2()? I'm confused but not looking at the code right now.

All the modifiers are read from CvCivicInfo each time AI_getAttitude() is called, right? I would double-check that code to make sure it tests in the correct direction as Opera said.
 
Indeed. You guys are correct. I switch around the Index variables (iI and iJ are index's, correct?) in the function, and the reverse happened. everyone loved me before switching, and hated me after switching. However, we have one last bug to work out. Why is applying the opposite effect if I don't have that civic combo?

Oh, and EmperorFool, Noncopydefaults and Noncopydefaultsreadpass2 are basically the same function now, yes.
 
iI and iJ are index's, correct?

Only because you use them as such in your code. Variable and function names have no symantec meaning to C++, they just have to be declared. You can call those variables "Larry" and "Moe" for all the compiler cares. If you're asking about terminology, then yes you are using those variables as indexes into an array. They are also called loop counters. "i" was the original choice to be short for "index".

Why is applying the opposite effect if I don't have that civic combo?

I don't understand this question. Paste the latest code for the function that calculates the attitude value for two players please.

Noncopydefaults and Noncopydefaultsreadpass2 are basically the same function now, yes.

That concerns me a bit. I wonder if copyNonDefaults() goes with readPass2() and copyNonDefaultsReadPass2() goes with readPass3() because the first read pass doesn't need any copying since there's no previously-read data to copy over. Try putting "return" as the first line of copyNonDefaultsReadPass2() and see if it makes a difference (if it returns a value, return the same value up top).
 
Actually, reading what xienwolf said above... It seems it goes ReadPass1 -> ReadPass2 -> CopyNoNDefaults1 -> CopyNonDefaults2 -> ReadPass3...
 
I don't understand this question. Paste the latest code for the function that calculates the attitude value for two players please.
Code:
int CvPlayerAI::AI_getCivicAttitudeChange(PlayerTypes ePlayer) const
{
    int iAttitude = 0;
    
    // add modifier for every combination of civics between the two players
    for (int iI = 0; iI < GC.getNumCivicOptionInfos(); iI++)
    {
        for (int iJ = 0; iJ < GC.getNumCivicOptionInfos(); iJ++)
        {
            iAttitude += GC.getCivicInfo(getCivics((CivicOptionTypes)iI)).getCivicAttitudeChange(GET_PLAYER(ePlayer).getCivics((CivicOptionTypes)iJ));
        }
    }
    
    return iAttitude;
}

That concerns me a bit. I wonder if copyNonDefaults() goes with readPass2() and copyNonDefaultsReadPass2() goes with readPass3() because the first read pass doesn't need any copying since there's no previously-read data to copy over. Try putting "return" as the first line of copyNonDefaultsReadPass2() and see if it makes a difference (if it returns a value, return the same value up top).

Putting return at the beginning of the function appears to have had no effect on how the code actually works.

Let me clarify what is occurring, in-game, currently. In the XML, I have it coded so that anyone player with Chiefdom, a starting government civic will have a -100 attitude with any player running slavery, a non-starting economic civic. When I start a new game, every player starts with Chiefdom and Barter for those civic categories. Yet, instantly, and before switching civics to slavery, the AI's all are furious towards me.Then, after switching to Slavery, the AI's all are friendly to me. The code has two problems. First, it shouldn't have any affect when we aren't running any of the civics that get the modifier. Second, When I switch to the civic that should have the modifier at -100, it seems to do the opposite, +100.
 
Are you sure you got ALL of your hardcoded 100's out of the code now that it is working? It could be that in a CopyNonDefault or in the default value for loading or somewhere else you have left a 100 value which is getting loaded for all civics. Though if you had 4 civics with +100 and one with -100 as would happen in such a case you would NEVER get them angry with you, so I don't think that is really the case here.
Code:
int CvPlayerAI::AI_getCivicAttitudeChange(PlayerTypes ePlayer) const
{
    int iAttitude = 0;
    
    // add modifier for every combination of civics between the two players
    for (int iI = 0; iI < GC.getNumCivicOptionInfos(); iI++)
    {
        CivicOptionTypes eCivicOption = GC.getCivicInfo(getCivics((CivicOptionTypes)iI));
[COLOR="Red"]        int iJunk = 0;[/COLOR]
        for (int iJ = 0; iJ < GC.getNumCivicOptionInfos(); iJ++)
        {
            iAttitude += eCivicOption.getCivicAttitudeChange(GET_PLAYER(ePlayer).getCivics((CivicOptionTypes)iJ));
        }
    }
    
    return iAttitude;
}

Rewrite your code slightly like this, just so that you have a variable to do a mouseover on, and set a breakpoint on the line in red. Then run a debug DLL and you can place the mouse over eCivicOption and it will expand all data loaded on the civic option. Check that the values for the civic adjustments are what you want them to be, then hit F5 so it continues (will instantly return to apparently the exact same spot, but will now be on the next civicoption, so mouseover again to check the next dataset)
 
Back
Top Bottom