X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=4a2f56697a9bed798aabe349f5153c0dea16a033;hb=b180608242f0190c6c8b31772e4dcfce2e9af47c;hp=346e1269ce6b77342083efe91436d2e4c4db659a;hpb=84f2d2359ecfa6253804b353f92dd9b2ccb55887;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index 346e1269..4a2f5669 100644 --- a/src/game.c +++ b/src/game.c @@ -232,6 +232,7 @@ /* forward declaration for internal use */ +static void SetPlayerWaiting(struct PlayerInfo *, boolean); static void AdvanceFrameAndPlayerCounters(int); static boolean MovePlayerOneStep(struct PlayerInfo *, int, int, int, int); @@ -680,7 +681,7 @@ static void InitPlayerField(int x, int y, int element, boolean init_game) } else { - stored_player[0].use_murphy_graphic = TRUE; + stored_player[0].use_murphy = TRUE; } Feld[x][y] = EL_PLAYER_1; @@ -1473,6 +1474,28 @@ static void InitGameEngine() access_direction_list[i].direction; } +int get_num_special_action(int element, int action_first, int action_last) +{ + int num_special_action = 0; + int i, j; + + for (i = action_first; i <= action_last; i++) + { + boolean found = FALSE; + + for (j = 0; j < NUM_DIRECTIONS; j++) + if (el_act_dir2img(element, i, j) != + el_act_dir2img(element, ACTION_DEFAULT, j)) + found = TRUE; + + if (found) + num_special_action++; + else + break; + } + + return num_special_action; +} /* ============================================================================= @@ -1487,7 +1510,7 @@ 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 */ - int i, j, k, x, y; + int i, j, x, y; InitGameEngine(); @@ -1531,7 +1554,8 @@ void InitGame() player->Frame = 0; player->StepFrame = 0; - player->use_murphy_graphic = FALSE; + player->use_murphy = FALSE; + player->artwork_element = player->element_nr; player->block_last_field = FALSE; /* initialized in InitPlayerField() */ player->block_delay_adjustment = 0; /* initialized in InitPlayerField() */ @@ -1570,38 +1594,13 @@ void InitGame() player->special_action_bored = ACTION_DEFAULT; player->special_action_sleeping = ACTION_DEFAULT; - player->num_special_action_bored = 0; - player->num_special_action_sleeping = 0; - - /* determine number of special actions for bored and sleeping animation */ - for (j = ACTION_BORING_1; j <= ACTION_BORING_LAST; j++) - { - boolean found = FALSE; - - for (k = 0; k < NUM_DIRECTIONS; k++) - if (el_act_dir2img(player->element_nr, j, k) != - el_act_dir2img(player->element_nr, ACTION_DEFAULT, k)) - found = TRUE; - - if (found) - player->num_special_action_bored++; - else - break; - } - for (j = ACTION_SLEEPING_1; j <= ACTION_SLEEPING_LAST; j++) - { - boolean found = FALSE; - - for (k = 0; k < NUM_DIRECTIONS; k++) - if (el_act_dir2img(player->element_nr, j, k) != - el_act_dir2img(player->element_nr, ACTION_DEFAULT, k)) - found = TRUE; - - if (found) - player->num_special_action_sleeping++; - else - break; - } + /* 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); player->switch_x = -1; player->switch_y = -1; @@ -1674,6 +1673,9 @@ void InitGame() game.gravity = level.initial_gravity; game.explosions_delayed = TRUE; + game.lenses_time_left = 0; + game.magnify_time_left = 0; + game.envelope_active = FALSE; for (i = 0; i < NUM_BELTS; i++) @@ -1821,6 +1823,8 @@ void InitGame() player->element_nr = some_player->element_nr; #endif + player->artwork_element = some_player->artwork_element; + player->block_last_field = some_player->block_last_field; player->block_delay_adjustment = some_player->block_delay_adjustment; @@ -2320,12 +2324,17 @@ void GameWon() { if (!tape.playing && !setup.sound_loops) PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MIDDLE); - if (TimeLeft > 0 && !(TimeLeft % 10)) - RaiseScore(level.score[SC_TIME_BONUS]); - if (TimeLeft > 100 && !(TimeLeft % 10)) + + if (TimeLeft > 100 && TimeLeft % 10 == 0) + { TimeLeft -= 10; + RaiseScore(level.score[SC_TIME_BONUS] * 10); + } else + { TimeLeft--; + RaiseScore(level.score[SC_TIME_BONUS]); + } DrawGameValue_Time(TimeLeft); @@ -2348,12 +2357,17 @@ void GameWon() { if (!tape.playing && !setup.sound_loops) PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MIDDLE); - if (TimePlayed < 999 && !(TimePlayed % 10)) - RaiseScore(level.score[SC_TIME_BONUS]); - if (TimePlayed < 900 && !(TimePlayed % 10)) + + if (TimePlayed < 900 && TimePlayed % 10 == 0) + { TimePlayed += 10; + RaiseScore(level.score[SC_TIME_BONUS] * 10); + } else + { TimePlayed++; + RaiseScore(level.score[SC_TIME_BONUS]); + } DrawGameValue_Time(TimePlayed); @@ -3096,7 +3110,7 @@ void Explode(int ex, int ey, int phase, int mode) break; } - if (PLAYERINFO(ex, ey)->use_murphy_graphic) + if (PLAYERINFO(ex, ey)->use_murphy) Store[x][y] = EL_EMPTY; } else if (center_element == EL_MOLE) @@ -3354,7 +3368,7 @@ void Bang(int x, int y) { struct PlayerInfo *player = PLAYERINFO(x, y); - element = Feld[x][y] = (player->use_murphy_graphic ? EL_SP_MURPHY : + element = Feld[x][y] = (player->use_murphy ? EL_SP_MURPHY : player->element_nr); } @@ -3637,50 +3651,155 @@ static void RedrawAllLightSwitchesAndInvisibleElements() { int x, y; - for (y = 0; y < lev_fieldy; y++) + for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) { - for (x = 0; x < lev_fieldx; x++) + int element = Feld[x][y]; + + if (element == EL_LIGHT_SWITCH && + game.light_time_left > 0) { - int element = Feld[x][y]; + Feld[x][y] = EL_LIGHT_SWITCH_ACTIVE; + DrawLevelField(x, y); + } + else if (element == EL_LIGHT_SWITCH_ACTIVE && + game.light_time_left == 0) + { + Feld[x][y] = EL_LIGHT_SWITCH; + DrawLevelField(x, y); + } + else if (element == EL_EMC_DRIPPER && + game.light_time_left > 0) + { + Feld[x][y] = EL_EMC_DRIPPER_ACTIVE; + DrawLevelField(x, y); + } + else if (element == EL_EMC_DRIPPER_ACTIVE && + game.light_time_left == 0) + { + Feld[x][y] = EL_EMC_DRIPPER; + DrawLevelField(x, y); + } + else if (element == EL_INVISIBLE_STEELWALL || + element == EL_INVISIBLE_WALL || + element == EL_INVISIBLE_SAND) + { + if (game.light_time_left > 0) + Feld[x][y] = getInvisibleActiveFromInvisibleElement(element); - if (element == EL_LIGHT_SWITCH && - game.light_time_left > 0) - { - Feld[x][y] = EL_LIGHT_SWITCH_ACTIVE; - DrawLevelField(x, y); - } - else if (element == EL_LIGHT_SWITCH_ACTIVE && - game.light_time_left == 0) - { - Feld[x][y] = EL_LIGHT_SWITCH; - DrawLevelField(x, y); - } - else if (element == EL_INVISIBLE_STEELWALL || - element == EL_INVISIBLE_WALL || - element == EL_INVISIBLE_SAND) - { - if (game.light_time_left > 0) - Feld[x][y] = getInvisibleActiveFromInvisibleElement(element); + DrawLevelField(x, y); - DrawLevelField(x, y); + /* uncrumble neighbour fields, if needed */ + if (element == EL_INVISIBLE_SAND) + DrawLevelFieldCrumbledSandNeighbours(x, y); + } + else if (element == EL_INVISIBLE_STEELWALL_ACTIVE || + element == EL_INVISIBLE_WALL_ACTIVE || + element == EL_INVISIBLE_SAND_ACTIVE) + { + if (game.light_time_left == 0) + Feld[x][y] = getInvisibleFromInvisibleActiveElement(element); - /* uncrumble neighbour fields, if needed */ - if (element == EL_INVISIBLE_SAND) - DrawLevelFieldCrumbledSandNeighbours(x, y); - } - else if (element == EL_INVISIBLE_STEELWALL_ACTIVE || - element == EL_INVISIBLE_WALL_ACTIVE || - element == EL_INVISIBLE_SAND_ACTIVE) - { - if (game.light_time_left == 0) - Feld[x][y] = getInvisibleFromInvisibleActiveElement(element); + DrawLevelField(x, y); - DrawLevelField(x, y); + /* re-crumble neighbour fields, if needed */ + if (element == EL_INVISIBLE_SAND) + DrawLevelFieldCrumbledSandNeighbours(x, y); + } + } +} - /* re-crumble neighbour fields, if needed */ - if (element == EL_INVISIBLE_SAND) - DrawLevelFieldCrumbledSandNeighbours(x, y); - } +static void RedrawAllInvisibleElementsForLenses() +{ + int x, y; + + for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) + { + int element = Feld[x][y]; + + if (element == EL_EMC_DRIPPER && + game.lenses_time_left > 0) + { + Feld[x][y] = EL_EMC_DRIPPER_ACTIVE; + DrawLevelField(x, y); + } + else if (element == EL_EMC_DRIPPER_ACTIVE && + game.lenses_time_left == 0) + { + Feld[x][y] = EL_EMC_DRIPPER; + DrawLevelField(x, y); + } + else if (element == EL_INVISIBLE_STEELWALL || + element == EL_INVISIBLE_WALL || + element == EL_INVISIBLE_SAND) + { + if (game.lenses_time_left > 0) + Feld[x][y] = getInvisibleActiveFromInvisibleElement(element); + + DrawLevelField(x, y); + + /* uncrumble neighbour fields, if needed */ + if (element == EL_INVISIBLE_SAND) + DrawLevelFieldCrumbledSandNeighbours(x, y); + } + else if (element == EL_INVISIBLE_STEELWALL_ACTIVE || + element == EL_INVISIBLE_WALL_ACTIVE || + element == EL_INVISIBLE_SAND_ACTIVE) + { + if (game.lenses_time_left == 0) + Feld[x][y] = getInvisibleFromInvisibleActiveElement(element); + + DrawLevelField(x, y); + + /* re-crumble neighbour fields, if needed */ + if (element == EL_INVISIBLE_SAND) + DrawLevelFieldCrumbledSandNeighbours(x, y); + } + } +} + +static void RedrawAllInvisibleElementsForMagnifier() +{ + int x, y; + + for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) + { + int element = Feld[x][y]; + + if (element == EL_EMC_FAKE_GRASS && + game.magnify_time_left > 0) + { + Feld[x][y] = EL_EMC_FAKE_GRASS_ACTIVE; + DrawLevelField(x, y); + } + else if (element == EL_EMC_FAKE_GRASS_ACTIVE && + game.magnify_time_left == 0) + { + Feld[x][y] = EL_EMC_FAKE_GRASS; + DrawLevelField(x, y); + } + else if (IS_GATE_GRAY(element) && + game.magnify_time_left > 0) + { + Feld[x][y] = (IS_RND_GATE_GRAY(element) ? + element - EL_GATE_1_GRAY + EL_GATE_1_GRAY_ACTIVE : + IS_EM_GATE_GRAY(element) ? + element - EL_EM_GATE_1_GRAY + EL_EM_GATE_1_GRAY_ACTIVE : + IS_EMC_GATE_GRAY(element) ? + element - EL_EMC_GATE_5_GRAY + EL_EMC_GATE_5_GRAY_ACTIVE : + element); + DrawLevelField(x, y); + } + else if (IS_GATE_GRAY_ACTIVE(element) && + game.magnify_time_left == 0) + { + Feld[x][y] = (IS_RND_GATE_GRAY_ACTIVE(element) ? + element - EL_GATE_1_GRAY_ACTIVE + EL_GATE_1_GRAY : + IS_EM_GATE_GRAY_ACTIVE(element) ? + element - EL_EM_GATE_1_GRAY_ACTIVE + EL_EM_GATE_1_GRAY : + IS_EMC_GATE_GRAY_ACTIVE(element) ? + element - EL_EMC_GATE_5_GRAY_ACTIVE + EL_EMC_GATE_5_GRAY : + element); + DrawLevelField(x, y); } } } @@ -5657,15 +5776,17 @@ void ContinueMoving(int x, int y) if (pushed_by_player && !game.use_change_when_pushing_bug) { - int dig_side = MV_DIR_OPPOSITE(direction); + int push_side = MV_DIR_OPPOSITE(direction); struct PlayerInfo *player = PLAYERINFO(x, y); CheckElementChangeByPlayer(newx, newy, element, CE_PUSHED_BY_PLAYER, - player->index_bit, dig_side); + player->index_bit, push_side); CheckTriggeredElementChangeByPlayer(newx,newy, element, CE_PLAYER_PUSHES_X, - player->index_bit, dig_side); + player->index_bit, push_side); } + CheckTriggeredElementChangeBySide(x, y, element, CE_MOVE_OF_X, direction); + TestIfElementTouchesCustomElement(x, y); /* empty or new element */ TestIfElementHitsCustomElement(newx, newy, direction); @@ -6589,7 +6710,11 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) if (!change->has_action) return; - /* ---------- determine action paramater values ---------- */ + /* ---------- determine action paramater values -------------------------- */ + + int level_time_value = + (level.time > 0 ? TimeLeft : + TimePlayed); int action_arg_element = (action_arg == CA_ARG_PLAYER_TRIGGER ? change->actual_trigger_player : @@ -6647,6 +6772,9 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) action_arg == CA_ARG_NUMBER_CE_VALUE ? ei->custom_value_initial : #endif action_arg == CA_ARG_NUMBER_CE_DELAY ? GET_CHANGE_DELAY(change) : + action_arg == CA_ARG_NUMBER_LEVEL_TIME ? level_time_value : + action_arg == CA_ARG_NUMBER_LEVEL_GEMS ? local_player->gems_still_needed : + action_arg == CA_ARG_NUMBER_LEVEL_SCORE ? local_player->score : action_arg == CA_ARG_ELEMENT_TARGET ? GET_NEW_CUSTOM_VALUE(change->target_element) : action_arg == CA_ARG_ELEMENT_TRIGGER ? change->actual_trigger_ce_value : -1); @@ -6676,7 +6804,7 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) action_arg == CA_ARG_PLAYER_TRIGGER ? trigger_player_bits : PLAYER_BITS_ANY); - /* ---------- execute action ---------- */ + /* ---------- execute action -------------------------------------------- */ switch(action_type) { @@ -6685,24 +6813,78 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) return; } - case CA_EXIT_PLAYER: + /* ---------- level actions ------------------------------------------- */ + + case CA_RESTART_LEVEL: { - for (i = 0; i < MAX_PLAYERS; i++) - if (action_arg_player_bits & (1 << i)) - stored_player[i].LevelSolved = stored_player[i].GameOver = TRUE; + game.restart_level = TRUE; break; } - case CA_KILL_PLAYER: + case CA_SHOW_ENVELOPE: { - for (i = 0; i < MAX_PLAYERS; i++) - if (action_arg_player_bits & (1 << i)) - KillPlayer(&stored_player[i]); + int element = getSpecialActionElement(action_arg_element, + action_arg_number, EL_ENVELOPE_1); + + if (IS_ENVELOPE(element)) + local_player->show_envelope = element; break; } + case CA_SET_LEVEL_TIME: + { + if (level.time > 0) /* only modify limited time value */ + { + TimeLeft = action_arg_number_new; + + DrawGameValue_Time(TimeLeft); + + if (!TimeLeft && setup.time_limit) + for (i = 0; i < MAX_PLAYERS; i++) + KillPlayer(&stored_player[i]); + } + + break; + } + + case CA_SET_LEVEL_SCORE: + { + local_player->score = action_arg_number_new; + + DrawGameValue_Score(local_player->score); + + break; + } + + case CA_SET_LEVEL_GEMS: + { + local_player->gems_still_needed = action_arg_number_new; + + DrawGameValue_Emeralds(local_player->gems_still_needed); + + break; + } + + case CA_SET_LEVEL_GRAVITY: + { + game.gravity = (action_arg == CA_ARG_GRAVITY_OFF ? FALSE : + action_arg == CA_ARG_GRAVITY_ON ? TRUE : + action_arg == CA_ARG_GRAVITY_TOGGLE ? !game.gravity : + game.gravity); + break; + } + + case CA_SET_LEVEL_WIND: + { + game.wind_direction = action_arg_direction; + + break; + } + + /* ---------- player actions ------------------------------------------ */ + case CA_MOVE_PLAYER: { /* automatically move to the next field in specified direction */ @@ -6713,20 +6895,20 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) break; } - case CA_RESTART_LEVEL: + case CA_EXIT_PLAYER: { - game.restart_level = TRUE; + for (i = 0; i < MAX_PLAYERS; i++) + if (action_arg_player_bits & (1 << i)) + stored_player[i].LevelSolved = stored_player[i].GameOver = TRUE; break; } - case CA_SHOW_ENVELOPE: + case CA_KILL_PLAYER: { - int element = getSpecialActionElement(action_arg_element, - action_arg_number, EL_ENVELOPE_1); - - if (IS_ENVELOPE(element)) - local_player->show_envelope = element; + for (i = 0; i < MAX_PLAYERS; i++) + if (action_arg_player_bits & (1 << i)) + KillPlayer(&stored_player[i]); break; } @@ -6822,61 +7004,31 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) { for (i = 0; i < MAX_PLAYERS; i++) { - int element = action_arg_element; - } - - break; - } - - case CA_SET_LEVEL_GRAVITY: - { - game.gravity = (action_arg == CA_ARG_GRAVITY_OFF ? FALSE : - action_arg == CA_ARG_GRAVITY_ON ? TRUE : - action_arg == CA_ARG_GRAVITY_TOGGLE ? !game.gravity : - game.gravity); - break; - } - - case CA_SET_LEVEL_WIND: - { - game.wind_direction = action_arg_direction; - - break; - } - - case CA_SET_LEVEL_GEMS: - { - local_player->gems_still_needed = action_arg_number_new; - - DrawGameValue_Emeralds(local_player->gems_still_needed); + if (trigger_player_bits & (1 << i)) + { + int artwork_element = action_arg_element; - break; - } + if (action_arg == CA_ARG_ELEMENT_RESET) + artwork_element = stored_player[i].element_nr; - case CA_SET_LEVEL_TIME: - { - if (level.time > 0) /* only modify limited time value */ - { - TimeLeft = action_arg_number_new; + stored_player[i].artwork_element = artwork_element; - DrawGameValue_Time(TimeLeft); + SetPlayerWaiting(&stored_player[i], FALSE); - if (!TimeLeft && setup.time_limit) - for (i = 0; i < MAX_PLAYERS; i++) - KillPlayer(&stored_player[i]); + /* set number of special actions for bored and sleeping animation */ + stored_player[i].num_special_action_bored = + get_num_special_action(artwork_element, + ACTION_BORING_1, ACTION_BORING_LAST); + stored_player[i].num_special_action_sleeping = + get_num_special_action(artwork_element, + ACTION_SLEEPING_1, ACTION_SLEEPING_LAST); + } } break; } - case CA_SET_LEVEL_SCORE: - { - local_player->score = action_arg_number_new; - - DrawGameValue_Score(local_player->score); - - break; - } + /* ---------- CE actions ---------------------------------------------- */ case CA_SET_CE_SCORE: { @@ -7473,24 +7625,24 @@ static boolean CheckElementChangeExt(int x, int y, static void PlayPlayerSound(struct PlayerInfo *player) { int jx = player->jx, jy = player->jy; - int element = player->element_nr; + int sound_element = player->artwork_element; int last_action = player->last_action_waiting; int action = player->action_waiting; if (player->is_waiting) { if (action != last_action) - PlayLevelSoundElementAction(jx, jy, element, action); + PlayLevelSoundElementAction(jx, jy, sound_element, action); else - PlayLevelSoundElementActionIfLoop(jx, jy, element, action); + PlayLevelSoundElementActionIfLoop(jx, jy, sound_element, action); } else { if (action != last_action) - StopSound(element_info[element].sound[last_action]); + StopSound(element_info[sound_element].sound[last_action]); if (last_action == ACTION_SLEEPING) - PlayLevelSoundElementAction(jx, jy, element, ACTION_AWAKENING); + PlayLevelSoundElementAction(jx, jy, sound_element, ACTION_AWAKENING); } } @@ -7557,7 +7709,7 @@ static void SetPlayerWaiting(struct PlayerInfo *player, boolean is_waiting) last_special_action < ACTION_SLEEPING_1 + num_special_action - 1 ? last_special_action + 1 : ACTION_SLEEPING); int special_graphic = - el_act_dir2img(player->element_nr, special_action, move_dir); + el_act_dir2img(player->artwork_element, special_action, move_dir); player->anim_delay_counter = graphic_info[special_graphic].anim_delay_fixed + @@ -7589,7 +7741,7 @@ static void SetPlayerWaiting(struct PlayerInfo *player, boolean is_waiting) int special_action = ACTION_BORING_1 + SimpleRND(player->num_special_action_bored); int special_graphic = - el_act_dir2img(player->element_nr, special_action, move_dir); + el_act_dir2img(player->artwork_element, special_action, move_dir); player->anim_delay_counter = graphic_info[special_graphic].anim_delay_fixed + @@ -7911,6 +8063,8 @@ void GameActions() { RemoveField(x, y); DrawLevelField(x, y); + + TestIfElementTouchesCustomElement(x, y); /* for empty space */ } } #endif @@ -8212,6 +8366,22 @@ void GameActions() CloseAllOpenTimegates(); } + if (game.lenses_time_left > 0) + { + game.lenses_time_left--; + + if (game.lenses_time_left == 0) + RedrawAllInvisibleElementsForLenses(); + } + + if (game.magnify_time_left > 0) + { + game.magnify_time_left--; + + if (game.magnify_time_left == 0) + RedrawAllInvisibleElementsForMagnifier(); + } + for (i = 0; i < MAX_PLAYERS; i++) { struct PlayerInfo *player = &stored_player[i]; @@ -8877,6 +9047,9 @@ void ScrollPlayer(struct PlayerInfo *player, int mode) CheckTriggeredElementChangeByPlayer(jx, jy, new_element, CE_PLAYER_ENTERS_X, player->index_bit, enter_side); + + CheckTriggeredElementChangeBySide(jx, jy, player->element_nr, + CE_MOVE_OF_X, move_direction); } if (game.engine_version >= VERSION_IDENT(3,0,7,0)) @@ -9452,7 +9625,7 @@ void BuryPlayer(struct PlayerInfo *player) if (!player->active) return; - PlayLevelSoundElementAction(jx, jy, player->element_nr, ACTION_DYING); + PlayLevelSoundElementAction(jx, jy, player->artwork_element, ACTION_DYING); PlayLevelSound(jx, jy, SND_GAME_LOSING); player->GameOver = TRUE; @@ -9625,7 +9798,17 @@ int DigField(struct PlayerInfo *player, if (mode == DF_SNAP && !IS_SNAPPABLE(element) && game.engine_version >= VERSION_IDENT(2,2,0,0)) + { + CheckElementChangeByPlayer(x, y, element, CE_SNAPPED_BY_PLAYER, + player->index_bit, dig_side); + CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_SNAPS_X, + player->index_bit, dig_side); + + if (Feld[x][y] != element) /* field changed by snapping */ + return MF_ACTION; + return MF_NO_ACTION; + } if (game.gravity && is_player && !player->is_auto_moving && canFallDown(player) && move_direction != MV_DOWN && @@ -9647,6 +9830,11 @@ int DigField(struct PlayerInfo *player, if (!player->key[RND_GATE_GRAY_NR(element)]) return MF_NO_ACTION; } + else if (IS_RND_GATE_GRAY_ACTIVE(element)) + { + if (!player->key[RND_GATE_GRAY_ACTIVE_NR(element)]) + return MF_NO_ACTION; + } else if (element == EL_EXIT_OPEN || element == EL_SP_EXIT_OPEN || element == EL_SP_EXIT_OPENING) @@ -9662,7 +9850,7 @@ int DigField(struct PlayerInfo *player, if (element_info[sound_element].sound[sound_action] != SND_UNDEFINED) PlayLevelSoundElementAction(x, y, sound_element, sound_action); else - PlayLevelSoundElementAction(x, y, player->element_nr, sound_action); + PlayLevelSoundElementAction(x, y, player->artwork_element, sound_action); } else if (IS_PASSABLE(element) && canPassField(x, y, move_direction)) { @@ -9682,6 +9870,11 @@ int DigField(struct PlayerInfo *player, if (!player->key[EM_GATE_GRAY_NR(element)]) return MF_NO_ACTION; } + else if (IS_EM_GATE_GRAY_ACTIVE(element)) + { + if (!player->key[EM_GATE_GRAY_ACTIVE_NR(element)]) + return MF_NO_ACTION; + } else if (IS_SP_PORT(element)) { if (element == EL_SP_GRAVITY_PORT_LEFT || @@ -9730,12 +9923,17 @@ int DigField(struct PlayerInfo *player, if (mode == DF_SNAP) { - TestIfElementTouchesCustomElement(x, y); /* for empty space */ - #if USE_NEW_SNAP_DELAY if (level.block_snap_field) setFieldForSnapping(x, y, element, move_direction); + else + TestIfElementTouchesCustomElement(x, y); /* for empty space */ +#else + TestIfElementTouchesCustomElement(x, y); /* for empty space */ #endif + + CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_SNAPS_X, + player->index_bit, dig_side); } } else if (IS_COLLECTIBLE(element)) @@ -9795,6 +9993,18 @@ int DigField(struct PlayerInfo *player, { player->show_envelope = element; } + else if (element == EL_EMC_LENSES) + { + game.lenses_time_left = level.lenses_time * FRAMES_PER_SECOND; + + RedrawAllInvisibleElementsForLenses(); + } + else if (element == EL_EMC_MAGNIFIER) + { + game.magnify_time_left = level.magnify_time * FRAMES_PER_SECOND; + + RedrawAllInvisibleElementsForMagnifier(); + } else if (IS_DROPPABLE(element) || IS_THROWABLE(element)) /* can be collected and dropped */ { @@ -9827,12 +10037,17 @@ int DigField(struct PlayerInfo *player, if (mode == DF_SNAP) { - TestIfElementTouchesCustomElement(x, y); /* for empty space */ - #if USE_NEW_SNAP_DELAY if (level.block_snap_field) setFieldForSnapping(x, y, element, move_direction); + else + TestIfElementTouchesCustomElement(x, y); /* for empty space */ +#else + TestIfElementTouchesCustomElement(x, y); /* for empty space */ #endif + + CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_SNAPS_X, + player->index_bit, dig_side); } } else if (IS_PUSHABLE(element)) @@ -10059,6 +10274,9 @@ int DigField(struct PlayerInfo *player, CheckTriggeredElementChangeByPlayer(x, y, element, CE_SWITCH_OF_X, player->index_bit, dig_side); + CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_SWITCHES_X, + player->index_bit, dig_side); + CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_PRESSES_X, player->index_bit, dig_side); @@ -10076,6 +10294,11 @@ int DigField(struct PlayerInfo *player, player->index_bit, dig_side); CheckTriggeredElementChangeByPlayer(x, y, element, CE_SWITCH_OF_X, player->index_bit, dig_side); + + CheckElementChangeByPlayer(x, y, element, CE_SWITCHED_BY_PLAYER, + player->index_bit, dig_side); + CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_SWITCHES_X, + player->index_bit, dig_side); } CheckElementChangeByPlayer(x, y, element, CE_PRESSED_BY_PLAYER, @@ -10636,7 +10859,7 @@ void RaiseScoreElement(int element) RaiseScore(level.score[SC_SHIELD]); break; case EL_EXTRA_TIME: - RaiseScore(level.score[SC_TIME_BONUS]); + RaiseScore(level.extra_time_score); break; case EL_KEY_1: case EL_KEY_2: