]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/ecs/systems/sv_physics.qc
Merge branch 'terencehill/noclip_death_fix' into 'master'
[xonotic/xonotic-data.pk3dir.git] / qcsrc / ecs / systems / sv_physics.qc
1 #include "physics.qh"
2
3 void sys_phys_fix(entity this, float dt)
4 {
5         WarpZone_PlayerPhysics_FixVAngle(this);
6         Physics_UpdateStats(this);
7         PM_ClientMovement_UpdateStatus(this);
8 }
9
10 bool sys_phys_override(entity this, float dt)
11 {
12         int buttons = PHYS_INPUT_BUTTON_MASK(this);
13         float idlesince = CS(this).parm_idlesince;
14         CS(this).parm_idlesince = time; // in the case that physics are overridden
15         if (PM_check_specialcommand(this, buttons)) { return true; }
16         if (this.PlayerPhysplug && this.PlayerPhysplug(this, dt)) { return true; }
17         CS(this).parm_idlesince = idlesince;
18         return false;
19 }
20
21 void sys_phys_monitor(entity this, float dt)
22 {
23         int buttons = PHYS_INPUT_BUTTON_MASK(this);
24         anticheat_physics(this);
25         if (sv_maxidle > 0) {
26                 if (buttons != CS(this).buttons_old
27                     || CS(this).movement != CS(this).movement_old
28                     || this.v_angle != CS(this).v_angle_old) { CS(this).parm_idlesince = time; }
29         }
30         PM_check_nickspam(this);
31         PM_check_punch(this, dt);
32 }
33
34 void sys_phys_ai(entity this)
35 {
36         if (!IS_BOT_CLIENT(this)) { return; }
37         bot_think(this);
38 }
39
40 void sys_phys_pregame_hold(entity this)
41 {
42         if (!IS_PLAYER(this)) { return; }
43         const bool allowed_to_move = (time >= game_starttime && !game_stopped);
44         if (!allowed_to_move) {
45                 this.velocity = '0 0 0';
46                 set_movetype(this, MOVETYPE_NONE);
47                 this.disableclientprediction = 2;
48         } else if (this.disableclientprediction == 2) {
49                 if (this.move_movetype == MOVETYPE_NONE) { set_movetype(this, MOVETYPE_WALK); }
50                 this.disableclientprediction = 0;
51         }
52 }
53
54 void sys_phys_spectator_control(entity this)
55 {
56         float maxspeed_mod = autocvar_sv_spectator_speed_multiplier;
57         if (!STAT(SPECTATORSPEED, this)) { STAT(SPECTATORSPEED, this) = maxspeed_mod; }
58         if ((CS(this).impulse >= 1 && CS(this).impulse <= 19)
59             || (CS(this).impulse >= 200 && CS(this).impulse <= 209)
60             || (CS(this).impulse >= 220 && CS(this).impulse <= 229)
61            ) {
62                 if (this.lastclassname != STR_PLAYER) {
63                         if (CS(this).impulse == 10
64                             || CS(this).impulse == 15
65                             || CS(this).impulse == 18
66                             || (CS(this).impulse >= 200 && CS(this).impulse <= 209)
67                            ) {
68                                 STAT(SPECTATORSPEED, this) = bound(autocvar_sv_spectator_speed_multiplier_min, STAT(SPECTATORSPEED, this) + 0.5, autocvar_sv_spectator_speed_multiplier_max);
69                         } else if (CS(this).impulse == 11) {
70                                 STAT(SPECTATORSPEED, this) = maxspeed_mod;
71                         } else if (CS(this).impulse == 12
72                             || CS(this).impulse == 16
73                             || CS(this).impulse == 19
74                             || (CS(this).impulse >= 220 && CS(this).impulse <= 229)
75                                   ) {
76                                 STAT(SPECTATORSPEED, this) = bound(autocvar_sv_spectator_speed_multiplier_min, STAT(SPECTATORSPEED, this) - 0.5, autocvar_sv_spectator_speed_multiplier_max);
77                         } else if (CS(this).impulse >= 1 && CS(this).impulse <= 9) {
78                                 STAT(SPECTATORSPEED, this) = 1 + 0.5 * (CS(this).impulse - 1);
79                         }
80                 }  // otherwise just clear
81                 CS(this).impulse = 0;
82         }
83 }
84
85 void sys_phys_fixspeed(entity this, float maxspeed_mod)
86 {
87         if (this.jumpspeedcap_min != autocvar_sv_jumpspeedcap_min) {
88                 this.jumpspeedcap_min = autocvar_sv_jumpspeedcap_min;
89                 stuffcmd(this, sprintf("\ncl_jumpspeedcap_min \"%s\"\n", autocvar_sv_jumpspeedcap_min));
90         }
91         if (this.jumpspeedcap_max != autocvar_sv_jumpspeedcap_max) {
92                 this.jumpspeedcap_max = autocvar_sv_jumpspeedcap_max;
93                 stuffcmd(this, sprintf("\ncl_jumpspeedcap_max \"%s\"\n", autocvar_sv_jumpspeedcap_max));
94         }
95 }
96
97 void sys_phys_land(entity this)
98 {
99         if (autocvar_speedmeter) {
100                 LOG_TRACEF("landing velocity: %v (abs: %f)", this.velocity, vlen(this.velocity));
101         }
102         if (this.jumppadcount > 1) {
103                 LOG_TRACEF("%dx jumppad combo", this.jumppadcount);
104         }
105         this.jumppadcount = 0;
106 }
107
108 STATIC_INIT(sys_phys)
109 {
110         entity listener = new_pure(sys_phys);
111         subscribe(listener, phys_land, sys_phys_land);
112 }