server/src/gamecode/archetype.c

162 lines
4.4 KiB
C
Raw Normal View History

2010-08-08 10:06:34 +02:00
#include <platform.h>
#include <kernel/config.h>
#include "archetype.h"
/* kernel includes */
#include <kernel/equipment.h>
#include <kernel/building.h>
#include <kernel/xmlkernel.h>
#include <kernel/xmlreader.h>
/* util includes */
#include <util/attrib.h>
#include <util/umlaut.h>
#include <util/language.h>
#include <util/xml.h>
#include <util/functions.h>
/* libxml includes */
#include <libxml/tree.h>
#include <libxml/xpath.h>
#include <libxml/encoding.h>
/* libc includes */
#include <string.h>
#include <assert.h>
2011-03-07 08:02:35 +01:00
static struct archetype *archetypes;
2010-08-08 10:06:34 +02:00
struct attrib_type at_recruit = {
"recruit", NULL, NULL, NULL, NULL, NULL, ATF_UNIQUE
};
2011-03-07 08:02:35 +01:00
const struct archetype *find_archetype(const char *s, const struct locale *lang)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
struct tnode *tokens = get_translations(lang, UT_ARCHETYPES);
2010-08-08 10:06:34 +02:00
variant token;
2011-03-07 08:02:35 +01:00
if (findtoken(tokens, s, &token) == E_TOK_SUCCESS) {
2010-08-08 10:06:34 +02:00
return (const struct archetype *)token.v;
}
return NULL;
}
2011-03-07 08:02:35 +01:00
void register_archetype(archetype * arch)
2010-08-08 10:06:34 +02:00
{
arch->next = archetypes;
archetypes = arch;
}
2011-03-07 08:02:35 +01:00
void init_archetypes(void)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
const struct locale *lang = locales;
for (; lang; lang = nextlocale(lang)) {
2010-08-08 10:06:34 +02:00
variant var;
2011-03-07 08:02:35 +01:00
archetype *arch = archetypes;
struct tnode *tokens = get_translations(lang, UT_ARCHETYPES);
for (; arch; arch = arch->next) {
2010-08-08 10:06:34 +02:00
const char *s1, *s2;
var.v = arch;
s1 = LOC(lang, arch->name[0]);
addtoken(tokens, s1, var);
s2 = LOC(lang, arch->name[1]);
2011-03-07 08:02:35 +01:00
if (strcmp(s2, s1) != 0) {
2010-08-08 10:06:34 +02:00
addtoken(tokens, s2, var);
}
}
}
}
2011-03-07 08:02:35 +01:00
static int parse_archetypes(xmlDocPtr doc)
2010-08-08 10:06:34 +02:00
{
char zName[64];
xmlXPathContextPtr xpath = xmlXPathNewContext(doc);
2011-03-07 08:02:35 +01:00
xmlXPathObjectPtr result =
xmlXPathEvalExpression(BAD_CAST "/eressea/archetypes/archetype", xpath);
2010-08-08 10:06:34 +02:00
xmlNodeSetPtr nodes = result->nodesetval;
2011-03-07 08:02:35 +01:00
xmlChar *propValue;
2010-08-08 10:06:34 +02:00
if (nodes) {
int i;
2011-03-07 08:02:35 +01:00
for (i = 0; i != nodes->nodeNr; ++i) {
2010-08-08 10:06:34 +02:00
xmlNodePtr node = nodes->nodeTab[i];
xmlNodePtr child;
2011-03-07 08:02:35 +01:00
archetype *arch = calloc(1, sizeof(archetype));
2010-08-08 10:06:34 +02:00
xmlXPathObjectPtr sub;
propValue = xmlGetProp(node, BAD_CAST "name");
2011-03-07 08:02:35 +01:00
assert(propValue != NULL);
2010-08-08 10:06:34 +02:00
arch->name[0] = strdup((const char *)propValue);
sprintf(zName, "%s_p", arch->name[0]);
arch->name[1] = strdup(zName);
xmlFree(propValue);
propValue = xmlGetProp(node, BAD_CAST "equip");
2011-03-07 08:02:35 +01:00
if (propValue != NULL) {
arch->equip = get_equipment((const char *)propValue);
2010-08-08 10:06:34 +02:00
xmlFree(propValue);
} else {
arch->equip = get_equipment(arch->name[0]);
}
propValue = xmlGetProp(node, BAD_CAST "building");
2011-03-07 08:02:35 +01:00
if (propValue != NULL) {
arch->btype = bt_find((const char *)propValue);
2010-08-08 10:06:34 +02:00
xmlFree(propValue);
}
arch->size = xml_ivalue(node, "cost", 0);
2011-03-07 08:02:35 +01:00
for (child = node->children; child; child = child->next) {
if (strcmp((const char *)child->name, "function") == 0) {
xmlChar *propName = xmlGetProp(child, BAD_CAST "name");
xmlChar *propValue = xmlGetProp(child, BAD_CAST "value");
2010-08-08 10:06:34 +02:00
if (strcmp((const char *)propName, "create")) {
pf_generic foo = get_function((const char *)propValue);
2011-03-07 08:02:35 +01:00
arch->exec = (archetype_function) foo;
2010-08-08 10:06:34 +02:00
}
xmlFree(propValue);
xmlFree(propName);
}
}
xpath->node = node;
sub = xmlXPathEvalExpression(BAD_CAST "allow|deny", xpath);
if (sub->nodesetval && sub->nodesetval->nodeNr) {
int k;
2011-03-07 08:02:35 +01:00
arch->rules = calloc(sub->nodesetval->nodeNr + 1, sizeof(rule));
for (k = 0; k != sub->nodesetval->nodeNr; ++k) {
2010-08-08 10:06:34 +02:00
xmlNodePtr rule = sub->nodesetval->nodeTab[k];
2011-03-07 08:02:35 +01:00
arch->rules[k].allow = (rule->name[0] == 'a');
2010-08-08 10:06:34 +02:00
propValue = xmlGetProp(rule, BAD_CAST "property");
arch->rules[k].property = strdup((const char *)propValue);
xmlFree(propValue);
propValue = xmlGetProp(rule, BAD_CAST "value");
arch->rules[k].value = strdup((const char *)propValue);
xmlFree(propValue);
}
}
xmlXPathFreeObject(sub);
xpath->node = node;
sub = xmlXPathEvalExpression(BAD_CAST "construction", xpath);
if (sub->nodesetval) {
xml_readconstruction(xpath, sub->nodesetval, &arch->ctype);
}
xmlXPathFreeObject(sub);
register_archetype(arch);
}
}
xmlXPathFreeObject(result);
xmlXPathFreeContext(xpath);
return 0;
}
2011-03-07 08:02:35 +01:00
void register_archetypes(void)
2010-08-08 10:06:34 +02:00
{
xml_register_callback(parse_archetypes);
}