1//////////////////////////////////////////////////////////////////////
2// This file is part of Remere's Map Editor
3//////////////////////////////////////////////////////////////////////
4// Remere's Map Editor is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Remere's Map Editor is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16//////////////////////////////////////////////////////////////////////
17
18#ifndef RME_BRUSH_H_
19#define RME_BRUSH_H_
20#include "main.h"
21
22#include "position.h"
23
24#include "brush_enums.h"
25
26// Thanks to a million forward declarations, we don't have to include any files!
27// TODO move to a declarations file.
28class ItemType;
29class CreatureType;
30class BaseMap;
31class House;
32class Item;
33class Tile;
34typedef std::vector<Tile*> TileVector;
35class AutoBorder;
36class Brush;
37class RAWBrush;
38class DoodadBrush;
39class TerrainBrush;
40class GroundBrush;
41class WallBrush;
42class WallDecorationBrush;
43class TableBrush;
44class CarpetBrush;
45class DoorBrush;
46class OptionalBorderBrush;
47class CreatureBrush;
48class SpawnBrush;
49class HouseBrush;
50class HouseExitBrush;
51class WaypointBrush;
52class FlagBrush;
53class EraserBrush;
54
55//=============================================================================
56// Brushes, holds all brushes
57
58typedef std::multimap<std::string, Brush*> BrushMap;
59
60class Brushes {
61public:
62 Brushes();
63 ~Brushes();
64
65 void init();
66 void clear();
67
68 Brush* getBrush(const std::string& name) const;
69
70 void addBrush(Brush* brush);
71 void removeBrush(const std::string& name);
72
73 bool unserializeBorder(pugi::xml_node node, wxArrayString& warnings);
74 bool unserializeBrush(pugi::xml_node node, wxArrayString& warnings);
75
76 const BrushMap& getMap() const {
77 return brushes;
78 }
79
80protected:
81 typedef std::map<uint32_t, AutoBorder*> BorderMap;
82 BrushMap brushes;
83 BorderMap borders;
84
85 friend class AutoBorder;
86 friend class GroundBrush;
87};
88
89extern Brushes g_brushes;
90
91//=============================================================================
92// Common brush interface
93
94class Brush {
95public:
96 Brush();
97 virtual ~Brush();
98
99 virtual bool load(pugi::xml_node node, wxArrayString& warnings) {
100 return true;
101 }
102
103 virtual void draw(BaseMap* map, Tile* tile, void* parameter = nullptr) = 0;
104 virtual void undraw(BaseMap* map, Tile* tile) = 0;
105 virtual bool canDraw(BaseMap* map, const Position& position) const = 0;
106
107 //
108 uint32_t getID() const {
109 return id;
110 }
111
112 virtual std::string getName() const = 0;
113 virtual void setName(const std::string& newName) {
114 ASSERT(_MSG("setName attempted on nameless brush!"));
115 }
116
117 virtual int getLookID() const = 0;
118
119 virtual bool needBorders() const {
120 return false;
121 }
122
123 virtual bool canDrag() const {
124 return false;
125 }
126 virtual bool canSmear() const {
127 return true;
128 }
129
130 virtual bool oneSizeFitsAll() const {
131 return false;
132 }
133
134 virtual int32_t getMaxVariation() const {
135 return 0;
136 }
137
138 virtual bool isRaw() const {
139 return false;
140 }
141 virtual bool isDoodad() const {
142 return false;
143 }
144 virtual bool isTerrain() const {
145 return false;
146 }
147 virtual bool isGround() const {
148 return false;
149 }
150 virtual bool isWall() const {
151 return false;
152 }
153 virtual bool isWallDecoration() const {
154 return false;
155 }
156 virtual bool isTable() const {
157 return false;
158 }
159 virtual bool isCarpet() const {
160 return false;
161 }
162 virtual bool isDoor() const {
163 return false;
164 }
165 virtual bool isOptionalBorder() const {
166 return false;
167 }
168 virtual bool isCreature() const {
169 return false;
170 }
171 virtual bool isSpawn() const {
172 return false;
173 }
174 virtual bool isHouse() const {
175 return false;
176 }
177 virtual bool isHouseExit() const {
178 return false;
179 }
180 virtual bool isWaypoint() const {
181 return false;
182 }
183 virtual bool isFlag() const {
184 return false;
185 }
186 virtual bool isEraser() const {
187 return false;
188 }
189
190 virtual RAWBrush* asRaw() {
191 return nullptr;
192 }
193 virtual DoodadBrush* asDoodad() {
194 return nullptr;
195 }
196 virtual TerrainBrush* asTerrain() {
197 return nullptr;
198 }
199 virtual GroundBrush* asGround() {
200 return nullptr;
201 }
202 virtual WallBrush* asWall() {
203 return nullptr;
204 }
205 virtual WallDecorationBrush* asWallDecoration() {
206 return nullptr;
207 }
208 virtual TableBrush* asTable() {
209 return nullptr;
210 }
211 virtual CarpetBrush* asCarpet() {
212 return nullptr;
213 }
214 virtual DoorBrush* asDoor() {
215 return nullptr;
216 }
217 virtual OptionalBorderBrush* asOptionalBorder() {
218 return nullptr;
219 }
220 virtual CreatureBrush* asCreature() {
221 return nullptr;
222 }
223 virtual SpawnBrush* asSpawn() {
224 return nullptr;
225 }
226 virtual HouseBrush* asHouse() {
227 return nullptr;
228 }
229 virtual HouseExitBrush* asHouseExit() {
230 return nullptr;
231 }
232 virtual WaypointBrush* asWaypoint() {
233 return nullptr;
234 }
235 virtual FlagBrush* asFlag() {
236 return nullptr;
237 }
238 virtual EraserBrush* asEraser() {
239 return nullptr;
240 }
241
242 bool visibleInPalette() const {
243 return visible;
244 }
245 void flagAsVisible() {
246 visible = true;
247 }
248
249 bool hasCollection() const {
250 return usesCollection;
251 }
252 void setCollection() {
253 usesCollection = true;
254 }
255
256
257
258protected:
259 static uint32_t id_counter;
260 uint32_t id;
261 bool visible; // Visible in any palette?
262 bool usesCollection;
263};
264
265//=============================================================================
266// Terrain brush interface
267
268class TerrainBrush : public Brush {
269public:
270 TerrainBrush();
271 virtual ~TerrainBrush();
272
273 bool isTerrain() const {
274 return true;
275 }
276 TerrainBrush* asTerrain() {
277 return static_cast<TerrainBrush*>(this);
278 }
279
280 virtual bool canDraw(BaseMap* map, const Position& position) const {
281 return true;
282 }
283
284 virtual std::string getName() const {
285 return name;
286 }
287 virtual void setName(const std::string& newName) {
288 name = newName;
289 }
290
291 virtual int32_t getZ() const {
292 return 0;
293 }
294 virtual int32_t getLookID() const {
295 return look_id;
296 }
297
298 virtual bool needBorders() const {
299 return true;
300 }
301 virtual bool canDrag() const {
302 return true;
303 }
304
305 bool friendOf(TerrainBrush* other);
306
307protected:
308 std::vector<uint32_t> friends;
309 std::string name;
310 uint16_t look_id;
311 bool hate_friends;
312};
313
314//=============================================================================
315// FlagBrush, draw PZ etc.
316
317class FlagBrush : public Brush {
318public:
319 FlagBrush(uint32_t _flag);
320 virtual ~FlagBrush();
321
322 bool isFlag() const {
323 return true;
324 }
325 FlagBrush* asFlag() {
326 return static_cast<FlagBrush*>(this);
327 }
328
329 virtual bool canDraw(BaseMap* map, const Position& position) const;
330 virtual void draw(BaseMap* map, Tile* tile, void* parameter);
331 virtual void undraw(BaseMap* map, Tile* tile);
332
333 virtual bool canDrag() const {
334 return true;
335 }
336 virtual int getLookID() const;
337 virtual std::string getName() const;
338 void setZoneId(uint16_t _zoneId) {
339 zoneId = _zoneId;
340 }
341
342protected:
343 uint32_t flag;
344 uint16_t zoneId;
345};
346
347//=============================================================================
348// Doorbrush, add doors, windows etc.
349
350class DoorBrush : public Brush {
351public:
352 DoorBrush(DoorType _doortype);
353 virtual ~DoorBrush();
354
355 bool isDoor() const {
356 return true;
357 }
358 DoorBrush* asDoor() {
359 return static_cast<DoorBrush*>(this);
360 }
361
362 static void switchDoor(Item* door);
363
364 virtual bool canDraw(BaseMap* map, const Position& position) const;
365 virtual void draw(BaseMap* map, Tile* tile, void* parameter);
366 virtual void undraw(BaseMap* map, Tile* tile);
367
368 virtual int getLookID() const;
369 virtual std::string getName() const;
370 virtual bool oneSizeFitsAll() const {
371 return true;
372 }
373
374protected:
375 DoorType doortype;
376};
377
378//=============================================================================
379// OptionalBorderBrush, add gravel 'round mountains.
380
381class OptionalBorderBrush : public Brush {
382public:
383 OptionalBorderBrush();
384 virtual ~OptionalBorderBrush();
385
386 bool isOptionalBorder() const {
387 return true;
388 }
389 OptionalBorderBrush* asOptionalBorder() {
390 return static_cast<OptionalBorderBrush*>(this);
391 }
392
393 virtual bool canDraw(BaseMap* map, const Position& position) const;
394 virtual void draw(BaseMap* map, Tile* tile, void* parameter);
395 virtual void undraw(BaseMap* map, Tile* tile);
396
397 virtual bool canDrag() const {
398 return true;
399 }
400 virtual int getLookID() const;
401 virtual std::string getName() const;
402};
403
404//=============================================================================
405// Rampbrush, add ramps to mountains.
406
407class EraserBrush : public Brush {
408public:
409 EraserBrush();
410 virtual ~EraserBrush();
411
412 bool isEraser() const {
413 return true;
414 }
415 EraserBrush* asEraser() {
416 return static_cast<EraserBrush*>(this);
417 }
418
419 virtual bool canDraw(BaseMap* map, const Position& position) const;
420 virtual void draw(BaseMap* map, Tile* tile, void* parameter);
421 virtual void undraw(BaseMap* map, Tile* tile);
422
423 virtual bool needBorders() const {
424 return true;
425 }
426 virtual bool canDrag() const {
427 return true;
428 }
429 virtual int getLookID() const;
430 virtual std::string getName() const;
431};
432
433//=============================================================================
434// Autoborder, used by GroundBrush, should be transparent to users
435
436class AutoBorder {
437public:
438 AutoBorder(int _id) :
439 id(_id), group(0), ground(false) {
440 for (int i = 0; i < 13; i++) {
441 tiles[i] = 0;
442 }
443 }
444 ~AutoBorder() { }
445
446 static int edgeNameToID(const std::string& edgename);
447 bool load(pugi::xml_node node, wxArrayString& warnings, GroundBrush* owner = nullptr, uint16_t ground_equivalent = 0);
448
449 // Check if this border contains the specified item ID
450 bool hasItemId(uint16_t id) const {
451 for (int i = 0; i < 13; ++i) {
452 if (tiles[i] == id) {
453 return true;
454 }
455 }
456 return false;
457 }
458
459 // Get the item ID for a specific border alignment
460 uint16_t getItemId(uint32_t alignment) const {
461 // For now, just return the first matching tile
462 if (alignment < 13 && tiles[alignment] != 0) {
463 return tiles[alignment];
464 }
465
466 // If no direct match, return the first non-zero tile
467 for (int i = 0; i < 13; ++i) {
468 if (tiles[i] != 0) {
469 return tiles[i];
470 }
471 }
472
473 return 0; // No valid item ID found
474 }
475
476 uint32_t tiles[13];
477 uint32_t id;
478 uint16_t group;
479 bool ground;
480};
481
482#endif
483