X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame_bd%2Fbd_caveengine.c;h=3019aeca80dea04636e5379ab4978c992781eb56;hb=a5625f62fe0e6212c4526637f23fa029f32301e8;hp=1fe5b2b017c8dee40e53d71d888736ed05e6f954;hpb=eea88cc5712224a52d4c606795f021be11ef5135;p=rocksndiamonds.git diff --git a/src/game_bd/bd_caveengine.c b/src/game_bd/bd_caveengine.c index 1fe5b2b0..3019aeca 100644 --- a/src/game_bd/bd_caveengine.c +++ b/src/game_bd/bd_caveengine.c @@ -303,6 +303,38 @@ static void play_sound_of_element_pushing(GdCave *cave, GdElement element, int x } } +static inline int getx(const GdCave *cave, const int x, const int y) +{ + return cave->getx(cave, x, y); +} + +static inline int gety(const GdCave *cave, const int x, const int y) +{ + return cave->gety(cave, x, y); +} + +/* perfect (non-lineshifting) GET x/y functions; returns range corrected x/y position */ +static inline int getx_perfect(const GdCave *cave, const int x, const int y) +{ + return (x + cave->w) % cave->w; +} + +static inline int gety_perfect(const GdCave *cave, const int x, const int y) +{ + return (y + cave->h) % cave->h; +} + +/* line shifting GET x/y function; returns range corrected x/y position */ +static inline int getx_shift(const GdCave *cave, int x, int y) +{ + return (x + cave->w) % cave->w; +} + +static inline int gety_shift(const GdCave *cave, int x, int y) +{ + return ((x < 0 ? y - 1 : x >= cave->w ? y + 1 : y) + cave->h) % cave->h; +} + static inline GdElement *getp(const GdCave *cave, const int x, const int y) { return cave->getp(cave, x, y); @@ -489,11 +521,24 @@ static inline boolean is_element_dir(const GdCave *cave, const int x, const int static inline boolean is_space_dir(const GdCave *cave, const int x, const int y, const GdDirection dir) { - GdElement e = get_dir(cave, x, y, dir)&O_MASK; + GdElement e = get_dir(cave, x, y, dir) & O_MASK; return (e == O_SPACE || e == O_LAVA); } +static inline void store_dir_buffer(GdCave *cave, const int x, const int y, const GdDirection dir) +{ + /* raw values without range correction */ + int raw_x = x + gd_dx[dir]; + int raw_y = y + gd_dy[dir]; + /* final values with range correction */ + int new_x = getx(cave, raw_x, raw_y); + int new_y = gety(cave, raw_x, raw_y); + int new_dir = (dir > GD_MV_TWICE ? dir - GD_MV_TWICE : dir); + + game_bd.game->dir_buffer[new_y][new_x] = new_dir; +} + /* store an element at the given position */ static inline void store(GdCave *cave, const int x, const int y, const GdElement element) { @@ -519,13 +564,15 @@ static inline void store_sc(GdCave *cave, const int x, const int y, const GdElem static inline void store_dir(GdCave *cave, const int x, const int y, const GdDirection dir, const GdElement element) { - store(cave, x + gd_dx[dir], y + gd_dy[dir], element|SCANNED); + store_dir_buffer(cave, x, y, dir); + store(cave, x + gd_dx[dir], y + gd_dy[dir], element | SCANNED); } /* store an element to a neighbouring cell */ static inline void store_dir_no_scanned(GdCave *cave, const int x, const int y, const GdDirection dir, const GdElement element) { + store_dir_buffer(cave, x, y, dir); store(cave, x + gd_dx[dir], y + gd_dy[dir], element); } @@ -1517,9 +1564,17 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, /* set cave get function; to implement perfect or lineshifting borders */ if (cave->lineshift) + { cave->getp = getp_shift; + cave->getx = getx_shift; + cave->gety = gety_shift; + } else + { cave->getp = getp_perfect; + cave->getx = getx_perfect; + cave->gety = gety_perfect; + } /* increment this. if the scan routine comes across player, clears it (sets to zero). */ if (cave->player_seen_ago < 100) @@ -1600,7 +1655,7 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, { /* if we find a scanned element, change it to the normal one, and that's all. */ /* this is required, for example for chasing stones, which have moved, always passing slime! */ - if (get(cave, x, y)&SCANNED) + if (get(cave, x, y) & SCANNED) { store(cave, x, y, get(cave, x, y) & ~SCANNED); @@ -1669,8 +1724,11 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, /* try to push element; if successful, break */ push = do_push(cave, x, y, player_move, player_fire); if (push) + { remains = O_SPACE; + } else + { switch (what) { case O_BOMB: @@ -1718,9 +1776,10 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, default: /* get element - process others. if cannot get, player_get_element will return the same */ - remains = player_get_element (cave, what, x, y); + remains = player_get_element(cave, what, x, y); break; } + } if (remains != what || remains == O_SPACE) { @@ -1785,7 +1844,9 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, /* player fire is false... */ if (do_push(cave, x, y, player_move, FALSE)) + { remains = O_SPACE; + } else { switch (what)