end bonus level handling
authormrtout <mrtout@78b8d119-cf0a-0410-b17c-f493084dd1d7>
Wed, 8 Mar 2006 13:43:32 +0000 (13:43 +0000)
committermrtout <mrtout@78b8d119-cf0a-0410-b17c-f493084dd1d7>
Wed, 8 Mar 2006 13:43:32 +0000 (13:43 +0000)
git-svn-id: https://s.snth.net/svn/neverball/trunk@276 78b8d119-cf0a-0410-b17c-f493084dd1d7

ball/level.h
ball/levels.c
ball/levels.h
ball/set.c
ball/st_fail.c
ball/st_goal.c

index 945fca0..338648c 100644 (file)
@@ -84,6 +84,9 @@ struct level_game
     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 */
index 1999347..4be1b9e 100644 (file)
@@ -46,6 +46,8 @@ int level_play_go(void)
     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;
     
@@ -55,7 +57,8 @@ int level_play_go(void)
     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);
 }
@@ -65,28 +68,18 @@ void level_play_single(const char *filename)
 /* 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 = &current_level_game; 
+    memset(lg, 0, sizeof(struct level_game));
+    lg->mode  = m;
+    lg->level = l;
+    lg->balls = 3;
 }
 
 /*---------------------------------------------------------------------------*/
@@ -128,9 +121,12 @@ void level_stop(int state, int state_value, int clock, int coins)
            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 */
@@ -140,13 +136,6 @@ void level_stop(int state, int state_value, int clock, int coins)
     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 = &current_level_game;
index f7c094c..94df642 100644 (file)
@@ -14,13 +14,9 @@ int  level_play_go(void);
 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);
 
 /*---------------------------------------------------------------------------*/
index 2b21312..f7d9f8b 100644 (file)
@@ -559,6 +559,9 @@ void set_finish_level(struct level_game *lg, const char *player)
                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);
@@ -566,9 +569,14 @@ void set_finish_level(struct level_game *lg, const char *player)
     /* 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 */ 
index cecc80c..807088b 100644 (file)
@@ -21,6 +21,7 @@
 
 #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:
@@ -45,8 +49,27 @@ static int fail_action(int i)
 
     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;
@@ -64,21 +87,29 @@ static int fail_buttn(int b, int d)
     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);
         }
 
@@ -86,6 +117,15 @@ static int fall_out_enter(void)
         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);
 
@@ -110,30 +150,7 @@ static void fall_out_timer(int id, float dt)
 
 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);
index 094dbb5..adc7d63 100644 (file)
@@ -149,7 +149,7 @@ static int goal_init(int * gidp)
            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);