]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/movetypes/push.qc
Merge branch 'master' into TimePath/global_self
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / movetypes / push.qc
1 void _Movetype_PushMove(float dt)  // SV_PushMove
2 {SELFPARAM();
3         if (self.move_velocity == '0 0 0' && self.move_avelocity == '0 0 0')
4         {
5                 self.move_ltime += dt;
6                 return;
7         }
8
9         switch (self.solid)
10         {
11                 // LordHavoc: valid pusher types
12                 case SOLID_BSP:
13                 case SOLID_BBOX:
14                 case SOLID_SLIDEBOX:
15                 case SOLID_CORPSE:  // LordHavoc: this would be weird...
16                         break;
17                 // LordHavoc: no collisions
18                 case SOLID_NOT:
19                 case SOLID_TRIGGER:
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);
27                         return;
28                 default:
29                         LOG_TRACEF("_Movetype_PushMove: entity %e, unrecognized solid type %d\n", self, self.solid);
30                         return;
31         }
32
33         bool rotated = (self.move_angles * self.move_angles) + (self.move_avelocity * self.move_avelocity) > 0;
34
35         vector move1 = self.move_velocity * dt;
36         vector moveangle = self.move_avelocity * dt;
37
38         makevectors_matrix(-moveangle);
39
40 //      vector pushorig = self.move_origin;
41 //      vector pushang = self.move_angles;
42 //      float pushltime = self.move_ltime;
43
44 // move the pusher to its final position
45
46         self.move_origin = self.move_origin + dt * self.move_velocity;
47         self.move_angles = self.move_angles + dt * self.move_avelocity;
48
49         self.move_ltime += dt;
50         _Movetype_LinkEdict(true);
51
52         int savesolid = self.solid;
53
54         if (self.move_movetype != MOVETYPE_FAKEPUSH)
55         {
56                 for (entity check = findradius(0.5 * (self.absmin + self.absmax), 0.5 * vlen(self.absmax - self.absmin)); check; check = check.chain)
57                 {
58                         switch (check.move_movetype)
59                         {
60                                 case MOVETYPE_NONE:
61                                 case MOVETYPE_PUSH:
62                                 case MOVETYPE_FOLLOW:
63                                 case MOVETYPE_NOCLIP:
64                                 case MOVETYPE_FLY_WORLDONLY:
65                                         continue;
66                                 default:
67                                         break;
68                         }
69
70                         if (check.owner == self)
71                                 continue;
72
73                         if (self.owner == check)
74                                 continue;
75
76                         vector pivot = check.mins + 0.5 * (check.maxs - check.mins);
77                         vector move;
78                         if (rotated)
79                         {
80                                 vector org = (check.move_origin - self.move_origin) + pivot;
81                                 vector org2;
82                                 org2.x = org * v_forward;
83                                 org2.y = org * v_right;
84                                 org2.z = org * v_up;
85                                 move = (org2 - org) + move1;
86                         }
87                         else
88                         {
89                                 move = move1;
90                         }
91
92                         // physics objects need better collisions than this code can do
93                         if (check.move_movetype == 32)  // MOVETYPE_PHYSICS
94                         {
95                                 check.move_origin = check.move_origin + move;
96                                 WITH(entity, self, check, _Movetype_LinkEdict(true));
97                                 continue;
98                         }
99
100                         // try moving the contacted entity
101                         self.solid = SOLID_NOT;
102                         bool flag;
103                         WITH(entity, self, check, {
104                                 flag = _Movetype_PushEntity(move, true);
105                         });
106                         if (!flag)
107                         {
108                                 // entity "check" got teleported
109                                 check.move_angles_y += trace_fraction * moveangle.y;
110                                 self.solid = savesolid;
111                                 continue;  // pushed enough
112                         }
113                         // FIXME: turn players specially
114                         check.move_angles_y += trace_fraction * moveangle.y;
115                         self.solid = savesolid;
116
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;
122                 }
123         }
124
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));
128 }
129
130 void _Movetype_Physics_Pusher(float dt)  // SV_Physics_Pusher
131 {SELFPARAM();
132         float oldltime = self.move_ltime;
133         float thinktime = self.move_nextthink;
134         float movetime;
135         if (thinktime < self.move_ltime + dt)
136         {
137                 movetime = thinktime - self.move_ltime;
138                 if (movetime < 0)
139                         movetime = 0;
140         }
141         else
142         {
143                 movetime = dt;
144         }
145
146         if (movetime)
147                 // advances self.move_ltime if not blocked
148                 _Movetype_PushMove(movetime);
149
150         if (thinktime > oldltime && thinktime <= self.move_ltime)
151         {
152                 self.move_nextthink = 0;
153                 self.move_time = time;
154                 other = world;
155                 if (self.move_think)
156                         self.move_think();
157         }
158 }