Xonotic
push.qc File Reference
#include "push.qh"
+ Include dependency graph for push.qc:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void _Movetype_Physics_Push (entity this, float dt)
 
void _Movetype_PushMove (entity this, float dt)
 

Function Documentation

◆ _Movetype_Physics_Push()

void _Movetype_Physics_Push ( entity  this,
float  dt 
)

Definition at line 201 of file push.qc.

References _Movetype_PushMove(), getthink, ltime, and nextthink.

Referenced by _Movetype_Physics_Frame().

202 {
203  float oldltime = this.ltime;
204  float movetime = dt;
205  if(this.nextthink < this.ltime + dt)
206  {
207  movetime = this.nextthink - this.ltime;
208  if(movetime < 0)
209  movetime = 0;
210  }
211 
212  if(movetime)
213  {
214  // advances this.ltime if not blocked
215  _Movetype_PushMove(this, movetime);
216  }
217 
218  if(this.nextthink > oldltime && this.nextthink <= this.ltime)
219  {
220  this.nextthink = 0;
221  getthink(this)(this);
222  }
223 }
#define getthink(e)
float ltime
Definition: progsdefs.qc:107
float nextthink
Definition: csprogsdefs.qc:121
void _Movetype_PushMove(entity this, float dt)
Definition: push.qc:3
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _Movetype_PushMove()

void _Movetype_PushMove ( entity  this,
float  dt 
)

Definition at line 3 of file push.qc.

References _Movetype_LinkEdict(), _Movetype_NudgeOutOfSolid_PivotIsKnownGood(), _Movetype_PushEntity(), absmax, absmin, angles, avelocity, entity(), etof(), floor(), g_pushmove_moved, IL_CLEAR, IL_EACH, IL_PUSH(), IS_ONGROUND, LOG_INFOF, ltime, modelindex, move_movetype, MOVE_NOMONSTERS, MOVETYPE_FAKEPUSH, MOVETYPE_FLY_WORLDONLY, MOVETYPE_FOLLOW, MOVETYPE_NOCLIP, MOVETYPE_NONE, MOVETYPE_PHYSICS, MOVETYPE_PUSH, MOVETYPE_WALK, origin, pushltime, solid, SOLID_BBOX, SOLID_BSP, SOLID_CORPSE, SOLID_NOT, SOLID_SLIDEBOX, SOLID_TRIGGER, trace_fraction, trace_startsolid, UNSET_ONGROUND, vector(), velocity, vlen(), and vlen2.

Referenced by _Movetype_Physics_Push().

