+Area *Map::AreaAt(const Vector<int> &offset) {
+ if (numAreas > 0) {
+ Vector<int> coords(TileCoordinates(offset));
+ Vector<int> areaOffset(coords / areas[0].Size());
+ int areaIndex(areaOffset.Index(width));
+ if (areaIndex < numAreas) {
+ return areas + areaIndex;
+ }
+ }
+ return 0;
+}
+
+const Area *Map::AreaAt(const Vector<int> &offset) const {
+ if (numAreas > 0) {
+ Vector<int> coords(TileCoordinates(offset));
+ Vector<int> areaOffset(coords / areas[0].Size());
+ int areaIndex(areaOffset.Index(width));
+ if (areaIndex < numAreas) {
+ return areas + areaIndex;
+ }
+ }
+ return 0;
+}
+
+Tile *Map::TileAt(const Vector<int> &offset) {
+ Area *area(AreaAt(offset));
+ if (area) {
+ Vector<int> tileOffset(TileCoordinates(offset) % area->Size());
+ return area->TileAt(tileOffset);
+ } else {
+ return 0;
+ }
+}
+
+const Tile *Map::TileAt(const Vector<int> &offset) const {
+ const Area *area(AreaAt(offset));
+ if (area) {
+ Vector<int> tileOffset(TileCoordinates(offset) % area->Size());
+ return area->TileAt(tileOffset);
+ } else {
+ return 0;
+ }
+}
+
+Trigger *Map::TriggerAt(const math::Vector<int> &offset) {
+ // TODO: add support for multiple triggers on a tile?
+ Vector<int> coords(TileCoordinates(offset));
+ for (Trigger *i(triggers); i != triggers + numTriggers; ++i) {
+ if (i->TilePosition() == coords) {
+ return i;
+ }
+ }
+ return 0;
+}
+
+SDL_Surface *Map::BattleBackgroundAt(const math::Vector<int> &position) {
+ Tile *tile(TileAt(position));
+ if (tile && tile->BattleBackground()) {
+ return tile->BattleBackground();
+ }
+ Area *area(AreaAt(position));
+ if (area && area->BattleBackground()) {
+ return area->BattleBackground();
+ }
+ return battlebg;
+}
+
+Vector<int> Map::TileCoordinates(const Vector<int> &position) const {
+ return position / tileset->Size();
+}
+
+Vector<int> Map::PixelCoordinates(const Vector<int> &position) const {
+ return position * tileset->Size();
+}
+
+
+void Map::Render(
+ SDL_Surface *dest,
+ const Vector<int> &inOffset,
+ unsigned int frame) const {
+ // TODO: skip invisible areas
+ for (int i(0); i < numAreas; ++i) {
+ const Area &area(areas[i]);
+ Vector<int> offset(inOffset + Vector<int>::FromIndex(i, width) * area.Size() * tileset->Size());
+ area.Render(dest, tileset, offset, frame);
+ }
+}
+
+void Map::RenderDebug(SDL_Surface *dest, const Vector<int> &inOffset) const {