- new alliances + commands

This commit is contained in:
Enno Rehling 2009-05-20 22:44:19 +00:00
parent 71b34b434a
commit f9946ff7f8
7 changed files with 425 additions and 202 deletions

View file

@ -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]) {

View file

@ -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 = &regions; 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 = &regions;
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) {

View file

@ -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

View file

@ -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);
} }

View file

@ -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 */

View file

@ -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>

View file

@ -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 -->