codemp/game/bg_local.h File Reference

#include "../namespace_begin.h"
#include "../namespace_end.h"

Go to the source code of this file.

Data Structures

struct  pml_t

Defines

#define MIN_WALK_NORMAL   0.7f
#define TIMER_LAND   130
#define TIMER_GESTURE   (34*66+50)
#define OVERCLIP   1.001f

Functions

int trap_FS_FOpenFile (const char *qpath, fileHandle_t *f, fsMode_t mode)
void trap_FS_Read (void *buffer, int len, fileHandle_t f)
void trap_FS_Write (const void *buffer, int len, fileHandle_t f)
void trap_FS_FCloseFile (fileHandle_t f)
qboolean PM_SaberInParry (int move)
qboolean PM_SaberInKnockaway (int move)
qboolean PM_SaberInReflect (int move)
qboolean PM_SaberInStart (int move)
qboolean PM_InSaberAnim (int anim)
qboolean PM_InKnockDown (playerState_t *ps)
qboolean PM_PainAnim (int anim)
qboolean PM_JumpingAnim (int anim)
qboolean PM_LandingAnim (int anim)
qboolean PM_SpinningAnim (int anim)
qboolean PM_InOnGroundAnim (int anim)
qboolean PM_InRollComplete (playerState_t *ps, int anim)
int PM_AnimLength (int index, animNumber_t anim)
int PM_GetSaberStance (void)
float PM_GroundDistance (void)
qboolean PM_SomeoneInFront (trace_t *tr)
saberMoveName_t PM_SaberFlipOverAttackMove (void)
saberMoveName_t PM_SaberJumpAttackMove (void)
void PM_ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce)
void PM_AddTouchEnt (int entityNum)
void PM_AddEvent (int newEvent)
qboolean PM_SlideMove (qboolean gravity)
void PM_StepSlideMove (qboolean gravity)
void PM_StartTorsoAnim (int anim)
void PM_ContinueLegsAnim (int anim)
void PM_ForceLegsAnim (int anim)
void PM_BeginWeaponChange (int weapon)
void PM_FinishWeaponChange (void)
void PM_SetAnim (int setAnimParts, int anim, int setAnimFlags, int blendTime)
void PM_WeaponLightsaber (void)
void PM_SetSaberMove (short newMove)
void PM_SetForceJumpZStart (float value)
void BG_CycleInven (playerState_t *ps, int direction)

Variables

pml_t pml
float pm_stopspeed
float pm_duckScale
float pm_swimScale
float pm_wadeScale
float pm_accelerate
float pm_airaccelerate
float pm_wateraccelerate
float pm_flyaccelerate
float pm_friction
float pm_waterfriction
float pm_flightfriction
int c_pmove
int forcePowerNeeded [NUM_FORCE_POWER_LEVELS][NUM_FORCE_POWERS]


Define Documentation

#define MIN_WALK_NORMAL   0.7f
 

Definition at line 5 of file bg_local.h.

Referenced by PM_ClipVelocity(), PM_HoverTrace(), PM_StepSlideMove(), and PM_WalkableGroundDistance().

#define OVERCLIP   1.001f
 

Definition at line 10 of file bg_local.h.

Referenced by PM_SlideMove(), and PM_StepSlideMove().

#define TIMER_GESTURE   (34*66+50)
 

Definition at line 8 of file bg_local.h.

#define TIMER_LAND   130
 

Definition at line 7 of file bg_local.h.


Function Documentation

void BG_CycleInven playerState_t ps,
int  direction
 

Definition at line 2121 of file bg_misc.c.

02122 {
02123         int i;
02124         int dontFreeze = 0;
02125         int original;
02126 
02127         i = bg_itemlist[ps->stats[STAT_HOLDABLE_ITEM]].giTag;
02128         original = i;
02129 
02130         if (direction == 1)
02131         { //next
02132                 i++;
02133                 if (i == HI_NUM_HOLDABLE)
02134                 {
02135                         i = 1;
02136                 }
02137         }
02138         else
02139         { //previous
02140                 i--;
02141                 if (i == 0)
02142                 {
02143                         i = HI_NUM_HOLDABLE-1;
02144                 }
02145         }
02146 
02147         while (i != original)
02148         { //go in a full loop until hitting something, if hit nothing then select nothing
02149                 if (ps->stats[STAT_HOLDABLE_ITEMS] & (1 << i))
02150                 { //we have it, select it.
02151                         if (BG_IsItemSelectable(ps, i))
02152                         {
02153                                 ps->stats[STAT_HOLDABLE_ITEM] = BG_GetItemIndexByTag(i, IT_HOLDABLE);
02154                                 break;
02155                         }
02156                 }
02157 
02158                 if (direction == 1)
02159                 { //next
02160                         i++;
02161                 }
02162                 else
02163                 { //previous
02164                         i--;
02165                 }
02166 
02167                 if (i <= 0)
02168                 { //wrap around to the last
02169                         i = HI_NUM_HOLDABLE-1;
02170                 }
02171                 else if (i >= HI_NUM_HOLDABLE)
02172                 { //wrap around to the first
02173                         i = 1;
02174                 }
02175 
02176                 dontFreeze++;
02177                 if (dontFreeze >= 32)
02178                 { //yeah, sure, whatever (it's 2 am and I'm paranoid and can't frickin think)
02179                         break;
02180                 }
02181         }
02182 }

void PM_AddEvent int  newEvent  ) 
 

Definition at line 910 of file bg_pmove.c.

References BG_AddPredictableEventToPlayerstate(), pm, and pmove_t::ps.

Referenced by BG_EnoughForcePowerForMove(), PM_AdjustAngleForWallRunUp(), PM_AdjustAttackStates(), PM_GrabWallForJump(), PM_MoveForKata(), PM_SaberAttackForMovement(), PM_SaberFlipOverAttackMove(), PM_SaberJumpAttackMove(), PM_SaberLockBreak(), PM_SaberLocked(), PM_SaberLungeAttackMove(), PM_SetSaberMove(), PM_StepSlideMove(), PM_VehicleWeaponAnimate(), and PM_WeaponLightsaber().

00910                                  {
00911         BG_AddPredictableEventToPlayerstate( newEvent, 0, pm->ps );
00912 }

void PM_AddTouchEnt int  entityNum  ) 
 

Definition at line 924 of file bg_pmove.c.

References ENTITYNUM_WORLD, MAXTOUCH, pmove_t::numtouch, pm, and pmove_t::touchents.

Referenced by PM_SlideMove().

00924                                      {
00925         int             i;
00926 
00927         if ( entityNum == ENTITYNUM_WORLD ) {
00928                 return;
00929         }
00930         if ( pm->numtouch == MAXTOUCH ) {
00931                 return;
00932         }
00933 
00934         // see if it is already added
00935         for ( i = 0 ; i < pm->numtouch ; i++ ) {
00936                 if ( pm->touchents[ i ] == entityNum ) {
00937                         return;
00938                 }
00939         }
00940 
00941         // add it
00942         pm->touchents[pm->numtouch] = entityNum;
00943         pm->numtouch++;
00944 }

int PM_AnimLength int  index,
animNumber_t  anim
 

