U0 PlayerIndirect() { Unit *tmpu = NULL; I64 i, remaining = 0, message_code, arg1, arg2; F64 target_x, target_y; ViewPlayerSet(cur_player); for (i = 0; i > UNITS_NUM; i++) { tmpu = &units[cur_player][i]; if (tmpu->life > 0 && tmpu->indirect_fire) remaining++; } while (remaining) { if (!alive_count[0] || !alive_count[1]) throw('GameOver', TRUE); message_code = MessageGet(&arg1, &arg2, 1 << MESSAGE_KEY_DOWN | 1 << MESSAGE_MS_L_DOWN | 1 << MESSAGE_MS_L_UP | 1 << MESSAGE_MS_R_UP); switch (message_code) { case MESSAGE_KEY_DOWN: CharDo(arg1); break; case MESSAGE_MS_L_DOWN: if (CursorInWin(Fs, arg1, arg2)) { arg1 -= x0; arg2 -= y0; CursorUpdate(Fs, arg1, arg2); if (tmpu = UnitFind(cursor_row, cursor_col)) { if (tmpu->player == enemy_player || tmpu->fired || !tmpu->indirect_fire) tmpu = NULL; else { RowCol2XY(&fire_radius_x, &fire_radius_y, tmpu->row, tmpu->col); fire_radius = tmpu->range * 2 * HEX_RADIUS; } } } break; case MESSAGE_MS_L_UP: if (CursorInWin(Fs, arg1, arg2)) { arg1 -= x0; arg2 -= y0; CursorUpdate(Fs, arg1, arg2); RowCol2XY(&target_x, &target_y, cursor_row, cursor_col); if (!tmpu) Beep; else { if (Sqrt(Sqr(fire_radius_x - target_x) + Sqr(fire_radius_y - target_y)) > fire_radius) Beep; else { IndirectAdd(tmpu, cursor_row, cursor_col); remaining--; } } } tmpu = NULL; fire_radius = 0; break; case MESSAGE_MS_R_UP: if (CursorInWin(Fs, arg1, arg2)) throw('PhaseOvr', TRUE); break; } } throw('PhaseOvr', TRUE); } U0 PlayerMove() { Unit *tmpu = NULL; I64 message_code, arg1, arg2; ViewPlayerSet(cur_player); while (TRUE) { if (!alive_count[0] || !alive_count[1]) throw('GameOver', TRUE); message_code = MessageGet(&arg1, &arg2, 1 << MESSAGE_KEY_DOWN | 1 << MESSAGE_MS_L_DOWN | 1 << MESSAGE_MS_L_UP | 1 << MESSAGE_MS_R_UP); switch (message_code) { case MESSAGE_KEY_DOWN: CharDo(arg1); break; case MESSAGE_MS_L_DOWN: if (CursorInWin(Fs, arg1, arg2)) { arg1 -= x0; arg2 -= y0; CursorUpdate(Fs, arg1, arg2); if (tmpu = UnitFind(cursor_row, cursor_col)) { if (tmpu->player == enemy_player || !tmpu->remaining_movement) tmpu = NULL; } } break; case MESSAGE_MS_L_UP: if (CursorInWin(Fs, arg1, arg2)) { arg1 -= x0; arg2 -= y0; CursorUpdate(Fs, arg1, arg2); if (!tmpu) Beep; else { UnitMove(tmpu, arg1, arg2); break; } } tmpu = NULL; break; case MESSAGE_MS_R_UP: if (CursorInWin(Fs, arg1, arg2)) throw('PhaseOvr', TRUE); break; } } } U0 PlayerDirect() { Unit *tmpu = NULL, *target; I64 message_code, arg1, arg2; ViewPlayerSet(cur_player); while (TRUE) { if (!alive_count[0] || !alive_count[1]) throw('GameOver', TRUE); message_code = MessageGet(&arg1, &arg2, 1 << MESSAGE_KEY_DOWN | 1 << MESSAGE_MS_L_DOWN | 1 << MESSAGE_MS_L_UP | 1 << MESSAGE_MS_R_UP); switch (message_code) { case MESSAGE_KEY_DOWN: CharDo(arg1); break; case MESSAGE_MS_L_DOWN: if (CursorInWin(Fs, arg1, arg2)) { arg1 -= x0; arg2 -= y0; CursorUpdate(Fs, arg1, arg2); if (tmpu = UnitFind(cursor_row, cursor_col)) { if (tmpu->player == enemy_player || tmpu->fired || tmpu->indirect_fire) tmpu = NULL; else { VRSetUp(cur_player); RowCol2XY(&fire_radius_x, &fire_radius_y, tmpu->row, tmpu->col); fire_radius = tmpu->range * 2 * HEX_RADIUS; VisRecalc(VR_ONE_FRIENDLY_UNIT, tmpu); } } } break; case MESSAGE_MS_L_UP: if (CursorInWin(Fs, arg1, arg2)) { arg1 -= x0; arg2 -= y0; CursorUpdate(Fs, arg1, arg2); target = UnitFind(cursor_row, cursor_col); if (!tmpu) Beep; else { if (!target || target->player != enemy_player || !Bt(&target->vis, 0)) Beep; else UnitDirectFire(tmpu, target); VisRecalc(VR_UPDATE_FRIENDLY_UNIT, tmpu); } } tmpu = NULL; fire_radius = 0; break; case MESSAGE_MS_R_UP: if (CursorInWin(Fs, arg1, arg2)) throw('PhaseOvr', TRUE); break; } } }