]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/client/csqcmodel_hooks.qc
Merge branch 'master' into Juhu/battle-royale
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / csqcmodel_hooks.qc
index a4f81a3304c426e2ea0385c1266546e427bf4d1d..4ce5c74a392ea94a0e4053b3156680fcf73c0765 100644 (file)
 .int lodmodelindex0;
 .int lodmodelindex1;
 .int lodmodelindex2;
-void CSQCPlayer_LOD_Apply(entity this)
+.float loddistance1;
+.float loddistance2;
+void CSQCModel_LOD_Apply(entity this, bool isplayer)
 {
+       int detailreduction = ((isplayer) ? autocvar_cl_playerdetailreduction : autocvar_cl_modeldetailreduction);
+
        // LOD model loading
-       if(this.lodmodelindex0 != this.modelindex)
+       if(this.lodmodelindex0 != this.modelindex && this.lodmodelindex1 != this.modelindex && this.lodmodelindex2 != this.modelindex)
        {
                string modelname = this.model;
                string s;
@@ -46,7 +50,7 @@ void CSQCPlayer_LOD_Apply(entity this)
                        precache_model(s);
                        _setmodel(this, s);
                        if(this.modelindex)
-                               this.lodmodelindex1 = this.modelindex;
+                               this.lodmodelindex2 = this.lodmodelindex1 = this.modelindex;
                }
 
                s = strcat(substring(modelname, 0, strlen(modelname)-4), "_lod2", substring(modelname, -4, 4));
@@ -63,23 +67,25 @@ void CSQCPlayer_LOD_Apply(entity this)
        }
 
        // apply LOD
