ManaPlus
navigationmanager.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2013-2019 The ManaPlus Developers
4  * Copyright (C) 2019-2021 Andrei Karas
5  *
6  * This file is part of The ManaPlus Client.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include "navigationmanager.h"
23 
25 
26 #include "resources/map/map.h"
27 #include "resources/map/metatile.h"
29 
30 #include "debug.h"
31 
32 static const int blockWalkMask = (BlockMask::WALL |
35 
36 #ifndef DYECMD
37 namespace
38 {
39  struct Cell final
40  {
41  Cell(const int x0, const int y0) :
42  x(x0),
43  y(y0)
44  {
45  }
46 
48 
49  int x;
50  int y;
51  };
52 } // namespace
53 #endif // DYECMD
54 
56 {
57 }
58 
60 {
61 }
62 
63 #ifndef DYECMD
65 {
66  if (map == nullptr)
67  return nullptr;
68 
69  const int width = map->getWidth();
70  const int height = map->getHeight();
71  if (width < 2 || height < 2)
72  return nullptr;
73  WalkLayer *const walkLayer = new WalkLayer(width, height);
74 
75  const MetaTile *const tiles = map->getMetaTiles();
76  int *const data = walkLayer->getData();
77  if ((tiles == nullptr) || (data == nullptr))
78  return walkLayer;
79 
80  int x = 0;
81  int y = 0;
82  int num = 1;
83  while (findWalkableTile(x, y, width, height, tiles, data))
84  {
85  fillNum(x, y, width, height, num, tiles, data);
86  num ++;
87  }
88 
89  return walkLayer;
90 }
91 
93  const int width,
94  const int height,
95  const int num,
96  const MetaTile *const tiles,
97  int *const data)
98 {
99  STD_VECTOR<Cell> cells;
100  cells.push_back(Cell(x, y));
101  while (!cells.empty())
102  {
103  const Cell cell = cells.back();
104  cells.pop_back();
105  int ptr;
106  x = cell.x;
107  y = cell.y;
108  data[x + width * y] = num;
109  if (x > 0)
110  {
111  ptr = (x - 1) + width * y;
112  if (data[ptr] == 0)
113  {
114  if ((tiles[ptr].blockmask & blockWalkMask) == 0)
115  cells.push_back(Cell(x - 1, y));
116  else
117  data[ptr] = -num;
118  }
119  }
120  if (x < width - 1)
121  {
122  ptr = (x + 1) + width * y;
123  if (data[ptr] == 0)
124  {
125  if ((tiles[ptr].blockmask & blockWalkMask) == 0)
126  cells.push_back(Cell(x + 1, y));
127  else
128  data[ptr] = -num;
129  }
130  }
131  if (y > 0)
132  {
133  ptr = x + width * (y - 1);
134  if (data[ptr] == 0)
135  {
136  if ((tiles[ptr].blockmask & blockWalkMask) == 0)
137  cells.push_back(Cell(x, y - 1));
138  else
139  data[ptr] = -num;
140  }
141  }
142  if (y < height - 1)
143  {
144  ptr = x + width * (y + 1);
145  if (data[ptr] == 0)
146  {
147  if ((tiles[ptr].blockmask & blockWalkMask) == 0)
148  cells.push_back(Cell(x, y + 1));
149  else
150  data[ptr] = -num;
151  }
152  }
153  }
154 }
155 
157  const int width,
158  const int height,
159  const MetaTile *const tiles,
160  const int *const data)
161 {
162  for (int y = 0; y < height; y ++)
163  {
164  const int y2 = y * width;
165  for (int x = 0; x < width; x ++)
166  {
167  const int ptr = x + y2;
168  if (((tiles[ptr].blockmask & blockWalkMask) == 0) &&
169  data[ptr] == 0)
170  {
171  x1 = x;
172  y1 = y;
173  return true;
174  }
175  }
176  }
177  return false;
178 }
179 #endif // DYECMD
Definition: map.h:75
const MetaTile * getMetaTiles() const
Definition: map.h:344
int getHeight() const
Definition: map.h:172
int getWidth() const
Definition: map.h:166
static bool findWalkableTile(int &x1, int &y1, const int width, const int height, const MetaTile *const tiles, const int *const data)
static void fillNum(int x, int y, const int width, const int height, const int num, const MetaTile *const tiles, int *const data)
static Resource * loadWalkLayer(const Map *const map)
int * getData()
Definition: walklayer.h:38
#define final
Definition: localconsts.h:46
#define A_DEFAULT_COPY(func)
Definition: localconsts.h:41
uint32_t data
static const int blockWalkMask