]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/client/main.qc
Use separate variable to store number of records to arrive from the server
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / main.qc
index 7ad10879f7ac23b05a69a96ae7d4f7441ea51c2d..9222d976b0b31a39a3807189e1dbe8991f01e68d 100644 (file)
@@ -97,7 +97,7 @@ void CSQC_Init()
        prvm_language = strzone(cvar_string("prvm_language"));
 
 #ifdef WATERMARK
-       LOG_INFOF("^4CSQC Build information: ^1%s\n", WATERMARK);
+       LOG_INFOF("^4CSQC Build information: ^1%s", WATERMARK);
 #endif
 
        {
@@ -134,6 +134,8 @@ void CSQC_Init()
        registercvar("cl_jumpspeedcap_min", "");
        registercvar("cl_jumpspeedcap_max", "");
 
+       registercvar("cl_shootfromfixedorigin", "");
+
        registercvar("cl_multijump", "1");
 
        registercvar("cl_spawn_near_teammate", "1");
@@ -414,7 +416,7 @@ NET_HANDLE(ENT_CLIENT_SCORES, bool isnew)
        if(!isNew && n != this.sv_entnum)
        {
                //print("A CSQC entity changed its owner!\n");
-               LOG_INFOF("A CSQC entity changed its owner! (edict: %d, classname: %s)\n", etof(this), this.classname);
+               LOG_INFOF("A CSQC entity changed its owner! (edict: %d, classname: %s)", etof(this), this.classname);
                isNew = true;
                Ent_Remove(this);
        }
@@ -435,11 +437,10 @@ NET_HANDLE(ENT_CLIENT_SCORES, bool isnew)
        //      RegisterPlayer(o);
        //playerchecker will do this for us later, if it has not already done so
 
-    int sf, lf;
-       sf = ReadShort();
-       lf = ReadShort();
+       int sf = ReadShort();
+       int lf = ReadShort();
        FOREACH(Scores, true, {
-        int p = 1 << (i % 16);
+               int p = 1 << (i % 16);
                if (sf & p)
                {
                        if (lf & p)
@@ -447,7 +448,7 @@ NET_HANDLE(ENT_CLIENT_SCORES, bool isnew)
                        else
                                o.(scores(it)) = ReadChar();
                }
-    });
+       });
 
        return = true;
 
