diff --git a/src/common/gamecode/study.c b/src/common/gamecode/study.c index fe771c0e0..d1c8093b4 100644 --- a/src/common/gamecode/study.c +++ b/src/common/gamecode/study.c @@ -121,16 +121,34 @@ study_cost(unit *u, int talent) /* ------------------------------------------------------------- */ +typedef struct teaching_info { + unit * teacher; + int value; +} teaching_info; + +static void +init_learning(struct attrib * a) +{ + a->data.v = calloc(sizeof(teaching_info), 1); +} + +static void +done_learning(struct attrib * a) +{ + free(a->data.v); +} + static const attrib_type at_learning = { "learning", - NULL, NULL, NULL, NULL, NULL, + init_learning, done_learning, NULL, NULL, NULL, ATF_UNIQUE }; static int -teach_unit(unit * teacher, unit * student, int teaching, skill_t sk, +teach_unit(unit * teacher, unit * student, int nteaching, skill_t sk, boolean report, int * academy) { + teaching_info * teach = NULL; attrib * a; int n; @@ -148,22 +166,27 @@ teach_unit(unit * teacher, unit * student, int teaching, skill_t sk, n = student->number * 30; a = a_find(student->attribs, &at_learning); - if (a!=NULL) n -= a->data.i; + if (a!=NULL) { + teach = (teaching_info*)a->data.v; + n -= teach->value; + } - n = min(n, teaching); + n = min(n, nteaching); if (n != 0) { struct building * b = inside_building(teacher); const struct building_type * btype = b?b->type:NULL; - if (a==NULL) a = a_add(&student->attribs, a_new(&at_learning)); - a->data.i += n; + if (teach==NULL) { + a = a_add(&student->attribs, a_new(&at_learning)); + teach = (teaching_info*)a->data.v; + } + teach->teacher = teacher; + teach->value += n; /* Solange Akademien größenbeschränkt sind, sollte Lehrer und * Student auch in unterschiedlichen Gebäuden stehen dürfen */ if (btype == &bt_academy -/* && student->building==teacher->building - * && inside_building(student)!=NULL) */ && student->building && student->building->type == &bt_academy) { int j = study_cost(student, sk); @@ -171,7 +194,7 @@ teach_unit(unit * teacher, unit * student, int teaching, skill_t sk, /* kann Einheit das zahlen? */ if (get_pooled(student, student->region, R_SILVER) >= j) { /* Jeder Schüler zusätzlich +10 Tage wenn in Uni. */ - a->data.i += (n / 30) * 10; /* learning erhöhen */ + teach->value += (n / 30) * 10; /* learning erhöhen */ /* Lehrer zusätzlich +1 Tag pro Schüler. */ if (academy) *academy += n; } /* sonst nehmen sie nicht am Unterricht teil */ @@ -206,16 +229,8 @@ teach_unit(unit * teacher, unit * student, int teaching, skill_t sk, * die Talentänderung (enno). */ - teaching = max(0, teaching - student->number * 30); + nteaching = max(0, nteaching - student->number * 30); - if (report || teacher->faction != student->faction) { - add_message(&student->faction->msgs, msg_message("teach", - "teacher student skill", teacher, student, sk)); - if (teacher->faction != student->faction) { - add_message(&teacher->faction->msgs, msg_message("teach", - "teacher student skill", teacher, student, sk)); - } - } } return n; } @@ -387,7 +402,7 @@ teach(region * r, unit * u) msg_error(u, u->thisorder, "teach_nolearn", "student", u2)); continue; } - if (eff_skill(u, sk, r) <= eff_skill(u2, sk, r)) { + if (eff_skill(u2, sk, r) + TEACHDIFFERENCE >= eff_skill(u, sk, r)) { add_message(&u->faction->msgs, msg_error(u, u->thisorder, "teach_asgood", "student", u2)); continue; @@ -448,6 +463,7 @@ learn(void) if (igetkeyword(u->thisorder, u->faction->locale) == K_STUDY) { double multi = 1.0; attrib * a = NULL; + teaching_info * teach = NULL; int money = 0; int maxalchemy = 0; if (u->race == new_race[RC_INSECT] && r_insectstalled(r) @@ -485,6 +501,9 @@ learn(void) p = studycost = study_cost(u,i); 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, @@ -597,7 +616,11 @@ learn(void) } } - if (a==NULL) a = a_add(&u->attribs, a_new(&at_learning)); + 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", @@ -606,12 +629,12 @@ learn(void) if (get_effect(u, oldpotiontype[P_WISE])) { l = min(u->number, get_effect(u, oldpotiontype[P_WISE])); - a->data.i += l * 10; + 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])); - a->data.i -= l * 30; + teach->value -= l * 30; change_effect(u, oldpotiontype[P_FOOL], -l); } @@ -621,10 +644,10 @@ learn(void) || i == SK_CATAPULT || i == SK_SWORD || i == SK_SPEAR || i == SK_AUSDAUER || i == SK_WEAPONLESS) { - a->data.i += u->number * (5+warrior_skill*5); + teach->value += u->number * (5+warrior_skill*5); } else { - a->data.i -= u->number * (5+warrior_skill*5); - a->data.i = max(0, a->data.i); + teach->value -= u->number * (5+warrior_skill*5); + teach->value = max(0, teach->value); } } @@ -633,20 +656,20 @@ learn(void) /* p ist Kosten ohne Uni, studycost mit; wenn * p!=studycost, ist die Einheit zwangsweise * in einer Uni */ - a->data.i += u->number * 10; + teach->value += u->number * 10; } if (is_cursed(r->attribs,C_BADLEARN,0)) { - a->data.i -= u->number * 10; + teach->value -= u->number * 10; } #ifdef SKILLFIX_SAVE - if (a && a->data.i) { + if (teach && teach->value) { int skill = get_skill(u, (skill_t)i); skillfix(u, (skill_t)i, skill, - (int)(u->number * 30 * multi), a->data.i); + (int)(u->number * 30 * multi), teach->value); } #endif - days = (int)((u->number * 30 + a->data.i) * multi); + days = (int)((u->number * 30 + teach->value) * multi); if (fval(u, FL_HUNGER)) days = days / 2; while (days) { if (days>=u->number*30) { @@ -659,6 +682,16 @@ learn(void) } } 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, (skill_t)i)); + add_message(&teacher->faction->msgs, msg_message("teach_teacher", + "teacher student skill level", teacher, u, (skill_t)i, + effskill(u, (skill_t)i))); + } + } a_remove(&u->attribs, a); a = NULL; } @@ -689,7 +722,6 @@ learn(void) } - void teaching(void) { diff --git a/src/common/kernel/save.c b/src/common/kernel/save.c index c4b72fed1..4bd82a35a 100644 --- a/src/common/kernel/save.c +++ b/src/common/kernel/save.c @@ -276,7 +276,7 @@ ri36(FILE * F) } #define MAXLINE 4096*16 -static char * +char * getbuf(FILE * F) { char lbuf[MAXLINE]; diff --git a/src/common/kernel/save.h b/src/common/kernel/save.h index 362c0043d..1aeb4d908 100644 --- a/src/common/kernel/save.h +++ b/src/common/kernel/save.h @@ -74,5 +74,6 @@ extern struct region * readregion(FILE * stream, int x, int y); extern void writefaction(FILE * stream, const struct faction * f); extern struct faction * readfaction(FILE * stream); +extern char * getbuf(FILE * F); #endif diff --git a/src/mapper/map_partei.c b/src/mapper/map_partei.c index fd052e7a4..bc1e11950 100644 --- a/src/mapper/map_partei.c +++ b/src/mapper/map_partei.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,8 @@ #include #include +const char * orderfile = NULL; + void RemovePartei(void) { faction *f, *F; @@ -153,12 +156,57 @@ give_latestart_bonus(region *r, unit *u, int b) typedef struct dropout { struct dropout * next; const struct race * race; - int x, y; + int x, y, fno; } dropout; static dropout * dropouts; static newfaction * newfactions; +void +read_orders(const char * filename) +{ + faction * f = NULL; + FILE * F = fopen(filename, "r"); + char * b; + char buffer[16]; + + if (F==NULL) return; + b = getbuf(F); + + for (;;) { + switch (igetparam(b, default_locale)) { + case P_GAMENAME: + case P_FACTION: + strncpy(buffer, getstrtoken(), 16); + f = findfaction(atoi36(buffer)); + if (f) fset(f, FL_MARK); + break; + + case P_NEXT: + f = NULL; + break; + } + b = getbuf(F); + } + fclose(F); + for (f=factions;f;f=f->next) { + if (!fval(f, FL_MARK) && f->age <=1) { + ursprung * ur = f->ursprung; + while (ur && ur->id!=0) ur=ur->next; + if (ur) { + dropout * drop = calloc(sizeof(dropout), 1); + drop->x = ur->x; + drop->y = ur->y; + drop->fno = f->no; + drop->race = f->race; + drop->next = dropouts; + dropouts = drop; + } + } + freset(f, FL_MARK); + } +} + void read_dropouts(const char * filename) { @@ -174,10 +222,12 @@ read_dropouts(const char * filename) drop->race = rc_find(race); drop->x = x; drop->y = y; + drop->fno = -1; drop->next = dropouts; dropouts = drop; } } + fclose(F); } void @@ -187,10 +237,12 @@ seed_dropouts(void) while (*dropp) { dropout *drop = *dropp; region * r = findregion(drop->x, drop->y); - if (r && r->units==NULL) { + if (r) { boolean found = false; newfaction **nfp = &newfactions; - while (*nfp) { + unit * u; + for (u=r->units;u;u=u->next) if (u->faction->no==drop->fno) break; + if (u==NULL) while (*nfp) { newfaction * nf = *nfp; if (nf->race==drop->race) { unit * u = addplayer(r, nf->email, nf->race, nf->lang); @@ -202,7 +254,7 @@ seed_dropouts(void) } nfp = &nf->next; } - if (found) dropp=&drop->next; + if (!found) dropp=&drop->next; } else { *dropp = drop->next; } diff --git a/src/mapper/mapper.c b/src/mapper/mapper.c index 54be379e0..126659ec3 100644 --- a/src/mapper/mapper.c +++ b/src/mapper/mapper.c @@ -56,6 +56,7 @@ #include #include +extern const char * orderfile; extern char *reportdir; extern char *datadir; extern char *basedir; @@ -1447,6 +1448,9 @@ main(int argc, char *argv[]) else turn = atoi(argv[++i]); break; + case 'v': + orderfile = argv[++i]; + break; case 'x': maxregions = atoi(argv[++i]); maxregions = (maxregions*81+80) / 81; diff --git a/src/res/de/messages.xml b/src/res/de/messages.xml index dec25e286..b3740886a 100644 --- a/src/res/de/messages.xml +++ b/src/res/de/messages.xml @@ -5761,17 +5761,23 @@ - + - - - "$unit($teacher) lehrt $unit($student) $skill($skill)." - - + "$unit($teacher) lehrt $unit($student) $skill($skill)." + + + + + + + + + + "$unit($teacher) lehrt $unit($student) $skill($skill) auf Stufe $int($level)." diff --git a/src/res/en/messages.xml b/src/res/en/messages.xml index c2fe4ffa8..ea4a4730f 100644 --- a/src/res/en/messages.xml +++ b/src/res/en/messages.xml @@ -3308,17 +3308,23 @@ - + - - - "$unit($teacher) teaches $unit($student) $skill($skill)." - - + "$unit($teacher) teaches $unit($student) $skill($skill)." + + + + + + + + + + "$unit($teacher) teaches $unit($student) $skill($skill) to level $int($level)."