diff --git a/conf/e2/catalog.xml b/conf/e2/catalog.xml index c13059eb4..87b1b2207 100644 --- a/conf/e2/catalog.xml +++ b/conf/e2/catalog.xml @@ -6,11 +6,11 @@ + rewritePrefix="../../core/res/" /> + rewritePrefix="../../res/eressea/" /> + rewritePrefix="../../res/" /> diff --git a/conf/e2/config.xml b/conf/e2/config.xml index 95153ed0e..2ca33346c 100644 --- a/conf/e2/config.xml +++ b/conf/e2/config.xml @@ -97,6 +97,8 @@ + + diff --git a/conf/e3/catalog.xml b/conf/e3/catalog.xml index 363cdec69..d231ffbfa 100644 --- a/conf/e3/catalog.xml +++ b/conf/e3/catalog.xml @@ -6,11 +6,11 @@ + rewritePrefix="../../core/res/" /> + rewritePrefix="../../res/e3a/" /> + rewritePrefix="../../res/" /> diff --git a/conf/e3/config.xml b/conf/e3/config.xml index 16722e6d9..55d020ae6 100644 --- a/conf/e3/config.xml +++ b/conf/e3/config.xml @@ -158,6 +158,8 @@ + + diff --git a/conf/e4/catalog.xml b/conf/e4/catalog.xml index 363cdec69..d231ffbfa 100644 --- a/conf/e4/catalog.xml +++ b/conf/e4/catalog.xml @@ -6,11 +6,11 @@ + rewritePrefix="../../core/res/" /> + rewritePrefix="../../res/e3a/" /> + rewritePrefix="../../res/" /> diff --git a/conf/e4/config.xml b/conf/e4/config.xml index b250e88ff..44cc35471 100644 --- a/conf/e4/config.xml +++ b/conf/e4/config.xml @@ -159,6 +159,8 @@ + + diff --git a/conf/eressea.ini b/conf/eressea.ini new file mode 100644 index 000000000..8874b3df3 --- /dev/null +++ b/conf/eressea.ini @@ -0,0 +1,15 @@ +[eressea] +base = . +report = reports +verbose = 0 +lomem = 0 +debug = 0 +memcheck = 0 +locales = de,en + +[config] +source_dir = ../server +maxnmrs = 20 + +[editor] +color = 1 diff --git a/src/bind_sqlite.c b/src/bind_sqlite.c index b164068aa..0029d1c2a 100644 --- a/src/bind_sqlite.c +++ b/src/bind_sqlite.c @@ -24,72 +24,72 @@ without prior permission by the authors of Eressea. extern int db_update_factions(sqlite3 * db, bool force, int game); static int tolua_db_update_factions(lua_State * L) { - sqlite3 *db = (sqlite3 *) tolua_tousertype(L, 1, 0); - db_update_factions(db, tolua_toboolean(L, 2, 0), global.game_id); - return 0; + sqlite3 *db = (sqlite3 *)tolua_tousertype(L, 1, 0); + db_update_factions(db, tolua_toboolean(L, 2, 0), game_id()); + return 0; } extern int db_update_scores(sqlite3 * db, bool force); static int tolua_db_update_scores(lua_State * L) { - sqlite3 *db = (sqlite3 *) tolua_tousertype(L, 1, 0); - db_update_scores(db, tolua_toboolean(L, 2, 0)); - return 0; + sqlite3 *db = (sqlite3 *)tolua_tousertype(L, 1, 0); + db_update_scores(db, tolua_toboolean(L, 2, 0)); + return 0; } static int tolua_db_execute(lua_State * L) { - sqlite3 *db = (sqlite3 *) tolua_tousertype(L, 1, 0); - const char *sql = tolua_tostring(L, 2, 0); + sqlite3 *db = (sqlite3 *)tolua_tousertype(L, 1, 0); + const char *sql = tolua_tostring(L, 2, 0); - int res = sqlite3_exec(db, sql, 0, 0, 0); + int res = sqlite3_exec(db, sql, 0, 0, 0); - tolua_pushnumber(L, (LUA_NUMBER) res); - return 1; + tolua_pushnumber(L, (LUA_NUMBER)res); + return 1; } static int tolua_db_close(lua_State * L) { - sqlite3 *db = (sqlite3 *) tolua_tousertype(L, 1, 0); - sqlite3_close(db); - return 0; + sqlite3 *db = (sqlite3 *)tolua_tousertype(L, 1, 0); + sqlite3_close(db); + return 0; } static int tolua_db_create(lua_State * L) { - sqlite3 *db; - const char *dbname = tolua_tostring(L, 1, 0); - int result = sqlite3_open_v2(dbname, &db, SQLITE_OPEN_READWRITE, 0); - if (result == SQLITE_OK) { - tolua_pushusertype(L, (void *)db, LTYPE_DB); - return 1; - } - return 0; + sqlite3 *db; + const char *dbname = tolua_tostring(L, 1, 0); + int result = sqlite3_open_v2(dbname, &db, SQLITE_OPEN_READWRITE, 0); + if (result == SQLITE_OK) { + tolua_pushusertype(L, (void *)db, LTYPE_DB); + return 1; + } + return 0; } int tolua_sqlite_open(lua_State * L) { - /* register user types */ + /* register user types */ - tolua_usertype(L, LTYPE_DB); + tolua_usertype(L, LTYPE_DB); - tolua_module(L, NULL, 0); - tolua_beginmodule(L, NULL); - { - tolua_cclass(L, LTYPE_DB, LTYPE_DB, TOLUA_CAST "", NULL); - tolua_beginmodule(L, LTYPE_DB); + tolua_module(L, NULL, 0); + tolua_beginmodule(L, NULL); { - tolua_function(L, TOLUA_CAST "open", &tolua_db_create); - tolua_function(L, TOLUA_CAST "close", &tolua_db_close); + tolua_cclass(L, LTYPE_DB, LTYPE_DB, TOLUA_CAST "", NULL); + tolua_beginmodule(L, LTYPE_DB); + { + tolua_function(L, TOLUA_CAST "open", &tolua_db_create); + tolua_function(L, TOLUA_CAST "close", &tolua_db_close); + + tolua_function(L, TOLUA_CAST "update_factions", + &tolua_db_update_factions); + tolua_function(L, TOLUA_CAST "update_scores", &tolua_db_update_scores); + tolua_function(L, TOLUA_CAST "execute", &tolua_db_execute); + } + tolua_endmodule(L); - tolua_function(L, TOLUA_CAST "update_factions", - &tolua_db_update_factions); - tolua_function(L, TOLUA_CAST "update_scores", &tolua_db_update_scores); - tolua_function(L, TOLUA_CAST "execute", &tolua_db_execute); } tolua_endmodule(L); - - } - tolua_endmodule(L); - return 0; + return 0; } diff --git a/src/creport.c b/src/creport.c index 68cb1aede..f558258f8 100644 --- a/src/creport.c +++ b/src/creport.c @@ -1490,7 +1490,7 @@ report_computer(const char *filename, report_context * ctx, const char *charset) fprintf(F, "\"%s\";locale\n", locale_name(f->locale)); fprintf(F, "%d;noskillpoints\n", 1); fprintf(F, "%ld;date\n", ctx->report_time); - fprintf(F, "\"%s\";Spiel\n", global.gamename); + fprintf(F, "\"%s\";Spiel\n", game_name()); fprintf(F, "\"%s\";Konfiguration\n", "Standard"); fprintf(F, "\"%s\";Koordinaten\n", "Hex"); fprintf(F, "%d;Basis\n", 36); diff --git a/src/kernel/config.c b/src/kernel/config.c index 26feac829..8be554c7d 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -1,7 +1,7 @@ /* Copyright (c) 1998-2010, Enno Rehling - Katja Zedel +Katja Zedel Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -97,7 +97,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include struct settings global = { - "Eressea", /* gamename */ + "Eressea", /* gamename */ }; bool lomem = false; @@ -108,57 +108,57 @@ int turn = -1; int NewbieImmunity(void) { - static int value = -1; - static int gamecookie = -1; - if (value < 0 || gamecookie != global.cookie) { - gamecookie = global.cookie; - value = get_param_int(global.parameters, "NewbieImmunity", 0); - } - return value; + static int value = -1; + static int gamecookie = -1; + if (value < 0 || gamecookie != global.cookie) { + gamecookie = global.cookie; + value = get_param_int(global.parameters, "NewbieImmunity", 0); + } + return value; } bool IsImmune(const faction * f) { - return !fval(f, FFL_NPC) && f->age < NewbieImmunity(); + return !fval(f, FFL_NPC) && f->age < NewbieImmunity(); } static int MaxAge(void) { - static int value = -1; - static int gamecookie = -1; - if (value < 0 || gamecookie != global.cookie) { - gamecookie = global.cookie; - value = get_param_int(global.parameters, "MaxAge", 0); - } - return value; + static int value = -1; + static int gamecookie = -1; + if (value < 0 || gamecookie != global.cookie) { + gamecookie = global.cookie; + value = get_param_int(global.parameters, "MaxAge", 0); + } + return value; } static int ally_flag(const char *s, int help_mask) { - if ((help_mask & HELP_MONEY) && strcmp(s, "money") == 0) - return HELP_MONEY; - if ((help_mask & HELP_FIGHT) && strcmp(s, "fight") == 0) - return HELP_FIGHT; - if ((help_mask & HELP_GIVE) && strcmp(s, "give") == 0) - return HELP_GIVE; - if ((help_mask & HELP_GUARD) && strcmp(s, "guard") == 0) - return HELP_GUARD; - if ((help_mask & HELP_FSTEALTH) && strcmp(s, "stealth") == 0) - return HELP_FSTEALTH; - if ((help_mask & HELP_TRAVEL) && strcmp(s, "travel") == 0) - return HELP_TRAVEL; - return 0; + if ((help_mask & HELP_MONEY) && strcmp(s, "money") == 0) + return HELP_MONEY; + if ((help_mask & HELP_FIGHT) && strcmp(s, "fight") == 0) + return HELP_FIGHT; + if ((help_mask & HELP_GIVE) && strcmp(s, "give") == 0) + return HELP_GIVE; + if ((help_mask & HELP_GUARD) && strcmp(s, "guard") == 0) + return HELP_GUARD; + if ((help_mask & HELP_FSTEALTH) && strcmp(s, "stealth") == 0) + return HELP_FSTEALTH; + if ((help_mask & HELP_TRAVEL) && strcmp(s, "travel") == 0) + return HELP_TRAVEL; + return 0; } bool ExpensiveMigrants(void) { - static int value = -1; - static int gamecookie = -1; - if (value < 0 || gamecookie != global.cookie) { - gamecookie = global.cookie; - value = get_param_int(global.parameters, "study.expensivemigrants", 0); - } - return value; + static int value = -1; + static int gamecookie = -1; + if (value < 0 || gamecookie != global.cookie) { + gamecookie = global.cookie; + value = get_param_int(global.parameters, "study.expensivemigrants", 0); + } + return value; } /** Specifies automatic alliance modes. @@ -167,23 +167,23 @@ bool ExpensiveMigrants(void) */ int AllianceAuto(void) { - static int value = -1; - static int gamecookie = -1; - if (value < 0 || gamecookie != global.cookie) { - const char *str = get_param(global.parameters, "alliance.auto"); - gamecookie = global.cookie; - value = 0; - if (str != NULL) { - char *sstr = _strdup(str); - char *tok = strtok(sstr, " "); - while (tok) { - value |= ally_flag(tok, -1); - tok = strtok(NULL, " "); - } - free(sstr); + static int value = -1; + static int gamecookie = -1; + if (value < 0 || gamecookie != global.cookie) { + const char *str = get_param(global.parameters, "alliance.auto"); + gamecookie = global.cookie; + value = 0; + if (str != NULL) { + char *sstr = _strdup(str); + char *tok = strtok(sstr, " "); + while (tok) { + value |= ally_flag(tok, -1); + tok = strtok(NULL, " "); + } + free(sstr); + } } - } - return value & HelpMask(); + return value & HelpMask(); } /** Limits the available help modes @@ -194,263 +194,264 @@ int AllianceAuto(void) */ int HelpMask(void) { - static int rule = -1; - static int gamecookie = -1; - if (rule < 0 || gamecookie != global.cookie) { - const char *str = get_param(global.parameters, "rules.help.mask"); - gamecookie = global.cookie; - rule = 0; - if (str != NULL) { - char *sstr = _strdup(str); - char *tok = strtok(sstr, " "); - while (tok) { - rule |= ally_flag(tok, -1); - tok = strtok(NULL, " "); - } - free(sstr); - } else { - rule = HELP_ALL; + static int rule = -1; + static int gamecookie = -1; + if (rule < 0 || gamecookie != global.cookie) { + const char *str = get_param(global.parameters, "rules.help.mask"); + gamecookie = global.cookie; + rule = 0; + if (str != NULL) { + char *sstr = _strdup(str); + char *tok = strtok(sstr, " "); + while (tok) { + rule |= ally_flag(tok, -1); + tok = strtok(NULL, " "); + } + free(sstr); + } + else { + rule = HELP_ALL; + } } - } - return rule; + return rule; } int AllianceRestricted(void) { - static int rule = -1; - static int gamecookie = -1; - if (rule < 0 || gamecookie != global.cookie) { - const char *str = get_param(global.parameters, "alliance.restricted"); - gamecookie = global.cookie; - rule = 0; - if (str != NULL) { - char *sstr = _strdup(str); - char *tok = strtok(sstr, " "); - while (tok) { - rule |= ally_flag(tok, -1); - tok = strtok(NULL, " "); - } - free(sstr); + static int rule = -1; + static int gamecookie = -1; + if (rule < 0 || gamecookie != global.cookie) { + const char *str = get_param(global.parameters, "alliance.restricted"); + gamecookie = global.cookie; + rule = 0; + if (str != NULL) { + char *sstr = _strdup(str); + char *tok = strtok(sstr, " "); + while (tok) { + rule |= ally_flag(tok, -1); + tok = strtok(NULL, " "); + } + free(sstr); + } + rule &= HelpMask(); } - rule &= HelpMask(); - } - return rule; + return rule; } int LongHunger(const struct unit *u) { - static int gamecookie = -1; - static int rule = -1; - if (u != NULL) { - if (!fval(u, UFL_HUNGER)) - return false; + static int gamecookie = -1; + static int rule = -1; + if (u != NULL) { + if (!fval(u, UFL_HUNGER)) + return false; #ifdef NEW_DAEMONHUNGER_RULE - if (u_race(u) == get_race(RC_DAEMON)) - return false; + if (u_race(u) == get_race(RC_DAEMON)) + return false; #endif - } - if (rule < 0 || gamecookie != global.cookie) { - gamecookie = global.cookie; - rule = get_param_int(global.parameters, "hunger.long", 0); - } - return rule; + } + if (rule < 0 || gamecookie != global.cookie) { + gamecookie = global.cookie; + rule = get_param_int(global.parameters, "hunger.long", 0); + } + return rule; } int SkillCap(skill_t sk) { - static int gamecookie = -1; - static int rule = -1; - if (sk == SK_MAGIC) - return 0; /* no caps on magic */ - if (rule < 0 || gamecookie != global.cookie) { - gamecookie = global.cookie; - rule = get_param_int(global.parameters, "skill.maxlevel", 0); - } - return rule; + static int gamecookie = -1; + static int rule = -1; + if (sk == SK_MAGIC) + return 0; /* no caps on magic */ + if (rule < 0 || gamecookie != global.cookie) { + gamecookie = global.cookie; + rule = get_param_int(global.parameters, "skill.maxlevel", 0); + } + return rule; } int NMRTimeout(void) { - static int gamecookie = -1; - static int rule = -1; - if (rule < 0 || gamecookie != global.cookie) { - gamecookie = global.cookie; - rule = get_param_int(global.parameters, "nmr.timeout", 0); - } - return rule; + static int gamecookie = -1; + static int rule = -1; + if (rule < 0 || gamecookie != global.cookie) { + gamecookie = global.cookie; + rule = get_param_int(global.parameters, "nmr.timeout", 0); + } + return rule; } race_t old_race(const struct race * rc) { - race_t i; - for (i = 0; i != MAXRACES; ++i) { - if (get_race(i) == rc) return i; - } - return NORACE; + race_t i; + for (i = 0; i != MAXRACES; ++i) { + if (get_race(i) == rc) return i; + } + return NORACE; } helpmode helpmodes[] = { - {"all", HELP_ALL} - , - {"money", HELP_MONEY} - , - {"fight", HELP_FIGHT} - , - {"observe", HELP_OBSERVE} - , - {"give", HELP_GIVE} - , - {"guard", HELP_GUARD} - , - {"stealth", HELP_FSTEALTH} - , - {"travel", HELP_TRAVEL} - , - {NULL, 0} + { "all", HELP_ALL } + , + { "money", HELP_MONEY } + , + { "fight", HELP_FIGHT } + , + { "observe", HELP_OBSERVE } + , + { "give", HELP_GIVE } + , + { "guard", HELP_GUARD } + , + { "stealth", HELP_FSTEALTH } + , + { "travel", HELP_TRAVEL } + , + { NULL, 0 } }; /** Returns the English name of the race, which is what the database uses. */ const char *dbrace(const struct race *rc) { - static char zText[32]; - char *zPtr = zText; + static char zText[32]; + char *zPtr = zText; - /* the english names are all in ASCII, so we don't need to worry about UTF8 */ - strcpy(zText, (const char *)LOC(get_locale("en"), rc_name(rc, 0))); - while (*zPtr) { - *zPtr = (char)(toupper(*zPtr)); - ++zPtr; - } - return zText; + /* the english names are all in ASCII, so we don't need to worry about UTF8 */ + strcpy(zText, (const char *)LOC(get_locale("en"), rc_name(rc, 0))); + while (*zPtr) { + *zPtr = (char)(toupper(*zPtr)); + ++zPtr; + } + return zText; } const char *parameters[MAXPARAMS] = { - "LOCALE", - "ALLES", - "JEDEM", - "BAUERN", - "BURG", - "EINHEIT", - "PRIVAT", - "HINTEN", - "KOMMANDO", - "KRAEUTER", - "NICHT", - "NAECHSTER", - "PARTEI", - "ERESSEA", - "PERSONEN", - "REGION", - "SCHIFF", - "SILBER", - "STRASSEN", - "TEMPORAERE", - "FLIEHE", - "GEBAEUDE", - "GIB", /* Für HELFE */ - "KAEMPFE", - "DURCHREISE", - "BEWACHE", - "ZAUBER", - "PAUSE", - "VORNE", - "AGGRESSIV", - "DEFENSIV", - "STUFE", - "HELFE", - "FREMDES", - "AURA", - "HINTER", - "VOR", - "ANZAHL", - "GEGENSTAENDE", - "TRAENKE", - "GRUPPE", - "PARTEITARNUNG", - "BAEUME", - "ALLIANZ" + "LOCALE", + "ALLES", + "JEDEM", + "BAUERN", + "BURG", + "EINHEIT", + "PRIVAT", + "HINTEN", + "KOMMANDO", + "KRAEUTER", + "NICHT", + "NAECHSTER", + "PARTEI", + "ERESSEA", + "PERSONEN", + "REGION", + "SCHIFF", + "SILBER", + "STRASSEN", + "TEMPORAERE", + "FLIEHE", + "GEBAEUDE", + "GIB", /* Für HELFE */ + "KAEMPFE", + "DURCHREISE", + "BEWACHE", + "ZAUBER", + "PAUSE", + "VORNE", + "AGGRESSIV", + "DEFENSIV", + "STUFE", + "HELFE", + "FREMDES", + "AURA", + "HINTER", + "VOR", + "ANZAHL", + "GEGENSTAENDE", + "TRAENKE", + "GRUPPE", + "PARTEITARNUNG", + "BAEUME", + "ALLIANZ" }; const char *report_options[MAX_MSG] = { - "Kampf", - "Ereignisse", - "Bewegung", - "Einkommen", - "Handel", - "Produktion", - "Orkvermehrung", - "Zauber", - "", - "" + "Kampf", + "Ereignisse", + "Bewegung", + "Einkommen", + "Handel", + "Produktion", + "Orkvermehrung", + "Zauber", + "", + "" }; const char *message_levels[ML_MAX] = { - "Wichtig", - "Debug", - "Fehler", - "Warnungen", - "Infos" + "Wichtig", + "Debug", + "Fehler", + "Warnungen", + "Infos" }; const char *options[MAXOPTIONS] = { - "AUSWERTUNG", - "COMPUTER", - "ZUGVORLAGE", - NULL, - "STATISTIK", - "DEBUG", - "ZIPPED", - "ZEITUNG", /* Option hat Sonderbehandlung! */ - NULL, - "ADRESSEN", - "BZIP2", - "PUNKTE", - "SHOWSKCHANGE" + "AUSWERTUNG", + "COMPUTER", + "ZUGVORLAGE", + NULL, + "STATISTIK", + "DEBUG", + "ZIPPED", + "ZEITUNG", /* Option hat Sonderbehandlung! */ + NULL, + "ADRESSEN", + "BZIP2", + "PUNKTE", + "SHOWSKCHANGE" }; static void init_maxmagicians(struct attrib *a) { - a->data.i = MAXMAGICIANS; + a->data.i = MAXMAGICIANS; } static attrib_type at_maxmagicians = { - "maxmagicians", - init_maxmagicians, - NULL, - NULL, - a_writeint, - a_readint, - ATF_UNIQUE + "maxmagicians", + init_maxmagicians, + NULL, + NULL, + a_writeint, + a_readint, + ATF_UNIQUE }; int max_magicians(const faction * f) { - int m = - get_param_int(global.parameters, "rules.maxskills.magic", MAXMAGICIANS); - attrib *a; + int m = + get_param_int(global.parameters, "rules.maxskills.magic", MAXMAGICIANS); + attrib *a; - if ((a = a_find(f->attribs, &at_maxmagicians)) != NULL) { - m = a->data.i; - } - if (f->race == get_race(RC_ELF)) - ++m; - return m; + if ((a = a_find(f->attribs, &at_maxmagicians)) != NULL) { + m = a->data.i; + } + if (f->race == get_race(RC_ELF)) + ++m; + return m; } static void init_npcfaction(struct attrib *a) { - a->data.i = 1; + a->data.i = 1; } static attrib_type at_npcfaction = { - "npcfaction", - init_npcfaction, - NULL, - NULL, - a_writeint, - a_readint, - ATF_UNIQUE + "npcfaction", + init_npcfaction, + NULL, + NULL, + a_writeint, + a_readint, + ATF_UNIQUE }; int verbosity = 1; @@ -459,77 +460,77 @@ FILE *debug; static int ShipSpeedBonus(const unit * u) { - static int level = -1; - if (level == -1) { - level = - get_param_int(global.parameters, "movement.shipspeed.skillbonus", 0); - } - if (level > 0) { - ship *sh = u->ship; - int skl = effskill(u, SK_SAILING); - int minsk = (sh->type->cptskill + 1) / 2; - return (skl - minsk) / level; - } - return 0; + static int level = -1; + if (level == -1) { + level = + get_param_int(global.parameters, "movement.shipspeed.skillbonus", 0); + } + if (level > 0) { + ship *sh = u->ship; + int skl = effskill(u, SK_SAILING); + int minsk = (sh->type->cptskill + 1) / 2; + return (skl - minsk) / level; + } + return 0; } int shipspeed(const ship * sh, const unit * u) { - double k = sh->type->range; - static const curse_type *stormwind_ct, *nodrift_ct; - static bool init; - attrib *a; - curse *c; + double k = sh->type->range; + static const curse_type *stormwind_ct, *nodrift_ct; + static bool init; + attrib *a; + curse *c; - if (!init) { - init = true; - stormwind_ct = ct_find("stormwind"); - nodrift_ct = ct_find("nodrift"); - } - - assert(u->ship == sh); - assert(sh->type->construction->improvement == NULL); /* sonst ist construction::size nicht ship_type::maxsize */ - if (sh->size != sh->type->construction->maxsize) - return 0; - - if (curse_active(get_curse(sh->attribs, stormwind_ct))) - k *= 2; - if (curse_active(get_curse(sh->attribs, nodrift_ct))) - k += 1; - - if (u->faction->race == u_race(u)) { - /* race bonus for this faction? */ - if (fval(u_race(u), RCF_SHIPSPEED)) { - k += 1; + if (!init) { + init = true; + stormwind_ct = ct_find("stormwind"); + nodrift_ct = ct_find("nodrift"); } - } - k += ShipSpeedBonus(u); + assert(u->ship == sh); + assert(sh->type->construction->improvement == NULL); /* sonst ist construction::size nicht ship_type::maxsize */ + if (sh->size != sh->type->construction->maxsize) + return 0; - a = a_find(sh->attribs, &at_speedup); - while (a != NULL && a->type == &at_speedup) { - k += a->data.sa[0]; - a = a->next; - } + if (curse_active(get_curse(sh->attribs, stormwind_ct))) + k *= 2; + if (curse_active(get_curse(sh->attribs, nodrift_ct))) + k += 1; - c = get_curse(sh->attribs, ct_find("shipspeedup")); - while (c) { - k += curse_geteffect(c); - c = c->nexthash; - } + if (u->faction->race == u_race(u)) { + /* race bonus for this faction? */ + if (fval(u_race(u), RCF_SHIPSPEED)) { + k += 1; + } + } + + k += ShipSpeedBonus(u); + + a = a_find(sh->attribs, &at_speedup); + while (a != NULL && a->type == &at_speedup) { + k += a->data.sa[0]; + a = a->next; + } + + c = get_curse(sh->attribs, ct_find("shipspeedup")); + while (c) { + k += curse_geteffect(c); + c = c->nexthash; + } #ifdef SHIPSPEED - k *= SHIPSPEED; + k *= SHIPSPEED; #endif #ifdef SHIPDAMAGE - if (sh->damage) - k = - (k * (sh->size * DAMAGE_SCALE - sh->damage) + sh->size * DAMAGE_SCALE - - 1) / (sh->size * DAMAGE_SCALE); + if (sh->damage) + k = + (k * (sh->size * DAMAGE_SCALE - sh->damage) + sh->size * DAMAGE_SCALE - + 1) / (sh->size * DAMAGE_SCALE); #endif - return (int)k; + return (int)k; } #define FMAXHASH 2039 @@ -537,27 +538,27 @@ faction *factionhash[FMAXHASH]; void fhash(faction * f) { - int index = f->no % FMAXHASH; - f->nexthash = factionhash[index]; - factionhash[index] = f; + int index = f->no % FMAXHASH; + f->nexthash = factionhash[index]; + factionhash[index] = f; } void funhash(faction * f) { - int index = f->no % FMAXHASH; - faction **fp = factionhash + index; - while (*fp && (*fp) != f) - fp = &(*fp)->nexthash; - *fp = f->nexthash; + int index = f->no % FMAXHASH; + faction **fp = factionhash + index; + while (*fp && (*fp) != f) + fp = &(*fp)->nexthash; + *fp = f->nexthash; } static faction *ffindhash(int no) { - int index = no % FMAXHASH; - faction *f = factionhash[index]; - while (f && f->no != no) - f = f->nexthash; - return f; + int index = no % FMAXHASH; + faction *f = factionhash[index]; + while (f && f->no != no) + f = f->nexthash; + return f; } /* ----------------------------------------------------------------------- */ @@ -565,421 +566,426 @@ static faction *ffindhash(int no) void verify_data(void) { #ifndef NDEBUG - int lf = -1; - faction *f; - unit *u; - int mage, alchemist; + int lf = -1; + faction *f; + unit *u; + int mage, alchemist; - if (verbosity >= 1) - puts(" - Überprüfe Daten auf Korrektheit..."); + if (verbosity >= 1) + puts(" - Überprüfe Daten auf Korrektheit..."); - for (f = factions; f; f = f->next) { - mage = 0; - alchemist = 0; - for (u = f->units; u; u = u->nextF) { - if (eff_skill(u, SK_MAGIC, u->region)) { - mage += u->number; - } - if (eff_skill(u, SK_ALCHEMY, u->region)) - alchemist += u->number; - if (u->number > UNIT_MAXSIZE) { - if (lf != f->no) { - lf = f->no; - log_printf(stdout, "Partei %s:\n", factionid(f)); + for (f = factions; f; f = f->next) { + mage = 0; + alchemist = 0; + for (u = f->units; u; u = u->nextF) { + if (eff_skill(u, SK_MAGIC, u->region)) { + mage += u->number; + } + if (eff_skill(u, SK_ALCHEMY, u->region)) + alchemist += u->number; + if (u->number > UNIT_MAXSIZE) { + if (lf != f->no) { + lf = f->no; + log_printf(stdout, "Partei %s:\n", factionid(f)); + } + log_warning("Einheit %s hat %d Personen\n", unitid(u), u->number); + } } - log_warning("Einheit %s hat %d Personen\n", unitid(u), u->number); - } + if (f->no != 0 && ((mage > 3 && f->race != get_race(RC_ELF)) || mage > 4)) + log_error("Partei %s hat %d Magier.\n", factionid(f), mage); + if (alchemist > 3) + log_error("Partei %s hat %d Alchemisten.\n", factionid(f), alchemist); } - if (f->no != 0 && ((mage > 3 && f->race != get_race(RC_ELF)) || mage > 4)) - log_error("Partei %s hat %d Magier.\n", factionid(f), mage); - if (alchemist > 3) - log_error("Partei %s hat %d Alchemisten.\n", factionid(f), alchemist); - } #endif } int distribute(int old, int new_value, int n) { - int i; - int t; - assert(new_value <= old); + int i; + int t; + assert(new_value <= old); - if (old == 0) - return 0; + if (old == 0) + return 0; - t = (n / old) * new_value; - for (i = (n % old); i; i--) - if (rng_int() % old < new_value) - t++; + t = (n / old) * new_value; + for (i = (n % old); i; i--) + if (rng_int() % old < new_value) + t++; - return t; + return t; } int change_hitpoints(unit * u, int value) { - int hp = u->hp; + int hp = u->hp; - hp += value; + hp += value; - /* Jede Person benötigt mindestens 1 HP */ - if (hp < u->number) { - if (hp < 0) { /* Einheit tot */ - hp = 0; + /* Jede Person benötigt mindestens 1 HP */ + if (hp < u->number) { + if (hp < 0) { /* Einheit tot */ + hp = 0; + } + scale_number(u, hp); } - scale_number(u, hp); - } - u->hp = hp; - return hp; + u->hp = hp; + return hp; } unsigned int atoip(const char *s) { - int n; + int n; - n = atoi(s); + n = atoi(s); - if (n < 0) - n = 0; + if (n < 0) + n = 0; - return n; + return n; } region *findunitregion(const unit * su) { #ifndef SLOW_REGION - return su->region; + return su->region; #else - region *r; - const unit *u; + region *r; + const unit *u; - for (r = regions; r; r = r->next) { - for (u = r->units; u; u = u->next) { - if (su == u) { - return r; - } + for (r = regions; r; r = r->next) { + for (u = r->units; u; u = u->next) { + if (su == u) { + return r; + } + } } - } - /* This should never happen */ - assert(!"Die unit wurde nicht gefunden"); + /* This should never happen */ + assert(!"Die unit wurde nicht gefunden"); - return (region *) NULL; + return (region *) NULL; #endif } int eff_stealth(const unit * u, const region * r) { - int e = 0; + int e = 0; - /* Auf Schiffen keine Tarnung! */ - if (!u->ship && skill_enabled(SK_STEALTH)) { - e = eff_skill(u, SK_STEALTH, r); + /* Auf Schiffen keine Tarnung! */ + if (!u->ship && skill_enabled(SK_STEALTH)) { + e = eff_skill(u, SK_STEALTH, r); - if (fval(u, UFL_STEALTH)) { - int es = u_geteffstealth(u); - if (es >= 0 && es < e) - return es; + if (fval(u, UFL_STEALTH)) { + int es = u_geteffstealth(u); + if (es >= 0 && es < e) + return es; + } } - } - return e; + return e; } bool unit_has_cursed_item(unit * u) { - item *itm = u->items; - while (itm) { - if (fval(itm->type, ITF_CURSED) && itm->number > 0) - return true; - itm = itm->next; - } - return false; + item *itm = u->items; + while (itm) { + if (fval(itm->type, ITF_CURSED) && itm->number > 0) + return true; + itm = itm->next; + } + return false; } static void init_gms(void) { - faction *f; + faction *f; - for (f = factions; f; f = f->next) { - const attrib *a = a_findc(f->attribs, &at_gm); + for (f = factions; f; f = f->next) { + const attrib *a = a_findc(f->attribs, &at_gm); - if (a != NULL) - fset(f, FFL_GM); - } + if (a != NULL) + fset(f, FFL_GM); + } } static int autoalliance(const plane * pl, const faction * sf, const faction * f2) { - static bool init = false; - if (!init) { - init_gms(); - init = true; - } - if (pl && (pl->flags & PFL_FRIENDLY)) - return HELP_ALL; - /* if f2 is a gm in this plane, everyone has an auto-help to it */ - if (fval(f2, FFL_GM)) { - attrib *a = a_find(f2->attribs, &at_gm); - - while (a) { - const plane *p = (const plane *)a->data.v; - if (p == pl) - return HELP_ALL; - a = a->next; + static bool init = false; + if (!init) { + init_gms(); + init = true; } - } + if (pl && (pl->flags & PFL_FRIENDLY)) + return HELP_ALL; + /* if f2 is a gm in this plane, everyone has an auto-help to it */ + if (fval(f2, FFL_GM)) { + attrib *a = a_find(f2->attribs, &at_gm); - if (f_get_alliance(sf) != NULL && AllianceAuto()) { - if (sf->alliance == f2->alliance) - return AllianceAuto(); - } + while (a) { + const plane *p = (const plane *)a->data.v; + if (p == pl) + return HELP_ALL; + a = a->next; + } + } - return 0; + if (f_get_alliance(sf) != NULL && AllianceAuto()) { + if (sf->alliance == f2->alliance) + return AllianceAuto(); + } + + return 0; } static int ally_mode(const ally * sf, int mode) { - if (sf == NULL) - return 0; - return sf->status & mode; + if (sf == NULL) + return 0; + return sf->status & mode; } int alliedgroup(const struct plane *pl, const struct faction *f, - const struct faction *f2, const struct ally *sf, int mode) +const struct faction *f2, const struct ally *sf, int mode) { - while (sf && sf->faction != f2) - sf = sf->next; - if (sf == NULL) { - mode = mode & autoalliance(pl, f, f2); - } - mode = ally_mode(sf, mode) | (mode & autoalliance(pl, f, f2)); - if (AllianceRestricted()) { - if (a_findc(f->attribs, &at_npcfaction)) { - return mode; + while (sf && sf->faction != f2) + sf = sf->next; + if (sf == NULL) { + mode = mode & autoalliance(pl, f, f2); } - if (a_findc(f2->attribs, &at_npcfaction)) { - return mode; + mode = ally_mode(sf, mode) | (mode & autoalliance(pl, f, f2)); + if (AllianceRestricted()) { + if (a_findc(f->attribs, &at_npcfaction)) { + return mode; + } + if (a_findc(f2->attribs, &at_npcfaction)) { + return mode; + } + if (f->alliance != f2->alliance) { + mode &= ~AllianceRestricted(); + } } - if (f->alliance != f2->alliance) { - mode &= ~AllianceRestricted(); - } - } - return mode; + return mode; } int alliedfaction(const struct plane *pl, const struct faction *f, - const struct faction *f2, int mode) +const struct faction *f2, int mode) { - return alliedgroup(pl, f, f2, f->allies, mode); + return alliedgroup(pl, f, f2, f->allies, mode); } /* Die Gruppe von Einheit u hat helfe zu f2 gesetzt. */ int alliedunit(const unit * u, const faction * f2, int mode) { - ally *sf; - int automode; + ally *sf; + int automode; - assert(u->region); /* the unit should be in a region, but it's possible that u->number==0 (TEMP units) */ - if (u->faction == f2) - return mode; - if (u->faction != NULL && f2 != NULL) { - plane *pl; + assert(u->region); /* the unit should be in a region, but it's possible that u->number==0 (TEMP units) */ + if (u->faction == f2) + return mode; + if (u->faction != NULL && f2 != NULL) { + plane *pl; - if (mode & HELP_FIGHT) { - if ((u->flags & UFL_DEFENDER) || (u->faction->flags & FFL_DEFENDER)) { - faction *owner = region_get_owner(u->region); - /* helps the owner of the region */ - if (owner == f2) { - return HELP_FIGHT; + if (mode & HELP_FIGHT) { + if ((u->flags & UFL_DEFENDER) || (u->faction->flags & FFL_DEFENDER)) { + faction *owner = region_get_owner(u->region); + /* helps the owner of the region */ + if (owner == f2) { + return HELP_FIGHT; + } + } } - } + + pl = rplane(u->region); + automode = mode & autoalliance(pl, u->faction, f2); + + if (pl != NULL && (pl->flags & PFL_NOALLIANCES)) + mode = (mode & automode) | (mode & HELP_GIVE); + + sf = u->faction->allies; + if (fval(u, UFL_GROUP)) { + const attrib *a = a_findc(u->attribs, &at_group); + if (a != NULL) + sf = ((group *)a->data.v)->allies; + } + return alliedgroup(pl, u->faction, f2, sf, mode); } - - pl = rplane(u->region); - automode = mode & autoalliance(pl, u->faction, f2); - - if (pl != NULL && (pl->flags & PFL_NOALLIANCES)) - mode = (mode & automode) | (mode & HELP_GIVE); - - sf = u->faction->allies; - if (fval(u, UFL_GROUP)) { - const attrib *a = a_findc(u->attribs, &at_group); - if (a != NULL) - sf = ((group *) a->data.v)->allies; - } - return alliedgroup(pl, u->faction, f2, sf, mode); - } - return 0; + return 0; } bool seefaction(const faction * f, const region * r, const unit * u, int modifier) { - if (((f == u->faction) || !fval(u, UFL_ANON_FACTION)) - && cansee(f, r, u, modifier)) - return true; - return false; + if (((f == u->faction) || !fval(u, UFL_ANON_FACTION)) + && cansee(f, r, u, modifier)) + return true; + return false; } bool cansee(const faction * f, const region * r, const unit * u, int modifier) - /* r kann != u->region sein, wenn es um durchreisen geht */ - /* und es muss niemand aus f in der region sein, wenn sie vom Turm - * erblickt wird */ +/* r kann != u->region sein, wenn es um durchreisen geht */ +/* und es muss niemand aus f in der region sein, wenn sie vom Turm + * erblickt wird */ { int stealth, rings; unit *u2 = r->units; - if (u->faction == f || omniscient(f)) { - return true; - } else if (fval(u_race(u), RCF_INVISIBLE)) { - return false; - } else if (u->number == 0) { - attrib *a = a_find(u->attribs, &at_creator); - if (a) { /* u is an empty temporary unit. In this special case - we look at the creating unit. */ - u = (unit *) a->data.v; - } else { - return false; - } - } - - if (leftship(u)) - return true; - - while (u2 && u2->faction != f) - u2 = u2->next; - if (u2 == NULL) - return false; - - /* simple visibility, just gotta have a unit in the region to see 'em */ - if (is_guard(u, GUARD_ALL) != 0 || usiege(u) || u->building || u->ship) { - return true; - } - - rings = invisible(u, NULL); - stealth = eff_stealth(u, r) - modifier; - - while (u2) { - if (rings < u->number || invisible(u, u2) < u->number) { - if (skill_enabled(SK_PERCEPTION)) { - int observation = eff_skill(u2, SK_PERCEPTION, r); - - if (observation >= stealth) { - return true; - } - } else { + if (u->faction == f || omniscient(f)) { return true; - } + } + else if (fval(u_race(u), RCF_INVISIBLE)) { + return false; + } + else if (u->number == 0) { + attrib *a = a_find(u->attribs, &at_creator); + if (a) { /* u is an empty temporary unit. In this special case + we look at the creating unit. */ + u = (unit *)a->data.v; + } + else { + return false; + } } - /* find next unit in our faction */ - do { - u2 = u2->next; - } while (u2 && u2->faction != f); - } - return false; + if (leftship(u)) + return true; + + while (u2 && u2->faction != f) + u2 = u2->next; + if (u2 == NULL) + return false; + + /* simple visibility, just gotta have a unit in the region to see 'em */ + if (is_guard(u, GUARD_ALL) != 0 || usiege(u) || u->building || u->ship) { + return true; + } + + rings = invisible(u, NULL); + stealth = eff_stealth(u, r) - modifier; + + while (u2) { + if (rings < u->number || invisible(u, u2) < u->number) { + if (skill_enabled(SK_PERCEPTION)) { + int observation = eff_skill(u2, SK_PERCEPTION, r); + + if (observation >= stealth) { + return true; + } + } + else { + return true; + } + } + + /* find next unit in our faction */ + do { + u2 = u2->next; + } while (u2 && u2->faction != f); + } + return false; } bool cansee_unit(const unit * u, const unit * target, int modifier) /* target->region kann != u->region sein, wenn es um durchreisen geht */ { - if (fval(u_race(target), RCF_INVISIBLE) || target->number == 0) - return false; - else if (target->faction == u->faction) - return true; - else { - int n, rings, o; - - if (is_guard(target, GUARD_ALL) != 0 || usiege(target) || target->building - || target->ship) { - return true; - } - - n = eff_stealth(target, target->region) - modifier; - rings = invisible(target, NULL); - if (rings == 0 && n <= 0) { - return true; - } - - if (rings && invisible(target, u) >= target->number) { - return false; - } - if (skill_enabled(SK_PERCEPTION)) { - o = eff_skill(u, SK_PERCEPTION, target->region); - if (o >= n) { + if (fval(u_race(target), RCF_INVISIBLE) || target->number == 0) + return false; + else if (target->faction == u->faction) return true; - } - } else { - return true; + else { + int n, rings, o; + + if (is_guard(target, GUARD_ALL) != 0 || usiege(target) || target->building + || target->ship) { + return true; + } + + n = eff_stealth(target, target->region) - modifier; + rings = invisible(target, NULL); + if (rings == 0 && n <= 0) { + return true; + } + + if (rings && invisible(target, u) >= target->number) { + return false; + } + if (skill_enabled(SK_PERCEPTION)) { + o = eff_skill(u, SK_PERCEPTION, target->region); + if (o >= n) { + return true; + } + } + else { + return true; + } } - } - return false; + return false; } bool cansee_durchgezogen(const faction * f, const region * r, const unit * u, - int modifier) +int modifier) /* r kann != u->region sein, wenn es um durchreisen geht */ /* und es muss niemand aus f in der region sein, wenn sie vom Turm * erblickt wird */ { - int n; - unit *u2; + int n; + unit *u2; - if (fval(u_race(u), RCF_INVISIBLE) || u->number == 0) - return false; - else if (u->faction == f) - return true; - else { - int rings; + if (fval(u_race(u), RCF_INVISIBLE) || u->number == 0) + return false; + else if (u->faction == f) + return true; + else { + int rings; - if (is_guard(u, GUARD_ALL) != 0 || usiege(u) || u->building || u->ship) { - return true; - } - - n = eff_stealth(u, r) - modifier; - rings = invisible(u, NULL); - if (rings == 0 && n <= 0) { - return true; - } - - for (u2 = r->units; u2; u2 = u2->next) { - if (u2->faction == f) { - int o; - - if (rings && invisible(u, u2) >= u->number) - continue; - - o = eff_skill(u2, SK_PERCEPTION, r); - - if (o >= n) { - return true; + if (is_guard(u, GUARD_ALL) != 0 || usiege(u) || u->building || u->ship) { + return true; + } + + n = eff_stealth(u, r) - modifier; + rings = invisible(u, NULL); + if (rings == 0 && n <= 0) { + return true; + } + + for (u2 = r->units; u2; u2 = u2->next) { + if (u2->faction == f) { + int o; + + if (rings && invisible(u, u2) >= u->number) + continue; + + o = eff_skill(u2, SK_PERCEPTION, r); + + if (o >= n) { + return true; + } + } } - } } - } - return false; + return false; } #ifndef NDEBUG const char *strcheck(const char *s, size_t maxlen) { - static char buffer[16 * 1024]; - if (strlen(s) > maxlen) { - assert(maxlen < 16 * 1024); - log_warning("[strcheck] String wurde auf %d Zeichen verkürzt:\n%s\n", (int)maxlen, s); - strlcpy(buffer, s, maxlen); - return buffer; - } - return s; + static char buffer[16 * 1024]; + if (strlen(s) > maxlen) { + assert(maxlen < 16 * 1024); + log_warning("[strcheck] String wurde auf %d Zeichen verkürzt:\n%s\n", (int)maxlen, s); + strlcpy(buffer, s, maxlen); + return buffer; + } + return s; } #endif static attrib_type at_lighthouse = { - "lighthouse" + "lighthouse" /* Rest ist NULL; temporäres, nicht alterndes Attribut */ }; @@ -999,7 +1005,7 @@ void update_lighthouse(building * lh) if (lh->size > 0) { r->flags |= RF_LIGHTHOUSE; } - + for (x = -d; x <= d; ++x) { int y; for (y = -d; y <= d; ++y) { @@ -1014,7 +1020,7 @@ void update_lighthouse(building * lh) continue; a = a_find(r2->attribs, &at_lighthouse); while (a && a->type == &at_lighthouse) { - building *b = (building *) a->data.v; + building *b = (building *)a->data.v; if (b == lh) break; a = a->next; @@ -1035,18 +1041,20 @@ int count_faction(const faction * f, int flags) for (u = f->units; u; u = u->nextF) { const race *rc = u_race(u); int x = (flags&COUNT_UNITS) ? 1 : u->number; - if (f->race!=rc) { + if (f->race != rc) { if (!playerrace(rc)) { if (flags&COUNT_MONSTERS) { - n+=x; - } - } else if (flags&COUNT_MIGRANTS) { - if (!is_cursed(u->attribs, C_SLAVE, 0)) { - n+=x; + n += x; } } - } else if (flags&COUNT_DEFAULT) { - n+=x; + else if (flags&COUNT_MIGRANTS) { + if (!is_cursed(u->attribs, C_SLAVE, 0)) { + n += x; + } + } + } + else if (flags&COUNT_DEFAULT) { + n += x; } } return n; @@ -1054,7 +1062,7 @@ int count_faction(const faction * f, int flags) int count_units(const faction * f) { - return count_faction(f, COUNT_ALL|COUNT_UNITS); + return count_faction(f, COUNT_ALL | COUNT_UNITS); } int count_all(const faction * f) { @@ -1067,105 +1075,105 @@ int count_migrants(const faction * f) int count_maxmigrants(const faction * f) { - static int migrants = -1; + static int migrants = -1; - if (migrants < 0) { - migrants = get_param_int(global.parameters, "rules.migrants", INT_MAX); - } - if (migrants == INT_MAX) { - int x = 0; - if (f->race == get_race(RC_HUMAN)) { - int nsize = count_all(f); - if (nsize > 0) { - x = (int)(log10(nsize / 50.0) * 20); - if (x < 0) - x = 0; - } + if (migrants < 0) { + migrants = get_param_int(global.parameters, "rules.migrants", INT_MAX); } - return x; - } - return migrants; + if (migrants == INT_MAX) { + int x = 0; + if (f->race == get_race(RC_HUMAN)) { + int nsize = count_all(f); + if (nsize > 0) { + x = (int)(log10(nsize / 50.0) * 20); + if (x < 0) + x = 0; + } + } + return x; + } + return migrants; } void -parse(keyword_t kword, int (*dofun) (unit *, struct order *), bool thisorder) +parse(keyword_t kword, int(*dofun) (unit *, struct order *), bool thisorder) { - region *r; + region *r; - for (r = regions; r; r = r->next) { - unit **up = &r->units; - while (*up) { - unit *u = *up; - order **ordp = &u->orders; - if (thisorder) - ordp = &u->thisorder; - while (*ordp) { - order *ord = *ordp; - if (getkeyword(ord) == kword) { - if (dofun(u, ord) != 0) - break; - if (u->orders == NULL) - break; + for (r = regions; r; r = r->next) { + unit **up = &r->units; + while (*up) { + unit *u = *up; + order **ordp = &u->orders; + if (thisorder) + ordp = &u->thisorder; + while (*ordp) { + order *ord = *ordp; + if (getkeyword(ord) == kword) { + if (dofun(u, ord) != 0) + break; + if (u->orders == NULL) + break; + } + if (thisorder) + break; + if (*ordp == ord) + ordp = &ord->next; + } + if (*up == u) + up = &u->next; } - if (thisorder) - break; - if (*ordp == ord) - ordp = &ord->next; - } - if (*up == u) - up = &u->next; } - } } const char *igetstrtoken(const char *initstr) { - if (initstr != NULL) { - init_tokens_str(initstr, NULL); - } + if (initstr != NULL) { + init_tokens_str(initstr, NULL); + } - return getstrtoken(); + return getstrtoken(); } unsigned int getuint(void) { - return atoip((const char *)getstrtoken()); + return atoip((const char *)getstrtoken()); } int getint(void) { - return atoi((const char *)getstrtoken()); + return atoi((const char *)getstrtoken()); } const struct race *findrace(const char *s, const struct locale *lang) { - void **tokens = get_translations(lang, UT_RACES); - variant token; + void **tokens = get_translations(lang, UT_RACES); + variant token; - assert(lang); - if (tokens && findtoken(*tokens, s, &token) == E_TOK_SUCCESS) { - return (const struct race *)token.v; - } - return NULL; + assert(lang); + if (tokens && findtoken(*tokens, s, &token) == E_TOK_SUCCESS) { + return (const struct race *)token.v; + } + return NULL; } int findoption(const char *s, const struct locale *lang) { - void **tokens = get_translations(lang, UT_OPTIONS); - variant token; + void **tokens = get_translations(lang, UT_OPTIONS); + variant token; - if (findtoken(*tokens, s, &token) == E_TOK_SUCCESS) { - return (direction_t) token.i; - } - return NODIRECTION; + if (findtoken(*tokens, s, &token) == E_TOK_SUCCESS) { + return (direction_t)token.i; + } + return NODIRECTION; } param_t findparam(const char *s, const struct locale * lang) { param_t result = NOPARAM; char buffer[64]; - char * str = transliterate(buffer, sizeof(buffer)-sizeof(int), s); - + char * str = transliterate(buffer, sizeof(buffer) - sizeof(int), s); + if (str && *str) { int i; const void * match; @@ -1184,174 +1192,174 @@ param_t findparam(const char *s, const struct locale * lang) param_t findparam_ex(const char *s, const struct locale * lang) { - param_t result = findparam(s, lang); + param_t result = findparam(s, lang); - if (result==NOPARAM) { - const building_type *btype = findbuildingtype(s, lang); - if (btype != NULL) - return P_GEBAEUDE; - } - return (result == P_BUILDING) ? P_GEBAEUDE : result; + if (result == NOPARAM) { + const building_type *btype = findbuildingtype(s, lang); + if (btype != NULL) + return P_GEBAEUDE; + } + return (result == P_BUILDING) ? P_GEBAEUDE : result; } bool isparam(const char *s, const struct locale * lang, param_t param) { - if (s[0]>'@') { - param_t p = (param==P_GEBAEUDE) ? findparam_ex(s, lang) : findparam(s, lang); - return p==param; - } - return false; + if (s[0] > '@') { + param_t p = (param == P_GEBAEUDE) ? findparam_ex(s, lang) : findparam(s, lang); + return p == param; + } + return false; } param_t getparam(const struct locale * lang) { - return findparam(getstrtoken(), lang); + return findparam(getstrtoken(), lang); } faction *findfaction(int n) { - faction *f = ffindhash(n); - return f; + faction *f = ffindhash(n); + return f; } faction *getfaction(void) { - return findfaction(getid()); + return findfaction(getid()); } unit *findunitr(const region * r, int n) { - unit *u; + unit *u; - /* findunit regional! */ + /* findunit regional! */ - for (u = r->units; u; u = u->next) - if (u->no == n) - return u; + for (u = r->units; u; u = u->next) + if (u->no == n) + return u; - return 0; + return 0; } unit *findunit(int n) { - if (n <= 0) { - return NULL; - } - return ufindhash(n); + if (n <= 0) { + return NULL; + } + return ufindhash(n); } unit *findunitg(int n, const region * hint) { - /* Abfangen von Syntaxfehlern. */ - if (n <= 0) - return NULL; + /* Abfangen von Syntaxfehlern. */ + if (n <= 0) + return NULL; - /* findunit global! */ - hint = 0; - return ufindhash(n); + /* findunit global! */ + hint = 0; + return ufindhash(n); } unit *getnewunit(const region * r, const faction * f) { - int n; - n = getid(); + int n; + n = getid(); - return findnewunit(r, f, n); + return findnewunit(r, f, n); } static int read_newunitid(const faction * f, const region * r) { - int n; - unit *u2; - n = getid(); - if (n == 0) + int n; + unit *u2; + n = getid(); + if (n == 0) + return -1; + + u2 = findnewunit(r, f, n); + if (u2) + return u2->no; + return -1; - - u2 = findnewunit(r, f, n); - if (u2) - return u2->no; - - return -1; } int read_unitid(const faction * f, const region * r) { - const char *s = getstrtoken(); + const char *s = getstrtoken(); - /* Da s nun nur einen string enthaelt, suchen wir ihn direkt in der - * paramliste. machen wir das nicht, dann wird getnewunit in s nach der - * nummer suchen, doch dort steht bei temp-units nur "temp" drinnen! */ + /* Da s nun nur einen string enthaelt, suchen wir ihn direkt in der + * paramliste. machen wir das nicht, dann wird getnewunit in s nach der + * nummer suchen, doch dort steht bei temp-units nur "temp" drinnen! */ - if (!s || *s == 0) { - return -1; - } - if (isparam(s, f->locale, P_TEMP)) { - return read_newunitid(f, r); - } - return atoi36((const char *)s); + if (!s || *s == 0) { + return -1; + } + if (isparam(s, f->locale, P_TEMP)) { + return read_newunitid(f, r); + } + return atoi36((const char *)s); } /* exported symbol */ bool getunitpeasants; unit *getunitg(const region * r, const faction * f) { - int n = read_unitid(f, r); + int n = read_unitid(f, r); - if (n == 0) { - getunitpeasants = 1; - return NULL; - } - getunitpeasants = 0; - if (n < 0) - return 0; + if (n == 0) { + getunitpeasants = 1; + return NULL; + } + getunitpeasants = 0; + if (n < 0) + return 0; - return findunit(n); + return findunit(n); } unit *getunit(const region * r, const faction * f) { - int n = read_unitid(f, r); - unit *u2; + int n = read_unitid(f, r); + unit *u2; + + if (n == 0) { + getunitpeasants = 1; + return NULL; + } + getunitpeasants = 0; + if (n < 0) + return 0; + + u2 = findunit(n); + if (u2 != NULL && u2->region == r) { + /* there used to be a 'u2->flags & UFL_ISNEW || u2->number>0' condition + * here, but it got removed because of a bug that made units disappear: + * http://eressea.upb.de/mantis/bug_view_page.php?bug_id=0000172 + */ + return u2; + } - if (n == 0) { - getunitpeasants = 1; return NULL; - } - getunitpeasants = 0; - if (n < 0) - return 0; - - u2 = findunit(n); - if (u2 != NULL && u2->region == r) { - /* there used to be a 'u2->flags & UFL_ISNEW || u2->number>0' condition - * here, but it got removed because of a bug that made units disappear: - * http://eressea.upb.de/mantis/bug_view_page.php?bug_id=0000172 - */ - return u2; - } - - return NULL; } /* - String Listen --------------------------------------------- */ void addstrlist(strlist ** SP, const char *s) { - strlist *slist = malloc(sizeof(strlist)); - slist->next = NULL; - slist->s = _strdup(s); - addlist(SP, slist); + strlist *slist = malloc(sizeof(strlist)); + slist->next = NULL; + slist->s = _strdup(s); + addlist(SP, slist); } void freestrlist(strlist * s) { - strlist *q, *p = s; - while (p) { - q = p->next; - free(p->s); - free(p); - p = q; - } + strlist *q, *p = s; + while (p) { + q = p->next; + free(p->s); + free(p); + p = q; + } } /* - Namen der Strukturen -------------------------------------- */ @@ -1361,75 +1369,75 @@ static int nextbuf = 0; char *estring_i(char *ibuf) { - char *p = ibuf; + char *p = ibuf; - while (*p) { - if (isxspace(*(unsigned *)p) == ' ') { - *p = '~'; + while (*p) { + if (isxspace(*(unsigned *)p) == ' ') { + *p = '~'; + } + ++p; } - ++p; - } - return ibuf; + return ibuf; } char *estring(const char *s) { - char *ibuf = idbuf[(++nextbuf) % 8]; + char *ibuf = idbuf[(++nextbuf) % 8]; - strlcpy(ibuf, s, sizeof(name)); - return estring_i(ibuf); + strlcpy(ibuf, s, sizeof(name)); + return estring_i(ibuf); } char *cstring_i(char *ibuf) { - char *p = ibuf; + char *p = ibuf; - while (*p) { - if (*p == '~') { - *p = ' '; + while (*p) { + if (*p == '~') { + *p = ' '; + } + ++p; } - ++p; - } - return ibuf; + return ibuf; } char *cstring(const char *s) { - char *ibuf = idbuf[(++nextbuf) % 8]; + char *ibuf = idbuf[(++nextbuf) % 8]; - strlcpy(ibuf, s, sizeof(name)); - return cstring_i(ibuf); + strlcpy(ibuf, s, sizeof(name)); + return cstring_i(ibuf); } building *largestbuilding(const region * r, cmp_building_cb cmp_gt, - bool imaginary) + bool imaginary) { - building *b, *best = NULL; + building *b, *best = NULL; - for (b = rbuildings(r); b; b = b->next) { - if (cmp_gt(b, best) <= 0) - continue; - if (!imaginary) { - const attrib *a = a_find(b->attribs, &at_icastle); - if (a) - continue; + for (b = rbuildings(r); b; b = b->next) { + if (cmp_gt(b, best) <= 0) + continue; + if (!imaginary) { + const attrib *a = a_find(b->attribs, &at_icastle); + if (a) + continue; + } + best = b; } - best = b; - } - return best; + return best; } char *write_unitname(const unit * u, char *buffer, size_t size) { - slprintf(buffer, size, "%s (%s)", (const char *)u->name, itoa36(u->no)); - buffer[size - 1] = 0; - return buffer; + slprintf(buffer, size, "%s (%s)", (const char *)u->name, itoa36(u->no)); + buffer[size - 1] = 0; + return buffer; } const char *unitname(const unit * u) { - char *ubuf = idbuf[(++nextbuf) % 8]; - return write_unitname(u, ubuf, sizeof(name)); + char *ubuf = idbuf[(++nextbuf) % 8]; + return write_unitname(u, ubuf, sizeof(name)); } /* -- Erschaffung neuer Einheiten ------------------------------ */ @@ -1440,228 +1448,232 @@ static const char *forbidden[] = { "t", "te", "tem", "temp", NULL }; int forbiddenid(int id) { - static int *forbid = NULL; - static size_t len; - size_t i; - if (id <= 0) - return 1; - if (!forbid) { - while (forbidden[len]) - ++len; - forbid = calloc(len, sizeof(int)); - for (i = 0; i != len; ++i) { - forbid[i] = strtol(forbidden[i], NULL, 36); + static int *forbid = NULL; + static size_t len; + size_t i; + if (id <= 0) + return 1; + if (!forbid) { + while (forbidden[len]) + ++len; + forbid = calloc(len, sizeof(int)); + for (i = 0; i != len; ++i) { + forbid[i] = strtol(forbidden[i], NULL, 36); + } } - } - for (i = 0; i != len; ++i) - if (id == forbid[i]) - return 1; - return 0; + for (i = 0; i != len; ++i) + if (id == forbid[i]) + return 1; + return 0; } /* ID's für Einheiten und Zauber */ int newunitid(void) { - int random_unit_no; - int start_random_no; - random_unit_no = 1 + (rng_int() % MAX_UNIT_NR); - start_random_no = random_unit_no; + int random_unit_no; + int start_random_no; + random_unit_no = 1 + (rng_int() % MAX_UNIT_NR); + start_random_no = random_unit_no; - while (ufindhash(random_unit_no) || dfindhash(random_unit_no) - || cfindhash(random_unit_no) - || forbiddenid(random_unit_no)) { - random_unit_no++; - if (random_unit_no == MAX_UNIT_NR + 1) { - random_unit_no = 1; + while (ufindhash(random_unit_no) || dfindhash(random_unit_no) + || cfindhash(random_unit_no) + || forbiddenid(random_unit_no)) { + random_unit_no++; + if (random_unit_no == MAX_UNIT_NR + 1) { + random_unit_no = 1; + } + if (random_unit_no == start_random_no) { + random_unit_no = (int)MAX_UNIT_NR + 1; + } } - if (random_unit_no == start_random_no) { - random_unit_no = (int)MAX_UNIT_NR + 1; - } - } - return random_unit_no; + return random_unit_no; } int newcontainerid(void) { - int random_no; - int start_random_no; + int random_no; + int start_random_no; - random_no = 1 + (rng_int() % MAX_CONTAINER_NR); - start_random_no = random_no; + random_no = 1 + (rng_int() % MAX_CONTAINER_NR); + start_random_no = random_no; - while (findship(random_no) || findbuilding(random_no)) { - random_no++; - if (random_no == MAX_CONTAINER_NR + 1) { - random_no = 1; + while (findship(random_no) || findbuilding(random_no)) { + random_no++; + if (random_no == MAX_CONTAINER_NR + 1) { + random_no = 1; + } + if (random_no == start_random_no) { + random_no = (int)MAX_CONTAINER_NR + 1; + } } - if (random_no == start_random_no) { - random_no = (int)MAX_CONTAINER_NR + 1; - } - } - return random_no; + return random_no; } unit *createunit(region * r, faction * f, int number, const struct race * rc) { - assert(rc); - return create_unit(r, f, number, rc, 0, NULL, NULL); + assert(rc); + return create_unit(r, f, number, rc, 0, NULL, NULL); } bool idle(faction * f) { - return (bool) (f ? false : true); + return (bool)(f ? false : true); } int maxworkingpeasants(const struct region *r) { - int i = production(r) * MAXPEASANTS_PER_AREA - - ((rtrees(r, 2) + rtrees(r, 1) / 2) * TREESIZE); - return _max(i, 0); + int i = production(r) * MAXPEASANTS_PER_AREA + - ((rtrees(r, 2) + rtrees(r, 1) / 2) * TREESIZE); + return _max(i, 0); } int lighthouse_range(const building * b, const faction * f) { - int d = 0; - if (fval(b, BLD_WORKING) && b->size >= 10) { - int maxd = (int)log10(b->size) + 1; + int d = 0; + if (fval(b, BLD_WORKING) && b->size >= 10) { + int maxd = (int)log10(b->size) + 1; - if (skill_enabled(SK_PERCEPTION)) { - region *r = b->region; - int c = 0; - unit *u; - for (u = r->units; u; u = u->next) { - if (u->building == b) { - c += u->number; - if (c > buildingcapacity(b)) - break; - if (f == NULL || u->faction == f) { - int sk = eff_skill(u, SK_PERCEPTION, r) / 3; - d = _max(d, sk); - d = _min(maxd, d); - if (d == maxd) - break; - } - } else if (c) - break; /* first unit that's no longer in the house ends the search */ - } - } else { - /* E3A rule: no perception req'd */ - return maxd; + if (skill_enabled(SK_PERCEPTION)) { + region *r = b->region; + int c = 0; + unit *u; + for (u = r->units; u; u = u->next) { + if (u->building == b) { + c += u->number; + if (c > buildingcapacity(b)) + break; + if (f == NULL || u->faction == f) { + int sk = eff_skill(u, SK_PERCEPTION, r) / 3; + d = _max(d, sk); + d = _min(maxd, d); + if (d == maxd) + break; + } + } + else if (c) + break; /* first unit that's no longer in the house ends the search */ + } + } + else { + /* E3A rule: no perception req'd */ + return maxd; + } } - } - return d; + return d; } bool check_leuchtturm(region * r, faction * f) { - attrib *a; + attrib *a; - if (!fval(r->terrain, SEA_REGION)) - return false; + if (!fval(r->terrain, SEA_REGION)) + return false; - for (a = a_find(r->attribs, &at_lighthouse); a && a->type == &at_lighthouse; - a = a->next) { - building *b = (building *) a->data.v; + for (a = a_find(r->attribs, &at_lighthouse); a && a->type == &at_lighthouse; + a = a->next) { + building *b = (building *)a->data.v; - assert(b->type == bt_find("lighthouse")); - if (fval(b, BLD_WORKING) && b->size >= 10) { - int maxd = (int)log10(b->size) + 1; + assert(b->type == bt_find("lighthouse")); + if (fval(b, BLD_WORKING) && b->size >= 10) { + int maxd = (int)log10(b->size) + 1; - if (skill_enabled(SK_PERCEPTION)) { - region *r2 = b->region; - unit *u; - int c = 0; - int d = 0; + if (skill_enabled(SK_PERCEPTION)) { + region *r2 = b->region; + unit *u; + int c = 0; + int d = 0; - for (u = r2->units; u; u = u->next) { - if (u->building == b) { - c += u->number; - if (c > buildingcapacity(b)) - break; - if (f == NULL || u->faction == f) { - if (!d) - d = distance(r, r2); - if (maxd < d) - break; - if (eff_skill(u, SK_PERCEPTION, r) >= d * 3) - return true; + for (u = r2->units; u; u = u->next) { + if (u->building == b) { + c += u->number; + if (c > buildingcapacity(b)) + break; + if (f == NULL || u->faction == f) { + if (!d) + d = distance(r, r2); + if (maxd < d) + break; + if (eff_skill(u, SK_PERCEPTION, r) >= d * 3) + return true; + } + } + else if (c) + break; /* first unit that's no longer in the house ends the search */ + } + } + else { + /* E3A rule: no perception req'd */ + return maxd; } - } else if (c) - break; /* first unit that's no longer in the house ends the search */ } - } else { - /* E3A rule: no perception req'd */ - return maxd; - } } - } - return false; + return false; } region *lastregion(faction * f) { #ifdef SMART_INTERVALS - unit *u = f->units; - region *r = f->last; + unit *u = f->units; + region *r = f->last; - if (u == NULL) - return NULL; - if (r != NULL) - return r->next; + if (u == NULL) + return NULL; + if (r != NULL) + return r->next; - /* it is safe to start in the region of the first unit. */ - f->last = u->region; - /* if regions have indices, we can skip ahead: */ - for (u = u->nextF; u != NULL; u = u->nextF) { - r = u->region; - if (r->index > f->last->index) - f->last = r; - } + /* it is safe to start in the region of the first unit. */ + f->last = u->region; + /* if regions have indices, we can skip ahead: */ + for (u = u->nextF; u != NULL; u = u->nextF) { + r = u->region; + if (r->index > f->last->index) + f->last = r; + } - /* we continue from the best region and look for travelthru etc. */ - for (r = f->last->next; r; r = r->next) { - plane *p = rplane(r); + /* we continue from the best region and look for travelthru etc. */ + for (r = f->last->next; r; r = r->next) { + plane *p = rplane(r); - /* search the region for travelthru-attributes: */ - if (fval(r, RF_TRAVELUNIT)) { - attrib *ru = a_find(r->attribs, &at_travelunit); - while (ru && ru->type == &at_travelunit) { - u = (unit *) ru->data.v; - if (u->faction == f) { - f->last = r; - break; + /* search the region for travelthru-attributes: */ + if (fval(r, RF_TRAVELUNIT)) { + attrib *ru = a_find(r->attribs, &at_travelunit); + while (ru && ru->type == &at_travelunit) { + u = (unit *)ru->data.v; + if (u->faction == f) { + f->last = r; + break; + } + ru = ru->next; + } + } + if (f->last == r) + continue; + if (check_leuchtturm(r, f)) + f->last = r; + if (p && is_watcher(p, f)) { + f->last = r; } - ru = ru->next; - } } - if (f->last == r) - continue; - if (check_leuchtturm(r, f)) - f->last = r; - if (p && is_watcher(p, f)) { - f->last = r; - } - } - return f->last->next; + return f->last->next; #else - return NULL; + return NULL; #endif } region *firstregion(faction * f) { #ifdef SMART_INTERVALS - region *r = f->first; + region *r = f->first; - if (f->units == NULL) - return NULL; - if (r != NULL) - return r; + if (f->units == NULL) + return NULL; + if (r != NULL) + return r; - return f->first = regions; + return f->first = regions; #else - return regions; + return regions; #endif } @@ -1671,33 +1683,33 @@ int blk_index; static void gc_done(void) { - int i, k; - for (i = 0; i != list_index; ++i) { - for (k = 0; k != 1024; ++k) - free(blk_list[i][k]); - free(blk_list[i]); - } - for (k = 0; k != blk_index; ++k) - free(blk_list[list_index][k]); - free(blk_list[list_index]); + int i, k; + for (i = 0; i != list_index; ++i) { + for (k = 0; k != 1024; ++k) + free(blk_list[i][k]); + free(blk_list[i]); + } + for (k = 0; k != blk_index; ++k) + free(blk_list[list_index][k]); + free(blk_list[list_index]); } void *gc_add(void *p) { - if (blk_index == 0) { - blk_list[list_index] = (void **)malloc(1024 * sizeof(void *)); - } - blk_list[list_index][blk_index] = p; - blk_index = (blk_index + 1) % 1024; - if (!blk_index) - ++list_index; - return p; + if (blk_index == 0) { + blk_list[list_index] = (void **)malloc(1024 * sizeof(void *)); + } + blk_list[list_index][blk_index] = p; + blk_index = (blk_index + 1) % 1024; + if (!blk_index) + ++list_index; + return p; } void add_translation(critbit_tree **cbp, const char *key, int i) { char buffer[256]; - char * str = transliterate(buffer, sizeof(buffer)-sizeof(int), key); + char * str = transliterate(buffer, sizeof(buffer) - sizeof(int), key); critbit_tree * cb = *cbp; if (str) { size_t len = strlen(str); @@ -1706,41 +1718,42 @@ void add_translation(critbit_tree **cbp, const char *key, int i) { } len = cb_new_kv(str, len, &i, sizeof(int), buffer); cb_insert(cb, buffer, len); - } else { + } + else { log_error("could not transliterate '%s'\n", key); } } void init_translations(const struct locale *lang, int ut, const char * (*string_cb)(int i), int maxstrings) { - void **tokens; - int i; + void **tokens; + int i; - assert(string_cb); - assert(maxstrings>0); - tokens = get_translations(lang, ut); - for (i = 0; i != maxstrings; ++i) { - const char * s = string_cb(i); - const char * key = s ? locale_string(lang, s) : 0; - key = key ? key : s; - if (key) { - critbit_tree ** cb = (critbit_tree **)tokens; - add_translation(cb, key, i); + assert(string_cb); + assert(maxstrings > 0); + tokens = get_translations(lang, ut); + for (i = 0; i != maxstrings; ++i) { + const char * s = string_cb(i); + const char * key = s ? locale_string(lang, s) : 0; + key = key ? key : s; + if (key) { + critbit_tree ** cb = (critbit_tree **)tokens; + add_translation(cb, key, i); + } } - } } static const char * parameter_key(int i) { - assert(i=0); - return parameters[i]; + assert(i < MAXPARAMS && i >= 0); + return parameters[i]; } void init_terrains_translation(const struct locale *lang) { void **tokens; const terrain_type *terrain; - + tokens = get_translations(lang, UT_TERRAINS); for (terrain = terrains(); terrain != NULL; terrain = terrain->next) { variant var; @@ -1833,19 +1846,19 @@ static void init_locale(const struct locale *lang) } typedef struct param { - struct param *next; - char *name; - char *data; + struct param *next; + char *name; + char *data; } param; int getid(void) { - const char *str = (const char *)getstrtoken(); - int i = atoi36(str); - if (i < 0) { - return -1; - } - return i; + const char *str = (const char *)getstrtoken(); + int i = atoi36(str); + if (i < 0) { + return -1; + } + return i; } const char *get_param(const struct param *p, const char *key) @@ -1854,8 +1867,8 @@ const char *get_param(const struct param *p, const char *key) int cmp = strcmp(p->name, key); if (cmp == 0) { return p->data; - } - else if (cmp>0) { + } + else if (cmp > 0) { break; } p = p->next; @@ -1872,42 +1885,42 @@ int get_param_int(const struct param *p, const char *key, int def) static const char *g_datadir; const char *datapath(void) { - static char zText[MAX_PATH]; - if (g_datadir) - return g_datadir; - return strcat(strcpy(zText, basepath()), "/data"); + static char zText[MAX_PATH]; + if (g_datadir) + return g_datadir; + return strcat(strcpy(zText, basepath()), "/data"); } void set_datapath(const char *path) { - g_datadir = path; + g_datadir = path; } static const char *g_reportdir; const char *reportpath(void) { - static char zText[MAX_PATH]; - if (g_reportdir) - return g_reportdir; - return strcat(strcpy(zText, basepath()), "/reports"); + static char zText[MAX_PATH]; + if (g_reportdir) + return g_reportdir; + return strcat(strcpy(zText, basepath()), "/reports"); } void set_reportpath(const char *path) { - g_reportdir = path; + g_reportdir = path; } static const char *g_basedir; const char *basepath(void) { - if (g_basedir) - return g_basedir; - return "."; + if (g_basedir) + return g_basedir; + return "."; } void set_basepath(const char *path) { - g_basedir = path; + g_basedir = path; } float get_param_flt(const struct param *p, const char *key, float def) @@ -1928,7 +1941,7 @@ void set_param(struct param **p, const char *key, const char *data) (*p)->data = _strdup(data); return; } - else if (cmp>0) { + else if (cmp > 0) { break; } p = &(*p)->next; @@ -1942,16 +1955,16 @@ void set_param(struct param **p, const char *key, const char *data) void kernel_done(void) { - /* calling this function releases memory assigned to static variables, etc. - * calling it is optional, e.g. a release server will most likely not do it. - */ - translation_done(); - gc_done(); + /* calling this function releases memory assigned to static variables, etc. + * calling it is optional, e.g. a release server will most likely not do it. + */ + translation_done(); + gc_done(); } const char *localenames[] = { - "de", "en", - NULL + "de", "en", + NULL }; void init_locales(void) @@ -1967,177 +1980,181 @@ void init_locales(void) extern struct attrib_type at_shiptrail; attrib_type at_germs = { - "germs", - DEFAULT_INIT, - DEFAULT_FINALIZE, - DEFAULT_AGE, - a_writeshorts, - a_readshorts, - ATF_UNIQUE + "germs", + DEFAULT_INIT, + DEFAULT_FINALIZE, + DEFAULT_AGE, + a_writeshorts, + a_readshorts, + ATF_UNIQUE }; /*********************/ /* at_guard */ /*********************/ attrib_type at_guard = { - "guard", - DEFAULT_INIT, - DEFAULT_FINALIZE, - DEFAULT_AGE, - a_writeint, - a_readint, - ATF_UNIQUE + "guard", + DEFAULT_INIT, + DEFAULT_FINALIZE, + DEFAULT_AGE, + a_writeint, + a_readint, + ATF_UNIQUE }; void setstatus(struct unit *u, int status) { - assert(status >= ST_AGGRO && status <= ST_FLEE); - if (u->status != status) { - u->status = (status_t) status; - } + assert(status >= ST_AGGRO && status <= ST_FLEE); + if (u->status != status) { + u->status = (status_t)status; + } } void setguard(unit * u, unsigned int flags) { - /* setzt die guard-flags der Einheit */ - attrib *a = NULL; - assert(flags == 0 || !fval(u, UFL_MOVED)); - assert(flags == 0 || u->status < ST_FLEE); - if (fval(u, UFL_GUARD)) { - a = a_find(u->attribs, &at_guard); - } - if (flags == GUARD_NONE) { - freset(u, UFL_GUARD); - if (a) - a_remove(&u->attribs, a); - return; - } - fset(u, UFL_GUARD); - fset(u->region, RF_GUARDED); - if ((int)flags == guard_flags(u)) { - if (a) - a_remove(&u->attribs, a); - } else { - if (!a) - a = a_add(&u->attribs, a_new(&at_guard)); - a->data.i = (int)flags; - } + /* setzt die guard-flags der Einheit */ + attrib *a = NULL; + assert(flags == 0 || !fval(u, UFL_MOVED)); + assert(flags == 0 || u->status < ST_FLEE); + if (fval(u, UFL_GUARD)) { + a = a_find(u->attribs, &at_guard); + } + if (flags == GUARD_NONE) { + freset(u, UFL_GUARD); + if (a) + a_remove(&u->attribs, a); + return; + } + fset(u, UFL_GUARD); + fset(u->region, RF_GUARDED); + if ((int)flags == guard_flags(u)) { + if (a) + a_remove(&u->attribs, a); + } + else { + if (!a) + a = a_add(&u->attribs, a_new(&at_guard)); + a->data.i = (int)flags; + } } unsigned int getguard(const unit * u) { - attrib *a; + attrib *a; - assert(fval(u, UFL_GUARD) || (u->building && u==building_owner(u->building)) - || !"you're doing it wrong! check is_guard first"); - a = a_find(u->attribs, &at_guard); - if (a) { - return (unsigned int)a->data.i; - } - return guard_flags(u); + assert(fval(u, UFL_GUARD) || (u->building && u == building_owner(u->building)) + || !"you're doing it wrong! check is_guard first"); + a = a_find(u->attribs, &at_guard); + if (a) { + return (unsigned int)a->data.i; + } + return guard_flags(u); } #ifndef HAVE_STRDUP char *_strdup(const char *s) { - return strcpy((char *)malloc(sizeof(char) * (strlen(s) + 1)), s); + return strcpy((char *)malloc(sizeof(char) * (strlen(s) + 1)), s); } #endif void remove_empty_factions(void) { - faction **fp, *f3; + faction **fp, *f3; - for (fp = &factions; *fp;) { - faction *f = *fp; - /* monster (0) werden nicht entfernt. alive kann beim readgame - * () auf 0 gesetzt werden, wenn monsters keine einheiten mehr - * haben. */ - if ((f->units == NULL || f->alive == 0) && !is_monsters(f)) { - ursprung *ur = f->ursprung; - while (ur && ur->id != 0) - ur = ur->next; - if (verbosity >= 2) - log_printf(stdout, "\t%s\n", factionname(f)); + for (fp = &factions; *fp;) { + faction *f = *fp; + /* monster (0) werden nicht entfernt. alive kann beim readgame + * () auf 0 gesetzt werden, wenn monsters keine einheiten mehr + * haben. */ + if ((f->units == NULL || f->alive == 0) && !is_monsters(f)) { + ursprung *ur = f->ursprung; + while (ur && ur->id != 0) + ur = ur->next; + if (verbosity >= 2) + log_printf(stdout, "\t%s\n", factionname(f)); - /* Einfach in eine Datei schreiben und später vermailen */ + /* Einfach in eine Datei schreiben und später vermailen */ - if (updatelog) - fprintf(updatelog, "dropout %s\n", itoa36(f->no)); + if (updatelog) + fprintf(updatelog, "dropout %s\n", itoa36(f->no)); - for (f3 = factions; f3; f3 = f3->next) { - ally *sf; - group *g; - ally **sfp = &f3->allies; - while (*sfp) { - sf = *sfp; - if (sf->faction == f || sf->faction == NULL) { - *sfp = sf->next; - free(sf); - } else - sfp = &(*sfp)->next; + for (f3 = factions; f3; f3 = f3->next) { + ally *sf; + group *g; + ally **sfp = &f3->allies; + while (*sfp) { + sf = *sfp; + if (sf->faction == f || sf->faction == NULL) { + *sfp = sf->next; + free(sf); + } + else + sfp = &(*sfp)->next; + } + for (g = f3->groups; g; g = g->next) { + sfp = &g->allies; + while (*sfp) { + sf = *sfp; + if (sf->faction == f || sf->faction == NULL) { + *sfp = sf->next; + free(sf); + } + else + sfp = &(*sfp)->next; + } + } + } + + *fp = f->next; + funhash(f); + free_faction(f); + free(f); } - for (g = f3->groups; g; g = g->next) { - sfp = &g->allies; - while (*sfp) { - sf = *sfp; - if (sf->faction == f || sf->faction == NULL) { - *sfp = sf->next; - free(sf); - } else - sfp = &(*sfp)->next; - } - } - } - - *fp = f->next; - funhash(f); - free_faction(f); - free(f); - } else - fp = &(*fp)->next; - } + else + fp = &(*fp)->next; + } } void remove_empty_units_in_region(region * r) { - unit **up = &r->units; + unit **up = &r->units; - while (*up) { - unit *u = *up; + while (*up) { + unit *u = *up; - if (u->number) { - faction *f = u->faction; - if (f == NULL || !f->alive) { - set_number(u, 0); - } - if (MaxAge() > 0) { - if ((!fval(f, FFL_NOTIMEOUT) && f->age > MaxAge())) { - set_number(u, 0); + if (u->number) { + faction *f = u->faction; + if (f == NULL || !f->alive) { + set_number(u, 0); + } + if (MaxAge() > 0) { + if ((!fval(f, FFL_NOTIMEOUT) && f->age > MaxAge())) { + set_number(u, 0); + } + } } - } + if ((u->number == 0 && u_race(u) != get_race(RC_SPELL)) || (u->age <= 0 + && u_race(u) == get_race(RC_SPELL))) { + remove_unit(up, u); + } + if (*up == u) + up = &u->next; } - if ((u->number == 0 && u_race(u) != get_race(RC_SPELL)) || (u->age <= 0 - && u_race(u) == get_race(RC_SPELL))) { - remove_unit(up, u); - } - if (*up == u) - up = &u->next; - } } void remove_empty_units(void) { - region *r; + region *r; - for (r = regions; r; r = r->next) { - remove_empty_units_in_region(r); - } + for (r = regions; r; r = r->next) { + remove_empty_units_in_region(r); + } } bool faction_id_is_unused(int id) { - return findfaction(id) == NULL; + return findfaction(id) == NULL; } int weight(const unit * u) @@ -2145,7 +2162,7 @@ int weight(const unit * u) int w = 0, n = 0, in_bag = 0; const resource_type *rtype = get_resourcetype(R_BAG_OF_HOLDING); item *itm; - + for (itm = u->items; itm; itm = itm->next) { w = itm->type->weight * itm->number; n += w; @@ -2153,630 +2170,639 @@ int weight(const unit * u) in_bag += w; } } - + n += u->number * u_race(u)->weight; - + if (rtype) { w = i_get(u->items, rtype->itype) * BAGCAPACITY; if (w > in_bag) w = in_bag; n -= w; } - + return n; } void make_undead_unit(unit * u) { - free_orders(&u->orders); - name_unit(u); - fset(u, UFL_ISNEW); + free_orders(&u->orders); + name_unit(u); + fset(u, UFL_ISNEW); } unsigned int guard_flags(const unit * u) { - unsigned int flags = - GUARD_CREWS | GUARD_LANDING | GUARD_TRAVELTHRU | GUARD_TAX; + unsigned int flags = + GUARD_CREWS | GUARD_LANDING | GUARD_TRAVELTHRU | GUARD_TAX; #if GUARD_DISABLES_PRODUCTION == 1 - flags |= GUARD_PRODUCE; + flags |= GUARD_PRODUCE; #endif #if GUARD_DISABLES_RECRUIT == 1 - flags |= GUARD_RECRUIT; + flags |= GUARD_RECRUIT; #endif - switch (old_race(u_race(u))) { - case RC_ELF: - if (u->faction->race != u_race(u)) - break; - /* else fallthrough */ - case RC_TREEMAN: - flags |= GUARD_TREES; - break; - case RC_IRONKEEPER: - flags = GUARD_MINING; - break; - default: - /* TODO: This should be configuration variables, all of it */ - break; - } - return flags; + switch (old_race(u_race(u))) { + case RC_ELF: + if (u->faction->race != u_race(u)) + break; + /* else fallthrough */ + case RC_TREEMAN: + flags |= GUARD_TREES; + break; + case RC_IRONKEEPER: + flags = GUARD_MINING; + break; + default: + /* TODO: This should be configuration variables, all of it */ + break; + } + return flags; } void guard(unit * u, unsigned int mask) { - unsigned int flags = guard_flags(u); - setguard(u, flags & mask); + unsigned int flags = guard_flags(u); + setguard(u, flags & mask); } int besieged(const unit * u) { - /* belagert kann man in schiffen und burgen werden */ - return (u && !keyword_disabled(K_BESIEGE) - && u->building && u->building->besieged - && u->building->besieged >= u->building->size * SIEGEFACTOR); + /* belagert kann man in schiffen und burgen werden */ + return (u && !keyword_disabled(K_BESIEGE) + && u->building && u->building->besieged + && u->building->besieged >= u->building->size * SIEGEFACTOR); } int lifestyle(const unit * u) { - int need; - plane *pl; - static int gamecookie = -1; - if (gamecookie != global.cookie) { - gamecookie = global.cookie; - } + int need; + plane *pl; + static int gamecookie = -1; + if (gamecookie != global.cookie) { + gamecookie = global.cookie; + } - if (is_monsters(u->faction)) - return 0; + if (is_monsters(u->faction)) + return 0; - need = maintenance_cost(u); + need = maintenance_cost(u); - pl = rplane(u->region); - if (pl && fval(pl, PFL_NOFEED)) - return 0; + pl = rplane(u->region); + if (pl && fval(pl, PFL_NOFEED)) + return 0; - return need; + return need; } bool has_horses(const struct unit * u) { - item *itm = u->items; - for (; itm; itm = itm->next) { - if (itm->type->flags & ITF_ANIMAL) - return true; - } - return false; + item *itm = u->items; + for (; itm; itm = itm->next) { + if (itm->type->flags & ITF_ANIMAL) + return true; + } + return false; } bool hunger(int number, unit * u) { - region *r = u->region; - int dead = 0, hpsub = 0; - int hp = u->hp / u->number; - static const char *damage = 0; - static const char *rcdamage = 0; - static const race *rc = 0; + region *r = u->region; + int dead = 0, hpsub = 0; + int hp = u->hp / u->number; + static const char *damage = 0; + static const char *rcdamage = 0; + static const race *rc = 0; - if (!damage) { - damage = get_param(global.parameters, "hunger.damage"); - if (damage == NULL) - damage = "1d12+12"; - } - if (rc != u_race(u)) { - rcdamage = get_param(u_race(u)->parameters, "hunger.damage"); - rc = u_race(u); - } - - while (number--) { - int dam = dice_rand(rcdamage ? rcdamage : damage); - if (dam >= hp) { - ++dead; - } else { - hpsub += dam; + if (!damage) { + damage = get_param(global.parameters, "hunger.damage"); + if (damage == NULL) + damage = "1d12+12"; } - } - - if (dead) { - /* Gestorbene aus der Einheit nehmen, - * Sie bekommen keine Beerdingung. */ - ADDMSG(&u->faction->msgs, msg_message("starvation", - "unit region dead live", u, r, dead, u->number - dead)); - - scale_number(u, u->number - dead); - deathcounts(r, dead); - } - if (hpsub > 0) { - /* Jetzt die Schäden der nicht gestorbenen abziehen. */ - u->hp -= hpsub; - /* Meldung nur, wenn noch keine für Tote generiert. */ - if (dead == 0) { - /* Durch unzureichende Ernährung wird %s geschwächt */ - ADDMSG(&u->faction->msgs, msg_message("malnourish", "unit region", u, r)); + if (rc != u_race(u)) { + rcdamage = get_param(u_race(u)->parameters, "hunger.damage"); + rc = u_race(u); } - } - return (dead || hpsub); + + while (number--) { + int dam = dice_rand(rcdamage ? rcdamage : damage); + if (dam >= hp) { + ++dead; + } + else { + hpsub += dam; + } + } + + if (dead) { + /* Gestorbene aus der Einheit nehmen, + * Sie bekommen keine Beerdingung. */ + ADDMSG(&u->faction->msgs, msg_message("starvation", + "unit region dead live", u, r, dead, u->number - dead)); + + scale_number(u, u->number - dead); + deathcounts(r, dead); + } + if (hpsub > 0) { + /* Jetzt die Schäden der nicht gestorbenen abziehen. */ + u->hp -= hpsub; + /* Meldung nur, wenn noch keine für Tote generiert. */ + if (dead == 0) { + /* Durch unzureichende Ernährung wird %s geschwächt */ + ADDMSG(&u->faction->msgs, msg_message("malnourish", "unit region", u, r)); + } + } + return (dead || hpsub); } void plagues(region * r, bool ismagic) { - int peasants; - int i; - int dead = 0; + int peasants; + int i; + int dead = 0; - /* Seuchenwahrscheinlichkeit in % */ + /* Seuchenwahrscheinlichkeit in % */ - if (!ismagic) { - double mwp = _max(maxworkingpeasants(r), 1); - double prob = - pow(rpeasants(r) / (mwp * wage(r, NULL, NULL, turn) * 0.13), 4.0) - * PLAGUE_CHANCE; + if (!ismagic) { + double mwp = _max(maxworkingpeasants(r), 1); + double prob = + pow(rpeasants(r) / (mwp * wage(r, NULL, NULL, turn) * 0.13), 4.0) + * PLAGUE_CHANCE; - if (rng_double() >= prob) - return; - } - - peasants = rpeasants(r); - dead = (int)(0.5F + PLAGUE_VICTIMS * peasants); - for (i = dead; i != 0; i--) { - if (rng_double() < PLAGUE_HEALCHANCE && rmoney(r) >= PLAGUE_HEALCOST) { - rsetmoney(r, rmoney(r) - PLAGUE_HEALCOST); - --dead; + if (rng_double() >= prob) + return; } - } - if (dead > 0) { - message *msg = add_message(&r->msgs, msg_message("pest", "dead", dead)); - msg_release(msg); - deathcounts(r, dead); - rsetpeasants(r, peasants - dead); - } + peasants = rpeasants(r); + dead = (int)(0.5F + PLAGUE_VICTIMS * peasants); + for (i = dead; i != 0; i--) { + if (rng_double() < PLAGUE_HEALCHANCE && rmoney(r) >= PLAGUE_HEALCOST) { + rsetmoney(r, rmoney(r) - PLAGUE_HEALCOST); + --dead; + } + } + + if (dead > 0) { + message *msg = add_message(&r->msgs, msg_message("pest", "dead", dead)); + msg_release(msg); + deathcounts(r, dead); + rsetpeasants(r, peasants - dead); + } } /* Lohn bei den einzelnen Burgstufen für Normale Typen, Orks, Bauern, * Modifikation für Städter. */ static const int wagetable[7][4] = { - {10, 10, 11, -7}, /* Baustelle */ - {10, 10, 11, -5}, /* Handelsposten */ - {11, 11, 12, -3}, /* Befestigung */ - {12, 11, 13, -1}, /* Turm */ - {13, 12, 14, 0}, /* Burg */ - {14, 12, 15, 1}, /* Festung */ - {15, 13, 16, 2} /* Zitadelle */ + { 10, 10, 11, -7 }, /* Baustelle */ + { 10, 10, 11, -5 }, /* Handelsposten */ + { 11, 11, 12, -3 }, /* Befestigung */ + { 12, 11, 13, -1 }, /* Turm */ + { 13, 12, 14, 0 }, /* Burg */ + { 14, 12, 15, 1 }, /* Festung */ + { 15, 13, 16, 2 } /* Zitadelle */ }; int cmp_wage(const struct building *b, const building * a) { - const struct building_type *bt_castle = bt_find("castle"); - if (b->type == bt_castle) { - if (!a) - return 1; - if (b->size > a->size) - return 1; - if (b->size == a->size) - return 0; - } - return -1; + const struct building_type *bt_castle = bt_find("castle"); + if (b->type == bt_castle) { + if (!a) + return 1; + if (b->size > a->size) + return 1; + if (b->size == a->size) + return 0; + } + return -1; } bool is_owner_building(const struct building * b) { - region *r = b->region; - if (b->type->taxes && r->land && r->land->ownership) { - unit *u = building_owner(b); - return u && u->faction == r->land->ownership->owner; - } - return false; + region *r = b->region; + if (b->type->taxes && r->land && r->land->ownership) { + unit *u = building_owner(b); + return u && u->faction == r->land->ownership->owner; + } + return false; } int cmp_taxes(const building * b, const building * a) { - faction *f = region_get_owner(b->region); - if (b->type->taxes) { - unit *u = building_owner(b); - if (!u) { - return -1; - } else if (a) { - int newsize = buildingeffsize(b, false); - double newtaxes = b->type->taxes(b, newsize); - int oldsize = buildingeffsize(a, false); - double oldtaxes = a->type->taxes(a, oldsize); - - if (newtaxes < oldtaxes) - return -1; - else if (newtaxes > oldtaxes) - return 1; - else if (b->size < a->size) - return -1; - else if (b->size > a->size) - return 1; - else { - if (u && u->faction == f) { - u = building_owner(a); - if (u && u->faction == f) + faction *f = region_get_owner(b->region); + if (b->type->taxes) { + unit *u = building_owner(b); + if (!u) { return -1; - return 1; } - } - } else { - return 1; + else if (a) { + int newsize = buildingeffsize(b, false); + double newtaxes = b->type->taxes(b, newsize); + int oldsize = buildingeffsize(a, false); + double oldtaxes = a->type->taxes(a, oldsize); + + if (newtaxes < oldtaxes) + return -1; + else if (newtaxes > oldtaxes) + return 1; + else if (b->size < a->size) + return -1; + else if (b->size > a->size) + return 1; + else { + if (u && u->faction == f) { + u = building_owner(a); + if (u && u->faction == f) + return -1; + return 1; + } + } + } + else { + return 1; + } } - } - return -1; + return -1; } int cmp_current_owner(const building * b, const building * a) { - faction *f = region_get_owner(b->region); + faction *f = region_get_owner(b->region); - assert(rule_region_owners()); - if (f && b->type->taxes) { - unit *u = building_owner(b); - if (!u || u->faction != f) - return -1; - if (a) { - int newsize = buildingeffsize(b, false); - double newtaxes = b->type->taxes(b, newsize); - int oldsize = buildingeffsize(a, false); - double oldtaxes = a->type->taxes(a, oldsize); + assert(rule_region_owners()); + if (f && b->type->taxes) { + unit *u = building_owner(b); + if (!u || u->faction != f) + return -1; + if (a) { + int newsize = buildingeffsize(b, false); + double newtaxes = b->type->taxes(b, newsize); + int oldsize = buildingeffsize(a, false); + double oldtaxes = a->type->taxes(a, oldsize); - if (newtaxes != oldtaxes) - return (newtaxes > oldtaxes) ? 1 : -1; - if (newsize != oldsize) - return newsize - oldsize; - return (b->size - a->size); - } else { - return 1; + if (newtaxes != oldtaxes) + return (newtaxes > oldtaxes) ? 1 : -1; + if (newsize != oldsize) + return newsize - oldsize; + return (b->size - a->size); + } + else { + return 1; + } } - } - return -1; + return -1; } int rule_stealth_faction(void) { - static int gamecookie = -1; - static int rule = -1; - if (rule < 0 || gamecookie != global.cookie) { - rule = get_param_int(global.parameters, "rules.stealth.faction", 0xFF); - gamecookie = global.cookie; - assert(rule >= 0); - } - return rule; + static int gamecookie = -1; + static int rule = -1; + if (rule < 0 || gamecookie != global.cookie) { + rule = get_param_int(global.parameters, "rules.stealth.faction", 0xFF); + gamecookie = global.cookie; + assert(rule >= 0); + } + return rule; } int rule_region_owners(void) { - static int gamecookie = -1; - static int rule = -1; - if (rule < 0 || gamecookie != global.cookie) { - rule = get_param_int(global.parameters, "rules.region_owners", 0); - gamecookie = global.cookie; - assert(rule >= 0); - } - return rule; + static int gamecookie = -1; + static int rule = -1; + if (rule < 0 || gamecookie != global.cookie) { + rule = get_param_int(global.parameters, "rules.region_owners", 0); + gamecookie = global.cookie; + assert(rule >= 0); + } + return rule; } int rule_auto_taxation(void) { - static int gamecookie = -1; - static int rule = -1; - if (rule < 0 || gamecookie != global.cookie) { - rule = - get_param_int(global.parameters, "rules.economy.taxation", TAX_ORDER); - gamecookie = global.cookie; - assert(rule >= 0); - } - return rule; + static int gamecookie = -1; + static int rule = -1; + if (rule < 0 || gamecookie != global.cookie) { + rule = + get_param_int(global.parameters, "rules.economy.taxation", TAX_ORDER); + gamecookie = global.cookie; + assert(rule >= 0); + } + return rule; } int rule_blessed_harvest(void) { - static int gamecookie = -1; - static int rule = -1; - if (rule < 0 || gamecookie != global.cookie) { - rule = - get_param_int(global.parameters, "rules.magic.blessed_harvest", - HARVEST_WORK); - gamecookie = global.cookie; - assert(rule >= 0); - } - return rule; + static int gamecookie = -1; + static int rule = -1; + if (rule < 0 || gamecookie != global.cookie) { + rule = + get_param_int(global.parameters, "rules.magic.blessed_harvest", + HARVEST_WORK); + gamecookie = global.cookie; + assert(rule >= 0); + } + return rule; } int rule_alliance_limit(void) { - static int gamecookie = -1; - static int rule = -1; - if (rule < 0 || gamecookie != global.cookie) { - rule = get_param_int(global.parameters, "rules.limit.alliance", 0); - gamecookie = global.cookie; - assert(rule >= 0); - } - return rule; + static int gamecookie = -1; + static int rule = -1; + if (rule < 0 || gamecookie != global.cookie) { + rule = get_param_int(global.parameters, "rules.limit.alliance", 0); + gamecookie = global.cookie; + assert(rule >= 0); + } + return rule; } int rule_faction_limit(void) { - static int gamecookie = -1; - static int rule = -1; - if (rule < 0 || gamecookie != global.cookie) { - rule = get_param_int(global.parameters, "rules.limit.faction", 0); - gamecookie = global.cookie; - assert(rule >= 0); - } - return rule; + static int gamecookie = -1; + static int rule = -1; + if (rule < 0 || gamecookie != global.cookie) { + rule = get_param_int(global.parameters, "rules.limit.faction", 0); + gamecookie = global.cookie; + assert(rule >= 0); + } + return rule; } int rule_transfermen(void) { - static int gamecookie = -1; - static int rule = -1; - if (rule < 0 || gamecookie != global.cookie) { - rule = get_param_int(global.parameters, "rules.transfermen", 1); - gamecookie = global.cookie; - assert(rule >= 0); - } - return rule; + static int gamecookie = -1; + static int rule = -1; + if (rule < 0 || gamecookie != global.cookie) { + rule = get_param_int(global.parameters, "rules.transfermen", 1); + gamecookie = global.cookie; + assert(rule >= 0); + } + return rule; } static int default_wage(const region * r, const faction * f, const race * rc, int in_turn) { - building *b = largestbuilding(r, &cmp_wage, false); - int esize = 0; - curse *c; - double wage; - attrib *a; - const building_type *artsculpture_type = bt_find("artsculpture"); - static const curse_type *drought_ct, *blessedharvest_ct; - static bool init; + building *b = largestbuilding(r, &cmp_wage, false); + int esize = 0; + curse *c; + double wage; + attrib *a; + const building_type *artsculpture_type = bt_find("artsculpture"); + static const curse_type *drought_ct, *blessedharvest_ct; + static bool init; - if (!init) { - init = true; - drought_ct = ct_find("drought"); - blessedharvest_ct = ct_find("blessedharvest"); - } - - if (b != NULL) { - /* TODO: this reveals imaginary castles */ - esize = buildingeffsize(b, false); - } - - if (f != NULL) { - int index = 0; - if (rc == get_race(RC_ORC) || rc == get_race(RC_SNOTLING)) { - index = 1; + if (!init) { + init = true; + drought_ct = ct_find("drought"); + blessedharvest_ct = ct_find("blessedharvest"); } - wage = wagetable[esize][index]; - } else { - if (is_mourning(r, in_turn)) { - wage = 10; - } else if (fval(r->terrain, SEA_REGION)) { - wage = 11; - } else if (fval(r, RF_ORCIFIED)) { - wage = wagetable[esize][1]; - } else { - wage = wagetable[esize][2]; + + if (b != NULL) { + /* TODO: this reveals imaginary castles */ + esize = buildingeffsize(b, false); } - if (rule_blessed_harvest() == HARVEST_WORK) { - /* E1 rules */ - wage += curse_geteffect(get_curse(r->attribs, blessedharvest_ct)); + + if (f != NULL) { + int index = 0; + if (rc == get_race(RC_ORC) || rc == get_race(RC_SNOTLING)) { + index = 1; + } + wage = wagetable[esize][index]; } - } - - /* Artsculpture: Income +5 */ - for (b = r->buildings; b; b = b->next) { - if (b->type == artsculpture_type) { - wage += 5; + else { + if (is_mourning(r, in_turn)) { + wage = 10; + } + else if (fval(r->terrain, SEA_REGION)) { + wage = 11; + } + else if (fval(r, RF_ORCIFIED)) { + wage = wagetable[esize][1]; + } + else { + wage = wagetable[esize][2]; + } + if (rule_blessed_harvest() == HARVEST_WORK) { + /* E1 rules */ + wage += curse_geteffect(get_curse(r->attribs, blessedharvest_ct)); + } } - } - /* Godcurse: Income -10 */ - if (curse_active(get_curse(r->attribs, ct_find("godcursezone")))) { - wage = _max(0, wage - 10); - } + /* Artsculpture: Income +5 */ + for (b = r->buildings; b; b = b->next) { + if (b->type == artsculpture_type) { + wage += 5; + } + } - /* Bei einer Dürre verdient man nur noch ein Viertel */ - if (drought_ct) { - c = get_curse(r->attribs, drought_ct); - if (curse_active(c)) - wage /= curse_geteffect(c); - } + /* Godcurse: Income -10 */ + if (curse_active(get_curse(r->attribs, ct_find("godcursezone")))) { + wage = _max(0, wage - 10); + } - a = a_find(r->attribs, &at_reduceproduction); - if (a) - wage = (wage * a->data.sa[0]) / 100; + /* Bei einer Dürre verdient man nur noch ein Viertel */ + if (drought_ct) { + c = get_curse(r->attribs, drought_ct); + if (curse_active(c)) + wage /= curse_geteffect(c); + } - return (int)wage; + a = a_find(r->attribs, &at_reduceproduction); + if (a) + wage = (wage * a->data.sa[0]) / 100; + + return (int)wage; } static int minimum_wage(const region * r, const faction * f, const race * rc, int in_turn) { - if (f && rc) { - return rc->maintenance; - } - return default_wage(r, f, rc, in_turn); + if (f && rc) { + return rc->maintenance; + } + return default_wage(r, f, rc, in_turn); } /* Gibt Arbeitslohn für entsprechende Rasse zurück, oder für * die Bauern wenn f == NULL. */ int wage(const region * r, const faction * f, const race * rc, int in_turn) { - if (global.functions.wage) { - return global.functions.wage(r, f, rc, in_turn); - } - return default_wage(r, f, rc, in_turn); + if (global.functions.wage) { + return global.functions.wage(r, f, rc, in_turn); + } + return default_wage(r, f, rc, in_turn); } #define MAINTENANCE 10 int maintenance_cost(const struct unit *u) { - if (u == NULL) - return MAINTENANCE; - if (global.functions.maintenance) { - int retval = global.functions.maintenance(u); - if (retval >= 0) - return retval; - } - return u_race(u)->maintenance * u->number; + if (u == NULL) + return MAINTENANCE; + if (global.functions.maintenance) { + int retval = global.functions.maintenance(u); + if (retval >= 0) + return retval; + } + return u_race(u)->maintenance * u->number; } message *movement_error(unit * u, const char *token, order * ord, - int error_code) + int error_code) { - direction_t d; - switch (error_code) { - case E_MOVE_BLOCKED: - d = get_direction(token, u->faction->locale); - return msg_message("moveblocked", "unit direction", u, d); - case E_MOVE_NOREGION: - return msg_feedback(u, ord, "unknowndirection", "dirname", token); - } - return NULL; + direction_t d; + switch (error_code) { + case E_MOVE_BLOCKED: + d = get_direction(token, u->faction->locale); + return msg_message("moveblocked", "unit direction", u, d); + case E_MOVE_NOREGION: + return msg_feedback(u, ord, "unknowndirection", "dirname", token); + } + return NULL; } int movewhere(const unit * u, const char *token, region * r, region ** resultp) { - region *r2; - direction_t d; + region *r2; + direction_t d; - if (*token == '\0') { - *resultp = NULL; + if (*token == '\0') { + *resultp = NULL; + return E_MOVE_OK; + } + + d = get_direction(token, u->faction->locale); + switch (d) { + case D_PAUSE: + *resultp = r; + break; + + case NODIRECTION: + r2 = find_special_direction(r, token, u->faction->locale); + if (r2 == NULL) { + return E_MOVE_NOREGION; + } + *resultp = r2; + break; + + default: + r2 = rconnect(r, d); + if (r2 == NULL || move_blocked(u, r, r2)) { + return E_MOVE_BLOCKED; + } + *resultp = r2; + } return E_MOVE_OK; - } - - d = get_direction(token, u->faction->locale); - switch (d) { - case D_PAUSE: - *resultp = r; - break; - - case NODIRECTION: - r2 = find_special_direction(r, token, u->faction->locale); - if (r2 == NULL) { - return E_MOVE_NOREGION; - } - *resultp = r2; - break; - - default: - r2 = rconnect(r, d); - if (r2 == NULL || move_blocked(u, r, r2)) { - return E_MOVE_BLOCKED; - } - *resultp = r2; - } - return E_MOVE_OK; } bool move_blocked(const unit * u, const region * r, const region * r2) { - connection *b; - curse *c; - static const curse_type *fogtrap_ct = NULL; + connection *b; + curse *c; + static const curse_type *fogtrap_ct = NULL; - if (r2 == NULL) - return true; - b = get_borders(r, r2); - while (b) { - if (b->type->block && b->type->block(b, u, r)) - return true; - b = b->next; - } + if (r2 == NULL) + return true; + b = get_borders(r, r2); + while (b) { + if (b->type->block && b->type->block(b, u, r)) + return true; + b = b->next; + } - if (fogtrap_ct == NULL) - fogtrap_ct = ct_find("fogtrap"); - c = get_curse(r->attribs, fogtrap_ct); - if (curse_active(c)) - return true; - return false; + if (fogtrap_ct == NULL) + fogtrap_ct = ct_find("fogtrap"); + c = get_curse(r->attribs, fogtrap_ct); + if (curse_active(c)) + return true; + return false; } void add_income(unit * u, int type, int want, int qty) { - if (want == INT_MAX) - want = qty; - ADDMSG(&u->faction->msgs, msg_message("income", - "unit region mode wanted amount", u, u->region, type, want, qty)); + if (want == INT_MAX) + want = qty; + ADDMSG(&u->faction->msgs, msg_message("income", + "unit region mode wanted amount", u, u->region, type, want, qty)); } int produceexp(struct unit *u, skill_t sk, int n) { - if (global.producexpchance > 0.0F) { - if (n == 0 || !playerrace(u_race(u))) - return 0; - learn_skill(u, sk, global.producexpchance); - } - return 0; + if (global.producexpchance > 0.0F) { + if (n == 0 || !playerrace(u_race(u))) + return 0; + learn_skill(u, sk, global.producexpchance); + } + return 0; } int lovar(double xpct_x2) { - int n = (int)(xpct_x2 * 500) + 1; - if (n == 0) - return 0; - return (rng_int() % n + rng_int() % n) / 1000; + int n = (int)(xpct_x2 * 500) + 1; + if (n == 0) + return 0; + return (rng_int() % n + rng_int() % n) / 1000; } bool has_limited_skills(const struct unit * u) { - if (has_skill(u, SK_MAGIC) || has_skill(u, SK_ALCHEMY) || - has_skill(u, SK_TACTICS) || has_skill(u, SK_HERBALISM) || - has_skill(u, SK_SPY)) { - return true; - } else { - return false; - } + if (has_skill(u, SK_MAGIC) || has_skill(u, SK_ALCHEMY) || + has_skill(u, SK_TACTICS) || has_skill(u, SK_HERBALISM) || + has_skill(u, SK_SPY)) { + return true; + } + else { + return false; + } } void attrib_init(void) { - /* Alle speicherbaren Attribute müssen hier registriert werden */ - at_register(&at_shiptrail); - at_register(&at_familiar); - at_register(&at_familiarmage); - at_register(&at_clone); - at_register(&at_clonemage); - at_register(&at_eventhandler); - at_register(&at_stealth); - at_register(&at_mage); - at_register(&at_countdown); - at_register(&at_curse); + /* Alle speicherbaren Attribute müssen hier registriert werden */ + at_register(&at_shiptrail); + at_register(&at_familiar); + at_register(&at_familiarmage); + at_register(&at_clone); + at_register(&at_clonemage); + at_register(&at_eventhandler); + at_register(&at_stealth); + at_register(&at_mage); + at_register(&at_countdown); + at_register(&at_curse); - at_register(&at_seenspell); + at_register(&at_seenspell); - /* neue REGION-Attribute */ - at_register(&at_direction); - at_register(&at_moveblock); - at_register(&at_deathcount); - at_register(&at_chaoscount); - at_register(&at_woodcount); + /* neue REGION-Attribute */ + at_register(&at_direction); + at_register(&at_moveblock); + at_register(&at_deathcount); + at_register(&at_chaoscount); + at_register(&at_woodcount); - /* neue UNIT-Attribute */ - at_register(&at_siege); - at_register(&at_effect); - at_register(&at_private); + /* neue UNIT-Attribute */ + at_register(&at_siege); + at_register(&at_effect); + at_register(&at_private); - at_register(&at_icastle); - at_register(&at_guard); - at_register(&at_group); + at_register(&at_icastle); + at_register(&at_guard); + at_register(&at_group); - at_register(&at_building_generic_type); - at_register(&at_maxmagicians); - at_register(&at_npcfaction); + at_register(&at_building_generic_type); + at_register(&at_maxmagicians); + at_register(&at_npcfaction); - /* connection-typen */ - register_bordertype(&bt_noway); - register_bordertype(&bt_fogwall); - register_bordertype(&bt_wall); - register_bordertype(&bt_illusionwall); - register_bordertype(&bt_road); + /* connection-typen */ + register_bordertype(&bt_noway); + register_bordertype(&bt_fogwall); + register_bordertype(&bt_wall); + register_bordertype(&bt_illusionwall); + register_bordertype(&bt_road); - register_function((pf_generic) & minimum_wage, "minimum_wage"); + register_function((pf_generic)& minimum_wage, "minimum_wage"); - at_register(&at_germs); + at_register(&at_germs); - at_deprecate("xontormiaexpress", a_readint); /* required for old datafiles */ - at_register(&at_speedup); - at_register(&at_building_action); + at_deprecate("xontormiaexpress", a_readint); /* required for old datafiles */ + at_register(&at_speedup); + at_register(&at_building_action); } void kernel_init(void) @@ -2794,55 +2820,56 @@ static order * defaults[MAXLOCALES]; order *default_order(const struct locale *lang) { - static int usedefault = 1; - int i = locale_index(lang); - order *result = 0; - assert(iattribs, C_DEPRESSION, 0)) { - return 0; - } + if (is_cursed(r->attribs, C_DEPRESSION, 0)) { + return 0; + } - n = rmoney(r) / ENTERTAINFRACTION; + n = rmoney(r) / ENTERTAINFRACTION; - if (is_cursed(r->attribs, C_GENEROUS, 0)) { - n *= get_curseeffect(r->attribs, C_GENEROUS, 0); - } + if (is_cursed(r->attribs, C_GENEROUS, 0)) { + n *= get_curseeffect(r->attribs, C_GENEROUS, 0); + } - return (int)n; + return (int)n; } int rule_give(void) { - static int value = -1; - if (value < 0) { - value = get_param_int(global.parameters, "rules.give", GIVE_DEFAULT); - } - return value; + static int value = -1; + if (value < 0) { + value = get_param_int(global.parameters, "rules.give", GIVE_DEFAULT); + } + return value; } int markets_module(void) { - static int value = -1; - if (value < 0) { - value = get_param_int(global.parameters, "modules.markets", 0); - } - return value; + static int value = -1; + if (value < 0) { + value = get_param_int(global.parameters, "modules.markets", 0); + } + return value; } /** releases all memory associated with the game state. @@ -2851,78 +2878,92 @@ int markets_module(void) */ void free_gamedata(void) { - int i; - free_units(); - free_regions(); - free_borders(); + int i; + free_units(); + free_regions(); + free_borders(); - for (i=0;i!=MAXLOCALES;++i) { - if (defaults[i]) { - free_order(defaults[i]); - defaults[i] = 0; + for (i = 0; i != MAXLOCALES; ++i) { + if (defaults[i]) { + free_order(defaults[i]); + defaults[i] = 0; + } + } + while (alliances) { + alliance *al = alliances; + alliances = al->next; + free_alliance(al); + } + while (factions) { + faction *f = factions; + factions = f->next; + funhash(f); + free_faction(f); + free(f); } - } - while (alliances) { - alliance *al = alliances; - alliances = al->next; - free_alliance(al); - } - while (factions) { - faction *f = factions; - factions = f->next; - funhash(f); - free_faction(f); - free(f); - } - while (planes) { - plane *pl = planes; - planes = planes->next; - free(pl->name); - free(pl); - } + while (planes) { + plane *pl = planes; + planes = planes->next; + free(pl->name); + free(pl); + } - while (global.attribs) { - a_remove(&global.attribs, global.attribs); - } - ++global.cookie; /* readgame() already does this, but sjust in case */ + while (global.attribs) { + a_remove(&global.attribs, global.attribs); + } + ++global.cookie; /* readgame() already does this, but sjust in case */ - init_resources(); + init_resources(); +} + +const char * game_name(void) { + const char * param = get_param(global.parameters, "game.name"); + return param ? param : global.gamename; +} + +int game_id(void) { + return get_param_int(global.parameters, "game.id", global.game_id); } void load_inifile(dictionary * d) { - const char *reportdir = reportpath(); - const char *datadir = datapath(); - const char *basedir = basepath(); - const char *str; + const char *reportdir = reportpath(); + const char *datadir = datapath(); + const char *basedir = basepath(); + const char *str; - assert(d); + assert(d); - str = iniparser_getstring(d, "eressea:base", basedir); - if (str != basedir) - set_basepath(str); - str = iniparser_getstring(d, "eressea:report", reportdir); - if (str != reportdir) - set_reportpath(str); - str = iniparser_getstring(d, "eressea:data", datadir); - if (str != datadir) - set_datapath(str); + str = iniparser_getstring(d, "eressea:base", basedir); + if (str != basedir) { + set_basepath(str); + } + str = iniparser_getstring(d, "eressea:report", reportdir); + if (str != reportdir) { + set_reportpath(str); + } + str = iniparser_getstring(d, "eressea:data", datadir); + if (str != datadir) { + set_datapath(str); + } - lomem = iniparser_getint(d, "eressea:lomem", lomem) ? 1 : 0; + lomem = iniparser_getint(d, "eressea:lomem", lomem) ? 1 : 0; - str = iniparser_getstring(d, "eressea:encoding", NULL); - if (str && (_strcmpl(str, "utf8")==0 || _strcmpl(str, "utf-8")==0)) { - enc_gamedata = ENCODING_UTF8; - } + str = iniparser_getstring(d, "eressea:encoding", NULL); + if (str && (_strcmpl(str, "utf8") == 0 || _strcmpl(str, "utf-8") == 0)) { + enc_gamedata = ENCODING_UTF8; + } - verbosity = iniparser_getint(d, "eressea:verbose", 2); - battledebug = iniparser_getint(d, "eressea:debug", battledebug) ? 1 : 0; + verbosity = iniparser_getint(d, "eressea:verbose", 2); + battledebug = iniparser_getint(d, "eressea:debug", battledebug) ? 1 : 0; - str = iniparser_getstring(d, "eressea:locales", "de,en"); - make_locales(str); + str = iniparser_getstring(d, "eressea:locales", "de,en"); + make_locales(str); - /* excerpt from [config] (the rest is used in bindings.c) */ - global.game_id = iniparser_getint(d, "config:game_id", 0); - global.inifile = d; + /* excerpt from [config] (the rest is used in bindings.c) */ + global.game_id = iniparser_getint(d, "config:game_id", 0); + + if (global.inifile) iniparser_free(global.inifile); + global.inifile = d; } diff --git a/src/kernel/config.h b/src/kernel/config.h index 859f5e0a6..958beef42 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -1,7 +1,7 @@ /* Copyright (c) 1998-2010, Enno Rehling - Katja Zedel +Katja Zedel Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -23,13 +23,13 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. extern "C" { #endif - /* this should always be the first thing included after platform.h */ + /* this should always be the first thing included after platform.h */ #include "types.h" - struct _dictionary_; - struct critbit_tree; - /* experimental gameplay features (that don't affect the savefile) */ - /* TODO: move these settings to settings.h or into configuration files */ + struct _dictionary_; + struct critbit_tree; + /* experimental gameplay features (that don't affect the savefile) */ + /* TODO: move these settings to settings.h or into configuration files */ #define GOBLINKILL /* Goblin-Spezialklau kann tödlich enden */ #define HERBS_ROT /* herbs owned by units have a chance to rot. */ #define SHIPDAMAGE /* Schiffsbeschädigungen */ @@ -38,7 +38,7 @@ extern "C" { #define ALLIED(f1, f2) (f1==f2 || (f1->alliance && f1->alliance==f2->alliance)) -/* for some good prime numbers, check http://www.math.niu.edu/~rusin/known-math/98/pi_x */ + /* for some good prime numbers, check http://www.math.niu.edu/~rusin/known-math/98/pi_x */ #ifndef MAXREGIONS # define MAXREGIONS 524287 /* must be prime for hashing. 262139 was a little small */ #endif @@ -52,23 +52,23 @@ extern "C" { #define PEASANTFORCE 0.75 /* Chance einer Vermehrung trotz 90% Auslastung */ #define HERBROTCHANCE 5 /* Verrottchance für Kräuter (ifdef HERBS_ROT) */ -/* Gebäudegröße = Minimalbelagerer */ + /* Gebäudegröße = Minimalbelagerer */ #define SIEGEFACTOR 2 -/** Magic */ + /** Magic */ #define MAXMAGICIANS 3 #define MAXALCHEMISTS 3 -/** Plagues **/ + /** Plagues **/ #define PLAGUE_CHANCE 0.1F /* Seuchenwahrscheinlichkeit (siehe plagues()) */ #define PLAGUE_VICTIMS 0.2F /* % Betroffene */ #define PLAGUE_HEALCHANCE 0.25F /* Wahrscheinlichkeit Heilung */ #define PLAGUE_HEALCOST 30 /* Heilkosten */ -/* Chance of a monster attack */ + /* Chance of a monster attack */ #define MONSTERATTACK 0.4F -/* Bewegungsweiten: */ + /* Bewegungsweiten: */ #define BP_WALKING 4 #define BP_RIDING 6 #define BP_UNICORN 9 @@ -80,10 +80,10 @@ extern "C" { #define PERSON_WEIGHT 1000 /* weight of a "normal" human unit */ #define STAMINA_AFFECTS_HP 1<<0 -/** - * Hier endet der Teil von config.h, der die defines für die - * Spielwelt Eressea enthält, und beginnen die allgemeinen Routinen - */ + /** + * Hier endet der Teil von config.h, der die defines für die + * Spielwelt Eressea enthält, und beginnen die allgemeinen Routinen + */ #define ENCCHANCE 10 /* %-Chance für einmalige Zufallsbegegnung */ @@ -92,75 +92,67 @@ extern "C" { #define IDSIZE 16 /* max. Länge einer no (als String), incl trailing 0 */ #define KEYWORDSIZE 16 /* max. Länge eines Keyword, incl trailing 0 */ #define OBJECTIDSIZE (NAMESIZE+5+IDSIZE) /* max. Länge der Strings, die - * von struct unitname, etc. zurückgegeben werden. ohne die 0 */ + * von struct unitname, etc. zurückgegeben werden. ohne die 0 */ #define BAGCAPACITY 20000 /* soviel paßt in einen Bag of Holding */ #define STRENGTHCAPACITY 50000 /* zusätzliche Tragkraft beim Kraftzauber (deprecated) */ #define STRENGTHMULTIPLIER 50 /* multiplier for trollbelt */ -/* ----------------- Befehle ----------------------------------- */ + /* ----------------- Befehle ----------------------------------- */ - extern const char *parameters[MAXPARAMS]; - -/** report options **/ #define want(option) (1<flags & (i)) #define fset(u, i) ((u)->flags |= (i)) #define freset(u, i) ((u)->flags &= ~(i)) - extern int turn; - extern int verbosity; + /* parteinummern */ + bool faction_id_is_unused(int); -/* parteinummern */ - bool faction_id_is_unused(int); + int max_magicians(const struct faction * f); + /* leuchtturm */ + bool check_leuchtturm(struct region *r, struct faction *f); + void update_lighthouse(struct building *lh); + int lighthouse_range(const struct building *b, + const struct faction *f); -int max_magicians(const struct faction * f); -/* leuchtturm */ - bool check_leuchtturm(struct region *r, struct faction *f); - void update_lighthouse(struct building *lh); - int lighthouse_range(const struct building *b, - const struct faction *f); + int findoption(const char *s, const struct locale *lang); - int findoption(const char *s, const struct locale *lang); + /* special units */ + void make_undead_unit(struct unit *); -/* special units */ - void make_undead_unit(struct unit *); + void addstrlist(strlist ** SP, const char *s); - void addstrlist(strlist ** SP, const char *s); + int armedmen(const struct unit *u, bool siege_weapons); - int armedmen(const struct unit *u, bool siege_weapons); + unsigned int atoip(const char *s); + unsigned int getuint(void); + int getint(void); - unsigned int atoip(const char *s); - unsigned int getuint(void); - int getint(void); + const char *igetstrtoken(const char *s); - const char *igetstrtoken(const char *s); + param_t findparam(const char *s, const struct locale *lang); + param_t findparam_ex(const char *s, const struct locale * lang); + bool isparam(const char *s, const struct locale * lang, param_t param); + param_t getparam(const struct locale *lang); - param_t findparam(const char *s, const struct locale *lang); - param_t findparam_ex(const char *s, const struct locale * lang); - bool isparam(const char *s, const struct locale * lang, param_t param); - param_t getparam(const struct locale *lang); - - int getid(void); + int getid(void); #define unitid(x) itoa36((x)->no) #define getshipid() getid() @@ -171,85 +163,86 @@ int max_magicians(const struct faction * f); #define factionid(x) itoa36((x)->no) #define curseid(x) itoa36((x)->no) - bool cansee(const struct faction *f, const struct region *r, - const struct unit *u, int modifier); - bool cansee_durchgezogen(const struct faction *f, const struct region *r, - const struct unit *u, int modifier); - bool cansee_unit(const struct unit *u, const struct unit *target, - int modifier); - bool seefaction(const struct faction *f, const struct region *r, - const struct unit *u, int modifier); + bool cansee(const struct faction *f, const struct region *r, + const struct unit *u, int modifier); + bool cansee_durchgezogen(const struct faction *f, const struct region *r, + const struct unit *u, int modifier); + bool cansee_unit(const struct unit *u, const struct unit *target, + int modifier); + bool seefaction(const struct faction *f, const struct region *r, + const struct unit *u, int modifier); - int lovar(double xpct_x2); - /* returns a value between [0..xpct_2], generated with two dice */ + const char * game_name(void); + int game_id(void); + int lovar(double xpct_x2); + /* returns a value between [0..xpct_2], generated with two dice */ - int distribute(int old, int new_value, int n); - void init_locales(void); + int distribute(int old, int new_value, int n); + void init_locales(void); - int newunitid(void); - int forbiddenid(int id); - int newcontainerid(void); + int newunitid(void); + int forbiddenid(int id); + int newcontainerid(void); - struct unit *createunit(struct region *r, struct faction *f, - int number, const struct race *rc); - void create_unitid(struct unit *u, int id); - extern bool getunitpeasants; - struct unit *getunitg(const struct region *r, const struct faction *f); - struct unit *getunit(const struct region *r, const struct faction *f); + struct unit *createunit(struct region *r, struct faction *f, + int number, const struct race *rc); + void create_unitid(struct unit *u, int id); + struct unit *getunitg(const struct region *r, const struct faction *f); + struct unit *getunit(const struct region *r, const struct faction *f); - int read_unitid(const struct faction *f, const struct region *r); + int read_unitid(const struct faction *f, const struct region *r); - int alliedunit(const struct unit *u, const struct faction *f2, - int mode); - int alliedfaction(const struct plane *pl, const struct faction *f, - const struct faction *f2, int mode); - int alliedgroup(const struct plane *pl, const struct faction *f, - const struct faction *f2, const struct ally *sf, int mode); + int alliedunit(const struct unit *u, const struct faction *f2, + int mode); + int alliedfaction(const struct plane *pl, const struct faction *f, + const struct faction *f2, int mode); + int alliedgroup(const struct plane *pl, const struct faction *f, + const struct faction *f2, const struct ally *sf, int mode); - struct faction *findfaction(int n); - struct faction *getfaction(void); + struct faction *findfaction(int n); + struct faction *getfaction(void); - struct unit *findunitg(int n, const struct region *hint); - struct unit *findunit(int n); + struct unit *findunitg(int n, const struct region *hint); + struct unit *findunit(int n); - struct unit *findunitr(const struct region *r, int n); - struct region *findunitregion(const struct unit *su); + struct unit *findunitr(const struct region *r, int n); + struct region *findunitregion(const struct unit *su); - char *estring(const char *s); - char *estring_i(char *s); - char *cstring(const char *s); - char *cstring_i(char *s); - const char *unitname(const struct unit *u); - char *write_unitname(const struct unit *u, char *buffer, size_t size); + char *estring(const char *s); + char *estring_i(char *s); + char *cstring(const char *s); + char *cstring_i(char *s); + const char *unitname(const struct unit *u); + char *write_unitname(const struct unit *u, char *buffer, size_t size); - typedef int (*cmp_building_cb) (const struct building * b, - const struct building * a); - struct building *largestbuilding(const struct region *r, cmp_building_cb, - bool imaginary); - int cmp_wage(const struct building *b, const struct building *bother); - int cmp_taxes(const struct building *b, const struct building *bother); - int cmp_current_owner(const struct building *b, - const struct building *bother); + typedef int(*cmp_building_cb) (const struct building * b, + const struct building * a); + struct building *largestbuilding(const struct region *r, cmp_building_cb, + bool imaginary); + int cmp_wage(const struct building *b, const struct building *bother); + int cmp_taxes(const struct building *b, const struct building *bother); + int cmp_current_owner(const struct building *b, + const struct building *bother); #define TAX_ORDER 0x00 #define TAX_OWNER 0x01 - int rule_auto_taxation(void); - int rule_transfermen(void); - int rule_region_owners(void); - int rule_stealth_faction(void); + int rule_auto_taxation(void); + int rule_transfermen(void); + int rule_region_owners(void); + int rule_stealth_faction(void); #define HARVEST_WORK 0x00 #define HARVEST_TAXES 0x01 - int rule_blessed_harvest(void); - int rule_give(void); - int rule_alliance_limit(void); - int rule_faction_limit(void); + int rule_blessed_harvest(void); + int rule_give(void); + int rule_alliance_limit(void); + int rule_faction_limit(void); #define COUNT_MONSTERS 0x01 #define COUNT_MIGRANTS 0x02 #define COUNT_DEFAULT 0x04 #define COUNT_ALL 0x07 #define COUNT_UNITS 0x10 - + int count_faction(const struct faction * f, int flags); int count_migrants(const struct faction * f); int count_maxmigrants(const struct faction * f); @@ -262,166 +255,159 @@ int max_magicians(const struct faction * f); int eff_stealth(const struct unit *u, const struct region *r); int ispresent(const struct faction *f, const struct region *r); - int check_option(struct faction *f, int option); + int check_option(struct faction *f, int option); -/* Anzahl Personen in einer Einheit festlegen. NUR (!) mit dieser Routine, - * sonst großes Unglück. Durch asserts an ein paar Stellen abgesichert. */ - void verify_data(void); + /* Anzahl Personen in einer Einheit festlegen. NUR (!) mit dieser Routine, + * sonst großes Unglück. Durch asserts an ein paar Stellen abgesichert. */ + void verify_data(void); - void freestrlist(strlist * s); + void freestrlist(strlist * s); - int change_hitpoints(struct unit *u, int value); + int change_hitpoints(struct unit *u, int value); - int weight(const struct unit *u); - void changeblockchaos(void); + int weight(const struct unit *u); + void changeblockchaos(void); -/* intervall, in dem die regionen der partei zu finden sind */ - struct region *firstregion(struct faction *f); - struct region *lastregion(struct faction *f); + /* intervall, in dem die regionen der partei zu finden sind */ + struct region *firstregion(struct faction *f); + struct region *lastregion(struct faction *f); - void fhash(struct faction *f); - void funhash(struct faction *f); + void fhash(struct faction *f); + void funhash(struct faction *f); - bool idle(struct faction *f); - bool unit_has_cursed_item(struct unit *u); + bool idle(struct faction *f); + bool unit_has_cursed_item(struct unit *u); -/* simple garbage collection: */ - void *gc_add(void *p); + /* simple garbage collection: */ + void *gc_add(void *p); -/* grammatik-flags: */ + /* grammatik-flags: */ #define GF_NONE 0 - /* singular, ohne was dran */ + /* singular, ohne was dran */ #define GF_PLURAL 1 - /* Angaben in Mehrzahl */ + /* Angaben in Mehrzahl */ #define GF_ARTICLE 8 - /* der, die, eine */ + /* der, die, eine */ #define GF_SPECIFIC 16 - /* der, die, das vs. ein, eine */ + /* der, die, das vs. ein, eine */ #define GF_DETAILED 32 - /* mehr Informationen. z.b. straße zu 50% */ + /* mehr Informationen. z.b. straße zu 50% */ #define GF_PURE 64 - /* untranslated */ + /* untranslated */ #define GUARD_NONE 0 #define GUARD_TAX 1 - /* Verhindert Steuereintreiben */ + /* Verhindert Steuereintreiben */ #define GUARD_MINING 2 - /* Verhindert Bergbau */ + /* Verhindert Bergbau */ #define GUARD_TREES 4 - /* Verhindert Waldarbeiten */ + /* Verhindert Waldarbeiten */ #define GUARD_TRAVELTHRU 8 - /* Blockiert Durchreisende */ + /* Blockiert Durchreisende */ #define GUARD_LANDING 16 - /* Verhindert Ausstieg + Weiterreise */ + /* Verhindert Ausstieg + Weiterreise */ #define GUARD_CREWS 32 - /* Verhindert Unterhaltung auf Schiffen */ + /* Verhindert Unterhaltung auf Schiffen */ #define GUARD_RECRUIT 64 - /* Verhindert Rekrutieren */ + /* Verhindert Rekrutieren */ #define GUARD_PRODUCE 128 - /* Verhindert Abbau von Resourcen mit RTF_LIMITED */ + /* Verhindert Abbau von Resourcen mit RTF_LIMITED */ #define GUARD_ALL 0xFFFF - void setstatus(struct unit *u, int status); -/* !< sets combatstatus of a unit */ - void setguard(struct unit *u, unsigned int flags); -/* !< setzt die guard-flags der Einheit */ - unsigned int getguard(const struct unit *u); - /* liest die guard-flags der Einheit */ - void guard(struct unit *u, unsigned int mask); - /* Einheit setzt "BEWACHE", rassenspezifzisch. - * 'mask' kann einzelne flags zusätzlich und-maskieren. - */ - unsigned int guard_flags(const struct unit *u); + void setstatus(struct unit *u, int status); + /* !< sets combatstatus of a unit */ + void setguard(struct unit *u, unsigned int flags); + /* !< setzt die guard-flags der Einheit */ + unsigned int getguard(const struct unit *u); + /* liest die guard-flags der Einheit */ + void guard(struct unit *u, unsigned int mask); + /* Einheit setzt "BEWACHE", rassenspezifzisch. + * 'mask' kann einzelne flags zusätzlich und-maskieren. + */ + unsigned int guard_flags(const struct unit *u); - bool hunger(int number, struct unit *u); - int lifestyle(const struct unit *); - int besieged(const struct unit *u); - int maxworkingpeasants(const struct region *r); - bool has_horses(const struct unit *u); - int markets_module(void); - int wage(const struct region *r, const struct faction *f, - const struct race *rc, int in_turn); - int maintenance_cost(const struct unit *u); - struct message *movement_error(struct unit *u, const char *token, + bool hunger(int number, struct unit *u); + int lifestyle(const struct unit *); + int besieged(const struct unit *u); + int maxworkingpeasants(const struct region *r); + bool has_horses(const struct unit *u); + int markets_module(void); + int wage(const struct region *r, const struct faction *f, + const struct race *rc, int in_turn); + int maintenance_cost(const struct unit *u); + struct message *movement_error(struct unit *u, const char *token, struct order *ord, int error_code); - bool move_blocked(const struct unit *u, const struct region *src, - const struct region *dest); - void add_income(struct unit *u, int type, int want, int qty); + bool move_blocked(const struct unit *u, const struct region *src, + const struct region *dest); + void add_income(struct unit *u, int type, int want, int qty); -/* movewhere error codes */ - enum { - E_MOVE_OK = 0, /* possible to move */ - E_MOVE_NOREGION, /* no region exists in this direction */ - E_MOVE_BLOCKED /* cannot see this region, there is a blocking connection. */ - }; - int movewhere(const struct unit *u, const char *token, + /* movewhere error codes */ + enum { + E_MOVE_OK = 0, /* possible to move */ + E_MOVE_NOREGION, /* no region exists in this direction */ + E_MOVE_BLOCKED /* cannot see this region, there is a blocking connection. */ + }; + int movewhere(const struct unit *u, const char *token, struct region *r, struct region **resultp); - const char *datapath(void); - void set_datapath(const char *path); + const char *datapath(void); + void set_datapath(const char *path); - const char *basepath(void); - void set_basepath(const char *); - void load_inifile(struct _dictionary_ *d); + const char *basepath(void); + void set_basepath(const char *); + void load_inifile(struct _dictionary_ *d); - const char *reportpath(void); - void set_reportpath(const char *); + const char *reportpath(void); + void set_reportpath(const char *); - void kernel_init(void); - void kernel_done(void); + void kernel_init(void); + void kernel_done(void); - extern const char *localenames[]; + /* globale settings des Spieles */ + typedef struct settings { + const char *gamename; + struct attrib *attribs; + unsigned int data_turn; + struct param *parameters; + void *vm_state; + float producexpchance; + int cookie; + int game_id; + int data_version; /* TODO: eliminate in favor of gamedata.version */ + struct _dictionary_ *inifile; -/* globale settings des Spieles */ - typedef struct settings { - const char *gamename; - struct attrib *attribs; - unsigned int data_turn; - struct param *parameters; - void *vm_state; - float producexpchance; - int cookie; - int game_id; - int data_version; /* TODO: eliminate in favor of gamedata.version */ - struct _dictionary_ *inifile; + struct global_functions { + int(*wage) (const struct region * r, const struct faction * f, + const struct race * rc, int in_turn); + int(*maintenance) (const struct unit * u); + } functions; + } settings; - struct global_functions { - int (*wage) (const struct region * r, const struct faction * f, - const struct race * rc, int in_turn); - int (*maintenance) (const struct unit * u); - } functions; - } settings; - extern settings global; + typedef struct helpmode { + const char *name; + int status; + } helpmode; - extern bool battledebug; - extern bool sqlpatch; - extern bool lomem; /* save memory */ + const char *dbrace(const struct race *rc); - const char *dbrace(const struct race *rc); + void set_param(struct param **p, const char *name, const char *data); + const char *get_param(const struct param *p, const char *name); + int get_param_int(const struct param *p, const char *name, int def); + float get_param_flt(const struct param *p, const char *name, float def); - void set_param(struct param **p, const char *name, const char *data); - const char *get_param(const struct param *p, const char *name); - int get_param_int(const struct param *p, const char *name, int def); - float get_param_flt(const struct param *p, const char *name, float def); + bool ExpensiveMigrants(void); + int NMRTimeout(void); + int LongHunger(const struct unit *u); + int NewbieImmunity(void); + bool IsImmune(const struct faction *f); + int AllianceAuto(void); /* flags that allied factions get automatically */ + int AllianceRestricted(void); /* flags restricted to allied factions */ + int HelpMask(void); /* flags restricted to allied factions */ + struct order *default_order(const struct locale *lang); + int entertainmoney(const struct region *r); - bool ExpensiveMigrants(void); - int NMRTimeout(void); - int LongHunger(const struct unit *u); - int NewbieImmunity(void); - bool IsImmune(const struct faction *f); - int AllianceAuto(void); /* flags that allied factions get automatically */ - int AllianceRestricted(void); /* flags restricted to allied factions */ - int HelpMask(void); /* flags restricted to allied factions */ - struct order *default_order(const struct locale *lang); - int entertainmoney(const struct region *r); - - void plagues(struct region *r, bool ismagic); - typedef struct helpmode { - const char *name; - int status; - } helpmode; - - extern struct helpmode helpmodes[]; + void plagues(struct region *r, bool ismagic); + void free_gamedata(void); #define GIVE_SELF 1 #define GIVE_PEASANTS 2 @@ -432,8 +418,38 @@ int max_magicians(const struct faction * f); #define GIVE_ALLITEMS (GIVE_GOODS|GIVE_HERBS|GIVE_LUXURIES) #define GIVE_DEFAULT (GIVE_SELF|GIVE_PEASANTS|GIVE_LUXURIES|GIVE_HERBS|GIVE_GOODS) - extern struct attrib_type at_guard; - void free_gamedata(void); + extern struct attrib_type at_guard; + extern struct helpmode helpmodes[]; + extern const char *parameters[]; + extern const char *localenames[]; + extern settings global; + + extern bool battledebug; + extern bool sqlpatch; + extern bool lomem; /* save memory */ + + extern int turn; + extern int verbosity; + extern bool getunitpeasants; + + /** report options **/ + extern const char *options[MAXOPTIONS]; + + extern struct helpmode helpmodes[]; + extern const char *parameters[]; + extern const char *localenames[]; + extern settings global; + + extern bool battledebug; + extern bool sqlpatch; + extern bool lomem; /* save memory */ + + extern int turn; + extern int verbosity; + extern bool getunitpeasants; + + /** report options **/ + extern const char *options[MAXOPTIONS]; #ifdef __cplusplus } diff --git a/src/kernel/save.c b/src/kernel/save.c index 1cae77a59..d34c0a2bc 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1,7 +1,7 @@ /* Copyright (c) 1998-2010, Enno Rehling - Katja Zedel +Katja Zedel Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -87,7 +87,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #define MAXPERSISTENT 128 /* exported symbols symbols */ -const char *game_name = "eressea"; int firstx = 0, firsty = 0; int enc_gamedata = ENCODING_UTF8; @@ -96,20 +95,20 @@ static region *current_region; char *rns(FILE * f, char *c, size_t size) { - char *s = c; - do { - *s = (char)getc(f); - } while (*s != '"'); + char *s = c; + do { + *s = (char)getc(f); + } while (*s != '"'); - for (;;) { - *s = (char)getc(f); - if (*s == '"') - break; - if (s < c + size) - ++s; - } - *s = 0; - return c; + for (;;) { + *s = (char)getc(f); + if (*s == '"') + break; + if (s < c + size) + ++s; + } + *s = 0; + return c; } extern unsigned int __at_hashkey(const char *s); @@ -117,222 +116,227 @@ extern unsigned int __at_hashkey(const char *s); static unit *unitorders(FILE * F, int enc, struct faction *f) { - int i; - unit *u; + int i; + unit *u; - if (!f) - return NULL; + if (!f) + return NULL; - i = getid(); - u = findunitg(i, NULL); + i = getid(); + u = findunitg(i, NULL); - if (u && u_race(u) == get_race(RC_SPELL)) - return NULL; - if (u && u->faction == f) { - order **ordp; + if (u && u_race(u) == get_race(RC_SPELL)) + return NULL; + if (u && u->faction == f) { + order **ordp; - if (!fval(u, UFL_ORDERS)) { - /* alle wiederholbaren, langen befehle werden gesichert: */ - fset(u, UFL_ORDERS); - u->old_orders = u->orders; - ordp = &u->old_orders; - while (*ordp) { - order *ord = *ordp; - if (!is_repeated(ord)) { - *ordp = ord->next; - ord->next = NULL; - free_order(ord); - } else { - ordp = &ord->next; + if (!fval(u, UFL_ORDERS)) { + /* alle wiederholbaren, langen befehle werden gesichert: */ + fset(u, UFL_ORDERS); + u->old_orders = u->orders; + ordp = &u->old_orders; + while (*ordp) { + order *ord = *ordp; + if (!is_repeated(ord)) { + *ordp = ord->next; + ord->next = NULL; + free_order(ord); + } + else { + ordp = &ord->next; + } + } } - } - } else { - free_orders(&u->orders); - } - u->orders = 0; + else { + free_orders(&u->orders); + } + u->orders = 0; - ordp = &u->orders; + ordp = &u->orders; - for (;;) { - const char *s; - /* Erst wenn wir sicher sind, dass kein Befehl - * eingegeben wurde, checken wir, ob nun eine neue - * Einheit oder ein neuer Spieler drankommt */ + for (;;) { + const char *s; + /* Erst wenn wir sicher sind, dass kein Befehl + * eingegeben wurde, checken wir, ob nun eine neue + * Einheit oder ein neuer Spieler drankommt */ - s = getbuf(F, enc); - if (s == NULL) - break; - - if (s[0]) { - if (s[0]!='@') { - const char *stok = s; - stok = parse_token(&stok); - - if (stok) { - bool quit = false; - param_t param = findparam(stok, u->faction->locale); - switch (param) { - case P_UNIT: - case P_REGION: - quit = true; - break; - case P_FACTION: - case P_NEXT: - case P_GAMENAME: - /* these terminate the orders, so we apply extra checking */ - if (strlen(stok) >= 3) { - quit = true; + s = getbuf(F, enc); + if (s == NULL) break; - } else { - quit = false; - } - break; - default: - /* TODO: syntax error message */ - break; - } - if (quit) { - break; - } - } - } - /* Nun wird der Befehl erzeut und eingehängt */ - *ordp = parse_order(s, u->faction->locale); - if (*ordp) { - ordp = &(*ordp)->next; - } - } - } - } else { - /* cmistake(?, buf, 160, MSG_EVENT); */ - return NULL; - } - return u; + if (s[0]) { + if (s[0] != '@') { + const char *stok = s; + stok = parse_token(&stok); + + if (stok) { + bool quit = false; + param_t param = findparam(stok, u->faction->locale); + switch (param) { + case P_UNIT: + case P_REGION: + quit = true; + break; + case P_FACTION: + case P_NEXT: + case P_GAMENAME: + /* these terminate the orders, so we apply extra checking */ + if (strlen(stok) >= 3) { + quit = true; + break; + } + else { + quit = false; + } + break; + default: + /* TODO: syntax error message */ + break; + } + if (quit) { + break; + } + } + } + /* Nun wird der Befehl erzeut und eingehängt */ + *ordp = parse_order(s, u->faction->locale); + if (*ordp) { + ordp = &(*ordp)->next; + } + } + } + + } + else { + /* cmistake(?, buf, 160, MSG_EVENT); */ + return NULL; + } + return u; } static faction *factionorders(void) { - faction *f = NULL; - int fid = getid(); + faction *f = NULL; + int fid = getid(); - f = findfaction(fid); + f = findfaction(fid); - if (f != NULL && !is_monsters(f)) { - const char *pass = getstrtoken(); + if (f != NULL && !is_monsters(f)) { + const char *pass = getstrtoken(); + + if (!checkpasswd(f, (const char *)pass, true)) { + log_debug("Invalid password for faction %s\n", itoa36(fid)); + ADDMSG(&f->msgs, msg_message("wrongpasswd", "faction password", + f->no, pass)); + return 0; + } + /* Die Partei hat sich zumindest gemeldet, so daß sie noch + * nicht als untätig gilt */ + + /* TODO: +1 ist ein Workaround, weil cturn erst in process_orders + * incrementiert wird. */ + f->lastorders = global.data_turn + 1; - if (!checkpasswd(f, (const char *)pass, true)) { - log_debug("Invalid password for faction %s\n", itoa36(fid)); - ADDMSG(&f->msgs, msg_message("wrongpasswd", "faction password", - f->no, pass)); - return 0; } - /* Die Partei hat sich zumindest gemeldet, so daß sie noch - * nicht als untätig gilt */ - - /* TODO: +1 ist ein Workaround, weil cturn erst in process_orders - * incrementiert wird. */ - f->lastorders = global.data_turn + 1; - - } else { - log_warning("orders for invalid faction %s\n", itoa36(fid)); - } - return f; + else { + log_warning("orders for invalid faction %s\n", itoa36(fid)); + } + return f; } /* ------------------------------------------------------------- */ static param_t igetparam(const char *s, const struct locale *lang) { - return findparam(igetstrtoken(s), lang); + return findparam(igetstrtoken(s), lang); } int readorders(const char *filename) { - FILE *F = NULL; - const char *b; - int nfactions = 0; - struct faction *f = NULL; + FILE *F = NULL; + const char *b; + int nfactions = 0; + struct faction *f = NULL; - F = fopen(filename, "rb"); - if (!F) { - perror(filename); - return -1; - } - if (verbosity >= 1) - puts(" - lese Befehlsdatei...\n"); + F = fopen(filename, "rb"); + if (!F) { + perror(filename); + return -1; + } + if (verbosity >= 1) + puts(" - lese Befehlsdatei...\n"); - /* TODO: recognize UTF8 BOM */ - b = getbuf(F, enc_gamedata); + /* TODO: recognize UTF8 BOM */ + b = getbuf(F, enc_gamedata); - /* Auffinden der ersten Partei, und danach abarbeiten bis zur letzten - * Partei */ + /* Auffinden der ersten Partei, und danach abarbeiten bis zur letzten + * Partei */ - while (b) { - const struct locale *lang = f ? f->locale : default_locale; - int p; - switch (igetparam(b, lang)) { + while (b) { + const struct locale *lang = f ? f->locale : default_locale; + int p; + switch (igetparam(b, lang)) { #undef LOCALE_CHANGE #ifdef LOCALE_CHANGE - case P_LOCALE: - { - const char *s = getstrtoken(); - if (f && get_locale(s)) { - f->locale = get_locale(s); + case P_LOCALE: + { + const char *s = getstrtoken(); + if (f && get_locale(s)) { + f->locale = get_locale(s); + } } - } - b = getbuf(F, enc_gamedata); - break; -#endif - case P_GAMENAME: - case P_FACTION: - f = factionorders(); - if (f) { - ++nfactions; - } - - b = getbuf(F, enc_gamedata); - break; - - /* in factionorders wird nur eine zeile gelesen: - * diejenige mit dem passwort. Die befehle der units - * werden geloescht, und die Partei wird als aktiv - * vermerkt. */ - - case P_UNIT: - if (!f || !unitorders(F, enc_gamedata, f)) - do { - b = getbuf(F, enc_gamedata); - if (!b) + b = getbuf(F, enc_gamedata); break; - p = (b[0]=='@') ? NOPARAM : igetparam(b, lang); - } while ((p != P_UNIT || !f) && p != P_FACTION && p != P_NEXT - && p != P_GAMENAME); - break; +#endif + case P_GAMENAME: + case P_FACTION: + f = factionorders(); + if (f) { + ++nfactions; + } - /* Falls in unitorders() abgebrochen wird, steht dort entweder eine neue - * Partei, eine neue Einheit oder das File-Ende. Das switch() wird erneut - * durchlaufen, und die entsprechende Funktion aufgerufen. Man darf buf - * auf alle Fälle nicht überschreiben! Bei allen anderen Einträgen hier - * muß buf erneut gefüllt werden, da die betreffende Information in nur - * einer Zeile steht, und nun die nächste gelesen werden muß. */ + b = getbuf(F, enc_gamedata); + break; - case P_NEXT: - f = NULL; - b = getbuf(F, enc_gamedata); - break; + /* in factionorders wird nur eine zeile gelesen: + * diejenige mit dem passwort. Die befehle der units + * werden geloescht, und die Partei wird als aktiv + * vermerkt. */ - default: - b = getbuf(F, enc_gamedata); - break; + case P_UNIT: + if (!f || !unitorders(F, enc_gamedata, f)) + do { + b = getbuf(F, enc_gamedata); + if (!b) + break; + p = (b[0] == '@') ? NOPARAM : igetparam(b, lang); + } while ((p != P_UNIT || !f) && p != P_FACTION && p != P_NEXT + && p != P_GAMENAME); + break; + + /* Falls in unitorders() abgebrochen wird, steht dort entweder eine neue + * Partei, eine neue Einheit oder das File-Ende. Das switch() wird erneut + * durchlaufen, und die entsprechende Funktion aufgerufen. Man darf buf + * auf alle Fälle nicht überschreiben! Bei allen anderen Einträgen hier + * muß buf erneut gefüllt werden, da die betreffende Information in nur + * einer Zeile steht, und nun die nächste gelesen werden muß. */ + + case P_NEXT: + f = NULL; + b = getbuf(F, enc_gamedata); + break; + + default: + b = getbuf(F, enc_gamedata); + break; + } } - } - fclose(F); - if (verbosity >= 1) - puts("\n"); - log_printf(stdout, " %d Befehlsdateien gelesen\n", nfactions); - return 0; + fclose(F); + if (verbosity >= 1) + puts("\n"); + log_printf(stdout, " %d Befehlsdateien gelesen\n", nfactions); + return 0; } /* ------------------------------------------------------------- */ @@ -342,56 +346,56 @@ int readorders(const char *filename) /* -9;-27;-1;-19;Sumpfloch */ int inner_world(region * r) { - static int xy[2] = { 18, -45 }; - static int size[2] = { 27, 27 }; + static int xy[2] = { 18, -45 }; + static int size[2] = { 27, 27 }; - if (r->x >= xy[0] && r->x < xy[0] + size[0] && r->y >= xy[1] - && r->y < xy[1] + size[1]) - return 2; - if (r->x >= xy[0] - 9 && r->x < xy[0] + size[0] + 9 && r->y >= xy[1] - 9 - && r->y < xy[1] + size[1] + 9) - return 1; - return 0; + if (r->x >= xy[0] && r->x < xy[0] + size[0] && r->y >= xy[1] + && r->y < xy[1] + size[1]) + return 2; + if (r->x >= xy[0] - 9 && r->x < xy[0] + size[0] + 9 && r->y >= xy[1] - 9 + && r->y < xy[1] + size[1] + 9) + return 1; + return 0; } int maxregions = -1; int loadplane = 0; enum { - U_MAN, - U_UNDEAD, - U_ILLUSION, - U_FIREDRAGON, - U_DRAGON, - U_WYRM, - U_SPELL, - U_TAVERNE, - U_MONSTER, - U_BIRTHDAYDRAGON, - U_TREEMAN, - MAXTYPES + U_MAN, + U_UNDEAD, + U_ILLUSION, + U_FIREDRAGON, + U_DRAGON, + U_WYRM, + U_SPELL, + U_TAVERNE, + U_MONSTER, + U_BIRTHDAYDRAGON, + U_TREEMAN, + MAXTYPES }; race_t typus2race(unsigned char typus) { - if (typus > 0 && typus <= 11) - return (race_t) (typus - 1); - return NORACE; + if (typus > 0 && typus <= 11) + return (race_t)(typus - 1); + return NORACE; } void create_backup(char *file) { #ifdef HAVE_LINK - char bfile[MAX_PATH]; - int c = 1; + char bfile[MAX_PATH]; + int c = 1; - if (access(file, R_OK) == 0) - return; - do { - sprintf(bfile, "%s.backup%d", file, c); - c++; - } while (access(bfile, R_OK) == 0); - link(file, bfile); + if (access(file, R_OK) == 0) + return; + do { + sprintf(bfile, "%s.backup%d", file, c); + c++; + } while (access(bfile, R_OK) == 0); + link(file, bfile); #endif } @@ -409,10 +413,12 @@ void read_items(struct storage *store, item ** ilist) READ_INT(store, &i); if (i <= 0) { log_error("data contains an entry with %d %s\n", i, rtype->_name[1]); - } else { + } + else { if (rtype && rtype->itype) { i_change(ilist, rtype->itype, i); - } else { + } + else { log_error("data contains unknown item type %s.\n", ibuf); } assert(rtype && rtype->itype); @@ -422,154 +428,160 @@ void read_items(struct storage *store, item ** ilist) static void read_alliances(struct storage *store) { - char pbuf[8]; - int id, terminator = 0; - if (global.data_version < SAVEALLIANCE_VERSION) { - if (!AllianceRestricted() && !AllianceAuto()) - return; - } - if (global.data_version < ALLIANCELEADER_VERSION) { - terminator = atoi36("end"); - READ_STR(store, pbuf, sizeof(pbuf)); - id = atoi36(pbuf); - } else { - READ_INT(store, &id); - } - while (id != terminator) { - char aname[128]; - alliance *al; - READ_STR(store, aname, sizeof(aname)); - al = makealliance(id, aname); - if (global.data_version >= OWNER_2_VERSION) { - READ_INT(store, &al->flags); + char pbuf[8]; + int id, terminator = 0; + if (global.data_version < SAVEALLIANCE_VERSION) { + if (!AllianceRestricted() && !AllianceAuto()) + return; } - if (global.data_version >= ALLIANCELEADER_VERSION) { - read_reference(&al->_leader, store, read_faction_reference, - resolve_faction); - READ_INT(store, &id); - } else { - READ_STR(store, pbuf, sizeof(pbuf)); - id = atoi36(pbuf); + if (global.data_version < ALLIANCELEADER_VERSION) { + terminator = atoi36("end"); + READ_STR(store, pbuf, sizeof(pbuf)); + id = atoi36(pbuf); + } + else { + READ_INT(store, &id); + } + while (id != terminator) { + char aname[128]; + alliance *al; + READ_STR(store, aname, sizeof(aname)); + al = makealliance(id, aname); + if (global.data_version >= OWNER_2_VERSION) { + READ_INT(store, &al->flags); + } + if (global.data_version >= ALLIANCELEADER_VERSION) { + read_reference(&al->_leader, store, read_faction_reference, + resolve_faction); + READ_INT(store, &id); + } + else { + READ_STR(store, pbuf, sizeof(pbuf)); + id = atoi36(pbuf); + } } - } } void write_alliances(struct gamedata *data) { - alliance *al = alliances; - while (al) { - if (al->_leader) { - WRITE_INT(data->store, al->id); - WRITE_STR(data->store, al->name); - WRITE_INT(data->store, (int)al->flags); - write_faction_reference(al->_leader, data->store); - WRITE_SECTION(data->store); + alliance *al = alliances; + while (al) { + if (al->_leader) { + WRITE_INT(data->store, al->id); + WRITE_STR(data->store, al->name); + WRITE_INT(data->store, (int)al->flags); + write_faction_reference(al->_leader, data->store); + WRITE_SECTION(data->store); + } + al = al->next; } - al = al->next; - } - WRITE_INT(data->store, 0); - WRITE_SECTION(data->store); + WRITE_INT(data->store, 0); + WRITE_SECTION(data->store); } void write_items(struct storage *store, item * ilist) { - item *itm; - for (itm = ilist; itm; itm = itm->next) { - assert(itm->number >= 0); - if (itm->number) { - WRITE_TOK(store, resourcename(itm->type->rtype, 0)); - WRITE_INT(store, itm->number); + item *itm; + for (itm = ilist; itm; itm = itm->next) { + assert(itm->number >= 0); + if (itm->number) { + WRITE_TOK(store, resourcename(itm->type->rtype, 0)); + WRITE_INT(store, itm->number); + } } - } - WRITE_TOK(store, "end"); + WRITE_TOK(store, "end"); } static int resolve_owner(variant id, void *address) { - region_owner *owner = (region_owner *) address; - int result = 0; - faction *f = NULL; - if (id.i != 0) { - f = findfaction(id.i); - if (f == NULL) { - log_error("region has an invalid owner (%s)\n", itoa36(id.i)); - f = get_monsters(); + region_owner *owner = (region_owner *)address; + int result = 0; + faction *f = NULL; + if (id.i != 0) { + f = findfaction(id.i); + if (f == NULL) { + log_error("region has an invalid owner (%s)\n", itoa36(id.i)); + f = get_monsters(); + } } - } - owner->owner = f; - if (f) { - owner->alliance = f->alliance; - } - return result; + owner->owner = f; + if (f) { + owner->alliance = f->alliance; + } + return result; } static void read_owner(struct gamedata *data, region_owner ** powner) { - int since_turn; + int since_turn; - READ_INT(data->store, &since_turn); - if (since_turn >= 0) { - region_owner *owner = malloc(sizeof(region_owner)); - owner->since_turn = since_turn; - READ_INT(data->store, &owner->morale_turn); - if (data->version >= MOURNING_VERSION) { - READ_INT(data->store, &owner->flags); - } else { - owner->flags = 0; + READ_INT(data->store, &since_turn); + if (since_turn >= 0) { + region_owner *owner = malloc(sizeof(region_owner)); + owner->since_turn = since_turn; + READ_INT(data->store, &owner->morale_turn); + if (data->version >= MOURNING_VERSION) { + READ_INT(data->store, &owner->flags); + } + else { + owner->flags = 0; + } + if (data->version >= OWNER_2_VERSION) { + int id; + READ_INT(data->store, &id); + owner->alliance = id ? findalliance(id) : NULL; + } + else { + owner->alliance = NULL; + } + read_reference(owner, data->store, &read_faction_reference, &resolve_owner); + *powner = owner; } - if (data->version >= OWNER_2_VERSION) { - int id; - READ_INT(data->store, &id); - owner->alliance = id ? findalliance(id) : NULL; - } else { - owner->alliance = NULL; + else { + *powner = 0; } - read_reference(owner, data->store, &read_faction_reference, &resolve_owner); - *powner = owner; - } else { - *powner = 0; - } } static void write_owner(struct gamedata *data, region_owner * owner) { - if (owner) { - WRITE_INT(data->store, owner->since_turn); - WRITE_INT(data->store, owner->morale_turn); - WRITE_INT(data->store, owner->flags); - WRITE_INT(data->store, owner->alliance ? owner->alliance->id : 0); - write_faction_reference(owner->owner, data->store); - } else { - WRITE_INT(data->store, -1); - } + if (owner) { + WRITE_INT(data->store, owner->since_turn); + WRITE_INT(data->store, owner->morale_turn); + WRITE_INT(data->store, owner->flags); + WRITE_INT(data->store, owner->alliance ? owner->alliance->id : 0); + write_faction_reference(owner->owner, data->store); + } + else { + WRITE_INT(data->store, -1); + } } int current_turn(void) { - char zText[MAX_PATH]; - int cturn = 0; - FILE *F; + char zText[MAX_PATH]; + int cturn = 0; + FILE *F; - sprintf(zText, "%s/turn", basepath()); - F = fopen(zText, "r"); - if (!F) { - perror(zText); - } - else { - fscanf(F, "%d\n", &cturn); - fclose(F); - } - return cturn; + sprintf(zText, "%s/turn", basepath()); + F = fopen(zText, "r"); + if (!F) { + perror(zText); + } + else { + fscanf(F, "%d\n", &cturn); + fclose(F); + } + return cturn; } static void writeorder(struct gamedata *data, const struct order *ord, - const struct locale *lang) +const struct locale *lang) { - char obuf[1024]; - write_order(ord, obuf, sizeof(obuf)); - if (obuf[0]) - WRITE_STR(data->store, obuf); + char obuf[1024]; + write_order(ord, obuf, sizeof(obuf)); + if (obuf[0]) + WRITE_STR(data->store, obuf); } unit *read_unit(struct gamedata *data) @@ -584,7 +596,7 @@ unit *read_unit(struct gamedata *data) READ_INT(data->store, &n); if (n <= 0) { log_error("data contains invalid unit %d.\n", n); - assert(n>0); + assert(n > 0); return 0; } u = findunit(n); @@ -600,7 +612,8 @@ unit *read_unit(struct gamedata *data) u->skills = 0; u->skill_size = 0; u_setfaction(u, NULL); - } else { + } + else { u = calloc(sizeof(unit), 1); u->no = n; uhash(u); @@ -613,383 +626,397 @@ unit *read_unit(struct gamedata *data) } if (u->faction) { ++u->faction->no_units; - } else { + } + else { log_error("unit %s has faction == NULL\n", unitname(u)); assert(u->faction); return 0; } - READ_STR(data->store, obuf, sizeof(obuf)); - u->name = _strdup(obuf); - if (lomem) { - READ_STR(data->store, NULL, 0); - } else { READ_STR(data->store, obuf, sizeof(obuf)); - u->display = _strdup(obuf); - } - READ_INT(data->store, &number); + u->name = _strdup(obuf); + if (lomem) { + READ_STR(data->store, NULL, 0); + } + else { + READ_STR(data->store, obuf, sizeof(obuf)); + u->display = _strdup(obuf); + } + READ_INT(data->store, &number); set_number(u, number); - - - - READ_INT(data->store, &n); - u->age = (short)n; - if (data->version < STORAGE_VERSION) { - char *space; - READ_STR(data->store, rname, sizeof(rname)); - space = strchr(rname, ' '); - if (space != NULL) { - char *inc = space + 1; - char *outc = space; - do { - while (*inc == ' ') - ++inc; - while (*inc) { - *outc++ = *inc++; - if (*inc == ' ') - break; - } - } while (*inc); - *outc = 0; - } - } else { - READ_TOK(data->store, rname, sizeof(rname)); - } - u_setrace(u, rc_find(rname)); - if (data->version < STORAGE_VERSION) { - READ_STR(data->store, rname, sizeof(rname)); - } else { - READ_TOK(data->store, rname, sizeof(rname)); - } - if (rname[0] && skill_enabled(SK_STEALTH)) - u->irace = rc_find(rname); - else - u->irace = NULL; - if (u_race(u)->describe) { - const char *rcdisp = u_race(u)->describe(u, u->faction->locale); - if (u->display && rcdisp) { - /* see if the data file contains old descriptions */ - if (strcmp(rcdisp, u->display) == 0) { - free(u->display); - u->display = NULL; - } - } - } - - READ_INT(data->store, &n); - if (n > 0) { - building * b = findbuilding(n); - if (b) { - u_set_building(u, b); - if (fval(u, UFL_OWNER)) { - building_set_owner(u); - } - } else { - log_error("read_unit: unit in unkown building '%s'\n", itoa36(n)); - } - } - - READ_INT(data->store, &n); - if (n > 0) { - ship * sh = findship(n); - if (sh) { - u_set_ship(u, sh); - if (fval(u, UFL_OWNER)) { - ship_set_owner(u); - } - } else { - log_error("read_unit: unit in unkown ship '%s'\n", itoa36(n)); - } - } - - READ_INT(data->store, &n); - setstatus(u, n); - READ_INT(data->store, &u->flags); - u->flags &= UFL_SAVEMASK; - if ((u->flags & UFL_ANON_FACTION) && !rule_stealth_faction()) { - /* if this rule is broken, then fix broken units */ - u->flags -= UFL_ANON_FACTION; - log_warning("%s was anonymous.\n", unitname(u)); - } - /* Persistente Befehle einlesen */ - free_orders(&u->orders); - READ_STR(data->store, obuf, sizeof(obuf)); - p = n = 0; - orderp = &u->orders; - while (obuf[0]) { - if (!lomem) { - order *ord = parse_order(obuf, u->faction->locale); - if (ord != NULL) { - if (++n < MAXORDERS) { - if (!is_persistent(ord) || ++p < MAXPERSISTENT) { - *orderp = ord; - orderp = &ord->next; - ord = NULL; - } else if (p == MAXPERSISTENT) { - log_warning("%s had %d or more persistent orders\n", unitname(u), MAXPERSISTENT); - } - } else if (n == MAXORDERS) { - log_warning("%s had %d or more orders\n", unitname(u), MAXORDERS); - } - if (ord != NULL) - free_order(ord); - } - } - READ_STR(data->store, obuf, sizeof(obuf)); - } - if (data->version < NOLASTORDER_VERSION) { - order *ord; - READ_STR(data->store, obuf, sizeof(obuf)); - ord = parse_order(obuf, u->faction->locale); - if (ord != NULL) { - addlist(&u->orders, ord); - } - } - set_order(&u->thisorder, NULL); - - assert(u_race(u)); - for (;;) { - int n, level, weeks; - skill_t sk; READ_INT(data->store, &n); - sk = (skill_t)n; - if (sk == NOSKILL) break; - READ_INT(data->store, &level); - READ_INT(data->store, &weeks); - if (level) { - skill *sv = add_skill(u, sk); - sv->level = sv->old = (unsigned char)level; - sv->weeks = (unsigned char)weeks; - } - } - read_items(data->store, &u->items); - READ_INT(data->store, &u->hp); - if (u->hp < u->number) { - log_error("Einheit %s hat %u Personen, und %u Trefferpunkte\n", itoa36(u->no), u->number, u->hp); - u->hp = u->number; - } + u->age = (short)n; - a_read(data->store, &u->attribs, u); - return u; + if (data->version < STORAGE_VERSION) { + char *space; + READ_STR(data->store, rname, sizeof(rname)); + space = strchr(rname, ' '); + if (space != NULL) { + char *inc = space + 1; + char *outc = space; + do { + while (*inc == ' ') + ++inc; + while (*inc) { + *outc++ = *inc++; + if (*inc == ' ') + break; + } + } while (*inc); + *outc = 0; + } + } + else { + READ_TOK(data->store, rname, sizeof(rname)); + } + u_setrace(u, rc_find(rname)); + + if (data->version < STORAGE_VERSION) { + READ_STR(data->store, rname, sizeof(rname)); + } + else { + READ_TOK(data->store, rname, sizeof(rname)); + } + if (rname[0] && skill_enabled(SK_STEALTH)) + u->irace = rc_find(rname); + else + u->irace = NULL; + + if (u_race(u)->describe) { + const char *rcdisp = u_race(u)->describe(u, u->faction->locale); + if (u->display && rcdisp) { + /* see if the data file contains old descriptions */ + if (strcmp(rcdisp, u->display) == 0) { + free(u->display); + u->display = NULL; + } + } + } + + READ_INT(data->store, &n); + if (n > 0) { + building * b = findbuilding(n); + if (b) { + u_set_building(u, b); + if (fval(u, UFL_OWNER)) { + building_set_owner(u); + } + } + else { + log_error("read_unit: unit in unkown building '%s'\n", itoa36(n)); + } + } + + READ_INT(data->store, &n); + if (n > 0) { + ship * sh = findship(n); + if (sh) { + u_set_ship(u, sh); + if (fval(u, UFL_OWNER)) { + ship_set_owner(u); + } + } + else { + log_error("read_unit: unit in unkown ship '%s'\n", itoa36(n)); + } + } + + READ_INT(data->store, &n); + setstatus(u, n); + READ_INT(data->store, &u->flags); + u->flags &= UFL_SAVEMASK; + if ((u->flags & UFL_ANON_FACTION) && !rule_stealth_faction()) { + /* if this rule is broken, then fix broken units */ + u->flags -= UFL_ANON_FACTION; + log_warning("%s was anonymous.\n", unitname(u)); + } + /* Persistente Befehle einlesen */ + free_orders(&u->orders); + READ_STR(data->store, obuf, sizeof(obuf)); + p = n = 0; + orderp = &u->orders; + while (obuf[0]) { + if (!lomem) { + order *ord = parse_order(obuf, u->faction->locale); + if (ord != NULL) { + if (++n < MAXORDERS) { + if (!is_persistent(ord) || ++p < MAXPERSISTENT) { + *orderp = ord; + orderp = &ord->next; + ord = NULL; + } + else if (p == MAXPERSISTENT) { + log_warning("%s had %d or more persistent orders\n", unitname(u), MAXPERSISTENT); + } + } + else if (n == MAXORDERS) { + log_warning("%s had %d or more orders\n", unitname(u), MAXORDERS); + } + if (ord != NULL) + free_order(ord); + } + } + READ_STR(data->store, obuf, sizeof(obuf)); + } + if (data->version < NOLASTORDER_VERSION) { + order *ord; + READ_STR(data->store, obuf, sizeof(obuf)); + ord = parse_order(obuf, u->faction->locale); + if (ord != NULL) { + addlist(&u->orders, ord); + } + } + set_order(&u->thisorder, NULL); + + assert(u_race(u)); + for (;;) { + int n, level, weeks; + skill_t sk; + READ_INT(data->store, &n); + sk = (skill_t)n; + if (sk == NOSKILL) break; + READ_INT(data->store, &level); + READ_INT(data->store, &weeks); + if (level) { + skill *sv = add_skill(u, sk); + sv->level = sv->old = (unsigned char)level; + sv->weeks = (unsigned char)weeks; + } + } + read_items(data->store, &u->items); + READ_INT(data->store, &u->hp); + if (u->hp < u->number) { + log_error("Einheit %s hat %u Personen, und %u Trefferpunkte\n", itoa36(u->no), u->number, u->hp); + u->hp = u->number; + } + + a_read(data->store, &u->attribs, u); + return u; } void write_unit(struct gamedata *data, const unit * u) { - order *ord; - int i, p = 0; - unsigned int flags = u->flags & UFL_SAVEMASK; - const race *irace = u_irace(u); + order *ord; + int i, p = 0; + unsigned int flags = u->flags & UFL_SAVEMASK; + const race *irace = u_irace(u); - write_unit_reference(u, data->store); - write_faction_reference(u->faction, data->store); - WRITE_STR(data->store, (const char *)u->name); - WRITE_STR(data->store, u->display ? (const char *)u->display : ""); - WRITE_INT(data->store, u->number); - WRITE_INT(data->store, u->age); - WRITE_TOK(data->store, u_race(u)->_name[0]); - WRITE_TOK(data->store, (irace && irace != u_race(u)) ? irace->_name[0] : ""); - write_building_reference(u->building, data->store); - write_ship_reference(u->ship, data->store); - WRITE_INT(data->store, u->status); - if (u->building && u==building_owner(u->building)) flags |= UFL_OWNER; - if (u->ship && u==ship_owner(u->ship)) flags |= UFL_OWNER; - WRITE_INT(data->store, flags); - WRITE_SECTION(data->store); - for (ord = u->old_orders; ord; ord = ord->next) { - if (++p < MAXPERSISTENT) { - writeorder(data, ord, u->faction->locale); - } else { - log_warning("%s had %d or more persistent orders\n", unitname(u), MAXPERSISTENT); - break; + write_unit_reference(u, data->store); + write_faction_reference(u->faction, data->store); + WRITE_STR(data->store, (const char *)u->name); + WRITE_STR(data->store, u->display ? (const char *)u->display : ""); + WRITE_INT(data->store, u->number); + WRITE_INT(data->store, u->age); + WRITE_TOK(data->store, u_race(u)->_name[0]); + WRITE_TOK(data->store, (irace && irace != u_race(u)) ? irace->_name[0] : ""); + write_building_reference(u->building, data->store); + write_ship_reference(u->ship, data->store); + WRITE_INT(data->store, u->status); + if (u->building && u == building_owner(u->building)) flags |= UFL_OWNER; + if (u->ship && u == ship_owner(u->ship)) flags |= UFL_OWNER; + WRITE_INT(data->store, flags); + WRITE_SECTION(data->store); + for (ord = u->old_orders; ord; ord = ord->next) { + if (++p < MAXPERSISTENT) { + writeorder(data, ord, u->faction->locale); + } + else { + log_warning("%s had %d or more persistent orders\n", unitname(u), MAXPERSISTENT); + break; + } } - } - for (ord = u->orders; ord; ord = ord->next) { - if (u->old_orders && is_repeated(ord)) - continue; /* has new defaults */ - if (is_persistent(ord)) { - if (++p < MAXPERSISTENT) { - writeorder(data, ord, u->faction->locale); - } else { - log_warning("%s had %d or more persistent orders\n", unitname(u), MAXPERSISTENT); - break; - } + for (ord = u->orders; ord; ord = ord->next) { + if (u->old_orders && is_repeated(ord)) + continue; /* has new defaults */ + if (is_persistent(ord)) { + if (++p < MAXPERSISTENT) { + writeorder(data, ord, u->faction->locale); + } + else { + log_warning("%s had %d or more persistent orders\n", unitname(u), MAXPERSISTENT); + break; + } + } } - } - /* write an empty string to terminate the list */ - WRITE_STR(data->store, ""); - WRITE_SECTION(data->store); + /* write an empty string to terminate the list */ + WRITE_STR(data->store, ""); + WRITE_SECTION(data->store); - assert(u_race(u)); + assert(u_race(u)); - for (i = 0; i != u->skill_size; ++i) { - skill *sv = u->skills + i; - assert(sv->weeks <= sv->level * 2 + 1); - if (sv->level > 0) { - WRITE_INT(data->store, sv->id); - WRITE_INT(data->store, sv->level); - WRITE_INT(data->store, sv->weeks); + for (i = 0; i != u->skill_size; ++i) { + skill *sv = u->skills + i; + assert(sv->weeks <= sv->level * 2 + 1); + if (sv->level > 0) { + WRITE_INT(data->store, sv->id); + WRITE_INT(data->store, sv->level); + WRITE_INT(data->store, sv->weeks); + } } - } - WRITE_INT(data->store, -1); - WRITE_SECTION(data->store); - write_items(data->store, u->items); - WRITE_SECTION(data->store); - if (u->hp == 0) { - log_error("unit %s has 0 hitpoints, adjusting.\n", itoa36(u->no)); - ((unit *) u)->hp = u->number; - } - WRITE_INT(data->store, u->hp); - WRITE_SECTION(data->store); - a_write(data->store, u->attribs, u); - WRITE_SECTION(data->store); + WRITE_INT(data->store, -1); + WRITE_SECTION(data->store); + write_items(data->store, u->items); + WRITE_SECTION(data->store); + if (u->hp == 0) { + log_error("unit %s has 0 hitpoints, adjusting.\n", itoa36(u->no)); + ((unit *)u)->hp = u->number; + } + WRITE_INT(data->store, u->hp); + WRITE_SECTION(data->store); + a_write(data->store, u->attribs, u); + WRITE_SECTION(data->store); } static region *readregion(struct gamedata *data, int x, int y) { - region *r = findregion(x, y); - const terrain_type *terrain; - char token[32]; - int uid = 0; - int n; + region *r = findregion(x, y); + const terrain_type *terrain; + char token[32]; + int uid = 0; + int n; - if (data->version >= UID_VERSION) { - READ_INT(data->store, &uid); - } + if (data->version >= UID_VERSION) { + READ_INT(data->store, &uid); + } - if (r == NULL) { - plane *pl = findplane(x, y); - r = new_region(x, y, pl, uid); - } else { - assert(uid == 0 || r->uid == uid); - current_region = r; - while (r->attribs) - a_remove(&r->attribs, r->attribs); + if (r == NULL) { + plane *pl = findplane(x, y); + r = new_region(x, y, pl, uid); + } + else { + assert(uid == 0 || r->uid == uid); + current_region = r; + while (r->attribs) + a_remove(&r->attribs, r->attribs); + if (r->land) { + free(r->land); /* mem leak */ + r->land->demands = 0; /* mem leak */ + } + while (r->resources) { + rawmaterial *rm = r->resources; + r->resources = rm->next; + free(rm); + } + r->land = 0; + } + if (lomem) { + READ_STR(data->store, NULL, 0); + } + else { + char info[DISPLAYSIZE]; + READ_STR(data->store, info, sizeof(info)); + region_setinfo(r, info); + } + + if (data->version < TERRAIN_VERSION) { + int ter; + READ_INT(data->store, &ter); + 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]; + READ_STR(data->store, name, sizeof(name)); + terrain = get_terrain(name); + if (terrain == NULL) { + log_error("Unknown terrain '%s'\n", name); + assert(!"unknown terrain"); + } + } + r->terrain = terrain; + READ_INT(data->store, &r->flags); + READ_INT(data->store, &n); + r->age = (unsigned short)n; + + if (fval(r->terrain, LAND_REGION)) { + char name[NAMESIZE]; + r->land = calloc(1, sizeof(land_region)); + READ_STR(data->store, name, sizeof(name)); + r->land->name = _strdup(name); + } if (r->land) { - free(r->land); /* mem leak */ - r->land->demands = 0; /* mem leak */ - } - while (r->resources) { - rawmaterial *rm = r->resources; - r->resources = rm->next; - free(rm); - } - r->land = 0; - } - if (lomem) { - READ_STR(data->store, NULL, 0); - } else { - char info[DISPLAYSIZE]; - READ_STR(data->store, info, sizeof(info)); - region_setinfo(r, info); - } + int i; + rawmaterial **pres = &r->resources; - if (data->version < TERRAIN_VERSION) { - int ter; - READ_INT(data->store, &ter); - 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]; - READ_STR(data->store, name, sizeof(name)); - terrain = get_terrain(name); - if (terrain == NULL) { - log_error("Unknown terrain '%s'\n", name); - assert(!"unknown terrain"); - } - } - r->terrain = terrain; - READ_INT(data->store, &r->flags); - READ_INT(data->store, &n); - r->age = (unsigned short)n; + READ_INT(data->store, &i); + if (i < 0) { + log_error("number of trees in %s is %d.\n", regionname(r, NULL), i); + i = 0; + } + rsettrees(r, 0, i); + READ_INT(data->store, &i); + if (i < 0) { + log_error("number of young trees in %s is %d.\n", regionname(r, NULL), i); + i = 0; + } + rsettrees(r, 1, i); + READ_INT(data->store, &i); + if (i < 0) { + log_error("number of seeds in %s is %d.\n", regionname(r, NULL), i); + i = 0; + } + rsettrees(r, 2, i); - if (fval(r->terrain, LAND_REGION)) { - char name[NAMESIZE]; - r->land = calloc(1, sizeof(land_region)); - READ_STR(data->store, name, sizeof(name)); - r->land->name = _strdup(name); - } - if (r->land) { - int i; - rawmaterial **pres = &r->resources; + READ_INT(data->store, &i); + rsethorses(r, i); + assert(*pres == NULL); + for (;;) { + rawmaterial *res; + READ_STR(data->store, token, sizeof(token)); + if (strcmp(token, "end") == 0) + break; + res = malloc(sizeof(rawmaterial)); + res->type = rmt_find(token); + if (res->type == NULL) { + log_error("invalid resourcetype %s in data.\n", token); + } + assert(res->type != NULL); + READ_INT(data->store, &n); + res->level = n; + READ_INT(data->store, &n); + res->amount = n; + res->flags = 0; - READ_INT(data->store, &i); - if (i < 0) { - log_error("number of trees in %s is %d.\n", regionname(r, NULL), i); - i = 0; + READ_INT(data->store, &n); + res->startlevel = n; + READ_INT(data->store, &n); + res->base = n; + READ_INT(data->store, &n); + res->divisor = n; + + *pres = res; + pres = &res->next; + } + *pres = NULL; + + READ_STR(data->store, token, sizeof(token)); + if (strcmp(token, "noherb") != 0) { + const resource_type *rtype = rt_find(token); + assert(rtype && rtype->itype && fval(rtype->itype, ITF_HERB)); + rsetherbtype(r, rtype->itype); + } + else { + rsetherbtype(r, NULL); + } + READ_INT(data->store, &n); + rsetherbs(r, (short)n); + READ_INT(data->store, &n); + rsetpeasants(r, n); + READ_INT(data->store, &n); + rsetmoney(r, n); } - rsettrees(r, 0, i); - READ_INT(data->store, &i); - if (i < 0) { - log_error("number of young trees in %s is %d.\n", regionname(r, NULL), i); - i = 0; - } - rsettrees(r, 1, i); - READ_INT(data->store, &i); - if (i < 0) { - log_error("number of seeds in %s is %d.\n", regionname(r, NULL), i); - i = 0; - } - rsettrees(r, 2, i); - READ_INT(data->store, &i); - rsethorses(r, i); - assert(*pres == NULL); - for (;;) { - rawmaterial *res; - READ_STR(data->store, token, sizeof(token)); - if (strcmp(token, "end") == 0) - break; - res = malloc(sizeof(rawmaterial)); - res->type = rmt_find(token); - if (res->type == NULL) { - log_error("invalid resourcetype %s in data.\n", token); - } - assert(res->type != NULL); - READ_INT(data->store, &n); - res->level = n; - READ_INT(data->store, &n); - res->amount = n; - res->flags = 0; - - READ_INT(data->store, &n); - res->startlevel = n; - READ_INT(data->store, &n); - res->base = n; - READ_INT(data->store, &n); - res->divisor = n; - - *pres = res; - pres = &res->next; - } - *pres = NULL; - - READ_STR(data->store, token, sizeof(token)); - if (strcmp(token, "noherb") != 0) { - const resource_type *rtype = rt_find(token); - assert(rtype && rtype->itype && fval(rtype->itype, ITF_HERB)); - rsetherbtype(r, rtype->itype); - } else { - rsetherbtype(r, NULL); - } - READ_INT(data->store, &n); - rsetherbs(r, (short)n); - READ_INT(data->store, &n); - rsetpeasants(r, n); - READ_INT(data->store, &n); - rsetmoney(r, n); - } - - assert(r->terrain != NULL); - assert(rhorses(r) >= 0); - assert(rpeasants(r) >= 0); - assert(rmoney(r) >= 0); + assert(r->terrain != NULL); + assert(rhorses(r) >= 0); + assert(rpeasants(r) >= 0); + assert(rmoney(r) >= 0); if (r->land) { int n; @@ -1021,176 +1048,179 @@ static region *readregion(struct gamedata *data, int x, int y) void writeregion(struct gamedata *data, const region * r) { - WRITE_INT(data->store, r->uid); - WRITE_STR(data->store, region_getinfo(r)); - WRITE_TOK(data->store, r->terrain->_name); - WRITE_INT(data->store, r->flags & RF_SAVEMASK); - WRITE_INT(data->store, r->age); - WRITE_SECTION(data->store); - if (fval(r->terrain, LAND_REGION)) { - const item_type *rht; - struct demand *demand; - rawmaterial *res = r->resources; - WRITE_STR(data->store, (const char *)r->land->name); - assert(rtrees(r, 0) >= 0); - assert(rtrees(r, 1) >= 0); - assert(rtrees(r, 2) >= 0); - WRITE_INT(data->store, rtrees(r, 0)); - WRITE_INT(data->store, rtrees(r, 1)); - WRITE_INT(data->store, rtrees(r, 2)); - WRITE_INT(data->store, rhorses(r)); - - while (res) { - WRITE_TOK(data->store, res->type->name); - WRITE_INT(data->store, res->level); - WRITE_INT(data->store, res->amount); - WRITE_INT(data->store, res->startlevel); - WRITE_INT(data->store, res->base); - WRITE_INT(data->store, res->divisor); - res = res->next; - } - WRITE_TOK(data->store, "end"); - - rht = rherbtype(r); - if (rht) { - WRITE_TOK(data->store, resourcename(rht->rtype, 0)); - } else { - WRITE_TOK(data->store, "noherb"); - } - WRITE_INT(data->store, rherbs(r)); - WRITE_INT(data->store, rpeasants(r)); - WRITE_INT(data->store, rmoney(r)); - if (r->land) - for (demand = r->land->demands; demand; demand = demand->next) { - WRITE_TOK(data->store, resourcename(demand->type->itype->rtype, 0)); - WRITE_INT(data->store, demand->value); - } - WRITE_TOK(data->store, "end"); -#if RELEASE_VERSION>=REGIONITEMS_VERSION - write_items(data->store, r->land->items); + WRITE_INT(data->store, r->uid); + WRITE_STR(data->store, region_getinfo(r)); + WRITE_TOK(data->store, r->terrain->_name); + WRITE_INT(data->store, r->flags & RF_SAVEMASK); + WRITE_INT(data->store, r->age); WRITE_SECTION(data->store); + if (fval(r->terrain, LAND_REGION)) { + const item_type *rht; + struct demand *demand; + rawmaterial *res = r->resources; + WRITE_STR(data->store, (const char *)r->land->name); + assert(rtrees(r, 0) >= 0); + assert(rtrees(r, 1) >= 0); + assert(rtrees(r, 2) >= 0); + WRITE_INT(data->store, rtrees(r, 0)); + WRITE_INT(data->store, rtrees(r, 1)); + WRITE_INT(data->store, rtrees(r, 2)); + WRITE_INT(data->store, rhorses(r)); + + while (res) { + WRITE_TOK(data->store, res->type->name); + WRITE_INT(data->store, res->level); + WRITE_INT(data->store, res->amount); + WRITE_INT(data->store, res->startlevel); + WRITE_INT(data->store, res->base); + WRITE_INT(data->store, res->divisor); + res = res->next; + } + WRITE_TOK(data->store, "end"); + + rht = rherbtype(r); + if (rht) { + WRITE_TOK(data->store, resourcename(rht->rtype, 0)); + } + else { + WRITE_TOK(data->store, "noherb"); + } + WRITE_INT(data->store, rherbs(r)); + WRITE_INT(data->store, rpeasants(r)); + WRITE_INT(data->store, rmoney(r)); + if (r->land) + for (demand = r->land->demands; demand; demand = demand->next) { + WRITE_TOK(data->store, resourcename(demand->type->itype->rtype, 0)); + WRITE_INT(data->store, demand->value); + } + WRITE_TOK(data->store, "end"); +#if RELEASE_VERSION>=REGIONITEMS_VERSION + write_items(data->store, r->land->items); + WRITE_SECTION(data->store); #endif #if RELEASE_VERSION>=REGIONOWNER_VERSION - WRITE_INT(data->store, r->land->morale); - write_owner(data, r->land->ownership); - WRITE_SECTION(data->store); + WRITE_INT(data->store, r->land->morale); + write_owner(data, r->land->ownership); + WRITE_SECTION(data->store); #endif - } - a_write(data->store, r->attribs, r); - WRITE_SECTION(data->store); + } + a_write(data->store, r->attribs, r); + WRITE_SECTION(data->store); } static ally **addally(const faction * f, ally ** sfp, int aid, int state) { - struct faction *af = findfaction(aid); - ally *sf; + struct faction *af = findfaction(aid); + ally *sf; - state &= ~HELP_OBSERVE; + state &= ~HELP_OBSERVE; #ifndef REGIONOWNERS - state &= ~HELP_TRAVEL; + state &= ~HELP_TRAVEL; #endif - state &= HelpMask(); + state &= HelpMask(); - if (state == 0) - return sfp; + if (state == 0) + return sfp; - sf = calloc(1, sizeof(ally)); - sf->faction = af; - if (!sf->faction) { - variant id; - id.i = aid; - ur_add(id, &sf->faction, resolve_faction); - } - sf->status = state & HELP_ALL; + sf = calloc(1, sizeof(ally)); + sf->faction = af; + if (!sf->faction) { + variant id; + id.i = aid; + ur_add(id, &sf->faction, resolve_faction); + } + sf->status = state & HELP_ALL; - while (*sfp) - sfp = &(*sfp)->next; - *sfp = sf; - return &sf->next; + while (*sfp) + sfp = &(*sfp)->next; + *sfp = sf; + return &sf->next; } int get_spell_level_faction(const spell * sp, void * cbdata) { - static spellbook * common = 0; - spellbook * book; - faction * f = (faction *)cbdata; - spellbook_entry * sbe; + static spellbook * common = 0; + spellbook * book; + faction * f = (faction *)cbdata; + spellbook_entry * sbe; - book = get_spellbook(magic_school[f->magiegebiet]); - if (book) { - sbe = spellbook_get(book, sp); - if (sbe) return sbe->level; - } - if (!common) { - common = get_spellbook(magic_school[M_COMMON]); - } - sbe = spellbook_get(common, sp); - if (sbe) { - return sbe->level; - } else { - log_error("read_spellbook: faction '%s' has a spell with unknown level: '%s'", factionname(f), sp->sname); - } - return 0; + book = get_spellbook(magic_school[f->magiegebiet]); + if (book) { + sbe = spellbook_get(book, sp); + if (sbe) return sbe->level; + } + if (!common) { + common = get_spellbook(magic_school[M_COMMON]); + } + sbe = spellbook_get(common, sp); + if (sbe) { + return sbe->level; + } + else { + log_error("read_spellbook: faction '%s' has a spell with unknown level: '%s'", factionname(f), sp->sname); + } + return 0; } void read_spellbook(spellbook **bookp, struct storage *store, int(*get_level)(const spell * sp, void *), void * cbdata) { - for (;;) { - spell *sp = 0; - char spname[64]; - int level = 0; + for (;;) { + spell *sp = 0; + char spname[64]; + int level = 0; - if (global.data_version < SPELLNAME_VERSION) { - int i; - READ_INT(store, &i); - if (i < 0) - break; - if (bookp) { - sp = find_spellbyid((unsigned int) i); - } - } else { - READ_TOK(store, spname, sizeof(spname)); - if (strcmp(spname, "end") == 0) - break; - if (bookp) { - sp = find_spell(spname); - if (!sp) { - log_error("read_spells: could not find spell '%s'\n", spname); + if (global.data_version < SPELLNAME_VERSION) { + int i; + READ_INT(store, &i); + if (i < 0) + break; + if (bookp) { + sp = find_spellbyid((unsigned int)i); + } + } + else { + READ_TOK(store, spname, sizeof(spname)); + if (strcmp(spname, "end") == 0) + break; + if (bookp) { + sp = find_spell(spname); + if (!sp) { + log_error("read_spells: could not find spell '%s'\n", spname); + } + } + } + if (global.data_version >= SPELLBOOK_VERSION) { + READ_INT(store, &level); + } + if (sp) { + spellbook * sb = *bookp; + if (level <= 0 && get_level) { + level = get_level(sp, cbdata); + } + if (!sb) { + *bookp = create_spellbook(0); + sb = *bookp; + } + if (global.data_version >= SPELLBOOK_VERSION || !spellbook_get(sb, sp)) { + spellbook_add(sb, sp, level); + } } - } } - if (global.data_version >= SPELLBOOK_VERSION) { - READ_INT(store, &level); - } - if (sp) { - spellbook * sb = *bookp; - if (level<=0 && get_level) { - level = get_level(sp, cbdata); - } - if (!sb) { - *bookp = create_spellbook(0); - sb = *bookp; - } - if (global.data_version >= SPELLBOOK_VERSION || !spellbook_get(sb, sp)) { - spellbook_add(sb, sp, level); - } - } - } } void write_spellbook(const struct spellbook *book, struct storage *store) { - quicklist *ql; - int qi; + quicklist *ql; + int qi; - if (book) { - for (ql = book->spells, qi = 0; ql; ql_advance(&ql, &qi, 1)) { - spellbook_entry *sbe = (spellbook_entry *) ql_get(ql, qi); - WRITE_TOK(store, sbe->sp->sname); - WRITE_INT(store, sbe->level); + if (book) { + for (ql = book->spells, qi = 0; ql; ql_advance(&ql, &qi, 1)) { + spellbook_entry *sbe = (spellbook_entry *)ql_get(ql, qi); + WRITE_TOK(store, sbe->sp->sname); + WRITE_INT(store, sbe->level); + } } - } - WRITE_TOK(store, "end"); + WRITE_TOK(store, "end"); } /** Reads a faction from a file. @@ -1199,774 +1229,780 @@ void write_spellbook(const struct spellbook *book, struct storage *store) */ faction *readfaction(struct gamedata * data) { - ally **sfp; - int planes, n; - faction *f; - char name[DISPLAYSIZE]; + ally **sfp; + int planes, n; + faction *f; + char name[DISPLAYSIZE]; - READ_INT(data->store, &n); - f = findfaction(n); - if (f == NULL) { - f = (faction *) calloc(1, sizeof(faction)); - f->no = n; - } else { - f->allies = NULL; /* mem leak */ - while (f->attribs) - a_remove(&f->attribs, f->attribs); - } - READ_INT(data->store, &f->subscription); - - if (alliances || data->version >= OWNER_2_VERSION) { - int allianceid; - READ_INT(data->store, &allianceid); - if (allianceid > 0) - f->alliance = findalliance(allianceid); - if (f->alliance) { - alliance *al = f->alliance; - if (al->flags & ALF_NON_ALLIED) { - assert(!al->members - || !"non-allied dummy-alliance has more than one member"); - } - ql_push(&al->members, f); - } else if (rule_region_owners()) { - /* compat fix for non-allied factions */ - alliance *al = makealliance(0, NULL); - setalliance(f, al); + READ_INT(data->store, &n); + f = findfaction(n); + if (f == NULL) { + f = (faction *)calloc(1, sizeof(faction)); + f->no = n; } - if (data->version >= OWNER_2_VERSION) { - READ_INT(data->store, &f->alliance_joindate); - } else { - f->alliance_joindate = turn - 10; /* we're guessing something safe here */ + else { + f->allies = NULL; /* mem leak */ + while (f->attribs) + a_remove(&f->attribs, f->attribs); } - } + READ_INT(data->store, &f->subscription); - READ_STR(data->store, name, sizeof(name)); - f->name = _strdup(name); - READ_STR(data->store, name, sizeof(name)); - f->banner = _strdup(name); + if (alliances || data->version >= OWNER_2_VERSION) { + int allianceid; + READ_INT(data->store, &allianceid); + if (allianceid > 0) + f->alliance = findalliance(allianceid); + if (f->alliance) { + alliance *al = f->alliance; + if (al->flags & ALF_NON_ALLIED) { + assert(!al->members + || !"non-allied dummy-alliance has more than one member"); + } + ql_push(&al->members, f); + } + else if (rule_region_owners()) { + /* compat fix for non-allied factions */ + alliance *al = makealliance(0, NULL); + setalliance(f, al); + } + if (data->version >= OWNER_2_VERSION) { + READ_INT(data->store, &f->alliance_joindate); + } + else { + f->alliance_joindate = turn - 10; /* we're guessing something safe here */ + } + } - log_printf(stdout, " - Lese Partei %s (%s)\n", f->name, factionid(f)); + READ_STR(data->store, name, sizeof(name)); + f->name = _strdup(name); + READ_STR(data->store, name, sizeof(name)); + f->banner = _strdup(name); - READ_STR(data->store, name, sizeof(name)); - if (set_email(&f->email, name) != 0) { - log_warning("Invalid email address for faction %s: %s\n", itoa36(f->no), name); - set_email(&f->email, ""); - } + log_printf(stdout, " - Lese Partei %s (%s)\n", f->name, factionid(f)); - READ_STR(data->store, name, sizeof(name)); - f->passw = _strdup(name); - if (data->version < NOOVERRIDE_VERSION && data->version >= OVERRIDE_VERSION) { - READ_STR(data->store, 0, 0); - } + READ_STR(data->store, name, sizeof(name)); + if (set_email(&f->email, name) != 0) { + log_warning("Invalid email address for faction %s: %s\n", itoa36(f->no), name); + set_email(&f->email, ""); + } - READ_STR(data->store, name, sizeof(name)); - f->locale = get_locale(name); - READ_INT(data->store, &f->lastorders); - READ_INT(data->store, &f->age); - READ_STR(data->store, name, sizeof(name)); - f->race = rc_find(name); + READ_STR(data->store, name, sizeof(name)); + f->passw = _strdup(name); + if (data->version < NOOVERRIDE_VERSION && data->version >= OVERRIDE_VERSION) { + READ_STR(data->store, 0, 0); + } + + READ_STR(data->store, name, sizeof(name)); + f->locale = get_locale(name); + READ_INT(data->store, &f->lastorders); + READ_INT(data->store, &f->age); + READ_STR(data->store, name, sizeof(name)); + f->race = rc_find(name); if (!f->race) { log_error("unknown race in data: %s\n", name); } assert(f->race); - READ_INT(data->store, &n); - f->magiegebiet = (magic_t)n; - - if (data->version < FOSS_VERSION) { - /* ignore karma */ READ_INT(data->store, &n); - } + f->magiegebiet = (magic_t)n; + + if (data->version < FOSS_VERSION) { + /* ignore karma */ + READ_INT(data->store, &n); + } READ_INT(data->store, &f->flags); if (data->version < INTFLAGS_VERSION) { - if (f->no==0 || f->no==666) { - f->flags = FFL_NPC|FFL_NOTIMEOUT|FFL_NOIDLEOUT; + if (f->no == 0 || f->no == 666) { + f->flags = FFL_NPC | FFL_NOTIMEOUT | FFL_NOIDLEOUT; } } assert((f->flags&FFL_SAVEMASK) == f->flags); - a_read(data->store, &f->attribs, f); - if (data->version >= CLAIM_VERSION) { - read_items(data->store, &f->items); - } - for (;;) { - READ_TOK(data->store, name, sizeof(name)); - if (strcmp("end", name) == 0) - break; - READ_INT(data->store, &n); /* there used to be a level here, which is now ignored */ - } - READ_INT(data->store, &planes); - while (--planes >= 0) { - int id, ux, uy; - READ_INT(data->store, &id); - READ_INT(data->store, &ux); - READ_INT(data->store, &uy); - set_ursprung(f, id, ux, uy); - } - f->newbies = 0; - - READ_INT(data->store, &n); - f->options = n; - - if ((n & (want(O_REPORT) | want(O_COMPUTER))) == 0 && !is_monsters(f)) { - /* Kein Report eingestellt, Fehler */ - f->options |= (want(O_REPORT) | want(O_ZUGVORLAGE)); - } - - sfp = &f->allies; - if (data->version < ALLIANCES_VERSION) { - int p; - READ_INT(data->store, &p); - while (--p >= 0) { - int aid, state; - READ_INT(data->store, &aid); - READ_INT(data->store, &state); - sfp = addally(f, sfp, aid, state); + a_read(data->store, &f->attribs, f); + if (data->version >= CLAIM_VERSION) { + read_items(data->store, &f->items); } - } else { for (;;) { - int aid = 0; - if (data->version < STORAGE_VERSION) { READ_TOK(data->store, name, sizeof(name)); - if (strcmp(name, "end") != 0) { - aid = atoi36(name); - } - } else { - READ_INT(data->store, &aid); - } - if (aid > 0) { - int state; - READ_INT(data->store, &state); - sfp = addally(f, sfp, aid, state); - } else { - break; - } + if (strcmp("end", name) == 0) + break; + READ_INT(data->store, &n); /* there used to be a level here, which is now ignored */ } - } - read_groups(data->store, f); - f->spellbook = 0; - if (data->version >= REGIONOWNER_VERSION) { - read_spellbook(FactionSpells() ? &f->spellbook : 0, data->store, get_spell_level_faction, (void *)f); - } - return f; + READ_INT(data->store, &planes); + while (--planes >= 0) { + int id, ux, uy; + READ_INT(data->store, &id); + READ_INT(data->store, &ux); + READ_INT(data->store, &uy); + set_ursprung(f, id, ux, uy); + } + f->newbies = 0; + + READ_INT(data->store, &n); + f->options = n; + + if ((n & (want(O_REPORT) | want(O_COMPUTER))) == 0 && !is_monsters(f)) { + /* Kein Report eingestellt, Fehler */ + f->options |= (want(O_REPORT) | want(O_ZUGVORLAGE)); + } + + sfp = &f->allies; + if (data->version < ALLIANCES_VERSION) { + int p; + READ_INT(data->store, &p); + while (--p >= 0) { + int aid, state; + READ_INT(data->store, &aid); + READ_INT(data->store, &state); + sfp = addally(f, sfp, aid, state); + } + } + else { + for (;;) { + int aid = 0; + if (data->version < STORAGE_VERSION) { + READ_TOK(data->store, name, sizeof(name)); + if (strcmp(name, "end") != 0) { + aid = atoi36(name); + } + } + else { + READ_INT(data->store, &aid); + } + if (aid > 0) { + int state; + READ_INT(data->store, &state); + sfp = addally(f, sfp, aid, state); + } + else { + break; + } + } + } + read_groups(data->store, f); + f->spellbook = 0; + if (data->version >= REGIONOWNER_VERSION) { + read_spellbook(FactionSpells() ? &f->spellbook : 0, data->store, get_spell_level_faction, (void *)f); + } + return f; } void writefaction(struct gamedata *data, const faction * f) { - ally *sf; - ursprung *ur; + ally *sf; + ursprung *ur; - write_faction_reference(f, data->store); - WRITE_INT(data->store, f->subscription); - if (f->alliance) { - WRITE_INT(data->store, f->alliance->id); - if (f->alliance->flags & ALF_NON_ALLIED) { - assert(f == f->alliance->_leader - || !"non-allied faction is not leader of its own dummy-alliance."); + write_faction_reference(f, data->store); + WRITE_INT(data->store, f->subscription); + if (f->alliance) { + WRITE_INT(data->store, f->alliance->id); + if (f->alliance->flags & ALF_NON_ALLIED) { + assert(f == f->alliance->_leader + || !"non-allied faction is not leader of its own dummy-alliance."); + } + } + else { + WRITE_INT(data->store, 0); + } + WRITE_INT(data->store, f->alliance_joindate); + + WRITE_STR(data->store, (const char *)f->name); + WRITE_STR(data->store, (const char *)f->banner); + WRITE_STR(data->store, f->email); + WRITE_TOK(data->store, (const char *)f->passw); + WRITE_TOK(data->store, locale_name(f->locale)); + WRITE_INT(data->store, f->lastorders); + WRITE_INT(data->store, f->age); + WRITE_TOK(data->store, f->race->_name[0]); + WRITE_SECTION(data->store); + WRITE_INT(data->store, f->magiegebiet); + + WRITE_INT(data->store, f->flags & FFL_SAVEMASK); + a_write(data->store, f->attribs, f); + WRITE_SECTION(data->store); + write_items(data->store, f->items); + WRITE_SECTION(data->store); + WRITE_TOK(data->store, "end"); + WRITE_SECTION(data->store); + WRITE_INT(data->store, listlen(f->ursprung)); + for (ur = f->ursprung; ur; ur = ur->next) { + WRITE_INT(data->store, ur->id); + WRITE_INT(data->store, ur->x); + WRITE_INT(data->store, ur->y); + } + WRITE_SECTION(data->store); + WRITE_INT(data->store, f->options & ~want(O_DEBUG)); + WRITE_SECTION(data->store); + + for (sf = f->allies; sf; sf = sf->next) { + int no = (sf->faction != NULL) ? sf->faction->no : 0; + int status = alliedfaction(NULL, f, sf->faction, HELP_ALL); + if (status != 0) { + WRITE_INT(data->store, no); + WRITE_INT(data->store, sf->status); + } } - } else { WRITE_INT(data->store, 0); - } - WRITE_INT(data->store, f->alliance_joindate); - - WRITE_STR(data->store, (const char *)f->name); - WRITE_STR(data->store, (const char *)f->banner); - WRITE_STR(data->store, f->email); - WRITE_TOK(data->store, (const char *)f->passw); - WRITE_TOK(data->store, locale_name(f->locale)); - WRITE_INT(data->store, f->lastorders); - WRITE_INT(data->store, f->age); - WRITE_TOK(data->store, f->race->_name[0]); - WRITE_SECTION(data->store); - WRITE_INT(data->store, f->magiegebiet); - - WRITE_INT(data->store, f->flags & FFL_SAVEMASK); - a_write(data->store, f->attribs, f); - WRITE_SECTION(data->store); - write_items(data->store, f->items); - WRITE_SECTION(data->store); - WRITE_TOK(data->store, "end"); - WRITE_SECTION(data->store); - WRITE_INT(data->store, listlen(f->ursprung)); - for (ur = f->ursprung; ur; ur = ur->next) { - WRITE_INT(data->store, ur->id); - WRITE_INT(data->store, ur->x); - WRITE_INT(data->store, ur->y); - } - WRITE_SECTION(data->store); - WRITE_INT(data->store, f->options & ~want(O_DEBUG)); - WRITE_SECTION(data->store); - - for (sf = f->allies; sf; sf = sf->next) { - int no = (sf->faction != NULL) ? sf->faction->no : 0; - int status = alliedfaction(NULL, f, sf->faction, HELP_ALL); - if (status != 0) { - WRITE_INT(data->store, no); - WRITE_INT(data->store, sf->status); - } - } - WRITE_INT(data->store, 0); - WRITE_SECTION(data->store); - write_groups(data->store, f->groups); - write_spellbook(f->spellbook, data->store); + WRITE_SECTION(data->store); + write_groups(data->store, f->groups); + write_spellbook(f->spellbook, data->store); } int readgame(const char *filename, int backup) { - int i, n, p, nread; - faction *f, **fp; - region *r; - building *b, **bp; - ship **shp; - unit *u; - int rmax = maxregions; - char path[MAX_PATH]; - char name[DISPLAYSIZE]; - const struct building_type *bt_lighthouse = bt_find("lighthouse"); - gamedata gdata = { 0 }; - storage store; - FILE *F; + int i, n, p, nread; + faction *f, **fp; + region *r; + building *b, **bp; + ship **shp; + unit *u; + int rmax = maxregions; + char path[MAX_PATH]; + char name[DISPLAYSIZE]; + const struct building_type *bt_lighthouse = bt_find("lighthouse"); + gamedata gdata = { 0 }; + storage store; + FILE *F; - log_printf(stdout, "- reading game data from %s\n", filename); - sprintf(path, "%s/%s", datapath(), filename); + log_printf(stdout, "- reading game data from %s\n", filename); + sprintf(path, "%s/%s", datapath(), filename); - if (backup) { - create_backup(path); - } - - F = fopen(path, "rb"); - if (!F) { - perror(path); - return -1; - } - fread(&gdata.version, sizeof(int), 1, F); - if (gdata.version >= INTPAK_VERSION) { - int stream_version; - fread(&stream_version, sizeof(int), 1, F); - assert(stream_version == STREAM_VERSION || !"unsupported data format"); - } - assert(gdata.version >= MIN_VERSION || !"unsupported data format"); - assert(gdata.version <= RELEASE_VERSION || !"unsupported data format"); - - gdata.encoding = enc_gamedata; - binstore_init(&store, F); - gdata.store = &store; - global.data_version = gdata.version; /* HACK: attribute::read does not have access to gamedata, only storage */ - - if (gdata.version >= SAVEXMLNAME_VERSION) { - char basefile[1024]; - - READ_STR(&store, basefile, sizeof(basefile)); - if (strcmp(game_name, basefile) != 0) { - char buffer[64]; - strlcpy(buffer, game_name, sizeof(buffer)); - strlcat(buffer, ".xml", sizeof(buffer)); - if (strcmp(basefile, buffer) != 0) { - log_warning("game mismatch: datafile contains %s, game is %s\n", basefile, game_name); - printf("WARNING: any key to continue, Ctrl-C to stop\n"); - getchar(); - } + if (backup) { + create_backup(path); } - } - a_read(&store, &global.attribs, NULL); - READ_INT(&store, &turn); - global.data_turn = turn; - log_printf(stdout, " - reading turn %d\n", turn); - rng_init(turn); - ++global.cookie; - READ_INT(&store, &nread); /* max_unique_id = ignore */ - READ_INT(&store, &nextborder); - /* Planes */ - planes = NULL; - READ_INT(&store, &nread); - while (--nread >= 0) { - int id; - variant fno; - plane *pl; - - READ_INT(&store, &id); - pl = getplanebyid(id); - - if (pl == NULL) { - pl = calloc(1, sizeof(plane)); - } else { - log_warning("the plane with id=%d already exists.\n", id); + F = fopen(path, "rb"); + if (!F) { + perror(path); + return -1; } - pl->id = id; - READ_STR(&store, name, sizeof(name)); - pl->name = _strdup(name); - READ_INT(&store, &pl->minx); - READ_INT(&store, &pl->maxx); - READ_INT(&store, &pl->miny); - READ_INT(&store, &pl->maxy); - READ_INT(&store, &pl->flags); + fread(&gdata.version, sizeof(int), 1, F); + if (gdata.version >= INTPAK_VERSION) { + int stream_version; + fread(&stream_version, sizeof(int), 1, F); + assert(stream_version == STREAM_VERSION || !"unsupported data format"); + } + assert(gdata.version >= MIN_VERSION || !"unsupported data format"); + assert(gdata.version <= RELEASE_VERSION || !"unsupported data format"); - /* read watchers */ - if (gdata.version < FIX_WATCHERS_VERSION) { - char rname[64]; - /* before this version, watcher storage was pretty broken. we are incompatible and don't read them */ - for (;;) { - READ_TOK(&store, rname, sizeof(rname)); - if (strcmp(rname, "end") == 0) { - break; /* this is most likely the end of the list */ - } else { - log_error( - ("This datafile contains watchers, but we are unable to read them\n")); + gdata.encoding = enc_gamedata; + binstore_init(&store, F); + gdata.store = &store; + global.data_version = gdata.version; /* HACK: attribute::read does not have access to gamedata, only storage */ + + if (gdata.version >= SAVEGAMEID_VERSION) { + int gameid; + + READ_INT(&store, &gameid); + if (gameid != game_id()) { + log_warning("game mismatch: datafile contains game %d, but config is for %d\n", gameid, game_id()); + printf("WARNING: invalid game id. any key to continue, Ctrl-C to stop\n"); + getchar(); } - } - } else { - fno = read_faction_reference(&store); - while (fno.i) { - watcher *w = (watcher *) malloc(sizeof(watcher)); - ur_add(fno, &w->faction, resolve_faction); - READ_INT(&store, &n); - w->mode = (unsigned char)n; - w->next = pl->watchers; - pl->watchers = w; - fno = read_faction_reference(&store); - } } - a_read(&store, &pl->attribs, pl); - addlist(&planes, pl); - } - - /* Read factions */ - if (gdata.version >= ALLIANCES_VERSION) { - read_alliances(&store); - } - READ_INT(&store, &nread); - log_printf(stdout, " - Einzulesende Parteien: %d\n", nread); - fp = &factions; - while (*fp) - fp = &(*fp)->next; - - while (--nread >= 0) { - faction *f = readfaction(&gdata); - - *fp = f; - fp = &f->next; - fhash(f); - } - *fp = 0; - - /* ignore the obsolete list of "used" faction ids */ - if (gdata.version < STORAGE_VERSION) { - READ_INT(&store, &i); - while (i--) { - READ_INT(&store, &n); + else if (gdata.version >= SAVEXMLNAME_VERSION) { + char basefile[32]; + READ_STR(&store, basefile, sizeof(basefile)); } - } + a_read(&store, &global.attribs, NULL); + READ_INT(&store, &turn); + global.data_turn = turn; + log_printf(stdout, " - reading turn %d\n", turn); + rng_init(turn); + ++global.cookie; + READ_INT(&store, &nread); /* max_unique_id = ignore */ + READ_INT(&store, &nextborder); - /* Regionen */ + /* Planes */ + planes = NULL; + READ_INT(&store, &nread); + while (--nread >= 0) { + int id; + variant fno; + plane *pl; - READ_INT(&store, &nread); - assert(nread < MAXREGIONS); - if (rmax < 0) { - rmax = nread; - } - log_printf(stdout, " - Einzulesende Regionen: %d/%d\r", rmax, nread); - while (--nread >= 0) { - unit **up; - int x, y; - READ_INT(&store, &x); - READ_INT(&store, &y); + READ_INT(&store, &id); + pl = getplanebyid(id); - if ((nread & 0x3FF) == 0) { /* das spart extrem Zeit */ - log_printf(stdout, " - Einzulesende Regionen: %d/%d * %d,%d \r", rmax, nread, x, y); - } - --rmax; - - r = readregion(&gdata, x, y); - - /* Burgen */ - READ_INT(&store, &p); - bp = &r->buildings; - - while (--p >= 0) { - - b = (building *) calloc(1, sizeof(building)); - READ_INT(&store, &b->no); - *bp = b; - bp = &b->next; - bhash(b); - READ_STR(&store, name, sizeof(name)); - b->name = _strdup(name); - if (lomem) { - READ_STR(gdata.store, NULL, 0); - } else { + if (pl == NULL) { + pl = calloc(1, sizeof(plane)); + } + else { + log_warning("the plane with id=%d already exists.\n", id); + } + pl->id = id; READ_STR(&store, name, sizeof(name)); - b->display = _strdup(name); - } - READ_INT(&store, &b->size); - READ_STR(&store, name, sizeof(name)); - b->type = bt_find(name); - b->region = r; - a_read(&store, &b->attribs, b); - if (b->type == bt_lighthouse) { - r->flags |= RF_LIGHTHOUSE; - } - } - /* Schiffe */ + pl->name = _strdup(name); + READ_INT(&store, &pl->minx); + READ_INT(&store, &pl->maxx); + READ_INT(&store, &pl->miny); + READ_INT(&store, &pl->maxy); + READ_INT(&store, &pl->flags); - READ_INT(&store, &p); - shp = &r->ships; - - while (--p >= 0) { - ship *sh = (ship *) calloc(1, sizeof(ship)); - sh->region = r; - READ_INT(&store, &sh->no); - *shp = sh; - shp = &sh->next; - shash(sh); - READ_STR(&store, name, sizeof(name)); - sh->name = _strdup(name); - if (lomem) { - READ_STR(&store, NULL, 0); - } else { - READ_STR(&store, name, sizeof(name)); - sh->display = _strdup(name); - } - READ_STR(&store, name, sizeof(name)); - sh->type = st_find(name); - if (sh->type == NULL) { - /* old datafiles */ - sh->type = st_find((const char *)locale_string(default_locale, name)); - } - assert(sh->type || !"ship_type not registered!"); - - READ_INT(&store, &sh->size); - READ_INT(&store, &sh->damage); - if (gdata.version >= FOSS_VERSION) { - READ_INT(&store, &sh->flags); - } - - /* Attribute rekursiv einlesen */ - - READ_INT(&store, &n); - sh->coast = (direction_t)n; - if (sh->type->flags & SFL_NOCOAST) { - sh->coast = NODIRECTION; - } - a_read(&store, &sh->attribs, sh); - } - - *shp = 0; - - /* Einheiten */ - - READ_INT(&store, &p); - up = &r->units; - - while (--p >= 0) { - unit *u = read_unit(&gdata); - sc_mage *mage; - - assert(u->region == NULL); - u->region = r; - *up = u; - up = &u->next; - - update_interval(u->faction, u->region); - mage = get_mage(u); - if (mage) { - faction *f = u->faction; - int skl = effskill(u, SK_MAGIC); - if (!is_monsters(f) && f->magiegebiet == M_GRAY) { - log_error("faction %s had magic=gray, fixing (%s)\n", factionname(f), magic_school[mage->magietyp]); - f->magiegebiet = mage->magietyp; + /* read watchers */ + if (gdata.version < FIX_WATCHERS_VERSION) { + char rname[64]; + /* before this version, watcher storage was pretty broken. we are incompatible and don't read them */ + for (;;) { + READ_TOK(&store, rname, sizeof(rname)); + if (strcmp(rname, "end") == 0) { + break; /* this is most likely the end of the list */ + } + else { + log_error( + ("This datafile contains watchers, but we are unable to read them\n")); + } + } } - if (f->max_spelllevel < skl) { - f->max_spelllevel = skl; + else { + fno = read_faction_reference(&store); + while (fno.i) { + watcher *w = (watcher *)malloc(sizeof(watcher)); + ur_add(fno, &w->faction, resolve_faction); + READ_INT(&store, &n); + w->mode = (unsigned char)n; + w->next = pl->watchers; + pl->watchers = w; + fno = read_faction_reference(&store); + } } - if (mage->spellcount < 0) { - mage->spellcount = 0; + a_read(&store, &pl->attribs, pl); + addlist(&planes, pl); + } + + /* Read factions */ + if (gdata.version >= ALLIANCES_VERSION) { + read_alliances(&store); + } + READ_INT(&store, &nread); + log_printf(stdout, " - Einzulesende Parteien: %d\n", nread); + fp = &factions; + while (*fp) + fp = &(*fp)->next; + + while (--nread >= 0) { + faction *f = readfaction(&gdata); + + *fp = f; + fp = &f->next; + fhash(f); + } + *fp = 0; + + /* ignore the obsolete list of "used" faction ids */ + if (gdata.version < STORAGE_VERSION) { + READ_INT(&store, &i); + while (i--) { + READ_INT(&store, &n); } - } } - } - log_printf(stdout, "\n"); - read_borders(&store); - binstore_done(&store); + /* Regionen */ - /* Unaufgeloeste Zeiger initialisieren */ - log_printf(stdout, "fixing unresolved references.\n"); - resolve(); - - log_printf(stdout, "updating area information for lighthouses.\n"); - for (r = regions; r; r = r->next) { - if (r->flags & RF_LIGHTHOUSE) { - building *b; - for (b = r->buildings; b; b = b->next) - update_lighthouse(b); + READ_INT(&store, &nread); + assert(nread < MAXREGIONS); + if (rmax < 0) { + rmax = nread; } - } - log_printf(stdout, "marking factions as alive.\n"); - for (f = factions; f; f = f->next) { - if (f->flags & FFL_NPC) { - f->alive = 1; - if (f->no == 0) { - int no = 666; - while (findfaction(no)) - ++no; - log_warning("renum(monsters, %d)\n", no); - renumber_faction(f, no); - } - } else { - for (u = f->units; u; u = u->nextF) { - if (u->number > 0) { - f->alive = 1; - break; + log_printf(stdout, " - Einzulesende Regionen: %d/%d\r", rmax, nread); + while (--nread >= 0) { + unit **up; + int x, y; + READ_INT(&store, &x); + READ_INT(&store, &y); + + if ((nread & 0x3FF) == 0) { /* das spart extrem Zeit */ + log_printf(stdout, " - Einzulesende Regionen: %d/%d * %d,%d \r", rmax, nread, x, y); + } + --rmax; + + r = readregion(&gdata, x, y); + + /* Burgen */ + READ_INT(&store, &p); + bp = &r->buildings; + + while (--p >= 0) { + + b = (building *)calloc(1, sizeof(building)); + READ_INT(&store, &b->no); + *bp = b; + bp = &b->next; + bhash(b); + READ_STR(&store, name, sizeof(name)); + b->name = _strdup(name); + if (lomem) { + READ_STR(gdata.store, NULL, 0); + } + else { + READ_STR(&store, name, sizeof(name)); + b->display = _strdup(name); + } + READ_INT(&store, &b->size); + READ_STR(&store, name, sizeof(name)); + b->type = bt_find(name); + b->region = r; + a_read(&store, &b->attribs, b); + if (b->type == bt_lighthouse) { + r->flags |= RF_LIGHTHOUSE; + } + } + /* Schiffe */ + + READ_INT(&store, &p); + shp = &r->ships; + + while (--p >= 0) { + ship *sh = (ship *)calloc(1, sizeof(ship)); + sh->region = r; + READ_INT(&store, &sh->no); + *shp = sh; + shp = &sh->next; + shash(sh); + READ_STR(&store, name, sizeof(name)); + sh->name = _strdup(name); + if (lomem) { + READ_STR(&store, NULL, 0); + } + else { + READ_STR(&store, name, sizeof(name)); + sh->display = _strdup(name); + } + READ_STR(&store, name, sizeof(name)); + sh->type = st_find(name); + if (sh->type == NULL) { + /* old datafiles */ + sh->type = st_find((const char *)locale_string(default_locale, name)); + } + assert(sh->type || !"ship_type not registered!"); + + READ_INT(&store, &sh->size); + READ_INT(&store, &sh->damage); + if (gdata.version >= FOSS_VERSION) { + READ_INT(&store, &sh->flags); + } + + /* Attribute rekursiv einlesen */ + + READ_INT(&store, &n); + sh->coast = (direction_t)n; + if (sh->type->flags & SFL_NOCOAST) { + sh->coast = NODIRECTION; + } + a_read(&store, &sh->attribs, sh); + } + + *shp = 0; + + /* Einheiten */ + + READ_INT(&store, &p); + up = &r->units; + + while (--p >= 0) { + unit *u = read_unit(&gdata); + sc_mage *mage; + + assert(u->region == NULL); + u->region = r; + *up = u; + up = &u->next; + + update_interval(u->faction, u->region); + mage = get_mage(u); + if (mage) { + faction *f = u->faction; + int skl = effskill(u, SK_MAGIC); + if (!is_monsters(f) && f->magiegebiet == M_GRAY) { + log_error("faction %s had magic=gray, fixing (%s)\n", factionname(f), magic_school[mage->magietyp]); + f->magiegebiet = mage->magietyp; + } + if (f->max_spelllevel < skl) { + f->max_spelllevel = skl; + } + if (mage->spellcount < 0) { + mage->spellcount = 0; + } + } } - } } - } - if (loadplane || maxregions >= 0) { - remove_empty_factions(); - } - log_printf(stdout, "Done loading turn %d.\n", turn); - return 0; + log_printf(stdout, "\n"); + read_borders(&store); + + binstore_done(&store); + + /* Unaufgeloeste Zeiger initialisieren */ + log_printf(stdout, "fixing unresolved references.\n"); + resolve(); + + log_printf(stdout, "updating area information for lighthouses.\n"); + for (r = regions; r; r = r->next) { + if (r->flags & RF_LIGHTHOUSE) { + building *b; + for (b = r->buildings; b; b = b->next) + update_lighthouse(b); + } + } + log_printf(stdout, "marking factions as alive.\n"); + for (f = factions; f; f = f->next) { + if (f->flags & FFL_NPC) { + f->alive = 1; + if (f->no == 0) { + int no = 666; + while (findfaction(no)) + ++no; + log_warning("renum(monsters, %d)\n", no); + renumber_faction(f, no); + } + } + else { + for (u = f->units; u; u = u->nextF) { + if (u->number > 0) { + f->alive = 1; + break; + } + } + } + } + if (loadplane || maxregions >= 0) { + remove_empty_factions(); + } + log_printf(stdout, "Done loading turn %d.\n", turn); + return 0; } static void clear_monster_orders(void) { - faction *f = get_monsters(); - if (f) { - unit *u; - for (u = f->units; u; u = u->nextF) { - free_orders(&u->orders); + faction *f = get_monsters(); + if (f) { + unit *u; + for (u = f->units; u; u = u->nextF) { + free_orders(&u->orders); + } } - } } int writegame(const char *filename) { - char *base; - int n; - faction *f; - region *r; - building *b; - ship *sh; - unit *u; - plane *pl; - char path[MAX_PATH]; - gamedata gdata; - storage store; - FILE *F; + int n; + faction *f; + region *r; + building *b; + ship *sh; + unit *u; + plane *pl; + char path[MAX_PATH]; + gamedata gdata; + storage store; + FILE *F; - clear_monster_orders(); - sprintf(path, "%s/%s", datapath(), filename); + clear_monster_orders(); + sprintf(path, "%s/%s", datapath(), filename); #ifdef HAVE_UNISTD_H - if (access(path, R_OK) == 0) { - /* make sure we don't overwrite some hardlinkedfile */ - unlink(path); - } + if (access(path, R_OK) == 0) { + /* make sure we don't overwrite some hardlinkedfile */ + unlink(path); + } #endif - F = fopen(path, "wb"); - if (!F) { - /* we might be missing the directory, let's try creating it */ - int err = _mkdir(datapath()); - if (err) return err; F = fopen(path, "wb"); if (!F) { - perror(path); - return -1; + /* we might be missing the directory, let's try creating it */ + int err = _mkdir(datapath()); + if (err) return err; + F = fopen(path, "wb"); + if (!F) { + perror(path); + return -1; + } } - } - gdata.store = &store; - gdata.encoding = enc_gamedata; - gdata.version = RELEASE_VERSION; - n = STREAM_VERSION; - fwrite(&gdata.version, sizeof(int), 1, F); - fwrite(&n, sizeof(int), 1, F); + gdata.store = &store; + gdata.encoding = enc_gamedata; + gdata.version = RELEASE_VERSION; + n = STREAM_VERSION; + fwrite(&gdata.version, sizeof(int), 1, F); + fwrite(&n, sizeof(int), 1, F); - binstore_init(&store, F); + binstore_init(&store, F); - /* globale Variablen */ + /* globale Variablen */ - base = strrchr(game_name, '/'); - if (base) { - WRITE_STR(&store, base + 1); - } else { - WRITE_STR(&store, game_name); - } - WRITE_SECTION(&store); - - a_write(&store, global.attribs, NULL); - WRITE_SECTION(&store); - - WRITE_INT(&store, turn); - WRITE_INT(&store, 0 /*max_unique_id */ ); - WRITE_INT(&store, nextborder); - - /* Write planes */ - WRITE_SECTION(&store); - WRITE_INT(&store, listlen(planes)); - WRITE_SECTION(&store); - - for (pl = planes; pl; pl = pl->next) { - watcher *w; - WRITE_INT(&store, pl->id); - WRITE_STR(&store, pl->name); - WRITE_INT(&store, pl->minx); - WRITE_INT(&store, pl->maxx); - WRITE_INT(&store, pl->miny); - WRITE_INT(&store, pl->maxy); - WRITE_INT(&store, pl->flags); - w = pl->watchers; - while (w) { - if (w->faction) { - write_faction_reference(w->faction, &store); - WRITE_INT(&store, w->mode); - } - w = w->next; - } - write_faction_reference(NULL, &store); /* mark the end of the list */ - a_write(&store, pl->attribs, pl); + WRITE_INT(&store, game_id()); WRITE_SECTION(&store); - } - /* Write factions */ + a_write(&store, global.attribs, NULL); + WRITE_SECTION(&store); + + WRITE_INT(&store, turn); + WRITE_INT(&store, 0 /*max_unique_id */); + WRITE_INT(&store, nextborder); + + /* Write planes */ + WRITE_SECTION(&store); + WRITE_INT(&store, listlen(planes)); + WRITE_SECTION(&store); + + for (pl = planes; pl; pl = pl->next) { + watcher *w; + WRITE_INT(&store, pl->id); + WRITE_STR(&store, pl->name); + WRITE_INT(&store, pl->minx); + WRITE_INT(&store, pl->maxx); + WRITE_INT(&store, pl->miny); + WRITE_INT(&store, pl->maxy); + WRITE_INT(&store, pl->flags); + w = pl->watchers; + while (w) { + if (w->faction) { + write_faction_reference(w->faction, &store); + WRITE_INT(&store, w->mode); + } + w = w->next; + } + write_faction_reference(NULL, &store); /* mark the end of the list */ + a_write(&store, pl->attribs, pl); + WRITE_SECTION(&store); + } + + /* Write factions */ #if RELEASE_VERSION>=ALLIANCES_VERSION - write_alliances(&gdata); + write_alliances(&gdata); #endif - n = listlen(factions); - WRITE_INT(&store, n); - WRITE_SECTION(&store); - - log_printf(stdout, " - Schreibe %d Parteien...\n", n); - for (f = factions; f; f = f->next) { - writefaction(&gdata, f); + n = listlen(factions); + WRITE_INT(&store, n); WRITE_SECTION(&store); - } - /* Write regions */ - - n = listlen(regions); - WRITE_INT(&store, n); - WRITE_SECTION(&store); - log_printf(stdout, " - Schreibe Regionen: %d \r", n); - - for (r = regions; r; r = r->next, --n) { - /* plus leerzeile */ - if ((n % 1024) == 0) { /* das spart extrem Zeit */ - log_printf(stdout, " - Schreibe Regionen: %d \r", n); - fflush(stdout); - } - WRITE_SECTION(&store); - WRITE_INT(&store, r->x); - WRITE_INT(&store, r->y); - writeregion(&gdata, r); - - WRITE_INT(&store, listlen(r->buildings)); - WRITE_SECTION(&store); - for (b = r->buildings; b; b = b->next) { - write_building_reference(b, &store); - WRITE_STR(&store, b->name); - WRITE_STR(&store, b->display ? b->display : ""); - WRITE_INT(&store, b->size); - WRITE_TOK(&store, b->type->_name); - WRITE_SECTION(&store); - a_write(&store, b->attribs, b); - WRITE_SECTION(&store); + log_printf(stdout, " - Schreibe %d Parteien...\n", n); + for (f = factions; f; f = f->next) { + writefaction(&gdata, f); + WRITE_SECTION(&store); } - WRITE_INT(&store, listlen(r->ships)); + /* Write regions */ + + n = listlen(regions); + WRITE_INT(&store, n); WRITE_SECTION(&store); - for (sh = r->ships; sh; sh = sh->next) { - assert(sh->region == r); - write_ship_reference(sh, &store); - WRITE_STR(&store, (const char *)sh->name); - WRITE_STR(&store, sh->display ? (const char *)sh->display : ""); - WRITE_TOK(&store, sh->type->_name); - WRITE_INT(&store, sh->size); - WRITE_INT(&store, sh->damage); - WRITE_INT(&store, sh->flags & SFL_SAVEMASK); - assert((sh->type->flags & SFL_NOCOAST) == 0 || sh->coast == NODIRECTION); - WRITE_INT(&store, sh->coast); - WRITE_SECTION(&store); - a_write(&store, sh->attribs, sh); - WRITE_SECTION(&store); - } + log_printf(stdout, " - Schreibe Regionen: %d \r", n); - WRITE_INT(&store, listlen(r->units)); + for (r = regions; r; r = r->next, --n) { + /* plus leerzeile */ + if ((n % 1024) == 0) { /* das spart extrem Zeit */ + log_printf(stdout, " - Schreibe Regionen: %d \r", n); + fflush(stdout); + } + WRITE_SECTION(&store); + WRITE_INT(&store, r->x); + WRITE_INT(&store, r->y); + writeregion(&gdata, r); + + WRITE_INT(&store, listlen(r->buildings)); + WRITE_SECTION(&store); + for (b = r->buildings; b; b = b->next) { + write_building_reference(b, &store); + WRITE_STR(&store, b->name); + WRITE_STR(&store, b->display ? b->display : ""); + WRITE_INT(&store, b->size); + WRITE_TOK(&store, b->type->_name); + WRITE_SECTION(&store); + a_write(&store, b->attribs, b); + WRITE_SECTION(&store); + } + + WRITE_INT(&store, listlen(r->ships)); + WRITE_SECTION(&store); + for (sh = r->ships; sh; sh = sh->next) { + assert(sh->region == r); + write_ship_reference(sh, &store); + WRITE_STR(&store, (const char *)sh->name); + WRITE_STR(&store, sh->display ? (const char *)sh->display : ""); + WRITE_TOK(&store, sh->type->_name); + WRITE_INT(&store, sh->size); + WRITE_INT(&store, sh->damage); + WRITE_INT(&store, sh->flags & SFL_SAVEMASK); + assert((sh->type->flags & SFL_NOCOAST) == 0 || sh->coast == NODIRECTION); + WRITE_INT(&store, sh->coast); + WRITE_SECTION(&store); + a_write(&store, sh->attribs, sh); + WRITE_SECTION(&store); + } + + WRITE_INT(&store, listlen(r->units)); + WRITE_SECTION(&store); + for (u = r->units; u; u = u->next) { + write_unit(&gdata, u); + } + } + WRITE_SECTION(&store); + write_borders(&store); WRITE_SECTION(&store); - for (u = r->units; u; u = u->next) { - write_unit(&gdata, u); - } - } - WRITE_SECTION(&store); - write_borders(&store); - WRITE_SECTION(&store); - binstore_done(&store); + binstore_done(&store); - log_printf(stdout, "\nOk.\n"); - return 0; + log_printf(stdout, "\nOk.\n"); + return 0; } int a_readint(attrib * a, void *owner, struct storage *store) { - /* assert(sizeof(int)==sizeof(a->data)); */ - READ_INT(store, &a->data.i); - return AT_READ_OK; + /* assert(sizeof(int)==sizeof(a->data)); */ + READ_INT(store, &a->data.i); + return AT_READ_OK; } void a_writeint(const attrib * a, const void *owner, struct storage *store) { - WRITE_INT(store, a->data.i); + WRITE_INT(store, a->data.i); } int a_readshorts(attrib * a, void *owner, struct storage *store) { - int n; - if (global.data_version < ATTRIBREAD_VERSION) { - return a_readint(a, store, owner); - } - READ_INT(store, &n); - a->data.sa[0] = (short)n; - READ_INT(store, &n); - a->data.sa[1] = (short)n; - return AT_READ_OK; + int n; + if (global.data_version < ATTRIBREAD_VERSION) { + return a_readint(a, store, owner); + } + READ_INT(store, &n); + a->data.sa[0] = (short)n; + READ_INT(store, &n); + a->data.sa[1] = (short)n; + return AT_READ_OK; } void a_writeshorts(const attrib * a, const void *owner, struct storage *store) { - WRITE_INT(store, a->data.sa[0]); - WRITE_INT(store, a->data.sa[1]); + WRITE_INT(store, a->data.sa[0]); + WRITE_INT(store, a->data.sa[1]); } int a_readchars(attrib * a, void *owner, struct storage *store) { - int i; - if (global.data_version < ATTRIBREAD_VERSION) { - return a_readint(a, store, owner); - } - for (i = 0; i != 4; ++i) { - int n; - READ_INT(store, &n); - a->data.ca[i] = (char)n; - } - return AT_READ_OK; + int i; + if (global.data_version < ATTRIBREAD_VERSION) { + return a_readint(a, store, owner); + } + for (i = 0; i != 4; ++i) { + int n; + READ_INT(store, &n); + a->data.ca[i] = (char)n; + } + return AT_READ_OK; } void a_writechars(const attrib * a, const void *owner, struct storage *store) { - int i; + int i; - for (i = 0; i != 4; ++i) { - WRITE_INT(store, a->data.ca[i]); - } + for (i = 0; i != 4; ++i) { + WRITE_INT(store, a->data.ca[i]); + } } int a_readvoid(attrib * a, void *owner, struct storage *store) { - if (global.data_version < ATTRIBREAD_VERSION) { - return a_readint(a, store, owner); - } - return AT_READ_OK; + if (global.data_version < ATTRIBREAD_VERSION) { + return a_readint(a, store, owner); + } + return AT_READ_OK; } void a_writevoid(const attrib * a, const void *owner, struct storage *store) @@ -1975,32 +2011,32 @@ void a_writevoid(const attrib * a, const void *owner, struct storage *store) int a_readstring(attrib * a, void *owner, struct storage *store) { - char buf[DISPLAYSIZE]; - char * result = 0; - int e; - size_t len = 0; - do { - e = READ_STR(store, buf, sizeof(buf)); - if (result) { - result = realloc(result, len + DISPLAYSIZE - 1); - strcpy(result + len, buf); - len += DISPLAYSIZE - 1; - } - else { - result = _strdup(buf); - } - } while (e == ENOMEM); - a->data.v = result; - return AT_READ_OK; + char buf[DISPLAYSIZE]; + char * result = 0; + int e; + size_t len = 0; + do { + e = READ_STR(store, buf, sizeof(buf)); + if (result) { + result = realloc(result, len + DISPLAYSIZE - 1); + strcpy(result + len, buf); + len += DISPLAYSIZE - 1; + } + else { + result = _strdup(buf); + } + } while (e == ENOMEM); + a->data.v = result; + return AT_READ_OK; } void a_writestring(const attrib * a, const void *owner, struct storage *store) { - assert(a->data.v); - WRITE_STR(store, (const char *)a->data.v); + assert(a->data.v); + WRITE_STR(store, (const char *)a->data.v); } void a_finalizestring(attrib * a) { - free(a->data.v); + free(a->data.v); } diff --git a/src/kernel/save.h b/src/kernel/save.h index c7654788a..775624f11 100644 --- a/src/kernel/save.h +++ b/src/kernel/save.h @@ -39,7 +39,6 @@ extern "C" { /* Versionsänderungen: */ extern int data_version; - extern const char *game_name; extern int enc_gamedata; extern int current_turn(void); diff --git a/src/kernel/version.h b/src/kernel/version.h index fb835e138..06a343ae9 100644 --- a/src/kernel/version.h +++ b/src/kernel/version.h @@ -71,8 +71,9 @@ #define SPELLBOOK_VERSION 340 /* turn 775, full spellbooks are stored for factions */ #define NOOVERRIDE_VERSION 341 /* turn 775, full spellbooks are stored for factions */ #define INTFLAGS_VERSION 342 /* turn 876, FFL_NPC is now bit 25, flags is an int */ +#define SAVEGAMEID_VERSION 343 /* instead of XMLNAME, save the game.id parameter from the config */ #define MIN_VERSION CURSETYPE_VERSION /* minimal datafile we support */ -#define RELEASE_VERSION INTFLAGS_VERSION /* current datafile */ +#define RELEASE_VERSION SAVEGAMEID_VERSION /* current datafile */ #define STREAM_VERSION 2 /* internal encoding of binary files */ diff --git a/src/main.c b/src/main.c index ac6b08338..a24800064 100644 --- a/src/main.c +++ b/src/main.c @@ -59,13 +59,7 @@ static void parse_config(const char *filename) /* only one value in the [editor] section */ force_color = iniparser_getint(d, "editor:color", force_color); #endif - /* excerpt from [config] (the rest is used in bindings.c) */ - game_name = iniparser_getstring(d, "config:game", game_name); } - else { - log_error("could not open configuration file %s\n", filename); - } - global.inifile = d; } static int usage(const char *prog, const char *arg) @@ -109,7 +103,7 @@ static int parse_args(int argc, char **argv, int *exitcode) printf("\n%s PBEM host\n" "Copyright (C) 1996-2005 C. Schlittchen, K. Zedel, E. Rehling, H. Peters.\n\n" "Compilation: " __DATE__ " at " __TIME__ "\nVersion: %d.%d.%d\n\n", - global.gamename, VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD); + game_name(), VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD); #ifdef USE_CURSES } else if (strcmp(argv[i] + 2, "color") == 0) { @@ -261,12 +255,13 @@ int main(int argc, char **argv) return err; } /* ini file sets defaults for arguments*/ - if (confpath) { + parse_config(inifile); + if (!global.inifile && confpath) { _snprintf(inipath, sizeof(inipath), "%s/%s", confpath, inifile); parse_config(inipath); } - else { - parse_config(inifile); + if (!global.inifile) { + log_error("could not open ini configuration %s\n", inifile); } /* parse arguments again, to override ini file */ parse_args(argc, argv, &err); diff --git a/src/report.c b/src/report.c index 918e5cbe7..b4a7a9bcd 100644 --- a/src/report.c +++ b/src/report.c @@ -2119,7 +2119,7 @@ report_plaintext(const char *filename, report_context * ctx, } strftime(pzTime, 64, "%A, %d. %B %Y, %H:%M", localtime(&ctx->report_time)); - m = msg_message("nr_header_date", "game date", global.gamename, pzTime); + m = msg_message("nr_header_date", "game date", game_name(), pzTime); nr_render(m, f->locale, buf, sizeof(buf), f); msg_release(m); centre(F, buf, true); diff --git a/src/report.h b/src/report.h index 8a338115f..9f4367d9a 100644 --- a/src/report.h +++ b/src/report.h @@ -15,8 +15,8 @@ extern "C" { #endif - extern void register_nr(void); - extern void report_cleanup(void); + void register_nr(void); + void report_cleanup(void); #ifdef __cplusplus } diff --git a/src/summary.c b/src/summary.c index 7924f2462..5eafa47ab 100644 --- a/src/summary.c +++ b/src/summary.c @@ -161,7 +161,7 @@ void report_summary(summary * s, summary * o, bool full) } #endif printf("Schreibe Zusammenfassung (parteien)...\n"); - fprintf(F, "%s\n%s\n\n", global.gamename, gamedate2(default_locale)); + fprintf(F, "%s\n%s\n\n", game_name(), gamedate2(default_locale)); fprintf(F, "Auswertung Nr: %d\n\n", turn); fprintf(F, "Parteien: %s\n", pcomp(s->factions, o->factions)); fprintf(F, "Einheiten: %s\n", pcomp(s->nunits, o->nunits));