Exemple #1
0
static void test_sabotage_other_fail(CuTest *tc) {
    unit *u, *u2;
    region *r;
    order *ord;
    message *msg;

    setup_sabotage();
    r = test_create_region(0, 0, 0);
    assert(r);
    u = test_create_unit(test_create_faction(NULL), r);
    u2 = test_create_unit(test_create_faction(NULL), r);
    assert(u && u2);
    u2->ship = test_create_ship(r, test_create_shiptype("boat"));
    assert(u2->ship);
    u->ship = u2->ship;
    ship_update_owner(u->ship);
    assert(ship_owner(u->ship) == u);
    ord = create_order(K_SABOTAGE, u->faction->locale, "SCHIFF");
    assert(ord);
    CuAssertIntEquals(tc, 0, sabotage_cmd(u2, ord));
    msg = test_get_last_message(u2->faction->msgs);
    CuAssertStrEquals(tc, "destroy_ship_1", test_get_messagetype(msg));
    msg = test_get_last_message(u->faction->msgs);
    CuAssertStrEquals(tc, "destroy_ship_3", test_get_messagetype(msg));
    CuAssertPtrNotNull(tc, r->ships);
    free_order(ord);
    test_cleanup();
}
Exemple #2
0
static void test_getunit(CuTest *tc) {
    unit *u, *u2;
    order *ord;
    attrib *a;
    struct region *r;
    struct locale *lang;
    struct terrain_type *t_plain;

    test_cleanup();
    lang = get_or_create_locale("de");
    test_translate_param(lang, P_TEMP, "TEMP");
    /* note that the english order is FIGHT, not COMBAT, so this is a poor example */
    t_plain = test_create_terrain("plain", LAND_REGION);
    u = test_create_unit(test_create_faction(0), test_create_region(0, 0, t_plain));
    a = a_add(&u->attribs, a_new(&at_alias));
    a->data.i = atoi36("42"); /* this unit is also TEMP 42 */
    r = test_create_region(1, 0, t_plain);

    ord = create_order(K_GIVE, lang, itoa36(u->no));
    init_order(ord);
    CuAssertIntEquals(tc, GET_UNIT, getunit(u->region, u->faction, &u2));
    CuAssertPtrEquals(tc, u, u2);
    init_order(ord);
    CuAssertIntEquals(tc, GET_NOTFOUND, getunit(r, u->faction, &u2));
    CuAssertPtrEquals(tc, NULL, u2);
    free_order(ord);

    ord = create_order(K_GIVE, lang, itoa36(u->no + 1));
    init_order(ord);
    CuAssertIntEquals(tc, GET_NOTFOUND, getunit(u->region, u->faction, &u2));
    CuAssertPtrEquals(tc, NULL, u2);
    free_order(ord);

    ord = create_order(K_GIVE, lang, "0");
    init_order(ord);
    CuAssertIntEquals(tc, GET_PEASANTS, getunit(u->region, u->faction, &u2));
    CuAssertPtrEquals(tc, NULL, u2);
    free_order(ord);

    ord = create_order(K_GIVE, lang, "TEMP 42");
    init_order(ord);
    CuAssertIntEquals(tc, GET_UNIT, getunit(u->region, u->faction, &u2));
    CuAssertPtrEquals(tc, u, u2);
    free_order(ord);

    test_cleanup();
}
Exemple #3
0
static void test_tax_cmd(CuTest *tc) {
    order *ord;
    faction *f;
    region *r;
    unit *u;
    item_type *sword, *silver;
    request *taxorders = 0;


    test_cleanup();
    config_set("taxing.perlevel", "20");
    test_create_world();
    f = test_create_faction(NULL);
    r = findregion(0, 0);
    assert(r && f);
    u = test_create_unit(f, r);

    ord = create_order(K_TAX, f->locale, "");
    assert(ord);

    tax_cmd(u, ord, &taxorders);
    CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error48"));
    test_clear_messages(u->faction);

    silver = get_resourcetype(R_SILVER)->itype;

    sword = it_get_or_create(rt_get_or_create("sword"));
    new_weapontype(sword, 0, 0.0, NULL, 0, 0, 0, SK_MELEE, 1);
    i_change(&u->items, sword, 1);
    set_level(u, SK_MELEE, 1);

    tax_cmd(u, ord, &taxorders);
    CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error_no_tax_skill"));
    test_clear_messages(u->faction);

    set_level(u, SK_TAXING, 1);
    tax_cmd(u, ord, &taxorders);
    CuAssertPtrEquals(tc, 0, test_find_messagetype(u->faction->msgs, "error_no_tax_skill"));
    CuAssertPtrNotNull(tc, taxorders);

    rsetmoney(r, 11);
    expandtax(r, taxorders);
    CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "income"));
    /* taxing is in multiples of 10 */
    CuAssertIntEquals(tc, 10, i_get(u->items, silver));
    test_clear_messages(u->faction);
    i_change(&u->items, silver, -i_get(u->items, silver));

    rsetmoney(r, 1000);
    taxorders = 0;
    tax_cmd(u, ord, &taxorders);
    expandtax(r, taxorders);
    CuAssertIntEquals(tc, 20, i_get(u->items, silver));
    test_clear_messages(u->faction);

    free_order(ord);
    test_cleanup();
}
static void test_read_unitid(CuTest *tc) {
    unit *u;
    order *ord;
    attrib *a;
    struct locale *lang;
    struct terrain_type *t_plain;

    test_cleanup();
    lang = get_or_create_locale("de");
    test_translate_param(lang, P_TEMP, "TEMP");
    /* note that the english order is FIGHT, not COMBAT, so this is a poor example */
    t_plain = test_create_terrain("plain", LAND_REGION);
    u = test_create_unit(test_create_faction(0), test_create_region(0, 0, t_plain));
    a = a_add(&u->attribs, a_new(&at_alias));
    a->data.i = atoi36("42"); /* this unit is also TEMP 42 */

    ord = create_order(K_GIVE, lang, "TEMP 42");
    init_order(ord);
    CuAssertIntEquals(tc, u->no, read_unitid(u->faction, u->region));
    free_order(ord);

    ord = create_order(K_GIVE, lang, "8");
    init_order(ord);
    CuAssertIntEquals(tc, 8, read_unitid(u->faction, u->region));
    free_order(ord);

    ord = create_order(K_GIVE, lang, "");
    init_order(ord);
    CuAssertIntEquals(tc, -1, read_unitid(u->faction, u->region));
    free_order(ord);

    ord = create_order(K_GIVE, lang, "TEMP");
    init_order(ord);
    CuAssertIntEquals(tc, -1, read_unitid(u->faction, u->region));
    free_order(ord);

    // bug https://bugs.eressea.de/view.php?id=1685
    ord = create_order(K_GIVE, lang, "##");
    init_order(ord);
    CuAssertIntEquals(tc, -1, read_unitid(u->faction, u->region));
    free_order(ord);

    test_cleanup();
}
Exemple #5
0
void
create_ship(region * r, unit * u, const struct ship_type *newtype, int want,
order * ord)
{
    ship *sh;
    int msize;
    const construction *cons = newtype->construction;
    order *new_order;

    if (!eff_skill(u, SK_SHIPBUILDING, r)) {
        cmistake(u, ord, 100, MSG_PRODUCE);
        return;
    }
    if (besieged(u)) {
        cmistake(u, ord, 60, MSG_PRODUCE);
        return;
    }

    /* check if skill and material for 1 size is available */
    if (eff_skill(u, cons->skill, r) < cons->minskill) {
        ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder,
            "error_build_skill_low", "value", cons->minskill));
        return;
    }

    msize = maxbuild(u, cons);
    if (msize == 0) {
        cmistake(u, ord, 88, MSG_PRODUCE);
        return;
    }
    if (want > 0)
        want = _min(want, msize);
    else
        want = msize;

    sh = new_ship(newtype, r, u->faction->locale);

    if (leave(u, false)) {
        if (fval(u_race(u), RCF_CANSAIL)) {
            u_set_ship(u, sh);
        }
    }
    new_order =
        create_order(K_MAKE, u->faction->locale, "%s %i", LOC(u->faction->locale,
        parameters[P_SHIP]), sh->no);
    replace_order(&u->orders, ord, new_order);
    free_order(new_order);

    build_ship(u, sh, want);
}
Exemple #6
0
static void test_parse_maketemp(CuTest *tc) {
    char cmd[32];
    order *ord;
    struct locale * lang = get_or_create_locale("en");

    locale_setstring(lang, keyword(K_MAKE), "MAKE");
    locale_setstring(lang, keyword(K_MAKETEMP), "MAKETEMP");
    locale_setstring(lang, "TEMP", "TEMP");
    init_locale(lang);

    ord = parse_order("MAKET herp", lang);
    CuAssertPtrNotNull(tc, ord);
    CuAssertStrEquals(tc, "MAKETEMP herp", get_command(ord, cmd, sizeof(cmd)));
    CuAssertIntEquals(tc, K_MAKETEMP, getkeyword(ord));
    CuAssertIntEquals(tc, K_MAKETEMP, init_order(ord));
    CuAssertStrEquals(tc, "herp", getstrtoken());
    free_order(ord);
}
Exemple #7
0
static void test_give_herbs(CuTest * tc) {
    struct give env = { 0 };
    struct order *ord;

    test_setup_ex(tc);
    env.f2 = env.f1 = test_create_faction(NULL);
    setup_give(&env);
    i_change(&env.src->items, env.itype, 10);

    ord = create_order(K_GIVE, env.f1->locale, "%s %s", itoa36(env.dst->no), LOC(env.f1->locale, parameters[P_HERBS]));
    assert(ord);

    give_cmd(env.src, ord);
    CuAssertIntEquals(tc, 0, i_get(env.src->items, env.itype));
    CuAssertIntEquals(tc, 10, i_get(env.dst->items, env.itype));
    free_order(ord);
    test_teardown();
}
Exemple #8
0
static void test_create_order(CuTest *tc) {
    char cmd[32];
    order *ord;
    struct locale * lang;

    test_cleanup();
    lang = get_or_create_locale("en");

    locale_setstring(lang, "keyword::move", "MOVE");
    ord = create_order(K_MOVE, lang, "NORTH");
    CuAssertPtrNotNull(tc, ord);
    CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
    CuAssertStrEquals(tc, "MOVE NORTH", get_command(ord, cmd, sizeof(cmd)));

    CuAssertIntEquals(tc, K_MOVE, init_order(ord));
    CuAssertStrEquals(tc, "NORTH", getstrtoken());
    free_order(ord);
    test_cleanup();
}
Exemple #9
0
static void test_sabotage_self(CuTest *tc) {
    unit *u;
    region *r;
    order *ord;

    setup_sabotage();
    r = test_create_region(0, 0, 0);
    assert(r);
    u = test_create_unit(test_create_faction(NULL), r);
    assert(u && u->faction && u->region == r);
    u->ship = test_create_ship(r, test_create_shiptype("boat"));
    assert(u->ship);
    ord = create_order(K_SABOTAGE, u->faction->locale, "SCHIFF");
    assert(ord);
    CuAssertIntEquals(tc, 0, sabotage_cmd(u, ord));
    CuAssertPtrEquals(tc, 0, r->ships);
    free_order(ord);
    test_cleanup();
}
Exemple #10
0
static void test_give_invalid_target(CuTest *tc) {
    /* bug https://bugs.eressea.de/view.php?id=1685 */
    struct give env = { 0 };
    order *ord;

    test_setup_ex(tc);
    env.f1 = test_create_faction(NULL);
    env.f2 = 0;
    setup_give(&env);

    i_change(&env.src->items, env.itype, 10);
    ord = create_order(K_GIVE, env.f1->locale, "## KRAUT");
    assert(ord);

    give_cmd(env.src, ord);
    CuAssertIntEquals(tc, 10, i_get(env.src->items, env.itype));
    CuAssertPtrNotNull(tc, test_find_messagetype(env.f1->msgs, "feedback_unit_not_found"));
    free_order(ord);
    test_teardown();
}
Exemple #11
0
static void test_setstealth_cmd(CuTest *tc) {
    unit *u;
    const struct locale *lang;
    
    test_setup();
    u = test_create_unit(test_create_faction(0), test_create_region(0,0,0));
    lang = u->faction->locale;
    u->flags = UFL_ANON_FACTION|UFL_SIEGE;
    u->thisorder = create_order(K_SETSTEALTH, lang, "%s %s",
            LOC(lang, parameters[P_FACTION]),
            LOC(lang, parameters[P_NOT]));
    setstealth_cmd(u, u->thisorder);
    CuAssertIntEquals(tc, UFL_SIEGE, u->flags);
    free_order(u->thisorder);
    u->thisorder = create_order(K_SETSTEALTH, lang, "%s",
            LOC(lang, parameters[P_FACTION]));
    setstealth_cmd(u, u->thisorder);
    CuAssertIntEquals(tc, UFL_SIEGE|UFL_ANON_FACTION, u->flags);
    test_cleanup();
}
Exemple #12
0
/** remove the unit from memory.
 * this frees all memory that's only accessible through the unit,
 * and you should already have called uunhash and removed the unit from the
 * region.
 */
