autoseed in ein Modul verlegt und zu einem Teil des Servers erhoben. Der Server kann jetzt durch Aufruf der lua-Funcktion utoseed(filename) selber neue Parteien erzeugen, was es erspart, vor jeder Runde den mapper aufzurufen, und das Aussetzen von Parteien erlaubt, wenn der Spieler in der selben Runde STIRB setzt.

This commit is contained in:
Enno Rehling 2005-03-23 23:39:26 +00:00
parent 3115e78b31
commit 464f50a48d
12 changed files with 118 additions and 217 deletions

View File

@ -930,7 +930,7 @@ plan_monsters(void)
/* Ab hier nur noch Befehle für NPC-Einheiten. */
if (u->faction->no != MONSTER_FACTION) continue;
u->status = ST_AGGRO; /* all monsters fight like crazy */
if (u->status>ST_BEHIND) u->status = ST_FIGHT; /* all monsters fight */
/* Monster bekommen jede Runde ein paar Tage Wahrnehmung dazu */
produceexp(u, SK_OBSERVATION, u->number);

View File

@ -68,6 +68,7 @@ lc_write(const struct attrib * a, FILE* F)
write_building_reference(b, F);
fwritestr(F, fname);
#if RELEASE_VERSION>=BACTION_VERSION
fputc(' ', F);
fwritestr(F, fparam?fparam:NULLSTRING);
#endif
fputc(' ', F);

View File

@ -9,6 +9,7 @@ SubDirHdrs $(SUBDIR)/../.. ;
SOURCES =
arena.c
autoseed.c
dungeon.c
gmcmd.c
infocmd.c

View File

