Troubles with Arrays and Arrays of Arrays...

I have a soft spot for them in my heart, yes, but they have been ejected from my toolbox except when copying code that I'm going to use in a very small function. One has to look no further than the CAR thread for a recent example of iI and iJ biting a seasoned programmer in the butt.

On that subject, even eBuilding isn't very descriptive. There's nothing worse than needing to add a second building to a function and resorting to eOtherBuilding (which I have done). Better to use a name such as eTargetPlayer to go with ePlayer (or eSourcePlayer if you want to get really descriptive).

This all comes down to using tools to write readable code, including descriptive names (functions and variables), documentation, and short functions that do one thing only. The more you do it up front, the less time you'll spend later fixing bugs and scratching your head trying to figure out what a function is supposed to do.
 
Lol.

This is slightly OT, but still on CIV4 SDK. Is there a way with the CvGametextMgr to place a ICON_BULLET without putting it in the text file? Like, in the SDK instead?
 
This is slightly OT, but still on CIV4 SDK. Is there a way with the CvGametextMgr to place a ICON_BULLET without putting it in the text file? Like, in the SDK instead?

Well, just casually browsing the code reveals lines like this:

Code:
...
CvWStringBuffer szInfoText;
CvWString szBuffer;
CvWString szText;
...

...
szBuffer.Format(L"%s  %c%s", NEWLINE, gDLL->getSymbolID(BULLET_CHAR), szText.GetCString());
szInfoText.append(szBuffer);
...

[This code is obviously only a snippet, used as an example.]

Following those conventions, it seems like the "gDLL->getSymbolID(BULLET_CHAR)" puts a bullet icon in the szBuffer, after the newline.
 
Well, just casually browsing the code reveals lines like this:

Code:
...
CvWStringBuffer szInfoText;
CvWString szBuffer;
CvWString szText;
...

...
szBuffer.Format(L"%s  %c%s", NEWLINE, gDLL->getSymbolID(BULLET_CHAR), szText.GetCString());
szInfoText.append(szBuffer);
...
[This code is obviously only a snippet, used as an example.]

Following those conventions, it seems like the "gDLL->getSymbolID(BULLET_CHAR)" puts a bullet icon in the szBuffer, after the newline.

Thanks Supercheese, I was wondering where it was.
 
Back on topic. I set up my Schema for the Tech Building Happiness, but I have a problem. When I start up the game it says that

Tag: 2 In Info class was Incorrect
Current XML file is:
blah blah blah...

My Schema:
Code:
	<ElementType name="TechHappinessChanges" content="eltOnly">
		<element type="PrereqTech"/>
		<element type="iHappiness" minOccurs="0"/>
	</ElementType>

My XML:
Code:
			<TechHappinessChanges>
				<PrereqTech>TECH_CROP_ROTATION</PrereqTech>
				<iHappiness>2</iHappiness>
			</TechHappinessChanges>
 
Don't you want multiple techs to be able to affect happiness per building?

Code:
<TechHappinessChanges>
	<TechHappinessChange>
		<PrereqTech>TECH_CROP_ROTATION</PrereqTech>
		<iHappiness>2</iHappiness>
	</TechHappinessChange>
	<TechHappinessChange>
		<PrereqTech>TECH_BIOLOGY</PrereqTech>
		<iHappiness>1</iHappiness>
	</TechHappinessChange>
</TechHappinessChanges>

What does the read() code look like? Are both PrereqTech and iHappiness defined in that schema? Recall that you must first define them with <ElementType> once and then use them any number of times with <element>.
 
Don't you want multiple techs to be able to affect happiness per building?

Code:
<TechHappinessChanges>
    <TechHappinessChange>
        <PrereqTech>TECH_CROP_ROTATION</PrereqTech>
        <iHappiness>2</iHappiness>
    </TechHappinessChange>
    <TechHappinessChange>
        <PrereqTech>TECH_BIOLOGY</PrereqTech>
        <iHappiness>1</iHappiness>
    </TechHappinessChange>
</TechHappinessChanges>
What does the read() code look like? Are both PrereqTech and iHappiness defined in that schema? Recall that you must first define them with <ElementType> once and then use them any number of times with <element>.

Your right, I thought it looked funny. Also, Prereq Tech and iHappiness are both defined. iHappiness is a standard buildinginfos element, and Prereq tech got defined with all my other Tech Commerce Changes...
 
Does changing the XML and schema to match what I posted fix the problem?

It fixed that problem, but apparently, the code for the happiness isn't working (and maybe the healthiness, I haven't tested it.) I added the building that was supposed to give +2 happiness with crop rotation. Then, I gave myself crop rotation. No effect to the happiness count. So I figured it was a CvGameTextMgr problem, but then, when I added extra population, the city got unhappy at the usual level, not 2 extra, which meant my happiness code wasn't working.

