X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=fea0d6ce8e1588f28bfc94634545cf5e5a180c74;hb=7c0b78ef65acbe880d7f905a5e38fb7bdac8f007;hp=daa0b30eb457c97ec29bd0aa69755f40964e19fd;hpb=e4f31a4e6f4b611a1dddb16afb66e3af177dd937;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index daa0b30e..fea0d6ce 100644 --- a/src/game.c +++ b/src/game.c @@ -1,7 +1,7 @@ /*********************************************************** * Rocks'n'Diamonds -- McDuffin Strikes Back! * *----------------------------------------------------------* -* (c) 1995-2002 Artsoft Entertainment * +* (c) 1995-2006 Artsoft Entertainment * * Holger Schemel * * Detmolder Strasse 189 * * 33604 Bielefeld * @@ -51,6 +51,8 @@ #define USE_CODE_THAT_BREAKS_SNAKE_BITE (USE_NEW_STUFF * 1) +#define USE_UFAST_PLAYER_EXIT_BUGFIX (USE_NEW_STUFF * 1) + /* for DigField() */ #define DF_NO_PUSH 0 @@ -77,23 +79,27 @@ #define EX_TYPE_DYNA (1 << 4) #define EX_TYPE_SINGLE_TILE (EX_TYPE_CENTER | EX_TYPE_BORDER) +#define PANEL_DEACTIVATED(p) ((p).x < 0 || (p).y < 0) + /* special positions in the game control window (relative to control window) */ -#define XX_LEVEL 37 -#define YY_LEVEL 20 -#define XX_EMERALDS 29 -#define YY_EMERALDS 54 -#define XX_DYNAMITE 29 -#define YY_DYNAMITE 89 -#define XX_KEYS 18 -#define YY_KEYS 123 -#define XX_SCORE 15 -#define YY_SCORE 159 -#define XX_TIME1 29 -#define XX_TIME2 30 -#define YY_TIME 194 +#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) /* 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) @@ -122,14 +128,10 @@ #define MOVE_DELAY_HIGH_SPEED 4 #define MOVE_DELAY_MAX_SPEED 1 -#if 0 -#define DOUBLE_MOVE_DELAY(x) (x = (x <= MOVE_DELAY_HIGH_SPEED ? x * 2 : x)) -#define HALVE_MOVE_DELAY(x) (x = (x >= MOVE_DELAY_HIGH_SPEED ? x / 2 : x)) -#else #define DOUBLE_MOVE_DELAY(x) (x = (x < MOVE_DELAY_MIN_SPEED ? x * 2 : x)) #define HALVE_MOVE_DELAY(x) (x = (x > MOVE_DELAY_MAX_SPEED ? x / 2 : x)) -#endif -#define DOUBLE_PLAYER_SPEED(p) (HALVE_MOVE_DELAY((p)->move_delay_value)) + +#define DOUBLE_PLAYER_SPEED(p) (HALVE_MOVE_DELAY( (p)->move_delay_value)) #define HALVE_PLAYER_SPEED(p) (DOUBLE_MOVE_DELAY((p)->move_delay_value)) /* values for other actions */ @@ -159,13 +161,8 @@ RND((c)->delay_random)) -#if 1 #define GET_VALID_RUNTIME_ELEMENT(e) \ ((e) >= NUM_RUNTIME_ELEMENTS ? EL_UNKNOWN : (e)) -#else -#define GET_VALID_FILE_ELEMENT(e) \ - ((e) >= NUM_FILE_ELEMENTS ? EL_UNKNOWN : (e)) -#endif #define RESOLVED_REFERENCE_ELEMENT(be, e) \ ((be) + (e) - EL_SELF < EL_CUSTOM_START ? EL_CUSTOM_START : \ @@ -255,15 +252,6 @@ (IN_LEV_FIELD(x, y) && (Feld[x][y] == EL_EMC_SPRING_BUMPER || \ Feld[x][y] == EL_EMC_SPRING_BUMPER_ACTIVE)) -#if 0 -#define GROUP_NR(e) ((e) - EL_GROUP_START) -#define IS_IN_GROUP(e, nr) (element_info[e].in_group[nr] == TRUE) -#define IS_IN_GROUP_EL(e, ge) (IS_IN_GROUP(e, (ge) - EL_GROUP_START)) - -#define IS_EQUAL_OR_IN_GROUP(e, ge) \ - (IS_GROUP_ELEMENT(ge) ? IS_IN_GROUP(e, GROUP_NR(ge)) : (e) == (ge)) -#endif - #define MOVE_ENTER_EL(e) (element_info[e].move_enter_element) #define CE_ENTER_FIELD_COND(e, x, y) \ @@ -408,8 +396,6 @@ static void RunTimegateWheel(int, int); static void InitMagicBallDelay(int, int); static void ActivateMagicBall(int, int); -static void InitDiagonalMovingElement(int, int); - struct ChangingElementInfo { int element; @@ -605,7 +591,7 @@ static struct ChangingElementInfo change_delay_list[] = 0, NULL, NULL, - InitDiagonalMovingElement + NULL, }, { @@ -1166,7 +1152,6 @@ static void InitField(int x, int y, boolean init_game) break; default: -#if 1 if (IS_CUSTOM_ELEMENT(element)) { if (CAN_MOVE(element)) @@ -1177,60 +1162,18 @@ static void InitField(int x, int y, boolean init_game) CustomValue[x][y] = GET_NEW_CE_VALUE(Feld[x][y]); #endif } -#else - if (IS_CUSTOM_ELEMENT(element) && CAN_MOVE(element)) - InitMovDir(x, y); -#endif else if (IS_GROUP_ELEMENT(element)) { -#if 1 Feld[x][y] = get_element_from_group_element(element); InitField(x, y, init_game); -#else - struct ElementGroupInfo *group = element_info[element].group; - int last_anim_random_frame = gfx.anim_random_frame; - int element_pos; - - if (group->choice_mode == ANIM_RANDOM) - gfx.anim_random_frame = RND(group->num_elements_resolved); - - element_pos = getAnimationFrame(group->num_elements_resolved, 1, - group->choice_mode, 0, - group->choice_pos); - - if (group->choice_mode == ANIM_RANDOM) - gfx.anim_random_frame = last_anim_random_frame; - - group->choice_pos++; - - Feld[x][y] = group->element_resolved[element_pos]; - - InitField(x, y, init_game); -#endif } break; } -#if 1 if (!init_game) CheckTriggeredElementChange(x, y, element, CE_CREATION_OF_X); -#endif - -#if 0 - -#if USE_NEW_CUSTOM_VALUE - -#if 1 - CustomValue[x][y] = GET_NEW_CE_VALUE(Feld[x][y]); -#else - CustomValue[x][y] = element_info[Feld[x][y]].custom_value_initial; -#endif - -#endif - -#endif } static inline void InitField_WithBug1(int x, int y, boolean init_game) @@ -1268,6 +1211,9 @@ inline void DrawGameValue_Emeralds(int value) { 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); } @@ -1275,6 +1221,9 @@ inline void DrawGameValue_Dynamite(int value) { 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); } @@ -1283,19 +1232,23 @@ inline void DrawGameValue_Keys(int key[MAX_NUM_KEYS]) 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); } } @@ -1303,6 +1256,9 @@ inline void DrawGameValue_Score(int value) { 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); } @@ -1311,9 +1267,12 @@ inline void DrawGameValue_Time(int value) 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); @@ -1323,26 +1282,13 @@ inline void DrawGameValue_Time(int value) 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 - { - /* misuse area for displaying emeralds to draw bigger level number */ - DrawTextExt(drawto, DX_EMERALDS, DY_EMERALDS, - int2str(value, 3), FONT_LEVEL_NUMBER, BLIT_OPAQUE); - - /* now copy it to the area for displaying level number */ - BlitBitmap(drawto, drawto, - DX_EMERALDS, DY_EMERALDS + 1, - getFontWidth(FONT_LEVEL_NUMBER) * 3, - getFontHeight(FONT_LEVEL_NUMBER) - 1, - DX_LEVEL - 1, DY_LEVEL + 1); - - /* restore the area for displaying emeralds */ - DrawGameValue_Emeralds(local_player->gems_still_needed); - - /* yes, this is all really ugly :-) */ - } + DrawText(DX_LEVEL2, DY_LEVEL, int2str(value, 3), FONT_LEVEL_NUMBER); } void DrawAllGameValues(int emeralds, int dynamite, int score, int time, @@ -1351,6 +1297,11 @@ void DrawAllGameValues(int emeralds, int dynamite, int score, int time, int key[MAX_NUM_KEYS]; int i; + /* prevent EM engine from updating time/score values parallel to GameWon() */ + if (level.game_engine_type == GAME_ENGINE_TYPE_EM && + local_player->LevelSolved) + return; + for (i = 0; i < MAX_NUM_KEYS; i++) key[i] = key_bits & (1 << i); @@ -1366,7 +1317,11 @@ void DrawAllGameValues(int emeralds, int dynamite, int score, int time, void DrawGameDoorValues() { - int dynamite_state = 0; + int time_value = (level.time == 0 ? TimePlayed : TimeLeft); + int dynamite_value = 0; + int score_value = (local_player->LevelSolved ? local_player->score_final : + local_player->score); + int gems_value = local_player->gems_still_needed; int key_bits = 0; int i, j; @@ -1377,16 +1332,6 @@ void DrawGameDoorValues() return; } -#if 0 - DrawGameValue_Level(level_nr); - - DrawGameValue_Emeralds(local_player->gems_still_needed); - DrawGameValue_Dynamite(local_player->inventory_size); - DrawGameValue_Score(local_player->score); - DrawGameValue_Time(TimeLeft); - -#else - if (game.centered_player_nr == -1) { for (i = 0; i < MAX_PLAYERS; i++) @@ -1395,12 +1340,8 @@ void DrawGameDoorValues() if (stored_player[i].key[j]) key_bits |= (1 << j); - dynamite_state += stored_player[i].inventory_size; + dynamite_value += stored_player[i].inventory_size; } - -#if 0 - DrawGameValue_Keys(stored_player[i].key); -#endif } else { @@ -1410,71 +1351,13 @@ void DrawGameDoorValues() if (stored_player[player_nr].key[i]) key_bits |= (1 << i); - dynamite_state = stored_player[player_nr].inventory_size; + dynamite_value = stored_player[player_nr].inventory_size; } - DrawAllGameValues(local_player->gems_still_needed, dynamite_state, - local_player->score, TimeLeft, key_bits); -#endif + DrawAllGameValues(gems_value, dynamite_value, score_value, time_value, + key_bits); } -#if 0 -static void resolve_group_element(int group_element, int recursion_depth) -{ - static int group_nr; - static struct ElementGroupInfo *group; - struct ElementGroupInfo *actual_group = element_info[group_element].group; - int i; - - if (recursion_depth > NUM_GROUP_ELEMENTS) /* recursion too deep */ - { - Error(ERR_WARN, "recursion too deep when resolving group element %d", - group_element - EL_GROUP_START + 1); - - /* replace element which caused too deep recursion by question mark */ - group->element_resolved[group->num_elements_resolved++] = EL_UNKNOWN; - - return; - } - - if (recursion_depth == 0) /* initialization */ - { - group = element_info[group_element].group; - group_nr = group_element - EL_GROUP_START; - - group->num_elements_resolved = 0; - group->choice_pos = 0; - } - - for (i = 0; i < actual_group->num_elements; i++) - { - int element = actual_group->element[i]; - - if (group->num_elements_resolved == NUM_FILE_ELEMENTS) - break; - - if (IS_GROUP_ELEMENT(element)) - resolve_group_element(element, recursion_depth + 1); - else - { - group->element_resolved[group->num_elements_resolved++] = element; - element_info[element].in_group[group_nr] = TRUE; - } - } -} -#endif - -#if 0 -static void replace_reference_element(int base_element, int *element) -{ - if (*element >= EL_LAST_CE_8 && *element <= EL_NEXT_CE_8) - { - *element = base_element + *element - EL_SELF; - *element = (*element < EL_CUSTOM_START ? EL_CUSTOM_START : - *element > EL_CUSTOM_END ? EL_CUSTOM_END : *element); - } -} -#endif /* ============================================================================= @@ -1606,29 +1489,12 @@ static void InitGameEngine() printf(" => game.engine_version == %06d\n", game.engine_version); #endif -#if 0 - /* ---------- recursively resolve group elements ------------------------- */ - - for (i = 0; i < MAX_NUM_ELEMENTS; i++) - for (j = 0; j < NUM_GROUP_ELEMENTS; j++) - element_info[i].in_group[j] = FALSE; - - for (i = 0; i < NUM_GROUP_ELEMENTS; i++) - resolve_group_element(EL_GROUP_START + i, 0); -#endif - /* ---------- initialize player's initial move delay --------------------- */ -#if 1 /* dynamically adjust player properties according to level information */ for (i = 0; i < MAX_PLAYERS; i++) game.initial_move_delay_value[i] = get_move_delay_from_stepsize(level.initial_player_stepsize[i]); -#else - /* dynamically adjust player properties according to level information */ - game.initial_move_delay_value = - (level.double_speed ? MOVE_DELAY_HIGH_SPEED : MOVE_DELAY_NORMAL_SPEED); -#endif /* dynamically adjust player properties according to game engine version */ for (i = 0; i < MAX_PLAYERS; i++) @@ -1778,11 +1644,9 @@ static void InitGameEngine() for (l = 0; l < group->num_elements_resolved; l++) trigger_events[group->element_resolved[l]][k] = TRUE; } -#if 1 else if (trigger_element == EL_ANY_ELEMENT) for (l = 0; l < MAX_NUM_ELEMENTS; l++) trigger_events[l][k] = TRUE; -#endif else trigger_events[trigger_element][k] = TRUE; } @@ -1798,7 +1662,6 @@ static void InitGameEngine() { if (!IS_CUSTOM_ELEMENT(i)) { -#if 1 /* set default push delay values (corrected since version 3.0.7-1) */ if (game.engine_version < VERSION_IDENT(3,0,7,1)) { @@ -1810,10 +1673,6 @@ static void InitGameEngine() element_info[i].push_delay_fixed = 8; element_info[i].push_delay_random = 8; } -#else - element_info[i].push_delay_fixed = game.default_push_delay_fixed; - element_info[i].push_delay_random = game.default_push_delay_random; -#endif } } @@ -1920,29 +1779,6 @@ static void InitGameEngine() EL_EMPTY); } } - -#if 0 - /* ---------- initialize reference elements ------------------------------- */ - for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) - { - int element = EL_CUSTOM_START + i; - struct ElementInfo *ei = &element_info[element]; - - for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) - replace_reference_element(element, &ei->content.e[x][y]); - - for (j = 0; j < ei->num_change_pages; j++) - { - struct ElementChangeInfo *change = &ei->change_page[j]; - - replace_reference_element(element, &change->target_element); - replace_reference_element(element, &change->trigger_element); - - for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) - replace_reference_element(element, &change->target_content.e[x][y]); - } - } -#endif } int get_num_special_action(int element, int action_first, int action_last) @@ -1965,13 +1801,10 @@ int get_num_special_action(int element, int action_first, int action_last) break; } -#if 0 - printf("::: %d->%d: %d\n", action_first, action_last, num_special_action); -#endif - return num_special_action; } + /* ============================================================================= InitGame() @@ -1985,8 +1818,11 @@ void InitGame() 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 */ @@ -2008,6 +1844,8 @@ void InitGame() player->programmed_action = 0; player->score = 0; + player->score_final = 0; + player->gems_still_needed = level.gems_needed; player->sokobanfields_still_needed = 0; player->lights_still_needed = 0; @@ -2075,18 +1913,6 @@ void InitGame() player->special_action_bored = ACTION_DEFAULT; player->special_action_sleeping = ACTION_DEFAULT; -#if 1 - /* cannot be set here -- could be modified in Init[Player]Field() below */ -#else - /* set number of special actions for bored and sleeping animation */ - player->num_special_action_bored = - get_num_special_action(player->artwork_element, - ACTION_BORING_1, ACTION_BORING_LAST); - player->num_special_action_sleeping = - get_num_special_action(player->artwork_element, - ACTION_SLEEPING_1, ACTION_SLEEPING_LAST); -#endif - player->switch_x = -1; player->switch_y = -1; @@ -2095,18 +1921,7 @@ void InitGame() player->show_envelope = 0; -#if 1 SetPlayerMoveSpeed(player, level.initial_player_stepsize[i], TRUE); -#else - player->move_delay = game.initial_move_delay; - player->move_delay_value = game.initial_move_delay_value; - - player->move_delay_value_next = -1; - - player->move_delay_reset_counter = 0; - - player->cannot_move = FALSE; -#endif player->push_delay = -1; /* initialized when pushing starts */ player->push_delay_value = game.initial_push_delay_value; @@ -2128,6 +1943,10 @@ void InitGame() player->LevelSolved = FALSE; player->GameOver = FALSE; + + player->LevelSolved_GameEnd = FALSE; + player->LevelSolved_SaveTape = FALSE; + player->LevelSolved_SaveScore = FALSE; } network_player_action_received = FALSE; @@ -2164,11 +1983,7 @@ void InitGame() game.wind_direction = level.wind_direction_initial; #if !USE_PLAYER_GRAVITY -#if 1 game.gravity = FALSE; -#else - game.gravity = level.initial_gravity; -#endif game.explosions_delayed = TRUE; #endif @@ -2192,11 +2007,6 @@ void InitGame() tape.set_centered_player = TRUE; } -#if 0 - printf("::: focus set to player %d [%d]\n", - game.centered_player_nr, local_player->index_nr); -#endif - for (i = 0; i < NUM_BELTS; i++) { game.belt_dir[i] = MV_NONE; @@ -2206,11 +2016,7 @@ void InitGame() for (i = 0; i < MAX_NUM_AMOEBA; i++) AmoebaCnt[i] = AmoebaCnt2[i] = 0; -#if 1 SCAN_PLAYFIELD(x, y) -#else - for (x = 0; x < lev_fieldx; x++) for (y = 0; y < lev_fieldy; y++) -#endif { Feld[x][y] = level.field[x][y]; MovPos[x][y] = MovDir[x][y] = MovDelay[x][y] = 0; @@ -2244,11 +2050,7 @@ void InitGame() GfxDir[x][y] = MV_NONE; } -#if 1 SCAN_PLAYFIELD(x, y) -#else - for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) -#endif { if (emulate_bd && !IS_BD_ELEMENT(Feld[x][y])) emulate_bd = FALSE; @@ -2266,7 +2068,6 @@ void InitGame() { struct PlayerInfo *player = &stored_player[i]; -#if 1 /* set number of special actions for bored and sleeping animation */ player->num_special_action_bored = get_num_special_action(player->artwork_element, @@ -2274,8 +2075,6 @@ void InitGame() player->num_special_action_sleeping = get_num_special_action(player->artwork_element, ACTION_SLEEPING_1, ACTION_SLEEPING_LAST); -#endif - } game.emulation = (emulate_bd ? EMU_BOULDERDASH : @@ -2356,10 +2155,6 @@ void InitGame() some_player->present = FALSE; some_player->active = FALSE; -#if 0 - player->element_nr = some_player->element_nr; -#endif - player->artwork_element = some_player->artwork_element; player->block_last_field = some_player->block_last_field; @@ -2472,11 +2267,7 @@ void InitGame() int found_element = EL_UNDEFINED; int player_nr = local_player->index_nr; -#if 1 SCAN_PLAYFIELD(x, y) -#else - for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) -#endif { int element = Feld[x][y]; int content; @@ -2573,13 +2364,21 @@ void InitGame() 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) { InitGameEngine_EM(); + + /* blit playfield from scroll buffer to normal back buffer for fading in */ + BlitScreenToBitmap_EM(backbuffer); } else { @@ -2590,14 +2389,19 @@ void InitGame() if (game.timegate_time_left == 0) CloseAllOpenTimegates(); + /* blit playfield from scroll buffer to normal back buffer for fading in */ if (setup.soft_scrolling) BlitBitmap(fieldbuffer, backbuffer, FX, FY, SXSIZE, SYSIZE, SX, SY); redraw_mask |= REDRAW_FROM_BACKBUFFER; - FadeToFront(); } /* !!! FIX THIS (END) !!! */ + if (do_fading) + FadeIn(REDRAW_FIELD); + + BackToFront(); + if (!game.restart_level) { /* copy default game door content to main double buffer */ @@ -2605,6 +2409,9 @@ void InitGame() DOOR_GFX_PAGEX5, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE, DX, DY); } + SetPanelBackground(); + SetDrawBackgroundMask(REDRAW_DOOR_1); + DrawGameDoorValues(); if (!game.restart_level) @@ -2623,7 +2430,7 @@ void InitGame() OpenDoor(DOOR_OPEN_ALL); - PlaySoundStereo(SND_GAME_STARTING, SOUND_MIDDLE); + PlaySound(SND_GAME_STARTING); if (setup.sound_music) PlayLevelMusic(); @@ -2848,123 +2655,144 @@ void InitAmoebaNr(int x, int y) AmoebaCnt2[group_nr]++; } +static void PlayerWins(struct PlayerInfo *player) +{ + player->LevelSolved = TRUE; + player->GameOver = TRUE; + + player->score_final = (level.game_engine_type == GAME_ENGINE_TYPE_EM ? + level.native_em_level->lev->score : player->score); +} + void GameWon() { - int hi_pos; - boolean raise_level = FALSE; + static int time, time_final; + static int score, score_final; + 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; - local_player->LevelSolved = FALSE; + if (tape.auto_play) /* tape might already be stopped here */ + tape.auto_play_level_solved = TRUE; - PlaySoundStereo(SND_GAME_WINNING, SOUND_MIDDLE); + game_over_delay = game_over_delay_value; - if (TimeLeft) - { - if (!tape.playing && setup.sound_loops) - PlaySoundExt(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_VOLUME, SOUND_MIDDLE, - SND_CTRL_PLAY_LOOP); + time = time_final = (level.time == 0 ? TimePlayed : TimeLeft); + score = score_final = local_player->score_final; - while (TimeLeft > 0) + if (TimeLeft > 0) { - if (!tape.playing && !setup.sound_loops) - 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]); - } + time_final = 0; + score_final += TimeLeft * level.score[SC_TIME_BONUS]; + } + else if (level.time == 0 && TimePlayed < 999) + { + time_final = 999; + score_final += (999 - TimePlayed) * level.score[SC_TIME_BONUS]; + } - DrawGameValue_Time(TimeLeft); + local_player->score_final = score_final; - BackToFront(); + if (level_editor_test_game) + { + time = time_final; + score = score_final; - if (!tape.playing) - Delay(10); + DrawGameValue_Time(time); + DrawGameValue_Score(score); } - if (!tape.playing && setup.sound_loops) - StopSound(SND_GAME_LEVELTIME_BONUS); - } - else if (level.time == 0) /* level without time limit */ - { - if (!tape.playing && setup.sound_loops) - PlaySoundExt(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_VOLUME, SOUND_MIDDLE, - SND_CTRL_PLAY_LOOP); - - while (TimePlayed < 999) + if (ExitX >= 0 && ExitY >= 0) /* local player has left the level */ { - if (!tape.playing && !setup.sound_loops) - PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MIDDLE); - - if (TimePlayed < 900 && TimePlayed % 10 == 0) + /* close exit door after last player */ + if (AllPlayersGone && + (Feld[ExitX][ExitY] == EL_EXIT_OPEN || + Feld[ExitX][ExitY] == EL_SP_EXIT_OPEN)) { - TimePlayed += 10; - RaiseScore(level.score[SC_TIME_BONUS] * 10); - } - else - { - TimePlayed++; - RaiseScore(level.score[SC_TIME_BONUS]); - } + int element = Feld[ExitX][ExitY]; - DrawGameValue_Time(TimePlayed); + Feld[ExitX][ExitY] = (element == EL_EXIT_OPEN ? EL_EXIT_CLOSING : + EL_SP_EXIT_CLOSING); - BackToFront(); + PlayLevelSoundElementAction(ExitX, ExitY, element, ACTION_CLOSING); + } - if (!tape.playing) - Delay(10); + /* player disappears */ + DrawLevelField(ExitX, ExitY); } - if (!tape.playing && setup.sound_loops) - StopSound(SND_GAME_LEVELTIME_BONUS); + PlaySound(SND_GAME_WINNING); } - /* 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)) + if (game_over_delay > 0) { - int element = Feld[ExitX][ExitY]; + game_over_delay--; - Feld[ExitX][ExitY] = (element == EL_EXIT_OPEN ? EL_EXIT_CLOSING : - EL_SP_EXIT_CLOSING); - - PlayLevelSoundElementAction(ExitX, ExitY, element, ACTION_CLOSING); + return; } - /* player disappears */ - if (ExitX >= 0 && ExitY >= 0) - DrawLevelField(ExitX, ExitY); + if (time != time_final) + { + int time_to_go = ABS(time_final - time); + int time_count_dir = (time < time_final ? +1 : -1); + int time_count_steps = (time_to_go > 100 && time_to_go % 10 == 0 ? 10 : 1); - BackToFront(); + time += time_count_steps * time_count_dir; + score += time_count_steps * level.score[SC_TIME_BONUS]; -#if 0 - if (tape.playing) - printf("::: TAPE PLAYING -> DO NOT SAVE SCORE\n"); - else - printf("::: NO TAPE PLAYING -> SAVING SCORE\n"); -#endif + DrawGameValue_Time(time); + DrawGameValue_Score(score); - if (tape.playing) - return; + if (time == time_final) + StopSound(SND_GAME_LEVELTIME_BONUS); + else if (setup.sound_loops) + PlaySoundLoop(SND_GAME_LEVELTIME_BONUS); + else + PlaySound(SND_GAME_LEVELTIME_BONUS); + } +} + +void GameEnd() +{ + int hi_pos; + boolean raise_level = FALSE; CloseDoor(DOOR_CLOSE_1); - if (tape.recording) + if (local_player->LevelSolved_SaveTape) { TapeStop(); - SaveTape(tape.level_nr); /* Ask to save tape */ + + SaveTape(tape.level_nr); /* ask to save tape */ + } + + if (level_editor_test_game) + { + game_status = GAME_MODE_MAIN; + + DrawMainMenu(); + + return; + } + + if (!local_player->LevelSolved_SaveScore) + { + FadeOut(REDRAW_FIELD); + + game_status = GAME_MODE_MAIN; + + DrawAndFadeInMainMenu(REDRAW_FIELD); + + return; } if (level_nr == leveldir_current->handicap_level) @@ -2973,15 +2801,15 @@ void GameWon() 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 (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++; @@ -2990,16 +2818,18 @@ void GameWon() } else { + FadeOut(REDRAW_FIELD); + game_status = GAME_MODE_MAIN; + if (raise_level) { level_nr++; TapeErase(); } - DrawMainMenu(); - } - BackToFront(); + DrawAndFadeInMainMenu(REDRAW_FIELD); + } } int NewHiScore() @@ -3010,12 +2840,12 @@ int NewHiScore() LoadScore(level_nr); if (strEqual(setup.player_name, EMPTY_PLAYER_NAME) || - local_player->score < highscore[MAX_SCORE_ENTRIES - 1].Score) + local_player->score_final < highscore[MAX_SCORE_ENTRIES - 1].Score) return -1; for (k = 0; k < MAX_SCORE_ENTRIES; k++) { - if (local_player->score > highscore[k].Score) + if (local_player->score_final > highscore[k].Score) { /* player has made it to the hall of fame */ @@ -3043,7 +2873,7 @@ int NewHiScore() #endif strncpy(highscore[k].Name, setup.player_name, MAX_PLAYER_NAME_LEN); highscore[k].Name[MAX_PLAYER_NAME_LEN] = '\0'; - highscore[k].Score = local_player->score; + highscore[k].Score = local_player->score_final; position = k; break; } @@ -3072,22 +2902,14 @@ inline static int getElementMoveStepsize(int x, int y) int sign = (horiz_move ? dx : dy); int step = sign * element_info[element].move_stepsize; - /* special values for move stepsize for spring and things on conveyor belt */ - if (horiz_move) - { -#if 0 - if (element == EL_SPRING) - step = sign * MOVE_STEPSIZE_NORMAL * 2; - else if (CAN_FALL(element) && !CAN_MOVE(element) && - y < lev_fieldy - 1 && IS_BELT_ACTIVE(Feld[x][y + 1])) - step = sign * MOVE_STEPSIZE_NORMAL / 2; -#else + /* special values for move stepsize for spring and things on conveyor belt */ + if (horiz_move) + { if (CAN_FALL(element) && y < lev_fieldy - 1 && IS_BELT_ACTIVE(Feld[x][y + 1])) step = sign * MOVE_STEPSIZE_NORMAL / 2; else if (element == EL_SPRING) step = sign * MOVE_STEPSIZE_NORMAL * 2; -#endif } return step; @@ -3132,28 +2954,10 @@ static void ResetGfxFrame(int x, int y, boolean redraw) static void ResetGfxAnimation(int x, int y) { -#if 0 - int element, graphic; -#endif - GfxAction[x][y] = ACTION_DEFAULT; GfxDir[x][y] = MovDir[x][y]; GfxFrame[x][y] = 0; -#if 0 - element = Feld[x][y]; - graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]); - - if (graphic_info[graphic].anim_global_sync) - GfxFrame[x][y] = FrameCounter; - else if (ANIM_MODE(graphic) == ANIM_CE_VALUE) - GfxFrame[x][y] = CustomValue[x][y]; - else if (ANIM_MODE(graphic) == ANIM_CE_SCORE) - GfxFrame[x][y] = element_info[element].collect_score; - else if (ANIM_MODE(graphic) == ANIM_CE_DELAY) - GfxFrame[x][y] = ChangeDelay[x][y]; -#endif - #if USE_GFX_RESET_GFX_ANIMATION ResetGfxFrame(x, y, FALSE); #endif @@ -3167,9 +2971,6 @@ static void ResetRandomAnimationValue(int x, int y) void InitMovingField(int x, int y, int direction) { int element = Feld[x][y]; -#if 0 - int graphic; -#endif int dx = (direction == MV_LEFT ? -1 : direction == MV_RIGHT ? +1 : 0); int dy = (direction == MV_UP ? -1 : direction == MV_DOWN ? +1 : 0); int newx = x + dx; @@ -3183,19 +2984,6 @@ void InitMovingField(int x, int y, int direction) GfxAction[x][y] = (direction == MV_DOWN && CAN_FALL(element) ? ACTION_FALLING : ACTION_MOVING); -#if 0 - graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]); - - if (graphic_info[graphic].anim_global_sync) - GfxFrame[x][y] = FrameCounter; - else if (ANIM_MODE(graphic) == ANIM_CE_VALUE) - GfxFrame[x][y] = CustomValue[x][y]; - else if (ANIM_MODE(graphic) == ANIM_CE_SCORE) - GfxFrame[x][y] = element_info[element].collect_score; - else if (ANIM_MODE(graphic) == ANIM_CE_DELAY) - GfxFrame[x][y] = ChangeDelay[x][y]; -#endif - /* this is needed for CEs with property "can move" / "not moving" */ if (getElementMoveStepsize(x, y) != 0) /* moving or being moved */ @@ -3219,13 +3007,8 @@ void InitMovingField(int x, int y, int direction) void Moving2Blocked(int x, int y, int *goes_to_x, int *goes_to_y) { int direction = MovDir[x][y]; -#if 1 int newx = x + (direction & MV_LEFT ? -1 : direction & MV_RIGHT ? +1 : 0); int newy = y + (direction & MV_UP ? -1 : direction & MV_DOWN ? +1 : 0); -#else - int newx = x + (direction == MV_LEFT ? -1 : direction == MV_RIGHT ? +1 : 0); - int newy = y + (direction == MV_UP ? -1 : direction == MV_DOWN ? +1 : 0); -#endif *goes_to_x = newx; *goes_to_y = newy; @@ -3412,8 +3195,6 @@ void CheckDynamite(int x, int y) Bang(x, y); } -#if 1 - static void setMinimalPlayerBoundaries(int *sx1, int *sy1, int *sx2, int *sy2) { boolean num_checked_players = 0; @@ -3464,33 +3245,6 @@ static void setScreenCenteredToAllPlayers(int *sx, int *sy) *sy = (sy1 + sy2) / 2; } -#if 0 -static void setMaxCenterDistanceForAllPlayers(int *max_dx, int *max_dy, - int center_x, int center_y) -{ - int sx1 = center_x, sy1 = center_y, sx2 = center_x, sy2 = center_y; - - setMinimalPlayerBoundaries(&sx1, &sy1, &sx2, &sy2); - - *max_dx = MAX(ABS(sx1 - center_x), ABS(sx2 - center_x)); - *max_dy = MAX(ABS(sy1 - center_y), ABS(sy2 - center_y)); -} - -static boolean checkIfAllPlayersAreVisible(int center_x, int center_y) -{ - int max_dx, max_dy; - - setMaxCenterDistanceForAllPlayers(&max_dx, &max_dy, center_x, center_y); - - return (max_dx <= SCR_FIELDX / 2 && - max_dy <= SCR_FIELDY / 2); -} -#endif - -#endif - -#if 1 - void DrawRelocateScreen(int x, int y, int move_dir, boolean center_screen, boolean quick_relocation) { @@ -3503,11 +3257,6 @@ void DrawRelocateScreen(int x, int y, int move_dir, boolean center_screen, { int offset = (setup.scroll_delay ? 3 : 0); -#if 0 - if (center_screen) - offset = 0; -#endif - if (!IN_VIS_FIELD(SCREENX(x), SCREENY(y)) || center_screen) { scroll_x = (x < SBX_Left + MIDPOSX ? SBX_Left : @@ -3587,102 +3336,6 @@ void DrawRelocateScreen(int x, int y, int move_dir, boolean center_screen, } } -#else - -void DrawRelocatePlayer(struct PlayerInfo *player, boolean quick_relocation) -{ - boolean ffwd_delay = (tape.playing && tape.fast_forward); - boolean no_delay = (tape.warp_forward); - int frame_delay_value = (ffwd_delay ? FfwdFrameDelay : GameFrameDelay); - int wait_delay_value = (no_delay ? 0 : frame_delay_value); - int jx = player->jx; - int jy = player->jy; - - if (quick_relocation) - { - int offset = (setup.scroll_delay ? 3 : 0); - - if (!IN_VIS_FIELD(SCREENX(jx), SCREENY(jy))) - { - scroll_x = (player->jx < SBX_Left + MIDPOSX ? SBX_Left : - player->jx > SBX_Right + MIDPOSX ? SBX_Right : - player->jx - MIDPOSX); - - scroll_y = (player->jy < SBY_Upper + MIDPOSY ? SBY_Upper : - player->jy > SBY_Lower + MIDPOSY ? SBY_Lower : - player->jy - MIDPOSY); - } - else - { - if ((player->MovDir == MV_LEFT && scroll_x > jx - MIDPOSX + offset) || - (player->MovDir == MV_RIGHT && scroll_x < jx - MIDPOSX - offset)) - scroll_x = jx - MIDPOSX + (scroll_x < jx-MIDPOSX ? -offset : +offset); - - if ((player->MovDir == MV_UP && scroll_y > jy - MIDPOSY + offset) || - (player->MovDir == MV_DOWN && scroll_y < jy - MIDPOSY - offset)) - scroll_y = jy - MIDPOSY + (scroll_y < jy-MIDPOSY ? -offset : +offset); - - /* don't scroll over playfield boundaries */ - if (scroll_x < SBX_Left || scroll_x > SBX_Right) - scroll_x = (scroll_x < SBX_Left ? SBX_Left : SBX_Right); - - /* don't scroll over playfield boundaries */ - if (scroll_y < SBY_Upper || scroll_y > SBY_Lower) - scroll_y = (scroll_y < SBY_Upper ? SBY_Upper : SBY_Lower); - } - - RedrawPlayfield(TRUE, 0,0,0,0); - } - else - { - int scroll_xx = (player->jx < SBX_Left + MIDPOSX ? SBX_Left : - player->jx > SBX_Right + MIDPOSX ? SBX_Right : - player->jx - MIDPOSX); - - int scroll_yy = (player->jy < SBY_Upper + MIDPOSY ? SBY_Upper : - player->jy > SBY_Lower + MIDPOSY ? SBY_Lower : - player->jy - MIDPOSY); - - ScrollScreen(NULL, SCROLL_GO_ON); /* scroll last frame to full tile */ - - while (scroll_x != scroll_xx || scroll_y != scroll_yy) - { - int dx = 0, dy = 0; - int fx = FX, fy = FY; - - dx = (scroll_xx < scroll_x ? +1 : scroll_xx > scroll_x ? -1 : 0); - dy = (scroll_yy < scroll_y ? +1 : scroll_yy > scroll_y ? -1 : 0); - - if (dx == 0 && dy == 0) /* no scrolling needed at all */ - break; - - scroll_x -= dx; - scroll_y -= dy; - - fx += dx * TILEX / 2; - fy += dy * TILEY / 2; - - ScrollLevel(dx, dy); - DrawAllPlayers(); - - /* scroll in two steps of half tile size to make things smoother */ - BlitBitmap(drawto_field, window, fx, fy, SXSIZE, SYSIZE, SX, SY); - FlushDisplay(); - Delay(wait_delay_value); - - /* scroll second step to align at full tile size */ - BackToFront(); - Delay(wait_delay_value); - } - - DrawPlayer(player); - BackToFront(); - Delay(wait_delay_value); - } -} - -#endif - void RelocatePlayer(int jx, int jy, int el_player_raw) { int el_player = GET_PLAYER_ELEMENT(el_player_raw); @@ -3758,19 +3411,9 @@ void RelocatePlayer(int jx, int jy, int el_player_raw) InitField(jx, jy, FALSE); } -#if 1 /* only visually relocate centered player */ -#if 1 DrawRelocateScreen(player->jx, player->jy, player->MovDir, FALSE, level.instant_relocation); -#else - if (player->index_nr == game.centered_player_nr) - DrawRelocatePlayer(player, level.instant_relocation); -#endif -#else - if (player == local_player) /* only visually relocate local player */ - DrawRelocatePlayer(player, level.instant_relocation); -#endif TestIfPlayerTouchesBadThing(jx, jy); TestIfPlayerTouchesCustomElement(jx, jy); @@ -3856,11 +3499,7 @@ void Explode(int ex, int ey, int phase, int mode) PlayLevelSoundElementAction(ex, ey, artwork_element, ACTION_EXPLODING); #endif -#if 1 last_phase = element_info[explosion_element].explosion_delay + 1; -#else - last_phase = element_info[center_element].explosion_delay + 1; -#endif for (y = ey - 1; y <= ey + 1; y++) for (x = ex - 1; x <= ex + 1; x++) { @@ -3933,33 +3572,14 @@ void Explode(int ex, int ey, int phase, int mode) if (IS_PLAYER(ex, ey) && !PLAYER_EXPLOSION_PROTECTED(ex, ey)) { -#if 1 int player_nr = StorePlayer[ex][ey] - EL_PLAYER_1; Store[x][y] = EL_PLAYER_IS_EXPLODING_1 + player_nr; -#else - switch(StorePlayer[ex][ey]) - { - case EL_PLAYER_2: - Store[x][y] = EL_PLAYER_IS_EXPLODING_2; - break; - case EL_PLAYER_3: - Store[x][y] = EL_PLAYER_IS_EXPLODING_3; - break; - case EL_PLAYER_4: - Store[x][y] = EL_PLAYER_IS_EXPLODING_4; - break; - case EL_PLAYER_1: - default: - Store[x][y] = EL_PLAYER_IS_EXPLODING_1; - break; - } -#endif if (PLAYERINFO(ex, ey)->use_murphy) Store[x][y] = EL_EMPTY; } -#if 1 + /* !!! check this case -- currently needed for rnd_rado_negundo_v, !!! levels 015 018 019 020 021 022 023 026 027 028 !!! */ else if (ELEM_IS_PLAYER(center_element)) @@ -3980,45 +3600,6 @@ void Explode(int ex, int ey, int phase, int mode) #endif else Store[x][y] = EL_EMPTY; -#else - else if (center_element == EL_MOLE) - Store[x][y] = EL_EMERALD_RED; - else if (center_element == EL_PENGUIN) - Store[x][y] = EL_EMERALD_PURPLE; - else if (center_element == EL_BUG) - Store[x][y] = ((x == ex && y == ey) ? EL_DIAMOND : EL_EMERALD); - else if (center_element == EL_BD_BUTTERFLY) - Store[x][y] = EL_BD_DIAMOND; - else if (center_element == EL_SP_ELECTRON) - Store[x][y] = EL_SP_INFOTRON; - else if (center_element == EL_AMOEBA_TO_DIAMOND) - Store[x][y] = level.amoeba_content; - else if (center_element == EL_YAMYAM) - Store[x][y] = level.yamyam_content[game.yamyam_content_nr].e[xx][yy]; - else if (IS_CUSTOM_ELEMENT(center_element) && - element_info[center_element].content.e[xx][yy] != EL_EMPTY) - Store[x][y] = element_info[center_element].content.e[xx][yy]; - else if (element == EL_WALL_EMERALD) - Store[x][y] = EL_EMERALD; - else if (element == EL_WALL_DIAMOND) - Store[x][y] = EL_DIAMOND; - else if (element == EL_WALL_BD_DIAMOND) - Store[x][y] = EL_BD_DIAMOND; - else if (element == EL_WALL_EMERALD_YELLOW) - Store[x][y] = EL_EMERALD_YELLOW; - else if (element == EL_WALL_EMERALD_RED) - Store[x][y] = EL_EMERALD_RED; - else if (element == EL_WALL_EMERALD_PURPLE) - Store[x][y] = EL_EMERALD_PURPLE; - else if (element == EL_WALL_PEARL) - Store[x][y] = EL_PEARL; - else if (element == EL_WALL_CRYSTAL) - Store[x][y] = EL_CRYSTAL; - else if (IS_CUSTOM_ELEMENT(element) && !CAN_EXPLODE(element)) - Store[x][y] = element_info[element].content.e[1][1]; - else - Store[x][y] = EL_EMPTY; -#endif if (x != ex || y != ey || mode == EX_TYPE_BORDER || center_element == EL_AMOEBA_TO_DIAMOND) @@ -4027,11 +3608,6 @@ void Explode(int ex, int ey, int phase, int mode) Feld[x][y] = EL_EXPLOSION; GfxElement[x][y] = artwork_element; -#if 0 - printf(":: setting gfx(%d,%d) to %d ['%s']\n", - x, y, artwork_element, EL_NAME(artwork_element)); -#endif - ExplodePhase[x][y] = 1; ExplodeDelay[x][y] = last_phase; @@ -4369,11 +3945,7 @@ static void InitBeltMovement() } } -#if 1 SCAN_PLAYFIELD(x, y) -#else - for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) -#endif { int element = Feld[x][y]; @@ -4453,11 +4025,7 @@ static void ToggleBeltSwitch(int x, int y) graphic_info[graphic].anim_mode |= ANIM_REVERSE; } -#if 1 SCAN_PLAYFIELD(xx, yy) -#else - for (yy = 0; yy < lev_fieldy; yy++) for (xx = 0; xx < lev_fieldx; xx++) -#endif { int element = Feld[xx][yy]; @@ -4504,11 +4072,7 @@ static void ToggleSwitchgateSwitch(int x, int y) game.switchgate_pos = !game.switchgate_pos; -#if 1 SCAN_PLAYFIELD(xx, yy) -#else - for (yy = 0; yy < lev_fieldy; yy++) for (xx = 0; xx < lev_fieldx; xx++) -#endif { int element = Feld[xx][yy]; @@ -4568,11 +4132,7 @@ static void RedrawAllLightSwitchesAndInvisibleElements() { int x, y; -#if 1 SCAN_PLAYFIELD(x, y) -#else - for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) -#endif { int element = Feld[x][y]; @@ -4633,11 +4193,7 @@ static void RedrawAllInvisibleElementsForLenses() { int x, y; -#if 1 SCAN_PLAYFIELD(x, y) -#else - for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) -#endif { int element = Feld[x][y]; @@ -4686,11 +4242,7 @@ static void RedrawAllInvisibleElementsForMagnifier() { int x, y; -#if 1 SCAN_PLAYFIELD(x, y) -#else - for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) -#endif { int element = Feld[x][y]; @@ -4750,11 +4302,7 @@ static void ActivateTimegateSwitch(int x, int y) game.timegate_time_left = level.time_timegate * FRAMES_PER_SECOND; -#if 1 SCAN_PLAYFIELD(xx, yy) -#else - for (yy = 0; yy < lev_fieldy; yy++) for (xx = 0; xx < lev_fieldx; xx++) -#endif { int element = Feld[xx][yy]; @@ -4881,11 +4429,7 @@ void Impact(int x, int y) EL_BD_MAGIC_WALL_ACTIVE); /* activate magic wall / mill */ -#if 1 SCAN_PLAYFIELD(xx, yy) -#else - for (yy = 0; yy < lev_fieldy; yy++) for (xx = 0; xx < lev_fieldx; xx++) -#endif if (Feld[xx][yy] == smashed) Feld[xx][yy] = activated_magic_wall; @@ -5836,9 +5380,6 @@ inline static void TurnRoundExt(int x, int y) static void TurnRound(int x, int y) { int direction = MovDir[x][y]; -#if 0 - int element, graphic; -#endif TurnRoundExt(x, y); @@ -5850,21 +5391,7 @@ static void TurnRound(int x, int y) if (MovDelay[x][y]) GfxAction[x][y] = ACTION_TURNING_FROM_LEFT + MV_DIR_TO_BIT(direction); -#if 1 ResetGfxFrame(x, y, FALSE); -#else - element = Feld[x][y]; - graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]); - - if (graphic_info[graphic].anim_global_sync) - GfxFrame[x][y] = FrameCounter; - else if (ANIM_MODE(graphic) == ANIM_CE_VALUE) - GfxFrame[x][y] = CustomValue[x][y]; - else if (ANIM_MODE(graphic) == ANIM_CE_SCORE) - GfxFrame[x][y] = element_info[element].collect_score; - else if (ANIM_MODE(graphic) == ANIM_CE_DELAY) - GfxFrame[x][y] = ChangeDelay[x][y]; -#endif } static boolean JustBeingPushed(int x, int y) @@ -6389,7 +5916,7 @@ void StartMoving(int x, int y) local_player->friends_still_needed--; if (!local_player->friends_still_needed && !local_player->GameOver && AllPlayersGone) - local_player->LevelSolved = local_player->GameOver = TRUE; + PlayerWins(local_player); return; } @@ -6885,29 +6412,17 @@ void ContinueMoving(int x, int y) MovDelay[newx][newy] = 0; -#if 1 if (CAN_CHANGE_OR_HAS_ACTION(element)) -#else - if (CAN_CHANGE(element)) -#endif { /* copy element change control values to new field */ ChangeDelay[newx][newy] = ChangeDelay[x][y]; ChangePage[newx][newy] = ChangePage[x][y]; ChangeCount[newx][newy] = ChangeCount[x][y]; ChangeEvent[newx][newy] = ChangeEvent[x][y]; - -#if 0 -#if USE_NEW_CUSTOM_VALUE - CustomValue[newx][newy] = CustomValue[x][y]; -#endif -#endif } -#if 1 #if USE_NEW_CUSTOM_VALUE CustomValue[newx][newy] = CustomValue[x][y]; -#endif #endif ChangeDelay[x][y] = 0; @@ -7073,12 +6588,10 @@ void ContinueMoving(int x, int y) TestIfPlayerTouchesCustomElement(newx, newy); TestIfElementTouchesCustomElement(newx, newy); -#if 1 if (IS_CUSTOM_ELEMENT(element) && ei->move_enter_element != EL_EMPTY && IS_EQUAL_OR_IN_GROUP(stored_new, ei->move_enter_element)) CheckElementChangeBySide(newx, newy, element, stored_new, CE_DIGGING_X, MV_DIR_OPPOSITE(direction)); -#endif } int AmoebeNachbarNr(int ax, int ay) @@ -7147,11 +6660,7 @@ void AmoebenVereinigen(int ax, int ay) AmoebaCnt2[new_group_nr] += AmoebaCnt2[old_group_nr]; AmoebaCnt2[old_group_nr] = 0; -#if 1 SCAN_PLAYFIELD(xx, yy) -#else - for (yy = 0; yy < lev_fieldy; yy++) for (xx = 0; xx < lev_fieldx; xx++) -#endif { if (AmoebaNr[xx][yy] == old_group_nr) AmoebaNr[xx][yy] = new_group_nr; @@ -7177,11 +6686,7 @@ void AmoebeUmwandeln(int ax, int ay) } #endif -#if 1 SCAN_PLAYFIELD(x, y) -#else - for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) -#endif { if (Feld[x][y] == EL_AMOEBA_DEAD && AmoebaNr[x][y] == group_nr) { @@ -7239,11 +6744,7 @@ void AmoebeUmwandelnBD(int ax, int ay, int new_element) } #endif -#if 1 SCAN_PLAYFIELD(x, y) -#else - for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) -#endif { if (AmoebaNr[x][y] == group_nr && (Feld[x][y] == EL_AMOEBA_DEAD || @@ -7492,9 +6993,6 @@ void AmoebeAbleger(int ax, int ay) void Life(int ax, int ay) { int x1, y1, x2, y2; -#if 0 - static int life[4] = { 2, 3, 3, 3 }; /* parameters for "game of life" */ -#endif int life_time = 40; int element = Feld[ax][ay]; int graphic = el2img(element); @@ -7639,13 +7137,6 @@ static void ActivateMagicBall(int bx, int by) game.ball_content_nr = (game.ball_content_nr + 1) % level.num_ball_contents; } -static void InitDiagonalMovingElement(int x, int y) -{ -#if 0 - MovDelay[x][y] = level.android_move_time; -#endif -} - void CheckExit(int x, int y) { if (local_player->gems_still_needed > 0 || @@ -7694,11 +7185,7 @@ static void CloseAllOpenTimegates() { int x, y; -#if 1 SCAN_PLAYFIELD(x, y) -#else - for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) -#endif { int element = Feld[x][y]; @@ -8093,7 +7580,7 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) action_type == CA_SET_LEVEL_GEMS ? level.gems_needed : action_type == CA_SET_LEVEL_TIME ? level.time : action_type == CA_SET_LEVEL_SCORE ? 0 : -#if 1 +#if USE_NEW_CUSTOM_VALUE action_type == CA_SET_CE_VALUE ? GET_NEW_CE_VALUE(element) : #else action_type == CA_SET_CE_VALUE ? ei->custom_value_initial : @@ -8249,7 +7736,7 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) { for (i = 0; i < MAX_PLAYERS; i++) if (action_arg_player_bits & (1 << i)) - stored_player[i].LevelSolved = stored_player[i].GameOver = TRUE; + PlayerWins(&stored_player[i]); break; } @@ -8277,13 +7764,7 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) { stored_player[i].key[KEY_NR(element)] = key_state; -#if 1 DrawGameDoorValues(); -#else - DrawGameValue_Keys(stored_player[i].key); -#endif - - redraw_mask |= REDRAW_DOOR_1; } } } @@ -8323,18 +7804,7 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) action_arg_number_min, action_arg_number_max); -#if 1 SetPlayerMoveSpeed(&stored_player[i], move_stepsize, FALSE); -#else - /* make sure that value is power of 2 */ - move_stepsize = (1 << log_2(move_stepsize)); - - /* do no immediately change -- the player might just be moving */ - stored_player[i].move_delay_value_next = TILEX / move_stepsize; - - stored_player[i].cannot_move = - (action_arg == CA_ARG_SPEED_NOT_MOVING ? TRUE : FALSE); -#endif } } @@ -8425,10 +7895,6 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) CustomValue[x][y] = action_arg_number_new; -#if 0 - printf("::: CE value == %d\n", CustomValue[x][y]); -#endif - if (CustomValue[x][y] != last_ce_value) { CheckElementChange(x, y, element, EL_UNDEFINED, CE_VALUE_CHANGES); @@ -8436,19 +7902,10 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) if (CustomValue[x][y] == 0) { -#if 0 - printf("::: CE_VALUE_GETS_ZERO\n"); -#endif - CheckElementChange(x, y, element, EL_UNDEFINED, CE_VALUE_GETS_ZERO); - CheckTriggeredElementChange(x, y, element, CE_VALUE_GETS_ZERO_OF_X); - -#if 0 - printf("::: RESULT: %d, %d\n", Feld[x][y], ChangePage[x][y]); -#endif + CheckTriggeredElementChange(x, y, element, CE_VALUE_GETS_ZERO_OF_X); } } - #endif break; @@ -8461,10 +7918,6 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) ei->collect_score = action_arg_number_new; -#if 0 - printf("::: CE score == %d\n", ei->collect_score); -#endif - if (ei->collect_score != last_ce_score) { CheckElementChange(x, y, element, EL_UNDEFINED, CE_SCORE_CHANGES); @@ -8474,18 +7927,9 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) { int xx, yy; -#if 0 - printf("::: CE_SCORE_GETS_ZERO\n"); -#endif - CheckElementChange(x, y, element, EL_UNDEFINED, CE_SCORE_GETS_ZERO); CheckTriggeredElementChange(x, y, element, CE_SCORE_GETS_ZERO_OF_X); -#if 0 - printf("::: RESULT: %d, %d\n", Feld[x][y], ChangePage[x][y]); -#endif - -#if 1 /* This is a very special case that seems to be a mixture between CheckElementChange() and CheckTriggeredElementChange(): while @@ -8503,10 +7947,8 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) CheckElementChange(xx, yy, element, EL_UNDEFINED, CE_SCORE_GETS_ZERO); } -#endif } } - #endif break; @@ -9031,11 +8473,7 @@ static boolean CheckTriggeredElementChangeExt(int trigger_x, int trigger_y, { int x, y; -#if 1 SCAN_PLAYFIELD(x, y) -#else - for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) -#endif { if (Feld[x][y] == element) { @@ -9240,11 +8678,7 @@ static void SetPlayerWaiting(struct PlayerInfo *player, boolean is_waiting) game.player_sleeping_delay_fixed + SimpleRND(game.player_sleeping_delay_random); -#if 1 InitPlayerGfxAnimation(player, ACTION_WAITING, move_dir); -#else - InitPlayerGfxAnimation(player, ACTION_WAITING, player->MovDir); -#endif } if (game.player_sleeping_delay_fixed + @@ -9262,7 +8696,6 @@ static void SetPlayerWaiting(struct PlayerInfo *player, boolean is_waiting) player->is_bored ? ACTION_BORING : ACTION_WAITING); -#if 1 if (player->is_sleeping && player->use_murphy) { /* special case for sleeping Murphy when leaning against non-free tile */ @@ -9280,7 +8713,6 @@ static void SetPlayerWaiting(struct PlayerInfo *player, boolean is_waiting) player->dir_waiting = move_dir; } -#endif if (player->is_sleeping) { @@ -9442,7 +8874,8 @@ static void CheckLevelTime() { if (level.native_em_level->lev->home == 0) /* all players at home */ { - local_player->LevelSolved = TRUE; + PlayerWins(local_player); + AllPlayersGone = TRUE; level.native_em_level->lev->home = -1; @@ -9473,7 +8906,7 @@ static void CheckLevelTime() } } - if (!level.use_step_counter) + if (!local_player->LevelSolved && !level.use_step_counter) { TimePlayed++; @@ -9482,7 +8915,7 @@ static void CheckLevelTime() TimeLeft--; if (TimeLeft <= 10 && setup.time_limit) - PlaySoundStereo(SND_GAME_RUNNING_OUT_OF_TIME, SOUND_MIDDLE); + PlaySound(SND_GAME_RUNNING_OUT_OF_TIME); DrawGameValue_Time(TimeLeft); @@ -9511,11 +8944,6 @@ void AdvanceFrameAndPlayerCounters(int player_nr) { int i; -#if 0 - Error(ERR_NETWORK_CLIENT, "advancing frame counter from %d to %d", - FrameCounter, FrameCounter + 1); -#endif - /* advance frame counters (global frame counter and time frame counter) */ FrameCounter++; TimeFrames++; @@ -9580,10 +9008,6 @@ void StartGameActions(boolean init_network_game, boolean record_tape, } #endif - StopAnimation(); - - game_status = GAME_MODE_PLAYING; - InitGame(); } @@ -9603,7 +9027,8 @@ void GameActions() { if (level.native_em_level->lev->home == 0) /* all players at home */ { - local_player->LevelSolved = TRUE; + PlayerWins(local_player); + AllPlayersGone = TRUE; level.native_em_level->lev->home = -1; @@ -9659,12 +9084,17 @@ void GameActions() /* at this point we know that we really continue executing the game */ -#if 1 network_player_action_received = FALSE; -#endif + /* when playing tape, read previously recorded player input from tape data */ recorded_player_action = (tape.playing ? TapePlayAction() : NULL); +#if 1 + /* TapePlayAction() may return NULL when toggling to "pause before death" */ + if (tape.pausing) + return; +#endif + if (tape.set_centered_player) { game.centered_player_nr_next = tape.centered_player_nr_next; @@ -9730,10 +9160,6 @@ void GameActions_EM_Main() for (i = 0; i < MAX_PLAYERS; i++) effective_action[i] = stored_player[i].effective_action; -#if 0 - printf("::: %04d: %08x\n", FrameCounter, effective_action[0]); -#endif - GameActions_EM(effective_action, warp_mode); CheckLevelTime(); @@ -9759,7 +9185,6 @@ void GameActions_RND() } #endif -#if 1 if (game.set_centered_player) { boolean all_players_fit_to_screen = checkIfAllPlayersFitToScreen_RND(); @@ -9801,7 +9226,6 @@ void GameActions_RND() DrawRelocateScreen(sx, sy, MV_NONE, TRUE, setup.quick_switch); DrawGameDoorValues(); } -#endif for (i = 0; i < MAX_PLAYERS; i++) { @@ -9822,22 +9246,11 @@ void GameActions_RND() if (stored_player[i].programmed_action) actual_player_action = stored_player[i].programmed_action; -#if 1 PlayerActions(&stored_player[i], actual_player_action); -#else - tape_action[i] = PlayerActions(&stored_player[i], actual_player_action); - - if (tape.recording && tape_action[i] && !tape.player_participates[i]) - tape.player_participates[i] = TRUE; /* player just appeared from CE */ -#endif ScrollPlayer(&stored_player[i], SCROLL_GO_ON); } -#if 0 - network_player_action_received = FALSE; -#endif - ScrollScreen(NULL, SCROLL_GO_ON); /* for backwards compatibility, the following code emulates a fixed bug that @@ -9872,11 +9285,7 @@ void GameActions_RND() } } -#if 1 SCAN_PLAYFIELD(x, y) -#else - for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) -#endif { ChangeCount[x][y] = 0; ChangeEvent[x][y] = -1; @@ -9948,61 +9357,12 @@ void GameActions_RND() #endif } -#if 1 SCAN_PLAYFIELD(x, y) -#else - for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) -#endif { element = Feld[x][y]; graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]); -#if 0 - printf("::: %d,%d\n", x, y); - - if (element == EL_ROCK) - printf("::: Yo man! Rocks can fall!\n"); -#endif - -#if 1 ResetGfxFrame(x, y, TRUE); -#else - if (graphic_info[graphic].anim_global_sync) - GfxFrame[x][y] = FrameCounter; - else if (ANIM_MODE(graphic) == ANIM_CE_VALUE) - { - int old_gfx_frame = GfxFrame[x][y]; - - GfxFrame[x][y] = CustomValue[x][y]; - -#if 1 - if (GfxFrame[x][y] != old_gfx_frame) -#endif - DrawLevelGraphicAnimation(x, y, graphic); - } - else if (ANIM_MODE(graphic) == ANIM_CE_SCORE) - { - int old_gfx_frame = GfxFrame[x][y]; - - GfxFrame[x][y] = element_info[element].collect_score; - -#if 1 - if (GfxFrame[x][y] != old_gfx_frame) -#endif - DrawLevelGraphicAnimation(x, y, graphic); - } - else if (ANIM_MODE(graphic) == ANIM_CE_DELAY) - { - int old_gfx_frame = GfxFrame[x][y]; - - GfxFrame[x][y] = ChangeDelay[x][y]; - -#if 1 - if (GfxFrame[x][y] != old_gfx_frame) -#endif - DrawLevelGraphicAnimation(x, y, graphic); - } -#endif if (ANIM_MODE(graphic) == ANIM_RANDOM && IS_NEXT_FRAME(GfxFrame[x][y], graphic)) @@ -10025,18 +9385,6 @@ void GameActions_RND() (game.engine_version < VERSION_IDENT(3,0,7,1) || !Stop[x][y])) { int page = element_info[element].event_page_nr[CE_DELAY]; -#if 0 - HandleElementChange(x, y, ChangePage[x][y] != -1 ? ChangePage[x][y] : page); -#else - -#if 0 - printf("::: ChangeDelay == %d\n", ChangeDelay[x][y]); -#endif - -#if 0 - if (element == EL_CUSTOM_255) - printf("::: ChangeDelay == %d\n", ChangeDelay[x][y]); -#endif #if 1 HandleElementChange(x, y, page); @@ -10046,8 +9394,6 @@ void GameActions_RND() if (HAS_ACTION(element)) ExecuteCustomElementAction(x, y, element, page); -#endif - #endif element = Feld[x][y]; @@ -10115,21 +9461,13 @@ void GameActions_RND() element == EL_DIAGONAL_SHRINKING || element == EL_DIAGONAL_GROWING) { -#if 1 graphic = el_act_dir2img(GfxElement[x][y], GfxAction[x][y],GfxDir[x][y]); DrawLevelGraphicAnimationIfNeeded(x, y, graphic); -#endif } else if (IS_ANIMATED(graphic) && !IS_CHANGING(x, y)) DrawLevelGraphicAnimationIfNeeded(x, y, graphic); -#if 0 - if (element == EL_CUSTOM_255 || - element == EL_CUSTOM_256) - DrawLevelGraphicAnimation(x, y, graphic); -#endif - if (IS_BELT_ACTIVE(element)) PlayLevelSoundAction(x, y, ACTION_ACTIVE); @@ -10189,11 +9527,7 @@ void GameActions_RND() { game.explosions_delayed = FALSE; -#if 1 SCAN_PLAYFIELD(x, y) -#else - for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) -#endif { element = Feld[x][y]; @@ -10227,11 +9561,7 @@ void GameActions_RND() game.magic_wall_time_left--; if (!game.magic_wall_time_left) { -#if 1 SCAN_PLAYFIELD(x, y) -#else - for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) -#endif { element = Feld[x][y]; @@ -10526,7 +9856,6 @@ boolean MovePlayerOneStep(struct PlayerInfo *player, if (!player_can_move) { -#if 1 if (player->MovPos == 0) { player->is_moving = FALSE; @@ -10535,14 +9864,6 @@ boolean MovePlayerOneStep(struct PlayerInfo *player, player->is_snapping = FALSE; player->is_pushing = FALSE; } -#else - DigField(player, 0, 0, 0, 0, 0, 0, DF_NO_PUSH); - SnapField(player, 0, 0); -#endif - -#if 0 - return MP_NO_ACTION; -#endif } #if 1 @@ -10577,18 +9898,9 @@ boolean MovePlayerOneStep(struct PlayerInfo *player, #endif can_move = DigField(player, jx, jy, new_jx, new_jy, real_dx,real_dy, DF_DIG); -#if 0 -#if USE_FIXED_DONT_RUN_INTO - if (can_move == MP_DONT_RUN_INTO) - return MP_MOVING; -#endif -#endif if (can_move != MP_MOVING) return can_move; -#if USE_FIXED_DONT_RUN_INTO -#endif - /* check if DigField() has caused relocation of the player */ if (player->jx != jx || player->jy != jy) return MP_NO_ACTION; /* <-- !!! CHECK THIS [-> MP_ACTION ?] !!! */ @@ -10613,7 +9925,14 @@ boolean MovePlayerOneStep(struct PlayerInfo *player, 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; } @@ -10811,6 +10130,11 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy) 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 { @@ -10902,12 +10226,6 @@ void ScrollPlayer(struct PlayerInfo *player, int mode) else if (!FrameReached(&player->actual_frame_counter, 1)) return; -#if 0 - printf("::: player->MovPos: %d -> %d\n", - player->MovPos, - player->MovPos + (player->MovPos > 0 ? -1 : 1) * move_stepsize); -#endif - #if USE_NEW_PLAYER_SPEED if (player->MovPos != 0) { @@ -10929,10 +10247,6 @@ void ScrollPlayer(struct PlayerInfo *player, int mode) if (player->MovPos == 0) /* player reached destination field */ { -#if 0 - printf("::: player reached destination field\n"); -#endif - if (player->move_delay_reset_counter > 0) { player->move_delay_reset_counter--; @@ -10959,7 +10273,7 @@ void ScrollPlayer(struct PlayerInfo *player, int mode) if (local_player->friends_still_needed == 0 || IS_SP_ELEMENT(Feld[jx][jy])) - player->LevelSolved = player->GameOver = TRUE; + PlayerWins(player); } /* this breaks one level: "machine", level 000 */ @@ -11007,7 +10321,7 @@ void ScrollPlayer(struct PlayerInfo *player, int mode) RemovePlayer(player); } - if (level.use_step_counter) + if (!local_player->LevelSolved && level.use_step_counter) { int i; @@ -11018,7 +10332,7 @@ void ScrollPlayer(struct PlayerInfo *player, int mode) TimeLeft--; if (TimeLeft <= 10 && setup.time_limit) - PlaySoundStereo(SND_GAME_RUNNING_OUT_OF_TIME, SOUND_MIDDLE); + PlaySound(SND_GAME_RUNNING_OUT_OF_TIME); DrawGameValue_Time(TimeLeft); @@ -11804,31 +11118,6 @@ int DigField(struct PlayerInfo *player, game.engine_version >= VERSION_IDENT(2,2,0,0)) old_element = Back[jx][jy]; - /* checking here causes player to move into acid even if the current field - cannot be left to that direction */ -#if 0 -#if USE_FIXED_DONT_RUN_INTO - if (player_can_move && DONT_RUN_INTO(element)) - { - if (element == EL_ACID && dx == 0 && dy == 1) - { - SplashAcid(x, y); - Feld[jx][jy] = EL_PLAYER_1; - InitMovingField(jx, jy, MV_DOWN); - Store[jx][jy] = EL_ACID; - ContinueMoving(jx, jy); - BuryPlayer(player); - } - else - TestIfPlayerRunsIntoBadThing(jx, jy, player->MovDir); - - return MP_DONT_RUN_INTO; - } -#endif -#endif - -#if 1 /* ------------------------------ NEW ------------------------------ */ - if (IS_WALKABLE(old_element) && !ACCESS_FROM(old_element, move_direction)) return MP_NO_ACTION; /* field has no opening in this direction */ @@ -11839,11 +11128,8 @@ int DigField(struct PlayerInfo *player, if (player_can_move && element == EL_ACID && move_direction == MV_DOWN) { SplashAcid(x, y); -#if 1 + Feld[jx][jy] = player->artwork_element; -#else - Feld[jx][jy] = EL_PLAYER_1; -#endif InitMovingField(jx, jy, MV_DOWN); Store[jx][jy] = EL_ACID; ContinueMoving(jx, jy); @@ -11862,65 +11148,6 @@ int DigField(struct PlayerInfo *player, } #endif -#else /* ------------------------------ OLD ------------------------------ */ - -#if 1 -#if USE_FIXED_DONT_RUN_INTO - if (player_can_move && DONT_RUN_INTO(element)) - { - TestIfPlayerRunsIntoBadThing(jx, jy, player->MovDir); - - return MP_DONT_RUN_INTO; - } -#endif -#endif - - if (IS_WALKABLE(old_element) && !ACCESS_FROM(old_element, move_direction)) - return MP_NO_ACTION; /* field has no opening in this direction */ - - if (IS_PASSABLE(old_element) && !ACCESS_FROM(old_element,opposite_direction)) - return MP_NO_ACTION; /* field has no opening in this direction */ - - /* checking here causes player to explode when moving into acid */ -#if 1 -#if USE_FIXED_DONT_RUN_INTO - if (player_can_move && element == EL_ACID && move_direction == MV_DOWN) - { - SplashAcid(x, y); - Feld[jx][jy] = EL_PLAYER_1; - InitMovingField(jx, jy, MV_DOWN); - Store[jx][jy] = EL_ACID; - ContinueMoving(jx, jy); - BuryPlayer(player); - - return MP_DONT_RUN_INTO; - } -#endif -#endif - -#endif /* ------------------------------ END ------------------------------ */ - -#if 0 -#if USE_FIXED_DONT_RUN_INTO - if (player_can_move && DONT_RUN_INTO(element)) - { - if (element == EL_ACID && dx == 0 && dy == 1) - { - SplashAcid(x, y); - Feld[jx][jy] = EL_PLAYER_1; - InitMovingField(jx, jy, MV_DOWN); - Store[jx][jy] = EL_ACID; - ContinueMoving(jx, jy); - BuryPlayer(player); - } - else - TestIfPlayerRunsIntoBadThing(jx, jy, player->MovDir); - - return MP_DONT_RUN_INTO; - } -#endif -#endif - #if USE_FIXED_DONT_RUN_INTO if (IS_MOVING(x, y) || IS_PLAYER(x, y)) return MP_NO_ACTION; @@ -12146,11 +11373,7 @@ int DigField(struct PlayerInfo *player, if (player->inventory_size < MAX_INVENTORY_SIZE) player->inventory_element[player->inventory_size++] = element; -#if 1 DrawGameDoorValues(); -#else - DrawGameValue_Dynamite(local_player->inventory_size); -#endif } else if (element == EL_DYNABOMB_INCREASE_NUMBER) { @@ -12169,13 +11392,7 @@ int DigField(struct PlayerInfo *player, { player->key[KEY_NR(element)] = TRUE; -#if 1 DrawGameDoorValues(); -#else - DrawGameValue_Keys(player->key); -#endif - - redraw_mask |= REDRAW_DOOR_1; } else if (IS_ENVELOPE(element)) { @@ -12205,11 +11422,7 @@ int DigField(struct PlayerInfo *player, if (player->inventory_size < MAX_INVENTORY_SIZE) player->inventory_element[player->inventory_size++] = element; -#if 1 DrawGameDoorValues(); -#else - DrawGameValue_Dynamite(local_player->inventory_size); -#endif } else if (collect_count > 0) { @@ -12342,7 +11555,8 @@ int DigField(struct PlayerInfo *player, if (local_player->sokobanfields_still_needed == 0 && game.emulation == EMU_SOKOBAN) { - player->LevelSolved = player->GameOver = TRUE; + PlayerWins(player); + PlayLevelSound(x, y, SND_GAME_SOKOBAN_SOLVING); } } @@ -12402,11 +11616,7 @@ int DigField(struct PlayerInfo *player, { int xx, yy; -#if 1 SCAN_PLAYFIELD(xx, yy) -#else - for (yy = 0; yy < lev_fieldy; yy++) for (xx = 0; xx < lev_fieldx; xx++) -#endif { if (Feld[xx][yy] == EL_SP_DISK_YELLOW) Bang(xx, yy); @@ -12474,11 +11684,7 @@ int DigField(struct PlayerInfo *player, game.ball_state = !game.ball_state; -#if 1 SCAN_PLAYFIELD(xx, yy) -#else - for (yy = 0; yy < lev_fieldy; yy++) for (xx = 0; xx < lev_fieldx; xx++) -#endif { int e = Feld[xx][yy]; @@ -12699,11 +11905,7 @@ boolean DropElement(struct PlayerInfo *player) { player->inventory_size--; -#if 1 DrawGameDoorValues(); -#else - DrawGameValue_Dynamite(local_player->inventory_size); -#endif if (new_element == EL_DYNAMITE) new_element = EL_DYNAMITE_ACTIVE; @@ -12896,9 +12098,12 @@ static void PlayLevelMusic() PlayMusic(MAP_NOCONF_MUSIC(level_nr)); /* from music dir */ } -void PlayLevelSound_EM(int x, int y, int element_em, int sample) +void PlayLevelSound_EM(int xx, int yy, int element_em, int sample) { int element = (element_em > -1 ? map_element_EM_to_RND(element_em) : 0); + int offset = (BorderElement == EL_STEELWALL ? 1 : 0); + int x = xx - 1 - offset; + int y = yy - 1 - offset; switch (sample) { @@ -13044,7 +12249,7 @@ void PlayLevelSound_EM(int x, int y, int element_em, int sample) break; case SAMPLE_time: - PlaySoundStereo(SND_GAME_RUNNING_OUT_OF_TIME, SOUND_MIDDLE); + PlaySound(SND_GAME_RUNNING_OUT_OF_TIME); break; default: @@ -13053,6 +12258,31 @@ void PlayLevelSound_EM(int x, int y, int element_em, int sample) } } +#if 0 +void ChangeTime(int value) +{ + int *time = (level.time == 0 ? &TimePlayed : &TimeLeft); + + *time += value; + + /* EMC game engine uses value from time counter of RND game engine */ + level.native_em_level->lev->time = *time; + + DrawGameValue_Time(*time); +} + +void RaiseScore(int value) +{ + /* EMC game engine and RND game engine have separate score counters */ + int *score = (level.game_engine_type == GAME_ENGINE_TYPE_EM ? + &level.native_em_level->lev->score : &local_player->score); + + *score += value; + + DrawGameValue_Score(*score); +} +#endif + void RaiseScore(int value) { local_player->score += value; @@ -13153,8 +12383,20 @@ void RequestQuitGame(boolean ask_if_really_quit) 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