4 {
5  if(this.velocity == '0 0 0' && this.avelocity == '0 0 0')
6  {
7  this.ltime += dt;
8  return;
9  }
10 
11  switch(this.solid)
12  {
13  // LadyHavoc: valid pusher types
14  case SOLID_BSP:
15  case SOLID_BBOX:
16  case SOLID_SLIDEBOX:
17  case SOLID_CORPSE: // LadyHavoc: this would be weird...
18  break;
19  // LadyHavoc: no collisions
20  case SOLID_NOT:
21  case SOLID_TRIGGER:
22  {
23  this.origin = this.origin + dt * this.velocity;
24  this.angles = this.angles + dt * this.avelocity;
25  this.angles_x -= 360.0 * floor(this.angles_x * (1.0 / 360.0));
26  this.angles_y -= 360.0 * floor(this.angles_y * (1.0 / 360.0));
27  this.angles_z -= 360.0 * floor(this.angles_z * (1.0 / 360.0));
28  this.ltime += dt;
29  _Movetype_LinkEdict(this, false);
30  return;
31  }
32  default:
33  {
34  LOG_INFOF("_Movetype_Physics_Push: entity #%d, unrecognized solid type %d", etof(this), this.solid);
35  return;
36  }
37  }
38  if(!this.modelindex)
39  {
40  LOG_INFOF("_Movetype_Physics_Push: entity #%d has an invalid modelindex %d", etof(this), this.modelindex);
41  return;
42  }
43 
44  bool rotated = ((vlen2(this.angles) + vlen2(this.avelocity)) > 0);
45 
46  vector move1 = this.velocity * dt;
47  vector moveangle = this.avelocity * dt;
48 
49  vector a = -moveangle;
50  vector forward, left, up;
51  MAKE_VECTORS(a, forward, left, up);
52  left *= -1; // actually make it left!
53 
54  vector pushorig = this.origin;
55  vector pushang = this.angles;
56  float pushltime = this.ltime;
57 
58  // move the pusher to its final position
59 
60  this.origin = this.origin + dt * this.velocity;
61  this.angles = this.angles + dt * this.avelocity;
62  this.ltime += dt;
63  _Movetype_LinkEdict(this, false); // pulls absmin/absmax from the engine
64 
65  if(this.move_movetype == MOVETYPE_FAKEPUSH) // Tenebrae's MOVETYPE_PUSH variant that doesn't push...
66  {
67  this.angles_x -= 360.0 * floor(this.angles_x * (1.0 / 360.0));
68  this.angles_y -= 360.0 * floor(this.angles_y * (1.0 / 360.0));
69  this.angles_z -= 360.0 * floor(this.angles_z * (1.0 / 360.0));
70  return;
71  }
72 
73  IL_CLEAR(g_pushmove_moved); // make sure it's not somehow uncleared
74 
75  for(entity check = findradius((this.absmin + this.absmax) * 0.5, vlen(this.absmax - this.absmin) * 0.5 + 1); check; check = check.chain)
76  {
77  switch(check.move_movetype)
78  {
79  case MOVETYPE_NONE:
80  case MOVETYPE_PUSH:
81  case MOVETYPE_FOLLOW:
82  case MOVETYPE_NOCLIP:
84  continue;
85  default:
86  break;
87  }
88 
89  if(check.owner == this || this.owner == check)
90  continue;
91 
92  // if the entity is standing on the pusher, it will definitely be moved
93  // if the entity is not standing on the pusher, but is in the pusher's
94  // final position, move it
95  if (!IS_ONGROUND(check) || check.groundentity != this)
96  {
97  tracebox(check.origin, check.mins, check.maxs, check.origin, MOVE_NOMONSTERS, check);
98  if(!trace_startsolid)
99  continue;
100  }
101  vector pivot = check.mins + 0.5 * (check.maxs - check.mins);
102  vector move;
103 
104  if(rotated)
105  {
106  vector org = check.origin - this.origin;
107  org = org + pivot;
108 
109  vector org2;
110  org2.x = (org * forward);
111  org2.y = (org * left);
112  org2.z = (org * up);
113  move = org2 - org;
114  move = move + move1;
115  }
116  else
117  move = move1;
118 
119  check.moved_from = check.origin;
120  check.moved_fromangles = check.angles;
121  IL_PUSH(g_pushmove_moved, check);
122 
123  // physics objects need better collisions than this code can do
124  if(check.move_movetype == MOVETYPE_PHYSICS)
125  {
126  check.origin = check.origin + move;
127  _Movetype_LinkEdict(check, true);
128  continue;
129  }
130 
131  // try moving the contacted entity
132  int savesolid = this.solid;
133  this.solid = SOLID_NOT;
134  if(!_Movetype_PushEntity(check, move, true, true))
135  {
136  // entity "check" got teleported
137  check.angles_y += trace_fraction * moveangle.y;
138  this.solid = savesolid;
139  continue; // pushed enough
140  }
141  // FIXME: turn players specially
142  check.angles_y += trace_fraction * moveangle.y;
143  this.solid = savesolid;
144 
145  // this trace.fraction < 1 check causes items to fall off of pushers
146  // if they pass under or through a wall
147  // the groundentity check causes items to fall off of ledges
148  if(check.move_movetype != MOVETYPE_WALK && (trace_fraction < 1 || check.groundentity != this))
149  UNSET_ONGROUND(check);
150 
151  // if it is still inside the pusher, block
152  tracebox(check.origin, check.mins, check.maxs, check.origin, MOVE_NOMONSTERS, check);
153  if(trace_startsolid)
154  {
156  {
157  // hack to invoke all necessary movement triggers
158  _Movetype_PushEntity(check, '0 0 0', true, true);
159  // we could fix it or entity "check" was telported
160  continue;
161  }
162 
163  // still inside pusher, so it's really blocked
164 
165  // fail the move
166  if(check.mins_x == check.maxs_x)
167  continue;
168  if(check.solid == SOLID_NOT || check.solid == SOLID_TRIGGER)
169  {
170  // corpse
171  check.mins_x = check.mins_y = 0;
172  check.maxs = check.mins;
173  continue;
174  }
175 
176  this.origin = pushorig;
177  this.angles = pushang;
178  this.ltime = pushltime;
179  _Movetype_LinkEdict(this, false);
180 
181  // move back any entities we already moved
183  {
184  check.origin = check.moved_from;
185  check.angles = check.moved_fromangles;
186  _Movetype_LinkEdict(check, false);
187  });
188 
189  // if the pusher has a "blocked" function, call it, otherwise just stay in place until the obstacle is gone
190  if(getblocked(this))
191  getblocked(this)(this, check);
192  break;
193  }
194  }
195  this.angles_x -= 360.0 * floor(this.angles_x * (1.0 / 360.0));
196  this.angles_y -= 360.0 * floor(this.angles_y * (1.0 / 360.0));
197  this.angles_z -= 360.0 * floor(this.angles_z * (1.0 / 360.0));
198  IL_CLEAR(g_pushmove_moved); // clean up
199 }
const float SOLID_NOT
Definition: csprogsdefs.qc:244
#define IL_EACH(this, cond, body)
float MOVETYPE_NONE
Definition: progsdefs.qc:246
const float SOLID_SLIDEBOX
Definition: csprogsdefs.qc:247
float MOVETYPE_WALK
Definition: progsdefs.qc:249
#define IL_CLEAR(this)
Remove all elements.
const float MOVETYPE_PHYSICS
float modelindex
Definition: csprogsdefs.qc:91
entity() spawn
#define IS_ONGROUND(s)
Definition: movetypes.qh:16
float pushltime
Definition: jumppads.qh:10
origin
Definition: ent_cs.qc:114
vector avelocity
Definition: csprogsdefs.qc:105
float ltime
Definition: progsdefs.qc:107
#define UNSET_ONGROUND(s)
Definition: movetypes.qh:18
bool _Movetype_NudgeOutOfSolid_PivotIsKnownGood(entity this, vector pivot)
Definition: movetypes.qc:23
const int MOVETYPE_FAKEPUSH
Definition: movetypes.qh:154
float move_movetype
Definition: movetypes.qh:76
vector absmax
Definition: csprogsdefs.qc:92
IntrusiveList g_pushmove_moved
Definition: push.qh:7
const float MOVE_NOMONSTERS
Definition: csprogsdefs.qc:253
#define vlen2(v)
Definition: vector.qh:4
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
#define LOG_INFOF(...)
Definition: log.qh:71
float MOVETYPE_PUSH
Definition: progsdefs.qc:253
float MOVETYPE_FLY_WORLDONLY
void _Movetype_LinkEdict(entity this, bool touch_triggers)
Definition: movetypes.qc:512
vector(float skel, float bonenum) _skel_get_boneabs_hidden
float MOVETYPE_NOCLIP
Definition: progsdefs.qc:254
const float SOLID_BSP
Definition: csprogsdefs.qc:248
float MOVETYPE_FOLLOW
const float SOLID_TRIGGER
Definition: csprogsdefs.qc:245
const float SOLID_BBOX
Definition: csprogsdefs.qc:246
vector angles
Definition: csprogsdefs.qc:104
float trace_startsolid
Definition: csprogsdefs.qc:35
vector absmin
Definition: csprogsdefs.qc:92
bool _Movetype_PushEntity(entity this, vector push, bool failonstartsolid, bool dolink)
Definition: movetypes.qc:697
vector velocity
Definition: csprogsdefs.qc:103
float trace_fraction
Definition: csprogsdefs.qc:36
float solid
Definition: csprogsdefs.qc:99
const float SOLID_CORPSE
Definition: csprogsdefs.qc:249
+ Here is the call graph for this function:
+ Here is the caller graph for this function: