WriteHeader(MSG_BROADCAST, TE_CSQC_TEAMNAGGER);
}
+int CountSpectators(entity player, entity to)
+{
+ if(!player) { return 0; } // not sure how, but best to be safe
+
+ int spec_count = 0;
+
+ FOREACH_CLIENT(IS_REAL_CLIENT(it) && IS_SPEC(it) && it != to && it.enemy == player,
+ {
+ spec_count++;
+ });
+
+ return spec_count;
+}
+
+void WriteSpectators(entity player, entity to)
+{
+ if(!player) { return; } // not sure how, but best to be safe
+
+ FOREACH_CLIENT(IS_REAL_CLIENT(it) && IS_SPEC(it) && it != to && it.enemy == player,
+ {
+ WriteByte(MSG_ENTITY, num_for_edict(it));
+ });
+}
+
bool ClientData_Send(entity this, entity to, int sf)
{
assert(to == this.owner, return false);
if (to.spectatee_status) sf |= 2; // spectator ent number follows
if (e.zoomstate) sf |= 4; // zoomed
if (e.porto_v_angle_held) sf |= 8; // angles held
+ sf |= 16; // always check spectators
WriteHeader(MSG_ENTITY, ENT_CLIENT_CLIENTDATA);
WriteByte(MSG_ENTITY, sf);
WriteAngle(MSG_ENTITY, e.v_angle.x);
WriteAngle(MSG_ENTITY, e.v_angle.y);
}
+
+ if(sf & 16)
+ {
+ float specs = CountSpectators(e, to);
+ WriteByte(MSG_ENTITY, specs);
+ WriteSpectators(e, to);
+ }
+
return true;
}
RemoveGrapplingHook(this);
Portal_ClearAll(this);
Unfreeze(this);
+ SetSpectatee(this, world);
if (this.alivetime)
{
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_QUIT_DISCONNECT, this.netname);
+ SetSpectatee(this, NULL);
+
MUTATOR_CALLHOOK(ClientDisconnect, this);
ClientState_detach(this);
if(!IS_PLAYER(this.enemy))
return false;
+ ClientData_Touch(this.enemy);
+
msg_entity = this;
WriteByte(MSG_ONE, SVC_SETVIEW);
WriteEntity(MSG_ONE, this.enemy);
// 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(this.enemy && this.enemy.arc_beam) { this.enemy.arc_beam.SendFlags |= ARC_SF_SETTINGS; }
+
+ // needed to update spectator list
+ if(old_spectatee) { ClientData_Touch(old_spectatee); }
}
bool Spectate(entity this, entity pl)
{
TRANSMUTE(Player, this);
+ SetSpectatee(self, world);
+
if(autocvar_g_campaign || autocvar_g_balance_teams)
{ JoinBestTeam(this, false, true); }