forked from github/server
"Angriffe in zweite Schlachtreihe überproportional?" - friendly/enemy being set incorrectly - debug output ported from main branch
This commit is contained in:
parent
1c5acea30c
commit
05a8bd5b39
1 changed files with 94 additions and 26 deletions
|
@ -83,7 +83,8 @@ static FILE *bdebug;
|
|||
# define DAMAGE_QUOTIENT 1 /* damage += skilldiff/DAMAGE_QUOTIENT */
|
||||
#endif
|
||||
|
||||
#undef DEBUG_FAST /* should be disabled when I'm sure it works */
|
||||
#undef DEBUG_FAST /* should be disabled when b->fast and b->rowcache works */
|
||||
#define DEBUG_SELECT /* should be disabled if select_enemy works */
|
||||
|
||||
typedef enum combatmagic {
|
||||
DO_PRECOMBATSPELL,
|
||||
|
@ -248,7 +249,7 @@ fbattlerecord(battle * b, faction * f, const char *s)
|
|||
#define enemy(as, ds) (as->relations[ds->index]&E_ENEMY)
|
||||
#define friendly(as, ds) (as->bf->faction==ds->bf->faction || (as->relations[ds->index]&E_FRIEND))
|
||||
|
||||
static void
|
||||
static boolean
|
||||
set_enemy(side * as, side * ds, boolean attacking)
|
||||
{
|
||||
int i;
|
||||
|
@ -261,14 +262,21 @@ set_enemy(side * as, side * ds, boolean attacking)
|
|||
if (as->enemies[i]==ds) break;
|
||||
}
|
||||
assert(i!=MAXSIDES);
|
||||
ds->relations[as->index] |= E_ENEMY;
|
||||
as->relations[ds->index] |= E_ENEMY;
|
||||
if (attacking) as->relations[ds->index] |= E_ATTACKING;
|
||||
if ((ds->relations[as->index] & E_ENEMY)==0) {
|
||||
/* enemy-relation are always symmetrical */
|
||||
assert((as->relations[ds->index] & (E_ENEMY|E_FRIEND))==0);
|
||||
ds->relations[as->index] |= E_ENEMY;
|
||||
as->relations[ds->index] |= E_ENEMY;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
set_friendly(side * as, side * ds)
|
||||
{
|
||||
assert((as->relations[ds->index] & E_ENEMY)==0);
|
||||
ds->relations[as->index] |= E_FRIEND;
|
||||
as->relations[ds->index] |= E_FRIEND;
|
||||
}
|
||||
|
@ -1269,9 +1277,11 @@ select_enemy(fighter * af, int minrow, int maxrow, int select)
|
|||
{
|
||||
side *as = af->side;
|
||||
battle * b = as->battle;
|
||||
int si;
|
||||
int si, selected;
|
||||
int enemies;
|
||||
|
||||
#ifdef DEBUG_SELECT
|
||||
troop result = no_troop;
|
||||
#endif
|
||||
if (af->unit->race->flags & RCF_FLY) {
|
||||
/* flying races ignore min- and maxrow and can attack anyone fighting
|
||||
* them */
|
||||
|
@ -1285,7 +1295,7 @@ select_enemy(fighter * af, int minrow, int maxrow, int select)
|
|||
/* Niemand ist in der angegebenen Entfernung? */
|
||||
if (enemies<=0) return no_troop;
|
||||
|
||||
enemies = rng_int() % enemies;
|
||||
selected = rng_int() % enemies;
|
||||
for (si=0;as->enemies[si];++si) {
|
||||
side *ds = as->enemies[si];
|
||||
fighter * df;
|
||||
|
@ -1312,17 +1322,32 @@ select_enemy(fighter * af, int minrow, int maxrow, int select)
|
|||
|
||||
if (select&SELECT_DISTANCE) dr += offset;
|
||||
if (dr < minrow || dr > maxrow) continue;
|
||||
if (df->alive - df->removed > enemies) {
|
||||
if (df->alive - df->removed > selected) {
|
||||
#ifdef DEBUG_SELECT
|
||||
if (result.fighter==NULL) {
|
||||
result.index = selected;
|
||||
result.fighter = df;
|
||||
}
|
||||
#else
|
||||
troop dt;
|
||||
dt.index = enemies;
|
||||
dt.index = selected;
|
||||
dt.fighter = df;
|
||||
return dt;
|
||||
#endif
|
||||
}
|
||||
else enemies -= (df->alive - df->removed);
|
||||
selected -= (df->alive - df->removed);
|
||||
enemies -= (df->alive - df->removed);
|
||||
}
|
||||
}
|
||||
assert(!enemies);
|
||||
if (enemies!=0) {
|
||||
log_error(("select_enemies has a bug.\n"));
|
||||
}
|
||||
#ifdef DEBUG_SELECT
|
||||
return result;
|
||||
#else
|
||||
assert(!selected);
|
||||
return no_troop;
|
||||
#endif
|
||||
}
|
||||
|
||||
static troop
|
||||
|
@ -2581,6 +2606,7 @@ battle_punit(unit * u, battle * b)
|
|||
fbattlerecord(b, f, x->s);
|
||||
if (bdebug && u->faction == f) {
|
||||
fputs(x->s, bdebug);
|
||||
fputc('\n', bdebug);
|
||||
}
|
||||
}
|
||||
if (S)
|
||||
|
@ -3111,8 +3137,8 @@ make_fighter(battle * b, unit * u, side * s1, boolean attack)
|
|||
}
|
||||
|
||||
|
||||
static fighter *
|
||||
join_battle(battle * b, unit * u, boolean attack)
|
||||
static int
|
||||
join_battle(battle * b, unit * u, boolean attack, fighter ** cp)
|
||||
{
|
||||
side * s;
|
||||
fighter *c = NULL;
|
||||
|
@ -3121,7 +3147,8 @@ join_battle(battle * b, unit * u, boolean attack)
|
|||
attrib * a = a_find(u->attribs, &at_fleechance);
|
||||
if (a!=NULL) {
|
||||
if (rng_double()<=a->data.flt) {
|
||||
return NULL;
|
||||
*cp = NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3138,8 +3165,12 @@ join_battle(battle * b, unit * u, boolean attack)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!c) c = make_fighter(b, u, NULL, attack);
|
||||
return c;
|
||||
if (!c) {
|
||||
*cp = make_fighter(b, u, NULL, attack);
|
||||
return *cp!=NULL;
|
||||
}
|
||||
*cp = c;
|
||||
return false;
|
||||
}
|
||||
|
||||
static const char *
|
||||
|
@ -3437,20 +3468,38 @@ join_allies(battle * b)
|
|||
if (ally==NULL) continue;
|
||||
}
|
||||
/* keine Einwände, also soll er mitmachen: */
|
||||
if (!c) c = join_battle(b, u, false);
|
||||
if (!c) continue;
|
||||
if (c==NULL) {
|
||||
if (join_battle(b, u, false, &c)) {
|
||||
if (battledebug) {
|
||||
fprintf(bdebug, "%s joins to help %s against %s.\n",
|
||||
unitname(u), factionname(s->bf->faction),
|
||||
factionname(se->bf->faction));
|
||||
}
|
||||
} else if (c==NULL) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Die Feinde meiner Freunde sind meine Feinde: */
|
||||
for (se = sbegin; se; se=se->next) {
|
||||
if (se->bf->faction!=u->faction && enemy(s, se)) {
|
||||
set_enemy(se, c->side, false);
|
||||
if (set_enemy(se, c->side, false) && battledebug) {
|
||||
fprintf(bdebug, "%u/%s hates %u/%s because they are enemies with %u/%s.\n",
|
||||
c->side->index, sidename(c->side),
|
||||
se->index, sidename(se),
|
||||
s->index, sidename(s));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (s=sbegin;s;s=s->next) {
|
||||
for (s=b->sides;s;s=s->next) {
|
||||
int si;
|
||||
side * sa;
|
||||
faction * f = s->bf->faction;
|
||||
|
||||
/* Den Feinden meiner Feinde gebe ich Deckung (gegen gemeinsame Feinde): */
|
||||
for (si=0; s->enemies[si]; ++si) {
|
||||
side * se = s->enemies[si];
|
||||
|
@ -3462,6 +3511,15 @@ join_allies(battle * b)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (sa=s->next;sa;sa=sa->next) {
|
||||
if (enemy(s, sa)) continue;
|
||||
if (friendly(s, sa)) continue;
|
||||
if (!alliedgroup(r->planep, f, sa->bf->faction, f->allies, HELP_FIGHT)) continue;
|
||||
if (!alliedgroup(r->planep, sa->bf->faction, f, sa->bf->faction->allies, HELP_FIGHT)) continue;
|
||||
|
||||
set_friendly(s, sa);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3671,8 +3729,18 @@ init_battle(region * r, battle **bp)
|
|||
}
|
||||
b = make_battle(r);
|
||||
}
|
||||
c1 = join_battle(b, u, true);
|
||||
c2 = join_battle(b, u2, false);
|
||||
if (join_battle(b, u, true, &c1)) {
|
||||
if (battledebug) {
|
||||
fprintf(bdebug, "%s joins by attacking %s.\n",
|
||||
unitname(u), unitname(u2));
|
||||
}
|
||||
}
|
||||
if (join_battle(b, u2, false, &c2)) {
|
||||
if (battledebug) {
|
||||
fprintf(bdebug, "%s joins because of an attack from %s.\n",
|
||||
unitname(u2), unitname(u));
|
||||
}
|
||||
}
|
||||
|
||||
/* Hat die attackierte Einheit keinen Noaid-Status,
|
||||
* wird das Flag von der Faction genommen, andere
|
||||
|
@ -3684,10 +3752,10 @@ init_battle(region * r, battle **bp)
|
|||
* Präcombataura bei kurzem Kampf. */
|
||||
c1->side->bf->attacker = true;
|
||||
|
||||
set_enemy(c1->side, c2->side, true);
|
||||
if (bdebug && !enemy(c1->side, c2->side)) {
|
||||
fprintf(bdebug, "%s attacks %s\n", sidename(c1->side),
|
||||
sidename(c2->side));
|
||||
if (set_enemy(c1->side, c2->side, true) && battledebug) {
|
||||
fprintf(bdebug, "%u/%s hates %u/%s because they attacked them.\n",
|
||||
c2->side->index, sidename(c2->side),
|
||||
c1->side->index, sidename(c1->side));
|
||||
}
|
||||
fighting = true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue