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