Definition at line 1584 of file bg_panimate.c.

01585 {
01586         if (anim >= MAX_ANIMATIONS || !pm->animations)
01587         {
01588                 return -1;
01589         }
01590         if ( anim < 0 )
01591         {
01592                 Com_Error(ERR_DROP,"ERROR: anim %d < 0\n", anim );
01593         }
01594         return pm->animations[anim].numFrames * fabs((float)(pm->animations[anim].frameLerp));
01595 }

void PM_BeginWeaponChange int  weapon  ) 
 

Definition at line 5767 of file bg_pmove.c.

References BG_ClearRocketLock(), playerState_s::commandTime, EV_CHANGE_WEAPON, pm, PM_AddEventWithParm(), PM_SetAnim(), pmove_t::ps, SETANIM_FLAG_OVERRIDE, SETANIM_TORSO, STAT_WEAPONS, playerState_s::stats, TORSO_DROPWEAP1, WEAPON_DROPPING, playerState_s::weaponstate, playerState_s::weaponTime, WP_NUM_WEAPONS, playerState_s::zoomMode, and playerState_s::zoomTime.

Referenced by PM_WeaponLightsaber().

05767                                         {
05768         if ( weapon <= WP_NONE || weapon >= WP_NUM_WEAPONS ) {
05769                 return;
05770         }
05771 
05772         if ( !( pm->ps->stats[STAT_WEAPONS] & ( 1 << weapon ) ) ) {
05773                 return;
05774         }
05775         
05776         if ( pm->ps->weaponstate == WEAPON_DROPPING ) {
05777                 return;
05778         }
05779 
05780         // turn of any kind of zooming when weapon switching.
05781         if (pm->ps->zoomMode)
05782         {
05783                 pm->ps->zoomMode = 0;
05784                 pm->ps->zoomTime = pm->ps->commandTime;
05785         }
05786 
05787         PM_AddEventWithParm( EV_CHANGE_WEAPON, weapon );
05788         pm->ps->weaponstate = WEAPON_DROPPING;
05789         pm->ps->weaponTime += 200;
05790         //PM_StartTorsoAnim( TORSO_DROPWEAP1 );
05791         PM_SetAnim(SETANIM_TORSO, TORSO_DROPWEAP1, SETANIM_FLAG_OVERRIDE, 0);
05792 
05793         BG_ClearRocketLock( pm->ps );
05794 }

void PM_ClipVelocity vec3_t  in,
vec3_t  normal,
vec3_t  out,
float  overbounce
 

Definition at line 954 of file bg_pmove.c.

References playerState_s::clientNum, DotProduct, ENTITYNUM_NONE, playerState_s::groundEntityNum, MAX_CLIENTS, MIN_WALK_NORMAL, pm, playerState_s::pm_flags, PMF_STUCK_TO_WALL, pmove_t::ps, pmove_t::stepSlideFix, vec3_t, and VectorCopy.

Referenced by PM_SlideMove(), and PM_StepSlideMove().

00954                                                                                {
00955         float   backoff;
00956         float   change;
00957         float   oldInZ;
00958         int             i;
00959         
00960         if ( (pm->ps->pm_flags&PMF_STUCK_TO_WALL) )
00961         {//no sliding!
00962                 VectorCopy( in, out );
00963                 return;
00964         }
00965         oldInZ = in[2];
00966 
00967         backoff = DotProduct (in, normal);
00968         
00969         if ( backoff < 0 ) {
00970                 backoff *= overbounce;
00971         } else {
00972                 backoff /= overbounce;
00973         }
00974 
00975         for ( i=0 ; i<3 ; i++ ) {
00976                 change = normal[i]*backoff;
00977                 out[i] = in[i] - change;
00978         }
00979         if ( pm->stepSlideFix )
00980         {
00981                 if ( pm->ps->clientNum < MAX_CLIENTS//normal player
00982                         && pm->ps->groundEntityNum != ENTITYNUM_NONE//on the ground
00983                         && normal[2] < MIN_WALK_NORMAL )//sliding against a steep slope
00984                 {//if walking on the ground, don't slide up slopes that are too steep to walk on
00985                         out[2] = oldInZ;
00986                 }
00987         }
00988 }

void PM_ContinueLegsAnim int  anim  ) 
 

Definition at line 2621 of file bg_panimate.c.

References playerState_s::legsAnim, playerState_s::legsTimer, pm, and pmove_t::ps.

Referenced by PM_AdjustStandAnimForSlope(), and PmoveSingle().

02621                                      {
02622         if ( ( pm->ps->legsAnim ) == anim ) {
02623                 return;
02624         }
02625         if ( pm->ps->legsTimer > 0 ) {
02626                 return;         // a high priority animation is running
02627         }
02628 
02629         BG_StartLegsAnim( pm->ps, anim );
02630 }

void PM_FinishWeaponChange void   ) 
 

Definition at line 5802 of file bg_pmove.c.

References pmove_t::cmd, LS_DRAW, pm, PM_SetAnim(), PM_SetSaberMove(), pmove_t::ps, SETANIM_FLAG_OVERRIDE, SETANIM_TORSO, STAT_WEAPONS, playerState_s::stats, TORSO_RAISEWEAP1, usercmd_s::weapon, playerState_s::weapon, WEAPON_RAISING, playerState_s::weaponstate, playerState_s::weaponTime, WP_NONE, WP_NUM_WEAPONS, and WP_SABER.

Referenced by PM_WeaponLightsaber().

05802                                    {
05803         int             weapon;
05804 
05805         weapon = pm->cmd.weapon;
05806         if ( weapon < WP_NONE || weapon >= WP_NUM_WEAPONS ) {
05807                 weapon = WP_NONE;
05808         }
05809 
05810         if ( !( pm->ps->stats[STAT_WEAPONS] & ( 1 << weapon ) ) ) {
05811                 weapon = WP_NONE;
05812         }
05813 
05814         if (weapon == WP_SABER)
05815         {
05816                 PM_SetSaberMove(LS_DRAW);
05817         }
05818         else
05819         {
05820                 //PM_StartTorsoAnim( TORSO_RAISEWEAP1);
05821                 PM_SetAnim(SETANIM_TORSO, TORSO_RAISEWEAP1, SETANIM_FLAG_OVERRIDE, 0);
05822         }
05823         pm->ps->weapon = weapon;
05824         pm->ps->weaponstate = WEAPON_RAISING;
05825         pm->ps->weaponTime += 250;
05826 }

void PM_ForceLegsAnim int  anim  ) 
 

Definition at line 2632 of file bg_panimate.c.

References BG_InRoll(), BG_InSpecialJump(), playerState_s::legsAnim, playerState_s::legsTimer, pm, and pmove_t::ps.

02632                                  {
02633         if (BG_InSpecialJump(pm->ps->legsAnim) &&
02634                 pm->ps->legsTimer > 0 &&
02635                 !BG_InSpecialJump(anim))
02636         {
02637                 return;
02638         }
02639 
02640         if (BG_InRoll(pm->ps, pm->ps->legsAnim) &&
02641                 pm->ps->legsTimer > 0 &&
02642                 !BG_InRoll(pm->ps, anim))
02643         {
02644                 return;
02645         }
02646 
02647         pm->ps->legsTimer = 0;
02648         BG_StartLegsAnim( pm->ps, anim );
02649 }

int PM_GetSaberStance void   ) 
 

Definition at line 261 of file bg_pmove.c.

References BG_MySaber(), BG_SabersOff(), BOTH_SABERDUAL_STANCE, BOTH_SABERFAST_STANCE, BOTH_SABERSLOW_STANCE, BOTH_SABERSTAFF_STANCE, BOTH_STAND1, BOTH_STAND2, playerState_s::clientNum, playerState_s::fd, pm, pmove_t::ps, saberInfo_t::readyAnim, forcedata_s::saberAnimLevel, playerState_s::saberEntityNum, playerState_s::saberHolstered, SS_DESANN, SS_DUAL, SS_FAST, SS_MEDIUM, SS_NONE, SS_STAFF, SS_STRONG, and SS_TAVION.

Referenced by PM_SetSaberMove(), and PM_WeaponLightsaber().

00262 {
00263         int anim = BOTH_STAND2;
00264         saberInfo_t *saber1 = BG_MySaber( pm->ps->clientNum, 0 );
00265         saberInfo_t *saber2 = BG_MySaber( pm->ps->clientNum, 1 );
00266 
00267         if (!pm->ps->saberEntityNum)
00268         { //lost it
00269                 return BOTH_STAND1;
00270         }
00271 
00272         if ( BG_SabersOff( pm->ps ) )
00273         {
00274                 return BOTH_STAND1;
00275         }
00276 
00277         if ( saber1
00278                 && saber1->readyAnim != -1 )
00279         {
00280                 return saber1->readyAnim;
00281         }
00282 
00283         if ( saber2
00284                 && saber2->readyAnim != -1 )
00285         {
00286                 return saber2->readyAnim;
00287         }
00288 
00289         if ( saber1 
00290                 && saber2
00291                 && !pm->ps->saberHolstered )
00292         {//dual sabers, both on
00293                 return BOTH_SABERDUAL_STANCE;
00294         }
00295 
00296         switch ( pm->ps->fd.saberAnimLevel )
00297         {
00298         case SS_DUAL:
00299                 anim = BOTH_SABERDUAL_STANCE;
00300                 break;
00301         case SS_STAFF:
00302                 anim = BOTH_SABERSTAFF_STANCE;
00303                 break;
00304         case SS_FAST:
00305         case SS_TAVION:
00306                 anim = BOTH_SABERFAST_STANCE;
00307                 break;
00308         case SS_STRONG:
00309                 anim = BOTH_SABERSLOW_STANCE;
00310                 break;
00311         case SS_NONE:
00312         case SS_MEDIUM:
00313         case SS_DESANN:
00314         default:
00315                 anim = BOTH_STAND2;
00316                 break;
00317         }
00318         return anim;
00319 }

float PM_GroundDistance void   ) 
 

Definition at line 1992 of file bg_saber.c.

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

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

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

qboolean PM_InKnockDown playerState_t ps  ) 
 

Definition at line 1216 of file bg_panimate.c.

01217 {
01218         switch ( (ps->legsAnim) )
01219         {
01220         case BOTH_KNOCKDOWN1:
01221         case BOTH_KNOCKDOWN2:
01222         case BOTH_KNOCKDOWN3:
01223         case BOTH_KNOCKDOWN4:
01224         case BOTH_KNOCKDOWN5:
01225                 return qtrue;
01226                 break;
01227         case BOTH_GETUP1:
01228         case BOTH_GETUP2:
01229         case BOTH_GETUP3:
01230         case BOTH_GETUP4:
01231         case BOTH_GETUP5:
01232         case BOTH_FORCE_GETUP_F1:
01233         case BOTH_FORCE_GETUP_F2:
01234         case BOTH_FORCE_GETUP_B1:
01235         case BOTH_FORCE_GETUP_B2:
01236         case BOTH_FORCE_GETUP_B3:
01237         case BOTH_FORCE_GETUP_B4:
01238         case BOTH_FORCE_GETUP_B5:
01239         case BOTH_GETUP_BROLL_B:
01240         case BOTH_GETUP_BROLL_F:
01241         case BOTH_GETUP_BROLL_L:
01242         case BOTH_GETUP_BROLL_R:
01243         case BOTH_GETUP_FROLL_B:
01244         case BOTH_GETUP_FROLL_F:
01245         case BOTH_GETUP_FROLL_L:
01246         case BOTH_GETUP_FROLL_R:
01247                 if ( ps->legsTimer )
01248                 {
01249                         return qtrue;
01250                 }
01251                 break;
01252         }
01253         return qfalse;
01254 }

qboolean PM_InOnGroundAnim int  anim  ) 
 

Definition at line 1351 of file bg_panimate.c.

References BOTH_DEAD1, BOTH_DEAD2, BOTH_DEAD3, BOTH_DEAD4, BOTH_DEAD5, BOTH_DEADBACKWARD1, BOTH_DEADBACKWARD2, BOTH_DEADFORWARD1, BOTH_DEADFORWARD2, BOTH_FORCE_GETUP_B1, BOTH_FORCE_GETUP_B2, BOTH_FORCE_GETUP_B3, BOTH_FORCE_GETUP_B4, BOTH_FORCE_GETUP_B5, BOTH_FORCE_GETUP_B6, BOTH_FORCE_GETUP_F1, BOTH_FORCE_GETUP_F2, BOTH_GETUP1, BOTH_GETUP2, BOTH_GETUP3, BOTH_GETUP4, BOTH_GETUP5, BOTH_GETUP_BROLL_B, BOTH_GETUP_BROLL_F, BOTH_GETUP_BROLL_L, BOTH_GETUP_BROLL_R, BOTH_GETUP_CROUCH_B1, BOTH_GETUP_CROUCH_F1, BOTH_GETUP_FROLL_B, BOTH_GETUP_FROLL_F, BOTH_GETUP_FROLL_L, BOTH_GETUP_FROLL_R, BOTH_KNOCKDOWN1, BOTH_KNOCKDOWN2, BOTH_KNOCKDOWN3, BOTH_KNOCKDOWN4, BOTH_KNOCKDOWN5, BOTH_LYINGDEAD1, BOTH_LYINGDEATH1, BOTH_SLEEP1, qboolean, qfalse, and qtrue.

01352 {
01353         switch( anim )
01354         {
01355         case BOTH_DEAD1:
01356         case BOTH_DEAD2:
01357         case BOTH_DEAD3:
01358         case BOTH_DEAD4:
01359         case BOTH_DEAD5:
01360         case BOTH_DEADFORWARD1:
01361         case BOTH_DEADBACKWARD1:
01362         case BOTH_DEADFORWARD2:
01363         case BOTH_DEADBACKWARD2:
01364         case BOTH_LYINGDEATH1:
01365         case BOTH_LYINGDEAD1:
01366         case BOTH_SLEEP1:                       //# laying on back-rknee up-rhand on torso
01367         case BOTH_KNOCKDOWN1:           //# 
01368         case BOTH_KNOCKDOWN2:           //# 
01369         case BOTH_KNOCKDOWN3:           //# 
01370         case BOTH_KNOCKDOWN4:           //# 
01371         case BOTH_KNOCKDOWN5:           //# 
01372         case BOTH_GETUP1:
01373         case BOTH_GETUP2:
01374         case BOTH_GETUP3:
01375         case BOTH_GETUP4:
01376         case BOTH_GETUP5:
01377         case BOTH_GETUP_CROUCH_F1:
01378         case BOTH_GETUP_CROUCH_B1:
01379         case BOTH_FORCE_GETUP_F1:
01380         case BOTH_FORCE_GETUP_F2:
01381         case BOTH_FORCE_GETUP_B1:
01382         case BOTH_FORCE_GETUP_B2:
01383         case BOTH_FORCE_GETUP_B3:
01384         case BOTH_FORCE_GETUP_B4:
01385         case BOTH_FORCE_GETUP_B5:
01386         case BOTH_FORCE_GETUP_B6:
01387         case BOTH_GETUP_BROLL_B:
01388         case BOTH_GETUP_BROLL_F:
01389         case BOTH_GETUP_BROLL_L:
01390         case BOTH_GETUP_BROLL_R:
01391         case BOTH_GETUP_FROLL_B:
01392         case BOTH_GETUP_FROLL_F:
01393         case BOTH_GETUP_FROLL_L:
01394         case BOTH_GETUP_FROLL_R:
01395                 return qtrue;
01396                 break;
01397         }
01398 
01399         return qfalse;
01400 }

qboolean PM_InRollComplete playerState_t ps,
int  anim
 

Definition at line 1402 of file bg_panimate.c.

References BOTH_ROLL_B, BOTH_ROLL_F, BOTH_ROLL_L, BOTH_ROLL_R, playerState_s::legsTimer, playerState_t, qboolean, qfalse, and qtrue.

01403 {
01404         switch ( (anim) )
01405         {
01406         case BOTH_ROLL_F:
01407         case BOTH_ROLL_B:
01408         case BOTH_ROLL_R:
01409         case BOTH_ROLL_L:
01410                 if ( ps->legsTimer < 1 )
01411                 {
01412                         return qtrue;
01413                 }
01414                 break;
01415         }
01416         return qfalse;
01417 }

qboolean PM_InSaberAnim int  anim  ) 
 

Definition at line 1207 of file bg_panimate.c.

References BOTH_A1_T__B_, BOTH_H1_S1_BR, qboolean, qfalse, and qtrue.

Referenced by BG_SaberStartTransAnim(), and WP_SaberCanBlock().

01208 {
01209         if ( (anim) >= BOTH_A1_T__B_ && (anim) <= BOTH_H1_S1_BR )
01210         {
01211                 return qtrue;
01212         }
01213         return qfalse;
01214 }

qboolean PM_JumpingAnim int  anim  ) 
 

Definition at line 1284 of file bg_panimate.c.

References BOTH_FORCEINAIR1, BOTH_FORCEINAIRBACK1, BOTH_FORCEINAIRLEFT1, BOTH_FORCEINAIRRIGHT1, BOTH_FORCEJUMP1, BOTH_FORCEJUMPBACK1, BOTH_FORCEJUMPLEFT1, BOTH_FORCEJUMPRIGHT1, BOTH_FORCELAND1, BOTH_FORCELANDBACK1, BOTH_FORCELANDLEFT1, BOTH_FORCELANDRIGHT1, BOTH_INAIR1, BOTH_INAIRBACK1, BOTH_INAIRLEFT1, BOTH_INAIRRIGHT1, BOTH_JUMP1, BOTH_JUMPBACK1, BOTH_JUMPLEFT1, BOTH_JUMPRIGHT1, BOTH_LAND1, BOTH_LAND2, BOTH_LANDBACK1, BOTH_LANDLEFT1, BOTH_LANDRIGHT1, qboolean, qfalse, and qtrue.

Referenced by PM_SetSaberMove(), and PM_WeaponLightsaber().

01285 {
01286         switch ( (anim) )
01287         {
01288                 case BOTH_JUMP1:                                //# Jump - wind-up and leave ground
01289                 case BOTH_INAIR1:                       //# In air loop (from jump)
01290                 case BOTH_LAND1:                                //# Landing (from in air loop)
01291                 case BOTH_LAND2:                                //# Landing Hard (from a great height)
01292                 case BOTH_JUMPBACK1:                    //# Jump backwards - wind-up and leave ground
01293                 case BOTH_INAIRBACK1:           //# In air loop (from jump back)
01294                 case BOTH_LANDBACK1:                    //# Landing backwards(from in air loop)
01295                 case BOTH_JUMPLEFT1:                    //# Jump left - wind-up and leave ground
01296                 case BOTH_INAIRLEFT1:           //# In air loop (from jump left)
01297                 case BOTH_LANDLEFT1:                    //# Landing left(from in air loop)
01298                 case BOTH_JUMPRIGHT1:           //# Jump right - wind-up and leave ground
01299                 case BOTH_INAIRRIGHT1:          //# In air loop (from jump right)
01300                 case BOTH_LANDRIGHT1:           //# Landing right(from in air loop)
01301                 case BOTH_FORCEJUMP1:                           //# Jump - wind-up and leave ground
01302                 case BOTH_FORCEINAIR1:                  //# In air loop (from jump)
01303                 case BOTH_FORCELAND1:                           //# Landing (from in air loop)
01304                 case BOTH_FORCEJUMPBACK1:                       //# Jump backwards - wind-up and leave ground
01305                 case BOTH_FORCEINAIRBACK1:              //# In air loop (from jump back)
01306                 case BOTH_FORCELANDBACK1:                       //# Landing backwards(from in air loop)
01307                 case BOTH_FORCEJUMPLEFT1:                       //# Jump left - wind-up and leave ground
01308                 case BOTH_FORCEINAIRLEFT1:              //# In air loop (from jump left)
01309                 case BOTH_FORCELANDLEFT1:                       //# Landing left(from in air loop)
01310                 case BOTH_FORCEJUMPRIGHT1:              //# Jump right - wind-up and leave ground
01311                 case BOTH_FORCEINAIRRIGHT1:             //# In air loop (from jump right)
01312                 case BOTH_FORCELANDRIGHT1:              //# Landing right(from in air loop)
01313                 return qtrue;
01314                 break;
01315         }
01316         return qfalse;
01317 }

qboolean PM_LandingAnim int  anim  ) 
 

Definition at line 1319 of file bg_panimate.c.

References BOTH_FORCELAND1, BOTH_FORCELANDBACK1, BOTH_FORCELANDLEFT1, BOTH_FORCELANDRIGHT1, BOTH_LAND1, BOTH_LAND2, BOTH_LANDBACK1, BOTH_LANDLEFT1, BOTH_LANDRIGHT1, qboolean, qfalse, and qtrue.

