]> de.git.xonotic.org Git - voretournament/voretournament.git/blob - data/qcsrc/client/projectile.qc
Include gmqcc binaries for Windows and Linux
[voretournament/voretournament.git] / data / qcsrc / client / projectile.qc
1 .vector iorigin1, iorigin2;\r
2 .float spawntime;\r
3 .vector trail_oldorigin;\r
4 .float trail_oldtime;\r
5 .float fade_time, fade_rate;\r
6 \r
7 void SUB_Null()\r
8 {\r
9 }\r
10 \r
11 void SUB_Stop()\r
12 {\r
13         self.move_velocity = self.move_avelocity = '0 0 0';\r
14         self.move_movetype = MOVETYPE_NONE;\r
15 }\r
16 \r
17 .float alphamod;\r
18 .float count; // set if clientside projectile\r
19 .float cnt; // sound index\r
20 .float gravity;\r
21 .float snd_looping;\r
22 .float silent;\r
23 .float traileffect;\r
24 \r
25 void Projectile_DrawTrail(vector to)\r
26 {\r
27         vector from;\r
28         float t0;\r
29         from = self.trail_oldorigin;\r
30         t0 = self.trail_oldtime;\r
31         self.trail_oldorigin = to;\r
32         self.trail_oldtime = time;\r
33 \r
34         if (self.traileffect)\r
35                 trailparticles(self, self.traileffect, from, to);\r
36 }\r
37 \r
38 void Projectile_Draw()\r
39 {\r
40         vector rot;\r
41         vector trailorigin;\r
42         float f;\r
43         float drawn;\r
44         float t;\r
45         float a;\r
46 \r
47         f = self.move_flags;\r
48 \r
49         if(self.count & 0x80)\r
50         {\r
51                 //self.move_flags &~= FL_ONGROUND;\r
52                 Movetype_Physics_MatchServer(autocvar_cl_projectiles_sloppy);\r
53                 if(!(self.move_flags & FL_ONGROUND))\r
54                         self.angles = vectoangles(self.velocity);\r
55         }\r
56         else\r
57         {\r
58                 InterpolateOrigin_Do();\r
59         }\r
60 \r
61         if(self.count & 0x80)\r
62         {\r
63                 drawn = (time >= self.spawntime - 0.02);\r
64                 t = max(time, self.spawntime);\r
65         }\r
66         else\r
67         {\r
68                 drawn = (self.iflags & IFLAG_VALID);\r
69                 t = time;\r
70         }\r
71 \r
72         if(!(f & FL_ONGROUND))\r
73         {\r
74                 rot = '0 0 0';\r
75                 switch(self.cnt)\r
76                 {\r
77                         /*\r
78                         case PROJECTILE_EXAMPLE:\r
79                                 rot = '0 0 0';\r
80                                 break;\r
81                         */\r
82                         default:\r
83                                 break;\r
84                 }\r
85                 self.angles = AnglesTransform_ToAngles(AnglesTransform_Multiply(AnglesTransform_FromAngles(self.angles), rot * (t - self.spawntime)));\r
86         }\r
87 \r
88         vector ang;\r
89         ang = self.angles;\r
90         ang_x = -ang_x;\r
91         makevectors(ang);\r
92 \r
93         a = 1 - (time - self.fade_time) * self.fade_rate;\r
94         if(a <= 0)\r
95                 drawn = 0;\r
96 \r
97         trailorigin = self.origin;\r
98         switch(self.cnt)\r
99         {\r
100                 case PROJECTILE_EXAMPLE:\r
101                         trailorigin += v_right * 1 + v_forward * -10;\r
102                         break;\r
103                 default:\r
104                         break;\r
105         }\r
106         if(drawn)\r
107                 Projectile_DrawTrail(trailorigin);\r
108         else\r
109         {\r
110                 self.trail_oldorigin = trailorigin;\r
111                 self.trail_oldtime = time;\r
112         }\r
113 \r
114         if(!drawn)\r
115                 return;\r
116 \r
117         switch(self.cnt)\r
118         {\r
119                 case PROJECTILE_EXAMPLE:\r
120                         R_AddDynamicLight(self.origin, 50 * a, '1 1 0');\r
121                         break;\r
122                 default:\r
123                         break;\r
124         }\r
125 \r
126         self.alpha = self.alphamod * a;\r
127         self.renderflags = 0;\r
128 \r
129         R_AddEntity(self);\r
130 }\r
131 \r
132 void loopsound(entity e, float ch, string samp, float vol, float attn)\r
133 {\r
134         if(self.silent)\r
135                 return;\r
136 \r
137         sound(e, ch, samp, vol, attn);\r
138         e.snd_looping = 1;\r
139 }\r
140 \r
141 void Ent_RemoveProjectile()\r
142 {\r
143         if(self.snd_looping)\r
144                 sound(self, CHAN_PROJECTILE, "misc/null.wav", VOL_BASE, ATTN_NORM);\r
145 \r
146         if(self.count & 0x80)\r
147         {\r
148                 tracebox(self.origin, self.mins, self.maxs, self.origin + self.velocity * 0.05, MOVE_NORMAL, self);\r
149                 Projectile_DrawTrail(trace_endpos);\r
150         }\r
151 }\r
152 \r
153 void Ent_Projectile()\r
154 {\r
155         float f;\r
156 \r
157         // projectile properties:\r
158         //   kind (interpolated, or clientside)\r
159         //\r
160         //   modelindex\r
161         //   origin\r
162         //   scale\r
163         //   if clientside:\r
164         //     velocity\r
165         //     gravity\r
166         //   soundindex (hardcoded list)\r
167         //   effects\r
168         //\r
169         // projectiles don't send angles, because they always follow the velocity\r
170         \r
171         f = ReadByte();\r
172         self.count = (f & 0x80);\r
173         self.iflags = (self.iflags & IFLAG_INTERNALMASK) | IFLAG_AUTOANGLES | IFLAG_ANGLES;\r
174         self.solid = SOLID_TRIGGER;\r
175         //self.effects = EF_NOMODELFLAGS;\r
176 \r
177         // this should make collisions with bmodels more exact, but it leads to\r
178         // projectiles no longer being able to lie on a bmodel\r
179         self.move_nomonsters = MOVE_WORLDONLY;\r
180         if(f & 0x40)\r
181                 self.move_flags |= FL_ONGROUND;\r
182         else\r
183                 self.move_flags &~= FL_ONGROUND;\r
184 \r
185         if(!self.move_time)\r
186         {\r
187                 // for some unknown reason, we don't need to care for\r
188                 // sv_gameplayfix_delayprojectiles here.\r
189                 self.move_time = time;\r
190                 self.spawntime = time;\r
191         }\r
192         else\r
193                 self.move_time = max(self.move_time, time);\r
194 \r
195         if(!(self.count & 0x80))\r
196                 InterpolateOrigin_Undo();\r
197 \r
198         if(f & 1)\r
199         {\r
200                 self.origin_x = ReadCoord();\r
201                 self.origin_y = ReadCoord();\r
202                 self.origin_z = ReadCoord();\r
203                 if(self.count & 0x80)\r
204                 {\r
205                         self.velocity_x = ReadCoord();\r
206                         self.velocity_y = ReadCoord();\r
207                         self.velocity_z = ReadCoord();\r
208                         self.gravity = ReadCoord();\r
209 \r
210                         self.move_origin = self.origin;\r
211                         self.move_velocity = self.velocity;\r
212                 }\r
213 \r
214                 if(time == self.spawntime || (self.count & 0x80) || (f & 0x10))\r
215                 {\r
216                         self.trail_oldorigin = self.origin;\r
217                         if(!(self.count & 0x80))\r
218                                 InterpolateOrigin_Reset();\r
219                 }\r
220 \r
221                 if(f & 0x20)\r
222                 {\r
223                         self.fade_time = time + ReadByte() * ticrate;\r
224                         self.fade_rate = 1 / (ReadByte() * ticrate);\r
225                 }\r
226                 else\r
227                 {\r
228                         self.fade_time = 0;\r
229                         self.fade_rate = 0;\r
230                 }\r
231         }\r
232 \r
233         if(f & 2)\r
234         {\r
235                 self.cnt = ReadByte();\r
236 \r
237                 self.silent = (self.cnt & 0x80);\r
238                 self.cnt = (self.cnt & 0x7F);\r
239 \r
240                 self.scale = 1;\r
241                 self.traileffect = 0;\r
242                 switch(self.cnt)\r
243                 {\r
244                         case PROJECTILE_EXAMPLE: setmodel(self, "models/example.mdl");self.traileffect = particleeffectnum("TR_EXAMPLE"); break;\r
245                         default:\r
246                                 error("Received invalid CSQC projectile, can't work with this!");\r
247                                 break;\r
248                 }\r
249 \r
250                 self.mins = '0 0 0';\r
251                 self.maxs = '0 0 0';\r
252                 self.colormod = '0 0 0';\r
253                 self.move_touch = SUB_Stop;\r
254                 self.move_movetype = MOVETYPE_TOSS;\r
255                 self.alphamod = 1;\r
256 \r
257                 switch(self.cnt)\r
258                 {\r
259                         case PROJECTILE_EXAMPLE:\r
260                                 loopsound(self, CHAN_PROJECTILE, "weapons/example.wav", VOL_BASE, ATTN_NORM);\r
261                                 self.mins = '-3 -3 -3';\r
262                                 self.maxs = '3 3 3';\r
263                                 break;\r
264                         default:\r
265                                 break;\r
266                 }\r
267         }\r
268 \r
269         if(self.gravity)\r
270         {\r
271                 if(self.move_movetype == MOVETYPE_FLY)\r
272                         self.move_movetype = MOVETYPE_TOSS;\r
273                 if(self.move_movetype == MOVETYPE_BOUNCEMISSILE)\r
274                         self.move_movetype = MOVETYPE_BOUNCE;\r
275         }\r
276         else\r
277         {\r
278                 if(self.move_movetype == MOVETYPE_TOSS)\r
279                         self.move_movetype = MOVETYPE_FLY;\r
280                 if(self.move_movetype == MOVETYPE_BOUNCE)\r
281                         self.move_movetype = MOVETYPE_BOUNCEMISSILE;\r
282         }\r
283 \r
284         if(!(self.count & 0x80))\r
285                 InterpolateOrigin_Note();\r
286         \r
287         self.draw = Projectile_Draw;\r
288         self.entremove = Ent_RemoveProjectile;\r
289 }\r
290 \r
291 void Projectile_Precache()\r
292 {\r
293         precache_model("models/example.mdl");\r
294         precache_sound("weapons/example.wav");\r
295 }\r