]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/physics/movetypes/push.qc
Merge branch 'master' into terencehill/menu_optimization
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / physics / movetypes / push.qc
1 void _Movetype_PushMove(entity this, float dt)  // SV_PushMove
2 {
3         if (this.move_velocity == '0 0 0' && this.move_avelocity == '0 0 0')
4         {
5                 this.move_ltime += dt;
6                 return;
7         }
8
9         switch (this.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                         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);
27                         return;
28                 default:
29                         LOG_TRACEF("_Movetype_PushMove: entity %e, unrecognized solid type %d\n", this, this.solid);
30                         return;
31         }
32
33         bool rotated = (this.move_angles * this.move_angles) + (this.move_avelocity * this.move_avelocity) > 0;
34
35         vector move1 = this.move_velocity * dt;
36         vector moveangle = this.move_avelocity * dt;
37
38         makevectors_matrix(-moveangle);
39
40 //      vector pushorig = this.move_origin;
41 //      vector pushang = this.move_angles;
42 //      float pushltime = this.move_ltime;
43
44 // move the pusher to its final position
45
46         this.move_origin = this.move_origin + dt * this.move_velocity;
47         this.move_angles = this.move_angles + dt * this.move_avelocity;
48
49         this.move_ltime += dt;
50         _Movetype_LinkEdict(this, true);
51
52         int savesolid = this.solid;
53
54         if (this.move_movetype != MOVETYPE_FAKEPUSH)
55         {
56                 for (entity check = findradius(0.5 * (this.absmin + this.absmax), 0.5 * vlen(this.absmax - this.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 == this)
71                                 continue;
72
73                         if (this.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 - this.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, this, check, _Movetype_LinkEdict(this, true));
97                                 continue;
98                         }
99
100                         // try moving the contacted entity
101                         this.solid = SOLID_NOT;
102                         bool flag = false;
103                         WITH(entity, this, check, {
104                                 flag = _Movetype_PushEntity(this, move, true);
105                         });
106                         if (!flag)
107                         {
108                                 // entity "check" got teleported
109                                 check.move_angles_y += trace_fraction * moveangle.y;
110                                 this.solid = savesolid;
111                                 continue;  // pushed enough
112                         }
113                         // FIXME: turn players specially
114                         check.move_angles_y += trace_fraction * moveangle.y;
115                         this.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 != this))
121                                 check.move_flags &= ~FL_ONGROUND;
122                 }
123         }
124
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));
128 }
129
130 void _Movetype_Physics_Pusher(entity this, float dt)  // SV_Physics_Pusher
131 {
132         float oldltime = this.move_ltime;
133         float thinktime = this.move_nextthink;
134         float movetime;
135         if (thinktime < this.move_ltime + dt)
136         {
137                 movetime = thinktime - this.move_ltime;
138                 if (movetime < 0)
139                         movetime = 0;
140         }
141         else
142         {
143                 movetime = dt;
144         }
145
146         if (movetime)
147                 // advances this.move_ltime if not blocked
148                 _Movetype_PushMove(this, movetime);
149
150         if (thinktime > oldltime && thinktime <= this.move_ltime)
151         {
152                 this.move_nextthink = 0;
153                 this.move_time = time;
154                 other = world;
155                 WITH(entity, self, this, this.move_think());
156         }
157 }