codemp/game/bg_saber.c File Reference

#include "q_shared.h"
#include "bg_public.h"
#include "bg_local.h"
#include "w_saber.h"
#include "../namespace_begin.h"
#include "../namespace_end.h"

Go to the source code of this file.

Defines

#define AFLAG_IDLE   (SETANIM_FLAG_NORMAL)
#define AFLAG_ACTIVE   (SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD | SETANIM_FLAG_HOLDLESS)
#define AFLAG_WAIT   (SETANIM_FLAG_HOLD | SETANIM_FLAG_HOLDLESS)
#define AFLAG_FINISH   (SETANIM_FLAG_HOLD)
#define BACK_STAB_DISTANCE   128
#define FLIPHACK_DISTANCE   200
#define SABER_ALT_ATTACK_POWER   50
#define SABER_ALT_ATTACK_POWER_LR   10
#define SABER_ALT_ATTACK_POWER_FB   25

Functions

qboolean BG_SabersOff (playerState_t *ps)
saberInfo_tBG_MySaber (int clientNum, int saberNum)
int PM_irand_timesync (int val1, int val2)
void BG_ForcePowerDrain (playerState_t *ps, forcePowers_t forcePower, int overrideAmt)
qboolean BG_EnoughForcePowerForMove (int cost)
saberMoveName_t PM_AttackMoveForQuad (int quad)
qboolean PM_SaberKataDone (int curmove, int newmove)
int PM_SaberAnimTransitionAnim (int curmove, int newmove)
qboolean BG_InKnockDown (int anim)
saberMoveName_t PM_CheckStabDown (void)
int PM_SaberMoveQuadrantForMovement (usercmd_t *ucmd)
qboolean PM_SaberInBounce (int move)
qboolean PM_SaberInTransition (int move)
int PM_SaberAttackChainAngle (int move1, int move2)
void PM_SetAnimFrame (playerState_t *gent, int frame, qboolean torso, qboolean legs)
int PM_SaberLockWinAnim (qboolean victory, qboolean superBreak)
int PM_SaberLockLoseAnim (playerState_t *genemy, qboolean victory, qboolean superBreak)
int PM_SaberLockResultAnim (playerState_t *duelist, qboolean superBreak, qboolean won)
void PM_SaberLockBreak (playerState_t *genemy, qboolean victory, int strength)
qboolean BG_CheckIncrementLockAnim (int anim, int winOrLose)
qboolean ValidAnimFileIndex (int index)
void PM_SaberLocked (void)
qboolean PM_SaberInBrokenParry (int move)
int PM_BrokenParryForParry (int move)
qboolean PM_CanBackstab (void)
saberMoveName_t PM_SaberFlipOverAttackMove (void)
int PM_SaberBackflipAttackMove (void)
int PM_SaberDualJumpAttackMove (void)
qboolean PM_SomeoneInFront (trace_t *tr)
saberMoveName_t PM_SaberLungeAttackMove (qboolean noSpecials)
saberMoveName_t PM_SaberJumpAttackMove2 (void)
saberMoveName_t PM_SaberJumpAttackMove (void)
float PM_GroundDistance (void)
float PM_WalkableGroundDistance (void)
qboolean BG_SaberInTransitionAny (int move)
qboolean PM_SaberInReturn (int move)
saberMoveName_t PM_CheckPullAttack (void)
qboolean PM_InSecondaryStyle (void)
saberMoveName_t PM_SaberAttackForMovement (saberMoveName_t curmove)
int PM_KickMoveForConditions (void)
qboolean BG_InSlopeAnim (int anim)
qboolean PM_RunningAnim (int anim)
qboolean PM_SaberMoveOkayForKata (void)
qboolean PM_CanDoKata (void)
qboolean PM_CheckAltKickAttack (void)
qboolean PM_SaberPowerCheck (void)
qboolean PM_CanDoRollStab (void)
qboolean PM_WalkingAnim (int anim)
qboolean PM_SwimmingAnim (int anim)
int PM_SaberBounceForAttack (int move)
qboolean BG_SuperBreakLoseAnim (int anim)
qboolean BG_SuperBreakWinAnim (int anim)
void PM_WeaponLightsaber (void)
void PM_SetSaberMove (short newMove)

Variables

saberMoveData_t saberMoveData [LS_MOVE_MAX]
int transitionMove [Q_NUM_QUADS][Q_NUM_QUADS]
int saberMoveTransitionAngle [Q_NUM_QUADS][Q_NUM_QUADS]
int bg_parryDebounce [NUM_FORCE_POWER_LEVELS]


Define Documentation

#define AFLAG_ACTIVE   (SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD | SETANIM_FLAG_HOLDLESS)
 

Definition at line 115 of file bg_saber.c.

#define AFLAG_FINISH   (SETANIM_FLAG_HOLD)
 

Definition at line 117 of file bg_saber.c.

#define AFLAG_IDLE   (SETANIM_FLAG_NORMAL)
 

Definition at line 114 of file bg_saber.c.

#define AFLAG_WAIT   (SETANIM_FLAG_HOLD | SETANIM_FLAG_HOLDLESS)
 

Definition at line 116 of file bg_saber.c.

#define BACK_STAB_DISTANCE   128
 

Definition at line 1620 of file bg_saber.c.

Referenced by PM_CanBackstab().

#define FLIPHACK_DISTANCE   200
 

Definition at line 1799 of file bg_saber.c.

Referenced by PM_SomeoneInFront().

#define SABER_ALT_ATTACK_POWER   50
 

Definition at line 2109 of file bg_saber.c.

Referenced by PM_CanDoKata(), and PM_WeaponLightsaber().

#define SABER_ALT_ATTACK_POWER_FB   25
 

Definition at line 2111 of file bg_saber.c.

Referenced by PM_CheckPullAttack(), PM_SaberAttackForMovement(), and PM_WeaponLightsaber().

#define SABER_ALT_ATTACK_POWER_LR   10
 

Definition at line 2110 of file bg_saber.c.

Referenced by PM_SaberAttackForMovement().


Function Documentation

qboolean BG_CheckIncrementLockAnim int  anim,
int  winOrLose
 

Definition at line 1339 of file bg_saber.c.

References BOTH_LK_DL_DL_S_L_1, BOTH_LK_DL_DL_S_L_2, BOTH_LK_DL_DL_T_L_1, BOTH_LK_DL_DL_T_L_2, BOTH_LK_DL_S_S_L_1, BOTH_LK_DL_S_T_L_1, BOTH_LK_DL_ST_S_L_1, BOTH_LK_DL_ST_T_L_1, BOTH_LK_S_DL_S_L_1, BOTH_LK_S_DL_T_L_1, BOTH_LK_S_S_S_L_1, BOTH_LK_S_S_S_L_2, BOTH_LK_S_S_T_L_1, BOTH_LK_S_S_T_L_2, BOTH_LK_S_ST_S_L_1, BOTH_LK_S_ST_T_L_1, BOTH_LK_ST_DL_S_L_1, BOTH_LK_ST_DL_T_L_1, BOTH_LK_ST_S_S_L_1, BOTH_LK_ST_S_T_L_1, BOTH_LK_ST_ST_S_L_1, BOTH_LK_ST_ST_S_L_2, BOTH_LK_ST_ST_T_L_1, BOTH_LK_ST_ST_T_L_2, qboolean, qfalse, qtrue, and SABERLOCK_WIN.

Referenced by PM_SaberLocked().

01340 {
01341         qboolean increment = qfalse;//???
01342         //RULE: if you are the first style in the lock anim, you advance from LOSING position to WINNING position
01343         //              if you are the second style in the lock anim, you advance from WINNING position to LOSING position
01344         switch ( anim )
01345         {
01346         //increment to win:
01347         case BOTH_LK_DL_DL_S_L_1:       //lock if I'm using dual vs. dual and I initiated
01348         case BOTH_LK_DL_DL_S_L_2:       //lock if I'm using dual vs. dual and other initiated
01349         case BOTH_LK_DL_DL_T_L_1:       //lock if I'm using dual vs. dual and I initiated
01350         case BOTH_LK_DL_DL_T_L_2:       //lock if I'm using dual vs. dual and other initiated
01351         case BOTH_LK_DL_S_S_L_1:                //lock if I'm using dual vs. a single
01352         case BOTH_LK_DL_S_T_L_1:                //lock if I'm using dual vs. a single
01353         case BOTH_LK_DL_ST_S_L_1:       //lock if I'm using dual vs. a staff
01354         case BOTH_LK_DL_ST_T_L_1:       //lock if I'm using dual vs. a staff
01355         case BOTH_LK_S_S_S_L_1:         //lock if I'm using single vs. a single and I initiated
01356         case BOTH_LK_S_S_T_L_2:         //lock if I'm using single vs. a single and other initiated
01357         case BOTH_LK_ST_S_S_L_1:                //lock if I'm using staff vs. a single
01358         case BOTH_LK_ST_S_T_L_1:                //lock if I'm using staff vs. a single
01359         case BOTH_LK_ST_ST_T_L_1:       //lock if I'm using staff vs. a staff and I initiated
01360         case BOTH_LK_ST_ST_T_L_2:       //lock if I'm using staff vs. a staff and other initiated
01361                 if ( winOrLose == SABERLOCK_WIN )
01362                 {
01363                         increment = qtrue;
01364                 }
01365                 else
01366                 {
01367                         increment = qfalse;
01368                 }
01369                 break;
01370 
01371         //decrement to win:
01372         case BOTH_LK_S_DL_S_L_1:                //lock if I'm using single vs. a dual
01373         case BOTH_LK_S_DL_T_L_1:                //lock if I'm using single vs. a dual
01374         case BOTH_LK_S_S_S_L_2:         //lock if I'm using single vs. a single and other intitiated
01375         case BOTH_LK_S_S_T_L_1:         //lock if I'm using single vs. a single and I initiated
01376         case BOTH_LK_S_ST_S_L_1:                //lock if I'm using single vs. a staff
01377         case BOTH_LK_S_ST_T_L_1:                //lock if I'm using single vs. a staff
01378         case BOTH_LK_ST_DL_S_L_1:       //lock if I'm using staff vs. dual
01379         case BOTH_LK_ST_DL_T_L_1:       //lock if I'm using staff vs. dual
01380         case BOTH_LK_ST_ST_S_L_1:       //lock if I'm using staff vs. a staff and I initiated
01381         case BOTH_LK_ST_ST_S_L_2:       //lock if I'm using staff vs. a staff and other initiated
01382                 if ( winOrLose == SABERLOCK_WIN )
01383                 {
01384                         increment = qfalse;
01385                 }
01386                 else
01387                 {
01388                         increment = qtrue;
01389                 }
01390                 break;
01391         default:
01392                 break;
01393         }
01394         return increment;
01395 }

qboolean BG_EnoughForcePowerForMove int  cost  ) 
 

Definition at line 102 of file bg_saber.c.

References EV_NOAMMO, playerState_s::fd, forcedata_s::forcePower, pm, PM_AddEvent(), pmove_t::ps, qboolean, qfalse, and qtrue.

Referenced by PM_CanDoKata(), PM_CheckPullAttack(), PM_SaberAttackForMovement(), PM_SaberPowerCheck(), and PM_WeaponLightsaber().

00103 {
00104         if ( pm->ps->fd.forcePower < cost )
00105         {
00106                 PM_AddEvent( EV_NOAMMO );
00107                 return qfalse;
00108         }
00109 
00110         return qtrue;
00111 }

void BG_ForcePowerDrain playerState_t ps,
forcePowers_t  forcePower,
int  overrideAmt
 

Definition at line 27 of file bg_saber.c.

References playerState_s::fd, forcedata_s::forcePower, forcedata_s::forcePowerLevel, forcePowerNeeded, forcePowers_t, FP_LEVITATION, playerState_t, and playerState_s::velocity.

Referenced by ForceHeal(), ForceShootDrain(), ForceTeamForceReplenish(), ForceTeamHeal(), PM_AdjustAngleForWallJump(), PM_CheckPullAttack(), PM_SaberAttackForMovement(), PM_WeaponLightsaber(), WP_DoSpecificPower(), and WP_ForcePowerStart().

00028 {
00029         //take away the power
00030         int     drain = overrideAmt;
00031 
00032         /*
00033         if (ps->powerups[PW_FORCE_BOON])
00034         {
00035                 return;
00036         }
00037         */
00038         //No longer grant infinite force with boon.
00039 
00040         if ( !drain )
00041         {
00042                 drain = forcePowerNeeded[ps->fd.forcePowerLevel[forcePower]][forcePower];
00043         }
00044         if ( !drain )
00045         {
00046                 return;
00047         }
00048 
00049         if (forcePower == FP_LEVITATION)
00050         { //special case
00051                 int jumpDrain = 0;
00052 
00053                 if (ps->velocity[2] > 250)
00054                 {
00055                         jumpDrain = 20;
00056                 }
00057                 else if (ps->velocity[2] > 200)
00058                 {
00059                         jumpDrain = 16;
00060                 }
00061                 else if (ps->velocity[2] > 150)
00062                 {
00063                         jumpDrain = 12;
00064                 }
00065                 else if (ps->velocity[2] > 100)
00066                 {
00067                         jumpDrain = 8;
00068                 }
00069                 else if (ps->velocity[2] > 50)
00070                 {
00071                         jumpDrain = 6;
00072                 }
00073                 else if (ps->velocity[2] > 0)
00074                 {
00075                         jumpDrain = 4;
00076                 }
00077 
00078                 if (jumpDrain)
00079                 {
00080                         if (ps->fd.forcePowerLevel[FP_LEVITATION])
00081                         { //don't divide by 0!
00082                                 jumpDrain /= ps->fd.forcePowerLevel[FP_LEVITATION];
00083                         }
00084                 }
00085 
00086                 ps->fd.forcePower -= jumpDrain;
00087                 if ( ps->fd.forcePower < 0 )
00088                 {
00089                         ps->fd.forcePower = 0;
00090                 }
00091 
00092                 return;
00093         }
00094 
00095         ps->fd.forcePower -= drain;
00096         if ( ps->fd.forcePower < 0 )
00097         {
00098                 ps->fd.forcePower = 0;
00099         }
00100 }

qboolean BG_InKnockDown int  anim  ) 
 

Definition at line 8526 of file bg_pmove.c.

08527 {
08528         switch ( (anim) )
08529         {
08530         case BOTH_KNOCKDOWN1:
08531         case BOTH_KNOCKDOWN2:
08532         case BOTH_KNOCKDOWN3:
08533         case BOTH_KNOCKDOWN4:
08534         case BOTH_KNOCKDOWN5:
08535                 return qtrue;
08536                 break;
08537         case BOTH_GETUP1:
08538         case BOTH_GETUP2:
08539         case BOTH_GETUP3:
08540         case BOTH_GETUP4:
08541         case BOTH_GETUP5:
08542         case BOTH_FORCE_GETUP_F1:
08543         case BOTH_FORCE_GETUP_F2:
08544         case BOTH_FORCE_GETUP_B1:
08545         case BOTH_FORCE_GETUP_B2:
08546         case BOTH_FORCE_GETUP_B3:
08547         case BOTH_FORCE_GETUP_B4:
08548         case BOTH_FORCE_GETUP_B5:
08549         case BOTH_GETUP_BROLL_B:
08550         case BOTH_GETUP_BROLL_F:
08551         case BOTH_GETUP_BROLL_L:
08552         case BOTH_GETUP_BROLL_R:
08553         case BOTH_GETUP_FROLL_B:
08554         case BOTH_GETUP_FROLL_F:
08555         case BOTH_GETUP_FROLL_L:
08556         case BOTH_GETUP_FROLL_R:
08557                 return qtrue;
08558                 break;
08559         }
08560         return qfalse;
08561 }

qboolean BG_InSlopeAnim int  anim  ) 
 

Definition at line 4743 of file bg_pmove.c.

References LEGS_LEFTUP1, LEGS_LEFTUP2, LEGS_LEFTUP3, LEGS_LEFTUP4, LEGS_LEFTUP5, LEGS_RIGHTUP1, LEGS_RIGHTUP2, LEGS_RIGHTUP3, LEGS_RIGHTUP4, LEGS_RIGHTUP5, LEGS_S1_LUP1, LEGS_S1_LUP2, LEGS_S1_LUP3, LEGS_S1_LUP4, LEGS_S1_LUP5, LEGS_S1_RUP1, LEGS_S1_RUP2, LEGS_S1_RUP3, LEGS_S1_RUP4, LEGS_S1_RUP5, LEGS_S3_LUP1, LEGS_S3_LUP2, LEGS_S3_LUP3, LEGS_S3_LUP4, LEGS_S3_LUP5, LEGS_S3_RUP1, LEGS_S3_RUP2, LEGS_S3_RUP3, LEGS_S3_RUP4, LEGS_S3_RUP5, LEGS_S4_LUP1, LEGS_S4_LUP2, LEGS_S4_LUP3, LEGS_S4_LUP4, LEGS_S4_LUP5, LEGS_S4_RUP1, LEGS_S4_RUP2, LEGS_S4_RUP3, LEGS_S4_RUP4, LEGS_S4_RUP5, LEGS_S5_LUP1, LEGS_S5_LUP2, LEGS_S5_LUP3, LEGS_S5_LUP4, LEGS_S5_LUP5, LEGS_S5_RUP1, LEGS_S5_RUP2, LEGS_S5_RUP3, LEGS_S5_RUP4, LEGS_S5_RUP5, qboolean, qfalse, and qtrue.

Referenced by PM_SetSaberMove(), and PM_WeaponLightsaber().

04744 {
04745         switch ( anim )
04746         {
04747         case LEGS_LEFTUP1:                      //# On a slope with left foot 4 higher than right
04748         case LEGS_LEFTUP2:                      //# On a slope with left foot 8 higher than right
04749         case LEGS_LEFTUP3:                      //# On a slope with left foot 12 higher than right
04750         case LEGS_LEFTUP4:                      //# On a slope with left foot 16 higher than right
04751         case LEGS_LEFTUP5:                      //# On a slope with left foot 20 higher than right
04752         case LEGS_RIGHTUP1:                     //# On a slope with RIGHT foot 4 higher than left
04753         case LEGS_RIGHTUP2:                     //# On a slope with RIGHT foot 8 higher than left
04754         case LEGS_RIGHTUP3:                     //# On a slope with RIGHT foot 12 higher than left
04755         case LEGS_RIGHTUP4:                     //# On a slope with RIGHT foot 16 higher than left
04756         case LEGS_RIGHTUP5:                     //# On a slope with RIGHT foot 20 higher than left
04757         case LEGS_S1_LUP1:
04758         case LEGS_S1_LUP2:
04759         case LEGS_S1_LUP3:
04760         case LEGS_S1_LUP4:
04761         case LEGS_S1_LUP5:
04762         case LEGS_S1_RUP1:
04763         case LEGS_S1_RUP2:
04764         case LEGS_S1_RUP3:
04765         case LEGS_S1_RUP4:
04766         case LEGS_S1_RUP5:
04767         case LEGS_S3_LUP1:
04768         case LEGS_S3_LUP2:
04769         case LEGS_S3_LUP3:
04770         case LEGS_S3_LUP4:
04771         case LEGS_S3_LUP5:
04772         case LEGS_S3_RUP1:
04773         case LEGS_S3_RUP2:
04774         case LEGS_S3_RUP3:
04775         case LEGS_S3_RUP4:
04776         case LEGS_S3_RUP5:
04777         case LEGS_S4_LUP1:
04778         case LEGS_S4_LUP2:
04779         case LEGS_S4_LUP3:
04780         case LEGS_S4_LUP4:
04781         case LEGS_S4_LUP5:
04782         case LEGS_S4_RUP1:
04783         case LEGS_S4_RUP2:
04784         case LEGS_S4_RUP3:
04785         case LEGS_S4_RUP4:
04786         case LEGS_S4_RUP5:
04787         case LEGS_S5_LUP1:
04788         case LEGS_S5_LUP2:
04789         case LEGS_S5_LUP3:
04790         case LEGS_S5_LUP4:
04791         case LEGS_S5_LUP5:
04792         case LEGS_S5_RUP1:
04793         case LEGS_S5_RUP2:
04794         case LEGS_S5_RUP3:
04795         case LEGS_S5_RUP4:
04796         case LEGS_S5_RUP5:
04797                 return qtrue;
04798                 break;
04799         }
04800         return qfalse;
04801 }

saberInfo_t* BG_MySaber int  clientNum,
int  saberNum
 

Referenced by BG_AdjustClientSpeed(), BG_SaberStartTransAnim(), PM_CanDoKata(), PM_CanDoRollStab(), PM_CheckAltKickAttack(), PM_CheckStabDown(), PM_GetSaberStance(), PM_SaberAttackForMovement(), PM_SaberBackflipAttackMove(), PM_SaberFlipOverAttackMove(), PM_SaberJumpAttackMove(), PM_SaberJumpAttackMove2(), PM_SaberLungeAttackMove(), PM_SetSaberMove(), and PM_WeaponLightsaber().

qboolean BG_SaberInTransitionAny int  move  ) 
 

Definition at line 1619 of file bg_panimate.c.

01620 {
01621         if ( PM_SaberInStart( move ) )
01622         {
01623                 return qtrue;
01624         }
01625         else if ( PM_SaberInTransition( move ) )
01626         {
01627                 return qtrue;
01628         }
01629         else if ( PM_SaberInReturn( move ) )
01630         {
01631                 return qtrue;
01632         }
01633         return qfalse;
01634 }

qboolean BG_SabersOff playerState_t ps  ) 
 

Definition at line 201 of file bg_pmove.c.

00202 {
00203         if ( !ps->saberHolstered )
00204         {
00205                 return qfalse;
00206         }
00207         if ( ps->fd.saberAnimLevelBase == SS_DUAL
00208                 || ps->fd.saberAnimLevelBase == SS_STAFF )
00209         {
00210                 if ( ps->saberHolstered < 2 )
00211                 {
00212                         return qfalse;
00213                 }
00214         }
00215         return qtrue;
00216 }

qboolean BG_SuperBreakLoseAnim int  anim  ) 
 

Definition at line 1430 of file bg_panimate.c.

01431 {
01432         switch ( anim )
01433         {
01434         case BOTH_LK_S_DL_S_SB_1_L:     //super break I lost
01435         case BOTH_LK_S_DL_T_SB_1_L:     //super break I lost
01436         case BOTH_LK_S_ST_S_SB_1_L:     //super break I lost
01437         case BOTH_LK_S_ST_T_SB_1_L:     //super break I lost
01438         case BOTH_LK_S_S_S_SB_1_L:      //super break I lost
01439         case BOTH_LK_S_S_T_SB_1_L:      //super break I lost
01440         case BOTH_LK_DL_DL_S_SB_1_L:    //super break I lost
01441         case BOTH_LK_DL_DL_T_SB_1_L:    //super break I lost
01442         case BOTH_LK_DL_ST_S_SB_1_L:    //super break I lost
01443         case BOTH_LK_DL_ST_T_SB_1_L:    //super break I lost
01444         case BOTH_LK_DL_S_S_SB_1_L:     //super break I lost
01445         case BOTH_LK_DL_S_T_SB_1_L:     //super break I lost
01446         case BOTH_LK_ST_DL_S_SB_1_L:    //super break I lost
01447         case BOTH_LK_ST_DL_T_SB_1_L:    //super break I lost
01448         case BOTH_LK_ST_ST_S_SB_1_L:    //super break I lost
01449         case BOTH_LK_ST_ST_T_SB_1_L:    //super break I lost
01450         case BOTH_LK_ST_S_S_SB_1_L:     //super break I lost
01451         case BOTH_LK_ST_S_T_SB_1_L:     //super break I lost
01452                 return qtrue;
01453                 break;
01454         }
01455         return qfalse;
01456 }

qboolean BG_SuperBreakWinAnim int  anim  ) 
 

Definition at line 1458 of file bg_panimate.c.

01459 {
01460         switch ( anim )
01461         {
01462         case BOTH_LK_S_DL_S_SB_1_W:     //super break I won
01463         case BOTH_LK_S_DL_T_SB_1_W:     //super break I won
01464         case BOTH_LK_S_ST_S_SB_1_W:     //super break I won
01465         case BOTH_LK_S_ST_T_SB_1_W:     //super break I won
01466         case BOTH_LK_S_S_S_SB_1_W:      //super break I won
01467         case BOTH_LK_S_S_T_SB_1_W:      //super break I won
01468         case BOTH_LK_DL_DL_S_SB_1_W:    //super break I won
01469         case BOTH_LK_DL_DL_T_SB_1_W:    //super break I won
01470         case BOTH_LK_DL_ST_S_SB_1_W:    //super break I won
01471         case BOTH_LK_DL_ST_T_SB_1_W:    //super break I won
01472         case BOTH_LK_DL_S_S_SB_1_W:     //super break I won
01473         case BOTH_LK_DL_S_T_SB_1_W:     //super break I won
01474         case BOTH_LK_ST_DL_S_SB_1_W:    //super break I won
01475         case BOTH_LK_ST_DL_T_SB_1_W:    //super break I won
01476         case BOTH_LK_ST_ST_S_SB_1_W:    //super break I won
01477         case BOTH_LK_ST_ST_T_SB_1_W:    //super break I won
01478         case BOTH_LK_ST_S_S_SB_1_W:     //super break I won
01479         case BOTH_LK_ST_S_T_SB_1_W:     //super break I won
01480                 return qtrue;
01481                 break;
01482         }
01483         return qfalse;
01484 }

saberMoveName_t PM_AttackMoveForQuad int  quad  ) 
 

Definition at line 392 of file bg_saber.c.

References LS_A_BL2TR, LS_A_BR2TL, LS_A_L2R, LS_A_R2L, LS_A_T2B, LS_A_TL2BR, LS_A_TR2BL, LS_NONE, Q_B, Q_BL, Q_BR, Q_L, Q_R, Q_T, Q_TL, Q_TR, and saberMoveName_t.

00393 {
00394         switch ( quad )
00395         {
00396         case Q_B:
00397         case Q_BR:
00398                 return LS_A_BR2TL;
00399                 break;
00400         case Q_R:
00401                 return LS_A_R2L;
00402                 break;
00403         case Q_TR:
00404                 return LS_A_TR2BL;
00405                 break;
00406         case Q_T:
00407                 return LS_A_T2B;
00408                 break;
00409         case Q_TL:
00410                 return LS_A_TL2BR;
00411                 break;
00412         case Q_L:
00413                 return LS_A_L2R;
00414                 break;
00415         case Q_BL:
00416                 return LS_A_BL2TR;
00417                 break;
00418         }
00419         return LS_NONE;
00420 }

int PM_BrokenParryForParry int  move  ) 
 

Definition at line 1594 of file bg_saber.c.

References LS_H1_B_, LS_H1_BL, LS_H1_BR, LS_H1_T_, LS_H1_TL, LS_H1_TR, LS_NONE, LS_PARRY_LL, LS_PARRY_LR, LS_PARRY_UL, LS_PARRY_UP, LS_PARRY_UR, and LS_READY.

Referenced by PM_WeaponLightsaber().

