Case Study: Adding new XML attributes and using them in the SDK

Kael said:
Feel free to check out FfH2, we have a new xml document 'CIV4SpellInfos.xml' that we use and it works great.
I just downloaded FfH2 just so I could check out the source code required - I can't quite get the XML to be read properly... however, there seems to be a source-code shortage. Any chance I could take a look at it?
 
Zulu9812:

I think the problem is in your get PeacekeepingAtttiude function, specificaly the if statment that controls it

Code:
	if (GET_PLAYER(ePlayer).getCivics((CivicOptionTypes)GC.getInfoTypeForString("CIVICOPTION_WARFARE")) == (CivicOptionTypes)GC.getInfoTypeForString("CIVIC_PEACEKEEPING") ||
        GET_PLAYER(ePlayer).getCivics((CivicOptionTypes)GC.getInfoTypeForString("CIVICOPTION_WARFARE")) == (CivicOptionTypes)GC.getInfoTypeForString("CIVIC_PEACEKEEPING"))
	{
		iAttitude += GC.getLeaderHeadInfo(getPersonalityType()).getPeacekeepingAttitudeChange();
	}

First off you have 2 identical comparisons being OR'ed together which is unessary. Second the static cast of (CivicOptionTypes) in the later half of the comparison should be a cast to (CivicOption), arn't you getting a compiling error here for incompatible comparison as the first half of the comparison's getCivics is going to return a CivicOption enum??

Though I still cant say ware the +1 is coming from, everything else looks ok to me.
 
I'm not sure if this is the right place to ask but have any of you looked into how specific unit bonuses work?
I've been trying to expand the number of promotions. Unfortunatly there are no tags for some of the variables that I'd like to modify such as "chance to intercept" or "traverse impassable terrain"
This is the only thread i've been able to find on creating new XML Tags so if anyone could halp me adapt this to the promotioninfos.xml I'd really appreciate it.
 
Slynky said:
I'm not sure if this is the right place to ask but have any of you looked into how specific unit bonuses work?
I've been trying to expand the number of promotions. Unfortunatly there are no tags for some of the variables that I'd like to modify such as "chance to intercept" or "traverse impassable terrain"
This is the only thread i've been able to find on creating new XML Tags so if anyone could halp me adapt this to the promotioninfos.xml I'd really appreciate it.