void free_unit(unit * u)
{
  free(u->name);
  free(u->display);
  free_order(u->thisorder);
  free_orders(&u->orders);
  if (u->skills)
    free(u->skills);
  while (u->items) {
    item *it = u->items->next;
    u->items->next = NULL;
    i_free(u->items);
    u->items = it;
  }
  while (u->attribs)
    a_remove(&u->attribs, u->attribs);
  while (u->reservations) {
    struct reservation *res = u->reservations;
    u->reservations = res->next;
    free(res);
  }
}
Exemple #13
0
static void test_give_men_requires_contact(CuTest * tc) {
    struct give env = { 0 };
    message * msg;
    order *ord;

    test_setup_ex(tc);
    env.f1 = test_create_faction(NULL);
    env.f2 = test_create_faction(NULL);
    setup_give(&env);
    msg = give_men(1, env.src, env.dst, NULL);
    CuAssertStrEquals(tc, "feedback_no_contact", test_get_messagetype(msg));
    CuAssertIntEquals(tc, 1, env.dst->number);
    CuAssertIntEquals(tc, 1, env.src->number);

    ord = create_order(K_GIVE, env.f1->locale, "%s ALLES PERSONEN", itoa36(env.dst->no));
    test_clear_messages(env.f1);
    give_cmd(env.src, ord);
    CuAssertPtrEquals(tc, NULL, test_find_messagetype(env.f1->msgs, "give_person"));
    CuAssertPtrNotNull(tc, test_find_messagetype(env.f1->msgs, "feedback_no_contact"));

    msg_release(msg);
    free_order(ord);
    test_teardown();
}
Exemple #14
0
static void test_sabotage_other_success(CuTest *tc) {
    unit *u, *u2;
    region *r;
    order *ord;

    setup_sabotage();
    r = test_create_region(0, 0, 0);
    assert(r);
    u = test_create_unit(test_create_faction(NULL), r);
    u2 = test_create_unit(test_create_faction(NULL), r);
    assert(u && u2);
    u2->ship = test_create_ship(r, test_create_shiptype("boat"));
    assert(u2->ship);
    u->ship = u2->ship;
    ship_update_owner(u->ship);
    assert(ship_owner(u->ship) == u);
    ord = create_order(K_SABOTAGE, u->faction->locale, "SCHIFF");
    assert(ord);
    set_level(u2, SK_SPY, 1);
    CuAssertIntEquals(tc, 0, sabotage_cmd(u2, ord));
    CuAssertPtrEquals(tc, 0, r->ships);
    free_order(ord);
    test_cleanup();
}
Exemple #15
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;
}
Exemple #16
0
/*************************************************************************
 * int main
 *************************************************************************/
