#define USE_CODE_THAT_BREAKS_SNAKE_BITE (USE_NEW_STUFF * 1)
+#define USE_UFAST_PLAYER_EXIT_BUGFIX (USE_NEW_STUFF * 1)
+#define USE_NEW_GAME_WON (USE_NEW_STUFF * 1)
+
/* for DigField() */
#define DF_NO_PUSH 0
#define EX_TYPE_DYNA (1 << 4)
#define EX_TYPE_SINGLE_TILE (EX_TYPE_CENTER | EX_TYPE_BORDER)
+#if 1
+
+#define PANEL_DEACTIVATED(p) ((p).x < 0 || (p).y < 0)
+
+/* special positions in the game control window (relative to control window) */
+#define XX_LEVEL1 (game.panel.level.x)
+#define XX_LEVEL2 (game.panel.level.x - 1)
+#define YY_LEVEL (game.panel.level.y)
+#define XX_EMERALDS (game.panel.gems.x)
+#define YY_EMERALDS (game.panel.gems.y)
+#define XX_DYNAMITE (game.panel.inventory.x)
+#define YY_DYNAMITE (game.panel.inventory.y)
+#define XX_KEYS (game.panel.keys.x)
+#define YY_KEYS (game.panel.keys.y)
+#define XX_SCORE (game.panel.score.x)
+#define YY_SCORE (game.panel.score.y)
+#define XX_TIME1 (game.panel.time.x)
+#define XX_TIME2 (game.panel.time.x + 1)
+#define YY_TIME (game.panel.time.y)
+
+#else
+
/* special positions in the game control window (relative to control window) */
#define XX_LEVEL 37
#define YY_LEVEL 20
#define XX_TIME2 30
#define YY_TIME 194
+#endif
+
/* special positions in the game control window (relative to main window) */
-#define DX_LEVEL (DX + XX_LEVEL)
+#define DX_LEVEL1 (DX + XX_LEVEL1)
+#define DX_LEVEL2 (DX + XX_LEVEL2)
#define DY_LEVEL (DY + YY_LEVEL)
#define DX_EMERALDS (DX + XX_EMERALDS)
#define DY_EMERALDS (DY + YY_EMERALDS)
{
int xpos = (3 * 14 - 3 * getFontWidth(FONT_TEXT_2)) / 2;
+ if (PANEL_DEACTIVATED(game.panel.gems))
+ return;
+
DrawText(DX_EMERALDS + xpos, DY_EMERALDS, int2str(value, 3), FONT_TEXT_2);
}
{
int xpos = (3 * 14 - 3 * getFontWidth(FONT_TEXT_2)) / 2;
+ if (PANEL_DEACTIVATED(game.panel.inventory))
+ return;
+
DrawText(DX_DYNAMITE + xpos, DY_DYNAMITE, int2str(value, 3), FONT_TEXT_2);
}
int base_key_graphic = EL_KEY_1;
int i;
+ if (PANEL_DEACTIVATED(game.panel.keys))
+ return;
+
if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
base_key_graphic = EL_EM_KEY_1;
/* currently only 4 of 8 possible keys are displayed */
for (i = 0; i < STD_NUM_KEYS; i++)
{
+ int x = XX_KEYS + i * MINI_TILEX;
+ int y = YY_KEYS;
+
if (key[i])
- DrawMiniGraphicExt(drawto, DX_KEYS + i * MINI_TILEX, DY_KEYS,
- el2edimg(base_key_graphic + i));
+ DrawMiniGraphicExt(drawto, DX + x,DY + y, el2edimg(base_key_graphic + i));
else
BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto,
- DOOR_GFX_PAGEX5 + XX_KEYS + i * MINI_TILEX, YY_KEYS,
- MINI_TILEX, MINI_TILEY, DX_KEYS + i * MINI_TILEX, DY_KEYS);
+ DOOR_GFX_PAGEX5 + x, y, MINI_TILEX, MINI_TILEY, DX + x,DY + y);
}
}
{
int xpos = (5 * 14 - 5 * getFontWidth(FONT_TEXT_2)) / 2;
+ if (PANEL_DEACTIVATED(game.panel.score))
+ return;
+
DrawText(DX_SCORE + xpos, DY_SCORE, int2str(value, 5), FONT_TEXT_2);
}
int xpos3 = (3 * 14 - 3 * getFontWidth(FONT_TEXT_2)) / 2;
int xpos4 = (4 * 10 - 4 * getFontWidth(FONT_LEVEL_NUMBER)) / 2;
+ if (PANEL_DEACTIVATED(game.panel.time))
+ return;
+
/* clear background if value just changed its size */
if (value == 999 || value == 1000)
- ClearRectangle(drawto, DX_TIME1, DY_TIME, 14 * 3, 14);
+ ClearRectangleOnBackground(drawto, DX_TIME1, DY_TIME, 14 * 3, 14);
if (value < 1000)
DrawText(DX_TIME1 + xpos3, DY_TIME, int2str(value, 3), FONT_TEXT_2);
inline void DrawGameValue_Level(int value)
{
+ if (PANEL_DEACTIVATED(game.panel.level))
+ return;
+
if (level_nr < 100)
- DrawText(DX_LEVEL, DY_LEVEL, int2str(value, 2), FONT_TEXT_2);
+ DrawText(DX_LEVEL1, DY_LEVEL, int2str(value, 2), FONT_TEXT_2);
else
+#if 1
+ DrawText(DX_LEVEL2, DY_LEVEL, int2str(value, 3), FONT_LEVEL_NUMBER);
+#else
{
/* misuse area for displaying emeralds to draw bigger level number */
DrawTextExt(drawto, DX_EMERALDS, DY_EMERALDS,
/* yes, this is all really ugly :-) */
}
+#endif
}
void DrawAllGameValues(int emeralds, int dynamite, int score, int time,
void DrawGameDoorValues()
{
+ int time_value = (level.time == 0 ? TimePlayed : TimeLeft);
int dynamite_state = 0;
int key_bits = 0;
int i, j;
}
DrawAllGameValues(local_player->gems_still_needed, dynamite_state,
- local_player->score, TimeLeft, key_bits);
+ local_player->score, time_value, key_bits);
#endif
}
boolean emulate_bd = TRUE; /* unless non-BOULDERDASH elements found */
boolean emulate_sb = TRUE; /* unless non-SOKOBAN elements found */
boolean emulate_sp = TRUE; /* unless non-SUPAPLEX elements found */
+ boolean do_fading = (game_status == GAME_MODE_MAIN);
int i, j, x, y;
+ game_status = GAME_MODE_PLAYING;
+
InitGameEngine();
/* don't play tapes over network */
player->LevelSolved = FALSE;
player->GameOver = FALSE;
+
+ player->LevelSolved_GameEnd = FALSE;
+ player->LevelSolved_SaveTape = FALSE;
+ player->LevelSolved_SaveScore = FALSE;
}
network_player_action_received = FALSE;
local_player->jy - MIDPOSY);
}
+ StopAnimation();
+
if (!game.restart_level)
CloseDoor(DOOR_CLOSE_1);
+ if (do_fading)
+ FadeOut(REDRAW_FIELD);
+
/* !!! FIX THIS (START) !!! */
if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
{
BlitBitmap(fieldbuffer, backbuffer, FX, FY, SXSIZE, SYSIZE, SX, SY);
redraw_mask |= REDRAW_FROM_BACKBUFFER;
+
+#if 0
FadeToFront();
+#endif
}
/* !!! FIX THIS (END) !!! */
+ if (do_fading)
+ FadeIn(REDRAW_FIELD);
+
if (!game.restart_level)
{
/* copy default game door content to main double buffer */
DOOR_GFX_PAGEX5, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE, DX, DY);
}
+#if 1
+ SetPanelBackground();
+ SetDrawBackgroundMask(REDRAW_DOOR_1);
+#endif
+
DrawGameDoorValues();
if (!game.restart_level)
AmoebaCnt2[group_nr]++;
}
+#if USE_NEW_GAME_WON
+
+void GameWon()
+{
+ static boolean score_done = FALSE;
+ static boolean player_done = FALSE;
+ static int game_over_delay = 0;
+ int game_over_delay_value = 50;
+
+ /* do not start end game actions before the player stops moving (to exit) */
+ if (local_player->MovPos)
+ return;
+
+ if (tape.auto_play) /* tape might already be stopped here */
+ tape.auto_play_level_solved = TRUE;
+
+ if (!local_player->LevelSolved_GameEnd)
+ {
+ local_player->LevelSolved_GameEnd = TRUE;
+ local_player->LevelSolved_SaveTape = tape.recording;
+ local_player->LevelSolved_SaveScore = !tape.playing;
+
+ score_done = FALSE;
+ player_done = FALSE;
+ game_over_delay = 0;
+ }
+
+ PlaySoundStereo(SND_GAME_WINNING, SOUND_MIDDLE);
+
+ if (TimeLeft > 0)
+ {
+ if (!tape.playing)
+ {
+ if (setup.sound_loops)
+ PlaySoundExt(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_VOLUME, SOUND_MIDDLE,
+ SND_CTRL_PLAY_LOOP);
+ else
+ PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MIDDLE);
+ }
+
+ if (TimeLeft > 100 && TimeLeft % 10 == 0)
+ {
+ TimeLeft -= 10;
+ RaiseScore(level.score[SC_TIME_BONUS] * 10);
+ }
+ else
+ {
+ TimeLeft--;
+ RaiseScore(level.score[SC_TIME_BONUS]);
+ }
+
+ DrawGameValue_Time(TimeLeft);
+
+#if 0
+ if (!tape.playing)
+ Delay(10);
+#endif
+
+ if (TimeLeft <= 0 && !tape.playing && setup.sound_loops)
+ StopSound(SND_GAME_LEVELTIME_BONUS);
+ }
+ else if (level.time == 0 && TimePlayed < 999) /* level without time limit */
+ {
+ if (!tape.playing)
+ {
+ if (setup.sound_loops)
+ PlaySoundExt(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_VOLUME, SOUND_MIDDLE,
+ SND_CTRL_PLAY_LOOP);
+ else
+ PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MIDDLE);
+ }
+
+ if (TimePlayed < 900 && TimePlayed % 10 == 0)
+ {
+ TimePlayed += 10;
+ RaiseScore(level.score[SC_TIME_BONUS] * 10);
+ }
+ else
+ {
+ TimePlayed++;
+ RaiseScore(level.score[SC_TIME_BONUS]);
+ }
+
+ DrawGameValue_Time(TimePlayed);
+
+ if (TimePlayed >= 999 && !tape.playing && setup.sound_loops)
+ StopSound(SND_GAME_LEVELTIME_BONUS);
+ }
+ else
+ {
+ score_done = TRUE;
+ }
+
+ /* close exit door after last player */
+ if (AllPlayersGone && ExitX >= 0 && ExitY >= 0 &&
+ (Feld[ExitX][ExitY] == EL_EXIT_OPEN ||
+ Feld[ExitX][ExitY] == EL_SP_EXIT_OPEN))
+ {
+ int element = Feld[ExitX][ExitY];
+
+ Feld[ExitX][ExitY] = (element == EL_EXIT_OPEN ? EL_EXIT_CLOSING :
+ EL_SP_EXIT_CLOSING);
+
+ PlayLevelSoundElementAction(ExitX, ExitY, element, ACTION_CLOSING);
+ }
+
+ /* player disappears */
+ if (ExitX >= 0 && ExitY >= 0 && !player_done)
+ {
+ DrawLevelField(ExitX, ExitY);
+
+ player_done = TRUE;
+ }
+
+ game_over_delay++;
+
+ if (game_over_delay < game_over_delay_value || !score_done)
+ return;
+}
+
+void GameEnd()
+{
+ int hi_pos;
+ boolean raise_level = FALSE;
+
+ CloseDoor(DOOR_CLOSE_1);
+
+ if (local_player->LevelSolved_SaveTape)
+ {
+ TapeStop();
+
+ SaveTape(tape.level_nr); /* Ask to save tape */
+ }
+
+ if (!local_player->LevelSolved_SaveScore)
+ {
+ FadeOut(REDRAW_FIELD);
+
+ game_status = GAME_MODE_MAIN;
+
+ DrawAndFadeInMainMenu(REDRAW_FIELD);
+
+ return;
+ }
+
+ if (level_nr == leveldir_current->handicap_level)
+ {
+ leveldir_current->handicap_level++;
+ SaveLevelSetup_SeriesInfo();
+ }
+
+ if (level_editor_test_game)
+ local_player->score = -1; /* no highscore when playing from editor */
+ else if (level_nr < leveldir_current->last_level)
+ raise_level = TRUE; /* advance to next level */
+
+ if ((hi_pos = NewHiScore()) >= 0)
+ {
+ game_status = GAME_MODE_SCORES;
+
+ DrawHallOfFame(hi_pos);
+
+ if (raise_level)
+ {
+ level_nr++;
+ TapeErase();
+ }
+ }
+ else
+ {
+ FadeOut(REDRAW_FIELD);
+
+ game_status = GAME_MODE_MAIN;
+
+ if (raise_level)
+ {
+ level_nr++;
+ TapeErase();
+ }
+
+ DrawAndFadeInMainMenu(REDRAW_FIELD);
+ }
+
+ local_player->LevelSolved_SaveScore = FALSE;
+}
+
+#else
+
void GameWon()
{
int hi_pos;
BackToFront();
}
+#endif
+
int NewHiScore()
{
int k, l;
}
#endif
- StopAnimation();
-
- game_status = GAME_MODE_PLAYING;
-
InitGame();
}
PlayerVisit[jx][jy] = FrameCounter;
+#if USE_UFAST_PLAYER_EXIT_BUGFIX
+ player->is_moving = TRUE;
+#endif
+
+#if 1
+ /* should better be called in MovePlayer(), but this breaks some tapes */
ScrollPlayer(player, SCROLL_INIT);
+#endif
return MP_MOVING;
}
player->is_dropping = FALSE;
player->is_dropping_pressed = FALSE;
player->drop_pressed_delay = 0;
+
+#if 0
+ /* should better be called here than above, but this breaks some tapes */
+ ScrollPlayer(player, SCROLL_INIT);
+#endif
}
else
{
else
#endif
{
- game_status = GAME_MODE_MAIN;
- DrawMainMenu();
+ if (!ask_if_really_quit || level_editor_test_game)
+ {
+ game_status = GAME_MODE_MAIN;
+
+ DrawMainMenu();
+ }
+ else
+ {
+ FadeOut(REDRAW_FIELD);
+
+ game_status = GAME_MODE_MAIN;
+
+ DrawAndFadeInMainMenu(REDRAW_FIELD);
+ }
}
}
else