X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=d2e58439281ec3d5b4b6386f6af5baba3b4f8673;hb=37a06df577bbfd00f4b361f92cacb0d97036ba93;hp=c9eb9360017fc84207d7f1505fde9b40e53d86bd;hpb=4761c712e043542d6bfd4ce58501ee6c6af68bd3;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index c9eb9360..d2e58439 100644 --- a/src/game.c +++ b/src/game.c @@ -654,6 +654,40 @@ static void InitPlayfieldScanMode(int mode) InitPlayfieldScanModeVars(); } +static int get_move_delay_from_stepsize(int move_stepsize) +{ + move_stepsize = + MIN(MAX(MOVE_STEPSIZE_MIN, move_stepsize), MOVE_STEPSIZE_MAX); + + /* make sure that stepsize value is always a power of 2 */ + move_stepsize = (1 << log_2(move_stepsize)); + + return TILEX / move_stepsize; +} + +static void SetPlayerMoveSpeed(struct PlayerInfo *player, int move_stepsize, + boolean init_game) +{ + int move_delay = get_move_delay_from_stepsize(move_stepsize); + boolean cannot_move = (move_stepsize == STEPSIZE_NOT_MOVING ? TRUE : FALSE); + + /* do no immediately change move delay -- the player might just be moving */ + player->move_delay_value_next = move_delay; + + /* information if player can move must be set separately */ + player->cannot_move = cannot_move; + + if (init_game) + { + 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; + } +} + void GetPlayerConfig() { if (!audio.sound_available) @@ -1341,9 +1375,15 @@ static void InitGameEngine() /* ---------- initialize player's initial move delay --------------------- */ +#if 1 + /* dynamically adjust player properties according to level information */ + game.initial_move_delay_value = + get_move_delay_from_stepsize(level.initial_player_stepsize); +#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 */ game.initial_move_delay = (game.engine_version <= VERSION_IDENT(2,0,1,0) ? @@ -1724,8 +1764,6 @@ void InitGame() player->is_bored = FALSE; player->is_sleeping = FALSE; - player->cannot_move = FALSE; - player->frame_counter_bored = -1; player->frame_counter_sleeping = -1; @@ -1753,6 +1791,9 @@ void InitGame() player->show_envelope = 0; +#if 1 + SetPlayerMoveSpeed(player, level.initial_player_stepsize, TRUE); +#else player->move_delay = game.initial_move_delay; player->move_delay_value = game.initial_move_delay_value; @@ -1760,6 +1801,9 @@ void InitGame() 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; @@ -6608,10 +6652,11 @@ static void RunTimegateWheel(int x, int y) static void InitMagicBallDelay(int x, int y) { - ChangeDelay[x][y] = level.ball_time * FRAMES_PER_SECOND; - - if (ChangeDelay[x][y] == 0) - ChangeDelay[x][y] = 1; +#if 1 + ChangeDelay[x][y] = (level.ball_time + 1) * 8 + 1; +#else + ChangeDelay[x][y] = level.ball_time * FRAMES_PER_SECOND + 1; +#endif } static void ActivateMagicBall(int bx, int by) @@ -7073,11 +7118,11 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) MV_NONE); int action_arg_number_min = - (action_type == CA_SET_PLAYER_SPEED ? MOVE_STEPSIZE_MIN : + (action_type == CA_SET_PLAYER_SPEED ? STEPSIZE_NOT_MOVING : CA_ARG_MIN); int action_arg_number_max = - (action_type == CA_SET_PLAYER_SPEED ? MOVE_STEPSIZE_MAX : + (action_type == CA_SET_PLAYER_SPEED ? STEPSIZE_EVEN_FASTER : action_type == CA_SET_LEVEL_GEMS ? 999 : action_type == CA_SET_LEVEL_TIME ? 9999 : action_type == CA_SET_LEVEL_SCORE ? 99999 : @@ -7086,7 +7131,7 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) CA_ARG_MAX); int action_arg_number_reset = - (action_type == CA_SET_PLAYER_SPEED ? TILEX/game.initial_move_delay_value : + (action_type == CA_SET_PLAYER_SPEED ? level.initial_player_stepsize : action_type == CA_SET_LEVEL_GEMS ? level.gems_needed : action_type == CA_SET_LEVEL_TIME ? level.time : action_type == CA_SET_LEVEL_SCORE ? 0 : @@ -7286,8 +7331,13 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) { int move_stepsize = TILEX / stored_player[i].move_delay_value; - if (action_arg == CA_ARG_SPEED_SLOWER || - action_arg == CA_ARG_SPEED_FASTER) + if (action_arg == CA_ARG_SPEED_FASTER && + stored_player[i].cannot_move) + { + action_arg_number = STEPSIZE_VERY_SLOW; + } + else if (action_arg == CA_ARG_SPEED_SLOWER || + action_arg == CA_ARG_SPEED_FASTER) { action_arg_number = 2; action_mode = (action_arg == CA_ARG_SPEED_SLOWER ? CA_MODE_DIVIDE : @@ -7301,6 +7351,9 @@ 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)); @@ -7309,6 +7362,7 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) stored_player[i].cannot_move = (action_arg == CA_ARG_SPEED_NOT_MOVING ? TRUE : FALSE); +#endif } } @@ -7419,19 +7473,19 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) } } -static void CreateField(int x, int y, int target_element) +static void CreateFieldExt(int x, int y, int element, boolean is_change) { int previous_move_direction = MovDir[x][y]; #if USE_NEW_CUSTOM_VALUE int last_ce_value = CustomValue[x][y]; #endif - boolean add_player = (ELEM_IS_PLAYER(target_element) && + boolean add_player = (ELEM_IS_PLAYER(element) && IS_WALKABLE(Feld[x][y])); /* check if element under player changes from accessible to unaccessible (needed for special case of dropping element which then changes) */ if (IS_PLAYER(x, y) && !PLAYER_EXPLOSION_PROTECTED(x, y) && - IS_ACCESSIBLE(Feld[x][y]) && !IS_ACCESSIBLE(target_element)) + IS_ACCESSIBLE(Feld[x][y]) && !IS_ACCESSIBLE(element)) { Bang(x, y); @@ -7445,7 +7499,7 @@ static void CreateField(int x, int y, int target_element) else RemoveField(x, y); - Feld[x][y] = target_element; + Feld[x][y] = element; ResetGfxAnimation(x, y); ResetRandomAnimationValue(x, y); @@ -7467,23 +7521,25 @@ static void CreateField(int x, int y, int target_element) } /* "ChangeCount" not set yet to allow "entered by player" change one time */ - if (ELEM_IS_PLAYER(target_element)) - RelocatePlayer(x, y, target_element); + if (ELEM_IS_PLAYER(element)) + RelocatePlayer(x, y, element); -#if 0 - ChangeCount[x][y]++; /* count number of changes in the same frame */ -#endif + if (is_change) + ChangeCount[x][y]++; /* count number of changes in the same frame */ TestIfBadThingTouchesPlayer(x, y); TestIfPlayerTouchesCustomElement(x, y); TestIfElementTouchesCustomElement(x, y); } -static void CreateElementFromChange(int x, int y, int element) +static void CreateField(int x, int y, int element) { - CreateField(x, y, element); + CreateFieldExt(x, y, element, FALSE); +} - ChangeCount[x][y]++; /* count number of changes in the same frame */ +static void CreateElementFromChange(int x, int y, int element) +{ + CreateFieldExt(x, y, element, TRUE); } static boolean ChangeElement(int x, int y, int element, int page) @@ -9072,6 +9128,7 @@ boolean MovePlayerOneStep(struct PlayerInfo *player, int new_jx = jx + dx, new_jy = jy + dy; int element; int can_move; + boolean player_can_move = !player->cannot_move; if (!player->active || (!dx && !dy)) return MF_NO_ACTION; @@ -9084,7 +9141,7 @@ boolean MovePlayerOneStep(struct PlayerInfo *player, if (!IN_LEV_FIELD(new_jx, new_jy)) return MF_NO_ACTION; - if (player->cannot_move) + if (!player_can_move) { #if 1 if (player->MovPos == 0) @@ -9100,7 +9157,9 @@ boolean MovePlayerOneStep(struct PlayerInfo *player, SnapField(player, 0, 0); #endif +#if 0 return MF_NO_ACTION; +#endif } if (!options.network && !AllPlayersInSight(player, new_jx, new_jy)) @@ -9108,7 +9167,7 @@ boolean MovePlayerOneStep(struct PlayerInfo *player, element = MovingOrBlocked2ElementIfNotLeaving(new_jx, new_jy); - if (DONT_RUN_INTO(element)) + if (player_can_move && DONT_RUN_INTO(element)) { if (element == EL_ACID && dx == 0 && dy == 1) { @@ -10166,6 +10225,7 @@ int DigField(struct PlayerInfo *player, { boolean is_player = (IS_PLAYER(oldx, oldy) || mode != DF_DIG); boolean player_was_pushing = player->is_pushing; + boolean player_can_enter = (!player->cannot_move || mode == DF_SNAP); int jx = oldx, jy = oldy; int dx = x - jx, dy = y - jy; int nextx = x + dx, nexty = y + dy; @@ -10260,7 +10320,8 @@ int DigField(struct PlayerInfo *player, !canMoveToValidFieldWithGravity(jx, jy, move_direction)) return MF_NO_ACTION; /* player cannot walk here due to gravity */ - if (IS_WALKABLE(element) && ACCESS_FROM(element, opposite_direction)) + if (player_can_enter && + IS_WALKABLE(element) && ACCESS_FROM(element, opposite_direction)) { int sound_element = SND_ELEMENT(element); int sound_action = ACTION_WALKING; @@ -10297,7 +10358,8 @@ int DigField(struct PlayerInfo *player, else PlayLevelSoundElementAction(x, y, player->artwork_element, sound_action); } - else if (IS_PASSABLE(element) && canPassField(x, y, move_direction)) + else if (player_can_enter && + IS_PASSABLE(element) && canPassField(x, y, move_direction)) { if (!ACCESS_FROM(element, opposite_direction)) return MF_NO_ACTION; /* field not accessible from this direction */ @@ -10351,7 +10413,7 @@ int DigField(struct PlayerInfo *player, PlayLevelSoundAction(x, y, ACTION_PASSING); } - else if (IS_DIGGABLE(element)) + else if (player_can_enter && IS_DIGGABLE(element)) { RemoveField(x, y); @@ -10381,7 +10443,7 @@ int DigField(struct PlayerInfo *player, player->index_bit, dig_side); } } - else if (IS_COLLECTIBLE(element)) + else if (player_can_enter && IS_COLLECTIBLE(element)) { RemoveField(x, y); @@ -10495,7 +10557,7 @@ int DigField(struct PlayerInfo *player, player->index_bit, dig_side); } } - else if (IS_PUSHABLE(element)) + else if (player_can_enter && IS_PUSHABLE(element)) { if (mode == DF_SNAP && element != EL_BD_ROCK) return MF_NO_ACTION;