]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/mapobjects/subs.qc
Improve server performance by making pure entities that don't have models
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / mapobjects / subs.qc
index bc699813180d1f13e2c7eeb894d6d6f3016ace81..c0b137404c55956d1fa509f697a23e1452c6676e 100644 (file)
@@ -1,4 +1,5 @@
 #include "subs.qh"
+
 void SUB_NullThink(entity this) { }
 
 void SUB_CalcMoveDone(entity this);
@@ -70,14 +71,16 @@ void SUB_SetFade_Think (entity this)
 ==================
 SUB_SetFade
 
-Fade 'ent' out when time >= 'when'
+Fade ent out when time >= vanish_time
 ==================
 */
-void SUB_SetFade (entity ent, float when, float fading_time)
+void SUB_SetFade(entity ent, float vanish_time, float fading_time)
 {
+       if (fading_time <= 0)
+               fading_time = 0.01;
        ent.fade_rate = 1/fading_time;
        setthink(ent, SUB_SetFade_Think);
-       ent.nextthink = when;
+       ent.nextthink = vanish_time;
 }
 
 /*
@@ -229,7 +232,7 @@ void SUB_CalcMove_Bezier (entity this, vector tcontrol, vector tdest, float tspe
        {
                delete(this.move_controller);
        }
-       controller = new(SUB_CalcMove_controller);
+       controller = new_pure(SUB_CalcMove_controller);
        controller.owner = this;
        this.move_controller = controller;
        controller.platmovetype = this.platmovetype;
@@ -287,7 +290,7 @@ void SUB_CalcMove (entity this, vector tdest, float tspeedtype, float tspeed, vo
        // Very short animations don't really show off the effect
        // of controlled animation, so let's just use linear movement.
        // Alternatively entities can choose to specify non-controlled movement.
-        // The only currently implemented alternative movement is linear (value 1)
+       // The only currently implemented alternative movement is linear (value 1)
        if (traveltime < 0.15 || (this.platmovetype_start == 1 && this.platmovetype_end == 1)) // is this correct?
        {
                this.velocity = delta * (1/traveltime); // QuakeC doesn't allow vector/float division
@@ -398,11 +401,11 @@ void ApplyMinMaxScaleAngles(entity e)
                setsize(e, e.mins, e.maxs);
 }
 
-void SetBrushEntityModel(entity this)
+void SetBrushEntityModel(entity this, bool with_lod)
 {
-       if(this.model != "")
-       {
-               precache_model(this.model);
+       if(this.model != "")
+       {
+               precache_model(this.model);
                if(this.mins != '0 0 0' || this.maxs != '0 0 0')
                {
                        vector mi = this.mins;
@@ -412,29 +415,105 @@ void SetBrushEntityModel(entity this)
                }
                else
                        _setmodel(this, this.model); // no precision needed
-               InitializeEntity(this, LODmodel_attach, INITPRIO_FINDTARGET);
-       }
+               if(with_lod)
+                       InitializeEntity(this, LODmodel_attach, INITPRIO_FINDTARGET);
+
+               if(endsWith(this.model, ".obj")) // WORKAROUND: darkplaces currently rotates .obj models on entities incorrectly, we need to add 180 degrees to the Y axis
+                       this.angles_y = anglemods(this.angles_y - 180);
+       }
        setorigin(this, this.origin);
        ApplyMinMaxScaleAngles(this);
 }
 
-void SetBrushEntityModelNoLOD(entity this)
+bool LOD_customize(entity this, entity client)
 {
-       if(this.model != "")
-       {
-               precache_model(this.model);
-               if(this.mins != '0 0 0' || this.maxs != '0 0 0')
+       if(autocvar_loddebug)
+       {
+               int d = autocvar_loddebug;
+               if(d == 1)
+                       this.modelindex = this.lodmodelindex0;
+               else if(d == 2 || !this.lodmodelindex2)
+                       this.modelindex = this.lodmodelindex1;
+               else // if(d == 3)
+                       this.modelindex = this.lodmodelindex2;
+               return true;
+       }
+
+       // TODO csqc network this so it only gets sent once
+       vector near_point = NearestPointOnBox(this, client.origin);
+       if(vdist(near_point - client.origin, <, this.loddistance1))
+               this.modelindex = this.lodmodelindex0;
+       else if(!this.lodmodelindex2 || vdist(near_point - client.origin, <, this.loddistance2))
+               this.modelindex = this.lodmodelindex1;
+       else
+               this.modelindex = this.lodmodelindex2;
+
+       return true;
+}
+
+void LOD_uncustomize(entity this)
+{
+       this.modelindex = this.lodmodelindex0;
+}
+
+void LODmodel_attach(entity this)
+{
+       entity e;
+
+       if(!this.loddistance1)
+               this.loddistance1 = 1000;
+       if(!this.loddistance2)
+               this.loddistance2 = 2000;
+       this.lodmodelindex0 = this.modelindex;
+
+       if(this.lodtarget1 != "")
+       {
+               e = find(NULL, targetname, this.lodtarget1);
+               if(e)
                {
-                       vector mi = this.mins;
-                       vector ma = this.maxs;
-                       _setmodel(this, this.model); // no precision needed
-                       setsize(this, mi, ma);
+                       this.lodmodel1 = e.model;
+                       delete(e);
                }
-               else
-                       _setmodel(this, this.model); // no precision needed
-       }
-       setorigin(this, this.origin);
-       ApplyMinMaxScaleAngles(this);
+       }
+       if(this.lodtarget2 != "")
+       {
+               e = find(NULL, targetname, this.lodtarget2);
+               if(e)
+               {
+                       this.lodmodel2 = e.model;
+                       delete(e);
+               }
+       }
+
+       if(autocvar_loddebug < 0)
+       {
+               this.lodmodel1 = this.lodmodel2 = ""; // don't even initialize
+       }
+
+       if(this.lodmodel1 != "")
+       {
+               vector mi, ma;
+               mi = this.mins;
+               ma = this.maxs;
+
+               precache_model(this.lodmodel1);
+               _setmodel(this, this.lodmodel1);
+               this.lodmodelindex1 = this.modelindex;
+
+               if(this.lodmodel2 != "")
+               {
+                       precache_model(this.lodmodel2);
+                       _setmodel(this, this.lodmodel2);
+                       this.lodmodelindex2 = this.modelindex;
+               }
+
+               this.modelindex = this.lodmodelindex0;
+               setsize(this, mi, ma);
+       }
+
+       if(this.lodmodelindex1)
+               if (!getSendEntity(this))
+                       SetCustomizer(this, LOD_customize, LOD_uncustomize);
 }
 
 /*
@@ -462,7 +541,7 @@ void InitTrigger(entity this)
 // to mean no restrictions, so use a yaw of 360 instead.
        SetMovedir(this);
        this.solid = SOLID_TRIGGER;
-       SetBrushEntityModel(this);
+       SetBrushEntityModel(this, false);
        set_movetype(this, MOVETYPE_NONE);
        this.modelindex = 0;
        this.model = "";
@@ -474,7 +553,7 @@ void InitSolidBSPTrigger(entity this)
 // to mean no restrictions, so use a yaw of 360 instead.
        SetMovedir(this);
        this.solid = SOLID_BSP;
-       SetBrushEntityModel(this);
+       SetBrushEntityModel(this, false);
        set_movetype(this, MOVETYPE_NONE); // why was this PUSH? -div0
 //     this.modelindex = 0;
        this.model = "";
@@ -485,7 +564,7 @@ bool InitMovingBrushTrigger(entity this)
 // trigger angles are used for one-way touches.  An angle of 0 is assumed
 // to mean no restrictions, so use a yaw of 360 instead.
        this.solid = SOLID_BSP;
-       SetBrushEntityModel(this);
+       SetBrushEntityModel(this, true);
        set_movetype(this, MOVETYPE_PUSH);
        if(this.modelindex == 0)
        {