]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/ecs/systems/physics.qc
Merge branch 'master' into martin-t/globals
[xonotic/xonotic-data.pk3dir.git] / qcsrc / ecs / systems / physics.qc
index f5052b376f89f4072ca33ef968b3e4bba3d66f56..2fbb9d9d02862d1fe86712700987b759b96c8ae3 100644 (file)
@@ -6,6 +6,8 @@
 void sys_phys_simulate(entity this, float dt);
 void sys_phys_simulate_simple(entity this, float dt);
 
+void sys_phys_postupdate(entity this);
+
 void sys_phys_update(entity this, float dt)
 {
        if (!IS_CLIENT(this)) {
@@ -15,11 +17,14 @@ void sys_phys_update(entity this, float dt)
        sys_in_update(this, dt);
 
        sys_phys_fix(this, dt);
-       if (sys_phys_override(this)) { return; } sys_phys_monitor(this);
+       if (sys_phys_override(this, dt))
+               return;
+
+       sys_phys_monitor(this, dt);
 
-       this.buttons_old = PHYS_INPUT_BUTTON_MASK(this);
-       this.movement_old = this.movement;
-       this.v_angle_old = this.v_angle;
+       PHYS_CS(this).movement_old = PHYS_CS(this).movement;
+       PHYS_CS(this).v_angle_old = this.v_angle;
+       PHYS_CS(this).buttons_old = PHYS_INPUT_BUTTON_MASK(this);
 
        sys_phys_ai(this);
 
@@ -40,28 +45,32 @@ void sys_phys_update(entity this, float dt)
        float maxspeed_mod = (!this.in_swamp) ? 1 : this.swamp_slowdown;  // cvar("g_balance_swamp_moverate");
 
 // conveyors: first fix velocity
-       if (this.conveyor.state) { this.velocity -= this.conveyor.movedir; }
-       MUTATOR_CALLHOOK(PlayerPhysics, this);
+       if (this.conveyor.active) { this.velocity -= this.conveyor.movedir; }
+       MUTATOR_CALLHOOK(PlayerPhysics, this, dt);
 
        if (!IS_PLAYER(this)) {
                sys_phys_spectator_control(this);
-               maxspeed_mod = this.spectatorspeed;
+               maxspeed_mod = STAT(SPECTATORSPEED, this);
        }
        sys_phys_fixspeed(this, maxspeed_mod);
 
        if (IS_DEAD(this)) {
                // handle water here
                vector midpoint = ((this.absmin + this.absmax) * 0.5);
-               if (pointcontents(midpoint) == CONTENT_WATER) {
+               int cont = pointcontents(midpoint);
+               if (cont == CONTENT_WATER || cont == CONTENT_LAVA || cont == CONTENT_SLIME) {
                        this.velocity = this.velocity * 0.5;
 
                        // do we want this?
                        // if(pointcontents(midpoint + '0 0 2') == CONTENT_WATER)
                        // { this.velocity_z = 70; }
                }
-               goto end;
+               sys_phys_postupdate(this);
+               return;
        }
 
+       PM_check_slick(this);
+
        if (IS_SVQC && !PHYS_FIXANGLE(this)) { this.angles = '0 1 0' * this.v_angle.y; }
        if (IS_PLAYER(this)) {
                if (IS_ONGROUND(this)) {
@@ -84,7 +93,7 @@ void sys_phys_update(entity this, float dt)
                        PHYS_TELEPORT_TIME(this) = 0;
                        PHYS_WATERJUMP_TIME(this) = 0;
                }
-       } else if (MUTATOR_CALLHOOK(PM_Physics, this, maxspeed_mod)) {
+       } else if (MUTATOR_CALLHOOK(PM_Physics, this, maxspeed_mod, dt)) {
                // handled
        } else if (this.move_movetype == MOVETYPE_NOCLIP
            || this.move_movetype == MOVETYPE_FLY
@@ -102,6 +111,7 @@ void sys_phys_update(entity this, float dt)
                this.com_phys_water = true;
                sys_phys_simulate(this, dt);
                this.com_phys_water = false;
+               this.jumppadcount = 0;
        } else if (time < this.ladder_time) {
                this.com_phys_friction = PHYS_FRICTION(this);
                this.com_phys_vel_max = PHYS_MAXSPEED(this) * maxspeed_mod;
@@ -115,7 +125,7 @@ void sys_phys_update(entity this, float dt)
                this.com_phys_ladder = false;
                this.com_phys_gravity = '0 0 0';
        } else if (ITEMS_STAT(this) & IT_USING_JETPACK) {
-               PM_jetpack(this, maxspeed_mod);
+               PM_jetpack(this, maxspeed_mod, dt);
        } else if (IS_ONGROUND(this)) {
                if (!WAS_ONGROUND(this)) {
                        emit(phys_land, this);
@@ -146,10 +156,14 @@ void sys_phys_update(entity this, float dt)
                this.com_phys_air = false;
        }
 
-       LABEL(end)
+       sys_phys_postupdate(this);
+}
+
+void sys_phys_postupdate(entity this)
+{
        if (IS_ONGROUND(this)) { this.lastground = time; }
 // conveyors: then break velocity again
-       if (this.conveyor.state) { this.velocity += this.conveyor.movedir; }
+       if (this.conveyor.active) { this.velocity += this.conveyor.movedir; }
        this.lastflags = this.flags;
 
        this.lastclassname = this.classname;
@@ -158,9 +172,6 @@ void sys_phys_update(entity this, float dt)
 /** for players */
 void sys_phys_simulate(entity this, float dt)
 {
-       const vector g = -this.com_phys_gravity;
-       const bool jump = this.com_in_jump;
-
        if (!this.com_phys_ground && !this.com_phys_air) {
                // noclipping
                // flying
@@ -170,6 +181,7 @@ void sys_phys_simulate(entity this, float dt)
                UNSET_ONGROUND(this);
 
                if (this.com_phys_friction_air) {
+                       const vector g = -this.com_phys_gravity;
                        this.velocity_z += g.z / 2;
                        this.velocity = this.velocity * (1 - dt * this.com_phys_friction);
                        this.velocity_z += g.z / 2;
@@ -179,10 +191,9 @@ void sys_phys_simulate(entity this, float dt)
        if (this.com_phys_water) {
                // water jump only in certain situations
                // this mimics quakeworld code
-               if (jump && this.waterlevel == WATERLEVEL_SWIMMING && this.velocity_z >= -180 && !this.viewloc) {
+               if (this.com_in_jump && this.waterlevel == WATERLEVEL_SWIMMING && this.velocity_z >= -180 && !this.viewloc) {
                        vector yawangles = '0 1 0' * this.v_angle.y;
-                       makevectors(yawangles);
-                       vector forward = v_forward;
+                       MAKE_VECTORS_NEW(yawangles, forward, right, up);
                        vector spot = this.origin + 24 * forward;
                        spot_z += 8;
                        traceline(spot, spot, MOVE_NOMONSTERS, this);
@@ -198,11 +209,12 @@ void sys_phys_simulate(entity this, float dt)
                        }
                }
        }
-       makevectors(vmul(this.v_angle, (this.com_phys_vel_2d ? '0 1 0' : '1 1 1')));
-       // wishvel = v_forward * this.movement.x + v_right * this.movement.y + v_up * this.movement.z;
-       vector wishvel = v_forward * this.movement.x
-           + v_right * this.movement.y
-           + '0 0 1' * this.movement.z * (this.com_phys_vel_2d ? 0 : 1);
+
+       MAKE_VECTORS_NEW(vmul(this.v_angle, (this.com_phys_vel_2d ? '0 1 0' : '1 1 1')), forward, right, up);
+       // wishvel = forward * PHYS_CS(this).movement.x + right * PHYS_CS(this).movement.y + up * PHYS_CS(this).movement.z;
+       vector wishvel = forward * PHYS_CS(this).movement.x
+           + right * PHYS_CS(this).movement.y
+           + '0 0 1' * PHYS_CS(this).movement.z * (this.com_phys_vel_2d ? 0 : 1);
        if (this.com_phys_water) {
                if (PHYS_INPUT_BUTTON_CROUCH(this)) {
                        wishvel.z = -PHYS_MAXSPEED(this);
@@ -215,7 +227,7 @@ void sys_phys_simulate(entity this, float dt)
        }
        if (this.com_phys_ladder) {
                if (this.viewloc) {
-                       wishvel.z = this.oldmovement.x;
+                       wishvel.z = PHYS_CS(this).movement_old.x;
                }
                if (this.ladder_entity.classname == "func_water") {
                        float f = vlen(wishvel);
@@ -263,14 +275,14 @@ void sys_phys_simulate(entity this, float dt)
                                airaccel += (this.com_phys_acc_rate_air_stop - airaccel) * max(0, -(curdir * wishdir));
                        }
                        // note that for straight forward jumping:
-                       // step = accel * PHYS_INPUT_TIMELENGTH * wishspeed0;
+                       // step = accel * dt * wishspeed0;
                        // accel  = bound(0, wishspeed - vel_xy_current, step) * accelqw + step * (1 - accelqw);
                        // -->
                        // dv/dt = accel * maxspeed (when slow)
                        // dv/dt = accel * maxspeed * (1 - accelqw) (when fast)
                        // log dv/dt = logaccel + logmaxspeed (when slow)
                        // log dv/dt = logaccel + logmaxspeed + log(1 - accelqw) (when fast)
-                       float strafity = IsMoveInDirection(this.movement, -90) + IsMoveInDirection(this.movement, +90);  // if one is nonzero, other is always zero
+                       float strafity = IsMoveInDirection(PHYS_CS(this).movement, -90) + IsMoveInDirection(PHYS_CS(this).movement, +90);  // if one is nonzero, other is always zero
                        if (PHYS_MAXAIRSTRAFESPEED(this)) {
                                wishspeed =
                                    min(wishspeed,
@@ -287,16 +299,16 @@ void sys_phys_simulate(entity this, float dt)
                        }
                        // !CPM
 
-                       if (PHYS_WARSOWBUNNY_TURNACCEL(this) && accelerating && this.movement.y == 0 && this.movement.x != 0) {
-                               PM_AirAccelerate(this, wishdir, wishspeed2);
+                       if (PHYS_WARSOWBUNNY_TURNACCEL(this) && accelerating && PHYS_CS(this).movement.y == 0 && PHYS_CS(this).movement.x != 0) {
+                               PM_AirAccelerate(this, dt, wishdir, wishspeed2);
                        } else {
                                float sidefric = maxairspd ? (PHYS_AIRACCEL_SIDEWAYS_FRICTION(this) / maxairspd) : 0;
-                               PM_Accelerate(this, wishdir, wishspeed, wishspeed0, airaccel, airaccelqw,
+                               PM_Accelerate(this, dt, wishdir, wishspeed, wishspeed0, airaccel, airaccelqw,
                                        PHYS_AIRACCEL_QW_STRETCHFACTOR(this), sidefric, PHYS_AIRSPEEDLIMIT_NONQW(this));
                        }
 
                        if (PHYS_AIRCONTROL(this)) {
-                               CPM_PM_Aircontrol(this, wishdir, wishspeed2);
+                               CPM_PM_Aircontrol(this, dt, wishdir, wishspeed2);
                        }
                }
        } else {
@@ -318,7 +330,7 @@ void sys_phys_simulate(entity this, float dt)
                                }
 
                                // holding jump button swims upward slowly
-                               if (jump && !this.viewloc) {
+                               if (this.com_in_jump && !this.viewloc) {
                                        // was:
                                        // lava: 50
                                        // slime: 80
@@ -338,7 +350,7 @@ void sys_phys_simulate(entity this, float dt)
                                }
                        } else {
                                // water acceleration
-                               PM_Accelerate(this, wishdir, wishspeed, wishspeed, this.com_phys_acc_rate, 1, 0, 0, 0);
+                               PM_Accelerate(this, dt, wishdir, wishspeed, wishspeed, this.com_phys_acc_rate, 1, 0, 0, 0);
                        }
                        return;
                }
@@ -391,7 +403,7 @@ void sys_phys_simulate(entity this, float dt)
                }
 
                if (IS_CSQC ? PHYS_WATERJUMP_TIME(this) <= 0 : time >= PHYS_TELEPORT_TIME(this)) {
-                       PM_Accelerate(this, wishdir, wishspeed, wishspeed, this.com_phys_acc_rate, 1, 0, 0, 0);
+                       PM_Accelerate(this, dt, wishdir, wishspeed, wishspeed, this.com_phys_acc_rate, 1, 0, 0, 0);
                }
        }
 }