forked from github/server
Merge pull request #453 from eressea/issue-451-destroyfaction
Issue 451 destroyfaction
This commit is contained in:
commit
05c53735c6
|
@ -343,8 +343,14 @@ static int tolua_faction_get_origin(lua_State * L)
|
||||||
|
|
||||||
static int tolua_faction_destroy(lua_State * L)
|
static int tolua_faction_destroy(lua_State * L)
|
||||||
{
|
{
|
||||||
faction *f = (faction *)tolua_tousertype(L, 1, 0);
|
faction **fp, *f = (faction *)tolua_tousertype(L, 1, 0);
|
||||||
destroyfaction(f);
|
// TODO: this loop is slow af, but what can we do?
|
||||||
|
for (fp = &factions; *fp; fp = &(*fp)->next) {
|
||||||
|
if (*fp == f) {
|
||||||
|
destroyfaction(fp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -424,13 +424,14 @@ void alliancevictory(void)
|
||||||
}
|
}
|
||||||
while (al != NULL) {
|
while (al != NULL) {
|
||||||
if (!fval(al, FFL_MARK)) {
|
if (!fval(al, FFL_MARK)) {
|
||||||
int qi;
|
faction **fp;
|
||||||
quicklist *flist = al->members;
|
for (fp = &factions; *fp; ) {
|
||||||
for (qi = 0; flist; ql_advance(&flist, &qi, 1)) {
|
faction *f = *fp;
|
||||||
faction *f = (faction *)ql_get(flist, qi);
|
|
||||||
if (f->alliance == al) {
|
if (f->alliance == al) {
|
||||||
ADDMSG(&f->msgs, msg_message("alliance::lost", "alliance", al));
|
ADDMSG(&f->msgs, msg_message("alliance::lost", "alliance", al));
|
||||||
destroyfaction(f);
|
destroyfaction(fp);
|
||||||
|
} else {
|
||||||
|
fp = &f->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -252,7 +252,7 @@ faction *addfaction(const char *email, const char *password,
|
||||||
|
|
||||||
f->alliance_joindate = turn;
|
f->alliance_joindate = turn;
|
||||||
f->lastorders = turn;
|
f->lastorders = turn;
|
||||||
f->alive = 1;
|
f->_alive = true;
|
||||||
f->age = 0;
|
f->age = 0;
|
||||||
f->race = frace;
|
f->race = frace;
|
||||||
f->magiegebiet = 0;
|
f->magiegebiet = 0;
|
||||||
|
@ -322,18 +322,18 @@ variant read_faction_reference(struct storage * store)
|
||||||
|
|
||||||
void write_faction_reference(const faction * f, struct storage *store)
|
void write_faction_reference(const faction * f, struct storage *store)
|
||||||
{
|
{
|
||||||
WRITE_INT(store, f ? f->no : 0);
|
WRITE_INT(store, (f && f->_alive) ? f->no : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroyfaction(faction * f)
|
void destroyfaction(faction ** fp)
|
||||||
{
|
{
|
||||||
|
faction * f = *fp;
|
||||||
unit *u = f->units;
|
unit *u = f->units;
|
||||||
faction *ff;
|
faction *ff;
|
||||||
|
|
||||||
if (!f->alive) {
|
*fp = f->next;
|
||||||
return;
|
|
||||||
}
|
|
||||||
fset(f, FFL_QUIT);
|
fset(f, FFL_QUIT);
|
||||||
|
f->_alive = false;
|
||||||
|
|
||||||
if (f->spellbook) {
|
if (f->spellbook) {
|
||||||
spellbook_clear(f->spellbook);
|
spellbook_clear(f->spellbook);
|
||||||
|
@ -389,32 +389,42 @@ void destroyfaction(faction * f)
|
||||||
u = u->nextF;
|
u = u->nextF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f->alive = 0;
|
|
||||||
/* no way! f->units = NULL; */
|
/* no way! f->units = NULL; */
|
||||||
handle_event(f->attribs, "destroy", f);
|
handle_event(f->attribs, "destroy", f);
|
||||||
for (ff = factions; ff; ff = ff->next) {
|
for (ff = factions; ff; ff = ff->next) {
|
||||||
group *g;
|
group *g;
|
||||||
ally *sf, *sfn;
|
ally *sf, **sfp;
|
||||||
|
|
||||||
/* Alle HELFE für die Partei löschen */
|
for (sfp = &ff->allies; *sfp;) {
|
||||||
for (sf = ff->allies; sf; sf = sf->next) {
|
sf = *sfp;
|
||||||
if (sf->faction == f) {
|
if (sf->faction == f || sf->faction == NULL) {
|
||||||
removelist(&ff->allies, sf);
|
*sfp = sf->next;
|
||||||
break;
|
free(sf);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
sfp = &(*sfp)->next;
|
||||||
}
|
}
|
||||||
for (g = ff->groups; g; g = g->next) {
|
for (g = ff->groups; g; g = g->next) {
|
||||||
for (sf = g->allies; sf;) {
|
for (sfp = &g->allies; *sfp; ) {
|
||||||
sfn = sf->next;
|
sf = *sfp;
|
||||||
if (sf->faction == f) {
|
if (sf->faction == f || sf->faction == NULL) {
|
||||||
removelist(&g->allies, sf);
|
*sfp = sf->next;
|
||||||
break;
|
free(sf);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sfp = &(*sfp)->next;
|
||||||
}
|
}
|
||||||
sf = sfn;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (f->alliance && f->alliance->_leader == f) {
|
||||||
|
setalliance(f, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
funhash(f);
|
||||||
|
free_faction(f);
|
||||||
|
|
||||||
/* units of other factions that were disguised as this faction
|
/* units of other factions that were disguised as this faction
|
||||||
* have their disguise replaced by ordinary faction hiding. */
|
* have their disguise replaced by ordinary faction hiding. */
|
||||||
if (rule_stealth_other()) {
|
if (rule_stealth_other()) {
|
||||||
|
@ -633,61 +643,26 @@ int skill_limit(faction * f, skill_t sk)
|
||||||
|
|
||||||
void remove_empty_factions(void)
|
void remove_empty_factions(void)
|
||||||
{
|
{
|
||||||
faction **fp, *f3;
|
faction **fp;
|
||||||
|
|
||||||
for (fp = &factions; *fp;) {
|
for (fp = &factions; *fp;) {
|
||||||
faction *f = *fp;
|
faction *f = *fp;
|
||||||
/* monster (0) werden nicht entfernt. alive kann beim readgame
|
|
||||||
* () auf 0 gesetzt werden, wenn monsters keine einheiten mehr
|
if (!(f->_alive && f->units!=NULL) && !fval(f, FFL_NOIDLEOUT)) {
|
||||||
* haben. */
|
|
||||||
if ((f->units == NULL || f->alive == 0) && !fval(f, FFL_NOIDLEOUT)) {
|
|
||||||
ursprung *ur = f->ursprung;
|
|
||||||
while (ur && ur->id != 0)
|
|
||||||
ur = ur->next;
|
|
||||||
log_debug("dead: %s", factionname(f));
|
log_debug("dead: %s", factionname(f));
|
||||||
|
destroyfaction(fp);
|
||||||
/* Einfach in eine Datei schreiben und später vermailen */
|
|
||||||
|
|
||||||
for (f3 = factions; f3; f3 = f3->next) {
|
|
||||||
ally *sf;
|
|
||||||
group *g;
|
|
||||||
ally **sfp = &f3->allies;
|
|
||||||
while (*sfp) {
|
|
||||||
sf = *sfp;
|
|
||||||
if (sf->faction == f || sf->faction == NULL) {
|
|
||||||
*sfp = sf->next;
|
|
||||||
free(sf);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sfp = &(*sfp)->next;
|
|
||||||
}
|
|
||||||
for (g = f3->groups; g; g = g->next) {
|
|
||||||
sfp = &g->allies;
|
|
||||||
while (*sfp) {
|
|
||||||
sf = *sfp;
|
|
||||||
if (sf->faction == f || sf->faction == NULL) {
|
|
||||||
*sfp = sf->next;
|
|
||||||
free(sf);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sfp = &(*sfp)->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*fp = f->next;
|
|
||||||
funhash(f);
|
|
||||||
free_faction(f);
|
|
||||||
if (f->alliance && f->alliance->_leader == f) {
|
|
||||||
setalliance(f, 0);
|
|
||||||
}
|
|
||||||
free(f);
|
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
fp = &(*fp)->next;
|
fp = &(*fp)->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool faction_alive(faction *f) {
|
||||||
|
assert(f);
|
||||||
|
return f->_alive || (f->flags&FFL_NPC);
|
||||||
|
}
|
||||||
|
|
||||||
void faction_getorigin(const faction * f, int id, int *x, int *y)
|
void faction_getorigin(const faction * f, int id, int *x, int *y)
|
||||||
{
|
{
|
||||||
ursprung *ur;
|
ursprung *ur;
|
||||||
|
|
|
@ -103,7 +103,7 @@ extern "C" {
|
||||||
struct item *items; /* items this faction can claim */
|
struct item *items; /* items this faction can claim */
|
||||||
struct seen_region **seen;
|
struct seen_region **seen;
|
||||||
struct quicklist *seen_factions;
|
struct quicklist *seen_factions;
|
||||||
bool alive; /* enno: sollte ein flag werden */
|
bool _alive; /* enno: sollte ein flag werden */
|
||||||
} faction;
|
} faction;
|
||||||
|
|
||||||
extern struct faction *factions;
|
extern struct faction *factions;
|
||||||
|
@ -121,7 +121,9 @@ extern "C" {
|
||||||
struct faction *addfaction(const char *email, const char *password,
|
struct faction *addfaction(const char *email, const char *password,
|
||||||
const struct race *frace, const struct locale *loc, int subscription);
|
const struct race *frace, const struct locale *loc, int subscription);
|
||||||
bool checkpasswd(const faction * f, const char *passwd);
|
bool checkpasswd(const faction * f, const char *passwd);
|
||||||
void destroyfaction(faction * f);
|
void destroyfaction(faction ** f);
|
||||||
|
|
||||||
|
bool faction_alive(struct faction *f);
|
||||||
|
|
||||||
void set_alliance(struct faction *a, struct faction *b, int status);
|
void set_alliance(struct faction *a, struct faction *b, int status);
|
||||||
int get_alliance(const struct faction *a, const struct faction *b);
|
int get_alliance(const struct faction *a, const struct faction *b);
|
||||||
|
|
|
@ -75,8 +75,8 @@ static void test_remove_dead_factions(CuTest *tc) {
|
||||||
remove_empty_factions();
|
remove_empty_factions();
|
||||||
CuAssertPtrEquals(tc, f, findfaction(f->no));
|
CuAssertPtrEquals(tc, f, findfaction(f->no));
|
||||||
CuAssertPtrNotNull(tc, get_monsters());
|
CuAssertPtrNotNull(tc, get_monsters());
|
||||||
fm->alive = 0;
|
fm->units = 0;
|
||||||
f->alive = 0;
|
f->_alive = false;
|
||||||
fno = f->no;
|
fno = f->no;
|
||||||
remove_empty_factions();
|
remove_empty_factions();
|
||||||
CuAssertPtrEquals(tc, 0, findfaction(fno));
|
CuAssertPtrEquals(tc, 0, findfaction(fno));
|
||||||
|
@ -107,7 +107,7 @@ static void test_addfaction(CuTest *tc) {
|
||||||
CuAssertIntEquals(tc, 1234, f->subscription);
|
CuAssertIntEquals(tc, 1234, f->subscription);
|
||||||
CuAssertIntEquals(tc, 0, f->flags);
|
CuAssertIntEquals(tc, 0, f->flags);
|
||||||
CuAssertIntEquals(tc, 0, f->age);
|
CuAssertIntEquals(tc, 0, f->age);
|
||||||
CuAssertIntEquals(tc, 1, f->alive);
|
CuAssertIntEquals(tc, true, faction_alive(f));
|
||||||
CuAssertIntEquals(tc, M_GRAY, f->magiegebiet);
|
CuAssertIntEquals(tc, M_GRAY, f->magiegebiet);
|
||||||
CuAssertIntEquals(tc, turn, f->lastorders);
|
CuAssertIntEquals(tc, turn, f->lastorders);
|
||||||
CuAssertPtrEquals(tc, f, findfaction(f->no));
|
CuAssertPtrEquals(tc, f, findfaction(f->no));
|
||||||
|
|
|
@ -1668,7 +1668,7 @@ int readgame(const char *filename, bool backup)
|
||||||
log_debug("marking factions as alive.\n");
|
log_debug("marking factions as alive.\n");
|
||||||
for (f = factions; f; f = f->next) {
|
for (f = factions; f; f = f->next) {
|
||||||
if (f->flags & FFL_NPC) {
|
if (f->flags & FFL_NPC) {
|
||||||
f->alive = 1;
|
f->_alive = true;
|
||||||
f->magiegebiet = M_GRAY;
|
f->magiegebiet = M_GRAY;
|
||||||
if (f->no == 0) {
|
if (f->no == 0) {
|
||||||
int no = 666;
|
int no = 666;
|
||||||
|
@ -1698,7 +1698,7 @@ int readgame(const char *filename, bool backup)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (u->number > 0) {
|
if (u->number > 0) {
|
||||||
f->alive = true;
|
f->_alive = true;
|
||||||
if (global.data_version >= SPELL_LEVEL_VERSION) {
|
if (global.data_version >= SPELL_LEVEL_VERSION) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1463,7 +1463,7 @@ unit *create_unit(region * r, faction * f, int number, const struct race *urace,
|
||||||
|
|
||||||
assert(urace);
|
assert(urace);
|
||||||
if (f) {
|
if (f) {
|
||||||
assert(f->alive);
|
assert(faction_alive(f));
|
||||||
u_setfaction(u, f);
|
u_setfaction(u, f);
|
||||||
|
|
||||||
if (f->locale) {
|
if (f->locale) {
|
||||||
|
@ -1828,7 +1828,7 @@ void remove_empty_units_in_region(region * r)
|
||||||
|
|
||||||
if (u->number) {
|
if (u->number) {
|
||||||
faction *f = u->faction;
|
faction *f = u->faction;
|
||||||
if (f == NULL || !f->alive) {
|
if (f == NULL || !faction_alive(f)) {
|
||||||
set_number(u, 0);
|
set_number(u, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ static void test_remove_units_with_dead_faction(CuTest *tc) {
|
||||||
|
|
||||||
u = test_create_unit(test_create_faction(test_create_race("human")), findregion(0, 0));
|
u = test_create_unit(test_create_faction(test_create_race("human")), findregion(0, 0));
|
||||||
uid = u->no;
|
uid = u->no;
|
||||||
u->faction->alive = false;
|
u->faction->_alive = false;
|
||||||
remove_empty_units_in_region(u->region);
|
remove_empty_units_in_region(u->region);
|
||||||
CuAssertPtrEquals(tc, 0, findunit(uid));
|
CuAssertPtrEquals(tc, 0, findunit(uid));
|
||||||
CuAssertIntEquals(tc, 0, u->number);
|
CuAssertIntEquals(tc, 0, u->number);
|
||||||
|
|
28
src/laws.c
28
src/laws.c
|
@ -1220,42 +1220,45 @@ static void nmr_death(faction * f)
|
||||||
|
|
||||||
static void remove_idle_players(void)
|
static void remove_idle_players(void)
|
||||||
{
|
{
|
||||||
faction *f;
|
faction **fp;
|
||||||
|
|
||||||
log_info(" - beseitige Spieler, die sich zu lange nicht mehr gemeldet haben...");
|
log_info(" - beseitige Spieler, die sich zu lange nicht mehr gemeldet haben...");
|
||||||
|
|
||||||
for (f = factions; f; f = f->next) {
|
for (fp = &factions; *fp;) {
|
||||||
|
faction *f = *fp;
|
||||||
if (fval(f, FFL_NOIDLEOUT)) {
|
if (fval(f, FFL_NOIDLEOUT)) {
|
||||||
f->lastorders = turn;
|
f->lastorders = turn;
|
||||||
}
|
}
|
||||||
if (NMRTimeout() > 0 && turn - f->lastorders >= NMRTimeout()) {
|
if (NMRTimeout() > 0 && turn - f->lastorders >= NMRTimeout()) {
|
||||||
nmr_death(f);
|
nmr_death(f);
|
||||||
destroyfaction(f);
|
destroyfaction(fp);
|
||||||
continue;
|
} else if (turn != f->lastorders) {
|
||||||
}
|
|
||||||
if (turn != f->lastorders) {
|
|
||||||
char info[256];
|
char info[256];
|
||||||
sprintf(info, "%d Einheiten, %d Personen, %d Silber",
|
sprintf(info, "%d Einheiten, %d Personen, %d Silber",
|
||||||
f->no_units, f->num_total, f->money);
|
f->no_units, f->num_total, f->money);
|
||||||
}
|
}
|
||||||
|
fp = &f->next;
|
||||||
}
|
}
|
||||||
log_info(" - beseitige Spieler, die sich nach der Anmeldung nicht gemeldet haben...");
|
log_info(" - beseitige Spieler, die sich nach der Anmeldung nicht gemeldet haben...");
|
||||||
|
|
||||||
age = calloc(_max(4, turn + 1), sizeof(int));
|
age = calloc(_max(4, turn + 1), sizeof(int));
|
||||||
for (f = factions; f; f = f->next)
|
for (fp = &factions; *fp;) {
|
||||||
|
faction *f = *fp;
|
||||||
if (!is_monsters(f)) {
|
if (!is_monsters(f)) {
|
||||||
if (RemoveNMRNewbie() && !fval(f, FFL_NOIDLEOUT)) {
|
if (RemoveNMRNewbie() && !fval(f, FFL_NOIDLEOUT)) {
|
||||||
if (f->age >= 0 && f->age <= turn)
|
if (f->age >= 0 && f->age <= turn)
|
||||||
++age[f->age];
|
++age[f->age];
|
||||||
if (f->age == 2 || f->age == 3) {
|
if (f->age == 2 || f->age == 3) {
|
||||||
if (f->lastorders == turn - 2) {
|
if (f->lastorders == turn - 2) {
|
||||||
destroyfaction(f);
|
|
||||||
++dropouts[f->age - 2];
|
++dropouts[f->age - 2];
|
||||||
|
destroyfaction(fp);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fp = &f->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void quit(void)
|
void quit(void)
|
||||||
|
@ -1264,7 +1267,7 @@ void quit(void)
|
||||||
while (*fptr) {
|
while (*fptr) {
|
||||||
faction *f = *fptr;
|
faction *f = *fptr;
|
||||||
if (f->flags & FFL_QUIT) {
|
if (f->flags & FFL_QUIT) {
|
||||||
destroyfaction(f);
|
destroyfaction(fptr);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
++f->age;
|
++f->age;
|
||||||
|
@ -1272,8 +1275,6 @@ void quit(void)
|
||||||
ADDMSG(&f->msgs, msg_message("newbieimmunity", "turns",
|
ADDMSG(&f->msgs, msg_message("newbieimmunity", "turns",
|
||||||
NewbieImmunity() - f->age - 1));
|
NewbieImmunity() - f->age - 1));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (*fptr == f) {
|
|
||||||
fptr = &f->next;
|
fptr = &f->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4263,8 +4264,8 @@ static void maintain_buildings_1(region * r)
|
||||||
*/
|
*/
|
||||||
static int warn_password(void)
|
static int warn_password(void)
|
||||||
{
|
{
|
||||||
faction *f = factions;
|
faction *f;
|
||||||
while (f) {
|
for (f = factions; f; f = f->next) {
|
||||||
bool pwok = true;
|
bool pwok = true;
|
||||||
const char *c = f->passw;
|
const char *c = f->passw;
|
||||||
while (*c && pwok) {
|
while (*c && pwok) {
|
||||||
|
@ -4277,7 +4278,6 @@ static int warn_password(void)
|
||||||
f->passw = _strdup(itoa36(rng_int()));
|
f->passw = _strdup(itoa36(rng_int()));
|
||||||
ADDMSG(&f->msgs, msg_message("illegal_password", "newpass", f->passw));
|
ADDMSG(&f->msgs, msg_message("illegal_password", "newpass", f->passw));
|
||||||
}
|
}
|
||||||
f = f->next;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ int update_nmrs(void)
|
||||||
if (fval(f, FFL_ISNEW)) {
|
if (fval(f, FFL_ISNEW)) {
|
||||||
++newplayers;
|
++newplayers;
|
||||||
}
|
}
|
||||||
else if (!fval(f, FFL_NOIDLEOUT) && f->alive) {
|
else if (!fval(f, FFL_NOIDLEOUT)) {
|
||||||
int nmr = turn - f->lastorders + 1;
|
int nmr = turn - f->lastorders + 1;
|
||||||
if (nmr < 0 || nmr > NMRTimeout()) {
|
if (nmr < 0 || nmr > NMRTimeout()) {
|
||||||
log_error("faction %s has %d NMRS\n", factionid(f), nmr);
|
log_error("faction %s has %d NMRS\n", factionid(f), nmr);
|
||||||
|
@ -370,7 +370,7 @@ summary *make_summary(void)
|
||||||
f->nregions = 0;
|
f->nregions = 0;
|
||||||
f->num_total = 0;
|
f->num_total = 0;
|
||||||
f->money = 0;
|
f->money = 0;
|
||||||
if (f->alive && f->units) {
|
if (f->units) {
|
||||||
s->factions++;
|
s->factions++;
|
||||||
/* Problem mit Monsterpartei ... */
|
/* Problem mit Monsterpartei ... */
|
||||||
if (!is_monsters(f)) {
|
if (!is_monsters(f)) {
|
||||||
|
|
Loading…
Reference in New Issue