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; }
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; }
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); } } }
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; }
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; }
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; }
/* 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; }
/* 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; }
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; }
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; }
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; }
/* 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; }
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; }
/* 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; }
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; }
/* 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; }
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; }
/** 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; }
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; }
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; }
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; }
/* 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; }