fix that catastrophic merge, make struct ally module-private

This commit is contained in:
Enno Rehling 2018-10-26 21:49:58 +02:00
parent 56ccb18fb1
commit d7a8a9b406
15 changed files with 180 additions and 200 deletions

View File

@ -1437,7 +1437,7 @@ msgstr "Goblins"
msgctxt "spellinfo" msgctxt "spellinfo"
msgid "song_of_slavery" msgid "song_of_slavery"
msgstr "Dieser mächtige Bann raubt dem Opfer seinen freien Willen und unterwirft sie den Befehlen des Barden. Für einige Zeit wird das Opfer sich völlig von seinen eigenen Leuten abwenden und der Partei des Barden zugehörig fühlen." msgstr "Dieser mächtige Bann raubt dem Opfer seinen freien Willen und unterwirft es den Befehlen des Barden. Für einige Zeit wird das Opfer sich völlig von seinen eigenen Leuten abwenden und der Partei des Barden zugehörig fühlen."
msgctxt "spell" msgctxt "spell"
msgid "healingzone" msgid "healingzone"

View File

@ -309,49 +309,6 @@ static int tolua_faction_count_msg_type(lua_State *L) {
return 1; return 1;
} }
static int tolua_faction_get_policy(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *other = (faction *)tolua_tousertype(L, 2, 0);
const char *policy = tolua_tostring(L, 3, 0);
int result = 0, mode;
for (mode = 0; helpmodes[mode].name != NULL; ++mode) {
if (strcmp(policy, helpmodes[mode].name) == 0) {
result = get_alliance(self, other) & mode;
break;
}
}
lua_pushinteger(L, result);
return 1;
}
static int tolua_faction_set_policy(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
faction *other = (faction *)tolua_tousertype(L, 2, 0);
const char *policy = tolua_tostring(L, 3, 0);
int value = tolua_toboolean(L, 4, 0);
int mode;
for (mode = 0; helpmodes[mode].name != NULL; ++mode) {
if (strcmp(policy, helpmodes[mode].name) == 0) {
if (value) {
set_alliance(self, other, get_alliance(self,
other) | helpmodes[mode].status);
}
else {
set_alliance(self, other, get_alliance(self,
other) & ~helpmodes[mode].status);
}
break;
}
}
return 0;
}
static int tolua_faction_normalize(lua_State * L) static int tolua_faction_normalize(lua_State * L)
{ {
faction *f = (faction *)tolua_tousertype(L, 1, 0); faction *f = (faction *)tolua_tousertype(L, 1, 0);
@ -632,8 +589,6 @@ void tolua_faction_open(lua_State * L)
tolua_variable(L, TOLUA_CAST "lastturn", tolua_faction_get_lastturn, tolua_variable(L, TOLUA_CAST "lastturn", tolua_faction_get_lastturn,
tolua_faction_set_lastturn); tolua_faction_set_lastturn);
tolua_function(L, TOLUA_CAST "set_policy", tolua_faction_set_policy);
tolua_function(L, TOLUA_CAST "get_policy", tolua_faction_get_policy);
tolua_function(L, TOLUA_CAST "get_origin", tolua_faction_get_origin); tolua_function(L, TOLUA_CAST "get_origin", tolua_faction_get_origin);
tolua_function(L, TOLUA_CAST "set_origin", tolua_faction_set_origin); tolua_function(L, TOLUA_CAST "set_origin", tolua_faction_set_origin);
tolua_function(L, TOLUA_CAST "normalize", tolua_faction_normalize); tolua_function(L, TOLUA_CAST "normalize", tolua_faction_normalize);

View File

@ -25,7 +25,29 @@ typedef struct ally {
int status; int status;
} ally; } ally;
int allies_walk(struct ally *allies, cb_allies_walk callback, void *udata) void allies_free(ally *al)
{
while (al) {
ally * an = al->next;
free(al);
al = an;
}
}
ally *allies_clone(const ally *al) {
ally *al_clone = NULL, **al_end = &al_clone;
for (; al; al = al->next) {
if (al->faction) {
ally * al_new = ally_add(al_end, al->faction);
al_new->status = al->status;
al_end = &al_new->next;
}
}
return al_clone;
}
int allies_walk(ally *allies, cb_allies_walk callback, void *udata)
{ {
ally *al; ally *al;
for (al = allies; al; al = al->next) { for (al = allies; al; al = al->next) {
@ -37,6 +59,18 @@ int allies_walk(struct ally *allies, cb_allies_walk callback, void *udata)
return 0; return 0;
} }
void write_allies(gamedata * data, const ally *alist)
{
const ally *a;
for (a = alist; a; a = a->next) {
if (a->faction && a->faction->_alive) {
write_faction_reference(a->faction, data->store);
WRITE_INT(data->store, a->status);
}
}
write_faction_reference(NULL, data->store);
}
void read_allies(gamedata * data, ally **sfp) void read_allies(gamedata * data, ally **sfp)
{ {
for (;;) { for (;;) {
@ -196,8 +230,7 @@ static int AllianceRestricted(void)
return rule; return rule;
} }
int alliance_status(const faction *f, const faction *f2, int status) {
int alliance_status(faction *f, faction *f2, int status) {
status |= autoalliance(f, f2); status |= autoalliance(f, f2);
if (status > 0) { if (status > 0) {
int mask = AllianceRestricted(); int mask = AllianceRestricted();
@ -226,7 +259,7 @@ alliedgroup(const struct faction *f,
if (!(faction_alive(f) && faction_alive(f2))) { if (!(faction_alive(f) && faction_alive(f2))) {
return 0; return 0;
} }
status = ally_get(all, f2); status = ally_get(all, f2) & mask;
return alliance_status(f, f2, status); return alliance_status(f, f2, status);
} }
@ -237,19 +270,19 @@ alliedfaction(const struct faction *f, const struct faction *f2, int mask)
} }
/* Die Gruppe von Einheit u hat helfe zu f2 gesetzt. */ /* Die Gruppe von Einheit u hat helfe zu f2 gesetzt. */
int alliedunit(const unit * u, const faction * f2, int mode) int alliedunit(const unit * u, const faction * f2, int mask)
{ {
assert(u); assert(u);
assert(f2); assert(f2);
assert(u->region); /* the unit should be in a region, but it's possible that u->number==0 (TEMP units) */ assert(u->region); /* the unit should be in a region, but it's possible that u->number==0 (TEMP units) */
if (u->faction == f2) { if (u->faction == f2) {
return mode; return mask;
} }
if (!faction_alive(f2)) { if (!faction_alive(f2)) {
return 0; return 0;
} }
if (u->faction != NULL && f2 != NULL) { if (u->faction != NULL && f2 != NULL) {
if (mode & HELP_FIGHT) { if (mask & HELP_FIGHT) {
if ((u->flags & UFL_DEFENDER) || (u->faction->flags & FFL_DEFENDER)) { if ((u->flags & UFL_DEFENDER) || (u->faction->flags & FFL_DEFENDER)) {
faction *owner = region_get_owner(u->region); faction *owner = region_get_owner(u->region);
/* helps the owner of the region */ /* helps the owner of the region */
@ -263,10 +296,10 @@ int alliedunit(const unit * u, const faction * f2, int mode)
const attrib *a = a_find(u->attribs, &at_group); const attrib *a = a_find(u->attribs, &at_group);
if (a != NULL) { if (a != NULL) {
group *g = (group *)a->data.v; group *g = (group *)a->data.v;
return alliedgroup(u->faction, f2, g, mode); return alliedgroup(u->faction, f2, g, mask);
} }
} }
return alliedfaction(u->faction, f2, mode); return alliedfaction(u->faction, f2, mask);
} }
return 0; return 0;
} }

View File

@ -33,23 +33,27 @@ extern "C" {
extern struct attrib_type at_npcfaction; extern struct attrib_type at_npcfaction;
void read_allies(struct gamedata * data, struct ally **alist); void read_allies(struct gamedata * data, struct ally **alist);
void write_allies(struct gamedata * data, const struct ally *alist);
typedef int (*cb_allies_walk)(struct ally *, struct faction *, int, void *); typedef int (*cb_allies_walk)(struct ally *, struct faction *, int, void *);
int allies_walk(struct ally *allies, cb_allies_walk callback, void *udata); int allies_walk(struct ally *allies, cb_allies_walk callback, void *udata);
struct ally *allies_clone(const struct ally *al);
void allies_free(struct ally *al);
struct ally* ally_find(struct ally*al, const struct faction *f); struct ally* ally_find(struct ally*al, const struct faction *f);
void ally_set(struct ally**al_p, struct faction *f, int status); void ally_set(struct ally**al_p, struct faction *f, int status);
int ally_get(struct ally *al, struct faction *f); int ally_get(struct ally *al, const struct faction *f);
struct ally* ally_add(struct ally**al_p, struct faction *f); struct ally* ally_add(struct ally**al_p, struct faction *f);
int AllianceAuto(void); /* flags that allied factions get automatically */ int AllianceAuto(void); /* flags that allied factions get automatically */
int HelpMask(void); /* flags restricted to allied factions */ int HelpMask(void); /* flags restricted to allied factions */
int alliedunit(const struct unit *u, const struct faction *f2, int alliedunit(const struct unit *u, const struct faction *f2,
int mode); int mask);
int alliedfaction(const struct faction *f, const struct faction *f2, int alliedfaction(const struct faction *f, const struct faction *f2,
int mode); int mask);
int alliedgroup(const struct faction *f, const struct faction *f2, int alliedgroup(const struct faction *f, const struct faction *f2,
const struct group *g, int mode); const struct group *g, int mask);
int alliance_status(const struct faction *f, const struct faction *f2, int mode); int alliance_status(const struct faction *f, const struct faction *f2, int status);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -7,22 +7,47 @@
static void test_ally(CuTest * tc) static void test_ally(CuTest * tc)
{ {
ally * al = NULL; struct ally * al = NULL;
struct faction * f1 = test_create_faction(NULL); struct faction * f;
ally_set(&al, f1, HELP_GUARD); test_setup();
f = test_create_faction(NULL);
ally_set(&al, f, HELP_GUARD);
CuAssertPtrNotNull(tc, al); CuAssertPtrNotNull(tc, al);
CuAssertIntEquals(tc, HELP_GUARD, ally_get(al, f1)); CuAssertIntEquals(tc, HELP_GUARD, ally_get(al, f));
ally_set(&al, f1, 0); ally_set(&al, f, 0);
CuAssertPtrEquals(tc, NULL, al); CuAssertPtrEquals(tc, NULL, al);
CuAssertIntEquals(tc, 0, ally_get(al, f1)); CuAssertIntEquals(tc, 0, ally_get(al, f));
allies_free(al);
test_teardown();
}
static void test_allies_clone(CuTest * tc)
{
struct ally * al = NULL, *ac;
struct faction * f;
test_setup();
f = test_create_faction(NULL);
CuAssertPtrEquals(tc, NULL, allies_clone(NULL));
ally_set(&al, f, HELP_GUARD);
ac = allies_clone(al);
CuAssertPtrNotNull(tc, ac);
CuAssertTrue(tc, al != ac);
CuAssertIntEquals(tc, HELP_GUARD, ally_get(ac, f));
CuAssertIntEquals(tc, HELP_GUARD, ally_get(al, f));
allies_free(al);
allies_free(ac);
test_teardown();
} }
CuSuite *get_ally_suite(void) CuSuite *get_ally_suite(void)
{ {
CuSuite *suite = CuSuiteNew(); CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_ally); SUITE_ADD_TEST(suite, test_ally);
SUITE_ADD_TEST(suite, test_allies_clone);
return suite; return suite;
} }

View File

@ -518,24 +518,6 @@ void destroyfaction(faction ** fp)
} }
} }
int get_alliance(const faction * a, const faction * b)
{
const ally *sf = a->allies;
for (; sf != NULL; sf = sf->next) {
if (sf->faction == b) {
return sf->status;
}
}
return 0;
}
void set_alliance(faction * a, faction * b, int status)
{
/* TODO: optimization (use allies_walk?) */
int original = ally_get(a->allies, b);
ally_set(&a->allies, b, status | original);
}
void renumber_faction(faction * f, int no) void renumber_faction(faction * f, int no)
{ {
funhash(f); funhash(f);

View File

@ -128,9 +128,6 @@ extern "C" {
bool faction_alive(const struct faction *f); bool faction_alive(const struct faction *f);
void set_alliance(struct faction *a, struct faction *b, int status);
int get_alliance(const struct faction *a, const struct faction *b);
struct alliance *f_get_alliance(const struct faction *f); struct alliance *f_get_alliance(const struct faction *f);
void write_faction_reference(const struct faction *f, void write_faction_reference(const struct faction *f,

View File

@ -53,7 +53,7 @@ group *new_group(faction * f, const char *name, int gid)
{ {
group **gp = &f->groups; group **gp = &f->groups;
int index = gid % GMAXHASH; int index = gid % GMAXHASH;
group *g = calloc(sizeof(group), 1); group *g = calloc(1, sizeof(group));
while (*gp) while (*gp)
gp = &(*gp)->next; gp = &(*gp)->next;
@ -69,14 +69,7 @@ group *new_group(faction * f, const char *name, int gid)
static void init_group(faction * f, group * g) static void init_group(faction * f, group * g)
{ {
ally *a, **an; g->allies = allies_clone(f->allies);
an = &g->allies;
for (a = f->allies; a; a = a->next) {
if (a->faction) {
ally_set(an, a->faction, a->status);
}
}
} }
static group *find_groupbyname(group * g, const char *name) static group *find_groupbyname(group * g, const char *name)
@ -138,11 +131,7 @@ void free_group(group * g)
if (g->attribs) { if (g->attribs) {
a_removeall(&g->attribs, NULL); a_removeall(&g->attribs, NULL);
} }
while (g->allies) { allies_free(g->allies);
ally *a = g->allies;
g->allies = a->next;
free(a);
}
free(g->name); free(g->name);
free(g); free(g);
} }
@ -203,20 +192,14 @@ group *join_group(unit * u, const char *name)
return g; return g;
} }
void write_groups(struct storage *store, const faction * f) void write_groups(struct gamedata *data, const faction * f)
{ {
group *g; group *g;
storage *store = data->store;
for (g = f->groups; g; g = g->next) { for (g = f->groups; g; g = g->next) {
ally *a;
WRITE_INT(store, g->gid); WRITE_INT(store, g->gid);
WRITE_STR(store, g->name); WRITE_STR(store, g->name);
for (a = g->allies; a; a = a->next) { write_allies(data, g->allies);
if (a->faction && a->faction->_alive) {
write_faction_reference(a->faction, store);
WRITE_INT(store, a->status);
}
}
write_faction_reference(NULL, store);
a_write(store, g->attribs, g); a_write(store, g->attribs, g);
WRITE_SECTION(store); WRITE_SECTION(store);
} }

View File

@ -42,7 +42,7 @@ extern "C" {
extern void free_group(struct group *g); extern void free_group(struct group *g);
struct group *new_group(struct faction * f, const char *name, int gid); struct group *new_group(struct faction * f, const char *name, int gid);
extern void write_groups(struct storage *data, const struct faction *f); extern void write_groups(struct gamedata *data, const struct faction *f);
extern void read_groups(struct gamedata *data, struct faction *f); extern void read_groups(struct gamedata *data, struct faction *f);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -84,7 +84,7 @@ static void test_group_readwrite(CuTest * tc)
g = new_group(f, "Egoisten", 43); g = new_group(f, "Egoisten", 43);
key_set(&g->attribs, 44, 44); key_set(&g->attribs, 44, 44);
ally_set(&g->allies, f, HELP_GIVE); ally_set(&g->allies, f, HELP_GIVE);
write_groups(&store, f); write_groups(&data, f);
WRITE_INT(&store, 47); WRITE_INT(&store, 47);
free_group(f->groups); free_group(f->groups);
@ -107,9 +107,7 @@ static void test_group_readwrite(CuTest * tc)
g = f->groups->next; g = f->groups->next;
CuAssertIntEquals(tc, 44, key_get(g->attribs, 44)); CuAssertIntEquals(tc, 44, key_get(g->attribs, 44));
CuAssertPtrNotNull(tc, g->allies); CuAssertPtrNotNull(tc, g->allies);
CuAssertPtrEquals(tc, NULL, g->allies->next); CuAssertIntEquals(tc, HELP_GIVE, ally_get(g->allies, f));
CuAssertPtrEquals(tc, f, g->allies->faction);
CuAssertIntEquals(tc, HELP_GIVE, g->allies->status);
test_teardown(); test_teardown();
} }

View File

@ -1094,7 +1094,6 @@ faction *read_faction(gamedata * data)
void write_faction(gamedata *data, const faction * f) void write_faction(gamedata *data, const faction * f)
{ {
ally *sf;
origin *ur; origin *ur;
assert(f->_alive); assert(f->_alive);
@ -1144,19 +1143,9 @@ void write_faction(gamedata *data, const faction * f)
WRITE_INT(data->store, f->options & ~WANT_OPTION(O_DEBUG)); WRITE_INT(data->store, f->options & ~WANT_OPTION(O_DEBUG));
WRITE_SECTION(data->store); WRITE_SECTION(data->store);
for (sf = f->allies; sf; sf = sf->next) { write_allies(data, f->allies);
assert(sf->faction);
if (faction_alive(sf->faction)) {
if (sf->status != 0) {
WRITE_INT(data->store, sf->faction->no);
WRITE_INT(data->store, sf->status);
}
}
}
WRITE_INT(data->store, 0);
WRITE_SECTION(data->store); WRITE_SECTION(data->store);
write_groups(data->store, f); write_groups(data, f);
write_spellbook(f->spellbook, data->store); write_spellbook(f->spellbook, data->store);
} }

View File

@ -268,6 +268,7 @@ static void test_readwrite_dead_faction_group(CuTest *tc) {
CuAssertPtrNotNull(tc, u); CuAssertPtrNotNull(tc, u);
g = join_group(u, "group"); g = join_group(u, "group");
CuAssertPtrNotNull(tc, g); CuAssertPtrNotNull(tc, g);
CuAssertPtrEquals(tc, NULL, g->allies);
ally_set(&g->allies, f, HELP_GIVE); ally_set(&g->allies, f, HELP_GIVE);
CuAssertPtrNotNull(tc, g->allies); CuAssertPtrNotNull(tc, g->allies);

View File

@ -1510,45 +1510,42 @@ report_template(const char *filename, report_context * ctx, const char *bom)
return 0; return 0;
} }
static void static int count_allies_cb(struct ally *all, faction *af, int status, void *udata) {
show_allies(const faction * f, struct ally * allies, char *buf, size_t size) int *num = (int *)udata;
{ if (status > 0) {
int allierte = 0; ++*num;
int i = 0, h, hh = 0, dh = 0;
const ally *sf;
for (sf = allies; sf; sf = sf->next) {
int mode = alliedfaction(f, sf->faction, HELP_ALL);
if (mode > 0) {
++allierte;
}
} }
return 0;
}
if (allierte > 0) { struct show_s {
sbstring sbs; sbstring sbs;
sbs_init(&sbs, buf, size); const faction *f;
int num_allies;
};
for (sf = allies; sf; sf = sf->next) { static int show_allies_cb(struct ally *all, faction *af, int status, void *udata) {
int mode = alliedfaction(f, sf->faction, HELP_ALL); struct show_s * show = (struct show_s *)udata;
if (mode <= 0) const faction * f = show->f;
continue;
i++; int mode = alliance_status(f, af, status);
if (dh) { --show->num_allies;
if (i == allierte) { if (sbs_length(&show->sbs) > 0) {
sbs_strcat(&sbs, LOC(f->locale, "list_and")); /* not the first entry */
if (0 == show->num_allies) {
sbs_strcat(&show->sbs, LOC(f->locale, "list_and"));
} }
else { else {
sbs_strcat(&sbs, ", "); sbs_strcat(&show->sbs, ", ");
} }
} }
dh = 1; sbs_strcat(&show->sbs, factionname(af));
hh = 0; sbs_strcat(&show->sbs, " (");
sbs_strcat(&sbs, factionname(sf->faction));
sbs_strcat(&sbs, " (");
if ((mode & HELP_ALL) == HELP_ALL) { if ((mode & HELP_ALL) == HELP_ALL) {
sbs_strcat(&sbs, LOC(f->locale, parameters[P_ANY])); sbs_strcat(&show->sbs, LOC(f->locale, parameters[P_ANY]));
} }
else { else {
int h, hh = 0;
for (h = 1; h <= HELP_TRAVEL; h *= 2) { for (h = 1; h <= HELP_TRAVEL; h *= 2) {
int p = MAXPARAMS; int p = MAXPARAMS;
if ((mode & h) == h) { if ((mode & h) == h) {
@ -1575,16 +1572,31 @@ show_allies(const faction * f, struct ally * allies, char *buf, size_t size)
} }
if (p != MAXPARAMS) { if (p != MAXPARAMS) {
if (hh) { if (hh) {
sbs_strcat(&sbs, ", "); sbs_strcat(&show->sbs, ", ");
} }
sbs_strcat(&sbs, LOC(f->locale, parameters[p])); sbs_strcat(&show->sbs, LOC(f->locale, parameters[p]));
hh = 1; hh = 1;
} }
} }
} }
sbs_strcat(&sbs, ")"); sbs_strcat(&show->sbs, ")");
} return 0;
sbs_strcat(&sbs, "."); }
static void
show_allies(const faction * f, struct ally * allies, char *buf, size_t size)
{
int num_allies = 0;
allies_walk(allies, count_allies_cb, &num_allies);
if (num_allies > 0) {
struct show_s show;
show.f = f;
show.num_allies = num_allies;
sbs_init(&show.sbs, buf, size);
allies_walk(allies, show_allies_cb, &show);
sbs_strcat(&show.sbs, ".");
} }
} }

View File

@ -167,7 +167,7 @@ void get_food(region * r)
struct faction *owner = region_get_owner(r); struct faction *owner = region_get_owner(r);
/* if the region is owned, and the owner is nice, then we'll get /* if the region is owned, and the owner is nice, then we'll get
* food from the peasants - should not be used with WORK */ * food from the peasants - should not be used with WORK */
if (owner != NULL && (get_alliance(owner, u->faction) & HELP_MONEY)) { if (owner != NULL && alliedfaction(owner, u->faction, HELP_MONEY)) {
int rm = rmoney(r); int rm = rmoney(r);
int use = (rm < need) ? rm : need; int use = (rm < need) ? rm : need;
rsetmoney(r, rm - use); rsetmoney(r, rm - use);

View File

@ -1,6 +1,7 @@
#include <platform.h> #include <platform.h>
#include "upkeep.h" #include "upkeep.h"
#include <kernel/ally.h>
#include <kernel/config.h> #include <kernel/config.h>
#include <kernel/faction.h> #include <kernel/faction.h>
#include <kernel/region.h> #include <kernel/region.h>
@ -117,7 +118,7 @@ void test_upkeep_from_friend(CuTest * tc)
f1 = test_create_faction(test_create_race("human")); f1 = test_create_faction(test_create_race("human"));
f2 = test_create_faction(test_create_race("human")); f2 = test_create_faction(test_create_race("human"));
assert(f1 && f2); assert(f1 && f2);
set_alliance(f1, f2, HELP_MONEY); ally_set(&f1->allies, f2, HELP_MONEY);
u1 = test_create_unit(f1, r); u1 = test_create_unit(f1, r);
u2 = test_create_unit(f2, r); u2 = test_create_unit(f2, r);
assert(r && u1 && u2); assert(r && u1 && u2);