diff options
Diffstat (limited to 'apps/plugins/sdl/progs/quake/cl_tent.c')
-rw-r--r-- | apps/plugins/sdl/progs/quake/cl_tent.c | 394 |
1 files changed, 394 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/quake/cl_tent.c b/apps/plugins/sdl/progs/quake/cl_tent.c new file mode 100644 index 0000000000..546e832f8b --- /dev/null +++ b/apps/plugins/sdl/progs/quake/cl_tent.c | |||
@@ -0,0 +1,394 @@ | |||
1 | /* | ||
2 | Copyright (C) 1996-1997 Id Software, Inc. | ||
3 | |||
4 | This program is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU General Public License | ||
6 | as published by the Free Software Foundation; either version 2 | ||
7 | of the License, or (at your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
12 | |||
13 | See the GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the Free Software | ||
17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
18 | |||
19 | */ | ||
20 | // cl_tent.c -- client side temporary entities | ||
21 | |||
22 | #include "quakedef.h" | ||
23 | |||
24 | int num_temp_entities; | ||
25 | entity_t cl_temp_entities[MAX_TEMP_ENTITIES]; | ||
26 | beam_t cl_beams[MAX_BEAMS]; | ||
27 | |||
28 | sfx_t *cl_sfx_wizhit; | ||
29 | sfx_t *cl_sfx_knighthit; | ||
30 | sfx_t *cl_sfx_tink1; | ||
31 | sfx_t *cl_sfx_ric1; | ||
32 | sfx_t *cl_sfx_ric2; | ||
33 | sfx_t *cl_sfx_ric3; | ||
34 | sfx_t *cl_sfx_r_exp3; | ||
35 | #ifdef QUAKE2 | ||
36 | sfx_t *cl_sfx_imp; | ||
37 | sfx_t *cl_sfx_rail; | ||
38 | #endif | ||
39 | |||
40 | /* | ||
41 | ================= | ||
42 | CL_ParseTEnt | ||
43 | ================= | ||
44 | */ | ||
45 | void CL_InitTEnts (void) | ||
46 | { | ||
47 | cl_sfx_wizhit = S_PrecacheSound ("wizard/hit.wav"); | ||
48 | cl_sfx_knighthit = S_PrecacheSound ("hknight/hit.wav"); | ||
49 | cl_sfx_tink1 = S_PrecacheSound ("weapons/tink1.wav"); | ||
50 | cl_sfx_ric1 = S_PrecacheSound ("weapons/ric1.wav"); | ||
51 | cl_sfx_ric2 = S_PrecacheSound ("weapons/ric2.wav"); | ||
52 | cl_sfx_ric3 = S_PrecacheSound ("weapons/ric3.wav"); | ||
53 | cl_sfx_r_exp3 = S_PrecacheSound ("weapons/r_exp3.wav"); | ||
54 | #ifdef QUAKE2 | ||
55 | cl_sfx_imp = S_PrecacheSound ("shambler/sattck1.wav"); | ||
56 | cl_sfx_rail = S_PrecacheSound ("weapons/lstart.wav"); | ||
57 | #endif | ||
58 | } | ||
59 | |||
60 | /* | ||
61 | ================= | ||
62 | CL_ParseBeam | ||
63 | ================= | ||
64 | */ | ||
65 | void CL_ParseBeam (model_t *m) | ||
66 | { | ||
67 | int ent; | ||
68 | vec3_t start, end; | ||
69 | beam_t *b; | ||
70 | int i; | ||
71 | |||
72 | ent = MSG_ReadShort (); | ||
73 | |||
74 | start[0] = MSG_ReadCoord (); | ||
75 | start[1] = MSG_ReadCoord (); | ||
76 | start[2] = MSG_ReadCoord (); | ||
77 | |||
78 | end[0] = MSG_ReadCoord (); | ||
79 | end[1] = MSG_ReadCoord (); | ||
80 | end[2] = MSG_ReadCoord (); | ||
81 | |||
82 | // override any beam with the same entity | ||
83 | for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) | ||
84 | if (b->entity == ent) | ||
85 | { | ||
86 | b->entity = ent; | ||
87 | b->model = m; | ||
88 | b->endtime = cl.time + 0.2; | ||
89 | VectorCopy (start, b->start); | ||
90 | VectorCopy (end, b->end); | ||
91 | return; | ||
92 | } | ||
93 | |||
94 | // find a free beam | ||
95 | for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) | ||
96 | { | ||
97 | if (!b->model || b->endtime < cl.time) | ||
98 | { | ||
99 | b->entity = ent; | ||
100 | b->model = m; | ||
101 | b->endtime = cl.time + 0.2; | ||
102 | VectorCopy (start, b->start); | ||
103 | VectorCopy (end, b->end); | ||
104 | return; | ||
105 | } | ||
106 | } | ||
107 | Con_Printf ("beam list overflow!\n"); | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | ================= | ||
112 | CL_ParseTEnt | ||
113 | ================= | ||
114 | */ | ||
115 | void CL_ParseTEnt (void) | ||
116 | { | ||
117 | int type; | ||
118 | vec3_t pos; | ||
119 | #ifdef QUAKE2 | ||
120 | vec3_t endpos; | ||
121 | #endif | ||
122 | dlight_t *dl; | ||
123 | int rnd; | ||
124 | int colorStart, colorLength; | ||
125 | |||
126 | type = MSG_ReadByte (); | ||
127 | switch (type) | ||
128 | { | ||
129 | case TE_WIZSPIKE: // spike hitting wall | ||
130 | pos[0] = MSG_ReadCoord (); | ||
131 | pos[1] = MSG_ReadCoord (); | ||
132 | pos[2] = MSG_ReadCoord (); | ||
133 | R_RunParticleEffect (pos, vec3_origin, 20, 30); | ||
134 | S_StartSound (-1, 0, cl_sfx_wizhit, pos, 1, 1); | ||
135 | break; | ||
136 | |||
137 | case TE_KNIGHTSPIKE: // spike hitting wall | ||
138 | pos[0] = MSG_ReadCoord (); | ||
139 | pos[1] = MSG_ReadCoord (); | ||
140 | pos[2] = MSG_ReadCoord (); | ||
141 | R_RunParticleEffect (pos, vec3_origin, 226, 20); | ||
142 | S_StartSound (-1, 0, cl_sfx_knighthit, pos, 1, 1); | ||
143 | break; | ||
144 | |||
145 | case TE_SPIKE: // spike hitting wall | ||
146 | pos[0] = MSG_ReadCoord (); | ||
147 | pos[1] = MSG_ReadCoord (); | ||
148 | pos[2] = MSG_ReadCoord (); | ||
149 | #ifdef GLTEST | ||
150 | Test_Spawn (pos); | ||
151 | #else | ||
152 | R_RunParticleEffect (pos, vec3_origin, 0, 10); | ||
153 | #endif | ||
154 | if ( rand() % 5 ) | ||
155 | S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1); | ||
156 | else | ||
157 | { | ||
158 | rnd = rand() & 3; | ||
159 | if (rnd == 1) | ||
160 | S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1); | ||
161 | else if (rnd == 2) | ||
162 | S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1); | ||
163 | else | ||
164 | S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1); | ||
165 | } | ||
166 | break; | ||
167 | case TE_SUPERSPIKE: // super spike hitting wall | ||
168 | pos[0] = MSG_ReadCoord (); | ||
169 | pos[1] = MSG_ReadCoord (); | ||
170 | pos[2] = MSG_ReadCoord (); | ||
171 | R_RunParticleEffect (pos, vec3_origin, 0, 20); | ||
172 | |||
173 | if ( rand() % 5 ) | ||
174 | S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1); | ||
175 | else | ||
176 | { | ||
177 | rnd = rand() & 3; | ||
178 | if (rnd == 1) | ||
179 | S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1); | ||
180 | else if (rnd == 2) | ||
181 | S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1); | ||
182 | else | ||
183 | S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1); | ||
184 | } | ||
185 | break; | ||
186 | |||
187 | case TE_GUNSHOT: // bullet hitting wall | ||
188 | pos[0] = MSG_ReadCoord (); | ||
189 | pos[1] = MSG_ReadCoord (); | ||
190 | pos[2] = MSG_ReadCoord (); | ||
191 | R_RunParticleEffect (pos, vec3_origin, 0, 20); | ||
192 | break; | ||
193 | |||
194 | case TE_EXPLOSION: // rocket explosion | ||
195 | pos[0] = MSG_ReadCoord (); | ||
196 | pos[1] = MSG_ReadCoord (); | ||
197 | pos[2] = MSG_ReadCoord (); | ||
198 | R_ParticleExplosion (pos); | ||
199 | dl = CL_AllocDlight (0); | ||
200 | VectorCopy (pos, dl->origin); | ||
201 | dl->radius = 350; | ||
202 | dl->die = cl.time + 0.5; | ||
203 | dl->decay = 300; | ||
204 | S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); | ||
205 | break; | ||
206 | |||
207 | case TE_TAREXPLOSION: // tarbaby explosion | ||
208 | pos[0] = MSG_ReadCoord (); | ||
209 | pos[1] = MSG_ReadCoord (); | ||
210 | pos[2] = MSG_ReadCoord (); | ||
211 | R_BlobExplosion (pos); | ||
212 | |||
213 | S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); | ||
214 | break; | ||
215 | |||
216 | case TE_LIGHTNING1: // lightning bolts | ||
217 | CL_ParseBeam (Mod_ForName("progs/bolt.mdl", true)); | ||
218 | break; | ||
219 | |||
220 | case TE_LIGHTNING2: // lightning bolts | ||
221 | CL_ParseBeam (Mod_ForName("progs/bolt2.mdl", true)); | ||
222 | break; | ||
223 | |||
224 | case TE_LIGHTNING3: // lightning bolts | ||
225 | CL_ParseBeam (Mod_ForName("progs/bolt3.mdl", true)); | ||
226 | break; | ||
227 | |||
228 | // PGM 01/21/97 | ||
229 | case TE_BEAM: // grappling hook beam | ||
230 | CL_ParseBeam (Mod_ForName("progs/beam.mdl", true)); | ||
231 | break; | ||
232 | // PGM 01/21/97 | ||
233 | |||
234 | case TE_LAVASPLASH: | ||
235 | pos[0] = MSG_ReadCoord (); | ||
236 | pos[1] = MSG_ReadCoord (); | ||
237 | pos[2] = MSG_ReadCoord (); | ||
238 | R_LavaSplash (pos); | ||
239 | break; | ||
240 | |||
241 | case TE_TELEPORT: | ||
242 | pos[0] = MSG_ReadCoord (); | ||
243 | pos[1] = MSG_ReadCoord (); | ||
244 | pos[2] = MSG_ReadCoord (); | ||
245 | R_TeleportSplash (pos); | ||
246 | break; | ||
247 | |||
248 | case TE_EXPLOSION2: // color mapped explosion | ||
249 | pos[0] = MSG_ReadCoord (); | ||
250 | pos[1] = MSG_ReadCoord (); | ||
251 | pos[2] = MSG_ReadCoord (); | ||
252 | colorStart = MSG_ReadByte (); | ||
253 | colorLength = MSG_ReadByte (); | ||
254 | R_ParticleExplosion2 (pos, colorStart, colorLength); | ||
255 | dl = CL_AllocDlight (0); | ||
256 | VectorCopy (pos, dl->origin); | ||
257 | dl->radius = 350; | ||
258 | dl->die = cl.time + 0.5; | ||
259 | dl->decay = 300; | ||
260 | S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); | ||
261 | break; | ||
262 | |||
263 | #ifdef QUAKE2 | ||
264 | case TE_IMPLOSION: | ||
265 | pos[0] = MSG_ReadCoord (); | ||
266 | pos[1] = MSG_ReadCoord (); | ||
267 | pos[2] = MSG_ReadCoord (); | ||
268 | S_StartSound (-1, 0, cl_sfx_imp, pos, 1, 1); | ||
269 | break; | ||
270 | |||
271 | case TE_RAILTRAIL: | ||
272 | pos[0] = MSG_ReadCoord (); | ||
273 | pos[1] = MSG_ReadCoord (); | ||
274 | pos[2] = MSG_ReadCoord (); | ||
275 | endpos[0] = MSG_ReadCoord (); | ||
276 | endpos[1] = MSG_ReadCoord (); | ||
277 | endpos[2] = MSG_ReadCoord (); | ||
278 | S_StartSound (-1, 0, cl_sfx_rail, pos, 1, 1); | ||
279 | S_StartSound (-1, 1, cl_sfx_r_exp3, endpos, 1, 1); | ||
280 | R_RocketTrail (pos, endpos, 0+128); | ||
281 | R_ParticleExplosion (endpos); | ||
282 | dl = CL_AllocDlight (-1); | ||
283 | VectorCopy (endpos, dl->origin); | ||
284 | dl->radius = 350; | ||
285 | dl->die = cl.time + 0.5; | ||
286 | dl->decay = 300; | ||
287 | break; | ||
288 | #endif | ||
289 | |||
290 | default: | ||
291 | Sys_Error ("CL_ParseTEnt: bad type"); | ||
292 | } | ||
293 | } | ||
294 | |||
295 | |||
296 | /* | ||
297 | ================= | ||
298 | CL_NewTempEntity | ||
299 | ================= | ||
300 | */ | ||
301 | entity_t *CL_NewTempEntity (void) | ||
302 | { | ||
303 | entity_t *ent; | ||
304 | |||
305 | if (cl_numvisedicts == MAX_VISEDICTS) | ||
306 | return NULL; | ||
307 | if (num_temp_entities == MAX_TEMP_ENTITIES) | ||
308 | return NULL; | ||
309 | ent = &cl_temp_entities[num_temp_entities]; | ||
310 | memset (ent, 0, sizeof(*ent)); | ||
311 | num_temp_entities++; | ||
312 | cl_visedicts[cl_numvisedicts] = ent; | ||
313 | cl_numvisedicts++; | ||
314 | |||
315 | ent->colormap = vid.colormap; | ||
316 | return ent; | ||
317 | } | ||
318 | |||
319 | |||
320 | /* | ||
321 | ================= | ||
322 | CL_UpdateTEnts | ||
323 | ================= | ||
324 | */ | ||
325 | void CL_UpdateTEnts (void) | ||
326 | { | ||
327 | int i; | ||
328 | beam_t *b; | ||
329 | vec3_t dist, org; | ||
330 | float d; | ||
331 | entity_t *ent; | ||
332 | float yaw, pitch; | ||
333 | float forward; | ||
334 | |||
335 | num_temp_entities = 0; | ||
336 | |||
337 | // update lightning | ||
338 | for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) | ||
339 | { | ||
340 | if (!b->model || b->endtime < cl.time) | ||
341 | continue; | ||
342 | |||
343 | // if coming from the player, update the start position | ||
344 | if (b->entity == cl.viewentity) | ||
345 | { | ||
346 | VectorCopy (cl_entities[cl.viewentity].origin, b->start); | ||
347 | } | ||
348 | |||
349 | // calculate pitch and yaw | ||
350 | VectorSubtract (b->end, b->start, dist); | ||
351 | |||
352 | if (dist[1] == 0 && dist[0] == 0) | ||
353 | { | ||
354 | yaw = 0; | ||
355 | if (dist[2] > 0) | ||
356 | pitch = 90; | ||
357 | else | ||
358 | pitch = 270; | ||
359 | } | ||
360 | else | ||
361 | { | ||
362 | yaw = (int) (atan2(dist[1], dist[0]) * 180 / M_PI); | ||
363 | if (yaw < 0) | ||
364 | yaw += 360; | ||
365 | |||
366 | forward = sqrt (dist[0]*dist[0] + dist[1]*dist[1]); | ||
367 | pitch = (int) (atan2(dist[2], forward) * 180 / M_PI); | ||
368 | if (pitch < 0) | ||
369 | pitch += 360; | ||
370 | } | ||
371 | |||
372 | // add new entities for the lightning | ||
373 | VectorCopy (b->start, org); | ||
374 | d = VectorNormalize(dist); | ||
375 | while (d > 0) | ||
376 | { | ||
377 | ent = CL_NewTempEntity (); | ||
378 | if (!ent) | ||
379 | return; | ||
380 | VectorCopy (org, ent->origin); | ||
381 | ent->model = b->model; | ||
382 | ent->angles[0] = pitch; | ||
383 | ent->angles[1] = yaw; | ||
384 | ent->angles[2] = rand()%360; | ||
385 | |||
386 | for (i=0 ; i<3 ; i++) | ||
387 | org[i] += dist[i]*30; | ||
388 | d -= 30; | ||
389 | } | ||
390 | } | ||
391 | |||
392 | } | ||
393 | |||
394 | |||