From 90e3ff7a2243839abfdcab8d11d0c23804e31d40 Mon Sep 17 00:00:00 2001
From: Tamir Atias <engine.games@gmail.com>
Date: Sat, 4 Feb 2012 23:51:45 +0200
Subject: [PATCH] [Fix] NPCs and Player shall no longer spawn inside entities!

---
 src/Unuk/Game.cpp                   |  4 +--
 src/libUnuk/Engine/WorldManager.cpp |  2 +-
 src/libUnuk/LevelGen/LevelGen.cpp   | 50 ++++++++++++++++++++++-------
 src/libUnuk/LevelGen/LevelGen.h     |  2 +-
 4 files changed, 42 insertions(+), 16 deletions(-)

diff --git a/src/Unuk/Game.cpp b/src/Unuk/Game.cpp
index 34d50c2..00ba266 100644
--- a/src/Unuk/Game.cpp
+++ b/src/Unuk/Game.cpp
@@ -252,10 +252,10 @@ void Game::NewSavegame(const string savegameIDArg) {
 	TiXmlElement* nameElement = new TiXmlElement("name");
 	TiXmlText* nameText = new TiXmlText("Allanis"); //TODO: replace with _player->GetName() when it works. --konom
 	nameElement->LinkEndChild(nameText);
-
+  
   int spawnX;
   int spawnY;
-  _map.FindSpawnPoint(spawnX, spawnY);
+  _map.FindSpawnPoint(spawnX, spawnY, _player->GetWidth(), _player->GetHeight());
   
   _player->SetXY(spawnX, spawnY);
   
diff --git a/src/libUnuk/Engine/WorldManager.cpp b/src/libUnuk/Engine/WorldManager.cpp
index 0ed8282..6f0eca3 100644
--- a/src/libUnuk/Engine/WorldManager.cpp
+++ b/src/libUnuk/Engine/WorldManager.cpp
@@ -130,7 +130,7 @@ void WorldManager::OnPlayerAttack(Player* player) {
         
         int spawnX;
         int spawnY;
-        _level->FindSpawnPoint(spawnX, spawnY);
+        _level->FindSpawnPoint(spawnX, spawnY, player->GetWidth(),player->GetHeight());
         player->SetXY(spawnX, spawnY);
       }
     }
diff --git a/src/libUnuk/LevelGen/LevelGen.cpp b/src/libUnuk/LevelGen/LevelGen.cpp
index a4271ce..bbeb780 100644
--- a/src/libUnuk/LevelGen/LevelGen.cpp
+++ b/src/libUnuk/LevelGen/LevelGen.cpp
@@ -1,3 +1,5 @@
+#include <list>
+
 #include "LevelGen.h"
 #include "../Engine/NPC.h"
 
@@ -235,20 +237,44 @@ void LevelGen::MakeWalkingPaths(void) {
 	}
 }
 
-void LevelGen::FindSpawnPoint(int& xArg, int& yArg) {
+void LevelGen::FindSpawnPoint(int& xArg, int& yArg, int objWidth, int objHeight) {
 	xArg = rand() % (BOUNDARIES_X * TILE_WIDTH);
 	yArg = rand() % (BOUNDARIES_Y * TILE_HEIGHT);
+  
+  if(_world.HasNPCIn(xArg, yArg)) {
+    goto findNext;
+  }
+  
+  SDL_Rect objRect;
+  objRect.x = xArg;
+  objRect.y = yArg;
+  objRect.w = objWidth;
+  objRect.h = objHeight;
+  
+  for(int x = 0; x < BOUNDARIES_X; x++) {
+    for(int y = 0; y < BOUNDARIES_Y; y++) {
+      if(_tile[x][y].GetTileSolidity()) {
+        goto findNext; 
+      }
+      
+      if(_tile[x][y].GetEntitySolitity()) {
+        SDL_Rect entityRect;
+        entityRect.x = _tile[x][y].GetEntityX();
+        entityRect.y = _tile[x][y].GetEntityY();
+        entityRect.w = _tile[x][y].GetEntityWidth();
+        entityRect.h = _tile[x][y].GetEntityHeight(); 
+        
+        if(CheckCollisionRect(entityRect, objRect)) {
+          goto findNext;
+        }
+      }
+    }
+  }
+  
+  return;
 
-	int tileX = xArg / 64;
-	int tileY = yArg / 64;
-
-	if(!_tile[tileX][tileY].GetEntitySolitity() && 
-     !_tile[tileX][tileY].GetTileSolidity() && 
-     !_world.HasNPCIn(xArg, yArg)) {
-			return;
-	}
-
-	FindSpawnPoint(xArg, yArg);
+findNext:
+	FindSpawnPoint(xArg, yArg, objWidth, objHeight);
 }
 
 void LevelGen::GenerateEnemies(void) {
@@ -257,7 +283,7 @@ void LevelGen::GenerateEnemies(void) {
   for(int i = 0; i < npcsToGen; i++) {
     int spawnX;
     int spawnY;
-    FindSpawnPoint(spawnX, spawnY);
+    FindSpawnPoint(spawnX, spawnY, 40,45);
     
     _world.CreateNPC(spawnX, spawnY);
   }
diff --git a/src/libUnuk/LevelGen/LevelGen.h b/src/libUnuk/LevelGen/LevelGen.h
index 8d67b3d..ba6d12d 100644
--- a/src/libUnuk/LevelGen/LevelGen.h
+++ b/src/libUnuk/LevelGen/LevelGen.h
@@ -25,7 +25,7 @@ public:
   void Update(void);
   void Render(void);
   
-  void FindSpawnPoint(int& xArg, int& yArg);
+  void FindSpawnPoint(int& xArg, int& yArg, int objWidth, int objHeight);
 
 	bool GetTileSolidity(int xArg, int yArg);
 	int  GetTileX(int xArg, int yArg);