01595 {
01596         switch ( move )
01597         {
01598         case LS_PARRY_UP:
01599                 return LS_H1_T_;
01600                 break;
01601         case LS_PARRY_UR:
01602                 return LS_H1_TR;
01603                 break;
01604         case LS_PARRY_UL:
01605                 return LS_H1_TL;
01606                 break;
01607         case LS_PARRY_LR:
01608                 return LS_H1_BL;
01609                 break;
01610         case LS_PARRY_LL:
01611                 return LS_H1_BR;
01612                 break;
01613         case LS_READY:
01614                 return LS_H1_B_;
01615                 break;
01616         }
01617         return LS_NONE;
01618 }

qboolean PM_CanBackstab void   ) 
 

Definition at line 1622 of file bg_saber.c.

References AngleVectors(), BACK_STAB_DISTANCE, bgEntity_t, playerState_s::clientNum, trace_t::entityNum, ENTITYNUM_NONE, ET_NPC, ET_PLAYER, entityState_s::eType, trace_t::fraction, MASK_PLAYERSOLID, playerState_s::origin, PITCH, pm, PM_BGEntForNum(), pmove_t::ps, qboolean, qfalse, qtrue, bgEntity_s::s, pmove_t::trace, vec3_t, VectorCopy, and playerState_s::viewangles.

Referenced by PM_SaberAttackForMovement().

01623 {
01624         trace_t tr;
01625         vec3_t flatAng;
01626         vec3_t fwd, back;
01627         vec3_t trmins = {-15, -15, -8};
01628         vec3_t trmaxs = {15, 15, 8};
01629 
01630         VectorCopy(pm->ps->viewangles, flatAng);
01631         flatAng[PITCH] = 0;
01632 
01633         AngleVectors(flatAng, fwd, 0, 0);
01634 
01635         back[0] = pm->ps->origin[0] - fwd[0]*BACK_STAB_DISTANCE;
01636         back[1] = pm->ps->origin[1] - fwd[1]*BACK_STAB_DISTANCE;
01637         back[2] = pm->ps->origin[2] - fwd[2]*BACK_STAB_DISTANCE;
01638 
01639         pm->trace(&tr, pm->ps->origin, trmins, trmaxs, back, pm->ps->clientNum, MASK_PLAYERSOLID);
01640 
01641         if (tr.fraction != 1.0 && tr.entityNum >= 0 && tr.entityNum < ENTITYNUM_NONE)
01642         {
01643                 bgEntity_t *bgEnt = PM_BGEntForNum(tr.entityNum);
01644 
01645                 if (bgEnt && (bgEnt->s.eType == ET_PLAYER || bgEnt->s.eType == ET_NPC))
01646                 {
01647                         return qtrue;
01648                 }
01649         }
01650 
01651         return qfalse;
01652 }

qboolean PM_CanDoKata void   ) 
 

Definition at line 2706 of file bg_saber.c.

References BG_EnoughForcePowerForMove(), BG_InKataAnim(), BG_MySaber(), BG_SaberInKata(), BUTTON_ALT_ATTACK, BUTTON_ATTACK, usercmd_s::buttons, playerState_s::clientNum, pmove_t::cmd, ENTITYNUM_NONE, usercmd_s::forwardmove, playerState_s::groundEntityNum, saberInfo_t::kataMove, playerState_s::legsAnim, LS_NONE, pm, PM_InSecondaryStyle(), PM_SaberMoveOkayForKata(), pmove_t::ps, qboolean, qfalse, qtrue, usercmd_s::rightmove, SABER_ALT_ATTACK_POWER, playerState_s::saberInFlight, playerState_s::saberMove, playerState_s::torsoAnim, and usercmd_s::upmove.

Referenced by PM_WeaponLightsaber().

02707 {
02708         if ( PM_InSecondaryStyle() )
02709         {
02710                 return qfalse;
02711         }
02712 
02713         if ( !pm->ps->saberInFlight//not throwing saber
02714                 && PM_SaberMoveOkayForKata()
02715                 && !BG_SaberInKata(pm->ps->saberMove)
02716                 && !BG_InKataAnim(pm->ps->legsAnim)
02717                 && !BG_InKataAnim(pm->ps->torsoAnim)
02718                 /*
02719                 && pm->ps->saberAnimLevel >= SS_FAST//fast, med or strong style
02720                 && pm->ps->saberAnimLevel <= SS_STRONG//FIXME: Tavion, too?
02721                 */
02722                 && pm->ps->groundEntityNum != ENTITYNUM_NONE//not in the air
02723                 && (pm->cmd.buttons&BUTTON_ATTACK)//pressing attack
02724                 && (pm->cmd.buttons&BUTTON_ALT_ATTACK)//pressing alt attack
02725                 && !pm->cmd.forwardmove//not moving f/b
02726                 && !pm->cmd.rightmove//not moving r/l
02727                 && pm->cmd.upmove <= 0//not jumping...?
02728                 && BG_EnoughForcePowerForMove(SABER_ALT_ATTACK_POWER) )// have enough power
02729         {//FIXME: check rage, etc...
02730                 saberInfo_t *saber = BG_MySaber( pm->ps->clientNum, 0 );
02731                 if ( saber
02732                         && saber->kataMove == LS_NONE )
02733                 {//kata move has been overridden in a way that should stop you from doing it at all
02734                         return qfalse;
02735                 }
02736                 saber = BG_MySaber( pm->ps->clientNum, 1 );
02737                 if ( saber
02738                         && saber->kataMove == LS_NONE )
02739                 {//kata move has been overridden in a way that should stop you from doing it at all
02740                         return qfalse;
02741                 }
02742                 return qtrue;
02743         }
02744         return qfalse;
02745 }

qboolean PM_CanDoRollStab void   ) 
 

Definition at line 2799 of file bg_saber.c.

References BG_MySaber(), playerState_s::clientNum, pm, pmove_t::ps, qboolean, qfalse, qtrue, saberInfo_t::saberFlags, SFL_NO_ROLL_STAB, playerState_s::weapon, and WP_SABER.

Referenced by PM_WeaponLightsaber().

02800 {
02801         if ( pm->ps->weapon == WP_SABER )
02802         {
02803                 saberInfo_t *saber = BG_MySaber( pm->ps->clientNum, 0 );
02804                 if ( saber
02805                         && (saber->saberFlags&SFL_NO_ROLL_STAB) )
02806                 {
02807                         return qfalse;
02808                 }
02809                 saber = BG_MySaber( pm->ps->clientNum, 1 );
02810                 if ( saber
02811                         && (saber->saberFlags&SFL_NO_ROLL_STAB) )
02812                 {
02813                         return qfalse;
02814                 }
02815         }
02816         return qtrue;
02817 }

qboolean PM_CheckAltKickAttack void   ) 
 

Definition at line 2747 of file bg_saber.c.

References BG_FlippingAnim(), BG_MySaber(), BUTTON_ALT_ATTACK, usercmd_s::buttons, playerState_s::clientNum, pmove_t::cmd, playerState_s::fd, playerState_s::legsAnim, playerState_s::legsTimer, pm, pmove_t::ps, qboolean, qfalse, qtrue, forcedata_s::saberAnimLevel, saberInfo_t::saberFlags, playerState_s::saberHolstered, SFL_NO_KICKS, SS_STAFF, playerState_s::weapon, and WP_SABER.

Referenced by PM_WeaponLightsaber().

02748 {
02749         if ( pm->ps->weapon == WP_SABER )
02750         {
02751                 saberInfo_t *saber = BG_MySaber( pm->ps->clientNum, 0 );
02752                 if ( saber
02753                         && (saber->saberFlags&SFL_NO_KICKS) )
02754                 {
02755                         return qfalse;
02756                 }
02757                 saber = BG_MySaber( pm->ps->clientNum, 1 );
02758                 if ( saber
02759                         && (saber->saberFlags&SFL_NO_KICKS) )
02760                 {
02761                         return qfalse;
02762                 }
02763         }
02764         if ( (pm->cmd.buttons&BUTTON_ALT_ATTACK) 
02765                 //&& (!(pm->ps->pm_flags&PMF_ALT_ATTACK_HELD)||PM_SaberInReturn(pm->ps->saberMove))
02766                 && (!BG_FlippingAnim(pm->ps->legsAnim)||pm->ps->legsTimer<=250)
02767                 && (pm->ps->fd.saberAnimLevel == SS_STAFF/*||!pm->ps->saber[0].throwable*/) && !pm->ps->saberHolstered )
02768         {
02769                 return qtrue;
02770         }
02771         return qfalse;
02772 }

saberMoveName_t PM_CheckPullAttack void   ) 
 

Definition at line 2114 of file bg_saber.c.

References BG_EnoughForcePowerForMove(), BG_ForcePowerDrain(), BUTTON_ATTACK, usercmd_s::buttons, pmove_t::cmd, playerState_s::fd, forcedata_s::forcePowersActive, FP_GRIP, LS_NONE, LS_PULL_ATTACK_STAB, LS_PULL_ATTACK_SWING, LS_READY, pm, PM_SaberInReflect(), PM_SaberInReturn(), playerState_s::powerups, pmove_t::ps, PW_DISINT_4, PW_PULL, qboolean, qtrue, SABER_ALT_ATTACK_POWER_FB, forcedata_s::saberAnimLevel, playerState_s::saberMove, saberMoveName_t, usercmd_s::serverTime, SS_FAST, and SS_STRONG.

Referenced by PM_WeaponLightsaber().

02115 {
02116 #if 0 //disabling these for MP, they aren't useful
02117         if (!(pm->cmd.buttons & BUTTON_ATTACK))
02118         {
02119                 return LS_NONE;
02120         }
02121 
02122         if ( (pm->ps->saberMove == LS_READY||PM_SaberInReturn(pm->ps->saberMove)||PM_SaberInReflect(pm->ps->saberMove))//ready
02123                 //&& (pm->ps->clientNum < MAX_CLIENTS||PM_ControlledByPlayer())//PLAYER ONLY
02124                 && pm->ps->fd.saberAnimLevel >= SS_FAST//single saber styles - FIXME: Tavion?
02125                 && pm->ps->fd.saberAnimLevel <= SS_STRONG//single saber styles - FIXME: Tavion?
02126                 //&& G_TryingPullAttack( pm->gent, &pm->cmd, qfalse )
02127                 //&& pm->ps->fd.forcePowerLevel[FP_PULL] 
02128                 //rwwFIXMEFIXME: rick has the damn msg.cpp file checked out exclusively so I can't update the bloody psf to send this for prediction
02129                 && pm->ps->powerups[PW_DISINT_4] > pm->cmd.serverTime
02130                 && !(pm->ps->fd.forcePowersActive & (1<<FP_GRIP))
02131                 && pm->ps->powerups[PW_PULL] > pm->cmd.serverTime
02132                 //&& pm->cmd.forwardmove<0//pulling back
02133                 && (pm->cmd.buttons&BUTTON_ATTACK)//attacking
02134                 && BG_EnoughForcePowerForMove( SABER_ALT_ATTACK_POWER_FB ) )//pm->ps->forcePower >= SABER_ALT_ATTACK_POWER_FB//have enough power
02135         {//FIXME: some NPC logic to do this?
02136                 qboolean doMove = qtrue;
02137 //              if ( g_saberNewControlScheme->integer
02138 //                      || g_crosshairEntNum < ENTITYNUM_WORLD )//in old control scheme, there has to be someone there
02139                 {       
02140                         saberMoveName_t pullAttackMove = LS_NONE;
02141                         if ( pm->ps->fd.saberAnimLevel == SS_FAST )
02142                         {
02143                                 pullAttackMove = LS_PULL_ATTACK_STAB;
02144                         }
02145                         else
02146                         {
02147                                 pullAttackMove = LS_PULL_ATTACK_SWING;
02148                         }
02149 
02150                         /*
02151                         if ( g_crosshairEntNum < ENTITYNUM_WORLD 
02152                                 && pm->gent && pm->gent->client )
02153                         {
02154                                 gentity_t *targEnt = &g_entities[g_crosshairEntNum];
02155                                 if ( targEnt->client
02156                                         && targEnt->health > 0
02157                                         //FIXME: check other things like in knockdown, saberlock, uninterruptable anims, etc.
02158                                         && !PM_InOnGroundAnim( &targEnt->client->ps )
02159                                         && !PM_LockedAnim( targEnt->client->ps.legsAnim ) 
02160                                         && !PM_SuperBreakLoseAnim( targEnt->client->ps.legsAnim )
02161                                         && !PM_SuperBreakWinAnim( targEnt->client->ps.legsAnim )
02162                                         && targEnt->client->ps.saberLockTime <= 0
02163                                         && WP_ForceThrowable( targEnt, targEnt, pm->gent, qtrue, 1.0f, 0.0f, NULL ) )
02164                                 {
02165                                         if ( !g_saberNewControlScheme->integer )
02166                                         {//in old control scheme, make sure they're close or far enough away for the move we'll be doing
02167                                                 float targDist = Distance( targEnt->currentOrigin, pm->ps->origin );
02168                                                 if ( pullAttackMove == LS_PULL_ATTACK_STAB )
02169                                                 {//must be closer than 512
02170                                                         if ( targDist > 384.0f )
02171                                                         {
02172                                                                 return LS_NONE;
02173                                                         }
02174                                                 }
02175                                                 else//if ( pullAttackMove == LS_PULL_ATTACK_SWING )
02176                                                 {//must be farther than 256
02177                                                         if ( targDist > 512.0f )
02178                                                         {
02179                                                                 return LS_NONE;
02180                                                         }
02181                                                         if ( targDist < 192.0f )
02182                                                         {
02183                                                                 return LS_NONE;
02184                                                         }
02185                                                 }
02186                                         }
02187 
02188                                         vec3_t targAngles = {0,targEnt->client->ps.viewangles[YAW],0};
02189                                         if ( InFront( pm->ps->origin, targEnt->currentOrigin, targAngles ) )
02190                                         {
02191                                                 NPC_SetAnim( targEnt, SETANIM_BOTH, BOTH_PULLED_INAIR_F, SETANIM_FLAG_OVERRIDE, SETANIM_FLAG_HOLD );
02192                                         }
02193                                         else
02194                                         {
02195                                                 NPC_SetAnim( targEnt, SETANIM_BOTH, BOTH_PULLED_INAIR_B, SETANIM_FLAG_OVERRIDE, SETANIM_FLAG_HOLD );
02196                                         }
02197                                         //hold the anim until I'm with done pull anim
02198                                         targEnt->client->ps.legsAnimTimer = targEnt->client->ps.torsoAnimTimer = PM_AnimLength( pm->gent->client->clientInfo.animFileIndex, (animNumber_t)saberMoveData[pullAttackMove].animToUse );
02199                                         //set pullAttackTime
02200                                         pm->gent->client->ps.pullAttackTime = targEnt->client->ps.pullAttackTime = level.time+targEnt->client->ps.legsAnimTimer;
02201                                         //make us know about each other
02202                                         pm->gent->client->ps.pullAttackEntNum = g_crosshairEntNum;
02203                                         targEnt->client->ps.pullAttackEntNum = pm->ps->clientNum;
02204                                         //do effect and sound on me
02205                                         pm->ps->powerups[PW_FORCE_PUSH] = level.time + 1000;
02206                                         if ( pm->gent )
02207                                         {
02208                                                 G_Sound( pm->gent, G_SoundIndex( "sound/weapons/force/pull.wav" ) );
02209                                         }
02210                                         doMove = qtrue;
02211                                 }
02212                         }
02213                         */
02214                         if ( doMove )
02215                         {
02216                                 BG_ForcePowerDrain(pm->ps, FP_GRIP, SABER_ALT_ATTACK_POWER_FB );
02217                                 return pullAttackMove;
02218                         }
02219                 }
02220         }
02221 #endif
02222         return LS_NONE;
02223 }

saberMoveName_t PM_CheckStabDown void   ) 
 

Definition at line 584 of file bg_saber.c.

References AngleVectors(), BG_InKnockDown(), BG_MySaber(), bgEntity_t, playerState_s::clientNum, pmove_t::cmd, trace_t::entityNum, ENTITYNUM_NONE, ENTITYNUM_WORLD, ET_NPC, ET_PLAYER, entityState_s::eType, playerState_s::fd, playerState_s::groundEntityNum, entityState_s::legsAnim, LS_NONE, LS_STABDOWN, LS_STABDOWN_DUAL, LS_STABDOWN_STAFF, MASK_PLAYERSOLID, MAX_CLIENTS, NULL, playerState_s::origin, pm, PM_BGEntForNum(), pmove_t::ps, bgEntity_s::s, forcedata_s::saberAnimLevel, saberInfo_t::saberFlags, saberMoveName_t, SFL_NO_STABDOWN, SS_DUAL, SS_STAFF, pmove_t::trace, usercmd_s::upmove, vec3_t, VectorMA, VectorSet, playerState_s::velocity, playerState_s::viewangles, and YAW.

Referenced by PM_SaberAttackForMovement().

00585 {
00586         vec3_t faceFwd, facingAngles;
00587         vec3_t fwd;
00588         bgEntity_t *ent = NULL;
00589         trace_t tr;
00590         //yeah, vm's may complain, but.. who cares!
00591         vec3_t trmins = {-15, -15, -15};
00592         vec3_t trmaxs = {15, 15, 15};
00593 
00594         saberInfo_t *saber1 = BG_MySaber( pm->ps->clientNum, 0 );
00595         saberInfo_t *saber2 = BG_MySaber( pm->ps->clientNum, 1 );
00596         if ( saber1
00597                 && (saber1->saberFlags&SFL_NO_STABDOWN) )
00598         {
00599                 return LS_NONE;
00600         }
00601         if ( saber2
00602                 && (saber2->saberFlags&SFL_NO_STABDOWN) )
00603         {
00604                 return LS_NONE;
00605         }
00606 
00607         if ( pm->ps->groundEntityNum == ENTITYNUM_NONE )
00608         {//sorry must be on ground!
00609                 return LS_NONE;
00610         }
00611         if ( pm->ps->clientNum < MAX_CLIENTS )
00612         {//player
00613                 pm->ps->velocity[2] = 0;
00614                 pm->cmd.upmove = 0;
00615         }
00616 
00617         VectorSet(facingAngles, 0, pm->ps->viewangles[YAW], 0);
00618         AngleVectors( facingAngles, faceFwd, NULL, NULL );
00619 
00620         //FIXME: need to only move forward until we bump into our target...?
00621         VectorMA(pm->ps->origin, 164.0f, faceFwd, fwd);
00622 
00623         pm->trace(&tr, pm->ps->origin, trmins, trmaxs, fwd, pm->ps->clientNum, MASK_PLAYERSOLID);
00624 
00625         if (tr.entityNum < ENTITYNUM_WORLD)
00626         {
00627                 ent = PM_BGEntForNum(tr.entityNum);
00628         }
00629 
00630         if ( ent &&
00631                 (ent->s.eType == ET_PLAYER || ent->s.eType == ET_NPC) &&
00632                 BG_InKnockDown( ent->s.legsAnim ) )
00633         {//guy is on the ground below me, do a top-down attack
00634                 if ( pm->ps->fd.saberAnimLevel == SS_DUAL )
00635                 {
00636                         return LS_STABDOWN_DUAL;
00637                 }
00638                 else if ( pm->ps->fd.saberAnimLevel == SS_STAFF )
00639                 {
00640                         return LS_STABDOWN_STAFF;
00641                 }
00642                 else
00643                 {
00644                         return LS_STABDOWN;
00645                 }
00646         }
00647         return LS_NONE;
00648 }

float PM_GroundDistance void   ) 
 

Definition at line 1992 of file bg_saber.c.

References playerState_s::clientNum, trace_t::endpos, MASK_SOLID, pmove_t::maxs, pmove_t::mins, playerState_s::origin, pm, pmove_t::ps, pmove_t::trace, vec3_t, VectorCopy, and VectorSubtract.

Referenced by PM_SaberAttackForMovement(), PM_WeaponLightsaber(), and PmoveSingle().

01993 {
01994         trace_t tr;
01995         vec3_t down;
01996 
01997         VectorCopy(pm->ps->origin, down);
01998 
01999         down[2] -= 4096;
02000 
02001         pm->trace(&tr, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, MASK_SOLID);
02002 
02003         VectorSubtract(pm->ps->origin, tr.endpos, down);
02004 
02005         return VectorLength(down);
02006 }

qboolean PM_InSecondaryStyle void   ) 
 

Definition at line 2225 of file bg_saber.c.

References playerState_s::fd, pm, pmove_t::ps, qboolean, qfalse, qtrue, forcedata_s::saberAnimLevel, forcedata_s::saberAnimLevelBase, SS_DUAL, and SS_STAFF.

Referenced by PM_CanDoKata(), and PM_SaberAttackForMovement().

02226 {
02227         if ( pm->ps->fd.saberAnimLevelBase == SS_STAFF 
02228                 || pm->ps->fd.saberAnimLevelBase == SS_DUAL )
02229         {
02230                 if ( pm->ps->fd.saberAnimLevel != pm->ps->fd.saberAnimLevelBase )
02231                 {
02232                         return qtrue;
02233                 }
02234         }
02235         return qfalse;
02236 }

int PM_irand_timesync int  val1,
int  val2
 

Definition at line 10 of file bg_saber.c.

References pmove_t::cmd, pm, Q_random(), and usercmd_s::serverTime.

Referenced by PM_SaberKataDone(), PM_SaberLockBreak(), PM_SaberLocked(), PM_SetSaberMove(), PM_VehicleWeaponAnimate(), and PM_WeaponLightsaber().

00011 {
00012         int i;
00013 
00014         i = (val1-1) + (Q_random( &pm->cmd.serverTime )*(val2 - val1)) + 1;
00015         if (i < val1)
00016         {
00017                 i = val1;
00018         }
00019         if (i > val2)
00020         {
00021                 i = val2;
00022         }
00023 
00024         return i;
00025 }

int PM_KickMoveForConditions void   ) 
 

Definition at line 2617 of file bg_saber.c.

References pmove_t::cmd, DIR_BACK, DIR_FRONT, DIR_LEFT, DIR_RIGHT, usercmd_s::forwardmove, LS_KICK_B, LS_KICK_F, LS_KICK_L, LS_KICK_R, LS_KICK_RL, LS_KICK_S, pm, usercmd_s::rightmove, and usercmd_s::upmove.

Referenced by PM_WeaponLightsaber().

02618 {
02619         int kickMove = -1;
02620 
02621         //FIXME: only if FP_SABER_OFFENSE >= 3
02622         if ( pm->cmd.rightmove )
02623         {//kick to side
02624                 if ( pm->cmd.rightmove > 0 )
02625                 {//kick right
02626                         kickMove = LS_KICK_R;
02627                 }
02628                 else
02629                 {//kick left
02630                         kickMove = LS_KICK_L;
02631                 }
02632                 pm->cmd.rightmove = 0;
02633         }
02634         else if ( pm->cmd.forwardmove )
02635         {//kick front/back
02636                 if ( pm->cmd.forwardmove > 0 )
02637                 {//kick fwd
02638                         /*
02639                         if (pm->ps->groundEntityNum != ENTITYNUM_NONE &&
02640                                 PM_CheckEnemyPresence( DIR_FRONT, 64.0f ))
02641                         {
02642                                 kickMove = LS_HILT_BASH;
02643                         }
02644                         else
02645                         */
02646                         {
02647                                 kickMove = LS_KICK_F;
02648                         }
02649                 }
02650                 else
02651                 {//kick back
02652                         kickMove = LS_KICK_B;
02653                 }
02654                 pm->cmd.forwardmove = 0;
02655         }
02656         else
02657         {
02658                 //if (pm->cmd.buttons & BUTTON_ATTACK)
02659                 //if (pm->ps->pm_flags & PMF_JUMP_HELD)
02660                 if (0)
02661                 { //ok, let's try some fancy kicks
02662                         //qboolean is actually of type int anyway, but just for safeness.
02663                         int front = (int)PM_CheckEnemyPresence( DIR_FRONT, 100.0f );
02664                         int back = (int)PM_CheckEnemyPresence( DIR_BACK, 100.0f );
02665                         int right = (int)PM_CheckEnemyPresence( DIR_RIGHT, 100.0f );
02666                         int left = (int)PM_CheckEnemyPresence( DIR_LEFT, 100.0f );
02667                         int numEnemy = front+back+right+left;
02668 
02669                         if (numEnemy >= 3 ||
02670                                 ((!right || !left) && numEnemy >= 2))
02671                         { //> 2 enemies near, or, >= 2 enemies near and they are not to the right and left.
02672                 kickMove = LS_KICK_S;
02673                         }
02674                         else if (right && left)
02675                         { //enemies on both sides
02676                                 kickMove = LS_KICK_RL;
02677                         }
02678                         else
02679                         { //oh well, just do a forward kick
02680                                 kickMove = LS_KICK_F;
02681                         }
02682 
02683                         pm->cmd.upmove = 0;
02684                 }
02685         }
02686 
02687         return kickMove;
02688 }

qboolean PM_RunningAnim int  anim  ) 
 

Definition at line 4601 of file bg_pmove.c.

04602 {
04603         switch ( (anim) )
04604         {
04605         case BOTH_RUN1:                 
04606         case BOTH_RUN2:                 
04607         case BOTH_RUN_STAFF:
04608         case BOTH_RUN_DUAL:
04609         case BOTH_RUNBACK1:                     
04610         case BOTH_RUNBACK2:                     
04611         case BOTH_RUNBACK_STAFF:                        
04612         case BOTH_RUNBACK_DUAL:
04613         case BOTH_RUN1START:                    //# Start into full run1
04614         case BOTH_RUN1STOP:                     //# Stop from full run1
04615         case BOTH_RUNSTRAFE_LEFT1:      //# Sidestep left: should loop
04616         case BOTH_RUNSTRAFE_RIGHT1:     //# Sidestep right: should loop
04617                 return qtrue;
04618                 break;
04619         }
04620         return qfalse;
04621 }

int PM_SaberAnimTransitionAnim int  curmove,
int  newmove
 

Definition at line 424 of file bg_saber.c.

References saberMoveData_t::endQuad, LS_A_BL2TR, LS_A_BR2TL, LS_A_L2R, LS_A_R2L, LS_A_T2B, LS_A_TL2BR, LS_A_TR2BL, LS_D1__L, LS_D1__R, LS_D1_B_, LS_D1_BL, LS_D1_BR, LS_D1_T_, LS_D1_TL, LS_D1_TR, LS_H1_BL, LS_H1_BR, LS_H1_T_, LS_H1_TL, LS_H1_TR, LS_K1_BL, LS_K1_BR, LS_K1_T_, LS_K1_TL, LS_K1_TR, LS_NONE, LS_PARRY_LL, LS_PARRY_LR, LS_PARRY_UL, LS_PARRY_UP, LS_PARRY_UR, LS_R_BL2TR, LS_R_BR2TL, LS_R_L2R, LS_R_R2L, LS_R_T2B, LS_R_TL2BR, LS_R_TR2BL, LS_READY, LS_REFLECT_LL, LS_REFLECT_LR, LS_REFLECT_UL, LS_REFLECT_UP, LS_REFLECT_UR, LS_S_TL2BR, LS_V1__L, LS_V1__R, LS_V1_B_, LS_V1_BL, LS_V1_BR, LS_V1_T_, LS_V1_TL, LS_V1_TR, PM_SaberKataDone(), saberMoveData, saberMoveData_t::startQuad, and transitionMove.

Referenced by PM_WeaponLightsaber().

00425 {
00426         int retmove = newmove;
00427         if ( curmove == LS_READY )
00428         {//just standing there
00429                 switch ( newmove )
00430                 {
00431                 case LS_A_TL2BR:
00432                 case LS_A_L2R:
00433                 case LS_A_BL2TR:
00434                 case LS_A_BR2TL:
00435                 case LS_A_R2L:
00436                 case LS_A_TR2BL:
00437                 case LS_A_T2B:
00438                         //transition is the start
00439                         retmove = LS_S_TL2BR + (newmove-LS_A_TL2BR);
00440                         break;
00441                 }
00442         }
00443         else
00444         {
00445                 switch ( newmove )
00446                 {
00447                 //transitioning to ready pose
00448                 case LS_READY:
00449                         switch ( curmove )
00450                         {
00451                         //transitioning from an attack
00452                         case LS_A_TL2BR:
00453                         case LS_A_L2R:
00454                         case LS_A_BL2TR:
00455                         case LS_A_BR2TL:
00456                         case LS_A_R2L:
00457                         case LS_A_TR2BL:
00458                         case LS_A_T2B:
00459                                 //transition is the return
00460                                 retmove = LS_R_TL2BR + (newmove-LS_A_TL2BR);
00461                                 break;
00462                         }
00463                         break;
00464                 //transitioning to an attack
00465                 case LS_A_TL2BR:
00466                 case LS_A_L2R:
00467                 case LS_A_BL2TR:
00468                 case LS_A_BR2TL:
00469                 case LS_A_R2L:
00470                 case LS_A_TR2BL:
00471                 case LS_A_T2B:
00472                         if ( newmove == curmove )
00473                         {
00474                                 //going into an attack
00475                                 if ( PM_SaberKataDone( curmove, newmove ) )
00476                                 {//done with this kata, must return to ready before attack again
00477                                         retmove = LS_R_TL2BR + (newmove-LS_A_TL2BR);
00478                                 }
00479                                 else
00480                                 {//okay to chain to another attack
00481                                         retmove = transitionMove[saberMoveData[curmove].endQuad][saberMoveData[newmove].startQuad];
00482                                 }
00483                         }
00484                         else if ( saberMoveData[curmove].endQuad == saberMoveData[newmove].startQuad )
00485                         {//new move starts from same quadrant
00486                                 retmove = newmove;
00487                         }
00488                         else
00489                         {
00490                                 switch ( curmove )
00491                                 {
00492                                 //transitioning from an attack
00493                                 case LS_A_TL2BR:
00494                                 case LS_A_L2R:
00495                                 case LS_A_BL2TR:
00496                                 case LS_A_BR2TL:
00497                                 case LS_A_R2L:
00498                                 case LS_A_TR2BL:
00499                                 case LS_A_T2B:
00500                                 case LS_D1_BR:
00501                                 case LS_D1__R:
00502                                 case LS_D1_TR:
00503                                 case LS_D1_T_:
00504                                 case LS_D1_TL:
00505                                 case LS_D1__L:
00506                                 case LS_D1_BL:
00507                                 case LS_D1_B_:
00508                                         retmove = transitionMove[saberMoveData[curmove].endQuad][saberMoveData[newmove].startQuad];
00509                                         break;
00510                                 //transitioning from a return
00511                                 case LS_R_TL2BR:
00512                                 case LS_R_L2R:
00513                                 case LS_R_BL2TR:
00514                                 case LS_R_BR2TL:
00515                                 case LS_R_R2L:
00516                                 case LS_R_TR2BL:
00517                                 case LS_R_T2B:
00518                                 //transitioning from a bounce
00519                                 /*
00520                                 case LS_BOUNCE_UL2LL:
00521                                 case LS_BOUNCE_LL2UL:
00522                                 case LS_BOUNCE_L2LL:
00523                                 case LS_BOUNCE_L2UL:
00524                                 case LS_BOUNCE_UR2LR:
00525                                 case LS_BOUNCE_LR2UR:
00526                                 case LS_BOUNCE_R2LR:
00527                                 case LS_BOUNCE_R2UR:
00528                                 case LS_BOUNCE_TOP:
00529                                 case LS_OVER_UR2UL:
00530                                 case LS_OVER_UL2UR:
00531                                 case LS_BOUNCE_UR:
00532                                 case LS_BOUNCE_UL:
00533                                 case LS_BOUNCE_LR:
00534                                 case LS_BOUNCE_LL:
00535                                 */
00536                                 //transitioning from a parry/reflection/knockaway/broken parry
00537                                 case LS_PARRY_UP:
00538                                 case LS_PARRY_UR:
00539                                 case LS_PARRY_UL:
00540                                 case LS_PARRY_LR:
00541                                 case LS_PARRY_LL:
00542                                 case LS_REFLECT_UP:
00543                                 case LS_REFLECT_UR:
00544                                 case LS_REFLECT_UL:
00545                                 case LS_REFLECT_LR:
00546                                 case LS_REFLECT_LL:
00547                                 case LS_K1_T_:
00548                                 case LS_K1_TR:
00549                                 case LS_K1_TL:
00550                                 case LS_K1_BR:
00551                                 case LS_K1_BL:
00552                                 case LS_V1_BR:
00553                                 case LS_V1__R:
00554                                 case LS_V1_TR:
00555                                 case LS_V1_T_:
00556                                 case LS_V1_TL:
00557                                 case LS_V1__L:
00558                                 case LS_V1_BL:
00559                                 case LS_V1_B_:
00560                                 case LS_H1_T_:
00561                                 case LS_H1_TR:
00562                                 case LS_H1_TL:
00563                                 case LS_H1_BR:
00564                                 case LS_H1_BL:
00565                                         retmove = transitionMove[saberMoveData[curmove].endQuad][saberMoveData[newmove].startQuad];
00566                                         break;
00567                                 //NB: transitioning from transitions is fine
00568                                 }
00569                         }
00570                         break;
00571                 //transitioning to any other anim is not supported
00572                 }
00573         }
00574 
00575         if ( retmove == LS_NONE )
00576         {
00577                 return newmove;
00578         }
00579 
00580         return retmove;
00581 }

int PM_SaberAttackChainAngle int  move1,
int  move2
 

Definition at line 783 of file bg_saber.c.

References saberMoveData_t::endQuad, saberMoveData, saberMoveTransitionAngle, and saberMoveData_t::startQuad.

Referenced by PM_SaberKataDone().

00784 {
00785         if ( move1 == -1 || move2 == -1 )
00786         {
00787                 return -1;
00788         }
00789         return saberMoveTransitionAngle[saberMoveData[move1].endQuad][saberMoveData[move2].startQuad];
00790 }

saberMoveName_t PM_SaberAttackForMovement saberMoveName_t  curmove  ) 
 

Definition at line 2238 of file bg_saber.c.

References AngleVectors(), BG_EnoughForcePowerForMove(), BG_ForcePowerDrain(), BG_InSpecialJump(), BG_MySaber(), BG_SaberInAttack(), BG_SaberInSpecialAttack(), BG_SaberInTransitionAny(), BUTTON_ATTACK, usercmd_s::buttons, saberMoveData_t::chain_attack, saberMoveData_t::chain_idle, playerState_s::clientNum, pmove_t::cmd, DIR_BACK, DIR_FRONT, DIR_LEFT, DIR_RIGHT, ENTITYNUM_NONE, EV_JUMP, playerState_s::fd, FORCE_LEVEL_1, FORCE_LEVEL_2, playerState_s::forceHandExtend, forcedata_s::forcePowerLevel, forcedata_s::forceRageRecoveryTime, usercmd_s::forwardmove, FP_GRIP, FP_LEVITATION, playerState_s::groundEntityNum, HANDEXTEND_NONE, saberInfo_t::jumpAtkLeftMove, saberInfo_t::jumpAtkRightMove, playerState_s::legsAnim, LS_A_BACK, LS_A_BACK_CR, LS_A_BACKSTAB, LS_A_BL2TR, LS_A_BR2TL, LS_A_L2R, LS_A_R2L, LS_A_T2B, LS_A_TL2BR, LS_A_TR2BL, LS_BUTTERFLY_LEFT, LS_BUTTERFLY_RIGHT, LS_DUAL_FB, LS_DUAL_LR, LS_INVALID, LS_JUMPATTACK_ARIAL_LEFT, LS_JUMPATTACK_ARIAL_RIGHT, LS_JUMPATTACK_CART_LEFT, LS_JUMPATTACK_CART_RIGHT, LS_NONE, LS_READY, LS_S_L2R, LS_S_R2L, LS_S_T2B, NULL, pm, PM_AddEvent(), PM_CanBackstab(), PM_CheckStabDown(), playerState_s::pm_flags, PM_GroundDistance(), PM_InSecondaryStyle(), PM_SaberBackflipAttackMove(), PM_SaberFlipOverAttackMove(), PM_SaberInBounce(), PM_SaberJumpAttackMove(), PM_SaberJumpAttackMove2(), PM_SaberKataDone(), PM_SaberLungeAttackMove(), PMF_DUCKED, PMF_JUMP_HELD, pmove_t::ps, qboolean, qfalse, qtrue, usercmd_s::rightmove, SABER_ALT_ATTACK_POWER_FB, SABER_ALT_ATTACK_POWER_LR, forcedata_s::saberAnimLevel, saberInfo_t::saberFlags, playerState_s::saberMove, saberMoveData, saberMoveName_t, usercmd_s::serverTime, SFL_NO_CARTWHEELS, SS_DUAL, SS_FAST, SS_MEDIUM, SS_STAFF, SS_STRONG, playerState_s::torsoAnim, usercmd_s::upmove, vec3_t, VectorMA, VectorSet, playerState_s::velocity, playerState_s::viewangles, playerState_s::weapon, playerState_s::weaponTime, WP_SABER, and YAW.

Referenced by PM_WeaponLightsaber().

02239 {
02240         saberMoveName_t newmove = LS_NONE;
02241         qboolean noSpecials = PM_InSecondaryStyle();
02242         qboolean allowCartwheels = qtrue;
02243         saberMoveName_t overrideJumpRightAttackMove = LS_INVALID;
02244         saberMoveName_t overrideJumpLeftAttackMove = LS_INVALID;
02245 
02246         if ( pm->ps->weapon == WP_SABER )
02247         {
02248                 saberInfo_t *saber1 = BG_MySaber( pm->ps->clientNum, 0 );
02249                 saberInfo_t *saber2 = BG_MySaber( pm->ps->clientNum, 1 );
02250 
02251                 if ( saber1
02252                         && saber1->jumpAtkRightMove != LS_INVALID )
02253                 {
02254                         if ( saber1->jumpAtkRightMove != LS_NONE )
02255                         {//actually overriding
02256                                 overrideJumpRightAttackMove = (saberMoveName_t)saber1->jumpAtkRightMove;
02257                         }
02258                         else if ( saber2
02259                                 && saber2->jumpAtkRightMove > LS_NONE )
02260                         {//would be cancelling it, but check the second saber, too
02261                                 overrideJumpRightAttackMove = (saberMoveName_t)saber2->jumpAtkRightMove;
02262                         }
02263                         else
02264                         {//nope, just cancel it
02265                                 overrideJumpRightAttackMove = LS_NONE;
02266                         }
02267                 }
02268                 else if ( saber2
02269                         && saber2->jumpAtkRightMove != LS_INVALID )
02270                 {//first saber not overridden, check second
02271                         overrideJumpRightAttackMove = (saberMoveName_t)saber2->jumpAtkRightMove;
02272                 }
02273 
02274                 if ( saber1
02275                         && saber1->jumpAtkLeftMove != LS_INVALID )
02276                 {
02277                         if ( saber1->jumpAtkLeftMove != LS_NONE )
02278                         {//actually overriding
02279                                 overrideJumpLeftAttackMove = (saberMoveName_t)saber1->jumpAtkLeftMove;
02280                         }
02281                         else if ( saber2
02282                                 && saber2->jumpAtkLeftMove > LS_NONE )
02283                         {//would be cancelling it, but check the second saber, too
02284                                 overrideJumpLeftAttackMove = (saberMoveName_t)saber2->jumpAtkLeftMove;
02285                         }
02286                         else
02287                         {//nope, just cancel it
02288                                 overrideJumpLeftAttackMove = LS_NONE;
02289                         }
02290                 }
02291                 else if ( saber2
02292                         && saber2->jumpAtkLeftMove != LS_INVALID )
02293                 {//first saber not overridden, check second
02294                         overrideJumpLeftAttackMove = (saberMoveName_t)saber1->jumpAtkLeftMove;
02295                 }
02296 
02297                 if ( saber1
02298                         && (saber1->saberFlags&SFL_NO_CARTWHEELS) )
02299                 {
02300                         allowCartwheels = qfalse;
02301                 }
02302                 if ( saber2
02303                         && (saber2->saberFlags&SFL_NO_CARTWHEELS) )
02304                 {
02305                         allowCartwheels = qfalse;
02306                 }
02307         }
02308 
02309         if ( pm->cmd.rightmove > 0 )
02310         {//moving right
02311                 if ( !noSpecials
02312                         && overrideJumpRightAttackMove != LS_NONE
02313                         && pm->ps->velocity[2] > 20.0f //pm->ps->groundEntityNum != ENTITYNUM_NONE//on ground
02314                         && (pm->cmd.buttons&BUTTON_ATTACK)//hitting attack
02315                         && PM_GroundDistance() < 70.0f //not too high above ground
02316                         && ( pm->cmd.upmove > 0 || (pm->ps->pm_flags & PMF_JUMP_HELD) )//focus-holding player
02317                         && BG_EnoughForcePowerForMove( SABER_ALT_ATTACK_POWER_LR ) )//have enough power
02318                 {//cartwheel right
02319                         BG_ForcePowerDrain(pm->ps, FP_GRIP, SABER_ALT_ATTACK_POWER_LR);
02320                         if ( overrideJumpRightAttackMove != LS_INVALID )
02321                         {//overridden with another move
02322                                 return overrideJumpRightAttackMove;
02323                         }
02324                         else
02325                         {
02326                                 vec3_t right, fwdAngles;
02327 
02328                                 VectorSet(fwdAngles, 0.0f, pm->ps->viewangles[YAW], 0.0f);
02329 
02330                                 AngleVectors( fwdAngles, NULL, right, NULL );
02331                                 pm->ps->velocity[0] = pm->ps->velocity[1] = 0.0f; 
02332                                 VectorMA( pm->ps->velocity, 190.0f, right, pm->ps->velocity );
02333                                 if ( pm->ps->fd.saberAnimLevel == SS_STAFF )
02334                                 {
02335                                         newmove = LS_BUTTERFLY_RIGHT;
02336                                         pm->ps->velocity[2] = 350.0f;
02337                                 }
02338                                 else if ( allowCartwheels )
02339                                 {
02340                                         //PM_SetJumped( JUMP_VELOCITY, qtrue );
02341                                         PM_AddEvent( EV_JUMP );
02342                                         pm->ps->velocity[2] = 300.0f;
02343 
02344                                         //if ( !Q_irand( 0, 1 ) )
02345                                         //if (PM_GroundDistance() >= 25.0f)
02346                                         if (1)
02347                                         {
02348                                                 newmove = LS_JUMPATTACK_ARIAL_RIGHT;
02349                                         }
02350                                         else
02351                                         {
02352                                                 newmove = LS_JUMPATTACK_CART_RIGHT;
02353                                         }
02354                                 }
02355                         }
02356                 }
02357                 else if ( pm->cmd.forwardmove > 0 )
02358                 {//forward right = TL2BR slash
02359                         newmove = LS_A_TL2BR;
02360                 }
02361                 else if ( pm->cmd.forwardmove < 0 )
02362                 {//backward right = BL2TR uppercut
02363                         newmove = LS_A_BL2TR;
02364                 }
02365                 else
02366                 {//just right is a left slice
02367                         newmove = LS_A_L2R;
02368                 }
02369         }
02370         else if ( pm->cmd.rightmove < 0 )
02371         {//moving left
02372                 if ( !noSpecials
02373                         && overrideJumpLeftAttackMove != LS_NONE
02374                         && pm->ps->velocity[2] > 20.0f //pm->ps->groundEntityNum != ENTITYNUM_NONE//on ground
02375                         && (pm->cmd.buttons&BUTTON_ATTACK)//hitting attack
02376                         && PM_GroundDistance() < 70.0f //not too high above ground
02377                         && ( pm->cmd.upmove > 0 || (pm->ps->pm_flags & PMF_JUMP_HELD) )//focus-holding player
02378                         && BG_EnoughForcePowerForMove( SABER_ALT_ATTACK_POWER_LR ) )//have enough power
02379                 {//cartwheel left
02380                         BG_ForcePowerDrain(pm->ps, FP_GRIP, SABER_ALT_ATTACK_POWER_LR);
02381 
02382                         if ( overrideJumpLeftAttackMove != LS_INVALID )
02383                         {//overridden with another move
02384                                 return overrideJumpLeftAttackMove;
02385                         }
02386                         else
02387                         {
02388                                 vec3_t right, fwdAngles;
02389 
02390                                 VectorSet(fwdAngles, 0.0f, pm->ps->viewangles[YAW], 0.0f);
02391                                 AngleVectors( fwdAngles, NULL, right, NULL );
02392                                 pm->ps->velocity[0] = pm->ps->velocity[1] = 0.0f; 
02393                                 VectorMA( pm->ps->velocity, -190.0f, right, pm->ps->velocity );
02394                                 if ( pm->ps->fd.saberAnimLevel == SS_STAFF )
02395                                 {
02396                                         newmove = LS_BUTTERFLY_LEFT;
02397                                         pm->ps->velocity[2] = 250.0f;
02398                                 }
02399                                 else if ( allowCartwheels )
02400                                 {
02401                                         //PM_SetJumped( JUMP_VELOCITY, qtrue );
02402                                         PM_AddEvent( EV_JUMP );
02403                                         pm->ps->velocity[2] = 350.0f;
02404 
02405                                         //if ( !Q_irand( 0, 1 ) )
02406                                         //if (PM_GroundDistance() >= 25.0f)
02407                                         if (1)
02408                                         {
02409                                                 newmove = LS_JUMPATTACK_ARIAL_LEFT;
02410                                         }
02411                                         else
02412                                         {
02413                                                 newmove = LS_JUMPATTACK_CART_LEFT;
02414                                         }
02415                                 }
02416                         }
02417                 }
02418                 else if ( pm->cmd.forwardmove > 0 )
02419                 {//forward left = TR2BL slash
02420                         newmove = LS_A_TR2BL;
02421                 }
02422                 else if ( pm->cmd.forwardmove < 0 )
02423                 {//backward left = BR2TL uppercut
02424                         newmove = LS_A_BR2TL;
02425                 }
02426                 else
02427                 {//just left is a right slice
02428                         newmove = LS_A_R2L;
02429                 }
02430         }
02431         else
02432         {//not moving left or right
02433                 if ( pm->cmd.forwardmove > 0 )
02434                 {//forward= T2B slash
02435                         if (!noSpecials&&
02436                                 (pm->ps->fd.saberAnimLevel == SS_DUAL || pm->ps->fd.saberAnimLevel == SS_STAFF) &&
02437                                 pm->ps->fd.forceRageRecoveryTime < pm->cmd.serverTime &&
02438                                 //pm->ps->fd.forcePowerLevel[FP_LEVITATION] > FORCE_LEVEL_1 &&
02439                                 (pm->ps->groundEntityNum != ENTITYNUM_NONE || PM_GroundDistance() <= 40) &&
02440                                 pm->ps->velocity[2] >= 0 &&
02441                                 (pm->cmd.upmove > 0 || pm->ps->pm_flags & PMF_JUMP_HELD) &&
02442                                 !BG_SaberInTransitionAny(pm->ps->saberMove) &&
02443                                 !BG_SaberInAttack(pm->ps->saberMove) &&
02444                                 pm->ps->weaponTime <= 0 &&
02445                                 pm->ps->forceHandExtend == HANDEXTEND_NONE &&
02446                                 (pm->cmd.buttons & BUTTON_ATTACK)&&
02447                                 BG_EnoughForcePowerForMove(SABER_ALT_ATTACK_POWER_FB) )
02448                         { //DUAL/STAFF JUMP ATTACK
02449                                 newmove = PM_SaberJumpAttackMove2();
02450                                 if ( newmove != LS_A_T2B 
02451                                         && newmove != LS_NONE )
02452                                 {
02453                                         BG_ForcePowerDrain(pm->ps, FP_GRIP, SABER_ALT_ATTACK_POWER_FB);
02454                                 }
02455                         }
02456                         else if (!noSpecials&&
02457                                 pm->ps->fd.saberAnimLevel == SS_MEDIUM &&
02458                                 pm->ps->velocity[2] > 100 &&
02459                                 PM_GroundDistance() < 32 &&
02460                                 !BG_InSpecialJump(pm->ps->legsAnim) &&
02461                                 !BG_SaberInSpecialAttack(pm->ps->torsoAnim)&&
02462                                 BG_EnoughForcePowerForMove(SABER_ALT_ATTACK_POWER_FB))
02463                         { //FLIP AND DOWNWARD ATTACK
02464                                 //trace_t tr;
02465 
02466                                 //if (PM_SomeoneInFront(&tr))
02467                                 {
02468                                         newmove = PM_SaberFlipOverAttackMove();
02469                                         if ( newmove != LS_A_T2B
02470                                                 && newmove != LS_NONE )
02471                                         {
02472                                                 BG_ForcePowerDrain(pm->ps, FP_GRIP, SABER_ALT_ATTACK_POWER_FB);
02473                                         }
02474                                 }
02475                         }
02476                         else if (!noSpecials&&
02477                                 pm->ps->fd.saberAnimLevel == SS_STRONG &&
02478                                 pm->ps->velocity[2] > 100 &&
02479                                 PM_GroundDistance() < 32 &&
02480                                 !BG_InSpecialJump(pm->ps->legsAnim) &&
02481                                 !BG_SaberInSpecialAttack(pm->ps->torsoAnim)&&
02482                                 BG_EnoughForcePowerForMove( SABER_ALT_ATTACK_POWER_FB ))
02483                         { //DFA
02484                                 //trace_t tr;
02485 
02486                                 //if (PM_SomeoneInFront(&tr))
02487                                 {
02488                                         newmove = PM_SaberJumpAttackMove();
02489                                         if ( newmove != LS_A_T2B
02490                                                 && newmove != LS_NONE )
02491                                         {
02492                                                 BG_ForcePowerDrain(pm->ps, FP_GRIP, SABER_ALT_ATTACK_POWER_FB);
02493                                         }
02494                                 }
02495                         }
02496                         else if ((pm->ps->fd.saberAnimLevel == SS_FAST || pm->ps->fd.saberAnimLevel == SS_DUAL || pm->ps->fd.saberAnimLevel == SS_STAFF) &&
02497                                 pm->ps->groundEntityNum != ENTITYNUM_NONE &&
02498                                 (pm->ps->pm_flags & PMF_DUCKED) &&
02499                                 pm->ps->weaponTime <= 0 &&
02500                                 !BG_SaberInSpecialAttack(pm->ps->torsoAnim)&&
02501                                 BG_EnoughForcePowerForMove(SABER_ALT_ATTACK_POWER_FB))
02502                         { //LUNGE (weak)
02503                                 newmove = PM_SaberLungeAttackMove( noSpecials );
02504                                 if ( newmove != LS_A_T2B
02505                                         && newmove != LS_NONE )
02506                                 {
02507                                         BG_ForcePowerDrain(pm->ps, FP_GRIP, SABER_ALT_ATTACK_POWER_FB);
02508                                 }
02509                         }
02510                         else if ( !noSpecials )
02511                         {
02512                                 saberMoveName_t stabDownMove = PM_CheckStabDown();
02513                                 if (stabDownMove != LS_NONE 
02514                                         && BG_EnoughForcePowerForMove(SABER_ALT_ATTACK_POWER_FB) )
02515                                 {
02516                                         newmove = stabDownMove;
02517                                         BG_ForcePowerDrain(pm->ps, FP_GRIP, SABER_ALT_ATTACK_POWER_FB);
02518                                 }
02519                                 else
02520                                 {
02521                                         newmove = LS_A_T2B;
02522                                 }
02523                         }
02524                 }
02525                 else if ( pm->cmd.forwardmove < 0 )
02526                 {//backward= T2B slash//B2T uppercut?
02527                         if (!noSpecials&&
02528                                 pm->ps->fd.saberAnimLevel == SS_STAFF &&
02529                                 pm->ps->fd.forceRageRecoveryTime < pm->cmd.serverTime &&
02530                                 pm->ps->fd.forcePowerLevel[FP_LEVITATION] > FORCE_LEVEL_1 &&
02531                                 (pm->ps->groundEntityNum != ENTITYNUM_NONE || PM_GroundDistance() <= 40) &&
02532                                 pm->ps->velocity[2] >= 0 &&
02533                                 (pm->cmd.upmove > 0 || pm->ps->pm_flags & PMF_JUMP_HELD) &&
02534                                 !BG_SaberInTransitionAny(pm->ps->saberMove) &&
02535                                 !BG_SaberInAttack(pm->ps->saberMove) &&
02536                                 pm->ps->weaponTime <= 0 &&
02537                                 pm->ps->forceHandExtend == HANDEXTEND_NONE &&
02538                                 (pm->cmd.buttons & BUTTON_ATTACK))
02539                         { //BACKFLIP ATTACK
02540                                 newmove = PM_SaberBackflipAttackMove();
02541                         }
02542                         else if (PM_CanBackstab() && !BG_SaberInSpecialAttack(pm->ps->torsoAnim))
02543                         { //BACKSTAB (attack varies by level)
02544                                 if (pm->ps->fd.saberAnimLevel >= FORCE_LEVEL_2 && pm->ps->fd.saberAnimLevel != SS_STAFF)
02545                                 {//medium and higher attacks
02546                                         if ( (pm->ps->pm_flags&PMF_DUCKED) || pm->cmd.upmove < 0 )
02547                                         {
02548                                                 newmove = LS_A_BACK_CR;
02549                                         }
02550                                         else
02551                                         {
02552                                                 newmove = LS_A_BACK;
02553                                         }
02554                                 }
02555                                 else
02556                                 { //weak attack
02557                                         newmove = LS_A_BACKSTAB;
02558                                 }
02559                         }
02560                         else
02561                         {
02562                                 newmove = LS_A_T2B;
02563                         }
02564                 }
02565                 else if ( PM_SaberInBounce( curmove ) )
02566                 {//bounces should go to their default attack if you don't specify a direction but are attacking
02567                         newmove = saberMoveData[curmove].chain_attack;
02568 
02569                         if ( PM_SaberKataDone(curmove, newmove) )
02570                         {
02571                                 newmove = saberMoveData[curmove].chain_idle;
02572                         }
02573                         else
02574                         {
02575                                 newmove = saberMoveData[curmove].chain_attack;
02576                         }
02577                 }
02578                 else if ( curmove == LS_READY )
02579                 {//Not moving at all, shouldn't have gotten here...?
02580                         //for now, just pick a random attack
02581                         //newmove = Q_irand( LS_A_TL2BR, LS_A_T2B );
02582                         //rww - If we don't seed with a "common" value, the client and server will get mismatched
02583                         //prediction values. Under laggy conditions this will cause the appearance of rapid swing
02584                         //sequence changes.
02585 
02586                         newmove = LS_A_T2B; //decided we don't like random attacks when idle, use an overhead instead.
02587                 }
02588         }
02589 
02590         if (pm->ps->fd.saberAnimLevel == SS_DUAL)
02591         {
02592                 if ( ( newmove == LS_A_R2L || newmove == LS_S_R2L
02593                                         || newmove == LS_A_L2R  || newmove == LS_S_L2R )
02594                         && PM_CanDoDualDoubleAttacks()
02595                         && PM_CheckEnemyPresence( DIR_RIGHT, 100.0f )
02596                         && PM_CheckEnemyPresence( DIR_LEFT, 100.0f ) )
02597                 {//enemy both on left and right
02598                         newmove = LS_DUAL_LR;
02599                         //probably already moved, but...
02600                         pm->cmd.rightmove = 0;
02601                 }
02602                 else if ( (newmove == LS_A_T2B || newmove == LS_S_T2B
02603                                         || newmove == LS_A_BACK || newmove == LS_A_BACK_CR )
02604                         && PM_CanDoDualDoubleAttacks()
02605                         && PM_CheckEnemyPresence( DIR_FRONT, 100.0f )
02606                         && PM_CheckEnemyPresence( DIR_BACK, 100.0f ) )
02607                 {//enemy both in front and back
02608                         newmove = LS_DUAL_FB;
02609                         //probably already moved, but...
02610                         pm->cmd.forwardmove = 0;
02611                 }
02612         }
02613 
02614         return newmove;
02615 }

