From 470de10de3a4d864ce2808bb3778cf9abfbc560e Mon Sep 17 00:00:00 2001
From: Loic Blot <loic.blot@unix-experience.fr>
Date: Fri, 3 Apr 2015 09:04:02 +0200
Subject: Fix players spawned at (0,0,0) in some rare cases instead of
 static_spawnpoint, if set Approved by: @kwoelkr

---
 src/server.cpp | 35 +++++++++++++++--------------------
 src/server.h   |  7 ++-----
 2 files changed, 17 insertions(+), 25 deletions(-)

diff --git a/src/server.cpp b/src/server.cpp
index a57d1f1aa..1969a5946 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -2522,7 +2522,7 @@ void Server::RespawnPlayer(u16 peer_id)
 
 	bool repositioned = m_script->on_respawnplayer(playersao);
 	if(!repositioned){
-		v3f pos = findSpawnPos(m_env->getServerMap());
+		v3f pos = findSpawnPos();
 		// setPos will send the new position to client
 		playersao->setPos(pos);
 	}
@@ -3179,23 +3179,24 @@ std::string Server::getBuiltinLuaPath()
 	return porting::path_share + DIR_DELIM + "builtin";
 }
 
-v3f findSpawnPos(ServerMap &map)
+v3f Server::findSpawnPos()
 {
-	//return v3f(50,50,50)*BS;
+	ServerMap &map = m_env->getServerMap();
+	v3f nodeposf;
+	if (g_settings->getV3FNoEx("static_spawnpoint", nodeposf)) {
+		return nodeposf * BS;
+	}
 
-	v3s16 nodepos;
+	// Default position is static_spawnpoint
+	// We will return it if we don't found a good place
+	v3s16 nodepos(nodeposf.X, nodeposf.Y, nodeposf.Z);
 
-#if 0
-	nodepos = v2s16(0,0);
-	groundheight = 20;
-#endif
-
-#if 1
 	s16 water_level = map.getWaterLevel();
 
+	bool is_good = false;
+
 	// Try to find a good place a few times
-	for(s32 i=0; i<1000; i++)
-	{
+	for(s32 i = 0; i < 1000 && !is_good; i++) {
 		s32 range = 1 + i;
 		// We're going to try to throw the player to this position
 		v2s16 nodepos2d = v2s16(
@@ -3210,7 +3211,7 @@ v3f findSpawnPos(ServerMap &map)
 			continue;
 
 		nodepos = v3s16(nodepos2d.X, groundheight, nodepos2d.Y);
-		bool is_good = false;
+
 		s32 air_count = 0;
 		for (s32 i = 0; i < 10; i++) {
 			v3s16 blockpos = getNodeBlockPos(nodepos);
@@ -3225,13 +3226,7 @@ v3f findSpawnPos(ServerMap &map)
 			}
 			nodepos.Y++;
 		}
-		if(is_good){
-			// Found a good place
-			//infostream<<"Searched through "<<i<<" places."<<std::endl;
-			break;
-		}
 	}
-#endif
 
 	return intToFloat(nodepos, BS);
 }
@@ -3274,7 +3269,7 @@ PlayerSAO* Server::emergePlayer(const char *name, u16 peer_id)
 		// Set player position
 		infostream<<"Server: Finding spawn place for player \""
 				<<name<<"\""<<std::endl;
-		v3f pos = findSpawnPos(m_env->getServerMap());
+		v3f pos = findSpawnPos();
 		player->setPosition(pos);
 
 		// Make sure the player is saved
diff --git a/src/server.h b/src/server.h
index a584cbe5a..da506acf1 100644
--- a/src/server.h
+++ b/src/server.h
@@ -63,11 +63,6 @@ enum ClientDeletionReason {
 	CDR_DENY
 };
 
-/*
-	Some random functions
-*/
-v3f findSpawnPos(ServerMap &map);
-
 class MapEditEventIgnorer
 {
 public:
@@ -474,6 +469,8 @@ private:
 	void DeleteClient(u16 peer_id, ClientDeletionReason reason);
 	void UpdateCrafting(Player *player);
 
+	v3f findSpawnPos();
+
 	// When called, connection mutex should be locked
 	RemoteClient* getClient(u16 peer_id,ClientState state_min=CS_Active);
 	RemoteClient* getClientNoEx(u16 peer_id,ClientState state_min=CS_Active);
-- 
cgit v1.2.3