]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/g_subs.qc
now CHAN_PLAYER dies
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / g_subs.qc
index 88e5fa1fd366d16bff86eedf6febecbff546be26..c311f3774f45f59c7ad934e6b5992e673c1b4f54 100644 (file)
@@ -16,6 +16,9 @@ void spawnfunc_info_null (void)
 
 void setanim(entity e, vector anim, float looping, float override, float restart)
 {
+       if (!anim)
+               return; // no animation was given to us! We can't use this. 
+               
        if (anim_x == e.animstate_startframe)
        if (anim_y == e.animstate_numframes)
        if (anim_z == e.animstate_framerate)
@@ -180,35 +183,34 @@ void SUB_CalcMoveDone (void)
 void SUB_CalcMove_controller_think (void)
 {
        entity oldself;
-       float movephase;
        float traveltime;
        float phasepos;
-       float remaining;
+       float nexttick;
        vector delta;
        vector veloc;
        vector nextpos;
        if(time < self.animstate_endtime) {
                delta = self.destvec;
+               nexttick = time + sys_frametime;
 
-               if((time + 0.1) < self.animstate_endtime) {
-
+               if(nexttick < self.animstate_endtime) {
                        traveltime = self.animstate_endtime - self.animstate_starttime;
-                       movephase = ((time + 0.1) - self.animstate_starttime) / traveltime;
-                       phasepos = sin(movephase * 3.14159265 / 2);
+                       phasepos = (nexttick - self.animstate_starttime) / traveltime; // range: [0, 1]
+                       phasepos = 3.14159265 + (phasepos * 3.14159265); // range: [pi, 2pi]
+                       phasepos = cos(phasepos); // cos [pi, 2pi] is in [-1, 1]
+                       phasepos = phasepos + 1; // correct range to [0, 2]
+                       phasepos = phasepos / 2; // correct range to [0, 1]
                        nextpos = self.origin + (delta * phasepos);
 
                        veloc = nextpos - self.owner.origin;
-                       veloc = veloc * 10; // so it arrives in 0.1 seconds
-                       self.nextthink = time + 0.1;
+                       veloc = veloc * (1 / sys_frametime); // so it arrives for the next frame
+
                } else {
-                       remaining = self.animstate_endtime - time;
                        veloc = self.finaldest - self.owner.origin;
-                       veloc = veloc * (1 / remaining); // so it'll arrive in the remaining time
-                       self.nextthink = self.animstate_endtime;
+                       veloc = veloc * (1 / sys_frametime); // so it arrives for the next frame
                }
-
                self.owner.velocity = veloc;
-
+               self.nextthink = nexttick;
        } else {
                oldself = self;
                self.owner.think = self.think1;
@@ -248,9 +250,11 @@ void SUB_CalcMove (vector tdest, float tspeed, void() func)
                return;
        }
 
-       // the controller only thinks every 0.1 seconds, so very short
-       // animations should just use the traditional movement
-       if (traveltime < 0.3)
+       // 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)
+       if (traveltime < 0.15 || self.platmovetype == 1)
        {
                self.velocity = delta * (1/traveltime); // QuakeC doesn't allow vector/float division
                self.nextthink = self.ltime + traveltime;
@@ -261,7 +265,7 @@ void SUB_CalcMove (vector tdest, float tspeed, void() func)
        controller.classname = "SUB_CalcMove_controller";
        controller.owner = self;
        controller.origin = self.origin; // starting point
-       controller.finaldest = tdest; // where do we want to end?
+       controller.finaldest = (tdest + '0 0 0.125'); // where do we want to end? Offset to overshoot a bit.
        controller.destvec = delta;
        controller.animstate_starttime = time;
        controller.animstate_endtime = time + traveltime;
@@ -431,13 +435,13 @@ void traceline_antilag_force (entity source, vector v1, vector v2, float nomonst
 }
 void traceline_antilag (entity source, vector v1, vector v2, float nomonst, entity forent, float lag)
 {
-       if (cvar("g_antilag") != 2 || source.cvar_cl_noantilag)
+       if (autocvar_g_antilag != 2 || source.cvar_cl_noantilag)
                lag = 0;
        traceline_antilag_force(source, v1, v2, nomonst, forent, lag);
 }
 void tracebox_antilag (entity source, vector v1, vector mi, vector ma, vector v2, float nomonst, entity forent, float lag)
 {
-       if (cvar("g_antilag") != 2 || source.cvar_cl_noantilag)
+       if (autocvar_g_antilag != 2 || source.cvar_cl_noantilag)
                lag = 0;
        tracebox_antilag_force_wz(source, v1, mi, ma, v2, nomonst, forent, lag, FALSE);
 }
@@ -447,13 +451,13 @@ void WarpZone_traceline_antilag_force (entity source, vector v1, vector v2, floa
 }
 void WarpZone_traceline_antilag (entity source, vector v1, vector v2, float nomonst, entity forent, float lag)
 {
-       if (cvar("g_antilag") != 2 || source.cvar_cl_noantilag)
+       if (autocvar_g_antilag != 2 || source.cvar_cl_noantilag)
                lag = 0;
        WarpZone_traceline_antilag_force(source, v1, v2, nomonst, forent, lag);
 }
 void WarpZone_tracebox_antilag (entity source, vector v1, vector mi, vector ma, vector v2, float nomonst, entity forent, float lag)
 {
-       if (cvar("g_antilag") != 2 || source.cvar_cl_noantilag)
+       if (autocvar_g_antilag != 2 || source.cvar_cl_noantilag)
                lag = 0;
        tracebox_antilag_force_wz(source, v1, mi, ma, v2, nomonst, forent, lag, TRUE);
 }
@@ -676,9 +680,9 @@ float LOD_customize()
 {
        float d;
 
-       if(cvar("loddebug"))
+       if(autocvar_loddebug)
        {
-               d = cvar("loddebug");
+               d = autocvar_loddebug;
                if(d == 1)
                        self.modelindex = self.lodmodelindex0;
                else if(d == 2 || !self.lodmodelindex2)
@@ -734,7 +738,7 @@ void LODmodel_attach()
                }
        }
 
-       if(cvar("loddebug") < 0)
+       if(autocvar_loddebug < 0)
        {
                self.lodmodel1 = self.lodmodel2 = ""; // don't even initialize
        }
@@ -765,6 +769,33 @@ void LODmodel_attach()
                        SetCustomizer(self, LOD_customize, LOD_uncustomize);
 }
 
+void ApplyMinMaxScaleAngles(entity e)
+{
+       if(e.angles_x != 0 || e.angles_z != 0 || self.avelocity_x != 0 || self.avelocity_z != 0) // "weird" rotation
+       {
+               e.maxs = '1 1 1' * vlen(
+                       '1 0 0' * max(-e.mins_x, e.maxs_x) +
+                       '0 1 0' * max(-e.mins_y, e.maxs_y) +
+                       '0 0 1' * max(-e.mins_z, e.maxs_z)
+               );
+               e.mins = -e.maxs;
+       }
+       else if(e.angles_y != 0 || self.avelocity_y != 0) // yaw only is a bit better
+       {
+               e.maxs_x = vlen(
+                       '1 0 0' * max(-e.mins_x, e.maxs_x) +
+                       '0 1 0' * max(-e.mins_y, e.maxs_y)
+               );
+               e.maxs_y = e.maxs_x;
+               e.mins_x = -e.maxs_x;
+               e.mins_y = -e.maxs_x;
+       }
+       if(e.scale)
+               setsize(e, e.mins * e.scale, e.maxs * e.scale);
+       else
+               setsize(e, e.mins, e.maxs);
+}
+
 void SetBrushEntityModel()
 {
        if(self.model != "")
@@ -774,10 +805,7 @@ void SetBrushEntityModel()
                InitializeEntity(self, LODmodel_attach, INITPRIO_FINDTARGET);
        }
        setorigin(self, self.origin);
-       if(self.scale)
-               setsize(self, self.mins * self.scale, self.maxs * self.scale);
-       else
-               setsize(self, self.mins, self.maxs);
+       ApplyMinMaxScaleAngles(self);
 }
 
 void SetBrushEntityModelNoLOD()
@@ -788,10 +816,7 @@ void SetBrushEntityModelNoLOD()
                setmodel(self, self.model); // no precision needed
        }
        setorigin(self, self.origin);
-       if(self.scale)
-               setsize(self, self.mins * self.scale, self.maxs * self.scale);
-       else
-               setsize(self, self.mins, self.maxs);
+       ApplyMinMaxScaleAngles(self);
 }
 
 /*
@@ -817,9 +842,7 @@ void InitTrigger()
 {
 // 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.
-       if (self.movedir == '0 0 0')
-       if (self.angles != '0 0 0')
-               SetMovedir ();
+       SetMovedir ();
        self.solid = SOLID_TRIGGER;
        SetBrushEntityModel();
        self.movetype = MOVETYPE_NONE;
@@ -831,9 +854,7 @@ void InitSolidBSPTrigger()
 {
 // 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.
-       if (self.movedir == '0 0 0')
-       if (self.angles != '0 0 0')
-               SetMovedir ();
+       SetMovedir ();
        self.solid = SOLID_BSP;
        SetBrushEntityModel();
        self.movetype = MOVETYPE_NONE; // why was this PUSH? -div0