int PM_SaberBackflipAttackMove void   ) 
 

Definition at line 1752 of file bg_saber.c.

References BG_MySaber(), playerState_s::clientNum, pmove_t::cmd, saberInfo_t::jumpAtkBackMove, LS_A_BACKFLIP_ATK, LS_A_T2B, LS_INVALID, LS_NONE, pm, pmove_t::ps, saberMoveName_t, usercmd_s::upmove, and playerState_s::velocity.

Referenced by PM_SaberAttackForMovement().

01753 {
01754         saberInfo_t *saber1 = BG_MySaber( pm->ps->clientNum, 0 );
01755         saberInfo_t *saber2 = BG_MySaber( pm->ps->clientNum, 1 );
01756         //see if we have an overridden (or cancelled) lunge move
01757         if ( saber1
01758                 && saber1->jumpAtkBackMove != LS_INVALID )
01759         {
01760                 if ( saber1->jumpAtkBackMove != LS_NONE )
01761                 {
01762                         return (saberMoveName_t)saber1->jumpAtkBackMove;
01763                 }
01764         }
01765         if ( saber2
01766                 && saber2->jumpAtkBackMove != LS_INVALID )
01767         {
01768                 if ( saber2->jumpAtkBackMove != LS_NONE )
01769                 {
01770                         return (saberMoveName_t)saber2->jumpAtkBackMove;
01771                 }
01772         }
01773         //no overrides, cancelled?
01774         if ( saber1
01775                 && saber1->jumpAtkBackMove == LS_NONE )
01776         {
01777                 return LS_A_T2B;//LS_NONE;
01778         }
01779         if ( saber2
01780                 && saber2->jumpAtkBackMove == LS_NONE )
01781         {
01782                 return LS_A_T2B;//LS_NONE;
01783         }
01784         //just do it
01785         pm->cmd.upmove = 127;
01786         pm->ps->velocity[2] = 500;
01787         return LS_A_BACKFLIP_ATK;
01788 }

int PM_SaberBounceForAttack int  move  ) 
 

Definition at line 1086 of file bg_panimate.c.

01087 {
01088         switch ( saberMoveData[move].startQuad )
01089         {
01090         case Q_B:
01091         case Q_BR:
01092                 return LS_B1_BR;
01093                 break;
01094         case Q_R:
01095                 return LS_B1__R;
01096                 break;
01097         case Q_TR:
01098                 return LS_B1_TR;
01099                 break;
01100         case Q_T:
01101                 return LS_B1_T_;
01102                 break;
01103         case Q_TL:
01104                 return LS_B1_TL;
01105                 break;
01106         case Q_L:
01107                 return LS_B1__L;
01108                 break;
01109         case Q_BL:
01110                 return LS_B1_BL;
01111                 break;
01112         }
01113         return LS_NONE;
01114 }

int PM_SaberDualJumpAttackMove void   ) 
 

Definition at line 1790 of file bg_saber.c.

References pmove_t::cmd, LS_JUMPATTACK_DUAL, pm, and usercmd_s::upmove.

Referenced by PM_SaberJumpAttackMove2().

01791 {
01792         //FIXME: to make this move easier to execute, should be allowed to do it 
01793         //              after you've already started your jump... but jump is delayed in
01794         //              this anim, so how do we undo the jump?
01795         pm->cmd.upmove = 0;//no jump just yet
01796         return LS_JUMPATTACK_DUAL;
01797 }

saberMoveName_t PM_SaberFlipOverAttackMove void   ) 
 

Definition at line 1654 of file bg_saber.c.

References AngleVectors(), BG_MySaber(), playerState_s::clientNum, pmove_t::cmd, EV_JUMP, playerState_s::fd, forcedata_s::forceJumpSound, saberInfo_t::jumpAtkFwdMove, LS_A_FLIP_SLASH, LS_A_T2B, LS_INVALID, LS_NONE, NULL, playerState_s::origin, PITCH, pm, PM_AddEvent(), PM_SetForceJumpZStart(), pmove_t::ps, ROLL, saberMoveName_t, usercmd_s::upmove, vec3_t, VectorCopy, VectorScale, playerState_s::velocity, and playerState_s::viewangles.

Referenced by PM_SaberAttackForMovement().

01655 { 
01656         vec3_t fwdAngles, jumpFwd;
01657 //      float zDiff = 0;
01658 //      playerState_t *psData;
01659 //      bgEntity_t *bgEnt;
01660 
01661         saberInfo_t *saber1 = BG_MySaber( pm->ps->clientNum, 0 );
01662         saberInfo_t *saber2 = BG_MySaber( pm->ps->clientNum, 1 );
01663         //see if we have an overridden (or cancelled) lunge move
01664         if ( saber1
01665                 && saber1->jumpAtkFwdMove != LS_INVALID )
01666         {
01667                 if ( saber1->jumpAtkFwdMove != LS_NONE )
01668                 {
01669                         return (saberMoveName_t)saber1->jumpAtkFwdMove;
01670                 }
01671         }
01672         if ( saber2
01673                 && saber2->jumpAtkFwdMove != LS_INVALID )
01674         {
01675                 if ( saber2->jumpAtkFwdMove != LS_NONE )
01676                 {
01677                         return (saberMoveName_t)saber2->jumpAtkFwdMove;
01678                 }
01679         }
01680         //no overrides, cancelled?
01681         if ( saber1
01682                 && saber1->jumpAtkFwdMove == LS_NONE )
01683         {
01684                 return LS_A_T2B;//LS_NONE;
01685         }
01686         if ( saber2 
01687                 && saber2->jumpAtkFwdMove == LS_NONE )
01688         {
01689                 return LS_A_T2B;//LS_NONE;
01690         }
01691         //just do it
01692         VectorCopy( pm->ps->viewangles, fwdAngles );
01693         fwdAngles[PITCH] = fwdAngles[ROLL] = 0;
01694         AngleVectors( fwdAngles, jumpFwd, NULL, NULL );
01695         VectorScale( jumpFwd, 150, pm->ps->velocity );//was 50
01696         pm->ps->velocity[2] = 400;
01697 
01698         /*
01699         bgEnt = PM_BGEntForNum(tr->entityNum);
01700 
01701         if (!bgEnt)
01702         {
01703                 return LS_A_FLIP_STAB;
01704         }
01705 
01706     psData = bgEnt->playerState;
01707 
01708         //go higher for enemies higher than you, lower for those lower than you
01709         if (psData)
01710         {
01711                 zDiff = psData->origin[2] - pm->ps->origin[2];
01712         }
01713         else
01714         {
01715                 zDiff = 0;
01716         }
01717         pm->ps->velocity[2] += (zDiff)*1.5f;
01718 
01719         //clamp to decent-looking values
01720         if ( zDiff <= 0 && pm->ps->velocity[2] < 200 )
01721         {//if we're on same level, don't let me jump so low, I clip into the ground
01722                 pm->ps->velocity[2] = 200;
01723         }
01724         else if ( pm->ps->velocity[2] < 100 )
01725         {
01726                 pm->ps->velocity[2] = 100;
01727         }
01728         else if ( pm->ps->velocity[2] > 400 )
01729         {
01730                 pm->ps->velocity[2] = 400;
01731         }
01732         */
01733 
01734         PM_SetForceJumpZStart(pm->ps->origin[2]);//so we don't take damage if we land at same height
01735 
01736         PM_AddEvent( EV_JUMP );
01737         pm->ps->fd.forceJumpSound = 1;
01738         pm->cmd.upmove = 0;
01739 
01740         /*
01741         if ( PM_irand_timesync( 0, 1 ) )
01742         {
01743                 return LS_A_FLIP_STAB;
01744         }
01745         else
01746         */
01747         {
01748                 return LS_A_FLIP_SLASH;
01749         }
01750 }

qboolean PM_SaberInBounce int  move  ) 
 

Definition at line 700 of file bg_saber.c.

References LS_B1_BL, LS_B1_BR, LS_D1_BL, LS_D1_BR, qboolean, qfalse, and qtrue.

Referenced by PM_SaberAttackForMovement(), and PM_WeaponLightsaber().

00701 {
00702         if ( move >= LS_B1_BR && move <= LS_B1_BL )
00703         {
00704                 return qtrue;
00705         }
00706         if ( move >= LS_D1_BR && move <= LS_D1_BL )
00707         {
00708                 return qtrue;
00709         }
00710         return qfalse;
00711 }

qboolean PM_SaberInBrokenParry int  move  ) 
 

Definition at line 1580 of file bg_saber.c.

References LS_H1_BL, LS_H1_T_, LS_V1_B_, LS_V1_BR, qboolean, qfalse, and qtrue.

Referenced by Jedi_SaberBusy(), PM_SetSaberMove(), PM_WeaponLightsaber(), and WP_SaberCanBlock().

01581 {
01582         if ( move >= LS_V1_BR && move <= LS_V1_B_ )
01583         {
01584                 return qtrue;
01585         }
01586         if ( move >= LS_H1_T_ && move <= LS_H1_BL )
01587         {
01588                 return qtrue;
01589         }
01590         return qfalse;
01591 }

qboolean PM_SaberInReturn int  move  ) 
 

Definition at line 1193 of file bg_panimate.c.

01194 {
01195         if ( move >= LS_R_TL2BR && move <= LS_R_T2B )
01196         {
01197                 return qtrue;
01198         }
01199         return qfalse;
01200 }

qboolean PM_SaberInTransition int  move  ) 
 

Definition at line 1610 of file bg_panimate.c.

01611 {
01612         if ( move >= LS_T1_BR__R && move <= LS_T1_BL__L )
01613         {
01614                 return qtrue;
01615         }
01616         return qfalse;
01617 }

saberMoveName_t PM_SaberJumpAttackMove void   ) 
 

Definition at line 1944 of file bg_saber.c.

References AngleVectors(), BG_MySaber(), playerState_s::clientNum, pmove_t::cmd, EV_JUMP, playerState_s::fd, forcedata_s::forceJumpSound, saberInfo_t::jumpAtkFwdMove, LS_A_JUMP_T__B_, LS_A_T2B, LS_INVALID, LS_NONE, NULL, playerState_s::origin, PITCH, pm, PM_AddEvent(), PM_SetForceJumpZStart(), pmove_t::ps, ROLL, saberMoveName_t, usercmd_s::upmove, vec3_t, VectorCopy, VectorScale, playerState_s::velocity, and playerState_s::viewangles.

Referenced by PM_SaberAttackForMovement().

01945 {
01946         vec3_t fwdAngles, jumpFwd;
01947         saberInfo_t *saber1 = BG_MySaber( pm->ps->clientNum, 0 );
01948         saberInfo_t *saber2 = BG_MySaber( pm->ps->clientNum, 1 );
01949         //see if we have an overridden (or cancelled) lunge move
01950         if ( saber1
01951                 && saber1->jumpAtkFwdMove != LS_INVALID )
01952         {
01953                 if ( saber1->jumpAtkFwdMove != LS_NONE )
01954                 {
01955                         return (saberMoveName_t)saber1->jumpAtkFwdMove;
01956                 }
01957         }
01958         if ( saber2
01959                 && saber2->jumpAtkFwdMove != LS_INVALID )
01960         {
01961                 if ( saber2->jumpAtkFwdMove != LS_NONE )
01962                 {
01963                         return (saberMoveName_t)saber2->jumpAtkFwdMove;
01964                 }
01965         }
01966         //no overrides, cancelled?
01967         if ( saber1
01968                 && saber1->jumpAtkFwdMove == LS_NONE )
01969         {
01970                 return LS_A_T2B;//LS_NONE;
01971         }
01972         if ( saber2
01973                 && saber2->jumpAtkFwdMove == LS_NONE )
01974         {
01975                 return LS_A_T2B;//LS_NONE;
01976         }
01977         //just do it
01978         VectorCopy( pm->ps->viewangles, fwdAngles );
01979         fwdAngles[PITCH] = fwdAngles[ROLL] = 0;
01980         AngleVectors( fwdAngles, jumpFwd, NULL, NULL );
01981         VectorScale( jumpFwd, 300, pm->ps->velocity );
01982         pm->ps->velocity[2] = 280;
01983         PM_SetForceJumpZStart(pm->ps->origin[2]);//so we don't take damage if we land at same height
01984 
01985         PM_AddEvent( EV_JUMP );
01986         pm->ps->fd.forceJumpSound = 1;
01987         pm->cmd.upmove = 0;
01988 
01989         return LS_A_JUMP_T__B_;
01990 }

saberMoveName_t PM_SaberJumpAttackMove2 void   ) 
 

Definition at line 1888 of file bg_saber.c.

References BG_MySaber(), playerState_s::clientNum, playerState_s::fd, saberInfo_t::jumpAtkFwdMove, LS_A_T2B, LS_INVALID, LS_JUMPATTACK_STAFF_RIGHT, LS_NONE, pm, PM_SaberDualJumpAttackMove(), pmove_t::ps, forcedata_s::saberAnimLevel, saberMoveName_t, and SS_DUAL.

Referenced by PM_SaberAttackForMovement().

01889 {
01890         saberInfo_t *saber1 = BG_MySaber( pm->ps->clientNum, 0 );
01891         saberInfo_t *saber2 = BG_MySaber( pm->ps->clientNum, 1 );
01892         //see if we have an overridden (or cancelled) lunge move
01893         if ( saber1
01894                 && saber1->jumpAtkFwdMove != LS_INVALID )
01895         {
01896                 if ( saber1->jumpAtkFwdMove != LS_NONE )
01897                 {
01898                         return (saberMoveName_t)saber1->jumpAtkFwdMove;
01899                 }
01900         }
01901         if ( saber2
01902         && saber2->jumpAtkFwdMove != LS_INVALID )
01903         {
01904                 if ( saber2->jumpAtkFwdMove != LS_NONE )
01905                 {
01906                         return (saberMoveName_t)saber2->jumpAtkFwdMove;
01907                 }
01908         }
01909         //no overrides, cancelled?
01910         if ( saber1
01911                 && saber1->jumpAtkFwdMove == LS_NONE )
01912         {
01913                 return LS_A_T2B;//LS_NONE;
01914         }
01915         if ( saber2
01916                 && saber2->jumpAtkFwdMove == LS_NONE )
01917         {
01918                 return LS_A_T2B;//LS_NONE;
01919         }
01920         //just do it
01921         if (pm->ps->fd.saberAnimLevel == SS_DUAL)
01922         {
01923                 return PM_SaberDualJumpAttackMove();
01924         }
01925         else
01926         {
01927                 //rwwFIXMEFIXME I don't like randomness for this sort of thing, gives people reason to
01928                 //complain combat is unpredictable. Maybe do something more clever to determine
01929                 //if we should do a left or right?
01930                 /*
01931                 if (PM_irand_timesync(0, 1))
01932                 {
01933                         newmove = LS_JUMPATTACK_STAFF_LEFT;
01934                 }
01935                 else
01936                 */
01937                 {
01938                         return LS_JUMPATTACK_STAFF_RIGHT;
01939                 }
01940         }
01941         return LS_A_T2B;
01942 }

qboolean PM_SaberKataDone int  curmove,
int  newmove
 

Definition at line 792 of file bg_saber.c.

References playerState_s::fd, FORCE_LEVEL_1, FORCE_LEVEL_2, FORCE_LEVEL_3, LS_A_BL2TR, LS_A_BR2TL, LS_A_L2R, LS_A_R2L, LS_A_TL2BR, LS_A_TR2BL, LS_NONE, playerState_s::m_iVehicleNum, pm, PM_irand_timesync(), PM_SaberAttackChainAngle(), pmove_t::ps, qboolean, qfalse, qtrue, forcedata_s::saberAnimLevel, playerState_s::saberAttackChainCount, SS_DESANN, SS_DUAL, SS_STAFF, and SS_TAVION.

Referenced by PM_SaberAnimTransitionAnim(), PM_SaberAttackForMovement(), and PM_WeaponLightsaber().

00793 {
00794         if (pm->ps->m_iVehicleNum)
00795         { //never continue kata on vehicle
00796                 if (pm->ps->saberAttackChainCount > 0)
00797                 {
00798                         return qtrue;
00799                 }
00800         }
00801 
00802         if ( pm->ps->fd.saberAnimLevel == SS_DESANN || pm->ps->fd.saberAnimLevel == SS_TAVION )
00803         {//desann and tavion can link up as many attacks as they want
00804                 return qfalse;
00805         }
00806 
00807         if ( pm->ps->fd.saberAnimLevel == SS_STAFF )
00808         {
00809                 //TEMP: for now, let staff attacks infinitely chain
00810                 return qfalse;
00811         }
00812         else if ( pm->ps->fd.saberAnimLevel == SS_DUAL )
00813         {
00814                 //TEMP: for now, let staff attacks infinitely chain
00815                 return qfalse;
00816         }
00817         else if ( pm->ps->fd.saberAnimLevel == FORCE_LEVEL_3 )
00818         {
00819                 if ( curmove == LS_NONE || newmove == LS_NONE )
00820                 {
00821                         if ( pm->ps->fd.saberAnimLevel >= FORCE_LEVEL_3 && pm->ps->saberAttackChainCount > PM_irand_timesync( 0, 1 ) )
00822                         {
00823                                 return qtrue;
00824                         }
00825                 }
00826                 else if ( pm->ps->saberAttackChainCount > PM_irand_timesync( 2, 3 ) )
00827                 {
00828                         return qtrue;
00829                 }
00830                 else if ( pm->ps->saberAttackChainCount > 0 )
00831                 {
00832                         int chainAngle = PM_SaberAttackChainAngle( curmove, newmove );
00833                         if ( chainAngle < 135 || chainAngle > 215 )
00834                         {//if trying to chain to a move that doesn't continue the momentum
00835                                 return qtrue;
00836                         }
00837                         else if ( chainAngle == 180 )
00838                         {//continues the momentum perfectly, allow it to chain 66% of the time
00839                                 if ( pm->ps->saberAttackChainCount > 1 )
00840                                 {
00841                                         return qtrue;
00842                                 }
00843                         }
00844                         else
00845                         {//would continue the movement somewhat, 50% chance of continuing
00846                                 if ( pm->ps->saberAttackChainCount > 2 )
00847                                 {
00848                                         return qtrue;
00849                                 }
00850                         }
00851                 }
00852         }
00853         else 
00854         {//Perhaps have chainAngle influence fast and medium chains as well? For now, just do level 3.
00855                 if (newmove == LS_A_TL2BR ||
00856                         newmove == LS_A_L2R ||
00857                         newmove == LS_A_BL2TR ||
00858                         newmove == LS_A_BR2TL ||
00859                         newmove == LS_A_R2L ||
00860                         newmove == LS_A_TR2BL )
00861                 { //lower chaining tolerance for spinning saber anims
00862                         int chainTolerance;
00863 
00864                         if (pm->ps->fd.saberAnimLevel == FORCE_LEVEL_1)
00865                         {
00866                                 chainTolerance = 5;
00867                         }
00868                         else
00869                         {
00870                                 chainTolerance = 3;
00871                         }
00872 
00873                         if (pm->ps->saberAttackChainCount >= chainTolerance && PM_irand_timesync(1, pm->ps->saberAttackChainCount) > chainTolerance)
00874                         {
00875                                 return qtrue;
00876                         }
00877                 }
00878                 if ( pm->ps->fd.saberAnimLevel == FORCE_LEVEL_2 && pm->ps->saberAttackChainCount > PM_irand_timesync( 2, 5 ) )
00879                 {
00880                         return qtrue;
00881                 }
00882         }
00883         return qfalse;
00884 }

void PM_SaberLockBreak playerState_t genemy,
qboolean  victory,
int  strength
 

Definition at line 1234 of file bg_saber.c.

References BG_AddPredictableEventToPlayerstate(), BG_KnockDownable(), BOTH_STAND1, pmove_t::checkDuelLoss, playerState_s::clientNum, pmove_t::cmd, EV_JUMP, playerState_s::forceDodgeAnim, playerState_s::forceHandExtend, playerState_s::forceHandExtendTime, HANDEXTEND_KNOCKDOWN, HANDEXTEND_WEAPONREADY, playerState_s::origin, playerState_s::otherKiller, playerState_s::otherKillerDebounceTime, playerState_s::otherKillerTime, playerState_t, pm, PM_AddEvent(), PM_irand_timesync(), PM_SaberLockLoseAnim(), PM_SaberLockResultAnim(), PM_SaberLockWinAnim(), pmove_t::ps, Q_irand(), qboolean, qfalse, qtrue, playerState_s::saberEntityNum, playerState_s::saberEventFlags, playerState_s::saberLockEnemy, playerState_s::saberLockFrame, playerState_s::saberLockHits, playerState_s::saberLockTime, SEF_LOCK_WON, usercmd_s::serverTime, vec3_t, VectorNormalize(), VectorSubtract, playerState_s::velocity, WEAPON_FIRING, WEAPON_READY, playerState_s::weaponstate, and playerState_s::weaponTime.

Referenced by PM_SaberLocked(), and PM_WeaponLightsaber().

01235 {
01236         int     winAnim = BOTH_STAND1, loseAnim = BOTH_STAND1;
01237         //qboolean punishLoser = qfalse;
01238         qboolean noKnockdown = qfalse;
01239         qboolean singleVsSingle = qtrue;
01240         qboolean superBreak = (strength+pm->ps->saberLockHits > Q_irand(2,4));
01241 
01242         winAnim = PM_SaberLockWinAnim( victory, superBreak );
01243         if ( winAnim != -1 )
01244         {//a single vs. single break
01245                 loseAnim = PM_SaberLockLoseAnim( genemy, victory, superBreak );
01246         }
01247         else
01248         {//must be a saberlock that's not between single and single...
01249                 singleVsSingle = qfalse;
01250                 winAnim = PM_SaberLockResultAnim( pm->ps, superBreak, qtrue );
01251                 pm->ps->weaponstate = WEAPON_FIRING;
01252                 loseAnim = PM_SaberLockResultAnim( genemy, superBreak, qfalse );
01253                 genemy->weaponstate = WEAPON_READY;
01254         }
01255 
01256         if ( victory )
01257         { //someone lost the lock, so punish them by knocking them down
01258                 if ( pm->ps->saberLockHits && !superBreak )
01259                 {//there was some over-power in the win, but not enough to superbreak
01260                         vec3_t oppDir;
01261 
01262                         int strength = 8;
01263 
01264                         VectorSubtract(genemy->origin, pm->ps->origin, oppDir);
01265                         VectorNormalize(oppDir);
01266 
01267                         if (noKnockdown)
01268                         {
01269                                 if (!genemy->saberEntityNum)
01270                                 { //if he has already lost his saber then just knock him down
01271                                         noKnockdown = qfalse;
01272                                 }
01273                         }
01274 
01275                         if (!noKnockdown && BG_KnockDownable(genemy))
01276                         {
01277                                 genemy->forceHandExtend = HANDEXTEND_KNOCKDOWN;
01278                                 genemy->forceHandExtendTime = pm->cmd.serverTime + 1100;
01279                                 genemy->forceDodgeAnim = 0; //this toggles between 1 and 0, when it's 1 we should play the get up anim
01280 
01281                                 genemy->otherKiller = pm->ps->clientNum;
01282                                 genemy->otherKillerTime = pm->cmd.serverTime + 5000;
01283                                 genemy->otherKillerDebounceTime = pm->cmd.serverTime + 100;
01284 
01285                                 genemy->velocity[0] = oppDir[0]*(strength*40);
01286                                 genemy->velocity[1] = oppDir[1]*(strength*40);
01287                                 genemy->velocity[2] = 100;
01288                         }
01289 
01290                         pm->checkDuelLoss = genemy->clientNum+1;
01291 
01292                         pm->ps->saberEventFlags |= SEF_LOCK_WON;
01293                 }
01294         }
01295         else
01296         { //If no one lost, then shove each player away from the other
01297                 vec3_t oppDir;
01298 
01299                 int strength = 4;
01300 
01301                 VectorSubtract(genemy->origin, pm->ps->origin, oppDir);
01302                 VectorNormalize(oppDir);
01303                 genemy->velocity[0] = oppDir[0]*(strength*40);
01304                 genemy->velocity[1] = oppDir[1]*(strength*40);
01305                 genemy->velocity[2] = 150;
01306 
01307                 VectorSubtract(pm->ps->origin, genemy->origin, oppDir);
01308                 VectorNormalize(oppDir);
01309                 pm->ps->velocity[0] = oppDir[0]*(strength*40);
01310                 pm->ps->velocity[1] = oppDir[1]*(strength*40);
01311                 pm->ps->velocity[2] = 150;
01312 
01313                 genemy->forceHandExtend = HANDEXTEND_WEAPONREADY;
01314         }
01315 
01316         pm->ps->weaponTime = 0;
01317         genemy->weaponTime = 0;
01318 
01319         pm->ps->saberLockTime = genemy->saberLockTime = 0;
01320         pm->ps->saberLockFrame = genemy->saberLockFrame = 0;
01321         pm->ps->saberLockEnemy = genemy->saberLockEnemy = 0;
01322 
01323         pm->ps->forceHandExtend = HANDEXTEND_WEAPONREADY;
01324 
01325         PM_AddEvent( EV_JUMP );
01326         if ( !victory )
01327         {//no-one won
01328                 BG_AddPredictableEventToPlayerstate(EV_JUMP, 0, genemy);
01329         }
01330         else
01331         {
01332                 if ( PM_irand_timesync( 0, 1 ) )
01333                 {
01334                         BG_AddPredictableEventToPlayerstate(EV_JUMP, PM_irand_timesync( 0, 75 ), genemy);
01335                 }
01336         }
01337 }

