X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=2062caa865f2ea33868c83e0ee0534bb35d60bc8;hb=3494549d6f5c8d1d5497ec7eb9fa80a7ca6579ee;hp=05325ad7ce0fbce0d4fc53dc836f084596552e29;hpb=d8f48d3767794442340cb624ec866098766d4d92;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index 05325ad7..2062caa8 100644 --- a/src/game.c +++ b/src/game.c @@ -658,10 +658,13 @@ static void InitField(int x, int y, boolean init_game) MovDir[x][y] = 1 << RND(4); break; +#if 0 case EL_SP_EMPTY: Feld[x][y] = EL_EMPTY; break; +#endif +#if 0 case EL_EM_KEY_1_FILE: Feld[x][y] = EL_EM_KEY_1; break; @@ -674,6 +677,7 @@ static void InitField(int x, int y, boolean init_game) case EL_EM_KEY_4_FILE: Feld[x][y] = EL_EM_KEY_4; break; +#endif case EL_CONVEYOR_BELT_1_SWITCH_LEFT: case EL_CONVEYOR_BELT_1_SWITCH_MIDDLE: @@ -802,7 +806,7 @@ static void InitGameEngine() ei->change_events = CE_BITMASK_DEFAULT; for (j=0; j < NUM_CHANGE_EVENTS; j++) { - ei->event_page_num[j] = 0; + ei->event_page_nr[j] = 0; ei->event_page[j] = &ei->change_page[0]; } } @@ -841,7 +845,7 @@ static void InitGameEngine() !(ei->change_events & CH_EVENT_BIT(k))) { ei->change_events |= CH_EVENT_BIT(k); - ei->event_page_num[k] = j; + ei->event_page_nr[k] = j; ei->event_page[k] = &ei->change_page[j]; } } @@ -1024,7 +1028,7 @@ void InitGame() player->is_digging = FALSE; player->is_collecting = FALSE; - player->show_envelope = FALSE; + player->show_envelope = 0; player->move_delay = game.initial_move_delay; player->move_delay_value = game.initial_move_delay_value; @@ -1081,6 +1085,8 @@ void InitGame() game.balloon_dir = MV_NO_MOVING; game.explosions_delayed = TRUE; + game.envelope_active = FALSE; + for (i=0; i<4; i++) { game.belt_dir[i] = MV_NO_MOVING; @@ -2317,10 +2323,10 @@ void Explode(int ex, int ey, int phase, int mode) if (GfxElement[x][y] == EL_UNDEFINED) { - printf("\n\n\n"); + printf("\n\n"); printf("Explode(): x = %d, y = %d: GfxElement == EL_UNDEFINED\n", x, y); printf("Explode(): This should never happen!\n"); - printf("\n\n\n"); + printf("\n\n"); GfxElement[x][y] = EL_EMPTY; } @@ -2373,7 +2379,7 @@ void Explode(int ex, int ey, int phase, int mode) TestIfElementTouchesCustomElement(x, y); - if (CAN_BE_CRUMBLED(element)) + if (GFX_CRUMBLED(element)) DrawLevelFieldCrumbledSandNeighbours(x, y); if (IS_PLAYER(x, y) && !PLAYERINFO(x,y)->present) @@ -2473,7 +2479,11 @@ void Bang(int x, int y) int element = Feld[x][y]; #endif +#if 1 + if (IS_PLAYER(x, y) && !PLAYER_PROTECTED(x, y)) +#else if (IS_PLAYER(x, y)) +#endif { struct PlayerInfo *player = PLAYERINFO(x, y); @@ -3643,6 +3653,13 @@ void TurnRound(int x, int y) MovDir[x][y] = old_move_dir; } } + else if (element_info[element].move_pattern == MV_WHEN_PUSHED) + { + if (!IN_LEV_FIELD_AND_IS_FREE(move_x, move_y)) + MovDir[x][y] = MV_NO_MOVING; + + MovDelay[x][y] = 0; + } } static boolean JustBeingPushed(int x, int y) @@ -3824,6 +3841,15 @@ void StartMoving(int x, int y) #endif } #if 1 + +#if 0 + /* TEST: bug where player gets not killed by falling rock ... */ + else if (CAN_SMASH(element) && + (Feld[x][y + 1] == EL_BLOCKED || + IS_PLAYER(x, y + 1)) && + JustStopped[x][y] && !Pushed[x][y + 1]) + +#else #if 1 else if (game.engine_version < RELEASE_IDENT(2,2,0,7) && CAN_SMASH(element) && Feld[x][y + 1] == EL_BLOCKED && @@ -3832,6 +3858,8 @@ void StartMoving(int x, int y) else if (CAN_SMASH(element) && Feld[x][y + 1] == EL_BLOCKED && JustStopped[x][y]) #endif +#endif + { /* calling "Impact()" here is not only completely unneccessary (because it already gets called from "ContinueMoving()" in @@ -3942,11 +3970,16 @@ void StartMoving(int x, int y) { int newx, newy; +#if 1 + if (IS_PUSHABLE(element) && JustBeingPushed(x, y)) + return; +#else if ((element == EL_SATELLITE || element == EL_BALLOON || element == EL_SPRING) && JustBeingPushed(x, y)) return; +#endif #if 0 #if 0 @@ -4462,6 +4495,12 @@ void ContinueMoving(int x, int y) Stop[newx][newy] = TRUE; /* ignore this element until the next frame */ + /* prevent pushed element from moving on in pushed direction */ + if (pushed && CAN_MOVE(element) && + element_info[element].move_pattern & MV_ANY_DIRECTION && + !(element_info[element].move_pattern & MovDir[newx][newy])) + TurnRound(newx, newy); + if (!pushed) /* special case: moving object pushed by player */ JustStopped[newx][newy] = 3; @@ -4479,7 +4518,7 @@ void ContinueMoving(int x, int y) Impact(x, newy); if (!IN_LEV_FIELD(nextx, nexty) || !IS_FREE(nextx, nexty)) - CheckElementChange(newx, newy, element, CE_COLLISION); + CheckElementSideChange(newx, newy, element, direction, CE_COLLISION, -1); #if 1 TestIfElementTouchesCustomElement(x, y); /* for empty space */ @@ -5409,7 +5448,7 @@ static void ChangeElementNowExt(int x, int y, int target_element) DrawLevelField(x, y); - if (CAN_BE_CRUMBLED(Feld[x][y])) + if (GFX_CRUMBLED(Feld[x][y])) DrawLevelFieldCrumbledSandNeighbours(x, y); TestIfBadThingTouchesHero(x, y); @@ -5516,6 +5555,8 @@ static boolean ChangeElementNow(int x, int y, int element, int page) if (IS_MOVING(ex, ey) || IS_BLOCKED(ex, ey)) RemoveMovingField(ex, ey); + ChangeEvent[ex][ey] = ChangeEvent[x][y]; + ChangeElementNowExt(ex, ey, change->content[xx][yy]); something_has_changed = TRUE; @@ -5545,6 +5586,19 @@ static void ChangeElement(int x, int y, int page) int element = MovingOrBlocked2Element(x, y); struct ElementChangeInfo *change = &element_info[element].change_page[page]; +#if 0 +#ifdef DEBUG + if (!CAN_CHANGE(element)) + { + printf("\n\n"); + printf("ChangeElement(): %d,%d: element = %d ('%s')\n", + x, y, element, element_info[element].token_name); + printf("ChangeElement(): This should never happen!\n"); + printf("\n\n"); + } +#endif +#endif + if (ChangeDelay[x][y] == 0) /* initialize element change */ { ChangeDelay[x][y] = ( change->delay_fixed * change->delay_frames + @@ -5601,10 +5655,9 @@ static boolean CheckTriggeredElementSideChange(int lx, int ly, int element = EL_CUSTOM_START + i; boolean change_element = FALSE; - int page; + int page = 0; - if (!CAN_CHANGE(element) || - !HAS_ANY_CHANGE_EVENT(element, trigger_event)) + if (!CAN_CHANGE(element) || !HAS_ANY_CHANGE_EVENT(element, trigger_event)) continue; for (j=0; j < element_info[element].num_change_pages; j++) @@ -5663,7 +5716,7 @@ static boolean CheckElementSideChange(int x, int y, int element, int side, } if (page < 0) - page = element_info[element].event_page_num[trigger_event]; + page = element_info[element].event_page_nr[trigger_event]; if (!(element_info[element].change_page[page].sides & side)) return FALSE; @@ -5946,7 +5999,7 @@ void GameActions() /* this may take place after moving, so 'element' may have changed */ if (IS_CHANGING(x, y)) { - ChangeElement(x, y, element_info[element].event_page_num[CE_DELAY]); + ChangeElement(x, y, element_info[element].event_page_nr[CE_DELAY]); element = Feld[x][y]; graphic = el_act_dir2img(element, GfxAction[x][y], MovDir[x][y]); } @@ -6284,11 +6337,11 @@ void GameActions() #endif #if 1 - if (local_player->show_envelope && local_player->MovPos == 0) + if (local_player->show_envelope != 0 && local_player->MovPos == 0) { - ShowEnvelope(); + ShowEnvelope(local_player->show_envelope - EL_ENVELOPE_1); - local_player->show_envelope = FALSE; + local_player->show_envelope = 0; } #endif } @@ -6655,6 +6708,10 @@ boolean MoveFigure(struct PlayerInfo *player, int dx, int dy) #if 1 player->snapped = FALSE; #endif + +#if 1 + player->Switching = FALSE; +#endif } else { @@ -6785,6 +6842,14 @@ void TestIfPlayerTouchesCustomElement(int x, int y) { +1, 0 }, { 0, +1 } }; + static int change_sides[4][2] = + { + /* center side border side */ + { CH_SIDE_TOP, CH_SIDE_BOTTOM }, /* check top */ + { CH_SIDE_LEFT, CH_SIDE_RIGHT }, /* check left */ + { CH_SIDE_RIGHT, CH_SIDE_LEFT }, /* check right */ + { CH_SIDE_BOTTOM, CH_SIDE_TOP } /* check bottom */ + }; int i; #if 0 @@ -6798,10 +6863,30 @@ 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]; if (!IN_LEV_FIELD(xx, yy)) continue; +#if 1 + if (IS_PLAYER(x, y)) + { + CheckTriggeredElementSideChange(xx, yy, Feld[xx][yy], border_side, + CE_OTHER_GETS_TOUCHED); + CheckElementSideChange(xx, yy, Feld[xx][yy], border_side, + CE_TOUCHED_BY_PLAYER, -1); + } + else if (IS_PLAYER(xx, yy)) + { + CheckTriggeredElementSideChange(x, y, Feld[x][y], center_side, + CE_OTHER_GETS_TOUCHED); + CheckElementSideChange(x, y, Feld[x][y], center_side, + CE_TOUCHED_BY_PLAYER, -1); + + break; + } +#else if (IS_PLAYER(x, y)) { CheckTriggeredElementChange(xx, yy, Feld[xx][yy], CE_OTHER_GETS_TOUCHED); @@ -6814,6 +6899,7 @@ void TestIfPlayerTouchesCustomElement(int x, int y) break; } +#endif } #if 0 @@ -7247,16 +7333,13 @@ static boolean checkDiagonalPushing(struct PlayerInfo *player, int DigField(struct PlayerInfo *player, int x, int y, int real_dx, int real_dy, int mode) { -#if 0 - static int change_sides[4][2] = + static int change_sides[4] = { - /* 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 */ + CH_SIDE_RIGHT, /* moving left */ + CH_SIDE_LEFT, /* moving right */ + CH_SIDE_BOTTOM, /* moving up */ + CH_SIDE_TOP, /* moving down */ }; -#endif boolean use_spring_bug = (game.engine_version < VERSION_IDENT(2,2,0)); int jx = player->jx, jy = player->jy; int dx = x - jx, dy = y - jy; @@ -7265,10 +7348,7 @@ int DigField(struct PlayerInfo *player, dx == +1 ? MV_RIGHT : dy == -1 ? MV_UP : dy == +1 ? MV_DOWN : MV_NO_MOVING); -#if 0 - int enter_side = change_sides[MV_DIR_BIT(move_direction)][0]; - int leave_side = change_sides[MV_DIR_BIT(move_direction)][1]; -#endif + int dig_side = change_sides[MV_DIR_BIT(move_direction)]; int element; if (player->MovPos == 0) @@ -7581,6 +7661,11 @@ int DigField(struct PlayerInfo *player, if (!IN_LEV_FIELD(nextx, nexty) || !IS_FREE(nextx, nexty)) return MF_NO_ACTION; +#if 1 + if (CAN_MOVE(element)) /* only fixed elements can be passed! */ + return MF_NO_ACTION; +#endif + if (element >= EL_EM_GATE_1 && element <= EL_EM_GATE_4) { if (!player->key[element - EL_EM_GATE_1]) @@ -7610,7 +7695,7 @@ int DigField(struct PlayerInfo *player, GfxElement[x][y] = GFX_ELEMENT(element); #else GfxElement[x][y] = - (CAN_BE_CRUMBLED(element) ? EL_SAND : GFX_ELEMENT(element)); + (GFX_CRUMBLED(element) ? EL_SAND : GFX_ELEMENT(element)); #endif player->is_digging = TRUE; } @@ -7681,12 +7766,12 @@ int DigField(struct PlayerInfo *player, el2edimg(EL_KEY_1 + key_nr)); redraw_mask |= REDRAW_DOOR_1; } - else if (element == EL_ENVELOPE) + else if (IS_ENVELOPE(element)) { #if 1 - player->show_envelope = TRUE; + player->show_envelope = element; #else - ShowEnvelope(); + ShowEnvelope(element - EL_ENVELOPE_1); #endif } else if (IS_DROPPABLE(element)) /* can be collected and dropped */ @@ -7732,9 +7817,15 @@ int DigField(struct PlayerInfo *player, !(element == EL_SPRING && use_spring_bug)) return MF_NO_ACTION; +#if 1 + /* do not push elements already moving away faster than player */ + if (CAN_MOVE(element) && MovDir[x][y] == move_direction && + ABS(getElementMoveStepsize(x, y)) > MOVE_STEPSIZE_NORMAL) + return MF_NO_ACTION; +#else if (element == EL_SPRING && MovDir[x][y] != MV_NO_MOVING) return MF_NO_ACTION; - +#endif if (!player->Pushing && game.engine_version >= RELEASE_IDENT(2,2,0,7)) player->push_delay_value = GET_NEW_PUSH_DELAY(element); @@ -7807,15 +7898,41 @@ int DigField(struct PlayerInfo *player, if (game.engine_version < RELEASE_IDENT(2,2,0,7)) player->push_delay_value = GET_NEW_PUSH_DELAY(element); +#if 1 + CheckTriggeredElementSideChange(x, y, element, dig_side, + CE_OTHER_GETS_PUSHED); + CheckElementSideChange(x, y, element, dig_side, + CE_PUSHED_BY_PLAYER, -1); +#else CheckTriggeredElementChange(x, y, element, CE_OTHER_GETS_PUSHED); CheckElementChange(x, y, element, CE_PUSHED_BY_PLAYER); +#endif break; } else { +#if 1 + +#if 1 + if (!player->Switching) + { + player->Switching = TRUE; + CheckTriggeredElementSideChange(x, y, element, dig_side, + CE_OTHER_GETS_SWITCHED); + CheckElementSideChange(x, y, element, dig_side, + CE_SWITCHED_BY_PLAYER, -1); + } +#endif + + CheckTriggeredElementSideChange(x, y, element, dig_side, + CE_OTHER_GETS_PRESSED); + CheckElementSideChange(x, y, element, dig_side, + CE_PRESSED_BY_PLAYER, -1); +#else CheckTriggeredElementChange(x, y, element, CE_OTHER_GETS_PRESSED); CheckElementChange(x, y, element, CE_PRESSED_BY_PLAYER); +#endif } return MF_NO_ACTION; @@ -7826,24 +7943,6 @@ int DigField(struct PlayerInfo *player, if (Feld[x][y] != element) /* really digged/collected something */ player->is_collecting = !player->is_digging; -#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); - } - - if (IS_CUSTOM_ELEMENT(Feld[x][y])) - { - CheckTriggeredElementSideChange(x, y, Feld[x][y], enter_side, - CE_OTHER_GETS_ENTERED); - CheckElementSideChange(x, y, Feld[x][y], enter_side, - CE_ENTERED_BY_PLAYER, -1); - } -#endif - return MF_MOVING; }