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; }
/* Feuersturm: Betrifft sehr viele Gegner (in der Regel alle), * macht nur vergleichsweise geringen Schaden */ int sp_immolation(struct castorder * co) { fighter * fi = co->magician.fig; int level = co->level; const spell * sp = co->sp; battle *b = fi->side->battle; troop at; int force, qi, killed = 0; const char *damage; quicklist *fgs, *ql; message *m; /* 2d4 HP */ damage = spell_damage(5); /* Betrifft alle Gegner */ force = 99999; if (!count_enemies(b, fi, FIGHT_ROW, AVOID_ROW, SELECT_ADVANCE | SELECT_FIND)) { message *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; fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_ENEMY); for (qi = 0, ql = fgs; ql; ql_advance(&ql, &qi, 1)) { fighter *df = (fighter *)ql_get(ql, qi); int n = df->alive - df->removed; troop dt; dt.fighter = df; while (n != 0) { dt.index = --n; killed += terminate(dt, at, AT_COMBATSPELL, damage, false); if (--force == 0) break; } if (force == 0) break; } ql_free(fgs); m = msg_message("battle::combatspell", "mage spell killed", fi->unit, sp, killed); 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; }
/* 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; }
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; }
int sp_tiredsoldiers(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 n = 0; int force = (int)(power * power * 4); message *m; if (!count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE | SELECT_FIND)) { message *m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); message_all(b, m); msg_release(m); return 0; } while (force) { troop t = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); fighter *df = t.fighter; if (!df) break; assert(!helping(fi->side, df->side)); if (!(df->person[t.index].flags & FL_TIRED)) { if (!is_magic_resistant(mage, df->unit, 0)) { df->person[t.index].flags = df->person[t.index].flags | FL_TIRED; df->person[t.index].defence -= 2; ++n; } } --force; } m = msg_message("cast_tired_effect", "mage spell amount", fi->unit, sp, n); message_all(b, m); msg_release(m); 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_sleep(struct castorder * co) { fighter * fi = co->magician.fig; int level = co->level; const spell * sp = co->sp; battle *b = fi->side->battle; unit *mage = fi->unit; unit *du; troop dt; int force, enemies; int k = 0; message *m; /* Immer aus der ersten Reihe nehmen */ force = lovar(co->force * 25); enemies = count_enemies(b, fi, FIGHT_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) { dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); assert(dt.fighter); du = dt.fighter->unit; if (!is_magic_resistant(mage, du, 0)) { dt.fighter->person[dt.index].flags |= FL_SLEEPING; ++k; --enemies; } --force; } m = msg_message("cast_sleep_effect", "mage spell amount", fi->unit, sp, k); message_all(b, m); msg_release(m); 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_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; }
/** 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; }
/** The mind blast spell for regular folks. * This spell temporarily reduces the skill of the victims */ int sp_mindblast(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 k = 0, reset = 0, maxloss = (level + 2) / 3; message *m; int force = lovar(power * 25); int enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, 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 > 0 && enemies > 0) { unit *du; troop dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); assert(dt.fighter); du = dt.fighter->unit; if (du->flags & UFL_MARK) { /* not this one again */ continue; } if (humanoidrace(u_race(du)) && force >= du->number) { if (!is_magic_resistant(mage, du, 0)) { skill_t sk = random_skill(du, true); if (sk != NOSKILL) { int n = 1 + rng_int() % maxloss; attrib *a = make_skillmod(sk, NULL, 0.0, n); /* neat: you can add a whole lot of these to a unit, they stack */ a_add(&du->attribs, a); } k += du->number; } force -= du->number; } du->flags |= UFL_MARK; reset = 1; enemies -= du->number; } if (reset) { unit *u; for (u = b->region->units; u; u = u->next) { u->flags &= ~UFL_MARK; } } m = msg_message("sp_mindblast_temp_effect", "mage spell amount", mage, sp, k); message_all(b, m); msg_release(m); return level; }
/* 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; }
/* 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; }
/** A mind blast spell for monsters. * This spell PERMANENTLY reduces the skill of the victims or kills them * when they have no skills left. Not currently in use. */ int sp_mindblast(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 killed = 0, k = 0, reset = 0; message *m; int force = lovar(power * 25); int enemies = count_enemies(b, fi, FIGHT_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 (enemies > 0 && force > 0) { unit *du; troop dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); assert(dt.fighter); du = dt.fighter->unit; if (du->flags & UFL_MARK) { /* not this one again */ continue; } if (humanoidrace(u_race(du)) && force >= du->number) { if (!is_magic_resistant(mage, du, 0)) { skill_t sk = random_skill(du, false); if (sk != NOSKILL) { skill *sv = unit_skill(du, sk); if (sv) { int n = 1 + rng_int() % 3; reduce_skill(du, sv, n); k += du->number; } } else { /* unit has no skill. kill it. */ kill_troop(dt); ++killed; } } force -= du->number; } else { /* only works against humanoids, don't try others. but do remove them * from 'force' once or we may never terminate. */ du->flags |= UFL_MARK; reset = 1; } enemies -= du->number; } if (reset) { unit *u; for (u = b->region->units; u; u = u->next) { u->flags &= ~UFL_MARK; } } m = msg_message("sp_mindblast_effect", "mage spell amount dead", mage, sp, k, killed); message_all(b, m); msg_release(m); return level; }
/* 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; }