forked from github/server
- bei mehereren Lehrern kriegen alle eine Meldung, nicht nur der letzte
This commit is contained in:
parent
b2c5c55ea3
commit
ccf0fe9bf7
|
@ -133,7 +133,7 @@ study_cost(unit *u, int talent)
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
|
|
||||||
typedef struct teaching_info {
|
typedef struct teaching_info {
|
||||||
unit * teacher;
|
unit * teachers[4];
|
||||||
int value;
|
int value;
|
||||||
} teaching_info;
|
} teaching_info;
|
||||||
|
|
||||||
|
@ -159,92 +159,96 @@ static int
|
||||||
teach_unit(unit * teacher, unit * student, int nteaching, skill_t sk,
|
teach_unit(unit * teacher, unit * student, int nteaching, skill_t sk,
|
||||||
boolean report, int * academy)
|
boolean report, int * academy)
|
||||||
{
|
{
|
||||||
teaching_info * teach = NULL;
|
teaching_info * teach = NULL;
|
||||||
attrib * a;
|
attrib * a;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
/* learning sind die Tage, die sie schon durch andere Lehrer zugute
|
/* learning sind die Tage, die sie schon durch andere Lehrer zugute
|
||||||
* geschrieben bekommen haben. Total darf dies nicht über 30 Tage pro Mann
|
* geschrieben bekommen haben. Total darf dies nicht über 30 Tage pro Mann
|
||||||
* steigen.
|
* steigen.
|
||||||
*
|
*
|
||||||
* n ist die Anzahl zusätzlich gelernter Tage. n darf max. die Differenz
|
* n ist die Anzahl zusätzlich gelernter Tage. n darf max. die Differenz
|
||||||
* von schon gelernten Tagen zum max(30 Tage pro Mann) betragen. */
|
* von schon gelernten Tagen zum max(30 Tage pro Mann) betragen. */
|
||||||
|
|
||||||
if (magic_lowskill(student)){
|
if (magic_lowskill(student)){
|
||||||
cmistake(teacher, teacher->thisorder, 292, MSG_EVENT);
|
cmistake(teacher, teacher->thisorder, 292, MSG_EVENT);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = student->number * 30;
|
n = student->number * 30;
|
||||||
a = a_find(student->attribs, &at_learning);
|
a = a_find(student->attribs, &at_learning);
|
||||||
if (a!=NULL) {
|
if (a!=NULL) {
|
||||||
teach = (teaching_info*)a->data.v;
|
teach = (teaching_info*)a->data.v;
|
||||||
n -= teach->value;
|
n -= teach->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = min(n, nteaching);
|
n = min(n, nteaching);
|
||||||
|
|
||||||
if (n != 0) {
|
if (n != 0) {
|
||||||
struct building * b = inside_building(teacher);
|
struct building * b = inside_building(teacher);
|
||||||
const struct building_type * btype = b?b->type:NULL;
|
const struct building_type * btype = b?b->type:NULL;
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
if (teach==NULL) {
|
if (teach==NULL) {
|
||||||
a = a_add(&student->attribs, a_new(&at_learning));
|
a = a_add(&student->attribs, a_new(&at_learning));
|
||||||
teach = (teaching_info*)a->data.v;
|
teach = (teaching_info*)a->data.v;
|
||||||
}
|
} else {
|
||||||
teach->teacher = teacher;
|
while (teach->teachers[index]) ++index;
|
||||||
teach->value += n;
|
}
|
||||||
|
teach->teachers[index] = teacher;
|
||||||
|
teach->teachers[index+1] = NULL;
|
||||||
|
teach->value += n;
|
||||||
|
|
||||||
/* Solange Akademien größenbeschränkt sind, sollte Lehrer und
|
/* Solange Akademien größenbeschränkt sind, sollte Lehrer und
|
||||||
* Student auch in unterschiedlichen Gebäuden stehen dürfen */
|
* Student auch in unterschiedlichen Gebäuden stehen dürfen */
|
||||||
if (btype == bt_find("academy")
|
if (btype == bt_find("academy")
|
||||||
&& student->building && student->building->type == bt_find("academy"))
|
&& student->building && student->building->type == bt_find("academy"))
|
||||||
{
|
{
|
||||||
int j = study_cost(student, sk);
|
int j = study_cost(student, sk);
|
||||||
j = max(50, j * 2);
|
j = max(50, j * 2);
|
||||||
/* kann Einheit das zahlen? */
|
/* kann Einheit das zahlen? */
|
||||||
if (get_pooled(student, student->region, R_SILVER) >= j) {
|
if (get_pooled(student, student->region, R_SILVER) >= j) {
|
||||||
/* Jeder Schüler zusätzlich +10 Tage wenn in Uni. */
|
/* Jeder Schüler zusätzlich +10 Tage wenn in Uni. */
|
||||||
teach->value += (n / 30) * 10; /* learning erhöhen */
|
teach->value += (n / 30) * 10; /* learning erhöhen */
|
||||||
/* Lehrer zusätzlich +1 Tag pro Schüler. */
|
/* Lehrer zusätzlich +1 Tag pro Schüler. */
|
||||||
if (academy) *academy += n;
|
if (academy) *academy += n;
|
||||||
} /* sonst nehmen sie nicht am Unterricht teil */
|
} /* sonst nehmen sie nicht am Unterricht teil */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Teaching ist die Anzahl Leute, denen man noch was beibringen kann. Da
|
/* Teaching ist die Anzahl Leute, denen man noch was beibringen kann. Da
|
||||||
* hier nicht n verwendet wird, werden die Leute gezählt und nicht die
|
* hier nicht n verwendet wird, werden die Leute gezählt und nicht die
|
||||||
* effektiv gelernten Tage. -> FALSCH ? (ENNO)
|
* effektiv gelernten Tage. -> FALSCH ? (ENNO)
|
||||||
*
|
*
|
||||||
* Eine Einheit A von 11 Mann mit Talent 0 profitiert vom ersten Lehrer B
|
* Eine Einheit A von 11 Mann mit Talent 0 profitiert vom ersten Lehrer B
|
||||||
* also 10x30=300 tage, und der zweite Lehrer C lehrt für nur noch 1x30=30
|
* also 10x30=300 tage, und der zweite Lehrer C lehrt für nur noch 1x30=30
|
||||||
* Tage (damit das Maximum von 11x30=330 nicht überschritten wird).
|
* Tage (damit das Maximum von 11x30=330 nicht überschritten wird).
|
||||||
*
|
*
|
||||||
* Damit es aber in der Ausführung nicht auf die Reihenfolge drauf ankommt,
|
* Damit es aber in der Ausführung nicht auf die Reihenfolge drauf ankommt,
|
||||||
* darf der zweite Lehrer C keine weiteren Einheiten D mehr lehren. Also
|
* darf der zweite Lehrer C keine weiteren Einheiten D mehr lehren. Also
|
||||||
* wird student 30 Tage gutgeschrieben, aber teaching sinkt auf 0 (300-11x30 <=
|
* wird student 30 Tage gutgeschrieben, aber teaching sinkt auf 0 (300-11x30 <=
|
||||||
* 0).
|
* 0).
|
||||||
*
|
*
|
||||||
* Sonst träte dies auf:
|
* Sonst träte dies auf:
|
||||||
*
|
*
|
||||||
* A: lernt B: lehrt A C: lehrt A D D: lernt
|
* A: lernt B: lehrt A C: lehrt A D D: lernt
|
||||||
*
|
*
|
||||||
* Wenn B vor C dran ist, lehrt C nur 30 Tage an A (wie oben) und
|
* Wenn B vor C dran ist, lehrt C nur 30 Tage an A (wie oben) und
|
||||||
* 270 Tage an D.
|
* 270 Tage an D.
|
||||||
*
|
*
|
||||||
* Ist C aber vor B dran, lehrt C 300 tage an A, und 0 tage an D,
|
* Ist C aber vor B dran, lehrt C 300 tage an A, und 0 tage an D,
|
||||||
* und B lehrt auch 0 tage an A.
|
* und B lehrt auch 0 tage an A.
|
||||||
*
|
*
|
||||||
* Deswegen darf C D nie lehren dürfen.
|
* Deswegen darf C D nie lehren dürfen.
|
||||||
*
|
*
|
||||||
* -> Das ist wirr. wer hat das entworfen?
|
* -> Das ist wirr. wer hat das entworfen?
|
||||||
* Besser wäre, man macht erst vorab alle zuordnungen, und dann
|
* Besser wäre, man macht erst vorab alle zuordnungen, und dann
|
||||||
* die Talentänderung (enno).
|
* die Talentänderung (enno).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
nteaching = max(0, nteaching - student->number * 30);
|
nteaching = max(0, nteaching - student->number * 30);
|
||||||
|
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -449,293 +453,296 @@ teach(region * r, unit * u)
|
||||||
void
|
void
|
||||||
learn(void)
|
learn(void)
|
||||||
{
|
{
|
||||||
region *r;
|
region *r;
|
||||||
unit *u;
|
unit *u;
|
||||||
int p;
|
int p;
|
||||||
magic_t mtyp;
|
magic_t mtyp;
|
||||||
int l;
|
int l;
|
||||||
int warrior_skill;
|
int warrior_skill;
|
||||||
int studycost;
|
int studycost;
|
||||||
|
|
||||||
/* lernen nach lehren */
|
/* lernen nach lehren */
|
||||||
|
|
||||||
for (r = regions; r; r = r->next) {
|
for (r = regions; r; r = r->next) {
|
||||||
for (u = r->units; u; u = u->next) {
|
for (u = r->units; u; u = u->next) {
|
||||||
int days;
|
int days;
|
||||||
if (rterrain(r) == T_OCEAN){
|
if (rterrain(r) == T_OCEAN){
|
||||||
/* sonderbehandlung aller die auf Ozeanen lernen können */
|
/* sonderbehandlung aller die auf Ozeanen lernen können */
|
||||||
if (u->race != new_race[RC_AQUARIAN]
|
if (u->race != new_race[RC_AQUARIAN]
|
||||||
&& !(u->race->flags & RCF_SWIM)) {
|
&& !(u->race->flags & RCF_SWIM)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
}
|
|
||||||
if (igetkeyword(u->thisorder, u->faction->locale) == K_STUDY) {
|
|
||||||
double multi = 1.0;
|
|
||||||
attrib * a = NULL;
|
|
||||||
teaching_info * teach = NULL;
|
|
||||||
int money = 0;
|
|
||||||
skill_t sk;
|
|
||||||
int maxalchemy = 0;
|
|
||||||
if (u->race == new_race[RC_INSECT] && r_insectstalled(r)
|
|
||||||
&& !is_cursed(u->attribs, C_KAELTESCHUTZ,0)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (attacked(u)) {
|
|
||||||
cmistake(u, findorder(u, u->thisorder), 52, MSG_PRODUCE);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ((u->race->flags & RCF_NOLEARN) || fval(u, UFL_WERE)) {
|
|
||||||
sprintf(buf, "%s können nichts lernen", LOC(default_locale, rc_name(u->race, 1)));
|
|
||||||
mistake(u, u->thisorder, buf, MSG_EVENT);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
sk = getskill(u->faction->locale);
|
|
||||||
|
|
||||||
if (sk < 0) {
|
|
||||||
cmistake(u, findorder(u, u->thisorder), 77, MSG_EVENT);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (SkillCap(sk) && SkillCap(sk) <= effskill(u, sk)) {
|
|
||||||
cmistake(u, findorder(u, u->thisorder), 77, MSG_EVENT);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* Hack: Talente mit Malus -99 können nicht gelernt werden */
|
|
||||||
if (u->race->bonus[sk] == -99) {
|
|
||||||
cmistake(u, findorder(u, u->thisorder), 77, MSG_EVENT);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* snotlings können Talente nur bis T8 lernen */
|
|
||||||
if (u->race == new_race[RC_SNOTLING]){
|
|
||||||
if (get_level(u, sk) >= 8){
|
|
||||||
cmistake(u, findorder(u, u->thisorder), 308, MSG_EVENT);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 für Migranten. Vertraute sind
|
|
||||||
* keine Migranten, wird in is_migrant abgefangen. Vorsicht,
|
|
||||||
* studycost darf hier noch nicht durch Akademie erhöht sein */
|
|
||||||
if (studycost > 0 && !ExpensiveMigrants() && is_migrant(u)) {
|
|
||||||
sprintf(buf, "Migranten können keine kostenpflichtigen Talente lernen");
|
|
||||||
mistake(u, u->thisorder, buf, MSG_EVENT);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* Akademie: */
|
|
||||||
{
|
|
||||||
struct building * b = inside_building(u);
|
|
||||||
const struct building_type * btype = b?b->type:NULL;
|
|
||||||
|
|
||||||
if (btype == bt_find("academy")) {
|
|
||||||
studycost = max(50, studycost * 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sk == SK_MAGIC) {
|
|
||||||
if (u->number > 1){
|
|
||||||
cmistake(u, findorder(u, u->thisorder), 106, MSG_MAGIC);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (is_familiar(u)){
|
|
||||||
/* Vertraute zählen nicht zu den Magiern einer Partei,
|
|
||||||
* können aber nur Graue Magie lernen */
|
|
||||||
mtyp = M_GRAU;
|
|
||||||
if (!has_skill(u, SK_MAGIC)) {
|
|
||||||
create_mage(u, mtyp);
|
|
||||||
}
|
|
||||||
} else if (!has_skill(u, SK_MAGIC)){
|
|
||||||
/* Die Einheit ist noch kein Magier */
|
|
||||||
if (count_skill(u->faction, SK_MAGIC) + u->number >
|
|
||||||
max_skill(u->faction, SK_MAGIC))
|
|
||||||
{
|
|
||||||
sprintf(buf, "Es kann maximal %d Magier pro Partei geben",
|
|
||||||
max_skill(u->faction, SK_MAGIC));
|
|
||||||
mistake(u, u->thisorder, buf, MSG_EVENT);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
mtyp = getmagicskill();
|
|
||||||
if (mtyp == M_NONE || mtyp == M_GRAU) {
|
|
||||||
/* wurde kein Magiegebiet angegeben, wird davon
|
|
||||||
* ausgegangen, daß 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 gewählt. */
|
|
||||||
cmistake(u, findorder(u, u->thisorder), 178, MSG_MAGIC);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mtyp != u->faction->magiegebiet){
|
|
||||||
/* Es wurde versucht, ein anderes Magiegebiet zu lernen
|
|
||||||
* als das der Partei */
|
|
||||||
if (u->faction->magiegebiet != 0){
|
|
||||||
cmistake(u, findorder(u, u->thisorder), 179, MSG_MAGIC);
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
/* Lernt zum ersten mal Magie und legt damit das
|
|
||||||
* Magiegebiet der Partei fest */
|
|
||||||
u->faction->magiegebiet = mtyp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
create_mage(u, mtyp);
|
|
||||||
} else {
|
|
||||||
/* ist schon ein Magier und kein Vertrauter */
|
|
||||||
if(u->faction->magiegebiet == 0){
|
|
||||||
/* die Partei hat noch kein Magiegebiet gewählt. */
|
|
||||||
mtyp = getmagicskill();
|
|
||||||
if (mtyp == M_NONE){
|
|
||||||
cmistake(u, findorder(u, u->thisorder), 178, MSG_MAGIC);
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
/* 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)==0
|
|
||||||
&& count_skill(u->faction, SK_ALCHEMY) + u->number >
|
|
||||||
max_skill(u->faction, SK_ALCHEMY)) {
|
|
||||||
sprintf(buf, "Es kann maximal %d Alchemisten pro Partei geben",
|
|
||||||
max_skill(u->faction, SK_ALCHEMY));
|
|
||||||
mistake(u, u->thisorder, buf, MSG_EVENT);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (studycost) {
|
|
||||||
money = get_pooled(u, r, R_SILVER);
|
|
||||||
money = min(money, studycost * u->number);
|
|
||||||
}
|
|
||||||
if (money < studycost * u->number) {
|
|
||||||
studycost = p; /* Ohne Univertreurung */
|
|
||||||
money = min(money, studycost);
|
|
||||||
if (p>0 && money < studycost * u->number) {
|
|
||||||
#ifdef PARTIAL_STUDY
|
|
||||||
cmistake(u, findorder(u, u->thisorder), 65, MSG_EVENT);
|
|
||||||
multi = money / (double)(studycost * u->number);
|
|
||||||
#else
|
|
||||||
cmistake(u, findorder(u, u->thisorder), 65, MSG_EVENT);
|
|
||||||
continue; /* nein, Silber reicht auch so nicht */
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (teach==NULL) {
|
|
||||||
a = a_add(&u->attribs, a_new(&at_learning));
|
|
||||||
teach = (teaching_info*)a->data.v;
|
|
||||||
teach->teacher = NULL;
|
|
||||||
}
|
|
||||||
if (money>0) {
|
|
||||||
use_pooled(u, r, R_SILVER, money);
|
|
||||||
add_message(&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);
|
|
||||||
}
|
|
||||||
|
|
||||||
warrior_skill = fspecial(u->faction, FS_WARRIOR);
|
|
||||||
if(warrior_skill > 0) {
|
|
||||||
if(sk == SK_CROSSBOW || sk == SK_LONGBOW
|
|
||||||
|| sk == SK_CATAPULT || sk == SK_SWORD || sk == SK_SPEAR
|
|
||||||
|| sk == SK_AUSDAUER || sk == SK_WEAPONLESS)
|
|
||||||
{
|
|
||||||
teach->value += u->number * (5+warrior_skill*5);
|
|
||||||
} else {
|
|
||||||
teach->value -= u->number * (5+warrior_skill*5);
|
|
||||||
teach->value = max(0, teach->value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
days = (int)((u->number * 30 + 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(buildingtype_exists(r, bt_find("artacademy"))) {
|
|
||||||
days *= 2;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (fval(u, UFL_HUNGER)) days = days / 2;
|
if (igetkeyword(u->thisorder, u->faction->locale) == K_STUDY) {
|
||||||
|
double multi = 1.0;
|
||||||
|
attrib * a = NULL;
|
||||||
|
teaching_info * teach = NULL;
|
||||||
|
int money = 0;
|
||||||
|
skill_t sk;
|
||||||
|
int maxalchemy = 0;
|
||||||
|
if (u->race == new_race[RC_INSECT] && r_insectstalled(r)
|
||||||
|
&& !is_cursed(u->attribs, C_KAELTESCHUTZ,0)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (attacked(u)) {
|
||||||
|
cmistake(u, findorder(u, u->thisorder), 52, MSG_PRODUCE);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((u->race->flags & RCF_NOLEARN) || fval(u, UFL_WERE)) {
|
||||||
|
sprintf(buf, "%s können nichts lernen", LOC(default_locale, rc_name(u->race, 1)));
|
||||||
|
mistake(u, u->thisorder, buf, MSG_EVENT);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
while (days) {
|
sk = getskill(u->faction->locale);
|
||||||
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) {
|
|
||||||
if (teach && teach->teacher) {
|
|
||||||
unit * teacher = teach->teacher;
|
|
||||||
if (teacher->faction != u->faction) {
|
|
||||||
add_message(&u->faction->msgs, msg_message("teach_student",
|
|
||||||
"teacher student skill", teacher, u, sk));
|
|
||||||
add_message(&teacher->faction->msgs, msg_message("teach_teacher",
|
|
||||||
"teacher student skill level", teacher, u, sk,
|
|
||||||
effskill(u, sk)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
a_remove(&u->attribs, a);
|
|
||||||
a = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Anzeigen neuer Tränke */
|
if (sk < 0) {
|
||||||
/* Spruchlistenaktualiesierung ist in Regeneration */
|
cmistake(u, findorder(u, u->thisorder), 77, MSG_EVENT);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (SkillCap(sk) && SkillCap(sk) <= effskill(u, sk)) {
|
||||||
|
cmistake(u, findorder(u, u->thisorder), 77, MSG_EVENT);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Hack: Talente mit Malus -99 können nicht gelernt werden */
|
||||||
|
if (u->race->bonus[sk] == -99) {
|
||||||
|
cmistake(u, findorder(u, u->thisorder), 77, MSG_EVENT);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* snotlings können Talente nur bis T8 lernen */
|
||||||
|
if (u->race == new_race[RC_SNOTLING]){
|
||||||
|
if (get_level(u, sk) >= 8){
|
||||||
|
cmistake(u, findorder(u, u->thisorder), 308, MSG_EVENT);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (sk == SK_ALCHEMY) {
|
p = studycost = study_cost(u, sk);
|
||||||
const potion_type * ptype;
|
a = a_find(u->attribs, &at_learning);
|
||||||
faction * f = u->faction;
|
if (a!=NULL) {
|
||||||
int skill = eff_skill(u, SK_ALCHEMY, r);
|
teach = (teaching_info*)a->data.v;
|
||||||
if (skill>maxalchemy) {
|
}
|
||||||
for (ptype=potiontypes; ptype; ptype=ptype->next) {
|
|
||||||
if (skill == ptype->level * 2) {
|
/* keine kostenpflichtigen Talente für Migranten. Vertraute sind
|
||||||
attrib * a = a_find(f->attribs, &at_showitem);
|
* keine Migranten, wird in is_migrant abgefangen. Vorsicht,
|
||||||
while (a && a->data.v != ptype) a=a->nexttype;
|
* studycost darf hier noch nicht durch Akademie erhöht sein */
|
||||||
if (!a) {
|
if (studycost > 0 && !ExpensiveMigrants() && is_migrant(u)) {
|
||||||
a = a_add(&f->attribs, a_new(&at_showitem));
|
sprintf(buf, "Migranten können keine kostenpflichtigen Talente lernen");
|
||||||
a->data.v = (void*) ptype->itype;
|
mistake(u, u->thisorder, buf, MSG_EVENT);
|
||||||
}
|
continue;
|
||||||
}
|
}
|
||||||
}
|
/* Akademie: */
|
||||||
}
|
{
|
||||||
}
|
struct building * b = inside_building(u);
|
||||||
}
|
const struct building_type * btype = b?b->type:NULL;
|
||||||
}
|
|
||||||
}
|
if (btype == bt_find("academy")) {
|
||||||
|
studycost = max(50, studycost * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sk == SK_MAGIC) {
|
||||||
|
if (u->number > 1){
|
||||||
|
cmistake(u, findorder(u, u->thisorder), 106, MSG_MAGIC);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (is_familiar(u)){
|
||||||
|
/* Vertraute zählen nicht zu den Magiern einer Partei,
|
||||||
|
* können aber nur Graue Magie lernen */
|
||||||
|
mtyp = M_GRAU;
|
||||||
|
if (!has_skill(u, SK_MAGIC)) {
|
||||||
|
create_mage(u, mtyp);
|
||||||
|
}
|
||||||
|
} else if (!has_skill(u, SK_MAGIC)){
|
||||||
|
/* Die Einheit ist noch kein Magier */
|
||||||
|
if (count_skill(u->faction, SK_MAGIC) + u->number >
|
||||||
|
max_skill(u->faction, SK_MAGIC))
|
||||||
|
{
|
||||||
|
sprintf(buf, "Es kann maximal %d Magier pro Partei geben",
|
||||||
|
max_skill(u->faction, SK_MAGIC));
|
||||||
|
mistake(u, u->thisorder, buf, MSG_EVENT);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
mtyp = getmagicskill();
|
||||||
|
if (mtyp == M_NONE || mtyp == M_GRAU) {
|
||||||
|
/* wurde kein Magiegebiet angegeben, wird davon
|
||||||
|
* ausgegangen, daß 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 gewählt. */
|
||||||
|
cmistake(u, findorder(u, u->thisorder), 178, MSG_MAGIC);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mtyp != u->faction->magiegebiet){
|
||||||
|
/* Es wurde versucht, ein anderes Magiegebiet zu lernen
|
||||||
|
* als das der Partei */
|
||||||
|
if (u->faction->magiegebiet != 0){
|
||||||
|
cmistake(u, findorder(u, u->thisorder), 179, MSG_MAGIC);
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
/* Lernt zum ersten mal Magie und legt damit das
|
||||||
|
* Magiegebiet der Partei fest */
|
||||||
|
u->faction->magiegebiet = mtyp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
create_mage(u, mtyp);
|
||||||
|
} else {
|
||||||
|
/* ist schon ein Magier und kein Vertrauter */
|
||||||
|
if(u->faction->magiegebiet == 0){
|
||||||
|
/* die Partei hat noch kein Magiegebiet gewählt. */
|
||||||
|
mtyp = getmagicskill();
|
||||||
|
if (mtyp == M_NONE){
|
||||||
|
cmistake(u, findorder(u, u->thisorder), 178, MSG_MAGIC);
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
/* 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)==0
|
||||||
|
&& count_skill(u->faction, SK_ALCHEMY) + u->number >
|
||||||
|
max_skill(u->faction, SK_ALCHEMY)) {
|
||||||
|
sprintf(buf, "Es kann maximal %d Alchemisten pro Partei geben",
|
||||||
|
max_skill(u->faction, SK_ALCHEMY));
|
||||||
|
mistake(u, u->thisorder, buf, MSG_EVENT);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (studycost) {
|
||||||
|
money = get_pooled(u, r, R_SILVER);
|
||||||
|
money = min(money, studycost * u->number);
|
||||||
|
}
|
||||||
|
if (money < studycost * u->number) {
|
||||||
|
studycost = p; /* Ohne Univertreurung */
|
||||||
|
money = min(money, studycost);
|
||||||
|
if (p>0 && money < studycost * u->number) {
|
||||||
|
#ifdef PARTIAL_STUDY
|
||||||
|
cmistake(u, findorder(u, u->thisorder), 65, MSG_EVENT);
|
||||||
|
multi = money / (double)(studycost * u->number);
|
||||||
|
#else
|
||||||
|
cmistake(u, findorder(u, u->thisorder), 65, MSG_EVENT);
|
||||||
|
continue; /* nein, Silber reicht auch so nicht */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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, r, R_SILVER, money);
|
||||||
|
add_message(&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);
|
||||||
|
}
|
||||||
|
|
||||||
|
warrior_skill = fspecial(u->faction, FS_WARRIOR);
|
||||||
|
if(warrior_skill > 0) {
|
||||||
|
if(sk == SK_CROSSBOW || sk == SK_LONGBOW
|
||||||
|
|| sk == SK_CATAPULT || sk == SK_SWORD || sk == SK_SPEAR
|
||||||
|
|| sk == SK_AUSDAUER || sk == SK_WEAPONLESS)
|
||||||
|
{
|
||||||
|
teach->value += u->number * (5+warrior_skill*5);
|
||||||
|
} else {
|
||||||
|
teach->value -= u->number * (5+warrior_skill*5);
|
||||||
|
teach->value = max(0, teach->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
days = (int)((u->number * 30 + 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(buildingtype_exists(r, bt_find("artacademy"))) {
|
||||||
|
days *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fval(u, UFL_HUNGER)) days = 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]) {
|
||||||
|
unit * teacher = teach->teachers[index++];
|
||||||
|
if (teacher->faction != u->faction) {
|
||||||
|
add_message(&u->faction->msgs, msg_message("teach_student",
|
||||||
|
"teacher student skill", teacher, u, sk));
|
||||||
|
add_message(&teacher->faction->msgs, msg_message("teach_teacher",
|
||||||
|
"teacher student skill level", teacher, u, sk,
|
||||||
|
effskill(u, sk)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a_remove(&u->attribs, a);
|
||||||
|
a = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Anzeigen neuer Tränke */
|
||||||
|
/* 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->data.v != ptype) a=a->nexttype;
|
||||||
|
if (!a) {
|
||||||
|
a = a_add(&f->attribs, a_new(&at_showitem));
|
||||||
|
a->data.v = (void*) ptype->itype;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue