From ed792d6d00d822384d79d049e644e372f7c3b4cd Mon Sep 17 00:00:00 2001
From: Daniel Karbach <daniel.karbach@localhorst.tv>
Date: Sun, 7 Oct 2012 15:00:20 +0200
Subject: [PATCH] made TileAt/AreaAt fail silently

this way the game does not halt when the player walks off the map
---
 src/map/Area.cpp     |  6 +++---
 src/map/Area.h       |  2 +-
 src/map/Map.cpp      | 18 +++++++++++-------
 src/map/Map.h        |  4 ++--
 src/map/MapState.cpp | 13 ++++++++-----
 5 files changed, 25 insertions(+), 18 deletions(-)

diff --git a/src/map/Area.cpp b/src/map/Area.cpp
index 6b3f9b1..9c066d6 100644
--- a/src/map/Area.cpp
+++ b/src/map/Area.cpp
@@ -25,12 +25,12 @@ Area::Area()
 }
 
 
-const Tile &Area::TileAt(const geometry::Vector<int> &offset) const {
+const Tile *Area::TileAt(const geometry::Vector<int> &offset) const {
 	int tileIndex(offset.Y() * width + offset.X());
 	if (tileIndex < numTiles) {
-		return tiles[tileIndex];
+		return tiles +tileIndex;
 	} else {
-		throw std::out_of_range("tile index out of range");
+		return 0;
 	}
 }
 
diff --git a/src/map/Area.h b/src/map/Area.h
index 0a56339..d9cc5d0 100644
--- a/src/map/Area.h
+++ b/src/map/Area.h
@@ -26,7 +26,7 @@ public:
 	int Width() const { return width; }
 	int Height() const { return numTiles / width + (numTiles % width ? 1 : 0); }
 	geometry::Vector<int> Size() const { return geometry::Vector<int>(Width(), Height()); }
-	const Tile &TileAt(const geometry::Vector<int> &) const;
+	const Tile *TileAt(const geometry::Vector<int> &) const;
 
 	void Render(SDL_Surface *dest, const graphics::Sprite *tileset, const geometry::Vector<int> &offset) const;
 	void RenderDebug(SDL_Surface *dest, const graphics::Sprite *tileset, const geometry::Vector<int> &offset) const;
diff --git a/src/map/Map.cpp b/src/map/Map.cpp
index d7c0b32..fc664c1 100644
--- a/src/map/Map.cpp
+++ b/src/map/Map.cpp
@@ -30,22 +30,26 @@ Map::Map()
 }
 
 
-const Area &Map::AreaAt(const Vector<int> &offset) const {
+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 areas + areaIndex;
 		}
 	}
-	throw std::out_of_range("area offset out of bounds");
+	return 0;
 }
 
-const Tile &Map::TileAt(const Vector<int> &offset) const {
-	const Area &area(AreaAt(offset));
-	Vector<int> tileOffset(TileCoordinates(offset) % area.Size());
-	return area.TileAt(tileOffset);
+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 geometry::Vector<int> &offset) {
diff --git a/src/map/Map.h b/src/map/Map.h
index 8c2804d..ab0728b 100644
--- a/src/map/Map.h
+++ b/src/map/Map.h
@@ -24,8 +24,8 @@ public:
 
 public:
 	const graphics::Sprite *Tileset() const { return tileset; }
-	const Area &AreaAt(const geometry::Vector<int> &) const;
-	const Tile &TileAt(const geometry::Vector<int> &) const;
+	const Area *AreaAt(const geometry::Vector<int> &) const;
+	const Tile *TileAt(const geometry::Vector<int> &) const;
 	Trigger *TriggerAt(const geometry::Vector<int> &);
 	geometry::Vector<int> TileCoordinates(const geometry::Vector<int> &) const;
 
diff --git a/src/map/MapState.cpp b/src/map/MapState.cpp
index 7e6d732..791cc0b 100644
--- a/src/map/MapState.cpp
+++ b/src/map/MapState.cpp
@@ -133,11 +133,14 @@ void MapState::OnTileLock() {
 }
 
 bool MapState::CheckBlocking() const {
-	const Tile &tile(map->TileAt(controlled->Position()));
+	const Tile *tile(map->TileAt(controlled->Position()));
+	if (!tile) {
+		return false;
+	}
 	Vector<int> nextPosition;
 	switch (nextDirection) {
 		case Entity::ORIENTATION_NORTH:
-			if (tile.BlocksNorth()) {
+			if (tile->BlocksNorth()) {
 				return true;
 			} else {
 				nextPosition = Vector<int>(
@@ -146,7 +149,7 @@ bool MapState::CheckBlocking() const {
 			}
 			break;
 		case Entity::ORIENTATION_EAST:
-			if (tile.BlocksEast()) {
+			if (tile->BlocksEast()) {
 				return true;
 			} else {
 				nextPosition = Vector<int>(
@@ -155,7 +158,7 @@ bool MapState::CheckBlocking() const {
 			}
 			break;
 		case Entity::ORIENTATION_SOUTH:
-			if (tile.BlocksSouth()) {
+			if (tile->BlocksSouth()) {
 				return true;
 			} else {
 				nextPosition = Vector<int>(
@@ -164,7 +167,7 @@ bool MapState::CheckBlocking() const {
 			}
 			break;
 		case Entity::ORIENTATION_WEST:
-			if (tile.BlocksWest()) {
+			if (tile->BlocksWest()) {
 				return true;
 			} else {
 				nextPosition = Vector<int>(
-- 
2.39.5