forked from github/server
- new alliances + commands
This commit is contained in:
parent
71b34b434a
commit
f9946ff7f8
7 changed files with 425 additions and 202 deletions
|
@ -3772,9 +3772,9 @@ init_processor(void)
|
||||||
add_proc_order(p, K_WEREWOLF, &setwere_cmd, 0, NULL);
|
add_proc_order(p, K_WEREWOLF, &setwere_cmd, 0, NULL);
|
||||||
#endif /* KARMA_MODULE */
|
#endif /* KARMA_MODULE */
|
||||||
|
|
||||||
if (get_param_int(global.parameters, "alliance-vinyambar", 0)==1) {
|
if (get_param_int(global.parameters, "rules.alliances", 0)==1) {
|
||||||
p+=10;
|
p+=10;
|
||||||
add_proc_global(p, &alliancekick, NULL);
|
add_proc_global(p, &alliance_cmd, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
p+=10;
|
p+=10;
|
||||||
|
@ -3785,11 +3785,6 @@ init_processor(void)
|
||||||
add_proc_region(p, &enter_1, "Kontaktieren & Betreten (1. Versuch)");
|
add_proc_region(p, &enter_1, "Kontaktieren & Betreten (1. Versuch)");
|
||||||
add_proc_order(p, K_USE, &use_cmd, 0, "Benutzen");
|
add_proc_order(p, K_USE, &use_cmd, 0, "Benutzen");
|
||||||
|
|
||||||
if (get_param_int(global.parameters, "alliance-vinyambar", 0)==1) {
|
|
||||||
p+=10; /* in case USE changes it */
|
|
||||||
add_proc_global(p, &alliancevictory, "Testen der Allianzbedingungen");
|
|
||||||
}
|
|
||||||
|
|
||||||
#if INFOCMD_MODULE
|
#if INFOCMD_MODULE
|
||||||
if (!global.disabled[K_INFO]) {
|
if (!global.disabled[K_INFO]) {
|
||||||
add_proc_global(p, &infocommands, NULL);
|
add_proc_global(p, &infocommands, NULL);
|
||||||
|
@ -3895,10 +3890,6 @@ init_processor(void)
|
||||||
#if KARMA_MODULE
|
#if KARMA_MODULE
|
||||||
p+=10;
|
p+=10;
|
||||||
add_proc_global(p, &karma, "Jihads setzen");
|
add_proc_global(p, &karma, "Jihads setzen");
|
||||||
#endif
|
|
||||||
#ifdef ALLIANCEJOIN
|
|
||||||
p+=10;
|
|
||||||
add_proc_global(p, &alliancejoin, "Allianzen");
|
|
||||||
#endif
|
#endif
|
||||||
add_proc_order(p, K_PROMOTION, &promotion_cmd, 0, "Heldenbefoerderung");
|
add_proc_order(p, K_PROMOTION, &promotion_cmd, 0, "Heldenbefoerderung");
|
||||||
if (!global.disabled[K_NUMBER]) {
|
if (!global.disabled[K_NUMBER]) {
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
/* vi: set ts=2:
|
/* vi: set ts=2:
|
||||||
+-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de>
|
+-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||||
| | Enno Rehling <enno@eressea.de>
|
| | Enno Rehling <enno@eressea.de>
|
||||||
| Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de>
|
| Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de>
|
||||||
| (c) 1998 - 2003 | Henning Peters <faroul@beyond.kn-bremen.de>
|
| (c) 1998 - 2003 | Henning Peters <faroul@beyond.kn-bremen.de>
|
||||||
| | Ingo Wilken <Ingo.Wilken@informatik.uni-oldenburg.de>
|
| | Ingo Wilken <Ingo.Wilken@informatik.uni-oldenburg.de>
|
||||||
+-------------------+ Stefan Reich <reich@halbling.de>
|
+-------------------+ Stefan Reich <reich@halbling.de>
|
||||||
|
|
||||||
This program may not be used, modified or distributed
|
This program may not be used, modified or distributed
|
||||||
without prior permission by the authors of Eressea.
|
without prior permission by the authors of Eressea.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma region includes
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <kernel/eressea.h>
|
#include <kernel/eressea.h>
|
||||||
#include "alliance.h"
|
#include "alliance.h"
|
||||||
|
@ -32,6 +34,7 @@
|
||||||
#include <util/lists.h>
|
#include <util/lists.h>
|
||||||
#include <util/language.h>
|
#include <util/language.h>
|
||||||
#include <util/parser.h>
|
#include <util/parser.h>
|
||||||
|
#include <util/rng.h>
|
||||||
#include <util/umlaut.h>
|
#include <util/umlaut.h>
|
||||||
|
|
||||||
/* libc includes */
|
/* libc includes */
|
||||||
|
@ -39,192 +42,389 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
alliance * alliances = NULL;
|
alliance * alliances = NULL;
|
||||||
|
|
||||||
alliance *
|
alliance *
|
||||||
makealliance(int id, const char * name)
|
makealliance(int id, const char * name)
|
||||||
{
|
{
|
||||||
alliance * al = calloc(1, sizeof(alliance));
|
alliance * al = calloc(1, sizeof(alliance));
|
||||||
al->id=id;
|
al->id=id;
|
||||||
al->name=strdup(name);
|
al->name=strdup(name);
|
||||||
al->next=alliances;
|
al->next=alliances;
|
||||||
return alliances=al;
|
return alliances=al;
|
||||||
}
|
}
|
||||||
|
|
||||||
alliance *
|
alliance *
|
||||||
findalliance(int id)
|
findalliance(int id)
|
||||||
{
|
{
|
||||||
alliance * al;
|
alliance * al;
|
||||||
for (al=alliances;al;al=al->next) {
|
for (al=alliances;al;al=al->next) {
|
||||||
if (al->id==id) return al;
|
if (al->id==id) return al;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy_kick(struct attrib * a)
|
typedef struct alliance_transaction {
|
||||||
|
struct alliance_transaction * next;
|
||||||
|
unit * u;
|
||||||
|
variant userdata;
|
||||||
|
order * ord;
|
||||||
|
} alliance_transaction;
|
||||||
|
|
||||||
|
static faction * alliance_leader(const alliance * al)
|
||||||
{
|
{
|
||||||
faction_list * flist = (faction_list*)a->data.v;
|
return al->leader;
|
||||||
freelist(flist);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const attrib_type at_kick = { "kick",
|
static alliance_transaction **
|
||||||
DEFAULT_INIT, destroy_kick
|
get_transaction(alliance * al, const variant * userdata, int type)
|
||||||
};
|
|
||||||
|
|
||||||
static attrib *
|
|
||||||
make_kick(void)
|
|
||||||
{
|
{
|
||||||
return a_new(&at_kick);
|
alliance_transaction ** tap=al->transactions+type;
|
||||||
|
while (*tap) {
|
||||||
|
alliance_transaction * ta = *tap;
|
||||||
|
if (userdata==NULL || memcmp(&ta->userdata, userdata, sizeof(variant))==0) {
|
||||||
|
return tap;
|
||||||
|
}
|
||||||
|
tap = &ta->next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_kick(attrib * a, faction * f)
|
create_transaction(alliance * al, int type, const variant * userdata, unit * u, order * ord)
|
||||||
{
|
{
|
||||||
faction_list * flist = (faction_list*)a->data.v;
|
alliance_transaction * tr = malloc(sizeof(alliance_transaction));
|
||||||
while (flist && flist->data!=f) flist = flist->next;
|
memcpy(&tr->userdata, userdata, sizeof(variant));
|
||||||
if (flist) return;
|
tr->ord = ord;
|
||||||
flist = calloc(1, sizeof(faction_list));
|
tr->next = al->transactions[type];
|
||||||
flist->data = (void*)f;
|
al->transactions[type] = tr;
|
||||||
flist->next = (faction_list*)a->data.v;
|
|
||||||
a->data.v = flist;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
alliance_kick(const tnode * tnext, void * data, struct order * ord)
|
cmd_kick(const tnode * tnext, void * data, struct order * ord)
|
||||||
{
|
{
|
||||||
unit * u = (unit*)data;
|
unit * u = (unit*)data;
|
||||||
|
alliance * al = u->faction->alliance;
|
||||||
faction * f = findfaction(getid());
|
faction * f = findfaction(getid());
|
||||||
attrib * a;
|
unused(tnext);
|
||||||
|
|
||||||
if (f==NULL || f->alliance!=u->faction->alliance) {
|
if (f && al && u->faction==alliance_leader(al)) {
|
||||||
/* does not belong to our alliance */
|
static variant var;
|
||||||
|
var.v = f;
|
||||||
|
create_transaction(al, ALLIANCE_KICK, &var, u, ord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_leave(const tnode * tnext, void * data, struct order * ord)
|
||||||
|
{
|
||||||
|
unit * u = (unit*)data;
|
||||||
|
alliance * al = u->faction->alliance;
|
||||||
|
unused(tnext);
|
||||||
|
|
||||||
|
if (al) {
|
||||||
|
create_transaction(al, ALLIANCE_LEAVE, NULL, u, ord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_transfer(const tnode * tnext, void * data, struct order * ord)
|
||||||
|
{
|
||||||
|
unit * u = (unit*)data;
|
||||||
|
alliance * al = u->faction->alliance;
|
||||||
|
faction * f = findfaction(getid());
|
||||||
|
unused(tnext);
|
||||||
|
|
||||||
|
if (f && al && f->alliance==al && u->faction==alliance_leader(al)) {
|
||||||
|
static variant var;
|
||||||
|
var.v = f;
|
||||||
|
create_transaction(al, ALLIANCE_TRANSFER, &var, u, ord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_new(const tnode * tnext, void * data, struct order * ord)
|
||||||
|
{
|
||||||
|
unit * u = (unit*)data;
|
||||||
|
alliance * al = u->faction->alliance;
|
||||||
|
unused(tnext);
|
||||||
|
|
||||||
|
if (al && u->faction==alliance_leader(al)) {
|
||||||
|
static variant var;
|
||||||
|
const char * str = getstrtoken();
|
||||||
|
|
||||||
|
var.i = str?atoi36(str):0;
|
||||||
|
create_transaction(al, ALLIANCE_NEW, &var, u, ord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_invite(const tnode * tnext, void * data, struct order * ord)
|
||||||
|
{
|
||||||
|
unit * u = (unit*)data;
|
||||||
|
alliance * al = u->faction->alliance;
|
||||||
|
faction * f = findfaction(getid());
|
||||||
|
unused(tnext);
|
||||||
|
|
||||||
|
if (f==NULL || al==NULL) {
|
||||||
|
/* TODO: error message */
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
static variant var;
|
||||||
|
var.v = f;
|
||||||
|
create_transaction(al, ALLIANCE_INVITE, &var, u, ord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_join(const tnode * tnext, void * data, struct order * ord)
|
||||||
|
{
|
||||||
|
unit * u = (unit*)data;
|
||||||
|
alliance * al = findalliance(getid());
|
||||||
|
unused(tnext);
|
||||||
|
|
||||||
|
if (u->faction->alliance==al || al==NULL) {
|
||||||
|
/* TODO: error message */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
a = a_find(f->attribs, &at_kick);
|
|
||||||
if (a==NULL) a = a_add(&f->attribs, make_kick());
|
create_transaction(al, ALLIANCE_JOIN, NULL, u, ord);
|
||||||
add_kick(a, f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
alliance_join(const tnode * tnext, void * data, struct order * ord)
|
perform_kick(alliance * al)
|
||||||
{
|
{
|
||||||
unit * u = (unit*)data;
|
alliance_transaction ** tap = al->transactions+ALLIANCE_KICK;
|
||||||
alliance * al = findalliance(getid());
|
while (*tap) {
|
||||||
unused(tnext);
|
alliance_transaction * ta = *tap;
|
||||||
|
faction * f = ta->u->faction;
|
||||||
if (u->faction->alliance!=NULL || al==NULL) {
|
setalliance(f, NULL);
|
||||||
/* not found */
|
*tap = ta->next;
|
||||||
return;
|
free(ta);
|
||||||
}
|
}
|
||||||
u->faction->alliance = al;
|
|
||||||
/* inform the rest? */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
execute(const struct syntaxtree * syntax)
|
perform_new(alliance * al)
|
||||||
{
|
{
|
||||||
region ** rp = ®ions;
|
alliance_transaction ** tap = al->transactions+ALLIANCE_LEAVE;
|
||||||
while (*rp) {
|
while (*tap) {
|
||||||
region * r = *rp;
|
alliance * al;
|
||||||
unit **up = &r->units;
|
alliance_transaction * ta = *tap;
|
||||||
while (*up) {
|
faction * f = ta->u->faction;
|
||||||
unit * u = *up;
|
int id = ta->userdata.i;
|
||||||
const struct locale * lang = u->faction->locale;
|
|
||||||
tnode * root = stree_find(syntax, lang);
|
do {
|
||||||
order * ord;
|
id = id?id:(1 + (rng_int() % MAX_UNIT_NR));
|
||||||
for (ord = u->orders; ord; ord = ord->next) {
|
for (al=alliances;al;al=al->next) {
|
||||||
if (get_keyword(ord) == K_ALLIANCE) {
|
if (al->id==id) {
|
||||||
do_command(root, u, ord);
|
id = 0;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
if (u==*up) up = &u->next;
|
}
|
||||||
}
|
} while (id==0);
|
||||||
if (*rp==r) rp = &r->next;
|
|
||||||
}
|
al = calloc(1, sizeof(alliance));
|
||||||
|
al->id = id;
|
||||||
|
setalliance(f, al);
|
||||||
|
|
||||||
|
*tap = ta->next;
|
||||||
|
free(ta);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
perform_leave(alliance * al)
|
||||||
|
{
|
||||||
|
alliance_transaction ** tap = al->transactions+ALLIANCE_LEAVE;
|
||||||
|
while (*tap) {
|
||||||
|
alliance_transaction * ta = *tap;
|
||||||
|
faction * f = ta->u->faction;
|
||||||
|
|
||||||
|
setalliance(f, NULL);
|
||||||
|
|
||||||
|
*tap = ta->next;
|
||||||
|
free(ta);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
perform_transfer(alliance * al)
|
||||||
|
{
|
||||||
|
alliance_transaction ** tap = al->transactions+ALLIANCE_LEAVE;
|
||||||
|
while (*tap) {
|
||||||
|
alliance_transaction * ta = *tap;
|
||||||
|
faction * f = (faction *)ta->userdata.v;
|
||||||
|
|
||||||
|
assert(f->alliance==al);
|
||||||
|
|
||||||
|
al->leader = f;
|
||||||
|
|
||||||
|
*tap = ta->next;
|
||||||
|
free(ta);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
perform_join(alliance * al)
|
||||||
|
{
|
||||||
|
alliance_transaction ** tap = al->transactions+ALLIANCE_JOIN;
|
||||||
|
while (*tap) {
|
||||||
|
alliance_transaction * ta = *tap;
|
||||||
|
faction * f = ta->u->faction;
|
||||||
|
if (f->alliance!=al) {
|
||||||
|
alliance_transaction ** tip = al->transactions+ALLIANCE_INVITE;
|
||||||
|
alliance_transaction * ti = *tip;
|
||||||
|
while (ti) {
|
||||||
|
if (ti->userdata.v==f) break;
|
||||||
|
tip = &ti->next;
|
||||||
|
ti = *tip;
|
||||||
|
}
|
||||||
|
if (ti) {
|
||||||
|
setalliance(f, al);
|
||||||
|
*tip = ti->next;
|
||||||
|
free(ti);
|
||||||
|
} else {
|
||||||
|
/* TODO: error message */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*tap = ta->next;
|
||||||
|
free(ta);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
execute(const struct syntaxtree * syntax, keyword_t kwd)
|
||||||
|
{
|
||||||
|
int run = 0;
|
||||||
|
|
||||||
|
region ** rp = ®ions;
|
||||||
|
while (*rp) {
|
||||||
|
region * r = *rp;
|
||||||
|
unit **up = &r->units;
|
||||||
|
while (*up) {
|
||||||
|
unit * u = *up;
|
||||||
|
const struct locale * lang = u->faction->locale;
|
||||||
|
tnode * root = stree_find(syntax, lang);
|
||||||
|
order * ord;
|
||||||
|
for (ord = u->orders; ord; ord = ord->next) {
|
||||||
|
if (get_keyword(ord) == kwd) {
|
||||||
|
do_command(root, u, ord);
|
||||||
|
run = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (u==*up) up = &u->next;
|
||||||
|
}
|
||||||
|
if (*rp==r) rp = &r->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (run) {
|
||||||
|
alliance * al;
|
||||||
|
for (al=alliances;al;al=al->next) {
|
||||||
|
perform_kick(al);
|
||||||
|
}
|
||||||
|
for (al=alliances;al;al=al->next) {
|
||||||
|
perform_leave(al);
|
||||||
|
}
|
||||||
|
for (al=alliances;al;al=al->next) {
|
||||||
|
perform_transfer(al);
|
||||||
|
}
|
||||||
|
for (al=alliances;al;al=al->next) {
|
||||||
|
perform_new(al);
|
||||||
|
}
|
||||||
|
for (al=alliances;al;al=al->next) {
|
||||||
|
perform_join(al);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
alliancekick(void)
|
alliance_cmd(void)
|
||||||
{
|
{
|
||||||
static syntaxtree * stree = NULL;
|
static syntaxtree * stree = NULL;
|
||||||
faction * f = factions;
|
if (stree==NULL) {
|
||||||
if (stree==NULL) {
|
syntaxtree * slang = stree = stree_create();
|
||||||
syntaxtree * slang = stree = stree_create();
|
while (slang) {
|
||||||
while (slang) {
|
struct tnode * root = calloc(sizeof(tnode), 1);
|
||||||
struct tnode * root = calloc(sizeof(tnode), 1);
|
struct tnode * leaf = calloc(sizeof(tnode), 1);
|
||||||
struct tnode * leaf = calloc(sizeof(tnode), 1);
|
add_command(root, leaf, LOC(slang->lang, "alliance"), NULL);
|
||||||
add_command(root, leaf, LOC(slang->lang, "alliance"), NULL);
|
add_command(leaf, NULL, LOC(slang->lang, "new"), &cmd_new);
|
||||||
add_command(leaf, NULL, LOC(slang->lang, "kick"), &alliance_kick);
|
add_command(leaf, NULL, LOC(slang->lang, "invite"), &cmd_invite);
|
||||||
slang = slang->next;
|
add_command(leaf, NULL, LOC(slang->lang, "join"), &cmd_join);
|
||||||
}
|
add_command(leaf, NULL, LOC(slang->lang, "kick"), &cmd_kick);
|
||||||
}
|
add_command(leaf, NULL, LOC(slang->lang, "leave"), &cmd_new);
|
||||||
execute(stree);
|
add_command(leaf, NULL, LOC(slang->lang, "command"), &cmd_transfer);
|
||||||
while (f) {
|
slang = slang->next;
|
||||||
attrib * a = a_find(f->attribs, &at_kick);
|
}
|
||||||
if (a!=NULL) {
|
}
|
||||||
faction_list * flist = (faction_list*)a->data.v;
|
execute(stree, K_ALLIANCE);
|
||||||
if (flist!=NULL) {
|
/* some may have been kicked, must remove f->alliance==NULL */
|
||||||
unsigned int votes = listlen(flist);
|
|
||||||
unsigned int size = listlen(f->alliance->members);
|
|
||||||
if (size<=votes*2) {
|
|
||||||
f->alliance = NULL;
|
|
||||||
/* tell him he's been kicked */
|
|
||||||
for (flist=f->alliance->members;flist;flist=flist->next) {
|
|
||||||
ADDMSG(&flist->data->msgs, msg_message("alliance::kickedout",
|
|
||||||
"member alliance votes", f, f->alliance, votes));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* warn that he's been attempted to kick */
|
|
||||||
for (flist=f->alliance->members;flist;flist=flist->next) {
|
|
||||||
ADDMSG(&flist->data->msgs, msg_message("alliance::kickattempt",
|
|
||||||
"member alliance votes", f, f->alliance, votes));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f = f->next;
|
|
||||||
}
|
|
||||||
/* some may have been kicked, must remove f->alliance==NULL */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
alliancejoin(void)
|
alliancejoin(void)
|
||||||
{
|
{
|
||||||
static syntaxtree * stree = NULL;
|
static syntaxtree * stree = NULL;
|
||||||
if (stree==NULL) {
|
if (stree==NULL) {
|
||||||
syntaxtree * slang = stree = stree_create();
|
syntaxtree * slang = stree = stree_create();
|
||||||
while (slang) {
|
while (slang) {
|
||||||
struct tnode * root = calloc(sizeof(tnode), 1);
|
struct tnode * root = calloc(sizeof(tnode), 1);
|
||||||
struct tnode * leaf = calloc(sizeof(tnode), 1);
|
struct tnode * leaf = calloc(sizeof(tnode), 1);
|
||||||
add_command(root, leaf, LOC(slang->lang, "alliance"), NULL);
|
add_command(root, leaf, LOC(slang->lang, "alliance"), NULL);
|
||||||
add_command(leaf, NULL, LOC(slang->lang, "join"), &alliance_join);
|
add_command(leaf, NULL, LOC(slang->lang, "join"), &cmd_join);
|
||||||
slang = slang->next;
|
slang = slang->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
execute(stree);
|
execute(stree, K_ALLIANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
setalliance(struct faction * f, alliance * al)
|
setalliance(struct faction * f, alliance * al)
|
||||||
{
|
{
|
||||||
|
faction_list * flist = NULL;
|
||||||
if (f->alliance==al) return;
|
if (f->alliance==al) return;
|
||||||
if (f->alliance!=NULL) {
|
if (f->alliance!=NULL) {
|
||||||
faction_list ** flistp = &f->alliance->members;
|
faction_list ** flistp = &f->alliance->members;
|
||||||
while (*flistp) {
|
while (*flistp) {
|
||||||
|
faction_list * flist = *flistp;
|
||||||
if ((*flistp)->data==f) {
|
if ((*flistp)->data==f) {
|
||||||
*flistp = (*flistp)->next;
|
*flistp = flist->next;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
flistp = &(*flistp)->next;
|
flistp = &flist->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f->alliance->leader==f) {
|
||||||
|
if (f->alliance->members) {
|
||||||
|
f->alliance->leader = f->alliance->members->data;
|
||||||
|
} else {
|
||||||
|
f->alliance->leader = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f->alliance = al;
|
f->alliance = al;
|
||||||
if (al!=NULL) {
|
if (al!=NULL) {
|
||||||
faction_list * flist = calloc(sizeof(faction_list), 1);
|
faction_list ** flistp = &al->members;
|
||||||
flist->next = al->members;
|
while (*flistp) {
|
||||||
flist->data = f;
|
flistp = &(*flistp)->next;
|
||||||
al->members = flist;
|
}
|
||||||
|
if (flist==NULL) {
|
||||||
|
flist = malloc(sizeof(faction_list));
|
||||||
|
flist->data = f;
|
||||||
|
}
|
||||||
|
*flistp = flist;
|
||||||
|
flist->next = NULL;
|
||||||
|
if (al->leader==NULL) {
|
||||||
|
al->leader = f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
free(flist);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
|
@ -248,40 +448,40 @@ alliancename(const alliance * al)
|
||||||
void
|
void
|
||||||
alliancevictory(void)
|
alliancevictory(void)
|
||||||
{
|
{
|
||||||
const struct building_type * btype = bt_find("stronghold");
|
const struct building_type * btype = bt_find("stronghold");
|
||||||
region * r = regions;
|
region * r = regions;
|
||||||
alliance * al = alliances;
|
alliance * al = alliances;
|
||||||
if (btype==NULL) return;
|
if (btype==NULL) return;
|
||||||
while (r!=NULL) {
|
while (r!=NULL) {
|
||||||
building * b = r->buildings;
|
building * b = r->buildings;
|
||||||
while (b!=NULL) {
|
while (b!=NULL) {
|
||||||
if (b->type==btype) {
|
if (b->type==btype) {
|
||||||
unit * u = buildingowner(r, b);
|
unit * u = buildingowner(r, b);
|
||||||
if (u) {
|
if (u) {
|
||||||
fset(u->faction->alliance, FFL_MARK);
|
fset(u->faction->alliance, FFL_MARK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b = b->next;
|
b = b->next;
|
||||||
}
|
}
|
||||||
r=r->next;
|
r=r->next;
|
||||||
}
|
}
|
||||||
while (al!=NULL) {
|
while (al!=NULL) {
|
||||||
if (!fval(al, FFL_MARK)) {
|
if (!fval(al, FFL_MARK)) {
|
||||||
faction_list * flist = al->members;
|
faction_list * flist = al->members;
|
||||||
while (flist!=0) {
|
while (flist!=0) {
|
||||||
faction * f = flist->data;
|
faction * f = flist->data;
|
||||||
if (f->alliance==al) {
|
if (f->alliance==al) {
|
||||||
ADDMSG(&f->msgs, msg_message("alliance::lost",
|
ADDMSG(&f->msgs, msg_message("alliance::lost",
|
||||||
"alliance", al));
|
"alliance", al));
|
||||||
destroyfaction(f);
|
destroyfaction(f);
|
||||||
}
|
}
|
||||||
flist = flist->next;
|
flist = flist->next;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
freset(al, FFL_MARK);
|
freset(al, FFL_MARK);
|
||||||
}
|
}
|
||||||
al = al->next;
|
al = al->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -324,19 +524,19 @@ victorycondition(const alliance * al, const char * name)
|
||||||
} else if (strcmp(name, "pyramid")==0) {
|
} else if (strcmp(name, "pyramid")==0) {
|
||||||
|
|
||||||
/* Logik:
|
/* Logik:
|
||||||
* - if (pyr > last_passed_size && pyr > all_others) {
|
* - if (pyr > last_passed_size && pyr > all_others) {
|
||||||
* pyr->passed->counter++;
|
* pyr->passed->counter++;
|
||||||
* for(all_other_pyrs) {
|
* for(all_other_pyrs) {
|
||||||
* pyr->passed->counter=0;
|
* pyr->passed->counter=0;
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* if(pyr->passed->counter >= 3) {
|
* if(pyr->passed->counter >= 3) {
|
||||||
* set(pyr, passed);
|
* set(pyr, passed);
|
||||||
* pyr->owner->set_attrib(pyra);
|
* pyr->owner->set_attrib(pyra);
|
||||||
* }
|
* }
|
||||||
* last_passed_size = pyr->size;
|
* last_passed_size = pyr->size;
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
faction_list * flist = al->members;
|
faction_list * flist = al->members;
|
||||||
for (;flist;flist=flist->next) {
|
for (;flist;flist=flist->next) {
|
||||||
|
|
|
@ -24,12 +24,20 @@ struct faction;
|
||||||
struct region;
|
struct region;
|
||||||
struct faction_list;
|
struct faction_list;
|
||||||
|
|
||||||
|
struct alliance_transaction;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ALLIANCE_KICK, ALLIANCE_LEAVE, ALLIANCE_TRANSFER, ALLIANCE_NEW, ALLIANCE_INVITE, ALLIANCE_JOIN, ALLIANCE_MAX
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct alliance {
|
typedef struct alliance {
|
||||||
struct alliance * next;
|
struct alliance * next;
|
||||||
struct faction_list * members;
|
struct faction * leader;
|
||||||
unsigned int flags;
|
struct faction_list * members;
|
||||||
int id;
|
struct alliance_transaction * transactions[ALLIANCE_MAX];
|
||||||
char * name;
|
unsigned int flags;
|
||||||
|
int id;
|
||||||
|
char * name;
|
||||||
} alliance;
|
} alliance;
|
||||||
|
|
||||||
extern alliance * alliances;
|
extern alliance * alliances;
|
||||||
|
@ -38,12 +46,9 @@ extern alliance * makealliance(int id, const char * name);
|
||||||
extern const char * alliancename(const struct alliance * al);
|
extern const char * alliancename(const struct alliance * al);
|
||||||
extern void setalliance(struct faction * f, alliance * al);
|
extern void setalliance(struct faction * f, alliance * al);
|
||||||
|
|
||||||
extern void alliancejoin(void);
|
extern void alliance_cmd(void);
|
||||||
extern void alliancekick(void);
|
|
||||||
extern void alliancevictory(void);
|
|
||||||
|
|
||||||
void alliance_setname(alliance * self, const char * name);
|
void alliance_setname(alliance * self, const char * name);
|
||||||
extern int victorycondition(const alliance * al, const char * name);
|
|
||||||
/* execute commands */
|
/* execute commands */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -554,8 +554,12 @@ read_alliances(struct storage * store)
|
||||||
store->r_str_buf(store, pbuf, sizeof(pbuf));
|
store->r_str_buf(store, pbuf, sizeof(pbuf));
|
||||||
while (strcmp(pbuf, "end")!=0) {
|
while (strcmp(pbuf, "end")!=0) {
|
||||||
char aname[128];
|
char aname[128];
|
||||||
|
alliance * al;
|
||||||
store->r_str_buf(store, aname, sizeof(aname));
|
store->r_str_buf(store, aname, sizeof(aname));
|
||||||
makealliance(atoi36(pbuf), aname);
|
al = makealliance(atoi36(pbuf), aname);
|
||||||
|
if (store->version>=ALLIANCELEADER_VERSION) {
|
||||||
|
read_reference(&al->leader, store, read_faction_reference, resolve_faction);
|
||||||
|
}
|
||||||
store->r_str_buf(store, pbuf, sizeof(pbuf));
|
store->r_str_buf(store, pbuf, sizeof(pbuf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -565,8 +569,13 @@ write_alliances(struct storage * store)
|
||||||
{
|
{
|
||||||
alliance * al = alliances;
|
alliance * al = alliances;
|
||||||
while (al) {
|
while (al) {
|
||||||
store->w_id(store, al->id);
|
if (al->leader) {
|
||||||
store->w_tok(store, al->name);
|
store->w_id(store, al->id);
|
||||||
|
store->w_tok(store, al->name);
|
||||||
|
if (store->version>=ALLIANCELEADER_VERSION) {
|
||||||
|
write_faction_reference(al->leader, store);
|
||||||
|
}
|
||||||
|
}
|
||||||
al = al->next;
|
al = al->next;
|
||||||
store->w_brk(store);
|
store->w_brk(store);
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
#define NOBORDERATTRIBS_VERSION 331 /* border::attribs has been moved to userdata */
|
#define NOBORDERATTRIBS_VERSION 331 /* border::attribs has been moved to userdata */
|
||||||
#define UIDHASH_VERSION 332 /* borders use the region.uid to store */
|
#define UIDHASH_VERSION 332 /* borders use the region.uid to store */
|
||||||
#define REGIONOWNER_VERSION 333 /* regions have owners and morale */
|
#define REGIONOWNER_VERSION 333 /* regions have owners and morale */
|
||||||
|
#define ALLIANCELEADER_VERSION 333 /* alliances have a leader */
|
||||||
|
|
||||||
#define MIN_VERSION CURSETYPE_VERSION /* minimal datafile we support */
|
#define MIN_VERSION CURSETYPE_VERSION /* minimal datafile we support */
|
||||||
#define RELEASE_VERSION REGIONOWNER_VERSION /* current datafile */
|
#define RELEASE_VERSION REGIONOWNER_VERSION /* current datafile */
|
||||||
|
|
|
@ -6719,7 +6719,23 @@
|
||||||
<text locale="de">AUSSTOSSEN</text>
|
<text locale="de">AUSSTOSSEN</text>
|
||||||
<text locale="en">KICK</text>
|
<text locale="en">KICK</text>
|
||||||
</string>
|
</string>
|
||||||
|
<string name="new">
|
||||||
|
<text locale="de">NEU</text>
|
||||||
|
<text locale="en">NEW</text>
|
||||||
|
</string>
|
||||||
|
<string name="command">
|
||||||
|
<text locale="de">KOMMANDO</text>
|
||||||
|
<text locale="en">COMMAND</text>
|
||||||
|
</string>
|
||||||
|
<string name="leave">
|
||||||
|
<text locale="de">VERLASSEN</text>
|
||||||
|
<text locale="en">LEAVE</text>
|
||||||
|
</string>
|
||||||
<string name="join">
|
<string name="join">
|
||||||
|
<text locale="de">BEITRETEN</text>
|
||||||
|
<text locale="en">JOIN</text>
|
||||||
|
</string>
|
||||||
|
<string name="invite">
|
||||||
<text locale="de">AUFNEHEMEN</text>
|
<text locale="de">AUFNEHEMEN</text>
|
||||||
<text locale="en">JOIN</text>
|
<text locale="en">JOIN</text>
|
||||||
</string>
|
</string>
|
||||||
|
|
|
@ -116,6 +116,7 @@
|
||||||
<param name="recruit.allow_merge" value="1"/>
|
<param name="recruit.allow_merge" value="1"/>
|
||||||
<param name="study.expensivemigrants" value="1"/>
|
<param name="study.expensivemigrants" value="1"/>
|
||||||
<param name="rules.check_overload" value="0"/>
|
<param name="rules.check_overload" value="0"/>
|
||||||
|
<param name="rules.alliances" value="1"/>
|
||||||
<param name="rules.combat.herospeed" value="3"/>
|
<param name="rules.combat.herospeed" value="3"/>
|
||||||
<param name="rules.combat.skill_bonus" value="0"/>
|
<param name="rules.combat.skill_bonus" value="0"/>
|
||||||
<param name="rules.combat.loot" value="3"/> <!-- only self + monsters -->
|
<param name="rules.combat.loot" value="3"/> <!-- only self + monsters -->
|
||||||
|
|
Loading…
Reference in a new issue