forked from github/server
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:
parent
3115e78b31
commit
464f50a48d
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -9,6 +9,7 @@ SubDirHdrs $(SUBDIR)/../.. ;
|
|||
|
||||
SOURCES =
|
||||
arena.c
|
||||
autoseed.c
|
||||
dungeon.c
|
||||
gmcmd.c
|
||||
infocmd.c
|
||||
|
|
|
@ -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) {
|
|
@ -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
|
|
@ -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>
|
||||
|
|
|
@ -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),
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ SubDirHdrs $(SUBDIR)/.. ;
|
|||
SubDirHdrs $(XMLHDRS) ;
|
||||
|
||||
SOURCES =
|
||||
autoseed.c
|
||||
logging.c
|
||||
map_modify.c
|
||||
map_partei.c
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue