Merge branch 'develop' of github.com:ennorehling/eressea into develop

This commit is contained in:
Enno Rehling 2018-11-24 19:23:09 +01:00
commit c596781aea
19 changed files with 344 additions and 319 deletions

View File

@ -62,7 +62,7 @@ static int tolua_bufunit(lua_State * L) {
if (f) { if (f) {
char buf[8192]; char buf[8192];
int mode = (int)tolua_tonumber(L, 3, (int)seen_unit); int mode = (int)tolua_tonumber(L, 3, (int)seen_unit);
bufunit(f, u, mode, buf, sizeof(buf)); bufunit_depr(f, u, mode, buf, sizeof(buf));
tolua_pushstring(L, buf); tolua_pushstring(L, buf);
return 1; return 1;
} }
@ -199,7 +199,7 @@ static int tolua_unit_set_id(lua_State * L)
static int tolua_unit_get_auramax(lua_State * L) static int tolua_unit_get_auramax(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *self = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, max_spellpoints(self->region, self)); lua_pushinteger(L, max_spellpoints_depr(self->region, self));
return 1; return 1;
} }

View File

@ -817,7 +817,7 @@ static int tolua_report_unit(lua_State * L)
char buffer[512]; char buffer[512];
unit *u = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
faction *f = (faction *)tolua_tousertype(L, 2, 0); faction *f = (faction *)tolua_tousertype(L, 2, 0);
bufunit(f, u, seen_unit, buffer, sizeof(buffer)); bufunit_depr(f, u, seen_unit, buffer, sizeof(buffer));
tolua_pushstring(L, buffer); tolua_pushstring(L, buffer);
return 1; return 1;
} }

View File

@ -917,7 +917,7 @@ void cr_output_unit(stream *out, const faction * f,
} }
if (is_mage(u)) { if (is_mage(u)) {
stream_printf(out, "%d;Aura\n", get_spellpoints(u)); stream_printf(out, "%d;Aura\n", get_spellpoints(u));
stream_printf(out, "%d;Auramax\n", max_spellpoints(u->region, u)); stream_printf(out, "%d;Auramax\n", max_spellpoints_depr(u->region, u));
} }
/* default commands */ /* default commands */
stream_printf(out, "COMMANDS\n"); stream_printf(out, "COMMANDS\n");

View File

@ -74,7 +74,7 @@ use_manacrystal(struct unit *u, const struct item_type *itype, int amount,
return -1; return -1;
} }
msp = max_spellpoints(u->region, u) / 2; msp = max_spellpoints_depr(u->region, u) / 2;
for (i = 0; i != amount; ++i) { for (i = 0; i != amount; ++i) {
sp += MAX(25, msp); sp += MAX(25, msp);
change_spellpoints(u, sp); change_spellpoints(u, sp);

View File

@ -62,7 +62,7 @@ int get_resource(const unit * u, const resource_type * rtype)
return get_spellpoints(u); return get_spellpoints(u);
} }
if (rtype == get_resourcetype(R_PERMAURA)) { if (rtype == get_resourcetype(R_PERMAURA)) {
return max_spellpoints(u->region, u); return max_spellpoints_depr(u->region, u);
} }
log_error("trying to get unknown resource '%s'.\n", rtype->_name); log_error("trying to get unknown resource '%s'.\n", rtype->_name);
return 0; return 0;

View File

@ -326,7 +326,7 @@ static void calculate_emigration(region * r)
static double peasant_growth_factor(void) static double peasant_growth_factor(void)
{ {
return config_get_flt("rules.peasants.growth.factor", 0.0001F * PEASANTGROWTH); return config_get_flt("rules.peasants.growth.factor", 0.0001 * (double)PEASANTGROWTH);
} }
static double peasant_luck_factor(void) static double peasant_luck_factor(void)
@ -424,8 +424,10 @@ static migration *get_migrants(region * r)
/* Es gibt noch keine Migration. Also eine erzeugen /* Es gibt noch keine Migration. Also eine erzeugen
*/ */
m = free_migrants; m = free_migrants;
if (!m) if (!m) {
m = calloc(1, sizeof(migration)); m = calloc(1, sizeof(migration));
if (!m) abort();
}
else { else {
free_migrants = free_migrants->next; free_migrants = free_migrants->next;
m->horses = 0; m->horses = 0;
@ -476,8 +478,8 @@ static void horses(region * r)
} }
else if (maxhorses > 0) { else if (maxhorses > 0) {
double growth = double growth =
(RESOURCE_QUANTITY * HORSEGROWTH * 200 * (maxhorses - (RESOURCE_QUANTITY * (HORSEGROWTH * 200.0 * ((double)maxhorses -
horses)) / maxhorses; horses))) / (double)maxhorses;
if (growth > 0) { if (growth > 0) {
int i; int i;
@ -1233,6 +1235,7 @@ static void remove_idle_players(void)
i = turn + 1; i = turn + 1;
if (i < 4) i = 4; if (i < 4) i = 4;
age = calloc(i, sizeof(int)); age = calloc(i, sizeof(int));
if (!age) abort();
for (fp = &factions; *fp;) { for (fp = &factions; *fp;) {
faction *f = *fp; faction *f = *fp;
if (!is_monsters(f)) { if (!is_monsters(f)) {
@ -1393,8 +1396,10 @@ static void init_prefixnames(void)
} }
in = in->next; in = in->next;
} }
if (in == NULL) if (in == NULL) {
in = calloc(sizeof(local_names), 1); in = calloc(sizeof(local_names), 1);
if (!in) abort();
}
in->next = pnames; in->next = pnames;
in->lang = lang; in->lang = lang;
@ -1432,7 +1437,8 @@ int prefix_cmd(unit * u, struct order *ord)
} }
if (in == NULL) { if (in == NULL) {
init_prefixnames(); init_prefixnames();
for (in = pnames; in->lang != lang; in = in->next); for (in = pnames; in && in->lang != lang; in = in->next);
if (!in) return 0;
} }
init_order_depr(ord); init_order_depr(ord);
@ -2173,8 +2179,10 @@ static void display_item(unit * u, const item_type * itype)
static void display_race(faction * f, const race * rc) static void display_race(faction * f, const race * rc)
{ {
char buf[2048]; char buf[2048];
sbstring sbs;
report_raceinfo(rc, f->locale, buf, sizeof(buf)); sbs_init(&sbs, buf, sizeof(buf));
report_raceinfo(rc, f->locale, &sbs);
addmessage(0, f, buf, MSG_EVENT, ML_IMPORTANT); addmessage(0, f, buf, MSG_EVENT, ML_IMPORTANT);
} }
@ -3070,9 +3078,11 @@ void monthly_healing(void)
/* hp über Maximum bauen sich ab. Wird zb durch Elixier der Macht /* hp über Maximum bauen sich ab. Wird zb durch Elixier der Macht
* oder verändertes Ausdauertalent verursacht */ * oder verändertes Ausdauertalent verursacht */
if (u->hp > umhp) { if (u->hp > umhp) {
u->hp -= (int)ceil((u->hp - umhp) / 2.0); int diff = u->hp - umhp;
if (u->hp < umhp) u->hp -= (int)ceil(diff / 2.0);
if (u->hp < umhp) {
u->hp = umhp; u->hp = umhp;
}
continue; continue;
} }
@ -3509,6 +3519,7 @@ static processor *add_proc(int priority, const char *name, processor_t type)
} }
proc = (processor *)malloc(sizeof(processor)); proc = (processor *)malloc(sizeof(processor));
if (!proc) abort();
proc->priority = priority; proc->priority = priority;
proc->type = type; proc->type = type;
proc->name = name; proc->name = name;

View File

