take accout of goal skip value and improve next_level computation
authormrtout <mrtout@78b8d119-cf0a-0410-b17c-f493084dd1d7>
Wed, 8 Mar 2006 11:22:40 +0000 (11:22 +0000)
committermrtout <mrtout@78b8d119-cf0a-0410-b17c-f493084dd1d7>
Wed, 8 Mar 2006 11:22:40 +0000 (11:22 +0000)
git-svn-id: https://s.snth.net/svn/neverball/trunk@271 78b8d119-cf0a-0410-b17c-f493084dd1d7

ball/demo.c
ball/game.c
ball/game.h
ball/level.h
ball/levels.c
ball/levels.h
ball/set.c
ball/st_demo.c
ball/st_fail.c
ball/st_goal.c
ball/st_play.c

index ca52588..e9db52a 100644 (file)
@@ -441,6 +441,7 @@ int demo_replay_init(const char *name, struct level_game *lg)
 int demo_replay_step(float *dt)
 {
     const float g[3] = { 0.0f, -9.8f, 0.0f };
+    int sv;
 
     if (demo_fp)
     {
@@ -450,7 +451,7 @@ int demo_replay_step(float *dt)
         {
             /* Play out current game state for particles, clock, etc. */
 
-            game_step(g, *dt, 1);
+            game_step(g, *dt, &sv);
 
             /* Load real current game state from file. */
             
index 3f7890f..35a4601 100644 (file)
@@ -621,11 +621,12 @@ static void game_update_time(float dt, int b)
     }
 }
 
-static int game_update_state(int bt)
+static int game_update_state(int *state_value)
 {
     struct s_file *fp = &file;
     float p[3];
     float c[3];
+    int bt = state_value != NULL;
     int n, e = swch_e;
 
     /* Test for a coin grab. */
@@ -672,8 +673,9 @@ static int game_update_state(int bt)
 
     /* Test for a goal. */
 
-    if (bt && goal_c == 0 && sol_goal_test(fp, p, 0))
+    if (bt && goal_c == 0 && (n = sol_goal_test(fp, p, 0)))
     {
+       *state_value = n - 1;
        audio_play(AUD_GOAL, 1.0f);
         return GAME_GOAL;
     }
@@ -706,7 +708,7 @@ static int game_update_state(int bt)
  * graphics frame rate.
  */
 
-int game_step(const float g[3], float dt, int bt)
+int game_step(const float g[3], float dt, int *state_value)
 {
     struct s_file *fp = &file;
 
@@ -773,9 +775,9 @@ int game_step(const float g[3], float dt, int bt)
 
         game_step_fade(dt);
         game_update_view(dt);
-        game_update_time(dt, bt);
+        game_update_time(dt, state_value != NULL);
 
-        return game_update_state(bt);
+        return game_update_state(state_value);
     }
     return GAME_NONE;
 }
index 2e9f5d8..7a74aed 100644 (file)
@@ -45,7 +45,7 @@ int   curr_coins(void);
 int   curr_goal(void);
 
 void  game_draw(int, float);
-int   game_step(const float[3], float, int);
+int   game_step(const float[3], float, int *);
 
 void  game_set_pos(int, int);
 void  game_set_x  (int);
index 4e30a6e..945fca0 100644 (file)
@@ -83,6 +83,7 @@ struct level_game
     int state;         /* state ending */
     int coins;         /* coins collected */
     int timer;         /* time elapsed */
+    int state_value;   /* more precision about the state: skip for goal */
     
     /* rank = 3  => unclassed */
     int coin_rank;     /* rank in the level high-scores */
index c25ef7b..1999347 100644 (file)
@@ -103,7 +103,7 @@ int count_extra_balls(int old_score, int coins)
     return sum / 100;
 }
 
