From a4a3ebd633012d5977ee621fad00c953d661231e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 21 Jul 2018 21:41:13 +0200 Subject: [PATCH 1/5] backup the reports, because sometimes I am an idiot --- process/backup-eressea | 3 +++ 1 file changed, 3 insertions(+) diff --git a/process/backup-eressea b/process/backup-eressea index 4914f5af0..4e5f69002 100755 --- a/process/backup-eressea +++ b/process/backup-eressea @@ -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 From e7184add00e0d1e1de1629489bddd5537e88f023 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 24 Jul 2018 13:57:46 +0200 Subject: [PATCH 2/5] use system-wide muttrc --- process/send-bz2-report | 2 +- process/send-zip-report | 2 +- s/preview | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/process/send-bz2-report b/process/send-bz2-report index c9fb87840..51a8113bf 100755 --- a/process/send-bz2-report +++ b/process/send-bz2-report @@ -25,6 +25,6 @@ addr=$1 subj=$2 shift 2 -mutt -F "$ERESSEA/etc/muttrc" -s "$subj" -a "$@" -- "$addr" \ +mutt -s "$subj" -a "$@" -- "$addr" \ < "$ERESSEA/server/etc/$TEMPLATE" diff --git a/process/send-zip-report b/process/send-zip-report index 89f742b82..a6bd85246 100755 --- a/process/send-zip-report +++ b/process/send-zip-report @@ -44,6 +44,6 @@ addr=$1 subject=$2 shift 2 -mutt -F "$ERESSEA/etc/muttrc" -s "$subject" -a "$@" -- "$addr" \ +mutt -s "$subject" -a "$@" -- "$addr" \ < "$TEMPLATE" || echo "Sending failed for email/report: $2/$3" diff --git a/s/preview b/s/preview index 68fe6e39f..39d5466d0 100755 --- a/s/preview +++ b/s/preview @@ -93,7 +93,7 @@ email=$(grep "faction=$1:" reports.txt | cut -d: -f2 | sed 's/email=//') echo "sending reports to $1 / $email" info=/dev/null [ -e ../email.txt ] && info=../email.txt -cat $info | mutt -F $ERESSEA/etc/muttrc -s "Testauswertung Spiel $game Partei $1" -a $zip -- $email +cat $info | mutt -s "Testauswertung Spiel $game Partei $1" -a $zip -- $email } game=0 From ec571924037cc06b23eff622b828f865cd65a57b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 30 Jul 2018 22:19:40 +0200 Subject: [PATCH 3/5] equip_newunits got called twice. --- scripts/eressea/equipment.lua | 1 - scripts/tests/config.lua | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/scripts/eressea/equipment.lua b/scripts/eressea/equipment.lua index 8852dfb27..c7bfe7dad 100644 --- a/scripts/eressea/equipment.lua +++ b/scripts/eressea/equipment.lua @@ -2,7 +2,6 @@ local self = {} local function equip_first(u) - equip_newunits(u) name = 'seed_' .. u.race equip_unit(u, name, 255) end diff --git a/scripts/tests/config.lua b/scripts/tests/config.lua index 316a8ccca..733a8ee07 100644 --- a/scripts/tests/config.lua +++ b/scripts/tests/config.lua @@ -30,6 +30,26 @@ function test_first_troll() assert_equal(2, u:eff_skill('perception')) end +function test_first_human() + local f = faction.create('human') + local r = region.create(0, 0, "plain") + local u = unit.create(f, r, 1) + u:equip('first_unit') + assert_not_nil(u.building) + assert_equal('castle', u.building.type) + assert_equal(10, u.building.size) +end + +function test_first_aquarian() + local f = faction.create('aquarian') + local r = region.create(0, 0, "plain") + local u = unit.create(f, r, 1) + u:equip('first_unit') + assert_not_nil(u.ship) + assert_equal('boat', u.ship.type) + assert_equal(1, u:get_skill('sailing')) +end + function test_seed_unit() local r = region.create(0, 0, "plain") local f = faction.create('human') @@ -53,3 +73,4 @@ function test_seed_elf() assert_equal('castle', u.building.type) assert_equal(10, u.building.size) end + From 67089aeb8c528412303c416631e94f9541d50a4b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 9 Sep 2018 15:13:20 +0200 Subject: [PATCH 4/5] Bug 2487: Fix LERNE AUTO translations Also disallow autolearning expensive skills. --- clibs | 2 +- res/translations/strings.de.po | 7 +++++ res/translations/strings.en.po | 9 ++++++- scripts/tests/e2/e2features.lua | 24 +++++++++++++++++ scripts/tests/study.lua | 14 +++++----- src/automate.c | 8 +++--- src/kernel/order.c | 19 +++++++++----- src/kernel/order.test.c | 13 ++++++++++ src/skill.c | 35 +++++++++++++++++++++++++ src/skill.h | 2 ++ src/skill.test.c | 26 ++++++++++++++++++- src/study.c | 46 ++++++++------------------------- src/study.h | 37 +++++++++++++------------- 13 files changed, 169 insertions(+), 73 deletions(-) diff --git a/clibs b/clibs index 66a891b38..d86c85254 160000 --- a/clibs +++ b/clibs @@ -1 +1 @@ -Subproject commit 66a891b383f1a51bb0d4e5cf002530f7f70bf7f4 +Subproject commit d86c8525489d7f11b7ba13e101bb59ecf160b871 diff --git a/res/translations/strings.de.po b/res/translations/strings.de.po index 1731fa10e..f4b166221 100644 --- a/res/translations/strings.de.po +++ b/res/translations/strings.de.po @@ -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" diff --git a/res/translations/strings.en.po b/res/translations/strings.en.po index 0d64e9f99..32924310c 100644 --- a/res/translations/strings.en.po +++ b/res/translations/strings.en.po @@ -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" diff --git a/scripts/tests/e2/e2features.lua b/scripts/tests/e2/e2features.lua index bf90ab6a0..54033d496 100644 --- a/scripts/tests/e2/e2features.lua +++ b/scripts/tests/e2/e2features.lua @@ -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)) diff --git a/scripts/tests/study.lua b/scripts/tests/study.lua index 14d4ce1d6..32638ba90 100644 --- a/scripts/tests/study.lua +++ b/scripts/tests/study.lua @@ -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) diff --git a/src/automate.c b/src/automate.c index a74cf770b..6af40d649 100644 --- a/src/automate.c +++ b/src/automate.c @@ -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", diff --git a/src/kernel/order.c b/src/kernel/order.c index 342f45577..c14a2b30b 100644 --- a/src/kernel/order.c +++ b/src/kernel/order.c @@ -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) { diff --git a/src/kernel/order.test.c b/src/kernel/order.test.c index d1f8b4176..c4a55177b 100644 --- a/src/kernel/order.test.c +++ b/src/kernel/order.test.c @@ -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(); } diff --git a/src/skill.c b/src/skill.c index 3d5b77a96..b279ab488 100644 --- a/src/skill.c +++ b/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; +} diff --git a/src/skill.h b/src/skill.h index 3c88be725..ad6c7c2cb 100644 --- a/src/skill.h +++ b/src/skill.h @@ -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 diff --git a/src/skill.test.c b/src/skill.test.c index abfe529f9..09e9c8fe9 100644 --- a/src/skill.test.c +++ b/src/skill.test.c @@ -1,6 +1,8 @@ #include -#include "skill.h" + +#include "kernel/config.h" #include "util/language.h" +#include "skill.h" #include "tests.h" #include @@ -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; } diff --git a/src/study.c b/src/study.c index bd29fc2a8..c978e69ad 100644 --- a/src/study.c +++ b/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); } /* ------------------------------------------------------------- */ diff --git a/src/study.h b/src/study.h index e99fb4808..cca0428b7 100644 --- a/src/study.h +++ b/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 From 9456c4bdc7306f8be246764de07ef04aa04ce35f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 9 Sep 2018 15:16:11 +0200 Subject: [PATCH 5/5] fix debug logging. --- scripts/tests/e3/buildings.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/tests/e3/buildings.lua b/scripts/tests/e3/buildings.lua index e642c1aa7..9899d138e 100644 --- a/scripts/tests/e3/buildings.lua +++ b/scripts/tests/e3/buildings.lua @@ -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