X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=e3007408dd8b4f65da4ffddb77f446689f338357;hb=c93f939100438a9047653b2c2c6b86f034e1bb01;hp=dd8af0d3679aa16450f8a65fac907bd7aadab7ee;hpb=d31107293214cf22c06b58465923e29f3a64e73b;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index dd8af0d3..e3007408 100644 --- a/src/game.c +++ b/src/game.c @@ -54,6 +54,12 @@ #define USE_HITTING_SOMETHING_BUGFIX (TRUE * USE_NEW_STUFF * 1) #define USE_HIT_BY_SOMETHING_BUGFIX (TRUE * USE_NEW_STUFF * 1) +#define USE_DROP_BUGFIX (TRUE * USE_NEW_STUFF * 1) + +#define USE_CHANGE_TO_TRIGGERED (TRUE * USE_NEW_STUFF * 1) + +#define USE_BACK_WALKABLE_BUGFIX (TRUE * USE_NEW_STUFF * 1) + /* for DigField() */ #define DF_NO_PUSH 0 @@ -1775,6 +1781,11 @@ void InitGame() player->switch_x = -1; player->switch_y = -1; +#if USE_DROP_BUGFIX + player->drop_x = -1; + player->drop_y = -1; +#endif + player->show_envelope = 0; player->move_delay = game.initial_move_delay; @@ -4395,9 +4406,9 @@ static void ActivateTimegateSwitch(int x, int y) void Impact(int x, int y) { - boolean lastline = (y == lev_fieldy-1); + boolean last_line = (y == lev_fieldy - 1); boolean object_hit = FALSE; - boolean impact = (lastline || object_hit); + boolean impact = (last_line || object_hit); int element = Feld[x][y]; int smashed = EL_STEELWALL; @@ -4405,7 +4416,7 @@ void Impact(int x, int y) printf("IMPACT!\n"); #endif - if (!lastline) /* check if element below was hit */ + if (!last_line) /* check if element below was hit */ { if (Feld[x][y + 1] == EL_PLAYER_IS_LEAVING) return; @@ -4426,10 +4437,10 @@ void Impact(int x, int y) if (object_hit) smashed = MovingOrBlocked2Element(x, y + 1); - impact = (lastline || object_hit); + impact = (last_line || object_hit); } - if (!lastline && smashed == EL_ACID) /* element falls into acid */ + if (!last_line && smashed == EL_ACID) /* element falls into acid */ { SplashAcid(x, y + 1); return; @@ -4628,7 +4639,7 @@ void Impact(int x, int y) } /* play sound of magic wall / mill */ - if (!lastline && + if (!last_line && (Feld[x][y + 1] == EL_MAGIC_WALL_ACTIVE || Feld[x][y + 1] == EL_BD_MAGIC_WALL_ACTIVE)) { @@ -4641,7 +4652,7 @@ void Impact(int x, int y) } /* play sound of object that hits the ground */ - if (lastline || object_hit) + if (last_line || object_hit) PlayLevelSoundElementAction(x, y, element, ACTION_IMPACT); } @@ -6212,7 +6223,16 @@ void StartMoving(int x, int y) #if 1 Store[newx][newy] = EL_EMPTY; if (IS_EQUAL_OR_IN_GROUP(new_element, MOVE_ENTER_EL(element))) + { +#if USE_CHANGE_TO_TRIGGERED + int move_leave_element = element_info[element].move_leave_element; + + Store[newx][newy] = (move_leave_element == EL_TRIGGER_ELEMENT ? + new_element : move_leave_element); +#else Store[newx][newy] = element_info[element].move_leave_element; +#endif + } #else Store[newx][newy] = EL_EMPTY; if (IS_EQUAL_OR_IN_GROUP(new_element, MOVE_ENTER_EL(element)) || @@ -6443,6 +6463,10 @@ void StartMoving(int x, int y) ContinueMoving(x, y); } +void dummy() +{ +} + void ContinueMoving(int x, int y) { int element = Feld[x][y]; @@ -6461,6 +6485,7 @@ void ContinueMoving(int x, int y) #else boolean pushed_by_player = Pushed[x][y]; #endif + boolean last_line = (newy == lev_fieldy - 1); MovPos[x][y] += getElementMoveStepsize(x, y); @@ -6622,6 +6647,12 @@ void ContinueMoving(int x, int y) { int move_leave_element = ei->move_leave_element; +#if USE_CHANGE_TO_TRIGGERED + if (ei->move_leave_type == LEAVE_TYPE_LIMITED && + ei->move_leave_element == EL_TRIGGER_ELEMENT) + move_leave_element = stored; +#endif + Feld[x][y] = move_leave_element; #if USE_PREVIOUS_MOVE_DIR @@ -6750,20 +6781,19 @@ void ContinueMoving(int x, int y) #if USE_NEW_MOVE_STYLE #if 0 if (CAN_FALL(element) && direction == MV_DOWN && - (newy == lev_fieldy - 1 || !IS_FREE(x, newy + 1)) && - IS_PLAYER(x, newy + 1)) + !last_line && IS_PLAYER(x, newy + 1)) printf("::: we would now kill the player [%d]\n", FrameCounter); #endif /* give the player one last chance (one more frame) to move away */ if (CAN_FALL(element) && direction == MV_DOWN && - (newy == lev_fieldy - 1 || !IS_FREE(x, newy + 1)) && - ((newy < lev_fieldy - 1 && !IS_PLAYER(x, newy + 1)) || - game.engine_version < VERSION_IDENT(3,1,1,0))) + (last_line || (!IS_FREE(x, newy + 1) && + (!IS_PLAYER(x, newy + 1) || + game.engine_version < VERSION_IDENT(3,1,1,0))))) Impact(x, newy); #else if (CAN_FALL(element) && direction == MV_DOWN && - (newy == lev_fieldy - 1 || !IS_FREE(x, newy + 1))) + (last_line || !IS_FREE(x, newy + 1))) Impact(x, newy); #endif @@ -7829,7 +7859,26 @@ static void ChangeActiveTrap(int x, int y) DrawLevelFieldCrumbledSand(x, y); } -static void ChangeElementNowExt(int x, int y, int target_element) +static void HandleChangeAction(int change_action) +{ + if (change_action == CA_EXIT_PLAYER) + { + printf("::: CA_EXIT_GAME\n"); + + /* !!! local_player <-> 4 players !!! (EXTEND THIS) !!! */ + local_player->LevelSolved = local_player->GameOver = TRUE; + } + else if (change_action == CA_KILL_PLAYER) + { + printf("::: CA_KILL_PLAYER\n"); + + /* !!! local_player <-> 4 players !!! (EXTEND THIS) !!! */ + KillHero(local_player); + } +} + +static void ChangeElementNowExt(struct ElementChangeInfo *change, + int x, int y, int target_element) { int previous_move_direction = MovDir[x][y]; #if 1 @@ -7916,6 +7965,9 @@ static void ChangeElementNowExt(int x, int y, int target_element) TestIfPlayerTouchesCustomElement(x, y); TestIfElementTouchesCustomElement(x, y); #endif + + if (change->use_change_action) + HandleChangeAction(change->change_action); } static boolean ChangeElementNow(int x, int y, int element, int page) @@ -8097,7 +8149,7 @@ static boolean ChangeElementNow(int x, int y, int element, int page) content_element = change->target_content[xx][yy]; target_element = GET_TARGET_ELEMENT(content_element, change); - ChangeElementNowExt(ex, ey, target_element); + ChangeElementNowExt(change, ex, ey, target_element); something_has_changed = TRUE; @@ -8115,7 +8167,7 @@ static boolean ChangeElementNow(int x, int y, int element, int page) { target_element = GET_TARGET_ELEMENT(change->target_element, change); - ChangeElementNowExt(x, y, target_element); + ChangeElementNowExt(change, x, y, target_element); PlayLevelSoundElementAction(x, y, element, ACTION_CHANGING); } @@ -11432,6 +11484,13 @@ int DigField(struct PlayerInfo *player, if (IS_TUBE(Back[jx][jy]) && game.engine_version >= VERSION_IDENT(2,2,0,0)) old_element = Back[jx][jy]; +#if USE_BACK_WALKABLE_BUGFIX + + /* in case of element dropped at player position, check background */ + else if (Back[jx][jy] != EL_EMPTY && + game.engine_version >= VERSION_IDENT(2,2,0,0)) + old_element = Back[jx][jy]; +#endif #endif @@ -12361,6 +12420,15 @@ boolean DropElement(struct PlayerInfo *player) EL_DYNABOMB_PLAYER_1_ACTIVE + player->index_nr : EL_UNDEFINED); +#if USE_DROP_BUGFIX + /* 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 + is dynamite, which can be placed on background for historical reasons) */ + if (PLAYER_DROPPING(player, dropx, dropy) && Feld[dropx][dropy] != EL_EMPTY) + return MF_ACTION; +#endif + if (IS_THROWABLE(drop_element)) { dropx += GET_DX_FROM_DIR(drop_direction); @@ -12557,6 +12625,10 @@ boolean DropElement(struct PlayerInfo *player) player->is_dropping = TRUE; +#if USE_DROP_BUGFIX + player->drop_x = dropx; + player->drop_y = dropy; +#endif return TRUE; }