-void level_stop(int state, int clock, int coins)
+void level_stop(int state, int state_value, int clock, int coins)
 /* Stop the current playing level */
 {
     struct level_game * lg = &current_level_game;
@@ -113,6 +113,7 @@ void level_stop(int state, int clock, int coins)
     lg->state = state;
     lg->coins = coins;
     lg->timer = timer;
+    lg->state_value = state_value; 
    
     /* Performs challenge mode opperations */ 
     if (mode == MODE_CHALLENGE)
@@ -128,15 +129,12 @@ void level_stop(int state, int clock, int coins)
        }
 
        /* lose ball */
-        if (state == GAME_TIME || state == GAME_FALL)
+        if ((state == GAME_TIME || state == GAME_FALL) && !lg->level->is_bonus)
            lg->balls--;
     }
     
     /* Update high-scores and next level */
-    if (state == GAME_GOAL && curr_set())
-       set_finish_level(lg, config_simple_get_s(CONFIG_PLAYER));
-    else
-       lg->next_level = NULL;
+    set_finish_level(lg, config_simple_get_s(CONFIG_PLAYER));
 
     /* stop demo recording */  
     demo_play_stop(lg);
index de59a7b..f7c094c 100644 (file)
@@ -13,7 +13,7 @@ void level_play(const struct level *, int);
 int  level_play_go(void);
 void level_next(void);
 
-void level_stop(int, int, int);
+void level_stop(int, int, int, int);
 int  level_dead(void);
 
 int  count_extra_balls(int, int);
index fd172a3..2b21312 100644 (file)
@@ -498,49 +498,81 @@ void score_change_name(struct level_game *lg, const char *player)
     set_store_hs();
 }
 
