static void get_some_skills(int who, int body, int chance) { struct skill_ent *e; int parent; /* * First do category skills */ loop_char_skill_known(body, e) { parent = skill_school(e->skill); if (parent != e->skill) continue; if (has_skill(who, e->skill)) continue; if (e->skill == sk_adv_sorcery) continue; /* * Fri Sep 20 12:49:59 1996 -- Scott Turner * * Can't learn religions by eating the dead! * */ if (rp_relig_skill(e->skill)) continue; if (rnd(1, 100) > chance) continue; learn_skill(who, e->skill); }
/** Talente von Dämonen verschieben sich. */ static void demon_skillchanges(void) { region *r; for (r = regions; r; r = r->next) { unit *u; for (u = r->units; u; u = u->next) { if (u_race(u) == get_race(RC_DAEMON)) { skill *sv = u->skills; int upchance = 15; int downchance = 10; if (fval(u, UFL_HUNGER)) { /* hungry demons only go down, never up in skill */ static int rule_hunger = -1; if (rule_hunger < 0) { rule_hunger = get_param_int(global.parameters, "hunger.demon.skill", 0); } if (rule_hunger) { upchance = 0; downchance = 15; } } while (sv != u->skills + u->skill_size) { int roll = rng_int() % 100; if (sv->level > 0 && roll < upchance + downchance) { int weeks = 1 + rng_int() % 3; if (roll < downchance) { reduce_skill(u, sv, weeks); if (sv->level < 1) { /* demons should never forget below 1 */ set_level(u, sv->id, 1); } } else { while (weeks--) learn_skill(u, sv->id, 1.0); } if (sv->old > sv->level) { if (verbosity >= 3) { log_printf(stdout, "%s dropped from %u to %u:%u in %s\n", unitname(u), sv->old, sv->level, sv->weeks, skillname(sv->id, NULL)); } } } ++sv; } } } } }
static bool improve_all(faction * f, skill_t sk, int by_weeks) { unit *u; bool result = false; for (u = f->units; u; u = u->nextF) { if (has_skill(u, sk)) { learn_skill(u, sk, by_weeks * STUDYDAYS); result = true; } } return result; }
loop_char_skill_known(body, e) { parent = skill_school(e->skill); if (parent == e->skill) continue; if (has_skill(who, e->skill) || has_skill(who, parent) == 0) continue; if (rnd(1, 100) > chance) continue; learn_skill(who, e->skill); }
int v_fix2(struct command *c) { int i; loop_char(i) { if (char_auraculum(i)) learn_skill(i, sk_adv_sorcery); } next_char; return TRUE; }
int v_know(struct command *c) { if (kind(c->a) != T_skill) { wout(c->who, "%s is not a skill.", c->parse[1]); return FALSE; } #if 1 learn_skill(c->who, c->a); #else set_skill(c->who, c->a, SKILL_know); #endif return TRUE; }
static int improve_all(faction * f, skill_t sk, int by_weeks) { unit *u; bool ret = by_weeks; for (u = f->units; u; u = u->nextF) { if (has_skill(u, sk)) { int weeks = 0; for (; weeks != by_weeks; ++weeks) { learn_skill(u, sk, 1.0); ret = 0; } } } return ret; }
/** Talente von Daemonen verschieben sich. */ void demon_skillchange(unit *u) { skill *sv = u->skills; int upchance = 15, downchance = 10; static int config; static bool rule_hunger; static int cfgup, cfgdown; if (config_changed(&config)) { rule_hunger = config_get_int("hunger.demon.skills", 0) != 0; cfgup = config_get_int("skillchange.demon.up", 15); cfgdown = config_get_int("skillchange.demon.down", 10); } if (cfgup == 0) { /* feature is disabled */ return; } upchance = cfgup; downchance = cfgdown; if (fval(u, UFL_HUNGER)) { /* hungry demons only go down, never up in skill */ if (rule_hunger) { downchance = upchance; upchance = 0; } } while (sv != u->skills + u->skill_size) { int roll = rng_int() % 100; if (sv->level > 0 && roll < upchance + downchance) { int weeks = 1 + rng_int() % 3; if (roll < downchance) { reduce_skill(u, sv, weeks); if (sv->level < 1) { /* demons should never forget below 1 */ set_level(u, sv->id, 1); } } else { learn_skill(u, sv->id, STUDYDAYS * u->number * weeks); } } ++sv; } }
void find_manual(region * r, unit * u) { char zLocation[32]; char zBook[32]; skill_t skill = NOSKILL; message *msg; switch (rng_int() % 36) { case 0: skill = SK_MAGIC; break; case 1: case 2: case 3: case 4: skill = SK_WEAPONSMITH; break; case 5: case 6: skill = SK_TACTICS; break; case 7: case 8: case 9: case 10: skill = SK_SHIPBUILDING; break; case 11: case 12: case 13: case 14: skill = SK_SAILING; break; case 15: case 16: case 17: skill = SK_HERBALISM; break; case 18: case 19: skill = SK_ALCHEMY; break; case 20: case 21: case 22: case 23: skill = SK_BUILDING; break; case 24: case 25: case 26: case 27: skill = SK_ARMORER; break; case 28: case 29: case 30: case 31: skill = SK_MINING; break; case 32: case 33: case 34: case 35: skill = SK_ENTERTAINMENT; break; } slprintf(zLocation, sizeof(zLocation), "manual_location_%d", (int)(rng_int() % 4)); slprintf(zBook, sizeof(zLocation), "manual_title_%s", skillnames[skill]); msg = msg_message("find_manual", "unit location book", u, zLocation, zBook); if (msg) { r_addmessage(r, u->faction, msg); msg_release(msg); } if (improve_all(u->faction, skill, 3) == 3) { int i; for (i = 0; i != 9; ++i) learn_skill(u, skill, 1.0); } }
int study_cmd(unit * u, order * ord) { region *r = u->region; int p; int l; int studycost, days; double multi = 1.0; attrib *a = NULL; teaching_info *teach = NULL; int money = 0; skill_t sk; int maxalchemy = 0; int speed_rule = (study_rule_t)config_get_int("study.speedup", 0); static const race *rc_snotling; static int rc_cache; if (rc_changed(&rc_cache)) { rc_snotling = get_race(RC_SNOTLING); } (void)init_order(ord, u->faction->locale); sk = getskill(u->faction->locale); if (!check_student(u, ord, sk)) { return -1; } /* snotlings koennen Talente nur bis T8 lernen */ if (u_race(u) == rc_snotling) { if (get_level(u, sk) >= 8) { cmistake(u, ord, 308, MSG_EVENT); return -1; } } p = studycost = study_cost(u, sk); a = a_find(u->attribs, &at_learning); if (a != NULL) { teach = (teaching_info *)a->data.v; } /* keine kostenpflichtigen Talente fuer Migranten. Vertraute sind * keine Migranten, wird in is_migrant abgefangen. Vorsicht, * studycost darf hier noch nicht durch Akademie erhoeht sein */ if (studycost > 0 && !ExpensiveMigrants() && is_migrant(u)) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_migrants_nolearn", "")); return -1; } /* Akademie: */ if (active_building(u, bt_find("academy"))) { studycost = studycost * 2; if (studycost < 50) studycost = 50; } if (sk == SK_MAGIC) { magic_t mtype; if (u->number > 1) { cmistake(u, ord, 106, MSG_MAGIC); return -1; } if (is_familiar(u)) { /* Vertraute zaehlen nicht zu den Magiern einer Partei, * koennen aber nur Graue Magie lernen */ mtype = M_GRAY; } else if (!has_skill(u, SK_MAGIC)) { int mmax = faction_skill_limit(u->faction, SK_MAGIC); /* Die Einheit ist noch kein Magier */ if (faction_count_skill(u->faction, SK_MAGIC) + u->number > mmax) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_max_magicians", "amount", mmax)); return -1; } mtype = getmagicskill(u->faction->locale); if (mtype == M_NONE || mtype == M_GRAY) { /* wurde kein Magiegebiet angegeben, wird davon * ausgegangen, dass das normal gelernt werden soll */ if (u->faction->magiegebiet != 0) { mtype = u->faction->magiegebiet; } else { /* Es wurde kein Magiegebiet angegeben und die Partei * hat noch keins gewaehlt. */ mtype = getmagicskill(u->faction->locale); if (mtype == M_NONE) { cmistake(u, ord, 178, MSG_MAGIC); return -1; } } } if (mtype != u->faction->magiegebiet) { /* Es wurde versucht, ein anderes Magiegebiet zu lernen * als das der Partei */ if (u->faction->magiegebiet != 0) { cmistake(u, ord, 179, MSG_MAGIC); return -1; } else { /* Lernt zum ersten mal Magie und legt damit das * Magiegebiet der Partei fest */ u->faction->magiegebiet = mtype; } } create_mage(u, mtype); } else { /* ist schon ein Magier und kein Vertrauter */ if (u->faction->magiegebiet == 0) { /* die Partei hat noch kein Magiegebiet gewaehlt. */ mtype = getmagicskill(u->faction->locale); if (mtype == M_NONE) { mtype = getmagicskill(u->faction->locale); if (mtype == M_NONE) { cmistake(u, ord, 178, MSG_MAGIC); return -1; } } /* Legt damit das Magiegebiet der Partei fest */ u->faction->magiegebiet = mtype; } } } if (sk == SK_ALCHEMY) { maxalchemy = effskill(u, SK_ALCHEMY, NULL); if (!has_skill(u, SK_ALCHEMY)) { int amax = faction_skill_limit(u->faction, SK_ALCHEMY); if (faction_count_skill(u->faction, SK_ALCHEMY) + u->number > amax) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_max_alchemists", "amount", amax)); return -1; } } } if (studycost) { int cost = studycost * u->number; money = get_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, cost); if (money > cost) money = cost; } if (money < studycost * u->number) { studycost = p; /* Ohne Univertreurung */ if (money > studycost) money = studycost; if (p > 0 && money < studycost * u->number) { cmistake(u, ord, 65, MSG_EVENT); multi = money / (double)(studycost * u->number); } } if (teach == NULL) { a = a_add(&u->attribs, a_new(&at_learning)); teach = (teaching_info *)a->data.v; assert(teach); teach->teachers = NULL; } if (money > 0) { use_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, money); ADDMSG(&u->faction->msgs, msg_message("studycost", "unit region cost skill", u, u->region, money, sk)); } if (get_effect(u, oldpotiontype[P_WISE])) { l = get_effect(u, oldpotiontype[P_WISE]); if (l > u->number) l = u->number; teach->days += l * EXPERIENCEDAYS; change_effect(u, oldpotiontype[P_WISE], -l); } if (get_effect(u, oldpotiontype[P_FOOL])) { l = get_effect(u, oldpotiontype[P_FOOL]); if (l > u->number) l = u->number; teach->days -= l * STUDYDAYS; change_effect(u, oldpotiontype[P_FOOL], -l); } if (p != studycost) { /* ist_in_gebaeude(r, u, BT_UNIVERSITAET) == 1) { */ /* p ist Kosten ohne Uni, studycost mit; wenn * p!=studycost, ist die Einheit zwangsweise * in einer Uni */ teach->days += u->number * EXPERIENCEDAYS; } if (is_cursed(r->attribs, &ct_badlearn)) { teach->days -= u->number * EXPERIENCEDAYS; } multi *= study_speedup(u, sk, speed_rule); days = study_days(u, sk); days = (int)((days + teach->days) * multi); /* the artacademy currently improves the learning of entertainment of all units in the region, to be able to make it cumulative with with an academy */ if (sk == SK_ENTERTAINMENT && buildingtype_exists(r, bt_find("artacademy"), false)) { days *= 2; } learn_skill(u, sk, days); if (a != NULL) { if (teach->teachers) { msg_teachers(teach->teachers, u, sk); } a_remove(&u->attribs, a); a = NULL; } u->flags |= (UFL_LONGACTION | UFL_NOTMOVING); /* Anzeigen neuer Traenke */ /* Spruchlistenaktualiesierung ist in Regeneration */ if (sk == SK_ALCHEMY) { faction *f = u->faction; int skill = effskill(u, SK_ALCHEMY, NULL); if (skill > maxalchemy) { show_potions(f, skill); } } init_order(NULL, NULL); return 0; }
int learn_cmd(unit * u, order * ord) { region *r = u->region; int p; magic_t mtyp; int l; int studycost, days; double multi = 1.0; attrib *a = NULL; teaching_info *teach = NULL; int money = 0; skill_t sk; int maxalchemy = 0; int speed_rule = (study_rule_t)get_param_int(global.parameters, "study.speedup", 0); static int learn_newskills = -1; if (learn_newskills < 0) { const char *str = get_param(global.parameters, "study.newskills"); if (str && strcmp(str, "false") == 0) learn_newskills = 0; else learn_newskills = 1; } if (!unit_can_study(u)) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_race_nolearn", "race", u_race(u))); return 0; } init_order(ord); sk = getskill(u->faction->locale); if (sk < 0) { cmistake(u, ord, 77, MSG_EVENT); return 0; } if (SkillCap(sk) && SkillCap(sk) <= effskill(u, sk)) { cmistake(u, ord, 771, MSG_EVENT); return 0; } /* Hack: Talente mit Malus -99 koennen nicht gelernt werden */ if (u_race(u)->bonus[sk] == -99) { cmistake(u, ord, 771, MSG_EVENT); return 0; } if (learn_newskills == 0) { skill *sv = unit_skill(u, sk); if (sv == NULL) { /* we can only learn skills we already have */ cmistake(u, ord, 771, MSG_EVENT); return 0; } } /* snotlings koennen Talente nur bis T8 lernen */ if (u_race(u) == get_race(RC_SNOTLING)) { if (get_level(u, sk) >= 8) { cmistake(u, ord, 308, MSG_EVENT); return 0; } } p = studycost = study_cost(u, sk); a = a_find(u->attribs, &at_learning); if (a != NULL) { teach = (teaching_info *)a->data.v; } /* keine kostenpflichtigen Talente fuer Migranten. Vertraute sind * keine Migranten, wird in is_migrant abgefangen. Vorsicht, * studycost darf hier noch nicht durch Akademie erhoeht sein */ if (studycost > 0 && !ExpensiveMigrants() && is_migrant(u)) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_migrants_nolearn", "")); return 0; } /* Akademie: */ { struct building *b = inside_building(u); const struct building_type *btype = b ? b->type : NULL; if (btype && btype == bt_find("academy")) { studycost = _max(50, studycost * 2); } } if (sk == SK_MAGIC) { if (u->number > 1) { cmistake(u, ord, 106, MSG_MAGIC); return 0; } if (is_familiar(u)) { /* Vertraute zaehlen nicht zu den Magiern einer Partei, * koennen aber nur Graue Magie lernen */ mtyp = M_GRAY; if (!is_mage(u)) create_mage(u, mtyp); } else if (!has_skill(u, SK_MAGIC)) { int mmax = skill_limit(u->faction, SK_MAGIC); /* Die Einheit ist noch kein Magier */ if (count_skill(u->faction, SK_MAGIC) + u->number > mmax) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_max_magicians", "amount", mmax)); return 0; } mtyp = getmagicskill(u->faction->locale); if (mtyp == M_NONE || mtyp == M_GRAY) { /* wurde kein Magiegebiet angegeben, wird davon * ausgegangen, dass das normal gelernt werden soll */ if (u->faction->magiegebiet != 0) { mtyp = u->faction->magiegebiet; } else { /* Es wurde kein Magiegebiet angegeben und die Partei * hat noch keins gewaehlt. */ mtyp = getmagicskill(u->faction->locale); if (mtyp == M_NONE) { cmistake(u, ord, 178, MSG_MAGIC); return 0; } } } if (mtyp != u->faction->magiegebiet) { /* Es wurde versucht, ein anderes Magiegebiet zu lernen * als das der Partei */ if (u->faction->magiegebiet != 0) { cmistake(u, ord, 179, MSG_MAGIC); return 0; } else { /* Lernt zum ersten mal Magie und legt damit das * Magiegebiet der Partei fest */ u->faction->magiegebiet = mtyp; } } if (!is_mage(u)) create_mage(u, mtyp); } else { /* ist schon ein Magier und kein Vertrauter */ if (u->faction->magiegebiet == 0) { /* die Partei hat noch kein Magiegebiet gewaehlt. */ mtyp = getmagicskill(u->faction->locale); if (mtyp == M_NONE) { mtyp = getmagicskill(u->faction->locale); if (mtyp == M_NONE) { cmistake(u, ord, 178, MSG_MAGIC); return 0; } } /* Legt damit das Magiegebiet der Partei fest */ u->faction->magiegebiet = mtyp; } } } if (sk == SK_ALCHEMY) { maxalchemy = eff_skill(u, SK_ALCHEMY, r); if (!has_skill(u, SK_ALCHEMY)) { int amax = skill_limit(u->faction, SK_ALCHEMY); if (count_skill(u->faction, SK_ALCHEMY) + u->number > amax) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_max_alchemists", "amount", amax)); return 0; } } } if (studycost) { int cost = studycost * u->number; money = get_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, cost); money = _min(money, cost); } if (money < studycost * u->number) { studycost = p; /* Ohne Univertreurung */ money = _min(money, studycost); if (p > 0 && money < studycost * u->number) { cmistake(u, ord, 65, MSG_EVENT); multi = money / (double)(studycost * u->number); } } if (teach == NULL) { a = a_add(&u->attribs, a_new(&at_learning)); teach = (teaching_info *)a->data.v; teach->teachers[0] = 0; } if (money > 0) { use_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, money); ADDMSG(&u->faction->msgs, msg_message("studycost", "unit region cost skill", u, u->region, money, sk)); } if (get_effect(u, oldpotiontype[P_WISE])) { l = _min(u->number, get_effect(u, oldpotiontype[P_WISE])); teach->value += l * 10; change_effect(u, oldpotiontype[P_WISE], -l); } if (get_effect(u, oldpotiontype[P_FOOL])) { l = _min(u->number, get_effect(u, oldpotiontype[P_FOOL])); teach->value -= l * 30; change_effect(u, oldpotiontype[P_FOOL], -l); } if (p != studycost) { /* ist_in_gebaeude(r, u, BT_UNIVERSITAET) == 1) { */ /* p ist Kosten ohne Uni, studycost mit; wenn * p!=studycost, ist die Einheit zwangsweise * in einer Uni */ teach->value += u->number * 10; } if (is_cursed(r->attribs, C_BADLEARN, 0)) { teach->value -= u->number * 10; } multi *= study_speedup(u, sk, speed_rule); days = study_days(u, sk); days = (int)((days + teach->value) * multi); /* the artacademy currently improves the learning of entertainment of all units in the region, to be able to make it cumulative with with an academy */ if (sk == SK_ENTERTAINMENT && buildingtype_exists(r, bt_find("artacademy"), false)) { days *= 2; } if (fval(u, UFL_HUNGER)) days /= 2; while (days) { if (days >= u->number * 30) { learn_skill(u, sk, 1.0); days -= u->number * 30; } else { double chance = (double)days / u->number / 30; learn_skill(u, sk, chance); days = 0; } } if (a != NULL) { if (teach != NULL) { int index = 0; while (teach->teachers[index] && index != MAXTEACHERS) { unit *teacher = teach->teachers[index++]; if (teacher->faction != u->faction) { bool feedback = alliedunit(u, teacher->faction, HELP_GUARD); if (feedback) { ADDMSG(&teacher->faction->msgs, msg_message("teach_teacher", "teacher student skill level", teacher, u, sk, effskill(u, sk))); } ADDMSG(&u->faction->msgs, msg_message("teach_student", "teacher student skill", teacher, u, sk)); } } } a_remove(&u->attribs, a); a = NULL; } fset(u, UFL_LONGACTION | UFL_NOTMOVING); /* Anzeigen neuer Traenke */ /* Spruchlistenaktualiesierung ist in Regeneration */ if (sk == SK_ALCHEMY) { const potion_type *ptype; faction *f = u->faction; int skill = eff_skill(u, SK_ALCHEMY, r); if (skill > maxalchemy) { for (ptype = potiontypes; ptype; ptype = ptype->next) { if (skill == ptype->level * 2) { attrib *a = a_find(f->attribs, &at_showitem); while (a && a->type == &at_showitem && a->data.v != ptype) a = a->next; if (a == NULL || a->type != &at_showitem) { a = a_add(&f->attribs, a_new(&at_showitem)); a->data.v = (void *)ptype->itype; } } } } } else if (sk == SK_MAGIC) { sc_mage *mage = get_mage(u); if (!mage) { mage = create_mage(u, u->faction->magiegebiet); } } return 0; }
int teach_cmd(unit * u, struct order *ord) { static const curse_type *gbdream_ct = NULL; plane *pl; region *r = u->region; int teaching, i, j, count, academy = 0; skill_t sk = NOSKILL; if (gbdream_ct == 0) gbdream_ct = ct_find("gbdream"); if (gbdream_ct) { if (get_curse(u->region->attribs, gbdream_ct)) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "gbdream_noteach", "")); return 0; } } if ((u_race(u)->flags & RCF_NOTEACH) || fval(u, UFL_WERE)) { cmistake(u, ord, 274, MSG_EVENT); return 0; } pl = rplane(r); if (pl && fval(pl, PFL_NOTEACH)) { cmistake(u, ord, 273, MSG_EVENT); return 0; } teaching = u->number * 30 * TEACHNUMBER; if ((i = get_effect(u, oldpotiontype[P_FOOL])) > 0) { /* Trank "Dumpfbackenbrot" */ i = _min(i, u->number * TEACHNUMBER); /* Trank wirkt pro Schueler, nicht pro Lehrer */ teaching -= i * 30; change_effect(u, oldpotiontype[P_FOOL], -i); j = teaching / 30; ADDMSG(&u->faction->msgs, msg_message("teachdumb", "teacher amount", u, j)); } if (teaching == 0) return 0; count = 0; init_order(ord); #if TEACH_ALL if (getparam(u->faction->locale) == P_ANY) { unit *student = r->units; skill_t teachskill[MAXSKILLS]; int i = 0; do { sk = getskill(u->faction->locale); teachskill[i++] = sk; } while (sk != NOSKILL); while (teaching && student) { if (student->faction == u->faction) { if (LongHunger(student)) continue; if (getkeyword(student->thisorder) == K_STUDY) { /* Input ist nun von student->thisorder !! */ init_order(student->thisorder); sk = getskill(student->faction->locale); if (sk != NOSKILL && teachskill[0] != NOSKILL) { for (i = 0; teachskill[i] != NOSKILL; ++i) if (sk == teachskill[i]) break; sk = teachskill[i]; } if (sk != NOSKILL && eff_skill_study(u, sk, r) - TEACHDIFFERENCE > eff_skill_study(student, sk, r)) { teaching -= teach_unit(u, student, teaching, sk, true, &academy); } } } student = student->next; } #ifdef TEACH_FRIENDS while (teaching && student) { if (student->faction != u->faction && alliedunit(u, student->faction, HELP_GUARD)) { if (LongHunger(student)) continue; if (getkeyword(student->thisorder) == K_STUDY) { /* Input ist nun von student->thisorder !! */ init_order(student->thisorder); sk = getskill(student->faction->locale); if (sk != NOSKILL && eff_skill_study(u, sk, r) - TEACHDIFFERENCE >= eff_skill(student, sk, r)) { teaching -= teach_unit(u, student, teaching, sk, true, &academy); } } } student = student->next; } #endif } else #endif { char zOrder[4096]; order *new_order; zOrder[0] = '\0'; init_order(ord); while (!parser_end()) { unit *u2; bool feedback; getunit(r, u->faction, &u2); ++count; /* Falls die Unit nicht gefunden wird, Fehler melden */ if (!u2) { char tbuf[20]; const char *uid; const char *token; /* Finde den string, der den Fehler verursacht hat */ parser_pushstate(); init_order(ord); for (j = 0; j != count - 1; ++j) { /* skip over the first 'count' units */ getunit(r, u->faction, NULL); } token = getstrtoken(); /* Beginne die Fehlermeldung */ if (isparam(token, u->faction->locale, P_TEMP)) { token = getstrtoken(); sprintf(tbuf, "%s %s", LOC(u->faction->locale, parameters[P_TEMP]), token); uid = tbuf; } else { uid = token; } ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "unitnotfound_id", "id", uid)); parser_popstate(); continue; } feedback = u->faction == u2->faction || alliedunit(u2, u->faction, HELP_GUARD); /* Neuen Befehl zusammenbauen. TEMP-Einheiten werden automatisch in * ihre neuen Nummern uebersetzt. */ if (zOrder[0]) strcat(zOrder, " "); strcat(zOrder, unitid(u2)); if (getkeyword(u2->thisorder) != K_STUDY) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "teach_nolearn", "student", u2)); continue; } /* Input ist nun von u2->thisorder !! */ parser_pushstate(); init_order(u2->thisorder); sk = getskill(u2->faction->locale); parser_popstate(); if (sk == NOSKILL) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "teach_nolearn", "student", u2)); continue; } /* u is teacher, u2 is student */ if (eff_skill_study(u2, sk, r) > eff_skill_study(u, sk, r) - TEACHDIFFERENCE) { if (feedback) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "teach_asgood", "student", u2)); } continue; } if (sk == SK_MAGIC) { /* ist der Magier schon spezialisiert, so versteht er nur noch * Lehrer seines Gebietes */ sc_mage *mage1 = get_mage(u); sc_mage *mage2 = get_mage(u2); if (!mage2 || !mage1 || (mage2->magietyp != M_GRAY && mage1->magietyp != mage2->magietyp)) { if (feedback) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_different_magic", "target", u2)); } continue; } } teaching -= teach_unit(u, u2, teaching, sk, false, &academy); } new_order = create_order(K_TEACH, u->faction->locale, "%s", zOrder); replace_order(&u->orders, ord, new_order); free_order(new_order); /* parse_order & set_order have each increased the refcount */ } if (academy && sk != NOSKILL) { academy = academy / 30; /* anzahl gelehrter wochen, max. 10 */ learn_skill(u, sk, academy / 30.0 / TEACHNUMBER); } return 0; }