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
}
}
+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.
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;
float autocvar_cl_deathglow;
float autocvar_developer_csqcentities;
float autocvar_g_jetpack_attenuation;
+float autocvar_cl_showspectators;
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)
float hud;
float view_quality;
float framecount;
+
+float num_spectators;
+#define MAX_SPECTATORS 7
+float spectatorlist[MAX_SPECTATORS];
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;
float autocvar_g_campcheck_distance;
float autocvar_g_campcheck_interval;
float autocvar_g_jump_grunt;
+float autocvar_sv_showspectators;
=============
*/
void FixPlayermodel();
+void UpdateSpectators(entity is_spec, entity is_player);
void PutObserverInServer (void)
{
entity spot;
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)
{
{
PutObserverInServer ();
}
+
+ UpdateSpectators(((IS_PLAYER(self)) ? world : self), ((IS_SPEC(self) || IS_OBSERVER(self)) ? self : world));
}
.float ebouncefactor, ebouncestop; // electro's values
void ReadyCount();
void ClientDisconnect (void)
{
+ UpdateSpectators(self, world);
+
if(self.vehicle)
vehicles_exit(VHEF_RELESE);
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()
{
}
if (other)
+ {
self.enemy = other;
+ UpdateSpectators(world, world);
+ }
return SpectateSet();
}
other = first;
}
self.enemy = other;
+ UpdateSpectators(world, world);
return SpectateSet();
}