X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=71aab9a62cb17f5557c41e8933796f4acc6bd28b;hb=5e616edfe5f101927d2ff3f7a14d2c65897de3cc;hp=312ac26426fdaebb246735eb1708679c204db785;hpb=c8da2fb958f55086c20c03246e17f7f542326137;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index 312ac264..71aab9a6 100644 --- a/src/game.c +++ b/src/game.c @@ -169,7 +169,9 @@ static void KillHeroUnlessProtected(int, int); static void TestIfPlayerTouchesCustomElement(int, int); static void TestIfElementTouchesCustomElement(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 void PlaySoundLevel(int, int, int); @@ -656,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; @@ -672,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: @@ -800,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]; } } @@ -821,33 +827,6 @@ static void InitGameEngine() ei->change_events |= CH_EVENT_BIT(CE_DELAY); } - /* set summarized change event CE_TOUCHING_ANY_SIDE_OF */ - for (i=0; i < NUM_CUSTOM_ELEMENTS; i++) - { - struct ElementInfo *ei = &element_info[EL_CUSTOM_START + i]; - - for (j=0; j < ei->num_change_pages; j++) - { - if (!ei->change_page[j].can_change) - continue; - - /* check for change event of touching other element on some side */ - if (ei->change_page[j].events & (CH_EVENT_BIT(CE_TOUCHING_ANY_SIDE_OF | - CE_TOUCHING_LEFT_OF | - CE_TOUCHING_RIGHT_OF | - CE_TOUCHING_TOP_OF | - CE_TOUCHING_BOTTOM_OF))) - ei->change_page[j].events |= CH_EVENT_BIT(CE_TOUCHING_SOME_SIDE); - - /* add change event for each side when event exists for any side */ - if (ei->change_page[j].events & CH_EVENT_BIT(CE_TOUCHING_ANY_SIDE_OF)) - ei->change_page[j].events |= (CH_EVENT_BIT(CE_TOUCHING_LEFT_OF) | - CH_EVENT_BIT(CE_TOUCHING_RIGHT_OF) | - CH_EVENT_BIT(CE_TOUCHING_TOP_OF) | - CH_EVENT_BIT(CE_TOUCHING_BOTTOM_OF)); - } - } - #if 1 /* add change events from custom element configuration */ for (i=0; i < NUM_CUSTOM_ELEMENTS; i++) @@ -866,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]; } } @@ -1049,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; @@ -4443,12 +4422,14 @@ void ContinueMoving(int x, int y) /* copy element change control values to new field */ ChangeDelay[newx][newy] = ChangeDelay[x][y]; +#if 1 Changed[newx][newy] = Changed[x][y]; ChangeEvent[newx][newy] = ChangeEvent[x][y]; ChangeDelay[x][y] = 0; Changed[x][y] = CE_BITMASK_DEFAULT; ChangeEvent[x][y] = CE_BITMASK_DEFAULT; +#endif /* copy animation control values to new field */ GfxFrame[newx][newy] = GfxFrame[x][y]; @@ -5570,6 +5551,16 @@ static void ChangeElement(int x, int y, int page) int element = MovingOrBlocked2Element(x, y); struct ElementChangeInfo *change = &element_info[element].change_page[page]; +#ifdef DEBUG + if (!CAN_CHANGE(element)) + { + printf("\n\n\n"); + printf("ChangeElement(): element = %d\n", element); + printf("Explode(): This should never happen!\n"); + printf("\n\n\n"); + } +#endif + if (ChangeDelay[x][y] == 0) /* initialize element change */ { ChangeDelay[x][y] = ( change->delay_fixed * change->delay_frames + @@ -5611,25 +5602,20 @@ static void ChangeElement(int x, int y, int page) } } -static boolean CheckTriggeredElementChange(int lx, int ly, int trigger_element, - int trigger_event) +static boolean CheckTriggeredElementSideChange(int lx, int ly, + int trigger_element, + int trigger_side, + int trigger_event) { int i, j, x, y; if (!(trigger_events[trigger_element] & CH_EVENT_BIT(trigger_event))) return FALSE; -#if 0 - /* prevent this function from running into a loop */ - if (trigger_event == CE_OTHER_IS_CHANGING) - Changed[lx][ly] = TRUE; -#endif - for (i=0; i < NUM_CUSTOM_ELEMENTS; i++) { int element = EL_CUSTOM_START + i; -#if 1 boolean change_element = FALSE; int page; @@ -5639,8 +5625,10 @@ static boolean CheckTriggeredElementChange(int lx, int ly, int trigger_element, for (j=0; j < element_info[element].num_change_pages; j++) { - if (element_info[element].change_page[j].trigger_element == - trigger_element) + struct ElementChangeInfo *change = &element_info[element].change_page[j]; + + if (change->sides & trigger_side && + change->trigger_element == trigger_element) { change_element = TRUE; page = j; @@ -5652,20 +5640,10 @@ static boolean CheckTriggeredElementChange(int lx, int ly, int trigger_element, if (!change_element) continue; -#else - if (!CAN_CHANGE(element) || - !HAS_ANY_CHANGE_EVENT(element, trigger_event) || - element_info[element].change->trigger_element != trigger_element) - continue; -#endif - for (y=0; yshow_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 } @@ -6435,8 +6417,22 @@ static void CheckGravityMovement(struct PlayerInfo *player) boolean MoveFigureOneStep(struct PlayerInfo *player, int dx, int dy, int real_dx, int real_dy) { + static int change_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 = (dx == -1 ? MV_LEFT : + 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 jx = player->jx, jy = player->jy; - int new_jx = jx+dx, new_jy = jy+dy; + int new_jx = jx + dx, new_jy = jy + dy; int element; int can_move; @@ -6488,15 +6484,33 @@ boolean MoveFigureOneStep(struct PlayerInfo *player, StorePlayer[jx][jy] = 0; player->last_jx = jx; player->last_jy = jy; - jx = player->jx = new_jx; - jy = player->jy = new_jy; - StorePlayer[jx][jy] = player->element_nr; + player->jx = new_jx; + player->jy = new_jy; + StorePlayer[new_jx][new_jy] = player->element_nr; player->MovPos = (dx > 0 || dy > 0 ? -1 : 1) * (TILEX - TILEX / player->move_delay_value); ScrollFigure(player, SCROLL_INIT); +#if 1 + 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[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); + } +#endif + return MF_MOVING; } @@ -6835,16 +6849,16 @@ void TestIfElementTouchesCustomElement(int x, int y) { +1, 0 }, { 0, +1 } }; - static int touching_side[4][2] = + static int change_sides[4][2] = { - { CE_TOUCHING_TOP_OF, CE_TOUCHING_BOTTOM_OF }, - { CE_TOUCHING_LEFT_OF, CE_TOUCHING_RIGHT_OF }, - { CE_TOUCHING_RIGHT_OF, CE_TOUCHING_LEFT_OF }, - { CE_TOUCHING_BOTTOM_OF, CE_TOUCHING_TOP_OF } + /* 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 */ }; boolean change_center_element = FALSE; int center_element_change_page = 0; - int center_element_change_event = 0; int center_element = Feld[x][y]; int i, j; @@ -6859,8 +6873,8 @@ void TestIfElementTouchesCustomElement(int x, int y) { int xx = x + xy[i][0]; int yy = y + xy[i][1]; - int change_event_center = touching_side[i][0]; - int change_event_border = touching_side[i][1]; + int center_side = change_sides[i][0]; + int border_side = change_sides[i][1]; int border_element; if (!IN_LEV_FIELD(xx, yy)) @@ -6870,7 +6884,7 @@ void TestIfElementTouchesCustomElement(int x, int y) /* check for change of center element (but change it only once) */ if (IS_CUSTOM_ELEMENT(center_element) && - HAS_ANY_CHANGE_EVENT(center_element, change_event_border) && + HAS_ANY_CHANGE_EVENT(center_element, CE_OTHER_IS_TOUCHING) && !change_center_element) { for (j=0; j < element_info[center_element].num_change_pages; j++) @@ -6878,12 +6892,12 @@ void TestIfElementTouchesCustomElement(int x, int y) struct ElementChangeInfo *change = &element_info[center_element].change_page[j]; - if (change->events & CH_EVENT_BIT(change_event_border) && + if (change->events & CH_EVENT_BIT(CE_OTHER_IS_TOUCHING) && + change->sides & border_side && change->trigger_element == border_element) { change_center_element = TRUE; center_element_change_page = j; - center_element_change_event = change_event_border; break; } @@ -6892,17 +6906,19 @@ void TestIfElementTouchesCustomElement(int x, int y) /* check for change of border element */ if (IS_CUSTOM_ELEMENT(border_element) && - HAS_ANY_CHANGE_EVENT(border_element, change_event_center)) + HAS_ANY_CHANGE_EVENT(border_element, CE_OTHER_IS_TOUCHING)) { for (j=0; j < element_info[border_element].num_change_pages; j++) { struct ElementChangeInfo *change = &element_info[border_element].change_page[j]; - if (change->events & CH_EVENT_BIT(change_event_center) && + if (change->events & CH_EVENT_BIT(CE_OTHER_IS_TOUCHING) && + change->sides & center_side && change->trigger_element == center_element) { - CheckElementChangeExt(xx,yy, border_element, change_event_center, j); + CheckElementSideChange(xx, yy, border_element, CH_SIDE_ANY, + CE_OTHER_IS_TOUCHING, j); break; } } @@ -6910,8 +6926,8 @@ void TestIfElementTouchesCustomElement(int x, int y) } if (change_center_element) - CheckElementChangeExt(x, y, center_element, center_element_change_event, - center_element_change_page); + CheckElementSideChange(x, y, center_element, CH_SIDE_ANY, + CE_OTHER_IS_TOUCHING, center_element_change_page); #if 0 check_changing = FALSE; @@ -7247,6 +7263,16 @@ 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] = + { + /* 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 */ + }; +#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; @@ -7255,6 +7281,10 @@ 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 element; if (player->MovPos == 0) @@ -7667,12 +7697,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 */ @@ -7812,6 +7842,24 @@ 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; }