From 1cf8f72e6702d255849f5bbf422fecd4e6a23f98 Mon Sep 17 00:00:00 2001
From: Joseph Walton-Rivers <joseph@walton-rivers.uk>
Date: Sun, 4 Sep 2022 18:10:58 +0100
Subject: [PATCH] shield the grid against out of bounds

---
 demo/include/grid.hpp                  |  6 ++++-
 include/fggl/entity/gridworld/zone.hpp | 32 ++++++++++++++++++++++----
 2 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/demo/include/grid.hpp b/demo/include/grid.hpp
index 158c56d..62ecb1d 100644
--- a/demo/include/grid.hpp
+++ b/demo/include/grid.hpp
@@ -91,7 +91,11 @@ namespace demo {
 				} else if (cell.direction == 3) {
 					moveDir.x = -1;
 				}
-				cell.pos += moveDir;
+
+				if ( m_grid->canMove(cell.pos, moveDir) ) {
+					cell.pos += moveDir;
+				}
+
 			}
 
 			inline void rotate(bool clockwise) {
diff --git a/include/fggl/entity/gridworld/zone.hpp b/include/fggl/entity/gridworld/zone.hpp
index 376c7db..38a14de 100644
--- a/include/fggl/entity/gridworld/zone.hpp
+++ b/include/fggl/entity/gridworld/zone.hpp
@@ -98,6 +98,11 @@ namespace fggl::entity::grid {
 				clear();
 			}
 
+			inline bool inBounds(GridPos pos) const {
+				return 0 <= pos.x && pos.x <= width
+				    && 0 <= pos.y && pos.y <= height;
+			}
+
 			void clear() {
 				WallState noWall;
 
@@ -135,7 +140,10 @@ namespace fggl::entity::grid {
 			}
 
 			inline bool canMove(GridPos pos) const {
-				return m_tiles.m_floors[m_floors.getCell(pos)] != 0;
+				if ( !inBounds(pos) ) {
+					return false;
+				}
+				return m_tiles.m_floors[m_floors.get(pos)].moveCost != FloorTile::IMPOSSIBLE;
 			}
 
 			inline bool canMove(GridPos pos, math::vec2i dir) const {
@@ -143,11 +151,25 @@ namespace fggl::entity::grid {
 			}
 
 			inline bool blocked(GridPos pos, math::vec2i dir) const {
-				if ( dir.x == -1 || dir.y == -1 ) {
-					return m_walls.getCell(pos) != 0;
-				} else {
-					m_walls.getCell(pos + dir) != 0;
+				auto targetPos = pos;
+				if ( dir.x == 1 || dir.y == 1 ) {
+					targetPos = pos + dir;
+				}
+
+				if ( !inBounds(targetPos) ) {
+					return true;
+				}
+
+				auto& wallObj = m_walls.get(targetPos);
+				if ( dir.y != 0 ) {
+					return wallObj.north != 0;
 				}
+
+				if (dir.x != 0) {
+					return wallObj.west != 0;
+				}
+
+				return true;
 			}
 
 			EntityManager& entities() {
-- 
GitLab