@@ -461,24 +462,21 @@ NET_HANDLE(ENT_CLIENT_TEAMSCORES, bool isnew)
 {
        make_pure(this);
        int i;
-       entity o;
 
        this.team = ReadByte();
-       o = this.owner = GetTeam(this.team, true); // these team numbers can always be trusted
+       entity o = this.owner = GetTeam(this.team, true); // these team numbers can always be trusted
 
-    int sf, lf;
 #if MAX_TEAMSCORE <= 8
-       sf = ReadByte();
-       lf = ReadByte();
+       int sf = ReadByte();
+       int lf = ReadByte();
 #else
-       sf = ReadShort();
-       lf = ReadShort();
+       int sf = ReadShort();
+       int lf = ReadShort();
 #endif
-       int p;
-       for(i = 0, p = 1; i < MAX_TEAMSCORE; ++i, p *= 2)
-               if(sf & p)
+       for(i = 0; i < MAX_TEAMSCORE; ++i)
+               if(sf & BIT(i))
                {
-                       if(lf & p)
+                       if(lf & BIT(i))
                                o.(teamscores(i)) = ReadInt24_t();
                        else
                                o.(teamscores(i)) = ReadChar();
@@ -494,7 +492,7 @@ NET_HANDLE(ENT_CLIENT_CLIENTDATA, bool isnew)
        make_pure(this);
        float newspectatee_status;
 
-    int f = ReadByte();
+       int f = ReadByte();
 
        scoreboard_showscores_force = (f & BIT(0));
 
@@ -551,15 +549,13 @@ NET_HANDLE(ENT_CLIENT_CLIENTDATA, bool isnew)
 NET_HANDLE(ENT_CLIENT_NAGGER, bool isnew)
 {
        make_pure(this);
-    int i, j, b, f;
+       int i, j, b, f;
 
-    int nags = ReadByte(); // NAGS NAGS NAGS NAGS NAGS NAGS NADZ NAGS NAGS NAGS
+       int nags = ReadByte(); // NAGS NAGS NAGS NAGS NAGS NAGS NADZ NAGS NAGS NAGS
 
        if(!(nags & BIT(2)))
        {
-               if(vote_called_vote)
-                       strunzone(vote_called_vote);
-               vote_called_vote = string_null;
+               strfree(vote_called_vote);
                vote_active = 0;
        }
        else
@@ -577,9 +573,7 @@ NET_HANDLE(ENT_CLIENT_NAGGER, bool isnew)
 
        if(nags & BIT(7))
        {
-               if(vote_called_vote)
-                       strunzone(vote_called_vote);
-               vote_called_vote = strzone(ReadString());
+               strcpy(vote_called_vote, ReadString());
        }
 
        if(nags & 1)
@@ -590,7 +584,7 @@ NET_HANDLE(ENT_CLIENT_NAGGER, bool isnew)
                for(i = 1; i <= maxclients; i += 8)
                {
                        f = ReadByte();
-                       for(j = i-1, b = 1; b < 256; b *= 2, ++j)
+                       for(j = i-1, b = BIT(0); b < BIT(8); b <<= 1, ++j)
                                if (!(f & b))
                                        if(playerslots[j])
                                                playerslots[j].ready = 0;
@@ -609,21 +603,24 @@ NET_HANDLE(ENT_CLIENT_NAGGER, bool isnew)
 NET_HANDLE(ENT_CLIENT_ELIMINATEDPLAYERS, bool isnew)
 {
        make_pure(this);
-    int i, j, b, f;
-
-    int sf = ReadByte();
-       if(sf & 1)
-       {
-               for(j = 0; j < maxclients; ++j)
-                       if(playerslots[j])
+       int sf = 0;
+       serialize(byte, 0, sf);
+       if (sf & 1) {
+               for (int j = 0; j < maxclients; ++j) {
+                       if (playerslots[j]) {
                                playerslots[j].eliminated = 1;
-               for(i = 1; i <= maxclients; i += 8)
-               {
-                       f = ReadByte();
-                       for(j = i-1, b = 1; b < 256; b *= 2, ++j)
-                               if (!(f & b))
-                                       if(playerslots[j])
-                                               playerslots[j].eliminated = 0;
+                       }
+               }
+               for (int i = 1; i <= maxclients; i += 8) {
+                       int f = 0;
+                       serialize(byte, 0, f);
+                       for (int b = 0; b < 8; ++b) {
+                               if (f & BIT(b)) continue;
+                               int j = i - 1 + b;
+                               if (playerslots[j]) {
+                                       playerslots[j].eliminated = 0;
+                               }
+                       }
                }
        }
        return true;
@@ -641,7 +638,7 @@ NET_HANDLE(ENT_CLIENT_RANDOMSEED, bool isnew)
 NET_HANDLE(ENT_CLIENT_ACCURACY, bool isnew)
 {
        make_pure(this);
-    int sf = ReadInt24_t();
+       int sf = ReadInt24_t();
        if (sf == 0) {
                for (int w = 0; w <= WEP_LAST - WEP_FIRST; ++w)
                        weapon_accuracy[w] = -1;
@@ -651,7 +648,7 @@ NET_HANDLE(ENT_CLIENT_ACCURACY, bool isnew)
        int f = 1;
        for (int w = 0; w <= WEP_LAST - WEP_FIRST; ++w) {
                if (sf & f) {
-            int b = ReadByte();
+                       int b = ReadByte();
                        if (b == 0)
                                weapon_accuracy[w] = -1;
                        else if (b == 255)
@@ -698,10 +695,7 @@ void Spawn_PreDraw(entity this)
 NET_HANDLE(ENT_CLIENT_SPAWNPOINT, bool is_new)
 {
        float teamnum = (ReadByte() - 1);
-       vector spn_origin;
-       spn_origin.x = ReadCoord();
-       spn_origin.y = ReadCoord();
-       spn_origin.z = ReadCoord();
+       vector spn_origin = ReadVector();
 
        this.team = (teamnum + 1);
 
@@ -758,9 +752,7 @@ NET_HANDLE(ENT_CLIENT_SPAWNEVENT, bool is_new)
 
        if(entnum)
        {
-               this.origin_x = ReadCoord();
-               this.origin_y = ReadCoord();
-               this.origin_z = ReadCoord();
+               this.origin = ReadVector();
 
                if(is_new)
                {
@@ -826,7 +818,7 @@ void CSQC_Ent_Update(entity this, bool isnew)
        {
                if (t != this.enttype || isnew)
                {
-                       LOG_INFOF("A CSQC entity changed its type! (edict: %d, server: %d, type: %d -> %d)\n", etof(this), this.entnum, this.enttype, t);
+                       LOG_INFOF("A CSQC entity changed its type! (edict: %d, server: %d, type: %d -> %d)", etof(this), this.entnum, this.enttype, t);
                        Ent_Remove(this);
                        clearentity(this);
                        isnew = true;
@@ -836,7 +828,7 @@ void CSQC_Ent_Update(entity this, bool isnew)
        {
                if (!isnew)
                {
-                       LOG_INFOF("A CSQC entity appeared out of nowhere! (edict: %d, server: %d, type: %d)\n", etof(this), this.entnum, t);
+                       LOG_INFOF("A CSQC entity appeared out of nowhere! (edict: %d, server: %d, type: %d)", etof(this), this.entnum, t);
                        isnew = true;
                }
        }
@@ -846,7 +838,7 @@ void CSQC_Ent_Update(entity this, bool isnew)
        FOREACH(LinkedEntities, it.m_id == t, {
                if (isnew) this.classname = it.netname;
                if (autocvar_developer_csqcentities)
-            LOG_INFOF("CSQC_Ent_Update(%d) at %f with this=%i {.entnum=%d, .enttype=%d} t=%s (%d)\n", isnew, savetime, this, this.entnum, this.enttype, this.classname, t);
+            LOG_INFOF("CSQC_Ent_Update(%d) at %f with this=%i {.entnum=%d, .enttype=%d} t=%s (%d)", isnew, savetime, this, this.entnum, this.enttype, this.classname, t);
                done = it.m_read(this, NULL, isnew);
                MUTATOR_CALLHOOK(Ent_Update, this, isnew);
                break;
@@ -886,7 +878,7 @@ void Ent_Remove(entity this)
 // CSQC_Ent_Remove : Called when the server requests a SSQC / CSQC entity to be removed.  Essentially call remove(this) as well.
 void CSQC_Ent_Remove(entity this)
 {
-       if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Ent_Remove() with this=%i {.entnum=%d, .enttype=%d}\n", this, this.entnum, this.enttype);
+       if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Ent_Remove() with this=%i {.entnum=%d, .enttype=%d}", this, this.entnum, this.enttype);
        if (wasfreed(this))
        {
                LOG_WARN("CSQC_Ent_Remove called for already removed entity. Packet loss?");
@@ -908,20 +900,20 @@ void Gamemode_Init()
 // CSQC_Parse_StuffCmd : Provides the stuffcmd string in the first parameter that the server provided.  To execute standard behavior, simply execute localcmd with the string.
 void CSQC_Parse_StuffCmd(string strMessage)
 {
-       if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_StuffCmd(\"%s\")\n", strMessage);
+       if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_StuffCmd(\"%s\")", strMessage);
        localcmd(strMessage);
 }
 // CSQC_Parse_Print : Provides the print string in the first parameter that the server provided.  To execute standard behavior, simply execute print with the string.
 void CSQC_Parse_Print(string strMessage)
 {
-       if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_Print(\"%s\")\n", strMessage);
+       if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_Print(\"%s\")", strMessage);
        print(ColorTranslateRGB(strMessage));
 }
 
 // CSQC_Parse_CenterPrint : Provides the centerprint_hud string in the first parameter that the server provided.
 void CSQC_Parse_CenterPrint(string strMessage)
 {
-       if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_CenterPrint(\"%s\")\n", strMessage);
+       if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_CenterPrint(\"%s\")", strMessage);
        centerprint_hud(strMessage);
 }
 
@@ -935,12 +927,12 @@ bool CSQC_Parse_TempEntity()
 
        FOREACH(TempEntities, it.m_id == nTEID, {
                if (autocvar_developer_csqcentities)
-                       LOG_INFOF("CSQC_Parse_TempEntity() nTEID=%s (%d)\n", it.netname, nTEID);
+                       LOG_INFOF("CSQC_Parse_TempEntity() nTEID=%s (%d)", it.netname, nTEID);
                return it.m_read(NULL, NULL, true);
        });
 
        if (autocvar_developer_csqcentities)
-               LOG_INFOF("CSQC_Parse_TempEntity() with nTEID=%d\n", nTEID);
+               LOG_INFOF("CSQC_Parse_TempEntity() with nTEID=%d", nTEID);
 
        // No special logic for this temporary entity; return 0 so the engine can handle it
        return false;
@@ -963,14 +955,12 @@ NET_HANDLE(ENT_CLIENT_SCORES_INFO, bool isnew)
        teamplay = _MapInfo_GetTeamPlayBool(gametype);
        HUD_ModIcons_SetFunc();
        FOREACH(Scores, true, {
-               if (scores_label(it)) strunzone(scores_label(it));
-               scores_label(it) = strzone(ReadString());
+               strcpy(scores_label(it), ReadString());
                scores_flags(it) = ReadByte();
        });
        for (int i = 0; i < MAX_TEAMSCORE; ++i)
        {
-               if (teamscores_label(i)) strunzone(teamscores_label(i));
-               teamscores_label(i) = strzone(ReadString());
+               strcpy(teamscores_label(i), ReadString());
                teamscores_flags(i) = ReadByte();
        }
        return = true;
@@ -991,8 +981,7 @@ NET_HANDLE(ENT_CLIENT_INIT, bool isnew)
        arc_shotorigin[2] = decompressShotOrigin(ReadInt24_t());
        arc_shotorigin[3] = decompressShotOrigin(ReadInt24_t());
 
-       if (forcefog) strunzone(forcefog);
-       forcefog = strzone(ReadString());
+       strcpy(forcefog, ReadString());
 
        armorblockpercent = ReadByte() / 255.0;
        damagepush_speedfactor = ReadByte() / 255.0;
@@ -1055,17 +1044,15 @@ NET_HANDLE(TE_CSQC_RACE, bool isNew)
                        race_time = ReadInt24_t();
                        race_previousbesttime = ReadInt24_t();
                        race_mypreviousbesttime = ReadInt24_t();
-                       if(race_previousbestname)
-                               strunzone(race_previousbestname);
                        string pbestname = ReadString();
                        if(autocvar_cl_race_cptimes_onlyself)
                        {
                                race_previousbesttime = race_mypreviousbesttime;
                                race_mypreviousbesttime = 0;
-                               race_previousbestname = strzone("");
+                               strcpy(race_previousbestname, "");
                        }
                        else
-                               race_previousbestname = strzone(pbestname);
+                               strcpy(race_previousbestname, pbestname);
 
                        race_checkpointtime = time;
 
@@ -1091,17 +1078,15 @@ NET_HANDLE(TE_CSQC_RACE, bool isNew)
                        race_nextbesttime = ReadInt24_t();
                        if(b != RACE_NET_CHECKPOINT_NEXT_SPEC_QUALIFYING) // not while spectating (matches server)
                                race_mybesttime = ReadInt24_t();
-                       if(race_nextbestname)
-                               strunzone(race_nextbestname);
                        string newname = ReadString();
                        if(autocvar_cl_race_cptimes_onlyself && b != RACE_NET_CHECKPOINT_NEXT_SPEC_QUALIFYING)
                        {
                                race_nextbesttime = race_mybesttime;
                                race_mybesttime = 0;
-                               race_nextbestname = strzone("");
+                               strcpy(race_nextbestname, "");
                        }
                        else
-                               race_nextbestname = strzone(newname);
+                               strcpy(race_nextbestname, newname);
                        break;
 
                case RACE_NET_CHECKPOINT_HIT_RACE:
@@ -1111,13 +1096,11 @@ NET_HANDLE(TE_CSQC_RACE, bool isNew)
                        race_mycheckpointlapsdelta = ReadByte();
                        if(race_mycheckpointlapsdelta >= 128)
                                race_mycheckpointlapsdelta -= 256;
-                       if(race_mycheckpointenemy)
-                               strunzone(race_mycheckpointenemy);
                        int who = ReadByte();
                        if(who)
-                               race_mycheckpointenemy = strzone(entcs_GetName(who - 1));
+                               strcpy(race_mycheckpointenemy, entcs_GetName(who - 1));
                        else
-                               race_mycheckpointenemy = strzone(""); // TODO: maybe string_null works fine here?
+                               strcpy(race_mycheckpointenemy, ""); // TODO: maybe string_null works fine here?
                        break;
 
                case RACE_NET_CHECKPOINT_HIT_RACE_BY_OPPONENT:
@@ -1127,31 +1110,25 @@ NET_HANDLE(TE_CSQC_RACE, bool isNew)
                        race_othercheckpointlapsdelta = ReadByte();
                        if(race_othercheckpointlapsdelta >= 128)
                                race_othercheckpointlapsdelta -= 256;
-                       if(race_othercheckpointenemy)
-                               strunzone(race_othercheckpointenemy);
                        int what = ReadByte();
                        if(what)
-                               race_othercheckpointenemy = strzone(entcs_GetName(what - 1));
+                               strcpy(race_othercheckpointenemy, entcs_GetName(what - 1));
                        else
-                               race_othercheckpointenemy = strzone(""); // TODO: maybe string_null works fine here?
+                               strcpy(race_othercheckpointenemy, ""); // TODO: maybe string_null works fine here?
                        break;
 
                case RACE_NET_PENALTY_RACE:
                        race_penaltyeventtime = time;
                        race_penaltytime = ReadShort();
                        //race_penaltyaccumulator += race_penaltytime;
-                       if(race_penaltyreason)
-                               strunzone(race_penaltyreason);
-                       race_penaltyreason = strzone(ReadString());
+                       strcpy(race_penaltyreason, ReadString());
                        break;
 
                case RACE_NET_PENALTY_QUALIFYING:
                        race_penaltyeventtime = time;
                        race_penaltytime = ReadShort();
                        race_penaltyaccumulator += race_penaltytime;
-                       if(race_penaltyreason)
-                               strunzone(race_penaltyreason);
-                       race_penaltyreason = strzone(ReadString());
+                       strcpy(race_penaltyreason, ReadString());
                        break;
 
                case RACE_NET_SERVER_RECORD:
@@ -1159,21 +1136,16 @@ NET_HANDLE(TE_CSQC_RACE, bool isNew)
                        break;
                case RACE_NET_SPEED_AWARD:
                        race_speedaward = ReadInt24_t() * GetSpeedUnitFactor(autocvar_hud_panel_physics_speed_unit);
-                       if(race_speedaward_holder)
-                               strunzone(race_speedaward_holder);
-                       race_speedaward_holder = strzone(ReadString());
-                       if(race_speedaward_unit)
-                               strunzone(race_speedaward_unit);
-                       race_speedaward_unit = strzone(GetSpeedUnit(autocvar_hud_panel_physics_speed_unit));
+                       strcpy(race_speedaward_holder, ReadString());
+                       strcpy(race_speedaward_unit, GetSpeedUnit(autocvar_hud_panel_physics_speed_unit));
                        break;
                case RACE_NET_SPEED_AWARD_BEST:
                        race_speedaward_alltimebest = ReadInt24_t() * GetSpeedUnitFactor(autocvar_hud_panel_physics_speed_unit);
-                       if(race_speedaward_alltimebest_holder)
-                               strunzone(race_speedaward_alltimebest_holder);
-                       race_speedaward_alltimebest_holder = strzone(ReadString());
-                       if(race_speedaward_alltimebest_unit)
-                               strunzone(race_speedaward_alltimebest_unit);
-                       race_speedaward_alltimebest_unit = strzone(GetSpeedUnit(autocvar_hud_panel_physics_speed_unit));
+                       strcpy(race_speedaward_alltimebest_holder, ReadString());
+                       strcpy(race_speedaward_alltimebest_unit, GetSpeedUnit(autocvar_hud_panel_physics_speed_unit));
+                       break;
+               case RACE_NET_RANKINGS_CNT:
+                       RANKINGS_DISPLAY_CNT = ReadByte();
                        break;
                case RACE_NET_SERVER_RANKINGS:
                        float prevpos, del;
@@ -1184,49 +1156,44 @@ NET_HANDLE(TE_CSQC_RACE, bool isNew)
                        // move other rankings out of the way
             int i;
                        if (prevpos) {
-                               for (i=prevpos-1;i>pos-1;--i) {
+                               int m = min(prevpos, RANKINGS_DISPLAY_CNT);
+                               for (i=m-1; i>pos-1; --i) {
                                        grecordtime[i] = grecordtime[i-1];
-                                       if(grecordholder[i])
-                                               strunzone(grecordholder[i]);
-                                       grecordholder[i] = strzone(grecordholder[i-1]);
+                                       strcpy(grecordholder[i], grecordholder[i-1]);
                                }
                        } else if (del) { // a record has been deleted by the admin
-                               for (i=pos-1; i<= RANKINGS_CNT-1; ++i) {
-                                       if (i == RANKINGS_CNT-1) { // clear out last record
+                               for (i=pos-1; i<= RANKINGS_DISPLAY_CNT-1; ++i) {
+                                       if (i == RANKINGS_DISPLAY_CNT-1) { // clear out last record
                                                grecordtime[i] = 0;
-                                               if (grecordholder[i])
-                                                       strunzone(grecordholder[i]);
-                                               grecordholder[i] = string_null;
+                                               strfree(grecordholder[i]);
                                        }
                                        else {
                                                grecordtime[i] = grecordtime[i+1];
-                                               if (grecordholder[i])
-                                                       strunzone(grecordholder[i]);
-                                               grecordholder[i] = strzone(grecordholder[i+1]);
+                                               strcpy(grecordholder[i], grecordholder[i+1]);
                                        }
                                }
                        } else { // player has no ranked record yet
-                               for (i=RANKINGS_CNT-1;i>pos-1;--i) {
+                               for (i=RANKINGS_DISPLAY_CNT-1;i>pos-1;--i) {
                                        grecordtime[i] = grecordtime[i-1];
-                                       if(grecordholder[i])
-                                               strunzone(grecordholder[i]);
-                                       grecordholder[i] = strzone(grecordholder[i-1]);
+                                       strcpy(grecordholder[i], grecordholder[i-1]);
                                }
                        }
 
+                       if (grecordtime[RANKINGS_DISPLAY_CNT]) {
+                               // kick off the player who fell from the last displayed position
+                               grecordtime[RANKINGS_DISPLAY_CNT] = 0;
+                               strfree(grecordholder[RANKINGS_DISPLAY_CNT]);
+                       }
+
                        // store new ranking
-                       if(grecordholder[pos-1] != "")
-                               strunzone(grecordholder[pos-1]);
-                       grecordholder[pos-1] = strzone(ReadString());
+                       strcpy(grecordholder[pos-1], ReadString());
                        grecordtime[pos-1] = ReadInt24_t();
                        if(strdecolorize(grecordholder[pos-1]) == strdecolorize(entcs_GetName(player_localnum)))
                                race_myrank = pos;
                        break;
                case RACE_NET_SERVER_STATUS:
                        race_status = ReadShort();
-                       if(race_status_name)
-                               strunzone(race_status_name);
-                       race_status_name = strzone(ReadString());
+                       strcpy(race_status_name, ReadString());
        }
        return true;
 }