[nexuiz-commits] r8417 - trunk/data/qcsrc/server

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Sat Dec 19 11:27:52 EST 2009


Author: div0
Date: 2009-12-19 11:27:51 -0500 (Sat, 19 Dec 2009)
New Revision: 8417

Modified:
   trunk/data/qcsrc/server/cl_client.qc
   trunk/data/qcsrc/server/miscfunctions.qc
   trunk/data/qcsrc/server/race.qc
   trunk/data/qcsrc/server/race.qh
Log:
race: improved respawn handling:
1. when respawning after touching a CP, always spawn at a spawn connected to EXACTLY THAT CP (if available).
2. when respawning without touching a CP, always spawn at the same spawn again


Modified: trunk/data/qcsrc/server/cl_client.qc
===================================================================
--- trunk/data/qcsrc/server/cl_client.qc	2009-12-19 09:59:05 UTC (rev 8416)
+++ trunk/data/qcsrc/server/cl_client.qc	2009-12-19 16:27:51 UTC (rev 8417)
@@ -74,8 +74,7 @@
 }
 
 
-#define SPAWNPOINT_SCORE frags
-
+.vector spawnpoint_score;
 .string netname_previous;
 
 void spawnfunc_info_player_survivor (void)
@@ -105,31 +104,34 @@
 };
 
 // Returns:
-//   -1 if a spawn can't be used
-//   otherwise, a weight of the spawnpoint
-float Spawn_Score(entity spot, entity playerlist, float teamcheck, float anypoint)
+//   _x: prio (-1 if unusable)
+//   _y: weight
+vector Spawn_Score(entity spot, entity playerlist, float teamcheck, float anypoint)
 {
 	float shortest, thisdist;
+	float prio;
 	entity player;
 
+	prio = 0;
+
 	// filter out spots for the wrong team
 	if(teamcheck)
 	if(spot.team != teamcheck)
-		return -1;
+		return '-1 0 0';
 
 	if(race_spawns)
 		if(spot.target == "")
-			return -1;
+			return '-1 0 0';
 
 	if(clienttype(self) == CLIENTTYPE_REAL)
 	{
 		if(spot.restriction == 1)
-			return -1;
+			return '-1 0 0';
 	}
 	else
 	{
 		if(spot.restriction == 2)
-			return -1;
+			return '-1 0 0';
 	}
 
 	// filter out spots for assault
@@ -143,7 +145,7 @@
 			{
 				found = 1;
 				if(ent.health < 0 || ent.health >= ASSAULT_VALUE_INACTIVE)
-					return -1;
+					return '-1 0 0';
 				good = 1;
 			}
 			else if(ent.classname == "trigger_race_checkpoint")
@@ -156,14 +158,17 @@
 					{
 						// spawn at first
 						if(ent.race_checkpoint != 0)
-							return -1;
+							return '-1 0 0';
 						if(spot.race_place != race_lowest_place_spawn)
-							return -1;
+							return '-1 0 0';
 					}
 					else
 					{
-						if(ent.race_checkpoint != race_PreviousCheckpoint(self.race_checkpoint))
-							return -1;
+						if(ent.race_checkpoint != max(0, self.race_respawn_checkpoint))
+							return '-1 0 0';
+						// try reusing the previous spawn
+						if(ent == self.race_respawn_spotref || spot == self.race_respawn_spotref)
+							prio += 1;
 						if(ent.race_checkpoint == 0)
 						{
 							float pl;
@@ -172,9 +177,8 @@
 								pl = 0;
 							if(pl == 0 && !self.race_started)
 								pl = race_highest_place_spawn; // use last place if he has not even touched finish yet
-							//print("race started? ", ftos(self.race_started), "\n");
 							if(spot.race_place != pl)
-								return -1;
+								return '-1 0 0';
 						}
 					}
 				}
@@ -184,7 +188,7 @@
 		}
 
 		if(found && !good)
-			return -1;
+			return '-1 0 0';
 	}
 
 	player = playerlist;
@@ -196,7 +200,7 @@
 			if (thisdist < shortest)
 				shortest = thisdist;
 		}
-	return shortest;
+	return prio * '1 0 0' + shortest * '0 1 0';
 }
 
 float spawn_allbad;
@@ -212,12 +216,12 @@
 
 	for(spot = firstspot; spot; spot = spot.chain)
 	{
-		spot.SPAWNPOINT_SCORE = Spawn_Score(spot, playerlist, teamcheck, anypoint);
+		spot.spawnpoint_score = Spawn_Score(spot, playerlist, teamcheck, anypoint);
 
 		if(cvar("spawn_debugview"))
 		{
 			setmodel(spot, "models/runematch/rune.mdl");
-			if(spot.SPAWNPOINT_SCORE < mindist)
+			if(spot.spawnpoint_score_y < mindist)
 			{
 				spot.colormod = '1 0 0';
 				spot.scale = 1;
@@ -225,13 +229,13 @@
 			else
 			{
 				spot.colormod = '0 1 0';
-				spot.scale = spot.SPAWNPOINT_SCORE / mindist;
+				spot.scale = spot.spawnpoint_score_y / mindist;
 			}
 		}
 
-		if(spot.SPAWNPOINT_SCORE >= 0) // spawning allowed here
+		if(spot.spawnpoint_score_x >= 0) // spawning allowed here
 		{
-			if(spot.SPAWNPOINT_SCORE < mindist)
+			if(spot.spawnpoint_score_y < mindist)
 			{
 				// too short distance
 				spawn_allgood = FALSE;
@@ -282,7 +286,7 @@
 
 	RandomSelection_Init();
 	for(spot = firstspot; spot; spot = spot.chain)
-		RandomSelection_Add(spot, 0, string_null, pow(bound(lower, spot.SPAWNPOINT_SCORE, upper), exponent) * spot.cnt, spot.SPAWNPOINT_SCORE >= lower);
+		RandomSelection_Add(spot, 0, string_null, pow(bound(lower, spot.spawnpoint_score_y, upper), exponent) * spot.cnt, (spot.spawnpoint_score_y >= lower) * 0.5 + spot.spawnpoint_score_x);
 
 	return RandomSelection_chosen_ent;
 }
@@ -344,7 +348,7 @@
 
 	if(cvar("spawn_debugview"))
 	{
-		print("spot mindistance: ", ftos(spot.SPAWNPOINT_SCORE), "\n");
+		print("spot mindistance: ", vtos(spot.spawnpoint_score), "\n");
 
 		entity e;
 		if(teamcheck)

Modified: trunk/data/qcsrc/server/miscfunctions.qc
===================================================================
--- trunk/data/qcsrc/server/miscfunctions.qc	2009-12-19 09:59:05 UTC (rev 8416)
+++ trunk/data/qcsrc/server/miscfunctions.qc	2009-12-19 16:27:51 UTC (rev 8417)
@@ -685,12 +685,12 @@
     war = cvar("prvm_backtraceforwarnings");
     cvar_set("developer", "1");
     cvar_set("prvm_backtraceforwarnings", "1");
-    dprint("\n");
-    dprint("--- CUT HERE ---\nWARNING: ");
-    dprint(msg);
-    dprint("\n");
+    print("\n");
+    print("--- CUT HERE ---\nWARNING: ");
+    print(msg);
+    print("\n");
     remove(world); // isn't there any better way to cause a backtrace?
-    dprint("\n--- CUT UNTIL HERE ---\n");
+    print("\n--- CUT UNTIL HERE ---\n");
     cvar_set("developer", ftos(dev));
     cvar_set("prvm_backtraceforwarnings", ftos(war));
 }

Modified: trunk/data/qcsrc/server/race.qc
===================================================================
--- trunk/data/qcsrc/server/race.qc	2009-12-19 09:59:05 UTC (rev 8416)
+++ trunk/data/qcsrc/server/race.qc	2009-12-19 16:27:51 UTC (rev 8417)
@@ -436,6 +436,8 @@
 			self.message = oldmsg;
 		}
 
+		other.race_respawn_checkpoint = self.race_checkpoint;
+		other.race_respawn_spotref = self; // this is not a spot but a CP, but spawnpoint selection will deal with that
 		other.race_checkpoint = race_NextCheckpoint(self.race_checkpoint);
 
 		race_SendTime(other, self.race_checkpoint, other.race_movetime, !!other.race_laptime);
@@ -761,18 +763,17 @@
 	race_ClearTime(self);
 	self.race_place = 0;
 	self.race_started = 0;
+	self.race_respawn_checkpoint = -1;
+	self.race_respawn_spotref = world;
 }
 
 void race_RetractPlayer()
 {
 	if(!g_race && !g_cts)
 		return;
-	if(self.race_started)
-		self.race_checkpoint = race_PreviousCheckpoint(self.race_checkpoint);
-	else
-		self.race_checkpoint = 0;
-	if(self.race_checkpoint == 0)
+	if(self.race_respawn_checkpoint == 0 || self.race_respawn_checkpoint == -1 || self.race_respawn_checkpoint == race_timed_checkpoint)
 		race_ClearTime(self);
+	self.race_checkpoint = self.race_respawn_checkpoint;
 }
 
 void race_PreDie()
@@ -787,8 +788,10 @@
 {
 	if(!g_race && !g_cts)
 		return;
-	if(self.killcount == -666 || g_race_qualifying)
+	if(self.killcount == -666 /* initial spawn */ || g_race_qualifying) // spawn
 		race_PreparePlayer();
+	else // respawn
+		race_RetractPlayer();
 
 	race_AbandonRaceCheck(self);
 }
@@ -797,23 +800,15 @@
 {
 	if(!g_race && !g_cts)
 		return;
-	if(self.killcount != -666 /* REspawning, not spawning */ && !g_race_qualifying)
-	{
-		if(spot.target == "")
-			// let the player run without timing, if he did not spawn at a targetting spawnpoint
-			race_PreparePlayer();
-		else
-			race_RetractPlayer();
-	}
 
-	if(spot.target != "" && self.race_checkpoint == -1 && self.race_started)
-	// if we have cleared the time, but were already in the race, set the
-	// current CP to 0, not -1, so when dying again we properly retract...
-	// however, note that race_laptime is still 0, so this won't count as
-	// completing another lap (as we already HAD seen that finish line before,
-	// or we wouldn't be at -1 and race_started)
-		self.race_checkpoint = 0;
+	if(spot.target == "")
+		// Emergency: this wasn't a real spawnpoint. Can this ever happen?
+		race_PreparePlayer();
 
+	// if we need to respawn, do it right
+	self.race_respawn_checkpoint = self.race_checkpoint;
+	self.race_respawn_spotref = spot;
+
 	self.race_place = 0;
 }
 
@@ -853,11 +848,15 @@
 		race_checkpoint_recordholders[i] = string_null;
 	}
 
-	FOR_EACH_CLIENT(e)
+	e = self;
+	FOR_EACH_CLIENT(self)
 	{
-		race_ClearTime(e);
-		e.race_started = 0;
+		float p;
+		p = self.race_place;
+		race_PreparePlayer();
+		self.race_place = p;
 	}
+	self = e;
 }
 
 void race_ReadyRestart()

Modified: trunk/data/qcsrc/server/race.qh
===================================================================
--- trunk/data/qcsrc/server/race.qh	2009-12-19 09:59:05 UTC (rev 8416)
+++ trunk/data/qcsrc/server/race.qh	2009-12-19 16:27:51 UTC (rev 8417)
@@ -24,3 +24,6 @@
 .float race_movetime; // for reading
 .float race_movetime_frac; // fractional accumulator for higher accuracy (helper for writing)
 .float race_movetime_count; // integer accumulator
+
+.float race_respawn_checkpoint;
+.entity race_respawn_spotref; // try THIS spawn in case you respawn



More information about the nexuiz-commits mailing list