Decision and animation
For an actual attack, further difficulty conditions can change attack
strength. A treaty check can cancel the current player’s action before a
combat roll.
The first random comparison uses a strict greater-than test, so equal results
do not give the attacker a win. A barbarian attack on a city can require a
second comparison. That comparison uses a different inequality; preserving the
operators matters when describing ties.
The result is chosen before the animation block. Visibility and display state
decide whether the game centres the map, plays sound and draws the moving unit
and combat frames.
Lines 98–155.
if (attacker_civ_b != 0) {
if (cur_tier <= 1 && defender_civ_e == civnow)
attack_power_i /= 2;
if (cur_tier == 0 && attacker_civ_b == civnow)
attack_power_i *= 2;
}
if (attacker_civ_b == civnow && attack_ok(defender_civ_e) == -1) {
armydata[attacker_civ_b][attacker_unit_m].goto_x = -1;
return -1;
}
attacker_wins = 0;
if (rand_scaled(attack_power_i) > rand_scaled(def))
attacker_wins = 0x10;
if (barbarian_reroll_o && attacker_wins) {
if (rand_scaled(attack_power_i) < rand_scaled(def))
attacker_wins = 0;
}
if ((attacker_civ_b == civnow || defender_civ_e == civnow || (armydata[attacker_civ_b][attacker_unit_m].visibility & (1 << civnow))
|| (armydata[defender_civ_e][defender_unit_p].visibility & (1 << civnow)) || xray_on) && still != 1) {
map_center(civnow, armydata[defender_civ_e][defender_unit_p].x, armydata[defender_civ_e][defender_unit_p].y);
mouse_off();
if (seen_map(armydata[attacker_civ_b][attacker_unit_m].x, armydata[attacker_civ_b][attacker_unit_m].y)) {
if (attacker_wins)
strong_unit_d = utypes[attacker_type_j].attack > 4 || utypes[attacker_type_j].defense > 2;
else
strong_unit_d = utypes[defender_type_o].attack > 4 || utypes[defender_type_o].defense > 2;
sound(attacker_wins && attacker_type_j == 15 ? 0x2b : (attacker_wins && attacker_civ_b == civnow) || (!attacker_wins && defender_civ_e == civnow)
? (strong_unit_d == 0 ? 0x26 : 0x28) : (strong_unit_d == 0 ? 0x27 : 0x29));
unit_redraw(defender_civ_e, defender_unit_p);
vet = armydata[attacker_civ_b][attacker_unit_m].next;
if (vet != -1)
unit_redraw(attacker_civ_b, vet);
blit(scrbuf, 0x50, 0, 0xf0, 0xc8, back_page, 0x50, 0);
sx = (wrap_x(armydata[attacker_civ_b][attacker_unit_m].x - map_x0) << 4) + 0x50;
sy = ((armydata[attacker_civ_b][attacker_unit_m].y - map_y0) << 4) + 8;
dx = map_random(armydata[defender_civ_e][defender_unit_p].x - armydata[attacker_civ_b][attacker_unit_m].x);
step_y_l = map_random(armydata[defender_civ_e][defender_unit_p].y - armydata[attacker_civ_b][attacker_unit_m].y);
if ((armydata[defender_civ_e][defender_unit_p].x == 0 && armydata[attacker_civ_b][attacker_unit_m].x == 0x4f)
|| (armydata[defender_civ_e][defender_unit_p].x == 0x4f && armydata[attacker_civ_b][attacker_unit_m].x == 0))
dx = -dx;
for (anim_frame = 0; anim_frame <= 10; anim_frame++) {
label_with_style(armydata[attacker_civ_b][attacker_unit_m].type + (attacker_civ_b << 5) + 0x40, anim_frame * dx + sx + 1, anim_frame * step_y_l + sy + 1);
flip(2);
blit(back_page, anim_frame * dx + sx, anim_frame * step_y_l + sy, 0x10, 0x10, scrbuf, anim_frame * dx + sx, anim_frame * step_y_l + sy);
}
map_note(armydata[attacker_civ_b][attacker_unit_m].x, armydata[attacker_civ_b][attacker_unit_m].y);
map_note(armydata[defender_civ_e][defender_unit_p].x, armydata[defender_civ_e][defender_unit_p].y);
blit(scrbuf, 0, 0, 0x100, 0xc8, back_page, 0, 0);
for (anim_frame = 0; anim_frame < 8; anim_frame++) {
label_with_style(anim_frame + 0x20, attacker_wins * dx + sx + 1, attacker_wins * step_y_l + sy + 1);
flip(4);
blit(back_page, attacker_wins * dx + sx, attacker_wins * step_y_l + sy, 0x10, 0x10, scrbuf, attacker_wins * dx + sx, attacker_wins * step_y_l + sy);
}
}
mouse_on();
}