Beispiel #1
0
static void rotting_herbs(void)
{
    region *r;
    int rule_rot = config_get_int("rules.economy.herbrot", HERBROTCHANCE);
    if (rule_rot == 0) return;

    for (r = regions; r; r = r->next) {
        unit *u;
        for (u = r->units; u; u = u->next) {
            const struct item_type *it_bag = it_find("magicherbbag");
            item **itmp = &u->items;
            int rot_chance = rule_rot;

            if (it_bag && *i_find(itmp, it_bag)) {
                rot_chance = (rot_chance * 2) / 5;
            }
            while (*itmp) {
                item *itm = *itmp;
                int n = itm->number;
                double k = n * rot_chance / 100.0;
                if (fval(itm->type, ITF_HERB)) {
                    double nv = normalvariate(k, k / 4);
                    int inv = (int)nv;
                    int delta = _min(n, inv);
                    if (!i_change(itmp, itm->type, -delta)) {
                        continue;
                    }
                }
                itmp = &itm->next;
            }
        }
    }
}
Beispiel #2
0
int 
Intervals::in(int x) {
  if (!n)
    return 0;
  if (i_find(this, x) > 0)
    return 1;
  return 0;
}
Beispiel #3
0
/*
 *  This routine is called when the 'Delete' menu item is selected
 */
void fun_del(WORD sobj)
{
    ANODE *pa;
    WNODE *pw;
    WORD disk_found = 0;

    /*
     * if the item selected is on the desktop, there may be other desktop
     * items that have been selected; make sure we process all of them
     */
    if ( (pa = i_find(0, sobj, NULL, NULL)) )
    {
        if (wants_to_delete_files() == FALSE)   /* i.e. remove icons or cancel */
            return;
        for ( ; sobj; sobj = win_isel(G.g_screen, DROOT, sobj))
        {
            pa = i_find(0,sobj,NULL,NULL);
            if (!pa)
                continue;
            if (pa->a_type == AT_ISDISK)
            {
                disk_found++;
                if (delete_disk(pa))
                    do_refresh_drive(pa->a_letter);
            }
        }
        if (disk_found)
        {
            desk_clear(0);
            return;
        }
    }

    /*
     * otherwise, process path associated with selected window icon, if any
     */
    pw = win_find(G.g_cwin);

    if (pw)
    {
        if (fun_op(OP_DELETE, -1, pw->w_path, NULL))
            fun_rebld(pw);
    }
}
Beispiel #4
0
/*
 *  Routine to call when several icons have been dragged from a
 *  window to another window (it might be the same window) and
 *  dropped on a particular icon or open space.
 *
 *  Note that, for DESK1, this is NEVER called if either the source
 *  or destination is the desktop.  Therefore 'datype' can ONLY be
 *  AT_ISFILE or AT_ISFOLD.
 */