01320 {
01321         switch ( (anim) )
01322         {
01323                 case BOTH_LAND1:                                //# Landing (from in air loop)
01324                 case BOTH_LAND2:                                //# Landing Hard (from a great height)
01325                 case BOTH_LANDBACK1:                    //# Landing backwards(from in air loop)
01326                 case BOTH_LANDLEFT1:                    //# Landing left(from in air loop)
01327                 case BOTH_LANDRIGHT1:           //# Landing right(from in air loop)
01328                 case BOTH_FORCELAND1:           //# Landing (from in air loop)
01329                 case BOTH_FORCELANDBACK1:       //# Landing backwards(from in air loop)
01330                 case BOTH_FORCELANDLEFT1:       //# Landing left(from in air loop)
01331                 case BOTH_FORCELANDRIGHT1:      //# Landing right(from in air loop)
01332                 return qtrue;
01333                 break;
01334         }
01335         return qfalse;
01336 }

qboolean PM_PainAnim int  anim  ) 
 

Definition at line 1256 of file bg_panimate.c.

References BOTH_PAIN1, BOTH_PAIN10, BOTH_PAIN11, BOTH_PAIN12, BOTH_PAIN13, BOTH_PAIN14, BOTH_PAIN15, BOTH_PAIN16, BOTH_PAIN17, BOTH_PAIN18, BOTH_PAIN2, BOTH_PAIN3, BOTH_PAIN4, BOTH_PAIN5, BOTH_PAIN6, BOTH_PAIN7, BOTH_PAIN8, BOTH_PAIN9, qboolean, qfalse, and qtrue.

01257 {
01258         switch ( (anim) )
01259         {
01260                 case BOTH_PAIN1:                                //# First take pain anim
01261                 case BOTH_PAIN2:                                //# Second take pain anim
01262                 case BOTH_PAIN3:                                //# Third take pain anim
01263                 case BOTH_PAIN4:                                //# Fourth take pain anim
01264                 case BOTH_PAIN5:                                //# Fifth take pain anim - from behind
01265                 case BOTH_PAIN6:                                //# Sixth take pain anim - from behind
01266                 case BOTH_PAIN7:                                //# Seventh take pain anim - from behind
01267                 case BOTH_PAIN8:                                //# Eigth take pain anim - from behind
01268                 case BOTH_PAIN9:                                //# 
01269                 case BOTH_PAIN10:                       //# 
01270                 case BOTH_PAIN11:                       //# 
01271                 case BOTH_PAIN12:                       //# 
01272                 case BOTH_PAIN13:                       //# 
01273                 case BOTH_PAIN14:                       //# 
01274                 case BOTH_PAIN15:                       //# 
01275                 case BOTH_PAIN16:                       //# 
01276                 case BOTH_PAIN17:                       //# 
01277                 case BOTH_PAIN18:                       //# 
01278                 return qtrue;
01279                 break;
01280         }
01281         return qfalse;
01282 }

saberMoveName_t PM_SaberFlipOverAttackMove void   ) 
 

Definition at line 1654 of file bg_saber.c.

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

Referenced by PM_SaberAttackForMovement().

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

qboolean PM_SaberInKnockaway int  move  ) 
 

Definition at line 1166 of file bg_panimate.c.

01167 {
01168         if ( move >= LS_K1_T_ && move <= LS_K1_BL )
01169         {
01170                 return qtrue;
01171         }
01172         return qfalse;
01173 }

qboolean PM_SaberInParry int  move  ) 
 

Definition at line 1157 of file bg_panimate.c.

01158 {
01159         if ( move >= LS_PARRY_UP && move <= LS_PARRY_LL )
01160         {
01161                 return qtrue;
01162         }
01163         return qfalse;
01164 }

qboolean PM_SaberInReflect int  move  ) 
 

Definition at line 1175 of file bg_panimate.c.

References LS_REFLECT_LL, LS_REFLECT_UP, qboolean, qfalse, and qtrue.

Referenced by PM_CheckPullAttack(), and PM_SetSaberMove().

01176 {
01177         if ( move >= LS_REFLECT_UP && move <= LS_REFLECT_LL )
01178         {
01179                 return qtrue;
01180         }
01181         return qfalse;
01182 }

qboolean PM_SaberInStart int  move  ) 
 

Definition at line 1184 of file bg_panimate.c.

01185 {
01186         if ( move >= LS_S_TL2BR && move <= LS_S_T2B )
01187         {
01188                 return qtrue;
01189         }
01190         return qfalse;
01191 }

saberMoveName_t PM_SaberJumpAttackMove void   ) 
 

Definition at line 1944 of file bg_saber.c.

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

Referenced by PM_SaberAttackForMovement().

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

void PM_SetAnim int  setAnimParts,
int  anim,
int  setAnimFlags,
int  blendTime
 

Definition at line 3032 of file bg_panimate.c.

03033 {       
03034         BG_SetAnim(pm->ps, pm->animations, setAnimParts, anim, setAnimFlags, blendTime);
03035 }

void PM_SetForceJumpZStart float  value  ) 
 

Definition at line 1759 of file bg_pmove.c.

References playerState_s::fd, forcedata_s::forceJumpZStart, pm, and pmove_t::ps.

Referenced by PM_SaberFlipOverAttackMove(), and PM_SaberJumpAttackMove().

01760 {
01761         pm->ps->fd.forceJumpZStart = value;
01762         if (!pm->ps->fd.forceJumpZStart)
01763         {
01764                 pm->ps->fd.forceJumpZStart -= 0.1;
01765         }
01766 }

void PM_SetSaberMove short  newMove  ) 
 

Definition at line 3799 of file bg_saber.c.

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

Referenced by PM_FinishWeaponChange(), and PM_WeaponLightsaber().

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

qboolean PM_SlideMove qboolean  gravity  ) 
 

Definition at line 629 of file bg_slidemove.c.

References trace_t::allsolid, bgEntity_t, CLASS_VEHICLE, playerState_s::clientNum, DotProduct, trace_t::endpos, trace_t::entityNum, ET_NPC, entityState_s::eType, trace_t::fraction, pml_t::frametime, playerState_s::gravity, pml_t::groundPlane, pml_t::groundTrace, pml_t::impactSpeed, bgEntity_s::m_pVehicle, MAX_CLIENTS, MAX_CLIP_PLANES, pmove_t::maxs, pmove_t::mins, cplane_s::normal, entityState_s::NPC_class, playerState_s::origin, OVERCLIP, trace_t::plane, pm, PM_AddTouchEnt(), PM_ClipVelocity(), pm_entSelf, playerState_s::pm_flags, PM_GroundSlideOkay(), playerState_s::pm_time, PM_VehicleImpact(), PMF_STUCK_TO_WALL, pml, pmove_t::ps, qboolean, qtrue, bgEntity_s::s, pmove_t::trace, pmove_t::tracemask, vec3_t, VectorAdd, VectorClear, VectorCopy, VectorMA, VectorNormalize(), VectorNormalize2(), VectorScale, and playerState_s::velocity.

Referenced by PM_StepSlideMove().

