X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=fa9d44a4ccb41e92bd5960810aa1771548d3600a;hb=274935f49f49068998ad7b4ed9d93892aedfc6aa;hp=461518830eff29fd78da568bfbbbabecf7fc90f3;hpb=b17705c5e8242e7769094e538b52c52c3c1687d0;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index 46151883..fa9d44a4 100644 --- a/src/game.c +++ b/src/game.c @@ -427,7 +427,7 @@ static unsigned long trigger_events[MAX_NUM_ELEMENTS]; void GetPlayerConfig() { if (!audio.sound_available) - setup.sound = FALSE; + setup.sound_simple = FALSE; if (!audio.loops_available) setup.sound_loops = FALSE; @@ -438,7 +438,7 @@ void GetPlayerConfig() if (!video.fullscreen_available) setup.fullscreen = FALSE; - setup.sound_simple = setup.sound; + setup.sound = (setup.sound_simple || setup.sound_loops || setup.sound_music); SetAudioMode(setup.sound); InitJoysticks(); @@ -773,30 +773,20 @@ static void InitGameEngine() /* ---------- initialize changing elements ------------------------------- */ /* initialize changing elements information */ - for (i=0; itarget_element = EL_EMPTY_SPACE; + element_info[i].change->delay_fixed = 0; + element_info[i].change->delay_random = 0; + element_info[i].change->delay_frames = 1; } changing_element[i] = FALSE; -#else - changing_element[i].base_element = EL_UNDEFINED; - changing_element[i].next_element = EL_UNDEFINED; - changing_element[i].change_delay = -1; - changing_element[i].pre_change_function = NULL; - changing_element[i].change_function = NULL; - changing_element[i].post_change_function = NULL; -#endif } /* add changing elements from pre-defined list */ @@ -804,46 +794,28 @@ static void InitGameEngine() { int element = changing_element_list[i].element; struct ChangingElementInfo *ce = &changing_element_list[i]; - struct ElementChangeInfo *change = &element_info[element].change; + struct ElementChangeInfo *change = element_info[element].change; -#if 1 change->target_element = ce->target_element; change->delay_fixed = ce->change_delay; + change->pre_change_function = ce->pre_change_function; change->change_function = ce->change_function; change->post_change_function = ce->post_change_function; changing_element[element] = TRUE; -#else - changing_element[element].base_element = ce->base_element; - changing_element[element].next_element = ce->next_element; - changing_element[element].change_delay = ce->change_delay; - changing_element[element].pre_change_function = ce->pre_change_function; - changing_element[element].change_function = ce->change_function; - changing_element[element].post_change_function = ce->post_change_function; -#endif } /* add changing elements from custom element configuration */ for (i=0; i < NUM_CUSTOM_ELEMENTS; i++) { int element = EL_CUSTOM_START + i; -#if 0 - struct ElementChangeInfo *change = &element_info[element].change; -#endif /* only add custom elements that change after fixed/random frame delay */ if (!CAN_CHANGE(element) || !HAS_CHANGE_EVENT(element, CE_DELAY)) continue; -#if 1 changing_element[element] = TRUE; -#else - changing_element[element].base_element = element; - changing_element[element].next_element = change->target_element; - changing_element[element].change_delay = (change->delay_fixed * - change->delay_frames); -#endif } /* ---------- initialize trigger events ---------------------------------- */ @@ -855,8 +827,8 @@ static void InitGameEngine() /* add trigger events from element change event properties */ for (i=0; itrigger_element] |= + element_info[i].change->events; /* ---------- initialize push delay -------------------------------------- */ @@ -1222,47 +1194,60 @@ void InitGame() { int start_x = 0, start_y = 0; int found_rating = 0; + int found_element = EL_UNDEFINED; - 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]; + int content; + int xx, yy; + boolean is_player; + + if (!IS_CUSTOM_ELEMENT(element)) + continue; + + if (CAN_CHANGE(element)) { - int element = Feld[x][y]; + content = element_info[element].change->target_element; + is_player = ELEM_IS_PLAYER(content); - if (IS_CUSTOM_ELEMENT(element)) + if (is_player && (found_rating < 3 || element < found_element)) { - int xx, yy; + start_x = x; + start_y = y; - for(yy=0; yy < 3; yy++) - { - for(xx=0; xx < 3; xx++) - { - int content; - boolean is_player; + found_rating = 3; + found_element = element; + } + } - content = element_info[element].content[xx][yy]; - is_player = (ELEM_IS_PLAYER(content) || content == EL_SP_MURPHY); + for(yy=0; yy < 3; yy++) for(xx=0; xx < 3; xx++) + { + content = element_info[element].content[xx][yy]; + is_player = ELEM_IS_PLAYER(content); - if (is_player && found_rating < 2) - { - start_x = x + xx - 1; - start_y = y + yy - 1; + if (is_player && (found_rating < 2 || element < found_element)) + { + start_x = x + xx - 1; + start_y = y + yy - 1; - found_rating = 2; - } + found_rating = 2; + found_element = element; + } - content = element_info[element].change.content[xx][yy]; - is_player = (ELEM_IS_PLAYER(content) || content == EL_SP_MURPHY); + if (!CAN_CHANGE(element)) + continue; - if (is_player && found_rating < 1) - { - start_x = x + xx - 1; - start_y = y + yy - 1; + content = element_info[element].change->content[xx][yy]; + is_player = ELEM_IS_PLAYER(content); - found_rating = 1; - } - } - } + if (is_player && (found_rating < 1 || element < found_element)) + { + start_x = x + xx - 1; + start_y = y + yy - 1; + + found_rating = 1; + found_element = element; } } } @@ -1960,22 +1945,50 @@ void RelocatePlayer(int x, int y, int element) } RemoveField(player->jx, player->jy); + DrawLevelField(player->jx, player->jy); } InitPlayerField(x, y, element, TRUE); if (player == local_player) { - scroll_x = (local_player->jx < SBX_Left + MIDPOSX ? SBX_Left : - local_player->jx > SBX_Right + MIDPOSX ? SBX_Right : - local_player->jx - MIDPOSX); + int scroll_xx = -999, scroll_yy = -999; - scroll_y = (local_player->jy < SBY_Upper + MIDPOSY ? SBY_Upper : - local_player->jy > SBY_Lower + MIDPOSY ? SBY_Lower : - local_player->jy - MIDPOSY); - } + while (scroll_xx != scroll_x || scroll_yy != scroll_y) + { + int dx = 0, dy = 0; + int fx = FX, fy = FY; - DrawLevel(); + scroll_xx = (local_player->jx < SBX_Left + MIDPOSX ? SBX_Left : + local_player->jx > SBX_Right + MIDPOSX ? SBX_Right : + local_player->jx - MIDPOSX); + + scroll_yy = (local_player->jy < SBY_Upper + MIDPOSY ? SBY_Upper : + local_player->jy > SBY_Lower + MIDPOSY ? SBY_Lower : + local_player->jy - MIDPOSY); + + dx = (scroll_xx < scroll_x ? +1 : scroll_xx > scroll_x ? -1 : 0); + dy = (scroll_yy < scroll_y ? +1 : scroll_yy > scroll_y ? -1 : 0); + + scroll_x -= dx; + scroll_y -= dy; + + fx += dx * TILEX / 2; + fy += dy * TILEY / 2; + + ScrollLevel(dx, dy); + DrawAllPlayers(); + + /* scroll in to steps of half tile size to make things smoother */ + BlitBitmap(drawto_field, window, fx, fy, SXSIZE, SYSIZE, SX, SY); + FlushDisplay(); + Delay(GAME_FRAME_DELAY); + + /* scroll second step to align at full tile size */ + BackToFront(); + Delay(GAME_FRAME_DELAY); + } + } } void Explode(int ex, int ey, int phase, int mode) @@ -3579,7 +3592,8 @@ void StartMoving(int x, int y) if (CAN_FALL(element) && y < lev_fieldy - 1) { - if ((x>0 && IS_PLAYER(x-1, y)) || (x 0 && IS_PLAYER(x - 1, y)) || + (x < lev_fieldx-1 && IS_PLAYER(x + 1, y))) if (JustBeingPushed(x, y)) return; @@ -3980,7 +3994,8 @@ void StartMoving(int x, int y) Moving2Blocked(x, y, &newx, &newy); /* get next screen position */ - if (DONT_COLLIDE_WITH(element) && IS_PLAYER(newx, newy) && + if (DONT_COLLIDE_WITH(element) && + IN_LEV_FIELD(newx, newy) && IS_PLAYER(newx, newy) && !PLAYER_PROTECTED(newx, newy)) { #if 1 @@ -5269,13 +5284,14 @@ static void ChangeActiveTrap(int x, int y) static void ChangeElementNowExt(int x, int y, int target_element) { -#if 0 /* !!! let the player exacpe from a suddenly unaccessible element */ - if (IS_PLAYER(x, y) && !IS_ACCESSIBLE(target_element)) + /* check if element under player changes from accessible to unaccessible + (needed for special case of dropping element which then changes) */ + if (IS_PLAYER(x, y) && + IS_ACCESSIBLE(Feld[x][y]) && !IS_ACCESSIBLE(target_element)) { Bang(x, y); return; } -#endif RemoveField(x, y); Feld[x][y] = target_element; @@ -5295,18 +5311,30 @@ static void ChangeElementNowExt(int x, int y, int target_element) TestIfBadThingTouchesHero(x, y); TestIfPlayerTouchesCustomElement(x, y); TestIfElementTouchesCustomElement(x, y); + + if (ELEM_IS_PLAYER(target_element)) + RelocatePlayer(x, y, target_element); } static void ChangeElementNow(int x, int y, int element) { - struct ElementChangeInfo *change = &element_info[element].change; + struct ElementChangeInfo *change = element_info[element].change; +#if 0 + if (element >= EL_CUSTOM_START + 17 && element <= EL_CUSTOM_START + 39) + printf("::: changing... [%d]\n", FrameCounter); +#endif + +#if 0 /* prevent CheckTriggeredElementChange() from looping */ Changing[x][y] = TRUE; +#endif CheckTriggeredElementChange(x, y, Feld[x][y], CE_OTHER_IS_CHANGING); +#if 0 Changing[x][y] = FALSE; +#endif if (change->explode) { @@ -5411,7 +5439,7 @@ static void ChangeElement(int x, int y) #else int element = Feld[x][y]; #endif - struct ElementChangeInfo *change = &element_info[element].change; + struct ElementChangeInfo *change = element_info[element].change; if (ChangeDelay[x][y] == 0) /* initialize element change */ { @@ -5423,8 +5451,8 @@ static void ChangeElement(int x, int y) if (IS_CUSTOM_ELEMENT(element) && HAS_CHANGE_EVENT(element, CE_DELAY)) { - int max_random_delay = element_info[element].change.delay_random; - int delay_frames = element_info[element].change.delay_frames; + int max_random_delay = element_info[element].change->delay_random; + int delay_frames = element_info[element].change->delay_frames; ChangeDelay[x][y] += RND(max_random_delay * delay_frames); } @@ -5481,7 +5509,7 @@ static void ChangeElement(int x, int y) if (next_element != EL_UNDEFINED) ChangeElementNow(x, y, next_element); else - ChangeElementNow(x, y, element_info[element].change.target_element); + ChangeElementNow(x, y, element_info[element].change->target_element); if (changing_element[element].post_change_function) changing_element[element].post_change_function(x, y); @@ -5497,10 +5525,14 @@ static boolean CheckTriggeredElementChange(int lx, int ly, int trigger_element, if (!(trigger_events[trigger_element] & CH_EVENT_BIT(trigger_event))) return FALSE; + /* prevent this function from running into a loop */ + if (trigger_event == CE_OTHER_IS_CHANGING) + Changing[lx][ly] = TRUE; + for (i=0; itrigger_element != trigger_element) continue; for (y=0; yjx != jx || player->jy != jy) + return MF_NO_ACTION; + StorePlayer[jx][jy] = 0; player->last_jx = jx; player->last_jy = jy; @@ -6466,6 +6508,9 @@ boolean MoveFigure(struct PlayerInfo *player, int dx, int dy) player->last_move_dir = player->MovDir; player->is_moving = TRUE; +#if 1 + player->snapped = FALSE; +#endif } else { @@ -6542,6 +6587,7 @@ void ScrollFigure(struct PlayerInfo *player, int mode) if (Feld[jx][jy] == EL_EXIT_OPEN || Feld[jx][jy] == EL_SP_EXIT_OPEN) { + DrawPlayer(player); /* needed here only to cleanup last field */ RemoveHero(player); if (local_player->friends_still_needed == 0 || @@ -6657,12 +6703,12 @@ void TestIfElementTouchesCustomElement(int x, int y) /* check for change of center element (but change it only once) */ if (IS_CUSTOM_ELEMENT(center_element) && - border_element == element_info[center_element].change.trigger_element) + border_element == element_info[center_element].change->trigger_element) change_center_element = TRUE; /* check for change of border element */ if (IS_CUSTOM_ELEMENT(border_element) && - center_element == element_info[border_element].change.trigger_element) + center_element == element_info[border_element].change->trigger_element) CheckElementChange(xx, yy, border_element, CE_OTHER_IS_TOUCHING); } @@ -7584,8 +7630,15 @@ boolean SnapField(struct PlayerInfo *player, int dx, int dy) { player->is_digging = FALSE; player->is_collecting = FALSE; +#if 1 + player->is_moving = FALSE; +#endif } +#if 0 + printf("::: trying to snap...\n"); +#endif + return FALSE; } @@ -7594,12 +7647,25 @@ boolean SnapField(struct PlayerInfo *player, int dx, int dy) player->MovDir = snap_direction; +#if 1 + player->is_digging = FALSE; + player->is_collecting = FALSE; +#if 1 + player->is_moving = FALSE; +#endif +#endif + if (DigField(player, x, y, 0, 0, DF_SNAP) == MF_NO_ACTION) return FALSE; player->snapped = TRUE; +#if 1 player->is_digging = FALSE; player->is_collecting = FALSE; +#if 1 + player->is_moving = FALSE; +#endif +#endif DrawLevelField(x, y); BackToFront();