1 /*
2 ===========================================================================
3 Copyright (C) 2000 - 2013, Raven Software, Inc.
4 Copyright (C) 2001 - 2013, Activision, Inc.
5 Copyright (C) 2013 - 2015, OpenJK contributors
6
7 This file is part of the OpenJK source code.
8
9 OpenJK is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License version 2 as
11 published by the Free Software Foundation.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, see <http://www.gnu.org/licenses/>.
20 ===========================================================================
21 */
22
23 // BG_PAnimate.c
24 // game and cgame, NOT ui
25
26 #include "qcommon/q_shared.h"
27 #include "bg_public.h"
28 #include "bg_local.h"
29 #include "anims.h"
30 #include "cgame/animtable.h"
31
32 #ifdef _GAME
33 #include "g_local.h"
34 #elif _CGAME
35 #include "cgame/cg_local.h"
36 #elif UI_BUILD
37 #include "ui/ui_local.h"
38 #endif
39
40 extern saberInfo_t *BG_MySaber( int clientNum, int saberNum );
41 /*
42 ==============================================================================
43 BEGIN: Animation utility functions (sequence checking)
44 ==============================================================================
45 */
46 //Called regardless of pm validity:
47
48 // VVFIXME - Most of these functions are totally stateless and stupid. Don't
49 // need multiple copies of this, but it's much easier (and less likely to
50 // break in the future) if I keep separate namespace versions now.
51
BG_SaberStanceAnim(int anim)52 qboolean BG_SaberStanceAnim( int anim )
53 {
54 switch ( anim )
55 {
56 case BOTH_STAND1://not really a saberstance anim, actually... "saber off" stance
57 case BOTH_STAND2://single-saber, medium style
58 case BOTH_SABERFAST_STANCE://single-saber, fast style
59 case BOTH_SABERSLOW_STANCE://single-saber, strong style
60 case BOTH_SABERSTAFF_STANCE://saber staff style
61 case BOTH_SABERDUAL_STANCE://dual saber style
62 return qtrue;
63 break;
64 }
65 return qfalse;
66 }
67
BG_CrouchAnim(int anim)68 qboolean BG_CrouchAnim( int anim )
69 {
70 switch ( anim )
71 {
72 case BOTH_SIT1: //# Normal chair sit.
73 case BOTH_SIT2: //# Lotus position.
74 case BOTH_SIT3: //# Sitting in tired position: elbows on knees
75 case BOTH_CROUCH1: //# Transition from standing to crouch
76 case BOTH_CROUCH1IDLE: //# Crouching idle
77 case BOTH_CROUCH1WALK: //# Walking while crouched
78 case BOTH_CROUCH1WALKBACK: //# Walking while crouched
79 case BOTH_CROUCH2TOSTAND1: //# going from crouch2 to stand1
80 case BOTH_CROUCH3: //# Desann crouching down to Kyle (cin 9)
81 case BOTH_KNEES1: //# Tavion on her knees
82 case BOTH_CROUCHATTACKBACK1://FIXME: not if in middle of anim?
83 case BOTH_ROLL_STAB:
84 return qtrue;
85 break;
86 }
87 return qfalse;
88 }
89
BG_InSpecialJump(int anim)90 qboolean BG_InSpecialJump( int anim )
91 {
92 switch ( (anim) )
93 {
94 case BOTH_WALL_RUN_RIGHT:
95 case BOTH_WALL_RUN_RIGHT_STOP:
96 case BOTH_WALL_RUN_RIGHT_FLIP:
97 case BOTH_WALL_RUN_LEFT:
98 case BOTH_WALL_RUN_LEFT_STOP:
99 case BOTH_WALL_RUN_LEFT_FLIP:
100 case BOTH_WALL_FLIP_RIGHT:
101 case BOTH_WALL_FLIP_LEFT:
102 case BOTH_FLIP_BACK1:
103 case BOTH_FLIP_BACK2:
104 case BOTH_FLIP_BACK3:
105 case BOTH_WALL_FLIP_BACK1:
106 case BOTH_BUTTERFLY_LEFT:
107 case BOTH_BUTTERFLY_RIGHT:
108 case BOTH_BUTTERFLY_FL1:
109 case BOTH_BUTTERFLY_FR1:
110 case BOTH_FJSS_TR_BL:
111 case BOTH_FJSS_TL_BR:
112 case BOTH_FORCELEAP2_T__B_:
113 case BOTH_JUMPFLIPSLASHDOWN1://#
114 case BOTH_JUMPFLIPSTABDOWN://#
115 case BOTH_JUMPATTACK6:
116 case BOTH_JUMPATTACK7:
117 case BOTH_ARIAL_LEFT:
118 case BOTH_ARIAL_RIGHT:
119 case BOTH_ARIAL_F1:
120 case BOTH_CARTWHEEL_LEFT:
121 case BOTH_CARTWHEEL_RIGHT:
122
123 case BOTH_FORCELONGLEAP_START:
124 case BOTH_FORCELONGLEAP_ATTACK:
125 case BOTH_FORCEWALLRUNFLIP_START:
126 case BOTH_FORCEWALLRUNFLIP_END:
127 case BOTH_FORCEWALLRUNFLIP_ALT:
128 case BOTH_FLIP_ATTACK7:
129 case BOTH_FLIP_HOLD7:
130 case BOTH_FLIP_LAND:
131 case BOTH_A7_SOULCAL:
132 return qtrue;
133 }
134 if ( BG_InReboundJump( anim ) )
135 {
136 return qtrue;
137 }
138 if ( BG_InReboundHold( anim ) )
139 {
140 return qtrue;
141 }
142 if ( BG_InReboundRelease( anim ) )
143 {
144 return qtrue;
145 }
146 if ( BG_InBackFlip( anim ) )
147 {
148 return qtrue;
149 }
150 return qfalse;
151 }
152
BG_InSaberStandAnim(int anim)153 qboolean BG_InSaberStandAnim( int anim )
154 {
155 switch ( (anim) )
156 {
157 case BOTH_SABERFAST_STANCE:
158 case BOTH_STAND2:
159 case BOTH_SABERSLOW_STANCE:
160 case BOTH_SABERDUAL_STANCE:
161 case BOTH_SABERSTAFF_STANCE:
162 return qtrue;
163 default:
164 return qfalse;
165 }
166 }
167
BG_InReboundJump(int anim)168 qboolean BG_InReboundJump( int anim )
169 {
170 switch ( anim )
171 {
172 case BOTH_FORCEWALLREBOUND_FORWARD:
173 case BOTH_FORCEWALLREBOUND_LEFT:
174 case BOTH_FORCEWALLREBOUND_BACK:
175 case BOTH_FORCEWALLREBOUND_RIGHT:
176 return qtrue;
177 break;
178 }
179 return qfalse;
180 }
181
BG_InReboundHold(int anim)182 qboolean BG_InReboundHold( int anim )
183 {
184 switch ( anim )
185 {
186 case BOTH_FORCEWALLHOLD_FORWARD:
187 case BOTH_FORCEWALLHOLD_LEFT:
188 case BOTH_FORCEWALLHOLD_BACK:
189 case BOTH_FORCEWALLHOLD_RIGHT:
190 return qtrue;
191 break;
192 }
193 return qfalse;
194 }
195
BG_InReboundRelease(int anim)196 qboolean BG_InReboundRelease( int anim )
197 {
198 switch ( anim )
199 {
200 case BOTH_FORCEWALLRELEASE_FORWARD:
201 case BOTH_FORCEWALLRELEASE_LEFT:
202 case BOTH_FORCEWALLRELEASE_BACK:
203 case BOTH_FORCEWALLRELEASE_RIGHT:
204 return qtrue;
205 break;
206 }
207 return qfalse;
208 }
209
BG_InBackFlip(int anim)210 qboolean BG_InBackFlip( int anim )
211 {
212 switch ( anim )
213 {
214 case BOTH_FLIP_BACK1:
215 case BOTH_FLIP_BACK2:
216 case BOTH_FLIP_BACK3:
217 return qtrue;
218 break;
219 }
220 return qfalse;
221 }
222
BG_DirectFlippingAnim(int anim)223 qboolean BG_DirectFlippingAnim( int anim )
224 {
225 switch ( (anim) )
226 {
227 case BOTH_FLIP_F: //# Flip forward
228 case BOTH_FLIP_B: //# Flip backwards
229 case BOTH_FLIP_L: //# Flip left
230 case BOTH_FLIP_R: //# Flip right
231 return qtrue;
232 break;
233 }
234
235 return qfalse;
236 }
237
BG_SaberInAttackPure(int move)238 qboolean BG_SaberInAttackPure( int move )
239 {
240 if ( move >= LS_A_TL2BR && move <= LS_A_T2B )
241 {
242 return qtrue;
243 }
244 return qfalse;
245 }
BG_SaberInAttack(int move)246 qboolean BG_SaberInAttack( int move )
247 {
248 if ( move >= LS_A_TL2BR && move <= LS_A_T2B )
249 {
250 return qtrue;
251 }
252 switch ( move )
253 {
254 case LS_A_BACK:
255 case LS_A_BACK_CR:
256 case LS_A_BACKSTAB:
257 case LS_ROLL_STAB:
258 case LS_A_LUNGE:
259 case LS_A_JUMP_T__B_:
260 case LS_A_FLIP_STAB:
261 case LS_A_FLIP_SLASH:
262 case LS_JUMPATTACK_DUAL:
263 case LS_JUMPATTACK_ARIAL_LEFT:
264 case LS_JUMPATTACK_ARIAL_RIGHT:
265 case LS_JUMPATTACK_CART_LEFT:
266 case LS_JUMPATTACK_CART_RIGHT:
267 case LS_JUMPATTACK_STAFF_LEFT:
268 case LS_JUMPATTACK_STAFF_RIGHT:
269 case LS_BUTTERFLY_LEFT:
270 case LS_BUTTERFLY_RIGHT:
271 case LS_A_BACKFLIP_ATK:
272 case LS_SPINATTACK_DUAL:
273 case LS_SPINATTACK:
274 case LS_LEAP_ATTACK:
275 case LS_SWOOP_ATTACK_RIGHT:
276 case LS_SWOOP_ATTACK_LEFT:
277 case LS_TAUNTAUN_ATTACK_RIGHT:
278 case LS_TAUNTAUN_ATTACK_LEFT:
279 case LS_KICK_F:
280 case LS_KICK_B:
281 case LS_KICK_R:
282 case LS_KICK_L:
283 case LS_KICK_S:
284 case LS_KICK_BF:
285 case LS_KICK_RL:
286 case LS_KICK_F_AIR:
287 case LS_KICK_B_AIR:
288 case LS_KICK_R_AIR:
289 case LS_KICK_L_AIR:
290 case LS_STABDOWN:
291 case LS_STABDOWN_STAFF:
292 case LS_STABDOWN_DUAL:
293 case LS_DUAL_SPIN_PROTECT:
294 case LS_STAFF_SOULCAL:
295 case LS_A1_SPECIAL:
296 case LS_A2_SPECIAL:
297 case LS_A3_SPECIAL:
298 case LS_UPSIDE_DOWN_ATTACK:
299 case LS_PULL_ATTACK_STAB:
300 case LS_PULL_ATTACK_SWING:
301 case LS_SPINATTACK_ALORA:
302 case LS_DUAL_FB:
303 case LS_DUAL_LR:
304 case LS_HILT_BASH:
305 return qtrue;
306 break;
307 }
308 return qfalse;
309 }
310
BG_SaberInKata(int saberMove)311 qboolean BG_SaberInKata( int saberMove )
312 {
313 switch ( saberMove )
314 {
315 case LS_A1_SPECIAL:
316 case LS_A2_SPECIAL:
317 case LS_A3_SPECIAL:
318 case LS_DUAL_SPIN_PROTECT:
319 case LS_STAFF_SOULCAL:
320 return qtrue;
321 }
322 return qfalse;
323 }
324
BG_InKataAnim(int anim)325 qboolean BG_InKataAnim(int anim)
326 {
327 switch (anim)
328 {
329 case BOTH_A6_SABERPROTECT:
330 case BOTH_A7_SOULCAL:
331 case BOTH_A1_SPECIAL:
332 case BOTH_A2_SPECIAL:
333 case BOTH_A3_SPECIAL:
334 return qtrue;
335 }
336 return qfalse;
337 }
338
BG_SaberInSpecial(int move)339 qboolean BG_SaberInSpecial( int move )
340 {
341 switch( move )
342 {
343 case LS_A_BACK:
344 case LS_A_BACK_CR:
345 case LS_A_BACKSTAB:
346 case LS_ROLL_STAB:
347 case LS_A_LUNGE:
348 case LS_A_JUMP_T__B_:
349 case LS_A_FLIP_STAB:
350 case LS_A_FLIP_SLASH:
351 case LS_JUMPATTACK_DUAL:
352 case LS_JUMPATTACK_ARIAL_LEFT:
353 case LS_JUMPATTACK_ARIAL_RIGHT:
354 case LS_JUMPATTACK_CART_LEFT:
355 case LS_JUMPATTACK_CART_RIGHT:
356 case LS_JUMPATTACK_STAFF_LEFT:
357 case LS_JUMPATTACK_STAFF_RIGHT:
358 case LS_BUTTERFLY_LEFT:
359 case LS_BUTTERFLY_RIGHT:
360 case LS_A_BACKFLIP_ATK:
361 case LS_SPINATTACK_DUAL:
362 case LS_SPINATTACK:
363 case LS_LEAP_ATTACK:
364 case LS_SWOOP_ATTACK_RIGHT:
365 case LS_SWOOP_ATTACK_LEFT:
366 case LS_TAUNTAUN_ATTACK_RIGHT:
367 case LS_TAUNTAUN_ATTACK_LEFT:
368 case LS_KICK_F:
369 case LS_KICK_B:
370 case LS_KICK_R:
371 case LS_KICK_L:
372 case LS_KICK_S:
373 case LS_KICK_BF:
374 case LS_KICK_RL:
375 case LS_KICK_F_AIR:
376 case LS_KICK_B_AIR:
377 case LS_KICK_R_AIR:
378 case LS_KICK_L_AIR:
379 case LS_STABDOWN:
380 case LS_STABDOWN_STAFF:
381 case LS_STABDOWN_DUAL:
382 case LS_DUAL_SPIN_PROTECT:
383 case LS_STAFF_SOULCAL:
384 case LS_A1_SPECIAL:
385 case LS_A2_SPECIAL:
386 case LS_A3_SPECIAL:
387 case LS_UPSIDE_DOWN_ATTACK:
388 case LS_PULL_ATTACK_STAB:
389 case LS_PULL_ATTACK_SWING:
390 case LS_SPINATTACK_ALORA:
391 case LS_DUAL_FB:
392 case LS_DUAL_LR:
393 case LS_HILT_BASH:
394 return qtrue;
395 }
396 return qfalse;
397 }
398
BG_KickMove(int move)399 qboolean BG_KickMove( int move )
400 {
401 switch( move )
402 {
403 case LS_KICK_F:
404 case LS_KICK_B:
405 case LS_KICK_R:
406 case LS_KICK_L:
407 case LS_KICK_S:
408 case LS_KICK_BF:
409 case LS_KICK_RL:
410 case LS_KICK_F_AIR:
411 case LS_KICK_B_AIR:
412 case LS_KICK_R_AIR:
413 case LS_KICK_L_AIR:
414 case LS_HILT_BASH:
415 return qtrue;
416 }
417 return qfalse;
418 }
419
BG_SaberInIdle(int move)420 qboolean BG_SaberInIdle( int move )
421 {
422 switch ( move )
423 {
424 case LS_NONE:
425 case LS_READY:
426 case LS_DRAW:
427 case LS_PUTAWAY:
428 return qtrue;
429 break;
430 }
431 return qfalse;
432 }
433
BG_InExtraDefenseSaberMove(int move)434 qboolean BG_InExtraDefenseSaberMove( int move )
435 {
436 switch ( move )
437 {
438 case LS_SPINATTACK_DUAL:
439 case LS_SPINATTACK:
440 case LS_DUAL_SPIN_PROTECT:
441 case LS_STAFF_SOULCAL:
442 case LS_A1_SPECIAL:
443 case LS_A2_SPECIAL:
444 case LS_A3_SPECIAL:
445 case LS_JUMPATTACK_DUAL:
446 return qtrue;
447 break;
448 }
449 return qfalse;
450 }
451
BG_FlippingAnim(int anim)452 qboolean BG_FlippingAnim( int anim )
453 {
454 switch ( anim )
455 {
456 case BOTH_FLIP_F: //# Flip forward
457 case BOTH_FLIP_B: //# Flip backwards
458 case BOTH_FLIP_L: //# Flip left
459 case BOTH_FLIP_R: //# Flip right
460 case BOTH_WALL_RUN_RIGHT_FLIP:
461 case BOTH_WALL_RUN_LEFT_FLIP:
462 case BOTH_WALL_FLIP_RIGHT:
463 case BOTH_WALL_FLIP_LEFT:
464 case BOTH_FLIP_BACK1:
465 case BOTH_FLIP_BACK2:
466 case BOTH_FLIP_BACK3:
467 case BOTH_WALL_FLIP_BACK1:
468 //Not really flips, but...
469 case BOTH_WALL_RUN_RIGHT:
470 case BOTH_WALL_RUN_LEFT:
471 case BOTH_WALL_RUN_RIGHT_STOP:
472 case BOTH_WALL_RUN_LEFT_STOP:
473 case BOTH_BUTTERFLY_LEFT:
474 case BOTH_BUTTERFLY_RIGHT:
475 case BOTH_BUTTERFLY_FL1:
476 case BOTH_BUTTERFLY_FR1:
477 //
478 case BOTH_ARIAL_LEFT:
479 case BOTH_ARIAL_RIGHT:
480 case BOTH_ARIAL_F1:
481 case BOTH_CARTWHEEL_LEFT:
482 case BOTH_CARTWHEEL_RIGHT:
483 case BOTH_JUMPFLIPSLASHDOWN1:
484 case BOTH_JUMPFLIPSTABDOWN:
485 case BOTH_JUMPATTACK6:
486 case BOTH_JUMPATTACK7:
487 //JKA
488 case BOTH_FORCEWALLRUNFLIP_END:
489 case BOTH_FORCEWALLRUNFLIP_ALT:
490 case BOTH_FLIP_ATTACK7:
491 case BOTH_A7_SOULCAL:
492 return qtrue;
493 break;
494 }
495 return qfalse;
496 }
497
BG_SpinningSaberAnim(int anim)498 qboolean BG_SpinningSaberAnim( int anim )
499 {
500 switch ( anim )
501 {
502 //level 1 - FIXME: level 1 will have *no* spins
503 case BOTH_T1_BR_BL:
504 case BOTH_T1__R__L:
505 case BOTH_T1__R_BL:
506 case BOTH_T1_TR_BL:
507 case BOTH_T1_BR_TL:
508 case BOTH_T1_BR__L:
509 case BOTH_T1_TL_BR:
510 case BOTH_T1__L_BR:
511 case BOTH_T1__L__R:
512 case BOTH_T1_BL_BR:
513 case BOTH_T1_BL__R:
514 case BOTH_T1_BL_TR:
515 //level 2
516 case BOTH_T2_BR__L:
517 case BOTH_T2_BR_BL:
518 case BOTH_T2__R_BL:
519 case BOTH_T2__L_BR:
520 case BOTH_T2_BL_BR:
521 case BOTH_T2_BL__R:
522 //level 3
523 case BOTH_T3_BR__L:
524 case BOTH_T3_BR_BL:
525 case BOTH_T3__R_BL:
526 case BOTH_T3__L_BR:
527 case BOTH_T3_BL_BR:
528 case BOTH_T3_BL__R:
529 //level 4
530 case BOTH_T4_BR__L:
531 case BOTH_T4_BR_BL:
532 case BOTH_T4__R_BL:
533 case BOTH_T4__L_BR:
534 case BOTH_T4_BL_BR:
535 case BOTH_T4_BL__R:
536 //level 5
537 case BOTH_T5_BR_BL:
538 case BOTH_T5__R__L:
539 case BOTH_T5__R_BL:
540 case BOTH_T5_TR_BL:
541 case BOTH_T5_BR_TL:
542 case BOTH_T5_BR__L:
543 case BOTH_T5_TL_BR:
544 case BOTH_T5__L_BR:
545 case BOTH_T5__L__R:
546 case BOTH_T5_BL_BR:
547 case BOTH_T5_BL__R:
548 case BOTH_T5_BL_TR:
549 //level 6
550 case BOTH_T6_BR_TL:
551 case BOTH_T6__R_TL:
552 case BOTH_T6__R__L:
553 case BOTH_T6__R_BL:
554 case BOTH_T6_TR_TL:
555 case BOTH_T6_TR__L:
556 case BOTH_T6_TR_BL:
557 case BOTH_T6_T__TL:
558 case BOTH_T6_T__BL:
559 case BOTH_T6_TL_BR:
560 case BOTH_T6__L_BR:
561 case BOTH_T6__L__R:
562 case BOTH_T6_TL__R:
563 case BOTH_T6_TL_TR:
564 case BOTH_T6__L_TR:
565 case BOTH_T6__L_T_:
566 case BOTH_T6_BL_T_:
567 case BOTH_T6_BR__L:
568 case BOTH_T6_BR_BL:
569 case BOTH_T6_BL_BR:
570 case BOTH_T6_BL__R:
571 case BOTH_T6_BL_TR:
572 //level 7
573 case BOTH_T7_BR_TL:
574 case BOTH_T7_BR__L:
575 case BOTH_T7_BR_BL:
576 case BOTH_T7__R__L:
577 case BOTH_T7__R_BL:
578 case BOTH_T7_TR__L:
579 case BOTH_T7_T___R:
580 case BOTH_T7_TL_BR:
581 case BOTH_T7__L_BR:
582 case BOTH_T7__L__R:
583 case BOTH_T7_BL_BR:
584 case BOTH_T7_BL__R:
585 case BOTH_T7_BL_TR:
586 case BOTH_T7_TL_TR:
587 case BOTH_T7_T__BR:
588 case BOTH_T7__L_TR:
589 case BOTH_V7_BL_S7:
590 //special
591 //case BOTH_A2_STABBACK1:
592 case BOTH_ATTACK_BACK:
593 case BOTH_CROUCHATTACKBACK1:
594 case BOTH_BUTTERFLY_LEFT:
595 case BOTH_BUTTERFLY_RIGHT:
596 case BOTH_FJSS_TR_BL:
597 case BOTH_FJSS_TL_BR:
598 case BOTH_JUMPFLIPSLASHDOWN1:
599 case BOTH_JUMPFLIPSTABDOWN:
600 return qtrue;
601 break;
602 }
603 return qfalse;
604 }
605
BG_SaberInSpecialAttack(int anim)606 qboolean BG_SaberInSpecialAttack( int anim )
607 {
608 switch ( anim )
609 {
610 case BOTH_A2_STABBACK1:
611 case BOTH_ATTACK_BACK:
612 case BOTH_CROUCHATTACKBACK1:
613 case BOTH_ROLL_STAB:
614 case BOTH_BUTTERFLY_LEFT:
615 case BOTH_BUTTERFLY_RIGHT:
616 case BOTH_BUTTERFLY_FL1:
617 case BOTH_BUTTERFLY_FR1:
618 case BOTH_FJSS_TR_BL:
619 case BOTH_FJSS_TL_BR:
620 case BOTH_LUNGE2_B__T_:
621 case BOTH_FORCELEAP2_T__B_:
622 case BOTH_JUMPFLIPSLASHDOWN1://#
623 case BOTH_JUMPFLIPSTABDOWN://#
624 case BOTH_JUMPATTACK6:
625 case BOTH_JUMPATTACK7:
626 case BOTH_SPINATTACK6:
627 case BOTH_SPINATTACK7:
628 case BOTH_FORCELONGLEAP_ATTACK:
629 case BOTH_VS_ATR_S:
630 case BOTH_VS_ATL_S:
631 case BOTH_VT_ATR_S:
632 case BOTH_VT_ATL_S:
633 case BOTH_A7_KICK_F:
634 case BOTH_A7_KICK_B:
635 case BOTH_A7_KICK_R:
636 case BOTH_A7_KICK_L:
637 case BOTH_A7_KICK_S:
638 case BOTH_A7_KICK_BF:
639 case BOTH_A7_KICK_RL:
640 case BOTH_A7_KICK_F_AIR:
641 case BOTH_A7_KICK_B_AIR:
642 case BOTH_A7_KICK_R_AIR:
643 case BOTH_A7_KICK_L_AIR:
644 case BOTH_STABDOWN:
645 case BOTH_STABDOWN_STAFF:
646 case BOTH_STABDOWN_DUAL:
647 case BOTH_A6_SABERPROTECT:
648 case BOTH_A7_SOULCAL:
649 case BOTH_A1_SPECIAL:
650 case BOTH_A2_SPECIAL:
651 case BOTH_A3_SPECIAL:
652 case BOTH_FLIP_ATTACK7:
653 case BOTH_PULL_IMPALE_STAB:
654 case BOTH_PULL_IMPALE_SWING:
655 case BOTH_ALORA_SPIN_SLASH:
656 case BOTH_A6_FB:
657 case BOTH_A6_LR:
658 case BOTH_A7_HILT:
659 return qtrue;
660 }
661 return qfalse;
662 }
663
BG_KickingAnim(int anim)664 qboolean BG_KickingAnim( int anim )
665 {
666 switch ( anim )
667 {
668 case BOTH_A7_KICK_F:
669 case BOTH_A7_KICK_B:
670 case BOTH_A7_KICK_R:
671 case BOTH_A7_KICK_L:
672 case BOTH_A7_KICK_S:
673 case BOTH_A7_KICK_BF:
674 case BOTH_A7_KICK_RL:
675 case BOTH_A7_KICK_F_AIR:
676 case BOTH_A7_KICK_B_AIR:
677 case BOTH_A7_KICK_R_AIR:
678 case BOTH_A7_KICK_L_AIR:
679 case BOTH_A7_HILT:
680 //NOT kicks, but do kick traces anyway
681 case BOTH_GETUP_BROLL_B:
682 case BOTH_GETUP_BROLL_F:
683 case BOTH_GETUP_FROLL_B:
684 case BOTH_GETUP_FROLL_F:
685 return qtrue;
686 break;
687 }
688 return qfalse;
689 }
690
BG_InGrappleMove(int anim)691 int BG_InGrappleMove(int anim)
692 {
693 switch (anim)
694 {
695 case BOTH_KYLE_GRAB:
696 case BOTH_KYLE_MISS:
697 return 1; //grabbing at someone
698 case BOTH_KYLE_PA_1:
699 case BOTH_KYLE_PA_2:
700 return 2; //beating the shit out of someone
701 case BOTH_PLAYER_PA_1:
702 case BOTH_PLAYER_PA_2:
703 case BOTH_PLAYER_PA_FLY:
704 return 3; //getting the shit beaten out of you
705 break;
706 }
707
708 return 0;
709 }
710
BG_BrokenParryForAttack(int move)711 int BG_BrokenParryForAttack( int move )
712 {
713 //Our attack was knocked away by a knockaway parry
714 //FIXME: need actual anims for this
715 //FIXME: need to know which side of the saber was hit! For now, we presume the saber gets knocked away from the center
716 switch ( saberMoveData[move].startQuad )
717 {
718 case Q_B:
719 return LS_V1_B_;
720 break;
721 case Q_BR:
722 return LS_V1_BR;
723 break;
724 case Q_R:
725 return LS_V1__R;
726 break;
727 case Q_TR:
728 return LS_V1_TR;
729 break;
730 case Q_T:
731 return LS_V1_T_;
732 break;
733 case Q_TL:
734 return LS_V1_TL;
735 break;
736 case Q_L:
737 return LS_V1__L;
738 break;
739 case Q_BL:
740 return LS_V1_BL;
741 break;
742 }
743 return LS_NONE;
744 }
745
BG_BrokenParryForParry(int move)746 int BG_BrokenParryForParry( int move )
747 {
748 //FIXME: need actual anims for this
749 //FIXME: need to know which side of the saber was hit! For now, we presume the saber gets knocked away from the center
750 switch ( move )
751 {
752 case LS_PARRY_UP:
753 //Hmm... since we don't know what dir the hit came from, randomly pick knock down or knock back
754 if ( Q_irand( 0, 1 ) )
755 {
756 return LS_H1_B_;
757 }
758 else
759 {
760 return LS_H1_T_;
761 }
762 break;
763 case LS_PARRY_UR:
764 return LS_H1_TR;
765 break;
766 case LS_PARRY_UL:
767 return LS_H1_TL;
768 break;
769 case LS_PARRY_LR:
770 return LS_H1_BR;
771 break;
772 case LS_PARRY_LL:
773 return LS_H1_BL;
774 break;
775 case LS_READY:
776 return LS_H1_B_;//???
777 break;
778 }
779 return LS_NONE;
780 }
781
BG_KnockawayForParry(int move)782 int BG_KnockawayForParry( int move )
783 {
784 //FIXME: need actual anims for this
785 //FIXME: need to know which side of the saber was hit! For now, we presume the saber gets knocked away from the center
786 switch ( move )
787 {
788 case BLOCKED_TOP://LS_PARRY_UP:
789 return LS_K1_T_;//push up
790 break;
791 case BLOCKED_UPPER_RIGHT://LS_PARRY_UR:
792 default://case LS_READY:
793 return LS_K1_TR;//push up, slightly to right
794 break;
795 case BLOCKED_UPPER_LEFT://LS_PARRY_UL:
796 return LS_K1_TL;//push up and to left
797 break;
798 case BLOCKED_LOWER_RIGHT://LS_PARRY_LR:
799 return LS_K1_BR;//push down and to left
800 break;
801 case BLOCKED_LOWER_LEFT://LS_PARRY_LL:
802 return LS_K1_BL;//push down and to right
803 break;
804 }
805 //return LS_NONE;
806 }
807
BG_InRoll(playerState_t * ps,int anim)808 qboolean BG_InRoll( playerState_t *ps, int anim )
809 {
810 switch ( (anim) )
811 {
812 case BOTH_GETUP_BROLL_B:
813 case BOTH_GETUP_BROLL_F:
814 case BOTH_GETUP_BROLL_L:
815 case BOTH_GETUP_BROLL_R:
816 case BOTH_GETUP_FROLL_B:
817 case BOTH_GETUP_FROLL_F:
818 case BOTH_GETUP_FROLL_L:
819 case BOTH_GETUP_FROLL_R:
820 case BOTH_ROLL_F:
821 case BOTH_ROLL_B:
822 case BOTH_ROLL_R:
823 case BOTH_ROLL_L:
824 if ( ps->legsTimer > 0 )
825 {
826 return qtrue;
827 }
828 break;
829 }
830 return qfalse;
831 }
832
BG_InSpecialDeathAnim(int anim)833 qboolean BG_InSpecialDeathAnim( int anim )
834 {
835 switch( anim )
836 {
837 case BOTH_DEATH_ROLL: //# Death anim from a roll
838 case BOTH_DEATH_FLIP: //# Death anim from a flip
839 case BOTH_DEATH_SPIN_90_R: //# Death anim when facing 90 degrees right
840 case BOTH_DEATH_SPIN_90_L: //# Death anim when facing 90 degrees left
841 case BOTH_DEATH_SPIN_180: //# Death anim when facing backwards
842 case BOTH_DEATH_LYING_UP: //# Death anim when lying on back
843 case BOTH_DEATH_LYING_DN: //# Death anim when lying on front
844 case BOTH_DEATH_FALLING_DN: //# Death anim when falling on face
845 case BOTH_DEATH_FALLING_UP: //# Death anim when falling on back
846 case BOTH_DEATH_CROUCHED: //# Death anim when crouched
847 return qtrue;
848 break;
849 default:
850 return qfalse;
851 break;
852 }
853 }
854
BG_InDeathAnim(int anim)855 qboolean BG_InDeathAnim ( int anim )
856 {//Purposely does not cover stumbledeath and falldeath...
857 switch( anim )
858 {
859 case BOTH_DEATH1: //# First Death anim
860 case BOTH_DEATH2: //# Second Death anim
861 case BOTH_DEATH3: //# Third Death anim
862 case BOTH_DEATH4: //# Fourth Death anim
863 case BOTH_DEATH5: //# Fifth Death anim
864 case BOTH_DEATH6: //# Sixth Death anim
865 case BOTH_DEATH7: //# Seventh Death anim
866 case BOTH_DEATH8: //#
867 case BOTH_DEATH9: //#
868 case BOTH_DEATH10: //#
869 case BOTH_DEATH11: //#
870 case BOTH_DEATH12: //#
871 case BOTH_DEATH13: //#
872 case BOTH_DEATH14: //#
873 case BOTH_DEATH14_UNGRIP: //# Desann's end death (cin #35)
874 case BOTH_DEATH14_SITUP: //# Tavion sitting up after having been thrown (cin #23)
875 case BOTH_DEATH15: //#
876 case BOTH_DEATH16: //#
877 case BOTH_DEATH17: //#
878 case BOTH_DEATH18: //#
879 case BOTH_DEATH19: //#
880 case BOTH_DEATH20: //#
881 case BOTH_DEATH21: //#
882 case BOTH_DEATH22: //#
883 case BOTH_DEATH23: //#
884 case BOTH_DEATH24: //#
885 case BOTH_DEATH25: //#
886
887 case BOTH_DEATHFORWARD1: //# First Death in which they get thrown forward
888 case BOTH_DEATHFORWARD2: //# Second Death in which they get thrown forward
889 case BOTH_DEATHFORWARD3: //# Tavion's falling in cin# 23
890 case BOTH_DEATHBACKWARD1: //# First Death in which they get thrown backward
891 case BOTH_DEATHBACKWARD2: //# Second Death in which they get thrown backward
892
893 case BOTH_DEATH1IDLE: //# Idle while close to death
894 case BOTH_LYINGDEATH1: //# Death to play when killed lying down
895 case BOTH_STUMBLEDEATH1: //# Stumble forward and fall face first death
896 case BOTH_FALLDEATH1: //# Fall forward off a high cliff and splat death - start
897 case BOTH_FALLDEATH1INAIR: //# Fall forward off a high cliff and splat death - loop
898 case BOTH_FALLDEATH1LAND: //# Fall forward off a high cliff and splat death - hit bottom
899 //# #sep case BOTH_ DEAD POSES # Should be last frame of corresponding previous anims
900 case BOTH_DEAD1: //# First Death finished pose
901 case BOTH_DEAD2: //# Second Death finished pose
902 case BOTH_DEAD3: //# Third Death finished pose
903 case BOTH_DEAD4: //# Fourth Death finished pose
904 case BOTH_DEAD5: //# Fifth Death finished pose
905 case BOTH_DEAD6: //# Sixth Death finished pose
906 case BOTH_DEAD7: //# Seventh Death finished pose
907 case BOTH_DEAD8: //#
908 case BOTH_DEAD9: //#
909 case BOTH_DEAD10: //#
910 case BOTH_DEAD11: //#
911 case BOTH_DEAD12: //#
912 case BOTH_DEAD13: //#
913 case BOTH_DEAD14: //#
914 case BOTH_DEAD15: //#
915 case BOTH_DEAD16: //#
916 case BOTH_DEAD17: //#
917 case BOTH_DEAD18: //#
918 case BOTH_DEAD19: //#
919 case BOTH_DEAD20: //#
920 case BOTH_DEAD21: //#
921 case BOTH_DEAD22: //#
922 case BOTH_DEAD23: //#
923 case BOTH_DEAD24: //#
924 case BOTH_DEAD25: //#
925 case BOTH_DEADFORWARD1: //# First thrown forward death finished pose
926 case BOTH_DEADFORWARD2: //# Second thrown forward death finished pose
927 case BOTH_DEADBACKWARD1: //# First thrown backward death finished pose
928 case BOTH_DEADBACKWARD2: //# Second thrown backward death finished pose
929 case BOTH_LYINGDEAD1: //# Killed lying down death finished pose
930 case BOTH_STUMBLEDEAD1: //# Stumble forward death finished pose
931 case BOTH_FALLDEAD1LAND: //# Fall forward and splat death finished pose
932 //# #sep case BOTH_ DEAD TWITCH/FLOP # React to being shot from death poses
933 case BOTH_DEADFLOP1: //# React to being shot from First Death finished pose
934 case BOTH_DEADFLOP2: //# React to being shot from Second Death finished pose
935 case BOTH_DISMEMBER_HEAD1: //#
936 case BOTH_DISMEMBER_TORSO1: //#
937 case BOTH_DISMEMBER_LLEG: //#
938 case BOTH_DISMEMBER_RLEG: //#
939 case BOTH_DISMEMBER_RARM: //#
940 case BOTH_DISMEMBER_LARM: //#
941 return qtrue;
942 break;
943 default:
944 return BG_InSpecialDeathAnim( anim );
945 break;
946 }
947 }
948
BG_InKnockDownOnly(int anim)949 qboolean BG_InKnockDownOnly( int anim )
950 {
951 switch ( anim )
952 {
953 case BOTH_KNOCKDOWN1:
954 case BOTH_KNOCKDOWN2:
955 case BOTH_KNOCKDOWN3:
956 case BOTH_KNOCKDOWN4:
957 case BOTH_KNOCKDOWN5:
958 return qtrue;
959 }
960 return qfalse;
961 }
962
BG_InSaberLockOld(int anim)963 qboolean BG_InSaberLockOld( int anim )
964 {
965 switch ( anim )
966 {
967 case BOTH_BF2LOCK:
968 case BOTH_BF1LOCK:
969 case BOTH_CWCIRCLELOCK:
970 case BOTH_CCWCIRCLELOCK:
971 return qtrue;
972 }
973 return qfalse;
974 }
975
BG_InSaberLock(int anim)976 qboolean BG_InSaberLock( int anim )
977 {
978 switch ( anim )
979 {
980 case BOTH_LK_S_DL_S_L_1: //lock if I'm using single vs. a dual
981 case BOTH_LK_S_DL_T_L_1: //lock if I'm using single vs. a dual
982 case BOTH_LK_S_ST_S_L_1: //lock if I'm using single vs. a staff
983 case BOTH_LK_S_ST_T_L_1: //lock if I'm using single vs. a staff
984 case BOTH_LK_S_S_S_L_1: //lock if I'm using single vs. a single and I initiated
985 case BOTH_LK_S_S_T_L_1: //lock if I'm using single vs. a single and I initiated
986 case BOTH_LK_DL_DL_S_L_1: //lock if I'm using dual vs. dual and I initiated
987 case BOTH_LK_DL_DL_T_L_1: //lock if I'm using dual vs. dual and I initiated
988 case BOTH_LK_DL_ST_S_L_1: //lock if I'm using dual vs. a staff
989 case BOTH_LK_DL_ST_T_L_1: //lock if I'm using dual vs. a staff
990 case BOTH_LK_DL_S_S_L_1: //lock if I'm using dual vs. a single
991 case BOTH_LK_DL_S_T_L_1: //lock if I'm using dual vs. a single
992 case BOTH_LK_ST_DL_S_L_1: //lock if I'm using staff vs. dual
993 case BOTH_LK_ST_DL_T_L_1: //lock if I'm using staff vs. dual
994 case BOTH_LK_ST_ST_S_L_1: //lock if I'm using staff vs. a staff and I initiated
995 case BOTH_LK_ST_ST_T_L_1: //lock if I'm using staff vs. a staff and I initiated
996 case BOTH_LK_ST_S_S_L_1: //lock if I'm using staff vs. a single
997 case BOTH_LK_ST_S_T_L_1: //lock if I'm using staff vs. a single
998 case BOTH_LK_S_S_S_L_2:
999 case BOTH_LK_S_S_T_L_2:
1000 case BOTH_LK_DL_DL_S_L_2:
1001 case BOTH_LK_DL_DL_T_L_2:
1002 case BOTH_LK_ST_ST_S_L_2:
1003 case BOTH_LK_ST_ST_T_L_2:
1004 return qtrue;
1005 break;
1006 default:
1007 return BG_InSaberLockOld( anim );
1008 break;
1009 }
1010 //return qfalse;
1011 }
1012
1013 //Called only where pm is valid (not all require pm, but some do):
PM_InCartwheel(int anim)1014 qboolean PM_InCartwheel( int anim )
1015 {
1016 switch ( anim )
1017 {
1018 case BOTH_ARIAL_LEFT:
1019 case BOTH_ARIAL_RIGHT:
1020 case BOTH_ARIAL_F1:
1021 case BOTH_CARTWHEEL_LEFT:
1022 case BOTH_CARTWHEEL_RIGHT:
1023 return qtrue;
1024 break;
1025 }
1026 return qfalse;
1027 }
1028
BG_InKnockDownOnGround(playerState_t * ps)1029 qboolean BG_InKnockDownOnGround( playerState_t *ps )
1030 {
1031 switch ( ps->legsAnim )
1032 {
1033 case BOTH_KNOCKDOWN1:
1034 case BOTH_KNOCKDOWN2:
1035 case BOTH_KNOCKDOWN3:
1036 case BOTH_KNOCKDOWN4:
1037 case BOTH_KNOCKDOWN5:
1038 case BOTH_RELEASED:
1039 //if ( PM_AnimLength( g_entities[ps->clientNum].client->clientInfo.animFileIndex, (animNumber_t)ps->legsAnim ) - ps->legsAnimTimer > 300 )
1040 {//at end of fall down anim
1041 return qtrue;
1042 }
1043 break;
1044 case BOTH_GETUP1:
1045 case BOTH_GETUP2:
1046 case BOTH_GETUP3:
1047 case BOTH_GETUP4:
1048 case BOTH_GETUP5:
1049 case BOTH_GETUP_CROUCH_F1:
1050 case BOTH_GETUP_CROUCH_B1:
1051 case BOTH_FORCE_GETUP_F1:
1052 case BOTH_FORCE_GETUP_F2:
1053 case BOTH_FORCE_GETUP_B1:
1054 case BOTH_FORCE_GETUP_B2:
1055 case BOTH_FORCE_GETUP_B3:
1056 case BOTH_FORCE_GETUP_B4:
1057 case BOTH_FORCE_GETUP_B5:
1058 case BOTH_FORCE_GETUP_B6:
1059 if ( BG_AnimLength( 0, (animNumber_t)ps->legsAnim ) - ps->legsTimer < 500 )
1060 {//at beginning of getup anim
1061 return qtrue;
1062 }
1063 break;
1064 case BOTH_GETUP_BROLL_B:
1065 case BOTH_GETUP_BROLL_F:
1066 case BOTH_GETUP_BROLL_L:
1067 case BOTH_GETUP_BROLL_R:
1068 case BOTH_GETUP_FROLL_B:
1069 case BOTH_GETUP_FROLL_F:
1070 case BOTH_GETUP_FROLL_L:
1071 case BOTH_GETUP_FROLL_R:
1072 if ( BG_AnimLength( 0, (animNumber_t)ps->legsAnim ) - ps->legsTimer < 500 )
1073 {//at beginning of getup anim
1074 return qtrue;
1075 }
1076 break;
1077 case BOTH_LK_DL_ST_T_SB_1_L:
1078 if ( ps->legsTimer < 1000 )
1079 {
1080 return qtrue;
1081 }
1082 break;
1083 case BOTH_PLAYER_PA_3_FLY:
1084 if ( ps->legsTimer < 300 )
1085 {
1086 return qtrue;
1087 }
1088 break;
1089 }
1090 return qfalse;
1091 }
1092
BG_StabDownAnim(int anim)1093 qboolean BG_StabDownAnim( int anim )
1094 {
1095 switch ( anim )
1096 {
1097 case BOTH_STABDOWN:
1098 case BOTH_STABDOWN_STAFF:
1099 case BOTH_STABDOWN_DUAL:
1100 return qtrue;
1101 }
1102 return qfalse;
1103 }
1104
PM_SaberBounceForAttack(int move)1105 int PM_SaberBounceForAttack( int move )
1106 {
1107 switch ( saberMoveData[move].startQuad )
1108 {
1109 case Q_B:
1110 case Q_BR:
1111 return LS_B1_BR;
1112 break;
1113 case Q_R:
1114 return LS_B1__R;
1115 break;
1116 case Q_TR:
1117 return LS_B1_TR;
1118 break;
1119 case Q_T:
1120 return LS_B1_T_;
1121 break;
1122 case Q_TL:
1123 return LS_B1_TL;
1124 break;
1125 case Q_L:
1126 return LS_B1__L;
1127 break;
1128 case Q_BL:
1129 return LS_B1_BL;
1130 break;
1131 }
1132 return LS_NONE;
1133 }
1134
PM_SaberDeflectionForQuad(int quad)1135 int PM_SaberDeflectionForQuad( int quad )
1136 {
1137 switch ( quad )
1138 {
1139 case Q_B:
1140 return LS_D1_B_;
1141 break;
1142 case Q_BR:
1143 return LS_D1_BR;
1144 break;
1145 case Q_R:
1146 return LS_D1__R;
1147 break;
1148 case Q_TR:
1149 return LS_D1_TR;
1150 break;
1151 case Q_T:
1152 return LS_D1_T_;
1153 break;
1154 case Q_TL:
1155 return LS_D1_TL;
1156 break;
1157 case Q_L:
1158 return LS_D1__L;
1159 break;
1160 case Q_BL:
1161 return LS_D1_BL;
1162 break;
1163 }
1164 return LS_NONE;
1165 }
1166
PM_SaberInDeflect(int move)1167 qboolean PM_SaberInDeflect( int move )
1168 {
1169 if ( move >= LS_D1_BR && move <= LS_D1_B_ )
1170 {
1171 return qtrue;
1172 }
1173 return qfalse;
1174 }
1175
PM_SaberInParry(int move)1176 qboolean PM_SaberInParry( int move )
1177 {
1178 if ( move >= LS_PARRY_UP && move <= LS_PARRY_LL )
1179 {
1180 return qtrue;
1181 }
1182 return qfalse;
1183 }
1184
PM_SaberInKnockaway(int move)1185 qboolean PM_SaberInKnockaway( int move )
1186 {
1187 if ( move >= LS_K1_T_ && move <= LS_K1_BL )
1188 {
1189 return qtrue;
1190 }
1191 return qfalse;
1192 }
1193
PM_SaberInReflect(int move)1194 qboolean PM_SaberInReflect( int move )
1195 {
1196 if ( move >= LS_REFLECT_UP && move <= LS_REFLECT_LL )
1197 {
1198 return qtrue;
1199 }
1200 return qfalse;
1201 }
1202
PM_SaberInStart(int move)1203 qboolean PM_SaberInStart( int move )
1204 {
1205 if ( move >= LS_S_TL2BR && move <= LS_S_T2B )
1206 {
1207 return qtrue;
1208 }
1209 return qfalse;
1210 }
1211
PM_SaberInReturn(int move)1212 qboolean PM_SaberInReturn( int move )
1213 {
1214 if ( move >= LS_R_TL2BR && move <= LS_R_T2B )
1215 {
1216 return qtrue;
1217 }
1218 return qfalse;
1219 }
1220
BG_SaberInReturn(int move)1221 qboolean BG_SaberInReturn( int move )
1222 {
1223 return PM_SaberInReturn( move );
1224 }
1225
PM_InSaberAnim(int anim)1226 qboolean PM_InSaberAnim( int anim )
1227 {
1228 if ( (anim) >= BOTH_A1_T__B_ && (anim) <= BOTH_H1_S1_BR )
1229 {
1230 return qtrue;
1231 }
1232 return qfalse;
1233 }
1234
PM_InKnockDown(playerState_t * ps)1235 qboolean PM_InKnockDown( playerState_t *ps )
1236 {
1237 switch ( (ps->legsAnim) )
1238 {
1239 case BOTH_KNOCKDOWN1:
1240 case BOTH_KNOCKDOWN2:
1241 case BOTH_KNOCKDOWN3:
1242 case BOTH_KNOCKDOWN4:
1243 case BOTH_KNOCKDOWN5:
1244 return qtrue;
1245 break;
1246 case BOTH_GETUP1:
1247 case BOTH_GETUP2:
1248 case BOTH_GETUP3:
1249 case BOTH_GETUP4:
1250 case BOTH_GETUP5:
1251 case BOTH_FORCE_GETUP_F1:
1252 case BOTH_FORCE_GETUP_F2:
1253 case BOTH_FORCE_GETUP_B1:
1254 case BOTH_FORCE_GETUP_B2:
1255 case BOTH_FORCE_GETUP_B3:
1256 case BOTH_FORCE_GETUP_B4:
1257 case BOTH_FORCE_GETUP_B5:
1258 case BOTH_GETUP_BROLL_B:
1259 case BOTH_GETUP_BROLL_F:
1260 case BOTH_GETUP_BROLL_L:
1261 case BOTH_GETUP_BROLL_R:
1262 case BOTH_GETUP_FROLL_B:
1263 case BOTH_GETUP_FROLL_F:
1264 case BOTH_GETUP_FROLL_L:
1265 case BOTH_GETUP_FROLL_R:
1266 if ( ps->legsTimer )
1267 {
1268 return qtrue;
1269 }
1270 break;
1271 }
1272 return qfalse;
1273 }
1274
PM_PainAnim(int anim)1275 qboolean PM_PainAnim( int anim )
1276 {
1277 switch ( (anim) )
1278 {
1279 case BOTH_PAIN1: //# First take pain anim
1280 case BOTH_PAIN2: //# Second take pain anim
1281 case BOTH_PAIN3: //# Third take pain anim
1282 case BOTH_PAIN4: //# Fourth take pain anim
1283 case BOTH_PAIN5: //# Fifth take pain anim - from behind
1284 case BOTH_PAIN6: //# Sixth take pain anim - from behind
1285 case BOTH_PAIN7: //# Seventh take pain anim - from behind
1286 case BOTH_PAIN8: //# Eigth take pain anim - from behind
1287 case BOTH_PAIN9: //#
1288 case BOTH_PAIN10: //#
1289 case BOTH_PAIN11: //#
1290 case BOTH_PAIN12: //#
1291 case BOTH_PAIN13: //#
1292 case BOTH_PAIN14: //#
1293 case BOTH_PAIN15: //#
1294 case BOTH_PAIN16: //#
1295 case BOTH_PAIN17: //#
1296 case BOTH_PAIN18: //#
1297 return qtrue;
1298 break;
1299 }
1300 return qfalse;
1301 }
1302
PM_JumpingAnim(int anim)1303 qboolean PM_JumpingAnim( int anim )
1304 {
1305 switch ( (anim) )
1306 {
1307 case BOTH_JUMP1: //# Jump - wind-up and leave ground
1308 case BOTH_INAIR1: //# In air loop (from jump)
1309 case BOTH_LAND1: //# Landing (from in air loop)
1310 case BOTH_LAND2: //# Landing Hard (from a great height)
1311 case BOTH_JUMPBACK1: //# Jump backwards - wind-up and leave ground
1312 case BOTH_INAIRBACK1: //# In air loop (from jump back)
1313 case BOTH_LANDBACK1: //# Landing backwards(from in air loop)
1314 case BOTH_JUMPLEFT1: //# Jump left - wind-up and leave ground
1315 case BOTH_INAIRLEFT1: //# In air loop (from jump left)
1316 case BOTH_LANDLEFT1: //# Landing left(from in air loop)
1317 case BOTH_JUMPRIGHT1: //# Jump right - wind-up and leave ground
1318 case BOTH_INAIRRIGHT1: //# In air loop (from jump right)
1319 case BOTH_LANDRIGHT1: //# Landing right(from in air loop)
1320 case BOTH_FORCEJUMP1: //# Jump - wind-up and leave ground
1321 case BOTH_FORCEINAIR1: //# In air loop (from jump)
1322 case BOTH_FORCELAND1: //# Landing (from in air loop)
1323 case BOTH_FORCEJUMPBACK1: //# Jump backwards - wind-up and leave ground
1324 case BOTH_FORCEINAIRBACK1: //# In air loop (from jump back)
1325 case BOTH_FORCELANDBACK1: //# Landing backwards(from in air loop)
1326 case BOTH_FORCEJUMPLEFT1: //# Jump left - wind-up and leave ground
1327 case BOTH_FORCEINAIRLEFT1: //# In air loop (from jump left)
1328 case BOTH_FORCELANDLEFT1: //# Landing left(from in air loop)
1329 case BOTH_FORCEJUMPRIGHT1: //# Jump right - wind-up and leave ground
1330 case BOTH_FORCEINAIRRIGHT1: //# In air loop (from jump right)
1331 case BOTH_FORCELANDRIGHT1: //# Landing right(from in air loop)
1332 return qtrue;
1333 break;
1334 }
1335 return qfalse;
1336 }
1337
PM_LandingAnim(int anim)1338 qboolean PM_LandingAnim( int anim )
1339 {
1340 switch ( (anim) )
1341 {
1342 case BOTH_LAND1: //# Landing (from in air loop)
1343 case BOTH_LAND2: //# Landing Hard (from a great height)
1344 case BOTH_LANDBACK1: //# Landing backwards(from in air loop)
1345 case BOTH_LANDLEFT1: //# Landing left(from in air loop)
1346 case BOTH_LANDRIGHT1: //# Landing right(from in air loop)
1347 case BOTH_FORCELAND1: //# Landing (from in air loop)
1348 case BOTH_FORCELANDBACK1: //# Landing backwards(from in air loop)
1349 case BOTH_FORCELANDLEFT1: //# Landing left(from in air loop)
1350 case BOTH_FORCELANDRIGHT1: //# Landing right(from in air loop)
1351 return qtrue;
1352 break;
1353 }
1354 return qfalse;
1355 }
1356
PM_SpinningAnim(int anim)1357 qboolean PM_SpinningAnim( int anim )
1358 {
1359 /*
1360 switch ( anim )
1361 {
1362 //FIXME: list any other spinning anims
1363 default:
1364 break;
1365 }
1366 */
1367 return BG_SpinningSaberAnim( anim );
1368 }
1369
PM_InOnGroundAnim(int anim)1370 qboolean PM_InOnGroundAnim ( int anim )
1371 {
1372 switch( anim )
1373 {
1374 case BOTH_DEAD1:
1375 case BOTH_DEAD2:
1376 case BOTH_DEAD3:
1377 case BOTH_DEAD4:
1378 case BOTH_DEAD5:
1379 case BOTH_DEADFORWARD1:
1380 case BOTH_DEADBACKWARD1:
1381 case BOTH_DEADFORWARD2:
1382 case BOTH_DEADBACKWARD2:
1383 case BOTH_LYINGDEATH1:
1384 case BOTH_LYINGDEAD1:
1385 case BOTH_SLEEP1: //# laying on back-rknee up-rhand on torso
1386 case BOTH_KNOCKDOWN1: //#
1387 case BOTH_KNOCKDOWN2: //#
1388 case BOTH_KNOCKDOWN3: //#
1389 case BOTH_KNOCKDOWN4: //#
1390 case BOTH_KNOCKDOWN5: //#
1391 case BOTH_GETUP1:
1392 case BOTH_GETUP2:
1393 case BOTH_GETUP3:
1394 case BOTH_GETUP4:
1395 case BOTH_GETUP5:
1396 case BOTH_GETUP_CROUCH_F1:
1397 case BOTH_GETUP_CROUCH_B1:
1398 case BOTH_FORCE_GETUP_F1:
1399 case BOTH_FORCE_GETUP_F2:
1400 case BOTH_FORCE_GETUP_B1:
1401 case BOTH_FORCE_GETUP_B2:
1402 case BOTH_FORCE_GETUP_B3:
1403 case BOTH_FORCE_GETUP_B4:
1404 case BOTH_FORCE_GETUP_B5:
1405 case BOTH_FORCE_GETUP_B6:
1406 case BOTH_GETUP_BROLL_B:
1407 case BOTH_GETUP_BROLL_F:
1408 case BOTH_GETUP_BROLL_L:
1409 case BOTH_GETUP_BROLL_R:
1410 case BOTH_GETUP_FROLL_B:
1411 case BOTH_GETUP_FROLL_F:
1412 case BOTH_GETUP_FROLL_L:
1413 case BOTH_GETUP_FROLL_R:
1414 return qtrue;
1415 break;
1416 }
1417
1418 return qfalse;
1419 }
1420
PM_InRollComplete(playerState_t * ps,int anim)1421 qboolean PM_InRollComplete( playerState_t *ps, int anim )
1422 {
1423 switch ( (anim) )
1424 {
1425 case BOTH_ROLL_F:
1426 case BOTH_ROLL_B:
1427 case BOTH_ROLL_R:
1428 case BOTH_ROLL_L:
1429 if ( ps->legsTimer < 1 )
1430 {
1431 return qtrue;
1432 }
1433 break;
1434 }
1435 return qfalse;
1436 }
1437
PM_CanRollFromSoulCal(playerState_t * ps)1438 qboolean PM_CanRollFromSoulCal( playerState_t *ps )
1439 {
1440 if ( ps->legsAnim == BOTH_A7_SOULCAL
1441 && ps->legsTimer < 700
1442 && ps->legsTimer > 250 )
1443 {
1444 return qtrue;
1445 }
1446 return qfalse;
1447 }
1448
BG_SuperBreakLoseAnim(int anim)1449 qboolean BG_SuperBreakLoseAnim( int anim )
1450 {
1451 switch ( anim )
1452 {
1453 case BOTH_LK_S_DL_S_SB_1_L: //super break I lost
1454 case BOTH_LK_S_DL_T_SB_1_L: //super break I lost
1455 case BOTH_LK_S_ST_S_SB_1_L: //super break I lost
1456 case BOTH_LK_S_ST_T_SB_1_L: //super break I lost
1457 case BOTH_LK_S_S_S_SB_1_L: //super break I lost
1458 case BOTH_LK_S_S_T_SB_1_L: //super break I lost
1459 case BOTH_LK_DL_DL_S_SB_1_L: //super break I lost
1460 case BOTH_LK_DL_DL_T_SB_1_L: //super break I lost
1461 case BOTH_LK_DL_ST_S_SB_1_L: //super break I lost
1462 case BOTH_LK_DL_ST_T_SB_1_L: //super break I lost
1463 case BOTH_LK_DL_S_S_SB_1_L: //super break I lost
1464 case BOTH_LK_DL_S_T_SB_1_L: //super break I lost
1465 case BOTH_LK_ST_DL_S_SB_1_L: //super break I lost
1466 case BOTH_LK_ST_DL_T_SB_1_L: //super break I lost
1467 case BOTH_LK_ST_ST_S_SB_1_L: //super break I lost
1468 case BOTH_LK_ST_ST_T_SB_1_L: //super break I lost
1469 case BOTH_LK_ST_S_S_SB_1_L: //super break I lost
1470 case BOTH_LK_ST_S_T_SB_1_L: //super break I lost
1471 return qtrue;
1472 break;
1473 }
1474 return qfalse;
1475 }
1476
BG_SuperBreakWinAnim(int anim)1477 qboolean BG_SuperBreakWinAnim( int anim )
1478 {
1479 switch ( anim )
1480 {
1481 case BOTH_LK_S_DL_S_SB_1_W: //super break I won
1482 case BOTH_LK_S_DL_T_SB_1_W: //super break I won
1483 case BOTH_LK_S_ST_S_SB_1_W: //super break I won
1484 case BOTH_LK_S_ST_T_SB_1_W: //super break I won
1485 case BOTH_LK_S_S_S_SB_1_W: //super break I won
1486 case BOTH_LK_S_S_T_SB_1_W: //super break I won
1487 case BOTH_LK_DL_DL_S_SB_1_W: //super break I won
1488 case BOTH_LK_DL_DL_T_SB_1_W: //super break I won
1489 case BOTH_LK_DL_ST_S_SB_1_W: //super break I won
1490 case BOTH_LK_DL_ST_T_SB_1_W: //super break I won
1491 case BOTH_LK_DL_S_S_SB_1_W: //super break I won
1492 case BOTH_LK_DL_S_T_SB_1_W: //super break I won
1493 case BOTH_LK_ST_DL_S_SB_1_W: //super break I won
1494 case BOTH_LK_ST_DL_T_SB_1_W: //super break I won
1495 case BOTH_LK_ST_ST_S_SB_1_W: //super break I won
1496 case BOTH_LK_ST_ST_T_SB_1_W: //super break I won
1497 case BOTH_LK_ST_S_S_SB_1_W: //super break I won
1498 case BOTH_LK_ST_S_T_SB_1_W: //super break I won
1499 return qtrue;
1500 break;
1501 }
1502 return qfalse;
1503 }
1504
1505
BG_SaberLockBreakAnim(int anim)1506 qboolean BG_SaberLockBreakAnim( int anim )
1507 {
1508 switch ( anim )
1509 {
1510 case BOTH_BF1BREAK:
1511 case BOTH_BF2BREAK:
1512 case BOTH_CWCIRCLEBREAK:
1513 case BOTH_CCWCIRCLEBREAK:
1514 case BOTH_LK_S_DL_S_B_1_L: //normal break I lost
1515 case BOTH_LK_S_DL_S_B_1_W: //normal break I won
1516 case BOTH_LK_S_DL_T_B_1_L: //normal break I lost
1517 case BOTH_LK_S_DL_T_B_1_W: //normal break I won
1518 case BOTH_LK_S_ST_S_B_1_L: //normal break I lost
1519 case BOTH_LK_S_ST_S_B_1_W: //normal break I won
1520 case BOTH_LK_S_ST_T_B_1_L: //normal break I lost
1521 case BOTH_LK_S_ST_T_B_1_W: //normal break I won
1522 case BOTH_LK_S_S_S_B_1_L: //normal break I lost
1523 case BOTH_LK_S_S_S_B_1_W: //normal break I won
1524 case BOTH_LK_S_S_T_B_1_L: //normal break I lost
1525 case BOTH_LK_S_S_T_B_1_W: //normal break I won
1526 case BOTH_LK_DL_DL_S_B_1_L: //normal break I lost
1527 case BOTH_LK_DL_DL_S_B_1_W: //normal break I won
1528 case BOTH_LK_DL_DL_T_B_1_L: //normal break I lost
1529 case BOTH_LK_DL_DL_T_B_1_W: //normal break I won
1530 case BOTH_LK_DL_ST_S_B_1_L: //normal break I lost
1531 case BOTH_LK_DL_ST_S_B_1_W: //normal break I won
1532 case BOTH_LK_DL_ST_T_B_1_L: //normal break I lost
1533 case BOTH_LK_DL_ST_T_B_1_W: //normal break I won
1534 case BOTH_LK_DL_S_S_B_1_L: //normal break I lost
1535 case BOTH_LK_DL_S_S_B_1_W: //normal break I won
1536 case BOTH_LK_DL_S_T_B_1_L: //normal break I lost
1537 case BOTH_LK_DL_S_T_B_1_W: //normal break I won
1538 case BOTH_LK_ST_DL_S_B_1_L: //normal break I lost
1539 case BOTH_LK_ST_DL_S_B_1_W: //normal break I won
1540 case BOTH_LK_ST_DL_T_B_1_L: //normal break I lost
1541 case BOTH_LK_ST_DL_T_B_1_W: //normal break I won
1542 case BOTH_LK_ST_ST_S_B_1_L: //normal break I lost
1543 case BOTH_LK_ST_ST_S_B_1_W: //normal break I won
1544 case BOTH_LK_ST_ST_T_B_1_L: //normal break I lost
1545 case BOTH_LK_ST_ST_T_B_1_W: //normal break I won
1546 case BOTH_LK_ST_S_S_B_1_L: //normal break I lost
1547 case BOTH_LK_ST_S_S_B_1_W: //normal break I won
1548 case BOTH_LK_ST_S_T_B_1_L: //normal break I lost
1549 case BOTH_LK_ST_S_T_B_1_W: //normal break I won
1550 return qtrue;
1551 break;
1552 }
1553 return (BG_SuperBreakLoseAnim(anim)||BG_SuperBreakWinAnim(anim));
1554 }
1555
1556
BG_FullBodyTauntAnim(int anim)1557 qboolean BG_FullBodyTauntAnim( int anim )
1558 {
1559 switch ( anim )
1560 {
1561 case BOTH_GESTURE1:
1562 case BOTH_DUAL_TAUNT:
1563 case BOTH_STAFF_TAUNT:
1564 case BOTH_BOW:
1565 case BOTH_MEDITATE:
1566 case BOTH_SHOWOFF_FAST:
1567 case BOTH_SHOWOFF_MEDIUM:
1568 case BOTH_SHOWOFF_STRONG:
1569 case BOTH_SHOWOFF_DUAL:
1570 case BOTH_SHOWOFF_STAFF:
1571 case BOTH_VICTORY_FAST:
1572 case BOTH_VICTORY_MEDIUM:
1573 case BOTH_VICTORY_STRONG:
1574 case BOTH_VICTORY_DUAL:
1575 case BOTH_VICTORY_STAFF:
1576 return qtrue;
1577 break;
1578 }
1579 return qfalse;
1580 }
1581
1582
1583 /*
1584 =============
1585 BG_AnimLength
1586
1587 Get the "length" of an anim given the local anim index (which skeleton)
1588 and anim number. Obviously does not take things like the length of the
1589 anim while force speeding (as an example) and whatnot into account.
1590 =============
1591 */
BG_AnimLength(int index,animNumber_t anim)1592 int BG_AnimLength( int index, animNumber_t anim ) {
1593 if ( (int)anim < 0 || anim >= MAX_ANIMATIONS ) {
1594 return 0;
1595 }
1596
1597 return bgAllAnims[index].anims[anim].numFrames * fabs( (float)(bgAllAnims[index].anims[anim].frameLerp) );
1598 }
1599
1600 //just use whatever pm->animations is
PM_AnimLength(int index,animNumber_t anim)1601 int PM_AnimLength( int index, animNumber_t anim ) {
1602 if ( !pm->animations || (int)anim < 0 || anim >= MAX_ANIMATIONS ) {
1603 return 0;
1604 }
1605
1606 return pm->animations[anim].numFrames * fabs( (float)(pm->animations[anim].frameLerp) );
1607 }
1608
PM_DebugLegsAnim(int anim)1609 void PM_DebugLegsAnim(int anim)
1610 {
1611 int oldAnim = (pm->ps->legsAnim);
1612 int newAnim = (anim);
1613
1614 if (oldAnim < MAX_TOTALANIMATIONS && oldAnim >= BOTH_DEATH1 &&
1615 newAnim < MAX_TOTALANIMATIONS && newAnim >= BOTH_DEATH1)
1616 {
1617 Com_Printf("OLD: %s\n", animTable[oldAnim]);
1618 Com_Printf("NEW: %s\n", animTable[newAnim]);
1619 }
1620 }
1621
PM_SaberInTransition(int move)1622 qboolean PM_SaberInTransition( int move )
1623 {
1624 if ( move >= LS_T1_BR__R && move <= LS_T1_BL__L )
1625 {
1626 return qtrue;
1627 }
1628 return qfalse;
1629 }
1630
BG_SaberInTransitionAny(int move)1631 qboolean BG_SaberInTransitionAny( int move )
1632 {
1633 if ( PM_SaberInStart( move ) )
1634 {
1635 return qtrue;
1636 }
1637 else if ( PM_SaberInTransition( move ) )
1638 {
1639 return qtrue;
1640 }
1641 else if ( PM_SaberInReturn( move ) )
1642 {
1643 return qtrue;
1644 }
1645 return qfalse;
1646 }
1647
1648 /*
1649 ==============================================================================
1650 END: Animation utility functions (sequence checking)
1651 ==============================================================================
1652 */
1653
BG_FlipPart(playerState_t * ps,int part)1654 void BG_FlipPart(playerState_t *ps, int part)
1655 {
1656 if (part == SETANIM_TORSO)
1657 {
1658 if (ps->torsoFlip)
1659 {
1660 ps->torsoFlip = qfalse;
1661 }
1662 else
1663 {
1664 ps->torsoFlip = qtrue;
1665 }
1666 }
1667 else if (part == SETANIM_LEGS)
1668 {
1669 if (ps->legsFlip)
1670 {
1671 ps->legsFlip = qfalse;
1672 }
1673 else
1674 {
1675 ps->legsFlip = qtrue;
1676 }
1677 }
1678 }
1679
1680 qboolean BGPAFtextLoaded = qfalse;
1681 animation_t bgHumanoidAnimations[MAX_TOTALANIMATIONS]; //humanoid animations are the only ones that are statically allocated.
1682
1683 bgLoadedAnim_t bgAllAnims[MAX_ANIM_FILES];
1684 int bgNumAllAnims = 2; //start off at 2, because 0 will always be assigned to humanoid, and 1 will always be rockettrooper
1685
1686 //ALWAYS call on game/cgame init
BG_InitAnimsets(void)1687 void BG_InitAnimsets(void)
1688 {
1689 memset(&bgAllAnims, 0, sizeof(bgAllAnims));
1690 BGPAFtextLoaded = qfalse; // VVFIXME - The PC doesn't seem to need this, but why?
1691 }
1692
1693 //ALWAYS call on game/cgame shutdown
BG_ClearAnimsets(void)1694 void BG_ClearAnimsets(void)
1695 {
1696 /*
1697 int i = 1;
1698
1699 while (i < bgNumAllAnims)
1700 {
1701 if (bgAllAnims[i].anims)
1702 {
1703 strap_TrueFree((void **)&bgAllAnims[i].anims);
1704 }
1705 i++;
1706 }
1707 */
1708 }
1709
BG_AnimsetAlloc(void)1710 animation_t *BG_AnimsetAlloc(void)
1711 {
1712 assert (bgNumAllAnims < MAX_ANIM_FILES);
1713 bgAllAnims[bgNumAllAnims].anims = (animation_t *) BG_Alloc(sizeof(animation_t)*MAX_TOTALANIMATIONS);
1714
1715 return bgAllAnims[bgNumAllAnims].anims;
1716 }
1717
BG_AnimsetFree(animation_t * animset)1718 void BG_AnimsetFree(animation_t *animset)
1719 {
1720 /*
1721 if (!animset)
1722 {
1723 return;
1724 }
1725
1726 strap_TrueFree((void **)&animset);
1727
1728 #ifdef _DEBUG
1729 if (animset)
1730 {
1731 assert(!"Failed to free anim set");
1732 }
1733 #endif
1734 */
1735 }
1736
1737 #ifdef _CGAME //none of this is actually needed serverside. Could just be moved to cgame code but it's here since it used to tie in a lot with the anim loading stuff.
1738 stringID_table_t animEventTypeTable[MAX_ANIM_EVENTS+1] =
1739 {
1740 ENUM2STRING(AEV_SOUND), //# animID AEV_SOUND framenum soundpath randomlow randomhi chancetoplay
1741 ENUM2STRING(AEV_FOOTSTEP), //# animID AEV_FOOTSTEP framenum footstepType
1742 ENUM2STRING(AEV_EFFECT), //# animID AEV_EFFECT framenum effectpath boltName
1743 ENUM2STRING(AEV_FIRE), //# animID AEV_FIRE framenum altfire chancetofire
1744 ENUM2STRING(AEV_MOVE), //# animID AEV_MOVE framenum forwardpush rightpush uppush
1745 ENUM2STRING(AEV_SOUNDCHAN), //# animID AEV_SOUNDCHAN framenum CHANNEL soundpath randomlow randomhi chancetoplay
1746 ENUM2STRING(AEV_SABER_SWING), //# animID AEV_SABER_SWING framenum CHANNEL randomlow randomhi chancetoplay
1747 ENUM2STRING(AEV_SABER_SPIN), //# animID AEV_SABER_SPIN framenum CHANNEL chancetoplay
1748 //must be terminated
1749 { NULL,-1 }
1750 };
1751
1752 stringID_table_t footstepTypeTable[NUM_FOOTSTEP_TYPES+1] =
1753 {
1754 ENUM2STRING(FOOTSTEP_R),
1755 ENUM2STRING(FOOTSTEP_L),
1756 ENUM2STRING(FOOTSTEP_HEAVY_R),
1757 ENUM2STRING(FOOTSTEP_HEAVY_L),
1758 //must be terminated
1759 { NULL,-1 }
1760 };
1761
CheckAnimFrameForEventType(animevent_t * animEvents,int keyFrame,animEventType_t eventType)1762 int CheckAnimFrameForEventType( animevent_t *animEvents, int keyFrame, animEventType_t eventType )
1763 {
1764 int i;
1765
1766 for ( i = 0; i < MAX_ANIM_EVENTS; i++ )
1767 {
1768 if ( animEvents[i].keyFrame == keyFrame )
1769 {//there is an animevent on this frame already
1770 if ( animEvents[i].eventType == eventType )
1771 {//and it is of the same type
1772 return i;
1773 }
1774 }
1775 }
1776 //nope
1777 return -1;
1778 }
1779
ParseAnimationEvtBlock(const char * aeb_filename,animevent_t * animEvents,animation_t * animations,int * i,const char ** text_p)1780 void ParseAnimationEvtBlock(const char *aeb_filename, animevent_t *animEvents, animation_t *animations, int *i,const char **text_p)
1781 {
1782 const char *token;
1783 int num, n, animNum, keyFrame, lowestVal, highestVal, curAnimEvent, lastAnimEvent = 0;
1784 animEventType_t eventType;
1785 char stringData[MAX_QPATH];
1786
1787 // get past starting bracket
1788 while(1)
1789 {
1790 token = COM_Parse( text_p );
1791 if ( !Q_stricmp( token, "{" ) )
1792 {
1793 break;
1794 }
1795 }
1796
1797 //NOTE: instead of a blind increment, increase the index
1798 // this way if we have an event on an anim that already
1799 // has an event of that type, it stomps it
1800
1801 // read information for each frame
1802 while ( 1 )
1803 {
1804 if ( lastAnimEvent >= MAX_ANIM_EVENTS )
1805 {
1806 Com_Error( ERR_DROP, "ParseAnimationEvtBlock: number events in animEvent file %s > MAX_ANIM_EVENTS(%i)", aeb_filename, MAX_ANIM_EVENTS );
1807 return;
1808 }
1809 // Get base frame of sequence
1810 token = COM_Parse( text_p );
1811 if ( !token || !token[0])
1812 {
1813 break;
1814 }
1815
1816 if ( !Q_stricmp( token, "}" ) ) // At end of block
1817 {
1818 break;
1819 }
1820
1821 //Compare to same table as animations used
1822 // so we don't have to use actual numbers for animation first frames,
1823 // just need offsets.
1824 //This way when animation numbers change, this table won't have to be updated,
1825 // at least not much.
1826 animNum = GetIDForString(animTable, token);
1827 if(animNum == -1)
1828 {//Unrecognized ANIM ENUM name, or we're skipping this line, keep going till you get a good one
1829 Com_Printf(S_COLOR_YELLOW"WARNING: Unknown token %s in animEvent file %s\n", token, aeb_filename );
1830 while (token[0])
1831 {
1832 token = COM_ParseExt( text_p, qfalse ); //returns empty string when next token is EOL
1833 }
1834 continue;
1835 }
1836
1837 if ( animations[animNum].numFrames == 0 )
1838 {//we don't use this anim
1839 Com_Printf(S_COLOR_YELLOW"WARNING: %s animevents.cfg: anim %s not used by this model\n", aeb_filename, token);
1840 //skip this entry
1841 SkipRestOfLine( text_p );
1842 continue;
1843 }
1844
1845 token = COM_Parse( text_p );
1846 eventType = (animEventType_t)GetIDForString(animEventTypeTable, token);
1847 if ( eventType == AEV_NONE || eventType == (animEventType_t)-1 )
1848 {//Unrecognized ANIM EVENT TYOE, or we're skipping this line, keep going till you get a good one
1849 //Com_Printf(S_COLOR_YELLOW"WARNING: Unknown token %s in animEvent file %s\n", token, aeb_filename );
1850 continue;
1851 }
1852
1853 //set our start frame
1854 keyFrame = animations[animNum].firstFrame;
1855 // Get offset to frame within sequence
1856 token = COM_Parse( text_p );
1857 if ( !token )
1858 {
1859 break;
1860 }
1861 keyFrame += atoi( token );
1862
1863 //see if this frame already has an event of this type on it, if so, overwrite it
1864 curAnimEvent = CheckAnimFrameForEventType( animEvents, keyFrame, eventType );
1865 if ( curAnimEvent == -1 )
1866 {//this anim frame doesn't already have an event of this type on it
1867 curAnimEvent = lastAnimEvent;
1868 }
1869
1870 //now that we know which event index we're going to plug the data into, start doing it
1871 animEvents[curAnimEvent].eventType = eventType;
1872 animEvents[curAnimEvent].keyFrame = keyFrame;
1873
1874 //now read out the proper data based on the type
1875 switch ( animEvents[curAnimEvent].eventType )
1876 {
1877 case AEV_SOUNDCHAN: //# animID AEV_SOUNDCHAN framenum CHANNEL soundpath randomlow randomhi chancetoplay
1878 token = COM_Parse( text_p );
1879 if ( !token )
1880 break;
1881
1882 if ( !Q_stricmp( token, "CHAN_VOICE_ATTEN" ) )
1883 animEvents[curAnimEvent].eventData[AED_SOUNDCHANNEL] = CHAN_VOICE_ATTEN;
1884 else if ( !Q_stricmp( token, "CHAN_VOICE_GLOBAL" ) )
1885 animEvents[curAnimEvent].eventData[AED_SOUNDCHANNEL] = CHAN_VOICE_GLOBAL;
1886 else if ( !Q_stricmp( token, "CHAN_ANNOUNCER" ) )
1887 animEvents[curAnimEvent].eventData[AED_SOUNDCHANNEL] = CHAN_ANNOUNCER;
1888 else if ( !Q_stricmp( token, "CHAN_BODY" ) )
1889 animEvents[curAnimEvent].eventData[AED_SOUNDCHANNEL] = CHAN_BODY;
1890 else if ( !Q_stricmp( token, "CHAN_WEAPON" ) )
1891 animEvents[curAnimEvent].eventData[AED_SOUNDCHANNEL] = CHAN_WEAPON;
1892 else if ( !Q_stricmp( token, "CHAN_VOICE" ) )
1893 animEvents[curAnimEvent].eventData[AED_SOUNDCHANNEL] = CHAN_VOICE;
1894 else
1895 animEvents[curAnimEvent].eventData[AED_SOUNDCHANNEL] = CHAN_AUTO;
1896
1897 //fall through to normal sound
1898 case AEV_SOUND: //# animID AEV_SOUND framenum soundpath randomlow randomhi chancetoplay
1899 //get soundstring
1900 token = COM_Parse( text_p );
1901 if ( !token )
1902 {
1903 break;
1904 }
1905 strcpy(stringData, token);
1906 //get lowest value
1907 token = COM_Parse( text_p );
1908 if ( !token )
1909 {//WARNING! BAD TABLE!
1910 break;
1911 }
1912 lowestVal = atoi( token );
1913 //get highest value
1914 token = COM_Parse( text_p );
1915 if ( !token )
1916 {//WARNING! BAD TABLE!
1917 break;
1918 }
1919 highestVal = atoi( token );
1920 //Now precache all the sounds
1921 //NOTE: If we can be assured sequential handles, we can store sound indices
1922 // instead of strings, unfortunately, if these sounds were previously
1923 // registered, we cannot be guaranteed sequential indices. Thus an array
1924 if(lowestVal && highestVal)
1925 {
1926 //assert(highestVal - lowestVal < MAX_RANDOM_ANIM_SOUNDS);
1927 if ((highestVal-lowestVal) >= MAX_RANDOM_ANIM_SOUNDS)
1928 {
1929 highestVal = lowestVal + (MAX_RANDOM_ANIM_SOUNDS-1);
1930 }
1931 for ( n = lowestVal, num = AED_SOUNDINDEX_START; n <= highestVal && num <= AED_SOUNDINDEX_END; n++, num++ )
1932 {
1933 if (stringData[0] == '*')
1934 { //FIXME? Would be nice to make custom sounds work with animEvents.
1935 animEvents[curAnimEvent].eventData[num] = 0;
1936 }
1937 else
1938 {
1939 animEvents[curAnimEvent].eventData[num] = trap->S_RegisterSound( va( stringData, n ) );
1940 }
1941 }
1942 animEvents[curAnimEvent].eventData[AED_SOUND_NUMRANDOMSNDS] = num - 1;
1943 }
1944 else
1945 {
1946 if (stringData[0] == '*')
1947 { //FIXME? Would be nice to make custom sounds work with animEvents.
1948 animEvents[curAnimEvent].eventData[AED_SOUNDINDEX_START] = 0;
1949 }
1950 else
1951 {
1952 animEvents[curAnimEvent].eventData[AED_SOUNDINDEX_START] = trap->S_RegisterSound( stringData );
1953 }
1954 #ifndef FINAL_BUILD
1955 if ( !animEvents[curAnimEvent].eventData[AED_SOUNDINDEX_START] &&
1956 stringData[0] != '*')
1957 {//couldn't register it - file not found
1958 Com_Printf( S_COLOR_RED "ParseAnimationSndBlock: sound %s does not exist (animevents.cfg %s)!\n", stringData, aeb_filename );
1959 }
1960 #endif
1961 animEvents[curAnimEvent].eventData[AED_SOUND_NUMRANDOMSNDS] = 0;
1962 }
1963 //get probability
1964 token = COM_Parse( text_p );
1965 if ( !token )
1966 {//WARNING! BAD TABLE!
1967 break;
1968 }
1969 animEvents[curAnimEvent].eventData[AED_SOUND_PROBABILITY] = atoi( token );
1970
1971 //last part - cheat and check and see if it's a special overridable saber sound we know of...
1972 if ( !Q_stricmpn( "sound/weapons/saber/saberhup", stringData, 28 ) )
1973 {//a saber swing
1974 animEvents[curAnimEvent].eventType = AEV_SABER_SWING;
1975 animEvents[curAnimEvent].eventData[AED_SABER_SWING_SABERNUM] = 0;//since we don't know which one they meant if we're hacking this, always use first saber
1976 animEvents[curAnimEvent].eventData[AED_SABER_SWING_PROBABILITY] = animEvents[curAnimEvent].eventData[AED_SOUND_PROBABILITY];
1977 if ( lowestVal < 4 )
1978 {//fast swing
1979 animEvents[curAnimEvent].eventData[AED_SABER_SWING_TYPE] = 0;//SWING_FAST;
1980 }
1981 else if ( lowestVal < 7 )
1982 {//medium swing
1983 animEvents[curAnimEvent].eventData[AED_SABER_SWING_TYPE] = 1;//SWING_MEDIUM;
1984 }
1985 else
1986 {//strong swing
1987 animEvents[curAnimEvent].eventData[AED_SABER_SWING_TYPE] = 2;//SWING_STRONG;
1988 }
1989 }
1990 else if ( !Q_stricmpn( "sound/weapons/saber/saberspin", stringData, 29 ) )
1991 {//a saber spin
1992 animEvents[curAnimEvent].eventType = AEV_SABER_SPIN;
1993 animEvents[curAnimEvent].eventData[AED_SABER_SPIN_SABERNUM] = 0;//since we don't know which one they meant if we're hacking this, always use first saber
1994 animEvents[curAnimEvent].eventData[AED_SABER_SPIN_PROBABILITY] = animEvents[curAnimEvent].eventData[AED_SOUND_PROBABILITY];
1995 if ( stringData[29] == 'o' )
1996 {//saberspinoff
1997 animEvents[curAnimEvent].eventData[AED_SABER_SPIN_TYPE] = 0;
1998 }
1999 else if ( stringData[29] == '1' )
2000 {//saberspin1
2001 animEvents[curAnimEvent].eventData[AED_SABER_SPIN_TYPE] = 2;
2002 }
2003 else if ( stringData[29] == '2' )
2004 {//saberspin2
2005 animEvents[curAnimEvent].eventData[AED_SABER_SPIN_TYPE] = 3;
2006 }
2007 else if ( stringData[29] == '3' )
2008 {//saberspin3
2009 animEvents[curAnimEvent].eventData[AED_SABER_SPIN_TYPE] = 4;
2010 }
2011 else if ( stringData[29] == '%' )
2012 {//saberspin%d
2013 animEvents[curAnimEvent].eventData[AED_SABER_SPIN_TYPE] = 5;
2014 }
2015 else
2016 {//just plain saberspin
2017 animEvents[curAnimEvent].eventData[AED_SABER_SPIN_TYPE] = 1;
2018 }
2019 }
2020 break;
2021 case AEV_FOOTSTEP: //# animID AEV_FOOTSTEP framenum footstepType
2022 //get footstep type
2023 token = COM_Parse( text_p );
2024 if ( !token )
2025 {
2026 break;
2027 }
2028 animEvents[curAnimEvent].eventData[AED_FOOTSTEP_TYPE] = GetIDForString(footstepTypeTable, token);
2029 //get probability
2030 token = COM_Parse( text_p );
2031 if ( !token )
2032 {//WARNING! BAD TABLE!
2033 break;
2034 }
2035 animEvents[curAnimEvent].eventData[AED_FOOTSTEP_PROBABILITY] = atoi( token );
2036 break;
2037 case AEV_EFFECT: //# animID AEV_EFFECT framenum effectpath boltName
2038 //get effect index
2039 token = COM_Parse( text_p );
2040 if ( !token )
2041 {
2042 break;
2043 }
2044 animEvents[curAnimEvent].eventData[AED_EFFECTINDEX] = trap->FX_RegisterEffect( token );
2045 //get bolt index
2046 token = COM_Parse( text_p );
2047 if ( !token )
2048 {
2049 break;
2050 }
2051 if ( Q_stricmp( "none", token ) != 0 && Q_stricmp( "NULL", token ) != 0 )
2052 {//actually are specifying a bolt to use
2053 if (!animEvents[curAnimEvent].stringData)
2054 { //eh, whatever. no dynamic stuff, so this will do.
2055 animEvents[curAnimEvent].stringData = (char *) BG_Alloc(2048);
2056 }
2057 strcpy(animEvents[curAnimEvent].stringData, token);
2058 }
2059 //NOTE: this string will later be used to add a bolt and store the index, as below:
2060 //animEvent->eventData[AED_BOLTINDEX] = trap->G2API_AddBolt( ¢->gent->ghoul2[cent->gent->playerModel], animEvent->stringData );
2061 //get probability
2062 token = COM_Parse( text_p );
2063 if ( !token )
2064 {//WARNING! BAD TABLE!
2065 break;
2066 }
2067 animEvents[curAnimEvent].eventData[AED_EFFECT_PROBABILITY] = atoi( token );
2068 break;
2069 case AEV_FIRE: //# animID AEV_FIRE framenum altfire chancetofire
2070 //get altfire
2071 token = COM_Parse( text_p );
2072 if ( !token )
2073 {//WARNING! BAD TABLE!
2074 break;
2075 }
2076 animEvents[curAnimEvent].eventData[AED_FIRE_ALT] = atoi( token );
2077 //get probability
2078 token = COM_Parse( text_p );
2079 if ( !token )
2080 {//WARNING! BAD TABLE!
2081 break;
2082 }
2083 animEvents[curAnimEvent].eventData[AED_FIRE_PROBABILITY] = atoi( token );
2084 break;
2085 case AEV_MOVE: //# animID AEV_MOVE framenum forwardpush rightpush uppush
2086 //get forward push
2087 token = COM_Parse( text_p );
2088 if ( !token )
2089 {//WARNING! BAD TABLE!
2090 break;
2091 }
2092 animEvents[curAnimEvent].eventData[AED_MOVE_FWD] = atoi( token );
2093 //get right push
2094 token = COM_Parse( text_p );
2095 if ( !token )
2096 {//WARNING! BAD TABLE!
2097 break;
2098 }
2099 animEvents[curAnimEvent].eventData[AED_MOVE_RT] = atoi( token );
2100 //get upwards push
2101 token = COM_Parse( text_p );
2102 if ( !token )
2103 {//WARNING! BAD TABLE!
2104 break;
2105 }
2106 animEvents[curAnimEvent].eventData[AED_MOVE_UP] = atoi( token );
2107 break;
2108 default: //unknown?
2109 SkipRestOfLine( text_p );
2110 continue;
2111 break;
2112 }
2113
2114 if ( curAnimEvent == lastAnimEvent )
2115 {
2116 lastAnimEvent++;
2117 }
2118 }
2119 }
2120
2121 /*
2122 ======================
2123 BG_ParseAnimationEvtFile
2124
2125 Read a configuration file containing animation events
2126 models/players/kyle/animevents.cfg, etc
2127
2128 This file's presence is not required
2129
2130 ======================
2131 */
2132 bgLoadedEvents_t bgAllEvents[MAX_ANIM_FILES];
2133 int bgNumAnimEvents = 1;
2134 static int bg_animParseIncluding = 0;
BG_ParseAnimationEvtFile(const char * as_filename,int animFileIndex,int eventFileIndex)2135 int BG_ParseAnimationEvtFile( const char *as_filename, int animFileIndex, int eventFileIndex )
2136 {
2137 const char *text_p;
2138 int len;
2139 const char *token;
2140 char text[80000];
2141 char sfilename[MAX_QPATH];
2142 fileHandle_t f;
2143 int i, j, upper_i, lower_i;
2144 int usedIndex = -1;
2145 animevent_t *legsAnimEvents;
2146 animevent_t *torsoAnimEvents;
2147 animation_t *animations;
2148 int forcedIndex;
2149
2150 assert(animFileIndex < MAX_ANIM_FILES);
2151 assert(eventFileIndex < MAX_ANIM_FILES);
2152
2153 if (eventFileIndex == -1)
2154 {
2155 forcedIndex = 0;
2156 }
2157 else
2158 {
2159 forcedIndex = eventFileIndex;
2160 }
2161
2162 if (bg_animParseIncluding <= 0)
2163 { //if we should be parsing an included file, skip this part
2164 if ( bgAllEvents[forcedIndex].eventsParsed )
2165 {//already cached this one
2166 return forcedIndex;
2167 }
2168 }
2169
2170 legsAnimEvents = bgAllEvents[forcedIndex].legsAnimEvents;
2171 torsoAnimEvents = bgAllEvents[forcedIndex].torsoAnimEvents;
2172 animations = bgAllAnims[animFileIndex].anims;
2173
2174 if (bg_animParseIncluding <= 0)
2175 { //if we should be parsing an included file, skip this part
2176 //Go through and see if this filename is already in the table.
2177 i = 0;
2178 while (i < bgNumAnimEvents && forcedIndex != 0)
2179 {
2180 if (!Q_stricmp(as_filename, bgAllEvents[i].filename))
2181 { //looks like we have it already.
2182 return i;
2183 }
2184 i++;
2185 }
2186 }
2187
2188 // Load and parse animevents.cfg file
2189 Com_sprintf( sfilename, sizeof( sfilename ), "%sanimevents.cfg", as_filename );
2190
2191 if (bg_animParseIncluding <= 0)
2192 { //should already be done if we're including
2193 //initialize anim event array
2194 for( i = 0; i < MAX_ANIM_EVENTS; i++ )
2195 {
2196 //Type of event
2197 torsoAnimEvents[i].eventType = AEV_NONE;
2198 legsAnimEvents[i].eventType = AEV_NONE;
2199 //Frame to play event on
2200 torsoAnimEvents[i].keyFrame = -1;
2201 legsAnimEvents[i].keyFrame = -1;
2202 //we allow storage of one string, temporarily (in case we have to look up an index later, then make sure to set stringData to NULL so we only do the look-up once)
2203 torsoAnimEvents[i].stringData = NULL;
2204 legsAnimEvents[i].stringData = NULL;
2205 //Unique IDs, can be soundIndex of sound file to play OR effect index or footstep type, etc.
2206 for ( j = 0; j < AED_ARRAY_SIZE; j++ )
2207 {
2208 torsoAnimEvents[i].eventData[j] = -1;
2209 legsAnimEvents[i].eventData[j] = -1;
2210 }
2211 }
2212 }
2213
2214 // load the file
2215 len = trap->FS_Open( sfilename, &f, FS_READ );
2216 if ( len <= 0 )
2217 {//no file
2218 goto fin;
2219 }
2220 if ( len >= sizeof( text ) - 1 )
2221 {
2222 trap->FS_Close(f);
2223 #ifndef FINAL_BUILD
2224 Com_Error(ERR_DROP, "File %s too long\n", sfilename );
2225 #else
2226 Com_Printf( "File %s too long\n", sfilename );
2227 #endif
2228 goto fin;
2229 }
2230
2231 trap->FS_Read( text, len, f );
2232 text[len] = 0;
2233 trap->FS_Close( f );
2234
2235 // parse the text
2236 text_p = text;
2237 upper_i =0;
2238 lower_i =0;
2239
2240 COM_BeginParseSession ("BG_ParseAnimationEvtFile");
2241
2242 // read information for batches of sounds (UPPER or LOWER)
2243 while ( 1 )
2244 {
2245 // Get base frame of sequence
2246 token = COM_Parse( &text_p );
2247 if ( !token || !token[0] )
2248 {
2249 break;
2250 }
2251
2252 if ( !Q_stricmp(token,"include") ) // grab from another animevents.cfg
2253 {//NOTE: you REALLY should NOT do this after the main block of UPPERSOUNDS and LOWERSOUNDS
2254 const char *include_filename = COM_Parse( &text_p );
2255 if ( include_filename != NULL )
2256 {
2257 char fullIPath[MAX_QPATH];
2258 strcpy(fullIPath, va("models/players/%s/", include_filename));
2259 bg_animParseIncluding++;
2260 BG_ParseAnimationEvtFile( fullIPath, animFileIndex, forcedIndex );
2261 bg_animParseIncluding--;
2262 }
2263 }
2264
2265 if ( !Q_stricmp(token,"UPPEREVENTS") ) // A batch of upper sounds
2266 {
2267 ParseAnimationEvtBlock( as_filename, torsoAnimEvents, animations, &upper_i, &text_p );
2268 }
2269
2270 else if ( !Q_stricmp(token,"LOWEREVENTS") ) // A batch of lower sounds
2271 {
2272 ParseAnimationEvtBlock( as_filename, legsAnimEvents, animations, &lower_i, &text_p );
2273 }
2274 }
2275
2276 usedIndex = forcedIndex;
2277 fin:
2278 //Mark this anim set so that we know we tried to load he sounds, don't care if the load failed
2279 if (bg_animParseIncluding <= 0)
2280 { //if we should be parsing an included file, skip this part
2281 bgAllEvents[forcedIndex].eventsParsed = qtrue;
2282 strcpy(bgAllEvents[forcedIndex].filename, as_filename);
2283 if (forcedIndex)
2284 {
2285 bgNumAnimEvents++;
2286 }
2287 }
2288
2289 return usedIndex;
2290 }
2291 #endif
2292
2293 /*
2294 ======================
2295 BG_ParseAnimationFile
2296
2297 Read a configuration file containing animation counts and rates
2298 models/players/visor/animation.cfg, etc
2299
2300 ======================
2301 */
BG_ParseAnimationFile(const char * filename,animation_t * animset,qboolean isHumanoid)2302 int BG_ParseAnimationFile(const char *filename, animation_t *animset, qboolean isHumanoid)
2303 {
2304 char *text_p;
2305 int len;
2306 int i;
2307 char *token;
2308 float fps;
2309 int usedIndex = -1;
2310 int nextIndex = bgNumAllAnims;
2311 qboolean dynAlloc = qfalse;
2312 ///qboolean wasLoaded = qfalse;
2313 static char BGPAFtext[60000];
2314 fileHandle_t f;
2315 int animNum;
2316
2317 BGPAFtext[0] = '\0';
2318
2319 if (!isHumanoid)
2320 {
2321 i = 0;
2322 while (i < bgNumAllAnims)
2323 { //see if it's been loaded already
2324 if (!Q_stricmp(bgAllAnims[i].filename, filename))
2325 {
2326 animset = bgAllAnims[i].anims;
2327 return i; //alright, we already have it.
2328 }
2329 i++;
2330 }
2331
2332 //Looks like it has not yet been loaded. Allocate space for the anim set if we need to, and continue along.
2333 if (!animset)
2334 {
2335 if (strstr(filename, "players/_humanoid/"))
2336 { //then use the static humanoid set.
2337 animset = bgHumanoidAnimations;
2338 nextIndex = 0;
2339 }
2340 else if (strstr(filename, "players/rockettrooper/"))
2341 { //rockettrooper always index 1
2342 nextIndex = 1;
2343 animset = BG_AnimsetAlloc();
2344 dynAlloc = qtrue; //so we know to free this memory in case we have to return early. Don't want any leaks.
2345
2346 if (!animset)
2347 {
2348 assert(!"Anim set alloc failed!");
2349 return -1;
2350 }
2351 }
2352 else
2353 {
2354 animset = BG_AnimsetAlloc();
2355 dynAlloc = qtrue; //so we know to free this memory in case we have to return early. Don't want any leaks.
2356
2357 if (!animset)
2358 {
2359 assert(!"Anim set alloc failed!");
2360 return -1;
2361 }
2362 }
2363 }
2364 }
2365 #ifdef _DEBUG
2366 else
2367 {
2368 assert(animset);
2369 }
2370 #endif
2371
2372 // load the file
2373 if (!BGPAFtextLoaded || !isHumanoid)
2374 { //rww - We are always using the same animation config now. So only load it once.
2375 len = trap->FS_Open( filename, &f, FS_READ );
2376 if ( (len <= 0) || (len >= sizeof( BGPAFtext ) - 1) )
2377 {
2378 trap->FS_Close( f );
2379 if (dynAlloc)
2380 {
2381 BG_AnimsetFree(animset);
2382 }
2383 if (len > 0)
2384 {
2385 Com_Error(ERR_DROP, "%s exceeds the allowed game-side animation buffer!", filename);
2386 }
2387 return -1;
2388 }
2389
2390 trap->FS_Read( BGPAFtext, len, f );
2391
2392 BGPAFtext[len] = 0;
2393 trap->FS_Close( f );
2394 }
2395 else
2396 {
2397 if (dynAlloc)
2398 {
2399 assert(!"Should not have allocated dynamically for humanoid");
2400 BG_AnimsetFree(animset);
2401 }
2402 return 0; //humanoid index
2403 }
2404
2405 // parse the text
2406 text_p = BGPAFtext;
2407
2408 //FIXME: have some way of playing anims backwards... negative numFrames?
2409
2410 //initialize anim array so that from 0 to MAX_ANIMATIONS, set default values of 0 1 0 100
2411 for(i = 0; i < MAX_ANIMATIONS; i++)
2412 {
2413 animset[i].firstFrame = 0;
2414 animset[i].numFrames = 0;
2415 animset[i].loopFrames = -1;
2416 animset[i].frameLerp = 100;
2417 }
2418
2419 // read information for each frame
2420 while(1)
2421 {
2422 token = COM_Parse( (const char **)(&text_p) );
2423
2424 if ( !token || !token[0])
2425 {
2426 break;
2427 }
2428
2429 animNum = GetIDForString(animTable, token);
2430 if(animNum == -1)
2431 {
2432 //#ifndef FINAL_BUILD
2433 #ifdef _DEBUG
2434 if (strcmp(token,"ROOT"))
2435 {
2436 Com_Printf(S_COLOR_RED"WARNING: Unknown token %s in %s\n", token, filename);
2437 }
2438 while (token[0])
2439 {
2440 token = COM_ParseExt( (const char **) &text_p, qfalse ); //returns empty string when next token is EOL
2441 }
2442 #endif
2443 continue;
2444 }
2445
2446 token = COM_Parse( (const char **)(&text_p) );
2447 if ( !token )
2448 {
2449 break;
2450 }
2451 animset[animNum].firstFrame = atoi( token );
2452
2453 token = COM_Parse( (const char **)(&text_p) );
2454 if ( !token )
2455 {
2456 break;
2457 }
2458 animset[animNum].numFrames = atoi( token );
2459
2460 token = COM_Parse( (const char **)(&text_p) );
2461 if ( !token )
2462 {
2463 break;
2464 }
2465 animset[animNum].loopFrames = atoi( token );
2466
2467 token = COM_Parse( (const char **)(&text_p) );
2468 if ( !token )
2469 {
2470 break;
2471 }
2472 fps = atof( token );
2473 if ( fps == 0 )
2474 {
2475 fps = 1;//Don't allow divide by zero error
2476 }
2477 if ( fps < 0 )
2478 {//backwards
2479 animset[animNum].frameLerp = floor(1000.0f / fps);
2480 }
2481 else
2482 {
2483 animset[animNum].frameLerp = ceil(1000.0f / fps);
2484 }
2485 }
2486 /*
2487 #ifdef _DEBUG
2488 //Check the array, and print the ones that have nothing in them.
2489 for(i = 0; i < MAX_ANIMATIONS; i++)
2490 {
2491 if (animTable[i].name != NULL) // This animation reference exists.
2492 {
2493 if (animset[i].firstFrame <= 0 && animset[i].numFrames <=0)
2494 { // This is an empty animation reference.
2495 Com_Printf("***ANIMTABLE reference #%d (%s) is empty!\n", i, animTable[i].name);
2496 }
2497 }
2498 }
2499 #endif // _DEBUG
2500 */
2501 #ifdef CONVENIENT_ANIMATION_FILE_DEBUG_THING
2502 SpewDebugStuffToFile();
2503 #endif
2504
2505 // wasLoaded = BGPAFtextLoaded;
2506
2507 if (isHumanoid)
2508 {
2509 bgAllAnims[0].anims = animset;
2510 strcpy(bgAllAnims[0].filename, filename);
2511 BGPAFtextLoaded = qtrue;
2512
2513 usedIndex = 0;
2514 }
2515 else
2516 {
2517 bgAllAnims[nextIndex].anims = animset;
2518 strcpy(bgAllAnims[nextIndex].filename, filename);
2519
2520 usedIndex = bgNumAllAnims;
2521
2522 if (nextIndex > 1)
2523 { //don't bother increasing the number if this ended up as a humanoid/rockettrooper load.
2524 bgNumAllAnims++;
2525 }
2526 else
2527 {
2528 BGPAFtextLoaded = qtrue;
2529 usedIndex = nextIndex;
2530 }
2531 }
2532
2533 /*
2534 if (!wasLoaded && BGPAFtextLoaded)
2535 { //just loaded humanoid skel - we always want the rockettrooper to be after it, in slot 1
2536 #ifdef _DEBUG
2537 assert(BG_ParseAnimationFile("models/players/rockettrooper/animation.cfg", NULL, qfalse) == 1);
2538 #else
2539 BG_ParseAnimationFile("models/players/rockettrooper/animation.cfg", NULL, qfalse);
2540 #endif
2541 }
2542 */
2543
2544 return usedIndex;
2545 }
2546
2547 /*
2548 ===================
2549 LEGS Animations
2550 Base animation for overall body
2551 ===================
2552 */
BG_StartLegsAnim(playerState_t * ps,int anim)2553 static void BG_StartLegsAnim( playerState_t *ps, int anim )
2554 {
2555 if ( ps->pm_type >= PM_DEAD )
2556 {
2557 //vehicles are allowed to do this.. IF it's a vehicle death anim
2558 if (ps->clientNum < MAX_CLIENTS || anim != BOTH_VT_DEATH1)
2559 {
2560 return;
2561 }
2562 }
2563 if ( ps->legsTimer > 0 )
2564 {
2565 return; // a high priority animation is running
2566 }
2567
2568 if (ps->legsAnim == anim)
2569 {
2570 BG_FlipPart(ps, SETANIM_LEGS);
2571 }
2572 #ifdef _GAME
2573 else if (g_entities[ps->clientNum].s.legsAnim == anim)
2574 { //toggled anim to one anim then back to the one we were at previously in
2575 //one frame, indicating that anim should be restarted.
2576 BG_FlipPart(ps, SETANIM_LEGS);
2577 }
2578 #endif
2579 ps->legsAnim = anim;
2580
2581 /*
2582 if ( pm->debugLevel ) {
2583 Com_Printf("%d: StartLegsAnim %d, on client#%d\n", pm->cmd.serverTime, anim, pm->ps->clientNum);
2584 }
2585 */
2586 }
2587
PM_ContinueLegsAnim(int anim)2588 void PM_ContinueLegsAnim( int anim ) {
2589 if ( ( pm->ps->legsAnim ) == anim ) {
2590 return;
2591 }
2592 if ( pm->ps->legsTimer > 0 ) {
2593 return; // a high priority animation is running
2594 }
2595
2596 BG_StartLegsAnim( pm->ps, anim );
2597 }
2598
PM_ForceLegsAnim(int anim)2599 void PM_ForceLegsAnim( int anim) {
2600 if (BG_InSpecialJump(pm->ps->legsAnim) &&
2601 pm->ps->legsTimer > 0 &&
2602 !BG_InSpecialJump(anim))
2603 {
2604 return;
2605 }
2606
2607 if (BG_InRoll(pm->ps, pm->ps->legsAnim) &&
2608 pm->ps->legsTimer > 0 &&
2609 !BG_InRoll(pm->ps, anim))
2610 {
2611 return;
2612 }
2613
2614 pm->ps->legsTimer = 0;
2615 BG_StartLegsAnim( pm->ps, anim );
2616 }
2617
2618
2619
2620 /*
2621 ===================
2622 TORSO Animations
2623 Override animations for upper body
2624 ===================
2625 */
BG_StartTorsoAnim(playerState_t * ps,int anim)2626 void BG_StartTorsoAnim( playerState_t *ps, int anim )
2627 {
2628 if ( ps->pm_type >= PM_DEAD )
2629 {
2630 return;
2631 }
2632
2633 if (ps->torsoAnim == anim)
2634 {
2635 BG_FlipPart(ps, SETANIM_TORSO);
2636 }
2637 #ifdef _GAME
2638 else if (g_entities[ps->clientNum].s.torsoAnim == anim)
2639 { //toggled anim to one anim then back to the one we were at previously in
2640 //one frame, indicating that anim should be restarted.
2641 BG_FlipPart(ps, SETANIM_TORSO);
2642 }
2643 #endif
2644 ps->torsoAnim = anim;
2645 }
2646
PM_StartTorsoAnim(int anim)2647 void PM_StartTorsoAnim( int anim )
2648 {
2649 BG_StartTorsoAnim(pm->ps, anim);
2650 }
2651
2652
2653 /*
2654 -------------------------
2655 PM_SetLegsAnimTimer
2656 -------------------------
2657 */
BG_SetLegsAnimTimer(playerState_t * ps,int time)2658 void BG_SetLegsAnimTimer(playerState_t *ps, int time)
2659 {
2660 ps->legsTimer = time;
2661
2662 if (ps->legsTimer < 0 && time != -1 )
2663 {//Cap timer to 0 if was counting down, but let it be -1 if that was intentional. NOTENOTE Yeah this seems dumb, but it mirrors SP.
2664 ps->legsTimer = 0;
2665 }
2666 }
2667
PM_SetLegsAnimTimer(int time)2668 void PM_SetLegsAnimTimer(int time)
2669 {
2670 BG_SetLegsAnimTimer(pm->ps, time);
2671 }
2672
2673 /*
2674 -------------------------
2675 PM_SetTorsoAnimTimer
2676 -------------------------
2677 */
BG_SetTorsoAnimTimer(playerState_t * ps,int time)2678 void BG_SetTorsoAnimTimer(playerState_t *ps, int time )
2679 {
2680 ps->torsoTimer = time;
2681
2682 if (ps->torsoTimer < 0 && time != -1 )
2683 {//Cap timer to 0 if was counting down, but let it be -1 if that was intentional. NOTENOTE Yeah this seems dumb, but it mirrors SP.
2684 ps->torsoTimer = 0;
2685 }
2686 }
2687
PM_SetTorsoAnimTimer(int time)2688 void PM_SetTorsoAnimTimer(int time )
2689 {
2690 BG_SetTorsoAnimTimer(pm->ps, time);
2691 }
2692
BG_SaberStartTransAnim(int clientNum,int saberAnimLevel,int weapon,int anim,float * animSpeed,int broken)2693 void BG_SaberStartTransAnim( int clientNum, int saberAnimLevel, int weapon, int anim, float *animSpeed, int broken )
2694 {
2695 if ( anim >= BOTH_A1_T__B_ && anim <= BOTH_ROLL_STAB )
2696 {
2697 if ( weapon == WP_SABER )
2698 {
2699 saberInfo_t *saber = BG_MySaber( clientNum, 0 );
2700 if ( saber
2701 && saber->animSpeedScale != 1.0f )
2702 {
2703 *animSpeed *= saber->animSpeedScale;
2704 }
2705 saber = BG_MySaber( clientNum, 1 );
2706 if ( saber
2707 && saber->animSpeedScale != 1.0f )
2708 {
2709 *animSpeed *= saber->animSpeedScale;
2710 }
2711 }
2712 }
2713
2714 if ( ( (anim) >= BOTH_T1_BR__R &&
2715 (anim) <= BOTH_T1_BL_TL ) ||
2716 ( (anim) >= BOTH_T2_BR__R &&
2717 (anim) <= BOTH_T2_BL_TL ) ||
2718 ( (anim) >= BOTH_T3_BR__R &&
2719 (anim) <= BOTH_T3_BL_TL ) )
2720 {
2721 if ( saberAnimLevel == FORCE_LEVEL_1 )
2722 {
2723 *animSpeed *= 1.5f;
2724 }
2725 else if ( saberAnimLevel == FORCE_LEVEL_3 )
2726 {
2727 *animSpeed *= 0.75f;
2728 }
2729
2730 if (broken & (1<<BROKENLIMB_RARM))
2731 {
2732 *animSpeed *= 0.5f;
2733 }
2734 else if (broken & (1<<BROKENLIMB_LARM))
2735 {
2736 *animSpeed *= 0.65f;
2737 }
2738 }
2739 else if (broken && PM_InSaberAnim(anim))
2740 {
2741 if (broken & (1<<BROKENLIMB_RARM))
2742 {
2743 *animSpeed *= 0.5f;
2744 }
2745 else if (broken & (1<<BROKENLIMB_LARM))
2746 {
2747 *animSpeed *= 0.65f;
2748 }
2749 }
2750 }
2751
2752 /*
2753 -------------------------
2754 PM_SetAnimFinal
2755 -------------------------
2756 */
2757 qboolean PM_RunningAnim( int anim );
2758 qboolean PM_WalkingAnim( int anim );
2759
BG_SetAnimFinal(playerState_t * ps,animation_t * animations,int setAnimParts,int anim,int setAnimFlags)2760 void BG_SetAnimFinal(playerState_t *ps, animation_t *animations,
2761 int setAnimParts,int anim,int setAnimFlags)
2762 {
2763 float editAnimSpeed = 1;
2764
2765 if (!animations)
2766 {
2767 return;
2768 }
2769
2770 assert(anim > -1);
2771 assert(animations[anim].firstFrame > 0 || animations[anim].numFrames > 0);
2772
2773 BG_SaberStartTransAnim(ps->clientNum, ps->fd.saberAnimLevel, ps->weapon, anim, &editAnimSpeed, ps->brokenLimbs);
2774
2775 // Set torso anim
2776 if (setAnimParts & SETANIM_TORSO)
2777 {
2778 // Don't reset if it's already running the anim
2779 if( !(setAnimFlags & SETANIM_FLAG_RESTART) && (ps->torsoAnim) == anim )
2780 {
2781 goto setAnimLegs;
2782 }
2783 // or if a more important anim is running
2784 if( !(setAnimFlags & SETANIM_FLAG_OVERRIDE) && ((ps->torsoTimer > 0)||(ps->torsoTimer == -1)) )
2785 {
2786 goto setAnimLegs;
2787 }
2788
2789 BG_StartTorsoAnim(ps, anim);
2790
2791 if (setAnimFlags & SETANIM_FLAG_HOLD)
2792 {
2793 if (setAnimFlags & SETANIM_FLAG_HOLDLESS)
2794 { // Make sure to only wait in full 1/20 sec server frame intervals.
2795 int dur;
2796 int speedDif;
2797
2798 dur = (animations[anim].numFrames-1) * fabs((float)(animations[anim].frameLerp));
2799 speedDif = dur - (dur * editAnimSpeed);
2800 dur += speedDif;
2801 if (dur > 1)
2802 {
2803 ps->torsoTimer = dur-1;
2804 }
2805 else
2806 {
2807 ps->torsoTimer = fabs((float)(animations[anim].frameLerp));
2808 }
2809 }
2810 else
2811 {
2812 ps->torsoTimer = ((animations[anim].numFrames ) * fabs((float)(animations[anim].frameLerp)));
2813 }
2814
2815 if (ps->fd.forcePowersActive & (1 << FP_RAGE))
2816 {
2817 ps->torsoTimer /= 1.7;
2818 }
2819 }
2820 }
2821
2822 setAnimLegs:
2823 // Set legs anim
2824 if (setAnimParts & SETANIM_LEGS)
2825 {
2826 // Don't reset if it's already running the anim
2827 if( !(setAnimFlags & SETANIM_FLAG_RESTART) && (ps->legsAnim) == anim )
2828 {
2829 goto setAnimDone;
2830 }
2831 // or if a more important anim is running
2832 if( !(setAnimFlags & SETANIM_FLAG_OVERRIDE) && ((ps->legsTimer > 0)||(ps->legsTimer == -1)) )
2833 {
2834 goto setAnimDone;
2835 }
2836
2837 BG_StartLegsAnim(ps, anim);
2838
2839 if (setAnimFlags & SETANIM_FLAG_HOLD)
2840 {
2841 if (setAnimFlags & SETANIM_FLAG_HOLDLESS)
2842 { // Make sure to only wait in full 1/20 sec server frame intervals.
2843 int dur;
2844 int speedDif;
2845
2846 dur = (animations[anim].numFrames-1) * fabs((float)(animations[anim].frameLerp));
2847 speedDif = dur - (dur * editAnimSpeed);
2848 dur += speedDif;
2849 if (dur > 1)
2850 {
2851 ps->legsTimer = dur-1;
2852 }
2853 else
2854 {
2855 ps->legsTimer = fabs((float)(animations[anim].frameLerp));
2856 }
2857 }
2858 else
2859 {
2860 ps->legsTimer = ((animations[anim].numFrames ) * fabs((float)(animations[anim].frameLerp)));
2861 }
2862
2863 if (PM_RunningAnim(anim) ||
2864 PM_WalkingAnim(anim)) //these guys are ok, they don't actually reference pm
2865 {
2866 if (ps->fd.forcePowersActive & (1 << FP_RAGE))
2867 {
2868 ps->legsTimer /= 1.3;
2869 }
2870 else if (ps->fd.forcePowersActive & (1 << FP_SPEED))
2871 {
2872 ps->legsTimer /= 1.7;
2873 }
2874 }
2875 }
2876 }
2877
2878 setAnimDone:
2879 return;
2880 }
2881
PM_SetAnimFinal(int setAnimParts,int anim,int setAnimFlags)2882 void PM_SetAnimFinal(int setAnimParts,int anim,int setAnimFlags)
2883 {
2884 BG_SetAnimFinal(pm->ps, pm->animations, setAnimParts, anim, setAnimFlags);
2885 }
2886
2887
BG_HasAnimation(int animIndex,int animation)2888 qboolean BG_HasAnimation(int animIndex, int animation)
2889 {
2890 animation_t *animations;
2891
2892 //must be a valid anim number
2893 if ( animation < 0 || animation >= MAX_ANIMATIONS )
2894 {
2895 return qfalse;
2896 }
2897
2898 //Must have a file index entry
2899 if( animIndex < 0 || animIndex > bgNumAllAnims )
2900 return qfalse;
2901
2902 animations = bgAllAnims[animIndex].anims;
2903
2904 //No frames, no anim
2905 if ( animations[animation].numFrames == 0 )
2906 return qfalse;
2907
2908 //Has the sequence
2909 return qtrue;
2910 }
2911
BG_PickAnim(int animIndex,int minAnim,int maxAnim)2912 int BG_PickAnim( int animIndex, int minAnim, int maxAnim )
2913 {
2914 int anim;
2915 int count = 0;
2916
2917 do
2918 {
2919 anim = Q_irand(minAnim, maxAnim);
2920 count++;
2921 }
2922 while ( !BG_HasAnimation( animIndex, anim ) && count < 1000 );
2923
2924 if (count == 1000)
2925 { //guess we just don't have a death anim then.
2926 return -1;
2927 }
2928
2929 return anim;
2930 }
2931
2932 //I want to be able to use this on a playerstate even when we are not the focus
2933 //of a pmove too so I have ported it to true BGishness.
2934 //Please do not reference pm in this function or any functions that it calls,
2935 //or I will cry. -rww
BG_SetAnim(playerState_t * ps,animation_t * animations,int setAnimParts,int anim,int setAnimFlags)2936 void BG_SetAnim(playerState_t *ps, animation_t *animations, int setAnimParts,int anim,int setAnimFlags)
2937 {
2938 if (!animations)
2939 {
2940 animations = bgAllAnims[0].anims;
2941 }
2942
2943 if (animations[anim].firstFrame == 0 && animations[anim].numFrames == 0)
2944 {
2945 if (anim == BOTH_RUNBACK1 ||
2946 anim == BOTH_WALKBACK1 ||
2947 anim == BOTH_RUN1)
2948 { //hack for droids
2949 anim = BOTH_WALK2;
2950 }
2951
2952 if (animations[anim].firstFrame == 0 && animations[anim].numFrames == 0)
2953 { //still? Just return then I guess.
2954 return;
2955 }
2956 }
2957
2958 /*
2959 if (BG_InSpecialJump(anim))
2960 {
2961 setAnimFlags |= SETANIM_FLAG_RESTART;
2962 }
2963 */
2964 //Don't know why I put this here originally but it's messing stuff up now and it isn't needed.
2965
2966 // if (BG_InRoll(ps, ps->legsAnim))
2967 // { //never interrupt a roll
2968 // return;
2969 // }
2970
2971 if (setAnimFlags&SETANIM_FLAG_OVERRIDE)
2972 {
2973 if (setAnimParts & SETANIM_TORSO)
2974 {
2975 if( (setAnimFlags & SETANIM_FLAG_RESTART) || (ps->torsoAnim) != anim )
2976 {
2977 BG_SetTorsoAnimTimer(ps, 0);
2978 }
2979 }
2980 if (setAnimParts & SETANIM_LEGS)
2981 {
2982 if( (setAnimFlags & SETANIM_FLAG_RESTART) || (ps->legsAnim) != anim )
2983 {
2984 BG_SetLegsAnimTimer(ps, 0);
2985 }
2986 }
2987 }
2988
2989 BG_SetAnimFinal(ps, animations, setAnimParts, anim, setAnimFlags);
2990 }
2991
PM_SetAnim(int setAnimParts,int anim,int setAnimFlags)2992 void PM_SetAnim(int setAnimParts,int anim,int setAnimFlags)
2993 {
2994 BG_SetAnim(pm->ps, pm->animations, setAnimParts, anim, setAnimFlags);
2995 }
2996
2997