forked from github/server
verify xml loading, fix remaining files for e2.
This commit is contained in:
parent
434b7ae29e
commit
df255b886a
|
@ -1,4 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<eressea>
|
||||
<strings>
|
||||
<!--
|
||||
_d: dativ (wir erklären allen /Schlümpfen/ den Krieg)
|
||||
|
@ -7483,3 +7484,4 @@
|
|||
</string>
|
||||
|
||||
</strings>
|
||||
</eressea>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<eressea>
|
||||
<strings>
|
||||
<!--
|
||||
Due to extreme lazyness on Enno's part, this file doesn't contain everything.
|
||||
|
@ -1661,3 +1662,4 @@
|
|||
<text locale="en">mistletoes</text>
|
||||
</string>
|
||||
</strings>
|
||||
</eressea>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<eressea>
|
||||
<messages>
|
||||
<message name="nr_insectwinter" section="nr">
|
||||
<text locale="de">Es ist Winter, und Insekten können nur in Wüsten oder mit Hilfe des Nestwärme-Tranks Personen rekrutieren.</text>
|
||||
|
@ -1654,35 +1655,6 @@
|
|||
<text locale="de">"Der Eisberg $region($region) treibt nach $direction($dir)."</text>
|
||||
<text locale="en">"The iceberg $region($region) drifts $direction($dir)."</text>
|
||||
</message>
|
||||
<message name="setjihad" section="events">
|
||||
<type>
|
||||
<arg name="race" type="race"/>
|
||||
</type>
|
||||
<text locale="de">"Wir erklären allen $race($race,2) den heiligen Krieg."</text>
|
||||
<text locale="en">"We declare jihad on all $race($race,2)."</text>
|
||||
</message>
|
||||
<message name="pray_success" section="events">
|
||||
<type>
|
||||
<arg name="unit" type="unit"/>
|
||||
</type>
|
||||
<text locale="de">"Die Götter erhören $unit($unit)."</text>
|
||||
<text locale="en">"The Gods have listened to $unit($unit)."</text>
|
||||
</message>
|
||||
<message name="new_fspecial_level" section="events">
|
||||
<type>
|
||||
<arg name="special" type="string"/>
|
||||
<arg name="level" type="int"/>
|
||||
</type>
|
||||
<text locale="de">"Die Götter gewähren uns die Kraft eines $special($int($level))."</text>
|
||||
<text locale="en">"The Gods grant us the powers of $special ($int($level))."</text>
|
||||
</message>
|
||||
<message name="new_fspecial" section="events">
|
||||
<type>
|
||||
<arg name="special" type="string"/>
|
||||
</type>
|
||||
<text locale="de">"Die Götter gewähren uns die Kraft eines ${special}."</text>
|
||||
<text locale="en">"The Gods grant us the powers of ${special}."</text>
|
||||
</message>
|
||||
<message name="casualties" section="battle">
|
||||
<type>
|
||||
<arg name="unit" type="unit"/>
|
||||
|
@ -8295,3 +8267,4 @@
|
|||
</message>
|
||||
|
||||
</messages>
|
||||
</eressea>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?xml version="1.0" ?>
|
||||
<eressea>
|
||||
<spellbook name="cerddor">
|
||||
<entry spell="song_of_healing" level="2" />
|
||||
<entry spell="song_of_confusion" level="4" />
|
||||
|
@ -36,3 +37,4 @@
|
|||
<entry spell="create_roqf" level="11" />
|
||||
<entry spell="blabbermouth" level="4" />
|
||||
</spellbook>
|
||||
</eressea>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?xml version="1.0" encoding="iso-8859-1" ?>
|
||||
<eressea>
|
||||
<spellbook name="draig">
|
||||
<entry spell="fireball" level="2" />
|
||||
<entry spell="combatrust" level="6" />
|
||||
|
@ -30,3 +31,4 @@
|
|||
<entry spell="create_firesword" level="12" />
|
||||
<entry spell="create_trollbelt" level="9" />
|
||||
</spellbook>
|
||||
</eressea>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?xml version="1.0" ?>
|
||||
<eressea>
|
||||
<spellbook name="gray">
|
||||
<entry spell="acidrain" level="8" />
|
||||
<entry spell="airship" level="6" />
|
||||
|
@ -165,3 +166,4 @@
|
|||
<entry spell="wolfhowl" level="7" />
|
||||
<entry spell="wyrm_transformation" level="1" />
|
||||
</spellbook>
|
||||
</eressea>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?xml version="1.0" ?>
|
||||
<eressea>
|
||||
<spellbook name="gwyrrd">
|
||||
<entry spell="hail" level="3" />
|
||||
<entry spell="rustweapon" level="3" />
|
||||
|
@ -39,3 +40,4 @@
|
|||
<entry spell="create_aots" level="6" />
|
||||
<entry spell="create_magicherbbag" level="5" />
|
||||
</spellbook>
|
||||
</eressea>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?xml version="1.0" ?>
|
||||
<eressea>
|
||||
<spellbook name="illaun">
|
||||
<entry spell="bad_dreams" level="10" />
|
||||
<entry spell="gooddreams" level="8" />
|
||||
|
@ -27,4 +28,4 @@
|
|||
<entry spell="create_invisibility_sphere" level="13" />
|
||||
<entry spell="readmind" level="7" />
|
||||
</spellbook>
|
||||
|
||||
</eressea>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?xml version="1.0" ?>
|
||||
<eressea>
|
||||
<spellbook name="tybied">
|
||||
<entry spell="auratransfer" level="5" />
|
||||
<entry spell="antimagiczone" level="5" />
|
||||
|
@ -34,3 +35,4 @@
|
|||
<entry spell="create_rop" level="9" />
|
||||
<entry spell="create_bagofholding" level="10" />
|
||||
</spellbook>
|
||||
</eressea>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<eressea>
|
||||
<strings>
|
||||
<namespace name="spellinfo">
|
||||
<string name="concealing_aura">
|
||||
|
@ -117,3 +118,4 @@
|
|||
</string>
|
||||
</namespace>
|
||||
</strings>
|
||||
</eressea>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<eressea>
|
||||
<strings>
|
||||
<namespace name="spellinfo">
|
||||
<string name="headache">
|
||||
|
@ -403,3 +404,4 @@
|
|||
<text locale="fr">amulettes du chaton</text>
|
||||
</string>
|
||||
</strings>
|
||||
</eressea>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<eressea>
|
||||
<strings>
|
||||
|
||||
<string name="dragon_postfix_0">
|
||||
<text locale="de">der Weise</text>
|
||||
</string>
|
||||
|
@ -91,5 +91,5 @@
|
|||
<string name="dragon_postfix_29">
|
||||
<text locale="de">die Schöne</text>
|
||||
</string>
|
||||
|
||||
</strings>
|
||||
</eressea>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<eressea>
|
||||
<strings>
|
||||
|
||||
<string name="ghoul_prefix_0">
|
||||
<text locale="de">Faulende</text>
|
||||
</string>
|
||||
|
@ -113,3 +113,4 @@
|
|||
</string>
|
||||
|
||||
</strings>
|
||||
</eressea>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<eressea>
|
||||
<strings>
|
||||
|
||||
<string name="skeleton_prefix_0">
|
||||
<text locale="de">Klapperige</text>
|
||||
</string>
|
||||
|
@ -117,5 +117,5 @@
|
|||
<string name="skeleton_postfix_13">
|
||||
<text locale="de">aus der Unterwelt</text>
|
||||
</string>
|
||||
|
||||
</strings>
|
||||
</eressea>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<eressea>
|
||||
<strings>
|
||||
<string name="undead_prefix_0">
|
||||
<text locale="de">Grausige</text>
|
||||
|
@ -154,3 +155,4 @@
|
|||
</string>
|
||||
|
||||
</strings>
|
||||
</eressea>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<eressea>
|
||||
<strings>
|
||||
<string name="zombie_prefix_0">
|
||||
<text locale="de">Faulende</text>
|
||||
|
@ -106,3 +107,4 @@
|
|||
</string>
|
||||
|
||||
</strings>
|
||||
</eressea>
|
||||
|
|
|
@ -18,6 +18,13 @@ require 'tests.e2'
|
|||
require 'lunit'
|
||||
|
||||
rng.inject(0)
|
||||
eressea.settings.set("rules.food.flags", "4")
|
||||
eressea.settings.set("rules.ship.damage.nocrew", "0")
|
||||
eressea.settings.set("rules.ship.drifting", "0")
|
||||
eressea.settings.set("rules.ship.storms", "0")
|
||||
eressea.settings.set("rules.encounters", "0")
|
||||
eressea.settings.set("nmr.timeout", "0")
|
||||
eressea.settings.set("NewbieImmunity", "0")
|
||||
rules = require('eressea.' .. config.rules)
|
||||
result = lunit.main()
|
||||
return result.errors + result.failed
|
||||
|
|
|
@ -19,6 +19,13 @@ require 'lunit'
|
|||
|
||||
rng.inject(0)
|
||||
eressea.settings.set("rules.alliances", "0")
|
||||
eressea.settings.set("rules.food.flags", "4")
|
||||
eressea.settings.set("rules.ship.damage.nocrew", "0")
|
||||
eressea.settings.set("rules.ship.drifting", "0")
|
||||
eressea.settings.set("rules.ship.storms", "0")
|
||||
eressea.settings.set("rules.encounters", "0")
|
||||
eressea.settings.set("nmr.timeout", "0")
|
||||
eressea.settings.set("NewbieImmunity", "0")
|
||||
rules = require('eressea.' .. config.rules)
|
||||
result = lunit.main()
|
||||
return result.errors + result.failed
|
||||
|
|
|
@ -897,10 +897,10 @@ static int tolua_get_spells(lua_State * L)
|
|||
return tolua_selist_push(L, "spell_list", "spell", spells);
|
||||
}
|
||||
|
||||
static int init_data(const char *filename, const char *catalog)
|
||||
static int init_data(const char *filename)
|
||||
{
|
||||
int l;
|
||||
l = read_xml(filename, catalog);
|
||||
l = read_xml(filename);
|
||||
reset_locales();
|
||||
if (l) {
|
||||
return l;
|
||||
|
@ -915,8 +915,7 @@ static int init_data(const char *filename, const char *catalog)
|
|||
int tolua_read_xml(lua_State * L)
|
||||
{
|
||||
const char *filename = tolua_tostring(L, 1, "config.xml");
|
||||
const char *catalog = tolua_tostring(L, 2, "catalog.xml");
|
||||
lua_pushinteger(L, init_data(filename, catalog));
|
||||
lua_pushinteger(L, init_data(filename));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ int main(int argc, char **argv) {
|
|||
if (argc < 4) return usage();
|
||||
xmlfile = argv[2];
|
||||
catalog = argv[3];
|
||||
read_xml(xmlfile, catalog);
|
||||
read_xml(xmlfile);
|
||||
write_rules("rules.dat");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -928,7 +928,7 @@ static const char * uri_to_file(const char * uri, char *name, size_t size) {
|
|||
return path;
|
||||
}
|
||||
|
||||
static void include_json(const char *uri) {
|
||||
static int include_json(const char *uri) {
|
||||
FILE *F;
|
||||
char name[PATH_MAX];
|
||||
const char *filename = uri_to_file(uri, name, sizeof(name));
|
||||
|
@ -955,19 +955,22 @@ static void include_json(const char *uri) {
|
|||
}
|
||||
else {
|
||||
log_error("could not parse JSON from %s", uri);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
fclose(F);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void include_xml(const char *uri) {
|
||||
static int include_xml(const char *uri) {
|
||||
char name[PATH_MAX];
|
||||
const char *filename = uri_to_file(uri, name, sizeof(name));
|
||||
int err = read_xml(filename, NULL);
|
||||
if (err != 0) {
|
||||
int err = read_xml(filename);
|
||||
if (err < 0) {
|
||||
log_error("could not parse XML from %s", uri);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static void json_include(cJSON *json) {
|
||||
|
@ -978,12 +981,16 @@ static void json_include(cJSON *json) {
|
|||
}
|
||||
for (child = json->child; child; child = child->next) {
|
||||
const char *uri = child->valuestring;
|
||||
int err;
|
||||
|
||||
if (strstr(uri, ".xml") != NULL) {
|
||||
include_xml(uri);
|
||||
err = include_xml(uri);
|
||||
}
|
||||
else {
|
||||
include_json(uri);
|
||||
err = include_json(uri);
|
||||
}
|
||||
if (err != 0) {
|
||||
log_error("no data found in %s", uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4085,7 +4085,12 @@ static void reset_game(void)
|
|||
|
||||
void turn_begin(void)
|
||||
{
|
||||
int start = first_turn();
|
||||
assert(turn >= 0);
|
||||
if (turn < start) {
|
||||
/* this should only happen during tests */
|
||||
turn = start;
|
||||
}
|
||||
++turn;
|
||||
reset_game();
|
||||
}
|
||||
|
|
|
@ -77,7 +77,6 @@ double xml_fvalue(xmlNodePtr node, const char *name, double dflt)
|
|||
/* libxml includes */
|
||||
#include <libxml/tree.h>
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/xinclude.h>
|
||||
|
||||
typedef struct xml_reader {
|
||||
struct xml_reader *next;
|
||||
|
@ -108,33 +107,25 @@ void xml_register_callback(xml_callback callback)
|
|||
*insert = reader;
|
||||
}
|
||||
|
||||
int read_xml(const char *filename, const char *catalog)
|
||||
int read_xml(const char *filename)
|
||||
{
|
||||
xml_reader *reader = xmlReaders;
|
||||
xmlDocPtr doc;
|
||||
int result = 0;
|
||||
int results = 0;
|
||||
|
||||
if (catalog) {
|
||||
xmlLoadCatalog(catalog);
|
||||
}
|
||||
doc = xmlReadFile(filename, NULL, XML_PARSE_XINCLUDE | XML_PARSE_NONET | XML_PARSE_PEDANTIC | XML_PARSE_COMPACT);
|
||||
doc = xmlReadFile(filename, NULL, XML_PARSE_NONET | XML_PARSE_PEDANTIC | XML_PARSE_COMPACT);
|
||||
if (doc == NULL) {
|
||||
log_error("could not open '%s'\n", filename);
|
||||
return -1;
|
||||
}
|
||||
if (catalog) {
|
||||
result = xmlXIncludeProcessFlags(doc, XML_PARSE_XINCLUDE | XML_PARSE_NONET | XML_PARSE_PEDANTIC | XML_PARSE_COMPACT);
|
||||
}
|
||||
if (result >= 0) {
|
||||
while (reader != NULL) {
|
||||
int i = reader->callback(doc);
|
||||
if (i != 0) {
|
||||
return i;
|
||||
}
|
||||
reader = reader->next;
|
||||
while (reader != NULL) {
|
||||
int i = reader->callback(doc);
|
||||
if (i < 0) {
|
||||
return i;
|
||||
}
|
||||
result = 0;
|
||||
results += i;
|
||||
reader = reader->next;
|
||||
}
|
||||
xmlFreeDoc(doc);
|
||||
return result;
|
||||
return (results > 0) ? 0 : -1;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ extern "C" {
|
|||
bool xml_bvalue(xmlNodePtr node, const char *name, bool dflt);
|
||||
|
||||
void xml_done(void);
|
||||
int read_xml(const char *filename, const char *catalog);
|
||||
int read_xml(const char *filename);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
616
src/xmlreader.c
616
src/xmlreader.c
|
@ -282,6 +282,7 @@ static int parse_buildings(xmlDocPtr doc)
|
|||
{
|
||||
xmlXPathContextPtr xpath = xmlXPathNewContext(doc);
|
||||
xmlXPathObjectPtr buildings;
|
||||
int result = 0;
|
||||
|
||||
/* reading eressea/buildings/building */
|
||||
buildings =
|
||||
|
@ -289,6 +290,7 @@ static int parse_buildings(xmlDocPtr doc)
|
|||
if (buildings->nodesetval != NULL) {
|
||||
xmlNodeSetPtr nodes = buildings->nodesetval;
|
||||
int i;
|
||||
result += nodes->nodeNr;
|
||||
for (i = 0; i != nodes->nodeNr; ++i) {
|
||||
xmlNodePtr node = nodes->nodeTab[i];
|
||||
xmlChar *propValue;
|
||||
|
@ -387,19 +389,21 @@ static int parse_buildings(xmlDocPtr doc)
|
|||
xmlXPathFreeObject(buildings);
|
||||
|
||||
xmlXPathFreeContext(xpath);
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
static int parse_ships(xmlDocPtr doc)
|
||||
{
|
||||
xmlXPathContextPtr xpath = xmlXPathNewContext(doc);
|
||||
xmlXPathObjectPtr ships;
|
||||
int result = 0;
|
||||
|
||||
/* reading eressea/ships/ship */
|
||||
ships = xmlXPathEvalExpression(BAD_CAST "/eressea/ships/ship", xpath);
|
||||
if (ships->nodesetval != NULL) {
|
||||
xmlNodeSetPtr nodes = ships->nodesetval;
|
||||
int i;
|
||||
result += nodes->nodeNr;
|
||||
for (i = 0; i != nodes->nodeNr; ++i) {
|
||||
xmlNodePtr child, node = nodes->nodeTab[i];
|
||||
xmlChar *propValue;
|
||||
|
@ -481,7 +485,7 @@ static int parse_ships(xmlDocPtr doc)
|
|||
xmlXPathFreeObject(ships);
|
||||
|
||||
xmlXPathFreeContext(xpath);
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
static void xml_readpotion(xmlXPathContextPtr xpath, item_type * itype)
|
||||
|
@ -794,95 +798,98 @@ static int parse_resources(xmlDocPtr doc)
|
|||
{
|
||||
xmlXPathContextPtr xpath = xmlXPathNewContext(doc);
|
||||
xmlXPathObjectPtr resources;
|
||||
xmlNodeSetPtr nodes;
|
||||
int i;
|
||||
int results = 0;
|
||||
|
||||
/* reading eressea/resources/resource */
|
||||
resources =
|
||||
xmlXPathEvalExpression(BAD_CAST "/eressea/resources/resource", xpath);
|
||||
nodes = resources->nodesetval;
|
||||
for (i = 0; i != nodes->nodeNr; ++i) {
|
||||
xmlNodePtr node = nodes->nodeTab[i];
|
||||
xmlChar *propValue, *name, *appearance;
|
||||
resource_type *rtype;
|
||||
unsigned int flags = RTF_NONE;
|
||||
xmlXPathObjectPtr result;
|
||||
if (resources->nodesetval) {
|
||||
int i;
|
||||
xmlNodeSetPtr nodes = resources->nodesetval;
|
||||
results = nodes->nodeNr;
|
||||
for (i = 0; i != nodes->nodeNr; ++i) {
|
||||
xmlNodePtr node = nodes->nodeTab[i];
|
||||
xmlChar *propValue, *name, *appearance;
|
||||
resource_type *rtype;
|
||||
unsigned int flags = RTF_NONE;
|
||||
xmlXPathObjectPtr result;
|
||||
|
||||
if (xml_bvalue(node, "pooled", true))
|
||||
flags |= RTF_POOLED;
|
||||
if (xml_bvalue(node, "pooled", true))
|
||||
flags |= RTF_POOLED;
|
||||
|
||||
name = xmlGetProp(node, BAD_CAST "name");
|
||||
if (!name) {
|
||||
assert(name);
|
||||
log_error("invalid resource %d has no name", i);
|
||||
continue;
|
||||
}
|
||||
rtype = rt_get_or_create((const char *)name);
|
||||
rtype->flags |= flags;
|
||||
xmlFree(name);
|
||||
name = xmlGetProp(node, BAD_CAST "name");
|
||||
if (!name) {
|
||||
assert(name);
|
||||
log_error("invalid resource %d has no name", i);
|
||||
continue;
|
||||
}
|
||||
rtype = rt_get_or_create((const char *)name);
|
||||
rtype->flags |= flags;
|
||||
xmlFree(name);
|
||||
|
||||
/* reading eressea/resources/resource/function */
|
||||
xpath->node = node;
|
||||
result = xmlXPathEvalExpression(BAD_CAST "function", xpath);
|
||||
if (result->nodesetval != NULL) {
|
||||
int k;
|
||||
for (k = 0; k != result->nodesetval->nodeNr; ++k) {
|
||||
xmlNodePtr node = result->nodesetval->nodeTab[k];
|
||||
pf_generic fun;
|
||||
/* reading eressea/resources/resource/function */
|
||||
xpath->node = node;
|
||||
result = xmlXPathEvalExpression(BAD_CAST "function", xpath);
|
||||
if (result->nodesetval != NULL) {
|
||||
int k;
|
||||
for (k = 0; k != result->nodesetval->nodeNr; ++k) {
|
||||
xmlNodePtr node = result->nodesetval->nodeTab[k];
|
||||
pf_generic fun;
|
||||
|
||||
parse_function(node, &fun, &propValue);
|
||||
if (fun == NULL) {
|
||||
log_error("unknown function name '%s' for resource %s\n", (const char *)propValue, rtype->_name);
|
||||
parse_function(node, &fun, &propValue);
|
||||
if (fun == NULL) {
|
||||
log_error("unknown function name '%s' for resource %s\n", (const char *)propValue, rtype->_name);
|
||||
xmlFree(propValue);
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(propValue != NULL);
|
||||
if (strcmp((const char *)propValue, "change") == 0) {
|
||||
rtype->uchange = (rtype_uchange)fun;
|
||||
}
|
||||
else if (strcmp((const char *)propValue, "name") == 0) {
|
||||
rtype->name = (rtype_name)fun;
|
||||
}
|
||||
else {
|
||||
log_error("unknown function type '%s' for resource %s\n", (const char *)propValue, rtype->_name);
|
||||
}
|
||||
xmlFree(propValue);
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(propValue != NULL);
|
||||
if (strcmp((const char *)propValue, "change") == 0) {
|
||||
rtype->uchange = (rtype_uchange)fun;
|
||||
}
|
||||
else if (strcmp((const char *)propValue, "name") == 0) {
|
||||
rtype->name = (rtype_name)fun;
|
||||
}
|
||||
else {
|
||||
log_error("unknown function type '%s' for resource %s\n", (const char *)propValue, rtype->_name);
|
||||
}
|
||||
xmlFree(propValue);
|
||||
}
|
||||
}
|
||||
xmlXPathFreeObject(result);
|
||||
xmlXPathFreeObject(result);
|
||||
|
||||
if (xml_bvalue(node, "material", false)) {
|
||||
rmt_create(rtype);
|
||||
}
|
||||
|
||||
if (xml_bvalue(node, "limited", false)) {
|
||||
rtype->flags |= RTF_LIMITED;
|
||||
}
|
||||
xpath->node = node;
|
||||
result = xmlXPathEvalExpression(BAD_CAST "modifier", xpath);
|
||||
rtype->modifiers = xml_readmodifiers(result, node);
|
||||
xmlXPathFreeObject(result);
|
||||
/* reading eressea/resources/resource/resourcelimit/function */
|
||||
xpath->node = node;
|
||||
result = xmlXPathEvalExpression(BAD_CAST "resourcelimit/function", xpath);
|
||||
xmlXPathFreeObject(result);
|
||||
|
||||
/* reading eressea/resources/resource/item */
|
||||
xpath->node = node;
|
||||
result = xmlXPathEvalExpression(BAD_CAST "item", xpath);
|
||||
assert(result->nodesetval->nodeNr <= 1);
|
||||
if (result->nodesetval->nodeNr != 0) {
|
||||
rtype->flags |= RTF_ITEM;
|
||||
xpath->node = result->nodesetval->nodeTab[0];
|
||||
rtype->itype = xml_readitem(xpath, rtype);
|
||||
appearance = xmlGetProp(node, BAD_CAST "appearance");
|
||||
if (appearance) {
|
||||
it_set_appearance(rtype->itype, (const char *)appearance);
|
||||
xmlFree(appearance);
|
||||
if (xml_bvalue(node, "material", false)) {
|
||||
rmt_create(rtype);
|
||||
}
|
||||
|
||||
if (xml_bvalue(node, "limited", false)) {
|
||||
rtype->flags |= RTF_LIMITED;
|
||||
}
|
||||
xpath->node = node;
|
||||
result = xmlXPathEvalExpression(BAD_CAST "modifier", xpath);
|
||||
rtype->modifiers = xml_readmodifiers(result, node);
|
||||
xmlXPathFreeObject(result);
|
||||
/* reading eressea/resources/resource/resourcelimit/function */
|
||||
xpath->node = node;
|
||||
result = xmlXPathEvalExpression(BAD_CAST "resourcelimit/function", xpath);
|
||||
xmlXPathFreeObject(result);
|
||||
|
||||
/* reading eressea/resources/resource/item */
|
||||
xpath->node = node;
|
||||
result = xmlXPathEvalExpression(BAD_CAST "item", xpath);
|
||||
assert(result->nodesetval->nodeNr <= 1);
|
||||
if (result->nodesetval->nodeNr != 0) {
|
||||
rtype->flags |= RTF_ITEM;
|
||||
xpath->node = result->nodesetval->nodeTab[0];
|
||||
rtype->itype = xml_readitem(xpath, rtype);
|
||||
appearance = xmlGetProp(node, BAD_CAST "appearance");
|
||||
if (appearance) {
|
||||
it_set_appearance(rtype->itype, (const char *)appearance);
|
||||
xmlFree(appearance);
|
||||
}
|
||||
}
|
||||
xmlXPathFreeObject(result);
|
||||
}
|
||||
xmlXPathFreeObject(result);
|
||||
}
|
||||
xmlXPathFreeObject(resources);
|
||||
|
||||
|
@ -891,7 +898,7 @@ static int parse_resources(xmlDocPtr doc)
|
|||
/* make sure old items (used in requirements) are available */
|
||||
init_resources();
|
||||
|
||||
return 0;
|
||||
return results;
|
||||
}
|
||||
|
||||
static void add_items(equipment * eq, xmlNodeSetPtr nsetItems)
|
||||
|
@ -1055,6 +1062,7 @@ static int parse_equipment(xmlDocPtr doc)
|
|||
{
|
||||
xmlXPathContextPtr xpath = xmlXPathNewContext(doc);
|
||||
xmlXPathObjectPtr xpathRaces;
|
||||
int result = 0;
|
||||
|
||||
/* reading eressea/equipment/set */
|
||||
xpathRaces = xmlXPathEvalExpression(BAD_CAST "/eressea/equipment/set", xpath);
|
||||
|
@ -1062,6 +1070,7 @@ static int parse_equipment(xmlDocPtr doc)
|
|||
xmlNodeSetPtr nsetRaces = xpathRaces->nodesetval;
|
||||
int i;
|
||||
|
||||
result += nsetRaces->nodeNr;
|
||||
for (i = 0; i != nsetRaces->nodeNr; ++i) {
|
||||
xmlNodePtr node = nsetRaces->nodeTab[i];
|
||||
xmlChar *propName = xmlGetProp(node, BAD_CAST "name");
|
||||
|
@ -1108,21 +1117,23 @@ static int parse_equipment(xmlDocPtr doc)
|
|||
xmlXPathFreeObject(xpathRaces);
|
||||
xmlXPathFreeContext(xpath);
|
||||
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
static int parse_spellbooks(xmlDocPtr doc)
|
||||
{
|
||||
xmlXPathContextPtr xpath = xmlXPathNewContext(doc);
|
||||
xmlXPathObjectPtr spellbooks;
|
||||
int results = 0;
|
||||
|
||||
/* reading eressea/spells/spell */
|
||||
spellbooks = xmlXPathEvalExpression(BAD_CAST "/eressea/spells/spellbook", xpath);
|
||||
spellbooks = xmlXPathEvalExpression(BAD_CAST "/eressea/spellbook", xpath);
|
||||
|
||||
if (spellbooks->nodesetval != NULL) {
|
||||
xmlNodeSetPtr nodes = spellbooks->nodesetval;
|
||||
int i, k;
|
||||
|
||||
results += nodes->nodeNr;
|
||||
for (i = 0; i != nodes->nodeNr; ++i) {
|
||||
xmlXPathObjectPtr result;
|
||||
xmlNodePtr node = nodes->nodeTab[i];
|
||||
|
@ -1166,13 +1177,14 @@ static int parse_spellbooks(xmlDocPtr doc)
|
|||
}
|
||||
xmlXPathFreeObject(spellbooks);
|
||||
xmlXPathFreeContext(xpath);
|
||||
return 0;
|
||||
return results;
|
||||
}
|
||||
|
||||
static int parse_spells(xmlDocPtr doc)
|
||||
{
|
||||
xmlXPathContextPtr xpath = xmlXPathNewContext(doc);
|
||||
xmlXPathObjectPtr spells;
|
||||
int result = 0;
|
||||
|
||||
/* reading eressea/spells/spell */
|
||||
spells = xmlXPathEvalExpression(BAD_CAST "/eressea/spells/spell", xpath);
|
||||
|
@ -1180,6 +1192,7 @@ static int parse_spells(xmlDocPtr doc)
|
|||
xmlNodeSetPtr nodes = spells->nodesetval;
|
||||
int i;
|
||||
|
||||
result += nodes->nodeNr;
|
||||
for (i = 0; i != nodes->nodeNr; ++i) {
|
||||
xmlXPathObjectPtr result;
|
||||
xmlNodePtr node = nodes->nodeTab[i];
|
||||
|
@ -1299,7 +1312,7 @@ static int parse_spells(xmlDocPtr doc)
|
|||
|
||||
xmlXPathFreeContext(xpath);
|
||||
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
static void parse_ai(race * rc, xmlNodePtr node)
|
||||
|
@ -1332,246 +1345,249 @@ static int parse_races(xmlDocPtr doc)
|
|||
{
|
||||
xmlXPathContextPtr xpath = xmlXPathNewContext(doc);
|
||||
xmlXPathObjectPtr races;
|
||||
xmlNodeSetPtr nodes;
|
||||
int i;
|
||||
int results = 0;
|
||||
|
||||
/* reading eressea/races/race */
|
||||
races = xmlXPathEvalExpression(BAD_CAST "/eressea/races/race", xpath);
|
||||
nodes = races->nodesetval;
|
||||
for (i = 0; i != nodes->nodeNr; ++i) {
|
||||
xmlNodePtr node = nodes->nodeTab[i];
|
||||
xmlNodePtr child;
|
||||
xmlChar *propValue;
|
||||
race *rc, *frc = 0;
|
||||
xmlXPathObjectPtr result;
|
||||
int k, study_speed_base, attacks;
|
||||
struct att *attack;
|
||||
skill_t sk;
|
||||
|
||||
propValue = xmlGetProp(node, BAD_CAST "name");
|
||||
assert(propValue != NULL);
|
||||
rc = rc_get_or_create((const char *)propValue);
|
||||
xmlFree(propValue);
|
||||
|
||||
propValue = xmlGetProp(node, BAD_CAST "damage");
|
||||
assert(propValue != NULL);
|
||||
rc->def_damage = str_strdup((const char *)propValue);
|
||||
xmlFree(propValue);
|
||||
|
||||
rc->magres = frac_make(xml_ivalue(node, "magres", 100), 100);
|
||||
rc->healing = (int)(xml_fvalue(node, "healing", rc->healing) * 100); /* TODO: store as int in XML */
|
||||
rc->maxaura = (int)(xml_fvalue(node, "maxaura", rc->maxaura) * 100); /* TODO: store as int in XML */
|
||||
rc->regaura = (float)xml_fvalue(node, "regaura", rc->regaura);
|
||||
rc->recruitcost = xml_ivalue(node, "recruitcost", rc->recruitcost);
|
||||
rc->maintenance = xml_ivalue(node, "maintenance", rc->maintenance);
|
||||
rc->weight = xml_ivalue(node, "weight", rc->weight);
|
||||
rc->capacity = xml_ivalue(node, "capacity", rc->capacity);
|
||||
rc->income = xml_ivalue(node, "income", rc->income);
|
||||
rc->speed = (float)xml_fvalue(node, "speed", rc->speed);
|
||||
rc->hitpoints = xml_ivalue(node, "hp", rc->hitpoints);
|
||||
rc->armor = (char)xml_ivalue(node, "ac", rc->armor);
|
||||
study_speed_base = xml_ivalue(node, "studyspeed", 0);
|
||||
if (study_speed_base != 0) {
|
||||
for (sk = 0; sk < MAXSKILLS; ++sk) {
|
||||
set_study_speed(rc, sk, study_speed_base);
|
||||
}
|
||||
}
|
||||
|
||||
rc->at_default = (char)xml_ivalue(node, "unarmedattack", -2);
|
||||
rc->df_default = (char)xml_ivalue(node, "unarmeddefense", -2);
|
||||
rc->at_bonus = (char)xml_ivalue(node, "attackmodifier", rc->at_bonus);
|
||||
rc->df_bonus = (char)xml_ivalue(node, "defensemodifier", rc->df_bonus);
|
||||
|
||||
if (!xml_bvalue(node, "playerrace", false)) {
|
||||
assert(rc->recruitcost == 0);
|
||||
rc->flags |= RCF_NPC;
|
||||
}
|
||||
if (xml_bvalue(node, "scarepeasants", false))
|
||||
rc->flags |= RCF_SCAREPEASANTS;
|
||||
if (!xml_bvalue(node, "cansteal", true))
|
||||
rc->flags |= RCF_NOSTEAL;
|
||||
if (xml_bvalue(node, "cansail", true))
|
||||
rc->flags |= RCF_CANSAIL;
|
||||
if (xml_bvalue(node, "cannotmove", false))
|
||||
rc->flags |= RCF_CANNOTMOVE;
|
||||
if (xml_bvalue(node, "fly", false))
|
||||
rc->flags |= RCF_FLY;
|
||||
if (xml_bvalue(node, "invisible", false))
|
||||
rc->flags |= RCF_INVISIBLE;
|
||||
if (xml_bvalue(node, "coastal", false))
|
||||
rc->flags |= RCF_COASTAL;
|
||||
if (xml_bvalue(node, "unarmedguard", false))
|
||||
rc->flags |= RCF_UNARMEDGUARD;
|
||||
if (xml_bvalue(node, "swim", false))
|
||||
rc->flags |= RCF_SWIM;
|
||||
if (xml_bvalue(node, "walk", false))
|
||||
rc->flags |= RCF_WALK;
|
||||
if (!xml_bvalue(node, "canlearn", true))
|
||||
rc->flags |= RCF_NOLEARN;
|
||||
if (!xml_bvalue(node, "canteach", true))
|
||||
rc->flags |= RCF_NOTEACH;
|
||||
if (xml_bvalue(node, "horse", false))
|
||||
rc->flags |= RCF_HORSE;
|
||||
if (xml_bvalue(node, "desert", false))
|
||||
rc->flags |= RCF_DESERT;
|
||||
if (xml_bvalue(node, "absorbpeasants", false))
|
||||
rc->flags |= RCF_ABSORBPEASANTS;
|
||||
if (xml_bvalue(node, "noheal", false))
|
||||
rc->flags |= RCF_NOHEAL;
|
||||
if (xml_bvalue(node, "noweapons", false))
|
||||
rc->flags |= RCF_NOWEAPONS;
|
||||
if (xml_bvalue(node, "shapeshift", false))
|
||||
rc->flags |= RCF_SHAPESHIFT;
|
||||
if (xml_bvalue(node, "shapeshiftany", false))
|
||||
rc->flags |= RCF_SHAPESHIFTANY;
|
||||
if (xml_bvalue(node, "illusionary", false))
|
||||
rc->flags |= RCF_ILLUSIONARY;
|
||||
if (xml_bvalue(node, "undead", false))
|
||||
rc->flags |= RCF_UNDEAD;
|
||||
if (xml_bvalue(node, "dragon", false))
|
||||
rc->flags |= RCF_DRAGON;
|
||||
if (xml_bvalue(node, "shipspeed", false))
|
||||
rc->flags |= RCF_SHIPSPEED;
|
||||
|
||||
if (xml_bvalue(node, "giveperson", false))
|
||||
rc->ec_flags |= ECF_GIVEPERSON;
|
||||
if (xml_bvalue(node, "giveunit", false))
|
||||
rc->ec_flags |= ECF_GIVEUNIT;
|
||||
if (xml_bvalue(node, "getitem", false))
|
||||
rc->ec_flags |= ECF_GETITEM;
|
||||
if (xml_bvalue(node, "recruitethereal", false))
|
||||
rc->ec_flags |= ECF_REC_ETHEREAL;
|
||||
if (xml_bvalue(node, "recruitunlimited", false))
|
||||
rc->ec_flags |= ECF_REC_UNLIMITED;
|
||||
if (xml_bvalue(node, "stonegolem", false))
|
||||
rc->ec_flags |= ECF_STONEGOLEM;
|
||||
if (xml_bvalue(node, "irongolem", false))
|
||||
rc->ec_flags |= ECF_IRONGOLEM;
|
||||
|
||||
if (xml_bvalue(node, "equipment", false))
|
||||
rc->battle_flags |= BF_EQUIPMENT; /* TODO: invert this flag, so rc_get_or_create gets simpler */
|
||||
if (xml_bvalue(node, "noblock", false))
|
||||
rc->battle_flags |= BF_NOBLOCK;
|
||||
if (xml_bvalue(node, "invinciblenonmagic", false))
|
||||
rc->battle_flags |= BF_INV_NONMAGIC;
|
||||
if (xml_bvalue(node, "resistbash", false))
|
||||
rc->battle_flags |= BF_RES_BASH;
|
||||
if (xml_bvalue(node, "resistcut", false))
|
||||
rc->battle_flags |= BF_RES_CUT;
|
||||
if (xml_bvalue(node, "resistpierce", false))
|
||||
rc->battle_flags |= BF_RES_PIERCE;
|
||||
if (xml_bvalue(node, "noattack", false))
|
||||
rc->battle_flags |= BF_NO_ATTACK;
|
||||
|
||||
rc->recruit_multi = 1.0;
|
||||
for (child = node->children; child; child = child->next) {
|
||||
if (strcmp((const char *)child->name, "ai") == 0) {
|
||||
parse_ai(rc, child);
|
||||
}
|
||||
else if (strcmp((const char *)child->name, "param") == 0) {
|
||||
xmlChar *propName = xmlGetProp(child, BAD_CAST "name");
|
||||
xmlChar *propValue = xmlGetProp(child, BAD_CAST "value");
|
||||
rc_set_param(rc, (const char *)propName, (const char *)propValue);
|
||||
xmlFree(propName);
|
||||
xmlFree(propValue);
|
||||
}
|
||||
}
|
||||
|
||||
/* reading eressea/races/race/skill */
|
||||
xpath->node = node;
|
||||
result = xmlXPathEvalExpression(BAD_CAST "skill", xpath);
|
||||
memset(rc->bonus, 0, sizeof(rc->bonus));
|
||||
for (k = 0; k != result->nodesetval->nodeNr; ++k) {
|
||||
xmlNodePtr node = result->nodesetval->nodeTab[k];
|
||||
int mod = xml_ivalue(node, "modifier", 0);
|
||||
int speed = xml_ivalue(node, "speed", study_speed_base);
|
||||
if (races->nodesetval) {
|
||||
xmlNodeSetPtr nodes = races->nodesetval;
|
||||
int i;
|
||||
results += nodes->nodeNr;
|
||||
for (i = 0; i != nodes->nodeNr; ++i) {
|
||||
xmlNodePtr node = nodes->nodeTab[i];
|
||||
xmlNodePtr child;
|
||||
xmlChar *propValue;
|
||||
race *rc, *frc = 0;
|
||||
xmlXPathObjectPtr result;
|
||||
int k, study_speed_base, attacks;
|
||||
struct att *attack;
|
||||
skill_t sk;
|
||||
|
||||
propValue = xmlGetProp(node, BAD_CAST "name");
|
||||
assert(propValue != NULL);
|
||||
sk = findskill((const char *)propValue);
|
||||
if (sk != NOSKILL) {
|
||||
rc->bonus[sk] = (char)mod;
|
||||
if (speed) {
|
||||
set_study_speed(rc, sk, speed);
|
||||
rc = rc_get_or_create((const char *)propValue);
|
||||
xmlFree(propValue);
|
||||
|
||||
propValue = xmlGetProp(node, BAD_CAST "damage");
|
||||
assert(propValue != NULL);
|
||||
rc->def_damage = str_strdup((const char *)propValue);
|
||||
xmlFree(propValue);
|
||||
|
||||
rc->magres = frac_make(xml_ivalue(node, "magres", 100), 100);
|
||||
rc->healing = (int)(xml_fvalue(node, "healing", rc->healing) * 100); /* TODO: store as int in XML */
|
||||
rc->maxaura = (int)(xml_fvalue(node, "maxaura", rc->maxaura) * 100); /* TODO: store as int in XML */
|
||||
rc->regaura = (float)xml_fvalue(node, "regaura", rc->regaura);
|
||||
rc->recruitcost = xml_ivalue(node, "recruitcost", rc->recruitcost);
|
||||
rc->maintenance = xml_ivalue(node, "maintenance", rc->maintenance);
|
||||
rc->weight = xml_ivalue(node, "weight", rc->weight);
|
||||
rc->capacity = xml_ivalue(node, "capacity", rc->capacity);
|
||||
rc->income = xml_ivalue(node, "income", rc->income);
|
||||
rc->speed = (float)xml_fvalue(node, "speed", rc->speed);
|
||||
rc->hitpoints = xml_ivalue(node, "hp", rc->hitpoints);
|
||||
rc->armor = (char)xml_ivalue(node, "ac", rc->armor);
|
||||
study_speed_base = xml_ivalue(node, "studyspeed", 0);
|
||||
if (study_speed_base != 0) {
|
||||
for (sk = 0; sk < MAXSKILLS; ++sk) {
|
||||
set_study_speed(rc, sk, study_speed_base);
|
||||
}
|
||||
}
|
||||
else {
|
||||
log_error("unknown skill '%s' in race '%s'\n", (const char *)propValue, rc->_name);
|
||||
|
||||
rc->at_default = (char)xml_ivalue(node, "unarmedattack", -2);
|
||||
rc->df_default = (char)xml_ivalue(node, "unarmeddefense", -2);
|
||||
rc->at_bonus = (char)xml_ivalue(node, "attackmodifier", rc->at_bonus);
|
||||
rc->df_bonus = (char)xml_ivalue(node, "defensemodifier", rc->df_bonus);
|
||||
|
||||
if (!xml_bvalue(node, "playerrace", false)) {
|
||||
assert(rc->recruitcost == 0);
|
||||
rc->flags |= RCF_NPC;
|
||||
}
|
||||
xmlFree(propValue);
|
||||
}
|
||||
xmlXPathFreeObject(result);
|
||||
if (xml_bvalue(node, "scarepeasants", false))
|
||||
rc->flags |= RCF_SCAREPEASANTS;
|
||||
if (!xml_bvalue(node, "cansteal", true))
|
||||
rc->flags |= RCF_NOSTEAL;
|
||||
if (xml_bvalue(node, "cansail", true))
|
||||
rc->flags |= RCF_CANSAIL;
|
||||
if (xml_bvalue(node, "cannotmove", false))
|
||||
rc->flags |= RCF_CANNOTMOVE;
|
||||
if (xml_bvalue(node, "fly", false))
|
||||
rc->flags |= RCF_FLY;
|
||||
if (xml_bvalue(node, "invisible", false))
|
||||
rc->flags |= RCF_INVISIBLE;
|
||||
if (xml_bvalue(node, "coastal", false))
|
||||
rc->flags |= RCF_COASTAL;
|
||||
if (xml_bvalue(node, "unarmedguard", false))
|
||||
rc->flags |= RCF_UNARMEDGUARD;
|
||||
if (xml_bvalue(node, "swim", false))
|
||||
rc->flags |= RCF_SWIM;
|
||||
if (xml_bvalue(node, "walk", false))
|
||||
rc->flags |= RCF_WALK;
|
||||
if (!xml_bvalue(node, "canlearn", true))
|
||||
rc->flags |= RCF_NOLEARN;
|
||||
if (!xml_bvalue(node, "canteach", true))
|
||||
rc->flags |= RCF_NOTEACH;
|
||||
if (xml_bvalue(node, "horse", false))
|
||||
rc->flags |= RCF_HORSE;
|
||||
if (xml_bvalue(node, "desert", false))
|
||||
rc->flags |= RCF_DESERT;
|
||||
if (xml_bvalue(node, "absorbpeasants", false))
|
||||
rc->flags |= RCF_ABSORBPEASANTS;
|
||||
if (xml_bvalue(node, "noheal", false))
|
||||
rc->flags |= RCF_NOHEAL;
|
||||
if (xml_bvalue(node, "noweapons", false))
|
||||
rc->flags |= RCF_NOWEAPONS;
|
||||
if (xml_bvalue(node, "shapeshift", false))
|
||||
rc->flags |= RCF_SHAPESHIFT;
|
||||
if (xml_bvalue(node, "shapeshiftany", false))
|
||||
rc->flags |= RCF_SHAPESHIFTANY;
|
||||
if (xml_bvalue(node, "illusionary", false))
|
||||
rc->flags |= RCF_ILLUSIONARY;
|
||||
if (xml_bvalue(node, "undead", false))
|
||||
rc->flags |= RCF_UNDEAD;
|
||||
if (xml_bvalue(node, "dragon", false))
|
||||
rc->flags |= RCF_DRAGON;
|
||||
if (xml_bvalue(node, "shipspeed", false))
|
||||
rc->flags |= RCF_SHIPSPEED;
|
||||
|
||||
/* reading eressea/races/race/familiar */
|
||||
xpath->node = node;
|
||||
result = xmlXPathEvalExpression(BAD_CAST "familiar", xpath);
|
||||
if (result->nodesetval->nodeNr > MAXMAGIETYP) {
|
||||
log_error("race %s has %d potential familiars", rc->_name, result->nodesetval->nodeNr);
|
||||
}
|
||||
else {
|
||||
for (k = 0; k != MAXMAGIETYP; ++k) {
|
||||
if (k < result->nodesetval->nodeNr) {
|
||||
xmlNodePtr node = result->nodesetval->nodeTab[k];
|
||||
if (xml_bvalue(node, "giveperson", false))
|
||||
rc->ec_flags |= ECF_GIVEPERSON;
|
||||
if (xml_bvalue(node, "giveunit", false))
|
||||
rc->ec_flags |= ECF_GIVEUNIT;
|
||||
if (xml_bvalue(node, "getitem", false))
|
||||
rc->ec_flags |= ECF_GETITEM;
|
||||
if (xml_bvalue(node, "recruitethereal", false))
|
||||
rc->ec_flags |= ECF_REC_ETHEREAL;
|
||||
if (xml_bvalue(node, "recruitunlimited", false))
|
||||
rc->ec_flags |= ECF_REC_UNLIMITED;
|
||||
if (xml_bvalue(node, "stonegolem", false))
|
||||
rc->ec_flags |= ECF_STONEGOLEM;
|
||||
if (xml_bvalue(node, "irongolem", false))
|
||||
rc->ec_flags |= ECF_IRONGOLEM;
|
||||
|
||||
propValue = xmlGetProp(node, BAD_CAST "race");
|
||||
assert(propValue != NULL);
|
||||
frc = rc_get_or_create((const char *)propValue);
|
||||
frc->flags |= RCF_FAMILIAR;
|
||||
if (xml_bvalue(node, "default", false)) {
|
||||
rc->familiars[k] = rc->familiars[0];
|
||||
rc->familiars[0] = frc;
|
||||
if (xml_bvalue(node, "equipment", false))
|
||||
rc->battle_flags |= BF_EQUIPMENT; /* TODO: invert this flag, so rc_get_or_create gets simpler */
|
||||
if (xml_bvalue(node, "noblock", false))
|
||||
rc->battle_flags |= BF_NOBLOCK;
|
||||
if (xml_bvalue(node, "invinciblenonmagic", false))
|
||||
rc->battle_flags |= BF_INV_NONMAGIC;
|
||||
if (xml_bvalue(node, "resistbash", false))
|
||||
rc->battle_flags |= BF_RES_BASH;
|
||||
if (xml_bvalue(node, "resistcut", false))
|
||||
rc->battle_flags |= BF_RES_CUT;
|
||||
if (xml_bvalue(node, "resistpierce", false))
|
||||
rc->battle_flags |= BF_RES_PIERCE;
|
||||
if (xml_bvalue(node, "noattack", false))
|
||||
rc->battle_flags |= BF_NO_ATTACK;
|
||||
|
||||
rc->recruit_multi = 1.0;
|
||||
for (child = node->children; child; child = child->next) {
|
||||
if (strcmp((const char *)child->name, "ai") == 0) {
|
||||
parse_ai(rc, child);
|
||||
}
|
||||
else if (strcmp((const char *)child->name, "param") == 0) {
|
||||
xmlChar *propName = xmlGetProp(child, BAD_CAST "name");
|
||||
xmlChar *propValue = xmlGetProp(child, BAD_CAST "value");
|
||||
rc_set_param(rc, (const char *)propName, (const char *)propValue);
|
||||
xmlFree(propName);
|
||||
xmlFree(propValue);
|
||||
}
|
||||
}
|
||||
|
||||
/* reading eressea/races/race/skill */
|
||||
xpath->node = node;
|
||||
result = xmlXPathEvalExpression(BAD_CAST "skill", xpath);
|
||||
memset(rc->bonus, 0, sizeof(rc->bonus));
|
||||
for (k = 0; k != result->nodesetval->nodeNr; ++k) {
|
||||
xmlNodePtr node = result->nodesetval->nodeTab[k];
|
||||
int mod = xml_ivalue(node, "modifier", 0);
|
||||
int speed = xml_ivalue(node, "speed", study_speed_base);
|
||||
|
||||
propValue = xmlGetProp(node, BAD_CAST "name");
|
||||
assert(propValue != NULL);
|
||||
sk = findskill((const char *)propValue);
|
||||
if (sk != NOSKILL) {
|
||||
rc->bonus[sk] = (char)mod;
|
||||
if (speed) {
|
||||
set_study_speed(rc, sk, speed);
|
||||
}
|
||||
}
|
||||
else {
|
||||
log_error("unknown skill '%s' in race '%s'\n", (const char *)propValue, rc->_name);
|
||||
}
|
||||
xmlFree(propValue);
|
||||
}
|
||||
xmlXPathFreeObject(result);
|
||||
|
||||
/* reading eressea/races/race/familiar */
|
||||
xpath->node = node;
|
||||
result = xmlXPathEvalExpression(BAD_CAST "familiar", xpath);
|
||||
if (result->nodesetval->nodeNr > MAXMAGIETYP) {
|
||||
log_error("race %s has %d potential familiars", rc->_name, result->nodesetval->nodeNr);
|
||||
}
|
||||
else {
|
||||
for (k = 0; k != MAXMAGIETYP; ++k) {
|
||||
if (k < result->nodesetval->nodeNr) {
|
||||
xmlNodePtr node = result->nodesetval->nodeTab[k];
|
||||
|
||||
propValue = xmlGetProp(node, BAD_CAST "race");
|
||||
assert(propValue != NULL);
|
||||
frc = rc_get_or_create((const char *)propValue);
|
||||
frc->flags |= RCF_FAMILIAR;
|
||||
if (xml_bvalue(node, "default", false)) {
|
||||
rc->familiars[k] = rc->familiars[0];
|
||||
rc->familiars[0] = frc;
|
||||
}
|
||||
else {
|
||||
rc->familiars[k] = frc;
|
||||
}
|
||||
xmlFree(propValue);
|
||||
}
|
||||
else {
|
||||
rc->familiars[k] = frc;
|
||||
}
|
||||
}
|
||||
}
|
||||
xmlXPathFreeObject(result);
|
||||
|
||||
/* reading eressea/races/race/attack */
|
||||
xpath->node = node;
|
||||
result = xmlXPathEvalExpression(BAD_CAST "attack", xpath);
|
||||
attack = rc->attack;
|
||||
attacks = 0;
|
||||
for (k = 0; k != result->nodesetval->nodeNr; ++k) {
|
||||
xmlNodePtr node = result->nodesetval->nodeTab[k];
|
||||
while (attack->type != AT_NONE) {
|
||||
++attack;
|
||||
if (attacks++ >= RACE_ATTACKS) {
|
||||
log_error("too many attacks for race '%s'\n", rc->_name);
|
||||
assert(!"aborting");
|
||||
}
|
||||
}
|
||||
|
||||
propValue = xmlGetProp(node, BAD_CAST "damage");
|
||||
if (propValue != NULL) {
|
||||
attack->data.dice = str_strdup((const char *)propValue);
|
||||
xmlFree(propValue);
|
||||
}
|
||||
else {
|
||||
rc->familiars[k] = frc;
|
||||
}
|
||||
}
|
||||
}
|
||||
xmlXPathFreeObject(result);
|
||||
|
||||
/* reading eressea/races/race/attack */
|
||||
xpath->node = node;
|
||||
result = xmlXPathEvalExpression(BAD_CAST "attack", xpath);
|
||||
attack = rc->attack;
|
||||
attacks = 0;
|
||||
for (k = 0; k != result->nodesetval->nodeNr; ++k) {
|
||||
xmlNodePtr node = result->nodesetval->nodeTab[k];
|
||||
while (attack->type != AT_NONE) {
|
||||
++attack;
|
||||
if (attacks++ >= RACE_ATTACKS) {
|
||||
log_error("too many attacks for race '%s'\n", rc->_name);
|
||||
assert(!"aborting");
|
||||
}
|
||||
}
|
||||
|
||||
propValue = xmlGetProp(node, BAD_CAST "damage");
|
||||
if (propValue != NULL) {
|
||||
attack->data.dice = str_strdup((const char *)propValue);
|
||||
xmlFree(propValue);
|
||||
}
|
||||
else {
|
||||
attack->data.sp = xml_spellref(node, "spell");
|
||||
if (attack->data.sp) {
|
||||
attack->level = xml_ivalue(node, "level", 0);
|
||||
if (attack->level <= 0) {
|
||||
log_error("magical attack '%s' for race '%s' needs a level: %d\n", attack->data.sp->name, rc->_name, attack->level);
|
||||
attack->data.sp = xml_spellref(node, "spell");
|
||||
if (attack->data.sp) {
|
||||
attack->level = xml_ivalue(node, "level", 0);
|
||||
if (attack->level <= 0) {
|
||||
log_error("magical attack '%s' for race '%s' needs a level: %d\n", attack->data.sp->name, rc->_name, attack->level);
|
||||
}
|
||||
}
|
||||
}
|
||||
attack->type = xml_ivalue(node, "type", 0);
|
||||
attack->flags = xml_ivalue(node, "flags", 0);
|
||||
}
|
||||
attack->type = xml_ivalue(node, "type", 0);
|
||||
attack->flags = xml_ivalue(node, "flags", 0);
|
||||
xmlXPathFreeObject(result);
|
||||
}
|
||||
xmlXPathFreeObject(result);
|
||||
}
|
||||
xmlXPathFreeObject(races);
|
||||
|
||||
xmlXPathFreeContext(xpath);
|
||||
|
||||
return 0;
|
||||
return results;
|
||||
}
|
||||
|
||||
static int parse_messages(xmlDocPtr doc)
|
||||
|
@ -1579,7 +1595,7 @@ static int parse_messages(xmlDocPtr doc)
|
|||
xmlXPathContextPtr xpath;
|
||||
xmlXPathObjectPtr messages;
|
||||
xmlNodeSetPtr nodes;
|
||||
int i;
|
||||
int i, results;
|
||||
|
||||
xpath = xmlXPathNewContext(doc);
|
||||
|
||||
|
@ -1587,6 +1603,7 @@ static int parse_messages(xmlDocPtr doc)
|
|||
messages =
|
||||
xmlXPathEvalExpression(BAD_CAST "/eressea/messages/message", xpath);
|
||||
nodes = messages->nodesetval;
|
||||
results = nodes->nodeNr;
|
||||
for (i = 0; i != nodes->nodeNr; ++i) {
|
||||
xmlNodePtr node = nodes->nodeTab[i];
|
||||
const char *default_section = "events";
|
||||
|
@ -1671,7 +1688,7 @@ static int parse_messages(xmlDocPtr doc)
|
|||
xmlXPathFreeObject(messages);
|
||||
|
||||
xmlXPathFreeContext(xpath);
|
||||
return 0;
|
||||
return results;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1726,21 +1743,24 @@ static int parse_strings(xmlDocPtr doc)
|
|||
{
|
||||
xmlXPathContextPtr xpath = xmlXPathNewContext(doc);
|
||||
xmlXPathObjectPtr strings;
|
||||
int results = 0;
|
||||
|
||||
/* reading eressea/strings/string */
|
||||
strings = xmlXPathEvalExpression(BAD_CAST "/eressea/strings/string", xpath);
|
||||
xml_readstrings(xpath, strings->nodesetval->nodeTab,
|
||||
strings->nodesetval->nodeNr, false);
|
||||
results += strings->nodesetval->nodeNr;
|
||||
xmlXPathFreeObject(strings);
|
||||
|
||||
strings =
|
||||
xmlXPathEvalExpression(BAD_CAST "/eressea/strings/namespace/string", xpath);
|
||||
xml_readstrings(xpath, strings->nodesetval->nodeTab,
|
||||
strings->nodesetval->nodeNr, true);
|
||||
results += strings->nodesetval->nodeNr;
|
||||
xmlXPathFreeObject(strings);
|
||||
|
||||
xmlXPathFreeContext(xpath);
|
||||
return 0;
|
||||
return results;
|
||||
}
|
||||
|
||||
void register_xmlreader(void)
|
||||
|
|
Loading…
Reference in New Issue