コード例 #1
0
ファイル: study.c プロジェクト: ennorehling/eressea
int teach_cmd(unit * teacher, struct order *ord)
{
    plane *pl;
    region *r = teacher->region;
    skill_t sk_academy = NOSKILL;
    int teaching, i, j, count, academy_students = 0;

    if (r->attribs) {
        if (get_curse(r->attribs, &ct_gbdream)) {
            ADDMSG(&teacher->faction->msgs,
                msg_feedback(teacher, ord, "gbdream_noteach", ""));
            return 0;
        }
    }
    if ((u_race(teacher)->flags & RCF_NOTEACH) || fval(teacher, UFL_WERE)) {
        cmistake(teacher, ord, 274, MSG_EVENT);
        return 0;
    }

    pl = rplane(r);
    if (pl && fval(pl, PFL_NOTEACH)) {
        cmistake(teacher, ord, 273, MSG_EVENT);
        return 0;
    }

    teaching = teacher->number  * TEACHNUMBER;

    if ((i = get_effect(teacher, oldpotiontype[P_FOOL])) > 0) { /* Trank "Dumpfbackenbrot" */
        if (i > teaching) i = teaching;
        /* Trank wirkt pro Schueler, nicht pro Lehrer */
        teaching -= i;
        change_effect(teacher, oldpotiontype[P_FOOL], -i);
        j = teaching;
        ADDMSG(&teacher->faction->msgs, msg_message("teachdumb", "teacher amount", teacher, j));
    }
    if (teaching <= 0)
        return 0;

    count = 0;

    init_order_depr(ord);

#if TEACH_ALL
    if (getparam(teacher->faction->locale) == P_ANY) {
        skill_t sk;
        unit *scholar;
        skill_t teachskill[MAXSKILLS];
        int t = 0;

        do {
            sk = getskill(teacher->faction->locale);
            teachskill[t] = getskill(teacher->faction->locale);
        } while (sk != NOSKILL);

        for (scholar = r->units; teaching > 0 && scholar; scholar = scholar->next) {
            if (LongHunger(scholar)) {
                continue;
            }
            else if (scholar->faction == teacher->faction) {
                if (getkeyword(scholar->thisorder) == K_STUDY) {
                    /* Input ist nun von student->thisorder !! */
                    init_order(scholar->thisorder, scholar->faction->locale);
                    sk = getskill(scholar->faction->locale);
                    if (sk != NOSKILL && teachskill[0] != NOSKILL) {
                        for (t = 0; teachskill[t] != NOSKILL; ++t) {
                            if (sk == teachskill[t]) {
                                break;
                            }
                        }
                        sk = teachskill[t];
                    }
                    if (sk != NOSKILL
                        && effskill_study(teacher, sk) - TEACHDIFFERENCE > effskill_study(scholar, sk)) {
                        teaching -= teach_unit(teacher, scholar, teaching, sk, true, &academy_students);
                    }
                }
            }
#ifdef TEACH_FRIENDS
            else if (alliedunit(teacher, scholar->faction, HELP_GUARD)) {
                if (getkeyword(scholar->thisorder) == K_STUDY) {
                    /* Input ist nun von student->thisorder !! */
                    init_order(scholar->thisorder, scholar->faction->locale);
                    sk = getskill(scholar->faction->locale);
                    if (sk != NOSKILL
                        && effskill_study(teacher, sk) - TEACHDIFFERENCE >= effskill(scholar, sk, NULL)) {
                        teaching -= teach_unit(teacher, scholar, teaching, sk, true, &academy_students);
                    }
                }
            }
#endif
        }
    }
    else
#endif
    {
        char zOrder[4096];
        size_t sz = sizeof(zOrder);
        order *new_order;

        zOrder[0] = '\0';
        init_order_depr(ord);

        while (!parser_end()) {
            skill_t sk;
            unit *scholar;
            bool feedback;

            getunit(r, teacher->faction, &scholar);
            ++count;

            /* Falls die Unit nicht gefunden wird, Fehler melden */

            if (!scholar) {
                char tbuf[20];
                const char *uid;
                const char *token;
                /* Finde den string, der den Fehler verursacht hat */
                parser_pushstate();
                init_order_depr(ord);

                for (j = 0; j != count - 1; ++j) {
                    /* skip over the first 'count' units */
                    getunit(r, teacher->faction, NULL);
                }

                token = getstrtoken();

                /* Beginne die Fehlermeldung */
                if (isparam(token, teacher->faction->locale, P_TEMP)) {
                    token = getstrtoken();
                    sprintf(tbuf, "%s %s", LOC(teacher->faction->locale,
                        parameters[P_TEMP]), token);
                    uid = tbuf;
                }
                else {
                    uid = token;
                }
                ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord, "unitnotfound_id",
                    "id", uid));

                parser_popstate();
                continue;
            }

            feedback = teacher->faction == scholar->faction
                || alliedunit(scholar, teacher->faction, HELP_GUARD);

            /* Neuen Befehl zusammenbauen. TEMP-Einheiten werden automatisch in
             * ihre neuen Nummern uebersetzt. */
            if (zOrder[0]) {
                strncat(zOrder, " ", sz - 1);
                --sz;
            }
            sz -= str_strlcpy(zOrder + 4096 - sz, itoa36(scholar->no), sz);

            if (getkeyword(scholar->thisorder) != K_STUDY) {
                ADDMSG(&teacher->faction->msgs,
                    msg_feedback(teacher, ord, "teach_nolearn", "student", scholar));
                continue;
            }

            /* Input ist nun von student->thisorder !! */
            parser_pushstate();
            init_order(scholar->thisorder, scholar->faction->locale);
            sk = getskill(scholar->faction->locale);
            parser_popstate();

            if (sk == NOSKILL) {
                ADDMSG(&teacher->faction->msgs,
                    msg_feedback(teacher, ord, "teach_nolearn", "student", scholar));
                continue;
            }

            if (effskill_study(scholar, sk) > effskill_study(teacher, sk)
                - TEACHDIFFERENCE) {
                if (feedback) {
                    ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord, "teach_asgood",
                        "student", scholar));
                }
                continue;
            }
            if (sk == SK_MAGIC) {
                /* ist der Magier schon spezialisiert, so versteht er nur noch
                 * Lehrer seines Gebietes */
                magic_t mage2 = unit_get_magic(scholar);
                if (mage2 != M_GRAY) {
                    magic_t mage1 = unit_get_magic(teacher);
                    if (mage1 != mage2) {
                        if (feedback) {
                            ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord,
                                "error_different_magic", "target", scholar));
                        }
                        continue;
                    }
                }
            }
            sk_academy = sk;
            teaching -= teach_unit(teacher, scholar, teaching, sk, false, &academy_students);
        }
        new_order = create_order(K_TEACH, teacher->faction->locale, "%s", zOrder);
        replace_order(&teacher->orders, ord, new_order);
        free_order(new_order);      /* parse_order & set_order have each increased the refcount */
    }
    if (academy_students > 0 && sk_academy!=NOSKILL) {
        academy_teaching_bonus(teacher, sk_academy, academy_students);
    }
    init_order_depr(NULL);
    return 0;
}
コード例 #2
0
ファイル: study.c プロジェクト: Xolgrim/server
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;
}