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.
This commit is contained in:
Enno Rehling 2002-10-04 21:25:16 +00:00
parent 12da2eeaef
commit 38e3799362
4 changed files with 68 additions and 48 deletions

View File

@ -177,7 +177,7 @@ attack_firesword(const troop * at, int *casualties, int row)
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) {
if (fi->person[i].weapon->type == oldweapontype[WP_FIRESWORD]) ++k; if (fi->person[i].melee->type == oldweapontype[WP_FIRESWORD]) ++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");
@ -206,7 +206,7 @@ attack_catapult(const troop * at, int * casualties, int row)
troop dt; troop dt;
int d = 0, n; int d = 0, n;
int minrow, maxrow; int minrow, maxrow;
weapon * wp = af->person[at->index].weapon; weapon * wp = af->person[at->index].missile;
assert(row>=FIGHT_ROW); assert(row>=FIGHT_ROW);
if (row>BEHIND_ROW) return false; /* keine weiteren attacken */ if (row>BEHIND_ROW) return false; /* keine weiteren attacken */
@ -224,7 +224,7 @@ attack_catapult(const troop * at, int * casualties, int row)
if (af->catmsg == -1) { if (af->catmsg == -1) {
int i, k=0; int i, k=0;
for (i=0;i<=at->index;++i) { for (i=0;i<=at->index;++i) {
if (af->person[i].reload==0 && af->person[i].weapon == wp) ++k; 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"); sprintf(buf, "%d Kämpfer aus %s feuer%s Katapult ab:", k, unitname(au), (k==1)?"t sein":"n ihr");
battlerecord(b, buf); battlerecord(b, buf);

View File

@ -635,13 +635,25 @@ select_weapon(const troop t, boolean attacking, boolean missile)
{ {
weapon * weapon = NULL; weapon * weapon = NULL;
/* Im Nahkampf: Verteidiger schalten auf eine Waffe, mit der das besser geht, um. */
if (!attacking && !missile) weapon = t.fighter->person[t.index].secondary; if (attacking) {
/* Wenn keine Nahkampfwaffe vorhanden, oder nicht Nahampf, dann die normale Waffe nehmen: */ if (!missile) {
if (weapon==NULL) weapon = t.fighter->person[t.index].weapon; /* try your best weapon if it's melee */
/* Wenn keine Waffe, dann NULL==waffenlos */ weapon = t.fighter->person[t.index].preferred;
if (weapon==NULL) return NULL; } else {
else return weapon; /* from the back rows, use your missile weapon */
weapon = t.fighter->person[t.index].missile;
}
} else {
if (!missile) {
/* have to use your melee weapon if it's melee */
weapon = t.fighter->person[t.index].melee;
} else {
/* from the back rows, use your best skill */
weapon = t.fighter->person[t.index].preferred;
}
}
return weapon;
} }
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
@ -725,9 +737,9 @@ weapon_effskill(troop t, troop enemy, const weapon * w, boolean attacking, boole
skill = weapon_skill(NULL, tu, attacking); skill = weapon_skill(NULL, tu, attacking);
} else { } else {
if (attacking) { if (attacking) {
skill = w->offskill; skill = w->attackskill;
} else { } else {
skill = missile?w->defmissile:w->defskill; skill = w->defenseskill;
} }
if (wtype->modifiers) { if (wtype->modifiers) {
/* Pferdebonus, Lanzenbonus, usw. */ /* Pferdebonus, Lanzenbonus, usw. */
@ -1694,7 +1706,7 @@ static int
setreload(troop at) setreload(troop at)
{ {
fighter * af = at.fighter; fighter * af = at.fighter;
const weapon_type * wtype = af->person[at.index].weapon->type; const weapon_type * wtype = af->person[at.index].missile->type;
if (wtype->reload == 0) return 0; if (wtype->reload == 0) return 0;
return af->person[at.index].reload = wtype->reload; return af->person[at.index].reload = wtype->reload;
} }
@ -1911,9 +1923,8 @@ attack(battle *b, troop ta, const att *a)
* konventionell weiter */ * konventionell weiter */
do_combatspell(ta, row); do_combatspell(ta, row);
} else { } else {
weapon * wp; weapon * wp = ta.fighter->person[ta.index].preferred;
if (row!=FIGHT_ROW) wp = ta.fighter->person[ta.index].missile;
wp = select_weapon(ta, true, true);
/* Sonderbehandlungen */ /* Sonderbehandlungen */
if (getreload(ta)) { if (getreload(ta)) {
@ -2680,7 +2691,15 @@ print_stats(battle * b)
} }
} next(side); } next(side);
} }
}
static int
weapon_weight(const weapon * w, boolean missile)
{
if (missile == i2b(fval(w->type, WTF_MISSILE))) {
return w->attackskill + w->defenseskill;
}
return 0;
} }
fighter * fighter *
@ -2821,11 +2840,8 @@ make_fighter(battle * b, unit * u, boolean attack)
for (itm=u->items;itm;itm=itm->next) { for (itm=u->items;itm;itm=itm->next) {
const weapon_type * wtype = resource2weapon(itm->type->rtype); const weapon_type * wtype = resource2weapon(itm->type->rtype);
if (wtype==NULL || itm->number==0) continue; if (wtype==NULL || itm->number==0) continue;
weapons[w].offskill = weapon_skill(wtype, u, true); weapons[w].attackskill = weapon_skill(wtype, u, true);
weapons[w].defskill = weapon_skill(wtype, u, false); weapons[w].defenseskill = weapon_skill(wtype, u, false);
weapons[w].defmissile = weapons[w].defskill;
/* Fernkämpfer haben im Nahkampf Talent/2 */
if (fval(wtype, WTF_MISSILE)) weapons[w].defskill/=2;
weapons[w].type = wtype; weapons[w].type = wtype;
weapons[w].used = 0; weapons[w].used = 0;
weapons[w].count = itm->number; weapons[w].count = itm->number;
@ -2837,12 +2853,12 @@ make_fighter(battle * b, unit * u, boolean attack)
for (i=0; i!=w; ++i) { for (i=0; i!=w; ++i) {
int j, o=0, d=0; int j, o=0, d=0;
for (j=0; j!=i; ++j) { for (j=0; j!=i; ++j) {
if (fig->weapons[j].defmissile>=fig->weapons[i].defmissile) ++d; if (weapon_weight(fig->weapons+j, true)>=weapon_weight(fig->weapons+i, true)) ++d;
if (fig->weapons[j].offskill>=fig->weapons[i].offskill) ++o; if (weapon_weight(fig->weapons+j, false)>=weapon_weight(fig->weapons+i, false)) ++o;
} }
for (j=i+1; j!=w; ++j) { for (j=i+1; j!=w; ++j) {
if (fig->weapons[j].defmissile>fig->weapons[i].defmissile) ++d; if (weapon_weight(fig->weapons+j, true)>weapon_weight(fig->weapons+i, true)) ++d;
if (fig->weapons[j].offskill>fig->weapons[i].offskill) ++o; if (weapon_weight(fig->weapons+j, false)>weapon_weight(fig->weapons+i, false)) ++o;
} }
owp[o] = i; owp[o] = i;
dwp[d] = i; dwp[d] = i;
@ -2851,31 +2867,34 @@ make_fighter(battle * b, unit * u, boolean attack)
* oi and di are the current index to the sorted owp/dwp arrays * oi and di are the current index to the sorted owp/dwp arrays
* owp, dwp contain indices to the figther::weapons array */ * owp, dwp contain indices to the figther::weapons array */
/* hand out offensive weapons: */ /* hand out melee weapons: */
for (i=0; i!=fig->alive; ++i) { for (i=0; i!=fig->alive; ++i) {
int wpless = weapon_skill(NULL, u, true); int wpless = weapon_skill(NULL, u, true);
while (oi!=w && fig->weapons[owp[oi]].used==fig->weapons[owp[oi]].count) { while (oi!=w && (fig->weapons[owp[oi]].used==fig->weapons[owp[oi]].count || fval(fig->weapons[owp[oi]].type, WTF_MISSILE))) {
++oi; ++oi;
} }
if (oi==w) break; /* no more weapons available */ if (oi==w) break; /* no more weapons available */
if (fig->weapons[owp[oi]].offskill<wpless) continue; /* we fight better with bare hands */ if (weapon_weight(fig->weapons+owp[oi], false)<=wpless) {
fig->person[i].weapon = &fig->weapons[owp[oi]]; continue; /* we fight better with bare hands */
if (fig->person[i].weapon->type->reload) {
fig->person[i].reload = rand() % fig->person[i].weapon->type->reload;
} }
fig->person[i].preferred = fig->person[i].melee = &fig->weapons[owp[oi]];
++fig->weapons[owp[oi]].used; ++fig->weapons[owp[oi]].used;
} }
/* hand out defensive weapons. No missiles, please. */ /* hand out missile weapons (from back to front, in case of mixed troops). */
for (di=0, i=0; i!=fig->alive; ++i) { for (di=0, i=fig->alive; i--!=0;) {
if (fig->person[i].weapon==NULL) continue; while (di!=w && (fig->weapons[dwp[di]].used==fig->weapons[dwp[di]].count || !fval(fig->weapons[dwp[di]].type, WTF_MISSILE))) {
while (di!=w && (fig->weapons[dwp[di]].used==fig->weapons[dwp[di]].count || fval(fig->weapons[dwp[di]].type, WTF_MISSILE))) {
++di; ++di;
} }
if (di==w) break; /* no more weapons available */ if (di==w) break; /* no more weapons available */
if (fig->weapons[dwp[di]].defmissile>fig->person[i].weapon->defmissile) { if (weapon_weight(fig->weapons+dwp[di], true)>0) {
fig->person[i].secondary = &fig->weapons[dwp[di]]; fig->person[i].missile = &fig->weapons[dwp[di]];
++fig->weapons[dwp[di]].used; ++fig->weapons[dwp[di]].used;
} }
if (fig->person[i].missile && (fig->person[i].melee==NULL ||
weapon_weight(fig->person[i].missile, true) >
weapon_weight(fig->person[i].melee, false))) {
fig->person[i].preferred = fig->person[i].missile;
}
} }
} }

View File

@ -96,9 +96,8 @@ typedef struct side {
typedef struct weapon { typedef struct weapon {
int count, used; int count, used;
const struct weapon_type * type; const struct weapon_type * type;
int offskill : 8; /* offense skill */ int attackskill : 8;
int defskill : 8; /* defense against melee attacks */ int defenseskill : 8;
int defmissile : 8; /* defense against missiles - not div. by 2 yet */
} weapon; } weapon;
/*** fighter::person::flags ***/ /*** fighter::person::flags ***/
@ -158,8 +157,9 @@ typedef struct fighter {
int reload : 4; /* Anzahl Runden, die die Waffe x noch laden muss. int reload : 4; /* Anzahl Runden, die die Waffe x noch laden muss.
* dahinter steckt ein array[RL_MAX] wenn er min. eine hat. */ * dahinter steckt ein array[RL_MAX] wenn er min. eine hat. */
int last_action : 8; /* In welcher Runde haben wir zuletzt etwas getan */ int last_action : 8; /* In welcher Runde haben wir zuletzt etwas getan */
struct weapon * weapon; /* offensive weapon */ struct weapon * preferred; /* weapon with best skill */
struct weapon * secondary; /* defensive weapon */ struct weapon * missile; /* missile weapon */
struct weapon * melee; /* melee weapon */
} * person; } * person;
int flags; int flags;
struct { struct {

View File

@ -334,15 +334,16 @@ sp_combatrosthauch(fighter * fi, int level, int power, spell * sp)
k +=n; k +=n;
i_change(&df->unit->items, wp->type->itype, -n); i_change(&df->unit->items, wp->type->itype, -n);
for (p=0;n && p!=df->unit->number;++p) { for (p=0;n && p!=df->unit->number;++p) {
if (df->person[p].weapon==wp) { if (df->person[p].missile==wp) {
df->person[p].weapon = df->person[p].secondary; df->person[p].preferred = df->person[p].melee;
df->person[p].secondary = NULL; df->person[p].missile = NULL;
--n; --n;
} }
} }
for (p=0;n && p!=df->unit->number;++p) { for (p=0;n && p!=df->unit->number;++p) {
if (df->person[p].secondary==wp) { if (df->person[p].melee==wp) {
df->person[p].secondary = NULL; df->person[p].preferred = df->person[p].missile;
df->person[p].melee = NULL;
--n; --n;
} }
} }
@ -1285,7 +1286,7 @@ sp_windshield(fighter * fi, int level, int power, spell * sp)
break; break;
assert(!helping(fi->side, df->side)); assert(!helping(fi->side, df->side));
if (df->person[dt.index].weapon && fval(df->person[dt.index].weapon->type, WTF_MISSILE)) { if (df->person[dt.index].preferred && df->person[dt.index].preferred==df->person[dt.index].missile) {
df->person[dt.index].attack -= at_malus; df->person[dt.index].attack -= at_malus;
--force; --force;
} }