1 void _Movetype_PushMove(entity this, float dt) // SV_PushMove
3 if (this.move_velocity == '0 0 0' && this.move_avelocity == '0 0 0')
11 // LordHavoc: valid pusher types
15 case SOLID_CORPSE: // LordHavoc: this would be weird...
17 // LordHavoc: no collisions
20 this.move_origin = this.move_origin + dt * this.move_velocity;
21 this.move_angles = this.move_angles + dt * this.move_avelocity;
22 this.move_angles_x -= 360.0 * floor(this.move_angles.x * (1.0 / 360.0));
23 this.move_angles_y -= 360.0 * floor(this.move_angles.y * (1.0 / 360.0));
24 this.move_angles_z -= 360.0 * floor(this.move_angles.z * (1.0 / 360.0));
25 this.move_ltime += dt;
26 _Movetype_LinkEdict(this, true);
29 LOG_TRACEF("_Movetype_PushMove: entity %e, unrecognized solid type %d\n", this, this.solid);
33 bool rotated = (this.move_angles * this.move_angles) + (this.move_avelocity * this.move_avelocity) > 0;
35 vector move1 = this.move_velocity * dt;
36 vector moveangle = this.move_avelocity * dt;
38 makevectors_matrix(-moveangle);
40 // vector pushorig = this.move_origin;
41 // vector pushang = this.move_angles;
42 // float pushltime = this.move_ltime;
44 // move the pusher to its final position
46 this.move_origin = this.move_origin + dt * this.move_velocity;
47 this.move_angles = this.move_angles + dt * this.move_avelocity;
49 this.move_ltime += dt;
50 _Movetype_LinkEdict(this, true);
52 int savesolid = this.solid;
54 if (this.move_movetype != MOVETYPE_FAKEPUSH)
56 for (entity check = findradius(0.5 * (this.absmin + this.absmax), 0.5 * vlen(this.absmax - this.absmin)); check; check = check.chain)
58 switch (check.move_movetype)
64 case MOVETYPE_FLY_WORLDONLY:
70 if (check.owner == this)
73 if (this.owner == check)
76 vector pivot = check.mins + 0.5 * (check.maxs - check.mins);
80 vector org = (check.move_origin - this.move_origin) + pivot;
82 org2.x = org * v_forward;
83 org2.y = org * v_right;
85 move = (org2 - org) + move1;
92 // physics objects need better collisions than this code can do
93 if (check.move_movetype == 32) // MOVETYPE_PHYSICS
95 check.move_origin = check.move_origin + move;
96 WITH(entity, this, check, _Movetype_LinkEdict(this, true));
100 // try moving the contacted entity
101 this.solid = SOLID_NOT;
103 WITH(entity, this, check, {
104 flag = _Movetype_PushEntity(this, move, true);
108 // entity "check" got teleported
109 check.move_angles_y += trace_fraction * moveangle.y;
110 this.solid = savesolid;
111 continue; // pushed enough
113 // FIXME: turn players specially
114 check.move_angles_y += trace_fraction * moveangle.y;
115 this.solid = savesolid;
117 // this trace.fraction < 1 check causes items to fall off of pushers
118 // if they pass under or through a wall
119 // the groundentity check causes items to fall off of ledges
120 if (check.move_movetype != MOVETYPE_WALK && (trace_fraction < 1 || check.move_groundentity != this))
121 check.move_flags &= ~FL_ONGROUND;
125 this.move_angles_x -= 360.0 * floor(this.move_angles.x * (1.0 / 360.0));
126 this.move_angles_y -= 360.0 * floor(this.move_angles.y * (1.0 / 360.0));
127 this.move_angles_z -= 360.0 * floor(this.move_angles.z * (1.0 / 360.0));
130 void _Movetype_Physics_Pusher(entity this, float dt) // SV_Physics_Pusher
132 float oldltime = this.move_ltime;
133 float thinktime = this.move_nextthink;
135 if (thinktime < this.move_ltime + dt)
137 movetime = thinktime - this.move_ltime;
147 // advances this.move_ltime if not blocked
148 _Movetype_PushMove(this, movetime);
150 if (thinktime > oldltime && thinktime <= this.move_ltime)
152 this.move_nextthink = 0;
153 this.move_time = time;
155 WITH(entity, self, this, this.move_think());