diff --git a/clibs b/clibs index f9842e07a..9b6e34959 160000 --- a/clibs +++ b/clibs @@ -1 +1 @@ -Subproject commit f9842e07a442c5453c270badf25ab72633b4edf5 +Subproject commit 9b6e34959f77d7ca3a4ce3826cb487487f557441 diff --git a/conf/e2/config.json b/conf/e2/config.json index ebc385adf..4da247263 100644 --- a/conf/e2/config.json +++ b/conf/e2/config.json @@ -39,7 +39,7 @@ "entertain.perlevel": 20, "taxing.perlevel": 20, "nmr.timeout": 5, - "nmr.removenewbie": 0, + "nmr.removenewbie": false, "GiveRestriction": 3, "hunger.long": true, "init_spells": 0, diff --git a/conf/e3/config.json b/conf/e3/config.json index c1fa2725c..b4b6d0e48 100644 --- a/conf/e3/config.json +++ b/conf/e3/config.json @@ -58,7 +58,7 @@ "entertain.base": 0, "entertain.perlevel": 20, "nmr.timeout": 5, - "nmr.removenewbie": 0, + "nmr.removenewbie": false, "GiveRestriction": 3, "healing.forest": 2.0, "hunger.long": false, diff --git a/scripts/eressea/e2/init.lua b/scripts/eressea/e2/init.lua index 52636d207..9df7a1062 100644 --- a/scripts/eressea/e2/init.lua +++ b/scripts/eressea/e2/init.lua @@ -4,6 +4,7 @@ eressea.log.debug('rules for game E2') math.randomseed(rng.random()) local equipment = require('eressea.equipment') + local sets = { ['seed_faction'] = { ['items'] = { diff --git a/scripts/eressea/init.lua b/scripts/eressea/init.lua index 1af37d2d5..d840fe899 100644 --- a/scripts/eressea/init.lua +++ b/scripts/eressea/init.lua @@ -1,5 +1,6 @@ require 'eressea.path' require 'eressea.resources' +require 'eressea.equipment' require 'eressea.spells' local self = {} diff --git a/scripts/map.lua b/scripts/map.lua index cad3ae1fd..98579924f 100644 --- a/scripts/map.lua +++ b/scripts/map.lua @@ -6,5 +6,6 @@ package.path = package.path .. ';' .. path .. '/?.lua;' .. path .. '/?/init.lua' require 'eressea.path' require 'eressea' require 'eressea.xmlconf' + eressea.read_game(get_turn() .. ".dat") gmtool.editor() diff --git a/src/attributes/attributes.c b/src/attributes/attributes.c index 907478aaa..fa6f15d73 100644 --- a/src/attributes/attributes.c +++ b/src/attributes/attributes.c @@ -209,6 +209,7 @@ void register_attributes(void) at_deprecate("maxmagicians", a_readint); /* factions with differnt magician limits, probably unused */ at_deprecate("hurting", a_readint); /* an old arena attribute */ + at_deprecate("chaoscount", a_readint); /* used to increase the chance of monster spawns */ at_deprecate("xontormiaexpress", a_readint); /* required for old datafiles */ at_deprecate("orcification", a_readint); /* required for old datafiles */ at_deprecate("lua", read_ext); /* required for old datafiles */ diff --git a/src/battle.c b/src/battle.c index 9092718a2..be950af7f 100644 --- a/src/battle.c +++ b/src/battle.c @@ -20,7 +20,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include "battle.h" #include "alchemy.h" -#include "chaos.h" #include "guard.h" #include "laws.h" #include "monsters.h" @@ -2531,7 +2530,6 @@ static void battle_effects(battle * b, int dead_players) } if (dead_peasants) { deathcounts(r, dead_peasants + dead_players); - add_chaoscount(r, dead_peasants / 2); rsetpeasants(r, rp - dead_peasants); } } diff --git a/src/bind_region.c b/src/bind_region.c index e041fba77..b49ceb078 100644 --- a/src/bind_region.c +++ b/src/bind_region.c @@ -7,7 +7,6 @@ #include "bind_ship.h" #include "bind_building.h" -#include "chaos.h" #include "teleport.h" #include @@ -356,7 +355,7 @@ static int tolua_region_get_resourcelevel(lua_State * L) #define LUA_ASSERT(c, s) if (!(c)) { log_error("%s(%d): %s\n", __FILE__, __LINE__, (s)); return 0; } static int special_resource(const char *type) { - const char * special[] = { "seed", "sapling", "tree", "grave", "chaos", 0 }; + const char * special[] = { "seed", "sapling", "tree", "grave", NULL }; int i; for (i = 0; special[i]; ++i) { @@ -389,9 +388,6 @@ static int tolua_region_get_resource(lua_State * L) case 3: result = deathcount(r); break; - case 4: - result = get_chaoscount(r); - break; default: rtype = rt_find(type); if (rtype) { @@ -423,9 +419,6 @@ static int tolua_region_set_resource(lua_State * L) case 3: deathcounts(r, value - deathcount(r)); break; - case 4: - add_chaoscount(r, value - get_chaoscount(r)); - break; default: rtype = rt_find(type); if (rtype != NULL) { diff --git a/src/chaos.c b/src/chaos.c index 67cdb356d..21a5a8624 100644 --- a/src/chaos.c +++ b/src/chaos.c @@ -39,57 +39,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -/*********************/ -/* at_chaoscount */ -/*********************/ -attrib_type at_chaoscount = { - "chaoscount", - DEFAULT_INIT, - DEFAULT_FINALIZE, - DEFAULT_AGE, - a_writeint, - a_readint, - NULL, - ATF_UNIQUE -}; - -void set_chaoscount(struct region *r, int deaths) -{ - if (deaths==0) { - a_removeall(&r->attribs, &at_chaoscount); - } else { - attrib *a = a_find(r->attribs, &at_chaoscount); - if (!a) { - a = a_add(&r->attribs, a_new(&at_chaoscount)); - } - a->data.i = deaths; - } -} - -int get_chaoscount(const region * r) -{ - attrib *a = a_find(r->attribs, &at_chaoscount); - if (!a) - return 0; - return a->data.i; -} - -void add_chaoscount(region * r, int fallen) -{ - attrib *a; - - if (fallen == 0) - return; - - a = a_find(r->attribs, &at_chaoscount); - if (!a) - a = a_add(&r->attribs, a_new(&at_chaoscount)); - a->data.i += fallen; - - if (a->data.i <= 0) - a_remove(&r->attribs, a); -} - static const terrain_type *chaosterrain(void) { static const terrain_type **types; @@ -248,18 +197,8 @@ void chaos_update(void) { region *r; /* Chaos */ for (r = regions; r; r = r->next) { - int i; - if ((r->flags & RF_CHAOTIC)) { chaos(r); } - i = get_chaoscount(r); - if (i) { - add_chaoscount(r, -(int)(i * ((double)(rng_int() % 10)) / 100.0)); - } } } - -void chaos_register(void) { - at_register(&at_chaoscount); -} diff --git a/src/chaos.h b/src/chaos.h index 0c2667083..550aa3efb 100644 --- a/src/chaos.h +++ b/src/chaos.h @@ -24,15 +24,8 @@ extern "C" { struct region; - extern struct attrib_type at_chaoscount; - - void chaos_register(void); void chaos_update(void); - void set_chaoscount(struct region *r, int deaths); - int get_chaoscount(const struct region * r); - void add_chaoscount(struct region * r, int deaths); - #ifdef __cplusplus } #endif diff --git a/src/eressea.c b/src/eressea.c index 982dfe6ee..0bf1454ee 100644 --- a/src/eressea.c +++ b/src/eressea.c @@ -24,7 +24,6 @@ #include "attributes/attributes.h" #include "races/races.h" -#include "chaos.h" #include "items.h" #include "creport.h" #include "report.h" @@ -82,5 +81,4 @@ void game_init(void) register_attributes(); register_gmcmd(); - chaos_register(); } diff --git a/src/gmtool.c b/src/gmtool.c index e13701f6f..d3858d09f 100644 --- a/src/gmtool.c +++ b/src/gmtool.c @@ -50,7 +50,6 @@ #include #include "gmtool_structs.h" -#include "chaos.h" #include "console.h" #include "listbox.h" #include "wormhole.h" @@ -531,7 +530,6 @@ static void statusline(WINDOW * win, const char *str) } static void reset_region(region *r) { - set_chaoscount(r, 0); r->flags = 0; a_removeall(&r->attribs, NULL); while (r->units) { diff --git a/src/kernel/config.c b/src/kernel/config.c index ff2457971..ec45ddd0d 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -631,28 +631,24 @@ void kernel_init(void) translation_init(); } -static order * defaults[MAXLOCALES]; - order *default_order(const struct locale *lang) { int i = locale_index(lang); + keyword_t kwd; + const char * str; order *result = 0; - assert(i < MAXLOCALES); - result = defaults[i]; - if (!result) { - const char * str; - keyword_t kwd = NOKEYWORD; - str = config_get("orders.default"); - if (str) { - kwd = findkeyword(str); - } - if (kwd != NOKEYWORD) { - result = create_order(kwd, lang, NULL); - defaults[i] = result; - } + assert(i < MAXLOCALES); + kwd = keyword_disabled(K_WORK) ? NOKEYWORD : K_WORK; + str = config_get("orders.default"); + if (str) { + kwd = findkeyword(str); } - return result ? copy_order(result) : 0; + if (kwd != NOKEYWORD) { + result = create_order(kwd, lang, NULL); + return copy_order(result); + } + return NULL; } int rule_give(void) @@ -760,14 +756,6 @@ void free_config(void) { */ void free_gamedata(void) { - int i; - - for (i = 0; i != MAXLOCALES; ++i) { - if (defaults[i]) { - free_order(defaults[i]); - defaults[i] = 0; - } - } free(forbidden_ids); forbidden_ids = NULL; diff --git a/src/kernel/config.test.c b/src/kernel/config.test.c index 7a2097ce4..e99ba9d08 100644 --- a/src/kernel/config.test.c +++ b/src/kernel/config.test.c @@ -180,15 +180,22 @@ static void test_default_order(CuTest *tc) { test_setup(); loc = test_create_locale(); - ord = default_order(loc); - CuAssertPtrEquals(tc, 0, ord); - free_order(ord); - config_set("orders.default", "work"); ord = default_order(loc); CuAssertPtrNotNull(tc, ord); CuAssertIntEquals(tc, K_WORK, getkeyword(ord)); free_order(ord); + + enable_keyword(K_WORK, false); + ord = default_order(loc); + CuAssertPtrEquals(tc, NULL, ord); + free_order(ord); + + config_set("orders.default", "entertain"); + ord = default_order(loc); + CuAssertPtrNotNull(tc, ord); + CuAssertIntEquals(tc, K_ENTERTAIN, getkeyword(ord)); + free_order(ord); test_teardown(); } diff --git a/src/kernel/faction.c b/src/kernel/faction.c index bc08ba010..16c0c789c 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -29,6 +29,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "group.h" #include "item.h" #include "messages.h" +#include "order.h" #include "plane.h" #include "race.h" #include "region.h" @@ -294,8 +295,13 @@ unit *addplayer(region * r, faction * f) assert(f->units == NULL); faction_setorigin(f, 0, r->x, r->y); u = create_unit(r, f, 1, f->race, 0, NULL, NULL); + u->thisorder = default_order(f->locale); + unit_addorder(u, copy_order(u->thisorder)); name = config_get("rules.equip_first"); - equip_unit(u, name ? name : "first_unit"); + if (!equip_unit(u, name ? name : "first_unit")) { + /* give every unit enough money to survive the first turn */ + i_change(&u->items, get_resourcetype(R_SILVER)->itype, maintenance_cost(u)); + } u->hp = unit_max_hp(u) * u->number; fset(u, UFL_ISNEW); if (f->race == get_race(RC_DAEMON)) { diff --git a/src/kernel/faction.test.c b/src/kernel/faction.test.c index 7748f693d..37ec70e50 100644 --- a/src/kernel/faction.test.c +++ b/src/kernel/faction.test.c @@ -3,8 +3,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -298,9 +300,30 @@ static void test_save_special_items(CuTest *tc) { test_teardown(); } +static void test_addplayer(CuTest *tc) { + unit *u; + region *r; + faction *f; + item_type *itype; + test_setup(); + callbacks.equip_unit = NULL; + itype = test_create_silver(); + r = test_create_plain(0, 0); + f = test_create_faction(NULL); + u = addplayer(r, f); + CuAssertPtrNotNull(tc, u); + CuAssertPtrEquals(tc, r, u->region); + CuAssertPtrEquals(tc, f, u->faction); + CuAssertIntEquals(tc, i_get(u->items, itype), 10); + CuAssertPtrNotNull(tc, u->orders); + CuAssertIntEquals(tc, K_WORK, getkeyword(u->orders)); + test_teardown(); +} + CuSuite *get_faction_suite(void) { CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_addplayer); SUITE_ADD_TEST(suite, test_max_migrants); SUITE_ADD_TEST(suite, test_addfaction); SUITE_ADD_TEST(suite, test_remove_empty_factions); diff --git a/src/kernel/order.test.c b/src/kernel/order.test.c index 37f88ae5a..3a2f44c56 100644 --- a/src/kernel/order.test.c +++ b/src/kernel/order.test.c @@ -512,6 +512,7 @@ static void test_create_order_long(CuTest *tc) { stream_order(&out, ord, lang, true); out.api->rewind(out.handle); out.api->readln(out.handle, buffer, sizeof(buffer)); + CuAssertIntEquals(tc, 1026, strlen(buffer)); mstream_done(&out); free_order(ord); test_teardown(); diff --git a/src/monsters.c b/src/monsters.c index be4ec7525..181615a40 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -24,7 +24,6 @@ #include "monsters.h" #include "economy.h" -#include "chaos.h" #include "give.h" #include "guard.h" #include "laws.h" @@ -843,18 +842,14 @@ void plan_monsters(faction * f) pathfinder_cleanup(); } -static double chaosfactor(region * r) -{ - return fval(r, RF_CHAOTIC) ? ((double)(1 + get_chaoscount(r)) / 1000.0) : 0.0; -} - static int nrand(int handle_start, int sub) { int res = 0; do { - if (rng_int() % 100 < handle_start) + if (rng_int() % 100 < handle_start) { res++; + } handle_start -= sub; } while (handle_start > 0); @@ -876,7 +871,7 @@ void spawn_dragons(void) region *r; faction *monsters = get_or_create_monsters(); int minage = config_get_int("monsters.spawn.min_age", 100); - int spawn_chance = 100 * config_get_int("monsters.spawn.chance", 100); + int spawn_chance = config_get_int("monsters.spawn.chance", 100); if (spawn_chance <= 0) { /* monster spawning disabled */ @@ -895,7 +890,8 @@ void spawn_dragons(void) else if ((r->terrain == newterrain(T_GLACIER) || r->terrain == newterrain(T_SWAMP) || r->terrain == newterrain(T_DESERT)) - && rng_int() % spawn_chance < (5 + 100 * chaosfactor(r))) { + && rng_int() % spawn_chance < 6) + { if (chance(0.80)) { u = create_unit(r, monsters, nrand(60, 20) + 1, get_race(RC_FIREDRAGON), 0, NULL, NULL); } @@ -907,7 +903,7 @@ void spawn_dragons(void) log_debug("spawning %d %s in %s.\n", u->number, LOC(default_locale, - rc_name_s(u_race(u), (u->number == 1) ? NAME_SINGULAR : NAME_PLURAL)), regionname(r, NULL)); + rc_name_s(u_race(u), (u->number == 1) ? NAME_SINGULAR : NAME_PLURAL)), regionname(r, NULL)); name_unit(u); @@ -932,9 +928,9 @@ void spawn_undead(void) continue; } } - /* Chance 0.1% * chaosfactor */ + if (r->land && unburied > rpeasants(r) / 20 - && rng_int() % 10000 < (100 + 100 * chaosfactor(r))) { + && rng_int() % 10000 < 200) { message *msg; unit *u; /* es ist sinnfrei, wenn irgendwo im Wald 3er-Einheiten Untote entstehen. diff --git a/src/report.c b/src/report.c index 2a0e9eb3a..31e1bcd26 100644 --- a/src/report.c +++ b/src/report.c @@ -79,7 +79,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include #include -#include +#include "util/bsdstring.h" #include #include #include @@ -243,39 +243,44 @@ static size_t write_spell_modifier(const spell * sp, int flag, const char * str, return 0; } -void nr_spell_syntax(struct stream *out, spellbook_entry * sbe, const struct locale *lang) +void nr_spell_syntax(char *buf, size_t size, spellbook_entry * sbe, const struct locale *lang) { - int bytes; - char buf[4096]; - char *bufp = buf; - size_t size = sizeof(buf) - 1; const spell *sp = spellref_get(&sbe->spref); const char *params = sp->parameter; + const char *spname; + sbstring sbs; + sbs_init(&sbs, buf, size); if (sp->sptyp & ISCOMBATSPELL) { - bytes = (int)str_strlcpy(bufp, LOC(lang, keyword(K_COMBATSPELL)), size); + sbs_strcpy(&sbs, LOC(lang, keyword(K_COMBATSPELL))); } else { - bytes = (int)str_strlcpy(bufp, LOC(lang, keyword(K_CAST)), size); + sbs_strcpy(&sbs, LOC(lang, keyword(K_CAST))); } - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); /* Reihenfolge beachten: Erst REGION, dann STUFE! */ if (sp->sptyp & FARCASTING) { - bytes = snprintf(bufp, size, " [%s x y]", LOC(lang, parameters[P_REGION])); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(&sbs, " ["); + sbs_strcat(&sbs, LOC(lang, parameters[P_REGION])); + sbs_strcat(&sbs, " x y]"); } if (sp->sptyp & SPELLLEVEL) { - bytes = snprintf(bufp, size, " [%s n]", LOC(lang, parameters[P_LEVEL])); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(&sbs, " ["); + sbs_strcat(&sbs, LOC(lang, parameters[P_LEVEL])); + sbs_strcat(&sbs, " n]"); } - bytes = (int)snprintf(bufp, size, " \"%s\"", spell_name(sp, lang)); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + spname = spell_name(sp, lang); + if (strchr(spname, ' ') != NULL) { + /* contains spaces, needs quotes */ + sbs_strcat(&sbs, " '"); + sbs_strcat(&sbs, spname); + sbs_strcat(&sbs, "'"); + } + else { + sbs_strcat(&sbs, " "); + sbs_strcat(&sbs, spname); + } while (params && *params) { typedef struct starget { @@ -298,52 +303,48 @@ void nr_spell_syntax(struct stream *out, spellbook_entry * sbe, const struct loc if (cp == 'u') { targetp = targets + 1; locp = LOC(lang, targetp->vars); - bytes = (int)snprintf(bufp, size, " <%s>", locp); + sbs_strcat(&sbs, " <"); + sbs_strcat(&sbs, locp); + sbs_strcat(&sbs, ">"); if (*params == '+') { ++params; - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = (int)snprintf(bufp, size, " [<%s> ...]", locp); + sbs_strcat(&sbs, " [<"); + sbs_strcat(&sbs, locp); + sbs_strcat(&sbs, "> ...]"); } - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); } else if (cp == 's') { targetp = targets + 2; locp = LOC(lang, targetp->vars); - bytes = (int)snprintf(bufp, size, " <%s>", locp); + sbs_strcat(&sbs, " <"); + sbs_strcat(&sbs, locp); + sbs_strcat(&sbs, ">"); if (*params == '+') { ++params; - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = (int)snprintf(bufp, size, " [<%s> ...]", locp); + sbs_strcat(&sbs, " [<"); + sbs_strcat(&sbs, locp); + sbs_strcat(&sbs, "> ...]"); } - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); } else if (cp == 'r') { - bytes = (int)str_strlcpy(bufp, " ", size); + sbs_strcat(&sbs, " "); if (*params == '+') { ++params; - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = (int)str_strlcpy(bufp, " [ ...]", size); + sbs_strcat(&sbs, " [ ...]"); } - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); } else if (cp == 'b') { targetp = targets + 3; locp = LOC(lang, targetp->vars); - bytes = (int)snprintf(bufp, size, " <%s>", locp); + sbs_strcat(&sbs, " <"); + sbs_strcat(&sbs, locp); + sbs_strcat(&sbs, ">"); if (*params == '+') { ++params; - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = (int)snprintf(bufp, size, " [<%s> ...]", locp); + sbs_strcat(&sbs, " [<"); + sbs_strcat(&sbs, locp); + sbs_strcat(&sbs, "> ...]"); } - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); } else if (cp == 'k') { int i, maxparam = 0; @@ -361,41 +362,35 @@ void nr_spell_syntax(struct stream *out, spellbook_entry * sbe, const struct loc ++maxparam; } if (!maxparam || maxparam > 1) { - bytes = (int)str_strlcpy(bufp, " (", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(&sbs, " ("); } i = 0; for (targetp = targets; targetp->flag; ++targetp) { if (!maxparam || sp->sptyp & targetp->flag) { if (i++ != 0) { - bytes = (int)str_strlcpy(bufp, " |", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(&sbs, " |"); } if (targetp->param && targetp->vars) { locp = LOC(lang, targetp->vars); - bytes = - (int)snprintf(bufp, size, " %s <%s>", parameters[targetp->param], - locp); + sbs_strcat(&sbs, " "); + sbs_strcat(&sbs, parameters[targetp->param]); + sbs_strcat(&sbs, " <"); + sbs_strcat(&sbs, locp); + sbs_strcat(&sbs, ">"); if (multi) { - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = (int)snprintf(bufp, size, " [<%s> ...]", locp); + sbs_strcat(&sbs, " [<"); + sbs_strcat(&sbs, locp); + sbs_strcat(&sbs, "> ...]"); } } else { - bytes = - (int)snprintf(bufp, size, " %s", parameters[targetp->param]); + sbs_strcat(&sbs, " "); + sbs_strcat(&sbs, parameters[targetp->param]); } - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); } } if (!maxparam || maxparam > 1) { - bytes = (int)str_strlcpy(bufp, " )", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(&sbs, " )"); } } else if (cp == 'i' || cp == 'c') { @@ -416,21 +411,20 @@ void nr_spell_syntax(struct stream *out, spellbook_entry * sbe, const struct loc } if (*params == '?') { ++params; - bytes = (int)snprintf(bufp, size, " [<%s>]", locp); + sbs_strcat(&sbs, " [<"); + sbs_strcat(&sbs, locp); + sbs_strcat(&sbs, ">]"); } else { - bytes = (int)snprintf(bufp, size, " <%s>", locp); + sbs_strcat(&sbs, " <"); + sbs_strcat(&sbs, locp); + sbs_strcat(&sbs, ">"); } - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); } else { log_error("unknown spell parameter %c for spell %s", cp, sp->sname); } } - *bufp = 0; - paragraph(out, buf, 2, 0, 0); - } void nr_spell(struct stream *out, spellbook_entry * sbe, const struct locale *lang) @@ -542,10 +536,8 @@ void nr_spell(struct stream *out, spellbook_entry * sbe, const struct locale *la paragraph(out, buf, 0, 0, 0); paragraph(out, LOC(lang, "nr_spell_syntax"), 0, 0, 0); - bufp = buf; - size = sizeof(buf) - 1; - - nr_spell_syntax(out, sbe, lang); + nr_spell_syntax(buf, sizeof(buf), sbe, lang); + paragraph(out, buf, 2, 0, 0); newline(out); } @@ -1825,72 +1817,61 @@ nr_ship(struct stream *out, const region *r, const ship * sh, const faction * f, static void nr_building(struct stream *out, const region *r, const building *b, const faction *f) { - int i, bytes; + int i; const char *name, *bname, *billusion = NULL; const struct locale *lang; - char buffer[8192], *bufp = buffer; + char buffer[8192]; message *msg; - size_t size = sizeof(buffer) - 1; + size_t size; + sbstring sbs; assert(f); lang = f->locale; newline(out); - bytes = - snprintf(bufp, size, "%s, %s %d, ", buildingname(b), LOC(lang, - "nr_size"), b->size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + sbs_init(&sbs, buffer, sizeof(buffer)); report_building(b, &bname, &billusion); + + size = str_slprintf(buffer, sizeof(buffer), "%s, %s %d, ", buildingname(b), + LOC(lang, "nr_size"), b->size); + sbs.end += size; name = LOC(lang, billusion ? billusion : bname); - bytes = (int)str_strlcpy(bufp, name, size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(&sbs, name); + if (billusion) { unit *owner = building_owner(b); if (owner && owner->faction == f) { /* illusion. report real type */ - name = LOC(lang, bname); - bytes = snprintf(bufp, size, " (%s)", name); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(&sbs, " ("); + sbs_strcat(&sbs, LOC(lang, bname)); + sbs_strcat(&sbs, ")"); } } if (!building_finished(b)) { - bytes = (int)str_strlcpy(bufp, " ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = (int)str_strlcpy(bufp, LOC(lang, "nr_building_inprogress"), size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(&sbs, " "); + sbs_strcat(&sbs, LOC(lang, "nr_building_inprogress")); } if (b->besieged > 0 && r->seen.mode >= seen_lighthouse) { msg = msg_message("nr_building_besieged", "soldiers diff", b->besieged, b->besieged - b->size * SIEGEFACTOR); - bytes = (int)nr_render(msg, lang, bufp, size, f); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + + size = nr_render(msg, lang, sbs.end, sbs.size - (sbs.end - sbs.begin), f); + sbs.end += size; + msg_release(msg); } i = 0; if (b->display && b->display[0]) { - bytes = (int)str_strlcpy(bufp, "; ", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); - bytes = (int)str_strlcpy(bufp, b->display, size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(&sbs, "; "); + sbs_strcat(&sbs, b->display); i = b->display[strlen(b->display) - 1]; } if (i != '!' && i != '?' && i != '.') { - bytes = (int)str_strlcpy(bufp, ".", size); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + sbs_strcat(&sbs, "."); } - *bufp = 0; paragraph(out, buffer, 2, 0, 0); if (r->seen.mode >= seen_lighthouse) { @@ -1900,14 +1881,10 @@ nr_building(struct stream *out, const region *r, const building *b, const factio static void nr_paragraph(struct stream *out, message * m, faction * f) { - int bytes; - char buf[4096], *bufp = buf; - size_t size = sizeof(buf) - 1; + char buf[4096]; assert(f); - bytes = (int)nr_render(m, f->locale, bufp, size, f); - if (wrptr(&bufp, &size, bytes) != 0) - WARN_STATIC_BUFFER(); + nr_render(m, f->locale, buf, sizeof(buf), f); msg_release(m); paragraph(out, buf, 0, 0, 0); @@ -2011,6 +1988,8 @@ void report_travelthru(struct stream *out, region *r, const faction *f) } } +#include "util/bsdstring.h" + int report_plaintext(const char *filename, report_context * ctx, const char *bom) diff --git a/src/report.h b/src/report.h index 45c620562..bb3629497 100644 --- a/src/report.h +++ b/src/report.h @@ -30,7 +30,7 @@ extern "C" { void report_travelthru(struct stream *out, struct region * r, const struct faction * f); void report_region(struct stream *out, const struct region * r, struct faction * f); - void nr_spell_syntax(struct stream *out, struct spellbook_entry * sbe, const struct locale *lang); + void nr_spell_syntax(char *buf, size_t size, struct spellbook_entry * sbe, const struct locale *lang); void nr_spell(struct stream *out, struct spellbook_entry * sbe, const struct locale *lang); #ifdef __cplusplus diff --git a/src/report.test.c b/src/report.test.c index 77bb6dca6..4fa97825c 100644 --- a/src/report.test.c +++ b/src/report.test.c @@ -228,32 +228,11 @@ static void set_parameter(spell_fixture spell, char *value) { } static void check_spell_syntax(CuTest *tc, char *msg, spell_fixture *spell, char *syntax) { - stream strm; char buf[1024]; - char *linestart, *newline; - size_t len; - mstream_init(&strm); - nr_spell_syntax(&strm, spell->sbe, spell->lang); - strm.api->rewind(strm.handle); - len = strm.api->read(strm.handle, buf, sizeof(buf)); - buf[len] = '\0'; + nr_spell_syntax(buf, sizeof(buf), spell->sbe, spell->lang); - linestart = strtok(buf, "\n"); - while (linestart && !strstr(linestart, "ZAUBERE")) - linestart = strtok(NULL, "\n"); - - CuAssertPtrNotNull(tc, linestart); - - newline = strtok(NULL, "\n"); - while (newline) { - *(newline - 1) = '\n'; - newline = strtok(NULL, "\n"); - } - - CuAssertStrEquals_Msg(tc, msg, syntax, linestart); - - mstream_done(&strm); + CuAssertStrEquals_Msg(tc, msg, syntax, buf); } static void test_write_spell_syntax(CuTest *tc) { @@ -262,54 +241,54 @@ static void test_write_spell_syntax(CuTest *tc) { test_setup(); setup_spell_fixture(&spell); - check_spell_syntax(tc, "vanilla", &spell, " ZAUBERE \"Testzauber\""); + check_spell_syntax(tc, "vanilla", &spell, "ZAUBERE Testzauber"); spell.sp->sptyp |= FARCASTING; - check_spell_syntax(tc, "far", &spell, " ZAUBERE [REGION x y] \"Testzauber\""); + check_spell_syntax(tc, "far", &spell, "ZAUBERE [REGION x y] Testzauber"); spell.sp->sptyp |= SPELLLEVEL; - check_spell_syntax(tc, "farlevel", &spell, " ZAUBERE [REGION x y] [STUFE n] \"Testzauber\""); + check_spell_syntax(tc, "farlevel", &spell, "ZAUBERE [REGION x y] [STUFE n] Testzauber"); spell.sp->sptyp = 0; set_parameter(spell, "kc"); - check_spell_syntax(tc, "kc", &spell, " ZAUBERE \"Testzauber\" ( REGION | EINHEIT | SCHIFF | BURG )"); + check_spell_syntax(tc, "kc", &spell, "ZAUBERE Testzauber ( REGION | EINHEIT | SCHIFF | BURG )"); spell.sp->sptyp |= BUILDINGSPELL; - check_spell_syntax(tc, "kc typed", &spell, " ZAUBERE \"Testzauber\" BURG "); + check_spell_syntax(tc, "kc typed", &spell, "ZAUBERE Testzauber BURG "); spell.sp->sptyp = 0; set_parameter(spell, "b"); - check_spell_syntax(tc, "b", &spell, " ZAUBERE \"Testzauber\" "); + check_spell_syntax(tc, "b", &spell, "ZAUBERE Testzauber "); set_parameter(spell, "s"); - check_spell_syntax(tc, "s", &spell, " ZAUBERE \"Testzauber\" "); + check_spell_syntax(tc, "s", &spell, "ZAUBERE Testzauber "); set_parameter(spell, "s+"); - check_spell_syntax(tc, "s+", &spell, " ZAUBERE \"Testzauber\" [ ...]"); + check_spell_syntax(tc, "s+", &spell, "ZAUBERE Testzauber [ ...]"); set_parameter(spell, "u"); - check_spell_syntax(tc, "u", &spell, " ZAUBERE \"Testzauber\" "); + check_spell_syntax(tc, "u", &spell, "ZAUBERE Testzauber "); set_parameter(spell, "r"); - check_spell_syntax(tc, "r", &spell, " ZAUBERE \"Testzauber\" "); + check_spell_syntax(tc, "r", &spell, "ZAUBERE Testzauber "); set_parameter(spell, "bc"); free(spell.sp->syntax); spell.sp->syntax = str_strdup("hodor"); - check_spell_syntax(tc, "bc hodor", &spell, " ZAUBERE \"Testzauber\" "); + check_spell_syntax(tc, "bc hodor", &spell, "ZAUBERE Testzauber "); free(spell.sp->syntax); spell.sp->syntax = 0; set_parameter(spell, "c?"); free(spell.sp->syntax); spell.sp->syntax = str_strdup("hodor"); - check_spell_syntax(tc, "c?", &spell, " ZAUBERE \"Testzauber\" []"); + check_spell_syntax(tc, "c?", &spell, "ZAUBERE Testzauber []"); free(spell.sp->syntax); spell.sp->syntax = 0; set_parameter(spell, "kc+"); check_spell_syntax(tc, "kc+", &spell, - " ZAUBERE \"Testzauber\" ( REGION | EINHEIT [ ...] | SCHIFF \n [ ...] | BURG [ ...] )"); + "ZAUBERE Testzauber ( REGION | EINHEIT [ ...] | SCHIFF [ ...] | BURG [ ...] )"); cleanup_spell_fixture(&spell); test_teardown(); diff --git a/src/reports.c b/src/reports.c index 06f6b0084..d240ee86d 100644 --- a/src/reports.c +++ b/src/reports.c @@ -2179,10 +2179,10 @@ void report_battle_start(battle * b) for (df = s->fighters; df; df = df->next) { if (is_attacker(df)) { if (first) { - sbs_strcpy(&sbs, ", "); + sbs_strcat(&sbs, ", "); } if (lastf) { - sbs_strcpy(&sbs, lastf); + sbs_strcat(&sbs, lastf); first = true; } if (seematrix(f, s)) @@ -2193,12 +2193,10 @@ void report_battle_start(battle * b) } } } - if (first) { + if (first && lastf) { sbs_strcat(&sbs, " "); sbs_strcat(&sbs, LOC(f->locale, "and")); sbs_strcat(&sbs, " "); - } - if (lastf) { sbs_strcat(&sbs, lastf); } diff --git a/storage b/storage index 5623ee652..6eea76952 160000 --- a/storage +++ b/storage @@ -1 +1 @@ -Subproject commit 5623ee6527e97af20c7d8efc03800b6fe1579744 +Subproject commit 6eea7695285f9c9f1d25421897ca55f466ef7566