I haven't been messing with code for long enough now that I'm starting to forget what a lot of it does... :(
 
Step through the code with an example on paper to see if you can find the problem yourself. If you have any questions, I'll gladly help you understand what things are doing. We're at the stage where you'll learn far more figuring out the problem on your own with help than by me just telling you the problem outright.

Things to try:

  • Expose the happiness and health to Python via CvBuildingInfo or CvTechInfo (I forget where it lands)
  • Use the above to validate the XML parsing code puts the values in the correct spots
  • Add debugging output (logging) in processTech() or changeTechBuildingXXX()
  • Add logging to CvCity::happyLevel(), etc.
 
Step through the code with an example on paper to see if you can find the problem yourself. If you have any questions, I'll gladly help you understand what things are doing. We're at the stage where you'll learn far more figuring out the problem on your own with help than by me just telling you the problem outright.

Things to try:

  • Expose the happiness and health to Python via CvBuildingInfo or CvTechInfo (I forget where it lands)
  • Use the above to validate the XML parsing code puts the values in the correct spots
  • Add debugging output (logging) in processTech() or changeTechBuildingXXX()
  • Add logging to CvCity::happyLevel(), etc.

Well, I just caught a really stupid error in CvInfos

I forgot to construct the array:

Code:
m_piTechHappinessChanges(NULL),
My
Code:
m_piTechHealthChanges(NULL),

was there, but for some reason, I left out Happiness. Everything else seemed okay there though.

EDIT:
After recompiling and testing, it seems there must be more than that error though. I still don't have the happiness kicking in when it should.
 
I have a question. Is this code in CvInfos right?

Code:
	pXML->SetVariableListTagPair(&m_piTechHappinessChanges, "TechHappinessChanges", sizeof(GC.getBuildingClassInfo((BuildingClassTypes)0)), GC.getNumBuildingClassInfos());
	pXML->SetVariableListTagPair(&m_piTechHealthChanges, "TechHealthChanges", sizeof(GC.getBuildingClassInfo((BuildingClassTypes)0)), GC.getNumBuildingClassInfos());

I'm thinking the array should be the size of NumTechInfos, not buildings.
 
So the suggestions in my previous post still stand. We worked through exposing the tech attitude modifiers to Python, and these would work exactly the same (exposing values in an array). This would allow you to verify that you are reading in your XML correctly.

If you don't want to do that, have the parsing code force a +2 for every tech/building combination. I think you can do that by passing in 2 to InitList(), but I'm not sure.

Use the tools I've shown you to gain more comfort with them. That way you'll be able to diagnose and solve your coding problems more quickly in the future. :)
 
So the suggestions in my previous post still stand. We worked through exposing the tech attitude modifiers to Python, and these would work exactly the same (exposing values in an array). This would allow you to verify that you are reading in your XML correctly.

If you don't want to do that, have the parsing code force a +2 for every tech/building combination. I think you can do that by passing in 2 to InitList(), but I'm not sure.

Use the tools I've shown you to gain more comfort with them. That way you'll be able to diagnose and solve your coding problems more quickly in the future. :)

I beat you by a minute to the post, so you probably didn't see my above post about the sizeof arrays. Can you answer that?
 
Those arrays are in CvBuildingInfo, right? Each building has an array of technology happiness/health modifiers, right? If so, then yes to your question: you should be using getNumTechInfos() instead of getNumBuildingClassInfos().

If it's the other way around, CvTechInfo contains arrays of building modifiers, then you need to change it to getNumBuildingInfos() and not BuildingClass. Regardless, BuildingClass should not appear anywhere in your changes since they are tied to actual building types and not classes.
 
Those arrays are in CvBuildingInfo, right? Each building has an array of technology happiness/health modifiers, right? If so, then yes to your question: you should be using getNumTechInfos() instead of getNumBuildingClassInfos().

It's this one. That's two errors. Recompiling to see if that was the problem.

edit:

So it should look like this:

Code:
	pXML->SetVariableListTagPair(&m_piTechHappinessChanges, "TechHappinessChanges", sizeof(GC.getTechInfo((TechTypes)0)), GC.getNumTechInfos());
	pXML->SetVariableListTagPair(&m_piTechHealthChanges, "TechHealthChanges", sizeof(GC.getTechInfo((TechTypes)0)), GC.getNumTechInfos());
 
While I don't understand why it wants the size of a CvTechInfo when it's only storing an int and isn't looking up the CvTechInfo itself--only its unique ID via getInfoTypeForString()--I do believe those are correct.
 
While I don't understand why it wants the size of a CvTechInfo when it's only storing an int and isn't looking up the CvTechInfo itself--only its unique ID via getInfoTypeForString()--I do believe those are correct.


Okay, well more errors than that exist than, because my code STILL isn't working. :( I'm going to keep looking.
 
Back
Top Bottom