BUG 2507: LERNE AUTO with invalid skill.

This commit is contained in:
Enno Rehling 2018-10-28 21:27:24 +01:00
parent 1305edb744
commit 113a6e68c7
4 changed files with 59 additions and 32 deletions

View File

@ -34,17 +34,19 @@ int autostudy_init(scholar scholars[], int max_scholars, region *r)
int nscholars = 0; int nscholars = 0;
for (u = r->units; u; u = u->next) { 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 (kwd == K_AUTOSTUDY) {
if (long_order_allowed(u) && unit_can_study(u)) { if (long_order_allowed(u)) {
scholar * st = scholars + nscholars; scholar * st = scholars + nscholars;
init_order(u->thisorder, u->faction->locale); skill_t sk = getskill(u->faction->locale);
st->sk = getskill(u->faction->locale); if (check_student(u, u->thisorder, sk)) {
st->level = effskill_study(u, st->sk); st->sk = sk;
st->learn = 0; st->level = effskill_study(u, st->sk);
st->u = u; st->learn = 0;
if (++nscholars == max_scholars) { st->u = u;
log_fatal("you must increase MAXSCHOLARS"); if (++nscholars == max_scholars) {
log_fatal("you must increase MAXSCHOLARS");
}
} }
} }
else { else {

View File

@ -116,7 +116,9 @@ skill_t get_skill(const char *s, const struct locale * lang)
int skill_cost(skill_t sk) { int skill_cost(skill_t sk) {
static int config; static int config;
static int costs[MAXSKILLS]; static int costs[MAXSKILLS];
int cost; int cost = -1;
assert(sk >= 0 && sk < MAXSKILLS);
switch (sk) { switch (sk) {
case SK_SPY: case SK_SPY:
cost = 100; cost = 100;
@ -146,5 +148,6 @@ int skill_cost(skill_t sk) {
} }
bool expensive_skill(skill_t sk) { bool expensive_skill(skill_t sk) {
assert(sk >= 0 && sk < MAXSKILLS);
return (sk == SK_MAGIC) || skill_cost(sk) > 0; return (sk == SK_MAGIC) || skill_cost(sk) > 0;
} }

View File

@ -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); 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) int study_cmd(unit * u, order * ord)
{ {
region *r = u->region; region *r = u->region;
@ -536,7 +578,6 @@ int study_cmd(unit * u, order * ord)
skill_t sk; skill_t sk;
int maxalchemy = 0; int maxalchemy = 0;
int speed_rule = (study_rule_t)config_get_int("study.speedup", 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 const race *rc_snotling;
static int rc_cache; static int rc_cache;
@ -544,32 +585,12 @@ int study_cmd(unit * u, order * ord)
rc_snotling = get_race(RC_SNOTLING); 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); (void)init_order(ord, u->faction->locale);
sk = getskill(u->faction->locale); sk = getskill(u->faction->locale);
if (sk < 0) { if (!check_student(u, ord, sk)) {
cmistake(u, ord, 77, MSG_EVENT);
return -1; 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 */ /* snotlings koennen Talente nur bis T8 lernen */
if (u_race(u) == rc_snotling) { if (u_race(u) == rc_snotling) {

View File

@ -47,6 +47,7 @@ extern "C" {
skill_t getskill(const struct locale *lang); skill_t getskill(const struct locale *lang);
bool is_migrant(struct unit *u); bool is_migrant(struct unit *u);
int study_cost(struct unit *u, skill_t sk); 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); typedef void(*learn_fun)(struct unit *u, skill_t sk, int days);