]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/cl_client.qc
remove an unused arg
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / cl_client.qc
index 7bee1dbb4cb335e5d7c8fe5bd279dfbbd233286b..9d220fc12be68e80ee4ce303907f8cdcdb41e9d9 100644 (file)
@@ -118,12 +118,12 @@ void spawnpoint_use()
                self.team = activator.team;
                some_spawn_has_been_used = 1;
        }
-};
+}
 
 // Returns:
 //   _x: prio (-1 if unusable)
 //   _y: weight
-vector Spawn_Score(entity spot, entity playerlist, float teamcheck, float anypoint)
+vector Spawn_Score(entity spot, float mindist, float teamcheck)
 {
        float shortest, thisdist;
        float prio;
@@ -151,147 +151,80 @@ vector Spawn_Score(entity spot, entity playerlist, float teamcheck, float anypoi
                        return '-1 0 0';
        }
 
+       shortest = vlen(world.maxs - world.mins);
+       FOR_EACH_PLAYER(player) if (player != self)
+       {
+               thisdist = vlen(player.origin - spot.origin);
+               if (thisdist < shortest)
+                       shortest = thisdist;
+       }
+       if(shortest < mindist)
+               prio += SPAWN_PRIO_GOOD_DISTANCE;
+
+       spawn_score = prio * '1 0 0' + shortest * '0 1 0';
+       spawn_score_spot = spot;
+
        // filter out spots for assault
        if(spot.target != "") {
-               local entity ent;
-               float good, found;
-               ent = find(world, targetname, spot.target);
+               entity ent;
+               float found;
 
-               while(ent) {
-                       if(ent.classname == "target_objective")
-                       {
-                               found = 1;
-                               if(ent.health < 0 || ent.health >= ASSAULT_VALUE_INACTIVE)
-                                       return '-1 0 0';
-                               good = 1;
-                       }
-                       else if(ent.classname == "trigger_race_checkpoint")
+               found = 0;
+               for(ent = world; (ent = find(ent, targetname, spot.target)); )
+               {
+                       ++found;
+                       if(ent.spawn_evalfunc)
                        {
-                               found = 1;
-                               if(!anypoint) // spectators may spawn everywhere
-
-                               {
-                                       if(g_race_qualifying)
-                                       {
-                                               // spawn at first
-                                               if(ent.race_checkpoint != 0)
-                                                       return '-1 0 0';
-                                               if(spot.race_place != race_lowest_place_spawn)
-                                                       return '-1 0 0';
-                                       }
-                                       else
-                                       {
-                                               if(ent.race_checkpoint != self.race_respawn_checkpoint)
-                                                       return '-1 0 0';
-                                               // try reusing the previous spawn
-                                               if(ent == self.race_respawn_spotref || spot == self.race_respawn_spotref)
-                                                       prio += 1;
-                                               if(ent.race_checkpoint == 0)
-                                               {
-                                                       float pl;
-                                                       pl = self.race_place;
-                                                       if(pl > race_highest_place_spawn)
-                                                               pl = 0;
-                                                       if(pl == 0 && !self.race_started)
-                                                               pl = race_highest_place_spawn; // use last place if he has not even touched finish yet
-                                                       if(spot.race_place != pl)
-                                                               return '-1 0 0';
-                                               }
-                                       }
-                               }
-                               good = 1;
+                               entity oldself = self;
+                               self = ent;
+                               spawn_score = ent.spawn_evalfunc(oldself, spot, spawn_score);
+                               self = oldself;
+                               if(spawn_score_x < 0)
+                                       return spawn_score;
                        }
-                       ent = find(ent, targetname, spot.target);
                }
 
-               if(found && !good)
+               if(!found)
+               {
+                       dprint("WARNING: spawnpoint at ", vtos(spot.origin), " could not find its target ", spot.target, "\n");
                        return '-1 0 0';
+               }
        }
 
-       player = playerlist;
-       shortest = vlen(world.maxs - world.mins);
-       for(player = playerlist; player; player = player.chain)
-               if (player != self)
-               {
-                       thisdist = vlen(player.origin - spot.origin);
-                       if (thisdist < shortest)
-                               shortest = thisdist;
-               }
-       return prio * '1 0 0' + shortest * '0 1 0';
+       MUTATOR_CALLHOOK(Spawn_Score);
+       return spawn_score;
+}
+
+void Spawn_ScoreAll(entity firstspot, float mindist, float teamcheck)
+{
+       entity spot;
+       for(spot = firstspot; spot; spot = spot.chain)
+               spot.spawnpoint_score = Spawn_Score(spot, mindist, teamcheck);
 }
 
-float spawn_allbad;
-float spawn_allgood;
-entity Spawn_FilterOutBadSpots(entity firstspot, entity playerlist, float mindist, float teamcheck, float anypoint)
+entity Spawn_FilterOutBadSpots(entity firstspot, float mindist, float teamcheck)
 {
-       local entity spot, spotlist, spotlistend;
-       spawn_allgood = TRUE;
-       spawn_allbad = TRUE;
+       entity spot, spotlist, spotlistend;
 
        spotlist = world;
        spotlistend = world;
 
+       Spawn_ScoreAll(firstspot, mindist, teamcheck);
+
        for(spot = firstspot; spot; spot = spot.chain)
        {
-               spot.spawnpoint_score = Spawn_Score(spot, playerlist, teamcheck, anypoint);
-
-               if(autocvar_spawn_debugview)
-               {
-                       setmodel(spot, "models/runematch/rune.mdl");
-                       if(spot.spawnpoint_score_y < mindist)
-                       {
-                               spot.colormod = '1 0 0';
-                               spot.scale = 1;
-                       }
-                       else
-                       {
-                               spot.colormod = '0 1 0';
-                               spot.scale = spot.spawnpoint_score_y / mindist;
-                       }
-               }
-
                if(spot.spawnpoint_score_x >= 0) // spawning allowed here
                {
-                       if(spot.spawnpoint_score_y < mindist)
-                       {
-                               // too short distance
-                               spawn_allgood = FALSE;
-                       }
-                       else
-                       {
-                               // perfect
-                               spawn_allbad = FALSE;
-
-                               if(spotlistend)
-                                       spotlistend.chain = spot;
-                               spotlistend = spot;
-                               if(!spotlist)
-                                       spotlist = spot;
-
-                               /*
-                               if(teamcheck >= 0)
-                               if(spot.team != teamcheck)
-                                       error("invalid spawn added");
-
-                               print("added ", etos(spot), "\n");
-                               */
-                       }
+                       if(spotlistend)
+                               spotlistend.chain = spot;
+                       spotlistend = spot;
+                       if(!spotlist)
+                               spotlist = spot;
                }
        }
        if(spotlistend)
                spotlistend.chain = world;
 
-       /*
-               entity e;
-               if(teamcheck >= 0)
-                       for(e = spotlist; e; e = e.chain)
-                       {
-                               print("seen ", etos(e), "\n");
-                               if(e.team != teamcheck)
-                                       error("invalid spawn found");
-                       }
-       */
-
        return spotlist;
 }
 
@@ -299,7 +232,7 @@ entity Spawn_WeightedPoint(entity firstspot, float lower, float upper, float exp
 {
        // weight of a point: bound(lower, mindisttoplayer, upper)^exponent
        // multiplied by spot.cnt (useful if you distribute many spawnpoints in a small area)
-       local entity spot;
+       entity spot;
 
        RandomSelection_Init();
        for(spot = firstspot; spot; spot = spot.chain)
@@ -317,15 +250,14 @@ Finds a point to respawn
 */
 entity SelectSpawnPoint (float anypoint)
 {
-       local float teamcheck;
-       local entity firstspot_new;
-       local entity spot, firstspot, playerlist;
+       float teamcheck;
+       entity spot, firstspot;
 
        spot = find (world, classname, "testplayerstart");
        if (spot)
                return spot;
 
-       if(anypoint)
+       if(anypoint || autocvar_g_spawn_useallspawns)
                teamcheck = -1;
        else if(have_team_spawns > 0)
        {
@@ -350,8 +282,6 @@ entity SelectSpawnPoint (float anypoint)
                // 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");
        // get the entire list of spots
        firstspot = findchain(classname, "info_player_deathmatch");
        // filter out the bad ones
@@ -362,38 +292,22 @@ entity SelectSpawnPoint (float anypoint)
        }
        else
        {
-               firstspot_new = Spawn_FilterOutBadSpots(firstspot, playerlist, 100, teamcheck, anypoint);
-               if(!firstspot_new)
-                       firstspot_new = Spawn_FilterOutBadSpots(firstspot, playerlist, -1, teamcheck, anypoint);
-               firstspot = firstspot_new;
+               float mindist;
+               if (arena_roundbased && !g_ca)
+                       mindist = 800;
+               else
+                       mindist = 100;
+               firstspot = Spawn_FilterOutBadSpots(firstspot, mindist, teamcheck);
 
                // there is 50/50 chance of choosing a random spot or the furthest spot
                // (this means that roughly every other spawn will be furthest, so you
                // usually won't get fragged at spawn twice in a row)
-               if (arena_roundbased && !g_ca)
-               {
-                       firstspot_new = Spawn_FilterOutBadSpots(firstspot, playerlist, 800, teamcheck, anypoint);
-                       if(firstspot_new)
-                               firstspot = firstspot_new;
-                       spot = Spawn_WeightedPoint(firstspot, 1, 1, 1);
-               }
-               else if (random() > autocvar_g_spawn_furthest)
+               if (random() > autocvar_g_spawn_furthest)
                        spot = Spawn_WeightedPoint(firstspot, 1, 1, 1);
                else
                        spot = Spawn_WeightedPoint(firstspot, 1, 5000, 5); // chooses a far far away spawnpoint
        }
 
-       if(autocvar_spawn_debugview)
-       {
-               print("spot mindistance: ", vtos(spot.spawnpoint_score), "\n");
-
-               entity e;
-               if(teamcheck >= 0)
-                       for(e = firstspot; e; e = e.chain)
-                               if(e.team != teamcheck)
-                                       error("invalid spawn found");
-       }
-
        if (!spot)
        {
                if(autocvar_spawn_debug)
@@ -662,6 +576,7 @@ void PutObserverInServer (void)
        
        self.classname = "observer";
        self.iscreature = FALSE;
+       self.damagedbycontents = FALSE;
        self.health = -666;
        self.takedamage = DAMAGE_NO;
        self.solid = SOLID_NOT;
@@ -705,6 +620,7 @@ void PutObserverInServer (void)
        self.model = "";
        self.modelindex = 0;
        self.weapon = 0;
+       self.weaponname = "";
        self.switchingweapon = 0;
        self.weaponmodel = "";
        self.weaponentity = world;
@@ -751,15 +667,17 @@ void PutObserverInServer (void)
                self.frags = FRAGS_SPECTATOR;
 }
 
+.float model_randomizer;
 void FixPlayermodel()
 {
-       local string defaultmodel;
-       local float defaultskin, chmdl, oldskin;
-       local vector m1, m2;
+       string defaultmodel;
+       float defaultskin, chmdl, oldskin, n, i;
+       vector m1, m2;
 
        defaultmodel = "";
 
-       if(autocvar_sv_defaultcharacter == 1) {
+       if(autocvar_sv_defaultcharacter == 1)
+       {
                defaultskin = 0;
 
                if(teamplay)
@@ -778,6 +696,17 @@ void FixPlayermodel()
                        defaultmodel = autocvar_sv_defaultplayermodel;
                        defaultskin = autocvar_sv_defaultplayerskin;
                }
+
+               n = tokenize_console(defaultmodel);
+               if(n > 0)
+                       defaultmodel = argv(floor(n * self.model_randomizer));
+
+               i = strstrofs(defaultmodel, ":", 0);
+               if(i >= 0)
+               {
+                       defaultskin = stof(substring(defaultmodel, i+1, -1));
+                       defaultmodel = substring(defaultmodel, 0, i);
+               }
        }
 
        if(self.modelindex == 0 && self.deadflag == DEAD_NO)
@@ -859,6 +788,9 @@ void PutClientInServer (void)
                WriteByte(MSG_ONE, SVC_SETVIEW);
                WriteEntity(MSG_ONE, self);
        }
+       
+       // reset player keys
+       self.itemkeys = 0;
 
        // player is dead and becomes observer
        // FIXME fix LMS scoring for new system
@@ -898,6 +830,7 @@ void PutClientInServer (void)
                self.classname = "player";
                self.wasplayer = TRUE;
                self.iscreature = TRUE;
+               self.damagedbycontents = TRUE;
                self.movetype = MOVETYPE_WALK;
                self.solid = SOLID_SLIDEBOX;
                self.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_SOLID;
@@ -906,9 +839,11 @@ void PutClientInServer (void)
                if(clienttype(self) == CLIENTTYPE_BOT && autocvar_g_botclip_collisions)
                        self.dphitcontentsmask |= DPCONTENTS_BOTCLIP;
                self.frags = FRAGS_PLAYER;
-               if(independent_players)
+               if(INDEPENDENT_PLAYERS)
                        MAKE_INDEPENDENT_PLAYER(self);
                self.flags = FL_CLIENT;
+               if(autocvar__notarget)
+                       self.flags |= FL_NOTARGET;
                self.takedamage = DAMAGE_AIM;
                if(g_minstagib)
                        self.effects = EF_FULLBRIGHT;
@@ -1027,7 +962,8 @@ void PutClientInServer (void)
                self.prevorigin = self.origin;
                self.lastrocket = world; // stop rocket guiding, no revenge from the grave!
                self.lastteleporttime = time; // prevent insane speeds due to changing origin
-
+        self.hud = HUD_NORMAL;
+        
                if(g_arena)
                {
                        Spawnqueue_Remove(self);
@@ -1049,8 +985,6 @@ void PutClientInServer (void)
                        self.killcount = 0;
                }
 
-               self.cnt = WEP_LASER;
-
                CL_SpawnWeaponentity();
                self.alpha = default_player_alpha;
                self.colormod = '1 1 1' * autocvar_g_player_brightness;
@@ -1092,7 +1026,7 @@ void PutClientInServer (void)
                        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"));
+                               self.(weapon_load[j]) = cvar(strcat("g_balance_", e.netname, "_reload_ammo"));
                }
 
                oldself = self;
@@ -1109,8 +1043,9 @@ void PutClientInServer (void)
                MUTATOR_CALLHOOK(PlayerSpawn);
 
                self.switchweapon = w_getbestweapon(self);
-               self.cnt = self.switchweapon;
+               self.cnt = -1; // W_LastWeapon will not complain
                self.weapon = 0;
+               self.weaponname = "";
                self.switchingweapon = 0;
 
                if(!self.alivetime)
@@ -1343,9 +1278,11 @@ void KillIndicator_Think()
        }
 }
 
+float clientkilltime;
 void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2 = spec
 {
        float killtime;
+       float starttime;
        entity e;
 
        if (gameover)
@@ -1381,13 +1318,16 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2
                }
                else
                {
+                       starttime = max(time, clientkilltime);
+
                        self.killindicator = spawn();
                        self.killindicator.owner = self;
                        self.killindicator.scale = 0.5;
                        setattachment(self.killindicator, self, "");
                        setorigin(self.killindicator, '0 0 52');
                        self.killindicator.think = KillIndicator_Think;
-                       self.killindicator.nextthink = time + (self.lip) * 0.05;
+                       self.killindicator.nextthink = starttime + (self.lip) * 0.05;
+                       clientkilltime = max(clientkilltime, self.killindicator.nextthink + 0.05);
                        self.killindicator.cnt = ceil(killtime);
                        self.killindicator.count = bound(0, ceil(killtime), 10);
                        //sprint(self, strcat("^1You'll be dead in ", ftos(self.killindicator.cnt), " seconds\n"));
@@ -1402,7 +1342,8 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2
                                setattachment(e.killindicator, e, "");
                                setorigin(e.killindicator, '0 0 52');
                                e.killindicator.think = KillIndicator_Think;
-                               e.killindicator.nextthink = time + (e.lip) * 0.05;
+                               e.killindicator.nextthink = starttime + (e.lip) * 0.05;
+                               clientkilltime = max(clientkilltime, e.killindicator.nextthink + 0.05);
                                e.killindicator.cnt = ceil(killtime);
                        }
                        self.lip = 0;
@@ -1667,8 +1608,7 @@ void ClientConnect (void)
        bprint("\n");
 
        stuffcmd(self, strcat(clientstuff, "\n"));
-       stuffcmd(self, strcat("exec maps/", mapname, ".cfg\n"));
-       stuffcmd(self, "cl_particles_reloadeffects\n");
+       stuffcmd(self, "cl_particles_reloadeffects\n"); // TODO do we still need this?
 
        FixClientCvars(self);
 
@@ -1678,9 +1618,6 @@ void ClientConnect (void)
        // Wazat's grappling hook
        SetGrappleHookBindings();
 
-       // get autoswitch state from player when he toggles it
-       stuffcmd(self, "alias autoswitch \"set cl_autoswitch $1 ; cmd autoswitch $1\"\n"); // default.cfg-ed in 2.4.1
-
        // get version info from player
        stuffcmd(self, "cmd clientversion $gameversion\n");
 
@@ -1782,6 +1719,8 @@ void ClientConnect (void)
 
        if(!autocvar_g_campaign)
                Send_CSQC_Centerprint_Generic(self, CPID_MOTD, getwelcomemessage(), autocvar_welcome_message_time, 0);
+
+       self.model_randomizer = random();
 }
 
 /*
@@ -1836,6 +1775,7 @@ void ClientDisconnect (void)
 
        Portal_ClearAll(self);
 
+       RemoveGrapplingHook(self);
        if(self.flagcarried)
                DropFlag(self.flagcarried, world, world);
        if(self.ballcarried && g_nexball)
@@ -1903,7 +1843,7 @@ void ChatBubbleThink()
                self.model = self.mdl;
        else
                self.model = "";
-};
+}
 
 void UpdateChatBubble()
 {
@@ -1932,7 +1872,7 @@ void UpdateChatBubble()
 // added to the model skins
 /*void UpdateColorModHack()
 {
-       local float c;
+       float c;
        c = self.clientcolors & 15;
        // LordHavoc: only bothering to support white, green, red, yellow, blue
             if (!teamplay) self.colormod = '0 0 0';
@@ -1942,7 +1882,7 @@ void UpdateChatBubble()
        else if (c == 12) self.colormod = '1.22 1.22 0.10';
        else if (c == 13) self.colormod = '0.10 0.10 1.73';
        else self.colormod = '1 1 1';
-};*/
+}*/
 
 .float oldcolormap;
 void respawn(void)
