about summary refs log tree commit diff
path: root/src/game/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/server')
-rw-r--r--src/game/server/entities/character.cpp4
-rw-r--r--src/game/server/gamecontroller.cpp74
-rw-r--r--src/game/server/gamecontroller.hpp28
-rw-r--r--src/game/server/hooks.cpp2
-rw-r--r--src/game/server/player.cpp80
5 files changed, 103 insertions, 85 deletions
diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp
index 0e15794e..f9e53e61 100644
--- a/src/game/server/entities/character.cpp
+++ b/src/game/server/entities/character.cpp
@@ -692,10 +692,6 @@ bool CHARACTER::take_damage(vec2 force, int dmg, int from, int weapon)
 	if(from == player->client_id)
 		dmg = max(1, dmg/2);
 
-	// CTF and TDM (TODO: check for FF)
-	//if (gameobj->gametype != GAMETYPE_DM && from >= 0 && players[from].team == team)
-		//return false;
-
 	damage_taken++;
 
 	// create healthmod indicator
diff --git a/src/game/server/gamecontroller.cpp b/src/game/server/gamecontroller.cpp
index b0a16cd6..4e25ff4e 100644
--- a/src/game/server/gamecontroller.cpp
+++ b/src/game/server/gamecontroller.cpp
@@ -10,6 +10,70 @@
 #include "gamecontroller.hpp"
 #include "gamecontext.hpp"
 
+float GAMECONTROLLER::evaluate_spawn_pos(SPAWNEVAL *eval, vec2 pos)
+{
+	float score = 0.0f;
+	CHARACTER *c = (CHARACTER *)game.world.find_first(NETOBJTYPE_CHARACTER);
+	for(; c; c = (CHARACTER *)c->typenext())
+	{
+		// team mates are not as dangerous as enemies
+		float scoremod = 1.0f;
+		if(eval->friendly_team != -1 && c->team == eval->friendly_team)
+			scoremod = 0.5f;
+			
+		float d = distance(pos, c->pos);
+		if(d == 0)
+			score += 1000000000.0f;
+		else
+			score += 1.0f/d;
+	}
+	
+	return score;
+}
+
+void GAMECONTROLLER::evaluate_spawn_type(SPAWNEVAL *eval, int t)
+{
+	// get spawn point
+	for(int i  = 0; i < num_spawn_points[t]; i++)
+	{
+		vec2 p = spawn_points[t][i];
+		float s = evaluate_spawn_pos(eval, p);
+		if(!eval->got || eval->score > s)
+		{
+			eval->got = true;
+			eval->score = s;
+			eval->pos = p;
+		}
+	}
+}
+
+bool GAMECONTROLLER::can_spawn(PLAYER *player, vec2 *out_pos)
+{
+	SPAWNEVAL eval;
+	
+	if(is_teamplay)
+	{
+		eval.friendly_team = player->team;
+		
+		// try first try own team spawn, then normal spawn and then enemy
+		evaluate_spawn_type(&eval, 1+(player->team&1));
+		if(!eval.got)
+		{
+			evaluate_spawn_type(&eval, 0);
+			if(!eval.got)
+				evaluate_spawn_type(&eval, 1+((player->team+1)&1));
+		}
+	}
+	else
+	{
+		evaluate_spawn_type(&eval, 0);
+		evaluate_spawn_type(&eval, 1);
+		evaluate_spawn_type(&eval, 2);
+	}
+	
+	*out_pos = eval.pos;
+	return eval.got;}
+
 GAMECONTROLLER::GAMECONTROLLER()
 {
 	// select gametype
@@ -37,13 +101,13 @@ GAMECONTROLLER::GAMECONTROLLER()
 	round_count = 0;
 	is_teamplay = false;
 	teamscore[0] = 0;
-	teamscore[1] = 0;	
+	teamscore[1] = 0;
+	
+	num_spawn_points[0] = 0;
+	num_spawn_points[1] = 0;
+	num_spawn_points[2] = 0;
 }
 
