RND(element_info[e].move_delay_random))
#define GET_MAX_MOVE_DELAY(e) ( (element_info[e].move_delay_fixed) + \
(element_info[e].move_delay_random))
+#define GET_NEW_STEP_DELAY(e) ( (element_info[e].step_delay_fixed) + \
+ RND(element_info[e].step_delay_random))
+#define GET_MAX_STEP_DELAY(e) ( (element_info[e].step_delay_fixed) + \
+ (element_info[e].step_delay_random))
#define GET_NEW_CE_VALUE(e) ( (element_info[e].ce_value_fixed_initial) +\
RND(element_info[e].ce_value_random_initial))
#define GET_CE_SCORE(e) ( (element_info[e].collect_score))
CheckTriggeredElementChangeExt(x, y, e, ev, CH_PLAYER_ANY, s, -1)
#define CheckTriggeredElementChangeByPage(x, y, e, ev, p) \
CheckTriggeredElementChangeExt(x,y,e,ev, CH_PLAYER_ANY, CH_SIDE_ANY, p)
+#define CheckTriggeredElementChangeByMouse(x, y, e, ev, s) \
+ CheckTriggeredElementChangeExt(x, y, e, ev, CH_PLAYER_ANY, s, -1)
static boolean CheckElementChangeExt(int, int, int, int, int, int, int);
#define CheckElementChange(x, y, e, te, ev) \
CheckElementChangeExt(x, y, e, EL_EMPTY, ev, p, s)
#define CheckElementChangeBySide(x, y, e, te, ev, s) \
CheckElementChangeExt(x, y, e, te, ev, CH_PLAYER_ANY, s)
+#define CheckElementChangeByMouse(x, y, e, ev, s) \
+ CheckElementChangeExt(x, y, e, EL_UNDEFINED, ev, CH_PLAYER_ANY, s)
static void PlayLevelSound(int, int, int);
static void PlayLevelSoundNearest(int, int, int);
static int game_over_delay_1 = 0;
static int game_over_delay_2 = 0;
static int game_over_delay_3 = 0;
- int game_over_delay_value_1 = 50;
- int game_over_delay_value_2 = 25;
- int game_over_delay_value_3 = 50;
int time_score_base = MIN(MAX(1, level.time_score_base), 10);
float time_score = (float)level.score[SC_TIME_BONUS] / time_score_base;
TapeStop();
- game_over_delay_1 = game_over_delay_value_1;
- game_over_delay_2 = game_over_delay_value_2;
- game_over_delay_3 = game_over_delay_value_3;
+ game_over_delay_1 = FRAMES_PER_SECOND; // delay before counting time
+ game_over_delay_2 = FRAMES_PER_SECOND / 2; // delay before counting health
+ game_over_delay_3 = FRAMES_PER_SECOND; // delay before ending the game
time = time_final = (game.no_time_limit ? TimePlayed : TimeLeft);
score = score_final = game.score_final;
return;
if (Back[x][y])
- DrawGraphic(sx, sy, el2img(Back[x][y]), 0);
+ DrawLevelElement(x, y, Back[x][y]);
else if (Store[x][y])
- DrawGraphic(sx, sy, el2img(Store[x][y]), 0);
+ DrawLevelElement(x, y, Store[x][y]);
+ else if (game.use_masked_elements)
+ DrawLevelElement(x, y, EL_EMPTY);
frame = getGraphicAnimationFrame(graphic, GfxFrame[x][y]);
- if (Back[x][y] || Store[x][y])
+ if (Back[x][y] || Store[x][y] || game.use_masked_elements)
DrawGraphicThruMask(sx, sy, graphic, frame);
else
DrawGraphic(sx, sy, graphic, frame);
DrawLevelElementThruMask(x, y, Back[x][y]);
}
else if (!IS_WALKABLE_INSIDE(Back[x][y]))
- DrawGraphic(SCREENX(x), SCREENY(y), graphic, frame);
+ DrawScreenGraphic(SCREENX(x), SCREENY(y), graphic, frame);
}
}
boolean pushed_by_player = (Pushed[x][y] && IS_PLAYER(x, y));
boolean pushed_by_conveyor = (Pushed[x][y] && !IS_PLAYER(x, y));
boolean last_line = (newy == lev_fieldy - 1);
+ boolean use_step_delay = (GET_MAX_STEP_DELAY(element) != 0);
- MovPos[x][y] += getElementMoveStepsize(x, y);
-
- if (pushed_by_player) // special case: moving object pushed by player
+ if (pushed_by_player) // special case: moving object pushed by player
+ {
MovPos[x][y] = SIGN(MovPos[x][y]) * (TILEX - ABS(PLAYERINFO(x,y)->MovPos));
+ }
+ else if (use_step_delay) // special case: moving object has step delay
+ {
+ if (!MovDelay[x][y])
+ MovPos[x][y] += getElementMoveStepsize(x, y);
+
+ if (MovDelay[x][y])
+ MovDelay[x][y]--;
+ else
+ MovDelay[x][y] = GET_NEW_STEP_DELAY(element);
+
+ if (MovDelay[x][y])
+ {
+ TEST_DrawLevelField(x, y);
+
+ return; // element is still waiting
+ }
+ }
+ else // normal case: generically moving object
+ {
+ MovPos[x][y] += getElementMoveStepsize(x, y);
+ }
if (ABS(MovPos[x][y]) < TILEX)
{
if (mouse_action.button)
{
int new_button = (mouse_action.button && mouse_action_last.button == 0);
+ int ch_button = CH_SIDE_FROM_BUTTON(mouse_action.button);
x = mouse_action.lx;
y = mouse_action.ly;
if (new_button)
{
- CheckElementChange(x, y, element, EL_UNDEFINED, CE_CLICKED_BY_MOUSE);
- CheckTriggeredElementChange(x, y, element, CE_MOUSE_CLICKED_ON_X);
+ CheckElementChangeByMouse(x, y, element, CE_CLICKED_BY_MOUSE, ch_button);
+ CheckTriggeredElementChangeByMouse(x, y, element, CE_MOUSE_CLICKED_ON_X,
+ ch_button);
}
- CheckElementChange(x, y, element, EL_UNDEFINED, CE_PRESSED_BY_MOUSE);
- CheckTriggeredElementChange(x, y, element, CE_MOUSE_PRESSED_ON_X);
+ CheckElementChangeByMouse(x, y, element, CE_PRESSED_BY_MOUSE, ch_button);
+ CheckTriggeredElementChangeByMouse(x, y, element, CE_MOUSE_PRESSED_ON_X,
+ ch_button);
}
SCAN_PLAYFIELD(x, y)
{
if (skip_request || Request(message, REQ_ASK | REQ_STAY_CLOSED))
{
- // closing door required in case of envelope style request dialogs
- if (!skip_request)
+ if (!quick_quit)
{
// prevent short reactivation of overlay buttons while closing door
SetOverlayActive(FALSE);
+ // door may still be open due to skipped or envelope style request
CloseDoor(DOOR_CLOSE_1);
}
}
}
-void RequestQuitGame(boolean ask_if_really_quit)
+void RequestQuitGame(boolean escape_key_pressed)
{
- boolean quick_quit = (!ask_if_really_quit || level_editor_test_game);
- boolean skip_request = game.all_players_gone || quick_quit;
+ boolean ask_on_escape = (setup.ask_on_escape && setup.ask_on_quit_game);
+ 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);
RequestQuitGameExt(skip_request, quick_quit,
"Do you really want to quit the game?");
if (tape.playing)
TapeStop();
else
- RequestQuitGame(TRUE);
+ RequestQuitGame(FALSE);
break;