@@ -1956,7 +1896,7 @@ void respawn(void)
                self.avelocity = randomvec() * autocvar_g_respawn_ghosts_speed * 3 - randomvec() * autocvar_g_respawn_ghosts_speed * 3;
                self.effects |= EF_ADDITIVE;
                self.oldcolormap = self.colormap;
-               self.colormap = 512;
+               self.colormap = 0; // this originally was 512, but raises a warning in the engine, so get rid of it
                pointparticles(particleeffectnum("respawn_ghost"), self.origin, '0 0 0', 1);
                if(autocvar_g_respawn_ghosts_maxtime)
                        SUB_SetFade (self, time + autocvar_g_respawn_ghosts_maxtime / 2 + random () * (autocvar_g_respawn_ghosts_maxtime - autocvar_g_respawn_ghosts_maxtime / 2), 1.5);
@@ -2461,6 +2401,7 @@ void ShowRespawnCountdown()
        }
 }
 
+.float prevent_join_msgtime;
 void LeaveSpectatorMode()
 {
        if(nJoinAllowed(1)) {
@@ -2482,6 +2423,12 @@ void LeaveSpectatorMode()
                        if (time < self.jointime + autocvar_welcome_message_time)
                                Send_CSQC_Centerprint_Generic_Expire(self, CPID_MOTD); // clear MOTD
 
+                       if (self.prevent_join_msgtime)
+                       {
+                               Send_CSQC_Centerprint_Generic_Expire(self, CPID_PREVENT_JOIN);
+                               self.prevent_join_msgtime = 0;
+                       }
+
                        return;
                } else {
                        if (g_ca && self.caplayer) {
@@ -2493,7 +2440,11 @@ void LeaveSpectatorMode()
        }
        else {
                //player may not join because of g_maxplayers is set
-               centerprint(self, PREVENT_JOIN_TEXT);
+               if (time - self.prevent_join_msgtime > 2)
+               {
+                       Send_CSQC_Centerprint_Generic(self, CPID_PREVENT_JOIN, PREVENT_JOIN_TEXT, 0, 0);
+                       self.prevent_join_msgtime = time;
+               }
        }
 }
 
@@ -2508,16 +2459,16 @@ float nJoinAllowed(float includeMe) {
                return FALSE; // forced spectators can never join
 
        // TODO simplify this
-       local entity e;
+       entity e;
 
-       local float totalClients;
+       float totalClients;
        FOR_EACH_CLIENT(e)
                totalClients += 1;
 
        if (!autocvar_g_maxplayers)
                return maxclients - totalClients + includeMe;
 
-       local float currentlyPlaying;
+       float currentlyPlaying;
        FOR_EACH_REALPLAYER(e)
                currentlyPlaying += 1;
 
@@ -2604,7 +2555,7 @@ void ObserverThink()
                        }
                }
        }
