[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