diff --git a/src/kernel/race.c b/src/kernel/race.c index dd0649afb..cb63647b5 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -38,7 +38,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include -#include #include #include #include @@ -536,21 +535,18 @@ const char *racename(const struct locale *loc, const unit * u, const race * rc) if (prefix != NULL) { static char lbuf[80]; /* FIXME: static return value */ - char *bufp = lbuf; - size_t size = sizeof(lbuf) - 1; - int ch, bytes; + sbstring sbs; + char ch[2]; - bytes = (int)str_strlcpy(bufp, LOC(loc, mkname("prefix", prefix)), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + sbs_init(&sbs, lbuf, sizeof(lbuf)); + sbs_strcpy(&sbs, LOC(loc, mkname("prefix", prefix))); - bytes = (int)str_strlcpy(bufp, LOC(loc, rc_name_s(rc, u->number != 1)), size); - assert(~bufp[0] & 0x80 || !"unicode/not implemented"); - ch = tolower(*(unsigned char *)bufp); - bufp[0] = (char)ch; - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - *bufp = 0; + str = LOC(loc, rc_name_s(rc, u->number != 1)); + assert(~str[0] & 0x80 || !"unicode/not implemented"); + ch[0] = (char)tolower(*(unsigned char *)str); + ch[1] = 0; + sbs_strcat(&sbs, ch); + sbs_strcat(&sbs, str + 1); return lbuf; } diff --git a/src/laws.c b/src/laws.c index 7b416f8a4..d90d2f173 100644 --- a/src/laws.c +++ b/src/laws.c @@ -81,7 +81,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include #include -#include #include #include #include @@ -2265,146 +2264,11 @@ static void display_item(unit * u, const item_type * itype) itype->weight, itype->rtype, info)); } -static void display_race(unit * u, const race * rc) +static void display_race(faction * f, const race * rc) { - faction * f = u->faction; - const char *name, *key; - const char *info; - int a, at_count; - char buf[2048], *bufp = buf; - size_t size = sizeof(buf) - 1; - size_t bytes; + char buf[2048]; - name = rc_name_s(rc, NAME_SINGULAR); - - bytes = slprintf(bufp, size, "%s: ", LOC(f->locale, name)); - assert(bytes <= INT_MAX); - if (wrptr(&bufp, &size, (int)bytes) != 0) - WARN_STATIC_BUFFER(); - - key = mkname("raceinfo", rc->_name); - info = locale_getstring(f->locale, key); - if (info == NULL) { - info = LOC(f->locale, mkname("raceinfo", "no_info")); - } - - if (info) bufp = STRLCPY(bufp, info, size); - - /* hp_p : Trefferpunkte */ - bytes = - slprintf(bufp, size, " %d %s", rc->hitpoints, LOC(f->locale, - "stat_hitpoints")); - assert(bytes <= INT_MAX); - if (wrptr(&bufp, &size, (int)bytes) != 0) - WARN_STATIC_BUFFER(); - - /* b_attacke : Angriff */ - bytes = - slprintf(bufp, size, ", %s: %d", LOC(f->locale, "stat_attack"), - (rc->at_default + rc->at_bonus)); - assert(bytes <= INT_MAX); - if (wrptr(&bufp, &size, (int)bytes) != 0) - WARN_STATIC_BUFFER(); - - /* b_defense : Verteidigung */ - bytes = - slprintf(bufp, size, ", %s: %d", LOC(f->locale, "stat_defense"), - (rc->df_default + rc->df_bonus)); - assert(bytes <= INT_MAX); - if (wrptr(&bufp, &size, (int)bytes) != 0) - WARN_STATIC_BUFFER(); - - /* b_armor : Rüstung */ - if (rc->armor > 0) { - bytes = - slprintf(bufp, size, ", %s: %d", LOC(f->locale, "stat_armor"), rc->armor); - assert(bytes <= INT_MAX); - if (wrptr(&bufp, &size, (int)bytes) != 0) - WARN_STATIC_BUFFER(); - } - - if (size > 1) { - *bufp++ = '.'; - --size; - } - else - WARN_STATIC_BUFFER(); - - /* b_damage : Schaden */ - at_count = 0; - for (a = 0; a < RACE_ATTACKS; a++) { - if (rc->attack[a].type != AT_NONE) { - at_count++; - } - } - if (rc->battle_flags & BF_EQUIPMENT) { - if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(f->locale, "stat_equipment"))) != 0) - WARN_STATIC_BUFFER(); - } - if (rc->battle_flags & BF_RES_PIERCE) { - if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(f->locale, "stat_pierce"))) != 0) - WARN_STATIC_BUFFER(); - } - if (rc->battle_flags & BF_RES_CUT) { - if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(f->locale, "stat_cut"))) != 0) - WARN_STATIC_BUFFER(); - } - if (rc->battle_flags & BF_RES_BASH) { - if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(f->locale, "stat_bash"))) != 0) - WARN_STATIC_BUFFER(); - } - - if (wrptr(&bufp, &size, snprintf(bufp, size, " %d %s", at_count, LOC(f->locale, (at_count == 1) ? "stat_attack" : "stat_attacks"))) != 0) - WARN_STATIC_BUFFER(); - - for (a = 0; a < RACE_ATTACKS; a++) { - if (rc->attack[a].type != AT_NONE) { - if (a != 0) - bufp = STRLCPY(bufp, ", ", size); - else - bufp = STRLCPY(bufp, ": ", size); - - switch (rc->attack[a].type) { - case AT_STANDARD: - bytes = - (size_t)snprintf(bufp, size, "%s (%s)", - LOC(f->locale, "attack_standard"), rc->def_damage); - break; - case AT_NATURAL: - bytes = - (size_t)snprintf(bufp, size, "%s (%s)", - LOC(f->locale, "attack_natural"), rc->attack[a].data.dice); - break; - case AT_SPELL: - case AT_COMBATSPELL: - case AT_DRAIN_ST: - case AT_DRAIN_EXP: - case AT_DAZZLE: - bytes = (size_t)snprintf(bufp, size, "%s", LOC(f->locale, "attack_magical")); - break; - case AT_STRUCTURAL: - bytes = - (size_t)snprintf(bufp, size, "%s (%s)", - LOC(f->locale, "attack_structural"), rc->attack[a].data.dice); - break; - default: - bytes = 0; - } - - assert(bytes <= INT_MAX); - if (bytes && wrptr(&bufp, &size, (int)bytes) != 0) - WARN_STATIC_BUFFER(); - } - } - - if (size > 1) { - *bufp++ = '.'; - --size; - } - else - WARN_STATIC_BUFFER(); - - *bufp = 0; + report_raceinfo(rc, f->locale, buf, sizeof(buf)); addmessage(0, f, buf, MSG_EVENT, ML_IMPORTANT); } @@ -2453,7 +2317,7 @@ static void reshow_other(unit * u, struct order *ord, const char *s) { } if (rc && u_race(u) == rc) { - display_race(u, rc); + display_race(u->faction, rc); found = true; } } diff --git a/src/reports.c b/src/reports.c index 0de70964c..b3aee94e0 100644 --- a/src/reports.c +++ b/src/reports.c @@ -363,25 +363,145 @@ static void report_resource(resource_report * result, const resource_type *rtype result->level = level; } -void report_race(const struct unit *u, const char **name, const char **illusion) +void report_raceinfo(const struct race *rc, const struct locale *lang, char *buf, size_t length) { - if (illusion) { - const race *irace = u_irace(u); - if (irace && irace != u_race(u)) { - *illusion = irace->_name; - } - else { - *illusion = NULL; + const char *info; + int a, at_count; + const char *name, *key; + char *bufp = buf; + size_t size = length - 1; + size_t bytes; + + name = rc_name_s(rc, NAME_SINGULAR); + + bytes = slprintf(bufp, size, "%s: ", LOC(lang, name)); + assert(bytes <= INT_MAX); + if (wrptr(&bufp, &size, (int)bytes) != 0) + WARN_STATIC_BUFFER(); + + key = mkname("raceinfo", rc->_name); + info = locale_getstring(lang, key); + if (info == NULL) { + info = LOC(lang, mkname("raceinfo", "no_info")); + } + + if (info) bufp = STRLCPY(bufp, info, size); + + /* hp_p : Trefferpunkte */ + bytes = + slprintf(bufp, size, " %d %s", rc->hitpoints, LOC(lang, + "stat_hitpoints")); + assert(bytes <= INT_MAX); + if (wrptr(&bufp, &size, (int)bytes) != 0) + WARN_STATIC_BUFFER(); + + /* b_attacke : Angriff */ + bytes = + slprintf(bufp, size, ", %s: %d", LOC(lang, "stat_attack"), + (rc->at_default + rc->at_bonus)); + assert(bytes <= INT_MAX); + if (wrptr(&bufp, &size, (int)bytes) != 0) + WARN_STATIC_BUFFER(); + + /* b_defense : Verteidigung */ + bytes = + slprintf(bufp, size, ", %s: %d", LOC(lang, "stat_defense"), + (rc->df_default + rc->df_bonus)); + assert(bytes <= INT_MAX); + if (wrptr(&bufp, &size, (int)bytes) != 0) + WARN_STATIC_BUFFER(); + + /* b_armor : Rüstung */ + if (rc->armor > 0) { + bytes = + slprintf(bufp, size, ", %s: %d", LOC(lang, "stat_armor"), rc->armor); + assert(bytes <= INT_MAX); + if (wrptr(&bufp, &size, (int)bytes) != 0) + WARN_STATIC_BUFFER(); + } + + if (size > 1) { + *bufp++ = '.'; + --size; + } + else + WARN_STATIC_BUFFER(); + + /* b_damage : Schaden */ + at_count = 0; + for (a = 0; a < RACE_ATTACKS; a++) { + if (rc->attack[a].type != AT_NONE) { + at_count++; } } - if (name) { - *name = u_race(u)->_name; - if (fval(u_race(u), RCF_SHAPESHIFTANY)) { - const char *str = get_racename(u->attribs); - if (str) - *name = str; + if (rc->battle_flags & BF_EQUIPMENT) { + if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(lang, "stat_equipment"))) != 0) + WARN_STATIC_BUFFER(); + } + if (rc->battle_flags & BF_RES_PIERCE) { + if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(lang, "stat_pierce"))) != 0) + WARN_STATIC_BUFFER(); + } + if (rc->battle_flags & BF_RES_CUT) { + if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(lang, "stat_cut"))) != 0) + WARN_STATIC_BUFFER(); + } + if (rc->battle_flags & BF_RES_BASH) { + if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(lang, "stat_bash"))) != 0) + WARN_STATIC_BUFFER(); + } + + if (wrptr(&bufp, &size, snprintf(bufp, size, " %d %s", at_count, LOC(lang, (at_count == 1) ? "stat_attack" : "stat_attacks"))) != 0) + WARN_STATIC_BUFFER(); + + for (a = 0; a < RACE_ATTACKS; a++) { + if (rc->attack[a].type != AT_NONE) { + if (a != 0) + bufp = STRLCPY(bufp, ", ", size); + else + bufp = STRLCPY(bufp, ": ", size); + + switch (rc->attack[a].type) { + case AT_STANDARD: + bytes = + (size_t)snprintf(bufp, size, "%s (%s)", + LOC(lang, "attack_standard"), rc->def_damage); + break; + case AT_NATURAL: + bytes = + (size_t)snprintf(bufp, size, "%s (%s)", + LOC(lang, "attack_natural"), rc->attack[a].data.dice); + break; + case AT_SPELL: + case AT_COMBATSPELL: + case AT_DRAIN_ST: + case AT_DRAIN_EXP: + case AT_DAZZLE: + bytes = (size_t)snprintf(bufp, size, "%s", LOC(lang, "attack_magical")); + break; + case AT_STRUCTURAL: + bytes = + (size_t)snprintf(bufp, size, "%s (%s)", + LOC(lang, "attack_structural"), rc->attack[a].data.dice); + break; + default: + bytes = 0; + } + + assert(bytes <= INT_MAX); + if (bytes && wrptr(&bufp, &size, (int)bytes) != 0) + WARN_STATIC_BUFFER(); } } + + if (size > 1) { + *bufp++ = '.'; + --size; + } + else + WARN_STATIC_BUFFER(); + + *bufp = 0; } void diff --git a/src/reports.h b/src/reports.h index e0a560fe8..0c285257e 100644 --- a/src/reports.h +++ b/src/reports.h @@ -120,15 +120,13 @@ extern "C" { int report_items(const struct unit *u, struct item *result, int size, const struct unit *owner, const struct faction *viewer); void report_warnings(struct faction *f, const struct gamedate *date); + void report_raceinfo(const struct race *rc, const struct locale *lang, char *buf, size_t length); void report_race_skills(const struct race *rc, char *zText, size_t length, const struct locale *lang); void report_item(const struct unit *owner, const struct item *i, const struct faction *viewer, const char **name, const char **basename, int *number, bool singular); void report_building(const struct building *b, const char **btype, const char **billusion); - void report_race(const struct unit *u, const char **rcname, - const char **rcillusion); - void add_seen_faction(struct faction *self, struct faction *seen); size_t f_regionid(const struct region *r, const struct faction *f, char *buffer, size_t size);