diff --git a/src/give.c b/src/give.c index 8d2fd5b0c..52b1cda34 100644 --- a/src/give.c +++ b/src/give.c @@ -209,6 +209,17 @@ struct order *ord) return 0; } +static bool unit_has_cursed_item(const unit * u) +{ + item *itm = u->items; + while (itm) { + if (fval(itm->type, ITF_CURSED) && itm->number > 0) + return true; + itm = itm->next; + } + return false; +} + static bool can_give_men(const unit *u, order *ord, message **msg) { if (u_race(u) == get_race(RC_SNOTLING)) { /* snotlings may not be given to the peasants. */ diff --git a/src/kernel/config.c b/src/kernel/config.c index fb316c086..56022ef74 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -165,22 +165,6 @@ helpmode helpmodes[] = { { 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]; // FIXME: static return value - char *zPtr = zText; - - /* the english names are all in ASCII, so we don't need to worry about UTF8 */ - strlcpy(zText, (const char *)LOC(get_locale("en"), rc_name_s(rc, NAME_SINGULAR)), sizeof(zText)); - while (*zPtr) { - *zPtr = (char)(toupper(*zPtr)); - ++zPtr; - } - return zText; -} - const char *parameters[MAXPARAMS] = { "LOCALE", "ALLES", @@ -267,37 +251,6 @@ const char *options[MAXOPTIONS] = { FILE *debug; -/* ----------------------------------------------------------------------- */ - -int distribute(int old, int new_value, int n) -{ - int i; - int t; - assert(new_value <= old); - - if (old == 0) - return 0; - - t = (n / old) * new_value; - for (i = (n % old); i; i--) - if (rng_int() % old < new_value) - t++; - - return t; -} - -bool unit_has_cursed_item(const unit * u) -{ - item *itm = u->items; - while (itm) { - if (fval(itm->type, ITF_CURSED) && itm->number > 0) - return true; - itm = itm->next; - } - return false; -} - - void parse(keyword_t kword, int(*dofun) (unit *, struct order *), bool thisorder) { @@ -403,11 +356,6 @@ param_t getparam(const struct locale * lang) return s ? findparam(s, lang) : NOPARAM; } -faction *getfaction(void) -{ - return findfaction(getid()); -} - unit *getnewunit(const region * r, const faction * f) { int n; @@ -450,8 +398,6 @@ building *largestbuilding(const region * r, cmp_building_cb cmp_gt, /* -- Erschaffung neuer Einheiten ------------------------------ */ -extern faction *dfindhash(int i); - static const char *forbidden[] = { "t", "te", "tem", "temp", NULL }; // PEASANT: "b", "ba", "bau", "baue", "p", "pe", "pea", "peas" @@ -756,14 +702,6 @@ void kernel_done(void) free_attribs(); } -void setstatus(struct unit *u, int status) -{ - assert(status >= ST_AGGRO && status <= ST_FLEE); - if (u->status != status) { - u->status = (status_t)status; - } -} - #ifndef HAVE_STRDUP char *_strdup(const char *s) { @@ -771,24 +709,6 @@ char *_strdup(const char *s) } #endif -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); -} - -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; -} - /* Lohn bei den einzelnen Burgstufen für Normale Typen, Orks, Bauern, * Modifikation für Städter. */ @@ -1026,19 +946,6 @@ int wage(const region * r, const faction * f, const race * rc, int 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; -} - int lovar(double xpct_x2) { int n = (int)(xpct_x2 * 500) + 1; @@ -1047,18 +954,6 @@ int lovar(double xpct_x2) 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; - } -} - void kernel_init(void) { register_reports(); diff --git a/src/kernel/config.h b/src/kernel/config.h index 3c1b90528..257de940d 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -70,8 +70,6 @@ struct param; int forbiddenid(int id); int newcontainerid(void); - struct faction *getfaction(void); - char *untilde(char *s); typedef int(*cmp_building_cb) (const struct building * b, @@ -101,11 +99,8 @@ struct param; #define GIVE_DEFAULT (GIVE_SELF|GIVE_PEASANTS|GIVE_LUXURIES|GIVE_HERBS|GIVE_GOODS) int rule_give(void); - bool has_limited_skills(const struct unit *u); const struct race *findrace(const char *, const struct locale *); - bool unit_has_cursed_item(const struct unit *u); - /* grammatik-flags: */ #define GF_NONE 0 /* singular, ohne was dran */ @@ -139,15 +134,10 @@ struct param; /* Verhindert Abbau von Resourcen mit RTF_LIMITED */ #define GUARD_ALL 0xFFFF - void setstatus(struct unit *u, int status); - /* !< sets combatstatus of a unit */ - int besieged(const struct unit *u); int maxworkingpeasants(const struct region *r); - bool has_horses(const struct unit *u); bool 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); const char *datapath(void); void set_datapath(const char *path); @@ -182,8 +172,6 @@ struct param; int status; } helpmode; - const char *dbrace(const struct race *rc); - void set_param(struct param **p, const char *key, const char *value); const char *get_param(const struct param *p, const char *key); int get_param_int(const struct param *p, const char *key, int def); diff --git a/src/kernel/faction.c b/src/kernel/faction.c index 324c4b180..6bc28e3e6 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -45,13 +45,15 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include +#include #include #include #include #include + #include +#include #include /* libc includes */ @@ -152,6 +154,11 @@ faction *findfaction(int n) return f; } +faction *getfaction(void) +{ + return findfaction(getid()); +} + void set_show_item(faction * f, const struct item_type *itype) { attrib *a = a_add(&f->attribs, a_new(&at_showitem)); @@ -803,3 +810,36 @@ int max_magicians(const faction * f) return m; } +#define DMAXHASH 7919 +typedef struct dead { + struct dead *nexthash; + faction *f; + int no; +} dead; + +static dead *deadhash[DMAXHASH]; + +void dhash(int no, faction * f) +{ + dead *hash = (dead *)calloc(1, sizeof(dead)); + dead *old = deadhash[no % DMAXHASH]; + hash->no = no; + hash->f = f; + deadhash[no % DMAXHASH] = hash; + hash->nexthash = old; +} + +faction *dfindhash(int no) +{ + dead *old; + + if (no < 0) + return 0; + + for (old = deadhash[no % DMAXHASH]; old; old = old->nexthash) { + if (old->no == no) { + return old->f; + } + } + return 0; +} diff --git a/src/kernel/faction.h b/src/kernel/faction.h index 4f47daaab..d22763d96 100644 --- a/src/kernel/faction.h +++ b/src/kernel/faction.h @@ -177,6 +177,12 @@ extern "C" { int count_units(const struct faction * f); int max_magicians(const struct faction * f); + struct faction *getfaction(void); + + /* looking up dead factions: */ + void dhash(int no, struct faction * f); + struct faction *dfindhash(int no); + #ifdef __cplusplus } #endif diff --git a/src/kernel/race.c b/src/kernel/race.c index 7d881fe7f..07de520ab 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -301,3 +301,20 @@ variant read_race_reference(struct storage *store) assert(result.v != NULL); return result; } + +/** Returns the English name of the race, which is what the database uses. +*/ +const char *dbrace(const struct race *rc) +{ + static char zText[32]; // FIXME: static return value + char *zPtr = zText; + + /* the english names are all in ASCII, so we don't need to worry about UTF8 */ + strlcpy(zText, (const char *)LOC(get_locale("en"), rc_name_s(rc, NAME_SINGULAR)), sizeof(zText)); + while (*zPtr) { + *zPtr = (char)(toupper(*zPtr)); + ++zPtr; + } + return zText; +} + diff --git a/src/kernel/race.h b/src/kernel/race.h index 0ae925c5d..c994746d9 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -233,8 +233,8 @@ extern "C" { #define BF_INV_NONMAGIC (1<<5) /* Immun gegen nichtmagischen Schaden */ #define BF_CANATTACK (1<<6) /* Kann keine ATTACKIERE Befehle ausfuehren */ - extern int unit_old_max_hp(struct unit *u); - extern const char *racename(const struct locale *lang, const struct unit *u, + int unit_old_max_hp(struct unit *u); + const char *racename(const struct locale *lang, const struct unit *u, const race * rc); #define omniscient(f) ((f)->race==get_race(RC_ILLUSION) || (f)->race==get_race(RC_TEMPLATE)) @@ -244,19 +244,20 @@ extern "C" { #define humanoidrace(rc) (fval((rc), RCF_UNDEAD) || (rc)==get_race(RC_DRACOID) || playerrace(rc)) #define illusionaryrace(rc) (fval(rc, RCF_ILLUSIONARY)) - extern bool allowed_dragon(const struct region *src, + bool allowed_dragon(const struct region *src, const struct region *target); - extern bool r_insectstalled(const struct region *r); + bool r_insectstalled(const struct region *r); - extern void write_race_reference(const struct race *rc, - struct storage *store); - extern variant read_race_reference(struct storage *store); + void write_race_reference(const struct race *rc, + struct storage *store); + variant read_race_reference(struct storage *store); - extern const char *raceprefix(const struct unit *u); + const char *raceprefix(const struct unit *u); - extern void give_starting_equipment(const struct equipment *eq, - struct unit *u); + void give_starting_equipment(const struct equipment *eq, + struct unit *u); + const char *dbrace(const struct race *rc); #ifdef __cplusplus } diff --git a/src/kernel/unit.c b/src/kernel/unit.c index b56c8220b..64db18193 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -183,40 +183,6 @@ unit *ufindhash(int uid) return NULL; } -#define DMAXHASH 7919 -typedef struct dead { - struct dead *nexthash; - faction *f; - int no; -} dead; - -static dead *deadhash[DMAXHASH]; - -static void dhash(int no, faction * f) -{ - dead *hash = (dead *)calloc(1, sizeof(dead)); - dead *old = deadhash[no % DMAXHASH]; - hash->no = no; - hash->f = f; - deadhash[no % DMAXHASH] = hash; - hash->nexthash = old; -} - -faction *dfindhash(int no) -{ - dead *old; - - if (no < 0) - return 0; - - for (old = deadhash[no % DMAXHASH]; old; old = old->nexthash) { - if (old->no == no) { - return old->f; - } - } - return 0; -} - typedef struct buddy { struct buddy *next; int number; @@ -2020,3 +1986,59 @@ int getunit(const region * r, const faction * f, unit **uresult) } return result; } + +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); +} + +bool has_horses(const unit * u) +{ + item *itm = u->items; + for (; itm; itm = itm->next) { + if (itm->type->flags & ITF_ANIMAL) + return true; + } + return false; +} + +void setstatus(unit *u, int status) +{ + assert(status >= ST_AGGRO && status <= ST_FLEE); + if (u->status != status) { + u->status = (status_t)status; + } +} + +#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; +} + +static skill_t limited_skills[] = { SK_MAGIC, SK_ALCHEMY, SK_TACTICS, SK_SPY, SK_HERBALISM, NOSKILL }; +bool has_limited_skills(const struct unit * u) +{ + int i, j; + + for (i = 0; i != u->skill_size; ++i) { + skill *sv = u->skills + i; + for (j = 0; limited_skills[j] != NOSKILL; ++j) { + if (sv->id == limited_skills[j]) { + return true; + } + } + } + return false; +} + diff --git a/src/kernel/unit.h b/src/kernel/unit.h index 2fd394ccb..e2dac5abe 100644 --- a/src/kernel/unit.h +++ b/src/kernel/unit.h @@ -206,7 +206,6 @@ extern "C" { /* cleanup code for this module */ void free_units(void); - struct faction *dfindhash(int no); void u_setfaction(struct unit *u, struct faction *f); void set_number(struct unit *u, int count); @@ -265,6 +264,13 @@ extern "C" { int newunitid(void); int read_unitid(const struct faction *f, const struct region *r); + void setstatus(struct unit *u, int status); + /* !< sets combatstatus of a unit */ + int besieged(const struct unit *u); + bool has_horses(const struct unit *u); + int maintenance_cost(const struct unit *u); + bool has_limited_skills(const struct unit *u); + #ifdef __cplusplus } #endif diff --git a/src/kernel/unit.test.c b/src/kernel/unit.test.c index 6e2b584cc..fc0336c71 100644 --- a/src/kernel/unit.test.c +++ b/src/kernel/unit.test.c @@ -392,6 +392,28 @@ static void test_inside_building(CuTest *tc) { test_cleanup(); } +static void test_limited_skills(CuTest *tc) { + unit *u; + test_cleanup(); + u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0)); + CuAssertIntEquals(tc, false, has_limited_skills(u)); + set_level(u, SK_ENTERTAINMENT, 1); + CuAssertIntEquals(tc, false, has_limited_skills(u)); + u->skills->id = SK_ALCHEMY; + CuAssertIntEquals(tc, true, has_limited_skills(u)); + u->skills->id = SK_MAGIC; + CuAssertIntEquals(tc, true, has_limited_skills(u)); + u->skills->id = SK_TACTICS; + CuAssertIntEquals(tc, true, has_limited_skills(u)); + u->skills->id = SK_HERBALISM; + CuAssertIntEquals(tc, true, has_limited_skills(u)); + u->skills->id = SK_SPY; + CuAssertIntEquals(tc, true, has_limited_skills(u)); + u->skills->id = SK_TAXING; + CuAssertIntEquals(tc, false, has_limited_skills(u)); + test_cleanup(); +} + CuSuite *get_unit_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -412,5 +434,6 @@ CuSuite *get_unit_suite(void) SUITE_ADD_TEST(suite, test_age_familiar); SUITE_ADD_TEST(suite, test_inside_building); SUITE_ADD_TEST(suite, test_produceexp); + SUITE_ADD_TEST(suite, test_limited_skills); return suite; }