void PM_SaberLocked void   ) 
 

Definition at line 1398 of file bg_saber.c.

References animation_t, pmove_t::animations, BG_AddPredictableEventToPlayerstate(), BG_CheckIncrementLockAnim(), BG_InSaberLock(), BG_InSaberLockOld(), bgEntity_t, BOTH_BF1LOCK, BOTH_BF2LOCK, BOTH_CCWCIRCLELOCK, BOTH_CWCIRCLELOCK, ceil(), EV_JUMP, EV_PAIN, playerState_s::fd, animation_s::firstFrame, floor(), forcedata_s::forcePowerLevel, FP_SABER_OFFENSE, animation_s::numFrames, playerState_s::origin, bgEntity_s::playerState, playerState_t, pm, PM_AddEvent(), PM_BGEntForNum(), PM_irand_timesync(), PM_SaberLockBreak(), PM_SetAnimFrame(), pmove_t::ps, qfalse, qtrue, SABERLOCK_LOSE, SABERLOCK_WIN, playerState_s::saberLockAdvance, playerState_s::saberLockEnemy, playerState_s::saberLockFrame, playerState_s::torsoAnim, playerState_s::torsoTimer, and playerState_s::weaponTime.

Referenced by PM_WeaponLightsaber().

01399 {
01400         int     remaining = 0;
01401         playerState_t *genemy;
01402         bgEntity_t *eGenemy = PM_BGEntForNum(pm->ps->saberLockEnemy);
01403 
01404         if (!eGenemy)
01405         {
01406                 return;
01407         }
01408 
01409         genemy = eGenemy->playerState;
01410 
01411         if ( !genemy )
01412         {
01413                 return;
01414         }
01415         /*if ( ( (pm->ps->torsoAnim) == BOTH_BF2LOCK ||
01416                         (pm->ps->torsoAnim) == BOTH_BF1LOCK ||
01417                         (pm->ps->torsoAnim) == BOTH_CWCIRCLELOCK ||
01418                         (pm->ps->torsoAnim) == BOTH_CCWCIRCLELOCK )
01419                 && ( (genemy->torsoAnim) == BOTH_BF2LOCK ||
01420                         (genemy->torsoAnim) == BOTH_BF1LOCK ||
01421                         (genemy->torsoAnim) == BOTH_CWCIRCLELOCK ||
01422                         (genemy->torsoAnim) == BOTH_CCWCIRCLELOCK )
01423                 )
01424                 */ //yeah..
01425         if (pm->ps->saberLockFrame &&
01426                 genemy->saberLockFrame &&
01427                 BG_InSaberLock(pm->ps->torsoAnim) &&
01428                 BG_InSaberLock(genemy->torsoAnim))
01429         {
01430                 float dist = 0;
01431 
01432                 pm->ps->torsoTimer = 0;
01433                 pm->ps->weaponTime = 0;
01434                 genemy->torsoTimer = 0;
01435                 genemy->weaponTime = 0;
01436 
01437                 dist = DistanceSquared(pm->ps->origin,genemy->origin);
01438                 if ( dist < 64 || dist > 6400 )
01439                 {//between 8 and 80 from each other
01440                         PM_SaberLockBreak( genemy, qfalse, 0 );
01441                         return;
01442                 }
01443                 /*
01444                 //NOTE: time-out is handled around where PM_SaberLocked is called
01445                 if ( pm->ps->saberLockTime <= pm->cmd.serverTime + 500 )
01446                 {//lock just ended
01447                         PM_SaberLockBreak( genemy, qfalse, 0 );
01448                         return;
01449                 }
01450                 */
01451                 if ( pm->ps->saberLockAdvance )
01452                 {//holding attack
01453                         animation_t *anim;
01454                         float           currentFrame;
01455                         int                     curFrame;
01456                         int                     strength = 1;
01457 
01458                         pm->ps->saberLockAdvance = qfalse;
01459 
01460                         anim = &pm->animations[pm->ps->torsoAnim];
01461 
01462                         currentFrame = pm->ps->saberLockFrame;
01463 
01464                         strength = pm->ps->fd.forcePowerLevel[FP_SABER_OFFENSE]+1;
01465 
01466                         //advance/decrement my frame number
01467                         if ( BG_InSaberLockOld( pm->ps->torsoAnim ) )
01468                         { //old locks
01469                                 if ( (pm->ps->torsoAnim) == BOTH_CCWCIRCLELOCK ||
01470                                         (pm->ps->torsoAnim) == BOTH_BF2LOCK )
01471                                 {
01472                                         curFrame = floor( currentFrame )-strength;
01473                                         //drop my frame one
01474                                         if ( curFrame <= anim->firstFrame )
01475                                         {//I won!  Break out
01476                                                 PM_SaberLockBreak( genemy, qtrue, strength );
01477                                                 return;
01478                                         }
01479                                         else
01480                                         {
01481                                                 PM_SetAnimFrame( pm->ps, curFrame, qtrue, qtrue );
01482                                                 remaining = curFrame-anim->firstFrame;
01483                                         }
01484                                 }
01485                                 else
01486                                 {
01487                                         curFrame = ceil( currentFrame )+strength;
01488                                         //advance my frame one
01489                                         if ( curFrame >= anim->firstFrame+anim->numFrames )
01490                                         {//I won!  Break out
01491                                                 PM_SaberLockBreak( genemy, qtrue, strength );
01492                                                 return;
01493                                         }
01494                                         else
01495                                         {
01496                                                 PM_SetAnimFrame( pm->ps, curFrame, qtrue, qtrue );
01497                                                 remaining = anim->firstFrame+anim->numFrames-curFrame;
01498                                         }
01499                                 }
01500                         }
01501                         else
01502                         { //new locks
01503                                 if ( BG_CheckIncrementLockAnim( pm->ps->torsoAnim, SABERLOCK_WIN ) )
01504                                 {
01505                                         curFrame = ceil( currentFrame )+strength;
01506                                         //advance my frame one
01507                                         if ( curFrame >= anim->firstFrame+anim->numFrames )
01508                                         {//I won!  Break out
01509                                                 PM_SaberLockBreak( genemy, qtrue, strength );
01510                                                 return;
01511                                         }
01512                                         else
01513                                         {
01514                                                 PM_SetAnimFrame( pm->ps, curFrame, qtrue, qtrue );
01515                                                 remaining = anim->firstFrame+anim->numFrames-curFrame;
01516                                         }
01517                                 }
01518                                 else
01519                                 {
01520                                         curFrame = floor( currentFrame )-strength;
01521                                         //drop my frame one
01522                                         if ( curFrame <= anim->firstFrame )
01523                                         {//I won!  Break out
01524                                                 PM_SaberLockBreak( genemy, qtrue, strength );
01525                                                 return;
01526                                         }
01527                                         else
01528                                         {
01529                                                 PM_SetAnimFrame( pm->ps, curFrame, qtrue, qtrue );
01530                                                 remaining = curFrame-anim->firstFrame;
01531                                         }
01532                                 }
01533                         }
01534                         if ( !PM_irand_timesync( 0, 2 ) )
01535                         {
01536                                 PM_AddEvent( EV_JUMP );
01537                         }
01538                         //advance/decrement enemy frame number
01539                         anim = &pm->animations[(genemy->torsoAnim)];
01540 
01541                         if ( BG_InSaberLockOld( genemy->torsoAnim ) )
01542                         {
01543                                 if ( (genemy->torsoAnim) == BOTH_CWCIRCLELOCK ||
01544                                         (genemy->torsoAnim) == BOTH_BF1LOCK )
01545                                 {
01546                                         if ( !PM_irand_timesync( 0, 2 ) )
01547                                         {
01548                                                 BG_AddPredictableEventToPlayerstate(EV_PAIN, floor((float)80/100*100.0f), genemy);
01549                                         }
01550                                         PM_SetAnimFrame( genemy, anim->firstFrame+remaining, qtrue, qtrue );
01551                                 }
01552                                 else
01553                                 {
01554                                         PM_SetAnimFrame( genemy, anim->firstFrame+anim->numFrames-remaining, qtrue, qtrue );
01555                                 }
01556                         }
01557                         else
01558                         {//new locks
01559                                 if ( BG_CheckIncrementLockAnim( genemy->torsoAnim, SABERLOCK_LOSE ) )
01560                                 {
01561                                         if ( !PM_irand_timesync( 0, 2 ) )
01562                                         {
01563                                                 BG_AddPredictableEventToPlayerstate(EV_PAIN, floor((float)80/100*100.0f), genemy);
01564                                         }
01565                                         PM_SetAnimFrame( genemy, anim->firstFrame+anim->numFrames-remaining, qtrue, qtrue );
01566                                 }
01567                                 else
01568                                 {
01569                                         PM_SetAnimFrame( genemy, anim->firstFrame+remaining, qtrue, qtrue );
01570                                 }
01571                         }
01572                 }
01573         }
01574         else
01575         {//something broke us out of it
01576                 PM_SaberLockBreak( genemy, qfalse, 0 );
01577         }
01578 }

int PM_SaberLockLoseAnim playerState_t genemy,
qboolean  victory,
qboolean  superBreak
 

Definition at line 1000 of file bg_saber.c.

References BLOCKED_NONE, BLOCKED_PARRY_BROKEN, BOTH_A3_T__B_, BOTH_BF1BREAK, BOTH_BF1LOCK, BOTH_BF2LOCK, BOTH_CCWCIRCLEBREAK, BOTH_CCWCIRCLELOCK, BOTH_CWCIRCLEBREAK, BOTH_CWCIRCLELOCK, BOTH_K1_S1_T_, BOTH_KNOCKDOWN4, BOTH_LK_S_S_S_SB_1_L, BOTH_LK_S_S_T_SB_1_L, BOTH_V1_BL_S1, BOTH_V1_BR_S1, playerState_s::clientNum, g_entities, LS_A_T2B, LS_K1_T_, LS_V1_BL, LS_V1_BR, NPC_SetAnim(), playerState_t, playerState_s::saberBlocked, playerState_s::saberMove, SETANIM_BOTH, SETANIM_FLAG_HOLD, SETANIM_FLAG_OVERRIDE, playerState_s::torsoAnim, playerState_s::torsoTimer, WEAPON_READY, playerState_s::weaponstate, and playerState_s::weaponTime.

Referenced by PM_SaberLockBreak().

01001 { 
01002         int loseAnim = -1;
01003         switch ( genemy->torsoAnim )
01004         {
01005 /*
01006         default:
01007 #ifndef FINAL_BUILD
01008                 Com_Printf( S_COLOR_RED"ERROR-PM_SaberLockBreak: %s not in saberlock anim, anim = (%d)%s\n", genemy->NPC_type, genemy->client->ps.torsoAnim, animTable[genemy->client->ps.torsoAnim].name );
01009 #endif
01010 */
01011         case BOTH_BF2LOCK:
01012                 if ( superBreak )
01013                 {
01014                         loseAnim = BOTH_LK_S_S_T_SB_1_L;
01015                 }
01016                 else if ( !victory )
01017                 {
01018                         loseAnim = BOTH_BF1BREAK;
01019                 }
01020                 else
01021                 {
01022                         if ( !victory )
01023                         {//no-one won
01024                                 genemy->saberMove = LS_K1_T_;
01025                                 loseAnim = BOTH_K1_S1_T_;
01026                         }
01027                         else
01028                         {//FIXME: this anim needs to transition back to ready when done
01029                                 loseAnim = BOTH_BF1BREAK;
01030                         }
01031                 }
01032                 break;
01033         case BOTH_BF1LOCK:
01034                 if ( superBreak )
01035                 {
01036                         loseAnim = BOTH_LK_S_S_T_SB_1_L;
01037                 }
01038                 else if ( !victory )
01039                 {
01040                         loseAnim = BOTH_KNOCKDOWN4;
01041                 }
01042                 else
01043                 {
01044                         if ( !victory )
01045                         {//no-one won
01046                                 genemy->saberMove = LS_A_T2B;
01047                                 loseAnim = BOTH_A3_T__B_;
01048                         }
01049                         else
01050                         {
01051                                 loseAnim = BOTH_KNOCKDOWN4;
01052                         }
01053                 }
01054                 break;
01055         case BOTH_CWCIRCLELOCK:
01056                 if ( superBreak )
01057                 {
01058                         loseAnim = BOTH_LK_S_S_S_SB_1_L;
01059                 }
01060                 else if ( !victory )
01061                 {
01062                         genemy->saberMove = LS_V1_BL;//genemy->saberBounceMove = 
01063                         genemy->saberBlocked = BLOCKED_PARRY_BROKEN;
01064                         loseAnim = BOTH_V1_BL_S1;
01065                 }
01066                 else
01067                 {
01068                         if ( !victory )
01069                         {//no-one won
01070                                 loseAnim = BOTH_CCWCIRCLEBREAK;
01071                         }
01072                         else
01073                         {
01074                                 genemy->saberMove = LS_V1_BL;//genemy->saberBounceMove = 
01075                                 genemy->saberBlocked = BLOCKED_PARRY_BROKEN;
01076                                 loseAnim = BOTH_V1_BL_S1;
01077                                 /*
01078                                 genemy->client->ps.saberMove = genemy->client->ps.saberBounceMove = LS_H1_BR;
01079                                 genemy->client->ps.saberBlocked = BLOCKED_PARRY_BROKEN;
01080                                 loseAnim = BOTH_H1_S1_BL;
01081                                 */
01082                         }
01083                 }
01084                 break;
01085         case BOTH_CCWCIRCLELOCK:
01086                 if ( superBreak )
01087                 {
01088                         loseAnim = BOTH_LK_S_S_S_SB_1_L;
01089                 }
01090                 else if ( !victory )
01091                 {
01092                         genemy->saberMove = LS_V1_BR;//genemy->saberBounceMove = 
01093                         genemy->saberBlocked = BLOCKED_PARRY_BROKEN;
01094                         loseAnim = BOTH_V1_BR_S1;
01095                 }
01096                 else
01097                 {
01098                         if ( !victory )
01099                         {//no-one won
01100                                 loseAnim = BOTH_CWCIRCLEBREAK;
01101                         }
01102                         else
01103                         {
01104                                 genemy->saberMove = LS_V1_BR;//genemy->saberBounceMove = 
01105                                 genemy->saberBlocked = BLOCKED_PARRY_BROKEN;
01106                                 loseAnim = BOTH_V1_BR_S1;
01107                                 /*
01108                                 genemy->client->ps.saberMove = genemy->client->ps.saberBounceMove = LS_H1_BL;
01109                                 genemy->client->ps.saberBlocked = BLOCKED_PARRY_BROKEN;
01110                                 loseAnim = BOTH_H1_S1_BR;
01111                                 */
01112                         }
01113                 }
01114                 break;
01115         }
01116         if ( loseAnim != -1 )
01117         {
01118 #ifdef QAGAME
01119                 NPC_SetAnim( &g_entities[genemy->clientNum], SETANIM_BOTH, loseAnim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
01120                 genemy->weaponTime = genemy->torsoTimer;// + 250;
01121 #endif
01122                 genemy->saberBlocked = BLOCKED_NONE;
01123                 genemy->weaponstate = WEAPON_READY;
01124         }
01125         return loseAnim;
01126 }

int PM_SaberLockResultAnim playerState_t duelist,
qboolean  superBreak,
qboolean  won
 

Definition at line 1128 of file bg_saber.c.

References BLOCKED_NONE, BOTH_LK_DL_DL_S_L_1, BOTH_LK_DL_DL_S_L_2, BOTH_LK_DL_DL_T_L_1, BOTH_LK_DL_DL_T_L_2, BOTH_LK_S_S_S_L_1, BOTH_LK_S_S_S_L_2, BOTH_LK_S_S_T_L_1, BOTH_LK_S_S_T_L_2, BOTH_LK_ST_ST_S_L_1, BOTH_LK_ST_ST_S_L_2, BOTH_LK_ST_ST_T_L_1, BOTH_LK_ST_ST_T_L_2, playerState_s::clientNum, g_entities, LS_NONE, NPC_SetAnim(), playerState_t, pm, PM_SetAnim(), pmove_t::ps, playerState_s::saberBlocked, playerState_s::saberMove, SETANIM_BOTH, SETANIM_FLAG_HOLD, SETANIM_FLAG_OVERRIDE, playerState_s::torsoAnim, playerState_s::torsoTimer, and playerState_s::weaponTime.

Referenced by PM_SaberLockBreak().

01129 {
01130         int baseAnim = duelist->torsoAnim;
01131         switch ( baseAnim )
01132         {
01133         case BOTH_LK_S_S_S_L_2:         //lock if I'm using single vs. a single and other intitiated
01134                 baseAnim = BOTH_LK_S_S_S_L_1;
01135                 break;
01136         case BOTH_LK_S_S_T_L_2:         //lock if I'm using single vs. a single and other initiated
01137                 baseAnim = BOTH_LK_S_S_T_L_1;
01138                 break;
01139         case BOTH_LK_DL_DL_S_L_2:       //lock if I'm using dual vs. dual and other initiated
01140                 baseAnim = BOTH_LK_DL_DL_S_L_1;
01141                 break;
01142         case BOTH_LK_DL_DL_T_L_2:       //lock if I'm using dual vs. dual and other initiated
01143                 baseAnim = BOTH_LK_DL_DL_T_L_1;
01144                 break;
01145         case BOTH_LK_ST_ST_S_L_2:       //lock if I'm using staff vs. a staff and other initiated
01146                 baseAnim = BOTH_LK_ST_ST_S_L_1;
01147                 break;
01148         case BOTH_LK_ST_ST_T_L_2:       //lock if I'm using staff vs. a staff and other initiated
01149                 baseAnim = BOTH_LK_ST_ST_T_L_1;
01150                 break;
01151         }
01152         //what kind of break?
01153         if ( !superBreak )
01154         { 
01155                 baseAnim -= 2;
01156         }
01157         else if ( superBreak )
01158         {
01159                 baseAnim += 1;
01160         }
01161         else
01162         {//WTF?  Not a valid result
01163                 return -1;
01164         }
01165         //win or lose?
01166         if ( won )
01167         {
01168                 baseAnim += 1;
01169         }
01170 
01171         //play the anim and hold it
01172 #ifdef QAGAME
01173         //server-side: set it on the other guy, too
01174         if ( duelist->clientNum == pm->ps->clientNum )
01175         {//me
01176                 PM_SetAnim( SETANIM_BOTH, baseAnim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0 );
01177         }
01178         else
01179         {//other guy
01180                 NPC_SetAnim( &g_entities[duelist->clientNum], SETANIM_BOTH, baseAnim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
01181         }
01182 #else
01183         PM_SetAnim( SETANIM_BOTH, baseAnim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0 );
01184 #endif
01185 
01186         if ( superBreak
01187                 && !won )
01188         {//if you lose a superbreak, you're defenseless
01189                 /*
01190                 //Taken care of in SetSaberBoxSize()
01191                 //make saberent not block
01192                 gentity_t *saberent = &g_entities[duelist->client->ps.saberEntityNum];
01193                 if ( saberent )
01194                 {
01195                         VectorClear(saberent->mins);
01196                         VectorClear(saberent->maxs);
01197                         G_SetOrigin(saberent, duelist->currentOrigin);
01198                 }
01199                 */
01200 #ifdef QAGAME
01201                 if ( 1 )
01202 #else
01203                 if ( duelist->clientNum == pm->ps->clientNum )
01204 #endif
01205                 {
01206                         //set sabermove to none
01207                         duelist->saberMove = LS_NONE;
01208                         //Hold the anim a little longer than it is
01209                         duelist->torsoTimer += 250;
01210                 }
01211         }
01212 
01213 #ifdef QAGAME
01214         if ( 1 )
01215 #else
01216         if ( duelist->clientNum == pm->ps->clientNum )
01217 #endif
01218         {
01219                 //no attacking during this anim
01220                 duelist->weaponTime = duelist->torsoTimer;
01221                 duelist->saberBlocked = BLOCKED_NONE;
01222                 /*
01223                 if ( superBreak
01224                         && won
01225                         && baseAnim != BOTH_LK_ST_DL_T_SB_1_W )
01226                 {//going to attack with saber, do a saber trail
01227                         duelist->client->ps.SaberActivateTrail( 200 );
01228                 }
01229                 */
01230         }
01231         return baseAnim;
01232 }

int PM_SaberLockWinAnim qboolean  victory,
qboolean  superBreak
 

Definition at line 891 of file bg_saber.c.

References BLOCKED_NONE, BLOCKED_PARRY_BROKEN, BOTH_A3_T__B_, BOTH_BF1BREAK, BOTH_BF1LOCK, BOTH_BF2LOCK, BOTH_CCWCIRCLEBREAK, BOTH_CCWCIRCLELOCK, BOTH_CWCIRCLEBREAK, BOTH_CWCIRCLELOCK, BOTH_K1_S1_T_, BOTH_KNOCKDOWN4, BOTH_LK_S_S_S_SB_1_W, BOTH_LK_S_S_T_SB_1_W, BOTH_V1_BL_S1, BOTH_V1_BR_S1, LS_A_T2B, LS_K1_T_, LS_V1_BL, LS_V1_BR, pm, PM_SetAnim(), pmove_t::ps, playerState_s::saberBlocked, playerState_s::saberMove, SETANIM_BOTH, SETANIM_FLAG_HOLD, SETANIM_FLAG_OVERRIDE, playerState_s::torsoAnim, playerState_s::torsoTimer, WEAPON_FIRING, playerState_s::weaponstate, and playerState_s::weaponTime.

Referenced by PM_SaberLockBreak().

00892 {
00893         int winAnim = -1;
00894         switch ( pm->ps->torsoAnim )
00895         {
00896 /*
00897         default:
00898 #ifndef FINAL_BUILD
00899                 Com_Printf( S_COLOR_RED"ERROR-PM_SaberLockBreak: %s not in saberlock anim, anim = (%d)%s\n", pm->gent->NPC_type, pm->ps->torsoAnim, animTable[pm->ps->torsoAnim].name );
00900 #endif
00901 */
00902         case BOTH_BF2LOCK:
00903                 if ( superBreak )
00904                 {
00905                         winAnim = BOTH_LK_S_S_T_SB_1_W;
00906                 }
00907                 else if ( !victory )
00908                 {
00909                         winAnim = BOTH_BF1BREAK;
00910                 }
00911                 else
00912                 {
00913                         pm->ps->saberMove = LS_A_T2B;
00914                         winAnim = BOTH_A3_T__B_;
00915                 }
00916                 break;
00917         case BOTH_BF1LOCK:
00918                 if ( superBreak )
00919                 {
00920                         winAnim = BOTH_LK_S_S_T_SB_1_W;
00921                 }
00922                 else if ( !victory )
00923                 {
00924                         winAnim = BOTH_KNOCKDOWN4;
00925                 }
00926                 else
00927                 {
00928                         pm->ps->saberMove = LS_K1_T_;
00929                         winAnim = BOTH_K1_S1_T_;
00930                 }
00931                 break;
00932         case BOTH_CWCIRCLELOCK:
00933                 if ( superBreak )
00934                 {
00935                         winAnim = BOTH_LK_S_S_S_SB_1_W;
00936                 }
00937                 else if ( !victory )
00938                 {
00939                         pm->ps->saberMove = LS_V1_BL;//pm->ps->saberBounceMove = 
00940                         pm->ps->saberBlocked = BLOCKED_PARRY_BROKEN;
00941                         winAnim = BOTH_V1_BL_S1;
00942                 }
00943                 else
00944                 {
00945                         winAnim = BOTH_CWCIRCLEBREAK;
00946                 }
00947                 break;
00948         case BOTH_CCWCIRCLELOCK:
00949                 if ( superBreak )
00950                 {
00951                         winAnim = BOTH_LK_S_S_S_SB_1_W;
00952                 }
00953                 else if ( !victory )
00954                 {
00955                         pm->ps->saberMove = LS_V1_BR;//pm->ps->saberBounceMove = 
00956                         pm->ps->saberBlocked = BLOCKED_PARRY_BROKEN;
00957                         winAnim = BOTH_V1_BR_S1;
00958                 }
00959                 else
00960                 {
00961                         winAnim = BOTH_CCWCIRCLEBREAK;
00962                 }
00963                 break;
00964         default:
00965                 //must be using new system:
00966                 break;
00967         }
00968         if ( winAnim != -1 )
00969         {
00970                 PM_SetAnim( SETANIM_BOTH, winAnim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0 );
00971                 pm->ps->weaponTime = pm->ps->torsoTimer;
00972                 pm->ps->saberBlocked = BLOCKED_NONE;
00973                 pm->ps->weaponstate = WEAPON_FIRING;
00974                 /*
00975                 if ( superBreak 
00976                         && winAnim != BOTH_LK_ST_DL_T_SB_1_W )
00977                 {//going to attack with saber, do a saber trail
00978                         pm->ps->SaberActivateTrail( 200 );
00979                 }
00980                 */
00981         }
00982         return winAnim;
00983 }

saberMoveName_t PM_SaberLungeAttackMove qboolean  noSpecials  ) 
 

Definition at line 1832 of file bg_saber.c.

References AngleVectors(), BG_MySaber(), playerState_s::clientNum, EV_JUMP, playerState_s::fd, LS_A_LUNGE, LS_A_T2B, LS_INVALID, LS_NONE, LS_SPINATTACK, LS_SPINATTACK_DUAL, saberInfo_t::lungeAtkMove, NULL, PITCH, pm, PM_AddEvent(), pmove_t::ps, ROLL, forcedata_s::saberAnimLevel, saberMoveName_t, SS_FAST, SS_STAFF, vec3_t, VectorCopy, VectorScale, playerState_s::velocity, and playerState_s::viewangles.

Referenced by PM_SaberAttackForMovement().

01833 {
01834         vec3_t fwdAngles, jumpFwd;
01835         saberInfo_t *saber1 = BG_MySaber( pm->ps->clientNum, 0 );
01836         saberInfo_t *saber2 = BG_MySaber( pm->ps->clientNum, 1 );
01837         //see if we have an overridden (or cancelled) lunge move
01838         if ( saber1
01839                 && saber1->lungeAtkMove != LS_INVALID )
01840         {
01841                 if ( saber1->lungeAtkMove != LS_NONE )
01842                 {
01843                         return (saberMoveName_t)saber1->lungeAtkMove;
01844                 }
01845         }
01846         if ( saber2
01847                 && saber2->lungeAtkMove != LS_INVALID )
01848         {
01849                 if ( saber2->lungeAtkMove != LS_NONE )
01850                 {
01851                         return (saberMoveName_t)saber2->lungeAtkMove;
01852                 }
01853         }
01854         //no overrides, cancelled?
01855         if ( saber1
01856                 && saber1->lungeAtkMove == LS_NONE )
01857         {
01858                 return LS_A_T2B;//LS_NONE;
01859         }
01860         if ( saber2
01861         && saber2->lungeAtkMove == LS_NONE )
01862         {
01863                 return LS_A_T2B;//LS_NONE;
01864         }
01865         //just do it
01866         if (pm->ps->fd.saberAnimLevel == SS_FAST)
01867         {
01868                 VectorCopy( pm->ps->viewangles, fwdAngles );
01869                 fwdAngles[PITCH] = fwdAngles[ROLL] = 0;
01870                 //do the lunge
01871                 AngleVectors( fwdAngles, jumpFwd, NULL, NULL );
01872                 VectorScale( jumpFwd, 150, pm->ps->velocity );
01873                 PM_AddEvent( EV_JUMP );
01874 
01875                 return LS_A_LUNGE;
01876         }
01877         else if ( !noSpecials && pm->ps->fd.saberAnimLevel == SS_STAFF)
01878         {
01879                 return LS_SPINATTACK;
01880         }
01881         else if ( !noSpecials )
01882         {
01883                 return LS_SPINATTACK_DUAL;
01884         }
01885         return LS_A_T2B;
01886 }

qboolean PM_SaberMoveOkayForKata void   ) 
 

