server/src/archetype.c

162 lines
4.4 KiB
C

#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>
static struct archetype *archetypes;
struct attrib_type at_recruit = {
"recruit", NULL, NULL, NULL, NULL, NULL, ATF_UNIQUE
};
const struct archetype *find_archetype(const char *s, const struct locale *lang)
{
void **tokens = get_translations(lang, UT_ARCHETYPES);
variant token;
if (tokens && findtoken(*tokens, s, &token) == E_TOK_SUCCESS) {
return (const struct archetype *)token.v;
}
return NULL;
}
void register_archetype(archetype * arch)
{
arch->next = archetypes;
archetypes = arch;
}
void init_archetypes(void)
{
const struct locale *lang = locales;
for (; lang; lang = nextlocale(lang)) {
variant var;
archetype *arch = archetypes;
void *tokens = get_translations(lang, UT_ARCHETYPES);
for (; arch; arch = arch->next) {
const char *s1, *s2;
var.v = arch;
s1 = LOC(lang, arch->name[0]);
addtoken(tokens, s1, var);
s2 = LOC(lang, arch->name[1]);
if (strcmp(s2, s1) != 0) {
addtoken(tokens, s2, var);
}
}
}
}
static int parse_archetypes(xmlDocPtr doc)
{
char zName[64];
xmlXPathContextPtr xpath = xmlXPathNewContext(doc);
xmlXPathObjectPtr result =
xmlXPathEvalExpression(BAD_CAST "/eressea/archetypes/archetype", xpath);
xmlNodeSetPtr nodes = result->nodesetval;
xmlChar *propValue;
if (nodes) {
int i;
for (i = 0; i != nodes->nodeNr; ++i) {
xmlNodePtr node = nodes->nodeTab[i];
xmlNodePtr child;
archetype *arch = calloc(1, sizeof(archetype));
xmlXPathObjectPtr sub;
propValue = xmlGetProp(node, BAD_CAST "name");
assert(propValue != NULL);
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");
if (propValue != NULL) {
arch->equip = get_equipment((const char *)propValue);
xmlFree(propValue);
} else {
arch->equip = get_equipment(arch->name[0]);
}
propValue = xmlGetProp(node, BAD_CAST "building");
if (propValue != NULL) {
arch->btype = bt_find((const char *)propValue);
xmlFree(propValue);
}
arch->size = xml_ivalue(node, "cost", 0);
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");
if (strcmp((const char *)propName, "create")) {
pf_generic foo = get_function((const char *)propValue);
arch->exec = (archetype_function) foo;
}
xmlFree(propValue);
xmlFree(propName);
}
}
xpath->node = node;
sub = xmlXPathEvalExpression(BAD_CAST "allow|deny", xpath);
if (sub->nodesetval && sub->nodesetval->nodeNr) {
int k;
arch->rules = calloc(sub->nodesetval->nodeNr + 1, sizeof(rule));
for (k = 0; k != sub->nodesetval->nodeNr; ++k) {
xmlNodePtr rule = sub->nodesetval->nodeTab[k];
arch->rules[k].allow = (rule->name[0] == 'a');
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;
}
void register_archetypes(void)
{
xml_register_callback(parse_archetypes);
}