diff options
author | Olivier Gayot <duskcoder@gmail.com> | 2015-01-08 15:04:26 +0100 |
---|---|---|
committer | Olivier Gayot <duskcoder@gmail.com> | 2015-01-08 15:37:48 +0100 |
commit | 1f9c71b49eeef9cd05b542515c06200b4a25f693 (patch) | |
tree | 6a29ab8af1ae447236013cbd78e5089937b72b1f | |
parent | adceeb1192fdd1d14e0f55219bbd1bcb14eacc05 (diff) |
use a generic way to navigate through entries
entries are actually any action or subaction that can be performed.
Attack, White Magic and so on are root actions.
Fire, Ice X are subactions of Black Magic.
Signed-off-by: Olivier Gayot <duskcoder@gmail.com>
-rw-r--r-- | actions.c | 25 | ||||
-rw-r--r-- | blits.c | 40 | ||||
-rw-r--r-- | entry.h | 30 | ||||
-rw-r--r-- | jouer.c | 129 | ||||
-rw-r--r-- | magies.c | 10 | ||||
-rw-r--r-- | priv_entries.h | 137 | ||||
-rw-r--r-- | prototypes.h | 12 | ||||
-rw-r--r-- | structures.h | 2 |
8 files changed, 311 insertions, 74 deletions
@@ -5,7 +5,7 @@ #include <stdio.h> #include <stdlib.h> -enum action_state_t Fattaquer(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy) +enum action_state_t Fattaquer(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, void *data) { int degats; struct character_t *target; @@ -13,6 +13,9 @@ enum action_state_t Fattaquer(SURFACES *surfaces,POSITIONS *positions, struct te int selection = 0; SDL_Event event; SDL_BlitSurface (surfaces->Pfondjeu,&positions->Vpositioncadreactions,surfaces->Pecran,&positions->Vpositioncadreactions); + + (void) data; + while(!enemy->chrs[selection].alive) selection++; update_selected_target(surfaces, positions, &enemy->chrs[selection]); @@ -150,7 +153,7 @@ enum action_state_t Fselectionnermagienoire(SURFACES *surfaces,POSITIONS *positi case SDLK_RETURN: SDL_BlitSurface(surfaces->Pfondjeu,&positions->Vpositiondegats,surfaces->Pecran,&positions->Vpositiondegats); SDL_Flip(surfaces->Pecran); - ret = Fmagieelement(surfaces,positions, ally, enemy, selection); + ret = Fmagieelement(surfaces,positions, ally, enemy, (enum element_t []) {selection}); if (ret == ACTION_PERFORMED) { continuer = 0; @@ -211,7 +214,7 @@ enum action_state_t Fselectionnermagieblanche(SURFACES *surfaces,POSITIONS *posi SDL_BlitSurface(surfaces->Pfondjeu,&positions->Vpositiondegats,surfaces->Pecran,&positions->Vpositiondegats); SDL_Flip(surfaces->Pecran); if(selection==SOIN) - ret = Fmagiesoin(surfaces,positions, ally, enemy); + ret = Fmagiesoin(surfaces,positions, ally, enemy, NULL); if (ret == ACTION_PERFORMED) { continuer = 0; @@ -273,17 +276,17 @@ enum action_state_t Fselectionnerobjet(SURFACES *surfaces,POSITIONS *positions, if(page==0) { if(selection==POTION) - ret = Fpotion(surfaces,positions, ally, enemy, selection); + ret = Fpotion(surfaces,positions, ally, enemy, (int []) {selection}); else if(selection==ETHER) - ret = Fether(surfaces,positions, ally, enemy, selection); + ret = Fether(surfaces,positions, ally, enemy, (int []) {selection}); else if(selection==POTIONPLUS) - ret = Fpotion(surfaces,positions, ally, enemy, selection); + ret = Fpotion(surfaces,positions, ally, enemy, (int []) { selection}); } else if(page==1) { if(selection==ETHERPLUS) - ret = Fether(surfaces,positions, ally, enemy, selection); + ret = Fether(surfaces,positions, ally, enemy, (int []) { selection}); } if (ret == ACTION_PERFORMED) { @@ -300,7 +303,7 @@ enum action_state_t Fselectionnerobjet(SURFACES *surfaces,POSITIONS *positions, return ret; } -enum action_state_t Fpotion(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, int type) +enum action_state_t Fpotion(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, void *data) { struct character_t *target; SDL_Event event; @@ -308,6 +311,8 @@ enum action_state_t Fpotion(SURFACES *surfaces,POSITIONS *positions, struct team int soins=0; int clan=ALLIE; + int type = *((int *)data); + if (type == POTION && ally->objects.potions <= 0) return ACTION_ERROR; else if(type == POTIONPLUS && ally->objects.potionsplus <= 0) @@ -365,7 +370,7 @@ enum action_state_t Fpotion(SURFACES *surfaces,POSITIONS *positions, struct team } } -enum action_state_t Fether(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, int type) +enum action_state_t Fether(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, void *data) { struct character_t *target; SDL_Event event; @@ -373,6 +378,8 @@ enum action_state_t Fether(SURFACES *surfaces,POSITIONS *positions, struct team_ int soins=0; int clan=ALLIE; + int type = *((int *)data); + if (type == ETHER && ally->objects.ethers <= 0) return ACTION_ERROR; else if (type == ETHERPLUS && ally->objects.ethersplus <= 0) @@ -152,6 +152,46 @@ void Fchangercurseurpersos (SURFACES *surfaces, POSITIONS *positions, struct cha TTF_CloseFont(police); } +void update_list_entries(SURFACES *surfaces, POSITIONS *positions, const struct entry_t *entries, int cnt, int selected) +{ + SDL_Color color = {0, 0, 0, 0}; + TTF_Font *font; + SDL_Surface *surf; + int off; + + if (selected == -1) { + SDL_BlitSurface(surfaces->Pfondjeu, &positions->Vpositioncadreactions, surfaces->Pecran, &positions->Vpositioncadreactions); + SDL_Flip(surfaces->Pecran); + return; + } + + SDL_BlitSurface(surfaces->Pcadreactions, NULL, surfaces->Pecran, &positions->Vpositioncadreactions); + + font = TTF_OpenFont("TIMESBI.TTF", 20); + off = selected / 3 * 3; + /* display at most three actions */ + for (int i = 0; i < 3; ++i) { + if (off + i >= cnt) { + SDL_BlitSurface(surfaces->Pactiondesactivee, NULL, surfaces->Pecran, &positions->Vpositionactionselectionnee[i]); + continue; + } + + /* if the current entry is the selected one */ + if (selected == off + i) { + SDL_BlitSurface(surfaces->Pactionselectionnee, NULL, surfaces->Pecran, &positions->Vpositionactionselectionnee[i]); + } + + surf = TTF_RenderText_Blended(font, entries[off + i].name, color); + + SDL_BlitSurface(surf, NULL, surfaces->Pecran, &positions->Vpositionnomactions[i]); + + SDL_FreeSurface(surf); + } + + TTF_CloseFont(font); + SDL_Flip(surfaces->Pecran); +} + void Fchangeractionselectionnee(SURFACES *surfaces, POSITIONS *positions,int selection,int page,int nbactions,int type) { int i; @@ -0,0 +1,30 @@ +#ifndef ENTRY_H +#define ENTRY_H + +#include "structures.h" +#include "players.h" + +struct entry_t { + /* displayed name */ + char *name; + int children_cnt; + + union { + struct entry_t *children; + + struct { + void *data; + enum action_state_t (*f)(SURFACES *, POSITIONS *, struct team_t *, struct team_t *, void *data); + }; + }; +}; + +struct action_params_t { + SURFACES *surfaces; + POSITIONS *positions; + + struct team_t *t1; + struct team_t *t2; +}; + +#endif /* ENTRY_H */ @@ -5,6 +5,8 @@ #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]; @@ -61,19 +63,62 @@ static void update_current_character(struct team_t *ally, bool *ally_turn) } } +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: + update_list_entries(params->surfaces, params->positions, NULL, 0, -1); + 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) { + return target->f(params->surfaces, params->positions, params->t1, params->t2, target->data); + } + + 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 *ally, struct team_t *enemy) { unsigned int continuer=1; - int selection=0; int i; - SDL_Event event; int Vtourennemi=0; int Vtour; int Vnbennemis=0; - int page=0; - int nbactions=5; unsigned int gagne,perdu; + if(surfaces->Pfondjeu!=NULL) { SDL_FreeSurface(surfaces->Pfondjeu); @@ -94,10 +139,22 @@ int Fjouer (SURFACES *surfaces, POSITIONS *positions, struct team_t *ally, struc blit_team(surfaces, ally); blit_team(surfaces, enemy); + SDL_Flip(surfaces->Pecran); + while (continuer) { if(Vtour==ALLIE) //si un player joue { + struct action_params_t params = { + .surfaces = surfaces, + .positions = positions, + + .t1 = ally, + .t2 = enemy, + }; + + enum action_state_t state; + while (!ally->chrs[ally->chr_cur].alive) //si le perso selectionné est mort { if (ally->chr_cur < ally->chr_cnt) // si ce n'est pas le dernier @@ -105,62 +162,18 @@ int Fjouer (SURFACES *surfaces, POSITIONS *positions, struct team_t *ally, struc else // sinon si c'est le dernier ally->chr_cur = 0; // on reprend le 1er } - Fchangeractionselectionnee(surfaces,positions,selection,page,nbactions,ACTIONS); - SDL_WaitEvent(&event); - switch(event.type) - { - case SDL_KEYDOWN: - switch(event.key.keysym.unicode) - { - case SDLK_ESCAPE: - case SDLK_a: - continuer=0; - break; - } - switch (event.key.keysym.sym) - { - case SDLK_UP: - case SDLK_k: - if (selection!=0) - selection--; - else - selection=nbactions-1; - page=selection/3; - Fchangeractionselectionnee(surfaces,positions,selection,page,nbactions,ACTIONS); - break; - case SDLK_DOWN: - case SDLK_j: - if (selection!=nbactions-1) - selection++; - else - selection=0; - page=selection/3; - Fchangeractionselectionnee(surfaces,positions,selection,page,nbactions,ACTIONS); + + state = dig_entry(action_entries_g, countof(action_entries_g), ¶ms); + switch (state) { + case ACTION_CANCELED: + continuer = 0; break; - case SDLK_RETURN: - case SDLK_f: - { - enum action_state_t (*actionp)(SURFACES *, POSITIONS *, struct team_t *ally, struct team_t *enemy) = NULL; - - switch (selection) { - case ATTAQUE: actionp = Fattaquer; break; - case MAGIE_BLANCHE: actionp = Fselectionnermagieblanche; break; - case MAGIE_NOIRE: actionp = Fselectionnermagienoire; break; - case TECHNIQUES: break; - case OBJETS: actionp = Fselectionnerobjet; break; - default: abort(); break; - } - - if (actionp && (*actionp)(surfaces,positions, ally, enemy) == ACTION_PERFORMED) { - update_current_character(ally, (bool *)&Vtour); - blit_team(surfaces, ally); - } - } + case ACTION_PERFORMED: + update_current_character(ally, (bool *)&Vtour); + blit_team(surfaces, ally); break; - default: + default: break; - } - break; } } else if(Vtour==ENNEMI) // sinon si c'est le cpu qui joue @@ -172,7 +185,7 @@ int Fjouer (SURFACES *surfaces, POSITIONS *positions, struct team_t *ally, struc Vtourennemi = 0; } } -/* TODO reactivate */ + /* TODO reactivate */ #if 0 Factionennemi(&Vtourennemi,surfaces,positions,ennemis,persos,Vnbennemis,&Vtour,Vtourallie); #else @@ -5,7 +5,7 @@ #include "constantes.h" #include "prototypes.h" -enum action_state_t Fmagieelement (SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, enum element_t element) +enum action_state_t Fmagieelement (SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, void *data) { struct character_t *target; int degats; @@ -13,6 +13,9 @@ enum action_state_t Fmagieelement (SURFACES *surfaces,POSITIONS *positions, stru int clan=ENNEMI; SDL_Event event; SDL_BlitSurface (surfaces->Pfondjeu,&positions->Vpositioncadreactions,surfaces->Pecran,&positions->Vpositioncadreactions); + + enum element_t element = *((enum element_t *)data); + while (!enemy->chrs[selection].alive) selection++; update_selected_target(surfaces,positions, &enemy->chrs[selection]); @@ -61,13 +64,16 @@ enum action_state_t Fmagieelement (SURFACES *surfaces,POSITIONS *positions, stru } } -enum action_state_t Fmagiesoin(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy) +enum action_state_t Fmagiesoin(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, void *data) { struct character_t *target; SDL_Event event; int soins; int clan=ALLIE; int selection=0; + + (void) data; + SDL_BlitSurface (surfaces->Pfondjeu,&positions->Vpositioncadreactions,surfaces->Pecran,&positions->Vpositioncadreactions); while(!ally->chrs[selection].alive) selection++; diff --git a/priv_entries.h b/priv_entries.h new file mode 100644 index 0000000..c2fa5c6 --- /dev/null +++ b/priv_entries.h @@ -0,0 +1,137 @@ +#ifndef PRIV_ENTRIES_H +#define PRIV_ENTRIES_H + +#include "prototypes.h" +#include "entry.h" + +/* TODO general make difference between action / action + and action x */ + +struct entry_t white_magic_entries[] = { + { + .name = "Cure", + .children_cnt = 0, + .f = Fattaquer, + .data = NULL, + }, { + .name = "Cure +", + .children_cnt = 0, + .f = Fattaquer, + .data = NULL, + }, +}; + +struct entry_t black_magic_entries[] = { + { + .name = "Fire", + .children_cnt = 0, + .f = Fmagieelement, + .data = (enum element_t []) { ELEMENT_FIRE }, + }, { + .name = "Fire +", + .children_cnt = 0, + .f = Fmagieelement, + .data = (enum element_t []) { ELEMENT_FIRE }, + }, { + .name = "Fire x", + .children_cnt = 0, + .f = Fmagieelement, + .data = (enum element_t []) { ELEMENT_FIRE }, + }, { + .name = "Ice -", + .children_cnt = 0, + .f = Fmagieelement, + .data = (enum element_t []) { ELEMENT_ICE }, + }, { + .name = "Ice +", + .children_cnt = 0, + .f = Fmagieelement, + .data = (enum element_t []) { ELEMENT_ICE }, + }, { + .name = "Ice x", + .children_cnt = 0, + .f = Fmagieelement, + .data = (enum element_t []) { ELEMENT_ICE }, + }, { + .name = "Thunder", + .children_cnt = 0, + .f = Fmagieelement, + .data = (enum element_t []) { ELEMENT_THUNDER }, + }, { + .name = "Thunder +", + .children_cnt = 0, + .f = Fmagieelement, + .data = (enum element_t []) { ELEMENT_THUNDER }, + }, { + .name = "Thunder x", + .children_cnt = 0, + .f = Fmagieelement, + .data = (enum element_t []) { ELEMENT_THUNDER }, + }, { + .name = "Water", + .children_cnt = 0, + .f = Fmagieelement, + .data = (enum element_t []) { ELEMENT_WATER }, + }, { + .name = "Water + ", + .children_cnt = 0, + .f = Fmagieelement, + .data = (enum element_t []) { ELEMENT_WATER }, + }, { + .name = "Water x", + .children_cnt = 0, + .f = Fmagieelement, + .data = (enum element_t []) { ELEMENT_WATER }, + }, { + .name = "Choc", + .children_cnt = 0, + .f = Fmagieelement, + .data = (enum element_t []) { ELEMENT_NONE }, + }, +}; + +struct entry_t object_entries[] = { + { + .name = "Potion", + .children_cnt = 0, + .f = Fpotion, + .data = (int []) { POTION }, + }, { + .name = "Potion +", + .children_cnt = 0, + .f = Fpotion, + .data = (int []) { POTIONPLUS }, + }, { + .name = "Ether", + .children_cnt = 0, + .f = Fether, + .data = (int []) { ETHER }, + }, { + .name = "Ether + ", + .children_cnt = 0, + .f = Fether, + .data = (int []) { ETHERPLUS }, + }, +}; + +struct entry_t action_entries_g[] = { + { + .name = "Attack", + .children_cnt = 0, + .f = Fattaquer, + .data = NULL, + }, { + .name = "White Magic", + .children = white_magic_entries, + .children_cnt = countof(white_magic_entries), + }, { + .name = "Black Magic", + .children = black_magic_entries, + .children_cnt = countof(black_magic_entries), + }, { + .name = "Use", + .children = object_entries, + .children_cnt = countof(object_entries), + }, +}; + +#endif /* PRIV_ENTRIES_H */ diff --git a/prototypes.h b/prototypes.h index d377fdf..a33c4ea 100644 --- a/prototypes.h +++ b/prototypes.h @@ -3,6 +3,7 @@ #include "constantes.h" #include "players.h" +#include "entry.h" void Fmenuprincipal (SURFACES *surfaces, POSITIONS *positions); void Fchangersurlignage (int Vmode, SURFACES *surfaces, POSITIONS *positions); @@ -19,14 +20,14 @@ void Fdechargerimages (SURFACES *surfaces); void Finitialiserpositions (POSITIONS *positions, SURFACES *surfaces); /* actions */ -enum action_state_t Fattaquer (SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy); +enum action_state_t Fattaquer (SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, void *data); enum action_state_t Fselectionnermagienoire (SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy); enum action_state_t Fselectionnermagieblanche(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy); enum action_state_t Fselectionnerobjet(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy); -enum action_state_t Fmagieelement (SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, enum element_t); -enum action_state_t Fmagiesoin (SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy); -enum action_state_t Fpotion(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, int type); -enum action_state_t Fether(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, int type); +enum action_state_t Fmagieelement (SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, void *data); +enum action_state_t Fmagiesoin (SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, void *data); +enum action_state_t Fpotion(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, void *data); +enum action_state_t Fether(SURFACES *surfaces,POSITIONS *positions, struct team_t *ally, struct team_t *enemy, void *data); int compute_damages(const struct character_t *src, const struct character_t *target, enum damages_type_t, enum element_t); int compute_cure(const struct character_t *src, const struct character_t *target); @@ -40,6 +41,7 @@ void cure_target_mp(SURFACES *surfaces, POSITIONS *, struct character_t *target, void update_selected_target(SURFACES *surfaces, POSITIONS *positions, struct character_t *); void Fblitteractivedesactive (SURFACES *surfaces,POSITIONS *positions,ENNEMIS ennemis[],int selection); void blit_character_affinities(SURFACES *, POSITIONS *, const struct character_t *); +void update_list_entries(SURFACES *surfaces, POSITIONS *positions, const struct entry_t *entries, int cnt, int selected); void Fchangeractionselectionnee(SURFACES *surfaces, POSITIONS *positions,int selection,int page,int nbactions,int type); void Fblitterpvcible (SURFACES *surfaces,POSITIONS *positions, const struct character_t *); void Fblitterpmcible (SURFACES *surfaces,POSITIONS *positions, const struct character_t *); diff --git a/structures.h b/structures.h index 11a0f76..fa7e5c0 100644 --- a/structures.h +++ b/structures.h @@ -1,6 +1,8 @@ #ifndef STRUCTURES_H #define STRUCTURES_H +#include <SDL/SDL.h> + typedef struct surfaces SURFACES; struct surfaces { |