Paprika = Ethnic Buildings + WoC Lite + further changes

cool3a2

Deity
Joined
Mar 30, 2007
Messages
2,177
Paprika = Ethnic Buildings + WoC Lite + further changes
Some C vitamine for a longer life of civ4...

So this is the result of my work of merging Asafs Ethnic Buildings modcomp with WoC Lite plus making further changes. The goal is to make a few things moddable the modular way, namely:
- building art (no support for citysets and improvements though)
- diplotexts
- audio (only quasi modular, which means that you will have to use a runnable jar to merge the audios xml)

There is no change to the WoC Lite code, so everything that was possible with WoC should be possible with this modcomp, too. Instead, my changes adressed Asafs Ethnic Buildings code as I didn't want to be restricted to early middle and late 'eras' as it is done with units (where it is okay IMO). This ways, there can be unique art for any building for any civ and for any era. This is how it is meant to look:

Spoiler :
<BuildingArtStyleTypeInfos>
<BuildingArtStyleTypeInfo>
<Type>BUILDING_ARTSTYLE_USA</Type>
<StyleBuildings>
<StyleBuilding>
<BuildingType>BUILDING_BARRACKS</BuildingType>
<BuildingMeshGroup>
<AncientArtDefineTag>ART_DEF_BUILDING_HUNG_VEGVAR</AncientArtDefineTag>
<ClassicalArtDefineTag>ART_DEF_BUILDING_BARRACKS</ClassicalArtDefineTag>
<MedievalArtDefineTag>ART_DEF_BUILDING_HUNG_VEGVAR</MedievalArtDefineTag>
<RenaissanceArtDefineTag>ART_DEF_BUILDING_BARRACKS</RenaissanceArtDefineTag>
<IndustrialArtDefineTag>ART_DEF_BUILDING_HUNG_VEGVAR</IndustrialArtDefineTag>
<ModernArtDefineTag>ART_DEF_BUILDING_BARRACKS</ModernArtDefineTag>
<FutureArtDefineTag>ART_DEF_BUILDING_HUNG_VEGVAR</FutureArtDefineTag>​
</BuildingMeshGroup>​
</StyleBuilding>​
</StyleBuildings>​
</BuildingArtStyleTypeInfo>​
</BuildingArtStyleTypeInfos>

Where the artdefs are done the common (modular) way. There is also a new element in the CivilizationsInfo file specifying the civs building artstyle, see readme coming with the package. There is also a simple example civ provided as separate package to show how things work.

As WoC Lite alters the look and behaviour of civ4 a bit, while there may be people that rather like to keep BtS in its original form (like me), I provided another package containing Asafs python Script from his Ethnic Building modcomp and further details about what can be deleted and what to take care for.

Downloads:
Paprika modcomp: http://forums.civfanatics.com/downloads.php?do=file&id=17078
Alternative python script and strip howto: http://forums.civfanatics.com/downloads.php?do=file&id=17079
Simple example civ to show how this works: http://forums.civfanatics.com/downloads.php?do=file&id=17080

Credits:
- Asaf for his Ethnic Building modcomp and his help to find the way through the sources
- The WoC and WoC Lite guys
- A couple of more people mentioned in the readme file in the modcomps package.
 
Congrats :goodjob:

Glad to see everything's working.
Can you add screen shots for your example civ? Or I can d/l and run it later ;)

I have a suggestion to make it even more moddable (I've just thought of that):
Instead of hard-coding the eras in the building art style type, you could have something like:
Code:
<StyleBuilding>

    <BuildingType>BUILDING_BARRACKS</BuildingType>
    <BuildingMeshGroup>
        <ArtDefine>
                <Era>ERA_ANCIENT</Era>
                <ArtDefineTag>ART_DEF_BUILDING_HUNG_VEGVAR</ArtDefineTag>
        </ArtDefine>
        <ArtDefine>
                <Era>ERA_CLASSICAL</Era>
                <ArtDefineTag>ART_DEF_BUILDING_BARRACKS</ArtDefineTag>
        </ArtDefine>
...

And so on. That way, you could modify the eras without changing the C++ code.
(Sorry for not coming up with it before you released you mod :blush:)
But that's another feature...
 
Thanks, Asaf! :)

