Civic Attitude Modifier

It doesn't work. Here's a screenshot, so you can see that I typed it right.


Civ4ScreenShot0058.jpg
 
If you type ` without holding shift, you get a different non-Python console. Make sure you hold shift and that you see a message in the console about it being for Python.
 
If you type ` without holding shift, you get a different non-Python console. Make sure you hold shift and that you see a message in the console about it being for Python.

I still get an error message, just a different one.

Civ4ScreenShot0059.jpg
 
The latest CvInfos.cpp file you sent still had the old plural name of getCivicAttitudeChanges(). Did you perhaps rename it like I suggested in your "secret" file? :p
 
The latest CvInfos.cpp file you sent still had the old plural name of getCivicAttitudeChanges(). Did you perhaps rename it like I suggested in your "secret" file? :p

No. I haven't renamed it. At this point, I'm starting to get really confused about what I have changed and haven't changed, so I would appreciate it if you could look at my CvInfos.cpp and tell me if anything's wrong.

View attachment 225403

And trust me, this is the most up-to-date version I have. No secret, more up to date file than this one.
 
I forgot that you hadn't exposed this new field to Python yet. This part is pretty easy. Add this line to CyInfoInterface1.cpp:

Code:
	python::class_<CvCivicInfo, python::bases<CvInfoBase> >("CvCivicInfo")
		...

		// Arrays
		...
		[B].def("getCivicAttitudeChanges", &CvCivicInfo::getCivicAttitudeChanges, "int (int /*CivicTypes*/ iCivicType)")[/B]
		;

	python::class_<CvUnitClassInfo, python::bases<CvInfoBase> >("CvUnitClassInfo")
		...

This should be enough to allow you to enter that test code above. :D
 
Ok, haven't completely read through all of the details since I realized the thread had quite a few posts in it, so here's my thoughts on a quick skim of the thread so far:

You should use arrays of size getNumCivicInfos so that you can have attitude modifiers across civic categories should someone want them. Makes it easier to code actually, and won't run noticeably slower. Didn't pay attention to your code to see if that is how you set it up anyway, but can say with 95% certainty that you did since setting it up to be an array only for the civicoption type would be relatively difficult to accomplish.


You absolutely MUST have a CopyNonDefaultsReadPass2 function for the data to load. Failure to have a CopyNonDefaults() (first readpass) means the module information gets ignored, but failure to have one for readpass 2 means that the main information gets abandoned. Can't remember if I ever checked to see if it only does this for stuff strictly loaded AS a module, but I don't think that is the case, so even main XML loaded information gets abandoned if you fail to have a CopyNonDef2.


I have completely half of the Idiot's Guide walkthrough for copying an array, unfortunately the section which would be of use to you is the one on creating a NEW array since I will write how to load the XML fully in that one and explain some things like readpass 2 and maybe even 3. It might have some useful insights for you though anyway, but at this point you are mostly past the last bits of what is written thus far.


Ok, looking at the last code you uploaded, my first comment would be that you have quite a few changes in Civics now, since the order doesn't matter too much, you may want to gather them all together within each function, just for simplicity of looking at your work should you ever have to bugfix anything, but that would mean fewer comment blocks which might confuse you later, so it is purely a matter of personal preference.

Ah, you are of size NumCivicInfos, figured you would be :) Though one issue I see here is that you only have a single value, an integer, being loaded, so no capacity to link the specific text field. I will assume you are saving that one for later since it is harder to set up the reading from the XML for that.

At the end of readPass1, instead of:
Code:
	// create arrays to hold attitude changes and messages
	SAFE_DELETE_ARRAY(m_piCivicAttitudeChanges);
	m_piCivicAttitudeChanges = new int[GC.getNumCivicInfos()];
	//SAFE_DELETE_ARRAY(m_pszCivicAttitudeTextKeys);
	//m_pszCivicAttitudeTextKeys = new CvString[GC.getNumCivicInfos()];

You can juse use:
Code:
	pXML->InitList(&m_piCivicAttitudeChanges, GC.getNumCivicInfos(), 0);

It will work better for you to have the value initialized as well, which this method accomplishes.

Oh, did you do any work in CvXMLLoadUtilitySet? If you didn't, then your readpass2 isn't actually doing anything at all. I would suspect you have not since it ought to have yelled at you for not having a CopyNonDefaultsReadPass2 if you had set things up properly.

Oh, you also need to have
Code:
	if (!CvInfoBase::read(pXML))
	{
		return false;
	}

At the top of readpass2 for WoC system to work properly.

Just before your return True at the end, you ought to pair your main IF statement
Code:
	if (gDLL->getXMLIFace()->SetToChildByTagName(pXML->GetXML(),"CivicAttitudeChanges"))
	{

With an Else InitList statement
Code:
	}
	else
	{
		pXML->InitList(&m_piCivicAttitudeChanges, GC.getNumCivicInfos(), 0);
	}