@ -11,15 +11,20 @@
*/
#include <config.h>
#include <eressea.h>
#include <kernel/eressea.h>
#include "autoseed.h"
/* kernel includes */
#include <region.h>
#include <plane.h>
#include <faction.h>
#include <race.h>
#include <unit.h>
#include <kernel/alliance.h>
#include <kernel/region.h>
#include <kernel/plane.h>
#include <kernel/faction.h>
#include <kernel/race.h>
#include <kernel/unit.h>
/* util includes */
#include <util/base36.h>
#include <util/goodies.h>
/* libc includes */
#include <limits.h>
@ -27,36 +32,67 @@
#include <string.h>
#include <stdlib.h>
newfaction * newfactions = NULL;
static int regions_per_faction = 3;
void
get_island(region_list ** rlist)
newfaction *
read_newfactions(const char * filename)
{
region_list *rcurrent = *rlist;
region_list **rnext = &rcurrent->next;
assert(rcurrent && *rnext==NULL);
newfaction * newfactions = NULL;
FILE * F = fopen(filename, "r");
if (F==NULL) return NULL;
for (;;) {
faction * f;
char race[20], email[64], lang[8], password[16];
newfaction *nf, **nfi;
int bonus, subscription;
int alliance = 0;
fset(rcurrent->data, FL_MARK);
while (rcurrent!=NULL) {
direction_t dir;
for (dir=0;dir!=MAXDIRECTIONS;++dir) {
region * r = rconnect(rcurrent->data, dir);
if (r!=NULL && r->land && !fval(r, FL_MARK)) {
fset(r, FL_MARK);
add_regionlist(rnext, r);
if (alliances!=NULL) {
/* email;race;locale;startbonus;subscription;alliance */
if (fscanf(F, "%s %s %s %d %d %s %d", email, race, lang, &bonus, &subscription, password, &alliance)<=0) break;
} else {
/* email;race;locale;startbonus;subscription */
if (fscanf(F, "%s %s %s %d %d %s", email, race, lang, &bonus, &subscription, password)<=0) break;
}
for (f=factions;f;f=f->next) {
if (strcmp(f->email, email)==0 && f->subscription) break;
}
rcurrent = *rnext;
rnext = &rcurrent->next;
if (f) continue; /* skip the ones we've already got */
for (nf=newfactions;nf;nf=nf->next) {
if (strcmp(nf->email, email)==0) break;
}
rnext=rlist;
while (*rnext) {
rcurrent = *rnext;
freset(rcurrent->data, FL_MARK);
rnext = &rcurrent->next;
if (nf) continue;
nf = calloc(sizeof(newfaction), 1);
if (set_email(&nf->email, email)!=0) {
log_error(("Invalid email address for subscription %s: %s\n", itoa36(subscription), email));
continue;
}
nf->password = strdup(password);
nf->race = rc_find(race);
nf->subscription = subscription;
if (alliances!=NULL) {
struct alliance * al = findalliance(alliance);
if (al==NULL) {
char zText[64];
sprintf(zText, "Allianz %d", alliance);
al = makealliance(alliance, zText);
}
nf->allies = al;
} else {
nf->allies = NULL;
}
if (nf->race==NULL) nf->race = findrace(race, default_locale);
nf->lang = find_locale(lang);
nf->bonus = bonus;
assert(nf->race && nf->email && nf->lang);
nfi = &newfactions;
while (*nfi) {
if ((*nfi)->race==nf->race) break;
nfi=&(*nfi)->next;
}
nf->next = *nfi;
*nfi = nf;
}
fclose(F);
return newfactions;
}
typedef struct seed_t {
@ -175,98 +211,12 @@ recalc(seed_t * seeds, int nseeds, int nplayers)
q += quality;
}
}
/*
q = q / nplayers;
for (i=0;i!=nplayers;++i) {
quality -= (qarr[i]-q)*(qarr[i]-q);
}
*/
return quality + q;
}
extern int numnewbies;
void
autoseed(struct region_list * rlist)
{
int nregions = listlen(rlist);
int nseeds = nregions;
double lastq;
seed_t * seeds = calloc(sizeof(seed_t), nseeds);
int i, nfactions = 0;
newfaction * nf = newfactions;
while (nf) {
if (nf->bonus==0) ++nfactions;
nf = nf->next;
}
nfactions = min(nfactions, nregions/regions_per_faction);
nf = newfactions;
for (i=0;i!=nseeds;++i) {
seeds[i].region = rlist->data;
rlist = rlist->next;
if (i<nfactions) {
while (nf->bonus!=0) nf=nf->next;
seeds[i].player = nf;
nf = nf->next;
}
}
for (i=0;i!=nseeds;++i) {
direction_t d;
for (d=0;d!=MAXDIRECTIONS;++d) {
region * r = rconnect(seeds[i].region, d);
if (r && r->land) {
int k;
for (k=i+1;k!=nseeds;++k) if (seeds[k].region==r) {
seeds[k].next[dir_invert(d)] = seeds+i;
seeds[i].next[d] = seeds+k;
}
}
}
}
lastq = recalc(seeds, nseeds, nfactions);
for (;;) {
double quality = lastq;
int i;
for (i=0;i!=nseeds;++i) {
int k;
for (k=i+1;k!=nseeds;++k) {
double q;
newfaction * player = seeds[k].player;
if (player==NULL && seeds[i].player==NULL) continue;
seeds[k].player = seeds[i].player;
seeds[i].player = player;
q = recalc(seeds, nseeds, nfactions);
if (q>quality) {
quality = q;
} else {
/* undo */
seeds[i].player = seeds[k].player;
seeds[k].player = player;
}
}
}
if (lastq==quality) break;
else lastq = quality;
}
for (i=0;i!=nseeds;++i) {
newfaction * nf = seeds[i].player;
if (nf) {
newfaction ** nfp = &newfactions;
unit * u;
while (*nfp!=nf) nfp=&(*nfp)->next;
u = addplayer(seeds[i].region, addfaction(nf->email, nf->password, nf->race,
nf->lang, nf->subscription));
u->faction->alliance = nf->allies;
++numnewbies;
*nfp = nf->next;
free(nf);
}
}
}
static terrain_t
preferred_terrain(const struct race * rc)
{
@ -283,7 +233,7 @@ preferred_terrain(const struct race * rc)
#define VOLCANO_CHANCE 100
int
mkisland(int nsize)
autoseed(newfaction ** players, int nsize)
{
int x = 0, y = 0;
region * r;
@ -317,7 +267,7 @@ mkisland(int nsize)
}
}
if (listlen(newfactions)<MINFACTIONS) return 0;
if (listlen(*players)<MINFACTIONS) return 0;
r = new_region(x, y);
terraform(r, T_OCEAN);
add_regionlist(&rlist, r);
@ -347,7 +297,7 @@ mkisland(int nsize)
if (rand() % VOLCANO_CHANCE == 0) {
terraform(r, T_VOLCANO);
} else if (rand() % REGIONS_PER_FACTION == 0 || rsize==0) {
newfaction ** nfp, * nextf = newfactions;
newfaction ** nfp, * nextf = *players;
unit * u;
terraform(r, preferred_terrain(nextf->race));
++isize;
@ -356,7 +306,7 @@ mkisland(int nsize)
u->faction->alliance = nextf->allies;
/* remove duplicate email addresses */
nfp=&newfactions;
nfp = players;
while (*nfp) {
newfaction * nf = *nfp;
if (strcmp(nextf->email, nf->email)==0) {

View File

@ -12,6 +12,10 @@
#ifndef _REGIONLIST_H
#define _REGIONLIST_H
#ifdef __cplusplus
extern "C" {
#endif
struct region_list;
struct newfaction;
@ -28,10 +32,10 @@ typedef struct newfaction {
struct alliance * allies;
} newfaction;
extern newfaction * newfactions;
extern void autoseed(struct region_list * rlist);
extern void get_island(struct region_list ** rlist);
extern int mkisland(int nsize);
extern int autoseed(newfaction ** players, int nsize);
extern newfaction * read_newfactions(const char * filename);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -123,6 +123,9 @@
<File
RelativePath=".\arena.h">
</File>
<File
RelativePath=".\autoseed.h">
</File>
<File
RelativePath=".\dungeon.h">
</File>
@ -154,6 +157,9 @@
<File
RelativePath=".\arena.c">
</File>
<File
RelativePath=".\autoseed.c">
</File>
<File
RelativePath=".\dungeon.c">
</File>

View File

@ -4,6 +4,7 @@
#include "script.h"
#include <attributes/key.h>
#include <modules/autoseed.h>
// gamecode includes
#include <gamecode/laws.h>
@ -144,6 +145,19 @@ race_setscript(const char * rcname, const functor<void>& f)
}
}
#define ISLANDSIZE 20
static void
lua_autoseed(const char * filename)
{
newfaction * players = read_newfactions(filename);
while (players) {
int n = listlen(players);
int k = (n+ISLANDSIZE-1)/ISLANDSIZE;
k = n / k;
autoseed(&players, k);
}
}
#ifdef LUABIND_NO_EXCEPTIONS
static void
error_callback(lua_State * L)
@ -180,6 +194,9 @@ bind_eressea(lua_State * L)
def("plan_monsters", &lua_planmonsters),
def("set_brain", &race_setscript),
/* map making */
def("autoseed", lua_autoseed),
/* string to enum */
def("direction", &get_direction),

View File

@ -10,7 +10,6 @@ SubDirHdrs $(SUBDIR)/.. ;
SubDirHdrs $(XMLHDRS) ;
SOURCES =
autoseed.c
logging.c
map_modify.c
map_partei.c

View File

@ -225,69 +225,6 @@ seed_dropouts(void)
}
}
void
read_newfactions(const char * filename)
{
FILE * F = fopen(filename, "r");
if (F==NULL) return;
for (;;) {
faction * f = factions;
char race[20], email[64], lang[8], password[16];
newfaction *nf, **nfi;
int bonus, subscription;
int alliance = 0;
if (alliances!=NULL) {
/* email;race;locale;startbonus;subscription;alliance */
if (fscanf(F, "%s %s %s %d %d %s %d", email, race, lang, &bonus, &subscription, password, &alliance)<=0) break;
} else {
/* email;race;locale;startbonus;subscription */
if (fscanf(F, "%s %s %s %d %d %s", email, race, lang, &bonus, &subscription, password)<=0) break;
}
while (f) {
if (strcmp(f->email, email)==0 && f->subscription) {
break;
}
f = f->next;
}
if (f) continue; /* skip the ones we've already got */
for (nf=newfactions;nf;nf=nf->next) {
if (strcmp(nf->email, email)==0) break;
}
if (nf) continue;
nf = calloc(sizeof(newfaction), 1);
if (set_email(&nf->email, email)!=0) {
log_error(("Invalid email address for subscription %s: %s\n", itoa36(subscription), email));
}
nf->password = strdup(password);
nf->race = rc_find(race);
nf->subscription = subscription;
if (alliances!=NULL) {
struct alliance * al = findalliance(alliance);
if (al==NULL) {
char zText[64];
sprintf(zText, "Allianz %d", alliance);
al = makealliance(alliance, zText);
}
nf->allies = al;
} else {
nf->allies = NULL;
}
if (nf->race==NULL) nf->race = findrace(race, default_locale);
nf->lang = find_locale(lang);
nf->bonus = bonus;
assert(nf->race && nf->email && nf->lang);
nfi = &newfactions;
while (*nfi) {
if ((*nfi)->race==nf->race) break;
nfi=&(*nfi)->next;
}
nf->next = *nfi;
*nfi = nf;
}
fclose(F);
}
newfaction *
select_newfaction(const struct race * rc)
{

View File

@ -20,7 +20,7 @@
#include <eressea.h>
#include "mapper.h"
#include "autoseed.h"
#include <modules/autoseed.h>
#include <spells/spells.h>
#include <attributes/attributes.h>
@ -138,6 +138,7 @@ boolean minimapx=false,minimapy=false; /* Karte nicht vert./hor. scrollen */
/* top, left => ? */
/* hx, hy => ? */
static newfaction * newfactions = NULL;
static void
runautoseed(void)
{
@ -145,7 +146,7 @@ runautoseed(void)
int n = listlen(newfactions);
int k = (n+ISLANDSIZE-1)/ISLANDSIZE;
k = n / k;
mkisland(k);
autoseed(&newfactions, k);
}
}
@ -1164,18 +1165,8 @@ movearound(int rx, int ry) {
ch = -9;
break;
case 'a':
#if 0
if (r && r->land) {
regionlist * rlist = NULL;
add_regionlist(&rlist, r);
get_island(&rlist);
autoseed(rlist);
modified = 1;
}
#else
runautoseed();
modified = 1;
#endif
case 's':
seed_dropouts();
modified = 1;
@ -1719,9 +1710,11 @@ main(int argc, char *argv[])
}
sprintf(buf, "%s/newfactions.%d", basepath(), turn);
read_newfactions(buf);
newfactions = read_newfactions(buf);
if (newfactions==NULL) {
sprintf(buf, "%s/newfactions", basepath());
read_newfactions(buf);
newfactions = read_newfactions(buf);
}
sprintf(buf, "%s/dropouts.%d", basepath(), turn);
read_dropouts(buf);

View File

@ -117,7 +117,6 @@ struct selection ** push_selection(struct selection ** p_sel, char * str, void *
void insert_selection(struct selection ** p_sel, struct selection * prev, char * str, void * payload);
void block_create(int x1, int y1, int size, char chaotisch, int special, char terrain);
extern void read_newfactions(const char * filename);
extern void read_orders(const char * filename);
extern void read_dropouts(const char *filename);
extern void seed_dropouts(void);

View File

@ -142,9 +142,6 @@
<Filter
Name="Header"
Filter="*.h">
<File
RelativePath=".\autoseed.h">
</File>
<File
RelativePath=".\logging.h">
</File>
@ -164,9 +161,6 @@
RelativePath="..\modules\weather.h">
</File>
</Filter>
<File
RelativePath=".\autoseed.c">
</File>
<File
RelativePath=".\logging.c">
</File>