Definition at line 2693 of file bg_saber.c.

References LS_READY, pm, PM_SaberInStart(), pmove_t::ps, qboolean, qfalse, qtrue, and playerState_s::saberMove.

Referenced by PM_CanDoKata().

02694 {
02695         if ( pm->ps->saberMove == LS_READY
02696                 || PM_SaberInStart( pm->ps->saberMove ) )
02697         {
02698                 return qtrue;
02699         }
02700         else
02701         {
02702                 return qfalse;
02703         }
02704 }

int PM_SaberMoveQuadrantForMovement usercmd_t ucmd  ) 
 

Definition at line 650 of file bg_saber.c.

References usercmd_s::forwardmove, Q_BL, Q_BR, Q_L, Q_R, Q_T, Q_TL, Q_TR, usercmd_s::rightmove, ucmd, and usercmd_t.

Referenced by PM_WeaponLightsaber().

00651 {
00652         if ( ucmd->rightmove > 0 )
00653         {//moving right
00654                 if ( ucmd->forwardmove > 0 )
00655                 {//forward right = TL2BR slash
00656                         return Q_TL;
00657                 }
00658                 else if ( ucmd->forwardmove < 0 )
00659                 {//backward right = BL2TR uppercut
00660                         return Q_BL;
00661                 }
00662                 else
00663                 {//just right is a left slice
00664                         return Q_L;
00665                 }
00666         }
00667         else if ( ucmd->rightmove < 0 )
00668         {//moving left
00669                 if ( ucmd->forwardmove > 0 )
00670                 {//forward left = TR2BL slash
00671                         return Q_TR;
00672                 }
00673                 else if ( ucmd->forwardmove < 0 )
00674                 {//backward left = BR2TL uppercut
00675                         return Q_BR;
00676                 }
00677                 else
00678                 {//just left is a right slice
00679                         return Q_R;
00680                 }
00681         }
00682         else
00683         {//not moving left or right
00684                 if ( ucmd->forwardmove > 0 )
00685                 {//forward= T2B slash
00686                         return Q_T;
00687                 }
00688                 else if ( ucmd->forwardmove < 0 )
00689                 {//backward= T2B slash  //or B2T uppercut?
00690                         return Q_T;
00691                 }
00692                 else
00693                 {//Not moving at all
00694                         return Q_R;
00695                 }
00696         }
00697 }

qboolean PM_SaberPowerCheck void   ) 
 

Definition at line 2782 of file bg_saber.c.

References BG_EnoughForcePowerForMove(), playerState_s::fd, forcedata_s::forcePower, forcedata_s::forcePowerLevel, forcePowerNeeded, FP_SABERTHROW, pm, pmove_t::ps, qboolean, qfalse, qtrue, and playerState_s::saberInFlight.

Referenced by PM_WeaponLightsaber().

02783 {
02784         if (pm->ps->saberInFlight)
02785         { //so we don't keep doing stupid force out thing while guiding saber.
02786                 if (pm->ps->fd.forcePower > forcePowerNeeded[pm->ps->fd.forcePowerLevel[FP_SABERTHROW]][FP_SABERTHROW])
02787                 {
02788                         return qtrue;
02789                 }
02790         }
02791         else
02792         {
02793                 return BG_EnoughForcePowerForMove(forcePowerNeeded[pm->ps->fd.forcePowerLevel[FP_SABERTHROW]][FP_SABERTHROW]);
02794         }
02795 
02796         return qfalse;
02797 }

void PM_SetAnimFrame playerState_t gent,
int  frame,
qboolean  torso,
qboolean  legs
 

Definition at line 886 of file bg_saber.c.

References playerState_t, and playerState_s::saberLockFrame.

Referenced by PM_SaberLocked().

00887 {
00888         gent->saberLockFrame = frame;
00889 }

void PM_SetSaberMove short  newMove  ) 
 

Definition at line 3799 of file bg_saber.c.

References saberMoveData_t::animSetFlags, saberMoveData_t::animToUse, BG_AddPredictableEventToPlayerstate(), BG_FlippingAnim(), BG_InRoll(), BG_InSaberStandAnim(), BG_InSlopeAnim(), BG_InSpecialJump(), BG_KickMove(), BG_MySaber(), BG_SaberInAttack(), BG_SaberInIdle(), BG_SaberInSpecial(), BG_SaberInSpecialAttack(), BG_SpinningSaberAnim(), BLOCKED_NONE, saberMoveData_t::blocking, BOTH_ARIAL_LEFT, BOTH_ARIAL_RIGHT, BOTH_P1_S1_T_, BOTH_P6_S6_T_, BOTH_P7_S7_T_, BOTH_S1_S6, BOTH_S1_S7, BOTH_S6_S1, BOTH_S7_S1, BOTH_STAND1, BOTH_STAND4TOATTACK2, BOTH_WALK1, BOTH_WALKBACK1, BOTH_WALKBACK2, BROKENLIMB_LARM, BROKENLIMB_RARM, playerState_s::brokenLimbs, playerState_s::clientNum, pmove_t::cmd, saberInfo_t::drawAnim, ENTITYNUM_NONE, EV_PAIN, EV_SABER_ATTACK, playerState_s::fd, FORCE_LEVEL_1, usercmd_s::forwardmove, playerState_s::groundEntityNum, playerState_s::legsAnim, playerState_s::legsTimer, LS_A1_SPECIAL, LS_A2_SPECIAL, LS_A3_SPECIAL, LS_A_BACK, LS_A_BACK_CR, LS_A_BACKFLIP_ATK, LS_A_BACKSTAB, LS_A_FLIP_SLASH, LS_A_FLIP_STAB, LS_A_JUMP_T__B_, LS_A_LUNGE, LS_DRAW, LS_DUAL_SPIN_PROTECT, LS_JUMPATTACK_ARIAL_LEFT, LS_JUMPATTACK_ARIAL_RIGHT, LS_JUMPATTACK_CART_LEFT, LS_JUMPATTACK_CART_RIGHT, LS_JUMPATTACK_DUAL, LS_JUMPATTACK_STAFF_LEFT, LS_JUMPATTACK_STAFF_RIGHT, LS_KICK_B, LS_KICK_B_AIR, LS_KICK_F, LS_KICK_F_AIR, LS_KICK_L, LS_KICK_L_AIR, LS_KICK_R, LS_KICK_R_AIR, LS_PULL_ATTACK_STAB, LS_PULL_ATTACK_SWING, LS_PUTAWAY, LS_READY, LS_REFLECT_LL, LS_ROLL_STAB, LS_S_TL2BR, LS_SPINATTACK, LS_SPINATTACK_DUAL, LS_STABDOWN, LS_STABDOWN_DUAL, LS_STABDOWN_STAFF, LS_STAFF_SOULCAL, LS_UPSIDE_DOWN_ATTACK, LS_V1_BR, playerState_s::m_iVehicleNum, pm, PM_AddEvent(), playerState_s::pm_flags, PM_GetSaberStance(), PM_InKnockDown(), PM_irand_timesync(), PM_JumpingAnim(), PM_SaberInBrokenParry(), PM_SaberInKnockaway(), PM_SaberInParry(), PM_SaberInReflect(), PM_SetAnim(), PMF_DUCKED, pmove_t::ps, saberInfo_t::putawayAnim, usercmd_s::rightmove, SABER_ANIM_GROUP_SIZE, forcedata_s::saberAnimLevel, playerState_s::saberAttackChainCount, playerState_s::saberBlocked, playerState_s::saberBlocking, playerState_s::saberMove, saberMoveData, SETANIM_BOTH, SETANIM_FLAG_OVERRIDE, SETANIM_FLAG_RESTART, SETANIM_LEGS, SETANIM_TORSO, SS_DUAL, SS_STAFF, TORSO_DROPWEAP1, TORSO_WEAPONIDLE10, playerState_s::torsoAnim, playerState_s::torsoTimer, usercmd_s::upmove, and playerState_s::weaponTime.

Referenced by PM_FinishWeaponChange(), and PM_WeaponLightsaber().

03800 {
03801         unsigned int setflags = saberMoveData[newMove].animSetFlags;
03802         int     anim = saberMoveData[newMove].animToUse;
03803         int parts = SETANIM_TORSO;
03804 
03805         if ( newMove == LS_READY || newMove == LS_A_FLIP_STAB || newMove == LS_A_FLIP_SLASH )
03806         {//finished with a kata (or in a special move) reset attack counter
03807                 pm->ps->saberAttackChainCount = 0;
03808         }
03809         else if ( BG_SaberInAttack( newMove ) )
03810         {//continuing with a kata, increment attack counter
03811                 pm->ps->saberAttackChainCount++;
03812         }
03813 
03814         if (pm->ps->saberAttackChainCount > 16)
03815         { //for the sake of being able to send the value over the net within a reasonable bit count
03816                 pm->ps->saberAttackChainCount = 16;
03817         }
03818 
03819         if ( newMove == LS_DRAW )
03820         {
03821                 saberInfo_t *saber1 = BG_MySaber( pm->ps->clientNum, 0 );
03822                 saberInfo_t *saber2 = BG_MySaber( pm->ps->clientNum, 1 );
03823                 if ( saber1 
03824                         && saber1->drawAnim != -1 )
03825                 {
03826                         anim = saber1->drawAnim;
03827                 }
03828                 else if ( saber2 
03829                         && saber2->drawAnim != -1 )
03830                 {
03831                         anim = saber2->drawAnim;
03832                 }
03833                 else if ( pm->ps->fd.saberAnimLevel == SS_STAFF )
03834                 {
03835                         anim = BOTH_S1_S7;
03836                 }
03837                 else if ( pm->ps->fd.saberAnimLevel == SS_DUAL )
03838                 {
03839                         anim = BOTH_S1_S6;
03840                 }
03841         }
03842         else if ( newMove == LS_PUTAWAY )
03843         {
03844                 saberInfo_t *saber1 = BG_MySaber( pm->ps->clientNum, 0 );
03845                 saberInfo_t *saber2 = BG_MySaber( pm->ps->clientNum, 1 );
03846                 if ( saber1 
03847                         && saber1->putawayAnim != -1 )
03848                 {
03849                         anim = saber1->putawayAnim;
03850                 }
03851                 else if ( saber2 
03852                         && saber2->putawayAnim != -1 )
03853                 {
03854                         anim = saber2->putawayAnim;
03855                 }
03856                 else if ( pm->ps->fd.saberAnimLevel == SS_STAFF )
03857                 {
03858                         anim = BOTH_S7_S1;
03859                 }
03860                 else if ( pm->ps->fd.saberAnimLevel == SS_DUAL )
03861                 {
03862                         anim = BOTH_S6_S1;
03863                 }
03864         }
03865         else if ( pm->ps->fd.saberAnimLevel == SS_STAFF && newMove >= LS_S_TL2BR && newMove < LS_REFLECT_LL )
03866         {//staff has an entirely new set of anims, besides special attacks
03867                 //FIXME: include ready and draw/putaway?
03868                 //FIXME: get hand-made bounces and deflections?
03869                 if ( newMove >= LS_V1_BR && newMove <= LS_REFLECT_LL )
03870                 {//there aren't 1-7, just 1, 6 and 7, so just set it
03871                         anim = BOTH_P7_S7_T_ + (anim-BOTH_P1_S1_T_);//shift it up to the proper set
03872                 }
03873                 else
03874                 {//add the appropriate animLevel
03875                         anim += (pm->ps->fd.saberAnimLevel-FORCE_LEVEL_1) * SABER_ANIM_GROUP_SIZE;
03876                 }
03877         }
03878         else if ( pm->ps->fd.saberAnimLevel == SS_DUAL && newMove >= LS_S_TL2BR && newMove < LS_REFLECT_LL )
03879         { //akimbo has an entirely new set of anims, besides special attacks
03880                 //FIXME: include ready and draw/putaway?
03881                 //FIXME: get hand-made bounces and deflections?
03882                 if ( newMove >= LS_V1_BR && newMove <= LS_REFLECT_LL )
03883                 {//there aren't 1-7, just 1, 6 and 7, so just set it
03884                         anim = BOTH_P6_S6_T_ + (anim-BOTH_P1_S1_T_);//shift it up to the proper set
03885                 }
03886                 else
03887                 {//add the appropriate animLevel
03888                         anim += (pm->ps->fd.saberAnimLevel-FORCE_LEVEL_1) * SABER_ANIM_GROUP_SIZE;
03889                 }
03890         }
03891         /*
03892         else if ( newMove == LS_DRAW && pm->ps->SaberStaff() )
03893         {//hold saber out front as we turn it on
03894                 //FIXME: need a real "draw" anim for this (and put-away)
03895                 anim = BOTH_SABERSTAFF_STANCE;
03896         }
03897         */
03898         else if ( pm->ps->fd.saberAnimLevel > FORCE_LEVEL_1 &&
03899                  !BG_SaberInIdle( newMove ) && !PM_SaberInParry( newMove ) && !PM_SaberInKnockaway( newMove ) && !PM_SaberInBrokenParry( newMove ) && !PM_SaberInReflect( newMove ) && !BG_SaberInSpecial(newMove))
03900         {//readies, parries and reflections have only 1 level 
03901                 anim += (pm->ps->fd.saberAnimLevel-FORCE_LEVEL_1) * SABER_ANIM_GROUP_SIZE;
03902         }
03903 
03904         // If the move does the same animation as the last one, we need to force a restart...
03905         if ( saberMoveData[pm->ps->saberMove].animToUse == anim && newMove > LS_PUTAWAY)
03906         {
03907                 setflags |= SETANIM_FLAG_RESTART;
03908         }
03909 
03910         //saber torso anims should always be highest priority (4/12/02 - for special anims only)
03911         if (!pm->ps->m_iVehicleNum)
03912         { //if not riding a vehicle
03913                 if (BG_SaberInSpecial(newMove))
03914                 {
03915                         setflags |= SETANIM_FLAG_OVERRIDE;
03916                 }
03917                 /*
03918                 if ( newMove == LS_A_LUNGE 
03919                         || newMove == LS_A_JUMP_T__B_ 
03920                         || newMove == LS_A_BACKSTAB
03921                         || newMove == LS_A_BACK
03922                         || newMove == LS_A_BACK_CR
03923                         || newMove == LS_A_FLIP_STAB
03924                         || newMove == LS_A_FLIP_SLASH
03925                         || newMove == LS_JUMPATTACK_DUAL
03926                         || newMove == LS_A_BACKFLIP_ATK)
03927                 {
03928                         setflags |= SETANIM_FLAG_OVERRIDE;
03929                 }
03930                 */
03931         }
03932         if ( BG_InSaberStandAnim(anim) || anim == BOTH_STAND1 )
03933         {
03934                 anim = (pm->ps->legsAnim);
03935 
03936                 if ((anim >= BOTH_STAND1 && anim <= BOTH_STAND4TOATTACK2) ||
03937                         (anim >= TORSO_DROPWEAP1 && anim <= TORSO_WEAPONIDLE10))
03938                 { //If standing then use the special saber stand anim
03939                         anim = PM_GetSaberStance();
03940                 }
03941 
03942                 if (pm->ps->pm_flags & PMF_DUCKED)
03943                 { //Playing torso walk anims while crouched makes you look like a monkey
03944                         anim = PM_GetSaberStance();
03945                 }
03946 
03947                 if (anim == BOTH_WALKBACK1 || anim == BOTH_WALKBACK2 || anim == BOTH_WALK1)
03948                 { //normal stance when walking backward so saber doesn't look like it's cutting through leg
03949                         anim = PM_GetSaberStance();
03950                 }
03951 
03952                 if (BG_InSlopeAnim( anim ))
03953                 {
03954                         anim = PM_GetSaberStance();
03955                 }
03956 
03957                 parts = SETANIM_TORSO;
03958         }
03959 
03960         if (!pm->ps->m_iVehicleNum)
03961         { //if not riding a vehicle
03962                 if (newMove == LS_JUMPATTACK_ARIAL_RIGHT ||
03963                                 newMove == LS_JUMPATTACK_ARIAL_LEFT)
03964                 { //force only on legs
03965                         parts = SETANIM_LEGS;
03966                 }
03967                 else if ( newMove == LS_A_LUNGE 
03968                                 || newMove == LS_A_JUMP_T__B_ 
03969                                 || newMove == LS_A_BACKSTAB
03970                                 || newMove == LS_A_BACK
03971                                 || newMove == LS_A_BACK_CR
03972                                 || newMove == LS_ROLL_STAB
03973                                 || newMove == LS_A_FLIP_STAB
03974                                 || newMove == LS_A_FLIP_SLASH
03975                                 || newMove == LS_JUMPATTACK_DUAL
03976                                 || newMove == LS_JUMPATTACK_ARIAL_LEFT
03977                                 || newMove == LS_JUMPATTACK_ARIAL_RIGHT
03978                                 || newMove == LS_JUMPATTACK_CART_LEFT
03979                                 || newMove == LS_JUMPATTACK_CART_RIGHT
03980                                 || newMove == LS_JUMPATTACK_STAFF_LEFT
03981                                 || newMove == LS_JUMPATTACK_STAFF_RIGHT
03982                                 || newMove == LS_A_BACKFLIP_ATK
03983                                 || newMove == LS_STABDOWN
03984                                 || newMove == LS_STABDOWN_STAFF
03985                                 || newMove == LS_STABDOWN_DUAL
03986                                 || newMove == LS_DUAL_SPIN_PROTECT
03987                                 || newMove == LS_STAFF_SOULCAL
03988                                 || newMove == LS_A1_SPECIAL
03989                                 || newMove == LS_A2_SPECIAL
03990                                 || newMove == LS_A3_SPECIAL
03991                                 || newMove == LS_UPSIDE_DOWN_ATTACK
03992                                 || newMove == LS_PULL_ATTACK_STAB
03993                                 || newMove == LS_PULL_ATTACK_SWING
03994                                 || BG_KickMove( newMove ) )
03995                 {
03996                         parts = SETANIM_BOTH;
03997                 }
03998                 else if ( BG_SpinningSaberAnim( anim ) )
03999                 {//spins must be played on entire body
04000                         parts = SETANIM_BOTH;
04001                 }
04002                 else if ( (!pm->cmd.forwardmove&&!pm->cmd.rightmove&&!pm->cmd.upmove))
04003                 {//not trying to run, duck or jump
04004                         if ( !BG_FlippingAnim( pm->ps->legsAnim ) && 
04005                                 !BG_InRoll( pm->ps, pm->ps->legsAnim ) && 
04006                                 !PM_InKnockDown( pm->ps ) && 
04007                                 !PM_JumpingAnim( pm->ps->legsAnim ) &&
04008                                 !BG_InSpecialJump( pm->ps->legsAnim ) &&
04009                                 anim != PM_GetSaberStance() &&
04010                                 pm->ps->groundEntityNum != ENTITYNUM_NONE &&
04011                                 !(pm->ps->pm_flags & PMF_DUCKED))
04012                         {
04013                                 parts = SETANIM_BOTH;
04014                         }
04015                         else if ( !(pm->ps->pm_flags & PMF_DUCKED) 
04016                                 && ( newMove == LS_SPINATTACK_DUAL || newMove == LS_SPINATTACK ) )
04017                         {
04018                                 parts = SETANIM_BOTH;
04019                         }
04020                 }
04021 
04022                 PM_SetAnim(parts, anim, setflags, saberMoveData[newMove].blendTime);
04023                 if (parts != SETANIM_LEGS &&
04024                         (pm->ps->legsAnim == BOTH_ARIAL_LEFT ||
04025                         pm->ps->legsAnim == BOTH_ARIAL_RIGHT))
04026                 {
04027                         if (pm->ps->legsTimer > pm->ps->torsoTimer)
04028                         {
04029                                 pm->ps->legsTimer = pm->ps->torsoTimer;
04030                         }
04031                 }
04032 
04033         }
04034 
04035         if ( (pm->ps->torsoAnim) == anim )
04036         {//successfully changed anims
04037         //special check for *starting* a saber swing
04038                 //playing at attack
04039                 if ( BG_SaberInAttack( newMove ) || BG_SaberInSpecialAttack( anim ) )
04040                 {
04041                         if ( pm->ps->saberMove != newMove )
04042                         {//wasn't playing that attack before
04043                                 if ( newMove != LS_KICK_F
04044                                         && newMove != LS_KICK_B
04045                                         && newMove != LS_KICK_R
04046                                         && newMove != LS_KICK_L
04047                                         && newMove != LS_KICK_F_AIR
04048                                         && newMove != LS_KICK_B_AIR
04049                                         && newMove != LS_KICK_R_AIR
04050                                         && newMove != LS_KICK_L_AIR )
04051                                 {
04052                     PM_AddEvent(EV_SABER_ATTACK);
04053                                 }
04054 
04055                                 if (pm->ps->brokenLimbs)
04056                                 { //randomly make pain sounds with a broken arm because we are suffering.
04057                                         int iFactor = -1;
04058 
04059                                         if (pm->ps->brokenLimbs & (1<<BROKENLIMB_RARM))
04060                                         { //You're using it more. So it hurts more.
04061                                                 iFactor = 5;
04062                                         }
04063                                         else if (pm->ps->brokenLimbs & (1<<BROKENLIMB_LARM))
04064                                         {
04065                                                 iFactor = 10;
04066                                         }
04067 
04068                                         if (iFactor != -1)
04069                                         {
04070                                                 if ( !PM_irand_timesync( 0, iFactor ) )
04071                                                 {
04072                                                         BG_AddPredictableEventToPlayerstate(EV_PAIN, PM_irand_timesync( 1, 100 ), pm->ps);
04073                                                 }
04074                                         }
04075                                 }
04076                         }
04077                 }
04078 
04079                 if (BG_SaberInSpecial(newMove) &&
04080                         pm->ps->weaponTime < pm->ps->torsoTimer)
04081                 { //rww 01-02-03 - I think this will solve the issue of special attacks being interruptable, hopefully without side effects
04082                         pm->ps->weaponTime = pm->ps->torsoTimer;
04083                 }
04084 
04085                 pm->ps->saberMove = newMove;
04086                 pm->ps->saberBlocking = saberMoveData[newMove].blocking;
04087 
04088                 pm->ps->torsoAnim = anim;
04089 
04090                 if (pm->ps->weaponTime <= 0)
04091                 {
04092                         pm->ps->saberBlocked = BLOCKED_NONE;
04093                 }
04094         }
04095 }

qboolean PM_SomeoneInFront trace_t tr  ) 
 

Definition at line 1801 of file bg_saber.c.

References AngleVectors(), bgEntity_t, playerState_s::clientNum, trace_t::entityNum, ENTITYNUM_NONE, ET_NPC, ET_PLAYER, entityState_s::eType, FLIPHACK_DISTANCE, trace_t::fraction, MASK_PLAYERSOLID, playerState_s::origin, PITCH, pm, PM_BGEntForNum(), pmove_t::ps, qboolean, qfalse, qtrue, bgEntity_s::s, pmove_t::trace, vec3_t, VectorCopy, and playerState_s::viewangles.

01802 { //Also a very simplified version of the sp counterpart
01803         vec3_t flatAng;
01804         vec3_t fwd, back;
01805         vec3_t trmins = {-15, -15, -8};
01806         vec3_t trmaxs = {15, 15, 8};
01807 
01808         VectorCopy(pm->ps->viewangles, flatAng);
01809         flatAng[PITCH] = 0;
01810 
01811         AngleVectors(flatAng, fwd, 0, 0);
01812 
01813         back[0] = pm->ps->origin[0] + fwd[0]*FLIPHACK_DISTANCE;
01814         back[1] = pm->ps->origin[1] + fwd[1]*FLIPHACK_DISTANCE;
01815         back[2] = pm->ps->origin[2] + fwd[2]*FLIPHACK_DISTANCE;
01816 
01817         pm->trace(tr, pm->ps->origin, trmins, trmaxs, back, pm->ps->clientNum, MASK_PLAYERSOLID);
01818 
01819         if (tr->fraction != 1.0 && tr->entityNum >= 0 && tr->entityNum < ENTITYNUM_NONE)
01820         {
01821                 bgEntity_t *bgEnt = PM_BGEntForNum(tr->entityNum);
01822 
01823                 if (bgEnt && (bgEnt->s.eType == ET_PLAYER || bgEnt->s.eType == ET_NPC))
01824                 {
01825                         return qtrue;
01826                 }
01827         }
01828 
01829         return qfalse;
01830 }

qboolean PM_SwimmingAnim int  anim  ) 
 

Definition at line 4623 of file bg_pmove.c.

References BOTH_SWIM_IDLE1, BOTH_SWIMBACKWARD, BOTH_SWIMFORWARD, qboolean, qfalse, and qtrue.

Referenced by PM_WeaponLightsaber().

04624 {
04625         switch ( anim )
04626         {
04627         case BOTH_SWIM_IDLE1:           //# Swimming Idle 1
04628         case BOTH_SWIMFORWARD:          //# Swim forward loop
04629         case BOTH_SWIMBACKWARD:         //# Swim backward loop
04630                 return qtrue;
04631                 break;
04632         }
04633         return qfalse;
04634 }

float PM_WalkableGroundDistance void   ) 
 

Definition at line 2008 of file bg_saber.c.

References playerState_s::clientNum, trace_t::endpos, MASK_SOLID, pmove_t::maxs, MIN_WALK_NORMAL, pmove_t::mins, cplane_s::normal, playerState_s::origin, trace_t::plane, pm, pmove_t::ps, pmove_t::trace, vec3_t, VectorCopy, and VectorSubtract.

02009 {
02010         trace_t tr;
02011         vec3_t down;
02012 
02013         VectorCopy(pm->ps->origin, down);
02014 
02015         down[2] -= 4096;
02016 
02017         pm->trace(&tr, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, MASK_SOLID);
02018 
02019         if ( tr.plane.normal[2] < MIN_WALK_NORMAL )
02020         {//can't stand on this plane
02021                 return 4096;
02022         }
02023 
02024         VectorSubtract(pm->ps->origin, tr.endpos, down);
02025 
02026         return VectorLength(down);
02027 }

