Merge branch 'master' into Mario/showspecs
authorMario <zacjardine@y7mail.com>
Tue, 14 Apr 2015 22:59:14 +0000 (08:59 +1000)
committerMario <zacjardine@y7mail.com>
Tue, 14 Apr 2015 22:59:14 +0000 (08:59 +1000)
Conflicts:
defaultXonotic.cfg
qcsrc/client/autocvars.qh
qcsrc/client/main.qc
qcsrc/client/main.qh
qcsrc/common/constants.qh
qcsrc/server/autocvars.qh
qcsrc/server/cl_client.qc

defaultXonotic.cfg
qcsrc/client/autocvars.qh
qcsrc/client/hud.qc
qcsrc/client/main.qc
qcsrc/client/main.qh
qcsrc/server/cl_client.qc

index 4f02d14..4d3c1fe 100644 (file)
@@ -1432,7 +1432,12 @@ set cl_fullbright_items 0 "enable fullbright items (if server allows, controled
 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"
 
+<<<<<<< HEAD
+set sv_showspectators 0
+set cl_showspectators 1
+=======
 // Facility for config.cfg use ONLY.
 // Interpreted in post-config.cfg.
 seta menu_forced_saved_cvars "" "These cvars will always be saved, despite engine/Xonotic cvar saving status"
 set menu_reverted_nonsaved_cvars "" "These cvars are currently marked as saved in the flags, but have been reverted and won't stay saved. INTERNAL USE ONLY."
+>>>>>>> master
index e35bf82..488115f 100644 (file)
@@ -460,6 +460,7 @@ string autocvar__cl_playermodel;
 float autocvar_cl_deathglow;
 bool autocvar_developer_csqcentities;
 float autocvar_g_jetpack_attenuation;
+bool autocvar_cl_showspectators;
 string autocvar_crosshair_hmg = "";
 vector autocvar_crosshair_hmg_color = '0.2 1.0 0.2';
 float autocvar_crosshair_hmg_alpha = 1;
index 74a5df1..2aaa81b 100644 (file)
@@ -3833,6 +3833,25 @@ void HUD_InfoMessages(void)
                        drawInfoMessage(s);
                }
 
+               if(autocvar_cl_showspectators)
+               if(num_spectators)
+               //if(spectatee_status != -1)
+               {
+                       s = ((spectatee_status) ? _("^1Spectating this player:") : _("^1Spectating you:"));
+                       //drawInfoMessage(s)
+                       float limit = min(num_spectators, MAX_SPECTATORS);
+                       float i;
+                       for(i = 0; i < limit; ++i)
+                       {
+                               float slot = spectatorlist[i];
+                               if(i == 0)
+                                       s = strcat(s, " ^3", GetPlayerName(slot));
+                               else
+                                       s = strcat("^3", GetPlayerName(slot));
+                               drawInfoMessage(s);
+                       }
+               }
+
                string blinkcolor;
                if(time % 1 >= 0.5)
                        blinkcolor = "^1";
index 36ec4f7..71198eb 100644 (file)
@@ -515,6 +515,22 @@ void Ent_ClientData()
        else
                angles_held_status = 0;
 
+       if(f & 16)
+       {
+               num_spectators = ReadByte();
+
+               float i, slot;
+
+               for(i = 0; i < MAX_SPECTATORS; ++i)
+                       spectatorlist[i] = 0; // reset list first
+
+               for(i = 0; i < num_spectators; ++i)
+               {
+                       slot = ReadByte();
+                       spectatorlist[i] = slot - 1;
+               }
+       }
+
        if(newspectatee_status != spectatee_status)
        {
                // clear race stuff
index b8823e6..bf0bb74 100644 (file)
@@ -148,5 +148,10 @@ entity entcs_receiver[255]; // 255 is the engine limit on maxclients
 
 float hud;
 float view_quality;
+
+int num_spectators;
+const int MAX_SPECTATORS = 7;
+int spectatorlist[MAX_SPECTATORS];
+
 int framecount;
 #endif
index 3bc5cc7..fe12ffc 100644 (file)
@@ -30,7 +30,38 @@ void send_CSQC_teamnagger() {
        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)
        {
@@ -54,6 +85,8 @@ float ClientData_Send(entity to, int sf)
                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);
@@ -67,6 +100,13 @@ float ClientData_Send(entity to, int 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;
 }
 
@@ -164,7 +204,10 @@ putting a client as observer in the server
 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); }
@@ -1280,6 +1323,8 @@ void ClientDisconnect (void)
 
        PlayerStats_GameReport_FinalizePlayer(self);
 
+       SetSpectator(self, world);
+
        if(IS_PLAYER(self)) { pointparticles(particleeffectnum("spawn_event_neutral"), self.origin, '0 0 0', 1); }
 
        CheatShutdownClient();
@@ -1812,31 +1857,21 @@ float SpectateUpdate()
 
 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;
 }
 
@@ -1850,12 +1885,15 @@ void SetSpectator(entity player, entity spectatee)
        // 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);
@@ -1863,23 +1901,21 @@ float Spectate(entity 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;
@@ -1889,10 +1925,13 @@ float SpectateNext()
 {
        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");
@@ -1978,6 +2017,8 @@ void LeaveSpectatorMode()
                        self.classname = "player";
                        nades_RemoveBonus(self);
 
+                       SetSpectator(self, world);
+
                        if(autocvar_g_campaign || autocvar_g_balance_teams)
                                { JoinBestTeam(self, false, true); }
 
@@ -2258,7 +2299,7 @@ void PlayerPreThink (void)
 
        // 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)