Beispiel #1
0
/* Panik (Praekampfzauber) */
int flee_spell(struct castorder * co, int strength)
{
    fighter * fi = co->magician.fig;
    int level = co->level;
    const spell * sp = co->sp;
    battle *b = fi->side->battle;
    unit *mage = fi->unit;
    selist *fgs, *ql;
    int n, qi, panik = 0;
    message *msg;
    double power = co->force;
    int force;

    force = (int)get_force(power, strength);
    if (force<=0 || !count_enemies(b, fi, FIGHT_ROW, AVOID_ROW, SELECT_ADVANCE | SELECT_FIND)) {
        msg = msg_message("sp_flee_effect_0", "mage spell", mage, sp);
        message_all(b, msg);
        msg_release(msg);
        return 0;
    }

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

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

        for (n = 0; force > 0 && n != df->alive; ++n) {
            if (df->person[n].flags & FL_PANICED) {   /* bei SPL_SONG_OF_FEAR moeglich */
                df->person[n].attack -= 1;
                --force;
                ++panik;
            }
            else if (!(df->person[n].flags & FL_COURAGE)
                || !(u_race(df->unit)->flags & RCF_UNDEAD)) {
                if (!is_magic_resistant(mage, df->unit, 0)) {
                    df->person[n].flags |= FL_PANICED;
                    ++panik;
                }
                --force;
            }
        }
    }
    selist_free(fgs);

    msg = msg_message("sp_flee_effect_1", "mage spell amount", mage, sp, panik);
    message_all(b, msg);
    msg_release(msg);

    return level;
}
Beispiel #2
0
int sp_healing(struct castorder * co)
{
    fighter * fi = co->magician.fig;
    int level = co->level;
    double power = co->force;
    battle *b = fi->side->battle;
    unit *mage = fi->unit;
    int j = 0;
    int healhp = (int)power * 200;
    selist *fgs;
    message *msg;
    bool use_item = has_ao_healing(mage);

    /* bis zu 11 Personen pro Stufe (einen HP muessen sie ja noch
     * haben, sonst waeren sie tot) koennen geheilt werden */

    if (use_item) {
        healhp *= 2;
    }

    /* gehe alle denen wir helfen der reihe nach durch, heile verwundete,
     * bis zu verteilende HP aufgebraucht sind */

    fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_HELP);
    scramble_fighters(fgs);
    j += heal_fighters(fgs, &healhp, false);
    j += heal_fighters(fgs, &healhp, true);
    selist_free(fgs);

    if (j <= 0) {
        level = j;
    }
    if (use_item) {
        msg =
            msg_message("healing_effect_1", "mage amount item", mage, j,
            get_resourcetype(R_AMULET_OF_HEALING));
    }
    else {
        msg = msg_message("healing_effect_0", "mage amount", mage, j);
    }
    message_all(b, msg);
    msg_release(msg);

    return level;
}
Beispiel #3
0
/** Spells: chaosrow / song of confusion.
 * German Title: 'Gesang der Verwirrung'
 */
