]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/movetypes/push.qc
Merge branch 'master' into sev/luma_revisions
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / movetypes / push.qc
1 void _Movetype_PushMove(float dt)  // SV_PushMove
2 {
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                         dprintf("_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                                 entity oldself = self;
97                                 self = check;
98                                 _Movetype_LinkEdict(true);
99                                 self = oldself;
100                                 continue;
101                         }
102
103                         // try moving the contacted entity
104                         self.solid = SOLID_NOT;
105                         entity oldself = self;
106                         self = check;
107                         if (!_Movetype_PushEntity(move, true))
108                         {
109                                 self = oldself;
110                                 // entity "check" got teleported
111                                 check.move_angles_y += trace_fraction * moveangle.y;
112                                 self.solid = savesolid;
113                                 continue;  // pushed enough
114                         }
115                         self = oldself;
116                         // FIXME: turn players specially
117                         check.move_angles_y += trace_fraction * moveangle.y;
118                         self.solid = savesolid;
119
120                         // this trace.fraction < 1 check causes items to fall off of pushers
121                         // if they pass under or through a wall
122                         // the groundentity check causes items to fall off of ledges
123                         if (check.move_movetype != MOVETYPE_WALK && (trace_fraction < 1 || check.move_groundentity != self))
124                                 check.move_flags &= ~FL_ONGROUND;
125                 }
126         }
127
128         self.move_angles_x -= 360.0 * floor(self.move_angles.x * (1.0 / 360.0));
129         self.move_angles_y -= 360.0 * floor(self.move_angles.y * (1.0 / 360.0));
130         self.move_angles_z -= 360.0 * floor(self.move_angles.z * (1.0 / 360.0));
131 }
132
133 void _Movetype_Physics_Pusher(float dt)  // SV_Physics_Pusher
134 {
135         float oldltime = self.move_ltime;
136         float thinktime = self.move_nextthink;
137         float movetime;
138         if (thinktime < self.move_ltime + dt)
139         {
140                 movetime = thinktime - self.move_ltime;
141                 if (movetime < 0)
142                         movetime = 0;
143         }
144         else
145         {
146                 movetime = dt;
147         }
148
149         if (movetime)
150                 // advances self.move_ltime if not blocked
151                 _Movetype_PushMove(movetime);
152
153         if (thinktime > oldltime && thinktime <= self.move_ltime)
154         {
155                 self.move_nextthink = 0;
156                 self.move_time = time;
157                 other = world;
158                 if (self.move_think)
159                         self.move_think();
160         }
161 }