forked from github/server
Merge branch 'develop' of https://github.com/ennorehling/eressea into develop
This commit is contained in:
commit
10c47d339e
2
clibs
2
clibs
|
@ -1 +1 @@
|
|||
Subproject commit 66a891b383f1a51bb0d4e5cf002530f7f70bf7f4
|
||||
Subproject commit d86c8525489d7f11b7ba13e101bb59ecf160b871
|
|
@ -28,6 +28,9 @@ if [ -e orders.$TURN ]; then
|
|||
files="$files orders.$TURN"
|
||||
fi
|
||||
echo "backup turn $TURN, game $GAME, files: $files"
|
||||
if [ -d reports ] ; then
|
||||
tar cjf backup/$TURN-reports.tar.bz2 reports
|
||||
fi
|
||||
tar cjf backup/$TURN.tar.bz2 $files
|
||||
echo "uploading game-$GAME/$TURN.tar.bz2"
|
||||
curl -s -n -T backup/$TURN.tar.bz2 https://dav.box.com/dav/Eressea/game-$GAME/$TURN.tar.bz2
|
||||
|
|
|
@ -2864,6 +2864,9 @@ msgstr "der Schatten"
|
|||
msgid "ALLES"
|
||||
msgstr "ALLES"
|
||||
|
||||
msgid "AUTO"
|
||||
msgstr "AUTO"
|
||||
|
||||
msgid "undead_postfix_2"
|
||||
msgstr "der Finsternis"
|
||||
|
||||
|
@ -5958,6 +5961,10 @@ msgctxt "keyword"
|
|||
msgid "maketemp"
|
||||
msgstr "MACHE TEMP"
|
||||
|
||||
msgctxt "keyword"
|
||||
msgid "autostudy"
|
||||
msgstr "LERNE AUTO"
|
||||
|
||||
msgctxt "spell"
|
||||
msgid "reanimate"
|
||||
msgstr "Wiederbelebung"
|
||||
|
|
|
@ -2510,6 +2510,9 @@ msgstr "halfling foot"
|
|||
msgid "ALLES"
|
||||
msgstr "ALL"
|
||||
|
||||
msgid "AUTO"
|
||||
msgstr "AUTO"
|
||||
|
||||
msgctxt "race"
|
||||
msgid "songdragon_d"
|
||||
msgstr "song dragons"
|
||||
|
@ -5268,7 +5271,11 @@ msgstr "berserkers blood potions"
|
|||
|
||||
msgctxt "keyword"
|
||||
msgid "maketemp"
|
||||
msgstr "MAKETEMP"
|
||||
msgstr "MAKE TEMP"
|
||||
|
||||
msgctxt "keyword"
|
||||
msgid "autostudy"
|
||||
msgstr "LEARN AUTO"
|
||||
|
||||
msgctxt "spell"
|
||||
msgid "reanimate"
|
||||
|
|
|
@ -12,6 +12,30 @@ function setup()
|
|||
eressea.settings.set("rules.peasants.growth.factor", "0")
|
||||
end
|
||||
|
||||
function test_study_auto()
|
||||
local r = region.create(0, 0, "plain")
|
||||
local f = faction.create("human")
|
||||
local u = unit.create(f, r, 1)
|
||||
u:add_order("LERN AUT Waffenbau")
|
||||
assert_equal("LERNE AUTO Waffenbau", u:get_order(0))
|
||||
process_orders()
|
||||
assert_equal(1, u:get_skill("weaponsmithing"))
|
||||
end
|
||||
|
||||
function test_study_auto_expensive()
|
||||
local r = region.create(0, 0, "plain")
|
||||
local f = faction.create("human")
|
||||
local u = unit.create(f, r, 1)
|
||||
u:add_order("LERNE AUTO Magie")
|
||||
assert_equal("LERNE Magie", u:get_order(0))
|
||||
u:clear_orders()
|
||||
u:add_order("LERN AUT Taktik")
|
||||
assert_equal("LERNE Taktik", u:get_order(0))
|
||||
u:clear_orders()
|
||||
u:add_order("LERN AUT Waffenbau")
|
||||
assert_equal("LERNE AUTO Waffenbau", u:get_order(0))
|
||||
end
|
||||
|
||||
function test_calendar()
|
||||
assert_equal("winter", get_season(1011))
|
||||
assert_equal("spring", get_season(1012))
|
||||
|
|
|
@ -42,7 +42,8 @@ function test_build_watch()
|
|||
process_orders()
|
||||
assert_not_nil(u.building)
|
||||
if 5 ~= u.building.size then
|
||||
for k,v in f.messages do
|
||||
-- debug logging to find intermittent errors
|
||||
for k,v in ipairs(f.messages) do
|
||||
print(v)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -24,7 +24,7 @@ end
|
|||
|
||||
function test_study()
|
||||
local r = region.create(0, 0, "plain")
|
||||
local f = faction.create("human", "test@example.com", "de")
|
||||
local f = faction.create("human")
|
||||
local u = unit.create(f, r, 1)
|
||||
u:add_order("LERNEN Armbrust")
|
||||
process_orders()
|
||||
|
@ -33,7 +33,7 @@ end
|
|||
|
||||
function test_study_expensive()
|
||||
local r = region.create(0, 0, "plain")
|
||||
local f = faction.create("human", "test@example.com", "de")
|
||||
local f = faction.create("human")
|
||||
local u = unit.create(f, r, 1)
|
||||
eressea.settings.set("skills.cost.alchemy", "50")
|
||||
u:add_order("LERNEN Alchemie")
|
||||
|
@ -45,7 +45,7 @@ end
|
|||
|
||||
function test_unit_spells()
|
||||
local r = region.create(0, 0, "plain")
|
||||
local f = faction.create("human", "test@example.com", "de")
|
||||
local f = faction.create("human")
|
||||
local u = unit.create(f, r, 1)
|
||||
u.magic = "gray"
|
||||
u:set_skill("magic", 1)
|
||||
|
@ -75,7 +75,7 @@ end
|
|||
|
||||
function test_study_no_teacher()
|
||||
local r = region.create(0, 0, "plain")
|
||||
local f = faction.create("human", "test@example.com", "de")
|
||||
local f = faction.create("human")
|
||||
local u1 = make_student(f, r, 1)
|
||||
u1:set_skill("crossbow", 1)
|
||||
process_orders()
|
||||
|
@ -84,7 +84,7 @@ end
|
|||
|
||||
function test_study_with_teacher()
|
||||
local r = region.create(0, 0, "plain")
|
||||
local f = faction.create("human", "test@example.com", "de")
|
||||
local f = faction.create("human")
|
||||
local u1 = make_student(f, r, 1)
|
||||
|
||||
make_teacher(u1)
|
||||
|
@ -95,7 +95,7 @@ end
|
|||
|
||||
function test_study_too_many_students()
|
||||
local r = region.create(0, 0, "plain")
|
||||
local f = faction.create("human", "test@example.com", "de")
|
||||
local f = faction.create("human")
|
||||
local u1 = make_student(f, r, 20, "Taktik")
|
||||
u1.name = "Student"
|
||||
u1:add_item("money", 201*u1.number)
|
||||
|
@ -106,7 +106,7 @@ end
|
|||
|
||||
function test_study_multiple_teachers()
|
||||
local r = region.create(0, 0, "plain")
|
||||
local f = faction.create("human", "test@example.com", "de")
|
||||
local f = faction.create("human")
|
||||
local u1 = make_student(f, r, 20, "Taktik")
|
||||
u1.name = "Student"
|
||||
u1:add_item("money", 201*u1.number)
|
||||
|
|
|
@ -38,14 +38,14 @@ int autostudy_init(scholar scholars[], int max_scholars, region *r)
|
|||
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;
|
||||
st->u = u;
|
||||
if (++nscholars == max_scholars) {
|
||||
log_fatal("you must increase MAXSCHOLARS");
|
||||
}
|
||||
}
|
||||
else {
|
||||
ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, "error_race_nolearn", "race",
|
||||
|
|
|
@ -141,7 +141,8 @@ int stream_order(struct stream *out, const struct order *ord, const struct local
|
|||
if (ord->id < 0) {
|
||||
skill_t sk = (skill_t)(100 + ord->id);
|
||||
|
||||
assert(kwd == K_STUDY && sk != SK_MAGIC && sk < MAXSKILLS);
|
||||
assert(kwd == K_AUTOSTUDY || kwd == K_STUDY);
|
||||
assert(sk != SK_MAGIC && sk < MAXSKILLS);
|
||||
text = skillname(sk, lang);
|
||||
if (strchr(text, ' ') != NULL) {
|
||||
swrite(" '", 1, 2, out);
|
||||
|
@ -310,12 +311,13 @@ order *parse_order(const char *s, const struct locale * lang)
|
|||
assert(lang);
|
||||
assert(s);
|
||||
if (*s != 0) {
|
||||
char token[32];
|
||||
keyword_t kwd = NOKEYWORD;
|
||||
const char *sptr = s;
|
||||
bool persistent = false, noerror = false;
|
||||
const char * p;
|
||||
char * p;
|
||||
|
||||
p = *sptr ? parse_token_depr(&sptr) : 0;
|
||||
p = parse_token(&sptr, token, sizeof(token));
|
||||
if (p) {
|
||||
while (*p == '!' || *p == '@') {
|
||||
if (*p == '!') noerror = true;
|
||||
|
@ -326,7 +328,7 @@ order *parse_order(const char *s, const struct locale * lang)
|
|||
}
|
||||
if (kwd == K_MAKE) {
|
||||
const char *sp = sptr;
|
||||
p = parse_token_depr(&sp);
|
||||
p = parse_token(&sp, token, sizeof(token));
|
||||
if (p && isparam(p, lang, P_TEMP)) {
|
||||
kwd = K_MAKETEMP;
|
||||
sptr = sp;
|
||||
|
@ -334,10 +336,15 @@ order *parse_order(const char *s, const struct locale * lang)
|
|||
}
|
||||
else if (kwd == K_STUDY) {
|
||||
const char *sp = sptr;
|
||||
p = parse_token_depr(&sp);
|
||||
p = parse_token(&sp, token, sizeof(token));
|
||||
if (p && isparam(p, lang, P_AUTO)) {
|
||||
kwd = K_AUTOSTUDY;
|
||||
skill_t sk;
|
||||
sptr = sp;
|
||||
p = parse_token(&sp, token, sizeof(token));
|
||||
sk = get_skill(p, lang);
|
||||
if (!expensive_skill(sk)) {
|
||||
kwd = K_AUTOSTUDY;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (kwd != NOKEYWORD) {
|
||||
|
|
|
@ -121,6 +121,8 @@ static void test_parse_autostudy(CuTest *tc) {
|
|||
test_setup();
|
||||
lang = get_or_create_locale("en");
|
||||
locale_setstring(lang, mkname("skill", skillnames[SK_ENTERTAINMENT]), "Entertainment");
|
||||
locale_setstring(lang, mkname("skill", skillnames[SK_MAGIC]), "Magic");
|
||||
locale_setstring(lang, mkname("skill", skillnames[SK_TACTICS]), "Tactics");
|
||||
locale_setstring(lang, keyword(K_STUDY), "STUDY");
|
||||
locale_setstring(lang, keyword(K_AUTOSTUDY), "AUTOSTUDY");
|
||||
locale_setstring(lang, parameters[P_AUTO], "AUTO");
|
||||
|
@ -134,6 +136,17 @@ static void test_parse_autostudy(CuTest *tc) {
|
|||
CuAssertIntEquals(tc, K_AUTOSTUDY, init_order(ord, lang));
|
||||
CuAssertStrEquals(tc, "Entertainment", getstrtoken());
|
||||
free_order(ord);
|
||||
|
||||
ord = parse_order("STUDY AUTO Magic", lang);
|
||||
CuAssertIntEquals(tc, K_STUDY, getkeyword(ord));
|
||||
CuAssertStrEquals(tc, "STUDY Magic", get_command(ord, lang, cmd, sizeof(cmd)));
|
||||
free_order(ord);
|
||||
|
||||
ord = parse_order("STUDY AUTO Tactics", lang);
|
||||
CuAssertIntEquals(tc, K_STUDY, getkeyword(ord));
|
||||
CuAssertStrEquals(tc, "STUDY Tactics", get_command(ord, lang, cmd, sizeof(cmd)));
|
||||
free_order(ord);
|
||||
|
||||
test_teardown();
|
||||
}
|
||||
|
||||
|
|
35
src/skill.c
35
src/skill.c
|
@ -113,3 +113,38 @@ skill_t get_skill(const char *s, const struct locale * lang)
|
|||
return result;
|
||||
}
|
||||
|
||||
int skill_cost(skill_t sk) {
|
||||
static int config;
|
||||
static int costs[MAXSKILLS];
|
||||
int cost;
|
||||
switch (sk) {
|
||||
case SK_SPY:
|
||||
cost = 100;
|
||||
break;
|
||||
case SK_TACTICS:
|
||||
case SK_HERBALISM:
|
||||
case SK_ALCHEMY:
|
||||
cost = 200;
|
||||
break;
|
||||
default:
|
||||
cost = -1;
|
||||
}
|
||||
|
||||
if (config_changed(&config)) {
|
||||
memset(costs, 0, sizeof(costs));
|
||||
}
|
||||
|
||||
if (costs[sk] == 0) {
|
||||
char buffer[256];
|
||||
sprintf(buffer, "skills.cost.%s", skillnames[sk]);
|
||||
costs[sk] = config_get_int(buffer, cost);
|
||||
}
|
||||
if (costs[sk] >= 0) {
|
||||
return costs[sk];
|
||||
}
|
||||
return (cost > 0) ? cost : 0;
|
||||
}
|
||||
|
||||
bool expensive_skill(skill_t sk) {
|
||||
return (sk == SK_MAGIC) || skill_cost(sk) > 0;
|
||||
}
|
||||
|
|
|
@ -49,5 +49,7 @@ void init_skills(const struct locale *lang);
|
|||
void init_skill(const struct locale *lang, skill_t kwd, const char *str);
|
||||
void enable_skill(skill_t sk, bool enabled);
|
||||
bool skill_enabled(skill_t sk);
|
||||
int skill_cost(skill_t sk);
|
||||
bool expensive_skill(skill_t sk);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include <platform.h>
|
||||
#include "skill.h"
|
||||
|
||||
#include "kernel/config.h"
|
||||
#include "util/language.h"
|
||||
#include "skill.h"
|
||||
#include "tests.h"
|
||||
|
||||
#include <CuTest.h>
|
||||
|
@ -38,12 +40,34 @@ static void test_get_skill(CuTest *tc) {
|
|||
test_teardown();
|
||||
}
|
||||
|
||||
static void test_skill_cost(CuTest *tc) {
|
||||
test_setup();
|
||||
CuAssertTrue(tc, expensive_skill(SK_MAGIC));
|
||||
CuAssertTrue(tc, expensive_skill(SK_TACTICS));
|
||||
CuAssertTrue(tc, expensive_skill(SK_SPY));
|
||||
CuAssertTrue(tc, expensive_skill(SK_ALCHEMY));
|
||||
CuAssertTrue(tc, expensive_skill(SK_HERBALISM));
|
||||
CuAssertTrue(tc, !expensive_skill(SK_CROSSBOW));
|
||||
|
||||
CuAssertIntEquals(tc, 100, skill_cost(SK_SPY));
|
||||
CuAssertIntEquals(tc, 200, skill_cost(SK_TACTICS));
|
||||
CuAssertIntEquals(tc, 200, skill_cost(SK_ALCHEMY));
|
||||
CuAssertIntEquals(tc, 200, skill_cost(SK_HERBALISM));
|
||||
CuAssertIntEquals(tc, 0, skill_cost(SK_CROSSBOW));
|
||||
|
||||
config_set_int("skills.cost.crossbow", 300);
|
||||
CuAssertIntEquals(tc, 300, skill_cost(SK_CROSSBOW));
|
||||
CuAssertTrue(tc, expensive_skill(SK_CROSSBOW));
|
||||
test_teardown();
|
||||
}
|
||||
|
||||
CuSuite *get_skill_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
SUITE_ADD_TEST(suite, test_init_skill);
|
||||
SUITE_ADD_TEST(suite, test_init_skills);
|
||||
SUITE_ADD_TEST(suite, test_get_skill);
|
||||
SUITE_ADD_TEST(suite, test_skill_cost);
|
||||
return suite;
|
||||
}
|
||||
|
||||
|
|
46
src/study.c
46
src/study.c
|
@ -130,47 +130,23 @@ bool magic_lowskill(unit * u)
|
|||
return u_race(u) == toad_rc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
||||
int study_cost(struct unit *u, skill_t sk)
|
||||
{
|
||||
static int config;
|
||||
static int costs[MAXSKILLS];
|
||||
int cost = -1;
|
||||
|
||||
if (sk == SK_MAGIC) {
|
||||
int next_level = 1 + (u ? get_level(u, sk) : 0);
|
||||
static int config;
|
||||
static int cost;
|
||||
/* Die Magiekosten betragen 50+Summe(50*Stufe) */
|
||||
/* 'Stufe' ist dabei die naechste zu erreichende Stufe */
|
||||
cost = config_get_int("skills.cost.magic", 50);
|
||||
return cost * (1 + ((next_level + next_level * next_level) / 2));
|
||||
if (config_changed(&config)) {
|
||||
cost = config_get_int("skills.cost.magic", 50);
|
||||
}
|
||||
if (cost > 0) {
|
||||
int next_level = 1 + (u ? get_level(u, sk) : 0);
|
||||
return cost * (1 + ((next_level + next_level * next_level) / 2));
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
else switch (sk) {
|
||||
case SK_SPY:
|
||||
cost = 100;
|
||||
break;
|
||||
case SK_TACTICS:
|
||||
case SK_HERBALISM:
|
||||
case SK_ALCHEMY:
|
||||
cost = 200;
|
||||
break;
|
||||
default:
|
||||
cost = -1;
|
||||
}
|
||||
|
||||
if (config_changed(&config)) {
|
||||
memset(costs, 0, sizeof(costs));
|
||||
}
|
||||
|
||||
if (costs[sk] == 0) {
|
||||
char buffer[256];
|
||||
sprintf(buffer, "skills.cost.%s", skillnames[sk]);
|
||||
costs[sk] = config_get_int(buffer, cost);
|
||||
}
|
||||
if (costs[sk] >= 0) {
|
||||
return costs[sk];
|
||||
}
|
||||
return (cost > 0) ? cost : 0;
|
||||
return skill_cost(sk);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
|
37
src/study.h
37
src/study.h
|
@ -29,26 +29,9 @@ extern "C" {
|
|||
struct unit;
|
||||
struct selist;
|
||||
|
||||
int teach_cmd(struct unit *u, struct order *ord);
|
||||
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);
|
||||
|
||||
typedef void(*learn_fun)(struct unit *u, skill_t sk, int days);
|
||||
|
||||
#define STUDYDAYS 30
|
||||
void learn_skill(struct unit *u, skill_t sk, int days);
|
||||
void reduce_skill_days(struct unit *u, skill_t sk, int days);
|
||||
|
||||
void produceexp(struct unit *u, skill_t sk, int n);
|
||||
void produceexp_ex(struct unit *u, skill_t sk, int n, learn_fun learn);
|
||||
|
||||
void demon_skillchange(struct unit *u);
|
||||
|
||||
#define TEACHNUMBER 10
|
||||
|
||||
typedef struct teaching_info {
|
||||
struct selist *teachers;
|
||||
int students;
|
||||
|
@ -57,6 +40,24 @@ extern "C" {
|
|||
|
||||
extern const struct attrib_type at_learning;
|
||||
|
||||
int teach_cmd(struct unit *u, struct order *ord);
|
||||
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 sk);
|
||||
|
||||
typedef void(*learn_fun)(struct unit *u, skill_t sk, int days);
|
||||
|
||||
void learn_skill(struct unit *u, skill_t sk, int days);
|
||||
void reduce_skill_days(struct unit *u, skill_t sk, int days);
|
||||
|
||||
void produceexp(struct unit *u, skill_t sk, int n);
|
||||
void produceexp_ex(struct unit *u, skill_t sk, int n, learn_fun learn);
|
||||
|
||||
void demon_skillchange(struct unit *u);
|
||||
|
||||
void inject_learn(learn_fun fun);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
Loading…
Reference in New Issue