forked from github/server
commit
c81d6e5f94
|
@ -1,5 +1,6 @@
|
|||
#include <platform.h>
|
||||
|
||||
#include "kernel/config.h"
|
||||
#include "kernel/faction.h"
|
||||
#include "kernel/messages.h"
|
||||
#include "kernel/order.h"
|
||||
|
@ -20,12 +21,12 @@ static int cmp_scholars(const void *lhs, const void *rhs)
|
|||
{
|
||||
const scholar *a = (const scholar *)lhs;
|
||||
const scholar *b = (const scholar *)rhs;
|
||||
if (a->sk == b->sk) {
|
||||
if (a->skill == b->skill) {
|
||||
/* sort by level, descending: */
|
||||
return b->level - a->level;
|
||||
}
|
||||
/* order by skill */
|
||||
return (int)a->sk - (int)b->sk;
|
||||
return a->skill - b->skill;
|
||||
}
|
||||
|
||||
int autostudy_init(scholar scholars[], int max_scholars, unit **units)
|
||||
|
@ -42,12 +43,14 @@ int autostudy_init(scholar scholars[], int max_scholars, unit **units)
|
|||
scholar * st = scholars + nscholars;
|
||||
skill_t sk = getskill(u->faction->locale);
|
||||
if (check_student(u, u->thisorder, sk)) {
|
||||
st->sk = sk;
|
||||
st->level = effskill_study(u, st->sk);
|
||||
st->skill = (short)sk;
|
||||
st->level = (short)effskill_study(u, sk);
|
||||
st->learn = 0;
|
||||
st->u = u;
|
||||
if (++nscholars > max_scholars) {
|
||||
log_fatal("you must increase MAXSCHOLARS");
|
||||
if (++nscholars >= max_scholars) {
|
||||
log_warning("you must increase MAXSCHOLARS");
|
||||
*units = u->next;
|
||||
return max_scholars;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -81,26 +84,26 @@ void autostudy_run(scholar scholars[], int nscholars)
|
|||
{
|
||||
int ti = 0;
|
||||
while (ti != nscholars) {
|
||||
skill_t sk = scholars[ti].sk;
|
||||
int skill = scholars[ti].skill;
|
||||
int t, se, ts = 0, tt = 0, si = ti;
|
||||
for (se = ti; se != nscholars && scholars[se].sk == sk; ++se) {
|
||||
for (se = ti; se != nscholars && scholars[se].skill == skill; ++se) {
|
||||
int mint;
|
||||
ts += scholars[se].u->number; /* count total scholars */
|
||||
mint = (ts + 10) / 11; /* need a minimum of ceil(ts/11) teachers */
|
||||
for (; mint > tt && si != nscholars && scholars[si].sk == sk; ++si) {
|
||||
for (; mint > tt && si != nscholars && scholars[si].skill == skill; ++si) {
|
||||
tt += scholars[si].u->number;
|
||||
}
|
||||
}
|
||||
/* now si splits the teachers and students 1:10 */
|
||||
/* first student must be 2 levels below first teacher: */
|
||||
for (; si != se && scholars[si].sk == sk; ++si) {
|
||||
for (; si != se && scholars[si].skill == skill; ++si) {
|
||||
if (scholars[si].level + TEACHDIFFERENCE <= scholars[ti].level) {
|
||||
break;
|
||||
}
|
||||
tt += scholars[si].u->number;
|
||||
}
|
||||
/* now si is the first unit we can teach, if we can teach any */
|
||||
if (si == se || scholars[si].sk != sk) {
|
||||
if (si == se || scholars[si].skill != skill) {
|
||||
/* there are no students, so standard learning for everyone */
|
||||
for (t = ti; t != se; ++t) {
|
||||
learning(scholars + t, scholars[t].u->number);
|
||||
|
@ -161,15 +164,19 @@ void autostudy_run(scholar scholars[], int nscholars)
|
|||
}
|
||||
}
|
||||
|
||||
#define MAXSCHOLARS 512
|
||||
|
||||
void do_autostudy(region *r)
|
||||
{
|
||||
static int max_scholars;
|
||||
unit *units = r->units;
|
||||
scholar scholars[MAXSCHOLARS];
|
||||
static int config;
|
||||
static int batchsize = MAXSCHOLARS;
|
||||
if (config_changed(&config)) {
|
||||
batchsize = config_get_int("automate.batchsize", MAXSCHOLARS);
|
||||
assert(batchsize <= MAXSCHOLARS);
|
||||
}
|
||||
while (units) {
|
||||
int i, nscholars = autostudy_init(scholars, MAXSCHOLARS, &units);
|
||||
int i, nscholars = autostudy_init(scholars, batchsize, &units);
|
||||
if (nscholars > max_scholars) {
|
||||
stats_count("automate.max_scholars", nscholars - max_scholars);
|
||||
max_scholars = nscholars;
|
||||
|
@ -177,7 +184,7 @@ void do_autostudy(region *r)
|
|||
autostudy_run(scholars, nscholars);
|
||||
for (i = 0; i != nscholars; ++i) {
|
||||
int days = STUDYDAYS * scholars[i].learn;
|
||||
learn_skill(scholars[i].u, scholars[i].sk, days);
|
||||
learn_skill(scholars[i].u, (skill_t)scholars[i].skill, days);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,11 +28,12 @@ struct unit;
|
|||
|
||||
typedef struct scholar {
|
||||
struct unit *u;
|
||||
skill_t sk;
|
||||
int level;
|
||||
int learn;
|
||||
short skill;
|
||||
short level;
|
||||
} scholar;
|
||||
|
||||
#define MAXSCHOLARS 128
|
||||
#define STUDENTS_PER_TEACHER 10
|
||||
|
||||
void do_autostudy(struct region *r);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "automate.h"
|
||||
|
||||
#include "kernel/config.h"
|
||||
#include "kernel/faction.h"
|
||||
#include "kernel/order.h"
|
||||
#include "kernel/region.h"
|
||||
|
@ -46,22 +47,22 @@ static void test_autostudy_init(CuTest *tc) {
|
|||
CuAssertPtrEquals(tc, u2, scholars[0].u);
|
||||
CuAssertIntEquals(tc, 2, scholars[0].level);
|
||||
CuAssertIntEquals(tc, 0, scholars[0].learn);
|
||||
CuAssertIntEquals(tc, SK_ENTERTAINMENT, scholars[0].sk);
|
||||
CuAssertIntEquals(tc, SK_ENTERTAINMENT, scholars[0].skill);
|
||||
CuAssertPtrEquals(tc, u1, scholars[1].u);
|
||||
CuAssertIntEquals(tc, 0, scholars[1].level);
|
||||
CuAssertIntEquals(tc, 0, scholars[1].learn);
|
||||
CuAssertIntEquals(tc, SK_ENTERTAINMENT, scholars[1].sk);
|
||||
CuAssertIntEquals(tc, SK_ENTERTAINMENT, scholars[1].skill);
|
||||
CuAssertPtrEquals(tc, u3, scholars[2].u);
|
||||
CuAssertIntEquals(tc, 0, scholars[2].level);
|
||||
CuAssertIntEquals(tc, 0, scholars[2].learn);
|
||||
CuAssertIntEquals(tc, SK_PERCEPTION, scholars[2].sk);
|
||||
CuAssertIntEquals(tc, SK_PERCEPTION, scholars[2].skill);
|
||||
CuAssertPtrEquals(tc, NULL, scholars[3].u);
|
||||
CuAssertPtrEquals(tc, u5, ulist);
|
||||
CuAssertIntEquals(tc, 1, autostudy_init(scholars, 4, &ulist));
|
||||
CuAssertPtrEquals(tc, u5, scholars[0].u);
|
||||
CuAssertIntEquals(tc, 0, scholars[0].level);
|
||||
CuAssertIntEquals(tc, 0, scholars[0].learn);
|
||||
CuAssertIntEquals(tc, SK_PERCEPTION, scholars[0].sk);
|
||||
CuAssertIntEquals(tc, SK_PERCEPTION, scholars[0].skill);
|
||||
CuAssertPtrEquals(tc, NULL, ulist);
|
||||
test_teardown();
|
||||
}
|
||||
|
@ -231,9 +232,44 @@ static void test_autostudy_run_skilldiff(CuTest *tc) {
|
|||
test_teardown();
|
||||
}
|
||||
|
||||
static void test_do_autostudy(CuTest *tc) {
|
||||
scholar scholars[2];
|
||||
int nscholars;
|
||||
unit *u1, *u2, *u3, *ulist;
|
||||
faction *f;
|
||||
region *r;
|
||||
|
||||
test_setup();
|
||||
r = test_create_plain(0, 0);
|
||||
f = test_create_faction(NULL);
|
||||
u1 = test_create_unit(f, r);
|
||||
u1->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
|
||||
set_number(u1, 1);
|
||||
set_level(u1, SK_PERCEPTION, 2);
|
||||
u2 = test_create_unit(f, r);
|
||||
u2->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
|
||||
set_number(u2, 10);
|
||||
u3 = test_create_unit(f, r);
|
||||
u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
|
||||
set_number(u3, 10);
|
||||
scholars[1].u = NULL;
|
||||
ulist = r->units;
|
||||
config_set("automate.batchsize", "2");
|
||||
CuAssertIntEquals(tc, 2, nscholars = autostudy_init(scholars, 2, &ulist));
|
||||
CuAssertPtrEquals(tc, u3, ulist);
|
||||
autostudy_run(scholars, nscholars);
|
||||
CuAssertIntEquals(tc, 0, scholars[0].learn);
|
||||
CuAssertIntEquals(tc, 20, scholars[1].learn);
|
||||
CuAssertIntEquals(tc, 1, nscholars = autostudy_init(scholars, 2, &ulist));
|
||||
autostudy_run(scholars, nscholars);
|
||||
CuAssertIntEquals(tc, 10, scholars[0].learn);
|
||||
test_teardown();
|
||||
}
|
||||
|
||||
CuSuite *get_automate_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
SUITE_ADD_TEST(suite, test_do_autostudy);
|
||||
SUITE_ADD_TEST(suite, test_autostudy_init);
|
||||
SUITE_ADD_TEST(suite, test_autostudy_run);
|
||||
SUITE_ADD_TEST(suite, test_autostudy_run_noteachers);
|
||||
|
|
|
@ -300,7 +300,7 @@ unit *addplayer(region * r, faction * f)
|
|||
} while (rc == NULL || urc == RC_DAEMON || !playerrace(rc));
|
||||
u->irace = rc;
|
||||
}
|
||||
f->lastorders = 0;
|
||||
f->lastorders = turn;
|
||||
return u;
|
||||
}
|
||||
|
||||
|
|
|
@ -344,6 +344,7 @@ static void test_addplayer(CuTest *tc) {
|
|||
CuAssertPtrNotNull(tc, u);
|
||||
CuAssertPtrEquals(tc, r, u->region);
|
||||
CuAssertPtrEquals(tc, f, u->faction);
|
||||
CuAssertIntEquals(tc, turn, u->faction->lastorders);
|
||||
CuAssertIntEquals(tc, i_get(u->items, itype), 10);
|
||||
CuAssertPtrNotNull(tc, u->orders);
|
||||
CuAssertIntEquals(tc, K_WORK, getkeyword(u->orders));
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#ifndef ERESSEA_VERSION
|
||||
/* the version number, if it was not passed to make with -D */
|
||||
#define ERESSEA_VERSION "3.20.0"
|
||||
#define ERESSEA_VERSION "3.21.0"
|
||||
#endif
|
||||
|
||||
const char *eressea_version(void) {
|
||||
|
|
|
@ -860,8 +860,9 @@ void reduce_skill_days(unit *u, skill_t sk, int days) {
|
|||
}
|
||||
}
|
||||
|
||||
/** Talente von Daemonen verschieben sich.
|
||||
*/
|
||||
/**
|
||||
* Talente von Daemonen verschieben sich.
|
||||
*/
|
||||
void demon_skillchange(unit *u)
|
||||
{
|
||||
skill *sv = u->skills;
|
||||
|
|
Loading…
Reference in New Issue