added functions to get range corrected x/y cave position for BD engine
[rocksndiamonds.git] / src / game_bd / bd_caveengine.c
index 1fe5b2b017c8dee40e53d71d888736ed05e6f954..5f97940a9b6af721de585fb51ede95fcdc455d1e 100644 (file)
@@ -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,7 +521,7 @@ 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);
 }
@@ -519,7 +551,7 @@ 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(cave, x + gd_dx[dir], y + gd_dy[dir], element | SCANNED);
 }
 
 /* store an element to a neighbouring cell */
@@ -1517,9 +1549,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 +1640,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);