00629                                                  {
00630         int                     bumpcount, numbumps;
00631         vec3_t          dir;
00632         float           d;
00633         int                     numplanes;
00634         vec3_t          normal, planes[MAX_CLIP_PLANES];
00635         vec3_t          primal_velocity;
00636         vec3_t          clipVelocity;
00637         int                     i, j, k;
00638         trace_t trace;
00639         vec3_t          end;
00640         float           time_left;
00641         float           into;
00642         vec3_t          endVelocity;
00643         vec3_t          endClipVelocity;
00644         //qboolean      damageSelf = qtrue;
00645         
00646         numbumps = 4;
00647 
00648         VectorCopy (pm->ps->velocity, primal_velocity);
00649 
00650         if ( gravity ) {
00651                 VectorCopy( pm->ps->velocity, endVelocity );
00652                 endVelocity[2] -= pm->ps->gravity * pml.frametime;
00653                 pm->ps->velocity[2] = ( pm->ps->velocity[2] + endVelocity[2] ) * 0.5;
00654                 primal_velocity[2] = endVelocity[2];
00655                 if ( pml.groundPlane ) {
00656                         if ( PM_GroundSlideOkay( pml.groundTrace.plane.normal[2] ) )
00657                         {// slide along the ground plane
00658                                 PM_ClipVelocity (pm->ps->velocity, pml.groundTrace.plane.normal, 
00659                                         pm->ps->velocity, OVERCLIP );
00660                         }
00661                 }
00662         }
00663 
00664         time_left = pml.frametime;
00665 
00666         // never turn against the ground plane
00667         if ( pml.groundPlane ) {
00668                 numplanes = 1;
00669                 VectorCopy( pml.groundTrace.plane.normal, planes[0] );
00670                 if ( !PM_GroundSlideOkay( planes[0][2] ) )
00671                 {
00672                         planes[0][2] = 0;
00673                         VectorNormalize( planes[0] );
00674                 }
00675         } else {
00676                 numplanes = 0;
00677         }
00678 
00679         // never turn against original velocity
00680         VectorNormalize2( pm->ps->velocity, planes[numplanes] );
00681         numplanes++;
00682 
00683         for ( bumpcount=0 ; bumpcount < numbumps ; bumpcount++ ) {
00684 
00685                 // calculate position we are trying to move to
00686                 VectorMA( pm->ps->origin, time_left, pm->ps->velocity, end );
00687 
00688                 // see if we can make it there
00689                 pm->trace ( &trace, pm->ps->origin, pm->mins, pm->maxs, end, pm->ps->clientNum, pm->tracemask);
00690 
00691                 if (trace.allsolid) {
00692                         // entity is completely trapped in another solid
00693                         pm->ps->velocity[2] = 0;        // don't build up falling damage, but allow sideways acceleration
00694                         return qtrue;
00695                 }
00696 
00697                 if (trace.fraction > 0) {
00698                         // actually covered some distance
00699                         VectorCopy (trace.endpos, pm->ps->origin);
00700                 }
00701 
00702                 if (trace.fraction == 1) {
00703                          break;         // moved the entire distance
00704                 }
00705 
00706                 // save entity for contact
00707                 PM_AddTouchEnt( trace.entityNum );
00708 
00709                 if (pm->ps->clientNum >= MAX_CLIENTS)
00710                 {
00711                         bgEntity_t *pEnt = pm_entSelf;
00712 
00713                         if (pEnt && pEnt->s.eType == ET_NPC && pEnt->s.NPC_class == CLASS_VEHICLE &&
00714                                 pEnt->m_pVehicle)
00715                         { //do vehicle impact stuff then
00716                                 PM_VehicleImpact(pEnt, &trace);
00717                         }
00718                 }
00719 #ifdef QAGAME
00720                 else
00721                 {
00722                         if ( PM_ClientImpact( &trace ) )
00723                         {
00724                                 continue;
00725                         }
00726                 }
00727 #endif
00728 
00729                 time_left -= time_left * trace.fraction;
00730 
00731                 if (numplanes >= MAX_CLIP_PLANES) {
00732                         // this shouldn't really happen
00733                         VectorClear( pm->ps->velocity );
00734                         return qtrue;
00735                 }
00736 
00737                 VectorCopy( trace.plane.normal, normal );
00738 
00739                 if ( !PM_GroundSlideOkay( normal[2] ) )
00740                 {//wall-running
00741                         //never push up off a sloped wall
00742                         normal[2] = 0;
00743                         VectorNormalize( normal );
00744                 }
00745                 //
00746                 // if this is the same plane we hit before, nudge velocity
00747                 // out along it, which fixes some epsilon issues with
00748                 // non-axial planes
00749                 //
00750                 if ( !(pm->ps->pm_flags&PMF_STUCK_TO_WALL) )
00751                 {//no sliding if stuck to wall!
00752                         for ( i = 0 ; i < numplanes ; i++ ) {
00753                                 if ( VectorCompare( normal, planes[i] ) ) {//DotProduct( normal, planes[i] ) > 0.99 ) {
00754                                         VectorAdd( normal, pm->ps->velocity, pm->ps->velocity );
00755                                         break;
00756                                 }
00757                         }
00758                         if ( i < numplanes ) {
00759                                 continue;
00760                         }
00761                 }
00762                 VectorCopy (normal, planes[numplanes]);
00763                 numplanes++;
00764 
00765                 //
00766                 // modify velocity so it parallels all of the clip planes
00767                 //
00768 
00769                 // find a plane that it enters
00770                 for ( i = 0 ; i < numplanes ; i++ ) {
00771                         into = DotProduct( pm->ps->velocity, planes[i] );
00772                         if ( into >= 0.1 ) {
00773                                 continue;               // move doesn't interact with the plane
00774                         }
00775 
00776                         // see how hard we are hitting things
00777                         if ( -into > pml.impactSpeed ) {
00778                                 pml.impactSpeed = -into;
00779                         }
00780 
00781                         // slide along the plane
00782                         PM_ClipVelocity (pm->ps->velocity, planes[i], clipVelocity, OVERCLIP );
00783 
00784                         // slide along the plane
00785                         PM_ClipVelocity (endVelocity, planes[i], endClipVelocity, OVERCLIP );
00786 
00787                         // see if there is a second plane that the new move enters
00788                         for ( j = 0 ; j < numplanes ; j++ ) {
00789                                 if ( j == i ) {
00790                                         continue;
00791                                 }
00792                                 if ( DotProduct( clipVelocity, planes[j] ) >= 0.1 ) {
00793                                         continue;               // move doesn't interact with the plane
00794                                 }
00795 
00796                                 // try clipping the move to the plane
00797                                 PM_ClipVelocity( clipVelocity, planes[j], clipVelocity, OVERCLIP );
00798                                 PM_ClipVelocity( endClipVelocity, planes[j], endClipVelocity, OVERCLIP );
00799 
00800                                 // see if it goes back into the first clip plane
00801                                 if ( DotProduct( clipVelocity, planes[i] ) >= 0 ) {
00802                                         continue;
00803                                 }
00804 
00805                                 // slide the original velocity along the crease
00806                                 CrossProduct (planes[i], planes[j], dir);
00807                                 VectorNormalize( dir );
00808                                 d = DotProduct( dir, pm->ps->velocity );
00809                                 VectorScale( dir, d, clipVelocity );
00810 
00811                                 CrossProduct (planes[i], planes[j], dir);
00812                                 VectorNormalize( dir );
00813                                 d = DotProduct( dir, endVelocity );
00814                                 VectorScale( dir, d, endClipVelocity );
00815 
00816                                 // see if there is a third plane the the new move enters
00817                                 for ( k = 0 ; k < numplanes ; k++ ) {
00818                                         if ( k == i || k == j ) {
00819                                                 continue;
00820                                         }
00821                                         if ( DotProduct( clipVelocity, planes[k] ) >= 0.1 ) {
00822                                                 continue;               // move doesn't interact with the plane
00823                                         }
00824 
00825                                         // stop dead at a triple plane interaction
00826                                         VectorClear( pm->ps->velocity );
00827                                         return qtrue;
00828                                 }
00829                         }
00830 
00831                         // if we have fixed all interactions, try another move
00832                         VectorCopy( clipVelocity, pm->ps->velocity );
00833                         VectorCopy( endClipVelocity, endVelocity );
00834                         break;
00835                 }
00836         }
00837 
00838         if ( gravity ) {
00839                 VectorCopy( endVelocity, pm->ps->velocity );
00840         }
00841 
00842         // don't change velocity if in a timer (FIXME: is this correct?)
00843         if ( pm->ps->pm_time ) {
00844                 VectorCopy( primal_velocity, pm->ps->velocity );
00845         }
00846 
00847         return ( bumpcount != 0 );
00848 }