int main(int argc, char *argv[])
{
  /* Data structures. */
  int       num_motifs;         /* The number of motifs in the model. */
  MOTIF_T   motifs[2 * MAX_MOTIFS]; /* The motifs. */
  STRING_LIST_T* motif_occurrences = NULL; /* Strings describing occurrences of
                                              motifs */
  BOOLEAN_T has_reverse_strand = FALSE;    /* MEME file contained both strands */
  ARRAY_T*  background;         /* Background probs for alphabet. */
  ORDER_T*  order_spacing;      /* Linear HMM order and spacing. */
  MATRIX_T* transp_freq = NULL; /* Matrix of inter-motif transitions freqs. */
  MATRIX_T* spacer_ave = NULL;  /* Matrix of average spacer lengths. */
  MHMM_T *  the_hmm = NULL;     /* The HMM being constructed. */

  /* Command line parameters. */
  char *    meme_filename;      /* Input file containg motifs. */
  char *    hmm_type_str;       /* HMM type. */
  HMM_T     hmm_type;
  STRING_LIST_T* requested_motifs; /* Indices of requested motifs. */
  int       request_n;          /* The user asked for the first n motifs. */
  double    e_threshold;        /* E-value threshold for motif inclusion. */
  double    complexity_threshold; // For eliminating low-complexity motifs.
  double    p_threshold;        /* p-value threshold for motif occurences. */
  char*     order_string;       /* Motif order and spacing. */
  int       spacer_states;      /* Number of states in each spacer. */
  BOOLEAN_T fim;                /* Represent spacers as free insertion
				   modules? */
  BOOLEAN_T keep_unused;        // Drop unused inter-motif transitions?
  double    trans_pseudo;       /* Transition pseudocount. */
  double    spacer_pseudo;      // Spacer (self-loop) pseudocount. */
  char*     description;        // Descriptive text to be stored in model.
  BOOLEAN_T print_header;       /* Print file header? */
  BOOLEAN_T print_params;       /* Print parameter summary? */
  BOOLEAN_T print_time;         /* Print timing data (dummy: always false). */

  /* Local variables. */
  int       i_motif;

  /**********************************************
   * COMMAND LINE PROCESSING
   **********************************************/
  // Define command line options.
  cmdoption const options[] = {
    {"type", OPTIONAL_VALUE},
    {"description", REQUIRED_VALUE},
    {"motif", REQUIRED_VALUE},
    {"nmotifs", REQUIRED_VALUE},
    {"ethresh", REQUIRED_VALUE},
    {"lowcomp", REQUIRED_VALUE},
    {"pthresh", REQUIRED_VALUE},
    {"order", REQUIRED_VALUE},
    {"nspacer", REQUIRED_VALUE},
    {"fim", NO_VALUE},
    {"keep-unused", NO_VALUE},
    {"transpseudo", REQUIRED_VALUE},
    {"spacerpseudo", REQUIRED_VALUE},
    {"verbosity", REQUIRED_VALUE},
    {"noheader", NO_VALUE},
    {"noparams", NO_VALUE},
    {"notime", NO_VALUE},
    {"quiet", NO_VALUE},
  };
  int option_count = 18;
  int option_index = 0;

  // Define the usage message.
  char      usage[1000] = "";
  strcat(usage, "USAGE: mhmm [options] <MEME file>\n");
  strcat(usage, "\n");
  strcat(usage, "   Options:\n");
  strcat(usage, "     --type [linear|complete|star] (default=linear)\n");
  strcat(usage, "     --description <string> (may be repeated)\n");
  strcat(usage, "     --motif <motif #> (may be repeated)\n");
  strcat(usage, "     --nmotifs <#>\n");
  strcat(usage, "     --ethresh <E-value>\n");
  strcat(usage, "     --lowcomp <value>\n");
  strcat(usage, "     --pthresh <p-value>\n");
  strcat(usage, "     --order <string>\n");
  strcat(usage, "     --nspacer <spacer length> (default=1)\n");
  strcat(usage, "     --fim\n");
  strcat(usage, "     --keep-unused\n");
  strcat(usage, "     --transpseudo <pseudocount>\n");
  strcat(usage, "     --spacerpseudo <pseudocount>\n");
  strcat(usage, "     --verbosity 1|2|3|4|5 (default=2)\n");
  strcat(usage, "     --noheader\n");
  strcat(usage, "     --noparams\n");
  strcat(usage, "     --notime\n");
  strcat(usage, "     --quiet\n");
  strcat(usage, "\n");

  /* Make sure various options are set to NULL or defaults. */
  meme_filename = NULL;
  hmm_type_str = NULL;
  hmm_type = INVALID_HMM;
  requested_motifs = new_string_list();
  request_n = 0;
  e_threshold = 0.0;
  complexity_threshold = 0.0;
  p_threshold = 0.0;
  order_string = NULL;
  spacer_states = DEFAULT_SPACER_STATES,
  fim = FALSE;
  keep_unused = FALSE;
  trans_pseudo = DEFAULT_TRANS_PSEUDO;
  spacer_pseudo = DEFAULT_SPACER_PSEUDO;
  description = NULL;
  print_header = TRUE;
  print_params = TRUE;
  print_time = FALSE;

	simple_setopt(argc, argv, option_count, options);

  // Parse the command line.
  while (1) { 
    int c = 0;
    char* option_name = NULL;
    char* option_value = NULL;
    const char * message = NULL;


    // Read the next option, and break if we're done.
    c = simple_getopt(&option_name, &option_value, &option_index);
    if (c == 0) {
      break;
    } else if (c < 0) {
    	simple_getopterror(&message);
      die("Error processing command line options (%s)\n", message);
    }

    if (strcmp(option_name, "type") == 0) {
			if (option_value != NULL) {
      	hmm_type_str = option_value;
			}
    } else if (strcmp(option_name, "description") == 0) {
      description = option_value;
    } else if (strcmp(option_name, "motif") == 0) {
      add_string(option_value, requested_motifs);
    } else if (strcmp(option_name, "nmotifs") == 0) {
      request_n = atoi(option_value);
    } else if (strcmp(option_name, "ethresh") == 0) {
      e_threshold = atof(option_value);
    } else if (strcmp(option_name, "lowcomp") == 0) {
      complexity_threshold = atof(option_value);
    } else if (strcmp(option_name, "pthresh") == 0) {
      p_threshold = atof(option_value);
    } else if (strcmp(option_name, "order") == 0) {
      order_string = option_value;
    } else if (strcmp(option_name, "nspacer") == 0) {
      spacer_states = atoi(option_value);
    } else if (strcmp(option_name, "fim") == 0) {
      fim = TRUE;
    } else if (strcmp(option_name, "keep-unused") == 0) {
      keep_unused = TRUE;
    } else if (strcmp(option_name, "transpseudo") == 0) {
      trans_pseudo = atof(option_value);
    } else if (strcmp(option_name, "spacerpseudo") == 0) {
      spacer_pseudo = atof(option_value);
    } else if (strcmp(option_name, "verbosity") == 0) {
      verbosity = (VERBOSE_T)atoi(option_value);
    } else if (strcmp(option_name, "noheader") == 0) {
      print_header = FALSE;
    } else if (strcmp(option_name, "noparams") == 0) {
      print_params = FALSE;
    } else if (strcmp(option_name, "notime") == 0) {
      print_time = FALSE;
    } else if (strcmp(option_name, "quiet") == 0) {
      print_header = print_params = print_time = FALSE;
      verbosity = QUIET_VERBOSE;
    }
  }

  // Read the single required argument.
  if (option_index + 1 != argc) {
    fprintf(stderr, "%s", usage);
    exit(1);
  }
  meme_filename = argv[option_index];

  // Set up motif requests. 
  if (request_n != 0) {
    if (get_num_strings(requested_motifs) != 0) {
      die("Can't combine the -motif and -nmotifs options.\n");
    } else {
      for (i_motif = 0; i_motif < request_n; i_motif++) {
        char motif_id[MAX_MOTIF_ID_LENGTH + 1];
        sprintf(motif_id, "%d", i_motif + 1);
        add_string(motif_id, requested_motifs);
      }
    }
  }

  /* Set the model type. */
  hmm_type = convert_enum_type_str(hmm_type_str, LINEAR_HMM, HMM_STRS, 
				   NUM_HMM_T);

  /* Gotta have positive spacer length. */
  if (spacer_states <= 0) {
    die("Negative spacer length (%d).\n", spacer_states);
  }

  /* Make sure motifs weren't selected redundantly. */
  // FIXME: Add tests for complexity threshold.
  if ((get_num_strings(requested_motifs) != 0) && (e_threshold != 0.0)) {
    die("Can't use -motif or -nmotifs with -ethresh.");
  }
  if ((get_num_strings(requested_motifs) != 0) && (order_string != NULL)) {
    die("Can't use -motif or -nmotifs with -order.");
  }
  if ((order_string != NULL) && (e_threshold != 0.0)) {
    die("Can't use -ethresh and -order.");
  }

  /* Prevent trying to build a complete or star model with ordering. */
  if (order_string != NULL) {
    if (hmm_type == COMPLETE_HMM) 
      die("Can't specify motif order with a completely connected model.");
    else if (hmm_type == STAR_HMM)
      die("Can't specify motif order with a star model.");
  } 

  // Parse the order string. 
  order_spacing = create_order(order_string);

  /**********************************************
   * READING THE MOTIFS
   **********************************************/

  BOOLEAN_T read_file = FALSE;
  double pseudocount = 0;

  read_meme_file(
		 meme_filename,
		 "motif-file", // Take bg freq. from motif file.
		 pseudocount,
     REQUIRE_PSPM,
		 &num_motifs,
		 motifs,
		 &motif_occurrences,
		 &has_reverse_strand,
		 &background
		 );

  process_raw_motifs_for_model(
       &num_motifs,
       motifs,
       motif_occurrences,
       requested_motifs,
       has_reverse_strand,
       keep_unused,
       p_threshold,
       e_threshold, 
       complexity_threshold, 
       &order_spacing,
       &transp_freq,
       &spacer_ave,
       trans_pseudo,
       spacer_pseudo
  );

  /**********************************************
   * BUILDING THE HMM
   **********************************************/

  /* Build the motif-based HMM. */
  if (hmm_type == LINEAR_HMM) {

    if (order_spacing != NULL) {
      reorder_motifs(order_spacing, &num_motifs, motifs);
    }
    else {
      die("No order specified for the motifs.\n"
          "For the linear model the motif file must contain motif occurence\n" 
          "data or the motif order must be specified using "
          "the --order option.");
    }

    build_linear_hmm(
      background,
		  order_spacing,
		  spacer_states,
		  motifs,
		  num_motifs, 
		  fim,
		  &the_hmm
    );

  } else if (hmm_type == COMPLETE_HMM) {

    build_complete_hmm(
      background,
		  spacer_states,
		  motifs,
		  num_motifs,
		  transp_freq,
		  spacer_ave,
		  fim,
		  &the_hmm
    );

  } else if (hmm_type == STAR_HMM) {

    build_star_hmm(
      background,
		  spacer_states,
		  motifs,
		  num_motifs,
		  fim,
		  &the_hmm
    );

  }

  // Add some global information.
  copy_string(&(the_hmm->motif_file), meme_filename);

  /**********************************************
   * WRITING THE HMM
   **********************************************/

  /* Print the header. */
  if (print_header)
    write_header(
     program, 
     "",
		 description,
		 meme_filename,
		 NULL,
		 NULL, 
		 stdout
    );

  /* Write the HMM. */
  write_mhmm(verbosity, the_hmm, stdout);

  /* Print the program parameters. */
  if (print_params) {
    printf("Program parameters for mhmm\n");
    printf("  MEME file: %s\n", meme_filename);
    printf("  Motifs:");
    write_string_list(" ", requested_motifs, stdout);
    printf("\n");
    printf("  Model topology: %s\n",
	   convert_enum_type(hmm_type, HMM_STRS, NUM_HMM_T));
    printf("  States per spacer: %d\n", spacer_states);
    printf("  Spacers are free-insertion modules: %s\n",
	   boolean_to_string(fim));
    printf("\n");
  }

  free_array(background);
  free_string_list(requested_motifs);
  free_order(order_spacing);
  free_matrix(transp_freq);
  free_matrix(spacer_ave);
  for (i_motif = 0; i_motif < num_motifs; i_motif++)
    free_motif(&(motifs[i_motif]));
  free_mhmm(the_hmm);
  return(0);
}
Exemple #17
0
/***********************************************************************
 * Parse the motif occurrences.
 *
 * Each motif occurence string contains the following items
 *  - sequence id,
 *  - sequence p-value,
 *  - number n of motif occurrences, and
 *  - length of sequence.
 *
 * This is followed by n triples containing
 *  - motif id,
 *  - occurrence position, and
 *  - occurrence p-value.
 *
 ***********************************************************************/
