"4 Reihe rueckt nicht auf, Bogenschuetzen ohne Wirkung"

Umstellung des Kampfcodes. Siehe  http://www.pbem-spiele.de/forum/viewtopic.php?t=2545
This commit is contained in:
Enno Rehling 2006-07-30 12:52:26 +00:00
parent 39ada16f6c
commit 91bf99036e
8 changed files with 273 additions and 272 deletions

View File

@ -73,72 +73,60 @@ static weapondata weapontable[WP_MAX + 1] =
weapon_type * oldweapontype[WP_MAX]; weapon_type * oldweapontype[WP_MAX];
static boolean static boolean
attack_firesword(const troop * at, const struct weapon_type * wtype, int *casualties, int row) attack_firesword(const troop * at, const struct weapon_type * wtype, int *casualties)
{ {
fighter *fi = at->fighter; fighter *fi = at->fighter;
troop dt; troop dt;
/* Immer aus der ersten Reihe nehmen */ int killed = 0;
int minrow = FIGHT_ROW; const char *damage = "2d8";
int maxrow = FIGHT_ROW; int force = 1+rng_int()%10;
int enemies = 0; int enemies = count_enemies(fi->side->battle, fi, 0, 1, SELECT_ADVANCE|SELECT_DISTANCE);
int killed = 0;
const char *damage = "2d8";
int force = 1+rng_int()%10;
if (row==FIGHT_ROW) { if (!enemies) {
enemies = count_enemies(fi->side->battle, fi->side, minrow, maxrow, true); if (casualties) *casualties = 0;
} return true; /* if no enemy found, no use doing standarad attack */
if (!enemies) { }
if (casualties) *casualties = 0;
return true; /* if no enemy found, no use doing standarad attack */
}
if (fi->catmsg == -1) { if (fi->catmsg == -1) {
int i, k=0; int i, k=0;
for (i=0;i<=at->index;++i) { for (i=0;i<=at->index;++i) {
struct weapon * wp = fi->person[i].melee; struct weapon * wp = fi->person[i].melee;
if (wp!=NULL && wp->type == wtype) ++k; if (wp!=NULL && wp->type == wtype) ++k;
} }
sprintf(buf, "%d Kämpfer aus %s benutz%s Flammenschwert%s:", k, unitname(fi->unit), sprintf(buf, "%d Kämpfer aus %s benutz%s Flammenschwert%s:", k, unitname(fi->unit),
(k==1)?"t sein ":"en ihre",(k==1)?"":"er"); (k==1)?"t sein ":"en ihre",(k==1)?"":"er");
battlerecord(fi->side->battle, buf); battlerecord(fi->side->battle, buf);
fi->catmsg = 0; fi->catmsg = 0;
} }
do { do {
dt = select_enemy(fi, minrow, maxrow, true); dt = select_enemy(fi, 0, 1, SELECT_ADVANCE|SELECT_DISTANCE);
assert(dt.fighter); assert(dt.fighter);
--force; --force;
killed += terminate(dt, *at, AT_SPELL, damage, 1); killed += terminate(dt, *at, AT_SPELL, damage, 1);
} while (force && killed < enemies); } while (force && killed < enemies);
if (casualties) *casualties = killed; if (casualties) *casualties = killed;
return true; return true;
} }
#define CATAPULT_ATTACKS 6 #define CATAPULT_ATTACKS 6
static boolean static boolean
attack_catapult(const troop * at, const struct weapon_type * wtype, int * casualties, int row) attack_catapult(const troop * at, const struct weapon_type * wtype, int * casualties)
{ {
fighter *af = at->fighter; fighter *af = at->fighter;
unit *au = af->unit; unit *au = af->unit;
battle * b = af->side->battle; battle * b = af->side->battle;
troop dt; troop dt;
int d = 0, n; int d = 0, enemies;
int minrow, maxrow; weapon * wp = af->person[at->index].missile;
weapon * wp = af->person[at->index].missile;
static item_type * it_catapultammo = NULL; static item_type * it_catapultammo = NULL;
if (it_catapultammo==NULL) { if (it_catapultammo==NULL) {
it_catapultammo = it_find("catapultammo"); it_catapultammo = it_find("catapultammo");
} }
assert(row>=FIGHT_ROW); assert(wp->type==wtype);
if (row>BEHIND_ROW) { assert(af->person[at->index].reload==0);
/* probiere noch weitere attacken, kann nicht schiessen */
return true;
}
assert(wp->type==wtype);
assert(af->person[at->index].reload==0);
if (it_catapultammo!=NULL) { if (it_catapultammo!=NULL) {
if (get_pooled(au, it_catapultammo->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, 1) <= 0) { if (get_pooled(au, it_catapultammo->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, 1) <= 0) {
@ -147,27 +135,29 @@ attack_catapult(const troop * at, const struct weapon_type * wtype, int * casual
} }
} }
if (af->catmsg == -1) { enemies = count_enemies(b, af, FIGHT_ROW, FIGHT_ROW, SELECT_ADVANCE);
int i, k=0; enemies = min(enemies, CATAPULT_ATTACKS);
for (i=0;i<=at->index;++i) { if (enemies==0) {
if (af->person[i].reload==0 && af->person[i].missile == wp) ++k; return true; /* allow further attacks */
} }
sprintf(buf, "%d Kämpfer aus %s feuer%s Katapult ab:", k, unitname(au), (k==1)?"t sein":"n ihr");
battlerecord(b, buf);
af->catmsg = 0;
}
minrow = FIGHT_ROW;
maxrow = FIGHT_ROW;
n = min(CATAPULT_ATTACKS, count_enemies(b, af->side, minrow, maxrow, true)); if (af->catmsg == -1) {
int i, k=0;
for (i=0;i<=at->index;++i) {
if (af->person[i].reload==0 && af->person[i].missile == wp) ++k;
}
sprintf(buf, "%d Kämpfer aus %s feuer%s Katapult ab:", k, unitname(au), (k==1)?"t sein":"n ihr");
battlerecord(b, buf);
af->catmsg = 0;
}
if (it_catapultammo!=NULL) { if (it_catapultammo!=NULL) {
use_pooled(au, it_catapultammo->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, 1); use_pooled(au, it_catapultammo->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, 1);
} }
while (--n >= 0) { while (--enemies >= 0) {
/* Select defender */ /* Select defender */
dt = select_enemy(af, minrow, maxrow, true); dt = select_enemy(af, FIGHT_ROW, FIGHT_ROW, SELECT_ADVANCE);
if (!dt.fighter) if (!dt.fighter)
break; break;
@ -198,7 +188,7 @@ init_oldweapons(void)
int minskill = 1, wflags = WTF_NONE; int minskill = 1, wflags = WTF_NONE;
int m; int m;
weapon_mod * modifiers = NULL; weapon_mod * modifiers = NULL;
boolean (*attack)(const troop *, const struct weapon_type *, int *, int) = NULL; boolean (*no_special_attack)(const troop *, const struct weapon_type *, int *) = NULL;
assert(itype!=NULL || !"item not initialized"); assert(itype!=NULL || !"item not initialized");
@ -214,7 +204,7 @@ init_oldweapons(void)
oldweapontype[w] = new_weapontype(itype, wflags, weapontable[w].magres, damage, weapontable[w].attmod, weapontable[w].defmod, weapontable[w].reload.time, weapontable[w].skill, minskill); oldweapontype[w] = new_weapontype(itype, wflags, weapontable[w].magres, damage, weapontable[w].attmod, weapontable[w].defmod, weapontable[w].reload.time, weapontable[w].skill, minskill);
oldweapontype[w]->modifiers = modifiers; oldweapontype[w]->modifiers = modifiers;
oldweapontype[w]->attack = attack; oldweapontype[w]->attack = no_special_attack;
#ifdef SCORE_MODULE #ifdef SCORE_MODULE
if (itype->construction->materials==NULL) { if (itype->construction->materials==NULL) {

View File

@ -284,7 +284,8 @@ fbattlerecord(battle * b, faction * f, const char *s)
msg_release(m); msg_release(m);
} }
#define enemy(as, ds) (as->enemy[ds->index]&E_ENEMY) #define enemy(as, ds) (as->relations[ds->index]&E_ENEMY)
#define friendly(as, ds) (as->relations[ds->index]&E_FRIEND)
static void static void
set_enemy(side * as, side * ds, boolean attacking) set_enemy(side * as, side * ds, boolean attacking)
@ -298,9 +299,16 @@ set_enemy(side * as, side * ds, boolean attacking)
if (as->enemies[i]==NULL) as->enemies[i]=ds; if (as->enemies[i]==NULL) as->enemies[i]=ds;
if (as->enemies[i]==ds) break; if (as->enemies[i]==ds) break;
} }
ds->enemy[as->index] |= E_ENEMY; ds->relations[as->index] |= E_ENEMY;
as->enemy[ds->index] |= E_ENEMY; as->relations[ds->index] |= E_ENEMY;
if (attacking) as->enemy[ds->index] |= E_ATTACKING; if (attacking) as->relations[ds->index] |= E_ATTACKING;
}
static void
set_friendly(side * as, side * ds)
{
ds->relations[as->index] |= E_FRIEND;
as->relations[ds->index] |= E_FRIEND;
} }
static int static int
@ -357,7 +365,7 @@ select_corpse(battle * b, fighter * af)
} }
boolean boolean
helping(side * as, side * ds) helping(const side * as, const side * ds)
{ {
if (as->bf->faction==ds->bf->faction) return true; if (as->bf->faction==ds->bf->faction) return true;
return (boolean)(!enemy(as, ds) && allysf(as, ds->bf->faction)); return (boolean)(!enemy(as, ds) && allysf(as, ds->bf->faction));
@ -405,7 +413,7 @@ hpflee(int status)
} }
static int static int
get_row(const side * s, int row) get_row(const side * s, int row, const side * vs)
{ {
boolean counted[MAXSIDES]; boolean counted[MAXSIDES];
int enemyfront = 0; int enemyfront = 0;
@ -418,21 +426,25 @@ get_row(const side * s, int row)
memset(size, 0, sizeof(size)); memset(size, 0, sizeof(size));
for (line=FIRST_ROW;line!=NUMROWS;++line) { for (line=FIRST_ROW;line!=NUMROWS;++line) {
int si; int si;
side *sa;
/* how many enemies are there in the first row? */ /* how many enemies are there in the first row? */
for (si=0;s->enemies[si];++si) { for (si=0;s->enemies[si];++si) {
side *se = s->enemies[si]; side *se = s->enemies[si];
if (se->size[line]>0) { if (se->size[line]>0) {
int ai; enemyfront += se->size[line];
enemyfront += se->size[line]; /* - s->nonblockers[line] (nicht, weil angreifer) */ /* - s->nonblockers[line] (nicht, weil angreifer) */
for (ai=0;se->enemies[ai];++ai) { }
side * ally = se->enemies[ai]; }
if (!counted[ally->index] && !enemy(ally, s)) { for (sa = s->battle->sides; sa; sa=sa->next) {
int i; /* count people that like me, but don't like my enemy */
counted[ally->index] = true; if (friendly(sa, s) && enemy(sa, vs)) {
for (i=0;i!=NUMROWS;++i) { if (!counted[sa->index]) {
size[i] += ally->size[i] - ally->nonblockers[i]; int i;
}
for (i=0;i!=NUMROWS;++i) {
size[i] += sa->size[i] - sa->nonblockers[i];
} }
counted[sa->index] = true;
} }
} }
} }
@ -455,9 +467,15 @@ get_row(const side * s, int row)
} }
int int
get_unitrow(const fighter * af) get_unitrow(const fighter * af, const side * vs)
{ {
return get_row(af->side, statusrow(af->status)); int row = statusrow(af->status);
if (vs==NULL) {
int i;
for (i=FIGHT_ROW;i!=row;++i) if (af->side->size[i]) break;
return FIGHT_ROW+(row-i);
}
return get_row(af->side, row, vs);
} }
static void static void
@ -1170,30 +1188,30 @@ terminate(troop dt, troop at, int type, const char *damage, boolean missile)
} }
static int static int
count_side(const side * s, int minrow, int maxrow, boolean advance) count_side(const side * s, const side * vs, int minrow, int maxrow, int select)
{ {
fighter * fig; fighter * fig;
int people = 0; int people = 0;
int unitrow[NUMROWS]; int unitrow[NUMROWS];
int i;
if (advance) { if (maxrow<FIGHT_ROW) return 0;
for (i=0;i!=NUMROWS;++i) unitrow[i] = -1; if (select&SELECT_ADVANCE) {
memset(unitrow, -1, sizeof(unitrow));
} }
for (fig = s->fighters; fig; fig = fig->next) { for (fig = s->fighters; fig; fig = fig->next) {
int row; if (fig->alive - fig->removed > 0) {
int row = statusrow(fig->status);
if (fig->alive - fig->removed <= 0) continue; if (select&SELECT_ADVANCE) {
row = statusrow(fig->status); if (unitrow[row] == -1) {
if (advance) { unitrow[row] = get_unitrow(fig, vs);
if (unitrow[row] == -1) { }
unitrow[row] = get_unitrow(fig); row = unitrow[row];
}
if (row >= minrow && row <= maxrow) {
people += fig->alive - fig->removed;
if (people>0 && (select&SELECT_FIND)) break;
} }
row = unitrow[row];
}
if (row >= minrow && row <= maxrow) {
people += fig->alive - fig->removed;
} }
} }
return people; return people;
@ -1203,7 +1221,7 @@ count_side(const side * s, int minrow, int maxrow, boolean advance)
* troops that are still alive, not those that are still fighting although * troops that are still alive, not those that are still fighting although
* dead. */ * dead. */
int int
count_allies(side * as, int minrow, int maxrow, boolean advance) count_allies(const side * as, int minrow, int maxrow, int select)
{ {
battle *b = as->battle; battle *b = as->battle;
side *s; side *s;
@ -1211,30 +1229,34 @@ count_allies(side * as, int minrow, int maxrow, boolean advance)
for (s=b->sides;s;s=s->next) { for (s=b->sides;s;s=s->next) {
if (!helping(as, s)) continue; if (!helping(as, s)) continue;
count += count_side(s, minrow, maxrow, advance); count += count_side(s, NULL, minrow, maxrow, select);
if (count>0 && (select&SELECT_FIND)) break;
} }
return count; return count;
} }
/* new implementation of count_enemies ignores mask, since it was never used */
int int
count_enemies(battle * b, side * as, int minrow, int maxrow, boolean advance) count_enemies(battle * b, const fighter * af, int minrow, int maxrow, int select)
{ {
int i = 0; int i = 0;
side * s; side *es, *as = af->side;
if (maxrow<FIRST_ROW) return 0; if (maxrow<FIRST_ROW) return 0;
for (es = b->sides; es; es = es->next) {
for (s = b->sides; s; s = s->next) { if (as==NULL || enemy(es, as)) {
if (as==NULL || enemy(s, as)) { int offset = 0;
i += count_side(s, minrow, maxrow, advance); if (select&SELECT_DISTANCE) {
offset = get_unitrow(af, es) - FIGHT_ROW;
}
i += count_side(es, as, minrow-offset, maxrow-offset, select);
if (i>0 && (select&SELECT_FIND)) break;
} }
} }
return i; return i;
} }
troop troop
select_enemy(fighter * af, int minrow, int maxrow, boolean advance) select_enemy(fighter * af, int minrow, int maxrow, int select)
{ {
side *as = af->side; side *as = af->side;
battle * b = as->battle; battle * b = as->battle;
@ -1249,7 +1271,7 @@ select_enemy(fighter * af, int minrow, int maxrow, boolean advance)
} }
minrow = max(minrow, FIGHT_ROW); minrow = max(minrow, FIGHT_ROW);
enemies = count_enemies(b, as, minrow, maxrow, advance); enemies = count_enemies(b, af, minrow, maxrow, select);
/* Niemand ist in der angegebenen Entfernung? */ /* Niemand ist in der angegebenen Entfernung? */
if (enemies<=0) return no_troop; if (enemies<=0) return no_troop;
@ -1259,8 +1281,11 @@ select_enemy(fighter * af, int minrow, int maxrow, boolean advance)
side *ds = as->enemies[si]; side *ds = as->enemies[si];
fighter * df; fighter * df;
int unitrow[NUMROWS]; int unitrow[NUMROWS];
int offset = 0;
if (advance) { if (select&SELECT_DISTANCE) offset = get_unitrow(af, ds) - FIGHT_ROW;
if (select&SELECT_ADVANCE) {
int ui; int ui;
for (ui=0;ui!=NUMROWS;++ui) unitrow[ui] = -1; for (ui=0;ui!=NUMROWS;++ui) unitrow[ui] = -1;
} }
@ -1269,13 +1294,14 @@ select_enemy(fighter * af, int minrow, int maxrow, boolean advance)
int dr; int dr;
dr = statusrow(df->status); dr = statusrow(df->status);
if (advance) { if (select&SELECT_ADVANCE) {
if (unitrow[dr]<0) { if (unitrow[dr]<0) {
unitrow[dr] = get_unitrow(df); unitrow[dr] = get_unitrow(df, as);
} }
dr = unitrow[dr]; dr = unitrow[dr];
} }
if (select&SELECT_DISTANCE) dr += offset;
if (dr < minrow || dr > maxrow) continue; if (dr < minrow || dr > maxrow) continue;
if (df->alive - df->removed > enemies) { if (df->alive - df->removed > enemies) {
troop dt; troop dt;
@ -1291,7 +1317,7 @@ select_enemy(fighter * af, int minrow, int maxrow, boolean advance)
} }
static troop static troop
select_opponent(battle * b, troop at, int minrow, int maxrow) select_opponent(battle * b, troop at, int mindist, int maxdist)
{ {
fighter * af = at.fighter; fighter * af = at.fighter;
troop dt; troop dt;
@ -1299,12 +1325,11 @@ select_opponent(battle * b, troop at, int minrow, int maxrow)
if (af->unit->race->flags & RCF_FLY) { if (af->unit->race->flags & RCF_FLY) {
/* flying races ignore min- and maxrow and can attack anyone fighting /* flying races ignore min- and maxrow and can attack anyone fighting
* them */ * them */
minrow = FIGHT_ROW; dt = select_enemy(at.fighter, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
maxrow = BEHIND_ROW; } else {
mindist = max(mindist, FIGHT_ROW);
dt = select_enemy(at.fighter, mindist, maxdist, SELECT_ADVANCE);
} }
minrow = max(minrow, FIGHT_ROW);
dt = select_enemy(at.fighter, minrow, maxrow, true);
return dt; return dt;
} }
@ -1327,24 +1352,25 @@ select_opponent(battle * b, troop at, int minrow, int maxrow)
*/ */
cvector * cvector *
fighters(battle *b, fighter *af, int minrow, int maxrow, int mask) fighters(battle *b, const side * vs, int minrow, int maxrow, int mask)
{ {
side * s; side * s;
cvector *fightervp = malloc(sizeof(cvector)); cvector *fightervp = malloc(sizeof(cvector));
assert(vs!=NULL);
cv_init(fightervp); cv_init(fightervp);
for (s = b->sides; s; s = s->next) { for (s = b->sides; s; s = s->next) {
fighter *fig; fighter *fig;
for (fig = s->fighters; fig; fig = fig->next) { for (fig = s->fighters; fig; fig = fig->next) {
int row = get_unitrow(fig); int row = get_unitrow(fig, vs);
if (row >= minrow && row <= maxrow) { if (row >= minrow && row <= maxrow) {
switch (mask) { switch (mask) {
case FS_ENEMY: case FS_ENEMY:
if (enemy(fig->side, af->side)) cv_pushback(fightervp, fig); if (enemy(fig->side, vs)) cv_pushback(fightervp, fig);
break; break;
case FS_HELP: case FS_HELP:
if (!enemy(fig->side, af->side) && allysf(fig->side, af->side->bf->faction)) if (!enemy(fig->side, vs) && allysf(fig->side, vs->bf->faction))
cv_pushback(fightervp, fig); cv_pushback(fightervp, fig);
break; break;
case FS_HELP|FS_ENEMY: case FS_HELP|FS_ENEMY:
@ -1470,7 +1496,7 @@ do_combatmagic(battle *b, combatmagic_t was)
static void static void
do_combatspell(troop at, int row) do_combatspell(troop at)
{ {
const spell *sp; const spell *sp;
fighter *fi = at.fighter; fighter *fi = at.fighter;
@ -1486,8 +1512,6 @@ do_combatspell(troop at, int row)
char cmd[128]; char cmd[128];
const struct locale * lang = mage->faction->locale; const struct locale * lang = mage->faction->locale;
if (row>BEHIND_ROW) return;
sp = get_combatspell(mage, 1); sp = get_combatspell(mage, 1);
if (sp == NULL) { if (sp == NULL) {
fi->magic = 0; /* Hat keinen Kampfzauber, kämpft nichtmagisch weiter */ fi->magic = 0; /* Hat keinen Kampfzauber, kämpft nichtmagisch weiter */
@ -1733,7 +1757,7 @@ hits(troop at, troop dt, weapon * awp)
char debugbuf[512]; char debugbuf[512];
const armor_type * armor, * shield; const armor_type * armor, * shield;
int skdiff = 0; int skdiff = 0;
int dist = get_unitrow(af) + get_unitrow(df) - 1; int dist = get_unitrow(af, df->side) + get_unitrow(df, af->side) - 1;
weapon * dwp = select_weapon(dt, false, dist>1); weapon * dwp = select_weapon(dt, false, dist>1);
if (!df->alive) return 0; if (!df->alive) return 0;
@ -1918,22 +1942,26 @@ attack(battle *b, troop ta, const att *a, int numattack)
fighter *af = ta.fighter; fighter *af = ta.fighter;
troop td; troop td;
unit *au = af->unit; unit *au = af->unit;
int row = get_unitrow(af);
int offset = row - FIGHT_ROW;
switch(a->type) { switch(a->type) {
case AT_COMBATSPELL: case AT_COMBATSPELL:
/* Magier versuchen immer erstmal zu zaubern, erst wenn das
* fehlschlägt, wird af->magic == 0 und der Magier kämpft
* konventionell weiter */
if (numattack==0 && af->magic > 0) { if (numattack==0 && af->magic > 0) {
/* Magier versuchen immer erstmal zu zaubern, erst wenn das /* wenn der magier in die potenzielle Reichweite von Attacken des
* fehlschlägt, wird af->magic == 0 und der Magier kämpft * Feindes kommt, beginnt er auch bei einem Status von KAEMPFE NICHT,
* konventionell weiter */ * Kampfzauber zu schleudern: */
do_combatspell(ta, row); if (count_enemies(b, af, melee_range[0], missile_range[1], SELECT_ADVANCE|SELECT_DISTANCE|SELECT_FIND)) {
do_combatspell(ta);
}
} }
break; break;
case AT_STANDARD: /* Waffen, mag. Gegenstände, Kampfzauber */ case AT_STANDARD: /* Waffen, mag. Gegenstände, Kampfzauber */
if (numattack > 0 || af->magic <= 0) { if (numattack > 0 || af->magic <= 0) {
weapon * wp = ta.fighter->person[ta.index].missile; weapon * wp = ta.fighter->person[ta.index].missile;
if (row==FIGHT_ROW) wp = preferred_weapon(ta, true); int melee = count_enemies(b, af, melee_range[0], melee_range[1], SELECT_ADVANCE|SELECT_DISTANCE|SELECT_FIND);
if (melee) wp = preferred_weapon(ta, true);
/* Sonderbehandlungen */ /* Sonderbehandlungen */
if (getreload(ta)) { if (getreload(ta)) {
@ -1945,7 +1973,7 @@ attack(battle *b, troop ta, const att *a, int numattack)
* sonst helden mit feuerschwertern zu mächtig */ * sonst helden mit feuerschwertern zu mächtig */
if (numattack==0 && wp && wp->type->attack) { if (numattack==0 && wp && wp->type->attack) {
int dead = 0; int dead = 0;
standard_attack = wp->type->attack(&ta, wp->type, &dead, row); standard_attack = wp->type->attack(&ta, wp->type, &dead);
if (!standard_attack) reload = true; if (!standard_attack) reload = true;
af->catmsg += dead; af->catmsg += dead;
if (!standard_attack && af->person[ta.index].last_action < b->turn) { if (!standard_attack && af->person[ta.index].last_action < b->turn) {
@ -1958,14 +1986,12 @@ attack(battle *b, troop ta, const att *a, int numattack)
} }
if (standard_attack) { if (standard_attack) {
boolean missile = false; boolean missile = false;
if (wp && fval(wp->type, WTF_MISSILE)) missile=true; if (wp && fval(wp->type, WTF_MISSILE)) missile = true;
if (missile) { if (missile) {
if (row<=BEHIND_ROW) td = select_opponent(b, ta, missile_range[0], missile_range[1]); td = select_opponent(b, ta, missile_range[0], missile_range[1]);
else return;
} }
else { else {
if (row<=FIGHT_ROW) td = select_opponent(b, ta, melee_range[0], melee_range[1]); td = select_opponent(b, ta, melee_range[0], melee_range[1]);
else return;
} }
if (!td.fighter) return; if (!td.fighter) return;
#ifdef COUNT_DF #ifdef COUNT_DF
@ -2005,7 +2031,7 @@ attack(battle *b, troop ta, const att *a, int numattack)
do_extra_spell(ta, a); do_extra_spell(ta, a);
break; break;
case AT_NATURAL: case AT_NATURAL:
td = select_opponent(b, ta, melee_range[0]-offset, melee_range[1]-offset); td = select_opponent(b, ta, melee_range[0], melee_range[1]);
if (!td.fighter) return; if (!td.fighter) return;
#ifdef COUNT_DF #ifdef COUNT_DF
if(td.fighter->person[td.index].last_action < b->turn) { if(td.fighter->person[td.index].last_action < b->turn) {
@ -2028,7 +2054,7 @@ attack(battle *b, troop ta, const att *a, int numattack)
} }
break; break;
case AT_DRAIN_ST: case AT_DRAIN_ST:
td = select_opponent(b, ta, melee_range[0]-offset, melee_range[1]-offset); td = select_opponent(b, ta, melee_range[0], melee_range[1]);
if (!td.fighter) return; if (!td.fighter) return;
#ifdef COUNT_DF #ifdef COUNT_DF
if(td.fighter->person[td.index].last_action < b->turn) { if(td.fighter->person[td.index].last_action < b->turn) {
@ -2059,7 +2085,7 @@ attack(battle *b, troop ta, const att *a, int numattack)
} }
break; break;
case AT_DRAIN_EXP: case AT_DRAIN_EXP:
td = select_opponent(b, ta, melee_range[0]-offset, melee_range[1]-offset); td = select_opponent(b, ta, melee_range[0], melee_range[1]);
if (!td.fighter) return; if (!td.fighter) return;
#ifdef COUNT_DF #ifdef COUNT_DF
if(td.fighter->person[td.index].last_action < b->turn) { if(td.fighter->person[td.index].last_action < b->turn) {
@ -2082,7 +2108,7 @@ attack(battle *b, troop ta, const att *a, int numattack)
} }
break; break;
case AT_DAZZLE: case AT_DAZZLE:
td = select_opponent(b, ta, melee_range[0]-offset, melee_range[1]-offset); td = select_opponent(b, ta, melee_range[0], melee_range[1]);
if (!td.fighter) return; if (!td.fighter) return;
#ifdef COUNT_DF #ifdef COUNT_DF
if(td.fighter->person[td.index].last_action < b->turn) { if(td.fighter->person[td.index].last_action < b->turn) {
@ -2105,7 +2131,7 @@ attack(battle *b, troop ta, const att *a, int numattack)
} }
break; break;
case AT_STRUCTURAL: case AT_STRUCTURAL:
td = select_opponent(b, ta, melee_range[0]-offset, melee_range[1]-offset); td = select_opponent(b, ta, melee_range[0], melee_range[1]);
if (!td.fighter) return; if (!td.fighter) return;
if(ta.fighter->person[ta.index].last_action < b->turn) { if(ta.fighter->person[ta.index].last_action < b->turn) {
ta.fighter->person[ta.index].last_action = b->turn; ta.fighter->person[ta.index].last_action = b->turn;
@ -2143,9 +2169,8 @@ do_attack(fighter * af)
while (ta.index--) { while (ta.index--) {
/* Wir suchen eine beliebige Feind-Einheit aus. An der können /* Wir suchen eine beliebige Feind-Einheit aus. An der können
* wir feststellen, ob noch jemand da ist. */ * wir feststellen, ob noch jemand da ist. */
int enemies = count_enemies(b, af->side, FIGHT_ROW, LAST_ROW, true);
int apr, attacks = attacks_per_round(ta); int apr, attacks = attacks_per_round(ta);
if (!enemies) break; if (!count_enemies(b, af, FIGHT_ROW, LAST_ROW, SELECT_FIND)) break;
for (apr=0;apr!=attacks;++apr) { for (apr=0;apr!=attacks;++apr) {
int a; int a;
@ -2285,7 +2310,7 @@ loot_items(fighter * corpse)
itm->number -= loot; itm->number -= loot;
if (maxrow == LAST_ROW || rng_int() % 100 < lootchance) { if (maxrow == LAST_ROW || rng_int() % 100 < lootchance) {
fighter *fig = select_enemy(corpse, FIGHT_ROW, maxrow, false).fighter; fighter *fig = select_enemy(corpse, FIGHT_ROW, maxrow, 0).fighter;
if (fig) { if (fig) {
item * l = fig->loot; item * l = fig->loot;
while (l && l->type!=itm->type) l=l->next; while (l && l->type!=itm->type) l=l->next;
@ -2655,7 +2680,6 @@ print_fighters(battle * b, const side * s)
int row; int row;
for (row=1;row!=NUMROWS;++row) { for (row=1;row!=NUMROWS;++row) {
int unitrow = get_row(s, row);
message * m = NULL; message * m = NULL;
for (df=s->fighters; df; df=df->next) { for (df=s->fighters; df; df=df->next) {
@ -2664,7 +2688,7 @@ print_fighters(battle * b, const side * s)
if (row == thisrow) { if (row == thisrow) {
if (m==NULL) { if (m==NULL) {
m = msg_message("battle::row_header", "row", unitrow); m = msg_message("battle::row_header", "row", row);
message_all(b, m); message_all(b, m);
} }
battle_punit(du, b); battle_punit(du, b);
@ -2765,13 +2789,30 @@ print_stats(battle * b)
} }
if (komma) fbattlerecord(b, f, buf); if (komma) fbattlerecord(b, f, buf);
bufp = buf;
size = sizeof(buf);
komma = 0;
header = LOC(f->locale, "battle_helpers");
for (s2=b->sides;s2;s2=s2->next) {
if (friendly(s2, s)) {
const char * abbrev = seematrix(f, s2)?sideabkz(s2, false):"-?-";
rsize = slprintf(bufp, size, "%s %s %d(%s)",
komma++ ? "," : header, loc_army, army_index(s2), abbrev);
if (rsize>size) rsize = size-1;
size -= rsize;
bufp += rsize;
}
}
if (komma) fbattlerecord(b, f, buf);
bufp = buf; bufp = buf;
size = sizeof(buf); size = sizeof(buf);
komma = 0; komma = 0;
header = LOC(f->locale, "battle_attack"); header = LOC(f->locale, "battle_attack");
for (s2=b->sides;s2;s2=s2->next) { for (s2=b->sides;s2;s2=s2->next) {
if (s->enemy[s2->index] & E_ATTACKING) { if (s->relations[s2->index] & E_ATTACKING) {
const char * abbrev = seematrix(f, s2)?sideabkz(s2, false):"-?-"; const char * abbrev = seematrix(f, s2)?sideabkz(s2, false):"-?-";
rsize = slprintf(bufp, size, "%s %s %d(%s)", komma++ ? "," : header, loc_army, rsize = slprintf(bufp, size, "%s %s %d(%s)", komma++ ? "," : header, loc_army,
army_index(s2), abbrev); army_index(s2), abbrev);
@ -3312,18 +3353,21 @@ free_battle(battle * b)
} }
static int * static int *
get_alive(battle * b, side * s, faction * f, boolean see) get_alive(side * s)
{ {
#if 0
static int alive[NUMROWS]; static int alive[NUMROWS];
fighter *fig; fighter *fig;
memset(alive, 0, NUMROWS * sizeof(int)); memset(alive, 0, NUMROWS * sizeof(int));
for (fig=s->fighters;fig;fig=fig->next) { for (fig=s->fighters;fig;fig=fig->next) {
if (fig->alive && seematrix(f, s)==see) { if (fig->alive>0) {
int row = get_unitrow(fig); int row = statusrow(fig);
alive[row] += fig->alive; alive[row] += fig->alive;
} }
} }
return alive; return alive;
#endif
return s->size;
} }
static int static int
@ -3365,7 +3409,7 @@ battle_report(battle * b)
komma = false; komma = false;
for (s=b->sides; s; s=s->next) { for (s=b->sides; s; s=s->next) {
if (s->alive) { if (s->alive) {
int r, k = 0, * alive = get_alive(b, s, fac, seematrix(fac, s)); int r, k = 0, * alive = get_alive(s);
int l = FIGHT_ROW; int l = FIGHT_ROW;
const char * abbrev = seematrix(fac, s)?sideabkz(s, false):"-?-"; const char * abbrev = seematrix(fac, s)?sideabkz(s, false):"-?-";
const char * loc_army = LOC(fac->locale, "battle_army"); const char * loc_army = LOC(fac->locale, "battle_army");
@ -3423,9 +3467,9 @@ battle_report(battle * b)
static void static void
join_allies(battle * b) join_allies(battle * b)
{ {
region * r = b->region; region *r = b->region;
unit * u; unit *u;
side * sbegin = b->sides; side *s, *sbegin = b->sides;
/* make_side might be adding a new faciton, but it adds them to the beginning /* make_side might be adding a new faciton, but it adds them to the beginning
* of the list, so we're safe in our iteration here if we remember b->sides * of the list, so we're safe in our iteration here if we remember b->sides
* up front. */ * up front. */
@ -3434,7 +3478,6 @@ join_allies(battle * b)
if (u->status != ST_FLEE && u->status != ST_AVOID && !fval(u, UFL_LONGACTION|UFL_ISNEW) && u->number > 0) { if (u->status != ST_FLEE && u->status != ST_AVOID && !fval(u, UFL_LONGACTION|UFL_ISNEW) && u->number > 0) {
faction * f = u->faction; faction * f = u->faction;
fighter * c = NULL; fighter * c = NULL;
side * s;
for (s = sbegin; s; s=s->next) { for (s = sbegin; s; s=s->next) {
side * se; side * se;
@ -3487,6 +3530,23 @@ join_allies(battle * b)
} }
} }
} }
for (s=sbegin;s;s=s->next) {
int si;
/* Den Feinden meiner Feinde gebe ich Deckung (gegen gemeinsame Feinde): */
for (si=0; s->enemies[si]; ++si) {
side * se = s->enemies[si];
int ai;
for (ai=0; se->enemies[ai]; ++ai) {
side * as = se->enemies[ai];
if (as!=s) {
if (!enemy(as, s)) {
set_friendly(as, s);
}
}
}
}
}
} }
static void static void

View File

@ -89,8 +89,9 @@ extern "C" {
const struct group * group; const struct group * group;
struct tactics leader; /* der beste Taktiker des Heeres */ struct tactics leader; /* der beste Taktiker des Heeres */
# define E_ENEMY 1 # define E_ENEMY 1
# define E_ATTACKING 2 # define E_FRIEND 2
unsigned char enemy[128]; # define E_ATTACKING 4
unsigned char relations[128];
struct side * enemies[128]; struct side * enemies[128];
struct fighter * fighters; struct fighter * fighters;
int index; /* Eintrag der Fraktion in b->matrix/b->enemies */ int index; /* Eintrag der Fraktion in b->matrix/b->enemies */
@ -208,8 +209,10 @@ extern "C" {
extern void do_battle(void); extern void do_battle(void);
/* for combar spells and special attacks */ /* for combar spells and special attacks */
extern troop select_enemy(struct fighter * af, int minrow, int maxrow, boolean advance); enum { SELECT_ADVANCE = 0x1, SELECT_DISTANCE = 0x2, SELECT_FIND = 0x4 };
extern int count_enemies(struct battle * b, struct side * as, int minrow, int maxrow, boolean advance);
extern troop select_enemy(struct fighter * af, int minrow, int maxrow, int select);
extern int count_enemies(struct battle * b, const struct fighter * af, int minrow, int maxrow, int select);
extern boolean terminate(troop dt, troop at, int type, const char *damage, boolean missile); extern boolean terminate(troop dt, troop at, int type, const char *damage, boolean missile);
extern void battlemsg(battle * b, struct unit * u, const char * s); extern void battlemsg(battle * b, struct unit * u, const char * s);
extern void battlerecord(battle * b, const char *s); extern void battlerecord(battle * b, const char *s);
@ -217,10 +220,10 @@ extern "C" {
extern void message_faction(battle * b, struct faction * f, struct message * m); extern void message_faction(battle * b, struct faction * f, struct message * m);
extern int hits(troop at, troop dt, weapon * awp); extern int hits(troop at, troop dt, weapon * awp);
extern void damage_building(struct battle *b, struct building *bldg, int damage_abs); extern void damage_building(struct battle *b, struct building *bldg, int damage_abs);
extern struct cvector * fighters(struct battle *b, struct fighter *af, int minrow, int maxrow, int mask); extern struct cvector * fighters(struct battle *b, const struct side * vs, int minrow, int maxrow, int mask);
extern int count_allies(struct side * as, int minrow, int maxrow, boolean advance); extern int count_allies(const struct side * as, int minrow, int maxrow, int select);
extern int get_unitrow(const struct fighter * af); extern int get_unitrow(const struct fighter * af, const struct side * vs);
extern boolean helping(struct side * as, struct side * ds); extern boolean helping(const struct side * as, const struct side * ds);
extern void rmfighter(fighter *df, int i); extern void rmfighter(fighter *df, int i);
extern struct region * fleeregion(const struct unit * u); extern struct region * fleeregion(const struct unit * u);
extern struct fighter * select_corpse(struct battle * b, struct fighter * af); extern struct fighter * select_corpse(struct battle * b, struct fighter * af);

View File

@ -1951,11 +1951,7 @@ create_unit(region * r, faction * f, int number, const struct race *urace, int i
else set_string(&u->name, dname); else set_string(&u->name, dname);
set_string(&u->display, ""); set_string(&u->display, "");
/* Nicht zu der Einheitenzahl zählen sollten auch alle Monster. Da if (count_unit(u)) f->no_units++;
* aber auf die MAXUNITS nur in MACHE TEMP geprüft wird, ist es egal */
if (playerrace(u->race)) {
f->no_units++;
}
if (creator) { if (creator) {
attrib * a; attrib * a;

View File

@ -207,7 +207,7 @@ typedef struct weapon_type {
int reload; /* time to reload this weapon */ int reload; /* time to reload this weapon */
weapon_mod * modifiers; weapon_mod * modifiers;
/* --- functions --- */ /* --- functions --- */
boolean (*attack)(const struct troop *, const struct weapon_type *, int *deaths, int row); boolean (*attack)(const struct troop *, const struct weapon_type *, int *deaths);
} weapon_type; } weapon_type;
extern void rt_register(resource_type * it); extern void rt_register(resource_type * it);

View File

@ -714,7 +714,7 @@ xml_readweapon(xmlXPathContextPtr xpath, item_type * itype)
} }
assert(property!=NULL); assert(property!=NULL);
if (strcmp((const char*)property, "attack")==0) { if (strcmp((const char*)property, "attack")==0) {
wtype->attack = (boolean (*)(const struct troop*, const struct weapon_type *, int*, int))fun; wtype->attack = (boolean (*)(const struct troop*, const struct weapon_type *, int*))fun;
} else { } else {
log_error(("unknown function type '%s' for item '%s'\n", log_error(("unknown function type '%s' for item '%s'\n",
(const char*)property, itype->rtype->_name[0])); (const char*)property, itype->rtype->_name[0]));
@ -1144,16 +1144,16 @@ add_skills(equipment * eq, xmlNodeSetPtr nsetSkills)
} }
static void static void
add_subsets(xmlDocPtr doc, equipment * eq, xmlNodeSetPtr nsetSkills) add_subsets(xmlDocPtr doc, equipment * eq, xmlNodeSetPtr nsetSubsets)
{ {
xmlXPathContextPtr xpath = xmlXPathNewContext(doc); xmlXPathContextPtr xpath = xmlXPathNewContext(doc);
if (nsetSkills!=NULL && nsetSkills->nodeNr>0) { if (nsetSubsets!=NULL && nsetSubsets->nodeNr>0) {
int i; int i;
eq->subsets = calloc(nsetSkills->nodeNr+1, sizeof(subset)); eq->subsets = calloc(nsetSubsets->nodeNr+1, sizeof(subset));
for (i=0;i!=nsetSkills->nodeNr;++i) { for (i=0;i!=nsetSubsets->nodeNr;++i) {
xmlXPathObjectPtr xpathResult; xmlXPathObjectPtr xpathResult;
xmlNodePtr node = nsetSkills->nodeTab[i]; xmlNodePtr node = nsetSubsets->nodeTab[i];
xmlChar * property; xmlChar * property;
eq->subsets[i].chance = 1.0f; eq->subsets[i].chance = 1.0f;

View File

@ -111,8 +111,6 @@ sp_kampfzauber(fighter * fi, int level, double power, spell * sp)
troop at, dt; troop at, dt;
message * m; message * m;
/* Immer aus der ersten Reihe nehmen */ /* Immer aus der ersten Reihe nehmen */
int minrow = FIGHT_ROW;
int maxrow = BEHIND_ROW-1;
int force, enemies; int force, enemies;
int killed = 0; int killed = 0;
const char *damage; const char *damage;
@ -143,7 +141,7 @@ sp_kampfzauber(fighter * fi, int level, double power, spell * sp)
sprintf(buf, "%s zaubert %s", unitname(fi->unit), sprintf(buf, "%s zaubert %s", unitname(fi->unit),
spell_name(sp, default_locale)); spell_name(sp, default_locale));
enemies = count_enemies(b, fi->side, minrow, maxrow, true); enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE);
if (enemies==0) { if (enemies==0) {
m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp);
message_all(b, m); message_all(b, m);
@ -152,7 +150,7 @@ sp_kampfzauber(fighter * fi, int level, double power, spell * sp)
} }
while (force>0 && killed < enemies) { while (force>0 && killed < enemies) {
dt = select_enemy(fi, minrow, maxrow, true); dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE);
assert(dt.fighter); assert(dt.fighter);
--force; --force;
killed += terminate(dt, at, AT_COMBATSPELL, damage, false); killed += terminate(dt, at, AT_COMBATSPELL, damage, false);
@ -173,8 +171,6 @@ sp_versteinern(fighter * fi, int level, double power, spell * sp)
battle *b = fi->side->battle; battle *b = fi->side->battle;
unit *mage = fi->unit; unit *mage = fi->unit;
/* Wirkt auf erste und zweite Reihe */ /* Wirkt auf erste und zweite Reihe */
int minrow = FIGHT_ROW;
int maxrow = BEHIND_ROW;
int force, enemies; int force, enemies;
int stoned = 0; int stoned = 0;
@ -183,7 +179,7 @@ sp_versteinern(fighter * fi, int level, double power, spell * sp)
force = lovar(get_force(power, 0)); force = lovar(get_force(power, 0));
enemies = count_enemies(b, fi->side, minrow, maxrow, true); enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
if (!enemies) { if (!enemies) {
scat(", aber niemand war in Reichweite."); scat(", aber niemand war in Reichweite.");
battlerecord(b, buf); battlerecord(b, buf);
@ -193,7 +189,7 @@ sp_versteinern(fighter * fi, int level, double power, spell * sp)
battlerecord(b, buf); battlerecord(b, buf);
while (force && stoned < enemies) { while (force && stoned < enemies) {
troop dt = select_enemy(fi, minrow, maxrow, true); troop dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
fighter * df = dt.fighter; fighter * df = dt.fighter;
unit * du = df->unit; unit * du = df->unit;
if (is_magic_resistant(mage, du, 0) == false) { if (is_magic_resistant(mage, du, 0) == false) {
@ -222,8 +218,6 @@ sp_stun(fighter * fi, int level, double power, spell * sp)
unit *mage = fi->unit; unit *mage = fi->unit;
troop at; troop at;
/* Aus beiden Reihen nehmen */ /* Aus beiden Reihen nehmen */
int minrow = FIGHT_ROW;
int maxrow = BEHIND_ROW;
int force=0, enemies; int force=0, enemies;
int stunned; int stunned;
at.fighter = fi; at.fighter = fi;
@ -242,7 +236,7 @@ sp_stun(fighter * fi, int level, double power, spell * sp)
assert(0); assert(0);
} }
enemies = count_enemies(b, fi->side, minrow, maxrow, true); enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
if (!enemies) { if (!enemies) {
scat(", aber niemand war in Reichweite."); scat(", aber niemand war in Reichweite.");
battlerecord(b, buf); battlerecord(b, buf);
@ -253,7 +247,7 @@ sp_stun(fighter * fi, int level, double power, spell * sp)
stunned = 0; stunned = 0;
while (force && stunned < enemies) { while (force && stunned < enemies) {
troop dt = select_enemy(fi, minrow, maxrow, true); troop dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
fighter * df = dt.fighter; fighter * df = dt.fighter;
unit * du = df->unit; unit * du = df->unit;
@ -284,11 +278,9 @@ sp_combatrosthauch(fighter * fi, int level, double power, spell * sp)
battle *b = fi->side->battle; battle *b = fi->side->battle;
cvector *fgs; cvector *fgs;
void **fig; void **fig;
int force, enemies; int force;
int k = 0; int k = 0;
/* Immer aus der ersten Reihe nehmen */ /* Immer aus der ersten Reihe nehmen */
int minrow = FIGHT_ROW;
int maxrow = BEHIND_ROW-1;
static const char * msgt[] = { static const char * msgt[] = {
"ruft ein fürchterliches Unwetter über seine Feinde, doch es gab niemanden mehr, den dies treffen konnte.", "ruft ein fürchterliches Unwetter über seine Feinde, doch es gab niemanden mehr, den dies treffen konnte.",
"ruft ein fürchterliches Unwetter über seine Feinde, doch der magische Regen zeigt keinen Effekt.", "ruft ein fürchterliches Unwetter über seine Feinde, doch der magische Regen zeigt keinen Effekt.",
@ -298,13 +290,12 @@ sp_combatrosthauch(fighter * fi, int level, double power, spell * sp)
force = lovar(power * 15); force = lovar(power * 15);
enemies = count_enemies(b, fi->side, minrow, maxrow, true); if (!count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE|SELECT_FIND)) {
if (!enemies) {
battlemsg(b, fi->unit, msgt[0]); battlemsg(b, fi->unit, msgt[0]);
return 0; return 0;
} }
fgs = fighters(b, fi, minrow, maxrow, FS_ENEMY); fgs = fighters(b, fi->side, FIGHT_ROW, BEHIND_ROW-1, FS_ENEMY);
v_scramble(fgs->begin, fgs->end); v_scramble(fgs->begin, fgs->end);
for (fig = fgs->begin; fig != fgs->end; ++fig) { for (fig = fgs->begin; fig != fgs->end; ++fig) {
@ -378,13 +369,11 @@ sp_sleep(fighter * fi, int level, double power, spell * sp)
int force, enemies; int force, enemies;
int k = 0; int k = 0;
/* Immer aus der ersten Reihe nehmen */ /* Immer aus der ersten Reihe nehmen */
int minrow = FIGHT_ROW;
int maxrow = BEHIND_ROW;
sprintf(buf, "%s zaubert %s", unitname(mage), sprintf(buf, "%s zaubert %s", unitname(mage),
spell_name(sp, default_locale)); spell_name(sp, default_locale));
force = lovar(power * 25); force = lovar(power * 25);
enemies = count_enemies(b, fi->side, minrow, maxrow, true); enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
if (!enemies) { if (!enemies) {
scat(", aber niemand war in Reichweite."); scat(", aber niemand war in Reichweite.");
@ -395,7 +384,7 @@ sp_sleep(fighter * fi, int level, double power, spell * sp)
battlerecord(b, buf); battlerecord(b, buf);
while (force && enemies) { while (force && enemies) {
dt = select_enemy(fi, minrow, maxrow, true); dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
assert(dt.fighter); assert(dt.fighter);
du = dt.fighter->unit; du = dt.fighter->unit;
if (is_magic_resistant(mage, du, 0) == false) { if (is_magic_resistant(mage, du, 0) == false) {
@ -419,7 +408,7 @@ select_ally(fighter * af, int minrow, int maxrow)
side *as = af->side; side *as = af->side;
battle *b = as->battle; battle *b = as->battle;
side * ds; side * ds;
int allies = count_allies(as, minrow, maxrow, true); int allies = count_allies(as, minrow, maxrow, SELECT_ADVANCE);
if (!allies) { if (!allies) {
return no_troop; return no_troop;
@ -430,7 +419,7 @@ select_ally(fighter * af, int minrow, int maxrow)
if (helping(as, ds)) { if (helping(as, ds)) {
fighter * df; fighter * df;
for (df=ds->fighters; df; df=df->next) { for (df=ds->fighters; df; df=df->next) {
int dr = get_unitrow(df); int dr = get_unitrow(df, NULL);
if (dr >= minrow && dr <= maxrow) { if (dr >= minrow && dr <= maxrow) {
if (df->alive - df->removed > allies) { if (df->alive - df->removed > allies) {
troop dt; troop dt;
@ -453,9 +442,6 @@ sp_speed(fighter * fi, int level, double power, spell * sp)
{ {
battle *b = fi->side->battle; battle *b = fi->side->battle;
int force; int force;
/* Immer aus der ersten Reihe nehmen */
int minrow = FIGHT_ROW;
int maxrow = BEHIND_ROW;
int allies; int allies;
int targets = 0; int targets = 0;
@ -466,13 +452,13 @@ sp_speed(fighter * fi, int level, double power, spell * sp)
force = lovar(power * power * 5); force = lovar(power * power * 5);
allies = count_allies(fi->side, minrow, maxrow, true); allies = count_allies(fi->side, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
/* maximal 2*allies Versuche ein Opfer zu finden, ansonsten bestände /* maximal 2*allies Versuche ein Opfer zu finden, ansonsten bestände
* die Gefahr eine Endlosschleife*/ * die Gefahr eine Endlosschleife*/
allies *= 2; allies *= 2;
while (force && allies) { while (force && allies) {
troop dt = select_ally(fi, minrow, maxrow); troop dt = select_ally(fi, FIGHT_ROW, BEHIND_ROW);
fighter *df = dt.fighter; fighter *df = dt.fighter;
--allies; --allies;
@ -527,14 +513,12 @@ sp_mindblast(fighter * fi, int level, double power, spell * sp)
int killed = 0; int killed = 0;
int force, enemies; int force, enemies;
int k = 0; int k = 0;
int minrow = FIGHT_ROW;
int maxrow = BEHIND_ROW;
sprintf(buf, "%s zaubert %s", unitname(mage), sprintf(buf, "%s zaubert %s", unitname(mage),
spell_name(sp, default_locale)); spell_name(sp, default_locale));
force = lovar(power * 25); force = lovar(power * 25);
enemies = count_enemies(b, fi->side, minrow, maxrow, true); enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
if (!enemies) { if (!enemies) {
scat(", aber niemand war in Reichweite."); scat(", aber niemand war in Reichweite.");
battlerecord(b, buf); battlerecord(b, buf);
@ -544,7 +528,7 @@ sp_mindblast(fighter * fi, int level, double power, spell * sp)
battlerecord(b, buf); battlerecord(b, buf);
while (force && enemies) { while (force && enemies) {
dt = select_enemy(fi, minrow, maxrow, true); dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
assert(dt.fighter); assert(dt.fighter);
du = dt.fighter->unit; du = dt.fighter->unit;
if (humanoidrace(du->race) && !is_magic_resistant(mage, du, 0)) { if (humanoidrace(du->race) && !is_magic_resistant(mage, du, 0)) {
@ -590,9 +574,6 @@ sp_dragonodem(fighter * fi, int level, double power, spell * sp)
battle *b = fi->side->battle; battle *b = fi->side->battle;
troop dt; troop dt;
troop at; troop at;
/* Immer aus der ersten Reihe nehmen */
int minrow = FIGHT_ROW;
int maxrow = BEHIND_ROW-1;
int force, enemies; int force, enemies;
int killed = 0; int killed = 0;
const char *damage; const char *damage;
@ -604,7 +585,7 @@ sp_dragonodem(fighter * fi, int level, double power, spell * sp)
/* Jungdrache 3->54, Drache 6->216, Wyrm 12->864 Treffer */ /* Jungdrache 3->54, Drache 6->216, Wyrm 12->864 Treffer */
force = lovar(get_force(level,6)); force = lovar(get_force(level,6));
enemies = count_enemies(b, fi->side, minrow, maxrow, true); enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE);
if (!enemies) { if (!enemies) {
scat(", aber niemand war in Reichweite."); scat(", aber niemand war in Reichweite.");
@ -618,7 +599,7 @@ sp_dragonodem(fighter * fi, int level, double power, spell * sp)
at.index = 0; at.index = 0;
while (force && killed < enemies) { while (force && killed < enemies) {
dt = select_enemy(fi, minrow, maxrow, true); dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE);
assert(dt.fighter); assert(dt.fighter);
--force; --force;
killed += terminate(dt, at, AT_COMBATSPELL, damage, false); killed += terminate(dt, at, AT_COMBATSPELL, damage, false);
@ -639,9 +620,7 @@ sp_immolation(fighter * fi, int level, double power, spell * sp)
{ {
battle *b = fi->side->battle; battle *b = fi->side->battle;
troop at; troop at;
int minrow = FIGHT_ROW; int force;
int maxrow = AVOID_ROW;
int force, enemies;
int killed = 0; int killed = 0;
const char *damage; const char *damage;
cvector *fgs; cvector *fgs;
@ -654,9 +633,7 @@ sp_immolation(fighter * fi, int level, double power, spell * sp)
/* Betrifft alle Gegner */ /* Betrifft alle Gegner */
force = 99999; force = 99999;
enemies = count_enemies(b, fi->side, minrow, maxrow, true); if (!count_enemies(b, fi, FIGHT_ROW, AVOID_ROW, SELECT_ADVANCE|SELECT_FIND)) {
if (!enemies) {
scat(", aber niemand war in Reichweite."); scat(", aber niemand war in Reichweite.");
battlerecord(b, buf); battlerecord(b, buf);
return 0; return 0;
@ -667,7 +644,7 @@ sp_immolation(fighter * fi, int level, double power, spell * sp)
at.fighter = fi; at.fighter = fi;
at.index = 0; at.index = 0;
fgs = fighters(b, fi, minrow, maxrow, FS_ENEMY); fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_ENEMY);
for (fig = fgs->begin; fig != fgs->end; ++fig) { for (fig = fgs->begin; fig != fgs->end; ++fig) {
fighter *df = *fig; fighter *df = *fig;
int n = df->alive-df->removed; int n = df->alive-df->removed;
@ -698,9 +675,6 @@ sp_drainodem(fighter * fi, int level, double power, spell * sp)
battle *b = fi->side->battle; battle *b = fi->side->battle;
troop dt; troop dt;
troop at; troop at;
/* Immer aus der ersten Reihe nehmen */
int minrow = FIGHT_ROW;
int maxrow = BEHIND_ROW-1;
int force, enemies; int force, enemies;
int drained = 0; int drained = 0;
int killed = 0; int killed = 0;
@ -713,7 +687,7 @@ sp_drainodem(fighter * fi, int level, double power, spell * sp)
/* Jungdrache 3->54, Drache 6->216, Wyrm 12->864 Treffer */ /* Jungdrache 3->54, Drache 6->216, Wyrm 12->864 Treffer */
force = lovar(get_force(level,6)); force = lovar(get_force(level,6));
enemies = count_enemies(b, fi->side, minrow, maxrow, true); enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE);
if (!enemies) { if (!enemies) {
scat(", aber niemand war in Reichweite."); scat(", aber niemand war in Reichweite.");
@ -727,7 +701,7 @@ sp_drainodem(fighter * fi, int level, double power, spell * sp)
at.index = 0; at.index = 0;
while (force && drained < enemies) { while (force && drained < enemies) {
dt = select_enemy(fi, minrow, maxrow, true); dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE);
assert(dt.fighter); assert(dt.fighter);
if (hits(at, dt, NULL)) { if (hits(at, dt, NULL)) {
drain_exp(dt.fighter->unit, 90); drain_exp(dt.fighter->unit, 90);
@ -887,10 +861,7 @@ sp_chaosrow(fighter * fi, int level, double power, spell * sp)
unit *mage = fi->unit; unit *mage = fi->unit;
cvector *fgs; cvector *fgs;
void **fig; void **fig;
int enemies;
int k = 0; int k = 0;
int minrow = FIGHT_ROW;
int maxrow = NUMROWS;
switch (sp->id) { switch (sp->id) {
case SPL_CHAOSROW: case SPL_CHAOSROW:
@ -904,15 +875,14 @@ sp_chaosrow(fighter * fi, int level, double power, spell * sp)
break; break;
} }
enemies = count_enemies(b, fi->side, minrow, maxrow, true); if (!count_enemies(b, fi, FIGHT_ROW, NUMROWS, SELECT_ADVANCE|SELECT_FIND)) {
if (!enemies) {
scat(", aber niemand war in Reichweite."); scat(", aber niemand war in Reichweite.");
battlerecord(b, buf); battlerecord(b, buf);
return 0; return 0;
} }
scat(". "); scat(". ");
fgs = fighters(b, fi, minrow, maxrow, FS_ENEMY); fgs = fighters(b, fi->side, FIGHT_ROW, NUMROWS, FS_ENEMY);
v_scramble(fgs->begin, fgs->end); v_scramble(fgs->begin, fgs->end);
for (fig = fgs->begin; fig != fgs->end; ++fig) { for (fig = fgs->begin; fig != fgs->end; ++fig) {
@ -980,8 +950,6 @@ sp_flee(fighter * fi, int level, double power, spell * sp)
unit *mage = fi->unit; unit *mage = fi->unit;
cvector *fgs; cvector *fgs;
void **fig; void **fig;
int minrow = FIGHT_ROW;
int maxrow = AVOID_ROW;
int force, n; int force, n;
int panik = 0; int panik = 0;
@ -1003,7 +971,7 @@ sp_flee(fighter * fi, int level, double power, spell * sp)
force = (int)get_force(power,10); force = (int)get_force(power,10);
} }
if (!count_enemies(b, fi->side, minrow, maxrow, true)) { if (!count_enemies(b, fi, FIGHT_ROW, AVOID_ROW, SELECT_ADVANCE|SELECT_FIND)) {
scat(", aber es gab niemanden mehr, der beeinflusst werden konnte."); scat(", aber es gab niemanden mehr, der beeinflusst werden konnte.");
battlerecord(b, buf); battlerecord(b, buf);
return 0; return 0;
@ -1011,7 +979,7 @@ sp_flee(fighter * fi, int level, double power, spell * sp)
scat(":"); scat(":");
battlerecord(b, buf); battlerecord(b, buf);
fgs = fighters(b, fi, minrow, maxrow, FS_ENEMY); fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_ENEMY);
v_scramble(fgs->begin, fgs->end); v_scramble(fgs->begin, fgs->end);
for (fig = fgs->begin; fig != fgs->end; ++fig) { for (fig = fgs->begin; fig != fgs->end; ++fig) {
@ -1051,9 +1019,6 @@ sp_hero(fighter * fi, int level, double power, spell * sp)
{ {
battle *b = fi->side->battle; battle *b = fi->side->battle;
unit *mage = fi->unit; unit *mage = fi->unit;
/* Immer aus der ersten Reihe nehmen */
int minrow = FIGHT_ROW;
int maxrow = BEHIND_ROW;
int df_bonus = 0; int df_bonus = 0;
int force = 0; int force = 0;
int allies; int allies;
@ -1074,13 +1039,13 @@ sp_hero(fighter * fi, int level, double power, spell * sp)
scat(":"); scat(":");
battlerecord(b, buf); battlerecord(b, buf);
allies = count_allies(fi->side, minrow, maxrow, true); allies = count_allies(fi->side, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
/* maximal 2*allies Versuche ein Opfer zu finden, ansonsten bestände /* maximal 2*allies Versuche ein Opfer zu finden, ansonsten bestände
* die Gefahr eine Endlosschleife*/ * die Gefahr eine Endlosschleife*/
allies *= 2; allies *= 2;
while (force && allies) { while (force && allies) {
troop dt = select_ally(fi, minrow, maxrow); troop dt = select_ally(fi, FIGHT_ROW, BEHIND_ROW);
fighter *df = dt.fighter; fighter *df = dt.fighter;
--allies; --allies;
@ -1107,9 +1072,6 @@ sp_berserk(fighter * fi, int level, double power, spell * sp)
{ {
battle *b = fi->side->battle; battle *b = fi->side->battle;
unit *mage = fi->unit; unit *mage = fi->unit;
/* Immer aus der ersten Reihe nehmen */
int minrow = FIGHT_ROW;
int maxrow = BEHIND_ROW-1;
int at_bonus = 0; int at_bonus = 0;
int df_malus = 0; int df_malus = 0;
int force = 0; int force = 0;
@ -1134,13 +1096,13 @@ sp_berserk(fighter * fi, int level, double power, spell * sp)
scat(":"); scat(":");
battlerecord(b, buf); battlerecord(b, buf);
allies = count_allies(fi->side, minrow, maxrow, true); allies = count_allies(fi->side, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE);
/* maximal 2*allies Versuche ein Opfer zu finden, ansonsten bestände /* maximal 2*allies Versuche ein Opfer zu finden, ansonsten bestände
* die Gefahr eine Endlosschleife*/ * die Gefahr eine Endlosschleife*/
allies *= 2; allies *= 2;
while (force && allies) { while (force && allies) {
troop dt = select_ally(fi, minrow, maxrow); troop dt = select_ally(fi, FIGHT_ROW, BEHIND_ROW-1);
fighter *df = dt.fighter; fighter *df = dt.fighter;
--allies; --allies;
@ -1168,9 +1130,6 @@ sp_frighten(fighter * fi, int level, double power, spell * sp)
{ {
battle *b = fi->side->battle; battle *b = fi->side->battle;
unit *mage = fi->unit; unit *mage = fi->unit;
/* Immer aus der ersten Reihe nehmen */
int minrow = FIGHT_ROW;
int maxrow = BEHIND_ROW-1;
int at_malus = 0; int at_malus = 0;
int df_malus = 0; int df_malus = 0;
int force = 0; int force = 0;
@ -1183,7 +1142,7 @@ sp_frighten(fighter * fi, int level, double power, spell * sp)
sprintf(buf, "%s zaubert %s", unitname(mage), sprintf(buf, "%s zaubert %s", unitname(mage),
spell_name(sp, default_locale)); spell_name(sp, default_locale));
enemies = count_enemies(b, fi->side, minrow, maxrow, true); enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE);
if (!enemies) { if (!enemies) {
scat(", aber niemand war in Reichweite."); scat(", aber niemand war in Reichweite.");
battlerecord(b, buf); battlerecord(b, buf);
@ -1193,7 +1152,7 @@ sp_frighten(fighter * fi, int level, double power, spell * sp)
battlerecord(b, buf); battlerecord(b, buf);
while (force && enemies) { while (force && enemies) {
troop dt = select_enemy(fi, minrow, maxrow, true); troop dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE);
fighter *df = dt.fighter; fighter *df = dt.fighter;
--enemies; --enemies;
@ -1232,14 +1191,14 @@ sp_tiredsoldiers(fighter * fi, int level, double power, spell * sp)
sprintf(buf, "%s zaubert %s", unitname(mage), sprintf(buf, "%s zaubert %s", unitname(mage),
spell_name(sp, default_locale)); spell_name(sp, default_locale));
if (!count_enemies(b, fi->side, FIGHT_ROW, BEHIND_ROW, true)) { if (!count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE|SELECT_FIND)) {
scat(", aber niemand war in Reichweite."); scat(", aber niemand war in Reichweite.");
battlerecord(b, buf); battlerecord(b, buf);
return 0; return 0;
} }
while (force) { while (force) {
troop t = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, true); troop t = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
fighter *df = t.fighter; fighter *df = t.fighter;
if (!df) if (!df)
@ -1276,9 +1235,6 @@ sp_windshield(fighter * fi, int level, double power, spell * sp)
unit *mage = fi->unit; unit *mage = fi->unit;
int force, at_malus; int force, at_malus;
int enemies; int enemies;
/* Immer aus der hinteren Reihe nehmen */
int minrow = BEHIND_ROW;
int maxrow = BEHIND_ROW;
sprintf(buf, "%s zaubert %s", unitname(mage), sprintf(buf, "%s zaubert %s", unitname(mage),
spell_name(sp, default_locale)); spell_name(sp, default_locale));
@ -1292,7 +1248,7 @@ sp_windshield(fighter * fi, int level, double power, spell * sp)
force = (int)power; force = (int)power;
at_malus = 2; at_malus = 2;
} }
enemies = count_enemies(b, fi->side, minrow, maxrow, true); enemies = count_enemies(b, fi, BEHIND_ROW, BEHIND_ROW, SELECT_ADVANCE);
if (!enemies) { if (!enemies) {
scat(", aber niemand war in Reichweite."); scat(", aber niemand war in Reichweite.");
battlerecord(b, buf); battlerecord(b, buf);
@ -1300,7 +1256,7 @@ sp_windshield(fighter * fi, int level, double power, spell * sp)
} }
while (force && enemies) { while (force && enemies) {
troop dt = select_enemy(fi, minrow, maxrow, true); troop dt = select_enemy(fi, BEHIND_ROW, BEHIND_ROW, SELECT_ADVANCE);
fighter *df = dt.fighter; fighter *df = dt.fighter;
--enemies; --enemies;
@ -1637,8 +1593,6 @@ sp_healing(fighter * fi, int level, double power, spell * sp)
{ {
battle *b = fi->side->battle; battle *b = fi->side->battle;
unit *mage = fi->unit; unit *mage = fi->unit;
int minrow = FIGHT_ROW;
int maxrow = AVOID_ROW;
int j = 0; int j = 0;
int healhp = (int)power; int healhp = (int)power;
cvector *fgs; cvector *fgs;
@ -1659,7 +1613,7 @@ sp_healing(fighter * fi, int level, double power, spell * sp)
/* gehe alle denen wir helfen der reihe nach durch, heile verwundete, /* gehe alle denen wir helfen der reihe nach durch, heile verwundete,
* bis zu verteilende HP aufgebraucht sind */ * bis zu verteilende HP aufgebraucht sind */
fgs = fighters(b, fi, minrow, maxrow, FS_HELP); fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_HELP);
v_scramble(fgs->begin, fgs->end); v_scramble(fgs->begin, fgs->end);
j += heal_fighters(fgs, &healhp, false); j += heal_fighters(fgs, &healhp, false);
j += heal_fighters(fgs, &healhp, true); j += heal_fighters(fgs, &healhp, true);
@ -1688,8 +1642,6 @@ sp_undeadhero(fighter * fi, int level, double power, spell * sp)
battle *b = fi->side->battle; battle *b = fi->side->battle;
unit *mage = fi->unit; unit *mage = fi->unit;
region *r = b->region; region *r = b->region;
int minrow = FIGHT_ROW;
int maxrow = AVOID_ROW;
cvector *fgs; cvector *fgs;
void **fig; void **fig;
int n, undead = 0; int n, undead = 0;
@ -1697,7 +1649,7 @@ sp_undeadhero(fighter * fi, int level, double power, spell * sp)
double c = 0.50 + 0.02 * power; double c = 0.50 + 0.02 * power;
/* Liste aus allen Kämpfern */ /* Liste aus allen Kämpfern */
fgs = fighters(b, fi, minrow, maxrow, FS_ENEMY | FS_HELP ); fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_ENEMY | FS_HELP );
v_scramble(fgs->begin, fgs->end); v_scramble(fgs->begin, fgs->end);
for (fig = fgs->begin; fig != fgs->end; ++fig) { for (fig = fgs->begin; fig != fgs->end; ++fig) {

View File

@ -283,7 +283,7 @@
</resource> </resource>
<resource name="catapult"> <resource name="catapult">
<item weight="4000"> <item weight="10000">
<construction skill="cartmaking" minskill="5" reqsize="1"> <construction skill="cartmaking" minskill="5" reqsize="1">
<requirement type="log" quantity="10"/> <requirement type="log" quantity="10"/>
</construction> </construction>