more clever conveyor implementation by plugging into cl_physics
authorRudolf Polzer <divverent@alientrap.org>
Thu, 29 Dec 2011 18:45:09 +0000 (19:45 +0100)
committerRudolf Polzer <divverent@alientrap.org>
Thu, 29 Dec 2011 18:45:09 +0000 (19:45 +0100)
qcsrc/server/cl_physics.qc
qcsrc/server/t_plats.qc

index b675c56..9364d72 100644 (file)
@@ -882,6 +882,26 @@ void SV_PlayerPhysics()
                swampspd_mod = self.swamp_slowdown; //cvar("g_balance_swamp_moverate");
        }
 
+       // conveyors: check if we still convey stuff
+       float conveyor_broken = FALSE;
+       if(self.groundentity.classname == "func_conveyor")
+       if(self.groundentity.nextthink)
+       {
+               if(!WarpZoneLib_BoxTouchesBrush(self.absmin + '0 0 -1', self.absmax + '0 0 -1', self.groundentity, self))
+                       self.groundentity = world;
+       }
+       if(!self.groundentity)
+       {
+               tracebox(self.origin + '0 0 -1', self.mins, self.maxs, self.origin + '0 0 -1', MOVE_NORMAL, self);
+               if(trace_ent.classname == "func_conveyor")
+                       self.groundentity = trace_ent;
+       }
+
+       // conveyors: first fix velocity
+       if(self.groundentity.classname == "func_conveyor")
+               if(self.groundentity.nextthink)
+                       self.velocity -= self.groundentity.movedir;
+
        if(self.classname != "player")
        {
                maxspd_mod = autocvar_sv_spectator_speed_multiplier;
@@ -1211,6 +1231,28 @@ void SV_PlayerPhysics()
                                self.velocity = self.velocity * f;
                        else
                                self.velocity = '0 0 0';
+                       /*
+                          Mathematical analysis time!
+
+                          Our goal is to invert this mess.
+
+                          For the two cases we get:
+                               v = v0 * (1 - frametime * (autocvar_sv_stopspeed / v0) * autocvar_sv_friction)
+                                 = v0 - frametime * autocvar_sv_stopspeed * autocvar_sv_friction
+                               v0 = v + frametime * autocvar_sv_stopspeed * autocvar_sv_friction
+                          and
+                               v = v0 * (1 - frametime * autocvar_sv_friction)
+                               v0 = v / (1 - frametime * autocvar_sv_friction)
+
+                          These cases would be chosen ONLY if:
+                               v0 < autocvar_sv_stopspeed
+                               v + frametime * autocvar_sv_stopspeed * autocvar_sv_friction < autocvar_sv_stopspeed
+                               v < autocvar_sv_stopspeed * (1 - frametime * autocvar_sv_friction)
+                          and, respectively:
+                               v0 >= autocvar_sv_stopspeed
+                               v / (1 - frametime * autocvar_sv_friction) >= autocvar_sv_stopspeed
+                               v >= autocvar_sv_stopspeed * (1 - frametime * autocvar_sv_friction)
+                        */
                }
 
                // acceleration
@@ -1339,6 +1381,11 @@ void SV_PlayerPhysics()
        if(self.flags & FL_ONGROUND)
                self.lastground = time;
 
+       // conveyors: then break velocity again
+       if(self.groundentity.classname == "func_conveyor")
+               if(self.groundentity.nextthink)
+                       self.velocity += self.groundentity.movedir;
+
        self.lastflags = self.flags;
        self.lastclassname = self.classname;
 }
index 6089120..8af076c 100644 (file)
@@ -2060,23 +2060,13 @@ void conveyor_think()
 {
        for(other = world; (other = findentity(other, groundentity, self)); )
        {
-               if(!WarpZoneLib_BoxTouchesBrush(other.absmin + '0 0 -1', other.absmax + '0 0 -1', self, other))
-               {
-                       other.flags &~= FL_ONGROUND;
-                       continue;
-               }
                if(other.flags & FL_CLIENT) // doing it via velocity has quite some advantages
-               {
-                       float f = 1 - frametime * autocvar_sv_friction;
-                       if(f > 0)
-                               other.velocity += self.movedir * self.speed * (1 / f - 1);
-               }
-               else
-               {
-                       tracebox(other.origin, other.mins, other.maxs, other.origin + self.movedir * (self.speed * sys_frametime), MOVE_NORMAL, other);
-                       if(trace_fraction > 0)
-                               setorigin(other, trace_endpos);
-               }
+                       continue; // done in SV_PlayerPhysics
+
+               // stupid conveyor code
+               tracebox(other.origin, other.mins, other.maxs, other.origin + self.movedir * sys_frametime, MOVE_NORMAL, other);
+               if(trace_fraction > 0)
+                       setorigin(other, trace_endpos);
        }
        self.nextthink = time;
 }
@@ -2105,6 +2095,7 @@ void spawnfunc_func_conveyor()
        self.movetype = MOVETYPE_NONE;
        if (!self.speed)
                self.speed = 200;
+       self.movedir = self.movedir * self.speed;
        self.think = conveyor_think;
        IFTARGETED
        {