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) {
int i, k=0;
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),
(k==1)?"t sein ":"en ihre",(k==1)?"":"er");
@ -206,7 +206,7 @@ attack_catapult(const troop * at, int * casualties, int row)
troop dt;
int d = 0, n;
int minrow, maxrow;
weapon * wp = af->person[at->index].weapon;
weapon * wp = af->person[at->index].missile;
assert(row>=FIGHT_ROW);
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) {
int i, k=0;
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");
battlerecord(b, buf);

View File

@ -635,13 +635,25 @@ select_weapon(const troop t, boolean attacking, boolean missile)
{
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;
/* Wenn keine Nahkampfwaffe vorhanden, oder nicht Nahampf, dann die normale Waffe nehmen: */
if (weapon==NULL) weapon = t.fighter->person[t.index].weapon;
/* Wenn keine Waffe, dann NULL==waffenlos */
if (weapon==NULL) return NULL;
else return weapon;
if (attacking) {
if (!missile) {
/* try your best weapon if it's melee */
weapon = t.fighter->person[t.index].preferred;
} else {
/* 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);
} else {
if (attacking) {
skill = w->offskill;
skill = w->attackskill;
} else {
skill = missile?w->defmissile:w->defskill;
skill = w->defenseskill;
}
if (wtype->modifiers) {
/* Pferdebonus, Lanzenbonus, usw. */
@ -1694,7 +1706,7 @@ static int
setreload(troop at)
{
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;
return af->person[at.index].reload = wtype->reload;
}
@ -1911,9 +1923,8 @@ attack(battle *b, troop ta, const att *a)
* konventionell weiter */
do_combatspell(ta, row);
} else {
weapon * wp;
wp = select_weapon(ta, true, true);
weapon * wp = ta.fighter->person[ta.index].preferred;
if (row!=FIGHT_ROW) wp = ta.fighter->person[ta.index].missile;
/* Sonderbehandlungen */
if (getreload(ta)) {
@ -2680,7 +2691,15 @@ print_stats(battle * b)
}
} 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 *
@ -2821,11 +2840,8 @@ make_fighter(battle * b, unit * u, boolean attack)
for (itm=u->items;itm;itm=itm->next) {
const weapon_type * wtype = resource2weapon(itm->type->rtype);
if (wtype==NULL || itm->number==0) continue;
weapons[w].offskill = weapon_skill(wtype, u, true);
weapons[w].defskill = 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].attackskill = weapon_skill(wtype, u, true);
weapons[w].defenseskill = weapon_skill(wtype, u, false);
weapons[w].type = wtype;
weapons[w].used = 0;
weapons[w].count = itm->number;
@ -2837,12 +2853,12 @@ make_fighter(battle * b, unit * u, boolean attack)
for (i=0; i!=w; ++i) {
int j, o=0, d=0;
for (j=0; j!=i; ++j) {
if (fig->weapons[j].defmissile>=fig->weapons[i].defmissile) ++d;
if (fig->weapons[j].offskill>=fig->weapons[i].offskill) ++o;
if (weapon_weight(fig->weapons+j, true)>=weapon_weight(fig->weapons+i, true)) ++d;
if (weapon_weight(fig->weapons+j, false)>=weapon_weight(fig->weapons+i, false)) ++o;
}
for (j=i+1; j!=w; ++j) {
if (fig->weapons[j].defmissile>fig->weapons[i].defmissile) ++d;
if (fig->weapons[j].offskill>fig->weapons[i].offskill) ++o;
if (weapon_weight(fig->weapons+j, true)>weapon_weight(fig->weapons+i, true)) ++d;
if (weapon_weight(fig->weapons+j, false)>weapon_weight(fig->weapons+i, false)) ++o;
}
owp[o] = 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
* owp, dwp contain indices to the figther::weapons array */
/* hand out offensive weapons: */
/* hand out melee weapons: */
for (i=0; i!=fig->alive; ++i) {
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;
}
if (oi==w) break; /* no more weapons available */
if (fig->weapons[owp[oi]].offskill<wpless) continue; /* we fight better with bare hands */
fig->person[i].weapon = &fig->weapons[owp[oi]];
if (fig->person[i].weapon->type->reload) {
fig->person[i].reload = rand() % fig->person[i].weapon->type->reload;
if (weapon_weight(fig->weapons+owp[oi], false)<=wpless) {
continue; /* we fight better with bare hands */
}
fig->person[i].preferred = fig->person[i].melee = &fig->weapons[owp[oi]];
++fig->weapons[owp[oi]].used;
}
/* hand out defensive weapons. No missiles, please. */
for (di=0, i=0; i!=fig->alive; ++i) {
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))) {
/* hand out missile weapons (from back to front, in case of mixed troops). */
for (di=0, i=fig->alive; i--!=0;) {
while (di!=w && (fig->weapons[dwp[di]].used==fig->weapons[dwp[di]].count || !fval(fig->weapons[dwp[di]].type, WTF_MISSILE))) {
++di;
}
if (di==w) break; /* no more weapons available */
if (fig->weapons[dwp[di]].defmissile>fig->person[i].weapon->defmissile) {
fig->person[i].secondary = &fig->weapons[dwp[di]];
if (weapon_weight(fig->weapons+dwp[di], true)>0) {
fig->person[i].missile = &fig->weapons[dwp[di]];
++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 {
int count, used;
const struct weapon_type * type;
int offskill : 8; /* offense skill */
int defskill : 8; /* defense against melee attacks */
int defmissile : 8; /* defense against missiles - not div. by 2 yet */
int attackskill : 8;
int defenseskill : 8;
} weapon;
/*** fighter::person::flags ***/
@ -158,8 +157,9 @@ typedef struct fighter {
int reload : 4; /* Anzahl Runden, die die Waffe x noch laden muss.
* dahinter steckt ein array[RL_MAX] wenn er min. eine hat. */
int last_action : 8; /* In welcher Runde haben wir zuletzt etwas getan */
struct weapon * weapon; /* offensive weapon */
struct weapon * secondary; /* defensive weapon */
struct weapon * preferred; /* weapon with best skill */
struct weapon * missile; /* missile weapon */
struct weapon * melee; /* melee weapon */
} * person;
int flags;
struct {

View File

@ -334,15 +334,16 @@ sp_combatrosthauch(fighter * fi, int level, int power, spell * sp)
k +=n;
i_change(&df->unit->items, wp->type->itype, -n);
for (p=0;n && p!=df->unit->number;++p) {
if (df->person[p].weapon==wp) {
df->person[p].weapon = df->person[p].secondary;
df->person[p].secondary = NULL;
if (df->person[p].missile==wp) {
df->person[p].preferred = df->person[p].melee;
df->person[p].missile = NULL;
--n;
}
}
for (p=0;n && p!=df->unit->number;++p) {
if (df->person[p].secondary==wp) {
df->person[p].secondary = NULL;
if (df->person[p].melee==wp) {
df->person[p].preferred = df->person[p].missile;
df->person[p].melee = NULL;
--n;
}
}
@ -1285,7 +1286,7 @@ sp_windshield(fighter * fi, int level, int power, spell * sp)
break;
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;
--force;
}