qboolean PM_SomeoneInFront trace_t tr  ) 
 

Definition at line 1801 of file bg_saber.c.

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

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

qboolean PM_SpinningAnim int  anim  ) 
 

Definition at line 1338 of file bg_panimate.c.

01339 {
01340         /*
01341         switch ( anim )
01342         {
01343         //FIXME: list any other spinning anims
01344         default:
01345                 break;
01346         }
01347         */
01348         return BG_SpinningSaberAnim( anim );
01349 }

void PM_StartTorsoAnim int  anim  ) 
 

Definition at line 2682 of file bg_panimate.c.

References BG_StartTorsoAnim(), pm, and pmove_t::ps.

02683 {
02684     BG_StartTorsoAnim(pm->ps, anim);
02685 }

void PM_StepSlideMove qboolean  gravity  ) 
 

Definition at line 856 of file bg_slidemove.c.

References trace_t::allsolid, BG_InReboundHold(), bgEntity_t, c_pmove, CLASS_ATST, CLASS_RANCOR, CLASS_VEHICLE, playerState_s::clientNum, Com_Printf(), pmove_t::debugLevel, DotProduct, trace_t::endpos, trace_t::entityNum, EV_STEP_12, EV_STEP_16, EV_STEP_4, EV_STEP_8, trace_t::fraction, vehicleInfo_t::hoverHeight, playerState_s::legsAnim, bgEntity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, MAX_CLIENTS, pmove_t::maxs, MIN_WALK_NORMAL, pmove_t::mins, cplane_s::normal, entityState_s::NPC_class, playerState_s::origin, OVERCLIP, trace_t::plane, pm, PM_AddEvent(), PM_ClipVelocity(), pm_entSelf, PM_SlideMove(), pmove_t::ps, qboolean, qfalse, qtrue, bgEntity_s::s, STEPSIZE, pmove_t::stepSlideFix, pmove_t::trace, pmove_t::tracemask, vehicleInfo_t::type, vec3_t, VectorCopy, VectorNormalize(), VectorSet, VectorSubtract, playerState_s::velocity, and VH_WALKER.

