]> git.localhorst.tv Git - l2e.git/blob - src/map/Map.cpp
closed the gap between battle and map state (yay)
[l2e.git] / src / map / Map.cpp
1 /*
2  * Map.cpp
3  *
4  *  Created on: Sep 29, 2012
5  *      Author: holy
6  */
7
8 #include "Map.h"
9
10 #include "Area.h"
11 #include "Tile.h"
12 #include "Trigger.h"
13 #include "../graphics/Sprite.h"
14
15 #include <stdexcept>
16
17 using geometry::Vector;
18
19 namespace map {
20
21 Map::Map()
22 : tileset(0)
23 , battlebg(0)
24 , areas(0)
25 , numAreas(0)
26 , triggers(0)
27 , numTriggers(0)
28 , entities(0)
29 , numEntities(0)
30 , width(0) {
31
32 }
33
34
35 Area *Map::AreaAt(const Vector<int> &offset) {
36         if (numAreas > 0) {
37                 Vector<int> coords(TileCoordinates(offset));
38                 Vector<int> areaOffset(coords / areas[0].Size());
39                 int areaIndex(areaOffset.Index(width));
40                 if (areaIndex < numAreas) {
41                         return areas + areaIndex;
42                 }
43         }
44         return 0;
45 }
46
47 const Area *Map::AreaAt(const Vector<int> &offset) const {
48         if (numAreas > 0) {
49                 Vector<int> coords(TileCoordinates(offset));
50                 Vector<int> areaOffset(coords / areas[0].Size());
51                 int areaIndex(areaOffset.Index(width));
52                 if (areaIndex < numAreas) {
53                         return areas + areaIndex;
54                 }
55         }
56         return 0;
57 }
58
59 Tile *Map::TileAt(const Vector<int> &offset) {
60         Area *area(AreaAt(offset));
61         if (area) {
62                 Vector<int> tileOffset(TileCoordinates(offset) % area->Size());
63                 return area->TileAt(tileOffset);
64         } else {
65                 return 0;
66         }
67 }
68
69 const Tile *Map::TileAt(const Vector<int> &offset) const {
70         const Area *area(AreaAt(offset));
71         if (area) {
72                 Vector<int> tileOffset(TileCoordinates(offset) % area->Size());
73                 return area->TileAt(tileOffset);
74         } else {
75                 return 0;
76         }
77 }
78
79 Trigger *Map::TriggerAt(const geometry::Vector<int> &offset) {
80         // TODO: add support for multiple triggers on a tile?
81         Vector<int> coords(TileCoordinates(offset));
82         for (Trigger *i(triggers); i != triggers + numTriggers; ++i) {
83                 if (i->TilePosition() == coords) {
84                         return i;
85                 }
86         }
87         return 0;
88 }
89
90 SDL_Surface *Map::BattleBackgroundAt(const geometry::Vector<int> &position) {
91         Tile *tile(TileAt(position));
92         if (tile && tile->BattleBackground()) {
93                 return tile->BattleBackground();
94         }
95         Area *area(AreaAt(position));
96         if (area && area->BattleBackground()) {
97                 return area->BattleBackground();
98         }
99         return battlebg;
100 }
101
102 Vector<int> Map::TileCoordinates(const Vector<int> &position) const {
103         return position / tileset->Size();
104 }
105
106
107 void Map::Render(SDL_Surface *dest, const Vector<int> &inOffset) const {
108         // TODO: skip invisible areas
109         for (int i(0); i < numAreas; ++i) {
110                 const Area &area(areas[i]);
111                 Vector<int> offset(inOffset + Vector<int>::FromIndex(i, width) * area.Size() * tileset->Size());
112                 area.Render(dest, tileset, offset);
113         }
114 }
115
116 void Map::RenderDebug(SDL_Surface *dest, const Vector<int> &inOffset) const {
117         // TODO: skip invisible areas
118         for (int i(0); i < numAreas; ++i) {
119                 const Area &area(areas[i]);
120                 Vector<int> offset(inOffset + Vector<int>::FromIndex(i, width) * area.Size() * tileset->Size());
121                 area.RenderDebug(dest, tileset, offset);
122         }
123         for (int i(0); i < numTriggers; ++i) {
124                 Vector<int> offset((triggers[i].TilePosition() * tileset->Size()) + inOffset);
125                 SDL_Rect destRect;
126                 destRect.x = offset.X() + (tileset->Width() / 4);
127                 destRect.y = offset.Y() + (tileset->Height() / 4);
128                 destRect.w = tileset->Width() / 2;
129                 destRect.h = tileset->Height() / 2;
130                 SDL_FillRect(dest, &destRect, SDL_MapRGB(dest->format, 0x00, 0xFF, 0xFF));
131         }
132 }
133
134 }