forked from github/server
properly create missing monster faction when spawning dragons.
remove cached monster faction (static). Conflicts: src/kernel/faction.c
This commit is contained in:
parent
206e0a2fc5
commit
138a4c10a0
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
|
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
|
||||||
Katja Zedel <katze@felidae.kn-bremen.de
|
Katja Zedel <katze@felidae.kn-bremen.de
|
||||||
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -68,526 +68,539 @@ faction *factions;
|
||||||
*/
|
*/
|
||||||
void free_faction(faction * f)
|
void free_faction(faction * f)
|
||||||
{
|
{
|
||||||
if (f->msgs)
|
if (f->msgs)
|
||||||
free_messagelist(f->msgs);
|
free_messagelist(f->msgs);
|
||||||
while (f->battles) {
|
while (f->battles) {
|
||||||
struct bmsg *bm = f->battles;
|
struct bmsg *bm = f->battles;
|
||||||
f->battles = bm->next;
|
f->battles = bm->next;
|
||||||
if (bm->msgs)
|
if (bm->msgs)
|
||||||
free_messagelist(bm->msgs);
|
free_messagelist(bm->msgs);
|
||||||
free(bm);
|
free(bm);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (f->groups) {
|
while (f->groups) {
|
||||||
group *g = f->groups;
|
group *g = f->groups;
|
||||||
f->groups = g->next;
|
f->groups = g->next;
|
||||||
free_group(g);
|
free_group(g);
|
||||||
}
|
}
|
||||||
freelist(f->allies);
|
freelist(f->allies);
|
||||||
|
|
||||||
free(f->email);
|
free(f->email);
|
||||||
free(f->banner);
|
free(f->banner);
|
||||||
free(f->passw);
|
free(f->passw);
|
||||||
free(f->name);
|
free(f->name);
|
||||||
|
|
||||||
while (f->attribs) {
|
while (f->attribs) {
|
||||||
a_remove(&f->attribs, f->attribs);
|
a_remove(&f->attribs, f->attribs);
|
||||||
}
|
}
|
||||||
|
|
||||||
i_freeall(&f->items);
|
i_freeall(&f->items);
|
||||||
|
|
||||||
freelist(f->ursprung);
|
freelist(f->ursprung);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_show_item(faction * f, const struct item_type *itype)
|
void set_show_item(faction * f, const struct item_type *itype)
|
||||||
{
|
{
|
||||||
attrib *a = a_add(&f->attribs, a_new(&at_showitem));
|
attrib *a = a_add(&f->attribs, a_new(&at_showitem));
|
||||||
a->data.v = (void *)itype;
|
a->data.v = (void *)itype;
|
||||||
}
|
}
|
||||||
|
|
||||||
faction *get_monsters(void)
|
faction *get_monsters(void) {
|
||||||
{
|
|
||||||
static faction *monsters;
|
|
||||||
static int gamecookie = -1;
|
|
||||||
|
|
||||||
if (gamecookie != global.cookie) {
|
|
||||||
monsters = NULL;
|
|
||||||
gamecookie = global.cookie;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!monsters) {
|
|
||||||
faction *f;
|
faction *f;
|
||||||
|
|
||||||
for (f = factions; f; f = f->next) {
|
for (f = factions; f; f = f->next) {
|
||||||
if ((f->flags & FFL_NPC) && !(f->flags & FFL_DEFENDER)) {
|
if ((f->flags & FFL_NPC) && !(f->flags & FFL_DEFENDER)) {
|
||||||
return monsters = f;
|
return f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!monsters) {
|
return 0;
|
||||||
/* shit! */
|
}
|
||||||
monsters = findfaction(666);
|
|
||||||
|
faction *get_or_create_monsters(void)
|
||||||
|
{
|
||||||
|
faction *f = get_monsters();
|
||||||
|
|
||||||
|
if (!f) {
|
||||||
|
/* shit! */
|
||||||
|
f = findfaction(666);
|
||||||
}
|
}
|
||||||
if (monsters) {
|
if (!f) {
|
||||||
fset(monsters, FFL_NPC | FFL_NOIDLEOUT);
|
const race *rc = rc_find("dragon");
|
||||||
|
|
||||||
|
f = addfaction("noreply@eressea.de", NULL, rc, NULL, 0);
|
||||||
|
renumber_faction(f, 666);
|
||||||
|
faction_setname(f, "Monster");
|
||||||
|
f->options = 0;
|
||||||
}
|
}
|
||||||
}
|
if (f) {
|
||||||
return monsters;
|
fset(f, FFL_NPC | FFL_NOIDLEOUT);
|
||||||
|
}
|
||||||
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
const unit *random_unit_in_faction(const faction * f)
|
const unit *random_unit_in_faction(const faction * f)
|
||||||
{
|
{
|
||||||
unit *u;
|
unit *u;
|
||||||
int c = 0, u_nr;
|
int c = 0, u_nr;
|
||||||
|
|
||||||
for (u = f->units; u; u = u->next)
|
for (u = f->units; u; u = u->next)
|
||||||
c++;
|
c++;
|
||||||
|
|
||||||
u_nr = rng_int() % c;
|
u_nr = rng_int() % c;
|
||||||
c = 0;
|
c = 0;
|
||||||
|
|
||||||
for (u = f->units; u; u = u->next)
|
for (u = f->units; u; u = u->next)
|
||||||
if (u_nr == c)
|
if (u_nr == c)
|
||||||
return u;
|
return u;
|
||||||
|
|
||||||
/* Hier sollte er nie ankommen */
|
/* Hier sollte er nie ankommen */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *factionname(const faction * f)
|
const char *factionname(const faction * f)
|
||||||
{
|
{
|
||||||
typedef char name[OBJECTIDSIZE + 1];
|
typedef char name[OBJECTIDSIZE + 1];
|
||||||
static name idbuf[8];
|
static name idbuf[8];
|
||||||
static int nextbuf = 0;
|
static int nextbuf = 0;
|
||||||
|
|
||||||
char *ibuf = idbuf[(++nextbuf) % 8];
|
char *ibuf = idbuf[(++nextbuf) % 8];
|
||||||
|
|
||||||
if (f && f->name) {
|
if (f && f->name) {
|
||||||
slprintf(ibuf, sizeof(name), "%s (%s)", f->name, itoa36(f->no));
|
slprintf(ibuf, sizeof(name), "%s (%s)", f->name, itoa36(f->no));
|
||||||
} else {
|
}
|
||||||
strcpy(ibuf, "Unbekannte Partei (?)");
|
else {
|
||||||
}
|
strcpy(ibuf, "Unbekannte Partei (?)");
|
||||||
return ibuf;
|
}
|
||||||
|
return ibuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
int resolve_faction(variant id, void *address)
|
int resolve_faction(variant id, void *address)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
faction *f = NULL;
|
faction *f = NULL;
|
||||||
if (id.i != 0) {
|
if (id.i != 0) {
|
||||||
f = findfaction(id.i);
|
f = findfaction(id.i);
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
result = -1;
|
result = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
*(faction **)address = f;
|
||||||
*(faction **) address = f;
|
return result;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_FACTION_ID (36*36*36*36)
|
#define MAX_FACTION_ID (36*36*36*36)
|
||||||
|
|
||||||
static int unused_faction_id(void)
|
static int unused_faction_id(void)
|
||||||
{
|
{
|
||||||
int id = rng_int() % MAX_FACTION_ID;
|
int id = rng_int() % MAX_FACTION_ID;
|
||||||
|
|
||||||
while (!faction_id_is_unused(id)) {
|
while (!faction_id_is_unused(id)) {
|
||||||
id++;
|
id++;
|
||||||
if (id == MAX_FACTION_ID)
|
if (id == MAX_FACTION_ID)
|
||||||
id = 0;
|
id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
faction *addfaction(const char *email, const char *password,
|
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)
|
||||||
{
|
{
|
||||||
faction *f = calloc(sizeof(faction), 1);
|
faction *f = calloc(sizeof(faction), 1);
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
|
||||||
assert(frace);
|
assert(frace);
|
||||||
|
|
||||||
|
if (set_email(&f->email, email) != 0) {
|
||||||
|
log_error("Invalid email address for faction %s: %s\n", itoa36(f->no), email);
|
||||||
|
}
|
||||||
|
|
||||||
if (set_email(&f->email, email) != 0) {
|
faction_setpassword(f, password);
|
||||||
log_error("Invalid email address for faction %s: %s\n", itoa36(f->no), email);
|
|
||||||
}
|
|
||||||
|
|
||||||
faction_setpassword(f, password);
|
f->alliance_joindate = turn;
|
||||||
|
f->lastorders = turn;
|
||||||
|
f->alive = 1;
|
||||||
|
f->age = 0;
|
||||||
|
f->race = frace;
|
||||||
|
f->magiegebiet = 0;
|
||||||
|
f->locale = loc;
|
||||||
|
f->subscription = subscription;
|
||||||
|
|
||||||
f->alliance_joindate = turn;
|
f->options =
|
||||||
f->lastorders = turn;
|
want(O_REPORT) | want(O_ZUGVORLAGE) | want(O_COMPUTER) | want(O_COMPRESS) |
|
||||||
f->alive = 1;
|
want(O_ADRESSEN) | want(O_STATISTICS);
|
||||||
f->age = 0;
|
|
||||||
f->race = frace;
|
|
||||||
f->magiegebiet = 0;
|
|
||||||
f->locale = loc;
|
|
||||||
f->subscription = subscription;
|
|
||||||
|
|
||||||
f->options =
|
f->no = unused_faction_id();
|
||||||
want(O_REPORT) | want(O_ZUGVORLAGE) | want(O_COMPUTER) | want(O_COMPRESS) |
|
if (rule_region_owners()) {
|
||||||
want(O_ADRESSEN) | want(O_STATISTICS);
|
alliance *al = makealliance(f->no, NULL);
|
||||||
|
setalliance(f, al);
|
||||||
|
}
|
||||||
|
addlist(&factions, f);
|
||||||
|
fhash(f);
|
||||||
|
|
||||||
f->no = unused_faction_id();
|
slprintf(buf, sizeof(buf), "%s %s", LOC(loc, "factiondefault"), factionid(f));
|
||||||
if (rule_region_owners()) {
|
f->name = _strdup(buf);
|
||||||
alliance *al = makealliance(f->no, NULL);
|
|
||||||
setalliance(f, al);
|
|
||||||
}
|
|
||||||
addlist(&factions, f);
|
|
||||||
fhash(f);
|
|
||||||
|
|
||||||
slprintf(buf, sizeof(buf), "%s %s", LOC(loc, "factiondefault"), factionid(f));
|
if (!f->race) {
|
||||||
f->name = _strdup(buf);
|
log_warning("creating a faction that has no race", factionid(f));
|
||||||
|
}
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
unit *addplayer(region * r, faction * f)
|
unit *addplayer(region * r, faction * f)
|
||||||
{
|
{
|
||||||
unit *u;
|
unit *u;
|
||||||
char buffer[32];
|
char buffer[32];
|
||||||
|
|
||||||
assert(f->units == NULL);
|
assert(f->units == NULL);
|
||||||
set_ursprung(f, 0, r->x, r->y);
|
set_ursprung(f, 0, r->x, r->y);
|
||||||
u = createunit(r, f, 1, f->race);
|
u = createunit(r, f, 1, f->race);
|
||||||
equip_items(&u->faction->items, get_equipment("new_faction"));
|
equip_items(&u->faction->items, get_equipment("new_faction"));
|
||||||
equip_unit(u, get_equipment("first_unit"));
|
equip_unit(u, get_equipment("first_unit"));
|
||||||
sprintf(buffer, "first_%s", u_race(u)->_name[0]);
|
sprintf(buffer, "first_%s", u_race(u)->_name[0]);
|
||||||
equip_unit(u, get_equipment(buffer));
|
equip_unit(u, get_equipment(buffer));
|
||||||
u->hp = unit_max_hp(u) * u->number;
|
u->hp = unit_max_hp(u) * u->number;
|
||||||
fset(u, UFL_ISNEW);
|
fset(u, UFL_ISNEW);
|
||||||
if (f->race == get_race(RC_DAEMON)) {
|
if (f->race == get_race(RC_DAEMON)) {
|
||||||
race_t urc;
|
race_t urc;
|
||||||
race *rc;
|
race *rc;
|
||||||
do {
|
do {
|
||||||
urc = (race_t) (rng_int() % MAXRACES);
|
urc = (race_t)(rng_int() % MAXRACES);
|
||||||
rc = get_race(urc);
|
rc = get_race(urc);
|
||||||
} while (rc == NULL || urc == RC_DAEMON || !playerrace(rc));
|
} while (rc == NULL || urc == RC_DAEMON || !playerrace(rc));
|
||||||
u->irace = rc;
|
u->irace = rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkpasswd(const faction * f, const char *passwd, bool shortp)
|
bool checkpasswd(const faction * f, const char *passwd, bool shortp)
|
||||||
{
|
{
|
||||||
if (unicode_utf8_strcasecmp(f->passw, passwd) == 0)
|
if (unicode_utf8_strcasecmp(f->passw, passwd) == 0)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
variant read_faction_reference(struct storage * store)
|
variant read_faction_reference(struct storage * store)
|
||||||
{
|
{
|
||||||
variant id;
|
variant id;
|
||||||
READ_INT(store, &id.i);
|
READ_INT(store, &id.i);
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
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->no : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroyfaction(faction * f)
|
void destroyfaction(faction * f)
|
||||||
{
|
{
|
||||||
unit *u = f->units;
|
unit *u = f->units;
|
||||||
faction *ff;
|
faction *ff;
|
||||||
|
|
||||||
if (!f->alive) {
|
if (!f->alive) {
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
fset(f, FFL_QUIT);
|
|
||||||
|
|
||||||
if (f->spellbook) {
|
|
||||||
spellbook_clear(f->spellbook);
|
|
||||||
free(f->spellbook);
|
|
||||||
f->spellbook = 0;
|
|
||||||
}
|
|
||||||
while (f->battles) {
|
|
||||||
struct bmsg *bm = f->battles;
|
|
||||||
f->battles = bm->next;
|
|
||||||
if (bm->msgs) {
|
|
||||||
free_messagelist(bm->msgs);
|
|
||||||
}
|
}
|
||||||
free(bm);
|
fset(f, FFL_QUIT);
|
||||||
}
|
|
||||||
|
|
||||||
while (u) {
|
if (f->spellbook) {
|
||||||
/* give away your stuff, make zombies if you cannot (quest items) */
|
spellbook_clear(f->spellbook);
|
||||||
int result = gift_items(u, GIFT_FRIENDS | GIFT_PEASANTS);
|
free(f->spellbook);
|
||||||
if (result != 0) {
|
f->spellbook = 0;
|
||||||
unit *zombie = u;
|
}
|
||||||
u = u->nextF;
|
while (f->battles) {
|
||||||
make_zombie(zombie);
|
struct bmsg *bm = f->battles;
|
||||||
} else {
|
f->battles = bm->next;
|
||||||
region *r = u->region;
|
if (bm->msgs) {
|
||||||
|
free_messagelist(bm->msgs);
|
||||||
|
}
|
||||||
|
free(bm);
|
||||||
|
}
|
||||||
|
|
||||||
if (!fval(r->terrain, SEA_REGION) && !!playerrace(u_race(u))) {
|
while (u) {
|
||||||
const race *rc = u_race(u);
|
/* give away your stuff, make zombies if you cannot (quest items) */
|
||||||
int m = rmoney(r);
|
int result = gift_items(u, GIFT_FRIENDS | GIFT_PEASANTS);
|
||||||
|
if (result != 0) {
|
||||||
|
unit *zombie = u;
|
||||||
|
u = u->nextF;
|
||||||
|
make_zombie(zombie);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
region *r = u->region;
|
||||||
|
|
||||||
if ((rc->ec_flags & ECF_REC_ETHEREAL) == 0) {
|
if (!fval(r->terrain, SEA_REGION) && !!playerrace(u_race(u))) {
|
||||||
int p = rpeasants(u->region);
|
const race *rc = u_race(u);
|
||||||
int h = rhorses(u->region);
|
int m = rmoney(r);
|
||||||
item *itm;
|
|
||||||
|
|
||||||
/* Personen gehen nur an die Bauern, wenn sie auch von dort
|
if ((rc->ec_flags & ECF_REC_ETHEREAL) == 0) {
|
||||||
* stammen */
|
int p = rpeasants(u->region);
|
||||||
if (rc->ec_flags & ECF_REC_HORSES) { /* Zentauren an die Pferde */
|
int h = rhorses(u->region);
|
||||||
h += u->number;
|
item *itm;
|
||||||
} else { /* Orks zählen nur zur Hälfte */
|
|
||||||
p += (int)(u->number * rc->recruit_multi);
|
/* Personen gehen nur an die Bauern, wenn sie auch von dort
|
||||||
}
|
* stammen */
|
||||||
for (itm = u->items; itm; itm = itm->next) {
|
if (rc->ec_flags & ECF_REC_HORSES) { /* Zentauren an die Pferde */
|
||||||
if (itm->type->flags & ITF_ANIMAL) {
|
h += u->number;
|
||||||
h += itm->number;
|
}
|
||||||
|
else { /* Orks zählen nur zur Hälfte */
|
||||||
|
p += (int)(u->number * rc->recruit_multi);
|
||||||
|
}
|
||||||
|
for (itm = u->items; itm; itm = itm->next) {
|
||||||
|
if (itm->type->flags & ITF_ANIMAL) {
|
||||||
|
h += itm->number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rsetpeasants(r, p);
|
||||||
|
rsethorses(r, h);
|
||||||
|
}
|
||||||
|
m += get_money(u);
|
||||||
|
rsetmoney(r, m);
|
||||||
}
|
}
|
||||||
}
|
set_number(u, 0);
|
||||||
rsetpeasants(r, p);
|
u = u->nextF;
|
||||||
rsethorses(r, h);
|
|
||||||
}
|
}
|
||||||
m += get_money(u);
|
|
||||||
rsetmoney(r, m);
|
|
||||||
}
|
|
||||||
set_number(u, 0);
|
|
||||||
u = u->nextF;
|
|
||||||
}
|
}
|
||||||
}
|
f->alive = 0;
|
||||||
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, *sfn;
|
|
||||||
|
|
||||||
/* Alle HELFE für die Partei löschen */
|
/* Alle HELFE für die Partei löschen */
|
||||||
for (sf = ff->allies; sf; sf = sf->next) {
|
for (sf = ff->allies; sf; sf = sf->next) {
|
||||||
if (sf->faction == f) {
|
if (sf->faction == f) {
|
||||||
removelist(&ff->allies, sf);
|
removelist(&ff->allies, sf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (g = ff->groups; g; g = g->next) {
|
for (g = ff->groups; g; g = g->next) {
|
||||||
for (sf = g->allies; sf;) {
|
for (sf = g->allies; sf;) {
|
||||||
sfn = sf->next;
|
sfn = sf->next;
|
||||||
if (sf->faction == f) {
|
if (sf->faction == f) {
|
||||||
removelist(&g->allies, sf);
|
removelist(&g->allies, sf);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
sf = sfn;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sf = sfn;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* 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_faction()) {
|
if (rule_stealth_faction()) {
|
||||||
region *rc;
|
region *rc;
|
||||||
for (rc = regions; rc; rc = rc->next) {
|
for (rc = regions; rc; rc = rc->next) {
|
||||||
for (u = rc->units; u; u = u->next) {
|
for (u = rc->units; u; u = u->next) {
|
||||||
attrib *a = a_find(u->attribs, &at_otherfaction);
|
attrib *a = a_find(u->attribs, &at_otherfaction);
|
||||||
if (!a)
|
if (!a)
|
||||||
continue;
|
continue;
|
||||||
if (get_otherfaction(a) == f) {
|
if (get_otherfaction(a) == f) {
|
||||||
a_removeall(&u->attribs, &at_otherfaction);
|
a_removeall(&u->attribs, &at_otherfaction);
|
||||||
fset(u, UFL_ANON_FACTION);
|
fset(u, UFL_ANON_FACTION);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_alliance(const faction * a, const faction * b)
|
int get_alliance(const faction * a, const faction * b)
|
||||||
{
|
{
|
||||||
const ally *sf = a->allies;
|
const ally *sf = a->allies;
|
||||||
for (; sf != NULL; sf = sf->next) {
|
for (; sf != NULL; sf = sf->next) {
|
||||||
if (sf->faction == b) {
|
if (sf->faction == b) {
|
||||||
return sf->status;
|
return sf->status;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_alliance(faction * a, faction * b, int status)
|
void set_alliance(faction * a, faction * b, int status)
|
||||||
{
|
{
|
||||||
ally **sfp;
|
ally **sfp;
|
||||||
sfp = &a->allies;
|
sfp = &a->allies;
|
||||||
while (*sfp) {
|
while (*sfp) {
|
||||||
ally *sf = *sfp;
|
ally *sf = *sfp;
|
||||||
if (sf->faction == b)
|
if (sf->faction == b)
|
||||||
break;
|
break;
|
||||||
sfp = &sf->next;
|
sfp = &sf->next;
|
||||||
}
|
}
|
||||||
if (*sfp == NULL) {
|
if (*sfp == NULL) {
|
||||||
ally *sf = *sfp = malloc(sizeof(ally));
|
ally *sf = *sfp = malloc(sizeof(ally));
|
||||||
sf->next = NULL;
|
sf->next = NULL;
|
||||||
sf->status = status;
|
sf->status = status;
|
||||||
sf->faction = b;
|
sf->faction = b;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
(*sfp)->status |= status;
|
(*sfp)->status |= status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void renumber_faction(faction * f, int no)
|
void renumber_faction(faction * f, int no)
|
||||||
{
|
{
|
||||||
funhash(f);
|
funhash(f);
|
||||||
f->no = no;
|
f->no = no;
|
||||||
fhash(f);
|
fhash(f);
|
||||||
fset(f, FFL_NEWID);
|
fset(f, FFL_NEWID);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SMART_INTERVALS
|
#ifdef SMART_INTERVALS
|
||||||
void update_interval(struct faction *f, struct region *r)
|
void update_interval(struct faction *f, struct region *r)
|
||||||
{
|
{
|
||||||
if (r == NULL || f == NULL)
|
if (r == NULL || f == NULL)
|
||||||
return;
|
return;
|
||||||
if (f->first == NULL || f->first->index > r->index) {
|
if (f->first == NULL || f->first->index > r->index) {
|
||||||
f->first = r;
|
f->first = r;
|
||||||
}
|
}
|
||||||
if (f->last == NULL || f->last->index <= r->index) {
|
if (f->last == NULL || f->last->index <= r->index) {
|
||||||
f->last = r;
|
f->last = r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char *faction_getname(const faction * self)
|
const char *faction_getname(const faction * self)
|
||||||
{
|
{
|
||||||
return self->name ? self->name : "";
|
return self->name ? self->name : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void faction_setname(faction * self, const char *name)
|
void faction_setname(faction * self, const char *name)
|
||||||
{
|
{
|
||||||
free(self->name);
|
free(self->name);
|
||||||
if (name)
|
if (name)
|
||||||
self->name = _strdup(name);
|
self->name = _strdup(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *faction_getemail(const faction * self)
|
const char *faction_getemail(const faction * self)
|
||||||
{
|
{
|
||||||
return self->email ? self->email : "";
|
return self->email ? self->email : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void faction_setemail(faction * self, const char *email)
|
void faction_setemail(faction * self, const char *email)
|
||||||
{
|
{
|
||||||
free(self->email);
|
free(self->email);
|
||||||
if (email)
|
if (email)
|
||||||
self->email = _strdup(email);
|
self->email = _strdup(email);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *faction_getbanner(const faction * self)
|
const char *faction_getbanner(const faction * self)
|
||||||
{
|
{
|
||||||
return self->banner ? self->banner : "";
|
return self->banner ? self->banner : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void faction_setbanner(faction * self, const char *banner)
|
void faction_setbanner(faction * self, const char *banner)
|
||||||
{
|
{
|
||||||
free(self->banner);
|
free(self->banner);
|
||||||
if (banner)
|
if (banner)
|
||||||
self->banner = _strdup(banner);
|
self->banner = _strdup(banner);
|
||||||
}
|
}
|
||||||
|
|
||||||
void faction_setpassword(faction * f, const char *passw)
|
void faction_setpassword(faction * f, const char *passw)
|
||||||
{
|
{
|
||||||
free(f->passw);
|
free(f->passw);
|
||||||
if (passw)
|
if (passw)
|
||||||
f->passw = _strdup(passw);
|
f->passw = _strdup(passw);
|
||||||
else
|
else
|
||||||
f->passw = _strdup(itoa36(rng_int()));
|
f->passw = _strdup(itoa36(rng_int()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool valid_race(const struct faction *f, const struct race *rc)
|
bool valid_race(const struct faction *f, const struct race *rc)
|
||||||
{
|
{
|
||||||
if (f->race == rc)
|
if (f->race == rc)
|
||||||
return true;
|
return true;
|
||||||
else {
|
else {
|
||||||
const char *str = get_param(f->race->parameters, "other_race");
|
const char *str = get_param(f->race->parameters, "other_race");
|
||||||
if (str)
|
if (str)
|
||||||
return (bool) (rc_find(str) == rc);
|
return (bool)(rc_find(str) == rc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *faction_getpassword(const faction * f)
|
const char *faction_getpassword(const faction * f)
|
||||||
{
|
{
|
||||||
return f->passw;
|
return f->passw;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct alliance *f_get_alliance(const struct faction *f)
|
struct alliance *f_get_alliance(const struct faction *f)
|
||||||
{
|
{
|
||||||
if (f->alliance && !(f->alliance->flags & ALF_NON_ALLIED)) {
|
if (f->alliance && !(f->alliance->flags & ALF_NON_ALLIED)) {
|
||||||
return f->alliance;
|
return f->alliance;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct spellbook * faction_get_spellbook(struct faction *f)
|
struct spellbook * faction_get_spellbook(struct faction *f)
|
||||||
{
|
{
|
||||||
if (f->spellbook) {
|
if (f->spellbook) {
|
||||||
return f->spellbook;
|
return f->spellbook;
|
||||||
}
|
}
|
||||||
if (f->magiegebiet!=M_GRAY) {
|
if (f->magiegebiet != M_GRAY) {
|
||||||
return get_spellbook(magic_school[f->magiegebiet]);
|
return get_spellbook(magic_school[f->magiegebiet]);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int allied_skillcount(const faction * f, skill_t sk)
|
static int allied_skillcount(const faction * f, skill_t sk)
|
||||||
{
|
{
|
||||||
int num = 0;
|
int num = 0;
|
||||||
alliance *a = f_get_alliance(f);
|
alliance *a = f_get_alliance(f);
|
||||||
quicklist *members = a->members;
|
quicklist *members = a->members;
|
||||||
int qi;
|
int qi;
|
||||||
|
|
||||||
for (qi = 0; members; ql_advance(&members, &qi, 1)) {
|
for (qi = 0; members; ql_advance(&members, &qi, 1)) {
|
||||||
faction *m = (faction *) ql_get(members, qi);
|
faction *m = (faction *)ql_get(members, qi);
|
||||||
num += count_skill(m, sk);
|
num += count_skill(m, sk);
|
||||||
}
|
}
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int allied_skilllimit(const faction * f, skill_t sk)
|
static int allied_skilllimit(const faction * f, skill_t sk)
|
||||||
{
|
{
|
||||||
static int value = -1;
|
static int value = -1;
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
value = get_param_int(global.parameters, "alliance.skilllimit", 0);
|
value = get_param_int(global.parameters, "alliance.skilllimit", 0);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
int count_skill(faction * f, skill_t sk)
|
int count_skill(faction * f, skill_t sk)
|
||||||
{
|
{
|
||||||
int n = 0;
|
int n = 0;
|
||||||
unit *u;
|
unit *u;
|
||||||
|
|
||||||
for (u = f->units; u; u = u->nextF) {
|
for (u = f->units; u; u = u->nextF) {
|
||||||
if (has_skill(u, sk)) {
|
if (has_skill(u, sk)) {
|
||||||
if (!is_familiar(u)) {
|
if (!is_familiar(u)) {
|
||||||
n += u->number;
|
n += u->number;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return n;
|
||||||
return n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int skill_limit(faction * f, skill_t sk)
|
int skill_limit(faction * f, skill_t sk)
|
||||||
{
|
{
|
||||||
int m = INT_MAX;
|
int m = INT_MAX;
|
||||||
int al = allied_skilllimit(f, sk);
|
int al = allied_skilllimit(f, sk);
|
||||||
if (al > 0) {
|
if (al > 0) {
|
||||||
if (sk != SK_ALCHEMY && sk != SK_MAGIC)
|
if (sk != SK_ALCHEMY && sk != SK_MAGIC)
|
||||||
return INT_MAX;
|
return INT_MAX;
|
||||||
if (f_get_alliance(f)) {
|
if (f_get_alliance(f)) {
|
||||||
int ac = listlen(f->alliance->members); /* number of factions */
|
int ac = listlen(f->alliance->members); /* number of factions */
|
||||||
int fl = (al + ac - 1) / ac; /* faction limit, rounded up */
|
int fl = (al + ac - 1) / ac; /* faction limit, rounded up */
|
||||||
/* the faction limit may not be achievable because it would break the alliance-limit */
|
/* the faction limit may not be achievable because it would break the alliance-limit */
|
||||||
int sc = al - allied_skillcount(f, sk);
|
int sc = al - allied_skillcount(f, sk);
|
||||||
if (sc <= 0)
|
if (sc <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
return fl;
|
return fl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (sk == SK_MAGIC) {
|
||||||
if (sk == SK_MAGIC) {
|
m = max_magicians(f);
|
||||||
m = max_magicians(f);
|
}
|
||||||
} else if (sk == SK_ALCHEMY) {
|
else if (sk == SK_ALCHEMY) {
|
||||||
m = get_param_int(global.parameters, "rules.maxskills.alchemy",
|
m = get_param_int(global.parameters, "rules.maxskills.alchemy",
|
||||||
MAXALCHEMISTS);
|
MAXALCHEMISTS);
|
||||||
}
|
}
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,7 @@ typedef struct faction {
|
||||||
extern struct faction *factions;
|
extern struct faction *factions;
|
||||||
|
|
||||||
struct faction *get_monsters(void);
|
struct faction *get_monsters(void);
|
||||||
|
struct faction *get_or_create_monsters(void);
|
||||||
int max_magicians(const faction * f);
|
int max_magicians(const faction * f);
|
||||||
void set_show_item(faction * f, const struct item_type *itype);
|
void set_show_item(faction * f, const struct item_type *itype);
|
||||||
|
|
||||||
|
|
|
@ -889,7 +889,7 @@ static int nrand(int start, int sub)
|
||||||
void spawn_dragons(void)
|
void spawn_dragons(void)
|
||||||
{
|
{
|
||||||
region *r;
|
region *r;
|
||||||
faction *monsters = get_monsters();
|
faction *monsters = get_or_create_monsters();
|
||||||
|
|
||||||
for (r = regions; r; r = r->next) {
|
for (r = regions; r; r = r->next) {
|
||||||
unit *u;
|
unit *u;
|
||||||
|
|
Loading…
Reference in New Issue