forked from github/server
Skillsystem nochmal überdacht (siehe Mail)
Bugfix Einheitenanzahl Automatisches Ausseten, Prototyp
This commit is contained in:
parent
80d6e8bbee
commit
b283d31116
|
@ -685,21 +685,37 @@ transfermen(unit * u, unit * u2, int n)
|
|||
|
||||
for (sk=0; sk!=MAXSKILLS; ++sk) {
|
||||
double dlevel = 0.0;
|
||||
int weeks, level;
|
||||
int weeks, level = 0;
|
||||
|
||||
sv = get_skill(u, sk);
|
||||
sn = get_skill(u2, sk);
|
||||
|
||||
if (sv==NULL && sn==NULL) continue;
|
||||
if (sv && sv->level) dlevel += (sv->level + 1 - sv->weeks/(sv->level*2.0+1)) * n;
|
||||
else dlevel += 0.5 * n;
|
||||
if (sn && sn->level) dlevel += (sn->level + 1 - sn->weeks/(sn->level*2.0+1)) * u2->number;
|
||||
else dlevel += 0.5 * u2->number;
|
||||
if (sv && sv->level) {
|
||||
dlevel += (sv->level + 1 - sv->weeks/(sv->level+1.0)) * n;
|
||||
level += sv->level * n;
|
||||
}
|
||||
if (sn && sn->level) {
|
||||
dlevel += (sn->level + 1 - sn->weeks/(sn->level+1.0)) * u2->number;
|
||||
level += sn->level * u2->number;
|
||||
}
|
||||
|
||||
dlevel = dlevel / (n + u2->number);
|
||||
level = level / (n + u2->number);
|
||||
if (level<=dlevel) {
|
||||
/* apply the remaining fraction to the number of weeks to go.
|
||||
* subtract the according number of weeks, getting closer to the
|
||||
* next level */
|
||||
level = (int)dlevel;
|
||||
weeks = (int)((level*2.0+1) * (1 - dlevel + level)+0.9999999);
|
||||
|
||||
weeks = (level+1) - (int)((dlevel - level) * (level+1));
|
||||
} else {
|
||||
/* make it harder to reach the next level.
|
||||
* weeks+level is the max difficulty, 1 - the fraction between
|
||||
* level and dlevel applied to the number of weeks between this
|
||||
* and the previous level is the added difficutly */
|
||||
level = (int)dlevel+1;
|
||||
weeks = 1 + 2 * level - (int)((1 + dlevel - level) * level);
|
||||
}
|
||||
if (level) {
|
||||
if (sn==NULL) sn = add_skill(u2, sk);
|
||||
sn->level = (unsigned char)level;
|
||||
|
@ -784,6 +800,7 @@ u_setfaction(unit * u, faction * f)
|
|||
#endif
|
||||
if (u->faction) {
|
||||
set_number(u, 0);
|
||||
--u->faction->no_units;
|
||||
join_group(u, NULL);
|
||||
}
|
||||
if (u->prevF) u->prevF->nextF = u->nextF;
|
||||
|
@ -802,9 +819,11 @@ u_setfaction(unit * u, faction * f)
|
|||
u->prevF = NULL;
|
||||
|
||||
u->faction = f;
|
||||
if (cnt && f) set_number(u, cnt);
|
||||
if (cnt && f) {
|
||||
set_number(u, cnt);
|
||||
++f->no_units;
|
||||
}
|
||||
}
|
||||
|
||||
/* vorsicht Sprüche können u->number == 0 (RS_FARVISION) haben! */
|
||||
void
|
||||
set_number(unit * u, int count)
|
||||
|
|
|
@ -0,0 +1,258 @@
|
|||
/* vi: set ts=2:
|
||||
+-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||
| | Enno Rehling <enno@eressea-pbem.de>
|
||||
| Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de>
|
||||
| (c) 1998 - 2001 | Henning Peters <faroul@beyond.kn-bremen.de>
|
||||
| | Ingo Wilken <Ingo.Wilken@informatik.uni-oldenburg.de>
|
||||
+-------------------+ Stefan Reich <reich@halbling.de>
|
||||
|
||||
This program may not be used, modified or distributed
|
||||
without prior permission by the authors of Eressea.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <eressea.h>
|
||||
#include "autoseed.h"
|
||||
|
||||
/* kernel includes */
|
||||
#include <region.h>
|
||||
#include <faction.h>
|
||||
#include <unit.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <limits.h>
|
||||
#include <memory.h>
|
||||
|
||||
newfaction * newfactions = NULL;
|
||||
|
||||
static int regions_per_faction = 3;
|
||||
|
||||
void
|
||||
get_island(regionlist ** rlist)
|
||||
{
|
||||
regionlist *rcurrent = *rlist;
|
||||
regionlist **rnext = &rcurrent->next;
|
||||
assert(rcurrent && *rnext==NULL);
|
||||
|
||||
fset(rcurrent->region, FL_MARK);
|
||||
while (rcurrent!=NULL) {
|
||||
direction_t dir;
|
||||
for (dir=0;dir!=MAXDIRECTIONS;++dir) {
|
||||
region * r = rconnect(rcurrent->region, dir);
|
||||
if (r!=NULL && r->land && !fval(r, FL_MARK)) {
|
||||
fset(r, FL_MARK);
|
||||
add_regionlist(rnext, r);
|
||||
}
|
||||
}
|
||||
rcurrent = *rnext;
|
||||
rnext = &rcurrent->next;
|
||||
}
|
||||
rnext=rlist;
|
||||
while (*rnext) {
|
||||
rcurrent = *rnext;
|
||||
freset(rcurrent->region, FL_MARK);
|
||||
rnext = &rcurrent->next;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct seed_t {
|
||||
struct region * region;
|
||||
struct newfaction * player;
|
||||
struct seed_t * next[MAXDIRECTIONS];
|
||||
} seed_t;
|
||||
|
||||
double
|
||||
get_influence(struct seed_t * seed, struct seed_t * target)
|
||||
{
|
||||
double q = 0.0;
|
||||
direction_t d;
|
||||
if (target==0 || seed==0) return q;
|
||||
for (d=0;d!=MAXDIRECTIONS;++d) {
|
||||
seed_t * s = seed->next[d];
|
||||
if (s==target) {
|
||||
if (target->player) {
|
||||
if (seed->player) {
|
||||
/* neighbours bad. */
|
||||
q -= 4.0;
|
||||
if (seed->player->race==target->player->race) {
|
||||
/* don't want similar people next to each other */
|
||||
q -= 2.0;
|
||||
} else if (seed->player->race==new_race[RC_ELF]) {
|
||||
if (target->player->race==new_race[RC_TROLL]) {
|
||||
/* elf sitting next to troll: poor troll */
|
||||
q -= 5.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (target->player) {
|
||||
/* empty regions good */
|
||||
q += 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
double
|
||||
get_quality(struct seed_t * seed)
|
||||
{
|
||||
double q = 0.0;
|
||||
int nterrains[MAXTERRAINS];
|
||||
direction_t d;
|
||||
|
||||
memset(nterrains, 0, sizeof(nterrains));
|
||||
for (d=0;d!=MAXDIRECTIONS;++d) {
|
||||
seed_t * ns = seed->next[d];
|
||||
if (ns) ++nterrains[rterrain(ns->region)];
|
||||
}
|
||||
++nterrains[rterrain(seed->region)];
|
||||
|
||||
if (nterrains[T_MOUNTAIN]) {
|
||||
/* 5 points for the first, and 2 points for every other mountain */
|
||||
q += (3+nterrains[T_MOUNTAIN]*2);
|
||||
} else if (seed->player->race==new_race[RC_DWARF]) {
|
||||
/* -10 for a dwarf who isn't close to a mountain */
|
||||
q -= 10.0;
|
||||
}
|
||||
|
||||
if (nterrains[T_PLAIN]) {
|
||||
/* 5 points for the first, and 2 points for every other plain */
|
||||
q += (3+nterrains[T_PLAIN]*2);
|
||||
} else if (seed->player->race==new_race[RC_ELF]) {
|
||||
/* -10 for an elf who isn't close to a plain */
|
||||
q -= 10.0;
|
||||
}
|
||||
|
||||
if (nterrains[T_DESERT]) {
|
||||
/* +10 points for the first if we are insects, and -2 points for every
|
||||
* other desert */
|
||||
if (seed->player->race==new_race[RC_INSECT]) q += 12;
|
||||
q -= (nterrains[T_DESERT]*2);
|
||||
}
|
||||
|
||||
switch (rterrain(seed->region)) {
|
||||
case T_DESERT:
|
||||
q -=8.0;
|
||||
break;
|
||||
case T_VOLCANO:
|
||||
q -=20.0;
|
||||
break;
|
||||
case T_GLACIER:
|
||||
q -=10.0;
|
||||
break;
|
||||
case T_SWAMP:
|
||||
q -= 1.0;
|
||||
break;
|
||||
case T_PLAIN:
|
||||
q += 4.0;
|
||||
break;
|
||||
case T_MOUNTAIN:
|
||||
q += 5.0;
|
||||
break;
|
||||
}
|
||||
|
||||
return 2.0;
|
||||
}
|
||||
|
||||
double
|
||||
recalc(seed_t * seeds, int nseeds, int nplayers)
|
||||
{
|
||||
int i, p = 0;
|
||||
double quality = 0.0, q = 0.0, *qarr = malloc(sizeof(int) * nplayers);
|
||||
for (i=0;i!=nseeds;++i) {
|
||||
if (seeds[i].player) {
|
||||
double quality = get_quality(seeds+i);
|
||||
direction_t d;
|
||||
for (d=0;d!=MAXDIRECTIONS;++d) {
|
||||
quality += get_influence(seeds[i].next[d], seeds+i);
|
||||
}
|
||||
qarr[p++] = quality;
|
||||
q += quality;
|
||||
}
|
||||
}
|
||||
/*
|
||||
q = q / nplayers;
|
||||
for (i=0;i!=nplayers;++i) {
|
||||
quality -= (qarr[i]-q)*(qarr[i]-q);
|
||||
}
|
||||
*/
|
||||
return quality + q;
|
||||
}
|
||||
|
||||
void
|
||||
autoseed(struct regionlist * 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->region;
|
||||
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[back[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;
|
||||
while (*nfp!=nf) nfp=&(*nfp)->next;
|
||||
addplayer(seeds[i].region, nf->email, nf->race, nf->lang);
|
||||
*nfp = nf->next;
|
||||
free(nf);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/* vi: set ts=2:
|
||||
+-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||
| | Enno Rehling <enno@eressea-pbem.de>
|
||||
| Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de>
|
||||
| (c) 1998 - 2001 | Henning Peters <faroul@beyond.kn-bremen.de>
|
||||
| | Ingo Wilken <Ingo.Wilken@informatik.uni-oldenburg.de>
|
||||
+-------------------+ Stefan Reich <reich@halbling.de>
|
||||
|
||||
This program may not be used, modified or distributed
|
||||
without prior permission by the authors of Eressea.
|
||||
*/
|
||||
|
||||
#ifndef _REGIONLIST_H
|
||||
#define _REGIONLIST_H
|
||||
|
||||
struct regionlist;
|
||||
struct newfaction;
|
||||
|
||||
typedef struct newfaction {
|
||||
struct newfaction * next;
|
||||
const char * email;
|
||||
const struct locale * lang;
|
||||
const struct race * race;
|
||||
int bonus;
|
||||
boolean oldregions;
|
||||
} newfaction;
|
||||
|
||||
extern newfaction * newfactions;
|
||||
|
||||
extern void autoseed(struct regionlist * rlist);
|
||||
extern void get_island(struct regionlist ** rlist);
|
||||
|
||||
#endif
|
|
@ -17,6 +17,8 @@
|
|||
#include <eressea.h>
|
||||
#include "mapper.h"
|
||||
|
||||
#include "autoseed.h"
|
||||
|
||||
/* kernel includes */
|
||||
#include <faction.h>
|
||||
#include <item.h>
|
||||
|
@ -160,7 +162,6 @@ typedef struct dropout {
|
|||
} dropout;
|
||||
|
||||
static dropout * dropouts;
|
||||
static newfaction * newfactions;
|
||||
|
||||
void
|
||||
read_orders(const char * filename)
|
||||
|
@ -248,9 +249,10 @@ seed_dropouts(void)
|
|||
if (nf->race==drop->race && !nf->bonus) {
|
||||
unit * u = addplayer(r, nf->email, nf->race, nf->lang);
|
||||
if (nf->bonus) give_latestart_bonus(r, u, nf->bonus);
|
||||
*nfp = nf->next;
|
||||
*dropp = drop->next;
|
||||
found=true;
|
||||
*dropp = drop->next;
|
||||
*nfp = nf->next;
|
||||
free(nf);
|
||||
break;
|
||||
}
|
||||
nfp = &nf->next;
|
||||
|
@ -439,6 +441,7 @@ NeuePartei(region * r)
|
|||
newfaction * nf = *nfp;
|
||||
if (strcmp(email, nf->email)==0) {
|
||||
*nfp = nf->next;
|
||||
free(nf);
|
||||
}
|
||||
else nfp = &nf->next;
|
||||
}
|
||||
|
|
|
@ -17,11 +17,12 @@
|
|||
#define BOOL_DEFINED
|
||||
/* wenn config.h nicht vor curses included wird, kompiliert es unter windows nicht */
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <curses.h>
|
||||
#include <eressea.h>
|
||||
#include "mapper.h"
|
||||
|
||||
#include "autoseed.h"
|
||||
|
||||
#include <spells/spells.h>
|
||||
#include <attributes/attributes.h>
|
||||
#include <triggers/triggers.h>
|
||||
|
@ -52,6 +53,7 @@
|
|||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
@ -61,6 +63,7 @@ extern char *reportdir;
|
|||
extern char *datadir;
|
||||
extern char *basedir;
|
||||
extern int maxregions;
|
||||
extern boolean dirtyload;
|
||||
char datafile[256];
|
||||
|
||||
/* -------------------- resizeterm ------------------------------------- */
|
||||
|
@ -1042,8 +1045,18 @@ movearound(int rx, int ry) {
|
|||
make_ocean_block(rx, ry);
|
||||
ch = -9;
|
||||
break;
|
||||
case 'a':
|
||||
if (r && r->land) {
|
||||
regionlist * rlist = NULL;
|
||||
add_regionlist(&rlist, r);
|
||||
get_island(&rlist);
|
||||
autoseed(rlist);
|
||||
modified = 1;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
seed_dropouts();
|
||||
modified = 1;
|
||||
break;
|
||||
case 'S':
|
||||
if (modified)
|
||||
|
@ -1467,6 +1480,9 @@ main(int argc, char *argv[])
|
|||
case 'v':
|
||||
orderfile = argv[++i];
|
||||
break;
|
||||
case 'X':
|
||||
dirtyload = true;
|
||||
break;
|
||||
case 'x':
|
||||
maxregions = atoi(argv[++i]);
|
||||
maxregions = (maxregions*81+80) / 81;
|
||||
|
|
|
@ -87,6 +87,10 @@ LINK32=link.exe
|
|||
# PROP Default_Filter "*.h"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\autoseed.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\logging.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -112,6 +116,10 @@ SOURCE=..\modules\weather.h
|
|||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\autoseed.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\logging.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
@ -43,15 +43,6 @@ typedef struct tagregion {
|
|||
struct region *r;
|
||||
} tagregion;
|
||||
|
||||
typedef struct newfaction {
|
||||
struct newfaction * next;
|
||||
const char * email;
|
||||
const struct locale * lang;
|
||||
const struct race * race;
|
||||
int bonus;
|
||||
boolean oldregions;
|
||||
} newfaction;
|
||||
|
||||
extern tagregion *Tagged;
|
||||
|
||||
void saddstr(char *s);
|
||||
|
|
Loading…
Reference in New Issue