diff --git a/src/automate.c b/src/automate.c index 1a553df29..9a3516c44 100644 --- a/src/automate.c +++ b/src/automate.c @@ -34,17 +34,19 @@ int autostudy_init(scholar scholars[], int max_scholars, region *r) int nscholars = 0; for (u = r->units; u; u = u->next) { - keyword_t kwd = getkeyword(u->thisorder); + keyword_t kwd = init_order(u->thisorder, u->faction->locale); if (kwd == K_AUTOSTUDY) { - if (long_order_allowed(u) && unit_can_study(u)) { + if (long_order_allowed(u)) { scholar * st = scholars + nscholars; - 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"); + 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->learn = 0; + st->u = u; + if (++nscholars == max_scholars) { + log_fatal("you must increase MAXSCHOLARS"); + } } } else { diff --git a/src/skill.c b/src/skill.c index b279ab488..2521befc6 100644 --- a/src/skill.c +++ b/src/skill.c @@ -116,7 +116,9 @@ skill_t get_skill(const char *s, const struct locale * lang) int skill_cost(skill_t sk) { static int config; static int costs[MAXSKILLS]; - int cost; + int cost = -1; + + assert(sk >= 0 && sk < MAXSKILLS); switch (sk) { case SK_SPY: cost = 100; @@ -146,5 +148,6 @@ int skill_cost(skill_t sk) { } bool expensive_skill(skill_t sk) { + assert(sk >= 0 && sk < MAXSKILLS); return (sk == SK_MAGIC) || skill_cost(sk) > 0; } diff --git a/src/study.c b/src/study.c index c978e69ad..738c591d7 100644 --- a/src/study.c +++ b/src/study.c @@ -523,6 +523,48 @@ static void msg_teachers(struct selist *teachers, struct unit *u, skill_t sk) { selist_foreach_ex(teachers, cb_msg_teach, &cbdata); } +bool check_student(const struct unit *u, struct order *ord, skill_t sk) { + int err = 0; + + if (sk < 0) { + err = 77; + } + /* Hack: Talente mit Malus -99 koennen nicht gelernt werden */ + else if (u_race(u)->bonus[sk] == -99) { + err = 771; + } + else { + static int config; + static bool learn_newskills; + + if (config_changed(&config)) { + learn_newskills = config_get_int("study.newskills", 1) != 0; + } + if (!learn_newskills) { + skill *sv = unit_skill(u, sk); + if (sv == NULL) { + /* we can only learn skills we already have */ + err = 771; + } + } + } + if (err) { + if (ord) { + cmistake(u, ord, err, MSG_EVENT); + } + return false; + } + + if ((u_race(u)->flags & RCF_NOLEARN) || fval(u, UFL_WERE)) { + if (ord) { + ADDMSG(&u->faction->msgs, + msg_feedback(u, ord, "error_race_nolearn", "race", u_race(u))); + } + return false; + } + return true; +} + int study_cmd(unit * u, order * ord) { region *r = u->region; @@ -536,7 +578,6 @@ int study_cmd(unit * u, order * ord) skill_t sk; int maxalchemy = 0; int speed_rule = (study_rule_t)config_get_int("study.speedup", 0); - bool learn_newskills = config_get_int("study.newskills", 1) != 0; static const race *rc_snotling; static int rc_cache; @@ -544,32 +585,12 @@ int study_cmd(unit * u, order * ord) rc_snotling = get_race(RC_SNOTLING); } - if (!unit_can_study(u)) { - ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_race_nolearn", "race", - u_race(u))); - return -1; - } - (void)init_order(ord, u->faction->locale); sk = getskill(u->faction->locale); - if (sk < 0) { - cmistake(u, ord, 77, MSG_EVENT); + if (!check_student(u, ord, sk)) { return -1; } - /* Hack: Talente mit Malus -99 koennen nicht gelernt werden */ - if (u_race(u)->bonus[sk] == -99) { - cmistake(u, ord, 771, MSG_EVENT); - return -1; - } - if (!learn_newskills) { - skill *sv = unit_skill(u, sk); - if (sv == NULL) { - /* we can only learn skills we already have */ - cmistake(u, ord, 771, MSG_EVENT); - return -1; - } - } /* snotlings koennen Talente nur bis T8 lernen */ if (u_race(u) == rc_snotling) { diff --git a/src/study.h b/src/study.h index cca0428b7..f85508dec 100644 --- a/src/study.h +++ b/src/study.h @@ -47,6 +47,7 @@ extern "C" { skill_t getskill(const struct locale *lang); bool is_migrant(struct unit *u); int study_cost(struct unit *u, skill_t sk); + bool check_student(const struct unit *u, struct order *ord, skill_t sk); typedef void(*learn_fun)(struct unit *u, skill_t sk, int days);