summaryrefslogtreecommitdiff
path: root/jouer.c
diff options
context:
space:
mode:
Diffstat (limited to 'jouer.c')
-rw-r--r--jouer.c234
1 files changed, 148 insertions, 86 deletions
diff --git a/jouer.c b/jouer.c
index 2d4a30f..5f0c9b9 100644
--- a/jouer.c
+++ b/jouer.c
@@ -160,6 +160,146 @@ select_default_target(const struct action_params_t *params,
abort();
}
+enum selection_change_t {
+ SELECTION_CHANGE_LEFT = 0x1,
+ SELECTION_CHANGE_RIGHT = SELECTION_CHANGE_LEFT << 0x1,
+
+ SELECTION_CHANGE_HORIZ = SELECTION_CHANGE_LEFT | SELECTION_CHANGE_RIGHT,
+
+ SELECTION_CHANGE_UP = SELECTION_CHANGE_RIGHT << 0x1,
+ SELECTION_CHANGE_DOWN = SELECTION_CHANGE_UP << 0x1,
+
+ SELECTION_CHANGE_VERT = SELECTION_CHANGE_UP | SELECTION_CHANGE_DOWN,
+
+ SELECTION_CHANGE_MODE = SELECTION_CHANGE_DOWN << 0x1,
+};
+
+static int
+change_selection_vert(bool up, struct target_t *target)
+{
+ struct chr_t *(*find)(const struct chr_t *);
+ struct chr_t *new_selection;
+
+ /* UP or DOWN when selecting a team does nothing */
+ if (!target->is_chr)
+ return -1;
+
+ find = (up) ? find_prev_team_member : find_next_team_member;
+
+ new_selection = (*find)(target->chr);
+
+ if (new_selection->idx == target->chr->idx)
+ return -1;
+
+ target->chr = new_selection;
+
+ return 0;
+}
+
+static int change_selection_horiz(const struct action_params_t *params,
+ enum target_type_t type, struct target_t *target)
+{
+ enum target_type_t filter_ally, filter_enemy;
+ struct team_t *team;
+
+ if (target->is_chr) {
+ filter_ally = TARGET_SINGLE_ALLY;
+ filter_enemy = TARGET_SINGLE_ENEMY;
+
+ team = (target->chr->team == params->t1) ? params->t2 : params->t1;
+ } else {
+ filter_ally = TARGET_TEAM_ALLY;
+ filter_enemy = TARGET_TEAM_ENEMY;
+
+ team = (target->team == params->t1) ? params->t2 : params->t1;
+ }
+
+ if (params->src->team == team && !(type & filter_ally))
+ return -1;
+
+ if (params->src->team != team && !(type & filter_enemy))
+ return -1;
+
+ if (target->is_chr) {
+ struct chr_t *new_chr;
+
+ new_chr = get_first_alive_character(team);
+
+ if (new_chr == NULL)
+ return -1;
+
+ target->chr = new_chr;
+ } else {
+ target->team = team;
+ }
+ return 0;
+}
+
+static int change_selection_mode(const struct action_params_t *params,
+ int type, struct target_t *target)
+{
+ enum target_type_t filter_ally, filter_enemy;
+ struct team_t *team;
+
+ if (target->is_chr) {
+ filter_ally = TARGET_TEAM_ALLY;
+ filter_enemy = TARGET_TEAM_ENEMY;
+
+ team = target->chr->team;
+ } else {
+ filter_ally = TARGET_SINGLE_ALLY | TARGET_SELF;
+ filter_enemy = TARGET_SINGLE_ENEMY;
+
+ team = target->team;
+ }
+
+ if (team == params->src->team && !(type & filter_ally))
+ return -1;
+
+ if (team != params->src->team && !(type & filter_enemy))
+ return -1;
+
+ if (target->is_chr) {
+ target->is_chr = false;
+ target->team = team;
+ } else {
+ target->is_chr = true;
+ target->chr = (params->src->team == team) ?
+ params->src : get_first_alive_character(team);
+ }
+
+ return 0;
+}
+
+static int change_selection(const struct action_params_t *params,
+ enum target_type_t type, enum selection_change_t change,
+ struct target_t *target)
+{
+ int ret;
+
+ /* the target is only `self' so cannot move */
+ if (type == TARGET_SELF)
+ return -1;
+
+ if (change & SELECTION_CHANGE_VERT) {
+ ret = change_selection_vert(change & SELECTION_CHANGE_UP, target);
+ } else if (change & SELECTION_CHANGE_HORIZ) {
+ ret = change_selection_horiz(params, type, target);
+ } else if (change == SELECTION_CHANGE_MODE) {
+ ret = change_selection_mode(params, type, target);
+ } else {
+ abort();
+ }
+
+ if (ret < 0)
+ return -1;
+
+ update_selected_target(params->surfaces, params->positions, target);
+ SDL_Flip(params->surfaces->screen);
+
+ return 0;
+}
+
static enum action_state_t
select_target(struct action_params_t *params, const struct action_t *action)
{
@@ -167,8 +307,6 @@ select_target(struct action_params_t *params, const struct action_t *action)
POSITIONS *positions = params->positions;
/* select our own character because he exists no matter what */
struct target_t target = select_default_target(params, action->target);
- struct chr_t *new_selection;
- struct team_t *team;
SDL_Event event;
update_selected_target(surfaces, positions, &target);
@@ -189,101 +327,25 @@ select_target(struct action_params_t *params, const struct action_t *action)
return ACTION_CANCELED;
case SDLK_TAB:
case SDLK_d:
- /* switch single / team */
-
- if (target.is_chr) {
- team = target.chr->team;
-
- if (team == params->src->team && !(action->target & TARGET_TEAM_ALLY))
- continue;
-
- if (team != params->src->team && !(action->target & TARGET_TEAM_ENEMY))
- continue;
-
- target.is_chr = false;
- target.team = team;
- } else {
- team = target.team;
-
- if (team == params->src->team && !(action->target & (TARGET_SINGLE_ALLY | TARGET_SELF)))
- continue;
-
- if (team != params->src->team && !(action->target & TARGET_SINGLE_ENEMY))
- continue;
-
- target.is_chr = true;
- target.chr = (params->src->team == team) ? params->src : get_first_alive_character(team);
- }
-
- update_selected_target(surfaces, positions, &target);
- SDL_Flip(surfaces->Pecran);
+ change_selection(params, action->target,
+ SELECTION_CHANGE_MODE, &target);
break;
case SDLK_UP:
case SDLK_k:
- if (!target.is_chr)
- continue;
-
- if (action->target & TARGET_SELF)
- continue;
-
- new_selection = find_prev_team_member(target.chr);
-
- if (new_selection->idx == target.chr->idx)
- continue;
-
- target.chr = new_selection;
- update_selected_target(surfaces, positions, &target);
- SDL_Flip(surfaces->Pecran);
+ change_selection(params, action->target, SELECTION_CHANGE_UP,
+ &target);
break;
case SDLK_DOWN:
case SDLK_j:
- if (!target.is_chr)
- continue;
-
- if (action->target & TARGET_SELF)
- continue;
-
- new_selection = find_next_team_member(target.chr);
-
- if (new_selection->idx == target.chr->idx)
- continue;
-
- target.chr = new_selection;
- update_selected_target(surfaces, positions, &target);
- SDL_Flip(surfaces->Pecran);
+ change_selection(params, action->target,
+ SELECTION_CHANGE_DOWN, &target);
break;
case SDLK_LEFT:
case SDLK_h:
case SDLK_RIGHT:
case SDLK_l:
- if (target.is_chr) {
- team = (target.chr->team == params->t1) ? params->t2 : params->t1;
-
- if (params->src->team == team && !(action->target & TARGET_SINGLE_ALLY))
- continue;
-
- if (params->src->team != team && !(action->target & TARGET_SINGLE_ENEMY))
- continue;
-
- new_selection = get_first_alive_character((target.chr->team == params->t1) ? params->t2 : params->t1);
- if (new_selection == NULL)
- continue;
-
- target.chr = new_selection;
- } else {
- team = (target.team == params->t1) ? params->t2 : params->t1;
-
- if (params->src->team == team && !(action->target & TARGET_TEAM_ALLY))
- continue;
-
- if (params->src->team != team && !(action->target & TARGET_TEAM_ENEMY))
- continue;
-
- target.team = team;
- }
-
- update_selected_target(surfaces, positions, &target);
- SDL_Flip(surfaces->Pecran);
+ change_selection(params, action->target,
+ SELECTION_CHANGE_HORIZ, &target);
break;
case SDLK_RETURN:
case SDLK_f: