[nexuiz-commits] r7188 - in trunk/data: qcsrc/client qcsrc/common qcsrc/server scripts

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Sat Jul 11 08:55:08 EDT 2009


Author: div0
Date: 2009-07-11 08:55:08 -0400 (Sat, 11 Jul 2009)
New Revision: 7188

Modified:
   trunk/data/qcsrc/client/Defs.qc
   trunk/data/qcsrc/client/Main.qc
   trunk/data/qcsrc/client/sbar.qc
   trunk/data/qcsrc/common/constants.qh
   trunk/data/qcsrc/server/cl_client.qc
   trunk/data/qcsrc/server/cl_physics.qc
   trunk/data/qcsrc/server/cl_weaponsystem.qc
   trunk/data/qcsrc/server/clientcommands.qc
   trunk/data/qcsrc/server/race.qc
   trunk/data/qcsrc/server/race.qh
   trunk/data/scripts/entities.def
Log:
experimental race penalty time system (entity fields race_penalty and race_penalty_reason, entities trigger_race_checkpoint and trigger_race_penalty)


Modified: trunk/data/qcsrc/client/Defs.qc
===================================================================
--- trunk/data/qcsrc/client/Defs.qc	2009-07-10 20:54:57 UTC (rev 7187)
+++ trunk/data/qcsrc/client/Defs.qc	2009-07-11 12:55:08 UTC (rev 7188)
@@ -188,6 +188,10 @@
 float race_nextcheckpoint;
 float race_nextbesttime;
 string race_nextbestname;
+float race_penaltyaccumulator; // qualifying: total penalty time in tenths
+float race_penaltyeventtime; // time when the player got the penalty
+float race_penaltytime; // duration of penalty time, in tenths
+string race_penaltyreason; // reason for penalty
 
 // RACE
 float race_mycheckpoint;

Modified: trunk/data/qcsrc/client/Main.qc
===================================================================
--- trunk/data/qcsrc/client/Main.qc	2009-07-10 20:54:57 UTC (rev 7187)
+++ trunk/data/qcsrc/client/Main.qc	2009-07-11 12:55:08 UTC (rev 7188)
@@ -919,7 +919,11 @@
 			race_checkpointtime = time;
 
 			if(race_checkpoint == 0 || race_checkpoint == 254)
+			{
+				race_penaltytime = 0;
+				race_penaltyaccumulator = 0;
 				race_laptime = time; // valid
+			}
 
 			break;
 
@@ -964,6 +968,24 @@
 				strunzone(race_othercheckpointenemy);
 			race_othercheckpointenemy = strzone(ColorTranslateRGB(ReadString()));
 			break;
+
+		case RACE_NET_PENALTY_RACE:
+			race_penaltyeventtime = time;
+			race_penaltytime = ReadByte();
+			//race_penaltyaccumulator += race_penaltytime;
+			if(race_penaltyreason)
+				strunzone(race_penaltyreason);
+			race_penaltyreason = strzone(ReadString());
+			break;
+
+		case RACE_NET_PENALTY_QUALIFYING:
+			race_penaltyeventtime = time;
+			race_penaltytime = ReadByte();
+			race_penaltyaccumulator += race_penaltytime;
+			if(race_penaltyreason)
+				strunzone(race_penaltyreason);
+			race_penaltyreason = strzone(ReadString());
+			break;
 	}
 }
 

Modified: trunk/data/qcsrc/client/sbar.qc
===================================================================
--- trunk/data/qcsrc/client/sbar.qc	2009-07-10 20:54:57 UTC (rev 7187)
+++ trunk/data/qcsrc/client/sbar.qc	2009-07-11 12:55:08 UTC (rev 7188)
@@ -1460,7 +1460,7 @@
 	if(gametype == GAME_RACE)
 	{
 		drawfont = sbar_bigfont;
-		float a;
+		float a, t;
 		vector m;
 		string s, forcetime;
 
@@ -1487,10 +1487,10 @@
 			{
 				if(race_laptime && race_nextbesttime && race_nextcheckpoint != 254)
 				{
-					a = bound(0, 2 - ((race_laptime + race_nextbesttime/10) - time), 1);
+					a = bound(0, 2 - ((race_laptime + race_nextbesttime/10) - (time + race_penaltyaccumulator/10)), 1);
 					if(a > 0) // next one?
 					{
-						s = MakeRaceString(race_nextcheckpoint, time - race_laptime, race_nextbesttime / 10, 0, race_nextbestname);
+						s = MakeRaceString(race_nextcheckpoint, (time + race_penaltyaccumulator/10) - race_laptime, race_nextbesttime / 10, 0, race_nextbestname);
 					}
 				}
 			}
@@ -1501,6 +1501,17 @@
 				drawcolorcodedstring(m - '0 16 0' - '8 0 0' * stringwidth(s, TRUE), s, '16 16 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
 			}
 
+			if(race_penaltytime)
+			{
+				a = bound(0, 2 - (time - race_penaltyeventtime), 1);
+				if(a > 0)
+				{
+					s = strcat("^1PENALTY: ", ftos_decimals(race_penaltytime * 0.1, 1), " (", race_penaltyreason, ")");
+					dummyfunction(0, 0, 0, 0, 0, 0, 0, 0); // work around DP bug (set OFS_PARAM5 to 0)
+					drawcolorcodedstring(m - '0 32 0' - '8 0 0' * stringwidth(s, TRUE), s, '16 16 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
+				}
+			}
+
 			if(forcetime != "")
 			{
 				a = bound(0, (time - race_checkpointtime) / 0.5, 1);
@@ -1511,7 +1522,7 @@
 
 			if(race_laptime && race_checkpoint != 255)
 			{
-				s = mmsss(10*(time - race_laptime));
+				s = mmsss(10*(time + race_penaltyaccumulator/10 - race_laptime));
 				drawstring(m - '16 0 0' * stringwidth(s, FALSE), s, '32 32 0', '1 1 1', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
 			}
 		}
@@ -1531,6 +1542,21 @@
 				dummyfunction(0, 0, 0, 0, 0, 0, 0, 0); // work around DP bug (set OFS_PARAM5 to 0)
 				drawcolorcodedstring(m - '0 0 0' - '8 0 0' * stringwidth(s, TRUE), s, '16 16 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
 			}
+
+			if(race_penaltytime && !race_penaltyaccumulator)
+			{
+				t = race_penaltytime * 0.1 + race_penaltyeventtime;
+				a = bound(0, (1 + t - time), 1);
+				if(a > 0)
+				{
+					if(time < t)
+						s = strcat("^1PENALTY: ", ftos_decimals(t - time, 1), " (", race_penaltyreason, ")");
+					else
+						s = strcat("^2PENALTY: 0.0 (", race_penaltyreason, ")");
+					dummyfunction(0, 0, 0, 0, 0, 0, 0, 0); // work around DP bug (set OFS_PARAM5 to 0)
+					drawcolorcodedstring(m - '0 32 0' - '8 0 0' * stringwidth(s, TRUE), s, '16 16 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL);
+				}
+			}
 		}
 
 		drawfont = sbar_font;

Modified: trunk/data/qcsrc/common/constants.qh
===================================================================
--- trunk/data/qcsrc/common/constants.qh	2009-07-10 20:54:57 UTC (rev 7187)
+++ trunk/data/qcsrc/common/constants.qh	2009-07-11 12:55:08 UTC (rev 7188)
@@ -56,6 +56,8 @@
 const float RACE_NET_CHECKPOINT_HIT_RACE = 3; // byte checkpoint, short delta, byte lapsdelta, string opponent
 const float RACE_NET_CHECKPOINT_HIT_RACE_BY_OPPONENT = 4; // byte checkpoint, short delta, byte lapsdelta, string opponent
 const float RACE_NET_CHECKPOINT_NEXT_SPEC_QUALIFYING = 5; // byte nextcheckpoint, float laptime, short recordtime, string recordholder
+const float RACE_NET_PENALTY_RACE = 6; // byte penaltytime, string reason
+const float RACE_NET_PENALTY_QUALIFYING = 7; // byte penaltytime, string reason
 
 const float ENT_CLIENT = 0;
 const float ENT_CLIENT_DEAD = 1;

Modified: trunk/data/qcsrc/server/cl_client.qc
===================================================================
--- trunk/data/qcsrc/server/cl_client.qc	2009-07-10 20:54:57 UTC (rev 7187)
+++ trunk/data/qcsrc/server/cl_client.qc	2009-07-11 12:55:08 UTC (rev 7188)
@@ -2745,9 +2745,6 @@
 =============
 */
 .float idlekick_lasttimeleft;
-.float race_penalty;
-.float race_penalty_nagged;
-.float race_penalty_nagtime;
 void PlayerPostThink (void)
 {
 	// Savage: Check for nameless players
@@ -2841,45 +2838,9 @@
 		//if (TetrisPostFrame()) return;
 
 		// restart countdown
-			if(time < game_starttime) {
-				if (!cvar("sv_ready_restart_after_countdown"))
-				{
-					if(self.movement != '0 0 0' && g_race && !g_race_qualifying)
-					{
-						if(time < game_starttime - 2)
-						{
-							if(!self.race_penalty_nagged)
-							{
-								// TODO better notification for this!
-								self.race_penalty_nagtime = 0;
-								self.race_penalty_nagged = 1;
-							}
-						}
-						else if(!self.race_penalty)
-						{
-							self.race_penalty_nagtime = 0;
-							self.race_penalty = time + 5;
-						}
-					}
-					if(time > self.race_penalty_nagtime)
-					{
-						if(self.race_penalty > time)
-						{
-							centerprint_atprio(self, CENTERPRIO_IDLEKICK, "^1FIVE SECONDS PENALTY.");
-						}
-						else if(self.race_penalty_nagged && time < game_starttime - 2)
-						{
-							centerprint_atprio(self, CENTERPRIO_IDLEKICK, "^1DO NOT MOVE DURING THE COUNTDOWN.");
-						}
-						self.race_penalty_nagtime = time + self.cvar_scr_centertime * 0.6;
-					}
-					self.movetype = MOVETYPE_NONE;		
-					self.velocity = '0 0 0';
-					self.avelocity = '0 0 0';
-					self.movement = '0 0 0';
-				}
-			}
-			else if (time < self.race_penalty)
+		if (!cvar("sv_ready_restart_after_countdown"))
+		{
+			if(time < game_starttime)
 			{
 				self.movetype = MOVETYPE_NONE;		
 				self.velocity = '0 0 0';
@@ -2889,16 +2850,10 @@
 			else
 			{
 				//allow the player to move again if sv_ready_restart_after_countdown is not used and countdown is over
-				if (!cvar("sv_ready_restart_after_countdown"))
-				{
-					if(self.movetype == MOVETYPE_NONE)
-					{
-						self.movetype = MOVETYPE_WALK;
-					}
-					self.race_penalty = 0;
-					self.race_penalty_nagged = 0;
-				}
+				if(self.movetype == MOVETYPE_NONE)
+					self.movetype = MOVETYPE_WALK;
 			}
+		}
 		GetPressedKeys();
 	} else if (self.classname == "observer") {
 		//do nothing

Modified: trunk/data/qcsrc/server/cl_physics.qc
===================================================================
--- trunk/data/qcsrc/server/cl_physics.qc	2009-07-10 20:54:57 UTC (rev 7187)
+++ trunk/data/qcsrc/server/cl_physics.qc	2009-07-11 12:55:08 UTC (rev 7188)
@@ -1,3 +1,5 @@
+.float race_penalty;
+
 float sv_accelerate;
 float sv_friction;
 float sv_maxspeed;
@@ -524,7 +526,27 @@
 
 	self.items &~= IT_USING_JETPACK;
 
-	if (self.movetype == MOVETYPE_NONE && self.disableclientprediction != 2)
+	if(self.race_penalty)
+	{
+		if(time > self.race_penalty)
+		{
+			if(self.disableclientprediction == 2)
+			{
+				self.movetype = MOVETYPE_WALK;
+				self.disableclientprediction = 0;
+			}
+			self.race_penalty = 0;
+		}
+	}
+
+	if(self.race_penalty)
+	{
+		self.velocity = '0 0 0';
+		self.movetype = MOVETYPE_NONE;
+		self.disableclientprediction = 2;
+	}
+
+	if (self.movetype == MOVETYPE_NONE)
 		return;
 
 	if (self.punchangle != '0 0 0')

Modified: trunk/data/qcsrc/server/cl_weaponsystem.qc
===================================================================
--- trunk/data/qcsrc/server/cl_weaponsystem.qc	2009-07-10 20:54:57 UTC (rev 7187)
+++ trunk/data/qcsrc/server/cl_weaponsystem.qc	2009-07-11 12:55:08 UTC (rev 7188)
@@ -993,10 +993,9 @@
 {
 	//if sv_ready_restart_after_countdown is set, don't allow the player to shoot
 	//if all players readied up and the countdown is running
-	if (cvar("sv_ready_restart_after_countdown"))
-		if(time < game_starttime || time < self.race_penalty) {
-			return FALSE;
-		}
+	if(time < game_starttime || time < self.race_penalty) {
+		return FALSE;
+	}
 	
 	if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
 	if (!weapon_action(self.weapon, WR_CHECKAMMO1 + secondary))

Modified: trunk/data/qcsrc/server/clientcommands.qc
===================================================================
--- trunk/data/qcsrc/server/clientcommands.qc	2009-07-10 20:54:57 UTC (rev 7187)
+++ trunk/data/qcsrc/server/clientcommands.qc	2009-07-11 12:55:08 UTC (rev 7188)
@@ -383,6 +383,11 @@
 		}
 		else
 			sprint(self, "Usage: sv_cheats 1; restart; cmd make models/... 0/1/2\n");
+	} else if(argv(0) == "penalty") {
+		if((sv_cheats || self.maycheat) && tokens == 3)
+			race_ImposePenaltyTime(self, stof(argv(1)), argv(2));
+		else
+			sprint(self, "Usage: sv_cheats 1; restart; cmd penalty 5.0 AHAHAHAHAHAHAH))\n");
 	} else {
 		//if(ctf_clientcommand())
 		//	return;

Modified: trunk/data/qcsrc/server/race.qc
===================================================================
--- trunk/data/qcsrc/server/race.qc	2009-07-10 20:54:57 UTC (rev 7187)
+++ trunk/data/qcsrc/server/race.qc	2009-07-11 12:55:08 UTC (rev 7188)
@@ -1,7 +1,11 @@
 #define MAX_CHECKPOINTS 255
 
+.float race_penalty;
+.float race_penalty_accumulator;
+.string race_penalty_reason;
 .float race_checkpoint; // player: next checkpoint that has to be reached
 .float race_laptime;
+.entity race_lastpenalty;
 
 .entity sprite;
 
@@ -75,7 +79,7 @@
 		if(spec)
 		{
 			WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_NEXT_SPEC_QUALIFYING);
-			WriteCoord(MSG_ONE, e.race_laptime);
+			WriteCoord(MSG_ONE, e.race_laptime - e.race_penalty_accumulator);
 		}
 		else
 			WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_NEXT_QUALIFYING);
@@ -97,6 +101,9 @@
 	float snew, l;
 	entity p;
 
+	if(g_race_qualifying)
+		t += e.race_penalty_accumulator;
+
 	t = floor(0.4 + 10 * t); // make integer
 	// adding just 0.4 so it rounds down in the .5 case (matching the timer display)
 
@@ -114,7 +121,7 @@
 		else
 		{
 			s = PlayerScore_Add(e, SP_RACE_TIME, 0);
-			snew = floor(0.5 + 10 * (time - game_starttime));
+			snew = floor(0.4 + 10 * (time - game_starttime));
 			PlayerScore_Add(e, SP_RACE_TIME, snew - s);
 			l = PlayerTeamScore_Add(e, SP_RACE_LAPS, ST_RACE_LAPS, 1);
 
@@ -284,6 +291,8 @@
 {
 	e.race_checkpoint = -1;
 	e.race_laptime = 0;
+	e.race_penalty_accumulator = 0;
+	e.race_lastpenalty = world;
 
 	msg_entity = e;
 	WRITESPECTATABLE_MSG_ONE({
@@ -366,12 +375,18 @@
 			self.message = oldmsg;
 		}
 
+		race_ImposePenaltyTime(other, self.race_penalty, self.race_penalty_reason);
+
 		other.race_checkpoint = race_NextCheckpoint(self.race_checkpoint);
 
 		race_SendTime(other, self.race_checkpoint, time - other.race_laptime, !!other.race_laptime);
 
 		if(!self.race_checkpoint) // start line
+		{
 			other.race_laptime = time;
+			other.race_penalty_accumulator = 0;
+			other.race_lastpenalty = world;
+		}
 
 		if(g_race_qualifying)
 			race_SendNextCheckpoint(other, 0);
@@ -462,10 +477,13 @@
 
 	if(race_timed_checkpoint)
 		for(cp = world; (cp = find(cp, classname, "trigger_race_checkpoint")); )
-			if(cp.race_checkpoint == 0)
-				WaypointSprite_UpdateSprites(cp.sprite, "race-start", "", "");
-			else if(cp.race_checkpoint == race_timed_checkpoint)
-				WaypointSprite_UpdateSprites(cp.sprite, "race-finish", "", "");
+			if(cp.sprite)
+			{
+				if(cp.race_checkpoint == 0)
+					WaypointSprite_UpdateSprites(cp.sprite, "race-start", "", "");
+				else if(cp.race_checkpoint == race_timed_checkpoint)
+					WaypointSprite_UpdateSprites(cp.sprite, "race-finish", "", "");
+			}
 
 	remove(self);
 	self = oldself;
@@ -495,6 +513,8 @@
 		self.message = "went backwards";
 	if (!self.message2)
 		self.message2 = "was pushed backwards by";
+	if (!self.race_penalty_reason)
+		self.race_penalty_reason = "missing a checkpoint";
 	
 	self.race_checkpoint = self.cnt;
 
@@ -507,10 +527,13 @@
 			race_timed_checkpoint = 0;
 	}
 
-	if(self.race_checkpoint)
-		WaypointSprite_SpawnFixed("race-checkpoint", o, self, sprite);
-	else
-		WaypointSprite_SpawnFixed("race-finish", o, self, sprite);
+	if(!self.race_penalty)
+	{
+		if(self.race_checkpoint)
+			WaypointSprite_SpawnFixed("race-checkpoint", o, self, sprite);
+		else
+			WaypointSprite_SpawnFixed("race-finish", o, self, sprite);
+	}
 
 	self.sprite.waypointsprite_visible_for_player = race_waypointsprite_visible_for_player;
 
@@ -643,3 +666,61 @@
 		ScoreRules_race();
 	}
 }
+
+void race_ImposePenaltyTime(entity pl, float penalty, string reason)
+{
+	if(g_race_qualifying)
+	{
+		pl.race_penalty_accumulator += penalty;
+		msg_entity = pl;
+		WRITESPECTATABLE_MSG_ONE({
+			WriteByte(MSG_ONE, SVC_TEMPENTITY);
+			WriteByte(MSG_ONE, TE_CSQC_RACE);
+			WriteByte(MSG_ONE, RACE_NET_PENALTY_QUALIFYING);
+			WriteByte(MSG_ONE, floor(0.4 + 10 * penalty));
+			WriteString(MSG_ONE, reason);
+		});
+	}
+	else
+	{
+		pl.race_penalty = time + penalty;
+		msg_entity = pl;
+		WRITESPECTATABLE_MSG_ONE_VARNAME(dummy, {
+			WriteByte(MSG_ONE, SVC_TEMPENTITY);
+			WriteByte(MSG_ONE, TE_CSQC_RACE);
+			WriteByte(MSG_ONE, RACE_NET_PENALTY_RACE);
+			WriteByte(MSG_ONE, floor(0.4 + 10 * penalty));
+			WriteString(MSG_ONE, reason);
+		});
+	}
+}
+
+void penalty_touch()
+{
+	EXACTTRIGGER_TOUCH;
+	race_ImposePenaltyTime(other, self.race_penalty, self.race_penalty_reason);
+}
+
+void penalty_use()
+{
+	other = activator;
+	if(other.race_lastpenalty != self)
+	{
+		other.race_lastpenalty = self;
+		race_ImposePenaltyTime(other, self.race_penalty, self.race_penalty_reason);
+	}
+}
+
+void spawnfunc_trigger_race_penalty()
+{
+	EXACTTRIGGER_INIT;
+
+	self.use = penalty_use;
+	if not(self.spawnflags & 1)
+		self.touch = penalty_touch;
+
+	if (!self.race_penalty_reason)
+		self.race_penalty_reason = "missing a checkpoint";
+	if (!self.race_penalty)
+		self.race_penalty = 5;
+}

Modified: trunk/data/qcsrc/server/race.qh
===================================================================
--- trunk/data/qcsrc/server/race.qh	2009-07-10 20:54:57 UTC (rev 7187)
+++ trunk/data/qcsrc/server/race.qh	2009-07-11 12:55:08 UTC (rev 7188)
@@ -16,3 +16,4 @@
 .float race_place;
 .float race_completed;
 float race_completing;
+void race_ImposePenaltyTime(entity pl, float penalty, string reason);

Modified: trunk/data/scripts/entities.def
===================================================================
--- trunk/data/scripts/entities.def	2009-07-10 20:54:57 UTC (rev 7187)
+++ trunk/data/scripts/entities.def	2009-07-11 12:55:08 UTC (rev 7188)
@@ -1228,6 +1228,8 @@
 message2: Death message when someone gets pushed into this (default: "was thrown into a world of hurt by"). The # character is replaced by the attacker name if present (and it instead does not get appended to the end)
 targetname: Name of the checkpoint. info_player_race can target this to assign a spawn to a checkpoint. Also used for triggering a checkpoint by an event.
 target: when the checkpoint is passed, these entities are triggered. Useful for forcing items in certain areas using trigger_items
+race_penalty: when set, this penalty time is given if passing this checkpoint, and the checkpoint does not show up with a sprite. Useful for invisible checkpoints to detect driving around the intended checkpoint
+race_penalty_reason: reason to display when the penalty time is imposed. Default: "missing a checkpoint"
 -------- SPAWNFLAGS --------
 NOTOUCH: the checkpoint will not become active when touched, it HAS to be targeted
 STRICTTRIGGER: only trigger the targets when the checkpoint actually was reached in a valid way (that is, not when going back)
@@ -1235,6 +1237,15 @@
 FINISH: when set on the last checkpoint (i.e. the one with highest cnt), it is marked as finish line and the CP with cnt=0 is the start line
 */
 
+/*QUAKED trigger_race_penalty (0 1 0) ? NOTOUCH
+A penalty trigger.
+-------- KEYS --------
+race_penalty: this penalty time is given if passing this trigger
+race_penalty_reason: reason to display when the penalty time is imposed. Default: "leaving the track"
+-------- SPAWNFLAGS --------
+NOTOUCH: the trigger will not become active when touched, it HAS to be targeted
+*/
+
 /*QUAKED info_player_race (1 0.5 0) (-16 -16 -24) (16 16 45) 
 Race spawn point.
 NOTE for race_place: when the race starts after the qualifying, the player with the fastest map ends up at the info_player_race with race_place 1, and so on. If there are too many players, or if someone comes in later, he will spawn at an info_player_race with race_place not set. So for each trigger_race_checkpoint, there must be at least one corresponding info_player_race with race_place NOT set.



More information about the nexuiz-commits mailing list