int sp_chaosrow(struct castorder * co)
{
    fighter * fi = co->magician.fig;
    int level = co->level;
    double power = co->force;
    const spell * sp = co->sp;
    battle *b = fi->side->battle;
    unit *mage = fi->unit;
    selist *fgs, *ql;
    message *m;
    const char *mtype;
    int qi, k = 0;
    bool chaosrow = strcmp(sp->sname, "chaosrow") == 0;

    if (!count_enemies(b, fi, FIGHT_ROW, NUMROWS, SELECT_ADVANCE | SELECT_FIND)) {
        m = msg_message("spell_out_of_range", "mage spell", fi->unit, sp);
        message_all(b, m);
        msg_release(m);
        return 0;
    }

    power = chaosrow ? (power * 40) : get_force(power, 5);

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

    for (qi = 0, ql = fgs; ql; selist_advance(&ql, &qi, 1)) {
        fighter *df = (fighter *)selist_get(ql, qi);
        int n = df->unit->number;

        if (df->alive == 0)
            continue;
        if (power <= 0.0)
            break;

        if (is_magic_resistant(mage, df->unit, 0))
            continue;

        if (chance(power / n)) {
            int row = statusrow(df->status);
            df->side->size[row] -= df->alive;
            if (u_race(df->unit)->battle_flags & BF_NOBLOCK) {
                df->side->nonblockers[row] -= df->alive;
            }
            row = FIRST_ROW + (rng_int() % (NUMROWS - FIRST_ROW));
            switch (row) {
            case FIGHT_ROW:
                df->status = ST_FIGHT;
                break;
            case BEHIND_ROW:
                df->status = ST_CHICKEN;
                break;
            case AVOID_ROW:
                df->status = ST_AVOID;
                break;
            case FLEE_ROW:
                df->status = ST_FLEE;
                break;
            default:
                assert(!"unknown combatrow");
            }
            assert(statusrow(df->status) == row);
            df->side->size[row] += df->alive;
            if (u_race(df->unit)->battle_flags & BF_NOBLOCK) {
                df->side->nonblockers[row] += df->alive;
            }
            k += df->alive;
        }
        power = fmax(0, power - n);
    }
    selist_free(fgs);

    if (chaosrow) {
        mtype = (k > 0) ? "sp_chaosrow_effect_1" : "sp_chaosrow_effect_0";
    }
    else {
        mtype = (k > 0) ? "sp_confusion_effect_1" : "sp_confusion_effect_0";
    }
    m = msg_message(mtype, "mage", mage);
    message_all(b, m);
    msg_release(m);
    return level;
}
Beispiel #4
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 #5
0
int sp_undeadhero(struct castorder * co)
{
    fighter * fi = co->magician.fig;
    int level = co->level;
    double power = co->force;
    battle *b = fi->side->battle;
    unit *mage = fi->unit;
    region *r = b->region;
    selist *fgs, *ql;
    int qi, n, undead = 0;
    message *msg;
    int force = (int)get_force(power, 0);
    double c = 0.50 + 0.02 * power;

    /* Liste aus allen Kaempfern */
    fgs = select_fighters(b, fi->side, FS_ENEMY | FS_HELP, select_hero, NULL);
    scramble_fighters(fgs);

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

        /* Wieviele Untote koennen wir aus dieser Einheit wecken? */
        for (n = df->alive + df->run.number; force>0 && n != du->number; n++) {
            if (chance(c)) {
                ++j;
                --force;
            }
        }

        if (j > 0) {
            item **ilist;
            unit *u =
                create_unit(r, mage->faction, 0, get_race(RC_UNDEAD), 0, unit_getname(du),
                du);

            /* new units gets some stats from old unit */

            unit_setinfo(u, unit_getinfo(du));
            unit_setstatus(u, du->status);
            setguard(u, false);
            for (ilist = &du->items; *ilist;) {
                item *itm = *ilist;
                int loot = itm->number * j / du->number;
                if (loot != itm->number) {
                    int split = itm->number * j % du->number;
                    if (split > 0 && (rng_int() % du->number) < split) {
                        ++loot;
                    }
                }
                i_change(&u->items, itm->type, loot);
                i_change(ilist, itm->type, -loot);
                if (*ilist == itm) {
                    ilist = &itm->next;
                }
            }

            /* inherit stealth from magician */
            if (mage->flags & UFL_ANON_FACTION) {
                u->flags |= UFL_ANON_FACTION;
            }

            /* transfer dead people to new unit, set hitpoints to those of old unit */
            transfermen(du, u, j);
            u->hp = u->number * unit_max_hp(du);
            assert(j <= df->side->casualties);
            df->side->casualties -= j;
            df->side->dead -= j;

            /* counting total number of undead */
            undead += j;
        }
    }
    selist_free(fgs);

    if (level > undead) {
        level = undead;
    }
    if (undead == 0) {
        msg =
            msg_message("summonundead_effect_0", "mage region", mage, mage->region);
    }
    else {
        msg =
            msg_message("summonundead_effect_1", "mage region amount", mage,
            mage->region, undead);
    }

    message_all(b, msg);
    msg_release(msg);
    return level;
}
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;
    quicklist *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 = fighters(b, fi->side, FIGHT_ROW, BEHIND_ROW - 1, FS_ENEMY);
    scramble_fighters(fgs);

    for (qi = 0, ql = fgs; ql; ql_advance(&ql, &qi, 1)) {
        fighter *df = (fighter *)ql_get(ql, qi);

        if (df->alive == 0)
            continue;
        if (force <= 0)
            break;

        /* da n _min(force, x), sollte force maximal auf 0 sinken */
        assert(force >= 0);

        if (df->weapons) {
            int w;
            for (w = 0; df->weapons[w].type != NULL; ++w) {
                weapon *wp = df->weapons;
                int n = _min(force, wp->used);
                if (n) {
                    requirement *mat = wp->type->itype->construction->materials;
                    bool iron = false;
                    while (mat && mat->number > 0) {
                        if (mat->rtype == get_resourcetype(R_IRON)) {
                            iron = true;
                            break;
                        }
                        mat++;
                    }
                    if (iron) {
                        int p;
                        force -= n;
                        wp->used -= n;
                        k += n;
                        i_change(&df->unit->items, wp->type->itype, -n);
                        for (p = 0; n && p != df->unit->number; ++p) {
                            if (df->person[p].missile == wp) {
                                df->person[p].missile = NULL;
                                --n;
                            }
                        }
                        for (p = 0; n && p != df->unit->number; ++p) {
                            if (df->person[p].melee == wp) {
                                df->person[p].melee = NULL;
                                --n;
                            }
                        }
                    }
                }
            }
        }
    }
    ql_free(fgs);

    if (k == 0) {
        /* keine Waffen mehr da, die zerst�rt werden k�nnten */
        message *msg = msg_message("rust_effect_1", "mage", fi->unit);
        message_all(b, msg);
        msg_release(msg);
        fi->magic = 0;              /* k�mpft 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
int sp_flee(struct castorder * co)
{
    fighter * fi = co->magician.fig;
    int level = co->level;
    double power = co->force;
    const spell * sp = co->sp;
    battle *b = fi->side->battle;
    unit *mage = fi->unit;
    quicklist *fgs, *ql;
    int force, n, qi;
    int panik = 0;
    message *msg;

    switch (sp->id) {
    case SPL_FLEE:
        force = (int)get_force(power, 4);
        break;
    case SPL_SONG_OF_FEAR:
        force = (int)get_force(power, 3);
        break;
    case SPL_AURA_OF_FEAR:
        force = (int)get_force(power, 5);
        break;
    default:
        force = (int)get_force(power, 10);
    }

    if (!count_enemies(b, fi, FIGHT_ROW, AVOID_ROW, SELECT_ADVANCE | SELECT_FIND)) {
        msg = msg_message("sp_flee_effect_0", "mage spell", mage, sp);
        message_all(b, msg);
        msg_release(msg);
        return 0;
    }

    fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_ENEMY);
    scramble_fighters(fgs);

    for (qi = 0, ql = fgs; ql; ql_advance(&ql, &qi, 1)) {
        fighter *df = (fighter *)ql_get(ql, qi);

        for (n = 0; n != df->alive; ++n) {
            if (force < 0)
                break;

            if (df->person[n].flags & FL_PANICED) {   /* bei SPL_SONG_OF_FEAR m�glich */
                df->person[n].attack -= 1;
                --force;
                ++panik;
            }
            else if (!(df->person[n].flags & FL_COURAGE)
                || !(u_race(df->unit)->flags & RCF_UNDEAD)) {
                if (!is_magic_resistant(mage, df->unit, 0)) {
                    df->person[n].flags |= FL_PANICED;
                    ++panik;
                }
                --force;
            }
        }
    }
    ql_free(fgs);

    msg = msg_message("sp_flee_effect_1", "mage spell amount", mage, sp, panik);
    message_all(b, msg);
    msg_release(msg);

    return level;
}
Beispiel #8
0
int sp_undeadhero(struct castorder * co)
{
  fighter * fi = co->magician.fig;
  int level = co->level;
  double power = co->force;
  battle *b = fi->side->battle;
  unit *mage = fi->unit;
  region *r = b->region;
  quicklist *fgs, *ql;
  int qi, n, undead = 0;
  message *msg;
  int force = (int)get_force(power, 0);
  double c = 0.50 + 0.02 * power;

  /* Liste aus allen Kämpfern */
  fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_ENEMY | FS_HELP);
  scramble_fighters(fgs);

  for (qi = 0, ql = fgs; ql; ql_advance(&ql, &qi, 1)) {
    fighter *df = (fighter *) ql_get(ql, qi);
    unit *du = df->unit;

    if (force <= 0)
      break;

    /* keine Monster */
    if (!playerrace(u_race(du)))
      continue;

    if (df->alive + df->run.number < du->number) {
      int j = 0;

      /* Wieviele Untote können wir aus dieser Einheit wecken? */
      for (n = df->alive + df->run.number; n != du->number; n++) {
        if (chance(c)) {
          ++j;
          if (--force <= 0)
            break;
        }
      }

      if (j > 0) {
        unit *u =
          create_unit(r, mage->faction, 0, new_race[RC_UNDEAD], 0, du->name,
          du);

        /* new units gets some stats from old unit */

        if (du->display) {
          unit_setinfo(u, du->display);
        } else {
          unit_setinfo(u, NULL);
        }
        setstatus(u, du->status);
        setguard(u, GUARD_NONE);

        /* inherit stealth from magician */
        if (fval(mage, UFL_ANON_FACTION)) {
          fset(u, UFL_ANON_FACTION);
        }

        /* transfer dead people to new unit, set hitpoints to those of old unit */
        transfermen(du, u, j);
        u->hp = u->number * unit_max_hp(du);
        assert(j <= df->side->casualties);
        df->side->casualties -= j;
        df->side->dead -= j;

        /* counting total number of undead */
        undead += j;
      }
    }
  }
  ql_free(fgs);

  level = _min(level, undead);
  if (undead == 0) {
    msg =
      msg_message("summonundead_effect_0", "mage region", mage, mage->region);
  } else {
    msg =
      msg_message("summonundead_effect_1", "mage region amount", mage,
      mage->region, undead);
  }

  message_all(b, msg);
  msg_release(msg);
  return level;
}