X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=6a797d86e7a0ff2545d3009c56cf9d776f79a93b;hb=73dfe4a920cabf20138c0ba49964a3c8c3f752d0;hp=cd919a2b3406687e2110a8c10123d032718c662f;hpb=075eb3589303dd053c9c09aa1ce2feadb397741e;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index cd919a2b..6a797d86 100644 --- a/src/game.c +++ b/src/game.c @@ -241,18 +241,38 @@ int DigField(struct PlayerInfo *, int, int, int, int, int, int, int); static void InitBeltMovement(void); static void CloseAllOpenTimegates(void); static void CheckGravityMovement(struct PlayerInfo *); +static void CheckGravityMovementWhenNotMoving(struct PlayerInfo *); static void KillHeroUnlessEnemyProtected(int, int); static void KillHeroUnlessExplosionProtected(int, int); static void TestIfPlayerTouchesCustomElement(int, int); static void TestIfElementTouchesCustomElement(int, int); static void TestIfElementHitsCustomElement(int, int, int); +#if 0 +static void TestIfElementSmashesCustomElement(int, int, int); +#endif static void ChangeElement(int, int, int); -static boolean CheckTriggeredElementSideChange(int, int, int, int, int); -static boolean CheckTriggeredElementChange(int, int, int, int); -static boolean CheckElementSideChange(int, int, int, int, int, int); -static boolean CheckElementChange(int, int, int, int); + +static boolean CheckTriggeredElementChangeExt(int, int, int, int, int,int,int); +#define CheckTriggeredElementChange(x, y, e, ev) \ + CheckTriggeredElementChangeExt(x, y, e, ev, -1, CH_SIDE_ANY, -1) +#define CheckTriggeredElementChangePlayer(x, y, e, ev, p, s) \ + CheckTriggeredElementChangeExt(x, y, e, ev, p, s, -1) +#define CheckTriggeredElementChangeSide(x, y, e, ev, s) \ + CheckTriggeredElementChangeExt(x, y, e, ev, -1, s, -1) +#define CheckTriggeredElementChangePage(x, y, e, ev, p) \ + CheckTriggeredElementChangeExt(x, y, e, ev, -1, CH_SIDE_ANY, p) + +static boolean CheckElementChangeExt(int, int, int, int, int, int, int); +#define CheckElementChange(x, y, e, ev) \ + CheckElementChangeExt(x, y, e, ev, -1, CH_SIDE_ANY, -1) +#define CheckElementChangePlayer(x, y, e, ev, p, s) \ + CheckElementChangeExt(x, y, e, ev, p, s, -1) +#define CheckElementChangeSide(x, y, e, ev, s) \ + CheckElementChangeExt(x, y, e, ev, -1, s, -1) +#define CheckElementChangePage(x, y, e, ev, p) \ + CheckElementChangeExt(x, y, e, ev, -1, CH_SIDE_ANY, p) static void PlayLevelSound(int, int, int); static void PlayLevelSoundNearest(int, int, int); @@ -1336,6 +1356,7 @@ void InitGame() struct PlayerInfo *player = &stored_player[i]; player->index_nr = i; + player->index_bit = (1 << i); player->element_nr = EL_PLAYER_1 + i; player->present = FALSE; @@ -1454,6 +1475,7 @@ void InitGame() player->shield_normal_time_left = 0; player->shield_deadly_time_left = 0; + player->inventory_infinite_element = EL_UNDEFINED; player->inventory_size = 0; DigField(player, 0, 0, 0, 0, 0, 0, DF_NO_PUSH); @@ -1477,6 +1499,7 @@ void InitGame() TimeFrames = 0; TimePlayed = 0; TimeLeft = level.time; + TapeTime = 0; ScreenMovDir = MV_NO_MOVING; ScreenMovPos = 0; @@ -1611,6 +1634,10 @@ void InitGame() some_player->present = FALSE; some_player->active = FALSE; +#if 0 + player->element_nr = some_player->element_nr; +#endif + StorePlayer[jx][jy] = player->element_nr; player->jx = player->last_jx = jx; player->jy = player->last_jy = jy; @@ -2518,6 +2545,9 @@ void RelocatePlayer(int x, int y, int element_raw) boolean no_delay = (tape.index_search); int frame_delay_value = (ffwd_delay ? FfwdFrameDelay : GameFrameDelay); int wait_delay_value = (no_delay ? 0 : frame_delay_value); +#if 1 + int old_jx, old_jy; +#endif if (player->GameOver) /* do not reanimate dead player */ return; @@ -2547,9 +2577,49 @@ void RelocatePlayer(int x, int y, int element_raw) player->is_moving = FALSE; } +#if 1 + old_jx = player->jx; + old_jy = player->jy; +#endif + Feld[x][y] = element; InitPlayerField(x, y, element, TRUE); +#if 0 + if (player == local_player) + { +#if 1 + + scroll_x += (local_player->jx - old_jx); + scroll_y += (local_player->jy - old_jy); + + /* 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); + +#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); +#endif + + RedrawPlayfield(TRUE, 0,0,0,0); +#if 0 + DrawAllPlayers(); + BackToFront(); +#endif + } + +#else + if (player == local_player) { int scroll_xx = -999, scroll_yy = -999; @@ -2589,6 +2659,7 @@ void RelocatePlayer(int x, int y, int element_raw) Delay(wait_delay_value); } } +#endif } void Explode(int ex, int ey, int phase, int mode) @@ -2620,6 +2691,10 @@ void Explode(int ex, int ey, int phase, int mode) { int center_element = Feld[ex][ey]; +#if 0 + printf("::: start explosion %d,%d [%d]\n", ex, ey, FrameCounter); +#endif + #if 0 /* --- This is only really needed (and now handled) in "Impact()". --- */ /* do not explode moving elements that left the explode field in time */ @@ -2960,6 +3035,10 @@ void Explode(int ex, int ey, int phase, int mode) { int element; +#if 0 + printf("::: explosion %d,%d done [%d]\n", x, y, FrameCounter); +#endif + element = Feld[x][y] = Store[x][y]; Store[x][y] = Store2[x][y] = 0; GfxElement[x][y] = EL_UNDEFINED; @@ -3169,11 +3248,9 @@ void Bang(int x, int y) case EL_PENGUIN: case EL_LAMP: case EL_LAMP_ACTIVE: - #if 1 case EL_AMOEBA_TO_DIAMOND: #endif - if (IS_PLAYER(x, y)) Explode(x, y, EX_PHASE_START, EX_NORMAL); else @@ -3770,12 +3847,15 @@ void Impact(int x, int y) } else { +#if 0 + TestIfElementSmashesCustomElement(x, y, MV_DOWN); +#endif + CheckElementChange(x, y + 1, smashed, CE_SMASHED); - CheckTriggeredElementSideChange(x, y + 1, smashed, CH_SIDE_TOP, - CE_OTHER_IS_SWITCHING); - CheckElementSideChange(x, y + 1, smashed, CH_SIDE_TOP, - CE_SWITCHED, -1); + CheckTriggeredElementChangeSide(x, y + 1, smashed, + CE_OTHER_IS_SWITCHING, CH_SIDE_TOP); + CheckElementChangeSide(x, y + 1, smashed, CE_SWITCHED, CH_SIDE_TOP); } } else @@ -5632,8 +5712,8 @@ void ContinueMoving(int x, int y) int hitting_element = Feld[newx][newy]; /* !!! fix side (direction) orientation here and elsewhere !!! */ - CheckElementSideChange(newx, newy, hitting_element, - direction, CE_HITTING_SOMETHING, -1); + CheckElementChangeSide(newx, newy, hitting_element, CE_HITTING_SOMETHING, + direction); #if 0 if (IN_LEV_FIELD(nextx, nexty)) @@ -5650,8 +5730,8 @@ void ContinueMoving(int x, int y) { int i; - CheckElementSideChange(nextx, nexty, touched_element, - opposite_direction, CE_HIT_BY_SOMETHING, -1); + CheckElementChangeSide(nextx, nexty, touched_element, + CE_HIT_BY_SOMETHING, opposite_direction); if (IS_CUSTOM_ELEMENT(hitting_element) && HAS_ANY_CHANGE_EVENT(hitting_element, CE_OTHER_IS_HITTING)) @@ -5663,11 +5743,11 @@ void ContinueMoving(int x, int y) if (change->can_change && change->events & CH_EVENT_BIT(CE_OTHER_IS_HITTING) && - change->sides & touched_side && + change->trigger_side & touched_side && change->trigger_element == touched_element) { - CheckElementSideChange(newx, newy, hitting_element, - CH_SIDE_ANY, CE_OTHER_IS_HITTING, i); + CheckElementChangePage(newx, newy, hitting_element, + CE_OTHER_IS_HITTING, i); break; } } @@ -5683,11 +5763,11 @@ void ContinueMoving(int x, int y) if (change->can_change && change->events & CH_EVENT_BIT(CE_OTHER_GETS_HIT) && - change->sides & hitting_side && + change->trigger_side & hitting_side && change->trigger_element == hitting_element) { - CheckElementSideChange(nextx, nexty, touched_element, - CH_SIDE_ANY, CE_OTHER_GETS_HIT, i); + CheckElementChangePage(nextx, nexty, touched_element, + CE_OTHER_GETS_HIT, i); break; } } @@ -6659,7 +6739,7 @@ static boolean ChangeElementNow(int x, int y, int element, int page) Changed[x][y] |= ChangeEvent[x][y]; /* ignore same changes in this frame */ - CheckTriggeredElementChange(x, y, Feld[x][y], CE_OTHER_IS_CHANGING); + CheckTriggeredElementChangePage(x,y, Feld[x][y], CE_OTHER_IS_CHANGING, page); if (change->explode) { @@ -6833,10 +6913,12 @@ static void ChangeElement(int x, int y, int page) } } -static boolean CheckTriggeredElementSideChange(int lx, int ly, - int trigger_element, - int trigger_side, - int trigger_event) +static boolean CheckTriggeredElementChangeExt(int lx, int ly, + int trigger_element, + int trigger_event, + int trigger_player, + int trigger_side, + int trigger_page) { int i, j, x, y; @@ -6858,16 +6940,11 @@ static boolean CheckTriggeredElementSideChange(int lx, int ly, struct ElementChangeInfo *change = &element_info[element].change_page[j]; if (change->can_change && -#if 1 change->events & CH_EVENT_BIT(trigger_event) && -#endif - change->sides & trigger_side && -#if 1 - IS_EQUAL_OR_IN_GROUP(trigger_element, change->trigger_element) -#else - change->trigger_element == trigger_element -#endif - ) + change->trigger_side & trigger_side && + change->trigger_player & trigger_player && + change->trigger_page & (1 << trigger_page) && + IS_EQUAL_OR_IN_GROUP(trigger_element, change->trigger_element)) { #if 0 if (!(change->events & CH_EVENT_BIT(trigger_event))) @@ -6904,15 +6981,12 @@ static boolean CheckTriggeredElementSideChange(int lx, int ly, return TRUE; } -static boolean CheckTriggeredElementChange(int lx, int ly, int trigger_element, - int trigger_event) -{ - return CheckTriggeredElementSideChange(lx, ly, trigger_element, CH_SIDE_ANY, - trigger_event); -} - -static boolean CheckElementSideChange(int x, int y, int element, int side, - int trigger_event, int page) +static boolean CheckElementChangeExt(int x, int y, + int element, + int trigger_event, + int trigger_player, + int trigger_side, + int trigger_page) { if (!CAN_CHANGE(element) || !HAS_ANY_CHANGE_EVENT(element, trigger_event)) return FALSE; @@ -6924,7 +6998,7 @@ static boolean CheckElementSideChange(int x, int y, int element, int side, } #if 1 - if (page < 0) + if (trigger_page < 0) { boolean change_element = FALSE; int i; @@ -6935,10 +7009,11 @@ static boolean CheckElementSideChange(int x, int y, int element, int side, if (change->can_change && change->events & CH_EVENT_BIT(trigger_event) && - change->sides & side) + change->trigger_side & trigger_side && + change->trigger_player & trigger_player) { change_element = TRUE; - page = i; + trigger_page = i; break; } @@ -6952,25 +7027,20 @@ static boolean CheckElementSideChange(int x, int y, int element, int side, /* !!! this check misses pages with same event, but different side !!! */ - if (page < 0) - page = element_info[element].event_page_nr[trigger_event]; + if (trigger_page < 0) + trigger_page = element_info[element].event_page_nr[trigger_event]; - if (!(element_info[element].change_page[page].sides & side)) + if (!(element_info[element].change_page[trigger_page].trigger_side & trigger_side)) return FALSE; #endif ChangeDelay[x][y] = 1; ChangeEvent[x][y] = CH_EVENT_BIT(trigger_event); - ChangeElement(x, y, page); + ChangeElement(x, y, trigger_page); return TRUE; } -static boolean CheckElementChange(int x, int y, int element, int trigger_event) -{ - return CheckElementSideChange(x, y, element, CH_SIDE_ANY, trigger_event, -1); -} - static void PlayPlayerSound(struct PlayerInfo *player) { int jx = player->jx, jy = player->jy; @@ -7173,6 +7243,11 @@ static byte PlayerActions(struct PlayerInfo *player, byte player_action) printf("::: player %d acts [%d]\n", player->index_nr, FrameCounter); #endif +#if 0 + /* !!! TEST !!! */ + if (player->MovPos == 0) + CheckGravityMovement(player); +#endif if (button1) snapped = SnapField(player, dx, dy); else @@ -7210,7 +7285,7 @@ static byte PlayerActions(struct PlayerInfo *player, byte player_action) DigField(player, 0, 0, 0, 0, 0, 0, DF_NO_PUSH); SnapField(player, 0, 0); - CheckGravityMovement(player); + CheckGravityMovementWhenNotMoving(player); if (player->MovPos == 0) SetPlayerWaiting(player, TRUE); @@ -7291,7 +7366,7 @@ static void PlayerActions(struct PlayerInfo *player, byte player_action) DigField(player, 0, 0, 0, 0, 0, 0, DF_NO_PUSH); SnapField(player, 0, 0); - CheckGravityMovement(player); + CheckGravityMovementWhenNotMoving(player); if (player->MovPos == 0) InitPlayerGfxAnimation(player, ACTION_DEFAULT, player->MovDir); @@ -7371,6 +7446,12 @@ void GameActions() recorded_player_action = (tape.playing ? TapePlayAction() : NULL); +#if 1 + if (recorded_player_action != NULL) + for (i = 0; i < MAX_PLAYERS; i++) + stored_player[i].action = recorded_player_action[i]; +#endif + for (i = 0; i < MAX_PLAYERS; i++) { summarized_player_action |= stored_player[i].action; @@ -7391,11 +7472,43 @@ void GameActions() { int actual_player_action = stored_player[i].effective_action; +#if 1 + /* !!! TEST !!! */ + if (stored_player[i].MovPos == 0) + CheckGravityMovement(&stored_player[i]); +#endif + +#if 1 + /* overwrite programmed action with tape action */ if (stored_player[i].programmed_action) actual_player_action = stored_player[i].programmed_action; +#endif if (recorded_player_action) + { +#if 0 + if (stored_player[i].programmed_action && + stored_player[i].programmed_action != recorded_player_action[i]) + printf("::: %d: %d <-> %d\n", i, + stored_player[i].programmed_action, recorded_player_action[i]); +#endif + +#if 0 actual_player_action = recorded_player_action[i]; +#endif + } + +#if 0 + /* overwrite tape action with programmed action */ + if (stored_player[i].programmed_action) + actual_player_action = stored_player[i].programmed_action; +#endif + +#if 0 + if (i == 0) + printf("::: action: %d: %x [%d]\n", + stored_player[i].MovPos, actual_player_action, FrameCounter); +#endif tape_action[i] = PlayerActions(&stored_player[i], actual_player_action); @@ -7829,39 +7942,44 @@ void GameActions() if (TimeFrames >= FRAMES_PER_SECOND) { TimeFrames = 0; - TimePlayed++; + TapeTime++; - for (i = 0; i < MAX_PLAYERS; i++) + if (!level.use_step_counter) { - struct PlayerInfo *player = &stored_player[i]; + TimePlayed++; - if (SHIELD_ON(player)) + for (i = 0; i < MAX_PLAYERS; i++) { - player->shield_normal_time_left--; + struct PlayerInfo *player = &stored_player[i]; - if (player->shield_deadly_time_left > 0) - player->shield_deadly_time_left--; - } - } + if (SHIELD_ON(player)) + { + player->shield_normal_time_left--; - if (tape.recording || tape.playing) - DrawVideoDisplay(VIDEO_STATE_TIME_ON, TimePlayed); + if (player->shield_deadly_time_left > 0) + player->shield_deadly_time_left--; + } + } - if (TimeLeft > 0) - { - TimeLeft--; + if (TimeLeft > 0) + { + TimeLeft--; - if (TimeLeft <= 10 && setup.time_limit) - PlaySoundStereo(SND_GAME_RUNNING_OUT_OF_TIME, SOUND_MIDDLE); + if (TimeLeft <= 10 && setup.time_limit) + PlaySoundStereo(SND_GAME_RUNNING_OUT_OF_TIME, SOUND_MIDDLE); - DrawGameValue_Time(TimeLeft); + DrawGameValue_Time(TimeLeft); - if (!TimeLeft && setup.time_limit) - for (i = 0; i < MAX_PLAYERS; i++) - KillHero(&stored_player[i]); + if (!TimeLeft && setup.time_limit) + for (i = 0; i < MAX_PLAYERS; i++) + KillHero(&stored_player[i]); + } + else if (level.time == 0 && !AllPlayersGone) /* level w/o time limit */ + DrawGameValue_Time(TimePlayed); } - else if (level.time == 0 && !AllPlayersGone) /* level without time limit */ - DrawGameValue_Time(TimePlayed); + + if (tape.recording || tape.playing) + DrawVideoDisplay(VIDEO_STATE_TIME_ON, TapeTime); } DrawAllPlayers(); @@ -8031,20 +8149,33 @@ static void CheckGravityMovement(struct PlayerInfo *player) { if (game.gravity && !player->programmed_action) { - int move_dir_vertical = player->action & (MV_UP | MV_DOWN); - int move_dir_horizontal = player->action & (MV_LEFT | MV_RIGHT); + int move_dir_horizontal = player->action & MV_HORIZONTAL; + int move_dir_vertical = player->action & MV_VERTICAL; int move_dir = - (player->last_move_dir & (MV_LEFT | MV_RIGHT) ? + (player->last_move_dir & MV_HORIZONTAL ? (move_dir_vertical ? move_dir_vertical : move_dir_horizontal) : (move_dir_horizontal ? move_dir_horizontal : move_dir_vertical)); int jx = player->jx, jy = player->jy; int dx = (move_dir & MV_LEFT ? -1 : move_dir & MV_RIGHT ? +1 : 0); int dy = (move_dir & MV_UP ? -1 : move_dir & MV_DOWN ? +1 : 0); int new_jx = jx + dx, new_jy = jy + dy; - boolean field_under_player_is_free = - (IN_LEV_FIELD(jx, jy + 1) && IS_FREE(jx, jy + 1)); + boolean player_is_snapping = player->action & JOY_BUTTON_1; +#if 1 + boolean player_can_fall_down = + (IN_LEV_FIELD(jx, jy + 1) && + (IS_FREE(jx, jy + 1) || + (Feld[jx][jy + 1] == EL_ACID && level.player_can_fall_into_acid))); +#else + boolean player_can_fall_down = + (IN_LEV_FIELD(jx, jy + 1) && + (IS_FREE(jx, jy + 1))); +#endif boolean player_is_moving_to_valid_field = - (IN_LEV_FIELD(new_jx, new_jy) && + ( +#if 1 + !player_is_snapping && +#endif + IN_LEV_FIELD(new_jx, new_jy) && (Feld[new_jx][new_jy] == EL_SP_BASE || Feld[new_jx][new_jy] == EL_SAND || (IS_SP_PORT(Feld[new_jx][new_jy]) && @@ -8056,9 +8187,45 @@ static void CheckGravityMovement(struct PlayerInfo *player) (IS_WALKABLE(Feld[jx][jy]) && !(element_info[Feld[jx][jy]].access_direction & MV_DOWN))); - if (field_under_player_is_free && +#if 0 + printf("::: checking gravity NOW [%d, %d, %d] [%d] ...\n", + player_can_fall_down, + player_is_standing_on_valid_field, + player_is_moving_to_valid_field, + (player_is_moving_to_valid_field ? Feld[new_jx][new_jy] : -1)); +#endif + + if (player_can_fall_down && !player_is_standing_on_valid_field && !player_is_moving_to_valid_field) + { +#if 0 + printf("::: setting programmed_action to MV_DOWN [%d,%d - %d] ...\n", + jx, jy, FrameCounter); +#endif + + player->programmed_action = MV_DOWN; + } + } +} + +static void CheckGravityMovementWhenNotMoving(struct PlayerInfo *player) +{ +#if 1 + return CheckGravityMovement(player); +#endif + + if (game.gravity && !player->programmed_action) + { + int jx = player->jx, jy = player->jy; + boolean field_under_player_is_free = + (IN_LEV_FIELD(jx, jy + 1) && IS_FREE(jx, jy + 1)); + boolean player_is_standing_on_valid_field = + (IS_WALKABLE_INSIDE(Feld[jx][jy]) || + (IS_WALKABLE(Feld[jx][jy]) && + !(element_info[Feld[jx][jy]].access_direction & MV_DOWN))); + + if (field_under_player_is_free && !player_is_standing_on_valid_field) player->programmed_action = MV_DOWN; } } @@ -8074,7 +8241,7 @@ boolean MovePlayerOneStep(struct PlayerInfo *player, int dx, int dy, int real_dx, int real_dy) { #if 0 - static int change_sides[4][2] = + static int trigger_sides[4][2] = { /* enter side leave side */ { CH_SIDE_RIGHT, CH_SIDE_LEFT }, /* moving left */ @@ -8086,8 +8253,8 @@ boolean MovePlayerOneStep(struct PlayerInfo *player, dx == +1 ? MV_RIGHT : dy == -1 ? MV_UP : dy == +1 ? MV_DOWN : MV_NO_MOVING); - int enter_side = change_sides[MV_DIR_BIT(move_direction)][0]; - int leave_side = change_sides[MV_DIR_BIT(move_direction)][1]; + int enter_side = trigger_sides[MV_DIR_BIT(move_direction)][0]; + int leave_side = trigger_sides[MV_DIR_BIT(move_direction)][1]; #endif int jx = player->jx, jy = player->jy; int new_jx = jx + dx, new_jy = jy + dy; @@ -8160,18 +8327,17 @@ boolean MovePlayerOneStep(struct PlayerInfo *player, #if 0 if (IS_CUSTOM_ELEMENT(Feld[jx][jy])) { - CheckTriggeredElementSideChange(jx, jy, Feld[jx][jy], leave_side, - CE_OTHER_GETS_LEFT); - CheckElementSideChange(jx, jy, Feld[jx][jy], leave_side, - CE_LEFT_BY_PLAYER, -1); + CheckTriggeredElementChangeSide(jx, jy, Feld[jx][jy], CE_OTHER_GETS_LEFT, + leave_side); + CheckElementChangeSide(jx, jy, Feld[jx][jy], CE_LEFT_BY_PLAYER,leave_side); } if (IS_CUSTOM_ELEMENT(Feld[new_jx][new_jy])) { - CheckTriggeredElementSideChange(new_jx, new_jy, Feld[new_jx][new_jy], - enter_side, CE_OTHER_GETS_ENTERED); - CheckElementSideChange(new_jx, new_jy, Feld[new_jx][new_jy], enter_side, - CE_ENTERED_BY_PLAYER, -1); + CheckTriggeredElementChangeSide(new_jx, new_jy, Feld[new_jx][new_jy], + CE_OTHER_GETS_ENTERED, enter_side); + CheckElementChangeSide(new_jx, new_jy, Feld[new_jx][new_jy], + CE_ENTERED_BY_PLAYER, enter_side); } #endif @@ -8211,9 +8377,16 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy) !tape.playing) return FALSE; #else + +#if 1 + if (!FrameReached(&player->move_delay, player->move_delay_value)) + return FALSE; +#else if (!FrameReached(&player->move_delay, player->move_delay_value) && !(tape.playing && tape.file_version < FILE_VERSION_2_0)) return FALSE; +#endif + #endif /* remove the last programmed player action */ @@ -8246,7 +8419,7 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy) player->move_delay_value = original_move_delay_value; } - if (player->last_move_dir & (MV_LEFT | MV_RIGHT)) + if (player->last_move_dir & MV_HORIZONTAL) { if (!(moved |= MovePlayerOneStep(player, 0, dy, dx, dy))) moved |= MovePlayerOneStep(player, dx, 0, dx, dy); @@ -8364,7 +8537,7 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy) #if 1 { - static int change_sides[4][2] = + static int trigger_sides[4][2] = { /* enter side leave side */ { CH_SIDE_RIGHT, CH_SIDE_LEFT }, /* moving left */ @@ -8373,24 +8546,27 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy) { CH_SIDE_TOP, CH_SIDE_BOTTOM } /* moving down */ }; int move_direction = player->MovDir; - int enter_side = change_sides[MV_DIR_BIT(move_direction)][0]; - int leave_side = change_sides[MV_DIR_BIT(move_direction)][1]; + int enter_side = trigger_sides[MV_DIR_BIT(move_direction)][0]; + int leave_side = trigger_sides[MV_DIR_BIT(move_direction)][1]; #if 1 if (IS_CUSTOM_ELEMENT(Feld[old_jx][old_jy])) { - CheckTriggeredElementSideChange(old_jx, old_jy, Feld[old_jx][old_jy], - leave_side, CE_OTHER_GETS_LEFT); - CheckElementSideChange(old_jx, old_jy, Feld[old_jx][old_jy], - leave_side, CE_LEFT_BY_PLAYER, -1); + CheckTriggeredElementChangePlayer(old_jx, old_jy, Feld[old_jx][old_jy], + CE_OTHER_GETS_LEFT, + player->index_bit, leave_side); + CheckElementChangePlayer(old_jx, old_jy, Feld[old_jx][old_jy], + CE_LEFT_BY_PLAYER, + player->index_bit, leave_side); } if (IS_CUSTOM_ELEMENT(Feld[jx][jy])) { - CheckTriggeredElementSideChange(jx, jy, Feld[jx][jy], - enter_side, CE_OTHER_GETS_ENTERED); - CheckElementSideChange(jx, jy, Feld[jx][jy], - enter_side, CE_ENTERED_BY_PLAYER, -1); + CheckTriggeredElementChangePlayer(jx, jy, Feld[jx][jy], + CE_OTHER_GETS_ENTERED, + player->index_bit, enter_side); + CheckElementChangePlayer(jx, jy, Feld[jx][jy], CE_ENTERED_BY_PLAYER, + player->index_bit, enter_side); } #endif @@ -8401,7 +8577,7 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy) } else { - CheckGravityMovement(player); + CheckGravityMovementWhenNotMoving(player); /* player->last_move_dir = MV_NO_MOVING; @@ -8508,6 +8684,47 @@ void ScrollPlayer(struct PlayerInfo *player, int mode) player->LevelSolved = player->GameOver = TRUE; } +#if 0 + /* !!! ENABLE THIS FOR NEW VERSIONS !!! */ + { + static int trigger_sides[4][2] = + { + /* enter side leave side */ + { CH_SIDE_RIGHT, CH_SIDE_LEFT }, /* moving left */ + { CH_SIDE_LEFT, CH_SIDE_RIGHT }, /* moving right */ + { CH_SIDE_BOTTOM, CH_SIDE_TOP }, /* moving up */ + { CH_SIDE_TOP, CH_SIDE_BOTTOM } /* moving down */ + }; + int move_direction = player->MovDir; + int enter_side = trigger_sides[MV_DIR_BIT(move_direction)][0]; + int leave_side = trigger_sides[MV_DIR_BIT(move_direction)][1]; + int old_jx = last_jx; + int old_jy = last_jy; + +#if 1 + if (IS_CUSTOM_ELEMENT(Feld[old_jx][old_jy])) + { + CheckTriggeredElementChangePlayer(old_jx, old_jy, Feld[old_jx][old_jy], + CE_OTHER_GETS_LEFT, + player->index_bit, leave_side); + CheckElementChangePlayer(old_jx, old_jy, Feld[old_jx][old_jy], + CE_LEFT_BY_PLAYER, + player->index_bit, leave_side); + } + + if (IS_CUSTOM_ELEMENT(Feld[jx][jy])) + { + CheckTriggeredElementChangePlayer(jx, jy, Feld[jx][jy], + CE_OTHER_GETS_ENTERED, + player->index_bit, enter_side); + CheckElementChangePlayer(jx, jy, Feld[jx][jy], CE_ENTERED_BY_PLAYER, + player->index_bit, enter_side); + } +#endif + + } +#endif + if (game.engine_version >= VERSION_IDENT(3,0,7,0)) { TestIfHeroTouchesBadThing(jx, jy); @@ -8520,6 +8737,42 @@ void ScrollPlayer(struct PlayerInfo *player, int mode) RemoveHero(player); } + if (level.use_step_counter) + { + int i; + + TimePlayed++; + + for (i = 0; i < MAX_PLAYERS; i++) + { + struct PlayerInfo *player = &stored_player[i]; + + if (SHIELD_ON(player)) + { + player->shield_normal_time_left--; + + if (player->shield_deadly_time_left > 0) + player->shield_deadly_time_left--; + } + } + + if (TimeLeft > 0) + { + TimeLeft--; + + if (TimeLeft <= 10 && setup.time_limit) + PlaySoundStereo(SND_GAME_RUNNING_OUT_OF_TIME, SOUND_MIDDLE); + + DrawGameValue_Time(TimeLeft); + + if (!TimeLeft && setup.time_limit) + for (i = 0; i < MAX_PLAYERS; i++) + KillHero(&stored_player[i]); + } + else if (level.time == 0 && !AllPlayersGone) /* level w/o time limit */ + DrawGameValue_Time(TimePlayed); + } + if (tape.single_step && tape.recording && !tape.pausing && !player->programmed_action) TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); @@ -8563,7 +8816,7 @@ void TestIfPlayerTouchesCustomElement(int x, int y) { +1, 0 }, { 0, +1 } }; - static int change_sides[4][2] = + static int trigger_sides[4][2] = { /* center side border side */ { CH_SIDE_TOP, CH_SIDE_BOTTOM }, /* check top */ @@ -8585,8 +8838,8 @@ void TestIfPlayerTouchesCustomElement(int x, int y) { int xx = x + xy[i][0]; int yy = y + xy[i][1]; - int center_side = change_sides[i][0]; - int border_side = change_sides[i][1]; + int center_side = trigger_sides[i][0]; + int border_side = trigger_sides[i][1]; int border_element; if (!IN_LEV_FIELD(xx, yy)) @@ -8594,6 +8847,8 @@ void TestIfPlayerTouchesCustomElement(int x, int y) if (IS_PLAYER(x, y)) { + struct PlayerInfo *player = PLAYERINFO(x, y); + if (game.engine_version < VERSION_IDENT(3,0,7,0)) border_element = Feld[xx][yy]; /* may be moving! */ else if (!IS_MOVING(xx, yy) && !IS_BLOCKED(xx, yy)) @@ -8603,25 +8858,27 @@ void TestIfPlayerTouchesCustomElement(int x, int y) else continue; /* center and border element do not touch */ - CheckTriggeredElementSideChange(xx, yy, border_element, border_side, - CE_OTHER_GETS_TOUCHED); - CheckElementSideChange(xx, yy, border_element, border_side, - CE_TOUCHED_BY_PLAYER, -1); + CheckTriggeredElementChangePlayer(xx, yy, border_element, + CE_OTHER_GETS_TOUCHED, + player->index_bit, border_side); + CheckElementChangePlayer(xx, yy, border_element, CE_TOUCHED_BY_PLAYER, + player->index_bit, border_side); } else if (IS_PLAYER(xx, yy)) { + struct PlayerInfo *player = PLAYERINFO(xx, yy); + if (game.engine_version >= VERSION_IDENT(3,0,7,0)) { - struct PlayerInfo *player = PLAYERINFO(xx, yy); - if (player->MovPos != 0 && !(player->MovDir & touch_dir[i])) continue; /* center and border element do not touch */ } - CheckTriggeredElementSideChange(x, y, center_element, center_side, - CE_OTHER_GETS_TOUCHED); - CheckElementSideChange(x, y, center_element, center_side, - CE_TOUCHED_BY_PLAYER, -1); + CheckTriggeredElementChangePlayer(x, y, center_element, + CE_OTHER_GETS_TOUCHED, + player->index_bit, center_side); + CheckElementChangePlayer(x, y, center_element, CE_TOUCHED_BY_PLAYER, + player->index_bit, center_side); break; } @@ -8637,7 +8894,7 @@ void TestIfElementTouchesCustomElement(int x, int y) { +1, 0 }, { 0, +1 } }; - static int change_sides[4][2] = + static int trigger_sides[4][2] = { /* center side border side */ { CH_SIDE_TOP, CH_SIDE_BOTTOM }, /* check top */ @@ -8661,8 +8918,8 @@ void TestIfElementTouchesCustomElement(int x, int y) { int xx = x + xy[i][0]; int yy = y + xy[i][1]; - int center_side = change_sides[i][0]; - int border_side = change_sides[i][1]; + int center_side = trigger_sides[i][0]; + int border_side = trigger_sides[i][1]; int border_element; if (!IN_LEV_FIELD(xx, yy)) @@ -8689,7 +8946,7 @@ void TestIfElementTouchesCustomElement(int x, int y) if (change->can_change && change->events & CH_EVENT_BIT(CE_OTHER_IS_TOUCHING) && - change->sides & border_side && + change->trigger_side & border_side && #if 1 IS_EQUAL_OR_IN_GROUP(border_element, change->trigger_element) #else @@ -8716,7 +8973,7 @@ void TestIfElementTouchesCustomElement(int x, int y) if (change->can_change && change->events & CH_EVENT_BIT(CE_OTHER_IS_TOUCHING) && - change->sides & center_side && + change->trigger_side & center_side && #if 1 IS_EQUAL_OR_IN_GROUP(center_element, change->trigger_element) #else @@ -8724,8 +8981,8 @@ void TestIfElementTouchesCustomElement(int x, int y) #endif ) { - CheckElementSideChange(xx, yy, border_element, CH_SIDE_ANY, - CE_OTHER_IS_TOUCHING, j); + CheckElementChangePage(xx, yy, border_element, CE_OTHER_IS_TOUCHING, + j); break; } } @@ -8733,8 +8990,8 @@ void TestIfElementTouchesCustomElement(int x, int y) } if (change_center_element) - CheckElementSideChange(x, y, center_element, CH_SIDE_ANY, - CE_OTHER_IS_TOUCHING, center_element_change_page); + CheckElementChangePage(x, y, center_element, CE_OTHER_IS_TOUCHING, + center_element_change_page); } void TestIfElementHitsCustomElement(int x, int y, int direction) @@ -8759,8 +9016,8 @@ void TestIfElementHitsCustomElement(int x, int y, int direction) return; #endif - CheckElementSideChange(x, y, hitting_element, - direction, CE_HITTING_SOMETHING, -1); + CheckElementChangeSide(x, y, hitting_element, CE_HITTING_SOMETHING, + direction); if (IN_LEV_FIELD(hitx, hity)) { @@ -8780,8 +9037,8 @@ void TestIfElementHitsCustomElement(int x, int y, int direction) { int i; - CheckElementSideChange(hitx, hity, touched_element, - opposite_direction, CE_HIT_BY_SOMETHING, -1); + CheckElementChangeSide(hitx, hity, touched_element, CE_HIT_BY_SOMETHING, + opposite_direction); if (IS_CUSTOM_ELEMENT(hitting_element) && HAS_ANY_CHANGE_EVENT(hitting_element, CE_OTHER_IS_HITTING)) @@ -8793,7 +9050,7 @@ void TestIfElementHitsCustomElement(int x, int y, int direction) if (change->can_change && change->events & CH_EVENT_BIT(CE_OTHER_IS_HITTING) && - change->sides & touched_side && + change->trigger_side & touched_side && #if 1 IS_EQUAL_OR_IN_GROUP(touched_element, change->trigger_element) @@ -8802,8 +9059,8 @@ void TestIfElementHitsCustomElement(int x, int y, int direction) #endif ) { - CheckElementSideChange(x, y, hitting_element, - CH_SIDE_ANY, CE_OTHER_IS_HITTING, i); + CheckElementChangePage(x, y, hitting_element, CE_OTHER_IS_HITTING, + i); break; } } @@ -8819,7 +9076,7 @@ void TestIfElementHitsCustomElement(int x, int y, int direction) if (change->can_change && change->events & CH_EVENT_BIT(CE_OTHER_GETS_HIT) && - change->sides & hitting_side && + change->trigger_side & hitting_side && #if 1 IS_EQUAL_OR_IN_GROUP(hitting_element, change->trigger_element) #else @@ -8827,8 +9084,8 @@ void TestIfElementHitsCustomElement(int x, int y, int direction) #endif ) { - CheckElementSideChange(hitx, hity, touched_element, - CH_SIDE_ANY, CE_OTHER_GETS_HIT, i); + CheckElementChangePage(hitx, hity, touched_element, + CE_OTHER_GETS_HIT, i); break; } } @@ -8837,6 +9094,108 @@ void TestIfElementHitsCustomElement(int x, int y, int direction) } } +#if 0 +void TestIfElementSmashesCustomElement(int x, int y, int direction) +{ + int dx = (direction == MV_LEFT ? -1 : direction == MV_RIGHT ? +1 : 0); + int dy = (direction == MV_UP ? -1 : direction == MV_DOWN ? +1 : 0); + int hitx = x + dx, hity = y + dy; + int hitting_element = Feld[x][y]; +#if 0 + boolean object_hit = (IN_LEV_FIELD(hitx, hity) && + !IS_FREE(hitx, hity) && + (!IS_MOVING(hitx, hity) || + MovDir[hitx][hity] != direction || + ABS(MovPos[hitx][hity]) <= TILEY / 2)); +#endif + + if (IN_LEV_FIELD(hitx, hity) && IS_FREE(hitx, hity)) + return; + +#if 0 + if (IN_LEV_FIELD(hitx, hity) && !object_hit) + return; +#endif + + CheckElementChangeSide(x, y, hitting_element, EP_CAN_SMASH_EVERYTHING, + direction); + + if (IN_LEV_FIELD(hitx, hity)) + { + int opposite_direction = MV_DIR_OPPOSITE(direction); + int hitting_side = direction; + int touched_side = opposite_direction; + int touched_element = MovingOrBlocked2Element(hitx, hity); +#if 1 + boolean object_hit = (!IS_MOVING(hitx, hity) || + MovDir[hitx][hity] != direction || + ABS(MovPos[hitx][hity]) <= TILEY / 2); + + object_hit = TRUE; +#endif + + if (object_hit) + { + int i; + + CheckElementChangeSide(hitx, hity, touched_element, + CE_SMASHED_BY_SOMETHING, opposite_direction); + + if (IS_CUSTOM_ELEMENT(hitting_element) && + HAS_ANY_CHANGE_EVENT(hitting_element, CE_OTHER_IS_SMASHING)) + { + for (i = 0; i < element_info[hitting_element].num_change_pages; i++) + { + struct ElementChangeInfo *change = + &element_info[hitting_element].change_page[i]; + + if (change->can_change && + change->events & CH_EVENT_BIT(CE_OTHER_IS_SMASHING) && + change->trigger_side & touched_side && + +#if 1 + IS_EQUAL_OR_IN_GROUP(touched_element, change->trigger_element) +#else + change->trigger_element == touched_element +#endif + ) + { + CheckElementChangePage(x, y, hitting_element, CE_OTHER_IS_SMASHING, + i); + break; + } + } + } + + if (IS_CUSTOM_ELEMENT(touched_element) && + HAS_ANY_CHANGE_EVENT(touched_element, CE_OTHER_GETS_SMASHED)) + { + for (i = 0; i < element_info[touched_element].num_change_pages; i++) + { + struct ElementChangeInfo *change = + &element_info[touched_element].change_page[i]; + + if (change->can_change && + change->events & CH_EVENT_BIT(CE_OTHER_GETS_SMASHED) && + change->trigger_side & hitting_side && +#if 1 + IS_EQUAL_OR_IN_GROUP(hitting_element, change->trigger_element) +#else + change->trigger_element == hitting_element +#endif + ) + { + CheckElementChangePage(hitx, hity, touched_element, + CE_OTHER_GETS_SMASHED, i); + break; + } + } + } + } + } +} +#endif + void TestIfGoodThingHitsBadThing(int good_x, int good_y, int good_move_dir) { int i, kill_x = -1, kill_y = -1; @@ -9168,7 +9527,7 @@ int DigField(struct PlayerInfo *player, int oldx, int oldy, int x, int y, int real_dx, int real_dy, int mode) { - static int change_sides[4] = + static int trigger_sides[4] = { CH_SIDE_RIGHT, /* moving left */ CH_SIDE_LEFT, /* moving right */ @@ -9186,7 +9545,7 @@ int DigField(struct PlayerInfo *player, dy == -1 ? MV_UP : dy == +1 ? MV_DOWN : MV_NO_MOVING); int opposite_direction = MV_DIR_OPPOSITE(move_direction); - int dig_side = change_sides[MV_DIR_BIT(move_direction)]; + int dig_side = trigger_sides[MV_DIR_BIT(move_direction)]; int old_element = Feld[jx][jy]; int element; @@ -9328,6 +9687,10 @@ int DigField(struct PlayerInfo *player, DOUBLE_PLAYER_SPEED(player); #endif +#if 0 + printf("::: passing port %d,%d [%d]\n", x, y, FrameCounter); +#endif + PlayLevelSound(x, y, SND_CLASS_SP_PORT_PASSING); break; @@ -9475,7 +9838,8 @@ int DigField(struct PlayerInfo *player, PlayLevelSoundElementAction(x, y, element, ACTION_DIGGING); - CheckTriggeredElementChange(x, y, element, CE_OTHER_GETS_DIGGED); + CheckTriggeredElementChangePlayer(x, y, element, CE_OTHER_GETS_DIGGED, + player->index_bit, CH_SIDE_ANY); #if 1 if (mode == DF_SNAP) @@ -9551,9 +9915,12 @@ int DigField(struct PlayerInfo *player, { int i; - for (i = 0; i < element_info[element].collect_count; i++) - if (player->inventory_size < MAX_INVENTORY_SIZE) - player->inventory_element[player->inventory_size++] = element; + if (element_info[element].collect_count == 0) + player->inventory_infinite_element = element; + else + for (i = 0; i < element_info[element].collect_count; i++) + if (player->inventory_size < MAX_INVENTORY_SIZE) + player->inventory_element[player->inventory_size++] = element; DrawGameValue_Dynamite(local_player->inventory_size); } @@ -9570,7 +9937,9 @@ int DigField(struct PlayerInfo *player, RaiseScoreElement(element); PlayLevelSoundElementAction(x, y, element, ACTION_COLLECTING); - CheckTriggeredElementChange(x, y, element, CE_OTHER_GETS_COLLECTED); + CheckTriggeredElementChangePlayer(x, y, element, + CE_OTHER_GETS_COLLECTED, + player->index_bit, CH_SIDE_ANY); #if 1 if (mode == DF_SNAP) @@ -9726,10 +10095,10 @@ int DigField(struct PlayerInfo *player, else player->push_delay_value = -1; /* get new value later */ - CheckTriggeredElementSideChange(x, y, element, dig_side, - CE_OTHER_GETS_PUSHED); - CheckElementSideChange(x, y, element, dig_side, - CE_PUSHED_BY_PLAYER, -1); + CheckTriggeredElementChangePlayer(x, y, element, CE_OTHER_GETS_PUSHED, + player->index_bit, dig_side); + CheckElementChangePlayer(x, y, element, CE_PUSHED_BY_PLAYER, + player->index_bit, dig_side); break; } @@ -9833,15 +10202,17 @@ int DigField(struct PlayerInfo *player, player->switch_x = x; player->switch_y = y; - CheckTriggeredElementSideChange(x, y, element, dig_side, - CE_OTHER_IS_SWITCHING); - CheckElementSideChange(x, y, element, dig_side, CE_SWITCHED, -1); + CheckTriggeredElementChangePlayer(x, y, element, + CE_OTHER_IS_SWITCHING, + player->index_bit, dig_side); + CheckElementChangePlayer(x, y, element, CE_SWITCHED, + player->index_bit, dig_side); } - CheckTriggeredElementSideChange(x, y, element, dig_side, - CE_OTHER_GETS_PRESSED); - CheckElementSideChange(x, y, element, dig_side, - CE_PRESSED_BY_PLAYER, -1); + CheckTriggeredElementChangePlayer(x, y, element, CE_OTHER_GETS_PRESSED, + player->index_bit, dig_side); + CheckElementChangePlayer(x, y, element, CE_PRESSED_BY_PLAYER, + player->index_bit, dig_side); } return MF_NO_ACTION; @@ -9864,8 +10235,13 @@ boolean SnapField(struct PlayerInfo *player, int dx, int dy) dy == -1 ? MV_UP : dy == +1 ? MV_DOWN : MV_NO_MOVING); +#if 0 + if (player->MovPos) + return FALSE; +#else if (player->MovPos && game.engine_version >= VERSION_IDENT(2,2,0,0)) return FALSE; +#endif if (!player->active || !IN_LEV_FIELD(x, y)) return FALSE; @@ -9930,25 +10306,43 @@ boolean DropElement(struct PlayerInfo *player) { int jx = player->jx, jy = player->jy; int old_element = Feld[jx][jy]; - int new_element; + int new_element = (player->inventory_size > 0 ? + player->inventory_element[player->inventory_size - 1] : + player->inventory_infinite_element != EL_UNDEFINED ? + player->inventory_infinite_element : + player->dynabombs_left > 0 ? + EL_DYNABOMB_PLAYER_1_ACTIVE + player->index_nr : + EL_UNDEFINED); /* check if player is active, not moving and ready to drop */ if (!player->active || player->MovPos || player->drop_delay > 0) return FALSE; /* check if player has anything that can be dropped */ - if (player->inventory_size == 0 && player->dynabombs_left == 0) +#if 1 + if (new_element == EL_UNDEFINED) return FALSE; +#else + if (player->inventory_size == 0 && + player->inventory_infinite_element == EL_UNDEFINED && + player->dynabombs_left == 0) + return FALSE; +#endif /* check if anything can be dropped at the current position */ if (IS_ACTIVE_BOMB(old_element) || old_element == EL_EXPLOSION) return FALSE; /* collected custom elements can only be dropped on empty fields */ +#if 1 + if (IS_CUSTOM_ELEMENT(new_element) && old_element != EL_EMPTY) + return FALSE; +#else if (player->inventory_size > 0 && IS_CUSTOM_ELEMENT(player->inventory_element[player->inventory_size - 1]) && old_element != EL_EMPTY) return FALSE; +#endif if (old_element != EL_EMPTY) Back[jx][jy] = old_element; /* store old element on this field */ @@ -9956,19 +10350,26 @@ boolean DropElement(struct PlayerInfo *player) ResetGfxAnimation(jx, jy); ResetRandomAnimationValue(jx, jy); - if (player->inventory_size > 0) + if (player->inventory_size > 0 || + player->inventory_infinite_element != EL_UNDEFINED) { - player->inventory_size--; - new_element = player->inventory_element[player->inventory_size]; + if (player->inventory_size > 0) + { + player->inventory_size--; - if (new_element == EL_DYNAMITE) - new_element = EL_DYNAMITE_ACTIVE; - else if (new_element == EL_SP_DISK_RED) - new_element = EL_SP_DISK_RED_ACTIVE; +#if 0 + new_element = player->inventory_element[player->inventory_size]; +#endif - Feld[jx][jy] = new_element; + DrawGameValue_Dynamite(local_player->inventory_size); - DrawGameValue_Dynamite(local_player->inventory_size); + if (new_element == EL_DYNAMITE) + new_element = EL_DYNAMITE_ACTIVE; + else if (new_element == EL_SP_DISK_RED) + new_element = EL_SP_DISK_RED_ACTIVE; + } + + Feld[jx][jy] = new_element; if (IN_SCR_FIELD(SCREENX(jx), SCREENY(jy))) DrawGraphicThruMask(SCREENX(jx), SCREENY(jy), el2img(Feld[jx][jy]), 0); @@ -9980,15 +10381,21 @@ boolean DropElement(struct PlayerInfo *player) Changed[jx][jy] = 0; /* allow another change */ #endif - CheckTriggeredElementChange(jx, jy, new_element, CE_OTHER_GETS_DROPPED); - CheckElementChange(jx, jy, new_element, CE_DROPPED_BY_PLAYER); + CheckTriggeredElementChangePlayer(jx, jy, new_element, + CE_OTHER_GETS_DROPPED, + player->index_bit, CH_SIDE_ANY); + CheckElementChangePlayer(jx, jy, new_element, CE_DROPPED_BY_PLAYER, + player->index_bit, CH_SIDE_ANY); TestIfElementTouchesCustomElement(jx, jy); } else /* player is dropping a dyna bomb */ { player->dynabombs_left--; + +#if 0 new_element = EL_DYNABOMB_PLAYER_1_ACTIVE + player->index_nr; +#endif Feld[jx][jy] = new_element; @@ -10046,8 +10453,8 @@ boolean DropElement(struct PlayerInfo *player) #if 1 TestIfElementHitsCustomElement(jx, jy, direction); #else - CheckElementSideChange(jx, jy, new_element, - direction, CE_HITTING_SOMETHING, -1); + CheckElementChangeSide(jx, jy, new_element, CE_HITTING_SOMETHING, + direction); #endif } @@ -10281,7 +10688,25 @@ void RequestQuitGame(boolean ask_if_really_quit) } else { + +#if 1 + if (tape.playing && tape.index_search) + { + SetDrawDeactivationMask(REDRAW_NONE); + audio.sound_deactivated = FALSE; + } +#endif + OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK); + +#if 1 + if (tape.playing && tape.index_search) + { + SetDrawDeactivationMask(REDRAW_FIELD); + audio.sound_deactivated = TRUE; + } +#endif + } }