@ -1483,6 +1483,34 @@ static void test_show_without_item(CuTest *tc)
test_teardown(); test_teardown();
} }
static struct locale *setup_locale(void) {
struct locale *loc;
loc = get_or_create_locale("de");
locale_setstring(loc, "elvenhorse", "Elfenpferd");
locale_setstring(loc, "elvenhorse_p", "Elfenpferde");
locale_setstring(loc, "iteminfo::elvenhorse", "Elfenpferd Informationen");
locale_setstring(loc, "race::elf_p", "Elfen");
locale_setstring(loc, "race::elf", "Elf");
locale_setstring(loc, "race::human_p", "Menschen");
locale_setstring(loc, "race::human", "Mensch");
locale_setstring(loc, "stat_hitpoints", "Trefferpunkte");
locale_setstring(loc, "stat_attack", "Angriff");
locale_setstring(loc, "stat_attacks", "Angriffe");
locale_setstring(loc, "stat_defense", "Verteidigung");
locale_setstring(loc, "stat_armor", "Ruestung");
locale_setstring(loc, "stat_equipment", "Gegenstaende");
locale_setstring(loc, "stat_pierce", "Pieks");
locale_setstring(loc, "stat_cut", "Schnipp");
locale_setstring(loc, "stat_bash", "Boink");
locale_setstring(loc, "attack_magical", "magisch");
locale_setstring(loc, "attack_standard", "normal");
locale_setstring(loc, "attack_natural", "natuerlich");
locale_setstring(loc, "attack_structural", "strukturell");
init_locale(loc);
return loc;
}
static void test_show_race(CuTest *tc) { static void test_show_race(CuTest *tc) {
order *ord; order *ord;
race * rc; race * rc;
@ -1495,12 +1523,7 @@ static void test_show_race(CuTest *tc) {
test_create_race("human"); test_create_race("human");
rc = test_create_race("elf"); rc = test_create_race("elf");
loc = get_or_create_locale("de"); loc = setup_locale();
locale_setstring(loc, "race::elf_p", "Elfen");
locale_setstring(loc, "race::elf", "Elf");
locale_setstring(loc, "race::human_p", "Menschen");
locale_setstring(loc, "race::human", "Mensch");
init_locale(loc);
u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL)); u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL));
u->faction->locale = loc; u->faction->locale = loc;
@ -1536,13 +1559,7 @@ static void test_show_both(CuTest *tc) {
rc = test_create_race("elf"); rc = test_create_race("elf");
test_create_itemtype("elvenhorse"); test_create_itemtype("elvenhorse");
loc = get_or_create_locale("de"); loc = setup_locale();
locale_setstring(loc, "elvenhorse", "Elfenpferd");
locale_setstring(loc, "elvenhorse_p", "Elfenpferde");
locale_setstring(loc, "iteminfo::elvenhorse", "Hiyaa!");
locale_setstring(loc, "race::elf_p", "Elfen");
locale_setstring(loc, "race::elf", "Elf");
init_locale(loc);
CuAssertPtrNotNull(tc, finditemtype("elf", loc)); CuAssertPtrNotNull(tc, finditemtype("elf", loc));
CuAssertPtrNotNull(tc, findrace("elf", loc)); CuAssertPtrNotNull(tc, findrace("elf", loc));
@ -1558,7 +1575,7 @@ static void test_show_both(CuTest *tc) {
CuAssertTrue(tc, memcmp("Elf:", msg->parameters[0].v, 4) == 0); CuAssertTrue(tc, memcmp("Elf:", msg->parameters[0].v, 4) == 0);
msg = test_find_messagetype(u->faction->msgs, "displayitem"); msg = test_find_messagetype(u->faction->msgs, "displayitem");
CuAssertPtrNotNull(tc, msg); CuAssertPtrNotNull(tc, msg);
CuAssertTrue(tc, memcmp("Hiyaa!", msg->parameters[2].v, 4) == 0); CuAssertTrue(tc, memcmp("Elfenpferd Informationen", msg->parameters[2].v, 4) == 0);
test_clear_messages(u->faction); test_clear_messages(u->faction);
free_order(ord); free_order(ord);
test_teardown(); test_teardown();

View File

@ -646,7 +646,7 @@ static int use_item_aura(const region * r, const unit * u)
return n; return n;
} }
int max_spellpoints(const region * r, const unit * u) int max_spellpoints(const struct unit *u, const region * r)
{ {
int sk; int sk;
double n, msp = 0; double n, msp = 0;
@ -654,6 +654,9 @@ int max_spellpoints(const region * r, const unit * u)
double divisor = 1.2; double divisor = 1.2;
const struct resource_type *rtype; const struct resource_type *rtype;
assert(u);
if (!r) r = u->region;
sk = effskill(u, SK_MAGIC, r); sk = effskill(u, SK_MAGIC, r);
msp = rc_maxaura(u_race(u)) * (pow(sk, potenz) / divisor + 1) + get_spchange(u); msp = rc_maxaura(u_race(u)) * (pow(sk, potenz) / divisor + 1) + get_spchange(u);
@ -668,6 +671,11 @@ int max_spellpoints(const region * r, const unit * u)
return (msp > 0) ? (int)msp : 0; return (msp > 0) ? (int)msp : 0;
} }
int max_spellpoints_depr(const struct region *r, const struct unit *u)
{
return max_spellpoints(u, r);
}
int change_maxspellpoints(unit * u, int csp) int change_maxspellpoints(unit * u, int csp)
{ {
sc_mage *m = get_mage(u); sc_mage *m = get_mage(u);
@ -675,7 +683,7 @@ int change_maxspellpoints(unit * u, int csp)
return 0; return 0;
} }
m->spchange += csp; m->spchange += csp;
return max_spellpoints(u->region, u); return max_spellpoints_depr(u->region, u);
} }
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
@ -1456,7 +1464,7 @@ void regenerate_aura(void)
for (u = r->units; u; u = u->next) { for (u = r->units; u; u = u->next) {
if (u->number && is_mage(u)) { if (u->number && is_mage(u)) {
aura = get_spellpoints(u); aura = get_spellpoints(u);
auramax = max_spellpoints(r, u); auramax = max_spellpoints_depr(r, u);
if (aura < auramax) { if (aura < auramax) {
struct building *b = inside_building(u); struct building *b = inside_building(u);
const struct building_type *btype = building_is_active(b) ? b->type : NULL; const struct building_type *btype = building_is_active(b) ? b->type : NULL;
@ -2979,6 +2987,11 @@ int cast_spell(struct castorder *co)
return fun(co); return fun(co);
} }
const char *magic_name(magic_t mtype, const struct locale *lang)
{
return LOC(lang, mkname("school", magic_school[mtype]));
}
static critbit_tree cb_spellbooks; static critbit_tree cb_spellbooks;
#define SBNAMELEN 16 #define SBNAMELEN 16

View File

@ -252,7 +252,8 @@ extern "C" {
/* setzt die Magiepunkte auf sp */ /* setzt die Magiepunkte auf sp */
int change_spellpoints(struct unit *u, int mp); int change_spellpoints(struct unit *u, int mp);
/* verändert die Anzahl der Magiepunkte der Einheit um +mp */ /* verändert die Anzahl der Magiepunkte der Einheit um +mp */
int max_spellpoints(const struct region *r, const struct unit *u); int max_spellpoints_depr(const struct region *r, const struct unit *u);
int max_spellpoints(const struct unit *u, const struct region *r);
/* gibt die aktuell maximal möglichen Magiepunkte der Einheit zurück */ /* gibt die aktuell maximal möglichen Magiepunkte der Einheit zurück */
int change_maxspellpoints(struct unit *u, int csp); int change_maxspellpoints(struct unit *u, int csp);
/* verändert die maximalen Magiepunkte einer Einheit */ /* verändert die maximalen Magiepunkte einer Einheit */
@ -316,6 +317,7 @@ extern "C" {
* widersteht */ * widersteht */
extern struct spell * unit_getspell(struct unit *u, const char *s, extern struct spell * unit_getspell(struct unit *u, const char *s,
const struct locale *lang); const struct locale *lang);
const char *magic_name(magic_t mtype, const struct locale *lang);
/* Sprüche in der struct region */ /* Sprüche in der struct region */
/* (sind in curse) */ /* (sind in curse) */

View File

@ -446,19 +446,19 @@ static void test_max_spellpoints(CuTest *tc) {
test_setup(); test_setup();
rc = test_create_race("human"); rc = test_create_race("human");
u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL)); u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL));
CuAssertIntEquals(tc, 1, max_spellpoints(u->region, u)); CuAssertIntEquals(tc, 1, max_spellpoints_depr(u->region, u));
rc->maxaura = 100; rc->maxaura = 100;
CuAssertIntEquals(tc, 1, max_spellpoints(u->region, u)); CuAssertIntEquals(tc, 1, max_spellpoints_depr(u->region, u));
rc->maxaura = 200; rc->maxaura = 200;
CuAssertIntEquals(tc, 2, max_spellpoints(u->region, u)); CuAssertIntEquals(tc, 2, max_spellpoints_depr(u->region, u));
create_mage(u, M_GWYRRD); create_mage(u, M_GWYRRD);
set_level(u, SK_MAGIC, 1); set_level(u, SK_MAGIC, 1);
CuAssertIntEquals(tc, 3, max_spellpoints(u->region, u)); CuAssertIntEquals(tc, 3, max_spellpoints_depr(u->region, u));
set_level(u, SK_MAGIC, 2); set_level(u, SK_MAGIC, 2);
CuAssertIntEquals(tc, 9, max_spellpoints(u->region, u)); CuAssertIntEquals(tc, 9, max_spellpoints_depr(u->region, u));
/* permanent aura loss: */ /* permanent aura loss: */
CuAssertIntEquals(tc, 7, change_maxspellpoints(u, -2)); CuAssertIntEquals(tc, 7, change_maxspellpoints(u, -2));
CuAssertIntEquals(tc, 7, max_spellpoints(u->region, u)); CuAssertIntEquals(tc, 7, max_spellpoints_depr(u->region, u));
test_teardown(); test_teardown();
} }

View File

@ -676,7 +676,7 @@ nr_unit(struct stream *out, const faction * f, const unit * u, int indent, seen_
return; return;
newline(out); newline(out);
dh = bufunit(f, u, mode, buf, sizeof(buf)); dh = bufunit_depr(f, u, mode, buf, sizeof(buf));
if (u->faction == f) { if (u->faction == f) {
marker = '*'; marker = '*';
@ -2026,7 +2026,7 @@ report_plaintext(const char *filename, report_context * ctx,
newline(out); newline(out);
sprintf(buf, "%s, %s/%s (%s)", factionname(f), sprintf(buf, "%s, %s/%s (%s)", factionname(f),
LOC(f->locale, rc_name_s(f->race, NAME_PLURAL)), LOC(f->locale, rc_name_s(f->race, NAME_PLURAL)),
LOC(f->locale, mkname("school", magic_school[f->magiegebiet])), faction_getemail(f)); magic_name(f->magiegebiet, f->locale), faction_getemail(f));
centre(out, buf, true); centre(out, buf, true);
if (f_get_alliance(f)) { if (f_get_alliance(f)) {
centre(out, alliancename(f->alliance), true); centre(out, alliancename(f->alliance), true);

View File

@ -162,29 +162,37 @@ const char *combatstatus[] = {
"status_avoid", "status_flee" "status_avoid", "status_flee"
}; };
size_t report_status(const unit * u, const struct locale *lang, char *fsbuf, size_t buflen) void report_status(const unit * u, const struct locale *lang, struct sbstring *sbp)
{ {
const char * status = LOC(lang, combatstatus[u->status]); const char * status = LOC(lang, combatstatus[u->status]);
size_t len = 0;
if (!status) { if (!status) {
const char *lname = locale_name(lang); const char *lname = locale_name(lang);
struct locale *wloc = get_locale(lname); struct locale *wloc = get_locale(lname);
log_warning("no translation for combat status %s in %s", combatstatus[u->status], lname); log_warning("no translation for combat status %s in %s", combatstatus[u->status], lname);
locale_setstring(wloc, combatstatus[u->status], combatstatus[u->status] + 7); locale_setstring(wloc, combatstatus[u->status], combatstatus[u->status] + 7);
len = str_strlcpy(fsbuf, combatstatus[u->status] + 7, buflen); sbs_strcat(sbp, combatstatus[u->status] + 7);
} }
else { else {
len = str_strlcpy(fsbuf, status, buflen); sbs_strcat(sbp, status);
} }
if (fval(u, UFL_NOAID)) { if (fval(u, UFL_NOAID)) {
len += str_strlcat(fsbuf + len, ", ", buflen - len); sbs_strcat(sbp, ", ");
len += str_strlcat(fsbuf + len, LOC(lang, "status_noaid"), buflen - len); sbs_strcat(sbp, LOC(lang, "status_noaid"));
} }
return len;
} }
size_t report_status_depr(const unit * u, const struct locale *lang, char *fsbuf, size_t buflen)
{
sbstring sbs;
sbs_init(&sbs, fsbuf, buflen);
report_status(u, lang, &sbs);
return sbs_length(&sbs);
}
const char *hp_status(const unit * u) const char *hp_status(const unit * u)
{ {
double p; double p;
@ -274,29 +282,19 @@ report_item(const unit * owner, const item * i, const faction * viewer,
} }
#define ORDERS_IN_NR 1 #define ORDERS_IN_NR 1
static size_t buforder(char *buffer, size_t size, const order * ord, const struct locale *lang, int mode) static void buforder(sbstring *sbp, const order * ord, const struct locale *lang, int mode)
{ {
char *bufp = buffer; sbs_strcat(sbp, ", \"");
bufp = STRLCPY(bufp, ", \"", size);
if (mode < ORDERS_IN_NR) { if (mode < ORDERS_IN_NR) {
char cmd[ORDERSIZE]; char cmd[ORDERSIZE];
get_command(ord, lang, cmd, sizeof(cmd)); get_command(ord, lang, cmd, sizeof(cmd));
bufp = STRLCPY(bufp, cmd, size); sbs_strcat(sbp, cmd);
} }
else { else {
bufp = STRLCPY(bufp, "...", size); sbs_strcat(sbp, "...");
} }
if (size > 1) { sbs_strcat(sbp, "\"");
*bufp++ = '\"';
--size;
}
else {
WARN_STATIC_BUFFER();
}
return bufp - buffer;
} }
/** create a report of a list of items to a non-owner. /** create a report of a list of items to a non-owner.
@ -365,21 +363,24 @@ static void report_resource(resource_report * result, const resource_type *rtype
result->level = level; result->level = level;
} }
void report_raceinfo(const struct race *rc, const struct locale *lang, char *buf, size_t length) static void bufattack(struct sbstring *sbp, const struct locale *lang, const char *name, const char *dmg) {
sbs_strcat(sbp, LOC(lang, name));
if (dmg) {
sbs_strcat(sbp, " (");
sbs_strcat(sbp, dmg);
sbs_strcat(sbp, ")");
}
}
void report_raceinfo(const struct race *rc, const struct locale *lang, struct sbstring *sbp)
{ {
const char *info; const char *info;
int a, at_count; int a, at_count;
const char *name, *key; const char *name, *key;
char *bufp = buf;
size_t size = length - 1;
size_t bytes;
name = rc_name_s(rc, NAME_SINGULAR); name = rc_name_s(rc, NAME_SINGULAR);
sbs_strcat(sbp, LOC(lang, name));
bytes = slprintf(bufp, size, "%s: ", LOC(lang, name)); sbs_strcat(sbp, ": ");
assert(bytes <= INT_MAX);
if (wrptr(&bufp, &size, (int)bytes) != 0)
WARN_STATIC_BUFFER();
key = mkname("raceinfo", rc->_name); key = mkname("raceinfo", rc->_name);
info = locale_getstring(lang, key); info = locale_getstring(lang, key);
@ -387,47 +388,37 @@ void report_raceinfo(const struct race *rc, const struct locale *lang, char *buf
info = LOC(lang, mkname("raceinfo", "no_info")); info = LOC(lang, mkname("raceinfo", "no_info"));
} }
if (info) bufp = STRLCPY(bufp, info, size); if (info) {
sbs_strcat(sbp, info);
}
/* hp_p : Trefferpunkte */ /* hp_p : Trefferpunkte */
bytes = sbs_strcat(sbp, " ");
slprintf(bufp, size, " %d %s", rc->hitpoints, LOC(lang, sbs_strcat(sbp, str_itoa(rc->hitpoints));
"stat_hitpoints")); sbs_strcat(sbp, " ");
assert(bytes <= INT_MAX); sbs_strcat(sbp, LOC(lang, "stat_hitpoints"));
if (wrptr(&bufp, &size, (int)bytes) != 0)
WARN_STATIC_BUFFER();
/* b_attacke : Angriff */ /* b_attacke : Angriff */
bytes = sbs_strcat(sbp, ", ");
slprintf(bufp, size, ", %s: %d", LOC(lang, "stat_attack"), sbs_strcat(sbp, LOC(lang, "stat_attack"));
(rc->at_default + rc->at_bonus)); sbs_strcat(sbp, ": ");
assert(bytes <= INT_MAX); sbs_strcat(sbp, str_itoa(rc->at_default + rc->at_bonus));
if (wrptr(&bufp, &size, (int)bytes) != 0)
WARN_STATIC_BUFFER();
/* b_defense : Verteidigung */ /* b_defense : Verteidigung */
bytes = sbs_strcat(sbp, ", ");
slprintf(bufp, size, ", %s: %d", LOC(lang, "stat_defense"), sbs_strcat(sbp, LOC(lang, "stat_defense"));
(rc->df_default + rc->df_bonus)); sbs_strcat(sbp, ": ");
assert(bytes <= INT_MAX); sbs_strcat(sbp, str_itoa(rc->df_default + rc->df_bonus));
if (wrptr(&bufp, &size, (int)bytes) != 0)
WARN_STATIC_BUFFER();
/* b_armor : Rüstung */ /* b_armor : Rüstung */
if (rc->armor > 0) { if (rc->armor > 0) {
bytes = sbs_strcat(sbp, ", ");
slprintf(bufp, size, ", %s: %d", LOC(lang, "stat_armor"), rc->armor); sbs_strcat(sbp, LOC(lang, "stat_armor"));
assert(bytes <= INT_MAX); sbs_strcat(sbp, ": ");
if (wrptr(&bufp, &size, (int)bytes) != 0) sbs_strcat(sbp, str_itoa(rc->armor));
WARN_STATIC_BUFFER();
} }
if (size > 1) { sbs_strcat(sbp, ".");
*bufp++ = '.';
--size;
}
else
WARN_STATIC_BUFFER();
/* b_damage : Schaden */ /* b_damage : Schaden */
at_count = 0; at_count = 0;
@ -437,73 +428,53 @@ void report_raceinfo(const struct race *rc, const struct locale *lang, char *buf
} }
} }
if (rc->battle_flags & BF_EQUIPMENT) { if (rc->battle_flags & BF_EQUIPMENT) {
if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(lang, "stat_equipment"))) != 0) sbs_strcat(sbp, " ");
WARN_STATIC_BUFFER(); sbs_strcat(sbp, LOC(lang, "stat_equipment"));
} }
if (rc->battle_flags & BF_RES_PIERCE) { if (rc->battle_flags & BF_RES_PIERCE) {
if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(lang, "stat_pierce"))) != 0) sbs_strcat(sbp, " ");
WARN_STATIC_BUFFER(); sbs_strcat(sbp, LOC(lang, "stat_pierce"));
} }
if (rc->battle_flags & BF_RES_CUT) { if (rc->battle_flags & BF_RES_CUT) {
if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(lang, "stat_cut"))) != 0) sbs_strcat(sbp, " ");
WARN_STATIC_BUFFER(); sbs_strcat(sbp, LOC(lang, "stat_cut"));
} }
if (rc->battle_flags & BF_RES_BASH) { if (rc->battle_flags & BF_RES_BASH) {
if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(lang, "stat_bash"))) != 0) sbs_strcat(sbp, " ");
WARN_STATIC_BUFFER(); sbs_strcat(sbp, LOC(lang, "stat_bash"));
} }
if (wrptr(&bufp, &size, snprintf(bufp, size, " %d %s", at_count, LOC(lang, (at_count == 1) ? "stat_attack" : "stat_attacks"))) != 0) sbs_strcat(sbp, " ");
WARN_STATIC_BUFFER(); sbs_strcat(sbp, str_itoa(at_count));
sbs_strcat(sbp, " ");
sbs_strcat(sbp, LOC(lang, (at_count == 1) ? "stat_attack" : "stat_attacks"));
for (a = 0; a < RACE_ATTACKS; a++) { for (a = 0; a < RACE_ATTACKS; a++) {
if (rc->attack[a].type != AT_NONE) { if (rc->attack[a].type != AT_NONE) {
if (a != 0) sbs_strcat(sbp, (a == 0) ? ": " : ", ");
bufp = STRLCPY(bufp, ", ", size);
else
bufp = STRLCPY(bufp, ": ", size);
switch (rc->attack[a].type) { switch (rc->attack[a].type) {
case AT_STANDARD: case AT_STANDARD:
bytes = bufattack(sbp, lang, "attack_standard", rc->def_damage);
(size_t)snprintf(bufp, size, "%s (%s)",
LOC(lang, "attack_standard"), rc->def_damage);
break; break;
case AT_NATURAL: case AT_NATURAL:
bytes = bufattack(sbp, lang, "attack_natural", rc->attack[a].data.dice);
(size_t)snprintf(bufp, size, "%s (%s)",
LOC(lang, "attack_natural"), rc->attack[a].data.dice);
break; break;
case AT_SPELL: case AT_SPELL:
case AT_COMBATSPELL: case AT_COMBATSPELL:
case AT_DRAIN_ST: case AT_DRAIN_ST:
case AT_DRAIN_EXP: case AT_DRAIN_EXP:
case AT_DAZZLE: case AT_DAZZLE:
bytes = (size_t)snprintf(bufp, size, "%s", LOC(lang, "attack_magical")); bufattack(sbp, lang, "attack_magical", NULL);
break; break;
case AT_STRUCTURAL: case AT_STRUCTURAL:
bytes = bufattack(sbp, lang, "attack_structural", rc->attack[a].data.dice);
(size_t)snprintf(bufp, size, "%s (%s)",
LOC(lang, "attack_structural"), rc->attack[a].data.dice);
break; break;
default:
bytes = 0;
} }
assert(bytes <= INT_MAX);
if (bytes && wrptr(&bufp, &size, (int)bytes) != 0)
WARN_STATIC_BUFFER();
} }
} }
if (size > 1) { sbs_strcat(sbp, ".");
*bufp++ = '.';
--size;
}
else
WARN_STATIC_BUFFER();
*bufp = 0;
} }
void void
@ -612,50 +583,47 @@ report_resources(const region * r, resource_report * result, int size,
return n; return n;
} }
static size_t spskill(char *buffer, size_t size, const struct locale * lang, static void spskill(sbstring *sbp, const struct locale * lang,
const struct unit * u, struct skill * sv, int *dh) const struct unit * u, struct skill * sv, int *dh)
{ {
char *bufp = buffer;
int effsk; int effsk;
if (!u->number) if (!u->number) {
return 0; return;
}
if (sv->level <= 0) { if (sv->level <= 0) {
if (sv->old <= 0 || (u->faction->options & WANT_OPTION(O_SHOWSKCHANGE)) == 0) { if (sv->old <= 0 || (u->faction->options & WANT_OPTION(O_SHOWSKCHANGE)) == 0) {
return 0; return;
} }
} }
sbs_strcat(sbp, ", ");
bufp = STRLCPY(bufp, ", ", size);
if (!*dh) { if (!*dh) {
bufp = STRLCPY(bufp, LOC(lang, "nr_skills"), size); sbs_strcat(sbp, LOC(lang, "nr_skills"));
bufp = STRLCPY(bufp, ": ", size); sbs_strcat(sbp, ": ");
*dh = 1; *dh = 1;
} }
bufp = STRLCPY(bufp, skillname(sv->id, lang), size); sbs_strcat(sbp, skillname(sv->id, lang));
bufp = STRLCPY(bufp, " ", size); sbs_strcat(sbp, " ");
if (sv->id == SK_MAGIC) { if (sv->id == SK_MAGIC) {
magic_t mtype = unit_get_magic(u); magic_t mtype = unit_get_magic(u);
if (mtype != M_GRAY) { if (mtype != M_GRAY) {
bufp = STRLCPY(bufp, sbs_strcat(sbp, magic_name(mtype, lang));
LOC(lang, mkname("school", magic_school[mtype])), size); sbs_strcat(sbp, " ");
bufp = STRLCPY(bufp, " ", size);
} }
} }
if (sv->id == SK_STEALTH && fval(u, UFL_STEALTH)) { if (sv->id == SK_STEALTH && fval(u, UFL_STEALTH)) {
int i = u_geteffstealth(u); int i = u_geteffstealth(u);
if (i >= 0) { if (i >= 0) {
if (wrptr(&bufp, &size, snprintf(bufp, size, "%d/", i)) != 0) sbs_strcat(sbp, str_itoa(i));
WARN_STATIC_BUFFER(); sbs_strcat(sbp, "/");
} }
} }
effsk = eff_skill(u, sv, 0); effsk = eff_skill(u, sv, 0);
if (wrptr(&bufp, &size, snprintf(bufp, size, "%d", effsk)) != 0) sbs_strcat(sbp, str_itoa(effsk));
WARN_STATIC_BUFFER();
if (u->faction->options & WANT_OPTION(O_SHOWSKCHANGE)) { if (u->faction->options & WANT_OPTION(O_SHOWSKCHANGE)) {
int oldeff = 0; int oldeff = 0;
@ -669,150 +637,146 @@ static size_t spskill(char *buffer, size_t size, const struct locale * lang,
diff = effsk - oldeff; diff = effsk - oldeff;
if (diff != 0) { if (diff != 0) {
if (wrptr(&bufp, &size, snprintf(bufp, size, " (%s%d)", (diff > 0) ? "+" : "", diff)) != 0) sbs_strcat(sbp, " (");
WARN_STATIC_BUFFER(); sbs_strcat(sbp, (diff > 0) ? "+" : "");
sbs_strcat(sbp, str_itoa(diff));
sbs_strcat(sbp, ")");
} }
} }
return bufp - buffer;
} }
int static size_t spskill_depr(char *buffer, size_t size, const struct locale * lang,
bufunit(const faction * f, const unit * u, seen_mode mode, char *buf, const struct unit * u, struct skill * sv, int *dh)
size_t size) {
sbstring sbs;
sbs_init(&sbs, buffer, size);
spskill(&sbs, lang, u, sv, dh);
return sbs_length(&sbs);
}
void bufunit(const faction * f, const unit * u, const faction *fv,
seen_mode mode, int getarnt, struct sbstring *sbp)
{ {
int i, dh; int i, dh;
int getarnt = fval(u, UFL_ANON_FACTION);
const char *pzTmp, *str; const char *pzTmp, *str;
bool isbattle = (mode == seen_battle); bool isbattle = (mode == seen_battle);
item *itm, *show = NULL; item *itm, *show = NULL;
faction *fv;
char *bufp = buf;
int result = 0;
item results[MAX_INVENTORY]; item results[MAX_INVENTORY];
const struct locale *lang = f->locale; const struct locale *lang = f->locale;
if (!fv) {
fv = visible_faction(f, u);
}
assert(f); assert(f);
bufp = STRLCPY(bufp, unitname(u), size); sbs_strcat(sbp, unitname(u));
fv = visible_faction(f, u);
if (!isbattle) { if (!isbattle) {
if (u->faction == f) { if (u->faction == f) {
if (fval(u, UFL_GROUP)) { if (fval(u, UFL_GROUP)) {
group *g = get_group(u); group *g = get_group(u);
if (g) { if (g) {
bufp = STRLCPY(bufp, ", ", size); sbs_strcat(sbp, ", ");
bufp = STRLCPY(bufp, groupid(g, f), size); sbs_strcat(sbp, groupid(g, f));
} }
} }
if (getarnt) { if (getarnt) {
bufp = STRLCPY(bufp, ", ", size); sbs_strcat(sbp, ", ");
bufp = STRLCPY(bufp, LOC(lang, "anonymous"), size); sbs_strcat(sbp, LOC(lang, "anonymous"));
} }
else if (u->attribs) { else if (u->attribs) {
faction *otherf = get_otherfaction(u); faction *otherf = get_otherfaction(u);
if (otherf) { if (otherf) {
bufp = STRLCPY(bufp, ", ", size); sbs_strcat(sbp, ", ");
bufp = STRLCPY(bufp, factionname(otherf), size); sbs_strcat(sbp, factionname(otherf));
} }
} }
} }
else { else {
if (getarnt) { if (getarnt) {
bufp = STRLCPY(bufp, ", ", size); sbs_strcat(sbp, ", ");
bufp = STRLCPY(bufp, LOC(lang, "anonymous"), size); sbs_strcat(sbp, LOC(lang, "anonymous"));
} }
else { else {
if (u->attribs && alliedunit(u, f, HELP_FSTEALTH)) { if (u->attribs && alliedunit(u, f, HELP_FSTEALTH)) {
faction *otherf = get_otherfaction(u); faction *otherf = get_otherfaction(u);
if (otherf) { if (otherf) {
int n = snprintf(bufp, size, ", %s (%s)", sbs_strcat(sbp, ", ");
factionname(otherf), factionname(u->faction)); sbs_strcat(sbp, factionname(otherf));
if (wrptr(&bufp, &size, n) != 0) sbs_strcat(sbp, " (");
WARN_STATIC_BUFFER(); sbs_strcat(sbp, factionname(u->faction));
sbs_strcat(sbp, ")");
} }
else { else {
bufp = STRLCPY(bufp, ", ", size); sbs_strcat(sbp, ", ");
bufp = STRLCPY(bufp, factionname(fv), size); sbs_strcat(sbp, factionname(fv));
} }
} }
else { else {
bufp = STRLCPY(bufp, ", ", size); sbs_strcat(sbp, ", ");
bufp = STRLCPY(bufp, factionname(fv), size); sbs_strcat(sbp, factionname(fv));
} }
} }
} }
} }
bufp = STRLCPY(bufp, ", ", size); sbs_strcat(sbp, ", ");
sbs_strcat(sbp, str_itoa(u->number));
if (wrptr(&bufp, &size, snprintf(bufp, size, "%d ", u->number))) sbs_strcat(sbp, " ");
WARN_STATIC_BUFFER();
pzTmp = get_racename(u->attribs); pzTmp = get_racename(u->attribs);
if (pzTmp) { if (pzTmp) {
bufp = STRLCPY(bufp, pzTmp, size); sbs_strcat(sbp, pzTmp);
if (u->faction == f && fval(u_race(u), RCF_SHAPESHIFTANY)) { if (u->faction == f && fval(u_race(u), RCF_SHAPESHIFTANY)) {
bufp = STRLCPY(bufp, " (", size); sbs_strcat(sbp, " (");
bufp = STRLCPY(bufp, racename(lang, u, u_race(u)), size); sbs_strcat(sbp, racename(lang, u, u_race(u)));
if (size > 1) { sbs_strcat(sbp, ")");
strcpy(bufp++, ")");
--size;
}
} }
} }
else { else {
const race *irace = u_irace(u); const race *irace = u_irace(u);
bufp = STRLCPY(bufp, racename(lang, u, irace), size); const race *urace = u_race(u);
if (u->faction == f && irace != u_race(u)) { sbs_strcat(sbp, racename(lang, u, irace));
bufp = STRLCPY(bufp, " (", size); if (u->faction == f && irace != urace) {
bufp = STRLCPY(bufp, racename(lang, u, u_race(u)), size); sbs_strcat(sbp, " (");
if (size > 1) { sbs_strcat(sbp, racename(lang, u, urace));
strcpy(bufp++, ")"); sbs_strcat(sbp, ")");
--size;
}
} }
} }
if (fval(u, UFL_HERO) && (u->faction == f || omniscient(f))) { if (fval(u, UFL_HERO) && (u->faction == f || omniscient(f))) {
bufp = STRLCPY(bufp, ", ", size); sbs_strcat(sbp, ", ");
bufp = STRLCPY(bufp, LOC(lang, "hero"), size); sbs_strcat(sbp, LOC(lang, "hero"));
} }
/* status */ /* status */
if (u->number && (u->faction == f || isbattle)) { if (u->number && (u->faction == f || isbattle)) {
const char *c = hp_status(u); const char *c = hp_status(u);
c = c ? LOC(lang, c) : 0; c = c ? LOC(lang, c) : 0;
bufp = STRLCPY(bufp, ", ", size); sbs_strcat(sbp, ", ");
bufp += report_status(u, lang, bufp, size); report_status(u, lang, sbp);
if (c || fval(u, UFL_HUNGER)) { if (c || fval(u, UFL_HUNGER)) {
bufp = STRLCPY(bufp, " (", size); sbs_strcat(sbp, " (");
if (c) { if (c) {
bufp = STRLCPY(bufp, c, size); sbs_strcat(sbp, c);
} }
if (fval(u, UFL_HUNGER)) { if (fval(u, UFL_HUNGER)) {
if (c) { if (c) {
bufp = STRLCPY(bufp, ", ", size); sbs_strcat(sbp, ", ");
} }
bufp = STRLCPY(bufp, LOC(lang, "unit_hungers"), size); sbs_strcat(sbp, LOC(lang, "unit_hungers"));
}
if (size > 1) {
strcpy(bufp++, ")");
--size;
} }
sbs_strcat(sbp, ")");
} }
} }
if (is_guard(u)) { if (is_guard(u)) {
bufp = STRLCPY(bufp, ", ", size); sbs_strcat(sbp, ", ");
bufp = STRLCPY(bufp, LOC(lang, "unit_guards"), size); sbs_strcat(sbp, LOC(lang, "unit_guards"));
} }
dh = 0; dh = 0;
if (u->faction == f) { if (u->faction == f) {
skill *sv; skill *sv;
for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) { for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) {
size_t bytes = spskill(bufp, size, lang, u, sv, &dh); spskill(sbp, lang, u, sv, &dh);
assert(bytes <= INT_MAX);
if (wrptr(&bufp, &size, (int)bytes) != 0)
WARN_STATIC_BUFFER();
} }
} }
@ -831,22 +795,23 @@ bufunit(const faction * f, const unit * u, seen_mode mode, char *buf,
const char *ic; const char *ic;
int in; int in;
report_item(u, itm, f, &ic, NULL, &in, false); report_item(u, itm, f, &ic, NULL, &in, false);
if (in == 0 || ic == NULL) if (in == 0 || ic == NULL) {
continue; continue;
bufp = STRLCPY(bufp, ", ", size); }
sbs_strcat(sbp, ", ");
if (!dh) { if (!dh) {
result = snprintf(bufp, size, "%s: ", LOC(lang, "nr_inventory")); sbs_strcat(sbp, LOC(lang, "nr_inventory"));
if (wrptr(&bufp, &size, result) != 0) sbs_strcat(sbp, ": ");
WARN_STATIC_BUFFER();
dh = 1; dh = 1;
} }
if (in == 1) { if (in == 1) {
bufp = STRLCPY(bufp, ic, size); sbs_strcat(sbp, ic);
} }
else { else {
if (wrptr(&bufp, &size, snprintf(bufp, size, "%d %s", in, ic))) sbs_strcat(sbp, str_itoa(in));
WARN_STATIC_BUFFER(); sbs_strcat(sbp, " ");
sbs_strcat(sbp, ic);
} }
} }
@ -856,27 +821,26 @@ bufunit(const faction * f, const unit * u, seen_mode mode, char *buf,
if (book) { if (book) {
selist *ql = book->spells; selist *ql = book->spells;
int qi, header, maxlevel = effskill(u, SK_MAGIC, 0); int qi, header, maxlevel = effskill(u, SK_MAGIC, 0);
int n = snprintf(bufp, size, ". Aura %d/%d", get_spellpoints(u), max_spellpoints(u->region, u)); sbs_strcat(sbp, ". Aura ");
if (wrptr(&bufp, &size, n) != 0) { sbs_strcat(sbp, str_itoa(get_spellpoints(u)));
WARN_STATIC_BUFFER(); sbs_strcat(sbp, "/");
} sbs_strcat(sbp, str_itoa(max_spellpoints(u, NULL)));
for (header = 0, qi = 0; ql; selist_advance(&ql, &qi, 1)) { for (header = 0, qi = 0; ql; selist_advance(&ql, &qi, 1)) {
spellbook_entry * sbe = (spellbook_entry *)selist_get(ql, qi); spellbook_entry * sbe = (spellbook_entry *)selist_get(ql, qi);
const spell *sp = spellref_get(&sbe->spref); const spell *sp = spellref_get(&sbe->spref);
if (sbe->level <= maxlevel) { if (sbe->level <= maxlevel) {
if (!header) { if (!header) {
n = snprintf(bufp, size, ", %s: ", LOC(lang, "nr_spells")); sbs_strcat(sbp, ", ");
sbs_strcat(sbp, LOC(lang, "nr_spells"));
sbs_strcat(sbp, ": ");
header = 1; header = 1;
} }
else { else {
n = (int)str_strlcpy(bufp, ", ", size); sbs_strcat(sbp, ", ");
}
if (wrptr(&bufp, &size, n) != 0) {
WARN_STATIC_BUFFER();
} }
/* TODO: no need to deref the spellref here (spref->name is good) */ /* TODO: no need to deref the spellref here (spref->name is good) */
bufp = STRLCPY(bufp, spell_name(sp, lang), size); sbs_strcat(sbp, spell_name(sp, lang));
} }
} }
@ -885,10 +849,9 @@ bufunit(const faction * f, const unit * u, seen_mode mode, char *buf,
break; break;
} }
if (i != MAXCOMBATSPELLS) { if (i != MAXCOMBATSPELLS) {
n = snprintf(bufp, size, ", %s: ", LOC(lang, "nr_combatspells")); sbs_strcat(sbp, ", ");
if (wrptr(&bufp, &size, n) != 0) sbs_strcat(sbp, LOC(lang, "nr_combatspells"));
WARN_STATIC_BUFFER(); sbs_strcat(sbp, ": ");
dh = 0; dh = 0;
for (i = 0; i < MAXCOMBATSPELLS; i++) { for (i = 0; i < MAXCOMBATSPELLS; i++) {
const spell *sp; const spell *sp;
@ -896,20 +859,20 @@ bufunit(const faction * f, const unit * u, seen_mode mode, char *buf,
dh = 1; dh = 1;
} }
else { else {
bufp = STRLCPY(bufp, ", ", size); sbs_strcat(sbp, ", ");
} }
sp = get_combatspell(u, i); sp = get_combatspell(u, i);
if (sp) { if (sp) {
int sl = get_combatspelllevel(u, i); int sl = get_combatspelllevel(u, i);
bufp = STRLCPY(bufp, spell_name(sp, lang), size); sbs_strcat(sbp, spell_name(sp, lang));
if (sl > 0) { if (sl > 0) {
n = snprintf(bufp, size, " (%d)", sl); sbs_strcat(sbp, "( ");
if (wrptr(&bufp, &size, n) != 0) sbs_strcat(sbp, str_itoa(sl));
WARN_STATIC_BUFFER(); sbs_strcat(sbp, ")");
} }
} }
else { else {
bufp = STRLCPY(bufp, LOC(lang, "nr_nospells"), size); sbs_strcat(sbp, LOC(lang, "nr_nospells"));
} }
} }
} }
@ -920,62 +883,59 @@ bufunit(const faction * f, const unit * u, seen_mode mode, char *buf,
for (ord = u->old_orders; ord; ord = ord->next) { for (ord = u->old_orders; ord; ord = ord->next) {
keyword_t kwd = getkeyword(ord); keyword_t kwd = getkeyword(ord);
if (is_repeated(kwd)) { if (is_repeated(kwd)) {
if (printed < ORDERS_IN_NR) { if (printed >= ORDERS_IN_NR) {
int n = (int)buforder(bufp, size, ord, u->faction->locale, printed++);
if (wrptr(&bufp, &size, n) != 0)
WARN_STATIC_BUFFER();
}
else
break; break;
}
buforder(sbp, ord, u->faction->locale, printed++);
} }
} }
if (printed < ORDERS_IN_NR) if (printed < ORDERS_IN_NR) {
for (ord = u->orders; ord; ord = ord->next) { for (ord = u->orders; ord; ord = ord->next) {
keyword_t kwd = getkeyword(ord); keyword_t kwd = getkeyword(ord);
if (is_repeated(kwd)) { if (is_repeated(kwd)) {
if (printed < ORDERS_IN_NR) { if (printed >= ORDERS_IN_NR) {
int n = (int)buforder(bufp, size, ord, lang, printed++);
if (wrptr(&bufp, &size, n) != 0)
WARN_STATIC_BUFFER();
}
else {
break; break;
} }
buforder(sbp, ord, lang, printed++);
} }
} }
}
} }
} }
i = 0; i = 0;
str = u_description(u, lang); str = u_description(u, lang);
if (str) { if (str) {
bufp = STRLCPY(bufp, "; ", size); sbs_strcat(sbp, "; ");
bufp = STRLCPY(bufp, str, size); sbs_strcat(sbp, str);
i = str[strlen(str) - 1]; i = str[strlen(str) - 1];
} }
if (i != '!' && i != '?' && i != '.') { if (i != '!' && i != '?' && i != '.') {
if (size > 1) { sbs_strcat(sbp, ".");
strcpy(bufp++, ".");
--size;
}
} }
pzTmp = uprivate(u); pzTmp = uprivate(u);
if (u->faction == f && pzTmp) { if (u->faction == f && pzTmp) {
bufp = STRLCPY(bufp, " (Bem: ", size); sbs_strcat(sbp, " (Bem: ");
bufp = STRLCPY(bufp, pzTmp, size); sbs_strcat(sbp, pzTmp);
bufp = STRLCPY(bufp, ")", size); sbs_strcat(sbp, ")");
} }
}
dh = 0; int bufunit_depr(const faction * f, const unit * u, seen_mode mode,
char *buf, size_t size)
{
int getarnt = fval(u, UFL_ANON_FACTION);
const faction * fv = visible_faction(f, u);
sbstring sbs;
sbs_init(&sbs, buf, size);
bufunit(f, u, fv, mode, getarnt, &sbs);
if (!getarnt) { if (!getarnt) {
if (alliedfaction(f, fv, HELP_ALL)) { if (alliedfaction(f, fv, HELP_ALL)) {
dh = 1; return 1;
} }
} }
if (size <= 1) { return 0;
log_warning("bufunit ran out of space after writing %u bytes.\n", (bufp - buf));
}
return dh;
} }
void split_paragraph(strlist ** SP, const char *s, unsigned int indent, unsigned int width, char mark) void split_paragraph(strlist ** SP, const char *s, unsigned int indent, unsigned int width, char mark)
@ -1049,7 +1009,7 @@ spunit(struct strlist **SP, const struct faction *f, const unit * u, unsigned in
seen_mode mode) seen_mode mode)
{ {
char buf[DISPLAYSIZE]; char buf[DISPLAYSIZE];
int dh = bufunit(f, u, mode, buf, sizeof(buf)); int dh = bufunit_depr(f, u, mode, buf, sizeof(buf));
lparagraph(SP, buf, indent, lparagraph(SP, buf, indent,
(char)((u->faction == f) ? '*' : (dh ? '+' : '-'))); (char)((u->faction == f) ? '*' : (dh ? '+' : '-')));
} }
@ -2225,31 +2185,29 @@ static void eval_regions(struct opstack **stack, const void *userdata)
int handle_end, begin = opop(stack).i; int handle_end, begin = opop(stack).i;
const arg_regions *aregs = (const arg_regions *)opop(stack).v; const arg_regions *aregs = (const arg_regions *)opop(stack).v;
char buf[256]; char buf[256];
size_t size = sizeof(buf) - 1;
variant var; variant var;
char *bufp = buf; sbstring sbs;
sbs_init(&sbs, buf, sizeof(buf));
if (aregs == NULL) { if (aregs == NULL) {
handle_end = begin; handle_end = begin;
} }
else { else if (i >= 0) {
if (i >= 0) handle_end = begin + i;
handle_end = begin + i;
else
handle_end = aregs->nregions + i;
} }
else {
handle_end = aregs->nregions + i;
}
for (i = begin; i < handle_end; ++i) { for (i = begin; i < handle_end; ++i) {
const char *rname = (const char *)regionname(aregs->regions[i], report); const char *rname = (const char *)regionname(aregs->regions[i], report);
bufp = STRLCPY(bufp, rname, size); sbs_strcat(&sbs, rname);
if (i + 1 < handle_end && size > 2) { if (i + 1 < handle_end) {
strcat(bufp, ", "); sbs_strcat(&sbs, ", ");
bufp += 2;
size -= 2;
} }
} }
*bufp = 0; var.v = strcpy(balloc(sbs_length(&sbs)), buf);
var.v = strcpy(balloc((size_t)(bufp - buf + 1)), buf);
opush(stack, var); opush(stack, var);
} }

View File

@ -31,6 +31,7 @@ extern "C" {
struct battle; struct battle;
struct gamedate; struct gamedate;
struct sbstring;
struct selist; struct selist;
struct stream; struct stream;
struct seen_region; struct seen_region;
@ -87,12 +88,15 @@ extern "C" {
void register_reporttype(const char *extension, report_fun write, void register_reporttype(const char *extension, report_fun write,
int flag); int flag);
int bufunit(const struct faction *f, const struct unit *u, seen_mode mode, int bufunit_depr(const struct faction *f, const struct unit *u, seen_mode mode,
char *buf, size_t size); char *buf, size_t size);
void bufunit(const struct faction * f, const struct unit * u,
const struct faction *fv, seen_mode mode, int getarnt,
struct sbstring *sbp);
const char *trailinto(const struct region *r, const char *trailinto(const struct region *r,
const struct locale *lang); const struct locale *lang);
size_t report_status(const struct unit *u, size_t report_status_depr(const struct unit *u,
const struct locale *lang, char *buf, size_t siz); const struct locale *lang, char *buf, size_t siz);
void report_battle_start(struct battle * b); void report_battle_start(struct battle * b);
@ -116,7 +120,7 @@ extern "C" {
int report_items(const struct unit *u, struct item *result, int size, int report_items(const struct unit *u, struct item *result, int size,
const struct unit *owner, const struct faction *viewer); const struct unit *owner, const struct faction *viewer);
void report_warnings(struct faction *f, int now); void report_warnings(struct faction *f, int now);
void report_raceinfo(const struct race *rc, const struct locale *lang, char *buf, size_t length); void report_raceinfo(const struct race *rc, const struct locale *lang, struct sbstring *sbp);
void report_race_skills(const struct race *rc, char *zText, size_t length, const struct locale *lang); 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, void report_item(const struct unit *owner, const struct item *i,
const struct faction *viewer, const char **name, const char **basename, const struct faction *viewer, const char **name, const char **basename,

View File

@ -199,55 +199,55 @@ static void test_bufunit_fstealth(CuTest *tc) {
key_set(&u->attribs, 42, 42); key_set(&u->attribs, 42, 42);
/* report to ourselves */ /* report to ourselves */
bufunit(f1, u, seen_unit, buf, sizeof(buf)); bufunit_depr(f1, u, seen_unit, buf, sizeof(buf));
CuAssertStrEquals(tc, "Hodor (1), 1 human, aggressive.", buf); CuAssertStrEquals(tc, "Hodor (1), 1 human, aggressive.", buf);
/* ... also when we are anonymous */ /* ... also when we are anonymous */
u->flags |= UFL_ANON_FACTION; u->flags |= UFL_ANON_FACTION;
bufunit(f1, u, seen_unit, buf, sizeof(buf)); bufunit_depr(f1, u, seen_unit, buf, sizeof(buf));
CuAssertStrEquals(tc, "Hodor (1), anonymous, 1 human, aggressive.", buf); CuAssertStrEquals(tc, "Hodor (1), anonymous, 1 human, aggressive.", buf);
u->flags &= ~UFL_ANON_FACTION; u->flags &= ~UFL_ANON_FACTION;
/* we see that our unit is cloaked */ /* we see that our unit is cloaked */
set_factionstealth(u, f2); set_factionstealth(u, f2);
CuAssertPtrNotNull(tc, u->attribs); CuAssertPtrNotNull(tc, u->attribs);
bufunit(f1, u, seen_unit, buf, sizeof(buf)); bufunit_depr(f1, u, seen_unit, buf, sizeof(buf));
CuAssertStrEquals(tc, "Hodor (1), TWW (2), 1 human, aggressive.", buf); CuAssertStrEquals(tc, "Hodor (1), TWW (2), 1 human, aggressive.", buf);
/* ... also when we are anonymous */ /* ... also when we are anonymous */
u->flags |= UFL_ANON_FACTION; u->flags |= UFL_ANON_FACTION;
bufunit(f1, u, seen_unit, buf, sizeof(buf)); bufunit_depr(f1, u, seen_unit, buf, sizeof(buf));
CuAssertStrEquals(tc, "Hodor (1), anonymous, 1 human, aggressive.", buf); CuAssertStrEquals(tc, "Hodor (1), anonymous, 1 human, aggressive.", buf);
u->flags &= ~UFL_ANON_FACTION; u->flags &= ~UFL_ANON_FACTION;
/* we can see that someone is presenting as us */ /* we can see that someone is presenting as us */
bufunit(f2, u, seen_unit, buf, sizeof(buf)); bufunit_depr(f2, u, seen_unit, buf, sizeof(buf));
CuAssertStrEquals(tc, "Hodor (1), TWW (2), 1 human.", buf); CuAssertStrEquals(tc, "Hodor (1), TWW (2), 1 human.", buf);
/* ... but not if they are anonymous */ /* ... but not if they are anonymous */
u->flags |= UFL_ANON_FACTION; u->flags |= UFL_ANON_FACTION;
bufunit(f2, u, seen_unit, buf, sizeof(buf)); bufunit_depr(f2, u, seen_unit, buf, sizeof(buf));
CuAssertStrEquals(tc, "Hodor (1), anonymous, 1 human.", buf); CuAssertStrEquals(tc, "Hodor (1), anonymous, 1 human.", buf);
u->flags &= ~UFL_ANON_FACTION; u->flags &= ~UFL_ANON_FACTION;
/* we see the same thing as them when we are an ally */ /* we see the same thing as them when we are an ally */
ally_set(&f1->allies, f2, HELP_FSTEALTH); ally_set(&f1->allies, f2, HELP_FSTEALTH);
bufunit(f2, u, seen_unit, buf, sizeof(buf)); bufunit_depr(f2, u, seen_unit, buf, sizeof(buf));
CuAssertStrEquals(tc, "Hodor (1), TWW (2) (UFO (1)), 1 human.", buf); CuAssertStrEquals(tc, "Hodor (1), TWW (2) (UFO (1)), 1 human.", buf);
/* ... also when they are anonymous */ /* ... also when they are anonymous */
u->flags |= UFL_ANON_FACTION; u->flags |= UFL_ANON_FACTION;
bufunit(f2, u, seen_unit, buf, sizeof(buf)); bufunit_depr(f2, u, seen_unit, buf, sizeof(buf));
CuAssertStrEquals(tc, "Hodor (1), anonymous, 1 human.", buf); CuAssertStrEquals(tc, "Hodor (1), anonymous, 1 human.", buf);
u->flags &= ~UFL_ANON_FACTION; u->flags &= ~UFL_ANON_FACTION;
/* fstealth has no influence when we are allies, same results again */ /* fstealth has no influence when we are allies, same results again */
set_factionstealth(u, NULL); set_factionstealth(u, NULL);
bufunit(f2, u, seen_unit, buf, sizeof(buf)); bufunit_depr(f2, u, seen_unit, buf, sizeof(buf));
CuAssertStrEquals(tc, "Hodor (1), UFO (1), 1 human.", buf); CuAssertStrEquals(tc, "Hodor (1), UFO (1), 1 human.", buf);
u->flags |= UFL_ANON_FACTION; u->flags |= UFL_ANON_FACTION;
bufunit(f2, u, seen_unit, buf, sizeof(buf)); bufunit_depr(f2, u, seen_unit, buf, sizeof(buf));
CuAssertStrEquals(tc, "Hodor (1), anonymous, 1 human.", buf); CuAssertStrEquals(tc, "Hodor (1), anonymous, 1 human.", buf);
u->flags &= ~UFL_ANON_FACTION; u->flags &= ~UFL_ANON_FACTION;
@ -277,20 +277,20 @@ static void test_bufunit(CuTest *tc) {
unit_setname(u, "Hodor"); unit_setname(u, "Hodor");
unit_setid(u, 1); unit_setid(u, 1);
bufunit(u->faction, u, 0, buffer, sizeof(buffer)); bufunit_depr(u->faction, u, 0, buffer, sizeof(buffer));
CuAssertStrEquals(tc, "Hodor (1), 1 human, aggressiv.", buffer); CuAssertStrEquals(tc, "Hodor (1), 1 human, aggressiv.", buffer);
set_level(u, SK_ALCHEMY, 1); set_level(u, SK_ALCHEMY, 1);
bufunit(u->faction, u, 0, buffer, sizeof(buffer)); bufunit_depr(u->faction, u, 0, buffer, sizeof(buffer));
CuAssertStrEquals(tc, "Hodor (1), 1 human, aggressiv, Talente: Alchemie 2.", buffer); CuAssertStrEquals(tc, "Hodor (1), 1 human, aggressiv, Talente: Alchemie 2.", buffer);
set_level(u, SK_SAILING, 1); set_level(u, SK_SAILING, 1);
bufunit(u->faction, u, 0, buffer, sizeof(buffer)); bufunit_depr(u->faction, u, 0, buffer, sizeof(buffer));
CuAssertStrEquals(tc, "Hodor (1), 1 human, aggressiv, Talente: Alchemie 2, Segeln 1.", buffer); CuAssertStrEquals(tc, "Hodor (1), 1 human, aggressiv, Talente: Alchemie 2, Segeln 1.", buffer);
f = test_create_faction(NULL); f = test_create_faction(NULL);
f->locale = get_or_create_locale("de"); f->locale = get_or_create_locale("de");
bufunit(f, u, 0, buffer, sizeof(buffer)); bufunit_depr(f, u, 0, buffer, sizeof(buffer));
CuAssertStrEquals(tc, "Hodor (1), UFO (1), 1 human.", buffer); CuAssertStrEquals(tc, "Hodor (1), UFO (1), 1 human.", buffer);
test_teardown(); test_teardown();

View File

@ -3790,7 +3790,7 @@ static int sp_migranten(castorder * co)
return 0; return 0;
} }
/* maximal Stufe Personen */ /* maximal Stufe Personen */
if (target->number > cast_level || target->number > max_spellpoints(r, mage)) { if (target->number > cast_level || target->number > max_spellpoints_depr(r, mage)) {
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
"spellfail_toomanytargets", "")); "spellfail_toomanytargets", ""));
return 0; return 0;

View File

@ -67,7 +67,7 @@ void spy_message(int spy, const unit * u, const unit * target)
{ {
char status[32]; char status[32];
report_status(target, u->faction->locale, status, sizeof(status)); report_status_depr(target, u->faction->locale, status, sizeof(status));
ADDMSG(&u->faction->msgs, msg_message("spyreport", "spy target status", u, ADDMSG(&u->faction->msgs, msg_message("spyreport", "spy target status", u,
target, status)); target, status));

View File

@ -67,7 +67,7 @@ static void do_shock(unit * u, const char *reason)
/* Aura - Verlust */ /* Aura - Verlust */
if (is_mage(u)) { if (is_mage(u)) {
int aura = max_spellpoints(u->region, u) / 10; int aura = max_spellpoints_depr(u->region, u) / 10;
int now = get_spellpoints(u); int now = get_spellpoints(u);
if (now > aura) { if (now > aura) {
set_spellpoints(u, aura); set_spellpoints(u, aura);

View File

@ -18,6 +18,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#ifdef _MSC_VER #ifdef _MSC_VER
#include <platform.h> #include <platform.h>
#define HAVE__ITOA
#endif #endif
#include "strings.h" #include "strings.h"
@ -34,10 +35,28 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <string.h> #include <string.h>
#endif #endif
const char *str_itoa(int n) { const char* str_itoab(int val, int base)
static char buf[12]; {
snprintf(buf, sizeof(buf), "%d", n); static char buf[32] = { 0 };
return buf; #ifdef HAVE__ITOAB
return _itoa(val, buf, base);
#else
int i = 30;
for (; val && i; --i, val /= base) {
buf[i] = "0123456789abcdefghijklmnopqrstuvwxyz"[val % base];
}
return &buf[i + 1];
#endif
}
const char *str_itoa(int n)
{
#ifdef HAVE__ITOA
static char buf[32] = { 0 };
return _itoa(n, buf, 10);
#else
return str_itoab(n, 10);
#endif
} }
size_t str_strlcpy(char *dst, const char *src, size_t len) size_t str_strlcpy(char *dst, const char *src, size_t len)

View File

@ -29,6 +29,7 @@ extern "C" {
void str_replace(char *buffer, size_t size, const char *tmpl, const char *var, const char *value); void str_replace(char *buffer, size_t size, const char *tmpl, const char *var, const char *value);
int str_hash(const char *s); int str_hash(const char *s);
const char *str_itoa(int i); const char *str_itoa(int i);
const char *str_itoab(int i, int base);
size_t str_slprintf(char * dst, size_t size, const char * format, ...); size_t str_slprintf(char * dst, size_t size, const char * format, ...);
size_t str_strlcpy(char *dst, const char *src, size_t len); size_t str_strlcpy(char *dst, const char *src, size_t len);
size_t str_strlcat(char *dst, const char *src, size_t len); size_t str_strlcat(char *dst, const char *src, size_t len);