diff options
Diffstat (limited to 'jouer.c')
-rw-r--r-- | jouer.c | 124 |
1 files changed, 117 insertions, 7 deletions
@@ -21,17 +21,17 @@ static inline void unhighlight_prev_character(struct team_t *team) chr->surf = chr->def_surf; } -static int find_next_ally(const struct team_t *ally) +static int find_next_team_member(const struct team_t *team, int current) { - for (int i = ally->chr_cur + 1; i < ally->chr_cnt; ++i) { - const struct character_t *chr = &ally->chrs[i]; + for (int i = current + 1; i < team->chr_cnt; ++i) { + const struct character_t *chr = &team->chrs[i]; if (chr->alive) return i; } - for (int i = 0; i <= ally->chr_cur; ++i) { - const struct character_t *chr = &ally->chrs[i]; + for (int i = 0; i <= current; ++i) { + const struct character_t *chr = &team->chrs[i]; if (chr->alive) return i; @@ -40,6 +40,35 @@ static int find_next_ally(const struct team_t *ally) return -1; } +static int find_prev_team_member(const struct team_t *team, int current) +{ + for (int i = current - 1; i >= 0; --i) { + const struct character_t *chr = &team->chrs[i]; + + if (chr->alive) + return i; + } + + for (int i = team->chr_cnt - 1; i >= current; ++i) { + const struct character_t *chr = &team->chrs[i]; + + if (chr->alive) + return i; + } + + return -1; +} + +static int get_alive_character(const struct team_t *team) +{ + for (int i = 0; i < team->chr_cnt; ++i) { + if (team->chrs[i].alive) + return i; + } + + return -1; +} + /* function called after an action has been performed */ static void update_current_character(struct team_t *ally, bool *ally_turn) { @@ -48,7 +77,7 @@ static void update_current_character(struct team_t *ally, bool *ally_turn) unhighlight_prev_character(ally); - next = find_next_ally(ally); + next = find_next_team_member(ally, ally->chr_cur); /* if there is no next ally or they are dead */ if (next <= ally->chr_cur) { @@ -63,6 +92,87 @@ static void update_current_character(struct team_t *ally, bool *ally_turn) } } +static +enum action_state_t select_target(SURFACES *surfaces, POSITIONS *positions, struct team_t *t1, struct team_t *t2, + void *data, void (*cb)(SURFACES *, POSITIONS *, struct character_t *, struct character_t *, void *)) +{ + SDL_Event event; + /* select our own character because he exists no matter what */ + struct team_t *target_team = t1; + int selection = target_team->chr_cur; + int new_selection; + + update_selected_target(surfaces, positions, &t1->chrs[selection]); + SDL_Flip(surfaces->Pecran); + + for (;;) { + SDL_WaitEvent(&event); + + if (event.type != SDL_KEYDOWN) + continue; + + switch (event.key.keysym.sym) { + case SDLK_ESCAPE: + case SDLK_a: + update_selected_target(surfaces, positions, NULL); + SDL_Flip(surfaces->Pecran); + return ACTION_CANCELED; + case SDLK_UP: + case SDLK_k: + new_selection = find_prev_team_member(target_team, selection); + + if (new_selection == selection) + continue; + + selection = new_selection; + update_selected_target(surfaces, positions, &target_team->chrs[selection]); + SDL_Flip(surfaces->Pecran); + break; + case SDLK_DOWN: + case SDLK_j: + new_selection = find_next_team_member(target_team, selection); + + if (new_selection == selection) + continue; + + selection = new_selection; + update_selected_target(surfaces, positions, &target_team->chrs[selection]); + SDL_Flip(surfaces->Pecran); + break; + case SDLK_LEFT: + case SDLK_h: + case SDLK_RIGHT: + case SDLK_l: + new_selection = get_alive_character((target_team == t1) ? t2 : t1); + if (new_selection < 0) + continue; + + selection = new_selection; + target_team = (target_team == t1) ? t2 : t1; + update_selected_target(surfaces, positions, &target_team->chrs[selection]); + SDL_Flip(surfaces->Pecran); + break; + case SDLK_RETURN: + case SDLK_f: + update_selected_target(surfaces, positions, NULL); + + (*cb)(surfaces, positions, &t1->chrs[t1->chr_cur], &target_team->chrs[selection], data); + + SDL_Flip(surfaces->Pecran); + + SDL_Delay(1000); + + SDL_BlitSurface(surfaces->Pfondjeu, &positions->Vpositiondegats, surfaces->Pecran, &positions->Vpositiondegats); + + SDL_Flip(surfaces->Pecran); + + return ACTION_PERFORMED; + default: + break; + } + } +} + enum action_state_t dig_entry(const struct entry_t *entries, int cnt_entries, struct action_params_t *params) { SDL_Event event; @@ -95,7 +205,7 @@ enum action_state_t dig_entry(const struct entry_t *entries, int cnt_entries, st case SDLK_RETURN: target = &entries[selection]; if (!target->children_cnt) { - enum action_state_t state = target->f(params->surfaces, params->positions, params->t1, params->t2, target->data); + enum action_state_t state = select_target(params->surfaces, params->positions, params->t1, params->t2, target->data, target->f); if (state == ACTION_PERFORMED) return ACTION_PERFORMED; |