diff --git a/src/common/gamecode/archetype.c b/src/common/gamecode/archetype.c index be70742d1..197d933d5 100644 --- a/src/common/gamecode/archetype.c +++ b/src/common/gamecode/archetype.c @@ -62,14 +62,21 @@ get_archetype(const char * name) void init_archetypes(void) { + char zName[64]; const struct locale * lang = locales; for (;lang;lang=nextlocale(lang)) { variant var; archetype * arch = archetypes; struct tnode * tokens = get_translations(lang, UT_ARCHETYPES); for (;arch;arch=arch->next) { + const char * s; var.v = arch; - addtoken(tokens, LOC(lang, arch->name), var); + + s = locale_getstring(lang, arch->name); + if (s!=NULL) addtoken(tokens, s, var); + sprintf(zName, "%s_p", arch->name); + s = locale_getstring(lang, zName); + if (s!=NULL) addtoken(tokens, s, var); } } } @@ -82,38 +89,42 @@ parse_archetypes(xmlDocPtr doc) xmlNodeSetPtr nodes = result->nodesetval; xmlChar * property; - if (nodes && nodes->nodeNr>0) { - xmlNodePtr node = nodes->nodeTab[0]; - archetype * arch = calloc(1, sizeof(archetype)); - xmlXPathObjectPtr sub; + if (nodes) { + int i; + for (i=0;i!=nodes->nodeNr;++i) { + xmlNodePtr node = nodes->nodeTab[i]; + archetype * arch = calloc(1, sizeof(archetype)); + xmlXPathObjectPtr sub; - property = xmlGetProp(node, BAD_CAST "name"); - assert(property!=NULL); - arch->name = strdup((const char *)property); - xmlFree(property); - - property = xmlGetProp(node, BAD_CAST "equip"); - if (property!=NULL) { - arch->equip = get_equipment((const char*)property); + property = xmlGetProp(node, BAD_CAST "name"); + assert(property!=NULL); + arch->name = strdup((const char *)property); xmlFree(property); - } else { - arch->equip = get_equipment(arch->name); - } - property = xmlGetProp(node, BAD_CAST "building"); - if (property!=NULL) { - arch->btype = bt_find((const char*)property); - xmlFree(property); - } + property = xmlGetProp(node, BAD_CAST "equip"); + if (property!=NULL) { + arch->equip = get_equipment((const char*)property); + xmlFree(property); + } else { + arch->equip = get_equipment(arch->name); + } - arch->size = xml_ivalue(node, "cost", 0); + property = xmlGetProp(node, BAD_CAST "building"); + if (property!=NULL) { + arch->btype = bt_find((const char*)property); + xmlFree(property); + } - xpath->node = node; - sub = xmlXPathEvalExpression(BAD_CAST "construction", xpath); - if (sub->nodesetval) { - xml_readconstruction(xpath, sub->nodesetval, &arch->ctype); + arch->size = xml_ivalue(node, "cost", 0); + + 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(sub); } xmlXPathFreeObject(result); diff --git a/src/common/gamecode/economy.c b/src/common/gamecode/economy.c index 28989c151..7a11bd998 100644 --- a/src/common/gamecode/economy.c +++ b/src/common/gamecode/economy.c @@ -1058,14 +1058,13 @@ maintain_buildings(region * r, boolean crash) static int recruit_archetype(unit * u, order * ord) { - int n, id; + int n; const char * s; init_tokens(ord); skip_token(); n = geti(); s = getstrtoken(); - id = getid(); if (n>0 && s && s[0]) { const archetype * arch = find_archetype(s, u->faction->locale); attrib * a = NULL; @@ -1104,12 +1103,14 @@ recruit_archetype(unit * u, order * ord) n = build(u, arch->ctype, 0, n); if (n>0) { - scale_number(u, n); + set_number(u, n); equip_unit(u, arch->equip); + u->hp = n * unit_max_hp(u); if (arch->size) { if (a==NULL) a = a_add(&u->building->attribs, a_new(&at_recruit)); a->data.i += n*arch->size; } + ADDMSG(&u->faction->msgs, msg_message("recruit_archetype", "unit archetype", u, arch->name)); return n; } else switch(n) { case ENOMATERIALS: diff --git a/src/common/gamecode/report.c b/src/common/gamecode/report.c index 64cf7269e..fbf7ca10d 100644 --- a/src/common/gamecode/report.c +++ b/src/common/gamecode/report.c @@ -1791,6 +1791,7 @@ report_plaintext(const char * filename, report_context * ctx) dh = 0; if (f->age <= 2) { + const char * s; if (f->age <= 1) { ADDMSG(&f->msgs, msg_message("changepasswd", "value", f->passw)); @@ -1798,14 +1799,23 @@ report_plaintext(const char * filename, report_context * ctx) RENDER(f, buf, sizeof(buf), ("newbie_password", "password", f->passw)); rnl(F); centre(F, buf, true); - rnl(F); - centre(F, LOC(f->locale, "newbie_info_1"), true); - rnl(F); - centre(F, LOC(f->locale, "newbie_info_2"), true); + s = locale_getstring(f->locale, "newbie_info_1"); + if (s) { + rnl(F); + centre(F, s, true); + } + s = locale_getstring(f->locale, "newbie_info_2"); + if (s) { + rnl(F); + centre(F, s, true); + } if ((f->options & want(O_COMPUTER)) == 0) { f->options |= want(O_COMPUTER); - rnl(F); - centre(F, LOC(f->locale, "newbie_info_3"), true); + s = locale_getstring(f->locale, "newbie_info_3"); + if (s) { + rnl(F); + centre(F, s, true); + } } } rnl(F); diff --git a/src/common/kernel/equipment.c b/src/common/kernel/equipment.c index c9bfda6f7..91ba98843 100644 --- a/src/common/kernel/equipment.c +++ b/src/common/kernel/equipment.c @@ -50,6 +50,7 @@ create_equipment(const char * eqname) eq->items = NULL; eq->spells = NULL; eq->subsets = NULL; + eq->callback = NULL; memset(eq->skills, 0, sizeof(eq->skills)); *eqp = eq; break; @@ -113,6 +114,12 @@ equipment_setitem(equipment * eq, const item_type * itype, const char * value) } } +void +equipment_setcallback(struct equipment * eq, void (*callback)(const struct equipment *, struct unit *)) +{ + eq->callback = callback; +} + void equip_unit(struct unit * u, const struct equipment * eq) { @@ -163,6 +170,8 @@ equip_unit(struct unit * u, const struct equipment * eq) } } } + + if (eq->callback) eq->callback(eq, u); } } diff --git a/src/common/kernel/equipment.h b/src/common/kernel/equipment.h index 1c62651ff..b17cc91b9 100644 --- a/src/common/kernel/equipment.h +++ b/src/common/kernel/equipment.h @@ -48,6 +48,7 @@ extern "C" { struct spell_list * spells; struct subset * subsets; struct equipment * next; + void (*callback)(const struct equipment *, struct unit *); } equipment; @@ -57,6 +58,7 @@ extern "C" { extern void equipment_setitem(struct equipment * eq, const struct item_type * itype, const char * value); extern void equipment_setskill(struct equipment * eq, skill_t sk, const char * value); extern void equipment_addspell(struct equipment * eq, struct spell * sp); + extern void equipment_setcallback(struct equipment * eq, void (*callback)(const struct equipment *, struct unit *)); extern void equip_unit(struct unit * u, const struct equipment * eq); extern void equip_items(struct item ** items, const struct equipment * eq); diff --git a/src/common/kernel/faction.c b/src/common/kernel/faction.c index 8ca8c3d3b..2a7fe5741 100644 --- a/src/common/kernel/faction.c +++ b/src/common/kernel/faction.c @@ -149,7 +149,7 @@ addplayer(region *r, faction * f) u = createunit(r, f, 1, f->race); equip_unit(u, get_equipment("new_faction")); equip_unit(u, get_equipment(u->race->_name[0])); - give_starting_equipment(u); + u->hp = unit_max_hp(u) * u->number; fset(u, UFL_ISNEW); if (f->race == new_race[RC_DAEMON]) { race_t urc; diff --git a/src/common/kernel/race.c b/src/common/kernel/race.c index 653defc76..b881a1146 100644 --- a/src/common/kernel/race.c +++ b/src/common/kernel/race.c @@ -225,12 +225,12 @@ unit_max_hp(const unit * u) return h; } -void -give_starting_equipment(struct unit *u) +static void +equip_newunits(const struct equipment * eq, struct unit *u) { struct region *r = u->region; - switch(old_race(u->race)) { + switch (old_race(u->race)) { case RC_ELF: set_show_item(u->faction, I_FEENSTIEFEL); break; @@ -239,7 +239,7 @@ give_starting_equipment(struct unit *u) set_number(u, 10); break; case RC_HUMAN: - { + if (u->building==NULL) { const building_type * btype = bt_find("castle"); if (btype!=NULL) { building *b = new_building(btype, r, u->faction->locale); @@ -264,7 +264,6 @@ give_starting_equipment(struct unit *u) rsethorses(r, 250+rng_int()%51+rng_int()%51); break; } - u->hp = unit_max_hp(u) * u->number; } boolean @@ -449,6 +448,7 @@ register_races(void) * to generate battle spoils * race->itemdrop() */ register_function((pf_generic)default_spoil, "defaultdrops"); + register_function((pf_generic)equip_newunits, "equip_newunits"); sprintf(zBuffer, "%s/races.xml", resourcepath()); } diff --git a/src/common/kernel/race.h b/src/common/kernel/race.h index 8ac8ba346..427dc57e9 100644 --- a/src/common/kernel/race.h +++ b/src/common/kernel/race.h @@ -183,7 +183,7 @@ extern int read_race_reference(const struct race ** rp, FILE * F); extern const char * raceprefix(const struct unit *u); -extern void give_starting_equipment(struct unit *u); +extern void give_starting_equipment(const struct equipment * eq, struct unit *u); #ifdef __cplusplus } diff --git a/src/common/kernel/xmlreader.c b/src/common/kernel/xmlreader.c index 623e3d800..e123af032 100644 --- a/src/common/kernel/xmlreader.c +++ b/src/common/kernel/xmlreader.c @@ -1088,6 +1088,28 @@ add_items(equipment * eq, xmlNodeSetPtr nsetItems) } } +static void +add_callbacks(equipment * eq, xmlNodeSetPtr nsetItems) +{ + if (nsetItems!=NULL && nsetItems->nodeNr>0) { + int i; + for (i=0;i!=nsetItems->nodeNr;++i) { + xmlNodePtr node = nsetItems->nodeTab[i]; + xmlChar * property; + pf_generic fun; + + property = xmlGetProp(node, BAD_CAST "name"); + if (property!=NULL) { + fun = get_function((const char*)property); + if (fun) { + equipment_setcallback(eq, (void (*)(const struct equipment *, struct unit *))fun); + } + xmlFree(property); + } + } + } +} + static void add_spells(equipment * eq, xmlNodeSetPtr nsetItems) { @@ -1224,6 +1246,10 @@ parse_equipment(xmlDocPtr doc) xpath->node = node; + xpathResult = xmlXPathEvalExpression(BAD_CAST "callback", xpath); + add_callbacks(eq, xpathResult->nodesetval); + xmlXPathFreeObject(xpathResult); + xpathResult = xmlXPathEvalExpression(BAD_CAST "item", xpath); add_items(eq, xpathResult->nodesetval); xmlXPathFreeObject(xpathResult); diff --git a/src/eressea/lua/script.cpp b/src/eressea/lua/script.cpp index cd487b6f1..1764f629b 100644 --- a/src/eressea/lua/script.cpp +++ b/src/eressea/lua/script.cpp @@ -303,6 +303,28 @@ race_setscript(const char * rcname, const luabind::object& f) } } +static void +lua_equipmentcallback(const struct equipment * eq, unit * u) +{ + char fname[64]; + snprintf(fname, sizeof(fname), "equip_%s", eq->name); + + lua_State * L = (lua_State *)global.vm_state; + if (is_function(L, fname)) { + try { + call_function(L, fname, u); + } + catch (error& e) { + lua_State* L = e.state(); + const char* error = lua_tostring(L, -1); + log_error(("An exception occured while %s tried to call '%s': %s.\n", + unitname(u), fname, error)); + lua_pop(L, 1); + std::terminate(); + } + } +} + void bind_script(lua_State * L) { @@ -311,6 +333,7 @@ bind_script(lua_State * L) register_function((pf_generic)&lua_useitem, "lua_useitem"); register_function((pf_generic)&lua_getresource, "lua_getresource"); register_function((pf_generic)&lua_changeresource, "lua_changeresource"); + register_function((pf_generic)&lua_equipmentcallback, "lua_equip"); module(L)[ def("overload", &overload), diff --git a/src/eressea/server.cpp b/src/eressea/server.cpp index e657991c3..8555fd1cd 100644 --- a/src/eressea/server.cpp +++ b/src/eressea/server.cpp @@ -223,7 +223,6 @@ game_init(void) register_ships(); register_itemfunctions(); register_spells(); - register_archetypes(); #ifdef DUNGEON_MODULE register_dungeon(); #endif @@ -239,6 +238,7 @@ game_init(void) register_itemtypes(); register_xmlreader(); + register_archetypes(); enable_xml_gamecode(); init_data(xmlfile); diff --git a/src/res/equipment.xml b/src/res/equipment.xml index 4962a3c6e..929d7ba2d 100644 --- a/src/res/equipment.xml +++ b/src/res/equipment.xml @@ -137,6 +137,7 @@ + @@ -149,6 +150,11 @@ + + + + + @@ -181,10 +187,16 @@ + + + + + + diff --git a/src/res/rts.xml b/src/res/rts.xml index b11cbeb34..337a17e32 100644 --- a/src/res/rts.xml +++ b/src/res/rts.xml @@ -12,6 +12,7 @@ + diff --git a/src/res/rts/equipment.xml b/src/res/rts/equipment.xml index 10ae844fc..a9c17616e 100644 --- a/src/res/rts/equipment.xml +++ b/src/res/rts/equipment.xml @@ -30,6 +30,7 @@ + diff --git a/src/res/rts/strings.xml b/src/res/rts/strings.xml new file mode 100644 index 000000000..20348358a --- /dev/null +++ b/src/res/rts/strings.xml @@ -0,0 +1,39 @@ + + + + + knight + Ritter + + + knights + + + craftsman + Handwerker + + + craftsmen + + + swordsman + Schwertkämpfer + + + swordsmen + + + swordsman + Pikenier + + + pikemen + Pikeniere + + + + Barracks + Kaserne + + + diff --git a/src/res/rts/units.xml b/src/res/rts/units.xml index 07dbf62b1..3d18bc8b4 100644 --- a/src/res/rts/units.xml +++ b/src/res/rts/units.xml @@ -2,26 +2,26 @@ - + - + - + - + diff --git a/src/res/vinyambar/de/strings-classic.xml b/src/res/vinyambar/de/strings-classic.xml index 2aebdb22a..4e22735df 100644 --- a/src/res/vinyambar/de/strings-classic.xml +++ b/src/res/vinyambar/de/strings-classic.xml @@ -6,7 +6,7 @@ Weitere Informationen über das Spiel findest Du unter htpp://www.vinyambar.de/ - Mit der ersten Auswertung bekommst du einen Computerreport, den du mit vielen der Tools auf http://www.eressea-pbem.de/download.html benutzen kannst. Wenn du ihn nicht bekommen möchtest, gib einer deiner Einheiten den Befehl OPTION COMPUTER NICHT. + Mit der ersten Auswertung bekommst du einen Computerreport, den du mit vielen der Tools auf http://www.eressea.de/ benutzen kannst. Wenn du ihn nicht bekommen möchtest, gib einer deiner Einheiten den Befehl OPTION COMPUTER NICHT. ARBEITE diff --git a/src/scripts/rts-run.lua b/src/scripts/rts-run.lua index 6c4c666bb..8d5fde91e 100644 --- a/src/scripts/rts-run.lua +++ b/src/scripts/rts-run.lua @@ -33,6 +33,12 @@ function run_scripts() end end +function equip_new_faction(u) + b = add_building(u.region, "castle") + b.size = 10 + u.building = b +end + function process(orders) file = "" .. get_turn() if read_game(file)~=0 then