]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/cl_client.qc
Merge branch 'master' into mirceakitsune/universal_reload_system
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / cl_client.qc
index 348779dba9e124fb3e8d1ef4d77f8fdc80b5d3f7..c5312469a892864b6dc231f92fc76831a4813da9 100644 (file)
@@ -1050,8 +1050,16 @@ void PutClientInServer (void)
 
                // reset fields the weapons may use
                for (j = WEP_FIRST; j <= WEP_LAST; ++j)
+               {
                        weapon_action(j, WR_RESETPLAYER);
 
+                       // all weapons must be fully loaded when we spawn
+                       entity e;
+                       e = get_weaponinfo(j);
+                       if(e.spawnflags & WEP_FLAG_RELOADABLE) // prevent accessing undefined cvars
+                               self.weapon_load[j] = cvar(strcat("g_balance_", e.netname, "_reload_ammo"));
+               }
+
                oldself = self;
                self = spot;
                        activator = oldself;
@@ -1065,8 +1073,6 @@ void PutClientInServer (void)
                self.cnt = self.switchweapon;
                self.weapon = 0;
 
-        self.wish_reload = 0;
-
                if(!self.alivetime)
                        self.alivetime = time;
        } else if(self.classname == "observer" || (g_ca && !allowed_to_spawn)) {
@@ -1109,7 +1115,6 @@ float ClientInit_SendEntity(entity to, float sf)
        WriteByte(MSG_ENTITY, autocvar_g_balance_nex_secondary); // client has to know if it should zoom or not
        WriteByte(MSG_ENTITY, autocvar_g_balance_sniperrifle_secondary); // client has to know if it should zoom or not
        WriteByte(MSG_ENTITY, serverflags); // client has to know if it should zoom or not
-       WriteByte(MSG_ENTITY, autocvar_g_balance_sniperrifle_magazinecapacity); // rifle max bullets
        WriteCoord(MSG_ENTITY, autocvar_g_trueaim_minrange);
        return TRUE;
 }
@@ -2043,7 +2048,7 @@ void player_powerups (void)
                self.modelflags &~= MF_ROCKET;
        }
 
-       self.effects &~= (EF_RED | EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT | EF_FLAME | EF_NODEPTHTEST);
+       self.effects &~= (EF_DIMLIGHT | EF_RED | EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT | EF_FLAME | EF_NODEPTHTEST);
 
        if(!self.modelindex || self.deadflag) // don't apply the flags if the player is gibbed
                return;
@@ -2341,11 +2346,14 @@ void SpectateCopy(entity spectatee) {
        self.ammo_nails = spectatee.ammo_nails;
        self.ammo_rockets = spectatee.ammo_rockets;
        self.ammo_fuel = spectatee.ammo_fuel;
+       self.clip_load = spectatee.clip_load;
+       self.clip_size = spectatee.clip_size;
        self.effects = spectatee.effects & EFMASK_CHEAP; // eat performance
        self.health = spectatee.health;
        self.impulse = 0;
        self.items = spectatee.items;
        self.last_pickup = spectatee.last_pickup;
+       self.hit_time = spectatee.hit_time;
        self.metertime = spectatee.metertime;
        self.strength_finished = spectatee.strength_finished;
        self.invincible_finished = spectatee.invincible_finished;
@@ -2438,7 +2446,7 @@ void ShowRespawnCountdown()
 
 void LeaveSpectatorMode()
 {
-       if(isJoinAllowed()) {
+       if(nJoinAllowed(1)) {
                if(!teams_matter || autocvar_g_campaign || autocvar_g_balance_teams || (self.wasplayer && autocvar_g_changeteam_banned) || self.team_forced > 0) {
                        self.classname = "player";
 
@@ -2475,25 +2483,30 @@ void LeaveSpectatorMode()
  * Determines whether the player is allowed to join. This depends on cvar
  * g_maxplayers, if it isn't used this function always return TRUE, otherwise
  * it checks whether the number of currently playing players exceeds g_maxplayers.
- * @return bool TRUE if the player is allowed to join, false otherwise
+ * @return int number of free slots for players, 0 if none
  */
-float isJoinAllowed() {
+float nJoinAllowed(float includeMe) {
        if(self.team_forced < 0)
                return FALSE; // forced spectators can never join
 
+       // TODO simplify this
+       local entity e;
+
+       local float totalClients;
+       FOR_EACH_CLIENT(e)
+               totalClients += 1;
+
        if (!autocvar_g_maxplayers)
-               return TRUE;
+               return maxclients - totalClients + includeMe;
 
-       local entity e;
        local float currentlyPlaying;
-       FOR_EACH_REALPLAYER(e) {
-               if(e.classname == "player")
-                       currentlyPlaying += 1;
-       }
+       FOR_EACH_REALPLAYER(e)
+               currentlyPlaying += 1;
+
        if(currentlyPlaying < autocvar_g_maxplayers)
-               return TRUE;
+               return min(maxclients - totalClients + includeMe, autocvar_g_maxplayers - currentlyPlaying);
 
-       return FALSE;
+       return 0;
 }
 
 /**
@@ -2937,6 +2950,10 @@ void PlayerPreThink (void)
        }
 
        target_voicescript_next(self);
+
+       // if a player goes unarmed after holding a loaded weapon, empty his clip size and remove the crosshair ammo ring
+       if(!self.weapon)
+               self.clip_load = self.clip_size = 0;
 }
 
 float isInvisibleString(string s)
@@ -3090,7 +3107,7 @@ void PlayerPostThink (void)
 
        playerdemo_write();
 
-       if((g_cts || g_race) && self.cvar_cl_allow_uid2name == 1)
+       if((g_cts || g_race) && self.cvar_cl_allow_uidtracking == 1 && self.cvar_cl_allow_uid2name == 1)
        {
                if(!self.stored_netname)
                        self.stored_netname = strzone(uid2name(self.crypto_idfp));