From eae4c929db000c8a3649b366f04b111784db9158 Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 16 Oct 2013 13:57:25 +1100 Subject: [PATCH] Add an option to show spectators watching you --- defaultXonotic.cfg | 3 +++ qcsrc/client/Main.qc | 17 +++++++++++++++++ qcsrc/client/autocvars.qh | 1 + qcsrc/client/hud.qc | 16 ++++++++++++++++ qcsrc/client/main.qh | 4 ++++ qcsrc/common/constants.qh | 1 + qcsrc/server/autocvars.qh | 1 + qcsrc/server/cl_client.qc | 40 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 83 insertions(+) diff --git a/defaultXonotic.cfg b/defaultXonotic.cfg index d967d53d5..2d0d242db 100644 --- a/defaultXonotic.cfg +++ b/defaultXonotic.cfg @@ -1572,3 +1572,6 @@ set cl_simpleitems_postfix "_simple" "posfix to add fo model name when simple it set cl_fullbright_items 0 "enable fullbright items (if server allows, controled by g_fullbrightitems)" set cl_weapon_stay_color "2 0.5 0.5" "Color of picked up weapons when g_weapon_stay > 0" set cl_weapon_stay_alpha 0.75 "Alpha of picked up weapons when g_weapon_stay > 0" + +set sv_showspectators 0 +set cl_showspectators 1 diff --git a/qcsrc/client/Main.qc b/qcsrc/client/Main.qc index 8e36cc9b5..be6c05950 100644 --- a/qcsrc/client/Main.qc +++ b/qcsrc/client/Main.qc @@ -1187,6 +1187,19 @@ void Net_WeaponComplain() } } +void Net_ReadSpecInfo() +{ + float i; + + num_spectators = ReadByte(); + for(i = 0; i < num_spectators; ++i) + { + local float slot = ReadByte(); + if(i < MAX_SPECTATORS) + spectatorlist[i] = slot - 1; + } +} + // 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. @@ -1248,6 +1261,10 @@ float CSQC_Parse_TempEntity() cl_notice_read(); bHandled = true; break; + case TE_CSQC_SPECINFO: + Net_ReadSpecInfo(); + bHandled = true; + break; default: // No special logic for this temporary entity; return 0 so the engine can handle it bHandled = false; diff --git a/qcsrc/client/autocvars.qh b/qcsrc/client/autocvars.qh index 8175695ab..36b3a5449 100644 --- a/qcsrc/client/autocvars.qh +++ b/qcsrc/client/autocvars.qh @@ -427,3 +427,4 @@ string autocvar__cl_playermodel; float autocvar_cl_deathglow; float autocvar_developer_csqcentities; float autocvar_g_jetpack_attenuation; +float autocvar_cl_showspectators; diff --git a/qcsrc/client/hud.qc b/qcsrc/client/hud.qc index 398078ace..29c741e3b 100644 --- a/qcsrc/client/hud.qc +++ b/qcsrc/client/hud.qc @@ -3736,6 +3736,22 @@ void HUD_InfoMessages(void) s = _("^2Currently in ^1warmup^2 stage!"); drawInfoMessage(s) } + + if(autocvar_cl_showspectators) + if(num_spectators) + if not(spectatee_status) + { + s = _("^1Spectating you:"); + drawInfoMessage(s) + float limit = min(num_spectators, MAX_SPECTATORS); + float i; + for(i = 0; i < limit; ++i) + { + float slot = spectatorlist[i]; + s = strcat("^3", GetPlayerName(slot)); + drawInfoMessage(s) + } + } string blinkcolor; if(mod(time, 1) >= 0.5) diff --git a/qcsrc/client/main.qh b/qcsrc/client/main.qh index 815c20a33..ce4f09a44 100644 --- a/qcsrc/client/main.qh +++ b/qcsrc/client/main.qh @@ -147,3 +147,7 @@ entity entcs_receiver[255]; // 255 is the engine limit on maxclients float hud; float view_quality; float framecount; + +float num_spectators; +#define MAX_SPECTATORS 7 +float spectatorlist[MAX_SPECTATORS]; diff --git a/qcsrc/common/constants.qh b/qcsrc/common/constants.qh index b3dafaaf7..15d1a2c93 100644 --- a/qcsrc/common/constants.qh +++ b/qcsrc/common/constants.qh @@ -42,6 +42,7 @@ const float TE_CSQC_MINELAYER_MAXMINES = 110; const float TE_CSQC_HAGAR_MAXROCKETS = 111; const float TE_CSQC_VEHICLESETUP = 112; const float TE_CSQC_SVNOTICE = 113; +const float TE_CSQC_SPECINFO = 114; const float RACE_NET_CHECKPOINT_HIT_QUALIFYING = 0; // byte checkpoint, short time, short recordtime, string recordholder const float RACE_NET_CHECKPOINT_CLEAR = 1; diff --git a/qcsrc/server/autocvars.qh b/qcsrc/server/autocvars.qh index 759aea6ad..220855610 100644 --- a/qcsrc/server/autocvars.qh +++ b/qcsrc/server/autocvars.qh @@ -1254,3 +1254,4 @@ float autocvar_g_campcheck_damage; float autocvar_g_campcheck_distance; float autocvar_g_campcheck_interval; float autocvar_g_jump_grunt; +float autocvar_sv_showspectators; diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index fac4314ca..a61a2a53e 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -136,6 +136,7 @@ putting a client as observer in the server ============= */ void FixPlayermodel(); +void UpdateSpectators(entity is_spec, entity is_player); void PutObserverInServer (void) { entity spot; @@ -153,6 +154,8 @@ void PutObserverInServer (void) WriteByte(MSG_ONE, SVC_SETVIEW); WriteEntity(MSG_ONE, self); } + + UpdateSpectators(self, self); // don't update spectators or spectatees if((g_race && g_race_qualifying) || g_cts) { @@ -609,6 +612,8 @@ void PutClientInServer (void) { PutObserverInServer (); } + + UpdateSpectators(((IS_PLAYER(self)) ? world : self), ((IS_SPEC(self) || IS_OBSERVER(self)) ? self : world)); } .float ebouncefactor, ebouncestop; // electro's values @@ -1246,6 +1251,8 @@ Called when a client disconnects from the server void ReadyCount(); void ClientDisconnect (void) { + UpdateSpectators(self, world); + if(self.vehicle) vehicles_exit(VHEF_RELESE); @@ -1767,13 +1774,42 @@ float SpectateUpdate() { return 0; if not(IS_PLAYER(self.enemy)) + { + self.enemy = world; return 0; + } SpectateCopy(self.enemy); return 1; } +void UpdateSpectators(entity is_spec, entity is_player) +{ + entity head, spec; + float specs = 0; + FOR_EACH_REALCLIENT(head) + { + msg_entity = head; + WriteByte(MSG_ONE, SVC_TEMPENTITY); + WriteByte(MSG_ONE, TE_CSQC_SPECINFO); + + specs = 0; + + FOR_EACH_SPEC(spec) if(spec.enemy == head && is_player != spec && spec != is_player) + ++specs; + + if(IS_SPEC(head) || IS_OBSERVER(head) || head == is_spec || !autocvar_sv_showspectators) + { + WriteByte(MSG_ONE, 0); + continue; + } + + WriteByte(MSG_ONE, specs); + FOR_EACH_SPEC(spec) if(spec.enemy == head && is_player != spec) + WriteByte(MSG_ONE, num_for_edict(spec)); + } +} float SpectateSet() { @@ -1852,7 +1888,10 @@ float SpectateNext() } if (other) + { self.enemy = other; + UpdateSpectators(world, world); + } return SpectateSet(); } @@ -1892,6 +1931,7 @@ float SpectatePrev() other = first; } self.enemy = other; + UpdateSpectators(world, world); return SpectateSet(); } -- 2.39.2