I have a suggestion to make it even more moddable (I've just thought of that):
Instead of hard-coding the eras in the building art style type, you could have something like...
Yeah, I was also thinking about that matter but didn't come that far yet. For my purposes this is already fine the way it is though, so this case won't get high priority for now. Your idea is got though, I'll keep it in mind. I'd just need to think how to make sure that the era given exists or at least that invalid xml won't cause crashs.

The example civ is not a big thing. Nothing actually changed, only provided the xml that I cited in post #1 making the civ use a unique barracks art. Nothing else really. It was meant for teaching purposes primarily. I don't see need to give screenshots. As it is somewhat handy, I ported my Hun mod to this to have a test before releasing the Paprika modcomp. I just didn't upload the ported Huns yet, I wanted to wait with that till my Hungary mod is finished, too. Although I'm working like an animal, I have no clue when this will be...
 
I have thought about what you said, Asaf, and I think that I will give this a shot. Even before I release the next version of my Hungary mod (as otherwise I would have to update my xmls again). Nevertheless, I think it is crucial that we validate the xml if we have it this ways. At least the eras should be compared to those from the Civ4EraInfos.xml. Regarding the artdefs, I would install a fallback to the default art if the artdef given is invalid or if there is no artdef for an era at all. In the former case, a validation to infrom the modder would also be nice. DOes anyone know how to force the game to validate the xmls this ways?
 
You mean validating the XML's besides asserts and log errors?
Because AFAIK that's the way it's done in the Firaxis code.
 
You mean validating the XML's besides asserts and log errors?
Because AFAIK that's the way it's done in the Firaxis code.
Well, that I want to get, is, that the game will complain about an invalid artdef or at least era if there is something like that while loading the mod. If I'm not mistaken, the game does that for some things, not for everything though. I could code that in C++, I guess, but I think that this would not be the proper place as the other xml errors happen at a different time, it seems. I'd say this is rather something with xml and schema, not sure though.

Hmmm... I may have used the phrase 'validating' improperly. I think an XML is 'valid' if it matches a schema, which does not seem to be the issue here.
 
So I started working on your suggestion, and thought that I got it done already, but ran into trouble. Basically, the game fails to load a bunch of xmls. Must have something to do with my read method:
bool CvBuildingArtStyleTypeInfo::read(CvXMLLoadUtility* pXML)
{
int i;
int iNumSibs;
int iIndex; // Building Index

CvString szTextVal;
if (!CvInfoBase::read(pXML))
{
return false;
}

if (gDLL->getXMLIFace()->SetToChildByTagName(pXML->GetXML(),"StyleBuildings"))
{
if (pXML->SkipToNextVal())
{
iNumSibs = gDLL->getXMLIFace()->GetNumChildren(pXML->GetXML());
if (gDLL->getXMLIFace()->SetToChild(pXML->GetXML()))
{
if (0 < iNumSibs)
{
for (i = 0; i < iNumSibs; i++)
{
pXML->GetChildXmlValByName(szTextVal, "BuildingType");
iIndex = pXML->FindInInfoClass(szTextVal);

if (iIndex > -1)
{
if (gDLL->getXMLIFace()->SetToChildByTagName(pXML->GetXML(),"BuildingArtDefines"))
{
ArtDefines kTag;
kTag.iBuildingType = iIndex;

bool bFoundArt = false;

if (gDLL->getXMLIFace()->SetToChildByTagName(pXML->GetXML(),"BuildingArtDefine"))
{
std::pair<CvString, CvString> firstArtDef;
if ((pXML->GetChildXmlValByName(firstArtDef.first, "Era")) && (pXML->GetChildXmlValByName(firstArtDef.second, "ArtDefineTag")))
{

kTag.BuildingArtdefArray.push_back(firstArtDef);
bFoundArt = true;
}

while(gDLL->getXMLIFace()->NextSibling(pXML->GetXML()))
{
std::pair<CvString, CvString> currentArtDef;
if ((pXML->GetChildXmlValByName(currentArtDef.first, "Era")) && (pXML->GetChildXmlValByName(currentArtDef.second, "ArtDefineTag")))
{
kTag.BuildingArtdefArray.push_back(currentArtDef);
bFoundArt = true;
}
}
}

if (bFoundArt)
{
// Found at least one art define tag, so add it to our list
m_azArtDefineTags.push_back(kTag);
}

gDLL->getXMLIFace()->SetToParent(pXML->GetXML());
gDLL->getXMLIFace()->SetToParent(pXML->GetXML());
}
}

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

return true;
}
(it's propably the best if you copy the code and paste the code to an editor...)

I basically kept your xml, just renamed some elements:
<BuildingArtStyleTypeInfo>
<Type>BUILDING_ARTSTYLE_USA</Type>
<StyleBuildings>
<StyleBuilding>
<BuildingType>BUILDING_BARRACKS</BuildingType>
<BuildingArtDefines>
<BuildingArtdefine>
<Era>ERA_ANCIENT</Era>
<ArtDefineTag>ART_DEF_BUILDING_HUNG_VEGVAR</ArtDefineTag>
</BuildingArtdefine>
<BuildingArtdefine>
<Era>ERA_CLASSICAL</Era>
<ArtDefineTag>ART_DEF_BUILDING_BARRACKS</ArtDefineTag>
</BuildingArtdefine>
<BuildingArtdefine>
<Era>ERA_MEDIEVAL</Era>
<ArtDefineTag>ART_DEF_BUILDING_HUNG_VEGVAR</ArtDefineTag>
</BuildingArtdefine>
<BuildingArtdefine>
<Era>ERA_RENAISSANCE</Era>
<ArtDefineTag>ART_DEF_BUILDING_BARRACKS</ArtDefineTag>
</BuildingArtdefine>
<BuildingArtdefine>
<Era>ERA_INDUSTRIAL</Era>
<ArtDefineTag>ART_DEF_BUILDING_HUNG_VEGVAR</ArtDefineTag>
</BuildingArtdefine>
<BuildingArtdefine>
<Era>ERA_MODERN</Era>
<ArtDefineTag>ART_DEF_BUILDING_BARRACKS</ArtDefineTag>
</BuildingArtdefine>
<BuildingArtdefine>
<Era>ERA_FUTURE</Era>
<ArtDefineTag>ART_DEF_BUILDING_HUNG_VEGVAR</ArtDefineTag>
</BuildingArtdefine>
</BuildingArtDefines>
</StyleBuilding>
</StyleBuildings>
</BuildingArtStyleTypeInfo>

The interesting part of the schema:
<!-- Ethnic Buildings (Asaf) - Start -->
<ElementType name="Era" content="textOnly"/>
<ElementType name="ArtDefineTag" content="textOnly"/>
<ElementType name="BuildingArtDefine" content="textOnly">
<ElementType name="Era" minOccurs="0" maxOccurs="1"/>
<ElementType name="ArtDefineTag" minOccurs="0" maxOccurs="1"/>
</ElementType>
<ElementType name="BuildingArtDefines" content="eltOnly">
<element type="BuildingArtDefine" minOccurs="0" maxOccurs="*"/>
</ElementType>
<ElementType name="StyleBuilding" content="eltOnly">
<element type="BuildingType" minOccurs="0" maxOccurs="1"/>
<element type="BuildingArtDefines" minOccurs="0" maxOccurs="1"/>
</ElementType>
<ElementType name="StyleBuildings" content="eltOnly">
<element type="StyleBuilding" minOccurs="0" maxOccurs="*"/>
</ElementType>
<ElementType name="BuildingArtStyleTypeInfo" content="eltOnly">
<element type="Type"/>
<element type="StyleBuildings" minOccurs="0" maxOccurs="1"/>
</ElementType>
<ElementType name="BuildingArtStyleTypeInfos" content="eltOnly">
<element type="BuildingArtStyleTypeInfo" minOccurs="0" maxOccurs="*"/>
</ElementType>
<ElementType name="Civ4BuildingArtStyleTypeInfos" content="eltOnly">
<element type="BuildingArtStyleTypeInfos" minOccurs="0"/>
</ElementType>
<!-- Ethnic Buildings (Asaf) - End -->

Let me know if you see something that is incorrect.

BTW: As far as I can see, all the eras get stored in an enum. Theoretically, I could query that to find out whether the specified era is valid. If it is not, I would inform the user and prevent the definition in question from being saved. Shouldn't harm, if I would save them, as they just never get queried, but we could save some memory this ways. Anyways, I'd have to compare them with a string somehow, but I don't want to store the eras in a list temporary as this appears to be too dirty to me. Also, I just found a microsoft dependend solution to convert between string and era. Don't like this, because I don't know what happens if a Mac user try to compile my code. Well, don't know if that is possible at all either...
 
I haven't checked everything (I don't have the definition for the ArtDefines C++ struct/class, for one), but your schema seems illegal.
Try replacing the schema you posted with this one:
Code:
  <ElementType name="Era" content="textOnly"/>
  <ElementType name="BuildingArtDefine" content="textOnly">
[B]    <element type="Era" minOccurs="0" maxOccurs="1"/>
    <element type="ArtDefineTag" minOccurs="0" maxOccurs="1"/>
[/B]  </ElementType>
  <ElementType name="BuildingArtDefines" content="eltOnly">
    <element type="BuildingArtDefine" minOccurs="0" maxOccurs="*"/>
  </ElementType>
  <ElementType name="StyleBuilding" content="eltOnly">
    <element type="BuildingType" minOccurs="0" maxOccurs="1"/>
    <element type="BuildingArtDefines" minOccurs="0" maxOccurs="1"/>
  </ElementType>
  <ElementType name="StyleBuildings" content="eltOnly">
    <element type="StyleBuilding" minOccurs="0" maxOccurs="*"/>
  </ElementType>
  <ElementType name="BuildingArtStyleTypeInfo" content="eltOnly">
    <element type="Type"/>
    <element type="StyleBuildings" minOccurs="0" maxOccurs="1"/>
  </ElementType>
  <ElementType name="BuildingArtStyleTypeInfos" content="eltOnly">
    <element type="BuildingArtStyleTypeInfo" minOccurs="0" maxOccurs="*"/>
  </ElementType>
  <ElementType name="Civ4BuildingArtStyleTypeInfos" content="eltOnly">
    <element type="BuildingArtStyleTypeInfos" minOccurs="0"/>
  </ElementType>

Note that I removed the definition of "ArtDefineTag" (it was already defined in the file) and that I changed the declaration inside BuildingArtDefine.

Visual Studio marks these errors, so try adding the XML and schema files to your project, or create another project specifically for XML in the solution (Maybe it'll show you the errors without adding the files to a project. I don't know).

BTW: As far as I can see, all the eras get stored in an enum. Theoretically, I could query that to find out whether the specified era is valid. If it is not, I would inform the user and prevent the definition in question from being saved. Shouldn't harm, if I would save them, as they just never get queried, but we could save some memory this ways. Anyways, I'd have to compare them with a string somehow, but I don't want to store the eras in a list temporary as this appears to be too dirty to me. Also, I just found a microsoft dependend solution to convert between string and era. Don't like this, because I don't know what happens if a Mac user try to compile my code. Well, don't know if that is possible at all either...

Reg. Mac - the code here is Windows-specific, and there is no C++ code released for Civ4 for mac, so it doesn't really matter.

Reg. the enum - you have GC.getInfoTypeForString() which returns the enum value of the string, or -1 if it is unknown.
 
I'm in hurry a bit, which is why I forgot to post the class that the Artdefines is part of and would have told you anything you'd need to know:
/* Ethnic Buildings (Asaf, Cool3a2) - Start */
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// class : CvBuildingArtStyleTypeInfo
// Unlike CvUnitArtStyleTypeInfo, it does NOT support multiple mesh groups.
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class CvBuildingArtStyleTypeInfo : public CvInfoBase
{
public:

CvBuildingArtStyleTypeInfo();
virtual ~CvBuildingArtStyleTypeInfo();

const TCHAR* getEraArtDefineTag(CvString szEra, int /*BuildingTypes*/ j) const;

bool read(CvXMLLoadUtility* pXML);

protected:

struct ArtDefines
{
int iBuildingType;
std::vector< std::pair<CvString, CvString> > BuildingArtdefArray;
};

typedef std::vector<ArtDefines> ArtDefineArray;
ArtDefineArray m_azArtDefineTags;
};
/* Ethnic Buildings (Asaf) - End */
So the Artdefines is just an int and a vector. The vector just saves pairs of era and artdef.

Thanks for the the other hints! I'll add the xmls to my project next time I work on this to have some sort of syntax highlighting etc. Also, the function you mentioned should just be perfect for my purposes!
 
I just forgot to mention the main point of my last post: the xml chnages did not solve the problem, the game still throws a ton of xml errors at me... Even those files are affected, that haven't been changed actually.
 
Okay, I think I got it working basically. I just need to inform the user about wrong xmls, that means if an era or an artdef doesn't exist. This is already handled that ways that invalid specifications aren't saved in the list of artdefs of a building, but the modder won't notice anything ATM. There should be some routine that takes a string and will then issue a dialog or something. Doesn't seem to be FAssertMsg as there is no error message in this case. Does anyone know what's the proper routine?
Also, I have to check what happens if there is no definition for a certain era. I guess that the art from the previous era will kept to be used, but that's not what a modder would expect to happen. It would be better if the default art would be used. Not 100% sure, but I think I can get that done by my own.

EDIT: Don't mind it. A wrong era is already handled automatically and by looking up that function that handles the era, I found out a proper routine to issue error messages. Also, a fallback to default artdef is already working, in contrast to what I thought. I will know do some evil things with the xml to simulate how the dll responds on a drunken modder. Could be of use for a certain leaderhead modder that is currently working on a mod similar to VD (;)).
 
Okay, I've got a little problem. I wanted the dll to validate the xml against its schema and I'm currently doing that explicitely (although that is actually not necessary, I guess) using...
if (!gDLL->getXMLIFace()->Validate(pXML->GetXML()))
{
char errorMsg[1024];
sprintf(errorMsg, "XML is invalid according to its schema.\nCurrent XML file is: %s", GC.getCurrentXMLFile().GetCString());
gDLL->MessageBox(errorMsg, "XML Error");
return false;
}
The problem is that even incorrect xmls (without a line for an era for example) pass the check. This wouldn't cause crashs later, but I'd prefer to inform the modder. My schema:
<Schema>
...
<!-- Ethnic Buildings (Asaf) - Start -->
<ElementType name="Era" content="textOnly"/>
<ElementType name="BuildingArtDefine">
<element type="Era" minOccurs="1" maxOccurs="1"/>
<element type="ArtDefineTag" minOccurs="1" maxOccurs="1"/>
</ElementType>
<ElementType name="BuildingArtDefines" content="eltOnly">
<element type="BuildingArtDefine" minOccurs="1" maxOccurs="*"/>
</ElementType>
<ElementType name="StyleBuilding" content="eltOnly">
<element type="BuildingType" minOccurs="0" maxOccurs="1"/>
<element type="BuildingArtDefines" minOccurs="1" maxOccurs="1"/>
</ElementType>
<ElementType name="StyleBuildings" content="eltOnly">
<element type="StyleBuilding" minOccurs="0" maxOccurs="*"/>
</ElementType>
<ElementType name="BuildingArtStyleTypeInfo" content="eltOnly">
<element type="Type"/>
<element type="StyleBuildings" minOccurs="0" maxOccurs="1"/>
</ElementType>
<ElementType name="BuildingArtStyleTypeInfos" content="eltOnly">
<element type="BuildingArtStyleTypeInfo" minOccurs="0" maxOccurs="*"/>
</ElementType>
<ElementType name="Civ4BuildingArtStyleTypeInfos" content="eltOnly">
<element type="BuildingArtStyleTypeInfos" minOccurs="0"/>
</ElementType>
<!-- Ethnic Buildings (Asaf) - End -->

<ElementType name="Civ4Civilizations" content="eltOnly">
<element type="LeaderHeadInfos" minOccurs="0" maxOccurs="*"/>
<element type="TraitInfos" minOccurs="0" maxOccurs="*"/>
<element type="CivilizationInfos" minOccurs="0" maxOccurs="*"/>
<element type="UnitArtStyleTypeInfos" minOccurs="0" maxOccurs="*"/>
<element type="BuildingArtStyleTypeInfos" minOccurs="0" maxOccurs="*"/>
</ElementType>
</Schema>
(Left some things out...)

And my xml:
<?xml version="1.0"?>
<!-- Created by Asaf for Ethnic Buildings Mod -->
<!-- Sid Meier's Civilization 4 -->
<!-- -->
<Civ4BuildingArtStyleTypeInfos xmlns="x-schema:USA_CIV4CivilizationsSchema.xml">
<BuildingArtStyleTypeInfos>
<!-- This is an example, and these art defs are not really defined. See readme.txt for information how to use this Mod -->
<BuildingArtStyleTypeInfo>
<Type>BUILDING_ARTSTYLE_USA</Type>
<StyleBuildings>
<StyleBuilding>
<BuildingType>BUILDING_STABLE</BuildingType>
<BuildingArtDefines>
<BuildingArtDefine>
<Era>ERA_ANCIENT</Era>
<ArtDefineTag>ART_DEF_BUILDING_HUNG_VEGVAR</ArtDefineTag>
</BuildingArtDefine>
<BuildingArtDefine>
<Era>ERA_MEDIEVAL</Era>
<ArtDefineTag>ART_DEF_BUILDING_HUNG_VEGVAR</ArtDefineTag>
</BuildingArtDefine>
<BuildingArtDefine>
<Era>ERA_RENAISSANCE</Era>
<ArtDefineTag>ART_DEF_BUILDING_BARRACKS</ArtDefineTag>
</BuildingArtDefine>
<Era>ERA_INDUSTRIAL</Era>
<ArtDefineTag>ART_DEF_BUILDING_HUNG_VEGVAR</ArtDefineTag>
<BuildingArtDefine>
</BuildingArtDefine>
<BuildingArtDefine>
<Era>ERA_MODERN</Era>
<ArtDefineTag>ART_DEF_BUILDING_BARRACKS</ArtDefineTag>
</BuildingArtDefine>
<BuildingArtDefine>
<Era>ERA_FUTURE</Era>
</BuildingArtDefine>
</BuildingArtDefines>
</StyleBuilding>
</StyleBuildings>
</BuildingArtStyleTypeInfo>
</BuildingArtStyleTypeInfos>
</Civ4BuildingArtStyleTypeInfos>
Any ideas?

EDIT: Anyways, I have uploaded a beta of this modcomp: http://www.mediafire.com/file/5wv7siw4wldhdb5/Paprika_v02beta.7z. Note, that the validation gainst the schema is still not working, I would appreciate any hint.
 
AFAIK, xml schema validation is already done...

I'm just guessing here, but I think that's the problem:
Code:
<Civ4BuildingArtStyleTypeInfos xmlns="x-schema:[B]USA_[/B]CIV4CivilizationsSchema.xml">

Replace all? ;)

Just a small comment: I think 'minOccurs="1" maxOccurs="1"' is the default, so you don't need to specify that. But you can leave it to make it clearer.
 
AFAIK, xml schema validation is already done...

I'm just guessing here, but I think that's the problem:
Code:

<Civ4BuildingArtStyleTypeInfos xmlns="x-schema:USA_CIV4CivilizationsSchema.xml">

Replace all?
I'm afraid I don't get your point... For modular loading, you have to provide a copy of the schema with your module that you have to refer to from your modules xml files (so my ArtStyleBuildingInfos refers to the Schema file named USA_CIV4CivilizationsSchema.xml). That's how it need to be done AFAIK. Well, maybe I missed your point as I'm weary already...

Just a small comment: I think 'minOccurs="1" maxOccurs="1"' is the default, so you don't need to specify that. But you can leave it to make it clearer.
Oh, okay. I'll keep that in mind. Thanks!
 
Oh, I never used modular loading so I didn't know each one has a separate schema... :blush: (why is that?)

I don't see the method Validate() used anywhere in the code, so I'm not sure it is really implemented properly...
 
Oh, I never used modular loading so I didn't know each one has a separate schema... (why is that?)
Ah, okay. No prob. Can't tell why you always have to provide a copy of the schema file. I assume that for some reason the original schema can't be found. I'm somewhat sure that the modular xmls validation happens before it is merged with the initial xml. In this case, I could imagine that the schema file needs to be located in the same directory. But that's pretty much a guess only. I'm just pretty sure that you have to do it if you mod the modular way.

I don't see the method Validate() used anywhere in the code, so I'm not sure it is really implemented properly...
I was thinking that some basic reading functions may use it, but if you say you couldn't find it anywhere (haven't checked it myself), you might be right by stating that it is not implemented properly. Nevertheless, I would have expected that the xml egts validated automatically anyways. Still, the xml seems to pass the validation...
 
Urgh... I was searching for a tool that would validate my xml with the same intention you had when suggesting VS. I spent hours for that as I didn't know that VS is able to validate, too. Before, I only added the empty version of the BuildingArtStylesFile which obviously doesn't cause any trouble. Strangely, the game didn't complain about that either... Not a good sign. Now that I added the modular file, it show me some errors that I wasn't aware of myself. Nevertheless, the missing <ArtDefineTag> element doesn't lead to validation errors. Seems like the schema isn't okay...
 
I'm a bit in hurry right now, so this won't be Goethe, sorry.

The xml was meant to be invalid due to a missing <ArtDefineTag> element. Besides of this, there was another mistake I wasn't aware of myself. An Era and a <ArtDefineTag> element were not surrounded by <BuildingArtDefine> tatgs. VS recognized the latter, but not the former. The game recognized neither. Meanwhile, I found out what is the solution for my initial problem. This one:
<ElementType name="BuildingArtDefine">
<element type="Era" minOccurs="1" maxOccurs="1"/>
<element type="ArtDefineTag" minOccurs="1" maxOccurs="1"/>
</ElementType>
should have been like this one:
<ElementType name="BuildingArtDefine" content="eltOnly">
<element type="Era" minOccurs="1" maxOccurs="1"/>
<element type="ArtDefineTag" minOccurs="1" maxOccurs="1"/>
</ElementType>
Seems like that content type makes the children automatically a sequence. I found that out when taking a look at the following page trying to add an order attribut: http://www.ltg.ed.ac.uk/~ht/XMLData-Reduced.htm. VS then complained that the content should be element only for this type of order, once I added that content type, the order was unnecessary. Seems like element only is sequence anyways. The game now recognizes the initial xml error I intentionally made, even without an explicite XmlValidation. Need to check what's with the other error I wasn't aware of before (corrected it temporarily).
 
Top Bottom