qboolean PM_WalkingAnim int  anim  ) 
 

Definition at line 4580 of file bg_pmove.c.

References BOTH_WALK1, BOTH_WALK2, BOTH_WALK5, BOTH_WALK6, BOTH_WALK7, BOTH_WALK_DUAL, BOTH_WALK_STAFF, BOTH_WALKBACK1, BOTH_WALKBACK2, BOTH_WALKBACK_DUAL, BOTH_WALKBACK_STAFF, qboolean, qfalse, and qtrue.

Referenced by BG_SetAnimFinal(), and PM_WeaponLightsaber().

04581 {
04582         switch ( anim )
04583         {
04584         case BOTH_WALK1:                                //# Normal walk
04585         case BOTH_WALK2:                                //# Normal walk with saber
04586         case BOTH_WALK_STAFF:                   //# Normal walk with staff
04587         case BOTH_WALK_DUAL:                    //# Normal walk with staff
04588         case BOTH_WALK5:                                //# Tavion taunting Kyle (cin 22)
04589         case BOTH_WALK6:                                //# Slow walk for Luke (cin 12)
04590         case BOTH_WALK7:                                //# Fast walk
04591         case BOTH_WALKBACK1:                    //# Walk1 backwards
04592         case BOTH_WALKBACK2:                    //# Walk2 backwards
04593         case BOTH_WALKBACK_STAFF:               //# Walk backwards with staff
04594         case BOTH_WALKBACK_DUAL:                //# Walk backwards with dual
04595                 return qtrue;
04596                 break;
04597         }
04598         return qfalse;
04599 }

void PM_WeaponLightsaber void   ) 
 

Definition at line 2833 of file bg_saber.c.

References trace_t::allsolid, AngleVectors(), saberMoveData_t::animToUse, BG_CanUseFPNow(), BG_EnoughForcePowerForMove(), BG_FlippingAnim(), BG_ForcePowerDrain(), BG_HasYsalamiri(), BG_InRoll(), BG_InSlopeAnim(), BG_KickingAnim(), BG_MySaber(), bg_parryDebounce, BG_SaberInAttack(), BG_SabersOff(), BG_SuperBreakLoseAnim(), BG_SuperBreakWinAnim(), bgEntity_t, BLOCKED_ATK_BOUNCE, BLOCKED_BOUNCE_MOVE, BLOCKED_LOWER_LEFT, BLOCKED_LOWER_LEFT_PROJ, BLOCKED_LOWER_RIGHT, BLOCKED_LOWER_RIGHT_PROJ, BLOCKED_NONE, BLOCKED_PARRY_BROKEN, BLOCKED_TOP, BLOCKED_TOP_PROJ, BLOCKED_UPPER_LEFT, BLOCKED_UPPER_LEFT_PROJ, BLOCKED_UPPER_RIGHT, BLOCKED_UPPER_RIGHT_PROJ, BOTH_FORCELEAP2_T__B_, BOTH_FORCELONGLEAP_ATTACK, BOTH_FORCELONGLEAP_LAND, BOTH_FORCELONGLEAP_START, BOTH_ROLL_F, BOTH_RUN1, BOTH_RUN2, BOTH_RUN_DUAL, BOTH_RUN_STAFF, BOTH_RUNBACK1, BOTH_RUNBACK2, BOTH_RUNBACK_STAFF, BOTH_SABERDUAL_STANCE, BOTH_SABERPULL, BOTH_STAND1, BOTH_WALK1, BOTH_WALK2, BOTH_WALK_DUAL, BOTH_WALK_STAFF, BOTH_WALKBACK1, BOTH_WALKBACK2, BOTH_WALKBACK_DUAL, BOTH_WALKBACK_STAFF, BUTTON_ALT_ATTACK, BUTTON_ATTACK, usercmd_s::buttons, saberMoveData_t::chain_attack, saberMoveData_t::chain_idle, playerState_s::clientNum, pmove_t::cmd, playerState_s::duelTime, saberMoveData_t::endQuad, ENTITYNUM_NONE, EV_SABER_UNHOLSTER, playerState_s::fd, playerState_s::forceHandExtend, forcedata_s::forcePower, forcedata_s::forcePowerLevel, forcePowerNeeded, usercmd_s::forwardmove, FP_GRIP, FP_SABER_DEFENSE, FP_SABERTHROW, trace_t::fraction, pmove_t::gametype, playerState_s::groundEntityNum, HANDEXTEND_NONE, saberInfo_t::kataMove, playerState_s::legsAnim, playerState_s::legsTimer, LS_A1_SPECIAL, LS_A2_SPECIAL, LS_A3_SPECIAL, LS_A_BL2TR, LS_A_BR2TL, LS_A_JUMP_T__B_, LS_A_T2B, LS_A_TL2BR, LS_A_TR2BL, LS_DUAL_SPIN_PROTECT, LS_INVALID, LS_KICK_B, LS_KICK_B_AIR, LS_KICK_F, LS_KICK_F_AIR, LS_KICK_L, LS_KICK_L_AIR, LS_KICK_R, LS_KICK_R_AIR, LS_LEAP_ATTACK, LS_MOVE_MAX, LS_NONE, LS_PARRY_LL, LS_PARRY_LR, LS_PARRY_UL, LS_PARRY_UP, LS_PARRY_UR, LS_R_BL2TR, LS_R_BR2TL, LS_R_T2B, LS_R_TL2BR, LS_READY, LS_REFLECT_LL, LS_REFLECT_LR, LS_REFLECT_UL, LS_REFLECT_UP, LS_REFLECT_UR, LS_ROLL_STAB, LS_S_T2B, LS_S_TL2BR, LS_STAFF_SOULCAL, LS_T1_BR__R, playerState_s::m_iVehicleNum, MASK_PLAYERSOLID, pml_t::msec, NULL, playerState_s::origin, bgEntity_s::playerState, playerState_t, pm, PM_AddEvent(), PM_BeginWeaponChange(), PM_BGEntForNum(), PM_BrokenParryForParry(), PM_CanDoKata(), PM_CanDoRollStab(), PM_CheckAltKickAttack(), PM_CheckPullAttack(), PM_FinishWeaponChange(), playerState_s::pm_flags, PM_GetSaberStance(), PM_GroundDistance(), PM_InKnockDown(), PM_irand_timesync(), PM_JumpingAnim(), PM_KickMoveForConditions(), PM_RunningAnim(), PM_SaberAnimTransitionAnim(), PM_SaberAttackForMovement(), PM_SaberBounceForAttack(), PM_SaberInBounce(), PM_SaberInBrokenParry(), PM_SaberInReturn(), PM_SaberInTransition(), PM_SaberKataDone(), PM_SaberLockBreak(), PM_SaberLocked(), PM_SaberMoveQuadrantForMovement(), PM_SaberPowerCheck(), PM_SetAnim(), PM_SetSaberMove(), PM_SwimmingAnim(), PM_WalkingAnim(), PMF_DUCKED, pml, pmove_t::ps, Q_BL, Q_BR, Q_T, Q_TL, Q_TR, qboolean, qfalse, qtrue, usercmd_s::rightmove, SABER_ALT_ATTACK_POWER, SABER_ALT_ATTACK_POWER_FB, SABER_MIN_THROW_DIST, forcedata_s::saberAnimLevel, playerState_s::saberAttackSequence, playerState_s::saberBlocked, playerState_s::saberCanThrow, playerState_s::saberEntityNum, playerState_s::saberHolstered, playerState_s::saberInFlight, playerState_s::saberLockEnemy, playerState_s::saberLockFrame, playerState_s::saberLockTime, SABERMAXS_X, SABERMAXS_Y, SABERMAXS_Z, SABERMINS_X, SABERMINS_Y, SABERMINS_Z, playerState_s::saberMove, saberMoveData, saberMoveName_t, usercmd_s::serverTime, SETANIM_FLAG_HOLD, SETANIM_FLAG_NORMAL, SETANIM_FLAG_OVERRIDE, SETANIM_LEGS, SETANIM_TORSO, SS_DESANN, SS_DUAL, SS_FAST, SS_MEDIUM, SS_STAFF, SS_STRONG, SS_TAVION, saberMoveData_t::startQuad, trace_t::startsolid, STAT_HEALTH, playerState_s::stats, playerState_s::torsoAnim, playerState_s::torsoTimer, pmove_t::trace, transitionMove, usercmd_s::upmove, vec3_t, VectorMA, VectorSet, playerState_s::velocity, playerState_s::viewangles, usercmd_s::weapon, playerState_s::weapon, WEAPON_DROPPING, WEAPON_FIRING, WEAPON_IDLE, WEAPON_RAISING, WEAPON_READY, weaponData, playerState_s::weaponstate, and playerState_s::weaponTime.