-       if(autocvar_cl_playerdetailreduction <= 0)
+       if(detailreduction <= 0)
        {
-               if(autocvar_cl_playerdetailreduction <= -2)
+               if(detailreduction <= -2)
                        this.modelindex = this.lodmodelindex2;
-               else if(autocvar_cl_playerdetailreduction <= -1)
+               else if(detailreduction <= -1)
                        this.modelindex = this.lodmodelindex1;
                else
                        this.modelindex = this.lodmodelindex0;
        }
        else
        {
-               float distance = vlen(this.origin - view_origin);
-               float f = (distance * current_viewzoom + 100.0) * autocvar_cl_playerdetailreduction;
+               float distance = vlen(((isplayer) ? this.origin : NearestPointOnBox(this, view_origin)) - view_origin); // TODO: perhaps it should just use NearestPointOnBox all the time, player hitbox can potentially be huge
+               float dist1 = (this.loddistance1 > 0) ? this.loddistance1 : autocvar_cl_loddistance1;
+               float dist2 = (this.loddistance2 > 0) ? this.loddistance2 : autocvar_cl_loddistance2;
+               float f = (distance * current_viewzoom + 100.0) * detailreduction;
                f *= 1.0 / bound(0.01, view_quality, 1);
-               if(f > autocvar_cl_loddistance2)
+               if(f > dist2)
                        this.modelindex = this.lodmodelindex2;
-               else if(f > autocvar_cl_loddistance1)
+               else if(f > dist1)
                        this.modelindex = this.lodmodelindex1;
                else
                        this.modelindex = this.lodmodelindex0;
@@ -201,6 +207,8 @@ void CSQCPlayer_ModelAppearance_Apply(entity this, bool islocalplayer)
 
        if(teamplay)
                isfriend = (cm == 1024 + 17 * myteam);
+       else if(ISGAMETYPE(BR))
+           isfriend = br_isSameSquad(this.entnum);
        else
                isfriend = islocalplayer;
 
@@ -234,21 +242,43 @@ void CSQCPlayer_ModelAppearance_Apply(entity this, bool islocalplayer)
        if(MUTATOR_CALLHOOK(ForcePlayercolors_Skip, this, islocalplayer))
                goto skipforcecolors;
 
+       bool forceplayercolors_enabled = false;
+       #define fpc autocvar_cl_forceplayercolors
+       if (gametype.m_1v1)
+       {
+               if ((myteam != NUM_SPECTATOR) && (fpc == 1 || fpc == 2 || fpc == 3 || fpc == 5))
+                       forceplayercolors_enabled = true;
+       }
+       else if (teamplay)
+       {
+               if ((team_count == 2) && (myteam != NUM_SPECTATOR) && (fpc == 2 || fpc == 4 || fpc == 5))
+                       forceplayercolors_enabled = true;
+       }
+       else if (ISGAMETYPE(BR))
+       {
+               if (br_inSquad() && (fpc == 2 || fpc == 5))
+                       forceplayercolors_enabled = true;
+       }
+       else
+       {
+               if (fpc == 1 || fpc == 2)
+                       forceplayercolors_enabled = true;
+       }
+
        // forceplayercolors too
-       if(teamplay)
+       if(teamplay || ISGAMETYPE(BR))
        {
                // own team's color is never forced
-               int forcecolor_friend = 0;
-               int forcecolor_enemy = 0;
+               int forcecolor_friend = 0, forcecolor_enemy = 0;
                entity tm;
 
                if(autocvar_cl_forcemyplayercolors)
                        forcecolor_friend = 1024 + autocvar_cl_forcemyplayercolors;
-               if((autocvar_cl_forceplayercolors == 2 && team_count == 2)
-                       || (autocvar_cl_forceplayercolors == 3 && IS_GAMETYPE(DUEL)))
+
+               if(forceplayercolors_enabled)
                        forcecolor_enemy = 1024 + autocvar__cl_color;
 
-               if(forcecolor_enemy && !forcecolor_friend)
+               if(!ISGAMETYPE(BR) && forcecolor_enemy && !forcecolor_friend)
                {
                        // only enemy color is forced?
                        // verify it is not equal to the friend color
@@ -256,7 +286,7 @@ void CSQCPlayer_ModelAppearance_Apply(entity this, bool islocalplayer)
                                forcecolor_enemy = 0;
                }
 
-               if(forcecolor_friend && !forcecolor_enemy)
+               if(!ISGAMETYPE(BR) && forcecolor_friend && !forcecolor_enemy)
                {
                        // only friend color is forced?
                        // verify it is not equal to the enemy color
@@ -269,7 +299,7 @@ void CSQCPlayer_ModelAppearance_Apply(entity this, bool islocalplayer)
                                        forcecolor_friend = 0;
                }
 
-               if(cm == 1024 + 17 * myteam)
+               if((!ISGAMETYPE(BR) && (cm == 1024 + 17 * myteam)) || (ISGAMETYPE(BR) && br_isSameSquad(this.entnum)))
                {
                        if(forcecolor_friend)
                                this.colormap = forcecolor_friend;
@@ -280,11 +310,23 @@ void CSQCPlayer_ModelAppearance_Apply(entity this, bool islocalplayer)
                                this.colormap = forcecolor_enemy;
                }
        }
-       else
+       else // if(!teamplay)
        {
                if(autocvar_cl_forcemyplayercolors && islocalplayer)
                        this.colormap = 1024 + autocvar_cl_forcemyplayercolors;
-               else if(autocvar_cl_forceplayercolors)
+               else if (autocvar_cl_forceuniqueplayercolors && !islocalplayer && !gametype.m_1v1)
+               {
+                       // Assign each enemy unique colors
+                       // pick colors from 0 to 14 since 15 is the rainbow color
+                       // pl01 0 1, pl02 1 2, ..., pl14 13 14, pl15 14 0
+                       // pl16 0 2, pl17 1 3, ..., pl29 13  0, pl30 14 1
+                       int num = this.entnum - 1;
+                       int c1 = num % 15;
+                       int q = floor(num / 15);
+                       int c2 = (c1 + 1 + q) % 15;
+                       this.colormap = 1024 + (c1 << 4) + c2;
+               }
+               else if(forceplayercolors_enabled)
                        this.colormap = player_localnum + 1;
        }
 
@@ -536,6 +578,11 @@ void CSQCModel_Effects_Apply(entity this)
                boxparticles(particleeffectnum(EFFECT_EF_FLAME), this, this.absmin, this.absmax, this.velocity, this.velocity, bound(0, frametime, 0.1), 0);
                //pointparticles(EFFECT_EF_FLAME, this.origin, '0 0 0', bound(0, frametime, 0.1));
        }
+       if(eff & EF_SHOCK)
+       {
+               boxparticles(particleeffectnum(EFFECT_ARC_LIGHTNING), this, this.absmin, this.absmax, '0 0 0', '0 0 0', bound(0, frametime, 0.1), 0);
+               //pointparticles(EFFECT_ARC_LIGHTNING, this.origin, '0 0 0', bound(0, frametime, 0.1));
+       }
        if(eff & EF_STARDUST)
        {
                boxparticles(particleeffectnum(EFFECT_EF_STARDUST), this, this.absmin, this.absmax, this.velocity, this.velocity, bound(0, frametime, 0.1), 0);
@@ -638,7 +685,7 @@ void CSQCModel_Hook_PreDraw(entity this, bool isplayer)
        if((this.isplayermodel & ISPLAYER_MODEL) && this.drawmask) // this checks if it's a player MODEL!
        {
                CSQCPlayer_ModelAppearance_Apply(this, (this.isplayermodel & ISPLAYER_LOCAL));
-               CSQCPlayer_LOD_Apply(this);
+               CSQCModel_LOD_Apply(this, true);
 
                if(!isplayer)
                {
@@ -716,6 +763,8 @@ void CSQCModel_Hook_PreDraw(entity this, bool isplayer)
                        }
                }
        }
+       else
+               CSQCModel_LOD_Apply(this, false);
 
        CSQCModel_AutoTagIndex_Apply(this);