static void parse_motif_occurrences(
  STRING_LIST_T*  motif_occurrences, // List of motif occurences OUT
  BOOLEAN_T  has_reverse_strand, // File included both strands? IN
  double     p_threshold,        // P-value to include motif occurences. OUT
  ORDER_T**  order_spacing,      // Motif order and spacing (linear HMM) 
                                 // IN OUT.
  MATRIX_T** transp_freq,        // Motif-to-motif transitions. OUT
  MATRIX_T** spacer_ave,         // Average inter-motif distances. OUT
  int        num_motifs,         // Number of motifs retrieved. IN
  MOTIF_T*   motifs              // The retrieved motifs. IN
) {

  ORDER_T*  new_order;      // New order and spacing. 
  BOOLEAN_T find_order;     // Should we look for the motif order? 

  // If we already have a motif order and spacing, don't find any more. 
  if (*order_spacing == NULL) {
    find_order = TRUE;
  } else {
    find_order = FALSE;
  }
  new_order = NULL;
  
  // Allocate the matrices. 
  *transp_freq = allocate_matrix(num_motifs + 2, num_motifs + 2);
  *spacer_ave = allocate_matrix(num_motifs + 2, num_motifs + 2);
  init_matrix(0.0, *transp_freq);
  init_matrix(0.0, *spacer_ave);

  int num_occurrence_strings = get_num_strings(motif_occurrences);
  int i;
  for (i = 0; i < num_occurrence_strings; i++) {
    char*  sequence_id;       // ID of the current sequence. 
    float  sequence_p;        // pvalue of the entire sequence. 
    int    num_occurs;        // Number of motif occurences in this sequence. 
    int    seq_length;        // Length of the current sequence. 
    int    i_occur;           // Index of the current occurrence. 
    char   prev_motif[MAX_MOTIF_ID_LENGTH + 1]; // Index of the previous motif. 
    int    prev_position;     // Location of the right edge of previous motif. 
    float  motif_p;           // P-value of the current occurrence. 
    char *c;          // Dummy to hold return of strtok.

    char* line = get_nth_string(i, motif_occurrences);

    /* Read the sequence identifier, p-value, number of occurrences
       and length. */
    // tlb; sscanf crashes if strtok returns NULL so pass it "" then
    sequence_id = strtok(line, " ");
    if (sequence_id == NULL) {
      die("Error reading motif occurrences.\n%s", line);
    }
    if (sscanf((c=strtok(NULL, " "))?c:"", "%f", &sequence_p) != 1) {
      die("Can't read p-value of sequence %s.", sequence_id);
    }
    if (sscanf((c=strtok(NULL, " "))?c:"", "%d", &num_occurs) != 1) {
      die("Can't read number of motif occurences in sequence %s.",
    sequence_id);
    }
    if (sscanf((c=strtok(NULL, " "))?c:"", "%d", &seq_length) != 1) {
      die("Can't read length of sequence %s.", sequence_id);
    }

    if (verbosity > NORMAL_VERBOSE) {
      fprintf(stderr, "Reading motif occurrences for sequence %s.\n", 
        sequence_id);
    }

    // If requested, try to create an order string. 
    if (find_order) {
      new_order = create_empty_order(num_occurs, sequence_p);
    }

    // Accumulate motif occurence data. 
    sprintf(prev_motif, "%d", 0);
    prev_position = 0;
    for (i_occur = 0; i_occur < num_occurs; i_occur++) {
      char  motif_id[MAX_MOTIF_ID_LENGTH + 1]; // ID of the current motif. 
      int   motif_position;    // Position of the current motif occurrence. 
      char *c;       // Dummy to hold return of strtok.
      
      // Read the three values. 
      if (sscanf((c=strtok(NULL, " "))?c:"", "%s", motif_id) != 1) {
        die("Can't read index of occurrence %d in sequence %s.",
        i_occur, sequence_id);
      }
      if (sscanf((c=strtok(NULL, " "))?c:"", "%d", &motif_position) != 1) {
        die("Can't read position of occurrence %d in sequence %s.",
        i_occur, sequence_id);
      }
      if (sscanf((c=strtok(NULL, " "))?c:"", "%f", &motif_p) != 1) {
        die("Can't read p-value of occurrence %d in sequence %s.",
        i_occur, sequence_id);
      }

      // Only include motifs that have been retained
      if (have_motif(motif_id, num_motifs, motifs)) {
        // Make sure we have strand information in the ID.
        if (has_reverse_strand) {
          add_strand(motif_id);
        }
  
        // Record this occurrence.
        record_occurrence(sequence_id,
          motif_id,
          p_threshold,
          motif_p,
          prev_motif,
          &prev_position,
          motif_position,
          *transp_freq,
          *spacer_ave,
          new_order,
          num_motifs, 
          motifs);
  
        /* Motifs are stored in order of their motif IDs, but they are
            indexed from zero rather than one. */
        prev_position = motif_position +
          (motifs[find_matrix_location(motifs, motif_id, num_motifs) - 1]).length;
      }
    }
  
    assert(seq_length >= prev_position);
  
    // Record the transition to the end state.
    record_occurrence(sequence_id,
          END_TRANSITION,
          p_threshold,
          motif_p,
          prev_motif,
          &prev_position,
          seq_length,
          *transp_freq,
          *spacer_ave,
          new_order,
          num_motifs,
          motifs);

    // Decide whether to keep the new order object. 
    if (find_order) {
      if ((get_num_distinct(new_order) > get_num_distinct(*order_spacing)) ||
         (((get_num_distinct(new_order) == get_num_distinct(*order_spacing))
         && (get_pvalue(new_order) < get_pvalue(*order_spacing))))) {
            if (verbosity > NORMAL_VERBOSE) {
              fprintf(stderr, "Storing order from sequence %s (%g < %g).\n",
                sequence_id, get_pvalue(new_order), 
                get_pvalue(*order_spacing));
              print_order_and_spacing(stderr, new_order);
            }
            free_order(*order_spacing);
            *order_spacing = new_order;
      } else {
        free_order(new_order);
      }
    }
  }
}
Exemple #18
0
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;
}
Exemple #19
0
int
build_building(unit * u, const building_type * btype, int id, int want, order * ord)
{
    region *r = u->region;
    int n = want, built = 0;
    building *b = NULL;
    /* einmalige Korrektur */
    const char *btname;
    order *new_order = NULL;
    const struct locale *lang = u->faction->locale;
    static int rule_other = -1;

    assert(u->number);
    assert(btype->construction);
    if (eff_skill(u, SK_BUILDING, r) == 0) {
        cmistake(u, ord, 101, MSG_PRODUCE);
        return 0;
    }

    /* Falls eine Nummer angegeben worden ist, und ein Gebaeude mit der
     * betreffenden Nummer existiert, ist b nun gueltig. Wenn keine Burg
     * gefunden wurde, dann wird nicht einfach eine neue erbaut. Ansonsten
     * baut man an der eigenen burg weiter. */

    /* Wenn die angegebene Nummer falsch ist, KEINE Burg bauen! */
    if (id > 0) {                 /* eine Nummer angegeben, keine neue Burg bauen */
        b = findbuilding(id);
        if (!b || b->region != u->region) { /* eine Burg mit dieser Nummer gibt es hier nicht */
            /* vieleicht Tippfehler und die eigene Burg ist gemeint? */
            if (u->building && u->building->type == btype) {
                b = u->building;
            }
            else {
                /* keine neue Burg anfangen wenn eine Nummer angegeben war */
                cmistake(u, ord, 6, MSG_PRODUCE);
                return 0;
            }
        }
    }
    else if (u->building && u->building->type == btype) {
        b = u->building;
    }

    if (b)
        btype = b->type;

    if (fval(btype, BTF_UNIQUE) && buildingtype_exists(r, btype, false)) {
        /* only one of these per region */
        cmistake(u, ord, 93, MSG_PRODUCE);
        return 0;
    }
    if (besieged(u)) {
        /* units under siege can not build */
        cmistake(u, ord, 60, MSG_PRODUCE);
        return 0;
    }
    if (btype->flags & BTF_NOBUILD) {
        /* special building, cannot be built */
        cmistake(u, ord, 221, MSG_PRODUCE);
        return 0;
    }
    if ((r->terrain->flags & LAND_REGION) == 0) {
        /* special terrain, cannot build */
        cmistake(u, ord, 221, MSG_PRODUCE);
        return 0;
    }
    if (btype->flags & BTF_ONEPERTURN) {
        if (b && fval(b, BLD_EXPANDED)) {
            cmistake(u, ord, 318, MSG_PRODUCE);
            return 0;
        }
        n = 1;
    }
    if (b) {
        if (rule_other < 0) {
            rule_other =
                get_param_int(global.parameters, "rules.build.other_buildings", 1);
        }
        if (!rule_other) {
            unit *owner = building_owner(b);
            if (!owner || owner->faction != u->faction) {
                cmistake(u, ord, 1222, MSG_PRODUCE);
                return 0;
            }
        }
    }

    if (b)
        built = b->size;
    if (n <= 0 || n == INT_MAX) {
        if (b == NULL) {
            if (btype->maxsize > 0) {
                n = btype->maxsize - built;
            }
            else {
                n = INT_MAX;
            }
        }
        else {
            if (b->type->maxsize > 0) {
                n = b->type->maxsize - built;
            }
            else {
                n = INT_MAX;
            }
        }
    }
    built = build(u, btype->construction, built, n);

    switch (built) {
    case ECOMPLETE:
        /* the building is already complete */
        cmistake(u, ord, 4, MSG_PRODUCE);
        break;
    case ENOMATERIALS:
        ADDMSG(&u->faction->msgs, msg_materials_required(u, ord,
            btype->construction, want));
        break;
    case ELOWSKILL:
    case ENEEDSKILL:
        /* no skill, or not enough skill points to build */
        cmistake(u, ord, 50, MSG_PRODUCE);
        break;
    }
    if (built <= 0) {
        return built;
    }
    /* at this point, the building size is increased. */
    if (b == NULL) {
        /* build a new building */
        b = new_building(btype, r, lang);
        b->type = btype;
        fset(b, BLD_MAINTAINED | BLD_WORKING);

        /* Die Einheit befindet sich automatisch im Inneren der neuen Burg. */
        if (u->number && leave(u, false)) {
            u_set_building(u, b);
        }
    }

    btname = LOC(lang, btype->_name);

    if (want - built <= 0) {
        /* gebäude fertig */
        new_order = default_order(lang);
    }
    else if (want != INT_MAX) {
        /* reduzierte restgröße */
        const char *hasspace = strchr(btname, ' ');
        if (hasspace) {
            new_order =
                create_order(K_MAKE, lang, "%d \"%s\" %i", n - built, btname, b->no);
        }
        else {
            new_order =
                create_order(K_MAKE, lang, "%d %s %i", n - built, btname, b->no);
        }
    }
    else if (btname) {
        /* Neues Haus, Befehl mit Gebäudename */
        const char *hasspace = strchr(btname, ' ');
        if (hasspace) {
            new_order = create_order(K_MAKE, lang, "\"%s\" %i", btname, b->no);
        }
        else {
            new_order = create_order(K_MAKE, lang, "%s %i", btname, b->no);
        }
    }

    if (new_order) {
        replace_order(&u->orders, ord, new_order);
        free_order(new_order);
    }

    b->size += built;
    fset(b, BLD_EXPANDED);

    update_lighthouse(b);

    ADDMSG(&u->faction->msgs, msg_message("buildbuilding",
        "building unit size", b, u, built));
    return built;
}
Exemple #20
0
void main_loop(int argc, char *argv[], int max_hosts)
{
	int i;
	int host;
	int *targeted_host;
	FileData local_file_data;
	FileData remote_file_data;
	Order *order;
	Direction direction;
	bool use_cache;
	char *top_dir;

	FtpInit();

	targeted_host = get_targeted_host(argc, argv, max_hosts);

	for (i = 0;; i++) {
		host = targeted_host[i];
		if (host == -1) {
			break;
		}

		message(PROCESS, cfgSectionNumberToName(host), 0, host);

		direction = get_direction(host);

		get_local_file_data(&local_file_data, host);

		if (command_line_option.rebuild_cache) { /* -r | --rebuild-cache */
			rebuild_cache(host);
			free_file_data(&local_file_data);
			continue;
		}
		if (command_line_option.catch_up) { /* -R | --catch-up */
			catch_up(&local_file_data, host);
			free_file_data(&local_file_data);
			continue;
		}

		if (direction == DOWNLOAD || !does_cache_exist(host)) {
			if (direction == DOWNLOAD) {
				printf(_("Rebuilding cache for downloading...\n"));
			} else {
				printf(_("Cache file is not found.\nCreating a new one...\n"));
			}
			if (connect_to_remote_host(host) != 0) {
				free_file_data(&local_file_data);
				continue;
			}
			get_remote_file_data(&remote_file_data, host);
			use_cache = FALSE;
		} else {
			load_cache(&remote_file_data, host);
			use_cache = TRUE;
		}

		order = compare_both_hosts_and_generate_order(&local_file_data, &remote_file_data, config.local_top_dir[host], config.remote_top_dir[host], direction, host);

		if (!does_need_update(order)) {
			disconnect_from_remote_host(host);
			if (direction == UPLOAD) {
				printf(_("The remote host doesn't need updating.\n"));
			} else {
				printf(_("The local host doesn't need updating.\n"));
			}
			if (!use_cache) {
				save_cache(&remote_file_data, host);
			}
			free_file_data(&remote_file_data);
			free_file_data(&local_file_data);
			continue;
		}

		if(command_line_option.list) {
			disconnect_from_remote_host(host);
			put_listing_of_updated_file(order, direction);
			free_file_data(&remote_file_data);
			free_file_data(&local_file_data);
			continue;
		}

		if(command_line_option.nlist) {
			disconnect_from_remote_host(host);
			put_the_number_of_updated_file(order, direction);
			free_file_data(&remote_file_data);
			free_file_data(&local_file_data);
			continue;
		}

		if (!use_cache) {
			printf("\n");
		}
		put_num_updated_file(order, direction);

		if (connect_to_remote_host(host) != 0) {
			free_file_data(&remote_file_data);
			free_file_data(&local_file_data);
			continue;
		}

		if (direction == UPLOAD) {
			top_dir = str_concat(config.remote_top_dir[host], "/", NULL);
		} else {
			top_dir = str_concat(config.local_top_dir[host], "/", NULL);
		}

		message(ENTER, top_dir, 0, host);
		execute_order(order, &remote_file_data, direction, host);
		message(LEAVE, top_dir, 0, host);

		free(top_dir);
		free_order(order);

		disconnect_from_remote_host(host);

		save_cache(&remote_file_data, host);

		free_file_data(&remote_file_data);
		free_file_data(&local_file_data);
	}
	free(targeted_host);
}