-#ifdef IMPLEMENTATION
+#include "bugrigs.qh"
+
+#ifdef GAMEQC
+
#ifdef SVQC
#include <server/antilag.qh>
#endif
#endif
-void RaceCarPhysics(entity this)
+float racecar_angle(float forward, float down)
+{
+ if (forward < 0)
+ {
+ forward = -forward;
+ down = -down;
+ }
+
+ float ret = vectoyaw('0 1 0' * down + '1 0 0' * forward);
+
+ float angle_mult = forward / (800 + forward);
+
+ if (ret > 180)
+ return ret * angle_mult + 360 * (1 - angle_mult);
+ else
+ return ret * angle_mult;
+}
+
+void RaceCarPhysics(entity this, float dt)
{
// using this move type for "big rigs"
// the engine does not push the entity!
vector rigvel;
vector angles_save = this.angles;
- float accel = bound(-1, this.movement.x / PHYS_MAXSPEED(this), 1);
- float steer = bound(-1, this.movement.y / PHYS_MAXSPEED(this), 1);
+ float accel = bound(-1, PHYS_CS(this).movement.x / PHYS_MAXSPEED(this), 1);
+ float steer = bound(-1, PHYS_CS(this).movement.y / PHYS_MAXSPEED(this), 1);
if (PHYS_BUGRIGS_REVERSE_SPEEDING(this))
{
float upspeed = this.velocity * v_up;
// responsiveness factor for steering and acceleration
- float f = 1 / (1 + pow(max(-myspeed, myspeed) / PHYS_BUGRIGS_SPEED_REF(this), PHYS_BUGRIGS_SPEED_POW(this)));
+ float f = 1 / (1 + ((max(-myspeed, myspeed) / PHYS_BUGRIGS_SPEED_REF(this)) ** PHYS_BUGRIGS_SPEED_POW(this)));
//MAXIMA: f(v) := 1 / (1 + (v / PHYS_BUGRIGS_SPEED_REF(this)) ^ PHYS_BUGRIGS_SPEED_POW(this));
float steerfactor;
{
if (myspeed > 0)
{
- myspeed = max(0, myspeed - PHYS_INPUT_TIMELENGTH * (PHYS_BUGRIGS_FRICTION_FLOOR(this) - PHYS_BUGRIGS_FRICTION_BRAKE(this) * accel));
+ myspeed = max(0, myspeed - dt * (PHYS_BUGRIGS_FRICTION_FLOOR(this) - PHYS_BUGRIGS_FRICTION_BRAKE(this) * accel));
}
else
{
if (!PHYS_BUGRIGS_REVERSE_SPEEDING(this))
- myspeed = min(0, myspeed + PHYS_INPUT_TIMELENGTH * PHYS_BUGRIGS_FRICTION_FLOOR(this));
+ myspeed = min(0, myspeed + dt * PHYS_BUGRIGS_FRICTION_FLOOR(this));
}
}
else
{
if (myspeed >= 0)
{
- myspeed = max(0, myspeed - PHYS_INPUT_TIMELENGTH * PHYS_BUGRIGS_FRICTION_FLOOR(this));
+ myspeed = max(0, myspeed - dt * PHYS_BUGRIGS_FRICTION_FLOOR(this));
}
else
{
if (PHYS_BUGRIGS_REVERSE_STOPPING(this))
myspeed = 0;
else
- myspeed = min(0, myspeed + PHYS_INPUT_TIMELENGTH * (PHYS_BUGRIGS_FRICTION_FLOOR(this) + PHYS_BUGRIGS_FRICTION_BRAKE(this) * accel));
+ myspeed = min(0, myspeed + dt * (PHYS_BUGRIGS_FRICTION_FLOOR(this) + PHYS_BUGRIGS_FRICTION_BRAKE(this) * accel));
}
}
// terminal velocity = velocity at which 50 == accelfactor, that is, 1549 units/sec
//MAXIMA: friction(v) := PHYS_BUGRIGS_FRICTION_FLOOR(this);
- this.angles_y += steer * PHYS_INPUT_TIMELENGTH * steerfactor; // apply steering
+ this.angles_y += steer * dt * steerfactor; // apply steering
makevectors(this.angles); // new forward direction!
- myspeed += accel * accelfactor * PHYS_INPUT_TIMELENGTH;
+ myspeed += accel * accelfactor * dt;
rigvel = myspeed * v_forward + '0 0 1' * upspeed;
}
float myspeed = vlen(this.velocity);
// responsiveness factor for steering and acceleration
- float f = 1 / (1 + pow(max(0, myspeed / PHYS_BUGRIGS_SPEED_REF(this)), PHYS_BUGRIGS_SPEED_POW(this)));
+ float f = 1 / (1 + (max(0, myspeed / PHYS_BUGRIGS_SPEED_REF(this)) ** PHYS_BUGRIGS_SPEED_POW(this)));
float steerfactor = -myspeed * f;
- this.angles_y += steer * PHYS_INPUT_TIMELENGTH * steerfactor; // apply steering
+ this.angles_y += steer * dt * steerfactor; // apply steering
rigvel = this.velocity;
makevectors(this.angles); // new forward direction!
}
- rigvel *= max(0, 1 - vlen(rigvel) * PHYS_BUGRIGS_FRICTION_AIR(this) * PHYS_INPUT_TIMELENGTH);
+ rigvel *= max(0, 1 - vlen(rigvel) * PHYS_BUGRIGS_FRICTION_AIR(this) * dt);
//MAXIMA: airfriction(v) := v * v * PHYS_BUGRIGS_FRICTION_AIR(this);
//MAXIMA: total_acceleration(v) := accel(v) - friction(v) - airfriction(v);
//MAXIMA: solve(total_acceleration(v) = 0, v);
vector rigvel_xy, neworigin, up;
float mt;
- rigvel_z -= PHYS_INPUT_TIMELENGTH * PHYS_GRAVITY(this); // 4x gravity plays better
+ rigvel_z -= dt * PHYS_GRAVITY(this); // 4x gravity plays better
rigvel_xy = vec2(rigvel);
if (PHYS_BUGRIGS_CAR_JUMPING(this))
// BUG RIGS: align the move to the surface instead of doing collision testing
// can we move?
- tracebox(trace_endpos, this.mins, this.maxs, trace_endpos + rigvel_xy * PHYS_INPUT_TIMELENGTH, mt, this);
+ tracebox(trace_endpos, this.mins, this.maxs, trace_endpos + rigvel_xy * dt, mt, this);
// align to surface
- tracebox(trace_endpos, this.mins, this.maxs, trace_endpos - up + '0 0 1' * rigvel_z * PHYS_INPUT_TIMELENGTH, mt, this);
+ tracebox(trace_endpos, this.mins, this.maxs, trace_endpos - up + '0 0 1' * rigvel_z * dt, mt, this);
if (trace_fraction < 0.5)
{
{
// now set angles_x so that the car points parallel to the surface
this.angles = vectoangles(
- '1 0 0' * v_forward_x * trace_plane_normal_z
+ '1 0 0' * v_forward.x * trace_plane_normal.z
+
- '0 1 0' * v_forward_y * trace_plane_normal_z
+ '0 1 0' * v_forward.y * trace_plane_normal.z
+
- '0 0 1' * -(v_forward_x * trace_plane_normal_x + v_forward_y * trace_plane_normal_y)
+ '0 0 1' * -(v_forward.x * trace_plane_normal.x + v_forward.y * trace_plane_normal.y)
);
SET_ONGROUND(this);
}
UNSET_ONGROUND(this);
}
- this.velocity = (neworigin - this.origin) * (1.0 / PHYS_INPUT_TIMELENGTH);
+ this.velocity = (neworigin - this.origin) * (1.0 / dt);
set_movetype(this, MOVETYPE_NOCLIP);
}
else
{
- rigvel_z -= PHYS_INPUT_TIMELENGTH * PHYS_GRAVITY(this); // 4x gravity plays better
+ rigvel_z -= dt * PHYS_GRAVITY(this); // 4x gravity plays better
this.velocity = rigvel;
set_movetype(this, MOVETYPE_FLY);
}
if (trace_fraction != 1)
{
this.angles = vectoangles2(
- '1 0 0' * v_forward_x * trace_plane_normal_z
+ '1 0 0' * v_forward.x * trace_plane_normal.z
+
- '0 1 0' * v_forward_y * trace_plane_normal_z
+ '0 1 0' * v_forward.y * trace_plane_normal.z
+
- '0 0 1' * -(v_forward_x * trace_plane_normal_x + v_forward_y * trace_plane_normal_y),
+ '0 0 1' * -(v_forward.x * trace_plane_normal.x + v_forward.y * trace_plane_normal.y),
trace_plane_normal
);
}
{
vector vel_local;
- vel_local_x = v_forward * this.velocity;
- vel_local_y = v_right * this.velocity;
- vel_local_z = v_up * this.velocity;
+ vel_local.x = v_forward * this.velocity;
+ vel_local.y = v_right * this.velocity;
+ vel_local.z = v_up * this.velocity;
- this.angles_x = racecar_angle(vel_local_x, vel_local_z);
- this.angles_z = racecar_angle(-vel_local_y, vel_local_z);
+ this.angles_x = racecar_angle(vel_local.x, vel_local.z);
+ this.angles_z = racecar_angle(-vel_local.y, vel_local.z);
}
// smooth the angles
vector vf1, vu1, smoothangles;
makevectors(this.angles);
- float f = bound(0, PHYS_INPUT_TIMELENGTH * PHYS_BUGRIGS_ANGLE_SMOOTHING(this), 1);
+ float f = bound(0, dt * PHYS_BUGRIGS_ANGLE_SMOOTHING(this), 1);
if (f == 0)
f = 1;
vf1 = v_forward * f;
vf1 = vf1 + v_forward * (1 - f);
vu1 = vu1 + v_up * (1 - f);
smoothangles = vectoangles2(vf1, vu1);
- this.angles_x = -smoothangles_x;
- this.angles_z = smoothangles_z;
+ this.angles_x = -smoothangles.x;
+ this.angles_z = smoothangles.z;
}
#ifdef SVQC
MUTATOR_HOOKFUNCTION(bugrigs, PM_Physics)
{
entity player = M_ARGV(0, entity);
+ float dt = M_ARGV(2, float);
if(!PHYS_BUGRIGS(player) || !IS_PLAYER(player)) { return; }
player.angles = player.bugrigs_prevangles;
#endif
- RaceCarPhysics(player);
+ RaceCarPhysics(player, dt);
return true;
}
}
#endif
+
#endif