4 * Created on: Sep 29, 2012
13 #include "../graphics/Sprite.h"
14 #include "../sdl/utility.h"
18 using geometry::Vector;
36 Area *Map::AreaAt(const Vector<int> &offset) {
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;
48 const Area *Map::AreaAt(const Vector<int> &offset) const {
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;
60 Tile *Map::TileAt(const Vector<int> &offset) {
61 Area *area(AreaAt(offset));
63 Vector<int> tileOffset(TileCoordinates(offset) % area->Size());
64 return area->TileAt(tileOffset);
70 const Tile *Map::TileAt(const Vector<int> &offset) const {
71 const Area *area(AreaAt(offset));
73 Vector<int> tileOffset(TileCoordinates(offset) % area->Size());
74 return area->TileAt(tileOffset);
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) {
91 SDL_Surface *Map::BattleBackgroundAt(const geometry::Vector<int> &position) {
92 Tile *tile(TileAt(position));
93 if (tile && tile->BattleBackground()) {
94 return tile->BattleBackground();
96 Area *area(AreaAt(position));
97 if (area && area->BattleBackground()) {
98 return area->BattleBackground();
103 Vector<int> Map::TileCoordinates(const Vector<int> &position) const {
104 return position / tileset->Size();
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);
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);
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));
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));
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));
136 case Trigger::TYPE_WEST:
137 sdl::VerticalLine(dest, offset + (tileset->Size() / 4), tileset->Width() / 2, SDL_MapRGB(dest->format, 0x00, 0xFF, 0xFF));
139 case Trigger::TYPE_CONTACT: {
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));