]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/g_subs.qc
Clean up g_subs a bit more
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / g_subs.qc
1 #include "g_subs.qh"
2
3 #include <server/defs.qh>
4 #include <server/miscfunctions.qh>
5 #include "antilag.qh"
6 #include "command/common.qh"
7 #include "../common/state.qh"
8 #include "../lib/warpzone/common.qh"
9 #include "../common/mapobjects/subs.qh"
10
11 /*
12 ==================
13 traceline_antilag
14
15 A version of traceline that must be used by SOLID_SLIDEBOX things that want to hit SOLID_CORPSE things with a trace attack
16 Additionally it moves players back into the past before the trace and restores them afterward.
17 ==================
18 */
19 void tracebox_antilag_force_wz (entity source, vector v1, vector mi, vector ma, vector v2, float nomonst, entity forent, float lag, float wz)
20 {
21         // check whether antilagged traces are enabled
22         if (lag < 0.001)
23                 lag = 0;
24         if (!IS_REAL_CLIENT(forent))
25                 lag = 0; // only antilag for clients
26
27         // change shooter to SOLID_BBOX so the shot can hit corpses
28         int oldsolid = source.dphitcontentsmask;
29         if(source)
30                 source.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
31
32         if (lag)
33                 antilag_takeback_all(forent, lag);
34
35         // do the trace
36         if(wz)
37                 WarpZone_TraceBox (v1, mi, ma, v2, nomonst, forent);
38         else
39                 tracebox (v1, mi, ma, v2, nomonst, forent);
40
41         // restore players to current positions
42         if (lag)
43                 antilag_restore_all(forent);
44
45         // restore shooter solid type
46         if(source)
47                 source.dphitcontentsmask = oldsolid;
48 }
49 void traceline_antilag_force (entity source, vector v1, vector v2, float nomonst, entity forent, float lag)
50 {
51         tracebox_antilag_force_wz(source, v1, '0 0 0', '0 0 0', v2, nomonst, forent, lag, false);
52 }
53 void traceline_antilag (entity source, vector v1, vector v2, float nomonst, entity forent, float lag)
54 {
55         bool noantilag = ((IS_CLIENT(source)) ? CS(source).cvar_cl_noantilag : false);
56         if (autocvar_g_antilag != 2 || noantilag)
57                 lag = 0;
58         traceline_antilag_force(source, v1, v2, nomonst, forent, lag);
59 }
60 void tracebox_antilag (entity source, vector v1, vector mi, vector ma, vector v2, float nomonst, entity forent, float lag)
61 {
62         bool noantilag = ((IS_CLIENT(source)) ? CS(source).cvar_cl_noantilag : false);
63         if (autocvar_g_antilag != 2 || noantilag)
64                 lag = 0;
65         tracebox_antilag_force_wz(source, v1, mi, ma, v2, nomonst, forent, lag, false);
66 }
67 void WarpZone_traceline_antilag_force (entity source, vector v1, vector v2, float nomonst, entity forent, float lag)
68 {
69         tracebox_antilag_force_wz(source, v1, '0 0 0', '0 0 0', v2, nomonst, forent, lag, true);
70 }
71 void WarpZone_traceline_antilag (entity source, vector v1, vector v2, float nomonst, entity forent, float lag)
72 {
73         bool noantilag = ((IS_CLIENT(source)) ? CS(source).cvar_cl_noantilag : false);
74         if (autocvar_g_antilag != 2 || noantilag)
75                 lag = 0;
76         WarpZone_traceline_antilag_force(source, v1, v2, nomonst, forent, lag);
77 }
78 void WarpZone_tracebox_antilag (entity source, vector v1, vector mi, vector ma, vector v2, float nomonst, entity forent, float lag)
79 {
80         bool noantilag = ((IS_CLIENT(source)) ? CS(source).cvar_cl_noantilag : false);
81         if (autocvar_g_antilag != 2 || noantilag)
82                 lag = 0;
83         tracebox_antilag_force_wz(source, v1, mi, ma, v2, nomonst, forent, lag, true);
84 }
85
86 float tracebox_inverted (vector v1, vector mi, vector ma, vector v2, float nomonsters, entity forent, float stopatentity, entity ignorestopatentity) // returns the number of traces done, for benchmarking
87 {
88         vector pos, dir, t;
89         float nudge;
90         entity stopentity;
91
92         //nudge = 2 * cvar("collision_impactnudge"); // why not?
93         nudge = 0.5;
94
95         dir = normalize(v2 - v1);
96
97         pos = v1 + dir * nudge;
98
99         float c;
100         c = 0;
101
102         for (;;)
103         {
104                 if(pos * dir >= v2 * dir)
105                 {
106                         // went too far
107                         trace_fraction = 1;
108                         trace_endpos = v2;
109                         return c;
110                 }
111
112                 tracebox(pos, mi, ma, v2, nomonsters, forent);
113                 ++c;
114
115                 if(c == 50)
116                 {
117                         LOG_TRACE("HOLY SHIT! When tracing from ", vtos(v1), " to ", vtos(v2));
118                         LOG_TRACE("  Nudging gets us nowhere at ", vtos(pos));
119                         LOG_TRACE("  trace_endpos is ", vtos(trace_endpos));
120                         LOG_TRACE("  trace distance is ", ftos(vlen(pos - trace_endpos)));
121                 }
122
123                 stopentity = trace_ent;
124
125                 if(trace_startsolid)
126                 {
127                         // we started inside solid.
128                         // then trace from endpos to pos
129                         t = trace_endpos;
130                         tracebox(t, mi, ma, pos, nomonsters, forent);
131                         ++c;
132                         if(trace_startsolid)
133                         {
134                                 // t is still inside solid? bad
135                                 // force advance, then, and retry
136                                 pos = t + dir * nudge;
137
138                                 // but if we hit an entity, stop RIGHT before it
139                                 if(stopatentity && stopentity && stopentity != ignorestopatentity)
140                                 {
141                                         trace_ent = stopentity;
142                                         trace_endpos = t;
143                                         trace_fraction = ((trace_endpos - v1) * dir) / ((v2 - v1) * dir);
144                                         return c;
145                                 }
146                         }
147                         else
148                         {
149                                 // we actually LEFT solid!
150                                 trace_fraction = ((trace_endpos - v1) * dir) / ((v2 - v1) * dir);
151                                 return c;
152                         }
153                 }
154                 else
155                 {
156                         // pos is outside solid?!? but why?!? never mind, just return it.
157                         trace_endpos = pos;
158                         trace_fraction = ((trace_endpos - v1) * dir) / ((v2 - v1) * dir);
159                         return c;
160                 }
161         }
162 }
163
164 void traceline_inverted (vector v1, vector v2, float nomonsters, entity forent, float stopatentity, entity ignorestopatentity)
165 {
166         tracebox_inverted(v1, '0 0 0', '0 0 0', v2, nomonsters, forent, stopatentity, ignorestopatentity);
167 }
168
169 /*
170 ==================
171 findbetterlocation
172
173 Returns a point at least 12 units away from walls
174 (useful for explosion animations, although the blast is performed where it really happened)
175 Ripped from DPMod
176 ==================
177 */
178 vector findbetterlocation (vector org, float mindist)
179 {
180         vector vec = mindist * '1 0 0';
181         int c = 0;
182         while (c < 6)
183         {
184                 traceline (org, org + vec, true, NULL);
185                 vec = vec * -1;
186                 if (trace_fraction < 1)
187                 {
188                         vector loc = trace_endpos;
189                         traceline (loc, loc + vec, true, NULL);
190                         if (trace_fraction >= 1)
191                                 org = loc + vec;
192                 }
193                 if (c & 1)
194                 {
195                         float h = vec.y;
196                         vec.y = vec.x;
197                         vec.x = vec.z;
198                         vec.z = h;
199                 }
200                 c = c + 1;
201         }
202
203         return org;
204 }