diff options
Diffstat (limited to 'jouer.c')
-rw-r--r-- | jouer.c | 234 |
1 files changed, 148 insertions, 86 deletions
@@ -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: |