#include #include #include #include "structures.h" #include "constantes.h" #include "prototypes.h" #include "priv_entries.h" static inline void highlight_current_character(struct team_t *team) { struct character_t *chr = &team->chrs[team->chr_cur]; chr->surf = chr->red_surf; } static inline void unhighlight_prev_character(struct team_t *team) { struct character_t *chr = &team->chrs[team->chr_cur]; chr->surf = chr->def_surf; } static int find_next_team_member(const struct team_t *team, int current) { 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 <= current; ++i) { const struct character_t *chr = &team->chrs[i]; if (chr->alive) return i; } 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 *t1, struct team_t *t2, struct team_t **playing) { struct team_t *current; int next; unhighlight_prev_character(*playing); current = *playing; next = find_next_team_member(current, current->chr_cur); if (next == -1) { /* if our team is dead */ current = *playing = (current == t1) ? t2 : t1; if (!current->chrs[current->chr_cur].alive) current->chr_cur = find_next_team_member(current, current->chr_cur); } else if (next > current->chr_cur) { /* we still have some players to use */ current->chr_cur = next; } else { current->chr_cur = next; current = *playing = (current == t1) ? t2 : t1; if (!current->chrs[current->chr_cur].alive) { current->chr_cur = find_next_team_member(current, current->chr_cur); if (current->chr_cur < 0) { /* there is no alive character in the other team */ current = *playing = (current == t1) ? t2 : t1; } } } highlight_current_character(*playing); } 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; } } } static enum action_state_t dig_entry(const struct entry_t *entries, int cnt_entries, struct action_params_t *params) { SDL_Event event; const struct entry_t *target; int selection = 0; update_list_entries(params->surfaces, params->positions, entries, cnt_entries, selection); for (;;) { SDL_WaitEvent(&event); if (event.type != SDL_KEYDOWN) continue; switch (event.key.keysym.sym) { case SDLK_a: case SDLK_ESCAPE: return ACTION_CANCELED; case SDLK_k: case SDLK_UP: selection = (selection > 0) ? selection - 1 : cnt_entries - 1; update_list_entries(params->surfaces, params->positions, entries, cnt_entries, selection); break; case SDLK_j: case SDLK_DOWN: selection = (selection < cnt_entries - 1) ? selection + 1 : 0; update_list_entries(params->surfaces, params->positions, entries, cnt_entries, selection); break; case SDLK_f: case SDLK_RETURN: target = &entries[selection]; if (!target->children_cnt) { 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; } else { if (dig_entry(target->children, target->children_cnt, params) == ACTION_PERFORMED) return ACTION_PERFORMED; } update_list_entries(params->surfaces, params->positions, entries, cnt_entries, selection); default: break; } } } int Fjouer (SURFACES *surfaces, POSITIONS *positions, struct team_t *t1, struct team_t *t2) { struct team_t *playing_team; unsigned int continuer=1; int i; unsigned int gagne,perdu; if(surfaces->Pfondjeu!=NULL) { SDL_FreeSurface(surfaces->Pfondjeu); surfaces->Pfondjeu=NULL; } Fblitterfond(surfaces); // on blit le fond du jeu /* compute whether the allies or the enemies should begin */ playing_team = (rand() % 2) ? t1 : t2; highlight_current_character(playing_team); blit_team(surfaces, t1); blit_team(surfaces, t2); SDL_Flip(surfaces->Pecran); while (continuer) { if (!playing_team->cpu) //si un player joue { struct action_params_t params = { .surfaces = surfaces, .positions = positions, .t1 = playing_team, .t2 = (playing_team == t1) ? t2 : t1, }; enum action_state_t state; state = dig_entry(action_entries_g, countof(action_entries_g), ¶ms); switch (state) { case ACTION_CANCELED: continuer = 0; break; case ACTION_PERFORMED: update_current_character(t1, t2, &playing_team); blit_team(surfaces, t1); blit_team(surfaces, t2); break; default: break; } } else { /* TODO reactivate */ #if 0 Factionennemi(&Vtourennemi,surfaces,positions,ennemis,persos,Vnbennemis,&Vtour,Vtourallie); #endif SDL_Flip(surfaces->Pecran); update_current_character(t1, t2, &playing_team); blit_team(surfaces, t1); blit_team(surfaces, t2); } // on vérifie à présent si on a gagné ou si on a perdu ! gagne=1; perdu=1; for (i = 0; i < t2->chr_cnt; i++) { if (t2->chrs[i].alive) gagne=0; } for (i = 0; i < t1->chr_cnt; i++) { if (t1->chrs[i].alive) perdu=0; } // la y'a des trucs a mettre pour si on gagne ou on perd parce que sa fait assez pitié :p if(perdu) { SDL_Delay(2000); continuer=0; } else if(gagne) { SDL_Delay(2000); continuer=0; } } return 0; }