02834 {
02835         int                     addTime,amount;
02836         qboolean        delayed_fire = qfalse;
02837         int                     anim=-1, curmove, newmove=LS_NONE;
02838 
02839         qboolean checkOnlyWeap = qfalse;
02840 
02841         if ( PM_InKnockDown( pm->ps ) || BG_InRoll( pm->ps, pm->ps->legsAnim ))
02842         {//in knockdown
02843                 // make weapon function
02844                 if ( pm->ps->weaponTime > 0 ) {
02845                         pm->ps->weaponTime -= pml.msec;
02846                         if ( pm->ps->weaponTime <= 0 )
02847                         {
02848                                 pm->ps->weaponTime = 0;
02849                         }
02850                 }
02851                 if ( pm->ps->legsAnim == BOTH_ROLL_F 
02852                         && pm->ps->legsTimer <= 250 )
02853                 {
02854                         if ( (pm->cmd.buttons&BUTTON_ATTACK) )
02855                         {
02856                                 if ( BG_EnoughForcePowerForMove(SABER_ALT_ATTACK_POWER_FB) && !pm->ps->saberInFlight )
02857                                 {
02858                                         if ( PM_CanDoRollStab() )
02859                                         {
02860                                                 //make sure the saber is on for this move!
02861                                                 if ( pm->ps->saberHolstered == 2 )
02862                                                 {//all the way off
02863                                                         pm->ps->saberHolstered = 0;
02864                                                         PM_AddEvent(EV_SABER_UNHOLSTER);
02865                                                 }
02866                                                 PM_SetSaberMove( LS_ROLL_STAB );
02867                                                 BG_ForcePowerDrain(pm->ps, FP_GRIP, SABER_ALT_ATTACK_POWER_FB);
02868                                         }
02869                                 }
02870                         }
02871                 }
02872                 return;
02873         }
02874 
02875         if ( pm->ps->saberLockTime > pm->cmd.serverTime )
02876         {
02877                 pm->ps->saberMove = LS_NONE;
02878                 PM_SaberLocked();
02879                 return;
02880         }
02881         else
02882         {
02883                 if ( /*( (pm->ps->torsoAnim) == BOTH_BF2LOCK ||
02884                                 (pm->ps->torsoAnim) == BOTH_BF1LOCK ||
02885                                 (pm->ps->torsoAnim) == BOTH_CWCIRCLELOCK ||
02886                                 (pm->ps->torsoAnim) == BOTH_CCWCIRCLELOCK ||*/
02887                                 pm->ps->saberLockFrame
02888                         )
02889                 {
02890                         if (pm->ps->saberLockEnemy < ENTITYNUM_NONE &&
02891                                 pm->ps->saberLockEnemy >= 0)
02892                         {
02893                                 bgEntity_t *bgEnt;
02894                                 playerState_t *en;
02895 
02896                                 bgEnt = PM_BGEntForNum(pm->ps->saberLockEnemy);
02897 
02898                                 if (bgEnt)
02899                                 {
02900                                         en = bgEnt->playerState;
02901 
02902                                         if (en)
02903                                         {
02904                                                 PM_SaberLockBreak(en, qfalse, 0);
02905                                                 return;
02906                                         }
02907                                 }
02908                         }
02909 
02910                         if (/* ( (pm->ps->torsoAnim) == BOTH_BF2LOCK ||
02911                                         (pm->ps->torsoAnim) == BOTH_BF1LOCK ||
02912                                         (pm->ps->torsoAnim) == BOTH_CWCIRCLELOCK ||
02913                                         (pm->ps->torsoAnim) == BOTH_CCWCIRCLELOCK ||*/
02914                                         pm->ps->saberLockFrame
02915                                 )
02916                         {
02917                                 pm->ps->torsoTimer = 0;
02918                                 PM_SetAnim(SETANIM_TORSO,BOTH_STAND1,SETANIM_FLAG_OVERRIDE, 100);
02919                                 pm->ps->saberLockFrame = 0;
02920                         }
02921                 }
02922         }
02923 
02924         if ( BG_KickingAnim( pm->ps->legsAnim ) ||
02925                 BG_KickingAnim( pm->ps->torsoAnim ))
02926         {
02927                 if ( pm->ps->legsTimer > 0 )
02928                 {//you're kicking, no interruptions
02929                         return;
02930                 }
02931                 //done?  be immeditately ready to do an attack
02932                 pm->ps->saberMove = LS_READY;
02933                 pm->ps->weaponTime = 0;
02934         }
02935 
02936         if ( BG_SuperBreakLoseAnim( pm->ps->torsoAnim )
02937                 || BG_SuperBreakWinAnim( pm->ps->torsoAnim ) )
02938         {
02939                 if ( pm->ps->torsoTimer > 0 )
02940                 {//never interrupt these
02941                         return;
02942                 }
02943         }
02944 
02945         if (BG_SabersOff( pm->ps ))
02946         {
02947                 if (pm->ps->saberMove != LS_READY)
02948                 {
02949                         PM_SetSaberMove( LS_READY );
02950                 }
02951 
02952                 if ((pm->ps->legsAnim) != (pm->ps->torsoAnim) && !BG_InSlopeAnim(pm->ps->legsAnim) &&
02953                         pm->ps->torsoTimer <= 0)
02954                 {
02955                         PM_SetAnim(SETANIM_TORSO,(pm->ps->legsAnim),SETANIM_FLAG_OVERRIDE, 100);
02956                 }
02957                 else if (BG_InSlopeAnim(pm->ps->legsAnim) && pm->ps->torsoTimer <= 0)
02958                 {
02959                         PM_SetAnim(SETANIM_TORSO,PM_GetSaberStance(),SETANIM_FLAG_OVERRIDE, 100);
02960                 }
02961 
02962                 if (pm->ps->weaponTime < 1 && ((pm->cmd.buttons & BUTTON_ALT_ATTACK) || (pm->cmd.buttons & BUTTON_ATTACK)))
02963                 {
02964                         if (pm->ps->duelTime < pm->cmd.serverTime)
02965                         {
02966                                 if (!pm->ps->m_iVehicleNum)
02967                                 { //don't let em unholster the saber by attacking while on vehicle
02968                                         pm->ps->saberHolstered = 0;
02969                                         PM_AddEvent(EV_SABER_UNHOLSTER);
02970                                 }
02971                                 else
02972                                 {
02973                                         pm->cmd.buttons &= ~BUTTON_ALT_ATTACK;
02974                                         pm->cmd.buttons &= ~BUTTON_ATTACK;
02975                                 }
02976                         }
02977                 }
02978 
02979                 if ( pm->ps->weaponTime > 0 )
02980                 {
02981                         pm->ps->weaponTime -= pml.msec;
02982                 }
02983 
02984                 checkOnlyWeap = qtrue;
02985                 goto weapChecks;
02986         }
02987 
02988         if (!pm->ps->saberEntityNum && pm->ps->saberInFlight)
02989         { //this means our saber has been knocked away
02990                 /*
02991                 if (pm->ps->saberMove != LS_READY)
02992                 {
02993                         PM_SetSaberMove( LS_READY );
02994                 }
02995 
02996                 if ((pm->ps->legsAnim) != (pm->ps->torsoAnim) && !BG_InSlopeAnim(pm->ps->legsAnim))
02997                 {
02998                         PM_SetAnim(SETANIM_TORSO,(pm->ps->legsAnim),SETANIM_FLAG_OVERRIDE, 100);
02999                 }
03000 
03001                 if (BG_InSaberStandAnim(pm->ps->torsoAnim) || pm->ps->torsoAnim == BOTH_SABERPULL)
03002                 {
03003                         PM_SetAnim(SETANIM_TORSO,BOTH_STAND1,SETANIM_FLAG_OVERRIDE, 100);
03004                 }
03005 
03006                 return;
03007                 */
03008                 //Old method, don't want to do this now because we want to finish up reflected attacks and things
03009                 //if our saber is pried out of our hands from one.
03010                 if ( pm->ps->fd.saberAnimLevel == SS_DUAL )
03011                 {
03012                         if ( pm->ps->saberHolstered > 1 )
03013                         {
03014                                 pm->ps->saberHolstered = 1;
03015                         }
03016                 }
03017                 else
03018                 {
03019                         pm->cmd.buttons &= ~BUTTON_ATTACK;
03020                 }
03021                 pm->cmd.buttons &= ~BUTTON_ALT_ATTACK;
03022         }
03023 
03024         if ( (pm->cmd.buttons & BUTTON_ALT_ATTACK) )
03025         { //might as well just check for a saber throw right here
03026                 if (pm->ps->fd.saberAnimLevel == SS_STAFF)
03027                 { //kick instead of doing a throw 
03028                         //if in a saber attack return anim, can interrupt it with a kick
03029                         if ( pm->ps->weaponTime > 0//can't fire yet
03030                                 && PM_SaberInReturn( pm->ps->saberMove )//in a saber return move - FIXME: what about transitions?
03031                                 //&& pm->ps->weaponTime <= 250//should be able to fire soon
03032                                 //&& pm->ps->torsoTimer <= 250//torso almost done
03033                                 && pm->ps->saberBlocked == BLOCKED_NONE//not interacting with any other saber
03034                                 && !(pm->cmd.buttons&BUTTON_ATTACK) )//not trying to swing the saber
03035                         {
03036                                 if ( (pm->cmd.forwardmove||pm->cmd.rightmove)//trying to kick in a specific direction
03037                                         && PM_CheckAltKickAttack() )//trying to do a kick
03038                                 {//allow them to do the kick now!
03039                                         int kickMove = PM_KickMoveForConditions();
03040                                         if (kickMove != -1)
03041                                         {
03042                                                 pm->ps->weaponTime = 0;
03043                                                 PM_SetSaberMove( kickMove );
03044                                                 return;
03045                                         }
03046                                 }
03047                         }
03048                 }
03049                 else if ( pm->ps->weaponTime < 1&&
03050                                 pm->ps->saberCanThrow &&
03051                                 //pm->ps->fd.forcePower >= forcePowerNeeded[pm->ps->fd.forcePowerLevel[FP_SABERTHROW]][FP_SABERTHROW] &&
03052                                 !BG_HasYsalamiri(pm->gametype, pm->ps) &&
03053                                 BG_CanUseFPNow(pm->gametype, pm->ps, pm->cmd.serverTime, FP_SABERTHROW) &&
03054                                 pm->ps->fd.forcePowerLevel[FP_SABERTHROW] > 0 &&
03055                                 PM_SaberPowerCheck() )
03056                 {
03057                         trace_t sabTr;
03058                         vec3_t  fwd, minFwd, sabMins, sabMaxs;
03059 
03060                         VectorSet( sabMins, SABERMINS_X, SABERMINS_Y, SABERMINS_Z );
03061                         VectorSet( sabMaxs, SABERMAXS_X, SABERMAXS_Y, SABERMAXS_Z );
03062 
03063                         AngleVectors( pm->ps->viewangles, fwd, NULL, NULL );
03064                         VectorMA( pm->ps->origin, SABER_MIN_THROW_DIST, fwd, minFwd );
03065 
03066                         pm->trace(&sabTr, pm->ps->origin, sabMins, sabMaxs, minFwd, pm->ps->clientNum, MASK_PLAYERSOLID);
03067 
03068                         if ( sabTr.allsolid || sabTr.startsolid || sabTr.fraction < 1.0f )
03069                         {//not enough room to throw
03070                         }
03071                         else
03072                         {//throw it
03073                                 //This will get set to false again once the saber makes it back to its owner game-side
03074                                 if (!pm->ps->saberInFlight)
03075                                 {
03076                                         pm->ps->fd.forcePower -= forcePowerNeeded[pm->ps->fd.forcePowerLevel[FP_SABERTHROW]][FP_SABERTHROW];
03077                                 }
03078 
03079                                 pm->ps->saberInFlight = qtrue;
03080                         }
03081                 }
03082         }
03083         
03084         if ( pm->ps->saberInFlight && pm->ps->saberEntityNum )
03085         {//guiding saber
03086                 if ( (pm->ps->fd.saberAnimLevel != SS_DUAL //not using 2 sabers
03087                           || pm->ps->saberHolstered //left one off - FIXME: saberHolstered 1 should be left one off, 0 should be both on, 2 should be both off
03088                           || (!(pm->cmd.buttons&BUTTON_ATTACK)//not trying to start an attack AND...
03089                                   && (pm->ps->torsoAnim == BOTH_SABERDUAL_STANCE//not already attacking
03090                                           || pm->ps->torsoAnim == BOTH_SABERPULL//not already attacking
03091                                           || pm->ps->torsoAnim == BOTH_STAND1//not already attacking
03092                                           || PM_RunningAnim( pm->ps->torsoAnim ) //not already attacking
03093                                           || PM_WalkingAnim( pm->ps->torsoAnim ) //not already attacking
03094                                           || PM_JumpingAnim( pm->ps->torsoAnim )//not already attacking
03095                                           || PM_SwimmingAnim( pm->ps->torsoAnim ))//not already attacking
03096                                 )
03097                           )
03098                         )
03099                 {
03100                         PM_SetAnim(SETANIM_TORSO, BOTH_SABERPULL, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 100);
03101                         pm->ps->torsoTimer = 1;
03102                         return;
03103                 }
03104         }
03105 
03106    // don't allow attack until all buttons are up
03107         //This is bad. It freezes the attack state and the animations if you hold the button after respawning, and it looks strange.
03108         /*
03109         if ( pm->ps->pm_flags & PMF_RESPAWNED ) {
03110                 return;
03111         }
03112         */
03113 
03114         // check for dead player
03115         if ( pm->ps->stats[STAT_HEALTH] <= 0 ) {
03116                 return;
03117         }
03118 
03119         /*
03120 
03121         if (pm->ps->weaponstate == WEAPON_READY ||
03122                 pm->ps->weaponstate == WEAPON_IDLE)
03123         {
03124                 if (pm->ps->saberMove != LS_READY && pm->ps->weaponTime <= 0 && !pm->ps->saberBlocked)
03125                 {
03126                         PM_SetSaberMove( LS_READY );
03127                 }
03128         }
03129 
03130         if(PM_RunningAnim(pm->ps->torsoAnim))
03131         {
03132                 if ((pm->ps->torsoAnim) != (pm->ps->legsAnim))
03133                 {
03134                         PM_SetAnim(SETANIM_TORSO,(pm->ps->legsAnim),SETANIM_FLAG_OVERRIDE, 100);
03135                 }
03136         }
03137         */
03138 
03139         // make weapon function
03140         if ( pm->ps->weaponTime > 0 )
03141         {
03142                 //check for special pull move while busy
03143                 saberMoveName_t pullmove = PM_CheckPullAttack();
03144                 if (pullmove != LS_NONE)
03145                 {
03146                         pm->ps->weaponTime = 0;
03147                         pm->ps->torsoTimer = 0;
03148                         pm->ps->legsTimer = 0;
03149                         pm->ps->forceHandExtend = HANDEXTEND_NONE;
03150                         pm->ps->weaponstate = WEAPON_READY;
03151                         PM_SetSaberMove(pullmove);
03152                         return;
03153                 }
03154 
03155                 pm->ps->weaponTime -= pml.msec;
03156 
03157                 //This was stupid and didn't work right. Looks like things are fine without it.
03158         //      if (pm->ps->saberBlocked && pm->ps->torsoAnim != saberMoveData[pm->ps->saberMove].animToUse)
03159         //      { //rww - keep him in the blocking pose until he can attack again
03160         //              PM_SetAnim(SETANIM_TORSO,saberMoveData[pm->ps->saberMove].animToUse,saberMoveData[pm->ps->saberMove].animSetFlags|SETANIM_FLAG_HOLD, saberMoveData[pm->ps->saberMove].blendTime);
03161         //              return;
03162         //      }
03163         }
03164         else
03165         {
03166                 pm->ps->weaponstate = WEAPON_READY;
03167         }
03168 
03169         // Now we react to a block action by the player's lightsaber.
03170         if ( pm->ps->saberBlocked )
03171         {
03172                 if ( pm->ps->saberBlocked >= BLOCKED_UPPER_RIGHT 
03173                         && pm->ps->saberBlocked < BLOCKED_UPPER_RIGHT_PROJ)
03174                 {//hold the parry for a bit
03175                         pm->ps->weaponTime = bg_parryDebounce[pm->ps->fd.forcePowerLevel[FP_SABER_DEFENSE]]+200;
03176                 }
03177                 switch ( pm->ps->saberBlocked )
03178                 {
03179                         case BLOCKED_BOUNCE_MOVE:
03180                                 { //act as a bounceMove and reset the saberMove instead of using a seperate value for it
03181                                         pm->ps->torsoTimer = 0;
03182                                         PM_SetSaberMove( pm->ps->saberMove );
03183                                         pm->ps->weaponTime = pm->ps->torsoTimer;
03184                                         pm->ps->saberBlocked = 0;
03185                                 }
03186                                 break;
03187                         case BLOCKED_PARRY_BROKEN:
03188                                 //whatever parry we were is in now broken, play the appropriate knocked-away anim
03189                                 {
03190                                         int nextMove;
03191 
03192                                         if ( PM_SaberInBrokenParry( pm->ps->saberMove ) )
03193                                         {//already have one...?
03194                                                 nextMove = pm->ps->saberMove;
03195                                         }
03196                                         else
03197                                         {
03198                                                 nextMove = PM_BrokenParryForParry( pm->ps->saberMove );
03199                                         }
03200                                         if ( nextMove != LS_NONE )
03201                                         {
03202                                                 PM_SetSaberMove( nextMove );
03203                                                 pm->ps->weaponTime = pm->ps->torsoTimer;
03204                                         }
03205                                         else
03206                                         {//Maybe in a knockaway?
03207                                         }
03208                                 }
03209                                 break;
03210                         case BLOCKED_ATK_BOUNCE:
03211                                 // If there is absolutely no blocked move in the chart, don't even mess with the animation.
03212                                 // OR if we are already in a block or parry.
03213                                 if (pm->ps->saberMove >= LS_T1_BR__R)
03214                                 {//an actual bounce?  Other bounces before this are actually transitions?
03215                                         pm->ps->saberBlocked = BLOCKED_NONE;
03216                                 }
03217                                 else
03218                                 {
03219                                         int bounceMove;
03220 
03221                                         if ( PM_SaberInBounce( pm->ps->saberMove ) || !BG_SaberInAttack( pm->ps->saberMove ) )
03222                                         {
03223                                                 if ( pm->cmd.buttons & BUTTON_ATTACK )
03224                                                 {//transition to a new attack
03225                                                         int newQuad = PM_SaberMoveQuadrantForMovement( &pm->cmd );
03226                                                         while ( newQuad == saberMoveData[pm->ps->saberMove].startQuad )
03227                                                         {//player is still in same attack quad, don't repeat that attack because it looks bad, 
03228                                                                 //FIXME: try to pick one that might look cool?
03229                                                                 //newQuad = Q_irand( Q_BR, Q_BL );
03230                                                                 newQuad = PM_irand_timesync( Q_BR, Q_BL );
03231                                                                 //FIXME: sanity check, just in case?
03232                                                         }//else player is switching up anyway, take the new attack dir
03233                                                         bounceMove = transitionMove[saberMoveData[pm->ps->saberMove].startQuad][newQuad];
03234                                                 }
03235                                                 else
03236                                                 {//return to ready
03237                                                         if ( saberMoveData[pm->ps->saberMove].startQuad == Q_T )
03238                                                         {
03239                                                                 bounceMove = LS_R_BL2TR;
03240                                                         }
03241                                                         else if ( saberMoveData[pm->ps->saberMove].startQuad < Q_T )
03242                                                         {
03243                                                                 bounceMove = LS_R_TL2BR+saberMoveData[pm->ps->saberMove].startQuad-Q_BR;
03244                                                         }
03245                                                         else// if ( saberMoveData[pm->ps->saberMove].startQuad > Q_T )
03246                                                         {
03247                                                                 bounceMove = LS_R_BR2TL+saberMoveData[pm->ps->saberMove].startQuad-Q_TL;
03248                                                         }
03249                                                 }
03250                                         }
03251                                         else
03252                                         {//start the bounce
03253                                                 bounceMove = PM_SaberBounceForAttack( (saberMoveName_t)pm->ps->saberMove );
03254                                         }
03255 
03256                                         PM_SetSaberMove( bounceMove );
03257 
03258                                         pm->ps->weaponTime = pm->ps->torsoTimer;//+saberMoveData[bounceMove].blendTime+SABER_BLOCK_DUR;
03259 
03260                                 }
03261                                 break;
03262                         case BLOCKED_UPPER_RIGHT:
03263                                 PM_SetSaberMove( LS_PARRY_UR );
03264                                 break;
03265                         case BLOCKED_UPPER_RIGHT_PROJ:
03266                                 PM_SetSaberMove( LS_REFLECT_UR );
03267                                 break;
03268                         case BLOCKED_UPPER_LEFT:
03269                                 PM_SetSaberMove( LS_PARRY_UL );
03270                                 break;
03271                         case BLOCKED_UPPER_LEFT_PROJ:
03272                                 PM_SetSaberMove( LS_REFLECT_UL );
03273                                 break;
03274                         case BLOCKED_LOWER_RIGHT:
03275                                 PM_SetSaberMove( LS_PARRY_LR );
03276                                 break;
03277                         case BLOCKED_LOWER_RIGHT_PROJ:
03278                                 PM_SetSaberMove( LS_REFLECT_LR );
03279                                 break;
03280                         case BLOCKED_LOWER_LEFT:
03281                                 PM_SetSaberMove( LS_PARRY_LL );
03282                                 break;
03283                         case BLOCKED_LOWER_LEFT_PROJ:
03284                                 PM_SetSaberMove( LS_REFLECT_LL);
03285                                 break;
03286                         case BLOCKED_TOP:
03287                                 PM_SetSaberMove( LS_PARRY_UP );
03288                                 break;
03289                         case BLOCKED_TOP_PROJ:
03290                                 PM_SetSaberMove( LS_REFLECT_UP );
03291                                 break;
03292                         default:
03293                                 pm->ps->saberBlocked = BLOCKED_NONE;
03294                                 break;
03295                 }
03296                 if ( pm->ps->saberBlocked >= BLOCKED_UPPER_RIGHT 
03297                         && pm->ps->saberBlocked < BLOCKED_UPPER_RIGHT_PROJ)
03298                 {//hold the parry for a bit
03299                         if ( pm->ps->torsoTimer < pm->ps->weaponTime )
03300                         {
03301                                 pm->ps->torsoTimer = pm->ps->weaponTime;
03302                         }
03303                 }
03304 
03305                 //what the? I don't know why I was doing this.
03306                 /*
03307                 if (pm->ps->saberBlocked != BLOCKED_ATK_BOUNCE && pm->ps->saberBlocked != BLOCKED_PARRY_BROKEN && pm->ps->weaponTime < 1)
03308                 {
03309                         pm->ps->torsoTimer = SABER_BLOCK_DUR;
03310                         pm->ps->weaponTime = pm->ps->torsoTimer;
03311                 }
03312                 */
03313 
03314                 //clear block
03315                 pm->ps->saberBlocked = 0;
03316 
03317                 // Charging is like a lead-up before attacking again.  This is an appropriate use, or we can create a new weaponstate for blocking
03318                 pm->ps->weaponstate = WEAPON_READY;
03319 
03320                 // Done with block, so stop these active weapon branches.
03321                 return;
03322         }
03323 
03324 weapChecks:
03325         if (pm->ps->saberEntityNum)
03326         { //only check if we have our saber with us
03327                 // check for weapon change
03328                 // can't change if weapon is firing, but can change again if lowering or raising
03329                 //if ( pm->ps->weaponTime <= 0 || pm->ps->weaponstate != WEAPON_FIRING ) {
03330                 if (pm->ps->weaponTime <= 0 && pm->ps->torsoTimer <= 0)
03331                 {
03332                         if ( pm->ps->weapon != pm->cmd.weapon ) {
03333                                 PM_BeginWeaponChange( pm->cmd.weapon );
03334                         }
03335                 }
03336         }
03337 
03338         if ( PM_CanDoKata() )
03339         {
03340                 saberMoveName_t overrideMove = LS_INVALID;
03341                 saberInfo_t *saber1 = BG_MySaber( pm->ps->clientNum, 0 );
03342                 saberInfo_t *saber2 = BG_MySaber( pm->ps->clientNum, 1 );
03343                 //see if we have an overridden (or cancelled) kata move
03344                 if ( saber1 && saber1->kataMove != LS_INVALID )
03345                 {
03346                         if ( saber1->kataMove != LS_NONE )
03347                         {
03348                                 overrideMove = (saberMoveName_t)saber1->kataMove;
03349                         }
03350                 }
03351                 if ( overrideMove == LS_INVALID )
03352                 {//not overridden by first saber, check second
03353                         if ( saber2
03354                                 && saber2->kataMove != LS_INVALID )
03355                         {
03356                                 if ( saber2->kataMove != LS_NONE )
03357                                 {
03358                                         overrideMove = (saberMoveName_t)saber2->kataMove;
03359                                 }
03360                         }
03361                 }
03362                 //no overrides, cancelled?
03363                 if ( overrideMove == LS_INVALID )
03364                 {
03365                         if ( saber2
03366                                 && saber2->kataMove == LS_NONE )
03367                         {
03368                                 overrideMove = LS_NONE;
03369                         }
03370                         else if ( saber2
03371                                 && saber2->kataMove == LS_NONE )
03372                         {
03373                                 overrideMove = LS_NONE;
03374                         }
03375                 }
03376                 if ( overrideMove == LS_INVALID )
03377                 {//not overridden
03378                         //FIXME: make sure to turn on saber(s)!
03379                         switch ( pm->ps->fd.saberAnimLevel )
03380                         {
03381                         case SS_FAST:
03382                         case SS_TAVION:
03383                                 PM_SetSaberMove( LS_A1_SPECIAL );
03384                                 break;
03385                         case SS_MEDIUM:
03386                                 PM_SetSaberMove( LS_A2_SPECIAL );
03387                                 break;
03388                         case SS_STRONG:
03389                         case SS_DESANN:
03390                                 PM_SetSaberMove( LS_A3_SPECIAL );
03391                                 break;
03392                         case SS_DUAL:
03393                                 PM_SetSaberMove( LS_DUAL_SPIN_PROTECT );//PM_CheckDualSpinProtect();
03394                                 break;
03395                         case SS_STAFF:
03396                                 PM_SetSaberMove( LS_STAFF_SOULCAL );
03397                                 break;
03398                         }
03399                         pm->ps->weaponstate = WEAPON_FIRING;
03400                         //G_DrainPowerForSpecialMove( pm->gent, FP_SABER_OFFENSE, SABER_ALT_ATTACK_POWER );//FP_SPEED, SINGLE_SPECIAL_POWER );
03401                         BG_ForcePowerDrain(pm->ps, FP_GRIP, SABER_ALT_ATTACK_POWER);
03402                 }
03403                 else if ( overrideMove != LS_NONE )
03404                 {
03405                         PM_SetSaberMove( overrideMove );
03406                         pm->ps->weaponstate = WEAPON_FIRING;
03407                         BG_ForcePowerDrain(pm->ps, FP_GRIP, SABER_ALT_ATTACK_POWER);
03408                 }
03409                 if ( overrideMove != LS_NONE )
03410                 {//not cancelled
03411                         return;
03412                 }
03413         }
03414 
03415         if ( pm->ps->weaponTime > 0 ) 
03416         {
03417                 return;
03418         }
03419 
03420         // *********************************************************
03421         // WEAPON_DROPPING
03422         // *********************************************************
03423 
03424         // change weapon if time
03425         if ( pm->ps->weaponstate == WEAPON_DROPPING ) {
03426                 PM_FinishWeaponChange();
03427                 return;
03428         }
03429 
03430         // *********************************************************
03431         // WEAPON_RAISING
03432         // *********************************************************
03433 
03434         if ( pm->ps->weaponstate == WEAPON_RAISING ) 
03435         {//Just selected the weapon
03436                 pm->ps->weaponstate = WEAPON_IDLE;
03437                 if((pm->ps->legsAnim) == BOTH_WALK1 )
03438                 {
03439                         PM_SetAnim(SETANIM_TORSO,BOTH_WALK1,SETANIM_FLAG_NORMAL, 100);
03440                 }
03441                 else if((pm->ps->legsAnim) == BOTH_RUN1 )
03442                 {
03443                         PM_SetAnim(SETANIM_TORSO,BOTH_RUN1,SETANIM_FLAG_NORMAL, 100);
03444                 }
03445                 else if((pm->ps->legsAnim) == BOTH_RUN2 )
03446                 {
03447                         PM_SetAnim(SETANIM_TORSO,BOTH_RUN2,SETANIM_FLAG_NORMAL, 100);
03448                 }
03449                 else if( pm->ps->legsAnim == BOTH_RUN_STAFF)
03450                 {
03451                         PM_SetAnim(SETANIM_TORSO,BOTH_RUN_STAFF,SETANIM_FLAG_NORMAL, 100);
03452                 }
03453                 else if( pm->ps->legsAnim == BOTH_RUN_DUAL)
03454                 {
03455                         PM_SetAnim(SETANIM_TORSO,BOTH_RUN_DUAL,SETANIM_FLAG_NORMAL, 100);
03456                 }
03457                 else if((pm->ps->legsAnim) == BOTH_WALK1 )
03458                 {
03459                         PM_SetAnim(SETANIM_TORSO,BOTH_WALK1,SETANIM_FLAG_NORMAL, 100);
03460                 }
03461                 else if( pm->ps->legsAnim == BOTH_WALK2)
03462                 {
03463                         PM_SetAnim(SETANIM_TORSO,BOTH_WALK2,SETANIM_FLAG_NORMAL, 100);
03464                 }
03465                 else if( pm->ps->legsAnim == BOTH_WALK_STAFF)
03466                 {
03467                         PM_SetAnim(SETANIM_TORSO,BOTH_WALK_STAFF,SETANIM_FLAG_NORMAL, 100);
03468                 }
03469                 else if( pm->ps->legsAnim == BOTH_WALK_DUAL)
03470                 {
03471                         PM_SetAnim(SETANIM_TORSO,BOTH_WALK_DUAL,SETANIM_FLAG_NORMAL, 100);
03472                 }
03473                 else
03474                 {
03475                         PM_SetAnim(SETANIM_TORSO,PM_GetSaberStance(),SETANIM_FLAG_NORMAL, 100);
03476                 }
03477 
03478                 if (pm->ps->weaponstate == WEAPON_RAISING)
03479                 {
03480                         return;
03481                 }
03482 
03483         }
03484 
03485         if (checkOnlyWeap)
03486         {
03487                 return;
03488         }
03489 
03490         // *********************************************************
03491         // Check for WEAPON ATTACK
03492         // *********************************************************
03493         if (pm->ps->fd.saberAnimLevel == SS_STAFF &&
03494                 (pm->cmd.buttons & BUTTON_ALT_ATTACK))
03495         { //ok, try a kick I guess.
03496                 int kickMove = -1;
03497 
03498                 if ( !BG_KickingAnim(pm->ps->torsoAnim) &&
03499                         !BG_KickingAnim(pm->ps->legsAnim) &&
03500                         !BG_InRoll(pm->ps, pm->ps->legsAnim) &&
03501 //                      !BG_KickMove( pm->ps->saberMove )//not already in a kick
03502                         pm->ps->saberMove == LS_READY
03503                         && !(pm->ps->pm_flags&PMF_DUCKED)//not ducked
03504                         && (pm->cmd.upmove >= 0 ) //not trying to duck
03505                         )//&& pm->ps->groundEntityNum != ENTITYNUM_NONE)
03506                 {//player kicks
03507                         kickMove = PM_KickMoveForConditions();
03508                 }
03509 
03510                 if (kickMove != -1)
03511                 {
03512                         if ( pm->ps->groundEntityNum == ENTITYNUM_NONE )
03513                         {//if in air, convert kick to an in-air kick
03514                                 float gDist = PM_GroundDistance();
03515                                 //let's only allow air kicks if a certain distance from the ground
03516                                 //it's silly to be able to do them right as you land.
03517                                 //also looks wrong to transition from a non-complete flip anim...
03518                                 if ((!BG_FlippingAnim( pm->ps->legsAnim ) || pm->ps->legsTimer <= 0) &&
03519                                         gDist > 64.0f && //strict minimum
03520                                         gDist > (-pm->ps->velocity[2])-64.0f //make sure we are high to ground relative to downward velocity as well
03521                                         )
03522                                 {
03523                                         switch ( kickMove )
03524                                         {
03525                                         case LS_KICK_F:
03526                                                 kickMove = LS_KICK_F_AIR;
03527                                                 break;
03528                                         case LS_KICK_B:
03529                                                 kickMove = LS_KICK_B_AIR;
03530                                                 break;
03531                                         case LS_KICK_R:
03532                                                 kickMove = LS_KICK_R_AIR;
03533                                                 break;
03534                                         case LS_KICK_L:
03535                                                 kickMove = LS_KICK_L_AIR;
03536                                                 break;
03537                                         default: //oh well, can't do any other kick move while in-air
03538                                                 kickMove = -1;
03539                                                 break;
03540                                         }
03541                                 }
03542                                 else
03543                                 {//leave it as a normal kick unless we're too high up
03544                                         if ( gDist > 128.0f || pm->ps->velocity[2] >= 0 )
03545                                         { //off ground, but too close to ground
03546                                                 kickMove = -1;
03547                                         }
03548                                 }
03549                         }
03550 
03551                         if (kickMove != -1)
03552                         {
03553                                 PM_SetSaberMove( kickMove );
03554                                 return;
03555                         }
03556                 }
03557         }
03558 
03559         //this is never a valid regular saber attack button
03560         pm->cmd.buttons &= ~BUTTON_ALT_ATTACK;
03561 
03562         if(!delayed_fire)
03563         {
03564                 // Start with the current move, and cross index it with the current control states.
03565                 if ( pm->ps->saberMove > LS_NONE && pm->ps->saberMove < LS_MOVE_MAX )
03566                 {
03567                         curmove = pm->ps->saberMove;
03568                 }
03569                 else
03570                 {
03571                         curmove = LS_READY;
03572                 }
03573 
03574                 if ( curmove == LS_A_JUMP_T__B_ || pm->ps->torsoAnim == BOTH_FORCELEAP2_T__B_ )
03575                 {//must transition back to ready from this anim
03576                         newmove = LS_R_T2B;
03577                 }
03578                 // check for fire
03579                 else if ( !(pm->cmd.buttons & (BUTTON_ATTACK|BUTTON_ALT_ATTACK)) )
03580                 {//not attacking
03581                         pm->ps->weaponTime = 0;
03582                         
03583                         if ( pm->ps->weaponTime > 0 )
03584                         {//Still firing
03585                                 pm->ps->weaponstate = WEAPON_FIRING;
03586                         }
03587                         else if ( pm->ps->weaponstate != WEAPON_READY )
03588                         {
03589                                 pm->ps->weaponstate = WEAPON_IDLE;
03590                         }
03591                         //Check for finishing an anim if necc.
03592                         if ( curmove >= LS_S_TL2BR && curmove <= LS_S_T2B )
03593                         {//started a swing, must continue from here
03594                                 newmove = LS_A_TL2BR + (curmove-LS_S_TL2BR);
03595                         }
03596                         else if ( curmove >= LS_A_TL2BR && curmove <= LS_A_T2B )
03597                         {//finished an attack, must continue from here
03598                                 newmove = LS_R_TL2BR + (curmove-LS_A_TL2BR);
03599                         }
03600                         else if ( PM_SaberInTransition( curmove ) )
03601                         {//in a transition, must play sequential attack
03602                                 newmove = saberMoveData[curmove].chain_attack;
03603                         }
03604                         else if ( PM_SaberInBounce( curmove ) )
03605                         {//in a bounce
03606                                 newmove = saberMoveData[curmove].chain_idle;//oops, not attacking, so don't chain
03607                         }
03608                         else
03609                         {//FIXME: what about returning from a parry?
03610                                 //PM_SetSaberMove( LS_READY );
03611                                 //if ( pm->ps->saberBlockingTime > pm->cmd.serverTime )
03612                                 {
03613                                         PM_SetSaberMove( LS_READY );
03614                                 }
03615                                 return;
03616                         }
03617                 }
03618 
03619                 // ***************************************************
03620                 // Pressing attack, so we must look up the proper attack move.
03621 
03622                 if ( pm->ps->weaponTime > 0 )
03623                 {       // Last attack is not yet complete.
03624                         pm->ps->weaponstate = WEAPON_FIRING;
03625                         return;
03626                 }
03627                 else
03628                 {
03629                         int     both = qfalse;
03630                         if ( pm->ps->torsoAnim == BOTH_FORCELONGLEAP_ATTACK
03631                                 || pm->ps->torsoAnim == BOTH_FORCELONGLEAP_LAND )
03632                         {//can't attack in these anims
03633                                 return;
03634                         }
03635                         else if ( pm->ps->torsoAnim == BOTH_FORCELONGLEAP_START )
03636                         {//only 1 attack you can do from this anim
03637                                 if ( pm->ps->torsoTimer >= 200 )
03638                                 {//hit it early enough to do the attack
03639                                         PM_SetSaberMove( LS_LEAP_ATTACK );
03640                                 }
03641                                 return;
03642                         }
03643                         if ( curmove >= LS_PARRY_UP && curmove <= LS_REFLECT_LL )
03644                         {//from a parry or reflection, can go directly into an attack
03645                                 switch ( saberMoveData[curmove].endQuad )
03646                                 {
03647                                 case Q_T:
03648                                         newmove = LS_A_T2B;
03649                                         break;
03650                                 case Q_TR:
03651                                         newmove = LS_A_TR2BL;
03652                                         break;
03653                                 case Q_TL:
03654                                         newmove = LS_A_TL2BR;
03655                                         break;
03656                                 case Q_BR:
03657                                         newmove = LS_A_BR2TL;
03658                                         break;
03659                                 case Q_BL:
03660                                         newmove = LS_A_BL2TR;
03661                                         break;
03662                                 //shouldn't be a parry that ends at L, R or B
03663                                 }
03664                         }
03665 
03666                         if ( newmove != LS_NONE )
03667                         {//have a valid, final LS_ move picked, so skip findingt he transition move and just get the anim
03668                                 anim = saberMoveData[newmove].animToUse;
03669                         }
03670 
03671                         //FIXME: diagonal dirs use the figure-eight attacks from ready pose?
03672                         if ( anim == -1 )
03673                         {
03674                                 //FIXME: take FP_SABER_OFFENSE into account here somehow?
03675                                 if ( PM_SaberInTransition( curmove ) )
03676                                 {//in a transition, must play sequential attack
03677                                         newmove = saberMoveData[curmove].chain_attack;
03678                                 }
03679                                 else if ( curmove >= LS_S_TL2BR && curmove <= LS_S_T2B )
03680                                 {//started a swing, must continue from here
03681                                         newmove = LS_A_TL2BR + (curmove-LS_S_TL2BR);
03682                                 }
03683                                 else if ( PM_SaberInBrokenParry( curmove ) )
03684                                 {//broken parries must always return to ready
03685                                         newmove = LS_READY;
03686                                 }
03687                                 else//if ( pm->cmd.buttons&BUTTON_ATTACK && !(pm->ps->pm_flags&PMF_ATTACK_HELD) )//only do this if just pressed attack button?
03688                                 {//get attack move from movement command
03689                                         /*
03690                                         if ( PM_SaberKataDone() )
03691                                         {//we came from a bounce and cannot chain to another attack because our kata is done
03692                                                 newmove = saberMoveData[curmove].chain_idle;
03693                                         }
03694                                         else */
03695                                         newmove = PM_SaberAttackForMovement( curmove );
03696                                         if ( (PM_SaberInBounce( curmove )||PM_SaberInBrokenParry( curmove ))
03697                                                 && saberMoveData[newmove].startQuad == saberMoveData[curmove].endQuad )
03698                                         {//this attack would be a repeat of the last (which was blocked), so don't actually use it, use the default chain attack for this bounce
03699                                                 newmove = saberMoveData[curmove].chain_attack;
03700                                         }
03701 
03702                                         if ( PM_SaberKataDone( curmove, newmove ) )
03703                                         {//cannot chain this time
03704                                                 newmove = saberMoveData[curmove].chain_idle;
03705                                         }
03706                                 }
03707                                 /*
03708                                 if ( newmove == LS_NONE )
03709                                 {//FIXME: should we allow this?  Are there some anims that you should never be able to chain into an attack?
03710                                         //only curmove that might get in here is LS_NONE, LS_DRAW, LS_PUTAWAY and the LS_R_ returns... all of which are in Q_R
03711                                         newmove = PM_AttackMoveForQuad( saberMoveData[curmove].endQuad );
03712                                 }
03713                                 */
03714                                 if ( newmove != LS_NONE )
03715                                 {
03716                                         //Now get the proper transition move
03717                                         newmove = PM_SaberAnimTransitionAnim( curmove, newmove );
03718                                         anim = saberMoveData[newmove].animToUse;
03719                                 }
03720                         }
03721 
03722                         if (anim == -1)
03723                         {//not side-stepping, pick neutral anim
03724                                 // Add randomness for prototype?
03725                                 newmove = saberMoveData[curmove].chain_attack;
03726 
03727                                 anim= saberMoveData[newmove].animToUse;
03728 
03729                                 if ( !pm->cmd.forwardmove && !pm->cmd.rightmove && pm->cmd.upmove >= 0 && pm->ps->groundEntityNum != ENTITYNUM_NONE )
03730                                 {//not moving at all, so set the anim on entire body
03731                                         both = qtrue;
03732                                 }
03733                         
03734                         }
03735 
03736                         if ( anim == -1)
03737                         {
03738                                 switch ( pm->ps->legsAnim )
03739                                 {
03740                                 case BOTH_WALK1:
03741                                 case BOTH_WALK2:
03742                                 case BOTH_WALK_STAFF:
03743                                 case BOTH_WALK_DUAL:
03744                                 case BOTH_WALKBACK1:
03745                                 case BOTH_WALKBACK2:
03746                                 case BOTH_WALKBACK_STAFF:
03747                                 case BOTH_WALKBACK_DUAL:
03748                                 case BOTH_RUN1:
03749                                 case BOTH_RUN2:
03750                                 case BOTH_RUN_STAFF:
03751                                 case BOTH_RUN_DUAL:
03752                                 case BOTH_RUNBACK1:
03753                                 case BOTH_RUNBACK2:
03754                                 case BOTH_RUNBACK_STAFF:
03755                                         anim = pm->ps->legsAnim;
03756                                         break;
03757                                 default:
03758                                         anim = PM_GetSaberStance();
03759                                         break;
03760                                 }
03761 
03762 //                              if (PM_RunningAnim(anim) && !pm->cmd.forwardmove && !pm->cmd.rightmove)
03763 //                              { //semi-hacky (if not moving on x-y and still playing the running anim, force the player out of it)
03764 //                                      anim = PM_GetSaberStance();
03765 //                              }
03766                                 newmove = LS_READY;
03767                         }
03768 
03769                         PM_SetSaberMove( newmove );
03770 
03771                         if ( both && pm->ps->torsoAnim == anim )
03772                         {
03773                                 PM_SetAnim(SETANIM_LEGS,anim,SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 100);
03774                         }
03775 
03776                         //don't fire again until anim is done
03777                         pm->ps->weaponTime = pm->ps->torsoTimer;
03778                 }
03779         }
03780 
03781         // *********************************************************
03782         // WEAPON_FIRING
03783         // *********************************************************
03784 
03785         pm->ps->weaponstate = WEAPON_FIRING;
03786 
03787         amount = weaponData[pm->ps->weapon].energyPerShot;
03788 
03789         addTime = pm->ps->weaponTime;
03790 
03791         pm->ps->saberAttackSequence = pm->ps->torsoAnim;
03792         if ( !addTime )
03793         {
03794                 addTime = weaponData[pm->ps->weapon].fireTime;
03795         }
03796         pm->ps->weaponTime = addTime;
03797 }

qboolean ValidAnimFileIndex int  index  ) 
 


Variable Documentation

int bg_parryDebounce[NUM_FORCE_POWER_LEVELS]
 

Initial value:

{
        500,
        300,
        150,
        50
}

Definition at line 2774 of file bg_saber.c.

Referenced by Jedi_ReCalcParryTime(), and PM_WeaponLightsaber().

saberMoveData_t saberMoveData[LS_MOVE_MAX]
 

Definition at line 120 of file bg_saber.c.

Referenced by BG_BrokenParryForAttack(), CG_AddSaberBlade(), Cmd_DebugSetSaberMove_f(), PM_SaberAnimTransitionAnim(), PM_SaberAttackChainAngle(), PM_SaberAttackForMovement(), PM_SaberBounceForAttack(), PM_SetSaberMove(), and PM_WeaponLightsaber().

int saberMoveTransitionAngle[Q_NUM_QUADS][Q_NUM_QUADS]
 

Definition at line 715 of file bg_saber.c.

Referenced by PM_SaberAttackChainAngle().

int transitionMove[Q_NUM_QUADS][Q_NUM_QUADS]
 

Definition at line 324 of file bg_saber.c.

Referenced by PM_SaberAnimTransitionAnim(), and PM_WeaponLightsaber().