X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=d1bf2d7d0f2a334760196aab48140344b55d1ba2;hb=f3e3bb074cc627f4b7ced30ea8db822538692c19;hp=53410d5ace4c808511e21dad4c6e2e8cf04e6ada;hpb=b4962aefbc6cf3356112afe7cf421e073360de14;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index 53410d5a..d1bf2d7d 100644 --- a/src/game.c +++ b/src/game.c @@ -3095,6 +3095,9 @@ static void InitGameEngine(void) game_em.use_single_button = (game.engine_version > VERSION_IDENT(4,0,0,2)); + game_em.use_push_delay = + (game.engine_version > VERSION_IDENT(4,3,7,1)); + game_em.use_snap_key_bug = (game.engine_version < VERSION_IDENT(4,0,1,0)); @@ -3279,6 +3282,8 @@ static void InitGameEngine(void) change->actual_trigger_side = CH_SIDE_NONE; change->actual_trigger_ce_value = 0; change->actual_trigger_ce_score = 0; + change->actual_trigger_x = -1; + change->actual_trigger_y = -1; } } @@ -3865,6 +3870,8 @@ void InitGame(void) game.LevelSolved_CountingScore = 0; game.LevelSolved_CountingHealth = 0; + game.RestartGameRequested = FALSE; + game.panel.active = TRUE; game.no_level_time_limit = (level.time == 0); @@ -3971,6 +3978,10 @@ void InitGame(void) InitBeltMovement(); + // required if level does not contain any "empty space" element + if (element_info[EL_EMPTY].use_gfx_element) + game.use_masked_elements = TRUE; + for (i = 0; i < MAX_PLAYERS; i++) { struct PlayerInfo *player = &stored_player[i]; @@ -4445,6 +4456,11 @@ void InitGame(void) scroll_y = SCROLL_POSITION_Y(local_player->jy); } + if (game.forced_scroll_x != ARG_UNDEFINED_VALUE) + scroll_x = game.forced_scroll_x; + if (game.forced_scroll_y != ARG_UNDEFINED_VALUE) + scroll_y = game.forced_scroll_y; + // !!! FIX THIS (START) !!! if (level.game_engine_type == GAME_ENGINE_TYPE_EM) { @@ -4535,9 +4551,7 @@ void InitGame(void) } game.restart_level = FALSE; - game.request_active = FALSE; - game.request_active_or_moving = FALSE; if (level.game_engine_type == GAME_ENGINE_TYPE_MM) InitGameActions_MM(); @@ -5682,6 +5696,40 @@ static void DrawRelocateScreen(int old_x, int old_y, int x, int y, // make sure that shifted scroll position does not scroll beyond screen new_scroll_x = SCROLL_POSITION_X(shifted_scroll_x + MIDPOSX); new_scroll_y = SCROLL_POSITION_Y(shifted_scroll_y + MIDPOSY); + + // special case for teleporting from one end of the playfield to the other + // (this kludge prevents the destination area to be shifted by half a tile + // against the source destination for even screen width or screen height; + // probably most useful when used with high "game.forced_scroll_delay_value" + // in combination with "game.forced_scroll_x" and "game.forced_scroll_y") + if (quick_relocation) + { + if (EVEN(SCR_FIELDX)) + { + // relocate (teleport) between left and right border (half or full) + if (scroll_x == SBX_Left && new_scroll_x == SBX_Right - 1) + new_scroll_x = SBX_Right; + else if (scroll_x == SBX_Left + 1 && new_scroll_x == SBX_Right) + new_scroll_x = SBX_Right - 1; + else if (scroll_x == SBX_Right && new_scroll_x == SBX_Left + 1) + new_scroll_x = SBX_Left; + else if (scroll_x == SBX_Right - 1 && new_scroll_x == SBX_Left) + new_scroll_x = SBX_Left + 1; + } + + if (EVEN(SCR_FIELDY)) + { + // relocate (teleport) between top and bottom border (half or full) + if (scroll_y == SBY_Upper && new_scroll_y == SBY_Lower - 1) + new_scroll_y = SBY_Lower; + else if (scroll_y == SBY_Upper + 1 && new_scroll_y == SBY_Lower) + new_scroll_y = SBY_Lower - 1; + else if (scroll_y == SBY_Lower && new_scroll_y == SBY_Upper + 1) + new_scroll_y = SBY_Upper; + else if (scroll_y == SBY_Lower - 1 && new_scroll_y == SBY_Upper) + new_scroll_y = SBY_Upper + 1; + } + } } if (quick_relocation) @@ -10720,6 +10768,8 @@ static boolean ChangeElement(int x, int y, int element, int page) change->actual_trigger_side = CH_SIDE_NONE; change->actual_trigger_ce_value = 0; change->actual_trigger_ce_score = 0; + change->actual_trigger_x = -1; + change->actual_trigger_y = -1; } // do not change elements more than a specified maximum number of changes @@ -10729,7 +10779,9 @@ static boolean ChangeElement(int x, int y, int element, int page) ChangeCount[x][y]++; // count number of changes in the same frame if (ei->has_anim_event) - HandleGlobalAnimEventByElementChange(element, page, x, y); + HandleGlobalAnimEventByElementChange(element, page, x, y, + change->actual_trigger_x, + change->actual_trigger_y); if (change->explode) { @@ -11059,6 +11111,8 @@ static boolean CheckTriggeredElementChangeExt(int trigger_x, int trigger_y, change->actual_trigger_side = trigger_side; change->actual_trigger_ce_value = CustomValue[trigger_x][trigger_y]; change->actual_trigger_ce_score = GET_CE_SCORE(trigger_element); + change->actual_trigger_x = trigger_x; + change->actual_trigger_y = trigger_y; if ((change->can_change && !change_done) || change->has_action) { @@ -11173,6 +11227,8 @@ static boolean CheckElementChangeExt(int x, int y, change->actual_trigger_side = trigger_side; change->actual_trigger_ce_value = CustomValue[x][y]; change->actual_trigger_ce_score = GET_CE_SCORE(trigger_element); + change->actual_trigger_x = x; + change->actual_trigger_y = y; // special case: trigger element not at (x,y) position for some events if (check_trigger_element) @@ -11196,6 +11252,8 @@ static boolean CheckElementChangeExt(int x, int y, change->actual_trigger_ce_value = CustomValue[xx][yy]; change->actual_trigger_ce_score = GET_CE_SCORE(trigger_element); + change->actual_trigger_x = xx; + change->actual_trigger_y = yy; } if (change->can_change && !change_done) @@ -15746,10 +15804,14 @@ boolean CheckRestartGame(void) return FALSE; } - // do not handle game over if request dialog is already active + // do not ask to play again if request dialog is already active if (game.request_active) return FALSE; + // do not ask to play again if request dialog already handled + if (game.RestartGameRequested) + return FALSE; + // do not ask to play again if game was never actually played if (!game.GamePlayed) return FALSE; @@ -15758,6 +15820,8 @@ boolean CheckRestartGame(void) if (!setup.ask_on_game_over) return FALSE; + game.RestartGameRequested = TRUE; + RequestRestartGame(); return TRUE;