+static struct level *next_level(int i)
+{
+/* Return the ith level, or NULL */
+    return set_level_exists(current_set, i) ? &level_v[i] : NULL;
+}
+
+static struct level *next_normal_level(int i)
+/* Return the next notmal level (starting for i) 
+ * Return NULL if there is not a such level */
+{
+    for (; i < current_set->count; i++)
+       if (!level_v[i].is_bonus)
+           return &level_v[i];
+    return NULL;
+}
+
 void set_finish_level(struct level_game *lg, const char *player)
 /* Inform the set that a level is finished. 
  * Update next_level and score rank fields */
 {
     struct set *s = current_set;
-    int level = lg->level->number;
-    int dirty = 0;
+    int ln = lg->level->number;     /* curent level number */
+    struct level *cl = &level_v[ln]; /* current level */
+    struct level *nl = NULL;        /* next level*/
+    int dirty = 0;                  /* HS should be saved? */
+
+    assert(s == cl->set);
+
+    /* On success */
+    if (lg->state == GAME_GOAL)
+    {      
+       /* Update scores */
+       dirty = level_score_update(lg, player);
+       dirty = set_score_update(lg, player) || dirty;
+       
+       /* if no set, no next level */    
+       if (s == NULL)
+       {
+           /* if no set, return */
+           lg->next_level = NULL;
+           return;
+       }
 
-    /* Complete the level */
-    if (!lg->level->is_completed)
-    {
-       level_v[level].is_completed = 1;
-       s->completed += 1;
-    }
-    
-    /* Update scores */
-    dirty = level_score_update(lg, player);
-    dirty = set_score_update(lg, player) || dirty;
-    
-    /* compute the next level */    
-    if (s == NULL)
+       if (lg->mode == MODE_CHALLENGE || lg->mode == MODE_NORMAL)
+       {
+           /* Complete the level */
+           if (!cl->is_completed)
+           {
+               cl->is_completed = 1;
+               s->completed += 1;
+               dirty = 1;
+           }
+
+           /* Identify the follwing level */
+           nl = next_level(ln + lg->state_value + 1);
+           if (nl != NULL)
+           {
+               /* skip bonuses if unlocked in non challenge mode*/
+               if(nl->is_bonus && nl->is_locked && lg->mode != MODE_CHALLENGE)
+                   nl = next_normal_level(nl->number);
+           }
+       }
+    } else if (cl->is_bonus)
+       nl = next_normal_level(ln);
+   
+    /* unlock the next level if needed */
+    if(nl != NULL && nl->is_locked)
     {
-        /* if no set, return */
-       lg->next_level = NULL;
-       return;
+       nl->is_locked = 0;
+       s->locked -= 1;
+       dirty = 1;
     }
-   
-    level++; /* level is the next level */
     
-    /* if the next level is not oppened */
-    if (level < s->count && level_v[level].is_locked)
-        if ((lg->mode == MODE_CHALLENGE) || (lg->mode == MODE_NORMAL))
-       {
-           level_v[level].is_locked = 0;
-           s->locked -= 1;
-           dirty = 1;
-       }      
-   
     /* got the next level */ 
-    if (level < s->count && !level_v[level].is_locked)
-       lg->next_level = &level_v[level];
-    else
-       lg->next_level = NULL;
+    lg->next_level = nl;
 
     /* Update file */
     if (dirty)
index 1c51c4f..7349096 100644 (file)
@@ -426,7 +426,7 @@ static void demo_end_timer(int id, float dt)
     float g[3] = { 0.0f, -9.8f, 0.0f };
 
     if (time_state() < 2.f)
-       game_step(g, dt, 0);
+       game_step(g, dt, NULL);
                
     gui_timer(id, dt);
     audio_timer(dt);
index 13b9f7b..cecc80c 100644 (file)
@@ -99,7 +99,7 @@ static void fall_out_timer(int id, float dt)
     float g[3] = { 0.0f, -9.8f, 0.0f };
 
     if (time_state() < 2.f)
-        game_step(g, dt, 0);
+        game_step(g, dt, NULL);
 
     gui_timer(id, dt);
     audio_timer(dt);
@@ -120,6 +120,11 @@ static int time_out_enter(void)
         {
             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
index f195e1e..094dbb5 100644 (file)
@@ -202,7 +202,7 @@ static void goal_timer(int id, float dt)
     DT += dt;
 
     if (time_state() < 1.f)
-        game_step(g, dt, 0);
+        game_step(g, dt, NULL);
     else if (DT > 0.05f && curr_lg()->mode == MODE_CHALLENGE)
     {
        int coins = gui_value(coins_id);
index b413f6b..db3f54f 100644 (file)
@@ -181,7 +181,7 @@ static void play_loop_timer(int id, float dt)
 
     float g[3] = { 0.0f, -9.8f, 0.0f };
 
-    int state;
+    int state, state_value;
     
     at = (7 * at + dt) / 8;
 
@@ -189,10 +189,10 @@ static void play_loop_timer(int id, float dt)
     hud_timer(at);
     game_set_rot(view_rotate * k);
 
-    state = game_step(g, at, 1);
+    state = game_step(g, at, &state_value);
     if (state)
     {
-       level_stop(state, curr_clock(), curr_coins());
+       level_stop(state, state_value, curr_clock(), curr_coins());
        switch (state)
        {
        case GAME_TIME: goto_state(&st_time_out); break;
@@ -264,7 +264,7 @@ static int play_loop_keybd(int c, int d)
     /* Cheat */
     if (d && c == SDLK_c && config_get_d(CONFIG_CHEAT))
     {
-        level_stop(GAME_GOAL, curr_clock(), curr_coins());
+        level_stop(GAME_GOAL, 0, curr_clock(), curr_coins());
         return goto_state(&st_goal);
     }
     return 1;
@@ -276,7 +276,7 @@ static int play_loop_buttn(int b, int d)
     {
         if (config_tst_d(CONFIG_JOYSTICK_BUTTON_EXIT, b))
        {
-           level_stop(GAME_NONE, curr_clock(), curr_coins());
+           level_stop(GAME_NONE, 0, curr_clock(), curr_coins());
             return abort_play();
        }