forked from github/server
commit
34abedd642
2
clibs
2
clibs
|
@ -1 +1 @@
|
|||
Subproject commit d86c8525489d7f11b7ba13e101bb59ecf160b871
|
||||
Subproject commit 66a891b383f1a51bb0d4e5cf002530f7f70bf7f4
|
Binary file not shown.
|
@ -86,6 +86,7 @@ ENDIF()
|
|||
|
||||
set (ERESSEA_SRC
|
||||
vortex.c
|
||||
automate.c
|
||||
move.c
|
||||
piracy.c
|
||||
spells.c
|
||||
|
@ -187,6 +188,7 @@ set(TESTS_SRC
|
|||
tests.c
|
||||
academy.test.c
|
||||
alchemy.test.c
|
||||
automate.test.c
|
||||
battle.test.c
|
||||
creport.test.c
|
||||
direction.test.c
|
||||
|
|
|
@ -33,13 +33,13 @@ void academy_teaching_bonus(struct unit *u, skill_t sk, int students) {
|
|||
}
|
||||
}
|
||||
|
||||
bool academy_can_teach(unit *teacher, unit *student, skill_t sk) {
|
||||
bool academy_can_teach(unit *teacher, unit *scholar, skill_t sk) {
|
||||
const struct building_type *btype = bt_find("academy");
|
||||
if (active_building(teacher, btype) && active_building(student, btype)) {
|
||||
int j = study_cost(student, sk) * 2;
|
||||
if (active_building(teacher, btype) && active_building(scholar, btype)) {
|
||||
int j = study_cost(scholar, sk) * 2;
|
||||
if (j < 50) j = 50;
|
||||
/* kann Einheit das zahlen? */
|
||||
return get_pooled(student, get_resourcetype(R_SILVER), GET_DEFAULT, j) >= j;
|
||||
return get_pooled(scholar, get_resourcetype(R_SILVER), GET_DEFAULT, j) >= j;
|
||||
/* sonst nehmen sie nicht am Unterricht teil */
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -9,7 +9,7 @@ extern "C" {
|
|||
|
||||
struct unit;
|
||||
void academy_teaching_bonus(struct unit *u, skill_t sk, int academy);
|
||||
bool academy_can_teach(struct unit *teacher, struct unit *student, skill_t sk);
|
||||
bool academy_can_teach(struct unit *teacher, struct unit *scholar, skill_t sk);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
#include <platform.h>
|
||||
|
||||
#include "kernel/faction.h"
|
||||
#include "kernel/messages.h"
|
||||
#include "kernel/order.h"
|
||||
#include "kernel/region.h"
|
||||
#include "kernel/unit.h"
|
||||
|
||||
#include "util/log.h"
|
||||
|
||||
#include "automate.h"
|
||||
#include "keyword.h"
|
||||
#include "laws.h"
|
||||
#include "study.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
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) {
|
||||
/* sort by level, descending: */
|
||||
return b->level - a->level;
|
||||
}
|
||||
/* order by skill */
|
||||
return (int)a->sk - (int)b->sk;
|
||||
}
|
||||
|
||||
int autostudy_init(scholar scholars[], int max_scholars, region *r)
|
||||
{
|
||||
unit *u;
|
||||
int nscholars = 0;
|
||||
|
||||
for (u = r->units; u; u = u->next) {
|
||||
keyword_t kwd = getkeyword(u->thisorder);
|
||||
if (kwd == K_AUTOSTUDY) {
|
||||
if (long_order_allowed(u) && unit_can_study(u)) {
|
||||
scholar * st = scholars + nscholars;
|
||||
if (++nscholars == max_scholars) {
|
||||
log_fatal("you must increase MAXSCHOLARS");
|
||||
}
|
||||
st->u = u;
|
||||
init_order(u->thisorder, u->faction->locale);
|
||||
st->sk = getskill(u->faction->locale);
|
||||
st->level = effskill_study(u, st->sk);
|
||||
st->learn = 0;
|
||||
}
|
||||
else {
|
||||
ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, "error_race_nolearn", "race",
|
||||
u_race(u)));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nscholars > 0) {
|
||||
qsort(scholars, nscholars, sizeof(scholar), cmp_scholars);
|
||||
}
|
||||
return nscholars;
|
||||
}
|
||||
|
||||
static void teaching(scholar *s, int n) {
|
||||
assert(n <= s->u->number);
|
||||
s->learn += n;
|
||||
s->u->flags |= UFL_LONGACTION;
|
||||
}
|
||||
|
||||
static void learning(scholar *s, int n) {
|
||||
assert(n <= s->u->number);
|
||||
s->learn += n;
|
||||
s->u->flags |= UFL_LONGACTION;
|
||||
}
|
||||
|
||||
void autostudy_run(scholar scholars[], int nscholars)
|
||||
{
|
||||
int ti = 0;
|
||||
while (ti != nscholars) {
|
||||
skill_t sk = scholars[ti].sk;
|
||||
int t, s, se, ts = 0, tt = 0, si = ti;
|
||||
for (se = ti; se != nscholars && scholars[se].sk == sk; ++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; ++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[ti].level - TEACHDIFFERENCE > scholars[si].level; ++si) {
|
||||
tt += scholars[si].u->number;
|
||||
}
|
||||
if (si == se) {
|
||||
/* there are no students, so standard learning only */
|
||||
for (t = ti; t != se; ++t) {
|
||||
learning(scholars + t, scholars[t].u->number);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* invariant: unit ti can still teach i students */
|
||||
int i = scholars[ti].u->number * STUDENTS_PER_TEACHER;
|
||||
/* invariant: unit si has n students that can still be taught */
|
||||
int n = scholars[si].u->number;
|
||||
for (t = ti, s = si; t != si && s != se; ) {
|
||||
if (i > n) {
|
||||
/* t has more than enough teaching capacity for s */
|
||||
i -= n;
|
||||
teaching(scholars + s, n);
|
||||
learning(scholars + s, scholars[s].u->number);
|
||||
/* next student, please: */
|
||||
if (++s == se) {
|
||||
continue;
|
||||
}
|
||||
n = scholars[s].u->number;
|
||||
}
|
||||
else {
|
||||
/* s gets partial credit and we need a new teacher */
|
||||
teaching(scholars + s, i);
|
||||
|
||||
/* we are done with this teacher. any remaining people are regular learners: */
|
||||
if (scholars[t].u->number > 1) {
|
||||
/* remain = number - ceil(taught/10); */
|
||||
int remain = (STUDENTS_PER_TEACHER * scholars[t].u->number - i + STUDENTS_PER_TEACHER - 1) / STUDENTS_PER_TEACHER;
|
||||
learning(scholars + t, remain);
|
||||
}
|
||||
|
||||
/* we want a new teacher for s. if any exists, it's next in the sequence. */
|
||||
if (++t == si) {
|
||||
continue;
|
||||
}
|
||||
if (scholars[t].level - TEACHDIFFERENCE < scholars[s].level) {
|
||||
/* next teacher cannot teach, we must skip students. */
|
||||
do {
|
||||
learning(scholars + s, (n - i));
|
||||
i = 0;
|
||||
if (++s == se) {
|
||||
continue;
|
||||
}
|
||||
n = scholars[s].u->number;
|
||||
} while (scholars[t].level - TEACHDIFFERENCE < scholars[s].level);
|
||||
}
|
||||
i = scholars[t].u->number * STUDENTS_PER_TEACHER;
|
||||
}
|
||||
}
|
||||
}
|
||||
ti = se;
|
||||
}
|
||||
}
|
||||
|
||||
#define MAXSCHOLARS 128
|
||||
|
||||
void do_autostudy(region *r)
|
||||
{
|
||||
scholar scholars[MAXSCHOLARS];
|
||||
int i, nscholars = autostudy_init(scholars, MAXSCHOLARS, 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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
Copyright (c) 1998-2018, Enno Rehling <enno@eressea.de>
|
||||
Katja Zedel <katze@felidae.kn-bremen.de
|
||||
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef H_GC_AUTOMATE
|
||||
#define H_GC_AUTOMATE
|
||||
|
||||
#include "skill.h"
|
||||
|
||||
struct region;
|
||||
struct unit;
|
||||
|
||||
typedef struct scholar {
|
||||
struct unit *u;
|
||||
skill_t sk;
|
||||
int level;
|
||||
int learn;
|
||||
} scholar;
|
||||
|
||||
#define STUDENTS_PER_TEACHER 10
|
||||
|
||||
void do_autostudy(struct region *r);
|
||||
|
||||
int autostudy_init(scholar scholars[], int max_scholars, struct region *r);
|
||||
void autostudy_run(scholar scholars[], int nscholars);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,114 @@
|
|||
#ifdef _MSC_VER
|
||||
#include <platform.h>
|
||||
#endif
|
||||
|
||||
#include "automate.h"
|
||||
|
||||
#include "kernel/faction.h"
|
||||
#include "kernel/order.h"
|
||||
#include "kernel/region.h"
|
||||
#include "kernel/unit.h"
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
#include <CuTest.h>
|
||||
|
||||
static void test_autostudy_init(CuTest *tc) {
|
||||
scholar scholars[4];
|
||||
unit *u1, *u2, *u3;
|
||||
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_ENTERTAINMENT]);
|
||||
test_create_unit(f, r);
|
||||
u2 = test_create_unit(f, r);
|
||||
u2->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
|
||||
set_level(u2, SK_ENTERTAINMENT, 2);
|
||||
u3 = test_create_unit(f, r);
|
||||
u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
|
||||
scholars[3].u = NULL;
|
||||
CuAssertIntEquals(tc, 3, autostudy_init(scholars, 4, r));
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
CuAssertPtrEquals(tc, NULL, scholars[3].u);
|
||||
test_teardown();
|
||||
}
|
||||
|
||||
static void test_autostudy_run(CuTest *tc) {
|
||||
scholar scholars[4];
|
||||
unit *u1, *u2, *u3;
|
||||
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_ENTERTAINMENT]);
|
||||
set_number(u1, 2);
|
||||
set_level(u1, SK_ENTERTAINMENT, 2);
|
||||
u2 = test_create_unit(f, r);
|
||||
u2->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
|
||||
set_number(u2, 10);
|
||||
u3 = test_create_unit(f, r);
|
||||
u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
|
||||
set_number(u3, 15);
|
||||
scholars[3].u = NULL;
|
||||
CuAssertIntEquals(tc, 3, autostudy_init(scholars, 4, r));
|
||||
autostudy_run(scholars, 3);
|
||||
CuAssertIntEquals(tc, 0, scholars[0].learn);
|
||||
CuAssertIntEquals(tc, 20, scholars[1].learn);
|
||||
CuAssertIntEquals(tc, 15, scholars[2].learn);
|
||||
test_teardown();
|
||||
}
|
||||
|
||||
static void test_autostudy_run_noteachers(CuTest *tc) {
|
||||
scholar scholars[4];
|
||||
unit *u1, *u2, *u3;
|
||||
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_LUMBERJACK]);
|
||||
set_number(u1, 2);
|
||||
set_level(u1, SK_ENTERTAINMENT, 2);
|
||||
u2 = test_create_unit(f, r);
|
||||
u2->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
|
||||
set_number(u2, 10);
|
||||
u3 = test_create_unit(f, r);
|
||||
u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
|
||||
set_number(u3, 15);
|
||||
scholars[3].u = NULL;
|
||||
CuAssertIntEquals(tc, 3, autostudy_init(scholars, 4, r));
|
||||
autostudy_run(scholars, 3);
|
||||
CuAssertIntEquals(tc, 2, scholars[0].learn);
|
||||
CuAssertIntEquals(tc, 10, scholars[1].learn);
|
||||
CuAssertIntEquals(tc, 15, scholars[2].learn);
|
||||
test_teardown();
|
||||
}
|
||||
|
||||
CuSuite *get_automate_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
SUITE_ADD_TEST(suite, test_autostudy_init);
|
||||
SUITE_ADD_TEST(suite, test_autostudy_run);
|
||||
SUITE_ADD_TEST(suite, test_autostudy_run_noteachers);
|
||||
return suite;
|
||||
}
|
|
@ -135,7 +135,8 @@ const char *parameters[MAXPARAMS] = {
|
|||
"GRUPPE",
|
||||
"PARTEITARNUNG",
|
||||
"BAEUME",
|
||||
"ALLIANZ"
|
||||
"ALLIANZ",
|
||||
"AUTO"
|
||||
};
|
||||
|
||||
int findoption(const char *s, const struct locale *lang)
|
||||
|
|
|
@ -84,7 +84,7 @@ char* get_command(const order *ord, const struct locale *lang, char *sbuffer, si
|
|||
sbs_strcat(&sbs, str);
|
||||
if (ord->id < 0) {
|
||||
skill_t sk = (skill_t)(100+ord->id);
|
||||
assert(kwd == K_STUDY && sk != SK_MAGIC && sk < MAXSKILLS);
|
||||
assert((kwd == K_STUDY || kwd == K_AUTOSTUDY) && sk != SK_MAGIC && sk < MAXSKILLS);
|
||||
str = skillname(sk, lang);
|
||||
if (str) {
|
||||
if (strchr(str, ' ') == NULL) {
|
||||
|
@ -214,12 +214,12 @@ static int create_data(keyword_t kwd, const char *s,
|
|||
order_data *data;
|
||||
int id;
|
||||
|
||||
assert(kwd!=NOKEYWORD);
|
||||
assert(kwd != NOKEYWORD);
|
||||
|
||||
if (!s || *s == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (kwd==K_STUDY) {
|
||||
if (kwd == K_STUDY || kwd == K_AUTOSTUDY) {
|
||||
const char * sptr = s;
|
||||
skill_t sk = get_skill(parse_token_depr(&sptr), lang);
|
||||
if (sk != SK_MAGIC && sk != NOSKILL) {
|
||||
|
@ -332,6 +332,14 @@ order *parse_order(const char *s, const struct locale * lang)
|
|||
sptr = sp;
|
||||
}
|
||||
}
|
||||
else if (kwd == K_STUDY) {
|
||||
const char *sp = sptr;
|
||||
p = parse_token_depr(&sp);
|
||||
if (p && isparam(p, lang, P_AUTO)) {
|
||||
kwd = K_AUTOSTUDY;
|
||||
sptr = sp;
|
||||
}
|
||||
}
|
||||
if (kwd != NOKEYWORD) {
|
||||
order *ord = (order *)malloc(sizeof(order));
|
||||
create_order_i(ord, kwd, sptr, persistent, noerror, lang);
|
||||
|
@ -366,6 +374,7 @@ bool is_repeated(keyword_t kwd)
|
|||
case K_STEAL:
|
||||
case K_SABOTAGE:
|
||||
case K_STUDY:
|
||||
case K_AUTOSTUDY:
|
||||
case K_TEACH:
|
||||
case K_GROW:
|
||||
case K_PLANT:
|
||||
|
@ -406,6 +415,7 @@ bool is_exclusive(const order * ord)
|
|||
case K_STEAL:
|
||||
case K_SABOTAGE:
|
||||
case K_STUDY:
|
||||
case K_AUTOSTUDY:
|
||||
case K_TEACH:
|
||||
case K_GROW:
|
||||
case K_PLANT:
|
||||
|
@ -447,6 +457,7 @@ bool is_long(keyword_t kwd)
|
|||
case K_STEAL:
|
||||
case K_SABOTAGE:
|
||||
case K_STUDY:
|
||||
case K_AUTOSTUDY:
|
||||
case K_TEACH:
|
||||
case K_GROW:
|
||||
case K_PLANT:
|
||||
|
@ -541,7 +552,7 @@ keyword_t init_order(const struct order *ord, const struct locale *lang)
|
|||
|
||||
assert(sk < MAXSKILLS);
|
||||
assert(lang);
|
||||
assert(kwd == K_STUDY);
|
||||
assert(kwd == K_STUDY || kwd == K_AUTOSTUDY);
|
||||
str = skillname(sk, lang);
|
||||
if (strchr(str, ' ') == NULL) {
|
||||
init_tokens_str(str);
|
||||
|
@ -575,7 +586,7 @@ keyword_t init_order_depr(const struct order *ord)
|
|||
{
|
||||
if (ord) {
|
||||
keyword_t kwd = ORD_KEYWORD(ord);
|
||||
assert(kwd != K_STUDY);
|
||||
assert(kwd != K_STUDY && kwd != K_AUTOSTUDY);
|
||||
}
|
||||
return init_order(ord, NULL);
|
||||
}
|
||||
|
|
|
@ -113,6 +113,30 @@ static void test_parse_make(CuTest *tc) {
|
|||
test_teardown();
|
||||
}
|
||||
|
||||
static void test_parse_autostudy(CuTest *tc) {
|
||||
char cmd[32];
|
||||
order *ord;
|
||||
struct locale * lang;
|
||||
|
||||
test_setup();
|
||||
lang = get_or_create_locale("en");
|
||||
locale_setstring(lang, mkname("skill", skillnames[SK_ENTERTAINMENT]), "Entertainment");
|
||||
locale_setstring(lang, keyword(K_STUDY), "STUDY");
|
||||
locale_setstring(lang, keyword(K_AUTOSTUDY), "AUTOSTUDY");
|
||||
locale_setstring(lang, parameters[P_AUTO], "AUTO");
|
||||
init_locale(lang);
|
||||
|
||||
ord = parse_order("STUDY AUTO Entertainment", lang);
|
||||
CuAssertPtrNotNull(tc, ord);
|
||||
CuAssertIntEquals(tc, K_AUTOSTUDY, getkeyword(ord));
|
||||
CuAssertStrEquals(tc, "AUTOSTUDY Entertainment", get_command(ord, lang, cmd, sizeof(cmd)));
|
||||
|
||||
CuAssertIntEquals(tc, K_AUTOSTUDY, init_order(ord, lang));
|
||||
CuAssertStrEquals(tc, "Entertainment", getstrtoken());
|
||||
free_order(ord);
|
||||
test_teardown();
|
||||
}
|
||||
|
||||
static void test_parse_make_temp(CuTest *tc) {
|
||||
char cmd[32];
|
||||
order *ord;
|
||||
|
@ -130,7 +154,7 @@ static void test_parse_make_temp(CuTest *tc) {
|
|||
CuAssertIntEquals(tc, K_MAKETEMP, getkeyword(ord));
|
||||
CuAssertStrEquals(tc, "MAKETEMP herp", get_command(ord, lang, cmd, sizeof(cmd)));
|
||||
|
||||
CuAssertIntEquals(tc, K_MAKETEMP, init_order_depr(ord));
|
||||
CuAssertIntEquals(tc, K_MAKETEMP, init_order(ord, lang));
|
||||
CuAssertStrEquals(tc, "herp", getstrtoken());
|
||||
free_order(ord);
|
||||
test_teardown();
|
||||
|
@ -153,7 +177,7 @@ static void test_parse_maketemp(CuTest *tc) {
|
|||
CuAssertPtrNotNull(tc, ord);
|
||||
CuAssertStrEquals(tc, "MAKETEMP herp", get_command(ord, lang, cmd, sizeof(cmd)));
|
||||
CuAssertIntEquals(tc, K_MAKETEMP, getkeyword(ord));
|
||||
CuAssertIntEquals(tc, K_MAKETEMP, init_order_depr(ord));
|
||||
CuAssertIntEquals(tc, K_MAKETEMP, init_order(ord, lang));
|
||||
CuAssertStrEquals(tc, "herp", getstrtoken());
|
||||
free_order(ord);
|
||||
test_teardown();
|
||||
|
@ -167,7 +191,7 @@ static void test_init_order(CuTest *tc) {
|
|||
|
||||
lang = get_or_create_locale("en");
|
||||
ord = create_order(K_MAKETEMP, lang, "hurr durr");
|
||||
CuAssertIntEquals(tc, K_MAKETEMP, init_order_depr(ord));
|
||||
CuAssertIntEquals(tc, K_MAKETEMP, init_order(ord, lang));
|
||||
CuAssertStrEquals(tc, "hurr", getstrtoken());
|
||||
CuAssertStrEquals(tc, "durr", getstrtoken());
|
||||
free_order(ord);
|
||||
|
@ -548,6 +572,7 @@ CuSuite *get_order_suite(void)
|
|||
SUITE_ADD_TEST(suite, test_study_order_quoted);
|
||||
SUITE_ADD_TEST(suite, test_parse_order);
|
||||
SUITE_ADD_TEST(suite, test_parse_make);
|
||||
SUITE_ADD_TEST(suite, test_parse_autostudy);
|
||||
SUITE_ADD_TEST(suite, test_parse_make_temp);
|
||||
SUITE_ADD_TEST(suite, test_parse_maketemp);
|
||||
SUITE_ADD_TEST(suite, test_init_order);
|
||||
|
|
|
@ -130,6 +130,7 @@ typedef enum {
|
|||
P_FACTIONSTEALTH,
|
||||
P_TREES,
|
||||
P_ALLIANCE,
|
||||
P_AUTO,
|
||||
MAXPARAMS,
|
||||
NOPARAM
|
||||
} param_t;
|
||||
|
|
|
@ -1310,13 +1310,12 @@ int eff_skill(const unit * u, const skill *sv, const region *r)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int effskill_study(const unit * u, skill_t sk, const region * r)
|
||||
int effskill_study(const unit * u, skill_t sk)
|
||||
{
|
||||
skill *sv = unit_skill(u, sk);
|
||||
if (sv && sv->level > 0) {
|
||||
int mlevel = sv->level;
|
||||
if (!r) r = u->region;
|
||||
mlevel += get_modifier(u, sv->id, sv->level, r, true);
|
||||
mlevel += get_modifier(u, sv->id, sv->level, u->region, true);
|
||||
if (mlevel > 0)
|
||||
return mlevel;
|
||||
}
|
||||
|
|
|
@ -163,7 +163,7 @@ extern "C" {
|
|||
void clone_men(const struct unit *src, struct unit *dst, int n); /* like transfer, but do not subtract from src */
|
||||
|
||||
int eff_skill(const struct unit *u, const struct skill *sv, const struct region *r);
|
||||
int effskill_study(const struct unit *u, skill_t sk, const struct region *r);
|
||||
int effskill_study(const struct unit *u, skill_t sk);
|
||||
|
||||
int get_modifier(const struct unit *u, skill_t sk, int level,
|
||||
const struct region *r, bool noitem);
|
||||
|
|
|
@ -149,5 +149,6 @@ const char *keywords[MAXKEYWORDS] = {
|
|||
"promote",
|
||||
"pay",
|
||||
"loot",
|
||||
"autostudy",
|
||||
};
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@ extern "C"
|
|||
K_PROMOTION,
|
||||
K_PAY,
|
||||
K_LOOT,
|
||||
K_AUTOSTUDY,
|
||||
MAXKEYWORDS,
|
||||
NOKEYWORD
|
||||
} keyword_t;
|
||||
|
|
33
src/laws.c
33
src/laws.c
|
@ -26,6 +26,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <modules/gmcmd.h>
|
||||
|
||||
#include "alchemy.h"
|
||||
#include "automate.h"
|
||||
#include "battle.h"
|
||||
#include "economy.h"
|
||||
#include "keyword.h"
|
||||
|
@ -3636,6 +3637,24 @@ void add_proc_unit(int priority, void(*process) (unit *), const char *name)
|
|||
}
|
||||
}
|
||||
|
||||
bool long_order_allowed(const unit *u)
|
||||
{
|
||||
const region *r = u->region;
|
||||
if (fval(u, UFL_LONGACTION)) {
|
||||
/* this message was already given in laws.update_long_order
|
||||
cmistake(u, ord, 52, MSG_PRODUCE);
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
else if (fval(r->terrain, SEA_REGION)
|
||||
&& u_race(u) != get_race(RC_AQUARIAN)
|
||||
&& !(u_race(u)->flags & RCF_SWIM)) {
|
||||
/* error message disabled by popular demand */
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* per priority, execute processors in order from PR_GLOBAL down to PR_ORDER */
|
||||
void process(void)
|
||||
{
|
||||
|
@ -3705,16 +3724,7 @@ void process(void)
|
|||
cmistake(u, ord, 224, MSG_MAGIC);
|
||||
ord = NULL;
|
||||
}
|
||||
else if (fval(u, UFL_LONGACTION)) {
|
||||
/* this message was already given in laws.update_long_order
|
||||
cmistake(u, ord, 52, MSG_PRODUCE);
|
||||
*/
|
||||
ord = NULL;
|
||||
}
|
||||
else if (fval(r->terrain, SEA_REGION)
|
||||
&& u_race(u) != get_race(RC_AQUARIAN)
|
||||
&& !(u_race(u)->flags & RCF_SWIM)) {
|
||||
/* error message disabled by popular demand */
|
||||
else if (!long_order_allowed(u)) {
|
||||
ord = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -4001,6 +4011,7 @@ void init_processor(void)
|
|||
}
|
||||
|
||||
p += 10;
|
||||
add_proc_region(p, do_autostudy, "study automation");
|
||||
add_proc_order(p, K_TEACH, teach_cmd, PROC_THISORDER | PROC_LONGORDER,
|
||||
"Lehren");
|
||||
p += 10;
|
||||
|
@ -4155,7 +4166,7 @@ void update_subscriptions(void)
|
|||
/** determine if unit can be seen by faction
|
||||
* @param f -- the observiong faction
|
||||
* @param u -- the unit that is observed
|
||||
* @param r -- the region that u is obesrved in (see below)
|
||||
* @param r -- the region that u is obesrved from (see below)
|
||||
* @param m -- terrain modifier to stealth
|
||||
*
|
||||
* r kann != u->region sein, wenn es um Durchreisen geht,
|
||||
|
|
|
@ -66,6 +66,7 @@ extern "C" {
|
|||
void update_long_order(struct unit *u);
|
||||
void sinkships(struct region * r);
|
||||
void do_enter(struct region *r, bool is_final_attempt);
|
||||
bool long_order_allowed(const struct unit *u);
|
||||
|
||||
int password_cmd(struct unit *u, struct order *ord);
|
||||
int banner_cmd(struct unit *u, struct order *ord);
|
||||
|
|
|
@ -1759,6 +1759,34 @@ static void test_nmr_timeout(CuTest *tc) {
|
|||
test_teardown();
|
||||
}
|
||||
|
||||
static void test_long_orders(CuTest *tc) {
|
||||
unit *u;
|
||||
|
||||
test_setup();
|
||||
u = test_create_unit(test_create_faction(NULL), test_create_plain(0, 0));
|
||||
CuAssertTrue(tc, long_order_allowed(u));
|
||||
u->flags |= UFL_LONGACTION;
|
||||
CuAssertTrue(tc, !long_order_allowed(u));
|
||||
test_teardown();
|
||||
}
|
||||
|
||||
static void test_long_order_on_ocean(CuTest *tc) {
|
||||
unit *u;
|
||||
race * rc;
|
||||
|
||||
test_setup();
|
||||
rc = test_create_race("pikachu");
|
||||
u = test_create_unit(test_create_faction(rc), test_create_ocean(0, 0));
|
||||
CuAssertTrue(tc, !long_order_allowed(u));
|
||||
rc->flags |= RCF_SWIM;
|
||||
CuAssertTrue(tc, long_order_allowed(u));
|
||||
|
||||
rc = test_create_race("aquarian");
|
||||
u = test_create_unit(test_create_faction(rc), u->region);
|
||||
CuAssertTrue(tc, long_order_allowed(u));
|
||||
test_teardown();
|
||||
}
|
||||
|
||||
CuSuite *get_laws_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
|
@ -1831,6 +1859,8 @@ CuSuite *get_laws_suite(void)
|
|||
SUITE_ADD_TEST(suite, test_cansee_ring);
|
||||
SUITE_ADD_TEST(suite, test_cansee_sphere);
|
||||
SUITE_ADD_TEST(suite, test_nmr_timeout);
|
||||
SUITE_ADD_TEST(suite, test_long_orders);
|
||||
SUITE_ADD_TEST(suite, test_long_order_on_ocean);
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
|
94
src/study.c
94
src/study.c
|
@ -69,7 +69,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#define TEACH_ALL 1
|
||||
#define TEACH_FRIENDS
|
||||
|
||||
static skill_t getskill(const struct locale *lang)
|
||||
skill_t getskill(const struct locale *lang)
|
||||
{
|
||||
char token[128];
|
||||
const char * s = gettoken(token, sizeof(token));
|
||||
|
@ -195,37 +195,37 @@ const attrib_type at_learning = {
|
|||
|
||||
#define EXPERIENCEDAYS 10
|
||||
|
||||
static int study_days(unit * student, skill_t sk)
|
||||
static int study_days(unit * scholar, skill_t sk)
|
||||
{
|
||||
int speed = STUDYDAYS;
|
||||
if (u_race(student)->study_speed) {
|
||||
speed += u_race(student)->study_speed[sk];
|
||||
if (u_race(scholar)->study_speed) {
|
||||
speed += u_race(scholar)->study_speed[sk];
|
||||
if (speed < STUDYDAYS) {
|
||||
skill *sv = unit_skill(student, sk);
|
||||
skill *sv = unit_skill(scholar, sk);
|
||||
if (sv == 0) {
|
||||
speed = STUDYDAYS;
|
||||
}
|
||||
}
|
||||
}
|
||||
return student->number * speed;
|
||||
return scholar->number * speed;
|
||||
}
|
||||
|
||||
static int
|
||||
teach_unit(unit * teacher, unit * student, int nteaching, skill_t sk,
|
||||
teach_unit(unit * teacher, unit * scholar, int nteaching, skill_t sk,
|
||||
bool report, int *academy_students)
|
||||
{
|
||||
teaching_info *teach = NULL;
|
||||
attrib *a;
|
||||
int students;
|
||||
|
||||
if (magic_lowskill(student)) {
|
||||
if (magic_lowskill(scholar)) {
|
||||
cmistake(teacher, teacher->thisorder, 292, MSG_EVENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
students = student->number;
|
||||
students = scholar->number;
|
||||
/* subtract already taught students */
|
||||
a = a_find(student->attribs, &at_learning);
|
||||
a = a_find(scholar->attribs, &at_learning);
|
||||
if (a != NULL) {
|
||||
teach = (teaching_info *)a->data.v;
|
||||
students -= teach->students;
|
||||
|
@ -235,18 +235,18 @@ teach_unit(unit * teacher, unit * student, int nteaching, skill_t sk,
|
|||
|
||||
if (students > 0) {
|
||||
if (teach == NULL) {
|
||||
a = a_add(&student->attribs, a_new(&at_learning));
|
||||
a = a_add(&scholar->attribs, a_new(&at_learning));
|
||||
teach = (teaching_info *)a->data.v;
|
||||
}
|
||||
selist_push(&teach->teachers, teacher);
|
||||
teach->days += students * STUDYDAYS;
|
||||
teach->students += students;
|
||||
|
||||
if (student->building && teacher->building == student->building) {
|
||||
if (scholar->building && teacher->building == scholar->building) {
|
||||
/* Solange Akademien groessenbeschraenkt sind, sollte Lehrer und
|
||||
* Student auch in unterschiedlichen Gebaeuden stehen duerfen */
|
||||
/* FIXME comment contradicts implementation */
|
||||
if (academy_can_teach(teacher, student, sk)) {
|
||||
if (academy_can_teach(teacher, scholar, sk)) {
|
||||
/* Jeder Schueler zusaetzlich +10 Tage wenn in Uni. */
|
||||
teach->days += students * EXPERIENCEDAYS; /* learning erhoehen */
|
||||
/* Lehrer zusaetzlich +1 Tag pro Schueler. */
|
||||
|
@ -304,7 +304,7 @@ int teach_cmd(unit * teacher, struct order *ord)
|
|||
#if TEACH_ALL
|
||||
if (getparam(teacher->faction->locale) == P_ANY) {
|
||||
skill_t sk;
|
||||
unit *student;
|
||||
unit *scholar;
|
||||
skill_t teachskill[MAXSKILLS];
|
||||
int t = 0;
|
||||
|
||||
|
@ -313,15 +313,15 @@ int teach_cmd(unit * teacher, struct order *ord)
|
|||
teachskill[t] = getskill(teacher->faction->locale);
|
||||
} while (sk != NOSKILL);
|
||||
|
||||
for (student = r->units; teaching > 0 && student; student = student->next) {
|
||||
if (LongHunger(student)) {
|
||||
for (scholar = r->units; teaching > 0 && scholar; scholar = scholar->next) {
|
||||
if (LongHunger(scholar)) {
|
||||
continue;
|
||||
}
|
||||
else if (student->faction == teacher->faction) {
|
||||
if (getkeyword(student->thisorder) == K_STUDY) {
|
||||
else if (scholar->faction == teacher->faction) {
|
||||
if (getkeyword(scholar->thisorder) == K_STUDY) {
|
||||
/* Input ist nun von student->thisorder !! */
|
||||
init_order(student->thisorder, student->faction->locale);
|
||||
sk = getskill(student->faction->locale);
|
||||
init_order(scholar->thisorder, scholar->faction->locale);
|
||||
sk = getskill(scholar->faction->locale);
|
||||
if (sk != NOSKILL && teachskill[0] != NOSKILL) {
|
||||
for (t = 0; teachskill[t] != NOSKILL; ++t) {
|
||||
if (sk == teachskill[t]) {
|
||||
|
@ -331,20 +331,20 @@ int teach_cmd(unit * teacher, struct order *ord)
|
|||
sk = teachskill[t];
|
||||
}
|
||||
if (sk != NOSKILL
|
||||
&& effskill_study(teacher, sk, 0) - TEACHDIFFERENCE > effskill_study(student, sk, 0)) {
|
||||
teaching -= teach_unit(teacher, student, teaching, sk, true, &academy_students);
|
||||
&& effskill_study(teacher, sk) - TEACHDIFFERENCE > effskill_study(scholar, sk)) {
|
||||
teaching -= teach_unit(teacher, scholar, teaching, sk, true, &academy_students);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef TEACH_FRIENDS
|
||||
else if (alliedunit(teacher, student->faction, HELP_GUARD)) {
|
||||
if (getkeyword(student->thisorder) == K_STUDY) {
|
||||
else if (alliedunit(teacher, scholar->faction, HELP_GUARD)) {
|
||||
if (getkeyword(scholar->thisorder) == K_STUDY) {
|
||||
/* Input ist nun von student->thisorder !! */
|
||||
init_order(student->thisorder, student->faction->locale);
|
||||
sk = getskill(student->faction->locale);
|
||||
init_order(scholar->thisorder, scholar->faction->locale);
|
||||
sk = getskill(scholar->faction->locale);
|
||||
if (sk != NOSKILL
|
||||
&& effskill_study(teacher, sk, 0) - TEACHDIFFERENCE >= effskill(student, sk, 0)) {
|
||||
teaching -= teach_unit(teacher, student, teaching, sk, true, &academy_students);
|
||||
&& effskill_study(teacher, sk) - TEACHDIFFERENCE >= effskill(scholar, sk, NULL)) {
|
||||
teaching -= teach_unit(teacher, scholar, teaching, sk, true, &academy_students);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -363,15 +363,15 @@ int teach_cmd(unit * teacher, struct order *ord)
|
|||
|
||||
while (!parser_end()) {
|
||||
skill_t sk;
|
||||
unit *student;
|
||||
unit *scholar;
|
||||
bool feedback;
|
||||
|
||||
getunit(r, teacher->faction, &student);
|
||||
getunit(r, teacher->faction, &scholar);
|
||||
++count;
|
||||
|
||||
/* Falls die Unit nicht gefunden wird, Fehler melden */
|
||||
|
||||
if (!student) {
|
||||
if (!scholar) {
|
||||
char tbuf[20];
|
||||
const char *uid;
|
||||
const char *token;
|
||||
|
@ -403,8 +403,8 @@ int teach_cmd(unit * teacher, struct order *ord)
|
|||
continue;
|
||||
}
|
||||
|
||||
feedback = teacher->faction == student->faction
|
||||
|| alliedunit(student, teacher->faction, HELP_GUARD);
|
||||
feedback = teacher->faction == scholar->faction
|
||||
|| alliedunit(scholar, teacher->faction, HELP_GUARD);
|
||||
|
||||
/* Neuen Befehl zusammenbauen. TEMP-Einheiten werden automatisch in
|
||||
* ihre neuen Nummern uebersetzt. */
|
||||
|
@ -412,31 +412,31 @@ int teach_cmd(unit * teacher, struct order *ord)
|
|||
strncat(zOrder, " ", sz - 1);
|
||||
--sz;
|
||||
}
|
||||
sz -= str_strlcpy(zOrder + 4096 - sz, itoa36(student->no), sz);
|
||||
sz -= str_strlcpy(zOrder + 4096 - sz, itoa36(scholar->no), sz);
|
||||
|
||||
if (getkeyword(student->thisorder) != K_STUDY) {
|
||||
if (getkeyword(scholar->thisorder) != K_STUDY) {
|
||||
ADDMSG(&teacher->faction->msgs,
|
||||
msg_feedback(teacher, ord, "teach_nolearn", "student", student));
|
||||
msg_feedback(teacher, ord, "teach_nolearn", "student", scholar));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Input ist nun von student->thisorder !! */
|
||||
parser_pushstate();
|
||||
init_order(student->thisorder, student->faction->locale);
|
||||
sk = getskill(student->faction->locale);
|
||||
init_order(scholar->thisorder, scholar->faction->locale);
|
||||
sk = getskill(scholar->faction->locale);
|
||||
parser_popstate();
|
||||
|
||||
if (sk == NOSKILL) {
|
||||
ADDMSG(&teacher->faction->msgs,
|
||||
msg_feedback(teacher, ord, "teach_nolearn", "student", student));
|
||||
msg_feedback(teacher, ord, "teach_nolearn", "student", scholar));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (effskill_study(student, sk, 0) > effskill_study(teacher, sk, 0)
|
||||
if (effskill_study(scholar, sk) > effskill_study(teacher, sk)
|
||||
- TEACHDIFFERENCE) {
|
||||
if (feedback) {
|
||||
ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord, "teach_asgood",
|
||||
"student", student));
|
||||
"student", scholar));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -444,18 +444,18 @@ int teach_cmd(unit * teacher, struct order *ord)
|
|||
/* ist der Magier schon spezialisiert, so versteht er nur noch
|
||||
* Lehrer seines Gebietes */
|
||||
sc_mage *mage1 = get_mage_depr(teacher);
|
||||
sc_mage *mage2 = get_mage_depr(student);
|
||||
sc_mage *mage2 = get_mage_depr(scholar);
|
||||
if (mage2 && mage1 && mage2->magietyp != M_GRAY
|
||||
&& mage1->magietyp != mage2->magietyp) {
|
||||
if (feedback) {
|
||||
ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord,
|
||||
"error_different_magic", "target", student));
|
||||
"error_different_magic", "target", scholar));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
sk_academy = sk;
|
||||
teaching -= teach_unit(teacher, student, teaching, sk, false, &academy_students);
|
||||
teaching -= teach_unit(teacher, scholar, teaching, sk, false, &academy_students);
|
||||
}
|
||||
new_order = create_order(K_TEACH, teacher->faction->locale, "%s", zOrder);
|
||||
replace_order(&teacher->orders, ord, new_order);
|
||||
|
@ -766,9 +766,6 @@ int study_cmd(unit * u, order * ord)
|
|||
days *= 2;
|
||||
}
|
||||
|
||||
if (fval(u, UFL_HUNGER))
|
||||
days /= 2;
|
||||
|
||||
learn_skill(u, sk, days);
|
||||
if (a != NULL) {
|
||||
if (teach->teachers) {
|
||||
|
@ -832,6 +829,9 @@ void learn_skill(unit *u, skill_t sk, int days) {
|
|||
int leveldays = STUDYDAYS * u->number;
|
||||
int weeks = 0;
|
||||
|
||||
if (fval(u, UFL_HUNGER)) {
|
||||
days /= 2;
|
||||
}
|
||||
assert(sk >= 0 && sk < MAXSKILLS);
|
||||
if (inject_learn_fun) {
|
||||
inject_learn_fun(u, sk, days);
|
||||
|
|
|
@ -33,6 +33,7 @@ extern "C" {
|
|||
int study_cmd(struct unit *u, struct order *ord);
|
||||
|
||||
magic_t getmagicskill(const struct locale *lang);
|
||||
skill_t getskill(const struct locale *lang);
|
||||
bool is_migrant(struct unit *u);
|
||||
int study_cost(struct unit *u, skill_t talent);
|
||||
|
||||
|
|
|
@ -89,15 +89,15 @@ static void setup_teacher(study_fixture *fix, skill_t sk) {
|
|||
setup_locale(lang);
|
||||
fix->u = test_create_unit(f, r);
|
||||
assert(fix->u);
|
||||
fix->u->thisorder = create_order(K_STUDY, f->locale, "%s", skillnames[sk]);
|
||||
fix->u->thisorder = create_order(K_STUDY, f->locale, skillnames[sk]);
|
||||
|
||||
fix->teachers[0] = test_create_unit(f, r);
|
||||
assert(fix->teachers[0]);
|
||||
fix->teachers[0]->thisorder = create_order(K_TEACH, f->locale, "%s", itoa36(fix->u->no));
|
||||
fix->teachers[0]->thisorder = create_order(K_TEACH, f->locale, itoa36(fix->u->no));
|
||||
|
||||
fix->teachers[1] = test_create_unit(f, r);
|
||||
assert(fix->teachers[1]);
|
||||
fix->teachers[1]->thisorder = create_order(K_TEACH, f->locale, "%s", itoa36(fix->u->no));
|
||||
fix->teachers[1]->thisorder = create_order(K_TEACH, f->locale, itoa36(fix->u->no));
|
||||
test_clear_messages(f);
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ static void test_study_no_teacher(CuTest *tc) {
|
|||
CuAssertPtrNotNull(tc, sv = unit_skill(fix.u, SK_CROSSBOW));
|
||||
CuAssertIntEquals(tc, 1, sv->level);
|
||||
CuAssertIntEquals(tc, 2, sv->weeks);
|
||||
CuAssertPtrEquals(tc, 0, test_get_last_message(fix.u->faction->msgs));
|
||||
CuAssertPtrEquals(tc, NULL, test_get_last_message(fix.u->faction->msgs));
|
||||
test_teardown();
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,7 @@ static void test_study_with_teacher(CuTest *tc) {
|
|||
setup_teacher(&fix, SK_CROSSBOW);
|
||||
set_level(fix.teachers[0], SK_CROSSBOW, TEACHDIFFERENCE);
|
||||
teach_cmd(fix.teachers[0], fix.teachers[0]->thisorder);
|
||||
CuAssertPtrEquals(tc, 0, test_get_last_message(fix.u->faction->msgs));
|
||||
CuAssertPtrEquals(tc, NULL, test_get_last_message(fix.u->faction->msgs));
|
||||
study_cmd(fix.u, fix.u->thisorder);
|
||||
CuAssertPtrNotNull(tc, sv = unit_skill(fix.u, SK_CROSSBOW));
|
||||
CuAssertIntEquals(tc, 1, sv->level);
|
||||
|
@ -288,7 +288,7 @@ static void test_academy_bonus(CuTest *tc) {
|
|||
u1 = test_create_unit(u->faction, u->region);
|
||||
u3 = test_create_unit(u->faction, u->region);
|
||||
u0->thisorder = create_order(K_TEACH, loc, "%s %s", itoa36(u3->no), itoa36(u1->no));
|
||||
u->thisorder = create_order(K_TEACH, loc, "%s", itoa36(u1->no));
|
||||
u->thisorder = create_order(K_TEACH, loc, itoa36(u1->no));
|
||||
u1->thisorder = create_order(K_STUDY, loc, skillnames[SK_CROSSBOW]);
|
||||
u3->thisorder = create_order(K_STUDY, loc, skillnames[SK_CROSSBOW]);
|
||||
|
||||
|
@ -405,7 +405,7 @@ static void test_study_magic(CuTest *tc) {
|
|||
f = test_create_faction(NULL);
|
||||
lang = f->locale;
|
||||
u = test_create_unit(f, test_create_region(0, 0, NULL));
|
||||
u->thisorder = create_order(K_STUDY, lang, "%s", skillnames[SK_MAGIC]);
|
||||
u->thisorder = create_order(K_STUDY, lang, skillnames[SK_MAGIC]);
|
||||
itype = test_create_silver();
|
||||
|
||||
CuAssertIntEquals(tc, -1, study_cmd(u, u->thisorder));
|
||||
|
@ -423,7 +423,7 @@ static void test_study_magic(CuTest *tc) {
|
|||
CuAssertIntEquals(tc, M_GWYRRD, f->magiegebiet);
|
||||
CuAssertIntEquals(tc, 0, i_get(u->items, itype));
|
||||
CuAssertPtrNotNull(tc, get_mage_depr(u));
|
||||
CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error65"));
|
||||
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error65"));
|
||||
CuAssertIntEquals(tc, M_GWYRRD, get_mage_depr(u)->magietyp);
|
||||
|
||||
test_teardown();
|
||||
|
@ -491,12 +491,12 @@ static void test_teach_magic(CuTest *tc) {
|
|||
f = test_create_faction(NULL);
|
||||
f->magiegebiet = M_GWYRRD;
|
||||
u = test_create_unit(f, test_create_region(0, 0, NULL));
|
||||
u->thisorder = create_order(K_STUDY, f->locale, "%s", skillnames[SK_MAGIC]);
|
||||
u->thisorder = create_order(K_STUDY, f->locale, skillnames[SK_MAGIC]);
|
||||
i_change(&u->items, itype, study_cost(u, SK_MAGIC));
|
||||
ut = test_create_unit(f, u->region);
|
||||
set_level(ut, SK_MAGIC, TEACHDIFFERENCE);
|
||||
create_mage(ut, M_GWYRRD);
|
||||
ut->thisorder = create_order(K_TEACH, f->locale, "%s", itoa36(u->no));
|
||||
ut->thisorder = create_order(K_TEACH, f->locale, itoa36(u->no));
|
||||
learn_inject();
|
||||
teach_cmd(ut, ut->thisorder);
|
||||
study_cmd(u, u->thisorder);
|
||||
|
|
|
@ -93,7 +93,6 @@ int RunAllTests(int argc, char *argv[])
|
|||
ADD_SUITE(xerewards);
|
||||
/* kernel */
|
||||
ADD_SUITE(academy);
|
||||
ADD_SUITE(alchemy);
|
||||
ADD_SUITE(alliance);
|
||||
ADD_SUITE(ally);
|
||||
ADD_SUITE(building);
|
||||
|
@ -121,6 +120,8 @@ int RunAllTests(int argc, char *argv[])
|
|||
ADD_SUITE(spells);
|
||||
ADD_SUITE(unit);
|
||||
/* gamecode */
|
||||
ADD_SUITE(alchemy);
|
||||
ADD_SUITE(automate);
|
||||
ADD_SUITE(battle);
|
||||
ADD_SUITE(calendar);
|
||||
ADD_SUITE(creport);
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue