{ EL_UNDEFINED, MV_NONE }
};
+static struct XY xy_topdown[] =
+{
+ { 0, -1 },
+ { -1, 0 },
+ { +1, 0 },
+ { 0, +1 }
+};
+
static boolean trigger_events[MAX_NUM_ELEMENTS][NUM_CHANGE_EVENTS];
#define IS_AUTO_CHANGING(e) (element_info[e].has_change_event[CE_DELAY])
player->active = TRUE;
// remove potentially duplicate players
- if (StorePlayer[jx][jy] == Tile[x][y])
+ if (IN_LEV_FIELD(jx, jy) && StorePlayer[jx][jy] == Tile[x][y])
StorePlayer[jx][jy] = 0;
StorePlayer[x][y] = Tile[x][y];
game_sp.time_played :
level.game_engine_type == GAME_ENGINE_TYPE_MM ?
game_mm.energy_left :
- game.no_time_limit ? TimePlayed : TimeLeft);
+ game.no_level_time_limit ? TimePlayed : TimeLeft);
int score = (game.LevelSolved ?
game.LevelSolved_CountingScore :
level.game_engine_type == GAME_ENGINE_TYPE_EM ?
int element = gpc->value;
int graphic = el2panelimg(element);
int init_gfx_random = (graphic_info[graphic].anim_global_sync ?
- sync_random_frame : INIT_GFX_RANDOM());
+ sync_random_frame :
+ graphic_info[graphic].anim_global_anim_sync ?
+ getGlobalAnimSyncFrame() : INIT_GFX_RANDOM());
if (gpc->value != gpc->last_value)
{
int last_anim_random_frame = gfx.anim_random_frame;
int graphic = gpc->graphic;
int init_gfx_random = (graphic_info[graphic].anim_global_sync ?
- sync_random_frame : INIT_GFX_RANDOM());
+ sync_random_frame :
+ graphic_info[graphic].anim_global_anim_sync ?
+ getGlobalAnimSyncFrame() : INIT_GFX_RANDOM());
if (gpc->value != gpc->last_value)
{
int full_lev_fieldx = lev_fieldx + (BorderElement != EL_EMPTY ? 2 : 0);
int full_lev_fieldy = lev_fieldy + (BorderElement != EL_EMPTY ? 2 : 0);
int fade_mask = REDRAW_FIELD;
-
+ boolean restarting = (game_status == GAME_MODE_PLAYING);
boolean emulate_bd = TRUE; // unless non-BOULDERDASH elements found
boolean emulate_sp = TRUE; // unless non-SUPAPLEX elements found
int initial_move_dir = MV_DOWN;
if (!game.restart_level)
CloseDoor(DOOR_CLOSE_1);
- SetGameStatus(GAME_MODE_PLAYING);
+ if (restarting)
+ {
+ // force fading out global animations displayed during game play
+ SetGameStatus(GAME_MODE_PSEUDO_RESTARTING);
+ }
+ else
+ {
+ SetGameStatus(GAME_MODE_PLAYING);
+ }
if (level_editor_test_game)
FadeSkipNextFadeOut();
FadeOut(fade_mask);
+ if (restarting)
+ {
+ // force restarting global animations displayed during game play
+ RestartGlobalAnimsByStatus(GAME_MODE_PSEUDO_RESTARTING);
+
+ SetGameStatus(GAME_MODE_PLAYING);
+ }
+
if (level_editor_test_game)
FadeSkipNextFadeIn();
player->can_fall_into_acid = CAN_MOVE_INTO_ACID(player->element_nr);
- player->actual_frame_counter = 0;
+ player->actual_frame_counter.count = 0;
+ player->actual_frame_counter.value = 1;
player->step_counter = 0;
game.panel.active = TRUE;
- game.no_time_limit = (level.time == 0);
+ game.no_level_time_limit = (level.time == 0);
+ game.time_limit = (leveldir_current->time_limit && setup.time_limit);
game.yamyam_content_nr = 0;
game.robot_wheel_active = FALSE;
}
game.restart_level = FALSE;
- game.restart_game_message = NULL;
game.request_active = FALSE;
game.request_active_or_moving = FALSE;
static void LevelSolved_SetFinalGameValues(void)
{
- game.time_final = (game.no_time_limit ? TimePlayed : TimeLeft);
+ game.time_final = (game.no_level_time_limit ? TimePlayed : TimeLeft);
game.score_time_final = (level.use_step_counter ? TimePlayed :
TimePlayed * FRAMES_PER_SECOND + TimeFrames);
game.LevelSolved = TRUE;
game.GameOver = TRUE;
+ tape.solved = TRUE;
+
// needed here to display correct panel values while player walks into exit
LevelSolved_SetFinalGameValues();
}
time_final = 0;
time_frames = time_frames_left;
}
- else if (game.no_time_limit && TimePlayed < time_final_max)
+ else if (game.no_level_time_limit && TimePlayed < time_final_max)
{
time_final = time_final_max;
time_frames = time_frames_final_max - time_frames_played;
game.LevelSolved_GameEnd = TRUE;
- if (game.LevelSolved_SaveTape)
+ if (game.LevelSolved_SaveTape && !score_info_tape_play)
{
// make sure that request dialog to save tape does not open door again
if (!global.use_envelope_request)
// if no tape is to be saved, close both doors simultaneously
CloseDoor(DOOR_CLOSE_ALL);
- if (level_editor_test_game)
+ if (level_editor_test_game || score_info_tape_play)
{
SetGameStatus(GAME_MODE_MAIN);
if (setup.auto_play_next_level)
{
+ scores.continue_playing = TRUE;
+ scores.next_level_nr = level_nr;
+
LoadLevel(level_nr);
SaveLevelSetup_SeriesInfo();
DrawHallOfFame(last_level_nr);
}
- else if (setup.auto_play_next_level && setup.increment_levels &&
- last_level_nr < leveldir_current->last_level &&
- !network_playing)
+ else if (scores.continue_playing)
{
StartGameActions(network.enabled, setup.autorecord, level.random_seed);
}
if (strEqual(new_entry->tape_basename, entry->tape_basename) &&
!strEqual(new_entry->tape_basename, UNDEFINED_FILENAME))
{
- // special case: use server score instead of local score value if higher
- // (historic scores might have been truncated to 16-bit values locally)
- if (score_is_better)
- entry->score = new_entry->score;
+ // add fields from server score entry not stored in local score entry
+ // (currently, this means setting platform, version and country fields;
+ // in rare cases, this may also correct an invalid score value, as
+ // historic scores might have been truncated to 16-bit values locally)
+ *entry = *new_entry;
return -1;
}
}
}
- return -1;
+ // special case: new score is beyond the last high score list position
+ return MAX_SCORE_ENTRIES;
}
void NewHighScore(int level_nr, boolean tape_saved)
scores.last_added = addScoreEntry(&scores, &new_entry, one_per_name);
+ if (scores.last_added >= MAX_SCORE_ENTRIES)
+ {
+ scores.last_added = MAX_SCORE_ENTRIES - 1;
+ scores.force_last_added = TRUE;
+
+ scores.entry[scores.last_added] = new_entry;
+
+ // store last added local score entry (before merging server scores)
+ scores.last_added_local = scores.last_added;
+
+ return;
+ }
+
if (scores.last_added < 0)
return;
if (graphic_info[graphic].anim_global_sync)
GfxFrame[x][y] = FrameCounter;
+ else if (graphic_info[graphic].anim_global_anim_sync)
+ GfxFrame[x][y] = getGlobalAnimSyncFrame();
else if (ANIM_MODE(graphic) == ANIM_CE_VALUE)
GfxFrame[x][y] = CustomValue[x][y];
else if (ANIM_MODE(graphic) == ANIM_CE_SCORE)
*sy = (sy1 + sy2) / 2;
}
-static void DrawRelocateScreen(int old_x, int old_y, int x, int y, int move_dir,
+static void DrawRelocateScreen(int old_x, int old_y, int x, int y,
boolean center_screen, boolean quick_relocation)
{
unsigned int frame_delay_value_old = GetVideoFrameDelay();
}
// only visually relocate centered player
- DrawRelocateScreen(old_jx, old_jy, player->jx, player->jy, player->MovDir,
+ DrawRelocateScreen(old_jx, old_jy, player->jx, player->jy,
FALSE, level.instant_relocation);
TestIfPlayerTouchesBadThing(jx, jy);
int last_phase;
int border_element;
- // !!! eliminate this variable !!!
- int delay = (game.emulation == EMU_SUPAPLEX ? 3 : 2);
-
if (game.explosions_delayed)
{
ExplodeField[ex][ey] = mode;
int graphic = el_act2img(GfxElement[x][y], ACTION_EXPLODING);
int frame = getGraphicAnimationFrameXY(graphic, x, y);
- if (phase == delay)
+ if (phase == 1)
TEST_DrawLevelFieldCrumbled(x, y);
if (IS_WALKABLE_OVER(Back[x][y]) && Back[x][y] != EL_EMPTY)
int dynabomb_size = 1;
boolean dynabomb_xl = FALSE;
struct PlayerInfo *player;
- static int xy[4][2] =
- {
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- { 0, +1 }
- };
+ struct XY *xy = xy_topdown;
if (IS_ACTIVE_BOMB(dynabomb_element))
{
{
for (j = 1; j <= dynabomb_size; j++)
{
- int x = ex + j * xy[i][0];
- int y = ey + j * xy[i][1];
+ int x = ex + j * xy[i].x;
+ int y = ey + j * xy[i].y;
int element;
if (!IN_LEV_FIELD(x, y) || IS_INDESTRUCTIBLE(Tile[x][y]))
}
}
-static void ToggleSwitchgateSwitch(int x, int y)
+static void ToggleSwitchgateSwitch(void)
{
int xx, yy;
smashed == EL_DC_SWITCHGATE_SWITCH_UP ||
smashed == EL_DC_SWITCHGATE_SWITCH_DOWN)
{
- ToggleSwitchgateSwitch(x, y + 1);
+ ToggleSwitchgateSwitch();
}
else if (smashed == EL_LIGHT_SWITCH ||
smashed == EL_LIGHT_SWITCH_ACTIVE)
if (element == EL_PENGUIN)
{
int i;
- static int xy[4][2] =
- {
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- { 0, +1 }
- };
+ struct XY *xy = xy_topdown;
for (i = 0; i < NUM_DIRECTIONS; i++)
{
- int ex = x + xy[i][0];
- int ey = y + xy[i][1];
+ int ex = x + xy[i].x;
+ int ey = y + xy[i].y;
if (IN_LEV_FIELD(ex, ey) && (Tile[ex][ey] == EL_EXIT_OPEN ||
Tile[ex][ey] == EL_EM_EXIT_OPEN ||
}
else if (move_pattern & MV_MAZE_RUNNER_STYLE)
{
- static int test_xy[7][2] =
- {
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- { 0, +1 },
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- };
- static int test_dir[7] =
+ struct XY *test_xy = xy_topdown;
+ static int test_dir[4] =
{
MV_UP,
MV_LEFT,
MV_RIGHT,
- MV_DOWN,
- MV_UP,
- MV_LEFT,
- MV_RIGHT,
+ MV_DOWN
};
boolean hunter_mode = (move_pattern == MV_MAZE_HUNTER);
int move_preference = -1000000; // start with very low preference
for (i = 0; i < NUM_DIRECTIONS; i++)
{
- int move_dir = test_dir[start_test + i];
+ int j = (start_test + i) % 4;
+ int move_dir = test_dir[j];
int move_dir_preference;
- xx = x + test_xy[start_test + i][0];
- yy = y + test_xy[start_test + i][1];
+ xx = x + test_xy[j].x;
+ yy = y + test_xy[j].y;
if (hunter_mode && IN_LEV_FIELD(xx, yy) &&
(IS_PLAYER(xx, yy) || Tile[xx][yy] == EL_PLAYER_IS_LEAVING))
int i;
int element = Tile[ax][ay];
int group_nr = 0;
- static int xy[4][2] =
- {
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- { 0, +1 }
- };
+ struct XY *xy = xy_topdown;
for (i = 0; i < NUM_DIRECTIONS; i++)
{
- int x = ax + xy[i][0];
- int y = ay + xy[i][1];
+ int x = ax + xy[i].x;
+ int y = ay + xy[i].y;
if (!IN_LEV_FIELD(x, y))
continue;
{
int i, x, y, xx, yy;
int new_group_nr = AmoebaNr[ax][ay];
- static int xy[4][2] =
- {
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- { 0, +1 }
- };
+ struct XY *xy = xy_topdown;
if (new_group_nr == 0)
return;
for (i = 0; i < NUM_DIRECTIONS; i++)
{
- x = ax + xy[i][0];
- y = ay + xy[i][1];
+ x = ax + xy[i].x;
+ y = ay + xy[i].y;
if (!IN_LEV_FIELD(x, y))
continue;
}
else
{
- static int xy[4][2] =
- {
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- { 0, +1 }
- };
+ struct XY *xy = xy_topdown;
for (i = 0; i < NUM_DIRECTIONS; i++)
{
- x = ax + xy[i][0];
- y = ay + xy[i][1];
+ x = ax + xy[i].x;
+ y = ay + xy[i].y;
if (!IN_LEV_FIELD(x, y))
continue;
static void AmoebaGrowing(int x, int y)
{
- static unsigned int sound_delay = 0;
- static unsigned int sound_delay_value = 0;
+ static DelayCounter sound_delay = { 0 };
if (!MovDelay[x][y]) // start new growing cycle
{
MovDelay[x][y] = 7;
- if (DelayReached(&sound_delay, sound_delay_value))
+ if (DelayReached(&sound_delay))
{
PlayLevelSoundElementAction(x, y, Store[x][y], ACTION_GROWING);
- sound_delay_value = 30;
+ sound_delay.value = 30;
}
}
static void AmoebaShrinking(int x, int y)
{
- static unsigned int sound_delay = 0;
- static unsigned int sound_delay_value = 0;
+ static DelayCounter sound_delay = { 0 };
if (!MovDelay[x][y]) // start new shrinking cycle
{
MovDelay[x][y] = 7;
- if (DelayReached(&sound_delay, sound_delay_value))
- sound_delay_value = 30;
+ if (DelayReached(&sound_delay))
+ sound_delay.value = 30;
}
if (MovDelay[x][y]) // wait some time before shrinking
int graphic = el2img(element);
int newax = ax, neway = ay;
boolean can_drop = (element == EL_AMOEBA_WET || element == EL_EMC_DRIPPER);
- static int xy[4][2] =
- {
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- { 0, +1 }
- };
+ struct XY *xy = xy_topdown;
if (!level.amoeba_speed && element != EL_EMC_DRIPPER)
{
if (can_drop) // EL_AMOEBA_WET or EL_EMC_DRIPPER
{
int start = RND(4);
- int x = ax + xy[start][0];
- int y = ay + xy[start][1];
+ int x = ax + xy[start].x;
+ int y = ay + xy[start].y;
if (!IN_LEV_FIELD(x, y))
return;
for (i = 0; i < NUM_DIRECTIONS; i++)
{
int j = (start + i) % 4;
- int x = ax + xy[j][0];
- int y = ay + xy[j][1];
+ int x = ax + xy[j].x;
+ int y = ay + xy[j].y;
if (!IN_LEV_FIELD(x, y))
continue;
}
}
-static void MauerWaechst(int x, int y)
+static void WallGrowing(int x, int y)
{
int delay = 6;
}
}
-static void MauerAbleger(int ax, int ay)
+static void CheckWallGrowing(int ax, int ay)
{
int element = Tile[ax][ay];
int graphic = el2img(element);
- boolean oben_frei = FALSE, unten_frei = FALSE;
- boolean links_frei = FALSE, rechts_frei = FALSE;
- boolean oben_massiv = FALSE, unten_massiv = FALSE;
- boolean links_massiv = FALSE, rechts_massiv = FALSE;
- boolean new_wall = FALSE;
+ boolean free_top = FALSE;
+ boolean free_bottom = FALSE;
+ boolean free_left = FALSE;
+ boolean free_right = FALSE;
+ boolean stop_top = FALSE;
+ boolean stop_bottom = FALSE;
+ boolean stop_left = FALSE;
+ boolean stop_right = FALSE;
+ boolean new_wall = FALSE;
+
+ boolean is_steelwall = (element == EL_EXPANDABLE_STEELWALL_HORIZONTAL ||
+ element == EL_EXPANDABLE_STEELWALL_VERTICAL ||
+ element == EL_EXPANDABLE_STEELWALL_ANY);
+
+ boolean grow_vertical = (element == EL_EXPANDABLE_WALL_VERTICAL ||
+ element == EL_EXPANDABLE_WALL_ANY ||
+ element == EL_EXPANDABLE_STEELWALL_VERTICAL ||
+ element == EL_EXPANDABLE_STEELWALL_ANY);
+
+ boolean grow_horizontal = (element == EL_EXPANDABLE_WALL_HORIZONTAL ||
+ element == EL_EXPANDABLE_WALL_ANY ||
+ element == EL_EXPANDABLE_WALL ||
+ element == EL_BD_EXPANDABLE_WALL ||
+ element == EL_EXPANDABLE_STEELWALL_HORIZONTAL ||
+ element == EL_EXPANDABLE_STEELWALL_ANY);
+
+ boolean stop_vertical = (element == EL_EXPANDABLE_WALL_VERTICAL ||
+ element == EL_EXPANDABLE_STEELWALL_VERTICAL);
+
+ boolean stop_horizontal = (element == EL_EXPANDABLE_WALL_HORIZONTAL ||
+ element == EL_EXPANDABLE_WALL ||
+ element == EL_EXPANDABLE_STEELWALL_HORIZONTAL);
+
+ int wall_growing = (is_steelwall ?
+ EL_EXPANDABLE_STEELWALL_GROWING :
+ EL_EXPANDABLE_WALL_GROWING);
+
+ int gfx_wall_growing_up = (is_steelwall ?
+ IMG_EXPANDABLE_STEELWALL_GROWING_UP :
+ IMG_EXPANDABLE_WALL_GROWING_UP);
+ int gfx_wall_growing_down = (is_steelwall ?
+ IMG_EXPANDABLE_STEELWALL_GROWING_DOWN :
+ IMG_EXPANDABLE_WALL_GROWING_DOWN);
+ int gfx_wall_growing_left = (is_steelwall ?
+ IMG_EXPANDABLE_STEELWALL_GROWING_LEFT :
+ IMG_EXPANDABLE_WALL_GROWING_LEFT);
+ int gfx_wall_growing_right = (is_steelwall ?
+ IMG_EXPANDABLE_STEELWALL_GROWING_RIGHT :
+ IMG_EXPANDABLE_WALL_GROWING_RIGHT);
if (IS_ANIMATED(graphic))
DrawLevelGraphicAnimationIfNeeded(ax, ay, graphic);
}
if (IN_LEV_FIELD(ax, ay - 1) && IS_FREE(ax, ay - 1))
- oben_frei = TRUE;
+ free_top = TRUE;
if (IN_LEV_FIELD(ax, ay + 1) && IS_FREE(ax, ay + 1))
- unten_frei = TRUE;
+ free_bottom = TRUE;
if (IN_LEV_FIELD(ax - 1, ay) && IS_FREE(ax - 1, ay))
- links_frei = TRUE;
+ free_left = TRUE;
if (IN_LEV_FIELD(ax + 1, ay) && IS_FREE(ax + 1, ay))
- rechts_frei = TRUE;
+ free_right = TRUE;
- if (element == EL_EXPANDABLE_WALL_VERTICAL ||
- element == EL_EXPANDABLE_WALL_ANY)
+ if (grow_vertical)
{
- if (oben_frei)
+ if (free_top)
{
- Tile[ax][ay - 1] = EL_EXPANDABLE_WALL_GROWING;
+ Tile[ax][ay - 1] = wall_growing;
Store[ax][ay - 1] = element;
GfxDir[ax][ay - 1] = MovDir[ax][ay - 1] = MV_UP;
- if (IN_SCR_FIELD(SCREENX(ax), SCREENY(ay - 1)))
- DrawLevelGraphic(ax, ay - 1, IMG_EXPANDABLE_WALL_GROWING_UP, 0);
- new_wall = TRUE;
- }
- if (unten_frei)
- {
- Tile[ax][ay + 1] = EL_EXPANDABLE_WALL_GROWING;
- Store[ax][ay + 1] = element;
- GfxDir[ax][ay + 1] = MovDir[ax][ay + 1] = MV_DOWN;
- if (IN_SCR_FIELD(SCREENX(ax), SCREENY(ay + 1)))
- DrawLevelGraphic(ax, ay + 1, IMG_EXPANDABLE_WALL_GROWING_DOWN, 0);
- new_wall = TRUE;
- }
- }
- if (element == EL_EXPANDABLE_WALL_HORIZONTAL ||
- element == EL_EXPANDABLE_WALL_ANY ||
- element == EL_EXPANDABLE_WALL ||
- element == EL_BD_EXPANDABLE_WALL)
- {
- if (links_frei)
- {
- Tile[ax - 1][ay] = EL_EXPANDABLE_WALL_GROWING;
- Store[ax - 1][ay] = element;
- GfxDir[ax - 1][ay] = MovDir[ax - 1][ay] = MV_LEFT;
- if (IN_SCR_FIELD(SCREENX(ax - 1), SCREENY(ay)))
- DrawLevelGraphic(ax - 1, ay, IMG_EXPANDABLE_WALL_GROWING_LEFT, 0);
- new_wall = TRUE;
- }
+ if (IN_SCR_FIELD(SCREENX(ax), SCREENY(ay - 1)))
+ DrawLevelGraphic(ax, ay - 1, gfx_wall_growing_up, 0);
- if (rechts_frei)
- {
- Tile[ax + 1][ay] = EL_EXPANDABLE_WALL_GROWING;
- Store[ax + 1][ay] = element;
- GfxDir[ax + 1][ay] = MovDir[ax + 1][ay] = MV_RIGHT;
- if (IN_SCR_FIELD(SCREENX(ax + 1), SCREENY(ay)))
- DrawLevelGraphic(ax + 1, ay, IMG_EXPANDABLE_WALL_GROWING_RIGHT, 0);
new_wall = TRUE;
}
- }
-
- if (element == EL_EXPANDABLE_WALL && (links_frei || rechts_frei))
- TEST_DrawLevelField(ax, ay);
-
- if (!IN_LEV_FIELD(ax, ay - 1) || IS_WALL(Tile[ax][ay - 1]))
- oben_massiv = TRUE;
- if (!IN_LEV_FIELD(ax, ay + 1) || IS_WALL(Tile[ax][ay + 1]))
- unten_massiv = TRUE;
- if (!IN_LEV_FIELD(ax - 1, ay) || IS_WALL(Tile[ax - 1][ay]))
- links_massiv = TRUE;
- if (!IN_LEV_FIELD(ax + 1, ay) || IS_WALL(Tile[ax + 1][ay]))
- rechts_massiv = TRUE;
-
- if (((oben_massiv && unten_massiv) ||
- element == EL_EXPANDABLE_WALL_HORIZONTAL ||
- element == EL_EXPANDABLE_WALL) &&
- ((links_massiv && rechts_massiv) ||
- element == EL_EXPANDABLE_WALL_VERTICAL))
- Tile[ax][ay] = EL_WALL;
-
- if (new_wall)
- PlayLevelSoundAction(ax, ay, ACTION_GROWING);
-}
-
-static void MauerAblegerStahl(int ax, int ay)
-{
- int element = Tile[ax][ay];
- int graphic = el2img(element);
- boolean oben_frei = FALSE, unten_frei = FALSE;
- boolean links_frei = FALSE, rechts_frei = FALSE;
- boolean oben_massiv = FALSE, unten_massiv = FALSE;
- boolean links_massiv = FALSE, rechts_massiv = FALSE;
- boolean new_wall = FALSE;
-
- if (IS_ANIMATED(graphic))
- DrawLevelGraphicAnimationIfNeeded(ax, ay, graphic);
-
- if (!MovDelay[ax][ay]) // start building new wall
- MovDelay[ax][ay] = 6;
-
- if (MovDelay[ax][ay]) // wait some time before building new wall
- {
- MovDelay[ax][ay]--;
- if (MovDelay[ax][ay])
- return;
- }
-
- if (IN_LEV_FIELD(ax, ay - 1) && IS_FREE(ax, ay - 1))
- oben_frei = TRUE;
- if (IN_LEV_FIELD(ax, ay + 1) && IS_FREE(ax, ay + 1))
- unten_frei = TRUE;
- if (IN_LEV_FIELD(ax - 1, ay) && IS_FREE(ax - 1, ay))
- links_frei = TRUE;
- if (IN_LEV_FIELD(ax + 1, ay) && IS_FREE(ax + 1, ay))
- rechts_frei = TRUE;
- if (element == EL_EXPANDABLE_STEELWALL_VERTICAL ||
- element == EL_EXPANDABLE_STEELWALL_ANY)
- {
- if (oben_frei)
+ if (free_bottom)
{
- Tile[ax][ay - 1] = EL_EXPANDABLE_STEELWALL_GROWING;
- Store[ax][ay - 1] = element;
- GfxDir[ax][ay - 1] = MovDir[ax][ay - 1] = MV_UP;
- if (IN_SCR_FIELD(SCREENX(ax), SCREENY(ay - 1)))
- DrawLevelGraphic(ax, ay - 1, IMG_EXPANDABLE_STEELWALL_GROWING_UP, 0);
- new_wall = TRUE;
- }
- if (unten_frei)
- {
- Tile[ax][ay + 1] = EL_EXPANDABLE_STEELWALL_GROWING;
+ Tile[ax][ay + 1] = wall_growing;
Store[ax][ay + 1] = element;
GfxDir[ax][ay + 1] = MovDir[ax][ay + 1] = MV_DOWN;
+
if (IN_SCR_FIELD(SCREENX(ax), SCREENY(ay + 1)))
- DrawLevelGraphic(ax, ay + 1, IMG_EXPANDABLE_STEELWALL_GROWING_DOWN, 0);
+ DrawLevelGraphic(ax, ay + 1, gfx_wall_growing_down, 0);
+
new_wall = TRUE;
}
}
- if (element == EL_EXPANDABLE_STEELWALL_HORIZONTAL ||
- element == EL_EXPANDABLE_STEELWALL_ANY)
+ if (grow_horizontal)
{
- if (links_frei)
+ if (free_left)
{
- Tile[ax - 1][ay] = EL_EXPANDABLE_STEELWALL_GROWING;
+ Tile[ax - 1][ay] = wall_growing;
Store[ax - 1][ay] = element;
GfxDir[ax - 1][ay] = MovDir[ax - 1][ay] = MV_LEFT;
+
if (IN_SCR_FIELD(SCREENX(ax - 1), SCREENY(ay)))
- DrawLevelGraphic(ax - 1, ay, IMG_EXPANDABLE_STEELWALL_GROWING_LEFT, 0);
+ DrawLevelGraphic(ax - 1, ay, gfx_wall_growing_left, 0);
+
new_wall = TRUE;
}
- if (rechts_frei)
+ if (free_right)
{
- Tile[ax + 1][ay] = EL_EXPANDABLE_STEELWALL_GROWING;
+ Tile[ax + 1][ay] = wall_growing;
Store[ax + 1][ay] = element;
GfxDir[ax + 1][ay] = MovDir[ax + 1][ay] = MV_RIGHT;
+
if (IN_SCR_FIELD(SCREENX(ax + 1), SCREENY(ay)))
- DrawLevelGraphic(ax + 1, ay, IMG_EXPANDABLE_STEELWALL_GROWING_RIGHT, 0);
+ DrawLevelGraphic(ax + 1, ay, gfx_wall_growing_right, 0);
+
new_wall = TRUE;
}
}
+ if (element == EL_EXPANDABLE_WALL && (free_left || free_right))
+ TEST_DrawLevelField(ax, ay);
+
if (!IN_LEV_FIELD(ax, ay - 1) || IS_WALL(Tile[ax][ay - 1]))
- oben_massiv = TRUE;
+ stop_top = TRUE;
if (!IN_LEV_FIELD(ax, ay + 1) || IS_WALL(Tile[ax][ay + 1]))
- unten_massiv = TRUE;
+ stop_bottom = TRUE;
if (!IN_LEV_FIELD(ax - 1, ay) || IS_WALL(Tile[ax - 1][ay]))
- links_massiv = TRUE;
+ stop_left = TRUE;
if (!IN_LEV_FIELD(ax + 1, ay) || IS_WALL(Tile[ax + 1][ay]))
- rechts_massiv = TRUE;
+ stop_right = TRUE;
- if (((oben_massiv && unten_massiv) ||
- element == EL_EXPANDABLE_STEELWALL_HORIZONTAL) &&
- ((links_massiv && rechts_massiv) ||
- element == EL_EXPANDABLE_STEELWALL_VERTICAL))
- Tile[ax][ay] = EL_STEELWALL;
+ if (((stop_top && stop_bottom) || stop_horizontal) &&
+ ((stop_left && stop_right) || stop_vertical))
+ Tile[ax][ay] = (is_steelwall ? EL_STEELWALL : EL_WALL);
if (new_wall)
PlayLevelSoundAction(ax, ay, ACTION_GROWING);
{
int i, j;
boolean dragon_found = FALSE;
- static int xy[4][2] =
- {
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- { 0, +1 }
- };
+ struct XY *xy = xy_topdown;
for (i = 0; i < NUM_DIRECTIONS; i++)
{
for (j = 0; j < 4; j++)
{
- int xx = x + j * xy[i][0], yy = y + j * xy[i][1];
+ int xx = x + j * xy[i].x;
+ int yy = y + j * xy[i].y;
if (IN_LEV_FIELD(xx, yy) &&
(Tile[xx][yy] == EL_FLAMES || Tile[xx][yy] == EL_DRAGON))
{
for (j = 0; j < 3; j++)
{
- int xx = x + j * xy[i][0], yy = y + j * xy[i][1];
-
+ int xx = x + j * xy[i].x;
+ int yy = y + j * xy[i].y;
+
if (IN_LEV_FIELD(xx, yy) && Tile[xx][yy] == EL_FLAMES)
{
Tile[xx][yy] = EL_EMPTY;
static void WarnBuggyBase(int x, int y)
{
int i;
- static int xy[4][2] =
- {
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- { 0, +1 }
- };
+ struct XY *xy = xy_topdown;
for (i = 0; i < NUM_DIRECTIONS; i++)
{
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
+ int xx = x + xy[i].x;
+ int yy = y + xy[i].y;
if (IN_LEV_FIELD(xx, yy) && IS_PLAYER(xx, yy))
{
DisplayGameControlValues();
- if (!TimeLeft && setup.time_limit)
+ if (!TimeLeft && game.time_limit)
for (i = 0; i < MAX_PLAYERS; i++)
KillPlayer(&stored_player[i]);
}
{
TimeLeft--;
- if (TimeLeft <= 10 && setup.time_limit && !game.LevelSolved)
+ if (TimeLeft <= 10 && game.time_limit && !game.LevelSolved)
PlaySound(SND_GAME_RUNNING_OUT_OF_TIME);
game_panel_controls[GAME_PANEL_TIME].value = TimeLeft;
DisplayGameControlValues();
- if (!TimeLeft && setup.time_limit && !game.LevelSolved)
+ if (!TimeLeft && game.time_limit && !game.LevelSolved)
for (i = 0; i < MAX_PLAYERS; i++)
KillPlayer(&stored_player[i]);
}
- else if (game.no_time_limit && !game.all_players_gone)
+ else if (game.no_level_time_limit && !game.all_players_gone)
{
game_panel_controls[GAME_PANEL_TIME].value = TimePlayed;
{
TimeLeft--;
- if (TimeLeft <= 10 && setup.time_limit)
+ if (TimeLeft <= 10 && game.time_limit)
PlaySound(SND_GAME_RUNNING_OUT_OF_TIME);
/* this does not make sense: game_panel_controls[GAME_PANEL_TIME].value
game_panel_controls[GAME_PANEL_TIME].value = TimeLeft;
- if (!TimeLeft && setup.time_limit)
+ if (!TimeLeft && game.time_limit)
{
if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
game_em.lev->killed_out_of_time = TRUE;
KillPlayer(&stored_player[i]);
}
}
- else if (game.no_time_limit && !game.all_players_gone)
+ else if (game.no_level_time_limit && !game.all_players_gone)
{
game_panel_controls[GAME_PANEL_TIME].value = TimePlayed;
}
- game_em.lev->time = (game.no_time_limit ? TimePlayed : TimeLeft);
+ game_em.lev->time = (game.no_level_time_limit ? TimePlayed : TimeLeft);
}
if (tape.recording || tape.playing)
}
}
+void AdvanceFrameCounter(void)
+{
+ FrameCounter++;
+}
+
+void AdvanceGfxFrame(void)
+{
+ int x, y;
+
+ SCAN_PLAYFIELD(x, y)
+ {
+ GfxFrame[x][y]++;
+ }
+}
+
void StartGameActions(boolean init_network_game, boolean record_tape,
int random_seed)
{
TapeRecordAction(tape_action);
// remember if game was played (especially after tape stopped playing)
- if (!tape.playing && summarized_player_action)
+ if (!tape.playing && summarized_player_action && !checkGameFailed())
game.GamePlayed = TRUE;
#if USE_NEW_PLAYER_ASSIGNMENTS
void GameActions_EM_Main(void)
{
byte effective_action[MAX_PLAYERS];
- boolean warp_mode = (tape.playing && tape.warp_forward && !tape.pausing);
int i;
for (i = 0; i < MAX_PLAYERS; i++)
effective_action[i] = stored_player[i].effective_action;
- GameActions_EM(effective_action, warp_mode);
+ GameActions_EM(effective_action);
}
void GameActions_SP_Main(void)
{
byte effective_action[MAX_PLAYERS];
- boolean warp_mode = (tape.playing && tape.warp_forward && !tape.pausing);
int i;
for (i = 0; i < MAX_PLAYERS; i++)
effective_action[i] = stored_player[i].effective_action;
- GameActions_SP(effective_action, warp_mode);
+ GameActions_SP(effective_action);
for (i = 0; i < MAX_PLAYERS; i++)
{
void GameActions_MM_Main(void)
{
- boolean warp_mode = (tape.playing && tape.warp_forward && !tape.pausing);
+ AdvanceGfxFrame();
- GameActions_MM(local_player->effective_mouse_action, warp_mode);
+ GameActions_MM(local_player->effective_mouse_action);
}
void GameActions_RND_Main(void)
game.centered_player_nr = game.centered_player_nr_next;
game.set_centered_player = FALSE;
- DrawRelocateScreen(0, 0, sx, sy, MV_NONE, TRUE, setup.quick_switch);
+ DrawRelocateScreen(0, 0, sx, sy, TRUE, setup.quick_switch);
DrawGameDoorValues();
}
CheckExitSP(x, y);
else if (element == EL_EXPANDABLE_WALL_GROWING ||
element == EL_EXPANDABLE_STEELWALL_GROWING)
- MauerWaechst(x, y);
+ WallGrowing(x, y);
else if (element == EL_EXPANDABLE_WALL ||
element == EL_EXPANDABLE_WALL_HORIZONTAL ||
element == EL_EXPANDABLE_WALL_VERTICAL ||
element == EL_EXPANDABLE_WALL_ANY ||
- element == EL_BD_EXPANDABLE_WALL)
- MauerAbleger(x, y);
- else if (element == EL_EXPANDABLE_STEELWALL_HORIZONTAL ||
+ element == EL_BD_EXPANDABLE_WALL ||
+ element == EL_EXPANDABLE_STEELWALL_HORIZONTAL ||
element == EL_EXPANDABLE_STEELWALL_VERTICAL ||
element == EL_EXPANDABLE_STEELWALL_ANY)
- MauerAblegerStahl(x, y);
+ CheckWallGrowing(x, y);
else if (element == EL_FLAMES)
CheckForDragon(x, y);
else if (element == EL_EXPLOSION)
if (mode == SCROLL_INIT)
{
- player->actual_frame_counter = FrameCounter;
+ player->actual_frame_counter.count = FrameCounter;
player->GfxPos = move_stepsize * (player->MovPos / move_stepsize);
if ((player->block_last_field || player->block_delay_adjustment > 0) &&
if (player->MovPos != 0) // player has not yet reached destination
return;
}
- else if (!FrameReached(&player->actual_frame_counter, 1))
+ else if (!FrameReached(&player->actual_frame_counter))
return;
if (player->MovPos != 0)
}
}
- player->last_jx = jx;
- player->last_jy = jy;
-
if (Tile[jx][jy] == EL_EXIT_OPEN ||
Tile[jx][jy] == EL_EM_EXIT_OPEN ||
Tile[jx][jy] == EL_EM_EXIT_OPENING ||
LevelSolved();
}
+ player->last_jx = jx;
+ player->last_jy = jy;
+
// this breaks one level: "machine", level 000
{
int move_direction = player->MovDir;
void ScrollScreen(struct PlayerInfo *player, int mode)
{
- static unsigned int screen_frame_counter = 0;
+ static DelayCounter screen_frame_counter = { 0 };
if (mode == SCROLL_INIT)
{
// set scrolling step size according to actual player's moving speed
ScrollStepSize = TILEX / player->move_delay_value;
- screen_frame_counter = FrameCounter;
+ screen_frame_counter.count = FrameCounter;
+ screen_frame_counter.value = 1;
+
ScreenMovDir = player->MovDir;
ScreenMovPos = player->MovPos;
ScreenGfxPos = ScrollStepSize * (ScreenMovPos / ScrollStepSize);
return;
}
- else if (!FrameReached(&screen_frame_counter, 1))
+ else if (!FrameReached(&screen_frame_counter))
return;
if (ScreenMovPos)
void TestIfPlayerNextToCustomElement(int x, int y)
{
- static int xy[4][2] =
- {
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- { 0, +1 }
- };
+ struct XY *xy = xy_topdown;
static int trigger_sides[4][2] =
{
// center side border side
for (i = 0; i < NUM_DIRECTIONS; i++)
{
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
+ int xx = x + xy[i].x;
+ int yy = y + xy[i].y;
int border_side = trigger_sides[i][1];
int border_element;
void TestIfPlayerTouchesCustomElement(int x, int y)
{
- static int xy[4][2] =
- {
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- { 0, +1 }
- };
+ struct XY *xy = xy_topdown;
static int trigger_sides[4][2] =
{
// center side border side
for (i = 0; i < NUM_DIRECTIONS; i++)
{
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
+ int xx = x + xy[i].x;
+ int yy = y + xy[i].y;
int center_side = trigger_sides[i][0];
int border_side = trigger_sides[i][1];
int border_element;
void TestIfElementNextToCustomElement(int x, int y)
{
- static int xy[4][2] =
- {
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- { 0, +1 }
- };
+ struct XY *xy = xy_topdown;
static int trigger_sides[4][2] =
{
// center side border side
for (i = 0; i < NUM_DIRECTIONS; i++)
{
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
+ int xx = x + xy[i].x;
+ int yy = y + xy[i].y;
int border_side = trigger_sides[i][1];
int border_element;
void TestIfElementTouchesCustomElement(int x, int y)
{
- static int xy[4][2] =
- {
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- { 0, +1 }
- };
+ struct XY *xy = xy_topdown;
static int trigger_sides[4][2] =
{
// center side border side
for (i = 0; i < NUM_DIRECTIONS; i++)
{
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
+ int xx = x + xy[i].x;
+ int yy = y + xy[i].y;
int border_element;
border_element_old[i] = -1;
for (i = 0; i < NUM_DIRECTIONS; i++)
{
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
+ int xx = x + xy[i].x;
+ int yy = y + xy[i].y;
int center_side = trigger_sides[i][0];
int border_element = border_element_old[i];
for (i = 0; i < NUM_DIRECTIONS; i++)
{
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
+ int xx = x + xy[i].x;
+ int yy = y + xy[i].y;
int border_side = trigger_sides[i][1];
int border_element = border_element_old[i];
int i, kill_x = -1, kill_y = -1;
int bad_element = -1;
- static int test_xy[4][2] =
- {
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- { 0, +1 }
- };
+ struct XY *test_xy = xy_topdown;
static int test_dir[4] =
{
MV_UP,
{
int test_x, test_y, test_move_dir, test_element;
- test_x = good_x + test_xy[i][0];
- test_y = good_y + test_xy[i][1];
+ test_x = good_x + test_xy[i].x;
+ test_y = good_y + test_xy[i].y;
if (!IN_LEV_FIELD(test_x, test_y))
continue;
{
int i, kill_x = -1, kill_y = -1;
int bad_element = Tile[bad_x][bad_y];
- static int test_xy[4][2] =
- {
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- { 0, +1 }
- };
+ struct XY *test_xy = xy_topdown;
static int touch_dir[4] =
{
MV_LEFT | MV_RIGHT,
{
int test_x, test_y, test_move_dir, test_element;
- test_x = bad_x + test_xy[i][0];
- test_y = bad_y + test_xy[i][1];
+ test_x = bad_x + test_xy[i].x;
+ test_y = bad_y + test_xy[i].y;
if (!IN_LEV_FIELD(test_x, test_y))
continue;
void TestIfBadThingTouchesOtherBadThing(int bad_x, int bad_y)
{
int i, kill_x = bad_x, kill_y = bad_y;
- static int xy[4][2] =
- {
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- { 0, +1 }
- };
+ struct XY *xy = xy_topdown;
for (i = 0; i < NUM_DIRECTIONS; i++)
{
int x, y, element;
- x = bad_x + xy[i][0];
- y = bad_y + xy[i][1];
+ x = bad_x + xy[i].x;
+ y = bad_y + xy[i].y;
if (!IN_LEV_FIELD(x, y))
continue;
player->killed = TRUE;
// remove accessible field at the player's position
- Tile[jx][jy] = EL_EMPTY;
+ RemoveField(jx, jy);
// deactivate shield (else Bang()/Explode() would not work right)
player->shield_normal_time_left = 0;
return;
PlayLevelSoundElementAction(jx, jy, player->artwork_element, ACTION_DYING);
- PlayLevelSound(jx, jy, SND_GAME_LOSING);
RemovePlayer(player);
}
else if (element == EL_SHIELD_NORMAL || element == EL_SHIELD_DEADLY)
{
- player->shield_normal_time_left += level.shield_normal_time;
+ int shield_time = (element == EL_SHIELD_DEADLY ?
+ level.shield_deadly_time :
+ level.shield_normal_time);
+
+ player->shield_normal_time_left += shield_time;
if (element == EL_SHIELD_DEADLY)
- player->shield_deadly_time_left += level.shield_deadly_time;
+ player->shield_deadly_time_left += shield_time;
}
else if (element == EL_DYNAMITE ||
element == EL_EM_DYNAMITE ||
LevelSolved();
- PlayLevelSound(x, y, SND_GAME_SOKOBAN_SOLVING);
+ PlaySound(SND_GAME_SOKOBAN_SOLVING);
}
}
else
element == EL_DC_SWITCHGATE_SWITCH_UP ||
element == EL_DC_SWITCHGATE_SWITCH_DOWN)
{
- ToggleSwitchgateSwitch(x, y);
+ ToggleSwitchgateSwitch();
}
else if (element == EL_LIGHT_SWITCH ||
element == EL_LIGHT_SWITCH_ACTIVE)
if (level.time > 0 || level.use_time_orb_bug)
{
TimeLeft += level.time_orb_time;
- game.no_time_limit = FALSE;
+ game.no_level_time_limit = FALSE;
game_panel_controls[GAME_PANEL_TIME].value = TimeLeft;
{
// prevent short reactivation of overlay buttons while closing door
SetOverlayActive(FALSE);
+ UnmapGameButtons();
// door may still be open due to skipped or envelope style request
- CloseDoor(DOOR_CLOSE_1);
+ CloseDoor(score_info_tape_play ? DOOR_CLOSE_ALL : DOOR_CLOSE_1);
}
if (network.enabled)
boolean quick_quit = ((escape_key_pressed && !ask_on_escape) ||
level_editor_test_game);
boolean skip_request = (game.all_players_gone || !setup.ask_on_quit_game ||
- quick_quit);
+ quick_quit || score_info_tape_play);
RequestQuitGameExt(skip_request, quick_quit,
"Do you really want to quit the game?");
}
-void RequestRestartGame(char *message)
+static char *getRestartGameMessage(void)
{
- game.restart_game_message = NULL;
+ boolean play_again = hasStartedNetworkGame();
+ static char message[MAX_OUTPUT_LINESIZE];
+ char *game_over_text = "Game over!";
+ char *play_again_text = " Play it again?";
+
+ if (level.game_engine_type == GAME_ENGINE_TYPE_MM &&
+ game_mm.game_over_message != NULL)
+ game_over_text = game_mm.game_over_message;
+ snprintf(message, MAX_OUTPUT_LINESIZE, "%s%s", game_over_text,
+ (play_again ? play_again_text : ""));
+
+ return message;
+}
+
+static void RequestRestartGame(void)
+{
+ char *message = getRestartGameMessage();
boolean has_started_game = hasStartedNetworkGame();
int request_mode = (has_started_game ? REQ_ASK : REQ_CONFIRM);
+ int door_state = DOOR_CLOSE_1;
- if (Request(message, request_mode | REQ_STAY_CLOSED) && has_started_game)
+ if (Request(message, request_mode | REQ_STAY_OPEN) && has_started_game)
{
+ CloseDoor(door_state);
+
StartGameActions(network.enabled, setup.autorecord, level.random_seed);
}
else
{
- // needed in case of envelope request to close game panel
- CloseDoor(DOOR_CLOSE_1);
+ // if game was invoked from level editor, also close tape recorder door
+ if (level_editor_test_game)
+ door_state = DOOR_CLOSE_ALL;
+
+ CloseDoor(door_state);
SetGameStatus(GAME_MODE_MAIN);
}
}
-void CheckGameOver(void)
+boolean CheckRestartGame(void)
{
- static boolean last_game_over = FALSE;
static int game_over_delay = 0;
int game_over_delay_value = 50;
boolean game_over = checkGameFailed();
- // do not handle game over if request dialog is already active
- if (game.request_active)
- return;
-
- // do not ask to play again if game was never actually played
- if (!game.GamePlayed)
- return;
-
if (!game_over)
{
- last_game_over = FALSE;
game_over_delay = game_over_delay_value;
- return;
+ return FALSE;
}
if (game_over_delay > 0)
{
+ if (game_over_delay == game_over_delay_value / 2)
+ PlaySound(SND_GAME_LOSING);
+
game_over_delay--;
- return;
+ return FALSE;
}
- if (last_game_over != game_over)
- game.restart_game_message = (hasStartedNetworkGame() ?
- "Game over! Play it again?" :
- "Game over!");
+ // do not handle game over if request dialog is already active
+ if (game.request_active)
+ return FALSE;
+
+ // do not ask to play again if game was never actually played
+ if (!game.GamePlayed)
+ return FALSE;
- last_game_over = game_over;
+ // do not ask to play again if this was disabled in setup menu
+ if (!setup.ask_on_game_over)
+ return FALSE;
+
+ RequestRestartGame();
+
+ return TRUE;
}
boolean checkGameSolved(void)
if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
SaveEngineSnapshotValues_SP(&buffers);
if (level.game_engine_type == GAME_ENGINE_TYPE_MM)
- SaveEngineSnapshotValues_MM(&buffers);
+ SaveEngineSnapshotValues_MM();
// save values stored in special snapshot structure
int y = (is_touch_button ? pos->y : GDI_ACTIVE_POS(pos->y));
int id = i;
+ // do not use touch buttons if overlay touch buttons are disabled
+ if (is_touch_button && !setup.touch.overlay_buttons)
+ continue;
+
if (gfx->bitmap == NULL)
{
game_gadget[id] = NULL;
case GAME_CTRL_ID_STOP:
case GAME_CTRL_ID_PANEL_STOP:
case GAME_CTRL_ID_TOUCH_STOP:
- if (game_status == GAME_MODE_MAIN)
- break;
-
- if (tape.playing)
- TapeStop();
- else
- RequestQuitGame(FALSE);
+ TapeStopGame();
break;