Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
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.

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}
float nextthink
float ltime
Definition net.qc:10
void _Movetype_PushMove(entity this, float dt)
Definition push.qc:3
#define getthink(e)

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

Referenced by _Movetype_Physics_Frame().

◆ _Movetype_PushMove()

void _Movetype_PushMove ( entity this,
float dt )

Definition at line 3 of file push.qc.

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);
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;
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))
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);
154 {
156 {
157 // hack to invoke all necessary movement triggers
158 _Movetype_PushEntity(check, '0 0 0', 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}
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
const float MOVE_NOMONSTERS
const float SOLID_SLIDEBOX
const float SOLID_TRIGGER
float modelindex
vector avelocity
const float SOLID_CORPSE
vector velocity
const float SOLID_BBOX
const float SOLID_NOT
float trace_startsolid
vector absmax
vector origin
float trace_fraction
vector absmin
const float SOLID_BSP
#define MAKE_VECTORS(angles, forward, right, up)
Same as the makevectors builtin but uses the provided locals instead of the v_* globals.
ent angles
Definition ent_cs.qc:121
angles_y
Definition ent_cs.qc:119
solid
Definition ent_cs.qc:165
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
#define IL_EACH(this, cond, body)
#define IL_CLEAR(this)
Remove all elements.
float pushltime
Definition jumppads.qh:21
#define LOG_INFOF(...)
Definition log.qh:66
float vlen(vector v)
float floor(float f)
#define etof(e)
Definition misc.qh:25
void _Movetype_LinkEdict(entity this, bool touch_triggers)
Definition movetypes.qc:516
bool _Movetype_PushEntity(entity this, vector push, bool dolink)
Definition movetypes.qc:668
bool _Movetype_NudgeOutOfSolid_PivotIsKnownGood(entity this, vector pivot)
Definition movetypes.qc:19
const int MOVETYPE_WALK
Definition movetypes.qh:132
const int MOVETYPE_NONE
Definition movetypes.qh:129
const int MOVETYPE_FOLLOW
Definition movetypes.qh:141
const int MOVETYPE_FAKEPUSH
Definition movetypes.qh:153
const int MOVETYPE_PUSH
Definition movetypes.qh:136
const int MOVETYPE_FLY_WORLDONLY
Definition movetypes.qh:143
float move_movetype
Definition movetypes.qh:76
#define UNSET_ONGROUND(s)
Definition movetypes.qh:18
const int MOVETYPE_PHYSICS
Definition movetypes.qh:142
const int MOVETYPE_NOCLIP
Definition movetypes.qh:137
#define IS_ONGROUND(s)
Definition movetypes.qh:16
IntrusiveList g_pushmove_moved
Definition push.qh:7
#define getblocked(e)
vector
Definition self.qh:92
vector org
Definition self.qh:92
#define vlen2(v)
Definition vector.qh:4

References _Movetype_LinkEdict(), _Movetype_NudgeOutOfSolid_PivotIsKnownGood(), _Movetype_PushEntity(), absmax, absmin, angles, angles_y, avelocity, entity(), etof, floor(), g_pushmove_moved, getblocked, IL_CLEAR, IL_EACH, IL_PUSH(), IS_ONGROUND, LOG_INFOF, ltime, MAKE_VECTORS, modelindex, move_movetype, MOVE_NOMONSTERS, MOVETYPE_FAKEPUSH, MOVETYPE_FLY_WORLDONLY, MOVETYPE_FOLLOW, MOVETYPE_NOCLIP, MOVETYPE_NONE, MOVETYPE_PHYSICS, MOVETYPE_PUSH, MOVETYPE_WALK, org, 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().