]> git.localhorst.tv Git - l2e.git/blob - src/map/Map.cpp
1c55eaf0690a552d470efcbb97a4be5ffe2ca2dd
[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 #include "../sdl/utility.h"
15
16 #include <stdexcept>
17
18 using geometry::Vector;
19
20 namespace map {
21
22 Map::Map()
23 : tileset(0)
24 , battlebg(0)
25 , areas(0)
26 , numAreas(0)
27 , triggers(0)
28 , numTriggers(0)
29 , entities(0)
30 , numEntities(0)
31 , width(0) {
32
33 }
34
35
36 Area *Map::AreaAt(const Vector<int> &offset) {
37         if (numAreas > 0) {
38                 Vector<int> coords(TileCoordinates(offset));
39                 Vector<int> areaOffset(coords / areas[0].Size());
40                 int areaIndex(areaOffset.Index(width));
41                 if (areaIndex < numAreas) {
42                         return areas + areaIndex;
43                 }
44         }
45         return 0;
46 }
47
48 const Area *Map::AreaAt(const Vector<int> &offset) const {
49         if (numAreas > 0) {
50                 Vector<int> coords(TileCoordinates(offset));
51                 Vector<int> areaOffset(coords / areas[0].Size());
52                 int areaIndex(areaOffset.Index(width));
53                 if (areaIndex < numAreas) {
54                         return areas + areaIndex;
55                 }
56         }
57         return 0;
58 }
59
60 Tile *Map::TileAt(const Vector<int> &offset) {
61         Area *area(AreaAt(offset));
62         if (area) {
63                 Vector<int> tileOffset(TileCoordinates(offset) % area->Size());
64                 return area->TileAt(tileOffset);
65         } else {
66                 return 0;
67         }
68 }
69
70 const Tile *Map::TileAt(const Vector<int> &offset) const {
71         const Area *area(AreaAt(offset));
72         if (area) {
73                 Vector<int> tileOffset(TileCoordinates(offset) % area->Size());
74                 return area->TileAt(tileOffset);
75         } else {
76                 return 0;
77         }
78 }
79
80 Trigger *Map::TriggerAt(const geometry::Vector<int> &offset) {
81         // TODO: add support for multiple triggers on a tile?
82         Vector<int> coords(TileCoordinates(offset));
83         for (Trigger *i(triggers); i != triggers + numTriggers; ++i) {
84                 if (i->TilePosition() == coords) {
85                         return i;
86                 }
87         }
88         return 0;
89 }
90
91 SDL_Surface *Map::BattleBackgroundAt(const geometry::Vector<int> &position) {
92         Tile *tile(TileAt(position));
93         if (tile && tile->BattleBackground()) {
94                 return tile->BattleBackground();
95         }
96         Area *area(AreaAt(position));
97         if (area && area->BattleBackground()) {
98                 return area->BattleBackground();
99         }
100         return battlebg;
101 }
102
103 Vector<int> Map::TileCoordinates(const Vector<int> &position) const {
104         return position / tileset->Size();
105 }
106
107
108 void Map::Render(SDL_Surface *dest, const Vector<int> &inOffset) const {
109         // TODO: skip invisible areas
110         for (int i(0); i < numAreas; ++i) {
111                 const Area &area(areas[i]);
112                 Vector<int> offset(inOffset + Vector<int>::FromIndex(i, width) * area.Size() * tileset->Size());
113                 area.Render(dest, tileset, offset);
114         }
115 }
116
117 void Map::RenderDebug(SDL_Surface *dest, const Vector<int> &inOffset) const {
118         // TODO: skip invisible areas
119         for (int i(0); i < numAreas; ++i) {
120                 const Area &area(areas[i]);
121                 Vector<int> offset(inOffset + Vector<int>::FromIndex(i, width) * area.Size() * tileset->Size());
122                 area.RenderDebug(dest, tileset, offset);
123         }
124         for (int i(0); i < numTriggers; ++i) {
125                 Vector<int> offset((triggers[i].TilePosition() * tileset->Size()) + inOffset);
126                 switch (triggers[i].GetType()) {
127                         case Trigger::TYPE_NORTH:
128                                 sdl::HorizontalLine(dest, offset + (tileset->Size() / 4), tileset->Width() / 2, SDL_MapRGB(dest->format, 0x00, 0xFF, 0xFF));
129                                 break;
130                         case Trigger::TYPE_EAST:
131                                 sdl::VerticalLine(dest, offset + Vector<int>(tileset->Width() * 3 / 4, tileset->Height() / 4), tileset->Height() / 2, SDL_MapRGB(dest->format, 0x00, 0xFF, 0xFF));
132                                 break;
133                         case Trigger::TYPE_SOUTH:
134                                 sdl::HorizontalLine(dest, offset + Vector<int>(tileset->Width() / 4, tileset->Height() * 3 / 4), tileset->Width() / 2, SDL_MapRGB(dest->format, 0x00, 0xFF, 0xFF));
135                                 break;
136                         case Trigger::TYPE_WEST:
137                                 sdl::VerticalLine(dest, offset + (tileset->Size() / 4), tileset->Width() / 2, SDL_MapRGB(dest->format, 0x00, 0xFF, 0xFF));
138                                 break;
139                         case Trigger::TYPE_CONTACT: {
140                                         SDL_Rect destRect;
141                                         destRect.x = offset.X() + (tileset->Width() / 4);
142                                         destRect.y = offset.Y() + (tileset->Height() / 4);
143                                         destRect.w = tileset->Width() / 2;
144                                         destRect.h = tileset->Height() / 2;
145                                         SDL_FillRect(dest, &destRect, SDL_MapRGB(dest->format, 0x00, 0xFF, 0xFF));
146                                 }
147                                 break;
148                 }
149         }
150 }
151
152 }