2001-12-10 01:13:39 +01:00
|
|
|
|
/* vi: set ts=2:
|
|
|
|
|
+-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de>
|
|
|
|
|
| | Enno Rehling <enno@eressea-pbem.de>
|
|
|
|
|
| Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de>
|
2003-07-29 11:48:03 +02:00
|
|
|
|
| (c) 1998 - 2003 | Henning Peters <faroul@beyond.kn-bremen.de>
|
2001-12-10 01:13:39 +01:00
|
|
|
|
| | Ingo Wilken <Ingo.Wilken@informatik.uni-oldenburg.de>
|
|
|
|
|
+-------------------+ Stefan Reich <reich@halbling.de>
|
|
|
|
|
|
|
|
|
|
This program may not be used, modified or distributed
|
|
|
|
|
without prior permission by the authors of Eressea.
|
|
|
|
|
*/
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#include <config.h>
|
|
|
|
|
#include "eressea.h"
|
|
|
|
|
|
|
|
|
|
/* kernel includes */
|
2001-04-16 16:34:19 +02:00
|
|
|
|
#include "battle.h"
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#include "build.h"
|
|
|
|
|
#include "building.h"
|
2001-04-16 16:34:19 +02:00
|
|
|
|
#include "faction.h"
|
|
|
|
|
#include "item.h"
|
|
|
|
|
#include "magic.h"
|
|
|
|
|
#include "region.h"
|
|
|
|
|
#include "unit.h"
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#include "movement.h"
|
|
|
|
|
#include "spell.h"
|
|
|
|
|
#include "race.h"
|
2001-12-10 01:13:39 +01:00
|
|
|
|
#include "skill.h"
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
/* util includes */
|
|
|
|
|
#include <rand.h>
|
|
|
|
|
|
|
|
|
|
/* libc includes */
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
|
|
#define EFFECT_HEALING_SPELL 5
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------ */
|
|
|
|
|
/* Kampfzauberfunktionen */
|
|
|
|
|
|
|
|
|
|
/* COMBAT */
|
|
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
|
spell_damage(int sp)
|
|
|
|
|
{
|
|
|
|
|
switch (sp) {
|
|
|
|
|
case 0:
|
|
|
|
|
/* meist t<>dlich 20-65 HP */
|
|
|
|
|
return "5d10+15";
|
|
|
|
|
case 1:
|
|
|
|
|
/* sehr variabel 4-48 HP */
|
|
|
|
|
return "4d12";
|
|
|
|
|
case 2:
|
|
|
|
|
/* leicht verwundet 4-18 HP */
|
|
|
|
|
return "2d8+2";
|
2001-02-11 23:13:07 +01:00
|
|
|
|
case 3:
|
|
|
|
|
/* fast immer t<>dlich 30-50 HP */
|
|
|
|
|
return "5d5+25";
|
2001-02-18 20:07:31 +01:00
|
|
|
|
case 4:
|
|
|
|
|
/* verwundet 11-26 HP */
|
|
|
|
|
return "3d6+8";
|
2001-01-25 10:37:55 +01:00
|
|
|
|
default:
|
|
|
|
|
/* schwer verwundet 14-34 HP */
|
|
|
|
|
return "4d6+10";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
get_force(int power, int formel)
|
|
|
|
|
{
|
|
|
|
|
switch (formel) {
|
|
|
|
|
case 0:
|
|
|
|
|
/* (4,8,12,16,20,24,28,32,36,40,44,..)*/
|
|
|
|
|
return (power * 4);
|
|
|
|
|
case 1:
|
|
|
|
|
/* (15,30,45,60,75,90,105,120,135,150,165,..) */
|
|
|
|
|
return (power*15);
|
|
|
|
|
case 2:
|
|
|
|
|
/* (40,80,120,160,200,240,280,320,360,400,440,..)*/
|
|
|
|
|
return (power*40);
|
|
|
|
|
case 3:
|
|
|
|
|
/* (2,8,18,32,50,72,98,128,162,200,242,..)*/
|
|
|
|
|
return (power*power*2);
|
|
|
|
|
case 4:
|
|
|
|
|
/* (4,16,36,64,100,144,196,256,324,400,484,..)*/
|
|
|
|
|
return (power*power*4);
|
|
|
|
|
case 5:
|
|
|
|
|
/* (10,40,90,160,250,360,490,640,810,1000,1210,1440,..)*/
|
|
|
|
|
return (power*power*10);
|
2001-02-11 23:19:55 +01:00
|
|
|
|
case 6:
|
2001-02-18 20:07:31 +01:00
|
|
|
|
/* (6,24,54,96,150,216,294,384,486,600,726,864)*/
|
2001-02-11 23:19:55 +01:00
|
|
|
|
return (power*power*6);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
default:
|
|
|
|
|
return power;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Generischer Kampfzauber */
|
|
|
|
|
int
|
|
|
|
|
sp_kampfzauber(fighter * fi, int level, int power, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
troop dt;
|
|
|
|
|
troop at;
|
|
|
|
|
/* Immer aus der ersten Reihe nehmen */
|
|
|
|
|
int minrow = FIGHT_ROW;
|
|
|
|
|
int maxrow = BEHIND_ROW-1;
|
|
|
|
|
int force, enemies;
|
|
|
|
|
int killed = 0;
|
|
|
|
|
const char *damage;
|
|
|
|
|
at.fighter = fi;
|
|
|
|
|
at.index = 0;
|
|
|
|
|
|
|
|
|
|
if (power <= 0) return 0;
|
|
|
|
|
|
2002-05-01 21:08:32 +02:00
|
|
|
|
sprintf(buf, "%s zaubert %s", unitname(fi->unit),
|
|
|
|
|
spell_name(sp, default_locale));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
switch(sp->id) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
/* lovar halbiert im Schnitt! */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
|
2002-04-07 02:44:01 +02:00
|
|
|
|
enemies = count_enemies(b, fi->side, FS_ENEMY,
|
2001-01-25 10:37:55 +01:00
|
|
|
|
minrow, maxrow);
|
|
|
|
|
if (!enemies) {
|
|
|
|
|
scat(", aber niemand war in Reichweite.");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
scat(":");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
|
|
|
|
|
do {
|
2002-04-07 02:44:01 +02:00
|
|
|
|
dt = select_enemy(b, fi, minrow, maxrow);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
assert(dt.fighter);
|
|
|
|
|
--force;
|
|
|
|
|
killed += terminate(dt, at, AT_COMBATSPELL, damage, false);
|
|
|
|
|
} while (force && killed < enemies);
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "%d Personen %s get<65>tet",
|
|
|
|
|
killed, killed == 1 ? "wurde" : "wurden");
|
|
|
|
|
|
|
|
|
|
scat(".");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Versteinern */
|
|
|
|
|
int
|
|
|
|
|
sp_versteinern(fighter * fi, int level, int power, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
unit *mage = fi->unit;
|
|
|
|
|
/* Wirkt auf erste und zweite Reihe */
|
|
|
|
|
int minrow = FIGHT_ROW;
|
|
|
|
|
int maxrow = BEHIND_ROW;
|
|
|
|
|
int force, enemies;
|
|
|
|
|
int stoned = 0;
|
|
|
|
|
|
2002-05-01 21:08:32 +02:00
|
|
|
|
sprintf(buf, "%s zaubert %s", unitname(fi->unit),
|
|
|
|
|
spell_name(sp, default_locale));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
force = lovar(get_force(power,0));
|
|
|
|
|
|
2002-04-07 02:44:01 +02:00
|
|
|
|
enemies = count_enemies(b, fi->side, FS_ENEMY,
|
2001-01-25 10:37:55 +01:00
|
|
|
|
minrow, maxrow);
|
|
|
|
|
if (!enemies) {
|
|
|
|
|
scat(", aber niemand war in Reichweite.");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
scat(":");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
|
|
|
|
|
do {
|
2002-04-07 02:44:01 +02:00
|
|
|
|
troop dt = select_enemy(b, fi, minrow, maxrow);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
fighter * df = dt.fighter;
|
|
|
|
|
unit * du = df->unit;
|
|
|
|
|
if (is_magic_resistant(mage, du, 0) == false) {
|
|
|
|
|
/* person ans ende hinter die lebenden schieben */
|
|
|
|
|
struct person p = dt.fighter->person[dt.index];
|
|
|
|
|
++dt.fighter->removed;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
++dt.fighter->side->removed;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
++stoned;
|
|
|
|
|
dt.fighter->person[dt.index] = dt.fighter->person[df->alive-df->removed];
|
2001-12-10 01:13:39 +01:00
|
|
|
|
dt.fighter->person[(df->alive - df->removed)] = p;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
--force;
|
|
|
|
|
} while (force && stoned < enemies);
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "%d Personen %s versteinert.",
|
|
|
|
|
stoned, stoned == 1 ? "wurde" : "wurden");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Benommenheit: eine Runde kein Angriff */
|
|
|
|
|
int
|
|
|
|
|
sp_stun(fighter * fi, int level, int power, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
unit *mage = fi->unit;
|
|
|
|
|
troop at;
|
|
|
|
|
/* Aus beiden Reihen nehmen */
|
|
|
|
|
int minrow = FIGHT_ROW;
|
|
|
|
|
int maxrow = BEHIND_ROW;
|
|
|
|
|
int force=0, enemies;
|
|
|
|
|
int stunned;
|
|
|
|
|
at.fighter = fi;
|
|
|
|
|
at.index = 0;
|
|
|
|
|
|
|
|
|
|
if (power <= 0) return 0;
|
|
|
|
|
|
2002-05-01 21:08:32 +02:00
|
|
|
|
sprintf(buf, "%s zaubert %s", unitname(fi->unit),
|
|
|
|
|
spell_name(sp, default_locale));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
switch(sp->id) {
|
|
|
|
|
case SPL_SHOCKWAVE:
|
|
|
|
|
force = lovar(get_force(power,1));
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
assert(0);
|
|
|
|
|
}
|
|
|
|
|
|
2002-04-07 02:44:01 +02:00
|
|
|
|
enemies = count_enemies(b, fi->side, FS_ENEMY, minrow, maxrow);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
if (!enemies) {
|
|
|
|
|
scat(", aber niemand war in Reichweite.");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
scat(":");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
|
|
|
|
|
stunned = 0;
|
|
|
|
|
do {
|
2002-04-07 02:44:01 +02:00
|
|
|
|
troop dt = select_enemy(b, fi, minrow, maxrow);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
fighter * df = dt.fighter;
|
|
|
|
|
unit * du = df->unit;
|
|
|
|
|
|
|
|
|
|
--force;
|
|
|
|
|
if (is_magic_resistant(mage, du, 0) == false) {
|
|
|
|
|
df->person[dt.index].flags |= FL_STUNNED;
|
|
|
|
|
++stunned;
|
|
|
|
|
}
|
|
|
|
|
} while (force && stunned < enemies);
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "%d Krieger %s f<>r einen Moment benommen.",
|
|
|
|
|
stunned, stunned == 1 ? "ist" : "sind");
|
|
|
|
|
|
|
|
|
|
scat(".");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
/* F<>r Spr<70>che 'get_scrambled_list_of_enemys_in_row', so da<64> man diese
|
|
|
|
|
* Liste nur noch einmal durchlaufen muss, um Fl<EFBFBD>chenzauberwirkungen
|
|
|
|
|
* abzuarbeiten */
|
|
|
|
|
|
|
|
|
|
/* Rosthauch */
|
|
|
|
|
int
|
|
|
|
|
sp_combatrosthauch(fighter * fi, int level, int power, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
cvector *fgs;
|
|
|
|
|
void **fig;
|
|
|
|
|
int force, enemies;
|
|
|
|
|
int k = 0;
|
|
|
|
|
/* Immer aus der ersten Reihe nehmen */
|
|
|
|
|
int minrow = FIGHT_ROW;
|
|
|
|
|
int maxrow = BEHIND_ROW-1;
|
|
|
|
|
static const char * msgt[] = {
|
|
|
|
|
"ruft ein f<>rchterliches Unwetter <20>ber seine Feinde, doch es gab niemanden mehr, den dies treffen konnte.",
|
|
|
|
|
"ruft ein f<>rchterliches Unwetter <20>ber seine Feinde, doch der magische Regen zeigt keinen Effekt.",
|
|
|
|
|
"ruft ein f<>rchterliches Unwetter <20>ber seine Feinde, Der magischen Regen l<>sst alles Eisen rosten."
|
|
|
|
|
};
|
|
|
|
|
unused(sp);
|
|
|
|
|
|
|
|
|
|
force = lovar(power * 15);
|
|
|
|
|
|
2002-04-07 02:44:01 +02:00
|
|
|
|
enemies = count_enemies(b, fi->side, FS_ENEMY, minrow, maxrow);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
if (!enemies) {
|
|
|
|
|
battlemsg(b, fi->unit, msgt[0]);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fgs = fighters(b, fi, minrow, maxrow, FS_ENEMY);
|
|
|
|
|
v_scramble(fgs->begin, fgs->end);
|
|
|
|
|
|
|
|
|
|
for (fig = fgs->begin; fig != fgs->end; ++fig) {
|
|
|
|
|
fighter *df = *fig;
|
|
|
|
|
if (!force)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/* da n min(force, x), sollte force maximal auf 0 sinken */
|
|
|
|
|
assert(force >= 0);
|
|
|
|
|
|
|
|
|
|
/* Eisenwaffen: I_SWORD, I_GREATSWORD, I_AXE, I_HALBERD (50%) */
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
boolean iron = false;
|
|
|
|
|
while (mat && mat->number>0) {
|
|
|
|
|
if (mat->type==R_IRON) {
|
|
|
|
|
iron = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
mat++;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
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) {
|
Zu Anfang des Kampfes wählt jeder Kämpfer aus seinem Arsenal zwei Waffen
aus: Seine beste Fernampfwaffe und seine beste Nahkampfwaffe.
Welches die beste Waffe ist, ist nicht immer einleuchtend, und an dieser
Stelle macht der Server eine Vereinfachung - er wählt die Waffe, bei der der
Angriffswert plus dem Verteidigungswert am größten ist.
** Wenn eine Einheit an der Reihe ist, wird geprüft:
1. Ist die Einheit ein Magier, so zaubert sie.
2. Ist die Einheit damit beschäftigt, eine Waffe nachzuladen, so tut sie das.
3. Steht die Einheit in einer der hinteren Reihen, attackiert sie, so
vorhanden, mit der Fernkampfwaffe.
4. Steht die Einheit in der vorderen Kampfreihe, so attackiert sie mit
derjenigen Waffe von beiden, in der ihr Talent am höchsten ist.
** Wird eine Einheit angegriffen, so gilt:
1. Handelt es sich um einen Angriff durch einen Nahkämpfer, so verteidigt
sie sich mit ihrer Nahkampfwaffe oder Waffenlosem Kampf.
2. Handelt es sich um eine Attacke durch einen Fernkämpfer, so verteidigt
sie sich mit dem halben Talent ihrer besten Waffe.
2002-10-04 23:25:16 +02:00
|
|
|
|
if (df->person[p].missile==wp) {
|
|
|
|
|
df->person[p].missile = NULL;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
--n;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (p=0;n && p!=df->unit->number;++p) {
|
Zu Anfang des Kampfes wählt jeder Kämpfer aus seinem Arsenal zwei Waffen
aus: Seine beste Fernampfwaffe und seine beste Nahkampfwaffe.
Welches die beste Waffe ist, ist nicht immer einleuchtend, und an dieser
Stelle macht der Server eine Vereinfachung - er wählt die Waffe, bei der der
Angriffswert plus dem Verteidigungswert am größten ist.
** Wenn eine Einheit an der Reihe ist, wird geprüft:
1. Ist die Einheit ein Magier, so zaubert sie.
2. Ist die Einheit damit beschäftigt, eine Waffe nachzuladen, so tut sie das.
3. Steht die Einheit in einer der hinteren Reihen, attackiert sie, so
vorhanden, mit der Fernkampfwaffe.
4. Steht die Einheit in der vorderen Kampfreihe, so attackiert sie mit
derjenigen Waffe von beiden, in der ihr Talent am höchsten ist.
** Wird eine Einheit angegriffen, so gilt:
1. Handelt es sich um einen Angriff durch einen Nahkämpfer, so verteidigt
sie sich mit ihrer Nahkampfwaffe oder Waffenlosem Kampf.
2. Handelt es sich um eine Attacke durch einen Fernkämpfer, so verteidigt
sie sich mit dem halben Talent ihrer besten Waffe.
2002-10-04 23:25:16 +02:00
|
|
|
|
if (df->person[p].melee==wp) {
|
|
|
|
|
df->person[p].melee = NULL;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
--n;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
cv_kill(fgs);
|
|
|
|
|
|
|
|
|
|
if (k == 0) {
|
|
|
|
|
/* keine Waffen mehr da, die zerst<73>rt werden k<>nnten */
|
|
|
|
|
battlemsg(b, fi->unit, msgt[1]);
|
|
|
|
|
fi->magic = 0; /* k<>mpft nichtmagisch weiter */
|
|
|
|
|
level = 0;
|
|
|
|
|
} else {
|
|
|
|
|
battlemsg(b, fi->unit, msgt[2]);
|
|
|
|
|
}
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
sp_sleep(fighter * fi, int level, int power, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
unit *mage = fi->unit;
|
|
|
|
|
unit *du;
|
|
|
|
|
troop dt;
|
|
|
|
|
int force, enemies;
|
|
|
|
|
int k = 0;
|
|
|
|
|
/* Immer aus der ersten Reihe nehmen */
|
|
|
|
|
int minrow = FIGHT_ROW;
|
|
|
|
|
int maxrow = BEHIND_ROW;
|
|
|
|
|
|
2002-05-01 21:08:32 +02:00
|
|
|
|
sprintf(buf, "%s zaubert %s", unitname(mage),
|
|
|
|
|
spell_name(sp, default_locale));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
force = lovar(power * 25);
|
2002-04-07 02:44:01 +02:00
|
|
|
|
enemies = count_enemies(b, fi->side, FS_ENEMY, minrow, maxrow);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
if (!enemies) {
|
|
|
|
|
scat(", aber niemand war in Reichweite.");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
scat(":");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
|
|
|
|
|
do {
|
2002-04-07 02:44:01 +02:00
|
|
|
|
dt = select_enemy(b, fi, minrow, maxrow);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
assert(dt.fighter);
|
|
|
|
|
du = dt.fighter->unit;
|
|
|
|
|
if (is_magic_resistant(mage, du, 0) == false) {
|
|
|
|
|
dt.fighter->person[dt.index].flags |= FL_SLEEPING;
|
|
|
|
|
++k;
|
|
|
|
|
--enemies;
|
|
|
|
|
}
|
|
|
|
|
--force;
|
|
|
|
|
} while (force && enemies);
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "%d Krieger %s in Schlaf versetzt.",
|
|
|
|
|
k, k == 1 ? "wurde" : "wurden");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static troop
|
|
|
|
|
select_ally_in_row(fighter * af, int minrow, int maxrow)
|
|
|
|
|
{
|
|
|
|
|
side *as = af->side;
|
|
|
|
|
battle *b = as->battle;
|
|
|
|
|
troop dt = no_troop;
|
|
|
|
|
fighter *df;
|
|
|
|
|
int allies;
|
|
|
|
|
|
|
|
|
|
allies = countallies(as);
|
|
|
|
|
|
|
|
|
|
if (!allies)
|
|
|
|
|
return dt;
|
|
|
|
|
allies = rand() % allies;
|
|
|
|
|
|
2003-07-29 11:48:03 +02:00
|
|
|
|
cv_foreach(df, b->fighters) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
side *ds = df->side;
|
|
|
|
|
int dr = get_unitrow(df);
|
|
|
|
|
|
|
|
|
|
if (helping(as, ds) && dr >= minrow && dr <= maxrow) {
|
|
|
|
|
if (df->alive - df->removed > allies) {
|
|
|
|
|
dt.index = allies;
|
|
|
|
|
dt.fighter = df;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
allies -= df->alive;
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-07-29 11:48:03 +02:00
|
|
|
|
cv_next(df);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
return dt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
sp_speed(fighter * fi, int level, int power, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
int force;
|
|
|
|
|
/* Immer aus der ersten Reihe nehmen */
|
|
|
|
|
int minrow = FIGHT_ROW;
|
|
|
|
|
int maxrow = BEHIND_ROW;
|
|
|
|
|
int allies;
|
|
|
|
|
int targets = 0;
|
|
|
|
|
|
2002-05-01 21:08:32 +02:00
|
|
|
|
sprintf(buf, "%s zaubert %s", unitname(fi->unit),
|
|
|
|
|
spell_name(sp, default_locale));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
scat(":");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
|
|
|
|
|
force = lovar(power * power * 5);
|
|
|
|
|
|
|
|
|
|
allies = countallies(fi->side);
|
|
|
|
|
/* maximal 2*allies Versuche ein Opfer zu finden, ansonsten best<73>nde
|
|
|
|
|
* die Gefahr eine Endlosschleife*/
|
|
|
|
|
allies *= 2;
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
troop dt = select_ally_in_row(fi, minrow, maxrow);
|
|
|
|
|
fighter *df = dt.fighter;
|
|
|
|
|
--allies;
|
|
|
|
|
|
|
|
|
|
if (df) {
|
|
|
|
|
if (df->person[dt.index].speed == 1) {
|
|
|
|
|
df->person[dt.index].speed++;
|
|
|
|
|
targets++;
|
|
|
|
|
--force;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} while (force && allies);
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "%d Krieger %s magisch beschleunigt.",
|
|
|
|
|
targets, targets == 1 ? "wurde" : "wurden");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static skill_t
|
|
|
|
|
random_skill(unit *u)
|
|
|
|
|
{
|
|
|
|
|
int n = 0;
|
|
|
|
|
skill_t sk;
|
|
|
|
|
|
|
|
|
|
for(sk=0;sk<MAXSKILLS;sk++) {
|
2002-02-15 17:13:30 +01:00
|
|
|
|
if (get_level(u, sk)) n++;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(n == 0)
|
|
|
|
|
return NOSKILL;
|
|
|
|
|
|
|
|
|
|
n = rand()%n;
|
|
|
|
|
|
|
|
|
|
for(sk=0;sk<MAXSKILLS;sk++) {
|
2002-02-15 17:13:30 +01:00
|
|
|
|
if (get_level(u, sk)) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
if(n == 0) return sk;
|
|
|
|
|
n--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert(0==1); /* Hier sollte er niemals ankommen. */
|
|
|
|
|
return NOSKILL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
sp_mindblast(fighter * fi, int level, int power, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
unit *mage = fi->unit;
|
|
|
|
|
troop dt;
|
|
|
|
|
unit *du;
|
|
|
|
|
skill_t sk;
|
|
|
|
|
int killed = 0;
|
|
|
|
|
int force, enemies;
|
|
|
|
|
int k = 0;
|
|
|
|
|
int minrow = FIGHT_ROW;
|
|
|
|
|
int maxrow = BEHIND_ROW;
|
|
|
|
|
|
2002-05-01 21:08:32 +02:00
|
|
|
|
sprintf(buf, "%s zaubert %s", unitname(mage),
|
|
|
|
|
spell_name(sp, default_locale));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
force = lovar(power * 25);
|
|
|
|
|
|
2002-04-07 02:44:01 +02:00
|
|
|
|
enemies = count_enemies(b, fi->side, FS_ENEMY, minrow, maxrow);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
if (!enemies) {
|
|
|
|
|
scat(", aber niemand war in Reichweite.");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
scat(":");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
|
|
|
|
|
do {
|
2002-04-07 02:44:01 +02:00
|
|
|
|
dt = select_enemy(b, fi, minrow, maxrow);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
assert(dt.fighter);
|
|
|
|
|
du = dt.fighter->unit;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (humanoidrace(du->race) && is_magic_resistant(mage, du, 0) == false) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
sk = random_skill(du);
|
|
|
|
|
if (sk != NOSKILL) {
|
|
|
|
|
/* Skill abziehen */
|
2002-02-16 11:37:18 +01:00
|
|
|
|
int n = 30+rand()%61;
|
|
|
|
|
skill * sv = get_skill(du, sk);
|
|
|
|
|
while (n>0) {
|
|
|
|
|
if (n>=30*du->number) {
|
2002-02-22 20:41:20 +01:00
|
|
|
|
reduce_skill(du, sv, 1);
|
2002-02-16 11:37:18 +01:00
|
|
|
|
n-=30;
|
|
|
|
|
} else {
|
2002-02-22 20:41:20 +01:00
|
|
|
|
if (rand()%(30*du->number)<n) reduce_skill(du, sv, 1);
|
2002-02-16 11:37:18 +01:00
|
|
|
|
n = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
--enemies;
|
|
|
|
|
} else {
|
|
|
|
|
troop t;
|
|
|
|
|
/* Keine Skills mehr, Einheit t<>ten */
|
|
|
|
|
t.fighter = dt.fighter;
|
|
|
|
|
t.index = 0;
|
|
|
|
|
while(dt.fighter->alive - dt.fighter->removed) {
|
|
|
|
|
rmtroop(t);
|
|
|
|
|
enemies--;
|
|
|
|
|
killed++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
k++;
|
|
|
|
|
}
|
|
|
|
|
--force;
|
|
|
|
|
} while (force && enemies);
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "%d Krieger %s Erinnerungen",
|
|
|
|
|
k, k == 1 ? "verliert" : "verlieren");
|
|
|
|
|
|
|
|
|
|
if (killed > 0) {
|
|
|
|
|
scat(", ");
|
|
|
|
|
icat(killed);
|
|
|
|
|
scat(" Krieger ");
|
|
|
|
|
if (killed == 1) {
|
|
|
|
|
scat("wurde");
|
|
|
|
|
} else {
|
|
|
|
|
scat("wurden");
|
|
|
|
|
}
|
|
|
|
|
scat(" get<65>tet");
|
|
|
|
|
}
|
|
|
|
|
scat(".");
|
|
|
|
|
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
sp_dragonodem(fighter * fi, int level, int power, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
troop dt;
|
|
|
|
|
troop at;
|
|
|
|
|
/* Immer aus der ersten Reihe nehmen */
|
|
|
|
|
int minrow = FIGHT_ROW;
|
|
|
|
|
int maxrow = BEHIND_ROW-1;
|
|
|
|
|
int force, enemies;
|
|
|
|
|
int killed = 0;
|
|
|
|
|
const char *damage;
|
|
|
|
|
|
2002-05-01 21:08:32 +02:00
|
|
|
|
sprintf(buf, "%s zaubert %s", unitname(fi->unit),
|
|
|
|
|
spell_name(sp, default_locale));
|
2001-02-18 20:07:31 +01:00
|
|
|
|
/* 11-26 HP */
|
|
|
|
|
damage = spell_damage(4);
|
2001-02-11 23:19:55 +01:00
|
|
|
|
/* Jungdrache 3->54, Drache 6->216, Wyrm 12->864 Treffer */
|
|
|
|
|
force = lovar(get_force(level,6));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2002-04-07 02:44:01 +02:00
|
|
|
|
enemies = count_enemies(b, fi->side, FS_ENEMY, minrow,
|
2001-01-25 10:37:55 +01:00
|
|
|
|
maxrow);
|
|
|
|
|
|
|
|
|
|
if (!enemies) {
|
|
|
|
|
scat(", aber niemand war in Reichweite.");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
scat(":");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
|
|
|
|
|
at.fighter = fi;
|
|
|
|
|
at.index = 0;
|
|
|
|
|
|
|
|
|
|
do {
|
2002-04-07 02:44:01 +02:00
|
|
|
|
dt = select_enemy(b, fi, minrow, maxrow);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
assert(dt.fighter);
|
|
|
|
|
--force;
|
|
|
|
|
killed += terminate(dt, at, AT_COMBATSPELL, damage, false);
|
|
|
|
|
} while (force && killed < enemies);
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "%d Personen %s get<65>tet",
|
|
|
|
|
killed, killed == 1 ? "wurde" : "wurden");
|
|
|
|
|
|
|
|
|
|
scat(".");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return level;
|
2002-02-23 20:04:51 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
sp_drainodem(fighter * fi, int level, int power, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
troop dt;
|
|
|
|
|
troop at;
|
|
|
|
|
/* Immer aus der ersten Reihe nehmen */
|
|
|
|
|
int minrow = FIGHT_ROW;
|
|
|
|
|
int maxrow = BEHIND_ROW-1;
|
|
|
|
|
int force, enemies;
|
|
|
|
|
int drained = 0;
|
|
|
|
|
int killed = 0;
|
|
|
|
|
const char *damage;
|
|
|
|
|
|
2002-05-01 21:08:32 +02:00
|
|
|
|
sprintf(buf, "%s zaubert %s", unitname(fi->unit),
|
|
|
|
|
spell_name(sp, default_locale));
|
2002-02-23 20:04:51 +01:00
|
|
|
|
/* 11-26 HP */
|
|
|
|
|
damage = spell_damage(4);
|
|
|
|
|
/* Jungdrache 3->54, Drache 6->216, Wyrm 12->864 Treffer */
|
|
|
|
|
force = lovar(get_force(level,6));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2002-04-07 02:44:01 +02:00
|
|
|
|
enemies = count_enemies(b, fi->side, FS_ENEMY, minrow,
|
2002-02-23 20:04:51 +01:00
|
|
|
|
maxrow);
|
|
|
|
|
|
|
|
|
|
if (!enemies) {
|
|
|
|
|
scat(", aber niemand war in Reichweite.");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
scat(":");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
|
|
|
|
|
at.fighter = fi;
|
|
|
|
|
at.index = 0;
|
|
|
|
|
|
|
|
|
|
do {
|
2002-04-07 02:44:01 +02:00
|
|
|
|
dt = select_enemy(b, fi, minrow, maxrow);
|
2002-02-23 20:04:51 +01:00
|
|
|
|
assert(dt.fighter);
|
|
|
|
|
if (hits(at, dt, NULL)) {
|
|
|
|
|
drain_exp(dt.fighter->unit, 90);
|
|
|
|
|
drained++;
|
|
|
|
|
}
|
|
|
|
|
killed += terminate(dt, at, AT_COMBATSPELL, damage, false);
|
|
|
|
|
--force;
|
|
|
|
|
} while (force && drained < enemies);
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "%d Person%s wurde ihre Lebenskraft entzogen",
|
|
|
|
|
drained, drained == 1 ? " wurde" : "en wurden");
|
|
|
|
|
|
|
|
|
|
scat(".");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return level;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
/* PRECOMBAT */
|
|
|
|
|
|
2002-02-23 20:04:51 +01:00
|
|
|
|
int
|
|
|
|
|
sp_shadowcall(fighter * fi, int level, int power, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
region *r = b->region;
|
|
|
|
|
unit *mage = fi->unit;
|
|
|
|
|
attrib *a;
|
|
|
|
|
int force = get_force(power, 3)/2;
|
2002-02-24 10:20:38 +01:00
|
|
|
|
const race *rc = NULL;
|
2002-02-23 20:04:51 +01:00
|
|
|
|
int num;
|
|
|
|
|
unit *u;
|
|
|
|
|
|
|
|
|
|
unused(sp);
|
|
|
|
|
|
|
|
|
|
switch(rand()%3) {
|
|
|
|
|
case 0:
|
|
|
|
|
rc = new_race[RC_SHADOWBAT];
|
|
|
|
|
num = 5000+dice_rand("3d5000");
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
rc = new_race[RC_NIGHTMARE];
|
|
|
|
|
num = 500+dice_rand("3d500");
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
rc = new_race[RC_VAMPUNICORN];
|
|
|
|
|
num = 500+dice_rand("3d500");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u = createunit(r, mage->faction, force, rc);
|
|
|
|
|
u->status = ST_FIGHT;
|
|
|
|
|
|
|
|
|
|
set_string(&u->name, racename(mage->faction->locale, u, u->race));
|
|
|
|
|
set_level(u, SK_WEAPONLESS, power/2);
|
|
|
|
|
set_level(u, SK_AUSDAUER, power/2);
|
|
|
|
|
u->hp = u->number * unit_max_hp(u);
|
|
|
|
|
|
2003-07-29 11:48:03 +02:00
|
|
|
|
if (fval(mage, UFL_PARTEITARNUNG))
|
|
|
|
|
fset(u, UFL_PARTEITARNUNG);
|
2002-02-23 20:04:51 +01:00
|
|
|
|
|
|
|
|
|
a = a_new(&at_unitdissolve);
|
|
|
|
|
a->data.ca[0] = 0;
|
|
|
|
|
a->data.ca[1] = 100;
|
|
|
|
|
a_add(&u->attribs, a);
|
|
|
|
|
|
|
|
|
|
make_fighter(b, u, true);
|
|
|
|
|
sprintf(buf, "%s ruft %d %s zu Hilfe", unitname(mage), force,
|
|
|
|
|
racename(default_locale, u, u->race));
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
int
|
|
|
|
|
sp_wolfhowl(fighter * fi, int level, int power, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
region *r = b->region;
|
|
|
|
|
unit *mage = fi->unit;
|
|
|
|
|
attrib *a;
|
2002-02-10 14:23:30 +01:00
|
|
|
|
int force = get_force(power, 3)/2;
|
|
|
|
|
unit *u = createunit(r, mage->faction, force, new_race[RC_WOLF]);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
unused(sp);
|
|
|
|
|
|
|
|
|
|
u->status = ST_FIGHT;
|
|
|
|
|
|
2002-02-23 20:04:51 +01:00
|
|
|
|
set_string(&u->name, racename(mage->faction->locale, u, u->race));
|
2002-02-10 14:23:30 +01:00
|
|
|
|
set_level(u, SK_WEAPONLESS, power/3);
|
|
|
|
|
set_level(u, SK_AUSDAUER, power/3);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
u->hp = u->number * unit_max_hp(u);
|
|
|
|
|
|
2003-07-29 11:48:03 +02:00
|
|
|
|
if (fval(mage, UFL_PARTEITARNUNG))
|
|
|
|
|
fset(u, UFL_PARTEITARNUNG);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
a = a_new(&at_unitdissolve);
|
|
|
|
|
a->data.ca[0] = 0;
|
|
|
|
|
a->data.ca[1] = 100;
|
|
|
|
|
a_add(&u->attribs, a);
|
|
|
|
|
|
|
|
|
|
make_fighter(b, u, true);
|
|
|
|
|
sprintf(buf, "%s ruft %d %s zu Hilfe", unitname(mage), force,
|
2002-02-23 20:04:51 +01:00
|
|
|
|
racename(default_locale, u, u->race));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
sp_shadowknights(fighter * fi, int level, int power, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
unit *u;
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
region *r = b->region;
|
|
|
|
|
unit *mage = fi->unit;
|
|
|
|
|
attrib *a;
|
|
|
|
|
int force;
|
|
|
|
|
unused(sp);
|
|
|
|
|
|
|
|
|
|
force = get_force(power, 3);
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
u = createunit(r, mage->faction, force, new_race[RC_SHADOWKNIGHT]);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
u->status = ST_FIGHT;
|
|
|
|
|
|
|
|
|
|
set_string(&u->name, "Schattenritter");
|
|
|
|
|
u->hp = u->number * unit_max_hp(u);
|
|
|
|
|
|
2003-07-29 11:48:03 +02:00
|
|
|
|
if (fval(mage, UFL_PARTEITARNUNG))
|
|
|
|
|
fset(u, UFL_PARTEITARNUNG);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
a = a_new(&at_unitdissolve);
|
|
|
|
|
a->data.ca[0] = 0;
|
|
|
|
|
a->data.ca[1] = 100;
|
|
|
|
|
a_add(&u->attribs, a);
|
|
|
|
|
|
|
|
|
|
make_fighter(b, u, true);
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "%s beschw<68>rt Trugbilder herauf", unitname(mage));
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
sp_strong_wall(fighter * fi, int level, int force, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
unit *mage = fi->unit;
|
|
|
|
|
building *burg;
|
|
|
|
|
int effect;
|
2002-05-01 21:08:32 +02:00
|
|
|
|
static boolean init = false;
|
|
|
|
|
static const curse_type * strongwall_ct;
|
|
|
|
|
if (!init) { init = true; strongwall_ct = ct_find("strongwall"); }
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
unused(sp);
|
|
|
|
|
|
|
|
|
|
if (!mage->building) {
|
|
|
|
|
sprintf(buf, "%s zaubert nicht, denn dieser Zauber h<>tte hier keinen "
|
|
|
|
|
"Sinn.", unitname(mage));
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
burg = mage->building;
|
|
|
|
|
|
|
|
|
|
effect = force/4;
|
|
|
|
|
if (rand()%4 < force%4)
|
|
|
|
|
effect++;
|
|
|
|
|
|
2002-05-01 21:08:32 +02:00
|
|
|
|
create_curse(mage, &burg->attribs, strongwall_ct, force, 1, effect, 0);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
sprintf(buf, "%s Mauern ergl<67>hen in einem unheimlichen magischen Licht.",
|
|
|
|
|
buildingname(burg));
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
sp_chaosrow(fighter * fi, int level, int force, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
unit *mage = fi->unit;
|
|
|
|
|
cvector *fgs;
|
|
|
|
|
void **fig;
|
|
|
|
|
int n, enemies, row;
|
|
|
|
|
int chance;
|
|
|
|
|
int k = 0;
|
|
|
|
|
int minrow = FIGHT_ROW;
|
2002-03-06 21:18:37 +01:00
|
|
|
|
int maxrow = NUMROWS;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
switch (sp->id) {
|
|
|
|
|
case SPL_CHAOSROW:
|
|
|
|
|
sprintf(buf, "%s murmelt eine d<>ster klingende Formel", unitname(mage));
|
|
|
|
|
force *= 40;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SPL_SONG_OF_CONFUSION:
|
|
|
|
|
sprintf(buf, "%s stimmt einen seltsamen Gesang an", unitname(mage));
|
|
|
|
|
force = get_force(force,5);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2002-04-07 02:44:01 +02:00
|
|
|
|
enemies = count_enemies(b, fi->side, FS_ENEMY, minrow, maxrow);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
if (!enemies) {
|
|
|
|
|
scat(", aber niemand war in Reichweite.");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
scat(". ");
|
|
|
|
|
|
|
|
|
|
fgs = fighters(b, fi, minrow, maxrow, FS_ENEMY);
|
|
|
|
|
v_scramble(fgs->begin, fgs->end);
|
|
|
|
|
|
|
|
|
|
for (fig = fgs->begin; fig != fgs->end; ++fig) {
|
|
|
|
|
fighter *df = *fig;
|
|
|
|
|
|
|
|
|
|
if (!force)
|
|
|
|
|
break;
|
|
|
|
|
/* force sollte wegen des max(0,x) nicht unter 0 fallen k<>nnen */
|
|
|
|
|
assert(force >= 0);
|
|
|
|
|
|
|
|
|
|
if (is_magic_resistant(mage, df->unit, 0))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
n = df->unit->number;
|
|
|
|
|
|
|
|
|
|
chance = 100 * force/n;
|
|
|
|
|
if (chance < 1 + rand()%100) {
|
2002-03-06 22:37:32 +01:00
|
|
|
|
row = statusrow(df->status)+FIRST_ROW;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
df->side->size[row] -= df->alive;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (df->unit->race->battle_flags & BF_NOBLOCK) {
|
2002-03-06 22:37:32 +01:00
|
|
|
|
df->side->nonblockers[row] -= df->alive;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2003-04-24 22:54:14 +02:00
|
|
|
|
row = FIRST_ROW + (rand()%(LAST_ROW-FIRST_ROW));
|
2002-03-06 22:37:32 +01:00
|
|
|
|
switch (row) {
|
|
|
|
|
case FIGHT_ROW:
|
|
|
|
|
df->status = ST_FIGHT;
|
2002-03-10 08:35:30 +01:00
|
|
|
|
break;
|
2002-03-06 22:37:32 +01:00
|
|
|
|
case BEHIND_ROW:
|
|
|
|
|
df->status = ST_CHICKEN;
|
2002-03-10 08:35:30 +01:00
|
|
|
|
break;
|
2002-03-06 22:37:32 +01:00
|
|
|
|
case AVOID_ROW:
|
|
|
|
|
df->status = ST_AVOID;
|
2002-03-10 08:35:30 +01:00
|
|
|
|
break;
|
2002-03-06 22:37:32 +01:00
|
|
|
|
case FLEE_ROW:
|
|
|
|
|
df->status = ST_FLEE;
|
2002-03-10 08:35:30 +01:00
|
|
|
|
break;
|
2002-03-06 22:37:32 +01:00
|
|
|
|
default:
|
|
|
|
|
assert(!"unknown combatrow");
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
df->side->size[row] += df->alive;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (df->unit->race->battle_flags & BF_NOBLOCK) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
df->side->nonblockers[row] += df->alive;
|
|
|
|
|
}
|
|
|
|
|
k++;
|
|
|
|
|
}
|
|
|
|
|
force = max(0, force-n);
|
|
|
|
|
}
|
|
|
|
|
cv_kill(fgs);
|
|
|
|
|
|
|
|
|
|
scat("Ein pl<70>tzlicher Tumult entsteht");
|
|
|
|
|
if (k > 0) {
|
|
|
|
|
scat(" und bringt die Kampfaufstellung durcheinander.");
|
|
|
|
|
}else{
|
|
|
|
|
scat(", der sich jedoch schnell wieder legt.");
|
|
|
|
|
}
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Gesang der Furcht (Kampfzauber) */
|
|
|
|
|
/* Panik (Pr<50>kampfzauber) */
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
sp_flee(fighter * fi, int level, int power, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
unit *mage = fi->unit;
|
|
|
|
|
cvector *fgs;
|
|
|
|
|
void **fig;
|
|
|
|
|
int minrow = FIGHT_ROW;
|
|
|
|
|
int maxrow = AVOID_ROW;
|
|
|
|
|
int force, n;
|
|
|
|
|
int panik = 0;
|
|
|
|
|
|
|
|
|
|
switch(sp->id) {
|
|
|
|
|
case SPL_FLEE:
|
2002-05-01 21:08:32 +02:00
|
|
|
|
sprintf(buf, "%s zaubert %s", unitname(mage),
|
|
|
|
|
spell_name(sp, default_locale));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
force = get_force(power,4);
|
|
|
|
|
break;
|
|
|
|
|
case SPL_SONG_OF_FEAR:
|
|
|
|
|
sprintf(buf, "%s stimmt einen d<>steren Gesang an", unitname(mage));
|
|
|
|
|
force = get_force(power,3);
|
|
|
|
|
break;
|
2002-02-23 20:04:51 +01:00
|
|
|
|
case SPL_AURA_OF_FEAR:
|
|
|
|
|
sprintf(buf, "%s ist von dunklen Schatten umgeben", unitname(mage));
|
|
|
|
|
force = get_force(power,5);
|
|
|
|
|
break;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
default:
|
|
|
|
|
force = get_force(power,10);
|
|
|
|
|
}
|
|
|
|
|
|
2002-04-07 02:44:01 +02:00
|
|
|
|
if (!count_enemies(b, fi->side, FS_ENEMY, minrow, maxrow)) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
scat(", aber es gab niemanden mehr, der beeinflusst werden konnte.");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
scat(":");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
|
|
|
|
|
fgs = fighters(b, fi, minrow, maxrow, FS_ENEMY);
|
|
|
|
|
v_scramble(fgs->begin, fgs->end);
|
|
|
|
|
|
|
|
|
|
for (fig = fgs->begin; fig != fgs->end; ++fig) {
|
|
|
|
|
fighter *df = *fig;
|
|
|
|
|
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_HERO)
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|| !fval(df->unit->race, RCF_UNDEAD))
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
if (is_magic_resistant(mage, df->unit, 0) == false) {
|
|
|
|
|
df->person[n].flags |= FL_PANICED;
|
|
|
|
|
++panik;
|
|
|
|
|
}
|
|
|
|
|
--force;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
cv_kill(fgs);
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "%d Krieger %s von Furcht gepackt.", panik,
|
|
|
|
|
panik == 1 ? "wurde" : "wurden");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Heldenmut */
|
|
|
|
|
int
|
|
|
|
|
sp_hero(fighter * fi, int level, int power, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
unit *mage = fi->unit;
|
|
|
|
|
/* Immer aus der ersten Reihe nehmen */
|
|
|
|
|
int minrow = FIGHT_ROW;
|
|
|
|
|
int maxrow = BEHIND_ROW-1;
|
|
|
|
|
int df_bonus = 0;
|
|
|
|
|
int force = 0;
|
|
|
|
|
int allies;
|
|
|
|
|
int targets = 0;
|
|
|
|
|
|
2002-05-01 21:08:32 +02:00
|
|
|
|
sprintf(buf, "%s zaubert %s", unitname(mage),
|
|
|
|
|
spell_name(sp, default_locale));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
switch(sp->id) {
|
|
|
|
|
case SPL_HERO:
|
|
|
|
|
df_bonus = power/5;
|
|
|
|
|
force = lovar(get_force(power,4));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
df_bonus = 1;
|
|
|
|
|
force = power;
|
|
|
|
|
}
|
|
|
|
|
scat(":");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
|
|
|
|
|
allies = countallies(fi->side);
|
|
|
|
|
/* maximal 2*allies Versuche ein Opfer zu finden, ansonsten best<73>nde
|
|
|
|
|
* die Gefahr eine Endlosschleife*/
|
|
|
|
|
allies *= 2;
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
troop dt = select_ally_in_row(fi, minrow, maxrow);
|
|
|
|
|
fighter *df = dt.fighter;
|
|
|
|
|
--allies;
|
|
|
|
|
|
|
|
|
|
if (df) {
|
|
|
|
|
if (!(df->person[dt.index].flags & FL_HERO)) {
|
|
|
|
|
df->person[dt.index].defence += df_bonus;
|
|
|
|
|
df->person[dt.index].flags = df->person[dt.index].flags | FL_HERO;
|
|
|
|
|
targets++;
|
|
|
|
|
--force;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} while (force && allies);
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "%d Krieger %s moralisch gest<73>rkt",
|
|
|
|
|
targets, targets == 1 ? "wurde" : "wurden");
|
|
|
|
|
|
|
|
|
|
scat(".");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
sp_berserk(fighter * fi, int level, int power, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
unit *mage = fi->unit;
|
|
|
|
|
/* Immer aus der ersten Reihe nehmen */
|
|
|
|
|
int minrow = FIGHT_ROW;
|
|
|
|
|
int maxrow = BEHIND_ROW-1;
|
|
|
|
|
int at_bonus = 0;
|
|
|
|
|
int df_malus = 0;
|
|
|
|
|
int force = 0;
|
|
|
|
|
int allies = 0;
|
|
|
|
|
int targets = 0;
|
|
|
|
|
|
2002-05-01 21:08:32 +02:00
|
|
|
|
sprintf(buf, "%s zaubert %s", unitname(mage),
|
|
|
|
|
spell_name(sp, default_locale));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
switch(sp->id) {
|
|
|
|
|
case SPL_BERSERK:
|
|
|
|
|
case SPL_BLOODTHIRST:
|
|
|
|
|
at_bonus = max(1,level/3);
|
|
|
|
|
df_malus = 2;
|
|
|
|
|
force = get_force(power,2);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
at_bonus = 1;
|
|
|
|
|
df_malus = 0;
|
|
|
|
|
force = power;
|
|
|
|
|
}
|
|
|
|
|
scat(":");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
|
|
|
|
|
allies = countallies(fi->side);
|
|
|
|
|
/* maximal 2*allies Versuche ein Opfer zu finden, ansonsten best<73>nde
|
|
|
|
|
* die Gefahr eine Endlosschleife*/
|
|
|
|
|
allies *= 2;
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
troop dt = select_ally_in_row(fi, minrow, maxrow);
|
|
|
|
|
fighter *df = dt.fighter;
|
|
|
|
|
--allies;
|
|
|
|
|
|
|
|
|
|
if (df) {
|
|
|
|
|
if (!(df->person[dt.index].flags & FL_HERO)) {
|
|
|
|
|
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_HERO;
|
|
|
|
|
targets++;
|
|
|
|
|
--force;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} while (force && allies);
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "%d Krieger %s in Blutrausch versetzt",
|
|
|
|
|
targets, targets == 1 ? "wurde" : "wurden");
|
|
|
|
|
|
|
|
|
|
scat(".");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
sp_frighten(fighter * fi, int level, int power, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
unit *mage = fi->unit;
|
|
|
|
|
/* Immer aus der ersten Reihe nehmen */
|
|
|
|
|
int minrow = FIGHT_ROW;
|
|
|
|
|
int maxrow = BEHIND_ROW-1;
|
|
|
|
|
int at_malus = 0;
|
|
|
|
|
int df_malus = 0;
|
|
|
|
|
int force = 0;
|
|
|
|
|
int enemies = 0;
|
|
|
|
|
int targets = 0;
|
|
|
|
|
|
|
|
|
|
at_malus = max(1,level - 4);
|
|
|
|
|
df_malus = 2;
|
|
|
|
|
force = get_force(power, 2);
|
|
|
|
|
|
2002-05-01 21:08:32 +02:00
|
|
|
|
sprintf(buf, "%s zaubert %s", unitname(mage),
|
|
|
|
|
spell_name(sp, default_locale));
|
2002-04-07 02:44:01 +02:00
|
|
|
|
enemies = count_enemies(b, fi->side, FS_ENEMY,
|
2001-01-25 10:37:55 +01:00
|
|
|
|
minrow, maxrow);
|
|
|
|
|
if (!enemies) {
|
|
|
|
|
scat(", aber niemand war in Reichweite.");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
scat(":");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
|
|
|
|
|
do {
|
2002-04-07 02:44:01 +02:00
|
|
|
|
troop dt = select_enemy(b, fi, minrow, maxrow);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
fighter *df = dt.fighter;
|
|
|
|
|
--enemies;
|
|
|
|
|
|
|
|
|
|
if (!df)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
assert(!helping(fi->side, df->side));
|
|
|
|
|
|
|
|
|
|
if (df->person[dt.index].flags & FL_HERO) {
|
|
|
|
|
df->person[dt.index].flags &= ~(FL_HERO);
|
|
|
|
|
}
|
|
|
|
|
if (is_magic_resistant(mage, df->unit, 0) == false) {
|
|
|
|
|
df->person[dt.index].attack -= at_malus;
|
|
|
|
|
df->person[dt.index].defence -= df_malus;
|
|
|
|
|
targets++;
|
|
|
|
|
}
|
|
|
|
|
--force;
|
|
|
|
|
} while (force && enemies);
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "%d Krieger %s eingesch<63>chtert",
|
|
|
|
|
targets, targets == 1 ? "wurde" : "wurden");
|
|
|
|
|
|
|
|
|
|
scat(".");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
sp_tiredsoldiers(fighter * fi, int level, int force, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
unit *mage = fi->unit;
|
|
|
|
|
int n = 0;
|
|
|
|
|
|
2001-02-09 14:53:53 +01:00
|
|
|
|
force = force * force * 4;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2002-05-01 21:08:32 +02:00
|
|
|
|
sprintf(buf, "%s zaubert %s", unitname(mage),
|
|
|
|
|
spell_name(sp, default_locale));
|
2002-04-07 02:44:01 +02:00
|
|
|
|
if (!count_enemies(b, fi->side, FS_ENEMY, FIGHT_ROW,
|
2001-01-25 10:37:55 +01:00
|
|
|
|
BEHIND_ROW)) {
|
|
|
|
|
scat(", aber niemand war in Reichweite.");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (force) {
|
2002-04-07 02:44:01 +02:00
|
|
|
|
troop t = select_enemy(b, fi, FIGHT_ROW, BEHIND_ROW);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
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) == false) {
|
|
|
|
|
df->person[t.index].flags = df->person[t.index].flags | FL_TIRED;
|
|
|
|
|
df->person[t.index].defence -= 2;
|
|
|
|
|
++n;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
--force;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
scat(": ");
|
|
|
|
|
if (n == 0) {
|
|
|
|
|
scat("Der Zauber konnte keinen Krieger erm<72>den.");
|
|
|
|
|
} else if (n == 1) {
|
|
|
|
|
scat("Ein Krieger schleppt sich m<>de in den Kampf.");
|
|
|
|
|
} else {
|
|
|
|
|
icat(n);
|
|
|
|
|
scat(" Krieger schleppen sich m<>de in den Kampf.");
|
|
|
|
|
}
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
sp_windshield(fighter * fi, int level, int power, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
unit *mage = fi->unit;
|
|
|
|
|
int force, at_malus;
|
|
|
|
|
int enemies;
|
|
|
|
|
/* Immer aus der hinteren Reihe nehmen */
|
|
|
|
|
int minrow = BEHIND_ROW;
|
|
|
|
|
int maxrow = BEHIND_ROW;
|
|
|
|
|
|
2002-05-01 21:08:32 +02:00
|
|
|
|
sprintf(buf, "%s zaubert %s", unitname(mage),
|
|
|
|
|
spell_name(sp, default_locale));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
switch(sp->id) {
|
|
|
|
|
case SPL_WINDSHIELD:
|
|
|
|
|
force = get_force(power,4);
|
|
|
|
|
at_malus = level/4;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
force = power;
|
|
|
|
|
at_malus = 2;
|
|
|
|
|
}
|
2002-04-07 02:44:01 +02:00
|
|
|
|
enemies = count_enemies(b, fi->side, FS_ENEMY,
|
2001-01-25 10:37:55 +01:00
|
|
|
|
minrow, maxrow);
|
|
|
|
|
if (!enemies) {
|
|
|
|
|
scat(", aber niemand war in Reichweite.");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
do {
|
2002-04-07 02:44:01 +02:00
|
|
|
|
troop dt = select_enemy(b, fi, minrow, maxrow);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
fighter *df = dt.fighter;
|
|
|
|
|
--enemies;
|
|
|
|
|
|
|
|
|
|
if (!df)
|
|
|
|
|
break;
|
|
|
|
|
assert(!helping(fi->side, df->side));
|
|
|
|
|
|
2002-10-04 23:37:35 +02:00
|
|
|
|
if (df->person[dt.index].missile) {
|
|
|
|
|
/* this suxx... affects your melee weapon as well. */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
df->person[dt.index].attack -= at_malus;
|
|
|
|
|
--force;
|
|
|
|
|
}
|
|
|
|
|
} while (force && enemies);
|
|
|
|
|
|
|
|
|
|
scat(": ");
|
|
|
|
|
scat("Ein Sturm kommt auf und die Sch<63>tzen k<>nnen kaum noch zielen.");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
sp_reeling_arrows(fighter * fi, int level, int force, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
unit *mage = fi->unit;
|
|
|
|
|
unused(force);
|
|
|
|
|
|
|
|
|
|
b->reelarrow = true;
|
2002-05-01 21:08:32 +02:00
|
|
|
|
sprintf(buf, "%s zaubert %s", unitname(mage),
|
|
|
|
|
spell_name(sp, default_locale));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
scat(": ");
|
|
|
|
|
scat("Ein Sturm kommt auf und die Sch<63>tzen k<>nnen kaum noch zielen.");
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
sp_denyattack(fighter * fi, int level, int power, spell * sp)
|
|
|
|
|
{
|
2001-03-04 19:41:27 +01:00
|
|
|
|
/* Magier weicht dem Kampf aus. Wenn er sich bewegen kann, zieht er in
|
|
|
|
|
* eine Nachbarregion, wobei ein NACH ber<EFBFBD>cksichtigt wird. Ansonsten
|
|
|
|
|
* bleibt er stehen und nimmt nicht weiter am Kampf teil. */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
unit *mage = fi->unit;
|
|
|
|
|
region *r = b->region;
|
|
|
|
|
unused(power);
|
|
|
|
|
|
2002-05-01 21:08:32 +02:00
|
|
|
|
sprintf(buf, "%s zaubert %s", unitname(mage),
|
|
|
|
|
spell_name(sp, default_locale));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
scat(": ");
|
|
|
|
|
|
|
|
|
|
/* Fliehende Einheiten verlassen auf jeden Fall Geb<65>ude und Schiffe. */
|
|
|
|
|
leave(r, mage);
|
|
|
|
|
/* und bewachen nicht */
|
|
|
|
|
setguard(mage, GUARD_NONE);
|
|
|
|
|
/* irgendwie den langen befehl sperren */
|
|
|
|
|
fset(fi, FIG_ATTACKED);
|
|
|
|
|
|
|
|
|
|
/* Hat der Magier ein NACH, wird die angegebene Richtung bevorzugt */
|
2001-04-16 16:34:19 +02:00
|
|
|
|
if (igetkeyword(mage->thisorder, mage->faction->locale) == K_MOVE
|
|
|
|
|
|| igetkeyword(mage->thisorder, mage->faction->locale) == K_ROUTE)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2001-03-04 19:41:27 +01:00
|
|
|
|
fi->run.region = movewhere(r, mage);
|
|
|
|
|
if (!fi->run.region) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
cmistake(mage, findorder(mage, mage->thisorder), 71, MSG_MOVE);
|
2001-03-04 19:41:27 +01:00
|
|
|
|
fi->run.region = fleeregion(mage);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
} else {
|
2001-03-04 19:41:27 +01:00
|
|
|
|
fi->run.region = fleeregion(mage);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2001-04-22 20:14:07 +02:00
|
|
|
|
/* bewegung erst am Ende des Kampfes, zusammen mit den normalen
|
|
|
|
|
* Fl<EFBFBD>chtlingen */
|
|
|
|
|
/* travel(r, mage, fi->run.region, 1); */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
/* wir tun so, als w<>re die Person geflohen */
|
|
|
|
|
fset(fi, FIG_NOLOOT);
|
2001-03-04 19:41:27 +01:00
|
|
|
|
fi->run.hp = mage->hp;
|
|
|
|
|
fi->run.number = mage->number;
|
2001-04-22 20:14:07 +02:00
|
|
|
|
/* fighter leeren */
|
|
|
|
|
rmfighter(fi, mage->number);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2001-03-04 19:41:27 +01:00
|
|
|
|
scat("Das Kampfget<65>mmel erstirbt und er kann unbehelligt "
|
|
|
|
|
"seines Weges ziehen.");
|
2001-01-25 10:37:55 +01:00
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
2003-07-29 11:48:03 +02:00
|
|
|
|
static void
|
2001-01-25 10:37:55 +01:00
|
|
|
|
do_meffect(fighter * af, int typ, int effect, int duration)
|
|
|
|
|
{
|
|
|
|
|
battle *b = af->side->battle;
|
|
|
|
|
meffect *meffect = calloc(1, sizeof(struct meffect));
|
|
|
|
|
cv_pushback(&b->meffects, meffect);
|
|
|
|
|
meffect->magician = af;
|
|
|
|
|
meffect->typ = typ;
|
|
|
|
|
meffect->effect = effect;
|
|
|
|
|
meffect->duration = duration;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
sp_armorshield(fighter * fi, int level, int power, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
int effect;
|
|
|
|
|
int duration;
|
|
|
|
|
unit *mage = fi->unit;
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
|
2002-05-01 21:08:32 +02:00
|
|
|
|
sprintf(buf, "%s zaubert %s", unitname(mage),
|
|
|
|
|
spell_name(sp, default_locale));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
|
|
|
|
|
/* gibt R<>stung +effect f<>r duration Treffer */
|
|
|
|
|
|
|
|
|
|
switch(sp->id) {
|
|
|
|
|
case SPL_ARMORSHIELD:
|
|
|
|
|
effect = level/3;
|
|
|
|
|
duration = 20*power*power;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
effect = level/4;
|
|
|
|
|
duration = power*power;
|
|
|
|
|
}
|
|
|
|
|
do_meffect(fi, SHIELD_ARMOR, effect, duration);
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
sp_reduceshield(fighter * fi, int level, int power, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
int effect;
|
|
|
|
|
int duration;
|
|
|
|
|
unit *mage = fi->unit;
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
|
2002-05-01 21:08:32 +02:00
|
|
|
|
sprintf(buf, "%s zaubert %s", unitname(mage),
|
|
|
|
|
spell_name(sp, default_locale));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
|
|
|
|
|
/* jeder Schaden wird um effect% reduziert bis der Schild duration
|
|
|
|
|
* Trefferpunkte aufgefangen hat */
|
|
|
|
|
|
|
|
|
|
switch(sp->id) {
|
|
|
|
|
case SPL_REDUCESHIELD:
|
|
|
|
|
effect = 50;
|
|
|
|
|
duration = 50*power*power;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
effect = level*3;
|
|
|
|
|
duration = get_force(power,5);
|
|
|
|
|
}
|
|
|
|
|
do_meffect(fi, SHIELD_REDUCE, effect, duration);
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
sp_fumbleshield(fighter * fi, int level, int power, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
int effect;
|
|
|
|
|
int duration;
|
|
|
|
|
unit *mage = fi->unit;
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
|
2002-05-01 21:08:32 +02:00
|
|
|
|
sprintf(buf, "%s zaubert %s", unitname(mage),
|
|
|
|
|
spell_name(sp, default_locale));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
|
|
|
|
|
/* der erste Zauber schl<68>gt mit 100% fehl */
|
|
|
|
|
|
|
|
|
|
switch(sp->id) {
|
|
|
|
|
case SPL_DRAIG_FUMBLESHIELD:
|
|
|
|
|
case SPL_GWYRRD_FUMBLESHIELD:
|
|
|
|
|
case SPL_CERRDOR_FUMBLESHIELD:
|
|
|
|
|
case SPL_TYBIED_FUMBLESHIELD:
|
|
|
|
|
duration = 100;
|
|
|
|
|
effect = max(1, 25-level);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
duration = 100;
|
|
|
|
|
effect = 10;
|
|
|
|
|
}
|
|
|
|
|
do_meffect(fi, SHIELD_BLOCK, effect, duration);
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
/* POSTCOMBAT */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
count_healable(battle *b, fighter *df)
|
|
|
|
|
{
|
|
|
|
|
side *s;
|
|
|
|
|
int healable = 0;
|
|
|
|
|
|
2003-07-29 11:48:03 +02:00
|
|
|
|
cv_foreach(s, b->sides) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
if (helping(df->side, s)) {
|
|
|
|
|
healable += s->casualties;
|
|
|
|
|
}
|
2003-07-29 11:48:03 +02:00
|
|
|
|
} cv_next(s);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
return healable;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* wiederbeleben */
|
|
|
|
|
int
|
|
|
|
|
sp_reanimate(fighter * fi, int level, int force, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
unit *mage = fi->unit;
|
|
|
|
|
int healable, k, j=0;
|
|
|
|
|
double c;
|
|
|
|
|
|
|
|
|
|
switch(sp->id) {
|
|
|
|
|
case SPL_REANIMATE:
|
|
|
|
|
sprintf(buf, "%s beginnt ein Ritual der Wiederbelebung",
|
|
|
|
|
unitname(mage));
|
|
|
|
|
k = EFFECT_HEALING_SPELL*force;
|
|
|
|
|
c = 0.50 + 0.02 * force;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
sprintf(buf, "%s zaubert %s",
|
2002-05-01 21:08:32 +02:00
|
|
|
|
unitname(mage),
|
|
|
|
|
spell_name(sp, default_locale));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
k = EFFECT_HEALING_SPELL*force;
|
|
|
|
|
c = 0.50;
|
|
|
|
|
}
|
|
|
|
|
if (get_item(mage, I_AMULET_OF_HEALING) > 0) {
|
|
|
|
|
scat(" und benutzt das ");
|
2001-05-20 10:41:11 +02:00
|
|
|
|
scat(locale_string(default_locale, resourcename(oldresourcetype[R_AMULET_OF_HEALING], 0)));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
scat(", um den Zauber zu verst<73>rken");
|
|
|
|
|
k *= 2;
|
|
|
|
|
c += 0.10;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
healable = count_healable(b, fi);
|
|
|
|
|
k = min(k, healable);
|
|
|
|
|
while (k--) {
|
|
|
|
|
troop t = select_corpse(b, fi);
|
|
|
|
|
if (t.fighter
|
|
|
|
|
&& t.fighter->side->casualties > 0
|
2001-12-10 01:13:39 +01:00
|
|
|
|
&& old_race(t.fighter->unit->race) != RC_DAEMON
|
2001-01-25 10:37:55 +01:00
|
|
|
|
&& (chance(c)))
|
|
|
|
|
{
|
|
|
|
|
assert(t.fighter->alive < t.fighter->unit->number);
|
|
|
|
|
/* t.fighter->person[].hp beginnt mit t.index = 0 zu z<>hlen,
|
|
|
|
|
* t.fighter->alive ist jedoch die Anzahl lebender in der Einheit,
|
|
|
|
|
* also sind die hp von t.fighter->alive
|
|
|
|
|
* t.fighter->hitpoints[t.fighter->alive-1] und der erste Tote
|
|
|
|
|
* oder weggelaufene ist t.fighter->hitpoints[t.fighter->alive] */
|
|
|
|
|
t.fighter->person[t.fighter->alive].hp = 2;
|
|
|
|
|
++t.fighter->alive;
|
|
|
|
|
++t.fighter->side->size[SUM_ROW];
|
|
|
|
|
++t.fighter->side->size[t.fighter->unit->status + 1];
|
|
|
|
|
++t.fighter->side->healed;
|
|
|
|
|
--t.fighter->side->casualties;
|
|
|
|
|
--healable;
|
|
|
|
|
++j;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (j == 0) {
|
|
|
|
|
scat(", kann aber niemanden wiederbeleben.");
|
|
|
|
|
level = 0;
|
|
|
|
|
} else if (j == 1) {
|
|
|
|
|
scat(" und belebt einen Toten wieder.");
|
|
|
|
|
level = 1;
|
|
|
|
|
} else {
|
|
|
|
|
scat(" und belebt ");
|
|
|
|
|
icat(j);
|
|
|
|
|
scat(" Tote wieder.");
|
|
|
|
|
}
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
sp_keeploot(fighter * fi, int level, int force, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
|
2002-05-01 21:08:32 +02:00
|
|
|
|
sprintf(buf, "%s zaubert %s.", unitname(fi->unit),
|
|
|
|
|
spell_name(sp, default_locale));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
|
|
|
|
|
b->keeploot = max(50, b->keeploot + 5*force);
|
|
|
|
|
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
sp_healing(fighter * fi, int level, int force, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
unit *mage = fi->unit;
|
|
|
|
|
int minrow = FIGHT_ROW;
|
|
|
|
|
int maxrow = AVOID_ROW;
|
|
|
|
|
int healhp;
|
|
|
|
|
int hp, wound;
|
|
|
|
|
int n, j = 0;
|
|
|
|
|
cvector *fgs;
|
|
|
|
|
void **fig;
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "%s k<>mmert sich um die Verletzten", unitname(mage));
|
|
|
|
|
|
|
|
|
|
/* bis zu 11 Personen pro Stufe (einen HP m<>ssen sie ja noch
|
|
|
|
|
* haben, sonst w<EFBFBD>ren sie tot) k<EFBFBD>nnen geheilt werden */
|
|
|
|
|
healhp = force * 200;
|
|
|
|
|
|
|
|
|
|
if (get_item(mage, I_AMULET_OF_HEALING) > 0) {
|
|
|
|
|
scat(" und benutzt das ");
|
2001-05-20 10:41:11 +02:00
|
|
|
|
scat(locale_string(default_locale, resourcename(oldresourcetype[R_AMULET_OF_HEALING], 0)));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
scat(", um die Heilzauber zu verst<73>rken");
|
|
|
|
|
healhp *= 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* gehe alle denen wir helfen der reihe nach durch, heile verwundete,
|
|
|
|
|
* bis zu verteilende HP aufgebraucht sind */
|
|
|
|
|
|
|
|
|
|
fgs = fighters(b, fi, minrow, maxrow, FS_HELP);
|
|
|
|
|
v_scramble(fgs->begin, fgs->end);
|
|
|
|
|
|
|
|
|
|
for (fig = fgs->begin; fig != fgs->end; ++fig) {
|
|
|
|
|
fighter *df = *fig;
|
|
|
|
|
|
|
|
|
|
if (!healhp)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/* wir heilen erstmal keine Monster */
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (!playerrace(df->unit->race))
|
2001-01-25 10:37:55 +01:00
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
hp = unit_max_hp(df->unit);
|
|
|
|
|
for (n = 0; n < df->unit->number; n++) {
|
|
|
|
|
if (!healhp)
|
|
|
|
|
break;
|
|
|
|
|
wound = hp - df->person[n].hp;
|
|
|
|
|
if ( wound > 0 && wound < hp) {
|
|
|
|
|
int heal = min(healhp, wound);
|
|
|
|
|
assert(heal>=0);
|
|
|
|
|
df->person[n].hp += heal;
|
|
|
|
|
healhp = max(0, healhp - heal);
|
|
|
|
|
j++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* haben wir noch HP <20>brig, so heilen wir nun auch Monster */
|
|
|
|
|
for (fig = fgs->begin; fig != fgs->end; ++fig) {
|
|
|
|
|
fighter *df = *fig;
|
|
|
|
|
|
|
|
|
|
if (!healhp)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/* Untote kann man nicht heilen */
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (fval(df->unit->race, RCF_NOHEAL))
|
2001-01-25 10:37:55 +01:00
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
hp = unit_max_hp(df->unit);
|
|
|
|
|
for (n = 0; n < df->unit->number; n++) {
|
|
|
|
|
if (!healhp)
|
|
|
|
|
break;
|
|
|
|
|
wound = hp - df->person[n].hp;
|
|
|
|
|
if ( wound > 0 && wound < hp) {
|
|
|
|
|
int heal = min(healhp, wound);
|
|
|
|
|
assert(heal>=0);
|
|
|
|
|
df->person[n].hp += heal;
|
|
|
|
|
healhp = max(0, healhp - heal);
|
|
|
|
|
j++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
cv_kill(fgs);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (j == 0) {
|
|
|
|
|
scat(", doch niemand mu<6D>te magisch geheilt werden.");
|
|
|
|
|
level = 0;
|
|
|
|
|
} else if (j == 1) {
|
|
|
|
|
scat(" und heilt einen Verwundeten.");
|
|
|
|
|
level = 1;
|
|
|
|
|
} else {
|
|
|
|
|
scat(" und heilt ");
|
|
|
|
|
icat(j);
|
|
|
|
|
scat(" Verwundete.");
|
|
|
|
|
}
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
sp_undeadhero(fighter * fi, int level, int force, spell * sp)
|
|
|
|
|
{
|
|
|
|
|
battle *b = fi->side->battle;
|
|
|
|
|
unit *mage = fi->unit;
|
|
|
|
|
region *r = b->region;
|
|
|
|
|
int minrow = FIGHT_ROW;
|
|
|
|
|
int maxrow = AVOID_ROW;
|
|
|
|
|
cvector *fgs;
|
|
|
|
|
void **fig;
|
|
|
|
|
int k, n, j;
|
|
|
|
|
int undead = 0;
|
|
|
|
|
double c;
|
|
|
|
|
|
|
|
|
|
/* maximal Stufe*4 Personen*/
|
|
|
|
|
k = get_force(force,0);
|
|
|
|
|
c = 0.50 + 0.02 * force;
|
|
|
|
|
|
|
|
|
|
/* Liste aus allen K<>mpfern */
|
|
|
|
|
fgs = fighters(b, fi, minrow, maxrow, FS_ENEMY | FS_HELP );
|
|
|
|
|
v_scramble(fgs->begin, fgs->end);
|
|
|
|
|
|
|
|
|
|
for (fig = fgs->begin; fig != fgs->end; ++fig) {
|
|
|
|
|
fighter *df = *fig;
|
|
|
|
|
unit *du = df->unit;
|
|
|
|
|
|
|
|
|
|
if (!k)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/* keine Monster */
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (!playerrace(du->race))
|
2001-01-25 10:37:55 +01:00
|
|
|
|
continue;
|
|
|
|
|
|
2001-03-04 19:41:27 +01:00
|
|
|
|
if (df->alive + df->run.number < du->number) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
j = 0;
|
|
|
|
|
|
|
|
|
|
/* Wieviele Untote k<>nnen wir aus dieser Einheit wecken? */
|
2001-03-04 19:41:27 +01:00
|
|
|
|
for (n = df->alive + df->run.number; n <= du->number; n++) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
if (!k) break;
|
|
|
|
|
|
|
|
|
|
if (chance(c)) {
|
|
|
|
|
undead++;
|
|
|
|
|
j++;
|
|
|
|
|
--df->side->casualties;
|
|
|
|
|
--k;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (j > 0) {
|
|
|
|
|
int hp = unit_max_hp(du);
|
|
|
|
|
if (j == du->number) {
|
|
|
|
|
/* Einheit war vollst<73>ndig tot und konnte vollst<73>ndig zu
|
|
|
|
|
* Untoten gemacht werden */
|
|
|
|
|
int nr;
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
du->race = new_race[RC_UNDEAD];
|
2001-01-25 10:37:55 +01:00
|
|
|
|
setguard(du, GUARD_NONE);
|
2001-02-10 15:18:01 +01:00
|
|
|
|
u_setfaction(du,mage->faction);
|
2003-07-29 11:48:03 +02:00
|
|
|
|
if (fval(mage, UFL_PARTEITARNUNG))
|
|
|
|
|
fset(du, UFL_PARTEITARNUNG);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
df->alive = du->number;
|
|
|
|
|
/* den Toten wieder volle Hitpoints geben */
|
|
|
|
|
for (nr = 0; nr != df->alive; ++nr) {
|
|
|
|
|
df->person[nr].hp = hp;
|
|
|
|
|
}
|
|
|
|
|
/* vereinfachtes loot */
|
|
|
|
|
change_money(mage, get_money(du));
|
|
|
|
|
set_money(du, 0);
|
|
|
|
|
} else {
|
|
|
|
|
unit *u;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
u = createunit(r, mage->faction, 0, new_race[RC_UNDEAD]);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
transfermen(du, u, j);
|
|
|
|
|
sprintf(buf, "%s", du->name);
|
|
|
|
|
set_string(&u->name, buf);
|
|
|
|
|
sprintf(buf, "%s", du->display);
|
|
|
|
|
set_string(&u->display, buf);
|
|
|
|
|
u->status = du->status;
|
|
|
|
|
setguard(u, GUARD_NONE);
|
2003-07-29 11:48:03 +02:00
|
|
|
|
if (fval(mage, UFL_PARTEITARNUNG))
|
|
|
|
|
fset(u, UFL_PARTEITARNUNG);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
set_string(&u->lastorder, du->lastorder);
|
|
|
|
|
/* den Toten volle Hitpoints geben */
|
|
|
|
|
u->hp = u->number * unit_max_hp(u);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
cv_kill(fgs);
|
|
|
|
|
|
|
|
|
|
if (undead == 0) {
|
|
|
|
|
sprintf(buf, "%s kann keinen Untoten rufen.", unitname(mage));
|
|
|
|
|
level = 0;
|
|
|
|
|
} else if (undead == 1) {
|
|
|
|
|
sprintf(buf, "%s erweckt einen Untoten.", unitname(mage));
|
|
|
|
|
level = 1;
|
|
|
|
|
} else {
|
|
|
|
|
sprintf(buf, "%s erweckt %d Untote.", unitname(mage), undead);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
battlerecord(b, buf);
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------ */
|