void fun_drag(WORD src_wh, WORD dst_wh, WORD dst_ob, WORD dulx, WORD duly, WORD keystate)
{
    WORD  ret, datype, op;
    WNODE *psw, *pdw;
    ANODE *pda;
    FNODE *pdf;
    BYTE  destpath[MAXPATHLEN];

    op = (keystate&MODE_CTRL) ? OP_MOVE : OP_COPY;
    psw = win_find(src_wh);
    if (!psw)
        return;
    pdw = win_find(dst_wh);
    if (!pdw)
        return;

    pda = i_find(dst_wh, dst_ob, &pdf, NULL);
    datype = (pda) ? pda->a_type : AT_ISFILE;

    /* set up default destination path name */
    strcpy(destpath, pdw->w_path->p_spec);

    /* if destination is folder, insert folder name in path */
    if (datype == AT_ISFOLD)
        add_path(destpath, pdf->f_name);

    ret = fun_op(op, -1, psw->w_path, destpath);

    if (ret)
    {
        if (src_wh != dst_wh)
            desk_clear(src_wh);
        if (op == OP_MOVE)
            fun_rebld(psw);
        fun_rebld(pdw);
        /*
         * if we copied into a folder, we must check to see if it's
         * open in a window and, if so, redraw it too
         */
        if (datype == AT_ISFOLD) {
            pdw = fold_wind(destpath);
            if (pdw)
                fun_rebld(pdw);
        }
    }
}
Beispiel #5
0
// insert into interval with merge
void 
Intervals::insert(int x) {
  if (!n) {
    add(x);
    add(x);
    return;
  }
  int l = i_find(this, x);
  if (l > 0)
    return;
  l = -l - 1;

  if (x > v[l + 1]) {
    if (x == v[l + 1] + 1) {
      v[l + 1]++;
      goto Lmerge;
    }
    l += 2;
    if (l < n) {
      if (x == v[l] - 1) {
        v[l]--;
        goto Lmerge;
      }
    }
    goto Lmore;
  } else {
    INT_ASSERT(x < v[l]);
    if (x == v[l] - 1) {
      v[l]--;
      goto Lmerge;
    }
    if (!l)
      goto Lmore;
    l -= 2;
    if (x == v[l + 1] + 1) {
      v[l + 1]++;
      goto Lmerge;
    }
  }
 Lmore:
  fill(n + 2);
  if (n - 2 - l > 0)
    memmove(v + l + 2, v + l, sizeof(int) * (n - 2 - l));
  v[l] = x;
  v[l+1] = x;
  return;
 Lmerge:
  if (l) {
    if (v[l] - v[l-1] < 2) {
      l -= 2;
      goto Ldomerge;
    }
  }
  if (l < n - 2) {
    if (v[l + 2] - v[l + 1] < 2)
      goto Ldomerge;
  }
  return;
 Ldomerge:
  memmove(v + l + 1, v + l + 3, sizeof(int) * (n - 3 - l));
  n -= 2;
  goto Lmerge;
}
Beispiel #6
0
/* Rosthauch */
int sp_combatrosthauch(struct castorder * co)
{
    fighter * fi = co->magician.fig;
    int level = co->level;
    double power = co->force;
    battle *b = fi->side->battle;
    selist *ql, *fgs;
    int force = lovar(power * 15);
    int qi, k = 0;

    if (!count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW - 1,
        SELECT_ADVANCE | SELECT_FIND)) {
        message *msg = msg_message("rust_effect_0", "mage", fi->unit);
        message_all(b, msg);
        msg_release(msg);
        return 0;
    }

    fgs = select_fighters(b, fi->side, FS_ENEMY, select_armed, NULL);
    scramble_fighters(fgs);

    for (qi = 0, ql = fgs; force>0 && ql; selist_advance(&ql, &qi, 1)) {
        fighter *df = (fighter *)selist_get(ql, qi);
        int w;

        for (w = 0; df->weapons[w].type != NULL; ++w) {
            weapon *wp = df->weapons;
            if (df->unit->items && force > 0) {
                item ** itp = i_find(&df->unit->items, wp->type->itype);
                if (*itp) {
                    item *it = *itp;
                    requirement *mat = wp->type->itype->construction->materials;
                    int n = force;
                    if (it->number < n) n = it->number;

                    while (mat && mat->number > 0) {
                        if (mat->rtype == get_resourcetype(R_IRON)) {
                            int p;
                            force -= n;
                            k += n;
                            i_change(itp, wp->type->itype, -n);
                            for (p = 0; n && p != df->unit->number; ++p) {
                                if (df->person[p].melee == wp) {
                                    df->person[p].melee = NULL;
                                    --n;
                                }
                            }
                            for (p = 0; n && p != df->unit->number; ++p) {
                                if (df->person[p].missile == wp) {
                                    df->person[p].missile = NULL;
                                    --n;
                                }
                            }
                            break;
                        }
                        mat++;
                    }
                }
            }
        }
    }
    selist_free(fgs);

    if (k == 0) {
        /* keine Waffen mehr da, die zerstoert werden koennten */
        message *msg = msg_message("rust_effect_1", "mage", fi->unit);
        message_all(b, msg);
        msg_release(msg);
        fi->magic = 0;              /* kaempft nichtmagisch weiter */
        level = 0;
    }
    else {
        message *msg = msg_message("rust_effect_2", "mage", fi->unit);
        message_all(b, msg);
        msg_release(msg);
    }
    return level;
}
Beispiel #7
0
/*
 *  Based on current selected icons, figure out which menu items
 *  should be selected (deselected)
 */