Sure. First off, realize that in order to add attributes you'll need to have the ability to modify and recompile the DLL, which is written in c++. Check out this thread for more on compiling the DLL. If you don't know c++, but have some programming background (perhaps in Java, C, or C#), you might be able to sqeak through, but if you run into a problem you're probably going to have a long night (or two) ahead of you.

So, I would try just getting the SDK code to compile first, without even changing any of it. If you can get that far, and feel comfortable with it, or are almost there and need a bit of help, check back in, and I'll see what I can do.
 
The problem is that SetVariableListTagPair in this case expects the second element of the XML to be an integer, because you passed it an integer array. It doesn't try to turn a string into a number by looking it up as a Civ4 tech/unit/unitclass/promotion/whatever name. The best way would probably be to use the string version like something like this:
Code:
CvString[] temp = new CvString[GC.getNumTechInfos()];
m_piFreeTechPromotions = new int[GC.getNumTechInfos()]
pXML->SetVariableListTagPair(&temp, "FreeTechPromotions", GC.getTechInfo(), sizeof(GC.getTechInfo((TechTypes)0)), GC.getNumTechInfos(), "");
for(int i = 0; i< GC.getNumTechInfos(); i++){
  if(temp[i].IsEmpty())
    m_piFreeTechPromotions[i] = -1;
  else
    m_piFreeTechPromotions[i] =CvXMLLoadUtility::FindInInfoClass( temp[i], GC.getTechInfo(), sizeof(GC.getTechInfo((TechTypes)0)), GC.getNumTechInfos());
}
delete[] temp;
(note: I haven't tested this, and I'm not sure if the delete[] temp is the proper deletion method) The rest would stay the same, only the Read(xmlthingy) method would change.
 
wow keal stricks again... cool tutorial :goodjob:

btw.. could the same idea be used to modify things like culture, or production, etc (edit xml, add to sdk)?
 
Civkid1991 said:
wow keal stricks again... cool tutorial :goodjob:

btw.. could the same idea be used to modify things like culture, or production, etc (edit xml, add to sdk)?

Yes, the process is definitly applicable to more than just this one example.
 
Great tutorial! I'm trying to add some tags to Civ4ImprovementInfos so that improvements can require bonuses to construct, in the same way that railroads require coal. I got a little greedy, and wanted to make multiple bonuses possible, and multiple ways of checking their presence. I added my tags inside the BonusTypeStruct of CivTerrainInfos.xml, as follows:


Code:
<ElementType name="BonusType" content="textOnly"/>
	<ElementType name="bBonusMakesValid" content="textOnly" dt:type="boolean"/>
	<!--begin adds -->
	
	<!-- The improvement requires that the bonus be available at the actual plot (ie must be on a trade route) -->
	<ElementType name="bBonusRequiredAt" content="textOnly" dt:type="boolean"/>
	<!-- The improvement requires the bonus be available at an adjacent plot (as for railroads/coal)-->
	<ElementType name="bBonusRequiredAdjacent" content="textOnly" dt:type="boolean"/>
	<!-- The improvement requires the bonus be available at the nearest city-->
	<ElementType name="bBonusRequiredCity" content="textOnly" dt:type="boolean"/>
	<!-- The improvement requires the bonus be available in the Capital -->
	<ElementType name="bBonusRequiredCapital" content="textOnly" dt:type="boolean"/>
	<!-- The improvement requires the resource be somewhere in the civilization -->
	<ElementType name="bBonusRequiredAnywhere" content="textOnly" dt:type="boolean"/>
	
	<!-- end adds -->
	
	<ElementType name="bBonusTrade" content="textOnly" dt:type="boolean"/>
	<ElementType name="iDiscoverRand" content="textOnly" dt:type="int"/>
	<ElementType name="BonusTypeStruct" content="eltOnly">
		<element type="BonusType"/>
		<element type="bBonusMakesValid"/>
		<!-- begin adds -->
		<element type="bBonusRequiredAt"/>
		<element type="bBonusRequiredAdjacent"/>
		<element type="bBonusRequiredCity"/>
		<element type="bBonusRequiredCapital"/>
		<element type="bBonusRequiredAnywhere"/>
		<!-- end adds -->
		<element type="bBonusTrade"/>
		<element type="iDiscoverRand"/>
		<element type="YieldChanges" minOccurs="0" maxOccurs="*"/>
	</ElementType>

I then added the new data to CivImprovementInfos.xml. this loaded okay, though after looking at the C++, I see that the data wasn't properly loaded without some changes.

I followed all the rest of the steps, with some changes to the XML read step, because the BonusTypeStruct is read differently (CvXMLLoadUtilitySet.cpp):
Code:
void CvXMLLoadUtility::SetImprovementBonuses(CvImprovementBonusInfo** ppImprovementBonus)
{
	....
        ....

// initialize the boolean list to the correct size and all the booleans to false
InitImprovementBonusList(ppImprovementBonus, GC.getNumBonusInfos());
// set the local pointer to the memory we just allocated
paImprovementBonus = *ppImprovementBonus;

         ...
         ...

GetNextXmlVal(&paImprovementBonus[iBonusIndex].m_bBonusMakesValid);

/* additions */
GetNextXmlVal(&paImprovementBonus[iBonusIndex].m_bBonusRequiredAt);
GetNextXmlVal(&paImprovementBonus[iBonusIndex].m_bBonusRequiredAdjacent);
GetNextXmlVal(&paImprovementBonus[iBonusIndex].m_bBonusRequiredCity);
GetNextXmlVal(&paImprovementBonus[iBonusIndex].m_bBonusRequiredCapital);
GetNextXmlVal(&paImprovementBonus[iBonusIndex].m_bBonusRequiredAnywhere);
/* end additions*/

GetNextXmlVal(&paImprovementBonus[iBonusIndex].m_bBonusTrade);
GetNextXmlVal(&paImprovementBonus[iBonusIndex].m_iDiscoverRand);

          ...
          ...
}

I also added some lines to initImprovementBonusList, to initialize the new members to false.

It still parses the XML fine, but the program is crashing sometime in the first few turns. I did add some implementation code, but it's all commented out now. I'm guessing that bad memory is being allocated somewhere, but in a codebase this big, I can't begin to figure out where. Any ideas?

Edit: Figured it out, I had null pointers cropping up in certain cases (trying to get the barbarian's capital, for instance).
 
I would make you a question about adding XML new tags.
Why, and how to avoid, I add a new tag to a Building (putting minOccurs="0"/) so I don't have to add it everywhere, I make all the steps required by Tutorial, but when the game load, it crushes while loading XML (it says it's a prb of ci4SpecialBuildings... anyway I know it's a prb of new xml tag I added.
Once I added to units and to improvements new tags, for units no problems, and for improvements same problem.

so anyone knows why?

I link here 2 threads to show you more pricesely what happened with improvements that is the same as buildigns.
thx.

http://forums.civfanatics.com/showthread.php?t=216260
http://forums.civfanatics.com/showthread.php?t=195251

PLS, I don't know how i solved that prb, and I would understand how to avoid to make it happens again.
 
Attach the relevant files and I will take a look (modified building file, schema file, and any changed SDK files).
 
sorry it worked for me 2 mins before...

here you are.

It looks to be defined pretty well. But if I were you I would add that attribute to all buildings, even if it is just set to 0. Even though you have set the min value to make no occurances valid according to xml schema the SDK still has to read it.

And it should be easy to do a search and replace for </FoodKept> and throw <iOilConsumption>0</iOilConsumption> behind it.

I would also recommend removing comments from the xml files. I have seen some odd problems with those, the SDK isnt the most XML aware app in the world.

Let me know if either of those solve your issue.
 
it returns always the same prb...
really I don't figure why...

Okay, remove your custom dll and see if you have the issue (ie: see if it will load just the modified schema and xml).
 
Weird. K, link up your entire mod and I'll check it out.
 
Back
Top Bottom