X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fgame.c;h=8978e70750489ebe4c15af503f0d3ae9c461537c;hp=3d2f055f27c88415dccb499d83d65932ad8a5f1e;hb=47da774c66f9325f9d27cddb5a697514154e2de9;hpb=567cfcb396e3fc031a25362b747dd0a5a096b4ec diff --git a/src/game.c b/src/game.c index 3d2f055f..8978e707 100644 --- a/src/game.c +++ b/src/game.c @@ -827,6 +827,14 @@ static struct GamePanelControlInfo game_panel_controls[] = #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 scroll positions */ +#define SCROLL_POSITION_X(x) ((x) < SBX_Left + MIDPOSX ? SBX_Left : \ + (x) > SBX_Right + MIDPOSX ? SBX_Right :\ + (x) - MIDPOSX) +#define SCROLL_POSITION_Y(y) ((y) < SBY_Upper + MIDPOSY ? SBY_Upper :\ + (y) > SBY_Lower + MIDPOSY ? SBY_Lower :\ + (y) - MIDPOSY) + /* values for other actions */ #define MOVE_STEPSIZE_NORMAL (TILEX / MOVE_DELAY_NORMAL_SPEED) #define MOVE_STEPSIZE_MIN (1) @@ -1611,7 +1619,6 @@ void GetPlayerConfig() setup.sound = (setup.sound_simple || setup.sound_loops || setup.sound_music); SetAudioMode(setup.sound); - InitJoysticks(); } int GetElementFromGroupElement(int element) @@ -2050,6 +2057,16 @@ static int compareGamePanelOrderInfo(const void *object1, const void *object2) return compare_result; } +int getPlayerInventorySize(int player_nr) +{ + if (level.game_engine_type == GAME_ENGINE_TYPE_EM) + return level.native_em_level->ply[player_nr]->dynamite; + else if (level.game_engine_type == GAME_ENGINE_TYPE_SP) + return level.native_sp_level->game_sp->red_disk_count; + else + return stored_player[player_nr].inventory_size; +} + void InitGameControlValues() { int i; @@ -2187,15 +2204,8 @@ void UpdateGameControlValues() get_key_element_from_nr(k); } - if (level.game_engine_type == GAME_ENGINE_TYPE_EM) - game_panel_controls[GAME_PANEL_INVENTORY_COUNT].value += - level.native_em_level->ply[i]->dynamite; - else if (level.game_engine_type == GAME_ENGINE_TYPE_SP) - game_panel_controls[GAME_PANEL_INVENTORY_COUNT].value += - level.native_sp_level->game_sp->red_disk_count; - else - game_panel_controls[GAME_PANEL_INVENTORY_COUNT].value += - stored_player[i].inventory_size; + game_panel_controls[GAME_PANEL_INVENTORY_COUNT].value += + getPlayerInventorySize(i); if (stored_player[i].num_white_keys > 0) game_panel_controls[GAME_PANEL_KEY_WHITE].value = @@ -2222,15 +2232,8 @@ void UpdateGameControlValues() get_key_element_from_nr(k); } - if (level.game_engine_type == GAME_ENGINE_TYPE_EM) - game_panel_controls[GAME_PANEL_INVENTORY_COUNT].value += - level.native_em_level->ply[player_nr]->dynamite; - else if (level.game_engine_type == GAME_ENGINE_TYPE_SP) - game_panel_controls[GAME_PANEL_INVENTORY_COUNT].value += - level.native_sp_level->game_sp->red_disk_count; - else - game_panel_controls[GAME_PANEL_INVENTORY_COUNT].value += - stored_player[player_nr].inventory_size; + game_panel_controls[GAME_PANEL_INVENTORY_COUNT].value += + getPlayerInventorySize(player_nr); if (stored_player[player_nr].num_white_keys > 0) game_panel_controls[GAME_PANEL_KEY_WHITE].value = EL_DC_KEY_WHITE; @@ -2695,6 +2698,9 @@ static void InitGameEngine() game.use_block_last_field_bug = (game.engine_version < VERSION_IDENT(3,1,1,0)); + game_em.use_single_button = + (game.engine_version > VERSION_IDENT(4,0,0,2)); + /* ---------------------------------------------------------------------- */ /* set maximal allowed number of custom element changes per game frame */ @@ -3218,6 +3224,8 @@ void InitGame() player->was_snapping = FALSE; player->was_dropping = FALSE; + player->force_dropping = FALSE; + player->frame_counter_bored = -1; player->frame_counter_sleeping = -1; @@ -3900,23 +3908,13 @@ void InitGame() } } - scroll_x = (start_x < SBX_Left + MIDPOSX ? SBX_Left : - start_x > SBX_Right + MIDPOSX ? SBX_Right : - start_x - MIDPOSX); - - scroll_y = (start_y < SBY_Upper + MIDPOSY ? SBY_Upper : - start_y > SBY_Lower + MIDPOSY ? SBY_Lower : - start_y - MIDPOSY); + scroll_x = SCROLL_POSITION_X(start_x); + scroll_y = SCROLL_POSITION_Y(start_y); } else { - scroll_x = (local_player->jx < SBX_Left + MIDPOSX ? SBX_Left : - local_player->jx > SBX_Right + MIDPOSX ? SBX_Right : - local_player->jx - MIDPOSX); - - scroll_y = (local_player->jy < SBY_Upper + MIDPOSY ? SBY_Upper : - local_player->jy > SBY_Lower + MIDPOSY ? SBY_Lower : - local_player->jy - MIDPOSY); + scroll_x = SCROLL_POSITION_X(local_player->jx); + scroll_y = SCROLL_POSITION_Y(local_player->jy); } /* !!! FIX THIS (START) !!! */ @@ -4467,7 +4465,8 @@ void GameEnd() SaveLevelSetup_SeriesInfo(); } - if (level_nr < leveldir_current->last_level) + if (setup.increment_levels && + level_nr < leveldir_current->last_level) raise_level = TRUE; /* advance to next level */ if ((hi_pos = NewHiScore()) >= 0) @@ -4500,6 +4499,7 @@ int NewHiScore() { int k, l; int position = -1; + boolean one_score_entry_per_name = !program.many_scores_per_name; LoadScore(level_nr); @@ -4517,13 +4517,15 @@ int NewHiScore() { int m = MAX_SCORE_ENTRIES - 1; -#ifdef ONE_PER_NAME - for (l = k; l < MAX_SCORE_ENTRIES; l++) - if (strEqual(setup.player_name, highscore[l].Name)) - m = l; - if (m == k) /* player's new highscore overwrites his old one */ - goto put_into_list; -#endif + if (one_score_entry_per_name) + { + for (l = k; l < MAX_SCORE_ENTRIES; l++) + if (strEqual(setup.player_name, highscore[l].Name)) + m = l; + + if (m == k) /* player's new highscore overwrites his old one */ + goto put_into_list; + } for (l = m; l > k; l--) { @@ -4532,22 +4534,19 @@ int NewHiScore() } } -#ifdef ONE_PER_NAME put_into_list: -#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_final; position = k; + break; } - -#ifdef ONE_PER_NAME - else if (!strncmp(setup.player_name, highscore[k].Name, + else if (one_score_entry_per_name && + !strncmp(setup.player_name, highscore[k].Name, MAX_PLAYER_NAME_LEN)) break; /* player already there with a higher score */ -#endif - } if (position >= 0) @@ -4594,11 +4593,10 @@ void InitPlayerGfxAnimation(struct PlayerInfo *player, int action, int dir) } } -static void ResetGfxFrame(int x, int y, boolean redraw) +static void ResetGfxFrame(int x, int y) { int element = Feld[x][y]; int graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]); - int last_gfx_frame = GfxFrame[x][y]; if (graphic_info[graphic].anim_global_sync) GfxFrame[x][y] = FrameCounter; @@ -4608,9 +4606,6 @@ static void ResetGfxFrame(int x, int y, boolean redraw) GfxFrame[x][y] = element_info[element].collect_score; else if (ANIM_MODE(graphic) == ANIM_CE_DELAY) GfxFrame[x][y] = ChangeDelay[x][y]; - - if (redraw && GfxFrame[x][y] != last_gfx_frame) - DrawLevelGraphicAnimation(x, y, graphic); } static void ResetGfxAnimation(int x, int y) @@ -4619,7 +4614,7 @@ static void ResetGfxAnimation(int x, int y) GfxDir[x][y] = MovDir[x][y]; GfxFrame[x][y] = 0; - ResetGfxFrame(x, y, FALSE); + ResetGfxFrame(x, y); } static void ResetRandomAnimationValue(int x, int y) @@ -4932,36 +4927,21 @@ void DrawRelocateScreen(int old_x, int old_y, int x, int y, int move_dir, { /* relocation _with_ centering of screen */ - new_scroll_x = (x < SBX_Left + MIDPOSX ? SBX_Left : - x > SBX_Right + MIDPOSX ? SBX_Right : - x - MIDPOSX); - - new_scroll_y = (y < SBY_Upper + MIDPOSY ? SBY_Upper : - y > SBY_Lower + MIDPOSY ? SBY_Lower : - y - MIDPOSY); + new_scroll_x = SCROLL_POSITION_X(x); + new_scroll_y = SCROLL_POSITION_Y(y); } else { /* relocation _without_ centering of screen */ - int center_scroll_x = (old_x < SBX_Left + MIDPOSX ? SBX_Left : - old_x > SBX_Right + MIDPOSX ? SBX_Right : - old_x - MIDPOSX); - - int center_scroll_y = (old_y < SBY_Upper + MIDPOSY ? SBY_Upper : - old_y > SBY_Lower + MIDPOSY ? SBY_Lower : - old_y - MIDPOSY); - + int center_scroll_x = SCROLL_POSITION_X(old_x); + int center_scroll_y = SCROLL_POSITION_Y(old_y); int offset_x = x + (scroll_x - center_scroll_x); int offset_y = y + (scroll_y - center_scroll_y); - new_scroll_x = (offset_x < SBX_Left + MIDPOSX ? SBX_Left : - offset_x > SBX_Right + MIDPOSX ? SBX_Right : - offset_x - MIDPOSX); - - new_scroll_y = (offset_y < SBY_Upper + MIDPOSY ? SBY_Upper : - offset_y > SBY_Lower + MIDPOSY ? SBY_Lower : - offset_y - MIDPOSY); + /* for new screen position, apply previous offset to center position */ + new_scroll_x = SCROLL_POSITION_X(offset_x); + new_scroll_y = SCROLL_POSITION_Y(offset_y); } if (quick_relocation) @@ -7080,7 +7060,7 @@ static void TurnRound(int x, int y) if (MovDelay[x][y]) GfxAction[x][y] = ACTION_TURNING_FROM_LEFT + MV_DIR_TO_BIT(direction); - ResetGfxFrame(x, y, FALSE); + ResetGfxFrame(x, y); } static boolean JustBeingPushed(int x, int y) @@ -10736,7 +10716,9 @@ static void CheckSingleStepMode(struct PlayerInfo *player) { /* as it is called "single step mode", just return to pause mode when the player stopped moving after one tile (or never starts moving at all) */ - if (!player->is_moving && !player->is_pushing) + if (!player->is_moving && + !player->is_pushing && + !player->is_dropping_pressed) { TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); SnapField(player, 0, 0); /* stop snapping */ @@ -11290,6 +11272,14 @@ void GameActions_SP_Main() effective_action[i] = stored_player[i].effective_action; GameActions_SP(effective_action, warp_mode); + + for (i = 0; i < MAX_PLAYERS; i++) + { + if (stored_player[i].force_dropping) + stored_player[i].action |= KEY_BUTTON_DROP; + + stored_player[i].force_dropping = FALSE; + } } void GameActions_RND_Main() @@ -11300,7 +11290,7 @@ void GameActions_RND_Main() void GameActions_RND() { int magic_wall_x = 0, magic_wall_y = 0; - int i, x, y, element, graphic; + int i, x, y, element, graphic, last_gfx_frame; InitPlayfieldScanModeVars(); @@ -11487,8 +11477,12 @@ void GameActions_RND() { element = Feld[x][y]; graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]); + last_gfx_frame = GfxFrame[x][y]; - ResetGfxFrame(x, y, TRUE); + ResetGfxFrame(x, y); + + if (GfxFrame[x][y] != last_gfx_frame && !Stop[x][y]) + DrawLevelGraphicAnimation(x, y, graphic); if (ANIM_MODE(graphic) == ANIM_RANDOM && IS_NEXT_FRAME(GfxFrame[x][y], graphic)) @@ -11533,8 +11527,12 @@ void GameActions_RND() if (IS_GEM(element) || element == EL_SP_INFOTRON) TEST_DrawTwinkleOnField(x, y); } - else if ((element == EL_ACID || - element == EL_EXIT_OPEN || + else if (element == EL_ACID) + { + if (!Stop[x][y]) + DrawLevelGraphicAnimationIfNeeded(x, y, graphic); + } + else if ((element == EL_EXIT_OPEN || element == EL_EM_EXIT_OPEN || element == EL_SP_EXIT_OPEN || element == EL_STEEL_EXIT_OPEN || @@ -13993,8 +13991,6 @@ static boolean DropElement(struct PlayerInfo *player) int drop_side = drop_direction; int drop_element = get_next_dropped_element(player); - player->is_dropping_pressed = TRUE; - /* do not drop an element on top of another element; when holding drop key pressed without moving, dropped element must move away before the next element can be dropped (this is especially important if the next element @@ -14022,6 +14018,9 @@ static boolean DropElement(struct PlayerInfo *player) if (new_element == EL_UNDEFINED) return FALSE; + /* only set if player has anything that can be dropped */ + player->is_dropping_pressed = TRUE; + /* check if drop key was pressed long enough for EM style dynamite */ if (new_element == EL_EM_DYNAMITE && player->drop_pressed_delay < 40) return FALSE;