]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/cl_client.qc
Sync with master
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / cl_client.qc
index fed5100c0a1105a8b1cc26e1012cf600d9b60415..276a0e887a9e704e3799d18aeef19da99b2eda81 100644 (file)
@@ -132,9 +132,9 @@ vector Spawn_Score(entity spot, entity playerlist, float teamcheck, float anypoi
        prio = 0;
 
        // filter out spots for the wrong team
-       if(teamcheck)
-       if(spot.team != teamcheck)
-               return '-1 0 0';
+       if(teamcheck >= 0)
+               if(spot.team != teamcheck)
+                       return '-1 0 0';
 
        if(race_spawns)
                if(spot.target == "")
@@ -269,7 +269,7 @@ entity Spawn_FilterOutBadSpots(entity firstspot, entity playerlist, float mindis
                                        spotlist = spot;
 
                                /*
-                               if(teamcheck)
+                               if(teamcheck >= 0)
                                if(spot.team != teamcheck)
                                        error("invalid spawn added");
 
@@ -283,7 +283,7 @@ entity Spawn_FilterOutBadSpots(entity firstspot, entity playerlist, float mindis
 
        /*
                entity e;
-               if(teamcheck)
+               if(teamcheck >= 0)
                        for(e = spotlist; e; e = e.chain)
                        {
                                print("seen ", etos(e), "\n");
@@ -325,10 +325,15 @@ entity SelectSpawnPoint (float anypoint)
        if (spot)
                return spot;
 
-       teamcheck = 0;
-
-       if(!anypoint && have_team_spawns > 0)
-               teamcheck = self.team;
+       if(anypoint)
+               teamcheck = -1;
+       else if(have_team_spawns > 0)
+               teamcheck = self.team; // MUST be team
+       else if(have_team_spawns == 0 && have_noteam_spawns)
+               teamcheck = 0; // MUST be noteam
+       else
+               teamcheck = -1;
+               // if we get here, we either require team spawns but have none, or we require non-team spawns and have none; use any spawn then
 
        // get the list of players
        playerlist = findchain(classname, "player");
@@ -368,7 +373,7 @@ entity SelectSpawnPoint (float anypoint)
                print("spot mindistance: ", vtos(spot.spawnpoint_score), "\n");
 
                entity e;
-               if(teamcheck)
+               if(teamcheck >= 0)
                        for(e = firstspot; e; e = e.chain)
                                if(e.team != teamcheck)
                                        error("invalid spawn found");
@@ -1056,7 +1061,8 @@ void PutClientInServer (void)
                        // all weapons must be fully loaded when we spawn
                        entity e;
                        e = get_weaponinfo(j);
-                       self.weapon_load[j] = cvar(strcat("g_balance_", e.netname, "_reload_ammo"));
+                       if(e.spawnflags & WEP_FLAG_RELOADABLE) // prevent accessing undefined cvars
+                               self.weapon_load[j] = cvar(strcat("g_balance_", e.netname, "_reload_ammo"));
                }
 
                oldself = self;
@@ -1114,6 +1120,7 @@ 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_minelayer_limit); // minelayer max mines
        WriteCoord(MSG_ENTITY, autocvar_g_trueaim_minrange);
        return TRUE;
 }
@@ -1540,7 +1547,7 @@ void ClientConnect (void)
        playerdemo_init();
 
        anticheat_init();
-       
+
        race_PreSpawnObserver();
 
        //if(g_domination)
@@ -1759,6 +1766,15 @@ Called when a client disconnects from the server
 void ReadyCount();
 void ClientDisconnect (void)
 {
+       if(self.vehicle)
+       {
+           entity oldself;
+           oldself = self;
+           self = self.vehicle;
+           self.vehicle_exit(VHEF_RELESE);
+           self = oldself;
+       }
+
        if not(self.flags & FL_CLIENT)
        {
                print("Warning: ClientDisconnect without ClientConnect\n");
@@ -2035,7 +2051,7 @@ void player_powerups (void)
 {
        // add a way to see what the items were BEFORE all of these checks for the mutator hook
        olditems = self.items;
-       
+
        if((self.items & IT_USING_JETPACK) && !self.deadflag)
        {
                SoundEntity_StartSound(self, CHAN_PLAYER, "misc/jetpack_fly.wav", VOL_BASE, autocvar_g_jetpack_attenuation);
@@ -2051,7 +2067,7 @@ void player_powerups (void)
 
        if(!self.modelindex || self.deadflag) // don't apply the flags if the player is gibbed
                return;
-       
+
        Fire_ApplyDamage(self);
        Fire_ApplyEffect(self);
 
@@ -2157,7 +2173,7 @@ void player_powerups (void)
                if (time < self.spawnshieldtime)
                        self.effects = self.effects | (EF_ADDITIVE | EF_FULLBRIGHT);
        }
-       
+
        MUTATOR_CALLHOOK(PlayerPowerups);
 }
 
@@ -2352,6 +2368,7 @@ void SpectateCopy(entity spectatee) {
        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;
@@ -2359,6 +2376,9 @@ void SpectateCopy(entity spectatee) {
        self.weapons = spectatee.weapons;
        self.switchweapon = spectatee.switchweapon;
        self.weapon = spectatee.weapon;
+       self.nex_charge = spectatee.nex_charge;
+       self.nex_chargepool_ammo = spectatee.nex_chargepool_ammo;
+       self.minelayer_mines = spectatee.minelayer_mines;
        self.punchangle = spectatee.punchangle;
        self.view_ofs = spectatee.view_ofs;
        self.v_angle = spectatee.v_angle;
@@ -2373,6 +2393,23 @@ void SpectateCopy(entity spectatee) {
        SetZoomState(spectatee.zoomstate);
 
        anticheat_spectatecopy(spectatee);
+
+       //self.vehicle = spectatee.vehicle;
+
+       self.hud = spectatee.hud;
+       if(spectatee.vehicle)
+    {
+        self.vehicle_health = spectatee.vehicle_health;
+        self.vehicle_shield = spectatee.vehicle_shield;
+        self.vehicle_energy = spectatee.vehicle_energy;
+        self.vehicle_ammo1 = spectatee.vehicle_ammo1;
+        self.vehicle_ammo2 = spectatee.vehicle_ammo2;
+        self.vehicle_reload1 = spectatee.vehicle_reload1;
+        self.vehicle_reload2 = spectatee.vehicle_reload2;
+        msg_entity = self;
+        WriteByte (MSG_ONE, SVC_SETVIEWPORT);
+        WriteEntity(MSG_ONE, spectatee.vehicle.vehicle_viewport);
+    }
 }
 
 float SpectateUpdate() {
@@ -3082,7 +3119,7 @@ void PlayerPostThink (void)
 
        if(self.waypointsprite_attachedforcarrier)
                WaypointSprite_UpdateHealth(self.waypointsprite_attachedforcarrier, '1 0 0' * healtharmor_maxdamage(self.health, self.armorvalue, autocvar_g_balance_armor_blockpercent));
-       
+
        if(self.classname == "player" && self.deadflag == DEAD_NO && autocvar_r_showbboxes)
        {
                if(!self.showheadshotbbox)
@@ -3105,7 +3142,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));