This ensures that the array exists yet again, because WoC will run this readpass2 on some data which hasn't run readpass1 at all at some point.

Hrm.. late here and I should head to sleep, so I won't look at the whole XML loading thing in too much detail right now, since I know you will be rewriting it in the short future to get the text keys added in anyways, and I know I will make mistakes right now if I try to rewrite it for you.

One important thing about CopyNonDefaults is that you will basically have the exact same chunk of code to handle the ReadPass2 data in both CopyNonDef1 and CopyNonDef2. It's a bit wierd, and I can't remember right now specifically why, so hopefully it wasn't due to something about how I rewrote their system and it actually DOES apply to you (check the other CopyNonDef2 functions to ensure they are almost exactly the same a few lines earlier in ::CND1)


And that gets me to the end of your CvInfos, except for the most vital part which I decided not to look at. nice of me wasn't that :p (but seriously, you do NOT want to assume I am correct about anything I posted just now, I am relatively tired and only skimmed the thread up to this point, but I do believe I was correct in most of what I did let myself say)
 
Thanks, xienwolf. I skimmed the WoC thread but couldn't find a good high-level description of the loading process. Do you have a link to one? If not, how about the best place to start looking in the code to see the flow? I was trying to guess where things went based on other CvInfo classes; nice to see I was so far off!

You are correct that we are leaving the XML text keys for after we get the first part working.
 
I put it all together myself when taking their functionality into Fall Further. Their WoCiki or whatnot ought to have somewhat of a description I imagine, but reading what other people describe code to be has never worked as well for me as reading straight through the code, so I never checked.

CvXML____ files contain most of the really important changes in WoC, and the place you should start looking at to figure out how things flow. Those are the REAL files which interact with the XML (they are what pXML-> points to). Also, don't forget in CvXMLLoadUtilitySet.cpp to enable the second readpass for this file. Just search for CvCivicInfos and you should just need to add ", true" to the end of the function call for it.
 
In CvXMLLoadUtilitySet.cpp look for "civicinfo" and modify this line:

Code:
LoadGlobalClassInfo(GC.getCivicInfo(), "CIV4CivicInfos", "GameInfo", "Civ4CivicInfos/CivicInfos/CivicInfo", [B]true[/B], &CvDLLUtilityIFaceBase::createCivicInfoCacheObject);

And here's the latest CvInfos.cpp based on your last version and xienwolf's fixes. Cross your fingers and roll the dice! :)
 
With those changes, I can compile, but get a CTD during Init XML...
 
Oh, I missed one part I think. In readpass2() make these changes:

Code:
		if (pXML->SkipToNextVal())
		{
			[B][COLOR="Orange"]pXML->InitList(&m_piCivicAttitudeChanges, GC.getNumCivicInfos(), 0);[/COLOR][/B]
			[s]for (int i = 0; i < GC.getNumCivicInfos(); i++)[/s]
			[s]{[/s]
				[s]m_piCivicAttitudeChanges[i] = 0;[/s]
				[s]//m_pszCivicAttitudeTextKeys[i] = NULL;[/s]
			[s]}[/s]

			int iCount = gDLL->getXMLIFace()->GetNumChildren(pXML->GetXML());

It looks like that during the second read pass, only the main information (type, description, key, etc) from CvInfoBase is read again, but read() isn't called again. Thus we need to initialize the arrays at the end of read() and at the start of readpass2().
 
Oh, I missed one part I think. In readpass2() make these changes:

Code:
        if (pXML->SkipToNextVal())
        {
            [B][COLOR=Orange]pXML->InitList(&m_piCivicAttitudeChanges, GC.getNumCivicInfos(), 0);[/COLOR][/B]
            [s]for (int i = 0; i < GC.getNumCivicInfos(); i++)[/s]
            [s]{[/s]
                [s]m_piCivicAttitudeChanges[i] = 0;[/s]
                [s]//m_pszCivicAttitudeTextKeys[i] = NULL;[/s]
            [s]}[/s]

            int iCount = gDLL->getXMLIFace()->GetNumChildren(pXML->GetXML());
It looks like that during the second read pass, only the main information (type, description, key, etc) from CvInfoBase is read again, but read() isn't called again. Thus we need to initialize the arrays at the end of read() and at the start of readpass2().

Hmm... I just made those changes, but I still get a CTD when Init XML...
 
Remove the call to pXML->InitList() from the end of read(). I think that's actually causing a problem because the number of civics is not known when they are first being read in.
 
Remove the call to pXML->InitList() from the end of read(). I think that's actually causing a problem because the number of civics is not known when they are first being read in.

I'm getting tired of reporting the same old thing...

Recompiled - Check
Tested - Crashed at Init XML - Check

So, it crashed, again, at Init XML.
 
Yes, that's correct. I'm attaching the latest CvInfos.cpp file. I moved the call to InitList() to before the test to see if the civic has any attitude changes. At this point I can't see anything else to do. Hopefully xienwolf has some more ideas if this doesn't work.
 
Back
Top Bottom