From cf7971bcfc68a1cb7823d7c48bda25f9273af46e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 25 Aug 2019 17:43:18 +0200 Subject: [PATCH 1/5] Tests for GIVE UNIT and groups. --- scripts/tests/common.lua | 29 +++++++++++++++++++++++++++++ src/kernel/group.c | 13 +++++++++---- src/kernel/group.h | 2 +- src/kernel/group.test.c | 6 ++++-- src/kernel/unit.c | 2 +- 5 files changed, 44 insertions(+), 8 deletions(-) diff --git a/scripts/tests/common.lua b/scripts/tests/common.lua index 70e1b61e4..41f551772 100644 --- a/scripts/tests/common.lua +++ b/scripts/tests/common.lua @@ -37,6 +37,35 @@ function setup() eressea.settings.set("study.random_progress", "0") end +function test_give_unit() + local r = region.create(0, 0, "plain") + local f1 = create_faction('elf') + local f2 = create_faction('elf') + local u1, u2 = two_units(r, f1, f2) + assert_equal(f1, u1.faction) + assert_equal(f2, u2.faction) + u2.name = 'Xolgrim' + u2.group = 'Experten' + assert_equal('Experten', u2.group) + u1:add_order("HELFE " .. itoa36(f2.id) .. " GIB") + u2:add_order("GIB " .. itoa36(u1.id) .. " EINHEIT") + process_orders() + assert_equal(f1, u2.faction) + assert_nil(u2.group) +end + +function test_set_faction() + local r = region.create(0, 0, "plain") + local f1 = create_faction('elf') + local f2 = create_faction('elf') + local u = one_unit(r, f1) + u.group = 'Experten' + assert_equal('Experten', u.group) + u.faction = f2 + assert_equal(f2, u.faction) + assert_nil(u.group) +end + function test_locales() assert_equal(2, eressea.locale.direction("de", "Ost")) assert_equal(5, eressea.locale.direction("de", "westen")) diff --git a/src/kernel/group.c b/src/kernel/group.c index 482eb26f8..1515f8ea1 100755 --- a/src/kernel/group.c +++ b/src/kernel/group.c @@ -49,7 +49,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. static group *ghash[GMAXHASH]; static int maxgid; -group *new_group(faction * f, const char *name, int gid) +group *create_group(faction * f, const char *name, int gid) { group **gp = &f->groups; int index = gid % GMAXHASH; @@ -63,6 +63,7 @@ group *new_group(faction * f, const char *name, int gid) if (gid > maxgid) maxgid = gid; g->name = str_strdup(name); g->gid = gid; + g->f = f; g->nexthash = ghash[index]; return ghash[index] = g; @@ -93,11 +94,15 @@ static int read_group(variant *var, void *owner, gamedata *data) { struct storage *store = data->store; group *g; + unit * u = (unit *)owner; int gid; READ_INT(store, &gid); var->v = g = find_group(gid); - if (g != 0) { + if (g != NULL) { + if (g->f != u->faction) { + return AT_READ_FAIL; + } g->members++; return AT_READ_OK; } @@ -184,7 +189,7 @@ group *join_group(unit * u, const char *name) if (name && name[0]) { g = find_groupbyname(u->faction->groups, name); if (g == NULL) { - g = new_group(u->faction, name, ++maxgid); + g = create_group(u->faction, name, ++maxgid); init_group(u->faction, g); } } @@ -219,7 +224,7 @@ void read_groups(gamedata *data, faction * f) if (gid == 0) break; READ_STR(store, buf, sizeof(buf)); - g = new_group(f, buf, gid); + g = create_group(f, buf, gid); read_allies(data, &g->allies); read_attribs(data, &g->attribs, g); } diff --git a/src/kernel/group.h b/src/kernel/group.h index 9b6d97cf9..8bb764603 100755 --- a/src/kernel/group.h +++ b/src/kernel/group.h @@ -40,7 +40,7 @@ extern "C" { extern void set_group(struct unit *u, struct group *g); extern struct group * get_group(const struct unit *u); extern void free_group(struct group *g); - struct group *new_group(struct faction * f, const char *name, int gid); + struct group *create_group(struct faction * f, const char *name, int gid); extern void write_groups(struct gamedata *data, const struct faction *f); extern void read_groups(struct gamedata *data, struct faction *f); diff --git a/src/kernel/group.test.c b/src/kernel/group.test.c index 7d14380d6..8c3bcb16e 100644 --- a/src/kernel/group.test.c +++ b/src/kernel/group.test.c @@ -80,8 +80,10 @@ static void test_group_readwrite(CuTest * tc) mstream_init(&data.strm); gamedata_init(&data, &store, RELEASE_VERSION); f = test_create_faction(NULL); - new_group(f, "NW", 42); - g = new_group(f, "Egoisten", 43); + create_group(f, "NW", 42); + g = create_group(f, "Egoisten", 43); + CuAssertPtrEquals(tc, f, g->f); + CuAssertStrEquals(tc, "Egoisten", g->name); key_set(&g->attribs, 44, 44); ally_set(&g->allies, f, HELP_GIVE); write_groups(&data, f); diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 2a9a3b5da..e92ea4ca0 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -923,7 +923,7 @@ void u_setfaction(unit * u, faction * f) --u->faction->num_units; u->faction->num_people -= u->number; } - join_group(u, NULL); + set_group(u, NULL); free_orders(&u->orders); set_order(&u->thisorder, NULL); From 827532dd4976fd855babb549c57eb34ecaf72f4e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 25 Aug 2019 17:55:04 +0200 Subject: [PATCH 2/5] extract read_regions from read_game. --- src/kernel/save.c | 111 +++++++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 51 deletions(-) diff --git a/src/kernel/save.c b/src/kernel/save.c index 9b4a30236..9b6513d2e 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1473,61 +1473,14 @@ static void fix_familiars(void (*callback)(unit *)) { } } -int read_game(gamedata *data) -{ - int p, nread; - faction *f, **fp; - region *r; - unit *u; +void read_regions(gamedata *data) { storage * store = data->store; const struct building_type *bt_lighthouse = bt_find("lighthouse"); const struct race *rc_spell = rc_find("spell"); - - if (data->version >= SAVEGAMEID_VERSION) { - int gameid; - - READ_INT(store, &gameid); - if (gameid != game_id()) { - log_warning("game mismatch: datafile contains game %d, but config is for %d", gameid, game_id()); - } - } - else { - READ_STR(store, NULL, 0); - } - - if (data->version < FIXATKEYS_VERSION) { - attrib *a = NULL; - read_attribs(data, &a, NULL); - a_removeall(&a, NULL); - } - - READ_INT(store, &turn); - log_debug(" - reading turn %d", turn); - rng_init(turn + config_get_int("game.seed", 0)); - READ_INT(store, NULL); /* max_unique_id = ignore */ - READ_INT(store, &nextborder); - - read_planes(data); - read_alliances(data); - READ_INT(store, &nread); - log_debug(" - Einzulesende Parteien: %d\n", nread); - fp = &factions; - while (*fp) { - fp = &(*fp)->next; - } - - while (--nread >= 0) { - faction *f = read_faction(data); - - *fp = f; - fp = &f->next; - } - *fp = 0; - - /* Regionen */ + int nread; READ_INT(store, &nread); - assert(nread < MAXREGIONS && nread >=0); + assert(nread < MAXREGIONS && nread >= 0); log_debug(" - Einzulesende Regionen: %d", nread); @@ -1535,13 +1488,15 @@ int read_game(gamedata *data) unit **up; building **bp; ship **shp; + region *r; + int p; r = read_region(data); /* Burgen */ READ_INT(store, &p); if (p > 0 && !r->land) { - log_debug("%s, uid=%d has %d %s", regionname(r, NULL), r->uid, p, (p==1) ? "building" : "buildings"); + log_debug("%s, uid=%d has %d %s", regionname(r, NULL), r->uid, p, (p == 1) ? "building" : "buildings"); } bp = &r->buildings; @@ -1595,6 +1550,60 @@ int read_game(gamedata *data) } } } +} + +int read_game(gamedata *data) +{ + storage * store = data->store; + int nread; + faction *f, **fp; + region *r; + unit *u; + + if (data->version >= SAVEGAMEID_VERSION) { + int gameid; + + READ_INT(store, &gameid); + if (gameid != game_id()) { + log_warning("game mismatch: datafile contains game %d, but config is for %d", gameid, game_id()); + } + } + else { + READ_STR(store, NULL, 0); + } + + if (data->version < FIXATKEYS_VERSION) { + attrib *a = NULL; + read_attribs(data, &a, NULL); + a_removeall(&a, NULL); + } + + READ_INT(store, &turn); + log_debug(" - reading turn %d", turn); + rng_init(turn + config_get_int("game.seed", 0)); + READ_INT(store, NULL); /* max_unique_id = ignore */ + READ_INT(store, &nextborder); + + read_planes(data); + read_alliances(data); + READ_INT(store, &nread); + log_debug(" - Einzulesende Parteien: %d\n", nread); + fp = &factions; + while (*fp) { + fp = &(*fp)->next; + } + + while (--nread >= 0) { + faction *f = read_faction(data); + + *fp = f; + fp = &f->next; + } + *fp = 0; + + /* Regionen */ + + read_regions(data); read_borders(data); log_debug("updating area information for lighthouses."); From 8bed3f3329a5363b2d45194753e0466256c16935 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 25 Aug 2019 18:11:14 +0200 Subject: [PATCH 3/5] fix give_unit test for E3 extract read_factions from read_game, now small and nice. --- scripts/tests/common.lua | 17 ---- scripts/tests/e2/e2features.lua | 17 ++++ scripts/tests/e3/rules.lua | 14 +++ src/kernel/save.c | 158 +++++++++++++++++--------------- 4 files changed, 115 insertions(+), 91 deletions(-) diff --git a/scripts/tests/common.lua b/scripts/tests/common.lua index 41f551772..a2008a69c 100644 --- a/scripts/tests/common.lua +++ b/scripts/tests/common.lua @@ -37,23 +37,6 @@ function setup() eressea.settings.set("study.random_progress", "0") end -function test_give_unit() - local r = region.create(0, 0, "plain") - local f1 = create_faction('elf') - local f2 = create_faction('elf') - local u1, u2 = two_units(r, f1, f2) - assert_equal(f1, u1.faction) - assert_equal(f2, u2.faction) - u2.name = 'Xolgrim' - u2.group = 'Experten' - assert_equal('Experten', u2.group) - u1:add_order("HELFE " .. itoa36(f2.id) .. " GIB") - u2:add_order("GIB " .. itoa36(u1.id) .. " EINHEIT") - process_orders() - assert_equal(f1, u2.faction) - assert_nil(u2.group) -end - function test_set_faction() local r = region.create(0, 0, "plain") local f1 = create_faction('elf') diff --git a/scripts/tests/e2/e2features.lua b/scripts/tests/e2/e2features.lua index acd2f1e03..b0233c3fb 100644 --- a/scripts/tests/e2/e2features.lua +++ b/scripts/tests/e2/e2features.lua @@ -12,6 +12,23 @@ function setup() eressea.settings.set("rules.peasants.growth.factor", "0") end +function test_give_unit() + local r = region.create(0, 0, "plain") + local f1 = faction.create('elf') + local f2 = faction.create('elf') + local u1 = unit.create(f1, r) + local u2 = unit.create(f2, r) + assert_equal(f1, u1.faction) + assert_equal(f2, u2.faction) + u2.group = 'Experten' + assert_equal('Experten', u2.group) + u1:add_order("HELFE " .. itoa36(f2.id) .. " GIB") + u2:add_order("GIB " .. itoa36(u1.id) .. " EINHEIT") + process_orders() + assert_equal(f1, u2.faction) + assert_nil(u2.group) +end + function test_study_auto() local r = region.create(0, 0, "plain") local f = faction.create("human") diff --git a/scripts/tests/e3/rules.lua b/scripts/tests/e3/rules.lua index b262f99a6..aae3b3ab1 100644 --- a/scripts/tests/e3/rules.lua +++ b/scripts/tests/e3/rules.lua @@ -36,6 +36,20 @@ function teardown() end end +function test_new_faction_cannot_give_unit() + local r = region.create(0, 0, "plain") + local f1 = faction.create('elf') + local f2 = faction.create('elf') + local u1 = unit.create(f1, r) + local u2 = unit.create(f2, r) + assert_equal(f1, u1.faction) + assert_equal(f2, u2.faction) + u1:add_order("HELFE " .. itoa36(f2.id) .. " GIB") + u2:add_order("GIB " .. itoa36(u1.id) .. " EINHEIT") + process_orders() + assert_equal(f2, u2.faction) +end + function test_calendar() assert_equal("winter", get_season(396)) end diff --git a/src/kernel/save.c b/src/kernel/save.c index 9b6513d2e..a39bde161 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1,3 +1,4 @@ +#include "save.h" /* Copyright (c) 1998-2019, Enno Rehling Katja Zedel store; const struct building_type *bt_lighthouse = bt_find("lighthouse"); const struct race *rc_spell = rc_find("spell"); + region *r; int nread; READ_INT(store, &nread); @@ -1488,7 +1490,6 @@ void read_regions(gamedata *data) { unit **up; building **bp; ship **shp; - region *r; int p; r = read_region(data); @@ -1550,15 +1551,90 @@ void read_regions(gamedata *data) { } } } + + log_debug("updating area information for lighthouses."); + for (r = regions; r; r = r->next) { + if (r->flags & RF_LIGHTHOUSE) { + building *b; + for (b = r->buildings; b; b = b->next) { + if (is_lighthouse(b->type)) { + update_lighthouse(b); + } + } + } + } +} + +static void init_factions(int data_version) +{ + log_debug("marking factions as alive."); + for (faction *f = factions; f; f = f->next) { + if (f->flags & FFL_NPC) { + f->_alive = true; + f->magiegebiet = M_GRAY; + if (f->no == 0) { + int no = 666; + while (findfaction(no)) + ++no; + log_warning("renum(monsters, %d)", no); + renumber_faction(f, no); + } + } + else { + assert(f->units); + for (unit *u = f->units; u; u = u->nextF) { + if (data_version < SPELL_LEVEL_VERSION) { + struct sc_mage *mage = get_mage(u); + if (mage) { + faction *f = u->faction; + int skl = effskill(u, SK_MAGIC, NULL); + if (f->magiegebiet == M_GRAY) { + f->magiegebiet = mage_get_type(mage); + log_error("faction %s had magic=gray, fixing (%s)", + factionname(f), magic_school[f->magiegebiet]); + } + if (f->max_spelllevel < skl) { + f->max_spelllevel = skl; + } + } + } + if (u->number > 0) { + f->_alive = true; + if (data_version >= SPELL_LEVEL_VERSION) { + break; + } + } + } + if (data_version < SPELL_LEVEL_VERSION && f->spellbook) { + spellbook_foreach(f->spellbook, cb_sb_maxlevel, f); + } + } + } +} + +static void read_factions(gamedata * data) +{ + storage * store = data->store; + int nread; + faction **fp; + READ_INT(store, &nread); + log_debug(" - Einzulesende Parteien: %d\n", nread); + fp = &factions; + while (*fp) { + fp = &(*fp)->next; + } + + while (--nread >= 0) { + faction *f = read_faction(data); + + *fp = f; + fp = &f->next; + } } int read_game(gamedata *data) { storage * store = data->store; - int nread; - faction *f, **fp; - region *r; - unit *u; if (data->version >= SAVEGAMEID_VERSION) { int gameid; @@ -1586,80 +1662,14 @@ int read_game(gamedata *data) read_planes(data); read_alliances(data); - READ_INT(store, &nread); - log_debug(" - Einzulesende Parteien: %d\n", nread); - fp = &factions; - while (*fp) { - fp = &(*fp)->next; - } - while (--nread >= 0) { - faction *f = read_faction(data); - - *fp = f; - fp = &f->next; - } - *fp = 0; + read_factions(data); /* Regionen */ read_regions(data); read_borders(data); - - log_debug("updating area information for lighthouses."); - for (r = regions; r; r = r->next) { - if (r->flags & RF_LIGHTHOUSE) { - building *b; - for (b = r->buildings; b; b = b->next) { - if (is_lighthouse(b->type)) { - update_lighthouse(b); - } - } - } - } - log_debug("marking factions as alive."); - for (f = factions; f; f = f->next) { - if (f->flags & FFL_NPC) { - f->_alive = true; - f->magiegebiet = M_GRAY; - if (f->no == 0) { - int no = 666; - while (findfaction(no)) - ++no; - log_warning("renum(monsters, %d)", no); - renumber_faction(f, no); - } - } - else { - assert(f->units); - for (u = f->units; u; u = u->nextF) { - if (data->version < SPELL_LEVEL_VERSION) { - struct sc_mage *mage = get_mage(u); - if (mage) { - faction *f = u->faction; - int skl = effskill(u, SK_MAGIC, NULL); - if (f->magiegebiet == M_GRAY) { - f->magiegebiet = mage_get_type(mage); - log_error("faction %s had magic=gray, fixing (%s)", - factionname(f), magic_school[f->magiegebiet]); - } - if (f->max_spelllevel < skl) { - f->max_spelllevel = skl; - } - } - } - if (u->number > 0) { - f->_alive = true; - if (data->version >= SPELL_LEVEL_VERSION) { - break; - } - } - } - if (data->version < SPELL_LEVEL_VERSION && f->spellbook) { - spellbook_foreach(f->spellbook, cb_sb_maxlevel, f); - } - } - } + init_factions(data->version); if (data->version < FIX_CLONES_VERSION) { fix_clones(); } From eb95613996d5605716ab5158371d6d0baa920a52 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 25 Aug 2019 18:14:03 +0200 Subject: [PATCH 4/5] fix gcc issues with new season_t type. --- src/jsonconf.c | 2 +- src/jsonconf.test.c | 4 ++-- src/kernel/calendar.h | 2 +- src/kernel/calendar.test.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/jsonconf.c b/src/jsonconf.c index 06ea2c786..fdcae9f25 100644 --- a/src/jsonconf.c +++ b/src/jsonconf.c @@ -792,7 +792,7 @@ static void json_calendar(cJSON *json) { for (i = 0, jmonth = child->child; jmonth; jmonth = jmonth->next, ++i) { if (jmonth->type == cJSON_Object) { storms[i] = cJSON_GetObjectItem(jmonth, "storm")->valueint; - month_season[i] = cJSON_GetObjectItem(jmonth, "season")->valueint; + month_season[i] = (season_t) cJSON_GetObjectItem(jmonth, "season")->valueint; } else { log_error("calendar.months[%d] is not an object: %d", i, json->type); diff --git a/src/jsonconf.test.c b/src/jsonconf.test.c index 1fc27d3e6..491668506 100644 --- a/src/jsonconf.test.c +++ b/src/jsonconf.test.c @@ -160,8 +160,8 @@ static void test_calendar(CuTest * tc) CuAssertIntEquals(tc, 99, storms[0]); CuAssertIntEquals(tc, 22, storms[1]); CuAssertPtrNotNull(tc, month_season); - CuAssertIntEquals(tc, 1, month_season[0]); - CuAssertIntEquals(tc, 2, month_season[1]); + CuAssertIntEquals(tc, SEASON_SPRING, month_season[0]); + CuAssertIntEquals(tc, SEASON_SUMMER, month_season[1]); cJSON_Delete(json); test_teardown(); } diff --git a/src/kernel/calendar.h b/src/kernel/calendar.h index d1a82f037..e0b7eb873 100644 --- a/src/kernel/calendar.h +++ b/src/kernel/calendar.h @@ -15,7 +15,7 @@ extern "C" { extern const char *seasonnames[CALENDAR_SEASONS]; extern int months_per_year; - extern int *month_season; + extern season_t *month_season; extern int first_month; extern int turn; diff --git a/src/kernel/calendar.test.c b/src/kernel/calendar.test.c index 1a951efb3..75806e8e6 100644 --- a/src/kernel/calendar.test.c +++ b/src/kernel/calendar.test.c @@ -71,7 +71,7 @@ static void setup_calendar() { months_per_year = 4; weeks_per_month = 2; free(month_season); - month_season = calloc(months_per_year, sizeof(int)); + month_season = calloc(months_per_year, sizeof(season_t)); for (i = 0; i != 4; ++i) { month_season[i] = (season_t)i; } From fc29b492a2b0d0ce0e2ac10fdcb18b6fb6a1fb98 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 25 Aug 2019 19:34:04 +0200 Subject: [PATCH 5/5] last gcc thing, I hope. --- src/kernel/calendar.test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel/calendar.test.c b/src/kernel/calendar.test.c index 75806e8e6..a251fd45b 100644 --- a/src/kernel/calendar.test.c +++ b/src/kernel/calendar.test.c @@ -65,7 +65,7 @@ static void test_calendar(CuTest * tc) test_teardown(); } -static void setup_calendar() { +static void setup_calendar(void) { int i; months_per_year = 4;