GC.getNumCivicInfos() == 0?

Voyhkah

Undead
Joined
Apr 25, 2009
Messages
1,444
Location
Earth
According to the game, GC.getNumCivicInfos returns zero. Any ideas? Note: This is called while CvBuildingInfo is loading from XML.
 
According to the xml.log file, CIV4BuildingInfos.xml is loaded before CIV4CivicInfos.xml by a few files (CIV4SpecialUnitInfos.xml and CIV4ProjectInfo.xml are between them, which is not relevant).

This brings to mind the term "readpass3". That sort of function is for allowing Thing to reference Other-Thing from a file that is not loaded until after the file the Thing is in is loaded.

Or you can invert the data storage. Instead of having a "SomethingInvolvingACivic" tag in the BuildingInfo, you have a "SomethingInvolvingABuilding" tag in the CivicInfo.
 
So how should I do it?
 
CvBuildingInfo has no ReadPass3. Can I make one?
 
Yes, and its signature should be the same as the other readpass3()'s.

You should add a call to it in a loop for all building infos after civic infos are read. This is done in CvXmlLoadUtilitySet.cpp in CvXMLLoadUtility::LoadPreMenuGlobals().

See, for example, how it's done there for VoteSourceInfos.
 
ReadPass3 takes no args. How can I read from XML in it?
 
You don't. You read the strings (CIVIC_XXX) in read(), and keep them as strings as a member of the class, and in readpass3 you convert them to the relevant CivicTypes value.
 
So how do I do this?

Code:
pXML->Init2DIntList(&m_ppiCivicCommerceChanges, GC.getNumCivicInfos(), NUM_COMMERCE_TYPES);
	if (gDLL->getXMLIFace()->SetToChildByTagName(pXML->GetXML(),"CivicCommerceChanges"))
	{
		iNumChildren = gDLL->getXMLIFace()->GetNumChildren(pXML->GetXML());

		if (gDLL->getXMLIFace()->SetToChildByTagName(pXML->GetXML(),"CivicCommerceChanges"))
		{
			for(j=0;j<iNumChildren;j++)
			{
				pXML->GetChildXmlValByName(szTextVal, "Civic");
				k = pXML->FindInInfoClass(szTextVal);
				if (k > -1)
				{
					// delete the array since it will be reallocated
					SAFE_DELETE_ARRAY(m_ppiCivicCommerceChanges[k]);
					if (gDLL->getXMLIFace()->SetToChildByTagName(pXML->GetXML(),"Commerces"))
					{
						// call the function that sets the yield change variable
						pXML->SetCommerce(&m_ppiCivicCommerceChanges[k]);
						gDLL->getXMLIFace()->SetToParent(pXML->GetXML());
					}
					else
					{
						pXML->InitList(&m_ppiCivicCommerceChanges[k], NUM_COMMERCE_TYPES);
					}
				}

				if (!gDLL->getXMLIFace()->NextSibling(pXML->GetXML()))
				{
					break;
				}
			}

			// set the current xml node to it's parent node
			gDLL->getXMLIFace()->SetToParent(pXML->GetXML());
		}

		// set the current xml node to it's parent node
		gDLL->getXMLIFace()->SetToParent(pXML->GetXML());
	}
 
Every CvInfo has a m_aszExtraXMLforPass3 member which is a vector of strings. You can add to it strings when you parse, and then go over them in readpass3()
 
So how do I do this?

Code:
pXML->Init2DIntList(&m_ppiCivicCommerceChanges, [B]GC.getNumCivicInfos()[/B], NUM_COMMERCE_TYPES);
	if (gDLL->getXMLIFace()->SetToChildByTagName(pXML->GetXML(),"CivicCommerceChanges"))
	{
		iNumChildren = gDLL->getXMLIFace()->GetNumChildren(pXML->GetXML());

		if (gDLL->getXMLIFace()->SetToChildByTagName(pXML->GetXML(),"CivicCommerceChanges"))
		{
			for(j=0;j<iNumChildren;j++)
			{
				pXML->GetChildXmlValByName(szTextVal, "Civic");
				k = pXML->FindInInfoClass(szTextVal);
				if (k > -1)
				{
					// delete the array since it will be reallocated
					SAFE_DELETE_ARRAY(m_ppiCivicCommerceChanges[k]);
					if (gDLL->getXMLIFace()->SetToChildByTagName(pXML->GetXML(),"Commerces"))
					{
						// call the function that sets the yield change variable
						pXML->SetCommerce(&m_ppiCivicCommerceChanges[k]);
						gDLL->getXMLIFace()->SetToParent(pXML->GetXML());
					}
					else
					{
						pXML->InitList(&m_ppiCivicCommerceChanges[k], NUM_COMMERCE_TYPES);
					}
				}

				if (!gDLL->getXMLIFace()->NextSibling(pXML->GetXML()))
				{
					break;
				}
			}

			// set the current xml node to it's parent node
			gDLL->getXMLIFace()->SetToParent(pXML->GetXML());
		}

		// set the current xml node to it's parent node
		gDLL->getXMLIFace()->SetToParent(pXML->GetXML());
	}

How can I load the array BEFORE I allocate it? The number of civic infos is needed to allocate the array itself, not just read it. I don't see how this can work. Are you seeing something I'm not?
 
Consider what you need to do: When reading the XML, you only need to store the strings. You don't need an array the size of num civics. You still need a variable size array, and that's why this member is a vector, which is a class which handles its own allocation and de-allocation.
Just use its push_back method.

Inside readpass3() you'll need to fill an array the size of num civics, but by then you have their number and can allocate it.
 
Oh, there's been a miscommunication. This is the same array that has been giving me trouble in the other thread. Each Civic has four different variables associated with it.
 
Did what solve my problem?
 
Wait, I got it, create a temprary vector of arrays to load the XML to, then convert it to the m_aszExtraXMLforPass3 thing, then read it again and convert it to a member var in ReadPass3()! Not elegant, but it'll work. Probably.
 
:confused:Does anyone have any clue on how exactly to write

Code:
<Commerces>
						<iCommerce>0</iCommerce>
						<iCommerce>0</iCommerce>
						<iCommerce>2</iCommerce>
						<iCommerce>0</iCommerce>
					</Commerces>

into a Vector?
 
Wait, I got it. But does anyone know how to convert a int to a CvString? And how do I go the other way?
 
To read this XML you don't need to manually convert the string to int. Just use SetCommerce() (There are plenty of samples in the DLL code).

To convert to string, use one of the string format functions - which one depends on the exact usage you need. Why do you need to convert int to string?
 
m_aszExtraXMLforPass3 is a vector of strings. So to put ints in it, you need to convert them. :cry::cry:I am actually done with the direct reading of the XML. All I need to do is to load a series of int values into m_aszExtraXMLforPass3, then read them back out later.
 
Back
Top Bottom