1 void _Movetype_PushMove(float dt) // SV_PushMove
3 if (self.move_velocity == '0 0 0' && self.move_avelocity == '0 0 0')
11 // LordHavoc: valid pusher types
15 case SOLID_CORPSE: // LordHavoc: this would be weird...
17 // LordHavoc: no collisions
20 self.move_origin = self.move_origin + dt * self.move_velocity;
21 self.move_angles = self.move_angles + dt * self.move_avelocity;
22 self.move_angles_x -= 360.0 * floor(self.move_angles.x * (1.0 / 360.0));
23 self.move_angles_y -= 360.0 * floor(self.move_angles.y * (1.0 / 360.0));
24 self.move_angles_z -= 360.0 * floor(self.move_angles.z * (1.0 / 360.0));
25 self.move_ltime += dt;
26 _Movetype_LinkEdict(true);
29 LOG_TRACEF("_Movetype_PushMove: entity %e, unrecognized solid type %d\n", self, self.solid);
33 bool rotated = (self.move_angles * self.move_angles) + (self.move_avelocity * self.move_avelocity) > 0;
35 vector move1 = self.move_velocity * dt;
36 vector moveangle = self.move_avelocity * dt;
38 makevectors_matrix(-moveangle);
40 // vector pushorig = self.move_origin;
41 // vector pushang = self.move_angles;
42 // float pushltime = self.move_ltime;
44 // move the pusher to its final position
46 self.move_origin = self.move_origin + dt * self.move_velocity;
47 self.move_angles = self.move_angles + dt * self.move_avelocity;
49 self.move_ltime += dt;
50 _Movetype_LinkEdict(true);
52 int savesolid = self.solid;
54 if (self.move_movetype != MOVETYPE_FAKEPUSH)
56 for (entity check = findradius(0.5 * (self.absmin + self.absmax), 0.5 * vlen(self.absmax - self.absmin)); check; check = check.chain)
58 switch (check.move_movetype)
64 case MOVETYPE_FLY_WORLDONLY:
70 if (check.owner == self)
73 if (self.owner == check)
76 vector pivot = check.mins + 0.5 * (check.maxs - check.mins);
80 vector org = (check.move_origin - self.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, self, check, _Movetype_LinkEdict(true));
100 // try moving the contacted entity
101 self.solid = SOLID_NOT;
103 WITH(entity, self, check, {
104 flag = _Movetype_PushEntity(move, true);
108 // entity "check" got teleported
109 check.move_angles_y += trace_fraction * moveangle.y;
110 self.solid = savesolid;
111 continue; // pushed enough
113 // FIXME: turn players specially
114 check.move_angles_y += trace_fraction * moveangle.y;
115 self.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 != self))
121 check.move_flags &= ~FL_ONGROUND;
125 self.move_angles_x -= 360.0 * floor(self.move_angles.x * (1.0 / 360.0));
126 self.move_angles_y -= 360.0 * floor(self.move_angles.y * (1.0 / 360.0));
127 self.move_angles_z -= 360.0 * floor(self.move_angles.z * (1.0 / 360.0));
130 void _Movetype_Physics_Pusher(float dt) // SV_Physics_Pusher
132 float oldltime = self.move_ltime;
133 float thinktime = self.move_nextthink;
135 if (thinktime < self.move_ltime + dt)
137 movetime = thinktime - self.move_ltime;
147 // advances self.move_ltime if not blocked
148 _Movetype_PushMove(movetime);
150 if (thinktime > oldltime && thinktime <= self.move_ltime)
152 self.move_nextthink = 0;
153 self.move_time = time;