int coins; /* coins collected */
int timer; /* time elapsed */
int state_value; /* more precision about the state: skip for goal */
+
+ int dead; /* Is the game over and lost? */
+ int win; /* Is the game over and win? */
/* rank = 3 => unclassed */
int coin_rank; /* rank in the level high-scores */
const struct level *l = lg->level;
int mode = lg->mode;
+ assert(l != NULL);
+
lg->goal = (mode == MODE_PRACTICE) ? 0 : l->goal;
lg->time = (mode == MODE_PRACTICE) ? 0 : l->time;
lg->timer = lg->time;
lg->coin_rank = lg->goal_rank = lg->time_rank =
lg->score_rank = lg-> times_rank = 3;
- lg->next_level = 0;
+ lg->win = lg->dead = 0;
+ lg->next_level = NULL;
return demo_play_init(USER_REPLAY_FILE, l, lg);
}
/* Prepare to play a single level */
{
struct level *l = &single_level;
-
- l->back[0] = '\0';
- l->grad[0] = '\0';
- l->song[0] = '\0';
- l->shot[0] = '\0';
- l->goal = 0;
- l->time = 0;
-
level_load(filename, l);
-
level_play(l, MODE_SINGLE);
}
void level_play(const struct level *l, int m)
/* Prepare to play a level sequence from the `i'th level */
{
- current_level_game.mode = m;
- current_level_game.level = l;
-
- current_level_game.score = 0;
- current_level_game.balls = 3;
- current_level_game.times = 0;
+ struct level_game *lg = ¤t_level_game;
+ memset(lg, 0, sizeof(struct level_game));
+ lg->mode = m;
+ lg->level = l;
+ lg->balls = 3;
}
/*---------------------------------------------------------------------------*/
lg->score += coins;
}
- /* lose ball */
+ /* lose ball and game */
if ((state == GAME_TIME || state == GAME_FALL) && !lg->level->is_bonus)
+ {
lg->balls--;
+ lg->dead = (lg->balls <= 0);
+ }
}
/* Update high-scores and next level */
demo_play_stop(lg);
}
-int level_dead(void)
-{
- int mode = current_level_game.mode;
- int balls = current_level_game.balls;
- return (mode == MODE_CHALLENGE) && (balls <= 0);
-}
-
void level_next(void)
{
struct level_game *lg = ¤t_level_game;
void level_next(void);
void level_stop(int, int, int, int);
-int level_dead(void);
int count_extra_balls(int, int);
-int level_sort(int *, int *);
-int level_done(int *, int *);
-
void level_update_player_name(void);
/*---------------------------------------------------------------------------*/
if(nl->is_bonus && nl->is_locked && lg->mode != MODE_CHALLENGE)
nl = next_normal_level(nl->number);
}
+ else if (lg->mode == MODE_CHALLENGE)
+ /* Win! */
+ lg->win = 1;
}
} else if (cl->is_bonus)
nl = next_normal_level(ln);
/* unlock the next level if needed */
if(nl != NULL && nl->is_locked)
{
- nl->is_locked = 0;
- s->locked -= 1;
- dirty = 1;
+ if (lg->mode == MODE_CHALLENGE || lg->mode == MODE_NORMAL)
+ {
+ nl->is_locked = 0;
+ s->locked -= 1;
+ dirty = 1;
+ }
+ else
+ nl = NULL;
}
/* got the next level */
#include "st_fail.h"
#include "st_over.h"
+#include "st_done.h"
#include "st_save.h"
#include "st_level.h"
#include "st_start.h"
#define FAIL_OVER 1
#define FAIL_RETRY 2
#define FAIL_SAVE 3
+#define FAIL_NEXT 4
+#define FAIL_DONE 5
static int fail_action(int i)
{
- struct state * next = level_dead() ? &st_over : &st_level;
+ struct state *next;
+ const struct level_game *lg = curr_lg();
switch (i)
{
case FAIL_BACK:
case FAIL_RETRY:
return goto_state(&st_level);
+
+ case FAIL_DONE:
+ return goto_state(&st_over);
+
+ case FAIL_NEXT:
+ level_next();
+ return goto_state(&st_level);
case FAIL_SAVE:
+ if (lg->next_level)
+ {
+ level_next();
+ next = &st_level;
+ }
+ else if (lg->dead)
+ next = &st_over;
+ else if (lg->win)
+ next = &st_done;
+ else
+ next = &st_level;
+
return goto_save(next, next);
}
return 1;
return 1;
}
-static int fall_out_enter(void)
+static int gui_fail(const char *title)
{
int id, jd, kd;
+ const struct level_game *lg = curr_lg();
if ((id = gui_vstack(0)))
{
- kd = gui_label(id, _("Fall-out!"), GUI_LRG, GUI_ALL, gui_gry, gui_red);
+ kd = gui_label(id, title, GUI_LRG, GUI_ALL, gui_gry, gui_red);
if ((jd = gui_harray(id)))
{
gui_state(jd, _("Save Replay"), GUI_SML, FAIL_SAVE, 0);
- if (level_dead())
+ if (lg->next_level != NULL && lg->mode != MODE_CHALLENGE)
+ gui_state(jd, _("Retry Level"), GUI_SML, FAIL_RETRY, 0);
+
+ if (lg->dead)
gui_start(jd, _("Game Over"), GUI_SML, FAIL_OVER, 0);
- else
+ else if (lg->win)
+ gui_start(jd, _("Finish"), GUI_SML, FAIL_DONE, 0);
+ else if (lg->next_level != NULL)
+ gui_start(jd, _("Next Level"), GUI_SML, FAIL_NEXT, 0);
+ else
gui_start(jd, _("Retry Level"), GUI_SML, FAIL_RETRY, 0);
}
gui_layout(id, 0, 0);
}
+ return id;
+}
+
+/*---------------------------------------------------------------------------*/
+
+static int fall_out_enter(void)
+{
+ int id = gui_fail(_("Fall-out!"));
+
audio_music_fade_out(2.0f);
audio_play(AUD_FALL, 1.0f);
static int time_out_enter(void)
{
- int id, jd, kd;
-
- if ((id = gui_vstack(0)))
- {
- kd = gui_label(id, _("Time's Up!"), GUI_LRG, GUI_ALL, gui_gry, gui_red);
-
- if ((jd = gui_harray(id)))
- {
- gui_state(jd, _("Save Replay"), GUI_SML, FAIL_SAVE, 0);
-
- if (curr_lg()->level->is_bonus)
- {
-
- }
-
- if (level_dead())
- gui_start(jd, _("Game Over"), GUI_SML, FAIL_OVER, 0);
- else
- gui_start(jd, _("Retry Level"), GUI_SML, FAIL_RETRY, 0);
- }
-
- gui_pulse(kd, 1.2f);
- gui_layout(id, 0, 0);
- }
+ int id = gui_fail(_("Time's Up!"));
audio_music_fade_out(2.0f);
audio_play(AUD_TIME, 1.0f);
if (mode != MODE_CHALLENGE)
gui_start(jd, _("Retry Level"), GUI_SML, GOAL_SAME, 0);
- if (mode == MODE_CHALLENGE && lg->next_level == NULL)
+ if (lg->win)
gui_start(jd, _("Finish"), GUI_SML, GOAL_DONE, 0);
else if (lg->next_level != NULL)
gui_state(jd, _("Next Level"), GUI_SML, GOAL_NEXT, 0);