diff --git a/src/common/gamecode/creport.c b/src/common/gamecode/creport.c index a9c7054fb..328ef94f4 100644 --- a/src/common/gamecode/creport.c +++ b/src/common/gamecode/creport.c @@ -1115,6 +1115,7 @@ cr_borders(seen_region ** seen, const region * r, const faction * f, int seemode } } } + static void cr_output_resources(FILE * F, report_context * ctx, region * r, struct rawmaterial * res, int see_mode) { @@ -1251,7 +1252,7 @@ cr_output_region(FILE * F, report_context * ctx, seen_region * sr) if (sr->mode>=see_unit) { /* trade */ - if (!TradeDisabled() && rpeasants(r)/TRADE_FRACTION > 0) { + if (rpeasants(r)/TRADE_FRACTION > 0) { struct demand * dmd = r->land->demands; fputs("PREISE\n", F); while (dmd) { diff --git a/src/common/gamecode/economy.c b/src/common/gamecode/economy.c index 1a21d6b0c..6591357f6 100644 --- a/src/common/gamecode/economy.c +++ b/src/common/gamecode/economy.c @@ -90,8 +90,6 @@ typedef struct request { } type; } request; -static request workers[1024]; -static request *nextworker; static int working; static request entertainers[1024]; @@ -1158,8 +1156,7 @@ recruit_classic(void) { static int value = -1; if (value<0) { - const char * str = get_param(global.parameters, "recruit.classic"); - value = str?atoi(str):1; + value = get_param_int(global.parameters, "recruit.classic", 1); } return value; } @@ -1169,8 +1166,7 @@ recruit_archetypes(void) { static int value = -1; if (value<0) { - const char * str = get_param(global.parameters, "recruit.archetypes"); - value = str?atoi(str):0; + value = get_param_int(global.parameters, "recruit.archetypes", 0); } return value; } @@ -2954,7 +2950,7 @@ entertain_cmd(unit * u, struct order * ord) static void -expandwork(region * r) +expandwork(region * r, request * work_begin, request * work_end) { int n, earnings; /* n: verbleibende Einnahmen */ @@ -2964,7 +2960,7 @@ expandwork(region * r) int verdienst = 0; request *o; - for (o = &workers[0]; o != nextworker; ++o) { + for (o = work_begin; o != work_end; ++o) { unit * u = o->unit; int workers; @@ -3000,33 +2996,38 @@ expandwork(region * r) rsetmoney(r, rmoney(r) + earnings); } -static void -work_cmd(unit * u, order * ord) +static int +do_work(unit * u, order * ord, request * o) { - region * r = u->region; - request *o; - int w; + if (playerrace(u->race)) { + region * r = u->region; + int w; - if(fval(u, UFL_WERE)) { - cmistake(u, ord, 313, MSG_INCOME); - return; - } - if (besieged(u)) { - cmistake(u, ord, 60, MSG_INCOME); - return; - } - if (u->ship && is_guarded(r, u, GUARD_CREWS)) { - cmistake(u, ord, 69, MSG_INCOME); - return; - } - w = wage(r, u->faction, u->race); - u->wants = u->number * w; - o = nextworker++; - o->unit = u; - o->qty = u->number * w; - working += u->number; + if(fval(u, UFL_WERE)) { + cmistake(u, ord, 313, MSG_INCOME); + return -1; + } + if (besieged(u)) { + cmistake(u, ord, 60, MSG_INCOME); + return -1; + } + if (u->ship && is_guarded(r, u, GUARD_CREWS)) { + cmistake(u, ord, 69, MSG_INCOME); + return -1; + } + w = wage(r, u->faction, u->race); + u->wants = u->number * w; + o->unit = u; + o->qty = u->number * w; + working += u->number; + return 0; + } + else if (!is_monsters(u->faction)) { + ADDMSG(&u->faction->msgs, + msg_feedback(u, ord, "race_cantwork", "race", u->race)); + } + return -1; } -/* ------------------------------------------------------------- */ static void expandtax(region * r, request * taxorders) @@ -3111,15 +3112,35 @@ tax_cmd(unit * u, struct order * ord, request ** taxorders) addlist(taxorders, o); return; } -/* ------------------------------------------------------------- */ + +void +auto_work(region * r) +{ + request workers[1024]; + request * nextworker = workers; + unit * u; + + for (u=r->units;u;u=u->next) { + if (!(u->flags & UFL_LONGACTION) && !is_monsters(u->faction)) { + if (do_work(u, NULL, nextworker)==0) { + ++nextworker; + } + } + } + if (nextworker!=workers) { + expandwork(r, workers, nextworker); + } +} void produce(void) { + request workers[1024]; region *r; request *taxorders, *sellorders, *stealorders, *buyorders; unit *u; int todo; + int autowork = get_param_int(global.parameters, "work.auto", 0); /* das sind alles befehle, die 30 tage brauchen, und die in thisorder * stehen! von allen 30-tage befehlen wird einfach der letzte verwendet @@ -3133,13 +3154,13 @@ produce(void) for (r = regions; r; r = r->next) { boolean limited = true; + request * nextworker = workers; assert(rmoney(r) >= 0); assert(rpeasants(r) >= 0); buyorders = 0; sellorders = 0; - nextworker = &workers[0]; working = 0; nextentertainer = &entertainers[0]; entertaining = 0; @@ -3147,6 +3168,9 @@ produce(void) stealorders = 0; for (u = r->units; u; u = u->next) { + order * ord; + boolean trader = false; + if (u->race == new_race[RC_SPELL] || fval(u, UFL_LONGACTION)) continue; @@ -3159,31 +3183,27 @@ produce(void) continue; } - if (!TradeDisabled()) { - order * ord; - boolean trader = false; - for (ord = u->orders;ord;ord=ord->next) { - switch (get_keyword(ord)) { - case K_BUY: - buy(u, &buyorders, ord); - trader = true; - break; - case K_SELL: - /* sell returns true if the sale is not limited - * by the region limit */ - limited &= !sell(u, &sellorders, ord); - trader = true; - break; - } + for (ord = u->orders;ord;ord=ord->next) { + switch (get_keyword(ord)) { + case K_BUY: + buy(u, &buyorders, ord); + trader = true; + break; + case K_SELL: + /* sell returns true if the sale is not limited + * by the region limit */ + limited &= !sell(u, &sellorders, ord); + trader = true; + break; } - if (trader) { - attrib * a = a_find(u->attribs, &at_trades); - if (a && a->data.i) { - produceexp(u, SK_TRADE, u->number); - } - fset(u, UFL_LONGACTION|UFL_NOTMOVING); - continue; + } + if (trader) { + attrib * a = a_find(u->attribs, &at_trades); + if (a && a->data.i) { + produceexp(u, SK_TRADE, u->number); } + fset(u, UFL_LONGACTION|UFL_NOTMOVING); + continue; } todo = get_keyword(u->thisorder); @@ -3201,10 +3221,8 @@ produce(void) break; case K_WORK: - if (playerrace(u->race)) work_cmd(u, u->thisorder); - else if (playerrace(u->faction->race)) { - ADDMSG(&u->faction->msgs, - msg_feedback(u, u->thisorder, "race_cantwork", "race", u->race)); + if (!autowork && do_work(u, u->thisorder, nextworker)==0) { + ++nextworker; } break; @@ -3240,7 +3258,7 @@ produce(void) * letzten Runde berechnen kann, wieviel die Bauern für Unterhaltung * auszugeben bereit sind. */ if (entertaining) expandentertainment(r); - expandwork(r); + if (!autowork) expandwork(r, workers, nextworker); if (taxorders) expandtax(r, taxorders); /* An erster Stelle Kaufen (expandbuying), die Bauern so Geld bekommen, um diff --git a/src/common/gamecode/economy.h b/src/common/gamecode/economy.h index 9b4e4c0e7..1a1e2f49c 100644 --- a/src/common/gamecode/economy.h +++ b/src/common/gamecode/economy.h @@ -49,6 +49,7 @@ extern int income(const struct unit * u); void economics(struct region *r); void produce(void); +void auto_work(struct region * r); enum { IC_WORK, IC_ENTERTAIN, IC_TAX, IC_TRADE, IC_TRADETAX, IC_STEAL, IC_MAGIC }; void maintain_buildings(struct region * r, boolean crash); diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c index 72a05ed60..c13f6936b 100644 --- a/src/common/gamecode/laws.c +++ b/src/common/gamecode/laws.c @@ -3549,11 +3549,13 @@ add_proc(int priority, const char * name, int type) void add_proc_order(int priority, keyword_t kword, int (*parser)(struct unit *, struct order *), unsigned int flags, const char * name) { - processor * proc = add_proc(priority, name, PR_ORDER); - if (proc) { - proc->data.per_order.process = parser; - proc->data.per_order.kword = kword; - proc->flags = flags; + if (!global.disabled[kword]) { + processor * proc = add_proc(priority, name, PR_ORDER); + if (proc) { + proc->data.per_order.process = parser; + proc->data.per_order.kword = kword; + proc->flags = flags; + } } } @@ -3756,7 +3758,7 @@ init_processor(void) add_proc_order(p, K_PREFIX, &prefix_cmd, 0, NULL); add_proc_order(p, K_SETSTEALTH, &setstealth_cmd, 0, NULL); add_proc_order(p, K_STATUS, &status_cmd, 0, NULL); - add_proc_order(p, K_COMBAT, &combatspell_cmd, 0, NULL); + add_proc_order(p, K_COMBATSPELL, &combatspell_cmd, 0, NULL); add_proc_order(p, K_DISPLAY, &display_cmd, 0, NULL); add_proc_order(p, K_NAME, &name_cmd, 0, NULL); add_proc_order(p, K_GUARD, &guard_off_cmd, 0, NULL); @@ -3800,8 +3802,10 @@ init_processor(void) add_proc_region(p, &do_battle, "Attackieren"); } - p+=10; /* after combat, reset rng */ - add_proc_region(p, &do_siege, "Belagern"); + if (!global.disabled[K_BESIEGE]) { + p+=10; + add_proc_region(p, &do_siege, "Belagern"); + } p+=10; /* can't allow reserve before siege (weapons) */ add_proc_region(p, &enter_1, "Kontaktieren & Betreten (2. Versuch)"); @@ -3816,15 +3820,17 @@ init_processor(void) p+=10; /* QUIT fuer sich alleine */ add_proc_global(p, &quit, "Sterben"); - add_proc_global(p, &parse_restart, "Neustart"); - - p+=10; - add_proc_global(p, &magic, "Zaubern"); - - p+=10; - if (!global.disabled[K_TEACH]) { - add_proc_order(p, K_TEACH, &teach_cmd, PROC_THISORDER|PROC_LONGORDER, "Lehren"); + if (!global.disabled[K_RESTART]) { + add_proc_global(p, &parse_restart, "Neustart"); } + + if (!global.disabled[K_CAST]) { + p+=10; + add_proc_global(p, &magic, "Zaubern"); + } + + p+=10; + add_proc_order(p, K_TEACH, &teach_cmd, PROC_THISORDER|PROC_LONGORDER, "Lehren"); p+=10; add_proc_order(p, K_STUDY, &learn_cmd, PROC_THISORDER|PROC_LONGORDER, "Lernen"); @@ -3842,11 +3848,16 @@ init_processor(void) p+=10; add_proc_global(p, &movement, "Bewegungen"); + if (get_param_int(global.parameters, "work.auto", 0)) { + p+=10; + add_proc_region(p, &auto_work, "Arbeiten (auto)"); + } + p+=10; add_proc_order(p, K_GUARD, &guard_on_cmd, 0, "Bewache (an)"); #if XECMD_MODULE /* can do together with guard */ - add_proc_order(p, K_LEAVE, &xecmd, 0, "Zeitung"); + add_proc_order(p, K_XE, &xecmd, 0, "Zeitung"); #endif p+=10; @@ -3860,14 +3871,18 @@ init_processor(void) p+=10; add_proc_global(p, &monthly_healing, "Regeneration (HP)"); add_proc_global(p, ®eneration_magiepunkte, "Regeneration (Aura)"); - add_proc_global(p, &defaultorders, "Defaults setzen"); + if (!global.disabled[K_DEFAULT]) { + add_proc_global(p, &defaultorders, "Defaults setzen"); + } add_proc_global(p, &demographics, "Nahrung, Seuchen, Wachstum, Wanderung"); p+=10; add_proc_region(p, &maintain_buildings_2, "Gebaeudeunterhalt (2. Versuch)"); - p+=10; - add_proc_global(p, &reorder, "Einheiten sortieren"); + if (!global.disabled[K_SORT]) { + p+=10; + add_proc_global(p, &reorder, "Einheiten sortieren"); + } #if KARMA_MODULE p+=10; add_proc_global(p, &karma, "Jihads setzen"); @@ -3881,10 +3896,11 @@ init_processor(void) add_proc_global(p, &declare_war, "Krieg & Frieden"); #endif add_proc_order(p, K_PROMOTION, &promotion_cmd, 0, "Heldenbefoerderung"); - add_proc_order(p, K_NUMBER, &renumber_cmd, 0, "Neue Nummern (Einheiten)"); - - p+=10; - add_proc_global(p, &renumber_factions, "Neue Nummern"); + if (!global.disabled[K_NUMBER]) { + add_proc_order(p, K_NUMBER, &renumber_cmd, 0, "Neue Nummern (Einheiten)"); + p+=10; + add_proc_global(p, &renumber_factions, "Neue Nummern"); + } } void diff --git a/src/common/gamecode/report.c b/src/common/gamecode/report.c index 3da27b62f..cce3ee9a6 100644 --- a/src/common/gamecode/report.c +++ b/src/common/gamecode/report.c @@ -330,7 +330,7 @@ report_spell(FILE * F, spell *sp, const struct locale * lang) size = sizeof(buf) - 1; if (sp->sptyp & ISCOMBATSPELL) { - bytes = (int)strlcpy(bufp, LOC(lang, keywords[K_COMBAT]), size); + bytes = (int)strlcpy(bufp, LOC(lang, keywords[K_COMBATSPELL]), size); } else { bytes = (int)strlcpy(bufp, LOC(lang, keywords[K_CAST]), size); } @@ -1215,18 +1215,16 @@ statistics(FILE * F, const region * r, const faction * f) rparagraph(F, buf, 2, 2, 0); msg_release(m); - if (!TradeDisabled()) { - if (buildingtype_exists(r, bt_find("caravan"))) { - m = msg_message("nr_stat_luxuries", "max", - (p * 2) / TRADE_FRACTION); - } else { - m = msg_message("nr_stat_luxuries", "max", - p / TRADE_FRACTION); - } - nr_render(m, f->locale, buf, sizeof(buf), f); - rparagraph(F, buf, 2, 2, 0); - msg_release(m); + if (buildingtype_exists(r, bt_find("caravan"))) { + m = msg_message("nr_stat_luxuries", "max", + (p * 2) / TRADE_FRACTION); + } else { + m = msg_message("nr_stat_luxuries", "max", + p / TRADE_FRACTION); } + nr_render(m, f->locale, buf, sizeof(buf), f); + rparagraph(F, buf, 2, 2, 0); + msg_release(m); } /* info about units */ @@ -2163,7 +2161,7 @@ report_plaintext(const char * filename, report_context * ctx, const char * chars if (sr->mode==see_unit) { anyunits = 1; describe(F, r, 0, f); - if (!TradeDisabled() && !fval(r->terrain, SEA_REGION) && rpeasants(r)/TRADE_FRACTION > 0) { + if (!fval(r->terrain, SEA_REGION) && rpeasants(r)/TRADE_FRACTION > 0) { rnl(F); prices(F, r, f); } diff --git a/src/common/kernel/build.c b/src/common/kernel/build.c index 5c9008999..0f7e8f950 100644 --- a/src/common/kernel/build.c +++ b/src/common/kernel/build.c @@ -76,8 +76,7 @@ CheckOverload(void) { static int value = -1; if (value<0) { - const char * str = get_param(global.parameters, "rules.check_overload"); - value = str?atoi(str):0; + value = get_param_int(global.parameters, "rules.check_overload", 0); } return value; } diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index 678c0b88d..3231fd6eb 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -117,8 +117,7 @@ int NewbieImmunity(void) { static int value = -1; if (value<0) { - const char * str = get_param(global.parameters, "NewbieImmunity"); - value = str?atoi(str):0; + value = get_param_int(global.parameters, "NewbieImmunity", 0); } return value; } @@ -127,8 +126,7 @@ static int MaxAge(void) { static int value = -1; if (value<0) { - const char * str = get_param(global.parameters, "MaxAge"); - value = str?atoi(str):0; + value = get_param_int(global.parameters, "MaxAge", 0); } return value; } @@ -151,8 +149,7 @@ ExpensiveMigrants(void) { int value = -1; if (value<0) { - const char * str = get_param(global.parameters, "study.expensivemigrants"); - value = str?atoi(str):0; + value = get_param_int(global.parameters, "study.expensivemigrants", 0); } return value; } @@ -207,8 +204,7 @@ LongHunger(const struct unit * u) { #endif } if (value<0) { - const char * str = get_param(global.parameters, "hunger.long"); - value = str?atoi(str):0; + value = get_param_int(global.parameters, "hunger.long", 0); } return value; } @@ -218,18 +214,7 @@ SkillCap(skill_t sk) { static int value = -1; if (sk==SK_MAGIC) return 0; /* no caps on magic */ if (value<0) { - const char * str = get_param(global.parameters, "skill.maxlevel"); - value = str?atoi(str):0; - } - return value; -} - -boolean -TradeDisabled(void) { - static int value = -1; - if (value<0) { - const char * str = get_param(global.parameters, "trade.disabled"); - value = str?atoi(str):0; + value = get_param_int(global.parameters, "skill.maxlevel", 0); } return value; } @@ -238,8 +223,7 @@ int NMRTimeout(void) { static int value = -1; if (value<0) { - const char * str = get_param(global.parameters, "nmr.timeout"); - value = str?atoi(str):0; + value = get_param_int(global.parameters, "nmr.timeout", 0); } return value; } @@ -470,8 +454,7 @@ allied_skilllimit(const faction * f, skill_t sk) { static int value = -1; if (value<0) { - const char * str = get_param(global.parameters, "alliance.skilllimit"); - value = str?atoi(str):0; + value = get_param_int(global.parameters, "alliance.skilllimit", 0); } return value; } @@ -2110,23 +2093,19 @@ init_locale(const struct locale * lang) #if PTRIES ptrie = get_ptrie(lang, UT_SKILLS); for (i=0;i!=MAXSKILLS;++i) { - if (i!=SK_TRADE || !TradeDisabled()) { - skill_t sk = (skill_t)i; - const char * skname = skillname(sk, lang); - if (skname!=NULL) { - ptrie_insert(ptrie, skname, &sk, sizeof(sk)); - } + skill_t sk = (skill_t)i; + const char * skname = skillname(sk, lang); + if (skname!=NULL) { + ptrie_insert(ptrie, skname, &sk, sizeof(sk)); } } #else tokens = get_translations(lang, UT_SKILLS); for (i=0;i!=MAXSKILLS;++i) { - if (i!=SK_TRADE || !TradeDisabled()) { - const char * skname = skillname((skill_t)i, lang); - if (skname!=NULL) { - var.i = i; - addtoken(tokens, skname, var); - } + const char * skname = skillname((skill_t)i, lang); + if (skname!=NULL) { + var.i = i; + addtoken(tokens, skname, var); } } #endif @@ -2177,6 +2156,17 @@ get_param(const struct param * p, const char * key) return NULL; } +int +get_param_int(const struct param * p, const char * key, int def) +{ + while (p!=NULL) { + if (strcmp(p->name, key)==0) return atoi(p->data); + p = p->next; + } + return def; +} + + void set_param(struct param ** p, const char * key, const char * data) diff --git a/src/common/kernel/eressea.h b/src/common/kernel/eressea.h index 091a4b695..8d9265a50 100644 --- a/src/common/kernel/eressea.h +++ b/src/common/kernel/eressea.h @@ -396,11 +396,11 @@ extern const char * dbrace(const struct race * rc); extern void set_param(struct param ** p, const char * name, const char * data); extern const char* get_param(const struct param * p, const char * name); +extern int get_param_int(const struct param * p, const char * name, int def); extern boolean ExpensiveMigrants(void); extern int NMRTimeout(void); extern int LongHunger(const struct unit * u); -extern boolean TradeDisabled(void); extern int SkillCap(skill_t sk); extern int NewbieImmunity(void); extern int AllianceAuto(void); /* flags that allied factions get automatically */ diff --git a/src/common/kernel/save.c b/src/common/kernel/save.c index fd5143f65..2365462f8 100644 --- a/src/common/kernel/save.c +++ b/src/common/kernel/save.c @@ -914,6 +914,10 @@ readregion(struct storage * store, short x, short y) if (store->version < TERRAIN_VERSION) { int ter = store->r_int(store); terrain = newterrain((terrain_t)ter); + if (terrain==NULL) { + log_error(("while reading datafile from pre-TERRAIN_VERSION, could not find terrain #%d.\n", ter)); + terrain = newterrain(T_PLAIN); + } } else { char name[64]; store->r_str_buf(store, name, sizeof(name)); diff --git a/src/common/kernel/skill.c b/src/common/kernel/skill.c index d6116ec2b..fc6d9770e 100644 --- a/src/common/kernel/skill.c +++ b/src/common/kernel/skill.c @@ -77,7 +77,7 @@ const char *skillnames[MAXSKILLS] = "unarmed" }; -static boolean skill_enabled[MAXSKILLS]; +boolean skill_enabled[MAXSKILLS]; const char * skillname(skill_t sk, const struct locale * lang) diff --git a/src/common/kernel/skill.h b/src/common/kernel/skill.h index 88856bfe4..e42d87247 100644 --- a/src/common/kernel/skill.h +++ b/src/common/kernel/skill.h @@ -60,6 +60,7 @@ extern int skill_compare(const skill * sk, const skill * sc); extern void sk_set(skill * sv, int level); extern const char *skillnames[]; +extern boolean skill_enabled[]; #ifdef __cplusplus } diff --git a/src/common/kernel/terrain.c b/src/common/kernel/terrain.c index 9d3c38770..299d2bbb7 100644 --- a/src/common/kernel/terrain.c +++ b/src/common/kernel/terrain.c @@ -38,7 +38,7 @@ #define MAXTERRAINS 20 -const char * terraindata[] = { +const char * terraindata[MAXTERRAINS] = { "ocean", "plain", "swamp", @@ -47,8 +47,8 @@ const char * terraindata[] = { "mountain", "glacier", "firewall", - "hell", /* dungeon module */ - "plain", /* former grassland */ + NULL, /* dungeon module */ + NULL, /* former grassland */ "fog", "thickfog", "volcano", @@ -56,11 +56,10 @@ const char * terraindata[] = { "iceberg_sleep", "iceberg", - "hall1", /* museum module */ - "corridor1", /* museum module */ - "plain", /* former magicstorm */ - "wall1", /* museum module */ - NULL + NULL, /* museum module */ + NULL, /* museum module */ + NULL, /* former magicstorm */ + NULL /* museum module */ }; static terrain_type * registered_terrains; @@ -142,11 +141,13 @@ init_terrains(void) for (t=0;t!=MAXTERRAINS;++t) { const terrain_type * newterrain = newterrains[t]; if (newterrain!=NULL) continue; - newterrain = get_terrain(terraindata[t]); - if (newterrain!=NULL) { - newterrains[t] = newterrain; - } else { - log_warning(("missing classic terrain %s\n", terraindata[t])); + if (terraindata[t]!=NULL) { + newterrain = get_terrain(terraindata[t]); + if (newterrain!=NULL) { + newterrains[t] = newterrain; + } else { + log_warning(("missing classic terrain %s\n", terraindata[t])); + } } } } diff --git a/src/common/kernel/types.h b/src/common/kernel/types.h index 7f24c1322..2ef3c2c97 100644 --- a/src/common/kernel/types.h +++ b/src/common/kernel/types.h @@ -103,7 +103,7 @@ enum { K_GIVE, K_ALLY, K_STATUS, - K_COMBAT, + K_COMBATSPELL, K_BUY, K_CONTACT, K_TEACH, diff --git a/src/common/kernel/xmlreader.c b/src/common/kernel/xmlreader.c index ccb838214..eef649ccf 100644 --- a/src/common/kernel/xmlreader.c +++ b/src/common/kernel/xmlreader.c @@ -852,6 +852,45 @@ xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) return itype; } +static int +parse_rules(xmlDocPtr doc) +{ + xmlXPathContextPtr xpath = xmlXPathNewContext(doc); + xmlXPathObjectPtr functions; + xmlNodeSetPtr nodes; + int i; + + /* reading eressea/resources/resource */ + functions = xmlXPathEvalExpression(BAD_CAST "/eressea/rules/function", xpath); + nodes = functions->nodesetval; + for (i=0;i!=nodes->nodeNr;++i) { + xmlNodePtr node = nodes->nodeTab[i]; + xmlChar *propValue; + pf_generic fun; + + parse_function(node, &fun, &propValue); + + if (fun==NULL) { + log_error(("unknown function for rule '%s' %s\n", (const char*)propValue)); + xmlFree(propValue); + continue; + } + assert(propValue!=NULL); + if (strcmp((const char*)propValue, "wage")==0) { + global.functions.wage = (int (*)(const struct region*, const struct faction*, const struct race*))fun; + } else if (strcmp((const char*)propValue, "maintenance")==0) { + global.functions.maintenance = (int (*)(const struct unit*))fun; + } else { + log_error(("unknown function for rule '%s'\n", + (const char*)propValue)); + } + xmlFree(propValue); + } + xmlXPathFreeObject(functions); + xmlXPathFreeContext(xpath); + return 0; +} + static int parse_resources(xmlDocPtr doc) { @@ -2037,6 +2076,7 @@ register_xmlreader(void) xml_register_callback(parse_prefixes); xml_register_callback(parse_messages); xml_register_callback(parse_resources); + xml_register_callback(parse_rules); xml_register_callback(parse_terrains); /* requires resources */ xml_register_callback(parse_buildings); /* requires resources */ diff --git a/src/eressea/korrektur.c b/src/eressea/korrektur.c index 49add37a3..d365a24c3 100644 --- a/src/eressea/korrektur.c +++ b/src/eressea/korrektur.c @@ -256,7 +256,7 @@ fix_age(void) const race * uruk = rc_find("uruk"); for (f=factions;f;f=f->next) { if (!is_monsters(f) && playerrace(f->race)) continue; - if (f->race==oldorc) f->race= uruk; + if (f->race==oldorc) f->race = uruk; else if (f->age!=turn) { log_printf("Alter von Partei %s auf %d angepasst.\n", factionid(f), turn); f->age = turn; diff --git a/src/eressea/lua/script.cpp b/src/eressea/lua/script.cpp index 84e7f926c..f47a6a013 100644 --- a/src/eressea/lua/script.cpp +++ b/src/eressea/lua/script.cpp @@ -36,7 +36,9 @@ #pragma warning (disable: 4127) #endif #include -#include +#if LUABIND_BETA >= 7 +# include +#endif #ifdef _MSC_VER #pragma warning (pop) #endif @@ -229,35 +231,23 @@ lua_getresource(unit * u, const struct resource_type * rtype) return retval; } -struct script_interface { - void destroy() { - delete wage; - wage = 0; - delete maintenance; - maintenance = 0; - } - object * wage; - object * maintenance; -}; - -static script_interface interface; - static int lua_wage(const region * r, const faction * f, const race * rc) { + const char * fname = "wage"; int retval = -1; + lua_State * L = (lua_State *)global.vm_state; - assert(interface.wage); - try { - object o = interface.wage->operator()(r, f, rc); - retval = object_cast(o); - } - catch (error& e) { - lua_State* L = e.state(); - const char* error = lua_tostring(L, -1); - log_error(("An exception occured in interface 'wage': %s.\n", error)); - lua_pop(L, 1); - std::terminate(); + if (is_function(L, fname)) { + try { + retval = luabind::call_function(L, fname, r, f, rc?rc->_name[0]:NULL); + } + catch (luabind::error& e) { + lua_State* L = e.state(); + const char* error = lua_tostring(L, -1); + log_error(("An exception occured while calling '%s': %s.\n", fname, error)); + lua_pop(L, 1); + } } return retval; } @@ -265,35 +255,24 @@ lua_wage(const region * r, const faction * f, const race * rc) static int lua_maintenance(const unit * u) { + const char * fname = "maintenance"; int retval = -1; - assert(interface.maintenance); + lua_State * L = (lua_State *)global.vm_state; - try { - object o = interface.maintenance->operator()(u); - retval = object_cast(o); - } - catch (error& e) { - lua_State* L = e.state(); - const char* error = lua_tostring(L, -1); - log_error(("An exception occured in interface 'maintenance': %s.\n", error)); - lua_pop(L, 1); - std::terminate(); + if (is_function(L, fname)) { + try { + retval = luabind::call_function(L, fname, u); + } + catch (luabind::error& e) { + lua_State* L = e.state(); + const char* error = lua_tostring(L, -1); + log_error(("An exception occured while calling '%s': %s.\n", fname, error)); + lua_pop(L, 1); + } } return retval; } -static void -overload(const char * name, const object& f) -{ - if (strcmp(name, "wage")==0) { - global.functions.wage = &lua_wage; - interface.wage = new object(f); - } else if (strcmp(name, "maintenance")==0) { - global.functions.maintenance = &lua_maintenance; - interface.maintenance = new object(f);; - } -} - static void unit_setscript(struct unit& u, const luabind::object& f) { @@ -343,8 +322,10 @@ bind_script(lua_State * L) register_function((pf_generic)&lua_changeresource, "lua_changeresource"); register_function((pf_generic)&lua_equipmentcallback, "lua_equip"); + register_function((pf_generic)&lua_wage, "lua_wage"); + register_function((pf_generic)&lua_maintenance, "lua_maintenance"); + module(L)[ - def("overload", &overload), def("set_race_brain", &race_setscript), def("set_unit_brain", &unit_setscript) ]; @@ -353,5 +334,4 @@ bind_script(lua_State * L) void reset_scripts() { - interface.destroy(); } diff --git a/src/res/asgard.xml b/src/res/asgard.xml new file mode 100644 index 000000000..88e172d85 --- /dev/null +++ b/src/res/asgard.xml @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + eressea-server@eressea.kn-bremen.de + eressea-server@eressea.kn-bremen.de + + + Bitte denke daran, deine Befehle mit dem Betreff + ERESSEA BEFEHLE an eressea-server@eressea.kn-bremen.de zu senden. + Remember to send your orders to + eressea-server@eressea.kn-bremen.de with the subject ERESSEA ORDERS. + + + ERESSEA BEFEHLE + ERESSEA ORDERS + + + diff --git a/src/res/asgard/items.xml b/src/res/asgard/items.xml new file mode 100644 index 000000000..2f370b0fc --- /dev/null +++ b/src/res/asgard/items.xml @@ -0,0 +1,600 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/res/asgard/races.xml b/src/res/asgard/races.xml new file mode 100644 index 000000000..3602fdf54 --- /dev/null +++ b/src/res/asgard/races.xml @@ -0,0 +1,1342 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/res/asgard/rules.xml b/src/res/asgard/rules.xml new file mode 100644 index 000000000..ec095ac88 --- /dev/null +++ b/src/res/asgard/rules.xml @@ -0,0 +1,4 @@ + + + + diff --git a/src/res/asgard/terrains.xml b/src/res/asgard/terrains.xml new file mode 100644 index 000000000..7eb41c87e --- /dev/null +++ b/src/res/asgard/terrains.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/scripts/asgard.lua b/src/scripts/asgard.lua new file mode 100644 index 000000000..538fb8227 --- /dev/null +++ b/src/scripts/asgard.lua @@ -0,0 +1,81 @@ +-- the locales that this gameworld supports. +local locales = { "de", "en" } + +function loadscript(name) + local script = scriptpath .. "/" .. name + print("- loading " .. script) + if pcall(dofile, script)==0 then + print("Could not load " .. script) + end +end + +loadscript("default.lua") + +function load_scripts() + scripts = { + "asgard/extensions.lua" + } + for index, value in pairs(scripts) do + loadscript(value) + end +end + +function process(orders) + -- initialize starting equipment for new players + + if open_game(get_turn())~=0 then + print("could not read game") + return -1 + end + init_summary() + + -- kill multi-players (external script) + -- loadscript("eressea/multis.lua") + + -- run the turn: + -- set_encoding("utf8") + if read_orders(orders) ~= 0 then + print("could not read " .. orders) + return -1 + end + + plan_monsters() + + local nmrs = get_nmrs(1) + if nmrs >= 80 then + print("Shit. More than 80 factions with 1 NMR (" .. nmrs .. ")") + write_summary() + return -1 + end + print (nmrs .. " Factions with 1 NMR") + + process_orders() + + -- post-turn updates: + update_guards() + update_scores() + + -- use newfactions file to place out new players + autoseed(basepath .. "/newfactions", false) + + write_files(locales) + + file = "" .. get_turn() .. ".dat" + if write_game(file, "binary")~=0 then + print("could not write game") + return -1 + end +end + +-- +-- main body of script +-- + +-- orderfile: contains the name of the orders. +load_scripts() +if orderfile==nil then + print "you must specify an orderfile" +else + process(orderfile) +end + diff --git a/src/scripts/asgard/extensions.lua b/src/scripts/asgard/extensions.lua new file mode 100644 index 000000000..8b219598d --- /dev/null +++ b/src/scripts/asgard/extensions.lua @@ -0,0 +1,94 @@ +-- wage per person in this region +function wage(r, f, race) + return 10 +end + +function peasant_getresource(u) + return u.region:get_resource("peasant") +end + +function peasant_changeresource(u, delta) + local p = u.region:get_resource("peasant") + p = p + delta + if p < 0 then + p = 0 + end + u.region:set_resource("peasant", p) + return p +end + +function hp_getresource(u) + return u.hp +end + +function hp_changeresource(u, delta) + local hp = u.hp + delta + + if hp < u.number then + if hp < 0 then + hp = 0 + end + u.number = hp + end + u.hp = hp + return hp +end + +function horse_limit(r) + return r:get_resource("horse") +end + +function horse_produce(r, n) + local horses = r:get_resource("horse") + if horses>=n then + r:set_resource("horse", horses-n) + else + r:set_resource("horse", 0) + end +end + +function log_limit(r) + if r:get_flag(1) then -- RF_MALLORN + return 0 + end + return r:get_resource("tree") + r:get_resource("sapling") +end + +function log_produce(r, n) + local trees = r:get_resource("tree") + if trees>=n then + r:set_resource("tree", trees-n) + else + r:set_resource("tree", 0) + n = n - trees + trees = r:get_resource("sapling") + if trees>=n then + r:set_resource("sapling", trees-n) + else + r:set_resource("sapling", 0) + end + end +end + +function mallorn_limit(r) + if not r:get_flag(1) then -- RF_MALLORN + return 0 + end + return r:get_resource("tree") + r:get_resource("sapling") +end + +function mallorn_produce(r, n) + local trees = r:get_resource("tree") + if trees>=n then + r:set_resource("tree", trees-n) + else + r:set_resource("tree", 0) + n = n - trees + trees = r:get_resource("sapling") + if trees>=n then + r:set_resource("sapling", trees-n) + else + r:set_resource("sapling", 0) + end + end +end diff --git a/src/scripts/kingdoms/extensions.lua b/src/scripts/kingdoms/extensions.lua index 2f9991a90..834f7afdb 100644 --- a/src/scripts/kingdoms/extensions.lua +++ b/src/scripts/kingdoms/extensions.lua @@ -1,9 +1,9 @@ -function get_wage(r, f, race) +function wage(r, f, race) return 10 end -function get_maintenance(u) +function maintenance(u) local f = u.region.owner if f ~= nil then if f == u.faction then @@ -14,6 +14,3 @@ function get_maintenance(u) end return 10 * u.number end - -overload("maintenance", get_maintenance) -overload("wage", get_wage)