static void men_update(OBJECT *tree)
{
    WORD item, nsel, isapp;
    const BYTE *pvalue;
    ANODE *appl;

    pvalue = 0;

    /* enable all items */
    for (item = OPENITEM; item <= PREFITEM; item++)
        menu_ienable(tree, item, 1);

    can_iapp = TRUE;
    can_show = TRUE;
    can_del = TRUE;

    /* disable some items */
    men_list(tree, ILL_ITEM, FALSE);

    nsel = 0;
    for (item = 0; (item=win_isel(G.g_screen, G.g_croot, item)) != 0; nsel++)
    {
        appl = i_find(G.g_cwin, item, NULL, &isapp);
        if (!appl)
            continue;
        switch(appl->a_type)
        {
        case AT_ISFILE:
            if (isapp || is_installed(appl))
                pvalue = ILL_FILE;
            else
            {
                pvalue = ILL_DOCU;
                can_iapp = FALSE;
            }
            break;
        case AT_ISFOLD:
            pvalue = ILL_FOLD;
            can_iapp = FALSE;
            break;
        case AT_ISDISK:
            pvalue = (appl->a_aicon == IG_FLOPPY) ? ILL_FDSK : ILL_HDSK;
            can_iapp = FALSE;
            break;
        case AT_ISTRSH:                 /* Trash */
            pvalue = ILL_TRASH;
            can_del = FALSE;
            break;
        }
        men_list(tree, pvalue, FALSE);       /* disable certain items */
    }

    if (win_ontop())
        pvalue = ILL_DESKTOP;
    else
        pvalue = ILL_NOTOP;
    if (pvalue == ILL_DESKTOP)
        men_list(tree, pvalue, TRUE);
    else
        men_list(tree, pvalue, FALSE);

    if (nsel != 1)
    {
        if (nsel)
        {
            pvalue = ILL_YSEL;
            can_show = FALSE;
        }
        else
        {
            pvalue = ILL_NOSEL;
            can_show = FALSE;
            can_del = FALSE;
            can_iapp = FALSE;
        }
        men_list(tree, pvalue, FALSE);
    }

#if CONF_WITH_SHUTDOWN
    menu_ienable(tree, QUITITEM, can_shutdown());
#else
    menu_ienable(tree, QUITITEM, 0);
#endif

#if WITH_CLI == 0
    menu_ienable(tree, CLIITEM, 0);
#endif

}
Beispiel #8
0
/** Use up resources for building an object.
* Build up to 'size' points of 'type', where 'completed'
* of the first object have already been finished. return the
* actual size that could be built.
*/
int build(unit * u, const construction * ctype, int completed, int want)
{
    const construction *type = ctype;
    int skills = INT_MAX;         /* number of skill points remainig */
    int basesk = 0;
    int made = 0;

    if (want <= 0)
        return 0;
    if (type == NULL)
        return ENOMATERIALS;
    if (type->improvement == NULL && completed == type->maxsize)
        return ECOMPLETE;
    if (type->btype != NULL) {
        building *b;
        if (!u->building || u->building->type != type->btype) {
            return EBUILDINGREQ;
        }
        b = inside_building(u);
        if (b == NULL)
            return EBUILDINGREQ;
    }

    if (type->skill != NOSKILL) {
        int effsk;
        int dm = get_effect(u, oldpotiontype[P_DOMORE]);

        assert(u->number);
        basesk = effskill(u, type->skill);
        if (basesk == 0)
            return ENEEDSKILL;

        effsk = basesk;
        if (inside_building(u)) {
            effsk = skillmod(u->building->type->attribs, u, u->region, type->skill,
                effsk, SMF_PRODUCTION);
        }
        effsk = skillmod(type->attribs, u, u->region, type->skill,
            effsk, SMF_PRODUCTION);
        if (effsk < 0)
            return effsk;             /* pass errors to caller */
        if (effsk == 0)
            return ENEEDSKILL;

        skills = effsk * u->number;

        /* technically, nimblefinge and domore should be in a global set of
         * "game"-attributes, (as at_skillmod) but for a while, we're leaving
         * them in here. */

        if (dm != 0) {
            /* Auswirkung Schaffenstrunk */
            dm = _min(dm, u->number);
            change_effect(u, oldpotiontype[P_DOMORE], -dm);
            skills += dm * effsk;
        }
    }
    for (; want > 0 && skills > 0;) {
        int c, n;

        /* skip over everything that's already been done:
         * type->improvement==NULL means no more improvements, but no size limits
         * type->improvement==type means build another object of the same time
         * while material lasts type->improvement==x means build x when type
         * is finished */
        while (type->improvement != NULL &&
            type->improvement != type &&
            type->maxsize > 0 && type->maxsize <= completed) {
            completed -= type->maxsize;
            type = type->improvement;
        }
        if (type == NULL) {
            if (made == 0)
                return ECOMPLETE;
            break;                    /* completed */
        }

        /*  Hier ist entweder maxsize == -1, oder completed < maxsize.
         *  Andernfalls ist das Datenfile oder sonstwas kaputt...
         *  (enno): Nein, das ist für Dinge, bei denen die nächste Ausbaustufe
         *  die gleiche wie die vorherige ist. z.b. gegenstände.
         */
        if (type->maxsize > 1) {
            completed = completed % type->maxsize;
        }
        else {
            completed = 0;
            assert(type->reqsize >= 1);
        }

        if (basesk < type->minskill) {
            if (made == 0)
                return ELOWSKILL;       /* not good enough to go on */
        }

        /* n = maximum buildable size */
        if (type->minskill > 1) {
            n = skills / type->minskill;
        }
        else {
            n = skills;
        }
        /* Flinkfingerring wirkt nicht auf Mengenbegrenzte (magische)
         * Talente */
        if (skill_limit(u->faction, type->skill) == INT_MAX) {
            const resource_type *ring = get_resourcetype(R_RING_OF_NIMBLEFINGER);
            item *itm = ring ? *i_find(&u->items, ring->itype) : 0;
            int i = itm ? itm->number : 0;
            if (i > 0) {
                int rings = _min(u->number, i);
                n = n * ((roqf_factor() - 1) * rings + u->number) / u->number;
            }
        }

        if (want < n) n = want;

        if (type->maxsize > 0) {
            n = _min(type->maxsize - completed, n);
            if (type->improvement == NULL) {
                want = n;
            }
        }

        if (type->materials)
            for (c = 0; n > 0 && type->materials[c].number; c++) {
                const struct resource_type *rtype = type->materials[c].rtype;
                int need, prebuilt;
                int canuse = get_pooled(u, rtype, GET_DEFAULT, INT_MAX);

                if (inside_building(u)) {
                    canuse = matmod(u->building->type->attribs, u, rtype, canuse);
                }

                if (canuse < 0)
                    return canuse;        /* pass errors to caller */
                canuse = matmod(type->attribs, u, rtype, canuse);
                if (type->reqsize > 1) {
                    prebuilt =
                        required(completed, type->reqsize, type->materials[c].number);
                    for (; n;) {
                        need =
                            required(completed + n, type->reqsize, type->materials[c].number);
                        if (need - prebuilt <= canuse)
                            break;
                        --n;                /* TODO: optimieren? */
                    }
                }
                else {
                    int maxn = canuse / type->materials[c].number;
                    if (maxn < n)
                        n = maxn;
                }
            }
        if (n <= 0) {
            if (made == 0)
                return ENOMATERIALS;
            else
                break;
        }
        if (type->materials)
            for (c = 0; type->materials[c].number; c++) {
                const struct resource_type *rtype = type->materials[c].rtype;
                int prebuilt =
                    required(completed, type->reqsize, type->materials[c].number);
                int need =
                    required(completed + n, type->reqsize, type->materials[c].number);
                int multi = 1;
                int canuse = 100;       /* normalization */
                if (inside_building(u))
                    canuse = matmod(u->building->type->attribs, u, rtype, canuse);
                if (canuse < 0)
                    return canuse;        /* pass errors to caller */
                canuse = matmod(type->attribs, u, rtype, canuse);

                assert(canuse % 100 == 0
                    || !"only constant multipliers are implemented in build()");
                multi = canuse / 100;
                if (canuse < 0)
                    return canuse;        /* pass errors to caller */

                use_pooled(u, rtype, GET_DEFAULT,
                    (need - prebuilt + multi - 1) / multi);
            }
        made += n;
        skills -= n * type->minskill;
        want -= n;
        completed = completed + n;
    }
    /* Nur soviel PRODUCEEXP wie auch tatsaechlich gemacht wurde */
    produceexp(u, ctype->skill, _min(made, u->number));

    return made;
}
Beispiel #9
0
void build_road(region * r, unit * u, int size, direction_t d)
{
    int n, left;
    region *rn = rconnect(r, d);

    assert(u->number);
    if (!eff_skill(u, SK_ROAD_BUILDING, r)) {
        cmistake(u, u->thisorder, 103, MSG_PRODUCE);
        return;
    }
    if (besieged(u)) {
        cmistake(u, u->thisorder, 60, MSG_PRODUCE);
        return;
    }

    if (rn == NULL || rn->terrain->max_road < 0) {
        cmistake(u, u->thisorder, 94, MSG_PRODUCE);
        return;
    }

    if (r->terrain->max_road < 0) {
        cmistake(u, u->thisorder, 94, MSG_PRODUCE);
        return;
    }

    if (r->terrain == newterrain(T_SWAMP)) {
        /* wenn kein Damm existiert */
        const struct building_type *bt_dam = bt_find("dam");
        if (!bt_dam || !buildingtype_exists(r, bt_dam, true)) {
            cmistake(u, u->thisorder, 132, MSG_PRODUCE);
            return;
        }
    }
    else if (r->terrain == newterrain(T_DESERT)) {
        const struct building_type *bt_caravan = bt_find("caravan");
        /* wenn keine Karawanserei existiert */
        if (!bt_caravan || !buildingtype_exists(r, bt_caravan, true)) {
            cmistake(u, u->thisorder, 133, MSG_PRODUCE);
            return;
        }
    }
    else if (r->terrain == newterrain(T_GLACIER)) {
        const struct building_type *bt_tunnel = bt_find("tunnel");
        /* wenn kein Tunnel existiert */
        if (!bt_tunnel || !buildingtype_exists(r, bt_tunnel, true)) {
            cmistake(u, u->thisorder, 131, MSG_PRODUCE);
            return;
        }
    }

    /* left kann man noch bauen */
    left = r->terrain->max_road - rroad(r, d);

    /* hoffentlich ist r->road <= r->terrain->max_road, n also >= 0 */
    if (left <= 0) {
        ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder,
            "error_roads_finished", ""));
        return;
    }

    if (size > 0)
        left = _min(size, left);
    /* baumaximum anhand der rohstoffe */
    if (u_race(u) == get_race(RC_STONEGOLEM)) {
        n = u->number * GOLEM_STONE;
    }
    else {
        n = get_pooled(u, get_resourcetype(R_STONE), GET_DEFAULT, left);
        if (n == 0) {
            cmistake(u, u->thisorder, 151, MSG_PRODUCE);
            return;
        }
    }
    left = _min(n, left);

    /* n = maximum by skill. try to maximize it */
    n = u->number * eff_skill(u, SK_ROAD_BUILDING, r);
    if (n < left) {
        const resource_type *ring = get_resourcetype(R_RING_OF_NIMBLEFINGER);
        item *itm = ring ? *i_find(&u->items, ring->itype) : 0;
        if (itm != NULL && itm->number > 0) {
            int rings = _min(u->number, itm->number);
            n = n * ((roqf_factor() - 1) * rings + u->number) / u->number;
        }
    }
    if (n < left) {
        int dm = get_effect(u, oldpotiontype[P_DOMORE]);
        if (dm != 0) {
            int sk = eff_skill(u, SK_ROAD_BUILDING, r);
            int todo = (left - n + sk - 1) / sk;
            todo = _min(todo, u->number);
            dm = _min(dm, todo);
            change_effect(u, oldpotiontype[P_DOMORE], -dm);
            n += dm * sk;
        }                           /* Auswirkung Schaffenstrunk */
    }

    /* make minimum of possible and available: */
    n = _min(left, n);

    /* n is now modified by several special effects, so we have to
     * minimize it again to make sure the road will not grow beyond
     * maximum. */
    rsetroad(r, d, rroad(r, d) + (short)n);

    if (u_race(u) == get_race(RC_STONEGOLEM)) {
        int golemsused = n / GOLEM_STONE;
        if (n % GOLEM_STONE != 0) {
            ++golemsused;
        }
        scale_number(u, u->number - golemsused);
    }
    else {
        use_pooled(u, get_resourcetype(R_STONE), GET_DEFAULT, n);
        /* Nur soviel PRODUCEEXP wie auch tatsaechlich gemacht wurde */
        produceexp(u, SK_ROAD_BUILDING, _min(n, u->number));
    }
    ADDMSG(&u->faction->msgs, msg_message("buildroad",
        "region unit size", r, u, n));
}