From e8b35eae36f56492069d8f242c078ec5275d1a0b Mon Sep 17 00:00:00 2001 From: Olivier Gayot Date: Thu, 8 Jan 2015 16:53:35 +0100 Subject: handle the selection of a target in a generic way. we do not split the code of the selection of a target anymore. Each action now does a very simple thing and as much efficiently as possible. every old function that are not used anymore have been removed. Signed-off-by: Olivier Gayot --- jouer.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 117 insertions(+), 7 deletions(-) (limited to 'jouer.c') diff --git a/jouer.c b/jouer.c index 70795a8..7175191 100644 --- a/jouer.c +++ b/jouer.c @@ -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; -- cgit v1.2.3