From 64b84481b2f9542078afcf06dbc164211ab3dfbd Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 24 Nov 2015 18:52:09 +0100 Subject: [PATCH] refactoring: move parsing and allies code out of config.c --- src/attributes/otherfaction.c | 1 + src/battle.c | 1 + src/economy.c | 1 + src/give.c | 1 + src/kernel/ally.c | 200 +++++++++++++++++++++++++ src/kernel/ally.h | 12 ++ src/kernel/build.c | 1 + src/kernel/config.c | 269 ---------------------------------- src/kernel/config.h | 15 -- src/kernel/pool.c | 1 + src/kernel/unit.c | 84 +++++++++++ src/kernel/unit.h | 4 + src/magic.c | 1 + src/move.c | 1 + src/piracy.c | 1 + src/reports.c | 1 + src/study.c | 1 + src/upkeep.c | 1 + 18 files changed, 312 insertions(+), 284 deletions(-) diff --git a/src/attributes/otherfaction.c b/src/attributes/otherfaction.c index 76d035dd1..8e4e7a6af 100644 --- a/src/attributes/otherfaction.c +++ b/src/attributes/otherfaction.c @@ -20,6 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include "otherfaction.h" +#include #include #include #include diff --git a/src/battle.c b/src/battle.c index 6e642ff00..57004514b 100644 --- a/src/battle.c +++ b/src/battle.c @@ -27,6 +27,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "skill.h" #include "monster.h" +#include #include #include #include diff --git a/src/economy.c b/src/economy.c index e4e52e0ce..be26c5d57 100644 --- a/src/economy.c +++ b/src/economy.c @@ -35,6 +35,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "calendar.h" /* kernel includes */ +#include #include #include #include diff --git a/src/give.c b/src/give.c index 634a37be6..8d2fd5b0c 100644 --- a/src/give.c +++ b/src/give.c @@ -18,6 +18,7 @@ #include "laws.h" /* kernel includes */ +#include #include #include #include diff --git a/src/kernel/ally.c b/src/kernel/ally.c index ed53cbce4..5e1742559 100644 --- a/src/kernel/ally.c +++ b/src/kernel/ally.c @@ -1,6 +1,17 @@ +#include "platform.h" +#include "config.h" #include "types.h" #include "ally.h" +#include "save.h" +#include "unit.h" +#include "region.h" +#include "group.h" +#include "faction.h" +#include "plane.h" + +#include +#include #include ally * ally_find(ally *al, const struct faction *f) { @@ -37,3 +48,192 @@ void ally_remove(ally **al_p, struct faction *f) { al_p = &al->next; } } + +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; +} + +/** Specifies automatic alliance modes. +* If this returns a value then the bits set are immutable between alliance +* partners (faction::alliance) and cannot be changed with the HELP command. +*/ +int AllianceAuto(void) +{ + int value; + const char *str = config_get("alliance.auto"); + 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(); +} + +static int +autoalliance(const plane * pl, const faction * sf, const faction * f2) +{ + if (pl && (pl->flags & PFL_FRIENDLY)) + return HELP_ALL; + + 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; +} + +static void init_npcfaction(struct attrib *a) +{ + a->data.i = 1; +} + +attrib_type at_npcfaction = { + "npcfaction", + init_npcfaction, + NULL, + NULL, + a_writeint, + a_readint, + ATF_UNIQUE +}; + +/** Limits the available help modes +* The bitfield returned by this function specifies the available help modes +* in this game (so you can, for example, disable HELP GIVE globally). +* Disabling a status will disable the command sequence entirely (order parsing +* uses this function). +*/ +int HelpMask(void) +{ + const char *str = config_get("rules.help.mask"); + int 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; +} + +static int AllianceRestricted(void) +{ + const char *str = config_get("alliance.restricted"); + int 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(); + return rule; +} + +int +alliedgroup(const struct plane *pl, const struct faction *f, + 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; + } + if (a_findc(f2->attribs, &at_npcfaction)) { + return mode; + } + if (f->alliance != f2->alliance) { + mode &= ~AllianceRestricted(); + } + } + return mode; +} + +int +alliedfaction(const struct plane *pl, const struct faction *f, + const struct faction *f2, int 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; + + assert(u); + assert(f2); + 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; + } + } + } + + 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; +} + diff --git a/src/kernel/ally.h b/src/kernel/ally.h index 55f8dc935..cd3f4c031 100644 --- a/src/kernel/ally.h +++ b/src/kernel/ally.h @@ -23,6 +23,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. extern "C" { #endif + struct attrib_type; + extern struct attrib_type at_npcfaction; + typedef struct ally { struct ally *next; struct faction *faction; @@ -33,6 +36,15 @@ extern "C" { ally * ally_add(ally **al_p, struct faction *f); void ally_remove(ally **al_p, struct faction *f); + int AllianceAuto(void); /* flags that allied factions get automatically */ + int HelpMask(void); /* flags restricted to allied factions */ + 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); + #ifdef __cplusplus } #endif diff --git a/src/kernel/build.c b/src/kernel/build.c index 7c387cb10..98ca2b28e 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -28,6 +28,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "lighthouse.h" /* kernel includes */ +#include #include #include #include diff --git a/src/kernel/config.c b/src/kernel/config.c index aa67d3fb0..ed6393349 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -117,91 +117,11 @@ bool IsImmune(const faction * f) return !fval(f, FFL_NPC) && f->age < NewbieImmunity(); } -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; -} - bool ExpensiveMigrants(void) { return config_get_int("study.expensivemigrants", 0) != 0; } -/** Specifies automatic alliance modes. - * If this returns a value then the bits set are immutable between alliance - * partners (faction::alliance) and cannot be changed with the HELP command. - */ -int AllianceAuto(void) -{ - int value; - const char *str = config_get("alliance.auto"); - 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(); -} - -/** Limits the available help modes - * The bitfield returned by this function specifies the available help modes - * in this game (so you can, for example, disable HELP GIVE globally). - * Disabling a status will disable the command sequence entirely (order parsing - * uses this function). - */ -int HelpMask(void) -{ - const char *str = config_get("rules.help.mask"); - int 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; -} - -int AllianceRestricted(void) -{ - const char *str = config_get("alliance.restricted"); - int 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(); - return rule; -} - int LongHunger(const struct unit *u) { if (u != NULL) { @@ -375,21 +295,6 @@ int max_magicians(const faction * f) return m; } -static void init_npcfaction(struct attrib *a) -{ - a->data.i = 1; -} - -static attrib_type at_npcfaction = { - "npcfaction", - init_npcfaction, - NULL, - NULL, - a_writeint, - a_readint, - ATF_UNIQUE -}; - FILE *debug; /* ----------------------------------------------------------------------- */ @@ -422,98 +327,7 @@ bool unit_has_cursed_item(const unit * u) return false; } -static int -autoalliance(const plane * pl, const faction * sf, const faction * f2) -{ - if (pl && (pl->flags & PFL_FRIENDLY)) - return HELP_ALL; - 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; -} - -int -alliedgroup(const struct plane *pl, const struct faction *f, - 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; - } - if (a_findc(f2->attribs, &at_npcfaction)) { - return mode; - } - if (f->alliance != f2->alliance) { - mode &= ~AllianceRestricted(); - } - } - return mode; -} - -int -alliedfaction(const struct plane *pl, const struct faction *f, - const struct faction *f2, int 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; - - assert(u); - assert(f2); - 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; - } - } - } - - 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; -} void parse(keyword_t kword, int(*dofun) (unit *, struct order *), bool thisorder) { @@ -632,67 +446,6 @@ unit *getnewunit(const region * r, const faction * f) return findnewunit(r, f, n); } -static int read_newunitid(const faction * f, const region * r) -{ - int n; - unit *u2; - n = getid(); - if (n == 0) - return -1; - - u2 = findnewunit(r, f, n); - if (u2) - return u2->no; - - return -1; -} - -int read_unitid(const faction * f, const region * r) -{ - char token[16]; - const char *s = gettoken(token, sizeof(token)); - - /* 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 || !isalnum(*s)) { - return -1; - } - if (isparam(s, f->locale, P_TEMP)) { - return read_newunitid(f, r); - } - return atoi36((const char *)s); -} - -int getunit(const region * r, const faction * f, unit **uresult) -{ - unit *u2 = NULL; - int n = read_unitid(f, r); - int result = GET_NOTFOUND; - - if (n == 0) { - result = GET_PEASANTS; - } - else if (n > 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 - */ - result = GET_UNIT; - } - else { - u2 = NULL; - } - } - if (uresult) { - *uresult = u2; - } - return result; -} - /* - Namen der Strukturen -------------------------------------- */ char *untilde(char *ibuf) { @@ -753,28 +506,6 @@ int forbiddenid(int id) 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; - - 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; - } - } - return random_unit_no; -} - int newcontainerid(void) { int random_no; diff --git a/src/kernel/config.h b/src/kernel/config.h index 14cfa6d2c..2296f0d99 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -73,21 +73,9 @@ struct param; int distribute(int old, int new_value, int n); void init_locale(struct locale *lang); - int newunitid(void); int forbiddenid(int id); int newcontainerid(void); - int getunit(const struct region * r, const struct faction * f, struct unit **uresult); - - 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); - struct faction *getfaction(void); char *untilde(char *s); @@ -220,9 +208,6 @@ struct param; 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); void set_default_order(int kwd); diff --git a/src/kernel/pool.c b/src/kernel/pool.c index 442553c28..6ceeda63d 100644 --- a/src/kernel/pool.c +++ b/src/kernel/pool.c @@ -20,6 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include "pool.h" +#include "ally.h" #include "faction.h" #include "item.h" #include "order.h" diff --git a/src/kernel/unit.c b/src/kernel/unit.c index bc403909c..5b3fae62c 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -20,6 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include "unit.h" +#include "ally.h" #include "building.h" #include "faction.h" #include "group.h" @@ -54,6 +55,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include #include #include @@ -1935,3 +1937,85 @@ void produceexp(struct unit *u, skill_t sk, int n) produceexp_ex(u, sk, n, learn_skill); } +/* 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; + + 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; + } + } + return random_unit_no; +} + +static int read_newunitid(const faction * f, const region * r) +{ + int n; + unit *u2; + n = getid(); + if (n == 0) + return -1; + + u2 = findnewunit(r, f, n); + if (u2) + return u2->no; + + return -1; +} + +int read_unitid(const faction * f, const region * r) +{ + char token[16]; + const char *s = gettoken(token, sizeof(token)); + + /* 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 || !isalnum(*s)) { + return -1; + } + if (isparam(s, f->locale, P_TEMP)) { + return read_newunitid(f, r); + } + return atoi36((const char *)s); +} + +int getunit(const region * r, const faction * f, unit **uresult) +{ + unit *u2 = NULL; + int n = read_unitid(f, r); + int result = GET_NOTFOUND; + + if (n == 0) { + result = GET_PEASANTS; + } + else if (n > 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 + */ + result = GET_UNIT; + } + else { + u2 = NULL; + } + } + if (uresult) { + *uresult = u2; + } + return result; +} diff --git a/src/kernel/unit.h b/src/kernel/unit.h index 7f8cca095..ee9d8ecfd 100644 --- a/src/kernel/unit.h +++ b/src/kernel/unit.h @@ -256,6 +256,10 @@ extern "C" { bool unit_name_equals_race(const struct unit *u); bool unit_can_study(const struct unit *u); + int newunitid(void); + int getunit(const struct region * r, const struct faction * f, struct unit **uresult); + int read_unitid(const struct faction *f, const struct region *r); + #ifdef __cplusplus } #endif diff --git a/src/magic.c b/src/magic.c index 510240a74..065a58e7c 100644 --- a/src/magic.c +++ b/src/magic.c @@ -24,6 +24,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "skill.h" #include "laws.h" +#include #include #include #include diff --git a/src/move.c b/src/move.c index 45a0c1fb8..063635178 100644 --- a/src/move.c +++ b/src/move.c @@ -29,6 +29,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "lighthouse.h" #include "piracy.h" +#include #include #include #include diff --git a/src/piracy.c b/src/piracy.c index e9bcb6105..8b215d718 100644 --- a/src/piracy.c +++ b/src/piracy.c @@ -6,6 +6,7 @@ #include "keyword.h" #include "move.h" +#include #include #include #include diff --git a/src/reports.c b/src/reports.c index 29b459f20..24ff6dcb2 100644 --- a/src/reports.c +++ b/src/reports.c @@ -26,6 +26,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "donations.h" /* kernel includes */ +#include #include #include #include diff --git a/src/study.c b/src/study.c index 9d3edddb1..a20959408 100644 --- a/src/study.c +++ b/src/study.c @@ -25,6 +25,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "move.h" #include "alchemy.h" +#include #include #include #include diff --git a/src/upkeep.c b/src/upkeep.c index da9cbff74..193c68480 100644 --- a/src/upkeep.c +++ b/src/upkeep.c @@ -1,6 +1,7 @@ #include #include "upkeep.h" +#include #include #include #include