Exemple #1
0
int sp_reduceshield(struct castorder * co)
{
    fighter * fi = co->magician.fig;
    int level = co->level;
    double power = co->force;
    const spell * sp = co->sp;
    int effect;
    int duration;
    battle *b = fi->side->battle;
    message *m = msg_message("cast_spell_effect", "mage spell", fi->unit, sp);
    message_all(b, m);
    msg_release(m);

    /* jeder Schaden wird um effect% reduziert bis der Schild duration
     * Trefferpunkte aufgefangen hat */

    switch (sp->id) {
    case SPL_REDUCESHIELD:
        effect = 50;
        duration = (int)(50 * power * power);
        break;

    default:
        effect = level * 3;
        duration = (int)get_force(power, 5);
    }
    do_meffect(fi, SHIELD_REDUCE, effect, duration);
    return level;
}
Exemple #2
0
int sp_shadowcall(struct castorder * co)
{
    fighter * fi = co->magician.fig;
    int level = co->level;
    double power = co->force;
    battle *b = fi->side->battle;
    region *r = b->region;
    unit *mage = fi->unit;
    attrib *a;
    int force = (int)(get_force(power, 3) / 2);
    unit *u;
    const char *races[3] = { "shadowbat", "nightmare", "vampunicorn" };
    const race *rc = rc_find(races[rng_int() % 3]);
    message *msg;

    u = create_unit(r, mage->faction, force, rc, 0, NULL, mage);
    setstatus(u, ST_FIGHT);

    set_level(u, SK_WEAPONLESS, (int)(power / 2));
    set_level(u, SK_STAMINA, (int)(power / 2));
    u->hp = u->number * unit_max_hp(u);

    a = a_new(&at_unitdissolve);
    a->data.ca[0] = 0;
    a->data.ca[1] = 100;
    a_add(&u->attribs, a);

    make_fighter(b, u, fi->side, is_attacker(fi));
    msg =
        msg_message("sp_shadowcall_effect", "mage amount race", mage, u->number,
        u_race(u));
    message_all(b, msg);
    msg_release(msg);
    return level;
}
void main(void)
{
  int position = get_position();
  int force = get_force();
  int target_force = get_target_force(position, target_position, stiffness);
  
  int p = position - target;
  p_array[d_pointer] = p;
  int next_d_pointer = get_next_d_pointer(d_pointer);
  int d = p_array[next_d_pointer] = p_array[p_pointer];
  int i += p;
  
  if (i_coeficient)
    {
      if (i > i_max)        i = i_max;
      else if (i < -i_max)  i = -i_max;
      
      if (i > 0)
	{
	  if (i > i_decay)  i -= i_decay;
	  else              i  = 0;
	}
      else if (i > 0)
	{
	  if (i < -i_decay) i += i_decay;
	  else              i  = 0;
	}
    }
  output = p * p_coeficient + d * d_coefficient + i * i_coeficient;
}
Exemple #4
0
void test_smooth_r4<float_type>::test()
{
    // place particles along the x-axis within one half of the box,
    // put every second particle at the origin
    unsigned int npart = particle->nparticle();
    vector_type dx(0);
    dx[0] = box->edges()(0, 0) / npart / 2;

    std::vector<vector_type> r_list(particle->nparticle());
    std::vector<unsigned int> species(particle->nparticle());
    for (unsigned int k = 0; k < r_list.size(); ++k) {
        r_list[k] = (k % 2) ? k * dx : vector_type(0);
        species[k] = (k < npart_list[0]) ? 0U : 1U;  // set particle type for a binary mixture
    }
    BOOST_CHECK( set_position(*particle, r_list.begin()) == r_list.end() );
    BOOST_CHECK( set_species(*particle, species.begin()) == species.end() );

    // read forces and other stuff from device
    std::vector<float> en_pot(particle->nparticle());
    BOOST_CHECK( get_potential_energy(*particle, en_pot.begin()) == en_pot.end() );

    std::vector<vector_type> f_list(particle->nparticle());
    BOOST_CHECK( get_force(*particle, f_list.begin()) == f_list.end() );

    float const eps = std::numeric_limits<float>::epsilon();

    for (unsigned int i = 0; i < npart; ++i) {
        unsigned int type1 = species[i];
        unsigned int type2 = species[(i + 1) % npart];
        vector_type r = r_list[i] - r_list[(i + 1) % npart];
        vector_type f = f_list[i];

        // reference values from host module
        host_float_type fval, en_pot_;
        host_float_type rr = inner_prod(r, r);
        std::tie(fval, en_pot_) = (*host_potential)(rr, type1, type2);

        if (rr < host_potential->rr_cut(type1, type2)) {
            double rcut = host_potential->r_cut(type1, type2);
            // the GPU force module stores only a fraction of these values
            en_pot_ /= 2;

            // the first term is from the smoothing, the second from the potential
            // (see lennard_jones.cpp from unit tests)
            float const tolerance = 8 * eps * (1 + rcut/(rcut - std::sqrt(rr))) + 10 * eps;

            BOOST_CHECK_SMALL(norm_inf(fval * r - f), std::max(norm_inf(fval * r), 1.f) * tolerance * 2);
            BOOST_CHECK_CLOSE_FRACTION(en_pot_, en_pot[i], 2 * tolerance);
        }
        else {
            // when the distance is greater than the cutoff
            // set the force and the pair potential to zero
            fval = en_pot_ = 0;
            BOOST_CHECK_SMALL(norm_inf(f), eps);
            BOOST_CHECK_SMALL(en_pot[i], eps);
        }
    }
}
Exemple #5
0
int sp_berserk(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;
    int at_bonus = 0;
    int df_malus = 0;
    int force = 0;
    int allies = 0;
    int targets = 0;
    message *m;

    switch (sp->id) {
    case SPL_BERSERK:
    case SPL_BLOODTHIRST:
        at_bonus = _max(1, level / 3);
        df_malus = 2;
        force = (int)get_force(power, 2);
        break;

    default:
        at_bonus = 1;
        df_malus = 0;
        force = (int)power;
    }

    allies =
        count_allies(fi->side, FIGHT_ROW, BEHIND_ROW - 1, SELECT_ADVANCE, ALLY_ANY);
    /* maximal 2*allies Versuche ein Opfer zu finden, ansonsten best�nde
     * die Gefahr eine Endlosschleife*/
    allies *= 2;

    while (force && allies) {
        troop dt = select_ally(fi, FIGHT_ROW, BEHIND_ROW - 1, ALLY_ANY);
        fighter *df = dt.fighter;
        --allies;

        if (df) {
            if (!(df->person[dt.index].flags & FL_COURAGE)) {
                df->person[dt.index].attack += at_bonus;
                df->person[dt.index].defence -= df_malus;
                df->person[dt.index].flags = df->person[dt.index].flags | FL_COURAGE;
                targets++;
                --force;
            }
        }
    }

    m =
        msg_message("cast_berserk_effect", "mage spell amount", fi->unit, sp,
        targets);
    message_all(b, m);
    msg_release(m);
    return level;
}
Exemple #6
0
int sp_frighten(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;
    int at_malus = 0;
    int df_malus = 0;
    int force = 0;
    int enemies = 0;
    int targets = 0;
    message *m;

    at_malus = level - 4;
    if (at_malus < 1) at_malus = 1;
    df_malus = 2;
    force = (int)get_force(power, 2);

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

    while (force && enemies) {
        troop dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW - 1, SELECT_ADVANCE);
        fighter *df = dt.fighter;
        --enemies;

        if (!df)
            break;

        assert(!helping(fi->side, df->side));

        if (df->person[dt.index].flags & FL_COURAGE) {
            df->person[dt.index].flags &= ~(FL_COURAGE);
        }
        if (!is_magic_resistant(mage, df->unit, 0)) {
            df->person[dt.index].attack -= at_malus;
            df->person[dt.index].defense -= df_malus;
            targets++;
        }
        --force;
    }

    m =
        msg_message("cast_frighten_effect", "mage spell amount", fi->unit, sp,
        targets);
    message_all(b, m);
    msg_release(m);
    return level;
}
Exemple #7
0
TACO_vec *calc_direct(struct particle *p, size_t np, int s) {
    // partition_bsp is a function that partitions the given set of
    // particles by the binary space partitioning. The result is a
    // octree for 3D particles and a quadtree for 2D particles.
    TACO_region3r r = {{{0.0, 0.0, 0.0}}, {{1.0, 1.0, 1.0}}};
    struct cell *root = partition_bsp(p, np, r, s);
    map(interact, product(root, root));
    TACO_vec *force = get_force(root);
    return force;
}
Exemple #8
0
/* Benommenheit: eine Runde kein Angriff */
int sp_stun(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;
    message *m;
    /* Aus beiden Reihen nehmen */
    int force = 0, enemies;
    int stunned;

    if (power <= 0)
        return 0;

    switch (sp->id) {
    case SPL_SHOCKWAVE:
        force = lovar(get_force(power, 1));
        break;
    default:
        assert(0);
    }

    enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
    if (!enemies) {
        message *m =
            msg_message("battle::out_of_range", "mage spell", fi->unit, sp);
        message_all(b, m);
        msg_release(m);
        return 0;
    }

    stunned = 0;
    while (force && stunned < enemies) {
        troop dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
        fighter *df = dt.fighter;
        unit *du = df->unit;

        --force;
        if (!is_magic_resistant(mage, du, 0)) {
            df->person[dt.index].flags |= FL_STUNNED;
            ++stunned;
        }
    }

    m = msg_message("cast_stun_effect", "mage spell amount", fi->unit, sp, stunned);
    message_all(b, m);
    msg_release(m);
    return level;
}
Exemple #9
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;
}
Exemple #10
0
int sp_windshield(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;
    int force, at_malus;
    int enemies;
    message *m;

    switch (sp->id) {
    case SPL_WINDSHIELD:
        force = (int)get_force(power, 4);
        at_malus = level / 4;
        break;

    default:
        force = (int)power;
        at_malus = 2;
    }
    enemies = count_enemies(b, fi, BEHIND_ROW, BEHIND_ROW, SELECT_ADVANCE);
    if (!enemies) {
        m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp);
        message_all(b, m);
        msg_release(m);
        return 0;
    }

    while (force && enemies) {
        troop dt = select_enemy(fi, BEHIND_ROW, BEHIND_ROW, SELECT_ADVANCE);
        fighter *df = dt.fighter;
        --enemies;

        if (!df)
            break;
        assert(!helping(fi->side, df->side));

        if (df->person[dt.index].missile) {
            /* this suxx... affects your melee weapon as well. */
            df->person[dt.index].attack -= at_malus;
            --force;
        }
    }

    m = msg_message("cast_storm_effect", "mage spell", fi->unit, sp);
    message_all(b, m);
    msg_release(m);
    return level;
}
Exemple #11
0
int sp_dragonodem(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;
    troop dt;
    troop at;
    int force, enemies;
    const char *damage;

    /* 11-26 HP */
    damage = spell_damage(4);
    /* Jungdrache 3->54, Drache 6->216, Wyrm 12->864 Treffer */
    force = lovar(get_force(power, 6));

    enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW - 1, SELECT_ADVANCE);

    if (!enemies) {
        struct message *m =
            msg_message("spell_out_of_range", "mage spell", fi->unit, sp);
        message_all(b, m);
        msg_release(m);
        return 0;
    }
    else {
        struct message *m;
        int killed = 0;

        at.fighter = fi;
        at.index = 0;

        while (force && killed < enemies) {
            dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW - 1, SELECT_ADVANCE);
            assert(dt.fighter);
            --force;
            killed += terminate(dt, at, AT_COMBATSPELL, damage, false);
        }

        m =
            msg_message("cast_combatspell", "mage spell dead", fi->unit, sp,
            killed);
        message_all(b, m);
        msg_release(m);
    }
    return level;
}
Exemple #12
0
int sp_drainodem(fighter * fi, int level, double power, spell * sp)
{
    battle *b = fi->side->battle;
    troop dt;
    troop at;
    int force, enemies;
    int drained = 0;
    int killed = 0;
    const char *damage;
    message *m;

    /* 11-26 HP */
    damage = spell_damage(4);
    /* Jungdrache 3->54, Drache 6->216, Wyrm 12->864 Treffer */
    force = lovar(get_force(power, 6));

    enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW - 1, SELECT_ADVANCE);

    if (!enemies) {
        m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp);
        message_all(b, m);
        msg_release(m);
        return 0;
    }

    at.fighter = fi;
    at.index = 0;

    while (force && drained < enemies) {
        dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW - 1, SELECT_ADVANCE);
        assert(dt.fighter);
        if (hits(at, dt, NULL)) {
            drain_exp(dt.fighter->unit, 90);
            ++drained;
            killed += terminate(dt, at, AT_COMBATSPELL, damage, false);
        }
        --force;
    }

    m =
        msg_message("cast_drainlife_effect", "mage spell amount", fi->unit, sp,
        drained);
    message_all(b, m);
    msg_release(m);
    return level;
}
Exemple #13
0
/* Heldenmut */
int sp_hero(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;
    int df_bonus = 0;
    int force = 0;
    int allies;
    int targets = 0;
    message *m;

    df_bonus = (int)(power / 5);
    force = lovar(get_force(power, 4));
    if (force < 1) force = 1;

    allies =
        count_allies(fi->side, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE, ALLY_ANY);
    /* maximal 2*allies Versuche ein Opfer zu finden, ansonsten bestuende
     * die Gefahr eine Endlosschleife*/
    allies *= 2;

    while (force && allies) {
        troop dt = select_ally(fi, FIGHT_ROW, BEHIND_ROW, ALLY_ANY);
        fighter *df = dt.fighter;
        --allies;

        if (df) {
            if (!(df->person[dt.index].flags & FL_COURAGE)) {
                df->person[dt.index].defense += df_bonus;
                df->person[dt.index].flags = df->person[dt.index].flags | FL_COURAGE;
                targets++;
                --force;
            }
        }
    }

    m =
        msg_message("cast_hero_effect", "mage spell amount", fi->unit, sp, targets);
    message_all(b, m);
    msg_release(m);

    return level;
}
Exemple #14
0
int sp_wolfhowl(castorder * co)
{
    fighter * fi = co->magician.fig;
    int level = co->level;
    double power = co->force;
    int force = (int)(get_force(power, 3) / 2);
    const race * rc = get_race(RC_WOLF);
    if (force > 0) {
        unit *u;
        int skills = (int)(power/3);
        fi = summon_allies(fi, rc, force);
        u = fi->unit;
        set_level(u, SK_WEAPONLESS, skills);
        set_level(u, SK_STAMINA, skills);
        u->hp = u->number * unit_max_hp(u);
    }
    return level;
}
Exemple #15
0
/* Versteinern */
int sp_petrify(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;
    /* Wirkt auf erste und zweite Reihe */
    int force, enemies;
    int stoned = 0;
    message *m;

    force = lovar(get_force(power, 0));

    enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
    if (!enemies) {
        message *m =
            msg_message("battle::out_of_range", "mage spell", fi->unit, sp);
        message_all(b, m);
        msg_release(m);
        return 0;
    }

    while (force && stoned < enemies) {
        troop dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
        unit *du = dt.fighter->unit;
        if (!is_magic_resistant(mage, du, 0)) {
            /* person ans ende hinter die lebenden schieben */
            remove_troop(dt);
            ++stoned;
        }
        --force;
    }

    m =
        msg_message("cast_petrify_effect", "mage spell amount", fi->unit, sp,
        stoned);
    message_all(b, m);
    msg_release(m);
    return level;
}
Exemple #16
0
int sp_wolfhowl(struct castorder * co)
{
  fighter * fi = co->magician.fig;
  int level = co->level;
  double power = co->force;
  battle *b = fi->side->battle;
  region *r = b->region;
  unit *mage = fi->unit;
  attrib *a;
  message *msg;
  int force = (int)(get_force(power, 3) / 2);
  const race * rc = new_race[RC_WOLF];
  if (force>0) {
    unit *u =
      create_unit(r, mage->faction, force, rc, 0, NULL, mage);
    leave(u, true);
    setstatus(u, ST_FIGHT);

    set_level(u, SK_WEAPONLESS, (int)(power / 3));
    set_level(u, SK_STAMINA, (int)(power / 3));
    u->hp = u->number * unit_max_hp(u);
    
    if (fval(mage, UFL_ANON_FACTION)) {
      fset(u, UFL_ANON_FACTION);
    }

    a = a_new(&at_unitdissolve);
    a->data.ca[0] = 0;
    a->data.ca[1] = 100;
    a_add(&u->attribs, a);

    make_fighter(b, u, fi->side, is_attacker(fi));
  }
  msg =
    msg_message("sp_wolfhowl_effect", "mage amount race", mage, force, rc);
  message_all(b, msg);
  msg_release(msg);

  return level;
}
Exemple #17
0
/* Generischer Kampfzauber */
int damage_spell(struct castorder * co, int dmg, int strength)
{
    fighter * fi = co->magician.fig;
    int level = co->level;
    const spell * sp = co->sp;
    double power = co->force;
    battle *b = fi->side->battle;
    troop at, dt;
    message *m;
    /* Immer aus der ersten Reihe nehmen */
    int enemies, killed = 0;
    int force = lovar(get_force(power, strength));
    const char *damage = spell_damage(dmg);

    at.fighter = fi;
    at.index = 0;

    enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW - 1, SELECT_ADVANCE);
    if (enemies == 0) {
        m = msg_message("spell_out_of_range", "mage spell", fi->unit, sp);
        message_all(b, m);
        msg_release(m);
        return 0;
    }

    while (force > 0 && killed < enemies) {
        dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW - 1, SELECT_ADVANCE);
        assert(dt.fighter);
        --force;
        killed += terminate(dt, at, AT_COMBATSPELL, damage, false);
    }

    m = msg_message("cast_combatspell", "mage spell dead",
        fi->unit, sp, killed);
    message_all(b, m);
    msg_release(m);

    return level;
}
Exemple #18
0
int sp_shadowknights(struct castorder * co)
{
    fighter * fi = co->magician.fig;
    int level = co->level;
    double power = co->force;
    unit *u;
    battle *b = fi->side->battle;
    region *r = b->region;
    unit *mage = fi->unit;
    attrib *a;
    int force = (int)fmax(1, get_force(power, 3));
    message *msg;

    u =
        create_unit(r, mage->faction, force, get_race(RC_SHADOWKNIGHT), 0, NULL,
        mage);
    unit_setstatus(u, ST_FIGHT);

    u->hp = u->number * unit_max_hp(u);

    if (mage->flags & UFL_ANON_FACTION) {
        u->flags |= UFL_ANON_FACTION;
    }

    a = a_new(&at_unitdissolve);
    a->data.ca[0] = 0;
    a->data.ca[1] = 100;
    a_add(&u->attribs, a);

    make_fighter(b, u, fi->side, is_attacker(fi));

    msg = msg_message("sp_shadowknights_effect", "mage", mage);
    message_all(b, msg);
    msg_release(msg);

    return level;
}
Exemple #19
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;
}
Exemple #20
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;
}
Exemple #21
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;
}
Exemple #22
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;
}
Exemple #23
0
/* Generischer Kampfzauber */
int sp_kampfzauber(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;
    troop at, dt;
    message *m;
    /* Immer aus der ersten Reihe nehmen */
    int force, enemies;
    int killed = 0;
    const char *damage;

    if (power <= 0)
        return 0;
    at.fighter = fi;
    at.index = 0;

    switch (sp->id) {
        /* lovar halbiert im Schnitt! */
    case SPL_FIREBALL:
        damage = spell_damage(0);
        force = lovar(get_force(power, 0));
        break;
    case SPL_HAGEL:
        damage = spell_damage(2);
        force = lovar(get_force(power, 4));
        break;
    case SPL_METEORRAIN:
        damage = spell_damage(1);
        force = lovar(get_force(power, 1));
        break;
    default:
        damage = spell_damage(10);
        force = lovar(get_force(power, 10));
    }

    enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW - 1, SELECT_ADVANCE);
    if (enemies == 0) {
        message *m =
            msg_message("battle::out_of_range", "mage spell", fi->unit, sp);
        message_all(b, m);
        msg_release(m);
        return 0;
    }

    while (force > 0 && killed < enemies) {
        dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW - 1, SELECT_ADVANCE);
        assert(dt.fighter);
        --force;
        killed += terminate(dt, at, AT_COMBATSPELL, damage, false);
    }

    m = msg_message("battle::combatspell", "mage spell dead",
        fi->unit, sp, killed);
    message_all(b, m);
    msg_release(m);

    return level;
}