Object new_ship(void) { Object ship = EMPTY_SHIP; ship.size = ini_val_i("ship_size"); ship.unique.s_data.lives = 2; reset_ship(&ship); return ship; }
static void spawn_new_ship(void) { --gc.ships_left; reset_ship(); gc.multiplier = 1; gc.multiplier_tic_count = 0; last_score_tic = -1; cur_combo = 0; gc.combo_message_tics = -1; }
static void update_inner_state(void) { static int prev_level_tics; inner_state.tics++; switch (inner_state.state) { case IS_WAVE_TITLE: if (inner_state.tics >= WAVE_TITLE_TICS) { set_inner_state(IS_IN_GAME); /* set_inner_state(IS_PRE_WAVE_CLEARED); */ } else { if (inner_state.tics == WAVE_TITLE_TICS/2) { if (!ship.is_alive) spawn_new_ship(); else reset_ship(); } } break; case IS_IN_GAME: level_stat_counters.tics++; game_stat_counters.tics++; if (gc.tics_remaining <= 0) { /* boom. */ hit_ship(&ship.pos, 1.f); trigger_game_over(); } else { gc.tics_remaining--; if (!ship.is_alive) { prev_level_tics = inner_state.tics; set_inner_state(IS_RESPAWNING_SHIP); } else if (!gc.foes_left) { level_stat_counters.waves++; game_stat_counters.waves++; if (gc.tics_remaining > TIME_BONUS_MIN_TICS) gc.score += gc.tics_remaining*TIME_BONUS_PER_TIC; set_inner_state(IS_PRE_WAVE_CLEARED); } else { spawn_new_foes(); } } break; case IS_PRE_WAVE_CLEARED: if (inner_state.tics >= PRE_WAVE_CLEARED_TICS) { gen_ship_implosion(); reset_powerups(); reset_missiles(); reset_bombs(); reset_lasers(); vec2_set(&ship.pos, 0.f, 0.f); /* HACK */ play_fx(FX_WAVE_TRANSITION); set_inner_state(IS_WAVE_CLEARED); } break; case IS_RESPAWNING_SHIP: if (inner_state.tics >= TICS_UNTIL_RESPAWN) { if (gc.ships_left) { spawn_new_ship(); set_inner_state(IS_IN_GAME); inner_state.tics = prev_level_tics; } else { trigger_game_over(); } } break; case IS_GAME_OVER: break; case IS_RANK: if (inner_state.tics >= RANK_TOTAL_TICS) { stop_music(); if (is_highscore(gc.score)) { set_inner_state(IS_HIGHSCORE_INPUT); SDL_ShowCursor(SDL_ENABLE); start_highscore_input(); } else { /* loser. */ SDL_ShowCursor(SDL_ENABLE); start_main_menu(); } } break; case IS_WAVE_CLEARED: if (gc.cur_wave == levels[gc.cur_level]->num_waves - 1 && inner_state.tics >= WAVE_CLEARED_TICS/2) { initialize_stats_table(&level_stat_counters); set_inner_state(IS_LEVEL_CLEARED); } else if (inner_state.tics >= WAVE_CLEARED_TICS) { gc.cur_wave++; assert(gc.cur_wave < levels[gc.cur_level]->num_waves); reset_wave(); set_inner_state(IS_WAVE_TITLE); } break; case IS_HIGHSCORE_INPUT: break; case IS_LEVEL_CLEARED: break; case IS_LEVEL_TRANSITION: if (inner_state.tics >= LEVEL_TRANSITION_TOTAL_TICS) { gc.cur_level = (gc.cur_level + 1)%NUM_LEVELS; set_inner_state(IS_WAVE_TITLE); reset_level(); } break; default: assert(0); } }