summaryrefslogtreecommitdiff
path: root/jouer.c
diff options
context:
space:
mode:
authorOlivier Gayot <duskcoder@gmail.com>2015-01-08 16:53:35 +0100
committerOlivier Gayot <duskcoder@gmail.com>2015-01-08 16:53:35 +0100
commite8b35eae36f56492069d8f242c078ec5275d1a0b (patch)
treebe50721ca7d46454d4be5ab311fdbee52578417a /jouer.c
parent6d8f84b21c4423afa52a3d3c4ff88110dbe1d1be (diff)
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 <duskcoder@gmail.com>
Diffstat (limited to 'jouer.c')
-rw-r--r--jouer.c124
1 files changed, 117 insertions, 7 deletions
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;