00001 #include "q_shared.h"
00002 #include "bg_public.h"
00003 #include "bg_local.h"
00004 #include "w_saber.h"
00005
00006 #include "../namespace_begin.h"
00007 extern qboolean BG_SabersOff( playerState_t *ps );
00008 saberInfo_t *BG_MySaber( int clientNum, int saberNum );
00009
00010 int PM_irand_timesync(int val1, int val2)
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 }
00026
00027 void BG_ForcePowerDrain( playerState_t *ps, forcePowers_t forcePower, int overrideAmt )
00028 {
00029
00030 int drain = overrideAmt;
00031
00032
00033
00034
00035
00036
00037
00038
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 {
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 {
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 }
00101
00102 qboolean BG_EnoughForcePowerForMove( int cost )
00103 {
00104 if ( pm->ps->fd.forcePower < cost )
00105 {
00106 PM_AddEvent( EV_NOAMMO );
00107 return qfalse;
00108 }
00109
00110 return qtrue;
00111 }
00112
00113
00114 #define AFLAG_IDLE (SETANIM_FLAG_NORMAL)
00115 #define AFLAG_ACTIVE (SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD | SETANIM_FLAG_HOLDLESS)
00116 #define AFLAG_WAIT (SETANIM_FLAG_HOLD | SETANIM_FLAG_HOLDLESS)
00117 #define AFLAG_FINISH (SETANIM_FLAG_HOLD)
00118
00119
00120 saberMoveData_t saberMoveData[LS_MOVE_MAX] = {
00121
00122 {"None", BOTH_STAND1, Q_R, Q_R, AFLAG_IDLE, 350, BLK_NO, LS_NONE, LS_NONE, 0 },
00123
00124
00125 {"Ready", BOTH_STAND2, Q_R, Q_R, AFLAG_IDLE, 350, BLK_WIDE, LS_READY, LS_S_R2L, 0 },
00126 {"Draw", BOTH_STAND1TO2, Q_R, Q_R, AFLAG_FINISH, 350, BLK_NO, LS_READY, LS_S_R2L, 0 },
00127 {"Putaway", BOTH_STAND2TO1, Q_R, Q_R, AFLAG_FINISH, 350, BLK_NO, LS_READY, LS_S_R2L, 0 },
00128
00129
00130
00131 {"TL2BR Att", BOTH_A1_TL_BR, Q_TL, Q_BR, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_R_TL2BR, LS_R_TL2BR, 200 },
00132
00133 {"L2R Att", BOTH_A1__L__R, Q_L, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_R_L2R, LS_R_L2R, 200 },
00134
00135 {"BL2TR Att", BOTH_A1_BL_TR, Q_BL, Q_TR, AFLAG_ACTIVE, 50, BLK_TIGHT, LS_R_BL2TR, LS_R_BL2TR, 200 },
00136
00137 {"BR2TL Att", BOTH_A1_BR_TL, Q_BR, Q_TL, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_R_BR2TL, LS_R_BR2TL, 200 },
00138
00139 {"R2L Att", BOTH_A1__R__L, Q_R, Q_L, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_R_R2L, LS_R_R2L, 200 },
00140
00141 {"TR2BL Att", BOTH_A1_TR_BL, Q_TR, Q_BL, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_R_TR2BL, LS_R_TR2BL, 200 },
00142
00143 {"T2B Att", BOTH_A1_T__B_, Q_T, Q_B, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_R_T2B, LS_R_T2B, 200 },
00144
00145 {"Back Stab", BOTH_A2_STABBACK1, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00146 {"Back Att", BOTH_ATTACK_BACK, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00147 {"CR Back Att", BOTH_CROUCHATTACKBACK1,Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00148 {"RollStab", BOTH_ROLL_STAB, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00149 {"Lunge Att", BOTH_LUNGE2_B__T_, Q_B, Q_T, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00150 {"Jump Att", BOTH_FORCELEAP2_T__B_,Q_T, Q_B, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00151 {"Flip Stab", BOTH_JUMPFLIPSTABDOWN,Q_R, Q_T, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_T1_T___R, 200 },
00152 {"Flip Slash", BOTH_JUMPFLIPSLASHDOWN1,Q_L,Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_T1__R_T_, 200 },
00153 {"DualJump Atk",BOTH_JUMPATTACK6, Q_R, Q_BL, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_T1_BL_TR, 200 },
00154
00155 {"DualJumpAtkL_A",BOTH_ARIAL_LEFT, Q_R, Q_TL, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_A_TL2BR, 200 },
00156 {"DualJumpAtkR_A",BOTH_ARIAL_RIGHT, Q_R, Q_TR, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_A_TR2BL, 200 },
00157
00158 {"DualJumpAtkL_A",BOTH_CARTWHEEL_LEFT, Q_R,Q_TL, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_T1_TL_BR, 200 },
00159 {"DualJumpAtkR_A",BOTH_CARTWHEEL_RIGHT, Q_R,Q_TR, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_T1_TR_BL, 200 },
00160
00161 {"DualJumpAtkLStaff", BOTH_BUTTERFLY_FL1,Q_R,Q_L, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_T1__L__R, 200 },
00162 {"DualJumpAtkRStaff", BOTH_BUTTERFLY_FR1,Q_R,Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_T1__R__L, 200 },
00163
00164 {"ButterflyLeft", BOTH_BUTTERFLY_LEFT,Q_R,Q_L, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_T1__L__R, 200 },
00165 {"ButterflyRight", BOTH_BUTTERFLY_RIGHT,Q_R,Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_T1__R__L, 200 },
00166
00167 {"BkFlip Atk", BOTH_JUMPATTACK7, Q_B, Q_T, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_T1_T___R, 200 },
00168 {"DualSpinAtk", BOTH_SPINATTACK6, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00169 {"StfSpinAtk", BOTH_SPINATTACK7, Q_L, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00170 {"LngLeapAtk", BOTH_FORCELONGLEAP_ATTACK,Q_R,Q_L, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00171 {"SwoopAtkR", BOTH_VS_ATR_S, Q_R, Q_T, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00172 {"SwoopAtkL", BOTH_VS_ATL_S, Q_L, Q_T, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00173 {"TauntaunAtkR",BOTH_VT_ATR_S, Q_R, Q_T, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00174 {"TauntaunAtkL",BOTH_VT_ATL_S, Q_L, Q_T, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00175 {"StfKickFwd", BOTH_A7_KICK_F, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_S_R2L, 200 },
00176 {"StfKickBack", BOTH_A7_KICK_B, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_S_R2L, 200 },
00177 {"StfKickRight",BOTH_A7_KICK_R, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_S_R2L, 200 },
00178 {"StfKickLeft", BOTH_A7_KICK_L, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_S_R2L, 200 },
00179 {"StfKickSpin", BOTH_A7_KICK_S, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_NO, LS_READY, LS_S_R2L, 200 },
00180 {"StfKickBkFwd",BOTH_A7_KICK_BF, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_NO, LS_READY, LS_S_R2L, 200 },
00181 {"StfKickSplit",BOTH_A7_KICK_RL, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_NO, LS_READY, LS_S_R2L, 200 },
00182 {"StfKickFwdAir",BOTH_A7_KICK_F_AIR,Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_S_R2L, 200 },
00183 {"StfKickBackAir",BOTH_A7_KICK_B_AIR,Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_S_R2L, 200 },
00184 {"StfKickRightAir",BOTH_A7_KICK_R_AIR,Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_S_R2L, 200 },
00185 {"StfKickLeftAir",BOTH_A7_KICK_L_AIR,Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_S_R2L, 200 },
00186 {"StabDown", BOTH_STABDOWN, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_S_R2L, 200 },
00187 {"StabDownStf", BOTH_STABDOWN_STAFF,Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_S_R2L, 200 },
00188 {"StabDownDual",BOTH_STABDOWN_DUAL, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_S_R2L, 200 },
00189 {"dualspinprot",BOTH_A6_SABERPROTECT,Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 500 },
00190 {"StfSoulCal", BOTH_A7_SOULCAL, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 500 },
00191 {"specialfast", BOTH_A1_SPECIAL, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 2000},
00192 {"specialmed", BOTH_A2_SPECIAL, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 2000},
00193 {"specialstr", BOTH_A3_SPECIAL, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 2000},
00194 {"upsidedwnatk",BOTH_FLIP_ATTACK7, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 200},
00195 {"pullatkstab", BOTH_PULL_IMPALE_STAB,Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 200},
00196 {"pullatkswing",BOTH_PULL_IMPALE_SWING,Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 200},
00197 {"AloraSpinAtk",BOTH_ALORA_SPIN_SLASH,Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00198 {"Dual FB Atk", BOTH_A6_FB, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00199 {"Dual LR Atk", BOTH_A6_LR, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00200 {"StfHiltBash", BOTH_A7_HILT, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00201
00202
00203 {"TL2BR St", BOTH_S1_S1_TL, Q_R, Q_TL, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_A_TL2BR, LS_A_TL2BR, 200 },
00204 {"L2R St", BOTH_S1_S1__L, Q_R, Q_L, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_A_L2R, LS_A_L2R, 200 },
00205 {"BL2TR St", BOTH_S1_S1_BL, Q_R, Q_BL, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_A_BL2TR, LS_A_BL2TR, 200 },
00206 {"BR2TL St", BOTH_S1_S1_BR, Q_R, Q_BR, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_A_BR2TL, LS_A_BR2TL, 200 },
00207 {"R2L St", BOTH_S1_S1__R, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_A_R2L, LS_A_R2L, 200 },
00208 {"TR2BL St", BOTH_S1_S1_TR, Q_R, Q_TR, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_A_TR2BL, LS_A_TR2BL, 200 },
00209 {"T2B St", BOTH_S1_S1_T_, Q_R, Q_T, AFLAG_ACTIVE, 100, BLK_TIGHT, LS_A_T2B, LS_A_T2B, 200 },
00210
00211
00212 {"TL2BR Ret", BOTH_R1_BR_S1, Q_BR, Q_R, AFLAG_FINISH, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00213 {"L2R Ret", BOTH_R1__R_S1, Q_R, Q_R, AFLAG_FINISH, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00214 {"BL2TR Ret", BOTH_R1_TR_S1, Q_TR, Q_R, AFLAG_FINISH, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00215 {"BR2TL Ret", BOTH_R1_TL_S1, Q_TL, Q_R, AFLAG_FINISH, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00216 {"R2L Ret", BOTH_R1__L_S1, Q_L, Q_R, AFLAG_FINISH, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00217 {"TR2BL Ret", BOTH_R1_BL_S1, Q_BL, Q_R, AFLAG_FINISH, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00218 {"T2B Ret", BOTH_R1_B__S1, Q_B, Q_R, AFLAG_FINISH, 100, BLK_TIGHT, LS_READY, LS_READY, 200 },
00219
00220
00221 {"BR2R Trans", BOTH_T1_BR__R, Q_BR, Q_R, AFLAG_ACTIVE, 100, BLK_NO, LS_R_L2R, LS_A_R2L, 150 },
00222 {"BR2TR Trans", BOTH_T1_BR_TR, Q_BR, Q_TR, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BL2TR, LS_A_TR2BL, 150 },
00223 {"BR2T Trans", BOTH_T1_BR_T_, Q_BR, Q_T, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BL2TR, LS_A_T2B, 150 },
00224 {"BR2TL Trans", BOTH_T1_BR_TL, Q_BR, Q_TL, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BR2TL, LS_A_TL2BR, 150 },
00225 {"BR2L Trans", BOTH_T1_BR__L, Q_BR, Q_L, AFLAG_ACTIVE, 100, BLK_NO, LS_R_R2L, LS_A_L2R, 150 },
00226 {"BR2BL Trans", BOTH_T1_BR_BL, Q_BR, Q_BL, AFLAG_ACTIVE, 100, BLK_NO, LS_R_TR2BL, LS_A_BL2TR, 150 },
00227 {"R2BR Trans", BOTH_T1__R_BR, Q_R, Q_BR, AFLAG_ACTIVE, 100, BLK_NO, LS_R_TL2BR, LS_A_BR2TL, 150 },
00228 {"R2TR Trans", BOTH_T1__R_TR, Q_R, Q_TR, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BL2TR, LS_A_TR2BL, 150 },
00229 {"R2T Trans", BOTH_T1__R_T_, Q_R, Q_T, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BL2TR, LS_A_T2B, 150 },
00230 {"R2TL Trans", BOTH_T1__R_TL, Q_R, Q_TL, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BR2TL, LS_A_TL2BR, 150 },
00231 {"R2L Trans", BOTH_T1__R__L, Q_R, Q_L, AFLAG_ACTIVE, 100, BLK_NO, LS_R_R2L, LS_A_L2R, 150 },
00232 {"R2BL Trans", BOTH_T1__R_BL, Q_R, Q_BL, AFLAG_ACTIVE, 100, BLK_NO, LS_R_TR2BL, LS_A_BL2TR, 150 },
00233 {"TR2BR Trans", BOTH_T1_TR_BR, Q_TR, Q_BR, AFLAG_ACTIVE, 100, BLK_NO, LS_R_TL2BR, LS_A_BR2TL, 150 },
00234 {"TR2R Trans", BOTH_T1_TR__R, Q_TR, Q_R, AFLAG_ACTIVE, 100, BLK_NO, LS_R_L2R, LS_A_R2L, 150 },
00235 {"TR2T Trans", BOTH_T1_TR_T_, Q_TR, Q_T, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BL2TR, LS_A_T2B, 150 },
00236 {"TR2TL Trans", BOTH_T1_TR_TL, Q_TR, Q_TL, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BR2TL, LS_A_TL2BR, 150 },
00237 {"TR2L Trans", BOTH_T1_TR__L, Q_TR, Q_L, AFLAG_ACTIVE, 100, BLK_NO, LS_R_R2L, LS_A_L2R, 150 },
00238 {"TR2BL Trans", BOTH_T1_TR_BL, Q_TR, Q_BL, AFLAG_ACTIVE, 100, BLK_NO, LS_R_TR2BL, LS_A_BL2TR, 150 },
00239 {"T2BR Trans", BOTH_T1_T__BR, Q_T, Q_BR, AFLAG_ACTIVE, 100, BLK_NO, LS_R_TL2BR, LS_A_BR2TL, 150 },
00240 {"T2R Trans", BOTH_T1_T___R, Q_T, Q_R, AFLAG_ACTIVE, 100, BLK_NO, LS_R_L2R, LS_A_R2L, 150 },
00241 {"T2TR Trans", BOTH_T1_T__TR, Q_T, Q_TR, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BL2TR, LS_A_TR2BL, 150 },
00242 {"T2TL Trans", BOTH_T1_T__TL, Q_T, Q_TL, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BR2TL, LS_A_TL2BR, 150 },
00243 {"T2L Trans", BOTH_T1_T___L, Q_T, Q_L, AFLAG_ACTIVE, 100, BLK_NO, LS_R_R2L, LS_A_L2R, 150 },
00244 {"T2BL Trans", BOTH_T1_T__BL, Q_T, Q_BL, AFLAG_ACTIVE, 100, BLK_NO, LS_R_TR2BL, LS_A_BL2TR, 150 },
00245 {"TL2BR Trans", BOTH_T1_TL_BR, Q_TL, Q_BR, AFLAG_ACTIVE, 100, BLK_NO, LS_R_TL2BR, LS_A_BR2TL, 150 },
00246 {"TL2R Trans", BOTH_T1_TL__R, Q_TL, Q_R, AFLAG_ACTIVE, 100, BLK_NO, LS_R_L2R, LS_A_R2L, 150 },
00247 {"TL2TR Trans", BOTH_T1_TL_TR, Q_TL, Q_TR, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BL2TR, LS_A_TR2BL, 150 },
00248 {"TL2T Trans", BOTH_T1_TL_T_, Q_TL, Q_T, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BL2TR, LS_A_T2B, 150 },
00249 {"TL2L Trans", BOTH_T1_TL__L, Q_TL, Q_L, AFLAG_ACTIVE, 100, BLK_NO, LS_R_R2L, LS_A_L2R, 150 },
00250 {"TL2BL Trans", BOTH_T1_TL_BL, Q_TL, Q_BL, AFLAG_ACTIVE, 100, BLK_NO, LS_R_TR2BL, LS_A_BL2TR, 150 },
00251 {"L2BR Trans", BOTH_T1__L_BR, Q_L, Q_BR, AFLAG_ACTIVE, 100, BLK_NO, LS_R_TL2BR, LS_A_BR2TL, 150 },
00252 {"L2R Trans", BOTH_T1__L__R, Q_L, Q_R, AFLAG_ACTIVE, 100, BLK_NO, LS_R_L2R, LS_A_R2L, 150 },
00253 {"L2TR Trans", BOTH_T1__L_TR, Q_L, Q_TR, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BL2TR, LS_A_TR2BL, 150 },
00254 {"L2T Trans", BOTH_T1__L_T_, Q_L, Q_T, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BL2TR, LS_A_T2B, 150 },
00255 {"L2TL Trans", BOTH_T1__L_TL, Q_L, Q_TL, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BR2TL, LS_A_TL2BR, 150 },
00256 {"L2BL Trans", BOTH_T1__L_BL, Q_L, Q_BL, AFLAG_ACTIVE, 100, BLK_NO, LS_R_TR2BL, LS_A_BL2TR, 150 },
00257 {"BL2BR Trans", BOTH_T1_BL_BR, Q_BL, Q_BR, AFLAG_ACTIVE, 100, BLK_NO, LS_R_TL2BR, LS_A_BR2TL, 150 },
00258 {"BL2R Trans", BOTH_T1_BL__R, Q_BL, Q_R, AFLAG_ACTIVE, 100, BLK_NO, LS_R_L2R, LS_A_R2L, 150 },
00259 {"BL2TR Trans", BOTH_T1_BL_TR, Q_BL, Q_TR, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BL2TR, LS_A_TR2BL, 150 },
00260 {"BL2T Trans", BOTH_T1_BL_T_, Q_BL, Q_T, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BL2TR, LS_A_T2B, 150 },
00261 {"BL2TL Trans", BOTH_T1_BL_TL, Q_BL, Q_TL, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BR2TL, LS_A_TL2BR, 150 },
00262 {"BL2L Trans", BOTH_T1_BL__L, Q_BL, Q_L, AFLAG_ACTIVE, 100, BLK_NO, LS_R_R2L, LS_A_L2R, 150 },
00263
00264
00265 {"Bounce BR", BOTH_B1_BR___, Q_BR, Q_BR, AFLAG_ACTIVE, 100, BLK_NO, LS_R_TL2BR, LS_T1_BR_TR, 150 },
00266 {"Bounce R", BOTH_B1__R___, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_NO, LS_R_L2R, LS_T1__R__L, 150 },
00267 {"Bounce TR", BOTH_B1_TR___, Q_TR, Q_TR, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BL2TR, LS_T1_TR_TL, 150 },
00268 {"Bounce T", BOTH_B1_T____, Q_T, Q_T, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BL2TR, LS_T1_T__BL, 150 },
00269 {"Bounce TL", BOTH_B1_TL___, Q_TL, Q_TL, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BR2TL, LS_T1_TL_TR, 150 },
00270 {"Bounce L", BOTH_B1__L___, Q_L, Q_L, AFLAG_ACTIVE, 100, BLK_NO, LS_R_R2L, LS_T1__L__R, 150 },
00271 {"Bounce BL", BOTH_B1_BL___, Q_BL, Q_BL, AFLAG_ACTIVE, 100, BLK_NO, LS_R_TR2BL, LS_T1_BL_TR, 150 },
00272
00273
00274 {"Deflect BR", BOTH_D1_BR___, Q_BR, Q_BR, AFLAG_ACTIVE, 100, BLK_NO, LS_R_TL2BR, LS_T1_BR_TR, 150 },
00275 {"Deflect R", BOTH_D1__R___, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_NO, LS_R_L2R, LS_T1__R__L, 150 },
00276 {"Deflect TR", BOTH_D1_TR___, Q_TR, Q_TR, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BL2TR, LS_T1_TR_TL, 150 },
00277 {"Deflect T", BOTH_B1_T____, Q_T, Q_T, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BL2TR, LS_T1_T__BL, 150 },
00278 {"Deflect TL", BOTH_D1_TL___, Q_TL, Q_TL, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BR2TL, LS_T1_TL_TR, 150 },
00279 {"Deflect L", BOTH_D1__L___, Q_L, Q_L, AFLAG_ACTIVE, 100, BLK_NO, LS_R_R2L, LS_T1__L__R, 150 },
00280 {"Deflect BL", BOTH_D1_BL___, Q_BL, Q_BL, AFLAG_ACTIVE, 100, BLK_NO, LS_R_TR2BL, LS_T1_BL_TR, 150 },
00281 {"Deflect B", BOTH_D1_B____, Q_B, Q_B, AFLAG_ACTIVE, 100, BLK_NO, LS_R_BL2TR, LS_T1_T__BL, 150 },
00282
00283
00284 {"Reflected BR",BOTH_V1_BR_S1, Q_BR, Q_BR, AFLAG_ACTIVE, 100, BLK_NO, LS_READY, LS_READY, 150 },
00285 {"Reflected R", BOTH_V1__R_S1, Q_R, Q_R, AFLAG_ACTIVE, 100, BLK_NO, LS_READY, LS_READY, 150 },
00286 {"Reflected TR",BOTH_V1_TR_S1, Q_TR, Q_TR, AFLAG_ACTIVE, 100, BLK_NO, LS_READY, LS_READY, 150 },
00287 {"Reflected T", BOTH_V1_T__S1, Q_T, Q_T, AFLAG_ACTIVE, 100, BLK_NO, LS_READY, LS_READY, 150 },
00288 {"Reflected TL",BOTH_V1_TL_S1, Q_TL, Q_TL, AFLAG_ACTIVE, 100, BLK_NO, LS_READY, LS_READY, 150 },
00289 {"Reflected L", BOTH_V1__L_S1, Q_L, Q_L, AFLAG_ACTIVE, 100, BLK_NO, LS_READY, LS_READY, 150 },
00290 {"Reflected BL",BOTH_V1_BL_S1, Q_BL, Q_BL, AFLAG_ACTIVE, 100, BLK_NO, LS_READY, LS_READY, 150 },
00291 {"Reflected B", BOTH_V1_B__S1, Q_B, Q_B, AFLAG_ACTIVE, 100, BLK_NO, LS_READY, LS_READY, 150 },
00292
00293
00294 {"BParry Top", BOTH_H1_S1_T_, Q_T, Q_B, AFLAG_ACTIVE, 50, BLK_NO, LS_READY, LS_READY, 150 },
00295 {"BParry UR", BOTH_H1_S1_TR, Q_TR, Q_BL, AFLAG_ACTIVE, 50, BLK_NO, LS_READY, LS_READY, 150 },
00296 {"BParry UL", BOTH_H1_S1_TL, Q_TL, Q_BR, AFLAG_ACTIVE, 50, BLK_NO, LS_READY, LS_READY, 150 },
00297 {"BParry LR", BOTH_H1_S1_BL, Q_BL, Q_TR, AFLAG_ACTIVE, 50, BLK_NO, LS_READY, LS_READY, 150 },
00298 {"BParry Bot", BOTH_H1_S1_B_, Q_B, Q_T, AFLAG_ACTIVE, 50, BLK_NO, LS_READY, LS_READY, 150 },
00299 {"BParry LL", BOTH_H1_S1_BR, Q_BR, Q_TL, AFLAG_ACTIVE, 50, BLK_NO, LS_READY, LS_READY, 150 },
00300
00301
00302 {"Knock Top", BOTH_K1_S1_T_, Q_R, Q_T, AFLAG_ACTIVE, 50, BLK_WIDE, LS_R_BL2TR, LS_T1_T__BR, 150 },
00303 {"Knock UR", BOTH_K1_S1_TR, Q_R, Q_TR, AFLAG_ACTIVE, 50, BLK_WIDE, LS_R_BL2TR, LS_T1_TR__R, 150 },
00304 {"Knock UL", BOTH_K1_S1_TL, Q_R, Q_TL, AFLAG_ACTIVE, 50, BLK_WIDE, LS_R_BR2TL, LS_T1_TL__L, 150 },
00305 {"Knock LR", BOTH_K1_S1_BL, Q_R, Q_BL, AFLAG_ACTIVE, 50, BLK_WIDE, LS_R_TL2BR, LS_T1_BL_TL, 150 },
00306 {"Knock LL", BOTH_K1_S1_BR, Q_R, Q_BR, AFLAG_ACTIVE, 50, BLK_WIDE, LS_R_TR2BL, LS_T1_BR_TR, 150 },
00307
00308
00309 {"Parry Top", BOTH_P1_S1_T_, Q_R, Q_T, AFLAG_ACTIVE, 50, BLK_WIDE, LS_R_BL2TR, LS_A_T2B, 150 },
00310 {"Parry UR", BOTH_P1_S1_TR, Q_R, Q_TL, AFLAG_ACTIVE, 50, BLK_WIDE, LS_R_BL2TR, LS_A_TR2BL, 150 },
00311 {"Parry UL", BOTH_P1_S1_TL, Q_R, Q_TR, AFLAG_ACTIVE, 50, BLK_WIDE, LS_R_BR2TL, LS_A_TL2BR, 150 },
00312 {"Parry LR", BOTH_P1_S1_BL, Q_R, Q_BR, AFLAG_ACTIVE, 50, BLK_WIDE, LS_R_TL2BR, LS_A_BR2TL, 150 },
00313 {"Parry LL", BOTH_P1_S1_BR, Q_R, Q_BL, AFLAG_ACTIVE, 50, BLK_WIDE, LS_R_TR2BL, LS_A_BL2TR, 150 },
00314
00315
00316 {"Reflect Top", BOTH_P1_S1_T_, Q_R, Q_T, AFLAG_ACTIVE, 50, BLK_WIDE, LS_R_BL2TR, LS_A_T2B, 300 },
00317 {"Reflect UR", BOTH_P1_S1_TL, Q_R, Q_TR, AFLAG_ACTIVE, 50, BLK_WIDE, LS_R_BR2TL, LS_A_TL2BR, 300 },
00318 {"Reflect UL", BOTH_P1_S1_TR, Q_R, Q_TL, AFLAG_ACTIVE, 50, BLK_WIDE, LS_R_BL2TR, LS_A_TR2BL, 300 },
00319 {"Reflect LR", BOTH_P1_S1_BR, Q_R, Q_BL, AFLAG_ACTIVE, 50, BLK_WIDE, LS_R_TR2BL, LS_A_BL2TR, 300 },
00320 {"Reflect LL", BOTH_P1_S1_BL, Q_R, Q_BR, AFLAG_ACTIVE, 50, BLK_WIDE, LS_R_TL2BR, LS_A_BR2TL, 300 },
00321 };
00322
00323
00324 int transitionMove[Q_NUM_QUADS][Q_NUM_QUADS] =
00325 {
00326 LS_NONE,
00327 LS_T1_BR__R,
00328 LS_T1_BR_TR,
00329 LS_T1_BR_T_,
00330 LS_T1_BR_TL,
00331 LS_T1_BR__L,
00332 LS_T1_BR_BL,
00333 LS_NONE,
00334 LS_T1__R_BR,
00335 LS_NONE,
00336 LS_T1__R_TR,
00337 LS_T1__R_T_,
00338 LS_T1__R_TL,
00339 LS_T1__R__L,
00340 LS_T1__R_BL,
00341 LS_NONE,
00342 LS_T1_TR_BR,
00343 LS_T1_TR__R,
00344 LS_NONE,
00345 LS_T1_TR_T_,
00346 LS_T1_TR_TL,
00347 LS_T1_TR__L,
00348 LS_T1_TR_BL,
00349 LS_NONE,
00350 LS_T1_T__BR,
00351 LS_T1_T___R,
00352 LS_T1_T__TR,
00353 LS_NONE,
00354 LS_T1_T__TL,
00355 LS_T1_T___L,
00356 LS_T1_T__BL,
00357 LS_NONE,
00358 LS_T1_TL_BR,
00359 LS_T1_TL__R,
00360 LS_T1_TL_TR,
00361 LS_T1_TL_T_,
00362 LS_NONE,
00363 LS_T1_TL__L,
00364 LS_T1_TL_BL,
00365 LS_NONE,
00366 LS_T1__L_BR,
00367 LS_T1__L__R,
00368 LS_T1__L_TR,
00369 LS_T1__L_T_,
00370 LS_T1__L_TL,
00371 LS_NONE,
00372 LS_T1__L_BL,
00373 LS_NONE,
00374 LS_T1_BL_BR,
00375 LS_T1_BL__R,
00376 LS_T1_BL_TR,
00377 LS_T1_BL_T_,
00378 LS_T1_BL_TL,
00379 LS_T1_BL__L,
00380 LS_NONE,
00381 LS_NONE,
00382 LS_T1_BL_BR,
00383 LS_T1_BR__R,
00384 LS_T1_BR_TR,
00385 LS_T1_BR_T_,
00386 LS_T1_BR_TL,
00387 LS_T1_BR__L,
00388 LS_T1_BR_BL,
00389 LS_NONE
00390 };
00391
00392 saberMoveName_t PM_AttackMoveForQuad( int quad )
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 }
00421
00422 qboolean PM_SaberKataDone(int curmove, int newmove);
00423
00424 int PM_SaberAnimTransitionAnim( int curmove, int newmove )
00425 {
00426 int retmove = newmove;
00427 if ( curmove == LS_READY )
00428 {
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
00439 retmove = LS_S_TL2BR + (newmove-LS_A_TL2BR);
00440 break;
00441 }
00442 }
00443 else
00444 {
00445 switch ( newmove )
00446 {
00447
00448 case LS_READY:
00449 switch ( curmove )
00450 {
00451
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
00460 retmove = LS_R_TL2BR + (newmove-LS_A_TL2BR);
00461 break;
00462 }
00463 break;
00464
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
00475 if ( PM_SaberKataDone( curmove, newmove ) )
00476 {
00477 retmove = LS_R_TL2BR + (newmove-LS_A_TL2BR);
00478 }
00479 else
00480 {
00481 retmove = transitionMove[saberMoveData[curmove].endQuad][saberMoveData[newmove].startQuad];
00482 }
00483 }
00484 else if ( saberMoveData[curmove].endQuad == saberMoveData[newmove].startQuad )
00485 {
00486 retmove = newmove;
00487 }
00488 else
00489 {
00490 switch ( curmove )
00491 {
00492
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
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
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
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
00568 }
00569 }
00570 break;
00571
00572 }
00573 }
00574
00575 if ( retmove == LS_NONE )
00576 {
00577 return newmove;
00578 }
00579
00580 return retmove;
00581 }
00582
00583 extern qboolean BG_InKnockDown( int anim );
00584 saberMoveName_t PM_CheckStabDown( void )
00585 {
00586 vec3_t faceFwd, facingAngles;
00587 vec3_t fwd;
00588 bgEntity_t *ent = NULL;
00589 trace_t tr;
00590
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 {
00609 return LS_NONE;
00610 }
00611 if ( pm->ps->clientNum < MAX_CLIENTS )
00612 {
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
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 {
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 }
00649
00650 int PM_SaberMoveQuadrantForMovement( usercmd_t *ucmd )
00651 {
00652 if ( ucmd->rightmove > 0 )
00653 {
00654 if ( ucmd->forwardmove > 0 )
00655 {
00656 return Q_TL;
00657 }
00658 else if ( ucmd->forwardmove < 0 )
00659 {
00660 return Q_BL;
00661 }
00662 else
00663 {
00664 return Q_L;
00665 }
00666 }
00667 else if ( ucmd->rightmove < 0 )
00668 {
00669 if ( ucmd->forwardmove > 0 )
00670 {
00671 return Q_TR;
00672 }
00673 else if ( ucmd->forwardmove < 0 )
00674 {
00675 return Q_BR;
00676 }
00677 else
00678 {
00679 return Q_R;
00680 }
00681 }
00682 else
00683 {
00684 if ( ucmd->forwardmove > 0 )
00685 {
00686 return Q_T;
00687 }
00688 else if ( ucmd->forwardmove < 0 )
00689 {
00690 return Q_T;
00691 }
00692 else
00693 {
00694 return Q_R;
00695 }
00696 }
00697 }
00698
00699
00700 qboolean PM_SaberInBounce( int move )
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 }
00712
00713 qboolean PM_SaberInTransition( int move );
00714
00715 int saberMoveTransitionAngle[Q_NUM_QUADS][Q_NUM_QUADS] =
00716 {
00717 0,
00718 45,
00719 90,
00720 135,
00721 180,
00722 215,
00723 270,
00724 45,
00725 45,
00726 0,
00727 45,
00728 90,
00729 135,
00730 180,
00731 215,
00732 90,
00733 90,
00734 45,
00735 0,
00736 45,
00737 90,
00738 135,
00739 180,
00740 135,
00741 135,
00742 90,
00743 45,
00744 0,
00745 45,
00746 90,
00747 135,
00748 180,
00749 180,
00750 135,
00751 90,
00752 45,
00753 0,
00754 45,
00755 90,
00756 135,
00757 215,
00758 180,
00759 135,
00760 90,
00761 45,
00762 0,
00763 45,
00764 90,
00765 270,
00766 215,
00767 180,
00768 135,
00769 90,
00770 45,
00771 0,
00772 45,
00773 45,
00774 90,
00775 135,
00776 180,
00777 135,
00778 90,
00779 45,
00780 0
00781 };
00782
00783 int PM_SaberAttackChainAngle( int move1, int move2 )
00784 {
00785 if ( move1 == -1 || move2 == -1 )
00786 {
00787 return -1;
00788 }
00789 return saberMoveTransitionAngle[saberMoveData[move1].endQuad][saberMoveData[move2].startQuad];
00790 }
00791
00792 qboolean PM_SaberKataDone(int curmove, int newmove)
00793 {
00794 if (pm->ps->m_iVehicleNum)
00795 {
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 {
00804 return qfalse;
00805 }
00806
00807 if ( pm->ps->fd.saberAnimLevel == SS_STAFF )
00808 {
00809
00810 return qfalse;
00811 }
00812 else if ( pm->ps->fd.saberAnimLevel == SS_DUAL )
00813 {
00814
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 {
00835 return qtrue;
00836 }
00837 else if ( chainAngle == 180 )
00838 {
00839 if ( pm->ps->saberAttackChainCount > 1 )
00840 {
00841 return qtrue;
00842 }
00843 }
00844 else
00845 {
00846 if ( pm->ps->saberAttackChainCount > 2 )
00847 {
00848 return qtrue;
00849 }
00850 }
00851 }
00852 }
00853 else
00854 {
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 {
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 }
00885
00886 void PM_SetAnimFrame( playerState_t *gent, int frame, qboolean torso, qboolean legs )
00887 {
00888 gent->saberLockFrame = frame;
00889 }
00890
00891 int PM_SaberLockWinAnim( qboolean victory, qboolean superBreak )
00892 {
00893 int winAnim = -1;
00894 switch ( pm->ps->torsoAnim )
00895 {
00896
00897
00898
00899
00900
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;
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;
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
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
00976
00977
00978
00979
00980
00981 }
00982 return winAnim;
00983 }
00984
00985
00986 #include "../namespace_end.h"
00987 #ifdef QAGAME //including game headers on cgame is FORBIDDEN ^_^
00988
00989 #include "g_local.h"
00990 extern void NPC_SetAnim(gentity_t *ent, int setAnimParts, int anim, int setAnimFlags);
00991 extern gentity_t g_entities[];
00992
00993 #elif defined CGAME
00994
00995 #include "..\cgame\cg_local.h"
00996
00997 #endif
00998 #include "../namespace_begin.h"
00999
01000 int PM_SaberLockLoseAnim( playerState_t *genemy, qboolean victory, qboolean superBreak )
01001 {
01002 int loseAnim = -1;
01003 switch ( genemy->torsoAnim )
01004 {
01005
01006
01007
01008
01009
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 {
01024 genemy->saberMove = LS_K1_T_;
01025 loseAnim = BOTH_K1_S1_T_;
01026 }
01027 else
01028 {
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 {
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;
01063 genemy->saberBlocked = BLOCKED_PARRY_BROKEN;
01064 loseAnim = BOTH_V1_BL_S1;
01065 }
01066 else
01067 {
01068 if ( !victory )
01069 {
01070 loseAnim = BOTH_CCWCIRCLEBREAK;
01071 }
01072 else
01073 {
01074 genemy->saberMove = LS_V1_BL;
01075 genemy->saberBlocked = BLOCKED_PARRY_BROKEN;
01076 loseAnim = BOTH_V1_BL_S1;
01077
01078
01079
01080
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;
01093 genemy->saberBlocked = BLOCKED_PARRY_BROKEN;
01094 loseAnim = BOTH_V1_BR_S1;
01095 }
01096 else
01097 {
01098 if ( !victory )
01099 {
01100 loseAnim = BOTH_CWCIRCLEBREAK;
01101 }
01102 else
01103 {
01104 genemy->saberMove = LS_V1_BR;
01105 genemy->saberBlocked = BLOCKED_PARRY_BROKEN;
01106 loseAnim = BOTH_V1_BR_S1;
01107
01108
01109
01110
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;
01121 #endif
01122 genemy->saberBlocked = BLOCKED_NONE;
01123 genemy->weaponstate = WEAPON_READY;
01124 }
01125 return loseAnim;
01126 }
01127
01128 int PM_SaberLockResultAnim( playerState_t *duelist, qboolean superBreak, qboolean won )
01129 {
01130 int baseAnim = duelist->torsoAnim;
01131 switch ( baseAnim )
01132 {
01133 case BOTH_LK_S_S_S_L_2:
01134 baseAnim = BOTH_LK_S_S_S_L_1;
01135 break;
01136 case BOTH_LK_S_S_T_L_2:
01137 baseAnim = BOTH_LK_S_S_T_L_1;
01138 break;
01139 case BOTH_LK_DL_DL_S_L_2:
01140 baseAnim = BOTH_LK_DL_DL_S_L_1;
01141 break;
01142 case BOTH_LK_DL_DL_T_L_2:
01143 baseAnim = BOTH_LK_DL_DL_T_L_1;
01144 break;
01145 case BOTH_LK_ST_ST_S_L_2:
01146 baseAnim = BOTH_LK_ST_ST_S_L_1;
01147 break;
01148 case BOTH_LK_ST_ST_T_L_2:
01149 baseAnim = BOTH_LK_ST_ST_T_L_1;
01150 break;
01151 }
01152
01153 if ( !superBreak )
01154 {
01155 baseAnim -= 2;
01156 }
01157 else if ( superBreak )
01158 {
01159 baseAnim += 1;
01160 }
01161 else
01162 {
01163 return -1;
01164 }
01165
01166 if ( won )
01167 {
01168 baseAnim += 1;
01169 }
01170
01171
01172 #ifdef QAGAME
01173
01174 if ( duelist->clientNum == pm->ps->clientNum )
01175 {
01176 PM_SetAnim( SETANIM_BOTH, baseAnim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0 );
01177 }
01178 else
01179 {
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 {
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200 #ifdef QAGAME
01201 if ( 1 )
01202 #else
01203 if ( duelist->clientNum == pm->ps->clientNum )
01204 #endif
01205 {
01206
01207 duelist->saberMove = LS_NONE;
01208
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
01220 duelist->weaponTime = duelist->torsoTimer;
01221 duelist->saberBlocked = BLOCKED_NONE;
01222
01223
01224
01225
01226
01227
01228
01229
01230 }
01231 return baseAnim;
01232 }
01233
01234 void PM_SaberLockBreak( playerState_t *genemy, qboolean victory, int strength )
01235 {
01236 int winAnim = BOTH_STAND1, loseAnim = BOTH_STAND1;
01237
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 {
01245 loseAnim = PM_SaberLockLoseAnim( genemy, victory, superBreak );
01246 }
01247 else
01248 {
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 {
01258 if ( pm->ps->saberLockHits && !superBreak )
01259 {
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 {
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;
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 {
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 {
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 }
01338
01339 qboolean BG_CheckIncrementLockAnim( int anim, int winOrLose )
01340 {
01341 qboolean increment = qfalse;
01342
01343
01344 switch ( anim )
01345 {
01346
01347 case BOTH_LK_DL_DL_S_L_1:
01348 case BOTH_LK_DL_DL_S_L_2:
01349 case BOTH_LK_DL_DL_T_L_1:
01350 case BOTH_LK_DL_DL_T_L_2:
01351 case BOTH_LK_DL_S_S_L_1:
01352 case BOTH_LK_DL_S_T_L_1:
01353 case BOTH_LK_DL_ST_S_L_1:
01354 case BOTH_LK_DL_ST_T_L_1:
01355 case BOTH_LK_S_S_S_L_1:
01356 case BOTH_LK_S_S_T_L_2:
01357 case BOTH_LK_ST_S_S_L_1:
01358 case BOTH_LK_ST_S_T_L_1:
01359 case BOTH_LK_ST_ST_T_L_1:
01360 case BOTH_LK_ST_ST_T_L_2:
01361 if ( winOrLose == SABERLOCK_WIN )
01362 {
01363 increment = qtrue;
01364 }
01365 else
01366 {
01367 increment = qfalse;
01368 }
01369 break;
01370
01371
01372 case BOTH_LK_S_DL_S_L_1:
01373 case BOTH_LK_S_DL_T_L_1:
01374 case BOTH_LK_S_S_S_L_2:
01375 case BOTH_LK_S_S_T_L_1:
01376 case BOTH_LK_S_ST_S_L_1:
01377 case BOTH_LK_S_ST_T_L_1:
01378 case BOTH_LK_ST_DL_S_L_1:
01379 case BOTH_LK_ST_DL_T_L_1:
01380 case BOTH_LK_ST_ST_S_L_1:
01381 case BOTH_LK_ST_ST_S_L_2:
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 }
01396
01397 extern qboolean ValidAnimFileIndex ( int index );
01398 void PM_SaberLocked( void )
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
01416
01417
01418
01419
01420
01421
01422
01423
01424
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 {
01440 PM_SaberLockBreak( genemy, qfalse, 0 );
01441 return;
01442 }
01443
01444
01445
01446
01447
01448
01449
01450
01451 if ( pm->ps->saberLockAdvance )
01452 {
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
01467 if ( BG_InSaberLockOld( pm->ps->torsoAnim ) )
01468 {
01469 if ( (pm->ps->torsoAnim) == BOTH_CCWCIRCLELOCK ||
01470 (pm->ps->torsoAnim) == BOTH_BF2LOCK )
01471 {
01472 curFrame = floor( currentFrame )-strength;
01473
01474 if ( curFrame <= anim->firstFrame )
01475 {
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
01489 if ( curFrame >= anim->firstFrame+anim->numFrames )
01490 {
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 {
01503 if ( BG_CheckIncrementLockAnim( pm->ps->torsoAnim, SABERLOCK_WIN ) )
01504 {
01505 curFrame = ceil( currentFrame )+strength;
01506
01507 if ( curFrame >= anim->firstFrame+anim->numFrames )
01508 {
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
01522 if ( curFrame <= anim->firstFrame )
01523 {
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
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 {
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 {
01576 PM_SaberLockBreak( genemy, qfalse, 0 );
01577 }
01578 }
01579
01580 qboolean PM_SaberInBrokenParry( int move )
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 }
01592
01593
01594 int PM_BrokenParryForParry( int move )
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 }
01619
01620 #define BACK_STAB_DISTANCE 128
01621
01622 qboolean PM_CanBackstab(void)
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 }
01653
01654 saberMoveName_t PM_SaberFlipOverAttackMove(void)
01655 {
01656 vec3_t fwdAngles, jumpFwd;
01657
01658
01659
01660
01661 saberInfo_t *saber1 = BG_MySaber( pm->ps->clientNum, 0 );
01662 saberInfo_t *saber2 = BG_MySaber( pm->ps->clientNum, 1 );
01663
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
01681 if ( saber1
01682 && saber1->jumpAtkFwdMove == LS_NONE )
01683 {
01684 return LS_A_T2B;
01685 }
01686 if ( saber2
01687 && saber2->jumpAtkFwdMove == LS_NONE )
01688 {
01689 return LS_A_T2B;
01690 }
01691
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 );
01696 pm->ps->velocity[2] = 400;
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734 PM_SetForceJumpZStart(pm->ps->origin[2]);
01735
01736 PM_AddEvent( EV_JUMP );
01737 pm->ps->fd.forceJumpSound = 1;
01738 pm->cmd.upmove = 0;
01739
01740
01741
01742
01743
01744
01745
01746
01747 {
01748 return LS_A_FLIP_SLASH;
01749 }
01750 }
01751
01752 int PM_SaberBackflipAttackMove( void )
01753 {
01754 saberInfo_t *saber1 = BG_MySaber( pm->ps->clientNum, 0 );
01755 saberInfo_t *saber2 = BG_MySaber( pm->ps->clientNum, 1 );
01756
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
01774 if ( saber1
01775 && saber1->jumpAtkBackMove == LS_NONE )
01776 {
01777 return LS_A_T2B;
01778 }
01779 if ( saber2
01780 && saber2->jumpAtkBackMove == LS_NONE )
01781 {
01782 return LS_A_T2B;
01783 }
01784
01785 pm->cmd.upmove = 127;
01786 pm->ps->velocity[2] = 500;
01787 return LS_A_BACKFLIP_ATK;
01788 }
01789
01790 int PM_SaberDualJumpAttackMove( void )
01791 {
01792
01793
01794
01795 pm->cmd.upmove = 0;
01796 return LS_JUMPATTACK_DUAL;
01797 }
01798
01799 #define FLIPHACK_DISTANCE 200
01800
01801 qboolean PM_SomeoneInFront(trace_t *tr)
01802 {
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 }
01831
01832 saberMoveName_t PM_SaberLungeAttackMove( qboolean noSpecials )
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
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
01855 if ( saber1
01856 && saber1->lungeAtkMove == LS_NONE )
01857 {
01858 return LS_A_T2B;
01859 }
01860 if ( saber2
01861 && saber2->lungeAtkMove == LS_NONE )
01862 {
01863 return LS_A_T2B;
01864 }
01865
01866 if (pm->ps->fd.saberAnimLevel == SS_FAST)
01867 {
01868 VectorCopy( pm->ps->viewangles, fwdAngles );
01869 fwdAngles[PITCH] = fwdAngles[ROLL] = 0;
01870
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 }
01887
01888 saberMoveName_t PM_SaberJumpAttackMove2( void )
01889 {
01890 saberInfo_t *saber1 = BG_MySaber( pm->ps->clientNum, 0 );
01891 saberInfo_t *saber2 = BG_MySaber( pm->ps->clientNum, 1 );
01892
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
01910 if ( saber1
01911 && saber1->jumpAtkFwdMove == LS_NONE )
01912 {
01913 return LS_A_T2B;
01914 }
01915 if ( saber2
01916 && saber2->jumpAtkFwdMove == LS_NONE )
01917 {
01918 return LS_A_T2B;
01919 }
01920
01921 if (pm->ps->fd.saberAnimLevel == SS_DUAL)
01922 {
01923 return PM_SaberDualJumpAttackMove();
01924 }
01925 else
01926 {
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937 {
01938 return LS_JUMPATTACK_STAFF_RIGHT;
01939 }
01940 }
01941 return LS_A_T2B;
01942 }
01943
01944 saberMoveName_t PM_SaberJumpAttackMove( void )
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
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
01967 if ( saber1
01968 && saber1->jumpAtkFwdMove == LS_NONE )
01969 {
01970 return LS_A_T2B;
01971 }
01972 if ( saber2
01973 && saber2->jumpAtkFwdMove == LS_NONE )
01974 {
01975 return LS_A_T2B;
01976 }
01977
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]);
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 }
01991
01992 float PM_GroundDistance(void)
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 }
02007
02008 float PM_WalkableGroundDistance(void)
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 {
02021 return 4096;
02022 }
02023
02024 VectorSubtract(pm->ps->origin, tr.endpos, down);
02025
02026 return VectorLength(down);
02027 }
02028
02029 qboolean BG_SaberInTransitionAny( int move );
02030 static qboolean PM_CanDoDualDoubleAttacks(void)
02031 {
02032 if ( pm->ps->weapon == WP_SABER )
02033 {
02034 saberInfo_t *saber = BG_MySaber( pm->ps->clientNum, 0 );
02035 if ( saber
02036 && (saber->saberFlags&SFL_NO_MIRROR_ATTACKS) )
02037 {
02038 return qfalse;
02039 }
02040 saber = BG_MySaber( pm->ps->clientNum, 1 );
02041 if ( saber
02042 && (saber->saberFlags&SFL_NO_MIRROR_ATTACKS) )
02043 {
02044 return qfalse;
02045 }
02046 }
02047 if (BG_SaberInSpecialAttack(pm->ps->torsoAnim) ||
02048 BG_SaberInSpecialAttack(pm->ps->legsAnim))
02049 {
02050 return qfalse;
02051 }
02052 return qtrue;
02053 }
02054
02055 static qboolean PM_CheckEnemyPresence( int dir, float radius )
02056 {
02057 vec3_t angles;
02058 vec3_t checkDir;
02059 vec3_t tTo;
02060 vec3_t tMins, tMaxs;
02061 trace_t tr;
02062 const float tSize = 12.0f;
02063
02064
02065
02066
02067 VectorSet(tMins, -tSize, -tSize, -tSize);
02068 VectorSet(tMaxs, tSize, tSize, tSize);
02069
02070 VectorCopy(pm->ps->viewangles, angles);
02071 angles[PITCH] = 0.0f;
02072
02073 switch( dir )
02074 {
02075 case DIR_RIGHT:
02076 AngleVectors( angles, NULL, checkDir, NULL );
02077 break;
02078 case DIR_LEFT:
02079 AngleVectors( angles, NULL, checkDir, NULL );
02080 VectorScale( checkDir, -1, checkDir );
02081 break;
02082 case DIR_FRONT:
02083 AngleVectors( angles, checkDir, NULL, NULL );
02084 break;
02085 case DIR_BACK:
02086 AngleVectors( angles, checkDir, NULL, NULL );
02087 VectorScale( checkDir, -1, checkDir );
02088 break;
02089 }
02090
02091 VectorMA(pm->ps->origin, radius, checkDir, tTo);
02092 pm->trace(&tr, pm->ps->origin, tMins, tMaxs, tTo, pm->ps->clientNum, MASK_PLAYERSOLID);
02093
02094 if (tr.fraction != 1.0f && tr.entityNum < ENTITYNUM_WORLD)
02095 {
02096 bgEntity_t *bgEnt = PM_BGEntForNum(tr.entityNum);
02097
02098 if (bgEnt &&
02099 (bgEnt->s.eType == ET_PLAYER || bgEnt->s.eType == ET_NPC))
02100 {
02101 return qtrue;
02102 }
02103 }
02104
02105
02106 return qfalse;
02107 }
02108
02109 #define SABER_ALT_ATTACK_POWER 50//75?
02110 #define SABER_ALT_ATTACK_POWER_LR 10//30?
02111 #define SABER_ALT_ATTACK_POWER_FB 25//30/50?
02112
02113 extern qboolean PM_SaberInReturn( int move );
02114 saberMoveName_t PM_CheckPullAttack( void )
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))
02123
02124 && pm->ps->fd.saberAnimLevel >= SS_FAST
02125 && pm->ps->fd.saberAnimLevel <= SS_STRONG
02126
02127
02128
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
02133 && (pm->cmd.buttons&BUTTON_ATTACK)
02134 && BG_EnoughForcePowerForMove( SABER_ALT_ATTACK_POWER_FB ) )
02135 {
02136 qboolean doMove = qtrue;
02137
02138
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
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
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 }
02224
02225 qboolean PM_InSecondaryStyle( void )
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 }
02237
02238 saberMoveName_t PM_SaberAttackForMovement(saberMoveName_t curmove)
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 {
02256 overrideJumpRightAttackMove = (saberMoveName_t)saber1->jumpAtkRightMove;
02257 }
02258 else if ( saber2
02259 && saber2->jumpAtkRightMove > LS_NONE )
02260 {
02261 overrideJumpRightAttackMove = (saberMoveName_t)saber2->jumpAtkRightMove;
02262 }
02263 else
02264 {
02265 overrideJumpRightAttackMove = LS_NONE;
02266 }
02267 }
02268 else if ( saber2
02269 && saber2->jumpAtkRightMove != LS_INVALID )
02270 {
02271 overrideJumpRightAttackMove = (saberMoveName_t)saber2->jumpAtkRightMove;
02272 }
02273
02274 if ( saber1
02275 && saber1->jumpAtkLeftMove != LS_INVALID )
02276 {
02277 if ( saber1->jumpAtkLeftMove != LS_NONE )
02278 {
02279 overrideJumpLeftAttackMove = (saberMoveName_t)saber1->jumpAtkLeftMove;
02280 }
02281 else if ( saber2
02282 && saber2->jumpAtkLeftMove > LS_NONE )
02283 {
02284 overrideJumpLeftAttackMove = (saberMoveName_t)saber2->jumpAtkLeftMove;
02285 }
02286 else
02287 {
02288 overrideJumpLeftAttackMove = LS_NONE;
02289 }
02290 }
02291 else if ( saber2
02292 && saber2->jumpAtkLeftMove != LS_INVALID )
02293 {
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 {
02311 if ( !noSpecials
02312 && overrideJumpRightAttackMove != LS_NONE
02313 && pm->ps->velocity[2] > 20.0f
02314 && (pm->cmd.buttons&BUTTON_ATTACK)
02315 && PM_GroundDistance() < 70.0f
02316 && ( pm->cmd.upmove > 0 || (pm->ps->pm_flags & PMF_JUMP_HELD) )
02317 && BG_EnoughForcePowerForMove( SABER_ALT_ATTACK_POWER_LR ) )
02318 {
02319 BG_ForcePowerDrain(pm->ps, FP_GRIP, SABER_ALT_ATTACK_POWER_LR);
02320 if ( overrideJumpRightAttackMove != LS_INVALID )
02321 {
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
02341 PM_AddEvent( EV_JUMP );
02342 pm->ps->velocity[2] = 300.0f;
02343
02344
02345
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 {
02359 newmove = LS_A_TL2BR;
02360 }
02361 else if ( pm->cmd.forwardmove < 0 )
02362 {
02363 newmove = LS_A_BL2TR;
02364 }
02365 else
02366 {
02367 newmove = LS_A_L2R;
02368 }
02369 }
02370 else if ( pm->cmd.rightmove < 0 )
02371 {
02372 if ( !noSpecials
02373 && overrideJumpLeftAttackMove != LS_NONE
02374 && pm->ps->velocity[2] > 20.0f
02375 && (pm->cmd.buttons&BUTTON_ATTACK)
02376 && PM_GroundDistance() < 70.0f
02377 && ( pm->cmd.upmove > 0 || (pm->ps->pm_flags & PMF_JUMP_HELD) )
02378 && BG_EnoughForcePowerForMove( SABER_ALT_ATTACK_POWER_LR ) )
02379 {
02380 BG_ForcePowerDrain(pm->ps, FP_GRIP, SABER_ALT_ATTACK_POWER_LR);
02381
02382 if ( overrideJumpLeftAttackMove != LS_INVALID )
02383 {
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
02402 PM_AddEvent( EV_JUMP );
02403 pm->ps->velocity[2] = 350.0f;
02404
02405
02406
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 {
02420 newmove = LS_A_TR2BL;
02421 }
02422 else if ( pm->cmd.forwardmove < 0 )
02423 {
02424 newmove = LS_A_BR2TL;
02425 }
02426 else
02427 {
02428 newmove = LS_A_R2L;
02429 }
02430 }
02431 else
02432 {
02433 if ( pm->cmd.forwardmove > 0 )
02434 {
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
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 {
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 {
02464
02465
02466
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 {
02484
02485
02486
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 {
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 {
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 {
02540 newmove = PM_SaberBackflipAttackMove();
02541 }
02542 else if (PM_CanBackstab() && !BG_SaberInSpecialAttack(pm->ps->torsoAnim))
02543 {
02544 if (pm->ps->fd.saberAnimLevel >= FORCE_LEVEL_2 && pm->ps->fd.saberAnimLevel != SS_STAFF)
02545 {
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 {
02557 newmove = LS_A_BACKSTAB;
02558 }
02559 }
02560 else
02561 {
02562 newmove = LS_A_T2B;
02563 }
02564 }
02565 else if ( PM_SaberInBounce( curmove ) )
02566 {
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 {
02580
02581
02582
02583
02584
02585
02586 newmove = LS_A_T2B;
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 {
02598 newmove = LS_DUAL_LR;
02599
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 {
02608 newmove = LS_DUAL_FB;
02609
02610 pm->cmd.forwardmove = 0;
02611 }
02612 }
02613
02614 return newmove;
02615 }
02616
02617 int PM_KickMoveForConditions(void)
02618 {
02619 int kickMove = -1;
02620
02621
02622 if ( pm->cmd.rightmove )
02623 {
02624 if ( pm->cmd.rightmove > 0 )
02625 {
02626 kickMove = LS_KICK_R;
02627 }
02628 else
02629 {
02630 kickMove = LS_KICK_L;
02631 }
02632 pm->cmd.rightmove = 0;
02633 }
02634 else if ( pm->cmd.forwardmove )
02635 {
02636 if ( pm->cmd.forwardmove > 0 )
02637 {
02638
02639
02640
02641
02642
02643
02644
02645
02646 {
02647 kickMove = LS_KICK_F;
02648 }
02649 }
02650 else
02651 {
02652 kickMove = LS_KICK_B;
02653 }
02654 pm->cmd.forwardmove = 0;
02655 }
02656 else
02657 {
02658
02659
02660 if (0)
02661 {
02662
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 {
02672 kickMove = LS_KICK_S;
02673 }
02674 else if (right && left)
02675 {
02676 kickMove = LS_KICK_RL;
02677 }
02678 else
02679 {
02680 kickMove = LS_KICK_F;
02681 }
02682
02683 pm->cmd.upmove = 0;
02684 }
02685 }
02686
02687 return kickMove;
02688 }
02689
02690 qboolean BG_InSlopeAnim( int anim );
02691 qboolean PM_RunningAnim( int anim );
02692
02693 qboolean PM_SaberMoveOkayForKata( void )
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 }
02705
02706 qboolean PM_CanDoKata( void )
02707 {
02708 if ( PM_InSecondaryStyle() )
02709 {
02710 return qfalse;
02711 }
02712
02713 if ( !pm->ps->saberInFlight
02714 && PM_SaberMoveOkayForKata()
02715 && !BG_SaberInKata(pm->ps->saberMove)
02716 && !BG_InKataAnim(pm->ps->legsAnim)
02717 && !BG_InKataAnim(pm->ps->torsoAnim)
02718
02719
02720
02721
02722 && pm->ps->groundEntityNum != ENTITYNUM_NONE
02723 && (pm->cmd.buttons&BUTTON_ATTACK)
02724 && (pm->cmd.buttons&BUTTON_ALT_ATTACK)
02725 && !pm->cmd.forwardmove
02726 && !pm->cmd.rightmove
02727 && pm->cmd.upmove <= 0
02728 && BG_EnoughForcePowerForMove(SABER_ALT_ATTACK_POWER) )
02729 {
02730 saberInfo_t *saber = BG_MySaber( pm->ps->clientNum, 0 );
02731 if ( saber
02732 && saber->kataMove == LS_NONE )
02733 {
02734 return qfalse;
02735 }
02736 saber = BG_MySaber( pm->ps->clientNum, 1 );
02737 if ( saber
02738 && saber->kataMove == LS_NONE )
02739 {
02740 return qfalse;
02741 }
02742 return qtrue;
02743 }
02744 return qfalse;
02745 }
02746
02747 qboolean PM_CheckAltKickAttack( void )
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
02766 && (!BG_FlippingAnim(pm->ps->legsAnim)||pm->ps->legsTimer<=250)
02767 && (pm->ps->fd.saberAnimLevel == SS_STAFF) && !pm->ps->saberHolstered )
02768 {
02769 return qtrue;
02770 }
02771 return qfalse;
02772 }
02773
02774 int bg_parryDebounce[NUM_FORCE_POWER_LEVELS] =
02775 {
02776 500,
02777 300,
02778 150,
02779 50
02780 };
02781
02782 qboolean PM_SaberPowerCheck(void)
02783 {
02784 if (pm->ps->saberInFlight)
02785 {
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 }
02798
02799 qboolean PM_CanDoRollStab( void )
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 }
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828 qboolean PM_WalkingAnim( int anim );
02829 qboolean PM_SwimmingAnim( int anim );
02830 int PM_SaberBounceForAttack( int move );
02831 qboolean BG_SuperBreakLoseAnim( int anim );
02832 qboolean BG_SuperBreakWinAnim( int anim );
02833 void PM_WeaponLightsaber(void)
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 {
02843
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
02861 if ( pm->ps->saberHolstered == 2 )
02862 {
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 (
02884
02885
02886
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 (
02911
02912
02913
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 {
02929 return;
02930 }
02931
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 {
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 {
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 {
02990
02991
02992
02993
02994
02995
02996
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009
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 {
03026 if (pm->ps->fd.saberAnimLevel == SS_STAFF)
03027 {
03028
03029 if ( pm->ps->weaponTime > 0
03030 && PM_SaberInReturn( pm->ps->saberMove )
03031
03032
03033 && pm->ps->saberBlocked == BLOCKED_NONE
03034 && !(pm->cmd.buttons&BUTTON_ATTACK) )
03035 {
03036 if ( (pm->cmd.forwardmove||pm->cmd.rightmove)
03037 && PM_CheckAltKickAttack() )
03038 {
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
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 {
03070 }
03071 else
03072 {
03073
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 {
03086 if ( (pm->ps->fd.saberAnimLevel != SS_DUAL
03087 || pm->ps->saberHolstered
03088 || (!(pm->cmd.buttons&BUTTON_ATTACK)
03089 && (pm->ps->torsoAnim == BOTH_SABERDUAL_STANCE
03090 || pm->ps->torsoAnim == BOTH_SABERPULL
03091 || pm->ps->torsoAnim == BOTH_STAND1
03092 || PM_RunningAnim( pm->ps->torsoAnim )
03093 || PM_WalkingAnim( pm->ps->torsoAnim )
03094 || PM_JumpingAnim( pm->ps->torsoAnim )
03095 || PM_SwimmingAnim( pm->ps->torsoAnim ))
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
03107
03108
03109
03110
03111
03112
03113
03114
03115 if ( pm->ps->stats[STAT_HEALTH] <= 0 ) {
03116 return;
03117 }
03118
03119
03120
03121
03122
03123
03124
03125
03126
03127
03128
03129
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140 if ( pm->ps->weaponTime > 0 )
03141 {
03142
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
03158
03159
03160
03161
03162
03163 }
03164 else
03165 {
03166 pm->ps->weaponstate = WEAPON_READY;
03167 }
03168
03169
03170 if ( pm->ps->saberBlocked )
03171 {
03172 if ( pm->ps->saberBlocked >= BLOCKED_UPPER_RIGHT
03173 && pm->ps->saberBlocked < BLOCKED_UPPER_RIGHT_PROJ)
03174 {
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 {
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
03189 {
03190 int nextMove;
03191
03192 if ( PM_SaberInBrokenParry( pm->ps->saberMove ) )
03193 {
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 {
03207 }
03208 }
03209 break;
03210 case BLOCKED_ATK_BOUNCE:
03211
03212
03213 if (pm->ps->saberMove >= LS_T1_BR__R)
03214 {
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 {
03225 int newQuad = PM_SaberMoveQuadrantForMovement( &pm->cmd );
03226 while ( newQuad == saberMoveData[pm->ps->saberMove].startQuad )
03227 {
03228
03229
03230 newQuad = PM_irand_timesync( Q_BR, Q_BL );
03231
03232 }
03233 bounceMove = transitionMove[saberMoveData[pm->ps->saberMove].startQuad][newQuad];
03234 }
03235 else
03236 {
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
03246 {
03247 bounceMove = LS_R_BR2TL+saberMoveData[pm->ps->saberMove].startQuad-Q_TL;
03248 }
03249 }
03250 }
03251 else
03252 {
03253 bounceMove = PM_SaberBounceForAttack( (saberMoveName_t)pm->ps->saberMove );
03254 }
03255
03256 PM_SetSaberMove( bounceMove );
03257
03258 pm->ps->weaponTime = pm->ps->torsoTimer;
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 {
03299 if ( pm->ps->torsoTimer < pm->ps->weaponTime )
03300 {
03301 pm->ps->torsoTimer = pm->ps->weaponTime;
03302 }
03303 }
03304
03305
03306
03307
03308
03309
03310
03311
03312
03313
03314
03315 pm->ps->saberBlocked = 0;
03316
03317
03318 pm->ps->weaponstate = WEAPON_READY;
03319
03320
03321 return;
03322 }
03323
03324 weapChecks:
03325 if (pm->ps->saberEntityNum)
03326 {
03327
03328
03329
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
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 {
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
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 {
03378
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 );
03394 break;
03395 case SS_STAFF:
03396 PM_SetSaberMove( LS_STAFF_SOULCAL );
03397 break;
03398 }
03399 pm->ps->weaponstate = WEAPON_FIRING;
03400
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 {
03411 return;
03412 }
03413 }
03414
03415 if ( pm->ps->weaponTime > 0 )
03416 {
03417 return;
03418 }
03419
03420
03421
03422
03423
03424
03425 if ( pm->ps->weaponstate == WEAPON_DROPPING ) {
03426 PM_FinishWeaponChange();
03427 return;
03428 }
03429
03430
03431
03432
03433
03434 if ( pm->ps->weaponstate == WEAPON_RAISING )
03435 {
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
03492
03493 if (pm->ps->fd.saberAnimLevel == SS_STAFF &&
03494 (pm->cmd.buttons & BUTTON_ALT_ATTACK))
03495 {
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
03502 pm->ps->saberMove == LS_READY
03503 && !(pm->ps->pm_flags&PMF_DUCKED)
03504 && (pm->cmd.upmove >= 0 )
03505 )
03506 {
03507 kickMove = PM_KickMoveForConditions();
03508 }
03509
03510 if (kickMove != -1)
03511 {
03512 if ( pm->ps->groundEntityNum == ENTITYNUM_NONE )
03513 {
03514 float gDist = PM_GroundDistance();
03515
03516
03517
03518 if ((!BG_FlippingAnim( pm->ps->legsAnim ) || pm->ps->legsTimer <= 0) &&
03519 gDist > 64.0f &&
03520 gDist > (-pm->ps->velocity[2])-64.0f
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:
03538 kickMove = -1;
03539 break;
03540 }
03541 }
03542 else
03543 {
03544 if ( gDist > 128.0f || pm->ps->velocity[2] >= 0 )
03545 {
03546 kickMove = -1;
03547 }
03548 }
03549 }
03550
03551 if (kickMove != -1)
03552 {
03553 PM_SetSaberMove( kickMove );
03554 return;
03555 }
03556 }
03557 }
03558
03559
03560 pm->cmd.buttons &= ~BUTTON_ALT_ATTACK;
03561
03562 if(!delayed_fire)
03563 {
03564
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 {
03576 newmove = LS_R_T2B;
03577 }
03578
03579 else if ( !(pm->cmd.buttons & (BUTTON_ATTACK|BUTTON_ALT_ATTACK)) )
03580 {
03581 pm->ps->weaponTime = 0;
03582
03583 if ( pm->ps->weaponTime > 0 )
03584 {
03585 pm->ps->weaponstate = WEAPON_FIRING;
03586 }
03587 else if ( pm->ps->weaponstate != WEAPON_READY )
03588 {
03589 pm->ps->weaponstate = WEAPON_IDLE;
03590 }
03591
03592 if ( curmove >= LS_S_TL2BR && curmove <= LS_S_T2B )
03593 {
03594 newmove = LS_A_TL2BR + (curmove-LS_S_TL2BR);
03595 }
03596 else if ( curmove >= LS_A_TL2BR && curmove <= LS_A_T2B )
03597 {
03598 newmove = LS_R_TL2BR + (curmove-LS_A_TL2BR);
03599 }
03600 else if ( PM_SaberInTransition( curmove ) )
03601 {
03602 newmove = saberMoveData[curmove].chain_attack;
03603 }
03604 else if ( PM_SaberInBounce( curmove ) )
03605 {
03606 newmove = saberMoveData[curmove].chain_idle;
03607 }
03608 else
03609 {
03610
03611
03612 {
03613 PM_SetSaberMove( LS_READY );
03614 }
03615 return;
03616 }
03617 }
03618
03619
03620
03621
03622 if ( pm->ps->weaponTime > 0 )
03623 {
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 {
03633 return;
03634 }
03635 else if ( pm->ps->torsoAnim == BOTH_FORCELONGLEAP_START )
03636 {
03637 if ( pm->ps->torsoTimer >= 200 )
03638 {
03639 PM_SetSaberMove( LS_LEAP_ATTACK );
03640 }
03641 return;
03642 }
03643 if ( curmove >= LS_PARRY_UP && curmove <= LS_REFLECT_LL )
03644 {
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
03663 }
03664 }
03665
03666 if ( newmove != LS_NONE )
03667 {
03668 anim = saberMoveData[newmove].animToUse;
03669 }
03670
03671
03672 if ( anim == -1 )
03673 {
03674
03675 if ( PM_SaberInTransition( curmove ) )
03676 {
03677 newmove = saberMoveData[curmove].chain_attack;
03678 }
03679 else if ( curmove >= LS_S_TL2BR && curmove <= LS_S_T2B )
03680 {
03681 newmove = LS_A_TL2BR + (curmove-LS_S_TL2BR);
03682 }
03683 else if ( PM_SaberInBrokenParry( curmove ) )
03684 {
03685 newmove = LS_READY;
03686 }
03687 else
03688 {
03689
03690
03691
03692
03693
03694
03695 newmove = PM_SaberAttackForMovement( curmove );
03696 if ( (PM_SaberInBounce( curmove )||PM_SaberInBrokenParry( curmove ))
03697 && saberMoveData[newmove].startQuad == saberMoveData[curmove].endQuad )
03698 {
03699 newmove = saberMoveData[curmove].chain_attack;
03700 }
03701
03702 if ( PM_SaberKataDone( curmove, newmove ) )
03703 {
03704 newmove = saberMoveData[curmove].chain_idle;
03705 }
03706 }
03707
03708
03709
03710
03711
03712
03713
03714 if ( newmove != LS_NONE )
03715 {
03716
03717 newmove = PM_SaberAnimTransitionAnim( curmove, newmove );
03718 anim = saberMoveData[newmove].animToUse;
03719 }
03720 }
03721
03722 if (anim == -1)
03723 {
03724
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 {
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
03763
03764
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
03777 pm->ps->weaponTime = pm->ps->torsoTimer;
03778 }
03779 }
03780
03781
03782
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 }
03798
03799 void PM_SetSaberMove(short newMove)
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 {
03807 pm->ps->saberAttackChainCount = 0;
03808 }
03809 else if ( BG_SaberInAttack( newMove ) )
03810 {
03811 pm->ps->saberAttackChainCount++;
03812 }
03813
03814 if (pm->ps->saberAttackChainCount > 16)
03815 {
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 {
03867
03868
03869 if ( newMove >= LS_V1_BR && newMove <= LS_REFLECT_LL )
03870 {
03871 anim = BOTH_P7_S7_T_ + (anim-BOTH_P1_S1_T_);
03872 }
03873 else
03874 {
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 {
03880
03881
03882 if ( newMove >= LS_V1_BR && newMove <= LS_REFLECT_LL )
03883 {
03884 anim = BOTH_P6_S6_T_ + (anim-BOTH_P1_S1_T_);
03885 }
03886 else
03887 {
03888 anim += (pm->ps->fd.saberAnimLevel-FORCE_LEVEL_1) * SABER_ANIM_GROUP_SIZE;
03889 }
03890 }
03891
03892
03893
03894
03895
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 {
03901 anim += (pm->ps->fd.saberAnimLevel-FORCE_LEVEL_1) * SABER_ANIM_GROUP_SIZE;
03902 }
03903
03904
03905 if ( saberMoveData[pm->ps->saberMove].animToUse == anim && newMove > LS_PUTAWAY)
03906 {
03907 setflags |= SETANIM_FLAG_RESTART;
03908 }
03909
03910
03911 if (!pm->ps->m_iVehicleNum)
03912 {
03913 if (BG_SaberInSpecial(newMove))
03914 {
03915 setflags |= SETANIM_FLAG_OVERRIDE;
03916 }
03917
03918
03919
03920
03921
03922
03923
03924
03925
03926
03927
03928
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 {
03939 anim = PM_GetSaberStance();
03940 }
03941
03942 if (pm->ps->pm_flags & PMF_DUCKED)
03943 {
03944 anim = PM_GetSaberStance();
03945 }
03946
03947 if (anim == BOTH_WALKBACK1 || anim == BOTH_WALKBACK2 || anim == BOTH_WALK1)
03948 {
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 {
03962 if (newMove == LS_JUMPATTACK_ARIAL_RIGHT ||
03963 newMove == LS_JUMPATTACK_ARIAL_LEFT)
03964 {
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 {
04000 parts = SETANIM_BOTH;
04001 }
04002 else if ( (!pm->cmd.forwardmove&&!pm->cmd.rightmove&&!pm->cmd.upmove))
04003 {
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 {
04037
04038
04039 if ( BG_SaberInAttack( newMove ) || BG_SaberInSpecialAttack( anim ) )
04040 {
04041 if ( pm->ps->saberMove != newMove )
04042 {
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 {
04057 int iFactor = -1;
04058
04059 if (pm->ps->brokenLimbs & (1<<BROKENLIMB_RARM))
04060 {
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 {
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 }
04096
04097 saberInfo_t *BG_MySaber( int clientNum, int saberNum )
04098 {
04099
04100 #ifdef QAGAME
04101 gentity_t *ent = &g_entities[clientNum];
04102 if ( ent->inuse && ent->client )
04103 {
04104 if ( !ent->client->saber[saberNum].model
04105 || !ent->client->saber[saberNum].model[0] )
04106 {
04107 return NULL;
04108 }
04109 return &ent->client->saber[saberNum];
04110 }
04111 #elif defined CGAME
04112 clientInfo_t *ci = NULL;
04113 if (clientNum < MAX_CLIENTS)
04114 {
04115 ci = &cgs.clientinfo[clientNum];
04116 }
04117 else
04118 {
04119 centity_t *cent = &cg_entities[clientNum];
04120 if (cent->npcClient)
04121 {
04122 ci = cent->npcClient;
04123 }
04124 }
04125 if ( ci
04126 && ci->infoValid )
04127 {
04128 if ( !ci->saber[saberNum].model
04129 || !ci->saber[saberNum].model[0] )
04130 {
04131 return NULL;
04132 }
04133 return &ci->saber[saberNum];
04134 }
04135 #endif
04136
04137 return NULL;
04138 }
04139
04140 #include "../namespace_end.h"