WriteByte(MSG_BROADCAST, TE_CSQC_TEAMNAGGER);
}
-float ClientData_Send(entity to, int sf)
+int CountSpectators(entity player, entity to)
+{
+ if(!player) { return 0; } // not sure how, but best to be safe
+
+ entity head;
+ float spec_count = 0;
+ FOR_EACH_REALCLIENT(head)
+ {
+ if(IS_SPEC(head))
+ if(head != to)
+ if(head.enemy == player)
+ spec_count += 1;
+ }
+
+ return spec_count;
+}
+
+void WriteSpectators(entity player, entity to)
+{
+ if(!player) { return; } // not sure how, but best to be safe
+
+ entity head;
+ FOR_EACH_REALCLIENT(head)
+ {
+ if(IS_SPEC(head))
+ if(head != to)
+ if(head.enemy == player)
+ WriteByte(MSG_ENTITY, num_for_edict(head));
+ }
+}
+
+bool ClientData_Send(entity to, int sf)
{
if(to != self.owner)
{
sf |= 4; // zoomed
if(e.porto_v_angle_held)
sf |= 8; // angles held
+ // always check spectators
+ sf |= 16; // spectator handling?
WriteByte(MSG_ENTITY, ENT_CLIENT_CLIENTDATA);
WriteByte(MSG_ENTITY, sf);
WriteAngle(MSG_ENTITY, e.v_angle.y);
}
+ if(sf & 16)
+ {
+ float specs = CountSpectators(e, to);
+ WriteByte(MSG_ENTITY, specs);
+ WriteSpectators(e, to);
+ }
+
return true;
}
void FixPlayermodel();
void PutObserverInServer (void)
{
- entity spot;
+ entity spot;
+
+ SetSpectator(self, world);
+
self.hud = HUD_NORMAL;
if(IS_PLAYER(self)) { pointparticles(particleeffectnum("spawn_event_neutral"), self.origin, '0 0 0', 1); }
PlayerStats_GameReport_FinalizePlayer(self);
+ SetSpectator(self, world);
+
if(IS_PLAYER(self)) { pointparticles(particleeffectnum("spawn_event_neutral"), self.origin, '0 0 0', 1); }
CheatShutdownClient();
float SpectateSet()
{
- if(self.enemy.classname != "player")
+ if(!IS_PLAYER(self.enemy))
return false;
- /*if(self.enemy.vehicle)
- {
- msg_entity = self;
- WriteByte(MSG_ONE, SVC_SETVIEW);
- WriteEntity(MSG_ONE, self.enemy);
- //stuffcmd(self, "set viewsize $tmpviewsize \n");
+ ClientData_Touch(self.enemy);
- self.movetype = MOVETYPE_NONE;
- accuracy_resend(self);
- }
- else
- {*/
- msg_entity = self;
- WriteByte(MSG_ONE, SVC_SETVIEW);
- WriteEntity(MSG_ONE, self.enemy);
- //stuffcmd(self, "set viewsize $tmpviewsize \n");
- self.movetype = MOVETYPE_NONE;
- accuracy_resend(self);
+ msg_entity = self;
+ WriteByte(MSG_ONE, SVC_SETVIEW);
+ WriteEntity(MSG_ONE, self.enemy);
+ //stuffcmd(self, "set viewsize $tmpviewsize \n");
+ self.movetype = MOVETYPE_NONE;
+ accuracy_resend(self);
+
+ if(!SpectateUpdate())
+ PutObserverInServer();
- if(!SpectateUpdate())
- PutObserverInServer();
- //}
return true;
}
// these are required to fix the spectator bug with arc
if(old_spectatee && old_spectatee.arc_beam) { old_spectatee.arc_beam.SendFlags |= ARC_SF_SETTINGS; }
if(player.enemy && player.enemy.arc_beam) { player.enemy.arc_beam.SendFlags |= ARC_SF_SETTINGS; }
+
+ // needed to update spectator list
+ if(old_spectatee) { ClientData_Touch(old_spectatee); }
}
float Spectate(entity pl)
{
if(g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer)
- if(pl.team != self.team)
+ if(DIFF_TEAM(pl, self))
return 0;
SetSpectator(self, pl);
}
// Returns next available player to spectate if g_ca_spectate_enemies == 0
-entity CA_SpectateNext(entity start) {
- if (start.team == self.team) {
- return start;
- }
+entity CA_SpectateNext(entity start)
+{
+ if(SAME_TEAM(start, self)) { return start; }
other = start;
// continue from current player
- while(other && other.team != self.team) {
+ while(other && DIFF_TEAM(other, self))
other = find(other, classname, "player");
- }
- if (!other) {
+ if (!other)
+ {
// restart from begining
other = find(other, classname, "player");
- while(other && other.team != self.team) {
+ while(other && DIFF_TEAM(other, self))
other = find(other, classname, "player");
- }
}
return other;
{
other = find(self.enemy, classname, "player");
- if (g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer) {
+ if (g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer)
+ {
// CA and ca players when spectating enemies is forbidden
other = CA_SpectateNext(other);
- } else {
+ }
+ else
+ {
// other modes and ca spectators or spectating enemies is allowed
if (!other)
other = find(other, classname, "player");
self.classname = "player";
nades_RemoveBonus(self);
+ SetSpectator(self, world);
+
if(autocvar_g_campaign || autocvar_g_balance_teams)
{ JoinBestTeam(self, false, true); }
// Savage: Check for nameless players
if (isInvisibleString(self.netname)) {
- string new_name = strzone(strcat("Player@", self.netaddress));
+ string new_name = strzone(strcat("Player@", ftos(self.playerid)));
if(autocvar_sv_eventlog)
GameLogEcho(strcat(":name:", ftos(self.playerid), ":", new_name));
if(self.netname_previous)