r4136 - in trunk/data/qcsrc: client common server
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Thu Aug 21 11:32:47 EDT 2008
Author: div0
Date: 2008-08-21 11:32:44 -0400 (Thu, 21 Aug 2008)
New Revision: 4136
Modified:
trunk/data/qcsrc/client/Defs.qc
trunk/data/qcsrc/client/Main.qc
trunk/data/qcsrc/client/miscfunctions.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/miscfunctions.qc
trunk/data/qcsrc/server/race.qc
trunk/data/qcsrc/server/teamplay.qc
Log:
Race: send stuff to people spectating someone too (incomplete)
New spectator mode display (csqc)
Spectating now allows changing spectating speed (using mouse wheel)
Modified: trunk/data/qcsrc/client/Defs.qc
===================================================================
--- trunk/data/qcsrc/client/Defs.qc 2008-08-17 13:35:05 UTC (rev 4135)
+++ trunk/data/qcsrc/client/Defs.qc 2008-08-21 15:32:44 UTC (rev 4136)
@@ -199,3 +199,6 @@
float race_othercheckpointlapsdelta;
string race_othercheckpointenemy;
float sb_showscores_force;
+
+// Spectating
+float spectatee_status;
Modified: trunk/data/qcsrc/client/Main.qc
===================================================================
--- trunk/data/qcsrc/client/Main.qc 2008-08-17 13:35:05 UTC (rev 4135)
+++ trunk/data/qcsrc/client/Main.qc 2008-08-21 15:32:44 UTC (rev 4136)
@@ -644,6 +644,28 @@
}
}
+void Net_ReadForceScoreboard()
+{
+ sb_showscores_force = ReadByte();
+}
+
+void Net_Reset()
+{
+ race_laptime = 0;
+ race_checkpointtime = 0;
+}
+
+void Net_ReadSpectating()
+{
+ float newspectatee_status;
+ newspectatee_status = ReadByte();
+ if(newspectatee_status == player_localentnum)
+ newspectatee_status = -1; // observing
+ if(newspectatee_status != spectatee_status)
+ Net_Reset();
+ spectatee_status = newspectatee_status;
+}
+
// CSQC_Parse_TempEntity : Handles all temporary entity network data in the CSQC layer.
// You must ALWAYS first acquire the temporary ID, which is sent as a byte.
// Return value should be 1 if CSQC handled the temporary entity, otherwise return 0 to have the engine process the event.
@@ -679,9 +701,13 @@
bHandled = true;
break;
case TE_CSQC_FORCESCOREBOARD:
- sb_showscores_force = true;
+ Net_ReadForceScoreboard();
bHandled = true;
break;
+ case TE_CSQC_SPECTATING:
+ Net_ReadSpectating();
+ bHandled = true;
+ break;
default:
// No special logic for this temporary entity; return 0 so the engine can handle it
bHandled = false;
Modified: trunk/data/qcsrc/client/miscfunctions.qc
===================================================================
--- trunk/data/qcsrc/client/miscfunctions.qc 2008-08-17 13:35:05 UTC (rev 4135)
+++ trunk/data/qcsrc/client/miscfunctions.qc 2008-08-21 15:32:44 UTC (rev 4136)
@@ -141,7 +141,16 @@
vector Sbar_GetFontsize()
{
if(csqc_flags & CSQC_FLAG_READPICTURE)
- return stov(cvar_string("sbar_fontsize"));
+ {
+ vector v;
+ v = stov(cvar_string("sbar_fontsize"));
+ if(v_x == 0)
+ v = '8 8 0';
+ if(v_y == 0)
+ v_y = v_x;
+ v_z = 0;
+ return v;
+ }
return '8 8 0' ;
}
Modified: trunk/data/qcsrc/client/sbar.qc
===================================================================
--- trunk/data/qcsrc/client/sbar.qc 2008-08-17 13:35:05 UTC (rev 4135)
+++ trunk/data/qcsrc/client/sbar.qc 2008-08-21 15:32:44 UTC (rev 4136)
@@ -742,12 +742,6 @@
lastpingstime = time;
}
- sbar_fontsize = Sbar_GetFontsize();
- if(sbar_fontsize_x == 0)
- sbar_fontsize = '8 8 0';
- if(sbar_fontsize_y == 0)
- sbar_fontsize_y = sbar_fontsize_x;
-
xmin = vid_conwidth / 5;
ymin = 20;
@@ -1325,11 +1319,86 @@
float x, fade;
float stat_items;
+ sbar_fontsize = Sbar_GetFontsize();
+
+ if(spectatee_status)
+ {
+ string s;
+ vector o;
+ o = '1 0 0' * vid_conwidth;
+ if(spectatee_status == -1)
+ s = "^1Observing";
+ else
+ s = strcat("^1Spectating ^7", getplayerkey(spectatee_status - 1, "name"));
+ dummyfunction(0, 0, 0, 0, 0, 0, 0, 0); // work around DP bug (set OFS_PARAM5 to 0)
+ drawcolorcodedstring(
+ o - sbar_fontsize_x * '1 0 0' * stringwidth(s, TRUE),
+ s,
+ sbar_fontsize,
+ sbar_alpha_fg,
+ 0
+ );
+ o += sbar_fontsize_y * '0 1 0';
+
+ if(spectatee_status == -1)
+ s = "^1Press ^3primary fire^1 to spectate";
+ else
+ s = "^1Press ^3primary fire^1 for another player";
+ dummyfunction(0, 0, 0, 0, 0, 0, 0, 0); // work around DP bug (set OFS_PARAM5 to 0)
+ drawcolorcodedstring(
+ o - sbar_fontsize_x * '1 0 0' * stringwidth(s, TRUE),
+ s,
+ sbar_fontsize,
+ sbar_alpha_fg,
+ 0
+ );
+ o += sbar_fontsize_y * '0 1 0';
+
+ if(spectatee_status != -1)
+ s = "^1Use ^3weapon switching^1 to change the speed";
+ else
+ s = "^1Press ^3secondary fire^1 to observe";
+ dummyfunction(0, 0, 0, 0, 0, 0, 0, 0); // work around DP bug (set OFS_PARAM5 to 0)
+ drawcolorcodedstring(
+ o - sbar_fontsize_x * '1 0 0' * stringwidth(s, TRUE),
+ s,
+ sbar_fontsize,
+ sbar_alpha_fg,
+ 0
+ );
+ o += sbar_fontsize_y * '0 1 0';
+
+ if(gametype == GAME_ARENA)
+ s = "^1Wait for your turn to join";
+ else if(gametype == GAME_LMS)
+ {
+ entity sk;
+ sk = playerslots[player_localentnum - 1];
+ if(sk.(scores[ps_primary]) >= 666)
+ s = "^1Match has already begun";
+ else if(sk.(scores[ps_primary]) > 0)
+ s = "^1You have no more lives left";
+ else
+ s = "^1Press ^7jump^1 to join";
+ }
+ else
+ s = "^1Press ^7jump^1 to join";
+ dummyfunction(0, 0, 0, 0, 0, 0, 0, 0); // work around DP bug (set OFS_PARAM5 to 0)
+ drawcolorcodedstring(
+ o - sbar_fontsize_x * '1 0 0' * stringwidth(s, TRUE),
+ s,
+ sbar_fontsize,
+ sbar_alpha_fg,
+ 0
+ );
+ o += sbar_fontsize_y * '0 1 0';
+ }
+
//Sbar_SortFrags();
Sbar_UpdatePlayerTeams();
sb_lines = 24;
-
+
if (sb_showscores)
Sbar_DrawScoreboard();
else if (intermission == 1)
Modified: trunk/data/qcsrc/common/constants.qh
===================================================================
--- trunk/data/qcsrc/common/constants.qh 2008-08-17 13:35:05 UTC (rev 4135)
+++ trunk/data/qcsrc/common/constants.qh 2008-08-21 15:32:44 UTC (rev 4136)
@@ -9,7 +9,8 @@
// Revision 8: race
// Revision 9: race delta
// Revision 10: scoreboard force
-#define CSQC_REVISION 9
+// Revision 11: scoreboard unforce; spectator support beginning
+#define CSQC_REVISION 11
// probably put these in common/
// so server/ and client/ can be synced better
@@ -189,6 +190,7 @@
const float TE_CSQC_SCORESINFO = 108;
const float TE_CSQC_RACE = 109;
const float TE_CSQC_FORCESCOREBOARD = 110;
+const float TE_CSQC_SPECTATING = 111;
const float STAT_KH_KEYS = 32;
const float STAT_CTF_STATE = 33;
Modified: trunk/data/qcsrc/server/cl_client.qc
===================================================================
--- trunk/data/qcsrc/server/cl_client.qc 2008-08-17 13:35:05 UTC (rev 4135)
+++ trunk/data/qcsrc/server/cl_client.qc 2008-08-21 15:32:44 UTC (rev 4136)
@@ -1920,6 +1920,7 @@
*/
void() ctf_setstatus;
.float vote_nagtime;
+.float spectatee_status;
void PlayerPreThink (void)
{
if(blockSpectators)
@@ -2187,6 +2188,21 @@
} else if(self.classname == "spectator") {
SpectatorThink();
}
+
+ float oldspectatee_status;
+ oldspectatee_status = self.spectatee_status;
+ if(self.classname == "spectator")
+ self.spectatee_status = num_for_edict(self.enemy);
+ else if(self.classname == "observer")
+ self.spectatee_status = num_for_edict(self);
+ else
+ self.spectatee_status = 0;
+ if(self.spectatee_status != oldspectatee_status)
+ {
+ WriteByte(MSG_ONE, SVC_TEMPENTITY);
+ WriteByte(MSG_ONE, TE_CSQC_SPECTATING);
+ WriteByte(MSG_ONE, self.spectatee_status);
+ }
}
Modified: trunk/data/qcsrc/server/cl_physics.qc
===================================================================
--- trunk/data/qcsrc/server/cl_physics.qc 2008-08-17 13:35:05 UTC (rev 4135)
+++ trunk/data/qcsrc/server/cl_physics.qc 2008-08-21 15:32:44 UTC (rev 4136)
@@ -14,6 +14,7 @@
.float lastflags;
.float lastground;
.float wasFlying;
+.float spectatorspeed;
#define SHTEST_DELTA 15
.float shtest_next;
@@ -206,7 +207,28 @@
}
if(self.flags & FL_NOTARGET)
+ {
maxspd_mod = cvar("sv_spectator_speed_multiplier");
+ if(!self.spectatorspeed)
+ self.spectatorspeed = maxspd_mod;
+ if(self.impulse && self.impulse <= 12)
+ {
+ if(self.lastflags & FL_NOTARGET)
+ {
+ if(self.impulse == 10)
+ self.spectatorspeed = bound(1, self.spectatorspeed + 0.5, 5);
+ else if(self.impulse == 11)
+ self.spectatorspeed = maxspd_mod;
+ else if(self.impulse == 12)
+ self.spectatorspeed = bound(1, self.spectatorspeed - 0.5, 5);
+ else if(self.impulse >= 1 && self.impulse <= 9)
+ self.spectatorspeed = 1 + 0.5 * (self.impulse - 1);
+ } // otherwise just clear
+ self.impulse = 0;
+ print("impulse\n");
+ }
+ maxspd_mod = self.spectatorspeed;
+ }
spd = sv_maxspeed * maxspd_mod * swampspd_mod;
Modified: trunk/data/qcsrc/server/miscfunctions.qc
===================================================================
--- trunk/data/qcsrc/server/miscfunctions.qc 2008-08-17 13:35:05 UTC (rev 4135)
+++ trunk/data/qcsrc/server/miscfunctions.qc 2008-08-21 15:32:44 UTC (rev 4136)
@@ -110,6 +110,8 @@
}
string STR_PLAYER = "player";
+string STR_SPECTATOR = "spectator";
+string STR_OBSERVER = "observer";
#if 0
#define FOR_EACH_CLIENT(v) for(v = world; (v = findflags(v, flags, FL_CLIENT)) != world; )
@@ -1137,3 +1139,21 @@
ambientsound ('0 0 0', self.noise, VOL_BASE, ATTN_NONE);
}
}
+
+#define WRITESPECTATABLE_MSG_ONE_VARNAME(varname,statement) \
+ entity varname; \
+ varname = msg_entity; \
+ FOR_EACH_REALCLIENT(msg_entity) \
+ if(msg_entity == varname || (msg_entity.classname == STR_SPECTATOR && msg_entity.enemy == varname)) \
+ statement \
+ msg_entity = varname
+#define WRITESPECTATABLE_MSG_ONE(statement) \
+ WRITESPECTATABLE_MSG_ONE_VARNAME(oldmsg_entity, statement)
+#define WRITESPECTATABLE(msg,statement) \
+ if(msg == MSG_ONE) \
+ { \
+ WRITESPECTATABLE_MSG_ONE(statement); \
+ } \
+ else \
+ statement \
+ float WRITESPECTATABLE_workaround = 0
Modified: trunk/data/qcsrc/server/race.qc
===================================================================
--- trunk/data/qcsrc/server/race.qc 2008-08-17 13:35:05 UTC (rev 4135)
+++ trunk/data/qcsrc/server/race.qc 2008-08-21 15:32:44 UTC (rev 4136)
@@ -38,9 +38,6 @@
string recordholder;
float cp;
- if(clienttype(e) != CLIENTTYPE_REAL)
- return;
-
if(!e.race_laptime)
return;
@@ -55,12 +52,14 @@
recordholder = "";
msg_entity = e;
- WriteByte(MSG_ONE, SVC_TEMPENTITY);
- WriteByte(MSG_ONE, TE_CSQC_RACE);
- WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_NEXT_QUALIFYING);
- WriteByte(MSG_ONE, cp); // checkpoint the player will be at next
- WriteShort(MSG_ONE, recordtime);
- WriteString(MSG_ONE, recordholder);
+ WRITESPECTATABLE_MSG_ONE({
+ WriteByte(MSG_ONE, SVC_TEMPENTITY);
+ WriteByte(MSG_ONE, TE_CSQC_RACE);
+ WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_NEXT_QUALIFYING);
+ WriteByte(MSG_ONE, cp); // checkpoint the player will be at next
+ WriteShort(MSG_ONE, recordtime);
+ WriteString(MSG_ONE, recordholder);
+ });
}
void race_SendTime(entity e, float cp, float t, float tvalid)
@@ -95,11 +94,13 @@
e.race_completed = 1;
MAKE_INDEPENDENT_PLAYER(e);
bprint(e.netname, "^7 has finished the race.\n");
+ // TODO support spectators with this (e.g. set a flag for forced sbar)
if(clienttype(e) == CLIENTTYPE_REAL)
{
msg_entity = e;
WriteByte(MSG_ONE, SVC_TEMPENTITY);
WriteByte(MSG_ONE, TE_CSQC_FORCESCOREBOARD);
+ WriteByte(MSG_ONE, 1);
// he can still move, but will see the scoreboard now
}
}
@@ -173,11 +174,10 @@
recordholder = "";
}
- if(clienttype(e) == CLIENTTYPE_REAL)
+ msg_entity = e;
+ if(g_race_qualifying)
{
- msg_entity = e;
- if(g_race_qualifying)
- {
+ WRITESPECTATABLE_MSG_ONE({
WriteByte(MSG_ONE, SVC_TEMPENTITY);
WriteByte(MSG_ONE, TE_CSQC_RACE);
WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_QUALIFYING);
@@ -185,7 +185,7 @@
WriteShort(MSG_ONE, t); // time to that intermediate
WriteShort(MSG_ONE, recordtime); // previously best time
WriteString(MSG_ONE, recordholder); // record holder
- }
+ });
}
}
else // RACE! Not Qualifying
@@ -202,9 +202,8 @@
else
lself = lother = othtime = 0;
- if(clienttype(e) == CLIENTTYPE_REAL)
- {
- msg_entity = e;
+ msg_entity = e;
+ WRITESPECTATABLE_MSG_ONE({
WriteByte(MSG_ONE, SVC_TEMPENTITY);
WriteByte(MSG_ONE, TE_CSQC_RACE);
WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_RACE);
@@ -221,16 +220,14 @@
WriteByte(MSG_ONE, lself - lother);
WriteString(MSG_ONE, oth.netname); // record holder
}
- }
+ });
race_checkpoint_lastplayers[cp] = e;
race_checkpoint_lasttimes[cp] = time;
race_checkpoint_lastlaps[cp] = lself;
- if(clienttype(oth) == CLIENTTYPE_REAL)
- if(oth.flags & FL_CLIENT)
- {
- msg_entity = oth;
+ msg_entity = oth;
+ WRITESPECTATABLE_MSG_ONE({
WriteByte(MSG_ONE, SVC_TEMPENTITY);
WriteByte(MSG_ONE, TE_CSQC_RACE);
WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_RACE_BY_OPPONENT);
@@ -247,7 +244,7 @@
WriteByte(MSG_ONE, lother - lself);
WriteString(MSG_ONE, e.netname); // record holder
}
- }
+ });
}
}
@@ -256,13 +253,12 @@
e.race_checkpoint = -1;
e.race_laptime = 0;
- if(clienttype(e) != CLIENTTYPE_REAL)
- return;
-
msg_entity = e;
- WriteByte(MSG_ONE, SVC_TEMPENTITY);
- WriteByte(MSG_ONE, TE_CSQC_RACE);
- WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_CLEAR); // next
+ WRITESPECTATABLE_MSG_ONE({
+ WriteByte(MSG_ONE, SVC_TEMPENTITY);
+ WriteByte(MSG_ONE, TE_CSQC_RACE);
+ WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_CLEAR); // next
+ });
}
void checkpoint_touch()
@@ -378,11 +374,13 @@
self.race_completed = 1;
MAKE_INDEPENDENT_PLAYER(self);
bprint(self.netname, "^7 has abandoned the race.\n");
+ // TODO support spectators with this (e.g. set a flag for forced sbar)
if(clienttype(self) == CLIENTTYPE_REAL)
{
msg_entity = self;
WriteByte(MSG_ONE, SVC_TEMPENTITY);
WriteByte(MSG_ONE, TE_CSQC_FORCESCOREBOARD);
+ WriteByte(MSG_ONE, 1);
// he can still move, but will see the scoreboard now
}
}
Modified: trunk/data/qcsrc/server/teamplay.qc
===================================================================
--- trunk/data/qcsrc/server/teamplay.qc 2008-08-17 13:35:05 UTC (rev 4135)
+++ trunk/data/qcsrc/server/teamplay.qc 2008-08-21 15:32:44 UTC (rev 4136)
@@ -344,7 +344,7 @@
cvar_set("timelimit", ftos(timelimit_override));
}
- if(g_race_qualifying)
+ if(g_race && g_race_qualifying)
{
race_fraglimit = cvar("fraglimit");
cvar_set("fraglimit", "0");
@@ -407,37 +407,16 @@
if(!self.BUTTON_INFO)
{
- if(self.classname == "observer")
- {
- if(g_lms)
- {
- p = PlayerScore_Add(self, SP_LMS_RANK, 0);
- if(p >= 666)
- return centerprint_atprio(self, CENTERPRIO_SPAM, strcat(NEWLINES, "^1Match has already begun\nwait for next round\n\n\n^7press attack to spectate other players"));
- else if(p > 0)
- return centerprint_atprio(self, CENTERPRIO_SPAM, strcat(NEWLINES, "^1You have no more lives left\nwait for next round\n\n\n^7press attack to spectate other players"));
- }
- }
- else if(self.classname == "spectator")
- {
- if(g_lms)
- {
- p = PlayerScore_Add(self, SP_LMS_RANK, 0);
- if(p)
- return centerprint_atprio(self, CENTERPRIO_SPAM, strcat(NEWLINES, "spectating ", self.enemy.netname, "\n\n\n^7press attack for next player\npress attack2 for free fly mode"));
- }
- if (g_arena)
- return centerprint_atprio(self, CENTERPRIO_SPAM, strcat(NEWLINES, "spectating ", self.enemy.netname, "\n\n\n^7press attack for next player\npress attack2 for free fly mode"));
-
- local string specString;
- specString = strcat(NEWLINES, "spectating ", self.enemy.netname, "\n\n\n^7press jump to play\n^7press attack for next player\npress attack2 for free fly mode");
-
- if(time < restart_countdown) //also show the countdown when being a spectator
- specString = strcat(specString, "\n\n^1Game starts in ", ftos(restartAnnouncer.cnt + 1), " seconds^7");
- else if (timeoutStatus != 0)
- specString = strcat(specString, "\n\n", getTimeoutText(1));
- return centerprint_atprio(self, CENTERPRIO_SPAM, specString);
- }
+ // TODO get rid of this too
+ local string specString;
+ specString = NEWLINES;
+ if(time < restart_countdown) //also show the countdown when being a spectator
+ specString = strcat(specString, "\n\n^1Game starts in ", ftos(restartAnnouncer.cnt + 1), " seconds^7");
+ else if (timeoutStatus != 0)
+ specString = strcat(specString, "\n\n", getTimeoutText(1));
+ else
+ return;
+ return centerprint_atprio(self, CENTERPRIO_SPAM, specString);
}
if(g_minstagib)
More information about the nexuiz-commits
mailing list