-       
+
        PrintWelcomeMessage();
 }
 
@@ -2714,10 +2665,12 @@ void PlayerPreThink (void)
                if(self.cvar_g_xonoticversion)
                        if(time > self.version_nagtime)
                        {
-                               if(strstr(self.cvar_g_xonoticversion, "git", 0) < 0)
+                               // don't notify git users
+                               if(strstr(self.cvar_g_xonoticversion, "git", 0) < 0 && strstr(self.cvar_g_xonoticversion, "autobuild", 0) < 0)
                                {
-                                       if(strstr(autocvar_g_xonoticversion, "git", 0) >= 0)
+                                       if(strstr(autocvar_g_xonoticversion, "git", 0) >= 0 || strstr(autocvar_g_xonoticversion, "autobuild", 0) >= 0)
                                        {
+                                               // notify release users if connecting to git
                                                dprint("^1NOTE^7 to ", self.netname, "^7 - the server is running ^3Xonotic ", autocvar_g_xonoticversion, " (beta)^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n");
                                                sprint(self, strcat("\{1}^1NOTE: ^7the server is running ^3Xonotic ", autocvar_g_xonoticversion, " (beta)^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n"));
                                        }
@@ -2727,12 +2680,14 @@ void PlayerPreThink (void)
                                                r = vercmp(self.cvar_g_xonoticversion, autocvar_g_xonoticversion);
                                                if(r < 0)
                                                {
+                                                       // give users new version
                                                        dprint("^1NOTE^7 to ", self.netname, "^7 - ^3Xonotic ", autocvar_g_xonoticversion, "^7 is out, and you still have ^3Xonotic ", self.cvar_g_xonoticversion, "^1 - get the update from ^4http://www.xonotic.org/^1!\n");
                                                        sprint(self, strcat("\{1}^1NOTE: ^3Xonotic ", autocvar_g_xonoticversion, "^7 is out, and you still have ^3Xonotic ", self.cvar_g_xonoticversion, "^1 - get the update from ^4http://www.xonotic.org/^1!\n"));
                                                }
                                                else if(r > 0)
                                                {
-                                                       dprint("^1NOTE^7 to ", self.netname, "^7 - the server is running ^3Xonotic ", autocvar_g_xonoticversion, "^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n");
+                                                       // notify users about old server version
+                                                       print("^1NOTE^7 to ", self.netname, "^7 - the server is running ^3Xonotic ", autocvar_g_xonoticversion, "^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n");
                                                        sprint(self, strcat("\{1}^1NOTE: ^7the server is running ^3Xonotic ", autocvar_g_xonoticversion, "^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n"));
                                                }
                                        }
@@ -2754,12 +2709,15 @@ void PlayerPreThink (void)
 
        MUTATOR_CALLHOOK(PlayerPreThink);
 
-       if(self.BUTTON_USE && !self.usekeypressed)
-               PlayerUseKey();
-       self.usekeypressed = self.BUTTON_USE;
+       if(!self.cvar_cl_newusekeysupported) // FIXME remove this - it was a stupid idea to begin with, we can JUST use the button
+       {
+               if(self.BUTTON_USE && !self.usekeypressed)
+                       PlayerUseKey();
+               self.usekeypressed = self.BUTTON_USE;
+       }
 
        PrintWelcomeMessage();
-       
+
        if(self.classname == "player") {
 //             if(self.netname == "Wazat")
 //                     bprint(self.classname, "\n");
@@ -2923,14 +2881,14 @@ void PlayerPreThink (void)
 
                self.prevorigin = self.origin;
 
-               if ((self.BUTTON_CROUCH && !self.hook.state) || self.health <= g_bloodloss)
+               if (((self.BUTTON_CROUCH && !self.hook.state) || self.health <= g_bloodloss) && self.animstate_startframe != self.anim_melee_x) // prevent crouching if using melee attack
                {
                        if (!self.crouch)
                        {
                                self.crouch = TRUE;
                                self.view_ofs = PL_CROUCH_VIEW_OFS;
                                setsize (self, PL_CROUCH_MIN, PL_CROUCH_MAX);
-                               setanim(self, self.anim_duck, FALSE, TRUE, TRUE);
+                               // setanim(self, self.anim_duck, FALSE, TRUE, TRUE); // this anim is BROKEN anyway
                        }
                }
                else
@@ -2989,7 +2947,10 @@ void PlayerPreThink (void)
 
                if(g_nexball)
                        nexball_setstatus();
-
+               
+               // secret status
+               secrets_setstatus();
+               
                self.dmg_team = max(0, self.dmg_team - autocvar_g_teamdamage_resetspeed * frametime);
 
                //self.angles_y=self.v_angle_y + 90;   // temp
@@ -3149,6 +3110,8 @@ void PlayerPostThink (void)
 
        CheatFrame();
 
+       //CheckPlayerJump();
+
        if(self.classname == "player") {
                CheckRules_Player();
                UpdateChatBubble();
@@ -3215,7 +3178,7 @@ void PlayerPostThink (void)
                        self.stored_netname = strzone(uid2name(self.crypto_idfp));
                if(self.stored_netname != self.netname)
                {
-                       db_put(ServerProgsDB, strcat("uid2name", self.crypto_idfp), self.netname);
+                       db_put(ServerProgsDB, strcat("/uid2name/", self.crypto_idfp), self.netname);
                        strunzone(self.stored_netname);
                        self.stored_netname = strzone(self.netname);
                }