int demo_replay_step(float *dt)
{
const float g[3] = { 0.0f, -9.8f, 0.0f };
+ int sv;
if (demo_fp)
{
{
/* 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. */
}
}
-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. */
/* 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;
}
* 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;
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;
}
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);
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 */
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 = ¤t_level_game;
lg->state = state;
lg->coins = coins;
lg->timer = timer;
+ lg->state_value = state_value;
/* Performs challenge mode opperations */
if (mode == MODE_CHALLENGE)
}
/* 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);
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);
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)
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);
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);
{
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
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);
float g[3] = { 0.0f, -9.8f, 0.0f };
- int state;
+ int state, state_value;
at = (7 * at + dt) / 8;
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;
/* 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;
{
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();
}