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"
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"
msgid "healingzone"

View File

@ -309,49 +309,6 @@ static int tolua_faction_count_msg_type(lua_State *L) {
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)
{
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_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 "set_origin", tolua_faction_set_origin);
tolua_function(L, TOLUA_CAST "normalize", tolua_faction_normalize);

View File

@ -25,7 +25,29 @@ typedef struct ally {
int status;
} 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;
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;
}
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)
{
for (;;) {
@ -196,8 +230,7 @@ static int AllianceRestricted(void)
return rule;
}
int alliance_status(faction *f, faction *f2, int status) {
int alliance_status(const faction *f, const faction *f2, int status) {
status |= autoalliance(f, f2);
if (status > 0) {
int mask = AllianceRestricted();
@ -226,7 +259,7 @@ alliedgroup(const struct faction *f,
if (!(faction_alive(f) && faction_alive(f2))) {
return 0;
}
status = ally_get(all, f2);
status = ally_get(all, f2) & mask;
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. */
int alliedunit(const unit * u, const faction * f2, int mode)
int alliedunit(const unit * u, const faction * f2, int mask)
{
assert(u);
assert(f2);
assert(u->region); /* the unit should be in a region, but it's possible that u->number==0 (TEMP units) */
if (u->faction == f2) {
return mode;
return mask;
}
if (!faction_alive(f2)) {
return 0;
}
if (u->faction != NULL && f2 != NULL) {
if (mode & HELP_FIGHT) {
if (mask & HELP_FIGHT) {
if ((u->flags & UFL_DEFENDER) || (u->faction->flags & FFL_DEFENDER)) {
faction *owner = region_get_owner(u->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);
if (a != NULL) {
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;
}

View File

@ -33,23 +33,27 @@ extern "C" {
extern struct attrib_type at_npcfaction;
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 *);
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);
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);
int AllianceAuto(void); /* flags that allied factions get automatically */
int HelpMask(void); /* flags restricted to allied factions */
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 mode);
int mask);
int alliedgroup(const struct faction *f, const struct faction *f2,
const struct group *g, int mode);
int alliance_status(const struct faction *f, const struct faction *f2, int mode);
const struct group *g, int mask);
int alliance_status(const struct faction *f, const struct faction *f2, int status);
#ifdef __cplusplus
}

View File

@ -7,22 +7,47 @@
static void test_ally(CuTest * tc)
{
ally * al = NULL;
struct faction * f1 = test_create_faction(NULL);
struct ally * al = 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);
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);
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 *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_ally);
SUITE_ADD_TEST(suite, test_allies_clone);
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)
{
funhash(f);

View File

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

View File

@ -42,7 +42,7 @@ extern "C" {
extern void free_group(struct group *g);
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);
#ifdef __cplusplus

View File

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

View File

@ -1094,7 +1094,6 @@ faction *read_faction(gamedata * data)
void write_faction(gamedata *data, const faction * f)
{
ally *sf;
origin *ur;
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_SECTION(data->store);
for (sf = f->allies; sf; sf = sf->next) {
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_allies(data, f->allies);
WRITE_SECTION(data->store);
write_groups(data->store, f);
write_groups(data, f);
write_spellbook(f->spellbook, data->store);
}

View File

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

View File

@ -1510,81 +1510,93 @@ report_template(const char *filename, report_context * ctx, const char *bom)
return 0;
}
static int count_allies_cb(struct ally *all, faction *af, int status, void *udata) {
int *num = (int *)udata;
if (status > 0) {
++*num;
}
return 0;
}
struct show_s {
sbstring sbs;
const faction *f;
int num_allies;
};
static int show_allies_cb(struct ally *all, faction *af, int status, void *udata) {
struct show_s * show = (struct show_s *)udata;
const faction * f = show->f;
int mode = alliance_status(f, af, status);
--show->num_allies;
if (sbs_length(&show->sbs) > 0) {
/* not the first entry */
if (0 == show->num_allies) {
sbs_strcat(&show->sbs, LOC(f->locale, "list_and"));
}
else {
sbs_strcat(&show->sbs, ", ");
}
}
sbs_strcat(&show->sbs, factionname(af));
sbs_strcat(&show->sbs, " (");
if ((mode & HELP_ALL) == HELP_ALL) {
sbs_strcat(&show->sbs, LOC(f->locale, parameters[P_ANY]));
}
else {
int h, hh = 0;
for (h = 1; h <= HELP_TRAVEL; h *= 2) {
int p = MAXPARAMS;
if ((mode & h) == h) {
switch (h) {
case HELP_TRAVEL:
p = P_TRAVEL;
break;
case HELP_MONEY:
p = P_MONEY;
break;
case HELP_FIGHT:
p = P_FIGHT;
break;
case HELP_GIVE:
p = P_GIVE;
break;
case HELP_GUARD:
p = P_GUARD;
break;
case HELP_FSTEALTH:
p = P_FACTIONSTEALTH;
break;
}
}
if (p != MAXPARAMS) {
if (hh) {
sbs_strcat(&show->sbs, ", ");
}
sbs_strcat(&show->sbs, LOC(f->locale, parameters[p]));
hh = 1;
}
}
}
sbs_strcat(&show->sbs, ")");
return 0;
}
static void
show_allies(const faction * f, struct ally * allies, char *buf, size_t size)
{
int allierte = 0;
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;
}
}
int num_allies = 0;
allies_walk(allies, count_allies_cb, &num_allies);
if (allierte > 0) {
sbstring sbs;
sbs_init(&sbs, buf, size);
if (num_allies > 0) {
struct show_s show;
show.f = f;
show.num_allies = num_allies;
sbs_init(&show.sbs, buf, size);
for (sf = allies; sf; sf = sf->next) {
int mode = alliedfaction(f, sf->faction, HELP_ALL);
if (mode <= 0)
continue;
i++;
if (dh) {
if (i == allierte) {
sbs_strcat(&sbs, LOC(f->locale, "list_and"));
}
else {
sbs_strcat(&sbs, ", ");
}
}
dh = 1;
hh = 0;
sbs_strcat(&sbs, factionname(sf->faction));
sbs_strcat(&sbs, " (");
if ((mode & HELP_ALL) == HELP_ALL) {
sbs_strcat(&sbs, LOC(f->locale, parameters[P_ANY]));
}
else {
for (h = 1; h <= HELP_TRAVEL; h *= 2) {
int p = MAXPARAMS;
if ((mode & h) == h) {
switch (h) {
case HELP_TRAVEL:
p = P_TRAVEL;
break;
case HELP_MONEY:
p = P_MONEY;
break;
case HELP_FIGHT:
p = P_FIGHT;
break;
case HELP_GIVE:
p = P_GIVE;
break;
case HELP_GUARD:
p = P_GUARD;
break;
case HELP_FSTEALTH:
p = P_FACTIONSTEALTH;
break;
}
}
if (p != MAXPARAMS) {
if (hh) {
sbs_strcat(&sbs, ", ");
}
sbs_strcat(&sbs, LOC(f->locale, parameters[p]));
hh = 1;
}
}
}
sbs_strcat(&sbs, ")");
}
sbs_strcat(&sbs, ".");
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);
/* if the region is owned, and the owner is nice, then we'll get
* 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 use = (rm < need) ? rm : need;
rsetmoney(r, rm - use);

View File

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