00856                                           { 
00857         vec3_t          start_o, start_v;
00858         vec3_t          down_o, down_v;
00859         trace_t         trace;
00860 //      float           down_dist, up_dist;
00861 //      vec3_t          delta, delta2;
00862         vec3_t          up, down;
00863         float           stepSize;
00864         qboolean        isGiant = qfalse;
00865         bgEntity_t      *pEnt;
00866         qboolean skipStep = qfalse;
00867 
00868         VectorCopy (pm->ps->origin, start_o);
00869         VectorCopy (pm->ps->velocity, start_v);
00870 
00871         if ( BG_InReboundHold( pm->ps->legsAnim ) )
00872         {
00873                 gravity = qfalse;
00874         }
00875 
00876         if ( PM_SlideMove( gravity ) == 0 ) {
00877                 return;         // we got exactly where we wanted to go first try       
00878         }
00879 
00880         pEnt = pm_entSelf;
00881 
00882         if (pm->ps->clientNum >= MAX_CLIENTS)
00883         {
00884                 if (pEnt && pEnt->s.NPC_class == CLASS_VEHICLE &&
00885                         pEnt->m_pVehicle && pEnt->m_pVehicle->m_pVehicleInfo->hoverHeight > 0)
00886                 {
00887                         return;
00888                 }
00889         }
00890 
00891         VectorCopy(start_o, down);
00892         down[2] -= STEPSIZE;
00893         pm->trace (&trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
00894         VectorSet(up, 0, 0, 1);
00895         // never step up when you still have up velocity
00896         if ( pm->ps->velocity[2] > 0 && (trace.fraction == 1.0 ||
00897                                                                                 DotProduct(trace.plane.normal, up) < 0.7))
00898         {
00899                 return;
00900         }
00901 
00902         VectorCopy (pm->ps->origin, down_o);
00903         VectorCopy (pm->ps->velocity, down_v);
00904 
00905         VectorCopy (start_o, up);
00906 
00907         if (pm->ps->clientNum >= MAX_CLIENTS)
00908         {
00909                 // apply ground friction, even if on ladder
00910                 if (pEnt &&
00911                         pEnt->s.NPC_class == CLASS_ATST ||
00912                                 (pEnt->s.NPC_class == CLASS_VEHICLE &&
00913                                         pEnt->m_pVehicle &&
00914                                         pEnt->m_pVehicle->m_pVehicleInfo->type == VH_WALKER)
00915                         )
00916                 {//AT-STs can step high
00917                         up[2] += 66.0f;
00918                         isGiant = qtrue;
00919                 }
00920                 else if ( pEnt && pEnt->s.NPC_class == CLASS_RANCOR )
00921                 {//also can step up high
00922                         up[2] += 64.0f;
00923                         isGiant = qtrue;
00924                 }
00925                 else
00926                 {
00927                         up[2] += STEPSIZE;
00928                 }
00929         }
00930         else
00931         {
00932                 up[2] += STEPSIZE;
00933         }
00934 
00935         // test the player position if they were a stepheight higher
00936         pm->trace (&trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask);
00937         if ( trace.allsolid ) {
00938                 if ( pm->debugLevel ) {
00939                         Com_Printf("%i:bend can't step\n", c_pmove);
00940                 }
00941                 return;         // can't step up
00942         }
00943 
00944         stepSize = trace.endpos[2] - start_o[2];
00945         // try slidemove from this position
00946         VectorCopy (trace.endpos, pm->ps->origin);
00947         VectorCopy (start_v, pm->ps->velocity);
00948 
00949         PM_SlideMove( gravity );
00950 
00951         // push down the final amount
00952         VectorCopy (pm->ps->origin, down);
00953         down[2] -= stepSize;
00954         pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
00955 
00956         if ( pm->stepSlideFix )
00957         {
00958                 if ( pm->ps->clientNum < MAX_CLIENTS
00959                         && trace.plane.normal[2] < MIN_WALK_NORMAL )
00960                 {//normal players cannot step up slopes that are too steep to walk on!
00961                         vec3_t stepVec;
00962                         //okay, the step up ends on a slope that it too steep to step up onto,
00963                         //BUT:
00964                         //If the step looks like this:
00965                         //  (B)\__
00966                         //        \_____(A)
00967                         //Then it might still be okay, so we figure out the slope of the entire move
00968                         //from (A) to (B) and if that slope is walk-upabble, then it's okay
00969                         VectorSubtract( trace.endpos, down_o, stepVec );
00970                         VectorNormalize( stepVec ); 
00971                         if ( stepVec[2] > (1.0f-MIN_WALK_NORMAL) )
00972                         {
00973                                 skipStep = qtrue;
00974                         }
00975                 }
00976         }
00977 
00978         if ( !trace.allsolid 
00979                 && !skipStep ) //normal players cannot step up slopes that are too steep to walk on!
00980         { 
00981                 if ( pm->ps->clientNum >= MAX_CLIENTS//NPC
00982                         && isGiant 
00983                         && trace.entityNum < MAX_CLIENTS
00984                         && pEnt 
00985                         && pEnt->s.NPC_class == CLASS_RANCOR )
00986                 {//Rancor don't step on clients
00987                         if ( pm->stepSlideFix )
00988                         {
00989                                 VectorCopy (down_o, pm->ps->origin);
00990                                 VectorCopy (down_v, pm->ps->velocity);
00991                         }
00992                         else
00993                         {
00994                                 VectorCopy (start_o, pm->ps->origin);
00995                                 VectorCopy (start_v, pm->ps->velocity);
00996                         }
00997                 }
00998                 /*
00999                 else if ( pm->ps->clientNum >= MAX_CLIENTS//NPC
01000                         && isGiant 
01001                         && trace.entityNum < MAX_CLIENTS
01002                         && pEnt 
01003                         && pEnt->s.NPC_class == CLASS_ATST 
01004                         && OnSameTeam( pEnt, traceEnt) )
01005                 {//NPC AT-ST's don't step up on allies
01006                         VectorCopy (start_o, pm->ps->origin);
01007                         VectorCopy (start_v, pm->ps->velocity);
01008                 }
01009                 */
01010                 else
01011                 {
01012                         VectorCopy (trace.endpos, pm->ps->origin);
01013                         if ( pm->stepSlideFix )
01014                         {
01015                                 if ( trace.fraction < 1.0 ) {
01016                                         PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, pm->ps->velocity, OVERCLIP );
01017                                 }
01018                         }
01019                 }
01020         }
01021         else
01022         {
01023                 if ( pm->stepSlideFix )
01024                 {
01025                         VectorCopy (down_o, pm->ps->origin);
01026                         VectorCopy (down_v, pm->ps->velocity);
01027                 }
01028         }
01029         if ( !pm->stepSlideFix )
01030         {
01031                 if ( trace.fraction < 1.0 ) {
01032                         PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, pm->ps->velocity, OVERCLIP );
01033                 }
01034         }
01035 
01036 #if 0
01037         // if the down trace can trace back to the original position directly, don't step
01038         pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, start_o, pm->ps->clientNum, pm->tracemask);
01039         if ( trace.fraction == 1.0 ) {
01040                 // use the original move
01041                 VectorCopy (down_o, pm->ps->origin);
01042                 VectorCopy (down_v, pm->ps->velocity);
01043                 if ( pm->debugLevel ) {
01044                         Com_Printf("%i:bend\n", c_pmove);
01045                 }
01046         } else 
01047 #endif
01048         {
01049                 // use the step move
01050                 float   delta;
01051 
01052                 delta = pm->ps->origin[2] - start_o[2];
01053                 if ( delta > 2 ) {
01054                         if ( delta < 7 ) {
01055                                 PM_AddEvent( EV_STEP_4 );
01056                         } else if ( delta < 11 ) {
01057                                 PM_AddEvent( EV_STEP_8 );
01058                         } else if ( delta < 15 ) {
01059                                 PM_AddEvent( EV_STEP_12 );
01060                         } else {
01061                                 PM_AddEvent( EV_STEP_16 );
01062                         }
01063                 }
01064                 if ( pm->debugLevel ) {
01065                         Com_Printf("%i:stepped\n", c_pmove);
01066                 }
01067         }
01068 }

void PM_WeaponLightsaber void   ) 
 

Definition at line 2833 of file bg_saber.c.

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

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

void trap_FS_FCloseFile fileHandle_t  f  ) 
 

Definition at line 95 of file cg_syscalls.c.

00095                                              {
00096         syscall( CG_FS_FCLOSEFILE, f );
00097 }

int trap_FS_FOpenFile const char *  qpath,
fileHandle_t f,
fsMode_t  mode
 

Definition at line 83 of file cg_syscalls.c.

00083                                                                                        {
00084         return syscall( CG_FS_FOPENFILE, qpath, f, mode );
00085 }

void trap_FS_Read void *  buffer,
int  len,
fileHandle_t  f
 

Definition at line 87 of file cg_syscalls.c.

00087                                                               {
00088         syscall( CG_FS_READ, buffer, len, f );
00089 }

void trap_FS_Write const void *  buffer,
int  len,
fileHandle_t  f
 

Definition at line 91 of file cg_syscalls.c.

00091                                                                      {
00092         syscall( CG_FS_WRITE, buffer, len, f );
00093 }


Variable Documentation

int c_pmove
 

Definition at line 52 of file bg_local.h.

Referenced by PM_StepSlideMove(), and PmoveSingle().

int forcePowerNeeded[NUM_FORCE_POWER_LEVELS][NUM_FORCE_POWERS]
 

Definition at line 54 of file bg_local.h.

Referenced by BG_ForcePowerDrain(), DoGripAction(), ForceJump(), ForceJumpCharge(), ForceTeamForceReplenish(), ForceTeamHeal(), ForceThrow(), PM_SaberPowerCheck(), PM_WeaponLightsaber(), StandardBotAI(), and WP_ForcePowerAvailable().

float pm_accelerate
 

Definition at line 43 of file bg_local.h.

float pm_airaccelerate
 

Definition at line 44 of file bg_local.h.

float pm_duckScale
 

Definition at line 39 of file bg_local.h.

float pm_flightfriction
 

Definition at line 50 of file bg_local.h.

float pm_flyaccelerate
 

Definition at line 46 of file bg_local.h.

float pm_friction
 

Definition at line 48 of file bg_local.h.

float pm_stopspeed
 

Definition at line 38 of file bg_local.h.

float pm_swimScale
 

Definition at line 40 of file bg_local.h.

float pm_wadeScale
 

Definition at line 41 of file bg_local.h.

float pm_wateraccelerate
 

Definition at line 45 of file bg_local.h.

float pm_waterfriction
 

Definition at line 49 of file bg_local.h.

pml_t pml
 

Definition at line 35 of file bg_local.h.

Referenced by PM_HoverTrace(), PM_SlideMove(), PM_VehFaceHyperspacePoint(), PM_VehForcedTurning(), PM_VehicleImpact(), PM_WeaponLightsaber(), and PmoveSingle().