-// UGLY!!!!
-extern vec2 spawn_points[3][64];
-extern int num_spawn_points[3];
-
 bool GAMECONTROLLER::on_entity(int index, vec2 pos)
 {
 	int type = -1;
diff --git a/src/game/server/gamecontroller.hpp b/src/game/server/gamecontroller.hpp
index a3cfe9ba..d756768f 100644
--- a/src/game/server/gamecontroller.hpp
+++ b/src/game/server/gamecontroller.hpp
@@ -10,7 +10,28 @@
 */
 class GAMECONTROLLER
 {
+	vec2 spawn_points[3][64];
+	int num_spawn_points[3];
 protected:
+	struct SPAWNEVAL
+	{
+		SPAWNEVAL()
+		{
+			got = false;
+			friendly_team = -1;
+			pos = vec2(100,100);
+		}
+			
+		vec2 pos;
+		bool got;
+		int friendly_team;
+		float score;
+	};
+
+	float evaluate_spawn_pos(SPAWNEVAL *eval, vec2 pos);
+	void evaluate_spawn_type(SPAWNEVAL *eval, int type);
+	bool evaluate_spawn(class PLAYER *p, vec2 *pos);
+
 	void cyclemap();
 	void resetgame();
 	
@@ -23,10 +44,11 @@ protected:
 	int warmup;
 	int round_count;
 	
-	bool is_teamplay;
 	
 public:
 	int gametype;
+	bool is_teamplay;
+	
 	GAMECONTROLLER();
 
 	void do_team_score_wincheck();
@@ -81,8 +103,12 @@ public:
 	*/
 	virtual int on_character_death(class CHARACTER *victim, class PLAYER *killer, int weapon);
 
+
 	virtual void on_player_info_change(class PLAYER *p);
 
+	//
+	virtual bool can_spawn(class PLAYER *p, vec2 *pos);
+
 	/*
 	
 	*/	
diff --git a/src/game/server/hooks.cpp b/src/game/server/hooks.cpp
index 328cfb4f..485c7850 100644
--- a/src/game/server/hooks.cpp
+++ b/src/game/server/hooks.cpp
@@ -360,7 +360,7 @@ void mods_init()
 		{
 			mods_connected(MAX_CLIENTS-i-1);
 			mods_client_enter(MAX_CLIENTS-i-1);
-			if(game.controller->gametype != GAMETYPE_DM)
+			if(game.controller->is_teamplay)
 				game.players[MAX_CLIENTS-i-1].team = i&1;
 		}
 	}
diff --git a/src/game/server/player.cpp b/src/game/server/player.cpp
index 3c84e5e7..1ad19701 100644
--- a/src/game/server/player.cpp
+++ b/src/game/server/player.cpp
@@ -149,87 +149,18 @@ void PLAYER::set_team(int new_team)
 	}
 }
 
-vec2 spawn_points[3][64];
-int num_spawn_points[3] = {0};
-
-struct SPAWNEVAL
-{
-	SPAWNEVAL()
-	{
-		got = false;
-		friendly_team = -1;
-//		die_pos = vec2(0,0);
-		pos = vec2(100,100);
-	}
-		
-	vec2 pos;
-	bool got;
-	int friendly_team;
-	float score;
-//	vec2 die_pos;
-};
-
-static float evaluate_spawn(SPAWNEVAL *eval, vec2 pos)
-{
-	float score = 0.0f;
-	CHARACTER *c = (CHARACTER *)game.world.find_first(NETOBJTYPE_CHARACTER);
-	for(; c; c = (CHARACTER *)c->typenext())
-	{
-		// team mates are not as dangerous as enemies
-		float scoremod = 1.0f;
-		if(eval->friendly_team != -1 && c->team == eval->friendly_team)
-			scoremod = 0.5f;
-			
-		float d = distance(pos, c->pos);
-		if(d == 0)
-			score += 1000000000.0f;
-		else
-			score += 1.0f/d;
-	}
-	
-	// weight in the die posititon
-	/*
-	float d = distance(pos, eval->die_pos);
-	if(d == 0)
-		score += 1000000000.0f;
-	else
-		score += 1.0f/d;*/
-	
-	return score;
-}
-
-static void evaluate_spawn_type(SPAWNEVAL *eval, int t)
-{
-	// get spawn point
-	/*
-	int start, num;
-	map_get_type(t, &start, &num);
-	if(!num)
-		return;
-	*/
-	for(int i  = 0; i < num_spawn_points[t]; i++)
-	{
-		//num_spawn_points[t]
-		//mapres_spawnpoint *sp = (mapres_spawnpoint*)map_get_item(start + i, NULL, NULL);
-		vec2 p = spawn_points[t][i];// vec2((float)sp->x, (float)sp->y);
-		float s = evaluate_spawn(eval, p);
-		if(!eval->got || eval->score > s)
-		{
-			eval->got = true;
-			eval->score = s;
-			eval->pos = p;
-		}
-	}
-}
-
 void PLAYER::try_respawn()
 {
 	vec2 spawnpos = vec2(100.0f, -60.0f);
 	
+	if(!game.controller->can_spawn(this, &spawnpos))
+		return;
+	
 	// get spawn point
-	SPAWNEVAL eval;
+	//SPAWNEVAL eval;
 	//eval.die_pos = die_pos;
 	
+	/*
 	eval.pos = vec2(100, 100);
 	
 	if(game.controller->gametype == GAMETYPE_CTF)
@@ -256,6 +187,7 @@ void PLAYER::try_respawn()
 	}
 	
 	spawnpos = eval.pos;
+	*/
 
 	// check if the position is occupado
 	ENTITY *ents[2] = {0};