Files
oboe/rsrc/schemas/scenario.xsd
Celtic Minstrel c1fa65a01d Much better error-checking when loading scenarios
- First of all, the program no longer crashes after an error.
- A lot more constraints are now checked for, such as required elements; even some constraints not expressed in the schema
- Special node parsing now has actually useful error messages
- Map data parsing now has error messages for the few invalid cases
- Fix the XML utility exception classes originally used only by the dialog engine; they're now correctly caught and properly report the error
- Fix loading of special shop entries
- Fix accepting any character as the separator in dice constants
- Verify that the monster ability type is on the right ability tag, that the extra element is present only if needed for general abilities, and that the missile and range elements are present for non-touch general abilities
- Use "infinite" for quantity in special shop items, instead of 0
- Tweak ticpp to fill out file/line/col information for _all_ exceptions, not just parse errors
- Raise error (ie, set stream failbit) when failing to convert an enumerator, instead of silently returning a default value (they do still return a default value though, if you don't bother to check stream state)
- Fix status effect enumerator not being correctly saved/loaded
2015-06-29 19:55:59 -04:00

386 lines
12 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="bool">
<xs:restriction base="xs:token">
<xs:enumeration value="true"/>
<xs:enumeration value="false"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name='shop-amount'>
<xs:union memberTypes='xs:integer'>
<xs:simpleType>
<xs:restriction base='xs:string'>
<xs:enumeration value='infinite'/>
</xs:restriction>
</xs:simpleType>
</xs:union>
</xs:simpleType>
<xs:attributeGroup name="rect">
<xs:attribute name="top" use="required" type="xs:integer"/>
<xs:attribute name="left" use="required" type="xs:integer"/>
<xs:attribute name="bottom" use="required" type="xs:integer"/>
<xs:attribute name="right" use="required" type="xs:integer"/>
</xs:attributeGroup>
<xs:attributeGroup name="point">
<xs:attribute name="x" use="required" type="xs:integer"/>
<xs:attribute name="y" use="required" type="xs:integer"/>
</xs:attributeGroup>
<xs:element name="icon">
<xs:complexType mixed="true">
<xs:attribute name="custom" type="bool" default="false"/>
<xs:attribute name="split" type="bool" default="false"/>
<xs:attribute name="row" type="xs:integer" default="0"/>
<xs:attribute name="col" type="xs:integer" default="0"/>
</xs:complexType>
</xs:element>
<xs:element name="version" type="xs:string"/>
<xs:element name="author">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="email" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="text">
<xs:complexType>
<xs:sequence>
<xs:element name="teaser" minOccurs="0" maxOccurs="2" type="xs:string"/>
<xs:element ref="icon" minOccurs="0"/>
<xs:element name="intro-msg" minOccurs="0" maxOccurs="6" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="ratings">
<xs:complexType>
<xs:all>
<xs:element name="content">
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="g"/>
<xs:enumeration value="pg"/>
<xs:enumeration value="r"/>
<xs:enumeration value="nc17"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="difficulty">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="4"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="flags">
<xs:complexType>
<xs:sequence>
<xs:element name="adjust-difficulty" type="bool"/>
<xs:element name="legacy" type="xs:string"/>
<xs:element name="custom-graphics" type="bool"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="creator">
<xs:complexType>
<xs:sequence>
<xs:element name="type" type="xs:string"/>
<xs:element ref="version"/>
<xs:element name="os" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name='entries'>
<xs:complexType>
<xs:choice minOccurs='0' maxOccurs='30'>
<xs:element name='item'>
<xs:complexType><xs:simpleContent>
<xs:extension base='xs:integer'>
<xs:attribute name='quantity' type='shop-amount' default='0'/>
<xs:attribute name='chance' type='xs:integer' default='100'/>
</xs:extension>
</xs:simpleContent></xs:complexType>
</xs:element>
<xs:element name='mage-spell'>
<xs:simpleType>
<xs:restriction base='xs:integer'>
<xs:minInclusive value='0'/>
<xs:maxInclusive value='61'/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name='priest-spell'>
<xs:simpleType>
<xs:restriction base='xs:integer'>
<xs:minInclusive value='0'/>
<xs:maxInclusive value='61'/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name='recipe'>
<xs:simpleType>
<xs:restriction base='xs:integer'>
<xs:minInclusive value='0'/>
<xs:maxInclusive value='19'/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name='skill'>
<xs:simpleType>
<xs:restriction base='xs:integer'>
<xs:minInclusive value='0'/>
<xs:maxInclusive value='20'/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name='treasure'>
<xs:simpleType>
<xs:restriction base='xs:integer'>
<xs:minInclusive value='0'/>
<xs:maxInclusive value='4'/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name='class'>
<xs:simpleType>
<xs:restriction base='xs:integer'>
<xs:minInclusive value='1'/>
<xs:maxInclusive value='100'/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name='heal'>
<xs:simpleType>
<xs:restriction base='xs:integer'>
<xs:minInclusive value='0'/>
<xs:maxInclusive value='9'/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name='special'>
<xs:complexType>
<xs:all>
<xs:element name='name' type='xs:string'/>
<xs:element name='description' type='xs:string'/>
<xs:element name='node' type='xs:integer'/>
<xs:element name='quantity' type='shop-amount'/>
<xs:element name='cost' type='xs:integer' minOccurs="0"/>
<xs:element name='icon' type='xs:integer'/>
</xs:all>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:element name="game">
<xs:complexType>
<xs:sequence>
<xs:element name="num-towns" type="xs:integer"/>
<xs:element name="out-width" type="xs:integer"/>
<xs:element name="out-height" type="xs:integer"/>
<xs:element name="on-init" type="xs:integer" minOccurs="0"/>
<xs:element name="start-town" type="xs:integer"/>
<xs:element name="town-start">
<xs:complexType>
<xs:attributeGroup ref="point"/>
</xs:complexType>
</xs:element>
<xs:element name="outdoor-start">
<xs:complexType>
<xs:attributeGroup ref="point"/>
</xs:complexType>
</xs:element>
<xs:element name="sector-start">
<xs:complexType>
<xs:attributeGroup ref="point"/>
</xs:complexType>
</xs:element>
<xs:element name="store-items" minOccurs="0" maxOccurs="3">
<xs:complexType>
<xs:attributeGroup ref="rect"/>
<xs:attribute name="town" type="xs:integer" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="town-flag" minOccurs="0" maxOccurs="10">
<xs:complexType>
<xs:attribute name="town" type="xs:integer" use="required"/>
<xs:attribute name="add-x" type="xs:integer" use="required"/>
<xs:attribute name="add-y" type="xs:integer" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="special-item" minOccurs="0" maxOccurs="50">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="description" type="xs:string"/>
</xs:sequence>
<xs:attribute name="special" type="xs:integer"/>
<xs:attribute name="start-with" type="bool"/>
<xs:attribute name="useable" type="bool"/>
</xs:complexType>
</xs:element>
<xs:element name="quest" minOccurs='0' maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name='deadline' minOccurs='0'>
<xs:complexType>
<xs:simpleContent>
<xs:extension base='xs:integer'>
<xs:attribute name="relative" type="bool"/>
<xs:attribute name='waive-if' type='xs:integer'/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name='reward' minOccurs='0'>
<xs:complexType>
<xs:attribute name='xp' type='xs:integer'/>
<xs:attribute name='gold' type='xs:integer'/>
</xs:complexType>
</xs:element>
<xs:element name='bank' type='xs:integer' minOccurs='0' maxOccurs='2'/>
<xs:element name="name" type="xs:string"/>
<xs:element name="description" type="xs:string"/>
</xs:sequence>
<xs:attribute name="start-with" type="bool"/>
</xs:complexType>
</xs:element>
<xs:element name="shop" minOccurs='0' maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name='name' type='xs:string'/>
<xs:element name='type'>
<xs:simpleType>
<xs:restriction base='xs:string'>
<xs:enumeration value='live'/>
<xs:enumeration value='dead'/>
<xs:enumeration value='rand'/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name='prompt'>
<xs:simpleType>
<xs:restriction base='xs:string'>
<xs:enumeration value='shop'/>
<xs:enumeration value='heal'/>
<xs:enumeration value='mage'/>
<xs:enumeration value='priest'/>
<xs:enumeration value='spell'/>
<xs:enumeration value='alch'/>
<xs:enumeration value='train'/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name='face' type='xs:integer'/>
<xs:element ref='entries'/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="timer" minOccurs="0" maxOccurs="20">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:integer">
<xs:attribute name="freq" type="xs:integer" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="string" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="id" type="xs:integer" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="journal" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="id" type="xs:integer" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="editor">
<xs:complexType>
<xs:sequence>
<xs:element name="default-ground" type="xs:integer"/>
<xs:element name="last-out-section">
<xs:complexType>
<xs:attributeGroup ref="point"/>
</xs:complexType>
</xs:element>
<xs:element name="last-town" type="xs:integer"/>
<xs:element name="graphics" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="pic" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:integer">
<xs:attribute name="index" type="xs:integer" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="storage" minOccurs="0" maxOccurs="10">
<xs:complexType>
<xs:sequence>
<xs:element name="on-terrain" type="xs:integer"/>
<xs:element name="is-property" type="bool"/>
<xs:element name="item" minOccurs="0" maxOccurs="10">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:integer">
<xs:attribute name="chance" type="xs:integer" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="sound" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="id" type="xs:integer" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="scenario">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element ref="icon"/>
<xs:element name="id" type="xs:string"/>
<xs:element ref="version"/>
<xs:element name="language" type="xs:language"/>
<xs:element ref="author"/>
<xs:element ref="text"/>
<xs:element ref="ratings"/>
<xs:element ref="flags"/>
<xs:element ref="creator"/>
<xs:element ref="game"/>
<xs:element ref="editor"/>
</xs:sequence>
<xs:attribute name="boes" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>