Xonotic
sv_physics.qc
Go to the documentation of this file.
1 #include "physics.qh"
2 
6 
7 void sys_phys_fix(entity this, float dt)
8 {
9  WarpZone_PlayerPhysics_FixVAngle(this);
10  Physics_UpdateStats(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);
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 
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';
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 
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 
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 }
float MOVETYPE_NONE
Definition: progsdefs.qc:246
string lastclassname
Definition: player.qh:67
float autocvar_sv_spectator_speed_multiplier_min
Definition: sv_physics.qc:4
#define PHYS_MAXAIRSPEED(s)
Definition: player.qh:130
float MOVETYPE_WALK
Definition: progsdefs.qc:249
float speed
Definition: subs.qh:41
void sys_phys_fixspeed(entity this, float maxspeed_mod)
Definition: sv_physics.qc:89
float autocvar_sv_maxidle
Definition: client.qh:36
STATIC_INIT(sys_phys)
Definition: sv_physics.qc:122
vector movement_old
Definition: player.qh:65
entity() spawn
ClientState CS(Client this)
Definition: state.qh:47
vector v_angle
Definition: progsdefs.qc:161
#define PHYS_INPUT_BUTTON_MASK(s)
Definition: player.qh:185
float autocvar_sv_spectator_speed_multiplier_max
Definition: sv_physics.qc:5
float jumppadcount
Definition: jumppads.qh:15
void PM_ClientMovement_UpdateStatus(entity this)
Definition: player.qc:122
bool sys_phys_override(entity this, float dt)
Definition: sv_physics.qc:14
float impulse
Definition: progsdefs.qc:158
float move_movetype
Definition: movetypes.qh:76
void PM_check_punch(entity this, float dt)
Definition: player.qc:585
bool PM_check_specialcommand(entity this, int buttons)
Definition: player.qc:530
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
void sys_phys_ai(entity this)
Definition: sv_physics.qc:38
void sys_phys_land(entity this)
Definition: sv_physics.qc:111
float autocvar_sv_maxidle_playertospectator
Definition: client.qh:38
#define LOG_TRACEF(...)
Definition: log.qh:82
int buttons_old
Definition: player.qh:64
void anticheat_physics(entity this)
Definition: anticheat.qc:64
float disableclientprediction
void sys_phys_monitor(entity this, float dt)
Definition: sv_physics.qc:25
vector movement
#define stuffcmd(cl,...)
Definition: progsdefs.qh:23
const string STR_PLAYER
Definition: utils.qh:5
#define IS_BOT_CLIENT(v)
want: (IS_CLIENT(v) && !IS_REAL_CLIENT(v))
Definition: utils.qh:15
#define new_pure(class)
purely logical entities (.origin doesn&#39;t work)
Definition: oo.qh:62
float autocvar_sv_spectator_speed_multiplier
Definition: sv_physics.qc:3
void bot_think(entity this)
Definition: bot.qc:57
#define subscribe(listener, T, fn)
Definition: lib.qh:22
float time
Definition: csprogsdefs.qc:16
vector velocity
Definition: csprogsdefs.qc:103
void sys_phys_pregame_hold(entity this)
Definition: sv_physics.qc:44
#define PHYS_MAXSPEED(s)
Definition: player.qh:132
void sys_phys_spectator_control(entity this)
Definition: sv_physics.qc:58
void set_movetype(entity this, int mt)
#define IS_PLAYER(v)
Definition: utils.qh:9
vector v_angle_old
Definition: player.qh:66
void PM_check_nickspam(entity this)
Definition: player.qc:563
void sys_phys_fix(entity this, float dt)
Definition: sv_physics.qc:7